@kitbase/analytics 0.1.6 → 0.1.7

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/lite.js CHANGED
@@ -1 +1 @@
1
- "use strict";var Kitbase=(()=>{var $=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var De=Object.getOwnPropertyNames;var Oe=Object.prototype.hasOwnProperty;var Ie=(n,e)=>{for(var t in e)$(n,t,{get:e[t],enumerable:!0})},Be=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of De(e))!Oe.call(n,s)&&s!==t&&$(n,s,{get:()=>e[s],enumerable:!(i=Se(e,s))||i.enumerable});return n};var Re=n=>Be($({},"__esModule",{value:!0}),n);var ot={};Ie(ot,{ApiError:()=>k,AuthenticationError:()=>y,DEFAULT_BOT_DETECTION_CONFIG:()=>E,KitbaseAnalytics:()=>C,KitbaseError:()=>p,TimeoutError:()=>w,ValidationError:()=>v,createDefaultPlugins:()=>H,detectBot:()=>g,getUserAgent:()=>ue,isBot:()=>le,isUserAgentBot:()=>ce});var p=class n extends Error{constructor(e){super(e),this.name="KitbaseError",Object.setPrototypeOf(this,n.prototype)}},y=class n extends p{constructor(e="Invalid API key"){super(e),this.name="AuthenticationError",Object.setPrototypeOf(this,n.prototype)}},k=class n extends p{statusCode;response;constructor(e,t,i){super(e),this.name="ApiError",this.statusCode=t,this.response=i,Object.setPrototypeOf(this,n.prototype)}},v=class n extends p{field;constructor(e,t){super(e),this.name="ValidationError",this.field=t,Object.setPrototypeOf(this,n.prototype)}},w=class n extends p{constructor(e="Request timed out"){super(e),this.name="TimeoutError",Object.setPrototypeOf(this,n.prototype)}};var Me=["__webdriver_evaluate","__selenium_evaluate","__webdriver_script_function","__webdriver_unwrapped","__fxdriver_evaluate","__driver_evaluate","_Selenium_IDE_Recorder","_selenium","calledSelenium","$cdc_asdjflasutopfhvcZLmcfl_","__nightmare","domAutomation","domAutomationController"],oe=["headlesschrome","phantomjs","selenium","webdriver","puppeteer","playwright"],ae=["python","curl","wget","java/","go-http","node-fetch","axios","postman","insomnia","httpie","ruby","perl","scrapy","bot","spider","crawler","slurp","googlebot","bingbot","yandexbot","baiduspider","duckduckbot","facebookexternalhit","twitterbot","linkedinbot","whatsapp","telegram","discord","slack"],E={enabled:!0,checkWebdriver:!0,checkPhantomJS:!0,checkNightmare:!0,checkAutomationGlobals:!0,checkDocumentAttributes:!0,checkUserAgentHeadless:!0,checkUserAgentHttpClient:!0};function d(){return typeof window<"u"&&typeof document<"u"}function L(n){try{return window[n]}catch{return}}function Ne(){if(!d())return!1;try{return window.navigator?.webdriver===!0}catch{return!1}}function Ue(){if(!d())return!1;try{return!!(L("callPhantom")||L("_phantom")||L("phantom"))}catch{return!1}}function Ke(){if(!d())return!1;try{return!!L("__nightmare")}catch{return!1}}function Ve(){if(!d())return!1;try{for(let n of Me)if(L(n)!==void 0)return!0;return!1}catch{return!1}}function Fe(){if(!d())return!1;try{let n=document.documentElement;return n?!!(n.getAttribute("webdriver")||n.getAttribute("selenium")||n.getAttribute("driver")):!1}catch{return!1}}function je(){if(!d())return!1;try{let n=window.navigator?.userAgent?.toLowerCase()||"";if(!n)return!1;for(let e of oe)if(n.includes(e))return!0;return!1}catch{return!1}}function He(n){if(!d())return!1;try{let e=window.navigator?.userAgent?.toLowerCase()||"";if(!e)return!1;for(let t of ae)if(e.includes(t))return!0;if(n){for(let t of n)if(e.includes(t.toLowerCase()))return!0}return!1}catch{return!1}}function We(){if(!d())return!1;try{let n=window.navigator?.userAgent;return!n||n===""||n==="undefined"||n.length<10}catch{return!1}}function $e(){if(!d())return!1;try{return!window.navigator||!window.location||!window.document||typeof window.navigator!="object"||typeof window.location!="object"||typeof window.document!="object"}catch{return!0}}function g(n={}){let e={...E,...n},t={webdriver:e.checkWebdriver?Ne():!1,phantomjs:e.checkPhantomJS?Ue():!1,nightmare:e.checkNightmare?Ke():!1,automationGlobals:e.checkAutomationGlobals?Ve():!1,documentAttributes:e.checkDocumentAttributes?Fe():!1,userAgentHeadless:e.checkUserAgentHeadless?je():!1,userAgentHttpClient:e.checkUserAgentHttpClient?He(n.additionalBotPatterns):!1,missingUserAgent:We(),invalidEnvironment:$e()},i;t.webdriver?i="WebDriver detected":t.phantomjs?i="PhantomJS detected":t.nightmare?i="Nightmare.js detected":t.automationGlobals?i="Automation tool globals detected":t.documentAttributes?i="Automation attributes on document element":t.userAgentHeadless?i="Headless browser user agent detected":t.userAgentHttpClient?i="HTTP client/bot user agent detected":t.missingUserAgent?i="Missing or invalid user agent":t.invalidEnvironment&&(i="Invalid browser environment");let s=Object.values(t).some(Boolean),r={isBot:s,reason:i,checks:t};if(s&&n.onBotDetected)try{n.onBotDetected(r)}catch{}return r}function le(n={}){return g(n).isBot}function ce(n,e){if(!n||n.length<10)return!0;let t=n.toLowerCase();for(let i of oe)if(t.includes(i))return!0;for(let i of ae)if(t.includes(i))return!0;if(e){for(let i of e)if(t.includes(i.toLowerCase()))return!0}return!1}function ue(){if(!d())return null;try{return window.navigator?.userAgent||null}catch{return null}}var S=["a","button","input","select","textarea",'[role="button"]','[role="link"]','[role="menuitem"]','[role="tab"]'].join(", ");function P(n){let e=n.composedPath?.();if(e){for(let i of e)if(i instanceof Element){if(i===document.documentElement)break;if(i.matches(S)){let s=i.getRootNode();return s instanceof ShadowRoot&&s.host instanceof Element?s.host:i}if(i.tagName.includes("-"))return i}}let t=n.target;return t?.closest?t.closest(S):null}function G(n){if(n.id)return`#${n.id}`;let e=n.tagName.toLowerCase(),t=n.className&&typeof n.className=="string"?"."+n.className.trim().split(/\s+/).slice(0,2).join("."):"";return t?`${e}${t}`:e}function D(n){let e=n.replace(/^www\./,"").split(".");return e.length>=2?e.slice(-2).join("."):n}function de(n,e){return D(n)===D(e)}function O(){if(typeof window>"u")return{};let n=new URLSearchParams(window.location.search),e={},t=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"];for(let i of t){let s=n.get(i);s&&(e[`__${i}`]=s)}return e}var Ge="https://api.kitbase.dev",qe=3e4,Ye="__analytics",C=class n{sdkKey;baseUrl;superProperties={};timedEvents=new Map;debugMode;analyticsConfig;userId=null;botDetectionConfig;botDetectionResult=null;clientSessionId=null;lastActivityAt=0;static SESSION_TIMEOUT_MS=1800*1e3;_plugins=new Map;_pluginContext=null;constructor(e,t){if(!e.sdkKey)throw new v("SDK key is required","sdkKey");if(this.sdkKey=e.sdkKey,this.baseUrl=(e.baseUrl??Ge).replace(/\/+$/,""),this.debugMode=e.debug??!1,this.analyticsConfig=e.analytics,this.botDetectionConfig={...E,...e.botDetection},this.botDetectionConfig.enabled&&(this.botDetectionResult=g(this.botDetectionConfig),this.botDetectionResult.isBot?this.log("Bot detected",{reason:this.botDetectionResult.reason,checks:this.botDetectionResult.checks}):this.log("Bot detection enabled, no bot detected")),t)for(let i of t)this.use(i)}use(e){if(this._plugins.has(e.name)){this.log(`Plugin "${e.name}" already registered`);return}let t=this.getPluginContext();if(e.setup(t)===!1){this.log(`Plugin "${e.name}" declined to activate`);return}this._plugins.set(e.name,e);let s=e.methods;if(s)for(let[r,o]of Object.entries(s))this[r]=o;this.log(`Plugin "${e.name}" registered`)}getPlugins(){return Array.from(this._plugins.keys())}getPluginContext(){return this._pluginContext?this._pluginContext:(this._pluginContext={track:e=>this.track(e),config:Object.freeze({autoTrackPageViews:this.analyticsConfig?.autoTrackPageViews,autoTrackOutboundLinks:this.analyticsConfig?.autoTrackOutboundLinks,autoTrackClicks:this.analyticsConfig?.autoTrackClicks,autoTrackScrollDepth:this.analyticsConfig?.autoTrackScrollDepth,autoTrackVisibility:this.analyticsConfig?.autoTrackVisibility,autoTrackWebVitals:this.analyticsConfig?.autoTrackWebVitals,autoDetectFrustration:this.analyticsConfig?.autoDetectFrustration}),debug:this.debugMode,log:(e,t)=>this.log(e,t),isBotBlockingActive:()=>this.isBotBlockingActive(),findClickableElement:P,CLICKABLE_SELECTOR:S,getRootDomain:D,isSameRootDomain:de,getUtmParams:O},this._pluginContext)}setDebugMode(e){this.debugMode=e,this.log(`Debug mode ${e?"enabled":"disabled"}`)}isDebugMode(){return this.debugMode}log(e,t){if(!this.debugMode)return;let i="[Kitbase]";t!==void 0?console.log(i,e,t):console.log(i,e)}register(e){this.superProperties={...this.superProperties,...e},this.log("Super properties registered",e)}registerOnce(e){let t={};for(let[i,s]of Object.entries(e))i in this.superProperties||(t[i]=s);Object.keys(t).length>0&&(this.superProperties={...this.superProperties,...t},this.log("Super properties registered (once)",t))}unregister(e){e in this.superProperties&&(delete this.superProperties[e],this.log("Super property removed",{key:e}))}getSuperProperties(){return{...this.superProperties}}clearSuperProperties(){this.superProperties={},this.log("Super properties cleared")}timeEvent(e){this.timedEvents.set(e,Date.now()),this.log("Timer started",{event:e})}cancelTimeEvent(e){this.timedEvents.has(e)&&(this.timedEvents.delete(e),this.log("Timer cancelled",{event:e}))}getTimedEvents(){return Array.from(this.timedEvents.keys())}getEventDuration(e){let t=this.timedEvents.get(e);return t===void 0?null:(Date.now()-t)/1e3}isBot(){return this.botDetectionConfig?.enabled?(this.botDetectionResult||(this.botDetectionResult=g(this.botDetectionConfig)),this.botDetectionResult.isBot):!1}getBotDetectionResult(){return this.botDetectionConfig.enabled?(this.botDetectionResult||(this.botDetectionResult=g(this.botDetectionConfig)),this.botDetectionResult):null}redetectBot(){return this.botDetectionResult=g(this.botDetectionConfig),this.log("Bot detection re-run",{isBot:this.botDetectionResult.isBot,reason:this.botDetectionResult.reason}),this.botDetectionResult}isBotBlockingActive(){return this.botDetectionConfig?.enabled===!0&&this.isBot()}getClientSessionId(){let e=Date.now();return(!this.clientSessionId||this.lastActivityAt>0&&e-this.lastActivityAt>n.SESSION_TIMEOUT_MS)&&(this.clientSessionId=n.generateUUID(),this.log("New client session started",{sessionId:this.clientSessionId})),this.lastActivityAt=e,this.clientSessionId}static generateUUID(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,i=>i.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}async track(e){if(this.validateTrackOptions(e),this.isBotBlockingActive()){this.log("Event skipped - bot detected",{event:e.event});return}let t,i=this.timedEvents.get(e.event);i!==void 0&&(t=(Date.now()-i)/1e3,this.timedEvents.delete(e.event),this.log("Timer stopped",{event:e.event,duration:t}));let s={...this.superProperties,...e.tags??{},...t!==void 0?{$duration:t}:{}},r={channel:e.channel,event:e.event,client_timestamp:Date.now(),client_session_id:this.getClientSessionId(),...e.user_id&&{user_id:e.user_id},...e.icon&&{icon:e.icon},...e.notify!==void 0&&{notify:e.notify},...e.description&&{description:e.description},...Object.keys(s).length>0&&{tags:s}};this.log("Track",{event:e.event,payload:r});let o=await this.sendRequest("/sdk/v1/logs",r);return this.log("Event sent successfully",{id:o.id}),o}validateTrackOptions(e){if(!e.event)throw new v("Event is required","event")}async sendRequest(e,t){let i=`${this.baseUrl}${e}`,s=new AbortController,r=setTimeout(()=>s.abort(),qe);try{let o=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":`${this.sdkKey}`},body:JSON.stringify(t),signal:s.signal});if(clearTimeout(r),!o.ok){let a=await this.parseResponseBody(o);throw o.status===401?new y:new k(this.getErrorMessage(a,o.statusText),o.status,a)}return await o.json()}catch(o){throw clearTimeout(r),o instanceof Error&&o.name==="AbortError"?new w:o}}async parseResponseBody(e){try{return await e.json()}catch{return null}}getErrorMessage(e,t){return e&&typeof e=="object"&&"message"in e?String(e.message):e&&typeof e=="object"&&"error"in e?String(e.error):t}async trackPageView(e){this.log("trackPageView() called but page-view plugin is not registered")}async trackClick(e){this.log("trackClick() called but click-tracking plugin is not registered")}async trackOutboundLink(e){this.log("trackOutboundLink() called but outbound-links plugin is not registered")}async trackRevenue(e){return this.track({channel:Ye,event:"revenue",user_id:e.user_id??this.userId??void 0,tags:{__revenue:e.amount,__currency:e.currency??"USD",...e.tags??{}}})}async identify(e){this.userId=e.userId,e.traits?this.register({__user_id:e.userId,...e.traits}):this.register({__user_id:e.userId});try{let t=await fetch(`${this.baseUrl}/sdk/v1/identify`,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":this.sdkKey},body:JSON.stringify({user_id:e.userId,traits:e.traits})});t.ok?this.log("Identity set on server",{userId:e.userId}):this.log("Identify API call failed",{status:t.status})}catch(t){this.log("Failed to call identify endpoint",t)}this.log("User identified",{userId:e.userId})}getUserId(){return this.userId}reset(){this.userId=null,this.clientSessionId=null,this.lastActivityAt=0,this.clearSuperProperties(),this.log("User reset complete")}shutdown(){this.log("Shutting down"),this.timedEvents.clear();let e=Array.from(this._plugins.keys()).reverse();for(let t of e){let i=this._plugins.get(t);try{i.teardown(),this.log(`Plugin "${t}" torn down`)}catch(s){this.log(`Plugin "${t}" teardown failed`,s)}}this._plugins.clear(),this._pluginContext=null,this.log("Shutdown complete")}};var Je="__analytics",I=class{name="page-view";ctx;active=!1;popstateListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.active=!0,Promise.resolve().then(()=>{this.active&&this.trackPageView().catch(s=>e.log("Failed to track initial page view",s))});let t=history.pushState.bind(history);history.pushState=(...s)=>{t(...s),this.active&&this.trackPageView().catch(r=>e.log("Failed to track page view (pushState)",r))};let i=history.replaceState.bind(history);history.replaceState=(...s)=>{i(...s)},this.popstateListener=()=>{this.active&&this.trackPageView().catch(s=>e.log("Failed to track page view (popstate)",s))},window.addEventListener("popstate",this.popstateListener),e.log("Auto page view tracking enabled")}teardown(){this.active=!1,this.popstateListener&&(window.removeEventListener("popstate",this.popstateListener),this.popstateListener=null)}get methods(){return{trackPageView:e=>this.trackPageView(e)}}async trackPageView(e={}){let t=e.path??(typeof window<"u"?window.location.pathname:""),i=e.title??(typeof document<"u"?document.title:""),s=e.referrer??(typeof document<"u"?document.referrer:"");return this.ctx.track({channel:Je,event:"screen_view",tags:{__path:t,__title:i,__referrer:s,...O(),...e.tags??{}}})}};var ze="__analytics",B=class{name="outbound-links";ctx;clickListener=null;keydownListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.clickListener=t=>{let i=t.target?.closest?.("a");i&&this.handleLinkClick(i)},this.keydownListener=t=>{if(t.key==="Enter"||t.key===" "){let i=t.target?.closest?.("a");i&&this.handleLinkClick(i)}},document.addEventListener("click",this.clickListener),document.addEventListener("keydown",this.keydownListener),e.log("Outbound link tracking enabled")}teardown(){this.clickListener&&(document.removeEventListener("click",this.clickListener),this.clickListener=null),this.keydownListener&&(document.removeEventListener("keydown",this.keydownListener),this.keydownListener=null)}get methods(){return{trackOutboundLink:e=>this.trackOutboundLink(e)}}handleLinkClick(e){if(e.href)try{let t=new URL(e.href);if(t.protocol!=="http:"&&t.protocol!=="https:")return;let i=window.location.hostname,s=t.hostname;if(s===i||this.ctx.isSameRootDomain(i,s))return;this.trackOutboundLink({url:e.href,text:e.textContent?.trim()||""}).catch(r=>this.ctx.log("Failed to track outbound link",r))}catch{}}async trackOutboundLink(e){return this.ctx.track({channel:ze,event:"outbound_link",tags:{__url:e.url,__text:e.text||""}})}};var Xe="__analytics",R=class{name="click-tracking";ctx;clickListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.clickListener=t=>{let s=t.target?.closest?.("[data-kb-track-click]");if(s){let m=s.getAttribute("data-kb-track-click");if(m){let b=s.getAttribute("data-kb-click-channel")||"engagement";e.track({channel:b,event:m,tags:{__path:window.location.pathname}}).catch(xe=>e.log("Failed to track data-attribute click",xe));return}}let r=e.findClickableElement(t);if(!r)return;if(e.config.autoTrackOutboundLinks!==!1){let m=r.href||r.getAttribute("href")||"";if(m)try{let b=new URL(m,window.location.origin);if((b.protocol==="http:"||b.protocol==="https:")&&b.hostname!==window.location.hostname&&!e.isSameRootDomain(window.location.hostname,b.hostname))return}catch{}}let o=r.tagName.toLowerCase(),a=r.id||"",c=r.className&&typeof r.className=="string"?r.className:"",l=(r.textContent||"").trim().slice(0,100),u=r.href||r.getAttribute("href")||"",W=window.location.pathname;this.trackClick({__tag:o,__id:a,__class:c,__text:l,__href:u,__path:W}).catch(m=>e.log("Failed to track click",m))},document.addEventListener("click",this.clickListener),e.log("Click tracking enabled")}teardown(){this.clickListener&&(document.removeEventListener("click",this.clickListener),this.clickListener=null)}get methods(){return{trackClick:e=>this.trackClick(e)}}async trackClick(e){return this.ctx.track({channel:Xe,event:"click",tags:e})}};var Ze="__analytics",M=class{name="scroll-depth";ctx;active=!1;maxScrollDepth=0;scrollListener=null;beforeUnloadListener=null;popstateListener=null;scrollRafScheduled=!1;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.active=!0,this.scrollListener=()=>{this.scrollRafScheduled||(this.scrollRafScheduled=!0,requestAnimationFrame(()=>{this.scrollRafScheduled=!1;let s=window.scrollY||document.documentElement.scrollTop,r=window.innerHeight,o=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight);if(o<=0)return;let a=Math.min(100,Math.round((s+r)/o*100));a>this.maxScrollDepth&&(this.maxScrollDepth=a)}))},this.beforeUnloadListener=()=>{this.flushScrollDepth()},window.addEventListener("scroll",this.scrollListener,{passive:!0}),window.addEventListener("beforeunload",this.beforeUnloadListener);let t=history.pushState,i=this;history.pushState=function(...s){return i.active&&i.flushScrollDepth(),t.apply(this,s)},this.popstateListener=()=>{this.active&&this.flushScrollDepth()},window.addEventListener("popstate",this.popstateListener),e.log("Scroll depth tracking enabled")}teardown(){this.active=!1,this.flushScrollDepth(),this.scrollListener&&(window.removeEventListener("scroll",this.scrollListener),this.scrollListener=null),this.beforeUnloadListener&&(window.removeEventListener("beforeunload",this.beforeUnloadListener),this.beforeUnloadListener=null),this.popstateListener&&(window.removeEventListener("popstate",this.popstateListener),this.popstateListener=null)}flushScrollDepth(){if(this.maxScrollDepth>0){let e=typeof window<"u"?window.location.pathname:"";this.ctx.track({channel:Ze,event:"scroll_depth",tags:{__depth:this.maxScrollDepth,__path:e}}).catch(t=>this.ctx.log("Failed to track scroll depth",t)),this.maxScrollDepth=0}}};var N=class{name="visibility";ctx;active=!1;visibilityObservers=new Map;visibilityMutationObserver=null;visibilityData=new Map;beforeUnloadListener=null;popstateListener=null;setup(e){if(typeof window>"u"||typeof IntersectionObserver>"u"||typeof MutationObserver>"u")return!1;this.ctx=e,this.active=!0,this.scanForVisibilityElements(),this.visibilityMutationObserver=new MutationObserver(s=>{for(let r of s){for(let o of Array.from(r.addedNodes))if(o instanceof Element){this.observeVisibilityElement(o);for(let a of Array.from(o.querySelectorAll("[data-kb-track-visibility]")))this.observeVisibilityElement(a)}for(let o of Array.from(r.removedNodes))if(o instanceof Element){this.flushVisibilityForElement(o);for(let a of Array.from(o.querySelectorAll("[data-kb-track-visibility]")))this.flushVisibilityForElement(a)}}}),this.visibilityMutationObserver.observe(document.body,{childList:!0,subtree:!0}),this.beforeUnloadListener=()=>{this.flushAllVisibilityEvents()},window.addEventListener("beforeunload",this.beforeUnloadListener);let t=history.pushState,i=this;history.pushState=function(...s){return i.active&&i.flushAllVisibilityEvents(),t.apply(this,s)},this.popstateListener=()=>{this.active&&this.flushAllVisibilityEvents()},window.addEventListener("popstate",this.popstateListener),e.log("Visibility tracking enabled")}teardown(){this.active=!1,this.flushAllVisibilityEvents();for(let e of this.visibilityObservers.values())e.disconnect();this.visibilityObservers.clear(),this.visibilityMutationObserver&&(this.visibilityMutationObserver.disconnect(),this.visibilityMutationObserver=null),this.beforeUnloadListener&&(window.removeEventListener("beforeunload",this.beforeUnloadListener),this.beforeUnloadListener=null),this.popstateListener&&(window.removeEventListener("popstate",this.popstateListener),this.popstateListener=null),this.visibilityData.clear()}scanForVisibilityElements(){for(let e of Array.from(document.querySelectorAll("[data-kb-track-visibility]")))this.observeVisibilityElement(e)}observeVisibilityElement(e){let t=e.getAttribute("data-kb-track-visibility");if(!t||this.visibilityData.has(e))return;let i=e.getAttribute("data-kb-visibility-channel")||"engagement",s=parseFloat(e.getAttribute("data-kb-visibility-threshold")||"0.5"),r=Math.max(0,Math.min(1,isNaN(s)?.5:s));this.visibilityData.set(e,{visibleSince:null,totalMs:0,event:t,channel:i}),this.getOrCreateObserver(r).observe(e)}getOrCreateObserver(e){let t=Math.round(e*100),i=this.visibilityObservers.get(t);return i||(i=new IntersectionObserver(s=>{let r=Date.now();for(let o of s){let a=this.visibilityData.get(o.target);a&&(o.isIntersecting?a.visibleSince=r:a.visibleSince!==null&&(a.totalMs+=r-a.visibleSince,a.visibleSince=null))}},{threshold:e}),this.visibilityObservers.set(t,i),i)}flushVisibilityForElement(e){let t=this.visibilityData.get(e);if(t){if(t.visibleSince!==null&&(t.totalMs+=Date.now()-t.visibleSince,t.visibleSince=null),t.totalMs>0){let i=Math.round(t.totalMs),s=Math.round(i/1e3);this.ctx.track({channel:t.channel,event:"element_visible",tags:{__element_name:t.event,__duration_seconds:s,__duration_ms:i}}).catch(r=>this.ctx.log("Failed to track visibility event",r))}for(let i of this.visibilityObservers.values())i.unobserve(e);this.visibilityData.delete(e)}}flushAllVisibilityEvents(){for(let[,e]of this.visibilityData.entries()){if(e.visibleSince!==null&&(e.totalMs+=Date.now()-e.visibleSince,e.visibleSince=null),e.totalMs>0){let t=Math.round(e.totalMs),i=Math.round(t/1e3);this.ctx.track({channel:e.channel,event:"element_visible",tags:{element_name:e.event,duration_seconds:i,duration_ms:t}}).catch(s=>this.ctx.log("Failed to track visibility event",s))}e.totalMs=0,e.visibleSince=null}}};var ke=-1,_=n=>{addEventListener("pageshow",(e=>{e.persisted&&(ke=e.timeStamp,n(e))}),!0)},h=(n,e,t,i)=>{let s,r;return o=>{e.value>=0&&(o||i)&&(r=e.value-(s??0),(r||s===void 0)&&(s=e.value,e.delta=r,e.rating=((a,c)=>a>c[1]?"poor":a>c[0]?"needs-improvement":"good")(e.value,t),n(e)))}},te=n=>{requestAnimationFrame((()=>requestAnimationFrame((()=>n()))))},ie=()=>{let n=performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},A=()=>ie()?.activationStart??0,f=(n,e=-1)=>{let t=ie(),i="navigate";return ke>=0?i="back-forward-cache":t&&(document.prerendering||A()>0?i="prerender":document.wasDiscarded?i="restore":t.type&&(i=t.type.replace(/_/g,"-"))),{name:n,value:e,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:i}},q=new WeakMap;function ne(n,e){return q.get(n)||q.set(n,new e),q.get(n)}var J=class{t;i=0;o=[];h(e){if(e.hadRecentInput)return;let t=this.o[0],i=this.o.at(-1);this.i&&t&&i&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}},x=(n,e,t={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(n)){let i=new PerformanceObserver((s=>{Promise.resolve().then((()=>{e(s.getEntries())}))}));return i.observe({type:n,buffered:!0,...t}),i}}catch{}},se=n=>{let e=!1;return()=>{e||(n(),e=!0)}},T=-1,we=new Set,he=()=>document.visibilityState!=="hidden"||document.prerendering?1/0:0,z=n=>{if(document.visibilityState==="hidden"){if(n.type==="visibilitychange")for(let e of we)e();isFinite(T)||(T=n.type==="visibilitychange"?n.timeStamp:0,removeEventListener("prerenderingchange",z,!0))}},K=()=>{if(T<0){let n=A();T=(document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter((t=>t.name==="hidden"&&t.startTime>n))[0]?.startTime)??he(),addEventListener("visibilitychange",z,!0),addEventListener("prerenderingchange",z,!0),_((()=>{setTimeout((()=>{T=he()}))}))}return{get firstHiddenTime(){return T},onHidden(n){we.add(n)}}},V=n=>{document.prerendering?addEventListener("prerenderingchange",(()=>n()),!0):n()},fe=[1800,3e3],re=(n,e={})=>{V((()=>{let t=K(),i,s=f("FCP"),r=x("paint",(o=>{for(let a of o)a.name==="first-contentful-paint"&&(r.disconnect(),a.startTime<t.firstHiddenTime&&(s.value=Math.max(a.startTime-A(),0),s.entries.push(a),i(!0)))}));r&&(i=h(n,s,fe,e.reportAllChanges),_((o=>{s=f("FCP"),i=h(n,s,fe,e.reportAllChanges),te((()=>{s.value=performance.now()-o.timeStamp,i(!0)}))})))}))},pe=[.1,.25],Ce=(n,e={})=>{let t=K();re(se((()=>{let i,s=f("CLS",0),r=ne(e,J),o=c=>{for(let l of c)r.h(l);r.i>s.value&&(s.value=r.i,s.entries=r.o,i())},a=x("layout-shift",o);a&&(i=h(n,s,pe,e.reportAllChanges),t.onHidden((()=>{o(a.takeRecords()),i(!0)})),_((()=>{r.i=0,s=f("CLS",0),i=h(n,s,pe,e.reportAllChanges),te((()=>i()))})),setTimeout(i))})))},Te=0,Y=1/0,U=0,Qe=n=>{for(let e of n)e.interactionId&&(Y=Math.min(Y,e.interactionId),U=Math.max(U,e.interactionId),Te=U?(U-Y)/7+1:0)},X,ge=()=>X?Te:performance.interactionCount??0,et=()=>{"interactionCount"in performance||X||(X=x("event",Qe,{type:"event",buffered:!0,durationThreshold:0}))},me=0,Z=class{u=[];l=new Map;m;p;v(){me=ge(),this.u.length=0,this.l.clear()}L(){let e=Math.min(this.u.length-1,Math.floor((ge()-me)/50));return this.u[e]}h(e){if(this.m?.(e),!e.interactionId&&e.entryType!=="first-input")return;let t=this.u.at(-1),i=this.l.get(e.interactionId);if(i||this.u.length<10||e.duration>t.P){if(i?e.duration>i.P?(i.entries=[e],i.P=e.duration):e.duration===i.P&&e.startTime===i.entries[0].startTime&&i.entries.push(e):(i={id:e.interactionId,entries:[e],P:e.duration},this.l.set(i.id,i),this.u.push(i)),this.u.sort(((s,r)=>r.P-s.P)),this.u.length>10){let s=this.u.splice(10);for(let r of s)this.l.delete(r.id)}this.p?.(i)}}},_e=n=>{let e=globalThis.requestIdleCallback||setTimeout;document.visibilityState==="hidden"?n():(n=se(n),addEventListener("visibilitychange",n,{once:!0,capture:!0}),e((()=>{n(),removeEventListener("visibilitychange",n,{capture:!0})})))},ve=[200,500],Le=(n,e={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;let t=K();V((()=>{et();let i,s=f("INP"),r=ne(e,Z),o=c=>{_e((()=>{for(let u of c)r.h(u);let l=r.L();l&&l.P!==s.value&&(s.value=l.P,s.entries=l.entries,i())}))},a=x("event",o,{durationThreshold:e.durationThreshold??40});i=h(n,s,ve,e.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),t.onHidden((()=>{o(a.takeRecords()),i(!0)})),_((()=>{r.v(),s=f("INP"),i=h(n,s,ve,e.reportAllChanges)})))}))},Q=class{m;h(e){this.m?.(e)}},be=[2500,4e3],Ee=(n,e={})=>{V((()=>{let t=K(),i,s=f("LCP"),r=ne(e,Q),o=c=>{e.reportAllChanges||(c=c.slice(-1));for(let l of c)r.h(l),l.startTime<t.firstHiddenTime&&(s.value=Math.max(l.startTime-A(),0),s.entries=[l],i())},a=x("largest-contentful-paint",o);if(a){i=h(n,s,be,e.reportAllChanges);let c=se((()=>{o(a.takeRecords()),a.disconnect(),i(!0)})),l=u=>{u.isTrusted&&(_e(c),removeEventListener(u.type,l,{capture:!0}))};for(let u of["keydown","click","visibilitychange"])addEventListener(u,l,{capture:!0});_((u=>{s=f("LCP"),i=h(n,s,be,e.reportAllChanges),te((()=>{s.value=performance.now()-u.timeStamp,i(!0)}))}))}}))},ye=[800,1800],ee=n=>{document.prerendering?V((()=>ee(n))):document.readyState!=="complete"?addEventListener("load",(()=>ee(n)),!0):setTimeout(n)},Pe=(n,e={})=>{let t=f("TTFB"),i=h(n,t,ye,e.reportAllChanges);ee((()=>{let s=ie();s&&(t.value=Math.max(s.responseStart-A(),0),t.entries=[s],i(!0),_((()=>{t=f("TTFB",0),i=h(n,t,ye,e.reportAllChanges),i(!0)})))}))};var tt="__analytics",F=class{name="web-vitals";ctx;sent=!1;timeout=null;beforeUnloadListener=null;data={lcp:null,cls:null,inp:null,fcp:null,ttfb:null};setup(e){if(typeof window>"u")return!1;this.ctx=e;let t=()=>{let{lcp:i,cls:s,inp:r,fcp:o,ttfb:a}=this.data;i!==null&&s!==null&&r!==null&&o!==null&&a!==null&&this.sendWebVitals()};Ee(i=>{this.data.lcp=i.value,e.log("Web Vital collected",{name:"LCP",value:i.value}),t()}),Ce(i=>{this.data.cls=i.value,e.log("Web Vital collected",{name:"CLS",value:i.value}),t()}),Le(i=>{this.data.inp=i.value,e.log("Web Vital collected",{name:"INP",value:i.value}),t()}),re(i=>{this.data.fcp=i.value,e.log("Web Vital collected",{name:"FCP",value:i.value}),t()}),Pe(i=>{this.data.ttfb=i.value,e.log("Web Vital collected",{name:"TTFB",value:i.value}),t()}),this.timeout=setTimeout(()=>{this.timeout=null,this.sendWebVitals()},3e4),this.beforeUnloadListener=()=>{this.sendWebVitals()},window.addEventListener("beforeunload",this.beforeUnloadListener),e.log("Web Vitals tracking enabled")}teardown(){this.timeout!==null&&(clearTimeout(this.timeout),this.timeout=null),this.sendWebVitals(),this.beforeUnloadListener&&(window.removeEventListener("beforeunload",this.beforeUnloadListener),this.beforeUnloadListener=null)}sendWebVitals(){if(this.sent)return;let{lcp:e,cls:t,inp:i,fcp:s,ttfb:r}=this.data;if(e===null&&t===null&&i===null&&s===null&&r===null)return;this.sent=!0,this.timeout!==null&&(clearTimeout(this.timeout),this.timeout=null);let o={};e!==null&&(o.__lcp=e),t!==null&&(o.__cls=t),i!==null&&(o.__inp=i),s!==null&&(o.__fcp=s),r!==null&&(o.__ttfb=r),this.ctx.log("Sending Web Vitals",o),this.ctx.track({channel:tt,event:"web_vitals",tags:o}).catch(a=>this.ctx.log("Failed to track web vitals",a))}};var Ae="__analytics",it=3,nt=1e3,st=30,rt=1e3,j=class{name="frustration";ctx;rageClickBuffer=[];deadClickObserver=null;deadClickTimeout=null;clickListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.clickListener=t=>{let i=t.target;if(!i)return;let s=Date.now();if(this.rageClickBuffer.push({time:s,x:t.clientX,y:t.clientY,target:i}),this.rageClickBuffer=this.rageClickBuffer.filter(a=>s-a.time<nt),this.rageClickBuffer.length>=it){let a=this.rageClickBuffer[0];if(this.rageClickBuffer.every(l=>Math.hypot(l.x-a.x,l.y-a.y)<st)){let l=P(t)||i,u=this.rageClickBuffer.length;this.rageClickBuffer=[],e.track({channel:Ae,event:"rage_click",tags:{__path:window.location.pathname,__tag:l.tagName.toLowerCase(),__id:l.id||"",__class:l.className&&typeof l.className=="string"?l.className:"",__text:(l.textContent||"").trim().slice(0,100),__selector:G(l),__click_count:u}}).catch(W=>e.log("Failed to track rage click",W));return}}let r=P(t);if(!r||i.closest?.("a[href]")||r.tagName==="SELECT"||i.closest?.("select"))return;this.deadClickTimeout!==null&&(clearTimeout(this.deadClickTimeout),this.deadClickTimeout=null),this.deadClickObserver&&this.deadClickObserver.disconnect();let o=!1;this.deadClickObserver=new MutationObserver(()=>{o=!0}),this.deadClickObserver.observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),this.deadClickTimeout=setTimeout(()=>{this.deadClickObserver&&(this.deadClickObserver.disconnect(),this.deadClickObserver=null),o||e.track({channel:Ae,event:"dead_click",tags:{__path:window.location.pathname,__tag:r.tagName.toLowerCase(),__id:r.id||"",__class:r.className&&typeof r.className=="string"?r.className:"",__text:(r.textContent||"").trim().slice(0,100),__selector:G(r)}}).catch(a=>e.log("Failed to track dead click",a))},rt)},document.addEventListener("click",this.clickListener,!0),e.log("Frustration signal detection enabled")}teardown(){this.clickListener&&(document.removeEventListener("click",this.clickListener,!0),this.clickListener=null),this.deadClickObserver&&(this.deadClickObserver.disconnect(),this.deadClickObserver=null),this.deadClickTimeout!==null&&(clearTimeout(this.deadClickTimeout),this.deadClickTimeout=null),this.rageClickBuffer=[]}};function H(n){let e=[];return n?.autoTrackPageViews!==!1&&e.push(new I),n?.autoTrackOutboundLinks!==!1&&e.push(new B),n?.autoTrackClicks!==!1&&e.push(new R),n?.autoTrackScrollDepth!==!1&&e.push(new M),n?.autoTrackVisibility!==!1&&e.push(new N),n?.autoTrackWebVitals===!0&&e.push(new F),n?.autoDetectFrustration!==!1&&e.push(new j),e}if(typeof window<"u"&&window.KITBASE_CONFIG)try{window.kitbase=new C(window.KITBASE_CONFIG,H(window.KITBASE_CONFIG.analytics)),window.KITBASE_CONFIG.debug&&console.log("[Kitbase] Auto-initialized from window.KITBASE_CONFIG")}catch(n){console.error("[Kitbase] Failed to auto-initialize:",n)}return Re(ot);})();
1
+ "use strict";var Kitbase=(()=>{var $=Object.defineProperty;var Se=Object.getOwnPropertyDescriptor;var De=Object.getOwnPropertyNames;var Oe=Object.prototype.hasOwnProperty;var Ie=(n,e)=>{for(var t in e)$(n,t,{get:e[t],enumerable:!0})},Be=(n,e,t,i)=>{if(e&&typeof e=="object"||typeof e=="function")for(let s of De(e))!Oe.call(n,s)&&s!==t&&$(n,s,{get:()=>e[s],enumerable:!(i=Se(e,s))||i.enumerable});return n};var Re=n=>Be($({},"__esModule",{value:!0}),n);var ot={};Ie(ot,{ApiError:()=>k,AuthenticationError:()=>y,DEFAULT_BOT_DETECTION_CONFIG:()=>E,KitbaseAnalytics:()=>C,KitbaseError:()=>p,TimeoutError:()=>w,ValidationError:()=>v,createDefaultPlugins:()=>H,detectBot:()=>g,getUserAgent:()=>ue,isBot:()=>le,isUserAgentBot:()=>ce});var p=class n extends Error{constructor(e){super(e),this.name="KitbaseError",Object.setPrototypeOf(this,n.prototype)}},y=class n extends p{constructor(e="Invalid API key"){super(e),this.name="AuthenticationError",Object.setPrototypeOf(this,n.prototype)}},k=class n extends p{statusCode;response;constructor(e,t,i){super(e),this.name="ApiError",this.statusCode=t,this.response=i,Object.setPrototypeOf(this,n.prototype)}},v=class n extends p{field;constructor(e,t){super(e),this.name="ValidationError",this.field=t,Object.setPrototypeOf(this,n.prototype)}},w=class n extends p{constructor(e="Request timed out"){super(e),this.name="TimeoutError",Object.setPrototypeOf(this,n.prototype)}};var Me=["__webdriver_evaluate","__selenium_evaluate","__webdriver_script_function","__webdriver_unwrapped","__fxdriver_evaluate","__driver_evaluate","_Selenium_IDE_Recorder","_selenium","calledSelenium","$cdc_asdjflasutopfhvcZLmcfl_","__nightmare","domAutomation","domAutomationController"],oe=["headlesschrome","phantomjs","selenium","webdriver","puppeteer","playwright"],ae=["python","curl","wget","java/","go-http","node-fetch","axios","postman","insomnia","httpie","ruby","perl","scrapy","bot","spider","crawler","slurp","googlebot","bingbot","yandexbot","baiduspider","duckduckbot","facebookexternalhit","twitterbot","linkedinbot","whatsapp","telegram","discord","slack"],E={enabled:!0,checkWebdriver:!0,checkPhantomJS:!0,checkNightmare:!0,checkAutomationGlobals:!0,checkDocumentAttributes:!0,checkUserAgentHeadless:!0,checkUserAgentHttpClient:!0};function d(){return typeof window<"u"&&typeof document<"u"}function L(n){try{return window[n]}catch{return}}function Ne(){if(!d())return!1;try{return window.navigator?.webdriver===!0}catch{return!1}}function Ue(){if(!d())return!1;try{return!!(L("callPhantom")||L("_phantom")||L("phantom"))}catch{return!1}}function Ke(){if(!d())return!1;try{return!!L("__nightmare")}catch{return!1}}function Ve(){if(!d())return!1;try{for(let n of Me)if(L(n)!==void 0)return!0;return!1}catch{return!1}}function Fe(){if(!d())return!1;try{let n=document.documentElement;return n?!!(n.getAttribute("webdriver")||n.getAttribute("selenium")||n.getAttribute("driver")):!1}catch{return!1}}function je(){if(!d())return!1;try{let n=window.navigator?.userAgent?.toLowerCase()||"";if(!n)return!1;for(let e of oe)if(n.includes(e))return!0;return!1}catch{return!1}}function He(n){if(!d())return!1;try{let e=window.navigator?.userAgent?.toLowerCase()||"";if(!e)return!1;for(let t of ae)if(e.includes(t))return!0;if(n){for(let t of n)if(e.includes(t.toLowerCase()))return!0}return!1}catch{return!1}}function We(){if(!d())return!1;try{let n=window.navigator?.userAgent;return!n||n===""||n==="undefined"||n.length<10}catch{return!1}}function $e(){if(!d())return!1;try{return!window.navigator||!window.location||!window.document||typeof window.navigator!="object"||typeof window.location!="object"||typeof window.document!="object"}catch{return!0}}function g(n={}){let e={...E,...n},t={webdriver:e.checkWebdriver?Ne():!1,phantomjs:e.checkPhantomJS?Ue():!1,nightmare:e.checkNightmare?Ke():!1,automationGlobals:e.checkAutomationGlobals?Ve():!1,documentAttributes:e.checkDocumentAttributes?Fe():!1,userAgentHeadless:e.checkUserAgentHeadless?je():!1,userAgentHttpClient:e.checkUserAgentHttpClient?He(n.additionalBotPatterns):!1,missingUserAgent:We(),invalidEnvironment:$e()},i;t.webdriver?i="WebDriver detected":t.phantomjs?i="PhantomJS detected":t.nightmare?i="Nightmare.js detected":t.automationGlobals?i="Automation tool globals detected":t.documentAttributes?i="Automation attributes on document element":t.userAgentHeadless?i="Headless browser user agent detected":t.userAgentHttpClient?i="HTTP client/bot user agent detected":t.missingUserAgent?i="Missing or invalid user agent":t.invalidEnvironment&&(i="Invalid browser environment");let s=Object.values(t).some(Boolean),r={isBot:s,reason:i,checks:t};if(s&&n.onBotDetected)try{n.onBotDetected(r)}catch{}return r}function le(n={}){return g(n).isBot}function ce(n,e){if(!n||n.length<10)return!0;let t=n.toLowerCase();for(let i of oe)if(t.includes(i))return!0;for(let i of ae)if(t.includes(i))return!0;if(e){for(let i of e)if(t.includes(i.toLowerCase()))return!0}return!1}function ue(){if(!d())return null;try{return window.navigator?.userAgent||null}catch{return null}}var S=["a","button","input","select","textarea",'[role="button"]','[role="link"]','[role="menuitem"]','[role="tab"]'].join(", ");function P(n){let e=n.composedPath?.();if(e){for(let i of e)if(i instanceof Element){if(i===document.documentElement)break;if(i.matches(S)){let s=i.getRootNode();return s instanceof ShadowRoot&&s.host instanceof Element?s.host:i}if(i.tagName.includes("-"))return i}}let t=n.target;return t?.closest?t.closest(S):null}function G(n){if(n.id)return`#${n.id}`;let e=n.tagName.toLowerCase(),t=n.className&&typeof n.className=="string"?"."+n.className.trim().split(/\s+/).slice(0,2).join("."):"";return t?`${e}${t}`:e}function D(n){let e=n.replace(/^www\./,"").split(".");return e.length>=2?e.slice(-2).join("."):n}function de(n,e){return D(n)===D(e)}function O(){if(typeof window>"u")return{};let n=new URLSearchParams(window.location.search),e={},t=["utm_source","utm_medium","utm_campaign","utm_term","utm_content"];for(let i of t){let s=n.get(i);s&&(e[`__${i}`]=s)}return e}var Ge="https://api.kitbase.dev",qe=3e4,Ye="__analytics",C=class n{sdkKey;baseUrl;superProperties={};timedEvents=new Map;debugMode;analyticsConfig;userId=null;botDetectionConfig;botDetectionResult=null;clientSessionId=null;lastActivityAt=0;static SESSION_TIMEOUT_MS=1800*1e3;_plugins=new Map;_pluginContext=null;constructor(e,t){if(!e.sdkKey)throw new v("SDK key is required","sdkKey");if(this.sdkKey=e.sdkKey,this.baseUrl=(e.baseUrl??Ge).replace(/\/+$/,""),this.debugMode=e.debug??!1,this.analyticsConfig=e.analytics,this.botDetectionConfig={...E,...e.botDetection},this.botDetectionConfig.enabled&&(this.botDetectionResult=g(this.botDetectionConfig),this.botDetectionResult.isBot?this.log("Bot detected",{reason:this.botDetectionResult.reason,checks:this.botDetectionResult.checks}):this.log("Bot detection enabled, no bot detected")),t)for(let i of t)this.use(i)}use(e){if(this._plugins.has(e.name)){this.log(`Plugin "${e.name}" already registered`);return}let t=this.getPluginContext();if(e.setup(t)===!1){this.log(`Plugin "${e.name}" declined to activate`);return}this._plugins.set(e.name,e);let s=e.methods;if(s)for(let[r,o]of Object.entries(s))this[r]=o;this.log(`Plugin "${e.name}" registered`)}getPlugins(){return Array.from(this._plugins.keys())}getPluginContext(){return this._pluginContext?this._pluginContext:(this._pluginContext={track:e=>this.track(e),config:Object.freeze({autoTrackPageViews:this.analyticsConfig?.autoTrackPageViews,autoTrackOutboundLinks:this.analyticsConfig?.autoTrackOutboundLinks,autoTrackClicks:this.analyticsConfig?.autoTrackClicks,autoTrackScrollDepth:this.analyticsConfig?.autoTrackScrollDepth,autoTrackVisibility:this.analyticsConfig?.autoTrackVisibility,autoTrackWebVitals:this.analyticsConfig?.autoTrackWebVitals,autoDetectFrustration:this.analyticsConfig?.autoDetectFrustration}),debug:this.debugMode,log:(e,t)=>this.log(e,t),isBotBlockingActive:()=>this.isBotBlockingActive(),findClickableElement:P,CLICKABLE_SELECTOR:S,getRootDomain:D,isSameRootDomain:de,getUtmParams:O},this._pluginContext)}setDebugMode(e){this.debugMode=e,this.log(`Debug mode ${e?"enabled":"disabled"}`)}isDebugMode(){return this.debugMode}log(e,t){if(!this.debugMode)return;let i="[Kitbase]";t!==void 0?console.log(i,e,t):console.log(i,e)}register(e){this.superProperties={...this.superProperties,...e},this.log("Super properties registered",e)}registerOnce(e){let t={};for(let[i,s]of Object.entries(e))i in this.superProperties||(t[i]=s);Object.keys(t).length>0&&(this.superProperties={...this.superProperties,...t},this.log("Super properties registered (once)",t))}unregister(e){e in this.superProperties&&(delete this.superProperties[e],this.log("Super property removed",{key:e}))}getSuperProperties(){return{...this.superProperties}}clearSuperProperties(){this.superProperties={},this.log("Super properties cleared")}timeEvent(e){this.timedEvents.set(e,Date.now()),this.log("Timer started",{event:e})}cancelTimeEvent(e){this.timedEvents.has(e)&&(this.timedEvents.delete(e),this.log("Timer cancelled",{event:e}))}getTimedEvents(){return Array.from(this.timedEvents.keys())}getEventDuration(e){let t=this.timedEvents.get(e);return t===void 0?null:(Date.now()-t)/1e3}isBot(){return this.botDetectionConfig?.enabled?(this.botDetectionResult||(this.botDetectionResult=g(this.botDetectionConfig)),this.botDetectionResult.isBot):!1}getBotDetectionResult(){return this.botDetectionConfig.enabled?(this.botDetectionResult||(this.botDetectionResult=g(this.botDetectionConfig)),this.botDetectionResult):null}redetectBot(){return this.botDetectionResult=g(this.botDetectionConfig),this.log("Bot detection re-run",{isBot:this.botDetectionResult.isBot,reason:this.botDetectionResult.reason}),this.botDetectionResult}isBotBlockingActive(){return this.botDetectionConfig?.enabled===!0&&this.isBot()}getClientSessionId(){let e=Date.now();return(!this.clientSessionId||this.lastActivityAt>0&&e-this.lastActivityAt>n.SESSION_TIMEOUT_MS)&&(this.clientSessionId=n.generateUUID(),this.log("New client session started",{sessionId:this.clientSessionId})),this.lastActivityAt=e,this.clientSessionId}static generateUUID(){if(typeof crypto<"u"&&typeof crypto.randomUUID=="function")return crypto.randomUUID();if(typeof crypto<"u"&&typeof crypto.getRandomValues=="function"){let e=new Uint8Array(16);crypto.getRandomValues(e),e[6]=e[6]&15|64,e[8]=e[8]&63|128;let t=Array.from(e,i=>i.toString(16).padStart(2,"0")).join("");return`${t.slice(0,8)}-${t.slice(8,12)}-${t.slice(12,16)}-${t.slice(16,20)}-${t.slice(20)}`}return"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}async track(e){if(this.validateTrackOptions(e),this.isBotBlockingActive()){this.log("Event skipped - bot detected",{event:e.event});return}let t,i=this.timedEvents.get(e.event);i!==void 0&&(t=(Date.now()-i)/1e3,this.timedEvents.delete(e.event),this.log("Timer stopped",{event:e.event,duration:t}));let s={...this.superProperties,...e.tags??{},...t!==void 0?{$duration:t}:{}},r={channel:e.channel,event:e.event,client_timestamp:Date.now(),client_session_id:this.getClientSessionId(),...e.user_id&&{user_id:e.user_id},...e.icon&&{icon:e.icon},...e.notify!==void 0&&{notify:e.notify},...e.description&&{description:e.description},...Object.keys(s).length>0&&{tags:s}};this.log("Track",{event:e.event,payload:r});let o=await this.sendRequest("/sdk/v1/logs",r);return this.log("Event sent successfully",{id:o.id}),o}validateTrackOptions(e){if(!e.event)throw new v("Event is required","event")}async sendRequest(e,t){let i=`${this.baseUrl}${e}`,s=new AbortController,r=setTimeout(()=>s.abort(),qe);try{let o=await fetch(i,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":`${this.sdkKey}`},body:JSON.stringify(t),signal:s.signal});if(clearTimeout(r),!o.ok){let a=await this.parseResponseBody(o);throw o.status===401?new y:new k(this.getErrorMessage(a,o.statusText),o.status,a)}return await o.json()}catch(o){throw clearTimeout(r),o instanceof Error&&o.name==="AbortError"?new w:o}}async parseResponseBody(e){try{return await e.json()}catch{return null}}getErrorMessage(e,t){return e&&typeof e=="object"&&"message"in e?String(e.message):e&&typeof e=="object"&&"error"in e?String(e.error):t}async trackPageView(e){this.log("trackPageView() called but page-view plugin is not registered")}async trackClick(e){this.log("trackClick() called but click-tracking plugin is not registered")}async trackOutboundLink(e){this.log("trackOutboundLink() called but outbound-links plugin is not registered")}async trackRevenue(e){return this.track({channel:Ye,event:"revenue",user_id:e.user_id??this.userId??void 0,tags:{__revenue:e.amount,__currency:e.currency??"USD",...e.tags??{}}})}async identify(e){this.userId=e.userId,e.traits?this.register({__user_id:e.userId,...e.traits}):this.register({__user_id:e.userId});try{let t=await fetch(`${this.baseUrl}/sdk/v1/identify`,{method:"POST",headers:{"Content-Type":"application/json","x-sdk-key":this.sdkKey},body:JSON.stringify({user_id:e.userId,traits:e.traits})});t.ok?this.log("Identity set on server",{userId:e.userId}):this.log("Identify API call failed",{status:t.status})}catch(t){this.log("Failed to call identify endpoint",t)}this.log("User identified",{userId:e.userId})}getUserId(){return this.userId}reset(){this.userId=null,this.clientSessionId=null,this.lastActivityAt=0,this.clearSuperProperties(),this.log("User reset complete")}shutdown(){this.log("Shutting down"),this.timedEvents.clear();let e=Array.from(this._plugins.keys()).reverse();for(let t of e){let i=this._plugins.get(t);try{i.teardown(),this.log(`Plugin "${t}" torn down`)}catch(s){this.log(`Plugin "${t}" teardown failed`,s)}}this._plugins.clear(),this._pluginContext=null,this.log("Shutdown complete")}};var Je="__analytics",I=class{name="page-view";ctx;active=!1;popstateListener=null;pageshowListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.active=!0,Promise.resolve().then(()=>{this.active&&this.trackPageView().catch(s=>e.log("Failed to track initial page view",s))});let t=history.pushState.bind(history);history.pushState=(...s)=>{t(...s),this.active&&this.trackPageView().catch(r=>e.log("Failed to track page view (pushState)",r))};let i=history.replaceState.bind(history);history.replaceState=(...s)=>{i(...s)},this.popstateListener=()=>{this.active&&this.trackPageView().catch(s=>e.log("Failed to track page view (popstate)",s))},window.addEventListener("popstate",this.popstateListener),e.config.trackBfcacheRestore!==!1&&(this.pageshowListener=s=>{s.persisted&&this.active&&this.trackPageView().catch(r=>e.log("Failed to track page view (bfcache)",r))},window.addEventListener("pageshow",this.pageshowListener)),e.log("Auto page view tracking enabled")}teardown(){this.active=!1,this.popstateListener&&(window.removeEventListener("popstate",this.popstateListener),this.popstateListener=null),this.pageshowListener&&(window.removeEventListener("pageshow",this.pageshowListener),this.pageshowListener=null)}get methods(){return{trackPageView:e=>this.trackPageView(e)}}async trackPageView(e={}){let t=e.path??(typeof window<"u"?window.location.pathname:""),i=e.title??(typeof document<"u"?document.title:""),s=e.referrer??(typeof document<"u"?document.referrer:"");return this.ctx.track({channel:Je,event:"screen_view",tags:{__path:t,__title:i,__referrer:s,...O(),...e.tags??{}}})}};var ze="__analytics",B=class{name="outbound-links";ctx;clickListener=null;keydownListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.clickListener=t=>{let i=t.target?.closest?.("a");i&&this.handleLinkClick(i)},this.keydownListener=t=>{if(t.key==="Enter"||t.key===" "){let i=t.target?.closest?.("a");i&&this.handleLinkClick(i)}},document.addEventListener("click",this.clickListener),document.addEventListener("keydown",this.keydownListener),e.log("Outbound link tracking enabled")}teardown(){this.clickListener&&(document.removeEventListener("click",this.clickListener),this.clickListener=null),this.keydownListener&&(document.removeEventListener("keydown",this.keydownListener),this.keydownListener=null)}get methods(){return{trackOutboundLink:e=>this.trackOutboundLink(e)}}handleLinkClick(e){if(e.href)try{let t=new URL(e.href);if(t.protocol!=="http:"&&t.protocol!=="https:")return;let i=window.location.hostname,s=t.hostname;if(s===i||this.ctx.isSameRootDomain(i,s))return;this.trackOutboundLink({url:e.href,text:e.textContent?.trim()||""}).catch(r=>this.ctx.log("Failed to track outbound link",r))}catch{}}async trackOutboundLink(e){return this.ctx.track({channel:ze,event:"outbound_link",tags:{__url:e.url,__text:e.text||""}})}};var Xe="__analytics",R=class{name="click-tracking";ctx;clickListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.clickListener=t=>{let s=t.target?.closest?.("[data-kb-track-click]");if(s){let m=s.getAttribute("data-kb-track-click");if(m){let b=s.getAttribute("data-kb-click-channel")||"engagement";e.track({channel:b,event:m,tags:{__path:window.location.pathname}}).catch(xe=>e.log("Failed to track data-attribute click",xe));return}}let r=e.findClickableElement(t);if(!r)return;if(e.config.autoTrackOutboundLinks!==!1){let m=r.href||r.getAttribute("href")||"";if(m)try{let b=new URL(m,window.location.origin);if((b.protocol==="http:"||b.protocol==="https:")&&b.hostname!==window.location.hostname&&!e.isSameRootDomain(window.location.hostname,b.hostname))return}catch{}}let o=r.tagName.toLowerCase(),a=r.id||"",c=r.className&&typeof r.className=="string"?r.className:"",l=(r.textContent||"").trim().slice(0,100),u=r.href||r.getAttribute("href")||"",W=window.location.pathname;this.trackClick({__tag:o,__id:a,__class:c,__text:l,__href:u,__path:W}).catch(m=>e.log("Failed to track click",m))},document.addEventListener("click",this.clickListener),e.log("Click tracking enabled")}teardown(){this.clickListener&&(document.removeEventListener("click",this.clickListener),this.clickListener=null)}get methods(){return{trackClick:e=>this.trackClick(e)}}async trackClick(e){return this.ctx.track({channel:Xe,event:"click",tags:e})}};var Ze="__analytics",M=class{name="scroll-depth";ctx;active=!1;maxScrollDepth=0;scrollListener=null;beforeUnloadListener=null;popstateListener=null;scrollRafScheduled=!1;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.active=!0,this.scrollListener=()=>{this.scrollRafScheduled||(this.scrollRafScheduled=!0,requestAnimationFrame(()=>{this.scrollRafScheduled=!1;let s=window.scrollY||document.documentElement.scrollTop,r=window.innerHeight,o=Math.max(document.body.scrollHeight,document.documentElement.scrollHeight);if(o<=0)return;let a=Math.min(100,Math.round((s+r)/o*100));a>this.maxScrollDepth&&(this.maxScrollDepth=a)}))},this.beforeUnloadListener=()=>{this.flushScrollDepth()},window.addEventListener("scroll",this.scrollListener,{passive:!0}),window.addEventListener("beforeunload",this.beforeUnloadListener);let t=history.pushState,i=this;history.pushState=function(...s){return i.active&&i.flushScrollDepth(),t.apply(this,s)},this.popstateListener=()=>{this.active&&this.flushScrollDepth()},window.addEventListener("popstate",this.popstateListener),e.log("Scroll depth tracking enabled")}teardown(){this.active=!1,this.flushScrollDepth(),this.scrollListener&&(window.removeEventListener("scroll",this.scrollListener),this.scrollListener=null),this.beforeUnloadListener&&(window.removeEventListener("beforeunload",this.beforeUnloadListener),this.beforeUnloadListener=null),this.popstateListener&&(window.removeEventListener("popstate",this.popstateListener),this.popstateListener=null)}flushScrollDepth(){if(this.maxScrollDepth>0){let e=typeof window<"u"?window.location.pathname:"";this.ctx.track({channel:Ze,event:"scroll_depth",tags:{__depth:this.maxScrollDepth,__path:e}}).catch(t=>this.ctx.log("Failed to track scroll depth",t)),this.maxScrollDepth=0}}};var N=class{name="visibility";ctx;active=!1;visibilityObservers=new Map;visibilityMutationObserver=null;visibilityData=new Map;beforeUnloadListener=null;popstateListener=null;setup(e){if(typeof window>"u"||typeof IntersectionObserver>"u"||typeof MutationObserver>"u")return!1;this.ctx=e,this.active=!0,this.scanForVisibilityElements(),this.visibilityMutationObserver=new MutationObserver(s=>{for(let r of s){for(let o of Array.from(r.addedNodes))if(o instanceof Element){this.observeVisibilityElement(o);for(let a of Array.from(o.querySelectorAll("[data-kb-track-visibility]")))this.observeVisibilityElement(a)}for(let o of Array.from(r.removedNodes))if(o instanceof Element){this.flushVisibilityForElement(o);for(let a of Array.from(o.querySelectorAll("[data-kb-track-visibility]")))this.flushVisibilityForElement(a)}}}),this.visibilityMutationObserver.observe(document.body,{childList:!0,subtree:!0}),this.beforeUnloadListener=()=>{this.flushAllVisibilityEvents()},window.addEventListener("beforeunload",this.beforeUnloadListener);let t=history.pushState,i=this;history.pushState=function(...s){return i.active&&i.flushAllVisibilityEvents(),t.apply(this,s)},this.popstateListener=()=>{this.active&&this.flushAllVisibilityEvents()},window.addEventListener("popstate",this.popstateListener),e.log("Visibility tracking enabled")}teardown(){this.active=!1,this.flushAllVisibilityEvents();for(let e of this.visibilityObservers.values())e.disconnect();this.visibilityObservers.clear(),this.visibilityMutationObserver&&(this.visibilityMutationObserver.disconnect(),this.visibilityMutationObserver=null),this.beforeUnloadListener&&(window.removeEventListener("beforeunload",this.beforeUnloadListener),this.beforeUnloadListener=null),this.popstateListener&&(window.removeEventListener("popstate",this.popstateListener),this.popstateListener=null),this.visibilityData.clear()}scanForVisibilityElements(){for(let e of Array.from(document.querySelectorAll("[data-kb-track-visibility]")))this.observeVisibilityElement(e)}observeVisibilityElement(e){let t=e.getAttribute("data-kb-track-visibility");if(!t||this.visibilityData.has(e))return;let i=e.getAttribute("data-kb-visibility-channel")||"engagement",s=parseFloat(e.getAttribute("data-kb-visibility-threshold")||"0.5"),r=Math.max(0,Math.min(1,isNaN(s)?.5:s));this.visibilityData.set(e,{visibleSince:null,totalMs:0,event:t,channel:i}),this.getOrCreateObserver(r).observe(e)}getOrCreateObserver(e){let t=Math.round(e*100),i=this.visibilityObservers.get(t);return i||(i=new IntersectionObserver(s=>{let r=Date.now();for(let o of s){let a=this.visibilityData.get(o.target);a&&(o.isIntersecting?a.visibleSince=r:a.visibleSince!==null&&(a.totalMs+=r-a.visibleSince,a.visibleSince=null))}},{threshold:e}),this.visibilityObservers.set(t,i),i)}flushVisibilityForElement(e){let t=this.visibilityData.get(e);if(t){if(t.visibleSince!==null&&(t.totalMs+=Date.now()-t.visibleSince,t.visibleSince=null),t.totalMs>0){let i=Math.round(t.totalMs),s=Math.round(i/1e3);this.ctx.track({channel:t.channel,event:"element_visible",tags:{__element_name:t.event,__duration_seconds:s,__duration_ms:i}}).catch(r=>this.ctx.log("Failed to track visibility event",r))}for(let i of this.visibilityObservers.values())i.unobserve(e);this.visibilityData.delete(e)}}flushAllVisibilityEvents(){for(let[,e]of this.visibilityData.entries()){if(e.visibleSince!==null&&(e.totalMs+=Date.now()-e.visibleSince,e.visibleSince=null),e.totalMs>0){let t=Math.round(e.totalMs),i=Math.round(t/1e3);this.ctx.track({channel:e.channel,event:"element_visible",tags:{element_name:e.event,duration_seconds:i,duration_ms:t}}).catch(s=>this.ctx.log("Failed to track visibility event",s))}e.totalMs=0,e.visibleSince=null}}};var ke=-1,_=n=>{addEventListener("pageshow",(e=>{e.persisted&&(ke=e.timeStamp,n(e))}),!0)},h=(n,e,t,i)=>{let s,r;return o=>{e.value>=0&&(o||i)&&(r=e.value-(s??0),(r||s===void 0)&&(s=e.value,e.delta=r,e.rating=((a,c)=>a>c[1]?"poor":a>c[0]?"needs-improvement":"good")(e.value,t),n(e)))}},te=n=>{requestAnimationFrame((()=>requestAnimationFrame((()=>n()))))},ie=()=>{let n=performance.getEntriesByType("navigation")[0];if(n&&n.responseStart>0&&n.responseStart<performance.now())return n},A=()=>ie()?.activationStart??0,f=(n,e=-1)=>{let t=ie(),i="navigate";return ke>=0?i="back-forward-cache":t&&(document.prerendering||A()>0?i="prerender":document.wasDiscarded?i="restore":t.type&&(i=t.type.replace(/_/g,"-"))),{name:n,value:e,rating:"good",delta:0,entries:[],id:`v5-${Date.now()}-${Math.floor(8999999999999*Math.random())+1e12}`,navigationType:i}},q=new WeakMap;function ne(n,e){return q.get(n)||q.set(n,new e),q.get(n)}var J=class{t;i=0;o=[];h(e){if(e.hadRecentInput)return;let t=this.o[0],i=this.o.at(-1);this.i&&t&&i&&e.startTime-i.startTime<1e3&&e.startTime-t.startTime<5e3?(this.i+=e.value,this.o.push(e)):(this.i=e.value,this.o=[e]),this.t?.(e)}},x=(n,e,t={})=>{try{if(PerformanceObserver.supportedEntryTypes.includes(n)){let i=new PerformanceObserver((s=>{Promise.resolve().then((()=>{e(s.getEntries())}))}));return i.observe({type:n,buffered:!0,...t}),i}}catch{}},se=n=>{let e=!1;return()=>{e||(n(),e=!0)}},T=-1,we=new Set,he=()=>document.visibilityState!=="hidden"||document.prerendering?1/0:0,z=n=>{if(document.visibilityState==="hidden"){if(n.type==="visibilitychange")for(let e of we)e();isFinite(T)||(T=n.type==="visibilitychange"?n.timeStamp:0,removeEventListener("prerenderingchange",z,!0))}},K=()=>{if(T<0){let n=A();T=(document.prerendering?void 0:globalThis.performance.getEntriesByType("visibility-state").filter((t=>t.name==="hidden"&&t.startTime>n))[0]?.startTime)??he(),addEventListener("visibilitychange",z,!0),addEventListener("prerenderingchange",z,!0),_((()=>{setTimeout((()=>{T=he()}))}))}return{get firstHiddenTime(){return T},onHidden(n){we.add(n)}}},V=n=>{document.prerendering?addEventListener("prerenderingchange",(()=>n()),!0):n()},fe=[1800,3e3],re=(n,e={})=>{V((()=>{let t=K(),i,s=f("FCP"),r=x("paint",(o=>{for(let a of o)a.name==="first-contentful-paint"&&(r.disconnect(),a.startTime<t.firstHiddenTime&&(s.value=Math.max(a.startTime-A(),0),s.entries.push(a),i(!0)))}));r&&(i=h(n,s,fe,e.reportAllChanges),_((o=>{s=f("FCP"),i=h(n,s,fe,e.reportAllChanges),te((()=>{s.value=performance.now()-o.timeStamp,i(!0)}))})))}))},pe=[.1,.25],Ce=(n,e={})=>{let t=K();re(se((()=>{let i,s=f("CLS",0),r=ne(e,J),o=c=>{for(let l of c)r.h(l);r.i>s.value&&(s.value=r.i,s.entries=r.o,i())},a=x("layout-shift",o);a&&(i=h(n,s,pe,e.reportAllChanges),t.onHidden((()=>{o(a.takeRecords()),i(!0)})),_((()=>{r.i=0,s=f("CLS",0),i=h(n,s,pe,e.reportAllChanges),te((()=>i()))})),setTimeout(i))})))},Te=0,Y=1/0,U=0,Qe=n=>{for(let e of n)e.interactionId&&(Y=Math.min(Y,e.interactionId),U=Math.max(U,e.interactionId),Te=U?(U-Y)/7+1:0)},X,ge=()=>X?Te:performance.interactionCount??0,et=()=>{"interactionCount"in performance||X||(X=x("event",Qe,{type:"event",buffered:!0,durationThreshold:0}))},me=0,Z=class{u=[];l=new Map;m;p;v(){me=ge(),this.u.length=0,this.l.clear()}L(){let e=Math.min(this.u.length-1,Math.floor((ge()-me)/50));return this.u[e]}h(e){if(this.m?.(e),!e.interactionId&&e.entryType!=="first-input")return;let t=this.u.at(-1),i=this.l.get(e.interactionId);if(i||this.u.length<10||e.duration>t.P){if(i?e.duration>i.P?(i.entries=[e],i.P=e.duration):e.duration===i.P&&e.startTime===i.entries[0].startTime&&i.entries.push(e):(i={id:e.interactionId,entries:[e],P:e.duration},this.l.set(i.id,i),this.u.push(i)),this.u.sort(((s,r)=>r.P-s.P)),this.u.length>10){let s=this.u.splice(10);for(let r of s)this.l.delete(r.id)}this.p?.(i)}}},_e=n=>{let e=globalThis.requestIdleCallback||setTimeout;document.visibilityState==="hidden"?n():(n=se(n),addEventListener("visibilitychange",n,{once:!0,capture:!0}),e((()=>{n(),removeEventListener("visibilitychange",n,{capture:!0})})))},ve=[200,500],Le=(n,e={})=>{if(!globalThis.PerformanceEventTiming||!("interactionId"in PerformanceEventTiming.prototype))return;let t=K();V((()=>{et();let i,s=f("INP"),r=ne(e,Z),o=c=>{_e((()=>{for(let u of c)r.h(u);let l=r.L();l&&l.P!==s.value&&(s.value=l.P,s.entries=l.entries,i())}))},a=x("event",o,{durationThreshold:e.durationThreshold??40});i=h(n,s,ve,e.reportAllChanges),a&&(a.observe({type:"first-input",buffered:!0}),t.onHidden((()=>{o(a.takeRecords()),i(!0)})),_((()=>{r.v(),s=f("INP"),i=h(n,s,ve,e.reportAllChanges)})))}))},Q=class{m;h(e){this.m?.(e)}},be=[2500,4e3],Ee=(n,e={})=>{V((()=>{let t=K(),i,s=f("LCP"),r=ne(e,Q),o=c=>{e.reportAllChanges||(c=c.slice(-1));for(let l of c)r.h(l),l.startTime<t.firstHiddenTime&&(s.value=Math.max(l.startTime-A(),0),s.entries=[l],i())},a=x("largest-contentful-paint",o);if(a){i=h(n,s,be,e.reportAllChanges);let c=se((()=>{o(a.takeRecords()),a.disconnect(),i(!0)})),l=u=>{u.isTrusted&&(_e(c),removeEventListener(u.type,l,{capture:!0}))};for(let u of["keydown","click","visibilitychange"])addEventListener(u,l,{capture:!0});_((u=>{s=f("LCP"),i=h(n,s,be,e.reportAllChanges),te((()=>{s.value=performance.now()-u.timeStamp,i(!0)}))}))}}))},ye=[800,1800],ee=n=>{document.prerendering?V((()=>ee(n))):document.readyState!=="complete"?addEventListener("load",(()=>ee(n)),!0):setTimeout(n)},Pe=(n,e={})=>{let t=f("TTFB"),i=h(n,t,ye,e.reportAllChanges);ee((()=>{let s=ie();s&&(t.value=Math.max(s.responseStart-A(),0),t.entries=[s],i(!0),_((()=>{t=f("TTFB",0),i=h(n,t,ye,e.reportAllChanges),i(!0)})))}))};var tt="__analytics",F=class{name="web-vitals";ctx;sent=!1;timeout=null;beforeUnloadListener=null;data={lcp:null,cls:null,inp:null,fcp:null,ttfb:null};setup(e){if(typeof window>"u")return!1;this.ctx=e;let t=()=>{let{lcp:i,cls:s,inp:r,fcp:o,ttfb:a}=this.data;i!==null&&s!==null&&r!==null&&o!==null&&a!==null&&this.sendWebVitals()};Ee(i=>{this.data.lcp=i.value,e.log("Web Vital collected",{name:"LCP",value:i.value}),t()}),Ce(i=>{this.data.cls=i.value,e.log("Web Vital collected",{name:"CLS",value:i.value}),t()}),Le(i=>{this.data.inp=i.value,e.log("Web Vital collected",{name:"INP",value:i.value}),t()}),re(i=>{this.data.fcp=i.value,e.log("Web Vital collected",{name:"FCP",value:i.value}),t()}),Pe(i=>{this.data.ttfb=i.value,e.log("Web Vital collected",{name:"TTFB",value:i.value}),t()}),this.timeout=setTimeout(()=>{this.timeout=null,this.sendWebVitals()},3e4),this.beforeUnloadListener=()=>{this.sendWebVitals()},window.addEventListener("beforeunload",this.beforeUnloadListener),e.log("Web Vitals tracking enabled")}teardown(){this.timeout!==null&&(clearTimeout(this.timeout),this.timeout=null),this.sendWebVitals(),this.beforeUnloadListener&&(window.removeEventListener("beforeunload",this.beforeUnloadListener),this.beforeUnloadListener=null)}sendWebVitals(){if(this.sent)return;let{lcp:e,cls:t,inp:i,fcp:s,ttfb:r}=this.data;if(e===null&&t===null&&i===null&&s===null&&r===null)return;this.sent=!0,this.timeout!==null&&(clearTimeout(this.timeout),this.timeout=null);let o={};e!==null&&(o.__lcp=e),t!==null&&(o.__cls=t),i!==null&&(o.__inp=i),s!==null&&(o.__fcp=s),r!==null&&(o.__ttfb=r),this.ctx.log("Sending Web Vitals",o),this.ctx.track({channel:tt,event:"web_vitals",tags:o}).catch(a=>this.ctx.log("Failed to track web vitals",a))}};var Ae="__analytics",it=3,nt=1e3,st=30,rt=1e3,j=class{name="frustration";ctx;rageClickBuffer=[];deadClickObserver=null;deadClickTimeout=null;clickListener=null;setup(e){if(typeof window>"u")return!1;this.ctx=e,this.clickListener=t=>{let i=t.target;if(!i)return;let s=Date.now();if(this.rageClickBuffer.push({time:s,x:t.clientX,y:t.clientY,target:i}),this.rageClickBuffer=this.rageClickBuffer.filter(a=>s-a.time<nt),this.rageClickBuffer.length>=it){let a=this.rageClickBuffer[0];if(this.rageClickBuffer.every(l=>Math.hypot(l.x-a.x,l.y-a.y)<st)){let l=P(t)||i,u=this.rageClickBuffer.length;this.rageClickBuffer=[],e.track({channel:Ae,event:"rage_click",tags:{__path:window.location.pathname,__tag:l.tagName.toLowerCase(),__id:l.id||"",__class:l.className&&typeof l.className=="string"?l.className:"",__text:(l.textContent||"").trim().slice(0,100),__selector:G(l),__click_count:u}}).catch(W=>e.log("Failed to track rage click",W));return}}let r=P(t);if(!r||i.closest?.("a[href]")||r.tagName==="SELECT"||i.closest?.("select"))return;this.deadClickTimeout!==null&&(clearTimeout(this.deadClickTimeout),this.deadClickTimeout=null),this.deadClickObserver&&this.deadClickObserver.disconnect();let o=!1;this.deadClickObserver=new MutationObserver(()=>{o=!0}),this.deadClickObserver.observe(document.body,{childList:!0,subtree:!0,attributes:!0,characterData:!0}),this.deadClickTimeout=setTimeout(()=>{this.deadClickObserver&&(this.deadClickObserver.disconnect(),this.deadClickObserver=null),o||e.track({channel:Ae,event:"dead_click",tags:{__path:window.location.pathname,__tag:r.tagName.toLowerCase(),__id:r.id||"",__class:r.className&&typeof r.className=="string"?r.className:"",__text:(r.textContent||"").trim().slice(0,100),__selector:G(r)}}).catch(a=>e.log("Failed to track dead click",a))},rt)},document.addEventListener("click",this.clickListener,!0),e.log("Frustration signal detection enabled")}teardown(){this.clickListener&&(document.removeEventListener("click",this.clickListener,!0),this.clickListener=null),this.deadClickObserver&&(this.deadClickObserver.disconnect(),this.deadClickObserver=null),this.deadClickTimeout!==null&&(clearTimeout(this.deadClickTimeout),this.deadClickTimeout=null),this.rageClickBuffer=[]}};function H(n){let e=[];return n?.autoTrackPageViews!==!1&&e.push(new I),n?.autoTrackOutboundLinks!==!1&&e.push(new B),n?.autoTrackClicks!==!1&&e.push(new R),n?.autoTrackScrollDepth!==!1&&e.push(new M),n?.autoTrackVisibility!==!1&&e.push(new N),n?.autoTrackWebVitals===!0&&e.push(new F),n?.autoDetectFrustration!==!1&&e.push(new j),e}if(typeof window<"u"&&window.KITBASE_CONFIG)try{window.kitbase=new C(window.KITBASE_CONFIG,H(window.KITBASE_CONFIG.analytics)),window.KITBASE_CONFIG.debug&&console.log("[Kitbase] Auto-initialized from window.KITBASE_CONFIG")}catch(n){console.error("[Kitbase] Failed to auto-initialize:",n)}return Re(ot);})();
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kitbase/analytics",
3
- "version": "0.1.6",
3
+ "version": "0.1.7",
4
4
  "description": "Kitbase Analytics SDK for TypeScript and JavaScript",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",