@tracelog/lib 0.8.2 → 0.8.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,8 +1,8 @@
1
- (function(u){"use strict";const U="data-tlog",be=["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"]'],De=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],T={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_GOOGLE_ANALYTICS_ID:"Google Analytics measurement ID is required when integration is enabled",INVALID_SCROLL_CONTAINER_SELECTORS:"Scroll container selectors must be valid CSS selectors",INVALID_GLOBAL_METADATA:"Global metadata must be an object",INVALID_SENSITIVE_QUERY_PARAMS:"Sensitive query params must be an array of strings"},Pe=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi];var k=(r=>(r.Localhost="localhost:8080",r.Fail="localhost:9999",r))(k||{}),m=(r=>(r.Mobile="mobile",r.Tablet="tablet",r.Desktop="desktop",r.Unknown="unknown",r))(m||{}),H=(r=>(r.EVENT="event",r.QUEUE="queue",r))(H||{});class A extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,A)}}var h=(r=>(r.PAGE_VIEW="page_view",r.CLICK="click",r.SCROLL="scroll",r.SESSION_START="session_start",r.SESSION_END="session_end",r.CUSTOM="custom",r.WEB_VITALS="web_vitals",r.ERROR="error",r))(h||{}),b=(r=>(r.UP="up",r.DOWN="down",r))(b||{}),M=(r=>(r.JS_ERROR="js_error",r.PROMISE_REJECTION="promise_rejection",r))(M||{}),w=(r=>(r.QA="qa",r))(w||{});class L extends Error{constructor(e,t,s){super(e),this.errorCode=t,this.layer=s,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class y extends L{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class ce extends L{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class Y extends L{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class p extends L{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class Ue extends L{constructor(e,t,s="runtime"){super(e,"INITIALIZATION_TIMEOUT",s),this.timeoutMs=t}}const ke=(r,e)=>{if(e){if(e instanceof Error){const t=e.message.replace(/\s+at\s+.*$/gm,"").replace(/\(.*?:\d+:\d+\)/g,"");return`[TraceLog] ${r}: ${t}`}return`[TraceLog] ${r}: ${e instanceof Error?e.message:"Unknown error"}`}return`[TraceLog] ${r}`},o=(r,e,t)=>{const{error:s,data:n,showToClient:i=!1}=t??{},a=s?ke(e,s):`[TraceLog] ${e}`,l=r==="error"?"error":r==="warn"?"warn":"log";if(!(r==="debug"||r==="info"&&!i))if(n!==void 0){const c=He(n);console[l](a,c)}else n!==void 0?console[l](a,n):console[l](a)},He=r=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[s,n]of Object.entries(r)){const i=s.toLowerCase();t.some(a=>i.includes(a))?e[s]="[REDACTED]":e[s]=n}return e};let Q,ue;const Ve=()=>{typeof window<"u"&&!Q&&(Q=window.matchMedia("(pointer: coarse)"),ue=window.matchMedia("(hover: none)"))},Ge=()=>{try{const r=navigator;if(r.userAgentData&&typeof r.userAgentData.mobile=="boolean")return r.userAgentData.platform&&/ipad|tablet/i.test(r.userAgentData.platform)?m.Tablet:r.userAgentData.mobile?m.Mobile:m.Desktop;Ve();const e=window.innerWidth,t=Q?.matches??!1,s=ue?.matches??!1,n="ontouchstart"in window||navigator.maxTouchPoints>0,i=navigator.userAgent.toLowerCase(),a=/mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i),l=/tablet|ipad|android(?!.*mobile)/.test(i);return e<=767||a&&n?m.Mobile:e>=768&&e<=1024||l||t&&s&&n?m.Tablet:m.Desktop}catch(r){return o("warn","Device detection failed, defaulting to desktop",{error:r}),m.Desktop}},I="tlog",de=`${I}:qa_mode`,Fe=`${I}:uid`,xe=r=>r?`${I}:${r}:queue`:`${I}:queue`,Xe=r=>r?`${I}:${r}:session`:`${I}:session`,Be=r=>r?`${I}:${r}:broadcast`:`${I}:broadcast`,he={LCP:4e3,FCP:1800,CLS:.25,INP:200,TTFB:800,LONG_TASK:50},$e=1e3,fe=[/\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],ge=500,Ee=5e3,V=50,ze=V*2,Ye=6e4,Se="tlog_mode",Qe="qa",je=()=>{if(sessionStorage.getItem(de)==="true")return!0;const e=new URLSearchParams(window.location.search),s=e.get(Se)===Qe;if(s){sessionStorage.setItem(de,"true"),e.delete(Se);const n=e.toString(),i=`${window.location.pathname}${n?"?"+n:""}${window.location.hash}`;try{window.history.replaceState({},"",i)}catch(a){o("warn","History API not available, cannot replace URL",{error:a})}console.log("%c[TraceLog] QA Mode ACTIVE","background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;")}return s},_e=()=>{const r=new URLSearchParams(window.location.search),e={};return De.forEach(s=>{const n=r.get(s);if(n){const i=s.split("utm_")[1];e[i]=n}}),Object.keys(e).length?e:void 0},Ke=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,r=>{const e=Math.random()*16|0;return(r==="x"?e:e&3|8).toString(16)}),We=()=>{const r=Date.now();let e="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const t=crypto.getRandomValues(new Uint8Array(4));t&&(e=Array.from(t,s=>s.toString(16).padStart(2,"0")).join(""))}}catch{}return e||(e=Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0")),`${r}-${e}`},Te=(r,e=!1)=>{try{const t=new URL(r),s=t.protocol==="https:",n=t.protocol==="http:";return s||e&&n}catch{return!1}},Ze=r=>{if(r.integrations?.tracelog?.projectId){const n=new URL(window.location.href).hostname.split(".");if(n.length===0)throw new Error("Invalid URL");const i=r.integrations.tracelog.projectId,a=n.slice(-2).join("."),l=`https://${i}.${a}/collect`;if(!Te(l))throw new Error("Invalid URL");return l}const e=r.integrations?.custom?.collectApiUrl;if(e){const t=r.integrations?.custom?.allowHttp??!1;if(!Te(e,t))throw new Error("Invalid URL");return e}return""},j=(r,e=[])=>{try{const t=new URL(r),s=t.searchParams;let n=!1;const i=[];return e.forEach(l=>{s.has(l)&&(s.delete(l),n=!0,i.push(l))}),!n&&r.includes("?")?r:(t.search=s.toString(),t.toString())}catch(t){return o("warn","URL normalization failed, returning original",{error:t,data:{url:r.slice(0,100)}}),r}},me=r=>{if(!r||typeof r!="string"||r.trim().length===0)return"";let e=r;r.length>1e3&&(e=r.slice(0,Math.max(0,1e3)));let t=0;for(const n of Pe){const i=e;e=e.replace(n,""),i!==e&&t++}return t>0&&o("warn","XSS patterns detected and removed",{data:{patternMatches:t,originalValue:r.slice(0,100)}}),e=e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#x27;").replaceAll("/","&#x2F;"),e.trim()},K=(r,e=0)=>{if(e>3||r==null)return null;if(typeof r=="string")return me(r);if(typeof r=="number")return!Number.isFinite(r)||r<-Number.MAX_SAFE_INTEGER||r>Number.MAX_SAFE_INTEGER?0:r;if(typeof r=="boolean")return r;if(Array.isArray(r))return r.slice(0,100).map(n=>K(n,e+1)).filter(n=>n!==null);if(typeof r=="object"){const t={},n=Object.entries(r).slice(0,20);for(const[i,a]of n){const l=me(i);if(l){const c=K(a,e+1);c!==null&&(t[l]=c)}}return t}return null},qe=r=>{if(typeof r!="object"||r===null)return{};try{const e=K(r);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}`)}},Je=r=>{if(r!==void 0&&(r===null||typeof r!="object"))throw new y("Configuration must be an object","config");if(r){if(r.sessionTimeout!==void 0&&(typeof r.sessionTimeout!="number"||r.sessionTimeout<3e4||r.sessionTimeout>864e5))throw new ce(T.INVALID_SESSION_TIMEOUT,"config");if(r.globalMetadata!==void 0&&(typeof r.globalMetadata!="object"||r.globalMetadata===null))throw new y(T.INVALID_GLOBAL_METADATA,"config");if(r.scrollContainerSelectors!==void 0&&tt(r.scrollContainerSelectors),r.integrations&&rt(r.integrations),r.sensitiveQueryParams!==void 0){if(!Array.isArray(r.sensitiveQueryParams))throw new y(T.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of r.sensitiveQueryParams)if(typeof e!="string")throw new y("All sensitive query params must be strings","config")}if(r.errorSampling!==void 0&&(typeof r.errorSampling!="number"||r.errorSampling<0||r.errorSampling>1))throw new Y(T.INVALID_ERROR_SAMPLING_RATE,"config");if(r.samplingRate!==void 0&&(typeof r.samplingRate!="number"||r.samplingRate<0||r.samplingRate>1))throw new Y(T.INVALID_SAMPLING_RATE,"config")}},et=r=>{if(r.includes("<")||r.includes(">")||/on\w+\s*=/i.test(r)||!/^[a-zA-Z0-9\-_#.[\]="':, >+~*()]+$/.test(r))return!1;let t=0;for(const n of r)if(n==="("&&t++,n===")"&&t--,t<0)return!1;if(t!==0)return!1;let s=0;for(const n of r)if(n==="["&&s++,n==="]"&&s--,s<0)return!1;return s===0},tt=r=>{const e=Array.isArray(r)?r:[r];for(const t of e){if(typeof t!="string"||t.trim()==="")throw o("error","Invalid scroll container selector",{showToClient:!0,data:{selector:t,type:typeof t,isEmpty:t===""||typeof t=="string"&&t.trim()===""}}),new y(T.INVALID_SCROLL_CONTAINER_SELECTORS,"config");if(!et(t))throw o("error","Invalid or potentially unsafe CSS selector",{showToClient:!0,data:{selector:t,reason:"Failed security validation"}}),new y("Invalid or potentially unsafe CSS selector","config")}},rt=r=>{if(r){if(r.tracelog&&(!r.tracelog.projectId||typeof r.tracelog.projectId!="string"||r.tracelog.projectId.trim()===""))throw new p(T.INVALID_TRACELOG_PROJECT_ID,"config");if(r.custom){if(!r.custom.collectApiUrl||typeof r.custom.collectApiUrl!="string"||r.custom.collectApiUrl.trim()==="")throw new p(T.INVALID_CUSTOM_API_URL,"config");if(r.custom.allowHttp!==void 0&&typeof r.custom.allowHttp!="boolean")throw new p("allowHttp must be a boolean","config");const e=r.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new p('Custom API URL must start with "http://" or "https://"',"config");if(!(r.custom.allowHttp??!1)&&e.startsWith("http://"))throw new p("Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)","config")}if(r.googleAnalytics){if(!r.googleAnalytics.measurementId||typeof r.googleAnalytics.measurementId!="string"||r.googleAnalytics.measurementId.trim()==="")throw new p(T.INVALID_GOOGLE_ANALYTICS_ID,"config");if(!r.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))throw new p('Google Analytics measurement ID must start with "G-" or "UA-"',"config")}}},st=r=>{Je(r);const e={...r??{},sessionTimeout:r?.sessionTimeout??9e5,globalMetadata:r?.globalMetadata??{},sensitiveQueryParams:r?.sensitiveQueryParams??[],errorSampling:r?.errorSampling??1,samplingRate:r?.samplingRate??1};return e.integrations?.custom&&(e.integrations.custom={...e.integrations.custom,allowHttp:e.integrations.custom.allowHttp??!1}),e},nt=r=>{if(typeof r=="string")return!0;if(typeof r=="object"&&r!==null&&!Array.isArray(r)){const e=Object.entries(r);if(e.length>20)return!1;for(const[,t]of e){if(t==null)continue;const s=typeof t;if(s!=="string"&&s!=="number"&&s!=="boolean")return!1}return!0}return!1},pe=(r,e=0)=>{if(typeof r!="object"||r===null||e>1)return!1;for(const t of Object.values(r)){if(t==null)continue;const s=typeof t;if(!(s==="string"||s==="number"||s==="boolean")){if(Array.isArray(t)){if(t.length===0)continue;if(typeof t[0]=="string"){if(!t.every(a=>typeof a=="string"))return!1}else if(!t.every(a=>nt(a)))return!1;continue}if(s==="object"&&e===0){if(!pe(t,e+1))return!1;continue}return!1}}return!0},it=r=>typeof r!="string"?{valid:!1,error:"Event name must be a string"}:r.length===0?{valid:!1,error:"Event name cannot be empty"}:r.length>120?{valid:!1,error:"Event name is too long (max 120 characters)"}:r.includes("<")||r.includes(">")||r.includes("&")?{valid:!1,error:"Event name contains invalid characters"}:["constructor","prototype","__proto__","eval","function","var","let","const"].includes(r.toLowerCase())?{valid:!1,error:"Event name cannot be a reserved word"}:{valid:!0},Ie=(r,e,t)=>{const s=qe(e),n=`${t} "${r}" metadata error`;if(!pe(s))return{valid:!1,error:`${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(s)}catch{return{valid:!1,error:`${n}: object contains circular references or cannot be serialized.`}}if(i.length>8192)return{valid:!1,error:`${n}: object is too large (max ${8192/1024} KB).`};if(Object.keys(s).length>10)return{valid:!1,error:`${n}: object has too many keys (max 10 keys).`};for(const[l,c]of Object.entries(s)){if(Array.isArray(c)){if(c.length>10)return{valid:!1,error:`${n}: 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:`${n}: array property "${l}" contains strings that are too long (max 500 characters).`}}if(typeof c=="string"&&c.length>1e3)return{valid:!1,error:`${n}: property "${l}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:s}},at=(r,e,t)=>{if(Array.isArray(e)){const s=[],n=`${t} "${r}" metadata error`;for(let i=0;i<e.length;i++){const a=e[i];if(typeof a!="object"||a===null||Array.isArray(a))return{valid:!1,error:`${n}: array item at index ${i} must be an object.`};const l=Ie(r,a,t);if(!l.valid)return{valid:!1,error:`${n}: array item at index ${i} is invalid: ${l.error}`};l.sanitizedMetadata&&s.push(l.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:s}}return Ie(r,e,t)},ot=(r,e)=>{const t=it(r);if(!t.valid)return o("error","Event name validation failed",{showToClient:!0,data:{eventName:r,error:t.error}}),t;if(!e)return{valid:!0};const s=at(r,e,"customEvent");return s.valid||o("error","Event metadata validation failed",{showToClient:!0,data:{eventName:r,error:s.error}}),s};class lt{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const s=this.listeners.get(e);if(s){const n=s.indexOf(t);n>-1&&s.splice(n,1)}}emit(e,t){const s=this.listeners.get(e);s&&s.forEach(n=>{n(t)})}removeAllListeners(){this.listeners.clear()}}const W={};class g{get(e){return W[e]}set(e,t){W[e]=t}getState(){return{...W}}}class ct extends g{storeManager;lastPermanentErrorLog=null;constructor(e){super(),this.storeManager=e}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return xe(e)}sendEventsQueueSync(e){return this.shouldSkipSend()?!0:this.get("config")?.integrations?.custom?.collectApiUrl===k.Fail?(o("warn","Fail mode: simulating network failure (sync)",{data:{events:e.events.length}}),!1):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){try{const s=await this.send(e);return s?(this.clearPersistedEvents(),t?.onSuccess?.(e.events.length,e.events,e)):(this.persistEvents(e),t?.onFailure?.()),s}catch(s){return s instanceof A?(this.logPermanentError("Permanent error, not retrying",s),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(e),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){try{const t=this.getPersistedData();if(!t||!this.isDataRecent(t)||t.events.length===0){this.clearPersistedEvents();return}const s=this.createRecoveryBody(t);await this.send(s)?(this.clearPersistedEvents(),e?.onSuccess?.(t.events.length,t.events,s)):e?.onFailure?.()}catch(t){if(t instanceof A){this.logPermanentError("Permanent error during recovery, clearing persisted events",t),this.clearPersistedEvents(),e?.onFailure?.();return}o("error","Failed to recover persisted events",{error:t})}}stop(){}async send(e){if(this.shouldSkipSend())return this.simulateSuccessfulSend();if(this.get("config")?.integrations?.custom?.collectApiUrl===k.Fail)return o("warn","Fail mode: simulating network failure",{data:{events:e.events.length}}),!1;const{url:s,payload:n}=this.prepareRequest(e);try{return(await this.sendWithTimeout(s,n)).ok}catch(i){if(i instanceof A)throw i;return o("error","Send request failed",{error:i,data:{events:e.events.length,url:s.replace(/\/\/[^/]+/,"//[DOMAIN]")}}),!1}}async sendWithTimeout(e,t){const s=new AbortController,n=setTimeout(()=>{s.abort()},1e4);try{const i=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:s.signal,headers:{"Content-Type":"application/json"}});if(!i.ok)throw i.status>=400&&i.status<500?new A(`HTTP ${i.status}: ${i.statusText}`,i.status):new Error(`HTTP ${i.status}: ${i.statusText}`);return i}finally{clearTimeout(n)}}sendQueueSyncInternal(e){const{url:t,payload:s}=this.prepareRequest(e),n=new Blob([s],{type:"application/json"});if(!this.isSendBeaconAvailable())return o("warn","sendBeacon not available, persisting events for recovery"),this.persistEvents(e),!1;const i=navigator.sendBeacon(t,n);return i||(o("warn","sendBeacon rejected request, persisting events for recovery"),this.persistEvents(e)),i}prepareRequest(e){const t={...e,_metadata:{referer:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()}};return{url:this.get("collectApiUrl"),payload:JSON.stringify(t)}}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){o("warn","Failed to parse persisted data",{error:e}),this.clearPersistedEvents()}return null}isDataRecent(e){return!e.timestamp||typeof e.timestamp!="number"?!1:(Date.now()-e.timestamp)/(1e3*60*60)<2}createRecoveryBody(e){return{user_id:e.userId,session_id:e.sessionId,device:e.device,events:e.events,...e.global_metadata&&{global_metadata:e.global_metadata}}}persistEvents(e){try{const t={userId:e.user_id,sessionId:e.session_id,device:e.device,events:e.events,timestamp:Date.now(),...e.global_metadata&&{global_metadata:e.global_metadata}},s=this.getQueueStorageKey();return this.storeManager.setItem(s,JSON.stringify(t)),!!this.storeManager.getItem(s)}catch(t){return o("warn","Failed to persist events",{error:t}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){o("warn","Failed to clear persisted events",{error:e})}}shouldSkipSend(){return!this.get("collectApiUrl")}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 s=Date.now();(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.statusCode!==t.statusCode||s-this.lastPermanentErrorLog.timestamp>=Ye)&&(o("error",e,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:s})}}class ut extends g{googleAnalytics;dataSender;emitter;eventsQueue=[];pendingEventsBuffer=[];lastEventFingerprint=null;lastEventTime=0;sendIntervalId=null;rateLimitCounter=0;rateLimitWindowStart=0;constructor(e,t=null,s=null){super(),this.googleAnalytics=t,this.dataSender=new ct(e),this.emitter=s}async recoverPersistedEvents(){await this.dataSender.recoverPersistedEvents({onSuccess:(e,t,s)=>{if(t&&t.length>0){const n=t.map(i=>i.id);this.removeProcessedEvents(n),s&&this.emitEventsQueue(s)}},onFailure:()=>{o("warn","Failed to recover persisted events")}})}track({type:e,page_url:t,from_page_url:s,scroll_data:n,click_data:i,custom_event:a,web_vitals:l,error_data:c,session_end_reason:d}){if(!e){o("error","Event type is required - event will be ignored");return}if(!this.get("sessionId")){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),o("warn","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:s,scroll_data:n,click_data:i,custom_event:a,web_vitals:l,error_data:c,session_end_reason:d});return}const v=e===h.SESSION_START||e===h.SESSION_END;if(!v&&!this.checkRateLimit())return;const P=e,Jt=P===h.SESSION_START,er=t||this.get("pageUrl"),le=this.buildEventPayload({type:P,page_url:er,from_page_url:s,scroll_data:n,click_data:i,custom_event:a,web_vitals:l,error_data:c,session_end_reason:d});if(!(!v&&!this.shouldSample())){if(Jt){const Oe=this.get("sessionId");if(!Oe){o("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){o("warn","Duplicate session_start detected",{data:{sessionId:Oe}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(le)){if(this.get("mode")===w.QA&&P===h.CUSTOM&&a){console.log("[TraceLog] Event",{name:a.name,...a.metadata&&{metadata:a.metadata}}),this.emitEvent(le);return}this.addToQueue(le)}}}stop(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null),this.eventsQueue=[],this.pendingEventsBuffer=[],this.lastEventFingerprint=null,this.lastEventTime=0,this.rateLimitCounter=0,this.rateLimitWindowStart=0,this.dataSender.stop()}async flushImmediately(){return this.flushEvents(!1)}flushImmediatelySync(){return this.flushEvents(!0)}getQueueLength(){return this.eventsQueue.length}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){o("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(s=>{this.track(s)})}clearSendInterval(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null)}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);const t=this.buildEventsPayload(),s=[...this.eventsQueue],n=s.map(i=>i.id);if(e){const i=this.dataSender.sendEventsQueueSync(t);return i&&(this.removeProcessedEvents(n),this.clearSendInterval(),this.emitEventsQueue(t)),i}else return this.dataSender.sendEventsQueue(t,{onSuccess:()=>{this.removeProcessedEvents(n),this.clearSendInterval(),this.emitEventsQueue(t)},onFailure:()=>{o("warn","Async flush failed",{data:{eventCount:s.length}})}})}async sendEventsQueue(){if(!this.get("sessionId")||this.eventsQueue.length===0)return;const e=this.buildEventsPayload(),t=[...this.eventsQueue],s=t.map(n=>n.id);await this.dataSender.sendEventsQueue(e,{onSuccess:()=>{this.removeProcessedEvents(s),this.emitEventsQueue(e)},onFailure:()=>{o("warn","Events send failed, keeping in queue",{data:{eventCount:t.length}})}})}buildEventsPayload(){const e=new Map,t=[];for(const n of this.eventsQueue){const i=this.createEventSignature(n);e.has(i)||t.push(i),e.set(i,n)}const s=t.map(n=>e.get(n)).filter(n=>!!n).sort((n,i)=>n.timestamp-i.timestamp);return{user_id:this.get("userId"),session_id:this.get("sessionId"),device:this.get("device"),events:s,...this.get("config")?.globalMetadata&&{global_metadata:this.get("config")?.globalMetadata}}}buildEventPayload(e){const t=e.type===h.SESSION_START,s=e.page_url??this.get("pageUrl");return{id:We(),type:e.type,page_url:s,timestamp:Date.now(),...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.session_end_reason&&{session_end_reason:e.session_end_reason},...t&&_e()&&{utm:_e()}}}isDuplicateEvent(e){const t=Date.now(),s=this.createEventFingerprint(e);return this.lastEventFingerprint===s&&t-this.lastEventTime<500?!0:(this.lastEventFingerprint=s,this.lastEventTime=t,!1)}createEventFingerprint(e){let t=`${e.type}_${e.page_url}`;if(e.click_data){const s=Math.round((e.click_data.x||0)/10)*10,n=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${s}_${n}`}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.eventsQueue.push(e),this.emitEvent(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(n=>n.type!==h.SESSION_START&&n.type!==h.SESSION_END),s=t>=0?this.eventsQueue.splice(t,1)[0]:this.eventsQueue.shift();o("warn","Event queue overflow, oldest non-critical event removed",{data:{maxLength:100,currentLength:this.eventsQueue.length,removedEventType:s?.type,wasCritical:s?.type===h.SESSION_START||s?.type===h.SESSION_END}})}this.sendIntervalId||this.startSendInterval(),this.handleGoogleAnalyticsIntegration(e)}startSendInterval(){this.sendIntervalId=window.setInterval(()=>{this.eventsQueue.length>0&&this.sendEventsQueue()},1e4)}handleGoogleAnalyticsIntegration(e){if(this.googleAnalytics&&e.type===h.CUSTOM&&e.custom_event){if(this.get("mode")===w.QA)return;this.googleAnalytics.trackEvent(e.custom_event.name,e.custom_event.metadata??{})}}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>=200?!1:(this.rateLimitCounter++,!0)}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(s=>!t.has(s.id))}emitEvent(e){this.emitter&&this.emitter.emit(H.EVENT,e)}emitEventsQueue(e){this.emitter&&this.emitter.emit(H.QUEUE,e)}}class dt{static getId(e){const t=Fe,s=e.getItem(t);if(s)return s;const n=Ke();return e.setItem(t,n),n}}class ht extends g{storageManager;eventManager;projectId;sessionTimeoutId=null;broadcastChannel=null;activityHandler=null;visibilityChangeHandler=null;beforeUnloadHandler=null;isTracking=!1;constructor(e,t,s){super(),this.storageManager=e,this.eventManager=t,this.projectId=s}initCrossTabSync(){if(typeof BroadcastChannel>"u"){o("warn","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel(Be(e)),this.broadcastChannel.onmessage=t=>{const{action:s,sessionId:n,timestamp:i,projectId:a}=t.data??{};if(a===e){if(s==="session_end"){this.resetSessionState();return}n&&typeof i=="number"&&i>Date.now()-5e3&&(this.set("sessionId",n),this.set("hasStartSession",!0),this.persistSession(n,i),this.isTracking&&this.setupSessionTimeout())}}}shareSession(e){this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function"&&this.broadcastChannel.postMessage({action:"session_start",projectId:this.getProjectId(),sessionId:e,timestamp:Date.now()})}broadcastSessionEnd(e,t){if(e&&this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function")try{this.broadcastChannel.postMessage({action:"session_end",projectId:this.getProjectId(),sessionId:e,reason:t,timestamp:Date.now()})}catch(s){o("warn","Failed to broadcast session end",{error:s,data:{sessionId:e,reason:t}})}}cleanupCrossTabSync(){this.broadcastChannel&&(typeof this.broadcastChannel.close=="function"&&this.broadcastChannel.close(),this.broadcastChannel=null)}recoverSession(){const e=this.loadStoredSession();if(!e)return 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 s=JSON.parse(t);return!s.id||typeof s.lastActivity!="number"?null:s}catch{return this.storageManager.removeItem(e),null}}saveStoredSession(e){const t=this.getSessionStorageKey();this.storageManager.setItem(t,JSON.stringify(e))}getSessionStorageKey(){return Xe(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){o("warn","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId(),s=!!e;this.isTracking=!0;try{this.set("sessionId",t),this.persistSession(t),s||this.eventManager.track({type:h.SESSION_START}),this.initCrossTabSync(),this.shareSession(t),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}catch(n){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),n}}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.endSession("inactivity")},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.beforeUnloadHandler||(this.visibilityChangeHandler=()=>{document.hidden?this.clearSessionTimeout():this.get("sessionId")&&this.setupSessionTimeout()},this.beforeUnloadHandler=()=>{this.endSession("page_unload")},document.addEventListener("visibilitychange",this.visibilityChangeHandler),window.addEventListener("beforeunload",this.beforeUnloadHandler))}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}endSession(e){const t=this.get("sessionId");if(!t){o("warn","endSession called without active session",{data:{reason:e}}),this.resetSessionState(e);return}this.eventManager.track({type:h.SESSION_END,session_end_reason:e}),this.eventManager.flushImmediatelySync()||o("warn","Sync flush failed during session end, events persisted for recovery",{data:{reason:e,sessionId:t}}),this.broadcastSessionEnd(t,e),this.resetSessionState(e)}resetSessionState(e){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),e!=="page_unload"&&this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.isTracking=!1}stopTracking(){this.endSession("manual_stop")}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.isTracking=!1,this.set("hasStartSession",!1)}}class ft extends g{eventManager;storageManager;sessionManager=null;destroyed=!1;constructor(e,t){super(),this.eventManager=t,this.storageManager=e}startTracking(){if(this.isActive())return;if(this.destroyed){o("warn","Cannot start tracking on destroyed handler");return}const e=this.get("config"),t=e?.integrations?.tracelog?.projectId??e?.integrations?.custom?.collectApiUrl??"default";if(!t)throw new Error("Cannot start session tracking: config not available");try{this.sessionManager=new ht(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(s){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw o("error","Failed to start session tracking",{error:s}),s}}isActive(){return this.sessionManager!==null&&!this.destroyed}cleanupSessionManager(){this.sessionManager&&(this.sessionManager.stopTracking(),this.sessionManager.destroy(),this.sessionManager=null)}stopTracking(){this.cleanupSessionManager()}destroy(){this.destroyed||(this.sessionManager&&(this.sessionManager.destroy(),this.sessionManager=null),this.destroyed=!0,this.set("hasStartSession",!1))}}class gt extends g{eventManager;onTrack;originalPushState;originalReplaceState;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)}patchHistory(e){const t=window.history[e];e==="pushState"&&!this.originalPushState?this.originalPushState=t:e==="replaceState"&&!this.originalReplaceState&&(this.originalReplaceState=t),window.history[e]=(...s)=>{t.apply(window.history,s),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=j(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;this.onTrack();const s=this.get("pageUrl");this.set("pageUrl",t);const n=this.extractPageViewData();this.eventManager.track({type:h.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:s,...n&&{page_view:n}})};trackInitialPageView(){const e=j(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.eventManager.track({type:h.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{pathname:e,search:t,hash:s}=window.location,{referrer:n}=document,{title:i}=document;return!n&&!i&&!e&&!t&&!s?void 0:{...n&&{referrer:n},...i&&{title:i},...e&&{pathname:e},...t&&{search:t},...s&&{hash:s}}}}class Et extends g{eventManager;clickHandler;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,s=t.target,n=typeof HTMLElement<"u"&&s instanceof HTMLElement?s:typeof HTMLElement<"u"&&s instanceof Node&&s.parentElement instanceof HTMLElement?s.parentElement:null;if(!n){o("warn","Click target not found or not an element");return}const i=this.findTrackingElement(n),a=this.getRelevantClickElement(n),l=this.calculateClickCoordinates(t,n);if(i){const d=this.extractTrackingData(i);if(d){const v=this.createCustomEventData(d);this.eventManager.track({type:h.CUSTOM,custom_event:{name:v.name,...v.value&&{metadata:{value:v.value}}}})}}const c=this.generateClickData(n,a,l);this.eventManager.track({type:h.CLICK,click_data:c})},window.addEventListener("click",this.clickHandler,!0))}stopTracking(){this.clickHandler&&(window.removeEventListener("click",this.clickHandler,!0),this.clickHandler=void 0)}findTrackingElement(e){return e.hasAttribute(`${U}-name`)?e:e.closest(`[${U}-name]`)||void 0}getRelevantClickElement(e){for(const t of be)try{if(e.matches(t))return e;const s=e.closest(t);if(s)return s}catch(s){o("warn","Invalid selector in element search",{error:s,data:{selector:t}});continue}return e}clamp(e){return Math.max(0,Math.min(1,Number(e.toFixed(3))))}calculateClickCoordinates(e,t){const s=t.getBoundingClientRect(),n=e.clientX,i=e.clientY,a=s.width>0?this.clamp((n-s.left)/s.width):0,l=s.height>0?this.clamp((i-s.top)/s.height):0;return{x:n,y:i,relativeX:a,relativeY:l}}extractTrackingData(e){const t=e.getAttribute(`${U}-name`),s=e.getAttribute(`${U}-value`);if(t)return{element:e,name:t,...s&&{value:s}}}generateClickData(e,t,s){const{x:n,y:i,relativeX:a,relativeY:l}=s,c=this.getRelevantText(e,t),d=this.extractElementAttributes(t);return{x:n,y:i,relativeX:a,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}}}getRelevantText(e,t){const s=e.textContent?.trim()??"",n=t.textContent?.trim()??"";return!s&&!n?"":s&&s.length<=255?s:n.length<=255?n:n.slice(0,252)+"..."}extractElementAttributes(e){const t=["id","class","data-testid","aria-label","title","href","type","name","alt","role"],s={};for(const n of t){const i=e.getAttribute(n);i&&(s[n]=i)}return s}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class St extends g{eventManager;containers=[];limitWarningLogged=!1;minDepthChange=5;minIntervalMs=500;maxEventsPerSession=120;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.applyConfigOverrides(),this.set("scrollEventCount",0);const e=this.get("config").scrollContainerSelectors,t=Array.isArray(e)?e:typeof e=="string"?[e]:[];t.length===0?this.setupScrollContainer(window):this.trySetupContainers(t,0)}stopTracking(){for(const e of this.containers)this.clearContainerTimer(e),e.element instanceof Window?window.removeEventListener("scroll",e.listener):e.element.removeEventListener("scroll",e.listener);this.containers.length=0,this.set("scrollEventCount",0),this.limitWarningLogged=!1}trySetupContainers(e,t){const s=e.map(n=>this.safeQuerySelector(n)).filter(n=>n!=null&&typeof HTMLElement<"u"&&n instanceof HTMLElement);if(s.length>0){for(const n of s)this.containers.some(a=>a.element===n)||this.setupScrollContainer(n);return}if(t<5){setTimeout(()=>{this.trySetupContainers(e,t+1)},200);return}this.containers.length===0&&this.setupScrollContainer(window)}setupScrollContainer(e){if(e!==window&&!this.isElementScrollable(e))return;const t=()=>{this.get("suppressNextScroll")||(this.clearContainerTimer(n),n.debounceTimer=window.setTimeout(()=>{const i=this.calculateScrollData(n);if(i){const a=Date.now();this.processScrollEvent(n,i,a)}n.debounceTimer=null},250))},s=this.getScrollTop(e),n={element:e,lastScrollPos:s,lastDepth:this.calculateScrollDepth(s,this.getScrollHeight(e),this.getViewportHeight(e)),lastDirection:b.DOWN,lastEventTime:0,debounceTimer:null,listener:t};this.containers.push(n),e instanceof Window?window.addEventListener("scroll",t,{passive:!0}):e.addEventListener("scroll",t,{passive:!0})}processScrollEvent(e,t,s){if(!this.shouldEmitScrollEvent(e,t,s))return;e.lastEventTime=s,e.lastDepth=t.depth,e.lastDirection=t.direction;const n=this.get("scrollEventCount")??0;this.set("scrollEventCount",n+1),this.eventManager.track({type:h.SCROLL,scroll_data:t})}shouldEmitScrollEvent(e,t,s){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,s)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=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,o("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?b.DOWN:b.UP}calculateScrollDepth(e,t,s){if(t<=s)return 0;const n=t-s;return Math.min(100,Math.max(0,Math.floor(e/n*100)))}calculateScrollData(e){const{element:t,lastScrollPos:s}=e,n=this.getScrollTop(t);if(Math.abs(n-s)<10||t===window&&!this.isWindowScrollable())return null;const a=this.getViewportHeight(t),l=this.getScrollHeight(t),c=this.getScrollDirection(n,s),d=this.calculateScrollDepth(n,l,a);return e.lastScrollPos=n,{depth:d,direction:c}}getScrollTop(e){return e instanceof Window?window.scrollY:e.scrollTop}getViewportHeight(e){return e instanceof Window?window.innerHeight:e.clientHeight}getScrollHeight(e){return e instanceof Window?document.documentElement.scrollHeight:e.scrollHeight}isElementScrollable(e){const t=getComputedStyle(e),s=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflowX==="auto"||t.overflowX==="scroll"||t.overflow==="auto"||t.overflow==="scroll",n=e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth;return s&&n}safeQuerySelector(e){try{return document.querySelector(e)}catch(t){return o("warn","Invalid CSS selector",{error:t,data:{selector:e},showToClient:!0}),null}}}class _t extends g{isInitialized=!1;async initialize(){if(this.isInitialized)return;const e=this.get("config").integrations?.googleAnalytics?.measurementId,t=this.get("userId");if(!(!e?.trim()||!t?.trim()))try{if(this.isScriptAlreadyLoaded()){this.isInitialized=!0;return}await this.loadScript(e),this.configureGtag(e,t),this.isInitialized=!0}catch(s){o("error","Google Analytics initialization failed",{error:s})}}trackEvent(e,t){if(!(!e?.trim()||!this.isInitialized||typeof window.gtag!="function"))try{const s=Array.isArray(t)?{items:t}:t;window.gtag("event",e,s)}catch(s){o("error","Google Analytics event tracking failed",{error:s})}}cleanup(){this.isInitialized=!1;const e=document.getElementById("tracelog-ga-script");e&&e.remove()}isScriptAlreadyLoaded(){return document.getElementById("tracelog-ga-script")?!0:!!document.querySelector('script[src*="googletagmanager.com/gtag/js"]')}async loadScript(e){return new Promise((t,s)=>{const n=document.createElement("script");n.id="tracelog-ga-script",n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${e}`,n.onload=()=>{t()},n.onerror=()=>{s(new Error("Failed to load Google Analytics script"))},document.head.appendChild(n)})}configureGtag(e,t){const s=document.createElement("script");s.innerHTML=`
1
+ (function(u){"use strict";const k="data-tlog",be=["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"]'],Pe=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"],m={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_GOOGLE_ANALYTICS_ID:"Google Analytics measurement ID is required when integration is enabled",INVALID_SCROLL_CONTAINER_SELECTORS:"Scroll container selectors must be valid CSS selectors",INVALID_GLOBAL_METADATA:"Global metadata must be an object",INVALID_SENSITIVE_QUERY_PARAMS:"Sensitive query params must be an array of strings"},De=[/<script\b[^<]*(?:(?!<\/script>)<[^<]*)*<\/script>/gi,/javascript:/gi,/on\w+\s*=/gi,/<iframe\b[^<]*(?:(?!<\/iframe>)<[^<]*)*<\/iframe>/gi,/<embed\b[^>]*>/gi,/<object\b[^<]*(?:(?!<\/object>)<[^<]*)*<\/object>/gi];var H=(r=>(r.Localhost="localhost:8080",r.Fail="localhost:9999",r))(H||{}),T=(r=>(r.Mobile="mobile",r.Tablet="tablet",r.Desktop="desktop",r.Unknown="unknown",r))(T||{}),U=(r=>(r.EVENT="event",r.QUEUE="queue",r))(U||{});class A extends Error{constructor(e,t){super(e),this.statusCode=t,this.name="PermanentError",Error.captureStackTrace&&Error.captureStackTrace(this,A)}}var h=(r=>(r.PAGE_VIEW="page_view",r.CLICK="click",r.SCROLL="scroll",r.SESSION_START="session_start",r.SESSION_END="session_end",r.CUSTOM="custom",r.WEB_VITALS="web_vitals",r.ERROR="error",r))(h||{}),b=(r=>(r.UP="up",r.DOWN="down",r))(b||{}),w=(r=>(r.JS_ERROR="js_error",r.PROMISE_REJECTION="promise_rejection",r))(w||{}),M=(r=>(r.QA="qa",r))(M||{});class L extends Error{constructor(e,t,s){super(e),this.errorCode=t,this.layer=s,this.name=this.constructor.name,Error.captureStackTrace&&Error.captureStackTrace(this,this.constructor)}}class y extends L{constructor(e,t="config"){super(e,"APP_CONFIG_INVALID",t)}}class ce extends L{constructor(e,t="config"){super(e,"SESSION_TIMEOUT_INVALID",t)}}class B extends L{constructor(e,t="config"){super(e,"SAMPLING_RATE_INVALID",t)}}class p extends L{constructor(e,t="config"){super(e,"INTEGRATION_INVALID",t)}}class ke extends L{constructor(e,t,s="runtime"){super(e,"INITIALIZATION_TIMEOUT",s),this.timeoutMs=t}}const He=(r,e)=>{if(e){if(e instanceof Error){const t=e.message.replace(/\s+at\s+.*$/gm,"").replace(/\(.*?:\d+:\d+\)/g,"");return`[TraceLog] ${r}: ${t}`}return`[TraceLog] ${r}: ${e instanceof Error?e.message:"Unknown error"}`}return`[TraceLog] ${r}`},o=(r,e,t)=>{const{error:s,data:n,showToClient:i=!1}=t??{},a=s?He(e,s):`[TraceLog] ${e}`,l=r==="error"?"error":r==="warn"?"warn":"log";if(!(r==="debug"||r==="info"&&!i))if(n!==void 0){const c=Ue(n);console[l](a,c)}else n!==void 0?console[l](a,n):console[l](a)},Ue=r=>{const e={},t=["token","password","secret","key","apikey","api_key","sessionid","session_id"];for(const[s,n]of Object.entries(r)){const i=s.toLowerCase();t.some(a=>i.includes(a))?e[s]="[REDACTED]":e[s]=n}return e};let Y,ue;const Ve=()=>{typeof window<"u"&&!Y&&(Y=window.matchMedia("(pointer: coarse)"),ue=window.matchMedia("(hover: none)"))},Ge=()=>{try{const r=navigator;if(r.userAgentData&&typeof r.userAgentData.mobile=="boolean")return r.userAgentData.platform&&/ipad|tablet/i.test(r.userAgentData.platform)?T.Tablet:r.userAgentData.mobile?T.Mobile:T.Desktop;Ve();const e=window.innerWidth,t=Y?.matches??!1,s=ue?.matches??!1,n="ontouchstart"in window||navigator.maxTouchPoints>0,i=navigator.userAgent.toLowerCase(),a=/mobile|android|iphone|ipod|blackberry|iemobile|opera mini/.test(i),l=/tablet|ipad|android(?!.*mobile)/.test(i);return e<=767||a&&n?T.Mobile:e>=768&&e<=1024||l||t&&s&&n?T.Tablet:T.Desktop}catch(r){return o("warn","Device detection failed, defaulting to desktop",{error:r}),T.Desktop}},I="tlog",de=`${I}:qa_mode`,Fe=`${I}:uid`,xe=r=>r?`${I}:${r}:queue`:`${I}:queue`,Xe=r=>r?`${I}:${r}:session`:`${I}:session`,$e=r=>r?`${I}:${r}:broadcast`:`${I}:broadcast`,he={LCP:4e3,FCP:1800,CLS:.25,INP:200,TTFB:800,LONG_TASK:50},ze=1e3,fe=[/\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],ge=500,Ee=5e3,V=50,Qe=V*2,Be=6e4,Se="tlog_mode",Ye="qa",je=()=>{if(sessionStorage.getItem(de)==="true")return!0;const e=new URLSearchParams(window.location.search),s=e.get(Se)===Ye;if(s){sessionStorage.setItem(de,"true"),e.delete(Se);const n=e.toString(),i=`${window.location.pathname}${n?"?"+n:""}${window.location.hash}`;try{window.history.replaceState({},"",i)}catch(a){o("warn","History API not available, cannot replace URL",{error:a})}console.log("%c[TraceLog] QA Mode ACTIVE","background: #ff9800; color: white; font-weight: bold; padding: 2px 8px; border-radius: 3px;")}return s},_e=()=>{const r=new URLSearchParams(window.location.search),e={};return Pe.forEach(s=>{const n=r.get(s);if(n){const i=s.split("utm_")[1];e[i]=n}}),Object.keys(e).length?e:void 0},We=()=>typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,r=>{const e=Math.random()*16|0;return(r==="x"?e:e&3|8).toString(16)}),Ke=()=>{const r=Date.now();let e="";try{if(typeof crypto<"u"&&crypto.getRandomValues){const t=crypto.getRandomValues(new Uint8Array(4));t&&(e=Array.from(t,s=>s.toString(16).padStart(2,"0")).join(""))}}catch{}return e||(e=Math.floor(Math.random()*4294967295).toString(16).padStart(8,"0")),`${r}-${e}`},me=(r,e=!1)=>{try{const t=new URL(r),s=t.protocol==="https:",n=t.protocol==="http:";return s||e&&n}catch{return!1}},qe=r=>{if(r.integrations?.tracelog?.projectId){const n=new URL(window.location.href).hostname.split(".");if(n.length===0)throw new Error("Invalid URL");const i=r.integrations.tracelog.projectId,a=n.slice(-2).join("."),l=`https://${i}.${a}/collect`;if(!me(l))throw new Error("Invalid URL");return l}const e=r.integrations?.custom?.collectApiUrl;if(e){const t=r.integrations?.custom?.allowHttp??!1;if(!me(e,t))throw new Error("Invalid URL");return e}return""},j=(r,e=[])=>{try{const t=new URL(r),s=t.searchParams;let n=!1;const i=[];return e.forEach(l=>{s.has(l)&&(s.delete(l),n=!0,i.push(l))}),!n&&r.includes("?")?r:(t.search=s.toString(),t.toString())}catch(t){return o("warn","URL normalization failed, returning original",{error:t,data:{url:r.slice(0,100)}}),r}},Te=r=>{if(!r||typeof r!="string"||r.trim().length===0)return"";let e=r;r.length>1e3&&(e=r.slice(0,Math.max(0,1e3)));let t=0;for(const n of De){const i=e;e=e.replace(n,""),i!==e&&t++}return t>0&&o("warn","XSS patterns detected and removed",{data:{patternMatches:t,originalValue:r.slice(0,100)}}),e=e.replaceAll("&","&amp;").replaceAll("<","&lt;").replaceAll(">","&gt;").replaceAll('"',"&quot;").replaceAll("'","&#x27;").replaceAll("/","&#x2F;"),e.trim()},W=(r,e=0)=>{if(e>3||r==null)return null;if(typeof r=="string")return Te(r);if(typeof r=="number")return!Number.isFinite(r)||r<-Number.MAX_SAFE_INTEGER||r>Number.MAX_SAFE_INTEGER?0:r;if(typeof r=="boolean")return r;if(Array.isArray(r))return r.slice(0,100).map(n=>W(n,e+1)).filter(n=>n!==null);if(typeof r=="object"){const t={},n=Object.entries(r).slice(0,20);for(const[i,a]of n){const l=Te(i);if(l){const c=W(a,e+1);c!==null&&(t[l]=c)}}return t}return null},Ze=r=>{if(typeof r!="object"||r===null)return{};try{const e=W(r);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}`)}},Je=r=>{if(r!==void 0&&(r===null||typeof r!="object"))throw new y("Configuration must be an object","config");if(r){if(r.sessionTimeout!==void 0&&(typeof r.sessionTimeout!="number"||r.sessionTimeout<3e4||r.sessionTimeout>864e5))throw new ce(m.INVALID_SESSION_TIMEOUT,"config");if(r.globalMetadata!==void 0&&(typeof r.globalMetadata!="object"||r.globalMetadata===null))throw new y(m.INVALID_GLOBAL_METADATA,"config");if(r.scrollContainerSelectors!==void 0&&tt(r.scrollContainerSelectors),r.integrations&&rt(r.integrations),r.sensitiveQueryParams!==void 0){if(!Array.isArray(r.sensitiveQueryParams))throw new y(m.INVALID_SENSITIVE_QUERY_PARAMS,"config");for(const e of r.sensitiveQueryParams)if(typeof e!="string")throw new y("All sensitive query params must be strings","config")}if(r.errorSampling!==void 0&&(typeof r.errorSampling!="number"||r.errorSampling<0||r.errorSampling>1))throw new B(m.INVALID_ERROR_SAMPLING_RATE,"config");if(r.samplingRate!==void 0&&(typeof r.samplingRate!="number"||r.samplingRate<0||r.samplingRate>1))throw new B(m.INVALID_SAMPLING_RATE,"config")}},et=r=>{if(r.includes("<")||r.includes(">")||/on\w+\s*=/i.test(r)||!/^[a-zA-Z0-9\-_#.[\]="':, >+~*()]+$/.test(r))return!1;let t=0;for(const n of r)if(n==="("&&t++,n===")"&&t--,t<0)return!1;if(t!==0)return!1;let s=0;for(const n of r)if(n==="["&&s++,n==="]"&&s--,s<0)return!1;return s===0},tt=r=>{const e=Array.isArray(r)?r:[r];for(const t of e){if(typeof t!="string"||t.trim()==="")throw o("error","Invalid scroll container selector",{showToClient:!0,data:{selector:t,type:typeof t,isEmpty:t===""||typeof t=="string"&&t.trim()===""}}),new y(m.INVALID_SCROLL_CONTAINER_SELECTORS,"config");if(!et(t))throw o("error","Invalid or potentially unsafe CSS selector",{showToClient:!0,data:{selector:t,reason:"Failed security validation"}}),new y("Invalid or potentially unsafe CSS selector","config")}},rt=r=>{if(r){if(r.tracelog&&(!r.tracelog.projectId||typeof r.tracelog.projectId!="string"||r.tracelog.projectId.trim()===""))throw new p(m.INVALID_TRACELOG_PROJECT_ID,"config");if(r.custom){if(!r.custom.collectApiUrl||typeof r.custom.collectApiUrl!="string"||r.custom.collectApiUrl.trim()==="")throw new p(m.INVALID_CUSTOM_API_URL,"config");if(r.custom.allowHttp!==void 0&&typeof r.custom.allowHttp!="boolean")throw new p("allowHttp must be a boolean","config");const e=r.custom.collectApiUrl.trim();if(!e.startsWith("http://")&&!e.startsWith("https://"))throw new p('Custom API URL must start with "http://" or "https://"',"config");if(!(r.custom.allowHttp??!1)&&e.startsWith("http://"))throw new p("Custom API URL must use HTTPS in production. Set allowHttp: true in integration config to allow HTTP (not recommended)","config")}if(r.googleAnalytics){if(!r.googleAnalytics.measurementId||typeof r.googleAnalytics.measurementId!="string"||r.googleAnalytics.measurementId.trim()==="")throw new p(m.INVALID_GOOGLE_ANALYTICS_ID,"config");if(!r.googleAnalytics.measurementId.trim().match(/^(G-|UA-)/))throw new p('Google Analytics measurement ID must start with "G-" or "UA-"',"config")}}},st=r=>{Je(r);const e={...r??{},sessionTimeout:r?.sessionTimeout??9e5,globalMetadata:r?.globalMetadata??{},sensitiveQueryParams:r?.sensitiveQueryParams??[],errorSampling:r?.errorSampling??1,samplingRate:r?.samplingRate??1};return e.integrations?.custom&&(e.integrations.custom={...e.integrations.custom,allowHttp:e.integrations.custom.allowHttp??!1}),e},nt=r=>{if(typeof r=="string")return!0;if(typeof r=="object"&&r!==null&&!Array.isArray(r)){const e=Object.entries(r);if(e.length>20)return!1;for(const[,t]of e){if(t==null)continue;const s=typeof t;if(s!=="string"&&s!=="number"&&s!=="boolean")return!1}return!0}return!1},pe=(r,e=0)=>{if(typeof r!="object"||r===null||e>1)return!1;for(const t of Object.values(r)){if(t==null)continue;const s=typeof t;if(!(s==="string"||s==="number"||s==="boolean")){if(Array.isArray(t)){if(t.length===0)continue;if(typeof t[0]=="string"){if(!t.every(a=>typeof a=="string"))return!1}else if(!t.every(a=>nt(a)))return!1;continue}if(s==="object"&&e===0){if(!pe(t,e+1))return!1;continue}return!1}}return!0},it=r=>typeof r!="string"?{valid:!1,error:"Event name must be a string"}:r.length===0?{valid:!1,error:"Event name cannot be empty"}:r.length>120?{valid:!1,error:"Event name is too long (max 120 characters)"}:r.includes("<")||r.includes(">")||r.includes("&")?{valid:!1,error:"Event name contains invalid characters"}:["constructor","prototype","__proto__","eval","function","var","let","const"].includes(r.toLowerCase())?{valid:!1,error:"Event name cannot be a reserved word"}:{valid:!0},Ie=(r,e,t)=>{const s=Ze(e),n=`${t} "${r}" metadata error`;if(!pe(s))return{valid:!1,error:`${n}: object has invalid types. Valid types are string, number, boolean or string arrays.`};let i;try{i=JSON.stringify(s)}catch{return{valid:!1,error:`${n}: object contains circular references or cannot be serialized.`}}if(i.length>8192)return{valid:!1,error:`${n}: object is too large (max ${8192/1024} KB).`};if(Object.keys(s).length>10)return{valid:!1,error:`${n}: object has too many keys (max 10 keys).`};for(const[l,c]of Object.entries(s)){if(Array.isArray(c)){if(c.length>10)return{valid:!1,error:`${n}: 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:`${n}: array property "${l}" contains strings that are too long (max 500 characters).`}}if(typeof c=="string"&&c.length>1e3)return{valid:!1,error:`${n}: property "${l}" is too long (max 1000 characters).`}}return{valid:!0,sanitizedMetadata:s}},at=(r,e,t)=>{if(Array.isArray(e)){const s=[],n=`${t} "${r}" metadata error`;for(let i=0;i<e.length;i++){const a=e[i];if(typeof a!="object"||a===null||Array.isArray(a))return{valid:!1,error:`${n}: array item at index ${i} must be an object.`};const l=Ie(r,a,t);if(!l.valid)return{valid:!1,error:`${n}: array item at index ${i} is invalid: ${l.error}`};l.sanitizedMetadata&&s.push(l.sanitizedMetadata)}return{valid:!0,sanitizedMetadata:s}}return Ie(r,e,t)},ot=(r,e)=>{const t=it(r);if(!t.valid)return o("error","Event name validation failed",{showToClient:!0,data:{eventName:r,error:t.error}}),t;if(!e)return{valid:!0};const s=at(r,e,"customEvent");return s.valid||o("error","Event metadata validation failed",{showToClient:!0,data:{eventName:r,error:s.error}}),s};class lt{listeners=new Map;on(e,t){this.listeners.has(e)||this.listeners.set(e,[]),this.listeners.get(e).push(t)}off(e,t){const s=this.listeners.get(e);if(s){const n=s.indexOf(t);n>-1&&s.splice(n,1)}}emit(e,t){const s=this.listeners.get(e);s&&s.forEach(n=>{n(t)})}removeAllListeners(){this.listeners.clear()}}const K={};class g{get(e){return K[e]}set(e,t){K[e]=t}getState(){return{...K}}}class ct extends g{storeManager;lastPermanentErrorLog=null;constructor(e){super(),this.storeManager=e}getQueueStorageKey(){const e=this.get("userId")||"anonymous";return xe(e)}sendEventsQueueSync(e){return this.shouldSkipSend()?!0:this.get("config")?.integrations?.custom?.collectApiUrl===H.Fail?(o("warn","Fail mode: simulating network failure (sync)",{data:{events:e.events.length}}),!1):this.sendQueueSyncInternal(e)}async sendEventsQueue(e,t){try{const s=await this.send(e);return s?(this.clearPersistedEvents(),t?.onSuccess?.(e.events.length,e.events,e)):(this.persistEvents(e),t?.onFailure?.()),s}catch(s){return s instanceof A?(this.logPermanentError("Permanent error, not retrying",s),this.clearPersistedEvents(),t?.onFailure?.(),!1):(this.persistEvents(e),t?.onFailure?.(),!1)}}async recoverPersistedEvents(e){try{const t=this.getPersistedData();if(!t||!this.isDataRecent(t)||t.events.length===0){this.clearPersistedEvents();return}const s=this.createRecoveryBody(t);await this.send(s)?(this.clearPersistedEvents(),e?.onSuccess?.(t.events.length,t.events,s)):e?.onFailure?.()}catch(t){if(t instanceof A){this.logPermanentError("Permanent error during recovery, clearing persisted events",t),this.clearPersistedEvents(),e?.onFailure?.();return}o("error","Failed to recover persisted events",{error:t})}}stop(){}async send(e){if(this.shouldSkipSend())return this.simulateSuccessfulSend();if(this.get("config")?.integrations?.custom?.collectApiUrl===H.Fail)return o("warn","Fail mode: simulating network failure",{data:{events:e.events.length}}),!1;const{url:s,payload:n}=this.prepareRequest(e);try{return(await this.sendWithTimeout(s,n)).ok}catch(i){if(i instanceof A)throw i;return o("error","Send request failed",{error:i,data:{events:e.events.length,url:s.replace(/\/\/[^/]+/,"//[DOMAIN]")}}),!1}}async sendWithTimeout(e,t){const s=new AbortController,n=setTimeout(()=>{s.abort()},1e4);try{const i=await fetch(e,{method:"POST",body:t,keepalive:!0,credentials:"include",signal:s.signal,headers:{"Content-Type":"application/json"}});if(!i.ok)throw i.status>=400&&i.status<500?new A(`HTTP ${i.status}: ${i.statusText}`,i.status):new Error(`HTTP ${i.status}: ${i.statusText}`);return i}finally{clearTimeout(n)}}sendQueueSyncInternal(e){const{url:t,payload:s}=this.prepareRequest(e),n=new Blob([s],{type:"application/json"});if(!this.isSendBeaconAvailable())return o("warn","sendBeacon not available, persisting events for recovery"),this.persistEvents(e),!1;const i=navigator.sendBeacon(t,n);return i||(o("warn","sendBeacon rejected request, persisting events for recovery"),this.persistEvents(e)),i}prepareRequest(e){const t={...e,_metadata:{referer:typeof window<"u"?window.location.href:void 0,timestamp:Date.now()}};return{url:this.get("collectApiUrl"),payload:JSON.stringify(t)}}getPersistedData(){try{const e=this.getQueueStorageKey(),t=this.storeManager.getItem(e);if(t)return JSON.parse(t)}catch(e){o("warn","Failed to parse persisted data",{error:e}),this.clearPersistedEvents()}return null}isDataRecent(e){return!e.timestamp||typeof e.timestamp!="number"?!1:(Date.now()-e.timestamp)/(1e3*60*60)<2}createRecoveryBody(e){return{user_id:e.userId,session_id:e.sessionId,device:e.device,events:e.events,...e.global_metadata&&{global_metadata:e.global_metadata}}}persistEvents(e){try{const t={userId:e.user_id,sessionId:e.session_id,device:e.device,events:e.events,timestamp:Date.now(),...e.global_metadata&&{global_metadata:e.global_metadata}},s=this.getQueueStorageKey();return this.storeManager.setItem(s,JSON.stringify(t)),!!this.storeManager.getItem(s)}catch(t){return o("warn","Failed to persist events",{error:t}),!1}}clearPersistedEvents(){try{const e=this.getQueueStorageKey();this.storeManager.removeItem(e)}catch(e){o("warn","Failed to clear persisted events",{error:e})}}shouldSkipSend(){return!this.get("collectApiUrl")}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 s=Date.now();(!this.lastPermanentErrorLog||this.lastPermanentErrorLog.statusCode!==t.statusCode||s-this.lastPermanentErrorLog.timestamp>=Be)&&(o("error",e,{data:{status:t.statusCode,message:t.message}}),this.lastPermanentErrorLog={statusCode:t.statusCode,timestamp:s})}}class ut extends g{googleAnalytics;dataSender;emitter;eventsQueue=[];pendingEventsBuffer=[];lastEventFingerprint=null;lastEventTime=0;sendIntervalId=null;rateLimitCounter=0;rateLimitWindowStart=0;constructor(e,t=null,s=null){super(),this.googleAnalytics=t,this.dataSender=new ct(e),this.emitter=s}async recoverPersistedEvents(){await this.dataSender.recoverPersistedEvents({onSuccess:(e,t,s)=>{if(t&&t.length>0){const n=t.map(i=>i.id);this.removeProcessedEvents(n),s&&this.emitEventsQueue(s)}},onFailure:()=>{o("warn","Failed to recover persisted events")}})}track({type:e,page_url:t,from_page_url:s,scroll_data:n,click_data:i,custom_event:a,web_vitals:l,error_data:c,session_end_reason:d}){if(!e){o("error","Event type is required - event will be ignored");return}if(!this.get("sessionId")){this.pendingEventsBuffer.length>=100&&(this.pendingEventsBuffer.shift(),o("warn","Pending events buffer full - dropping oldest event",{data:{maxBufferSize:100}})),this.pendingEventsBuffer.push({type:e,page_url:t,from_page_url:s,scroll_data:n,click_data:i,custom_event:a,web_vitals:l,error_data:c,session_end_reason:d});return}const v=e===h.SESSION_START||e===h.SESSION_END;if(!v&&!this.checkRateLimit())return;const D=e,Jt=D===h.SESSION_START,er=t||this.get("pageUrl"),le=this.buildEventPayload({type:D,page_url:er,from_page_url:s,scroll_data:n,click_data:i,custom_event:a,web_vitals:l,error_data:c,session_end_reason:d});if(!(!v&&!this.shouldSample())){if(Jt){const Oe=this.get("sessionId");if(!Oe){o("error","Session start event requires sessionId - event will be ignored");return}if(this.get("hasStartSession")){o("warn","Duplicate session_start detected",{data:{sessionId:Oe}});return}this.set("hasStartSession",!0)}if(!this.isDuplicateEvent(le)){if(this.get("mode")===M.QA&&D===h.CUSTOM&&a){console.log("[TraceLog] Event",{name:a.name,...a.metadata&&{metadata:a.metadata}}),this.emitEvent(le);return}this.addToQueue(le)}}}stop(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null),this.eventsQueue=[],this.pendingEventsBuffer=[],this.lastEventFingerprint=null,this.lastEventTime=0,this.rateLimitCounter=0,this.rateLimitWindowStart=0,this.dataSender.stop()}async flushImmediately(){return this.flushEvents(!1)}flushImmediatelySync(){return this.flushEvents(!0)}getQueueLength(){return this.eventsQueue.length}flushPendingEvents(){if(this.pendingEventsBuffer.length===0)return;if(!this.get("sessionId")){o("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(s=>{this.track(s)})}clearSendInterval(){this.sendIntervalId&&(clearInterval(this.sendIntervalId),this.sendIntervalId=null)}flushEvents(e){if(this.eventsQueue.length===0)return e?!0:Promise.resolve(!0);const t=this.buildEventsPayload(),s=[...this.eventsQueue],n=s.map(i=>i.id);if(e){const i=this.dataSender.sendEventsQueueSync(t);return i&&(this.removeProcessedEvents(n),this.clearSendInterval(),this.emitEventsQueue(t)),i}else return this.dataSender.sendEventsQueue(t,{onSuccess:()=>{this.removeProcessedEvents(n),this.clearSendInterval(),this.emitEventsQueue(t)},onFailure:()=>{o("warn","Async flush failed",{data:{eventCount:s.length}})}})}async sendEventsQueue(){if(!this.get("sessionId")||this.eventsQueue.length===0)return;const e=this.buildEventsPayload(),t=[...this.eventsQueue],s=t.map(n=>n.id);await this.dataSender.sendEventsQueue(e,{onSuccess:()=>{this.removeProcessedEvents(s),this.emitEventsQueue(e)},onFailure:()=>{o("warn","Events send failed, keeping in queue",{data:{eventCount:t.length}})}})}buildEventsPayload(){const e=new Map,t=[];for(const n of this.eventsQueue){const i=this.createEventSignature(n);e.has(i)||t.push(i),e.set(i,n)}const s=t.map(n=>e.get(n)).filter(n=>!!n).sort((n,i)=>n.timestamp-i.timestamp);return{user_id:this.get("userId"),session_id:this.get("sessionId"),device:this.get("device"),events:s,...this.get("config")?.globalMetadata&&{global_metadata:this.get("config")?.globalMetadata}}}buildEventPayload(e){const t=e.type===h.SESSION_START,s=e.page_url??this.get("pageUrl");return{id:Ke(),type:e.type,page_url:s,timestamp:Date.now(),...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.session_end_reason&&{session_end_reason:e.session_end_reason},...t&&_e()&&{utm:_e()}}}isDuplicateEvent(e){const t=Date.now(),s=this.createEventFingerprint(e);return this.lastEventFingerprint===s&&t-this.lastEventTime<500?!0:(this.lastEventFingerprint=s,this.lastEventTime=t,!1)}createEventFingerprint(e){let t=`${e.type}_${e.page_url}`;if(e.click_data){const s=Math.round((e.click_data.x||0)/10)*10,n=Math.round((e.click_data.y||0)/10)*10;t+=`_click_${s}_${n}`}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.eventsQueue.push(e),this.emitEvent(e),this.eventsQueue.length>100){const t=this.eventsQueue.findIndex(n=>n.type!==h.SESSION_START&&n.type!==h.SESSION_END),s=t>=0?this.eventsQueue.splice(t,1)[0]:this.eventsQueue.shift();o("warn","Event queue overflow, oldest non-critical event removed",{data:{maxLength:100,currentLength:this.eventsQueue.length,removedEventType:s?.type,wasCritical:s?.type===h.SESSION_START||s?.type===h.SESSION_END}})}this.sendIntervalId||this.startSendInterval(),this.handleGoogleAnalyticsIntegration(e)}startSendInterval(){this.sendIntervalId=window.setInterval(()=>{this.eventsQueue.length>0&&this.sendEventsQueue()},1e4)}handleGoogleAnalyticsIntegration(e){if(this.googleAnalytics&&e.type===h.CUSTOM&&e.custom_event){if(this.get("mode")===M.QA)return;this.googleAnalytics.trackEvent(e.custom_event.name,e.custom_event.metadata??{})}}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>=200?!1:(this.rateLimitCounter++,!0)}removeProcessedEvents(e){const t=new Set(e);this.eventsQueue=this.eventsQueue.filter(s=>!t.has(s.id))}emitEvent(e){this.emitter&&this.emitter.emit(U.EVENT,e)}emitEventsQueue(e){this.emitter&&this.emitter.emit(U.QUEUE,e)}}class dt{static getId(e){const t=Fe,s=e.getItem(t);if(s)return s;const n=We();return e.setItem(t,n),n}}class ht extends g{storageManager;eventManager;projectId;sessionTimeoutId=null;broadcastChannel=null;activityHandler=null;visibilityChangeHandler=null;beforeUnloadHandler=null;isTracking=!1;constructor(e,t,s){super(),this.storageManager=e,this.eventManager=t,this.projectId=s}initCrossTabSync(){if(typeof BroadcastChannel>"u"){o("warn","BroadcastChannel not supported");return}const e=this.getProjectId();this.broadcastChannel=new BroadcastChannel($e(e)),this.broadcastChannel.onmessage=t=>{const{action:s,sessionId:n,timestamp:i,projectId:a}=t.data??{};if(a===e){if(s==="session_end"){this.resetSessionState();return}n&&typeof i=="number"&&i>Date.now()-5e3&&(this.set("sessionId",n),this.set("hasStartSession",!0),this.persistSession(n,i),this.isTracking&&this.setupSessionTimeout())}}}shareSession(e){this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function"&&this.broadcastChannel.postMessage({action:"session_start",projectId:this.getProjectId(),sessionId:e,timestamp:Date.now()})}broadcastSessionEnd(e,t){if(e&&this.broadcastChannel&&typeof this.broadcastChannel.postMessage=="function")try{this.broadcastChannel.postMessage({action:"session_end",projectId:this.getProjectId(),sessionId:e,reason:t,timestamp:Date.now()})}catch(s){o("warn","Failed to broadcast session end",{error:s,data:{sessionId:e,reason:t}})}}cleanupCrossTabSync(){this.broadcastChannel&&(typeof this.broadcastChannel.close=="function"&&this.broadcastChannel.close(),this.broadcastChannel=null)}recoverSession(){const e=this.loadStoredSession();if(!e)return 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 s=JSON.parse(t);return!s.id||typeof s.lastActivity!="number"?null:s}catch{return this.storageManager.removeItem(e),null}}saveStoredSession(e){const t=this.getSessionStorageKey();this.storageManager.setItem(t,JSON.stringify(e))}getSessionStorageKey(){return Xe(this.getProjectId())}getProjectId(){return this.projectId}startTracking(){if(this.isTracking){o("warn","Session tracking already active");return}const e=this.recoverSession(),t=e??this.generateSessionId(),s=!!e;this.isTracking=!0;try{this.set("sessionId",t),this.persistSession(t),s||this.eventManager.track({type:h.SESSION_START}),this.initCrossTabSync(),this.shareSession(t),this.setupSessionTimeout(),this.setupActivityListeners(),this.setupLifecycleListeners()}catch(n){throw this.isTracking=!1,this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),this.set("sessionId",null),n}}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.endSession("inactivity")},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.beforeUnloadHandler||(this.visibilityChangeHandler=()=>{document.hidden?this.clearSessionTimeout():this.get("sessionId")&&this.setupSessionTimeout()},this.beforeUnloadHandler=()=>{this.endSession("page_unload")},document.addEventListener("visibilitychange",this.visibilityChangeHandler),window.addEventListener("beforeunload",this.beforeUnloadHandler))}cleanupLifecycleListeners(){this.visibilityChangeHandler&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.beforeUnloadHandler&&(window.removeEventListener("beforeunload",this.beforeUnloadHandler),this.beforeUnloadHandler=null)}endSession(e){const t=this.get("sessionId");if(!t){o("warn","endSession called without active session",{data:{reason:e}}),this.resetSessionState(e);return}this.eventManager.track({type:h.SESSION_END,session_end_reason:e}),this.eventManager.flushImmediatelySync()||o("warn","Sync flush failed during session end, events persisted for recovery",{data:{reason:e,sessionId:t}}),this.broadcastSessionEnd(t,e),this.resetSessionState(e)}resetSessionState(e){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupLifecycleListeners(),this.cleanupCrossTabSync(),e!=="page_unload"&&this.clearStoredSession(),this.set("sessionId",null),this.set("hasStartSession",!1),this.isTracking=!1}stopTracking(){this.endSession("manual_stop")}destroy(){this.clearSessionTimeout(),this.cleanupActivityListeners(),this.cleanupCrossTabSync(),this.cleanupLifecycleListeners(),this.isTracking=!1,this.set("hasStartSession",!1)}}class ft extends g{eventManager;storageManager;sessionManager=null;destroyed=!1;constructor(e,t){super(),this.eventManager=t,this.storageManager=e}startTracking(){if(this.isActive())return;if(this.destroyed){o("warn","Cannot start tracking on destroyed handler");return}const e=this.get("config"),t=e?.integrations?.tracelog?.projectId??e?.integrations?.custom?.collectApiUrl??"default";if(!t)throw new Error("Cannot start session tracking: config not available");try{this.sessionManager=new ht(this.storageManager,this.eventManager,t),this.sessionManager.startTracking(),this.eventManager.flushPendingEvents()}catch(s){if(this.sessionManager){try{this.sessionManager.destroy()}catch{}this.sessionManager=null}throw o("error","Failed to start session tracking",{error:s}),s}}isActive(){return this.sessionManager!==null&&!this.destroyed}cleanupSessionManager(){this.sessionManager&&(this.sessionManager.stopTracking(),this.sessionManager.destroy(),this.sessionManager=null)}stopTracking(){this.cleanupSessionManager()}destroy(){this.destroyed||(this.sessionManager&&(this.sessionManager.destroy(),this.sessionManager=null),this.destroyed=!0,this.set("hasStartSession",!1))}}class gt extends g{eventManager;onTrack;originalPushState;originalReplaceState;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)}patchHistory(e){const t=window.history[e];e==="pushState"&&!this.originalPushState?this.originalPushState=t:e==="replaceState"&&!this.originalReplaceState&&(this.originalReplaceState=t),window.history[e]=(...s)=>{t.apply(window.history,s),this.trackCurrentPage()}}trackCurrentPage=()=>{const e=window.location.href,t=j(e,this.get("config").sensitiveQueryParams);if(this.get("pageUrl")===t)return;this.onTrack();const s=this.get("pageUrl");this.set("pageUrl",t);const n=this.extractPageViewData();this.eventManager.track({type:h.PAGE_VIEW,page_url:this.get("pageUrl"),from_page_url:s,...n&&{page_view:n}})};trackInitialPageView(){const e=j(window.location.href,this.get("config").sensitiveQueryParams),t=this.extractPageViewData();this.eventManager.track({type:h.PAGE_VIEW,page_url:e,...t&&{page_view:t}}),this.onTrack()}extractPageViewData(){const{pathname:e,search:t,hash:s}=window.location,{referrer:n}=document,{title:i}=document;return!n&&!i&&!e&&!t&&!s?void 0:{...n&&{referrer:n},...i&&{title:i},...e&&{pathname:e},...t&&{search:t},...s&&{hash:s}}}}class Et extends g{eventManager;clickHandler;constructor(e){super(),this.eventManager=e}startTracking(){this.clickHandler||(this.clickHandler=e=>{const t=e,s=t.target,n=typeof HTMLElement<"u"&&s instanceof HTMLElement?s:typeof HTMLElement<"u"&&s instanceof Node&&s.parentElement instanceof HTMLElement?s.parentElement:null;if(!n){o("warn","Click target not found or not an element");return}const i=this.findTrackingElement(n),a=this.getRelevantClickElement(n),l=this.calculateClickCoordinates(t,n);if(i){const d=this.extractTrackingData(i);if(d){const v=this.createCustomEventData(d);this.eventManager.track({type:h.CUSTOM,custom_event:{name:v.name,...v.value&&{metadata:{value:v.value}}}})}}const c=this.generateClickData(n,a,l);this.eventManager.track({type:h.CLICK,click_data:c})},window.addEventListener("click",this.clickHandler,!0))}stopTracking(){this.clickHandler&&(window.removeEventListener("click",this.clickHandler,!0),this.clickHandler=void 0)}findTrackingElement(e){return e.hasAttribute(`${k}-name`)?e:e.closest(`[${k}-name]`)||void 0}getRelevantClickElement(e){for(const t of be)try{if(e.matches(t))return e;const s=e.closest(t);if(s)return s}catch(s){o("warn","Invalid selector in element search",{error:s,data:{selector:t}});continue}return e}clamp(e){return Math.max(0,Math.min(1,Number(e.toFixed(3))))}calculateClickCoordinates(e,t){const s=t.getBoundingClientRect(),n=e.clientX,i=e.clientY,a=s.width>0?this.clamp((n-s.left)/s.width):0,l=s.height>0?this.clamp((i-s.top)/s.height):0;return{x:n,y:i,relativeX:a,relativeY:l}}extractTrackingData(e){const t=e.getAttribute(`${k}-name`),s=e.getAttribute(`${k}-value`);if(t)return{element:e,name:t,...s&&{value:s}}}generateClickData(e,t,s){const{x:n,y:i,relativeX:a,relativeY:l}=s,c=this.getRelevantText(e,t),d=this.extractElementAttributes(t);return{x:n,y:i,relativeX:a,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}}}getRelevantText(e,t){const s=e.textContent?.trim()??"",n=t.textContent?.trim()??"";return!s&&!n?"":s&&s.length<=255?s:n.length<=255?n:n.slice(0,252)+"..."}extractElementAttributes(e){const t=["id","class","data-testid","aria-label","title","href","type","name","alt","role"],s={};for(const n of t){const i=e.getAttribute(n);i&&(s[n]=i)}return s}createCustomEventData(e){return{name:e.name,...e.value&&{value:e.value}}}}class St extends g{eventManager;containers=[];limitWarningLogged=!1;minDepthChange=5;minIntervalMs=500;maxEventsPerSession=120;constructor(e){super(),this.eventManager=e}startTracking(){this.limitWarningLogged=!1,this.applyConfigOverrides(),this.set("scrollEventCount",0);const e=this.get("config").scrollContainerSelectors,t=Array.isArray(e)?e:typeof e=="string"?[e]:[];t.length===0?this.setupScrollContainer(window):this.trySetupContainers(t,0)}stopTracking(){for(const e of this.containers)this.clearContainerTimer(e),e.element instanceof Window?window.removeEventListener("scroll",e.listener):e.element.removeEventListener("scroll",e.listener);this.containers.length=0,this.set("scrollEventCount",0),this.limitWarningLogged=!1}trySetupContainers(e,t){const s=e.map(n=>this.safeQuerySelector(n)).filter(n=>n!=null&&typeof HTMLElement<"u"&&n instanceof HTMLElement);if(s.length>0){for(const n of s)this.containers.some(a=>a.element===n)||this.setupScrollContainer(n);return}if(t<5){setTimeout(()=>{this.trySetupContainers(e,t+1)},200);return}this.containers.length===0&&this.setupScrollContainer(window)}setupScrollContainer(e){if(e!==window&&!this.isElementScrollable(e))return;const t=()=>{this.get("suppressNextScroll")||(this.clearContainerTimer(n),n.debounceTimer=window.setTimeout(()=>{const i=this.calculateScrollData(n);if(i){const a=Date.now();this.processScrollEvent(n,i,a)}n.debounceTimer=null},250))},s=this.getScrollTop(e),n={element:e,lastScrollPos:s,lastDepth:this.calculateScrollDepth(s,this.getScrollHeight(e),this.getViewportHeight(e)),lastDirection:b.DOWN,lastEventTime:0,debounceTimer:null,listener:t};this.containers.push(n),e instanceof Window?window.addEventListener("scroll",t,{passive:!0}):e.addEventListener("scroll",t,{passive:!0})}processScrollEvent(e,t,s){if(!this.shouldEmitScrollEvent(e,t,s))return;e.lastEventTime=s,e.lastDepth=t.depth,e.lastDirection=t.direction;const n=this.get("scrollEventCount")??0;this.set("scrollEventCount",n+1),this.eventManager.track({type:h.SCROLL,scroll_data:t})}shouldEmitScrollEvent(e,t,s){return this.hasReachedSessionLimit()?(this.logLimitOnce(),!1):!(!this.hasElapsedMinimumInterval(e,s)||!this.hasSignificantDepthChange(e,t.depth))}hasReachedSessionLimit(){return(this.get("scrollEventCount")??0)>=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,o("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?b.DOWN:b.UP}calculateScrollDepth(e,t,s){if(t<=s)return 0;const n=t-s;return Math.min(100,Math.max(0,Math.floor(e/n*100)))}calculateScrollData(e){const{element:t,lastScrollPos:s}=e,n=this.getScrollTop(t);if(Math.abs(n-s)<10||t===window&&!this.isWindowScrollable())return null;const a=this.getViewportHeight(t),l=this.getScrollHeight(t),c=this.getScrollDirection(n,s),d=this.calculateScrollDepth(n,l,a);return e.lastScrollPos=n,{depth:d,direction:c}}getScrollTop(e){return e instanceof Window?window.scrollY:e.scrollTop}getViewportHeight(e){return e instanceof Window?window.innerHeight:e.clientHeight}getScrollHeight(e){return e instanceof Window?document.documentElement.scrollHeight:e.scrollHeight}isElementScrollable(e){const t=getComputedStyle(e),s=t.overflowY==="auto"||t.overflowY==="scroll"||t.overflowX==="auto"||t.overflowX==="scroll"||t.overflow==="auto"||t.overflow==="scroll",n=e.scrollHeight>e.clientHeight||e.scrollWidth>e.clientWidth;return s&&n}safeQuerySelector(e){try{return document.querySelector(e)}catch(t){return o("warn","Invalid CSS selector",{error:t,data:{selector:e},showToClient:!0}),null}}}class _t extends g{isInitialized=!1;async initialize(){if(this.isInitialized)return;const e=this.get("config").integrations?.googleAnalytics?.measurementId,t=this.get("userId");if(!(!e?.trim()||!t?.trim()))try{if(this.isScriptAlreadyLoaded()){this.isInitialized=!0;return}await this.loadScript(e),this.configureGtag(e,t),this.isInitialized=!0}catch(s){o("error","Google Analytics initialization failed",{error:s})}}trackEvent(e,t){if(!(!e?.trim()||!this.isInitialized||typeof window.gtag!="function"))try{const s=Array.isArray(t)?{items:t}:t;window.gtag("event",e,s)}catch(s){o("error","Google Analytics event tracking failed",{error:s})}}cleanup(){this.isInitialized=!1;const e=document.getElementById("tracelog-ga-script");e&&e.remove()}isScriptAlreadyLoaded(){return document.getElementById("tracelog-ga-script")?!0:!!document.querySelector('script[src*="googletagmanager.com/gtag/js"]')}async loadScript(e){return new Promise((t,s)=>{const n=document.createElement("script");n.id="tracelog-ga-script",n.async=!0,n.src=`https://www.googletagmanager.com/gtag/js?id=${e}`,n.onload=()=>{t()},n.onerror=()=>{s(new Error("Failed to load Google Analytics script"))},document.head.appendChild(n)})}configureGtag(e,t){const s=document.createElement("script");s.innerHTML=`
2
2
  window.dataLayer = window.dataLayer || [];
3
3
  function gtag(){dataLayer.push(arguments);}
4
4
  gtag('js', new Date());
5
5
  gtag('config', '${e}', {
6
6
  'user_id': '${t}'
7
7
  });
8
- `,document.head.appendChild(s)}}class Tt{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;hasQuotaExceededError=!1;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||o("warn","localStorage not available, using memory fallback"),this.sessionStorageRef||o("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(s){if(s instanceof DOMException&&s.name==="QuotaExceededError")if(this.hasQuotaExceededError=!0,o("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(i){o("error","localStorage quota exceeded even after cleanup - data will not persist",{error:i,data:{key:e,valueSize:t.length}})}else o("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:s,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 s=this.storage.key(t);s?.startsWith("tracelog_")&&e.push(s)}e.forEach(t=>{this.storage.removeItem(t)}),this.fallbackStorage.clear()}catch(e){o("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 a=this.storage.key(i);a?.startsWith("tracelog_")&&(e.push(a),a.startsWith("tracelog_persisted_events_")&&t.push(a))}if(t.length>0)return t.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0;const s=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],n=e.filter(i=>!s.some(a=>i.startsWith(a)));return n.length>0?(n.slice(0,5).forEach(a=>{try{this.storage.removeItem(a)}catch{}}),!0):!1}catch(e){return o("error","Failed to cleanup old data",{error:e}),!1}}initializeStorage(e){if(typeof window>"u")return null;try{const t=e==="localStorage"?window.localStorage:window.sessionStorage,s="__tracelog_test__";return t.setItem(s,"test"),t.removeItem(s),t}catch{return null}}getSessionItem(e){try{return this.sessionStorageRef?this.sessionStorageRef.getItem(e):this.fallbackSessionStorage.get(e)??null}catch{return this.fallbackSessionStorage.get(e)??null}}setSessionItem(e,t){this.fallbackSessionStorage.set(e,t);try{if(this.sessionStorageRef){this.sessionStorageRef.setItem(e,t);return}}catch(s){s instanceof DOMException&&s.name==="QuotaExceededError"&&o("error","sessionStorage quota exceeded - data will not persist",{error:s,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class mt extends g{eventManager;reportedByNav=new Map;observers=[];lastLongTaskSentAt=0;vitalThresholds=he;constructor(e){super(),this.eventManager=e}async startTracking(){await this.initWebVitals(),this.observeLongTasks()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(s){o("warn","Failed to disconnect performance observer",{error:s,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear()}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",s=>{const n=s.getEntries(),i=n[n.length-1];i&&this.sendVital({type:"LCP",value:Number(i.startTime.toFixed(2))})},{type:"largest-contentful-paint",buffered:!0},!0);let e=0,t=this.getNavigationId();this.safeObserve("layout-shift",s=>{const n=this.getNavigationId();n!==t&&(e=0,t=n);const i=s.getEntries();for(const a of i){if(a.hadRecentInput===!0)continue;const l=typeof a.value=="number"?a.value:0;e+=l}this.sendVital({type:"CLS",value:Number(e.toFixed(2))})},{type:"layout-shift",buffered:!0}),this.safeObserve("paint",s=>{for(const n of s.getEntries())n.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(n.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",s=>{let n=0;const i=s.getEntries();for(const a of i){const l=(a.processingEnd??0)-(a.startTime??0);n=Math.max(n,l)}n>0&&this.sendVital({type:"INP",value:Number(n.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:s,onTTFB:n,onINP:i}=await Promise.resolve().then(()=>qt),a=l=>c=>{const d=Number(c.value.toFixed(2));this.sendVital({type:l,value:d})};e(a("LCP")),t(a("CLS")),s(a("FCP")),n(a("TTFB")),i(a("INP"))}catch(e){o("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){o("warn","Failed to report TTFB",{error:e})}}observeLongTasks(){this.safeObserve("longtask",e=>{const t=e.getEntries();for(const s of t){const n=Number(s.duration.toFixed(2)),i=Date.now();i-this.lastLongTaskSentAt>=$e&&(this.shouldSendVital("LONG_TASK",n)&&this.trackWebVital("LONG_TASK",n),this.lastLongTaskSentAt=i)}},{type:"longtask",buffered:!0})}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const s=this.reportedByNav.get(t);if(s?.has(e.type))return;s?s.add(e.type):this.reportedByNav.set(t,new Set([e.type]))}this.trackWebVital(e.type,e.value)}trackWebVital(e,t){if(!Number.isFinite(t)){o("warn","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:h.WEB_VITALS,web_vitals:{type:e,value:t}})}getNavigationId(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return null;const t=e.startTime||performance.now(),s=Math.random().toString(36).substr(2,5);return`${t.toFixed(2)}_${window.location.pathname}_${s}`}catch(e){return o("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,s,n=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((a,l)=>{try{t(a,l)}catch(c){o("warn","Observer callback failed",{error:c,data:{type:e}})}if(n)try{l.disconnect()}catch{}});return i.observe(s??{type:e,buffered:!0}),n||this.observers.push(i),!0}catch(i){return o("warn","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return o("warn","Invalid web vital value",{data:{type:e,value:t}}),!1;const s=this.vitalThresholds[e];return!(typeof s=="number"&&t<=s)}}class pt extends g{eventManager;recentErrors=new Map;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()}shouldSample(){const t=this.get("config")?.errorSampling??.1;return Math.random()<t}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");this.shouldSuppressError(M.JS_ERROR,t)||this.eventManager.track({type:h.ERROR,error_data:{type:M.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),s=this.sanitize(t);this.shouldSuppressError(M.PROMISE_REJECTION,s)||this.eventManager.track({type:h.ERROR,error_data:{type:M.PROMISE_REJECTION,message:s}})};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>ge?e.slice(0,ge)+"...":e;for(const s of fe){const n=new RegExp(s.source,s.flags);t=t.replace(n,"[REDACTED]")}return t}shouldSuppressError(e,t){const s=Date.now(),n=`${e}:${t}`,i=this.recentErrors.get(n);return i&&s-i<Ee?(this.recentErrors.set(n,s),!0):(this.recentErrors.set(n,s),this.recentErrors.size>ze?(this.recentErrors.clear(),this.recentErrors.set(n,s),!1):(this.recentErrors.size>V&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[n,i]of this.recentErrors.entries())e-i>Ee&&this.recentErrors.delete(n);if(this.recentErrors.size<=V)return;const t=Array.from(this.recentErrors.entries()).sort((n,i)=>n[1]-i[1]),s=this.recentErrors.size-V;for(let n=0;n<s;n+=1){const i=t[n];i&&this.recentErrors.delete(i[0])}}}class It extends g{isInitialized=!1;suppressNextScrollTimer=null;emitter=new lt;managers={};handlers={};integrations={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new Tt;try{this.setupState(e),await this.setupIntegrations(),this.managers.event=new ut(this.managers.storage,this.integrations.googleAnalytics,this.emitter),this.initializeHandlers(),await this.managers.event.recoverPersistedEvents().catch(t=>{o("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0}catch(t){this.destroy(!0);const s=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${s}`)}}}sendCustomEvent(e,t){if(!this.managers.event)return;const{valid:s,error:n,sanitizedMetadata:i}=ot(e,t);if(!s){if(this.get("mode")===w.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${n}`);return}this.managers.event.track({type:h.CUSTOM,custom_event:{name:e,...i&&{metadata:i}}})}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}destroy(e=!1){!this.isInitialized&&!e||(this.integrations.googleAnalytics?.cleanup(),Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(s){o("warn","Failed to stop tracking",{error:s})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.managers.event?.flushImmediatelySync(),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.set("hasStartSession",!1),this.set("suppressNextScroll",!1),this.set("sessionId",null),this.isInitialized=!1,this.handlers={})}setupState(e={}){this.set("config",e);const t=dt.getId(this.managers.storage);this.set("userId",t);const s=Ze(e);this.set("collectApiUrl",s);const n=Ge();this.set("device",n);const i=j(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const a=je()?w.QA:void 0;a&&this.set("mode",a)}async setupIntegrations(){if(this.get("config").integrations?.googleAnalytics?.measurementId?.trim())try{this.integrations.googleAnalytics=new _t,await this.integrations.googleAnalytics.initialize()}catch{this.integrations.googleAnalytics=void 0}}initializeHandlers(){this.handlers.session=new ft(this.managers.storage,this.managers.event),this.handlers.session.startTracking();const e=()=>{this.set("suppressNextScroll",!0),this.suppressNextScrollTimer&&clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=window.setTimeout(()=>{this.set("suppressNextScroll",!1)},250*2)};this.handlers.pageView=new gt(this.managers.event,e),this.handlers.pageView.startTracking(),this.handlers.click=new Et(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new St(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new mt(this.managers.event),this.handlers.performance.startTracking().catch(t=>{o("warn","Failed to start performance tracking",{error:t})}),this.handlers.error=new pt(this.managers.event),this.handlers.error.startTracking()}}const N=[];let f=null,C=!1,G=!1;const vt=async r=>{if(typeof window>"u"||typeof document>"u")throw new Error("[TraceLog] This library can only be used in a browser environment");if(!window.__traceLogDisabled&&!f&&!C){C=!0;try{const e=st(r??{}),t=new It;try{N.forEach(({event:i,callback:a})=>{t.on(i,a)}),N.length=0;const s=t.init(e),n=new Promise((i,a)=>{setTimeout(()=>{a(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)});await Promise.race([s,n]),f=t}catch(s){try{t.destroy(!0)}catch(n){o("error","Failed to cleanup partially initialized app",{error:n})}throw s}}catch(e){throw f=null,e}finally{C=!1}}},At=(r,e)=>{if(!f)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(G)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");f.sendCustomEvent(r,e)},yt=(r,e)=>{if(!f||C){N.push({event:r,callback:e});return}f.on(r,e)},Nt=(r,e)=>{if(!f){const t=N.findIndex(s=>s.event===r&&s.callback===e);t!==-1&&N.splice(t,1);return}f.off(r,e)},Mt=()=>f!==null,wt=()=>{if(G)throw new Error("[TraceLog] Destroy operation already in progress");if(!f)throw new Error("[TraceLog] App not initialized");G=!0;try{f.destroy(),f=null,C=!1,N.length=0}catch(r){f=null,C=!1,N.length=0,o("warn","Error during destroy, forced cleanup completed",{error:r})}finally{G=!1}},Lt={WEB_VITALS_THRESHOLDS:he},Ct={PII_PATTERNS:fe},Rt={LOW_ACTIVITY_EVENT_COUNT:50,HIGH_ACTIVITY_EVENT_COUNT:1e3,MIN_EVENTS_FOR_DYNAMIC_CALCULATION:100,MIN_EVENTS_FOR_TREND_ANALYSIS:30,BOUNCE_RATE_SESSION_THRESHOLD:1,MIN_ENGAGED_SESSION_DURATION_MS:30*1e3,MIN_SCROLL_DEPTH_ENGAGEMENT:25},Ot={INACTIVITY_TIMEOUT_MS:30*60*1e3,SHORT_SESSION_THRESHOLD_MS:30*1e3,MEDIUM_SESSION_THRESHOLD_MS:5*60*1e3,LONG_SESSION_THRESHOLD_MS:30*60*1e3,MAX_REALISTIC_SESSION_DURATION_MS:8*60*60*1e3},bt={MOBILE_MAX_WIDTH:768,TABLET_MAX_WIDTH:1024,MOBILE_PERFORMANCE_FACTOR:1.5,TABLET_PERFORMANCE_FACTOR:1.2},Dt={MIN_TEXT_LENGTH_FOR_ANALYSIS:10,MIN_CLICKS_FOR_HOT_ELEMENT:10,MIN_SCROLL_COMPLETION_PERCENT:80,MIN_TIME_ON_PAGE_FOR_READ_MS:15*1e3},Pt={SIGNIFICANT_CHANGE_PERCENT:20,MAJOR_CHANGE_PERCENT:50,MIN_EVENTS_FOR_INSIGHT:100,MIN_SESSIONS_FOR_INSIGHT:10,MIN_CORRELATION_STRENGTH:.7,LOW_ERROR_RATE_PERCENT:1,HIGH_ERROR_RATE_PERCENT:5,CRITICAL_ERROR_RATE_PERCENT:10},Ut={SHORT_TERM_TREND_HOURS:24,MEDIUM_TERM_TREND_DAYS:7,LONG_TERM_TREND_DAYS:30,MIN_DATA_POINTS_FOR_TREND:5,WEEKLY_PATTERN_MIN_WEEKS:4,DAILY_PATTERN_MIN_DAYS:14},kt={MIN_SEGMENT_SIZE:10,MIN_COHORT_SIZE:5,COHORT_ANALYSIS_DAYS:[1,3,7,14,30],MIN_FUNNEL_EVENTS:20},Ht={DEFAULT_EVENTS_LIMIT:5,DEFAULT_SESSIONS_LIMIT:5,DEFAULT_PAGES_LIMIT:5,MAX_EVENTS_FOR_DEEP_ANALYSIS:1e4,MAX_TIME_RANGE_DAYS:365,ANALYTICS_BATCH_SIZE:1e3},Vt={ANOMALY_THRESHOLD_SIGMA:2.5,STRONG_ANOMALY_THRESHOLD_SIGMA:3,TRAFFIC_DROP_ALERT_PERCENT:-30,TRAFFIC_SPIKE_ALERT_PERCENT:200,MIN_BASELINE_DAYS:7,MIN_EVENTS_FOR_ANOMALY_DETECTION:50},Gt={PAGE_URL_EXCLUDED:"excluded",PAGE_URL_UNKNOWN:"unknown"},Ft={init:vt,event:At,on:yt,off:Nt,isInitialized:Mt,destroy:wt};var Z,ve=-1,R=function(r){addEventListener("pageshow",function(e){e.persisted&&(ve=e.timeStamp,r(e))},!0)},q=function(){var r=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(r&&r.responseStart>0&&r.responseStart<performance.now())return r},F=function(){var r=q();return r&&r.activationStart||0},E=function(r,e){var t=q(),s="navigate";return ve>=0?s="back-forward-cache":t&&(document.prerendering||F()>0?s="prerender":document.wasDiscarded?s="restore":t.type&&(s=t.type.replace(/_/g,"-"))),{name:r,value:e===void 0?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:s}},D=function(r,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(r)){var s=new PerformanceObserver(function(n){Promise.resolve().then(function(){e(n.getEntries())})});return s.observe(Object.assign({type:r,buffered:!0},t||{})),s}}catch{}},S=function(r,e,t,s){var n,i;return function(a){e.value>=0&&(a||s)&&((i=e.value-(n||0))||n===void 0)&&(n=e.value,e.delta=i,e.rating=function(l,c){return l>c[1]?"poor":l>c[0]?"needs-improvement":"good"}(e.value,t),r(e))}},J=function(r){requestAnimationFrame(function(){return requestAnimationFrame(function(){return r()})})},x=function(r){document.addEventListener("visibilitychange",function(){document.visibilityState==="hidden"&&r()})},ee=function(r){var e=!1;return function(){e||(r(),e=!0)}},O=-1,Ae=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},X=function(r){document.visibilityState==="hidden"&&O>-1&&(O=r.type==="visibilitychange"?r.timeStamp:0,xt())},ye=function(){addEventListener("visibilitychange",X,!0),addEventListener("prerenderingchange",X,!0)},xt=function(){removeEventListener("visibilitychange",X,!0),removeEventListener("prerenderingchange",X,!0)},Ne=function(){return O<0&&(O=Ae(),ye(),R(function(){setTimeout(function(){O=Ae(),ye()},0)})),{get firstHiddenTime(){return O}}},B=function(r){document.prerendering?addEventListener("prerenderingchange",function(){return r()},!0):r()},te=[1800,3e3],Me=function(r,e){e=e||{},B(function(){var t,s=Ne(),n=E("FCP"),i=D("paint",function(a){a.forEach(function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<s.firstHiddenTime&&(n.value=Math.max(l.startTime-F(),0),n.entries.push(l),t(!0)))})});i&&(t=S(r,n,te,e.reportAllChanges),R(function(a){n=E("FCP"),t=S(r,n,te,e.reportAllChanges),J(function(){n.value=performance.now()-a.timeStamp,t(!0)})}))})},re=[.1,.25],Xt=function(r,e){e=e||{},Me(ee(function(){var t,s=E("CLS",0),n=0,i=[],a=function(c){c.forEach(function(d){if(!d.hadRecentInput){var v=i[0],P=i[i.length-1];n&&d.startTime-P.startTime<1e3&&d.startTime-v.startTime<5e3?(n+=d.value,i.push(d)):(n=d.value,i=[d])}}),n>s.value&&(s.value=n,s.entries=i,t())},l=D("layout-shift",a);l&&(t=S(r,s,re,e.reportAllChanges),x(function(){a(l.takeRecords()),t(!0)}),R(function(){n=0,s=E("CLS",0),t=S(r,s,re,e.reportAllChanges),J(function(){return t()})}),setTimeout(t,0))}))},we=0,se=1/0,$=0,Bt=function(r){r.forEach(function(e){e.interactionId&&(se=Math.min(se,e.interactionId),$=Math.max($,e.interactionId),we=$?($-se)/7+1:0)})},Le=function(){return Z?we:performance.interactionCount||0},$t=function(){"interactionCount"in performance||Z||(Z=D("event",Bt,{type:"event",buffered:!0,durationThreshold:0}))},_=[],z=new Map,Ce=0,zt=function(){var r=Math.min(_.length-1,Math.floor((Le()-Ce)/50));return _[r]},Yt=[],Qt=function(r){if(Yt.forEach(function(n){return n(r)}),r.interactionId||r.entryType==="first-input"){var e=_[_.length-1],t=z.get(r.interactionId);if(t||_.length<10||r.duration>e.latency){if(t)r.duration>t.latency?(t.entries=[r],t.latency=r.duration):r.duration===t.latency&&r.startTime===t.entries[0].startTime&&t.entries.push(r);else{var s={id:r.interactionId,latency:r.duration,entries:[r]};z.set(s.id,s),_.push(s)}_.sort(function(n,i){return i.latency-n.latency}),_.length>10&&_.splice(10).forEach(function(n){return z.delete(n.id)})}}},Re=function(r){var e=self.requestIdleCallback||self.setTimeout,t=-1;return r=ee(r),document.visibilityState==="hidden"?r():(t=e(r),x(r)),t},ne=[200,500],jt=function(r,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},B(function(){var t;$t();var s,n=E("INP"),i=function(l){Re(function(){l.forEach(Qt);var c=zt();c&&c.latency!==n.value&&(n.value=c.latency,n.entries=c.entries,s())})},a=D("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});s=S(r,n,ne,e.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),x(function(){i(a.takeRecords()),s(!0)}),R(function(){Ce=Le(),_.length=0,z.clear(),n=E("INP"),s=S(r,n,ne,e.reportAllChanges)}))}))},ie=[2500,4e3],ae={},Kt=function(r,e){e=e||{},B(function(){var t,s=Ne(),n=E("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach(function(d){d.startTime<s.firstHiddenTime&&(n.value=Math.max(d.startTime-F(),0),n.entries=[d],t())})},a=D("largest-contentful-paint",i);if(a){t=S(r,n,ie,e.reportAllChanges);var l=ee(function(){ae[n.id]||(i(a.takeRecords()),a.disconnect(),ae[n.id]=!0,t(!0))});["keydown","click"].forEach(function(c){addEventListener(c,function(){return Re(l)},{once:!0,capture:!0})}),x(l),R(function(c){n=E("LCP"),t=S(r,n,ie,e.reportAllChanges),J(function(){n.value=performance.now()-c.timeStamp,ae[n.id]=!0,t(!0)})})}})},oe=[800,1800],Wt=function r(e){document.prerendering?B(function(){return r(e)}):document.readyState!=="complete"?addEventListener("load",function(){return r(e)},!0):setTimeout(e,0)},Zt=function(r,e){e=e||{};var t=E("TTFB"),s=S(r,t,oe,e.reportAllChanges);Wt(function(){var n=q();n&&(t.value=Math.max(n.responseStart-F(),0),t.entries=[n],s(!0),R(function(){t=E("TTFB",0),(s=S(r,t,oe,e.reportAllChanges))(!0)}))})};const qt=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:re,FCPThresholds:te,INPThresholds:ne,LCPThresholds:ie,TTFBThresholds:oe,onCLS:Xt,onFCP:Me,onINP:jt,onLCP:Kt,onTTFB:Zt},Symbol.toStringTag,{value:"Module"}));u.ANALYTICS_QUERY_LIMITS=Ht,u.ANOMALY_DETECTION=Vt,u.AppConfigValidationError=y,u.CONTENT_ANALYTICS=Dt,u.DATA_PROTECTION=Ct,u.DEVICE_ANALYTICS=bt,u.DeviceType=m,u.ENGAGEMENT_THRESHOLDS=Rt,u.EmitterEvent=H,u.ErrorType=M,u.EventType=h,u.INSIGHT_THRESHOLDS=Pt,u.InitializationTimeoutError=Ue,u.IntegrationValidationError=p,u.MAX_ARRAY_LENGTH=100,u.MAX_CUSTOM_EVENT_ARRAY_SIZE=10,u.MAX_CUSTOM_EVENT_ARRAY_SIZE_BACKEND=100,u.MAX_CUSTOM_EVENT_JSON_SIZE_BACKEND=51200,u.MAX_CUSTOM_EVENT_KEYS=10,u.MAX_CUSTOM_EVENT_KEYS_BACKEND=50,u.MAX_CUSTOM_EVENT_NAME_LENGTH=120,u.MAX_CUSTOM_EVENT_STRING_SIZE=8192,u.MAX_METADATA_NESTING_DEPTH=1,u.MAX_METADATA_NESTING_DEPTH_BACKEND=2,u.MAX_NESTED_OBJECT_KEYS=20,u.MAX_STRING_LENGTH=1e3,u.MAX_STRING_LENGTH_BACKEND=2e3,u.MAX_STRING_LENGTH_IN_ARRAY=500,u.Mode=w,u.PERFORMANCE_CONFIG=Lt,u.PermanentError=A,u.SEGMENTATION_ANALYTICS=kt,u.SESSION_ANALYTICS=Ot,u.SPECIAL_PAGE_URLS=Gt,u.SamplingRateValidationError=Y,u.ScrollDirection=b,u.SessionTimeoutValidationError=ce,u.SpecialApiUrl=k,u.TEMPORAL_ANALYSIS=Ut,u.TraceLogValidationError=L,u.tracelog=Ft,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);
8
+ `,document.head.appendChild(s)}}class mt{storage;sessionStorageRef;fallbackStorage=new Map;fallbackSessionStorage=new Map;hasQuotaExceededError=!1;constructor(){this.storage=this.initializeStorage("localStorage"),this.sessionStorageRef=this.initializeStorage("sessionStorage"),this.storage||o("warn","localStorage not available, using memory fallback"),this.sessionStorageRef||o("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(s){if(s instanceof DOMException&&s.name==="QuotaExceededError")if(this.hasQuotaExceededError=!0,o("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(i){o("error","localStorage quota exceeded even after cleanup - data will not persist",{error:i,data:{key:e,valueSize:t.length}})}else o("error","localStorage quota exceeded and no data to cleanup - data will not persist",{error:s,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 s=this.storage.key(t);s?.startsWith("tracelog_")&&e.push(s)}e.forEach(t=>{this.storage.removeItem(t)}),this.fallbackStorage.clear()}catch(e){o("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 a=this.storage.key(i);a?.startsWith("tracelog_")&&(e.push(a),a.startsWith("tracelog_persisted_events_")&&t.push(a))}if(t.length>0)return t.forEach(i=>{try{this.storage.removeItem(i)}catch{}}),!0;const s=["tracelog_session_","tracelog_user_id","tracelog_device_id","tracelog_config"],n=e.filter(i=>!s.some(a=>i.startsWith(a)));return n.length>0?(n.slice(0,5).forEach(a=>{try{this.storage.removeItem(a)}catch{}}),!0):!1}catch(e){return o("error","Failed to cleanup old data",{error:e}),!1}}initializeStorage(e){if(typeof window>"u")return null;try{const t=e==="localStorage"?window.localStorage:window.sessionStorage,s="__tracelog_test__";return t.setItem(s,"test"),t.removeItem(s),t}catch{return null}}getSessionItem(e){try{return this.sessionStorageRef?this.sessionStorageRef.getItem(e):this.fallbackSessionStorage.get(e)??null}catch{return this.fallbackSessionStorage.get(e)??null}}setSessionItem(e,t){this.fallbackSessionStorage.set(e,t);try{if(this.sessionStorageRef){this.sessionStorageRef.setItem(e,t);return}}catch(s){s instanceof DOMException&&s.name==="QuotaExceededError"&&o("error","sessionStorage quota exceeded - data will not persist",{error:s,data:{key:e,valueSize:t.length}})}}removeSessionItem(e){try{this.sessionStorageRef&&this.sessionStorageRef.removeItem(e)}catch{}this.fallbackSessionStorage.delete(e)}}class Tt extends g{eventManager;reportedByNav=new Map;observers=[];lastLongTaskSentAt=0;vitalThresholds=he;constructor(e){super(),this.eventManager=e}async startTracking(){await this.initWebVitals(),this.observeLongTasks()}stopTracking(){this.observers.forEach((e,t)=>{try{e.disconnect()}catch(s){o("warn","Failed to disconnect performance observer",{error:s,data:{observerIndex:t}})}}),this.observers.length=0,this.reportedByNav.clear()}observeWebVitalsFallback(){this.reportTTFB(),this.safeObserve("largest-contentful-paint",s=>{const n=s.getEntries(),i=n[n.length-1];i&&this.sendVital({type:"LCP",value:Number(i.startTime.toFixed(2))})},{type:"largest-contentful-paint",buffered:!0},!0);let e=0,t=this.getNavigationId();this.safeObserve("layout-shift",s=>{const n=this.getNavigationId();n!==t&&(e=0,t=n);const i=s.getEntries();for(const a of i){if(a.hadRecentInput===!0)continue;const l=typeof a.value=="number"?a.value:0;e+=l}this.sendVital({type:"CLS",value:Number(e.toFixed(2))})},{type:"layout-shift",buffered:!0}),this.safeObserve("paint",s=>{for(const n of s.getEntries())n.name==="first-contentful-paint"&&this.sendVital({type:"FCP",value:Number(n.startTime.toFixed(2))})},{type:"paint",buffered:!0},!0),this.safeObserve("event",s=>{let n=0;const i=s.getEntries();for(const a of i){const l=(a.processingEnd??0)-(a.startTime??0);n=Math.max(n,l)}n>0&&this.sendVital({type:"INP",value:Number(n.toFixed(2))})},{type:"event",buffered:!0})}async initWebVitals(){try{const{onLCP:e,onCLS:t,onFCP:s,onTTFB:n,onINP:i}=await Promise.resolve().then(()=>Zt),a=l=>c=>{const d=Number(c.value.toFixed(2));this.sendVital({type:l,value:d})};e(a("LCP")),t(a("CLS")),s(a("FCP")),n(a("TTFB")),i(a("INP"))}catch(e){o("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){o("warn","Failed to report TTFB",{error:e})}}observeLongTasks(){this.safeObserve("longtask",e=>{const t=e.getEntries();for(const s of t){const n=Number(s.duration.toFixed(2)),i=Date.now();i-this.lastLongTaskSentAt>=ze&&(this.shouldSendVital("LONG_TASK",n)&&this.trackWebVital("LONG_TASK",n),this.lastLongTaskSentAt=i)}},{type:"longtask",buffered:!0})}sendVital(e){if(!this.shouldSendVital(e.type,e.value))return;const t=this.getNavigationId();if(t){const s=this.reportedByNav.get(t);if(s?.has(e.type))return;s?s.add(e.type):this.reportedByNav.set(t,new Set([e.type]))}this.trackWebVital(e.type,e.value)}trackWebVital(e,t){if(!Number.isFinite(t)){o("warn","Invalid web vital value",{data:{type:e,value:t}});return}this.eventManager.track({type:h.WEB_VITALS,web_vitals:{type:e,value:t}})}getNavigationId(){try{const e=performance.getEntriesByType("navigation")[0];if(!e)return null;const t=e.startTime||performance.now(),s=Math.random().toString(36).substr(2,5);return`${t.toFixed(2)}_${window.location.pathname}_${s}`}catch(e){return o("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,s,n=!1){try{if(!this.isObserverSupported(e))return!1;const i=new PerformanceObserver((a,l)=>{try{t(a,l)}catch(c){o("warn","Observer callback failed",{error:c,data:{type:e}})}if(n)try{l.disconnect()}catch{}});return i.observe(s??{type:e,buffered:!0}),n||this.observers.push(i),!0}catch(i){return o("warn","Failed to create performance observer",{error:i,data:{type:e}}),!1}}shouldSendVital(e,t){if(typeof t!="number"||!Number.isFinite(t))return o("warn","Invalid web vital value",{data:{type:e,value:t}}),!1;const s=this.vitalThresholds[e];return!(typeof s=="number"&&t<=s)}}class pt extends g{eventManager;recentErrors=new Map;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()}shouldSample(){const t=this.get("config")?.errorSampling??.1;return Math.random()<t}handleError=e=>{if(!this.shouldSample())return;const t=this.sanitize(e.message||"Unknown error");this.shouldSuppressError(w.JS_ERROR,t)||this.eventManager.track({type:h.ERROR,error_data:{type:w.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),s=this.sanitize(t);this.shouldSuppressError(w.PROMISE_REJECTION,s)||this.eventManager.track({type:h.ERROR,error_data:{type:w.PROMISE_REJECTION,message:s}})};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>ge?e.slice(0,ge)+"...":e;for(const s of fe){const n=new RegExp(s.source,s.flags);t=t.replace(n,"[REDACTED]")}return t}shouldSuppressError(e,t){const s=Date.now(),n=`${e}:${t}`,i=this.recentErrors.get(n);return i&&s-i<Ee?(this.recentErrors.set(n,s),!0):(this.recentErrors.set(n,s),this.recentErrors.size>Qe?(this.recentErrors.clear(),this.recentErrors.set(n,s),!1):(this.recentErrors.size>V&&this.pruneOldErrors(),!1))}pruneOldErrors(){const e=Date.now();for(const[n,i]of this.recentErrors.entries())e-i>Ee&&this.recentErrors.delete(n);if(this.recentErrors.size<=V)return;const t=Array.from(this.recentErrors.entries()).sort((n,i)=>n[1]-i[1]),s=this.recentErrors.size-V;for(let n=0;n<s;n+=1){const i=t[n];i&&this.recentErrors.delete(i[0])}}}class It extends g{isInitialized=!1;suppressNextScrollTimer=null;emitter=new lt;managers={};handlers={};integrations={};get initialized(){return this.isInitialized}async init(e={}){if(!this.isInitialized){this.managers.storage=new mt;try{this.setupState(e),await this.setupIntegrations(),this.managers.event=new ut(this.managers.storage,this.integrations.googleAnalytics,this.emitter),this.initializeHandlers(),await this.managers.event.recoverPersistedEvents().catch(t=>{o("warn","Failed to recover persisted events",{error:t})}),this.isInitialized=!0}catch(t){this.destroy(!0);const s=t instanceof Error?t.message:String(t);throw new Error(`[TraceLog] TraceLog initialization failed: ${s}`)}}}sendCustomEvent(e,t){if(!this.managers.event)return;const{valid:s,error:n,sanitizedMetadata:i}=ot(e,t);if(!s){if(this.get("mode")===M.QA)throw new Error(`[TraceLog] Custom event "${e}" validation failed: ${n}`);return}this.managers.event.track({type:h.CUSTOM,custom_event:{name:e,...i&&{metadata:i}}})}on(e,t){this.emitter.on(e,t)}off(e,t){this.emitter.off(e,t)}destroy(e=!1){!this.isInitialized&&!e||(this.integrations.googleAnalytics?.cleanup(),Object.values(this.handlers).filter(Boolean).forEach(t=>{try{t.stopTracking()}catch(s){o("warn","Failed to stop tracking",{error:s})}}),this.suppressNextScrollTimer&&(clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=null),this.managers.event?.flushImmediatelySync(),this.managers.event?.stop(),this.emitter.removeAllListeners(),this.set("hasStartSession",!1),this.set("suppressNextScroll",!1),this.set("sessionId",null),this.isInitialized=!1,this.handlers={})}setupState(e={}){this.set("config",e);const t=dt.getId(this.managers.storage);this.set("userId",t);const s=qe(e);this.set("collectApiUrl",s);const n=Ge();this.set("device",n);const i=j(window.location.href,e.sensitiveQueryParams);this.set("pageUrl",i);const a=je()?M.QA:void 0;a&&this.set("mode",a)}async setupIntegrations(){if(this.get("config").integrations?.googleAnalytics?.measurementId?.trim())try{this.integrations.googleAnalytics=new _t,await this.integrations.googleAnalytics.initialize()}catch{this.integrations.googleAnalytics=void 0}}initializeHandlers(){this.handlers.session=new ft(this.managers.storage,this.managers.event),this.handlers.session.startTracking();const e=()=>{this.set("suppressNextScroll",!0),this.suppressNextScrollTimer&&clearTimeout(this.suppressNextScrollTimer),this.suppressNextScrollTimer=window.setTimeout(()=>{this.set("suppressNextScroll",!1)},250*2)};this.handlers.pageView=new gt(this.managers.event,e),this.handlers.pageView.startTracking(),this.handlers.click=new Et(this.managers.event),this.handlers.click.startTracking(),this.handlers.scroll=new St(this.managers.event),this.handlers.scroll.startTracking(),this.handlers.performance=new Tt(this.managers.event),this.handlers.performance.startTracking().catch(t=>{o("warn","Failed to start performance tracking",{error:t})}),this.handlers.error=new pt(this.managers.event),this.handlers.error.startTracking()}}const N=[];let f=null,R=!1,G=!1;const vt=async r=>{if(typeof window>"u"||typeof document>"u")throw new Error("[TraceLog] This library can only be used in a browser environment");if(!window.__traceLogDisabled&&!f&&!R){R=!0;try{const e=st(r??{}),t=new It;try{N.forEach(({event:i,callback:a})=>{t.on(i,a)}),N.length=0;const s=t.init(e),n=new Promise((i,a)=>{setTimeout(()=>{a(new Error("[TraceLog] Initialization timeout after 10000ms"))},1e4)});await Promise.race([s,n]),f=t}catch(s){try{t.destroy(!0)}catch(n){o("error","Failed to cleanup partially initialized app",{error:n})}throw s}}catch(e){throw f=null,e}finally{R=!1}}},At=(r,e)=>{if(!f)throw new Error("[TraceLog] TraceLog not initialized. Please call init() first.");if(G)throw new Error("[TraceLog] Cannot send events while TraceLog is being destroyed");f.sendCustomEvent(r,e)},yt=(r,e)=>{if(!f||R){N.push({event:r,callback:e});return}f.on(r,e)},Nt=(r,e)=>{if(!f){const t=N.findIndex(s=>s.event===r&&s.callback===e);t!==-1&&N.splice(t,1);return}f.off(r,e)},wt=()=>f!==null,Mt=()=>{if(G)throw new Error("[TraceLog] Destroy operation already in progress");if(!f)throw new Error("[TraceLog] App not initialized");G=!0;try{f.destroy(),f=null,R=!1,N.length=0}catch(r){f=null,R=!1,N.length=0,o("warn","Error during destroy, forced cleanup completed",{error:r})}finally{G=!1}},Lt={WEB_VITALS_THRESHOLDS:he},Rt={PII_PATTERNS:fe},Ct={LOW_ACTIVITY_EVENT_COUNT:50,HIGH_ACTIVITY_EVENT_COUNT:1e3,MIN_EVENTS_FOR_DYNAMIC_CALCULATION:100,MIN_EVENTS_FOR_TREND_ANALYSIS:30,BOUNCE_RATE_SESSION_THRESHOLD:1,MIN_ENGAGED_SESSION_DURATION_MS:30*1e3,MIN_SCROLL_DEPTH_ENGAGEMENT:25},Ot={INACTIVITY_TIMEOUT_MS:30*60*1e3,SHORT_SESSION_THRESHOLD_MS:30*1e3,MEDIUM_SESSION_THRESHOLD_MS:5*60*1e3,LONG_SESSION_THRESHOLD_MS:30*60*1e3,MAX_REALISTIC_SESSION_DURATION_MS:8*60*60*1e3},bt={MOBILE_MAX_WIDTH:768,TABLET_MAX_WIDTH:1024,MOBILE_PERFORMANCE_FACTOR:1.5,TABLET_PERFORMANCE_FACTOR:1.2},Pt={MIN_TEXT_LENGTH_FOR_ANALYSIS:10,MIN_CLICKS_FOR_HOT_ELEMENT:10,MIN_SCROLL_COMPLETION_PERCENT:80,MIN_TIME_ON_PAGE_FOR_READ_MS:15*1e3},Dt={SIGNIFICANT_CHANGE_PERCENT:20,MAJOR_CHANGE_PERCENT:50,MIN_EVENTS_FOR_INSIGHT:100,MIN_SESSIONS_FOR_INSIGHT:10,MIN_CORRELATION_STRENGTH:.7,LOW_ERROR_RATE_PERCENT:1,HIGH_ERROR_RATE_PERCENT:5,CRITICAL_ERROR_RATE_PERCENT:10},kt={SHORT_TERM_TREND_HOURS:24,MEDIUM_TERM_TREND_DAYS:7,LONG_TERM_TREND_DAYS:30,MIN_DATA_POINTS_FOR_TREND:5,WEEKLY_PATTERN_MIN_WEEKS:4,DAILY_PATTERN_MIN_DAYS:14},Ht={MIN_SEGMENT_SIZE:10,MIN_COHORT_SIZE:5,COHORT_ANALYSIS_DAYS:[1,3,7,14,30],MIN_FUNNEL_EVENTS:20},Ut={DEFAULT_EVENTS_LIMIT:5,DEFAULT_SESSIONS_LIMIT:5,DEFAULT_PAGES_LIMIT:5,MAX_EVENTS_FOR_DEEP_ANALYSIS:1e4,MAX_TIME_RANGE_DAYS:365,ANALYTICS_BATCH_SIZE:1e3},Vt={ANOMALY_THRESHOLD_SIGMA:2.5,STRONG_ANOMALY_THRESHOLD_SIGMA:3,TRAFFIC_DROP_ALERT_PERCENT:-30,TRAFFIC_SPIKE_ALERT_PERCENT:200,MIN_BASELINE_DAYS:7,MIN_EVENTS_FOR_ANOMALY_DETECTION:50},Gt={PAGE_URL_EXCLUDED:"excluded",PAGE_URL_UNKNOWN:"unknown"},Ft={init:vt,event:At,on:yt,off:Nt,isInitialized:wt,destroy:Mt};var q,ve=-1,C=function(r){addEventListener("pageshow",function(e){e.persisted&&(ve=e.timeStamp,r(e))},!0)},Z=function(){var r=self.performance&&performance.getEntriesByType&&performance.getEntriesByType("navigation")[0];if(r&&r.responseStart>0&&r.responseStart<performance.now())return r},F=function(){var r=Z();return r&&r.activationStart||0},E=function(r,e){var t=Z(),s="navigate";return ve>=0?s="back-forward-cache":t&&(document.prerendering||F()>0?s="prerender":document.wasDiscarded?s="restore":t.type&&(s=t.type.replace(/_/g,"-"))),{name:r,value:e===void 0?-1:e,rating:"good",delta:0,entries:[],id:"v4-".concat(Date.now(),"-").concat(Math.floor(8999999999999*Math.random())+1e12),navigationType:s}},P=function(r,e,t){try{if(PerformanceObserver.supportedEntryTypes.includes(r)){var s=new PerformanceObserver(function(n){Promise.resolve().then(function(){e(n.getEntries())})});return s.observe(Object.assign({type:r,buffered:!0},t||{})),s}}catch{}},S=function(r,e,t,s){var n,i;return function(a){e.value>=0&&(a||s)&&((i=e.value-(n||0))||n===void 0)&&(n=e.value,e.delta=i,e.rating=function(l,c){return l>c[1]?"poor":l>c[0]?"needs-improvement":"good"}(e.value,t),r(e))}},J=function(r){requestAnimationFrame(function(){return requestAnimationFrame(function(){return r()})})},x=function(r){document.addEventListener("visibilitychange",function(){document.visibilityState==="hidden"&&r()})},ee=function(r){var e=!1;return function(){e||(r(),e=!0)}},O=-1,Ae=function(){return document.visibilityState!=="hidden"||document.prerendering?1/0:0},X=function(r){document.visibilityState==="hidden"&&O>-1&&(O=r.type==="visibilitychange"?r.timeStamp:0,xt())},ye=function(){addEventListener("visibilitychange",X,!0),addEventListener("prerenderingchange",X,!0)},xt=function(){removeEventListener("visibilitychange",X,!0),removeEventListener("prerenderingchange",X,!0)},Ne=function(){return O<0&&(O=Ae(),ye(),C(function(){setTimeout(function(){O=Ae(),ye()},0)})),{get firstHiddenTime(){return O}}},$=function(r){document.prerendering?addEventListener("prerenderingchange",function(){return r()},!0):r()},te=[1800,3e3],we=function(r,e){e=e||{},$(function(){var t,s=Ne(),n=E("FCP"),i=P("paint",function(a){a.forEach(function(l){l.name==="first-contentful-paint"&&(i.disconnect(),l.startTime<s.firstHiddenTime&&(n.value=Math.max(l.startTime-F(),0),n.entries.push(l),t(!0)))})});i&&(t=S(r,n,te,e.reportAllChanges),C(function(a){n=E("FCP"),t=S(r,n,te,e.reportAllChanges),J(function(){n.value=performance.now()-a.timeStamp,t(!0)})}))})},re=[.1,.25],Xt=function(r,e){e=e||{},we(ee(function(){var t,s=E("CLS",0),n=0,i=[],a=function(c){c.forEach(function(d){if(!d.hadRecentInput){var v=i[0],D=i[i.length-1];n&&d.startTime-D.startTime<1e3&&d.startTime-v.startTime<5e3?(n+=d.value,i.push(d)):(n=d.value,i=[d])}}),n>s.value&&(s.value=n,s.entries=i,t())},l=P("layout-shift",a);l&&(t=S(r,s,re,e.reportAllChanges),x(function(){a(l.takeRecords()),t(!0)}),C(function(){n=0,s=E("CLS",0),t=S(r,s,re,e.reportAllChanges),J(function(){return t()})}),setTimeout(t,0))}))},Me=0,se=1/0,z=0,$t=function(r){r.forEach(function(e){e.interactionId&&(se=Math.min(se,e.interactionId),z=Math.max(z,e.interactionId),Me=z?(z-se)/7+1:0)})},Le=function(){return q?Me:performance.interactionCount||0},zt=function(){"interactionCount"in performance||q||(q=P("event",$t,{type:"event",buffered:!0,durationThreshold:0}))},_=[],Q=new Map,Re=0,Qt=function(){var r=Math.min(_.length-1,Math.floor((Le()-Re)/50));return _[r]},Bt=[],Yt=function(r){if(Bt.forEach(function(n){return n(r)}),r.interactionId||r.entryType==="first-input"){var e=_[_.length-1],t=Q.get(r.interactionId);if(t||_.length<10||r.duration>e.latency){if(t)r.duration>t.latency?(t.entries=[r],t.latency=r.duration):r.duration===t.latency&&r.startTime===t.entries[0].startTime&&t.entries.push(r);else{var s={id:r.interactionId,latency:r.duration,entries:[r]};Q.set(s.id,s),_.push(s)}_.sort(function(n,i){return i.latency-n.latency}),_.length>10&&_.splice(10).forEach(function(n){return Q.delete(n.id)})}}},Ce=function(r){var e=self.requestIdleCallback||self.setTimeout,t=-1;return r=ee(r),document.visibilityState==="hidden"?r():(t=e(r),x(r)),t},ne=[200,500],jt=function(r,e){"PerformanceEventTiming"in self&&"interactionId"in PerformanceEventTiming.prototype&&(e=e||{},$(function(){var t;zt();var s,n=E("INP"),i=function(l){Ce(function(){l.forEach(Yt);var c=Qt();c&&c.latency!==n.value&&(n.value=c.latency,n.entries=c.entries,s())})},a=P("event",i,{durationThreshold:(t=e.durationThreshold)!==null&&t!==void 0?t:40});s=S(r,n,ne,e.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),x(function(){i(a.takeRecords()),s(!0)}),C(function(){Re=Le(),_.length=0,Q.clear(),n=E("INP"),s=S(r,n,ne,e.reportAllChanges)}))}))},ie=[2500,4e3],ae={},Wt=function(r,e){e=e||{},$(function(){var t,s=Ne(),n=E("LCP"),i=function(c){e.reportAllChanges||(c=c.slice(-1)),c.forEach(function(d){d.startTime<s.firstHiddenTime&&(n.value=Math.max(d.startTime-F(),0),n.entries=[d],t())})},a=P("largest-contentful-paint",i);if(a){t=S(r,n,ie,e.reportAllChanges);var l=ee(function(){ae[n.id]||(i(a.takeRecords()),a.disconnect(),ae[n.id]=!0,t(!0))});["keydown","click"].forEach(function(c){addEventListener(c,function(){return Ce(l)},{once:!0,capture:!0})}),x(l),C(function(c){n=E("LCP"),t=S(r,n,ie,e.reportAllChanges),J(function(){n.value=performance.now()-c.timeStamp,ae[n.id]=!0,t(!0)})})}})},oe=[800,1800],Kt=function r(e){document.prerendering?$(function(){return r(e)}):document.readyState!=="complete"?addEventListener("load",function(){return r(e)},!0):setTimeout(e,0)},qt=function(r,e){e=e||{};var t=E("TTFB"),s=S(r,t,oe,e.reportAllChanges);Kt(function(){var n=Z();n&&(t.value=Math.max(n.responseStart-F(),0),t.entries=[n],s(!0),C(function(){t=E("TTFB",0),(s=S(r,t,oe,e.reportAllChanges))(!0)}))})};const Zt=Object.freeze(Object.defineProperty({__proto__:null,CLSThresholds:re,FCPThresholds:te,INPThresholds:ne,LCPThresholds:ie,TTFBThresholds:oe,onCLS:Xt,onFCP:we,onINP:jt,onLCP:Wt,onTTFB:qt},Symbol.toStringTag,{value:"Module"}));u.ANALYTICS_QUERY_LIMITS=Ut,u.ANOMALY_DETECTION=Vt,u.AppConfigValidationError=y,u.CONTENT_ANALYTICS=Pt,u.DATA_PROTECTION=Rt,u.DEVICE_ANALYTICS=bt,u.DeviceType=T,u.ENGAGEMENT_THRESHOLDS=Ct,u.EmitterEvent=U,u.ErrorType=w,u.EventType=h,u.INSIGHT_THRESHOLDS=Dt,u.InitializationTimeoutError=ke,u.IntegrationValidationError=p,u.MAX_ARRAY_LENGTH=100,u.MAX_CUSTOM_EVENT_ARRAY_SIZE=10,u.MAX_CUSTOM_EVENT_KEYS=10,u.MAX_CUSTOM_EVENT_NAME_LENGTH=120,u.MAX_CUSTOM_EVENT_STRING_SIZE=8192,u.MAX_METADATA_NESTING_DEPTH=1,u.MAX_NESTED_OBJECT_KEYS=20,u.MAX_STRING_LENGTH=1e3,u.MAX_STRING_LENGTH_IN_ARRAY=500,u.Mode=M,u.PERFORMANCE_CONFIG=Lt,u.PermanentError=A,u.SEGMENTATION_ANALYTICS=Ht,u.SESSION_ANALYTICS=Ot,u.SPECIAL_PAGE_URLS=Gt,u.SamplingRateValidationError=B,u.ScrollDirection=b,u.SessionTimeoutValidationError=ce,u.SpecialApiUrl=H,u.TEMPORAL_ANALYSIS=kt,u.TraceLogValidationError=L,u.tracelog=Ft,Object.defineProperty(u,Symbol.toStringTag,{value:"Module"})})(this.TraceLog=this.TraceLog||{});typeof window<"u"&&window.TraceLog?.tracelog&&(window.tracelog=window.TraceLog.tracelog);