@grainql/analytics-web 2.7.1 → 2.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/cjs/debug-agent.d.ts +171 -0
  2. package/dist/cjs/debug-agent.d.ts.map +1 -0
  3. package/dist/cjs/debug-agent.js +1219 -0
  4. package/dist/cjs/debug-agent.js.map +1 -0
  5. package/dist/cjs/index.d.ts +14 -0
  6. package/dist/cjs/index.d.ts.map +1 -1
  7. package/dist/cjs/index.js.map +1 -1
  8. package/dist/cjs/interaction-tracking.d.ts +6 -0
  9. package/dist/cjs/interaction-tracking.d.ts.map +1 -1
  10. package/dist/cjs/interaction-tracking.js +55 -5
  11. package/dist/cjs/interaction-tracking.js.map +1 -1
  12. package/dist/debug-agent.d.ts +171 -0
  13. package/dist/debug-agent.d.ts.map +1 -0
  14. package/dist/debug-agent.js +1219 -0
  15. package/dist/esm/debug-agent.d.ts +171 -0
  16. package/dist/esm/debug-agent.d.ts.map +1 -0
  17. package/dist/esm/debug-agent.js +1215 -0
  18. package/dist/esm/debug-agent.js.map +1 -0
  19. package/dist/esm/index.d.ts +14 -0
  20. package/dist/esm/index.d.ts.map +1 -1
  21. package/dist/esm/index.js.map +1 -1
  22. package/dist/esm/interaction-tracking.d.ts +6 -0
  23. package/dist/esm/interaction-tracking.d.ts.map +1 -1
  24. package/dist/esm/interaction-tracking.js +55 -5
  25. package/dist/esm/interaction-tracking.js.map +1 -1
  26. package/dist/index.d.ts +14 -0
  27. package/dist/index.d.ts.map +1 -1
  28. package/dist/index.global.dev.js +1326 -6
  29. package/dist/index.global.dev.js.map +4 -4
  30. package/dist/index.global.js +506 -2
  31. package/dist/index.global.js.map +4 -4
  32. package/dist/index.js +99 -0
  33. package/dist/index.mjs +99 -0
  34. package/dist/interaction-tracking.d.ts +6 -0
  35. package/dist/interaction-tracking.d.ts.map +1 -1
  36. package/dist/interaction-tracking.js +55 -5
  37. package/package.json +1 -1
