@arsel.sa/web-sdk 1.1.0 → 1.2.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,4 +1,4 @@
1
- (function(m,$){typeof exports=="object"&&typeof module<"u"?$(exports):typeof define=="function"&&define.amd?define(["exports"],$):(m=typeof globalThis<"u"?globalThis:m||self,$(m.Arsel={}))})(this,(function(m){"use strict";const $="arsel",v={events:"events",inAppBeacons:"inapp_beacons"};let Y=null;function at(){return Y||(Y=new Promise((e,t)=>{const n=indexedDB.open($,2);n.onupgradeneeded=()=>{const i=n.result;i.objectStoreNames.contains("kv")||i.createObjectStore("kv");for(const r of Object.values(v))i.objectStoreNames.contains(r)||i.createObjectStore(r,{keyPath:"id",autoIncrement:!0})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),Y)}function N(e,t,n){return at().then(i=>new Promise((r,s)=>{const a=n(i.transaction(e,t).objectStore(e));a.onsuccess=()=>r(a.result),a.onerror=()=>s(a.error)}))}function c(e){return N("kv","readonly",t=>t.get(e)).then(t=>t??null)}function u(e,t){return N("kv","readwrite",n=>n.put(t,e))}function K(e){return N("kv","readwrite",t=>t.delete(e))}function ve(e,t,n=""){return N(e,"readwrite",i=>i.add({body:t,idempotencyKey:n,createdAtMs:Date.now()}))}function oe(e){return N(e,"readonly",t=>t.getAll())}function se(e,t){return N(e,"readwrite",n=>n.delete(t))}function Se(e){return N(e,"readonly",t=>t.count())}async function ct(e,t){const n=await oe(e);if(!(n.length<=t))for(const i of n.slice(0,n.length-t))i.id!==void 0&&await se(e,i.id)}const o={clientKey:"client_key",baseUrl:"base_url",anonymousId:"anonymous_id",externalId:"external_id",email:"email",phoneNumber:"phone_number",installationId:"installation_id",deviceSecret:"device_secret",vapidKeyVersion:"vapid_key_version",endpoint:"endpoint",subscriptionStatus:"subscription_status",sessionStartedAt:"session_started_at",backgroundedAt:"backgrounded_at",lastResponseCode:"last_response_code",lastResponsePath:"last_response_path",lastResponseAtMs:"last_response_at",inAppBundle:"inapp_bundle",inAppState:"inapp_state",inAppSession:"inapp_session"};async function L(){const e=await c(o.anonymousId);if(e)return e;const t=crypto.randomUUID();return await u(o.anonymousId,t),t}async function lt(){const e=crypto.randomUUID();return await u(o.anonymousId,e),e}const V="1.1.0",Ae={"X-Arsel-SDK":`web/${V}`},b={success:"success",retryable:"retryable",permanent:"permanent",reauth:"reauth"},J=-1;function Ee(e,t){return e>=200&&e<=299?b.success:e===408||e===429||e>=500&&e<=599?b.retryable:t&&(e===401||e===403||e===404)?b.reauth:e===404?b.retryable:b.permanent}async function G(e,t){try{await Promise.all([u(o.lastResponseCode,t),u(o.lastResponsePath,e),u(o.lastResponseAtMs,Date.now())])}catch{}}async function F(e,t,n,i={},r=!1){let s;try{s=await fetch(e+t,{method:"POST",headers:{"Content-Type":"application/json",...Ae,...i},body:JSON.stringify(n),credentials:"omit",keepalive:!0})}catch{return await G(t,J),{result:b.retryable,code:J,body:null}}await G(t,s.status);const a=Ee(s.status,r);let l=null;try{l=await s.json()}catch{}return{result:a,code:s.status,body:l}}async function ae(e,t,n={},i=!1,r={}){let s;try{s=await fetch(e+t,{...r,credentials:"omit",headers:{...Ae,...n}})}catch{return await G(t,J),{result:b.retryable,code:J,body:null}}await G(t,s.status);let a=null;try{a=await s.json()}catch{}return{result:Ee(s.status,i),code:s.status,body:a}}const ut="/v1/events/send",T="arsel.",dt=`${T}session_start`,ft=`${T}session_end`,pt=`${T}identify`,mt=`${T}screen`,yt=80,bt=128,ht=255,Ie=50,gt=8,_e=64*1024;function ce(e,t){if(e===null)return null;const n=typeof e;if(n==="string"||n==="boolean")return e;if(n==="number")return Number.isFinite(e)?e:String(e);if(n==="bigint")return String(e);if(e instanceof Date)return Number.isNaN(e.getTime())?void 0:e.toISOString();if(n!=="object"||t>=gt)return;if(Array.isArray(e))return e.map(r=>ce(r,t+1)??null);const i={};for(const[r,s]of Object.entries(e)){if(!r)continue;const a=ce(s,t+1);a!==void 0&&(i[r]=a)}return i}function wt(e){const t={};let n=2,i=!1;for(const[r,s]of Object.entries(e??{})){if(!r)continue;const a=ce(s,0);if(a===void 0)continue;const l=r.length+JSON.stringify(a).length+6;if(n+l>_e){i=!0;continue}n+=l,t[r]=a}return i&&console.warn(`[arsel] event data exceeded ${_e} serialized bytes — oversized properties were dropped`),t}async function vt(e,t,n){const[i,r,s,a]=await Promise.all([L(),c(o.externalId),c(o.email),c(o.phoneNumber)]),l={event:e.slice(0,yt),anonymous_id:i.slice(0,bt),data:wt(t),timestamp:new Date(n).toISOString()};return r&&(l.external_id=r.slice(0,ht)),s&&(l.email=s),a&&(l.phone_number=a),JSON.stringify(l)}async function P(e,t,n=Date.now()){await ve(v.events,await vt(e,t,n),crypto.randomUUID()),W().catch(()=>{})}let j=null;function W(){return j||(j=Et().finally(()=>{j=null}),j)}function St(e){const t=e[0].idempotencyKey;return e.length===1?t:`${t}:${e[e.length-1].idempotencyKey}:${e.length}`}function At(e,t,n){e.some(r=>r.external_id||r.email||r.phone_number)&&console.error(`[arsel] ${e.length} event(s) carrying identifiers were rejected permanently (HTTP ${t}) and dropped. Response: ${JSON.stringify(n)}`)}async function Et(){const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!(!e||!t))for(;;){const n=await oe(v.events);if(n.length===0)return;for(let i=0;i<n.length;i+=Ie){const r=n.slice(i,i+Ie),s=r.map(l=>JSON.parse(l.body)),a=await F(t,ut,r.length===1?s[0]:{events:s},{Authorization:`Bearer ${e}`,"Idempotency-Key":St(r)});if(a.result===b.retryable)return;a.result!==b.success&&At(s,a.code,a.body);for(const l of r)l.id!==void 0&&await se(v.events,l.id)}}}const Z=1e3,It=720*60*60*Z,_t=500,Ne=50,Nt=86400,xt=900,Q={maxPerSession:1,maxLifetime:3,minSecondsBetween:86400,delaySeconds:0},kt=["MODAL","BANNER_TOP","BANNER_BOTTOM","IMAGE_ONLY"];let le=!1,d=null,g={},S={startedAt:0,counts:{}},X=null,z=null,xe=!1,ue=null,x=null,ke=!1,Te=!1;function k(e){ke&&console.info(`[arsel] in-app: ${e}`)}async function Tt(e){le=!0,ke=e;const[t,n,i]=await Promise.all([c(o.inAppBundle),c(o.inAppState),c(o.inAppSession)]);d=t,g=n??{},S=i??{startedAt:0,counts:{}},await Be(),await ee()}function Pt(e){x=e}function Dt(e){xe=e,e&&fe()}function Ot(){return{messages:(d==null?void 0:d.messages.length)??0,bundleVersion:(d==null?void 0:d.bundleVersion)??null,fetchedAtMs:(d==null?void 0:d.fetchedAtMs)??null}}function Mt(){return Se(v.inAppBeacons)}async function Pe(){d=null,await K(o.inAppBundle),le&&await ee(!0)}function Rt(){ee(!0)}function ee(e=!1){return ue??(ue=Ut(e).finally(()=>{ue=null})),ue}async function Ut(e){if(!le)return;const t=Date.now();if(!e&&d&&t-d.fetchedAtMs<d.ttlSeconds*Z)return;const n=await Oe();if(!n)return;const i=Bt(n.clientKey,n.installationId),r={"X-Arsel-Device-Auth":n.deviceSecret},s=!!(d!=null&&d.bundleVersion);s&&(r["If-None-Match"]=`"${(d==null?void 0:d.bundleVersion)??""}"`);let a=await De(n.baseUrl,i,r);if(a.code===Yt&&s&&Te&&(k("conditional request failed; retrying without If-None-Match"),delete r["If-None-Match"],a=await De(n.baseUrl,i,r)),a.code===Jt){d&&(d={...d,fetchedAtMs:t},await u(o.inAppBundle,d));return}if(a.result!==b.success||!a.body)return;s||(Te=!0);const l=Ct(a.body,t);l&&(d=l,await u(o.inAppBundle,d),await Ht(l,t))}function De(e,t,n){return ae(e,t,n,!0,{cache:"no-store"})}function Bt(e,t){const n=encodeURIComponent(e),i=encodeURIComponent(t);return`/api/v1/orgs/${n}/in-app/bundle?installationId=${i}`}async function Oe(){const[e,t,n,i]=await Promise.all([c(o.clientKey),c(o.baseUrl),c(o.installationId),c(o.deviceSecret)]);return!e||!t||!n||!i?null:{clientKey:e,baseUrl:t,installationId:n,deviceSecret:i}}function Ct(e,t){if(typeof(e==null?void 0:e.bundleVersion)!="string")return k("response carried no bundleVersion"),null;e.contractVersion!==void 0&&e.contractVersion!==1&&k(`unknown contractVersion ${String(e.contractVersion)}; proceeding`);const n=Array.isArray(e.messages)?e.messages:[],i=[];for(const s of n){const a=$t(s);a&&i.push(a)}n.length!==i.length&&k(`dropped ${n.length-i.length} unrenderable message(s)`);const r=O(e.ttlSeconds);return{bundleVersion:e.bundleVersion,ttlSeconds:r&&r>0?r:xt,fetchedAtMs:t,messages:i}}function $t(e){if(!D(e))return null;const t=y(e.campaignId),n=y(e.messageId),i=y(e.layout),r=D(e.content)?e.content:null,s=r?y(r.headline):void 0;if(!t||!n||!i||!r||!s)return k("message missing a required field"),null;if(!kt.includes(i))return k(`layout ${i} is not renderable on web`),null;const a=D(e.trigger)?e.trigger:{},l=D(e.displayRules)?e.displayRules:{};return{campaignId:t,messageId:n,variantKey:y(e.variantKey)??"default",priority:O(e.priority)??0,expiresAtMs:qt(e.expiresAt),triggerType:y(a.type)??"APP_OPEN",triggerEventName:y(a.eventName)??null,triggerProperties:D(a.properties)?a.properties:null,displayRules:{maxPerSession:O(l.maxPerSession)??Q.maxPerSession,maxLifetime:O(l.maxLifetime)??Q.maxLifetime,minSecondsBetween:O(l.minSecondsBetween)??Q.minSecondsBetween,delaySeconds:O(l.delaySeconds)??Q.delaySeconds},layout:i,content:{headline:s,body:y(r.body)??"",imageUrl:y(r.imageUrl),backgroundColor:y(r.backgroundColor),textColor:y(r.textColor),showCloseButton:r.showCloseButton!==!1},buttons:Array.isArray(e.buttons)?e.buttons.map(Kt).filter(w=>w!==null):[]}}function Kt(e){if(!D(e))return null;const t=y(e.buttonId),n=y(e.label),i=y(e.action);return!t||!n||!i?null:{buttonId:t,label:n,action:i,value:y(e.value),style:y(e.style)==="SECONDARY"?"SECONDARY":"PRIMARY"}}function Lt(e,t,n,i){if(xe||X!==null||!d)return null;for(const r of d.messages){if(r.triggerType!==t||t!=="APP_OPEN"&&r.triggerEventName!==n||!Vt(r.triggerProperties,i))continue;const s=g[r.messageId];if(r.expiresAtMs!==null&&r.expiresAtMs<=e){zt(r);continue}if(!(((s==null?void 0:s.shown)??0)>=r.displayRules.maxLifetime)&&!((S.counts[r.messageId]??0)>=r.displayRules.maxPerSession)&&!(s&&e-s.lastShownAtMs<r.displayRules.minSecondsBetween*Z))return r}return null}function Vt(e,t){if(!e)return!0;const n=t;for(const[i,r]of Object.entries(e))if(String(n[i])!==String(r))return!1;return!0}function de(e,t,n={}){try{const i=Lt(Date.now(),e,t,n);if(!i)return;X=i.messageId,Me=t;const r=i.displayRules.delaySeconds*Z;if(r<=0){x==null||x(i);return}z=setTimeout(()=>{z=null,x==null||x(i)},r)}catch(i){k(`observe failed: ${i instanceof Error?i.message:"unknown"}`),X=null}}let Me=null;function Ft(){return Me}function Re(){Be().then(()=>{de("APP_OPEN",null,{})})}function fe(){z!==null&&(clearTimeout(z),z=null,X=null)}function Ue(){X=null}async function jt(e,t){const n=Date.now(),i=g[e.messageId]??{shown:0,lastShownAtMs:0,lastSeenInBundleAtMs:n};g={...g,[e.messageId]:{...i,shown:i.shown+1,lastShownAtMs:n}},S={...S,counts:{...S.counts,[e.messageId]:(S.counts[e.messageId]??0)+1}},await Promise.all([u(o.inAppState,g),u(o.inAppSession,S)]),await te(e,"impression",{triggerEventName:t})}async function Wt(e,t){await te(e,"clicked",{buttonId:t})}async function Xt(e,t){await te(e,"dismissed",{visibleSeconds:Math.max(0,Math.min(Nt,Math.round(t)))})}function zt(e){const t=g[e.messageId];t!=null&&t.expiredReported||(g={...g,[e.messageId]:{shown:(t==null?void 0:t.shown)??0,lastShownAtMs:(t==null?void 0:t.lastShownAtMs)??0,lastSeenInBundleAtMs:(t==null?void 0:t.lastSeenInBundleAtMs)??Date.now(),expiredReported:!0}},u(o.inAppState,g),te(e,"expired",{}))}async function te(e,t,n){const i={messageId:e.messageId,campaignId:e.campaignId,eventType:t,timestamp:new Date().toISOString(),variantKey:e.variantKey};n.buttonId&&(i.buttonId=n.buttonId),n.visibleSeconds!==void 0&&(i.visibleSeconds=n.visibleSeconds),n.triggerEventName&&(i.triggerEventName=n.triggerEventName),await ve(v.inAppBeacons,JSON.stringify(i)),await ct(v.inAppBeacons,_t),ne()}async function ne(){const e=await Oe();if(!e)return;const t=await oe(v.inAppBeacons);if(t.length===0)return;const n=`/api/v1/orgs/${encodeURIComponent(e.clientKey)}/in-app/events`;for(let i=0;i<t.length;i+=Ne){const r=t.slice(i,i+Ne);if((await F(e.baseUrl,n,{installationId:e.installationId,events:r.map(a=>JSON.parse(a.body))},{"X-Arsel-Device-Auth":e.deviceSecret},!0)).result===b.retryable)return;for(const a of r)a.id!==void 0&&await se(v.inAppBeacons,a.id)}}async function Ht(e,t){const n=new Set(e.messages.map(r=>r.messageId)),i={};for(const[r,s]of Object.entries(g)){const a=n.has(r)?t:s.lastSeenInBundleAtMs;t-a>It||(i[r]={...s,lastSeenInBundleAtMs:a})}g=i,await u(o.inAppState,g)}async function Be(){const e=await c(o.sessionStartedAt)??0;S.startedAt!==e&&(S={startedAt:e,counts:{}},await u(o.inAppSession,S))}function D(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function y(e){return typeof e=="string"&&e.length>0?e:void 0}function O(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function qt(e){if(typeof e!="string")return null;const t=Date.parse(e);return Number.isNaN(t)?null:t}const Yt=-1,Jt=304,Gt=2147483e3,pe=44,Ce=/^#[0-9a-fA-F]{3,8}$/,Zt=.6;let $e=null,Qt=0;function en(e,t,n){const i=e.layout==="MODAL",r=Date.now(),s=`arsel-iam-${Qt+=1}`,a=document.createElement("div");a.setAttribute("data-arsel-inapp","");const l=a.attachShadow({mode:"closed"});fn(l),a.style.setProperty("z-index",String(t.zIndex||Gt)),a.style.setProperty("isolation","isolate"),a.setAttribute("data-layout",e.layout),a.setAttribute("dir",ln());const w=document.activeElement instanceof HTMLElement?document.activeElement:null,f=document.createElement("div");f.className="panel",f.tabIndex=-1,i?(f.setAttribute("role","dialog"),f.setAttribute("aria-modal","true"),f.setAttribute("aria-labelledby",`${s}-h`),e.content.body&&f.setAttribute("aria-describedby",`${s}-b`)):(f.setAttribute("role","status"),f.setAttribute("aria-live","polite"));const I=un(e);I.background&&f.style.setProperty("background",I.background),I.text&&f.style.setProperty("color",I.text);let q=!1;const _=p=>{var A,st;q||(q=!0,document.removeEventListener("keydown",C,!0),a.remove(),w!=null&&w.isConnected?w.focus():i&&((st=(A=document.body).focus)==null||st.call(A)),p==="dismiss"&&n.onDismiss((Date.now()-r)/1e3))},C=p=>{p.key==="Escape"&&(p.stopPropagation(),_("dismiss"))};if(e.layout==="IMAGE_ONLY"&&e.content.imageUrl)f.append(nn(e,()=>Un(e)));else{e.content.imageUrl&&f.append(tn(e.content.imageUrl,e.content.headline));const p=document.createElement("h2");if(p.id=`${s}-h`,p.className="headline",p.textContent=e.content.headline,f.append(p),e.content.body){const A=document.createElement("p");A.id=`${s}-b`,A.className="body",A.textContent=e.content.body,f.append(A)}}if(e.buttons.length>0&&f.append(rn(e,n,_)),(e.content.showCloseButton||!e.buttons.some(p=>p.action==="DISMISS"))&&f.append(an(t.closeLabel,()=>_("dismiss"))),i){const p=document.createElement("div");p.className="backdrop",e.content.showCloseButton&&p.addEventListener("click",()=>_("dismiss")),l.append(p)}l.append(f),document.body.append(a),i?(f.focus({preventScroll:!0}),l.addEventListener("keydown",p=>{p instanceof KeyboardEvent&&cn(p,l)})):(f.textContent,f.setAttribute("aria-busy","true"),requestAnimationFrame(()=>{f.removeAttribute("aria-busy")})),document.addEventListener("keydown",C,!0),requestAnimationFrame(()=>{q||!a.isConnected||document.visibilityState==="visible"&&n.onImpression()});function Un(p){const A=p.buttons[0];if(!A){_("dismiss");return}n.onButton(A),_("button")}return{close:_,root:l}}function tn(e,t){const n=document.createElement("figure");n.className="figure";const i=document.createElement("img");return i.src=e,i.alt=t,i.loading="eager",i.decoding="async",i.referrerPolicy="no-referrer",i.addEventListener("error",()=>n.remove()),n.append(i),n}function nn(e,t){const n=document.createElement("button");n.type="button",n.className="image-only";const i=document.createElement("img");return i.src=e.content.imageUrl??"",i.alt=e.content.headline,i.loading="eager",i.decoding="async",i.referrerPolicy="no-referrer",n.append(i),n.addEventListener("click",t),n}function rn(e,t,n){const i=document.createElement("div");i.className="buttons";for(const r of e.buttons){const s=r.action==="URL"&&r.value?on(r):sn(r);s.addEventListener("click",()=>{r.action!=="DISMISS"&&t.onButton(r),n(r.action==="DISMISS"?"dismiss":"button"),r.action==="DEEP_LINK"&&r.value&&location.assign(r.value)}),i.append(s)}return i}function on(e){const t=document.createElement("a");return t.href=e.value??"#",t.target="_blank",t.rel="noopener noreferrer",t.className=`cta ${e.style.toLowerCase()}`,t.textContent=e.label,t}function sn(e){const t=document.createElement("button");return t.type="button",t.className=`cta ${e.style.toLowerCase()}`,t.textContent=e.label,t}function an(e,t){const n=document.createElement("button");return n.type="button",n.className="close",n.setAttribute("aria-label",e),n.textContent="×",n.addEventListener("click",t),n}function cn(e,t){if(e.key!=="Tab")return;const n=[...t.querySelectorAll("button, a[href]")].filter(a=>!a.hasAttribute("disabled"));if(n.length===0)return;const i=n[0],r=n[n.length-1];if(!i||!r)return;const s=t.activeElement;if(e.shiftKey&&s===i){e.preventDefault(),r.focus();return}!e.shiftKey&&s===r&&(e.preventDefault(),i.focus())}function ln(){const e=document.documentElement.getAttribute("dir");if(e)return e;try{return getComputedStyle(document.documentElement).direction||"ltr"}catch{return"ltr"}}function un(e){const t=Ce.test(e.content.backgroundColor??"")?e.content.backgroundColor:void 0,n=Ce.test(e.content.textColor??"")?e.content.textColor:void 0;return t&&!n?{background:t,text:dn(t)>Zt?"#101010":"#FFFFFF"}:{background:t,text:n}}function dn(e){const t=e.slice(1),n=t.length===3?t.split("").map(a=>a+a).join(""):t.slice(0,6),i=parseInt(n.slice(0,2),16)/255,r=parseInt(n.slice(2,4),16)/255,s=parseInt(n.slice(4,6),16)/255;return .2126*i+.7152*r+.0722*s}function fn(e){if("adoptedStyleSheets"in Document.prototype&&typeof CSSStyleSheet=="function")try{$e??($e=pn()),e.adoptedStyleSheets=[$e];return}catch{}const t=document.createElement("style");t.textContent=Ke,e.append(t)}function pn(){const e=new CSSStyleSheet;return e.replaceSync(Ke),e}const Ke=`
1
+ (function(m,K){typeof exports=="object"&&typeof module<"u"?K(exports):typeof define=="function"&&define.amd?define(["exports"],K):(m=typeof globalThis<"u"?globalThis:m||self,K(m.Arsel={}))})(this,(function(m){"use strict";const K="arsel",v={events:"events",inAppBeacons:"inapp_beacons"};let Y=null;function at(){return Y||(Y=new Promise((e,t)=>{const n=indexedDB.open(K,2);n.onupgradeneeded=()=>{const i=n.result;i.objectStoreNames.contains("kv")||i.createObjectStore("kv");for(const r of Object.values(v))i.objectStoreNames.contains(r)||i.createObjectStore(r,{keyPath:"id",autoIncrement:!0})},n.onsuccess=()=>e(n.result),n.onerror=()=>t(n.error)}),Y)}function N(e,t,n){return at().then(i=>new Promise((r,s)=>{const a=n(i.transaction(e,t).objectStore(e));a.onsuccess=()=>r(a.result),a.onerror=()=>s(a.error)}))}function c(e){return N("kv","readonly",t=>t.get(e)).then(t=>t??null)}function u(e,t){return N("kv","readwrite",n=>n.put(t,e))}function L(e){return N("kv","readwrite",t=>t.delete(e))}function ve(e,t,n=""){return N(e,"readwrite",i=>i.add({body:t,idempotencyKey:n,createdAtMs:Date.now()}))}function oe(e){return N(e,"readonly",t=>t.getAll())}function se(e,t){return N(e,"readwrite",n=>n.delete(t))}function Se(e){return N(e,"readonly",t=>t.count())}async function ct(e,t){const n=await oe(e);if(!(n.length<=t))for(const i of n.slice(0,n.length-t))i.id!==void 0&&await se(e,i.id)}const o={clientKey:"client_key",baseUrl:"base_url",anonymousId:"anonymous_id",externalId:"external_id",email:"email",phoneNumber:"phone_number",installationId:"installation_id",deviceSecret:"device_secret",vapidKeyVersion:"vapid_key_version",endpoint:"endpoint",subscriptionStatus:"subscription_status",installReported:"install_reported",sessionStartedAt:"session_started_at",backgroundedAt:"backgrounded_at",lastResponseCode:"last_response_code",lastResponsePath:"last_response_path",lastResponseAtMs:"last_response_at",inAppBundle:"inapp_bundle",inAppState:"inapp_state",inAppSession:"inapp_session"};async function V(){const e=await c(o.anonymousId);if(e)return e;const t=crypto.randomUUID();return await u(o.anonymousId,t),t}async function lt(){const e=crypto.randomUUID();return await u(o.anonymousId,e),e}const D="1.2.0",Ae={"X-Arsel-SDK":`web/${D}`},b={success:"success",retryable:"retryable",permanent:"permanent",reauth:"reauth"},J=-1;function Ee(e,t){return e>=200&&e<=299?b.success:e===408||e===429||e>=500&&e<=599?b.retryable:t&&(e===401||e===403||e===404)?b.reauth:e===404?b.retryable:b.permanent}async function G(e,t){try{await Promise.all([u(o.lastResponseCode,t),u(o.lastResponsePath,e),u(o.lastResponseAtMs,Date.now())])}catch{}}async function F(e,t,n,i={},r=!1){let s;try{s=await fetch(e+t,{method:"POST",headers:{"Content-Type":"application/json",...Ae,...i},body:JSON.stringify(n),credentials:"omit",keepalive:!0})}catch{return await G(t,J),{result:b.retryable,code:J,body:null}}await G(t,s.status);const a=Ee(s.status,r);let l=null;try{l=await s.json()}catch{}return{result:a,code:s.status,body:l}}async function ae(e,t,n={},i=!1,r={}){let s;try{s=await fetch(e+t,{...r,credentials:"omit",headers:{...Ae,...n}})}catch{return await G(t,J),{result:b.retryable,code:J,body:null}}await G(t,s.status);let a=null;try{a=await s.json()}catch{}return{result:Ee(s.status,i),code:s.status,body:a}}const ut="/v1/events/send",k="arsel.",dt=`${k}session_start`,ft=`${k}session_end`,pt=`${k}identify`,mt=`${k}app_installed`,yt=`${k}screen_view`,bt=80,ht=128,gt=255,Ie=50,wt=8,_e=64*1024;function ce(e,t){if(e===null)return null;const n=typeof e;if(n==="string"||n==="boolean")return e;if(n==="number")return Number.isFinite(e)?e:String(e);if(n==="bigint")return String(e);if(e instanceof Date)return Number.isNaN(e.getTime())?void 0:e.toISOString();if(n!=="object"||t>=wt)return;if(Array.isArray(e))return e.map(r=>ce(r,t+1)??null);const i={};for(const[r,s]of Object.entries(e)){if(!r)continue;const a=ce(s,t+1);a!==void 0&&(i[r]=a)}return i}function vt(e){const t={};let n=2,i=!1;for(const[r,s]of Object.entries(e??{})){if(!r)continue;const a=ce(s,0);if(a===void 0)continue;const l=r.length+JSON.stringify(a).length+6;if(n+l>_e){i=!0;continue}n+=l,t[r]=a}return i&&console.warn(`[arsel] event data exceeded ${_e} serialized bytes — oversized properties were dropped`),t}async function St(e,t,n){const[i,r,s,a]=await Promise.all([V(),c(o.externalId),c(o.email),c(o.phoneNumber)]),l={event:e.slice(0,bt),anonymous_id:i.slice(0,ht),data:vt(t),timestamp:new Date(n).toISOString()};return r&&(l.external_id=r.slice(0,gt)),s&&(l.email=s),a&&(l.phone_number=a),JSON.stringify(l)}async function x(e,t,n=Date.now()){await ve(v.events,await St(e,t,n),crypto.randomUUID()),W().catch(()=>{})}let j=null;function W(){return j||(j=It().finally(()=>{j=null}),j)}function At(e){const t=e[0].idempotencyKey;return e.length===1?t:`${t}:${e[e.length-1].idempotencyKey}:${e.length}`}function Et(e,t,n){e.some(r=>r.external_id||r.email||r.phone_number)&&console.error(`[arsel] ${e.length} event(s) carrying identifiers were rejected permanently (HTTP ${t}) and dropped. Response: ${JSON.stringify(n)}`)}async function It(){const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!(!e||!t))for(;;){const n=await oe(v.events);if(n.length===0)return;for(let i=0;i<n.length;i+=Ie){const r=n.slice(i,i+Ie),s=r.map(l=>JSON.parse(l.body)),a=await F(t,ut,r.length===1?s[0]:{events:s},{Authorization:`Bearer ${e}`,"Idempotency-Key":At(r)});if(a.result===b.retryable)return;a.result!==b.success&&Et(s,a.code,a.body);for(const l of r)l.id!==void 0&&await se(v.events,l.id)}}}const Z=1e3,_t=720*60*60*Z,Nt=500,Ne=50,kt=86400,xt=900,Q={maxPerSession:1,maxLifetime:3,minSecondsBetween:86400,delaySeconds:0},Pt=["MODAL","BANNER_TOP","BANNER_BOTTOM","IMAGE_ONLY"];let le=!1,d=null,g={},S={startedAt:0,counts:{}},X=null,z=null,ke=!1,ue=null,P=null,xe=!1,Pe=!1;function T(e){xe&&console.info(`[arsel] in-app: ${e}`)}async function Tt(e){le=!0,xe=e;const[t,n,i]=await Promise.all([c(o.inAppBundle),c(o.inAppState),c(o.inAppSession)]);d=t,g=n??{},S=i??{startedAt:0,counts:{}},await Ue(),await ee()}function Dt(e){P=e}function Ot(e){ke=e,e&&fe()}function Mt(){return{messages:(d==null?void 0:d.messages.length)??0,bundleVersion:(d==null?void 0:d.bundleVersion)??null,fetchedAtMs:(d==null?void 0:d.fetchedAtMs)??null}}function Rt(){return Se(v.inAppBeacons)}async function Te(){d=null,await L(o.inAppBundle),le&&await ee(!0)}function Bt(){ee(!0)}function ee(e=!1){return ue??(ue=Ut(e).finally(()=>{ue=null})),ue}async function Ut(e){if(!le)return;const t=Date.now();if(!e&&d&&t-d.fetchedAtMs<d.ttlSeconds*Z)return;const n=await Oe();if(!n)return;const i=Ct(n.clientKey,n.installationId),r={"X-Arsel-Device-Auth":n.deviceSecret},s=!!(d!=null&&d.bundleVersion);s&&(r["If-None-Match"]=`"${(d==null?void 0:d.bundleVersion)??""}"`);let a=await De(n.baseUrl,i,r);if(a.code===Jt&&s&&Pe&&(T("conditional request failed; retrying without If-None-Match"),delete r["If-None-Match"],a=await De(n.baseUrl,i,r)),a.code===Gt){d&&(d={...d,fetchedAtMs:t},await u(o.inAppBundle,d));return}if(a.result!==b.success||!a.body)return;s||(Pe=!0);const l=$t(a.body,t);l&&(d=l,await u(o.inAppBundle,d),await qt(l,t))}function De(e,t,n){return ae(e,t,n,!0,{cache:"no-store"})}function Ct(e,t){const n=encodeURIComponent(e),i=encodeURIComponent(t);return`/api/v1/orgs/${n}/in-app/bundle?installationId=${i}`}async function Oe(){const[e,t,n,i]=await Promise.all([c(o.clientKey),c(o.baseUrl),c(o.installationId),c(o.deviceSecret)]);return!e||!t||!n||!i?null:{clientKey:e,baseUrl:t,installationId:n,deviceSecret:i}}function $t(e,t){if(typeof(e==null?void 0:e.bundleVersion)!="string")return T("response carried no bundleVersion"),null;e.contractVersion!==void 0&&e.contractVersion!==1&&T(`unknown contractVersion ${String(e.contractVersion)}; proceeding`);const n=Array.isArray(e.messages)?e.messages:[],i=[];for(const s of n){const a=Kt(s);a&&i.push(a)}n.length!==i.length&&T(`dropped ${n.length-i.length} unrenderable message(s)`);const r=M(e.ttlSeconds);return{bundleVersion:e.bundleVersion,ttlSeconds:r&&r>0?r:xt,fetchedAtMs:t,messages:i}}function Kt(e){if(!O(e))return null;const t=y(e.campaignId),n=y(e.messageId),i=y(e.layout),r=O(e.content)?e.content:null,s=r?y(r.headline):void 0;if(!t||!n||!i||!r||!s)return T("message missing a required field"),null;if(!Pt.includes(i))return T(`layout ${i} is not renderable on web`),null;const a=O(e.trigger)?e.trigger:{},l=O(e.displayRules)?e.displayRules:{};return{campaignId:t,messageId:n,variantKey:y(e.variantKey)??"default",priority:M(e.priority)??0,expiresAtMs:Yt(e.expiresAt),triggerType:y(a.type)??"APP_OPEN",triggerEventName:y(a.eventName)??null,triggerProperties:O(a.properties)?a.properties:null,displayRules:{maxPerSession:M(l.maxPerSession)??Q.maxPerSession,maxLifetime:M(l.maxLifetime)??Q.maxLifetime,minSecondsBetween:M(l.minSecondsBetween)??Q.minSecondsBetween,delaySeconds:M(l.delaySeconds)??Q.delaySeconds},layout:i,content:{headline:s,body:y(r.body)??"",imageUrl:y(r.imageUrl),backgroundColor:y(r.backgroundColor),textColor:y(r.textColor),showCloseButton:r.showCloseButton!==!1},buttons:Array.isArray(e.buttons)?e.buttons.map(Lt).filter(w=>w!==null):[]}}function Lt(e){if(!O(e))return null;const t=y(e.buttonId),n=y(e.label),i=y(e.action);return!t||!n||!i?null:{buttonId:t,label:n,action:i,value:y(e.value),style:y(e.style)==="SECONDARY"?"SECONDARY":"PRIMARY"}}function Vt(e,t,n,i){if(ke||X!==null||!d)return null;for(const r of d.messages){if(r.triggerType!==t||t!=="APP_OPEN"&&r.triggerEventName!==n||!Ft(r.triggerProperties,i))continue;const s=g[r.messageId];if(r.expiresAtMs!==null&&r.expiresAtMs<=e){Ht(r);continue}if(!(((s==null?void 0:s.shown)??0)>=r.displayRules.maxLifetime)&&!((S.counts[r.messageId]??0)>=r.displayRules.maxPerSession)&&!(s&&e-s.lastShownAtMs<r.displayRules.minSecondsBetween*Z))return r}return null}function Ft(e,t){if(!e)return!0;const n=t;for(const[i,r]of Object.entries(e))if(String(n[i])!==String(r))return!1;return!0}function de(e,t,n={}){try{const i=Vt(Date.now(),e,t,n);if(!i)return;X=i.messageId,Me=t;const r=i.displayRules.delaySeconds*Z;if(r<=0){P==null||P(i);return}z=setTimeout(()=>{z=null,P==null||P(i)},r)}catch(i){T(`observe failed: ${i instanceof Error?i.message:"unknown"}`),X=null}}let Me=null;function jt(){return Me}function Re(){Ue().then(()=>{de("APP_OPEN",null,{})})}function fe(){z!==null&&(clearTimeout(z),z=null,X=null)}function Be(){X=null}async function Wt(e,t){const n=Date.now(),i=g[e.messageId]??{shown:0,lastShownAtMs:0,lastSeenInBundleAtMs:n};g={...g,[e.messageId]:{...i,shown:i.shown+1,lastShownAtMs:n}},S={...S,counts:{...S.counts,[e.messageId]:(S.counts[e.messageId]??0)+1}},await Promise.all([u(o.inAppState,g),u(o.inAppSession,S)]),await te(e,"impression",{triggerEventName:t})}async function Xt(e,t){await te(e,"clicked",{buttonId:t})}async function zt(e,t){await te(e,"dismissed",{visibleSeconds:Math.max(0,Math.min(kt,Math.round(t)))})}function Ht(e){const t=g[e.messageId];t!=null&&t.expiredReported||(g={...g,[e.messageId]:{shown:(t==null?void 0:t.shown)??0,lastShownAtMs:(t==null?void 0:t.lastShownAtMs)??0,lastSeenInBundleAtMs:(t==null?void 0:t.lastSeenInBundleAtMs)??Date.now(),expiredReported:!0}},u(o.inAppState,g),te(e,"expired",{}))}async function te(e,t,n){const i={messageId:e.messageId,campaignId:e.campaignId,eventType:t,timestamp:new Date().toISOString(),variantKey:e.variantKey};n.buttonId&&(i.buttonId=n.buttonId),n.visibleSeconds!==void 0&&(i.visibleSeconds=n.visibleSeconds),n.triggerEventName&&(i.triggerEventName=n.triggerEventName),await ve(v.inAppBeacons,JSON.stringify(i)),await ct(v.inAppBeacons,Nt),ne()}async function ne(){const e=await Oe();if(!e)return;const t=await oe(v.inAppBeacons);if(t.length===0)return;const n=`/api/v1/orgs/${encodeURIComponent(e.clientKey)}/in-app/events`;for(let i=0;i<t.length;i+=Ne){const r=t.slice(i,i+Ne);if((await F(e.baseUrl,n,{installationId:e.installationId,events:r.map(a=>JSON.parse(a.body))},{"X-Arsel-Device-Auth":e.deviceSecret},!0)).result===b.retryable)return;for(const a of r)a.id!==void 0&&await se(v.inAppBeacons,a.id)}}async function qt(e,t){const n=new Set(e.messages.map(r=>r.messageId)),i={};for(const[r,s]of Object.entries(g)){const a=n.has(r)?t:s.lastSeenInBundleAtMs;t-a>_t||(i[r]={...s,lastSeenInBundleAtMs:a})}g=i,await u(o.inAppState,g)}async function Ue(){const e=await c(o.sessionStartedAt)??0;S.startedAt!==e&&(S={startedAt:e,counts:{}},await u(o.inAppSession,S))}function O(e){return typeof e=="object"&&e!==null&&!Array.isArray(e)}function y(e){return typeof e=="string"&&e.length>0?e:void 0}function M(e){return typeof e=="number"&&Number.isFinite(e)?e:void 0}function Yt(e){if(typeof e!="string")return null;const t=Date.parse(e);return Number.isNaN(t)?null:t}const Jt=-1,Gt=304,Zt=2147483e3,pe=44,Ce=/^#[0-9a-fA-F]{3,8}$/,Qt=.6;let $e=null,en=0;function tn(e,t,n){const i=e.layout==="MODAL",r=Date.now(),s=`arsel-iam-${en+=1}`,a=document.createElement("div");a.setAttribute("data-arsel-inapp","");const l=a.attachShadow({mode:"closed"});pn(l),a.style.setProperty("z-index",String(t.zIndex||Zt)),a.style.setProperty("isolation","isolate"),a.setAttribute("data-layout",e.layout),a.setAttribute("dir",un());const w=document.activeElement instanceof HTMLElement?document.activeElement:null,f=document.createElement("div");f.className="panel",f.tabIndex=-1,i?(f.setAttribute("role","dialog"),f.setAttribute("aria-modal","true"),f.setAttribute("aria-labelledby",`${s}-h`),e.content.body&&f.setAttribute("aria-describedby",`${s}-b`)):(f.setAttribute("role","status"),f.setAttribute("aria-live","polite"));const I=dn(e);I.background&&f.style.setProperty("background",I.background),I.text&&f.style.setProperty("color",I.text);let q=!1;const _=p=>{var A,st;q||(q=!0,document.removeEventListener("keydown",$,!0),a.remove(),w!=null&&w.isConnected?w.focus():i&&((st=(A=document.body).focus)==null||st.call(A)),p==="dismiss"&&n.onDismiss((Date.now()-r)/1e3))},$=p=>{p.key==="Escape"&&(p.stopPropagation(),_("dismiss"))};if(e.layout==="IMAGE_ONLY"&&e.content.imageUrl)f.append(rn(e,()=>$n(e)));else{e.content.imageUrl&&f.append(nn(e.content.imageUrl,e.content.headline));const p=document.createElement("h2");if(p.id=`${s}-h`,p.className="headline",p.textContent=e.content.headline,f.append(p),e.content.body){const A=document.createElement("p");A.id=`${s}-b`,A.className="body",A.textContent=e.content.body,f.append(A)}}if(e.buttons.length>0&&f.append(on(e,n,_)),(e.content.showCloseButton||!e.buttons.some(p=>p.action==="DISMISS"))&&f.append(cn(t.closeLabel,()=>_("dismiss"))),i){const p=document.createElement("div");p.className="backdrop",e.content.showCloseButton&&p.addEventListener("click",()=>_("dismiss")),l.append(p)}l.append(f),document.body.append(a),i?(f.focus({preventScroll:!0}),l.addEventListener("keydown",p=>{p instanceof KeyboardEvent&&ln(p,l)})):(f.textContent,f.setAttribute("aria-busy","true"),requestAnimationFrame(()=>{f.removeAttribute("aria-busy")})),document.addEventListener("keydown",$,!0),requestAnimationFrame(()=>{q||!a.isConnected||document.visibilityState==="visible"&&n.onImpression()});function $n(p){const A=p.buttons[0];if(!A){_("dismiss");return}n.onButton(A),_("button")}return{close:_,root:l}}function nn(e,t){const n=document.createElement("figure");n.className="figure";const i=document.createElement("img");return i.src=e,i.alt=t,i.loading="eager",i.decoding="async",i.referrerPolicy="no-referrer",i.addEventListener("error",()=>n.remove()),n.append(i),n}function rn(e,t){const n=document.createElement("button");n.type="button",n.className="image-only";const i=document.createElement("img");return i.src=e.content.imageUrl??"",i.alt=e.content.headline,i.loading="eager",i.decoding="async",i.referrerPolicy="no-referrer",n.append(i),n.addEventListener("click",t),n}function on(e,t,n){const i=document.createElement("div");i.className="buttons";for(const r of e.buttons){const s=r.action==="URL"&&r.value?sn(r):an(r);s.addEventListener("click",()=>{r.action!=="DISMISS"&&t.onButton(r),n(r.action==="DISMISS"?"dismiss":"button"),r.action==="DEEP_LINK"&&r.value&&location.assign(r.value)}),i.append(s)}return i}function sn(e){const t=document.createElement("a");return t.href=e.value??"#",t.target="_blank",t.rel="noopener noreferrer",t.className=`cta ${e.style.toLowerCase()}`,t.textContent=e.label,t}function an(e){const t=document.createElement("button");return t.type="button",t.className=`cta ${e.style.toLowerCase()}`,t.textContent=e.label,t}function cn(e,t){const n=document.createElement("button");return n.type="button",n.className="close",n.setAttribute("aria-label",e),n.textContent="×",n.addEventListener("click",t),n}function ln(e,t){if(e.key!=="Tab")return;const n=[...t.querySelectorAll("button, a[href]")].filter(a=>!a.hasAttribute("disabled"));if(n.length===0)return;const i=n[0],r=n[n.length-1];if(!i||!r)return;const s=t.activeElement;if(e.shiftKey&&s===i){e.preventDefault(),r.focus();return}!e.shiftKey&&s===r&&(e.preventDefault(),i.focus())}function un(){const e=document.documentElement.getAttribute("dir");if(e)return e;try{return getComputedStyle(document.documentElement).direction||"ltr"}catch{return"ltr"}}function dn(e){const t=Ce.test(e.content.backgroundColor??"")?e.content.backgroundColor:void 0,n=Ce.test(e.content.textColor??"")?e.content.textColor:void 0;return t&&!n?{background:t,text:fn(t)>Qt?"#101010":"#FFFFFF"}:{background:t,text:n}}function fn(e){const t=e.slice(1),n=t.length===3?t.split("").map(a=>a+a).join(""):t.slice(0,6),i=parseInt(n.slice(0,2),16)/255,r=parseInt(n.slice(2,4),16)/255,s=parseInt(n.slice(4,6),16)/255;return .2126*i+.7152*r+.0722*s}function pn(e){if("adoptedStyleSheets"in Document.prototype&&typeof CSSStyleSheet=="function")try{$e??($e=mn()),e.adoptedStyleSheets=[$e];return}catch{}const t=document.createElement("style");t.textContent=Ke,e.append(t)}function mn(){const e=new CSSStyleSheet;return e.replaceSync(Ke),e}const Ke=`
2
2
  :host {
3
3
  all: initial;
4
4
  display: block;
@@ -104,5 +104,5 @@
104
104
  @media (prefers-reduced-motion: reduce) {
105
105
  .panel { animation: none; transition: none; }
106
106
  }
107
- `,me="REVOKED";function mn(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=atob(t+"=".repeat((4-t.length%4)%4)),i=new Uint8Array(n.length);for(let r=0;r<n.length;r+=1)i[r]=n.charCodeAt(r);return i.buffer}function M(){return typeof navigator<"u"&&"serviceWorker"in navigator&&typeof PushManager<"u"&&typeof Notification<"u"}function Le(e){return`/api/v1/orgs/${e}/push/web/config`}function ye(e){return`/api/v1/orgs/${e}/push/subscriptions`}const Ve=1e4;let R="none",H=null,ie=null;function yn(){R="external"}async function bn(e){if(M()){R="managed";try{H=await navigator.serviceWorker.register(e),ie=null}catch(t){H=null,ie=`service worker registration failed for '${e}': ${String(t)}. Check that the file is deployed and served with a JavaScript content type.`}}}function hn(e,t){return e.active?Promise.resolve(e):new Promise((n,i)=>{const r=setTimeout(()=>{i(new Error(`service worker did not activate within ${t}ms — check the worker script for load errors in DevTools → Application → Service Workers`))},t),s=l=>{l.addEventListener("statechange",()=>{l.state==="activated"?(clearTimeout(r),n(e)):l.state==="redundant"&&(clearTimeout(r),i(new Error("service worker became redundant before activating — its script likely failed to parse")))})},a=e.installing??e.waiting;a?s(a):e.addEventListener("updatefound",()=>{e.installing&&s(e.installing)})})}function gn(e,t,n){return Promise.race([e,new Promise((i,r)=>{setTimeout(()=>r(new Error(n)),t)})])}async function be(e=Ve){if(R==="none")throw new Error("push is not configured — pass serviceWorkerPath to init(), or serviceWorker: 'external' if your own service worker imports arsel-sw.js");if(R==="external")return gn(navigator.serviceWorker.ready,e,`no service worker became active within ${e}ms — with serviceWorker: 'external', your own worker must be registered and must importScripts arsel-sw.js`);if(ie)throw new Error(ie);if(!H)throw new Error("service worker registration has not completed");return hn(H,e)}async function wn(e=Ve){try{return await be(e),null}catch(t){return t instanceof Error?t.message:String(t)}}async function Fe(e,t){try{return await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:mn(t)})}catch(n){return console.error(`[arsel] push subscribe failed: ${n instanceof Error?n.message:n}`),null}}async function vn(){const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!e||!t||!M())return!1;const{body:n}=await ae(t,Le(e));if(!(n!=null&&n.vapidPublicKey))return!1;let i;try{i=await be()}catch(s){return console.error(`[arsel] ${s instanceof Error?s.message:s}`),!1}const r=await Fe(i,n.vapidPublicKey);return r?je(r,n.keyVersion):!1}async function je(e,t){var f,I;const[n,i,r]=await Promise.all([c(o.clientKey),c(o.baseUrl),L()]);if(!n||!i)return!1;let s=await c(o.installationId);s||(s=crypto.randomUUID(),await u(o.installationId,s));const a=e.toJSON(),l=await F(i,ye(n),{installationId:s,platform:"web",endpoint:a.endpoint,keys:a.keys,anonymousId:r,enablementStatus:Notification.permission==="granted"?"AUTHORIZED":"DENIED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});if(l.result!==b.success)return!1;(f=l.body)!=null&&f.deviceSecret&&await u(o.deviceSecret,l.body.deviceSecret),await u(o.vapidKeyVersion,t),await u(o.endpoint,a.endpoint??null);const w=((I=l.body)==null?void 0:I.status)??null;return await u(o.subscriptionStatus,w),w!==me}async function Sn(){const[e,t,n,i]=await Promise.all([c(o.clientKey),c(o.baseUrl),c(o.installationId),c(o.deviceSecret)]);return!e||!t||!n||!i||(await F(t,`${ye(e)}/unsubscribe`,{installationId:n},{"X-Arsel-Device-Auth":i},!0)).result!==b.success?!1:(await u(o.subscriptionStatus,me),!0)}async function An(){if(R==="none"||!M()||Notification.permission!=="granted")return;const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!e||!t)return;const{body:n}=await ae(t,Le(e));if(!(n!=null&&n.vapidPublicKey))return;let i;try{i=await be()}catch{return}const r=await i.pushManager.getSubscription(),s=await c(o.vapidKeyVersion);if(r&&s===n.keyVersion)return;r&&await r.unsubscribe().catch(()=>!1);const a=await Fe(i,n.vapidPublicKey);a&&await je(a,n.keyVersion)}async function En(){if(!M()||await c(o.subscriptionStatus)===me)return!1;try{const e=R==="managed"?H:await navigator.serviceWorker.getRegistration();return e?await e.pushManager.getSubscription()!==null:!1}catch{return!1}}function In(){return he??(he=_n().finally(()=>{he=null})),he}let he=null;async function _n(){var s;const[e,t,n]=await Promise.all([c(o.clientKey),c(o.baseUrl),L()]);if(!e||!t)return!1;if(await c(o.deviceSecret))return!0;let i=await c(o.installationId);i||(i=crypto.randomUUID(),await u(o.installationId,i));const r=await F(t,ye(e),{installationId:i,platform:"web",anonymousId:n,enablementStatus:"NOT_DETERMINED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});return r.code===403?(console.error("[arsel] this origin is not on the organization's allowed origins list — in-app messaging is disabled"),!1):r.result!==b.success?!1:((s=r.body)!=null&&s.deviceSecret&&await u(o.deviceSecret,r.body.deviceSecret),!0)}const Nn=30*6e4;async function We(e=Date.now()){const t=await c(o.sessionStartedAt)??0,n=await c(o.backgroundedAt)??0;if(t!==0){if(n===0||e-n<Nn)return;await P(ft,{duration_seconds:Math.round((n-t)/1e3)},n)}await u(o.sessionStartedAt,e),await u(o.backgroundedAt,0),await P(dt,{},e)}async function Xe(e=Date.now()){(await c(o.sessionStartedAt)??0)!==0&&await u(o.backgroundedAt,e)}function xn(e){typeof document>"u"||(document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?We().then(()=>e==null?void 0:e()):Xe()}),window.addEventListener("pagehide",()=>void Xe()))}let h=null,ge=!1,U=null;function E(e){ge&&console.info(`[arsel] ${e}`)}const kn=/^\+[1-9]\d{6,14}$/,Tn=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,ze=100;let re=[],He=!1;function Pn(){typeof navigator<"u"&&navigator.serviceWorker&&navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;(t==null?void 0:t.type)==="arsel_iam_sync"&&Rt()}),typeof window<"u"&&(window.addEventListener("online",()=>{W().catch(()=>{}),ne().catch(()=>{})}),window.addEventListener("pagehide",()=>{fe(),ne().catch(()=>{})})),typeof document<"u"&&document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"){W().catch(()=>{}),ee().catch(()=>{});return}fe(),ne().catch(()=>{})})}function B(){return U===null}function Dn(e){var n,i;if(!((n=e.clientKey)!=null&&n.trim()))return"clientKey is required (the org's publishable pub_… key)";if(!e.clientKey.startsWith("pub_"))return"clientKey should be the publishable pub_… key — never a secret API key";const t=/^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/.test(e.baseUrl??"");if(!((i=e.baseUrl)!=null&&i.startsWith("https://"))&&!t)return"baseUrl must be HTTPS (http is allowed for localhost only)";try{new URL(e.baseUrl)}catch{return"baseUrl is not a valid URL"}return null}function qe(e){return h||(h=(async()=>{if(ge=e.debug??!1,U=Dn(e),U){console.error(`[arsel] not started — ${U}`);return}const t=e.baseUrl.replace(/\/+$/,"");await Promise.all([u(o.clientKey,e.clientKey),u(o.baseUrl,t)]),await L();const n=re;re=[];for(const a of n)await P(a.name,a.properties,a.timestampMs);e.serviceWorker==="external"?yn():e.serviceWorkerPath&&await bn(e.serviceWorkerPath);const i=On(e.inApp);xn(i?Re:void 0),Pn();const r=typeof document<"u"?document:void 0,s=(r==null?void 0:r.visibilityState)==="visible"&&r.prerendering!==!0;s&&await We(),i&&(Pt(Mn(i)),await In()&&(await Tt(ge),s&&Re())),W().catch(()=>{}),An().catch(()=>{}),E(`initialized (sdk ${V})`)})(),h)}async function we(e,t={}){const n=e==null?void 0:e.trim();if(!n){E("track() called with a blank event name — ignoring");return}if(n.startsWith(T)){E(`'${T}' is reserved for the SDK — ignoring '${n}'`);return}if(!h){if(re.length>=ze){He||(He=!0,console.warn(`[arsel] more than ${ze} events tracked before init() — dropping the rest. Call init() earlier.`));return}re.push({name:n,properties:t,timestampMs:Date.now()});return}await h,B()&&(await P(n,t),de("CUSTOM_EVENT",n,t))}async function Ye(e,t={}){const n=e==null?void 0:e.trim();if(!n){E("screen() called with a blank name — ignoring");return}await h,await P(mt,{...t,screen_name:n}),de("SCREEN_VIEW",n,t)}function Je(e){Dt(e)}async function Ge(e){if(await h,!B())return;let{email:t,phoneNumber:n}=e??{};const i=e==null?void 0:e.externalId;if(t&&!Tn.test(t)&&(console.error(`[arsel] identify(): '${t}' is not a valid email address — ignored`),t=void 0),n&&!kn.test(n)&&(console.error(`[arsel] identify(): '${n}' is not E.164 (e.g. +966501234567) — ignored`),n=void 0),!i&&!t&&!n){E("identify() needs at least one of externalId, email or phoneNumber");return}i&&await u(o.externalId,i),t&&await u(o.email,t),n&&await u(o.phoneNumber,n),await P(pt,{}),await Pe()}async function Ze(){await h,B()&&(await Promise.all([K(o.externalId),K(o.email),K(o.phoneNumber),K(o.sessionStartedAt)]),await lt(),await Pe(),E("identity reset"))}async function Qe(){if(await h,!B())return!1;const e=await Sn();return E(e?"push opt-out recorded":"push opt-out not sent — no registration to revoke"),e}async function et(){if(await h,!B()||!M())return!1;const e=await wn();if(e)return console.error(`[arsel] promptForPush(): ${e}`),!1;const t=await Notification.requestPermission();return t!=="granted"?(E(`notification permission: ${t}`),!1):vn()}async function tt(){return await h,L()}async function nt(){const[e,t,n,i,r,s,a,l,w,f,I,q,_]=await Promise.all([c(o.anonymousId),c(o.externalId),c(o.email),c(o.phoneNumber),c(o.installationId),c(o.deviceSecret),c(o.vapidKeyVersion),Se(v.events),En(),c(o.subscriptionStatus),c(o.lastResponseCode),c(o.lastResponsePath),c(o.lastResponseAtMs)]),C=Ot(),ot=await Mt().catch(()=>0);return{sdkVersion:V,initialized:h!==null&&U===null,configError:U,inAppMessages:C.messages,inAppBundleVersion:C.bundleVersion,inAppFetchedAtMs:C.fetchedAtMs,pendingInAppBeacons:ot,anonymousId:e,hasAssertedIdentity:!!(t||n||i),installationId:r,hasDeviceSecret:!!s,pendingEvents:l,permission:M()?Notification.permission:"unsupported",isSubscribed:w,subscriptionStatus:f,vapidKeyVersion:a,lastResponseCode:I,lastResponsePath:q,lastResponseAtMs:_}}async function it(){await h,B()&&await W()}const rt={init:qe,track:we,screen:Ye,suppressInAppMessages:Je,identify:Ge,reset:Ze,optOut:Qe,promptForPush:et,getAnonymousId:tt,diagnostics:nt,flushNow:it,SDK_VERSION:V};function On(e){if(e===!1)return;const t=typeof e=="object"&&e!==null?e:{};return{zIndex:t.zIndex??Rn,closeLabel:t.closeLabel??"Close"}}function Mn(e){return t=>{const n=Ft();try{en(t,e,{onImpression:()=>void jt(t,n),onButton:i=>{Wt(t,i.buttonId),i.action==="CUSTOM_EVENT"&&i.value&&we(i.value)},onDismiss:i=>{Xt(t,i),Ue()}})}catch(i){E(`in-app render failed: ${i instanceof Error?i.message:""}`),Ue()}}}const Rn=2147483e3;m.Arsel=rt,m.SDK_VERSION=V,m.default=rt,m.diagnostics=nt,m.flushNow=it,m.getAnonymousId=tt,m.identify=Ge,m.init=qe,m.optOut=Qe,m.promptForPush=et,m.reset=Ze,m.screen=Ye,m.suppressInAppMessages=Je,m.track=we,Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
107
+ `;async function yn(e){await c(o.installReported)||(await u(o.installReported,!0),!e&&await x(mt,{sdk_version:D,platform:"web"}))}async function bn(){const[e,t]=await Promise.all([c(o.anonymousId),c(o.installationId)]);return!!e||!!t}const me="REVOKED";function hn(e){const t=e.replace(/-/g,"+").replace(/_/g,"/"),n=atob(t+"=".repeat((4-t.length%4)%4)),i=new Uint8Array(n.length);for(let r=0;r<n.length;r+=1)i[r]=n.charCodeAt(r);return i.buffer}function R(){return typeof navigator<"u"&&"serviceWorker"in navigator&&typeof PushManager<"u"&&typeof Notification<"u"}function Le(e){return`/api/v1/orgs/${e}/push/web/config`}function ye(e){return`/api/v1/orgs/${e}/push/subscriptions`}const Ve=1e4;let B="none",H=null,ie=null;function gn(){B="external"}async function wn(e){if(R()){B="managed";try{H=await navigator.serviceWorker.register(e),ie=null}catch(t){H=null,ie=`service worker registration failed for '${e}': ${String(t)}. Check that the file is deployed and served with a JavaScript content type.`}}}function vn(e,t){return e.active?Promise.resolve(e):new Promise((n,i)=>{const r=setTimeout(()=>{i(new Error(`service worker did not activate within ${t}ms — check the worker script for load errors in DevTools → Application → Service Workers`))},t),s=l=>{l.addEventListener("statechange",()=>{l.state==="activated"?(clearTimeout(r),n(e)):l.state==="redundant"&&(clearTimeout(r),i(new Error("service worker became redundant before activating — its script likely failed to parse")))})},a=e.installing??e.waiting;a?s(a):e.addEventListener("updatefound",()=>{e.installing&&s(e.installing)})})}function Sn(e,t,n){return Promise.race([e,new Promise((i,r)=>{setTimeout(()=>r(new Error(n)),t)})])}async function be(e=Ve){if(B==="none")throw new Error("push is not configured — pass serviceWorkerPath to init(), or serviceWorker: 'external' if your own service worker imports arsel-sw.js");if(B==="external")return Sn(navigator.serviceWorker.ready,e,`no service worker became active within ${e}ms — with serviceWorker: 'external', your own worker must be registered and must importScripts arsel-sw.js`);if(ie)throw new Error(ie);if(!H)throw new Error("service worker registration has not completed");return vn(H,e)}async function An(e=Ve){try{return await be(e),null}catch(t){return t instanceof Error?t.message:String(t)}}async function Fe(e,t){try{return await e.pushManager.subscribe({userVisibleOnly:!0,applicationServerKey:hn(t)})}catch(n){return console.error(`[arsel] push subscribe failed: ${n instanceof Error?n.message:n}`),null}}async function En(){const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!e||!t||!R())return!1;const{body:n}=await ae(t,Le(e));if(!(n!=null&&n.vapidPublicKey))return!1;let i;try{i=await be()}catch(s){return console.error(`[arsel] ${s instanceof Error?s.message:s}`),!1}const r=await Fe(i,n.vapidPublicKey);return r?je(r,n.keyVersion):!1}async function je(e,t){var f,I;const[n,i,r]=await Promise.all([c(o.clientKey),c(o.baseUrl),V()]);if(!n||!i)return!1;let s=await c(o.installationId);s||(s=crypto.randomUUID(),await u(o.installationId,s));const a=e.toJSON(),l=await F(i,ye(n),{installationId:s,platform:"web",endpoint:a.endpoint,keys:a.keys,anonymousId:r,enablementStatus:Notification.permission==="granted"?"AUTHORIZED":"DENIED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});if(l.result!==b.success)return!1;(f=l.body)!=null&&f.deviceSecret&&await u(o.deviceSecret,l.body.deviceSecret),await u(o.vapidKeyVersion,t),await u(o.endpoint,a.endpoint??null);const w=((I=l.body)==null?void 0:I.status)??null;return await u(o.subscriptionStatus,w),w!==me}async function In(){const[e,t,n,i]=await Promise.all([c(o.clientKey),c(o.baseUrl),c(o.installationId),c(o.deviceSecret)]);return!e||!t||!n||!i||(await F(t,`${ye(e)}/unsubscribe`,{installationId:n},{"X-Arsel-Device-Auth":i},!0)).result!==b.success?!1:(await u(o.subscriptionStatus,me),!0)}async function _n(){if(B==="none"||!R()||Notification.permission!=="granted")return;const[e,t]=await Promise.all([c(o.clientKey),c(o.baseUrl)]);if(!e||!t)return;const{body:n}=await ae(t,Le(e));if(!(n!=null&&n.vapidPublicKey))return;let i;try{i=await be()}catch{return}const r=await i.pushManager.getSubscription(),s=await c(o.vapidKeyVersion);if(r&&s===n.keyVersion)return;r&&await r.unsubscribe().catch(()=>!1);const a=await Fe(i,n.vapidPublicKey);a&&await je(a,n.keyVersion)}async function Nn(){if(!R()||await c(o.subscriptionStatus)===me)return!1;try{const e=B==="managed"?H:await navigator.serviceWorker.getRegistration();return e?await e.pushManager.getSubscription()!==null:!1}catch{return!1}}function kn(){return he??(he=xn().finally(()=>{he=null})),he}let he=null;async function xn(){var s;const[e,t,n]=await Promise.all([c(o.clientKey),c(o.baseUrl),V()]);if(!e||!t)return!1;if(await c(o.deviceSecret))return!0;let i=await c(o.installationId);i||(i=crypto.randomUUID(),await u(o.installationId,i));const r=await F(t,ye(e),{installationId:i,platform:"web",anonymousId:n,enablementStatus:"NOT_DETERMINED",deviceTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone,deviceLocale:navigator.language});return r.code===403?(console.error("[arsel] this origin is not on the organization's allowed origins list — in-app messaging is disabled"),!1):r.result!==b.success?!1:((s=r.body)!=null&&s.deviceSecret&&await u(o.deviceSecret,r.body.deviceSecret),!0)}const Pn=30*6e4;async function We(e=Date.now()){const t=await c(o.sessionStartedAt)??0,n=await c(o.backgroundedAt)??0;if(t!==0){if(n===0||e-n<Pn)return;await x(ft,{duration_seconds:Math.round((n-t)/1e3)},n)}await u(o.sessionStartedAt,e),await u(o.backgroundedAt,0),await x(dt,{},e)}async function Xe(e=Date.now()){(await c(o.sessionStartedAt)??0)!==0&&await u(o.backgroundedAt,e)}function Tn(e){typeof document>"u"||(document.addEventListener("visibilitychange",()=>{document.visibilityState==="visible"?We().then(()=>e==null?void 0:e()):Xe()}),window.addEventListener("pagehide",()=>void Xe()))}let h=null,ge=!1,U=null;function E(e){ge&&console.info(`[arsel] ${e}`)}const Dn=/^\+[1-9]\d{6,14}$/,On=/^[^\s@]+@[^\s@]+\.[^\s@]+$/,ze=100;let re=[],He=!1;function Mn(){typeof navigator<"u"&&navigator.serviceWorker&&navigator.serviceWorker.addEventListener("message",e=>{const t=e.data;(t==null?void 0:t.type)==="arsel_iam_sync"&&Bt()}),typeof window<"u"&&(window.addEventListener("online",()=>{W().catch(()=>{}),ne().catch(()=>{})}),window.addEventListener("pagehide",()=>{fe(),ne().catch(()=>{})})),typeof document<"u"&&document.addEventListener("visibilitychange",()=>{if(document.visibilityState==="visible"){W().catch(()=>{}),ee().catch(()=>{});return}fe(),ne().catch(()=>{})})}function C(){return U===null}function Rn(e){var n,i;if(!((n=e.clientKey)!=null&&n.trim()))return"clientKey is required (the org's publishable pub_… key)";if(!e.clientKey.startsWith("pub_"))return"clientKey should be the publishable pub_… key — never a secret API key";const t=/^http:\/\/(localhost|127\.0\.0\.1)(:\d+)?(\/|$)/.test(e.baseUrl??"");if(!((i=e.baseUrl)!=null&&i.startsWith("https://"))&&!t)return"baseUrl must be HTTPS (http is allowed for localhost only)";try{new URL(e.baseUrl)}catch{return"baseUrl is not a valid URL"}return null}function qe(e){return h||(h=(async()=>{if(ge=e.debug??!1,U=Rn(e),U){console.error(`[arsel] not started — ${U}`);return}const t=e.baseUrl.replace(/\/+$/,"");await Promise.all([u(o.clientKey,e.clientKey),u(o.baseUrl,t)]);const n=await bn();await V(),await yn(n);const i=re;re=[];for(const l of i)await x(l.name,l.properties,l.timestampMs);e.serviceWorker==="external"?gn():e.serviceWorkerPath&&await wn(e.serviceWorkerPath);const r=Bn(e.inApp);Tn(r?Re:void 0),Mn();const s=typeof document<"u"?document:void 0,a=(s==null?void 0:s.visibilityState)==="visible"&&s.prerendering!==!0;a&&await We(),r&&(Dt(Un(r)),await kn()&&(await Tt(ge),a&&Re())),W().catch(()=>{}),_n().catch(()=>{}),E(`initialized (sdk ${D})`)})(),h)}async function we(e,t={}){const n=e==null?void 0:e.trim();if(!n){E("track() called with a blank event name — ignoring");return}if(n.startsWith(k)){E(`'${k}' is reserved for the SDK — ignoring '${n}'`);return}if(!h){if(re.length>=ze){He||(He=!0,console.warn(`[arsel] more than ${ze} events tracked before init() — dropping the rest. Call init() earlier.`));return}re.push({name:n,properties:t,timestampMs:Date.now()});return}await h,C()&&(await x(n,t),de("CUSTOM_EVENT",n,t))}async function Ye(e,t={}){const n=e==null?void 0:e.trim();if(!n){E("screen() called with a blank name — ignoring");return}await h,await x(yt,{...t,screen_name:n}),de("SCREEN_VIEW",n,t)}function Je(e){Ot(e)}async function Ge(e){if(await h,!C())return;let{email:t,phoneNumber:n}=e??{};const i=e==null?void 0:e.externalId;if(t&&!On.test(t)&&(console.error(`[arsel] identify(): '${t}' is not a valid email address — ignored`),t=void 0),n&&!Dn.test(n)&&(console.error(`[arsel] identify(): '${n}' is not E.164 (e.g. +966501234567) — ignored`),n=void 0),!i&&!t&&!n){E("identify() needs at least one of externalId, email or phoneNumber");return}i&&await u(o.externalId,i),t&&await u(o.email,t),n&&await u(o.phoneNumber,n),await x(pt,{}),await Te()}async function Ze(){await h,C()&&(await Promise.all([L(o.externalId),L(o.email),L(o.phoneNumber),L(o.sessionStartedAt)]),await lt(),await Te(),E("identity reset"))}async function Qe(){if(await h,!C())return!1;const e=await In();return E(e?"push opt-out recorded":"push opt-out not sent — no registration to revoke"),e}async function et(){if(await h,!C()||!R())return!1;const e=await An();if(e)return console.error(`[arsel] promptForPush(): ${e}`),!1;const t=await Notification.requestPermission();return t!=="granted"?(E(`notification permission: ${t}`),!1):En()}async function tt(){return await h,V()}async function nt(){const[e,t,n,i,r,s,a,l,w,f,I,q,_]=await Promise.all([c(o.anonymousId),c(o.externalId),c(o.email),c(o.phoneNumber),c(o.installationId),c(o.deviceSecret),c(o.vapidKeyVersion),Se(v.events),Nn(),c(o.subscriptionStatus),c(o.lastResponseCode),c(o.lastResponsePath),c(o.lastResponseAtMs)]),$=Mt(),ot=await Rt().catch(()=>0);return{sdkVersion:D,initialized:h!==null&&U===null,configError:U,inAppMessages:$.messages,inAppBundleVersion:$.bundleVersion,inAppFetchedAtMs:$.fetchedAtMs,pendingInAppBeacons:ot,anonymousId:e,hasAssertedIdentity:!!(t||n||i),installationId:r,hasDeviceSecret:!!s,pendingEvents:l,permission:R()?Notification.permission:"unsupported",isSubscribed:w,subscriptionStatus:f,vapidKeyVersion:a,lastResponseCode:I,lastResponsePath:q,lastResponseAtMs:_}}async function it(){await h,C()&&await W()}const rt={init:qe,track:we,screen:Ye,suppressInAppMessages:Je,identify:Ge,reset:Ze,optOut:Qe,promptForPush:et,getAnonymousId:tt,diagnostics:nt,flushNow:it,SDK_VERSION:D};function Bn(e){if(e===!1)return;const t=typeof e=="object"&&e!==null?e:{};return{zIndex:t.zIndex??Cn,closeLabel:t.closeLabel??"Close"}}function Un(e){return t=>{const n=jt();try{tn(t,e,{onImpression:()=>void Wt(t,n),onButton:i=>{Xt(t,i.buttonId),i.action==="CUSTOM_EVENT"&&i.value&&we(i.value)},onDismiss:i=>{zt(t,i),Be()}})}catch(i){E(`in-app render failed: ${i instanceof Error?i.message:""}`),Be()}}}const Cn=2147483e3;m.Arsel=rt,m.SDK_VERSION=D,m.default=rt,m.diagnostics=nt,m.flushNow=it,m.getAnonymousId=tt,m.identify=Ge,m.init=qe,m.optOut=Qe,m.promptForPush=et,m.reset=Ze,m.screen=Ye,m.suppressInAppMessages=Je,m.track=we,Object.defineProperties(m,{__esModule:{value:!0},[Symbol.toStringTag]:{value:"Module"}})}));
108
108
  //# sourceMappingURL=arsel.umd.cjs.map