@kryptonhq/analytics 0.1.2 → 0.1.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- "use strict";var KryptonAnalytics=(()=>{var Z=Object.defineProperty;var we=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var Ce=(e,t)=>{for(var r in t)Z(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Se(t))!be.call(e,n)&&n!==r&&Z(e,n,{get:()=>t[n],enumerable:!(i=we(t,n))||i.enumerable});return e};var Ie=e=>xe(Z({},"__esModule",{value:!0}),e);var at={};Ce(at,{Krypton:()=>q,default:()=>nt,init:()=>ye});var v;(function(e){e[e.Document=0]="Document",e[e.DocumentType=1]="DocumentType",e[e.Element=2]="Element",e[e.Text=3]="Text",e[e.CDATA=4]="CDATA",e[e.Comment=5]="Comment"})(v||(v={}));function Te(e){return e.nodeType===e.ELEMENT_NODE}function Ee(e){var t=e?.host;return t?.shadowRoot===e}function ee(e){return Object.prototype.toString.call(e)==="[object ShadowRoot]"}function Le(e){return e.includes(" background-clip: text;")&&!e.includes(" -webkit-background-clip: text;")&&(e=e.replace(" background-clip: text;"," -webkit-background-clip: text; background-clip: text;")),e}function te(e){try{var t=e.rules||e.cssRules;return t?Le(Array.from(t).map(Re).join("")):null}catch{return null}}function Re(e){var t=e.cssText;if(_e(e))try{t=te(e.styleSheet)||t}catch{}return t}function _e(e){return"styleSheet"in e}var Ne=(function(){function e(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap}return e.prototype.getId=function(t){var r;if(!t)return-1;var i=(r=this.getMeta(t))===null||r===void 0?void 0:r.id;return i??-1},e.prototype.getNode=function(t){return this.idNodeMap.get(t)||null},e.prototype.getIds=function(){return Array.from(this.idNodeMap.keys())},e.prototype.getMeta=function(t){return this.nodeMetaMap.get(t)||null},e.prototype.removeNodeFromMap=function(t){var r=this,i=this.getId(t);this.idNodeMap.delete(i),t.childNodes&&t.childNodes.forEach(function(n){return r.removeNodeFromMap(n)})},e.prototype.has=function(t){return this.idNodeMap.has(t)},e.prototype.hasNode=function(t){return this.nodeMetaMap.has(t)},e.prototype.add=function(t,r){var i=r.id;this.idNodeMap.set(i,t),this.nodeMetaMap.set(t,r)},e.prototype.replace=function(t,r){var i=this.getNode(t);if(i){var n=this.nodeMetaMap.get(i);n&&this.nodeMetaMap.set(r,n)}this.idNodeMap.set(t,r)},e.prototype.reset=function(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap},e})();function Oe(e){var t=e.maskInputOptions,r=e.tagName,i=e.type,n=e.value,a=e.maskInputFn,c=n||"";return(t[r.toLowerCase()]||t[i])&&(a?c=a(c):c="*".repeat(c.length)),c}var le="__rrweb_original__";function Me(e){var t=e.getContext("2d");if(!t)return!0;for(var r=50,i=0;i<e.width;i+=r)for(var n=0;n<e.height;n+=r){var a=t.getImageData,c=le in a?a[le]:a,u=new Uint32Array(c.call(t,i,n,Math.min(r,e.width-i),Math.min(r,e.height-n)).data.buffer);if(u.some(function(o){return o!==0}))return!1}return!0}var Ae=1,De=new RegExp("[^a-z0-9-_:]"),ue=-2;function Fe(){return Ae++}function Pe(e){if(e instanceof HTMLFormElement)return"form";var t=e.tagName.toLowerCase().trim();return De.test(t)?"div":t}function He(e){return e.cssRules?Array.from(e.cssRules).map(function(t){return t.cssText||""}).join(""):""}function Ue(e){var t="";return e.indexOf("//")>-1?t=e.split("/").slice(0,3).join("/"):t=e.split("/")[0],t=t.split("?")[0],t}var z,fe,We=/url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm,Ke=/^(?!www\.|(?:http|ftp)s?:\/\/|[A-Za-z]:\\|\/\/|#).*/,Be=/^(data:)([^,]*),(.*)/i;function $(e,t){return(e||"").replace(We,function(r,i,n,a,c,u){var o=n||c||u,f=i||a||"";if(!o)return r;if(!Ke.test(o)||Be.test(o))return"url(".concat(f).concat(o).concat(f,")");if(o[0]==="/")return"url(".concat(f).concat(Ue(t)+o).concat(f,")");var l=t.split("/"),h=o.split("/");l.pop();for(var b=0,k=h;b<k.length;b++){var w=k[b];w!=="."&&(w===".."?l.pop():l.push(w))}return"url(".concat(f).concat(l.join("/")).concat(f,")")})}var ze=/^[^ \t\n\r\u000c]+/,je=/^[, \t\n\r\u000c]+/;function qe(e,t){if(t.trim()==="")return t;var r=0;function i(f){var l,h=f.exec(t.substring(r));return h?(l=h[0],r+=l.length,l):""}for(var n=[];i(je),!(r>=t.length);){var a=i(ze);if(a.slice(-1)===",")a=j(e,a.substring(0,a.length-1)),n.push(a);else{var c="";a=j(e,a);for(var u=!1;;){var o=t.charAt(r);if(o===""){n.push((a+c).trim());break}else if(u)o===")"&&(u=!1);else if(o===","){r+=1,n.push((a+c).trim());break}else o==="("&&(u=!0);c+=o,r+=1}}}return n.join(", ")}function j(e,t){if(!t||t.trim()==="")return t;var r=e.createElement("a");return r.href=t,r.href}function Ge(e){return!!(e.tagName==="svg"||e.ownerSVGElement)}function ie(){var e=document.createElement("a");return e.href="",e.href}function Qe(e,t,r,i){return r==="src"||r==="href"&&i&&!(t==="use"&&i[0]==="#")||r==="xlink:href"&&i&&i[0]!=="#"||r==="background"&&i&&(t==="table"||t==="td"||t==="th")?j(e,i):r==="srcset"&&i?qe(e,i):r==="style"&&i?$(i,ie()):t==="object"&&r==="data"&&i?j(e,i):i}function $e(e,t,r){if(typeof t=="string"){if(e.classList.contains(t))return!0}else for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?e.matches(r):!1}function re(e,t,r){if(!e)return!1;if(e.nodeType!==e.ELEMENT_NODE)return r?re(e.parentNode,t,r):!1;for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?re(e.parentNode,t,r):!1}function Je(e,t,r){var i=e.nodeType===e.ELEMENT_NODE?e:e.parentElement;if(i===null)return!1;if(typeof t=="string"){if(i.classList.contains(t)||i.closest(".".concat(t)))return!0}else if(re(i,t,!0))return!0;return!!(r&&(i.matches(r)||i.closest(r)))}function Ve(e,t,r){var i=e.contentWindow;if(i){var n=!1,a;try{a=i.document.readyState}catch{return}if(a!=="complete"){var c=setTimeout(function(){n||(t(),n=!0)},r);e.addEventListener("load",function(){clearTimeout(c),n=!0,t()});return}var u="about:blank";if(i.location.href!==u||e.src===u||e.src==="")return setTimeout(t,0),e.addEventListener("load",t);e.addEventListener("load",t)}}function Ye(e,t,r){var i=!1,n;try{n=e.sheet}catch{return}if(!n){var a=setTimeout(function(){i||(t(),i=!0)},r);e.addEventListener("load",function(){clearTimeout(a),i=!0,t()})}}function Xe(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.inlineStylesheet,f=t.maskInputOptions,l=f===void 0?{}:f,h=t.maskTextFn,b=t.maskInputFn,k=t.dataURLOptions,w=k===void 0?{}:k,x=t.inlineImages,I=t.recordCanvas,T=t.keepIframeSrcFn,p=t.newlyAddedElement,s=p===void 0?!1:p,y=Ze(r,i);switch(e.nodeType){case e.DOCUMENT_NODE:return e.compatMode!=="CSS1Compat"?{type:v.Document,childNodes:[],compatMode:e.compatMode}:{type:v.Document,childNodes:[]};case e.DOCUMENT_TYPE_NODE:return{type:v.DocumentType,name:e.name,publicId:e.publicId,systemId:e.systemId,rootId:y};case e.ELEMENT_NODE:return tt(e,{doc:r,blockClass:n,blockSelector:a,inlineStylesheet:o,maskInputOptions:l,maskInputFn:b,dataURLOptions:w,inlineImages:x,recordCanvas:I,keepIframeSrcFn:T,newlyAddedElement:s,rootId:y});case e.TEXT_NODE:return et(e,{maskTextClass:c,maskTextSelector:u,maskTextFn:h,rootId:y});case e.CDATA_SECTION_NODE:return{type:v.CDATA,textContent:"",rootId:y};case e.COMMENT_NODE:return{type:v.Comment,textContent:e.textContent||"",rootId:y};default:return!1}}function Ze(e,t){if(t.hasNode(e)){var r=t.getId(e);return r===1?void 0:r}}function et(e,t){var r,i=t.maskTextClass,n=t.maskTextSelector,a=t.maskTextFn,c=t.rootId,u=e.parentNode&&e.parentNode.tagName,o=e.textContent,f=u==="STYLE"?!0:void 0,l=u==="SCRIPT"?!0:void 0;if(f&&o){try{e.nextSibling||e.previousSibling||!((r=e.parentNode.sheet)===null||r===void 0)&&r.cssRules&&(o=He(e.parentNode.sheet))}catch(h){console.warn("Cannot get CSS styles from text's parentNode. Error: ".concat(h),e)}o=$(o,ie())}return l&&(o="SCRIPT_PLACEHOLDER"),!f&&!l&&o&&Je(e,i,n)&&(o=a?a(o):o.replace(/[\S]/g,"*")),{type:v.Text,textContent:o||"",isStyle:f,rootId:c}}function tt(e,t){for(var r=t.doc,i=t.blockClass,n=t.blockSelector,a=t.inlineStylesheet,c=t.maskInputOptions,u=c===void 0?{}:c,o=t.maskInputFn,f=t.dataURLOptions,l=f===void 0?{}:f,h=t.inlineImages,b=t.recordCanvas,k=t.keepIframeSrcFn,w=t.newlyAddedElement,x=w===void 0?!1:w,I=t.rootId,T=$e(e,i,n),p=Pe(e),s={},y=e.attributes.length,M=0;M<y;M++){var E=e.attributes[M];s[E.name]=Qe(r,p,E.name,E.value)}if(p==="link"&&a){var C=Array.from(r.styleSheets).find(function(R){return R.href===e.href}),m=null;C&&(m=te(C)),m&&(delete s.rel,delete s.href,s._cssText=$(m,C.href))}if(p==="style"&&e.sheet&&!(e.innerText||e.textContent||"").trim().length){var m=te(e.sheet);m&&(s._cssText=$(m,ie()))}if(p==="input"||p==="textarea"||p==="select"){var P=e.value,_=e.checked;s.type!=="radio"&&s.type!=="checkbox"&&s.type!=="submit"&&s.type!=="button"&&P?s.value=Oe({type:s.type,tagName:p,value:P,maskInputOptions:u,maskInputFn:o}):_&&(s.checked=_)}if(p==="option"&&(e.selected&&!u.select?s.selected=!0:delete s.selected),p==="canvas"&&b){if(e.__context==="2d")Me(e)||(s.rr_dataURL=e.toDataURL(l.type,l.quality));else if(!("__context"in e)){var L=e.toDataURL(l.type,l.quality),A=document.createElement("canvas");A.width=e.width,A.height=e.height;var D=A.toDataURL(l.type,l.quality);L!==D&&(s.rr_dataURL=L)}}if(p==="img"&&h){z||(z=r.createElement("canvas"),fe=z.getContext("2d"));var S=e,N=S.crossOrigin;S.crossOrigin="anonymous";var F=function(){try{z.width=S.naturalWidth,z.height=S.naturalHeight,fe.drawImage(S,0,0),s.rr_dataURL=z.toDataURL(l.type,l.quality)}catch(R){console.warn("Cannot inline img src=".concat(S.currentSrc,"! Error: ").concat(R))}N?s.crossOrigin=N:S.removeAttribute("crossorigin")};S.complete&&S.naturalWidth!==0?F():S.onload=F}if((p==="audio"||p==="video")&&(s.rr_mediaState=e.paused?"paused":"played",s.rr_mediaCurrentTime=e.currentTime),x||(e.scrollLeft&&(s.rr_scrollLeft=e.scrollLeft),e.scrollTop&&(s.rr_scrollTop=e.scrollTop)),T){var U=e.getBoundingClientRect(),W=U.width,O=U.height;s={class:s.class,rr_width:"".concat(W,"px"),rr_height:"".concat(O,"px")}}return p==="iframe"&&!k(s.src)&&(e.contentDocument||(s.rr_src=s.src),delete s.src),{type:v.Element,tagName:p,attributes:s,childNodes:[],isSVG:Ge(e)||void 0,needBlock:T,rootId:I}}function d(e){return e===void 0?"":e.toLowerCase()}function rt(e,t){if(t.comment&&e.type===v.Comment)return!0;if(e.type===v.Element){if(t.script&&(e.tagName==="script"||e.tagName==="link"&&e.attributes.rel==="preload"&&e.attributes.as==="script"||e.tagName==="link"&&e.attributes.rel==="prefetch"&&typeof e.attributes.href=="string"&&e.attributes.href.endsWith(".js")))return!0;if(t.headFavicon&&(e.tagName==="link"&&e.attributes.rel==="shortcut icon"||e.tagName==="meta"&&(d(e.attributes.name).match(/^msapplication-tile(image|color)$/)||d(e.attributes.name)==="application-name"||d(e.attributes.rel)==="icon"||d(e.attributes.rel)==="apple-touch-icon"||d(e.attributes.rel)==="shortcut icon")))return!0;if(e.tagName==="meta"){if(t.headMetaDescKeywords&&d(e.attributes.name).match(/^description|keywords$/))return!0;if(t.headMetaSocial&&(d(e.attributes.property).match(/^(og|twitter|fb):/)||d(e.attributes.name).match(/^(og|twitter):/)||d(e.attributes.name)==="pinterest"))return!0;if(t.headMetaRobots&&(d(e.attributes.name)==="robots"||d(e.attributes.name)==="googlebot"||d(e.attributes.name)==="bingbot"))return!0;if(t.headMetaHttpEquiv&&e.attributes["http-equiv"]!==void 0)return!0;if(t.headMetaAuthorship&&(d(e.attributes.name)==="author"||d(e.attributes.name)==="generator"||d(e.attributes.name)==="framework"||d(e.attributes.name)==="publisher"||d(e.attributes.name)==="progid"||d(e.attributes.property).match(/^article:/)||d(e.attributes.property).match(/^product:/)))return!0;if(t.headMetaVerification&&(d(e.attributes.name)==="google-site-verification"||d(e.attributes.name)==="yandex-verification"||d(e.attributes.name)==="csrf-token"||d(e.attributes.name)==="p:domain_verify"||d(e.attributes.name)==="verify-v1"||d(e.attributes.name)==="verification"||d(e.attributes.name)==="shopify-checkout-api-token"))return!0}}return!1}function Q(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.skipChild,f=o===void 0?!1:o,l=t.inlineStylesheet,h=l===void 0?!0:l,b=t.maskInputOptions,k=b===void 0?{}:b,w=t.maskTextFn,x=t.maskInputFn,I=t.slimDOMOptions,T=t.dataURLOptions,p=T===void 0?{}:T,s=t.inlineImages,y=s===void 0?!1:s,M=t.recordCanvas,E=M===void 0?!1:M,C=t.onSerialize,m=t.onIframeLoad,P=t.iframeLoadTimeout,_=P===void 0?5e3:P,L=t.onStylesheetLoad,A=t.stylesheetLoadTimeout,D=A===void 0?5e3:A,S=t.keepIframeSrcFn,N=S===void 0?function(){return!1}:S,F=t.newlyAddedElement,U=F===void 0?!1:F,W=t.preserveWhiteSpace,O=W===void 0?!0:W,R=Xe(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,dataURLOptions:p,inlineImages:y,recordCanvas:E,keepIframeSrcFn:N,newlyAddedElement:U});if(!R)return console.warn(e,"not serialized"),null;var G;i.hasNode(e)?G=i.getId(e):rt(R,I)||!O&&R.type===v.Text&&!R.isStyle&&!R.textContent.replace(/^\s+|\s+$/gm,"").length?G=ue:G=Fe();var g=Object.assign(R,{id:G});if(i.add(e,g),G===ue)return null;C&&C(e);var J=!f;if(g.type===v.Element){J=J&&!g.needBlock,delete g.needBlock;var ne=e.shadowRoot;ne&&ee(ne)&&(g.isShadowHost=!0)}if((g.type===v.Document||g.type===v.Element)&&J){I.headWhitespace&&g.type===v.Element&&g.tagName==="head"&&(O=!1);for(var ae={doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:f,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:D,keepIframeSrcFn:N},V=0,oe=Array.from(e.childNodes);V<oe.length;V++){var Y=oe[V],K=Q(Y,ae);K&&g.childNodes.push(K)}if(Te(e)&&e.shadowRoot)for(var X=0,se=Array.from(e.shadowRoot.childNodes);X<se.length;X++){var Y=se[X],K=Q(Y,ae);K&&(ee(e.shadowRoot)&&(K.isShadow=!0),g.childNodes.push(K))}}return e.parentNode&&Ee(e.parentNode)&&ee(e.parentNode)&&(g.isShadow=!0),g.type===v.Element&&g.tagName==="iframe"&&Ve(e,function(){var B=e.contentDocument;if(B&&m){var ce=Q(B,{doc:B,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:D,keepIframeSrcFn:N});ce&&m(e,ce)}},_),g.type===v.Element&&g.tagName==="link"&&g.attributes.rel==="stylesheet"&&Ye(e,function(){if(L){var B=Q(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:k,maskTextFn:w,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:D,keepIframeSrcFn:N});B&&L(e,B)}},D),g}function de(e,t){var r=t||{},i=r.mirror,n=i===void 0?new Ne:i,a=r.blockClass,c=a===void 0?"rr-block":a,u=r.blockSelector,o=u===void 0?null:u,f=r.maskTextClass,l=f===void 0?"rr-mask":f,h=r.maskTextSelector,b=h===void 0?null:h,k=r.inlineStylesheet,w=k===void 0?!0:k,x=r.inlineImages,I=x===void 0?!1:x,T=r.recordCanvas,p=T===void 0?!1:T,s=r.maskAllInputs,y=s===void 0?!1:s,M=r.maskTextFn,E=r.maskInputFn,C=r.slimDOM,m=C===void 0?!1:C,P=r.dataURLOptions,_=r.preserveWhiteSpace,L=r.onSerialize,A=r.onIframeLoad,D=r.iframeLoadTimeout,S=r.onStylesheetLoad,N=r.stylesheetLoadTimeout,F=r.keepIframeSrcFn,U=F===void 0?function(){return!1}:F,W=y===!0?{color:!0,date:!0,"datetime-local":!0,email:!0,month:!0,number:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0,textarea:!0,select:!0,password:!0}:y===!1?{password:!0}:y,O=m===!0||m==="all"?{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:m==="all",headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0,headMetaVerification:!0}:m===!1?{}:m;return Q(e,{doc:e,mirror:n,blockClass:c,blockSelector:o,maskTextClass:l,maskTextSelector:b,skipChild:!1,inlineStylesheet:w,maskInputOptions:W,maskTextFn:M,maskInputFn:E,slimDOMOptions:O,dataURLOptions:P,inlineImages:I,recordCanvas:p,preserveWhiteSpace:_,onSerialize:L,onIframeLoad:A,iframeLoadTimeout:D,onStylesheetLoad:S,stylesheetLoadTimeout:N,keepIframeSrcFn:U,newlyAddedElement:!1})}var it=/([^\\]):hover/,st=new RegExp(it.source,"g");function H(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function pe(){let e="_krypton_sid";try{if(typeof sessionStorage<"u"){let t=sessionStorage.getItem(e);return t||(t=H(),sessionStorage.setItem(e,t)),t}}catch{}return H()}function he(){let e="_krypton_did";try{if(typeof localStorage<"u"){let t=localStorage.getItem(e);return t||(t=H(),localStorage.setItem(e,t)),t}}catch{}return H()}function me(){if(typeof window>"u")return{};let e=new URLSearchParams(window.location.search),t={};for(let r of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let i=e.get(r);i&&(t[r]=i)}return t}function ge(){if(typeof window>"u")return"unknown";let e=window.innerWidth;return e<768?"mobile":e<1024?"tablet":"desktop"}function ve(e){if(e.id)return`#${e.id}`;let t=[],r=e;for(;r&&r!==document.body;){let i=r.tagName.toLowerCase();if(r.id){t.unshift(`#${r.id}`);break}if(r.className&&typeof r.className=="string"){let n=r.className.trim().split(/\s+/).slice(0,2).join(".");n&&(i+=`.${n}`)}t.unshift(i),r=r.parentElement}return t.join(" > ")}var q=class{constructor(t){this.eventQueue=[];this.heatmapQueue=[];this.flushTimer=null;this.initialized=!1;this.lastSnapshotUrl=null;this.heatmapSetup=!1;this.geoRequested=!1;this.geoContext=null;this.serverConfig=null;this.configFetched=!1;this.config={autoPageview:!0,heatmap:!1,consentRequired:!1,showConsentBanner:!1,consentCategories:{},flushInterval:5e3,batchSize:20,...t},this.distinctId=H(),this.sessionId=H(),this.consent=this.resolveInitialConsent(),this.canTrackAnalytics()&&this.promotePersistentIds(),this.init()}init(){this.initialized||(this.initialized=!0,this.fetchConfig().then(()=>{this.setupTracking(),this.config.consentRequired&&this.config.showConsentBanner&&!this.hasStoredConsent()&&this.showConsentBanner()}))}resolveInitialConsent(){let t=this.loadStoredConsent();return t||{...this.config.consentRequired?{analytics:!1,heatmaps:!1,geo:!1}:{analytics:!0,heatmaps:!!this.config.heatmap,geo:!1},...this.config.consentCategories}}consentStorageKey(){return`_krypton_consent_${this.config.apiKey}`}hasStoredConsent(){try{return typeof localStorage>"u"?!1:!!localStorage.getItem(this.consentStorageKey())}catch{return!1}}loadStoredConsent(){try{if(typeof localStorage>"u")return null;let t=localStorage.getItem(this.consentStorageKey());if(!t)return null;let r=JSON.parse(t);return{analytics:!!r.analytics,heatmaps:!!r.heatmaps,geo:!!r.geo}}catch{return null}}persistConsent(){try{if(typeof localStorage>"u")return;localStorage.setItem(this.consentStorageKey(),JSON.stringify(this.consent))}catch{}}promotePersistentIds(){this.distinctId=he(),this.sessionId=pe()}canTrackAnalytics(){return!!this.consent.analytics}isHeatmapFeatureEnabled(){return!this.config.heatmap||this.configFetched&&!this.serverConfig?.heatmaps_enabled?!1:!!this.consent.heatmaps}async fetchConfig(){if(typeof window>"u")return;let t=`_krypton_config_${this.config.apiKey}`,r=null;try{r=sessionStorage.getItem(t)}catch{r=null}if(r)try{let i=JSON.parse(r);if(i._ts&&Date.now()-i._ts<300*1e3){this.serverConfig=i,this.configFetched=!0;return}}catch{}try{let i=await fetch(`${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`);if(i.ok){let n=await i.json();this.serverConfig=n,this.configFetched=!0;try{sessionStorage.setItem(t,JSON.stringify({...n,_ts:Date.now()}))}catch{}}}catch{}}setupTracking(){if(this.flushTimer=setInterval(()=>this.flush(),this.config.flushInterval),typeof window>"u")return;window.addEventListener("beforeunload",()=>this.flush()),this.config.autoPageview&&this.canTrackAnalytics()&&this.trackPageview();let t=history.pushState;history.pushState=(...i)=>{t.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)};let r=history.replaceState;history.replaceState=(...i)=>{r.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)},window.addEventListener("popstate",()=>{this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}),this.isHeatmapFeatureEnabled()&&this.setupHeatmap(),this.consent.geo&&this.captureGeoOnce()}showConsentBanner(){if(typeof document>"u"||document.getElementById("krypton-consent-banner"))return;let t=document.createElement("div");t.id="krypton-consent-banner",t.style.cssText=["position:fixed","left:16px","right:16px","bottom:16px","z-index:2147483647","max-width:720px","margin:0 auto","background:#111827","color:#f9fafb","border-radius:12px","padding:16px","box-shadow:0 12px 30px rgba(0,0,0,0.35)","font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif","font-size:14px","line-height:1.4"].join(";");let r=a=>a?"checked":"";t.innerHTML=`
1
+ "use strict";var KryptonAnalytics=(()=>{var Z=Object.defineProperty;var ke=Object.getOwnPropertyDescriptor;var Se=Object.getOwnPropertyNames;var be=Object.prototype.hasOwnProperty;var Ce=(e,t)=>{for(var r in t)Z(e,r,{get:t[r],enumerable:!0})},xe=(e,t,r,i)=>{if(t&&typeof t=="object"||typeof t=="function")for(let n of Se(t))!be.call(e,n)&&n!==r&&Z(e,n,{get:()=>t[n],enumerable:!(i=ke(t,n))||i.enumerable});return e};var Ie=e=>xe(Z({},"__esModule",{value:!0}),e);var at={};Ce(at,{Krypton:()=>q,default:()=>nt,init:()=>ye});var v;(function(e){e[e.Document=0]="Document",e[e.DocumentType=1]="DocumentType",e[e.Element=2]="Element",e[e.Text=3]="Text",e[e.CDATA=4]="CDATA",e[e.Comment=5]="Comment"})(v||(v={}));function Te(e){return e.nodeType===e.ELEMENT_NODE}function Ee(e){var t=e?.host;return t?.shadowRoot===e}function ee(e){return Object.prototype.toString.call(e)==="[object ShadowRoot]"}function Le(e){return e.includes(" background-clip: text;")&&!e.includes(" -webkit-background-clip: text;")&&(e=e.replace(" background-clip: text;"," -webkit-background-clip: text; background-clip: text;")),e}function te(e){try{var t=e.rules||e.cssRules;return t?Le(Array.from(t).map(Re).join("")):null}catch{return null}}function Re(e){var t=e.cssText;if(_e(e))try{t=te(e.styleSheet)||t}catch{}return t}function _e(e){return"styleSheet"in e}var Ne=(function(){function e(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap}return e.prototype.getId=function(t){var r;if(!t)return-1;var i=(r=this.getMeta(t))===null||r===void 0?void 0:r.id;return i??-1},e.prototype.getNode=function(t){return this.idNodeMap.get(t)||null},e.prototype.getIds=function(){return Array.from(this.idNodeMap.keys())},e.prototype.getMeta=function(t){return this.nodeMetaMap.get(t)||null},e.prototype.removeNodeFromMap=function(t){var r=this,i=this.getId(t);this.idNodeMap.delete(i),t.childNodes&&t.childNodes.forEach(function(n){return r.removeNodeFromMap(n)})},e.prototype.has=function(t){return this.idNodeMap.has(t)},e.prototype.hasNode=function(t){return this.nodeMetaMap.has(t)},e.prototype.add=function(t,r){var i=r.id;this.idNodeMap.set(i,t),this.nodeMetaMap.set(t,r)},e.prototype.replace=function(t,r){var i=this.getNode(t);if(i){var n=this.nodeMetaMap.get(i);n&&this.nodeMetaMap.set(r,n)}this.idNodeMap.set(t,r)},e.prototype.reset=function(){this.idNodeMap=new Map,this.nodeMetaMap=new WeakMap},e})();function Oe(e){var t=e.maskInputOptions,r=e.tagName,i=e.type,n=e.value,a=e.maskInputFn,c=n||"";return(t[r.toLowerCase()]||t[i])&&(a?c=a(c):c="*".repeat(c.length)),c}var le="__rrweb_original__";function Ae(e){var t=e.getContext("2d");if(!t)return!0;for(var r=50,i=0;i<e.width;i+=r)for(var n=0;n<e.height;n+=r){var a=t.getImageData,c=le in a?a[le]:a,u=new Uint32Array(c.call(t,i,n,Math.min(r,e.width-i),Math.min(r,e.height-n)).data.buffer);if(u.some(function(o){return o!==0}))return!1}return!0}var Me=1,Pe=new RegExp("[^a-z0-9-_:]"),ue=-2;function De(){return Me++}function Fe(e){if(e instanceof HTMLFormElement)return"form";var t=e.tagName.toLowerCase().trim();return Pe.test(t)?"div":t}function He(e){return e.cssRules?Array.from(e.cssRules).map(function(t){return t.cssText||""}).join(""):""}function Ue(e){var t="";return e.indexOf("//")>-1?t=e.split("/").slice(0,3).join("/"):t=e.split("/")[0],t=t.split("?")[0],t}var B,fe,We=/url\((?:(')([^']*)'|(")(.*?)"|([^)]*))\)/gm,Ke=/^(?!www\.|(?:http|ftp)s?:\/\/|[A-Za-z]:\\|\/\/|#).*/,ze=/^(data:)([^,]*),(.*)/i;function Q(e,t){return(e||"").replace(We,function(r,i,n,a,c,u){var o=n||c||u,f=i||a||"";if(!o)return r;if(!Ke.test(o)||ze.test(o))return"url(".concat(f).concat(o).concat(f,")");if(o[0]==="/")return"url(".concat(f).concat(Ue(t)+o).concat(f,")");var l=t.split("/"),h=o.split("/");l.pop();for(var b=0,w=h;b<w.length;b++){var k=w[b];k!=="."&&(k===".."?l.pop():l.push(k))}return"url(".concat(f).concat(l.join("/")).concat(f,")")})}var Be=/^[^ \t\n\r\u000c]+/,je=/^[, \t\n\r\u000c]+/;function qe(e,t){if(t.trim()==="")return t;var r=0;function i(f){var l,h=f.exec(t.substring(r));return h?(l=h[0],r+=l.length,l):""}for(var n=[];i(je),!(r>=t.length);){var a=i(Be);if(a.slice(-1)===",")a=j(e,a.substring(0,a.length-1)),n.push(a);else{var c="";a=j(e,a);for(var u=!1;;){var o=t.charAt(r);if(o===""){n.push((a+c).trim());break}else if(u)o===")"&&(u=!1);else if(o===","){r+=1,n.push((a+c).trim());break}else o==="("&&(u=!0);c+=o,r+=1}}}return n.join(", ")}function j(e,t){if(!t||t.trim()==="")return t;var r=e.createElement("a");return r.href=t,r.href}function $e(e){return!!(e.tagName==="svg"||e.ownerSVGElement)}function ie(){var e=document.createElement("a");return e.href="",e.href}function Ge(e,t,r,i){return r==="src"||r==="href"&&i&&!(t==="use"&&i[0]==="#")||r==="xlink:href"&&i&&i[0]!=="#"||r==="background"&&i&&(t==="table"||t==="td"||t==="th")?j(e,i):r==="srcset"&&i?qe(e,i):r==="style"&&i?Q(i,ie()):t==="object"&&r==="data"&&i?j(e,i):i}function Qe(e,t,r){if(typeof t=="string"){if(e.classList.contains(t))return!0}else for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?e.matches(r):!1}function re(e,t,r){if(!e)return!1;if(e.nodeType!==e.ELEMENT_NODE)return r?re(e.parentNode,t,r):!1;for(var i=e.classList.length;i--;){var n=e.classList[i];if(t.test(n))return!0}return r?re(e.parentNode,t,r):!1}function Je(e,t,r){var i=e.nodeType===e.ELEMENT_NODE?e:e.parentElement;if(i===null)return!1;if(typeof t=="string"){if(i.classList.contains(t)||i.closest(".".concat(t)))return!0}else if(re(i,t,!0))return!0;return!!(r&&(i.matches(r)||i.closest(r)))}function Ve(e,t,r){var i=e.contentWindow;if(i){var n=!1,a;try{a=i.document.readyState}catch{return}if(a!=="complete"){var c=setTimeout(function(){n||(t(),n=!0)},r);e.addEventListener("load",function(){clearTimeout(c),n=!0,t()});return}var u="about:blank";if(i.location.href!==u||e.src===u||e.src==="")return setTimeout(t,0),e.addEventListener("load",t);e.addEventListener("load",t)}}function Ye(e,t,r){var i=!1,n;try{n=e.sheet}catch{return}if(!n){var a=setTimeout(function(){i||(t(),i=!0)},r);e.addEventListener("load",function(){clearTimeout(a),i=!0,t()})}}function Xe(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.inlineStylesheet,f=t.maskInputOptions,l=f===void 0?{}:f,h=t.maskTextFn,b=t.maskInputFn,w=t.dataURLOptions,k=w===void 0?{}:w,x=t.inlineImages,I=t.recordCanvas,T=t.keepIframeSrcFn,p=t.newlyAddedElement,s=p===void 0?!1:p,y=Ze(r,i);switch(e.nodeType){case e.DOCUMENT_NODE:return e.compatMode!=="CSS1Compat"?{type:v.Document,childNodes:[],compatMode:e.compatMode}:{type:v.Document,childNodes:[]};case e.DOCUMENT_TYPE_NODE:return{type:v.DocumentType,name:e.name,publicId:e.publicId,systemId:e.systemId,rootId:y};case e.ELEMENT_NODE:return tt(e,{doc:r,blockClass:n,blockSelector:a,inlineStylesheet:o,maskInputOptions:l,maskInputFn:b,dataURLOptions:k,inlineImages:x,recordCanvas:I,keepIframeSrcFn:T,newlyAddedElement:s,rootId:y});case e.TEXT_NODE:return et(e,{maskTextClass:c,maskTextSelector:u,maskTextFn:h,rootId:y});case e.CDATA_SECTION_NODE:return{type:v.CDATA,textContent:"",rootId:y};case e.COMMENT_NODE:return{type:v.Comment,textContent:e.textContent||"",rootId:y};default:return!1}}function Ze(e,t){if(t.hasNode(e)){var r=t.getId(e);return r===1?void 0:r}}function et(e,t){var r,i=t.maskTextClass,n=t.maskTextSelector,a=t.maskTextFn,c=t.rootId,u=e.parentNode&&e.parentNode.tagName,o=e.textContent,f=u==="STYLE"?!0:void 0,l=u==="SCRIPT"?!0:void 0;if(f&&o){try{e.nextSibling||e.previousSibling||!((r=e.parentNode.sheet)===null||r===void 0)&&r.cssRules&&(o=He(e.parentNode.sheet))}catch(h){console.warn("Cannot get CSS styles from text's parentNode. Error: ".concat(h),e)}o=Q(o,ie())}return l&&(o="SCRIPT_PLACEHOLDER"),!f&&!l&&o&&Je(e,i,n)&&(o=a?a(o):o.replace(/[\S]/g,"*")),{type:v.Text,textContent:o||"",isStyle:f,rootId:c}}function tt(e,t){for(var r=t.doc,i=t.blockClass,n=t.blockSelector,a=t.inlineStylesheet,c=t.maskInputOptions,u=c===void 0?{}:c,o=t.maskInputFn,f=t.dataURLOptions,l=f===void 0?{}:f,h=t.inlineImages,b=t.recordCanvas,w=t.keepIframeSrcFn,k=t.newlyAddedElement,x=k===void 0?!1:k,I=t.rootId,T=Qe(e,i,n),p=Fe(e),s={},y=e.attributes.length,A=0;A<y;A++){var E=e.attributes[A];s[E.name]=Ge(r,p,E.name,E.value)}if(p==="link"&&a){var C=Array.from(r.styleSheets).find(function(R){return R.href===e.href}),m=null;C&&(m=te(C)),m&&(delete s.rel,delete s.href,s._cssText=Q(m,C.href))}if(p==="style"&&e.sheet&&!(e.innerText||e.textContent||"").trim().length){var m=te(e.sheet);m&&(s._cssText=Q(m,ie()))}if(p==="input"||p==="textarea"||p==="select"){var F=e.value,_=e.checked;s.type!=="radio"&&s.type!=="checkbox"&&s.type!=="submit"&&s.type!=="button"&&F?s.value=Oe({type:s.type,tagName:p,value:F,maskInputOptions:u,maskInputFn:o}):_&&(s.checked=_)}if(p==="option"&&(e.selected&&!u.select?s.selected=!0:delete s.selected),p==="canvas"&&b){if(e.__context==="2d")Ae(e)||(s.rr_dataURL=e.toDataURL(l.type,l.quality));else if(!("__context"in e)){var L=e.toDataURL(l.type,l.quality),M=document.createElement("canvas");M.width=e.width,M.height=e.height;var P=M.toDataURL(l.type,l.quality);L!==P&&(s.rr_dataURL=L)}}if(p==="img"&&h){B||(B=r.createElement("canvas"),fe=B.getContext("2d"));var S=e,N=S.crossOrigin;S.crossOrigin="anonymous";var D=function(){try{B.width=S.naturalWidth,B.height=S.naturalHeight,fe.drawImage(S,0,0),s.rr_dataURL=B.toDataURL(l.type,l.quality)}catch(R){console.warn("Cannot inline img src=".concat(S.currentSrc,"! Error: ").concat(R))}N?s.crossOrigin=N:S.removeAttribute("crossorigin")};S.complete&&S.naturalWidth!==0?D():S.onload=D}if((p==="audio"||p==="video")&&(s.rr_mediaState=e.paused?"paused":"played",s.rr_mediaCurrentTime=e.currentTime),x||(e.scrollLeft&&(s.rr_scrollLeft=e.scrollLeft),e.scrollTop&&(s.rr_scrollTop=e.scrollTop)),T){var U=e.getBoundingClientRect(),W=U.width,O=U.height;s={class:s.class,rr_width:"".concat(W,"px"),rr_height:"".concat(O,"px")}}return p==="iframe"&&!w(s.src)&&(e.contentDocument||(s.rr_src=s.src),delete s.src),{type:v.Element,tagName:p,attributes:s,childNodes:[],isSVG:$e(e)||void 0,needBlock:T,rootId:I}}function d(e){return e===void 0?"":e.toLowerCase()}function rt(e,t){if(t.comment&&e.type===v.Comment)return!0;if(e.type===v.Element){if(t.script&&(e.tagName==="script"||e.tagName==="link"&&e.attributes.rel==="preload"&&e.attributes.as==="script"||e.tagName==="link"&&e.attributes.rel==="prefetch"&&typeof e.attributes.href=="string"&&e.attributes.href.endsWith(".js")))return!0;if(t.headFavicon&&(e.tagName==="link"&&e.attributes.rel==="shortcut icon"||e.tagName==="meta"&&(d(e.attributes.name).match(/^msapplication-tile(image|color)$/)||d(e.attributes.name)==="application-name"||d(e.attributes.rel)==="icon"||d(e.attributes.rel)==="apple-touch-icon"||d(e.attributes.rel)==="shortcut icon")))return!0;if(e.tagName==="meta"){if(t.headMetaDescKeywords&&d(e.attributes.name).match(/^description|keywords$/))return!0;if(t.headMetaSocial&&(d(e.attributes.property).match(/^(og|twitter|fb):/)||d(e.attributes.name).match(/^(og|twitter):/)||d(e.attributes.name)==="pinterest"))return!0;if(t.headMetaRobots&&(d(e.attributes.name)==="robots"||d(e.attributes.name)==="googlebot"||d(e.attributes.name)==="bingbot"))return!0;if(t.headMetaHttpEquiv&&e.attributes["http-equiv"]!==void 0)return!0;if(t.headMetaAuthorship&&(d(e.attributes.name)==="author"||d(e.attributes.name)==="generator"||d(e.attributes.name)==="framework"||d(e.attributes.name)==="publisher"||d(e.attributes.name)==="progid"||d(e.attributes.property).match(/^article:/)||d(e.attributes.property).match(/^product:/)))return!0;if(t.headMetaVerification&&(d(e.attributes.name)==="google-site-verification"||d(e.attributes.name)==="yandex-verification"||d(e.attributes.name)==="csrf-token"||d(e.attributes.name)==="p:domain_verify"||d(e.attributes.name)==="verify-v1"||d(e.attributes.name)==="verification"||d(e.attributes.name)==="shopify-checkout-api-token"))return!0}}return!1}function G(e,t){var r=t.doc,i=t.mirror,n=t.blockClass,a=t.blockSelector,c=t.maskTextClass,u=t.maskTextSelector,o=t.skipChild,f=o===void 0?!1:o,l=t.inlineStylesheet,h=l===void 0?!0:l,b=t.maskInputOptions,w=b===void 0?{}:b,k=t.maskTextFn,x=t.maskInputFn,I=t.slimDOMOptions,T=t.dataURLOptions,p=T===void 0?{}:T,s=t.inlineImages,y=s===void 0?!1:s,A=t.recordCanvas,E=A===void 0?!1:A,C=t.onSerialize,m=t.onIframeLoad,F=t.iframeLoadTimeout,_=F===void 0?5e3:F,L=t.onStylesheetLoad,M=t.stylesheetLoadTimeout,P=M===void 0?5e3:M,S=t.keepIframeSrcFn,N=S===void 0?function(){return!1}:S,D=t.newlyAddedElement,U=D===void 0?!1:D,W=t.preserveWhiteSpace,O=W===void 0?!0:W,R=Xe(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,dataURLOptions:p,inlineImages:y,recordCanvas:E,keepIframeSrcFn:N,newlyAddedElement:U});if(!R)return console.warn(e,"not serialized"),null;var $;i.hasNode(e)?$=i.getId(e):rt(R,I)||!O&&R.type===v.Text&&!R.isStyle&&!R.textContent.replace(/^\s+|\s+$/gm,"").length?$=ue:$=De();var g=Object.assign(R,{id:$});if(i.add(e,g),$===ue)return null;C&&C(e);var J=!f;if(g.type===v.Element){J=J&&!g.needBlock,delete g.needBlock;var ne=e.shadowRoot;ne&&ee(ne)&&(g.isShadowHost=!0)}if((g.type===v.Document||g.type===v.Element)&&J){I.headWhitespace&&g.type===v.Element&&g.tagName==="head"&&(O=!1);for(var ae={doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:f,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:P,keepIframeSrcFn:N},V=0,oe=Array.from(e.childNodes);V<oe.length;V++){var Y=oe[V],K=G(Y,ae);K&&g.childNodes.push(K)}if(Te(e)&&e.shadowRoot)for(var X=0,se=Array.from(e.shadowRoot.childNodes);X<se.length;X++){var Y=se[X],K=G(Y,ae);K&&(ee(e.shadowRoot)&&(K.isShadow=!0),g.childNodes.push(K))}}return e.parentNode&&Ee(e.parentNode)&&ee(e.parentNode)&&(g.isShadow=!0),g.type===v.Element&&g.tagName==="iframe"&&Ve(e,function(){var z=e.contentDocument;if(z&&m){var ce=G(z,{doc:z,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:P,keepIframeSrcFn:N});ce&&m(e,ce)}},_),g.type===v.Element&&g.tagName==="link"&&g.attributes.rel==="stylesheet"&&Ye(e,function(){if(L){var z=G(e,{doc:r,mirror:i,blockClass:n,blockSelector:a,maskTextClass:c,maskTextSelector:u,skipChild:!1,inlineStylesheet:h,maskInputOptions:w,maskTextFn:k,maskInputFn:x,slimDOMOptions:I,dataURLOptions:p,inlineImages:y,recordCanvas:E,preserveWhiteSpace:O,onSerialize:C,onIframeLoad:m,iframeLoadTimeout:_,onStylesheetLoad:L,stylesheetLoadTimeout:P,keepIframeSrcFn:N});z&&L(e,z)}},P),g}function de(e,t){var r=t||{},i=r.mirror,n=i===void 0?new Ne:i,a=r.blockClass,c=a===void 0?"rr-block":a,u=r.blockSelector,o=u===void 0?null:u,f=r.maskTextClass,l=f===void 0?"rr-mask":f,h=r.maskTextSelector,b=h===void 0?null:h,w=r.inlineStylesheet,k=w===void 0?!0:w,x=r.inlineImages,I=x===void 0?!1:x,T=r.recordCanvas,p=T===void 0?!1:T,s=r.maskAllInputs,y=s===void 0?!1:s,A=r.maskTextFn,E=r.maskInputFn,C=r.slimDOM,m=C===void 0?!1:C,F=r.dataURLOptions,_=r.preserveWhiteSpace,L=r.onSerialize,M=r.onIframeLoad,P=r.iframeLoadTimeout,S=r.onStylesheetLoad,N=r.stylesheetLoadTimeout,D=r.keepIframeSrcFn,U=D===void 0?function(){return!1}:D,W=y===!0?{color:!0,date:!0,"datetime-local":!0,email:!0,month:!0,number:!0,range:!0,search:!0,tel:!0,text:!0,time:!0,url:!0,week:!0,textarea:!0,select:!0,password:!0}:y===!1?{password:!0}:y,O=m===!0||m==="all"?{script:!0,comment:!0,headFavicon:!0,headWhitespace:!0,headMetaDescKeywords:m==="all",headMetaSocial:!0,headMetaRobots:!0,headMetaHttpEquiv:!0,headMetaAuthorship:!0,headMetaVerification:!0}:m===!1?{}:m;return G(e,{doc:e,mirror:n,blockClass:c,blockSelector:o,maskTextClass:l,maskTextSelector:b,skipChild:!1,inlineStylesheet:k,maskInputOptions:W,maskTextFn:A,maskInputFn:E,slimDOMOptions:O,dataURLOptions:F,inlineImages:I,recordCanvas:p,preserveWhiteSpace:_,onSerialize:L,onIframeLoad:M,iframeLoadTimeout:P,onStylesheetLoad:S,stylesheetLoadTimeout:N,keepIframeSrcFn:U,newlyAddedElement:!1})}var it=/([^\\]):hover/,st=new RegExp(it.source,"g");function H(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():"xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g,e=>{let t=Math.random()*16|0;return(e==="x"?t:t&3|8).toString(16)})}function pe(){let e="_krypton_sid";try{if(typeof sessionStorage<"u"){let t=sessionStorage.getItem(e);return t||(t=H(),sessionStorage.setItem(e,t)),t}}catch{}return H()}function he(){let e="_krypton_did";try{if(typeof localStorage<"u"){let t=localStorage.getItem(e);return t||(t=H(),localStorage.setItem(e,t)),t}}catch{}return H()}function me(){if(typeof window>"u")return{};let e=new URLSearchParams(window.location.search),t={};for(let r of["utm_source","utm_medium","utm_campaign","utm_term","utm_content"]){let i=e.get(r);i&&(t[r]=i)}return t}function ge(){if(typeof window>"u")return"unknown";let e=window.innerWidth;return e<768?"mobile":e<1024?"tablet":"desktop"}function ve(e){if(e.id)return`#${e.id}`;let t=[],r=e;for(;r&&r!==document.body;){let i=r.tagName.toLowerCase();if(r.id){t.unshift(`#${r.id}`);break}if(r.className&&typeof r.className=="string"){let n=r.className.trim().split(/\s+/).slice(0,2).join(".");n&&(i+=`.${n}`)}t.unshift(i),r=r.parentElement}return t.join(" > ")}var q=class{constructor(t){this.eventQueue=[];this.heatmapQueue=[];this.flushTimer=null;this.initialized=!1;this.lastSnapshotUrl=null;this.heatmapSetup=!1;this.geoRequested=!1;this.geoContext=null;this.serverConfig=null;this.configFetched=!1;this.logPrefix="[Krypton SDK]";this.config={autoPageview:!0,heatmap:!1,consentRequired:!1,showConsentBanner:!1,consentCategories:{},flushInterval:5e3,batchSize:20,...t},this.distinctId=H(),this.sessionId=H(),this.consent=this.resolveInitialConsent(),this.canTrackAnalytics()&&this.promotePersistentIds(),this.init()}init(){this.initialized||(this.initialized=!0,this.fetchConfig().then(()=>{this.setupTracking(),this.config.consentRequired&&this.config.showConsentBanner&&!this.hasStoredConsent()&&this.showConsentBanner()}).catch(t=>{this.warn("Initialization failed",t)}))}resolveInitialConsent(){let t=this.loadStoredConsent();return t||{...this.config.consentRequired?{analytics:!1,heatmaps:!1,geo:!1}:{analytics:!0,heatmaps:!!this.config.heatmap,geo:!1},...this.config.consentCategories}}consentStorageKey(){return`_krypton_consent_${this.config.apiKey}`}hasStoredConsent(){try{return typeof localStorage>"u"?!1:!!localStorage.getItem(this.consentStorageKey())}catch{return!1}}loadStoredConsent(){try{if(typeof localStorage>"u")return null;let t=localStorage.getItem(this.consentStorageKey());if(!t)return null;let r=JSON.parse(t);return{analytics:!!r.analytics,heatmaps:!!r.heatmaps,geo:!!r.geo}}catch{return null}}persistConsent(){try{if(typeof localStorage>"u")return;localStorage.setItem(this.consentStorageKey(),JSON.stringify(this.consent))}catch{}}promotePersistentIds(){this.distinctId=he(),this.sessionId=pe()}canTrackAnalytics(){return!!this.consent.analytics}isHeatmapFeatureEnabled(){return!this.config.heatmap||this.configFetched&&!this.serverConfig?.heatmaps_enabled?!1:!!this.consent.heatmaps}async fetchConfig(){if(typeof window>"u")return;let t=`_krypton_config_${this.config.apiKey}`,r=null;try{r=sessionStorage.getItem(t)}catch{r=null}if(r)try{let i=JSON.parse(r);if(i._ts&&Date.now()-i._ts<300*1e3){this.serverConfig=i,this.configFetched=!0;return}}catch{}try{let i=await fetch(`${this.config.endpoint}/api/v1/config?api_key=${encodeURIComponent(this.config.apiKey)}`);if(i.ok){let n=await i.json();this.serverConfig=n,this.configFetched=!0;try{sessionStorage.setItem(t,JSON.stringify({...n,_ts:Date.now()}))}catch{}}}catch{}}setupTracking(){if(this.flushTimer=setInterval(()=>{this.flush()},this.config.flushInterval),typeof window>"u")return;window.addEventListener("beforeunload",()=>{this.flush()}),this.config.autoPageview&&this.canTrackAnalytics()&&this.trackPageview();let t=history.pushState;history.pushState=(...i)=>{try{t.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}catch(n){this.warn("pushState hook failed",n)}};let r=history.replaceState;history.replaceState=(...i)=>{try{r.apply(history,i),this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}catch(n){this.warn("replaceState hook failed",n)}},window.addEventListener("popstate",()=>{try{this.config.autoPageview&&this.canTrackAnalytics()&&setTimeout(()=>this.trackPageview(),0),this.isHeatmapFeatureEnabled()&&setTimeout(()=>this.captureSnapshot(),0)}catch(i){this.warn("popstate hook failed",i)}}),this.isHeatmapFeatureEnabled()&&this.setupHeatmap(),this.consent.geo&&this.captureGeoOnce()}showConsentBanner(){if(typeof document>"u"||document.getElementById("krypton-consent-banner"))return;let t=document.createElement("div");t.id="krypton-consent-banner",t.style.cssText=["position:fixed","left:16px","right:16px","bottom:16px","z-index:2147483647","max-width:720px","margin:0 auto","background:#111827","color:#f9fafb","border-radius:12px","padding:16px","box-shadow:0 12px 30px rgba(0,0,0,0.35)","font-family:system-ui,-apple-system,Segoe UI,Roboto,sans-serif","font-size:14px","line-height:1.4"].join(";");let r=a=>a?"checked":"";t.innerHTML=`
2
2
  <div style="font-weight:600;margin-bottom:6px">Privacy preferences</div>
3
3
  <div style="opacity:0.9;margin-bottom:10px">Choose what data you allow us to collect.</div>
4
4
  <label style="display:flex;gap:8px;align-items:flex-start;margin:6px 0">
@@ -18,4 +18,4 @@
18
18
  <button id="krypton-consent-all" style="border:0;background:#16a34a;color:#fff;padding:8px 12px;border-radius:8px;cursor:pointer">Accept all</button>
19
19
  <button id="krypton-consent-none" style="border:1px solid #4b5563;background:transparent;color:#f9fafb;padding:8px 12px;border-radius:8px;cursor:pointer">Reject all</button>
20
20
  </div>
21
- `;let i=()=>{t.remove()},n=a=>!!document.getElementById(a)?.checked;t.querySelector("#krypton-consent-save")?.addEventListener("click",()=>{this.setConsent({analytics:n("krypton-consent-analytics"),heatmaps:n("krypton-consent-heatmaps"),geo:n("krypton-consent-geo")}),i()}),t.querySelector("#krypton-consent-all")?.addEventListener("click",()=>{this.setConsent({analytics:!0,heatmaps:!0,geo:!0}),i()}),t.querySelector("#krypton-consent-none")?.addEventListener("click",()=>{this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),i()}),document.body.appendChild(t)}setConsent(t,r=!0){let i={...this.consent};this.consent={analytics:t.analytics??i.analytics,heatmaps:t.heatmaps??i.heatmaps,geo:t.geo??i.geo},r&&this.persistConsent(),!i.analytics&&this.consent.analytics&&(this.promotePersistentIds(),this.config.autoPageview&&this.trackPageview()),i.analytics&&!this.consent.analytics&&(this.eventQueue=[]),!i.heatmaps&&this.isHeatmapFeatureEnabled()&&(this.setupHeatmap(),this.captureSnapshot()),i.heatmaps&&!this.consent.heatmaps&&(this.heatmapQueue=[]),!i.geo&&this.consent.geo&&this.captureGeoOnce()}getConsent(){return{...this.consent}}grantConsent(){this.setConsent({analytics:!0,heatmaps:!0,geo:!0})}revokeConsent(){this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),this.eventQueue=[],this.heatmapQueue=[]}identify(t){if(this.distinctId=t,this.canTrackAnalytics())try{typeof localStorage<"u"&&localStorage.setItem("_krypton_did",t)}catch{}}trackPageview(t){this.canTrackAnalytics()&&this.track("$pageview",{...t})}track(t,r){if(!this.canTrackAnalytics())return;let i=me(),n={...r||{}};this.consent.geo&&this.geoContext&&(n.geo=this.geoContext);let a={project_id:this.config.apiKey,distinct_id:this.distinctId,event_name:t,timestamp:new Date().toISOString(),properties:n,page_url:typeof window<"u"?window.location.href:"",page_title:typeof document<"u"?document.title:"",referrer:typeof document<"u"?document.referrer:"",utm_source:i.utm_source||"",utm_medium:i.utm_medium||"",utm_campaign:i.utm_campaign||"",utm_term:i.utm_term||"",utm_content:i.utm_content||"",device_type:ge(),browser:this.getBrowser(),screen_width:typeof window<"u"?window.screen.width:0,screen_height:typeof window<"u"?window.screen.height:0,session_id:this.sessionId};this.eventQueue.push(a),this.eventQueue.length>=this.config.batchSize&&this.flush()}async flush(){await Promise.all([this.flushEvents(),this.flushHeatmapEvents()])}shutdown(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flush()}captureGeoOnce(){this.geoRequested||this.consent.geo&&(typeof navigator>"u"||!navigator.geolocation||(this.geoRequested=!0,navigator.geolocation.getCurrentPosition(t=>{let r=(i,n=3)=>Number(i.toFixed(n));this.geoContext={lat:r(t.coords.latitude),lon:r(t.coords.longitude),accuracy_m:Math.round(t.coords.accuracy),captured_at:new Date().toISOString()}},()=>{},{enableHighAccuracy:!1,maximumAge:600*1e3,timeout:5e3})))}async flushEvents(){if(this.eventQueue.length===0)return;let t=this.eventQueue.splice(0,this.eventQueue.length),r={api_key:this.config.apiKey,events:t};try{await fetch(`${this.config.endpoint}/api/v1/ingest/batch`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),keepalive:!0})}catch{this.eventQueue.length<this.config.batchSize*5&&this.eventQueue.unshift(...t)}}async flushHeatmapEvents(){if(this.heatmapQueue.length===0)return;let t=this.heatmapQueue.splice(0,this.heatmapQueue.length),r={api_key:this.config.apiKey,events:t};try{await fetch(`${this.config.endpoint}/api/v1/heatmap`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),keepalive:!0})}catch{this.heatmapQueue.length<this.config.batchSize*5&&this.heatmapQueue.unshift(...t)}}captureSnapshot(){if(typeof window>"u"||typeof document>"u"||!this.isHeatmapFeatureEnabled())return;let t=window.location.href;this.lastSnapshotUrl!==t&&(this.lastSnapshotUrl=t,setTimeout(()=>{try{let r=de(document,{maskAllInputs:!0,blockSelector:"[data-krypton-block]",inlineStylesheet:!0});if(!r)return;let i=JSON.stringify(r),n={api_key:this.config.apiKey,page_url:t,snapshot:i,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,timestamp:new Date().toISOString()};fetch(`${this.config.endpoint}/api/v1/snapshot`,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(n),keepalive:!0}).catch(()=>{})}catch{}},1e3))}setupHeatmap(){if(typeof window>"u"||this.heatmapSetup)return;this.heatmapSetup=!0,this.captureSnapshot(),document.addEventListener("click",i=>{if(!this.isHeatmapFeatureEnabled())return;let n=i.target;this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"click",x:i.clientX+window.scrollX,y:i.clientY+window.scrollY,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,selector:ve(n)})});let t=0,r=null;window.addEventListener("scroll",()=>{if(!this.isHeatmapFeatureEnabled())return;let i=window.scrollY||document.documentElement.scrollTop,n=document.documentElement.scrollHeight-window.innerHeight,a=n>0?i/n*100:0;a>t&&(t=a),r&&clearTimeout(r),r=setTimeout(()=>{this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"scroll",scroll_depth:t,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight})},500)})}getBrowser(){if(typeof navigator>"u")return"unknown";let t=navigator.userAgent;return t.includes("Firefox")?"Firefox":t.includes("Edg")?"Edge":t.includes("Chrome")?"Chrome":t.includes("Safari")?"Safari":"Other"}};function ye(e){return new q(e)}var ke={Krypton:q,init:ye};typeof window<"u"&&(window.KryptonAnalytics=ke);var nt=ke;return Ie(at);})();
21
+ `;let i=()=>{t.remove();try{document.body&&(document.body.style.cursor=""),document.documentElement&&(document.documentElement.style.cursor="")}catch{}},n=a=>!!document.getElementById(a)?.checked;t.querySelector("#krypton-consent-save")?.addEventListener("click",()=>{let a={analytics:n("krypton-consent-analytics"),heatmaps:n("krypton-consent-heatmaps"),geo:n("krypton-consent-geo")};i(),setTimeout(()=>this.setConsent(a),0)}),t.querySelector("#krypton-consent-all")?.addEventListener("click",()=>{i(),setTimeout(()=>this.setConsent({analytics:!0,heatmaps:!0,geo:!0}),0)}),t.querySelector("#krypton-consent-none")?.addEventListener("click",()=>{i(),setTimeout(()=>this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),0)}),document.body.appendChild(t)}setConsent(t,r=!0){try{let i={...this.consent};this.consent={analytics:t.analytics??i.analytics,heatmaps:t.heatmaps??i.heatmaps,geo:t.geo??i.geo},r&&this.persistConsent(),!i.analytics&&this.consent.analytics&&(this.promotePersistentIds(),this.config.autoPageview&&this.trackPageview()),i.analytics&&!this.consent.analytics&&(this.eventQueue=[]),!i.heatmaps&&this.isHeatmapFeatureEnabled()&&(this.setupHeatmap(),this.captureSnapshot()),i.heatmaps&&!this.consent.heatmaps&&(this.heatmapQueue=[]),!i.geo&&this.consent.geo&&this.captureGeoOnce()}catch(i){this.warn("setConsent failed",i)}}getConsent(){return{...this.consent}}grantConsent(){this.setConsent({analytics:!0,heatmaps:!0,geo:!0})}revokeConsent(){this.setConsent({analytics:!1,heatmaps:!1,geo:!1}),this.eventQueue=[],this.heatmapQueue=[]}identify(t){try{if(this.distinctId=t,this.canTrackAnalytics())try{typeof localStorage<"u"&&localStorage.setItem("_krypton_did",t)}catch{}}catch(r){this.warn("identify failed",r)}}trackPageview(t){try{if(!this.canTrackAnalytics())return;this.track("$pageview",{...t})}catch(r){this.warn("trackPageview failed",r)}}track(t,r){try{if(!this.canTrackAnalytics())return;let i=me(),n={...r||{}};this.consent.geo&&this.geoContext&&(n.geo=this.geoContext);let a={project_id:this.config.apiKey,distinct_id:this.distinctId,event_name:t,timestamp:new Date().toISOString(),properties:n,page_url:typeof window<"u"?window.location.href:"",page_title:typeof document<"u"?document.title:"",referrer:typeof document<"u"?document.referrer:"",utm_source:i.utm_source||"",utm_medium:i.utm_medium||"",utm_campaign:i.utm_campaign||"",utm_term:i.utm_term||"",utm_content:i.utm_content||"",device_type:ge(),browser:this.getBrowser(),screen_width:typeof window<"u"?window.screen.width:0,screen_height:typeof window<"u"?window.screen.height:0,session_id:this.sessionId};this.eventQueue.push(a),this.eventQueue.length>=this.config.batchSize&&this.flush()}catch(i){this.warn("track failed",i)}}async flush(){try{await Promise.all([this.flushEvents(),this.flushHeatmapEvents()])}catch(t){this.warn("flush failed",t)}}shutdown(){this.flushTimer&&(clearInterval(this.flushTimer),this.flushTimer=null),this.flush()}captureGeoOnce(){this.geoRequested||this.consent.geo&&(typeof navigator>"u"||!navigator.geolocation||(this.geoRequested=!0,navigator.geolocation.getCurrentPosition(t=>{let r=(i,n=3)=>Number(i.toFixed(n));this.geoContext={lat:r(t.coords.latitude),lon:r(t.coords.longitude),accuracy_m:Math.round(t.coords.accuracy),captured_at:new Date().toISOString()}},()=>{},{enableHighAccuracy:!1,maximumAge:600*1e3,timeout:5e3})))}async flushEvents(){if(this.eventQueue.length===0)return;let t=this.eventQueue.splice(0,this.eventQueue.length),r={api_key:this.config.apiKey,events:t};await this.safePost(`${this.config.endpoint}/api/v1/ingest/batch`,r)||this.eventQueue.length<this.config.batchSize*5&&this.eventQueue.unshift(...t)}async flushHeatmapEvents(){if(this.heatmapQueue.length===0)return;let t=this.heatmapQueue.splice(0,this.heatmapQueue.length),r={api_key:this.config.apiKey,events:t};await this.safePost(`${this.config.endpoint}/api/v1/heatmap`,r)||this.heatmapQueue.length<this.config.batchSize*5&&this.heatmapQueue.unshift(...t)}captureSnapshot(){if(typeof window>"u"||typeof document>"u"||!this.isHeatmapFeatureEnabled())return;let t=window.location.href;this.lastSnapshotUrl!==t&&(this.lastSnapshotUrl=t,setTimeout(()=>{try{let r=de(document,{maskAllInputs:!0,blockSelector:"[data-krypton-block]",inlineStylesheet:!0});if(!r)return;let i=JSON.stringify(r),n={api_key:this.config.apiKey,page_url:t,snapshot:i,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,timestamp:new Date().toISOString()};this.safePost(`${this.config.endpoint}/api/v1/snapshot`,n)}catch{}},1e3))}setupHeatmap(){if(typeof window>"u"||this.heatmapSetup)return;this.heatmapSetup=!0,this.captureSnapshot(),document.addEventListener("click",i=>{if(this.isHeatmapFeatureEnabled())try{let n=i.target;this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"click",x:i.clientX+window.scrollX,y:i.clientY+window.scrollY,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight,selector:ve(n)})}catch(n){this.warn("heatmap click capture failed",n)}});let t=0,r=null;window.addEventListener("scroll",()=>{if(this.isHeatmapFeatureEnabled())try{let i=window.scrollY||document.documentElement.scrollTop,n=document.documentElement.scrollHeight-window.innerHeight,a=n>0?i/n*100:0;a>t&&(t=a),r&&clearTimeout(r),r=setTimeout(()=>{this.heatmapQueue.push({project_id:this.config.apiKey,distinct_id:this.distinctId,session_id:this.sessionId,timestamp:new Date().toISOString(),page_url:window.location.href,interaction_type:"scroll",scroll_depth:t,viewport_width:window.innerWidth,viewport_height:window.innerHeight,page_width:document.documentElement.scrollWidth,page_height:document.documentElement.scrollHeight})},500)}catch(i){this.warn("heatmap scroll capture failed",i)}})}async safePost(t,r){try{let i=await fetch(t,{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify(r),keepalive:!0});return i.ok?!0:(this.warn(`API request failed (${i.status})`,{url:t}),!1)}catch(i){return this.warn("API request failed",{url:t,err:i}),!1}}warn(t,r){try{console.warn(`${this.logPrefix} ${t}`,r??"")}catch{}}getBrowser(){if(typeof navigator>"u")return"unknown";let t=navigator.userAgent;return t.includes("Firefox")?"Firefox":t.includes("Edg")?"Edge":t.includes("Chrome")?"Chrome":t.includes("Safari")?"Safari":"Other"}};function ye(e){return new q(e)}var we={Krypton:q,init:ye};typeof window<"u"&&(window.KryptonAnalytics=we);var nt=we;return Ie(at);})();
package/dist/index.d.mts CHANGED
@@ -79,6 +79,7 @@ declare class Krypton {
79
79
  private consent;
80
80
  private serverConfig;
81
81
  private configFetched;
82
+ private readonly logPrefix;
82
83
  constructor(config: KryptonConfig);
83
84
  private init;
84
85
  private resolveInitialConsent;
@@ -113,6 +114,8 @@ declare class Krypton {
113
114
  private flushHeatmapEvents;
114
115
  private captureSnapshot;
115
116
  private setupHeatmap;
117
+ private safePost;
118
+ private warn;
116
119
  private getBrowser;
117
120
  }
118
121
  declare function createKrypton(config: KryptonConfig): Krypton;
package/dist/index.d.ts CHANGED
@@ -79,6 +79,7 @@ declare class Krypton {
79
79
  private consent;
80
80
  private serverConfig;
81
81
  private configFetched;
82
+ private readonly logPrefix;
82
83
  constructor(config: KryptonConfig);
83
84
  private init;
84
85
  private resolveInitialConsent;
@@ -113,6 +114,8 @@ declare class Krypton {
113
114
  private flushHeatmapEvents;
114
115
  private captureSnapshot;
115
116
  private setupHeatmap;
117
+ private safePost;
118
+ private warn;
116
119
  private getBrowser;
117
120
  }
118
121
  declare function createKrypton(config: KryptonConfig): Krypton;
package/dist/index.js CHANGED
@@ -117,6 +117,7 @@ var Krypton = class {
117
117
  this.geoContext = null;
118
118
  this.serverConfig = null;
119
119
  this.configFetched = false;
120
+ this.logPrefix = "[Krypton SDK]";
120
121
  this.config = {
121
122
  autoPageview: true,
122
123
  heatmap: false,
@@ -143,6 +144,8 @@ var Krypton = class {
143
144
  if (this.config.consentRequired && this.config.showConsentBanner && !this.hasStoredConsent()) {
144
145
  this.showConsentBanner();
145
146
  }
147
+ }).catch((err) => {
148
+ this.warn("Initialization failed", err);
146
149
  });
147
150
  }
148
151
  resolveInitialConsent() {
@@ -240,38 +243,54 @@ var Krypton = class {
240
243
  }
241
244
  }
242
245
  setupTracking() {
243
- this.flushTimer = setInterval(() => this.flush(), this.config.flushInterval);
246
+ this.flushTimer = setInterval(() => {
247
+ void this.flush();
248
+ }, this.config.flushInterval);
244
249
  if (typeof window === "undefined") return;
245
- window.addEventListener("beforeunload", () => this.flush());
250
+ window.addEventListener("beforeunload", () => {
251
+ void this.flush();
252
+ });
246
253
  if (this.config.autoPageview && this.canTrackAnalytics()) {
247
254
  this.trackPageview();
248
255
  }
249
256
  const originalPushState = history.pushState;
250
257
  history.pushState = (...args) => {
251
- originalPushState.apply(history, args);
252
- if (this.config.autoPageview && this.canTrackAnalytics()) {
253
- setTimeout(() => this.trackPageview(), 0);
254
- }
255
- if (this.isHeatmapFeatureEnabled()) {
256
- setTimeout(() => this.captureSnapshot(), 0);
258
+ try {
259
+ originalPushState.apply(history, args);
260
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
261
+ setTimeout(() => this.trackPageview(), 0);
262
+ }
263
+ if (this.isHeatmapFeatureEnabled()) {
264
+ setTimeout(() => this.captureSnapshot(), 0);
265
+ }
266
+ } catch (err) {
267
+ this.warn("pushState hook failed", err);
257
268
  }
258
269
  };
259
270
  const originalReplaceState = history.replaceState;
260
271
  history.replaceState = (...args) => {
261
- originalReplaceState.apply(history, args);
262
- if (this.config.autoPageview && this.canTrackAnalytics()) {
263
- setTimeout(() => this.trackPageview(), 0);
264
- }
265
- if (this.isHeatmapFeatureEnabled()) {
266
- setTimeout(() => this.captureSnapshot(), 0);
272
+ try {
273
+ originalReplaceState.apply(history, args);
274
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
275
+ setTimeout(() => this.trackPageview(), 0);
276
+ }
277
+ if (this.isHeatmapFeatureEnabled()) {
278
+ setTimeout(() => this.captureSnapshot(), 0);
279
+ }
280
+ } catch (err) {
281
+ this.warn("replaceState hook failed", err);
267
282
  }
268
283
  };
269
284
  window.addEventListener("popstate", () => {
270
- if (this.config.autoPageview && this.canTrackAnalytics()) {
271
- setTimeout(() => this.trackPageview(), 0);
272
- }
273
- if (this.isHeatmapFeatureEnabled()) {
274
- setTimeout(() => this.captureSnapshot(), 0);
285
+ try {
286
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
287
+ setTimeout(() => this.trackPageview(), 0);
288
+ }
289
+ if (this.isHeatmapFeatureEnabled()) {
290
+ setTimeout(() => this.captureSnapshot(), 0);
291
+ }
292
+ } catch (err) {
293
+ this.warn("popstate hook failed", err);
275
294
  }
276
295
  });
277
296
  if (this.isHeatmapFeatureEnabled()) {
@@ -328,58 +347,68 @@ var Krypton = class {
328
347
  `;