@@ -1,3 +1,507 @@
1
- /* Grain Analytics Web SDK v2.7.1 | MIT License */
2
- "use strict";var Grain=(()=>{var _=Object.defineProperty;var te=Object.getOwnPropertyDescriptor;var ie=Object.getOwnPropertyNames;var re=Object.prototype.hasOwnProperty;var A=(s,e)=>()=>(s&&(e=s(s=0)),e);var S=(s,e)=>{for(var t in e)_(s,t,{get:e[t],enumerable:!0})},ne=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ie(e))!re.call(s,r)&&r!==t&&_(s,r,{get:()=>e[r],enumerable:!(i=te(e,r))||i.enumerable});return s};var ae=s=>ne(_({},"__esModule",{value:!0}),s);var ge,m,x=A(()=>{"use strict";ge={maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4},m=class{constructor(e,t={}){this.isDestroyed=!1;this.isPageVisible=!0;this.visibilityChangeHandler=null;this.sectionStates=new Map;this.lastFilterReason=null;this.activityDetector=e,this.options={...ge,...t,debug:t.debug??!1},this.setupPageVisibilityTracking()}setupPageVisibilityTracking(){typeof document>"u"||(this.isPageVisible=document.visibilityState==="visible",this.visibilityChangeHandler=()=>{let e=this.isPageVisible;this.isPageVisible=document.visibilityState==="visible",!this.isPageVisible&&e?this.log("Page hidden - tracking paused"):this.isPageVisible&&!e&&(this.log("Page visible - tracking resumed"),this.resetAllSections())},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}shouldTrack(){return this.isPageVisible?this.activityDetector.isActive(this.options.idleThreshold)?(this.lastFilterReason=null,!0):(this.lastFilterReason="user_idle",!1):(this.lastFilterReason="page_hidden",!1)}shouldTrackSection(e,t){if(!this.shouldTrack())return{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"};let i=this.sectionStates.get(e);i||(i={sectionName:e,currentDuration:0,lastScrollPosition:t,lastResetTime:Date.now()},this.sectionStates.set(e,i));let r=Math.abs(t-i.lastScrollPosition);return r>=this.options.minScrollDistance?(this.log(`Section "${e}": Attention reset due to ${Math.round(r)}px scroll`),i.currentDuration=0,i.lastScrollPosition=t,i.lastResetTime=Date.now(),{shouldTrack:!0,resetAttention:!0}):i.currentDuration>=this.options.maxSectionDuration?{shouldTrack:!1,reason:"max_duration_reached"}:{shouldTrack:!0}}updateSectionDuration(e,t){let i=this.sectionStates.get(e);i&&(i.currentDuration+=t,i.currentDuration>=this.options.maxSectionDuration&&this.log(`Section "${e}": Max duration cap reached (${i.currentDuration}ms)`))}resetSection(e){let t=this.sectionStates.get(e);t&&(this.log(`Section "${e}": Attention reset (section exit)`),t.currentDuration=0,t.lastResetTime=Date.now())}resetAllSections(){this.log("Resetting all section attention states");for(let e of this.sectionStates.values())e.currentDuration=0,e.lastResetTime=Date.now()}getSectionState(e){return this.sectionStates.get(e)}getLastFilterReason(){return this.lastFilterReason}shouldTrackScroll(e,t){return this.shouldTrack()?Math.abs(t-e)<10?{shouldTrack:!1,reason:"scroll_too_small"}:{shouldTrack:!0}:{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"}}getPolicies(){return{maxSectionDuration:this.options.maxSectionDuration,minScrollDistance:this.options.minScrollDistance,idleThreshold:this.options.idleThreshold}}getTrackingState(){return{isPageVisible:this.isPageVisible,isUserActive:this.activityDetector.isActive(this.options.idleThreshold),timeSinceLastActivity:this.activityDetector.getTimeSinceLastActivity(),activeSections:this.sectionStates.size}}log(...e){this.options.debug&&console.log("[AttentionQuality]",...e)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.sectionStates.clear())}}});function me(s){if(s)return s.replace(/[\u{1F300}-\u{1F9FF}]/gu,"").replace(/[\u{1F600}-\u{1F64F}]/gu,"").replace(/[\u{1F680}-\u{1F6FF}]/gu,"").replace(/[\u{2600}-\u{26FF}]/gu,"").replace(/[\u{2700}-\u{27BF}]/gu,"").replace(/[\u{1F900}-\u{1F9FF}]/gu,"").replace(/[\u{1F1E0}-\u{1F1FF}]/gu,"").replace(/[\u{200D}]/gu,"").replace(/[\u{FE0F}]/gu,"").replace(/[\u{20E3}]/gu,"").trim()}function M(s,e=100){if(!s)return;let t=me(s);if(t)return t.substring(0,e)||void 0}var L=A(()=>{"use strict"});var J={};S(J,{HeatmapTrackingManager:()=>N});var fe,N,j=A(()=>{"use strict";x();L();fe={scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:!1},N=class{constructor(e,t={}){this.isDestroyed=!1;this.currentScrollState=null;this.pendingClicks=[];this.pendingScrolls=[];this.scrollDebounceTimer=null;this.batchTimer=null;this.scrollTrackingTimer=null;this.periodicScrollTimer=null;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.SPLIT_DURATION=3e3;this.tracker=e,this.options={...fe,...t},this.attentionQuality=new m(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing heatmap tracking"),this.setupClickTracking(),this.setupScrollTracking(),this.startScrollTracking(),this.setupUnloadHandler())}setupClickTracking(){if(typeof document>"u")return;let e=t=>{this.isDestroyed||this.tracker.hasConsent("analytics")&&this.handleClick(t)};document.addEventListener("click",e,{passive:!0,capture:!0})}setupScrollTracking(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.handleScroll(),this.scrollDebounceTimer=null},this.options.scrollDebounceDelay)};window.addEventListener("scroll",e,{passive:!0})}startScrollTracking(){typeof window>"u"||(this.updateScrollState(),this.scrollTrackingTimer=window.setInterval(()=>{this.isDestroyed||this.updateScrollState()},500),this.startPeriodicScrollTracking())}startPeriodicScrollTracking(){typeof window>"u"||(this.periodicScrollTimer=window.setInterval(()=>{if(this.isDestroyed||!this.currentScrollState||!this.tracker.hasConsent("analytics"))return;if(!this.attentionQuality.shouldTrack()){this.log("Scroll tracking paused:",this.attentionQuality.getLastFilterReason());return}let e=Date.now(),t=e-this.currentScrollState.entryTime;if(t>1e3){let i=window.scrollY||window.pageYOffset,r=window.innerHeight,a=document.documentElement.scrollHeight,n=`viewport_section_${this.currentScrollState.viewportSection}`,o=this.attentionQuality.shouldTrackSection(n,i);if(o.resetAttention){this.log(`Viewport section ${this.currentScrollState.viewportSection}: Attention reset`),this.currentScrollState.entryTime=e;return}if(!o.shouldTrack){this.log(`Viewport section ${this.currentScrollState.viewportSection}: ${o.reason}`);return}let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:i,durationMs:t,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:a,viewportHeight:r};this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:c.pageUrl,viewport_section:c.viewportSection,scroll_depth_px:c.scrollDepthPx,duration_ms:c.durationMs,entry_timestamp:c.entryTimestamp,exit_timestamp:c.exitTimestamp,page_height:c.pageHeight,viewport_height:c.viewportHeight,is_split:!0},{flush:!0}),this.attentionQuality.updateSectionDuration(n,t),this.currentScrollState.entryTime=e}},this.SPLIT_DURATION))}setupUnloadHandler(){if(typeof window>"u")return;let e=()=>{if(this.currentScrollState){let t=Date.now(),i=t-this.currentScrollState.entryTime;if(i>100){let r={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:i,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:t,pageHeight:document.documentElement.scrollHeight,viewportHeight:window.innerHeight};this.pendingScrolls.push(r)}}this.flushPendingEventsWithBeacon()};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e)}handleClick(e){if(!this.tracker.hasConsent("analytics"))return;let t=e.target;if(!t)return;let i=window.location.href,r=this.generateXPath(t),a=Math.round(e.clientX),n=Math.round(e.clientY),o=Math.round(e.pageX),c=Math.round(e.pageY),u=t.tagName?.toLowerCase()||"unknown",l=M(t.textContent),d={pageUrl:i,xpath:r,viewportX:a,viewportY:n,pageX:o,pageY:c,elementTag:u,elementText:l||void 0,timestamp:Date.now()};t instanceof HTMLAnchorElement&&t.href?this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:d.pageUrl,xpath:d.xpath,viewport_x:d.viewportX,viewport_y:d.viewportY,page_x:d.pageX,page_y:d.pageY,element_tag:d.elementTag,element_text:d.elementText,timestamp:d.timestamp},{flush:!0}):(this.pendingClicks.push(d),this.considerBatchFlush())}handleScroll(){this.tracker.hasConsent("analytics")&&this.updateScrollState()}updateScrollState(){if(typeof window>"u"||!this.tracker.hasConsent("analytics"))return;let e=Date.now(),t=window.scrollY||window.pageYOffset,i=window.innerHeight,r=document.documentElement.scrollHeight,a=Math.floor(t/i);if(this.currentScrollState&&this.currentScrollState.viewportSection!==a){let n=e-this.currentScrollState.entryTime;if(n>100){let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:n,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:r,viewportHeight:i};this.pendingScrolls.push(c)}let o=`viewport_section_${this.currentScrollState.viewportSection}`;this.attentionQuality.resetSection(o)}(!this.currentScrollState||this.currentScrollState.viewportSection!==a)&&(this.currentScrollState={viewportSection:a,entryTime:e,scrollDepthPx:t}),this.lastScrollPosition=t,this.lastScrollTime=e,this.considerBatchFlush()}generateXPath(e){if(!e)return"";if(e.id)return`//*[@id="${e.id}"]`;let t=[],i=e;for(;i&&i.nodeType===Node.ELEMENT_NODE;){let r=0,a=i;for(;a;)a=a.previousElementSibling,a&&a.nodeName===i.nodeName&&r++;let n=i.nodeName.toLowerCase(),o=r>0?`[${r+1}]`:"";t.unshift(`${n}${o}`),i=i.parentElement}return t.length?`/${t.join("/")}`:""}considerBatchFlush(){let e=this.pendingClicks.length+this.pendingScrolls.length;if(e>=this.options.maxBatchSize){this.flushPendingEvents();return}this.batchTimer===null&&e>0&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents(),this.batchTimer=null},this.options.batchDelay))}flushPendingEvents(){if(!this.isDestroyed){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight});this.pendingScrolls=[]}this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null)}}flushPendingEventsWithBeacon(){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp},{flush:!0});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight},{flush:!0});this.pendingScrolls=[]}}log(...e){this.options.debug&&this.tracker.log("[Heatmap Tracking]",...e)}destroy(){this.isDestroyed=!0,this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.scrollTrackingTimer!==null&&(clearInterval(this.scrollTrackingTimer),this.scrollTrackingTimer=null),this.periodicScrollTimer!==null&&(clearInterval(this.periodicScrollTimer),this.periodicScrollTimer=null),this.attentionQuality.destroy(),this.flushPendingEvents()}}});var Y={};S(Y,{InteractionTrackingManager:()=>O});var O,Z=A(()=>{"use strict";L();O=class{constructor(e,t,i={}){this.isDestroyed=!1;this.attachedListeners=new Map;this.xpathCache=new Map;this.mutationObserver=null;this.mutationDebounceTimer=null;this.tracker=e,this.interactions=t,this.config={debug:i.debug??!1,enableMutationObserver:i.enableMutationObserver??!0,mutationDebounceDelay:i.mutationDebounceDelay??500},typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.attachAllListeners()):setTimeout(()=>this.attachAllListeners(),0),this.config.enableMutationObserver&&this.setupMutationObserver())}attachAllListeners(){if(!this.isDestroyed){this.log("Attaching interaction listeners");for(let e of this.interactions)this.attachInteractionListener(e)}}attachInteractionListener(e){if(this.isDestroyed)return;let t=this.findElementByXPath(e.selector);if(!t){this.log("Element not found for interaction:",e.eventName,"selector:",e.selector);return}if(this.attachedListeners.has(t)){this.log("Listeners already attached for element:",t);return}let i=[],r=a=>this.handleInteractionClick(e,a);if(t.addEventListener("click",r,{passive:!0}),i.push({event:"click",handler:r}),t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){let a=n=>this.handleInteractionFocus(e,n);t.addEventListener("focus",a,{passive:!0}),i.push({event:"focus",handler:a})}this.attachedListeners.set(t,i)}handleInteractionClick(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target,r=i instanceof HTMLAnchorElement&&i.href,a={interaction_type:"click",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_text:M(i.textContent),element_id:i.id||void 0,element_class:i.className||void 0,...r&&{href:i.href},timestamp:Date.now()},n=this.tracker.track(e.eventName,a,{flush:!0});n instanceof Promise&&n.catch(o=>{this.log("Failed to track click:",o)})}handleInteractionFocus(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target;this.tracker.track(e.eventName,{interaction_type:"focus",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_id:i.id||void 0,element_class:i.className||void 0,timestamp:Date.now()})}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}setupMutationObserver(){if(typeof MutationObserver>"u"){this.log("MutationObserver not supported");return}this.mutationObserver=new MutationObserver(e=>{this.mutationDebounceTimer!==null&&clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.handleMutations(e),this.mutationDebounceTimer=null},this.config.mutationDebounceDelay)}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Mutation observer setup")}handleMutations(e){if(this.isDestroyed)return;this.xpathCache.clear();let t=new Set;for(let i of e)i.removedNodes.forEach(r=>{r instanceof Element&&(t.add(r),this.attachedListeners.forEach((a,n)=>{r.contains(n)&&t.add(n)}))});t.forEach(i=>{this.detachListeners(i)}),this.attachAllListeners()}detachListeners(e){let t=this.attachedListeners.get(e);t&&(t.forEach(({event:i,handler:r})=>{e.removeEventListener(i,r)}),this.attachedListeners.delete(e))}log(...e){this.config.debug&&console.log("[InteractionTracking]",...e)}updateInteractions(e){this.isDestroyed||(this.log("Updating interactions configuration"),this.attachedListeners.forEach((t,i)=>{this.detachListeners(i)}),this.xpathCache.clear(),this.interactions=e,this.attachAllListeners())}destroy(){this.isDestroyed||(this.log("Destroying interaction tracking manager"),this.isDestroyed=!0,this.mutationDebounceTimer!==null&&(clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.attachedListeners.forEach((e,t)=>{this.detachListeners(t)}),this.attachedListeners.clear(),this.xpathCache.clear())}}});var q={};S(q,{SectionTrackingManager:()=>H});var pe,H,X=A(()=>{"use strict";x();pe={minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:!1},H=class{constructor(e,t,i={}){this.isDestroyed=!1;this.sectionStates=new Map;this.intersectionObserver=null;this.xpathCache=new Map;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.scrollVelocity=0;this.scrollDebounceTimer=null;this.pendingEvents=[];this.batchTimer=null;this.sectionTimers=new Map;this.SPLIT_DURATION=3e3;this.tracker=e,this.sections=t,this.options={...pe,...i},this.attentionQuality=new m(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing section tracking"),this.setupIntersectionObserver(),this.setupScrollListener(),this.initializeSections())}setupIntersectionObserver(){if(typeof IntersectionObserver>"u"){this.log("IntersectionObserver not supported");return}this.intersectionObserver=new IntersectionObserver(e=>{e.forEach(t=>{this.handleIntersection(t)})},{threshold:[0,.1,.25,.5,.75,1],rootMargin:"0px"}),this.log("IntersectionObserver created")}setupScrollListener(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.updateScrollVelocity(),this.scrollDebounceTimer=null},this.options.debounceDelay)};window.addEventListener("scroll",e,{passive:!0}),this.log("Scroll listener attached")}initializeSections(){for(let e of this.sections){let t=this.findElementByXPath(e.selector);if(!t){this.log("Section element not found:",e.sectionName,"selector:",e.selector);continue}let i={element:t,config:e,entryTime:null,exitTime:null,isVisible:!1,lastScrollPosition:window.scrollY,lastScrollTime:Date.now(),entryScrollSpeed:0,exitScrollSpeed:0,maxVisibleArea:0};this.sectionStates.set(e.sectionName,i),this.intersectionObserver&&this.intersectionObserver.observe(t)}}handleIntersection(e){if(this.isDestroyed)return;let t=Array.from(this.sectionStates.values()).find(a=>a.element===e.target);if(!t)return;let i=e.isIntersecting&&e.intersectionRatio>=this.options.intersectionThreshold,r=e.intersectionRatio;r>t.maxVisibleArea&&(t.maxVisibleArea=r),i&&!t.isVisible?this.handleSectionEntry(t):!i&&t.isVisible&&this.handleSectionExit(t),t.isVisible=i}handleSectionEntry(e){e.entryTime=Date.now(),e.entryScrollSpeed=this.scrollVelocity,e.lastScrollPosition=window.scrollY,e.lastScrollTime=Date.now(),e.maxVisibleArea=0,this.startPeriodicTracking(e)}startPeriodicTracking(e){this.stopPeriodicTracking(e.config.sectionName);let t=window.setInterval(()=>{if(this.isDestroyed||!e.isVisible||e.entryTime===null){this.stopPeriodicTracking(e.config.sectionName);return}let i=Date.now(),r=i-e.entryTime;if(r>=this.options.minDwellTime){let a=window.scrollY,n=this.attentionQuality.shouldTrackSection(e.config.sectionName,a);if(n.resetAttention){this.log(`Section "${e.config.sectionName}": Attention reset, restarting timer`),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity;return}if(!n.shouldTrack){this.log(`Section "${e.config.sectionName}": Tracking paused - ${n.reason}`);return}let o={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:i,duration:r,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:this.scrollVelocity};this.shouldTrackSection(o)&&(this.tracker.trackSystemEvent("_grain_section_view",{section_name:o.sectionName,section_type:o.sectionType,duration_ms:o.duration,viewport_width:o.viewportWidth,viewport_height:o.viewportHeight,scroll_depth_percent:o.scrollDepth,visible_area_percent:o.visibleAreaPercentage,scroll_speed_entry:Math.round(o.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(o.scrollSpeedAtExit||0),entry_timestamp:o.entryTime,exit_timestamp:o.exitTime,is_split:!0}),this.attentionQuality.updateSectionDuration(e.config.sectionName,r),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity)}},this.SPLIT_DURATION);this.sectionTimers.set(e.config.sectionName,t)}stopPeriodicTracking(e){let t=this.sectionTimers.get(e);t!==void 0&&(clearInterval(t),this.sectionTimers.delete(e))}handleSectionExit(e){if(this.stopPeriodicTracking(e.config.sectionName),this.attentionQuality.resetSection(e.config.sectionName),e.entryTime===null)return;e.exitTime=Date.now(),e.exitScrollSpeed=this.scrollVelocity;let t=e.exitTime-e.entryTime,i={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:e.exitTime,duration:t,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:e.exitScrollSpeed};this.shouldTrackSection(i)?this.queueSectionView(i):this.log("Section view filtered out:",e.config.sectionName,"duration:",t),e.entryTime=null}updateScrollVelocity(){let e=Date.now(),t=window.scrollY,i=e-this.lastScrollTime,r=Math.abs(t-this.lastScrollPosition);i>0&&(this.scrollVelocity=r/i*1e3),this.lastScrollPosition=t,this.lastScrollTime=e}calculateScrollDepth(){if(typeof window>"u"||typeof document>"u")return 0;let e=window.innerHeight,t=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight),i=window.scrollY,r=t-e;return r<=0?100:Math.round(i/r*100)}shouldTrackSection(e){return!(e.duration<this.options.minDwellTime||(e.scrollSpeedAtEntry+e.scrollSpeedAtExit)/2>this.options.scrollVelocityThreshold*2||e.visibleAreaPercentage<10)}queueSectionView(e){this.pendingEvents.push(e),this.batchTimer===null&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents()},this.options.batchDelay))}flushPendingEvents(){if(!(this.isDestroyed||this.pendingEvents.length===0)){if(!this.tracker.hasConsent("analytics")){this.pendingEvents=[];return}for(let e of this.pendingEvents)this.tracker.trackSystemEvent("_grain_section_view",{section_name:e.sectionName,section_type:e.sectionType,duration_ms:e.duration,viewport_width:e.viewportWidth,viewport_height:e.viewportHeight,scroll_depth_percent:e.scrollDepth,visible_area_percent:e.visibleAreaPercentage,scroll_speed_entry:Math.round(e.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(e.scrollSpeedAtExit||0),entry_timestamp:e.entryTime,exit_timestamp:e.exitTime});this.pendingEvents=[],this.batchTimer=null}}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}log(...e){this.options.debug&&console.log("[SectionTracking]",...e)}updateSections(e){this.isDestroyed||(this.log("Updating sections configuration"),this.intersectionObserver&&this.intersectionObserver.disconnect(),this.sectionStates.clear(),this.xpathCache.clear(),this.sections=e,this.setupIntersectionObserver(),this.initializeSections())}destroy(){this.isDestroyed||(this.log("Destroying section tracking manager"),this.isDestroyed=!0,this.sectionTimers.forEach(e=>{clearInterval(e)}),this.sectionTimers.clear(),this.flushPendingEvents(),this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.intersectionObserver&&(this.intersectionObserver.disconnect(),this.intersectionObserver=null),this.attentionQuality.destroy(),this.sectionStates.clear(),this.xpathCache.clear(),this.pendingEvents=[])}}});var ve={};S(ve,{GrainAnalytics:()=>f,categorizeReferrer:()=>h,createGrainAnalytics:()=>ee,default:()=>Ae,getCountry:()=>$,getCountryCodeFromTimezone:()=>k,getState:()=>W,parseUTMParameters:()=>v});var B=["necessary","analytics","functional"],E="1.0.0",T=class{constructor(e,t="opt-out"){this.consentState=null;this.listeners=[];this.consentMode=t,this.storageKey=`grain_consent_${e}`,this.loadConsentState()}loadConsentState(){if(!(typeof window>"u"))try{let e=localStorage.getItem(this.storageKey);if(e){let t=JSON.parse(e);this.consentState={...t,timestamp:new Date(t.timestamp)}}else(this.consentMode==="opt-out"||this.consentMode==="disabled")&&(this.consentState={granted:!0,categories:B,timestamp:new Date,version:E},this.saveConsentState())}catch{}}saveConsentState(){if(!(typeof window>"u"||!this.consentState))try{localStorage.setItem(this.storageKey,JSON.stringify(this.consentState))}catch{}}grantConsent(e){let t=e||B;this.consentState={granted:!0,categories:t,timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}revokeConsent(e){this.consentState?e?this.consentState={...this.consentState,categories:this.consentState.categories.filter(t=>!e.includes(t)),granted:this.consentState.categories.length>0,timestamp:new Date}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}getConsentState(){return this.consentState?{...this.consentState}:null}hasConsent(e){return this.consentMode==="disabled"?!0:this.consentMode==="opt-in"&&!this.consentState||!this.consentState?.granted?!1:e?this.consentState.categories.includes(e):!0}shouldWaitForConsent(){return this.consentMode==="opt-in"&&!this.consentState?.granted}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){this.consentState&&this.listeners.forEach(e=>{try{e(this.consentState)}catch{}})}clearConsent(){if(!(typeof window>"u"))try{localStorage.removeItem(this.storageKey),this.consentState=null}catch{}}};function I(s,e,t){if(typeof document>"u")return;let i=[`${encodeURIComponent(s)}=${encodeURIComponent(e)}`];t?.maxAge!==void 0&&i.push(`max-age=${t.maxAge}`),t?.domain&&i.push(`domain=${t.domain}`),t?.path?i.push(`path=${t.path}`):i.push("path=/"),t?.sameSite&&i.push(`samesite=${t.sameSite}`),t?.secure&&i.push("secure"),document.cookie=i.join("; ")}function D(s){if(typeof document>"u")return null;let e=encodeURIComponent(s)+"=",t=document.cookie.split(";");for(let i=0;i<t.length;i++){let r=t[i];for(;r.charAt(0)===" ";)r=r.substring(1);if(r.indexOf(e)===0)return decodeURIComponent(r.substring(e.length))}return null}function oe(s,e){if(typeof document>"u")return;let t=[`${encodeURIComponent(s)}=`,"max-age=0"];e?.domain&&t.push(`domain=${e.domain}`),e?.path?t.push(`path=${e.path}`):t.push("path=/"),document.cookie=t.join("; ")}function F(){if(typeof document>"u")return!1;try{let s="_grain_cookie_test";I(s,"test",{maxAge:1});let e=D(s)==="test";return oe(s),e}catch{return!1}}var b=class{constructor(){this.activityThreshold=3e4;this.listeners=[];this.isDestroyed=!1;this.activityEvents=["mousemove","mousedown","keydown","scroll","touchstart","click"];this.lastActivityTime=Date.now(),this.boundActivityHandler=this.debounce(this.handleActivity.bind(this),500),this.setupListeners()}setupListeners(){if(!(typeof window>"u"))for(let e of this.activityEvents)window.addEventListener(e,this.boundActivityHandler,{passive:!0})}handleActivity(){this.isDestroyed||(this.lastActivityTime=Date.now(),this.notifyListeners())}debounce(e,t){let i=null;return()=>{i!==null&&clearTimeout(i),i=window.setTimeout(()=>{e(),i=null},t)}}isActive(e){let t=e??this.activityThreshold;return Date.now()-this.lastActivityTime<t}getTimeSinceLastActivity(){return Date.now()-this.lastActivityTime}getLastActivityTime(){return this.lastActivityTime}setActivityThreshold(e){this.activityThreshold=e}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){for(let e of this.listeners)try{e()}catch{}}destroy(){if(!this.isDestroyed){if(typeof window<"u")for(let e of this.activityEvents)window.removeEventListener(e,this.boundActivityHandler);this.listeners=[],this.isDestroyed=!0}}};var C=class{constructor(e,t,i){this.heartbeatTimer=null;this.isDestroyed=!1;this.hasSentPageLoadHeartbeat=!1;this.tracker=e,this.activityDetector=t,this.config=i,this.lastHeartbeatTime=Date.now(),this.currentInterval=i.activeInterval,this.sendPageLoadHeartbeat(),this.scheduleNextHeartbeat()}sendPageLoadHeartbeat(){if(!(this.isDestroyed||this.hasSentPageLoadHeartbeat))if(typeof window<"u"&&document.readyState!=="complete"){let e=()=>{this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0,window.removeEventListener("load",e)};window.addEventListener("load",e)}else this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0}scheduleNextHeartbeat(){if(this.isDestroyed)return;this.heartbeatTimer!==null&&clearTimeout(this.heartbeatTimer);let e=this.activityDetector.isActive(6e4);this.currentInterval=e?this.config.activeInterval:this.config.inactiveInterval,this.heartbeatTimer=window.setTimeout(()=>{this.sendHeartbeat("periodic"),this.scheduleNextHeartbeat()},this.currentInterval),this.config.debug&&console.log(`[Heartbeat] Scheduled next heartbeat in ${this.currentInterval/1e3}s (${e?"active":"inactive"})`)}sendHeartbeat(e="periodic"){if(this.isDestroyed)return;let t=Date.now(),i=this.activityDetector.isActive(6e4),r=this.tracker.hasConsent("analytics"),a={heartbeat_type:e,status:i?"active":"inactive",timestamp:t};if(r){let n=this.tracker.getCurrentPage();n&&(a.page=n),a.session_id=this.tracker.getSessionId(),e==="periodic"&&(a.duration=t-this.lastHeartbeatTime,a.event_count=this.tracker.getEventCountSinceLastHeartbeat(),this.tracker.resetEventCountSinceLastHeartbeat())}this.tracker.trackSystemEvent("_grain_heartbeat",a),this.lastHeartbeatTime=t}destroy(){this.isDestroyed||(this.heartbeatTimer!==null&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null),this.isDestroyed=!0)}};var se=["gclid","msclkid","fbclid","ttclid","li_fat_id","twclid","ScCid"],ce=["facebook.com","twitter.com","x.com","linkedin.com","instagram.com","pinterest.com","reddit.com","tiktok.com","youtube.com","snapchat.com","t.co","fb.me","lnkd.in"],ue=["google.","bing.com","yahoo.com","duckduckgo.com","baidu.com","yandex.com","ecosia.org","ask.com"],le=["mail.google.com","outlook.live.com","mail.yahoo.com","mail.aol.com"];function R(s){try{return new URL(s).hostname.toLowerCase()}catch{return""}}function K(s){try{let e=new URL(s);return se.some(t=>e.searchParams.has(t))}catch{return!1}}function h(s,e=""){if(!s||s.trim()==="")return"direct";let t=R(s);if(e){let i=R(e);if(t===i)return"direct"}return K(s)||K(e)?"paid":le.some(i=>t.includes(i))?"email":ce.some(i=>t.includes(i))?"social":ue.some(i=>t.includes(i))?"organic":"referral"}function v(s){try{let e=new URL(s),t={},i=e.searchParams.get("utm_source"),r=e.searchParams.get("utm_medium"),a=e.searchParams.get("utm_campaign"),n=e.searchParams.get("utm_term"),o=e.searchParams.get("utm_content");return i&&(t.utm_source=i),r&&(t.utm_medium=r),a&&(t.utm_campaign=a),n&&(t.utm_term=n),o&&(t.utm_content=o),t}catch{return{}}}function U(s){if(typeof window>"u"||typeof localStorage>"u")return null;try{let e=`_grain_first_touch_${s}`,t=localStorage.getItem(e);if(t)return JSON.parse(t)}catch(e){console.warn("[Grain Attribution] Failed to retrieve first-touch attribution:",e)}return null}function de(s,e){if(!(typeof window>"u"||typeof localStorage>"u"))try{let t=`_grain_first_touch_${s}`;localStorage.setItem(t,JSON.stringify(e))}catch(t){console.warn("[Grain Attribution] Failed to store first-touch attribution:",t)}}function w(s,e,t,i){let r=U(s);if(r)return r;let a=h(e,t),n=R(e),o={source:i.utm_source||n||"direct",medium:i.utm_medium||a,campaign:i.utm_campaign||"none",referrer:e||"direct",referrer_category:a,timestamp:Date.now()};return de(s,o),o}var V=null;function g(){return V}function z(s){V=s}var he={AD:"Andorra",AE:"United Arab Emirates",AF:"Afghanistan",AG:"Antigua and Barbuda",AI:"Anguilla",AL:"Albania",AM:"Armenia",AO:"Angola",AQ:"Antarctica",AR:"Argentina",AS:"American Samoa",AT:"Austria",AU:"Australia",AW:"Aruba",AX:"\xC5land Islands",AZ:"Azerbaijan",BA:"Bosnia and Herzegovina",BB:"Barbados",BD:"Bangladesh",BE:"Belgium",BF:"Burkina Faso",BG:"Bulgaria",BH:"Bahrain",BI:"Burundi",BJ:"Benin",BL:"Saint Barth\xE9lemy",BM:"Bermuda",BN:"Brunei",BO:"Bolivia",BQ:"Caribbean Netherlands",BR:"Brazil",BS:"Bahamas",BT:"Bhutan",BV:"Bouvet Island",BW:"Botswana",BY:"Belarus",BZ:"Belize",CA:"Canada",CC:"Cocos Islands",CD:"Democratic Republic of the Congo",CF:"Central African Republic",CG:"Republic of the Congo",CH:"Switzerland",CI:"Ivory Coast",CK:"Cook Islands",CL:"Chile",CM:"Cameroon",CN:"China",CO:"Colombia",CR:"Costa Rica",CU:"Cuba",CV:"Cabo Verde",CW:"Cura\xE7ao",CX:"Christmas Island",CY:"Cyprus",CZ:"Czechia",DE:"Germany",DJ:"Djibouti",DK:"Denmark",DM:"Dominica",DO:"Dominican Republic",DZ:"Algeria",EC:"Ecuador",EE:"Estonia",EG:"Egypt",EH:"Western Sahara",ER:"Eritrea",ES:"Spain",ET:"Ethiopia",FI:"Finland",FJ:"Fiji",FK:"Falkland Islands",FM:"Micronesia",FO:"Faroe Islands",FR:"France",GA:"Gabon",GB:"United Kingdom",GD:"Grenada",GE:"Georgia",GF:"French Guiana",GG:"Guernsey",GH:"Ghana",GI:"Gibraltar",GL:"Greenland",GM:"Gambia",GN:"Guinea",GP:"Guadeloupe",GQ:"Equatorial Guinea",GR:"Greece",GS:"South Georgia and the South Sandwich Islands",GT:"Guatemala",GU:"Guam",GW:"Guinea-Bissau",GY:"Guyana",HK:"Hong Kong",HM:"Heard Island and McDonald Islands",HN:"Honduras",HR:"Croatia",HT:"Haiti",HU:"Hungary",ID:"Indonesia",IE:"Ireland",IL:"Israel",IM:"Isle of Man",IN:"India",IO:"British Indian Ocean Territory",IQ:"Iraq",IR:"Iran",IS:"Iceland",IT:"Italy",JE:"Jersey",JM:"Jamaica",JO:"Jordan",JP:"Japan",KE:"Kenya",KG:"Kyrgyzstan",KH:"Cambodia",KI:"Kiribati",KM:"Comoros",KN:"Saint Kitts and Nevis",KP:"North Korea",KR:"South Korea",KW:"Kuwait",KY:"Cayman Islands",KZ:"Kazakhstan",LA:"Laos",LB:"Lebanon",LC:"Saint Lucia",LI:"Liechtenstein",LK:"Sri Lanka",LR:"Liberia",LS:"Lesotho",LT:"Lithuania",LU:"Luxembourg",LV:"Latvia",LY:"Libya",MA:"Morocco",MC:"Monaco",MD:"Moldova",ME:"Montenegro",MF:"Saint Martin",MG:"Madagascar",MH:"Marshall Islands",MK:"North Macedonia",ML:"Mali",MM:"Myanmar",MN:"Mongolia",MO:"Macao",MP:"Northern Mariana Islands",MQ:"Martinique",MR:"Mauritania",MS:"Montserrat",MT:"Malta",MU:"Mauritius",MV:"Maldives",MW:"Malawi",MX:"Mexico",MY:"Malaysia",MZ:"Mozambique",NA:"Namibia",NC:"New Caledonia",NE:"Niger",NF:"Norfolk Island",NG:"Nigeria",NI:"Nicaragua",NL:"Netherlands",NO:"Norway",NP:"Nepal",NR:"Nauru",NU:"Niue",NZ:"New Zealand",OM:"Oman",PA:"Panama",PE:"Peru",PF:"French Polynesia",PG:"Papua New Guinea",PH:"Philippines",PK:"Pakistan",PL:"Poland",PM:"Saint Pierre and Miquelon",PN:"Pitcairn",PR:"Puerto Rico",PS:"Palestine",PT:"Portugal",PW:"Palau",PY:"Paraguay",QA:"Qatar",RE:"R\xE9union",RO:"Romania",RS:"Serbia",RU:"Russia",RW:"Rwanda",SA:"Saudi Arabia",SB:"Solomon Islands",SC:"Seychelles",SD:"Sudan",SE:"Sweden",SG:"Singapore",SH:"Saint Helena, Ascension and Tristan da Cunha",SI:"Slovenia",SJ:"Svalbard and Jan Mayen",SK:"Slovakia",SL:"Sierra Leone",SM:"San Marino",SN:"Senegal",SO:"Somalia",SR:"Suriname",SS:"South Sudan",ST:"Sao Tome and Principe",SV:"El Salvador",SX:"Sint Maarten",SY:"Syria",SZ:"Eswatini",TC:"Turks and Caicos Islands",TD:"Chad",TF:"French Southern Territories",TG:"Togo",TH:"Thailand",TJ:"Tajikistan",TK:"Tokelau",TL:"Timor-Leste",TM:"Turkmenistan",TN:"Tunisia",TO:"Tonga",TR:"Turkey",TT:"Trinidad and Tobago",TV:"Tuvalu",TW:"Taiwan",TZ:"Tanzania",UA:"Ukraine",UG:"Uganda",UM:"United States Minor Outlying Islands",US:"United States of America",UY:"Uruguay",UZ:"Uzbekistan",VA:"Holy See",VC:"Saint Vincent and the Grenadines",VE:"Venezuela",VG:"Virgin Islands (UK)",VI:"Virgin Islands (US)",VN:"Vietnam",VU:"Vanuatu",WF:"Wallis and Futuna",WS:"Samoa",YE:"Yemen",YT:"Mayotte",ZA:"South Africa",ZM:"Zambia",ZW:"Zimbabwe"},Q={"Africa/Abidjan":{u:0,c:["CI","BF","GH","GM","GN","ML","MR","SH","SL","SN","TG"]},"Africa/Accra":{a:"Africa/Abidjan",c:["GH"],r:1},"Africa/Addis_Ababa":{a:"Africa/Nairobi",c:["ET"],r:1},"Africa/Algiers":{u:60,c:["DZ"]},"Africa/Asmara":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Asmera":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Bamako":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Bangui":{a:"Africa/Lagos",c:["CF"],r:1},"Africa/Banjul":{a:"Africa/Abidjan",c:["GM"],r:1},"Africa/Bissau":{u:0,c:["GW"]},"Africa/Blantyre":{a:"Africa/Maputo",c:["MW"],r:1},"Africa/Brazzaville":{a:"Africa/Lagos",c:["CG"],r:1},"Africa/Bujumbura":{a:"Africa/Maputo",c:["BI"],r:1},"Africa/Cairo":{u:120,c:["EG"]},"Africa/Casablanca":{u:60,d:0,c:["MA"]},"Africa/Ceuta":{u:60,d:120,c:["ES"]},"Africa/Conakry":{a:"Africa/Abidjan",c:["GN"],r:1},"Africa/Dakar":{a:"Africa/Abidjan",c:["SN"],r:1},"Africa/Dar_es_Salaam":{a:"Africa/Nairobi",c:["TZ"],r:1},"Africa/Djibouti":{a:"Africa/Nairobi",c:["DJ"],r:1},"Africa/Douala":{a:"Africa/Lagos",c:["CM"],r:1},"Africa/El_Aaiun":{u:60,d:0,c:["EH"]},"Africa/Freetown":{a:"Africa/Abidjan",c:["SL"],r:1},"Africa/Gaborone":{a:"Africa/Maputo",c:["BW"],r:1},"Africa/Harare":{a:"Africa/Maputo",c:["ZW"],r:1},"Africa/Johannesburg":{u:120,c:["ZA","LS","SZ"]},"Africa/Juba":{u:120,c:["SS"]},"Africa/Kampala":{a:"Africa/Nairobi",c:["UG"],r:1},"Africa/Khartoum":{u:120,c:["SD"]},"Africa/Kigali":{a:"Africa/Maputo",c:["RW"],r:1},"Africa/Kinshasa":{a:"Africa/Lagos",c:["CD"],r:1},"Africa/Lagos":{u:60,c:["NG","AO","BJ","CD","CF","CG","CM","GA","GQ","NE"]},"Africa/Libreville":{a:"Africa/Lagos",c:["GA"],r:1},"Africa/Lome":{a:"Africa/Abidjan",c:["TG"],r:1},"Africa/Luanda":{a:"Africa/Lagos",c:["AO"],r:1},"Africa/Lubumbashi":{a:"Africa/Maputo",c:["CD"],r:1},"Africa/Lusaka":{a:"Africa/Maputo",c:["ZM"],r:1},"Africa/Malabo":{a:"Africa/Lagos",c:["GQ"],r:1},"Africa/Maputo":{u:120,c:["MZ","BI","BW","CD","MW","RW","ZM","ZW"]},"Africa/Maseru":{a:"Africa/Johannesburg",c:["LS"],r:1},"Africa/Mbabane":{a:"Africa/Johannesburg",c:["SZ"],r:1},"Africa/Mogadishu":{a:"Africa/Nairobi",c:["SO"],r:1},"Africa/Monrovia":{u:0,c:["LR"]},"Africa/Nairobi":{u:180,c:["KE","DJ","ER","ET","KM","MG","SO","TZ","UG","YT"]},"Africa/Ndjamena":{u:60,c:["TD"]},"Africa/Niamey":{a:"Africa/Lagos",c:["NE"],r:1},"Africa/Nouakchott":{a:"Africa/Abidjan",c:["MR"],r:1},"Africa/Ouagadougou":{a:"Africa/Abidjan",c:["BF"],r:1},"Africa/Porto-Novo":{a:"Africa/Lagos",c:["BJ"],r:1},"Africa/Sao_Tome":{u:0,c:["ST"]},"Africa/Timbuktu":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Tripoli":{u:120,c:["LY"]},"Africa/Tunis":{u:60,c:["TN"]},"Africa/Windhoek":{u:120,c:["NA"]},"America/Adak":{u:-600,d:-540,c:["US"]},"America/Anchorage":{u:-540,d:-480,c:["US"]},"America/Anguilla":{a:"America/Puerto_Rico",c:["AI"],r:1},"America/Antigua":{a:"America/Puerto_Rico",c:["AG"],r:1},"America/Araguaina":{u:-180,c:["BR"]},"America/Argentina/Buenos_Aires":{u:-180,c:["AR"]},"America/Argentina/Catamarca":{u:-180,c:["AR"]},"America/Argentina/ComodRivadavia":{a:"America/Argentina/Catamarca",r:1},"America/Argentina/Cordoba":{u:-180,c:["AR"]},"America/Argentina/Jujuy":{u:-180,c:["AR"]},"America/Argentina/La_Rioja":{u:-180,c:["AR"]},"America/Argentina/Mendoza":{u:-180,c:["AR"]},"America/Argentina/Rio_Gallegos":{u:-180,c:["AR"]},"America/Argentina/Salta":{u:-180,c:["AR"]},"America/Argentina/San_Juan":{u:-180,c:["AR"]},"America/Argentina/San_Luis":{u:-180,c:["AR"]},"America/Argentina/Tucuman":{u:-180,c:["AR"]},"America/Argentina/Ushuaia":{u:-180,c:["AR"]},"America/Aruba":{a:"America/Puerto_Rico",c:["AW"],r:1},"America/Asuncion":{u:-240,d:-180,c:["PY"]},"America/Atikokan":{a:"America/Panama",c:["CA"],r:1},"America/Atka":{a:"America/Adak",r:1},"America/Bahia":{u:-180,c:["BR"]},"America/Bahia_Banderas":{u:-360,d:-300,c:["MX"]},"America/Barbados":{u:-240,c:["BB"]},"America/Belem":{u:-180,c:["BR"]},"America/Belize":{u:-360,c:["BZ"]},"America/Blanc-Sablon":{a:"America/Puerto_Rico",c:["CA"],r:1},"America/Boa_Vista":{u:-240,c:["BR"]},"America/Bogota":{u:-300,c:["CO"]},"America/Boise":{u:-420,d:-360,c:["US"]},"America/Buenos_Aires":{a:"America/Argentina/Buenos_Aires",r:1},"America/Cambridge_Bay":{u:-420,d:-360,c:["CA"]},"America/Campo_Grande":{u:-240,c:["BR"]},"America/Cancun":{u:-300,c:["MX"]},"America/Caracas":{u:-240,c:["VE"]},"America/Catamarca":{a:"America/Argentina/Catamarca",r:1},"America/Cayenne":{u:-180,c:["GF"]},"America/Cayman":{a:"America/Panama",c:["KY"],r:1},"America/Chicago":{u:-360,d:-300,c:["US"]},"America/Chihuahua":{u:-420,d:-360,c:["MX"]},"America/Coral_Harbour":{a:"America/Panama",c:["CA"],r:1},"America/Cordoba":{a:"America/Argentina/Cordoba",r:1},"America/Costa_Rica":{u:-360,c:["CR"]},"America/Creston":{a:"America/Phoenix",c:["CA"],r:1},"America/Cuiaba":{u:-240,c:["BR"]},"America/Curacao":{a:"America/Puerto_Rico",c:["CW"],r:1},"America/Danmarkshavn":{u:0,c:["GL"]},"America/Dawson":{u:-420,c:["CA"]},"America/Dawson_Creek":{u:-420,c:["CA"]},"America/Denver":{u:-420,d:-360,c:["US"]},"America/Detroit":{u:-300,d:-240,c:["US"]},"America/Dominica":{a:"America/Puerto_Rico",c:["DM"],r:1},"America/Edmonton":{u:-420,d:-360,c:["CA"]},"America/Eirunepe":{u:-300,c:["BR"]},"America/El_Salvador":{u:-360,c:["SV"]},"America/Ensenada":{a:"America/Tijuana",r:1},"America/Fort_Nelson":{u:-420,c:["CA"]},"America/Fort_Wayne":{a:"America/Indiana/Indianapolis",r:1},"America/Fortaleza":{u:-180,c:["BR"]},"America/Glace_Bay":{u:-240,d:-180,c:["CA"]},"America/Godthab":{a:"America/Nuuk",r:1},"America/Goose_Bay":{u:-240,d:-180,c:["CA"]},"America/Grand_Turk":{u:-300,d:-240,c:["TC"]},"America/Grenada":{a:"America/Puerto_Rico",c:["GD"],r:1},"America/Guadeloupe":{a:"America/Puerto_Rico",c:["GP"],r:1},"America/Guatemala":{u:-360,c:["GT"]},"America/Guayaquil":{u:-300,c:["EC"]},"America/Guyana":{u:-240,c:["GY"]},"America/Halifax":{u:-240,d:-180,c:["CA"]},"America/Havana":{u:-300,d:-240,c:["CU"]},"America/Hermosillo":{u:-420,c:["MX"]},"America/Indiana/Indianapolis":{u:-300,d:-240,c:["US"]},"America/Indiana/Knox":{u:-360,d:-300,c:["US"]},"America/Indiana/Marengo":{u:-300,d:-240,c:["US"]},"America/Indiana/Petersburg":{u:-300,d:-240,c:["US"]},"America/Indiana/Tell_City":{u:-360,d:-300,c:["US"]},"America/Indiana/Vevay":{u:-300,d:-240,c:["US"]},"America/Indiana/Vincennes":{u:-300,d:-240,c:["US"]},"America/Indiana/Winamac":{u:-300,d:-240,c:["US"]},"America/Indianapolis":{a:"America/Indiana/Indianapolis",r:1},"America/Inuvik":{u:-420,d:-360,c:["CA"]},"America/Iqaluit":{u:-300,d:-240,c:["CA"]},"America/Jamaica":{u:-300,c:["JM"]},"America/Jujuy":{a:"America/Argentina/Jujuy",r:1},"America/Juneau":{u:-540,d:-480,c:["US"]},"America/Kentucky/Louisville":{u:-300,d:-240,c:["US"]},"America/Kentucky/Monticello":{u:-300,d:-240,c:["US"]},"America/Knox_IN":{a:"America/Indiana/Knox",r:1},"America/Kralendijk":{a:"America/Puerto_Rico",c:["BQ"],r:1},"America/La_Paz":{u:-240,c:["BO"]},"America/Lima":{u:-300,c:["PE"]},"America/Los_Angeles":{u:-480,d:-420,c:["US"]},"America/Louisville":{a:"America/Kentucky/Louisville",r:1},"America/Lower_Princes":{a:"America/Puerto_Rico",c:["SX"],r:1},"America/Maceio":{u:-180,c:["BR"]},"America/Managua":{u:-360,c:["NI"]},"America/Manaus":{u:-240,c:["BR"]},"America/Marigot":{a:"America/Puerto_Rico",c:["MF"],r:1},"America/Martinique":{u:-240,c:["MQ"]},"America/Matamoros":{u:-360,d:-300,c:["MX"]},"America/Mazatlan":{u:-420,d:-360,c:["MX"]},"America/Mendoza":{a:"America/Argentina/Mendoza",r:1},"America/Menominee":{u:-360,d:-300,c:["US"]},"America/Merida":{u:-360,d:-300,c:["MX"]},"America/Metlakatla":{u:-540,d:-480,c:["US"]},"America/Mexico_City":{u:-360,d:-300,c:["MX"]},"America/Miquelon":{u:-180,d:-120,c:["PM"]},"America/Moncton":{u:-240,d:-180,c:["CA"]},"America/Monterrey":{u:-360,d:-300,c:["MX"]},"America/Montevideo":{u:-180,c:["UY"]},"America/Montreal":{a:"America/Toronto",c:["CA"],r:1},"America/Montserrat":{a:"America/Puerto_Rico",c:["MS"],r:1},"America/Nassau":{a:"America/Toronto",c:["BS"],r:1},"America/New_York":{u:-300,d:-240,c:["US"]},"America/Nipigon":{u:-300,d:-240,c:["CA"]},"America/Nome":{u:-540,d:-480,c:["US"]},"America/Noronha":{u:-120,c:["BR"]},"America/North_Dakota/Beulah":{u:-360,d:-300,c:["US"]},"America/North_Dakota/Center":{u:-360,d:-300,c:["US"]},"America/North_Dakota/New_Salem":{u:-360,d:-300,c:["US"]},"America/Nuuk":{u:-180,d:-120,c:["GL"]},"America/Ojinaga":{u:-420,d:-360,c:["MX"]},"America/Panama":{u:-300,c:["PA","CA","KY"]},"America/Pangnirtung":{u:-300,d:-240,c:["CA"]},"America/Paramaribo":{u:-180,c:["SR"]},"America/Phoenix":{u:-420,c:["US","CA"]},"America/Port-au-Prince":{u:-300,d:-240,c:["HT"]},"America/Port_of_Spain":{a:"America/Puerto_Rico",c:["TT"],r:1},"America/Porto_Acre":{a:"America/Rio_Branco",r:1},"America/Porto_Velho":{u:-240,c:["BR"]},"America/Puerto_Rico":{u:-240,c:["PR","AG","CA","AI","AW","BL","BQ","CW","DM","GD","GP","KN","LC","MF","MS","SX","TT","VC","VG","VI"]},"America/Punta_Arenas":{u:-180,c:["CL"]},"America/Rainy_River":{u:-360,d:-300,c:["CA"]},"America/Rankin_Inlet":{u:-360,d:-300,c:["CA"]},"America/Recife":{u:-180,c:["BR"]},"America/Regina":{u:-360,c:["CA"]},"America/Resolute":{u:-360,d:-300,c:["CA"]},"America/Rio_Branco":{u:-300,c:["BR"]},"America/Rosario":{a:"America/Argentina/Cordoba",r:1},"America/Santa_Isabel":{a:"America/Tijuana",r:1},"America/Santarem":{u:-180,c:["BR"]},"America/Santiago":{u:-240,d:-180,c:["CL"]},"America/Santo_Domingo":{u:-240,c:["DO"]},"America/Sao_Paulo":{u:-180,c:["BR"]},"America/Scoresbysund":{u:-60,d:0,c:["GL"]},"America/Shiprock":{a:"America/Denver",r:1},"America/Sitka":{u:-540,d:-480,c:["US"]},"America/St_Barthelemy":{a:"America/Puerto_Rico",c:["BL"],r:1},"America/St_Johns":{u:-150,d:-90,c:["CA"]},"America/St_Kitts":{a:"America/Puerto_Rico",c:["KN"],r:1},"America/St_Lucia":{a:"America/Puerto_Rico",c:["LC"],r:1},"America/St_Thomas":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/St_Vincent":{a:"America/Puerto_Rico",c:["VC"],r:1},"America/Swift_Current":{u:-360,c:["CA"]},"America/Tegucigalpa":{u:-360,c:["HN"]},"America/Thule":{u:-240,d:-180,c:["GL"]},"America/Thunder_Bay":{u:-300,d:-240,c:["CA"]},"America/Tijuana":{u:-480,d:-420,c:["MX"]},"America/Toronto":{u:-300,d:-240,c:["CA","BS"]},"America/Tortola":{a:"America/Puerto_Rico",c:["VG"],r:1},"America/Vancouver":{u:-480,d:-420,c:["CA"]},"America/Virgin":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/Whitehorse":{u:-420,c:["CA"]},"America/Winnipeg":{u:-360,d:-300,c:["CA"]},"America/Yakutat":{u:-540,d:-480,c:["US"]},"America/Yellowknife":{u:-420,d:-360,c:["CA"]},"Antarctica/Casey":{u:660,c:["AQ"]},"Antarctica/Davis":{u:420,c:["AQ"]},"Antarctica/DumontDUrville":{a:"Pacific/Port_Moresby",c:["AQ"],r:1},"Antarctica/Macquarie":{u:600,d:660,c:["AU"]},"Antarctica/Mawson":{u:300,c:["AQ"]},"Antarctica/McMurdo":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Palmer":{u:-180,c:["AQ"]},"Antarctica/Rothera":{u:-180,c:["AQ"]},"Antarctica/South_Pole":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Syowa":{a:"Asia/Riyadh",c:["AQ"],r:1},"Antarctica/Troll":{u:0,d:120,c:["AQ"]},"Antarctica/Vostok":{u:360,c:["AQ"]},"Arctic/Longyearbyen":{a:"Europe/Oslo",c:["SJ"],r:1},"Asia/Aden":{a:"Asia/Riyadh",c:["YE"],r:1},"Asia/Almaty":{u:360,c:["KZ"]},"Asia/Amman":{u:120,d:180,c:["JO"]},"Asia/Anadyr":{u:720,c:["RU"]},"Asia/Aqtau":{u:300,c:["KZ"]},"Asia/Aqtobe":{u:300,c:["KZ"]},"Asia/Ashgabat":{u:300,c:["TM"]},"Asia/Ashkhabad":{a:"Asia/Ashgabat",r:1},"Asia/Atyrau":{u:300,c:["KZ"]},"Asia/Baghdad":{u:180,c:["IQ"]},"Asia/Bahrain":{a:"Asia/Qatar",c:["BH"],r:1},"Asia/Baku":{u:240,c:["AZ"]},"Asia/Bangkok":{u:420,c:["TH","KH","LA","VN"]},"Asia/Barnaul":{u:420,c:["RU"]},"Asia/Beirut":{u:120,d:180,c:["LB"]},"Asia/Bishkek":{u:360,c:["KG"]},"Asia/Brunei":{u:480,c:["BN"]},"Asia/Calcutta":{a:"Asia/Kolkata",r:1},"Asia/Chita":{u:540,c:["RU"]},"Asia/Choibalsan":{u:480,c:["MN"]},"Asia/Chongqing":{a:"Asia/Shanghai",r:1},"Asia/Chungking":{a:"Asia/Shanghai",r:1},"Asia/Colombo":{u:330,c:["LK"]},"Asia/Dacca":{a:"Asia/Dhaka",r:1},"Asia/Damascus":{u:120,d:180,c:["SY"]},"Asia/Dhaka":{u:360,c:["BD"]},"Asia/Dili":{u:540,c:["TL"]},"Asia/Dubai":{u:240,c:["AE","OM"]},"Asia/Dushanbe":{u:300,c:["TJ"]},"Asia/Famagusta":{u:120,d:180,c:["CY"]},"Asia/Gaza":{u:120,d:180,c:["PS"]},"Asia/Harbin":{a:"Asia/Shanghai",r:1},"Asia/Hebron":{u:120,d:180,c:["PS"]},"Asia/Ho_Chi_Minh":{u:420,c:["VN"]},"Asia/Hong_Kong":{u:480,c:["HK"]},"Asia/Hovd":{u:420,c:["MN"]},"Asia/Irkutsk":{u:480,c:["RU"]},"Asia/Istanbul":{a:"Europe/Istanbul",r:1},"Asia/Jakarta":{u:420,c:["ID"]},"Asia/Jayapura":{u:540,c:["ID"]},"Asia/Jerusalem":{u:120,d:180,c:["IL"]},"Asia/Kabul":{u:270,c:["AF"]},"Asia/Kamchatka":{u:720,c:["RU"]},"Asia/Karachi":{u:300,c:["PK"]},"Asia/Kashgar":{a:"Asia/Urumqi",r:1},"Asia/Kathmandu":{u:345,c:["NP"]},"Asia/Katmandu":{a:"Asia/Kathmandu",r:1},"Asia/Khandyga":{u:540,c:["RU"]},"Asia/Kolkata":{u:330,c:["IN"]},"Asia/Krasnoyarsk":{u:420,c:["RU"]},"Asia/Kuala_Lumpur":{u:480,c:["MY"]},"Asia/Kuching":{u:480,c:["MY"]},"Asia/Kuwait":{a:"Asia/Riyadh",c:["KW"],r:1},"Asia/Macao":{a:"Asia/Macau",r:1},"Asia/Macau":{u:480,c:["MO"]},"Asia/Magadan":{u:660,c:["RU"]},"Asia/Makassar":{u:480,c:["ID"]},"Asia/Manila":{u:480,c:["PH"]},"Asia/Muscat":{a:"Asia/Dubai",c:["OM"],r:1},"Asia/Nicosia":{u:120,d:180,c:["CY"]},"Asia/Novokuznetsk":{u:420,c:["RU"]},"Asia/Novosibirsk":{u:420,c:["RU"]},"Asia/Omsk":{u:360,c:["RU"]},"Asia/Oral":{u:300,c:["KZ"]},"Asia/Phnom_Penh":{a:"Asia/Bangkok",c:["KH"],r:1},"Asia/Pontianak":{u:420,c:["ID"]},"Asia/Pyongyang":{u:540,c:["KP"]},"Asia/Qatar":{u:180,c:["QA","BH"]},"Asia/Qostanay":{u:360,c:["KZ"]},"Asia/Qyzylorda":{u:300,c:["KZ"]},"Asia/Rangoon":{a:"Asia/Yangon",r:1},"Asia/Riyadh":{u:180,c:["SA","AQ","KW","YE"]},"Asia/Saigon":{a:"Asia/Ho_Chi_Minh",r:1},"Asia/Sakhalin":{u:660,c:["RU"]},"Asia/Samarkand":{u:300,c:["UZ"]},"Asia/Seoul":{u:540,c:["KR"]},"Asia/Shanghai":{u:480,c:["CN"]},"Asia/Singapore":{u:480,c:["SG","MY"]},"Asia/Srednekolymsk":{u:660,c:["RU"]},"Asia/Taipei":{u:480,c:["TW"]},"Asia/Tashkent":{u:300,c:["UZ"]},"Asia/Tbilisi":{u:240,c:["GE"]},"Asia/Tehran":{u:210,d:270,c:["IR"]},"Asia/Tel_Aviv":{a:"Asia/Jerusalem",r:1},"Asia/Thimbu":{a:"Asia/Thimphu",r:1},"Asia/Thimphu":{u:360,c:["BT"]},"Asia/Tokyo":{u:540,c:["JP"]},"Asia/Tomsk":{u:420,c:["RU"]},"Asia/Ujung_Pandang":{a:"Asia/Makassar",r:1},"Asia/Ulaanbaatar":{u:480,c:["MN"]},"Asia/Ulan_Bator":{a:"Asia/Ulaanbaatar",r:1},"Asia/Urumqi":{u:360,c:["CN"]},"Asia/Ust-Nera":{u:600,c:["RU"]},"Asia/Vientiane":{a:"Asia/Bangkok",c:["LA"],r:1},"Asia/Vladivostok":{u:600,c:["RU"]},"Asia/Yakutsk":{u:540,c:["RU"]},"Asia/Yangon":{u:390,c:["MM"]},"Asia/Yekaterinburg":{u:300,c:["RU"]},"Asia/Yerevan":{u:240,c:["AM"]},"Atlantic/Azores":{u:-60,d:0,c:["PT"]},"Atlantic/Bermuda":{u:-240,d:-180,c:["BM"]},"Atlantic/Canary":{u:0,d:60,c:["ES"]},"Atlantic/Cape_Verde":{u:-60,c:["CV"]},"Atlantic/Faeroe":{a:"Atlantic/Faroe",r:1},"Atlantic/Faroe":{u:0,d:60,c:["FO"]},"Atlantic/Jan_Mayen":{a:"Europe/Oslo",c:["SJ"],r:1},"Atlantic/Madeira":{u:0,d:60,c:["PT"]},"Atlantic/Reykjavik":{u:0,c:["IS"]},"Atlantic/South_Georgia":{u:-120,c:["GS"]},"Atlantic/St_Helena":{a:"Africa/Abidjan",c:["SH"],r:1},"Atlantic/Stanley":{u:-180,c:["FK"]},"Australia/ACT":{a:"Australia/Sydney",r:1},"Australia/Adelaide":{u:570,d:630,c:["AU"]},"Australia/Brisbane":{u:600,c:["AU"]},"Australia/Broken_Hill":{u:570,d:630,c:["AU"]},"Australia/Canberra":{a:"Australia/Sydney",r:1},"Australia/Currie":{a:"Australia/Hobart",r:1},"Australia/Darwin":{u:570,c:["AU"]},"Australia/Eucla":{u:525,c:["AU"]},"Australia/Hobart":{u:600,d:660,c:["AU"]},"Australia/LHI":{a:"Australia/Lord_Howe",r:1},"Australia/Lindeman":{u:600,c:["AU"]},"Australia/Lord_Howe":{u:630,d:660,c:["AU"]},"Australia/Melbourne":{u:600,d:660,c:["AU"]},"Australia/NSW":{a:"Australia/Sydney",r:1},"Australia/North":{a:"Australia/Darwin",r:1},"Australia/Perth":{u:480,c:["AU"]},"Australia/Queensland":{a:"Australia/Brisbane",r:1},"Australia/South":{a:"Australia/Adelaide",r:1},"Australia/Sydney":{u:600,d:660,c:["AU"]},"Australia/Tasmania":{a:"Australia/Hobart",r:1},"Australia/Victoria":{a:"Australia/Melbourne",r:1},"Australia/West":{a:"Australia/Perth",r:1},"Australia/Yancowinna":{a:"Australia/Broken_Hill",r:1},"Brazil/Acre":{a:"America/Rio_Branco",r:1},"Brazil/DeNoronha":{a:"America/Noronha",r:1},"Brazil/East":{a:"America/Sao_Paulo",r:1},"Brazil/West":{a:"America/Manaus",r:1},CET:{u:60,d:120},CST6CDT:{u:-360,d:-300},"Canada/Atlantic":{a:"America/Halifax",r:1},"Canada/Central":{a:"America/Winnipeg",r:1},"Canada/Eastern":{a:"America/Toronto",c:["CA"],r:1},"Canada/Mountain":{a:"America/Edmonton",r:1},"Canada/Newfoundland":{a:"America/St_Johns",r:1},"Canada/Pacific":{a:"America/Vancouver",r:1},"Canada/Saskatchewan":{a:"America/Regina",r:1},"Canada/Yukon":{a:"America/Whitehorse",r:1},"Chile/Continental":{a:"America/Santiago",r:1},"Chile/EasterIsland":{a:"Pacific/Easter",r:1},Cuba:{a:"America/Havana",r:1},EET:{u:120,d:180},EST:{u:-300},EST5EDT:{u:-300,d:-240},Egypt:{a:"Africa/Cairo",r:1},Eire:{a:"Europe/Dublin",r:1},"Etc/GMT":{u:0},"Etc/GMT+0":{a:"Etc/GMT",r:1},"Etc/GMT+1":{u:-60},"Etc/GMT+10":{u:-600},"Etc/GMT+11":{u:-660},"Etc/GMT+12":{u:-720},"Etc/GMT+2":{u:-120},"Etc/GMT+3":{u:-180},"Etc/GMT+4":{u:-240},"Etc/GMT+5":{u:-300},"Etc/GMT+6":{u:-360},"Etc/GMT+7":{u:-420},"Etc/GMT+8":{u:-480},"Etc/GMT+9":{u:-540},"Etc/GMT-0":{a:"Etc/GMT",r:1},"Etc/GMT-1":{u:60},"Etc/GMT-10":{u:600},"Etc/GMT-11":{u:660},"Etc/GMT-12":{u:720},"Etc/GMT-13":{u:780},"Etc/GMT-14":{u:840},"Etc/GMT-2":{u:120},"Etc/GMT-3":{u:180},"Etc/GMT-4":{u:240},"Etc/GMT-5":{u:300},"Etc/GMT-6":{u:360},"Etc/GMT-7":{u:420},"Etc/GMT-8":{u:480},"Etc/GMT-9":{u:540},"Etc/GMT0":{a:"Etc/GMT",r:1},"Etc/Greenwich":{a:"Etc/GMT",r:1},"Etc/UCT":{a:"Etc/UTC",r:1},"Etc/UTC":{u:0},"Etc/Universal":{a:"Etc/UTC",r:1},"Etc/Zulu":{a:"Etc/UTC",r:1},"Europe/Amsterdam":{u:60,d:120,c:["NL"]},"Europe/Andorra":{u:60,d:120,c:["AD"]},"Europe/Astrakhan":{u:240,c:["RU"]},"Europe/Athens":{u:120,d:180,c:["GR"]},"Europe/Belfast":{a:"Europe/London",c:["GB"],r:1},"Europe/Belgrade":{u:60,d:120,c:["RS","BA","HR","ME","MK","SI"]},"Europe/Berlin":{u:60,d:120,c:["DE"]},"Europe/Bratislava":{a:"Europe/Prague",c:["SK"],r:1},"Europe/Brussels":{u:60,d:120,c:["BE"]},"Europe/Bucharest":{u:120,d:180,c:["RO"]},"Europe/Budapest":{u:60,d:120,c:["HU"]},"Europe/Busingen":{a:"Europe/Zurich",c:["DE"],r:1},"Europe/Chisinau":{u:120,d:180,c:["MD"]},"Europe/Copenhagen":{u:60,d:120,c:["DK"]},"Europe/Dublin":{u:60,d:0,c:["IE"]},"Europe/Gibraltar":{u:60,d:120,c:["GI"]},"Europe/Guernsey":{a:"Europe/London",c:["GG"],r:1},"Europe/Helsinki":{u:120,d:180,c:["FI","AX"]},"Europe/Isle_of_Man":{a:"Europe/London",c:["IM"],r:1},"Europe/Istanbul":{u:180,c:["TR"]},"Europe/Jersey":{a:"Europe/London",c:["JE"],r:1},"Europe/Kaliningrad":{u:120,c:["RU"]},"Europe/Kiev":{u:120,d:180,c:["UA"]},"Europe/Kirov":{u:180,c:["RU"]},"Europe/Lisbon":{u:0,d:60,c:["PT"]},"Europe/Ljubljana":{a:"Europe/Belgrade",c:["SI"],r:1},"Europe/London":{u:0,d:60,c:["GB","GG","IM","JE"]},"Europe/Luxembourg":{u:60,d:120,c:["LU"]},"Europe/Madrid":{u:60,d:120,c:["ES"]},"Europe/Malta":{u:60,d:120,c:["MT"]},"Europe/Mariehamn":{a:"Europe/Helsinki",c:["AX"],r:1},"Europe/Minsk":{u:180,c:["BY"]},"Europe/Monaco":{u:60,d:120,c:["MC"]},"Europe/Moscow":{u:180,c:["RU"]},"Europe/Nicosia":{a:"Asia/Nicosia",r:1},"Europe/Oslo":{u:60,d:120,c:["NO","SJ","BV"]},"Europe/Paris":{u:60,d:120,c:["FR"]},"Europe/Podgorica":{a:"Europe/Belgrade",c:["ME"],r:1},"Europe/Prague":{u:60,d:120,c:["CZ","SK"]},"Europe/Riga":{u:120,d:180,c:["LV"]},"Europe/Rome":{u:60,d:120,c:["IT","SM","VA"]},"Europe/Samara":{u:240,c:["RU"]},"Europe/San_Marino":{a:"Europe/Rome",c:["SM"],r:1},"Europe/Sarajevo":{a:"Europe/Belgrade",c:["BA"],r:1},"Europe/Saratov":{u:240,c:["RU"]},"Europe/Simferopol":{u:180,c:["RU","UA"]},"Europe/Skopje":{a:"Europe/Belgrade",c:["MK"],r:1},"Europe/Sofia":{u:120,d:180,c:["BG"]},"Europe/Stockholm":{u:60,d:120,c:["SE"]},"Europe/Tallinn":{u:120,d:180,c:["EE"]},"Europe/Tirane":{u:60,d:120,c:["AL"]},"Europe/Tiraspol":{a:"Europe/Chisinau",r:1},"Europe/Ulyanovsk":{u:240,c:["RU"]},"Europe/Uzhgorod":{u:120,d:180,c:["UA"]},"Europe/Vaduz":{a:"Europe/Zurich",c:["LI"],r:1},"Europe/Vatican":{a:"Europe/Rome",c:["VA"],r:1},"Europe/Vienna":{u:60,d:120,c:["AT"]},"Europe/Vilnius":{u:120,d:180,c:["LT"]},"Europe/Volgograd":{u:180,c:["RU"]},"Europe/Warsaw":{u:60,d:120,c:["PL"]},"Europe/Zagreb":{a:"Europe/Belgrade",c:["HR"],r:1},"Europe/Zaporozhye":{u:120,d:180,c:["UA"]},"Europe/Zurich":{u:60,d:120,c:["CH","DE","LI"]},Factory:{u:0},GB:{a:"Europe/London",c:["GB"],r:1},"GB-Eire":{a:"Europe/London",c:["GB"],r:1},GMT:{a:"Etc/GMT",r:1},"GMT+0":{a:"Etc/GMT",r:1},"GMT-0":{a:"Etc/GMT",r:1},GMT0:{a:"Etc/GMT",r:1},Greenwich:{a:"Etc/GMT",r:1},HST:{u:-600},Hongkong:{a:"Asia/Hong_Kong",r:1},Iceland:{a:"Atlantic/Reykjavik",r:1},"Indian/Antananarivo":{a:"Africa/Nairobi",c:["MG"],r:1},"Indian/Chagos":{u:360,c:["IO"]},"Indian/Christmas":{u:420,c:["CX"]},"Indian/Cocos":{u:390,c:["CC"]},"Indian/Comoro":{a:"Africa/Nairobi",c:["KM"],r:1},"Indian/Kerguelen":{u:300,c:["TF","HM"]},"Indian/Mahe":{u:240,c:["SC"]},"Indian/Maldives":{u:300,c:["MV"]},"Indian/Mauritius":{u:240,c:["MU"]},"Indian/Mayotte":{a:"Africa/Nairobi",c:["YT"],r:1},"Indian/Reunion":{u:240,c:["RE","TF"]},Iran:{a:"Asia/Tehran",r:1},Israel:{a:"Asia/Jerusalem",r:1},Jamaica:{a:"America/Jamaica",r:1},Japan:{a:"Asia/Tokyo",r:1},Kwajalein:{a:"Pacific/Kwajalein",r:1},Libya:{a:"Africa/Tripoli",r:1},MET:{u:60,d:120},MST:{u:-420},MST7MDT:{u:-420,d:-360},"Mexico/BajaNorte":{a:"America/Tijuana",r:1},"Mexico/BajaSur":{a:"America/Mazatlan",r:1},"Mexico/General":{a:"America/Mexico_City",r:1},NZ:{a:"Pacific/Auckland",c:["NZ"],r:1},"NZ-CHAT":{a:"Pacific/Chatham",r:1},Navajo:{a:"America/Denver",r:1},PRC:{a:"Asia/Shanghai",r:1},PST8PDT:{u:-480,d:-420},"Pacific/Apia":{u:780,c:["WS"]},"Pacific/Auckland":{u:720,d:780,c:["NZ","AQ"]},"Pacific/Bougainville":{u:660,c:["PG"]},"Pacific/Chatham":{u:765,d:825,c:["NZ"]},"Pacific/Chuuk":{u:600,c:["FM"]},"Pacific/Easter":{u:-360,d:-300,c:["CL"]},"Pacific/Efate":{u:660,c:["VU"]},"Pacific/Enderbury":{a:"Pacific/Kanton",r:1},"Pacific/Fakaofo":{u:780,c:["TK"]},"Pacific/Fiji":{u:720,d:780,c:["FJ"]},"Pacific/Funafuti":{u:720,c:["TV"]},"Pacific/Galapagos":{u:-360,c:["EC"]},"Pacific/Gambier":{u:-540,c:["PF"]},"Pacific/Guadalcanal":{u:660,c:["SB"]},"Pacific/Guam":{u:600,c:["GU","MP"]},"Pacific/Honolulu":{u:-600,c:["US","UM"]},"Pacific/Johnston":{a:"Pacific/Honolulu",c:["UM"],r:1},"Pacific/Kanton":{u:780,c:["KI"]},"Pacific/Kiritimati":{u:840,c:["KI"]},"Pacific/Kosrae":{u:660,c:["FM"]},"Pacific/Kwajalein":{u:720,c:["MH"]},"Pacific/Majuro":{u:720,c:["MH"]},"Pacific/Marquesas":{u:-510,c:["PF"]},"Pacific/Midway":{a:"Pacific/Pago_Pago",c:["UM"],r:1},"Pacific/Nauru":{u:720,c:["NR"]},"Pacific/Niue":{u:-660,c:["NU"]},"Pacific/Norfolk":{u:660,d:720,c:["NF"]},"Pacific/Noumea":{u:660,c:["NC"]},"Pacific/Pago_Pago":{u:-660,c:["AS","UM"]},"Pacific/Palau":{u:540,c:["PW"]},"Pacific/Pitcairn":{u:-480,c:["PN"]},"Pacific/Pohnpei":{u:660,c:["FM"]},"Pacific/Ponape":{a:"Pacific/Pohnpei",r:1},"Pacific/Port_Moresby":{u:600,c:["PG","AQ"]},"Pacific/Rarotonga":{u:-600,c:["CK"]},"Pacific/Saipan":{a:"Pacific/Guam",c:["MP"],r:1},"Pacific/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},"Pacific/Tahiti":{u:-600,c:["PF"]},"Pacific/Tarawa":{u:720,c:["KI"]},"Pacific/Tongatapu":{u:780,c:["TO"]},"Pacific/Truk":{a:"Pacific/Chuuk",r:1},"Pacific/Wake":{u:720,c:["UM"]},"Pacific/Wallis":{u:720,c:["WF"]},"Pacific/Yap":{a:"Pacific/Chuuk",r:1},Poland:{a:"Europe/Warsaw",r:1},Portugal:{a:"Europe/Lisbon",r:1},ROC:{a:"Asia/Taipei",r:1},ROK:{a:"Asia/Seoul",r:1},Singapore:{a:"Asia/Singapore",c:["SG"],r:1},Turkey:{a:"Europe/Istanbul",r:1},UCT:{a:"Etc/UTC",r:1},"US/Alaska":{a:"America/Anchorage",r:1},"US/Aleutian":{a:"America/Adak",r:1},"US/Arizona":{a:"America/Phoenix",c:["US"],r:1},"US/Central":{a:"America/Chicago",r:1},"US/East-Indiana":{a:"America/Indiana/Indianapolis",r:1},"US/Eastern":{a:"America/New_York",r:1},"US/Hawaii":{a:"Pacific/Honolulu",c:["US"],r:1},"US/Indiana-Starke":{a:"America/Indiana/Knox",r:1},"US/Michigan":{a:"America/Detroit",r:1},"US/Mountain":{a:"America/Denver",r:1},"US/Pacific":{a:"America/Los_Angeles",r:1},"US/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},UTC:{a:"Etc/UTC",r:1},Universal:{a:"Etc/UTC",r:1},"W-SU":{a:"Europe/Moscow",r:1},WET:{u:0,d:60},Zulu:{a:"Etc/UTC",r:1}};function $(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return null;try{let e=Q[s]?.c?.[0];return e&&he[e]||null}catch{return null}}function k(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return"Unknown";try{return Q[s]?.c?.[0]||"Unknown"}catch{return"Unknown"}}function W(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;return s===""||!s?null:s.split("/")[1]?.replace("_"," ")||null}var P=class{constructor(e,t){this.isDestroyed=!1;this.currentPath=null;this.originalPushState=null;this.originalReplaceState=null;this.previousPage=null;this.landingPage=null;this.pageViewCount=0;this.handlePopState=()=>{this.isDestroyed||this.trackCurrentPage()};this.handleHashChange=()=>{this.isDestroyed||this.trackCurrentPage()};this.tracker=e,this.config=t,this.trackCurrentPage(!0),this.setupHistoryListeners(),this.setupHashChangeListener()}setupHistoryListeners(){typeof window>"u"||typeof history>"u"||(this.originalPushState=history.pushState,history.pushState=(e,t,i)=>{this.originalPushState?.call(history,e,t,i),this.trackCurrentPage()},this.originalReplaceState=history.replaceState,history.replaceState=(e,t,i)=>{this.originalReplaceState?.call(history,e,t,i),this.trackCurrentPage()},window.addEventListener("popstate",this.handlePopState))}setupHashChangeListener(){typeof window>"u"||window.addEventListener("hashchange",this.handleHashChange)}trackCurrentPage(e=!1){if(this.isDestroyed||typeof window>"u")return;let t=this.extractPath(window.location.href);if(!e&&t===this.currentPath)return;this.currentPath&&(this.previousPage=this.currentPath),this.currentPath=t,this.pageViewCount++,e&&(this.landingPage=t);let i=this.tracker.hasConsent("analytics"),r=window.location.href,a=document.referrer||"",n=v(r);Object.keys(n).length>0&&(!g()||e)&&z(n);let o=g()||{},c=w(this.config.tenantId,a,r,o),u={page:t,timestamp:Date.now()};if(i){u.title=document.title||"",u.full_url=r,u.session_id=this.tracker.getSessionId(),a&&(u.referrer=a,u.referrer_domain=this.extractDomain(a),u.referrer_category=h(a,r)),this.landingPage&&!e&&(u.landing_page=this.landingPage),this.previousPage&&(u.previous_page=this.previousPage),o.utm_source&&(u.utm_source=o.utm_source),o.utm_medium&&(u.utm_medium=o.utm_medium),o.utm_campaign&&(u.utm_campaign=o.utm_campaign),o.utm_term&&(u.utm_term=o.utm_term),o.utm_content&&(u.utm_content=o.utm_content),u.first_touch_source=c.source,u.first_touch_medium=c.medium,u.first_touch_campaign=c.campaign,u.first_touch_referrer_category=c.referrer_category,u.device=this.getDeviceType(),u.browser=this.getBrowser(),u.os=this.getOS(),u.language=navigator.language||"";let l=Intl.DateTimeFormat().resolvedOptions().timeZone;u.timezone=l,u.country=k(),u.screen_resolution=`${screen.width}x${screen.height}`,u.viewport=`${window.innerWidth}x${window.innerHeight}`}this.tracker.trackSystemEvent("page_view",u)}extractDomain(e){try{return new URL(e).hostname}catch{return""}}getBrowser(){let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}extractPath(e){try{let t=new URL(e),i=t.pathname+t.hash;return!this.config.stripQueryParams&&t.search&&(i+=t.search),i}catch(t){return this.config.debug&&console.warn("[Page Tracking] Failed to parse URL:",e,t),e}}getCurrentPage(){return this.currentPath}trackPage(e,t){if(this.isDestroyed)return;let i=this.tracker.hasConsent("analytics"),r={page:e,timestamp:Date.now(),...t};i&&typeof document<"u"&&typeof window<"u"&&(r.referrer||(r.referrer=document.referrer||""),r.title||(r.title=document.title||""),r.full_url||(r.full_url=window.location.href),r.session_id||(r.session_id=this.tracker.getSessionId()),r.browser||(r.browser=this.getBrowser()),r.os||(r.os=this.getOS())),this.tracker.trackSystemEvent("page_view",r)}getPageViewCount(){return this.pageViewCount}destroy(){this.isDestroyed||(typeof history<"u"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState)),typeof window<"u"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.isDestroyed=!0)}};var f=class{constructor(e){this.eventQueue=[];this.waitingForConsentQueue=[];this.flushTimer=null;this.isDestroyed=!1;this.globalUserId=null;this.persistentAnonymousUserId=null;this.configCache=null;this.configRefreshTimer=null;this.configChangeListeners=[];this.configFetchPromise=null;this.cookiesEnabled=!1;this.activityDetector=null;this.heartbeatManager=null;this.pageTrackingManager=null;this.ephemeralSessionId=null;this.eventCountSinceLastHeartbeat=0;this.interactionTrackingManager=null;this.sectionTrackingManager=null;this.heatmapTrackingManager=null;this.sessionStartTime=Date.now();this.sessionEventCount=0;this.config={apiUrl:"https://api.grainql.com",authStrategy:"NONE",batchSize:50,flushInterval:5e3,retryAttempts:3,retryDelay:1e3,maxEventsPerRequest:160,debug:!1,defaultConfigurations:{},configCacheKey:"grain_config",configRefreshInterval:3e5,enableConfigCache:!0,consentMode:"opt-out",waitForConsent:!1,enableCookies:!1,anonymizeIP:!1,disableAutoProperties:!1,enableHeartbeat:!0,heartbeatActiveInterval:12e4,heartbeatInactiveInterval:3e5,enableAutoPageView:!0,stripQueryParams:!0,enableHeatmapTracking:!0,...e,tenantId:e.tenantId},this.consentManager=new T(this.config.tenantId,this.config.consentMode),this.config.enableCookies&&(this.cookiesEnabled=F(),!this.cookiesEnabled&&this.config.debug&&console.warn("[Grain Analytics] Cookies are not available, falling back to localStorage")),e.userId&&(this.globalUserId=e.userId),this.validateConfig(),this.initializePersistentAnonymousUserId(),this.setupBeforeUnload(),this.startFlushTimer(),this.initializeConfigCache(),this.ephemeralSessionId=this.generateUUID(),typeof window<"u"&&(this.initializeAutomaticTracking(),this.trackSessionStart(),this.config.enableHeatmapTracking&&this.initializeHeatmapTracking()),this.consentManager.addListener(t=>{t.granted&&this.handleConsentGranted()})}validateConfig(){if(!this.config.tenantId)throw new Error("Grain Analytics: tenantId is required");if(this.config.authStrategy==="SERVER_SIDE"&&!this.config.secretKey)throw new Error("Grain Analytics: secretKey is required for SERVER_SIDE auth strategy");if(this.config.authStrategy==="JWT"&&!this.config.authProvider)throw new Error("Grain Analytics: authProvider is required for JWT auth strategy")}generateUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}shouldAllowPersistentStorage(){let e=this.consentManager.hasConsent("analytics"),t=this.config.consentMode==="opt-in",i=!!this.globalUserId,r=this.config.authStrategy==="JWT";return e||!t||i||r}generateAnonymousUserId(){return this.generateUUID()}initializePersistentAnonymousUserId(){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID initialization (GDPR compliance)");return}let e=`grain_anonymous_user_id_${this.config.tenantId}`,t="_grain_uid";try{if(this.cookiesEnabled){let r=D(t);if(r){this.persistentAnonymousUserId=r,this.log("Loaded persistent anonymous user ID from cookie:",this.persistentAnonymousUserId);return}}let i=localStorage.getItem(e);i?(this.persistentAnonymousUserId=i,this.log("Loaded persistent anonymous user ID from localStorage:",this.persistentAnonymousUserId),this.cookiesEnabled&&this.savePersistentAnonymousUserId(i)):(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.log("Generated new persistent anonymous user ID:",this.persistentAnonymousUserId))}catch(i){this.log("Failed to initialize persistent anonymous user ID:",i),this.persistentAnonymousUserId=this.generateAnonymousUserId()}}savePersistentAnonymousUserId(e){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID save (GDPR compliance)");return}let t=`grain_anonymous_user_id_${this.config.tenantId}`,i="_grain_uid";try{if(this.cookiesEnabled){let r={maxAge:31536e3,sameSite:"lax",secure:typeof window<"u"&&window.location.protocol==="https:",...this.config.cookieOptions};I(i,e,r)}localStorage.setItem(t,e)}catch(r){this.log("Failed to save persistent anonymous user ID:",r)}}getEffectiveUserIdInternal(){return this.globalUserId?this.globalUserId:this.persistentAnonymousUserId?this.persistentAnonymousUserId:(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.persistentAnonymousUserId)}log(...e){this.config.debug&&console.log("[Grain Analytics]",...e)}createErrorDigest(e){let t=[...new Set(e.map(n=>n.eventName))],i=[...new Set(e.map(n=>n.userId))],r=0,a=0;return e.forEach(n=>{let o=n.properties||{};r+=Object.keys(o).length,a+=JSON.stringify(n).length}),{eventCount:e.length,totalProperties:r,totalSize:a,eventNames:t,userIds:i}}formatError(e,t,i){let r=i?this.createErrorDigest(i):{eventCount:0,totalProperties:0,totalSize:0,eventNames:[],userIds:[]},a="UNKNOWN_ERROR",n="An unknown error occurred";if(e instanceof Error)n=e.message,n.includes("fetch failed")||n.includes("network error")?a="NETWORK_ERROR":n.includes("timeout")?a="TIMEOUT_ERROR":n.includes("HTTP 4")?a="CLIENT_ERROR":n.includes("HTTP 5")?a="SERVER_ERROR":n.includes("JSON")?a="PARSE_ERROR":n.includes("auth")||n.includes("unauthorized")?a="AUTH_ERROR":n.includes("rate limit")||n.includes("429")?a="RATE_LIMIT_ERROR":a="GENERAL_ERROR";else if(typeof e=="string")n=e,a="STRING_ERROR";else if(e&&typeof e=="object"&&"status"in e){let o=e.status;a=`HTTP_${o}`,n=`HTTP ${o} error`}return{code:a,message:n,digest:r,timestamp:new Date().toISOString(),context:t,originalError:e}}logError(e){if(!this.config.debug)return;let{code:t,message:i,digest:r,timestamp:a,context:n}=e,o={"\u{1F6A8} Grain Analytics Error":{"Error Code":t,Message:i,Context:n,Timestamp:a,"Event Digest":{Events:r.eventCount,Properties:r.totalProperties,"Size (bytes)":r.totalSize,"Event Names":r.eventNames.length>0?r.eventNames.join(", "):"None","User IDs":r.userIds.length>0?r.userIds.slice(0,3).join(", ")+(r.userIds.length>3?"...":""):"None"}}};console.error("\u{1F6A8} Grain Analytics Error:",o),console.error(`[Grain Analytics] ${t}: ${i} (${n}) - Events: ${r.eventCount}, Props: ${r.totalProperties}, Size: ${r.totalSize}B`)}async safeExecute(e,t,i){try{return await e()}catch(r){let a=this.formatError(r,t,i);return this.logError(a),null}}formatEvent(e){let t=e.properties||{};if(!this.config.disableAutoProperties&&typeof window<"u"){let i=this.consentManager.hasConsent("analytics");if(!e.eventName.startsWith("_grain_")&&i){let a=g();a&&(a.utm_source&&(t.utm_source=a.utm_source),a.utm_medium&&(t.utm_medium=a.utm_medium),a.utm_campaign&&(t.utm_campaign=a.utm_campaign),a.utm_term&&(t.utm_term=a.utm_term),a.utm_content&&(t.utm_content=a.utm_content));let n=U(this.config.tenantId);n&&(t.first_touch_source=n.source,t.first_touch_medium=n.medium,t.first_touch_campaign=n.campaign,t.first_touch_referrer_category=n.referrer_category),t.session_id||(t.session_id=this.getSessionId())}}return{eventName:e.eventName,userId:e.userId||this.getEffectiveUserIdInternal(),properties:t}}async getAuthHeaders(){let e={"Content-Type":"application/json"};switch(this.config.authStrategy){case"NONE":break;case"SERVER_SIDE":e.Authorization=`Chase ${this.config.secretKey}`;break;case"JWT":if(this.config.authProvider){let t=await this.config.authProvider.getToken();e.Authorization=`Bearer ${t}`}break}return e}async delay(e){return new Promise(t=>setTimeout(t,e))}isRetriableError(e){if(e instanceof Error){let t=e.message.toLowerCase();if(t.includes("fetch failed")||t==="network error"||t.includes("timeout")||t.includes("connection"))return!0}if(typeof e=="object"&&e!==null&&"status"in e){let t=e.status;return t>=500||t===429}return!1}async sendEvents(e){if(e.length===0)return;let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(e)});if(!n.ok){let o=`HTTP ${n.status}`;try{let u=await n.json();u?.message&&(o=u.message)}catch{let u=await n.text();u&&(o=u)}let c=new Error(`Failed to send events: ${o}`);throw c.status=n.status,c}this.log(`Successfully sent ${e.length} events`);return}catch(r){if(t=r,i===this.config.retryAttempts){let n=this.formatError(r,`sendEvents (attempt ${i+1}/${this.config.retryAttempts+1})`,e);this.logError(n);return}if(!this.isRetriableError(r)){let n=this.formatError(r,"sendEvents (non-retriable error)",e);this.logError(n);return}let a=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${a}ms after error:`,r),await this.delay(a)}}async sendEventsWithBeacon(e){if(e.length!==0)try{let t=await this.getAuthHeaders(),i=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,r=JSON.stringify(e);if(!(this.config.authStrategy!=="NONE")&&typeof navigator<"u"&&"sendBeacon"in navigator){let n=new Blob([r],{type:"application/json"});if(navigator.sendBeacon(i,n)){this.log(`Successfully sent ${e.length} events via beacon`);return}}await fetch(i,{method:"POST",headers:t,body:r,keepalive:!0})}catch(t){let i=this.formatError(t,"sendEventsWithBeacon",e);this.logError(i)}}startFlushTimer(){typeof window>"u"||(this.flushTimer&&clearInterval(this.flushTimer),this.flushTimer=window.setInterval(()=>{this.eventQueue.length>0&&this.flush().catch(e=>{let t=this.formatError(e,"auto-flush");this.logError(t)})},this.config.flushInterval))}setupBeforeUnload(){if(typeof window>"u")return;let e=()=>{if(this.trackSessionEnd(),this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden"&&this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}})}initializeAutomaticTracking(){if(this.config.enableHeartbeat)try{this.activityDetector=new b,this.heartbeatManager=new C(this,this.activityDetector,{activeInterval:this.config.heartbeatActiveInterval,inactiveInterval:this.config.heartbeatInactiveInterval,debug:this.config.debug})}catch(e){this.log("Failed to initialize heartbeat tracking:",e)}if(this.config.enableAutoPageView)try{this.pageTrackingManager=new P(this,{stripQueryParams:this.config.stripQueryParams,debug:this.config.debug,tenantId:this.config.tenantId})}catch(e){this.log("Failed to initialize page view tracking:",e)}this.initializeAutoTracking()}initializeHeatmapTracking(){if(!(typeof window>"u"))try{this.log("Initializing heatmap tracking"),Promise.resolve().then(()=>(j(),J)).then(({HeatmapTrackingManager:e})=>{try{this.heatmapTrackingManager=new e(this,{scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:this.config.debug}),this.log("Heatmap tracking initialized")}catch(t){this.log("Failed to initialize heatmap tracking:",t)}}).catch(e=>{this.log("Failed to load heatmap tracking module:",e)})}catch(e){this.log("Failed to initialize heatmap tracking:",e)}}async initializeAutoTracking(){try{this.log("Initializing auto-tracking");let e=this.globalUserId||this.persistentAnonymousUserId||this.generateUUID(),t=typeof window<"u"?window.location.href:"",i={userId:e,immediateKeys:[],properties:{},currentUrl:t},r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(i)});if(!n.ok){this.log("Failed to fetch auto-tracking config:",n.status);return}let o=await n.json();o.autoTrackingConfig&&(this.log("Auto-tracking config loaded"),this.setupAutoTrackingManagers(o.autoTrackingConfig))}catch(e){this.log("Failed to initialize auto-tracking:",e)}}setupAutoTrackingManagers(e){this.log("Setting up auto-tracking managers"),e.interactions&&e.interactions.length>0&&(this.log("Loading interaction tracking:",e.interactions.length,"interactions"),Promise.resolve().then(()=>(Z(),Y)).then(({InteractionTrackingManager:t})=>{try{this.interactionTrackingManager=new t(this,e.interactions,{debug:this.config.debug,enableMutationObserver:!0,mutationDebounceDelay:500}),this.log("Interaction tracking initialized")}catch(i){this.log("Failed to initialize interaction tracking:",i)}}).catch(t=>{this.log("Failed to load interaction tracking module:",t)})),e.sections&&e.sections.length>0&&(this.log("Loading section tracking:",e.sections.length,"sections"),Promise.resolve().then(()=>(X(),q)).then(({SectionTrackingManager:t})=>{try{this.sectionTrackingManager=new t(this,e.sections,{minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:this.config.debug}),this.log("Section tracking initialized")}catch(i){this.log("Failed to initialize section tracking:",i)}}).catch(t=>{this.log("Failed to load section tracking module:",t)}))}trackSessionStart(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t={session_id:this.getSessionId(),timestamp:this.sessionStartTime};if(e){let i=document.referrer||"",r=window.location.href,a=v(r),n=g()||a,o=w(this.config.tenantId,i,r,n);t.landing_page=window.location.pathname,i?(t.referrer=i,t.referrer_domain=new URL(i).hostname,t.referrer_category=h(i,r)):t.referrer_category="direct",n.utm_source&&(t.utm_source=n.utm_source),n.utm_medium&&(t.utm_medium=n.utm_medium),n.utm_campaign&&(t.utm_campaign=n.utm_campaign),n.utm_term&&(t.utm_term=n.utm_term),n.utm_content&&(t.utm_content=n.utm_content),t.first_touch_source=o.source,t.first_touch_medium=o.medium,t.first_touch_campaign=o.campaign,t.first_touch_referrer_category=o.referrer_category,t.device=this.getDeviceType(),t.screen_resolution=`${screen.width}x${screen.height}`,t.viewport=`${window.innerWidth}x${window.innerHeight}`,t.browser=this.getBrowser(),t.os=this.getOS(),t.language=navigator.language||"",t.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}this.trackSystemEvent("_grain_session_start",t),this.log("Session started")}trackSessionEnd(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t=Date.now()-this.sessionStartTime,i={session_id:this.getSessionId(),session_duration:Math.floor(t/1e3),duration:t,event_count:this.sessionEventCount,timestamp:Date.now()};if(e&&this.pageTrackingManager){let r=this.pageTrackingManager.getPageViewCount();i.pages_per_session=r,i.page_count=r}this.trackSystemEvent("_grain_session_end",i),this.log("Session ended")}getBrowser(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){if(typeof window>"u"||typeof navigator>"u")return"Unknown";let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}handleConsentGranted(){this.flushWaitingForConsentQueue(),this.persistentAnonymousUserId||(this.initializePersistentAnonymousUserId(),this.log("Initialized persistent ID after consent grant")),this.ephemeralSessionId&&this.trackSystemEvent("_grain_consent_granted",{previous_session_id:this.ephemeralSessionId,new_user_id:this.getEffectiveUserId(),timestamp:Date.now()})}trackSystemEvent(e,t){if(this.isDestroyed)return;let i=this.consentManager.hasConsent("analytics"),r={eventName:e,userId:i?this.getEffectiveUserId():this.getEphemeralSessionId(),properties:{...t,_minimal:!i,_consent_status:i?"granted":"pending"}};this.eventQueue.push(r),this.eventCountSinceLastHeartbeat++,this.log(`Queued system event: ${e}`),this.eventQueue.length>=this.config.batchSize&&this.flush().catch(a=>{let n=this.formatError(a,"flush system event");this.logError(n)})}getEphemeralSessionId(){return this.ephemeralSessionId||(this.ephemeralSessionId=this.generateUUID()),this.ephemeralSessionId}getCurrentPage(){return this.pageTrackingManager?.getCurrentPage()||null}getEventCountSinceLastHeartbeat(){return this.eventCountSinceLastHeartbeat}resetEventCountSinceLastHeartbeat(){this.eventCountSinceLastHeartbeat=0}getActivityDetector(){if(!this.activityDetector)throw new Error("Activity detector not initialized");return this.activityDetector}getEffectiveUserId(){return this.getEffectiveUserIdInternal()}getSessionId(){return this.consentManager.hasConsent("analytics")?this.getEffectiveUserId():this.getEphemeralSessionId()}async track(e,t,i){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"track (client destroyed)");this.logError(c);return}let r,a={};if(typeof e=="string"?(r={eventName:e,properties:t},a=i||{}):(r=e,a=t||{}),this.config.allowedProperties&&r.properties){let o={};for(let c of this.config.allowedProperties)c in r.properties&&(o[c]=r.properties[c]);r.properties=o}let n=this.formatEvent(r);if(this.consentManager.shouldWaitForConsent()&&this.config.waitForConsent){this.waitingForConsentQueue.push(n),this.log(`Event waiting for consent: ${r.eventName}`,r.properties);return}if(!this.consentManager.hasConsent("analytics")){this.log(`Event blocked by consent: ${r.eventName}`);return}this.eventQueue.push(n),this.eventCountSinceLastHeartbeat++,this.sessionEventCount++,this.log(`Queued event: ${r.eventName}`),(a.flush||this.eventQueue.length>=this.config.batchSize)&&await this.flush()}catch(r){let a=this.formatError(r,"track");this.logError(a)}}flushWaitingForConsentQueue(){this.waitingForConsentQueue.length!==0&&(this.log(`Flushing ${this.waitingForConsentQueue.length} events waiting for consent`),this.eventQueue.push(...this.waitingForConsentQueue),this.waitingForConsentQueue=[],this.flush().catch(e=>{let t=this.formatError(e,"flush waiting for consent queue");this.logError(t)}))}identify(e){this.log(`Identified user: ${e}`),this.globalUserId=e,this.persistentAnonymousUserId=null}setUserId(e){this.log(`Set global user ID: ${e}`),this.globalUserId=e,e?this.persistentAnonymousUserId=null:this.persistentAnonymousUserId||(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId))}getUserId(){return this.globalUserId}getEffectiveUserIdPublic(){return this.getEffectiveUserIdInternal()}login(e){try{if(this.isDestroyed){let t=new Error("Grain Analytics: Client has been destroyed"),i=this.formatError(t,"login (client destroyed)");this.logError(i);return}e.userId&&(this.log(`Login: Setting user ID to ${e.userId}`),this.globalUserId=e.userId,this.persistentAnonymousUserId=null),e.authToken&&(this.log("Login: Setting auth token"),this.config.authStrategy==="NONE"&&(this.config.authStrategy="JWT"),this.config.authProvider={getToken:()=>e.authToken}),e.authStrategy&&(this.log(`Login: Setting auth strategy to ${e.authStrategy}`),this.config.authStrategy=e.authStrategy),this.log(`Login successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(t){let i=this.formatError(t,"login");this.logError(i)}}logout(){try{if(this.isDestroyed){let e=new Error("Grain Analytics: Client has been destroyed"),t=this.formatError(e,"logout (client destroyed)");this.logError(t);return}if(this.log("Logout: Clearing user session"),this.globalUserId=null,this.config.authStrategy="NONE",this.config.authProvider=void 0,!this.persistentAnonymousUserId&&(this.persistentAnonymousUserId=this.generateAnonymousUserId(),typeof window<"u"))try{let e=`grain_anonymous_user_id_${this.config.tenantId}`;localStorage.setItem(e,this.persistentAnonymousUserId)}catch(e){this.log("Failed to persist new anonymous user ID after logout:",e)}this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(e){let t=this.formatError(e,"logout");this.logError(t)}}async setProperty(e,t){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"setProperty (client destroyed)");this.logError(c);return}let i=t?.userId||this.getEffectiveUserIdInternal(),r=Object.keys(e);if(r.length>4){let o=new Error("Grain Analytics: Maximum 4 properties allowed per request"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}if(r.length===0){let o=new Error("Grain Analytics: At least one property is required"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}let a={};for(let[o,c]of Object.entries(e))c==null?a[o]="":typeof c=="string"?a[o]=c:a[o]=JSON.stringify(c);let n={userId:i,...a};await this.sendProperties(n)}catch(i){let r=this.formatError(i,"setProperty");this.logError(r)}}async sendProperties(e){let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),a=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`,n=await fetch(a,{method:"POST",headers:r,body:JSON.stringify(e)});if(!n.ok){let o=`HTTP ${n.status}`;try{let u=await n.json();u?.message&&(o=u.message)}catch{let u=await n.text();u&&(o=u)}let c=new Error(`Failed to set properties: ${o}`);throw c.status=n.status,c}this.log(`Successfully set properties for user ${e.userId}`);return}catch(r){if(t=r,i===this.config.retryAttempts){let n=this.formatError(r,`sendProperties (attempt ${i+1}/${this.config.retryAttempts+1})`);this.logError(n);return}if(!this.isRetriableError(r)){let n=this.formatError(r,"sendProperties (non-retriable error)");this.logError(n);return}let a=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${a}ms after error:`,r),await this.delay(a)}}async trackLogin(e,t){try{return await this.track("login",e,t)}catch(i){let r=this.formatError(i,"trackLogin");this.logError(r)}}async trackSignup(e,t){try{return await this.track("signup",e,t)}catch(i){let r=this.formatError(i,"trackSignup");this.logError(r)}}async trackCheckout(e,t){try{return await this.track("checkout",e,t)}catch(i){let r=this.formatError(i,"trackCheckout");this.logError(r)}}async trackPageView(e,t){try{return await this.track("page_view",e,t)}catch(i){let r=this.formatError(i,"trackPageView");this.logError(r)}}async trackPurchase(e,t){try{return await this.track("purchase",e,t)}catch(i){let r=this.formatError(i,"trackPurchase");this.logError(r)}}async trackSearch(e,t){try{return await this.track("search",e,t)}catch(i){let r=this.formatError(i,"trackSearch");this.logError(r)}}async trackAddToCart(e,t){try{return await this.track("add_to_cart",e,t)}catch(i){let r=this.formatError(i,"trackAddToCart");this.logError(r)}}async trackRemoveFromCart(e,t){try{return await this.track("remove_from_cart",e,t)}catch(i){let r=this.formatError(i,"trackRemoveFromCart");this.logError(r)}}async flush(){try{if(this.eventQueue.length===0)return;let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);for(let i of t)await this.sendEvents(i)}catch(e){let t=this.formatError(e,"flush");this.logError(t)}}initializeConfigCache(){if(!(!this.config.enableConfigCache||typeof window>"u"))try{let e=localStorage.getItem(this.config.configCacheKey);e&&(this.configCache=JSON.parse(e),this.log("Loaded configuration from cache:",this.configCache))}catch(e){this.log("Failed to load configuration cache:",e)}}saveConfigCache(e){if(!(!this.config.enableConfigCache||typeof window>"u"))try{localStorage.setItem(this.config.configCacheKey,JSON.stringify(e)),this.log("Saved configuration to cache:",e)}catch(t){this.log("Failed to save configuration cache:",t)}}getConfig(e){if(this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e]}getAllConfigs(){let e={...this.config.defaultConfigurations};return this.configCache?.configurations&&Object.assign(e,this.configCache.configurations),e}async fetchConfig(e={}){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"fetchConfig (client destroyed)");return this.logError(c),null}let t=e.userId||this.getEffectiveUserIdInternal(),i=e.immediateKeys||[],r=e.properties||{},a={userId:t,immediateKeys:i,properties:r},n;for(let o=0;o<=this.config.retryAttempts;o++)try{let c=await this.getAuthHeaders(),u=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,l=await fetch(u,{method:"POST",headers:c,body:JSON.stringify(a)});if(!l.ok){let y=`HTTP ${l.status}`;try{let p=await l.json();p?.message&&(y=p.message)}catch{let p=await l.text();p&&(y=p)}let G=new Error(`Failed to fetch configurations: ${y}`);throw G.status=l.status,G}let d=await l.json();return d.configurations&&this.updateConfigCache(d,t),this.log("Successfully fetched configurations"),d}catch(c){if(n=c,o===this.config.retryAttempts){let l=this.formatError(c,`fetchConfig (attempt ${o+1}/${this.config.retryAttempts+1})`);return this.logError(l),null}if(!this.isRetriableError(c)){let l=this.formatError(c,"fetchConfig (non-retriable error)");return this.logError(l),null}let u=this.config.retryDelay*Math.pow(2,o);this.log(`Retrying config fetch in ${u}ms after error:`,c),await this.delay(u)}return null}catch(t){let i=this.formatError(t,"fetchConfig");return this.logError(i),null}}async getConfigAsync(e,t={}){try{if(!t.forceRefresh&&this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(!t.forceRefresh&&this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e];let i=await this.fetchConfig(t);return i?i.configurations[e]:this.config.defaultConfigurations?.[e]}catch(i){let r=this.formatError(i,"getConfigAsync");return this.logError(r),this.config.defaultConfigurations?.[e]}}async getAllConfigsAsync(e={}){try{if(!e.forceRefresh&&this.configCache?.configurations)return{...this.config.defaultConfigurations,...this.configCache.configurations};let t=await this.fetchConfig(e);return t?{...this.config.defaultConfigurations,...t.configurations}:{...this.config.defaultConfigurations}}catch(t){let i=this.formatError(t,"getAllConfigsAsync");return this.logError(i),{...this.config.defaultConfigurations}}}updateConfigCache(e,t){let i={configurations:e.configurations,snapshotId:e.snapshotId,timestamp:e.timestamp,userId:t},r=this.configCache?.configurations||{};this.configCache=i,this.saveConfigCache(i),JSON.stringify(r)!==JSON.stringify(e.configurations)&&this.notifyConfigChangeListeners(e.configurations)}addConfigChangeListener(e){this.configChangeListeners.push(e)}removeConfigChangeListener(e){let t=this.configChangeListeners.indexOf(e);t>-1&&this.configChangeListeners.splice(t,1)}notifyConfigChangeListeners(e){this.configChangeListeners.forEach(t=>{try{t(e)}catch(i){console.error("[Grain Analytics] Config change listener error:",i)}})}startConfigRefreshTimer(){typeof window>"u"||(this.configRefreshTimer&&clearInterval(this.configRefreshTimer),this.configRefreshTimer=window.setInterval(()=>{this.isDestroyed||this.fetchConfig().catch(e=>{let t=this.formatError(e,"auto-config refresh");this.logError(t)})},this.config.configRefreshInterval))}stopConfigRefreshTimer(){this.configRefreshTimer&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null)}async preloadConfig(e=[],t){try{let i=this.getEffectiveUserIdInternal();this.log(`Preloading config for user: ${i}`),await this.fetchConfig({immediateKeys:e,properties:t})&&this.startConfigRefreshTimer()}catch(i){let r=this.formatError(i,"preloadConfig");this.logError(r)}}chunkEvents(e,t){let i=[];for(let r=0;r<e.length;r+=t)i.push(e.slice(r,r+t));return i}grantConsent(e){try{this.consentManager.grantConsent(e),this.log("Consent granted",e)}catch(t){let i=this.formatError(t,"grantConsent");this.logError(i)}}revokeConsent(e){try{this.consentManager.revokeConsent(e),this.log("Consent revoked",e),this.eventQueue=[],this.waitingForConsentQueue=[]}catch(t){let i=this.formatError(t,"revokeConsent");this.logError(i)}}getConsentState(){return this.consentManager.getConsentState()}hasConsent(e){return this.consentManager.hasConsent(e)}onConsentChange(e){this.consentManager.addListener(e)}offConsentChange(e){this.consentManager.removeListener(e)}destroy(){if(this.isDestroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.stopConfigRefreshTimer(),this.configChangeListeners=[],this.heartbeatManager&&(this.heartbeatManager.destroy(),this.heartbeatManager=null),this.pageTrackingManager&&(this.pageTrackingManager.destroy(),this.pageTrackingManager=null),this.activityDetector&&(this.activityDetector.destroy(),this.activityDetector=null),this.interactionTrackingManager&&(this.interactionTrackingManager.destroy(),this.interactionTrackingManager=null),this.sectionTrackingManager&&(this.sectionTrackingManager.destroy(),this.sectionTrackingManager=null),this.heatmapTrackingManager&&(this.heatmapTrackingManager.destroy(),this.heatmapTrackingManager=null),this.eventQueue.length>0){let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);if(t.length>0){this.sendEventsWithBeacon(t[0]).catch(()=>{});for(let i=1;i<t.length;i++)this.sendEventsWithBeacon(t[i]).catch(()=>{})}}}};function ee(s){return new f(s)}var Ae=f;typeof window<"u"&&(window.Grain={GrainAnalytics:f,createGrainAnalytics:ee});return ae(ve);})();
1
+ /* Grain Analytics Web SDK v2.8.0 | MIT License */
2
+ "use strict";var Grain=(()=>{var I=Object.defineProperty;var ne=Object.getOwnPropertyDescriptor;var ae=Object.getOwnPropertyNames;var oe=Object.prototype.hasOwnProperty;var g=(s,e)=>()=>(s&&(e=s(s=0)),e);var b=(s,e)=>{for(var t in e)I(s,t,{get:e[t],enumerable:!0})},se=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of ae(e))!oe.call(s,r)&&r!==t&&I(s,r,{get:()=>e[r],enumerable:!(i=ne(e,r))||i.enumerable});return s};var ce=s=>se(I({},"__esModule",{value:!0}),s);var fe,f,U=g(()=>{"use strict";fe={maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4},f=class{constructor(e,t={}){this.isDestroyed=!1;this.isPageVisible=!0;this.visibilityChangeHandler=null;this.sectionStates=new Map;this.lastFilterReason=null;this.activityDetector=e,this.options={...fe,...t,debug:t.debug??!1},this.setupPageVisibilityTracking()}setupPageVisibilityTracking(){typeof document>"u"||(this.isPageVisible=document.visibilityState==="visible",this.visibilityChangeHandler=()=>{let e=this.isPageVisible;this.isPageVisible=document.visibilityState==="visible",!this.isPageVisible&&e?this.log("Page hidden - tracking paused"):this.isPageVisible&&!e&&(this.log("Page visible - tracking resumed"),this.resetAllSections())},document.addEventListener("visibilitychange",this.visibilityChangeHandler))}shouldTrack(){return this.isPageVisible?this.activityDetector.isActive(this.options.idleThreshold)?(this.lastFilterReason=null,!0):(this.lastFilterReason="user_idle",!1):(this.lastFilterReason="page_hidden",!1)}shouldTrackSection(e,t){if(!this.shouldTrack())return{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"};let i=this.sectionStates.get(e);i||(i={sectionName:e,currentDuration:0,lastScrollPosition:t,lastResetTime:Date.now()},this.sectionStates.set(e,i));let r=Math.abs(t-i.lastScrollPosition);return r>=this.options.minScrollDistance?(this.log(`Section "${e}": Attention reset due to ${Math.round(r)}px scroll`),i.currentDuration=0,i.lastScrollPosition=t,i.lastResetTime=Date.now(),{shouldTrack:!0,resetAttention:!0}):i.currentDuration>=this.options.maxSectionDuration?{shouldTrack:!1,reason:"max_duration_reached"}:{shouldTrack:!0}}updateSectionDuration(e,t){let i=this.sectionStates.get(e);i&&(i.currentDuration+=t,i.currentDuration>=this.options.maxSectionDuration&&this.log(`Section "${e}": Max duration cap reached (${i.currentDuration}ms)`))}resetSection(e){let t=this.sectionStates.get(e);t&&(this.log(`Section "${e}": Attention reset (section exit)`),t.currentDuration=0,t.lastResetTime=Date.now())}resetAllSections(){this.log("Resetting all section attention states");for(let e of this.sectionStates.values())e.currentDuration=0,e.lastResetTime=Date.now()}getSectionState(e){return this.sectionStates.get(e)}getLastFilterReason(){return this.lastFilterReason}shouldTrackScroll(e,t){return this.shouldTrack()?Math.abs(t-e)<10?{shouldTrack:!1,reason:"scroll_too_small"}:{shouldTrack:!0}:{shouldTrack:!1,reason:this.lastFilterReason||"global_policy"}}getPolicies(){return{maxSectionDuration:this.options.maxSectionDuration,minScrollDistance:this.options.minScrollDistance,idleThreshold:this.options.idleThreshold}}getTrackingState(){return{isPageVisible:this.isPageVisible,isUserActive:this.activityDetector.isActive(this.options.idleThreshold),timeSinceLastActivity:this.activityDetector.getTimeSinceLastActivity(),activeSections:this.sectionStates.size}}log(...e){this.options.debug&&console.log("[AttentionQuality]",...e)}destroy(){this.isDestroyed||(this.isDestroyed=!0,this.visibilityChangeHandler&&typeof document<"u"&&(document.removeEventListener("visibilitychange",this.visibilityChangeHandler),this.visibilityChangeHandler=null),this.sectionStates.clear())}}});function ve(s){if(s)return s.replace(/[\u{1F300}-\u{1F9FF}]/gu,"").replace(/[\u{1F600}-\u{1F64F}]/gu,"").replace(/[\u{1F680}-\u{1F6FF}]/gu,"").replace(/[\u{2600}-\u{26FF}]/gu,"").replace(/[\u{2700}-\u{27BF}]/gu,"").replace(/[\u{1F900}-\u{1F9FF}]/gu,"").replace(/[\u{1F1E0}-\u{1F1FF}]/gu,"").replace(/[\u{200D}]/gu,"").replace(/[\u{FE0F}]/gu,"").replace(/[\u{20E3}]/gu,"").trim()}function x(s,e=100){if(!s)return;let t=ve(s);if(t)return t.substring(0,e)||void 0}var N=g(()=>{"use strict"});var j={};b(j,{HeatmapTrackingManager:()=>H});var ye,H,J=g(()=>{"use strict";U();N();ye={scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:!1},H=class{constructor(e,t={}){this.isDestroyed=!1;this.currentScrollState=null;this.pendingClicks=[];this.pendingScrolls=[];this.scrollDebounceTimer=null;this.batchTimer=null;this.scrollTrackingTimer=null;this.periodicScrollTimer=null;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.SPLIT_DURATION=3e3;this.tracker=e,this.options={...ye,...t},this.attentionQuality=new f(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing heatmap tracking"),this.setupClickTracking(),this.setupScrollTracking(),this.startScrollTracking(),this.setupUnloadHandler())}setupClickTracking(){if(typeof document>"u")return;let e=t=>{this.isDestroyed||this.tracker.hasConsent("analytics")&&this.handleClick(t)};document.addEventListener("click",e,{passive:!0,capture:!0})}setupScrollTracking(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.handleScroll(),this.scrollDebounceTimer=null},this.options.scrollDebounceDelay)};window.addEventListener("scroll",e,{passive:!0})}startScrollTracking(){typeof window>"u"||(this.updateScrollState(),this.scrollTrackingTimer=window.setInterval(()=>{this.isDestroyed||this.updateScrollState()},500),this.startPeriodicScrollTracking())}startPeriodicScrollTracking(){typeof window>"u"||(this.periodicScrollTimer=window.setInterval(()=>{if(this.isDestroyed||!this.currentScrollState||!this.tracker.hasConsent("analytics"))return;if(!this.attentionQuality.shouldTrack()){this.log("Scroll tracking paused:",this.attentionQuality.getLastFilterReason());return}let e=Date.now(),t=e-this.currentScrollState.entryTime;if(t>1e3){let i=window.scrollY||window.pageYOffset,r=window.innerHeight,n=document.documentElement.scrollHeight,a=`viewport_section_${this.currentScrollState.viewportSection}`,o=this.attentionQuality.shouldTrackSection(a,i);if(o.resetAttention){this.log(`Viewport section ${this.currentScrollState.viewportSection}: Attention reset`),this.currentScrollState.entryTime=e;return}if(!o.shouldTrack){this.log(`Viewport section ${this.currentScrollState.viewportSection}: ${o.reason}`);return}let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:i,durationMs:t,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:n,viewportHeight:r};this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:c.pageUrl,viewport_section:c.viewportSection,scroll_depth_px:c.scrollDepthPx,duration_ms:c.durationMs,entry_timestamp:c.entryTimestamp,exit_timestamp:c.exitTimestamp,page_height:c.pageHeight,viewport_height:c.viewportHeight,is_split:!0},{flush:!0}),this.attentionQuality.updateSectionDuration(a,t),this.currentScrollState.entryTime=e}},this.SPLIT_DURATION))}setupUnloadHandler(){if(typeof window>"u")return;let e=()=>{if(this.currentScrollState){let t=Date.now(),i=t-this.currentScrollState.entryTime;if(i>100){let r={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:i,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:t,pageHeight:document.documentElement.scrollHeight,viewportHeight:window.innerHeight};this.pendingScrolls.push(r)}}this.flushPendingEventsWithBeacon()};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e)}handleClick(e){if(!this.tracker.hasConsent("analytics"))return;let t=e.target;if(!t)return;let i=window.location.href,r=this.generateXPath(t),n=Math.round(e.clientX),a=Math.round(e.clientY),o=Math.round(e.pageX),c=Math.round(e.pageY),l=t.tagName?.toLowerCase()||"unknown",u=x(t.textContent),d={pageUrl:i,xpath:r,viewportX:n,viewportY:a,pageX:o,pageY:c,elementTag:l,elementText:u||void 0,timestamp:Date.now()};t instanceof HTMLAnchorElement&&t.href?this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:d.pageUrl,xpath:d.xpath,viewport_x:d.viewportX,viewport_y:d.viewportY,page_x:d.pageX,page_y:d.pageY,element_tag:d.elementTag,element_text:d.elementText,timestamp:d.timestamp},{flush:!0}):(this.pendingClicks.push(d),this.considerBatchFlush())}handleScroll(){this.tracker.hasConsent("analytics")&&this.updateScrollState()}updateScrollState(){if(typeof window>"u"||!this.tracker.hasConsent("analytics"))return;let e=Date.now(),t=window.scrollY||window.pageYOffset,i=window.innerHeight,r=document.documentElement.scrollHeight,n=Math.floor(t/i);if(this.currentScrollState&&this.currentScrollState.viewportSection!==n){let a=e-this.currentScrollState.entryTime;if(a>100){let c={pageUrl:window.location.href,viewportSection:this.currentScrollState.viewportSection,scrollDepthPx:this.currentScrollState.scrollDepthPx,durationMs:a,entryTimestamp:this.currentScrollState.entryTime,exitTimestamp:e,pageHeight:r,viewportHeight:i};this.pendingScrolls.push(c)}let o=`viewport_section_${this.currentScrollState.viewportSection}`;this.attentionQuality.resetSection(o)}(!this.currentScrollState||this.currentScrollState.viewportSection!==n)&&(this.currentScrollState={viewportSection:n,entryTime:e,scrollDepthPx:t}),this.lastScrollPosition=t,this.lastScrollTime=e,this.considerBatchFlush()}generateXPath(e){if(!e)return"";if(e.id)return`//*[@id="${e.id}"]`;let t=[],i=e;for(;i&&i.nodeType===Node.ELEMENT_NODE;){let r=0,n=i;for(;n;)n=n.previousElementSibling,n&&n.nodeName===i.nodeName&&r++;let a=i.nodeName.toLowerCase(),o=r>0?`[${r+1}]`:"";t.unshift(`${a}${o}`),i=i.parentElement}return t.length?`/${t.join("/")}`:""}considerBatchFlush(){let e=this.pendingClicks.length+this.pendingScrolls.length;if(e>=this.options.maxBatchSize){this.flushPendingEvents();return}this.batchTimer===null&&e>0&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents(),this.batchTimer=null},this.options.batchDelay))}flushPendingEvents(){if(!this.isDestroyed){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight});this.pendingScrolls=[]}this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null)}}flushPendingEventsWithBeacon(){if(!this.tracker.hasConsent("analytics")){this.pendingClicks=[],this.pendingScrolls=[];return}if(this.pendingClicks.length>0){for(let e of this.pendingClicks)this.tracker.trackSystemEvent("_grain_heatmap_click",{page_url:e.pageUrl,xpath:e.xpath,viewport_x:e.viewportX,viewport_y:e.viewportY,page_x:e.pageX,page_y:e.pageY,element_tag:e.elementTag,element_text:e.elementText,timestamp:e.timestamp},{flush:!0});this.pendingClicks=[]}if(this.pendingScrolls.length>0){for(let e of this.pendingScrolls)this.tracker.trackSystemEvent("_grain_heatmap_scroll",{page_url:e.pageUrl,viewport_section:e.viewportSection,scroll_depth_px:e.scrollDepthPx,duration_ms:e.durationMs,entry_timestamp:e.entryTimestamp,exit_timestamp:e.exitTimestamp,page_height:e.pageHeight,viewport_height:e.viewportHeight},{flush:!0});this.pendingScrolls=[]}}log(...e){this.options.debug&&this.tracker.log("[Heatmap Tracking]",...e)}destroy(){this.isDestroyed=!0,this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.scrollTrackingTimer!==null&&(clearInterval(this.scrollTrackingTimer),this.scrollTrackingTimer=null),this.periodicScrollTimer!==null&&(clearInterval(this.periodicScrollTimer),this.periodicScrollTimer=null),this.attentionQuality.destroy(),this.flushPendingEvents()}}});var q={};b(q,{InteractionTrackingManager:()=>O});var O,X=g(()=>{"use strict";N();O=class{constructor(e,t,i={}){this.isDestroyed=!1;this.attachedListeners=new Map;this.xpathCache=new Map;this.mutationObserver=null;this.mutationDebounceTimer=null;this.tracker=e,this.interactions=t,this.config={debug:i.debug??!1,enableMutationObserver:i.enableMutationObserver??!0,mutationDebounceDelay:i.mutationDebounceDelay??500,tenantId:i.tenantId,apiUrl:i.apiUrl},typeof window<"u"&&typeof document<"u"&&(this.config.tenantId&&this.config.apiUrl?this.fetchAndMergeTrackers().then(()=>{this.attachAllListeners()}):document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.attachAllListeners()):setTimeout(()=>this.attachAllListeners(),0),this.config.enableMutationObserver&&this.setupMutationObserver())}async fetchAndMergeTrackers(){if(!(!this.config.tenantId||!this.config.apiUrl))try{let e=typeof window<"u"?window.location.href:"",t=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/trackers?url=${encodeURIComponent(e)}`;this.log("Fetching trackers from:",t);let i=await fetch(t,{method:"GET",headers:{"Content-Type":"application/json"}});if(!i.ok){this.log("Failed to fetch trackers:",i.status);return}let r=await i.json();if(r.trackers&&Array.isArray(r.trackers)){this.log("Fetched",r.trackers.length,"trackers");let n=r.trackers.map(a=>({eventName:a.eventName,selector:a.selector,priority:5,label:a.eventName,description:`Tracker: ${a.eventName}`}));this.interactions=[...n,...this.interactions],this.log("Merged trackers, total interactions:",this.interactions.length)}}catch(e){this.log("Error fetching trackers:",e)}}attachAllListeners(){if(!this.isDestroyed){this.log("Attaching interaction listeners");for(let e of this.interactions)this.attachInteractionListener(e)}}attachInteractionListener(e){if(this.isDestroyed)return;let t=this.findElementByXPath(e.selector);if(!t){this.log("Element not found for interaction:",e.eventName,"selector:",e.selector);return}if(this.attachedListeners.has(t)){this.log("Listeners already attached for element:",t);return}let i=[],r=n=>this.handleInteractionClick(e,n);if(t.addEventListener("click",r,{passive:!0}),i.push({event:"click",handler:r}),t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement||t instanceof HTMLSelectElement){let n=a=>this.handleInteractionFocus(e,a);t.addEventListener("focus",n,{passive:!0}),i.push({event:"focus",handler:n})}this.attachedListeners.set(t,i)}handleInteractionClick(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target,r=i instanceof HTMLAnchorElement&&i.href,n={interaction_type:"click",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_text:x(i.textContent),element_id:i.id||void 0,element_class:i.className||void 0,...r&&{href:i.href},timestamp:Date.now()},a=this.tracker.track(e.eventName,n,{flush:!0});a instanceof Promise&&a.catch(o=>{this.log("Failed to track click:",o)})}handleInteractionFocus(e,t){if(this.isDestroyed||!this.tracker.hasConsent("analytics"))return;let i=t.target;this.tracker.track(e.eventName,{interaction_type:"focus",interaction_label:e.label,interaction_description:e.description,interaction_priority:e.priority,element_tag:i.tagName?.toLowerCase(),element_id:i.id||void 0,element_class:i.className||void 0,timestamp:Date.now()})}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}setupMutationObserver(){if(typeof MutationObserver>"u"){this.log("MutationObserver not supported");return}this.mutationObserver=new MutationObserver(e=>{this.mutationDebounceTimer!==null&&clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=window.setTimeout(()=>{this.handleMutations(e),this.mutationDebounceTimer=null},this.config.mutationDebounceDelay)}),this.mutationObserver.observe(document.body,{childList:!0,subtree:!0}),this.log("Mutation observer setup")}handleMutations(e){if(this.isDestroyed)return;this.xpathCache.clear();let t=new Set;for(let i of e)i.removedNodes.forEach(r=>{r instanceof Element&&(t.add(r),this.attachedListeners.forEach((n,a)=>{r.contains(a)&&t.add(a)}))});t.forEach(i=>{this.detachListeners(i)}),this.attachAllListeners()}detachListeners(e){let t=this.attachedListeners.get(e);t&&(t.forEach(({event:i,handler:r})=>{e.removeEventListener(i,r)}),this.attachedListeners.delete(e))}log(...e){this.config.debug&&console.log("[InteractionTracking]",...e)}updateInteractions(e){this.isDestroyed||(this.log("Updating interactions configuration"),this.attachedListeners.forEach((t,i)=>{this.detachListeners(i)}),this.xpathCache.clear(),this.interactions=e,this.attachAllListeners())}destroy(){this.isDestroyed||(this.log("Destroying interaction tracking manager"),this.isDestroyed=!0,this.mutationDebounceTimer!==null&&(clearTimeout(this.mutationDebounceTimer),this.mutationDebounceTimer=null),this.mutationObserver&&(this.mutationObserver.disconnect(),this.mutationObserver=null),this.attachedListeners.forEach((e,t)=>{this.detachListeners(t)}),this.attachedListeners.clear(),this.xpathCache.clear())}}});var Z={};b(Z,{SectionTrackingManager:()=>B});var be,B,ee=g(()=>{"use strict";U();be={minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:!1},B=class{constructor(e,t,i={}){this.isDestroyed=!1;this.sectionStates=new Map;this.intersectionObserver=null;this.xpathCache=new Map;this.lastScrollPosition=0;this.lastScrollTime=Date.now();this.scrollVelocity=0;this.scrollDebounceTimer=null;this.pendingEvents=[];this.batchTimer=null;this.sectionTimers=new Map;this.SPLIT_DURATION=3e3;this.tracker=e,this.sections=t,this.options={...be,...i},this.attentionQuality=new f(e.getActivityDetector(),{maxSectionDuration:9e3,minScrollDistance:100,idleThreshold:3e4,debug:this.options.debug}),typeof window<"u"&&typeof document<"u"&&(document.readyState==="loading"?document.addEventListener("DOMContentLoaded",()=>this.initialize()):setTimeout(()=>this.initialize(),0))}initialize(){this.isDestroyed||(this.log("Initializing section tracking"),this.setupIntersectionObserver(),this.setupScrollListener(),this.initializeSections())}setupIntersectionObserver(){if(typeof IntersectionObserver>"u"){this.log("IntersectionObserver not supported");return}this.intersectionObserver=new IntersectionObserver(e=>{e.forEach(t=>{this.handleIntersection(t)})},{threshold:[0,.1,.25,.5,.75,1],rootMargin:"0px"}),this.log("IntersectionObserver created")}setupScrollListener(){if(typeof window>"u")return;let e=()=>{this.scrollDebounceTimer!==null&&clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=window.setTimeout(()=>{this.updateScrollVelocity(),this.scrollDebounceTimer=null},this.options.debounceDelay)};window.addEventListener("scroll",e,{passive:!0}),this.log("Scroll listener attached")}initializeSections(){for(let e of this.sections){let t=this.findElementByXPath(e.selector);if(!t){this.log("Section element not found:",e.sectionName,"selector:",e.selector);continue}let i={element:t,config:e,entryTime:null,exitTime:null,isVisible:!1,lastScrollPosition:window.scrollY,lastScrollTime:Date.now(),entryScrollSpeed:0,exitScrollSpeed:0,maxVisibleArea:0};this.sectionStates.set(e.sectionName,i),this.intersectionObserver&&this.intersectionObserver.observe(t)}}handleIntersection(e){if(this.isDestroyed)return;let t=Array.from(this.sectionStates.values()).find(n=>n.element===e.target);if(!t)return;let i=e.isIntersecting&&e.intersectionRatio>=this.options.intersectionThreshold,r=e.intersectionRatio;r>t.maxVisibleArea&&(t.maxVisibleArea=r),i&&!t.isVisible?this.handleSectionEntry(t):!i&&t.isVisible&&this.handleSectionExit(t),t.isVisible=i}handleSectionEntry(e){e.entryTime=Date.now(),e.entryScrollSpeed=this.scrollVelocity,e.lastScrollPosition=window.scrollY,e.lastScrollTime=Date.now(),e.maxVisibleArea=0,this.startPeriodicTracking(e)}startPeriodicTracking(e){this.stopPeriodicTracking(e.config.sectionName);let t=window.setInterval(()=>{if(this.isDestroyed||!e.isVisible||e.entryTime===null){this.stopPeriodicTracking(e.config.sectionName);return}let i=Date.now(),r=i-e.entryTime;if(r>=this.options.minDwellTime){let n=window.scrollY,a=this.attentionQuality.shouldTrackSection(e.config.sectionName,n);if(a.resetAttention){this.log(`Section "${e.config.sectionName}": Attention reset, restarting timer`),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity;return}if(!a.shouldTrack){this.log(`Section "${e.config.sectionName}": Tracking paused - ${a.reason}`);return}let o={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:i,duration:r,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:this.scrollVelocity};this.shouldTrackSection(o)&&(this.tracker.trackSystemEvent("_grain_section_view",{section_name:o.sectionName,section_type:o.sectionType,duration_ms:o.duration,viewport_width:o.viewportWidth,viewport_height:o.viewportHeight,scroll_depth_percent:o.scrollDepth,visible_area_percent:o.visibleAreaPercentage,scroll_speed_entry:Math.round(o.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(o.scrollSpeedAtExit||0),entry_timestamp:o.entryTime,exit_timestamp:o.exitTime,is_split:!0}),this.attentionQuality.updateSectionDuration(e.config.sectionName,r),e.entryTime=i,e.entryScrollSpeed=this.scrollVelocity)}},this.SPLIT_DURATION);this.sectionTimers.set(e.config.sectionName,t)}stopPeriodicTracking(e){let t=this.sectionTimers.get(e);t!==void 0&&(clearInterval(t),this.sectionTimers.delete(e))}handleSectionExit(e){if(this.stopPeriodicTracking(e.config.sectionName),this.attentionQuality.resetSection(e.config.sectionName),e.entryTime===null)return;e.exitTime=Date.now(),e.exitScrollSpeed=this.scrollVelocity;let t=e.exitTime-e.entryTime,i={sectionName:e.config.sectionName,sectionType:e.config.sectionType,entryTime:e.entryTime,exitTime:e.exitTime,duration:t,viewportWidth:window.innerWidth,viewportHeight:window.innerHeight,scrollDepth:this.calculateScrollDepth(),visibleAreaPercentage:Math.round(e.maxVisibleArea*100),scrollSpeedAtEntry:e.entryScrollSpeed,scrollSpeedAtExit:e.exitScrollSpeed};this.shouldTrackSection(i)?this.queueSectionView(i):this.log("Section view filtered out:",e.config.sectionName,"duration:",t),e.entryTime=null}updateScrollVelocity(){let e=Date.now(),t=window.scrollY,i=e-this.lastScrollTime,r=Math.abs(t-this.lastScrollPosition);i>0&&(this.scrollVelocity=r/i*1e3),this.lastScrollPosition=t,this.lastScrollTime=e}calculateScrollDepth(){if(typeof window>"u"||typeof document>"u")return 0;let e=window.innerHeight,t=Math.max(document.body.scrollHeight,document.body.offsetHeight,document.documentElement.clientHeight,document.documentElement.scrollHeight,document.documentElement.offsetHeight),i=window.scrollY,r=t-e;return r<=0?100:Math.round(i/r*100)}shouldTrackSection(e){return!(e.duration<this.options.minDwellTime||(e.scrollSpeedAtEntry+e.scrollSpeedAtExit)/2>this.options.scrollVelocityThreshold*2||e.visibleAreaPercentage<10)}queueSectionView(e){this.pendingEvents.push(e),this.batchTimer===null&&(this.batchTimer=window.setTimeout(()=>{this.flushPendingEvents()},this.options.batchDelay))}flushPendingEvents(){if(!(this.isDestroyed||this.pendingEvents.length===0)){if(!this.tracker.hasConsent("analytics")){this.pendingEvents=[];return}for(let e of this.pendingEvents)this.tracker.trackSystemEvent("_grain_section_view",{section_name:e.sectionName,section_type:e.sectionType,duration_ms:e.duration,viewport_width:e.viewportWidth,viewport_height:e.viewportHeight,scroll_depth_percent:e.scrollDepth,visible_area_percent:e.visibleAreaPercentage,scroll_speed_entry:Math.round(e.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(e.scrollSpeedAtExit||0),entry_timestamp:e.entryTime,exit_timestamp:e.exitTime});this.pendingEvents=[],this.batchTimer=null}}findElementByXPath(e){if(this.xpathCache.has(e)){let t=this.xpathCache.get(e);if(t&&document.contains(t))return t;this.xpathCache.delete(e)}try{let t=e;e.startsWith("xpath=")&&(t=e.substring(6));let r=document.evaluate(t,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue;return r&&this.xpathCache.set(e,r),r}catch(t){return this.log("Error evaluating XPath:",e,t),null}}log(...e){this.options.debug&&console.log("[SectionTracking]",...e)}updateSections(e){this.isDestroyed||(this.log("Updating sections configuration"),this.intersectionObserver&&this.intersectionObserver.disconnect(),this.sectionStates.clear(),this.xpathCache.clear(),this.sections=e,this.setupIntersectionObserver(),this.initializeSections())}destroy(){this.isDestroyed||(this.log("Destroying section tracking manager"),this.isDestroyed=!0,this.sectionTimers.forEach(e=>{clearInterval(e)}),this.sectionTimers.clear(),this.flushPendingEvents(),this.scrollDebounceTimer!==null&&(clearTimeout(this.scrollDebounceTimer),this.scrollDebounceTimer=null),this.batchTimer!==null&&(clearTimeout(this.batchTimer),this.batchTimer=null),this.intersectionObserver&&(this.intersectionObserver.disconnect(),this.intersectionObserver=null),this.attentionQuality.destroy(),this.sectionStates.clear(),this.xpathCache.clear(),this.pendingEvents=[])}}});var te={};b(te,{DebugAgent:()=>G});var G,ie=g(()=>{"use strict";G=class{constructor(e,t,i,r,n={}){this.isDestroyed=!1;this.isInspectMode=!1;this.showTrackers=!1;this.selectedElement=null;this.toolbarElement=null;this.panelElement=null;this.highlightElement=null;this.existingTrackers=[];this.trackerHighlights=[];this.isDragging=!1;this.dragStartX=0;this.dragStartY=0;this.toolbarStartX=0;this.toolbarStartY=0;this.mouseMoveListener=null;this.clickListener=null;this.dragMoveListener=null;this.dragEndListener=null;this.handleEscapeKey=e=>{e.key==="Escape"&&this.isInspectMode&&this.disableInspectMode()};this.tracker=e,this.sessionId=t,this.tenantId=i,this.apiUrl=r,this.config={debug:n.debug??!1},typeof window<"u"&&typeof document<"u"&&this.initialize()}async initialize(){this.log("Initializing debug agent"),await this.loadExistingTrackers(),this.showToolbar(),this.createHighlightElement(),this.showTrackers=!0,this.showTrackerHighlights(),this.showTrackersList()}async loadExistingTrackers(){try{let e=`${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/trackers`,t=await fetch(e);t.ok&&(this.existingTrackers=await t.json(),this.log("Loaded trackers:",this.existingTrackers))}catch(e){this.log("Failed to load trackers:",e),this.existingTrackers=[]}}showToolbar(){if(this.toolbarElement)return;let e=document.createElement("div");e.id="grain-debug-toolbar",e.innerHTML=`
3
+ <style>
4
+ #grain-debug-toolbar {
5
+ position: fixed;
6
+ bottom: 20px;
7
+ right: 20px;
8
+ background: repeating-linear-gradient(
9
+ 45deg,
10
+ #fbbf24,
11
+ #fbbf24 10px,
12
+ #1e293b 10px,
13
+ #1e293b 20px
14
+ );
15
+ border: 2px solid #1e293b;
16
+ border-radius: 12px;
17
+ padding: 6px;
18
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.2), 0 2px 8px rgba(0, 0, 0, 0.1);
19
+ z-index: 999999;
20
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
21
+ font-size: 13px;
22
+ }
23
+
24
+ .grain-toolbar-inner {
25
+ display: flex;
26
+ align-items: center;
27
+ gap: 12px;
28
+ background: white;
29
+ border-radius: 6px;
30
+ padding: 8px 12px;
31
+ }
32
+
33
+ #grain-debug-toolbar.dragging {
34
+ cursor: move;
35
+ user-select: none;
36
+ }
37
+
38
+ .grain-toolbar-header {
39
+ display: flex;
40
+ align-items: center;
41
+ cursor: move;
42
+ user-select: none;
43
+ padding: 6px 10px;
44
+ background: #1e293b;
45
+ border-radius: 4px;
46
+ margin-right: 4px;
47
+ }
48
+
49
+ .grain-toolbar-title {
50
+ font-size: 11px;
51
+ font-weight: 700;
52
+ letter-spacing: 1.2px;
53
+ text-transform: uppercase;
54
+ color: #fbbf24;
55
+ }
56
+
57
+ .grain-toolbar-body {
58
+ display: flex;
59
+ align-items: center;
60
+ gap: 10px;
61
+ flex: 1;
62
+ }
63
+
64
+ .grain-toolbar-stats {
65
+ display: flex;
66
+ gap: 12px;
67
+ padding: 6px 10px;
68
+ background: #f8fafc;
69
+ border-radius: 4px;
70
+ margin-right: 4px;
71
+ }
72
+
73
+ .grain-stat {
74
+ display: flex;
75
+ align-items: baseline;
76
+ gap: 6px;
77
+ }
78
+
79
+ .grain-stat-value {
80
+ font-size: 18px;
81
+ font-weight: 700;
82
+ color: #1e293b;
83
+ }
84
+
85
+ .grain-stat-label {
86
+ font-size: 11px;
87
+ color: #64748b;
88
+ font-weight: 500;
89
+ }
90
+
91
+ .grain-toolbar-actions {
92
+ display: flex;
93
+ gap: 8px;
94
+ align-items: center;
95
+ }
96
+
97
+ #grain-debug-toolbar button {
98
+ background: white;
99
+ border: 1.5px solid #e2e8f0;
100
+ color: #475569;
101
+ padding: 8px 14px;
102
+ border-radius: 8px;
103
+ cursor: pointer;
104
+ font-size: 12px;
105
+ font-weight: 600;
106
+ transition: all 0.2s;
107
+ display: flex;
108
+ align-items: center;
109
+ justify-content: center;
110
+ gap: 6px;
111
+ white-space: nowrap;
112
+ }
113
+
114
+ #grain-debug-toolbar button:hover {
115
+ background: #f8fafc;
116
+ border-color: #cbd5e1;
117
+ transform: translateY(-1px);
118
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.08);
119
+ }
120
+
121
+ #grain-debug-toolbar button.active {
122
+ background: #fbbf24;
123
+ color: #1e293b;
124
+ border-color: #fbbf24;
125
+ box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);
126
+ }
127
+
128
+ #grain-debug-toolbar button.danger {
129
+ background: linear-gradient(135deg, #ef4444 0%, #dc2626 100%);
130
+ border-color: #ef4444;
131
+ color: white;
132
+ }
133
+
134
+ #grain-debug-toolbar button.danger:hover {
135
+ transform: translateY(-1px);
136
+ box-shadow: 0 2px 8px rgba(239, 68, 68, 0.25);
137
+ }
138
+
139
+ .grain-debug-highlight {
140
+ position: absolute;
141
+ pointer-events: none;
142
+ border: 2px solid #10b981;
143
+ background: rgba(16, 185, 129, 0.1);
144
+ z-index: 999998;
145
+ transition: all 0.1s;
146
+ }
147
+
148
+ .grain-tracker-highlight {
149
+ position: absolute;
150
+ pointer-events: none;
151
+ border: 2px solid #6366f1;
152
+ background: rgba(99, 102, 241, 0.08);
153
+ z-index: 999997;
154
+ transition: opacity 0.2s;
155
+ }
156
+
157
+ .grain-tracker-label {
158
+ position: absolute;
159
+ top: -28px;
160
+ left: 0;
161
+ background: #6366f1;
162
+ color: white;
163
+ padding: 4px 10px;
164
+ border-radius: 6px;
165
+ font-size: 11px;
166
+ font-weight: 600;
167
+ white-space: nowrap;
168
+ box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
169
+ pointer-events: none;
170
+ }
171
+
172
+ .grain-tracker-label::after {
173
+ content: '';
174
+ position: absolute;
175
+ bottom: -4px;
176
+ left: 10px;
177
+ width: 0;
178
+ height: 0;
179
+ border-left: 4px solid transparent;
180
+ border-right: 4px solid transparent;
181
+ border-top: 4px solid #6366f1;
182
+ }
183
+
184
+ .grain-trackers-list {
185
+ position: fixed;
186
+ bottom: 80px;
187
+ right: 20px;
188
+ background: white;
189
+ border: 1.5px solid #e2e8f0;
190
+ border-radius: 10px;
191
+ padding: 12px;
192
+ max-height: 400px;
193
+ width: 320px;
194
+ overflow-y: auto;
195
+ box-shadow: 0 8px 24px rgba(0, 0, 0, 0.1), 0 2px 8px rgba(0, 0, 0, 0.06);
196
+ z-index: 999998;
197
+ }
198
+
199
+ .grain-tracker-item {
200
+ padding: 10px;
201
+ background: #f8fafc;
202
+ border-radius: 8px;
203
+ margin-bottom: 8px;
204
+ cursor: pointer;
205
+ transition: all 0.2s;
206
+ }
207
+
208
+ .grain-tracker-item:hover {
209
+ background: #f1f5f9;
210
+ transform: translateX(4px);
211
+ }
212
+
213
+ .grain-tracker-item:last-child {
214
+ margin-bottom: 0;
215
+ }
216
+
217
+ .grain-tracker-name {
218
+ font-weight: 600;
219
+ color: #1e293b;
220
+ font-size: 13px;
221
+ margin-bottom: 4px;
222
+ }
223
+
224
+ .grain-tracker-details {
225
+ font-size: 11px;
226
+ color: #64748b;
227
+ display: flex;
228
+ gap: 8px;
229
+ align-items: center;
230
+ }
231
+
232
+ .grain-tracker-type {
233
+ background: #dbeafe;
234
+ color: #1e40af;
235
+ padding: 2px 6px;
236
+ border-radius: 4px;
237
+ font-weight: 600;
238
+ text-transform: uppercase;
239
+ font-size: 9px;
240
+ letter-spacing: 0.5px;
241
+ }
242
+ </style>
243
+ <div class="grain-toolbar-inner">
244
+ <div class="grain-toolbar-header" id="grain-toolbar-handle">
245
+ <div class="grain-toolbar-title">Grain Debug</div>
246
+ </div>
247
+ <div class="grain-toolbar-body">
248
+ <div class="grain-toolbar-stats">
249
+ <div class="grain-stat">
250
+ <div class="grain-stat-value">${this.existingTrackers.length}</div>
251
+ <div class="grain-stat-label">trackers</div>
252
+ </div>
253
+ <div class="grain-stat">
254
+ <div class="grain-stat-value">${this.existingTrackers.filter(a=>a.isEnabled).length}</div>
255
+ <div class="grain-stat-label">active</div>
256
+ </div>
257
+ </div>
258
+ <div class="grain-toolbar-actions">
259
+ <button id="grain-debug-inspect" type="button">
260
+ + New
261
+ </button>
262
+ <button id="grain-debug-trackers" class="active" type="button">
263
+ Hide
264
+ </button>
265
+ <button id="grain-debug-end" class="danger" type="button">
266
+ End Session
267
+ </button>
268
+ </div>
269
+ </div>
270
+ </div>
271
+ <div id="grain-trackers-list-container"></div>
272
+ `,document.body.appendChild(e),this.toolbarElement=e;let t=e.querySelector("#grain-toolbar-handle");t&&t.addEventListener("mousedown",a=>this.startDrag(a));let i=e.querySelector("#grain-debug-inspect"),r=e.querySelector("#grain-debug-trackers"),n=e.querySelector("#grain-debug-end");i&&i.addEventListener("click",()=>this.toggleInspectMode()),r&&r.addEventListener("click",()=>this.toggleTrackerView()),n&&n.addEventListener("click",()=>this.endDebug()),this.log("Toolbar shown")}createHighlightElement(){if(this.highlightElement)return;let e=document.createElement("div");e.className="grain-debug-highlight",e.style.display="none",document.body.appendChild(e),this.highlightElement=e}startDrag(e){if(!this.toolbarElement)return;this.isDragging=!0,this.dragStartX=e.clientX,this.dragStartY=e.clientY;let t=this.toolbarElement.getBoundingClientRect();this.toolbarStartX=t.left,this.toolbarStartY=t.top,this.toolbarElement.classList.add("dragging"),this.dragMoveListener=i=>this.onDrag(i),this.dragEndListener=()=>this.endDrag(),document.addEventListener("mousemove",this.dragMoveListener),document.addEventListener("mouseup",this.dragEndListener)}onDrag(e){if(!this.isDragging||!this.toolbarElement)return;let t=e.clientX-this.dragStartX,i=e.clientY-this.dragStartY,r=this.toolbarStartX+t,n=this.toolbarStartY+i,a=window.innerWidth-this.toolbarElement.offsetWidth,o=window.innerHeight-this.toolbarElement.offsetHeight,c=Math.max(0,Math.min(r,a)),l=Math.max(0,Math.min(n,o));this.toolbarElement.style.left=`${c}px`,this.toolbarElement.style.top=`${l}px`,this.toolbarElement.style.right="auto",this.toolbarElement.style.bottom="auto"}endDrag(){this.isDragging&&(this.isDragging=!1,this.toolbarElement&&this.toolbarElement.classList.remove("dragging"),this.dragMoveListener&&(document.removeEventListener("mousemove",this.dragMoveListener),this.dragMoveListener=null),this.dragEndListener&&(document.removeEventListener("mouseup",this.dragEndListener),this.dragEndListener=null))}toggleTrackerView(){this.showTrackers=!this.showTrackers;let e=document.querySelector("#grain-debug-trackers");e&&(e.textContent=this.showTrackers?"Hide":"View",e.classList.toggle("active",this.showTrackers)),this.showTrackers?(this.showTrackerHighlights(),this.showTrackersList()):(this.hideTrackerHighlights(),this.hideTrackersList())}showTrackerHighlights(){this.hideTrackerHighlights();for(let e of this.existingTrackers)if(e.isEnabled)try{let t=this.findElementBySelector(e.selector);if(!t)continue;let i=t.getBoundingClientRect(),r=document.createElement("div");r.className="grain-tracker-highlight";let n=document.createElement("div");n.className="grain-tracker-label",n.textContent=e.name,r.style.top=`${i.top+window.scrollY}px`,r.style.left=`${i.left+window.scrollX}px`,r.style.width=`${i.width}px`,r.style.height=`${i.height}px`,r.appendChild(n),document.body.appendChild(r),this.trackerHighlights.push(r)}catch(t){this.log("Failed to highlight tracker:",e.name,t)}}hideTrackerHighlights(){for(let e of this.trackerHighlights)e.remove();this.trackerHighlights=[]}showTrackersList(){let e=document.querySelector(".grain-trackers-list");if(this.existingTrackers.length===0){e&&e.remove();return}e||(e=document.createElement("div"),e.className="grain-trackers-list",document.body.appendChild(e)),e.innerHTML=`
273
+ ${this.existingTrackers.map(t=>`
274
+ <div class="grain-tracker-item" data-tracker-id="${t.trackerId}">
275
+ <div class="grain-tracker-name">${t.name}</div>
276
+ <div class="grain-tracker-details">
277
+ <span class="grain-tracker-type">${t.type}</span>
278
+ <span>${t.urlScope}</span>
279
+ ${t.isEnabled?"":'<span style="color: #ef4444;">\u2022 Disabled</span>'}
280
+ </div>
281
+ </div>
282
+ `).join("")}
283
+ `,e.querySelectorAll(".grain-tracker-item").forEach(t=>{t.addEventListener("click",()=>{let i=t.getAttribute("data-tracker-id"),r=this.existingTrackers.find(n=>n.trackerId===i);r&&this.scrollToTracker(r)})})}hideTrackersList(){let e=document.querySelector(".grain-trackers-list");e&&e.remove()}scrollToTracker(e){try{let t=this.findElementBySelector(e.selector);if(t){t.scrollIntoView({behavior:"smooth",block:"center"});let i=this.trackerHighlights.find(r=>{let n=t.getBoundingClientRect(),a=r.getBoundingClientRect();return Math.abs(a.top-n.top)<5});i&&(i.style.opacity="0",setTimeout(()=>{i.style.opacity="1"},100),setTimeout(()=>{i.style.opacity="0"},300),setTimeout(()=>{i.style.opacity="1"},500))}}catch(t){this.log("Failed to scroll to tracker:",t)}}findElementBySelector(e){try{return document.evaluate(e,document,null,XPathResult.FIRST_ORDERED_NODE_TYPE,null).singleNodeValue}catch(t){return this.log("Failed to find element:",t),null}}toggleInspectMode(){this.isInspectMode?this.disableInspectMode():this.enableInspectMode()}enableInspectMode(){if(this.isInspectMode)return;this.log("Enabling inspect mode"),this.isInspectMode=!0;let e=document.querySelector("#grain-debug-inspect");e&&(e.classList.add("active"),e.textContent="Click Element"),this.mouseMoveListener=t=>this.handleMouseMove(t),this.clickListener=t=>this.handleElementClick(t),document.addEventListener("mousemove",this.mouseMoveListener,!0),document.addEventListener("click",this.clickListener,!0),document.addEventListener("keydown",this.handleEscapeKey)}disableInspectMode(){if(!this.isInspectMode)return;this.log("Disabling inspect mode"),this.isInspectMode=!1;let e=document.querySelector("#grain-debug-inspect");e&&(e.classList.remove("active"),e.textContent="+ New"),this.mouseMoveListener&&(document.removeEventListener("mousemove",this.mouseMoveListener,!0),this.mouseMoveListener=null),this.clickListener&&(document.removeEventListener("click",this.clickListener,!0),this.clickListener=null),document.removeEventListener("keydown",this.handleEscapeKey),this.highlightElement&&(this.highlightElement.style.display="none")}handleMouseMove(e){if(!this.isInspectMode||!this.highlightElement)return;let t=e.target;if(t.closest("#grain-debug-toolbar")||t.closest("#grain-debug-panel")||t.closest(".grain-trackers-list")){this.highlightElement.style.display="none";return}let r=e.target.getBoundingClientRect();this.highlightElement.style.display="block",this.highlightElement.style.top=`${r.top+window.scrollY}px`,this.highlightElement.style.left=`${r.left+window.scrollX}px`,this.highlightElement.style.width=`${r.width}px`,this.highlightElement.style.height=`${r.height}px`}handleElementClick(e){if(!this.isInspectMode)return;let t=e.target;if(t.closest("#grain-debug-toolbar")||t.closest(".grain-trackers-list")){this.disableInspectMode();return}if(t.closest("#grain-debug-panel")){e.preventDefault(),e.stopPropagation();return}e.preventDefault(),e.stopPropagation(),this.selectedElement=t,this.disableInspectMode(),this.showCreationPanel(t)}showCreationPanel(e){this.panelElement&&this.panelElement.remove();let t=document.createElement("div");t.id="grain-debug-panel";let i=e.tagName.toLowerCase(),r=e.id,n=e.textContent?.trim().substring(0,50)||"",a=this.getXPathForElement(e);t.innerHTML=`
284
+ <style>
285
+ #grain-debug-panel {
286
+ position: fixed;
287
+ top: 50%;
288
+ left: 50%;
289
+ transform: translate(-50%, -50%);
290
+ background: repeating-linear-gradient(
291
+ 45deg,
292
+ #fbbf24,
293
+ #fbbf24 10px,
294
+ #1e293b 10px,
295
+ #1e293b 20px
296
+ );
297
+ border: 2px solid #1e293b;
298
+ border-radius: 16px;
299
+ padding: 6px;
300
+ width: 420px;
301
+ max-width: 90vw;
302
+ box-shadow: 0 20px 60px rgba(0, 0, 0, 0.25), 0 8px 24px rgba(0, 0, 0, 0.15);
303
+ z-index: 1000000;
304
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
305
+ }
306
+
307
+ .grain-panel-inner {
308
+ background: white;
309
+ border-radius: 10px;
310
+ overflow: hidden;
311
+ }
312
+
313
+ .grain-panel-header {
314
+ background: #1e293b;
315
+ padding: 14px 18px;
316
+ color: white;
317
+ }
318
+
319
+ .grain-panel-header h3 {
320
+ margin: 0 0 4px 0;
321
+ font-size: 16px;
322
+ font-weight: 700;
323
+ letter-spacing: 0.5px;
324
+ color: #fbbf24;
325
+ text-transform: uppercase;
326
+ }
327
+
328
+ .grain-panel-header p {
329
+ margin: 0;
330
+ font-size: 12px;
331
+ opacity: 0.85;
332
+ color: white;
333
+ }
334
+
335
+ .grain-panel-body {
336
+ padding: 18px;
337
+ }
338
+
339
+ #grain-debug-panel .element-preview {
340
+ background: #f8fafc;
341
+ border: 1.5px solid #e2e8f0;
342
+ border-radius: 8px;
343
+ padding: 10px 12px;
344
+ margin-bottom: 16px;
345
+ font-size: 11px;
346
+ color: #475569;
347
+ }
348
+
349
+ #grain-debug-panel .element-preview div {
350
+ margin-bottom: 4px;
351
+ }
352
+
353
+ #grain-debug-panel .element-preview div:last-child {
354
+ margin-bottom: 0;
355
+ }
356
+
357
+ #grain-debug-panel .element-preview strong {
358
+ color: #1e293b;
359
+ font-weight: 600;
360
+ }
361
+
362
+ #grain-debug-panel label {
363
+ display: block;
364
+ color: #1e293b;
365
+ font-size: 12px;
366
+ font-weight: 600;
367
+ margin-bottom: 6px;
368
+ }
369
+
370
+ #grain-debug-panel input,
371
+ #grain-debug-panel select {
372
+ width: 100%;
373
+ background: white;
374
+ border: 1.5px solid #e2e8f0;
375
+ border-radius: 8px;
376
+ padding: 9px 12px;
377
+ color: #1e293b;
378
+ font-size: 13px;
379
+ margin-bottom: 14px;
380
+ box-sizing: border-box;
381
+ transition: all 0.2s;
382
+ }
383
+
384
+ #grain-debug-panel input:focus,
385
+ #grain-debug-panel select:focus {
386
+ outline: none;
387
+ border-color: #fbbf24;
388
+ box-shadow: 0 0 0 3px rgba(251, 191, 36, 0.1);
389
+ }
390
+
391
+ #grain-debug-panel .button-group {
392
+ display: flex;
393
+ gap: 8px;
394
+ margin-top: 18px;
395
+ }
396
+
397
+ #grain-debug-panel button {
398
+ flex: 1;
399
+ padding: 10px 16px;
400
+ border: none;
401
+ border-radius: 8px;
402
+ font-size: 13px;
403
+ font-weight: 600;
404
+ cursor: pointer;
405
+ transition: all 0.2s;
406
+ }
407
+
408
+ #grain-debug-panel button.primary {
409
+ background: #fbbf24;
410
+ color: #1e293b;
411
+ box-shadow: 0 2px 8px rgba(251, 191, 36, 0.3);
412
+ }
413
+
414
+ #grain-debug-panel button.primary:hover {
415
+ background: #f59e0b;
416
+ transform: translateY(-1px);
417
+ box-shadow: 0 4px 12px rgba(251, 191, 36, 0.4);
418
+ }
419
+
420
+ #grain-debug-panel button.secondary {
421
+ background: white;
422
+ border: 1.5px solid #e2e8f0;
423
+ color: #475569;
424
+ }
425
+
426
+ #grain-debug-panel button.secondary:hover {
427
+ background: #f8fafc;
428
+ border-color: #cbd5e1;
429
+ }
430
+
431
+ #grain-debug-panel .url-pattern-input {
432
+ display: none;
433
+ }
434
+
435
+ #grain-debug-panel .url-pattern-input.visible {
436
+ display: block;
437
+ }
438
+ </style>
439
+ <div class="grain-panel-inner">
440
+ <div class="grain-panel-header">
441
+ <h3>Create Tracker</h3>
442
+ <p>Set up automatic tracking for this element</p>
443
+ </div>
444
+ <div class="grain-panel-body">
445
+ <div class="element-preview">
446
+ <div><strong>Element:</strong> ${i}${r?`#${r}`:""}</div>
447
+ ${n?`<div><strong>Text:</strong> ${n}</div>`:""}
448
+ </div>
449
+ <div>
450
+ <label>Event Name</label>
451
+ <input type="text" id="grain-event-name" placeholder="e.g., signup_button_click" value="" />
452
+ </div>
453
+ <div>
454
+ <label>Type</label>
455
+ <select id="grain-event-type">
456
+ <option value="metric">Metric</option>
457
+ <option value="conversion">Conversion</option>
458
+ </select>
459
+ </div>
460
+ <div>
461
+ <label>URL Scope</label>
462
+ <select id="grain-url-scope">
463
+ <option value="all">All Pages</option>
464
+ <option value="contains" selected>This Page</option>
465
+ <option value="equals">Exact URL</option>
466
+ </select>
467
+ </div>
468
+ <div class="url-pattern-input visible" id="grain-url-pattern-container">
469
+ <label>URL Pattern</label>
470
+ <input type="text" id="grain-url-pattern" placeholder="e.g., /pricing" value="${window.location.pathname}" />
471
+ </div>
472
+ <div class="button-group">
473
+ <button type="button" class="secondary" id="grain-cancel">Cancel</button>
474
+ <button type="button" class="primary" id="grain-create">\u2713 Create</button>
475
+ </div>
476
+ </div>
477
+ </div>
478
+ `,document.body.appendChild(t),this.panelElement=t;let o=t.querySelector("#grain-event-name");if(o){let S=this.generateEventName(e);o.value=S,o.select()}let c=t.querySelector("#grain-url-scope"),l=t.querySelector("#grain-url-pattern-container"),u=t.querySelector("#grain-url-pattern");c&&l&&c.addEventListener("change",()=>{c.value==="all"?l.classList.remove("visible"):(l.classList.add("visible"),u&&!u.value&&(u.value=window.location.pathname))});let d=t.querySelector("#grain-cancel"),h=t.querySelector("#grain-create");d&&d.addEventListener("click",()=>this.hideCreationPanel()),h&&h.addEventListener("click",()=>this.handleCreateTracker(a))}generateEventName(e){let t=e.tagName.toLowerCase(),i=e.id,r=e.textContent?.trim().toLowerCase().replace(/\s+/g,"_").substring(0,30)||"";return i?`${i}_click`:r?`${r}_click`:t==="button"?"button_click":t==="a"?"link_click":`${t}_click`}async handleCreateTracker(e){if(!this.panelElement)return;let t=this.panelElement.querySelector("#grain-event-name"),i=this.panelElement.querySelector("#grain-event-type"),r=this.panelElement.querySelector("#grain-url-scope"),n=this.panelElement.querySelector("#grain-url-pattern");if(!t||!i||!r)return;let a=t.value.trim(),o=i.value,c=r.value,l=n?.value.trim()||void 0;if(!a){alert("Please enter an event name");return}if(!a.match(/^[a-zA-Z0-9_-]+$/)){alert("Event name can only contain letters, numbers, underscores, and hyphens");return}if((c==="contains"||c==="equals")&&!l){alert("Please enter a URL pattern");return}try{let u=this.panelElement.querySelector("#grain-create");u&&(u.textContent="Creating...",u.disabled=!0),await this.createTracker(a,o,e,c,l),this.hideCreationPanel(),this.showSuccessMessage(`Tracker "${a}" created successfully!`),await this.loadExistingTrackers(),this.updateToolbarStats(),this.showTrackers&&(this.showTrackerHighlights(),this.showTrackersList()),this.log("Tracker created:",a)}catch(u){alert("Failed to create tracker. Please try again."),this.log("Failed to create tracker:",u);let d=this.panelElement.querySelector("#grain-create");d&&(d.textContent="Create Tracker",d.disabled=!1)}}async createTracker(e,t,i,r,n){let a=`${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/trackers`,o=await fetch(a,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({name:e,type:t,selector:i,urlScope:r,urlPattern:n})});if(!o.ok)throw new Error(`Failed to create tracker: ${o.status}`)}hideCreationPanel(){this.panelElement&&(this.panelElement.remove(),this.panelElement=null),this.selectedElement=null}showSuccessMessage(e){let t=document.createElement("div");t.style.cssText=`
479
+ position: fixed;
480
+ top: 20px;
481
+ left: 50%;
482
+ transform: translateX(-50%) translateY(-20px);
483
+ background: linear-gradient(135deg, #10b981 0%, #059669 100%);
484
+ color: white;
485
+ padding: 14px 24px;
486
+ border-radius: 12px;
487
+ font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', Roboto, sans-serif;
488
+ font-size: 14px;
489
+ font-weight: 600;
490
+ box-shadow: 0 12px 32px rgba(16, 185, 129, 0.3), 0 4px 12px rgba(0, 0, 0, 0.15);
491
+ z-index: 1000000;
492
+ display: flex;
493
+ align-items: center;
494
+ gap: 10px;
495
+ animation: slideDown 0.3s ease-out forwards;
496
+ `,t.innerHTML=`
497
+ <style>
498
+ @keyframes slideDown {
499
+ to {
500
+ transform: translateX(-50%) translateY(0);
501
+ }
502
+ }
503
+ </style>
504
+ <span style="font-size: 18px;">\u2713</span>
505
+ <span>${e}</span>
506
+ `,document.body.appendChild(t),setTimeout(()=>{t.style.animation="slideDown 0.3s ease-in reverse",setTimeout(()=>{t.remove()},300)},2700)}async endDebug(){try{let t=`${this.apiUrl}/v1/tenant/${encodeURIComponent(this.tenantId)}/debug-sessions/${this.sessionId}/end`;await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"}})}catch(t){this.log("Failed to end debug session:",t)}this.destroy();let e=new URL(window.location.href);e.searchParams.delete("grain_debug"),e.searchParams.delete("grain_session"),window.location.href=e.toString()}getXPathForElement(e){if(e.id)return`//*[@id="${e.id}"]`;let t=[],i=e;for(;i&&i.nodeType===Node.ELEMENT_NODE;){let r=0,n=i;for(;n;)n.nodeType===Node.ELEMENT_NODE&&n.tagName===i.tagName&&r++,n=n.previousElementSibling;let a=i.tagName.toLowerCase(),o=r>1?`[${r}]`:"";t.unshift(`${a}${o}`),i=i.parentElement}return t.length?`/${t.join("/")}`:""}log(...e){this.config.debug&&console.log("[DebugAgent]",...e)}updateToolbarStats(){if(!this.toolbarElement)return;let e=this.toolbarElement.querySelector(".grain-stat:nth-child(1) .grain-stat-value"),t=this.toolbarElement.querySelector(".grain-stat:nth-child(2) .grain-stat-value");e&&(e.textContent=String(this.existingTrackers.length)),t&&(t.textContent=String(this.existingTrackers.filter(i=>i.isEnabled).length))}destroy(){this.isDestroyed||(this.log("Destroying debug agent"),this.isDestroyed=!0,this.disableInspectMode(),this.hideTrackerHighlights(),this.endDrag(),this.toolbarElement&&(this.toolbarElement.remove(),this.toolbarElement=null),this.panelElement&&(this.panelElement.remove(),this.panelElement=null),this.highlightElement&&(this.highlightElement.remove(),this.highlightElement=null))}}});var Se={};b(Se,{GrainAnalytics:()=>v,categorizeReferrer:()=>m,createGrainAnalytics:()=>re,default:()=>Ae,getCountry:()=>W,getCountryCodeFromTimezone:()=>P,getState:()=>Y,parseUTMParameters:()=>A});var F=["necessary","analytics","functional"],E="1.0.0",T=class{constructor(e,t="opt-out"){this.consentState=null;this.listeners=[];this.consentMode=t,this.storageKey=`grain_consent_${e}`,this.loadConsentState()}loadConsentState(){if(!(typeof window>"u"))try{let e=localStorage.getItem(this.storageKey);if(e){let t=JSON.parse(e);this.consentState={...t,timestamp:new Date(t.timestamp)}}else(this.consentMode==="opt-out"||this.consentMode==="disabled")&&(this.consentState={granted:!0,categories:F,timestamp:new Date,version:E},this.saveConsentState())}catch{}}saveConsentState(){if(!(typeof window>"u"||!this.consentState))try{localStorage.setItem(this.storageKey,JSON.stringify(this.consentState))}catch{}}grantConsent(e){let t=e||F;this.consentState={granted:!0,categories:t,timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}revokeConsent(e){this.consentState?e?this.consentState={...this.consentState,categories:this.consentState.categories.filter(t=>!e.includes(t)),granted:this.consentState.categories.length>0,timestamp:new Date}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:E},this.saveConsentState(),this.notifyListeners()}getConsentState(){return this.consentState?{...this.consentState}:null}hasConsent(e){return this.consentMode==="disabled"?!0:this.consentMode==="opt-in"&&!this.consentState||!this.consentState?.granted?!1:e?this.consentState.categories.includes(e):!0}shouldWaitForConsent(){return this.consentMode==="opt-in"&&!this.consentState?.granted}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){this.consentState&&this.listeners.forEach(e=>{try{e(this.consentState)}catch{}})}clearConsent(){if(!(typeof window>"u"))try{localStorage.removeItem(this.storageKey),this.consentState=null}catch{}}};function _(s,e,t){if(typeof document>"u")return;let i=[`${encodeURIComponent(s)}=${encodeURIComponent(e)}`];t?.maxAge!==void 0&&i.push(`max-age=${t.maxAge}`),t?.domain&&i.push(`domain=${t.domain}`),t?.path?i.push(`path=${t.path}`):i.push("path=/"),t?.sameSite&&i.push(`samesite=${t.sameSite}`),t?.secure&&i.push("secure"),document.cookie=i.join("; ")}function D(s){if(typeof document>"u")return null;let e=encodeURIComponent(s)+"=",t=document.cookie.split(";");for(let i=0;i<t.length;i++){let r=t[i];for(;r.charAt(0)===" ";)r=r.substring(1);if(r.indexOf(e)===0)return decodeURIComponent(r.substring(e.length))}return null}function le(s,e){if(typeof document>"u")return;let t=[`${encodeURIComponent(s)}=`,"max-age=0"];e?.domain&&t.push(`domain=${e.domain}`),e?.path?t.push(`path=${e.path}`):t.push("path=/"),document.cookie=t.join("; ")}function $(){if(typeof document>"u")return!1;try{let s="_grain_cookie_test";_(s,"test",{maxAge:1});let e=D(s)==="test";return le(s),e}catch{return!1}}var k=class{constructor(){this.activityThreshold=3e4;this.listeners=[];this.isDestroyed=!1;this.activityEvents=["mousemove","mousedown","keydown","scroll","touchstart","click"];this.lastActivityTime=Date.now(),this.boundActivityHandler=this.debounce(this.handleActivity.bind(this),500),this.setupListeners()}setupListeners(){if(!(typeof window>"u"))for(let e of this.activityEvents)window.addEventListener(e,this.boundActivityHandler,{passive:!0})}handleActivity(){this.isDestroyed||(this.lastActivityTime=Date.now(),this.notifyListeners())}debounce(e,t){let i=null;return()=>{i!==null&&clearTimeout(i),i=window.setTimeout(()=>{e(),i=null},t)}}isActive(e){let t=e??this.activityThreshold;return Date.now()-this.lastActivityTime<t}getTimeSinceLastActivity(){return Date.now()-this.lastActivityTime}getLastActivityTime(){return this.lastActivityTime}setActivityThreshold(e){this.activityThreshold=e}addListener(e){this.listeners.push(e)}removeListener(e){let t=this.listeners.indexOf(e);t>-1&&this.listeners.splice(t,1)}notifyListeners(){for(let e of this.listeners)try{e()}catch{}}destroy(){if(!this.isDestroyed){if(typeof window<"u")for(let e of this.activityEvents)window.removeEventListener(e,this.boundActivityHandler);this.listeners=[],this.isDestroyed=!0}}};var w=class{constructor(e,t,i){this.heartbeatTimer=null;this.isDestroyed=!1;this.hasSentPageLoadHeartbeat=!1;this.tracker=e,this.activityDetector=t,this.config=i,this.lastHeartbeatTime=Date.now(),this.currentInterval=i.activeInterval,this.sendPageLoadHeartbeat(),this.scheduleNextHeartbeat()}sendPageLoadHeartbeat(){if(!(this.isDestroyed||this.hasSentPageLoadHeartbeat))if(typeof window<"u"&&document.readyState!=="complete"){let e=()=>{this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0,window.removeEventListener("load",e)};window.addEventListener("load",e)}else this.sendHeartbeat("page_load"),this.hasSentPageLoadHeartbeat=!0}scheduleNextHeartbeat(){if(this.isDestroyed)return;this.heartbeatTimer!==null&&clearTimeout(this.heartbeatTimer);let e=this.activityDetector.isActive(6e4);this.currentInterval=e?this.config.activeInterval:this.config.inactiveInterval,this.heartbeatTimer=window.setTimeout(()=>{this.sendHeartbeat("periodic"),this.scheduleNextHeartbeat()},this.currentInterval),this.config.debug&&console.log(`[Heartbeat] Scheduled next heartbeat in ${this.currentInterval/1e3}s (${e?"active":"inactive"})`)}sendHeartbeat(e="periodic"){if(this.isDestroyed)return;let t=Date.now(),i=this.activityDetector.isActive(6e4),r=this.tracker.hasConsent("analytics"),n={heartbeat_type:e,status:i?"active":"inactive",timestamp:t};if(r){let a=this.tracker.getCurrentPage();a&&(n.page=a),n.session_id=this.tracker.getSessionId(),e==="periodic"&&(n.duration=t-this.lastHeartbeatTime,n.event_count=this.tracker.getEventCountSinceLastHeartbeat(),this.tracker.resetEventCountSinceLastHeartbeat())}this.tracker.trackSystemEvent("_grain_heartbeat",n),this.lastHeartbeatTime=t}destroy(){this.isDestroyed||(this.heartbeatTimer!==null&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null),this.isDestroyed=!0)}};var ue=["gclid","msclkid","fbclid","ttclid","li_fat_id","twclid","ScCid"],de=["facebook.com","twitter.com","x.com","linkedin.com","instagram.com","pinterest.com","reddit.com","tiktok.com","youtube.com","snapchat.com","t.co","fb.me","lnkd.in"],he=["google.","bing.com","yahoo.com","duckduckgo.com","baidu.com","yandex.com","ecosia.org","ask.com"],ge=["mail.google.com","outlook.live.com","mail.yahoo.com","mail.aol.com"];function R(s){try{return new URL(s).hostname.toLowerCase()}catch{return""}}function z(s){try{let e=new URL(s);return ue.some(t=>e.searchParams.has(t))}catch{return!1}}function m(s,e=""){if(!s||s.trim()==="")return"direct";let t=R(s);if(e){let i=R(e);if(t===i)return"direct"}return z(s)||z(e)?"paid":ge.some(i=>t.includes(i))?"email":de.some(i=>t.includes(i))?"social":he.some(i=>t.includes(i))?"organic":"referral"}function A(s){try{let e=new URL(s),t={},i=e.searchParams.get("utm_source"),r=e.searchParams.get("utm_medium"),n=e.searchParams.get("utm_campaign"),a=e.searchParams.get("utm_term"),o=e.searchParams.get("utm_content");return i&&(t.utm_source=i),r&&(t.utm_medium=r),n&&(t.utm_campaign=n),a&&(t.utm_term=a),o&&(t.utm_content=o),t}catch{return{}}}function L(s){if(typeof window>"u"||typeof localStorage>"u")return null;try{let e=`_grain_first_touch_${s}`,t=localStorage.getItem(e);if(t)return JSON.parse(t)}catch(e){console.warn("[Grain Attribution] Failed to retrieve first-touch attribution:",e)}return null}function me(s,e){if(!(typeof window>"u"||typeof localStorage>"u"))try{let t=`_grain_first_touch_${s}`;localStorage.setItem(t,JSON.stringify(e))}catch(t){console.warn("[Grain Attribution] Failed to store first-touch attribution:",t)}}function C(s,e,t,i){let r=L(s);if(r)return r;let n=m(e,t),a=R(e),o={source:i.utm_source||a||"direct",medium:i.utm_medium||n,campaign:i.utm_campaign||"none",referrer:e||"direct",referrer_category:n,timestamp:Date.now()};return me(s,o),o}var K=null;function p(){return K}function V(s){K=s}var pe={AD:"Andorra",AE:"United Arab Emirates",AF:"Afghanistan",AG:"Antigua and Barbuda",AI:"Anguilla",AL:"Albania",AM:"Armenia",AO:"Angola",AQ:"Antarctica",AR:"Argentina",AS:"American Samoa",AT:"Austria",AU:"Australia",AW:"Aruba",AX:"\xC5land Islands",AZ:"Azerbaijan",BA:"Bosnia and Herzegovina",BB:"Barbados",BD:"Bangladesh",BE:"Belgium",BF:"Burkina Faso",BG:"Bulgaria",BH:"Bahrain",BI:"Burundi",BJ:"Benin",BL:"Saint Barth\xE9lemy",BM:"Bermuda",BN:"Brunei",BO:"Bolivia",BQ:"Caribbean Netherlands",BR:"Brazil",BS:"Bahamas",BT:"Bhutan",BV:"Bouvet Island",BW:"Botswana",BY:"Belarus",BZ:"Belize",CA:"Canada",CC:"Cocos Islands",CD:"Democratic Republic of the Congo",CF:"Central African Republic",CG:"Republic of the Congo",CH:"Switzerland",CI:"Ivory Coast",CK:"Cook Islands",CL:"Chile",CM:"Cameroon",CN:"China",CO:"Colombia",CR:"Costa Rica",CU:"Cuba",CV:"Cabo Verde",CW:"Cura\xE7ao",CX:"Christmas Island",CY:"Cyprus",CZ:"Czechia",DE:"Germany",DJ:"Djibouti",DK:"Denmark",DM:"Dominica",DO:"Dominican Republic",DZ:"Algeria",EC:"Ecuador",EE:"Estonia",EG:"Egypt",EH:"Western Sahara",ER:"Eritrea",ES:"Spain",ET:"Ethiopia",FI:"Finland",FJ:"Fiji",FK:"Falkland Islands",FM:"Micronesia",FO:"Faroe Islands",FR:"France",GA:"Gabon",GB:"United Kingdom",GD:"Grenada",GE:"Georgia",GF:"French Guiana",GG:"Guernsey",GH:"Ghana",GI:"Gibraltar",GL:"Greenland",GM:"Gambia",GN:"Guinea",GP:"Guadeloupe",GQ:"Equatorial Guinea",GR:"Greece",GS:"South Georgia and the South Sandwich Islands",GT:"Guatemala",GU:"Guam",GW:"Guinea-Bissau",GY:"Guyana",HK:"Hong Kong",HM:"Heard Island and McDonald Islands",HN:"Honduras",HR:"Croatia",HT:"Haiti",HU:"Hungary",ID:"Indonesia",IE:"Ireland",IL:"Israel",IM:"Isle of Man",IN:"India",IO:"British Indian Ocean Territory",IQ:"Iraq",IR:"Iran",IS:"Iceland",IT:"Italy",JE:"Jersey",JM:"Jamaica",JO:"Jordan",JP:"Japan",KE:"Kenya",KG:"Kyrgyzstan",KH:"Cambodia",KI:"Kiribati",KM:"Comoros",KN:"Saint Kitts and Nevis",KP:"North Korea",KR:"South Korea",KW:"Kuwait",KY:"Cayman Islands",KZ:"Kazakhstan",LA:"Laos",LB:"Lebanon",LC:"Saint Lucia",LI:"Liechtenstein",LK:"Sri Lanka",LR:"Liberia",LS:"Lesotho",LT:"Lithuania",LU:"Luxembourg",LV:"Latvia",LY:"Libya",MA:"Morocco",MC:"Monaco",MD:"Moldova",ME:"Montenegro",MF:"Saint Martin",MG:"Madagascar",MH:"Marshall Islands",MK:"North Macedonia",ML:"Mali",MM:"Myanmar",MN:"Mongolia",MO:"Macao",MP:"Northern Mariana Islands",MQ:"Martinique",MR:"Mauritania",MS:"Montserrat",MT:"Malta",MU:"Mauritius",MV:"Maldives",MW:"Malawi",MX:"Mexico",MY:"Malaysia",MZ:"Mozambique",NA:"Namibia",NC:"New Caledonia",NE:"Niger",NF:"Norfolk Island",NG:"Nigeria",NI:"Nicaragua",NL:"Netherlands",NO:"Norway",NP:"Nepal",NR:"Nauru",NU:"Niue",NZ:"New Zealand",OM:"Oman",PA:"Panama",PE:"Peru",PF:"French Polynesia",PG:"Papua New Guinea",PH:"Philippines",PK:"Pakistan",PL:"Poland",PM:"Saint Pierre and Miquelon",PN:"Pitcairn",PR:"Puerto Rico",PS:"Palestine",PT:"Portugal",PW:"Palau",PY:"Paraguay",QA:"Qatar",RE:"R\xE9union",RO:"Romania",RS:"Serbia",RU:"Russia",RW:"Rwanda",SA:"Saudi Arabia",SB:"Solomon Islands",SC:"Seychelles",SD:"Sudan",SE:"Sweden",SG:"Singapore",SH:"Saint Helena, Ascension and Tristan da Cunha",SI:"Slovenia",SJ:"Svalbard and Jan Mayen",SK:"Slovakia",SL:"Sierra Leone",SM:"San Marino",SN:"Senegal",SO:"Somalia",SR:"Suriname",SS:"South Sudan",ST:"Sao Tome and Principe",SV:"El Salvador",SX:"Sint Maarten",SY:"Syria",SZ:"Eswatini",TC:"Turks and Caicos Islands",TD:"Chad",TF:"French Southern Territories",TG:"Togo",TH:"Thailand",TJ:"Tajikistan",TK:"Tokelau",TL:"Timor-Leste",TM:"Turkmenistan",TN:"Tunisia",TO:"Tonga",TR:"Turkey",TT:"Trinidad and Tobago",TV:"Tuvalu",TW:"Taiwan",TZ:"Tanzania",UA:"Ukraine",UG:"Uganda",UM:"United States Minor Outlying Islands",US:"United States of America",UY:"Uruguay",UZ:"Uzbekistan",VA:"Holy See",VC:"Saint Vincent and the Grenadines",VE:"Venezuela",VG:"Virgin Islands (UK)",VI:"Virgin Islands (US)",VN:"Vietnam",VU:"Vanuatu",WF:"Wallis and Futuna",WS:"Samoa",YE:"Yemen",YT:"Mayotte",ZA:"South Africa",ZM:"Zambia",ZW:"Zimbabwe"},Q={"Africa/Abidjan":{u:0,c:["CI","BF","GH","GM","GN","ML","MR","SH","SL","SN","TG"]},"Africa/Accra":{a:"Africa/Abidjan",c:["GH"],r:1},"Africa/Addis_Ababa":{a:"Africa/Nairobi",c:["ET"],r:1},"Africa/Algiers":{u:60,c:["DZ"]},"Africa/Asmara":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Asmera":{a:"Africa/Nairobi",c:["ER"],r:1},"Africa/Bamako":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Bangui":{a:"Africa/Lagos",c:["CF"],r:1},"Africa/Banjul":{a:"Africa/Abidjan",c:["GM"],r:1},"Africa/Bissau":{u:0,c:["GW"]},"Africa/Blantyre":{a:"Africa/Maputo",c:["MW"],r:1},"Africa/Brazzaville":{a:"Africa/Lagos",c:["CG"],r:1},"Africa/Bujumbura":{a:"Africa/Maputo",c:["BI"],r:1},"Africa/Cairo":{u:120,c:["EG"]},"Africa/Casablanca":{u:60,d:0,c:["MA"]},"Africa/Ceuta":{u:60,d:120,c:["ES"]},"Africa/Conakry":{a:"Africa/Abidjan",c:["GN"],r:1},"Africa/Dakar":{a:"Africa/Abidjan",c:["SN"],r:1},"Africa/Dar_es_Salaam":{a:"Africa/Nairobi",c:["TZ"],r:1},"Africa/Djibouti":{a:"Africa/Nairobi",c:["DJ"],r:1},"Africa/Douala":{a:"Africa/Lagos",c:["CM"],r:1},"Africa/El_Aaiun":{u:60,d:0,c:["EH"]},"Africa/Freetown":{a:"Africa/Abidjan",c:["SL"],r:1},"Africa/Gaborone":{a:"Africa/Maputo",c:["BW"],r:1},"Africa/Harare":{a:"Africa/Maputo",c:["ZW"],r:1},"Africa/Johannesburg":{u:120,c:["ZA","LS","SZ"]},"Africa/Juba":{u:120,c:["SS"]},"Africa/Kampala":{a:"Africa/Nairobi",c:["UG"],r:1},"Africa/Khartoum":{u:120,c:["SD"]},"Africa/Kigali":{a:"Africa/Maputo",c:["RW"],r:1},"Africa/Kinshasa":{a:"Africa/Lagos",c:["CD"],r:1},"Africa/Lagos":{u:60,c:["NG","AO","BJ","CD","CF","CG","CM","GA","GQ","NE"]},"Africa/Libreville":{a:"Africa/Lagos",c:["GA"],r:1},"Africa/Lome":{a:"Africa/Abidjan",c:["TG"],r:1},"Africa/Luanda":{a:"Africa/Lagos",c:["AO"],r:1},"Africa/Lubumbashi":{a:"Africa/Maputo",c:["CD"],r:1},"Africa/Lusaka":{a:"Africa/Maputo",c:["ZM"],r:1},"Africa/Malabo":{a:"Africa/Lagos",c:["GQ"],r:1},"Africa/Maputo":{u:120,c:["MZ","BI","BW","CD","MW","RW","ZM","ZW"]},"Africa/Maseru":{a:"Africa/Johannesburg",c:["LS"],r:1},"Africa/Mbabane":{a:"Africa/Johannesburg",c:["SZ"],r:1},"Africa/Mogadishu":{a:"Africa/Nairobi",c:["SO"],r:1},"Africa/Monrovia":{u:0,c:["LR"]},"Africa/Nairobi":{u:180,c:["KE","DJ","ER","ET","KM","MG","SO","TZ","UG","YT"]},"Africa/Ndjamena":{u:60,c:["TD"]},"Africa/Niamey":{a:"Africa/Lagos",c:["NE"],r:1},"Africa/Nouakchott":{a:"Africa/Abidjan",c:["MR"],r:1},"Africa/Ouagadougou":{a:"Africa/Abidjan",c:["BF"],r:1},"Africa/Porto-Novo":{a:"Africa/Lagos",c:["BJ"],r:1},"Africa/Sao_Tome":{u:0,c:["ST"]},"Africa/Timbuktu":{a:"Africa/Abidjan",c:["ML"],r:1},"Africa/Tripoli":{u:120,c:["LY"]},"Africa/Tunis":{u:60,c:["TN"]},"Africa/Windhoek":{u:120,c:["NA"]},"America/Adak":{u:-600,d:-540,c:["US"]},"America/Anchorage":{u:-540,d:-480,c:["US"]},"America/Anguilla":{a:"America/Puerto_Rico",c:["AI"],r:1},"America/Antigua":{a:"America/Puerto_Rico",c:["AG"],r:1},"America/Araguaina":{u:-180,c:["BR"]},"America/Argentina/Buenos_Aires":{u:-180,c:["AR"]},"America/Argentina/Catamarca":{u:-180,c:["AR"]},"America/Argentina/ComodRivadavia":{a:"America/Argentina/Catamarca",r:1},"America/Argentina/Cordoba":{u:-180,c:["AR"]},"America/Argentina/Jujuy":{u:-180,c:["AR"]},"America/Argentina/La_Rioja":{u:-180,c:["AR"]},"America/Argentina/Mendoza":{u:-180,c:["AR"]},"America/Argentina/Rio_Gallegos":{u:-180,c:["AR"]},"America/Argentina/Salta":{u:-180,c:["AR"]},"America/Argentina/San_Juan":{u:-180,c:["AR"]},"America/Argentina/San_Luis":{u:-180,c:["AR"]},"America/Argentina/Tucuman":{u:-180,c:["AR"]},"America/Argentina/Ushuaia":{u:-180,c:["AR"]},"America/Aruba":{a:"America/Puerto_Rico",c:["AW"],r:1},"America/Asuncion":{u:-240,d:-180,c:["PY"]},"America/Atikokan":{a:"America/Panama",c:["CA"],r:1},"America/Atka":{a:"America/Adak",r:1},"America/Bahia":{u:-180,c:["BR"]},"America/Bahia_Banderas":{u:-360,d:-300,c:["MX"]},"America/Barbados":{u:-240,c:["BB"]},"America/Belem":{u:-180,c:["BR"]},"America/Belize":{u:-360,c:["BZ"]},"America/Blanc-Sablon":{a:"America/Puerto_Rico",c:["CA"],r:1},"America/Boa_Vista":{u:-240,c:["BR"]},"America/Bogota":{u:-300,c:["CO"]},"America/Boise":{u:-420,d:-360,c:["US"]},"America/Buenos_Aires":{a:"America/Argentina/Buenos_Aires",r:1},"America/Cambridge_Bay":{u:-420,d:-360,c:["CA"]},"America/Campo_Grande":{u:-240,c:["BR"]},"America/Cancun":{u:-300,c:["MX"]},"America/Caracas":{u:-240,c:["VE"]},"America/Catamarca":{a:"America/Argentina/Catamarca",r:1},"America/Cayenne":{u:-180,c:["GF"]},"America/Cayman":{a:"America/Panama",c:["KY"],r:1},"America/Chicago":{u:-360,d:-300,c:["US"]},"America/Chihuahua":{u:-420,d:-360,c:["MX"]},"America/Coral_Harbour":{a:"America/Panama",c:["CA"],r:1},"America/Cordoba":{a:"America/Argentina/Cordoba",r:1},"America/Costa_Rica":{u:-360,c:["CR"]},"America/Creston":{a:"America/Phoenix",c:["CA"],r:1},"America/Cuiaba":{u:-240,c:["BR"]},"America/Curacao":{a:"America/Puerto_Rico",c:["CW"],r:1},"America/Danmarkshavn":{u:0,c:["GL"]},"America/Dawson":{u:-420,c:["CA"]},"America/Dawson_Creek":{u:-420,c:["CA"]},"America/Denver":{u:-420,d:-360,c:["US"]},"America/Detroit":{u:-300,d:-240,c:["US"]},"America/Dominica":{a:"America/Puerto_Rico",c:["DM"],r:1},"America/Edmonton":{u:-420,d:-360,c:["CA"]},"America/Eirunepe":{u:-300,c:["BR"]},"America/El_Salvador":{u:-360,c:["SV"]},"America/Ensenada":{a:"America/Tijuana",r:1},"America/Fort_Nelson":{u:-420,c:["CA"]},"America/Fort_Wayne":{a:"America/Indiana/Indianapolis",r:1},"America/Fortaleza":{u:-180,c:["BR"]},"America/Glace_Bay":{u:-240,d:-180,c:["CA"]},"America/Godthab":{a:"America/Nuuk",r:1},"America/Goose_Bay":{u:-240,d:-180,c:["CA"]},"America/Grand_Turk":{u:-300,d:-240,c:["TC"]},"America/Grenada":{a:"America/Puerto_Rico",c:["GD"],r:1},"America/Guadeloupe":{a:"America/Puerto_Rico",c:["GP"],r:1},"America/Guatemala":{u:-360,c:["GT"]},"America/Guayaquil":{u:-300,c:["EC"]},"America/Guyana":{u:-240,c:["GY"]},"America/Halifax":{u:-240,d:-180,c:["CA"]},"America/Havana":{u:-300,d:-240,c:["CU"]},"America/Hermosillo":{u:-420,c:["MX"]},"America/Indiana/Indianapolis":{u:-300,d:-240,c:["US"]},"America/Indiana/Knox":{u:-360,d:-300,c:["US"]},"America/Indiana/Marengo":{u:-300,d:-240,c:["US"]},"America/Indiana/Petersburg":{u:-300,d:-240,c:["US"]},"America/Indiana/Tell_City":{u:-360,d:-300,c:["US"]},"America/Indiana/Vevay":{u:-300,d:-240,c:["US"]},"America/Indiana/Vincennes":{u:-300,d:-240,c:["US"]},"America/Indiana/Winamac":{u:-300,d:-240,c:["US"]},"America/Indianapolis":{a:"America/Indiana/Indianapolis",r:1},"America/Inuvik":{u:-420,d:-360,c:["CA"]},"America/Iqaluit":{u:-300,d:-240,c:["CA"]},"America/Jamaica":{u:-300,c:["JM"]},"America/Jujuy":{a:"America/Argentina/Jujuy",r:1},"America/Juneau":{u:-540,d:-480,c:["US"]},"America/Kentucky/Louisville":{u:-300,d:-240,c:["US"]},"America/Kentucky/Monticello":{u:-300,d:-240,c:["US"]},"America/Knox_IN":{a:"America/Indiana/Knox",r:1},"America/Kralendijk":{a:"America/Puerto_Rico",c:["BQ"],r:1},"America/La_Paz":{u:-240,c:["BO"]},"America/Lima":{u:-300,c:["PE"]},"America/Los_Angeles":{u:-480,d:-420,c:["US"]},"America/Louisville":{a:"America/Kentucky/Louisville",r:1},"America/Lower_Princes":{a:"America/Puerto_Rico",c:["SX"],r:1},"America/Maceio":{u:-180,c:["BR"]},"America/Managua":{u:-360,c:["NI"]},"America/Manaus":{u:-240,c:["BR"]},"America/Marigot":{a:"America/Puerto_Rico",c:["MF"],r:1},"America/Martinique":{u:-240,c:["MQ"]},"America/Matamoros":{u:-360,d:-300,c:["MX"]},"America/Mazatlan":{u:-420,d:-360,c:["MX"]},"America/Mendoza":{a:"America/Argentina/Mendoza",r:1},"America/Menominee":{u:-360,d:-300,c:["US"]},"America/Merida":{u:-360,d:-300,c:["MX"]},"America/Metlakatla":{u:-540,d:-480,c:["US"]},"America/Mexico_City":{u:-360,d:-300,c:["MX"]},"America/Miquelon":{u:-180,d:-120,c:["PM"]},"America/Moncton":{u:-240,d:-180,c:["CA"]},"America/Monterrey":{u:-360,d:-300,c:["MX"]},"America/Montevideo":{u:-180,c:["UY"]},"America/Montreal":{a:"America/Toronto",c:["CA"],r:1},"America/Montserrat":{a:"America/Puerto_Rico",c:["MS"],r:1},"America/Nassau":{a:"America/Toronto",c:["BS"],r:1},"America/New_York":{u:-300,d:-240,c:["US"]},"America/Nipigon":{u:-300,d:-240,c:["CA"]},"America/Nome":{u:-540,d:-480,c:["US"]},"America/Noronha":{u:-120,c:["BR"]},"America/North_Dakota/Beulah":{u:-360,d:-300,c:["US"]},"America/North_Dakota/Center":{u:-360,d:-300,c:["US"]},"America/North_Dakota/New_Salem":{u:-360,d:-300,c:["US"]},"America/Nuuk":{u:-180,d:-120,c:["GL"]},"America/Ojinaga":{u:-420,d:-360,c:["MX"]},"America/Panama":{u:-300,c:["PA","CA","KY"]},"America/Pangnirtung":{u:-300,d:-240,c:["CA"]},"America/Paramaribo":{u:-180,c:["SR"]},"America/Phoenix":{u:-420,c:["US","CA"]},"America/Port-au-Prince":{u:-300,d:-240,c:["HT"]},"America/Port_of_Spain":{a:"America/Puerto_Rico",c:["TT"],r:1},"America/Porto_Acre":{a:"America/Rio_Branco",r:1},"America/Porto_Velho":{u:-240,c:["BR"]},"America/Puerto_Rico":{u:-240,c:["PR","AG","CA","AI","AW","BL","BQ","CW","DM","GD","GP","KN","LC","MF","MS","SX","TT","VC","VG","VI"]},"America/Punta_Arenas":{u:-180,c:["CL"]},"America/Rainy_River":{u:-360,d:-300,c:["CA"]},"America/Rankin_Inlet":{u:-360,d:-300,c:["CA"]},"America/Recife":{u:-180,c:["BR"]},"America/Regina":{u:-360,c:["CA"]},"America/Resolute":{u:-360,d:-300,c:["CA"]},"America/Rio_Branco":{u:-300,c:["BR"]},"America/Rosario":{a:"America/Argentina/Cordoba",r:1},"America/Santa_Isabel":{a:"America/Tijuana",r:1},"America/Santarem":{u:-180,c:["BR"]},"America/Santiago":{u:-240,d:-180,c:["CL"]},"America/Santo_Domingo":{u:-240,c:["DO"]},"America/Sao_Paulo":{u:-180,c:["BR"]},"America/Scoresbysund":{u:-60,d:0,c:["GL"]},"America/Shiprock":{a:"America/Denver",r:1},"America/Sitka":{u:-540,d:-480,c:["US"]},"America/St_Barthelemy":{a:"America/Puerto_Rico",c:["BL"],r:1},"America/St_Johns":{u:-150,d:-90,c:["CA"]},"America/St_Kitts":{a:"America/Puerto_Rico",c:["KN"],r:1},"America/St_Lucia":{a:"America/Puerto_Rico",c:["LC"],r:1},"America/St_Thomas":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/St_Vincent":{a:"America/Puerto_Rico",c:["VC"],r:1},"America/Swift_Current":{u:-360,c:["CA"]},"America/Tegucigalpa":{u:-360,c:["HN"]},"America/Thule":{u:-240,d:-180,c:["GL"]},"America/Thunder_Bay":{u:-300,d:-240,c:["CA"]},"America/Tijuana":{u:-480,d:-420,c:["MX"]},"America/Toronto":{u:-300,d:-240,c:["CA","BS"]},"America/Tortola":{a:"America/Puerto_Rico",c:["VG"],r:1},"America/Vancouver":{u:-480,d:-420,c:["CA"]},"America/Virgin":{a:"America/Puerto_Rico",c:["VI"],r:1},"America/Whitehorse":{u:-420,c:["CA"]},"America/Winnipeg":{u:-360,d:-300,c:["CA"]},"America/Yakutat":{u:-540,d:-480,c:["US"]},"America/Yellowknife":{u:-420,d:-360,c:["CA"]},"Antarctica/Casey":{u:660,c:["AQ"]},"Antarctica/Davis":{u:420,c:["AQ"]},"Antarctica/DumontDUrville":{a:"Pacific/Port_Moresby",c:["AQ"],r:1},"Antarctica/Macquarie":{u:600,d:660,c:["AU"]},"Antarctica/Mawson":{u:300,c:["AQ"]},"Antarctica/McMurdo":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Palmer":{u:-180,c:["AQ"]},"Antarctica/Rothera":{u:-180,c:["AQ"]},"Antarctica/South_Pole":{a:"Pacific/Auckland",c:["AQ"],r:1},"Antarctica/Syowa":{a:"Asia/Riyadh",c:["AQ"],r:1},"Antarctica/Troll":{u:0,d:120,c:["AQ"]},"Antarctica/Vostok":{u:360,c:["AQ"]},"Arctic/Longyearbyen":{a:"Europe/Oslo",c:["SJ"],r:1},"Asia/Aden":{a:"Asia/Riyadh",c:["YE"],r:1},"Asia/Almaty":{u:360,c:["KZ"]},"Asia/Amman":{u:120,d:180,c:["JO"]},"Asia/Anadyr":{u:720,c:["RU"]},"Asia/Aqtau":{u:300,c:["KZ"]},"Asia/Aqtobe":{u:300,c:["KZ"]},"Asia/Ashgabat":{u:300,c:["TM"]},"Asia/Ashkhabad":{a:"Asia/Ashgabat",r:1},"Asia/Atyrau":{u:300,c:["KZ"]},"Asia/Baghdad":{u:180,c:["IQ"]},"Asia/Bahrain":{a:"Asia/Qatar",c:["BH"],r:1},"Asia/Baku":{u:240,c:["AZ"]},"Asia/Bangkok":{u:420,c:["TH","KH","LA","VN"]},"Asia/Barnaul":{u:420,c:["RU"]},"Asia/Beirut":{u:120,d:180,c:["LB"]},"Asia/Bishkek":{u:360,c:["KG"]},"Asia/Brunei":{u:480,c:["BN"]},"Asia/Calcutta":{a:"Asia/Kolkata",r:1},"Asia/Chita":{u:540,c:["RU"]},"Asia/Choibalsan":{u:480,c:["MN"]},"Asia/Chongqing":{a:"Asia/Shanghai",r:1},"Asia/Chungking":{a:"Asia/Shanghai",r:1},"Asia/Colombo":{u:330,c:["LK"]},"Asia/Dacca":{a:"Asia/Dhaka",r:1},"Asia/Damascus":{u:120,d:180,c:["SY"]},"Asia/Dhaka":{u:360,c:["BD"]},"Asia/Dili":{u:540,c:["TL"]},"Asia/Dubai":{u:240,c:["AE","OM"]},"Asia/Dushanbe":{u:300,c:["TJ"]},"Asia/Famagusta":{u:120,d:180,c:["CY"]},"Asia/Gaza":{u:120,d:180,c:["PS"]},"Asia/Harbin":{a:"Asia/Shanghai",r:1},"Asia/Hebron":{u:120,d:180,c:["PS"]},"Asia/Ho_Chi_Minh":{u:420,c:["VN"]},"Asia/Hong_Kong":{u:480,c:["HK"]},"Asia/Hovd":{u:420,c:["MN"]},"Asia/Irkutsk":{u:480,c:["RU"]},"Asia/Istanbul":{a:"Europe/Istanbul",r:1},"Asia/Jakarta":{u:420,c:["ID"]},"Asia/Jayapura":{u:540,c:["ID"]},"Asia/Jerusalem":{u:120,d:180,c:["IL"]},"Asia/Kabul":{u:270,c:["AF"]},"Asia/Kamchatka":{u:720,c:["RU"]},"Asia/Karachi":{u:300,c:["PK"]},"Asia/Kashgar":{a:"Asia/Urumqi",r:1},"Asia/Kathmandu":{u:345,c:["NP"]},"Asia/Katmandu":{a:"Asia/Kathmandu",r:1},"Asia/Khandyga":{u:540,c:["RU"]},"Asia/Kolkata":{u:330,c:["IN"]},"Asia/Krasnoyarsk":{u:420,c:["RU"]},"Asia/Kuala_Lumpur":{u:480,c:["MY"]},"Asia/Kuching":{u:480,c:["MY"]},"Asia/Kuwait":{a:"Asia/Riyadh",c:["KW"],r:1},"Asia/Macao":{a:"Asia/Macau",r:1},"Asia/Macau":{u:480,c:["MO"]},"Asia/Magadan":{u:660,c:["RU"]},"Asia/Makassar":{u:480,c:["ID"]},"Asia/Manila":{u:480,c:["PH"]},"Asia/Muscat":{a:"Asia/Dubai",c:["OM"],r:1},"Asia/Nicosia":{u:120,d:180,c:["CY"]},"Asia/Novokuznetsk":{u:420,c:["RU"]},"Asia/Novosibirsk":{u:420,c:["RU"]},"Asia/Omsk":{u:360,c:["RU"]},"Asia/Oral":{u:300,c:["KZ"]},"Asia/Phnom_Penh":{a:"Asia/Bangkok",c:["KH"],r:1},"Asia/Pontianak":{u:420,c:["ID"]},"Asia/Pyongyang":{u:540,c:["KP"]},"Asia/Qatar":{u:180,c:["QA","BH"]},"Asia/Qostanay":{u:360,c:["KZ"]},"Asia/Qyzylorda":{u:300,c:["KZ"]},"Asia/Rangoon":{a:"Asia/Yangon",r:1},"Asia/Riyadh":{u:180,c:["SA","AQ","KW","YE"]},"Asia/Saigon":{a:"Asia/Ho_Chi_Minh",r:1},"Asia/Sakhalin":{u:660,c:["RU"]},"Asia/Samarkand":{u:300,c:["UZ"]},"Asia/Seoul":{u:540,c:["KR"]},"Asia/Shanghai":{u:480,c:["CN"]},"Asia/Singapore":{u:480,c:["SG","MY"]},"Asia/Srednekolymsk":{u:660,c:["RU"]},"Asia/Taipei":{u:480,c:["TW"]},"Asia/Tashkent":{u:300,c:["UZ"]},"Asia/Tbilisi":{u:240,c:["GE"]},"Asia/Tehran":{u:210,d:270,c:["IR"]},"Asia/Tel_Aviv":{a:"Asia/Jerusalem",r:1},"Asia/Thimbu":{a:"Asia/Thimphu",r:1},"Asia/Thimphu":{u:360,c:["BT"]},"Asia/Tokyo":{u:540,c:["JP"]},"Asia/Tomsk":{u:420,c:["RU"]},"Asia/Ujung_Pandang":{a:"Asia/Makassar",r:1},"Asia/Ulaanbaatar":{u:480,c:["MN"]},"Asia/Ulan_Bator":{a:"Asia/Ulaanbaatar",r:1},"Asia/Urumqi":{u:360,c:["CN"]},"Asia/Ust-Nera":{u:600,c:["RU"]},"Asia/Vientiane":{a:"Asia/Bangkok",c:["LA"],r:1},"Asia/Vladivostok":{u:600,c:["RU"]},"Asia/Yakutsk":{u:540,c:["RU"]},"Asia/Yangon":{u:390,c:["MM"]},"Asia/Yekaterinburg":{u:300,c:["RU"]},"Asia/Yerevan":{u:240,c:["AM"]},"Atlantic/Azores":{u:-60,d:0,c:["PT"]},"Atlantic/Bermuda":{u:-240,d:-180,c:["BM"]},"Atlantic/Canary":{u:0,d:60,c:["ES"]},"Atlantic/Cape_Verde":{u:-60,c:["CV"]},"Atlantic/Faeroe":{a:"Atlantic/Faroe",r:1},"Atlantic/Faroe":{u:0,d:60,c:["FO"]},"Atlantic/Jan_Mayen":{a:"Europe/Oslo",c:["SJ"],r:1},"Atlantic/Madeira":{u:0,d:60,c:["PT"]},"Atlantic/Reykjavik":{u:0,c:["IS"]},"Atlantic/South_Georgia":{u:-120,c:["GS"]},"Atlantic/St_Helena":{a:"Africa/Abidjan",c:["SH"],r:1},"Atlantic/Stanley":{u:-180,c:["FK"]},"Australia/ACT":{a:"Australia/Sydney",r:1},"Australia/Adelaide":{u:570,d:630,c:["AU"]},"Australia/Brisbane":{u:600,c:["AU"]},"Australia/Broken_Hill":{u:570,d:630,c:["AU"]},"Australia/Canberra":{a:"Australia/Sydney",r:1},"Australia/Currie":{a:"Australia/Hobart",r:1},"Australia/Darwin":{u:570,c:["AU"]},"Australia/Eucla":{u:525,c:["AU"]},"Australia/Hobart":{u:600,d:660,c:["AU"]},"Australia/LHI":{a:"Australia/Lord_Howe",r:1},"Australia/Lindeman":{u:600,c:["AU"]},"Australia/Lord_Howe":{u:630,d:660,c:["AU"]},"Australia/Melbourne":{u:600,d:660,c:["AU"]},"Australia/NSW":{a:"Australia/Sydney",r:1},"Australia/North":{a:"Australia/Darwin",r:1},"Australia/Perth":{u:480,c:["AU"]},"Australia/Queensland":{a:"Australia/Brisbane",r:1},"Australia/South":{a:"Australia/Adelaide",r:1},"Australia/Sydney":{u:600,d:660,c:["AU"]},"Australia/Tasmania":{a:"Australia/Hobart",r:1},"Australia/Victoria":{a:"Australia/Melbourne",r:1},"Australia/West":{a:"Australia/Perth",r:1},"Australia/Yancowinna":{a:"Australia/Broken_Hill",r:1},"Brazil/Acre":{a:"America/Rio_Branco",r:1},"Brazil/DeNoronha":{a:"America/Noronha",r:1},"Brazil/East":{a:"America/Sao_Paulo",r:1},"Brazil/West":{a:"America/Manaus",r:1},CET:{u:60,d:120},CST6CDT:{u:-360,d:-300},"Canada/Atlantic":{a:"America/Halifax",r:1},"Canada/Central":{a:"America/Winnipeg",r:1},"Canada/Eastern":{a:"America/Toronto",c:["CA"],r:1},"Canada/Mountain":{a:"America/Edmonton",r:1},"Canada/Newfoundland":{a:"America/St_Johns",r:1},"Canada/Pacific":{a:"America/Vancouver",r:1},"Canada/Saskatchewan":{a:"America/Regina",r:1},"Canada/Yukon":{a:"America/Whitehorse",r:1},"Chile/Continental":{a:"America/Santiago",r:1},"Chile/EasterIsland":{a:"Pacific/Easter",r:1},Cuba:{a:"America/Havana",r:1},EET:{u:120,d:180},EST:{u:-300},EST5EDT:{u:-300,d:-240},Egypt:{a:"Africa/Cairo",r:1},Eire:{a:"Europe/Dublin",r:1},"Etc/GMT":{u:0},"Etc/GMT+0":{a:"Etc/GMT",r:1},"Etc/GMT+1":{u:-60},"Etc/GMT+10":{u:-600},"Etc/GMT+11":{u:-660},"Etc/GMT+12":{u:-720},"Etc/GMT+2":{u:-120},"Etc/GMT+3":{u:-180},"Etc/GMT+4":{u:-240},"Etc/GMT+5":{u:-300},"Etc/GMT+6":{u:-360},"Etc/GMT+7":{u:-420},"Etc/GMT+8":{u:-480},"Etc/GMT+9":{u:-540},"Etc/GMT-0":{a:"Etc/GMT",r:1},"Etc/GMT-1":{u:60},"Etc/GMT-10":{u:600},"Etc/GMT-11":{u:660},"Etc/GMT-12":{u:720},"Etc/GMT-13":{u:780},"Etc/GMT-14":{u:840},"Etc/GMT-2":{u:120},"Etc/GMT-3":{u:180},"Etc/GMT-4":{u:240},"Etc/GMT-5":{u:300},"Etc/GMT-6":{u:360},"Etc/GMT-7":{u:420},"Etc/GMT-8":{u:480},"Etc/GMT-9":{u:540},"Etc/GMT0":{a:"Etc/GMT",r:1},"Etc/Greenwich":{a:"Etc/GMT",r:1},"Etc/UCT":{a:"Etc/UTC",r:1},"Etc/UTC":{u:0},"Etc/Universal":{a:"Etc/UTC",r:1},"Etc/Zulu":{a:"Etc/UTC",r:1},"Europe/Amsterdam":{u:60,d:120,c:["NL"]},"Europe/Andorra":{u:60,d:120,c:["AD"]},"Europe/Astrakhan":{u:240,c:["RU"]},"Europe/Athens":{u:120,d:180,c:["GR"]},"Europe/Belfast":{a:"Europe/London",c:["GB"],r:1},"Europe/Belgrade":{u:60,d:120,c:["RS","BA","HR","ME","MK","SI"]},"Europe/Berlin":{u:60,d:120,c:["DE"]},"Europe/Bratislava":{a:"Europe/Prague",c:["SK"],r:1},"Europe/Brussels":{u:60,d:120,c:["BE"]},"Europe/Bucharest":{u:120,d:180,c:["RO"]},"Europe/Budapest":{u:60,d:120,c:["HU"]},"Europe/Busingen":{a:"Europe/Zurich",c:["DE"],r:1},"Europe/Chisinau":{u:120,d:180,c:["MD"]},"Europe/Copenhagen":{u:60,d:120,c:["DK"]},"Europe/Dublin":{u:60,d:0,c:["IE"]},"Europe/Gibraltar":{u:60,d:120,c:["GI"]},"Europe/Guernsey":{a:"Europe/London",c:["GG"],r:1},"Europe/Helsinki":{u:120,d:180,c:["FI","AX"]},"Europe/Isle_of_Man":{a:"Europe/London",c:["IM"],r:1},"Europe/Istanbul":{u:180,c:["TR"]},"Europe/Jersey":{a:"Europe/London",c:["JE"],r:1},"Europe/Kaliningrad":{u:120,c:["RU"]},"Europe/Kiev":{u:120,d:180,c:["UA"]},"Europe/Kirov":{u:180,c:["RU"]},"Europe/Lisbon":{u:0,d:60,c:["PT"]},"Europe/Ljubljana":{a:"Europe/Belgrade",c:["SI"],r:1},"Europe/London":{u:0,d:60,c:["GB","GG","IM","JE"]},"Europe/Luxembourg":{u:60,d:120,c:["LU"]},"Europe/Madrid":{u:60,d:120,c:["ES"]},"Europe/Malta":{u:60,d:120,c:["MT"]},"Europe/Mariehamn":{a:"Europe/Helsinki",c:["AX"],r:1},"Europe/Minsk":{u:180,c:["BY"]},"Europe/Monaco":{u:60,d:120,c:["MC"]},"Europe/Moscow":{u:180,c:["RU"]},"Europe/Nicosia":{a:"Asia/Nicosia",r:1},"Europe/Oslo":{u:60,d:120,c:["NO","SJ","BV"]},"Europe/Paris":{u:60,d:120,c:["FR"]},"Europe/Podgorica":{a:"Europe/Belgrade",c:["ME"],r:1},"Europe/Prague":{u:60,d:120,c:["CZ","SK"]},"Europe/Riga":{u:120,d:180,c:["LV"]},"Europe/Rome":{u:60,d:120,c:["IT","SM","VA"]},"Europe/Samara":{u:240,c:["RU"]},"Europe/San_Marino":{a:"Europe/Rome",c:["SM"],r:1},"Europe/Sarajevo":{a:"Europe/Belgrade",c:["BA"],r:1},"Europe/Saratov":{u:240,c:["RU"]},"Europe/Simferopol":{u:180,c:["RU","UA"]},"Europe/Skopje":{a:"Europe/Belgrade",c:["MK"],r:1},"Europe/Sofia":{u:120,d:180,c:["BG"]},"Europe/Stockholm":{u:60,d:120,c:["SE"]},"Europe/Tallinn":{u:120,d:180,c:["EE"]},"Europe/Tirane":{u:60,d:120,c:["AL"]},"Europe/Tiraspol":{a:"Europe/Chisinau",r:1},"Europe/Ulyanovsk":{u:240,c:["RU"]},"Europe/Uzhgorod":{u:120,d:180,c:["UA"]},"Europe/Vaduz":{a:"Europe/Zurich",c:["LI"],r:1},"Europe/Vatican":{a:"Europe/Rome",c:["VA"],r:1},"Europe/Vienna":{u:60,d:120,c:["AT"]},"Europe/Vilnius":{u:120,d:180,c:["LT"]},"Europe/Volgograd":{u:180,c:["RU"]},"Europe/Warsaw":{u:60,d:120,c:["PL"]},"Europe/Zagreb":{a:"Europe/Belgrade",c:["HR"],r:1},"Europe/Zaporozhye":{u:120,d:180,c:["UA"]},"Europe/Zurich":{u:60,d:120,c:["CH","DE","LI"]},Factory:{u:0},GB:{a:"Europe/London",c:["GB"],r:1},"GB-Eire":{a:"Europe/London",c:["GB"],r:1},GMT:{a:"Etc/GMT",r:1},"GMT+0":{a:"Etc/GMT",r:1},"GMT-0":{a:"Etc/GMT",r:1},GMT0:{a:"Etc/GMT",r:1},Greenwich:{a:"Etc/GMT",r:1},HST:{u:-600},Hongkong:{a:"Asia/Hong_Kong",r:1},Iceland:{a:"Atlantic/Reykjavik",r:1},"Indian/Antananarivo":{a:"Africa/Nairobi",c:["MG"],r:1},"Indian/Chagos":{u:360,c:["IO"]},"Indian/Christmas":{u:420,c:["CX"]},"Indian/Cocos":{u:390,c:["CC"]},"Indian/Comoro":{a:"Africa/Nairobi",c:["KM"],r:1},"Indian/Kerguelen":{u:300,c:["TF","HM"]},"Indian/Mahe":{u:240,c:["SC"]},"Indian/Maldives":{u:300,c:["MV"]},"Indian/Mauritius":{u:240,c:["MU"]},"Indian/Mayotte":{a:"Africa/Nairobi",c:["YT"],r:1},"Indian/Reunion":{u:240,c:["RE","TF"]},Iran:{a:"Asia/Tehran",r:1},Israel:{a:"Asia/Jerusalem",r:1},Jamaica:{a:"America/Jamaica",r:1},Japan:{a:"Asia/Tokyo",r:1},Kwajalein:{a:"Pacific/Kwajalein",r:1},Libya:{a:"Africa/Tripoli",r:1},MET:{u:60,d:120},MST:{u:-420},MST7MDT:{u:-420,d:-360},"Mexico/BajaNorte":{a:"America/Tijuana",r:1},"Mexico/BajaSur":{a:"America/Mazatlan",r:1},"Mexico/General":{a:"America/Mexico_City",r:1},NZ:{a:"Pacific/Auckland",c:["NZ"],r:1},"NZ-CHAT":{a:"Pacific/Chatham",r:1},Navajo:{a:"America/Denver",r:1},PRC:{a:"Asia/Shanghai",r:1},PST8PDT:{u:-480,d:-420},"Pacific/Apia":{u:780,c:["WS"]},"Pacific/Auckland":{u:720,d:780,c:["NZ","AQ"]},"Pacific/Bougainville":{u:660,c:["PG"]},"Pacific/Chatham":{u:765,d:825,c:["NZ"]},"Pacific/Chuuk":{u:600,c:["FM"]},"Pacific/Easter":{u:-360,d:-300,c:["CL"]},"Pacific/Efate":{u:660,c:["VU"]},"Pacific/Enderbury":{a:"Pacific/Kanton",r:1},"Pacific/Fakaofo":{u:780,c:["TK"]},"Pacific/Fiji":{u:720,d:780,c:["FJ"]},"Pacific/Funafuti":{u:720,c:["TV"]},"Pacific/Galapagos":{u:-360,c:["EC"]},"Pacific/Gambier":{u:-540,c:["PF"]},"Pacific/Guadalcanal":{u:660,c:["SB"]},"Pacific/Guam":{u:600,c:["GU","MP"]},"Pacific/Honolulu":{u:-600,c:["US","UM"]},"Pacific/Johnston":{a:"Pacific/Honolulu",c:["UM"],r:1},"Pacific/Kanton":{u:780,c:["KI"]},"Pacific/Kiritimati":{u:840,c:["KI"]},"Pacific/Kosrae":{u:660,c:["FM"]},"Pacific/Kwajalein":{u:720,c:["MH"]},"Pacific/Majuro":{u:720,c:["MH"]},"Pacific/Marquesas":{u:-510,c:["PF"]},"Pacific/Midway":{a:"Pacific/Pago_Pago",c:["UM"],r:1},"Pacific/Nauru":{u:720,c:["NR"]},"Pacific/Niue":{u:-660,c:["NU"]},"Pacific/Norfolk":{u:660,d:720,c:["NF"]},"Pacific/Noumea":{u:660,c:["NC"]},"Pacific/Pago_Pago":{u:-660,c:["AS","UM"]},"Pacific/Palau":{u:540,c:["PW"]},"Pacific/Pitcairn":{u:-480,c:["PN"]},"Pacific/Pohnpei":{u:660,c:["FM"]},"Pacific/Ponape":{a:"Pacific/Pohnpei",r:1},"Pacific/Port_Moresby":{u:600,c:["PG","AQ"]},"Pacific/Rarotonga":{u:-600,c:["CK"]},"Pacific/Saipan":{a:"Pacific/Guam",c:["MP"],r:1},"Pacific/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},"Pacific/Tahiti":{u:-600,c:["PF"]},"Pacific/Tarawa":{u:720,c:["KI"]},"Pacific/Tongatapu":{u:780,c:["TO"]},"Pacific/Truk":{a:"Pacific/Chuuk",r:1},"Pacific/Wake":{u:720,c:["UM"]},"Pacific/Wallis":{u:720,c:["WF"]},"Pacific/Yap":{a:"Pacific/Chuuk",r:1},Poland:{a:"Europe/Warsaw",r:1},Portugal:{a:"Europe/Lisbon",r:1},ROC:{a:"Asia/Taipei",r:1},ROK:{a:"Asia/Seoul",r:1},Singapore:{a:"Asia/Singapore",c:["SG"],r:1},Turkey:{a:"Europe/Istanbul",r:1},UCT:{a:"Etc/UTC",r:1},"US/Alaska":{a:"America/Anchorage",r:1},"US/Aleutian":{a:"America/Adak",r:1},"US/Arizona":{a:"America/Phoenix",c:["US"],r:1},"US/Central":{a:"America/Chicago",r:1},"US/East-Indiana":{a:"America/Indiana/Indianapolis",r:1},"US/Eastern":{a:"America/New_York",r:1},"US/Hawaii":{a:"Pacific/Honolulu",c:["US"],r:1},"US/Indiana-Starke":{a:"America/Indiana/Knox",r:1},"US/Michigan":{a:"America/Detroit",r:1},"US/Mountain":{a:"America/Denver",r:1},"US/Pacific":{a:"America/Los_Angeles",r:1},"US/Samoa":{a:"Pacific/Pago_Pago",c:["WS"],r:1},UTC:{a:"Etc/UTC",r:1},Universal:{a:"Etc/UTC",r:1},"W-SU":{a:"Europe/Moscow",r:1},WET:{u:0,d:60},Zulu:{a:"Etc/UTC",r:1}};function W(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return null;try{let e=Q[s]?.c?.[0];return e&&pe[e]||null}catch{return null}}function P(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return"Unknown";try{return Q[s]?.c?.[0]||"Unknown"}catch{return"Unknown"}}function Y(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;return s===""||!s?null:s.split("/")[1]?.replace("_"," ")||null}var M=class{constructor(e,t){this.isDestroyed=!1;this.currentPath=null;this.originalPushState=null;this.originalReplaceState=null;this.previousPage=null;this.landingPage=null;this.pageViewCount=0;this.handlePopState=()=>{this.isDestroyed||this.trackCurrentPage()};this.handleHashChange=()=>{this.isDestroyed||this.trackCurrentPage()};this.tracker=e,this.config=t,this.trackCurrentPage(!0),this.setupHistoryListeners(),this.setupHashChangeListener()}setupHistoryListeners(){typeof window>"u"||typeof history>"u"||(this.originalPushState=history.pushState,history.pushState=(e,t,i)=>{this.originalPushState?.call(history,e,t,i),this.trackCurrentPage()},this.originalReplaceState=history.replaceState,history.replaceState=(e,t,i)=>{this.originalReplaceState?.call(history,e,t,i),this.trackCurrentPage()},window.addEventListener("popstate",this.handlePopState))}setupHashChangeListener(){typeof window>"u"||window.addEventListener("hashchange",this.handleHashChange)}trackCurrentPage(e=!1){if(this.isDestroyed||typeof window>"u")return;let t=this.extractPath(window.location.href);if(!e&&t===this.currentPath)return;this.currentPath&&(this.previousPage=this.currentPath),this.currentPath=t,this.pageViewCount++,e&&(this.landingPage=t);let i=this.tracker.hasConsent("analytics"),r=window.location.href,n=document.referrer||"",a=A(r);Object.keys(a).length>0&&(!p()||e)&&V(a);let o=p()||{},c=C(this.config.tenantId,n,r,o),l={page:t,timestamp:Date.now()};if(i){l.title=document.title||"",l.full_url=r,l.session_id=this.tracker.getSessionId(),n&&(l.referrer=n,l.referrer_domain=this.extractDomain(n),l.referrer_category=m(n,r)),this.landingPage&&!e&&(l.landing_page=this.landingPage),this.previousPage&&(l.previous_page=this.previousPage),o.utm_source&&(l.utm_source=o.utm_source),o.utm_medium&&(l.utm_medium=o.utm_medium),o.utm_campaign&&(l.utm_campaign=o.utm_campaign),o.utm_term&&(l.utm_term=o.utm_term),o.utm_content&&(l.utm_content=o.utm_content),l.first_touch_source=c.source,l.first_touch_medium=c.medium,l.first_touch_campaign=c.campaign,l.first_touch_referrer_category=c.referrer_category,l.device=this.getDeviceType(),l.browser=this.getBrowser(),l.os=this.getOS(),l.language=navigator.language||"";let u=Intl.DateTimeFormat().resolvedOptions().timeZone;l.timezone=u,l.country=P(),l.screen_resolution=`${screen.width}x${screen.height}`,l.viewport=`${window.innerWidth}x${window.innerHeight}`}this.tracker.trackSystemEvent("page_view",l)}extractDomain(e){try{return new URL(e).hostname}catch{return""}}getBrowser(){let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}extractPath(e){try{let t=new URL(e),i=t.pathname+t.hash;return!this.config.stripQueryParams&&t.search&&(i+=t.search),i}catch(t){return this.config.debug&&console.warn("[Page Tracking] Failed to parse URL:",e,t),e}}getCurrentPage(){return this.currentPath}trackPage(e,t){if(this.isDestroyed)return;let i=this.tracker.hasConsent("analytics"),r={page:e,timestamp:Date.now(),...t};i&&typeof document<"u"&&typeof window<"u"&&(r.referrer||(r.referrer=document.referrer||""),r.title||(r.title=document.title||""),r.full_url||(r.full_url=window.location.href),r.session_id||(r.session_id=this.tracker.getSessionId()),r.browser||(r.browser=this.getBrowser()),r.os||(r.os=this.getOS())),this.tracker.trackSystemEvent("page_view",r)}getPageViewCount(){return this.pageViewCount}destroy(){this.isDestroyed||(typeof history<"u"&&(this.originalPushState&&(history.pushState=this.originalPushState),this.originalReplaceState&&(history.replaceState=this.originalReplaceState)),typeof window<"u"&&(window.removeEventListener("popstate",this.handlePopState),window.removeEventListener("hashchange",this.handleHashChange)),this.isDestroyed=!0)}};var v=class{constructor(e){this.eventQueue=[];this.waitingForConsentQueue=[];this.flushTimer=null;this.isDestroyed=!1;this.globalUserId=null;this.persistentAnonymousUserId=null;this.configCache=null;this.configRefreshTimer=null;this.configChangeListeners=[];this.configFetchPromise=null;this.cookiesEnabled=!1;this.activityDetector=null;this.heartbeatManager=null;this.pageTrackingManager=null;this.ephemeralSessionId=null;this.eventCountSinceLastHeartbeat=0;this.interactionTrackingManager=null;this.sectionTrackingManager=null;this.heatmapTrackingManager=null;this.sessionStartTime=Date.now();this.sessionEventCount=0;this.debugAgent=null;this.isDebugMode=!1;this.config={apiUrl:"https://api.grainql.com",authStrategy:"NONE",batchSize:50,flushInterval:5e3,retryAttempts:3,retryDelay:1e3,maxEventsPerRequest:160,debug:!1,defaultConfigurations:{},configCacheKey:"grain_config",configRefreshInterval:3e5,enableConfigCache:!0,consentMode:"opt-out",waitForConsent:!1,enableCookies:!1,anonymizeIP:!1,disableAutoProperties:!1,enableHeartbeat:!0,heartbeatActiveInterval:12e4,heartbeatInactiveInterval:3e5,enableAutoPageView:!0,stripQueryParams:!0,enableHeatmapTracking:!0,...e,tenantId:e.tenantId},this.consentManager=new T(this.config.tenantId,this.config.consentMode),this.config.enableCookies&&(this.cookiesEnabled=$(),!this.cookiesEnabled&&this.config.debug&&console.warn("[Grain Analytics] Cookies are not available, falling back to localStorage")),e.userId&&(this.globalUserId=e.userId),this.validateConfig(),this.initializePersistentAnonymousUserId(),this.setupBeforeUnload(),this.startFlushTimer(),this.initializeConfigCache(),this.ephemeralSessionId=this.generateUUID(),typeof window<"u"&&(this.checkAndInitializeDebugMode(),this.initializeAutomaticTracking(),this.trackSessionStart(),this.config.enableHeatmapTracking&&this.initializeHeatmapTracking()),this.consentManager.addListener(t=>{t.granted&&this.handleConsentGranted()})}validateConfig(){if(!this.config.tenantId)throw new Error("Grain Analytics: tenantId is required");if(this.config.authStrategy==="SERVER_SIDE"&&!this.config.secretKey)throw new Error("Grain Analytics: secretKey is required for SERVER_SIDE auth strategy");if(this.config.authStrategy==="JWT"&&!this.config.authProvider)throw new Error("Grain Analytics: authProvider is required for JWT auth strategy")}generateUUID(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,function(e){let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}shouldAllowPersistentStorage(){let e=this.consentManager.hasConsent("analytics"),t=this.config.consentMode==="opt-in",i=!!this.globalUserId,r=this.config.authStrategy==="JWT";return e||!t||i||r}generateAnonymousUserId(){return this.generateUUID()}initializePersistentAnonymousUserId(){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID initialization (GDPR compliance)");return}let e=`grain_anonymous_user_id_${this.config.tenantId}`,t="_grain_uid";try{if(this.cookiesEnabled){let r=D(t);if(r){this.persistentAnonymousUserId=r,this.log("Loaded persistent anonymous user ID from cookie:",this.persistentAnonymousUserId);return}}let i=localStorage.getItem(e);i?(this.persistentAnonymousUserId=i,this.log("Loaded persistent anonymous user ID from localStorage:",this.persistentAnonymousUserId),this.cookiesEnabled&&this.savePersistentAnonymousUserId(i)):(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.log("Generated new persistent anonymous user ID:",this.persistentAnonymousUserId))}catch(i){this.log("Failed to initialize persistent anonymous user ID:",i),this.persistentAnonymousUserId=this.generateAnonymousUserId()}}savePersistentAnonymousUserId(e){if(typeof window>"u")return;if(!this.shouldAllowPersistentStorage()){this.log("Opt-in mode without consent: skipping persistent ID save (GDPR compliance)");return}let t=`grain_anonymous_user_id_${this.config.tenantId}`,i="_grain_uid";try{if(this.cookiesEnabled){let r={maxAge:31536e3,sameSite:"lax",secure:typeof window<"u"&&window.location.protocol==="https:",...this.config.cookieOptions};_(i,e,r)}localStorage.setItem(t,e)}catch(r){this.log("Failed to save persistent anonymous user ID:",r)}}getEffectiveUserIdInternal(){return this.globalUserId?this.globalUserId:this.persistentAnonymousUserId?this.persistentAnonymousUserId:(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId),this.persistentAnonymousUserId)}log(...e){this.config.debug&&console.log("[Grain Analytics]",...e)}createErrorDigest(e){let t=[...new Set(e.map(a=>a.eventName))],i=[...new Set(e.map(a=>a.userId))],r=0,n=0;return e.forEach(a=>{let o=a.properties||{};r+=Object.keys(o).length,n+=JSON.stringify(a).length}),{eventCount:e.length,totalProperties:r,totalSize:n,eventNames:t,userIds:i}}formatError(e,t,i){let r=i?this.createErrorDigest(i):{eventCount:0,totalProperties:0,totalSize:0,eventNames:[],userIds:[]},n="UNKNOWN_ERROR",a="An unknown error occurred";if(e instanceof Error)a=e.message,a.includes("fetch failed")||a.includes("network error")?n="NETWORK_ERROR":a.includes("timeout")?n="TIMEOUT_ERROR":a.includes("HTTP 4")?n="CLIENT_ERROR":a.includes("HTTP 5")?n="SERVER_ERROR":a.includes("JSON")?n="PARSE_ERROR":a.includes("auth")||a.includes("unauthorized")?n="AUTH_ERROR":a.includes("rate limit")||a.includes("429")?n="RATE_LIMIT_ERROR":n="GENERAL_ERROR";else if(typeof e=="string")a=e,n="STRING_ERROR";else if(e&&typeof e=="object"&&"status"in e){let o=e.status;n=`HTTP_${o}`,a=`HTTP ${o} error`}return{code:n,message:a,digest:r,timestamp:new Date().toISOString(),context:t,originalError:e}}logError(e){if(!this.config.debug)return;let{code:t,message:i,digest:r,timestamp:n,context:a}=e,o={"\u{1F6A8} Grain Analytics Error":{"Error Code":t,Message:i,Context:a,Timestamp:n,"Event Digest":{Events:r.eventCount,Properties:r.totalProperties,"Size (bytes)":r.totalSize,"Event Names":r.eventNames.length>0?r.eventNames.join(", "):"None","User IDs":r.userIds.length>0?r.userIds.slice(0,3).join(", ")+(r.userIds.length>3?"...":""):"None"}}};console.error("\u{1F6A8} Grain Analytics Error:",o),console.error(`[Grain Analytics] ${t}: ${i} (${a}) - Events: ${r.eventCount}, Props: ${r.totalProperties}, Size: ${r.totalSize}B`)}async safeExecute(e,t,i){try{return await e()}catch(r){let n=this.formatError(r,t,i);return this.logError(n),null}}formatEvent(e){let t=e.properties||{};if(!this.config.disableAutoProperties&&typeof window<"u"){let i=this.consentManager.hasConsent("analytics");if(!e.eventName.startsWith("_grain_")&&i){let n=p();n&&(n.utm_source&&(t.utm_source=n.utm_source),n.utm_medium&&(t.utm_medium=n.utm_medium),n.utm_campaign&&(t.utm_campaign=n.utm_campaign),n.utm_term&&(t.utm_term=n.utm_term),n.utm_content&&(t.utm_content=n.utm_content));let a=L(this.config.tenantId);a&&(t.first_touch_source=a.source,t.first_touch_medium=a.medium,t.first_touch_campaign=a.campaign,t.first_touch_referrer_category=a.referrer_category),t.session_id||(t.session_id=this.getSessionId())}}return{eventName:e.eventName,userId:e.userId||this.getEffectiveUserIdInternal(),properties:t}}async getAuthHeaders(){let e={"Content-Type":"application/json"};switch(this.config.authStrategy){case"NONE":break;case"SERVER_SIDE":e.Authorization=`Chase ${this.config.secretKey}`;break;case"JWT":if(this.config.authProvider){let t=await this.config.authProvider.getToken();e.Authorization=`Bearer ${t}`}break}return e}async delay(e){return new Promise(t=>setTimeout(t,e))}isRetriableError(e){if(e instanceof Error){let t=e.message.toLowerCase();if(t.includes("fetch failed")||t==="network error"||t.includes("timeout")||t.includes("connection"))return!0}if(typeof e=="object"&&e!==null&&"status"in e){let t=e.status;return t>=500||t===429}return!1}async sendEvents(e){if(e.length===0)return;let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),n=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(e)});if(!a.ok){let o=`HTTP ${a.status}`;try{let l=await a.json();l?.message&&(o=l.message)}catch{let l=await a.text();l&&(o=l)}let c=new Error(`Failed to send events: ${o}`);throw c.status=a.status,c}this.log(`Successfully sent ${e.length} events`);return}catch(r){if(t=r,i===this.config.retryAttempts){let a=this.formatError(r,`sendEvents (attempt ${i+1}/${this.config.retryAttempts+1})`,e);this.logError(a);return}if(!this.isRetriableError(r)){let a=this.formatError(r,"sendEvents (non-retriable error)",e);this.logError(a);return}let n=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${n}ms after error:`,r),await this.delay(n)}}async sendEventsWithBeacon(e){if(e.length!==0)try{let t=await this.getAuthHeaders(),i=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/multi`,r=JSON.stringify(e);if(!(this.config.authStrategy!=="NONE")&&typeof navigator<"u"&&"sendBeacon"in navigator){let a=new Blob([r],{type:"application/json"});if(navigator.sendBeacon(i,a)){this.log(`Successfully sent ${e.length} events via beacon`);return}}await fetch(i,{method:"POST",headers:t,body:r,keepalive:!0})}catch(t){let i=this.formatError(t,"sendEventsWithBeacon",e);this.logError(i)}}startFlushTimer(){typeof window>"u"||(this.flushTimer&&clearInterval(this.flushTimer),this.flushTimer=window.setInterval(()=>{this.eventQueue.length>0&&this.flush().catch(e=>{let t=this.formatError(e,"auto-flush");this.logError(t)})},this.config.flushInterval))}setupBeforeUnload(){if(typeof window>"u")return;let e=()=>{if(this.trackSessionEnd(),this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}};window.addEventListener("beforeunload",e),window.addEventListener("pagehide",e),document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="hidden"&&this.eventQueue.length>0){let t=[...this.eventQueue];this.eventQueue=[];let i=this.chunkEvents(t,this.config.maxEventsPerRequest);i.length>0&&this.sendEventsWithBeacon(i[0]).catch(()=>{})}})}initializeAutomaticTracking(){if(this.config.enableHeartbeat)try{this.activityDetector=new k,this.heartbeatManager=new w(this,this.activityDetector,{activeInterval:this.config.heartbeatActiveInterval,inactiveInterval:this.config.heartbeatInactiveInterval,debug:this.config.debug})}catch(e){this.log("Failed to initialize heartbeat tracking:",e)}if(this.config.enableAutoPageView)try{this.pageTrackingManager=new M(this,{stripQueryParams:this.config.stripQueryParams,debug:this.config.debug,tenantId:this.config.tenantId})}catch(e){this.log("Failed to initialize page view tracking:",e)}this.initializeAutoTracking()}initializeHeatmapTracking(){if(!(typeof window>"u"))try{this.log("Initializing heatmap tracking"),Promise.resolve().then(()=>(J(),j)).then(({HeatmapTrackingManager:e})=>{try{this.heatmapTrackingManager=new e(this,{scrollDebounceDelay:100,batchDelay:2e3,maxBatchSize:20,debug:this.config.debug}),this.log("Heatmap tracking initialized")}catch(t){this.log("Failed to initialize heatmap tracking:",t)}}).catch(e=>{this.log("Failed to load heatmap tracking module:",e)})}catch(e){this.log("Failed to initialize heatmap tracking:",e)}}async initializeAutoTracking(){try{this.log("Initializing auto-tracking");let e=this.globalUserId||this.persistentAnonymousUserId||this.generateUUID(),t=typeof window<"u"?window.location.href:"",i={userId:e,immediateKeys:[],properties:{},currentUrl:t},r=await this.getAuthHeaders(),n=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(i)});if(!a.ok){this.log("Failed to fetch auto-tracking config:",a.status);return}let o=await a.json();o.autoTrackingConfig&&(this.log("Auto-tracking config loaded"),this.setupAutoTrackingManagers(o.autoTrackingConfig))}catch(e){this.log("Failed to initialize auto-tracking:",e)}}setupAutoTrackingManagers(e){this.log("Setting up auto-tracking managers"),e.interactions&&e.interactions.length>0&&(this.log("Loading interaction tracking:",e.interactions.length,"interactions"),Promise.resolve().then(()=>(X(),q)).then(({InteractionTrackingManager:t})=>{try{this.interactionTrackingManager=new t(this,e.interactions,{debug:this.config.debug,enableMutationObserver:!0,mutationDebounceDelay:500,tenantId:this.config.tenantId,apiUrl:this.config.apiUrl}),this.log("Interaction tracking initialized")}catch(i){this.log("Failed to initialize interaction tracking:",i)}}).catch(t=>{this.log("Failed to load interaction tracking module:",t)})),e.sections&&e.sections.length>0&&(this.log("Loading section tracking:",e.sections.length,"sections"),Promise.resolve().then(()=>(ee(),Z)).then(({SectionTrackingManager:t})=>{try{this.sectionTrackingManager=new t(this,e.sections,{minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:this.config.debug}),this.log("Section tracking initialized")}catch(i){this.log("Failed to initialize section tracking:",i)}}).catch(t=>{this.log("Failed to load section tracking module:",t)}))}trackSessionStart(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t={session_id:this.getSessionId(),timestamp:this.sessionStartTime};if(e){let i=document.referrer||"",r=window.location.href,n=A(r),a=p()||n,o=C(this.config.tenantId,i,r,a);t.landing_page=window.location.pathname,i?(t.referrer=i,t.referrer_domain=new URL(i).hostname,t.referrer_category=m(i,r)):t.referrer_category="direct",a.utm_source&&(t.utm_source=a.utm_source),a.utm_medium&&(t.utm_medium=a.utm_medium),a.utm_campaign&&(t.utm_campaign=a.utm_campaign),a.utm_term&&(t.utm_term=a.utm_term),a.utm_content&&(t.utm_content=a.utm_content),t.first_touch_source=o.source,t.first_touch_medium=o.medium,t.first_touch_campaign=o.campaign,t.first_touch_referrer_category=o.referrer_category,t.device=this.getDeviceType(),t.screen_resolution=`${screen.width}x${screen.height}`,t.viewport=`${window.innerWidth}x${window.innerHeight}`,t.browser=this.getBrowser(),t.os=this.getOS(),t.language=navigator.language||"",t.timezone=Intl.DateTimeFormat().resolvedOptions().timeZone}this.trackSystemEvent("_grain_session_start",t),this.log("Session started")}trackSessionEnd(){if(typeof window>"u")return;let e=this.consentManager.hasConsent("analytics"),t=Date.now()-this.sessionStartTime,i={session_id:this.getSessionId(),session_duration:Math.floor(t/1e3),duration:t,event_count:this.sessionEventCount,timestamp:Date.now()};if(e&&this.pageTrackingManager){let r=this.pageTrackingManager.getPageViewCount();i.pages_per_session=r,i.page_count=r}this.trackSystemEvent("_grain_session_end",i),this.log("Session ended")}getBrowser(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Firefox/")?"Firefox":e.includes("Edg/")?"Edge":e.includes("Chrome/")?"Chrome":e.includes("Safari/")&&!e.includes("Chrome/")?"Safari":e.includes("Opera/")||e.includes("OPR/")?"Opera":"Unknown"}getOS(){if(typeof navigator>"u")return"Unknown";let e=navigator.userAgent;return e.includes("Win")?"Windows":e.includes("Mac")?"macOS":e.includes("Linux")?"Linux":e.includes("Android")?"Android":e.includes("iOS")||e.includes("iPhone")||e.includes("iPad")?"iOS":"Unknown"}getDeviceType(){if(typeof window>"u"||typeof navigator>"u")return"Unknown";let e=navigator.userAgent,t=window.innerWidth;return e.includes("iPad")||e.includes("Android")&&!e.includes("Mobile")?"Tablet":e.includes("Mobile")||e.includes("iPhone")||e.includes("Android")||t<768?"Mobile":t>=768&&t<1024?"Tablet":"Desktop"}handleConsentGranted(){this.flushWaitingForConsentQueue(),this.persistentAnonymousUserId||(this.initializePersistentAnonymousUserId(),this.log("Initialized persistent ID after consent grant")),this.ephemeralSessionId&&this.trackSystemEvent("_grain_consent_granted",{previous_session_id:this.ephemeralSessionId,new_user_id:this.getEffectiveUserId(),timestamp:Date.now()})}trackSystemEvent(e,t){if(this.isDestroyed)return;let i=this.consentManager.hasConsent("analytics"),r={eventName:e,userId:i?this.getEffectiveUserId():this.getEphemeralSessionId(),properties:{...t,_minimal:!i,_consent_status:i?"granted":"pending"}};this.eventQueue.push(r),this.eventCountSinceLastHeartbeat++,this.log(`Queued system event: ${e}`),this.eventQueue.length>=this.config.batchSize&&this.flush().catch(n=>{let a=this.formatError(n,"flush system event");this.logError(a)})}getEphemeralSessionId(){return this.ephemeralSessionId||(this.ephemeralSessionId=this.generateUUID()),this.ephemeralSessionId}getCurrentPage(){return this.pageTrackingManager?.getCurrentPage()||null}getEventCountSinceLastHeartbeat(){return this.eventCountSinceLastHeartbeat}resetEventCountSinceLastHeartbeat(){this.eventCountSinceLastHeartbeat=0}getActivityDetector(){if(!this.activityDetector)throw new Error("Activity detector not initialized");return this.activityDetector}getEffectiveUserId(){return this.getEffectiveUserIdInternal()}getSessionId(){return this.consentManager.hasConsent("analytics")?this.getEffectiveUserId():this.getEphemeralSessionId()}async track(e,t,i){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"track (client destroyed)");this.logError(c);return}let r,n={};if(typeof e=="string"?(r={eventName:e,properties:t},n=i||{}):(r=e,n=t||{}),this.config.allowedProperties&&r.properties){let o={};for(let c of this.config.allowedProperties)c in r.properties&&(o[c]=r.properties[c]);r.properties=o}let a=this.formatEvent(r);if(this.consentManager.shouldWaitForConsent()&&this.config.waitForConsent){this.waitingForConsentQueue.push(a),this.log(`Event waiting for consent: ${r.eventName}`,r.properties);return}if(!this.consentManager.hasConsent("analytics")){this.log(`Event blocked by consent: ${r.eventName}`);return}this.eventQueue.push(a),this.eventCountSinceLastHeartbeat++,this.sessionEventCount++,this.log(`Queued event: ${r.eventName}`),(n.flush||this.eventQueue.length>=this.config.batchSize)&&await this.flush()}catch(r){let n=this.formatError(r,"track");this.logError(n)}}flushWaitingForConsentQueue(){this.waitingForConsentQueue.length!==0&&(this.log(`Flushing ${this.waitingForConsentQueue.length} events waiting for consent`),this.eventQueue.push(...this.waitingForConsentQueue),this.waitingForConsentQueue=[],this.flush().catch(e=>{let t=this.formatError(e,"flush waiting for consent queue");this.logError(t)}))}identify(e){this.log(`Identified user: ${e}`),this.globalUserId=e,this.persistentAnonymousUserId=null}setUserId(e){this.log(`Set global user ID: ${e}`),this.globalUserId=e,e?this.persistentAnonymousUserId=null:this.persistentAnonymousUserId||(this.persistentAnonymousUserId=this.generateAnonymousUserId(),this.savePersistentAnonymousUserId(this.persistentAnonymousUserId))}getUserId(){return this.globalUserId}getEffectiveUserIdPublic(){return this.getEffectiveUserIdInternal()}login(e){try{if(this.isDestroyed){let t=new Error("Grain Analytics: Client has been destroyed"),i=this.formatError(t,"login (client destroyed)");this.logError(i);return}e.userId&&(this.log(`Login: Setting user ID to ${e.userId}`),this.globalUserId=e.userId,this.persistentAnonymousUserId=null),e.authToken&&(this.log("Login: Setting auth token"),this.config.authStrategy==="NONE"&&(this.config.authStrategy="JWT"),this.config.authProvider={getToken:()=>e.authToken}),e.authStrategy&&(this.log(`Login: Setting auth strategy to ${e.authStrategy}`),this.config.authStrategy=e.authStrategy),this.log(`Login successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(t){let i=this.formatError(t,"login");this.logError(i)}}logout(){try{if(this.isDestroyed){let e=new Error("Grain Analytics: Client has been destroyed"),t=this.formatError(e,"logout (client destroyed)");this.logError(t);return}if(this.log("Logout: Clearing user session"),this.globalUserId=null,this.config.authStrategy="NONE",this.config.authProvider=void 0,!this.persistentAnonymousUserId&&(this.persistentAnonymousUserId=this.generateAnonymousUserId(),typeof window<"u"))try{let e=`grain_anonymous_user_id_${this.config.tenantId}`;localStorage.setItem(e,this.persistentAnonymousUserId)}catch(e){this.log("Failed to persist new anonymous user ID after logout:",e)}this.log(`Logout successful. Effective user ID: ${this.getEffectiveUserIdInternal()}`)}catch(e){let t=this.formatError(e,"logout");this.logError(t)}}async setProperty(e,t){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"setProperty (client destroyed)");this.logError(c);return}let i=t?.userId||this.getEffectiveUserIdInternal(),r=Object.keys(e);if(r.length>4){let o=new Error("Grain Analytics: Maximum 4 properties allowed per request"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}if(r.length===0){let o=new Error("Grain Analytics: At least one property is required"),c=this.formatError(o,"setProperty (validation)");this.logError(c);return}let n={};for(let[o,c]of Object.entries(e))c==null?n[o]="":typeof c=="string"?n[o]=c:n[o]=JSON.stringify(c);let a={userId:i,...n};await this.sendProperties(a)}catch(i){let r=this.formatError(i,"setProperty");this.logError(r)}}async sendProperties(e){let t;for(let i=0;i<=this.config.retryAttempts;i++)try{let r=await this.getAuthHeaders(),n=`${this.config.apiUrl}/v1/events/${encodeURIComponent(this.config.tenantId)}/properties`,a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(e)});if(!a.ok){let o=`HTTP ${a.status}`;try{let l=await a.json();l?.message&&(o=l.message)}catch{let l=await a.text();l&&(o=l)}let c=new Error(`Failed to set properties: ${o}`);throw c.status=a.status,c}this.log(`Successfully set properties for user ${e.userId}`);return}catch(r){if(t=r,i===this.config.retryAttempts){let a=this.formatError(r,`sendProperties (attempt ${i+1}/${this.config.retryAttempts+1})`);this.logError(a);return}if(!this.isRetriableError(r)){let a=this.formatError(r,"sendProperties (non-retriable error)");this.logError(a);return}let n=this.config.retryDelay*Math.pow(2,i);this.log(`Retrying in ${n}ms after error:`,r),await this.delay(n)}}async trackLogin(e,t){try{return await this.track("login",e,t)}catch(i){let r=this.formatError(i,"trackLogin");this.logError(r)}}async trackSignup(e,t){try{return await this.track("signup",e,t)}catch(i){let r=this.formatError(i,"trackSignup");this.logError(r)}}async trackCheckout(e,t){try{return await this.track("checkout",e,t)}catch(i){let r=this.formatError(i,"trackCheckout");this.logError(r)}}async trackPageView(e,t){try{return await this.track("page_view",e,t)}catch(i){let r=this.formatError(i,"trackPageView");this.logError(r)}}async trackPurchase(e,t){try{return await this.track("purchase",e,t)}catch(i){let r=this.formatError(i,"trackPurchase");this.logError(r)}}async trackSearch(e,t){try{return await this.track("search",e,t)}catch(i){let r=this.formatError(i,"trackSearch");this.logError(r)}}async trackAddToCart(e,t){try{return await this.track("add_to_cart",e,t)}catch(i){let r=this.formatError(i,"trackAddToCart");this.logError(r)}}async trackRemoveFromCart(e,t){try{return await this.track("remove_from_cart",e,t)}catch(i){let r=this.formatError(i,"trackRemoveFromCart");this.logError(r)}}async flush(){try{if(this.eventQueue.length===0)return;let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);for(let i of t)await this.sendEvents(i)}catch(e){let t=this.formatError(e,"flush");this.logError(t)}}initializeConfigCache(){if(!(!this.config.enableConfigCache||typeof window>"u"))try{let e=localStorage.getItem(this.config.configCacheKey);e&&(this.configCache=JSON.parse(e),this.log("Loaded configuration from cache:",this.configCache))}catch(e){this.log("Failed to load configuration cache:",e)}}saveConfigCache(e){if(!(!this.config.enableConfigCache||typeof window>"u"))try{localStorage.setItem(this.config.configCacheKey,JSON.stringify(e)),this.log("Saved configuration to cache:",e)}catch(t){this.log("Failed to save configuration cache:",t)}}getConfig(e){if(this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e]}getAllConfigs(){let e={...this.config.defaultConfigurations};return this.configCache?.configurations&&Object.assign(e,this.configCache.configurations),e}async fetchConfig(e={}){try{if(this.isDestroyed){let o=new Error("Grain Analytics: Client has been destroyed"),c=this.formatError(o,"fetchConfig (client destroyed)");return this.logError(c),null}let t=e.userId||this.getEffectiveUserIdInternal(),i=e.immediateKeys||[],r=e.properties||{},n={userId:t,immediateKeys:i,properties:r},a;for(let o=0;o<=this.config.retryAttempts;o++)try{let c=await this.getAuthHeaders(),l=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`,u=await fetch(l,{method:"POST",headers:c,body:JSON.stringify(n)});if(!u.ok){let h=`HTTP ${u.status}`;try{let y=await u.json();y?.message&&(h=y.message)}catch{let y=await u.text();y&&(h=y)}let S=new Error(`Failed to fetch configurations: ${h}`);throw S.status=u.status,S}let d=await u.json();return d.configurations&&this.updateConfigCache(d,t),this.log("Successfully fetched configurations"),d}catch(c){if(a=c,o===this.config.retryAttempts){let u=this.formatError(c,`fetchConfig (attempt ${o+1}/${this.config.retryAttempts+1})`);return this.logError(u),null}if(!this.isRetriableError(c)){let u=this.formatError(c,"fetchConfig (non-retriable error)");return this.logError(u),null}let l=this.config.retryDelay*Math.pow(2,o);this.log(`Retrying config fetch in ${l}ms after error:`,c),await this.delay(l)}return null}catch(t){let i=this.formatError(t,"fetchConfig");return this.logError(i),null}}async getConfigAsync(e,t={}){try{if(!t.forceRefresh&&this.configCache?.configurations?.[e])return this.configCache.configurations[e];if(!t.forceRefresh&&this.config.defaultConfigurations?.[e])return this.config.defaultConfigurations[e];let i=await this.fetchConfig(t);return i?i.configurations[e]:this.config.defaultConfigurations?.[e]}catch(i){let r=this.formatError(i,"getConfigAsync");return this.logError(r),this.config.defaultConfigurations?.[e]}}async getAllConfigsAsync(e={}){try{if(!e.forceRefresh&&this.configCache?.configurations)return{...this.config.defaultConfigurations,...this.configCache.configurations};let t=await this.fetchConfig(e);return t?{...this.config.defaultConfigurations,...t.configurations}:{...this.config.defaultConfigurations}}catch(t){let i=this.formatError(t,"getAllConfigsAsync");return this.logError(i),{...this.config.defaultConfigurations}}}updateConfigCache(e,t){let i={configurations:e.configurations,snapshotId:e.snapshotId,timestamp:e.timestamp,userId:t},r=this.configCache?.configurations||{};this.configCache=i,this.saveConfigCache(i),JSON.stringify(r)!==JSON.stringify(e.configurations)&&this.notifyConfigChangeListeners(e.configurations)}addConfigChangeListener(e){this.configChangeListeners.push(e)}removeConfigChangeListener(e){let t=this.configChangeListeners.indexOf(e);t>-1&&this.configChangeListeners.splice(t,1)}notifyConfigChangeListeners(e){this.configChangeListeners.forEach(t=>{try{t(e)}catch(i){console.error("[Grain Analytics] Config change listener error:",i)}})}startConfigRefreshTimer(){typeof window>"u"||(this.configRefreshTimer&&clearInterval(this.configRefreshTimer),this.configRefreshTimer=window.setInterval(()=>{this.isDestroyed||this.fetchConfig().catch(e=>{let t=this.formatError(e,"auto-config refresh");this.logError(t)})},this.config.configRefreshInterval))}stopConfigRefreshTimer(){this.configRefreshTimer&&(clearInterval(this.configRefreshTimer),this.configRefreshTimer=null)}async preloadConfig(e=[],t){try{let i=this.getEffectiveUserIdInternal();this.log(`Preloading config for user: ${i}`),await this.fetchConfig({immediateKeys:e,properties:t})&&this.startConfigRefreshTimer()}catch(i){let r=this.formatError(i,"preloadConfig");this.logError(r)}}chunkEvents(e,t){let i=[];for(let r=0;r<e.length;r+=t)i.push(e.slice(r,r+t));return i}grantConsent(e){try{this.consentManager.grantConsent(e),this.log("Consent granted",e)}catch(t){let i=this.formatError(t,"grantConsent");this.logError(i)}}revokeConsent(e){try{this.consentManager.revokeConsent(e),this.log("Consent revoked",e),this.eventQueue=[],this.waitingForConsentQueue=[]}catch(t){let i=this.formatError(t,"revokeConsent");this.logError(i)}}getConsentState(){return this.consentManager.getConsentState()}hasConsent(e){return this.consentManager.hasConsent(e)}onConsentChange(e){this.consentManager.addListener(e)}offConsentChange(e){this.consentManager.removeListener(e)}checkAndInitializeDebugMode(){if(!(typeof window>"u"))try{let e=new URLSearchParams(window.location.search),t=e.get("grain_debug")==="1",i=e.get("grain_session");if(!t||!i)return;this.log("Debug mode detected, verifying session:",i),this.verifyDebugSession(i,window.location.hostname).then(r=>{r?(this.log("Debug session verified, initializing debug agent"),this.isDebugMode=!0,this.initializeDebugAgent(i)):this.log("Debug session verification failed")}).catch(r=>{this.log("Failed to verify debug session:",r)})}catch(e){this.log("Error checking debug mode:",e)}}async verifyDebugSession(e,t){try{let i=`${this.config.apiUrl}/v1/tenant/${encodeURIComponent(this.config.tenantId)}/debug-sessions/verify`,r=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({sessionId:e,domain:t})});return r.ok?(await r.json()).valid===!0:!1}catch(i){return this.log("Debug session verification error:",i),!1}}initializeDebugAgent(e){if(!(typeof window>"u"))try{this.log("Loading debug agent module"),Promise.resolve().then(()=>(ie(),te)).then(({DebugAgent:t})=>{try{this.debugAgent=new t(this,e,this.config.tenantId,this.config.apiUrl,{debug:this.config.debug}),this.log("Debug agent initialized")}catch(i){this.log("Failed to initialize debug agent:",i)}}).catch(t=>{this.log("Failed to load debug agent module:",t)})}catch(t){this.log("Error initializing debug agent:",t)}}destroy(){if(this.isDestroyed=!0,this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.stopConfigRefreshTimer(),this.configChangeListeners=[],this.heartbeatManager&&(this.heartbeatManager.destroy(),this.heartbeatManager=null),this.pageTrackingManager&&(this.pageTrackingManager.destroy(),this.pageTrackingManager=null),this.activityDetector&&(this.activityDetector.destroy(),this.activityDetector=null),this.interactionTrackingManager&&(this.interactionTrackingManager.destroy(),this.interactionTrackingManager=null),this.sectionTrackingManager&&(this.sectionTrackingManager.destroy(),this.sectionTrackingManager=null),this.heatmapTrackingManager&&(this.heatmapTrackingManager.destroy(),this.heatmapTrackingManager=null),this.debugAgent&&(this.debugAgent.destroy(),this.debugAgent=null),this.eventQueue.length>0){let e=[...this.eventQueue];this.eventQueue=[];let t=this.chunkEvents(e,this.config.maxEventsPerRequest);if(t.length>0){this.sendEventsWithBeacon(t[0]).catch(()=>{});for(let i=1;i<t.length;i++)this.sendEventsWithBeacon(t[i]).catch(()=>{})}}}};function re(s){return new v(s)}var Ae=v;typeof window<"u"&&(window.Grain={GrainAnalytics:v,createGrainAnalytics:re});return ce(Se);})();
3
507
  //# sourceMappingURL=index.global.js.map