@grainql/analytics-web 2.5.3 → 2.5.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.ts.map +1 -1
- package/dist/esm/index.js.map +1 -1
- package/dist/index.d.ts.map +1 -1
- package/dist/index.global.dev.js +32 -2
- package/dist/index.global.dev.js.map +2 -2
- package/dist/index.global.js +2 -2
- package/dist/index.global.js.map +3 -3
- package/dist/index.js +37 -1
- package/dist/index.mjs +38 -2
- package/package.json +1 -1
package/dist/index.global.js
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
/* Grain Analytics Web SDK v2.5.
|
|
2
|
-
"use strict";var Grain=(()=>{var P=Object.defineProperty;var J=Object.getOwnPropertyDescriptor;var Q=Object.getOwnPropertyNames;var j=Object.prototype.hasOwnProperty;var D=(s,e)=>()=>(s&&(e=s(s=0)),e);var w=(s,e)=>{for(var t in e)P(s,t,{get:e[t],enumerable:!0})},Z=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of Q(e))!j.call(s,r)&&r!==t&&P(s,r,{get:()=>e[r],enumerable:!(i=J(e,r))||i.enumerable});return s};var Y=s=>Z(P({},"__esModule",{value:!0}),s);var K={};w(K,{InteractionTrackingManager:()=>R});var R,V=D(()=>{"use strict";R=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",this.interactions.length,"interactions");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),this.log("Attached listeners to element for:",e.eventName)}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:i.textContent?.trim().substring(0,100),element_id:i.id||void 0,element_class:i.className||void 0,...r&&{href:i.href},timestamp:Date.now()};if(r){let a=this.tracker.track(e.eventName,n,{flush:!0});a instanceof Promise&&a.catch(o=>{this.log("Failed to track navigation click:",o)})}else this.tracker.track(e.eventName,n);this.log("Tracked click interaction:",e.eventName)}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()}),this.log("Tracked focus interaction:",e.eventName)}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),this.log("Detached listeners from element"))}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={};w(z,{SectionTrackingManager:()=>_});var oe,_,W=D(()=>{"use strict";oe={minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:!1},_=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={...oe,...i},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 for",this.sections.length,"sections"),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),this.log("Section initialized and observed:",e.sectionName)}}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){this.log("Section entered view:",e.config.sectionName),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={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(n)&&(this.tracker.trackSystemEvent("_grain_section_view",{section_name:n.sectionName,section_type:n.sectionType,duration_ms:n.duration,viewport_width:n.viewportWidth,viewport_height:n.viewportHeight,scroll_depth_percent:n.scrollDepth,visible_area_percent:n.visibleAreaPercentage,scroll_speed_entry:Math.round(n.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(n.scrollSpeedAtExit||0),entry_timestamp:n.entryTime,exit_timestamp:n.exitTime,is_split:!0}),this.log("Tracked periodic section view split:",e.config.sectionName,"duration:",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.log("Section exited view:",e.config.sectionName),this.stopPeriodicTracking(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.log("Queued section view:",e.sectionName,"duration:",e.duration),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}this.log("Flushing",this.pendingEvents.length,"section view events");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.sectionStates.clear(),this.xpathCache.clear(),this.pendingEvents=[])}}});var ce={};w(ce,{GrainAnalytics:()=>h,categorizeReferrer:()=>d,createGrainAnalytics:()=>$,default:()=>se,getCountry:()=>H,getCountryCodeFromTimezone:()=>C,getState:()=>F,parseUTMParameters:()=>f});var L=["necessary","analytics","functional"],A="1.0.0",v=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:L,timestamp:new Date,version:A},this.saveConsentState())}catch(e){console.error("[Grain Consent] Failed to load consent state:",e)}}saveConsentState(){if(!(typeof window>"u"||!this.consentState))try{localStorage.setItem(this.storageKey,JSON.stringify(this.consentState))}catch(e){console.error("[Grain Consent] Failed to save consent state:",e)}}grantConsent(e){let t=e||L;this.consentState={granted:!0,categories:t,timestamp:new Date,version:A},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:A}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:A},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(t){console.error("[Grain Consent] Listener error:",t)}})}clearConsent(){if(!(typeof window>"u"))try{localStorage.removeItem(this.storageKey),this.consentState=null}catch(e){console.error("[Grain Consent] Failed to clear consent:",e)}}};function k(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 M(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 q(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 N(){if(typeof document>"u")return!1;try{let s="_grain_cookie_test";k(s,"test",{maxAge:1});let e=M(s)==="test";return q(s),e}catch{return!1}}var y=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(t){console.error("[Activity Detector] Listener error:",t)}}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 E=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,this.config.debug&&console.log("[Heartbeat] Sent heartbeat:",n)}destroy(){this.isDestroyed||(this.heartbeatTimer!==null&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null),this.isDestroyed=!0,this.config.debug&&console.log("[Heartbeat] Destroyed"))}};var X=["gclid","msclkid","fbclid","ttclid","li_fat_id","twclid","ScCid"],ee=["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"],te=["google.","bing.com","yahoo.com","duckduckgo.com","baidu.com","yandex.com","ecosia.org","ask.com"],ie=["mail.google.com","outlook.live.com","mail.yahoo.com","mail.aol.com"];function I(s){try{return new URL(s).hostname.toLowerCase()}catch{return""}}function x(s){try{let e=new URL(s);return X.some(t=>e.searchParams.has(t))}catch{return!1}}function d(s,e=""){if(!s||s.trim()==="")return"direct";let t=I(s);if(e){let i=I(e);if(t===i)return"direct"}return x(s)||x(e)?"paid":ie.some(i=>t.includes(i))?"email":ee.some(i=>t.includes(i))?"social":te.some(i=>t.includes(i))?"organic":"referral"}function f(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 re(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 ne(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 S(s,e,t,i){let r=re(s);if(r)return r;let n=d(e,t),a=I(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 ne(s,o),o}var G=null;function m(){return G}function O(s){G=s}var ae={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"},B={"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 H(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return null;try{let e=B[s]?.c?.[0];return e&&ae[e]||null}catch{return null}}function C(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return"Unknown";try{return B[s]?.c?.[0]||"Unknown"}catch{return"Unknown"}}function F(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;return s===""||!s?null:s.split("/")[1]?.replace("_"," ")||null}var b=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=f(r);Object.keys(a).length>0&&(!m()||e)&&O(a);let o=m()||{},u=S(this.config.tenantId,n,r,o),c={page:t,timestamp:Date.now()};if(i){c.title=document.title||"",c.full_url=r,c.session_id=this.tracker.getSessionId(),n&&(c.referrer=n,c.referrer_domain=this.extractDomain(n),c.referrer_category=d(n,r)),this.landingPage&&!e&&(c.landing_page=this.landingPage),this.previousPage&&(c.previous_page=this.previousPage),o.utm_source&&(c.utm_source=o.utm_source),o.utm_medium&&(c.utm_medium=o.utm_medium),o.utm_campaign&&(c.utm_campaign=o.utm_campaign),o.utm_term&&(c.utm_term=o.utm_term),o.utm_content&&(c.utm_content=o.utm_content),c.first_touch_source=u.source,c.first_touch_medium=u.medium,c.first_touch_campaign=u.campaign,c.first_touch_referrer_category=u.referrer_category,c.device=this.getDeviceType(),c.browser=this.getBrowser(),c.os=this.getOS(),c.language=navigator.language||"";let l=Intl.DateTimeFormat().resolvedOptions().timeZone;c.timezone=l,c.country=C(),c.screen_resolution=`${screen.width}x${screen.height}`,c.viewport=`${window.innerWidth}x${window.innerHeight}`}this.tracker.trackSystemEvent("page_view",c),this.config.debug&&console.log("[Page Tracking] Tracked page view:",c)}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),this.config.debug&&console.log("[Page Tracking] Manually tracked page:",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,this.config.debug&&console.log("[Page Tracking] Destroyed"))}};var h=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.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,...e,tenantId:e.tenantId},this.consentManager=new v(this.config.tenantId,this.config.consentMode),this.config.enableCookies&&(this.cookiesEnabled=N(),!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.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=M(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};k(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){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),this.config.debug&&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){return{eventName:e.eventName,userId:e.userId||this.getEffectiveUserIdInternal(),properties:e.properties||{}}}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`;this.log(`Sending ${e.length} events to ${n} (attempt ${i+1})`);let a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(e)});if(!a.ok){let o=`HTTP ${a.status}`;try{let c=await a.json();c?.message&&(o=c.message)}catch{let c=await a.text();c&&(o=c)}let u=new Error(`Failed to send events: ${o}`);throw u.status=a.status,u}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}),this.log(`Successfully sent ${e.length} events via fetch (keepalive)`)}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 y,this.heartbeatManager=new E(this,this.activityDetector,{activeInterval:this.config.heartbeatActiveInterval,inactiveInterval:this.config.heartbeatInactiveInterval,debug:this.config.debug}),this.log("Heartbeat tracking initialized")}catch(e){this.log("Failed to initialize heartbeat tracking:",e)}if(this.config.enableAutoPageView)try{this.pageTrackingManager=new b(this,{stripQueryParams:this.config.stripQueryParams,debug:this.config.debug,tenantId:this.config.tenantId}),this.log("Auto page view tracking initialized")}catch(e){this.log("Failed to initialize page view tracking:",e)}this.initializeAutoTracking()}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`;this.log("Fetching auto-tracking config from:",n);let 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,a.statusText);return}let o=await a.json();this.log("Received config response:",o),o.autoTrackingConfig?(this.log("Auto-tracking config found:",o.autoTrackingConfig),this.setupAutoTrackingManagers(o.autoTrackingConfig)):this.log("No auto-tracking config in response")}catch(e){this.log("Failed to initialize auto-tracking:",e)}}setupAutoTrackingManagers(e){this.log("Setting up auto-tracking managers...",e),e.interactions&&e.interactions.length>0?(this.log("Loading interaction tracking module for",e.interactions.length,"interactions"),Promise.resolve().then(()=>(V(),K)).then(({InteractionTrackingManager:t})=>{try{this.interactionTrackingManager=new t(this,e.interactions,{debug:this.config.debug,enableMutationObserver:!0,mutationDebounceDelay:500}),this.log("\u2705 Interaction tracking initialized successfully with",e.interactions.length,"interactions")}catch(i){this.log("\u274C Failed to initialize interaction tracking:",i)}}).catch(t=>{this.log("\u274C Failed to load interaction tracking module:",t)})):this.log("No interactions configured for auto-tracking"),e.sections&&e.sections.length>0?(this.log("Loading section tracking module for",e.sections.length,"sections"),Promise.resolve().then(()=>(W(),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("\u2705 Section tracking initialized successfully with",e.sections.length,"sections")}catch(i){this.log("\u274C Failed to initialize section tracking:",i)}}).catch(t=>{this.log("\u274C Failed to load section tracking module:",t)})):this.log("No sections configured for auto-tracking")}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=f(r),a=m()||n,o=S(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=d(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:",t)}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:",i)}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}`,t),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}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"),u=this.formatError(o,"track (client destroyed)");this.logError(u);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 u of this.config.allowedProperties)u in r.properties&&(o[u]=r.properties[u]);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}`,r.properties),(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"),u=this.formatError(o,"setProperty (client destroyed)");this.logError(u);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"),u=this.formatError(o,"setProperty (validation)");this.logError(u);return}if(r.length===0){let o=new Error("Grain Analytics: At least one property is required"),u=this.formatError(o,"setProperty (validation)");this.logError(u);return}let n={};for(let[o,u]of Object.entries(e))u==null?n[o]="":typeof u=="string"?n[o]=u:n[o]=JSON.stringify(u);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`;this.log(`Setting properties for user ${e.userId} (attempt ${i+1})`);let a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(e)});if(!a.ok){let o=`HTTP ${a.status}`;try{let c=await a.json();c?.message&&(o=c.message)}catch{let c=await a.text();c&&(o=c)}let u=new Error(`Failed to set properties: ${o}`);throw u.status=a.status,u}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"),u=this.formatError(o,"fetchConfig (client destroyed)");return this.logError(u),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 u=await this.getAuthHeaders(),c=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;this.log(`Fetching configurations for user ${t} (attempt ${o+1})`);let l=await fetch(c,{method:"POST",headers:u,body:JSON.stringify(n)});if(!l.ok){let T=`HTTP ${l.status}`;try{let g=await l.json();g?.message&&(T=g.message)}catch{let g=await l.text();g&&(T=g)}let U=new Error(`Failed to fetch configurations: ${T}`);throw U.status=l.status,U}let p=await l.json();return p.configurations&&this.updateConfigCache(p,t),this.log(`Successfully fetched configurations for user ${t}:`,p),p}catch(u){if(a=u,o===this.config.retryAttempts){let l=this.formatError(u,`fetchConfig (attempt ${o+1}/${this.config.retryAttempts+1})`);return this.logError(l),null}if(!this.isRetriableError(u)){let l=this.formatError(u,"fetchConfig (non-retriable error)");return this.logError(l),null}let c=this.config.retryDelay*Math.pow(2,o);this.log(`Retrying config fetch in ${c}ms after error:`,u),await this.delay(c)}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.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 $(s){return new h(s)}var se=h;typeof window<"u"&&(window.Grain={GrainAnalytics:h,createGrainAnalytics:$});return Y(ce);})();
|
|
1
|
+
/* Grain Analytics Web SDK v2.5.4 | MIT License */
|
|
2
|
+
"use strict";var Grain=(()=>{var P=Object.defineProperty;var Q=Object.getOwnPropertyDescriptor;var j=Object.getOwnPropertyNames;var Z=Object.prototype.hasOwnProperty;var L=(s,e)=>()=>(s&&(e=s(s=0)),e);var w=(s,e)=>{for(var t in e)P(s,t,{get:e[t],enumerable:!0})},Y=(s,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let r of j(e))!Z.call(s,r)&&r!==t&&P(s,r,{get:()=>e[r],enumerable:!(i=Q(e,r))||i.enumerable});return s};var q=s=>Y(P({},"__esModule",{value:!0}),s);var V={};w(V,{InteractionTrackingManager:()=>R});var R,z=L(()=>{"use strict";R=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",this.interactions.length,"interactions");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),this.log("Attached listeners to element for:",e.eventName)}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:i.textContent?.trim().substring(0,100),element_id:i.id||void 0,element_class:i.className||void 0,...r&&{href:i.href},timestamp:Date.now()};if(r){let a=this.tracker.track(e.eventName,n,{flush:!0});a instanceof Promise&&a.catch(o=>{this.log("Failed to track navigation click:",o)})}else this.tracker.track(e.eventName,n);this.log("Tracked click interaction:",e.eventName)}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()}),this.log("Tracked focus interaction:",e.eventName)}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),this.log("Detached listeners from element"))}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 W={};w(W,{SectionTrackingManager:()=>U});var oe,U,$=L(()=>{"use strict";oe={minDwellTime:1e3,scrollVelocityThreshold:500,intersectionThreshold:.1,debounceDelay:100,batchDelay:2e3,debug:!1},U=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={...oe,...i},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 for",this.sections.length,"sections"),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),this.log("Section initialized and observed:",e.sectionName)}}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){this.log("Section entered view:",e.config.sectionName),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={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(n)&&(this.tracker.trackSystemEvent("_grain_section_view",{section_name:n.sectionName,section_type:n.sectionType,duration_ms:n.duration,viewport_width:n.viewportWidth,viewport_height:n.viewportHeight,scroll_depth_percent:n.scrollDepth,visible_area_percent:n.visibleAreaPercentage,scroll_speed_entry:Math.round(n.scrollSpeedAtEntry||0),scroll_speed_exit:Math.round(n.scrollSpeedAtExit||0),entry_timestamp:n.entryTime,exit_timestamp:n.exitTime,is_split:!0}),this.log("Tracked periodic section view split:",e.config.sectionName,"duration:",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.log("Section exited view:",e.config.sectionName),this.stopPeriodicTracking(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.log("Queued section view:",e.sectionName,"duration:",e.duration),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}this.log("Flushing",this.pendingEvents.length,"section view events");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.sectionStates.clear(),this.xpathCache.clear(),this.pendingEvents=[])}}});var ce={};w(ce,{GrainAnalytics:()=>g,categorizeReferrer:()=>d,createGrainAnalytics:()=>J,default:()=>se,getCountry:()=>F,getCountryCodeFromTimezone:()=>C,getState:()=>K,parseUTMParameters:()=>f});var N=["necessary","analytics","functional"],A="1.0.0",v=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:N,timestamp:new Date,version:A},this.saveConsentState())}catch(e){console.error("[Grain Consent] Failed to load consent state:",e)}}saveConsentState(){if(!(typeof window>"u"||!this.consentState))try{localStorage.setItem(this.storageKey,JSON.stringify(this.consentState))}catch(e){console.error("[Grain Consent] Failed to save consent state:",e)}}grantConsent(e){let t=e||N;this.consentState={granted:!0,categories:t,timestamp:new Date,version:A},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:A}:this.consentState={granted:!1,categories:[],timestamp:new Date,version:A},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(t){console.error("[Grain Consent] Listener error:",t)}})}clearConsent(){if(!(typeof window>"u"))try{localStorage.removeItem(this.storageKey),this.consentState=null}catch(e){console.error("[Grain Consent] Failed to clear consent:",e)}}};function k(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 M(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 X(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 x(){if(typeof document>"u")return!1;try{let s="_grain_cookie_test";k(s,"test",{maxAge:1});let e=M(s)==="test";return X(s),e}catch{return!1}}var y=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(t){console.error("[Activity Detector] Listener error:",t)}}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 E=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,this.config.debug&&console.log("[Heartbeat] Sent heartbeat:",n)}destroy(){this.isDestroyed||(this.heartbeatTimer!==null&&(clearTimeout(this.heartbeatTimer),this.heartbeatTimer=null),this.isDestroyed=!0,this.config.debug&&console.log("[Heartbeat] Destroyed"))}};var ee=["gclid","msclkid","fbclid","ttclid","li_fat_id","twclid","ScCid"],te=["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"],ie=["google.","bing.com","yahoo.com","duckduckgo.com","baidu.com","yandex.com","ecosia.org","ask.com"],re=["mail.google.com","outlook.live.com","mail.yahoo.com","mail.aol.com"];function I(s){try{return new URL(s).hostname.toLowerCase()}catch{return""}}function G(s){try{let e=new URL(s);return ee.some(t=>e.searchParams.has(t))}catch{return!1}}function d(s,e=""){if(!s||s.trim()==="")return"direct";let t=I(s);if(e){let i=I(e);if(t===i)return"direct"}return G(s)||G(e)?"paid":re.some(i=>t.includes(i))?"email":te.some(i=>t.includes(i))?"social":ie.some(i=>t.includes(i))?"organic":"referral"}function f(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 _(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 ne(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 S(s,e,t,i){let r=_(s);if(r)return r;let n=d(e,t),a=I(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 ne(s,o),o}var O=null;function h(){return O}function B(s){O=s}var ae={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"},H={"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 F(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return null;try{let e=H[s]?.c?.[0];return e&&ae[e]||null}catch{return null}}function C(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;if(s===""||!s)return"Unknown";try{return H[s]?.c?.[0]||"Unknown"}catch{return"Unknown"}}function K(){let s=Intl.DateTimeFormat().resolvedOptions().timeZone;return s===""||!s?null:s.split("/")[1]?.replace("_"," ")||null}var b=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=f(r);Object.keys(a).length>0&&(!h()||e)&&B(a);let o=h()||{},u=S(this.config.tenantId,n,r,o),c={page:t,timestamp:Date.now()};if(i){c.title=document.title||"",c.full_url=r,c.session_id=this.tracker.getSessionId(),n&&(c.referrer=n,c.referrer_domain=this.extractDomain(n),c.referrer_category=d(n,r)),this.landingPage&&!e&&(c.landing_page=this.landingPage),this.previousPage&&(c.previous_page=this.previousPage),o.utm_source&&(c.utm_source=o.utm_source),o.utm_medium&&(c.utm_medium=o.utm_medium),o.utm_campaign&&(c.utm_campaign=o.utm_campaign),o.utm_term&&(c.utm_term=o.utm_term),o.utm_content&&(c.utm_content=o.utm_content),c.first_touch_source=u.source,c.first_touch_medium=u.medium,c.first_touch_campaign=u.campaign,c.first_touch_referrer_category=u.referrer_category,c.device=this.getDeviceType(),c.browser=this.getBrowser(),c.os=this.getOS(),c.language=navigator.language||"";let l=Intl.DateTimeFormat().resolvedOptions().timeZone;c.timezone=l,c.country=C(),c.screen_resolution=`${screen.width}x${screen.height}`,c.viewport=`${window.innerWidth}x${window.innerHeight}`}this.tracker.trackSystemEvent("page_view",c),this.config.debug&&console.log("[Page Tracking] Tracked page view:",c)}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),this.config.debug&&console.log("[Page Tracking] Manually tracked page:",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,this.config.debug&&console.log("[Page Tracking] Destroyed"))}};var g=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.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,...e,tenantId:e.tenantId},this.consentManager=new v(this.config.tenantId,this.config.consentMode),this.config.enableCookies&&(this.cookiesEnabled=x(),!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.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=M(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};k(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){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),this.config.debug&&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=h();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=_(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`;this.log(`Sending ${e.length} events to ${n} (attempt ${i+1})`);let a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(e)});if(!a.ok){let o=`HTTP ${a.status}`;try{let c=await a.json();c?.message&&(o=c.message)}catch{let c=await a.text();c&&(o=c)}let u=new Error(`Failed to send events: ${o}`);throw u.status=a.status,u}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}),this.log(`Successfully sent ${e.length} events via fetch (keepalive)`)}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 y,this.heartbeatManager=new E(this,this.activityDetector,{activeInterval:this.config.heartbeatActiveInterval,inactiveInterval:this.config.heartbeatInactiveInterval,debug:this.config.debug}),this.log("Heartbeat tracking initialized")}catch(e){this.log("Failed to initialize heartbeat tracking:",e)}if(this.config.enableAutoPageView)try{this.pageTrackingManager=new b(this,{stripQueryParams:this.config.stripQueryParams,debug:this.config.debug,tenantId:this.config.tenantId}),this.log("Auto page view tracking initialized")}catch(e){this.log("Failed to initialize page view tracking:",e)}this.initializeAutoTracking()}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`;this.log("Fetching auto-tracking config from:",n);let 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,a.statusText);return}let o=await a.json();this.log("Received config response:",o),o.autoTrackingConfig?(this.log("Auto-tracking config found:",o.autoTrackingConfig),this.setupAutoTrackingManagers(o.autoTrackingConfig)):this.log("No auto-tracking config in response")}catch(e){this.log("Failed to initialize auto-tracking:",e)}}setupAutoTrackingManagers(e){this.log("Setting up auto-tracking managers...",e),e.interactions&&e.interactions.length>0?(this.log("Loading interaction tracking module for",e.interactions.length,"interactions"),Promise.resolve().then(()=>(z(),V)).then(({InteractionTrackingManager:t})=>{try{this.interactionTrackingManager=new t(this,e.interactions,{debug:this.config.debug,enableMutationObserver:!0,mutationDebounceDelay:500}),this.log("\u2705 Interaction tracking initialized successfully with",e.interactions.length,"interactions")}catch(i){this.log("\u274C Failed to initialize interaction tracking:",i)}}).catch(t=>{this.log("\u274C Failed to load interaction tracking module:",t)})):this.log("No interactions configured for auto-tracking"),e.sections&&e.sections.length>0?(this.log("Loading section tracking module for",e.sections.length,"sections"),Promise.resolve().then(()=>($(),W)).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("\u2705 Section tracking initialized successfully with",e.sections.length,"sections")}catch(i){this.log("\u274C Failed to initialize section tracking:",i)}}).catch(t=>{this.log("\u274C Failed to load section tracking module:",t)})):this.log("No sections configured for auto-tracking")}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=f(r),a=h()||n,o=S(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=d(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:",t)}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:",i)}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}`,t),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}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"),u=this.formatError(o,"track (client destroyed)");this.logError(u);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 u of this.config.allowedProperties)u in r.properties&&(o[u]=r.properties[u]);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}`,r.properties),(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"),u=this.formatError(o,"setProperty (client destroyed)");this.logError(u);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"),u=this.formatError(o,"setProperty (validation)");this.logError(u);return}if(r.length===0){let o=new Error("Grain Analytics: At least one property is required"),u=this.formatError(o,"setProperty (validation)");this.logError(u);return}let n={};for(let[o,u]of Object.entries(e))u==null?n[o]="":typeof u=="string"?n[o]=u:n[o]=JSON.stringify(u);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`;this.log(`Setting properties for user ${e.userId} (attempt ${i+1})`);let a=await fetch(n,{method:"POST",headers:r,body:JSON.stringify(e)});if(!a.ok){let o=`HTTP ${a.status}`;try{let c=await a.json();c?.message&&(o=c.message)}catch{let c=await a.text();c&&(o=c)}let u=new Error(`Failed to set properties: ${o}`);throw u.status=a.status,u}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"),u=this.formatError(o,"fetchConfig (client destroyed)");return this.logError(u),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 u=await this.getAuthHeaders(),c=`${this.config.apiUrl}/v1/client/${encodeURIComponent(this.config.tenantId)}/config/configurations`;this.log(`Fetching configurations for user ${t} (attempt ${o+1})`);let l=await fetch(c,{method:"POST",headers:u,body:JSON.stringify(n)});if(!l.ok){let T=`HTTP ${l.status}`;try{let m=await l.json();m?.message&&(T=m.message)}catch{let m=await l.text();m&&(T=m)}let D=new Error(`Failed to fetch configurations: ${T}`);throw D.status=l.status,D}let p=await l.json();return p.configurations&&this.updateConfigCache(p,t),this.log(`Successfully fetched configurations for user ${t}:`,p),p}catch(u){if(a=u,o===this.config.retryAttempts){let l=this.formatError(u,`fetchConfig (attempt ${o+1}/${this.config.retryAttempts+1})`);return this.logError(l),null}if(!this.isRetriableError(u)){let l=this.formatError(u,"fetchConfig (non-retriable error)");return this.logError(l),null}let c=this.config.retryDelay*Math.pow(2,o);this.log(`Retrying config fetch in ${c}ms after error:`,u),await this.delay(c)}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.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 J(s){return new g(s)}var se=g;typeof window<"u"&&(window.Grain={GrainAnalytics:g,createGrainAnalytics:J});return q(ce);})();
|
|
3
3
|
//# sourceMappingURL=index.global.js.map
|