@thg-agentic/hyper-personalisation-web 3.24.0 → 3.25.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.
- package/README.md +46 -16
- package/dist/hp.min.js +2 -2
- package/dist/onsite-render.min.js +3 -3
- package/dist/onsite-wheel.min.js +1 -1
- package/package.json +1 -1
- package/src/bootstrap.js +59 -30
- package/src/consent-gate.js +8 -5
- package/src/context.js +2 -1
- package/src/device-storage.js +4 -4
- package/src/index.js +68 -7
- package/src/onsite/render.js +49 -18
- package/src/onsite/styles.js +1 -1
- package/src/onsite/wheel.js +61 -13
- package/src/settings.js +30 -2
- package/src/social-proof.js +5 -1
- package/src/storage-scope.js +2 -2
- package/src/transport.js +22 -2
- package/src/version.js +1 -1
- package/types/bootstrap.d.ts +3 -2
- package/types/hp.d.ts +3 -2
- package/types/index.d.ts +4 -3
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{async function Re(
|
|
1
|
+
(()=>{async function Re(i,o,a){let l=m=>Array.from(new Uint8Array(m),v=>v.toString(16).padStart(2,"0")).join(""),f=new TextEncoder,x=i.maxnumber??1e6;for(let m=0;m<=x;m+=256){let v=[];for(let T=m;T<m+256&&T<=x;T++)v.push(crypto.subtle.digest("SHA-256",f.encode(i.salt+T)));let h=(await Promise.all(v)).findIndex(T=>l(T)===i.challenge);if(h>=0)return m+h;if(o&&await o(),a?.aborted)return null}return null}var kt=()=>globalThis.scheduler?.postTask?.(()=>{},{priority:"user-visible"})??new Promise(i=>setTimeout(i,0)),De=(i,o)=>Re(i,kt,o);function At(i,o){let a=`onmessage=async(e)=>postMessage(await(${Re})(e.data))`,l=URL.createObjectURL(new Blob([a],{type:"text/javascript"}));return new Promise((f,x)=>{let m;try{m=new Worker(l)}catch(h){URL.revokeObjectURL(l),x(h);return}let v=(h,T)=>{m.terminate(),URL.revokeObjectURL(l),h(T)};o.addEventListener("abort",()=>v(f,null),{once:!0}),m.onmessage=h=>v(f,h.data),m.onerror=h=>{h.preventDefault?.(),v(x,h)},m.postMessage({challenge:i.challenge,salt:i.salt,maxnumber:i.maxnumber})})}var St=i=>i&&i.algorithm==="SHA-256"&&typeof i.challenge=="string"&&typeof i.salt=="string"&&typeof i.signature=="string";async function Ue(i){if(!St(i)||typeof crypto?.subtle?.digest!="function")return null;let o=Date.now(),a=new AbortController,l,f=new Promise(v=>{l=setTimeout(()=>v(null),2e4)}),x=typeof Worker=="function"&&typeof Blob=="function"?At(i,a.signal).catch(()=>De(i,a.signal)):De(i,a.signal),m=await Promise.race([x,f]);return clearTimeout(l),a.abort(),typeof m!="number"?null:btoa(JSON.stringify({algorithm:i.algorithm,challenge:i.challenge,number:m,salt:i.salt,signature:i.signature,took:Date.now()-o}))}function B(i){if(typeof i!="string")return null;try{let o=new URL(i);return o.protocol==="https:"?o.href:null}catch{return null}}function G(i){if(typeof i!="string")return null;try{let o=new URL(i);return o.protocol==="https:"||o.protocol==="http:"&&o.hostname==="localhost"?o.href:null}catch{return null}}function pe(i,o,a,l){if(typeof o=="string"){i.append(a.createTextNode(o));return}if(l>6||o===null)return;if(Array.isArray(o)){for(let v of o)pe(i,v,a,l+1);return}if(typeof o!="object")return;let f="b"in o?"b":"i"in o?"i":"a"in o?"a":null;if(!f)return;let x=f==="a"?B(o.href):null,m=f==="a"&&!x?i:a.createElement(f);x&&(m.setAttribute("href",x),m.setAttribute("rel","noopener")),pe(m,o[f],a,l+1),m!==i&&i.append(m)}function We(i,o=document){let a=o.createDocumentFragment();return pe(a,i,o,0),a}var Et=i=>i!==null&&typeof i=="object"&&!Array.isArray(i);function V(i,o,a){if(typeof a=="string"&&a)return a;let l=Et(i?.next?.answers)?i.next.answers:{};for(let[f,x]of Object.entries(l)){let m=f.indexOf("="),v=o[f.slice(0,m)];if(m>0&&v?.includes(f.slice(m+1)))return x}return typeof i?.next?.default=="string"?i.next.default:null}var ue={AT:"43",AU:"61",BE:"32",CA:"1",CH:"41",DE:"49",DK:"45",ES:"34",FI:"358",FR:"33",GB:"44",IE:"353",IT:"39",NL:"31",NO:"47",NZ:"64",PL:"48",PT:"351",SE:"46",US:"1"};function Fe(i,o){let a=String(i??"").replace(/[\s.()-]/g,"");a.startsWith("00")&&(a=`+${a.slice(2)}`);let l=ue[String(o??"").toUpperCase()];return!a.startsWith("+")&&l&&(a=`+${l}${a.replace(/^0/,"")}`),/^\+[1-9]\d{7,14}$/.test(a)?a:null}var Ye=i=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(i);function fe(i,o,a,l,f){let x=i("select","i");x.setAttribute("aria-label",o);for(let[m,v]of[["",a],...l]){let h=i("option","",v);h.value=m,h.selected=m===f,x.append(h)}return x}var he={system:"system-ui,sans-serif","neo-grotesque":'Inter,Roboto,"Helvetica Neue",Arial,sans-serif',humanist:'Seravek,"Gill Sans Nova",Ubuntu,Calibri,sans-serif',"geometric-humanist":"Avenir,Montserrat,Corbel,sans-serif","rounded-sans":'ui-rounded,Quicksand,Comfortaa,"Arial Rounded MT Bold",sans-serif',industrial:'Bahnschrift,"DIN Alternate","Franklin Gothic Medium",sans-serif',transitional:'Charter,"Sitka Text",Cambria,serif',"old-style":'"Iowan Old Style","Palatino Linotype",P052,serif',didone:'Didot,"Bodoni MT","Noto Serif Display",serif',"slab-serif":'Rockwell,"Roboto Slab","DejaVu Serif",serif'},me="cubic-bezier(.16,1,.3,1)",be=`
|
|
2
2
|
:host{all:initial}
|
|
3
3
|
:host([preview]){display:block;position:relative;width:100%;height:100%;overflow:hidden;contain:layout paint}
|
|
4
4
|
.s{--a:var(--hp-accent,#111);--b:var(--hp-bg,#fff);--t:var(--hp-text,#111);--r:var(--hp-radius,16px);--oa:var(--hp-on-accent,#fff);--ot:var(--hp-on-accent-text,var(--oa));--fl:var(--hp-field,color-mix(in srgb,var(--t) 5%,var(--b)));--ft:var(--hp-field-text,var(--t));--mu:color-mix(in srgb,var(--t) 74%,var(--b));--ln:color-mix(in srgb,var(--t) 18%,var(--b));--br:min(12px,var(--r));--ir:min(var(--r),8px);font:16px/1.5 var(--hp-font,system-ui,-apple-system,"Segoe UI",Roboto,sans-serif);color:var(--t);-webkit-font-smoothing:antialiased;box-sizing:border-box;margin:0;padding:0;border:0;background:none;max-width:none;max-height:none;overflow:visible}
|
|
@@ -115,7 +115,7 @@ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
|
115
115
|
.hd{display:none}
|
|
116
116
|
.uc h2{text-transform:uppercase;font-weight:800;letter-spacing:-.01em;line-height:1.02}
|
|
117
117
|
.uc .btn:not(.no),.uc .tb{text-transform:uppercase;letter-spacing:.06em}
|
|
118
|
-
.sheet,.bar,.teaser{position:fixed;inset:auto;z-index:2147483646;display:flex;flex-direction:column}
|
|
118
|
+
.sheet,.bar,.teaser{position:fixed;inset:auto;height:auto;z-index:2147483646;display:flex;flex-direction:column}
|
|
119
119
|
.sheet{right:24px;bottom:24px;width:min(400px,calc(100% - 32px));max-height:calc(100% - 48px)}
|
|
120
120
|
.sheet.p-bottom-left{right:auto;left:24px}
|
|
121
121
|
.sheet.p-bottom{right:auto;left:50%;translate:-50% 0}
|
|
@@ -179,4 +179,4 @@ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
|
179
179
|
@keyframes hp-down{from{transform:translateY(-100%)}}
|
|
180
180
|
@keyframes hp-out{to{opacity:0;transform:translateY(12px) scale(.98)}}
|
|
181
181
|
@media (prefers-reduced-motion:reduce){.s .w,.s .ov,.f>*{animation:hp-fade .15s ease both!important}.btn{transition:none}}
|
|
182
|
-
`;var $t=/^#(?:[0-9a-f]{3}){1,2}$/i,He=["popup","fullscreen"],_t=["ok","verify","already"],zt=["stack","split","overlay","image-only"],Be={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},Tt=["xs","sm","md","lg","xl","display"],Ge={xs:4,sm:8,md:16,lg:28,xl:44},Ve={sm:380,md:480,lg:880},Ct=["left","center","right"],Xe={secondary:" b2",link:" no"},Lt=220,Mt=["verify","already","held","fallback","success"],Ot=[500,1500],It=600,Pt=1800,$={email:"Enter a valid email address.",phone:"Enter a valid mobile number.",intl:"Enter a valid mobile number, starting with + and its country code.",consent:"Tick the box to sign up.",failed:"Something went wrong. Please try again.",busy:"Too many tries. Please wait a moment and try again.",spin:"Sign up first to spin.",yours:"Your code",held:"You\u2019re already on the list",resent:"We\u2019ve sent your code to your inbox again.",inbox:"Your code is in the email we sent when you first signed up.",shop:"Continue shopping",closeOffer:"Close offer",code:"We\u2019ll email your code to you.",claimed:"This email address has already claimed its code.",copied:"Copied",thanks:"Thanks, you\u2019re signed up",unavailable:"Not available right now.",won:"You won"},P=n=>n!==null&&typeof n=="object"&&!Array.isArray(n),F=(n,o,a)=>n.includes(o)?o:a,I=(n,o,a)=>Number.isFinite(n)?Math.min(Math.max(n,o),a):null,ge=n=>n.type==="date"||n.type==="number",xe=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function Ze(n){let o=P(n.layout)?n.layout:{},a=P(o.media)?o.media:null,l=F(zt,o.template,"stack"),u=a?.side==="right"?"right":"left";return!a&&P(o.image)&&o.image.side!=="none"&&(a=o.image,o.image.side!=="top"&&(l="split",u=o.image.side==="right"?"right":"left")),(!a||!G(a.asset))&&(a=null,l="stack"),{template:l,media:a,side:u,scrim:I(o.scrim,0,.9)??.45,padding:F(["none","sm","md","lg"],o.padding,"md")}}var Je=(n,o)=>F(["sm","md","lg","full"],n.size,null)??(o.template==="split"||o.template==="overlay"?"lg":"md"),Qe=(n,o,a=1)=>{if(n==="fullscreen"||o==="full")return"100vw";let l=n==="teaser"?220:n==="sheet"?400:Ve[o]??Ve.md;return`(max-width: 639px) 100vw, ${Math.round(l*a)}px`},et=(n,o,a)=>{if(!a||!Array.isArray(n.widths)||!o.endsWith(".webp"))return null;let l=n.widths.filter(u=>Number.isInteger(u)&&u>0&&u<a).sort((u,x)=>u-x);return l.length===0?null:[...l.map(u=>`${o.slice(0,-5)}-${u}w.webp ${u}w`),`${o} ${a}w`].join(",")},tt=(n,o)=>n.format==="inline"?"inline":o.format&&o.format!=="inline"?o.format:n.format,ve=n=>n.kind==="video"||n.t==="video",we={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},ke=n=>we[n.split(/[?#]/)[0].split(".").pop().toLowerCase()],Nt=(n,o)=>[...new Set([o,...Array.isArray(n.sources)?n.sources.map(G):[]])].filter(Boolean).sort((a,l)=>(ke(l)===we.webm)-(ke(a)===we.webm));function Ae(n,o,a,l=new Set){let u=o.steps.find(k=>k.id===a);if(!u)return Promise.resolve();let x=tt(n,o),m=Ze(u),v=x==="teaser"&&u===o.steps[0],h=x==="teaser"&&!v?"popup":x,T=Je(o.theme,m),S=v?[]:u.blocks.filter(k=>P(k)&&(k.t==="image"||k.t==="video")).map(k=>[k,1]);return m.media&&!(v&&m.template!=="image-only")&&S.push([m.media,m.template==="split"?.46:1]),Promise.all(S.map(([k,Z])=>{let C=G(ve(k)?k.poster:k.asset);if(!C)return null;let L=document.createElement("img"),U=!ve(k)&&et(k,C,I(k.width,1,8192));U&&(L.sizes=Qe(h,T,Z),L.srcset=U);let y=`${L.sizes} ${U||C}`;return l.has(y)?null:(l.add(y),L.src=C,L.decode?.().catch(()=>{}))}))}var jt=0,ye=n=>`hp-${n}-${++jt}`;function f(n,o,a){let l=document.createElement(n);return o&&(l.className=o),a!==void 0&&l.append(We(a)),l}var nt=n=>{let o=n.length===4?[...n.slice(1)].map(a=>a+a).join(""):n.slice(1);return[0,2,4].map(a=>Number.parseInt(o.slice(a,a+2),16))},K=n=>{let[o,a,l]=nt(n).map(u=>{let x=u/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*o+.7152*a+.0722*l},Ke=(n,o=4.5)=>{let a=K(n)+.05,l=1.05/a;return l>=o?"#fff":a/(K("#111")+.05)>l?"#111":"#fff"};function qt(n,o){let a=(S,k)=>k&&n.style.setProperty(S,k),l=S=>$t.test(S??"")?S:null;a("--hp-accent",l(o.accent)),a("--hp-bg",l(o.background)),a("--hp-text",l(o.text));let u=I(o.radius,0,48);u!==null&&a("--hp-radius",`${u}px`),a("--hp-font",o.font==="site"?n.ownerDocument.defaultView.getComputedStyle(n.parentElement??n.ownerDocument.body).fontFamily:Object.hasOwn(he,o.font)?he[o.font]:null),l(o.accent)&&(a("--hp-on-accent",Ke(o.accent,3)),a("--hp-on-accent-text",Ke(o.accent))),l(o.background)&&K(o.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=P(o.overlay)?o.overlay:{},m=[l(o.text),l(o.background)].filter(Boolean).sort((S,k)=>K(S)-K(k))[0],[v,h,T]=nt(l(x.colour)??m??"#0b0b0f");a("--hp-ov",`rgb(${v} ${h} ${T} / ${I(x.opacity,0,1)??.6})`)}function Dt(n){try{let o=new CSSStyleSheet;o.replaceSync(be),n.adoptedStyleSheets=[o]}catch{let o=document.createElement("style");o.textContent=be,n.append(o)}}function it(n){let{form:o,creative:a,decision:l,access:u,client:x,api:m,counters:v}=n,h=n.preview??null,T=e=>{let t=e.blocks.find(r=>r?.t==="email"||r?.t==="phone");return t?.t==="phone"||!t&&!o.consent_text?o.sms_consent_text:o.consent_text},S=tt(o,a),k=a.theme,Z=F(Be[S]??[],k.position,Be[S]?.[0]),C=document.createElement("hp-onsite");h&&C.setAttribute("preview",""),qt(C,k);let L=C.attachShadow({mode:"open"});Dt(L);let U=S!=="inline"&&!h,y=f(U?"dialog":S==="inline"?"section":"div"),Se=f("div","ov"),E=f("div","w"),W=f("div","m");h&&(W.dataset.hpMedia="");let Ee=()=>{let e=f("form","f");return e.noValidate=!0,e.addEventListener("submit",gt),e.addEventListener("input",()=>{M.textContent&&A.getAttribute("aria-busy")!=="true"&&N(null)}),e},A=Ee(),M=f("p","e");M.id=ye("err"),M.setAttribute("aria-live","assertive");let ie=f("div","hd");ie.setAttribute("aria-hidden","true"),E.append(ie,W,A),y.append(Se,E);let Y=S!=="inline"&&f("button","x");Y&&(Y.type="button",Y.addEventListener("click",()=>j("close")),E.append(Y),Se.addEventListener("click",()=>j("close"))),L.append(y);let i={step:null,mode:S,size:"md",modal:!1,mobile:h?.device==="mobile",answers:{},sent:new Set,receipt:null,claim:n.coupon?{code:n.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:n.warmed??new Set,warming:!1,owed:!1,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=o.locale||document.documentElement.lang,ot=o.questions.some(ge)&&n.loadAnswers().catch(()=>null),$e=new WeakMap,_e=()=>{let e=P(k.button)?k.button:{};y.className=`s ${i.mode}${Z?` p-${Z}`:""} b-${F(["pill","rounded","square"],e.shape,"rounded")}${i.mobile?" mob":""}${h?" pv":""}${e.style==="outline"?" bo":""}${k.caps===!0?" uc":""}`},X=h?null:globalThis.matchMedia?.("(max-width: 639px)"),ze=()=>{i.mobile=X?.matches===!0,ae(),_e()};X&&(i.mobile=X.matches===!0,X.addEventListener?.("change",ze));let Q=(e,t)=>{h||!l.decision_id||!u.analytics()||x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??i.step?.id??null})},N=(e,t)=>{M.className="e",M.textContent=e??"";for(let s of A.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let r=t?.closest("label,fieldset");r&&A.contains(r)?r.after(M):A.append(M),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",M.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},H=e=>{A.setAttribute("aria-busy",String(e));for(let t of A.querySelectorAll("button"))t.disabled=e},Te=()=>h?Promise.resolve(null):(i.pow??(i.pow=m.challenge().then(e=>e.status===200?Ue(e.body):null).catch(()=>null)),i.pow),oe=()=>{for(let e of i.videos)try{document.hidden||xe()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",oe);function Ce(e,t,r,s){let c=G(e.asset);if(!c)return null;let p=typeof e.alt=="string"?e.alt:"",d;if(ve(e)){d=f("video",t),d.muted=d.defaultMuted=d.loop=d.playsInline=!0;let w=G(e.poster);w&&(d.poster=w),p?d.setAttribute("aria-label",p):d.setAttribute("aria-hidden","true"),d.autoplay=!xe()&&!h,d.preload=d.autoplay?"auto":w?"none":"metadata";let _=Nt(e,c);if(_.length>1)for(let z of _){let O=f("source");O.src=z;let q=ke(z);q&&(O.type=q),d.append(O)}else d.src=c;i.videos.push(d)}else{d=f("img",t),d.alt=p,d.decoding="async",d.loading=r?"eager":"lazy",r&&(d.fetchPriority="high");let w=et(e,c,I(e.width,1,8192));w&&(d.sizes=Qe(i.mode,i.size,s),d.srcset=w),d.src=c}let b=I(e.width,1,8192),g=I(e.height,1,8192);return b&&g&&(d.width=b,d.height=g),P(e.focal)&&(d.style.objectPosition=`${I(e.focal.x,0,100)??50}% ${I(e.focal.y,0,100)??50}%`),d}function Le(e,t){let r=f("label","l");r.append(f("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let s=f("input","i");if(s.type=t,s.name=t==="email"?"email":"phone",s.autocomplete=s.inputMode=t,s.required=!0,typeof e.placeholder=="string"&&(s.placeholder=e.placeholder),s.setAttribute("aria-describedby",M.id),s.addEventListener("focus",Te,{once:!0}),t!=="tel")return r.append(s),r;s.id=`${M.id}-p`,r.htmlFor=s.id;let c=fe(f,"Country code","+",Object.entries(ue).map(([d,b])=>[d,`${d} +${b}`]),(e.country||/-(\w\w)$/.exec(J)?.[1]||"").toUpperCase());c.classList.add("cc"),c.name="hp_cc";let p=f("span","ph");return p.append(c,s),r.append(p),r}function rt(e){let t=o.questions.find(b=>b.key===e.question);if(!t||!ge(t)&&!Array.isArray(t.options))return null;let r=f("fieldset");r.dataset.question=t.key,r.append(f("legend","",t.label??""));let s=i.answers[t.key]??[];if(ge(t))return ot.then(b=>{if(!b)return r.append(f("p","sm",$.unavailable));b.answerFields(r,t,f,s[0],J),$e.set(r,()=>b.answerOf(r,t,void 0,J))}),r;let c=t.type==="many",p=F(["list","dropdown"],e.display,"buttons"),d=t.options.filter(b=>P(b)&&typeof b.value=="string");if(p==="dropdown"&&!c)return r.append(fe(f,t.label??t.key,"\u2014",d.map(b=>[b.value,b.label??b.value]),s[0])),r;p!=="buttons"&&(r.className="ls");for(let b of d){let g=f("input");g.value=b.value,g.checked=s.includes(b.value),g.type=c?"checkbox":"radio",g.name=`q_${t.key}`;let w=f("label",p==="buttons"?"ch":"c");w.append(g,f("span","",b.label??b.value)),r.append(w)}return r}function re(){for(let e of i.codes){if(e.replaceChildren(),!i.claim)continue;if(!i.claim.code){e.append(f("p","",i.claim.held?$.claimed:$.code));continue}i.claim.prize?.label&&e.append(f("p","",i.claim.prize.label));let t=f("output");t.textContent=i.claim.code;let r=f("button","btn cp");r.type="button",r.textContent="Copy code",r.addEventListener("click",()=>{navigator.clipboard?.writeText(i.claim.code).then(()=>{r.textContent=$.copied}).catch(()=>{})}),e.append(t,r)}}function st(e){if(i.claim&&!i.claim.code)return null;let t=f("p","tm");t.setAttribute("role","timer");let r=Date.now()+Math.max(0,Number(e.minutes)||0)*6e4,s=()=>{let p=Math.max(0,Math.round((r-Date.now())/1e3));t.textContent=`${String(Math.floor(p/60)).padStart(2,"0")}:${String(p%60).padStart(2,"0")}`,p===0&&clearInterval(c)},c=setInterval(s,1e3);return i.timers.push(c),s(),t}function se(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",r=>{h?r.preventDefault():Q("click")}),e}function at(e){let t=e.label??"Continue";if(e.action==="link"){let s=B(e.href);return s?se(f("a",`btn${Xe[e.variant]??""}`,t),s):null}let r=f("button",`btn${Xe[e.variant]??""}`,t);return r.type=e.action==="submit"?"submit":"button",r.type==="button"?r.addEventListener("click",()=>te(e)):r.dataset.submit="",r}let Me=(e,t,r)=>(e.classList.add(`x-${F(Tt,t.size,r)}`),Ct.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Oe(e){let t=Ce(e,"bi",i.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let r=I(e.radius,0,48);r!==null&&(t.style.borderRadius=`${r}px`);let s=I(e.max_height,40,800);if(s!==null&&(t.style.maxHeight=`${s}px`),!t.width&&e.fit!=="contain"&&(t.style.aspectRatio="16 / 9"),e.t==="video"||!B(e.href))return t;let c=se(f("a","bl"),B(e.href));return c.append(t),c}function lt(e){let t=I(e.threshold,.01,1e7);if(!t)return null;let r=f("div","pg"),s=f("p"),c=f("div","tr"),p=f("i");c.append(p),c.setAttribute("role","progressbar"),c.setAttribute("aria-valuemin","0"),c.setAttribute("aria-valuemax",String(t)),r.append(s,c);let d=g=>g.toFixed(2);try{let g=new Intl.NumberFormat(J||void 0,{style:"currency",currency:e.currency});d=w=>g.format(w)}catch{}let b=()=>{let g=Math.max(0,Number(n.basket?.())||0),w=t-g;s.textContent=w>0?String(e.text??"").replace("{amount}",d(w)):e.done??"",p.style.transform=`scaleX(${Math.min(1,g/t)})`,c.setAttribute("aria-valuenow",String(Math.min(g,t))),s.id||(s.id=ye("pg")),c.setAttribute("aria-labelledby",s.id)};return b(),i.timers.push(setInterval(b,2e3)),r}let Ie={heading(e){let t=Me(f("h2","",e.text),e,"xl");return t.id=ye("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),i.step===a.steps[0]&&He.includes(i.mode)&&!h&&(t.autofocus=!0)),t},text:e=>Me(f("p","",e.text),e,"md"),email:e=>Le(e,"email"),phone:e=>Le(e,"tel"),consent(e){let t=T(i.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return f("p","sm",t);let r=f("label","c"),s=f("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",M.id),r.append(s,f("span","",t)),r},question:rt,wheel(){let e=f("div","wh");return n.loadWheel().then(t=>{i.closed||(i.wheel=t.mountWheel(e,o.prizes))}).catch(()=>{}),e},code(){let e=f("div","k");return e.setAttribute("aria-live","polite"),i.codes.push(e),e},button:at,decline(e){let t=f("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>j("decline")),t},countdown:st,progress:lt,image:Oe,video:Oe,spacer(e){let t=f("div","sp");return t.style.height=`${Ge[e.size]??Ge.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>f("hr")};function ct(e,t){W.replaceChildren();let r=e.media,s=!r||t&&e.template!=="image-only";if(i.size=Je(k,e),E.className=`w t-${e.template} z-${i.size}${e.side==="right"?" right":""}${k.text_align==="center"?" ta-center":""}${s?" nm":""}`,E.style.setProperty("--sc",String(e.scrim)),A.className=`f pd-${e.padding}`,W.hidden=s,W.hidden)return;let c=Ce(r,"",i.step===a.steps[0],e.template==="split"?.46:1);if(!c)return;if(c.width?E.style.setProperty("--ar",`${c.width} / ${c.height}`):E.style.removeProperty("--ar"),e.template!=="image-only"){c.tagName==="IMG"&&e.template==="overlay"&&(c.alt=""),W.append(c);return}let p=B(r.href),d=p?se(f("a","io"),p):f("button","io");p||(d.type="button",d.addEventListener("click",()=>te({action:"next"}))),d.append(c),W.append(d)}function dt(e){let t=e.blocks.find(c=>c?.t==="heading"),r=e.blocks.find(c=>c?.t==="button"&&c.action==="next"),s=f("button","tb");return s.textContent=t?f("b","",t.text).textContent:r?.label??"Open",s.type="button",s.addEventListener("click",()=>te(r??{action:"next"})),s}function R(e,t=new Set){let r=a.steps.find(z=>z.id===e);if(!r)return j("done");if(r.kind==="question"&&!h&&!u.analytics()&&!t.has(r.id))return R(V(r,i.answers),t.add(r.id));let s=i.step!==null,c=s&&(L.activeElement||document.activeElement===document.body),p=s&&!h?{mode:i.mode,w:E.offsetWidth,h:E.offsetHeight,top:E.offsetTop}:null;i.step=r,i.touched=!1;for(let z of i.timers.splice(0))clearInterval(z);i.codes=[],i.videos=[],i.wheel=null;let d=S==="teaser"&&r===a.steps[0];if(i.mode=S==="teaser"&&!d?"popup":S,S==="teaser"&&v.tab?.(o.slot,d),Y&&Y.setAttribute("aria-label",d?$.closeOffer:"Close"),_e(),y.removeAttribute("aria-labelledby"),p){let z=Ee();A.replaceWith(z),A=z}let b=Ze(r);ct(b,d);let g=p?.mode==="popup"&&i.mode==="popup";if(ae(),p?.mode===i.mode&&p.h>0&&!g&&(E.style.setProperty("--lw",`${p.w}px`),E.style.setProperty("--lh",`${p.h}px`),E.classList.add("lk")),A.replaceChildren(),d&&b.template!=="image-only")A.append(dt(r));else for(let[z,O]of r.blocks.entries()){let q=P(O)&&Object.hasOwn(Ie,O.t)?Ie[O.t](O):null;q&&(h&&(q.dataset.hpBlock=String(z)),A.append(q))}let w=A.querySelector("[data-submit]"),_=A.querySelector("[name=hp_consent]")?.parentNode;w&&_&&w.before(_),A.hidden=A.childElementCount===0,N(null),re(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",b.media?.alt?.trim?.()||"Sign up"),g&&p.h>0&&pt(p),s&&Pe(),oe(),h||ut(r),c&&A.querySelector("h2")?.focus()}function ae(){E.classList.remove("lk","an"),E.style.removeProperty("--tp")}function pt(e){let t=E.offsetHeight;E.classList.add("an");let r=E.offsetTop,s=Math.max(0,e.top-r);if(s+t>y.clientHeight-2*r)return ae();E.style.setProperty("--tp",`${s}px`)}function ut(e){let t=e.next??{};for(let c of[t.default,...Object.values(P(t.answers)?t.answers:{}),...e.blocks.map(p=>p?.next),...Mt])typeof c=="string"&&i.toWarm.add(c);if(i.warming)return;i.warming=!0;let r=()=>{if(i.warming=!1,!i.closed&&C.isConnected)for(let c of i.toWarm)Ae(o,a,c,i.warmed);i.toWarm.clear()},s=()=>globalThis.requestIdleCallback?requestIdleCallback(r,{timeout:2e3}):setTimeout(r,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function Pe(){if(!U)return;let e=He.includes(i.mode);if(!(y.open&&i.modal===e)){try{y.open&&y.close()}catch{}if(i.modal=e,y.setAttribute("aria-modal",String(e)),e&&typeof y.showModal=="function")y.showModal();else if(typeof y.show=="function"){let t=document.activeElement;y.show(),t&&t!==document.body?t.focus?.({preventScroll:!0}):C.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function ft(){for(let e of A.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,r=$e.get(e)?.()??{};if(r.error)return r;let s=[r.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(c=>c.value)].filter(Boolean);s.length?i.answers[t]=s:delete i.answers[t]}}function mt(){let e=[];for(let[r,s]of Object.entries(i.answers)){let c=`${r}=${s.join(",")}`;i.sent.has(c)||(i.sent.add(c),e.push({question:r,values:s}))}let t=i.step.id;if(i.signedUp&&e.length)return void m.answers({anonymousId:u.anonymousId(),sessionId:u.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t,...i.signedUp,answers:e,context:Ne()});if(u.analytics())for(let r of e)x.preferencesStated({...r,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t})}let Ne=()=>({page:{url:u.pageUrl()},locale:u.locale()??void 0,consent:u.consent()}),ee=e=>{i.receipt&&!h&&mt(),R(V(i.step,i.answers,e))};async function ht(e){let t=i.step,r=A.querySelector("input[name=email],input[name=phone]");if(!r)return ee(e.next);let s=r.name==="email"?"email":"sms",c=A.querySelector("select[name=hp_cc]")?.value,p=s==="email"?Ye(r.value.trim())?r.value.trim():null:Fe(r.value,c);if(!p)return N(s==="email"?$.email:c?$.phone:$.intl,r);let d=A.querySelector("input[name=hp_consent]");if(d&&!d.checked)return N($.consent,d);N(null),H(!0);let b=await Te();i.pow=null;let g=Object.entries(i.answers).map(([D,de])=>({question:D,values:de})),w=s==="sms"?o.sms_consent_text:o.consent_text,_=await m.capture({anonymousId:u.anonymousId(),sessionId:u.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t.id,channel:s,[s==="email"?"email":"phone"]:p,...s==="sms"&&i.signedUp,consent_text:w?{id:w.id,version:w.version}:void 0,...g.length?{answers:g}:{},...b?{altcha:b}:{},context:Ne()}),z=_.body?.status,O=(_.status===202||_.status===200)&&_t.includes(z);if(i.closed&&!O)return;O||H(!1);let q=_.status===400?_.body?.field:null;if(q==="email"||q==="phone")return N($[q],r);if(!O)return N(_.status===429?$.busy:$.failed,r);r.value="";for(let[D,de]of Object.entries(i.answers))i.sent.add(`${D}=${de.join(",")}`);i.receipt=typeof _.body.receipt=="string"?_.body.receipt:null,s==="email"&&(i.signedUp={email:p,email_receipt:i.receipt}),i.submitted=!0,v.submitted(o.slot),Q("submit",t.id),i.owed=s==="email"&&o.prizes.length>0;let ne=i.owed?ce([]):null;ne||n.emit?.("submitted",{coupon:null});let yt=ne&&await Promise.race([ne,new Promise(D=>setTimeout(D,It))]);if(i.closed)return;if(H(!1),yt?.held)return R(le("held"));let vt=z!=="ok"&&a.steps.some(D=>D.id===z);R(vt?z:V(t,i.answers,e.next));let wt=i.step;ne?.then(D=>{D?.held&&!i.closed&&i.step===wt&&!i.touched&&R(le("held"))})}function le(e){if(a.steps.some(r=>r.id===e))return e;let t=e==="fallback"||i.claim?.code?[{t:"heading",text:e==="fallback"?$.thanks:$.yours},{t:"code"}]:[{t:"heading",text:$.held},{t:"text",text:o.code_relayed===!0?$.resent:$.inbox},{t:"button",label:$.shop,action:"close"}];return a.steps.push({id:e,blocks:t}),e}function je(e){i.owed&&(i.owed=!1,n.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function ce(e=Ot){let t=i.receipt;return i.claiming??(i.claiming=(async()=>{let r;for(let d of[0,...e])if(d&&await new Promise(b=>setTimeout(b,d)),r=await m.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),r.status!==503)break;let s=r.body,c=s?.fallback===!0&&!s.code;if(r.status!==200||!(P(s?.prize)||c))return i.claiming=null,!e.length&&r.status===503?ce():(je(null),null);let p=s.held&&!s.code?v.code?.():null;return p&&(s={...s,code:p}),i.claim=s,typeof s.code=="string"&&v.code?.(s.code),je(s),i.closed||re(),s})()),i.claiming}async function bt(e){if(!i.receipt)return N($.spin);H(!0);let t=await ce();if(i.closed)return;if(!t)return H(!1),N($.failed);let r=t.fallback===!0&&!t.code,s=t.held?-1:o.prizes.findIndex(d=>d.key===t.prize?.key&&d.label===t.prize?.label);if(i.wheel&&s>=0&&!r){if(await i.wheel.spinTo(s),i.closed)return;M.className="e won",M.textContent=`${$.won} ${t.prize.label}`,await new Promise(d=>setTimeout(d,Pt))}if(i.closed)return;H(!1);let c=r?"fallback":s<0?"held":null,p=c?le(c):V(i.step,i.answers,e.next);p?R(p):re()}function te(e){if(e.action==="close")return j("close");let t=ft();return h?ee(e.next):t?N(t.error,t.input):e.action==="apply"?(n.emit?.("apply",{coupon:i.claim?.code?{code:i.claim.code}:null}),Q("click"),V(i.step,i.answers,e.next)?ee(e.next):j("done")):e.action==="submit"?ht(e):e.action==="spin"?bt(e):ee(e.next)}function gt(e){if(e.preventDefault(),A.getAttribute("aria-busy")==="true")return;let t=i.step.blocks.find(r=>r?.t==="button"&&r.action==="submit");te(t??{action:"next"})}function qe(){i.closed=!0;for(let t of i.timers.splice(0))clearInterval(t);document.removeEventListener("visibilitychange",oe),X?.removeEventListener?.("change",ze);let e=()=>{try{y.open&&y.close()}catch{}C.remove()};if(!U||xe())return e();y.classList.add("out"),setTimeout(e,Lt)}function j(e){i.closed||h||(!i.submitted&&e!=="done"&&Q("dismiss"),v.closed(o.slot),v.tab?.(o.slot,!1),qe(),n.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{i.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),j("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!i.modal&&S!=="inline"&&j("esc"),e.key==="Tab"&&i.modal&&xt(e)});function xt(e){let t=[...L.querySelectorAll("input[type=radio]:checked")],r=new Set,s=[...L.querySelectorAll("a[href],button,input,select,textarea")].filter(g=>{if(g.disabled||!g.getClientRects().length)return!1;if(g.type!=="radio")return!0;let w=t.find(_=>_.name===g.name);return(w?g!==w:r.has(g.name))?!1:(r.add(g.name),!0)});if(!s.length)return;let c=e.shiftKey,p=L.activeElement;p?.type==="radio"&&(p=s.find(g=>g.type==="radio"&&g.name===p.name)??p);let d=s.indexOf(p),b=null;if(d<0){let g=w=>p&&p.compareDocumentPosition(w)&4;b=c?s.findLast(w=>!g(w))??s.at(-1):s.find(g)??s[0]}else(c?d===0:d===s.length-1)&&(b=s.at(c?-1:0));b&&(e.preventDefault(),b.focus())}return ie.addEventListener("pointerdown",e=>{if(!i.mobile||i.mode!=="sheet")return;let t=e.clientY,r=0,s=p=>{r=Math.max(0,p.clientY-t),E.style.transform=`translateY(${r}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),E.style.transform="",r>80&&j("close")};document.addEventListener("pointermove",s),document.addEventListener("pointerup",c)}),R(h?.step&&a.steps.some(e=>e.id===h.step)?h.step:a.steps[0].id),(n.container??document.body).append(C),Pe(),{close:j,root:L,host:C,show:R,step:()=>i.step?.id??null,modal:()=>!i.closed&&i.modal,destroy:()=>!i.closed&&qe()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:it,warm:Ae};})();
|
|
182
|
+
`;var $t=/^#(?:[0-9a-f]{3}){1,2}$/i,He=["popup","fullscreen"],_t=["ok","verify","already"],zt=["stack","split","overlay","image-only"],Be={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},Tt=["xs","sm","md","lg","xl","display"],Ge={xs:4,sm:8,md:16,lg:28,xl:44},Ve={sm:380,md:480,lg:880},Ct=["left","center","right"],Xe={secondary:" b2",link:" no"},Lt=220,Mt=["verify","already","held","fallback","success"],Ot=[500,1500],It=600,Pt=1800,A={email:"Enter a valid email address.",phone:"Enter a valid mobile number.",intl:"Enter a valid mobile number, starting with + and its country code.",consent:"Tick the box to sign up.",failed:"Something went wrong. Please try again.",busy:"Too many tries. Please wait a moment and try again.",spin:"Sign up first to spin.",yours:"Your code",held:"You\u2019re already on the list",resent:"We\u2019ve sent your code to your inbox again.",inbox:"Your code is in the email we sent when you first signed up.",shop:"Continue shopping",closeOffer:"Close offer",code:"We\u2019ll email your code to you.",claimed:"This email address has already claimed its code.",copied:"Copied",thanks:"Thanks, you\u2019re signed up",retry:"You\u2019re signed up, but we couldn\u2019t load your prize. Please try again.",unclaimed:"We couldn\u2019t load your prize right now.",unavailable:"Not available right now.",won:"You won"},P=i=>i!==null&&typeof i=="object"&&!Array.isArray(i),F=(i,o,a)=>i.includes(o)?o:a,I=(i,o,a)=>Number.isFinite(i)?Math.min(Math.max(i,o),a):null,ge=i=>i.type==="date"||i.type==="number",xe=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function Ze(i){let o=P(i.layout)?i.layout:{},a=P(o.media)?o.media:null,l=F(zt,o.template,"stack"),f=a?.side==="right"?"right":"left";return!a&&P(o.image)&&o.image.side!=="none"&&(a=o.image,o.image.side!=="top"&&(l="split",f=o.image.side==="right"?"right":"left")),(!a||!G(a.asset))&&(a=null,l="stack"),{template:l,media:a,side:f,scrim:I(o.scrim,0,.9)??.45,padding:F(["none","sm","md","lg"],o.padding,"md")}}var Je=(i,o)=>F(["sm","md","lg","full"],i.size,null)??(o.template==="split"||o.template==="overlay"?"lg":"md"),Qe=(i,o,a=1)=>{if(i==="fullscreen"||o==="full")return"100vw";let l=i==="teaser"?220:i==="sheet"?400:Ve[o]??Ve.md;return`(max-width: 639px) 100vw, ${Math.round(l*a)}px`},et=(i,o,a)=>{if(!a||!Array.isArray(i.widths)||!o.endsWith(".webp"))return null;let l=i.widths.filter(f=>Number.isInteger(f)&&f>0&&f<a).sort((f,x)=>f-x);return l.length===0?null:[...l.map(f=>`${o.slice(0,-5)}-${f}w.webp ${f}w`),`${o} ${a}w`].join(",")},tt=(i,o)=>i.format==="inline"?"inline":o.format&&o.format!=="inline"?o.format:i.format,ve=i=>i.kind==="video"||i.t==="video",we={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},ke=i=>we[i.split(/[?#]/)[0].split(".").pop().toLowerCase()],Nt=(i,o)=>[...new Set([o,...Array.isArray(i.sources)?i.sources.map(G):[]])].filter(Boolean).sort((a,l)=>(ke(l)===we.webm)-(ke(a)===we.webm));function Ae(i,o,a,l=new Set){let f=o.steps.find(k=>k.id===a);if(!f)return Promise.resolve();let x=tt(i,o),m=Ze(f),v=x==="teaser"&&f===o.steps[0],h=x==="teaser"&&!v?"popup":x,T=Je(o.theme,m),E=v?[]:f.blocks.filter(k=>P(k)&&(k.t==="image"||k.t==="video")).map(k=>[k,1]);return m.media&&!(v&&m.template!=="image-only")&&E.push([m.media,m.template==="split"?.46:1]),Promise.all(E.map(([k,Z])=>{let C=G(ve(k)?k.poster:k.asset);if(!C)return null;let L=document.createElement("img"),U=!ve(k)&&et(k,C,I(k.width,1,8192));U&&(L.sizes=Qe(h,T,Z),L.srcset=U);let y=`${L.sizes} ${U||C}`;return l.has(y)?null:(l.add(y),L.src=C,L.decode?.().catch(()=>{}))}))}var jt=0,ye=i=>`hp-${i}-${++jt}`;function u(i,o,a){let l=document.createElement(i);return o&&(l.className=o),a!==void 0&&l.append(We(a)),l}var nt=i=>{let o=i.length===4?[...i.slice(1)].map(a=>a+a).join(""):i.slice(1);return[0,2,4].map(a=>Number.parseInt(o.slice(a,a+2),16))},K=i=>{let[o,a,l]=nt(i).map(f=>{let x=f/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*o+.7152*a+.0722*l},Ke=(i,o=4.5)=>{let a=K(i)+.05,l=1.05/a;return l>=o?"#fff":a/(K("#111")+.05)>l?"#111":"#fff"};function qt(i,o){let a=(E,k)=>k&&i.style.setProperty(E,k),l=E=>$t.test(E??"")?E:null;a("--hp-accent",l(o.accent)),a("--hp-bg",l(o.background)),a("--hp-text",l(o.text));let f=I(o.radius,0,48);f!==null&&a("--hp-radius",`${f}px`),a("--hp-font",o.font==="site"?i.ownerDocument.defaultView.getComputedStyle(i.parentElement??i.ownerDocument.body).fontFamily:Object.hasOwn(he,o.font)?he[o.font]:null),l(o.accent)&&(a("--hp-on-accent",Ke(o.accent,3)),a("--hp-on-accent-text",Ke(o.accent))),l(o.background)&&K(o.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=P(o.overlay)?o.overlay:{},m=[l(o.text),l(o.background)].filter(Boolean).sort((E,k)=>K(E)-K(k))[0],[v,h,T]=nt(l(x.colour)??m??"#0b0b0f");a("--hp-ov",`rgb(${v} ${h} ${T} / ${I(x.opacity,0,1)??.6})`)}function Dt(i){try{let o=new CSSStyleSheet;o.replaceSync(be),i.adoptedStyleSheets=[o]}catch{let o=document.createElement("style");o.textContent=be,i.append(o)}}function it(i){let{form:o,creative:a,decision:l,access:f,client:x,api:m,counters:v}=i,h=i.preview??null,T=e=>{let t=e.blocks.find(r=>r?.t==="email"||r?.t==="phone");return t?.t==="phone"||!t&&!o.consent_text?o.sms_consent_text:o.consent_text},E=tt(o,a),k=a.theme,Z=F(Be[E]??[],k.position,Be[E]?.[0]),C=document.createElement("hp-onsite");h&&C.setAttribute("preview",""),qt(C,k);let L=C.attachShadow({mode:"open"});Dt(L);let U=E!=="inline"&&!h,y=u(U?"dialog":E==="inline"?"section":"div"),Se=u("div","ov"),$=u("div","w"),W=u("div","m");h&&(W.dataset.hpMedia="");let Ee=()=>{let e=u("form","f");return e.noValidate=!0,e.addEventListener("submit",gt),e.addEventListener("input",()=>{M.textContent&&S.getAttribute("aria-busy")!=="true"&&N(null)}),e},S=Ee(),M=u("p","e");M.id=ye("err"),M.setAttribute("aria-live","assertive");let re=u("div","hd");re.setAttribute("aria-hidden","true"),$.append(re,W,S),y.append(Se,$);let Y=E!=="inline"&&u("button","x");Y&&(Y.type="button",Y.addEventListener("click",()=>j("close")),$.append(Y),Se.addEventListener("click",()=>j("close"))),L.append(y);let n={step:null,mode:E,size:"md",modal:!1,mobile:h?.device==="mobile",answers:{},sent:new Set,receipt:null,claim:i.coupon?{code:i.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:i.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=o.locale||document.documentElement.lang,ot=o.questions.some(ge)&&i.loadAnswers().catch(()=>null),$e=new WeakMap,_e=()=>{let e=P(k.button)?k.button:{};y.className=`s ${n.mode}${Z?` p-${Z}`:""} b-${F(["pill","rounded","square"],e.shape,"rounded")}${n.mobile?" mob":""}${h?" pv":""}${e.style==="outline"?" bo":""}${k.caps===!0?" uc":""}`},X=h?null:globalThis.matchMedia?.("(max-width: 639px)"),ze=()=>{n.mobile=X?.matches===!0,le(),_e()};X&&(n.mobile=X.matches===!0,X.addEventListener?.("change",ze));let Q=(e,t)=>{h||!l.decision_id||!f.analytics()||x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null})},N=(e,t)=>{M.className="e",M.textContent=e??"";for(let s of S.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let r=t?.closest("label,fieldset");r&&S.contains(r)?r.after(M):S.append(M),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",M.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},H=e=>{S.setAttribute("aria-busy",String(e));for(let t of S.querySelectorAll("button"))t.disabled=e},Te=()=>h?Promise.resolve(null):(n.pow??(n.pow=m.challenge().then(e=>e.status===200?Ue(e.body):null).catch(()=>null)),n.pow),se=()=>{for(let e of n.videos)try{document.hidden||xe()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",se);function Ce(e,t,r,s){let c=G(e.asset);if(!c)return null;let p=typeof e.alt=="string"?e.alt:"",d;if(ve(e)){d=u("video",t),d.muted=d.defaultMuted=d.loop=d.playsInline=!0;let w=G(e.poster);w&&(d.poster=w),p?d.setAttribute("aria-label",p):d.setAttribute("aria-hidden","true"),d.autoplay=!xe()&&!h,d.preload=d.autoplay?"auto":w?"none":"metadata";let _=Nt(e,c);if(_.length>1)for(let z of _){let O=u("source");O.src=z;let q=ke(z);q&&(O.type=q),d.append(O)}else d.src=c;n.videos.push(d)}else{d=u("img",t),d.alt=p,d.decoding="async",d.loading=r?"eager":"lazy",r&&(d.fetchPriority="high");let w=et(e,c,I(e.width,1,8192));w&&(d.sizes=Qe(n.mode,n.size,s),d.srcset=w),d.src=c}let b=I(e.width,1,8192),g=I(e.height,1,8192);return b&&g&&(d.width=b,d.height=g),P(e.focal)&&(d.style.objectPosition=`${I(e.focal.x,0,100)??50}% ${I(e.focal.y,0,100)??50}%`),d}function Le(e,t){let r=u("label","l");r.append(u("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let s=u("input","i");if(s.type=t,s.name=t==="email"?"email":"phone",s.autocomplete=s.inputMode=t,s.required=!0,typeof e.placeholder=="string"&&(s.placeholder=e.placeholder),s.setAttribute("aria-describedby",M.id),s.addEventListener("focus",Te,{once:!0}),t!=="tel")return r.append(s),r;s.id=`${M.id}-p`,r.htmlFor=s.id;let c=fe(u,"Country code","+",Object.entries(ue).map(([d,b])=>[d,`${d} +${b}`]),(e.country||/-(\w\w)$/.exec(J)?.[1]||"").toUpperCase());c.classList.add("cc"),c.name="hp_cc";let p=u("span","ph");return p.append(c,s),r.append(p),r}function rt(e){let t=o.questions.find(b=>b.key===e.question);if(!t||!ge(t)&&!Array.isArray(t.options))return null;let r=u("fieldset");r.dataset.question=t.key,r.append(u("legend","",t.label??""));let s=n.answers[t.key]??[];if(ge(t))return ot.then(b=>{if(!b)return r.append(u("p","sm",A.unavailable));b.answerFields(r,t,u,s[0],J),$e.set(r,()=>b.answerOf(r,t,void 0,J))}),r;let c=t.type==="many",p=F(["list","dropdown"],e.display,"buttons"),d=t.options.filter(b=>P(b)&&typeof b.value=="string");if(p==="dropdown"&&!c)return r.append(fe(u,t.label??t.key,"\u2014",d.map(b=>[b.value,b.label??b.value]),s[0])),r;p!=="buttons"&&(r.className="ls");for(let b of d){let g=u("input");g.value=b.value,g.checked=s.includes(b.value),g.type=c?"checkbox":"radio",g.name=`q_${t.key}`;let w=u("label",p==="buttons"?"ch":"c");w.append(g,u("span","",b.label??b.value)),r.append(w)}return r}function ee(){for(let e of n.codes){if(e.replaceChildren(),!n.claim){n.unclaimed&&e.append(u("p","",A.unclaimed));continue}if(!n.claim.code){let s=n.claim.held?A.claimed:n.claim.fallback===!0?A.code:n.claim.prize?.label;s&&e.append(u("p","",s));continue}n.claim.prize?.label&&e.append(u("p","",n.claim.prize.label));let t=u("output");t.textContent=n.claim.code;let r=u("button","btn cp");r.type="button",r.textContent="Copy code",r.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{r.textContent=A.copied}).catch(()=>{})}),e.append(t,r)}}function st(e){if(n.claim&&!n.claim.code)return null;let t=u("p","tm");t.setAttribute("role","timer");let r=Date.now()+Math.max(0,Number(e.minutes)||0)*6e4,s=()=>{let p=Math.max(0,Math.round((r-Date.now())/1e3));t.textContent=`${String(Math.floor(p/60)).padStart(2,"0")}:${String(p%60).padStart(2,"0")}`,p===0&&clearInterval(c)},c=setInterval(s,1e3);return n.timers.push(c),s(),t}function ae(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",r=>{h?r.preventDefault():Q("click")}),e}function at(e){let t=e.label??"Continue";if(e.action==="link"){let s=B(e.href);return s?ae(u("a",`btn${Xe[e.variant]??""}`,t),s):null}let r=u("button",`btn${Xe[e.variant]??""}`,t);return r.type=e.action==="submit"?"submit":"button",r.type==="button"?r.addEventListener("click",()=>ie(e)):r.dataset.submit="",r}let Me=(e,t,r)=>(e.classList.add(`x-${F(Tt,t.size,r)}`),Ct.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Oe(e){let t=Ce(e,"bi",n.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let r=I(e.radius,0,48);r!==null&&(t.style.borderRadius=`${r}px`);let s=I(e.max_height,40,800);if(s!==null&&(t.style.maxHeight=`${s}px`),!t.width&&e.fit!=="contain"&&(t.style.aspectRatio="16 / 9"),e.t==="video"||!B(e.href))return t;let c=ae(u("a","bl"),B(e.href));return c.append(t),c}function lt(e){let t=I(e.threshold,.01,1e7);if(!t)return null;let r=u("div","pg"),s=u("p"),c=u("div","tr"),p=u("i");c.append(p),c.setAttribute("role","progressbar"),c.setAttribute("aria-valuemin","0"),c.setAttribute("aria-valuemax",String(t)),r.append(s,c);let d=g=>g.toFixed(2);try{let g=new Intl.NumberFormat(J||void 0,{style:"currency",currency:e.currency});d=w=>g.format(w)}catch{}let b=()=>{let g=Math.max(0,Number(i.basket?.())||0),w=t-g;s.textContent=w>0?String(e.text??"").replace("{amount}",d(w)):e.done??"",p.style.transform=`scaleX(${Math.min(1,g/t)})`,c.setAttribute("aria-valuenow",String(Math.min(g,t))),s.id||(s.id=ye("pg")),c.setAttribute("aria-labelledby",s.id)};return b(),n.timers.push(setInterval(b,2e3)),r}let Ie={heading(e){let t=Me(u("h2","",e.text),e,"xl");return t.id=ye("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),n.step===a.steps[0]&&He.includes(n.mode)&&!h&&(t.autofocus=!0)),t},text:e=>Me(u("p","",e.text),e,"md"),email:e=>Le(e,"email"),phone:e=>Le(e,"tel"),consent(e){let t=T(n.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return u("p","sm",t);let r=u("label","c"),s=u("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",M.id),r.append(s,u("span","",t)),r},question:rt,wheel(){let e=u("div","wh");return i.loadWheel().then(t=>{n.closed||(n.wheel=t.mountWheel(e,o.prizes))}).catch(()=>{}),e},code(){let e=u("div","k");return e.setAttribute("aria-live","polite"),n.codes.push(e),e},button:at,decline(e){let t=u("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>j("decline")),t},countdown:st,progress:lt,image:Oe,video:Oe,spacer(e){let t=u("div","sp");return t.style.height=`${Ge[e.size]??Ge.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>u("hr")};function ct(e,t){W.replaceChildren();let r=e.media,s=!r||t&&e.template!=="image-only";if(n.size=Je(k,e),$.className=`w t-${e.template} z-${n.size}${e.side==="right"?" right":""}${k.text_align==="center"?" ta-center":""}${s?" nm":""}`,$.style.setProperty("--sc",String(e.scrim)),S.className=`f pd-${e.padding}`,W.hidden=s,W.hidden)return;let c=Ce(r,"",n.step===a.steps[0],e.template==="split"?.46:1);if(!c)return;if(c.width?$.style.setProperty("--ar",`${c.width} / ${c.height}`):$.style.removeProperty("--ar"),e.template!=="image-only"){c.tagName==="IMG"&&e.template==="overlay"&&(c.alt=""),W.append(c);return}let p=B(r.href),d=p?ae(u("a","io"),p):u("button","io");p||(d.type="button",d.addEventListener("click",()=>ie({action:"next"}))),d.append(c),W.append(d)}function dt(e){let t=e.blocks.find(c=>c?.t==="heading"),r=e.blocks.find(c=>c?.t==="button"&&c.action==="next"),s=u("button","tb");return s.textContent=t?u("b","",t.text).textContent:r?.label??"Open",s.type="button",s.addEventListener("click",()=>ie(r??{action:"next"})),s}function D(e,t=new Set){let r=a.steps.find(z=>z.id===e);if(!r)return j("done");if(r.kind==="question"&&!h&&!f.analytics()&&!t.has(r.id))return D(V(r,n.answers),t.add(r.id));let s=n.step!==null,c=s&&(L.activeElement||document.activeElement===document.body),p=s&&!h?{mode:n.mode,w:$.offsetWidth,h:$.offsetHeight,top:$.offsetTop}:null;n.step=r,n.touched=!1;for(let z of n.timers.splice(0))clearInterval(z);n.codes=[],n.videos=[],n.wheel=null;let d=E==="teaser"&&r===a.steps[0];if(n.mode=E==="teaser"&&!d?"popup":E,E==="teaser"&&v.tab?.(o.slot,d),Y&&Y.setAttribute("aria-label",d?A.closeOffer:"Close"),_e(),y.removeAttribute("aria-labelledby"),p){let z=Ee();S.replaceWith(z),S=z}let b=Ze(r);ct(b,d);let g=p?.mode==="popup"&&n.mode==="popup";if(le(),p?.mode===n.mode&&p.h>0&&!g&&($.style.setProperty("--lw",`${p.w}px`),$.style.setProperty("--lh",`${p.h}px`),$.classList.add("lk")),S.replaceChildren(),d&&b.template!=="image-only")S.append(dt(r));else for(let[z,O]of r.blocks.entries()){let q=P(O)&&Object.hasOwn(Ie,O.t)?Ie[O.t](O):null;q&&(h&&(q.dataset.hpBlock=String(z)),S.append(q))}let w=S.querySelector("[data-submit]"),_=S.querySelector("[name=hp_consent]")?.parentNode;w&&_&&w.before(_),S.hidden=S.childElementCount===0,N(null),ee(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",b.media?.alt?.trim?.()||"Sign up"),g&&p.h>0&&pt(p),s&&Pe(),se(),h||ut(r),c&&S.querySelector("h2")?.focus()}function le(){$.classList.remove("lk","an"),$.style.removeProperty("--tp")}function pt(e){let t=$.offsetHeight;$.classList.add("an");let r=$.offsetTop,s=Math.max(0,e.top-r);if(s+t>y.clientHeight-2*r)return le();$.style.setProperty("--tp",`${s}px`)}function ut(e){let t=e.next??{};for(let c of[t.default,...Object.values(P(t.answers)?t.answers:{}),...e.blocks.map(p=>p?.next),...Mt])typeof c=="string"&&n.toWarm.add(c);if(n.warming)return;n.warming=!0;let r=()=>{if(n.warming=!1,!n.closed&&C.isConnected)for(let c of n.toWarm)Ae(o,a,c,n.warmed);n.toWarm.clear()},s=()=>globalThis.requestIdleCallback?requestIdleCallback(r,{timeout:2e3}):setTimeout(r,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function Pe(){if(!U)return;let e=He.includes(n.mode);if(!(y.open&&n.modal===e)){try{y.open&&y.close()}catch{}if(n.modal=e,y.setAttribute("aria-modal",String(e)),e&&typeof y.showModal=="function")y.showModal();else if(typeof y.show=="function"){let t=document.activeElement;y.show(),t&&t!==document.body?t.focus?.({preventScroll:!0}):C.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function ft(){for(let e of S.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,r=$e.get(e)?.()??{};if(r.error)return r;let s=[r.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(c=>c.value)].filter(Boolean);s.length?n.answers[t]=s:delete n.answers[t]}}function mt(){let e=[];for(let[r,s]of Object.entries(n.answers)){let c=`${r}=${s.join(",")}`;n.sent.has(c)||(n.sent.add(c),e.push({question:r,values:s}))}let t=n.step.id;if(n.signedUp&&e.length)return void m.answers({anonymousId:f.anonymousId(),sessionId:f.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t,...n.signedUp,answers:e,context:Ne()});if(f.analytics())for(let r of e)x.preferencesStated({...r,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t})}let Ne=()=>({page:{url:f.pageUrl()},locale:f.locale()??void 0,consent:f.consent()}),te=e=>{n.receipt&&!h&&mt(),D(V(n.step,n.answers,e))};async function ht(e){let t=n.step,r=S.querySelector("input[name=email],input[name=phone]");if(!r)return te(e.next);let s=r.name==="email"?"email":"sms",c=S.querySelector("select[name=hp_cc]")?.value,p=s==="email"?Ye(r.value.trim())?r.value.trim():null:Fe(r.value,c);if(!p)return N(s==="email"?A.email:c?A.phone:A.intl,r);let d=S.querySelector("input[name=hp_consent]");if(d&&!d.checked)return N(A.consent,d);N(null),H(!0);let b=await Te();n.pow=null;let g=Object.entries(n.answers).map(([R,de])=>({question:R,values:de})),w=s==="sms"?o.sms_consent_text:o.consent_text,_=await m.capture({anonymousId:f.anonymousId(),sessionId:f.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:t.id,channel:s,[s==="email"?"email":"phone"]:p,...s==="sms"&&n.signedUp,consent_text:w?{id:w.id,version:w.version}:void 0,...g.length?{answers:g}:{},...b?{altcha:b}:{},context:Ne()}),z=_.body?.status,O=(_.status===202||_.status===200)&&_t.includes(z);if(n.closed&&!O)return;O||H(!1);let q=_.status===400?_.body?.field:null;if(q==="email"||q==="phone")return N(A[q],r);if(!O)return N(_.status===429?A.busy:A.failed,r);r.value="";for(let[R,de]of Object.entries(n.answers))n.sent.add(`${R}=${de.join(",")}`);n.receipt=typeof _.body.receipt=="string"?_.body.receipt:null,s==="email"&&(n.signedUp={email:p,email_receipt:n.receipt}),n.submitted=!0,v.submitted(o.slot),Q("submit",t.id),n.owed=s==="email"&&o.prizes.length>0;let oe=n.owed?ce([]):null;oe||i.emit?.("submitted",{coupon:null});let yt=oe&&await Promise.race([oe,new Promise(R=>setTimeout(R,It))]);if(n.closed)return;if(H(!1),yt?.held)return D(ne("held"));let vt=z!=="ok"&&a.steps.some(R=>R.id===z);D(vt?z:V(t,n.answers,e.next));let wt=n.step;oe?.then(R=>{R?.held&&!n.closed&&n.step===wt&&!n.touched&&D(ne("held"))})}function ne(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:A.shop,action:"close"},r=e==="unclaimed"?[{t:"heading",text:A.thanks},{t:"text",text:A.unclaimed},t]:e==="fallback"||n.claim?.code?[{t:"heading",text:e==="fallback"?A.thanks:A.yours},{t:"code"}]:[{t:"heading",text:A.held},{t:"text",text:o.code_relayed===!0?A.resent:A.inbox},t];return a.steps.push({id:e,blocks:r}),e}function je(e){n.owed&&(n.owed=!1,i.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function ce(e=Ot){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let r;for(let d of[0,...e])if(d&&await new Promise(b=>setTimeout(b,d)),r=await m.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),r.status!==503)break;let s=r.body,c=s?.fallback===!0&&!s.code;if(r.status!==200||!(P(s?.prize)||c))return n.claiming=null,!e.length&&r.status===503?ce():(je(null),n.unclaimed=!0,n.closed||ee(),null);let p=s.held&&!s.code?v.code?.():null;return p&&(s={...s,code:p}),n.claim=s,typeof s.code=="string"&&v.code?.(s.code),je(s),n.closed||ee(),s})()),n.claiming}async function bt(e){if(!n.receipt)return N(A.spin);H(!0);let t=await ce();if(n.closed)return;if(!t)return H(!1),n.misses+=1,n.misses<2?N(A.retry):D(ne("unclaimed"));let r=t.fallback===!0&&!t.code,s=t.held?-1:o.prizes.findIndex(d=>d.key===t.prize?.key&&d.label===t.prize?.label);if(n.wheel&&s>=0&&!r){if(await n.wheel.spinTo(s),n.closed)return;M.className="e won",M.textContent=`${A.won} ${t.prize.label}`,await new Promise(d=>setTimeout(d,Pt))}if(n.closed)return;H(!1);let c=r?"fallback":s<0?"held":null,p=c?ne(c):V(n.step,n.answers,e.next);p?D(p):ee()}function ie(e){if(e.action==="close")return j("close");let t=ft();return h?te(e.next):t?N(t.error,t.input):e.action==="apply"?(i.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),Q("click"),V(n.step,n.answers,e.next)?te(e.next):j("done")):e.action==="submit"?ht(e):e.action==="spin"?bt(e):te(e.next)}function gt(e){if(e.preventDefault(),S.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(r=>r?.t==="button"&&r.action==="submit");ie(t??{action:"next"})}function qe(){n.closed=!0;for(let t of n.timers.splice(0))clearInterval(t);document.removeEventListener("visibilitychange",se),X?.removeEventListener?.("change",ze);let e=()=>{try{y.open&&y.close()}catch{}C.remove()};if(!U||xe())return e();y.classList.add("out"),setTimeout(e,Lt)}function j(e){n.closed||h||(!n.submitted&&e!=="done"&&Q("dismiss"),v.closed(o.slot),v.tab?.(o.slot,!1),qe(),i.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{n.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),j("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!n.modal&&E!=="inline"&&j("esc"),e.key==="Tab"&&n.modal&&xt(e)});function xt(e){let t=[...L.querySelectorAll("input[type=radio]:checked")],r=new Set,s=[...L.querySelectorAll("a[href],button,input,select,textarea")].filter(g=>{if(g.disabled||!g.getClientRects().length)return!1;if(g.type!=="radio")return!0;let w=t.find(_=>_.name===g.name);return(w?g!==w:r.has(g.name))?!1:(r.add(g.name),!0)});if(!s.length)return;let c=e.shiftKey,p=L.activeElement;p?.type==="radio"&&(p=s.find(g=>g.type==="radio"&&g.name===p.name)??p);let d=s.indexOf(p),b=null;if(d<0){let g=w=>p&&p.compareDocumentPosition(w)&4;b=c?s.findLast(w=>!g(w))??s.at(-1):s.find(g)??s[0]}else(c?d===0:d===s.length-1)&&(b=s.at(c?-1:0));b&&(e.preventDefault(),b.focus())}return re.addEventListener("pointerdown",e=>{if(!n.mobile||n.mode!=="sheet")return;let t=e.clientY,r=0,s=p=>{r=Math.max(0,p.clientY-t),$.style.transform=`translateY(${r}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),$.style.transform="",r>80&&j("close")};document.addEventListener("pointermove",s),document.addEventListener("pointerup",c)}),D(h?.step&&a.steps.some(e=>e.id===h.step)?h.step:a.steps[0].id),(i.container??document.body).append(C),Pe(),{close:j,root:L,host:C,show:D,step:()=>n.step?.id??null,modal:()=>!n.closed&&n.modal,destroy:()=>!n.closed&&qe()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:it,warm:Ae};})();
|
package/dist/onsite-wheel.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function
|
|
1
|
+
(()=>{function L(e,i,s=5){let n=360/i;return s*360+(360-(e+.5)*n)}var k="http://www.w3.org/2000/svg",z=4500,S=.22,O=.95,v=.105,w=.082,A=.062,I=.62,F=1.15,N="var(--hp-accent,#111)",C="var(--hp-on-accent,#fff)",g="var(--hp-bg,#fff)",T="var(--hp-text,#111)";function c(e,i={}){let s=document.createElementNS(k,e);for(let[n,o]of Object.entries(i))s.setAttribute(n,String(o));return s}function f(e,i,s,n=1){return e.style.fill=i,n<1&&(e.style.fillOpacity=String(n)),s&&(e.style.stroke=s),e}var j=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0,$=(e,i=1)=>{let s=(e-90)*Math.PI/180;return`${(i*Math.cos(s)).toFixed(4)} ${(i*Math.sin(s)).toFixed(4)}`};function B(e,i){let s=O-S,n=2*.35*Math.sin(Math.min(Math.PI/i,Math.PI/2)),o=t=>Math.max(w,Math.min(v,n/(t*F))),a=t=>s/(Math.max(1,t.length)*I),r=[...e.matchAll(/ /g)].map(t=>t.index),u=e.length/2,p=r.length?r.reduce((t,l)=>Math.abs(l-u)<Math.abs(t-u)?l:t):-1,h=p<0?null:[e.slice(0,p),e.slice(p+1)];for(let t of[w,A]){let l=a(e);if(l>=t)return{lines:[e],size:Math.min(o(1),l)};if(h){let m=Math.min(o(2),...h.map(a));if(m>=t)return{lines:h,size:m}}}let d=Math.floor(s/(A*I));return{lines:[`${e.slice(0,d-1).trimEnd()}\u2026`],size:A}}function P(e){let i=O-S,s=n=>n.getComputedTextLength?.()??0;for(let n of e){let o=[...n.querySelectorAll("tspan")],a=Math.max(0,...o.map(s));if(!(a>i))continue;let r=Math.max(A,Number(n.getAttribute("font-size"))*i/a);n.setAttribute("font-size",r.toFixed(4)),o.forEach((u,p)=>{u.setAttribute("y",((p-(o.length-1)/2)*r*F).toFixed(4)),s(u)>i&&(u.setAttribute("textLength",i.toFixed(4)),u.setAttribute("lengthAdjust","spacingAndGlyphs"))})}}function R(e,i){let s=(Array.isArray(i)?i:[]).map(d=>String(d?.label??d?.key??"")),n=s.length;if(n<2)return null;let o=360/n,a=c("svg",{viewBox:"-1.2 -1.2 2.4 2.4",role:"img","aria-label":`Prize wheel: ${s.join(", ")}`}),r=c("g");r.style.transformBox="fill-box",r.style.transformOrigin="50% 50%";let u=[[1,C],[.14,T],[.72,C]];r.append(f(c("circle",{r:1}),g));let p=[],h=[];return s.forEach((d,t)=>{let[l,m]=u[n%2===1&&t===n-1?2:t%2];r.append(f(c("path",{d:`M0 0L${$(t*o)}A1 1 0 ${o>180?1:0} 1 ${$((t+1)*o)}Z`,"stroke-width":.012}),N,g,l));let b=(t+.5)*o-90,x=B(d,n),_=f(c("text",{transform:`rotate(${b}) translate(${(S+O)/2} 0)${b>90&&b<270?" rotate(180)":""}`,"text-anchor":"middle","dominant-baseline":"central","font-size":x.size.toFixed(4),"font-weight":700,"aria-hidden":"true"}),m);x.lines.forEach((M,E)=>{let y=c("tspan",{x:0,y:((E-(x.lines.length-1)/2)*x.size*F).toFixed(4)});y.textContent=M,_.append(y)}),r.append(_),h.push(_);for(let M of[t*o,(t+.5)*o]){let[E,y]=$(M,1.075).split(" ");p.push(f(c("circle",{cx:E,cy:y,r:.024}),g))}}),a.append(f(c("circle",{r:1.13}),T),...p,r,f(c("circle",{r:.17,"stroke-width":.035}),g,T),f(c("circle",{r:.065}),N),f(c("path",{d:"M-0.12 -1.2L0.12 -1.2L0 -0.86Z","stroke-width":.03,"stroke-linejoin":"round"}),N,g)),e.append(a),P(h),globalThis.requestAnimationFrame?.(()=>P(h)),{spinTo(d){let t=j();return r.style.transition=t?"none":`transform ${z}ms cubic-bezier(.15,.7,.1,1)`,r.style.transform=`rotate(${L(d,s.length,t?0:5)}deg)`,t?Promise.resolve():new Promise(l=>{let m=setTimeout(l,z+200);r.addEventListener("transitionend",()=>{clearTimeout(m),l()},{once:!0})})},remove:()=>a.remove()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel")]={mountWheel:R};})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thg-agentic/hyper-personalisation-web",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.25.0",
|
|
4
4
|
"description": "Browser SDK for the THG Hyper-Personalisation event specification: event tracking from a write key and remote settings, strict CMP-agnostic consent, a GA4 dataLayer bridge and in-session audience evaluation. Dependency-free ESM on the Segment wire protocol, a CDN script (dist/hp.min.js), and an optional @segment/analytics-next plugin path.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/bootstrap.js
CHANGED
|
@@ -16,9 +16,10 @@
|
|
|
16
16
|
* cookie, the device cookie's), the per-request currency / ship-to / locale getters, the preset,
|
|
17
17
|
* the page type, debug, and which property this page is for a key scoped to several.
|
|
18
18
|
*
|
|
19
|
-
* Resolves to the client, or null when the key is disabled or unknown, the
|
|
20
|
-
* fetched on a first visit
|
|
21
|
-
* idempotent per page. createAnalytics() and connectDataLayer()
|
|
19
|
+
* Resolves to the client, or null when the key is disabled or unknown, or the options are invalid.
|
|
20
|
+
* Settings that cannot be fetched on a first visit start it on built-in, collect-only defaults.
|
|
21
|
+
* Never throws into the page, and is idempotent per page. createAnalytics() and connectDataLayer()
|
|
22
|
+
* remain the lower-level API.
|
|
22
23
|
*/
|
|
23
24
|
|
|
24
25
|
import { assignmentDecisionId, assignmentSession } from './assignment.js';
|
|
@@ -47,9 +48,9 @@ import { createAnalytics, normaliseSha256, PAGE_TYPES } from './index.js';
|
|
|
47
48
|
import { dropPendingOpens, onsite } from './onsite-facade.js';
|
|
48
49
|
import { loadOnsite } from './onsite-loader.js';
|
|
49
50
|
import {
|
|
51
|
+
BUILT_IN,
|
|
50
52
|
cachedSettings,
|
|
51
53
|
cacheSettings,
|
|
52
|
-
DISABLED,
|
|
53
54
|
eventsHost,
|
|
54
55
|
fetchSettings,
|
|
55
56
|
forgetSettings,
|
|
@@ -68,6 +69,9 @@ const INSTANCE = Symbol.for('@thg-agentic/hyper-personalisation-web.bootstrap');
|
|
|
68
69
|
const DRAIN = Symbol.for('@thg-agentic/hyper-personalisation-web.drain');
|
|
69
70
|
const CARRY = Symbol.for('@thg-agentic/hyper-personalisation-web.carry');
|
|
70
71
|
const REPLAY = Symbol.for('@thg-agentic/hyper-personalisation-web.replay');
|
|
72
|
+
const UNREACHABLE = Symbol.for(
|
|
73
|
+
'@thg-agentic/hyper-personalisation-web.unreachable',
|
|
74
|
+
);
|
|
71
75
|
/** Where bootstrap leaves `hp.assignmentDecisionId` its reader of the page's identity cookies. */
|
|
72
76
|
const ASSIGNMENT = Symbol.for(
|
|
73
77
|
'@thg-agentic/hyper-personalisation-web.assignment',
|
|
@@ -218,21 +222,18 @@ function pendingIdentify(propertyId, identity) {
|
|
|
218
222
|
*
|
|
219
223
|
* Inline settings (development, tests) are used as given and never fetched or cached. Otherwise a
|
|
220
224
|
* cached answer starts the page at once while the API is asked again for the next page; with no
|
|
221
|
-
* cache the page waits for the API, and
|
|
225
|
+
* cache the page waits for the API, and starts on BUILT_IN when it cannot be asked: an outage of
|
|
226
|
+
* the API never turns collection off, and the events it cannot take wait in the retry buffer.
|
|
222
227
|
*/
|
|
223
228
|
async function resolveSettings({ writeKey, apiHost }, options) {
|
|
224
229
|
if (options.settings !== undefined)
|
|
225
230
|
return { settings: readSettings(options.settings), revalidated: null };
|
|
226
231
|
const fetched = fetchSettings(apiHost, writeKey);
|
|
227
232
|
const cached = cachedSettings(writeKey);
|
|
228
|
-
if (cached) return { settings: cached, revalidated: fetched };
|
|
233
|
+
if (cached) return { settings: cached, revalidated: fetched, fetched };
|
|
229
234
|
const answer = await fetched;
|
|
230
|
-
|
|
231
|
-
return {
|
|
232
|
-
settings,
|
|
233
|
-
revalidated: Promise.resolve(settings),
|
|
234
|
-
unreachable: answer === null,
|
|
235
|
-
};
|
|
235
|
+
if (!answer) return { settings: BUILT_IN, revalidated: null, fetched };
|
|
236
|
+
return { settings: answer, revalidated: fetched, fetched };
|
|
236
237
|
}
|
|
237
238
|
|
|
238
239
|
/**
|
|
@@ -320,14 +321,44 @@ function startAutocapture(client, autocapture) {
|
|
|
320
321
|
};
|
|
321
322
|
}
|
|
322
323
|
|
|
324
|
+
/**
|
|
325
|
+
* How long a page that started from cached settings lets its forms wait for the fresh answer: the
|
|
326
|
+
* settings request already in flight, which the edge answers in well under this. Only the forms
|
|
327
|
+
* wait, never the page or its events; a slower answer leaves this page's forms on the cache.
|
|
328
|
+
*/
|
|
329
|
+
const ONSITE_FRESH_MS = 1000;
|
|
330
|
+
|
|
323
331
|
/**
|
|
324
332
|
* Onsite forms, only when the page opted in and the settings have a live one: the runtime is a
|
|
325
|
-
* separate chunk, fetched here and never part of the core.
|
|
333
|
+
* separate chunk, fetched here and never part of the core. A page that started from cached settings
|
|
334
|
+
* judges its forms by the answer it revalidates with, when that comes within ONSITE_FRESH_MS, so a
|
|
335
|
+
* form set live, changed or stopped in the console shows on the next page, not the one after.
|
|
326
336
|
*/
|
|
327
|
-
function startOnsiteForms(client, opted, settings) {
|
|
328
|
-
if (!opted
|
|
329
|
-
|
|
330
|
-
|
|
337
|
+
function startOnsiteForms(client, opted, settings, revalidated) {
|
|
338
|
+
if (!opted) return dropPendingOpens();
|
|
339
|
+
// The chunk is fetched alongside the fresh answer when the cache has a form, so neither waits.
|
|
340
|
+
const early = settings.onsite ? loadOnsite() : null;
|
|
341
|
+
early?.catch(() => {});
|
|
342
|
+
const fresh = revalidated
|
|
343
|
+
? Promise.race([
|
|
344
|
+
revalidated.then((next) => next ?? settings),
|
|
345
|
+
new Promise((resolve) =>
|
|
346
|
+
setTimeout(() => resolve(settings), ONSITE_FRESH_MS),
|
|
347
|
+
),
|
|
348
|
+
])
|
|
349
|
+
: Promise.resolve(settings);
|
|
350
|
+
fresh
|
|
351
|
+
.then((current) => {
|
|
352
|
+
const forms = current.enabled ? current.onsite : null;
|
|
353
|
+
if (!forms) return dropPendingOpens();
|
|
354
|
+
const options = opted === true ? {} : opted;
|
|
355
|
+
return (early ?? loadOnsite()).then((module) =>
|
|
356
|
+
module.startOnsite(client, {
|
|
357
|
+
...options,
|
|
358
|
+
settings: options.settings ?? forms,
|
|
359
|
+
}),
|
|
360
|
+
);
|
|
361
|
+
})
|
|
331
362
|
.catch((err) => {
|
|
332
363
|
dropPendingOpens();
|
|
333
364
|
console.warn('[hp] onsite not started:', err?.message ?? err);
|
|
@@ -356,11 +387,10 @@ async function start(config, options, carry) {
|
|
|
356
387
|
const { writeKey } = config;
|
|
357
388
|
// The visitor's identity may still be looking itself up; it is waited for alongside the
|
|
358
389
|
// settings, never before them. A lookup that fails leaves the visitor anonymous.
|
|
359
|
-
const [{ settings, revalidated,
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
]);
|
|
390
|
+
const [{ settings, revalidated, fetched }, identity] = await Promise.all([
|
|
391
|
+
resolveSettings(config, options),
|
|
392
|
+
Promise.resolve(options.identity).catch(() => null),
|
|
393
|
+
]);
|
|
364
394
|
|
|
365
395
|
// What to cache is the newest answer; when is the first grant. Either may come first.
|
|
366
396
|
let latest = revalidated ? settings : null;
|
|
@@ -373,11 +403,6 @@ async function start(config, options, carry) {
|
|
|
373
403
|
else forgetSettings(writeKey);
|
|
374
404
|
});
|
|
375
405
|
|
|
376
|
-
// Unreachable, or left before the answer: what `hp` queued goes to the next page.
|
|
377
|
-
if (unreachable) {
|
|
378
|
-
dropPendingOpens();
|
|
379
|
-
return null;
|
|
380
|
-
}
|
|
381
406
|
if (!settings.enabled) {
|
|
382
407
|
if (options.debug)
|
|
383
408
|
console.info(
|
|
@@ -386,8 +411,9 @@ async function start(config, options, carry) {
|
|
|
386
411
|
return off(carry);
|
|
387
412
|
}
|
|
388
413
|
// The page's own property, else the source's default; a source with several and no default needs the page's.
|
|
389
|
-
|
|
390
|
-
|
|
414
|
+
// On BUILT_IN the ingest stamps the key's, and quarantines the events of a key with several.
|
|
415
|
+
const propertyId = options.propertyId ?? settings.propertyId ?? null;
|
|
416
|
+
if (!propertyId && settings !== BUILT_IN) {
|
|
391
417
|
console.warn(
|
|
392
418
|
'[hp] not started: this write key covers several properties, so propertyId is required',
|
|
393
419
|
);
|
|
@@ -482,6 +508,9 @@ async function start(config, options, carry) {
|
|
|
482
508
|
|
|
483
509
|
if (typeof window !== 'undefined')
|
|
484
510
|
window[RECOMMENDATION_CONTEXT] = () => client.recommendationContext();
|
|
511
|
+
// The settings and the ingest share a host: one failing says the other likely is too, so what
|
|
512
|
+
// leaves at unload is also kept for the next page.
|
|
513
|
+
fetched?.then((answer) => answer === null && client[UNREACHABLE]());
|
|
485
514
|
|
|
486
515
|
// Before this page's own events: they were made first. Consent here decides, as for any call.
|
|
487
516
|
for (const [method, args, made] of carry.take()) {
|
|
@@ -535,7 +564,7 @@ async function start(config, options, carry) {
|
|
|
535
564
|
|
|
536
565
|
if (identified) client.identify(identified, undefined, IDENTITY_OPTION);
|
|
537
566
|
client.onsite = onsite;
|
|
538
|
-
startOnsiteForms(client, options.onsite, settings);
|
|
567
|
+
startOnsiteForms(client, options.onsite, settings, revalidated);
|
|
539
568
|
return client;
|
|
540
569
|
} catch (err) {
|
|
541
570
|
console.warn('[hp] not started:', err?.message ?? err);
|
package/src/consent-gate.js
CHANGED
|
@@ -98,7 +98,8 @@ function previousFromCookie(name) {
|
|
|
98
98
|
* @param {boolean} [options.debug]
|
|
99
99
|
* @param {{ read: () => any[], write: (items: any[]) => void }} [options.store]
|
|
100
100
|
* Carry held items across pages (`holdAcrossPages`). Read on start, so a grant on the next page
|
|
101
|
-
* releases what the previous one held; cleared on a grant or a
|
|
101
|
+
* releases what the previous one held; written when the page is hidden, cleared on a grant or a
|
|
102
|
+
* refusal.
|
|
102
103
|
*/
|
|
103
104
|
export function createConsentGate(options) {
|
|
104
105
|
const {
|
|
@@ -240,9 +241,12 @@ export function createConsentGate(options) {
|
|
|
240
241
|
*/
|
|
241
242
|
function onHidden(event) {
|
|
242
243
|
if (!awaitingAnswer()) return;
|
|
243
|
-
// With a store, the stored copy is what the next page answers for:
|
|
244
|
-
// discards nothing.
|
|
245
|
-
if (store)
|
|
244
|
+
// With a store, the stored copy is what the next page answers for: written here, once, rather
|
|
245
|
+
// than on every held event, and the end of this page discards nothing.
|
|
246
|
+
if (store) {
|
|
247
|
+
store.write(held);
|
|
248
|
+
return;
|
|
249
|
+
}
|
|
246
250
|
if (event?.type !== 'visibilitychange' && !event?.persisted) discardHeld();
|
|
247
251
|
}
|
|
248
252
|
|
|
@@ -297,7 +301,6 @@ export function createConsentGate(options) {
|
|
|
297
301
|
return false;
|
|
298
302
|
}
|
|
299
303
|
held.push(item);
|
|
300
|
-
store?.write(held);
|
|
301
304
|
return true;
|
|
302
305
|
},
|
|
303
306
|
/** Items unload would lose; the caller's own unload path flushes after this. */
|
package/src/context.js
CHANGED
|
@@ -344,7 +344,8 @@ export const CONTEXT_KEYS = [
|
|
|
344
344
|
|
|
345
345
|
export function sourceContext(cfg) {
|
|
346
346
|
return {
|
|
347
|
-
|
|
347
|
+
// None known (BUILT_IN settings): the ingest stamps the key's.
|
|
348
|
+
...(cfg.propertyId == null ? {} : { property_id: String(cfg.propertyId) }),
|
|
348
349
|
channel: cfg.channel ?? null,
|
|
349
350
|
market: cfg.market ?? null,
|
|
350
351
|
environment: cfg.environment ?? null,
|
package/src/device-storage.js
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
* Two device writes beyond the SDK's own buffers.
|
|
3
3
|
*
|
|
4
4
|
* held store events the consent gate holds for an unanswered CMP, in sessionStorage per
|
|
5
|
-
*
|
|
6
|
-
* them (`holdAcrossPages`, 3.5). They leave only on a
|
|
7
|
-
* comes; a refusal deletes them.
|
|
5
|
+
* write key, so a navigation before the answer (a sign-in redirect) does not lose
|
|
6
|
+
* them (`holdAcrossPages`, 3.5). They leave only on a
|
|
7
|
+
* grant, on whichever page it comes; a refusal deletes them.
|
|
8
8
|
* device cookie Hyper-Personalisation's device id, for a source whose settings say `hp_cookie`
|
|
9
9
|
* (3.6). Under strict consent it is written only once analytics is granted.
|
|
10
10
|
*/
|
|
@@ -33,7 +33,7 @@ const local = () => {
|
|
|
33
33
|
};
|
|
34
34
|
|
|
35
35
|
/**
|
|
36
|
-
* @param {string} key A
|
|
36
|
+
* @param {string} key A write-key-scoped key (storageKey(storageName('held'), writeKey)).
|
|
37
37
|
* @param {() => number} [now]
|
|
38
38
|
*/
|
|
39
39
|
export function createHeldStore(key, now = () => Date.now()) {
|
package/src/index.js
CHANGED
|
@@ -115,6 +115,10 @@ export { emailSha256, getCookie };
|
|
|
115
115
|
|
|
116
116
|
/** How a call made before the SDK started is replayed with the messageId and time it was made at. */
|
|
117
117
|
const REPLAY = Symbol.for('@thg-agentic/hyper-personalisation-web.replay');
|
|
118
|
+
/** How bootstrap tells the client its API could not be reached. Not public API. */
|
|
119
|
+
const UNREACHABLE = Symbol.for(
|
|
120
|
+
'@thg-agentic/hyper-personalisation-web.unreachable',
|
|
121
|
+
);
|
|
118
122
|
/** How ./onsite reads what it needs from a client it was handed. Not public API. */
|
|
119
123
|
const ONSITE_ACCESS = Symbol.for(
|
|
120
124
|
'@thg-agentic/hyper-personalisation-web.onsite-access',
|
|
@@ -309,14 +313,65 @@ function contextOverrides(options) {
|
|
|
309
313
|
return options;
|
|
310
314
|
}
|
|
311
315
|
|
|
316
|
+
/**
|
|
317
|
+
* Before 3.25 the retry buffer and the held store were per property. What a 3.24 page kept there
|
|
318
|
+
* moves to this write key's, oldest first, and the old key goes: the batches keep their messageIds
|
|
319
|
+
* and are replayed as any other, under the same consent rules.
|
|
320
|
+
*/
|
|
321
|
+
function adoptPropertyScopedBuffers(propertyId, writeKey) {
|
|
322
|
+
if (propertyId == null || String(propertyId) === writeKey) return;
|
|
323
|
+
const moves = [
|
|
324
|
+
[
|
|
325
|
+
'localStorage',
|
|
326
|
+
'retry',
|
|
327
|
+
(old, current) => [
|
|
328
|
+
...(Array.isArray(old) ? old : []),
|
|
329
|
+
...(Array.isArray(current) ? current : []),
|
|
330
|
+
],
|
|
331
|
+
],
|
|
332
|
+
[
|
|
333
|
+
'sessionStorage',
|
|
334
|
+
'held',
|
|
335
|
+
(old, current) =>
|
|
336
|
+
current
|
|
337
|
+
? {
|
|
338
|
+
...current,
|
|
339
|
+
items: [...(old.items ?? []), ...(current.items ?? [])],
|
|
340
|
+
}
|
|
341
|
+
: old,
|
|
342
|
+
],
|
|
343
|
+
];
|
|
344
|
+
for (const [store, name, merge] of moves) {
|
|
345
|
+
try {
|
|
346
|
+
const storage = globalThis[store];
|
|
347
|
+
const from = storageKey(storageName(name), propertyId);
|
|
348
|
+
const raw = storage?.getItem(from);
|
|
349
|
+
if (!raw) continue;
|
|
350
|
+
const to = storageKey(storageName(name), writeKey);
|
|
351
|
+
const current = storage.getItem(to);
|
|
352
|
+
storage.setItem(
|
|
353
|
+
to,
|
|
354
|
+
JSON.stringify(
|
|
355
|
+
merge(JSON.parse(raw), current ? JSON.parse(current) : null),
|
|
356
|
+
),
|
|
357
|
+
);
|
|
358
|
+
storage.removeItem(from);
|
|
359
|
+
} catch {
|
|
360
|
+
/* unreadable or full: left where it was */
|
|
361
|
+
}
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
|
|
312
365
|
export function createAnalytics(options) {
|
|
313
366
|
const apiHost = resolveApiHost(options?.apiHost);
|
|
314
367
|
if (!apiHost)
|
|
315
368
|
throw new Error(
|
|
316
369
|
'createAnalytics: apiHost, when given, must be a host or an http(s) origin',
|
|
317
370
|
);
|
|
318
|
-
if (!options?.propertyId)
|
|
319
|
-
throw new Error(
|
|
371
|
+
if (options?.propertyId !== null && !options?.propertyId)
|
|
372
|
+
throw new Error(
|
|
373
|
+
'createAnalytics: propertyId is required (null: the ingest stamps the key’s)',
|
|
374
|
+
);
|
|
320
375
|
|
|
321
376
|
const cfg = {
|
|
322
377
|
libraryName: LIB,
|
|
@@ -341,10 +396,12 @@ export function createAnalytics(options) {
|
|
|
341
396
|
cfg.getConsent = () => (gate ? gate.stamp() : hostConsent());
|
|
342
397
|
const granted = () => !strict || gate?.status === 'granted';
|
|
343
398
|
|
|
344
|
-
|
|
399
|
+
adoptPropertyScopedBuffers(cfg.propertyId, cfg.writeKey);
|
|
400
|
+
// Opt-in (3.5): events held for an unanswered CMP survive a navigation, in sessionStorage. Per
|
|
401
|
+
// write key, as the retry buffer: what they are sent with.
|
|
345
402
|
const heldStore =
|
|
346
403
|
strict && cfg.holdAcrossPages
|
|
347
|
-
? createHeldStore(storageKey(storageName('held'), cfg.
|
|
404
|
+
? createHeldStore(storageKey(storageName('held'), cfg.writeKey))
|
|
348
405
|
: null;
|
|
349
406
|
const carried = heldStore?.read() ?? { items: [], anonymousId: null };
|
|
350
407
|
|
|
@@ -379,9 +436,9 @@ export function createAnalytics(options) {
|
|
|
379
436
|
new Transport({
|
|
380
437
|
apiHost: cfg.apiHost,
|
|
381
438
|
writeKey: cfg.writeKey,
|
|
382
|
-
// Per
|
|
383
|
-
//
|
|
384
|
-
storageKey: storageKey(storageName('retry'), cfg.
|
|
439
|
+
// Per write key, which a replay is sent with: one origin can serve several tenants, and a page
|
|
440
|
+
// started without its property (BUILT_IN settings) is replayed by the next one, which has it.
|
|
441
|
+
storageKey: storageKey(storageName('retry'), cfg.writeKey),
|
|
385
442
|
// Under strict consent, persisting is a device write and replaying is a send: both wait for a
|
|
386
443
|
// grant (see onStatus below, which replays on a grant and clears on a refusal).
|
|
387
444
|
mayPersist: strict ? () => gate?.status === 'granted' : undefined,
|
|
@@ -1098,6 +1155,10 @@ export function createAnalytics(options) {
|
|
|
1098
1155
|
},
|
|
1099
1156
|
};
|
|
1100
1157
|
},
|
|
1158
|
+
/** bootstrap: the settings could not be fetched, so the ingest on the same host is taken as down. */
|
|
1159
|
+
[UNREACHABLE]() {
|
|
1160
|
+
transport.markFailing?.();
|
|
1161
|
+
},
|
|
1101
1162
|
/** `hp` and bootstrap replay a call made before the start through this. Not public API. */
|
|
1102
1163
|
[REPLAY](method, args, made) {
|
|
1103
1164
|
if (typeof this[method] !== 'function') return;
|