@traffical/js-client 0.16.0 → 0.16.1

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,3 +1,3 @@
1
- /* @traffical/js-client v0.16.0 */
2
- "use strict";var Traffical=(()=>{var q=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var st=(r,e,t)=>e in r?q(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var at=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ct=(r,e)=>{for(var t in e)q(r,t,{get:e[t],enumerable:!0})},lt=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of rt(e))!ot.call(r,i)&&i!==t&&q(r,i,{get:()=>e[i],enumerable:!(n=it(e,i))||n.enumerable});return r};var ut=r=>lt(q({},"__esModule",{value:!0}),r);var m=(r,e,t)=>(st(r,typeof e!="symbol"?e+"":e,t),t);var He=at(()=>{});var En={};ct(En,{TrafficalClient:()=>M,createDOMBindingPlugin:()=>nt,createDebugPlugin:()=>Me,createRedirectAttributionPlugin:()=>Le,createRedirectPlugin:()=>Re,destroy:()=>xn,init:()=>vn,initSync:()=>_n,instance:()=>bn});function dt(r){return r instanceof Uint8Array||ArrayBuffer.isView(r)&&r.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in r&&r.BYTES_PER_ELEMENT===1}function he(r,e,t=""){let n=dt(r),i=r?.length,o=e!==void 0;if(!n||o&&i!==e){let s=t&&`"${t}" `,a=o?` of length ${e}`:"",c=n?`length=${i}`:`type=${typeof r}`,f=s+"expected Uint8Array"+a+", got "+c;throw n?new RangeError(f):new TypeError(f)}return r}function pe(r,e=!0){if(r.destroyed)throw new Error("Hash instance has been destroyed");if(e&&r.finished)throw new Error("Hash#digest() has already been called")}function Be(r,e){he(r,void 0,"digestInto() output");let t=e.outputLen;if(r.length<t)throw new RangeError('"digestInto() output" expected to be of length >='+t)}function B(...r){for(let e=0;e<r.length;e++)r[e].fill(0)}function X(r){return new DataView(r.buffer,r.byteOffset,r.byteLength)}function I(r,e){return r<<32-e|r>>>e}function Ne(r,e={}){let t=(i,o)=>r(o).update(i).digest(),n=r(void 0);return t.outputLen=n.outputLen,t.blockLen=n.blockLen,t.canXOF=n.canXOF,t.create=i=>r(i),Object.assign(t,e),Object.freeze(t)}var Ve=r=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,r])});function Ue(r,e,t){return r&e^~r&t}function Fe(r,e,t){return r&e^r&t^e&t}var J=class{constructor(e,t,n,i){m(this,"blockLen");m(this,"outputLen");m(this,"canXOF",!1);m(this,"padOffset");m(this,"isLE");m(this,"buffer");m(this,"view");m(this,"finished",!1);m(this,"length",0);m(this,"pos",0);m(this,"destroyed",!1);this.blockLen=e,this.outputLen=t,this.padOffset=n,this.isLE=i,this.buffer=new Uint8Array(e),this.view=X(this.buffer)}update(e){pe(this),he(e);let{view:t,buffer:n,blockLen:i}=this,o=e.length;for(let s=0;s<o;){let a=Math.min(i-this.pos,o-s);if(a===i){let c=X(e);for(;i<=o-s;s+=i)this.process(c,s);continue}n.set(e.subarray(s,s+a),this.pos),this.pos+=a,s+=a,this.pos===i&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){pe(this),Be(e,this),this.finished=!0;let{buffer:t,view:n,blockLen:i,isLE:o}=this,{pos:s}=this;t[s++]=128,B(this.buffer.subarray(s)),this.padOffset>i-s&&(this.process(n,0),s=0);for(let l=s;l<i;l++)t[l]=0;n.setBigUint64(i-8,BigInt(this.length*8),o),this.process(n,0);let a=X(e),c=this.outputLen;if(c%4)throw new Error("_sha2: outputLen must be aligned to 32bit");let f=c/4,h=this.get();if(f>h.length)throw new Error("_sha2: outputLen bigger than state");for(let l=0;l<f;l++)a.setUint32(4*l,h[l],o)}digest(){let{buffer:e,outputLen:t}=this;this.digestInto(e);let n=e.slice(0,t);return this.destroy(),n}_cloneInto(e){e||(e=new this.constructor),e.set(...this.get());let{blockLen:t,buffer:n,length:i,finished:o,destroyed:s,pos:a}=this;return e.destroyed=s,e.finished=o,e.length=i,e.pos=a,i%t&&e.buffer.set(n),e}clone(){return this._cloneInto()}},k=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var ft=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),S=new Uint32Array(64),me=class extends J{constructor(e){super(64,e,8,!1)}get(){let{A:e,B:t,C:n,D:i,E:o,F:s,G:a,H:c}=this;return[e,t,n,i,o,s,a,c]}set(e,t,n,i,o,s,a,c){this.A=e|0,this.B=t|0,this.C=n|0,this.D=i|0,this.E=o|0,this.F=s|0,this.G=a|0,this.H=c|0}process(e,t){for(let l=0;l<16;l++,t+=4)S[l]=e.getUint32(t,!1);for(let l=16;l<64;l++){let _=S[l-15],u=S[l-2],g=I(_,7)^I(_,18)^_>>>3,y=I(u,17)^I(u,19)^u>>>10;S[l]=y+S[l-7]+g+S[l-16]|0}let{A:n,B:i,C:o,D:s,E:a,F:c,G:f,H:h}=this;for(let l=0;l<64;l++){let _=I(a,6)^I(a,11)^I(a,25),u=h+_+Ue(a,c,f)+ft[l]+S[l]|0,y=(I(n,2)^I(n,13)^I(n,22))+Fe(n,i,o)|0;h=f,f=c,c=a,a=s+u|0,s=o,o=i,i=n,n=u+y|0}n=n+this.A|0,i=i+this.B|0,o=o+this.C|0,s=s+this.D|0,a=a+this.E|0,c=c+this.F|0,f=f+this.G|0,h=h+this.H|0,this.set(n,i,o,s,a,c,f,h)}roundClean(){B(S)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),B(this.buffer)}},ye=class extends me{constructor(){super(32);m(this,"A",k[0]|0);m(this,"B",k[1]|0);m(this,"C",k[2]|0);m(this,"D",k[3]|0);m(this,"E",k[4]|0);m(this,"F",k[5]|0);m(this,"G",k[6]|0);m(this,"H",k[7]|0)}};var Ke=Ne(()=>new ye,Ve(1));var $e=new TextEncoder,ve="v2";function Q(r){return $e.encode(r).length}function Y(r,e){let t=Q(r),n=Q(e);return`traffical:assignment:${ve}|u:${t}:${r}|l:${n}:${e}`}function N(r){return Ke($e.encode(r))}function V(r){let e=0n;for(let t=0;t<8;t++)e=e<<8n|BigInt(r[t]);return e}function Z(r){return V(N(r))}function ee(r,e,t){let n=N(Y(r,e)),i=V(n);return Number(i%BigInt(t))}function _e(r,e){return r>=e[0]&&r<=e[1]}function te(r,e){for(let t of e)if(_e(r,t.bucketRange))return t;return null}var gt=1n<<53n,ht=9007199254740992;function R(r,e){if(r.length===0||r.length===1)return 0;let t=Z(e),n=Number(t%gt)/ht,i=0;for(let o=0;o<r.length;o++)if(i+=r[o],n<i)return o;return r.length-1}function be(r,e){let{field:t,op:n,value:i,values:o}=r,s=yt(e,t);switch(n){case"eq":return s===i;case"neq":return s!==i;case"in":return Array.isArray(o)?o.includes(s):!1;case"nin":return Array.isArray(o)?!o.includes(s):!0;case"gt":return typeof s=="number"&&s>i;case"gte":return typeof s=="number"&&s>=i;case"lt":return typeof s=="number"&&s<i;case"lte":return typeof s=="number"&&s<=i;case"contains":return typeof s=="string"&&typeof i=="string"&&s.includes(i);case"startsWith":return typeof s=="string"&&typeof i=="string"&&s.startsWith(i);case"endsWith":return typeof s=="string"&&typeof i=="string"&&s.endsWith(i);case"regex":if(typeof s!="string"||typeof i!="string")return!1;try{return new RegExp(i).test(s)}catch{return!1}case"exists":return s!=null;case"notExists":return s==null;default:return!1}}function ne(r,e){return r.length===0?!0:r.every(t=>be(t,e))}function yt(r,e){let t=e.split("."),n=r;for(let i of t){if(n==null)return;if(typeof n=="object")n=n[i];else return}return n}function xe(r,e){let t=r.intercept;for(let{key:n,coef:i,missing:o}of r.numeric){let s=e[n];t+=typeof s=="number"?i*s:o}for(let{key:n,values:i,missing:o}of r.categorical){let s=e[n],a=s!=null?String(s):null;t+=a!==null&&a in i?i[a]:o}return t}function Ee(r,e){if(r.length===0)return[];if(r.length===1)return[1];let t=Math.max(e,1e-10),n=r.map(a=>a/t),i=Math.max(...n),o=n.map(a=>Math.exp(a-i)),s=o.reduce((a,c)=>a+c,0);return o.map(a=>a/s)}function Te(r,e){if(r.length===0)return[];if(e<=0)return r;let t=r.length,n=1/t,i=Math.min(e,n),o=r.map(a=>Math.max(a,i)),s=o.reduce((a,c)=>a+c,0);return s===0?Array(t).fill(1/t):o.map(a=>a/s)}function ie(r,e,t){let n=r.contextualModel;if(!n||r.allocations.length===0)return null;let i=vt(n,r.allocations,e),o=Ee(i,n.gamma),s=Te(o,n.actionProbabilityFloor),a=`ctx:${t}:${r.id}`,c=R(s,a);return{allocation:r.allocations[c],probability:s[c]}}function vt(r,e,t){return e.map(n=>{let i=r.coefficients[n.name];return i?xe(i,t):r.defaultAllocationScore})}var _t=r=>crypto.getRandomValues(new Uint8Array(r)),bt=(r,e,t)=>{let n=(2<<Math.log2(r.length-1))-1,i=-~(1.6*n*e/r.length);return(o=e)=>{let s="";for(;;){let a=t(i),c=i|0;for(;c--;)if(s+=r[a[c]&n]||"",s.length>=o)return s}}},je=(r,e=21)=>bt(r,e|0,_t);function re(r){let e=new Error(r);return e.source="ulid",e}var Ie="0123456789ABCDEFGHJKMNPQRSTVWXYZ",U=Ie.length,We=Math.pow(2,48)-1,xt=10,Et=16;function Tt(r){let e=Math.floor(r()*U);return e===U&&(e=U-1),Ie.charAt(e)}function It(r,e){if(isNaN(r))throw new Error(r+" must be a number");if(r>We)throw re("cannot encode time greater than "+We);if(r<0)throw re("time must be positive");if(Number.isInteger(Number(r))===!1)throw re("time must be an integer");let t,n="";for(;e>0;e--)t=r%U,n=Ie.charAt(t)+n,r=(r-t)/U;return n}function wt(r,e){let t="";for(;r>0;r--)t=Tt(e)+t;return t}function At(r=!1,e){e||(e=typeof window<"u"?window:null);let t=e&&(e.crypto||e.msCrypto);if(t)return()=>{let n=new Uint8Array(1);return t.getRandomValues(n),n[0]/255};try{let n=He();return()=>n.randomBytes(1).readUInt8()/255}catch{}if(r){try{console.error("secure crypto unusable, falling back to insecure Math.random()!")}catch{}return()=>Math.random()}throw re("secure crypto unusable, insecure Math.random not allowed")}function Ct(r){return r||(r=At()),function(t){return isNaN(t)&&(t=Date.now()),It(t,xt)+wt(Et,r)}}var ze=Ct();var kt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",St=8,ei=je(kt,St);function F(r){return`${r}_${ze()}`}function L(){return F("dec")}function we(){return F("exp")}function Ae(){return F("trk")}function Ce(){return F("asn")}function Dt(r,e){let t=new Set;for(let i of e)if(i.contextLogging?.allowedFields)for(let o of i.contextLogging.allowedFields)t.add(o);if(t.size===0)return;let n={};for(let i of t)i in r&&(n[i]=r[i]);return Object.keys(n).length>0?n:void 0}function Pt(r,e){let t=[];for(let n of r){let i=e[n];if(i==null)return null;t.push(String(i))}return t.join("_")}function Ge(r){if(r<=0)return[];let e=1/r;return Array(r).fill(e)}function Rt(r,e,t,n){let i=r.entityState?.[e];if(!i)return Ge(n);let o=i.entities[t];if(o&&o.weights.length===n)return o.weights;let s=i._global;return s&&s.weights.length===n?s.weights:Ge(n)}function Lt(r,e,t,n){let i=e.entityConfig;if(!i)return null;let o=Pt(i.entityKeys,t);if(!o)return null;let s,a;if(i.dynamicAllocations){let l=i.dynamicAllocations.countKey,_=t[l];if(typeof _!="number"||_<=0)return null;a=Math.floor(_),s=Array.from({length:a},(u,g)=>({id:`${e.id}_dynamic_${g}`,name:String(g),bucketRange:[0,0],overrides:{}}))}else s=e.allocations,a=s.length;if(a===0)return null;let c=Rt(r,e.id,o,a),f=`${o}:${n}:${e.id}`,h=R(c,f);return{allocation:s[h],weight:c[h],entityId:o}}function K(r,e){let t=e[r.hashing.unitKey];return t==null?null:String(t)}function oe(r){return r?.hashing?.unitKey??null}function se(r,e){return r?r.parameters.find(n=>n.key===e)?.layerId??null:null}function qe(r,e,t,n){let i={...t},o=[],s=[];if(!r)return{assignments:i,unitKeyValue:"",layers:o,matchedPolicies:s};let a=K(r,e)??"",c=new Set(Object.keys(t)),f=r.parameters.filter(l=>c.has(l.key));for(let l of f)l.key in i&&(i[l.key]=l.default);let h=new Map;for(let l of f){let _=h.get(l.layerId)||[];_.push(l),h.set(l.layerId,_)}for(let l of r.layers){let _=h.get(l.id),u=_&&_.length>0,g=l.unitKey,y=g!=null;if(y&&String(g).trim()===""){o.push({layerId:l.id,bucket:-1,...u?{}:{attributionOnly:!0}});continue}let b=y?String(e[g]??""):a;if(!b){o.push({layerId:l.id,bucket:-1,...y?{unitKey:g,unitKeyValue:""}:{},...u?{}:{attributionOnly:!0}});continue}let w=ee(b,l.id,r.hashing.bucketCount),d,v,A,O;for(let p of l.policies)if(p.state==="running"){if(p.eligibleBucketRange){let{start:x,end:E}=p.eligibleBucketRange;if(w<x||w>E)continue}if(ne(p.conditions,e)){if(p.contextualModel){let x=ie(p,e,b);if(x){if(d=p,v=x.allocation,A=x.probability,O=p.contextualModel.generatedAt??p.contextualModel.modelVersion,s.push(p),u)for(let[E,C]of Object.entries(x.allocation.overrides))E in i&&(i[E]=C);break}}if(p.entityConfig&&p.entityConfig.resolutionMode==="bundle"){let x=Lt(r,p,e,b);if(x){if(d=p,v=x.allocation,A=x.weight,s.push(p),u&&!p.entityConfig.dynamicAllocations)for(let[E,C]of Object.entries(x.allocation.overrides))E in i&&(i[E]=C);break}}else if(p.entityConfig&&p.entityConfig.resolutionMode==="edge"){let x=n?.edgeResults?.get(p.id);if(x){if(d=p,s.push(p),p.entityConfig.dynamicAllocations)v={id:`${p.id}_dynamic_${x.allocationIndex}`,name:String(x.allocationIndex),bucketRange:[0,0],overrides:{}};else if(p.allocations[x.allocationIndex]&&(v=p.allocations[x.allocationIndex],u&&v))for(let[E,C]of Object.entries(v.overrides))E in i&&(i[E]=C);break}continue}else{let x=te(w,p.allocations);if(x){if(d=p,v=x,p.kind==="adaptive"){let[E,C]=x.bucketRange;A=(C-E+1)/r.hashing.bucketCount}if(s.push(p),u)for(let[E,C]of Object.entries(x.overrides))E in i&&(i[E]=C);break}}}}o.push({layerId:l.id,bucket:w,policyId:d?.id,policyKey:d?.key,allocationId:v?.id,allocationName:v?.name,allocationKey:v?.key,...A!==void 0&&A>0&&A<=1?{probability:A}:{},...O!==void 0?{modelVersion:O}:{},...y?{unitKey:g,unitKeyValue:b}:{},...u?{}:{attributionOnly:!0}})}return{assignments:i,unitKeyValue:a,layers:o,matchedPolicies:s}}function ae(r,e,t,n){return qe(r,e,t,n).assignments}function ce(r,e,t,n){let{assignments:i,unitKeyValue:o,layers:s,matchedPolicies:a}=qe(r,e,t,n),c=Dt(e,a);return{decisionId:L(),assignments:i,metadata:{timestamp:new Date().toISOString(),unitKeyValue:o,layers:s,filteredContext:c,...r?.version?{configVersion:r.version}:{}}}}var P=class r{constructor(e={}){m(this,"_seen",new Map);m(this,"_ttlMs");m(this,"_maxEntries");m(this,"_lastCleanup",Date.now());this._ttlMs=e.ttlMs??36e5,this._maxEntries=e.maxEntries??1e4}static hashAssignments(e){let t=Object.keys(e).sort(),n=[];for(let i of t){let o=e[i],s=typeof o=="object"?JSON.stringify(o):String(o);n.push(`${i}=${s}`)}return n.join("|")}static createKey(e,t){return`${e}:${t}`}checkAndMark(e,t){let n=r.createKey(e,t),i=Date.now(),o=this._seen.get(n);return o!==void 0&&i-o<this._ttlMs?!1:(this._seen.set(n,i),this._maybeCleanup(i),!0)}wouldBeNew(e,t){let n=r.createKey(e,t),i=Date.now(),o=this._seen.get(n);return o===void 0?!0:i-o>=this._ttlMs}clear(){this._seen.clear()}get size(){return this._seen.size}_maybeCleanup(e){(e-this._lastCleanup>this._ttlMs*.2||this._seen.size>this._maxEntries)&&(this._lastCleanup=e,this._cleanup(e))}_cleanup(e){let t=[];for(let[n,i]of this._seen.entries())e-i>=this._ttlMs&&t.push(n);for(let n of t)this._seen.delete(n);if(this._seen.size>this._maxEntries){let i=Array.from(this._seen.entries()).sort((o,s)=>o[1]-s[1]).slice(0,this._seen.size-this._maxEntries);for(let[o]of i)this._seen.delete(o)}}};var $=class{constructor(e){m(this,"config");m(this,"defaultTimeout");this.config=e,this.defaultTimeout=e.defaultTimeoutMs??5e3}async resolve(e){try{let t=new AbortController,n=setTimeout(()=>t.abort(),this.defaultTimeout),i=`${this.config.baseUrl}/v1/resolve`,o=await fetch(i,{method:"POST",headers:this._headers(),body:JSON.stringify({context:e.context,env:e.env??this.config.env,parameters:e.parameters}),signal:t.signal});return clearTimeout(n),o.ok?await o.json():(console.warn(`[Traffical] Resolve failed: ${o.status} ${o.statusText}`),null)}catch(t){return t instanceof Error&&t.name==="AbortError"?console.warn(`[Traffical] Resolve timed out after ${this.defaultTimeout}ms`):console.warn("[Traffical] Resolve error:",t),null}}async decideEntity(e,t){let n=t??Math.min(this.defaultTimeout,100);try{let i=new AbortController,o=setTimeout(()=>i.abort(),n),s=`${this.config.baseUrl}/v1/decide/${e.policyId}`,a=await fetch(s,{method:"POST",headers:this._headers(),body:JSON.stringify({entityId:e.entityId,unitKeyValue:e.unitKeyValue,allocationCount:e.allocationCount,context:e.context}),signal:i.signal});return clearTimeout(o),a.ok?await a.json():(console.warn(`[Traffical] Edge decide failed: ${a.status} ${a.statusText}`),null)}catch(i){return i instanceof Error&&i.name==="AbortError"?console.warn(`[Traffical] Edge decide timed out after ${n}ms`):console.warn("[Traffical] Edge decide error:",i),null}}async decideEntityBatch(e,t){if(e.length===0)return[];if(e.length===1)return[await this.decideEntity(e[0],t)];let n=t??Math.min(this.defaultTimeout,200);try{let i=new AbortController,o=setTimeout(()=>i.abort(),n),s=`${this.config.baseUrl}/v1/decide/batch`,a=await fetch(s,{method:"POST",headers:this._headers(),body:JSON.stringify({requests:e}),signal:i.signal});return clearTimeout(o),a.ok?(await a.json()).responses:(console.warn(`[Traffical] Edge batch decide failed: ${a.status} ${a.statusText}`),e.map(()=>null))}catch(i){return i instanceof Error&&i.name==="AbortError"?console.warn(`[Traffical] Edge batch decide timed out after ${n}ms`):console.warn("[Traffical] Edge batch decide error:",i),e.map(()=>null)}}_headers(){return{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,"X-Org-Id":this.config.orgId,"X-Project-Id":this.config.projectId,"X-Env":this.config.env}}};function ke(r,e,t,n,i){let o=[];for(let a of e){let c=t[a];if(c==null)return null;o.push(String(c))}let s=o.join("_");return{policyId:r,entityId:s,unitKeyValue:n,allocationCount:i,context:t}}var le=class{constructor(e={}){this._seen=new Set;this._lastError=null;this._options=e}capture(e,t,n){try{return t()}catch(i){return this._onError(e,i),n}}async captureAsync(e,t,n){try{return await t()}catch(i){return this._onError(e,i),n}}async swallow(e,t){try{await t()}catch(n){this._onError(e,n)}}getLastError(){let e=this._lastError;return this._lastError=null,e}clearSeen(){this._seen.clear()}_onError(e,t){let n=this._resolveError(t);this._lastError=n;let i=`${e}:${n.name}:${n.message}`;this._seen.has(i)||(this._seen.add(i),console.warn(`[Traffical] Error in ${e}:`,n.message),this._options.onError?.(e,n),this._options.reportErrors&&this._options.errorEndpoint&&this._reportError(e,n).catch(()=>{}))}async _reportError(e,t){if(this._options.errorEndpoint)try{await fetch(this._options.errorEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...this._options.sdkKey&&{"X-Traffical-Key":this._options.sdkKey}},body:JSON.stringify({tag:e,error:t.name,message:t.message,stack:t.stack,timestamp:new Date().toISOString(),sdk:"@traffical/js-client",userAgent:typeof navigator<"u"?navigator.userAgent:void 0})})}catch{}}_resolveError(e){return e instanceof Error?e:typeof e=="string"?new Error(e):new Error("An unknown error occurred")}};var j="failed_events";var ue=class{constructor(e){this._queue=[];this._flushTimer=null;this._isFlushing=!1;this._isDisabled=!1;this._droppedCount=0;this._endpoint=e.endpoint,this._apiKey=e.apiKey,this._storage=e.storage,this._batchSize=e.batchSize??10,this._flushIntervalMs=e.flushIntervalMs??3e4,this._requestTimeoutMs=e.requestTimeoutMs??1e4,this._maxQueueSize=e.maxQueueSize??1e3,this._onError=e.onError,this._onSchemaWarnings=e.onSchemaWarnings,this._lifecycleProvider=e.lifecycleProvider,this._setupListeners(),this._retryFailedEvents(),this._startFlushTimer()}log(e){this._isDisabled||(this._queue.length>=this._maxQueueSize&&(this._queue.shift(),this._droppedCount++),this._queue.push(e),this._queue.length>=this._batchSize&&this.flush())}async flush(){if(this._isFlushing||this._isDisabled||this._queue.length===0)return;this._isFlushing=!0;let e=[...this._queue];this._queue=[];try{let t=await this._sendEvents(e);if(t>=200&&t<300)return;if(t===401){this._disable();return}if(t===429||t>=500){this._persistFailedEvents(e),this._onError?.(new Error(`HTTP ${t}: event delivery failed, will retry`));return}this._onError?.(new Error(`HTTP ${t}: batch rejected, dropping ${e.length} events`))}catch(t){this._persistFailedEvents(e),this._onError?.(t instanceof Error?t:new Error(String(t)))}finally{this._isFlushing=!1}}_disable(){this._isDisabled||(this._isDisabled=!0,this._queue=[],this._storage.remove(j),console.warn("[Traffical] API key rejected (HTTP 401); event delivery disabled for this client"))}get droppedCount(){return this._droppedCount}get isDisabled(){return this._isDisabled}flushBeacon(){if(this._queue.length===0)return!0;if(typeof fetch>"u")return this.flush(),!1;let e=[...this._queue];return this._queue=[],fetch(this._endpoint,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this._apiKey}`},body:JSON.stringify({events:e}),keepalive:!0}).catch(()=>{this._persistFailedEvents(e)}),!0}get queueSize(){return this._queue.length}destroy(){this._flushTimer&&(clearInterval(this._flushTimer),this._flushTimer=null),this._removeListeners()}async _sendEvents(e){let t=new AbortController,n=setTimeout(()=>t.abort(),this._requestTimeoutMs),i;try{i=await fetch(this._endpoint,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this._apiKey}`},body:JSON.stringify({events:e}),signal:t.signal})}finally{clearTimeout(n)}if(!i.ok)return i.status;if(this._onSchemaWarnings)try{let o=await i.json();o.schemaWarnings&&o.schemaWarnings.length>0&&this._onSchemaWarnings(o.schemaWarnings)}catch{}return i.status}_persistFailedEvents(e){let n=[...this._storage.get(j)??[],...e].slice(-100);this._storage.set(j,n)}_retryFailedEvents(){let e=this._storage.get(j);!e||e.length===0||(this._storage.remove(j),this._queue.push(...e))}_startFlushTimer(){this._flushIntervalMs<=0||(this._flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this._flushIntervalMs))}_setupListeners(){this._lifecycleProvider&&(this._visibilityCallback=e=>{e==="background"?this._lifecycleProvider?.isUnloading()?this.flushBeacon():this.flush().catch(()=>{}):this._retryFailedEvents()},this._lifecycleProvider.onVisibilityChange(this._visibilityCallback))}_removeListeners(){this._lifecycleProvider&&this._visibilityCallback&&(this._lifecycleProvider.removeVisibilityListener(this._visibilityCallback),this._visibilityCallback=void 0)}};var H="exposure_dedup";var W=class r{constructor(e){this._storage=e.storage,this._sessionTtlMs=e.sessionTtlMs??18e5,this._seen=new Set,this._sessionStart=Date.now(),this._restore()}static createKey(e,t,n){return`${e}:${t}:${n}`}shouldTrack(e){return this._isSessionExpired()&&this._resetSession(),this._seen.has(e)?!1:(this._seen.add(e),this._persist(),!0)}checkAndMark(e,t,n){let i=r.createKey(e,t,n);return this.shouldTrack(i)}clear(){this._seen.clear(),this._storage.remove(H)}get size(){return this._seen.size}_isSessionExpired(){return Date.now()-this._sessionStart>this._sessionTtlMs}_resetSession(){this._seen.clear(),this._sessionStart=Date.now(),this._storage.remove(H)}_persist(){let e={seen:Array.from(this._seen),sessionStart:this._sessionStart};this._storage.set(H,e,this._sessionTtlMs)}_restore(){let e=this._storage.get(H);if(!e)return;if(Date.now()-e.sessionStart>this._sessionTtlMs){this._storage.remove(H);return}this._seen=new Set(e.seen),this._sessionStart=e.sessionStart}};var z="stable_id",Xt="traffical_sid";var de=class{constructor(e){this._cachedId=null;this._storage=e.storage,this._useCookieFallback=e.useCookieFallback??!0,this._cookieName=e.cookieName??Xt}getId(){if(this._cachedId)return this._cachedId;let e=this._storage.get(z);return e?(this._cachedId=e,e):this._useCookieFallback&&(e=this._getCookie(),e)?(this._storage.set(z,e),this._cachedId=e,e):(e=this._generateId(),this._persist(e),this._cachedId=e,e)}setId(e){this._persist(e),this._cachedId=e}clear(){this._storage.remove(z),this._useCookieFallback&&this._deleteCookie(),this._cachedId=null}hasId(){return this._storage.get(z)!==null||this._getCookie()!==null}_persist(e){this._storage.set(z,e),this._useCookieFallback&&this._setCookie(e)}_generateId(){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)})}_getCookie(){if(typeof document>"u")return null;try{let e=document.cookie.split(";");for(let t of e){let[n,i]=t.trim().split("=");if(n===this._cookieName&&i)return decodeURIComponent(i)}}catch{}return null}_setCookie(e){if(!(typeof document>"u"))try{document.cookie=`${this._cookieName}=${encodeURIComponent(e)}; max-age=31536000; path=/; SameSite=Lax`}catch{}}_deleteCookie(){if(!(typeof document>"u"))try{document.cookie=`${this._cookieName}=; max-age=0; path=/`}catch{}}};var G="traffical:",Se=class{constructor(){this._available=this._checkAvailability()}get(e){if(!this._available)return null;try{let t=localStorage.getItem(G+e);if(!t)return null;let n=JSON.parse(t);return n.expiresAt&&Date.now()>n.expiresAt?(this.remove(e),null):n.value}catch{return null}}set(e,t,n){if(this._available)try{let i={value:t,...n&&{expiresAt:Date.now()+n}};localStorage.setItem(G+e,JSON.stringify(i))}catch{}}remove(e){if(this._available)try{localStorage.removeItem(G+e)}catch{}}clear(){if(this._available)try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n?.startsWith(G)&&e.push(n)}e.forEach(t=>localStorage.removeItem(t))}catch{}}_checkAvailability(){try{let e=G+"__test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return!1}}},De=class{constructor(){this._store=new Map}get(e){let t=this._store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.remove(e),null):t.value:null}set(e,t,n){this._store.set(e,{value:t,...n&&{expiresAt:Date.now()+n}})}remove(e){this._store.delete(e)}clear(){this._store.clear()}};function Xe(){let r=new Se;return r.get("__check__")!==null||Jt()?r:new De}function Jt(){try{let r="__traffical_storage_test__";return localStorage.setItem(r,"test"),localStorage.removeItem(r),!0}catch{return!1}}var D="0.16.0";var Qt="js-client";function Pe(r,e){let t=new P({ttlMs:r.deduplicationTtlMs});return{name:"decision-tracking",onDecision(n){if(r.disabled)return;let i=n.metadata.unitKeyValue;if(!i)return;let o=P.hashAssignments(n.assignments);if(!t.checkAndMark(i,o))return;let s={type:"decision",id:n.decisionId,orgId:e.orgId,projectId:e.projectId,env:e.env,unitKey:i,timestamp:n.metadata.timestamp,assignments:n.assignments,layers:n.metadata.layers,context:n.metadata.filteredContext,configVersion:n.metadata.configVersion??e.getConfigVersion?.()??void 0,sdkName:Qt,sdkVersion:D};e.log(s)},onDestroy(){t.clear()}}}var Yt="traffical_rdr";function Zt(r,e,t){if(!(typeof document>"u"))try{document.cookie=`${r}=${encodeURIComponent(e)}; max-age=${t}; path=/; SameSite=Lax`}catch{}}function Re(r={}){let e=r.parameterKey??"redirect.url",t=r.compareMode??"pathname",n=r.cookieName??Yt;return{name:"redirect",onInitialize(i){typeof window>"u"||i.decide({context:{},defaults:{[e]:""}})},onBeforeDecision(i){return typeof window>"u"?i:{"url.pathname":window.location.pathname,...i}},onDecision(i){let o=i.assignments[e];if(typeof o!="string"||!o)return;let s=t==="href"?window.location.href:window.location.pathname;if(o===s)return;let a=i.metadata.layers.find(c=>c.policyId&&c.allocationName);a&&Zt(n,JSON.stringify({l:a.layerId,p:a.policyId,a:a.allocationName,ts:Date.now()}),86400),window.location.replace(o)}}}var en="traffical_rdr";function tn(r){if(typeof document>"u")return null;try{for(let e of document.cookie.split(";")){let[t,n]=e.trim().split("=");if(t===r&&n)return decodeURIComponent(n)}}catch{}return null}function nn(r,e){let t=tn(r);if(!t)return null;try{let n=JSON.parse(t);return Date.now()-n.ts>e?null:{layerId:n.l,policyId:n.p,allocationName:n.a}}catch{return null}}function Le(r={}){let e=r.cookieName??en,t=r.expiryMs??864e5;function n(i){let o=nn(e,t);if(!o)return;i.attribution=i.attribution??[],i.attribution.some(a=>a.layerId===o.layerId&&a.policyId===o.policyId)||i.attribution.push(o)}return{name:"redirect-attribution",onTrack(i){return n(i),!0},onExposure(i){return n(i),!0}}}var fe=[],Je={};function rn(){if(typeof window>"u")return{version:1,instances:Je,subscribe:()=>()=>{}};if(!window.__TRAFFICAL_DEBUG__){let r={version:1,instances:Je,subscribe(e){return fe.push(e),()=>{fe=fe.filter(t=>t!==e)}}};window.__TRAFFICAL_DEBUG__=r}return window.__TRAFFICAL_DEBUG__}function Qe(r){for(let e of fe)try{e(r)}catch{}}var on=0;function sn(){return`traffical_${Date.now().toString(36)}_${(++on).toString(36)}`}function an(){return`evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}var cn="traffical-debug";function Me(r={}){let e=r.instanceId??sn(),t=r.maxEvents??500,n=null,i=null,o={},s=[],a=null,c=null,f=[],h=[],l=[];function _(){return{ready:n?.isInitialized===!0,stableId:n?.getStableId?.()??null,effectiveUnitKey:c,configVersion:n?.getConfigVersion?.()??null,assignments:{...o},layers:[...s],lastDecisionId:a,overrides:n?.getOverrides?.()??{}}}function u(){let d=_();for(let v of h)try{v(d)}catch{}}function g(d,v){let A={id:an(),type:d,timestamp:Date.now(),data:v};f.push(A),f.length>t&&f.splice(0,f.length-t);for(let O of l)try{O(A)}catch{}}function y(){if(n)try{n.decide({context:{},defaults:{}})}catch{}}let b={id:e,meta:{orgId:"",projectId:"",env:"",sdkVersion:D},getState:_,subscribe(d){return h.push(d),()=>{h=h.filter(v=>v!==d)}},getEvents(d){return d!==void 0?f.slice(-d):[...f]},onEvent(d){return l.push(d),()=>{l=l.filter(v=>v!==d)}},getConfigBundle(){return i},setUnitKey(d){n?.identify?n.identify(d):n?.setStableId&&n.setStableId(d),u()},setOverride(d,v){n?.applyOverrides&&n.applyOverrides({[d]:v}),u(),y()},clearOverride(d){if(n?.getOverrides&&n?.applyOverrides){let v=n.getOverrides();delete v[d],n.clearOverrides?.(),n.applyOverrides(v)}u(),y()},clearAllOverrides(){n?.clearOverrides?.(),u(),y()},getOverrides(){return n?.getOverrides?.()??{}},reDecide(){y()},async refresh(){n?.refreshConfig&&await n.refreshConfig()}};return{name:cn,onInitialize(d){n=d,i&&(b.meta.orgId=i.orgId,b.meta.projectId=i.projectId,b.meta.env=i.env);let v=rn();v.instances[e]=b,Qe({type:"register",instanceId:e}),u()},onConfigUpdate(d){i=d,b.meta.orgId=d.orgId,b.meta.projectId=d.projectId,b.meta.env=d.env,u()},onDecision(d){o={...d.assignments},s=d.metadata?.layers?[...d.metadata.layers]:[],a=d.decisionId,d.metadata?.unitKeyValue&&(c=d.metadata.unitKeyValue),g("decision",d),u()},onResolve(d){o={...d},u()},onExposure(d){return g("exposure",d),!0},onTrack(d){return g("track",d),!0},onDestroy(){let d=typeof window<"u"?window.__TRAFFICAL_DEBUG__:null;d&&(delete d.instances[e],Qe({type:"unregister",instanceId:e})),h=[],l=[],n=null}}}var ge=class{constructor(){this._plugins=[]}register(e){let t="plugin"in e?e.plugin:e,n="priority"in e?e.priority??0:0;return this._plugins.some(i=>i.plugin.name===t.name)?(console.warn(`[Traffical] Plugin "${t.name}" already registered, skipping.`),!1):(this._plugins.push({plugin:t,priority:n}),this._plugins.sort((i,o)=>o.priority-i.priority),!0)}unregister(e){let t=this._plugins.findIndex(n=>n.plugin.name===e);return t===-1?!1:(this._plugins.splice(t,1),!0)}get(e){return this._plugins.find(t=>t.plugin.name===e)?.plugin}getAll(){return this._plugins.map(e=>e.plugin)}async runInitialize(e){for(let{plugin:t}of this._plugins)if(t.onInitialize)try{await t.onInitialize(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onInitialize error:`,n)}}runConfigUpdate(e){for(let{plugin:t}of this._plugins)if(t.onConfigUpdate)try{t.onConfigUpdate(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onConfigUpdate error:`,n)}}runBeforeDecision(e){let t=e;for(let{plugin:n}of this._plugins)if(n.onBeforeDecision)try{let i=n.onBeforeDecision(t);i&&(t=i)}catch(i){console.warn(`[Traffical] Plugin "${n.name}" onBeforeDecision error:`,i)}return t}runDecision(e){for(let{plugin:t}of this._plugins)if(t.onDecision)try{t.onDecision(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onDecision error:`,n)}}runResolve(e){for(let{plugin:t}of this._plugins)if(t.onResolve)try{t.onResolve(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onResolve error:`,n)}}runExposure(e){for(let{plugin:t}of this._plugins)if(t.onExposure)try{if(t.onExposure(e)===!1)return!1}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onExposure error:`,n)}return!0}runTrack(e){for(let{plugin:t}of this._plugins)if(t.onTrack)try{if(t.onTrack(e)===!1)return!1}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onTrack error:`,n)}return!0}runDestroy(){for(let{plugin:e}of this._plugins)if(e.onDestroy)try{e.onDestroy()}catch(t){console.warn(`[Traffical] Plugin "${e.name}" onDestroy error:`,t)}}clear(){this._plugins=[]}};function Ye(){let r=[],e=!1;function t(s){for(let a of r)a(s)}let n=()=>{e=!0,t("background")},i=()=>{typeof document<"u"&&t(document.visibilityState==="hidden"?"background":"foreground")},o=()=>{e=!0,t("background")};return typeof window<"u"&&(window.addEventListener("pagehide",n),window.addEventListener("beforeunload",o)),typeof document<"u"&&document.addEventListener("visibilitychange",i),{onVisibilityChange(s){r.push(s)},removeVisibilityListener(s){let a=r.indexOf(s);a!==-1&&r.splice(a,1)},isUnloading(){return e}}}var Oe="js-client";function Ze(r,e){if(e!==void 0)return{context:r,defaults:e};let t=r;return{context:t.context,defaults:t.defaults}}var ln="https://sdk.traffical.io",un=6e4,dn=1e4,fn=3e5,gn=3e5,hn=100,pn=.1;function mn(r){let e=r*pn;return r+(Math.random()*2-1)*e}function yn(r){if(!r||typeof r!="object")return!1;let e=r;if(!Array.isArray(e.parameters)||!Array.isArray(e.layers))return!1;let t=e.hashing;return!(!t||typeof t!="object"||typeof t.unitKey!="string"||t.unitKey.length===0||typeof t.bucketCount!="number"||!Number.isInteger(t.bucketCount)||t.bucketCount<1)}var M=class{constructor(e){this._state={bundle:null,etag:null,lastFetchTime:0,lastOfflineWarning:0,lastMalformedWarning:0,refreshTimer:null,isInitialized:!1,serverResponse:null,cachedEdgeResults:null};this._decisionCache=new Map;this._cumulativeAttribution=new Map;this._identityListeners=[];this._overrideListeners=[];this._overrides={};this._lastResolveContextKey=null;this._readyPromise=new Promise(e=>{this._readyResolve=e});let t=e.evaluationMode??"bundle";this._options={orgId:e.orgId,projectId:e.projectId,env:e.env,apiKey:e.apiKey,baseUrl:e.baseUrl??ln,localConfig:e.localConfig,refreshIntervalMs:e.refreshIntervalMs??un,attributionMode:e.attributionMode??"cumulative",evaluationMode:t},this._requestTimeoutMs=e.configTimeoutMs??e.requestTimeoutMs??dn;let n={baseUrl:this._options.baseUrl,orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,apiKey:this._options.apiKey,defaultTimeoutMs:e.resolveTimeoutMs??e.requestTimeoutMs};if(this._decisionClient=new $(n),this._errorBoundary=new le(e.errorBoundary),this._storage=e.storage??Xe(),this._lifecycleProvider=e.lifecycleProvider??Ye(),!e.onSchemaWarnings)try{typeof globalThis<"u"&&globalThis.process?.env?.NODE_ENV==="development"&&(e.onSchemaWarnings=o=>{for(let s of o)console.warn(`[Traffical] Schema warning for "${s.event}":`,s.violations.map(a=>`${a.path}: ${a.message}`).join(", "))})}catch{}if(this._eventLogger=new ue({endpoint:`${this._options.baseUrl}/v1/events/batch`,apiKey:e.apiKey,storage:this._storage,lifecycleProvider:this._lifecycleProvider,batchSize:e.batchSize??e.eventBatchSize,flushIntervalMs:e.flushIntervalMs??e.eventFlushIntervalMs,maxQueueSize:e.eventMaxQueueSize,requestTimeoutMs:e.eventsTimeoutMs??e.requestTimeoutMs,onError:i=>{console.warn("[Traffical] Event logging error:",i.message)},onSchemaWarnings:e.onSchemaWarnings}),this._exposureDedup=new W({storage:this._storage,sessionTtlMs:e.exposureSessionTtlMs}),this._stableId=new de({storage:this._storage}),this._plugins=new ge,this._assignmentLogger=e.assignmentLogger,this._byoEventLogger=e.eventLogger,this._disableCloudEvents=e.disableCloudEvents??!1,this._assignmentLoggerDedup=e.deduplicateAssignmentLogger!==!1&&e.assignmentLogger?new W({storage:this._storage,sessionTtlMs:e.exposureSessionTtlMs}):null,e.trackDecisions!==!1&&(!this._disableCloudEvents||this._byoEventLogger)&&this._plugins.register({plugin:Pe({deduplicationTtlMs:e.decisionDeduplicationTtlMs},{orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,log:i=>this._dispatchEvent(i),getConfigVersion:()=>this.getConfigVersion()}),priority:100}),e.plugins)for(let i of e.plugins)this._plugins.register(i);if(this._options.localConfig&&(this._state.bundle=this._options.localConfig,this._plugins.runConfigUpdate(this._options.localConfig)),typeof window<"u"){let i=window;i.__TRAFFICAL_INSTANCES__??(i.__TRAFFICAL_INSTANCES__=[]),i.__TRAFFICAL_INSTANCES__.push(this)}}async initialize(){await this._errorBoundary.captureAsync("initialize",async()=>{this._options.evaluationMode==="server"?await this._fetchServerResolve():await this._fetchConfig(),this._startBackgroundRefresh(),this._state.isInitialized=!0,await this._plugins.runInitialize(this)},void 0),this._readyResolve()}get isInitialized(){return this._state.isInitialized}async waitForReady(){return this._readyPromise}async close(){if(this._state.refreshTimer&&(clearInterval(this._state.refreshTimer),this._state.refreshTimer=null),this._lifecycleProvider.isUnloading()?this._eventLogger.flushBeacon():await this._eventLogger.flush().catch(()=>{}),this._eventLogger.destroy(),this._plugins.runDestroy(),this._identityListeners=[],this._overrideListeners=[],this._overrides={},typeof window<"u"){let t=window.__TRAFFICAL_INSTANCES__;if(t){let n=t.indexOf(this);n!==-1&&t.splice(n,1)}}}destroy(){if(this._state.refreshTimer&&(clearInterval(this._state.refreshTimer),this._state.refreshTimer=null),this._lifecycleProvider.isUnloading()?this._eventLogger.flushBeacon():this._eventLogger.flush().catch(()=>{}),this._eventLogger.destroy(),this._plugins.runDestroy(),this._identityListeners=[],this._overrideListeners=[],this._overrides={},typeof window<"u"){let t=window.__TRAFFICAL_INSTANCES__;if(t){let n=t.indexOf(this);n!==-1&&t.splice(n,1)}}}async refreshConfig(){await this._errorBoundary.swallow("refreshConfig",async()=>{this._options.evaluationMode==="server"?await this._fetchServerResolve():await this._fetchConfig()})}getConfigVersion(){return this._state.serverResponse?.stateVersion??this._state.bundle?.version??null}getUnitKeyField(){return oe(this._getEffectiveBundle())}getParameterLayerId(e){return se(this._getEffectiveBundle(),e)}getParams(e,t){let{context:n,defaults:i}=Ze(e,t);return this._errorBoundary.capture("getParams",()=>{if(this._options.evaluationMode==="server"&&this._state.serverResponse){this._maybeResolveForContext(n);let c={...i};for(let[f,h]of Object.entries(this._state.serverResponse.assignments))f in c&&(c[f]=h);return this._plugins.runResolve(c),this._applyOverridesToResult(c),c}let o=this._getEffectiveBundle(),s=this._enrichContext(n),a=ae(o,s,i);return this._plugins.runResolve(a),this._applyOverridesToResult(a),a},i)}decide(e,t){let{context:n,defaults:i}=Ze(e,t);return this._errorBoundary.capture("decide",()=>{if(this._options.evaluationMode==="server"&&this._state.serverResponse){this._maybeResolveForContext(n);let f=this._state.serverResponse,h={...i};for(let[_,u]of Object.entries(f.assignments))_ in h&&(h[_]=u);let l={decisionId:L(),assignments:h,metadata:{...f.metadata,configVersion:f.stateVersion}};return this._cacheDecision(l),this._updateCumulativeAttribution(l),this._plugins.runDecision(l),this._applyOverridesToResult(l.assignments),this._emitAssignmentLogEntries(l,"decision"),l}let o=this._getEffectiveBundle(),s=this._enrichContext(n);s=this._plugins.runBeforeDecision(s);let a=this._state.cachedEdgeResults??void 0,c=ce(o,s,i,a);return this._cacheDecision(c),this._updateCumulativeAttribution(c),this._plugins.runDecision(c),this._applyOverridesToResult(c.assignments),this._emitAssignmentLogEntries(c,"decision"),c},{decisionId:L(),assignments:i,metadata:{timestamp:new Date().toISOString(),unitKeyValue:"",layers:[]}})}trackExposure(e){this._errorBoundary.capture("trackExposure",()=>{let t=e.metadata.unitKeyValue;if(!t)return;this._emitAssignmentLogEntries(e,"exposure");let n=e.metadata.configVersion??this.getConfigVersion()??void 0,i=[];for(let s of e.metadata.layers)!s.policyId||!s.allocationName||s.attributionOnly||!this._exposureDedup.checkAndMark(t,s.policyId,s.allocationName)||i.push(s);if(i.length===0)return;let o={type:"exposure",id:we(),decisionId:e.decisionId,orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,unitKey:t,timestamp:new Date().toISOString(),assignments:e.assignments,layers:i,context:e.metadata.filteredContext,configVersion:n,sdkName:Oe,sdkVersion:D};this._plugins.runExposure(o)&&this._dispatchEvent(o)},void 0)}track(e,t,n){this._errorBoundary.capture("track",()=>{let i=n?.unitKey??this._stableId.getId(),o=typeof n?.value=="number"?n.value:typeof t?.value=="number"?t.value:void 0,s=this._buildAttribution(i,n?.decisionId),a=n?.decisionId,c={type:"track",id:Ae(),orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,unitKey:i,timestamp:new Date().toISOString(),event:e,value:o,values:n?.values,properties:t,decisionId:a,attribution:s,eventTimestamp:n?.eventTimestamp,sdkName:Oe,sdkVersion:D};this._plugins.runTrack(c)&&this._dispatchEvent(c)},void 0)}async flushEvents(){await this._errorBoundary.swallow("flushEvents",async()=>{await this._eventLogger.flush()})}use(e){if(!this._plugins.register(e))return this;if(this._state.isInitialized){try{e.onInitialize?.(this)}catch(n){console.warn(`[Traffical] Plugin "${e.name}" late onInitialize error:`,n)}if(this._state.bundle)try{e.onConfigUpdate?.(this._state.bundle)}catch(n){console.warn(`[Traffical] Plugin "${e.name}" late onConfigUpdate error:`,n)}}return this}getPlugin(e){return this._plugins.get(e)}getStableId(){return this._stableId.getId()}setStableId(e){this._stableId.setId(e)}identify(e){this._stableId.setId(e);for(let t of this._identityListeners)try{t(e)}catch{}}onIdentityChange(e){return this._identityListeners.push(e),()=>{this._identityListeners=this._identityListeners.filter(t=>t!==e)}}onOverridesChange(e){return this._overrideListeners.push(e),()=>{this._overrideListeners=this._overrideListeners.filter(t=>t!==e)}}applyOverrides(e){Object.assign(this._overrides,e),this._notifyOverrideListeners()}clearOverrides(){this._overrides={},this._notifyOverrideListeners()}getOverrides(){return{...this._overrides}}_notifyOverrideListeners(){let e={...this._overrides};for(let t of this._overrideListeners)try{t(e)}catch{}}_dispatchEvent(e){if(this._byoEventLogger)try{this._byoEventLogger(e)}catch{}this._disableCloudEvents||this._eventLogger.log(e)}_emitAssignmentLogEntries(e,t){if(!this._assignmentLogger)return;let n=e.metadata.unitKeyValue;if(!n)return;let i=e.metadata.configVersion??this.getConfigVersion()??void 0;for(let o of e.metadata.layers)!o.policyId||!o.allocationName||this._assignmentLoggerDedup&&!this._assignmentLoggerDedup.checkAndMark(n,o.policyId,`${o.allocationName}:${t}`)||this._assignmentLogger({unitKey:n,policyId:o.policyId,policyKey:o.policyKey,allocationName:o.allocationName,allocationKey:o.allocationKey,timestamp:e.metadata.timestamp,layerId:o.layerId,allocationId:o.allocationId,orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,sdkName:Oe,sdkVersion:D,properties:e.metadata.filteredContext,type:t,decisionId:e.decisionId,anonymousId:this._stableId.getId(),id:Ce(),bucket:o.bucket>=0?o.bucket:void 0,probability:o.probability,modelVersion:o.modelVersion,configVersion:i})}_applyOverridesToResult(e){let t=Object.keys(this._overrides);if(t.length!==0)for(let n of t)n in e&&(e[n]=this._overrides[n])}_getEffectiveBundle(){return this._state.bundle??this._options.localConfig??null}_enrichContext(e){let n=this._getEffectiveBundle()?.hashing?.unitKey??"userId";return e[n]?e:{...e,[n]:this._stableId.getId()}}async _fetchConfig(){let e=`${this._options.baseUrl}/v1/config/${encodeURIComponent(this._options.projectId)}?env=${encodeURIComponent(this._options.env)}`,t={"Content-Type":"application/json",Authorization:`Bearer ${this._options.apiKey}`};this._state.etag&&(t["If-None-Match"]=this._state.etag);let n=new AbortController,i=setTimeout(()=>n.abort(),this._requestTimeoutMs);try{let o=await fetch(e,{method:"GET",headers:t,signal:n.signal});if(o.status===304){this._state.lastFetchTime=Date.now();return}if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);let s=await o.json(),a=o.headers.get("ETag");if(!yn(s)){this._logMalformedBundleWarning();return}if(this._state.bundle=s,this._state.etag=a,this._state.lastFetchTime=Date.now(),this._findEdgePolicies(s).length>0){let c=await this._prefetchEdgeResults(s,this._enrichContext({}));this._state.cachedEdgeResults=c}else this._state.cachedEdgeResults=null;this._plugins.runConfigUpdate(s)}catch(o){this._logOfflineWarning(o)}finally{clearTimeout(i)}}_startBackgroundRefresh(){let e=this._options.evaluationMode==="server"?this._state.serverResponse?.suggestedRefreshMs??this._options.refreshIntervalMs:this._options.refreshIntervalMs;if(e<=0)return;let t=()=>{this._state.refreshTimer=setTimeout(()=>{t(),this._options.evaluationMode==="server"?this._fetchServerResolve().catch(()=>{}):this._fetchConfig().catch(()=>{})},mn(e))};t()}_maybeResolveForContext(e){let t=this._enrichContext(e),n;try{n=JSON.stringify(t)}catch{n=""}n!==this._lastResolveContextKey&&(this._lastResolveContextKey=n,this._fetchServerResolve(t))}async _fetchServerResolve(e){if(this._decisionClient)try{let t=e??this._enrichContext({}),n=await this._decisionClient.resolve({context:t});n&&(this._state.serverResponse=n,this._state.lastFetchTime=Date.now())}catch(t){this._logOfflineWarning(t)}}_findEdgePolicies(e){let t=[];for(let n of e.layers)for(let i of n.policies)i.state==="running"&&i.entityConfig?.resolutionMode==="edge"&&t.push(i);return t}async _prefetchEdgeResults(e,t){if(!this._decisionClient)return{};let n=this._findEdgePolicies(e);if(n.length===0)return{};let i=K(e,t);if(!i)return{};let o=n.map(s=>{if(!s.entityConfig)return null;let a=s.entityConfig.dynamicAllocations?typeof t[s.entityConfig.dynamicAllocations.countKey]=="number"?Math.floor(t[s.entityConfig.dynamicAllocations.countKey]):0:s.allocations.length;return ke(s.id,s.entityConfig.entityKeys,t,i,a||void 0)}).filter(s=>s!==null);if(o.length===0)return{};try{let s=await this._decisionClient.decideEntityBatch(o),a=new Map;for(let c=0;c<o.length;c++){let f=s[c];f&&a.set(o[c].policyId,{allocationIndex:f.allocationIndex,entityId:o[c].entityId})}return a.size>0?{edgeResults:a}:{}}catch{return{}}}_logOfflineWarning(e){let t=Date.now();t-this._state.lastOfflineWarning>fn&&(console.warn(`[Traffical] Failed to fetch config: ${e instanceof Error?e.message:String(e)}. Using ${this._state.bundle?"cached":"local"} config.`),this._state.lastOfflineWarning=t)}_logMalformedBundleWarning(){let e=Date.now();e-this._state.lastMalformedWarning>gn&&(console.warn(`[Traffical] Discarded malformed config bundle (invalid hashing/shape). Using ${this._state.bundle?"cached":"local"} config.`),this._state.lastMalformedWarning=e)}_cacheDecision(e){if(this._decisionCache.size>=hn){let t=this._decisionCache.keys().next().value;t&&this._decisionCache.delete(t)}this._decisionCache.set(e.decisionId,e)}_updateCumulativeAttribution(e){let t=e.metadata.unitKeyValue;if(!t)return;let n=this._cumulativeAttribution.get(t);n||(n=new Map,this._cumulativeAttribution.set(t,n));for(let i of e.metadata.layers){if(!i.policyId||!i.allocationName)continue;let o=`${i.layerId}:${i.policyId}`;n.set(o,{layerId:i.layerId,policyId:i.policyId,allocationName:i.allocationName})}}_buildAttribution(e,t){if(this._options.attributionMode==="decision"){if(!t)return;let i=this._decisionCache.get(t);return i?i.metadata.layers.filter(o=>o.policyId&&o.allocationName).map(o=>({layerId:o.layerId,policyId:o.policyId,allocationName:o.allocationName})):void 0}let n=this._cumulativeAttribution.get(e);return n&&n.size>0?Array.from(n.values()):void 0}};async function et(r){let e=new M(r);return await e.initialize(),e}function tt(r){return new M(r)}function nt(r={}){let e={observeMutations:r.observeMutations??!0,debounceMs:r.debounceMs??100},t=[],n={},i=null,o=null;function s(u,g){try{return new RegExp(u).test(g)}catch{return g===u}}function a(u,g,y){if(g==="innerHTML")u.innerHTML=y;else if(g==="textContent")u.textContent=y;else if(g==="src"&&"src"in u)u.src=y;else if(g==="href"&&"href"in u)u.href=y;else if(g.startsWith("style.")){let b=g.slice(6);u.style[b]=y}else u.setAttribute(g,y)}function c(u,g){let y=String(g);try{let b=document.querySelectorAll(u.selector);for(let w of b)a(w,u.property,y)}catch(b){console.warn(`[Traffical DOM Binding] Failed to apply binding for ${u.parameterKey}:`,b)}}function f(u,g=!1){n=u;let y=typeof window<"u"?window.location.pathname:"";for(let b of t){if(!g&&!s(b.urlPattern,y))continue;let w=u[b.parameterKey];w!==void 0&&c(b,w)}}function h(){o&&clearTimeout(o),o=setTimeout(()=>{f(n)},e.debounceMs)}function l(){i||typeof MutationObserver>"u"||typeof document>"u"||(i=new MutationObserver(()=>{h()}),i.observe(document.body,{childList:!0,subtree:!0}))}function _(){i&&(i.disconnect(),i=null),o&&(clearTimeout(o),o=null)}return{name:"dom-binding",onInitialize(){e.observeMutations&&l()},onConfigUpdate(u){t=u.domBindings??[]},onResolve(u){f(u)},onDecision(u){f(u.assignments)},onDestroy(){_(),t=[],n={}},applyBindings(u){f(u||n)},getBindings(){return t}}}var T=null;async function vn(r){return T?(console.warn("[Traffical] Client already initialized. Returning existing instance."),T):(T=await et(r),T)}function _n(r){return T?(console.warn("[Traffical] Client already initialized. Returning existing instance."),T):(T=tt(r),T.initialize().catch(e=>{console.warn("[Traffical] Initialization error:",e)}),T)}function bn(){return T}function xn(){T&&(T.destroy(),T=null)}return ut(En);})();
1
+ /* @traffical/js-client v0.16.1 */
2
+ "use strict";var Traffical=(()=>{var q=Object.defineProperty;var it=Object.getOwnPropertyDescriptor;var rt=Object.getOwnPropertyNames;var ot=Object.prototype.hasOwnProperty;var st=(r,e,t)=>e in r?q(r,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):r[e]=t;var at=(r,e)=>()=>(e||r((e={exports:{}}).exports,e),e.exports),ct=(r,e)=>{for(var t in e)q(r,t,{get:e[t],enumerable:!0})},lt=(r,e,t,n)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of rt(e))!ot.call(r,i)&&i!==t&&q(r,i,{get:()=>e[i],enumerable:!(n=it(e,i))||n.enumerable});return r};var ut=r=>lt(q({},"__esModule",{value:!0}),r);var m=(r,e,t)=>(st(r,typeof e!="symbol"?e+"":e,t),t);var He=at(()=>{});var En={};ct(En,{TrafficalClient:()=>M,createDOMBindingPlugin:()=>nt,createDebugPlugin:()=>Me,createRedirectAttributionPlugin:()=>Le,createRedirectPlugin:()=>Re,destroy:()=>xn,init:()=>vn,initSync:()=>_n,instance:()=>bn});function dt(r){return r instanceof Uint8Array||ArrayBuffer.isView(r)&&r.constructor.name==="Uint8Array"&&"BYTES_PER_ELEMENT"in r&&r.BYTES_PER_ELEMENT===1}function he(r,e,t=""){let n=dt(r),i=r?.length,o=e!==void 0;if(!n||o&&i!==e){let s=t&&`"${t}" `,a=o?` of length ${e}`:"",c=n?`length=${i}`:`type=${typeof r}`,f=s+"expected Uint8Array"+a+", got "+c;throw n?new RangeError(f):new TypeError(f)}return r}function pe(r,e=!0){if(r.destroyed)throw new Error("Hash instance has been destroyed");if(e&&r.finished)throw new Error("Hash#digest() has already been called")}function Be(r,e){he(r,void 0,"digestInto() output");let t=e.outputLen;if(r.length<t)throw new RangeError('"digestInto() output" expected to be of length >='+t)}function B(...r){for(let e=0;e<r.length;e++)r[e].fill(0)}function X(r){return new DataView(r.buffer,r.byteOffset,r.byteLength)}function I(r,e){return r<<32-e|r>>>e}function Ne(r,e={}){let t=(i,o)=>r(o).update(i).digest(),n=r(void 0);return t.outputLen=n.outputLen,t.blockLen=n.blockLen,t.canXOF=n.canXOF,t.create=i=>r(i),Object.assign(t,e),Object.freeze(t)}var Ve=r=>({oid:Uint8Array.from([6,9,96,134,72,1,101,3,4,2,r])});function Ue(r,e,t){return r&e^~r&t}function Fe(r,e,t){return r&e^r&t^e&t}var J=class{constructor(e,t,n,i){m(this,"blockLen");m(this,"outputLen");m(this,"canXOF",!1);m(this,"padOffset");m(this,"isLE");m(this,"buffer");m(this,"view");m(this,"finished",!1);m(this,"length",0);m(this,"pos",0);m(this,"destroyed",!1);this.blockLen=e,this.outputLen=t,this.padOffset=n,this.isLE=i,this.buffer=new Uint8Array(e),this.view=X(this.buffer)}update(e){pe(this),he(e);let{view:t,buffer:n,blockLen:i}=this,o=e.length;for(let s=0;s<o;){let a=Math.min(i-this.pos,o-s);if(a===i){let c=X(e);for(;i<=o-s;s+=i)this.process(c,s);continue}n.set(e.subarray(s,s+a),this.pos),this.pos+=a,s+=a,this.pos===i&&(this.process(t,0),this.pos=0)}return this.length+=e.length,this.roundClean(),this}digestInto(e){pe(this),Be(e,this),this.finished=!0;let{buffer:t,view:n,blockLen:i,isLE:o}=this,{pos:s}=this;t[s++]=128,B(this.buffer.subarray(s)),this.padOffset>i-s&&(this.process(n,0),s=0);for(let l=s;l<i;l++)t[l]=0;n.setBigUint64(i-8,BigInt(this.length*8),o),this.process(n,0);let a=X(e),c=this.outputLen;if(c%4)throw new Error("_sha2: outputLen must be aligned to 32bit");let f=c/4,h=this.get();if(f>h.length)throw new Error("_sha2: outputLen bigger than state");for(let l=0;l<f;l++)a.setUint32(4*l,h[l],o)}digest(){let{buffer:e,outputLen:t}=this;this.digestInto(e);let n=e.slice(0,t);return this.destroy(),n}_cloneInto(e){e||(e=new this.constructor),e.set(...this.get());let{blockLen:t,buffer:n,length:i,finished:o,destroyed:s,pos:a}=this;return e.destroyed=s,e.finished=o,e.length=i,e.pos=a,i%t&&e.buffer.set(n),e}clone(){return this._cloneInto()}},k=Uint32Array.from([1779033703,3144134277,1013904242,2773480762,1359893119,2600822924,528734635,1541459225]);var ft=Uint32Array.from([1116352408,1899447441,3049323471,3921009573,961987163,1508970993,2453635748,2870763221,3624381080,310598401,607225278,1426881987,1925078388,2162078206,2614888103,3248222580,3835390401,4022224774,264347078,604807628,770255983,1249150122,1555081692,1996064986,2554220882,2821834349,2952996808,3210313671,3336571891,3584528711,113926993,338241895,666307205,773529912,1294757372,1396182291,1695183700,1986661051,2177026350,2456956037,2730485921,2820302411,3259730800,3345764771,3516065817,3600352804,4094571909,275423344,430227734,506948616,659060556,883997877,958139571,1322822218,1537002063,1747873779,1955562222,2024104815,2227730452,2361852424,2428436474,2756734187,3204031479,3329325298]),S=new Uint32Array(64),me=class extends J{constructor(e){super(64,e,8,!1)}get(){let{A:e,B:t,C:n,D:i,E:o,F:s,G:a,H:c}=this;return[e,t,n,i,o,s,a,c]}set(e,t,n,i,o,s,a,c){this.A=e|0,this.B=t|0,this.C=n|0,this.D=i|0,this.E=o|0,this.F=s|0,this.G=a|0,this.H=c|0}process(e,t){for(let l=0;l<16;l++,t+=4)S[l]=e.getUint32(t,!1);for(let l=16;l<64;l++){let _=S[l-15],u=S[l-2],g=I(_,7)^I(_,18)^_>>>3,y=I(u,17)^I(u,19)^u>>>10;S[l]=y+S[l-7]+g+S[l-16]|0}let{A:n,B:i,C:o,D:s,E:a,F:c,G:f,H:h}=this;for(let l=0;l<64;l++){let _=I(a,6)^I(a,11)^I(a,25),u=h+_+Ue(a,c,f)+ft[l]+S[l]|0,y=(I(n,2)^I(n,13)^I(n,22))+Fe(n,i,o)|0;h=f,f=c,c=a,a=s+u|0,s=o,o=i,i=n,n=u+y|0}n=n+this.A|0,i=i+this.B|0,o=o+this.C|0,s=s+this.D|0,a=a+this.E|0,c=c+this.F|0,f=f+this.G|0,h=h+this.H|0,this.set(n,i,o,s,a,c,f,h)}roundClean(){B(S)}destroy(){this.destroyed=!0,this.set(0,0,0,0,0,0,0,0),B(this.buffer)}},ye=class extends me{constructor(){super(32);m(this,"A",k[0]|0);m(this,"B",k[1]|0);m(this,"C",k[2]|0);m(this,"D",k[3]|0);m(this,"E",k[4]|0);m(this,"F",k[5]|0);m(this,"G",k[6]|0);m(this,"H",k[7]|0)}};var Ke=Ne(()=>new ye,Ve(1));var $e=new TextEncoder,ve="v2";function Q(r){return $e.encode(r).length}function Y(r,e){let t=Q(r),n=Q(e);return`traffical:assignment:${ve}|u:${t}:${r}|l:${n}:${e}`}function N(r){return Ke($e.encode(r))}function V(r){let e=0n;for(let t=0;t<8;t++)e=e<<8n|BigInt(r[t]);return e}function Z(r){return V(N(r))}function ee(r,e,t){let n=N(Y(r,e)),i=V(n);return Number(i%BigInt(t))}function _e(r,e){return r>=e[0]&&r<=e[1]}function te(r,e){for(let t of e)if(_e(r,t.bucketRange))return t;return null}var gt=1n<<53n,ht=9007199254740992;function R(r,e){if(r.length===0||r.length===1)return 0;let t=Z(e),n=Number(t%gt)/ht,i=0;for(let o=0;o<r.length;o++)if(i+=r[o],n<i)return o;return r.length-1}function be(r,e){let{field:t,op:n,value:i,values:o}=r,s=yt(e,t);switch(n){case"eq":return s===i;case"neq":return s!==i;case"in":return Array.isArray(o)?o.includes(s):!1;case"nin":return Array.isArray(o)?!o.includes(s):!0;case"gt":return typeof s=="number"&&s>i;case"gte":return typeof s=="number"&&s>=i;case"lt":return typeof s=="number"&&s<i;case"lte":return typeof s=="number"&&s<=i;case"contains":return typeof s=="string"&&typeof i=="string"&&s.includes(i);case"startsWith":return typeof s=="string"&&typeof i=="string"&&s.startsWith(i);case"endsWith":return typeof s=="string"&&typeof i=="string"&&s.endsWith(i);case"regex":if(typeof s!="string"||typeof i!="string")return!1;try{return new RegExp(i).test(s)}catch{return!1}case"exists":return s!=null;case"notExists":return s==null;default:return!1}}function ne(r,e){return r.length===0?!0:r.every(t=>be(t,e))}function yt(r,e){let t=e.split("."),n=r;for(let i of t){if(n==null)return;if(typeof n=="object")n=n[i];else return}return n}function xe(r,e){let t=r.intercept;for(let{key:n,coef:i,missing:o}of r.numeric){let s=e[n];t+=typeof s=="number"?i*s:o}for(let{key:n,values:i,missing:o}of r.categorical){let s=e[n],a=s!=null?String(s):null;t+=a!==null&&a in i?i[a]:o}return t}function Ee(r,e){if(r.length===0)return[];if(r.length===1)return[1];let t=Math.max(e,1e-10),n=r.map(a=>a/t),i=Math.max(...n),o=n.map(a=>Math.exp(a-i)),s=o.reduce((a,c)=>a+c,0);return o.map(a=>a/s)}function Te(r,e){if(r.length===0)return[];if(e<=0)return r;let t=r.length,n=1/t,i=Math.min(e,n),o=r.map(a=>Math.max(a,i)),s=o.reduce((a,c)=>a+c,0);return s===0?Array(t).fill(1/t):o.map(a=>a/s)}function ie(r,e,t){let n=r.contextualModel;if(!n||r.allocations.length===0)return null;let i=vt(n,r.allocations,e),o=Ee(i,n.gamma),s=Te(o,n.actionProbabilityFloor),a=`ctx:${t}:${r.id}`,c=R(s,a);return{allocation:r.allocations[c],probability:s[c]}}function vt(r,e,t){return e.map(n=>{let i=r.coefficients[n.key??n.name];return i?xe(i,t):r.defaultAllocationScore})}var _t=r=>crypto.getRandomValues(new Uint8Array(r)),bt=(r,e,t)=>{let n=(2<<Math.log2(r.length-1))-1,i=-~(1.6*n*e/r.length);return(o=e)=>{let s="";for(;;){let a=t(i),c=i|0;for(;c--;)if(s+=r[a[c]&n]||"",s.length>=o)return s}}},je=(r,e=21)=>bt(r,e|0,_t);function re(r){let e=new Error(r);return e.source="ulid",e}var Ie="0123456789ABCDEFGHJKMNPQRSTVWXYZ",U=Ie.length,We=Math.pow(2,48)-1,xt=10,Et=16;function Tt(r){let e=Math.floor(r()*U);return e===U&&(e=U-1),Ie.charAt(e)}function It(r,e){if(isNaN(r))throw new Error(r+" must be a number");if(r>We)throw re("cannot encode time greater than "+We);if(r<0)throw re("time must be positive");if(Number.isInteger(Number(r))===!1)throw re("time must be an integer");let t,n="";for(;e>0;e--)t=r%U,n=Ie.charAt(t)+n,r=(r-t)/U;return n}function wt(r,e){let t="";for(;r>0;r--)t=Tt(e)+t;return t}function At(r=!1,e){e||(e=typeof window<"u"?window:null);let t=e&&(e.crypto||e.msCrypto);if(t)return()=>{let n=new Uint8Array(1);return t.getRandomValues(n),n[0]/255};try{let n=He();return()=>n.randomBytes(1).readUInt8()/255}catch{}if(r){try{console.error("secure crypto unusable, falling back to insecure Math.random()!")}catch{}return()=>Math.random()}throw re("secure crypto unusable, insecure Math.random not allowed")}function Ct(r){return r||(r=At()),function(t){return isNaN(t)&&(t=Date.now()),It(t,xt)+wt(Et,r)}}var ze=Ct();var kt="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz",St=8,ei=je(kt,St);function F(r){return`${r}_${ze()}`}function L(){return F("dec")}function we(){return F("exp")}function Ae(){return F("trk")}function Ce(){return F("asn")}function Dt(r,e){let t=new Set;for(let i of e)if(i.contextLogging?.allowedFields)for(let o of i.contextLogging.allowedFields)t.add(o);if(t.size===0)return;let n={};for(let i of t)i in r&&(n[i]=r[i]);return Object.keys(n).length>0?n:void 0}function Pt(r,e){let t=[];for(let n of r){let i=e[n];if(i==null)return null;t.push(String(i))}return t.join("_")}function Ge(r){if(r<=0)return[];let e=1/r;return Array(r).fill(e)}function Rt(r,e,t,n){let i=r.entityState?.[e];if(!i)return Ge(n);let o=i.entities[t];if(o&&o.weights.length===n)return o.weights;let s=i._global;return s&&s.weights.length===n?s.weights:Ge(n)}function Lt(r,e,t,n){let i=e.entityConfig;if(!i)return null;let o=Pt(i.entityKeys,t);if(!o)return null;let s,a;if(i.dynamicAllocations){let l=i.dynamicAllocations.countKey,_=t[l];if(typeof _!="number"||_<=0)return null;a=Math.floor(_),s=Array.from({length:a},(u,g)=>({id:`${e.id}_dynamic_${g}`,name:String(g),bucketRange:[0,0],overrides:{}}))}else s=e.allocations,a=s.length;if(a===0)return null;let c=Rt(r,e.id,o,a),f=`${o}:${n}:${e.id}`,h=R(c,f);return{allocation:s[h],weight:c[h],entityId:o}}function K(r,e){let t=e[r.hashing.unitKey];return t==null?null:String(t)}function oe(r){return r?.hashing?.unitKey??null}function se(r,e){return r?r.parameters.find(n=>n.key===e)?.layerId??null:null}function qe(r,e,t,n){let i={...t},o=[],s=[];if(!r)return{assignments:i,unitKeyValue:"",layers:o,matchedPolicies:s};let a=K(r,e)??"",c=new Set(Object.keys(t)),f=r.parameters.filter(l=>c.has(l.key));for(let l of f)l.key in i&&(i[l.key]=l.default);let h=new Map;for(let l of f){let _=h.get(l.layerId)||[];_.push(l),h.set(l.layerId,_)}for(let l of r.layers){let _=h.get(l.id),u=_&&_.length>0,g=l.unitKey,y=g!=null;if(y&&String(g).trim()===""){o.push({layerId:l.id,bucket:-1,...u?{}:{attributionOnly:!0}});continue}let b=y?String(e[g]??""):a;if(!b){o.push({layerId:l.id,bucket:-1,...y?{unitKey:g,unitKeyValue:""}:{},...u?{}:{attributionOnly:!0}});continue}let w=ee(b,l.id,r.hashing.bucketCount),d,v,A,O;for(let p of l.policies)if(p.state==="running"){if(p.eligibleBucketRange){let{start:x,end:E}=p.eligibleBucketRange;if(w<x||w>E)continue}if(ne(p.conditions,e)){if(p.contextualModel){let x=ie(p,e,b);if(x){if(d=p,v=x.allocation,A=x.probability,O=p.contextualModel.generatedAt??p.contextualModel.modelVersion,s.push(p),u)for(let[E,C]of Object.entries(x.allocation.overrides))E in i&&(i[E]=C);break}}if(p.entityConfig&&p.entityConfig.resolutionMode==="bundle"){let x=Lt(r,p,e,b);if(x){if(d=p,v=x.allocation,A=x.weight,s.push(p),u&&!p.entityConfig.dynamicAllocations)for(let[E,C]of Object.entries(x.allocation.overrides))E in i&&(i[E]=C);break}}else if(p.entityConfig&&p.entityConfig.resolutionMode==="edge"){let x=n?.edgeResults?.get(p.id);if(x){if(d=p,s.push(p),p.entityConfig.dynamicAllocations)v={id:`${p.id}_dynamic_${x.allocationIndex}`,name:String(x.allocationIndex),bucketRange:[0,0],overrides:{}};else if(p.allocations[x.allocationIndex]&&(v=p.allocations[x.allocationIndex],u&&v))for(let[E,C]of Object.entries(v.overrides))E in i&&(i[E]=C);break}continue}else{let x=te(w,p.allocations);if(x){if(d=p,v=x,p.kind==="adaptive"){let[E,C]=x.bucketRange;A=(C-E+1)/r.hashing.bucketCount}if(s.push(p),u)for(let[E,C]of Object.entries(x.overrides))E in i&&(i[E]=C);break}}}}o.push({layerId:l.id,bucket:w,policyId:d?.id,policyKey:d?.key,allocationId:v?.id,allocationName:v?.name,allocationKey:v?.key,...A!==void 0&&A>0&&A<=1?{probability:A}:{},...O!==void 0?{modelVersion:O}:{},...y?{unitKey:g,unitKeyValue:b}:{},...u?{}:{attributionOnly:!0}})}return{assignments:i,unitKeyValue:a,layers:o,matchedPolicies:s}}function ae(r,e,t,n){return qe(r,e,t,n).assignments}function ce(r,e,t,n){let{assignments:i,unitKeyValue:o,layers:s,matchedPolicies:a}=qe(r,e,t,n),c=Dt(e,a);return{decisionId:L(),assignments:i,metadata:{timestamp:new Date().toISOString(),unitKeyValue:o,layers:s,filteredContext:c,...r?.version?{configVersion:r.version}:{}}}}var P=class r{constructor(e={}){m(this,"_seen",new Map);m(this,"_ttlMs");m(this,"_maxEntries");m(this,"_lastCleanup",Date.now());this._ttlMs=e.ttlMs??36e5,this._maxEntries=e.maxEntries??1e4}static hashAssignments(e){let t=Object.keys(e).sort(),n=[];for(let i of t){let o=e[i],s=typeof o=="object"?JSON.stringify(o):String(o);n.push(`${i}=${s}`)}return n.join("|")}static createKey(e,t){return`${e}:${t}`}checkAndMark(e,t){let n=r.createKey(e,t),i=Date.now(),o=this._seen.get(n);return o!==void 0&&i-o<this._ttlMs?!1:(this._seen.set(n,i),this._maybeCleanup(i),!0)}wouldBeNew(e,t){let n=r.createKey(e,t),i=Date.now(),o=this._seen.get(n);return o===void 0?!0:i-o>=this._ttlMs}clear(){this._seen.clear()}get size(){return this._seen.size}_maybeCleanup(e){(e-this._lastCleanup>this._ttlMs*.2||this._seen.size>this._maxEntries)&&(this._lastCleanup=e,this._cleanup(e))}_cleanup(e){let t=[];for(let[n,i]of this._seen.entries())e-i>=this._ttlMs&&t.push(n);for(let n of t)this._seen.delete(n);if(this._seen.size>this._maxEntries){let i=Array.from(this._seen.entries()).sort((o,s)=>o[1]-s[1]).slice(0,this._seen.size-this._maxEntries);for(let[o]of i)this._seen.delete(o)}}};var $=class{constructor(e){m(this,"config");m(this,"defaultTimeout");this.config=e,this.defaultTimeout=e.defaultTimeoutMs??5e3}async resolve(e){try{let t=new AbortController,n=setTimeout(()=>t.abort(),this.defaultTimeout),i=`${this.config.baseUrl}/v1/resolve`,o=await fetch(i,{method:"POST",headers:this._headers(),body:JSON.stringify({context:e.context,env:e.env??this.config.env,parameters:e.parameters}),signal:t.signal});return clearTimeout(n),o.ok?await o.json():(console.warn(`[Traffical] Resolve failed: ${o.status} ${o.statusText}`),null)}catch(t){return t instanceof Error&&t.name==="AbortError"?console.warn(`[Traffical] Resolve timed out after ${this.defaultTimeout}ms`):console.warn("[Traffical] Resolve error:",t),null}}async decideEntity(e,t){let n=t??Math.min(this.defaultTimeout,100);try{let i=new AbortController,o=setTimeout(()=>i.abort(),n),s=`${this.config.baseUrl}/v1/decide/${e.policyId}`,a=await fetch(s,{method:"POST",headers:this._headers(),body:JSON.stringify({entityId:e.entityId,unitKeyValue:e.unitKeyValue,allocationCount:e.allocationCount,context:e.context}),signal:i.signal});return clearTimeout(o),a.ok?await a.json():(console.warn(`[Traffical] Edge decide failed: ${a.status} ${a.statusText}`),null)}catch(i){return i instanceof Error&&i.name==="AbortError"?console.warn(`[Traffical] Edge decide timed out after ${n}ms`):console.warn("[Traffical] Edge decide error:",i),null}}async decideEntityBatch(e,t){if(e.length===0)return[];if(e.length===1)return[await this.decideEntity(e[0],t)];let n=t??Math.min(this.defaultTimeout,200);try{let i=new AbortController,o=setTimeout(()=>i.abort(),n),s=`${this.config.baseUrl}/v1/decide/batch`,a=await fetch(s,{method:"POST",headers:this._headers(),body:JSON.stringify({requests:e}),signal:i.signal});return clearTimeout(o),a.ok?(await a.json()).responses:(console.warn(`[Traffical] Edge batch decide failed: ${a.status} ${a.statusText}`),e.map(()=>null))}catch(i){return i instanceof Error&&i.name==="AbortError"?console.warn(`[Traffical] Edge batch decide timed out after ${n}ms`):console.warn("[Traffical] Edge batch decide error:",i),e.map(()=>null)}}_headers(){return{"Content-Type":"application/json",Authorization:`Bearer ${this.config.apiKey}`,"X-Org-Id":this.config.orgId,"X-Project-Id":this.config.projectId,"X-Env":this.config.env}}};function ke(r,e,t,n,i){let o=[];for(let a of e){let c=t[a];if(c==null)return null;o.push(String(c))}let s=o.join("_");return{policyId:r,entityId:s,unitKeyValue:n,allocationCount:i,context:t}}var le=class{constructor(e={}){this._seen=new Set;this._lastError=null;this._options=e}capture(e,t,n){try{return t()}catch(i){return this._onError(e,i),n}}async captureAsync(e,t,n){try{return await t()}catch(i){return this._onError(e,i),n}}async swallow(e,t){try{await t()}catch(n){this._onError(e,n)}}getLastError(){let e=this._lastError;return this._lastError=null,e}clearSeen(){this._seen.clear()}_onError(e,t){let n=this._resolveError(t);this._lastError=n;let i=`${e}:${n.name}:${n.message}`;this._seen.has(i)||(this._seen.add(i),console.warn(`[Traffical] Error in ${e}:`,n.message),this._options.onError?.(e,n),this._options.reportErrors&&this._options.errorEndpoint&&this._reportError(e,n).catch(()=>{}))}async _reportError(e,t){if(this._options.errorEndpoint)try{await fetch(this._options.errorEndpoint,{method:"POST",headers:{"Content-Type":"application/json",...this._options.sdkKey&&{"X-Traffical-Key":this._options.sdkKey}},body:JSON.stringify({tag:e,error:t.name,message:t.message,stack:t.stack,timestamp:new Date().toISOString(),sdk:"@traffical/js-client",userAgent:typeof navigator<"u"?navigator.userAgent:void 0})})}catch{}}_resolveError(e){return e instanceof Error?e:typeof e=="string"?new Error(e):new Error("An unknown error occurred")}};var j="failed_events";var ue=class{constructor(e){this._queue=[];this._flushTimer=null;this._isFlushing=!1;this._isDisabled=!1;this._droppedCount=0;this._endpoint=e.endpoint,this._apiKey=e.apiKey,this._storage=e.storage,this._batchSize=e.batchSize??10,this._flushIntervalMs=e.flushIntervalMs??3e4,this._requestTimeoutMs=e.requestTimeoutMs??1e4,this._maxQueueSize=e.maxQueueSize??1e3,this._onError=e.onError,this._onSchemaWarnings=e.onSchemaWarnings,this._lifecycleProvider=e.lifecycleProvider,this._setupListeners(),this._retryFailedEvents(),this._startFlushTimer()}log(e){this._isDisabled||(this._queue.length>=this._maxQueueSize&&(this._queue.shift(),this._droppedCount++),this._queue.push(e),this._queue.length>=this._batchSize&&this.flush())}async flush(){if(this._isFlushing||this._isDisabled||this._queue.length===0)return;this._isFlushing=!0;let e=[...this._queue];this._queue=[];try{let t=await this._sendEvents(e);if(t>=200&&t<300)return;if(t===401){this._disable();return}if(t===429||t>=500){this._persistFailedEvents(e),this._onError?.(new Error(`HTTP ${t}: event delivery failed, will retry`));return}this._onError?.(new Error(`HTTP ${t}: batch rejected, dropping ${e.length} events`))}catch(t){this._persistFailedEvents(e),this._onError?.(t instanceof Error?t:new Error(String(t)))}finally{this._isFlushing=!1}}_disable(){this._isDisabled||(this._isDisabled=!0,this._queue=[],this._storage.remove(j),console.warn("[Traffical] API key rejected (HTTP 401); event delivery disabled for this client"))}get droppedCount(){return this._droppedCount}get isDisabled(){return this._isDisabled}flushBeacon(){if(this._queue.length===0)return!0;if(typeof fetch>"u")return this.flush(),!1;let e=[...this._queue];return this._queue=[],fetch(this._endpoint,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this._apiKey}`},body:JSON.stringify({events:e}),keepalive:!0}).catch(()=>{this._persistFailedEvents(e)}),!0}get queueSize(){return this._queue.length}destroy(){this._flushTimer&&(clearInterval(this._flushTimer),this._flushTimer=null),this._removeListeners()}async _sendEvents(e){let t=new AbortController,n=setTimeout(()=>t.abort(),this._requestTimeoutMs),i;try{i=await fetch(this._endpoint,{method:"POST",headers:{"Content-Type":"application/json",Authorization:`Bearer ${this._apiKey}`},body:JSON.stringify({events:e}),signal:t.signal})}finally{clearTimeout(n)}if(!i.ok)return i.status;if(this._onSchemaWarnings)try{let o=await i.json();o.schemaWarnings&&o.schemaWarnings.length>0&&this._onSchemaWarnings(o.schemaWarnings)}catch{}return i.status}_persistFailedEvents(e){let n=[...this._storage.get(j)??[],...e].slice(-100);this._storage.set(j,n)}_retryFailedEvents(){let e=this._storage.get(j);!e||e.length===0||(this._storage.remove(j),this._queue.push(...e))}_startFlushTimer(){this._flushIntervalMs<=0||(this._flushTimer=setInterval(()=>{this.flush().catch(()=>{})},this._flushIntervalMs))}_setupListeners(){this._lifecycleProvider&&(this._visibilityCallback=e=>{e==="background"?this._lifecycleProvider?.isUnloading()?this.flushBeacon():this.flush().catch(()=>{}):this._retryFailedEvents()},this._lifecycleProvider.onVisibilityChange(this._visibilityCallback))}_removeListeners(){this._lifecycleProvider&&this._visibilityCallback&&(this._lifecycleProvider.removeVisibilityListener(this._visibilityCallback),this._visibilityCallback=void 0)}};var H="exposure_dedup";var W=class r{constructor(e){this._storage=e.storage,this._sessionTtlMs=e.sessionTtlMs??18e5,this._seen=new Set,this._sessionStart=Date.now(),this._restore()}static createKey(e,t,n){return`${e}:${t}:${n}`}shouldTrack(e){return this._isSessionExpired()&&this._resetSession(),this._seen.has(e)?!1:(this._seen.add(e),this._persist(),!0)}checkAndMark(e,t,n){let i=r.createKey(e,t,n);return this.shouldTrack(i)}clear(){this._seen.clear(),this._storage.remove(H)}get size(){return this._seen.size}_isSessionExpired(){return Date.now()-this._sessionStart>this._sessionTtlMs}_resetSession(){this._seen.clear(),this._sessionStart=Date.now(),this._storage.remove(H)}_persist(){let e={seen:Array.from(this._seen),sessionStart:this._sessionStart};this._storage.set(H,e,this._sessionTtlMs)}_restore(){let e=this._storage.get(H);if(!e)return;if(Date.now()-e.sessionStart>this._sessionTtlMs){this._storage.remove(H);return}this._seen=new Set(e.seen),this._sessionStart=e.sessionStart}};var z="stable_id",Xt="traffical_sid";var de=class{constructor(e){this._cachedId=null;this._storage=e.storage,this._useCookieFallback=e.useCookieFallback??!0,this._cookieName=e.cookieName??Xt}getId(){if(this._cachedId)return this._cachedId;let e=this._storage.get(z);return e?(this._cachedId=e,e):this._useCookieFallback&&(e=this._getCookie(),e)?(this._storage.set(z,e),this._cachedId=e,e):(e=this._generateId(),this._persist(e),this._cachedId=e,e)}setId(e){this._persist(e),this._cachedId=e}clear(){this._storage.remove(z),this._useCookieFallback&&this._deleteCookie(),this._cachedId=null}hasId(){return this._storage.get(z)!==null||this._getCookie()!==null}_persist(e){this._storage.set(z,e),this._useCookieFallback&&this._setCookie(e)}_generateId(){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)})}_getCookie(){if(typeof document>"u")return null;try{let e=document.cookie.split(";");for(let t of e){let[n,i]=t.trim().split("=");if(n===this._cookieName&&i)return decodeURIComponent(i)}}catch{}return null}_setCookie(e){if(!(typeof document>"u"))try{document.cookie=`${this._cookieName}=${encodeURIComponent(e)}; max-age=31536000; path=/; SameSite=Lax`}catch{}}_deleteCookie(){if(!(typeof document>"u"))try{document.cookie=`${this._cookieName}=; max-age=0; path=/`}catch{}}};var G="traffical:",Se=class{constructor(){this._available=this._checkAvailability()}get(e){if(!this._available)return null;try{let t=localStorage.getItem(G+e);if(!t)return null;let n=JSON.parse(t);return n.expiresAt&&Date.now()>n.expiresAt?(this.remove(e),null):n.value}catch{return null}}set(e,t,n){if(this._available)try{let i={value:t,...n&&{expiresAt:Date.now()+n}};localStorage.setItem(G+e,JSON.stringify(i))}catch{}}remove(e){if(this._available)try{localStorage.removeItem(G+e)}catch{}}clear(){if(this._available)try{let e=[];for(let t=0;t<localStorage.length;t++){let n=localStorage.key(t);n?.startsWith(G)&&e.push(n)}e.forEach(t=>localStorage.removeItem(t))}catch{}}_checkAvailability(){try{let e=G+"__test__";return localStorage.setItem(e,"test"),localStorage.removeItem(e),!0}catch{return!1}}},De=class{constructor(){this._store=new Map}get(e){let t=this._store.get(e);return t?t.expiresAt&&Date.now()>t.expiresAt?(this.remove(e),null):t.value:null}set(e,t,n){this._store.set(e,{value:t,...n&&{expiresAt:Date.now()+n}})}remove(e){this._store.delete(e)}clear(){this._store.clear()}};function Xe(){let r=new Se;return r.get("__check__")!==null||Jt()?r:new De}function Jt(){try{let r="__traffical_storage_test__";return localStorage.setItem(r,"test"),localStorage.removeItem(r),!0}catch{return!1}}var D="0.16.1";var Qt="js-client";function Pe(r,e){let t=new P({ttlMs:r.deduplicationTtlMs});return{name:"decision-tracking",onDecision(n){if(r.disabled)return;let i=n.metadata.unitKeyValue;if(!i)return;let o=P.hashAssignments(n.assignments);if(!t.checkAndMark(i,o))return;let s={type:"decision",id:n.decisionId,orgId:e.orgId,projectId:e.projectId,env:e.env,unitKey:i,timestamp:n.metadata.timestamp,assignments:n.assignments,layers:n.metadata.layers,context:n.metadata.filteredContext,configVersion:n.metadata.configVersion??e.getConfigVersion?.()??void 0,sdkName:Qt,sdkVersion:D};e.log(s)},onDestroy(){t.clear()}}}var Yt="traffical_rdr";function Zt(r,e,t){if(!(typeof document>"u"))try{document.cookie=`${r}=${encodeURIComponent(e)}; max-age=${t}; path=/; SameSite=Lax`}catch{}}function Re(r={}){let e=r.parameterKey??"redirect.url",t=r.compareMode??"pathname",n=r.cookieName??Yt;return{name:"redirect",onInitialize(i){typeof window>"u"||i.decide({context:{},defaults:{[e]:""}})},onBeforeDecision(i){return typeof window>"u"?i:{"url.pathname":window.location.pathname,...i}},onDecision(i){let o=i.assignments[e];if(typeof o!="string"||!o)return;let s=t==="href"?window.location.href:window.location.pathname;if(o===s)return;let a=i.metadata.layers.find(c=>c.policyId&&c.allocationName);a&&Zt(n,JSON.stringify({l:a.layerId,p:a.policyId,a:a.allocationName,ts:Date.now()}),86400),window.location.replace(o)}}}var en="traffical_rdr";function tn(r){if(typeof document>"u")return null;try{for(let e of document.cookie.split(";")){let[t,n]=e.trim().split("=");if(t===r&&n)return decodeURIComponent(n)}}catch{}return null}function nn(r,e){let t=tn(r);if(!t)return null;try{let n=JSON.parse(t);return Date.now()-n.ts>e?null:{layerId:n.l,policyId:n.p,allocationName:n.a}}catch{return null}}function Le(r={}){let e=r.cookieName??en,t=r.expiryMs??864e5;function n(i){let o=nn(e,t);if(!o)return;i.attribution=i.attribution??[],i.attribution.some(a=>a.layerId===o.layerId&&a.policyId===o.policyId)||i.attribution.push(o)}return{name:"redirect-attribution",onTrack(i){return n(i),!0},onExposure(i){return n(i),!0}}}var fe=[],Je={};function rn(){if(typeof window>"u")return{version:1,instances:Je,subscribe:()=>()=>{}};if(!window.__TRAFFICAL_DEBUG__){let r={version:1,instances:Je,subscribe(e){return fe.push(e),()=>{fe=fe.filter(t=>t!==e)}}};window.__TRAFFICAL_DEBUG__=r}return window.__TRAFFICAL_DEBUG__}function Qe(r){for(let e of fe)try{e(r)}catch{}}var on=0;function sn(){return`traffical_${Date.now().toString(36)}_${(++on).toString(36)}`}function an(){return`evt_${Date.now().toString(36)}_${Math.random().toString(36).slice(2,8)}`}var cn="traffical-debug";function Me(r={}){let e=r.instanceId??sn(),t=r.maxEvents??500,n=null,i=null,o={},s=[],a=null,c=null,f=[],h=[],l=[];function _(){return{ready:n?.isInitialized===!0,stableId:n?.getStableId?.()??null,effectiveUnitKey:c,configVersion:n?.getConfigVersion?.()??null,assignments:{...o},layers:[...s],lastDecisionId:a,overrides:n?.getOverrides?.()??{}}}function u(){let d=_();for(let v of h)try{v(d)}catch{}}function g(d,v){let A={id:an(),type:d,timestamp:Date.now(),data:v};f.push(A),f.length>t&&f.splice(0,f.length-t);for(let O of l)try{O(A)}catch{}}function y(){if(n)try{n.decide({context:{},defaults:{}})}catch{}}let b={id:e,meta:{orgId:"",projectId:"",env:"",sdkVersion:D},getState:_,subscribe(d){return h.push(d),()=>{h=h.filter(v=>v!==d)}},getEvents(d){return d!==void 0?f.slice(-d):[...f]},onEvent(d){return l.push(d),()=>{l=l.filter(v=>v!==d)}},getConfigBundle(){return i},setUnitKey(d){n?.identify?n.identify(d):n?.setStableId&&n.setStableId(d),u()},setOverride(d,v){n?.applyOverrides&&n.applyOverrides({[d]:v}),u(),y()},clearOverride(d){if(n?.getOverrides&&n?.applyOverrides){let v=n.getOverrides();delete v[d],n.clearOverrides?.(),n.applyOverrides(v)}u(),y()},clearAllOverrides(){n?.clearOverrides?.(),u(),y()},getOverrides(){return n?.getOverrides?.()??{}},reDecide(){y()},async refresh(){n?.refreshConfig&&await n.refreshConfig()}};return{name:cn,onInitialize(d){n=d,i&&(b.meta.orgId=i.orgId,b.meta.projectId=i.projectId,b.meta.env=i.env);let v=rn();v.instances[e]=b,Qe({type:"register",instanceId:e}),u()},onConfigUpdate(d){i=d,b.meta.orgId=d.orgId,b.meta.projectId=d.projectId,b.meta.env=d.env,u()},onDecision(d){o={...d.assignments},s=d.metadata?.layers?[...d.metadata.layers]:[],a=d.decisionId,d.metadata?.unitKeyValue&&(c=d.metadata.unitKeyValue),g("decision",d),u()},onResolve(d){o={...d},u()},onExposure(d){return g("exposure",d),!0},onTrack(d){return g("track",d),!0},onDestroy(){let d=typeof window<"u"?window.__TRAFFICAL_DEBUG__:null;d&&(delete d.instances[e],Qe({type:"unregister",instanceId:e})),h=[],l=[],n=null}}}var ge=class{constructor(){this._plugins=[]}register(e){let t="plugin"in e?e.plugin:e,n="priority"in e?e.priority??0:0;return this._plugins.some(i=>i.plugin.name===t.name)?(console.warn(`[Traffical] Plugin "${t.name}" already registered, skipping.`),!1):(this._plugins.push({plugin:t,priority:n}),this._plugins.sort((i,o)=>o.priority-i.priority),!0)}unregister(e){let t=this._plugins.findIndex(n=>n.plugin.name===e);return t===-1?!1:(this._plugins.splice(t,1),!0)}get(e){return this._plugins.find(t=>t.plugin.name===e)?.plugin}getAll(){return this._plugins.map(e=>e.plugin)}async runInitialize(e){for(let{plugin:t}of this._plugins)if(t.onInitialize)try{await t.onInitialize(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onInitialize error:`,n)}}runConfigUpdate(e){for(let{plugin:t}of this._plugins)if(t.onConfigUpdate)try{t.onConfigUpdate(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onConfigUpdate error:`,n)}}runBeforeDecision(e){let t=e;for(let{plugin:n}of this._plugins)if(n.onBeforeDecision)try{let i=n.onBeforeDecision(t);i&&(t=i)}catch(i){console.warn(`[Traffical] Plugin "${n.name}" onBeforeDecision error:`,i)}return t}runDecision(e){for(let{plugin:t}of this._plugins)if(t.onDecision)try{t.onDecision(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onDecision error:`,n)}}runResolve(e){for(let{plugin:t}of this._plugins)if(t.onResolve)try{t.onResolve(e)}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onResolve error:`,n)}}runExposure(e){for(let{plugin:t}of this._plugins)if(t.onExposure)try{if(t.onExposure(e)===!1)return!1}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onExposure error:`,n)}return!0}runTrack(e){for(let{plugin:t}of this._plugins)if(t.onTrack)try{if(t.onTrack(e)===!1)return!1}catch(n){console.warn(`[Traffical] Plugin "${t.name}" onTrack error:`,n)}return!0}runDestroy(){for(let{plugin:e}of this._plugins)if(e.onDestroy)try{e.onDestroy()}catch(t){console.warn(`[Traffical] Plugin "${e.name}" onDestroy error:`,t)}}clear(){this._plugins=[]}};function Ye(){let r=[],e=!1;function t(s){for(let a of r)a(s)}let n=()=>{e=!0,t("background")},i=()=>{typeof document<"u"&&t(document.visibilityState==="hidden"?"background":"foreground")},o=()=>{e=!0,t("background")};return typeof window<"u"&&(window.addEventListener("pagehide",n),window.addEventListener("beforeunload",o)),typeof document<"u"&&document.addEventListener("visibilitychange",i),{onVisibilityChange(s){r.push(s)},removeVisibilityListener(s){let a=r.indexOf(s);a!==-1&&r.splice(a,1)},isUnloading(){return e}}}var Oe="js-client";function Ze(r,e){if(e!==void 0)return{context:r,defaults:e};let t=r;return{context:t.context,defaults:t.defaults}}var ln="https://sdk.traffical.io",un=6e4,dn=1e4,fn=3e5,gn=3e5,hn=100,pn=.1;function mn(r){let e=r*pn;return r+(Math.random()*2-1)*e}function yn(r){if(!r||typeof r!="object")return!1;let e=r;if(!Array.isArray(e.parameters)||!Array.isArray(e.layers))return!1;let t=e.hashing;return!(!t||typeof t!="object"||typeof t.unitKey!="string"||t.unitKey.length===0||typeof t.bucketCount!="number"||!Number.isInteger(t.bucketCount)||t.bucketCount<1)}var M=class{constructor(e){this._state={bundle:null,etag:null,lastFetchTime:0,lastOfflineWarning:0,lastMalformedWarning:0,refreshTimer:null,isInitialized:!1,serverResponse:null,cachedEdgeResults:null};this._decisionCache=new Map;this._cumulativeAttribution=new Map;this._identityListeners=[];this._overrideListeners=[];this._overrides={};this._lastResolveContextKey=null;this._readyPromise=new Promise(e=>{this._readyResolve=e});let t=e.evaluationMode??"bundle";this._options={orgId:e.orgId,projectId:e.projectId,env:e.env,apiKey:e.apiKey,baseUrl:e.baseUrl??ln,localConfig:e.localConfig,refreshIntervalMs:e.refreshIntervalMs??un,attributionMode:e.attributionMode??"cumulative",evaluationMode:t},this._requestTimeoutMs=e.configTimeoutMs??e.requestTimeoutMs??dn;let n={baseUrl:this._options.baseUrl,orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,apiKey:this._options.apiKey,defaultTimeoutMs:e.resolveTimeoutMs??e.requestTimeoutMs};if(this._decisionClient=new $(n),this._errorBoundary=new le(e.errorBoundary),this._storage=e.storage??Xe(),this._lifecycleProvider=e.lifecycleProvider??Ye(),!e.onSchemaWarnings)try{typeof globalThis<"u"&&globalThis.process?.env?.NODE_ENV==="development"&&(e.onSchemaWarnings=o=>{for(let s of o)console.warn(`[Traffical] Schema warning for "${s.event}":`,s.violations.map(a=>`${a.path}: ${a.message}`).join(", "))})}catch{}if(this._eventLogger=new ue({endpoint:`${this._options.baseUrl}/v1/events/batch`,apiKey:e.apiKey,storage:this._storage,lifecycleProvider:this._lifecycleProvider,batchSize:e.batchSize??e.eventBatchSize,flushIntervalMs:e.flushIntervalMs??e.eventFlushIntervalMs,maxQueueSize:e.eventMaxQueueSize,requestTimeoutMs:e.eventsTimeoutMs??e.requestTimeoutMs,onError:i=>{console.warn("[Traffical] Event logging error:",i.message)},onSchemaWarnings:e.onSchemaWarnings}),this._exposureDedup=new W({storage:this._storage,sessionTtlMs:e.exposureSessionTtlMs}),this._stableId=new de({storage:this._storage}),this._plugins=new ge,this._assignmentLogger=e.assignmentLogger,this._byoEventLogger=e.eventLogger,this._disableCloudEvents=e.disableCloudEvents??!1,this._assignmentLoggerDedup=e.deduplicateAssignmentLogger!==!1&&e.assignmentLogger?new W({storage:this._storage,sessionTtlMs:e.exposureSessionTtlMs}):null,e.trackDecisions!==!1&&(!this._disableCloudEvents||this._byoEventLogger)&&this._plugins.register({plugin:Pe({deduplicationTtlMs:e.decisionDeduplicationTtlMs},{orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,log:i=>this._dispatchEvent(i),getConfigVersion:()=>this.getConfigVersion()}),priority:100}),e.plugins)for(let i of e.plugins)this._plugins.register(i);if(this._options.localConfig&&(this._state.bundle=this._options.localConfig,this._plugins.runConfigUpdate(this._options.localConfig)),typeof window<"u"){let i=window;i.__TRAFFICAL_INSTANCES__??(i.__TRAFFICAL_INSTANCES__=[]),i.__TRAFFICAL_INSTANCES__.push(this)}}async initialize(){await this._errorBoundary.captureAsync("initialize",async()=>{this._options.evaluationMode==="server"?await this._fetchServerResolve():await this._fetchConfig(),this._startBackgroundRefresh(),this._state.isInitialized=!0,await this._plugins.runInitialize(this)},void 0),this._readyResolve()}get isInitialized(){return this._state.isInitialized}async waitForReady(){return this._readyPromise}async close(){if(this._state.refreshTimer&&(clearInterval(this._state.refreshTimer),this._state.refreshTimer=null),this._lifecycleProvider.isUnloading()?this._eventLogger.flushBeacon():await this._eventLogger.flush().catch(()=>{}),this._eventLogger.destroy(),this._plugins.runDestroy(),this._identityListeners=[],this._overrideListeners=[],this._overrides={},typeof window<"u"){let t=window.__TRAFFICAL_INSTANCES__;if(t){let n=t.indexOf(this);n!==-1&&t.splice(n,1)}}}destroy(){if(this._state.refreshTimer&&(clearInterval(this._state.refreshTimer),this._state.refreshTimer=null),this._lifecycleProvider.isUnloading()?this._eventLogger.flushBeacon():this._eventLogger.flush().catch(()=>{}),this._eventLogger.destroy(),this._plugins.runDestroy(),this._identityListeners=[],this._overrideListeners=[],this._overrides={},typeof window<"u"){let t=window.__TRAFFICAL_INSTANCES__;if(t){let n=t.indexOf(this);n!==-1&&t.splice(n,1)}}}async refreshConfig(){await this._errorBoundary.swallow("refreshConfig",async()=>{this._options.evaluationMode==="server"?await this._fetchServerResolve():await this._fetchConfig()})}getConfigVersion(){return this._state.serverResponse?.stateVersion??this._state.bundle?.version??null}getUnitKeyField(){return oe(this._getEffectiveBundle())}getParameterLayerId(e){return se(this._getEffectiveBundle(),e)}getParams(e,t){let{context:n,defaults:i}=Ze(e,t);return this._errorBoundary.capture("getParams",()=>{if(this._options.evaluationMode==="server"&&this._state.serverResponse){this._maybeResolveForContext(n);let c={...i};for(let[f,h]of Object.entries(this._state.serverResponse.assignments))f in c&&(c[f]=h);return this._plugins.runResolve(c),this._applyOverridesToResult(c),c}let o=this._getEffectiveBundle(),s=this._enrichContext(n),a=ae(o,s,i);return this._plugins.runResolve(a),this._applyOverridesToResult(a),a},i)}decide(e,t){let{context:n,defaults:i}=Ze(e,t);return this._errorBoundary.capture("decide",()=>{if(this._options.evaluationMode==="server"&&this._state.serverResponse){this._maybeResolveForContext(n);let f=this._state.serverResponse,h={...i};for(let[_,u]of Object.entries(f.assignments))_ in h&&(h[_]=u);let l={decisionId:L(),assignments:h,metadata:{...f.metadata,configVersion:f.stateVersion}};return this._cacheDecision(l),this._updateCumulativeAttribution(l),this._plugins.runDecision(l),this._applyOverridesToResult(l.assignments),this._emitAssignmentLogEntries(l,"decision"),l}let o=this._getEffectiveBundle(),s=this._enrichContext(n);s=this._plugins.runBeforeDecision(s);let a=this._state.cachedEdgeResults??void 0,c=ce(o,s,i,a);return this._cacheDecision(c),this._updateCumulativeAttribution(c),this._plugins.runDecision(c),this._applyOverridesToResult(c.assignments),this._emitAssignmentLogEntries(c,"decision"),c},{decisionId:L(),assignments:i,metadata:{timestamp:new Date().toISOString(),unitKeyValue:"",layers:[]}})}trackExposure(e){this._errorBoundary.capture("trackExposure",()=>{let t=e.metadata.unitKeyValue;if(!t)return;this._emitAssignmentLogEntries(e,"exposure");let n=e.metadata.configVersion??this.getConfigVersion()??void 0,i=[];for(let s of e.metadata.layers)!s.policyId||!s.allocationName||s.attributionOnly||!this._exposureDedup.checkAndMark(t,s.policyId,s.allocationName)||i.push(s);if(i.length===0)return;let o={type:"exposure",id:we(),decisionId:e.decisionId,orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,unitKey:t,timestamp:new Date().toISOString(),assignments:e.assignments,layers:i,context:e.metadata.filteredContext,configVersion:n,sdkName:Oe,sdkVersion:D};this._plugins.runExposure(o)&&this._dispatchEvent(o)},void 0)}track(e,t,n){this._errorBoundary.capture("track",()=>{let i=n?.unitKey??this._stableId.getId(),o=typeof n?.value=="number"?n.value:typeof t?.value=="number"?t.value:void 0,s=this._buildAttribution(i,n?.decisionId),a=n?.decisionId,c={type:"track",id:Ae(),orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,unitKey:i,timestamp:new Date().toISOString(),event:e,value:o,values:n?.values,properties:t,decisionId:a,attribution:s,eventTimestamp:n?.eventTimestamp,sdkName:Oe,sdkVersion:D};this._plugins.runTrack(c)&&this._dispatchEvent(c)},void 0)}async flushEvents(){await this._errorBoundary.swallow("flushEvents",async()=>{await this._eventLogger.flush()})}use(e){if(!this._plugins.register(e))return this;if(this._state.isInitialized){try{e.onInitialize?.(this)}catch(n){console.warn(`[Traffical] Plugin "${e.name}" late onInitialize error:`,n)}if(this._state.bundle)try{e.onConfigUpdate?.(this._state.bundle)}catch(n){console.warn(`[Traffical] Plugin "${e.name}" late onConfigUpdate error:`,n)}}return this}getPlugin(e){return this._plugins.get(e)}getStableId(){return this._stableId.getId()}setStableId(e){this._stableId.setId(e)}identify(e){this._stableId.setId(e);for(let t of this._identityListeners)try{t(e)}catch{}}onIdentityChange(e){return this._identityListeners.push(e),()=>{this._identityListeners=this._identityListeners.filter(t=>t!==e)}}onOverridesChange(e){return this._overrideListeners.push(e),()=>{this._overrideListeners=this._overrideListeners.filter(t=>t!==e)}}applyOverrides(e){Object.assign(this._overrides,e),this._notifyOverrideListeners()}clearOverrides(){this._overrides={},this._notifyOverrideListeners()}getOverrides(){return{...this._overrides}}_notifyOverrideListeners(){let e={...this._overrides};for(let t of this._overrideListeners)try{t(e)}catch{}}_dispatchEvent(e){if(this._byoEventLogger)try{this._byoEventLogger(e)}catch{}this._disableCloudEvents||this._eventLogger.log(e)}_emitAssignmentLogEntries(e,t){if(!this._assignmentLogger)return;let n=e.metadata.unitKeyValue;if(!n)return;let i=e.metadata.configVersion??this.getConfigVersion()??void 0;for(let o of e.metadata.layers)!o.policyId||!o.allocationName||this._assignmentLoggerDedup&&!this._assignmentLoggerDedup.checkAndMark(n,o.policyId,`${o.allocationName}:${t}`)||this._assignmentLogger({unitKey:n,policyId:o.policyId,policyKey:o.policyKey,allocationName:o.allocationName,allocationKey:o.allocationKey,timestamp:e.metadata.timestamp,layerId:o.layerId,allocationId:o.allocationId,orgId:this._options.orgId,projectId:this._options.projectId,env:this._options.env,sdkName:Oe,sdkVersion:D,properties:e.metadata.filteredContext,type:t,decisionId:e.decisionId,anonymousId:this._stableId.getId(),id:Ce(),bucket:o.bucket>=0?o.bucket:void 0,probability:o.probability,modelVersion:o.modelVersion,configVersion:i})}_applyOverridesToResult(e){let t=Object.keys(this._overrides);if(t.length!==0)for(let n of t)n in e&&(e[n]=this._overrides[n])}_getEffectiveBundle(){return this._state.bundle??this._options.localConfig??null}_enrichContext(e){let n=this._getEffectiveBundle()?.hashing?.unitKey??"userId";return e[n]?e:{...e,[n]:this._stableId.getId()}}async _fetchConfig(){let e=`${this._options.baseUrl}/v1/config/${encodeURIComponent(this._options.projectId)}?env=${encodeURIComponent(this._options.env)}`,t={"Content-Type":"application/json",Authorization:`Bearer ${this._options.apiKey}`};this._state.etag&&(t["If-None-Match"]=this._state.etag);let n=new AbortController,i=setTimeout(()=>n.abort(),this._requestTimeoutMs);try{let o=await fetch(e,{method:"GET",headers:t,signal:n.signal});if(o.status===304){this._state.lastFetchTime=Date.now();return}if(!o.ok)throw new Error(`HTTP ${o.status}: ${o.statusText}`);let s=await o.json(),a=o.headers.get("ETag");if(!yn(s)){this._logMalformedBundleWarning();return}if(this._state.bundle=s,this._state.etag=a,this._state.lastFetchTime=Date.now(),this._findEdgePolicies(s).length>0){let c=await this._prefetchEdgeResults(s,this._enrichContext({}));this._state.cachedEdgeResults=c}else this._state.cachedEdgeResults=null;this._plugins.runConfigUpdate(s)}catch(o){this._logOfflineWarning(o)}finally{clearTimeout(i)}}_startBackgroundRefresh(){let e=this._options.evaluationMode==="server"?this._state.serverResponse?.suggestedRefreshMs??this._options.refreshIntervalMs:this._options.refreshIntervalMs;if(e<=0)return;let t=()=>{this._state.refreshTimer=setTimeout(()=>{t(),this._options.evaluationMode==="server"?this._fetchServerResolve().catch(()=>{}):this._fetchConfig().catch(()=>{})},mn(e))};t()}_maybeResolveForContext(e){let t=this._enrichContext(e),n;try{n=JSON.stringify(t)}catch{n=""}n!==this._lastResolveContextKey&&(this._lastResolveContextKey=n,this._fetchServerResolve(t))}async _fetchServerResolve(e){if(this._decisionClient)try{let t=e??this._enrichContext({}),n=await this._decisionClient.resolve({context:t});n&&(this._state.serverResponse=n,this._state.lastFetchTime=Date.now())}catch(t){this._logOfflineWarning(t)}}_findEdgePolicies(e){let t=[];for(let n of e.layers)for(let i of n.policies)i.state==="running"&&i.entityConfig?.resolutionMode==="edge"&&t.push(i);return t}async _prefetchEdgeResults(e,t){if(!this._decisionClient)return{};let n=this._findEdgePolicies(e);if(n.length===0)return{};let i=K(e,t);if(!i)return{};let o=n.map(s=>{if(!s.entityConfig)return null;let a=s.entityConfig.dynamicAllocations?typeof t[s.entityConfig.dynamicAllocations.countKey]=="number"?Math.floor(t[s.entityConfig.dynamicAllocations.countKey]):0:s.allocations.length;return ke(s.id,s.entityConfig.entityKeys,t,i,a||void 0)}).filter(s=>s!==null);if(o.length===0)return{};try{let s=await this._decisionClient.decideEntityBatch(o),a=new Map;for(let c=0;c<o.length;c++){let f=s[c];f&&a.set(o[c].policyId,{allocationIndex:f.allocationIndex,entityId:o[c].entityId})}return a.size>0?{edgeResults:a}:{}}catch{return{}}}_logOfflineWarning(e){let t=Date.now();t-this._state.lastOfflineWarning>fn&&(console.warn(`[Traffical] Failed to fetch config: ${e instanceof Error?e.message:String(e)}. Using ${this._state.bundle?"cached":"local"} config.`),this._state.lastOfflineWarning=t)}_logMalformedBundleWarning(){let e=Date.now();e-this._state.lastMalformedWarning>gn&&(console.warn(`[Traffical] Discarded malformed config bundle (invalid hashing/shape). Using ${this._state.bundle?"cached":"local"} config.`),this._state.lastMalformedWarning=e)}_cacheDecision(e){if(this._decisionCache.size>=hn){let t=this._decisionCache.keys().next().value;t&&this._decisionCache.delete(t)}this._decisionCache.set(e.decisionId,e)}_updateCumulativeAttribution(e){let t=e.metadata.unitKeyValue;if(!t)return;let n=this._cumulativeAttribution.get(t);n||(n=new Map,this._cumulativeAttribution.set(t,n));for(let i of e.metadata.layers){if(!i.policyId||!i.allocationName)continue;let o=`${i.layerId}:${i.policyId}`;n.set(o,{layerId:i.layerId,policyId:i.policyId,allocationName:i.allocationName})}}_buildAttribution(e,t){if(this._options.attributionMode==="decision"){if(!t)return;let i=this._decisionCache.get(t);return i?i.metadata.layers.filter(o=>o.policyId&&o.allocationName).map(o=>({layerId:o.layerId,policyId:o.policyId,allocationName:o.allocationName})):void 0}let n=this._cumulativeAttribution.get(e);return n&&n.size>0?Array.from(n.values()):void 0}};async function et(r){let e=new M(r);return await e.initialize(),e}function tt(r){return new M(r)}function nt(r={}){let e={observeMutations:r.observeMutations??!0,debounceMs:r.debounceMs??100},t=[],n={},i=null,o=null;function s(u,g){try{return new RegExp(u).test(g)}catch{return g===u}}function a(u,g,y){if(g==="innerHTML")u.innerHTML=y;else if(g==="textContent")u.textContent=y;else if(g==="src"&&"src"in u)u.src=y;else if(g==="href"&&"href"in u)u.href=y;else if(g.startsWith("style.")){let b=g.slice(6);u.style[b]=y}else u.setAttribute(g,y)}function c(u,g){let y=String(g);try{let b=document.querySelectorAll(u.selector);for(let w of b)a(w,u.property,y)}catch(b){console.warn(`[Traffical DOM Binding] Failed to apply binding for ${u.parameterKey}:`,b)}}function f(u,g=!1){n=u;let y=typeof window<"u"?window.location.pathname:"";for(let b of t){if(!g&&!s(b.urlPattern,y))continue;let w=u[b.parameterKey];w!==void 0&&c(b,w)}}function h(){o&&clearTimeout(o),o=setTimeout(()=>{f(n)},e.debounceMs)}function l(){i||typeof MutationObserver>"u"||typeof document>"u"||(i=new MutationObserver(()=>{h()}),i.observe(document.body,{childList:!0,subtree:!0}))}function _(){i&&(i.disconnect(),i=null),o&&(clearTimeout(o),o=null)}return{name:"dom-binding",onInitialize(){e.observeMutations&&l()},onConfigUpdate(u){t=u.domBindings??[]},onResolve(u){f(u)},onDecision(u){f(u.assignments)},onDestroy(){_(),t=[],n={}},applyBindings(u){f(u||n)},getBindings(){return t}}}var T=null;async function vn(r){return T?(console.warn("[Traffical] Client already initialized. Returning existing instance."),T):(T=await et(r),T)}function _n(r){return T?(console.warn("[Traffical] Client already initialized. Returning existing instance."),T):(T=tt(r),T.initialize().catch(e=>{console.warn("[Traffical] Initialization error:",e)}),T)}function bn(){return T}function xn(){T&&(T.destroy(),T=null)}return ut(En);})();
3
3
  //# sourceMappingURL=traffical.min.js.map