329
348
  const remove = () => {
330
349
  banner.remove();
350
+ try {
351
+ if (document.body) document.body.style.cursor = "";
352
+ if (document.documentElement) document.documentElement.style.cursor = "";
353
+ } catch {
354
+ }
331
355
  };
332
356
  const readValue = (id) => {
333
357
  const el = document.getElementById(id);
334
358
  return !!el?.checked;
335
359
  };
336
360
  banner.querySelector("#krypton-consent-save")?.addEventListener("click", () => {
337
- this.setConsent({
361
+ const next = {
338
362
  analytics: readValue("krypton-consent-analytics"),
339
363
  heatmaps: readValue("krypton-consent-heatmaps"),
340
364
  geo: readValue("krypton-consent-geo")
341
- });
365
+ };
342
366
  remove();
367
+ setTimeout(() => this.setConsent(next), 0);
343
368
  });
344
369
  banner.querySelector("#krypton-consent-all")?.addEventListener("click", () => {
345
- this.setConsent({ analytics: true, heatmaps: true, geo: true });
346
370
  remove();
371
+ setTimeout(() => this.setConsent({ analytics: true, heatmaps: true, geo: true }), 0);
347
372
  });
348
373
  banner.querySelector("#krypton-consent-none")?.addEventListener("click", () => {
349
- this.setConsent({ analytics: false, heatmaps: false, geo: false });
350
374
  remove();
375
+ setTimeout(() => this.setConsent({ analytics: false, heatmaps: false, geo: false }), 0);
351
376
  });
