@tracelog/lib 3.0.0 → 3.1.0-rc.116.2

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,2 +1,2 @@
1
- (function(h){"use strict";const L="data-tlog",Et=["button","a",'input[type="button"]','input[type="submit"]','input[type="reset"]','input[type="checkbox"]','input[type="radio"]',"select","textarea",'[role="button"]','[role="link"]','[role="tab"]','[role="menuitem"]','[role="option"]','[role="checkbox"]','[role="radio"]','[role="switch"]',"[routerLink]","[ng-click]","[data-action]","[data-click]","[data-navigate]","[data-toggle]","[onclick]",".btn",".button",".clickable",".nav-link",".menu-item","[data-testid]",'[tabindex="0"]'],Tt=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],_t=["token","auth","key","session","reset","password","api_key","apikey","secret","access_token","refresh_token","verification","code","otp"],I={INVALID_SESSION_TIMEOUT:"Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",INVALID_SAMPLING_RATE:"Sampling rate must be between 0 and 1",INVALID_ERROR_SAMPLING_RATE:"Error sampling must be between 0 and 1",INVALID_TRACELOG_PROJECT_ID:"TraceLog project ID is required when integration is enabled",INVALID_GLOBAL_METADATA:"Global metadata must be an object",INVALID_SENSITIVE_QUERY_PARAMS:"Sensitive query params must be an array of strings",INVALID_PAGE_VIEW_THROTTLE:"Page view throttle must be a non-negative number",INVALID_CLICK_THROTTLE:"Click throttle must be a non-negative number",INVALID_MAX_SAME_EVENT_PER_MINUTE:"Max same event per minute must be a positive number",INVALID_SEND_INTERVAL:"Send interval must be between 1000ms (1 second) and 60000ms (60 seconds)"},vt=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi],m="tlog",z=`${m}:qa_mode`,ue=`${m}:uid`,xe="tlog_mode",$e="qa",Be="qa_off",de=n=>n?`${m}:${n}:queue`:`${m}:queue`,he=n=>n?`${m}:${n}:rate_limit`:`${m}:rate_limit`,yt=n=>n?`${m}:${n}:session`:`${m}:session`,It=n=>n?`${m}:${n}:broadcast`:`${m}:broadcast`,Xe=(n,e)=>`${m}:${n}:session_counts:${e}`,Ge=10080*60*1e3,We=`${m}:session_counts_last_cleanup`,Ke=3600*1e3,fe=n=>n?`${m}:${n}:identity`:`${m}:identity`,D=`${m}:pending_identity`;var k=(n=>(n.Localhost="localhost:8080",n.Fail="localhost:9999",n))(k||{}),w=(n=>(n.Mobile="mobile",n.Tablet="tablet",n.Desktop="desktop",n.Unknown="unknown",n))(w||{}),N=(n=>(n.EVENT="event",n.QUEUE="queue",n))(N||{});class b extends Error{constructor(e,t,s){super(e),this.statusCode=t,this.responseCode=s,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,b)}statusCode;responseCode}class $ extends Error{constructor(e){super(e),this.name="RateLimitError",Error.captureStackTrace&&Error.captureStackTrace(this,$)}}class B extends Error{constructor(e){super(e),this.name="TimeoutError",Error.captureStackTrace&&Error.captureStackTrace(this,B)}}var d=(n=>(n.PAGE_VIEW="page_view",n.CLICK="click",n.SCROLL="scroll",n.SESSION_START="session_start",n.CUSTOM="custom",n.WEB_VITALS="web_vitals",n.ERROR="error",n))(d||{}),Q=(n=>(n.UP="up",n.DOWN="down",n))(Q||{}),U=(n=>(n.JS_ERROR="js_error",n.PROMISE_REJECTION="promise_rejection",n))(U||{}),X=(n=>(n.QA="qa",n))(X||{});class F extends Error{constructor(e,t,s){super(e),this.errorCode=t,this.layer=s,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}errorCode;layer}class S extends F{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class je extends F{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class ge extends F{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class me extends F{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class wt extends F{constructor(e,t,s="runtime"){super(e,"INITIALIZATION_TIMEOUT",s),this.timeoutMs=t}timeoutMs}const At="background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",Mt="background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",Lt="background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",bt=(n,e)=>{if(e){if(e instanceof Error){const t=e.message.replace(/\s+at\s+.*$/gm,"").replace(/\s*\([^()]+:\d+:\d+\)/g,"");return`[TraceLog] ${n}: ${t}`}if(e instanceof Error)return`[TraceLog] ${n}: ${e.message}`;if(typeof e=="string")return`[TraceLog] ${n}: ${e}`;if(typeof e=="object")try{return`[TraceLog] ${n}: ${JSON.stringify(e)}`}catch{return`[TraceLog] ${n}: [Unable to serialize error]`}return`[TraceLog] ${n}: ${String(e)}`}return`[TraceLog] ${n}`},Rt=()=>{if(typeof window>"u"||typeof sessionStorage>"u")return!1;try{return sessionStorage.getItem(z)==="true"}catch{return!1}},a=(n,e,t)=>{const{error:s,data:r,showToClient:i=!1,style:o,visibility:l}=t??{},c=s?bt(e,s):`[TraceLog] ${e}`,u=n==="error"?"error":n==="warn"?"warn":"log";if(!Nt(l,i))return;const p=Ct(l,o),v=r!==void 0?Se(r):void 0;Ot(u,c,p,v)},Nt=(n,e)=>n==="critical"?!0:n==="qa"||e?Rt():!1,Ct=(n,e)=>e!==void 0&&e!==""?e:n==="critical"?Lt:"",Ot=(n,e,t,s)=>{const r=t!==void 0&&t!=="",i=r?`%c${e}`:e;s!==void 0?r?console[n](i,t,s):console[n](i,s):r?console[n](i,t):console[n](i)},Se=n=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[s,r]of Object.entries(n)){const i=s.toLowerCase();if(t.some(o=>i.includes(o))){e[s]="[REDACTED]";continue}r!==null&&typeof r=="object"&&!Array.isArray(r)?e[s]=Se(r):Array.isArray(r)?e[s]=r.map(o=>o!==null&&typeof o=="object"&&!Array.isArray(o)?Se(o):o):e[s]=r}return e};let pe,ze;const Pt=()=>{typeof window<"u"&&!pe&&(pe=window.matchMedia("(pointer: coarse)"),ze=window.matchMedia("(hover: none)"))},Y="Unknown",Dt=n=>{const e=n.userAgentData?.platform;if(e!=null&&e!==""){if(/windows/i.test(e))return"Windows";if(/macos/i.test(e))return"macOS";if(/android/i.test(e))return"Android";if(/linux/i.test(e))return"Linux";if(/chromeos/i.test(e))return"ChromeOS";if(/ios/i.test(e))return"iOS"}const t=navigator.userAgent;return/Windows/i.test(t)?"Windows":/iPhone|iPad|iPod/i.test(t)?"iOS":/Mac OS X|Macintosh/i.test(t)?"macOS":/Android/i.test(t)?"Android":/CrOS/i.test(t)?"ChromeOS":/Linux/i.test(t)?"Linux":Y},kt=n=>{const e=n.userAgentData?.brands;if(e!=null&&e.length>0){const r=e.filter(i=>!/not.?a.?brand|chromium/i.test(i.brand))[0];if(r!=null){const i=r.brand;return/google chrome/i.test(i)?"Chrome":/microsoft edge/i.test(i)?"Edge":/opera/i.test(i)?"Opera":i}}const t=navigator.userAgent;return/Edg\//i.test(t)?"Edge":/OPR\//i.test(t)?"Opera":/Chrome/i.test(t)?"Chrome":/Firefox/i.test(t)?"Firefox":/Safari/i.test(t)&&!/Chrome/i.test(t)?"Safari":Y},Ut=()=>{try{const n=navigator;if(n.userAgentData!=null&&typeof n.userAgentData.mobile=="boolean"){const c=n.userAgentData.platform;return c!=null&&c!==""&&/ipad|tablet/i.test(c)?w.Tablet:n.userAgentData.mobile?w.Mobile:w.Desktop}Pt();const e=window.innerWidth,t=pe?.matches??!1,s=ze?.matches??!1,r="ontouchstart"in window||navigator.maxTouchPoints>0,i=navigator.userAgent.toLowerCase(),o=/mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i),l=/tablet|ipad|android(?!.*mobile)/.test(i);return e<=767||o&&r?w.Mobile:e>=768&&e<=1024||l||t&&s&&r?w.Tablet:w.Desktop}catch(n){return a("debug","Device detection failed, defaulting to desktop",{error:n}),w.Desktop}},Ft=()=>{try{const n=navigator;return{type:Ut(),os:Dt(n),browser:kt(n)}}catch(n){return a("debug","Device info detection failed, using defaults",{error:n}),{type:w.Desktop,os:Y,browser:Y}}},Qe=500,Ye=2e3,qe=5e3,q=50,Vt=q*2,Je=1,Ht=1e3,xt=10,Ze=5e3,$t=3,Bt=200,Xt=6e4,Gt=64,Wt={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800},Ee={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800},et={LCP:4e3,FCP:3e3,CLS:.25,INP:500,TTFB:1800},J="needs-improvement",Te=(n=J)=>{switch(n){case"all":return{LCP:0,FCP:0,CLS:0,INP:0,TTFB:0};case"needs-improvement":return Ee;case"poor":return et;default:return Ee}},Kt=50,jt="2.10.0",zt=()=>typeof window<"u"&&typeof sessionStorage<"u",Qt=()=>{try{const n=new URLSearchParams(window.location.search);n.delete(xe);const e=n.toString(),t=window.location.pathname+(e?"?"+e:"")+window.location.hash;window.history.replaceState({},"",t)}catch{}},Yt=()=>{if(!zt())return!1;try{const e=new URLSearchParams(window.location.search).get(xe),t=sessionStorage.getItem(z);let s=null;return e===$e?(s=!0,sessionStorage.setItem(z,"true"),a("info","QA Mode ACTIVE",{visibility:"qa",style:At})):e===Be&&(s=!1,sessionStorage.setItem(z,"false"),a("info","QA Mode DISABLED",{visibility:"qa",style:Mt})),(e===$e||e===Be)&&Qt(),s??t==="true"}catch{return!1}},qt=["co.uk","org.uk","com.au","net.au","com.br","co.nz","co.jp","com.mx","co.in","com.cn","co.za"],tt=n=>{const e=n.toLowerCase().split(".");if(e.length<=2)return n.toLowerCase();const t=e.slice(-2).join(".");return qt.includes(t)?e.slice(-3).join("."):e.slice(-2).join(".")},Jt=(n,e)=>n===e?!0:tt(n)===tt(e),_e=()=>{const n=document.referrer;if(!n)return"Direct";try{const e=new URL(n).hostname.toLowerCase(),t=window.location.hostname.toLowerCase();return Jt(e,t)?"Direct":n}catch(e){return a("debug","Failed to parse referrer URL, using raw value",{error:e,data:{referrer:n}}),n}},ve=()=>{const n=new URLSearchParams(window.location.search),e={};return Tt.forEach(s=>{const r=n.get(s);if(r){const i=s.split("utm_")[1];e[i]=r}}),Object.keys(e).length?e:void 0},st=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)});let Z=0,ee=0;const Zt=()=>{let n=Date.now();n<ee&&(n=ee),n===ee?Z=(Z+1)%1e3:Z=0,ee=n;const e=Z.toString().padStart(3,"0");let t="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const s=crypto.getRandomValues(new Uint8Array(3));s&&(t=Array.from(s,r=>r.toString(16).padStart(2,"0")).join(""))}}catch{}return t||(t=Math.floor(Math.random()*16777215).toString(16).padStart(6,"0")),`${n}-${e}-${t}`},es=n=>{try{return new URL(n).protocol==="https:"}catch{return!1}},ts=n=>{try{const t=new URL(window.location.href).hostname;if(!t||typeof t!="string")throw new Error("Invalid hostname");if(t==="localhost"||t==="127.0.0.1"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t))throw new Error("SaaS integration requires a domain hostname; localhost and IP addresses are not supported. For local development, omit `integrations.tracelog` to run in standalone mode (events emitted locally, no network requests), or test against a staging domain that resolves to your dev machine via /etc/hosts.");const s=t.split(".");if(!s||!Array.isArray(s)||s.length===0||s.length===1&&s[0]==="")throw new Error("Invalid hostname structure");if(s.length===1)throw new Error("Single-part domain not supported for SaaS integration");const r=s.length===2?s.join("."):s.slice(-2).join(".");if(!r||r.split(".").length<2)throw new Error("Invalid domain structure for SaaS");const i=`https://${n}.${r}/collect`;if(!es(i))throw new Error("Generated URL failed validation");return i}catch(e){throw new Error(`Invalid SaaS URL configuration: ${e instanceof Error?e.message:String(e)}`)}},ss=n=>{const e={};return n.integrations?.tracelog?.projectId&&(e.saas=ts(n.integrations.tracelog.projectId)),e},ye=(n,e=[])=>{if(!n||typeof n!="string")return a("warn","Invalid URL provided to normalizeUrl",{data:{type:typeof n}}),n||"";try{const t=new URL(n),s=t.searchParams,r=[...new Set([..._t,...e])];let i=!1;const o=[];return r.forEach(l=>{s.has(l)&&(s.delete(l),i=!0,o.push(l))}),!i&&n.includes("?")?n:(t.search=s.toString(),t.toString())}catch(t){return a("warn","URL normalization failed, returning original",{error:t,data:{urlLength:n?.length}}),n}},nt=n=>{if(!n||typeof n!="string"||n.trim().length===0)return"";let e=n;n.length>1e3&&(e=n.slice(0,Math.max(0,1e3)));let t=0;for(const r of vt){const i=e;e=e.replace(r,""),i!==e&&t++}return t>0&&a("warn","XSS patterns detected and removed",{data:{patternMatches:t,valueLength:n.length}}),e.trim()},Ie=(n,e=0)=>{if(n==null)return null;if(typeof n=="string")return nt(n);if(typeof n=="number")return!Number.isFinite(n)||n<-Number.MAX_SAFE_INTEGER||n>Number.MAX_SAFE_INTEGER?0:n;if(typeof n=="boolean")return n;if(e>10)return null;if(Array.isArray(n))return n.slice(0,1e3).map(r=>Ie(r,e+1)).filter(r=>r!==null);if(typeof n=="object"){const t={},r=Object.entries(n).slice(0,200);for(const[i,o]of r){const l=nt(i);if(l){const c=Ie(o,e+1);c!==null&&(t[l]=c)}}return t}return null},ns=n=>{if(typeof n!="object"||n===null)return{};try{const e=Ie(n);return typeof e=="object"&&e!==null?e:{}}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`)}},rt=[/\b[A-Za-z0-9._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\.)+[A-Za-z]{2,63}\b/gi,/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,/\b[A-Z]{2}\d{2}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/gi,/\b[sp]k_(test|live)_[a-zA-Z0-9]{10,}\b/gi,/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,/:\/\/[^:/]+:([^@]+)@/gi,/[?&](token|password|passwd|auth|secret|secret_key|private_key|auth_key|api_key|apikey|access_token)=[^&\s]+/gi],te=n=>{let e=n;for(const t of rt)e=e.replace(t,"[REDACTED]");return e},rs=n=>{if(n!==void 0&&(n===null||typeof n!="object"))throw new S("Configuration must be an object","config");if(n){if(n.sessionTimeout!==void 0&&(typeof n.sessionTimeout!="number"||n.sessionTimeout<3e4||n.sessionTimeout>864e5))throw new je(I.INVALID_SESSION_TIMEOUT,"config");if(n.globalMetadata!==void 0&&(typeof n.globalMetadata!="object"||n.globalMetadata===null))throw new S(I.INVALID_GLOBAL_METADATA,"config");if(n.integrations&&is(n.integrations),n.sensitiveQueryParams!==void 0){if(!Array.isArray(n.sensitiveQueryParams))throw new S(I.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of n.sensitiveQueryParams)if(typeof e!="string")throw new S("All sensitive query params must be strings","config")}if(n.errorSampling!==void 0&&(typeof n.errorSampling!="number"||n.errorSampling<0||n.errorSampling>1))throw new ge(I.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new ge(I.INVALID_SAMPLING_RATE,"config");if(n.pageViewThrottleMs!==void 0&&(typeof n.pageViewThrottleMs!="number"||n.pageViewThrottleMs<0))throw new S(I.INVALID_PAGE_VIEW_THROTTLE,"config");if(n.clickThrottleMs!==void 0&&(typeof n.clickThrottleMs!="number"||n.clickThrottleMs<0))throw new S(I.INVALID_CLICK_THROTTLE,"config");if(n.maxSameEventPerMinute!==void 0&&(typeof n.maxSameEventPerMinute!="number"||n.maxSameEventPerMinute<=0))throw new S(I.INVALID_MAX_SAME_EVENT_PER_MINUTE,"config");if(n.sendIntervalMs!==void 0&&(!Number.isFinite(n.sendIntervalMs)||n.sendIntervalMs<1e3||n.sendIntervalMs>6e4))throw new S(I.INVALID_SEND_INTERVAL,"config");if(n.flushOnSpaNavigation!==void 0&&typeof n.flushOnSpaNavigation!="boolean")throw new S(`Invalid flushOnSpaNavigation type: ${typeof n.flushOnSpaNavigation}. Must be a boolean`,"config");if(n.flushOnPageHidden!==void 0&&typeof n.flushOnPageHidden!="boolean")throw new S(`Invalid flushOnPageHidden type: ${typeof n.flushOnPageHidden}. Must be a boolean`,"config");if(n.webVitalsMode!==void 0){if(typeof n.webVitalsMode!="string")throw new S(`Invalid webVitalsMode type: ${typeof n.webVitalsMode}. Must be a string`,"config");const e=["all","needs-improvement","poor"];if(!e.includes(n.webVitalsMode))throw new S(`Invalid webVitalsMode: "${n.webVitalsMode}". Must be one of: ${e.join(", ")}`,"config")}if(n.webVitalsThresholds!==void 0){if(typeof n.webVitalsThresholds!="object"||n.webVitalsThresholds===null||Array.isArray(n.webVitalsThresholds))throw new S("webVitalsThresholds must be an object","config");const e=["LCP","FCP","CLS","INP","TTFB"];for(const[t,s]of Object.entries(n.webVitalsThresholds)){if(!e.includes(t))throw new S(`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,"config");if(typeof s!="number"||!Number.isFinite(s)||s<0)throw new S(`Invalid Web Vitals threshold value for ${t}: ${s}. Must be a non-negative finite number`,"config")}}}},is=n=>{if(n&&n.tracelog){if(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()==="")throw new me(I.INVALID_TRACELOG_PROJECT_ID,"config");if(n.tracelog.shopify!==void 0&&typeof n.tracelog.shopify!="boolean")throw new me("tracelog.shopify must be a boolean","config")}},os=n=>(rs(n),{...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??Je,samplingRate:n?.samplingRate??1,pageViewThrottleMs:n?.pageViewThrottleMs??1e3,clickThrottleMs:n?.clickThrottleMs??300,maxSameEventPerMinute:n?.maxSameEventPerMinute??60,sendIntervalMs:n?.sendIntervalMs??1e4,flushOnSpaNavigation:n?.flushOnSpaNavigation??!1,flushOnPageHidden:n?.flushOnPageHidden??!0}),we=(n,e=new Set)=>{if(n==null)return!0;const t=typeof n;return t==="string"||t==="number"||t==="boolean"?!0:t==="function"||t==="symbol"||t==="bigint"||e.has(n)?!1:(e.add(n),Array.isArray(n)?n.every(s=>we(s,e)):t==="object"?Object.values(n).every(s=>we(s,e)):!1)},as=n=>typeof n!="object"||n===null?!1:we(n),Ae=n=>{if(typeof n!="object"||n===null||Array.isArray(n))return;const e={};for(const[t,s]of Object.entries(n))typeof s=="string"&&(e[t]=s);return Object.keys(e).length>0?e:void 0},ls=n=>typeof n!="string"?{valid:!1,error:"Event name must be a string"}:n.length===0?{valid:!1,error:"Event name cannot be empty"}:n.length>120?{valid:!1,error:"Event name is too long (max 120 characters)"}:n.includes("<")||n.includes(">")||n.includes("&")?{valid:!1,error:"Event name contains invalid characters"}:["constructor","prototype","__proto__","eval","function","var","let","const"].includes(n.toLowerCase())?{valid:!1,error:"Event name cannot be a reserved word"}:{valid:!0},it=(n,e,t)=>{const s=ns(e),r=`${t} "${n}" metadata error`;if(!as(s))return{valid:!1,error:`${r}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(s)}catch{return{valid:!1,error:`${r}: object contains circular references or cannot be serialized.`}}if(new TextEncoder().encode(i).byteLength>49152)return{valid:!1,error:`${r}: object is too large (max ${49152/1024} KB).`};if(Object.keys(s).length>100)return{valid:!1,error:`${r}: object has too many keys (max 100 keys).`};for(const[c,u]of Object.entries(s)){if(Array.isArray(u)){if(u.length>500)return{valid:!1,error:`${r}: array property "${c}" is too large (max 500 items).`};for(const f of u)if(typeof f=="string"&&f.length>500)return{valid:!1,error:`${r}: array property "${c}" contains strings that are too long (max 500 characters).`}}if(typeof u=="string"&&u.length>1e3)return{valid:!1,error:`${r}: property "${c}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:s}},cs=(n,e,t)=>{if(Array.isArray(e)){const s=[],r=`${t} "${n}" metadata error`;for(let i=0;i<e.length;i++){const o=e[i];if(typeof o!="object"||o===null||Array.isArray(o))return{valid:!1,error:`${r}: array item at index ${i} must be an object.`};const l=it(n,o,t);if(!l.valid)return{valid:!1,error:`${r}: array item at index ${i} is invalid: ${l.error}`};l.sanitizedMetadata&&s.push(l.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:s}}return it(n,e,t)},us=(n,e)=>{const t=ls(n);if(!t.valid)return a("error","Event name validation failed",{data:{eventName:n,error:t.error}}),t;if(!e)return{valid:!0};const s=cs(n,e,"customEvent");return s.valid||a("error","Event metadata validation failed",{data:{eventName:n,error:s.error}}),s};class ds{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const s=this.listeners.get(e);if(s){const r=s.indexOf(t);r>-1&&s.splice(r,1)}}emit(e,t){const s=this.listeners.get(e);s&&s.forEach(r=>{r(t)})}removeAllListeners(){this.listeners.clear()}}const hs=/https?:\/\/\S+/g,fs=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,gs=/0x[0-9a-fA-F]{4,}/g,ms=/(?<!\d)\d{4,}(?!\d)/g,Ss=/(['"])[^'"]{20,}\1/g;function ps(n){return n.replace(hs,"[URL]").replace(fs,"[ID]").replace(gs,"[ADDR]").replace(ms,"[N]").replace(Ss,"$1[VAR]$1").toLowerCase().trim()}function Es(n){const e=ps(n.message),t=(n.filename??"").trim(),s=t.search(/[?#]/),r=s===-1?t:t.slice(0,s),i=n.line==null?"":String(n.line);return`${e}|${r}|${i}`}const Me={config:{}};class E{get(e){return Me[e]}set(e,t){Me[e]=t}getState(){return{...Me}}}class Ts extends E{storeManager;apiUrl;lastPermanentErrorLog=null;recoveryInProgress=!1;lastMetadataTimestamp=0;pendingControllers=new Set;consecutiveNetworkFailures=0;circuitOpenedAt=0;rateLimitedUntil=0;rateLimitStorageKeyAtArm=null;constructor(e,t){super(),this.storeManager=e,this.apiUrl=t,this.migrateLegacyV2Keys(),this.rateLimitedUntil=this.loadRateLimitCooldown()}migrateLegacyV2Keys(){const e=this.get("userId")||"anonymous",t=`${de(e)}:saas`,s=`${de(e)}:custom`,r=`${he(e)}:saas`,i=`${he(e)}:custom`;try{const o=this.storeManager.getItem(t);if(o){const l=this.getQueueStorageKey(),c=this.storeManager.getItem(l);c?this.mergeLegacyIntoCurrent(l,o,c):(this.storeManager.setItem(l,o),a("debug","Migrated v2 SaaS queue to v3 unscoped key")),this.storeManager.removeItem(t)}}catch(o){a("debug","Failed to migrate v2 SaaS queue, discarding legacy key",{error:o});try{this.storeManager.removeItem(t)}catch{}}[s,r,i].forEach(o=>{try{this.storeManager.getItem(o)!==null&&this.storeManager.removeItem(o)}catch{}})}mergeLegacyIntoCurrent(e,t,s){try{const r=JSON.parse(t),i=JSON.parse(s);if(!Array.isArray(r?.events)||!Array.isArray(i?.events)){a("debug","Legacy or current queue malformed, keeping current only");return}const o=new Set(i.events.map(u=>u.id)),l=[...i.events,...r.events.filter(u=>typeof u.id=="string"&&!o.has(u.id))],c={...i,events:l,timestamp:typeof i.timestamp=="number"&&typeof r.timestamp=="number"?Math.min(i.timestamp,r.timestamp):i.timestamp??r.timestamp??Date.now(),recoveryFailures:Math.max(i.recoveryFailures??0,r.recoveryFailures??0)||void 0};this.storeManager.setItem(e,JSON.stringify(c)),a("debug","Merged v2 SaaS queue into existing v3 queue",{data:{added:l.length-i.events.length,total:l.length}})}catch(r){a("debug","Failed to merge legacy queue, keeping current",{error:r})}}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return de(e)}getRateLimitStorageKey(){const e=this.get("userId")||"anonymous";return he(e)}getActiveRateLimitKey(){return this.rateLimitStorageKeyAtArm??this.getRateLimitStorageKey()}armRateLimitCooldown(e){this.rateLimitedUntil=e,this.rateLimitStorageKeyAtArm=this.getRateLimitStorageKey(),this.persistRateLimitCooldown(e)}loadRateLimitCooldown(){const e=this.getRateLimitStorageKey();try{const t=this.storeManager.getItem(e);if(!t)return 0;const s=Number(t);return!Number.isFinite(s)||s<=Date.now()?(this.storeManager.removeItem(e),0):(this.rateLimitStorageKeyAtArm=e,s)}catch{return 0}}persistRateLimitCooldown(e){const t=this.getActiveRateLimitKey();try{const s=this.storeManager.getItem(t);if(s){const r=Number(s);if(Number.isFinite(r)&&r>=e)return}this.storeManager.setItem(t,String(e))}catch{}}clearRateLimitCooldown(){const e=this.getActiveRateLimitKey();try{const t=this.storeManager.getItem(e);if(t){const s=Number(t);if(Number.isFinite(s)&&s>Date.now()){this.rateLimitedUntil=s;return}}this.storeManager.removeItem(e)}catch{}this.rateLimitedUntil=0,this.rateLimitStorageKeyAtArm=null}isRateLimited(){return this.rateLimitedUntil===0&&(this.rateLimitedUntil=this.loadRateLimitCooldown()),!(this.rateLimitedUntil===0||Date.now()>=this.rateLimitedUntil&&(this.clearRateLimitCooldown(),this.rateLimitedUntil===0))}sendEventsQueueSync(e){if(this.isRateLimited()){a("debug","Rate-limit cooldown active, skipping sync send",{data:{cooldownRemainingMs:this.rateLimitedUntil-Date.now(),events:e.events.length}});const t=this.ensureBatchMetadata(e),s=this.getPersistedData(),r=typeof s?.recoveryFailures=="number"&&Number.isFinite(s.recoveryFailures)?s.recoveryFailures:0;return this.persistEventsWithFailureCount(t,r,!0),!1}return this.apiUrl.includes(k.Fail)?(a("warn","Fail mode: simulating network failure (sync)",{data:{events:e.events.length}}),!1):this.apiUrl.includes(k.Localhost)?(a("debug","Success mode: simulating successful send (sync)",{data:{events:e.events.length}}),!0):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){const s=this.ensureBatchMetadata(e);try{const r=await this.send(s);return r?(this.clearPersistedEvents(),t?.onSuccess?.(s.events.length,s.events,s)):(this.persistEvents(s),t?.onFailure?.()),r}catch(r){return r instanceof b?(this.logPermanentError("Permanent error, not retrying",r),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(s),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){if(this.recoveryInProgress){a("debug","Recovery already in progress, skipping duplicate attempt");return}this.recoveryInProgress=!0;let t=null,s=0;try{const r=this.getPersistedData();if(!r||!this.isDataRecent(r)||r.events.length===0){this.clearPersistedEvents();return}const i=r.recoveryFailures;if(s=typeof i=="number"&&Number.isFinite(i)&&i>=0?i:0,s>=3){a("debug",`Discarding persisted events after ${s} failed recovery attempts`),this.clearPersistedEvents(),e?.onFailure?.();return}if(this.isRateLimited()){a("debug","Rate-limit cooldown active, deferring recovery",{data:{cooldownRemainingMs:this.rateLimitedUntil-Date.now()}}),e?.onFailure?.();return}if(t=this.ensureBatchMetadata(this.createRecoveryBody(r)),t.events.length===0){a("debug","All persisted events exceeded the recovery age cutoff; discarding batch"),this.clearPersistedEvents();return}await this.send(t)?(this.clearPersistedEvents(),e?.onSuccess?.(r.events.length,r.events,t)):(this.persistEventsWithFailureCount(t,s+1,!0),e?.onFailure?.())}catch(r){if(r instanceof b){this.logPermanentError("Permanent error during recovery, clearing persisted events",r),this.clearPersistedEvents(),e?.onFailure?.();return}a("error","Failed to recover persisted events",{error:r}),t&&this.persistEventsWithFailureCount(t,s+1,!0),e?.onFailure?.()}finally{this.recoveryInProgress=!1}}stop(){}async backoffDelay(e){const t=100*Math.pow(2,e),s=Math.random()*100;return new Promise(r=>setTimeout(r,t+s))}async send(e){const t=this.ensureBatchMetadata(e,e._metadata?.idempotency_token);if(this.apiUrl.includes(k.Fail))return a("debug","Fail mode: simulating network failure",{data:{events:t.events.length}}),!1;if(this.apiUrl.includes(k.Localhost))return a("debug","Success mode: simulating successful send",{data:{events:t.events.length}}),!0;if(this.isRateLimited())return a("debug","Rate-limit cooldown active, skipping send",{data:{cooldownRemainingMs:this.rateLimitedUntil-Date.now(),events:t.events.length}}),!1;if(this.consecutiveNetworkFailures>=3){const l=Date.now()-this.circuitOpenedAt;if(l<12e4)return a("debug","Network circuit open, skipping send",{data:{consecutiveNetworkFailures:this.consecutiveNetworkFailures,cooldownRemainingMs:12e4-l}}),!1}const{url:s,payload:r}=this.prepareRequest(t);let i=!0,o=!1;for(let l=1;l<=3;l++)try{return(await this.sendWithTimeout(s,r)).ok?(l>1&&a("info",`Send succeeded after ${l-1} retry attempt(s)`,{data:{events:t.events.length,attempt:l}}),this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0,!0):!1}catch(c){const u=l===3;if(c instanceof b)throw this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0,c;if(c instanceof $){this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0,i=!1,o=!0,this.armRateLimitCooldown(Date.now()+6e4),a("warn","Rate limited, skipping retries",{data:{events:e.events.length,attempt:l,cooldownMs:6e4}});break}if(c instanceof B||(i=!1),c instanceof TypeError||(o=!0),a(u?"error":"warn",`Send attempt ${l} failed${u?" (all retries exhausted)":", will retry"}`,{error:c,data:{events:e.events.length,url:s.replace(/\/\/[^/]+/,"//[DOMAIN]"),attempt:l,maxAttempts:3}}),!u){await this.backoffDelay(l);continue}return i?(a("debug","All retry attempts timed out, preserving batch for retry",{data:{events:t.events.length}}),!1):(o?(this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0):(this.consecutiveNetworkFailures=Math.min(this.consecutiveNetworkFailures+1,3),this.consecutiveNetworkFailures>=3&&(this.circuitOpenedAt=Date.now())),!1)}return!1}async sendWithTimeout(e,t){const s=new AbortController;this.pendingControllers.add(s);let r=!1;const i=setTimeout(()=>{r=!0,s.abort()},15e3);try{const o=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:s.signal,headers:{"Content-Type":"application/json"}});if(!o.ok){if(o.status>=400&&o.status<500&&o.status!==408&&o.status!==429){const c=await this.readTraceLogErrorCode(o),u=c?`HTTP ${o.status}: ${o.statusText} (${c})`:`HTTP ${o.status}: ${o.statusText}`;throw new b(u,o.status,c)}throw o.status===429?new $(`HTTP 429: ${o.statusText}`):new Error(`HTTP ${o.status}: ${o.statusText}`)}return o}catch(o){throw o instanceof b?o:r?new B("Request timed out"):o}finally{clearTimeout(i),this.pendingControllers.delete(s)}}async readTraceLogErrorCode(e){try{const t=await e.clone().json();if(typeof t.code=="string"&&t.code.length>0&&t.code.length<=Gt)return t.code}catch{}}sendQueueSyncInternal(e){const t=this.ensureBatchMetadata(e),s=this.ensureBatchMetadata(t,t._metadata?.idempotency_token),{url:r,payload:i}=this.prepareRequest(s);if(i.length>65536)return a("warn","Payload exceeds sendBeacon limit, persisting for recovery",{data:{size:i.length,limit:65536,events:s.events.length}}),this.persistEvents(t),!1;const o=new Blob([i],{type:"application/json"});if(!this.isSendBeaconAvailable())return a("warn","sendBeacon not available, persisting events for recovery"),this.persistEvents(t),!1;const l=navigator.sendBeacon(r,o);return l||(a("warn","sendBeacon rejected request, persisting events for recovery"),this.persistEvents(t)),l}prepareRequest(e){let t=Date.now();t<this.lastMetadataTimestamp&&(t=this.lastMetadataTimestamp),this.lastMetadataTimestamp=t;const s={...e,_metadata:{...e._metadata,idempotency_token:e._metadata?.idempotency_token??this.computeContentToken(e),referer:typeof window<"u"?window.location.href:void 0,timestamp:t,client_version:jt}};return{url:this.apiUrl,payload:JSON.stringify(s)}}ensureBatchMetadata(e,t){const s=e._metadata?.idempotency_token??t??this.computeContentToken(e);return e._metadata?.idempotency_token===s?e:{...e,_metadata:{...e._metadata,idempotency_token:s}}}computeContentToken(e){const t=e.events.map(i=>i.id).sort().join(","),s=`${e.user_id}|${e.session_id}|${t}`;let r=2166136261;for(let i=0;i<s.length;i++)r^=s.charCodeAt(i),r=Math.imul(r,16777619)>>>0;return r.toString(16).padStart(8,"0")}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){a("debug","Failed to parse persisted data",{error:e}),this.clearPersistedEvents()}return null}isDataRecent(e){return!e.timestamp||typeof e.timestamp!="number"?!1:(Date.now()-e.timestamp)/(1e3*60*60)<2}createRecoveryBody(e){const{timestamp:t,recoveryFailures:s,...r}=e,i=r.events??[],o=Date.now()-5184e5,l=i.filter(c=>{const u=typeof c.timestamp=="number"?c.timestamp:new Date(c.timestamp).getTime();return Number.isFinite(u)&&u>=o});return l.length<i.length&&a("debug","Recovery dropped stale events",{data:{dropped:i.length-l.length,kept:l.length}}),{...r,events:l}}persistEvents(e){const t=this.getPersistedData(),s=typeof t?.recoveryFailures=="number"&&Number.isFinite(t.recoveryFailures)?t.recoveryFailures:0;return this.persistEventsWithFailureCount(e,s)}persistEventsWithFailureCount(e,t,s=!1){try{const r=this.getPersistedData();if(!s&&r&&r.timestamp){const l=Date.now()-r.timestamp;if(l<1e3)return a("debug","Skipping persistence, another tab recently persisted events",{data:{timeSinceExisting:l}}),!0}const i={...e,timestamp:Date.now(),...t>0&&{recoveryFailures:t}},o=this.getQueueStorageKey();return this.storeManager.setItem(o,JSON.stringify(i)),!!this.storeManager.getItem(o)}catch(r){return a("debug","Failed to persist events",{error:r}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){a("debug","Failed to clear persisted events",{error:e})}}isSendBeaconAvailable(){return typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}logPermanentError(e,t){const s=Date.now(),r=`${t.statusCode??"unknown"}:${t.responseCode??""}`;(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.key!==r||s-this.lastPermanentErrorLog.timestamp>=Xt)&&(a("error",e,{data:{status:t.statusCode,code:t.responseCode,message:t.message}}),this.lastPermanentErrorLog={key:r,timestamp:s})}}class _s extends E{bootTime;bootTimestamp;hasPerformanceNow;constructor(){if(super(),typeof window>"u"){this.hasPerformanceNow=!1,this.bootTime=0,this.bootTimestamp=0;return}this.hasPerformanceNow=typeof performance<"u"&&typeof performance.now=="function",this.hasPerformanceNow?(this.bootTime=performance.now(),this.bootTimestamp=Date.now()):(this.bootTime=0,this.bootTimestamp=Date.now(),a("debug","performance.now() not available, falling back to Date.now()"))}now(){if(!this.hasPerformanceNow)return Date.now();const e=performance.now()-this.bootTime;return Math.round(this.bootTimestamp+e)}validateTimestamp(e){const s=e-this.now();return s>12e4?{valid:!1,error:`Timestamp is ${(s/1e3/60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`}:{valid:!0}}}const vs=new Set(Object.values(d));class ys extends E{dataSenders;emitter;timeManager;recentEventFingerprints=new Map;perEventRateLimits=new Map;eventsQueue=[];pendingEventsBuffer=[];sendTimeoutId=null;sendInProgress=!1;consecutiveSendFailures=0;rateLimitCounter=0;rateLimitWindowStart=0;lastSessionId=null;pendingSyncFlush=!1;sessionEventCounts={total:0,[d.CLICK]:0,[d.PAGE_VIEW]:0,[d.CUSTOM]:0,[d.SCROLL]:0};saveSessionCountsDebounced=null;constructor(e,t=null){super(),this.emitter=t,this.timeManager=new _s,this.dataSenders=[];const s=this.get("collectApiUrls");s?.saas&&this.dataSenders.push(new Ts(e,s.saas)),this.saveSessionCountsDebounced=this.debounce(r=>{this.saveSessionCounts(r)},500),this.cleanupExpiredSessionCounts()}async recoverPersistedEvents(){const e=this.dataSenders.map(async t=>t.recoverPersistedEvents({onSuccess:(s,r,i)=>{if(r&&r.length>0){const o=r.map(l=>l.id);this.removeProcessedEvents(o),i&&this.emitEventsQueue(i)}},onFailure:()=>{a("debug","Failed to recover persisted events")}}));await Promise.allSettled(e)}track({type:e,page_url:t,from_page_url:s,scroll_data:r,click_data:i,custom_event:o,web_vitals:l,error_data:c,page_view:u}){if(!e){a("error","Event type is required - event will be ignored");return}if(!vs.has(e)){a("error","Invalid event type - event will be ignored",{data:{type:e}});return}const f=this.get("sessionId");if(!f){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),a("debug","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:s,scroll_data:r,click_data:i,custom_event:o,web_vitals:l,error_data:c,page_view:u});return}this.lastSessionId!==f&&(this.lastSessionId=f,this.sessionEventCounts=this.loadSessionCounts(f));const p=e===d.SESSION_START;if(p&&a("debug","Processing SESSION_START event",{data:{sessionId:f}}),!p&&!this.checkRateLimit())return;const v=e;if(!p){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:v,total:this.sessionEventCounts.total,limit:1e3}});return}const y=this.getTypeLimitForEvent(v);if(y){const He=this.sessionEventCounts[v];if(He!==void 0&&He>=y){a("warn","Session event type limit reached",{data:{type:v,count:He,limit:y}});return}}}if(v===d.CUSTOM&&o?.name){const y=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,y))return}const Js=v===d.SESSION_START,Zs=t||this.get("pageUrl"),ce=this.buildEventPayload({type:v,page_url:Zs,from_page_url:s,scroll_data:r,click_data:i,custom_event:o,web_vitals:l,error_data:c,page_view:u});if(ce&&!(!p&&!this.shouldSample())){if(Js){const y=this.get("sessionId");if(!y){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("debug","Duplicate session_start detected",{data:{sessionId:y}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(ce)){if(this.get("mode")===X.QA&&v===d.CUSTOM&&o){a("info",`Custom Event: ${o.name}`,{visibility:"qa",data:{name:o.name,...o.metadata&&{metadata:o.metadata}}}),this.emitEvent(ce);return}if(this.addToQueue(ce),!p){this.sessionEventCounts.total++,this.sessionEventCounts[v]!==void 0&&this.sessionEventCounts[v]++;const y=this.get("sessionId");y&&this.saveSessionCountsDebounced&&this.saveSessionCountsDebounced(y)}}}}stop(){this.clearSendTimeout(),this.sendInProgress=!1,this.pendingSyncFlush=!1,this.consecutiveSendFailures=0;const e=this.get("sessionId");e&&this.saveSessionCounts(e),this.eventsQueue=[],this.pendingEventsBuffer=[],this.recentEventFingerprints.clear(),this.rateLimitCounter=0,this.rateLimitWindowStart=0,this.perEventRateLimits.clear(),this.sessionEventCounts={total:0,[d.CLICK]:0,[d.PAGE_VIEW]:0,[d.CUSTOM]:0,[d.SCROLL]:0},this.lastSessionId=null,this.set("hasStartSession",!1),this.dataSenders.forEach(t=>{t.stop()})}async flushImmediately(){return this.flushEvents(!1)}flushImmediatelySync(){return this.flushEvents(!0)}getQueueLength(){return this.eventsQueue.length}getQueueEvents(){return this.eventsQueue.map(({_session_id:e,...t})=>t)}async flushQueue(){await this.flushImmediately()}clearQueue(){this.eventsQueue=[]}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){a("debug","Cannot flush pending events: session not initialized - keeping in buffer",{data:{bufferedEventCount:this.pendingEventsBuffer.length}});return}const t=[...this.pendingEventsBuffer];this.pendingEventsBuffer=[],t.forEach(s=>{this.track(s)})}clearSendTimeout(){this.sendTimeoutId!==null&&(clearTimeout(this.sendTimeoutId),this.sendTimeoutId=null)}isSuccessfulResult(e){return e.status==="fulfilled"&&e.value===!0}groupQueuedEventsBySession(){const e=new Map,t=[];for(const s of this.eventsQueue){if(!s._session_id){a("debug","Queued event missing _session_id, dropping",{data:{eventId:s.id,type:s.type}}),t.push(s.id);continue}const r=e.get(s._session_id);r?r.push(s):e.set(s._session_id,[s])}return t.length>0&&this.removeProcessedEvents(t),e}buildBatchesWithIds(){const e=this.groupQueuedEventsBySession();if(e.size===0)return[];const t=[];for(const[s,r]of e)t.push({batch:this.buildBatchFromGroup(s,r),eventIds:r.map(i=>i.id)});return t}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);if(!e&&this.sendInProgress)return a("debug","Async flush skipped: send already in progress"),Promise.resolve(!1);const t=this.buildBatchesWithIds();if(t.length===0)return e?!0:Promise.resolve(!0);if(this.dataSenders.length===0){for(const{batch:s,eventIds:r}of t)this.removeProcessedEvents(r),this.emitEventsQueue(s);return this.clearSendTimeout(),e?!0:Promise.resolve(!0)}if(e&&this.sendInProgress){const s=t.reduce((r,i)=>r+i.eventIds.length,0);return this.pendingSyncFlush=!0,a("debug","Sync flush deferred: async send in-flight, will retry on settle",{data:{eventCount:s}}),!1}if(e){const s=t.map(({batch:r,eventIds:i})=>this.sendBatchSync(r,i));return this.settleSendTimeout(),s.some(Boolean)}return this.sendInProgress=!0,(async()=>{try{const s=await Promise.all(t.map(async({batch:r,eventIds:i})=>this.sendBatchAsync(r,i)));return this.settleSendTimeout(),s.some(Boolean)}finally{this.sendInProgress=!1,this.drainPendingSyncFlush()}})()}settleSendTimeout(){this.eventsQueue.length===0?this.clearSendTimeout():this.scheduleSendTimeout()}drainPendingSyncFlush(){this.pendingSyncFlush&&(this.pendingSyncFlush=!1,this.flushImmediatelySync())}sendBatchSync(e,t){const r=this.dataSenders.map(i=>i.sendEventsQueueSync(e)).some(i=>i);return r?(this.removeProcessedEvents(t),this.emitEventsQueue(e)):a("debug","Sync send complete failure, events kept in queue for retry",{data:{eventCount:t.length,sessionId:e.session_id}}),r}async sendBatchAsync(e,t){const s=this.dataSenders.map(async o=>o.sendEventsQueue(e,{onSuccess:()=>{},onFailure:()=>{}})),r=await Promise.allSettled(s),i=r.some(o=>this.isSuccessfulResult(o));if(i){this.removeProcessedEvents(t),this.emitEventsQueue(e);const o=r.filter(l=>!this.isSuccessfulResult(l)).length;o>0&&a("debug","Async send completed with some failures, removed from queue and persisted per-integration",{data:{eventCount:t.length,failedCount:o,sessionId:e.session_id}})}else a("debug","Async send complete failure, events kept in queue for retry",{data:{eventCount:t.length,sessionId:e.session_id}});return i}async sendEventsQueue(){if(!(this.eventsQueue.length===0||this.sendInProgress)){this.sendInProgress=!0;try{const e=this.buildBatchesWithIds();if(e.length===0)return;if(this.dataSenders.length===0){for(const{batch:r}of e)this.emitEventsQueue(r);return}(await Promise.all(e.map(async({batch:r,eventIds:i})=>this.sendBatchAsync(r,i)))).some(Boolean)?this.consecutiveSendFailures=0:this.consecutiveSendFailures=Math.min(this.consecutiveSendFailures+1,5),this.eventsQueue.length===0?this.clearSendTimeout():this.scheduleSendTimeout()}finally{this.sendInProgress=!1,this.drainPendingSyncFlush()}}}buildBatchFromGroup(e,t){const s=new Map,r=[];for(const u of t){const f=this.createEventSignature(u);s.has(f)||r.push(f),s.set(f,u)}const i=r.map(u=>s.get(u)).filter(u=>!!u).sort((u,f)=>u.type===d.SESSION_START&&f.type!==d.SESSION_START?-1:f.type===d.SESSION_START&&u.type!==d.SESSION_START?1:u.timestamp-f.timestamp).map(({_session_id:u,...f})=>f),o=this.get("config")?.globalMetadata,l=this.get("identity");return{user_id:this.get("userId"),session_id:e,device:this.get("device"),events:i,...o&&{global_metadata:o},...l&&{identify:l}}}buildEventPayload(e){const t=this.get("sessionId");if(!t)return a("error","buildEventPayload reached without sessionId — event dropped",{data:{type:e.type},visibility:"critical"}),null;const s=e.page_url??this.get("pageUrl"),r=typeof s=="string"&&s.length>0?s:"unknown",i=this.timeManager.now(),o=this.timeManager.validateTimestamp(i);o.valid||a("warn","Event timestamp validation failed",{data:{type:e.type,error:o.error}});const l=this.get("sessionReferrer"),c=this.get("sessionUtm");return{...{id:Zt(),type:e.type,page_url:r,timestamp:i,...l&&{referrer:l},...e.from_page_url&&{from_page_url:e.from_page_url},...e.scroll_data&&{scroll_data:e.scroll_data},...e.click_data&&{click_data:e.click_data},...e.custom_event&&{custom_event:e.custom_event},...e.web_vitals&&{web_vitals:e.web_vitals},...e.error_data&&{error_data:e.error_data},...e.page_view&&{page_view:e.page_view},...c&&{utm:c}},_session_id:t}}isDuplicateEvent(e){const t=Date.now(),s=this.createEventFingerprint(e),r=this.recentEventFingerprints.get(s);return r&&t-r<1e3?(this.recentEventFingerprints.set(s,t),!0):(this.recentEventFingerprints.set(s,t),this.recentEventFingerprints.size>1500&&this.pruneOldFingerprints(),this.recentEventFingerprints.size>3e3&&(this.recentEventFingerprints.clear(),this.recentEventFingerprints.set(s,t),a("debug","Event fingerprint cache exceeded hard limit, cleared",{data:{hardLimit:3e3}})),!1)}pruneOldFingerprints(){const e=Date.now(),t=1e3*10;for(const[s,r]of this.recentEventFingerprints.entries())e-r>t&&this.recentEventFingerprints.delete(s);a("debug","Pruned old event fingerprints",{data:{remaining:this.recentEventFingerprints.size,cutoffMs:t}})}createEventFingerprint(e){let t=`${e.type}_${e.page_url}`;if(e.click_data){const s=Math.round((e.click_data.x||0)/10)*10,r=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${s}_${r}`}return e.scroll_data&&(t+=`_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`),e.custom_event&&(t+=`_custom_${e.custom_event.name}`,e.custom_event.metadata&&(t+=`_${this.stableStringify(e.custom_event.metadata)}`)),e.web_vitals&&(t+=`_vitals_${e.web_vitals.type}`),e.error_data&&(t+=`_error_${e.error_data.type}_${e.error_data.message}`),t}createEventSignature(e){return this.createEventFingerprint(e)}stableStringify(e){return JSON.stringify(e,(t,s)=>s&&typeof s=="object"&&!Array.isArray(s)?Object.keys(s).sort().reduce((r,i)=>(r[i]=s[i],r),{}):s)}addToQueue(e){if(this.emitEvent(e),this.eventsQueue.push(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(r=>r.type!==d.SESSION_START),s=t>=0?this.eventsQueue.splice(t,1)[0]:this.eventsQueue.shift();a("warn","Event queue overflow, oldest non-critical event removed",{data:{maxLength:100,currentLength:this.eventsQueue.length,removedEventType:s?.type,wasCritical:s?.type===d.SESSION_START}})}this.scheduleSendTimeout(),this.eventsQueue.length>=50&&this.consecutiveSendFailures<5&&this.sendEventsQueue()}scheduleSendTimeout(){if(this.sendTimeoutId!==null)return;const e=this.calculateSendDelay();this.sendTimeoutId=window.setTimeout(()=>{this.sendTimeoutId=null,this.eventsQueue.length>0&&this.sendEventsQueue()},e)}calculateSendDelay(){const e=this.get("config")?.sendIntervalMs??1e4;if(this.consecutiveSendFailures===0)return e;const t=e*Math.pow(2,this.consecutiveSendFailures);return Math.min(t,12e4)}shouldSample(){const e=this.get("config")?.samplingRate??1;return Math.random()<e}checkRateLimit(){const e=Date.now();return e-this.rateLimitWindowStart>1e3&&(this.rateLimitCounter=0,this.rateLimitWindowStart=e),this.rateLimitCounter>=50?!1:(this.rateLimitCounter++,!0)}checkPerEventRateLimit(e,t){const s=Date.now(),i=(this.perEventRateLimits.get(e)??[]).filter(o=>s-o<6e4);return i.length>=t?(a("warn","Per-event rate limit exceeded for custom event",{data:{eventName:e,limit:t,window:`${6e4/1e3}s`}}),!1):(i.push(s),this.perEventRateLimits.set(e,i),!0)}getTypeLimitForEvent(e){return{[d.CLICK]:500,[d.PAGE_VIEW]:100,[d.CUSTOM]:500,[d.SCROLL]:120}[e]??null}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(s=>!t.has(s.id))}emitEvent(e){if(this.emitter){const{_session_id:t,...s}=e;this.emitter.emit(N.EVENT,s)}}emitEventsQueue(e){this.emitter&&this.emitter.emit(N.QUEUE,e)}debounce(e,t){let s=null;return((...r)=>{s!==null&&clearTimeout(s),s=setTimeout(()=>{e(...r),s=null},t)})}getInitialCounts(){return{total:0,[d.CLICK]:0,[d.PAGE_VIEW]:0,[d.CUSTOM]:0,[d.SCROLL]:0}}loadSessionCounts(e){if(typeof window>"u"||typeof localStorage>"u")return this.getInitialCounts();const t=this.get("userId")||"anonymous",s=Xe(t,e);try{const r=localStorage.getItem(s);if(!r)return this.getInitialCounts();const i=JSON.parse(r);return i._timestamp&&Date.now()-i._timestamp>Ge?(a("debug","Session counts expired, clearing",{data:{sessionId:e,age:Date.now()-i._timestamp}}),localStorage.removeItem(s),this.getInitialCounts()):typeof i.total=="number"&&typeof i[d.CLICK]=="number"&&typeof i[d.PAGE_VIEW]=="number"&&typeof i[d.CUSTOM]=="number"&&typeof i[d.SCROLL]=="number"?{total:i.total,[d.CLICK]:i[d.CLICK],[d.PAGE_VIEW]:i[d.PAGE_VIEW],[d.CUSTOM]:i[d.CUSTOM],[d.SCROLL]:i[d.SCROLL]}:(a("warn","Invalid session counts structure in localStorage, resetting",{data:{sessionId:e,parsed:i}}),localStorage.removeItem(s),a("debug","Session counts removed due to invalid/corrupted data",{data:{sessionId:e,parsed:i}}),this.getInitialCounts())}catch(r){return a("warn","Failed to load session counts from localStorage",{error:r,data:{sessionId:e}}),this.getInitialCounts()}}cleanupExpiredSessionCounts(){if(!(typeof window>"u"||typeof localStorage>"u"))try{const e=localStorage.getItem(We);if(e){const i=Date.now()-parseInt(e,10);if(i<Ke){a("debug","Skipping session counts cleanup (throttled)",{data:{timeSinceLastCleanup:i,throttleMs:Ke}});return}}const t=this.get("userId")||"anonymous",s=`${m}:${t}:session_counts:`,r=[];for(let i=0;i<localStorage.length;i++){const o=localStorage.key(i);if(o?.startsWith(s))try{const l=localStorage.getItem(o);if(l){const c=JSON.parse(l);c._timestamp&&Date.now()-c._timestamp>Ge&&r.push(o)}}catch{}}r.forEach(i=>{localStorage.removeItem(i),a("debug","Cleaned up expired session counts",{data:{key:i}})}),r.length>0&&a("info",`Cleaned up ${r.length} expired session counts entries`),localStorage.setItem(We,Date.now().toString())}catch(e){a("warn","Failed to cleanup expired session counts",{error:e})}}saveSessionCounts(e){const t=this.get("userId")||"anonymous",s=Xe(t,e);try{const r={...this.sessionEventCounts,_timestamp:Date.now(),_version:1};localStorage.setItem(s,JSON.stringify(r))}catch(r){a("warn","Failed to persist session counts to localStorage",{error:r,data:{sessionId:e}})}}}class Is{static getId(e){const t=e.getItem(ue);if(t)return t;const s=st();return e.setItem(ue,s),s}}const ws=/^\d{13}-[a-z0-9]{9}$/;class As extends E{storageManager;eventManager;projectId;activityHandler=null;visibilityChangeHandler=null;sessionTimeoutId=null;broadcastChannel=null;isTracking=!1;needsRenewal=!1;constructor(e,t,s){super(),this.storageManager=e,this.eventManager=t,this.projectId=s}initCrossTabSync(){if(typeof BroadcastChannel>"u"){a("debug","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel(It(e)),this.broadcastChannel.onmessage=t=>{const{action:s,sessionId:r,timestamp:i,projectId:o}=t.data??{};o===e&&(s==="session_start"&&r&&typeof i=="number"&&i>Date.now()-5e3?(this.set("sessionId",r),this.persistSession(r,i),this.isTracking&&this.setupSessionTimeout()):s&&s!=="session_start"&&a("debug","Ignored BroadcastChannel message with unknown action",{data:{action:s}}))}}shareSession(e){this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function"&&this.broadcastChannel.postMessage({action:"session_start",projectId:this.getProjectId(),sessionId:e,timestamp:Date.now()})}cleanupCrossTabSync(){this.broadcastChannel&&(typeof this.broadcastChannel.close=="function"&&this.broadcastChannel.close(),this.broadcastChannel=null)}recoverSession(){const e=this.loadStoredSession();if(!e)return null;if(!ws.test(e.id))return a("warn","Invalid session ID format recovered from storage, clearing",{data:{sessionId:e.id}}),this.clearStoredSession(),null;const t=this.get("config")?.sessionTimeout??9e5;return Date.now()-e.lastActivity>t?(this.clearStoredSession(),null):e.id}persistSession(e,t=Date.now(),s,r){this.saveStoredSession({id:e,lastActivity:t,...s&&{referrer:s},...r&&{utm:r}})}clearStoredSession(){const e=this.getSessionStorageKey();this.storageManager.removeItem(e)}loadStoredSession(){const e=this.getSessionStorageKey(),t=this.storageManager.getItem(e);if(t!==null)try{const r=JSON.parse(t);if(r.id&&typeof r.lastActivity=="number")return r}catch{this.storageManager.removeItem(e)}const s=this.storageManager.getSessionItem(e);if(s!==null)try{const r=JSON.parse(s);if(r.id&&typeof r.lastActivity=="number")return r}catch{this.storageManager.removeSessionItem(e)}return null}saveStoredSession(e){const t=this.getSessionStorageKey(),s=JSON.stringify(e);this.storageManager.setItem(t,s),this.storageManager.setSessionItem(t,s)}getSessionStorageKey(){return yt(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){a("debug","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId();let s,r;if(e){const i=this.loadStoredSession();s=i?.referrer??_e(),r=i?.utm??ve()}else s=_e(),r=ve();a("debug","Session tracking initialized",{data:{sessionId:t,wasRecovered:!!e,willEmitSessionStart:!e,sessionReferrer:s,hasUtm:!!r}}),this.isTracking=!0;try{this.set("sessionId",t),this.set("sessionReferrer",s),this.set("sessionUtm",r),this.persistSession(t,Date.now(),s,r),this.initCrossTabSync(),this.shareSession(t),e?a("debug","Session recovered, skipping SESSION_START",{data:{sessionId:t}}):(a("debug","Emitting SESSION_START event",{data:{sessionId:t}}),this.eventManager.track({type:d.SESSION_START})),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}catch(i){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),i}}generateSessionId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}setupSessionTimeout(){this.clearSessionTimeout();const e=this.get("config")?.sessionTimeout??9e5;this.sessionTimeoutId=setTimeout(()=>{this.enterRenewalMode()},e)}resetSessionTimeout(){this.setupSessionTimeout();const e=this.get("sessionId");e&&this.persistSession(e,Date.now(),this.get("sessionReferrer"),this.get("sessionUtm"))}clearSessionTimeout(){this.sessionTimeoutId&&(clearTimeout(this.sessionTimeoutId),this.sessionTimeoutId=null)}setupActivityListeners(){this.activityHandler=()=>{this.needsRenewal?this.renewSession():this.resetSessionTimeout()},document.addEventListener("click",this.activityHandler,{passive:!0}),document.addEventListener("keydown",this.activityHandler,{passive:!0}),document.addEventListener("scroll",this.activityHandler,{passive:!0})}renewSession(){this.needsRenewal=!1;const e=this.generateSessionId(),t=_e(),s=ve();a("debug","Renewing session after timeout",{data:{newSessionId:e}}),this.set("sessionId",e),this.set("sessionReferrer",t),this.set("sessionUtm",s),this.persistSession(e,Date.now(),t,s),this.cleanupCrossTabSync(),this.initCrossTabSync(),this.shareSession(e),this.eventManager.track({type:d.SESSION_START}),this.eventManager.flushPendingEvents(),this.setupSessionTimeout()}cleanupActivityListeners(){this.activityHandler&&(document.removeEventListener("click",this.activityHandler),document.removeEventListener("keydown",this.activityHandler),document.removeEventListener("scroll",this.activityHandler),this.activityHandler=null)}setupLifecycleListeners(){this.visibilityChangeHandler||(this.visibilityChangeHandler=()=>{if(document.hidden)this.clearSessionTimeout();else{if(this.isSessionStale()){a("debug","Session expired during suspend, entering renewal mode"),this.enterRenewalMode();return}this.get("sessionId")&&this.setupSessionTimeout()}},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}isSessionStale(){if(this.needsRenewal||!this.get("sessionId"))return!1;const t=this.loadStoredSession();if(!t)return!1;const s=this.get("config")?.sessionTimeout??9e5;return Date.now()-t.lastActivity>s}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null)}enterRenewalMode(){this.clearSessionTimeout(),this.cleanupCrossTabSync(),this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.set("sessionReferrer",void 0),this.set("sessionUtm",void 0),this.needsRenewal=!0,a("debug","Session timed out, entering renewal mode")}resetSessionState(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.set("sessionReferrer",void 0),this.set("sessionUtm",void 0),this.needsRenewal=!1,this.isTracking=!1}stopTracking(){this.resetSessionState()}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.isTracking=!1,this.needsRenewal=!1,this.set("hasStartSession",!1)}}class Ms extends E{eventManager;storageManager;sessionManager=null;destroyed=!1;constructor(e,t){super(),this.eventManager=t,this.storageManager=e}startTracking(){if(this.isActive())return;if(this.destroyed){a("debug","Cannot start tracking on destroyed handler");return}const t=this.get("config")?.integrations?.tracelog?.projectId??"custom";try{this.sessionManager=new As(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(s){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw a("error","Failed to start session tracking",{error:s}),s}}isActive(){return this.sessionManager!==null&&!this.destroyed}cleanupSessionManager(){this.sessionManager&&(this.sessionManager.stopTracking(),this.sessionManager.destroy(),this.sessionManager=null)}stopTracking(){this.cleanupSessionManager()}destroy(){this.destroyed||(this.sessionManager&&(this.sessionManager.destroy(),this.sessionManager=null),this.destroyed=!0)}}class Ls extends E{eventManager;onTrack;originalPushState;originalReplaceState;lastPageViewTime=0;constructor(e,t){super(),this.eventManager=e,this.onTrack=t}startTracking(){this.trackInitialPageView(),window.addEventListener("popstate",this.trackCurrentPage,!0),window.addEventListener("hashchange",this.trackCurrentPage,!0),this.patchHistory("pushState"),this.patchHistory("replaceState")}stopTracking(){window.removeEventListener("popstate",this.trackCurrentPage,!0),window.removeEventListener("hashchange",this.trackCurrentPage,!0),this.originalPushState&&(window.history.pushState=this.originalPushState),this.originalReplaceState&&(window.history.replaceState=this.originalReplaceState),this.lastPageViewTime=0}patchHistory(e){const t=window.history[e];e==="pushState"&&!this.originalPushState?this.originalPushState=t:e==="replaceState"&&!this.originalReplaceState&&(this.originalReplaceState=t),window.history[e]=(...s)=>{t.apply(window.history,s),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=ye(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;const s=Date.now(),r=this.get("config").pageViewThrottleMs??1e3;if(s-this.lastPageViewTime<r)return;this.lastPageViewTime=s,this.onTrack();const i=this.get("pageUrl");this.set("pageUrl",t);const o=this.extractPageViewData();this.eventManager.track({type:d.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:i,...o&&{page_view:o}}),this.get("config").flushOnSpaNavigation===!0&&this.eventManager.flushImmediately()};trackInitialPageView(){const e=ye(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.lastPageViewTime=Date.now(),this.eventManager.track({type:d.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{referrer:e}=document,{title:t}=document;if(!(!e&&!t))return{...e&&{referrer:e},...t&&{title:t}}}}class bs extends E{eventManager;lastClickTimes=new Map;clickHandler;lastPruneTime=0;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,s=t.target,r=typeof HTMLElement<"u"&&s instanceof HTMLElement?s:typeof HTMLElement<"u"&&s instanceof Node&&s.parentElement instanceof HTMLElement?s.parentElement:null;if(!r){a("debug","Click target not found or not an element");return}if(this.shouldIgnoreElement(r))return;const i=this.get("config")?.clickThrottleMs??300;if(i>0&&!this.checkClickThrottle(r,i))return;const o=this.findTrackingElement(r),l=this.getRelevantClickElement(r),c=this.calculateClickCoordinates(t);if(o){const f=this.extractTrackingData(o);if(f){const p=this.createCustomEventData(f);this.eventManager.track({type:d.CUSTOM,custom_event:{name:p.name,...p.value&&{metadata:{value:p.value}}}})}}if(!c){a("debug","Click skipped: invalid coordinates (likely synthetic)");return}const u=this.generateClickData(r,l,c);this.eventManager.track({type:d.CLICK,click_data:u})},window.addEventListener("click",this.clickHandler,!0))}stopTracking(){this.clickHandler&&(window.removeEventListener("click",this.clickHandler,!0),this.clickHandler=void 0),this.lastClickTimes.clear(),this.lastPruneTime=0}shouldIgnoreElement(e){return e.hasAttribute(`${L}-ignore`)?!0:e.closest(`[${L}-ignore]`)!==null}checkClickThrottle(e,t){const s=this.getElementSignature(e),r=Date.now();this.pruneThrottleCache(r);const i=this.lastClickTimes.get(s);return i!==void 0&&r-i<t?(a("debug","ClickHandler: Click suppressed by throttle",{data:{signature:s,throttleRemaining:t-(r-i)}}),!1):(this.lastClickTimes.set(s,r),!0)}pruneThrottleCache(e){if(e-this.lastPruneTime<3e4)return;this.lastPruneTime=e;const t=e-3e5;for(const[s,r]of this.lastClickTimes.entries())r<t&&this.lastClickTimes.delete(s);if(this.lastClickTimes.size>1e3){const s=Array.from(this.lastClickTimes.entries()).sort((o,l)=>o[1]-l[1]),r=this.lastClickTimes.size-1e3,i=s.slice(0,r);for(const[o]of i)this.lastClickTimes.delete(o);a("debug","ClickHandler: Pruned throttle cache",{data:{removed:i.length,remaining:this.lastClickTimes.size}})}}getElementSignature(e){if(e.id)return`#${e.id}`;const t=e.getAttribute("data-testid");if(t)return`[data-testid="${t}"]`;const s=e.getAttribute(`${L}-name`);return s?`[${L}-name="${s}"]`:this.getElementPath(e)}getElementPath(e){const t=[];let s=e;for(;s&&s!==document.body;){let r=s.tagName.toLowerCase();if(s.className){const i=s.className.split(" ")[0];i&&(r+=`.${i}`)}t.unshift(r),s=s.parentElement}return t.join(">")||"unknown"}findTrackingElement(e){return e.hasAttribute(`${L}-name`)?e:e.closest(`[${L}-name]`)}getRelevantClickElement(e){for(const t of Et)try{if(e.matches(t))return e;const s=e.closest(t);if(s)return s}catch(s){a("debug","Invalid selector in element search",{error:s,data:{selector:t}});continue}return e}calculateClickCoordinates(e){const t=e.clientX,s=e.clientY;return typeof t!="number"||typeof s!="number"||!Number.isFinite(t)||!Number.isFinite(s)||t===0&&s===0&&!e.isTrusted?null:{x:t,y:s}}extractTrackingData(e){const t=e.getAttribute(`${L}-name`),s=e.getAttribute(`${L}-value`);if(t)return{element:e,name:t,...s&&{value:s}}}generateClickData(e,t,s){const{x:r,y:i}=s,o=this.getRelevantText(e,t),l=t.getAttribute("href")??void 0;return{x:r,y:i,tag:t.tagName.toLowerCase(),...t.id&&{id:t.id},...t.className&&{class:t.className},...o&&{text:o},...l&&{href:l}}}getRelevantText(e,t){const s=e.textContent?.trim()??"",r=t.textContent?.trim()??"";if(!s&&!r)return"";let i="";return s&&s.length<=255?i=s:r.length<=255?i=r:i=r.slice(0,252)+"...",te(i)}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class Rs extends E{eventManager;containers=[];limitWarningLogged=!1;containerDiscoveryTimeoutId=null;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.set("scrollEventCount",0),this.tryDetectScrollContainers(0)}stopTracking(){this.containerDiscoveryTimeoutId!==null&&(clearTimeout(this.containerDiscoveryTimeoutId),this.containerDiscoveryTimeoutId=null);for(const e of this.containers)this.clearContainerTimer(e),e.element===window?window.removeEventListener("scroll",e.listener):e.element.removeEventListener("scroll",e.listener);this.containers.length=0,this.set("scrollEventCount",0),this.limitWarningLogged=!1}tryDetectScrollContainers(e){const t=this.findScrollableElements();if(this.isWindowScrollable()&&this.setupScrollContainer(window,"window"),t.length>0){for(const s of t){const r=this.getElementSelector(s);this.setupScrollContainer(s,r)}return}if(e<5){this.containerDiscoveryTimeoutId=window.setTimeout(()=>{this.containerDiscoveryTimeoutId=null,this.tryDetectScrollContainers(e+1)},200);return}this.containers.length===0&&this.setupScrollContainer(window,"window")}findScrollableElements(){if(!document.body)return[];const e=[],t=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const i=r;if(!i.isConnected||!i.offsetParent)return NodeFilter.FILTER_SKIP;const o=getComputedStyle(i);return o.overflowY==="auto"||o.overflowY==="scroll"||o.overflow==="auto"||o.overflow==="scroll"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});let s;for(;(s=t.nextNode())&&e.length<10;){const r=s;this.isElementScrollable(r)&&e.push(r)}return e}getElementSelector(e){if(e===window)return"window";const t=e;if(t.id)return`#${t.id}`;if(t.className&&typeof t.className=="string"){const s=t.className.split(" ").filter(r=>r.trim())[0];if(s)return`.${s}`}return t.tagName.toLowerCase()}setupScrollContainer(e,t){if(this.containers.some(c=>c.element===e)||e!==window&&!this.isElementScrollable(e))return;const r=this.getScrollTop(e),i=this.calculateScrollDepth(r,this.getScrollHeight(e),this.getViewportHeight(e)),o={element:e,selector:t,lastScrollPos:r,lastDepth:i,lastEventTime:0,debounceTimer:null,listener:null},l=()=>{this.get("suppressNextScroll")||(this.clearContainerTimer(o),o.debounceTimer=window.setTimeout(()=>{const c=this.calculateScrollData(o);c&&this.processScrollEvent(o,c,Date.now()),o.debounceTimer=null},250))};o.listener=l,this.containers.push(o),e===window?window.addEventListener("scroll",l,{passive:!0}):e.addEventListener("scroll",l,{passive:!0})}processScrollEvent(e,t,s){if(!this.shouldEmitScrollEvent(e,t,s))return;e.lastEventTime=s,e.lastDepth=t.depth;const r=this.get("scrollEventCount")??0;this.set("scrollEventCount",r+1),this.eventManager.track({type:d.SCROLL,scroll_data:{...t,container_selector:e.selector}})}shouldEmitScrollEvent(e,t,s){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,s)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=120}hasElapsedMinimumInterval(e,t){return e.lastEventTime===0?!0:t-e.lastEventTime>=500}hasSignificantDepthChange(e,t){return Math.abs(t-e.lastDepth)>=5}logLimitOnce(){this.limitWarningLogged||(this.limitWarningLogged=!0,a("debug","Max scroll events per session reached",{data:{limit:120}}))}isWindowScrollable(){return document.documentElement.scrollHeight>window.innerHeight}clearContainerTimer(e){e.debounceTimer!==null&&(clearTimeout(e.debounceTimer),e.debounceTimer=null)}getScrollDirection(e,t){return e>t?Q.DOWN:Q.UP}calculateScrollDepth(e,t,s){if(t<=s)return 0;const r=t-s;return Math.min(100,Math.max(0,Math.floor(e/r*100)))}calculateScrollData(e){const{element:t,lastScrollPos:s}=e,r=this.getScrollTop(t);if(Math.abs(r-s)<10||t===window&&!this.isWindowScrollable())return null;const o=this.getViewportHeight(t),l=this.getScrollHeight(t),c=this.getScrollDirection(r,s),u=this.calculateScrollDepth(r,l,o);return e.lastScrollPos=r,{depth:u,direction:c}}getScrollTop(e){return e===window?window.scrollY:e.scrollTop}getViewportHeight(e){return e===window?window.innerHeight:e.clientHeight}getScrollHeight(e){return e===window?document.documentElement.scrollHeight:e.scrollHeight}isElementScrollable(e){const t=getComputedStyle(e),s=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflow==="auto"||t.overflow==="scroll",r=e.scrollHeight>e.clientHeight;return s&&r}}const Ns="tracelog_session_id",Cs="tracelog_user_id";class Os extends E{visibilityHandler=null;pageshowHandler=null;lastSyncedKey=null;activate(){this.cleanupListeners(),this.syncCartAttribute(),this.setupListeners()}deactivate(){this.cleanupListeners(),this.lastSyncedKey=null}onSessionChange(){this.syncCartAttribute()}syncCartAttribute(){const e=this.get("sessionId");if(!e)return;const t=this.get("userId"),s=typeof t=="string"&&t.length>0?t:"",r=`${e}|${s}`;r!==this.lastSyncedKey&&(this.lastSyncedKey=r,this.postCartUpdate(e,s))}postCartUpdate(e,t){const s={[Ns]:e};t.length>0&&(s[Cs]=t);try{fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:s}),credentials:"same-origin"}).then(r=>{r.ok||(this.lastSyncedKey=null,a("debug","Shopify cart attribute update failed",{data:{status:r.status}}))}).catch(()=>{this.lastSyncedKey=null,a("debug","Shopify cart attribute update failed")})}catch{this.lastSyncedKey=null,a("debug","Shopify cart attribute update failed")}}setupListeners(){this.visibilityHandler=()=>{document.hidden||this.syncCartAttribute()},document.addEventListener("visibilitychange",this.visibilityHandler),this.pageshowHandler=e=>{e.persisted&&this.syncCartAttribute()},window.addEventListener("pageshow",this.pageshowHandler)}cleanupListeners(){this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.pageshowHandler&&(window.removeEventListener("pageshow",this.pageshowHandler),this.pageshowHandler=null)}}class Ps{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||a("debug","localStorage not available, using memory fallback"),this.sessionStorageRef||a("debug","sessionStorage not available, using memory fallback")}getItem(e){try{return this.storage?this.storage.getItem(e):this.fallbackStorage.get(e)??null}catch{return this.fallbackStorage.get(e)??null}}setItem(e,t){if(this.fallbackStorage.set(e,t),!!this.storage)try{this.storage.setItem(e,t);return}catch(s){if(!(s instanceof DOMException&&s.name==="QuotaExceededError"||s instanceof Error&&s.name==="QuotaExceededError"))return;if(a("warn","localStorage quota exceeded, attempting cleanup",{data:{key:e,valueSize:t.length}}),!this.cleanupOldData()){a("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:s,data:{key:e,valueSize:t.length}});return}try{this.storage.setItem(e,t)}catch(i){a("error","localStorage quota exceeded even after cleanup - data will not persist",{error:i,data:{key:e,valueSize:t.length}})}}}removeItem(e){try{this.storage&&this.storage.removeItem(e)}catch{}this.fallbackStorage.delete(e)}cleanupOldData(){if(!this.storage)return!1;try{const e=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],t=[],s=[];for(let i=0;i<this.storage.length;i++){const o=this.storage.key(i);o?.startsWith("tracelog_")&&(o.startsWith("tracelog_persisted_events_")?t.push(o):e.some(l=>o.startsWith(l))||s.push(o))}const r=[...t,...s.slice(0,5)];return r.length===0?!1:(r.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0)}catch(e){return a("error","Failed to cleanup old data",{error:e}),!1}}initializeStorage(e){if(typeof window>"u")return null;try{const t=e==="localStorage"?window.localStorage:window.sessionStorage,s="__tracelog_test__";return t.setItem(s,"test"),t.removeItem(s),t}catch{return null}}getSessionItem(e){try{return this.sessionStorageRef?this.sessionStorageRef.getItem(e):this.fallbackSessionStorage.get(e)??null}catch{return this.fallbackSessionStorage.get(e)??null}}setSessionItem(e,t){this.fallbackSessionStorage.set(e,t);try{if(this.sessionStorageRef){this.sessionStorageRef.setItem(e,t);return}}catch(s){(s instanceof DOMException&&s.name==="QuotaExceededError"||s instanceof Error&&s.name==="QuotaExceededError")&&a("error","sessionStorage quota exceeded - data will not persist",{error:s,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class Ds extends E{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds;navigationCounter=0;constructor(e){super(),this.eventManager=e,this.vitalThresholds=Te(J)}async startTracking(){const e=this.get("config"),t=e?.webVitalsMode??J;this.vitalThresholds=Te(t),e?.webVitalsThresholds&&(this.vitalThresholds={...this.vitalThresholds,...e.webVitalsThresholds}),await this.initWebVitals()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(s){a("debug","Failed to disconnect performance observer",{error:s,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear(),this.navigationHistory.length=0}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",s=>{const r=s.getEntries(),i=r[r.length-1];i&&this.sendVital({type:"LCP",value:Number(i.startTime.toFixed(2))})},{type:"largest-contentful-paint",buffered:!0},!0);let e=0,t=this.getNavigationId();this.safeObserve("layout-shift",s=>{const r=this.getNavigationId();r!==t&&(e=0,t=r);const i=s.getEntries();for(const o of i){if(o.hadRecentInput===!0)continue;const l=typeof o.value=="number"?o.value:0;e+=l}this.sendVital({type:"CLS",value:Number(e.toFixed(2))})},{type:"layout-shift",buffered:!0}),this.safeObserve("paint",s=>{for(const r of s.getEntries())r.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(r.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",s=>{let r=0;const i=s.getEntries();for(const o of i){const l=(o.processingEnd??0)-(o.startTime??0);r=Math.max(r,l)}r>0&&this.sendVital({type:"INP",value:Number(r.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:s,onTTFB:r,onINP:i}=await Promise.resolve().then(()=>qs),o=l=>c=>{const u=Number(c.value.toFixed(2));this.sendVital({type:l,value:u})};e(o("LCP"),{reportAllChanges:!1}),t(o("CLS"),{reportAllChanges:!1}),s(o("FCP"),{reportAllChanges:!1}),r(o("TTFB"),{reportAllChanges:!1}),i(o("INP"),{reportAllChanges:!1})}catch(e){a("debug","Failed to load web-vitals library, using fallback",{error:e}),this.observeWebVitalsFallback()}}reportTTFB(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return;const t=e.responseStart;typeof t=="number"&&Number.isFinite(t)&&this.sendVital({type:"TTFB",value:Number(t.toFixed(2))})}catch(e){a("debug","Failed to report TTFB",{error:e})}}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const s=this.reportedByNav.get(t);if(s?.has(e.type))return;if(s)s.add(e.type);else if(this.reportedByNav.set(t,new Set([e.type])),this.navigationHistory.push(t),this.navigationHistory.length>Kt){const i=this.navigationHistory.shift();i&&this.reportedByNav.delete(i)}}this.trackWebVital(e.type,e.value)}trackWebVital(e,t){if(!Number.isFinite(t)){a("debug","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:d.WEB_VITALS,web_vitals:{type:e,value:t}})}getNavigationId(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return null;const t=e.startTime||performance.now(),s=++this.navigationCounter,r=`${t.toFixed(2)}_${window.location.pathname}`;return s>1?`${r}_${s}`:r}catch(e){return a("debug","Failed to get navigation ID",{error:e}),null}}isObserverSupported(e){if(typeof PerformanceObserver>"u")return!1;const t=PerformanceObserver.supportedEntryTypes;return!t||t.includes(e)}safeObserve(e,t,s,r=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((o,l)=>{try{t(o,l)}catch(c){a("debug","Observer callback failed",{error:c,data:{type:e}})}if(r)try{l.disconnect()}catch{}});return i.observe(s??{type:e,buffered:!0}),r||this.observers.push(i),!0}catch(i){return a("debug","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return a("debug","Invalid web vital value",{data:{type:e,value:t}}),!1;const s=this.vitalThresholds[e];return!(typeof s=="number"&&t<=s)}}class se extends E{eventManager;emitter;recentErrors=new Map;pageviewSignatureCounts=new Map;errorBurstCounter=0;burstWindowStart=0;burstBackoffUntil=0;pagehideHandler=null;pageviewResetListener=null;constructor(e,t){super(),this.eventManager=e,this.emitter=t}startTracking(){window.addEventListener("error",this.handleError),window.addEventListener("unhandledrejection",this.handleRejection),this.pagehideHandler=()=>{this.resetPageviewCounter()},window.addEventListener("pagehide",this.pagehideHandler,{passive:!0}),this.emitter&&(this.pageviewResetListener=e=>{(e.type===d.SESSION_START||e.type===d.PAGE_VIEW)&&this.resetPageviewCounter()},this.emitter.on(N.EVENT,this.pageviewResetListener))}stopTracking(){window.removeEventListener("error",this.handleError),window.removeEventListener("unhandledrejection",this.handleRejection),this.pagehideHandler&&(window.removeEventListener("pagehide",this.pagehideHandler),this.pagehideHandler=null),this.emitter&&this.pageviewResetListener&&(this.emitter.off(N.EVENT,this.pageviewResetListener),this.pageviewResetListener=null),this.recentErrors.clear(),this.pageviewSignatureCounts.clear(),this.errorBurstCounter=0,this.burstWindowStart=0,this.burstBackoffUntil=0}resetPageviewCounter(){this.pageviewSignatureCounts.clear()}shouldSample(){const e=Date.now();if(e<this.burstBackoffUntil)return!1;if(e-this.burstWindowStart>Ht&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>xt)return this.burstBackoffUntil=e+Ze,a("debug","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:Ze}}),!1;const s=this.get("config").errorSampling??Je;return Math.random()<s}shouldThrottleBySignature(e){const t=Es({message:e.message,filename:e.filename,line:e.line}),s=this.pageviewSignatureCounts.get(t)??0;if(s>=$t)return a("debug","Error throttled (pageview cap)",{data:{signature:t,count:s}}),!0;const r=s+1;return this.pageviewSignatureCounts.set(t,r),this.pageviewSignatureCounts.size>Bt&&(this.pageviewSignatureCounts.clear(),this.pageviewSignatureCounts.set(t,r)),!1}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");if(this.shouldSuppressError(U.JS_ERROR,t)||this.shouldThrottleBySignature({message:t,filename:e.filename,line:e.lineno}))return;const s=typeof e.error?.stack=="string"?this.truncateStack(e.error.stack):void 0,r=typeof e.error?.name=="string"&&e.error.name!=="Error"?e.error.name:void 0;this.eventManager.track({type:d.ERROR,error_data:{type:U.JS_ERROR,message:t,...r!==void 0&&{name:r},...e.filename!==""&&{filename:e.filename},...e.lineno!==0&&{line:e.lineno},...e.colno!==0&&{column:e.colno},...s!==void 0&&{stack:s}}})};handleRejection=e=>{if(!this.shouldSample())return;const t=this.extractRejectionMessage(e.reason),s=this.sanitize(t);if(this.shouldSuppressError(U.PROMISE_REJECTION,s)||this.shouldThrottleBySignature({message:s}))return;const r=e.reason instanceof Error&&typeof e.reason.stack=="string"?this.truncateStack(e.reason.stack):void 0,i=e.reason instanceof Error&&e.reason.name!=="Error"?e.reason.name:void 0;this.eventManager.track({type:d.ERROR,error_data:{type:U.PROMISE_REJECTION,message:s,...i!==void 0&&{name:i},...r!==void 0&&{stack:r}}})};extractRejectionMessage(e){if(e==null)return"Unknown rejection";if(typeof e=="string")return e;if(e instanceof Error)return e.message;if(typeof e=="object"&&"message"in e)return String(e.message);try{return JSON.stringify(e)}catch{return"Unserializable rejection"}}sanitize(e){const t=e.length>Qe?e.slice(0,Qe)+"...":e;return te(t)}shouldSuppressError(e,t){const s=Date.now(),r=`${e}:${t}`,i=this.recentErrors.get(r);return i!==void 0&&s-i<qe?(this.recentErrors.set(r,s),!0):(this.recentErrors.set(r,s),this.recentErrors.size>Vt?(this.recentErrors.clear(),this.recentErrors.set(r,s),!1):(this.recentErrors.size>q&&this.pruneOldErrors(),!1))}static TRUNCATION_SUFFIX=`
2
- ...truncated`;truncateStack(e){if(e.length<=Ye)return te(e);const t=Ye-se.TRUNCATION_SUFFIX.length,s=e.slice(0,t)+se.TRUNCATION_SUFFIX;return te(s)}pruneOldErrors(){const e=Date.now();for(const[r,i]of this.recentErrors.entries())e-i>qe&&this.recentErrors.delete(r);if(this.recentErrors.size<=q)return;const t=Array.from(this.recentErrors.entries()).sort((r,i)=>r[1]-i[1]),s=this.recentErrors.size-q;for(let r=0;r<s;r+=1){const i=t[r];i&&this.recentErrors.delete(i[0])}}}class ks extends E{isInitialized=!1;suppressNextScrollTimer=null;pageUnloadHandler=null;pageShowHandler=null;visibilityFlushHandler=null;emitter=new ds;managers={};handlers={};integrationInstances={};get initialized(){return this.isInitialized}async init(e={}){if(this.isInitialized)return{sessionId:this.get("sessionId")??""};this.managers.storage=new Ps;try{return this.setupState(e),this.managers.event=new ys(this.managers.storage,this.emitter),this.loadPersistedIdentity(),this.initializeHandlers(),this.setupPageLifecycleListeners(),await this.managers.event.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0,{sessionId:this.get("sessionId")??""}}catch(t){this.destroy(!0);const s=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${s}`)}}sendCustomEvent(e,t,s){if(!this.managers.event){a("warn","Cannot send custom event: TraceLog not initialized",{data:{name:e}});return}let r=t;t&&typeof t=="object"&&!Array.isArray(t)&&Object.getPrototypeOf(t)!==Object.prototype&&(r=Object.assign({},t));const{valid:i,error:o,sanitizedMetadata:l}=us(e,r);if(!i){if(this.get("mode")===X.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${o}`);a("warn",`Custom event "${e}" dropped: ${o}`);return}this.managers.event.track({type:d.CUSTOM,custom_event:{name:e,...l&&{metadata:l}}}),s?.critical===!0&&(this.managers.event.flushImmediatelySync()||a("debug","Critical event flush returned false (deferred to in-flight send or empty queue)",{data:{name:e}}))}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}destroy(e=!1){!this.isInitialized&&!e||(Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(s){a("warn","Failed to stop tracking",{error:s})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.pageUnloadHandler&&(window.removeEventListener("pagehide",this.pageUnloadHandler),window.removeEventListener("beforeunload",this.pageUnloadHandler),this.pageUnloadHandler=null),this.pageShowHandler&&(window.removeEventListener("pageshow",this.pageShowHandler),this.pageShowHandler=null),this.visibilityFlushHandler&&(document.removeEventListener("visibilitychange",this.visibilityFlushHandler),this.visibilityFlushHandler=null),this.managers.event?.flushImmediatelySync(),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.set("suppressNextScroll",!1),this.set("sessionId",null),this.set("identity",void 0),this.clearPersistedIdentity(),this.integrationInstances.shopifyCartLinker?.deactivate(),this.integrationInstances={},this.isInitialized=!1,this.handlers={},this.managers={})}setupState(e={}){this.set("config",e);const t=Is.getId(this.managers.storage);this.set("userId",t);const s=ss(e);this.set("collectApiUrls",s);const r=Ft();this.set("device",r);const i=ye(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i),Yt()&&this.set("mode",X.QA)}getConfig(){return this.get("config")}getCollectApiUrls(){return this.get("collectApiUrls")}getEventManager(){return this.managers.event}getSessionId(){return this.get("sessionId")}getUserId(){return this.get("userId")}identify(e,t){if(!e||typeof e!="string"||e.trim().length===0){a("warn","identify() called with invalid userId",{data:{type:typeof e,length:typeof e=="string"?e.trim().length:0}});return}if(e.trim().length>256){a("warn","identify() userId exceeds 256 characters",{data:{length:e.trim().length}});return}const s=e.trim(),r=Ae(t),i={userId:s,...r?{traits:r}:{}};this.set("identity",i),this.persistIdentity(i),a("debug","Visitor identified",{data:{userIdLength:s.length,traitKeys:r?Object.keys(r):[]}})}async resetIdentity(){await this.managers.event?.flushImmediately().catch(t=>(a("debug","Failed to flush before identity reset",{error:t}),!1)),this.set("identity",void 0),this.clearPersistedIdentity();const e=st();this.managers.storage.setItem(ue,e),this.set("userId",e),this.set("hasStartSession",!1),this.set("sessionId",null),this.handlers.session?.stopTracking(),this.handlers.session?.startTracking(),a("debug","Identity reset, new UUID generated")}getProjectId(){return this.get("config")?.integrations?.tracelog?.projectId??"custom"}persistIdentity(e){try{const t=this.getProjectId(),s=fe(t);this.managers.storage.setItem(s,JSON.stringify(e))}catch{a("debug","Failed to persist identity to localStorage")}}loadPersistedIdentity(){const e=this.managers.storage,t=this.getProjectId(),s=fe(t);try{const r=e.getItem(D);if(r){const i=JSON.parse(r);if(e.removeItem(D),!this.isValidIdentityData(i)){a("debug","Invalid pending identity in localStorage, discarded");return}const o=this.normalizePersistedIdentity(i);e.setItem(s,JSON.stringify(o)),this.set("identity",o),a("debug","Migrated pending identity to project-scoped key");return}}catch{e.removeItem(D)}try{const r=e.getItem(s);if(r){const i=JSON.parse(r);if(!this.isValidIdentityData(i)){e.removeItem(s),a("debug","Invalid persisted identity in localStorage, discarded");return}const o=this.normalizePersistedIdentity(i);this.set("identity",o),a("debug","Loaded persisted identity")}}catch{a("debug","Failed to load persisted identity")}}isValidIdentityData(e){if(!e||typeof e!="object")return!1;const{userId:t}=e;return!(typeof t!="string"||t.trim().length===0||t.trim().length>256)}normalizePersistedIdentity(e){const t=Ae(e.traits);return{userId:e.userId.trim(),...t?{traits:t}:{}}}clearPersistedIdentity(){try{const e=this.managers.storage,t=this.getProjectId();e.removeItem(fe(t)),e.removeItem(D)}catch{a("debug","Failed to clear persisted identity")}}setupPageLifecycleListeners(){this.pageUnloadHandler=()=>{this.managers.event?.flushImmediatelySync()},this.pageShowHandler=e=>{e.persisted&&this.managers.event?.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events on bfcache restore",{error:t})})},this.visibilityFlushHandler=()=>{typeof document>"u"||!document.hidden||this.get("config").flushOnPageHidden!==!1&&this.managers.event?.flushImmediatelySync()},window.addEventListener("pagehide",this.pageUnloadHandler),window.addEventListener("beforeunload",this.pageUnloadHandler),window.addEventListener("pageshow",this.pageShowHandler),document.addEventListener("visibilitychange",this.visibilityFlushHandler)}initializeHandlers(){const e=this.get("config");this.handlers.session=new Ms(this.managers.storage,this.managers.event),this.handlers.session.startTracking();const t=()=>{this.set("suppressNextScroll",!0),this.suppressNextScrollTimer&&clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=window.setTimeout(()=>{this.set("suppressNextScroll",!1)},500)};if(this.handlers.pageView=new Ls(this.managers.event,t),this.handlers.pageView.startTracking(),this.handlers.click=new bs(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new Rs(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new Ds(this.managers.event),this.handlers.performance.startTracking().catch(s=>{a("warn","Failed to start performance tracking",{error:s})}),this.handlers.error=new se(this.managers.event,this.emitter),this.handlers.error.startTracking(),e.integrations?.tracelog?.shopify){const s=new Os;s.activate(),this.integrationInstances.shopifyCartLinker=s,this.emitter.on(N.EVENT,r=>{r.type===d.SESSION_START&&s.onSessionChange()})}}}const C=[];let g=null,V=!1,M=!1,O=null;const Us={init:async n=>typeof window>"u"||typeof document>"u"?{sessionId:""}:(M=!1,window.__traceLogDisabled===!0?{sessionId:""}:g?{sessionId:g.getSessionId()??""}:(V&&O||(V=!0,O=(async()=>{try{const e=os(n??{}),t=new ks;try{C.forEach(({event:o,callback:l})=>{t.on(o,l)}),C.length=0;const s=t.init(e),r=new Promise((o,l)=>{setTimeout(()=>{l(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)}),i=await Promise.race([s,r]);return g=t,i}catch(s){try{t.destroy(!0)}catch(r){a("error","Failed to cleanup partially initialized app",{error:r})}throw s}}catch(e){throw g=null,e}finally{V=!1,O=null}})()),O)),event:(n,e,t)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(M)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");g.sendCustomEvent(n,e,t)}},on:(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g||V){C.push({event:n,callback:e});return}g.on(n,e)}},off:(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g){const t=C.findIndex(s=>s.event===n&&s.callback===e);t!==-1&&C.splice(t,1);return}g.off(n,e)}},isInitialized:()=>typeof window>"u"||typeof document>"u"?!1:g!==null,getSessionId:()=>typeof window>"u"||typeof document>"u"||!g?null:g.getSessionId(),getUserId:()=>typeof window>"u"||typeof document>"u"||!g?null:g.getUserId(),destroy:()=>{if(!(typeof window>"u"||typeof document>"u")){if(M)throw new Error("[TraceLog] Destroy operation already in progress");if(!g){M=!1;return}M=!0;try{g.destroy(),g=null,V=!1,O=null,C.length=0,M=!1}catch(n){g=null,V=!1,O=null,C.length=0,M=!1,a("warn","Error during destroy, forced cleanup completed",{error:n})}}},identify:(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!n||typeof n!="string"||n.trim().length===0){a("warn","identify() called with invalid userId");return}if(n.trim().length>256){a("warn","identify() userId exceeds 256 characters");return}if(M){a("warn","Cannot identify while TraceLog is being destroyed");return}if(g){g.identify(n,e);return}try{const t=Ae(e),s={userId:n.trim(),...t?{traits:t}:{}};localStorage.setItem(D,JSON.stringify(s)),a("debug","Identity persisted pre-init (will be applied on init)")}catch{a("debug","Failed to persist pre-init identity")}}},resetIdentity:async()=>{if(!(typeof window>"u"||typeof document>"u")){if(!g){try{localStorage.removeItem(D)}catch{}return}if(M)throw new Error("[TraceLog] Cannot reset identity while TraceLog is being destroyed");await g.resetIdentity()}}};var Le,R,G,ot,ne,at=-1,P=function(n){addEventListener("pageshow",(function(e){e.persisted&&(at=e.timeStamp,n(e))}),!0)},be=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},re=function(){var n=be();return n&&n.activationStart||0},T=function(n,e){var t=be(),s="navigate";return at>=0?s="back-forward-cache":t&&(document.prerendering||re()>0?s="prerender":document.wasDiscarded?s="restore":t.type&&(s=t.type.replace(/_/g,"-"))),{name:n,value:e===void 0?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:s}},H=function(n,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(n)){var s=new PerformanceObserver((function(r){Promise.resolve().then((function(){e(r.getEntries())}))}));return s.observe(Object.assign({type:n,buffered:!0},t||{})),s}}catch{}},_=function(n,e,t,s){var r,i;return function(o){e.value>=0&&(o||s)&&((i=e.value-(r||0))||r===void 0)&&(r=e.value,e.delta=i,e.rating=(function(l,c){return l>c[1]?"poor":l>c[0]?"needs-improvement":"good"})(e.value,t),n(e))}},Re=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},W=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},ie=function(n){var e=!1;return function(){e||(n(),e=!0)}},x=-1,lt=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},oe=function(n){document.visibilityState==="hidden"&&x>-1&&(x=n.type==="visibilitychange"?n.timeStamp:0,Fs())},ct=function(){addEventListener("visibilitychange",oe,!0),addEventListener("prerenderingchange",oe,!0)},Fs=function(){removeEventListener("visibilitychange",oe,!0),removeEventListener("prerenderingchange",oe,!0)},Ne=function(){return x<0&&(x=lt(),ct(),P((function(){setTimeout((function(){x=lt(),ct()}),0)}))),{get firstHiddenTime(){return x}}},K=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},Ce=[1800,3e3],ut=function(n,e){e=e||{},K((function(){var t,s=Ne(),r=T("FCP"),i=H("paint",(function(o){o.forEach((function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<s.firstHiddenTime&&(r.value=Math.max(l.startTime-re(),0),r.entries.push(l),t(!0)))}))}));i&&(t=_(n,r,Ce,e.reportAllChanges),P((function(o){r=T("FCP"),t=_(n,r,Ce,e.reportAllChanges),Re((function(){r.value=performance.now()-o.timeStamp,t(!0)}))})))}))},Oe=[.1,.25],Vs=function(n,e){e=e||{},ut(ie((function(){var t,s=T("CLS",0),r=0,i=[],o=function(c){c.forEach((function(u){if(!u.hadRecentInput){var f=i[0],p=i[i.length-1];r&&u.startTime-p.startTime<1e3&&u.startTime-f.startTime<5e3?(r+=u.value,i.push(u)):(r=u.value,i=[u])}})),r>s.value&&(s.value=r,s.entries=i,t())},l=H("layout-shift",o);l&&(t=_(n,s,Oe,e.reportAllChanges),W((function(){o(l.takeRecords()),t(!0)})),P((function(){r=0,s=T("CLS",0),t=_(n,s,Oe,e.reportAllChanges),Re((function(){return t()}))})),setTimeout(t,0))})))},dt=0,Pe=1/0,ae=0,Hs=function(n){n.forEach((function(e){e.interactionId&&(Pe=Math.min(Pe,e.interactionId),ae=Math.max(ae,e.interactionId),dt=ae?(ae-Pe)/7+1:0)}))},ht=function(){return Le?dt:performance.interactionCount||0},xs=function(){"interactionCount"in performance||Le||(Le=H("event",Hs,{type:"event",buffered:!0,durationThreshold:0}))},A=[],le=new Map,ft=0,$s=function(){var n=Math.min(A.length-1,Math.floor((ht()-ft)/50));return A[n]},Bs=[],Xs=function(n){if(Bs.forEach((function(r){return r(n)})),n.interactionId||n.entryType==="first-input"){var e=A[A.length-1],t=le.get(n.interactionId);if(t||A.length<10||n.duration>e.latency){if(t)n.duration>t.latency?(t.entries=[n],t.latency=n.duration):n.duration===t.latency&&n.startTime===t.entries[0].startTime&&t.entries.push(n);else{var s={id:n.interactionId,latency:n.duration,entries:[n]};le.set(s.id,s),A.push(s)}A.sort((function(r,i){return i.latency-r.latency})),A.length>10&&A.splice(10).forEach((function(r){return le.delete(r.id)}))}}},gt=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=ie(n),document.visibilityState==="hidden"?n():(t=e(n),W(n)),t},De=[200,500],Gs=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},K((function(){var t;xs();var s,r=T("INP"),i=function(l){gt((function(){l.forEach(Xs);var c=$s();c&&c.latency!==r.value&&(r.value=c.latency,r.entries=c.entries,s())}))},o=H("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});s=_(n,r,De,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),W((function(){i(o.takeRecords()),s(!0)})),P((function(){ft=ht(),A.length=0,le.clear(),r=T("INP"),s=_(n,r,De,e.reportAllChanges)})))})))},ke=[2500,4e3],Ue={},Ws=function(n,e){e=e||{},K((function(){var t,s=Ne(),r=T("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach((function(u){u.startTime<s.firstHiddenTime&&(r.value=Math.max(u.startTime-re(),0),r.entries=[u],t())}))},o=H("largest-contentful-paint",i);if(o){t=_(n,r,ke,e.reportAllChanges);var l=ie((function(){Ue[r.id]||(i(o.takeRecords()),o.disconnect(),Ue[r.id]=!0,t(!0))}));["keydown","click"].forEach((function(c){addEventListener(c,(function(){return gt(l)}),{once:!0,capture:!0})})),W(l),P((function(c){r=T("LCP"),t=_(n,r,ke,e.reportAllChanges),Re((function(){r.value=performance.now()-c.timeStamp,Ue[r.id]=!0,t(!0)}))}))}}))},Fe=[800,1800],Ks=function n(e){document.prerendering?K((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},js=function(n,e){e=e||{};var t=T("TTFB"),s=_(n,t,Fe,e.reportAllChanges);Ks((function(){var r=be();r&&(t.value=Math.max(r.responseStart-re(),0),t.entries=[r],s(!0),P((function(){t=T("TTFB",0),(s=_(n,t,Fe,e.reportAllChanges))(!0)})))}))},j={passive:!0,capture:!0},zs=new Date,mt=function(n,e){R||(R=e,G=n,ot=new Date,pt(removeEventListener),St())},St=function(){if(G>=0&&G<ot-zs){var n={entryType:"first-input",name:R.type,target:R.target,cancelable:R.cancelable,startTime:R.timeStamp,processingStart:R.timeStamp+G};ne.forEach((function(e){e(n)})),ne=[]}},Qs=function(n){if(n.cancelable){var e=(n.timeStamp>1e12?new Date:performance.now())-n.timeStamp;n.type=="pointerdown"?(function(t,s){var r=function(){mt(t,s),o()},i=function(){o()},o=function(){removeEventListener("pointerup",r,j),removeEventListener("pointercancel",i,j)};addEventListener("pointerup",r,j),addEventListener("pointercancel",i,j)})(e,n):mt(e,n)}},pt=function(n){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return n(e,Qs,j)}))},Ve=[100,300],Ys=function(n,e){e=e||{},K((function(){var t,s=Ne(),r=T("FID"),i=function(c){c.startTime<s.firstHiddenTime&&(r.value=c.processingStart-c.startTime,r.entries.push(c),t(!0))},o=function(c){c.forEach(i)},l=H("first-input",o);t=_(n,r,Ve,e.reportAllChanges),l&&(W(ie((function(){o(l.takeRecords()),l.disconnect()}))),P((function(){var c;r=T("FID"),t=_(n,r,Ve,e.reportAllChanges),ne=[],G=-1,R=null,pt(addEventListener),c=i,ne.push(c),St()})))}))};const qs=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:Oe,FCPThresholds:Ce,FIDThresholds:Ve,INPThresholds:De,LCPThresholds:ke,TTFBThresholds:Fe,onCLS:Vs,onFCP:ut,onFID:Ys,onINP:Gs,onLCP:Ws,onTTFB:js},Symbol.toStringTag,{value:"Module"}));h.AppConfigValidationError=S,h.DEFAULT_SESSION_TIMEOUT=9e5,h.DEFAULT_WEB_VITALS_MODE=J,h.DeviceType=w,h.EmitterEvent=N,h.ErrorType=U,h.EventType=d,h.InitializationTimeoutError=wt,h.IntegrationValidationError=me,h.MAX_ARRAY_LENGTH=1e3,h.MAX_CUSTOM_EVENT_ARRAY_SIZE=500,h.MAX_CUSTOM_EVENT_KEYS=100,h.MAX_CUSTOM_EVENT_NAME_LENGTH=120,h.MAX_CUSTOM_EVENT_STRING_SIZE=49152,h.MAX_NESTED_OBJECT_KEYS=200,h.MAX_STRING_LENGTH=1e3,h.MAX_STRING_LENGTH_IN_ARRAY=500,h.Mode=X,h.PII_PATTERNS=rt,h.PermanentError=b,h.RateLimitError=$,h.SamplingRateValidationError=ge,h.ScrollDirection=Q,h.SessionTimeoutValidationError=je,h.SpecialApiUrl=k,h.TimeoutError=B,h.TraceLogValidationError=F,h.WEB_VITALS_GOOD_THRESHOLDS=Wt,h.WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS=Ee,h.WEB_VITALS_POOR_THRESHOLDS=et,h.getWebVitalsThresholds=Te,h.tracelog=Us,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);
1
+ (function(h){"use strict";const L="data-tlog",vt=["button","a",'input[type="button"]','input[type="submit"]','input[type="reset"]','input[type="checkbox"]','input[type="radio"]',"select","textarea",'[role="button"]','[role="link"]','[role="tab"]','[role="menuitem"]','[role="option"]','[role="checkbox"]','[role="radio"]','[role="switch"]',"[routerLink]","[ng-click]","[data-action]","[data-click]","[data-navigate]","[data-toggle]","[onclick]",".btn",".button",".clickable",".nav-link",".menu-item","[data-testid]",'[tabindex="0"]'],yt=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],It=["token","auth","key","session","reset","password","api_key","apikey","secret","access_token","refresh_token","verification","code","otp"],I={INVALID_SESSION_TIMEOUT:"Session timeout must be between 30000ms (30 seconds) and 86400000ms (24 hours)",INVALID_SAMPLING_RATE:"Sampling rate must be between 0 and 1",INVALID_ERROR_SAMPLING_RATE:"Error sampling must be between 0 and 1",INVALID_TRACELOG_PROJECT_ID:"TraceLog project ID is required when integration is enabled",INVALID_GLOBAL_METADATA:"Global metadata must be an object",INVALID_SENSITIVE_QUERY_PARAMS:"Sensitive query params must be an array of strings",INVALID_PAGE_VIEW_THROTTLE:"Page view throttle must be a non-negative number",INVALID_CLICK_THROTTLE:"Click throttle must be a non-negative number",INVALID_MAX_SAME_EVENT_PER_MINUTE:"Max same event per minute must be a positive number",INVALID_SEND_INTERVAL:"Send interval must be between 1000ms (1 second) and 60000ms (60 seconds)"},wt=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi],m="tlog",z=`${m}:qa_mode`,ue=`${m}:uid`,$e="tlog_mode",Be="qa",Xe="qa_off",de=n=>n?`${m}:${n}:queue`:`${m}:queue`,he=n=>n?`${m}:${n}:rate_limit`:`${m}:rate_limit`,At=n=>n?`${m}:${n}:session`:`${m}:session`,Mt=n=>n?`${m}:${n}:broadcast`:`${m}:broadcast`,Ge=(n,e)=>`${m}:${n}:session_counts:${e}`,We=10080*60*1e3,Ke=`${m}:session_counts_last_cleanup`,je=3600*1e3,fe=n=>n?`${m}:${n}:identity`:`${m}:identity`,D=`${m}:pending_identity`;var k=(n=>(n.Localhost="localhost:8080",n.Fail="localhost:9999",n))(k||{}),w=(n=>(n.Mobile="mobile",n.Tablet="tablet",n.Desktop="desktop",n.Unknown="unknown",n))(w||{}),C=(n=>(n.EVENT="event",n.QUEUE="queue",n))(C||{});class b extends Error{constructor(e,t,s){super(e),this.statusCode=t,this.responseCode=s,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,b)}statusCode;responseCode}class $ extends Error{constructor(e){super(e),this.name="RateLimitError",Error.captureStackTrace&&Error.captureStackTrace(this,$)}}class B extends Error{constructor(e){super(e),this.name="TimeoutError",Error.captureStackTrace&&Error.captureStackTrace(this,B)}}var d=(n=>(n.PAGE_VIEW="page_view",n.CLICK="click",n.SCROLL="scroll",n.SESSION_START="session_start",n.CUSTOM="custom",n.WEB_VITALS="web_vitals",n.ERROR="error",n))(d||{}),Q=(n=>(n.UP="up",n.DOWN="down",n))(Q||{}),U=(n=>(n.JS_ERROR="js_error",n.PROMISE_REJECTION="promise_rejection",n))(U||{}),X=(n=>(n.QA="qa",n))(X||{});class F extends Error{constructor(e,t,s){super(e),this.errorCode=t,this.layer=s,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}errorCode;layer}class p extends F{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class ze extends F{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class ge extends F{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class me extends F{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class Lt extends F{constructor(e,t,s="runtime"){super(e,"INITIALIZATION_TIMEOUT",s),this.timeoutMs=t}timeoutMs}const bt=["gclid","gbraid","wbraid","fbclid","ttclid"],pe=()=>{const n=new URLSearchParams(window.location.search),e={};return bt.forEach(s=>{const r=n.get(s);r&&(e[s]=r)}),Object.keys(e).length?e:void 0},Rt="background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",Ct="background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",Nt="background: #d32f2f; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",Ot=(n,e)=>{if(e){if(e instanceof Error){const t=e.message.replace(/\s+at\s+.*$/gm,"").replace(/\s*\([^()]+:\d+:\d+\)/g,"");return`[TraceLog] ${n}: ${t}`}if(e instanceof Error)return`[TraceLog] ${n}: ${e.message}`;if(typeof e=="string")return`[TraceLog] ${n}: ${e}`;if(typeof e=="object")try{return`[TraceLog] ${n}: ${JSON.stringify(e)}`}catch{return`[TraceLog] ${n}: [Unable to serialize error]`}return`[TraceLog] ${n}: ${String(e)}`}return`[TraceLog] ${n}`},Pt=()=>{if(typeof window>"u"||typeof sessionStorage>"u")return!1;try{return sessionStorage.getItem(z)==="true"}catch{return!1}},a=(n,e,t)=>{const{error:s,data:r,showToClient:i=!1,style:o,visibility:c}=t??{},l=s?Ot(e,s):`[TraceLog] ${e}`,u=n==="error"?"error":n==="warn"?"warn":"log";if(!Dt(c,i))return;const S=kt(c,o),v=r!==void 0?Se(r):void 0;Ut(u,l,S,v)},Dt=(n,e)=>n==="critical"?!0:n==="qa"||e?Pt():!1,kt=(n,e)=>e!==void 0&&e!==""?e:n==="critical"?Nt:"",Ut=(n,e,t,s)=>{const r=t!==void 0&&t!=="",i=r?`%c${e}`:e;s!==void 0?r?console[n](i,t,s):console[n](i,s):r?console[n](i,t):console[n](i)},Se=n=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[s,r]of Object.entries(n)){const i=s.toLowerCase();if(t.some(o=>i.includes(o))){e[s]="[REDACTED]";continue}r!==null&&typeof r=="object"&&!Array.isArray(r)?e[s]=Se(r):Array.isArray(r)?e[s]=r.map(o=>o!==null&&typeof o=="object"&&!Array.isArray(o)?Se(o):o):e[s]=r}return e};let Ee,Qe;const Ft=()=>{typeof window<"u"&&!Ee&&(Ee=window.matchMedia("(pointer: coarse)"),Qe=window.matchMedia("(hover: none)"))},Y="Unknown",Vt=n=>{const e=n.userAgentData?.platform;if(e!=null&&e!==""){if(/windows/i.test(e))return"Windows";if(/macos/i.test(e))return"macOS";if(/android/i.test(e))return"Android";if(/linux/i.test(e))return"Linux";if(/chromeos/i.test(e))return"ChromeOS";if(/ios/i.test(e))return"iOS"}const t=navigator.userAgent;return/Windows/i.test(t)?"Windows":/iPhone|iPad|iPod/i.test(t)?"iOS":/Mac OS X|Macintosh/i.test(t)?"macOS":/Android/i.test(t)?"Android":/CrOS/i.test(t)?"ChromeOS":/Linux/i.test(t)?"Linux":Y},Ht=n=>{const e=n.userAgentData?.brands;if(e!=null&&e.length>0){const r=e.filter(i=>!/not.?a.?brand|chromium/i.test(i.brand))[0];if(r!=null){const i=r.brand;return/google chrome/i.test(i)?"Chrome":/microsoft edge/i.test(i)?"Edge":/opera/i.test(i)?"Opera":i}}const t=navigator.userAgent;return/Edg\//i.test(t)?"Edge":/OPR\//i.test(t)?"Opera":/Chrome/i.test(t)?"Chrome":/Firefox/i.test(t)?"Firefox":/Safari/i.test(t)&&!/Chrome/i.test(t)?"Safari":Y},xt=()=>{try{const n=navigator;if(n.userAgentData!=null&&typeof n.userAgentData.mobile=="boolean"){const l=n.userAgentData.platform;return l!=null&&l!==""&&/ipad|tablet/i.test(l)?w.Tablet:n.userAgentData.mobile?w.Mobile:w.Desktop}Ft();const e=window.innerWidth,t=Ee?.matches??!1,s=Qe?.matches??!1,r="ontouchstart"in window||navigator.maxTouchPoints>0,i=navigator.userAgent.toLowerCase(),o=/mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i),c=/tablet|ipad|android(?!.*mobile)/.test(i);return e<=767||o&&r?w.Mobile:e>=768&&e<=1024||c||t&&s&&r?w.Tablet:w.Desktop}catch(n){return a("debug","Device detection failed, defaulting to desktop",{error:n}),w.Desktop}},$t=()=>{try{const n=navigator;return{type:xt(),os:Vt(n),browser:Ht(n)}}catch(n){return a("debug","Device info detection failed, using defaults",{error:n}),{type:w.Desktop,os:Y,browser:Y}}},Ye=500,qe=2e3,Je=5e3,q=50,Bt=q*2,Ze=1,Xt=1e3,Gt=10,et=5e3,Wt=3,Kt=200,jt=6e4,zt=64,Qt={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800},Te={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800},tt={LCP:4e3,FCP:3e3,CLS:.25,INP:500,TTFB:1800},J="needs-improvement",_e=(n=J)=>{switch(n){case"all":return{LCP:0,FCP:0,CLS:0,INP:0,TTFB:0};case"needs-improvement":return Te;case"poor":return tt;default:return Te}},Yt=50,qt="3.1.0",Jt=()=>typeof window<"u"&&typeof sessionStorage<"u",Zt=()=>{try{const n=new URLSearchParams(window.location.search);n.delete($e);const e=n.toString(),t=window.location.pathname+(e?"?"+e:"")+window.location.hash;window.history.replaceState({},"",t)}catch{}},es=()=>{if(!Jt())return!1;try{const e=new URLSearchParams(window.location.search).get($e),t=sessionStorage.getItem(z);let s=null;return e===Be?(s=!0,sessionStorage.setItem(z,"true"),a("info","QA Mode ACTIVE",{visibility:"qa",style:Rt})):e===Xe&&(s=!1,sessionStorage.setItem(z,"false"),a("info","QA Mode DISABLED",{visibility:"qa",style:Ct})),(e===Be||e===Xe)&&Zt(),s??t==="true"}catch{return!1}},st=()=>typeof document<"u"&&document.prerendering===!0,ts=["co.uk","org.uk","com.au","net.au","com.br","co.nz","co.jp","com.mx","co.in","com.cn","co.za"],nt=n=>{const e=n.toLowerCase().split(".");if(e.length<=2)return n.toLowerCase();const t=e.slice(-2).join(".");return ts.includes(t)?e.slice(-3).join("."):e.slice(-2).join(".")},ss=(n,e)=>n===e?!0:nt(n)===nt(e),ve=()=>{const n=document.referrer;if(!n)return"Direct";try{const e=new URL(n).hostname.toLowerCase(),t=window.location.hostname.toLowerCase();return ss(e,t)?"Direct":n}catch(e){return a("debug","Failed to parse referrer URL, using raw value",{error:e,data:{referrer:n}}),n}},ye=()=>{const n=new URLSearchParams(window.location.search),e={};return yt.forEach(s=>{const r=n.get(s);if(r){const i=s.split("utm_")[1];e[i]=r}}),Object.keys(e).length?e:void 0},rt=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,n=>{const e=Math.random()*16|0;return(n==="x"?e:e&3|8).toString(16)});let Z=0,ee=0;const ns=()=>{let n=Date.now();n<ee&&(n=ee),n===ee?Z=(Z+1)%1e3:Z=0,ee=n;const e=Z.toString().padStart(3,"0");let t="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const s=crypto.getRandomValues(new Uint8Array(3));s&&(t=Array.from(s,r=>r.toString(16).padStart(2,"0")).join(""))}}catch{}return t||(t=Math.floor(Math.random()*16777215).toString(16).padStart(6,"0")),`${n}-${e}-${t}`},rs=n=>{try{return new URL(n).protocol==="https:"}catch{return!1}},is=n=>{try{const t=new URL(window.location.href).hostname;if(!t||typeof t!="string")throw new Error("Invalid hostname");if(t==="localhost"||t==="127.0.0.1"||/^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$/.test(t))throw new Error("SaaS integration requires a domain hostname; localhost and IP addresses are not supported. For local development, omit `integrations.tracelog` to run in standalone mode (events emitted locally, no network requests), or test against a staging domain that resolves to your dev machine via /etc/hosts.");const s=t.split(".");if(!s||!Array.isArray(s)||s.length===0||s.length===1&&s[0]==="")throw new Error("Invalid hostname structure");if(s.length===1)throw new Error("Single-part domain not supported for SaaS integration");const r=s.length===2?s.join("."):s.slice(-2).join(".");if(!r||r.split(".").length<2)throw new Error("Invalid domain structure for SaaS");const i=`https://${n}.${r}/collect`;if(!rs(i))throw new Error("Generated URL failed validation");return i}catch(e){throw new Error(`Invalid SaaS URL configuration: ${e instanceof Error?e.message:String(e)}`)}},os=n=>{const e={};return n.integrations?.tracelog?.projectId&&(e.saas=is(n.integrations.tracelog.projectId)),e},Ie=(n,e=[])=>{if(!n||typeof n!="string")return a("warn","Invalid URL provided to normalizeUrl",{data:{type:typeof n}}),n||"";try{const t=new URL(n),s=t.searchParams,r=[...new Set([...It,...e])];let i=!1;const o=[];return r.forEach(c=>{s.has(c)&&(s.delete(c),i=!0,o.push(c))}),!i&&n.includes("?")?n:(t.search=s.toString(),t.toString())}catch(t){return a("warn","URL normalization failed, returning original",{error:t,data:{urlLength:n?.length}}),n}},it=n=>{if(!n||typeof n!="string"||n.trim().length===0)return"";let e=n;n.length>1e3&&(e=n.slice(0,Math.max(0,1e3)));let t=0;for(const r of wt){const i=e;e=e.replace(r,""),i!==e&&t++}return t>0&&a("warn","XSS patterns detected and removed",{data:{patternMatches:t,valueLength:n.length}}),e.trim()},we=(n,e=0)=>{if(n==null)return null;if(typeof n=="string")return it(n);if(typeof n=="number")return!Number.isFinite(n)||n<-Number.MAX_SAFE_INTEGER||n>Number.MAX_SAFE_INTEGER?0:n;if(typeof n=="boolean")return n;if(e>10)return null;if(Array.isArray(n))return n.slice(0,1e3).map(r=>we(r,e+1)).filter(r=>r!==null);if(typeof n=="object"){const t={},r=Object.entries(n).slice(0,200);for(const[i,o]of r){const c=it(i);if(c){const l=we(o,e+1);l!==null&&(t[c]=l)}}return t}return null},as=n=>{if(typeof n!="object"||n===null)return{};try{const e=we(n);return typeof e=="object"&&e!==null?e:{}}catch(e){const t=e instanceof Error?e.message:String(e);throw new Error(`[TraceLog] Metadata sanitization failed: ${t}`)}},ot=[/\b[A-Za-z0-9._%+-]{1,64}@(?:[A-Za-z0-9-]{1,63}\.)+[A-Za-z]{2,63}\b/gi,/\b\d{3}[-.]?\d{3}[-.]?\d{4}\b/g,/\b\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/g,/\b[A-Z]{2}\d{2}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}[-\s]?\d{4}\b/gi,/\b[sp]k_(test|live)_[a-zA-Z0-9]{10,}\b/gi,/Bearer\s+[A-Za-z0-9_-]+(?:\.[A-Za-z0-9_-]+)?(?:\.[A-Za-z0-9_-]+)?/gi,/:\/\/[^:/]+:([^@]+)@/gi,/[?&](token|password|passwd|auth|secret|secret_key|private_key|auth_key|api_key|apikey|access_token)=[^&\s]+/gi],te=n=>{let e=n;for(const t of ot)e=e.replace(t,"[REDACTED]");return e},cs=n=>{if(n!==void 0&&(n===null||typeof n!="object"))throw new p("Configuration must be an object","config");if(n){if(n.sessionTimeout!==void 0&&(typeof n.sessionTimeout!="number"||n.sessionTimeout<3e4||n.sessionTimeout>864e5))throw new ze(I.INVALID_SESSION_TIMEOUT,"config");if(n.globalMetadata!==void 0&&(typeof n.globalMetadata!="object"||n.globalMetadata===null))throw new p(I.INVALID_GLOBAL_METADATA,"config");if(n.integrations&&ls(n.integrations),n.sensitiveQueryParams!==void 0){if(!Array.isArray(n.sensitiveQueryParams))throw new p(I.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of n.sensitiveQueryParams)if(typeof e!="string")throw new p("All sensitive query params must be strings","config")}if(n.errorSampling!==void 0&&(typeof n.errorSampling!="number"||n.errorSampling<0||n.errorSampling>1))throw new ge(I.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new ge(I.INVALID_SAMPLING_RATE,"config");if(n.pageViewThrottleMs!==void 0&&(typeof n.pageViewThrottleMs!="number"||n.pageViewThrottleMs<0))throw new p(I.INVALID_PAGE_VIEW_THROTTLE,"config");if(n.clickThrottleMs!==void 0&&(typeof n.clickThrottleMs!="number"||n.clickThrottleMs<0))throw new p(I.INVALID_CLICK_THROTTLE,"config");if(n.maxSameEventPerMinute!==void 0&&(typeof n.maxSameEventPerMinute!="number"||n.maxSameEventPerMinute<=0))throw new p(I.INVALID_MAX_SAME_EVENT_PER_MINUTE,"config");if(n.sendIntervalMs!==void 0&&(!Number.isFinite(n.sendIntervalMs)||n.sendIntervalMs<1e3||n.sendIntervalMs>6e4))throw new p(I.INVALID_SEND_INTERVAL,"config");if(n.flushOnSpaNavigation!==void 0&&typeof n.flushOnSpaNavigation!="boolean")throw new p(`Invalid flushOnSpaNavigation type: ${typeof n.flushOnSpaNavigation}. Must be a boolean`,"config");if(n.flushOnPageHidden!==void 0&&typeof n.flushOnPageHidden!="boolean")throw new p(`Invalid flushOnPageHidden type: ${typeof n.flushOnPageHidden}. Must be a boolean`,"config");if(n.webVitalsMode!==void 0){if(typeof n.webVitalsMode!="string")throw new p(`Invalid webVitalsMode type: ${typeof n.webVitalsMode}. Must be a string`,"config");const e=["all","needs-improvement","poor"];if(!e.includes(n.webVitalsMode))throw new p(`Invalid webVitalsMode: "${n.webVitalsMode}". Must be one of: ${e.join(", ")}`,"config")}if(n.webVitalsThresholds!==void 0){if(typeof n.webVitalsThresholds!="object"||n.webVitalsThresholds===null||Array.isArray(n.webVitalsThresholds))throw new p("webVitalsThresholds must be an object","config");const e=["LCP","FCP","CLS","INP","TTFB"];for(const[t,s]of Object.entries(n.webVitalsThresholds)){if(!e.includes(t))throw new p(`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,"config");if(typeof s!="number"||!Number.isFinite(s)||s<0)throw new p(`Invalid Web Vitals threshold value for ${t}: ${s}. Must be a non-negative finite number`,"config")}}}},ls=n=>{if(n&&n.tracelog){if(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()==="")throw new me(I.INVALID_TRACELOG_PROJECT_ID,"config");if(n.tracelog.shopify!==void 0&&typeof n.tracelog.shopify!="boolean")throw new me("tracelog.shopify must be a boolean","config")}},us=n=>(cs(n),{...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??Ze,samplingRate:n?.samplingRate??1,pageViewThrottleMs:n?.pageViewThrottleMs??1e3,clickThrottleMs:n?.clickThrottleMs??300,maxSameEventPerMinute:n?.maxSameEventPerMinute??60,sendIntervalMs:n?.sendIntervalMs??1e4,flushOnSpaNavigation:n?.flushOnSpaNavigation??!1,flushOnPageHidden:n?.flushOnPageHidden??!0}),Ae=(n,e=new Set)=>{if(n==null)return!0;const t=typeof n;return t==="string"||t==="number"||t==="boolean"?!0:t==="function"||t==="symbol"||t==="bigint"||e.has(n)?!1:(e.add(n),Array.isArray(n)?n.every(s=>Ae(s,e)):t==="object"?Object.values(n).every(s=>Ae(s,e)):!1)},ds=n=>typeof n!="object"||n===null?!1:Ae(n),Me=n=>{if(typeof n!="object"||n===null||Array.isArray(n))return;const e={};for(const[t,s]of Object.entries(n))typeof s=="string"&&(e[t]=s);return Object.keys(e).length>0?e:void 0},hs=n=>typeof n!="string"?{valid:!1,error:"Event name must be a string"}:n.length===0?{valid:!1,error:"Event name cannot be empty"}:n.length>120?{valid:!1,error:"Event name is too long (max 120 characters)"}:n.includes("<")||n.includes(">")||n.includes("&")?{valid:!1,error:"Event name contains invalid characters"}:["constructor","prototype","__proto__","eval","function","var","let","const"].includes(n.toLowerCase())?{valid:!1,error:"Event name cannot be a reserved word"}:{valid:!0},at=(n,e,t)=>{const s=as(e),r=`${t} "${n}" metadata error`;if(!ds(s))return{valid:!1,error:`${r}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(s)}catch{return{valid:!1,error:`${r}: object contains circular references or cannot be serialized.`}}if(new TextEncoder().encode(i).byteLength>49152)return{valid:!1,error:`${r}: object is too large (max ${49152/1024} KB).`};if(Object.keys(s).length>100)return{valid:!1,error:`${r}: object has too many keys (max 100 keys).`};for(const[l,u]of Object.entries(s)){if(Array.isArray(u)){if(u.length>500)return{valid:!1,error:`${r}: array property "${l}" is too large (max 500 items).`};for(const f of u)if(typeof f=="string"&&f.length>500)return{valid:!1,error:`${r}: array property "${l}" contains strings that are too long (max 500 characters).`}}if(typeof u=="string"&&u.length>1e3)return{valid:!1,error:`${r}: property "${l}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:s}},fs=(n,e,t)=>{if(Array.isArray(e)){const s=[],r=`${t} "${n}" metadata error`;for(let i=0;i<e.length;i++){const o=e[i];if(typeof o!="object"||o===null||Array.isArray(o))return{valid:!1,error:`${r}: array item at index ${i} must be an object.`};const c=at(n,o,t);if(!c.valid)return{valid:!1,error:`${r}: array item at index ${i} is invalid: ${c.error}`};c.sanitizedMetadata&&s.push(c.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:s}}return at(n,e,t)},gs=(n,e)=>{const t=hs(n);if(!t.valid)return a("error","Event name validation failed",{data:{eventName:n,error:t.error}}),t;if(!e)return{valid:!0};const s=fs(n,e,"customEvent");return s.valid||a("error","Event metadata validation failed",{data:{eventName:n,error:s.error}}),s};class ms{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const s=this.listeners.get(e);if(s){const r=s.indexOf(t);r>-1&&s.splice(r,1)}}emit(e,t){const s=this.listeners.get(e);s&&s.forEach(r=>{r(t)})}removeAllListeners(){this.listeners.clear()}}const ps=/https?:\/\/\S+/g,Ss=/[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}/gi,Es=/0x[0-9a-fA-F]{4,}/g,Ts=/(?<!\d)\d{4,}(?!\d)/g,_s=/(['"])[^'"]{20,}\1/g;function vs(n){return n.replace(ps,"[URL]").replace(Ss,"[ID]").replace(Es,"[ADDR]").replace(Ts,"[N]").replace(_s,"$1[VAR]$1").toLowerCase().trim()}function ct(n){const e=n.search(/[?#]/);return e===-1?n:n.slice(0,e)}function ys(n,e){const t=ct((n??"").trim());if(!t)return"";let s;try{s=new URL(t)}catch{return t}if(s.protocol!=="http:"&&s.protocol!=="https:")return"";const r=ct((e??"").trim());return r&&t===r?s.origin:t}function Is(n){const e=vs(n.message),t=ys(n.filename,n.page_url),s=n.line==null?"":String(n.line);return`${e}|${t}|${s}`}const Le={config:{}};class E{get(e){return Le[e]}set(e,t){Le[e]=t}getState(){return{...Le}}}class ws extends E{storeManager;apiUrl;lastPermanentErrorLog=null;recoveryInProgress=!1;lastMetadataTimestamp=0;pendingControllers=new Set;consecutiveNetworkFailures=0;circuitOpenedAt=0;rateLimitedUntil=0;rateLimitStorageKeyAtArm=null;constructor(e,t){super(),this.storeManager=e,this.apiUrl=t,this.migrateLegacyV2Keys(),this.rateLimitedUntil=this.loadRateLimitCooldown()}migrateLegacyV2Keys(){const e=this.get("userId")||"anonymous",t=`${de(e)}:saas`,s=`${de(e)}:custom`,r=`${he(e)}:saas`,i=`${he(e)}:custom`;try{const o=this.storeManager.getItem(t);if(o){const c=this.getQueueStorageKey(),l=this.storeManager.getItem(c);l?this.mergeLegacyIntoCurrent(c,o,l):(this.storeManager.setItem(c,o),a("debug","Migrated v2 SaaS queue to v3 unscoped key")),this.storeManager.removeItem(t)}}catch(o){a("debug","Failed to migrate v2 SaaS queue, discarding legacy key",{error:o});try{this.storeManager.removeItem(t)}catch{}}[s,r,i].forEach(o=>{try{this.storeManager.getItem(o)!==null&&this.storeManager.removeItem(o)}catch{}})}mergeLegacyIntoCurrent(e,t,s){try{const r=JSON.parse(t),i=JSON.parse(s);if(!Array.isArray(r?.events)||!Array.isArray(i?.events)){a("debug","Legacy or current queue malformed, keeping current only");return}const o=new Set(i.events.map(u=>u.id)),c=[...i.events,...r.events.filter(u=>typeof u.id=="string"&&!o.has(u.id))],l={...i,events:c,timestamp:typeof i.timestamp=="number"&&typeof r.timestamp=="number"?Math.min(i.timestamp,r.timestamp):i.timestamp??r.timestamp??Date.now(),recoveryFailures:Math.max(i.recoveryFailures??0,r.recoveryFailures??0)||void 0};this.storeManager.setItem(e,JSON.stringify(l)),a("debug","Merged v2 SaaS queue into existing v3 queue",{data:{added:c.length-i.events.length,total:c.length}})}catch(r){a("debug","Failed to merge legacy queue, keeping current",{error:r})}}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return de(e)}getRateLimitStorageKey(){const e=this.get("userId")||"anonymous";return he(e)}getActiveRateLimitKey(){return this.rateLimitStorageKeyAtArm??this.getRateLimitStorageKey()}armRateLimitCooldown(e){this.rateLimitedUntil=e,this.rateLimitStorageKeyAtArm=this.getRateLimitStorageKey(),this.persistRateLimitCooldown(e)}loadRateLimitCooldown(){const e=this.getRateLimitStorageKey();try{const t=this.storeManager.getItem(e);if(!t)return 0;const s=Number(t);return!Number.isFinite(s)||s<=Date.now()?(this.storeManager.removeItem(e),0):(this.rateLimitStorageKeyAtArm=e,s)}catch{return 0}}persistRateLimitCooldown(e){const t=this.getActiveRateLimitKey();try{const s=this.storeManager.getItem(t);if(s){const r=Number(s);if(Number.isFinite(r)&&r>=e)return}this.storeManager.setItem(t,String(e))}catch{}}clearRateLimitCooldown(){const e=this.getActiveRateLimitKey();try{const t=this.storeManager.getItem(e);if(t){const s=Number(t);if(Number.isFinite(s)&&s>Date.now()){this.rateLimitedUntil=s;return}}this.storeManager.removeItem(e)}catch{}this.rateLimitedUntil=0,this.rateLimitStorageKeyAtArm=null}isRateLimited(){return this.rateLimitedUntil===0&&(this.rateLimitedUntil=this.loadRateLimitCooldown()),!(this.rateLimitedUntil===0||Date.now()>=this.rateLimitedUntil&&(this.clearRateLimitCooldown(),this.rateLimitedUntil===0))}sendEventsQueueSync(e){if(this.isRateLimited()){a("debug","Rate-limit cooldown active, skipping sync send",{data:{cooldownRemainingMs:this.rateLimitedUntil-Date.now(),events:e.events.length}});const t=this.ensureBatchMetadata(e),s=this.getPersistedData(),r=typeof s?.recoveryFailures=="number"&&Number.isFinite(s.recoveryFailures)?s.recoveryFailures:0;return this.persistEventsWithFailureCount(t,r,!0),!1}return this.apiUrl.includes(k.Fail)?(a("warn","Fail mode: simulating network failure (sync)",{data:{events:e.events.length}}),!1):this.apiUrl.includes(k.Localhost)?(a("debug","Success mode: simulating successful send (sync)",{data:{events:e.events.length}}),!0):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){const s=this.ensureBatchMetadata(e);try{const r=await this.send(s);return r?(this.clearPersistedEvents(),t?.onSuccess?.(s.events.length,s.events,s)):(this.persistEvents(s),t?.onFailure?.()),r}catch(r){return r instanceof b?(this.logPermanentError("Permanent error, not retrying",r),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(s),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){if(this.recoveryInProgress){a("debug","Recovery already in progress, skipping duplicate attempt");return}this.recoveryInProgress=!0;let t=null,s=0;try{const r=this.getPersistedData();if(!r||!this.isDataRecent(r)||r.events.length===0){this.clearPersistedEvents();return}const i=r.recoveryFailures;if(s=typeof i=="number"&&Number.isFinite(i)&&i>=0?i:0,s>=3){a("debug",`Discarding persisted events after ${s} failed recovery attempts`),this.clearPersistedEvents(),e?.onFailure?.();return}if(this.isRateLimited()){a("debug","Rate-limit cooldown active, deferring recovery",{data:{cooldownRemainingMs:this.rateLimitedUntil-Date.now()}}),e?.onFailure?.();return}if(t=this.ensureBatchMetadata(this.createRecoveryBody(r)),t.events.length===0){a("debug","All persisted events exceeded the recovery age cutoff; discarding batch"),this.clearPersistedEvents();return}await this.send(t)?(this.clearPersistedEvents(),e?.onSuccess?.(r.events.length,r.events,t)):(this.persistEventsWithFailureCount(t,s+1,!0),e?.onFailure?.())}catch(r){if(r instanceof b){this.logPermanentError("Permanent error during recovery, clearing persisted events",r),this.clearPersistedEvents(),e?.onFailure?.();return}a("error","Failed to recover persisted events",{error:r}),t&&this.persistEventsWithFailureCount(t,s+1,!0),e?.onFailure?.()}finally{this.recoveryInProgress=!1}}stop(){}async backoffDelay(e){const t=100*Math.pow(2,e),s=Math.random()*100;return new Promise(r=>setTimeout(r,t+s))}async send(e){const t=this.ensureBatchMetadata(e,e._metadata?.idempotency_token);if(this.apiUrl.includes(k.Fail))return a("debug","Fail mode: simulating network failure",{data:{events:t.events.length}}),!1;if(this.apiUrl.includes(k.Localhost))return a("debug","Success mode: simulating successful send",{data:{events:t.events.length}}),!0;if(this.isRateLimited())return a("debug","Rate-limit cooldown active, skipping send",{data:{cooldownRemainingMs:this.rateLimitedUntil-Date.now(),events:t.events.length}}),!1;if(this.consecutiveNetworkFailures>=3){const c=Date.now()-this.circuitOpenedAt;if(c<12e4)return a("debug","Network circuit open, skipping send",{data:{consecutiveNetworkFailures:this.consecutiveNetworkFailures,cooldownRemainingMs:12e4-c}}),!1}const{url:s,payload:r}=this.prepareRequest(t);let i=!0,o=!1;for(let c=1;c<=3;c++)try{return(await this.sendWithTimeout(s,r)).ok?(c>1&&a("info",`Send succeeded after ${c-1} retry attempt(s)`,{data:{events:t.events.length,attempt:c}}),this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0,!0):!1}catch(l){const u=c===3;if(l instanceof b)throw this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0,l;if(l instanceof $){this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0,i=!1,o=!0,this.armRateLimitCooldown(Date.now()+6e4),a("warn","Rate limited, skipping retries",{data:{events:e.events.length,attempt:c,cooldownMs:6e4}});break}if(l instanceof B||(i=!1),l instanceof TypeError||(o=!0),a(u?"error":"warn",`Send attempt ${c} failed${u?" (all retries exhausted)":", will retry"}`,{error:l,data:{events:e.events.length,url:s.replace(/\/\/[^/]+/,"//[DOMAIN]"),attempt:c,maxAttempts:3}}),!u){await this.backoffDelay(c);continue}return i?(a("debug","All retry attempts timed out, preserving batch for retry",{data:{events:t.events.length}}),!1):(o?(this.consecutiveNetworkFailures=0,this.circuitOpenedAt=0):(this.consecutiveNetworkFailures=Math.min(this.consecutiveNetworkFailures+1,3),this.consecutiveNetworkFailures>=3&&(this.circuitOpenedAt=Date.now())),!1)}return!1}async sendWithTimeout(e,t){const s=new AbortController;this.pendingControllers.add(s);let r=!1;const i=setTimeout(()=>{r=!0,s.abort()},15e3);try{const o=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:s.signal,headers:{"Content-Type":"application/json"}});if(!o.ok){if(o.status>=400&&o.status<500&&o.status!==408&&o.status!==429){const l=await this.readTraceLogErrorCode(o),u=l?`HTTP ${o.status}: ${o.statusText} (${l})`:`HTTP ${o.status}: ${o.statusText}`;throw new b(u,o.status,l)}throw o.status===429?new $(`HTTP 429: ${o.statusText}`):new Error(`HTTP ${o.status}: ${o.statusText}`)}return o}catch(o){throw o instanceof b?o:r?new B("Request timed out"):o}finally{clearTimeout(i),this.pendingControllers.delete(s)}}async readTraceLogErrorCode(e){try{const t=await e.clone().json();if(typeof t.code=="string"&&t.code.length>0&&t.code.length<=zt)return t.code}catch{}}sendQueueSyncInternal(e){const t=this.ensureBatchMetadata(e),s=this.ensureBatchMetadata(t,t._metadata?.idempotency_token),{url:r,payload:i}=this.prepareRequest(s);if(i.length>65536)return a("warn","Payload exceeds sendBeacon limit, persisting for recovery",{data:{size:i.length,limit:65536,events:s.events.length}}),this.persistEvents(t),!1;const o=new Blob([i],{type:"application/json"});if(!this.isSendBeaconAvailable())return a("warn","sendBeacon not available, persisting events for recovery"),this.persistEvents(t),!1;const c=navigator.sendBeacon(r,o);return c||(a("warn","sendBeacon rejected request, persisting events for recovery"),this.persistEvents(t)),c}prepareRequest(e){let t=Date.now();t<this.lastMetadataTimestamp&&(t=this.lastMetadataTimestamp),this.lastMetadataTimestamp=t;const s={...e,_metadata:{...e._metadata,idempotency_token:e._metadata?.idempotency_token??this.computeContentToken(e),referer:typeof window<"u"?window.location.href:void 0,timestamp:t,client_version:qt}};return{url:this.apiUrl,payload:JSON.stringify(s)}}ensureBatchMetadata(e,t){const s=e._metadata?.idempotency_token??t??this.computeContentToken(e);return e._metadata?.idempotency_token===s?e:{...e,_metadata:{...e._metadata,idempotency_token:s}}}computeContentToken(e){const t=e.events.map(i=>i.id).sort().join(","),s=`${e.user_id}|${e.session_id}|${t}`;let r=2166136261;for(let i=0;i<s.length;i++)r^=s.charCodeAt(i),r=Math.imul(r,16777619)>>>0;return r.toString(16).padStart(8,"0")}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){a("debug","Failed to parse persisted data",{error:e}),this.clearPersistedEvents()}return null}isDataRecent(e){return!e.timestamp||typeof e.timestamp!="number"?!1:(Date.now()-e.timestamp)/(1e3*60*60)<2}createRecoveryBody(e){const{timestamp:t,recoveryFailures:s,...r}=e,i=r.events??[],o=Date.now()-5184e5,c=i.filter(l=>{const u=typeof l.timestamp=="number"?l.timestamp:new Date(l.timestamp).getTime();return Number.isFinite(u)&&u>=o});return c.length<i.length&&a("debug","Recovery dropped stale events",{data:{dropped:i.length-c.length,kept:c.length}}),{...r,events:c}}persistEvents(e){const t=this.getPersistedData(),s=typeof t?.recoveryFailures=="number"&&Number.isFinite(t.recoveryFailures)?t.recoveryFailures:0;return this.persistEventsWithFailureCount(e,s)}persistEventsWithFailureCount(e,t,s=!1){try{const r=this.getPersistedData();if(!s&&r&&r.timestamp){const c=Date.now()-r.timestamp;if(c<1e3)return a("debug","Skipping persistence, another tab recently persisted events",{data:{timeSinceExisting:c}}),!0}const i={...e,timestamp:Date.now(),...t>0&&{recoveryFailures:t}},o=this.getQueueStorageKey();return this.storeManager.setItem(o,JSON.stringify(i)),!!this.storeManager.getItem(o)}catch(r){return a("debug","Failed to persist events",{error:r}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){a("debug","Failed to clear persisted events",{error:e})}}isSendBeaconAvailable(){return typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}logPermanentError(e,t){const s=Date.now(),r=`${t.statusCode??"unknown"}:${t.responseCode??""}`;(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.key!==r||s-this.lastPermanentErrorLog.timestamp>=jt)&&(a("error",e,{data:{status:t.statusCode,code:t.responseCode,message:t.message}}),this.lastPermanentErrorLog={key:r,timestamp:s})}}class As extends E{bootTime;bootTimestamp;hasPerformanceNow;constructor(){if(super(),typeof window>"u"){this.hasPerformanceNow=!1,this.bootTime=0,this.bootTimestamp=0;return}this.hasPerformanceNow=typeof performance<"u"&&typeof performance.now=="function",this.hasPerformanceNow?(this.bootTime=performance.now(),this.bootTimestamp=Date.now()):(this.bootTime=0,this.bootTimestamp=Date.now(),a("debug","performance.now() not available, falling back to Date.now()"))}now(){if(!this.hasPerformanceNow)return Date.now();const e=performance.now()-this.bootTime;return Math.round(this.bootTimestamp+e)}validateTimestamp(e){const s=e-this.now();return s>12e4?{valid:!1,error:`Timestamp is ${(s/1e3/60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`}:{valid:!0}}}const Ms=new Set(Object.values(d));class Ls extends E{dataSenders;emitter;timeManager;recentEventFingerprints=new Map;perEventRateLimits=new Map;eventsQueue=[];pendingEventsBuffer=[];sendTimeoutId=null;sendInProgress=!1;consecutiveSendFailures=0;rateLimitCounter=0;rateLimitWindowStart=0;lastSessionId=null;pendingSyncFlush=!1;sessionEventCounts={total:0,[d.CLICK]:0,[d.PAGE_VIEW]:0,[d.CUSTOM]:0,[d.SCROLL]:0};saveSessionCountsDebounced=null;constructor(e,t=null){super(),this.emitter=t,this.timeManager=new As,this.dataSenders=[];const s=this.get("collectApiUrls");s?.saas&&this.dataSenders.push(new ws(e,s.saas)),this.saveSessionCountsDebounced=this.debounce(r=>{this.saveSessionCounts(r)},500),this.cleanupExpiredSessionCounts()}async recoverPersistedEvents(){const e=this.dataSenders.map(async t=>t.recoverPersistedEvents({onSuccess:(s,r,i)=>{if(r&&r.length>0){const o=r.map(c=>c.id);this.removeProcessedEvents(o),i&&this.emitEventsQueue(i)}},onFailure:()=>{a("debug","Failed to recover persisted events")}}));await Promise.allSettled(e)}track({type:e,page_url:t,from_page_url:s,scroll_data:r,click_data:i,custom_event:o,web_vitals:c,error_data:l,page_view:u}){if(!e){a("error","Event type is required - event will be ignored");return}if(!Ms.has(e)){a("error","Invalid event type - event will be ignored",{data:{type:e}});return}const f=this.get("sessionId");if(!f){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),a("debug","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:s,scroll_data:r,click_data:i,custom_event:o,web_vitals:c,error_data:l,page_view:u});return}this.lastSessionId!==f&&(this.lastSessionId=f,this.sessionEventCounts=this.loadSessionCounts(f));const S=e===d.SESSION_START;if(S&&a("debug","Processing SESSION_START event",{data:{sessionId:f}}),!S&&!this.checkRateLimit())return;const v=e;if(!S){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:v,total:this.sessionEventCounts.total,limit:1e3}});return}const y=this.getTypeLimitForEvent(v);if(y){const xe=this.sessionEventCounts[v];if(xe!==void 0&&xe>=y){a("warn","Session event type limit reached",{data:{type:v,count:xe,limit:y}});return}}}if(v===d.CUSTOM&&o?.name){const y=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,y))return}const nn=v===d.SESSION_START,rn=t||this.get("pageUrl"),le=this.buildEventPayload({type:v,page_url:rn,from_page_url:s,scroll_data:r,click_data:i,custom_event:o,web_vitals:c,error_data:l,page_view:u});if(le&&!(!S&&!this.shouldSample())){if(nn){const y=this.get("sessionId");if(!y){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("debug","Duplicate session_start detected",{data:{sessionId:y}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(le)){if(this.get("mode")===X.QA&&v===d.CUSTOM&&o){a("info",`Custom Event: ${o.name}`,{visibility:"qa",data:{name:o.name,...o.metadata&&{metadata:o.metadata}}}),this.emitEvent(le);return}if(this.addToQueue(le),!S){this.sessionEventCounts.total++,this.sessionEventCounts[v]!==void 0&&this.sessionEventCounts[v]++;const y=this.get("sessionId");y&&this.saveSessionCountsDebounced&&this.saveSessionCountsDebounced(y)}}}}stop(){this.clearSendTimeout(),this.sendInProgress=!1,this.pendingSyncFlush=!1,this.consecutiveSendFailures=0;const e=this.get("sessionId");e&&this.saveSessionCounts(e),this.eventsQueue=[],this.pendingEventsBuffer=[],this.recentEventFingerprints.clear(),this.rateLimitCounter=0,this.rateLimitWindowStart=0,this.perEventRateLimits.clear(),this.sessionEventCounts={total:0,[d.CLICK]:0,[d.PAGE_VIEW]:0,[d.CUSTOM]:0,[d.SCROLL]:0},this.lastSessionId=null,this.set("hasStartSession",!1),this.dataSenders.forEach(t=>{t.stop()})}async flushImmediately(){return this.flushEvents(!1)}flushImmediatelySync(){return this.flushEvents(!0)}getQueueLength(){return this.eventsQueue.length}getQueueEvents(){return this.eventsQueue.map(({_session_id:e,...t})=>t)}async flushQueue(){await this.flushImmediately()}clearQueue(){this.eventsQueue=[]}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){a("debug","Cannot flush pending events: session not initialized - keeping in buffer",{data:{bufferedEventCount:this.pendingEventsBuffer.length}});return}const t=[...this.pendingEventsBuffer];this.pendingEventsBuffer=[],t.forEach(s=>{this.track(s)})}clearSendTimeout(){this.sendTimeoutId!==null&&(clearTimeout(this.sendTimeoutId),this.sendTimeoutId=null)}isSuccessfulResult(e){return e.status==="fulfilled"&&e.value===!0}groupQueuedEventsBySession(){const e=new Map,t=[];for(const s of this.eventsQueue){if(!s._session_id){a("debug","Queued event missing _session_id, dropping",{data:{eventId:s.id,type:s.type}}),t.push(s.id);continue}const r=e.get(s._session_id);r?r.push(s):e.set(s._session_id,[s])}return t.length>0&&this.removeProcessedEvents(t),e}buildBatchesWithIds(){const e=this.groupQueuedEventsBySession();if(e.size===0)return[];const t=[];for(const[s,r]of e)t.push({batch:this.buildBatchFromGroup(s,r),eventIds:r.map(i=>i.id)});return t}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);if(!e&&this.sendInProgress)return a("debug","Async flush skipped: send already in progress"),Promise.resolve(!1);const t=this.buildBatchesWithIds();if(t.length===0)return e?!0:Promise.resolve(!0);if(this.dataSenders.length===0){for(const{batch:s,eventIds:r}of t)this.removeProcessedEvents(r),this.emitEventsQueue(s);return this.clearSendTimeout(),e?!0:Promise.resolve(!0)}if(e&&this.sendInProgress){const s=t.reduce((r,i)=>r+i.eventIds.length,0);return this.pendingSyncFlush=!0,a("debug","Sync flush deferred: async send in-flight, will retry on settle",{data:{eventCount:s}}),!1}if(e){const s=t.map(({batch:r,eventIds:i})=>this.sendBatchSync(r,i));return this.settleSendTimeout(),s.some(Boolean)}return this.sendInProgress=!0,(async()=>{try{const s=await Promise.all(t.map(async({batch:r,eventIds:i})=>this.sendBatchAsync(r,i)));return this.settleSendTimeout(),s.some(Boolean)}finally{this.sendInProgress=!1,this.drainPendingSyncFlush()}})()}settleSendTimeout(){this.eventsQueue.length===0?this.clearSendTimeout():this.scheduleSendTimeout()}drainPendingSyncFlush(){this.pendingSyncFlush&&(this.pendingSyncFlush=!1,this.flushImmediatelySync())}sendBatchSync(e,t){const r=this.dataSenders.map(i=>i.sendEventsQueueSync(e)).some(i=>i);return r?(this.removeProcessedEvents(t),this.emitEventsQueue(e)):a("debug","Sync send complete failure, events kept in queue for retry",{data:{eventCount:t.length,sessionId:e.session_id}}),r}async sendBatchAsync(e,t){const s=this.dataSenders.map(async o=>o.sendEventsQueue(e,{onSuccess:()=>{},onFailure:()=>{}})),r=await Promise.allSettled(s),i=r.some(o=>this.isSuccessfulResult(o));if(i){this.removeProcessedEvents(t),this.emitEventsQueue(e);const o=r.filter(c=>!this.isSuccessfulResult(c)).length;o>0&&a("debug","Async send completed with some failures, removed from queue and persisted per-integration",{data:{eventCount:t.length,failedCount:o,sessionId:e.session_id}})}else a("debug","Async send complete failure, events kept in queue for retry",{data:{eventCount:t.length,sessionId:e.session_id}});return i}async sendEventsQueue(){if(!(this.eventsQueue.length===0||this.sendInProgress)){this.sendInProgress=!0;try{const e=this.buildBatchesWithIds();if(e.length===0)return;if(this.dataSenders.length===0){for(const{batch:r}of e)this.emitEventsQueue(r);return}(await Promise.all(e.map(async({batch:r,eventIds:i})=>this.sendBatchAsync(r,i)))).some(Boolean)?this.consecutiveSendFailures=0:this.consecutiveSendFailures=Math.min(this.consecutiveSendFailures+1,5),this.eventsQueue.length===0?this.clearSendTimeout():this.scheduleSendTimeout()}finally{this.sendInProgress=!1,this.drainPendingSyncFlush()}}}buildBatchFromGroup(e,t){const s=new Map,r=[];for(const u of t){const f=this.createEventSignature(u);s.has(f)||r.push(f),s.set(f,u)}const i=r.map(u=>s.get(u)).filter(u=>!!u).sort((u,f)=>u.type===d.SESSION_START&&f.type!==d.SESSION_START?-1:f.type===d.SESSION_START&&u.type!==d.SESSION_START?1:u.timestamp-f.timestamp).map(({_session_id:u,...f})=>f),o=this.get("config")?.globalMetadata,c=this.get("identity");return{user_id:this.get("userId"),session_id:e,device:this.get("device"),events:i,...o&&{global_metadata:o},...c&&{identify:c}}}buildEventPayload(e){const t=this.get("sessionId");if(!t)return a("error","buildEventPayload reached without sessionId — event dropped",{data:{type:e.type},visibility:"critical"}),null;const s=e.page_url??this.get("pageUrl"),r=typeof s=="string"&&s.length>0?s:"unknown",i=this.timeManager.now(),o=this.timeManager.validateTimestamp(i);o.valid||a("warn","Event timestamp validation failed",{data:{type:e.type,error:o.error}});const c=this.get("sessionReferrer"),l=this.get("sessionUtm"),u=this.get("sessionClickIds");return{...{id:ns(),type:e.type,page_url:r,timestamp:i,...c&&{referrer:c},...e.from_page_url&&{from_page_url:e.from_page_url},...e.scroll_data&&{scroll_data:e.scroll_data},...e.click_data&&{click_data:e.click_data},...e.custom_event&&{custom_event:e.custom_event},...e.web_vitals&&{web_vitals:e.web_vitals},...e.error_data&&{error_data:e.error_data},...e.page_view&&{page_view:e.page_view},...l&&{utm:l},...u&&{click_ids:u}},_session_id:t}}isDuplicateEvent(e){const t=Date.now(),s=this.createEventFingerprint(e),r=this.recentEventFingerprints.get(s);return r&&t-r<1e3?(this.recentEventFingerprints.set(s,t),!0):(this.recentEventFingerprints.set(s,t),this.recentEventFingerprints.size>1500&&this.pruneOldFingerprints(),this.recentEventFingerprints.size>3e3&&(this.recentEventFingerprints.clear(),this.recentEventFingerprints.set(s,t),a("debug","Event fingerprint cache exceeded hard limit, cleared",{data:{hardLimit:3e3}})),!1)}pruneOldFingerprints(){const e=Date.now(),t=1e3*10;for(const[s,r]of this.recentEventFingerprints.entries())e-r>t&&this.recentEventFingerprints.delete(s);a("debug","Pruned old event fingerprints",{data:{remaining:this.recentEventFingerprints.size,cutoffMs:t}})}createEventFingerprint(e){let t=`${e.type}_${e.page_url}`;if(e.click_data){const s=Math.round((e.click_data.x||0)/10)*10,r=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${s}_${r}`}return e.scroll_data&&(t+=`_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`),e.custom_event&&(t+=`_custom_${e.custom_event.name}`,e.custom_event.metadata&&(t+=`_${this.stableStringify(e.custom_event.metadata)}`)),e.web_vitals&&(t+=`_vitals_${e.web_vitals.type}`),e.error_data&&(t+=`_error_${e.error_data.type}_${e.error_data.message}`),t}createEventSignature(e){return this.createEventFingerprint(e)}stableStringify(e){return JSON.stringify(e,(t,s)=>s&&typeof s=="object"&&!Array.isArray(s)?Object.keys(s).sort().reduce((r,i)=>(r[i]=s[i],r),{}):s)}addToQueue(e){if(this.emitEvent(e),this.eventsQueue.push(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(r=>r.type!==d.SESSION_START),s=t>=0?this.eventsQueue.splice(t,1)[0]:this.eventsQueue.shift();a("warn","Event queue overflow, oldest non-critical event removed",{data:{maxLength:100,currentLength:this.eventsQueue.length,removedEventType:s?.type,wasCritical:s?.type===d.SESSION_START}})}this.scheduleSendTimeout(),this.eventsQueue.length>=50&&this.consecutiveSendFailures<5&&this.sendEventsQueue()}scheduleSendTimeout(){if(this.sendTimeoutId!==null)return;const e=this.calculateSendDelay();this.sendTimeoutId=window.setTimeout(()=>{this.sendTimeoutId=null,this.eventsQueue.length>0&&this.sendEventsQueue()},e)}calculateSendDelay(){const e=this.get("config")?.sendIntervalMs??1e4;if(this.consecutiveSendFailures===0)return e;const t=e*Math.pow(2,this.consecutiveSendFailures);return Math.min(t,12e4)}shouldSample(){const e=this.get("config")?.samplingRate??1;return Math.random()<e}checkRateLimit(){const e=Date.now();return e-this.rateLimitWindowStart>1e3&&(this.rateLimitCounter=0,this.rateLimitWindowStart=e),this.rateLimitCounter>=50?!1:(this.rateLimitCounter++,!0)}checkPerEventRateLimit(e,t){const s=Date.now(),i=(this.perEventRateLimits.get(e)??[]).filter(o=>s-o<6e4);return i.length>=t?(a("warn","Per-event rate limit exceeded for custom event",{data:{eventName:e,limit:t,window:`${6e4/1e3}s`}}),!1):(i.push(s),this.perEventRateLimits.set(e,i),!0)}getTypeLimitForEvent(e){return{[d.CLICK]:500,[d.PAGE_VIEW]:100,[d.CUSTOM]:500,[d.SCROLL]:120}[e]??null}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(s=>!t.has(s.id))}emitEvent(e){if(this.emitter){const{_session_id:t,...s}=e;this.emitter.emit(C.EVENT,s)}}emitEventsQueue(e){this.emitter&&this.emitter.emit(C.QUEUE,e)}debounce(e,t){let s=null;return((...r)=>{s!==null&&clearTimeout(s),s=setTimeout(()=>{e(...r),s=null},t)})}getInitialCounts(){return{total:0,[d.CLICK]:0,[d.PAGE_VIEW]:0,[d.CUSTOM]:0,[d.SCROLL]:0}}loadSessionCounts(e){if(typeof window>"u"||typeof localStorage>"u")return this.getInitialCounts();const t=this.get("userId")||"anonymous",s=Ge(t,e);try{const r=localStorage.getItem(s);if(!r)return this.getInitialCounts();const i=JSON.parse(r);return i._timestamp&&Date.now()-i._timestamp>We?(a("debug","Session counts expired, clearing",{data:{sessionId:e,age:Date.now()-i._timestamp}}),localStorage.removeItem(s),this.getInitialCounts()):typeof i.total=="number"&&typeof i[d.CLICK]=="number"&&typeof i[d.PAGE_VIEW]=="number"&&typeof i[d.CUSTOM]=="number"&&typeof i[d.SCROLL]=="number"?{total:i.total,[d.CLICK]:i[d.CLICK],[d.PAGE_VIEW]:i[d.PAGE_VIEW],[d.CUSTOM]:i[d.CUSTOM],[d.SCROLL]:i[d.SCROLL]}:(a("warn","Invalid session counts structure in localStorage, resetting",{data:{sessionId:e,parsed:i}}),localStorage.removeItem(s),a("debug","Session counts removed due to invalid/corrupted data",{data:{sessionId:e,parsed:i}}),this.getInitialCounts())}catch(r){return a("warn","Failed to load session counts from localStorage",{error:r,data:{sessionId:e}}),this.getInitialCounts()}}cleanupExpiredSessionCounts(){if(!(typeof window>"u"||typeof localStorage>"u"))try{const e=localStorage.getItem(Ke);if(e){const i=Date.now()-parseInt(e,10);if(i<je){a("debug","Skipping session counts cleanup (throttled)",{data:{timeSinceLastCleanup:i,throttleMs:je}});return}}const t=this.get("userId")||"anonymous",s=`${m}:${t}:session_counts:`,r=[];for(let i=0;i<localStorage.length;i++){const o=localStorage.key(i);if(o?.startsWith(s))try{const c=localStorage.getItem(o);if(c){const l=JSON.parse(c);l._timestamp&&Date.now()-l._timestamp>We&&r.push(o)}}catch{}}r.forEach(i=>{localStorage.removeItem(i),a("debug","Cleaned up expired session counts",{data:{key:i}})}),r.length>0&&a("info",`Cleaned up ${r.length} expired session counts entries`),localStorage.setItem(Ke,Date.now().toString())}catch(e){a("warn","Failed to cleanup expired session counts",{error:e})}}saveSessionCounts(e){const t=this.get("userId")||"anonymous",s=Ge(t,e);try{const r={...this.sessionEventCounts,_timestamp:Date.now(),_version:1};localStorage.setItem(s,JSON.stringify(r))}catch(r){a("warn","Failed to persist session counts to localStorage",{error:r,data:{sessionId:e}})}}}class bs{static getId(e){const t=e.getItem(ue);if(t)return t;const s=rt();return e.setItem(ue,s),s}}const Rs=/^\d{13}-[a-z0-9]{9}$/;class Cs extends E{storageManager;eventManager;projectId;activityHandler=null;visibilityChangeHandler=null;sessionTimeoutId=null;broadcastChannel=null;isTracking=!1;needsRenewal=!1;prerenderActivationHandler=null;constructor(e,t,s){super(),this.storageManager=e,this.eventManager=t,this.projectId=s}initCrossTabSync(){if(typeof BroadcastChannel>"u"){a("debug","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel(Mt(e)),this.broadcastChannel.onmessage=t=>{const{action:s,sessionId:r,timestamp:i,projectId:o}=t.data??{};if(o===e)if(s==="session_start"&&r&&typeof i=="number"&&i>Date.now()-5e3){this.set("sessionId",r);const c=this.loadStoredSession();this.set("sessionReferrer",c?.referrer),this.set("sessionUtm",c?.utm),this.set("sessionClickIds",c?.clickIds),this.persistSession(r,i,c?.referrer,c?.utm,c?.clickIds),this.isTracking&&this.setupSessionTimeout()}else s&&s!=="session_start"&&a("debug","Ignored BroadcastChannel message with unknown action",{data:{action:s}})}}shareSession(e){this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function"&&this.broadcastChannel.postMessage({action:"session_start",projectId:this.getProjectId(),sessionId:e,timestamp:Date.now()})}cleanupCrossTabSync(){this.broadcastChannel&&(typeof this.broadcastChannel.close=="function"&&this.broadcastChannel.close(),this.broadcastChannel=null)}recoverSession(){const e=this.loadStoredSession();if(!e)return null;if(!Rs.test(e.id))return a("warn","Invalid session ID format recovered from storage, clearing",{data:{sessionId:e.id}}),this.clearStoredSession(),null;const t=this.get("config")?.sessionTimeout??9e5;return Date.now()-e.lastActivity>t?(this.clearStoredSession(),null):e.id}persistSession(e,t=Date.now(),s,r,i){this.saveStoredSession({id:e,lastActivity:t,...s&&{referrer:s},...r&&{utm:r},...i&&{clickIds:i}})}clearStoredSession(){const e=this.getSessionStorageKey();this.storageManager.removeItem(e)}loadStoredSession(){const e=this.getSessionStorageKey(),t=this.storageManager.getItem(e);if(t!==null)try{const r=JSON.parse(t);if(r.id&&typeof r.lastActivity=="number")return r}catch{this.storageManager.removeItem(e)}const s=this.storageManager.getSessionItem(e);if(s!==null)try{const r=JSON.parse(s);if(r.id&&typeof r.lastActivity=="number")return r}catch{this.storageManager.removeSessionItem(e)}return null}saveStoredSession(e){const t=this.getSessionStorageKey(),s=JSON.stringify(e);this.storageManager.setItem(t,s),this.storageManager.setSessionItem(t,s)}getSessionStorageKey(){return At(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){a("debug","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId();let s,r,i;if(e){const o=this.loadStoredSession();s=o?.referrer??ve(),r=o?.utm??ye(),i=o?.clickIds??pe()}else s=ve(),r=ye(),i=pe();a("debug","Session tracking initialized",{data:{sessionId:t,wasRecovered:!!e,willEmitSessionStart:!e,sessionReferrer:s,hasUtm:!!r,hasClickIds:!!i}}),this.isTracking=!0;try{if(this.set("sessionId",t),this.set("sessionReferrer",s),this.set("sessionUtm",r),this.set("sessionClickIds",i),st()){this.prerenderActivationHandler=()=>{this.prerenderActivationHandler=null,this.activateSession(t,e,s,r,i)},document.addEventListener("prerenderingchange",this.prerenderActivationHandler,{once:!0});return}this.activateSession(t,e,s,r,i)}catch(o){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),o}}activateSession(e,t,s,r,i){this.persistSession(e,Date.now(),s,r,i),this.initCrossTabSync(),this.shareSession(e),t?a("debug","Session recovered, skipping SESSION_START",{data:{sessionId:e}}):(a("debug","Emitting SESSION_START event",{data:{sessionId:e}}),this.eventManager.track({type:d.SESSION_START})),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}generateSessionId(){return`${Date.now()}-${Math.random().toString(36).substring(2,11)}`}setupSessionTimeout(){this.clearSessionTimeout();const e=this.get("config")?.sessionTimeout??9e5;this.sessionTimeoutId=setTimeout(()=>{this.enterRenewalMode()},e)}resetSessionTimeout(){this.setupSessionTimeout();const e=this.get("sessionId");e&&this.persistSession(e,Date.now(),this.get("sessionReferrer"),this.get("sessionUtm"),this.get("sessionClickIds"))}clearSessionTimeout(){this.sessionTimeoutId&&(clearTimeout(this.sessionTimeoutId),this.sessionTimeoutId=null)}setupActivityListeners(){this.activityHandler=()=>{this.needsRenewal?this.renewSession():this.resetSessionTimeout()},document.addEventListener("click",this.activityHandler,{passive:!0}),document.addEventListener("keydown",this.activityHandler,{passive:!0}),document.addEventListener("scroll",this.activityHandler,{passive:!0})}renewSession(){this.needsRenewal=!1;const e=this.generateSessionId(),t=ve(),s=ye(),r=pe();a("debug","Renewing session after timeout",{data:{newSessionId:e}}),this.set("sessionId",e),this.set("sessionReferrer",t),this.set("sessionUtm",s),this.set("sessionClickIds",r),this.persistSession(e,Date.now(),t,s,r),this.cleanupCrossTabSync(),this.initCrossTabSync(),this.shareSession(e),this.eventManager.track({type:d.SESSION_START}),this.eventManager.flushPendingEvents(),this.setupSessionTimeout()}cleanupActivityListeners(){this.activityHandler&&(document.removeEventListener("click",this.activityHandler),document.removeEventListener("keydown",this.activityHandler),document.removeEventListener("scroll",this.activityHandler),this.activityHandler=null)}setupLifecycleListeners(){this.visibilityChangeHandler||(this.visibilityChangeHandler=()=>{if(document.hidden)this.clearSessionTimeout();else{if(this.isSessionStale()){a("debug","Session expired during suspend, entering renewal mode"),this.enterRenewalMode();return}this.get("sessionId")&&this.setupSessionTimeout()}},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}isSessionStale(){if(this.needsRenewal||!this.get("sessionId"))return!1;const t=this.loadStoredSession();if(!t)return!1;const s=this.get("config")?.sessionTimeout??9e5;return Date.now()-t.lastActivity>s}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null)}enterRenewalMode(){this.clearSessionTimeout(),this.cleanupCrossTabSync(),this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.set("sessionReferrer",void 0),this.set("sessionUtm",void 0),this.set("sessionClickIds",void 0),this.needsRenewal=!0,a("debug","Session timed out, entering renewal mode")}resetSessionState(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.cleanupPrerenderActivation(),this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.set("sessionReferrer",void 0),this.set("sessionUtm",void 0),this.set("sessionClickIds",void 0),this.needsRenewal=!1,this.isTracking=!1}stopTracking(){this.resetSessionState()}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.cleanupPrerenderActivation(),this.isTracking=!1,this.needsRenewal=!1,this.set("hasStartSession",!1)}cleanupPrerenderActivation(){this.prerenderActivationHandler&&(document.removeEventListener("prerenderingchange",this.prerenderActivationHandler),this.prerenderActivationHandler=null)}}class Ns extends E{eventManager;storageManager;sessionManager=null;destroyed=!1;constructor(e,t){super(),this.eventManager=t,this.storageManager=e}startTracking(){if(this.isActive())return;if(this.destroyed){a("debug","Cannot start tracking on destroyed handler");return}const t=this.get("config")?.integrations?.tracelog?.projectId??"custom";try{this.sessionManager=new Cs(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(s){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw a("error","Failed to start session tracking",{error:s}),s}}isActive(){return this.sessionManager!==null&&!this.destroyed}cleanupSessionManager(){this.sessionManager&&(this.sessionManager.stopTracking(),this.sessionManager.destroy(),this.sessionManager=null)}stopTracking(){this.cleanupSessionManager()}destroy(){this.destroyed||(this.sessionManager&&(this.sessionManager.destroy(),this.sessionManager=null),this.destroyed=!0)}}class Os extends E{eventManager;onTrack;originalPushState;originalReplaceState;lastPageViewTime=0;constructor(e,t){super(),this.eventManager=e,this.onTrack=t}startTracking(){this.trackInitialPageView(),window.addEventListener("popstate",this.trackCurrentPage,!0),window.addEventListener("hashchange",this.trackCurrentPage,!0),this.patchHistory("pushState"),this.patchHistory("replaceState")}stopTracking(){window.removeEventListener("popstate",this.trackCurrentPage,!0),window.removeEventListener("hashchange",this.trackCurrentPage,!0),this.originalPushState&&(window.history.pushState=this.originalPushState),this.originalReplaceState&&(window.history.replaceState=this.originalReplaceState),this.lastPageViewTime=0}patchHistory(e){const t=window.history[e];e==="pushState"&&!this.originalPushState?this.originalPushState=t:e==="replaceState"&&!this.originalReplaceState&&(this.originalReplaceState=t),window.history[e]=(...s)=>{t.apply(window.history,s),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=Ie(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;const s=Date.now(),r=this.get("config").pageViewThrottleMs??1e3;if(s-this.lastPageViewTime<r)return;this.lastPageViewTime=s,this.onTrack();const i=this.get("pageUrl");this.set("pageUrl",t);const o=this.extractPageViewData();this.eventManager.track({type:d.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:i,...o&&{page_view:o}}),this.get("config").flushOnSpaNavigation===!0&&this.eventManager.flushImmediately()};trackInitialPageView(){const e=Ie(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.lastPageViewTime=Date.now(),this.eventManager.track({type:d.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{referrer:e}=document,{title:t}=document;if(!(!e&&!t))return{...e&&{referrer:e},...t&&{title:t}}}}class Ps extends E{eventManager;lastClickTimes=new Map;clickHandler;lastPruneTime=0;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,s=t.target,r=typeof HTMLElement<"u"&&s instanceof HTMLElement?s:typeof HTMLElement<"u"&&s instanceof Node&&s.parentElement instanceof HTMLElement?s.parentElement:null;if(!r){a("debug","Click target not found or not an element");return}if(this.shouldIgnoreElement(r))return;const i=this.get("config")?.clickThrottleMs??300;if(i>0&&!this.checkClickThrottle(r,i))return;const o=this.findTrackingElement(r),c=this.getRelevantClickElement(r),l=this.calculateClickCoordinates(t);if(o){const f=this.extractTrackingData(o);if(f){const S=this.createCustomEventData(f);this.eventManager.track({type:d.CUSTOM,custom_event:{name:S.name,...S.value&&{metadata:{value:S.value}}}})}}if(!l){a("debug","Click skipped: invalid coordinates (likely synthetic)");return}const u=this.generateClickData(r,c,l);this.eventManager.track({type:d.CLICK,click_data:u})},window.addEventListener("click",this.clickHandler,!0))}stopTracking(){this.clickHandler&&(window.removeEventListener("click",this.clickHandler,!0),this.clickHandler=void 0),this.lastClickTimes.clear(),this.lastPruneTime=0}shouldIgnoreElement(e){return e.hasAttribute(`${L}-ignore`)?!0:e.closest(`[${L}-ignore]`)!==null}checkClickThrottle(e,t){const s=this.getElementSignature(e),r=Date.now();this.pruneThrottleCache(r);const i=this.lastClickTimes.get(s);return i!==void 0&&r-i<t?(a("debug","ClickHandler: Click suppressed by throttle",{data:{signature:s,throttleRemaining:t-(r-i)}}),!1):(this.lastClickTimes.set(s,r),!0)}pruneThrottleCache(e){if(e-this.lastPruneTime<3e4)return;this.lastPruneTime=e;const t=e-3e5;for(const[s,r]of this.lastClickTimes.entries())r<t&&this.lastClickTimes.delete(s);if(this.lastClickTimes.size>1e3){const s=Array.from(this.lastClickTimes.entries()).sort((o,c)=>o[1]-c[1]),r=this.lastClickTimes.size-1e3,i=s.slice(0,r);for(const[o]of i)this.lastClickTimes.delete(o);a("debug","ClickHandler: Pruned throttle cache",{data:{removed:i.length,remaining:this.lastClickTimes.size}})}}getElementSignature(e){if(e.id)return`#${e.id}`;const t=e.getAttribute("data-testid");if(t)return`[data-testid="${t}"]`;const s=e.getAttribute(`${L}-name`);return s?`[${L}-name="${s}"]`:this.getElementPath(e)}getElementPath(e){const t=[];let s=e;for(;s&&s!==document.body;){let r=s.tagName.toLowerCase();if(s.className){const i=s.className.split(" ")[0];i&&(r+=`.${i}`)}t.unshift(r),s=s.parentElement}return t.join(">")||"unknown"}findTrackingElement(e){return e.hasAttribute(`${L}-name`)?e:e.closest(`[${L}-name]`)}getRelevantClickElement(e){for(const t of vt)try{if(e.matches(t))return e;const s=e.closest(t);if(s)return s}catch(s){a("debug","Invalid selector in element search",{error:s,data:{selector:t}});continue}return e}calculateClickCoordinates(e){const t=e.clientX,s=e.clientY;return typeof t!="number"||typeof s!="number"||!Number.isFinite(t)||!Number.isFinite(s)||t===0&&s===0&&!e.isTrusted?null:{x:t,y:s}}extractTrackingData(e){const t=e.getAttribute(`${L}-name`),s=e.getAttribute(`${L}-value`);if(t)return{element:e,name:t,...s&&{value:s}}}generateClickData(e,t,s){const{x:r,y:i}=s,o=this.getRelevantText(e,t),c=t.getAttribute("href")??void 0;return{x:r,y:i,tag:t.tagName.toLowerCase(),...t.id&&{id:t.id},...t.className&&{class:t.className},...o&&{text:o},...c&&{href:c}}}getRelevantText(e,t){const s=e.textContent?.trim()??"",r=t.textContent?.trim()??"";if(!s&&!r)return"";let i="";return s&&s.length<=255?i=s:r.length<=255?i=r:i=r.slice(0,252)+"...",te(i)}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class Ds extends E{eventManager;containers=[];limitWarningLogged=!1;containerDiscoveryTimeoutId=null;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.set("scrollEventCount",0),this.tryDetectScrollContainers(0)}stopTracking(){this.containerDiscoveryTimeoutId!==null&&(clearTimeout(this.containerDiscoveryTimeoutId),this.containerDiscoveryTimeoutId=null);for(const e of this.containers)this.clearContainerTimer(e),e.element===window?window.removeEventListener("scroll",e.listener):e.element.removeEventListener("scroll",e.listener);this.containers.length=0,this.set("scrollEventCount",0),this.limitWarningLogged=!1}tryDetectScrollContainers(e){const t=this.findScrollableElements();if(this.isWindowScrollable()&&this.setupScrollContainer(window,"window"),t.length>0){for(const s of t){const r=this.getElementSelector(s);this.setupScrollContainer(s,r)}return}if(e<5){this.containerDiscoveryTimeoutId=window.setTimeout(()=>{this.containerDiscoveryTimeoutId=null,this.tryDetectScrollContainers(e+1)},200);return}this.containers.length===0&&this.setupScrollContainer(window,"window")}findScrollableElements(){if(!document.body)return[];const e=[],t=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,{acceptNode:r=>{const i=r;if(!i.isConnected||!i.offsetParent)return NodeFilter.FILTER_SKIP;const o=getComputedStyle(i);return o.overflowY==="auto"||o.overflowY==="scroll"||o.overflow==="auto"||o.overflow==="scroll"?NodeFilter.FILTER_ACCEPT:NodeFilter.FILTER_SKIP}});let s;for(;(s=t.nextNode())&&e.length<10;){const r=s;this.isElementScrollable(r)&&e.push(r)}return e}getElementSelector(e){if(e===window)return"window";const t=e;if(t.id)return`#${t.id}`;if(t.className&&typeof t.className=="string"){const s=t.className.split(" ").filter(r=>r.trim())[0];if(s)return`.${s}`}return t.tagName.toLowerCase()}setupScrollContainer(e,t){if(this.containers.some(l=>l.element===e)||e!==window&&!this.isElementScrollable(e))return;const r=this.getScrollTop(e),i=this.calculateScrollDepth(r,this.getScrollHeight(e),this.getViewportHeight(e)),o={element:e,selector:t,lastScrollPos:r,lastDepth:i,lastEventTime:0,debounceTimer:null,listener:null},c=()=>{this.get("suppressNextScroll")||(this.clearContainerTimer(o),o.debounceTimer=window.setTimeout(()=>{const l=this.calculateScrollData(o);l&&this.processScrollEvent(o,l,Date.now()),o.debounceTimer=null},250))};o.listener=c,this.containers.push(o),e===window?window.addEventListener("scroll",c,{passive:!0}):e.addEventListener("scroll",c,{passive:!0})}processScrollEvent(e,t,s){if(!this.shouldEmitScrollEvent(e,t,s))return;e.lastEventTime=s,e.lastDepth=t.depth;const r=this.get("scrollEventCount")??0;this.set("scrollEventCount",r+1),this.eventManager.track({type:d.SCROLL,scroll_data:{...t,container_selector:e.selector}})}shouldEmitScrollEvent(e,t,s){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,s)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=120}hasElapsedMinimumInterval(e,t){return e.lastEventTime===0?!0:t-e.lastEventTime>=500}hasSignificantDepthChange(e,t){return Math.abs(t-e.lastDepth)>=5}logLimitOnce(){this.limitWarningLogged||(this.limitWarningLogged=!0,a("debug","Max scroll events per session reached",{data:{limit:120}}))}isWindowScrollable(){return document.documentElement.scrollHeight>window.innerHeight}clearContainerTimer(e){e.debounceTimer!==null&&(clearTimeout(e.debounceTimer),e.debounceTimer=null)}getScrollDirection(e,t){return e>t?Q.DOWN:Q.UP}calculateScrollDepth(e,t,s){if(t<=s)return 0;const r=t-s;return Math.min(100,Math.max(0,Math.floor(e/r*100)))}calculateScrollData(e){const{element:t,lastScrollPos:s}=e,r=this.getScrollTop(t);if(Math.abs(r-s)<10||t===window&&!this.isWindowScrollable())return null;const o=this.getViewportHeight(t),c=this.getScrollHeight(t),l=this.getScrollDirection(r,s),u=this.calculateScrollDepth(r,c,o);return e.lastScrollPos=r,{depth:u,direction:l}}getScrollTop(e){return e===window?window.scrollY:e.scrollTop}getViewportHeight(e){return e===window?window.innerHeight:e.clientHeight}getScrollHeight(e){return e===window?document.documentElement.scrollHeight:e.scrollHeight}isElementScrollable(e){const t=getComputedStyle(e),s=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflow==="auto"||t.overflow==="scroll",r=e.scrollHeight>e.clientHeight;return s&&r}}const ks="tracelog_session_id",Us="tracelog_user_id";class Fs extends E{visibilityHandler=null;pageshowHandler=null;lastSyncedKey=null;activate(){this.cleanupListeners(),this.syncCartAttribute(),this.setupListeners()}deactivate(){this.cleanupListeners(),this.lastSyncedKey=null}onSessionChange(){this.syncCartAttribute()}syncCartAttribute(){const e=this.get("sessionId");if(!e)return;const t=this.get("userId"),s=typeof t=="string"&&t.length>0?t:"",r=`${e}|${s}`;r!==this.lastSyncedKey&&(this.lastSyncedKey=r,this.postCartUpdate(e,s))}postCartUpdate(e,t){const s={[ks]:e};t.length>0&&(s[Us]=t);try{fetch("/cart/update.js",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({attributes:s}),credentials:"same-origin"}).then(r=>{r.ok||(this.lastSyncedKey=null,a("debug","Shopify cart attribute update failed",{data:{status:r.status}}))}).catch(()=>{this.lastSyncedKey=null,a("debug","Shopify cart attribute update failed")})}catch{this.lastSyncedKey=null,a("debug","Shopify cart attribute update failed")}}setupListeners(){this.visibilityHandler=()=>{document.hidden||this.syncCartAttribute()},document.addEventListener("visibilitychange",this.visibilityHandler),this.pageshowHandler=e=>{e.persisted&&this.syncCartAttribute()},window.addEventListener("pageshow",this.pageshowHandler)}cleanupListeners(){this.visibilityHandler&&(document.removeEventListener("visibilitychange",this.visibilityHandler),this.visibilityHandler=null),this.pageshowHandler&&(window.removeEventListener("pageshow",this.pageshowHandler),this.pageshowHandler=null)}}class Vs{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||a("debug","localStorage not available, using memory fallback"),this.sessionStorageRef||a("debug","sessionStorage not available, using memory fallback")}getItem(e){try{return this.storage?this.storage.getItem(e):this.fallbackStorage.get(e)??null}catch{return this.fallbackStorage.get(e)??null}}setItem(e,t){if(this.fallbackStorage.set(e,t),!!this.storage)try{this.storage.setItem(e,t);return}catch(s){if(!(s instanceof DOMException&&s.name==="QuotaExceededError"||s instanceof Error&&s.name==="QuotaExceededError"))return;if(a("warn","localStorage quota exceeded, attempting cleanup",{data:{key:e,valueSize:t.length}}),!this.cleanupOldData()){a("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:s,data:{key:e,valueSize:t.length}});return}try{this.storage.setItem(e,t)}catch(i){a("error","localStorage quota exceeded even after cleanup - data will not persist",{error:i,data:{key:e,valueSize:t.length}})}}}removeItem(e){try{this.storage&&this.storage.removeItem(e)}catch{}this.fallbackStorage.delete(e)}cleanupOldData(){if(!this.storage)return!1;try{const e=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],t=[],s=[];for(let i=0;i<this.storage.length;i++){const o=this.storage.key(i);o?.startsWith("tracelog_")&&(o.startsWith("tracelog_persisted_events_")?t.push(o):e.some(c=>o.startsWith(c))||s.push(o))}const r=[...t,...s.slice(0,5)];return r.length===0?!1:(r.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0)}catch(e){return a("error","Failed to cleanup old data",{error:e}),!1}}initializeStorage(e){if(typeof window>"u")return null;try{const t=e==="localStorage"?window.localStorage:window.sessionStorage,s="__tracelog_test__";return t.setItem(s,"test"),t.removeItem(s),t}catch{return null}}getSessionItem(e){try{return this.sessionStorageRef?this.sessionStorageRef.getItem(e):this.fallbackSessionStorage.get(e)??null}catch{return this.fallbackSessionStorage.get(e)??null}}setSessionItem(e,t){this.fallbackSessionStorage.set(e,t);try{if(this.sessionStorageRef){this.sessionStorageRef.setItem(e,t);return}}catch(s){(s instanceof DOMException&&s.name==="QuotaExceededError"||s instanceof Error&&s.name==="QuotaExceededError")&&a("error","sessionStorage quota exceeded - data will not persist",{error:s,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class Hs extends E{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds;navigationCounter=0;constructor(e){super(),this.eventManager=e,this.vitalThresholds=_e(J)}async startTracking(){const e=this.get("config"),t=e?.webVitalsMode??J;this.vitalThresholds=_e(t),e?.webVitalsThresholds&&(this.vitalThresholds={...this.vitalThresholds,...e.webVitalsThresholds}),await this.initWebVitals()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(s){a("debug","Failed to disconnect performance observer",{error:s,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear(),this.navigationHistory.length=0}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",s=>{const r=s.getEntries(),i=r[r.length-1];i&&this.sendVital({type:"LCP",value:Number(i.startTime.toFixed(2))})},{type:"largest-contentful-paint",buffered:!0},!0);let e=0,t=this.getNavigationId();this.safeObserve("layout-shift",s=>{const r=this.getNavigationId();r!==t&&(e=0,t=r);const i=s.getEntries();for(const o of i){if(o.hadRecentInput===!0)continue;const c=typeof o.value=="number"?o.value:0;e+=c}this.sendVital({type:"CLS",value:Number(e.toFixed(2))})},{type:"layout-shift",buffered:!0}),this.safeObserve("paint",s=>{for(const r of s.getEntries())r.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(r.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",s=>{let r=0;const i=s.getEntries();for(const o of i){const c=(o.processingEnd??0)-(o.startTime??0);r=Math.max(r,c)}r>0&&this.sendVital({type:"INP",value:Number(r.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:s,onTTFB:r,onINP:i}=await Promise.resolve().then(()=>sn),o=c=>l=>{const u=Number(l.value.toFixed(2));this.sendVital({type:c,value:u})};e(o("LCP"),{reportAllChanges:!1}),t(o("CLS"),{reportAllChanges:!1}),s(o("FCP"),{reportAllChanges:!1}),r(o("TTFB"),{reportAllChanges:!1}),i(o("INP"),{reportAllChanges:!1})}catch(e){a("debug","Failed to load web-vitals library, using fallback",{error:e}),this.observeWebVitalsFallback()}}reportTTFB(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return;const t=e.responseStart;typeof t=="number"&&Number.isFinite(t)&&this.sendVital({type:"TTFB",value:Number(t.toFixed(2))})}catch(e){a("debug","Failed to report TTFB",{error:e})}}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const s=this.reportedByNav.get(t);if(s?.has(e.type))return;if(s)s.add(e.type);else if(this.reportedByNav.set(t,new Set([e.type])),this.navigationHistory.push(t),this.navigationHistory.length>Yt){const i=this.navigationHistory.shift();i&&this.reportedByNav.delete(i)}}this.trackWebVital(e.type,e.value)}trackWebVital(e,t){if(!Number.isFinite(t)){a("debug","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:d.WEB_VITALS,web_vitals:{type:e,value:t}})}getNavigationId(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return null;const t=e.startTime||performance.now(),s=++this.navigationCounter,r=`${t.toFixed(2)}_${window.location.pathname}`;return s>1?`${r}_${s}`:r}catch(e){return a("debug","Failed to get navigation ID",{error:e}),null}}isObserverSupported(e){if(typeof PerformanceObserver>"u")return!1;const t=PerformanceObserver.supportedEntryTypes;return!t||t.includes(e)}safeObserve(e,t,s,r=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((o,c)=>{try{t(o,c)}catch(l){a("debug","Observer callback failed",{error:l,data:{type:e}})}if(r)try{c.disconnect()}catch{}});return i.observe(s??{type:e,buffered:!0}),r||this.observers.push(i),!0}catch(i){return a("debug","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return a("debug","Invalid web vital value",{data:{type:e,value:t}}),!1;const s=this.vitalThresholds[e];return!(typeof s=="number"&&t<=s)}}class se extends E{eventManager;emitter;recentErrors=new Map;pageviewSignatureCounts=new Map;errorBurstCounter=0;burstWindowStart=0;burstBackoffUntil=0;pagehideHandler=null;pageviewResetListener=null;constructor(e,t){super(),this.eventManager=e,this.emitter=t}startTracking(){window.addEventListener("error",this.handleError),window.addEventListener("unhandledrejection",this.handleRejection),this.pagehideHandler=()=>{this.resetPageviewCounter()},window.addEventListener("pagehide",this.pagehideHandler,{passive:!0}),this.emitter&&(this.pageviewResetListener=e=>{(e.type===d.SESSION_START||e.type===d.PAGE_VIEW)&&this.resetPageviewCounter()},this.emitter.on(C.EVENT,this.pageviewResetListener))}stopTracking(){window.removeEventListener("error",this.handleError),window.removeEventListener("unhandledrejection",this.handleRejection),this.pagehideHandler&&(window.removeEventListener("pagehide",this.pagehideHandler),this.pagehideHandler=null),this.emitter&&this.pageviewResetListener&&(this.emitter.off(C.EVENT,this.pageviewResetListener),this.pageviewResetListener=null),this.recentErrors.clear(),this.pageviewSignatureCounts.clear(),this.errorBurstCounter=0,this.burstWindowStart=0,this.burstBackoffUntil=0}resetPageviewCounter(){this.pageviewSignatureCounts.clear()}shouldSample(){const e=Date.now();if(e<this.burstBackoffUntil)return!1;if(e-this.burstWindowStart>Xt&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>Gt)return this.burstBackoffUntil=e+et,a("debug","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:et}}),!1;const s=this.get("config").errorSampling??Ze;return Math.random()<s}shouldThrottleBySignature(e){const t=Is(e),s=this.pageviewSignatureCounts.get(t)??0;if(s>=Wt)return a("debug","Error throttled (pageview cap)",{data:{signature:t,count:s}}),!0;const r=s+1;return this.pageviewSignatureCounts.set(t,r),this.pageviewSignatureCounts.size>Kt&&(this.pageviewSignatureCounts.clear(),this.pageviewSignatureCounts.set(t,r)),!1}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");if(this.shouldSuppressError(U.JS_ERROR,t)||this.shouldThrottleBySignature({message:t,filename:e.filename,line:e.lineno,page_url:window.location.href}))return;const s=typeof e.error?.stack=="string"?this.truncateStack(e.error.stack):void 0,r=typeof e.error?.name=="string"&&e.error.name!=="Error"?e.error.name:void 0;this.eventManager.track({type:d.ERROR,error_data:{type:U.JS_ERROR,message:t,...r!==void 0&&{name:r},...e.filename!==""&&{filename:e.filename},...e.lineno!==0&&{line:e.lineno},...e.colno!==0&&{column:e.colno},...s!==void 0&&{stack:s}}})};handleRejection=e=>{if(!this.shouldSample())return;const t=this.extractRejectionMessage(e.reason),s=this.sanitize(t);if(this.shouldSuppressError(U.PROMISE_REJECTION,s)||this.shouldThrottleBySignature({message:s}))return;const r=e.reason instanceof Error&&typeof e.reason.stack=="string"?this.truncateStack(e.reason.stack):void 0,i=e.reason instanceof Error&&e.reason.name!=="Error"?e.reason.name:void 0;this.eventManager.track({type:d.ERROR,error_data:{type:U.PROMISE_REJECTION,message:s,...i!==void 0&&{name:i},...r!==void 0&&{stack:r}}})};extractRejectionMessage(e){if(e==null)return"Unknown rejection";if(typeof e=="string")return e;if(e instanceof Error)return e.message;if(typeof e=="object"&&"message"in e)return String(e.message);try{return JSON.stringify(e)}catch{return"Unserializable rejection"}}sanitize(e){const t=e.length>Ye?e.slice(0,Ye)+"...":e;return te(t)}shouldSuppressError(e,t){const s=Date.now(),r=`${e}:${t}`,i=this.recentErrors.get(r);return i!==void 0&&s-i<Je?(this.recentErrors.set(r,s),!0):(this.recentErrors.set(r,s),this.recentErrors.size>Bt?(this.recentErrors.clear(),this.recentErrors.set(r,s),!1):(this.recentErrors.size>q&&this.pruneOldErrors(),!1))}static TRUNCATION_SUFFIX=`
2
+ ...truncated`;truncateStack(e){if(e.length<=qe)return te(e);const t=qe-se.TRUNCATION_SUFFIX.length,s=e.slice(0,t)+se.TRUNCATION_SUFFIX;return te(s)}pruneOldErrors(){const e=Date.now();for(const[r,i]of this.recentErrors.entries())e-i>Je&&this.recentErrors.delete(r);if(this.recentErrors.size<=q)return;const t=Array.from(this.recentErrors.entries()).sort((r,i)=>r[1]-i[1]),s=this.recentErrors.size-q;for(let r=0;r<s;r+=1){const i=t[r];i&&this.recentErrors.delete(i[0])}}}class xs extends E{isInitialized=!1;suppressNextScrollTimer=null;pageUnloadHandler=null;pageShowHandler=null;visibilityFlushHandler=null;prerenderActivationHandler=null;emitter=new ms;managers={};handlers={};integrationInstances={};get initialized(){return this.isInitialized}async init(e={}){if(this.isInitialized)return{sessionId:this.get("sessionId")??""};this.managers.storage=new Vs;try{return this.setupState(e),this.managers.event=new Ls(this.managers.storage,this.emitter),this.loadPersistedIdentity(),this.initializeHandlers(),this.setupPageLifecycleListeners(),await this.managers.event.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0,{sessionId:this.get("sessionId")??""}}catch(t){this.destroy(!0);const s=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${s}`)}}sendCustomEvent(e,t,s){if(!this.managers.event){a("warn","Cannot send custom event: TraceLog not initialized",{data:{name:e}});return}let r=t;t&&typeof t=="object"&&!Array.isArray(t)&&Object.getPrototypeOf(t)!==Object.prototype&&(r=Object.assign({},t));const{valid:i,error:o,sanitizedMetadata:c}=gs(e,r);if(!i){if(this.get("mode")===X.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${o}`);a("warn",`Custom event "${e}" dropped: ${o}`);return}this.managers.event.track({type:d.CUSTOM,custom_event:{name:e,...c&&{metadata:c}}}),s?.critical===!0&&(this.managers.event.flushImmediatelySync()||a("debug","Critical event flush returned false (deferred to in-flight send or empty queue)",{data:{name:e}}))}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}destroy(e=!1){!this.isInitialized&&!e||(Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(s){a("warn","Failed to stop tracking",{error:s})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.pageUnloadHandler&&(window.removeEventListener("pagehide",this.pageUnloadHandler),window.removeEventListener("beforeunload",this.pageUnloadHandler),this.pageUnloadHandler=null),this.pageShowHandler&&(window.removeEventListener("pageshow",this.pageShowHandler),this.pageShowHandler=null),this.visibilityFlushHandler&&(document.removeEventListener("visibilitychange",this.visibilityFlushHandler),this.visibilityFlushHandler=null),this.prerenderActivationHandler&&(document.removeEventListener("prerenderingchange",this.prerenderActivationHandler),this.prerenderActivationHandler=null),this.managers.event?.flushImmediatelySync(),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.set("suppressNextScroll",!1),this.set("sessionId",null),this.set("identity",void 0),this.clearPersistedIdentity(),this.integrationInstances.shopifyCartLinker?.deactivate(),this.integrationInstances={},this.isInitialized=!1,this.handlers={},this.managers={})}setupState(e={}){this.set("config",e);const t=bs.getId(this.managers.storage);this.set("userId",t);const s=os(e);this.set("collectApiUrls",s);const r=$t();this.set("device",r);const i=Ie(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i),es()&&this.set("mode",X.QA)}getConfig(){return this.get("config")}getCollectApiUrls(){return this.get("collectApiUrls")}getEventManager(){return this.managers.event}getSessionId(){return this.get("sessionId")}getUserId(){return this.get("userId")}identify(e,t){if(!e||typeof e!="string"||e.trim().length===0){a("warn","identify() called with invalid userId",{data:{type:typeof e,length:typeof e=="string"?e.trim().length:0}});return}if(e.trim().length>256){a("warn","identify() userId exceeds 256 characters",{data:{length:e.trim().length}});return}const s=e.trim(),r=Me(t),i={userId:s,...r?{traits:r}:{}};this.set("identity",i),this.persistIdentity(i),a("debug","Visitor identified",{data:{userIdLength:s.length,traitKeys:r?Object.keys(r):[]}})}async resetIdentity(){await this.managers.event?.flushImmediately().catch(t=>(a("debug","Failed to flush before identity reset",{error:t}),!1)),this.set("identity",void 0),this.clearPersistedIdentity();const e=rt();this.managers.storage.setItem(ue,e),this.set("userId",e),this.set("hasStartSession",!1),this.set("sessionId",null),this.handlers.session?.stopTracking(),this.handlers.session?.startTracking(),a("debug","Identity reset, new UUID generated")}getProjectId(){return this.get("config")?.integrations?.tracelog?.projectId??"custom"}persistIdentity(e){try{const t=this.getProjectId(),s=fe(t);this.managers.storage.setItem(s,JSON.stringify(e))}catch{a("debug","Failed to persist identity to localStorage")}}loadPersistedIdentity(){const e=this.managers.storage,t=this.getProjectId(),s=fe(t);try{const r=e.getItem(D);if(r){const i=JSON.parse(r);if(e.removeItem(D),!this.isValidIdentityData(i)){a("debug","Invalid pending identity in localStorage, discarded");return}const o=this.normalizePersistedIdentity(i);e.setItem(s,JSON.stringify(o)),this.set("identity",o),a("debug","Migrated pending identity to project-scoped key");return}}catch{e.removeItem(D)}try{const r=e.getItem(s);if(r){const i=JSON.parse(r);if(!this.isValidIdentityData(i)){e.removeItem(s),a("debug","Invalid persisted identity in localStorage, discarded");return}const o=this.normalizePersistedIdentity(i);this.set("identity",o),a("debug","Loaded persisted identity")}}catch{a("debug","Failed to load persisted identity")}}isValidIdentityData(e){if(!e||typeof e!="object")return!1;const{userId:t}=e;return!(typeof t!="string"||t.trim().length===0||t.trim().length>256)}normalizePersistedIdentity(e){const t=Me(e.traits);return{userId:e.userId.trim(),...t?{traits:t}:{}}}clearPersistedIdentity(){try{const e=this.managers.storage,t=this.getProjectId();e.removeItem(fe(t)),e.removeItem(D)}catch{a("debug","Failed to clear persisted identity")}}setupPageLifecycleListeners(){this.pageUnloadHandler=()=>{this.managers.event?.flushImmediatelySync()},this.pageShowHandler=e=>{e.persisted&&this.managers.event?.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events on bfcache restore",{error:t})})},this.visibilityFlushHandler=()=>{typeof document>"u"||!document.hidden||this.get("config").flushOnPageHidden!==!1&&this.managers.event?.flushImmediatelySync()},window.addEventListener("pagehide",this.pageUnloadHandler),window.addEventListener("beforeunload",this.pageUnloadHandler),window.addEventListener("pageshow",this.pageShowHandler),document.addEventListener("visibilitychange",this.visibilityFlushHandler)}initializeHandlers(){const e=this.get("config");this.handlers.session=new Ns(this.managers.storage,this.managers.event),this.handlers.session.startTracking();const t=()=>{this.set("suppressNextScroll",!0),this.suppressNextScrollTimer&&clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=window.setTimeout(()=>{this.set("suppressNextScroll",!1)},500)};this.handlers.pageView=new Os(this.managers.event,t),this.handlers.click=new Ps(this.managers.event),this.handlers.scroll=new Ds(this.managers.event),this.handlers.performance=new Hs(this.managers.event),this.handlers.error=new se(this.managers.event,this.emitter);const s=()=>{if(this.handlers.pageView?.startTracking(),this.handlers.click?.startTracking(),this.handlers.scroll?.startTracking(),this.handlers.performance?.startTracking().catch(r=>{a("warn","Failed to start performance tracking",{error:r})}),this.handlers.error?.startTracking(),e.integrations?.tracelog?.shopify){const r=new Fs;r.activate(),this.integrationInstances.shopifyCartLinker=r,this.emitter.on(C.EVENT,i=>{i.type===d.SESSION_START&&r.onSessionChange()})}};st()?(this.prerenderActivationHandler=()=>{this.prerenderActivationHandler=null,s()},document.addEventListener("prerenderingchange",this.prerenderActivationHandler,{once:!0})):s()}}const N=[];let g=null,V=!1,M=!1,O=null;const $s={init:async n=>typeof window>"u"||typeof document>"u"?{sessionId:""}:(M=!1,window.__traceLogDisabled===!0?{sessionId:""}:g?{sessionId:g.getSessionId()??""}:(V&&O||(V=!0,O=(async()=>{try{const e=us(n??{}),t=new xs;try{N.forEach(({event:o,callback:c})=>{t.on(o,c)}),N.length=0;const s=t.init(e),r=new Promise((o,c)=>{setTimeout(()=>{c(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)}),i=await Promise.race([s,r]);return g=t,i}catch(s){try{t.destroy(!0)}catch(r){a("error","Failed to cleanup partially initialized app",{error:r})}throw s}}catch(e){throw g=null,e}finally{V=!1,O=null}})()),O)),event:(n,e,t)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(M)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");g.sendCustomEvent(n,e,t)}},on:(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g||V){N.push({event:n,callback:e});return}g.on(n,e)}},off:(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!g){const t=N.findIndex(s=>s.event===n&&s.callback===e);t!==-1&&N.splice(t,1);return}g.off(n,e)}},isInitialized:()=>typeof window>"u"||typeof document>"u"?!1:g!==null,getSessionId:()=>typeof window>"u"||typeof document>"u"||!g?null:g.getSessionId(),getUserId:()=>typeof window>"u"||typeof document>"u"||!g?null:g.getUserId(),destroy:()=>{if(!(typeof window>"u"||typeof document>"u")){if(M)throw new Error("[TraceLog] Destroy operation already in progress");if(!g){M=!1;return}M=!0;try{g.destroy(),g=null,V=!1,O=null,N.length=0,M=!1}catch(n){g=null,V=!1,O=null,N.length=0,M=!1,a("warn","Error during destroy, forced cleanup completed",{error:n})}}},identify:(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!n||typeof n!="string"||n.trim().length===0){a("warn","identify() called with invalid userId");return}if(n.trim().length>256){a("warn","identify() userId exceeds 256 characters");return}if(M){a("warn","Cannot identify while TraceLog is being destroyed");return}if(g){g.identify(n,e);return}try{const t=Me(e),s={userId:n.trim(),...t?{traits:t}:{}};localStorage.setItem(D,JSON.stringify(s)),a("debug","Identity persisted pre-init (will be applied on init)")}catch{a("debug","Failed to persist pre-init identity")}}},resetIdentity:async()=>{if(!(typeof window>"u"||typeof document>"u")){if(!g){try{localStorage.removeItem(D)}catch{}return}if(M)throw new Error("[TraceLog] Cannot reset identity while TraceLog is being destroyed");await g.resetIdentity()}}};var be,R,G,lt,ne,ut=-1,P=function(n){addEventListener("pageshow",(function(e){e.persisted&&(ut=e.timeStamp,n(e))}),!0)},Re=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},re=function(){var n=Re();return n&&n.activationStart||0},T=function(n,e){var t=Re(),s="navigate";return ut>=0?s="back-forward-cache":t&&(document.prerendering||re()>0?s="prerender":document.wasDiscarded?s="restore":t.type&&(s=t.type.replace(/_/g,"-"))),{name:n,value:e===void 0?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:s}},H=function(n,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(n)){var s=new PerformanceObserver((function(r){Promise.resolve().then((function(){e(r.getEntries())}))}));return s.observe(Object.assign({type:n,buffered:!0},t||{})),s}}catch{}},_=function(n,e,t,s){var r,i;return function(o){e.value>=0&&(o||s)&&((i=e.value-(r||0))||r===void 0)&&(r=e.value,e.delta=i,e.rating=(function(c,l){return c>l[1]?"poor":c>l[0]?"needs-improvement":"good"})(e.value,t),n(e))}},Ce=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},W=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},ie=function(n){var e=!1;return function(){e||(n(),e=!0)}},x=-1,dt=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},oe=function(n){document.visibilityState==="hidden"&&x>-1&&(x=n.type==="visibilitychange"?n.timeStamp:0,Bs())},ht=function(){addEventListener("visibilitychange",oe,!0),addEventListener("prerenderingchange",oe,!0)},Bs=function(){removeEventListener("visibilitychange",oe,!0),removeEventListener("prerenderingchange",oe,!0)},Ne=function(){return x<0&&(x=dt(),ht(),P((function(){setTimeout((function(){x=dt(),ht()}),0)}))),{get firstHiddenTime(){return x}}},K=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},Oe=[1800,3e3],ft=function(n,e){e=e||{},K((function(){var t,s=Ne(),r=T("FCP"),i=H("paint",(function(o){o.forEach((function(c){c.name==="first-contentful-paint"&&(i.disconnect(),c.startTime<s.firstHiddenTime&&(r.value=Math.max(c.startTime-re(),0),r.entries.push(c),t(!0)))}))}));i&&(t=_(n,r,Oe,e.reportAllChanges),P((function(o){r=T("FCP"),t=_(n,r,Oe,e.reportAllChanges),Ce((function(){r.value=performance.now()-o.timeStamp,t(!0)}))})))}))},Pe=[.1,.25],Xs=function(n,e){e=e||{},ft(ie((function(){var t,s=T("CLS",0),r=0,i=[],o=function(l){l.forEach((function(u){if(!u.hadRecentInput){var f=i[0],S=i[i.length-1];r&&u.startTime-S.startTime<1e3&&u.startTime-f.startTime<5e3?(r+=u.value,i.push(u)):(r=u.value,i=[u])}})),r>s.value&&(s.value=r,s.entries=i,t())},c=H("layout-shift",o);c&&(t=_(n,s,Pe,e.reportAllChanges),W((function(){o(c.takeRecords()),t(!0)})),P((function(){r=0,s=T("CLS",0),t=_(n,s,Pe,e.reportAllChanges),Ce((function(){return t()}))})),setTimeout(t,0))})))},gt=0,De=1/0,ae=0,Gs=function(n){n.forEach((function(e){e.interactionId&&(De=Math.min(De,e.interactionId),ae=Math.max(ae,e.interactionId),gt=ae?(ae-De)/7+1:0)}))},mt=function(){return be?gt:performance.interactionCount||0},Ws=function(){"interactionCount"in performance||be||(be=H("event",Gs,{type:"event",buffered:!0,durationThreshold:0}))},A=[],ce=new Map,pt=0,Ks=function(){var n=Math.min(A.length-1,Math.floor((mt()-pt)/50));return A[n]},js=[],zs=function(n){if(js.forEach((function(r){return r(n)})),n.interactionId||n.entryType==="first-input"){var e=A[A.length-1],t=ce.get(n.interactionId);if(t||A.length<10||n.duration>e.latency){if(t)n.duration>t.latency?(t.entries=[n],t.latency=n.duration):n.duration===t.latency&&n.startTime===t.entries[0].startTime&&t.entries.push(n);else{var s={id:n.interactionId,latency:n.duration,entries:[n]};ce.set(s.id,s),A.push(s)}A.sort((function(r,i){return i.latency-r.latency})),A.length>10&&A.splice(10).forEach((function(r){return ce.delete(r.id)}))}}},St=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=ie(n),document.visibilityState==="hidden"?n():(t=e(n),W(n)),t},ke=[200,500],Qs=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},K((function(){var t;Ws();var s,r=T("INP"),i=function(c){St((function(){c.forEach(zs);var l=Ks();l&&l.latency!==r.value&&(r.value=l.latency,r.entries=l.entries,s())}))},o=H("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});s=_(n,r,ke,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),W((function(){i(o.takeRecords()),s(!0)})),P((function(){pt=mt(),A.length=0,ce.clear(),r=T("INP"),s=_(n,r,ke,e.reportAllChanges)})))})))},Ue=[2500,4e3],Fe={},Ys=function(n,e){e=e||{},K((function(){var t,s=Ne(),r=T("LCP"),i=function(l){e.reportAllChanges||(l=l.slice(-1)),l.forEach((function(u){u.startTime<s.firstHiddenTime&&(r.value=Math.max(u.startTime-re(),0),r.entries=[u],t())}))},o=H("largest-contentful-paint",i);if(o){t=_(n,r,Ue,e.reportAllChanges);var c=ie((function(){Fe[r.id]||(i(o.takeRecords()),o.disconnect(),Fe[r.id]=!0,t(!0))}));["keydown","click"].forEach((function(l){addEventListener(l,(function(){return St(c)}),{once:!0,capture:!0})})),W(c),P((function(l){r=T("LCP"),t=_(n,r,Ue,e.reportAllChanges),Ce((function(){r.value=performance.now()-l.timeStamp,Fe[r.id]=!0,t(!0)}))}))}}))},Ve=[800,1800],qs=function n(e){document.prerendering?K((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},Js=function(n,e){e=e||{};var t=T("TTFB"),s=_(n,t,Ve,e.reportAllChanges);qs((function(){var r=Re();r&&(t.value=Math.max(r.responseStart-re(),0),t.entries=[r],s(!0),P((function(){t=T("TTFB",0),(s=_(n,t,Ve,e.reportAllChanges))(!0)})))}))},j={passive:!0,capture:!0},Zs=new Date,Et=function(n,e){R||(R=e,G=n,lt=new Date,_t(removeEventListener),Tt())},Tt=function(){if(G>=0&&G<lt-Zs){var n={entryType:"first-input",name:R.type,target:R.target,cancelable:R.cancelable,startTime:R.timeStamp,processingStart:R.timeStamp+G};ne.forEach((function(e){e(n)})),ne=[]}},en=function(n){if(n.cancelable){var e=(n.timeStamp>1e12?new Date:performance.now())-n.timeStamp;n.type=="pointerdown"?(function(t,s){var r=function(){Et(t,s),o()},i=function(){o()},o=function(){removeEventListener("pointerup",r,j),removeEventListener("pointercancel",i,j)};addEventListener("pointerup",r,j),addEventListener("pointercancel",i,j)})(e,n):Et(e,n)}},_t=function(n){["mousedown","keydown","touchstart","pointerdown"].forEach((function(e){return n(e,en,j)}))},He=[100,300],tn=function(n,e){e=e||{},K((function(){var t,s=Ne(),r=T("FID"),i=function(l){l.startTime<s.firstHiddenTime&&(r.value=l.processingStart-l.startTime,r.entries.push(l),t(!0))},o=function(l){l.forEach(i)},c=H("first-input",o);t=_(n,r,He,e.reportAllChanges),c&&(W(ie((function(){o(c.takeRecords()),c.disconnect()}))),P((function(){var l;r=T("FID"),t=_(n,r,He,e.reportAllChanges),ne=[],G=-1,R=null,_t(addEventListener),l=i,ne.push(l),Tt()})))}))};const sn=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:Pe,FCPThresholds:Oe,FIDThresholds:He,INPThresholds:ke,LCPThresholds:Ue,TTFBThresholds:Ve,onCLS:Xs,onFCP:ft,onFID:tn,onINP:Qs,onLCP:Ys,onTTFB:Js},Symbol.toStringTag,{value:"Module"}));h.AppConfigValidationError=p,h.DEFAULT_SESSION_TIMEOUT=9e5,h.DEFAULT_WEB_VITALS_MODE=J,h.DeviceType=w,h.EmitterEvent=C,h.ErrorType=U,h.EventType=d,h.InitializationTimeoutError=Lt,h.IntegrationValidationError=me,h.MAX_ARRAY_LENGTH=1e3,h.MAX_CUSTOM_EVENT_ARRAY_SIZE=500,h.MAX_CUSTOM_EVENT_KEYS=100,h.MAX_CUSTOM_EVENT_NAME_LENGTH=120,h.MAX_CUSTOM_EVENT_STRING_SIZE=49152,h.MAX_NESTED_OBJECT_KEYS=200,h.MAX_STRING_LENGTH=1e3,h.MAX_STRING_LENGTH_IN_ARRAY=500,h.Mode=X,h.PII_PATTERNS=ot,h.PermanentError=b,h.RateLimitError=$,h.SamplingRateValidationError=ge,h.ScrollDirection=Q,h.SessionTimeoutValidationError=ze,h.SpecialApiUrl=k,h.TimeoutError=B,h.TraceLogValidationError=F,h.WEB_VITALS_GOOD_THRESHOLDS=Qt,h.WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS=Te,h.WEB_VITALS_POOR_THRESHOLDS=tt,h.getWebVitalsThresholds=_e,h.tracelog=$s,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);