@thg-agentic/hyper-personalisation-web 3.31.0 → 3.32.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 +27 -5
- package/dist/hp.min.js +3 -3
- package/dist/onsite-products.min.js +2 -2
- package/dist/onsite-render.min.js +2 -2
- package/dist/onsite-values.min.js +1 -0
- package/dist/onsite.min.js +1 -1
- package/package.json +3 -2
- package/src/index.js +34 -1
- package/src/onsite/index.js +34 -19
- package/src/onsite/money.js +11 -0
- package/src/onsite/preview.js +24 -12
- package/src/onsite/products.js +3 -9
- package/src/onsite/render.js +9 -7
- package/src/onsite/rich-text.js +12 -1
- package/src/onsite/values-loader.js +6 -0
- package/src/onsite/values.js +218 -0
- package/src/onsite-facade.js +20 -2
- package/src/session/record.js +18 -0
- package/src/session/signals.js +4 -0
- package/src/version.js +1 -1
- package/types/onsite-preview.d.ts +27 -0
- package/types/onsite.d.ts +39 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
(()=>{async function Be(o,r,a){let l=b=>Array.from(new Uint8Array(b),w=>w.toString(16).padStart(2,"0")).join(""),p=new TextEncoder,x=o.maxnumber??1e6;for(let b=0;b<=x;b+=256){let w=[];for(let C=b;C<b+256&&C<=x;C++)w.push(crypto.subtle.digest("SHA-256",p.encode(o.salt+C)));let h=(await Promise.all(w)).findIndex(C=>l(C)===o.challenge);if(h>=0)return b+h;if(r&&await r(),a?.aborted)return null}return null}var Ct=()=>globalThis.scheduler?.postTask?.(()=>{},{priority:"user-visible"})??new Promise(o=>setTimeout(o,0)),He=(o,r)=>Be(o,Ct,r);function Tt(o,r){let a=`onmessage=async(e)=>postMessage(await(${Be})(e.data))`,l=URL.createObjectURL(new Blob([a],{type:"text/javascript"}));return new Promise((p,x)=>{let b;try{b=new Worker(l)}catch(h){URL.revokeObjectURL(l),x(h);return}let w=(h,C)=>{b.terminate(),URL.revokeObjectURL(l),h(C)};r.addEventListener("abort",()=>w(p,null),{once:!0}),b.onmessage=h=>w(p,h.data),b.onerror=h=>{h.preventDefault?.(),w(x,h)},b.postMessage({challenge:o.challenge,salt:o.salt,maxnumber:o.maxnumber})})}var Lt=o=>o&&o.algorithm==="SHA-256"&&typeof o.challenge=="string"&&typeof o.salt=="string"&&typeof o.signature=="string";async function
|
|
1
|
+
(()=>{async function Be(o,r,a){let l=b=>Array.from(new Uint8Array(b),w=>w.toString(16).padStart(2,"0")).join(""),p=new TextEncoder,x=o.maxnumber??1e6;for(let b=0;b<=x;b+=256){let w=[];for(let C=b;C<b+256&&C<=x;C++)w.push(crypto.subtle.digest("SHA-256",p.encode(o.salt+C)));let h=(await Promise.all(w)).findIndex(C=>l(C)===o.challenge);if(h>=0)return b+h;if(r&&await r(),a?.aborted)return null}return null}var Ct=()=>globalThis.scheduler?.postTask?.(()=>{},{priority:"user-visible"})??new Promise(o=>setTimeout(o,0)),He=(o,r)=>Be(o,Ct,r);function Tt(o,r){let a=`onmessage=async(e)=>postMessage(await(${Be})(e.data))`,l=URL.createObjectURL(new Blob([a],{type:"text/javascript"}));return new Promise((p,x)=>{let b;try{b=new Worker(l)}catch(h){URL.revokeObjectURL(l),x(h);return}let w=(h,C)=>{b.terminate(),URL.revokeObjectURL(l),h(C)};r.addEventListener("abort",()=>w(p,null),{once:!0}),b.onmessage=h=>w(p,h.data),b.onerror=h=>{h.preventDefault?.(),w(x,h)},b.postMessage({challenge:o.challenge,salt:o.salt,maxnumber:o.maxnumber})})}var Lt=o=>o&&o.algorithm==="SHA-256"&&typeof o.challenge=="string"&&typeof o.salt=="string"&&typeof o.signature=="string";async function Ve(o){if(!Lt(o)||typeof crypto?.subtle?.digest!="function")return null;let r=Date.now(),a=new AbortController,l,p=new Promise(w=>{l=setTimeout(()=>w(null),2e4)}),x=typeof Worker=="function"&&typeof Blob=="function"?Tt(o,a.signal).catch(()=>He(o,a.signal)):He(o,a.signal),b=await Promise.race([x,p]);return clearTimeout(l),a.abort(),typeof b!="number"?null:btoa(JSON.stringify({algorithm:o.algorithm,challenge:o.challenge,number:b,salt:o.salt,signature:o.signature,took:Date.now()-r}))}function X(o){if(typeof o!="string")return null;try{let r=new URL(o);return r.protocol==="https:"?r.href:null}catch{return null}}function K(o){if(typeof o!="string")return null;try{let r=new URL(o);return r.protocol==="https:"||r.protocol==="http:"&&r.hostname==="localhost"?r.href:null}catch{return null}}function be(o,r,a,l){if(typeof r=="string"){o.append(a.createTextNode(r));return}if(l>6||r===null)return;if(Array.isArray(r)){for(let w of r)be(o,w,a,l+1);return}if(typeof r!="object")return;let p="b"in r?"b":"i"in r?"i":"a"in r?"a":null;if(!p)return;let x=p==="a"?X(r.href):null,b=p==="a"&&!x?o:a.createElement(p);x&&(b.setAttribute("href",x),b.setAttribute("rel","noopener")),be(b,r[p],a,l+1),b!==o&&o.append(b)}function Ge(o,r=document){let a=r.createDocumentFragment();return be(a,o,r,0),a}var M=o=>o!==null&&typeof o=="object"&&!Array.isArray(o);function ee(o,r,a){if(typeof a=="string"&&a)return a;let l=M(o?.next?.answers)?o.next.answers:{};for(let p of o?.blocks??[])for(let x of r[p?.question]??[]){let b=l[`${p.question}=${x}`];if(typeof b=="string")return b}return typeof o?.next?.default=="string"?o.next.default:null}var ge={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 Xe(o,r){let a=String(o??"").replace(/[\s.()-]/g,"");a.startsWith("00")&&(a=`+${a.slice(2)}`);let l=ge[String(r??"").toUpperCase()];return!a.startsWith("+")&&l&&(a=`+${l}${a.replace(/^0/,"")}`),/^\+[1-9]\d{7,14}$/.test(a)?a:null}var Ke=o=>/^[^\s@]+@[^\s@]+\.[^\s@]+$/.test(o);function xe(o,r,a,l,p){let x=o("select","i");x.setAttribute("aria-label",r);for(let[b,w]of[["",a],...l]){let h=o("option","",w);h.value=b,h.selected=b===p,x.append(h)}return x}var Ze=o=>{let r=o.options.length;return r<=4?r:r%4?3:4};var ve={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'},ye="cubic-bezier(.16,1,.3,1)",we=`
|
|
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}
|
|
@@ -178,4 +178,4 @@ hr{width:100%;margin:4px 0;border:0;border-top:1px solid var(--ln)}
|
|
|
178
178
|
@keyframes hp-down{from{transform:translateY(-100%)}}
|
|
179
179
|
@keyframes hp-out{to{opacity:0;transform:translateY(12px) scale(.98)}}
|
|
180
180
|
@media (prefers-reduced-motion:reduce){.s .w,.s .ov,.f>*{animation:hp-fade .15s ease both!important}.btn{transition:none}}
|
|
181
|
-
`;var Ot=/^#(?:[0-9a-f]{3}){1,2}$/i,Je=["popup","fullscreen"],Mt=["ok","verify","already"],It=["stack","split","overlay","image-only"],Qe={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},Pt=["xs","sm","md","lg","xl","display"],et={xs:4,sm:8,md:16,lg:28,xl:44},tt={sm:380,md:480,lg:880},qt=["left","center","right"],nt={secondary:" b2",link:" no"},Nt=220,jt=["verify","already","held","fallback","success"],Rt=[500,1500],Dt=600,Ut=1800,S={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"},H=(o,r,a)=>o.includes(r)?r:a,I=(o,r,a)=>Number.isFinite(o)?Math.min(Math.max(o,r),a):null,ke=o=>o.type==="date"||o.type==="number",Ae=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function rt(o){let r=M(o.layout)?o.layout:{},a=M(r.media)?r.media:null,l=H(It,r.template,"stack"),p=a?.side==="right"?"right":"left";return!a&&M(r.image)&&r.image.side!=="none"&&(a=r.image,r.image.side!=="top"&&(l="split",p=r.image.side==="right"?"right":"left")),(!a||!K(a.asset))&&(a=null,l="stack"),{template:l,media:a,side:p,scrim:I(r.scrim,0,.9)??.45,padding:H(["none","sm","md","lg"],r.padding,"md")}}var st=(o,r)=>H(["sm","md","lg","full"],o.size,null)??(r.template==="split"||r.template==="overlay"?"lg":"md"),at=(o,r,a=1,l="100vw")=>{if(o==="fullscreen"||r==="full")return l;let p=o==="teaser"?220:o==="sheet"?400:tt[r]??tt.md;return`(max-width: 639px) ${l}, ${Math.round(p*a)}px`},lt=(o,r)=>o==="lg"?1/Ze(r):.5,ct=(o,r,a)=>{if(!a||!Array.isArray(o.widths)||!r.endsWith(".webp"))return null;let l=o.widths.filter(p=>Number.isInteger(p)&&p>0&&p<a).sort((p,x)=>p-x);return l.length===0?null:[...l.map(p=>`${r.slice(0,-5)}-${p}w.webp ${p}w`),`${r} ${a}w`].join(",")},dt=(o,r)=>o.format==="inline"?"inline":r.format&&r.format!=="inline"?r.format:o.format,Ee=o=>o.kind==="video"||o.t==="video",$e={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},_e=o=>$e[o.split(/[?#]/)[0].split(".").pop().toLowerCase()],Wt=(o,r)=>[...new Set([r,...Array.isArray(o.sources)?o.sources.map(K):[]])].filter(Boolean).sort((a,l)=>(_e(l)===$e.webm)-(_e(a)===$e.webm));function ze(o,r,a,l=new Set){let p=r.steps.find(v=>v.id===a);if(!p)return Promise.resolve();let x=dt(o,r),b=rt(p),w=x==="teaser"&&p===r.steps[0],h=x==="teaser"&&!w?"popup":x,C=st(r.theme,b),$=w?[]:p.blocks.flatMap(v=>{if(v?.t==="image"||v?.t==="video")return[[v]];let W=v?.display==="cards"&&o.questions.find(T=>T.key===v.question&&T.type==="one");return W?Object.values(v.pictures??{}).filter(M).map(T=>[T,lt(C,W),"50vw"]):[]});return b.media&&!(w&&b.template!=="image-only")&&$.push([b.media,b.template==="split"?.46:1]),Promise.all($.map(([v,W,T])=>{let L=K(Ee(v)?v.poster:v.asset);if(!L)return null;let j=document.createElement("img"),y=!Ee(v)&&ct(v,L,I(v.width,1,8192));y&&(j.sizes=at(h,C,W,T),j.srcset=y);let Z=`${j.sizes} ${y||L}`;return l.has(Z)?null:(l.add(Z),j.src=L,j.decode?.().catch(()=>{}))}))}var it=o=>o?.call?o():clearInterval(o),Ft=0,Se=o=>`hp-${o}-${++Ft}`;function d(o,r,a){let l=document.createElement(o);return r&&(l.className=r),a!==void 0&&l.append(Ve(a)),l}var pt=o=>{let r=o.length===4?[...o.slice(1)].map(a=>a+a).join(""):o.slice(1);return[0,2,4].map(a=>Number.parseInt(r.slice(a,a+2),16))},te=o=>{let[r,a,l]=pt(o).map(p=>{let x=p/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*r+.7152*a+.0722*l},ot=(o,r=4.5)=>{let a=te(o)+.05,l=1.05/a;return l>=r?"#fff":a/(te("#111")+.05)>l?"#111":"#fff"};function Yt(o,r){let a=($,v)=>v&&o.style.setProperty($,v),l=$=>Ot.test($??"")?$:null;a("--hp-accent",l(r.accent)),a("--hp-bg",l(r.background)),a("--hp-text",l(r.text));let p=I(r.radius,0,48);p!==null&&a("--hp-radius",`${p}px`),a("--hp-font",r.font==="site"?o.ownerDocument.defaultView.getComputedStyle(o.parentElement??o.ownerDocument.body).fontFamily:Object.hasOwn(ve,r.font)?ve[r.font]:null),l(r.accent)&&(a("--hp-on-accent",ot(r.accent,3)),a("--hp-on-accent-text",ot(r.accent))),l(r.background)&&te(r.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=M(r.overlay)?r.overlay:{},b=[l(r.text),l(r.background)].filter(Boolean).sort(($,v)=>te($)-te(v))[0],[w,h,C]=pt(l(x.colour)??b??"#0b0b0f");a("--hp-ov",`rgb(${w} ${h} ${C} / ${I(x.opacity,0,1)??.6})`)}function Ht(o){try{let r=new CSSStyleSheet;r.replaceSync(we),o.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=we,o.append(r)}}function ut(o){let{form:r,creative:a,decision:l,access:p,client:x,api:b,counters:w}=o,h=o.preview??null,C=e=>{let t=e.blocks.find(i=>i?.t==="email"||i?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},$=dt(r,a),v=a.theme,W=H(Qe[$]??[],v.position,Qe[$]?.[0]),T=document.createElement("hp-onsite");h&&T.setAttribute("preview",""),Yt(T,v);let L=T.attachShadow({mode:"open"});Ht(L);let j=$!=="inline"&&!h,y=d(j?"dialog":$==="inline"?"section":"div"),Z=d("div","ov"),_=d("div","w"),F=d("div","m");h&&(F.dataset.hpMedia="");let Ce=()=>{let e=d("form","f");return e.noValidate=!0,e.addEventListener("submit",St),e.addEventListener("input",()=>{O.textContent&&E.getAttribute("aria-busy")!=="true"&&N(null)}),e},E=Ce(),O=d("p","e");O.id=Se("err"),O.setAttribute("aria-live","assertive");let se=d("div","hd");se.setAttribute("aria-hidden","true"),_.append(se,F,E),y.append(Z,_);let B=$!=="inline"&&d("button","x");B&&(B.type="button",B.addEventListener("click",()=>D("close")),_.append(B),Z.addEventListener("click",()=>D("close"))),L.append(y);let n={step:null,mode:$,size:"md",modal:!1,mobile:h?.device==="mobile",answers:{},answeredOn:{},sent:new Set,clicked:!1,seen:new Set,receipt:null,claim:o.coupon?{code:o.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:o.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=r.locale||document.documentElement.lang,Te=(r.questions.some(ke)||a.steps.some(e=>e.blocks.some(t=>t?.t==="countdown"||t?.display==="cards")))&&o.loadAnswers().catch(()=>null),Le=new WeakMap,Oe=()=>{let e=M(v.button)?v.button:{};y.className=`s ${n.mode}${W?` p-${W}`:""} b-${H(["pill","rounded","square"],e.shape,"rounded")}${n.mobile?" mob":""}${h?" pv":""}${e.style==="outline"?" bo":""}${v.caps===!0?" uc":""}`},Q=h?null:globalThis.matchMedia?.("(max-width: 639px)"),Me=()=>{n.mobile=Q?.matches===!0,pe(),Oe()};Q&&(n.mobile=Q.matches===!0,Q.addEventListener?.("change",Me));let ae=!r.channels?.length,G=(e,t,i={})=>{if(!(h||!l.decision_id||!p.analytics())){if(e==="click"){let s=n.clicked;if(n.clicked=!0,s&&!i.products)return}x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...i})}},N=(e,t)=>{O.className="e",O.textContent=e??"";for(let s of E.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let i=t?.closest("label,fieldset");i&&E.contains(i)?i.after(O):E.append(O),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",O.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},V=e=>{E.setAttribute("aria-busy",String(e));for(let t of E.querySelectorAll("button"))t.disabled=e},Ie=()=>h?Promise.resolve(null):(n.pow??(n.pow=b.challenge().then(e=>e.status===200?Ge(e.body):null).catch(()=>null)),n.pow),le=()=>{for(let e of n.videos)try{document.hidden||Ae()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",le);function ce(e,t,i,s,c){let u=K(e.asset);if(!u)return null;let g=typeof e.alt=="string"?e.alt:"",m;if(Ee(e)){m=d("video",t),m.muted=m.defaultMuted=m.loop=m.playsInline=!0;let A=K(e.poster);A&&(m.poster=A),g?m.setAttribute("aria-label",g):m.setAttribute("aria-hidden","true"),m.autoplay=!Ae()&&!h,m.preload=m.autoplay?"auto":A?"none":"metadata";let z=Wt(e,u);if(z.length>1)for(let P of z){let q=d("source");q.src=P;let Y=_e(P);Y&&(q.type=Y),m.append(q)}else m.src=u;n.videos.push(m)}else{m=d("img",t),m.alt=g,m.decoding="async",m.loading=i?"eager":"lazy",i&&(m.fetchPriority="high");let A=ct(e,u,I(e.width,1,8192));A&&(m.sizes=at(n.mode,n.size,s,c),m.srcset=A),m.src=u}let f=I(e.width,1,8192),k=I(e.height,1,8192);return f&&k&&(m.width=f,m.height=k),M(e.focal)&&(m.style.objectPosition=`${I(e.focal.x,0,100)??50}% ${I(e.focal.y,0,100)??50}%`),m}function Pe(e,t){let i=d("label","l");i.append(d("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let s=d("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",O.id),s.addEventListener("focus",Ie,{once:!0}),t!=="tel")return i.append(s),i;s.id=`${O.id}-p`,i.htmlFor=s.id;let c=xe(d,"Country code","+",Object.entries(ge).map(([g,m])=>[g,`${g} +${m}`]),(e.country||/-(\w\w)$/.exec(J)?.[1]||"").toUpperCase());c.classList.add("cc"),c.name="hp_cc";let u=d("span","ph");return u.append(c,s),i.append(u),i}function ft(e){let t=r.questions.find(f=>f.key===e.question);if(!t||!ke(t)&&!Array.isArray(t.options))return null;let i=d("fieldset");i.dataset.question=t.key,i.append(d("legend","",t.label??""));let s=n.answers[t.key]??[],c=e.display==="cards"&&t.type==="one";if(ke(t)||c)return Te.then(f=>{if(!f)return i.append(d("p","sm",S.unavailable));if(c)return f.answerCards(i,t,e,d,s,k=>ce(k,"qi",!1,lt(n.size,t),"50vw"),L);f.answerFields(i,t,d,s[0],J),Le.set(i,()=>f.answerOf(i,t,void 0,J))}),i;let u=t.type==="many",g=H(["list","dropdown"],e.display,"buttons"),m=t.options.filter(f=>M(f)&&typeof f.value=="string");if(g==="dropdown"&&!u)return i.append(xe(d,t.label??t.key,"\u2014",m.map(f=>[f.value,f.label??f.value]),s[0])),i;g!=="buttons"&&(i.className="ls");for(let f of m){let k=d("label",g==="buttons"?"ch":"c"),A=d("input");A.type=u?"checkbox":"radio",A.name=`q_${t.key}`,A.value=f.value,A.checked=s.includes(f.value),k.append(A,d("span","",f.label??f.value)),i.append(k)}return i}function ne(){for(let e of n.codes){if(e.replaceChildren(),!n.claim){n.unclaimed&&e.append(d("p","",S.unclaimed));continue}if(!n.claim.code){let s=n.claim.held?S.claimed:n.claim.fallback===!0?S.code:n.claim.prize?.label;s&&e.append(d("p","",s));continue}n.claim.prize?.label&&e.append(d("p","",n.claim.prize.label));let t=d("output");t.textContent=n.claim.code;let i=d("button","btn cp");i.type="button",i.textContent="Copy code",i.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{i.textContent=S.copied}).catch(()=>{})}),e.append(t,i)}}function mt(e){if(n.claim&&!n.claim.code)return null;let t=d("div","cd");return t.hidden=!0,Te.then(i=>i&&t.isConnected&&n.timers.push(i.countdown(t,e,h,d))),t}function de(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",i=>{if(h)return i.preventDefault();G("click"),We()}),e}function ht(e){let t=e.label??"Continue";if(e.action==="link"){let s=X(e.href);return s?de(d("a",`btn${nt[e.variant]??""}`,t),s):null}let i=d("button",`btn${nt[e.variant]??""}`,t);return i.type=e.action==="submit"?"submit":"button",i.type==="button"?i.addEventListener("click",()=>re(e)):i.dataset.submit="",i}let qe=(e,t,i)=>(e.classList.add(`x-${H(Pt,t.size,i)}`),qt.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Ne(e){let t=ce(e,"bi",n.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let i=I(e.radius,0,48);i!==null&&(t.style.borderRadius=`${i}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"||!X(e.href))return t;let c=de(d("a","bl"),X(e.href));return c.append(t),c}function bt(e){let t=I(e.threshold,.01,1e7);if(!t)return null;let i=d("div","pg"),s=d("p"),c=d("div","tr"),u=d("i");c.append(u),c.setAttribute("role","progressbar"),c.setAttribute("aria-valuemin","0"),c.setAttribute("aria-valuemax",String(t)),i.append(s,c);let g=f=>f.toFixed(2);try{let f=new Intl.NumberFormat(J||void 0,{style:"currency",currency:e.currency});g=k=>f.format(k)}catch{}let m=()=>{let f=Math.max(0,Number(o.basket?.())||0),k=t-f;s.textContent=k>0?String(e.text??"").replace("{amount}",g(k)):e.done??"",u.style.transform=`scaleX(${Math.min(1,f/t)})`,c.setAttribute("aria-valuenow",String(Math.min(f,t))),s.id||(s.id=Se("pg")),c.setAttribute("aria-labelledby",s.id)};return m(),n.timers.push(setInterval(m,2e3)),i}function gt(e){let t=d("div","pr");return o.loadProducts?.().then(i=>{t.isConnected&&n.timers.push(i.mountProducts(t,e,{el:d,lang:J,root:L,placement:r.slot,preview:h,client:!h&&p.analytics()&&x,engaged:G,seen:n.seen}))}).catch(()=>{}),t}let je={heading(e){let t=qe(d("h2","",e.text),e,"xl");return t.id=Se("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),n.step===a.steps[0]&&Je.includes(n.mode)&&!h&&(t.autofocus=!0)),t},text:e=>qe(d("p","",e.text),e,"md"),email:e=>Pe(e,"email"),phone:e=>Pe(e,"tel"),consent(e){let t=C(n.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return d("p","sm",t);let i=d("label","c"),s=d("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",O.id),i.append(s,d("span","",t)),i},question:ft,wheel(){let e=d("div","wh");return o.loadWheel().then(t=>{n.closed||(n.wheel=t.mountWheel(e,r.prizes))}).catch(()=>{}),e},code(){let e=d("div","k");return e.setAttribute("aria-live","polite"),n.codes.push(e),e},button:ht,decline(e){let t=d("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>D("decline")),t},countdown:mt,progress:bt,products:gt,image:Ne,video:Ne,spacer(e){let t=d("div","sp");return t.style.height=`${et[e.size]??et.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>d("hr")};function xt(e,t){F.replaceChildren();let i=e.media,s=!i||t&&e.template!=="image-only";if(n.size=st(v,e),_.className=`w t-${e.template} z-${n.size}${e.side==="right"?" right":""}${v.text_align==="center"?" ta-center":""}${s?" nm":""}`,_.style.setProperty("--sc",String(e.scrim)),E.className=`f pd-${e.padding}`,F.hidden=s,F.hidden)return;let c=ce(i,"",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=""),F.append(c);return}let u=X(i.href),g=u?de(d("a","io"),u):d("button","io");u||(g.type="button",g.addEventListener("click",()=>re({action:"next"}))),g.append(c),F.append(g)}function yt(e){let t=e.blocks.find(c=>c?.t==="heading"),i=e.blocks.find(c=>c?.t==="button"&&c.action==="next"),s=d("button","tb");return s.textContent=t?d("b","",t.text).textContent:i?.label??"Open",s.type="button",s.addEventListener("click",()=>re(i??{action:"next"})),s}function R(e,t=new Set){let i=a.steps.find(z=>z.id===e);if(!i)return D("done");if(i.kind==="question"&&!h&&!p.analytics()&&!t.has(i.id))return R(ee(i,n.answers),t.add(i.id));let s=n.step!==null,c=s&&(L.activeElement||document.activeElement===document.body),u=s&&!h?{mode:n.mode,w:_.offsetWidth,h:_.offsetHeight,top:_.offsetTop}:null;n.step=i,n.touched=!1;for(let z of n.timers.splice(0))it(z);n.codes=[],n.videos=[],n.wheel=null;let g=$==="teaser"&&i===a.steps[0];if(n.mode=$==="teaser"&&!g?"popup":$,$==="teaser"&&w.tab?.(r.slot,g),B&&B.setAttribute("aria-label",g?S.closeOffer:"Close"),Oe(),y.removeAttribute("aria-labelledby"),u){let z=Ce();E.replaceWith(z),E=z}let m=rt(i);xt(m,g);let f=u?.mode==="popup"&&n.mode==="popup";if(pe(),u?.mode===n.mode&&u.h>0&&!f&&(_.style.setProperty("--lw",`${u.w}px`),_.style.setProperty("--lh",`${u.h}px`),_.classList.add("lk")),E.replaceChildren(),g&&m.template!=="image-only")E.append(yt(i));else for(let[z,P]of i.blocks.entries()){let q=M(P)&&Object.hasOwn(je,P.t)?je[P.t](P):null;q&&(h&&(q.dataset.hpBlock=String(z)),E.append(q))}let k=E.querySelector("[data-submit]"),A=E.querySelector("[name=hp_consent]")?.parentNode;k&&A&&k.before(A),E.hidden=E.childElementCount===0,N(null),ne(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",m.media?.alt?.trim?.()||"Sign up"),f&&u.h>0&&vt(u),s&&Re(),le(),h||wt(i),c&&E.querySelector("h2")?.focus()}function pe(){_.classList.remove("lk","an"),_.style.removeProperty("--tp")}function vt(e){let t=_.offsetHeight;_.classList.add("an");let i=_.offsetTop,s=Math.max(0,e.top-i);if(s+t>y.clientHeight-2*i)return pe();_.style.setProperty("--tp",`${s}px`)}function wt(e){let t=e.next??{};for(let c of[t.default,...Object.values(M(t.answers)?t.answers:{}),...e.blocks.map(u=>u?.next),...jt])typeof c=="string"&&n.toWarm.add(c);if(n.warming)return;n.warming=!0;let i=()=>{if(n.warming=!1,!n.closed&&T.isConnected)for(let c of n.toWarm)ze(r,a,c,n.warmed);n.toWarm.clear()},s=()=>globalThis.requestIdleCallback?requestIdleCallback(i,{timeout:2e3}):setTimeout(i,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function Re(){if(!j)return;let e=Je.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}):T.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function De(){for(let e of E.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,i=Le.get(e)?.()??{};if(i.error)return i;let s=[i.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(c=>c.value)].filter(Boolean);s.length?(n.answers[t]=s,n.answeredOn[t]=n.step.id):delete n.answers[t]}}function Ue(){let e=Object.entries(n.answers).map(([i,s])=>({question:i,values:s})).filter(i=>!n.sent.has(ue(i))),t=({question:i})=>n.answeredOn[i];if(n.signedUp){for(let i of new Set(e.map(t))){let s=e.filter(c=>t(c)===i);for(let c of s)n.sent.add(ue(c));b.answers({anonymousId:p.anonymousId(),sessionId:p.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:i,...n.signedUp,answers:s,context:Fe()})}return}if(p.analytics())for(let i of e)n.sent.add(ue(i)),x.preferencesStated({...i,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t(i)})}let ue=({question:e,values:t})=>`${e}=${t.join(",")}`,We=()=>{ae&&(De(),Ue())},Fe=()=>({page:{url:p.pageUrl()},locale:p.locale()??void 0,consent:p.consent()}),ie=e=>{!h&&(n.receipt||ae)&&Ue(),R(ee(n.step,n.answers,e))};async function kt(e){let t=n.step,i=E.querySelector("input[name=email],input[name=phone]");if(!i)return ie(e.next);let s=i.name==="email"?"email":"sms",c=E.querySelector("select[name=hp_cc]")?.value,u=s==="email"?Ke(i.value.trim())?i.value.trim():null:Xe(i.value,c);if(!u)return N(s==="email"?S.email:c?S.phone:S.intl,i);let g=E.querySelector("input[name=hp_consent]");if(g&&!g.checked)return N(S.consent,g);N(null),V(!0);let m=await Ie();n.pow=null;let f=Object.entries(n.answers).map(([U,he])=>({question:U,values:he})),k=s==="sms"?r.sms_consent_text:r.consent_text,A=await b.capture({anonymousId:p.anonymousId(),sessionId:p.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"]:u,...s==="sms"&&n.signedUp,consent_text:k?{id:k.id,version:k.version}:void 0,...f.length?{answers:f}:{},...m?{altcha:m}:{},context:Fe()}),z=A.body?.status,P=(A.status===202||A.status===200)&&Mt.includes(z);if(n.closed&&!P)return;P||V(!1);let q=A.status===400?A.body?.field:null;if(q==="email"||q==="phone")return N(S[q],i);if(!P)return N(A.status===429?S.busy:S.failed,i);i.value="";for(let[U,he]of Object.entries(n.answers))n.sent.add(`${U}=${he.join(",")}`);n.receipt=typeof A.body.receipt=="string"?A.body.receipt:null,s==="email"&&(n.signedUp={email:u,email_receipt:n.receipt}),n.submitted=!0,w.submitted(r.slot),G("submit",t.id),n.owed=s==="email"&&r.prizes.length>0;let Y=n.owed?fe([]):null;Y||o.emit?.("submitted",{coupon:null});let $t=Y&&await Promise.race([Y,new Promise(U=>setTimeout(U,Dt))]);if(n.closed)return;if(V(!1),$t?.held)return R(oe("held"));let _t=z!=="ok"&&a.steps.some(U=>U.id===z);R(_t?z:ee(t,n.answers,e.next));let zt=n.step;Y?.then(U=>{U?.held&&!n.closed&&n.step===zt&&!n.touched&&R(oe("held"))})}function oe(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:S.shop,action:"close"},i=e==="unclaimed"?[{t:"heading",text:S.thanks},{t:"text",text:S.unclaimed},t]:e==="fallback"||n.claim?.code?[{t:"heading",text:e==="fallback"?S.thanks:S.yours},{t:"code"}]:[{t:"heading",text:S.held},{t:"text",text:r.code_relayed===!0?S.resent:S.inbox},t];return a.steps.push({id:e,blocks:i}),e}function Ye(e){n.owed&&(n.owed=!1,o.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function fe(e=Rt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let i;for(let g of[0,...e])if(g&&await new Promise(m=>setTimeout(m,g)),i=await b.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),i.status!==503)break;let s=i.body,c=s?.fallback===!0&&!s.code;if(i.status!==200||!(M(s?.prize)||c))return n.claiming=null,!e.length&&i.status===503?fe():(Ye(null),n.unclaimed=!0,n.closed||ne(),null);let u=s.held&&!s.code?w.code?.():null;return u&&(s={...s,code:u}),n.claim=s,typeof s.code=="string"&&w.code?.(s.code),Ye(s),n.closed||ne(),s})()),n.claiming}async function At(e){if(!n.receipt)return N(S.spin);V(!0);let t=await fe();if(n.closed)return;if(!t)return V(!1),n.misses+=1,n.misses<2?N(S.retry):R(oe("unclaimed"));let i=t.fallback===!0&&!t.code,s=t.held?-1:r.prizes.findIndex(g=>g.key===t.prize?.key&&g.label===t.prize?.label);if(n.wheel&&s>=0&&!i){if(await n.wheel.spinTo(s),n.closed)return;O.className="e won",O.textContent=`${S.won} ${t.prize.label}`,await new Promise(g=>setTimeout(g,Ut))}if(n.closed)return;V(!1);let c=i?"fallback":s<0?"held":null,u=c?oe(c):ee(n.step,n.answers,e.next);u?R(u):ne()}function re(e){if(e.action==="close")return D("close");let t=De();return h?ie(e.next):t?N(t.error,t.input):(ae&&n.step.blocks.some(i=>n.answers[i?.question])&&G("click"),e.action==="apply"?(o.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),G("click"),ie(e.next)):e.action==="submit"?kt(e):e.action==="spin"?At(e):ie(e.next))}function St(e){if(e.preventDefault(),E.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(i=>i?.t==="button"&&i.action==="submit");re(t??{action:"next"})}function me(e=!1){n.closed=!0;for(let i of n.timers.splice(0))it(i);document.removeEventListener("visibilitychange",le),Q?.removeEventListener?.("change",Me);let t=()=>{try{y.open&&y.close()}catch{}T.remove()};if(e||!j||Ae())return t();y.classList.add("out"),setTimeout(t,Nt)}function D(e){n.closed||h||(We(),!n.submitted&&e!=="done"&&G("dismiss"),w.closed(r.slot),w.tab?.(r.slot,!1),me(),o.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{n.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),D("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!n.modal&&$!=="inline"&&D("esc"),e.key==="Tab"&&n.modal&&Et(e)});function Et(e){let t=[...L.querySelectorAll("input[type=radio]:checked")],i=new Set,s=[...L.querySelectorAll("a[href],button,input,select,textarea")].filter(f=>{if(f.disabled||!f.getClientRects().length)return!1;if(f.type!=="radio")return!0;let k=t.find(A=>A.name===f.name);return(k?f!==k:i.has(f.name))?!1:(i.add(f.name),!0)});if(!s.length)return;let c=e.shiftKey,u=L.activeElement;u?.type==="radio"&&(u=s.find(f=>f.type==="radio"&&f.name===u.name)??u);let g=s.indexOf(u),m=null;if(g<0){let f=k=>u&&u.compareDocumentPosition(k)&4;m=c?s.findLast(k=>!f(k))??s.at(-1):s.find(f)??s[0]}else(c?g===0:g===s.length-1)&&(m=s.at(c?-1:0));m&&(e.preventDefault(),m.focus())}se.addEventListener("pointerdown",e=>{if(!n.mobile||n.mode!=="sheet")return;let t=e.clientY,i=0,s=u=>{i=Math.max(0,u.clientY-t),_.style.transform=`translateY(${i}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),_.style.transform="",i>80&&D("close")};document.addEventListener("pointermove",s),document.addEventListener("pointerup",c)});try{R(h?.step&&a.steps.some(e=>e.id===h.step)?h.step:a.steps[0].id),(o.container??document.body).append(T),Re()}catch(e){throw me(!0),e}return{close:D,root:L,host:T,show:R,step:()=>n.step?.id??null,modal:()=>!n.closed&&n.modal,destroy:()=>!n.closed&&me()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:ut,warm:ze};})();
|
|
181
|
+
`;var Ot=/^#(?:[0-9a-f]{3}){1,2}$/i,Je=["popup","fullscreen"],Mt=["ok","verify","already"],Pt=["stack","split","overlay","image-only"],Qe={bar:["bottom","top"],sheet:["bottom-right","bottom-left","bottom"],teaser:["bottom-left","bottom-right","left","right"]},It=["xs","sm","md","lg","xl","display"],et={xs:4,sm:8,md:16,lg:28,xl:44},tt={sm:380,md:480,lg:880},qt=["left","center","right"],nt={secondary:" b2",link:" no"},Nt=220,jt=["verify","already","held","fallback","success"],Rt=[500,1500],Dt=600,Ut=1800,S={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"},H=(o,r,a)=>o.includes(r)?r:a,I=(o,r,a)=>Number.isFinite(o)?Math.min(Math.max(o,r),a):null,ke=o=>o.type==="date"||o.type==="number",Ae=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function rt(o){let r=M(o.layout)?o.layout:{},a=M(r.media)?r.media:null,l=H(Pt,r.template,"stack"),p=a?.side==="right"?"right":"left";return!a&&M(r.image)&&r.image.side!=="none"&&(a=r.image,r.image.side!=="top"&&(l="split",p=r.image.side==="right"?"right":"left")),(!a||!K(a.asset))&&(a=null,l="stack"),{template:l,media:a,side:p,scrim:I(r.scrim,0,.9)??.45,padding:H(["none","sm","md","lg"],r.padding,"md")}}var st=(o,r)=>H(["sm","md","lg","full"],o.size,null)??(r.template==="split"||r.template==="overlay"?"lg":"md"),at=(o,r,a=1,l="100vw")=>{if(o==="fullscreen"||r==="full")return l;let p=o==="teaser"?220:o==="sheet"?400:tt[r]??tt.md;return`(max-width: 639px) ${l}, ${Math.round(p*a)}px`},lt=(o,r)=>o==="lg"?1/Ze(r):.5,ct=(o,r,a)=>{if(!a||!Array.isArray(o.widths)||!r.endsWith(".webp"))return null;let l=o.widths.filter(p=>Number.isInteger(p)&&p>0&&p<a).sort((p,x)=>p-x);return l.length===0?null:[...l.map(p=>`${r.slice(0,-5)}-${p}w.webp ${p}w`),`${r} ${a}w`].join(",")},dt=(o,r)=>o.format==="inline"?"inline":r.format&&r.format!=="inline"?r.format:o.format,Ee=o=>o.kind==="video"||o.t==="video",_e={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},$e=o=>_e[o.split(/[?#]/)[0].split(".").pop().toLowerCase()],Wt=(o,r)=>[...new Set([r,...Array.isArray(o.sources)?o.sources.map(K):[]])].filter(Boolean).sort((a,l)=>($e(l)===_e.webm)-($e(a)===_e.webm));function ze(o,r,a,l=new Set){let p=r.steps.find(v=>v.id===a);if(!p)return Promise.resolve();let x=dt(o,r),b=rt(p),w=x==="teaser"&&p===r.steps[0],h=x==="teaser"&&!w?"popup":x,C=st(r.theme,b),_=w?[]:p.blocks.flatMap(v=>{if(v?.t==="image"||v?.t==="video")return[[v]];let F=v?.display==="cards"&&o.questions.find(T=>T.key===v.question&&T.type==="one");return F?Object.values(v.pictures??{}).filter(M).map(T=>[T,lt(C,F),"50vw"]):[]});return b.media&&!(w&&b.template!=="image-only")&&_.push([b.media,b.template==="split"?.46:1]),Promise.all(_.map(([v,F,T])=>{let L=K(Ee(v)?v.poster:v.asset);if(!L)return null;let R=document.createElement("img"),y=!Ee(v)&&ct(v,L,I(v.width,1,8192));y&&(R.sizes=at(h,C,F,T),R.srcset=y);let Z=`${R.sizes} ${y||L}`;return l.has(Z)?null:(l.add(Z),R.src=L,R.decode?.().catch(()=>{}))}))}var it=o=>o?.call?o():clearInterval(o),Ft=0,Se=o=>`hp-${o}-${++Ft}`;function d(o,r,a){let l=document.createElement(o);return r&&(l.className=r),a!==void 0&&l.append(Ge(a)),l}var pt=o=>{let r=o.length===4?[...o.slice(1)].map(a=>a+a).join(""):o.slice(1);return[0,2,4].map(a=>Number.parseInt(r.slice(a,a+2),16))},te=o=>{let[r,a,l]=pt(o).map(p=>{let x=p/255;return x<=.04045?x/12.92:((x+.055)/1.055)**2.4});return .2126*r+.7152*a+.0722*l},ot=(o,r=4.5)=>{let a=te(o)+.05,l=1.05/a;return l>=r?"#fff":a/(te("#111")+.05)>l?"#111":"#fff"};function Yt(o,r){let a=(_,v)=>v&&o.style.setProperty(_,v),l=_=>Ot.test(_??"")?_:null;a("--hp-accent",l(r.accent)),a("--hp-bg",l(r.background)),a("--hp-text",l(r.text));let p=I(r.radius,0,48);p!==null&&a("--hp-radius",`${p}px`),a("--hp-font",r.font==="site"?o.ownerDocument.defaultView.getComputedStyle(o.parentElement??o.ownerDocument.body).fontFamily:Object.hasOwn(ve,r.font)?ve[r.font]:null),l(r.accent)&&(a("--hp-on-accent",ot(r.accent,3)),a("--hp-on-accent-text",ot(r.accent))),l(r.background)&&te(r.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=M(r.overlay)?r.overlay:{},b=[l(r.text),l(r.background)].filter(Boolean).sort((_,v)=>te(_)-te(v))[0],[w,h,C]=pt(l(x.colour)??b??"#0b0b0f");a("--hp-ov",`rgb(${w} ${h} ${C} / ${I(x.opacity,0,1)??.6})`)}function Ht(o){try{let r=new CSSStyleSheet;r.replaceSync(we),o.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=we,o.append(r)}}function ut(o){let{form:r,creative:a,decision:l,access:p,client:x,api:b,counters:w}=o,h=o.preview??null,C=e=>{let t=e.blocks.find(i=>i?.t==="email"||i?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},_=dt(r,a),v=a.theme,F=H(Qe[_]??[],v.position,Qe[_]?.[0]),T=document.createElement("hp-onsite");h&&T.setAttribute("preview",""),Yt(T,v);let L=T.attachShadow({mode:"open"});Ht(L);let R=_!=="inline"&&!h,y=d(R?"dialog":_==="inline"?"section":"div"),Z=d("div","ov"),$=d("div","w"),Y=d("div","m");h&&(Y.dataset.hpMedia="");let Ce=()=>{let e=d("form","f");return e.noValidate=!0,e.addEventListener("submit",St),e.addEventListener("input",()=>{O.textContent&&E.getAttribute("aria-busy")!=="true"&&N(null)}),e},E=Ce(),O=d("p","e");O.id=Se("err"),O.setAttribute("aria-live","assertive");let se=d("div","hd");se.setAttribute("aria-hidden","true"),$.append(se,Y,E),y.append(Z,$);let B=_!=="inline"&&d("button","x");B&&(B.type="button",B.addEventListener("click",()=>U("close")),$.append(B),Z.addEventListener("click",()=>U("close"))),L.append(y);let n={step:null,mode:_,size:"md",modal:!1,mobile:h?.device==="mobile",answers:{},answeredOn:{},sent:new Set,clicked:!1,seen:new Set,receipt:null,claim:o.coupon?{code:o.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:o.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=r.locale||document.documentElement.lang,Te=(r.questions.some(ke)||a.steps.some(e=>e.blocks.some(t=>t?.t==="countdown"||t?.display==="cards")))&&o.loadAnswers().catch(()=>null),Le=new WeakMap,Oe=()=>{let e=M(v.button)?v.button:{};y.className=`s ${n.mode}${F?` p-${F}`:""} b-${H(["pill","rounded","square"],e.shape,"rounded")}${n.mobile?" mob":""}${h?" pv":""}${e.style==="outline"?" bo":""}${v.caps===!0?" uc":""}`},Q=h?null:globalThis.matchMedia?.("(max-width: 639px)"),Me=()=>{n.mobile=Q?.matches===!0,pe(),Oe()};Q&&(n.mobile=Q.matches===!0,Q.addEventListener?.("change",Me));let ae=!r.channels?.length,V=(e,t,i={})=>{if(!(h||!l.decision_id||!p.analytics())){if(e==="click"){let s=n.clicked;if(n.clicked=!0,s&&!i.products)return}x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...i})}},N=(e,t)=>{O.className="e",O.textContent=e??"";for(let s of E.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let i=t?.closest("label,fieldset");i&&E.contains(i)?i.after(O):E.append(O),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",O.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},G=e=>{E.setAttribute("aria-busy",String(e));for(let t of E.querySelectorAll("button"))t.disabled=e},Pe=()=>h?Promise.resolve(null):(n.pow??(n.pow=b.challenge().then(e=>e.status===200?Ve(e.body):null).catch(()=>null)),n.pow),le=()=>{for(let e of n.videos)try{document.hidden||Ae()?e.pause():e.play()?.catch?.(()=>{})}catch{}};document.addEventListener("visibilitychange",le);function ce(e,t,i,s,c){let u=K(e.asset);if(!u)return null;let g=typeof e.alt=="string"?e.alt:"",m;if(Ee(e)){m=d("video",t),m.muted=m.defaultMuted=m.loop=m.playsInline=!0;let A=K(e.poster);A&&(m.poster=A),g?m.setAttribute("aria-label",g):m.setAttribute("aria-hidden","true"),m.autoplay=!Ae()&&!h,m.preload=m.autoplay?"auto":A?"none":"metadata";let j=Wt(e,u);if(j.length>1)for(let z of j){let P=d("source");P.src=z;let q=$e(z);q&&(P.type=q),m.append(P)}else m.src=u;n.videos.push(m)}else{m=d("img",t),m.alt=g,m.decoding="async",m.loading=i?"eager":"lazy",i&&(m.fetchPriority="high");let A=ct(e,u,I(e.width,1,8192));A&&(m.sizes=at(n.mode,n.size,s,c),m.srcset=A),m.src=u}let f=I(e.width,1,8192),k=I(e.height,1,8192);return f&&k&&(m.width=f,m.height=k),M(e.focal)&&(m.style.objectPosition=`${I(e.focal.x,0,100)??50}% ${I(e.focal.y,0,100)??50}%`),m}function Ie(e,t){let i=d("label","l");i.append(d("span","lt",e.label??(t==="email"?"Email":"Mobile number")));let s=d("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",O.id),s.addEventListener("focus",Pe,{once:!0}),t!=="tel")return i.append(s),i;s.id=`${O.id}-p`,i.htmlFor=s.id;let c=xe(d,"Country code","+",Object.entries(ge).map(([g,m])=>[g,`${g} +${m}`]),(e.country||/-(\w\w)$/.exec(J)?.[1]||"").toUpperCase());c.classList.add("cc"),c.name="hp_cc";let u=d("span","ph");return u.append(c,s),i.append(u),i}function ft(e){let t=r.questions.find(f=>f.key===e.question);if(!t||!ke(t)&&!Array.isArray(t.options))return null;let i=d("fieldset");i.dataset.question=t.key,i.append(d("legend","",t.label??""));let s=n.answers[t.key]??[],c=e.display==="cards"&&t.type==="one";if(ke(t)||c)return Te.then(f=>{if(!f)return i.append(d("p","sm",S.unavailable));if(c)return f.answerCards(i,t,e,d,s,k=>ce(k,"qi",!1,lt(n.size,t),"50vw"),L);f.answerFields(i,t,d,s[0],J),Le.set(i,()=>f.answerOf(i,t,void 0,J))}),i;let u=t.type==="many",g=H(["list","dropdown"],e.display,"buttons"),m=t.options.filter(f=>M(f)&&typeof f.value=="string");if(g==="dropdown"&&!u)return i.append(xe(d,t.label??t.key,"\u2014",m.map(f=>[f.value,f.label??f.value]),s[0])),i;g!=="buttons"&&(i.className="ls");for(let f of m){let k=d("label",g==="buttons"?"ch":"c"),A=d("input");A.type=u?"checkbox":"radio",A.name=`q_${t.key}`,A.value=f.value,A.checked=s.includes(f.value),k.append(A,d("span","",f.label??f.value)),i.append(k)}return i}function ne(){for(let e of n.codes){if(e.replaceChildren(),!n.claim){n.unclaimed&&e.append(d("p","",S.unclaimed));continue}if(!n.claim.code){let s=n.claim.held?S.claimed:n.claim.fallback===!0?S.code:n.claim.prize?.label;s&&e.append(d("p","",s));continue}n.claim.prize?.label&&e.append(d("p","",n.claim.prize.label));let t=d("output");t.textContent=n.claim.code;let i=d("button","btn cp");i.type="button",i.textContent="Copy code",i.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{i.textContent=S.copied}).catch(()=>{})}),e.append(t,i)}}function mt(e){if(n.claim&&!n.claim.code)return null;let t=d("div","cd");return t.hidden=!0,Te.then(i=>i&&t.isConnected&&n.timers.push(i.countdown(t,e,h,d))),t}function de(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",i=>{if(h)return i.preventDefault();V("click"),We()}),e}function ht(e){let t=e.label??"Continue";if(e.action==="link"){let s=X(e.href);return s?de(d("a",`btn${nt[e.variant]??""}`,t),s):null}let i=d("button",`btn${nt[e.variant]??""}`,t);return i.type=e.action==="submit"?"submit":"button",i.type==="button"?i.addEventListener("click",()=>re(e)):i.dataset.submit="",i}let qe=(e,t,i)=>(e.classList.add(`x-${H(It,t.size,i)}`),qt.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function Ne(e){let t=ce(e,"bi",n.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let i=I(e.radius,0,48);i!==null&&(t.style.borderRadius=`${i}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"||!X(e.href))return t;let c=de(d("a","bl"),X(e.href));return c.append(t),c}function bt(e){let t=I(e.threshold,.01,1e7);if(!t)return null;let i=d("div","pg"),s=d("p"),c=d("div","tr"),u=d("i");c.append(u),c.setAttribute("role","progressbar"),c.setAttribute("aria-valuemin","0"),c.setAttribute("aria-valuemax",String(t)),i.append(s,c);let g=f=>f.toFixed(2);try{let f=new Intl.NumberFormat(J||void 0,{style:"currency",currency:e.currency});g=k=>f.format(k)}catch{}let m=()=>{let f=Math.max(0,Number(o.basket?.())||0),k=t-f;s.textContent=k>0?String(e.text??"").replace("{amount}",g(k)):e.done??"",u.style.transform=`scaleX(${Math.min(1,f/t)})`,c.setAttribute("aria-valuenow",String(Math.min(f,t))),s.id||(s.id=Se("pg")),c.setAttribute("aria-labelledby",s.id)};return m(),n.timers.push(setInterval(m,2e3)),i}function gt(e){let t=d("div","pr");return o.loadProducts?.().then(i=>{t.isConnected&&n.timers.push(i.mountProducts(t,e,{el:d,lang:J,root:L,placement:r.slot,preview:h,client:!h&&p.analytics()&&x,engaged:V,seen:n.seen}))}).catch(()=>{}),t}let je={heading(e){let t=qe(d("h2","",e.text),e,"xl");return t.id=Se("h"),t.tabIndex=-1,y.hasAttribute("aria-labelledby")||(y.setAttribute("aria-labelledby",t.id),n.step===a.steps[0]&&Je.includes(n.mode)&&!h&&(t.autofocus=!0)),t},text:e=>qe(d("p","",e.text),e,"md"),email:e=>Ie(e,"email"),phone:e=>Ie(e,"tel"),consent(e){let t=C(n.step)?.text;if(typeof t!="string")return null;if(e.required!==!0)return d("p","sm",t);let i=d("label","c"),s=d("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",O.id),i.append(s,d("span","",t)),i},question:ft,wheel(){let e=d("div","wh");return o.loadWheel().then(t=>{n.closed||(n.wheel=t.mountWheel(e,r.prizes))}).catch(()=>{}),e},code(){let e=d("div","k");return e.setAttribute("aria-live","polite"),n.codes.push(e),e},button:ht,decline(e){let t=d("button","btn no",e.label??"No thanks");return t.type="button",t.addEventListener("click",()=>U("decline")),t},countdown:mt,progress:bt,products:gt,image:Ne,video:Ne,spacer(e){let t=d("div","sp");return t.style.height=`${et[e.size]??et.md}px`,t.setAttribute("aria-hidden","true"),t},divider:()=>d("hr")};function xt(e,t){Y.replaceChildren();let i=e.media,s=!i||t&&e.template!=="image-only";if(n.size=st(v,e),$.className=`w t-${e.template} z-${n.size}${e.side==="right"?" right":""}${v.text_align==="center"?" ta-center":""}${s?" nm":""}`,$.style.setProperty("--sc",String(e.scrim)),E.className=`f pd-${e.padding}`,Y.hidden=s,Y.hidden)return;let c=ce(i,"",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=""),Y.append(c);return}let u=X(i.href),g=u?de(d("a","io"),u):d("button","io");u||(g.type="button",g.addEventListener("click",()=>re({action:"next"}))),g.append(c),Y.append(g)}function yt(e){let t=e.find(c=>c?.t==="heading"),i=e.find(c=>c?.t==="button"&&c.action==="next"),s=d("button","tb");return s.textContent=t?d("b","",t.text).textContent:i?.label??"Open",s.type="button",s.addEventListener("click",()=>re(i??{action:"next"})),s}function D(e,t=new Set){let i=a.steps.find(z=>z.id===e);if(!i)return U("done");if(i.kind==="question"&&!h&&!p.analytics()&&!t.has(i.id))return D(ee(i,n.answers),t.add(i.id));let s=n.step!==null,c=s&&(L.activeElement||document.activeElement===document.body),u=s&&!h?{mode:n.mode,w:$.offsetWidth,h:$.offsetHeight,top:$.offsetTop}:null;n.step=i,n.touched=!1;for(let z of n.timers.splice(0))it(z);n.codes=[],n.videos=[],n.wheel=null;let g=_==="teaser"&&i===a.steps[0];if(n.mode=_==="teaser"&&!g?"popup":_,_==="teaser"&&w.tab?.(r.slot,g),B&&B.setAttribute("aria-label",g?S.closeOffer:"Close"),Oe(),y.removeAttribute("aria-labelledby"),u){let z=Ce();E.replaceWith(z),E=z}let m=rt(i);xt(m,g);let f=u?.mode==="popup"&&n.mode==="popup";pe(),u?.mode===n.mode&&u.h>0&&!f&&($.style.setProperty("--lw",`${u.w}px`),$.style.setProperty("--lh",`${u.h}px`),$.classList.add("lk")),E.replaceChildren();let k=i.blocks.map(z=>o.fill?.(z,n.answers)??z);if(g&&m.template!=="image-only")E.append(yt(k));else for(let[z,P]of k.entries()){let q=M(P)&&Object.hasOwn(je,P.t)?je[P.t](P):null;q&&(h&&(q.dataset.hpBlock=String(z)),E.append(q))}let A=E.querySelector("[data-submit]"),j=E.querySelector("[name=hp_consent]")?.parentNode;A&&j&&A.before(j),E.hidden=E.childElementCount===0,N(null),ne(),y.hasAttribute("aria-labelledby")?y.removeAttribute("aria-label"):y.setAttribute("aria-label",m.media?.alt?.trim?.()||"Sign up"),f&&u.h>0&&vt(u),s&&Re(),le(),h||wt(i),c&&E.querySelector("h2")?.focus()}function pe(){$.classList.remove("lk","an"),$.style.removeProperty("--tp")}function vt(e){let t=$.offsetHeight;$.classList.add("an");let i=$.offsetTop,s=Math.max(0,e.top-i);if(s+t>y.clientHeight-2*i)return pe();$.style.setProperty("--tp",`${s}px`)}function wt(e){let t=e.next??{};for(let c of[t.default,...Object.values(M(t.answers)?t.answers:{}),...e.blocks.map(u=>u?.next),...jt])typeof c=="string"&&n.toWarm.add(c);if(n.warming)return;n.warming=!0;let i=()=>{if(n.warming=!1,!n.closed&&T.isConnected)for(let c of n.toWarm)ze(r,a,c,n.warmed);n.toWarm.clear()},s=()=>globalThis.requestIdleCallback?requestIdleCallback(i,{timeout:2e3}):setTimeout(i,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function Re(){if(!R)return;let e=Je.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}):T.blur()}else y.setAttribute("open","");!e||typeof y.showModal!="function"?y.setAttribute("role","dialog"):y.removeAttribute("role")}}function De(){for(let e of E.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,i=Le.get(e)?.()??{};if(i.error)return i;let s=[i.value,...[...e.querySelectorAll("input:checked,select:not([name])")].map(c=>c.value)].filter(Boolean);s.length?(n.answers[t]=s,n.answeredOn[t]=n.step.id):delete n.answers[t]}}function Ue(){let e=Object.entries(n.answers).map(([i,s])=>({question:i,values:s})).filter(i=>!n.sent.has(ue(i))),t=({question:i})=>n.answeredOn[i];if(n.signedUp){for(let i of new Set(e.map(t))){let s=e.filter(c=>t(c)===i);for(let c of s)n.sent.add(ue(c));b.answers({anonymousId:p.anonymousId(),sessionId:p.sessionId()??void 0,slot:l.slot,arm:l.arm??void 0,decision_id:l.decision_id??void 0,step:i,...n.signedUp,answers:s,context:Fe()})}return}if(p.analytics())for(let i of e)n.sent.add(ue(i)),x.preferencesStated({...i,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t(i)})}let ue=({question:e,values:t})=>`${e}=${t.join(",")}`,We=()=>{ae&&(De(),Ue())},Fe=()=>({page:{url:p.pageUrl()},locale:p.locale()??void 0,consent:p.consent()}),ie=e=>{!h&&(n.receipt||ae)&&Ue(),D(ee(n.step,n.answers,e))};async function kt(e){let t=n.step,i=E.querySelector("input[name=email],input[name=phone]");if(!i)return ie(e.next);let s=i.name==="email"?"email":"sms",c=E.querySelector("select[name=hp_cc]")?.value,u=s==="email"?Ke(i.value.trim())?i.value.trim():null:Xe(i.value,c);if(!u)return N(s==="email"?S.email:c?S.phone:S.intl,i);let g=E.querySelector("input[name=hp_consent]");if(g&&!g.checked)return N(S.consent,g);N(null),G(!0);let m=await Pe();n.pow=null;let f=Object.entries(n.answers).map(([W,he])=>({question:W,values:he})),k=s==="sms"?r.sms_consent_text:r.consent_text,A=await b.capture({anonymousId:p.anonymousId(),sessionId:p.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"]:u,...s==="sms"&&n.signedUp,consent_text:k?{id:k.id,version:k.version}:void 0,...f.length?{answers:f}:{},...m?{altcha:m}:{},context:Fe()}),j=A.body?.status,z=(A.status===202||A.status===200)&&Mt.includes(j);if(n.closed&&!z)return;z||G(!1);let P=A.status===400?A.body?.field:null;if(P==="email"||P==="phone")return N(S[P],i);if(!z)return N(A.status===429?S.busy:S.failed,i);i.value="";for(let[W,he]of Object.entries(n.answers))n.sent.add(`${W}=${he.join(",")}`);n.receipt=typeof A.body.receipt=="string"?A.body.receipt:null,s==="email"&&(n.signedUp={email:u,email_receipt:n.receipt}),n.submitted=!0,w.submitted(r.slot),V("submit",t.id),n.owed=s==="email"&&r.prizes.length>0;let q=n.owed?fe([]):null;q||o.emit?.("submitted",{coupon:null});let _t=q&&await Promise.race([q,new Promise(W=>setTimeout(W,Dt))]);if(n.closed)return;if(G(!1),_t?.held)return D(oe("held"));let $t=j!=="ok"&&a.steps.some(W=>W.id===j);D($t?j:ee(t,n.answers,e.next));let zt=n.step;q?.then(W=>{W?.held&&!n.closed&&n.step===zt&&!n.touched&&D(oe("held"))})}function oe(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:S.shop,action:"close"},i=e==="unclaimed"?[{t:"heading",text:S.thanks},{t:"text",text:S.unclaimed},t]:e==="fallback"||n.claim?.code?[{t:"heading",text:e==="fallback"?S.thanks:S.yours},{t:"code"}]:[{t:"heading",text:S.held},{t:"text",text:r.code_relayed===!0?S.resent:S.inbox},t];return a.steps.push({id:e,blocks:i}),e}function Ye(e){n.owed&&(n.owed=!1,o.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function fe(e=Rt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let i;for(let g of[0,...e])if(g&&await new Promise(m=>setTimeout(m,g)),i=await b.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),i.status!==503)break;let s=i.body,c=s?.fallback===!0&&!s.code;if(i.status!==200||!(M(s?.prize)||c))return n.claiming=null,!e.length&&i.status===503?fe():(Ye(null),n.unclaimed=!0,n.closed||ne(),null);let u=s.held&&!s.code?w.code?.():null;return u&&(s={...s,code:u}),n.claim=s,typeof s.code=="string"&&w.code?.(s.code),Ye(s),n.closed||ne(),s})()),n.claiming}async function At(e){if(!n.receipt)return N(S.spin);G(!0);let t=await fe();if(n.closed)return;if(!t)return G(!1),n.misses+=1,n.misses<2?N(S.retry):D(oe("unclaimed"));let i=t.fallback===!0&&!t.code,s=t.held?-1:r.prizes.findIndex(g=>g.key===t.prize?.key&&g.label===t.prize?.label);if(n.wheel&&s>=0&&!i){if(await n.wheel.spinTo(s),n.closed)return;O.className="e won",O.textContent=`${S.won} ${t.prize.label}`,await new Promise(g=>setTimeout(g,Ut))}if(n.closed)return;G(!1);let c=i?"fallback":s<0?"held":null,u=c?oe(c):ee(n.step,n.answers,e.next);u?D(u):ne()}function re(e){if(e.action==="close")return U("close");let t=De();return h?ie(e.next):t?N(t.error,t.input):(ae&&n.step.blocks.some(i=>n.answers[i?.question])&&V("click"),e.action==="apply"?(o.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),V("click"),ie(e.next)):e.action==="submit"?kt(e):e.action==="spin"?At(e):ie(e.next))}function St(e){if(e.preventDefault(),E.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(i=>i?.t==="button"&&i.action==="submit");re(t??{action:"next"})}function me(e=!1){n.closed=!0;for(let i of n.timers.splice(0))it(i);document.removeEventListener("visibilitychange",le),Q?.removeEventListener?.("change",Me);let t=()=>{try{y.open&&y.close()}catch{}T.remove()};if(e||!R||Ae())return t();y.classList.add("out"),setTimeout(t,Nt)}function U(e){n.closed||h||(We(),!n.submitted&&e!=="done"&&V("dismiss"),w.closed(r.slot),w.tab?.(r.slot,!1),me(),o.onClose?.(e))}for(let e of["pointerdown","keydown","input"])y.addEventListener(e,()=>{n.touched=!0});y.addEventListener("cancel",e=>{e.preventDefault(),U("esc")}),y.addEventListener("keydown",e=>{e.key==="Escape"&&!n.modal&&_!=="inline"&&U("esc"),e.key==="Tab"&&n.modal&&Et(e)});function Et(e){let t=[...L.querySelectorAll("input[type=radio]:checked")],i=new Set,s=[...L.querySelectorAll("a[href],button,input,select,textarea")].filter(f=>{if(f.disabled||!f.getClientRects().length)return!1;if(f.type!=="radio")return!0;let k=t.find(A=>A.name===f.name);return(k?f!==k:i.has(f.name))?!1:(i.add(f.name),!0)});if(!s.length)return;let c=e.shiftKey,u=L.activeElement;u?.type==="radio"&&(u=s.find(f=>f.type==="radio"&&f.name===u.name)??u);let g=s.indexOf(u),m=null;if(g<0){let f=k=>u&&u.compareDocumentPosition(k)&4;m=c?s.findLast(k=>!f(k))??s.at(-1):s.find(f)??s[0]}else(c?g===0:g===s.length-1)&&(m=s.at(c?-1:0));m&&(e.preventDefault(),m.focus())}se.addEventListener("pointerdown",e=>{if(!n.mobile||n.mode!=="sheet")return;let t=e.clientY,i=0,s=u=>{i=Math.max(0,u.clientY-t),$.style.transform=`translateY(${i}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),$.style.transform="",i>80&&U("close")};document.addEventListener("pointermove",s),document.addEventListener("pointerup",c)});try{D(h?.step&&a.steps.some(e=>e.id===h.step)?h.step:a.steps[0].id),(o.container??document.body).append(T),Re()}catch(e){throw me(!0),e}return{close:U,root:L,host:T,show:D,step:()=>n.step?.id??null,modal:()=>!n.closed&&n.modal,destroy:()=>!n.closed&&me()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render")]={mountForm:ut,warm:ze};})();
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
(()=>{function v(n,r){try{return new Intl.NumberFormat(n||void 0,{style:"currency",currency:r})}catch{return null}}var A=(n,r=0)=>r<=6&&typeof n=="object"&&!!n&&(Array.isArray(n)?n.some(o=>A(o,r+1)):typeof n.v=="string"||A(n.b??n.i??n.a,r+1));var $=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-values"),F=60,I=new RegExp("[\\u0000-\\u001f\\u007f-\\u009f\\u200b-\\u200f\\u202a-\\u202e\\u2060-\\u206f\\ufeff]","g"),N={basket_value:{style:"money"},basket_items:{style:"number",plural:{one:"item",other:"items"}}},M="answer.",S=["first_name"],_=[["year",31536e6],["month",2592e6],["week",6048e5],["day",864e5],["hour",36e5],["minute",6e4]];function E(n){let r=[...String(n).replace(I,"").replace(/\s+/g," ").trim()];return r.length>F?`${r.slice(0,F-1).join("").trimEnd()}\u2026`:r.join("")}function P(n){try{return Intl.getCanonicalLocales(n||[])[0]}catch{return}}var T=new Map,y=(n,r)=>(T.has(n)||T.set(n,r()),T.get(n));function d(n,r,{lang:o,currency:c,plural:h,now:a}={}){if(n==null||n==="")return null;try{if(r==="date"||r==="relative"){let t=typeof n=="number"?n:Date.parse(n);if(!Number.isFinite(t))return null;if(r==="date")return y(`date ${o}`,()=>new Intl.DateTimeFormat(o,{dateStyle:"medium"})).format(t);let u=t-(a??Date.now()),[i,s]=_.find(([,l])=>Math.abs(u)>=l)??["minute",6e4];return y(`relative ${o}`,()=>new Intl.RelativeTimeFormat(o,{numeric:"auto"})).format(Math.round(u/s),i)}if(r!=="number"&&r!=="money")return E(n)||null;if(typeof n!="number"||!Number.isFinite(n))return null;let m=r==="money"?y(`money ${o} ${c}`,()=>v(o,c)):y(`number ${o}`,()=>new Intl.NumberFormat(o));if(!m)return null;let g=m.format(n);if(!h)return g;let w=y(`plural ${o}`,()=>new Intl.PluralRules(o)).select(n)==="one";return E(`${g} ${(w?h.one:h.other)??""}`)}catch{return null}}function j(n,r,o){let c=P(n.locale||globalThis.document?.documentElement.lang),h=new Map((Array.isArray(n.questions)?n.questions:[]).map(t=>[t?.key,t])),a=null,m=()=>{if(!a){let t=globalThis.window?.[$]??o??{};a={...r.values?.()};for(let u of S)typeof t[u]=="string"&&(a[u]=t[u]);queueMicrotask(()=>{a=null})}return a},g=(t,u)=>{let i=h.get(t),{answers:s}=m();if(!i||!s)return null;let l=u?.[t]??s[t],e=(Array.isArray(l)?l:[]).flatMap(b=>{let f=i.options?.find(p=>p?.value===b)?.label;return typeof f=="string"&&f?[E(f)]:[]});if(!e.length)return null;try{return y(`list ${c}`,()=>new Intl.ListFormat(c,{type:"conjunction"})).format(e)}catch{return e.join(", ")}},w=(t,u)=>{let i=t.v,s=t.format&&typeof t.format=="object"?t.format:N[i],l=i.startsWith(M)?g(i.slice(M.length),u):m()[i];return d(l,s?.style??"text",{lang:c,currency:m().currency,plural:s?.plural})};return(t,u)=>{if(t?.t!=="heading"&&t?.t!=="text"||!A(t.text))return t;let i=!1,s=(e,b)=>{if(typeof e=="string"||b>6)return e;if(Array.isArray(e))return e.map(p=>s(p,b+1));if(!e||typeof e!="object")return e;if(typeof e.v=="string"){let p=w(e,u);return p===null&&(i=!0),p??E(e.fallback??"")}let f="b"in e?"b":"i"in e?"i":"a"in e?"a":null;return f?{...e,[f]:s(e[f],b+1)}:e},l=s(t.text,0);return i&&t.missing==="hide"?!1:{...t,text:l}}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.values")]={fillFor:j};})();
|
package/dist/onsite.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function x(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var G=new Map;function T(e,s){return window[s]?Promise.resolve(window[s]):e?(G.has(s)||G.set(s,new Promise((n,r)=>{let p=document.createElement("script");p.src=e,p.async=!0,p.onload=()=>window[s]?n(window[s]):r(new Error(`${e} did not register`)),p.onerror=()=>r(new Error(`${e} did not load`)),document.head.append(p)}).finally(()=>G.delete(s))),G.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var nt=x("onsite-answers.min.js"),ge=()=>T(nt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var st="/v1/capture/challenge",ot=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:st;function me(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),r=s.servingHost??e.servingHost,p=s.gatewayHost??e.gatewayHost;async function l(c,{method:o="GET",body:i,consent:u=!1,timeoutMs:y}={}){if(!n)return{status:0,body:null};try{let S=await n(c,{method:o,credentials:"omit",signal:y&&AbortSignal.timeout?.(y),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...i?{"content-type":"application/json"}:{},...u?e.headers():{}},...i?{body:JSON.stringify(i)}:{}}),A=null;try{A=await S.json()}catch{}return{status:S.status,body:A}}catch{return{status:0,body:null}}}let h=(c,o)=>l(`${p}/v1/capture${c}`,{method:"POST",body:o}).then(i=>(i.status>=200&&i.status<300&&e.answered?.(o.answers,o.slot),i));return{decide:(c,o,{visitAudiences:i,visitCampaign:u,visitContext:y,timeoutMs:S=3e3}={})=>l(`${r}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,S),body:{slots:[o?{key:c,pin:{experiment:o[0],arm:o[1],split:o[2]}}:c],library:e.library,identifier_value:e.anonymousId()??void 0,session_id:e.sessionId()??void 0,identity_token:e.identityToken?.()??void 0,...e.preview?{preview:e.preview}:{},...i&&{visit_audiences:i.claims,...i.answered?.length&&{answered_audiences:i.answered}},...u?{visit_campaign:u}:{},...y?{visit_context:y}:{}}}),datafile:()=>l(`${r}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>l(`${p}${ot(s.challenge)}`),capture:c=>h("",c),answers:c=>h("/answers",c),claim:c=>l(`${r}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}var it=x("onsite-audiences.min.js"),ye=()=>T(it,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function be(e,s){let n={},r=()=>{try{let l=JSON.parse(e().getItem(s));l&&typeof l=="object"&&(n=l)}catch{}return n};return{read:r,write:l=>{let h=r();l(h),n=h;try{e().setItem(s,JSON.stringify(h))}catch{}}}}function Se(e,s=()=>!0){let n=be(()=>sessionStorage,e),r=be(()=>localStorage,e),p=()=>s()?r:n,l=()=>{let o=r.read();(o.sub!==void 0||o.k!==void 0)&&r.write(i=>{delete i.sub,delete i.k})},h=()=>s()?[n.read(),r.read()]:(l(),[n.read()]),c=(o,i)=>{var u;return o.f??(o.f={}),(u=o.f)[i]??(u[i]={}),o.f[i]};return{seen(o){let i=r.read().f?.[o]??{};return{session:n.read().f?.[o]?.n??0,lifetime:i.n??0,closedAt:i.c??null,submitted:i.s===1}},subscribed:()=>h().some(o=>o.sub===1),shown(o){n.write(i=>{let u=c(i,o);u.n=(u.n??0)+1}),r.write(i=>{let u=c(i,o);u.n=(u.n??0)+1})},closed(o,i=Date.now()){r.write(u=>{c(u,o).c=i})},tab(o,i){n.write(u=>{let y=c(u,o);i?y.t=1:delete y.t})},tabOut:o=>n.read().f?.[o]?.t===1,pin(o,i){if(i===void 0)return n.read().f?.[o]?.p??null;n.write(u=>{c(u,o).p=i})},coveredAt:()=>n.read().o??null,covered(o=Date.now()){n.write(i=>{i.o=o})},code(o,i=Date.now()){if(o===void 0){let[u]=h().flatMap(y=>y.k?[y.k]:[]).sort((y,S)=>S.at-y.at);return u&&i-u.at<14*864e5?u.c:null}return p().write(u=>{u.k={c:o,at:i}}),o},submitted(o){r.write(i=>{c(i,o).s=1}),p().write(i=>{i.sub=1})}}}var rt=x("onsite-products.min.js"),V=()=>T(rt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var lt=x("onsite-render.min.js"),_e=()=>T(lt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var at=["source","medium","campaign","content","term"];var Ae=e=>String(e).trim().toLowerCase();function ct(e,s,n){let r=Ae(e),p=Ae(n);return s==="is"?r===p:s==="contains"&&p!==""&&r.includes(p)}function ve(e,s){return(Array.isArray(e)?e:[]).every(n=>{let r=s?.[n?.field];return!at.includes(n?.field)||typeof r!="string"?!1:[].concat(n.values??[]).some(p=>ct(r,n.match,p))})}var Me=["popup","sheet","bar","teaser","inline","fullscreen"],ut=["entry","exit","scroll","time","idle","inline","manual"],oe=e=>e!=="inline",Ie=e=>e==="popup"||e==="sheet"||e==="fullscreen",E=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),j=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],Ee=e=>Number.isInteger(e)&&e>=0?e:null,dt={field:null,match:null,values:[]},pt=e=>e==null?[]:Array.isArray(e)&&e.every(E)?e:[dt];function Ce(e){if(!E(e)||typeof e.slot!="string"||e.slot==="")return null;let s=E(e.trigger)?e.trigger:{};if(!Me.includes(e.format)||!ut.includes(s.type))return null;let n=E(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:E(e.pages)?e.pages:{},devices:j(e.devices),aliases:j(e.aliases),audiences:j(e.audiences),arrived_from:pt(e.arrived_from),caps:{per_session:Ee(n.per_session),lifetime:Ee(n.lifetime),after_close_days:Number.isFinite(n.after_close_days)?n.after_close_days:null},window:E(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(E):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(E):[]}}var ft=/^[a-z][a-z0-9_-]{0,31}$/;function Oe(e){if(!E(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>E(n)&&ft.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:Me.includes(e.format)?e.format:null,theme:E(e.theme)?e.theme:{},steps:s}}function xe(e,s){let n=String(e).split("*").map(r=>r.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function ht(e,s){let n=j(e?.include);return(!n.length||n.some(r=>xe(r,s)))&&!j(e?.exclude).some(r=>xe(r,s))}function De(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var Te=e=>typeof e=="string"?Date.parse(e):Number.NaN,U=e=>e.trigger.type==="manual";function ie(e,s){let n=[];ht(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),ve(e.arrived_from,s.campaign)||n.push("not from its campaign");let r=Te(e.window.starts_at),p=Te(e.window.ends_at);if((s.now<r||s.now>=p)&&n.push("outside its dates"),e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(c=>s.audiences.includes(c))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||U(e))return n;let{seen:l}=s,{caps:h}=e;return l.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),h.per_session!==null&&l.session>=h.per_session&&n.push("per_session cap"),h.lifetime!==null&&l.lifetime>=h.lifetime&&n.push("lifetime cap"),h.after_close_days!==null&&l.closedAt&&s.now-l.closedAt<h.after_close_days*864e5&&n.push("closed recently"),n}var $e=(e,s)=>s.priority-e.priority;var wt=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function gt(){let e=[];return{on:(r,p,l,h={passive:!0})=>{r.addEventListener(p,l,h),e.push(()=>r.removeEventListener(p,l,h))},later:(r,p)=>{let l=setTimeout(r,p);e.push(()=>clearTimeout(l))},stop:()=>{for(let r of e.splice(0))r()}}}var Ne=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},mt=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function yt({on:e,later:s},n,r,p,l){let h=!1,c=!1,o=null,i=0;s(()=>{h=!0},r.delay_ms??5e3),e(l,"mousemove",u=>{u.clientY>p.innerHeight*.1&&(c=!0),o!==null&&(i=u.clientY-o),o=u.clientY}),e(l,"mouseout",u=>{h&&c&&!u.relatedTarget&&u.clientY<=0&&i<0&&!mt(l)&&n("exit")})}function bt({on:e,later:s},n,r,p,l){let h=!1,c=0,o=p.scrollY,i=Date.now(),u=null,y=null;s(()=>{h=!0},r.delay_ms??5e3),e(p,"scroll",()=>{let S=p.scrollY,A=Date.now();if(c=Math.max(c,Ne(p,l)),S<o){(!u||A-u.t>300)&&(u={y:o,t:i});let M=u.y-S;h&&c>=.3&&M>=120&&M/Math.max(1,A-u.t)>=.5&&n("exit_scroll")}else u=null;o=S,i=A}),e(l,"visibilitychange",()=>{l.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),l.visibilityState!=="hidden"&&(y=null)})}function Pe(e,s,{device:n,win:r=window,doc:p=document}){let l=gt(),h=(e.seconds??30)*1e3;if(e.type==="entry"&&l.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&l.later(()=>s("time"),h),e.type==="exit"&&(n==="mobile"?bt:yt)(l,s,e,r,p),e.type==="scroll"){let c=e.depth??.5;l.on(r,"scroll",()=>Ne(r,p)>=c&&s("scroll"))}if(e.type==="idle"){let c=null,o=()=>{clearTimeout(c),c=setTimeout(()=>s("idle"),h)};o();for(let i of wt)l.on(i==="scroll"?r:p,i,o);return l.on(p,"visibilitychange",o),()=>{clearTimeout(c),l.stop()}}return l.stop}var St=x("onsite-wheel.min.js"),ke=()=>T(St,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var Le=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),W=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),_t=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),At=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),Re=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),Fe={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},vt=new Set(["decision-failed","no-creative","no-code","renderer-failed","products-failed","error"]),je=3e3,Ue={status:0,body:null},Et=1500,We=50,xt=300,Tt=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},Mt=e=>Array.isArray(e?.steps)&&e.steps.some(s=>Array.isArray(s?.blocks)&&s.blocks.some(n=>n?.t==="products"));function Ke(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[W])return window[W];let n=typeof e?.[Le]=="function"?e[Le]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let r=s.settings??n.settings??{};n.started?.(r);let p=me(n,{...s,challenge:r.capture?.challenge}),l=n.preview?Fe:Se(n.storageKey,n.personalisation),h=()=>n.campaign?.()??null,c=new Map,o=()=>window[Re]?.size>0,i=(t,a)=>{for(let d of window[At]?.[t]??[])try{d(a)}catch(f){console.warn(`[hp] onsite ${t} listener failed:`,f)}},u=De(window),y=n.debug||s.debug===!0||Tt(),S=new Map,A=new Map,M=[];for(let t of Array.isArray(r.forms)?r.forms:[]){let a=Ce(t);a?M.push(a):S.set(String(t?.slot??`form ${S.size+1}`),{slot:String(t?.slot??""),state:"invalid",code:"invalid",reasons:["not a form this SDK can show"]})}let re=()=>ye().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&M.some(t=>t.audiences.length>0)&&re().then(t=>t?.prefetch(p));let N=new Map,K=new Map,I=null,le=!1,ae=new Set,He=t=>{for(let a of N.keys()){let d=c.get(a);if(!t||!d||d.modal?.())return a}return null},H=null,q=new Set,B=Number.isInteger(r.overlay_gap_minutes)?r.overlay_gap_minutes:0,Ye=()=>{let t=l.coveredAt();if(!(B>0)||typeof t!="number")return null;let a=Math.max(0,Math.floor((Date.now()-t)/6e4));return a<B?`a popup showed ${a} min ago; ${B} min between them`:null},P=new Set,Y=new Map,b=(t,a,d,f=[])=>(S.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:a,code:d,reasons:f}),y&&console.info(`[hp] onsite ${t.slot}: ${a}${f.length?` (${f.join("; ")})`:""}`),{state:a,code:d}),D=(t,a,d,f)=>(N.delete(t.slot),b(t,a,d,f)),k=(t,a,d)=>{let f;return Promise.race([t,new Promise(m=>{f=setTimeout(m,a-Date.now(),d)})]).then(m=>Date.now()>a?d:m).finally(()=>clearTimeout(f))},Xe=(t,a)=>{le||o()||(I??(I=t.slot),i("nothing",{slot:t.slot,format:t.format,code:a}))},ce=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},ue=t=>({path:location.pathname,device:u,campaign:h(),now:Date.now(),seen:l.seen(t.slot),subscribed:l.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:ce()}),J=t=>{A.get(t.slot)?.(),A.delete(t.slot)};function L(t,a,d=!1,f=U(t),m=Date.now()+je){if(c.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:f});let g=K.get(t.slot);return g?(g.asked||(g.asked=f),g.done):(g={asked:f},g.done=ze(t,a,d,f,m).catch(v=>c.has(t.slot)?{state:"shown",code:"shown"}:(console.warn("[hp] onsite form failed:",v?.message??v),D(t,"not shown","error",[`failed: ${v?.message??v}`]))).then(v=>(K.delete(t.slot),{...v,asked:g.asked||g.opened})),K.set(t.slot,g),g.done)}async function ze(t,a,d,f,m){if(o())return b(t,"not shown","suppressed",[`suppressed: ${[...window[Re]].join(", ")}`]);let g=ie(t,{...ue(t),...d?{seen:Fe.seen()}:{},asked:f});if(g.length)return b(t,"not eligible","not-eligible",g);let v=Ie(t.format)&&!d,C=v&&!f&&Ye();if(C)return b(t,"not shown","overlay-gap",[C]);if(v&&!n.preview&&n.consentAnswered?.()===!1)return Y.set(t,f),b(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let O=oe(t.format),pe=O&&He(f);if(pe)return b(t,"not shown","another-showing",[`${pe} is showing`]);if(O&&I&&!f)return b(t,"not shown","allowance-spent",[`${I} already showed on this page view`]);let X=null;if(!O){try{X=document.querySelector(t.trigger.selector??"")}catch{X=null}if(!X)return b(t,"not shown","no-element",["no element matches its selector"])}O&&N.set(t.slot,t),J(t),b(t,"asking for a decision","deciding",[a]);let Be=_e().catch(w=>(console.warn("[hp] onsite renderer not loaded:",w?.message??w),null)),z=t.visit_context===!0?V().catch(()=>null):null,Q=ce()??[],fe={claims:[...new Set([...t.audiences,...Q])].filter(w=>Q.includes(w)).slice(0,100)},Je=t.audiences.length>0&&!n.preview&&n.personalisation()?await k(re().then(w=>w?w.visitAudiences(p,n.sessionSignals,t.audiences,Q):fe),Math.min(m,Date.now()+Et),fe):null,F=Date.now()<m?await k(p.decide(t.slot,l.pin(t.slot),{visitAudiences:Je,visitCampaign:t.arrived_from.length?h():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:null,timeoutMs:m-Date.now()}),m,Ue):Ue,ee=F.status===200?F.body?.decisions:null,_=Array.isArray(ee)?ee.find(w=>w?.slot===t.slot):null;_?.experiment&&_.arm&&_.split&&l.pin(t.slot,[_.experiment,_.arm,_.split]);let $=_&&_.holdout!==!0?Oe(_.payload):null,he=$?.steps[0].blocks??[],we=_?.offer?.code??(n.preview?"PREVIEW":l.code()),Ze=n.basketValue?.()??null,te=he.some(w=>w?.t==="code")&&!we&&"no code to remind of"||he.some(w=>w?.t==="progress")&&!(Ze>0)&&"the basket is empty";if(te){let w=te==="the basket is empty";return w&&P.add(t),D(t,"not shown",w?"empty-basket":"no-code",[te])}if(P.delete(t),!$){let w=_?.holdout===!0;return w&&n.analytics()&&e.recordExposure(F.body),O&&w&&(I??(I=t.slot)),w&&!f&&i("held",{slot:t.slot,arm:_.arm??null,format:t.format}),w||Array.isArray(ee)?D(t,w?"held out":"no decision",w?"held-out":"no-creative",["no creative for this visitor"]):D(t,"no decision","decision-failed",[`decisions answered ${F.status}`])}let ne=await k(Be,m,null);if(!ne)return D(t,"not shown","renderer-failed",["the renderer did not load"]);if(Mt($)&&(z??(z=V().catch(()=>null)),!await k(z,m,null)))return D(t,"not shown","products-failed",["its products did not load"]);if(await k(ne.warm?.(t,$,$.steps[0].id,ae),Math.min(m,Date.now()+xt)),o())return D(t,"not shown","suppressed",["suppressed"]);let se=(w,tt={})=>i(w,{slot:t.slot,arm:_.arm??null,format:$.format??t.format,...tt}),Qe=ne.mountForm({form:t,creative:$,decision:_,access:n,client:e,api:p,counters:l,loadWheel:ke,loadAnswers:ge,loadProducts:()=>z??V(),container:X,warmed:ae,coupon:we,basket:()=>n.basketValue?.()??null,emit:se,onClose(w){c.delete(t.slot),N.delete(t.slot),b(t,"closed","closed",[w]),se("closed",{reason:w})}});c.set(t.slot,Qe),d||l.shown(t.slot),v&&l.covered(),O&&(I??(I=t.slot)),n.analytics()&&e.recordExposure(F.body);let et=b(t,"shown","shown",[a]);return se("shown"),et}function Z(t,a,d=U(t)){if(!oe(t.format))return L(t,a,!1,d);if(!H){let f={forms:[],taken:new Set,deadline:Date.now()+We+je};H=f,q.add(f),setTimeout(()=>{H=null,Ge(f)},We)}H.forms.push([t,a,d])}async function Ge(t){let a=t.forms.sort(([f],[m])=>$e(f,m)),d=null;for(let[f,[m,g,v]]of a.entries()){if(t.taken.has(m))continue;let C=await L(m,g,!1,v,t.deadline);if(!d&&vt.has(C.code)&&!C.asked&&(d=[m,C.code]),C.state==="shown"||C.state==="held out"){for(let[O]of a.slice(f+1))b(O,"not shown","lower-priority",[`${m.slot} has a higher priority`]);d=null;break}}q.delete(t),d&&Xe(...d)}for(let t of M){if(t.format==="teaser"&&l.tabOut(t.slot)){L(t,"tab kept from an earlier page",!0);continue}let a=ie(t,ue(t));if(a.length){b(t,"not eligible","not-eligible",a);continue}let d=t.trigger.type;d==="manual"?b(t,"waiting for hp.onsite.open","waiting-for-open"):d==="inline"||t.format==="inline"?L(t,"inline"):de(t)}function de(t){J(t),A.set(t.slot,Pe(t.trigger,a=>{J(t),Z(t,a)},{device:u})),b(t,"armed","armed",[`${t.trigger.type} on ${u}`])}let Ve=n.onConsentAnswered?.(()=>{let t=[...Y];Y.clear();for(let[a,d]of t)c.has(a.slot)||(d?Z(a,"manual",d):de(a))}),qe=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...P];P.clear();for(let a of t)c.has(a.slot)||Z(a,"the basket changed")}),R=Object.freeze({open(t){let a=M.find(g=>g.slot===t),d=a??M.find(g=>g.aliases.includes(t));if(!d)return Promise.resolve(!1);if(c.has(d.slot))return Promise.resolve(!0);for(let g of q)g.taken.add(d);let f=L(d,"manual",!1,U(d)||!a),m=K.get(d.slot);return m&&(m.opened=!0),f.then(({state:g})=>g==="shown")},suppress(){for(let[t,a]of c){a.destroy(),c.delete(t),N.delete(t);let d=M.find(f=>f.slot===t);d&&b(d,"closed","suppressed",["suppressed"])}},debug:()=>[...S.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){le=!0;for(let t of A.values())t();A.clear(),qe?.(),Ve?.(),P.clear(),Y.clear(),window[W]===R&&delete window[W]}});window[W]=R;for(let{slot:t,resolve:a}of window[_t]?.splice(0)??[])a(R.open(t));return y&&console.table?.(R.debug()),R}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:Ke};})();
|
|
1
|
+
(()=>{function E(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var z=new Map;function T(e,s){return window[s]?Promise.resolve(window[s]):e?(z.has(s)||z.set(s,new Promise((n,i)=>{let p=document.createElement("script");p.src=e,p.async=!0,p.onload=()=>window[s]?n(window[s]):i(new Error(`${e} did not register`)),p.onerror=()=>i(new Error(`${e} did not load`)),document.head.append(p)}).finally(()=>z.delete(s))),z.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var ct=E("onsite-answers.min.js"),be=()=>T(ct,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var ut="/v1/capture/challenge",dt=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:ut;function _e(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),i=s.servingHost??e.servingHost,p=s.gatewayHost??e.gatewayHost;async function l(c,{method:o="GET",body:r,consent:u=!1,timeoutMs:y}={}){if(!n)return{status:0,body:null};try{let _=await n(c,{method:o,credentials:"omit",signal:y&&AbortSignal.timeout?.(y),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...r?{"content-type":"application/json"}:{},...u?e.headers():{}},...r?{body:JSON.stringify(r)}:{}}),A=null;try{A=await _.json()}catch{}return{status:_.status,body:A}}catch{return{status:0,body:null}}}let m=(c,o)=>l(`${p}/v1/capture${c}`,{method:"POST",body:o}).then(r=>(r.status>=200&&r.status<300&&e.answered?.(o.answers,o.slot),r));return{decide:(c,o,{visitAudiences:r,visitCampaign:u,visitContext:y,timeoutMs:_=3e3}={})=>l(`${i}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,_),body:{slots:[o?{key:c,pin:{experiment:o[0],arm:o[1],split:o[2]}}:c],library:e.library,identifier_value:e.anonymousId()??void 0,session_id:e.sessionId()??void 0,identity_token:e.identityToken?.()??void 0,...e.preview?{preview:e.preview}:{},...r&&{visit_audiences:r.claims,...r.answered?.length&&{answered_audiences:r.answered}},...u?{visit_campaign:u}:{},...y?{visit_context:y}:{}}}),datafile:()=>l(`${i}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>l(`${p}${dt(s.challenge)}`),capture:c=>m("",c),answers:c=>m("/answers",c),claim:c=>l(`${i}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}var pt=E("onsite-audiences.min.js"),Se=()=>T(pt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function Ae(e,s){let n={},i=()=>{try{let l=JSON.parse(e().getItem(s));l&&typeof l=="object"&&(n=l)}catch{}return n};return{read:i,write:l=>{let m=i();l(m),n=m;try{e().setItem(s,JSON.stringify(m))}catch{}}}}function ve(e,s=()=>!0){let n=Ae(()=>sessionStorage,e),i=Ae(()=>localStorage,e),p=()=>s()?i:n,l=()=>{let o=i.read();(o.sub!==void 0||o.k!==void 0)&&i.write(r=>{delete r.sub,delete r.k})},m=()=>s()?[n.read(),i.read()]:(l(),[n.read()]),c=(o,r)=>{var u;return o.f??(o.f={}),(u=o.f)[r]??(u[r]={}),o.f[r]};return{seen(o){let r=i.read().f?.[o]??{};return{session:n.read().f?.[o]?.n??0,lifetime:r.n??0,closedAt:r.c??null,submitted:r.s===1}},subscribed:()=>m().some(o=>o.sub===1),shown(o){n.write(r=>{let u=c(r,o);u.n=(u.n??0)+1}),i.write(r=>{let u=c(r,o);u.n=(u.n??0)+1})},closed(o,r=Date.now()){i.write(u=>{c(u,o).c=r})},tab(o,r){n.write(u=>{let y=c(u,o);r?y.t=1:delete y.t})},tabOut:o=>n.read().f?.[o]?.t===1,pin(o,r){if(r===void 0)return n.read().f?.[o]?.p??null;n.write(u=>{c(u,o).p=r})},coveredAt:()=>n.read().o??null,covered(o=Date.now()){n.write(r=>{r.o=o})},code(o,r=Date.now()){if(o===void 0){let[u]=m().flatMap(y=>y.k?[y.k]:[]).sort((y,_)=>_.at-y.at);return u&&r-u.at<14*864e5?u.c:null}return p().write(u=>{u.k={c:o,at:r}}),o},submitted(o){i.write(r=>{c(r,o).s=1}),p().write(r=>{r.sub=1})}}}var ft=E("onsite-products.min.js"),G=()=>T(ft,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var ht=E("onsite-render.min.js"),Ee=()=>T(ht,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var q=(e,s=0)=>s<=6&&typeof e=="object"&&!!e&&(Array.isArray(e)?e.some(n=>q(n,s+1)):typeof e.v=="string"||q(e.b??e.i??e.a,s+1));var mt=["source","medium","campaign","content","term"];var Te=e=>String(e).trim().toLowerCase();function gt(e,s,n){let i=Te(e),p=Te(n);return s==="is"?i===p:s==="contains"&&p!==""&&i.includes(p)}function xe(e,s){return(Array.isArray(e)?e:[]).every(n=>{let i=s?.[n?.field];return!mt.includes(n?.field)||typeof i!="string"?!1:[].concat(n.values??[]).some(p=>gt(i,n.match,p))})}var De=["popup","sheet","bar","teaser","inline","fullscreen"],wt=["entry","exit","scroll","time","idle","inline","manual"],ie=e=>e!=="inline",Oe=e=>e==="popup"||e==="sheet"||e==="fullscreen",x=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),j=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],Me=e=>Number.isInteger(e)&&e>=0?e:null,yt={field:null,match:null,values:[]},bt=e=>e==null?[]:Array.isArray(e)&&e.every(x)?e:[yt];function Pe(e){if(!x(e)||typeof e.slot!="string"||e.slot==="")return null;let s=x(e.trigger)?e.trigger:{};if(!De.includes(e.format)||!wt.includes(s.type))return null;let n=x(e.caps)?e.caps:{};return{...e,trigger:s,priority:Number.isFinite(e.priority)?e.priority:0,pages:x(e.pages)?e.pages:{},devices:j(e.devices),aliases:j(e.aliases),audiences:j(e.audiences),arrived_from:bt(e.arrived_from),caps:{per_session:Me(n.per_session),lifetime:Me(n.lifetime),after_close_days:Number.isFinite(n.after_close_days)?n.after_close_days:null},window:x(e.window)?e.window:{},questions:Array.isArray(e.questions)?e.questions.filter(x):[],prizes:Array.isArray(e.prizes)?e.prizes.filter(x):[]}}var _t=/^[a-z][a-z0-9_-]{0,31}$/;function Ne(e){if(!x(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>x(n)&&_t.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:De.includes(e.format)?e.format:null,theme:x(e.theme)?e.theme:{},steps:s}}function Ie(e,s){let n=String(e).split("*").map(i=>i.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function St(e,s){let n=j(e?.include);return(!n.length||n.some(i=>Ie(i,s)))&&!j(e?.exclude).some(i=>Ie(i,s))}function $e(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var Ce=e=>typeof e=="string"?Date.parse(e):Number.NaN,U=e=>e.trigger.type==="manual";function le(e,s){let n=[];St(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),xe(e.arrived_from,s.campaign)||n.push("not from its campaign");let i=Ce(e.window.starts_at),p=Ce(e.window.ends_at);if((s.now<i||s.now>=p)&&n.push("outside its dates"),e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(c=>s.audiences.includes(c))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||U(e))return n;let{seen:l}=s,{caps:m}=e;return l.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),m.per_session!==null&&l.session>=m.per_session&&n.push("per_session cap"),m.lifetime!==null&&l.lifetime>=m.lifetime&&n.push("lifetime cap"),m.after_close_days!==null&&l.closedAt&&s.now-l.closedAt<m.after_close_days*864e5&&n.push("closed recently"),n}var ke=(e,s)=>s.priority-e.priority;var At=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function vt(){let e=[];return{on:(i,p,l,m={passive:!0})=>{i.addEventListener(p,l,m),e.push(()=>i.removeEventListener(p,l,m))},later:(i,p)=>{let l=setTimeout(i,p);e.push(()=>clearTimeout(l))},stop:()=>{for(let i of e.splice(0))i()}}}var Le=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},Et=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function Tt({on:e,later:s},n,i,p,l){let m=!1,c=!1,o=null,r=0;s(()=>{m=!0},i.delay_ms??5e3),e(l,"mousemove",u=>{u.clientY>p.innerHeight*.1&&(c=!0),o!==null&&(r=u.clientY-o),o=u.clientY}),e(l,"mouseout",u=>{m&&c&&!u.relatedTarget&&u.clientY<=0&&r<0&&!Et(l)&&n("exit")})}function xt({on:e,later:s},n,i,p,l){let m=!1,c=0,o=p.scrollY,r=Date.now(),u=null,y=null;s(()=>{m=!0},i.delay_ms??5e3),e(p,"scroll",()=>{let _=p.scrollY,A=Date.now();if(c=Math.max(c,Le(p,l)),_<o){(!u||A-u.t>300)&&(u={y:o,t:r});let M=u.y-_;m&&c>=.3&&M>=120&&M/Math.max(1,A-u.t)>=.5&&n("exit_scroll")}else u=null;o=_,r=A}),e(l,"visibilitychange",()=>{l.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),l.visibilityState!=="hidden"&&(y=null)})}function Re(e,s,{device:n,win:i=window,doc:p=document}){let l=vt(),m=(e.seconds??30)*1e3;if(e.type==="entry"&&l.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&l.later(()=>s("time"),m),e.type==="exit"&&(n==="mobile"?xt:Tt)(l,s,e,i,p),e.type==="scroll"){let c=e.depth??.5;l.on(i,"scroll",()=>Le(i,p)>=c&&s("scroll"))}if(e.type==="idle"){let c=null,o=()=>{clearTimeout(c),c=setTimeout(()=>s("idle"),m)};o();for(let r of At)l.on(r==="scroll"?i:p,r,o);return l.on(p,"visibilitychange",o),()=>{clearTimeout(c),l.stop()}}return l.stop}var Mt=E("onsite-values.min.js"),Fe=()=>T(Mt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.values"));var It=E("onsite-wheel.min.js"),je=()=>T(It,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var Ue=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),H=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),Ct=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),Dt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),He=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),We={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},Ot=new Set(["decision-failed","no-creative","no-code","renderer-failed","products-failed","values-failed","error"]),Xe=3e3,Ke={status:0,body:null},Pt=1500,Ve=50,Nt=300,$t=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},Ye=(e,s)=>e.steps.some(n=>n.blocks.some(s));function ze(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[H])return window[H];let n=typeof e?.[Ue]=="function"?e[Ue]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let i=s.settings??n.settings??{};n.started?.(i);let p=_e(n,{...s,challenge:i.capture?.challenge}),l=n.preview?We:ve(n.storageKey,n.personalisation),m=()=>n.campaign?.()??null,c=new Map,o=()=>window[He]?.size>0,r=(t,a)=>{for(let d of window[Dt]?.[t]??[])try{d(a)}catch(f){console.warn(`[hp] onsite ${t} listener failed:`,f)}},u=$e(window),y=n.debug||s.debug===!0||$t(),_=new Map,A=new Map,M=[];for(let t of Array.isArray(i.forms)?i.forms:[]){let a=Pe(t);a?M.push(a):_.set(String(t?.slot??`form ${_.size+1}`),{slot:String(t?.slot??""),state:"invalid",code:"invalid",reasons:["not a form this SDK can show"]})}let ae=()=>Se().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&M.some(t=>t.audiences.length>0)&&ae().then(t=>t?.prefetch(p));let $=new Map,W=new Map,I=null,ce=!1,ue=new Set,Ge=t=>{for(let a of $.keys()){let d=c.get(a);if(!t||!d||d.modal?.())return a}return null},X=null,B=new Set,J=Number.isInteger(i.overlay_gap_minutes)?i.overlay_gap_minutes:0,qe=()=>{let t=l.coveredAt();if(!(J>0)||typeof t!="number")return null;let a=Math.max(0,Math.floor((Date.now()-t)/6e4));return a<J?`a popup showed ${a} min ago; ${J} min between them`:null},k=new Set,K=new Map,b=(t,a,d,f=[])=>(_.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:a,code:d,reasons:f}),y&&console.info(`[hp] onsite ${t.slot}: ${a}${f.length?` (${f.join("; ")})`:""}`),{state:a,code:d}),C=(t,a,d,f)=>($.delete(t.slot),b(t,a,d,f)),N=(t,a,d)=>{let f;return Promise.race([t,new Promise(g=>{f=setTimeout(g,a-Date.now(),d)})]).then(g=>Date.now()>a?d:g).finally(()=>clearTimeout(f))},Be=(t,a)=>{ce||o()||(I??(I=t.slot),r("nothing",{slot:t.slot,format:t.format,code:a}))},de=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},pe=t=>({path:location.pathname,device:u,campaign:m(),now:Date.now(),seen:l.seen(t.slot),subscribed:l.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:de()}),Z=t=>{A.get(t.slot)?.(),A.delete(t.slot)};function L(t,a,d=!1,f=U(t),g=Date.now()+Xe){if(c.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:f});let w=W.get(t.slot);return w?(w.asked||(w.asked=f),w.done):(w={asked:f},w.done=Je(t,a,d,f,g).catch(v=>c.has(t.slot)?{state:"shown",code:"shown"}:(console.warn("[hp] onsite form failed:",v?.message??v),C(t,"not shown","error",[`failed: ${v?.message??v}`]))).then(v=>(W.delete(t.slot),{...v,asked:w.asked||w.opened})),W.set(t.slot,w),w.done)}async function Je(t,a,d,f,g){if(o())return b(t,"not shown","suppressed",[`suppressed: ${[...window[He]].join(", ")}`]);let w=le(t,{...pe(t),...d?{seen:We.seen()}:{},asked:f});if(w.length)return b(t,"not eligible","not-eligible",w);let v=Oe(t.format)&&!d,D=v&&!f&&qe();if(D)return b(t,"not shown","overlay-gap",[D]);if(v&&!n.preview&&n.consentAnswered?.()===!1)return K.set(t,f),b(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let O=ie(t.format),he=O&&Ge(f);if(he)return b(t,"not shown","another-showing",[`${he} is showing`]);if(O&&I&&!f)return b(t,"not shown","allowance-spent",[`${I} already showed on this page view`]);let V=null;if(!O){try{V=document.querySelector(t.trigger.selector??"")}catch{V=null}if(!V)return b(t,"not shown","no-element",["no element matches its selector"])}O&&$.set(t.slot,t),Z(t),b(t,"asking for a decision","deciding",[a]);let tt=Ee().catch(h=>(console.warn("[hp] onsite renderer not loaded:",h?.message??h),null)),Y=t.visit_context===!0?G().catch(()=>null):null,ee=de()??[],me={claims:[...new Set([...t.audiences,...ee])].filter(h=>ee.includes(h)).slice(0,100)},nt=t.audiences.length>0&&!n.preview&&n.personalisation()?await N(ae().then(h=>h?h.visitAudiences(p,n.sessionSignals,t.audiences,ee):me),Math.min(g,Date.now()+Pt),me):null,F=Date.now()<g?await N(p.decide(t.slot,l.pin(t.slot),{visitAudiences:nt,visitCampaign:t.arrived_from.length?m():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:null,timeoutMs:g-Date.now()}),g,Ke):Ke,te=F.status===200?F.body?.decisions:null,S=Array.isArray(te)?te.find(h=>h?.slot===t.slot):null;S?.experiment&&S.arm&&S.split&&l.pin(t.slot,[S.experiment,S.arm,S.split]);let P=S&&S.holdout!==!0?Ne(S.payload):null,ge=P?.steps[0].blocks??[],we=S?.offer?.code??(n.preview?"PREVIEW":l.code()),st=n.basketValue?.()??null,ne=ge.some(h=>h?.t==="code")&&!we&&"no code to remind of"||ge.some(h=>h?.t==="progress")&&!(st>0)&&"the basket is empty";if(ne){let h=ne==="the basket is empty";return h&&k.add(t),C(t,"not shown",h?"empty-basket":"no-code",[ne])}if(k.delete(t),!P){let h=S?.holdout===!0;return h&&n.analytics()&&e.recordExposure(F.body),O&&h&&(I??(I=t.slot)),h&&!f&&r("held",{slot:t.slot,arm:S.arm??null,format:t.format}),h||Array.isArray(te)?C(t,h?"held out":"no decision",h?"held-out":"no-creative",["no creative for this visitor"]):C(t,"no decision","decision-failed",[`decisions answered ${F.status}`])}let se=await N(tt,g,null);if(!se)return C(t,"not shown","renderer-failed",["the renderer did not load"]);let ye=Ye(P,h=>h?.t==="products");ye&&(Y??(Y=G().catch(()=>null)));let ot=N(se.warm?.(t,P,P.steps[0].id,ue),Math.min(g,Date.now()+Nt)),[rt,oe]=await Promise.all([!ye||N(Y,g,null),Ye(P,h=>(h?.t==="heading"||h?.t==="text")&&q(h.text))&&N(Fe().catch(()=>null),g,null)]);if(!rt)return C(t,"not shown","products-failed",["its products did not load"]);if(oe===null)return C(t,"not shown","values-failed",["its values did not load"]);if(await ot,o())return C(t,"not shown","suppressed",["suppressed"]);let re=(h,at={})=>r(h,{slot:t.slot,arm:S.arm??null,format:P.format??t.format,...at}),it=se.mountForm({form:t,creative:P,decision:S,access:n,client:e,api:p,counters:l,loadWheel:je,loadAnswers:be,loadProducts:()=>Y??G(),container:V,warmed:ue,coupon:we,basket:()=>n.basketValue?.()??null,fill:oe?oe.fillFor(t,n,s.values):void 0,emit:re,onClose(h){c.delete(t.slot),$.delete(t.slot),b(t,"closed","closed",[h]),re("closed",{reason:h})}});c.set(t.slot,it),d||l.shown(t.slot),v&&l.covered(),O&&(I??(I=t.slot)),n.analytics()&&e.recordExposure(F.body);let lt=b(t,"shown","shown",[a]);return re("shown"),lt}function Q(t,a,d=U(t)){if(!ie(t.format))return L(t,a,!1,d);if(!X){let f={forms:[],taken:new Set,deadline:Date.now()+Ve+Xe};X=f,B.add(f),setTimeout(()=>{X=null,Ze(f)},Ve)}X.forms.push([t,a,d])}async function Ze(t){let a=t.forms.sort(([f],[g])=>ke(f,g)),d=null;for(let[f,[g,w,v]]of a.entries()){if(t.taken.has(g))continue;let D=await L(g,w,!1,v,t.deadline);if(!d&&Ot.has(D.code)&&!D.asked&&(d=[g,D.code]),D.state==="shown"||D.state==="held out"){for(let[O]of a.slice(f+1))b(O,"not shown","lower-priority",[`${g.slot} has a higher priority`]);d=null;break}}B.delete(t),d&&Be(...d)}for(let t of M){if(t.format==="teaser"&&l.tabOut(t.slot)){L(t,"tab kept from an earlier page",!0);continue}let a=le(t,pe(t));if(a.length){b(t,"not eligible","not-eligible",a);continue}let d=t.trigger.type;d==="manual"?b(t,"waiting for hp.onsite.open","waiting-for-open"):d==="inline"||t.format==="inline"?L(t,"inline"):fe(t)}function fe(t){Z(t),A.set(t.slot,Re(t.trigger,a=>{Z(t),Q(t,a)},{device:u})),b(t,"armed","armed",[`${t.trigger.type} on ${u}`])}let Qe=n.onConsentAnswered?.(()=>{let t=[...K];K.clear();for(let[a,d]of t)c.has(a.slot)||(d?Q(a,"manual",d):fe(a))}),et=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...k];k.clear();for(let a of t)c.has(a.slot)||Q(a,"the basket changed")}),R=Object.freeze({open(t){let a=M.find(w=>w.slot===t),d=a??M.find(w=>w.aliases.includes(t));if(!d)return Promise.resolve(!1);if(c.has(d.slot))return Promise.resolve(!0);for(let w of B)w.taken.add(d);let f=L(d,"manual",!1,U(d)||!a),g=W.get(d.slot);return g&&(g.opened=!0),f.then(({state:w})=>w==="shown")},suppress(){for(let[t,a]of c){a.destroy(),c.delete(t),$.delete(t);let d=M.find(f=>f.slot===t);d&&b(d,"closed","suppressed",["suppressed"])}},debug:()=>[..._.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){ce=!0;for(let t of A.values())t();A.clear(),et?.(),Qe?.(),k.clear(),K.clear(),window[H]===R&&delete window[H]}});window[H]=R;for(let{slot:t,resolve:a}of window[Ct]?.splice(0)??[])a(R.open(t));return y&&console.table?.(R.debug()),R}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:ze};})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thg-agentic/hyper-personalisation-web",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.32.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",
|
|
@@ -62,7 +62,8 @@
|
|
|
62
62
|
"dist/onsite-wheel.min.js",
|
|
63
63
|
"dist/onsite-products.min.js",
|
|
64
64
|
"dist/onsite-answers.min.js",
|
|
65
|
-
"dist/onsite-audiences.min.js"
|
|
65
|
+
"dist/onsite-audiences.min.js",
|
|
66
|
+
"dist/onsite-values.min.js"
|
|
66
67
|
],
|
|
67
68
|
"sideEffects": false,
|
|
68
69
|
"license": "MIT",
|
package/src/index.js
CHANGED
|
@@ -53,6 +53,7 @@ import { hostConsent, servingHeaders } from './consent.js';
|
|
|
53
53
|
import { createConsentGate } from './consent-gate.js';
|
|
54
54
|
import {
|
|
55
55
|
buildContext,
|
|
56
|
+
currencyCode,
|
|
56
57
|
getCookie,
|
|
57
58
|
localeTag,
|
|
58
59
|
perRequest,
|
|
@@ -76,7 +77,7 @@ import {
|
|
|
76
77
|
recommendationContextFrom,
|
|
77
78
|
} from './recommendation-context.js';
|
|
78
79
|
import { sampledIn } from './sampling.js';
|
|
79
|
-
import { recordSessionEvent } from './session/record.js';
|
|
80
|
+
import { basketItemsOf, recordSessionEvent } from './session/record.js';
|
|
80
81
|
import {
|
|
81
82
|
clearSessionSignals,
|
|
82
83
|
getSessionSignals,
|
|
@@ -541,6 +542,9 @@ export function createAnalytics(options) {
|
|
|
541
542
|
* Noted before the plan, the sample or beforeSend can drop the event.
|
|
542
543
|
*/
|
|
543
544
|
let pageBasket = null;
|
|
545
|
+
/** How many items it holds, when its lines say, and its currency, when it names one. */
|
|
546
|
+
let pageItems = null;
|
|
547
|
+
let pageCurrency = null;
|
|
544
548
|
/** The product this page is about: the last Product Viewed it sent, for an onsite form's products. */
|
|
545
549
|
let pageProduct = null;
|
|
546
550
|
const basketListeners = new Set();
|
|
@@ -555,6 +559,9 @@ export function createAnalytics(options) {
|
|
|
555
559
|
}
|
|
556
560
|
if (partial.type !== 'track' || partial.event !== 'Cart Updated') return;
|
|
557
561
|
const value = partial.properties?.value;
|
|
562
|
+
const lines = partial.properties?.products;
|
|
563
|
+
pageItems = Array.isArray(lines) ? basketItemsOf(lines) : null;
|
|
564
|
+
pageCurrency = currencyCode(partial.properties?.currency);
|
|
558
565
|
pageBasket =
|
|
559
566
|
typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
560
567
|
? value
|
|
@@ -1254,6 +1261,32 @@ export function createAnalytics(options) {
|
|
|
1254
1261
|
const value = getSessionSignals().basketValue;
|
|
1255
1262
|
return pageBasket ?? (Number.isFinite(value) ? value : null);
|
|
1256
1263
|
},
|
|
1264
|
+
/**
|
|
1265
|
+
* What a form's text may show (ADR 0064, shopper values): the basket's value and items,
|
|
1266
|
+
* as for a basket bar, in the currency of the basket the value came from (else the
|
|
1267
|
+
* client's), and only under personalisation consent the answers kept (else null).
|
|
1268
|
+
* Drawn as text on this page by the values chunk, never sent.
|
|
1269
|
+
*/
|
|
1270
|
+
values: () => {
|
|
1271
|
+
const { basketValue, basketItems, basketCurrency } =
|
|
1272
|
+
getSessionSignals();
|
|
1273
|
+
const onPage = pageBasket !== null;
|
|
1274
|
+
return {
|
|
1275
|
+
basket_value: onPage
|
|
1276
|
+
? pageBasket
|
|
1277
|
+
: Number.isFinite(basketValue)
|
|
1278
|
+
? basketValue
|
|
1279
|
+
: null,
|
|
1280
|
+
basket_items:
|
|
1281
|
+
pageItems ?? (Number.isInteger(basketItems) ? basketItems : null),
|
|
1282
|
+
currency:
|
|
1283
|
+
(onPage ? pageCurrency : currencyCode(basketCurrency)) ??
|
|
1284
|
+
currencyCode(perRequest(cfg.getCurrency, cfg.currency)),
|
|
1285
|
+
answers: personalisationGranted()
|
|
1286
|
+
? readAnswers(cfg.propertyId)
|
|
1287
|
+
: null,
|
|
1288
|
+
};
|
|
1289
|
+
},
|
|
1257
1290
|
/**
|
|
1258
1291
|
* This visit's session signals, kept only under personalisation consent; else null. The
|
|
1259
1292
|
* campaign is the store's as it stands, so one that has lapsed since the last event is gone.
|
package/src/onsite/index.js
CHANGED
|
@@ -23,6 +23,7 @@ import { loadAudiences } from './audiences-loader.js';
|
|
|
23
23
|
import { createCounters } from './counters.js';
|
|
24
24
|
import { loadProducts } from './products-loader.js';
|
|
25
25
|
import { loadRender } from './render-loader.js';
|
|
26
|
+
import { holdsValue } from './rich-text.js';
|
|
26
27
|
import {
|
|
27
28
|
ASKED,
|
|
28
29
|
blockers,
|
|
@@ -34,6 +35,7 @@ import {
|
|
|
34
35
|
readForm,
|
|
35
36
|
} from './rules.js';
|
|
36
37
|
import { watch } from './triggers.js';
|
|
38
|
+
import { loadValues } from './values-loader.js';
|
|
37
39
|
import { loadWheel } from './wheel-loader.js';
|
|
38
40
|
|
|
39
41
|
const ACCESS = Symbol.for(
|
|
@@ -75,6 +77,7 @@ const NOTHING = new Set([
|
|
|
75
77
|
'no-code',
|
|
76
78
|
'renderer-failed',
|
|
77
79
|
'products-failed',
|
|
80
|
+
'values-failed',
|
|
78
81
|
'error',
|
|
79
82
|
]);
|
|
80
83
|
|
|
@@ -102,14 +105,9 @@ const debugParam = () => {
|
|
|
102
105
|
}
|
|
103
106
|
};
|
|
104
107
|
|
|
105
|
-
/** Whether
|
|
106
|
-
const
|
|
107
|
-
|
|
108
|
-
creative.steps.some(
|
|
109
|
-
(step) =>
|
|
110
|
-
Array.isArray(step?.blocks) &&
|
|
111
|
-
step.blocks.some((block) => block?.t === 'products'),
|
|
112
|
-
);
|
|
108
|
+
/** Whether any block of any of the creative's steps meets `uses`. */
|
|
109
|
+
const stepsUse = (creative, uses) =>
|
|
110
|
+
creative.steps.some((step) => step.blocks.some(uses));
|
|
113
111
|
|
|
114
112
|
/**
|
|
115
113
|
* Start onsite forms for `client`, once per page. Returns the controller, or null without a
|
|
@@ -521,20 +519,36 @@ export function startOnsite(client, options = {}) {
|
|
|
521
519
|
return drop(form, 'not shown', 'renderer-failed', [
|
|
522
520
|
'the renderer did not load',
|
|
523
521
|
]);
|
|
524
|
-
// Its products
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
]);
|
|
531
|
-
}
|
|
532
|
-
// Its first step's pictures fetched and decoded first, so it never opens on an empty one, and
|
|
533
|
-
// never waits for them longer than WARM_MS or past its deadline.
|
|
534
|
-
await within(
|
|
522
|
+
// Its products and its text's values are drawn by chunks of their own, fetched together while
|
|
523
|
+
// its first step's pictures warm: without them the form would open on an empty block, or on
|
|
524
|
+
// text with a gap. The pictures are waited for no longer than WARM_MS or past its deadline.
|
|
525
|
+
const products = stepsUse(creative, (b) => b?.t === 'products');
|
|
526
|
+
if (products) cards ??= loadProducts().catch(() => null);
|
|
527
|
+
const warming = within(
|
|
535
528
|
render.warm?.(form, creative, creative.steps[0].id, warmed),
|
|
536
529
|
Math.min(deadline, Date.now() + WARM_MS),
|
|
537
530
|
);
|
|
531
|
+
const [drawn, values] = await Promise.all([
|
|
532
|
+
!products || within(cards, deadline, null),
|
|
533
|
+
stepsUse(
|
|
534
|
+
creative,
|
|
535
|
+
(b) => (b?.t === 'heading' || b?.t === 'text') && holdsValue(b.text),
|
|
536
|
+
) &&
|
|
537
|
+
within(
|
|
538
|
+
loadValues().catch(() => null),
|
|
539
|
+
deadline,
|
|
540
|
+
null,
|
|
541
|
+
),
|
|
542
|
+
]);
|
|
543
|
+
if (!drawn)
|
|
544
|
+
return drop(form, 'not shown', 'products-failed', [
|
|
545
|
+
'its products did not load',
|
|
546
|
+
]);
|
|
547
|
+
if (values === null)
|
|
548
|
+
return drop(form, 'not shown', 'values-failed', [
|
|
549
|
+
'its values did not load',
|
|
550
|
+
]);
|
|
551
|
+
await warming;
|
|
538
552
|
if (suppressed())
|
|
539
553
|
return drop(form, 'not shown', 'suppressed', ['suppressed']);
|
|
540
554
|
const tell = (name, detail = {}) =>
|
|
@@ -559,6 +573,7 @@ export function startOnsite(client, options = {}) {
|
|
|
559
573
|
warmed,
|
|
560
574
|
coupon,
|
|
561
575
|
basket: () => access.basketValue?.() ?? null,
|
|
576
|
+
fill: values ? values.fillFor(form, access, options.values) : undefined,
|
|
562
577
|
emit: tell,
|
|
563
578
|
onClose(why) {
|
|
564
579
|
mounted.delete(form.slot);
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
/** Money in `currency` for the language `lang` (else the browser's); null for a currency `Intl` does not know. */
|
|
2
|
+
export function money(lang, currency) {
|
|
3
|
+
try {
|
|
4
|
+
return new Intl.NumberFormat(lang || undefined, {
|
|
5
|
+
style: 'currency',
|
|
6
|
+
currency,
|
|
7
|
+
});
|
|
8
|
+
} catch {
|
|
9
|
+
return null;
|
|
10
|
+
}
|
|
11
|
+
}
|
package/src/onsite/preview.js
CHANGED
|
@@ -10,9 +10,12 @@ import { answerCards, answerFields, answerOf, countdown } from './answers.js';
|
|
|
10
10
|
import { mountProducts } from './products.js';
|
|
11
11
|
import { mountForm } from './render.js';
|
|
12
12
|
import { readCreative } from './rules.js';
|
|
13
|
+
import { fillFor } from './values.js';
|
|
13
14
|
import { mountWheel } from './wheel.js';
|
|
14
15
|
|
|
15
16
|
export { CALLING_CODES } from './rules.js';
|
|
17
|
+
/** A shopper value as the SDK shows it, so the console's examples read as shoppers see them. */
|
|
18
|
+
export { formatValue } from './values.js';
|
|
16
19
|
|
|
17
20
|
const SAMPLE_CONSENT = 'Your consent text appears here.';
|
|
18
21
|
const SAMPLE_SMS_CONSENT = 'Your SMS consent text appears here.';
|
|
@@ -35,7 +38,10 @@ const SAMPLE_BASKET = 32;
|
|
|
35
38
|
* @param {unknown} creative The arm's payload.
|
|
36
39
|
* @param {{ step?: string, device?: 'desktop'|'mobile', consentText?: string, smsConsentText?: string, locale?: string,
|
|
37
40
|
* questions?: Array<{ key: string, type?: 'one'|'many'|'date'|'number', label?: string, options?: Array<{ value: string, label?: string }>, format?: object }>,
|
|
38
|
-
* prizes?: Array<{ key: string, label: string }>, basketValue?: number
|
|
41
|
+
* prizes?: Array<{ key: string, label: string }>, basketValue?: number,
|
|
42
|
+
* values?: { first_name?: string, basket_value?: number, basket_items?: number, currency?: string, answers?: Record<string, string[]> } | null }} [options]
|
|
43
|
+
* `values`: a returning shopper's, for the text's shopper values; without them every value shows
|
|
44
|
+
* its fallback, as for a new visitor, but for an answer given in the form itself.
|
|
39
45
|
* @returns {{ update(creative: unknown, options?: object): void, destroy(): void, step(): string|null }}
|
|
40
46
|
*/
|
|
41
47
|
export function mountPreview(host, creative, options = {}) {
|
|
@@ -48,19 +54,25 @@ export function mountPreview(host, creative, options = {}) {
|
|
|
48
54
|
mounted = null;
|
|
49
55
|
if (!read) return;
|
|
50
56
|
const format = read.format ?? 'popup';
|
|
57
|
+
const form = {
|
|
58
|
+
slot: 'preview',
|
|
59
|
+
format,
|
|
60
|
+
// The settings' `locale`, so the preview orders a birthday and picks a phone's
|
|
61
|
+
// country as shoppers see them, not by the console's own language.
|
|
62
|
+
...(opts.locale ? { locale: opts.locale } : {}),
|
|
63
|
+
consent_text: { text: opts.consentText ?? SAMPLE_CONSENT },
|
|
64
|
+
sms_consent_text: { text: opts.smsConsentText ?? SAMPLE_SMS_CONSENT },
|
|
65
|
+
questions: Array.isArray(opts.questions) ? opts.questions : [],
|
|
66
|
+
prizes: Array.isArray(opts.prizes) ? opts.prizes : [],
|
|
67
|
+
};
|
|
68
|
+
const values = opts.values ?? null;
|
|
51
69
|
mounted = mountForm({
|
|
52
|
-
form
|
|
53
|
-
slot: 'preview',
|
|
54
|
-
format,
|
|
55
|
-
// The settings' `locale`, so the preview orders a birthday and picks a phone's
|
|
56
|
-
// country as shoppers see them, not by the console's own language.
|
|
57
|
-
...(opts.locale ? { locale: opts.locale } : {}),
|
|
58
|
-
consent_text: { text: opts.consentText ?? SAMPLE_CONSENT },
|
|
59
|
-
sms_consent_text: { text: opts.smsConsentText ?? SAMPLE_SMS_CONSENT },
|
|
60
|
-
questions: Array.isArray(opts.questions) ? opts.questions : [],
|
|
61
|
-
prizes: Array.isArray(opts.prizes) ? opts.prizes : [],
|
|
62
|
-
},
|
|
70
|
+
form,
|
|
63
71
|
creative: read,
|
|
72
|
+
fill: fillFor(form, {
|
|
73
|
+
// A new visitor: nothing known yet, though the answers they give in the form show.
|
|
74
|
+
values: () => values ?? { answers: {} },
|
|
75
|
+
}),
|
|
64
76
|
decision: { slot: 'preview' },
|
|
65
77
|
access: silent,
|
|
66
78
|
client: null,
|
package/src/onsite/products.js
CHANGED
|
@@ -10,6 +10,7 @@
|
|
|
10
10
|
*/
|
|
11
11
|
|
|
12
12
|
import { watchViewability } from '../auto/viewability.js';
|
|
13
|
+
import { money } from './money.js';
|
|
13
14
|
import { httpsHref } from './rich-text.js';
|
|
14
15
|
import { isObject } from './rules.js';
|
|
15
16
|
|
|
@@ -42,15 +43,8 @@ const ALIGNS = ['left', 'center', 'right'];
|
|
|
42
43
|
|
|
43
44
|
/** Money in the form's language; the bare amount for a currency the browser does not know. */
|
|
44
45
|
function moneyIn(lang, currency) {
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
style: 'currency',
|
|
48
|
-
currency,
|
|
49
|
-
});
|
|
50
|
-
return (n) => format.format(n);
|
|
51
|
-
} catch {
|
|
52
|
-
return (n) => n.toFixed(2);
|
|
53
|
-
}
|
|
46
|
+
const format = money(lang, currency);
|
|
47
|
+
return format ? (n) => format.format(n) : (n) => n.toFixed(2);
|
|
54
48
|
}
|
|
55
49
|
|
|
56
50
|
/**
|
package/src/onsite/render.js
CHANGED
|
@@ -352,6 +352,8 @@ function styles(root) {
|
|
|
352
352
|
* @param {(name: 'submitted'|'apply', detail: object) => void} [o.emit] To `hp.onsite.on` listeners.
|
|
353
353
|
* @param {string|null} [o.coupon] A code the form starts with: an unused one to remind of.
|
|
354
354
|
* @param {() => number|null} [o.basket] The basket's value, for a progress block.
|
|
355
|
+
* @param {(block: object, answers: object) => object|false} [o.fill] A form whose text has shopper
|
|
356
|
+
* values: each block as it shows (./values.js `fillFor`), `false` for one hidden.
|
|
355
357
|
* @param {{ device: 'desktop'|'mobile', step?: string }} [o.preview] Render inside `container`,
|
|
356
358
|
* inert but for moving between steps: no network, no events, no counters.
|
|
357
359
|
*/
|
|
@@ -1002,11 +1004,9 @@ export function mountForm(o) {
|
|
|
1002
1004
|
}
|
|
1003
1005
|
|
|
1004
1006
|
/** A teaser's first step: a tab that opens the rest of the form. */
|
|
1005
|
-
function tab(
|
|
1006
|
-
const heading =
|
|
1007
|
-
const open =
|
|
1008
|
-
(b) => b?.t === 'button' && b.action === 'next',
|
|
1009
|
-
);
|
|
1007
|
+
function tab(blocks) {
|
|
1008
|
+
const heading = blocks.find((b) => b?.t === 'heading');
|
|
1009
|
+
const open = blocks.find((b) => b?.t === 'button' && b.action === 'next');
|
|
1010
1010
|
// The heading's words without its marks: a button holds no link.
|
|
1011
1011
|
const b = el('button', 'tb');
|
|
1012
1012
|
b.textContent = heading
|
|
@@ -1075,9 +1075,11 @@ export function mountForm(o) {
|
|
|
1075
1075
|
wrap.classList.add('lk');
|
|
1076
1076
|
}
|
|
1077
1077
|
body.replaceChildren();
|
|
1078
|
-
|
|
1078
|
+
// Shopper values filled in as text (./values.js), from this form's answers too; false: hidden.
|
|
1079
|
+
const blocks = step.blocks.map((b) => o.fill?.(b, state.answers) ?? b);
|
|
1080
|
+
if (asTab && l.template !== 'image-only') body.append(tab(blocks));
|
|
1079
1081
|
else
|
|
1080
|
-
for (const [index, block] of
|
|
1082
|
+
for (const [index, block] of blocks.entries()) {
|
|
1081
1083
|
const node =
|
|
1082
1084
|
isObject(block) && Object.hasOwn(BLOCKS, block.t)
|
|
1083
1085
|
? BLOCKS[block.t](block)
|