352
377
  document.body.appendChild(banner);
353
378
  }
354
379
  /** Set one or more consent categories and apply changes immediately. */
355
380
  setConsent(next, persist = true) {
356
- const prev = { ...this.consent };
357
- this.consent = {
358
- analytics: next.analytics ?? prev.analytics,
359
- heatmaps: next.heatmaps ?? prev.heatmaps,
360
- geo: next.geo ?? prev.geo
361
- };
362
- if (persist) {
363
- this.persistConsent();
364
- }
365
- if (!prev.analytics && this.consent.analytics) {
366
- this.promotePersistentIds();
367
- if (this.config.autoPageview) {
368
- this.trackPageview();
381
+ try {
382
+ const prev = { ...this.consent };
383
+ this.consent = {
384
+ analytics: next.analytics ?? prev.analytics,
385
+ heatmaps: next.heatmaps ?? prev.heatmaps,
386
+ geo: next.geo ?? prev.geo
387
+ };
388
+ if (persist) {
389
+ this.persistConsent();
369
390
  }
370
- }
371
- if (prev.analytics && !this.consent.analytics) {
372
- this.eventQueue = [];
373
- }
374
- if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
375
- this.setupHeatmap();
376
- this.captureSnapshot();
377
- }
378
- if (prev.heatmaps && !this.consent.heatmaps) {
379
- this.heatmapQueue = [];
380
- }
381
- if (!prev.geo && this.consent.geo) {
382
- this.captureGeoOnce();
391
+ if (!prev.analytics && this.consent.analytics) {
392
+ this.promotePersistentIds();
393
+ if (this.config.autoPageview) {
394
+ this.trackPageview();
395
+ }
396
+ }
397
+ if (prev.analytics && !this.consent.analytics) {
398
+ this.eventQueue = [];
399
+ }
400
+ if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
401
+ this.setupHeatmap();
402
+ this.captureSnapshot();
403
+ }
404
+ if (prev.heatmaps && !this.consent.heatmaps) {
405
+ this.heatmapQueue = [];
406
+ }
407
+ if (!prev.geo && this.consent.geo) {
408
+ this.captureGeoOnce();
409
+ }
410
+ } catch (err) {
411
+ this.warn("setConsent failed", err);
383
412
  }
384
413
  }
