@tracelog/lib 2.0.2 → 2.0.3

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 +1 @@
1
- (function(h){"use strict";const w="data-tlog",it=["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"]'],ot=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],at=["token","auth","key","session","reset","password","api_key","apikey","secret","access_token","refresh_token","verification","code","otp"],E={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_CUSTOM_API_URL:"Custom API URL 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_PRIMARY_SCROLL_SELECTOR:"Primary scroll selector must be a non-empty string",INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX:"Invalid CSS selector syntax for primaryScrollSelector",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_VIEWPORT_CONFIG:"Viewport config must be an object",INVALID_VIEWPORT_ELEMENTS:"Viewport elements must be a non-empty array",INVALID_VIEWPORT_ELEMENT:"Each viewport element must have a valid selector string",INVALID_VIEWPORT_ELEMENT_ID:"Viewport element id must be a non-empty string",INVALID_VIEWPORT_ELEMENT_NAME:"Viewport element name must be a non-empty string",INVALID_VIEWPORT_THRESHOLD:"Viewport threshold must be a number between 0 and 1",INVALID_VIEWPORT_MIN_DWELL_TIME:"Viewport minDwellTime must be a non-negative number",INVALID_VIEWPORT_COOLDOWN_PERIOD:"Viewport cooldownPeriod must be a non-negative number",INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS:"Viewport maxTrackedElements must be a positive number"},lt=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi],_="tlog",H=`${_}:qa_mode`,we=`${_}:uid`,ye="tlog_mode",Ae="qa",Me="qa_off",ct=n=>n?`${_}:${n}:queue`:`${_}:queue`,ut=n=>n?`${_}:${n}:session`:`${_}:session`,dt=n=>n?`${_}:${n}:broadcast`:`${_}:broadcast`,be=(n,e)=>`${_}:${n}:session_counts:${e}`,Le=10080*60*1e3,Re=`${_}:session_counts_last_cleanup`,Ce=3600*1e3;var O=(n=>(n.Localhost="localhost:8080",n.Fail="localhost:9999",n))(O||{}),b=(n=>(n.Mobile="mobile",n.Tablet="tablet",n.Desktop="desktop",n.Unknown="unknown",n))(b||{}),B=(n=>(n.EVENT="event",n.QUEUE="queue",n))(B||{});class R extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,R)}}var u=(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.VIEWPORT_VISIBLE="viewport_visible",n))(u||{}),x=(n=>(n.UP="up",n.DOWN="down",n))(x||{}),P=(n=>(n.JS_ERROR="js_error",n.PROMISE_REJECTION="promise_rejection",n))(P||{}),F=(n=>(n.QA="qa",n))(F||{});const ht=n=>n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!0,ft=n=>n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!1;class D extends Error{constructor(e,t,r){super(e),this.errorCode=t,this.layer=r,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class f extends D{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class Ne extends D{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class re extends D{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class V extends D{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class mt extends D{constructor(e,t,r="runtime"){super(e,"INITIALIZATION_TIMEOUT",r),this.timeoutMs=t}}const Et=(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}`},a=(n,e,t)=>{const{error:r,data:s,showToClient:i=!1,style:o}=t??{},l=r?Et(e,r):`[TraceLog] ${e}`,c=n==="error"?"error":n==="warn"?"warn":"log";if(n==="debug"||n==="info"&&!i)return;const d=o!==void 0&&o!=="",g=d?`%c${l}`:l;if(s!==void 0){const S=ne(s);d?console[c](g,o,S):console[c](g,S)}else d?console[c](g,o):console[c](g)},ne=n=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[r,s]of Object.entries(n)){const i=r.toLowerCase();if(t.some(o=>i.includes(o))){e[r]="[REDACTED]";continue}s!==null&&typeof s=="object"&&!Array.isArray(s)?e[r]=ne(s):Array.isArray(s)?e[r]=s.map(o=>o!==null&&typeof o=="object"&&!Array.isArray(o)?ne(o):o):e[r]=s}return e};let se,Oe;const gt=()=>{typeof window<"u"&&!se&&(se=window.matchMedia("(pointer: coarse)"),Oe=window.matchMedia("(hover: none)"))},St=()=>{try{const n=navigator;if(n.userAgentData&&typeof n.userAgentData.mobile=="boolean")return n.userAgentData.platform&&/ipad|tablet/i.test(n.userAgentData.platform)?b.Tablet:n.userAgentData.mobile?b.Mobile:b.Desktop;gt();const e=window.innerWidth,t=se?.matches??!1,r=Oe?.matches??!1,s="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&&s?b.Mobile:e>=768&&e<=1024||l||t&&r&&s?b.Tablet:b.Desktop}catch(n){return a("warn","Device detection failed, defaulting to desktop",{error:n}),b.Desktop}},Pe="background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",De="background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",Ve=["scroll","web_vitals","error"],ie=[/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\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],ke=500,Ue=5e3,W=50,Tt=W*2,He=1,pt=1e3,_t=10,xe=5e3,It=6e4,vt={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},oe={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},Fe={LCP:4e3,FCP:3e3,CLS:.25,INP:500,TTFB:1800,LONG_TASK:50},G="needs-improvement",ae=(n=G)=>{switch(n){case"all":return{LCP:0,FCP:0,CLS:0,INP:0,TTFB:0,LONG_TASK:0};case"needs-improvement":return oe;case"poor":return Fe;default:return oe}},wt=1e3,yt=50,At="2.0.1",Mt=()=>{if(typeof window>"u"||typeof document>"u")return!1;try{const n=new URLSearchParams(window.location.search),e=n.get(ye),t=sessionStorage.getItem(H);let r=null;if(e===Ae?(r=!0,sessionStorage.setItem(H,"true"),a("info","QA Mode ACTIVE",{showToClient:!0,style:Pe})):e===Me&&(r=!1,sessionStorage.setItem(H,"false"),a("info","QA Mode DISABLED",{showToClient:!0,style:De})),e===Ae||e===Me)try{n.delete(ye);const s=n.toString(),i=window.location.pathname+(s?"?"+s:"")+window.location.hash;window.history.replaceState({},"",i)}catch{}return r??t==="true"}catch{return!1}},bt=n=>{if(!(typeof window>"u"||typeof document>"u"))try{n?(sessionStorage.setItem(H,"true"),a("info","QA Mode ENABLED",{showToClient:!0,style:Pe})):(sessionStorage.setItem(H,"false"),a("info","QA Mode DISABLED",{showToClient:!0,style:De}))}catch{a("warn","Cannot set QA mode: sessionStorage unavailable")}},$e=()=>{const n=new URLSearchParams(window.location.search),e={};return ot.forEach(r=>{const s=n.get(r);if(s){const i=r.split("utm_")[1];e[i]=s}}),Object.keys(e).length?e:void 0},Lt=()=>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 X=0,Q=0;const Rt=()=>{let n=Date.now();n<Q&&(n=Q),n===Q?X=(X+1)%1e3:X=0,Q=n;const e=X.toString().padStart(3,"0");let t="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const r=crypto.getRandomValues(new Uint8Array(3));r&&(t=Array.from(r,s=>s.toString(16).padStart(2,"0")).join(""))}}catch{}return t||(t=Math.floor(Math.random()*16777215).toString(16).padStart(6,"0")),`${n}-${e}-${t}`},Be=(n,e=!1)=>{try{const t=new URL(n),r=t.protocol==="https:",s=t.protocol==="http:";return r||e&&s}catch{return!1}},Ct=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 not supported on localhost or IP addresses. Use custom backend integration instead.");const r=t.split(".");if(!r||!Array.isArray(r)||r.length===0||r.length===1&&r[0]==="")throw new Error("Invalid hostname structure");if(r.length===1)throw new Error("Single-part domain not supported for SaaS integration");let s;if(r.length===2?s=r.join("."):s=r.slice(-2).join("."),!s||s.split(".").length<2)throw new Error("Invalid domain structure for SaaS");const i=`https://${n}.${s}/collect`;if(!Be(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)}`)}},Nt=n=>{const e={};n.integrations?.tracelog?.projectId&&(e.saas=Ct(n.integrations.tracelog.projectId));const t=n.integrations?.custom?.collectApiUrl;if(t){const r=n.integrations?.custom?.allowHttp??!1;if(!Be(t,r))throw new Error("Invalid custom API URL");e.custom=t}return e},le=(n,e=[])=>{if(!n||typeof n!="string")return a("warn","Invalid URL provided to normalizeUrl",{data:{url:String(n)}}),n||"";try{const t=new URL(n),r=t.searchParams,s=[...new Set([...at,...e])];let i=!1;const o=[];return s.forEach(c=>{r.has(c)&&(r.delete(c),i=!0,o.push(c))}),!i&&n.includes("?")?n:(t.search=r.toString(),t.toString())}catch(t){const r=n&&typeof n=="string"?n.slice(0,100):String(n);return a("warn","URL normalization failed, returning original",{error:t,data:{url:r}}),n}},We=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 s of lt){const i=e;e=e.replace(s,""),i!==e&&t++}return t>0&&a("warn","XSS patterns detected and removed",{data:{patternMatches:t,originalValue:n.slice(0,100)}}),e=e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#x27;").replaceAll("/","&#x2F;"),e.trim()},ce=(n,e=0)=>{if(e>3||n==null)return null;if(typeof n=="string")return We(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(Array.isArray(n))return n.slice(0,100).map(s=>ce(s,e+1)).filter(s=>s!==null);if(typeof n=="object"){const t={},s=Object.entries(n).slice(0,20);for(const[i,o]of s){const l=We(i);if(l){const c=ce(o,e+1);c!==null&&(t[l]=c)}}return t}return null},Ot=n=>{if(typeof n!="object"||n===null)return{};try{const e=ce(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}`)}},Pt=n=>{if(n!==void 0&&(n===null||typeof n!="object"))throw new f("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 Ne(E.INVALID_SESSION_TIMEOUT,"config");if(n.globalMetadata!==void 0&&(typeof n.globalMetadata!="object"||n.globalMetadata===null))throw new f(E.INVALID_GLOBAL_METADATA,"config");if(n.integrations&&Vt(n.integrations),n.sensitiveQueryParams!==void 0){if(!Array.isArray(n.sensitiveQueryParams))throw new f(E.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of n.sensitiveQueryParams)if(typeof e!="string")throw new f("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 re(E.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new re(E.INVALID_SAMPLING_RATE,"config");if(n.primaryScrollSelector!==void 0){if(typeof n.primaryScrollSelector!="string"||!n.primaryScrollSelector.trim())throw new f(E.INVALID_PRIMARY_SCROLL_SELECTOR,"config");if(n.primaryScrollSelector!=="window")try{document.querySelector(n.primaryScrollSelector)}catch{throw new f(`${E.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${n.primaryScrollSelector}"`,"config")}}if(n.pageViewThrottleMs!==void 0&&(typeof n.pageViewThrottleMs!="number"||n.pageViewThrottleMs<0))throw new f(E.INVALID_PAGE_VIEW_THROTTLE,"config");if(n.clickThrottleMs!==void 0&&(typeof n.clickThrottleMs!="number"||n.clickThrottleMs<0))throw new f(E.INVALID_CLICK_THROTTLE,"config");if(n.maxSameEventPerMinute!==void 0&&(typeof n.maxSameEventPerMinute!="number"||n.maxSameEventPerMinute<=0))throw new f(E.INVALID_MAX_SAME_EVENT_PER_MINUTE,"config");if(n.viewport!==void 0&&Dt(n.viewport),n.disabledEvents!==void 0){if(!Array.isArray(n.disabledEvents))throw new f("disabledEvents must be an array","config");const e=new Set;for(const t of n.disabledEvents){if(typeof t!="string")throw new f("All disabled event types must be strings","config");if(!Ve.includes(t))throw new f(`Invalid disabled event type: "${t}". Must be one of: ${Ve.join(", ")}`,"config");if(e.has(t))throw new f(`Duplicate disabled event type found: "${t}". Each event type should appear only once.`,"config");e.add(t)}}if(n.webVitalsMode!==void 0){if(typeof n.webVitalsMode!="string")throw new f(`Invalid webVitalsMode type: ${typeof n.webVitalsMode}. Must be a string`,"config");const e=["all","needs-improvement","poor"];if(!e.includes(n.webVitalsMode))throw new f(`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 f("webVitalsThresholds must be an object","config");const e=["LCP","FCP","CLS","INP","TTFB","LONG_TASK"];for(const[t,r]of Object.entries(n.webVitalsThresholds)){if(!e.includes(t))throw new f(`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,"config");if(typeof r!="number"||!Number.isFinite(r)||r<0)throw new f(`Invalid Web Vitals threshold value for ${t}: ${r}. Must be a non-negative finite number`,"config")}}}},Dt=n=>{if(typeof n!="object"||n===null)throw new f(E.INVALID_VIEWPORT_CONFIG,"config");if(!n.elements||!Array.isArray(n.elements))throw new f(E.INVALID_VIEWPORT_ELEMENTS,"config");if(n.elements.length===0)throw new f(E.INVALID_VIEWPORT_ELEMENTS,"config");const e=new Set;for(const t of n.elements){if(!t.selector||typeof t.selector!="string"||!t.selector.trim())throw new f(E.INVALID_VIEWPORT_ELEMENT,"config");const r=t.selector.trim();if(e.has(r))throw new f(`Duplicate viewport selector found: "${r}". Each selector should appear only once.`,"config");if(e.add(r),t.id!==void 0&&(typeof t.id!="string"||!t.id.trim()))throw new f(E.INVALID_VIEWPORT_ELEMENT_ID,"config");if(t.name!==void 0&&(typeof t.name!="string"||!t.name.trim()))throw new f(E.INVALID_VIEWPORT_ELEMENT_NAME,"config")}if(n.threshold!==void 0&&(typeof n.threshold!="number"||n.threshold<0||n.threshold>1))throw new f(E.INVALID_VIEWPORT_THRESHOLD,"config");if(n.minDwellTime!==void 0&&(typeof n.minDwellTime!="number"||n.minDwellTime<0))throw new f(E.INVALID_VIEWPORT_MIN_DWELL_TIME,"config");if(n.cooldownPeriod!==void 0&&(typeof n.cooldownPeriod!="number"||n.cooldownPeriod<0))throw new f(E.INVALID_VIEWPORT_COOLDOWN_PERIOD,"config");if(n.maxTrackedElements!==void 0&&(typeof n.maxTrackedElements!="number"||n.maxTrackedElements<=0))throw new f(E.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS,"config")},Vt=n=>{if(n){if(n.tracelog&&(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()===""))throw new V(E.INVALID_TRACELOG_PROJECT_ID,"config");if(n.custom){if(!n.custom.collectApiUrl||typeof n.custom.collectApiUrl!="string"||n.custom.collectApiUrl.trim()==="")throw new V(E.INVALID_CUSTOM_API_URL,"config");if(n.custom.allowHttp!==void 0&&typeof n.custom.allowHttp!="boolean")throw new V("allowHttp must be a boolean","config");const e=n.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new V('Custom API URL must start with "http://" or "https://"',"config");if(!(n.custom.allowHttp??!1)&&e.startsWith("http://"))throw new V("Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)","config")}}},kt=n=>{Pt(n);const e={...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??He,samplingRate:n?.samplingRate??1,pageViewThrottleMs:n?.pageViewThrottleMs??1e3,clickThrottleMs:n?.clickThrottleMs??300,maxSameEventPerMinute:n?.maxSameEventPerMinute??60,disabledEvents:n?.disabledEvents??[]};return e.integrations?.custom&&(e.integrations.custom={...e.integrations.custom,allowHttp:e.integrations.custom.allowHttp??!1}),e.viewport&&(e.viewport={...e.viewport,threshold:e.viewport.threshold??.5,minDwellTime:e.viewport.minDwellTime??2e3,cooldownPeriod:e.viewport.cooldownPeriod??6e4,maxTrackedElements:e.viewport.maxTrackedElements??100}),e},Ut=n=>{if(typeof n=="string")return!0;if(typeof n=="object"&&n!==null&&!Array.isArray(n)){const e=Object.entries(n);if(e.length>20)return!1;for(const[,t]of e){if(t==null)continue;const r=typeof t;if(r!=="string"&&r!=="number"&&r!=="boolean")return!1}return!0}return!1},Ge=(n,e=0)=>{if(typeof n!="object"||n===null||e>1)return!1;for(const t of Object.values(n)){if(t==null)continue;const r=typeof t;if(!(r==="string"||r==="number"||r==="boolean")){if(Array.isArray(t)){if(t.length===0)continue;if(typeof t[0]=="string"){if(!t.every(o=>typeof o=="string"))return!1}else if(!t.every(o=>Ut(o)))return!1;continue}if(r==="object"&&e===0){if(!Ge(t,e+1))return!1;continue}return!1}}return!0},Ht=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},Xe=(n,e,t)=>{const r=Ot(e),s=t&&t==="customEvent"?`${t} "${n}" metadata error`:`${n} metadata error`;if(!Ge(r))return{valid:!1,error:`${s}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(r)}catch{return{valid:!1,error:`${s}: object contains circular references or cannot be serialized.`}}if(i.length>8192)return{valid:!1,error:`${s}: object is too large (max ${8192/1024} KB).`};if(Object.keys(r).length>10)return{valid:!1,error:`${s}: object has too many keys (max 10 keys).`};for(const[l,c]of Object.entries(r)){if(Array.isArray(c)){if(c.length>10)return{valid:!1,error:`${s}: array property "${l}" is too large (max 10 items).`};for(const d of c)if(typeof d=="string"&&d.length>500)return{valid:!1,error:`${s}: array property "${l}" contains strings that are too long (max 500 characters).`}}if(typeof c=="string"&&c.length>1e3)return{valid:!1,error:`${s}: property "${l}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:r}},Qe=(n,e,t)=>{if(Array.isArray(e)){const r=[],s=t&&t==="customEvent"?`${t} "${n}" metadata error`:`${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:`${s}: array item at index ${i} must be an object.`};const l=Xe(n,o,t);if(!l.valid)return{valid:!1,error:`${s}: array item at index ${i} is invalid: ${l.error}`};l.sanitizedMetadata&&r.push(l.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:r}}return Xe(n,e,t)},xt=(n,e)=>{const t=Ht(n);if(!t.valid)return a("error","Event name validation failed",{showToClient:!0,data:{eventName:n,error:t.error}}),t;if(!e)return{valid:!0};const r=Qe(n,e,"customEvent");return r.valid||a("error","Event metadata validation failed",{showToClient:!0,data:{eventName:n,error:r.error}}),r};class Ft{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const r=this.listeners.get(e);if(r){const s=r.indexOf(t);s>-1&&r.splice(s,1)}}emit(e,t){const r=this.listeners.get(e);r&&r.forEach(s=>{s(t)})}removeAllListeners(){this.listeners.clear()}}function ze(n,e,t){try{const r=e(n);return r===null?null:typeof r=="object"&&r!==null&&"type"in r?r:(a("warn",`beforeSend transformer returned invalid data, using original [${t}]`),n)}catch(r){return a("error",`beforeSend transformer threw error, using original event [${t}]`,{error:r}),n}}function $t(n,e,t){return n.map(r=>ze(r,e,t)).filter(r=>r!==null)}function je(n,e,t){try{const r=e(n);return r===null?(a("debug",`Batch filtered by beforeBatch transformer [${t}]`,{data:{eventCount:n.events.length}}),null):typeof r=="object"&&r!==null&&Array.isArray(r.events)?r:(a("warn",`beforeBatch transformer returned invalid data, using original [${t}]`,{data:{eventCount:n.events.length}}),n)}catch(r){return a("error",`beforeBatch transformer threw error, using original batch [${t}]`,{error:r,data:{eventCount:n.events.length}}),n}}const ue={};class p{get(e){return ue[e]}set(e,t){ue[e]=t}getState(){return{...ue}}}class Ke extends p{storeManager;integrationId;apiUrl;transformers;lastPermanentErrorLog=null;recoveryInProgress=!1;lastMetadataTimestamp=0;pendingControllers=new Set;constructor(e,t,r,s={}){if(super(),t&&!r||!t&&r)throw new Error("SenderManager: integrationId and apiUrl must either both be provided or both be undefined");this.storeManager=e,this.integrationId=t,this.apiUrl=r,this.transformers=s}getIntegrationId(){return this.integrationId}getQueueStorageKey(){const e=this.get("userId")||"anonymous",t=ct(e);return this.integrationId?`${t}:${this.integrationId}`:t}sendEventsQueueSync(e){return this.shouldSkipSend()?!0:this.apiUrl?.includes(O.Fail)?(a("warn",`Fail mode: simulating network failure (sync)${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:e.events.length}}),!1):this.apiUrl?.includes(O.Localhost)?(a("debug",`Success mode: simulating successful send (sync)${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:e.events.length}}),!0):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){try{const r=await this.send(e);return r?(this.clearPersistedEvents(),t?.onSuccess?.(e.events.length,e.events,e)):(this.persistEvents(e),t?.onFailure?.()),r}catch(r){return r instanceof R?(this.logPermanentError("Permanent error, not retrying",r),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(e),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){if(this.recoveryInProgress){a("debug","Recovery already in progress, skipping duplicate attempt");return}this.recoveryInProgress=!0;try{const t=this.getPersistedData();if(!t||!this.isDataRecent(t)||t.events.length===0){this.clearPersistedEvents();return}const r=this.createRecoveryBody(t);await this.send(r)?(this.clearPersistedEvents(),e?.onSuccess?.(t.events.length,t.events,r)):e?.onFailure?.()}catch(t){if(t instanceof R){this.logPermanentError("Permanent error during recovery, clearing persisted events",t),this.clearPersistedEvents(),e?.onFailure?.();return}a("error","Failed to recover persisted events",{error:t})}finally{this.recoveryInProgress=!1}}stop(){}applyBeforeSendTransformer(e){if(this.integrationId==="saas")return e;const t=this.transformers.beforeSend;if(!t)return e;const r=$t(e.events,t,this.integrationId||"SenderManager");return r.length===0?null:{...e,events:r}}applyBeforeBatchTransformer(e){if(this.integrationId==="saas")return e;const t=this.transformers.beforeBatch;return t?je(e,t,this.integrationId||"SenderManager"):e}async backoffDelay(e){const t=100*Math.pow(2,e),r=Math.random()*100,s=t+r;return new Promise(i=>setTimeout(i,s))}async send(e){if(this.shouldSkipSend())return this.simulateSuccessfulSend();const t=this.applyBeforeSendTransformer(e);if(!t)return!0;const r=this.applyBeforeBatchTransformer(t);if(!r)return!0;if(this.apiUrl?.includes(O.Fail))return a("warn",`Fail mode: simulating network failure${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:r.events.length}}),!1;if(this.apiUrl?.includes(O.Localhost))return a("debug",`Success mode: simulating successful send${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:r.events.length}}),!0;const{url:s,payload:i}=this.prepareRequest(r);for(let o=1;o<=3;o++)try{return(await this.sendWithTimeout(s,i)).ok?(o>1&&a("info",`Send succeeded after ${o-1} retry attempt(s)${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:r.events.length,attempt:o}}),!0):!1}catch(l){const c=o===3;if(l instanceof R)throw l;if(a(c?"error":"warn",`Send attempt ${o} failed${this.integrationId?` [${this.integrationId}]`:""}${c?" (all retries exhausted)":", will retry"}`,{error:l,data:{events:e.events.length,url:s.replace(/\/\/[^/]+/,"//[DOMAIN]"),attempt:o,maxAttempts:3}}),!c){await this.backoffDelay(o);continue}return!1}return!1}async sendWithTimeout(e,t){const r=new AbortController;this.pendingControllers.add(r);const s=setTimeout(()=>{r.abort()},15e3);try{const i=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:r.signal,headers:{"Content-Type":"application/json"}});if(!i.ok)throw i.status>=400&&i.status<500&&i.status!==408&&i.status!==429?new R(`HTTP ${i.status}: ${i.statusText}`,i.status):new Error(`HTTP ${i.status}: ${i.statusText}`);return i}finally{clearTimeout(s),this.pendingControllers.delete(r)}}sendQueueSyncInternal(e){const t=this.applyBeforeSendTransformer(e);if(!t)return!0;const r=this.applyBeforeBatchTransformer(t);if(!r)return!0;const{url:s,payload:i}=this.prepareRequest(r);if(i.length>65536)return a("warn",`Payload exceeds sendBeacon limit, persisting for recovery${this.integrationId?` [${this.integrationId}]`:""}`,{data:{size:i.length,limit:65536,events:r.events.length}}),this.persistEvents(r),!1;const o=new Blob([i],{type:"application/json"});if(!this.isSendBeaconAvailable())return a("warn",`sendBeacon not available, persisting events for recovery${this.integrationId?` [${this.integrationId}]`:""}`),this.persistEvents(r),!1;const l=navigator.sendBeacon(s,o);return l||(a("warn",`sendBeacon rejected request, persisting events for recovery${this.integrationId?` [${this.integrationId}]`:""}`),this.persistEvents(r)),l}prepareRequest(e){let t=Date.now();t<this.lastMetadataTimestamp&&(t=this.lastMetadataTimestamp),this.lastMetadataTimestamp=t;const r={...e,_metadata:{referer:typeof window<"u"?window.location.href:void 0,timestamp:t,client_version:At}};return{url:this.apiUrl||"",payload:JSON.stringify(r)}}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){a("warn",`Failed to parse persisted data${this.integrationId?` [${this.integrationId}]`:""}`,{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,...r}=e;return r}persistEvents(e){try{const t=this.getPersistedData();if(t&&t.timestamp){const i=Date.now()-t.timestamp;if(i<1e3)return a("debug",`Skipping persistence, another tab recently persisted events${this.integrationId?` [${this.integrationId}]`:""}`,{data:{timeSinceExisting:i}}),!0}const r={...e,timestamp:Date.now()},s=this.getQueueStorageKey();return this.storeManager.setItem(s,JSON.stringify(r)),!!this.storeManager.getItem(s)}catch(t){return a("warn",`Failed to persist events${this.integrationId?` [${this.integrationId}]`:""}`,{error:t}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){a("warn",`Failed to clear persisted events${this.integrationId?` [${this.integrationId}]`:""}`,{error:e})}}shouldSkipSend(){return!this.apiUrl}async simulateSuccessfulSend(){const e=Math.random()*400+100;return await new Promise(t=>setTimeout(t,e)),!0}isSendBeaconAvailable(){return typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}logPermanentError(e,t){const r=Date.now();(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.statusCode!==t.statusCode||r-this.lastPermanentErrorLog.timestamp>=It)&&(a("error",`${e}${this.integrationId?` [${this.integrationId}]`:""}`,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:r})}}class Bt extends p{bootTime;bootTimestamp;hasPerformanceNow;lastClockSkewCheck=0;detectedSkew=0;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(),a("debug","TimeManager initialized with monotonic clock",{data:{bootTime:this.bootTime.toFixed(3),bootTimestamp:this.bootTimestamp}})):(this.bootTime=0,this.bootTimestamp=Date.now(),a("warn","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)}getClockSkew(){if(!this.hasPerformanceNow)return 0;const e=Date.now();if(e-this.lastClockSkewCheck<5e3)return this.detectedSkew;this.lastClockSkewCheck=e;const t=this.now(),r=Date.now();return this.detectedSkew=r-t,Math.abs(this.detectedSkew)>3e4&&a("warn","Significant clock skew detected",{data:{skewMs:this.detectedSkew,skewMinutes:(this.detectedSkew/1e3/60).toFixed(2),monotonicTime:new Date(t).toISOString(),systemTime:new Date(r).toISOString()}}),this.detectedSkew}validateTimestamp(e){const r=this.now(),s=e-r;return s>12e4?{valid:!1,error:`Timestamp is ${(s/1e3/60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`}:{valid:!0}}getBootInfo(){return{bootTime:this.bootTime,bootTimestamp:this.bootTimestamp,hasPerformanceNow:this.hasPerformanceNow,clockSkew:this.getClockSkew()}}}class Wt extends p{dataSenders;emitter;transformers;timeManager;recentEventFingerprints=new Map;perEventRateLimits=new Map;eventsQueue=[];pendingEventsBuffer=[];sendIntervalId=null;rateLimitCounter=0;rateLimitWindowStart=0;lastSessionId=null;sessionEventCounts={total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0};saveSessionCountsDebounced=null;constructor(e,t=null,r={}){super(),this.emitter=t,this.transformers=r,this.timeManager=new Bt,this.dataSenders=[];const s=this.get("collectApiUrls");s?.saas&&this.dataSenders.push(new Ke(e,"saas",s.saas,r)),s?.custom&&this.dataSenders.push(new Ke(e,"custom",s.custom,r)),this.saveSessionCountsDebounced=this.debounce(i=>{this.saveSessionCounts(i)},500),this.cleanupExpiredSessionCounts()}async recoverPersistedEvents(){const e=this.dataSenders.map(async t=>t.recoverPersistedEvents({onSuccess:(r,s,i)=>{if(s&&s.length>0){const o=s.map(l=>l.id);this.removeProcessedEvents(o),i&&this.emitEventsQueue(i)}},onFailure:()=>{a("warn","Failed to recover persisted events")}}));await Promise.allSettled(e)}track({type:e,page_url:t,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,viewport_data:d}){if(!e){a("error","Event type is required - event will be ignored");return}const g=this.get("sessionId");if(!g){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),a("warn","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,viewport_data:d});return}this.lastSessionId!==g&&(this.lastSessionId=g,this.sessionEventCounts=this.loadSessionCounts(g));const S=e===u.SESSION_START;if(S&&a("debug","Processing SESSION_START event",{data:{sessionId:g}}),!S&&!this.checkRateLimit())return;const T=e;if(!S){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:T,total:this.sessionEventCounts.total,limit:1e3}});return}const v=this.getTypeLimitForEvent(T);if(v){const ve=this.sessionEventCounts[T];if(ve!==void 0&&ve>=v){a("warn","Session event type limit reached",{data:{type:T,count:ve,limit:v}});return}}}if(T===u.CUSTOM&&o?.name){const v=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,v))return}const Z=T===u.SESSION_START,ee=t||this.get("pageUrl"),te=this.buildEventPayload({type:T,page_url:ee,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,viewport_data:d});if(te&&!(!S&&!this.shouldSample())){if(Z){const v=this.get("sessionId");if(!v){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("warn","Duplicate session_start detected",{data:{sessionId:v}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(te)){if(this.get("mode")===F.QA&&T===u.CUSTOM&&o){a("info",`Custom Event: ${o.name}`,{showToClient:!0,data:{name:o.name,...o.metadata&&{metadata:o.metadata}}}),this.emitEvent(te);return}if(this.addToQueue(te),!S){this.sessionEventCounts.total++,this.sessionEventCounts[T]!==void 0&&this.sessionEventCounts[T]++;const v=this.get("sessionId");v&&this.saveSessionCountsDebounced&&this.saveSessionCountsDebounced(v)}}}}stop(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null);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,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.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]}async flushQueue(){await this.flushImmediately()}clearQueue(){this.eventsQueue=[]}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){a("warn","Cannot flush pending events: session not initialized - keeping in buffer",{data:{bufferedEventCount:this.pendingEventsBuffer.length}});return}const t=[...this.pendingEventsBuffer];this.pendingEventsBuffer=[],t.forEach(r=>{this.track(r)})}clearSendInterval(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null)}isSuccessfulResult(e){return e.status==="fulfilled"&&e.value===!0}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);const t=this.buildEventsPayload(),r=[...this.eventsQueue],s=r.map(i=>i.id);if(this.dataSenders.length===0)return this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t),e?!0:Promise.resolve(!0);if(e){const o=this.dataSenders.map(l=>l.sendEventsQueueSync(t)).some(l=>l);return o?(this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t)):(this.clearSendInterval(),a("warn","Sync flush complete failure, events kept in queue for retry",{data:{eventCount:s.length}})),o}else{const i=this.dataSenders.map(async o=>o.sendEventsQueue(t,{onSuccess:()=>{},onFailure:()=>{}}));return Promise.allSettled(i).then(o=>{const l=o.some(c=>this.isSuccessfulResult(c));return l?(this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t)):a("warn","Async flush complete failure, events kept in queue for retry",{data:{eventCount:r.length}}),l})}}async sendEventsQueue(){if(!this.get("sessionId")||this.eventsQueue.length===0)return;const e=this.buildEventsPayload();if(this.dataSenders.length===0){this.emitEventsQueue(e);return}const t=[...this.eventsQueue],r=t.map(l=>l.id),s=this.dataSenders.map(async l=>l.sendEventsQueue(e,{onSuccess:()=>{},onFailure:()=>{}})),i=await Promise.allSettled(s);if(i.some(l=>this.isSuccessfulResult(l))){this.removeProcessedEvents(r),this.emitEventsQueue(e);const l=i.filter(c=>!this.isSuccessfulResult(c)).length;l>0&&a("warn","Periodic send completed with some failures, removed from queue and persisted per-integration",{data:{eventCount:t.length,failedCount:l}})}else a("warn","Periodic send complete failure, events kept in queue for retry",{data:{eventCount:t.length}});this.eventsQueue.length===0&&this.clearSendInterval()}buildEventsPayload(){const e=new Map,t=[];for(const c of this.eventsQueue){const d=this.createEventSignature(c);e.has(d)||t.push(d),e.set(d,c)}const r=t.map(c=>e.get(c)).filter(c=>!!c).sort((c,d)=>c.type===u.SESSION_START&&d.type!==u.SESSION_START?-1:d.type===u.SESSION_START&&c.type!==u.SESSION_START?1:c.timestamp-d.timestamp);let s={user_id:this.get("userId"),session_id:this.get("sessionId"),device:this.get("device"),events:r,...this.get("config")?.globalMetadata&&{global_metadata:this.get("config")?.globalMetadata}};const i=this.get("collectApiUrls"),o=!!(i?.custom||i?.saas),l=this.transformers.beforeBatch;if(!o&&l){const c=je(s,l,"EventManager");c!==null&&(s=c)}return s}buildEventPayload(e){const t=e.type===u.SESSION_START,r=e.page_url??this.get("pageUrl"),s=this.timeManager.now(),i=this.timeManager.validateTimestamp(s);i.valid||a("warn","Event timestamp validation failed",{data:{type:e.type,error:i.error}});let o={id:Rt(),type:e.type,page_url:r,timestamp:s,...t&&{referrer:document.referrer||"Direct"},...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.viewport_data&&{viewport_data:e.viewport_data},...t&&$e()&&{utm:$e()}};const l=this.get("collectApiUrls"),c=!!l?.custom,d=!!l?.saas,g=c||d,S=c&&d,T=this.transformers.beforeSend;if(T&&(!g||c&&!S)){const ee=ze(o,T,"EventManager");if(ee===null)return null;o=ee}return o}isDuplicateEvent(e){const t=Date.now(),r=this.createEventFingerprint(e),s=this.recentEventFingerprints.get(r);return s&&t-s<1e3?(this.recentEventFingerprints.set(r,t),!0):(this.recentEventFingerprints.set(r,t),this.recentEventFingerprints.size>1500&&this.pruneOldFingerprints(),this.recentEventFingerprints.size>3e3&&(this.recentEventFingerprints.clear(),this.recentEventFingerprints.set(r,t),a("warn","Event fingerprint cache exceeded hard limit, cleared",{data:{hardLimit:3e3}})),!1)}pruneOldFingerprints(){const e=Date.now(),t=1e3*10;for(const[r,s]of this.recentEventFingerprints.entries())e-s>t&&this.recentEventFingerprints.delete(r);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 r=Math.round((e.click_data.x||0)/10)*10,s=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${r}_${s}`}return e.scroll_data&&(t+=`_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`),e.custom_event&&(t+=`_custom_${e.custom_event.name}`),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)}addToQueue(e){if(this.emitEvent(e),this.eventsQueue.push(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(s=>s.type!==u.SESSION_START),r=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:r?.type,wasCritical:r?.type===u.SESSION_START}})}this.sendIntervalId||this.startSendInterval(),this.eventsQueue.length>=50&&this.sendEventsQueue()}startSendInterval(){this.sendIntervalId=window.setInterval(()=>{this.eventsQueue.length>0&&this.sendEventsQueue()},1e4)}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 r=Date.now(),i=(this.perEventRateLimits.get(e)??[]).filter(o=>r-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(r),this.perEventRateLimits.set(e,i),!0)}getTypeLimitForEvent(e){return{[u.CLICK]:500,[u.PAGE_VIEW]:100,[u.CUSTOM]:500,[u.VIEWPORT_VISIBLE]:200,[u.SCROLL]:120}[e]??null}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(r=>!t.has(r.id))}emitEvent(e){this.emitter&&this.emitter.emit(B.EVENT,e)}emitEventsQueue(e){this.emitter&&this.emitter.emit(B.QUEUE,e)}debounce(e,t){let r=null;return((...s)=>{r!==null&&clearTimeout(r),r=setTimeout(()=>{e(...s),r=null},t)})}getInitialCounts(){return{total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0}}loadSessionCounts(e){if(typeof window>"u"||typeof localStorage>"u")return this.getInitialCounts();const t=this.get("userId")||"anonymous",r=be(t,e);try{const s=localStorage.getItem(r);if(!s)return this.getInitialCounts();const i=JSON.parse(s);return i._timestamp&&Date.now()-i._timestamp>Le?(a("debug","Session counts expired, clearing",{data:{sessionId:e,age:Date.now()-i._timestamp}}),localStorage.removeItem(r),this.getInitialCounts()):typeof i.total=="number"&&typeof i[u.CLICK]=="number"&&typeof i[u.PAGE_VIEW]=="number"&&typeof i[u.CUSTOM]=="number"&&typeof i[u.VIEWPORT_VISIBLE]=="number"&&typeof i[u.SCROLL]=="number"?{total:i.total,[u.CLICK]:i[u.CLICK],[u.PAGE_VIEW]:i[u.PAGE_VIEW],[u.CUSTOM]:i[u.CUSTOM],[u.VIEWPORT_VISIBLE]:i[u.VIEWPORT_VISIBLE],[u.SCROLL]:i[u.SCROLL]}:(a("warn","Invalid session counts structure in localStorage, resetting",{data:{sessionId:e,parsed:i}}),localStorage.removeItem(r),a("debug","Session counts removed due to invalid/corrupted data",{data:{sessionId:e,parsed:i}}),this.getInitialCounts())}catch(s){return a("warn","Failed to load session counts from localStorage",{error:s,data:{sessionId:e}}),this.getInitialCounts()}}cleanupExpiredSessionCounts(){if(!(typeof window>"u"||typeof localStorage>"u"))try{const e=localStorage.getItem(Re);if(e){const i=Date.now()-parseInt(e,10);if(i<Ce){a("debug","Skipping session counts cleanup (throttled)",{data:{timeSinceLastCleanup:i,throttleMs:Ce}});return}}const t=this.get("userId")||"anonymous",r=`${_}:${t}:session_counts:`,s=[];for(let i=0;i<localStorage.length;i++){const o=localStorage.key(i);if(o?.startsWith(r))try{const l=localStorage.getItem(o);if(l){const c=JSON.parse(l);c._timestamp&&Date.now()-c._timestamp>Le&&s.push(o)}}catch{}}s.forEach(i=>{localStorage.removeItem(i),a("debug","Cleaned up expired session counts",{data:{key:i}})}),s.length>0&&a("info",`Cleaned up ${s.length} expired session counts entries`),localStorage.setItem(Re,Date.now().toString())}catch(e){a("warn","Failed to cleanup expired session counts",{error:e})}}saveSessionCounts(e){const t=this.get("userId")||"anonymous",r=be(t,e);try{const s={...this.sessionEventCounts,_timestamp:Date.now(),_version:1};localStorage.setItem(r,JSON.stringify(s))}catch(s){a("warn","Failed to persist session counts to localStorage",{error:s,data:{sessionId:e}})}}}class Gt{static getId(e){const t=e.getItem(we);if(t)return t;const r=Lt();return e.setItem(we,r),r}}const Xt=/^\d{13}-[a-z0-9]{9}$/;class Qt extends p{storageManager;eventManager;projectId;activityHandler=null;visibilityChangeHandler=null;sessionTimeoutId=null;broadcastChannel=null;isTracking=!1;constructor(e,t,r){super(),this.storageManager=e,this.eventManager=t,this.projectId=r}initCrossTabSync(){if(typeof BroadcastChannel>"u"){a("warn","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel(dt(e)),this.broadcastChannel.onmessage=t=>{const{action:r,sessionId:s,timestamp:i,projectId:o}=t.data??{};o===e&&(r==="session_start"&&s&&typeof i=="number"&&i>Date.now()-5e3?(this.set("sessionId",s),this.persistSession(s,i),this.isTracking&&this.setupSessionTimeout()):r&&r!=="session_start"&&a("debug","Ignored BroadcastChannel message with unknown action",{data:{action:r}}))}}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(!Xt.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()){this.saveStoredSession({id:e,lastActivity:t})}clearStoredSession(){const e=this.getSessionStorageKey();this.storageManager.removeItem(e)}loadStoredSession(){const e=this.getSessionStorageKey(),t=this.storageManager.getItem(e);if(!t)return null;try{const r=JSON.parse(t);return!r.id||typeof r.lastActivity!="number"?null:r}catch{return this.storageManager.removeItem(e),null}}saveStoredSession(e){const t=this.getSessionStorageKey();this.storageManager.setItem(t,JSON.stringify(e))}getSessionStorageKey(){return ut(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){a("warn","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId();a("debug","Session tracking initialized",{data:{sessionId:t,wasRecovered:!!e,willEmitSessionStart:!0}}),this.isTracking=!0;try{this.set("sessionId",t),this.persistSession(t),this.initCrossTabSync(),this.shareSession(t),a("debug","Emitting SESSION_START event",{data:{sessionId:t}}),this.eventManager.track({type:u.SESSION_START}),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}catch(r){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),r}}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.resetSessionState()},e)}resetSessionTimeout(){this.setupSessionTimeout();const e=this.get("sessionId");e&&this.persistSession(e)}clearSessionTimeout(){this.sessionTimeoutId&&(clearTimeout(this.sessionTimeoutId),this.sessionTimeoutId=null)}setupActivityListeners(){this.activityHandler=()=>{this.resetSessionTimeout()},document.addEventListener("click",this.activityHandler,{passive:!0}),document.addEventListener("keydown",this.activityHandler,{passive:!0}),document.addEventListener("scroll",this.activityHandler,{passive:!0})}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=()=>{document.hidden?this.clearSessionTimeout():this.get("sessionId")&&this.setupSessionTimeout()},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null)}resetSessionState(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.isTracking=!1}stopTracking(){this.resetSessionState()}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.isTracking=!1,this.set("hasStartSession",!1)}}class zt extends p{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("warn","Cannot start tracking on destroyed handler");return}const t=this.get("config")?.integrations?.tracelog?.projectId??"custom";try{this.sessionManager=new Qt(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(r){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw a("error","Failed to start session tracking",{error:r}),r}}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 jt extends p{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]=(...r)=>{t.apply(window.history,r),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=le(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;const r=Date.now(),s=this.get("config").pageViewThrottleMs??1e3;if(r-this.lastPageViewTime<s)return;this.lastPageViewTime=r,this.onTrack();const i=this.get("pageUrl");this.set("pageUrl",t);const o=this.extractPageViewData();this.eventManager.track({type:u.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:i,...o&&{page_view:o}})};trackInitialPageView(){const e=le(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.lastPageViewTime=Date.now(),this.eventManager.track({type:u.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{pathname:e,search:t,hash:r}=window.location,{referrer:s}=document,{title:i}=document;return!s&&!i&&!e&&!t&&!r?void 0:{...s&&{referrer:s},...i&&{title:i},...e&&{pathname:e},...t&&{search:t},...r&&{hash:r}}}}class Kt extends p{eventManager;lastClickTimes=new Map;clickHandler;lastPruneTime=0;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,r=t.target,s=typeof HTMLElement<"u"&&r instanceof HTMLElement?r:typeof HTMLElement<"u"&&r instanceof Node&&r.parentElement instanceof HTMLElement?r.parentElement:null;if(!s){a("warn","Click target not found or not an element");return}if(this.shouldIgnoreElement(s))return;const i=this.get("config")?.clickThrottleMs??300;if(i>0&&!this.checkClickThrottle(s,i))return;const o=this.findTrackingElement(s),l=this.getRelevantClickElement(s),c=this.calculateClickCoordinates(t,s);if(o){const g=this.extractTrackingData(o);if(g){const S=this.createCustomEventData(g);this.eventManager.track({type:u.CUSTOM,custom_event:{name:S.name,...S.value&&{metadata:{value:S.value}}}})}}const d=this.generateClickData(s,l,c);this.eventManager.track({type:u.CLICK,click_data:d})},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(`${w}-ignore`)?!0:e.closest(`[${w}-ignore]`)!==null}checkClickThrottle(e,t){const r=this.getElementSignature(e),s=Date.now();this.pruneThrottleCache(s);const i=this.lastClickTimes.get(r);return i!==void 0&&s-i<t?(a("debug","ClickHandler: Click suppressed by throttle",{data:{signature:r,throttleRemaining:t-(s-i)}}),!1):(this.lastClickTimes.set(r,s),!0)}pruneThrottleCache(e){if(e-this.lastPruneTime<3e4)return;this.lastPruneTime=e;const t=e-3e5;for(const[r,s]of this.lastClickTimes.entries())s<t&&this.lastClickTimes.delete(r);if(this.lastClickTimes.size>1e3){const r=Array.from(this.lastClickTimes.entries()).sort((o,l)=>o[1]-l[1]),s=this.lastClickTimes.size-1e3,i=r.slice(0,s);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 r=e.getAttribute(`${w}-name`);return r?`[${w}-name="${r}"]`:this.getElementPath(e)}getElementPath(e){const t=[];let r=e;for(;r&&r!==document.body;){let s=r.tagName.toLowerCase();if(r.className){const i=r.className.split(" ")[0];i&&(s+=`.${i}`)}t.unshift(s),r=r.parentElement}return t.join(">")||"unknown"}findTrackingElement(e){return e.hasAttribute(`${w}-name`)?e:e.closest(`[${w}-name]`)}getRelevantClickElement(e){for(const t of it)try{if(e.matches(t))return e;const r=e.closest(t);if(r)return r}catch(r){a("warn","Invalid selector in element search",{error:r,data:{selector:t}});continue}return e}clamp(e){return Math.max(0,Math.min(1,Number(e.toFixed(3))))}calculateClickCoordinates(e,t){const r=t.getBoundingClientRect(),s=e.clientX,i=e.clientY,o=r.width>0?this.clamp((s-r.left)/r.width):0,l=r.height>0?this.clamp((i-r.top)/r.height):0;return{x:s,y:i,relativeX:o,relativeY:l}}extractTrackingData(e){const t=e.getAttribute(`${w}-name`),r=e.getAttribute(`${w}-value`);if(t)return{element:e,name:t,...r&&{value:r}}}generateClickData(e,t,r){const{x:s,y:i,relativeX:o,relativeY:l}=r,c=this.getRelevantText(e,t),d=this.extractElementAttributes(t);return{x:s,y:i,relativeX:o,relativeY:l,tag:t.tagName.toLowerCase(),...t.id&&{id:t.id},...t.className&&{class:t.className},...c&&{text:c},...d.href&&{href:d.href},...d.title&&{title:d.title},...d.alt&&{alt:d.alt},...d.role&&{role:d.role},...d["aria-label"]&&{ariaLabel:d["aria-label"]},...Object.keys(d).length>0&&{dataAttributes:d}}}sanitizeText(e){let t=e;for(const r of ie){const s=new RegExp(r.source,r.flags);t=t.replace(s,"[REDACTED]")}return t}getRelevantText(e,t){const r=e.textContent?.trim()??"",s=t.textContent?.trim()??"";if(!r&&!s)return"";let i="";return r&&r.length<=255?i=r:s.length<=255?i=s:i=s.slice(0,252)+"...",this.sanitizeText(i)}extractElementAttributes(e){const t=["id","class","data-testid","aria-label","title","href","type","name","alt","role"],r={};for(const s of t){const i=e.getAttribute(s);i&&(r[s]=i)}return r}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class Yt extends p{eventManager;containers=[];limitWarningLogged=!1;minDepthChange=5;minIntervalMs=500;maxEventsPerSession=120;containerDiscoveryTimeoutId=null;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.applyConfigOverrides(),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 r of t){const s=this.getElementSelector(r);this.setupScrollContainer(r,s)}this.applyPrimaryScrollSelectorIfConfigured();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"),this.applyPrimaryScrollSelectorIfConfigured()}applyPrimaryScrollSelectorIfConfigured(){const e=this.get("config");e?.primaryScrollSelector&&this.applyPrimaryScrollSelector(e.primaryScrollSelector)}findScrollableElements(){if(!document.body)return[];const e=[],t=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,{acceptNode:s=>{const i=s;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 r;for(;(r=t.nextNode())&&e.length<10;){const s=r;this.isElementScrollable(s)&&e.push(s)}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 r=t.className.split(" ").filter(s=>s.trim())[0];if(r)return`.${r}`}return t.tagName.toLowerCase()}determineIfPrimary(e){return this.isWindowScrollable()?e===window:this.containers.length===0}setupScrollContainer(e,t){if(this.containers.some(d=>d.element===e)||e!==window&&!this.isElementScrollable(e))return;const s=this.getScrollTop(e),i=this.calculateScrollDepth(s,this.getScrollHeight(e),this.getViewportHeight(e)),o=this.determineIfPrimary(e),l={element:e,selector:t,isPrimary:o,lastScrollPos:s,lastDepth:i,lastDirection:x.DOWN,lastEventTime:0,firstScrollEventTime:null,maxDepthReached:i,debounceTimer:null,listener:null},c=()=>{this.get("suppressNextScroll")||(l.firstScrollEventTime===null&&(l.firstScrollEventTime=Date.now()),this.clearContainerTimer(l),l.debounceTimer=window.setTimeout(()=>{const d=this.calculateScrollData(l);if(d){const g=Date.now();this.processScrollEvent(l,d,g)}l.debounceTimer=null},250))};l.listener=c,this.containers.push(l),e===window?window.addEventListener("scroll",c,{passive:!0}):e.addEventListener("scroll",c,{passive:!0})}processScrollEvent(e,t,r){if(!this.shouldEmitScrollEvent(e,t,r))return;e.lastEventTime=r,e.lastDepth=t.depth,e.lastDirection=t.direction;const s=this.get("scrollEventCount")??0;this.set("scrollEventCount",s+1),this.eventManager.track({type:u.SCROLL,scroll_data:{...t,container_selector:e.selector,is_primary:e.isPrimary}})}shouldEmitScrollEvent(e,t,r){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,r)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=this.maxEventsPerSession}hasElapsedMinimumInterval(e,t){return e.lastEventTime===0?!0:t-e.lastEventTime>=this.minIntervalMs}hasSignificantDepthChange(e,t){return Math.abs(t-e.lastDepth)>=this.minDepthChange}logLimitOnce(){this.limitWarningLogged||(this.limitWarningLogged=!0,a("warn","Max scroll events per session reached",{data:{limit:this.maxEventsPerSession}}))}applyConfigOverrides(){this.minDepthChange=5,this.minIntervalMs=500,this.maxEventsPerSession=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?x.DOWN:x.UP}calculateScrollDepth(e,t,r){if(t<=r)return 0;const s=t-r;return Math.min(100,Math.max(0,Math.floor(e/s*100)))}calculateScrollData(e){const{element:t,lastScrollPos:r,lastEventTime:s}=e,i=this.getScrollTop(t),o=Date.now(),l=Math.abs(i-r);if(l<10||t===window&&!this.isWindowScrollable())return null;const c=this.getViewportHeight(t),d=this.getScrollHeight(t),g=this.getScrollDirection(i,r),S=this.calculateScrollDepth(i,d,c);let T;s>0?T=o-s:e.firstScrollEventTime!==null?T=o-e.firstScrollEventTime:T=250;const Z=Math.round(l/T*1e3);return S>e.maxDepthReached&&(e.maxDepthReached=S),e.lastScrollPos=i,{depth:S,direction:g,velocity:Z,max_depth_reached:e.maxDepthReached}}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),r=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflow==="auto"||t.overflow==="scroll",s=e.scrollHeight>e.clientHeight;return r&&s}applyPrimaryScrollSelector(e){let t;if(e==="window")t=window;else{const s=document.querySelector(e);if(!(s instanceof HTMLElement)){a("warn",`Selector "${e}" did not match an HTMLElement`);return}t=s}this.containers.forEach(s=>{this.updateContainerPrimary(s,s.element===t)}),!this.containers.some(s=>s.element===t)&&t instanceof HTMLElement&&this.isElementScrollable(t)&&this.setupScrollContainer(t,e)}updateContainerPrimary(e,t){e.isPrimary=t}}class qt extends p{eventManager;trackedElements=new Map;observer=null;mutationObserver=null;mutationDebounceTimer=null;config=null;constructor(e){super(),this.eventManager=e}startTracking(){const e=this.get("config");if(this.config=e.viewport??null,!this.config?.elements||this.config.elements.length===0)return;const t=this.config.threshold??.5,r=this.config.minDwellTime??1e3;if(t<0||t>1){a("warn","ViewportHandler: Invalid threshold, must be between 0 and 1");return}if(r<0){a("warn","ViewportHandler: Invalid minDwellTime, must be non-negative");return}if(typeof IntersectionObserver>"u"){a("warn","ViewportHandler: IntersectionObserver not supported in this browser");return}this.observer=new IntersectionObserver(this.handleIntersection,{threshold:t}),this.observeElements(),this.setupMutationObserver()}stopTracking(){this.observer&&(this.observer.disconnect(),this.observer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.mutationDebounceTimer!==null&&(window.clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null);for(const e of this.trackedElements.values())e.timeoutId!==null&&window.clearTimeout(e.timeoutId);this.trackedElements.clear()}observeElements(){if(!this.config||!this.observer)return;const e=this.config.maxTrackedElements??100;let t=this.trackedElements.size;for(const r of this.config.elements)try{const s=document.querySelectorAll(r.selector);for(const i of Array.from(s)){if(t>=e){a("warn","ViewportHandler: Maximum tracked elements reached",{data:{limit:e,selector:r.selector,message:"Some elements will not be tracked. Consider more specific selectors."}});return}i.hasAttribute(`${w}-ignore`)||this.trackedElements.has(i)||(this.trackedElements.set(i,{element:i,selector:r.selector,id:r.id,name:r.name,startTime:null,timeoutId:null,lastFiredTime:null}),this.observer?.observe(i),t++)}}catch(s){a("warn",`ViewportHandler: Invalid selector "${r.selector}"`,{error:s})}a("debug","ViewportHandler: Elements tracked",{data:{count:t,limit:e}})}handleIntersection=e=>{if(!this.config)return;const t=this.config.minDwellTime??1e3;for(const r of e){const s=this.trackedElements.get(r.target);s&&(r.isIntersecting?s.startTime===null&&(s.startTime=performance.now(),s.timeoutId=window.setTimeout(()=>{const i=Math.round(r.intersectionRatio*100)/100;this.fireViewportEvent(s,i)},t)):s.startTime!==null&&(s.timeoutId!==null&&(window.clearTimeout(s.timeoutId),s.timeoutId=null),s.startTime=null))}};fireViewportEvent(e,t){if(e.startTime===null)return;const r=Math.round(performance.now()-e.startTime);if(e.element.hasAttribute(`${w}-ignore`))return;const s=this.config?.cooldownPeriod??6e4,i=Date.now();if(e.lastFiredTime!==null&&i-e.lastFiredTime<s){a("debug","ViewportHandler: Event suppressed by cooldown period",{data:{selector:e.selector,cooldownRemaining:s-(i-e.lastFiredTime)}}),e.startTime=null,e.timeoutId=null;return}const o={selector:e.selector,dwellTime:r,visibilityRatio:t,...e.id!==void 0&&{id:e.id},...e.name!==void 0&&{name:e.name}};this.eventManager.track({type:u.VIEWPORT_VISIBLE,viewport_data:o}),e.startTime=null,e.timeoutId=null,e.lastFiredTime=i}setupMutationObserver(){if(!(!this.config||typeof MutationObserver>"u")){if(!document.body){a("warn","ViewportHandler: document.body not available, skipping MutationObserver setup");return}this.mutationObserver=new MutationObserver(e=>{let t=!1;for(const r of e)r.type==="childList"&&(r.addedNodes.length>0&&(t=!0),r.removedNodes.length>0&&this.cleanupRemovedNodes(r.removedNodes));t&&(this.mutationDebounceTimer!==null&&window.clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.observeElements(),this.mutationDebounceTimer=null},100))}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}}cleanupRemovedNodes(e){e.forEach(t=>{if(t.nodeType!==1)return;const r=t,s=this.trackedElements.get(r);s&&(s.timeoutId!==null&&window.clearTimeout(s.timeoutId),this.observer?.unobserve(r),this.trackedElements.delete(r)),Array.from(this.trackedElements.keys()).filter(o=>r.contains(o)).forEach(o=>{const l=this.trackedElements.get(o);l&&l.timeoutId!==null&&window.clearTimeout(l.timeoutId),this.observer?.unobserve(o),this.trackedElements.delete(o)})})}}class Jt{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;hasQuotaExceededError=!1;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||a("warn","localStorage not available, using memory fallback"),this.sessionStorageRef||a("warn","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){this.fallbackStorage.set(e,t);try{if(this.storage){this.storage.setItem(e,t);return}}catch(r){if(r instanceof DOMException&&r.name==="QuotaExceededError"||r instanceof Error&&r.name==="QuotaExceededError")if(this.hasQuotaExceededError=!0,a("warn","localStorage quota exceeded, attempting cleanup",{data:{key:e,valueSize:t.length}}),this.cleanupOldData())try{if(this.storage){this.storage.setItem(e,t);return}}catch(o){a("error","localStorage quota exceeded even after cleanup - data will not persist",{error:o,data:{key:e,valueSize:t.length}})}else a("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:r,data:{key:e,valueSize:t.length}})}}removeItem(e){try{this.storage&&this.storage.removeItem(e)}catch{}this.fallbackStorage.delete(e)}clear(){if(!this.storage){this.fallbackStorage.clear();return}try{const e=[];for(let t=0;t<this.storage.length;t++){const r=this.storage.key(t);r?.startsWith("tracelog_")&&e.push(r)}e.forEach(t=>{this.storage.removeItem(t)}),this.fallbackStorage.clear()}catch(e){a("error","Failed to clear storage",{error:e}),this.fallbackStorage.clear()}}isAvailable(){return this.storage!==null}hasQuotaError(){return this.hasQuotaExceededError}cleanupOldData(){if(!this.storage)return!1;try{const e=[],t=[];for(let i=0;i<this.storage.length;i++){const o=this.storage.key(i);o?.startsWith("tracelog_")&&(e.push(o),o.startsWith("tracelog_persisted_events_")&&t.push(o))}if(t.length>0)return t.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0;const r=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],s=e.filter(i=>!r.some(o=>i.startsWith(o)));return s.length>0?(s.slice(0,5).forEach(o=>{try{this.storage.removeItem(o)}catch{}}),!0):!1}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,r="__tracelog_test__";return t.setItem(r,"test"),t.removeItem(r),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(r){(r instanceof DOMException&&r.name==="QuotaExceededError"||r instanceof Error&&r.name==="QuotaExceededError")&&a("error","sessionStorage quota exceeded - data will not persist",{error:r,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class Zt extends p{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds;lastLongTaskSentAt=0;navigationCounter=0;constructor(e){super(),this.eventManager=e,this.vitalThresholds=ae(G)}async startTracking(){const e=this.get("config"),t=e?.webVitalsMode??G;this.vitalThresholds=ae(t),e?.webVitalsThresholds&&(this.vitalThresholds={...this.vitalThresholds,...e.webVitalsThresholds}),await this.initWebVitals(),this.observeLongTasks()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(r){a("warn","Failed to disconnect performance observer",{error:r,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear(),this.navigationHistory.length=0}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",r=>{const s=r.getEntries(),i=s[s.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",r=>{const s=this.getNavigationId();s!==t&&(e=0,t=s);const i=r.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",r=>{for(const s of r.getEntries())s.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(s.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",r=>{let s=0;const i=r.getEntries();for(const o of i){const l=(o.processingEnd??0)-(o.startTime??0);s=Math.max(s,l)}s>0&&this.sendVital({type:"INP",value:Number(s.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:r,onTTFB:s,onINP:i}=await Promise.resolve().then(()=>pr),o=l=>c=>{const d=Number(c.value.toFixed(2));this.sendVital({type:l,value:d})};e(o("LCP"),{reportAllChanges:!1}),t(o("CLS"),{reportAllChanges:!1}),r(o("FCP"),{reportAllChanges:!1}),s(o("TTFB"),{reportAllChanges:!1}),i(o("INP"),{reportAllChanges:!1})}catch(e){a("warn","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("warn","Failed to report TTFB",{error:e})}}observeLongTasks(){this.safeObserve("longtask",e=>{const t=e.getEntries();for(const r of t){const s=Number(r.duration.toFixed(2)),i=Date.now();i-this.lastLongTaskSentAt>=wt&&(this.shouldSendVital("LONG_TASK",s)&&this.trackWebVital("LONG_TASK",s),this.lastLongTaskSentAt=i)}},{type:"longtask",buffered:!0})}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const r=this.reportedByNav.get(t);if(r?.has(e.type))return;if(r)r.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("warn","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:u.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(),r=++this.navigationCounter,s=`${t.toFixed(2)}_${window.location.pathname}`;return r>1?`${s}_${r}`:s}catch(e){return a("warn","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,r,s=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((o,l)=>{try{t(o,l)}catch(c){a("warn","Observer callback failed",{error:c,data:{type:e}})}if(s)try{l.disconnect()}catch{}});return i.observe(r??{type:e,buffered:!0}),s||this.observers.push(i),!0}catch(i){return a("warn","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return a("warn","Invalid web vital value",{data:{type:e,value:t}}),!1;const r=this.vitalThresholds[e];return!(typeof r=="number"&&t<=r)}}class er extends p{eventManager;recentErrors=new Map;errorBurstCounter=0;burstWindowStart=0;burstBackoffUntil=0;constructor(e){super(),this.eventManager=e}startTracking(){window.addEventListener("error",this.handleError),window.addEventListener("unhandledrejection",this.handleRejection)}stopTracking(){window.removeEventListener("error",this.handleError),window.removeEventListener("unhandledrejection",this.handleRejection),this.recentErrors.clear(),this.errorBurstCounter=0,this.burstWindowStart=0,this.burstBackoffUntil=0}shouldSample(){const e=Date.now();if(e<this.burstBackoffUntil)return!1;if(e-this.burstWindowStart>pt&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>_t)return this.burstBackoffUntil=e+xe,a("warn","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:xe}}),!1;const r=this.get("config")?.errorSampling??He;return Math.random()<r}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");this.shouldSuppressError(P.JS_ERROR,t)||this.eventManager.track({type:u.ERROR,error_data:{type:P.JS_ERROR,message:t,...e.filename&&{filename:e.filename},...e.lineno&&{line:e.lineno},...e.colno&&{column:e.colno}}})};handleRejection=e=>{if(!this.shouldSample())return;const t=this.extractRejectionMessage(e.reason),r=this.sanitize(t);this.shouldSuppressError(P.PROMISE_REJECTION,r)||this.eventManager.track({type:u.ERROR,error_data:{type:P.PROMISE_REJECTION,message:r}})};extractRejectionMessage(e){if(!e)return"Unknown rejection";if(typeof e=="string")return e;if(e instanceof Error)return e.stack??e.message??e.toString();if(typeof e=="object"&&"message"in e)return String(e.message);try{return JSON.stringify(e)}catch{return String(e)}}sanitize(e){let t=e.length>ke?e.slice(0,ke)+"...":e;for(const r of ie){const s=new RegExp(r.source,r.flags);t=t.replace(s,"[REDACTED]")}return t}shouldSuppressError(e,t){const r=Date.now(),s=`${e}:${t}`,i=this.recentErrors.get(s);return i&&r-i<Ue?(this.recentErrors.set(s,r),!0):(this.recentErrors.set(s,r),this.recentErrors.size>Tt?(this.recentErrors.clear(),this.recentErrors.set(s,r),!1):(this.recentErrors.size>W&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[s,i]of this.recentErrors.entries())e-i>Ue&&this.recentErrors.delete(s);if(this.recentErrors.size<=W)return;const t=Array.from(this.recentErrors.entries()).sort((s,i)=>s[1]-i[1]),r=this.recentErrors.size-W;for(let s=0;s<r;s+=1){const i=t[s];i&&this.recentErrors.delete(i[0])}}}class tr extends p{isInitialized=!1;suppressNextScrollTimer=null;emitter=new Ft;transformers={};managers={};handlers={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new Jt;try{this.setupState(e),this.managers.event=new Wt(this.managers.storage,this.emitter,this.transformers),this.initializeHandlers(),await this.managers.event.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0}catch(t){this.destroy(!0);const r=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${r}`)}}}sendCustomEvent(e,t){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:s,error:i,sanitizedMetadata:o}=xt(e,r);if(!s){if(this.get("mode")===F.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${i}`);return}this.managers.event.track({type:u.CUSTOM,custom_event:{name:e,...o&&{metadata:o}}})}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}setTransformer(e,t){if(typeof t!="function")throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof t}`);this.transformers[e]=t}removeTransformer(e){delete this.transformers[e]}getTransformer(e){return this.transformers[e]}destroy(e=!1){!this.isInitialized&&!e||(Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(r){a("warn","Failed to stop tracking",{error:r})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.transformers.beforeSend=void 0,this.transformers.beforeBatch=void 0,this.set("suppressNextScroll",!1),this.set("sessionId",null),this.isInitialized=!1,this.handlers={},this.managers={})}setupState(e={}){this.set("config",e);const t=Gt.getId(this.managers.storage);this.set("userId",t);const r=Nt(e);this.set("collectApiUrls",r);const s=St();this.set("device",s);const i=le(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const o=Mt()?F.QA:void 0;o&&this.set("mode",o)}getConfig(){return this.get("config")}getCollectApiUrls(){return this.get("collectApiUrls")}getEventManager(){return this.managers.event}validateGlobalMetadata(e){if(typeof e!="object"||e===null||Array.isArray(e))return{valid:!1,error:"Global metadata must be a plain object"};const t=Qe("Global",e,"globalMetadata");return t.valid?{valid:!0}:{valid:!1,error:t.error}}updateGlobalMetadata(e){const t=this.validateGlobalMetadata(e);if(!t.valid)throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);const s={...this.get("config"),globalMetadata:e};this.set("config",s),a("debug","Global metadata updated (replaced)",{data:{keys:Object.keys(e)}})}mergeGlobalMetadata(e){const t=this.validateGlobalMetadata(e);if(!t.valid)throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);const r=this.get("config"),i={...r.globalMetadata??{},...e},o={...r,globalMetadata:i};this.set("config",o),a("debug","Global metadata updated (merged)",{data:{keys:Object.keys(e)}})}initializeHandlers(){const e=this.get("config"),t=e.disabledEvents??[];this.handlers.session=new zt(this.managers.storage,this.managers.event),this.handlers.session.startTracking();const r=()=>{this.set("suppressNextScroll",!0),this.suppressNextScrollTimer&&clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=window.setTimeout(()=>{this.set("suppressNextScroll",!1)},500)};this.handlers.pageView=new jt(this.managers.event,r),this.handlers.pageView.startTracking(),this.handlers.click=new Kt(this.managers.event),this.handlers.click.startTracking(),t.includes("scroll")||(this.handlers.scroll=new Yt(this.managers.event),this.handlers.scroll.startTracking()),t.includes("web_vitals")||(this.handlers.performance=new Zt(this.managers.event),this.handlers.performance.startTracking().catch(s=>{a("warn","Failed to start performance tracking",{error:s})})),t.includes("error")||(this.handlers.error=new er(this.managers.event),this.handlers.error.startTracking()),e.viewport&&(this.handlers.viewport=new qt(this.managers.event),this.handlers.viewport.startTracking())}}const C=[],L=[];let m=null,N=!1,I=!1;const rr=async n=>{if(!(typeof window>"u"||typeof document>"u")&&(I=!1,window.__traceLogDisabled!==!0&&!m&&!N)){N=!0;try{const e=kt(n??{}),t=new tr;try{C.forEach(({event:i,callback:o})=>{t.on(i,o)}),C.length=0,L.forEach(({hook:i,fn:o})=>{i==="beforeSend"?t.setTransformer("beforeSend",o):t.setTransformer("beforeBatch",o)}),L.length=0;const r=t.init(e),s=new Promise((i,o)=>{setTimeout(()=>{o(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)});await Promise.race([r,s]),m=t}catch(r){try{t.destroy(!0)}catch(s){a("error","Failed to cleanup partially initialized app",{error:s})}throw r}}catch(e){throw m=null,e}finally{N=!1}}},nr=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!m)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(I)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");m.sendCustomEvent(n,e)}},sr=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!m||N){C.push({event:n,callback:e});return}m.on(n,e)}},ir=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!m){const t=C.findIndex(r=>r.event===n&&r.callback===e);t!==-1&&C.splice(t,1);return}m.off(n,e)}};function or(n,e){if(!(typeof window>"u"||typeof document>"u")){if(typeof e!="function")throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);if(!m||N){const t=L.findIndex(r=>r.hook===n);t!==-1&&L.splice(t,1),L.push({hook:n,fn:e});return}if(I)throw new Error("[TraceLog] Cannot set transformers while TraceLog is being destroyed");n==="beforeSend"?m.setTransformer("beforeSend",e):m.setTransformer("beforeBatch",e)}}const ar={init:rr,event:nr,on:sr,off:ir,setTransformer:or,removeTransformer:n=>{if(!(typeof window>"u"||typeof document>"u")){if(!m){const e=L.findIndex(t=>t.hook===n);e!==-1&&L.splice(e,1);return}if(I)throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");m.removeTransformer(n)}},isInitialized:()=>typeof window>"u"||typeof document>"u"?!1:m!==null,destroy:()=>{if(!(typeof window>"u"||typeof document>"u")){if(I)throw new Error("[TraceLog] Destroy operation already in progress");if(!m){I=!1;return}I=!0;try{m.destroy(),m=null,N=!1,C.length=0,L.length=0,I=!1}catch(n){m=null,N=!1,C.length=0,L.length=0,I=!1,a("warn","Error during destroy, forced cleanup completed",{error:n})}}},setQaMode:n=>{typeof window>"u"||typeof document>"u"||bt(n)},updateGlobalMetadata:n=>{if(!(typeof window>"u"||typeof document>"u")){if(!m)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(I)throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");m.updateGlobalMetadata(n)}},mergeGlobalMetadata:n=>{if(!(typeof window>"u"||typeof document>"u")){if(!m)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(I)throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");m.mergeGlobalMetadata(n)}}};var de,Ye=-1,k=function(n){addEventListener("pageshow",(function(e){e.persisted&&(Ye=e.timeStamp,n(e))}),!0)},he=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},z=function(){var n=he();return n&&n.activationStart||0},y=function(n,e){var t=he(),r="navigate";return Ye>=0?r="back-forward-cache":t&&(document.prerendering||z()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=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:r}},$=function(n,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(n)){var r=new PerformanceObserver((function(s){Promise.resolve().then((function(){e(s.getEntries())}))}));return r.observe(Object.assign({type:n,buffered:!0},t||{})),r}}catch{}},A=function(n,e,t,r){var s,i;return function(o){e.value>=0&&(o||r)&&((i=e.value-(s||0))||s===void 0)&&(s=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))}},fe=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},j=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},me=function(n){var e=!1;return function(){e||(n(),e=!0)}},U=-1,qe=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},K=function(n){document.visibilityState==="hidden"&&U>-1&&(U=n.type==="visibilitychange"?n.timeStamp:0,lr())},Je=function(){addEventListener("visibilitychange",K,!0),addEventListener("prerenderingchange",K,!0)},lr=function(){removeEventListener("visibilitychange",K,!0),removeEventListener("prerenderingchange",K,!0)},Ze=function(){return U<0&&(U=qe(),Je(),k((function(){setTimeout((function(){U=qe(),Je()}),0)}))),{get firstHiddenTime(){return U}}},Y=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},Ee=[1800,3e3],et=function(n,e){e=e||{},Y((function(){var t,r=Ze(),s=y("FCP"),i=$("paint",(function(o){o.forEach((function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<r.firstHiddenTime&&(s.value=Math.max(l.startTime-z(),0),s.entries.push(l),t(!0)))}))}));i&&(t=A(n,s,Ee,e.reportAllChanges),k((function(o){s=y("FCP"),t=A(n,s,Ee,e.reportAllChanges),fe((function(){s.value=performance.now()-o.timeStamp,t(!0)}))})))}))},ge=[.1,.25],cr=function(n,e){e=e||{},et(me((function(){var t,r=y("CLS",0),s=0,i=[],o=function(c){c.forEach((function(d){if(!d.hadRecentInput){var g=i[0],S=i[i.length-1];s&&d.startTime-S.startTime<1e3&&d.startTime-g.startTime<5e3?(s+=d.value,i.push(d)):(s=d.value,i=[d])}})),s>r.value&&(r.value=s,r.entries=i,t())},l=$("layout-shift",o);l&&(t=A(n,r,ge,e.reportAllChanges),j((function(){o(l.takeRecords()),t(!0)})),k((function(){s=0,r=y("CLS",0),t=A(n,r,ge,e.reportAllChanges),fe((function(){return t()}))})),setTimeout(t,0))})))},tt=0,Se=1/0,q=0,ur=function(n){n.forEach((function(e){e.interactionId&&(Se=Math.min(Se,e.interactionId),q=Math.max(q,e.interactionId),tt=q?(q-Se)/7+1:0)}))},rt=function(){return de?tt:performance.interactionCount||0},dr=function(){"interactionCount"in performance||de||(de=$("event",ur,{type:"event",buffered:!0,durationThreshold:0}))},M=[],J=new Map,nt=0,hr=function(){var n=Math.min(M.length-1,Math.floor((rt()-nt)/50));return M[n]},fr=[],mr=function(n){if(fr.forEach((function(s){return s(n)})),n.interactionId||n.entryType==="first-input"){var e=M[M.length-1],t=J.get(n.interactionId);if(t||M.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 r={id:n.interactionId,latency:n.duration,entries:[n]};J.set(r.id,r),M.push(r)}M.sort((function(s,i){return i.latency-s.latency})),M.length>10&&M.splice(10).forEach((function(s){return J.delete(s.id)}))}}},st=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=me(n),document.visibilityState==="hidden"?n():(t=e(n),j(n)),t},Te=[200,500],Er=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},Y((function(){var t;dr();var r,s=y("INP"),i=function(l){st((function(){l.forEach(mr);var c=hr();c&&c.latency!==s.value&&(s.value=c.latency,s.entries=c.entries,r())}))},o=$("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});r=A(n,s,Te,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),j((function(){i(o.takeRecords()),r(!0)})),k((function(){nt=rt(),M.length=0,J.clear(),s=y("INP"),r=A(n,s,Te,e.reportAllChanges)})))})))},pe=[2500,4e3],_e={},gr=function(n,e){e=e||{},Y((function(){var t,r=Ze(),s=y("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach((function(d){d.startTime<r.firstHiddenTime&&(s.value=Math.max(d.startTime-z(),0),s.entries=[d],t())}))},o=$("largest-contentful-paint",i);if(o){t=A(n,s,pe,e.reportAllChanges);var l=me((function(){_e[s.id]||(i(o.takeRecords()),o.disconnect(),_e[s.id]=!0,t(!0))}));["keydown","click"].forEach((function(c){addEventListener(c,(function(){return st(l)}),{once:!0,capture:!0})})),j(l),k((function(c){s=y("LCP"),t=A(n,s,pe,e.reportAllChanges),fe((function(){s.value=performance.now()-c.timeStamp,_e[s.id]=!0,t(!0)}))}))}}))},Ie=[800,1800],Sr=function n(e){document.prerendering?Y((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},Tr=function(n,e){e=e||{};var t=y("TTFB"),r=A(n,t,Ie,e.reportAllChanges);Sr((function(){var s=he();s&&(t.value=Math.max(s.responseStart-z(),0),t.entries=[s],r(!0),k((function(){t=y("TTFB",0),(r=A(n,t,Ie,e.reportAllChanges))(!0)})))}))};const pr=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:ge,FCPThresholds:Ee,INPThresholds:Te,LCPThresholds:pe,TTFBThresholds:Ie,onCLS:cr,onFCP:et,onINP:Er,onLCP:gr,onTTFB:Tr},Symbol.toStringTag,{value:"Module"}));h.AppConfigValidationError=f,h.DEFAULT_SESSION_TIMEOUT=9e5,h.DEFAULT_WEB_VITALS_MODE=G,h.DeviceType=b,h.EmitterEvent=B,h.ErrorType=P,h.EventType=u,h.InitializationTimeoutError=mt,h.IntegrationValidationError=V,h.MAX_ARRAY_LENGTH=100,h.MAX_CUSTOM_EVENT_ARRAY_SIZE=10,h.MAX_CUSTOM_EVENT_KEYS=10,h.MAX_CUSTOM_EVENT_NAME_LENGTH=120,h.MAX_CUSTOM_EVENT_STRING_SIZE=8192,h.MAX_METADATA_NESTING_DEPTH=1,h.MAX_NESTED_OBJECT_KEYS=20,h.MAX_STRING_LENGTH=1e3,h.MAX_STRING_LENGTH_IN_ARRAY=500,h.Mode=F,h.PII_PATTERNS=ie,h.PermanentError=R,h.SamplingRateValidationError=re,h.ScrollDirection=x,h.SessionTimeoutValidationError=Ne,h.SpecialApiUrl=O,h.TraceLogValidationError=D,h.WEB_VITALS_GOOD_THRESHOLDS=vt,h.WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS=oe,h.WEB_VITALS_POOR_THRESHOLDS=Fe,h.getWebVitalsThresholds=ae,h.isPrimaryScrollEvent=ht,h.isSecondaryScrollEvent=ft,h.tracelog=ar,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 w="data-tlog",st=["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"]'],it=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],ot=["token","auth","key","session","reset","password","api_key","apikey","secret","access_token","refresh_token","verification","code","otp"],E={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_CUSTOM_API_URL:"Custom API URL 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_PRIMARY_SCROLL_SELECTOR:"Primary scroll selector must be a non-empty string",INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX:"Invalid CSS selector syntax for primaryScrollSelector",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_VIEWPORT_CONFIG:"Viewport config must be an object",INVALID_VIEWPORT_ELEMENTS:"Viewport elements must be a non-empty array",INVALID_VIEWPORT_ELEMENT:"Each viewport element must have a valid selector string",INVALID_VIEWPORT_ELEMENT_ID:"Viewport element id must be a non-empty string",INVALID_VIEWPORT_ELEMENT_NAME:"Viewport element name must be a non-empty string",INVALID_VIEWPORT_THRESHOLD:"Viewport threshold must be a number between 0 and 1",INVALID_VIEWPORT_MIN_DWELL_TIME:"Viewport minDwellTime must be a non-negative number",INVALID_VIEWPORT_COOLDOWN_PERIOD:"Viewport cooldownPeriod must be a non-negative number",INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS:"Viewport maxTrackedElements must be a positive number"},at=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi],_="tlog",H=`${_}:qa_mode`,we=`${_}:uid`,ye="tlog_mode",Ae="qa",Me="qa_off",lt=n=>n?`${_}:${n}:queue`:`${_}:queue`,ct=n=>n?`${_}:${n}:session`:`${_}:session`,ut=n=>n?`${_}:${n}:broadcast`:`${_}:broadcast`,Le=(n,e)=>`${_}:${n}:session_counts:${e}`,be=10080*60*1e3,Re=`${_}:session_counts_last_cleanup`,Ce=3600*1e3;var O=(n=>(n.Localhost="localhost:8080",n.Fail="localhost:9999",n))(O||{}),L=(n=>(n.Mobile="mobile",n.Tablet="tablet",n.Desktop="desktop",n.Unknown="unknown",n))(L||{}),B=(n=>(n.EVENT="event",n.QUEUE="queue",n))(B||{});class R extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,R)}}var u=(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.VIEWPORT_VISIBLE="viewport_visible",n))(u||{}),x=(n=>(n.UP="up",n.DOWN="down",n))(x||{}),P=(n=>(n.JS_ERROR="js_error",n.PROMISE_REJECTION="promise_rejection",n))(P||{}),F=(n=>(n.QA="qa",n))(F||{});const dt=n=>n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!0,ht=n=>n.type===u.SCROLL&&"scroll_data"in n&&n.scroll_data.is_primary===!1;class D extends Error{constructor(e,t,r){super(e),this.errorCode=t,this.layer=r,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class f extends D{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class Ne extends D{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class re extends D{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class V extends D{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class ft extends D{constructor(e,t,r="runtime"){super(e,"INITIALIZATION_TIMEOUT",r),this.timeoutMs=t}}const mt=(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}`},a=(n,e,t)=>{const{error:r,data:s,showToClient:i=!1,style:o}=t??{},l=r?mt(e,r):`[TraceLog] ${e}`,c=n==="error"?"error":n==="warn"?"warn":"log";if(n==="debug"||n==="info"&&!i)return;const d=o!==void 0&&o!=="",g=d?`%c${l}`:l;if(s!==void 0){const S=ne(s);d?console[c](g,o,S):console[c](g,S)}else d?console[c](g,o):console[c](g)},ne=n=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[r,s]of Object.entries(n)){const i=r.toLowerCase();if(t.some(o=>i.includes(o))){e[r]="[REDACTED]";continue}s!==null&&typeof s=="object"&&!Array.isArray(s)?e[r]=ne(s):Array.isArray(s)?e[r]=s.map(o=>o!==null&&typeof o=="object"&&!Array.isArray(o)?ne(o):o):e[r]=s}return e};let se,Oe;const Et=()=>{typeof window<"u"&&!se&&(se=window.matchMedia("(pointer: coarse)"),Oe=window.matchMedia("(hover: none)"))},gt=()=>{try{const n=navigator;if(n.userAgentData&&typeof n.userAgentData.mobile=="boolean")return n.userAgentData.platform&&/ipad|tablet/i.test(n.userAgentData.platform)?L.Tablet:n.userAgentData.mobile?L.Mobile:L.Desktop;Et();const e=window.innerWidth,t=se?.matches??!1,r=Oe?.matches??!1,s="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&&s?L.Mobile:e>=768&&e<=1024||l||t&&r&&s?L.Tablet:L.Desktop}catch(n){return a("warn","Device detection failed, defaulting to desktop",{error:n}),L.Desktop}},Pe="background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",De="background: #9e9e9e; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;",ie=[/\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,}\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],Ve=500,ke=5e3,W=50,St=W*2,Ue=1,Tt=1e3,pt=10,He=5e3,_t=6e4,It={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},oe={LCP:2500,FCP:1800,CLS:.1,INP:200,TTFB:800,LONG_TASK:50},xe={LCP:4e3,FCP:3e3,CLS:.25,INP:500,TTFB:1800,LONG_TASK:50},G="needs-improvement",ae=(n=G)=>{switch(n){case"all":return{LCP:0,FCP:0,CLS:0,INP:0,TTFB:0,LONG_TASK:0};case"needs-improvement":return oe;case"poor":return xe;default:return oe}},vt=1e3,wt=50,yt="2.0.2",At=()=>{if(typeof window>"u"||typeof document>"u")return!1;try{const n=new URLSearchParams(window.location.search),e=n.get(ye),t=sessionStorage.getItem(H);let r=null;if(e===Ae?(r=!0,sessionStorage.setItem(H,"true"),a("info","QA Mode ACTIVE",{showToClient:!0,style:Pe})):e===Me&&(r=!1,sessionStorage.setItem(H,"false"),a("info","QA Mode DISABLED",{showToClient:!0,style:De})),e===Ae||e===Me)try{n.delete(ye);const s=n.toString(),i=window.location.pathname+(s?"?"+s:"")+window.location.hash;window.history.replaceState({},"",i)}catch{}return r??t==="true"}catch{return!1}},Mt=n=>{if(!(typeof window>"u"||typeof document>"u"))try{n?(sessionStorage.setItem(H,"true"),a("info","QA Mode ENABLED",{showToClient:!0,style:Pe})):(sessionStorage.setItem(H,"false"),a("info","QA Mode DISABLED",{showToClient:!0,style:De}))}catch{a("warn","Cannot set QA mode: sessionStorage unavailable")}},Fe=()=>{const n=new URLSearchParams(window.location.search),e={};return it.forEach(r=>{const s=n.get(r);if(s){const i=r.split("utm_")[1];e[i]=s}}),Object.keys(e).length?e:void 0},Lt=()=>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 X=0,Q=0;const bt=()=>{let n=Date.now();n<Q&&(n=Q),n===Q?X=(X+1)%1e3:X=0,Q=n;const e=X.toString().padStart(3,"0");let t="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const r=crypto.getRandomValues(new Uint8Array(3));r&&(t=Array.from(r,s=>s.toString(16).padStart(2,"0")).join(""))}}catch{}return t||(t=Math.floor(Math.random()*16777215).toString(16).padStart(6,"0")),`${n}-${e}-${t}`},$e=(n,e=!1)=>{try{const t=new URL(n),r=t.protocol==="https:",s=t.protocol==="http:";return r||e&&s}catch{return!1}},Rt=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 not supported on localhost or IP addresses. Use custom backend integration instead.");const r=t.split(".");if(!r||!Array.isArray(r)||r.length===0||r.length===1&&r[0]==="")throw new Error("Invalid hostname structure");if(r.length===1)throw new Error("Single-part domain not supported for SaaS integration");let s;if(r.length===2?s=r.join("."):s=r.slice(-2).join("."),!s||s.split(".").length<2)throw new Error("Invalid domain structure for SaaS");const i=`https://${n}.${s}/collect`;if(!$e(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)}`)}},Ct=n=>{const e={};n.integrations?.tracelog?.projectId&&(e.saas=Rt(n.integrations.tracelog.projectId));const t=n.integrations?.custom?.collectApiUrl;if(t){const r=n.integrations?.custom?.allowHttp??!1;if(!$e(t,r))throw new Error("Invalid custom API URL");e.custom=t}return e},le=(n,e=[])=>{if(!n||typeof n!="string")return a("warn","Invalid URL provided to normalizeUrl",{data:{url:String(n)}}),n||"";try{const t=new URL(n),r=t.searchParams,s=[...new Set([...ot,...e])];let i=!1;const o=[];return s.forEach(c=>{r.has(c)&&(r.delete(c),i=!0,o.push(c))}),!i&&n.includes("?")?n:(t.search=r.toString(),t.toString())}catch(t){const r=n&&typeof n=="string"?n.slice(0,100):String(n);return a("warn","URL normalization failed, returning original",{error:t,data:{url:r}}),n}},Be=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 s of at){const i=e;e=e.replace(s,""),i!==e&&t++}return t>0&&a("warn","XSS patterns detected and removed",{data:{patternMatches:t,originalValue:n.slice(0,100)}}),e=e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#x27;").replaceAll("/","&#x2F;"),e.trim()},ce=(n,e=0)=>{if(e>3||n==null)return null;if(typeof n=="string")return Be(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(Array.isArray(n))return n.slice(0,100).map(s=>ce(s,e+1)).filter(s=>s!==null);if(typeof n=="object"){const t={},s=Object.entries(n).slice(0,20);for(const[i,o]of s){const l=Be(i);if(l){const c=ce(o,e+1);c!==null&&(t[l]=c)}}return t}return null},Nt=n=>{if(typeof n!="object"||n===null)return{};try{const e=ce(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=n=>{if(n!==void 0&&(n===null||typeof n!="object"))throw new f("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 Ne(E.INVALID_SESSION_TIMEOUT,"config");if(n.globalMetadata!==void 0&&(typeof n.globalMetadata!="object"||n.globalMetadata===null))throw new f(E.INVALID_GLOBAL_METADATA,"config");if(n.integrations&&Dt(n.integrations),n.sensitiveQueryParams!==void 0){if(!Array.isArray(n.sensitiveQueryParams))throw new f(E.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of n.sensitiveQueryParams)if(typeof e!="string")throw new f("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 re(E.INVALID_ERROR_SAMPLING_RATE,"config");if(n.samplingRate!==void 0&&(typeof n.samplingRate!="number"||n.samplingRate<0||n.samplingRate>1))throw new re(E.INVALID_SAMPLING_RATE,"config");if(n.primaryScrollSelector!==void 0){if(typeof n.primaryScrollSelector!="string"||!n.primaryScrollSelector.trim())throw new f(E.INVALID_PRIMARY_SCROLL_SELECTOR,"config");if(n.primaryScrollSelector!=="window")try{document.querySelector(n.primaryScrollSelector)}catch{throw new f(`${E.INVALID_PRIMARY_SCROLL_SELECTOR_SYNTAX}: "${n.primaryScrollSelector}"`,"config")}}if(n.pageViewThrottleMs!==void 0&&(typeof n.pageViewThrottleMs!="number"||n.pageViewThrottleMs<0))throw new f(E.INVALID_PAGE_VIEW_THROTTLE,"config");if(n.clickThrottleMs!==void 0&&(typeof n.clickThrottleMs!="number"||n.clickThrottleMs<0))throw new f(E.INVALID_CLICK_THROTTLE,"config");if(n.maxSameEventPerMinute!==void 0&&(typeof n.maxSameEventPerMinute!="number"||n.maxSameEventPerMinute<=0))throw new f(E.INVALID_MAX_SAME_EVENT_PER_MINUTE,"config");if(n.viewport!==void 0&&Pt(n.viewport),n.webVitalsMode!==void 0){if(typeof n.webVitalsMode!="string")throw new f(`Invalid webVitalsMode type: ${typeof n.webVitalsMode}. Must be a string`,"config");const e=["all","needs-improvement","poor"];if(!e.includes(n.webVitalsMode))throw new f(`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 f("webVitalsThresholds must be an object","config");const e=["LCP","FCP","CLS","INP","TTFB","LONG_TASK"];for(const[t,r]of Object.entries(n.webVitalsThresholds)){if(!e.includes(t))throw new f(`Invalid Web Vitals threshold key: "${t}". Must be one of: ${e.join(", ")}`,"config");if(typeof r!="number"||!Number.isFinite(r)||r<0)throw new f(`Invalid Web Vitals threshold value for ${t}: ${r}. Must be a non-negative finite number`,"config")}}}},Pt=n=>{if(typeof n!="object"||n===null)throw new f(E.INVALID_VIEWPORT_CONFIG,"config");if(!n.elements||!Array.isArray(n.elements))throw new f(E.INVALID_VIEWPORT_ELEMENTS,"config");if(n.elements.length===0)throw new f(E.INVALID_VIEWPORT_ELEMENTS,"config");const e=new Set;for(const t of n.elements){if(!t.selector||typeof t.selector!="string"||!t.selector.trim())throw new f(E.INVALID_VIEWPORT_ELEMENT,"config");const r=t.selector.trim();if(e.has(r))throw new f(`Duplicate viewport selector found: "${r}". Each selector should appear only once.`,"config");if(e.add(r),t.id!==void 0&&(typeof t.id!="string"||!t.id.trim()))throw new f(E.INVALID_VIEWPORT_ELEMENT_ID,"config");if(t.name!==void 0&&(typeof t.name!="string"||!t.name.trim()))throw new f(E.INVALID_VIEWPORT_ELEMENT_NAME,"config")}if(n.threshold!==void 0&&(typeof n.threshold!="number"||n.threshold<0||n.threshold>1))throw new f(E.INVALID_VIEWPORT_THRESHOLD,"config");if(n.minDwellTime!==void 0&&(typeof n.minDwellTime!="number"||n.minDwellTime<0))throw new f(E.INVALID_VIEWPORT_MIN_DWELL_TIME,"config");if(n.cooldownPeriod!==void 0&&(typeof n.cooldownPeriod!="number"||n.cooldownPeriod<0))throw new f(E.INVALID_VIEWPORT_COOLDOWN_PERIOD,"config");if(n.maxTrackedElements!==void 0&&(typeof n.maxTrackedElements!="number"||n.maxTrackedElements<=0))throw new f(E.INVALID_VIEWPORT_MAX_TRACKED_ELEMENTS,"config")},Dt=n=>{if(n){if(n.tracelog&&(!n.tracelog.projectId||typeof n.tracelog.projectId!="string"||n.tracelog.projectId.trim()===""))throw new V(E.INVALID_TRACELOG_PROJECT_ID,"config");if(n.custom){if(!n.custom.collectApiUrl||typeof n.custom.collectApiUrl!="string"||n.custom.collectApiUrl.trim()==="")throw new V(E.INVALID_CUSTOM_API_URL,"config");if(n.custom.allowHttp!==void 0&&typeof n.custom.allowHttp!="boolean")throw new V("allowHttp must be a boolean","config");const e=n.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new V('Custom API URL must start with "http://" or "https://"',"config");if(!(n.custom.allowHttp??!1)&&e.startsWith("http://"))throw new V("Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)","config")}}},Vt=n=>{Ot(n);const e={...n??{},sessionTimeout:n?.sessionTimeout??9e5,globalMetadata:n?.globalMetadata??{},sensitiveQueryParams:n?.sensitiveQueryParams??[],errorSampling:n?.errorSampling??Ue,samplingRate:n?.samplingRate??1,pageViewThrottleMs:n?.pageViewThrottleMs??1e3,clickThrottleMs:n?.clickThrottleMs??300,maxSameEventPerMinute:n?.maxSameEventPerMinute??60};return e.integrations?.custom&&(e.integrations.custom={...e.integrations.custom,allowHttp:e.integrations.custom.allowHttp??!1}),e.viewport&&(e.viewport={...e.viewport,threshold:e.viewport.threshold??.5,minDwellTime:e.viewport.minDwellTime??2e3,cooldownPeriod:e.viewport.cooldownPeriod??6e4,maxTrackedElements:e.viewport.maxTrackedElements??100}),e},kt=n=>{if(typeof n=="string")return!0;if(typeof n=="object"&&n!==null&&!Array.isArray(n)){const e=Object.entries(n);if(e.length>20)return!1;for(const[,t]of e){if(t==null)continue;const r=typeof t;if(r!=="string"&&r!=="number"&&r!=="boolean")return!1}return!0}return!1},We=(n,e=0)=>{if(typeof n!="object"||n===null||e>1)return!1;for(const t of Object.values(n)){if(t==null)continue;const r=typeof t;if(!(r==="string"||r==="number"||r==="boolean")){if(Array.isArray(t)){if(t.length===0)continue;if(typeof t[0]=="string"){if(!t.every(o=>typeof o=="string"))return!1}else if(!t.every(o=>kt(o)))return!1;continue}if(r==="object"&&e===0){if(!We(t,e+1))return!1;continue}return!1}}return!0},Ut=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},Ge=(n,e,t)=>{const r=Nt(e),s=t&&t==="customEvent"?`${t} "${n}" metadata error`:`${n} metadata error`;if(!We(r))return{valid:!1,error:`${s}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(r)}catch{return{valid:!1,error:`${s}: object contains circular references or cannot be serialized.`}}if(i.length>8192)return{valid:!1,error:`${s}: object is too large (max ${8192/1024} KB).`};if(Object.keys(r).length>10)return{valid:!1,error:`${s}: object has too many keys (max 10 keys).`};for(const[l,c]of Object.entries(r)){if(Array.isArray(c)){if(c.length>10)return{valid:!1,error:`${s}: array property "${l}" is too large (max 10 items).`};for(const d of c)if(typeof d=="string"&&d.length>500)return{valid:!1,error:`${s}: array property "${l}" contains strings that are too long (max 500 characters).`}}if(typeof c=="string"&&c.length>1e3)return{valid:!1,error:`${s}: property "${l}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:r}},Xe=(n,e,t)=>{if(Array.isArray(e)){const r=[],s=t&&t==="customEvent"?`${t} "${n}" metadata error`:`${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:`${s}: array item at index ${i} must be an object.`};const l=Ge(n,o,t);if(!l.valid)return{valid:!1,error:`${s}: array item at index ${i} is invalid: ${l.error}`};l.sanitizedMetadata&&r.push(l.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:r}}return Ge(n,e,t)},Ht=(n,e)=>{const t=Ut(n);if(!t.valid)return a("error","Event name validation failed",{showToClient:!0,data:{eventName:n,error:t.error}}),t;if(!e)return{valid:!0};const r=Xe(n,e,"customEvent");return r.valid||a("error","Event metadata validation failed",{showToClient:!0,data:{eventName:n,error:r.error}}),r};class xt{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const r=this.listeners.get(e);if(r){const s=r.indexOf(t);s>-1&&r.splice(s,1)}}emit(e,t){const r=this.listeners.get(e);r&&r.forEach(s=>{s(t)})}removeAllListeners(){this.listeners.clear()}}function Qe(n,e,t){try{const r=e(n);return r===null?null:typeof r=="object"&&r!==null&&"type"in r?r:(a("warn",`beforeSend transformer returned invalid data, using original [${t}]`),n)}catch(r){return a("error",`beforeSend transformer threw error, using original event [${t}]`,{error:r}),n}}function Ft(n,e,t){return n.map(r=>Qe(r,e,t)).filter(r=>r!==null)}function ze(n,e,t){try{const r=e(n);return r===null?(a("debug",`Batch filtered by beforeBatch transformer [${t}]`,{data:{eventCount:n.events.length}}),null):typeof r=="object"&&r!==null&&Array.isArray(r.events)?r:(a("warn",`beforeBatch transformer returned invalid data, using original [${t}]`,{data:{eventCount:n.events.length}}),n)}catch(r){return a("error",`beforeBatch transformer threw error, using original batch [${t}]`,{error:r,data:{eventCount:n.events.length}}),n}}const ue={};class p{get(e){return ue[e]}set(e,t){ue[e]=t}getState(){return{...ue}}}class je extends p{storeManager;integrationId;apiUrl;transformers;lastPermanentErrorLog=null;recoveryInProgress=!1;lastMetadataTimestamp=0;pendingControllers=new Set;constructor(e,t,r,s={}){if(super(),t&&!r||!t&&r)throw new Error("SenderManager: integrationId and apiUrl must either both be provided or both be undefined");this.storeManager=e,this.integrationId=t,this.apiUrl=r,this.transformers=s}getIntegrationId(){return this.integrationId}getQueueStorageKey(){const e=this.get("userId")||"anonymous",t=lt(e);return this.integrationId?`${t}:${this.integrationId}`:t}sendEventsQueueSync(e){return this.shouldSkipSend()?!0:this.apiUrl?.includes(O.Fail)?(a("warn",`Fail mode: simulating network failure (sync)${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:e.events.length}}),!1):this.apiUrl?.includes(O.Localhost)?(a("debug",`Success mode: simulating successful send (sync)${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:e.events.length}}),!0):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){try{const r=await this.send(e);return r?(this.clearPersistedEvents(),t?.onSuccess?.(e.events.length,e.events,e)):(this.persistEvents(e),t?.onFailure?.()),r}catch(r){return r instanceof R?(this.logPermanentError("Permanent error, not retrying",r),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(e),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){if(this.recoveryInProgress){a("debug","Recovery already in progress, skipping duplicate attempt");return}this.recoveryInProgress=!0;try{const t=this.getPersistedData();if(!t||!this.isDataRecent(t)||t.events.length===0){this.clearPersistedEvents();return}const r=this.createRecoveryBody(t);await this.send(r)?(this.clearPersistedEvents(),e?.onSuccess?.(t.events.length,t.events,r)):e?.onFailure?.()}catch(t){if(t instanceof R){this.logPermanentError("Permanent error during recovery, clearing persisted events",t),this.clearPersistedEvents(),e?.onFailure?.();return}a("error","Failed to recover persisted events",{error:t})}finally{this.recoveryInProgress=!1}}stop(){}applyBeforeSendTransformer(e){if(this.integrationId==="saas")return e;const t=this.transformers.beforeSend;if(!t)return e;const r=Ft(e.events,t,this.integrationId||"SenderManager");return r.length===0?null:{...e,events:r}}applyBeforeBatchTransformer(e){if(this.integrationId==="saas")return e;const t=this.transformers.beforeBatch;return t?ze(e,t,this.integrationId||"SenderManager"):e}async backoffDelay(e){const t=100*Math.pow(2,e),r=Math.random()*100,s=t+r;return new Promise(i=>setTimeout(i,s))}async send(e){if(this.shouldSkipSend())return this.simulateSuccessfulSend();const t=this.applyBeforeSendTransformer(e);if(!t)return!0;const r=this.applyBeforeBatchTransformer(t);if(!r)return!0;if(this.apiUrl?.includes(O.Fail))return a("warn",`Fail mode: simulating network failure${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:r.events.length}}),!1;if(this.apiUrl?.includes(O.Localhost))return a("debug",`Success mode: simulating successful send${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:r.events.length}}),!0;const{url:s,payload:i}=this.prepareRequest(r);for(let o=1;o<=3;o++)try{return(await this.sendWithTimeout(s,i)).ok?(o>1&&a("info",`Send succeeded after ${o-1} retry attempt(s)${this.integrationId?` [${this.integrationId}]`:""}`,{data:{events:r.events.length,attempt:o}}),!0):!1}catch(l){const c=o===3;if(l instanceof R)throw l;if(a(c?"error":"warn",`Send attempt ${o} failed${this.integrationId?` [${this.integrationId}]`:""}${c?" (all retries exhausted)":", will retry"}`,{error:l,data:{events:e.events.length,url:s.replace(/\/\/[^/]+/,"//[DOMAIN]"),attempt:o,maxAttempts:3}}),!c){await this.backoffDelay(o);continue}return!1}return!1}async sendWithTimeout(e,t){const r=new AbortController;this.pendingControllers.add(r);const s=setTimeout(()=>{r.abort()},15e3);try{const i=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:r.signal,headers:{"Content-Type":"application/json"}});if(!i.ok)throw i.status>=400&&i.status<500&&i.status!==408&&i.status!==429?new R(`HTTP ${i.status}: ${i.statusText}`,i.status):new Error(`HTTP ${i.status}: ${i.statusText}`);return i}finally{clearTimeout(s),this.pendingControllers.delete(r)}}sendQueueSyncInternal(e){const t=this.applyBeforeSendTransformer(e);if(!t)return!0;const r=this.applyBeforeBatchTransformer(t);if(!r)return!0;const{url:s,payload:i}=this.prepareRequest(r);if(i.length>65536)return a("warn",`Payload exceeds sendBeacon limit, persisting for recovery${this.integrationId?` [${this.integrationId}]`:""}`,{data:{size:i.length,limit:65536,events:r.events.length}}),this.persistEvents(r),!1;const o=new Blob([i],{type:"application/json"});if(!this.isSendBeaconAvailable())return a("warn",`sendBeacon not available, persisting events for recovery${this.integrationId?` [${this.integrationId}]`:""}`),this.persistEvents(r),!1;const l=navigator.sendBeacon(s,o);return l||(a("warn",`sendBeacon rejected request, persisting events for recovery${this.integrationId?` [${this.integrationId}]`:""}`),this.persistEvents(r)),l}prepareRequest(e){let t=Date.now();t<this.lastMetadataTimestamp&&(t=this.lastMetadataTimestamp),this.lastMetadataTimestamp=t;const r={...e,_metadata:{referer:typeof window<"u"?window.location.href:void 0,timestamp:t,client_version:yt}};return{url:this.apiUrl||"",payload:JSON.stringify(r)}}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){a("warn",`Failed to parse persisted data${this.integrationId?` [${this.integrationId}]`:""}`,{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,...r}=e;return r}persistEvents(e){try{const t=this.getPersistedData();if(t&&t.timestamp){const i=Date.now()-t.timestamp;if(i<1e3)return a("debug",`Skipping persistence, another tab recently persisted events${this.integrationId?` [${this.integrationId}]`:""}`,{data:{timeSinceExisting:i}}),!0}const r={...e,timestamp:Date.now()},s=this.getQueueStorageKey();return this.storeManager.setItem(s,JSON.stringify(r)),!!this.storeManager.getItem(s)}catch(t){return a("warn",`Failed to persist events${this.integrationId?` [${this.integrationId}]`:""}`,{error:t}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){a("warn",`Failed to clear persisted events${this.integrationId?` [${this.integrationId}]`:""}`,{error:e})}}shouldSkipSend(){return!this.apiUrl}async simulateSuccessfulSend(){const e=Math.random()*400+100;return await new Promise(t=>setTimeout(t,e)),!0}isSendBeaconAvailable(){return typeof navigator<"u"&&typeof navigator.sendBeacon=="function"}logPermanentError(e,t){const r=Date.now();(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.statusCode!==t.statusCode||r-this.lastPermanentErrorLog.timestamp>=_t)&&(a("error",`${e}${this.integrationId?` [${this.integrationId}]`:""}`,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:r})}}class $t extends p{bootTime;bootTimestamp;hasPerformanceNow;lastClockSkewCheck=0;detectedSkew=0;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(),a("debug","TimeManager initialized with monotonic clock",{data:{bootTime:this.bootTime.toFixed(3),bootTimestamp:this.bootTimestamp}})):(this.bootTime=0,this.bootTimestamp=Date.now(),a("warn","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)}getClockSkew(){if(!this.hasPerformanceNow)return 0;const e=Date.now();if(e-this.lastClockSkewCheck<5e3)return this.detectedSkew;this.lastClockSkewCheck=e;const t=this.now(),r=Date.now();return this.detectedSkew=r-t,Math.abs(this.detectedSkew)>3e4&&a("warn","Significant clock skew detected",{data:{skewMs:this.detectedSkew,skewMinutes:(this.detectedSkew/1e3/60).toFixed(2),monotonicTime:new Date(t).toISOString(),systemTime:new Date(r).toISOString()}}),this.detectedSkew}validateTimestamp(e){const r=this.now(),s=e-r;return s>12e4?{valid:!1,error:`Timestamp is ${(s/1e3/60).toFixed(2)} minutes in the future (max allowed: 2 minutes)`}:{valid:!0}}getBootInfo(){return{bootTime:this.bootTime,bootTimestamp:this.bootTimestamp,hasPerformanceNow:this.hasPerformanceNow,clockSkew:this.getClockSkew()}}}class Bt extends p{dataSenders;emitter;transformers;timeManager;recentEventFingerprints=new Map;perEventRateLimits=new Map;eventsQueue=[];pendingEventsBuffer=[];sendIntervalId=null;rateLimitCounter=0;rateLimitWindowStart=0;lastSessionId=null;sessionEventCounts={total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0};saveSessionCountsDebounced=null;constructor(e,t=null,r={}){super(),this.emitter=t,this.transformers=r,this.timeManager=new $t,this.dataSenders=[];const s=this.get("collectApiUrls");s?.saas&&this.dataSenders.push(new je(e,"saas",s.saas,r)),s?.custom&&this.dataSenders.push(new je(e,"custom",s.custom,r)),this.saveSessionCountsDebounced=this.debounce(i=>{this.saveSessionCounts(i)},500),this.cleanupExpiredSessionCounts()}async recoverPersistedEvents(){const e=this.dataSenders.map(async t=>t.recoverPersistedEvents({onSuccess:(r,s,i)=>{if(s&&s.length>0){const o=s.map(l=>l.id);this.removeProcessedEvents(o),i&&this.emitEventsQueue(i)}},onFailure:()=>{a("warn","Failed to recover persisted events")}}));await Promise.allSettled(e)}track({type:e,page_url:t,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,viewport_data:d}){if(!e){a("error","Event type is required - event will be ignored");return}const g=this.get("sessionId");if(!g){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),a("warn","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,viewport_data:d});return}this.lastSessionId!==g&&(this.lastSessionId=g,this.sessionEventCounts=this.loadSessionCounts(g));const S=e===u.SESSION_START;if(S&&a("debug","Processing SESSION_START event",{data:{sessionId:g}}),!S&&!this.checkRateLimit())return;const T=e;if(!S){if(this.sessionEventCounts.total>=1e3){a("warn","Session event limit reached",{data:{type:T,total:this.sessionEventCounts.total,limit:1e3}});return}const v=this.getTypeLimitForEvent(T);if(v){const ve=this.sessionEventCounts[T];if(ve!==void 0&&ve>=v){a("warn","Session event type limit reached",{data:{type:T,count:ve,limit:v}});return}}}if(T===u.CUSTOM&&o?.name){const v=this.get("config")?.maxSameEventPerMinute??60;if(!this.checkPerEventRateLimit(o.name,v))return}const Z=T===u.SESSION_START,ee=t||this.get("pageUrl"),te=this.buildEventPayload({type:T,page_url:ee,from_page_url:r,scroll_data:s,click_data:i,custom_event:o,web_vitals:l,error_data:c,viewport_data:d});if(te&&!(!S&&!this.shouldSample())){if(Z){const v=this.get("sessionId");if(!v){a("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){a("warn","Duplicate session_start detected",{data:{sessionId:v}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(te)){if(this.get("mode")===F.QA&&T===u.CUSTOM&&o){a("info",`Custom Event: ${o.name}`,{showToClient:!0,data:{name:o.name,...o.metadata&&{metadata:o.metadata}}}),this.emitEvent(te);return}if(this.addToQueue(te),!S){this.sessionEventCounts.total++,this.sessionEventCounts[T]!==void 0&&this.sessionEventCounts[T]++;const v=this.get("sessionId");v&&this.saveSessionCountsDebounced&&this.saveSessionCountsDebounced(v)}}}}stop(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null);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,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.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]}async flushQueue(){await this.flushImmediately()}clearQueue(){this.eventsQueue=[]}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){a("warn","Cannot flush pending events: session not initialized - keeping in buffer",{data:{bufferedEventCount:this.pendingEventsBuffer.length}});return}const t=[...this.pendingEventsBuffer];this.pendingEventsBuffer=[],t.forEach(r=>{this.track(r)})}clearSendInterval(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null)}isSuccessfulResult(e){return e.status==="fulfilled"&&e.value===!0}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);const t=this.buildEventsPayload(),r=[...this.eventsQueue],s=r.map(i=>i.id);if(this.dataSenders.length===0)return this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t),e?!0:Promise.resolve(!0);if(e){const o=this.dataSenders.map(l=>l.sendEventsQueueSync(t)).some(l=>l);return o?(this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t)):(this.clearSendInterval(),a("warn","Sync flush complete failure, events kept in queue for retry",{data:{eventCount:s.length}})),o}else{const i=this.dataSenders.map(async o=>o.sendEventsQueue(t,{onSuccess:()=>{},onFailure:()=>{}}));return Promise.allSettled(i).then(o=>{const l=o.some(c=>this.isSuccessfulResult(c));return l?(this.removeProcessedEvents(s),this.clearSendInterval(),this.emitEventsQueue(t)):a("warn","Async flush complete failure, events kept in queue for retry",{data:{eventCount:r.length}}),l})}}async sendEventsQueue(){if(!this.get("sessionId")||this.eventsQueue.length===0)return;const e=this.buildEventsPayload();if(this.dataSenders.length===0){this.emitEventsQueue(e);return}const t=[...this.eventsQueue],r=t.map(l=>l.id),s=this.dataSenders.map(async l=>l.sendEventsQueue(e,{onSuccess:()=>{},onFailure:()=>{}})),i=await Promise.allSettled(s);if(i.some(l=>this.isSuccessfulResult(l))){this.removeProcessedEvents(r),this.emitEventsQueue(e);const l=i.filter(c=>!this.isSuccessfulResult(c)).length;l>0&&a("warn","Periodic send completed with some failures, removed from queue and persisted per-integration",{data:{eventCount:t.length,failedCount:l}})}else a("warn","Periodic send complete failure, events kept in queue for retry",{data:{eventCount:t.length}});this.eventsQueue.length===0&&this.clearSendInterval()}buildEventsPayload(){const e=new Map,t=[];for(const c of this.eventsQueue){const d=this.createEventSignature(c);e.has(d)||t.push(d),e.set(d,c)}const r=t.map(c=>e.get(c)).filter(c=>!!c).sort((c,d)=>c.type===u.SESSION_START&&d.type!==u.SESSION_START?-1:d.type===u.SESSION_START&&c.type!==u.SESSION_START?1:c.timestamp-d.timestamp);let s={user_id:this.get("userId"),session_id:this.get("sessionId"),device:this.get("device"),events:r,...this.get("config")?.globalMetadata&&{global_metadata:this.get("config")?.globalMetadata}};const i=this.get("collectApiUrls"),o=!!(i?.custom||i?.saas),l=this.transformers.beforeBatch;if(!o&&l){const c=ze(s,l,"EventManager");c!==null&&(s=c)}return s}buildEventPayload(e){const t=e.type===u.SESSION_START,r=e.page_url??this.get("pageUrl"),s=this.timeManager.now(),i=this.timeManager.validateTimestamp(s);i.valid||a("warn","Event timestamp validation failed",{data:{type:e.type,error:i.error}});let o={id:bt(),type:e.type,page_url:r,timestamp:s,...t&&{referrer:document.referrer||"Direct"},...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.viewport_data&&{viewport_data:e.viewport_data},...t&&Fe()&&{utm:Fe()}};const l=this.get("collectApiUrls"),c=!!l?.custom,d=!!l?.saas,g=c||d,S=c&&d,T=this.transformers.beforeSend;if(T&&(!g||c&&!S)){const ee=Qe(o,T,"EventManager");if(ee===null)return null;o=ee}return o}isDuplicateEvent(e){const t=Date.now(),r=this.createEventFingerprint(e),s=this.recentEventFingerprints.get(r);return s&&t-s<1e3?(this.recentEventFingerprints.set(r,t),!0):(this.recentEventFingerprints.set(r,t),this.recentEventFingerprints.size>1500&&this.pruneOldFingerprints(),this.recentEventFingerprints.size>3e3&&(this.recentEventFingerprints.clear(),this.recentEventFingerprints.set(r,t),a("warn","Event fingerprint cache exceeded hard limit, cleared",{data:{hardLimit:3e3}})),!1)}pruneOldFingerprints(){const e=Date.now(),t=1e3*10;for(const[r,s]of this.recentEventFingerprints.entries())e-s>t&&this.recentEventFingerprints.delete(r);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 r=Math.round((e.click_data.x||0)/10)*10,s=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${r}_${s}`}return e.scroll_data&&(t+=`_scroll_${e.scroll_data.depth}_${e.scroll_data.direction}`),e.custom_event&&(t+=`_custom_${e.custom_event.name}`),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)}addToQueue(e){if(this.emitEvent(e),this.eventsQueue.push(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(s=>s.type!==u.SESSION_START),r=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:r?.type,wasCritical:r?.type===u.SESSION_START}})}this.sendIntervalId||this.startSendInterval(),this.eventsQueue.length>=50&&this.sendEventsQueue()}startSendInterval(){this.sendIntervalId=window.setInterval(()=>{this.eventsQueue.length>0&&this.sendEventsQueue()},1e4)}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 r=Date.now(),i=(this.perEventRateLimits.get(e)??[]).filter(o=>r-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(r),this.perEventRateLimits.set(e,i),!0)}getTypeLimitForEvent(e){return{[u.CLICK]:500,[u.PAGE_VIEW]:100,[u.CUSTOM]:500,[u.VIEWPORT_VISIBLE]:200,[u.SCROLL]:120}[e]??null}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(r=>!t.has(r.id))}emitEvent(e){this.emitter&&this.emitter.emit(B.EVENT,e)}emitEventsQueue(e){this.emitter&&this.emitter.emit(B.QUEUE,e)}debounce(e,t){let r=null;return((...s)=>{r!==null&&clearTimeout(r),r=setTimeout(()=>{e(...s),r=null},t)})}getInitialCounts(){return{total:0,[u.CLICK]:0,[u.PAGE_VIEW]:0,[u.CUSTOM]:0,[u.VIEWPORT_VISIBLE]:0,[u.SCROLL]:0}}loadSessionCounts(e){if(typeof window>"u"||typeof localStorage>"u")return this.getInitialCounts();const t=this.get("userId")||"anonymous",r=Le(t,e);try{const s=localStorage.getItem(r);if(!s)return this.getInitialCounts();const i=JSON.parse(s);return i._timestamp&&Date.now()-i._timestamp>be?(a("debug","Session counts expired, clearing",{data:{sessionId:e,age:Date.now()-i._timestamp}}),localStorage.removeItem(r),this.getInitialCounts()):typeof i.total=="number"&&typeof i[u.CLICK]=="number"&&typeof i[u.PAGE_VIEW]=="number"&&typeof i[u.CUSTOM]=="number"&&typeof i[u.VIEWPORT_VISIBLE]=="number"&&typeof i[u.SCROLL]=="number"?{total:i.total,[u.CLICK]:i[u.CLICK],[u.PAGE_VIEW]:i[u.PAGE_VIEW],[u.CUSTOM]:i[u.CUSTOM],[u.VIEWPORT_VISIBLE]:i[u.VIEWPORT_VISIBLE],[u.SCROLL]:i[u.SCROLL]}:(a("warn","Invalid session counts structure in localStorage, resetting",{data:{sessionId:e,parsed:i}}),localStorage.removeItem(r),a("debug","Session counts removed due to invalid/corrupted data",{data:{sessionId:e,parsed:i}}),this.getInitialCounts())}catch(s){return a("warn","Failed to load session counts from localStorage",{error:s,data:{sessionId:e}}),this.getInitialCounts()}}cleanupExpiredSessionCounts(){if(!(typeof window>"u"||typeof localStorage>"u"))try{const e=localStorage.getItem(Re);if(e){const i=Date.now()-parseInt(e,10);if(i<Ce){a("debug","Skipping session counts cleanup (throttled)",{data:{timeSinceLastCleanup:i,throttleMs:Ce}});return}}const t=this.get("userId")||"anonymous",r=`${_}:${t}:session_counts:`,s=[];for(let i=0;i<localStorage.length;i++){const o=localStorage.key(i);if(o?.startsWith(r))try{const l=localStorage.getItem(o);if(l){const c=JSON.parse(l);c._timestamp&&Date.now()-c._timestamp>be&&s.push(o)}}catch{}}s.forEach(i=>{localStorage.removeItem(i),a("debug","Cleaned up expired session counts",{data:{key:i}})}),s.length>0&&a("info",`Cleaned up ${s.length} expired session counts entries`),localStorage.setItem(Re,Date.now().toString())}catch(e){a("warn","Failed to cleanup expired session counts",{error:e})}}saveSessionCounts(e){const t=this.get("userId")||"anonymous",r=Le(t,e);try{const s={...this.sessionEventCounts,_timestamp:Date.now(),_version:1};localStorage.setItem(r,JSON.stringify(s))}catch(s){a("warn","Failed to persist session counts to localStorage",{error:s,data:{sessionId:e}})}}}class Wt{static getId(e){const t=e.getItem(we);if(t)return t;const r=Lt();return e.setItem(we,r),r}}const Gt=/^\d{13}-[a-z0-9]{9}$/;class Xt extends p{storageManager;eventManager;projectId;activityHandler=null;visibilityChangeHandler=null;sessionTimeoutId=null;broadcastChannel=null;isTracking=!1;constructor(e,t,r){super(),this.storageManager=e,this.eventManager=t,this.projectId=r}initCrossTabSync(){if(typeof BroadcastChannel>"u"){a("warn","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel(ut(e)),this.broadcastChannel.onmessage=t=>{const{action:r,sessionId:s,timestamp:i,projectId:o}=t.data??{};o===e&&(r==="session_start"&&s&&typeof i=="number"&&i>Date.now()-5e3?(this.set("sessionId",s),this.persistSession(s,i),this.isTracking&&this.setupSessionTimeout()):r&&r!=="session_start"&&a("debug","Ignored BroadcastChannel message with unknown action",{data:{action:r}}))}}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(!Gt.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()){this.saveStoredSession({id:e,lastActivity:t})}clearStoredSession(){const e=this.getSessionStorageKey();this.storageManager.removeItem(e)}loadStoredSession(){const e=this.getSessionStorageKey(),t=this.storageManager.getItem(e);if(!t)return null;try{const r=JSON.parse(t);return!r.id||typeof r.lastActivity!="number"?null:r}catch{return this.storageManager.removeItem(e),null}}saveStoredSession(e){const t=this.getSessionStorageKey();this.storageManager.setItem(t,JSON.stringify(e))}getSessionStorageKey(){return ct(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){a("warn","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId();a("debug","Session tracking initialized",{data:{sessionId:t,wasRecovered:!!e,willEmitSessionStart:!0}}),this.isTracking=!0;try{this.set("sessionId",t),this.persistSession(t),this.initCrossTabSync(),this.shareSession(t),a("debug","Emitting SESSION_START event",{data:{sessionId:t}}),this.eventManager.track({type:u.SESSION_START}),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}catch(r){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),r}}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.resetSessionState()},e)}resetSessionTimeout(){this.setupSessionTimeout();const e=this.get("sessionId");e&&this.persistSession(e)}clearSessionTimeout(){this.sessionTimeoutId&&(clearTimeout(this.sessionTimeoutId),this.sessionTimeoutId=null)}setupActivityListeners(){this.activityHandler=()=>{this.resetSessionTimeout()},document.addEventListener("click",this.activityHandler,{passive:!0}),document.addEventListener("keydown",this.activityHandler,{passive:!0}),document.addEventListener("scroll",this.activityHandler,{passive:!0})}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=()=>{document.hidden?this.clearSessionTimeout():this.get("sessionId")&&this.setupSessionTimeout()},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null)}resetSessionState(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.isTracking=!1}stopTracking(){this.resetSessionState()}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.isTracking=!1,this.set("hasStartSession",!1)}}class Qt extends p{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("warn","Cannot start tracking on destroyed handler");return}const t=this.get("config")?.integrations?.tracelog?.projectId??"custom";try{this.sessionManager=new Xt(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(r){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw a("error","Failed to start session tracking",{error:r}),r}}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 zt extends p{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]=(...r)=>{t.apply(window.history,r),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=le(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;const r=Date.now(),s=this.get("config").pageViewThrottleMs??1e3;if(r-this.lastPageViewTime<s)return;this.lastPageViewTime=r,this.onTrack();const i=this.get("pageUrl");this.set("pageUrl",t);const o=this.extractPageViewData();this.eventManager.track({type:u.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:i,...o&&{page_view:o}})};trackInitialPageView(){const e=le(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.lastPageViewTime=Date.now(),this.eventManager.track({type:u.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{pathname:e,search:t,hash:r}=window.location,{referrer:s}=document,{title:i}=document;return!s&&!i&&!e&&!t&&!r?void 0:{...s&&{referrer:s},...i&&{title:i},...e&&{pathname:e},...t&&{search:t},...r&&{hash:r}}}}class jt extends p{eventManager;lastClickTimes=new Map;clickHandler;lastPruneTime=0;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,r=t.target,s=typeof HTMLElement<"u"&&r instanceof HTMLElement?r:typeof HTMLElement<"u"&&r instanceof Node&&r.parentElement instanceof HTMLElement?r.parentElement:null;if(!s){a("warn","Click target not found or not an element");return}if(this.shouldIgnoreElement(s))return;const i=this.get("config")?.clickThrottleMs??300;if(i>0&&!this.checkClickThrottle(s,i))return;const o=this.findTrackingElement(s),l=this.getRelevantClickElement(s),c=this.calculateClickCoordinates(t,s);if(o){const g=this.extractTrackingData(o);if(g){const S=this.createCustomEventData(g);this.eventManager.track({type:u.CUSTOM,custom_event:{name:S.name,...S.value&&{metadata:{value:S.value}}}})}}const d=this.generateClickData(s,l,c);this.eventManager.track({type:u.CLICK,click_data:d})},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(`${w}-ignore`)?!0:e.closest(`[${w}-ignore]`)!==null}checkClickThrottle(e,t){const r=this.getElementSignature(e),s=Date.now();this.pruneThrottleCache(s);const i=this.lastClickTimes.get(r);return i!==void 0&&s-i<t?(a("debug","ClickHandler: Click suppressed by throttle",{data:{signature:r,throttleRemaining:t-(s-i)}}),!1):(this.lastClickTimes.set(r,s),!0)}pruneThrottleCache(e){if(e-this.lastPruneTime<3e4)return;this.lastPruneTime=e;const t=e-3e5;for(const[r,s]of this.lastClickTimes.entries())s<t&&this.lastClickTimes.delete(r);if(this.lastClickTimes.size>1e3){const r=Array.from(this.lastClickTimes.entries()).sort((o,l)=>o[1]-l[1]),s=this.lastClickTimes.size-1e3,i=r.slice(0,s);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 r=e.getAttribute(`${w}-name`);return r?`[${w}-name="${r}"]`:this.getElementPath(e)}getElementPath(e){const t=[];let r=e;for(;r&&r!==document.body;){let s=r.tagName.toLowerCase();if(r.className){const i=r.className.split(" ")[0];i&&(s+=`.${i}`)}t.unshift(s),r=r.parentElement}return t.join(">")||"unknown"}findTrackingElement(e){return e.hasAttribute(`${w}-name`)?e:e.closest(`[${w}-name]`)}getRelevantClickElement(e){for(const t of st)try{if(e.matches(t))return e;const r=e.closest(t);if(r)return r}catch(r){a("warn","Invalid selector in element search",{error:r,data:{selector:t}});continue}return e}clamp(e){return Math.max(0,Math.min(1,Number(e.toFixed(3))))}calculateClickCoordinates(e,t){const r=t.getBoundingClientRect(),s=e.clientX,i=e.clientY,o=r.width>0?this.clamp((s-r.left)/r.width):0,l=r.height>0?this.clamp((i-r.top)/r.height):0;return{x:s,y:i,relativeX:o,relativeY:l}}extractTrackingData(e){const t=e.getAttribute(`${w}-name`),r=e.getAttribute(`${w}-value`);if(t)return{element:e,name:t,...r&&{value:r}}}generateClickData(e,t,r){const{x:s,y:i,relativeX:o,relativeY:l}=r,c=this.getRelevantText(e,t),d=this.extractElementAttributes(t);return{x:s,y:i,relativeX:o,relativeY:l,tag:t.tagName.toLowerCase(),...t.id&&{id:t.id},...t.className&&{class:t.className},...c&&{text:c},...d.href&&{href:d.href},...d.title&&{title:d.title},...d.alt&&{alt:d.alt},...d.role&&{role:d.role},...d["aria-label"]&&{ariaLabel:d["aria-label"]},...Object.keys(d).length>0&&{dataAttributes:d}}}sanitizeText(e){let t=e;for(const r of ie){const s=new RegExp(r.source,r.flags);t=t.replace(s,"[REDACTED]")}return t}getRelevantText(e,t){const r=e.textContent?.trim()??"",s=t.textContent?.trim()??"";if(!r&&!s)return"";let i="";return r&&r.length<=255?i=r:s.length<=255?i=s:i=s.slice(0,252)+"...",this.sanitizeText(i)}extractElementAttributes(e){const t=["id","class","data-testid","aria-label","title","href","type","name","alt","role"],r={};for(const s of t){const i=e.getAttribute(s);i&&(r[s]=i)}return r}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class Kt extends p{eventManager;containers=[];limitWarningLogged=!1;minDepthChange=5;minIntervalMs=500;maxEventsPerSession=120;containerDiscoveryTimeoutId=null;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.applyConfigOverrides(),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 r of t){const s=this.getElementSelector(r);this.setupScrollContainer(r,s)}this.applyPrimaryScrollSelectorIfConfigured();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"),this.applyPrimaryScrollSelectorIfConfigured()}applyPrimaryScrollSelectorIfConfigured(){const e=this.get("config");e?.primaryScrollSelector&&this.applyPrimaryScrollSelector(e.primaryScrollSelector)}findScrollableElements(){if(!document.body)return[];const e=[],t=document.createTreeWalker(document.body,NodeFilter.SHOW_ELEMENT,{acceptNode:s=>{const i=s;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 r;for(;(r=t.nextNode())&&e.length<10;){const s=r;this.isElementScrollable(s)&&e.push(s)}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 r=t.className.split(" ").filter(s=>s.trim())[0];if(r)return`.${r}`}return t.tagName.toLowerCase()}determineIfPrimary(e){return this.isWindowScrollable()?e===window:this.containers.length===0}setupScrollContainer(e,t){if(this.containers.some(d=>d.element===e)||e!==window&&!this.isElementScrollable(e))return;const s=this.getScrollTop(e),i=this.calculateScrollDepth(s,this.getScrollHeight(e),this.getViewportHeight(e)),o=this.determineIfPrimary(e),l={element:e,selector:t,isPrimary:o,lastScrollPos:s,lastDepth:i,lastDirection:x.DOWN,lastEventTime:0,firstScrollEventTime:null,maxDepthReached:i,debounceTimer:null,listener:null},c=()=>{this.get("suppressNextScroll")||(l.firstScrollEventTime===null&&(l.firstScrollEventTime=Date.now()),this.clearContainerTimer(l),l.debounceTimer=window.setTimeout(()=>{const d=this.calculateScrollData(l);if(d){const g=Date.now();this.processScrollEvent(l,d,g)}l.debounceTimer=null},250))};l.listener=c,this.containers.push(l),e===window?window.addEventListener("scroll",c,{passive:!0}):e.addEventListener("scroll",c,{passive:!0})}processScrollEvent(e,t,r){if(!this.shouldEmitScrollEvent(e,t,r))return;e.lastEventTime=r,e.lastDepth=t.depth,e.lastDirection=t.direction;const s=this.get("scrollEventCount")??0;this.set("scrollEventCount",s+1),this.eventManager.track({type:u.SCROLL,scroll_data:{...t,container_selector:e.selector,is_primary:e.isPrimary}})}shouldEmitScrollEvent(e,t,r){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,r)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=this.maxEventsPerSession}hasElapsedMinimumInterval(e,t){return e.lastEventTime===0?!0:t-e.lastEventTime>=this.minIntervalMs}hasSignificantDepthChange(e,t){return Math.abs(t-e.lastDepth)>=this.minDepthChange}logLimitOnce(){this.limitWarningLogged||(this.limitWarningLogged=!0,a("warn","Max scroll events per session reached",{data:{limit:this.maxEventsPerSession}}))}applyConfigOverrides(){this.minDepthChange=5,this.minIntervalMs=500,this.maxEventsPerSession=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?x.DOWN:x.UP}calculateScrollDepth(e,t,r){if(t<=r)return 0;const s=t-r;return Math.min(100,Math.max(0,Math.floor(e/s*100)))}calculateScrollData(e){const{element:t,lastScrollPos:r,lastEventTime:s}=e,i=this.getScrollTop(t),o=Date.now(),l=Math.abs(i-r);if(l<10||t===window&&!this.isWindowScrollable())return null;const c=this.getViewportHeight(t),d=this.getScrollHeight(t),g=this.getScrollDirection(i,r),S=this.calculateScrollDepth(i,d,c);let T;s>0?T=o-s:e.firstScrollEventTime!==null?T=o-e.firstScrollEventTime:T=250;const Z=Math.round(l/T*1e3);return S>e.maxDepthReached&&(e.maxDepthReached=S),e.lastScrollPos=i,{depth:S,direction:g,velocity:Z,max_depth_reached:e.maxDepthReached}}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),r=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflow==="auto"||t.overflow==="scroll",s=e.scrollHeight>e.clientHeight;return r&&s}applyPrimaryScrollSelector(e){let t;if(e==="window")t=window;else{const s=document.querySelector(e);if(!(s instanceof HTMLElement)){a("warn",`Selector "${e}" did not match an HTMLElement`);return}t=s}this.containers.forEach(s=>{this.updateContainerPrimary(s,s.element===t)}),!this.containers.some(s=>s.element===t)&&t instanceof HTMLElement&&this.isElementScrollable(t)&&this.setupScrollContainer(t,e)}updateContainerPrimary(e,t){e.isPrimary=t}}class Yt extends p{eventManager;trackedElements=new Map;observer=null;mutationObserver=null;mutationDebounceTimer=null;config=null;constructor(e){super(),this.eventManager=e}startTracking(){const e=this.get("config");if(this.config=e.viewport??null,!this.config?.elements||this.config.elements.length===0)return;const t=this.config.threshold??.5,r=this.config.minDwellTime??1e3;if(t<0||t>1){a("warn","ViewportHandler: Invalid threshold, must be between 0 and 1");return}if(r<0){a("warn","ViewportHandler: Invalid minDwellTime, must be non-negative");return}if(typeof IntersectionObserver>"u"){a("warn","ViewportHandler: IntersectionObserver not supported in this browser");return}this.observer=new IntersectionObserver(this.handleIntersection,{threshold:t}),this.observeElements(),this.setupMutationObserver()}stopTracking(){this.observer&&(this.observer.disconnect(),this.observer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.mutationDebounceTimer!==null&&(window.clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null);for(const e of this.trackedElements.values())e.timeoutId!==null&&window.clearTimeout(e.timeoutId);this.trackedElements.clear()}observeElements(){if(!this.config||!this.observer)return;const e=this.config.maxTrackedElements??100;let t=this.trackedElements.size;for(const r of this.config.elements)try{const s=document.querySelectorAll(r.selector);for(const i of Array.from(s)){if(t>=e){a("warn","ViewportHandler: Maximum tracked elements reached",{data:{limit:e,selector:r.selector,message:"Some elements will not be tracked. Consider more specific selectors."}});return}i.hasAttribute(`${w}-ignore`)||this.trackedElements.has(i)||(this.trackedElements.set(i,{element:i,selector:r.selector,id:r.id,name:r.name,startTime:null,timeoutId:null,lastFiredTime:null}),this.observer?.observe(i),t++)}}catch(s){a("warn",`ViewportHandler: Invalid selector "${r.selector}"`,{error:s})}a("debug","ViewportHandler: Elements tracked",{data:{count:t,limit:e}})}handleIntersection=e=>{if(!this.config)return;const t=this.config.minDwellTime??1e3;for(const r of e){const s=this.trackedElements.get(r.target);s&&(r.isIntersecting?s.startTime===null&&(s.startTime=performance.now(),s.timeoutId=window.setTimeout(()=>{const i=Math.round(r.intersectionRatio*100)/100;this.fireViewportEvent(s,i)},t)):s.startTime!==null&&(s.timeoutId!==null&&(window.clearTimeout(s.timeoutId),s.timeoutId=null),s.startTime=null))}};fireViewportEvent(e,t){if(e.startTime===null)return;const r=Math.round(performance.now()-e.startTime);if(e.element.hasAttribute(`${w}-ignore`))return;const s=this.config?.cooldownPeriod??6e4,i=Date.now();if(e.lastFiredTime!==null&&i-e.lastFiredTime<s){a("debug","ViewportHandler: Event suppressed by cooldown period",{data:{selector:e.selector,cooldownRemaining:s-(i-e.lastFiredTime)}}),e.startTime=null,e.timeoutId=null;return}const o={selector:e.selector,dwellTime:r,visibilityRatio:t,...e.id!==void 0&&{id:e.id},...e.name!==void 0&&{name:e.name}};this.eventManager.track({type:u.VIEWPORT_VISIBLE,viewport_data:o}),e.startTime=null,e.timeoutId=null,e.lastFiredTime=i}setupMutationObserver(){if(!(!this.config||typeof MutationObserver>"u")){if(!document.body){a("warn","ViewportHandler: document.body not available, skipping MutationObserver setup");return}this.mutationObserver=new MutationObserver(e=>{let t=!1;for(const r of e)r.type==="childList"&&(r.addedNodes.length>0&&(t=!0),r.removedNodes.length>0&&this.cleanupRemovedNodes(r.removedNodes));t&&(this.mutationDebounceTimer!==null&&window.clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.observeElements(),this.mutationDebounceTimer=null},100))}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0})}}cleanupRemovedNodes(e){e.forEach(t=>{if(t.nodeType!==1)return;const r=t,s=this.trackedElements.get(r);s&&(s.timeoutId!==null&&window.clearTimeout(s.timeoutId),this.observer?.unobserve(r),this.trackedElements.delete(r)),Array.from(this.trackedElements.keys()).filter(o=>r.contains(o)).forEach(o=>{const l=this.trackedElements.get(o);l&&l.timeoutId!==null&&window.clearTimeout(l.timeoutId),this.observer?.unobserve(o),this.trackedElements.delete(o)})})}}class qt{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;hasQuotaExceededError=!1;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||a("warn","localStorage not available, using memory fallback"),this.sessionStorageRef||a("warn","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){this.fallbackStorage.set(e,t);try{if(this.storage){this.storage.setItem(e,t);return}}catch(r){if(r instanceof DOMException&&r.name==="QuotaExceededError"||r instanceof Error&&r.name==="QuotaExceededError")if(this.hasQuotaExceededError=!0,a("warn","localStorage quota exceeded, attempting cleanup",{data:{key:e,valueSize:t.length}}),this.cleanupOldData())try{if(this.storage){this.storage.setItem(e,t);return}}catch(o){a("error","localStorage quota exceeded even after cleanup - data will not persist",{error:o,data:{key:e,valueSize:t.length}})}else a("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:r,data:{key:e,valueSize:t.length}})}}removeItem(e){try{this.storage&&this.storage.removeItem(e)}catch{}this.fallbackStorage.delete(e)}clear(){if(!this.storage){this.fallbackStorage.clear();return}try{const e=[];for(let t=0;t<this.storage.length;t++){const r=this.storage.key(t);r?.startsWith("tracelog_")&&e.push(r)}e.forEach(t=>{this.storage.removeItem(t)}),this.fallbackStorage.clear()}catch(e){a("error","Failed to clear storage",{error:e}),this.fallbackStorage.clear()}}isAvailable(){return this.storage!==null}hasQuotaError(){return this.hasQuotaExceededError}cleanupOldData(){if(!this.storage)return!1;try{const e=[],t=[];for(let i=0;i<this.storage.length;i++){const o=this.storage.key(i);o?.startsWith("tracelog_")&&(e.push(o),o.startsWith("tracelog_persisted_events_")&&t.push(o))}if(t.length>0)return t.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0;const r=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],s=e.filter(i=>!r.some(o=>i.startsWith(o)));return s.length>0?(s.slice(0,5).forEach(o=>{try{this.storage.removeItem(o)}catch{}}),!0):!1}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,r="__tracelog_test__";return t.setItem(r,"test"),t.removeItem(r),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(r){(r instanceof DOMException&&r.name==="QuotaExceededError"||r instanceof Error&&r.name==="QuotaExceededError")&&a("error","sessionStorage quota exceeded - data will not persist",{error:r,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class Jt extends p{eventManager;reportedByNav=new Map;navigationHistory=[];observers=[];vitalThresholds;lastLongTaskSentAt=0;navigationCounter=0;constructor(e){super(),this.eventManager=e,this.vitalThresholds=ae(G)}async startTracking(){const e=this.get("config"),t=e?.webVitalsMode??G;this.vitalThresholds=ae(t),e?.webVitalsThresholds&&(this.vitalThresholds={...this.vitalThresholds,...e.webVitalsThresholds}),await this.initWebVitals(),this.observeLongTasks()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(r){a("warn","Failed to disconnect performance observer",{error:r,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear(),this.navigationHistory.length=0}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",r=>{const s=r.getEntries(),i=s[s.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",r=>{const s=this.getNavigationId();s!==t&&(e=0,t=s);const i=r.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",r=>{for(const s of r.getEntries())s.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(s.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",r=>{let s=0;const i=r.getEntries();for(const o of i){const l=(o.processingEnd??0)-(o.startTime??0);s=Math.max(s,l)}s>0&&this.sendVital({type:"INP",value:Number(s.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:r,onTTFB:s,onINP:i}=await Promise.resolve().then(()=>Tr),o=l=>c=>{const d=Number(c.value.toFixed(2));this.sendVital({type:l,value:d})};e(o("LCP"),{reportAllChanges:!1}),t(o("CLS"),{reportAllChanges:!1}),r(o("FCP"),{reportAllChanges:!1}),s(o("TTFB"),{reportAllChanges:!1}),i(o("INP"),{reportAllChanges:!1})}catch(e){a("warn","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("warn","Failed to report TTFB",{error:e})}}observeLongTasks(){this.safeObserve("longtask",e=>{const t=e.getEntries();for(const r of t){const s=Number(r.duration.toFixed(2)),i=Date.now();i-this.lastLongTaskSentAt>=vt&&(this.shouldSendVital("LONG_TASK",s)&&this.trackWebVital("LONG_TASK",s),this.lastLongTaskSentAt=i)}},{type:"longtask",buffered:!0})}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const r=this.reportedByNav.get(t);if(r?.has(e.type))return;if(r)r.add(e.type);else if(this.reportedByNav.set(t,new Set([e.type])),this.navigationHistory.push(t),this.navigationHistory.length>wt){const i=this.navigationHistory.shift();i&&this.reportedByNav.delete(i)}}this.trackWebVital(e.type,e.value)}trackWebVital(e,t){if(!Number.isFinite(t)){a("warn","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:u.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(),r=++this.navigationCounter,s=`${t.toFixed(2)}_${window.location.pathname}`;return r>1?`${s}_${r}`:s}catch(e){return a("warn","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,r,s=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((o,l)=>{try{t(o,l)}catch(c){a("warn","Observer callback failed",{error:c,data:{type:e}})}if(s)try{l.disconnect()}catch{}});return i.observe(r??{type:e,buffered:!0}),s||this.observers.push(i),!0}catch(i){return a("warn","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return a("warn","Invalid web vital value",{data:{type:e,value:t}}),!1;const r=this.vitalThresholds[e];return!(typeof r=="number"&&t<=r)}}class Zt extends p{eventManager;recentErrors=new Map;errorBurstCounter=0;burstWindowStart=0;burstBackoffUntil=0;constructor(e){super(),this.eventManager=e}startTracking(){window.addEventListener("error",this.handleError),window.addEventListener("unhandledrejection",this.handleRejection)}stopTracking(){window.removeEventListener("error",this.handleError),window.removeEventListener("unhandledrejection",this.handleRejection),this.recentErrors.clear(),this.errorBurstCounter=0,this.burstWindowStart=0,this.burstBackoffUntil=0}shouldSample(){const e=Date.now();if(e<this.burstBackoffUntil)return!1;if(e-this.burstWindowStart>Tt&&(this.errorBurstCounter=0,this.burstWindowStart=e),this.errorBurstCounter++,this.errorBurstCounter>pt)return this.burstBackoffUntil=e+He,a("warn","Error burst detected - entering cooldown",{data:{errorsInWindow:this.errorBurstCounter,cooldownMs:He}}),!1;const r=this.get("config")?.errorSampling??Ue;return Math.random()<r}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");this.shouldSuppressError(P.JS_ERROR,t)||this.eventManager.track({type:u.ERROR,error_data:{type:P.JS_ERROR,message:t,...e.filename&&{filename:e.filename},...e.lineno&&{line:e.lineno},...e.colno&&{column:e.colno}}})};handleRejection=e=>{if(!this.shouldSample())return;const t=this.extractRejectionMessage(e.reason),r=this.sanitize(t);this.shouldSuppressError(P.PROMISE_REJECTION,r)||this.eventManager.track({type:u.ERROR,error_data:{type:P.PROMISE_REJECTION,message:r}})};extractRejectionMessage(e){if(!e)return"Unknown rejection";if(typeof e=="string")return e;if(e instanceof Error)return e.stack??e.message??e.toString();if(typeof e=="object"&&"message"in e)return String(e.message);try{return JSON.stringify(e)}catch{return String(e)}}sanitize(e){let t=e.length>Ve?e.slice(0,Ve)+"...":e;for(const r of ie){const s=new RegExp(r.source,r.flags);t=t.replace(s,"[REDACTED]")}return t}shouldSuppressError(e,t){const r=Date.now(),s=`${e}:${t}`,i=this.recentErrors.get(s);return i&&r-i<ke?(this.recentErrors.set(s,r),!0):(this.recentErrors.set(s,r),this.recentErrors.size>St?(this.recentErrors.clear(),this.recentErrors.set(s,r),!1):(this.recentErrors.size>W&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[s,i]of this.recentErrors.entries())e-i>ke&&this.recentErrors.delete(s);if(this.recentErrors.size<=W)return;const t=Array.from(this.recentErrors.entries()).sort((s,i)=>s[1]-i[1]),r=this.recentErrors.size-W;for(let s=0;s<r;s+=1){const i=t[s];i&&this.recentErrors.delete(i[0])}}}class er extends p{isInitialized=!1;suppressNextScrollTimer=null;emitter=new xt;transformers={};managers={};handlers={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new qt;try{this.setupState(e),this.managers.event=new Bt(this.managers.storage,this.emitter,this.transformers),this.initializeHandlers(),await this.managers.event.recoverPersistedEvents().catch(t=>{a("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0}catch(t){this.destroy(!0);const r=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${r}`)}}}sendCustomEvent(e,t){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:s,error:i,sanitizedMetadata:o}=Ht(e,r);if(!s){if(this.get("mode")===F.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${i}`);return}this.managers.event.track({type:u.CUSTOM,custom_event:{name:e,...o&&{metadata:o}}})}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}setTransformer(e,t){if(typeof t!="function")throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof t}`);this.transformers[e]=t}removeTransformer(e){delete this.transformers[e]}getTransformer(e){return this.transformers[e]}destroy(e=!1){!this.isInitialized&&!e||(Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(r){a("warn","Failed to stop tracking",{error:r})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.transformers.beforeSend=void 0,this.transformers.beforeBatch=void 0,this.set("suppressNextScroll",!1),this.set("sessionId",null),this.isInitialized=!1,this.handlers={},this.managers={})}setupState(e={}){this.set("config",e);const t=Wt.getId(this.managers.storage);this.set("userId",t);const r=Ct(e);this.set("collectApiUrls",r);const s=gt();this.set("device",s);const i=le(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const o=At()?F.QA:void 0;o&&this.set("mode",o)}getConfig(){return this.get("config")}getCollectApiUrls(){return this.get("collectApiUrls")}getEventManager(){return this.managers.event}validateGlobalMetadata(e){if(typeof e!="object"||e===null||Array.isArray(e))return{valid:!1,error:"Global metadata must be a plain object"};const t=Xe("Global",e,"globalMetadata");return t.valid?{valid:!0}:{valid:!1,error:t.error}}updateGlobalMetadata(e){const t=this.validateGlobalMetadata(e);if(!t.valid)throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);const s={...this.get("config"),globalMetadata:e};this.set("config",s),a("debug","Global metadata updated (replaced)",{data:{keys:Object.keys(e)}})}mergeGlobalMetadata(e){const t=this.validateGlobalMetadata(e);if(!t.valid)throw new Error(`[TraceLog] Invalid global metadata: ${t.error}`);const r=this.get("config"),i={...r.globalMetadata??{},...e},o={...r,globalMetadata:i};this.set("config",o),a("debug","Global metadata updated (merged)",{data:{keys:Object.keys(e)}})}initializeHandlers(){const e=this.get("config");this.handlers.session=new Qt(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 zt(this.managers.event,t),this.handlers.pageView.startTracking(),this.handlers.click=new jt(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new Kt(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new Jt(this.managers.event),this.handlers.performance.startTracking().catch(r=>{a("warn","Failed to start performance tracking",{error:r})}),this.handlers.error=new Zt(this.managers.event),this.handlers.error.startTracking(),e.viewport&&(this.handlers.viewport=new Yt(this.managers.event),this.handlers.viewport.startTracking())}}const C=[],b=[];let m=null,N=!1,I=!1;const tr=async n=>{if(!(typeof window>"u"||typeof document>"u")&&(I=!1,window.__traceLogDisabled!==!0&&!m&&!N)){N=!0;try{const e=Vt(n??{}),t=new er;try{C.forEach(({event:i,callback:o})=>{t.on(i,o)}),C.length=0,b.forEach(({hook:i,fn:o})=>{i==="beforeSend"?t.setTransformer("beforeSend",o):t.setTransformer("beforeBatch",o)}),b.length=0;const r=t.init(e),s=new Promise((i,o)=>{setTimeout(()=>{o(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)});await Promise.race([r,s]),m=t}catch(r){try{t.destroy(!0)}catch(s){a("error","Failed to cleanup partially initialized app",{error:s})}throw r}}catch(e){throw m=null,e}finally{N=!1}}},rr=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!m)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(I)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");m.sendCustomEvent(n,e)}},nr=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!m||N){C.push({event:n,callback:e});return}m.on(n,e)}},sr=(n,e)=>{if(!(typeof window>"u"||typeof document>"u")){if(!m){const t=C.findIndex(r=>r.event===n&&r.callback===e);t!==-1&&C.splice(t,1);return}m.off(n,e)}};function ir(n,e){if(!(typeof window>"u"||typeof document>"u")){if(typeof e!="function")throw new Error(`[TraceLog] Transformer must be a function, received: ${typeof e}`);if(!m||N){const t=b.findIndex(r=>r.hook===n);t!==-1&&b.splice(t,1),b.push({hook:n,fn:e});return}if(I)throw new Error("[TraceLog] Cannot set transformers while TraceLog is being destroyed");n==="beforeSend"?m.setTransformer("beforeSend",e):m.setTransformer("beforeBatch",e)}}const or={init:tr,event:rr,on:nr,off:sr,setTransformer:ir,removeTransformer:n=>{if(!(typeof window>"u"||typeof document>"u")){if(!m){const e=b.findIndex(t=>t.hook===n);e!==-1&&b.splice(e,1);return}if(I)throw new Error("[TraceLog] Cannot remove transformers while TraceLog is being destroyed");m.removeTransformer(n)}},isInitialized:()=>typeof window>"u"||typeof document>"u"?!1:m!==null,destroy:()=>{if(!(typeof window>"u"||typeof document>"u")){if(I)throw new Error("[TraceLog] Destroy operation already in progress");if(!m){I=!1;return}I=!0;try{m.destroy(),m=null,N=!1,C.length=0,b.length=0,I=!1}catch(n){m=null,N=!1,C.length=0,b.length=0,I=!1,a("warn","Error during destroy, forced cleanup completed",{error:n})}}},setQaMode:n=>{typeof window>"u"||typeof document>"u"||Mt(n)},updateGlobalMetadata:n=>{if(!(typeof window>"u"||typeof document>"u")){if(!m)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(I)throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");m.updateGlobalMetadata(n)}},mergeGlobalMetadata:n=>{if(!(typeof window>"u"||typeof document>"u")){if(!m)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(I)throw new Error("[TraceLog] Cannot update metadata while TraceLog is being destroyed");m.mergeGlobalMetadata(n)}}};var de,Ke=-1,k=function(n){addEventListener("pageshow",(function(e){e.persisted&&(Ke=e.timeStamp,n(e))}),!0)},he=function(){var n=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},z=function(){var n=he();return n&&n.activationStart||0},y=function(n,e){var t=he(),r="navigate";return Ke>=0?r="back-forward-cache":t&&(document.prerendering||z()>0?r="prerender":document.wasDiscarded?r="restore":t.type&&(r=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:r}},$=function(n,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(n)){var r=new PerformanceObserver((function(s){Promise.resolve().then((function(){e(s.getEntries())}))}));return r.observe(Object.assign({type:n,buffered:!0},t||{})),r}}catch{}},A=function(n,e,t,r){var s,i;return function(o){e.value>=0&&(o||r)&&((i=e.value-(s||0))||s===void 0)&&(s=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))}},fe=function(n){requestAnimationFrame((function(){return requestAnimationFrame((function(){return n()}))}))},j=function(n){document.addEventListener("visibilitychange",(function(){document.visibilityState==="hidden"&&n()}))},me=function(n){var e=!1;return function(){e||(n(),e=!0)}},U=-1,Ye=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},K=function(n){document.visibilityState==="hidden"&&U>-1&&(U=n.type==="visibilitychange"?n.timeStamp:0,ar())},qe=function(){addEventListener("visibilitychange",K,!0),addEventListener("prerenderingchange",K,!0)},ar=function(){removeEventListener("visibilitychange",K,!0),removeEventListener("prerenderingchange",K,!0)},Je=function(){return U<0&&(U=Ye(),qe(),k((function(){setTimeout((function(){U=Ye(),qe()}),0)}))),{get firstHiddenTime(){return U}}},Y=function(n){document.prerendering?addEventListener("prerenderingchange",(function(){return n()}),!0):n()},Ee=[1800,3e3],Ze=function(n,e){e=e||{},Y((function(){var t,r=Je(),s=y("FCP"),i=$("paint",(function(o){o.forEach((function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<r.firstHiddenTime&&(s.value=Math.max(l.startTime-z(),0),s.entries.push(l),t(!0)))}))}));i&&(t=A(n,s,Ee,e.reportAllChanges),k((function(o){s=y("FCP"),t=A(n,s,Ee,e.reportAllChanges),fe((function(){s.value=performance.now()-o.timeStamp,t(!0)}))})))}))},ge=[.1,.25],lr=function(n,e){e=e||{},Ze(me((function(){var t,r=y("CLS",0),s=0,i=[],o=function(c){c.forEach((function(d){if(!d.hadRecentInput){var g=i[0],S=i[i.length-1];s&&d.startTime-S.startTime<1e3&&d.startTime-g.startTime<5e3?(s+=d.value,i.push(d)):(s=d.value,i=[d])}})),s>r.value&&(r.value=s,r.entries=i,t())},l=$("layout-shift",o);l&&(t=A(n,r,ge,e.reportAllChanges),j((function(){o(l.takeRecords()),t(!0)})),k((function(){s=0,r=y("CLS",0),t=A(n,r,ge,e.reportAllChanges),fe((function(){return t()}))})),setTimeout(t,0))})))},et=0,Se=1/0,q=0,cr=function(n){n.forEach((function(e){e.interactionId&&(Se=Math.min(Se,e.interactionId),q=Math.max(q,e.interactionId),et=q?(q-Se)/7+1:0)}))},tt=function(){return de?et:performance.interactionCount||0},ur=function(){"interactionCount"in performance||de||(de=$("event",cr,{type:"event",buffered:!0,durationThreshold:0}))},M=[],J=new Map,rt=0,dr=function(){var n=Math.min(M.length-1,Math.floor((tt()-rt)/50));return M[n]},hr=[],fr=function(n){if(hr.forEach((function(s){return s(n)})),n.interactionId||n.entryType==="first-input"){var e=M[M.length-1],t=J.get(n.interactionId);if(t||M.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 r={id:n.interactionId,latency:n.duration,entries:[n]};J.set(r.id,r),M.push(r)}M.sort((function(s,i){return i.latency-s.latency})),M.length>10&&M.splice(10).forEach((function(s){return J.delete(s.id)}))}}},nt=function(n){var e=self.requestIdleCallback||self.setTimeout,t=-1;return n=me(n),document.visibilityState==="hidden"?n():(t=e(n),j(n)),t},Te=[200,500],mr=function(n,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},Y((function(){var t;ur();var r,s=y("INP"),i=function(l){nt((function(){l.forEach(fr);var c=dr();c&&c.latency!==s.value&&(s.value=c.latency,s.entries=c.entries,r())}))},o=$("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});r=A(n,s,Te,e.reportAllChanges),o&&(o.observe({type:"first-input",buffered:!0}),j((function(){i(o.takeRecords()),r(!0)})),k((function(){rt=tt(),M.length=0,J.clear(),s=y("INP"),r=A(n,s,Te,e.reportAllChanges)})))})))},pe=[2500,4e3],_e={},Er=function(n,e){e=e||{},Y((function(){var t,r=Je(),s=y("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach((function(d){d.startTime<r.firstHiddenTime&&(s.value=Math.max(d.startTime-z(),0),s.entries=[d],t())}))},o=$("largest-contentful-paint",i);if(o){t=A(n,s,pe,e.reportAllChanges);var l=me((function(){_e[s.id]||(i(o.takeRecords()),o.disconnect(),_e[s.id]=!0,t(!0))}));["keydown","click"].forEach((function(c){addEventListener(c,(function(){return nt(l)}),{once:!0,capture:!0})})),j(l),k((function(c){s=y("LCP"),t=A(n,s,pe,e.reportAllChanges),fe((function(){s.value=performance.now()-c.timeStamp,_e[s.id]=!0,t(!0)}))}))}}))},Ie=[800,1800],gr=function n(e){document.prerendering?Y((function(){return n(e)})):document.readyState!=="complete"?addEventListener("load",(function(){return n(e)}),!0):setTimeout(e,0)},Sr=function(n,e){e=e||{};var t=y("TTFB"),r=A(n,t,Ie,e.reportAllChanges);gr((function(){var s=he();s&&(t.value=Math.max(s.responseStart-z(),0),t.entries=[s],r(!0),k((function(){t=y("TTFB",0),(r=A(n,t,Ie,e.reportAllChanges))(!0)})))}))};const Tr=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:ge,FCPThresholds:Ee,INPThresholds:Te,LCPThresholds:pe,TTFBThresholds:Ie,onCLS:lr,onFCP:Ze,onINP:mr,onLCP:Er,onTTFB:Sr},Symbol.toStringTag,{value:"Module"}));h.AppConfigValidationError=f,h.DEFAULT_SESSION_TIMEOUT=9e5,h.DEFAULT_WEB_VITALS_MODE=G,h.DeviceType=L,h.EmitterEvent=B,h.ErrorType=P,h.EventType=u,h.InitializationTimeoutError=ft,h.IntegrationValidationError=V,h.MAX_ARRAY_LENGTH=100,h.MAX_CUSTOM_EVENT_ARRAY_SIZE=10,h.MAX_CUSTOM_EVENT_KEYS=10,h.MAX_CUSTOM_EVENT_NAME_LENGTH=120,h.MAX_CUSTOM_EVENT_STRING_SIZE=8192,h.MAX_METADATA_NESTING_DEPTH=1,h.MAX_NESTED_OBJECT_KEYS=20,h.MAX_STRING_LENGTH=1e3,h.MAX_STRING_LENGTH_IN_ARRAY=500,h.Mode=F,h.PII_PATTERNS=ie,h.PermanentError=R,h.SamplingRateValidationError=re,h.ScrollDirection=x,h.SessionTimeoutValidationError=Ne,h.SpecialApiUrl=O,h.TraceLogValidationError=D,h.WEB_VITALS_GOOD_THRESHOLDS=It,h.WEB_VITALS_NEEDS_IMPROVEMENT_THRESHOLDS=oe,h.WEB_VITALS_POOR_THRESHOLDS=xe,h.getWebVitalsThresholds=ae,h.isPrimaryScrollEvent=dt,h.isSecondaryScrollEvent=ht,h.tracelog=or,Object.defineProperty(h,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);