385
414
  getConsent() {
@@ -397,65 +426,81 @@ var Krypton = class {
397
426
  }
398
427
  /** Identify a user with a custom distinct ID */
399
428
  identify(distinctId) {
400
- this.distinctId = distinctId;
401
- if (this.canTrackAnalytics()) {
402
- try {
403
- if (typeof localStorage !== "undefined") {
404
- localStorage.setItem("_krypton_did", distinctId);
429
+ try {
430
+ this.distinctId = distinctId;
431
+ if (this.canTrackAnalytics()) {
432
+ try {
433
+ if (typeof localStorage !== "undefined") {
434
+ localStorage.setItem("_krypton_did", distinctId);
435
+ }
436
+ } catch {
405
437
  }
406
- } catch {
407
438
  }
439
+ } catch (err) {
440
+ this.warn("identify failed", err);
408
441
  }
409
442
  }
410
443
  /** Track a pageview */
411
444
  trackPageview(properties) {
412
- if (!this.canTrackAnalytics()) return;
413
- this.track("$pageview", {
414
- ...properties
415
- });
445
+ try {
446
+ if (!this.canTrackAnalytics()) return;
447
+ this.track("$pageview", {
448
+ ...properties
449
+ });
450
+ } catch (err) {
451
+ this.warn("trackPageview failed", err);
452
+ }
416
453
  }
417
454
  /** Track a custom event */
418
455
  track(eventName, properties) {
419
- if (!this.canTrackAnalytics()) return;
420
- const utm = getUTMParams();
421
- const mergedProperties = { ...properties || {} };
422
- if (this.consent.geo && this.geoContext) {
423
- mergedProperties.geo = this.geoContext;
424
- }
425
- const event = {
426
- project_id: this.config.apiKey,
427
- distinct_id: this.distinctId,
428
- event_name: eventName,
429
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
430
- properties: mergedProperties,
431
- page_url: typeof window !== "undefined" ? window.location.href : "",
432
- page_title: typeof document !== "undefined" ? document.title : "",
433
- referrer: typeof document !== "undefined" ? document.referrer : "",
434
- utm_source: utm.utm_source || "",
435
- utm_medium: utm.utm_medium || "",
436
- utm_campaign: utm.utm_campaign || "",
437
- utm_term: utm.utm_term || "",
438
- utm_content: utm.utm_content || "",
439
- device_type: getDeviceType(),
440
- browser: this.getBrowser(),
441
- screen_width: typeof window !== "undefined" ? window.screen.width : 0,
442
- screen_height: typeof window !== "undefined" ? window.screen.height : 0,
443
- session_id: this.sessionId
444
- };
445
- this.eventQueue.push(event);
446
- if (this.eventQueue.length >= this.config.batchSize) {
447
- this.flush();
456
+ try {
457
+ if (!this.canTrackAnalytics()) return;
458
+ const utm = getUTMParams();
459
+ const mergedProperties = { ...properties || {} };
460
+ if (this.consent.geo && this.geoContext) {
461
+ mergedProperties.geo = this.geoContext;
462
+ }
463
+ const event = {
464
+ project_id: this.config.apiKey,
465
+ distinct_id: this.distinctId,
466
+ event_name: eventName,
467
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
468
+ properties: mergedProperties,
469
+ page_url: typeof window !== "undefined" ? window.location.href : "",
470
+ page_title: typeof document !== "undefined" ? document.title : "",
471
+ referrer: typeof document !== "undefined" ? document.referrer : "",
472
+ utm_source: utm.utm_source || "",
473
+ utm_medium: utm.utm_medium || "",
474
+ utm_campaign: utm.utm_campaign || "",
475
+ utm_term: utm.utm_term || "",
476
+ utm_content: utm.utm_content || "",
477
+ device_type: getDeviceType(),
478
+ browser: this.getBrowser(),
479
+ screen_width: typeof window !== "undefined" ? window.screen.width : 0,
480
+ screen_height: typeof window !== "undefined" ? window.screen.height : 0,
481
+ session_id: this.sessionId
482
+ };
483
+ this.eventQueue.push(event);
484
+ if (this.eventQueue.length >= this.config.batchSize) {
485
+ void this.flush();
486
+ }
487
+ } catch (err) {
488
+ this.warn("track failed", err);
448
489
  }
449
490
  }
450
491
  async flush() {
451
- await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
492
+ try {
493
+ await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
494
+ } catch (err) {
495
+ this.warn("flush failed", err);
496
+ }
452
497
  }
453
498
  shutdown() {
454
499
  if (this.flushTimer) {
455
500
  clearInterval(this.flushTimer);
456
501
  this.flushTimer = null;
457
502
  }
458
- this.flush();
503
+ void this.flush();
459
504
  }
460
505
  captureGeoOnce() {
461
506
  if (this.geoRequested) return;
@@ -488,14 +533,8 @@ var Krypton = class {
488
533
  api_key: this.config.apiKey,
489
534
  events
490
535
  };
491
- try {
492
- await fetch(`${this.config.endpoint}/api/v1/ingest/batch`, {
493
- method: "POST",
494
- headers: { "Content-Type": "application/json" },
495
- body: JSON.stringify(payload),
496
- keepalive: true
497
- });
498
- } catch {
536
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/ingest/batch`, payload);
537
+ if (!ok) {
499
538
  if (this.eventQueue.length < this.config.batchSize * 5) {
500
539
  this.eventQueue.unshift(...events);
501
540
  }
@@ -508,14 +547,8 @@ var Krypton = class {
508
547
  api_key: this.config.apiKey,
509
548
  events
510
549
  };
511
- try {
512
- await fetch(`${this.config.endpoint}/api/v1/heatmap`, {
513
- method: "POST",
514
- headers: { "Content-Type": "application/json" },
515
- body: JSON.stringify(payload),
516
- keepalive: true
517
- });
518
- } catch {
550
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/heatmap`, payload);
551
+ if (!ok) {
519
552
  if (this.heatmapQueue.length < this.config.batchSize * 5) {
520
553
  this.heatmapQueue.unshift(...events);
521
554
  }
@@ -546,13 +579,7 @@ var Krypton = class {
546
579
  page_height: document.documentElement.scrollHeight,
547
580
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
548
581
  };
549
- fetch(`${this.config.endpoint}/api/v1/snapshot`, {
550
- method: "POST",
551
- headers: { "Content-Type": "application/json" },
552
- body: JSON.stringify(payload),
553
- keepalive: true
554
- }).catch(() => {
555
- });
582
+ void this.safePost(`${this.config.endpoint}/api/v1/snapshot`, payload);
556
583
  } catch {
557
584
  }
558
585
  }, 1e3);
@@ -564,50 +591,82 @@ var Krypton = class {
564
591
  this.captureSnapshot();
565
592
  document.addEventListener("click", (e) => {
566
593
  if (!this.isHeatmapFeatureEnabled()) return;
567
- const target = e.target;
568
- this.heatmapQueue.push({
569
- project_id: this.config.apiKey,
570
- distinct_id: this.distinctId,
571
- session_id: this.sessionId,
572
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
573
- page_url: window.location.href,
574
- interaction_type: "click",
575
- x: e.clientX + window.scrollX,
576
- y: e.clientY + window.scrollY,
577
- viewport_width: window.innerWidth,
578
- viewport_height: window.innerHeight,
579
- page_width: document.documentElement.scrollWidth,
580
- page_height: document.documentElement.scrollHeight,
581
- selector: getSelector(target)
582
- });
583
- });
584
- let maxScrollDepth = 0;
585
- let scrollTimeout = null;
586
- window.addEventListener("scroll", () => {
587
- if (!this.isHeatmapFeatureEnabled()) return;
588
- const scrollTop = window.scrollY || document.documentElement.scrollTop;
589
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
590
- const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
591
- if (depth > maxScrollDepth) {
592
- maxScrollDepth = depth;
593
- }
594
- if (scrollTimeout) clearTimeout(scrollTimeout);
595
- scrollTimeout = setTimeout(() => {
594
+ try {
595
+ const target = e.target;
596
596
  this.heatmapQueue.push({
597
597
  project_id: this.config.apiKey,
598
598
  distinct_id: this.distinctId,
599
599
  session_id: this.sessionId,
600
600
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
601
601
  page_url: window.location.href,
602
- interaction_type: "scroll",
603
- scroll_depth: maxScrollDepth,
602
+ interaction_type: "click",
603
+ x: e.clientX + window.scrollX,
604
+ y: e.clientY + window.scrollY,
604
605
  viewport_width: window.innerWidth,
605
606
  viewport_height: window.innerHeight,
606
607
  page_width: document.documentElement.scrollWidth,
607
- page_height: document.documentElement.scrollHeight
608
+ page_height: document.documentElement.scrollHeight,
609
+ selector: getSelector(target)
608
610
  });
609
- }, 500);
611
+ } catch (err) {
612
+ this.warn("heatmap click capture failed", err);
613
+ }
610
614
  });
615
+ let maxScrollDepth = 0;
616
+ let scrollTimeout = null;
617
+ window.addEventListener("scroll", () => {
618
+ if (!this.isHeatmapFeatureEnabled()) return;
619
+ try {
620
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
621
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
622
+ const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
623
+ if (depth > maxScrollDepth) {
624
+ maxScrollDepth = depth;
625
+ }
626
+ if (scrollTimeout) clearTimeout(scrollTimeout);
627
+ scrollTimeout = setTimeout(() => {
628
+ this.heatmapQueue.push({
629
+ project_id: this.config.apiKey,
630
+ distinct_id: this.distinctId,
631
+ session_id: this.sessionId,
632
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
633
+ page_url: window.location.href,
634
+ interaction_type: "scroll",
635
+ scroll_depth: maxScrollDepth,
636
+ viewport_width: window.innerWidth,
637
+ viewport_height: window.innerHeight,
638
+ page_width: document.documentElement.scrollWidth,
639
+ page_height: document.documentElement.scrollHeight
640
+ });
641
+ }, 500);
642
+ } catch (err) {
643
+ this.warn("heatmap scroll capture failed", err);
644
+ }
645
+ });
646
+ }
647
+ async safePost(url, payload) {
648
+ try {
649
+ const res = await fetch(url, {
650
+ method: "POST",
651
+ headers: { "Content-Type": "application/json" },
652
+ body: JSON.stringify(payload),
653
+ keepalive: true
654
+ });
655
+ if (!res.ok) {
656
+ this.warn(`API request failed (${res.status})`, { url });
657
+ return false;
658
+ }
659
+ return true;
660
+ } catch (err) {
661
+ this.warn("API request failed", { url, err });
662
+ return false;
663
+ }
664
+ }
665
+ warn(message, details) {
666
+ try {
667
+ console.warn(`${this.logPrefix} ${message}`, details ?? "");
668
+ } catch {
669
+ }
611
670
  }
612
671
  getBrowser() {
613
672
  if (typeof navigator === "undefined") return "unknown";
package/dist/index.mjs CHANGED
@@ -92,6 +92,7 @@ var Krypton = class {
92
92
  this.geoContext = null;
93
93
  this.serverConfig = null;
94
94
  this.configFetched = false;
95
+ this.logPrefix = "[Krypton SDK]";
95
96
  this.config = {
96
97
  autoPageview: true,
97
98
  heatmap: false,
@@ -118,6 +119,8 @@ var Krypton = class {
118
119
  if (this.config.consentRequired && this.config.showConsentBanner && !this.hasStoredConsent()) {
119
120
  this.showConsentBanner();
120
121
  }
122
+ }).catch((err) => {
123
+ this.warn("Initialization failed", err);
121
124
  });
122
125
  }
123
126
  resolveInitialConsent() {
@@ -215,38 +218,54 @@ var Krypton = class {
215
218
  }
216
219
  }
217
220
  setupTracking() {
218
- this.flushTimer = setInterval(() => this.flush(), this.config.flushInterval);
221
+ this.flushTimer = setInterval(() => {
222
+ void this.flush();
223
+ }, this.config.flushInterval);
219
224
  if (typeof window === "undefined") return;
220
- window.addEventListener("beforeunload", () => this.flush());
225
+ window.addEventListener("beforeunload", () => {
226
+ void this.flush();
227
+ });
221
228
  if (this.config.autoPageview && this.canTrackAnalytics()) {
222
229
  this.trackPageview();
223
230
  }
224
231
  const originalPushState = history.pushState;
225
232
  history.pushState = (...args) => {
226
- originalPushState.apply(history, args);
227
- if (this.config.autoPageview && this.canTrackAnalytics()) {
228
- setTimeout(() => this.trackPageview(), 0);
229
- }
230
- if (this.isHeatmapFeatureEnabled()) {
231
- setTimeout(() => this.captureSnapshot(), 0);
233
+ try {
234
+ originalPushState.apply(history, args);
235
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
236
+ setTimeout(() => this.trackPageview(), 0);
237
+ }
238
+ if (this.isHeatmapFeatureEnabled()) {
239
+ setTimeout(() => this.captureSnapshot(), 0);
240
+ }
241
+ } catch (err) {
242
+ this.warn("pushState hook failed", err);
232
243
  }
233
244
  };
234
245
  const originalReplaceState = history.replaceState;
235
246
  history.replaceState = (...args) => {
236
- originalReplaceState.apply(history, args);
237
- if (this.config.autoPageview && this.canTrackAnalytics()) {
238
- setTimeout(() => this.trackPageview(), 0);
239
- }
240
- if (this.isHeatmapFeatureEnabled()) {
241
- setTimeout(() => this.captureSnapshot(), 0);
247
+ try {
248
+ originalReplaceState.apply(history, args);
249
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
250
+ setTimeout(() => this.trackPageview(), 0);
251
+ }
252
+ if (this.isHeatmapFeatureEnabled()) {
253
+ setTimeout(() => this.captureSnapshot(), 0);
254
+ }
255
+ } catch (err) {
256
+ this.warn("replaceState hook failed", err);
242
257
  }
243
258
  };
244
259
  window.addEventListener("popstate", () => {
245
- if (this.config.autoPageview && this.canTrackAnalytics()) {
246
- setTimeout(() => this.trackPageview(), 0);
247
- }
248
- if (this.isHeatmapFeatureEnabled()) {
249
- setTimeout(() => this.captureSnapshot(), 0);
260
+ try {
261
+ if (this.config.autoPageview && this.canTrackAnalytics()) {
262
+ setTimeout(() => this.trackPageview(), 0);
263
+ }
264
+ if (this.isHeatmapFeatureEnabled()) {
265
+ setTimeout(() => this.captureSnapshot(), 0);
266
+ }
267
+ } catch (err) {
268
+ this.warn("popstate hook failed", err);
250
269
  }
251
270
  });
252
271
  if (this.isHeatmapFeatureEnabled()) {
@@ -303,58 +322,68 @@ var Krypton = class {
303
322
  `;
304
323
  const remove = () => {
305
324
  banner.remove();
325
+ try {
326
+ if (document.body) document.body.style.cursor = "";
327
+ if (document.documentElement) document.documentElement.style.cursor = "";
328
+ } catch {
329
+ }
306
330
  };
307
331
  const readValue = (id) => {
308
332
  const el = document.getElementById(id);
309
333
  return !!el?.checked;
310
334
  };
311
335
  banner.querySelector("#krypton-consent-save")?.addEventListener("click", () => {
312
- this.setConsent({
336
+ const next = {
313
337
  analytics: readValue("krypton-consent-analytics"),
314
338
  heatmaps: readValue("krypton-consent-heatmaps"),
315
339
  geo: readValue("krypton-consent-geo")
316
- });
340
+ };
317
341
  remove();
342
+ setTimeout(() => this.setConsent(next), 0);
318
343
  });
319
344
  banner.querySelector("#krypton-consent-all")?.addEventListener("click", () => {
320
- this.setConsent({ analytics: true, heatmaps: true, geo: true });
321
345
  remove();
346
+ setTimeout(() => this.setConsent({ analytics: true, heatmaps: true, geo: true }), 0);
322
347
  });
323
348
  banner.querySelector("#krypton-consent-none")?.addEventListener("click", () => {
324
- this.setConsent({ analytics: false, heatmaps: false, geo: false });
325
349
  remove();
350
+ setTimeout(() => this.setConsent({ analytics: false, heatmaps: false, geo: false }), 0);
326
351
  });
327
352
  document.body.appendChild(banner);
328
353
  }
329
354
  /** Set one or more consent categories and apply changes immediately. */
330
355
  setConsent(next, persist = true) {
331
- const prev = { ...this.consent };
332
- this.consent = {
333
- analytics: next.analytics ?? prev.analytics,
334
- heatmaps: next.heatmaps ?? prev.heatmaps,
335
- geo: next.geo ?? prev.geo
336
- };
337
- if (persist) {
338
- this.persistConsent();
339
- }
340
- if (!prev.analytics && this.consent.analytics) {
341
- this.promotePersistentIds();
342
- if (this.config.autoPageview) {
343
- this.trackPageview();
356
+ try {
357
+ const prev = { ...this.consent };
358
+ this.consent = {
359
+ analytics: next.analytics ?? prev.analytics,
360
+ heatmaps: next.heatmaps ?? prev.heatmaps,
361
+ geo: next.geo ?? prev.geo
362
+ };
363
+ if (persist) {
364
+ this.persistConsent();
344
365
  }
345
- }
346
- if (prev.analytics && !this.consent.analytics) {
347
- this.eventQueue = [];
348
- }
349
- if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
350
- this.setupHeatmap();
351
- this.captureSnapshot();
352
- }
353
- if (prev.heatmaps && !this.consent.heatmaps) {
354
- this.heatmapQueue = [];
355
- }
356
- if (!prev.geo && this.consent.geo) {
357
- this.captureGeoOnce();
366
+ if (!prev.analytics && this.consent.analytics) {
367
+ this.promotePersistentIds();
368
+ if (this.config.autoPageview) {
369
+ this.trackPageview();
370
+ }
371
+ }
372
+ if (prev.analytics && !this.consent.analytics) {
373
+ this.eventQueue = [];
374
+ }
375
+ if (!prev.heatmaps && this.isHeatmapFeatureEnabled()) {
376
+ this.setupHeatmap();
377
+ this.captureSnapshot();
378
+ }
379
+ if (prev.heatmaps && !this.consent.heatmaps) {
380
+ this.heatmapQueue = [];
381
+ }
382
+ if (!prev.geo && this.consent.geo) {
383
+ this.captureGeoOnce();
384
+ }
385
+ } catch (err) {
386
+ this.warn("setConsent failed", err);
358
387
  }
359
388
  }
360
389
  getConsent() {
@@ -372,65 +401,81 @@ var Krypton = class {
372
401
  }
373
402
  /** Identify a user with a custom distinct ID */
374
403
  identify(distinctId) {
375
- this.distinctId = distinctId;
376
- if (this.canTrackAnalytics()) {
377
- try {
378
- if (typeof localStorage !== "undefined") {
379
- localStorage.setItem("_krypton_did", distinctId);
404
+ try {
405
+ this.distinctId = distinctId;
406
+ if (this.canTrackAnalytics()) {
407
+ try {
408
+ if (typeof localStorage !== "undefined") {
409
+ localStorage.setItem("_krypton_did", distinctId);
410
+ }
411
+ } catch {
380
412
  }
381
- } catch {
382
413
  }
414
+ } catch (err) {
415
+ this.warn("identify failed", err);
383
416
  }
384
417
  }
385
418
  /** Track a pageview */
386
419
  trackPageview(properties) {
387
- if (!this.canTrackAnalytics()) return;
388
- this.track("$pageview", {
389
- ...properties
390
- });
420
+ try {
421
+ if (!this.canTrackAnalytics()) return;
422
+ this.track("$pageview", {
423
+ ...properties
424
+ });
425
+ } catch (err) {
426
+ this.warn("trackPageview failed", err);
427
+ }
391
428
  }
392
429
  /** Track a custom event */
393
430
  track(eventName, properties) {
394
- if (!this.canTrackAnalytics()) return;
395
- const utm = getUTMParams();
396
- const mergedProperties = { ...properties || {} };
397
- if (this.consent.geo && this.geoContext) {
398
- mergedProperties.geo = this.geoContext;
399
- }
400
- const event = {
401
- project_id: this.config.apiKey,
402
- distinct_id: this.distinctId,
403
- event_name: eventName,
404
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
405
- properties: mergedProperties,
406
- page_url: typeof window !== "undefined" ? window.location.href : "",
407
- page_title: typeof document !== "undefined" ? document.title : "",
408
- referrer: typeof document !== "undefined" ? document.referrer : "",
409
- utm_source: utm.utm_source || "",
410
- utm_medium: utm.utm_medium || "",
411
- utm_campaign: utm.utm_campaign || "",
412
- utm_term: utm.utm_term || "",
413
- utm_content: utm.utm_content || "",
414
- device_type: getDeviceType(),
415
- browser: this.getBrowser(),
416
- screen_width: typeof window !== "undefined" ? window.screen.width : 0,
417
- screen_height: typeof window !== "undefined" ? window.screen.height : 0,
418
- session_id: this.sessionId
419
- };
420
- this.eventQueue.push(event);
421
- if (this.eventQueue.length >= this.config.batchSize) {
422
- this.flush();
431
+ try {
432
+ if (!this.canTrackAnalytics()) return;
433
+ const utm = getUTMParams();
434
+ const mergedProperties = { ...properties || {} };
435
+ if (this.consent.geo && this.geoContext) {
436
+ mergedProperties.geo = this.geoContext;
437
+ }
438
+ const event = {
439
+ project_id: this.config.apiKey,
440
+ distinct_id: this.distinctId,
441
+ event_name: eventName,
442
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
443
+ properties: mergedProperties,
444
+ page_url: typeof window !== "undefined" ? window.location.href : "",
445
+ page_title: typeof document !== "undefined" ? document.title : "",
446
+ referrer: typeof document !== "undefined" ? document.referrer : "",
447
+ utm_source: utm.utm_source || "",
448
+ utm_medium: utm.utm_medium || "",
449
+ utm_campaign: utm.utm_campaign || "",
450
+ utm_term: utm.utm_term || "",
451
+ utm_content: utm.utm_content || "",
452
+ device_type: getDeviceType(),
453
+ browser: this.getBrowser(),
454
+ screen_width: typeof window !== "undefined" ? window.screen.width : 0,
455
+ screen_height: typeof window !== "undefined" ? window.screen.height : 0,
456
+ session_id: this.sessionId
457
+ };
458
+ this.eventQueue.push(event);
459
+ if (this.eventQueue.length >= this.config.batchSize) {
460
+ void this.flush();
461
+ }
462
+ } catch (err) {
463
+ this.warn("track failed", err);
423
464
  }
424
465
  }
425
466
  async flush() {
426
- await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
467
+ try {
468
+ await Promise.all([this.flushEvents(), this.flushHeatmapEvents()]);
469
+ } catch (err) {
470
+ this.warn("flush failed", err);
471
+ }
427
472
  }
428
473
  shutdown() {
429
474
  if (this.flushTimer) {
430
475
  clearInterval(this.flushTimer);
431
476
  this.flushTimer = null;
432
477
  }
433
- this.flush();
478
+ void this.flush();
434
479
  }
435
480
  captureGeoOnce() {
436
481
  if (this.geoRequested) return;
@@ -463,14 +508,8 @@ var Krypton = class {
463
508
  api_key: this.config.apiKey,
464
509
  events
465
510
  };
466
- try {
467
- await fetch(`${this.config.endpoint}/api/v1/ingest/batch`, {
468
- method: "POST",
469
- headers: { "Content-Type": "application/json" },
470
- body: JSON.stringify(payload),
471
- keepalive: true
472
- });
473
- } catch {
511
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/ingest/batch`, payload);
512
+ if (!ok) {
474
513
  if (this.eventQueue.length < this.config.batchSize * 5) {
475
514
  this.eventQueue.unshift(...events);
476
515
  }
@@ -483,14 +522,8 @@ var Krypton = class {
483
522
  api_key: this.config.apiKey,
484
523
  events
485
524
  };
486
- try {
487
- await fetch(`${this.config.endpoint}/api/v1/heatmap`, {
488
- method: "POST",
489
- headers: { "Content-Type": "application/json" },
490
- body: JSON.stringify(payload),
491
- keepalive: true
492
- });
493
- } catch {
525
+ const ok = await this.safePost(`${this.config.endpoint}/api/v1/heatmap`, payload);
526
+ if (!ok) {
494
527
  if (this.heatmapQueue.length < this.config.batchSize * 5) {
495
528
  this.heatmapQueue.unshift(...events);
496
529
  }
@@ -521,13 +554,7 @@ var Krypton = class {
521
554
  page_height: document.documentElement.scrollHeight,
522
555
  timestamp: (/* @__PURE__ */ new Date()).toISOString()
523
556
  };
524
- fetch(`${this.config.endpoint}/api/v1/snapshot`, {
525
- method: "POST",
526
- headers: { "Content-Type": "application/json" },
527
- body: JSON.stringify(payload),
528
- keepalive: true
529
- }).catch(() => {
530
- });
557
+ void this.safePost(`${this.config.endpoint}/api/v1/snapshot`, payload);
531
558
  } catch {
532
559
  }
533
560
  }, 1e3);
@@ -539,50 +566,82 @@ var Krypton = class {
539
566
  this.captureSnapshot();
540
567
  document.addEventListener("click", (e) => {
541
568
  if (!this.isHeatmapFeatureEnabled()) return;
542
- const target = e.target;
543
- this.heatmapQueue.push({
544
- project_id: this.config.apiKey,
545
- distinct_id: this.distinctId,
546
- session_id: this.sessionId,
547
- timestamp: (/* @__PURE__ */ new Date()).toISOString(),
548
- page_url: window.location.href,
549
- interaction_type: "click",
550
- x: e.clientX + window.scrollX,
551
- y: e.clientY + window.scrollY,
552
- viewport_width: window.innerWidth,
553
- viewport_height: window.innerHeight,
554
- page_width: document.documentElement.scrollWidth,
555
- page_height: document.documentElement.scrollHeight,
556
- selector: getSelector(target)
557
- });
558
- });
559
- let maxScrollDepth = 0;
560
- let scrollTimeout = null;
561
- window.addEventListener("scroll", () => {
562
- if (!this.isHeatmapFeatureEnabled()) return;
563
- const scrollTop = window.scrollY || document.documentElement.scrollTop;
564
- const docHeight = document.documentElement.scrollHeight - window.innerHeight;
565
- const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
566
- if (depth > maxScrollDepth) {
567
- maxScrollDepth = depth;
568
- }
569
- if (scrollTimeout) clearTimeout(scrollTimeout);
570
- scrollTimeout = setTimeout(() => {
569
+ try {
570
+ const target = e.target;
571
571
  this.heatmapQueue.push({
572
572
  project_id: this.config.apiKey,
573
573
  distinct_id: this.distinctId,
574
574
  session_id: this.sessionId,
575
575
  timestamp: (/* @__PURE__ */ new Date()).toISOString(),
576
576
  page_url: window.location.href,
577
- interaction_type: "scroll",
578
- scroll_depth: maxScrollDepth,
577
+ interaction_type: "click",
578
+ x: e.clientX + window.scrollX,
579
+ y: e.clientY + window.scrollY,
579
580
  viewport_width: window.innerWidth,
580
581
  viewport_height: window.innerHeight,
581
582
  page_width: document.documentElement.scrollWidth,
582
- page_height: document.documentElement.scrollHeight
583
+ page_height: document.documentElement.scrollHeight,
584
+ selector: getSelector(target)
583
585
  });
584
- }, 500);
586
+ } catch (err) {
587
+ this.warn("heatmap click capture failed", err);
588
+ }
585
589
  });
590
+ let maxScrollDepth = 0;
591
+ let scrollTimeout = null;
592
+ window.addEventListener("scroll", () => {
593
+ if (!this.isHeatmapFeatureEnabled()) return;
594
+ try {
595
+ const scrollTop = window.scrollY || document.documentElement.scrollTop;
596
+ const docHeight = document.documentElement.scrollHeight - window.innerHeight;
597
+ const depth = docHeight > 0 ? scrollTop / docHeight * 100 : 0;
598
+ if (depth > maxScrollDepth) {
599
+ maxScrollDepth = depth;
600
+ }
601
+ if (scrollTimeout) clearTimeout(scrollTimeout);
602
+ scrollTimeout = setTimeout(() => {
603
+ this.heatmapQueue.push({
604
+ project_id: this.config.apiKey,
605
+ distinct_id: this.distinctId,
606
+ session_id: this.sessionId,
607
+ timestamp: (/* @__PURE__ */ new Date()).toISOString(),
608
+ page_url: window.location.href,
609
+ interaction_type: "scroll",
610
+ scroll_depth: maxScrollDepth,
611
+ viewport_width: window.innerWidth,
612
+ viewport_height: window.innerHeight,
613
+ page_width: document.documentElement.scrollWidth,
614
+ page_height: document.documentElement.scrollHeight
615
+ });
616
+ }, 500);
617
+ } catch (err) {
618
+ this.warn("heatmap scroll capture failed", err);
619
+ }
620
+ });
621
+ }
622
+ async safePost(url, payload) {
623
+ try {
624
+ const res = await fetch(url, {
625
+ method: "POST",
626
+ headers: { "Content-Type": "application/json" },
627
+ body: JSON.stringify(payload),
628
+ keepalive: true
629
+ });
630
+ if (!res.ok) {
631
+ this.warn(`API request failed (${res.status})`, { url });
632
+ return false;
633
+ }
634
+ return true;
635
+ } catch (err) {
636
+ this.warn("API request failed", { url, err });
637
+ return false;
638
+ }
639
+ }
640
+ warn(message, details) {
641
+ try {
642
+ console.warn(`${this.logPrefix} ${message}`, details ?? "");
643
+ } catch {
644
+ }
586
645
  }
587
646
  getBrowser() {
588
647
  if (typeof navigator === "undefined") return "unknown";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kryptonhq/analytics",
3
- "version": "0.1.2",
3
+ "version": "0.1.3",
4
4
  "description": "Krypton Analytics JavaScript SDK — privacy-first analytics tracking",
5
5
  "main": "dist/index.js",
6
6
  "module": "dist/index.mjs",