@thg-agentic/hyper-personalisation-web 3.34.0 → 3.35.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 +10 -2
- package/dist/hp.min.js +2 -2
- package/dist/onsite-answers.min.js +2 -2
- package/dist/onsite-audiences.min.js +1 -1
- package/dist/onsite-products.min.js +1 -1
- package/dist/onsite-render.min.js +1 -1
- package/dist/onsite-wheel.min.js +1 -1
- package/dist/onsite.min.js +1 -1
- package/package.json +1 -1
- package/src/datalayer.js +7 -2
- package/src/index.js +51 -3
- package/src/onsite/index.js +33 -7
- package/src/onsite/rules.js +6 -1
- package/src/segment.js +2 -1
- package/src/session/record.js +61 -0
- package/src/session/rules.js +3 -1
- package/src/session/signals.js +3 -0
- package/src/shape.js +9 -6
- package/src/version.js +1 -1
- package/types/index.d.ts +1 -1
- package/types/onsite.d.ts +5 -0
|
@@ -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 Lt=/^#(?:[0-9a-f]{3}){1,2}$/i,Je=["popup","fullscreen"],It=["ok","verify","already"],Mt=["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"],Dt=[500,1500],Rt=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"},Y=(i,r,a)=>i.includes(r)?r:a,P=(i,r,a)=>Number.isFinite(i)?Math.min(Math.max(i,r),a):null,ke=i=>i.type==="date"||i.type==="number",Ae=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function rt(i){let r=I(i.layout)?i.layout:{},a=I(r.media)?r.media:null,l=Y(Mt,r.template,"stack"),p=a?.side==="right"?"right":"left";return!a&&I(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:P(r.scrim,0,.9)??.45,padding:Y(["none","sm","md","lg"],r.padding,"md")}}var st=(i,r)=>Y(["sm","md","lg","full"],i.size,null)??(r.template==="split"||r.template==="overlay"?"lg":"md"),at=(i,r,a=1,l="100vw")=>{if(i==="fullscreen"||r==="full")return l;let p=i==="teaser"?220:i==="sheet"?400:tt[r]??tt.md;return`(max-width: 639px) ${l}, ${Math.round(p*a)}px`},lt=(i,r)=>i==="lg"?1/Ze(r):.5,ct=(i,r,a)=>{if(!a||!Array.isArray(i.widths)||!r.endsWith(".webp"))return null;let l=i.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=(i,r)=>i.format==="inline"?"inline":r.format&&r.format!=="inline"?r.format:i.format,Ee=i=>i.kind==="video"||i.t==="video",_e={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},$e=i=>_e[i.split(/[?#]/)[0].split(".").pop().toLowerCase()],Wt=(i,r)=>[...new Set([r,...Array.isArray(i.sources)?i.sources.map(K):[]])].filter(Boolean).sort((a,l)=>($e(l)===_e.webm)-($e(a)===_e.webm));function ze(i,r,a,l=new Set){let p=r.steps.find(v=>v.id===a);if(!p)return Promise.resolve();let x=dt(i,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"&&i.questions.find(T=>T.key===v.question&&T.type==="one");return F?Object.values(v.pictures??{}).filter(I).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 O=K(Ee(v)?v.poster:v.asset);if(!O)return null;let D=document.createElement("img"),y=!Ee(v)&&ct(v,O,P(v.width,1,8192));y&&(D.sizes=at(h,C,F,T),D.srcset=y);let Z=`${D.sizes} ${y||O}`;return l.has(Z)?null:(l.add(Z),D.src=O,D.decode?.().catch(()=>{}))}))}var ot=i=>i?.call?i():clearInterval(i),Ft=0,Se=i=>`hp-${i}-${++Ft}`;function d(i,r,a){let l=document.createElement(i);return r&&(l.className=r),a!==void 0&&l.append(Ve(a)),l}var pt=i=>{let r=i.length===4?[...i.slice(1)].map(a=>a+a).join(""):i.slice(1);return[0,2,4].map(a=>Number.parseInt(r.slice(a,a+2),16))},te=i=>{let[r,a,l]=pt(i).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},it=(i,r=4.5)=>{let a=te(i)+.05,l=1.05/a;return l>=r?"#fff":a/(te("#111")+.05)>l?"#111":"#fff"};function Ht(i,r){let a=(_,v)=>v&&i.style.setProperty(_,v),l=_=>Lt.test(_??"")?_:null;a("--hp-accent",l(r.accent)),a("--hp-bg",l(r.background)),a("--hp-text",l(r.text));let p=P(r.radius,0,48);p!==null&&a("--hp-radius",`${p}px`),a("--hp-font",r.font==="site"?i.ownerDocument.defaultView.getComputedStyle(i.parentElement??i.ownerDocument.body).fontFamily:Object.hasOwn(ve,r.font)?ve[r.font]:null),l(r.accent)&&(a("--hp-on-accent",it(r.accent,3)),a("--hp-on-accent-text",it(r.accent))),l(r.background)&&te(r.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=I(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} / ${P(x.opacity,0,1)??.6})`)}function Yt(i){try{let r=new CSSStyleSheet;r.replaceSync(we),i.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=we,i.append(r)}}function ut(i){let{form:r,creative:a,decision:l,access:p,client:x,api:b,counters:w}=i,h=i.preview??null,C=e=>{let t=e.blocks.find(o=>o?.t==="email"||o?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},_=dt(r,a),v=a.theme,F=Y(Qe[_]??[],v.position,Qe[_]?.[0]),T=document.createElement("hp-onsite");h&&T.setAttribute("preview",""),Ht(T,v);let O=T.attachShadow({mode:"open"});Yt(O);let D=_!=="inline"&&!h,y=d(D?"dialog":_==="inline"?"section":"div"),Z=d("div","ov"),$=d("div","w"),H=d("div","m");h&&(H.dataset.hpMedia="");let Ce=()=>{let e=d("form","f");return e.noValidate=!0,e.addEventListener("submit",St),e.addEventListener("input",()=>{L.textContent&&E.getAttribute("aria-busy")!=="true"&&N(null)}),e},E=Ce(),L=d("p","e");L.id=Se("err"),L.setAttribute("aria-live","assertive");let se=d("div","hd");se.setAttribute("aria-hidden","true"),$.append(se,H,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"))),O.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:i.coupon?{code:i.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:i.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=r.locale||document.documentElement.lang,Te=(r.questions.some(ke)||a.steps.some(e=>e.blocks.some(t=>t?.t==="countdown"||t?.display==="cards")))&&i.loadAnswers().catch(()=>null),Oe=new WeakMap,Le=()=>{let e=I(v.button)?v.button:{};y.className=`s ${n.mode}${F?` p-${F}`:""} b-${Y(["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)"),Ie=()=>{n.mobile=Q?.matches===!0,pe(),Le()};Q&&(n.mobile=Q.matches===!0,Q.addEventListener?.("change",Ie));let ae=!r.channels?.length,G=(e,t,o={})=>{if(!(h||!l.decision_id||!p.analytics())){if(e==="click"){let s=n.clicked;if(n.clicked=!0,s&&!o.products)return}x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...o})}},N=(e,t)=>{L.className="e",L.textContent=e??"";for(let s of E.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let o=t?.closest("label,fieldset");o&&E.contains(o)?o.after(L):E.append(L),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",L.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},Me=()=>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,o,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 M=d("source");M.src=z;let q=$e(z);q&&(M.type=q),m.append(M)}else m.src=u;n.videos.push(m)}else{m=d("img",t),m.alt=g,m.decoding="async",m.loading=o?"eager":"lazy",o&&(m.fetchPriority="high");let A=ct(e,u,P(e.width,1,8192));A&&(m.sizes=at(n.mode,n.size,s,c),m.srcset=A),m.src=u}let f=P(e.width,1,8192),k=P(e.height,1,8192);return f&&k&&(m.width=f,m.height=k),I(e.focal)&&(m.style.objectPosition=`${P(e.focal.x,0,100)??50}% ${P(e.focal.y,0,100)??50}%`),m}function Pe(e,t){let o=d("label","l");o.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",L.id),s.addEventListener("focus",Me,{once:!0}),t!=="tel")return o.append(s),o;s.id=`${L.id}-p`,o.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),o.append(u),o}function ft(e){let t=r.questions.find(f=>f.key===e.question);if(!t||!ke(t)&&!Array.isArray(t.options))return null;let o=d("fieldset");o.dataset.question=t.key,o.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 o.append(d("p","sm",S.unavailable));if(c)return f.answerCards(o,t,e,d,s,k=>ce(k,"qi",!1,lt(n.size,t),"50vw"),O);f.answerFields(o,t,d,s[0],J),Oe.set(o,()=>f.answerOf(o,t,void 0,J))}),o;let u=t.type==="many",g=Y(["list","dropdown"],e.display,"buttons"),m=t.options.filter(f=>I(f)&&typeof f.value=="string");if(g==="dropdown"&&!u)return o.append(xe(d,t.label??t.key,"\u2014",m.map(f=>[f.value,f.label??f.value]),s[0])),o;g!=="buttons"&&(o.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)),o.append(k)}return o}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 o=d("button","btn cp");o.type="button",o.textContent="Copy code",o.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{o.textContent=S.copied}).catch(()=>{})}),e.append(t,o)}}function mt(e){if(n.claim&&!n.claim.code)return null;let t=d("div","cd");return t.hidden=!0,Te.then(o=>o&&t.isConnected&&n.timers.push(o.countdown(t,e,h,d,r.window.daily?.next))),t}function de(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",o=>{if(h)return o.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 o=d("button",`btn${nt[e.variant]??""}`,t);return o.type=e.action==="submit"?"submit":"button",o.type==="button"?o.addEventListener("click",()=>re(e)):o.dataset.submit="",o}let qe=(e,t,o)=>(e.classList.add(`x-${Y(Pt,t.size,o)}`),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 o=P(e.radius,0,48);o!==null&&(t.style.borderRadius=`${o}px`);let s=P(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=P(e.threshold,.01,1e7);if(!t)return null;let o=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)),o.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(i.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)),o}function gt(e){let t=d("div","pr");return i.loadProducts?.().then(o=>{t.isConnected&&n.timers.push(o.mountProducts(t,e,{el:d,lang:J,root:O,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 o=d("label","c"),s=d("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",L.id),o.append(s,d("span","",t)),o},question:ft,wheel(){let e=d("div","wh");return i.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){H.replaceChildren();let o=e.media,s=!o||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}`,H.hidden=s,H.hidden)return;let c=ce(o,"",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=""),H.append(c);return}let u=X(o.href),g=u?de(d("a","io"),u):d("button","io");u||(g.type="button",g.addEventListener("click",()=>re({action:"next"}))),g.append(c),H.append(g)}function yt(e){let t=e.find(c=>c?.t==="heading"),o=e.find(c=>c?.t==="button"&&c.action==="next"),s=d("button","tb");return s.textContent=t?d("b","",t.text).textContent:o?.label??"Open",s.type="button",s.addEventListener("click",()=>re(o??{action:"next"})),s}function R(e,t=new Set){let o=a.steps.find(z=>z.id===e);if(!o)return U("done");if(o.kind==="question"&&!h&&!p.analytics()&&!t.has(o.id))return R(ee(o,n.answers),t.add(o.id));let s=n.step!==null,c=s&&(O.activeElement||document.activeElement===document.body),u=s&&!h?{mode:n.mode,w:$.offsetWidth,h:$.offsetHeight,top:$.offsetTop}:null;n.step=o,n.touched=!1;for(let z of n.timers.splice(0))ot(z);n.codes=[],n.videos=[],n.wheel=null;let g=_==="teaser"&&o===a.steps[0];if(n.mode=_==="teaser"&&!g?"popup":_,_==="teaser"&&w.tab?.(r.slot,g),B&&B.setAttribute("aria-label",g?S.closeOffer:"Close"),Le(),y.removeAttribute("aria-labelledby"),u){let z=Ce();E.replaceWith(z),E=z}let m=rt(o);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=o.blocks.map(z=>i.fill?.(z,n.answers)??z);if(g&&m.template!=="image-only")E.append(yt(k));else for(let[z,M]of k.entries()){let q=I(M)&&Object.hasOwn(je,M.t)?je[M.t](M):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&&De(),le(),h||wt(o),c&&E.querySelector("h2")?.focus()}function pe(){$.classList.remove("lk","an"),$.style.removeProperty("--tp")}function vt(e){let t=$.offsetHeight;$.classList.add("an");let o=$.offsetTop,s=Math.max(0,e.top-o);if(s+t>y.clientHeight-2*o)return pe();$.style.setProperty("--tp",`${s}px`)}function wt(e){let t=e.next??{};for(let c of[t.default,...Object.values(I(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 o=()=>{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(o,{timeout:2e3}):setTimeout(o,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function De(){if(!D)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 Re(){for(let e of E.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,o=Oe.get(e)?.()??{};if(o.error)return o;let s=[o.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(([o,s])=>({question:o,values:s})).filter(o=>!n.sent.has(ue(o))),t=({question:o})=>n.answeredOn[o];if(n.signedUp){for(let o of new Set(e.map(t))){let s=e.filter(c=>t(c)===o);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:o,...n.signedUp,answers:s,context:Fe()})}return}if(p.analytics())for(let o of e)n.sent.add(ue(o)),x.preferencesStated({...o,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t(o)})}let ue=({question:e,values:t})=>`${e}=${t.join(",")}`,We=()=>{ae&&(Re(),Ue())},Fe=()=>({page:{url:p.pageUrl()},locale:p.locale()??void 0,consent:p.consent()}),oe=e=>{!h&&(n.receipt||ae)&&Ue(),R(ee(n.step,n.answers,e))};async function kt(e){let t=n.step,o=E.querySelector("input[name=email],input[name=phone]");if(!o)return oe(e.next);let s=o.name==="email"?"email":"sms",c=E.querySelector("select[name=hp_cc]")?.value,u=s==="email"?Ke(o.value.trim())?o.value.trim():null:Xe(o.value,c);if(!u)return N(s==="email"?S.email:c?S.phone:S.intl,o);let g=E.querySelector("input[name=hp_consent]");if(g&&!g.checked)return N(S.consent,g);N(null),V(!0);let m=await Me();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)&&It.includes(j);if(n.closed&&!z)return;z||V(!1);let M=A.status===400?A.body?.field:null;if(M==="email"||M==="phone")return N(S[M],o);if(!z)return N(A.status===429?S.busy:S.failed,o);o.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),G("submit",t.id),n.owed=s==="email"&&r.prizes.length>0;let q=n.owed?fe([]):null;q||i.emit?.("submitted",{coupon:null});let _t=q&&await Promise.race([q,new Promise(W=>setTimeout(W,Rt))]);if(n.closed)return;if(V(!1),_t?.held)return R(ie("held"));let $t=j!=="ok"&&a.steps.some(W=>W.id===j);R($t?j:ee(t,n.answers,e.next));let zt=n.step;q?.then(W=>{W?.held&&!n.closed&&n.step===zt&&!n.touched&&R(ie("held"))})}function ie(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:S.shop,action:"close"},o=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:o}),e}function He(e){n.owed&&(n.owed=!1,i.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function fe(e=Dt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let o;for(let g of[0,...e])if(g&&await new Promise(m=>setTimeout(m,g)),o=await b.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),o.status!==503)break;let s=o.body,c=s?.fallback===!0&&!s.code;if(o.status!==200||!(I(s?.prize)||c))return n.claiming=null,!e.length&&o.status===503?fe():(He(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),He(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(ie("unclaimed"));let o=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&&!o){if(await n.wheel.spinTo(s),n.closed)return;L.className="e won",L.textContent=`${S.won} ${t.prize.label}`,await new Promise(g=>setTimeout(g,Ut))}if(n.closed)return;V(!1);let c=o?"fallback":s<0?"held":null,u=c?ie(c):ee(n.step,n.answers,e.next);u?R(u):ne()}function re(e){if(e.action==="close")return U("close");let t=Re();return h?oe(e.next):t?N(t.error,t.input):(ae&&n.step.blocks.some(o=>n.answers[o?.question])&&G("click"),e.action==="apply"?(i.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),G("click"),oe(e.next)):e.action==="submit"?kt(e):e.action==="spin"?At(e):oe(e.next))}function St(e){if(e.preventDefault(),E.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(o=>o?.t==="button"&&o.action==="submit");re(t??{action:"next"})}function me(e=!1){n.closed=!0;for(let o of n.timers.splice(0))ot(o);document.removeEventListener("visibilitychange",le),Q?.removeEventListener?.("change",Ie);let t=()=>{try{y.open&&y.close()}catch{}T.remove()};if(e||!D||Ae())return t();y.classList.add("out"),setTimeout(t,Nt)}function U(e){n.closed||h||(We(),!n.submitted&&e!=="done"&&G("dismiss"),w.closed(r.slot),w.tab?.(r.slot,!1),me(),i.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=[...O.querySelectorAll("input[type=radio]:checked")],o=new Set,s=[...O.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:o.has(f.name))?!1:(o.add(f.name),!0)});if(!s.length)return;let c=e.shiftKey,u=O.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,o=0,s=u=>{o=Math.max(0,u.clientY-t),$.style.transform=`translateY(${o}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),$.style.transform="",o>80&&U("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),(i.container??document.body).append(T),De()}catch(e){throw me(!0),e}return{close:U,root:O,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 Lt=/^#(?:[0-9a-f]{3}){1,2}$/i,Je=["popup","fullscreen"],It=["ok","verify","already"],Mt=["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},Nt=["left","center","right"],nt={secondary:" b2",link:" no"},qt=220,jt=["verify","already","held","fallback","success"],Dt=[500,1500],Rt=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"},Y=(i,r,a)=>i.includes(r)?r:a,P=(i,r,a)=>Number.isFinite(i)?Math.min(Math.max(i,r),a):null,ke=i=>i.type==="date"||i.type==="number",Ae=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0;function rt(i){let r=I(i.layout)?i.layout:{},a=I(r.media)?r.media:null,l=Y(Mt,r.template,"stack"),p=a?.side==="right"?"right":"left";return!a&&I(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:P(r.scrim,0,.9)??.45,padding:Y(["none","sm","md","lg"],r.padding,"md")}}var st=(i,r)=>Y(["sm","md","lg","full"],i.size,null)??(r.template==="split"||r.template==="overlay"?"lg":"md"),at=(i,r,a=1,l="100vw")=>{if(i==="fullscreen"||r==="full")return l;let p=i==="teaser"?220:i==="sheet"?400:tt[r]??tt.md;return`(max-width: 639px) ${l}, ${Math.round(p*a)}px`},lt=(i,r)=>i==="lg"?1/Ze(r):.5,ct=(i,r,a)=>{if(!a||!Array.isArray(i.widths)||!r.endsWith(".webp"))return null;let l=i.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=(i,r)=>i.format==="inline"?"inline":r.format&&r.format!=="inline"?r.format:i.format,_e=i=>i.kind==="video"||i.t==="video",Ee={webm:"video/webm",mp4:"video/mp4",m4v:"video/mp4",mov:"video/quicktime",ogv:"video/ogg"},$e=i=>Ee[i.split(/[?#]/)[0].split(".").pop().toLowerCase()],Wt=(i,r)=>[...new Set([r,...Array.isArray(i.sources)?i.sources.map(K):[]])].filter(Boolean).sort((a,l)=>($e(l)===Ee.webm)-($e(a)===Ee.webm));function ze(i,r,a,l=new Set){let p=r.steps.find(v=>v.id===a);if(!p)return Promise.resolve();let x=dt(i,r),b=rt(p),w=x==="teaser"&&p===r.steps[0],h=x==="teaser"&&!w?"popup":x,C=st(r.theme,b),E=w?[]:p.blocks.flatMap(v=>{if(v?.t==="image"||v?.t==="video")return[[v]];let F=v?.display==="cards"&&i.questions.find(T=>T.key===v.question&&T.type==="one");return F?Object.values(v.pictures??{}).filter(I).map(T=>[T,lt(C,F),"50vw"]):[]});return b.media&&!(w&&b.template!=="image-only")&&E.push([b.media,b.template==="split"?.46:1]),Promise.all(E.map(([v,F,T])=>{let O=K(_e(v)?v.poster:v.asset);if(!O)return null;let D=document.createElement("img"),y=!_e(v)&&ct(v,O,P(v.width,1,8192));y&&(D.sizes=at(h,C,F,T),D.srcset=y);let Z=`${D.sizes} ${y||O}`;return l.has(Z)?null:(l.add(Z),D.src=O,D.decode?.().catch(()=>{}))}))}var ot=i=>i?.call?i():clearInterval(i),Ft=0,Se=i=>`hp-${i}-${++Ft}`;function d(i,r,a){let l=document.createElement(i);return r&&(l.className=r),a!==void 0&&l.append(Ve(a)),l}var pt=i=>{let r=i.length===4?[...i.slice(1)].map(a=>a+a).join(""):i.slice(1);return[0,2,4].map(a=>Number.parseInt(r.slice(a,a+2),16))},te=i=>{let[r,a,l]=pt(i).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},it=(i,r=4.5)=>{let a=te(i)+.05,l=1.05/a;return l>=r?"#fff":a/(te("#111")+.05)>l?"#111":"#fff"};function Ht(i,r){let a=(E,v)=>v&&i.style.setProperty(E,v),l=E=>Lt.test(E??"")?E:null;a("--hp-accent",l(r.accent)),a("--hp-bg",l(r.background)),a("--hp-text",l(r.text));let p=P(r.radius,0,48);p!==null&&a("--hp-radius",`${p}px`),a("--hp-font",r.font==="site"?i.ownerDocument.defaultView.getComputedStyle(i.parentElement??i.ownerDocument.body).fontFamily:Object.hasOwn(ve,r.font)?ve[r.font]:null),l(r.accent)&&(a("--hp-on-accent",it(r.accent,3)),a("--hp-on-accent-text",it(r.accent))),l(r.background)&&te(r.background)<.18&&(a("--hp-field","#fff"),a("--hp-field-text","#111"));let x=I(r.overlay)?r.overlay:{},b=[l(r.text),l(r.background)].filter(Boolean).sort((E,v)=>te(E)-te(v))[0],[w,h,C]=pt(l(x.colour)??b??"#0b0b0f");a("--hp-ov",`rgb(${w} ${h} ${C} / ${P(x.opacity,0,1)??.6})`)}function Yt(i){try{let r=new CSSStyleSheet;r.replaceSync(we),i.adoptedStyleSheets=[r]}catch{let r=document.createElement("style");r.textContent=we,i.append(r)}}function ut(i){let{form:r,creative:a,decision:l,access:p,client:x,api:b,counters:w}=i,h=i.preview??null,C=e=>{let t=e.blocks.find(o=>o?.t==="email"||o?.t==="phone");return t?.t==="phone"||!t&&!r.consent_text?r.sms_consent_text:r.consent_text},E=dt(r,a),v=a.theme,F=Y(Qe[E]??[],v.position,Qe[E]?.[0]),T=document.createElement("hp-onsite");h&&T.setAttribute("preview",""),Ht(T,v);let O=T.attachShadow({mode:"open"});Yt(O);let D=E!=="inline"&&!h,y=d(D?"dialog":E==="inline"?"section":"div"),Z=d("div","ov"),$=d("div","w"),H=d("div","m");h&&(H.dataset.hpMedia="");let Ce=()=>{let e=d("form","f");return e.noValidate=!0,e.addEventListener("submit",St),e.addEventListener("input",()=>{L.textContent&&_.getAttribute("aria-busy")!=="true"&&q(null)}),e},_=Ce(),L=d("p","e");L.id=Se("err"),L.setAttribute("aria-live","assertive");let se=d("div","hd");se.setAttribute("aria-hidden","true"),$.append(se,H,_),y.append(Z,$);let B=E!=="inline"&&d("button","x");B&&(B.type="button",B.addEventListener("click",()=>U("close")),$.append(B),Z.addEventListener("click",()=>U("close"))),O.append(y);let n={step:null,mode:E,size:"md",modal:!1,mobile:h?.device==="mobile",answers:{},answeredOn:{},sent:new Set,clicked:!1,seen:new Set,receipt:null,claim:i.coupon?{code:i.coupon}:h?{code:"WELCOME15"}:null,claiming:null,touched:!1,toWarm:new Set,warmed:i.warmed??new Set,warming:!1,owed:!1,unclaimed:!1,misses:0,submitted:!1,pow:null,wheel:null,timers:[],codes:[],videos:[],closed:!1},J=r.locale||document.documentElement.lang,Te=(r.questions.some(ke)||a.steps.some(e=>e.blocks.some(t=>t?.t==="countdown"||t?.display==="cards")))&&i.loadAnswers().catch(()=>null),Oe=new WeakMap,Le=()=>{let e=I(v.button)?v.button:{};y.className=`s ${n.mode}${F?` p-${F}`:""} b-${Y(["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)"),Ie=()=>{n.mobile=Q?.matches===!0,pe(),Le()};Q&&(n.mobile=Q.matches===!0,Q.addEventListener?.("change",Ie));let ae=!r.channels?.length,G=(e,t,o={})=>{if(!(h||!l.decision_id||!p.analytics())){if(e==="click"){let s=n.clicked;if(n.clicked=!0,s&&!o.products)return}x.slotEngaged({decision_id:l.decision_id,slot:l.slot,arm:l.arm??null,engagement:e,step:t??n.step?.id??null,...o})}},q=(e,t)=>{L.className="e",L.textContent=e??"";for(let s of _.querySelectorAll("[aria-invalid]"))s.removeAttribute("aria-invalid");let o=t?.closest("label,fieldset");o&&_.contains(o)?o.after(L):_.append(L),t&&(t.setAttribute("aria-invalid","true"),t.setAttribute("aria-describedby",L.id),t.focus(),t.scrollIntoView?.({block:"nearest"}))},V=e=>{_.setAttribute("aria-busy",String(e));for(let t of _.querySelectorAll("button"))t.disabled=e},Me=()=>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,o,s,c){let u=K(e.asset);if(!u)return null;let g=typeof e.alt=="string"?e.alt:"",m;if(_e(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 M=d("source");M.src=z;let N=$e(z);N&&(M.type=N),m.append(M)}else m.src=u;n.videos.push(m)}else{m=d("img",t),m.alt=g,m.decoding="async",m.loading=o?"eager":"lazy",o&&(m.fetchPriority="high");let A=ct(e,u,P(e.width,1,8192));A&&(m.sizes=at(n.mode,n.size,s,c),m.srcset=A),m.src=u}let f=P(e.width,1,8192),k=P(e.height,1,8192);return f&&k&&(m.width=f,m.height=k),I(e.focal)&&(m.style.objectPosition=`${P(e.focal.x,0,100)??50}% ${P(e.focal.y,0,100)??50}%`),m}function Pe(e,t){let o=d("label","l");o.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",L.id),s.addEventListener("focus",Me,{once:!0}),t!=="tel")return o.append(s),o;s.id=`${L.id}-p`,o.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),o.append(u),o}function ft(e){let t=r.questions.find(f=>f.key===e.question);if(!t||!ke(t)&&!Array.isArray(t.options))return null;let o=d("fieldset");o.dataset.question=t.key,o.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 o.append(d("p","sm",S.unavailable));if(c)return f.answerCards(o,t,e,d,s,k=>ce(k,"qi",!1,lt(n.size,t),"50vw"),O);f.answerFields(o,t,d,s[0],J),Oe.set(o,()=>f.answerOf(o,t,void 0,J))}),o;let u=t.type==="many",g=Y(["list","dropdown"],e.display,"buttons"),m=t.options.filter(f=>I(f)&&typeof f.value=="string");if(g==="dropdown"&&!u)return o.append(xe(d,t.label??t.key,"\u2014",m.map(f=>[f.value,f.label??f.value]),s[0])),o;g!=="buttons"&&(o.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)),o.append(k)}return o}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 o=d("button","btn cp");o.type="button",o.textContent="Copy code",o.addEventListener("click",()=>{navigator.clipboard?.writeText(n.claim.code).then(()=>{o.textContent=S.copied}).catch(()=>{})}),e.append(t,o)}}function mt(e){if(n.claim&&!n.claim.code)return null;let t=d("div","cd");return t.hidden=!0,Te.then(o=>o&&t.isConnected&&n.timers.push(o.countdown(t,e,h,d,r.window.daily?.next))),t}function de(e,t){return e.href=t,e.rel="noopener",e.addEventListener("click",o=>{if(h)return o.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 o=d("button",`btn${nt[e.variant]??""}`,t);return o.type=e.action==="submit"?"submit":"button",o.type==="button"?o.addEventListener("click",()=>re(e)):o.dataset.submit="",o}let Ne=(e,t,o)=>(e.classList.add(`x-${Y(Pt,t.size,o)}`),Nt.includes(t.align)&&e.classList.add(`a-${t.align}`),e);function qe(e){let t=ce(e,"bi",n.step===a.steps[0]);if(!t)return null;t.style.objectFit=e.fit==="contain"?"contain":"cover";let o=P(e.radius,0,48);o!==null&&(t.style.borderRadius=`${o}px`);let s=P(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=P(e.threshold,.01,1e7);if(!t)return null;let o=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)),o.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(i.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)),o}function gt(e){let t=d("div","pr");return i.loadProducts?.().then(o=>{t.isConnected&&n.timers.push(o.mountProducts(t,e,{el:d,lang:J,root:O,placement:r.slot,preview:h,client:!h&&p.analytics()&&x,engaged:G,seen:n.seen}))}).catch(()=>{}),t}let je={heading(e){let t=Ne(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=>Ne(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 o=d("label","c"),s=d("input");return s.type="checkbox",s.name="hp_consent",s.required=!0,s.setAttribute("aria-describedby",L.id),o.append(s,d("span","",t)),o},question:ft,wheel(){let e=d("div","wh");return i.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:qe,video:qe,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){H.replaceChildren();let o=e.media,s=!o||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)),_.className=`f pd-${e.padding}`,H.hidden=s,H.hidden)return;let c=ce(o,"",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=""),H.append(c);return}let u=X(o.href),g=u?de(d("a","io"),u):d("button","io");u||(g.type="button",g.addEventListener("click",()=>re({action:"next"}))),g.append(c),H.append(g)}function yt(e){let t=e.find(c=>c?.t==="heading"),o=e.find(c=>c?.t==="button"&&c.action==="next"),s=d("button","tb");return s.textContent=t?d("b","",t.text).textContent:o?.label??"Open",s.type="button",s.addEventListener("click",()=>re(o??{action:"next"})),s}function R(e,t=new Set){let o=a.steps.find(z=>z.id===e);if(!o)return U("done");if(o.kind==="question"&&!h&&!p.analytics()&&!t.has(o.id))return R(ee(o,n.answers),t.add(o.id));let s=n.step!==null,c=s&&(O.activeElement||document.activeElement===document.body),u=s&&!h?{mode:n.mode,w:$.offsetWidth,h:$.offsetHeight,top:$.offsetTop}:null;n.step=o,n.touched=!1;for(let z of n.timers.splice(0))ot(z);n.codes=[],n.videos=[],n.wheel=null;let g=E==="teaser"&&o===a.steps[0];if(n.mode=E==="teaser"&&!g?"popup":E,E==="teaser"&&w.tab?.(r.slot,g),B&&B.setAttribute("aria-label",g?S.closeOffer:"Close"),Le(),y.removeAttribute("aria-labelledby"),u){let z=Ce();_.replaceWith(z),_=z}let m=rt(o);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")),_.replaceChildren();let k=o.blocks.map(z=>i.fill?.(z,n.answers)??z);if(g&&m.template!=="image-only")_.append(yt(k));else for(let[z,M]of k.entries()){let N=I(M)&&Object.hasOwn(je,M.t)?je[M.t](M):null;N&&(h&&(N.dataset.hpBlock=String(z)),_.append(N))}let A=_.querySelector("[data-submit]"),j=_.querySelector("[name=hp_consent]")?.parentNode;A&&j&&A.before(j),_.hidden=_.childElementCount===0,q(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&&De(),le(),h||wt(o),c&&_.querySelector("h2")?.focus()}function pe(){$.classList.remove("lk","an"),$.style.removeProperty("--tp")}function vt(e){let t=$.offsetHeight;$.classList.add("an");let o=$.offsetTop,s=Math.max(0,e.top-o);if(s+t>y.clientHeight-2*o)return pe();$.style.setProperty("--tp",`${s}px`)}function wt(e){let t=e.next??{};for(let c of[t.default,...Object.values(I(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 o=()=>{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(o,{timeout:2e3}):setTimeout(o,200);document.readyState==="complete"?s():window.addEventListener("load",s,{once:!0})}function De(){if(!D)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 Re(){for(let e of _.querySelectorAll("fieldset[data-question]")){let t=e.dataset.question,o=Oe.get(e)?.()??{};if(o.error)return o;let s=[o.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(([o,s])=>({question:o,values:s})).filter(o=>!n.sent.has(ue(o))),t=({question:o})=>n.answeredOn[o];if(n.signedUp){for(let o of new Set(e.map(t))){let s=e.filter(c=>t(c)===o);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:o,...n.signedUp,answers:s,context:Fe()})}return}if(p.analytics())for(let o of e)n.sent.add(ue(o)),x.preferencesStated({...o,source:"onsite",slot:l.slot,arm:l.arm??null,decision_id:l.decision_id??null,step:t(o)})}let ue=({question:e,values:t})=>`${e}=${t.join(",")}`,We=()=>{ae&&(Re(),Ue())},Fe=()=>({page:{url:p.pageUrl()},locale:p.locale()??void 0,consent:p.consent()}),oe=e=>{!h&&(n.receipt||ae)&&Ue(),R(ee(n.step,n.answers,e))};async function kt(e){let t=n.step,o=_.querySelector("input[name=email],input[name=phone]");if(!o)return oe(e.next);let s=o.name==="email"?"email":"sms",c=_.querySelector("select[name=hp_cc]")?.value,u=s==="email"?Ke(o.value.trim())?o.value.trim():null:Xe(o.value,c);if(!u)return q(s==="email"?S.email:c?S.phone:S.intl,o);let g=_.querySelector("input[name=hp_consent]");if(g&&!g.checked)return q(S.consent,g);q(null),V(!0);let m=await Me();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)&&It.includes(j);if(n.closed&&!z)return;z||V(!1);let M=A.status===400?A.body?.field:null;if(M==="email"||M==="phone")return q(S[M],o);if(!z)return q(A.status===429?S.busy:S.failed,o);o.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),G("submit",t.id),n.owed=s==="email"&&r.prizes.length>0;let N=n.owed?fe([]):null;N||i.emit?.("submitted",{coupon:null});let Et=N&&await Promise.race([N,new Promise(W=>setTimeout(W,Rt))]);if(n.closed)return;if(V(!1),Et?.held)return R(ie("held"));let $t=j!=="ok"&&a.steps.some(W=>W.id===j);R($t?j:ee(t,n.answers,e.next));let zt=n.step;N?.then(W=>{W?.held&&!n.closed&&n.step===zt&&!n.touched&&R(ie("held"))})}function ie(e){if(a.steps.some(s=>s.id===e))return e;let t={t:"button",label:S.shop,action:"close"},o=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:o}),e}function He(e){n.owed&&(n.owed=!1,i.emit?.("submitted",{coupon:e?{code:e.code??null,prize:e.prize?.key}:null}))}function fe(e=Dt){let t=n.receipt;return n.claiming??(n.claiming=(async()=>{n.unclaimed=!1;let o;for(let g of[0,...e])if(g&&await new Promise(m=>setTimeout(m,g)),o=await b.claim({slot:l.slot,decision_id:l.decision_id??void 0,receipt:t}),o.status!==503)break;let s=o.body,c=s?.fallback===!0&&!s.code;if(o.status!==200||!(I(s?.prize)||c))return n.claiming=null,!e.length&&o.status===503?fe():(He(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),He(s),n.closed||ne(),s})()),n.claiming}async function At(e){if(!n.receipt)return q(S.spin);V(!0);let t=await fe();if(n.closed)return;if(!t)return V(!1),n.misses+=1,n.misses<2?q(S.retry):R(ie("unclaimed"));let o=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&&!o){if(await n.wheel.spinTo(s),n.closed)return;L.className="e won",L.textContent=`${S.won} ${t.prize.label}`,await new Promise(g=>setTimeout(g,Ut))}if(n.closed)return;V(!1);let c=o?"fallback":s<0?"held":null,u=c?ie(c):ee(n.step,n.answers,e.next);u?R(u):ne()}function re(e){if(e.action==="close")return U("close");let t=Re();return h?oe(e.next):t?q(t.error,t.input):(ae&&n.step.blocks.some(o=>n.answers[o?.question])&&G("click"),e.action==="apply"?(i.emit?.("apply",{coupon:n.claim?.code?{code:n.claim.code}:null}),G("click"),oe(e.next)):e.action==="submit"?kt(e):e.action==="spin"?At(e):oe(e.next))}function St(e){if(e.preventDefault(),_.getAttribute("aria-busy")==="true")return;let t=n.step.blocks.find(o=>o?.t==="button"&&o.action==="submit");re(t??{action:"next"})}function me(e=!1){n.closed=!0;for(let o of n.timers.splice(0))ot(o);document.removeEventListener("visibilitychange",le),Q?.removeEventListener?.("change",Ie);let t=()=>{try{y.open&&y.close()}catch{}T.remove()};if(e||!D||Ae())return t();y.classList.add("out"),setTimeout(t,qt)}function U(e){n.closed||h||(We(),!n.submitted&&e!=="done"&&G("dismiss"),w.closed(r.slot),w.tab?.(r.slot,!1),me(),i.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&&E!=="inline"&&U("esc"),e.key==="Tab"&&n.modal&&_t(e)});function _t(e){let t=[...O.querySelectorAll("input[type=radio]:checked")],o=new Set,s=[...O.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:o.has(f.name))?!1:(o.add(f.name),!0)});if(!s.length)return;let c=e.shiftKey,u=O.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,o=0,s=u=>{o=Math.max(0,u.clientY-t),$.style.transform=`translateY(${o}px)`},c=()=>{document.removeEventListener("pointermove",s),document.removeEventListener("pointerup",c),$.style.transform="",o>80&&U("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),(i.container??document.body).append(T),De()}catch(e){throw me(!0),e}return{close:U,root:O,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};})();
|
package/dist/onsite-wheel.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function F(e,o,s=5){let n=360/o;return s*360+(360-(e+.5)*n)}var
|
|
1
|
+
(()=>{function F(e,o,s=5){let n=360/o;return s*360+(360-(e+.5)*n)}var v="http://www.w3.org/2000/svg",I=4500,T=.22,O=.95,R=.105,L=.082,A=.062,z=.62,w=1.15,N="var(--hp-accent,#111)",k="var(--hp-on-accent,#fff)",m="var(--hp-bg,#fff)",$="var(--hp-text,#111)";function c(e,o={}){let s=document.createElementNS(v,e);for(let[n,i]of Object.entries(o))s.setAttribute(n,String(i));return s}function f(e,o,s,n=1){return e.style.fill=o,n<1&&(e.style.fillOpacity=String(n)),s&&(e.style.stroke=s),e}var D=()=>globalThis.matchMedia?.("(prefers-reduced-motion: reduce)")?.matches===!0,S=(e,o=1)=>{let s=(e-90)*Math.PI/180;return`${(o*Math.cos(s)).toFixed(4)} ${(o*Math.sin(s)).toFixed(4)}`};function q(e,o){let s=O-T,n=2*.35*Math.sin(Math.min(Math.PI/o,Math.PI/2)),i=t=>Math.max(L,Math.min(R,n/(t*w))),a=t=>s/(Math.max(1,t.length)*z),r=[...e.matchAll(/ /g)].map(t=>t.index),u=e.length/2,p=r.length?r.reduce((t,l)=>Math.abs(l-u)<Math.abs(t-u)?l:t):-1,h=p<0?null:[e.slice(0,p),e.slice(p+1)];for(let t of[L,A]){let l=a(e);if(l>=t)return{lines:[e],size:Math.min(i(1),l)};if(h){let g=Math.min(i(2),...h.map(a));if(g>=t)return{lines:h,size:g}}}let d=Math.floor(s/(A*z));return{lines:[`${e.slice(0,d-1).trimEnd()}\u2026`],size:A}}function C(e){let o=O-T,s=n=>n.getComputedTextLength?.()??0;for(let n of e){let i=[...n.querySelectorAll("tspan")],a=Math.max(0,...i.map(s));if(!(a>o))continue;let r=Math.max(A,Number(n.getAttribute("font-size"))*o/a);n.setAttribute("font-size",r.toFixed(4)),i.forEach((u,p)=>{u.setAttribute("y",((p-(i.length-1)/2)*r*w).toFixed(4)),s(u)>o&&(u.setAttribute("textLength",o.toFixed(4)),u.setAttribute("lengthAdjust","spacingAndGlyphs"))})}}function P(e,o){let s=(Array.isArray(o)?o:[]).map(d=>String(d?.label??d?.key??"")),n=s.length;if(n<2)return null;let i=360/n,a=c("svg",{viewBox:"-1.2 -1.2 2.4 2.4",role:"img","aria-label":`Prize wheel: ${s.join(", ")}`}),r=c("g");r.style.transformBox="fill-box",r.style.transformOrigin="50% 50%";let u=[[1,k],[.14,$],[.72,k]];r.append(f(c("circle",{r:1}),m));let p=[],h=[];return s.forEach((d,t)=>{let[l,g]=u[n%2===1&&t===n-1?2:t%2];r.append(f(c("path",{d:`M0 0L${S(t*i)}A1 1 0 ${i>180?1:0} 1 ${S((t+1)*i)}Z`,"stroke-width":.012}),N,m,l));let _=(t+.5)*i-90,x=q(d,n),b=f(c("text",{transform:`rotate(${_}) translate(${(T+O)/2} 0)${_>90&&_<270?" rotate(180)":""}`,"text-anchor":"middle","dominant-baseline":"central","font-size":x.size.toFixed(4),"font-weight":700,"aria-hidden":"true"}),g);x.lines.forEach((E,M)=>{let y=c("tspan",{x:0,y:((M-(x.lines.length-1)/2)*x.size*w).toFixed(4)});y.textContent=E,b.append(y)}),r.append(b),h.push(b);for(let E of[t*i,(t+.5)*i]){let[M,y]=S(E,1.075).split(" ");p.push(f(c("circle",{cx:M,cy:y,r:.024}),m))}}),a.append(f(c("circle",{r:1.13}),$),...p,r,f(c("circle",{r:.17,"stroke-width":.035}),m,$),f(c("circle",{r:.065}),N),f(c("path",{d:"M-0.12 -1.2L0.12 -1.2L0 -0.86Z","stroke-width":.03,"stroke-linejoin":"round"}),N,m)),e.append(a),C(h),globalThis.requestAnimationFrame?.(()=>C(h)),{spinTo(d){let t=D();return r.style.transition=t?"none":`transform ${I}ms cubic-bezier(.15,.7,.1,1)`,r.style.transform=`rotate(${F(d,s.length,t?0:5)}deg)`,t?Promise.resolve():new Promise(l=>{let g=setTimeout(l,I+200);r.addEventListener("transitionend",()=>{clearTimeout(g),l()},{once:!0})})},remove:()=>a.remove()}}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel")]={mountWheel:P};})();
|
package/dist/onsite.min.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
(()=>{function E(e){let s=typeof document>"u"?null:document.currentScript?.src;return s?new URL(e,s).href:null}var B=new Map;function T(e,s){return window[s]?Promise.resolve(window[s]):e?(B.has(s)||B.set(s,new Promise((n,o)=>{let u=document.createElement("script");u.src=e,u.async=!0,u.onload=()=>window[s]?n(window[s]):o(new Error(`${e} did not register`)),u.onerror=()=>o(new Error(`${e} did not load`)),document.head.append(u)}).finally(()=>B.delete(s))),B.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var St=E("onsite-answers.min.js"),xe=()=>T(St,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var At="/v1/capture/challenge",vt=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:At;function Ie(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),o=s.servingHost??e.servingHost,u=s.gatewayHost??e.gatewayHost;async function l(c,{method:i="GET",body:r,consent:p=!1,timeoutMs:y}={}){if(!n)return{status:0,body:null};try{let b=await n(c,{method:i,credentials:"omit",signal:y&&AbortSignal.timeout?.(y),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...r?{"content-type":"application/json"}:{},...p?e.headers():{}},...r?{body:JSON.stringify(r)}:{}}),S=null;try{S=await b.json()}catch{}return{status:b.status,body:S}}catch{return{status:0,body:null}}}let g=(c,i)=>l(`${u}/v1/capture${c}`,{method:"POST",body:i}).then(r=>(r.status>=200&&r.status<300&&e.answered?.(i.answers,i.slot),r));return{decide:(c,i,{visitAudiences:r,visitCampaign:p,visitContext:y,pageFacts:b,timeoutMs:S=3e3}={})=>l(`${o}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,S),body:{slots:[i?{key:c,pin:{experiment:i[0],arm:i[1],split:i[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}},...p?{visit_campaign:p}:{},...y?{visit_context:y}:{},...b?{page_facts:b}:{}}}),datafile:()=>l(`${o}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>l(`${u}${vt(s.challenge)}`),capture:c=>g("",c),answers:c=>g("/answers",c),claim:c=>l(`${o}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}var Et=E("onsite-audiences.min.js"),Me=()=>T(Et,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function De(e,s){let n={},o=()=>{try{let l=JSON.parse(e().getItem(s));l&&typeof l=="object"&&(n=l)}catch{}return n};return{read:o,write:l=>{let g=o();l(g),n=g;try{e().setItem(s,JSON.stringify(g))}catch{}}}}function Oe(e,s=()=>!0){let n=De(()=>sessionStorage,e),o=De(()=>localStorage,e),u=()=>s()?o:n,l=()=>{let i=o.read();(i.sub!==void 0||i.k!==void 0)&&o.write(r=>{delete r.sub,delete r.k})},g=()=>s()?[n.read(),o.read()]:(l(),[n.read()]),c=(i,r)=>{var p;return i.f??(i.f={}),(p=i.f)[r]??(p[r]={}),i.f[r]};return{seen(i){let r=o.read().f?.[i]??{};return{session:n.read().f?.[i]?.n??0,lifetime:r.n??0,closedAt:r.c??null,submitted:r.s===1}},subscribed:()=>g().some(i=>i.sub===1),shown(i){n.write(r=>{let p=c(r,i);p.n=(p.n??0)+1}),o.write(r=>{let p=c(r,i);p.n=(p.n??0)+1})},closed(i,r=Date.now()){o.write(p=>{c(p,i).c=r})},tab(i,r){n.write(p=>{let y=c(p,i);r?y.t=1:delete y.t})},tabOut:i=>n.read().f?.[i]?.t===1,pin(i,r){if(r===void 0)return n.read().f?.[i]?.p??null;n.write(p=>{c(p,i).p=r})},coveredAt:()=>n.read().o??null,covered(i=Date.now()){n.write(r=>{r.o=i})},code(i,r=Date.now()){if(i===void 0){let[p]=g().flatMap(y=>y.k?[y.k]:[]).sort((y,b)=>b.at-y.at);return p&&r-p.at<14*864e5?p.c:null}return u().write(p=>{p.k={c:i,at:r}}),i},submitted(i){o.write(r=>{c(r,i).s=1}),u().write(r=>{r.sub=1})}}}var Tt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-facts");function pe(e=globalThis.window){let s=e?.[Tt];return s?.path===e?.location?.pathname?s.facts:{}}var Pe=e=>typeof e=="string"?e.slice(0,100):e,Ce=e=>typeof e=="string"?e.trim().toLowerCase():e,Ne=(e,s)=>e.every(n=>{let o=Pe(s?.[n.fact]),u=Array.isArray(n.values)?n.values:[];if(o==null||typeof o!=typeof u[0]||typeof o=="number"&&!Number.isFinite(o))return!1;let l=u.some(g=>Ce(g)===Ce(o));return n.op==="is"?l:n.op==="is_not"?!l:n.op==="at_least"?o>=u[0]:n.op==="at_most"&&o<=u[0]}),$e=(e,s)=>Object.fromEntries(e.filter(n=>n.fact in s).map(n=>[n.fact,Pe(s[n.fact])]));var xt=E("onsite-products.min.js"),J=()=>T(xt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var It=E("onsite-render.min.js"),ke=()=>T(It,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var Z=(e,s=0)=>s<=6&&typeof e=="object"&&!!e&&(Array.isArray(e)?e.some(n=>Z(n,s+1)):typeof e.v=="string"||Z(e.b??e.i??e.a,s+1));var Mt=["source","medium","campaign","content","term"];var Le=e=>String(e).trim().toLowerCase();function Dt(e,s,n){let o=Le(e),u=Le(n);return s==="is"?o===u:s==="contains"&&u!==""&&o.includes(u)}function Fe(e,s){return(Array.isArray(e)?e:[]).every(n=>{let o=s?.[n?.field];return!Mt.includes(n?.field)||typeof o!="string"?!1:[].concat(n.values??[]).some(u=>Dt(o,n.match,u))})}var Q=["the page does not say so","not a product page"],We=["popup","sheet","bar","teaser","inline","fullscreen"],Ot=["entry","exit","scroll","time","idle","inline","manual"],fe=e=>e!=="inline",Xe=e=>e==="popup"||e==="sheet"||e==="fullscreen",x=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),H=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],Re=e=>Number.isInteger(e)&&e>=0?e:null,Ue=(e,s)=>e==null?[]:Array.isArray(e)&&e.every(x)?e:[s];function Ke(e){if(!x(e)||typeof e.slot!="string"||e.slot==="")return null;let s=x(e.trigger)?e.trigger:{};if(!We.includes(e.format)||!Ot.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:H(e.devices),aliases:H(e.aliases),audiences:H(e.audiences),arrived_from:Ue(e.arrived_from,{field:null,match:null,values:[]}),page_facts:Ue(e.page_facts,{fact:null,op:null,values:[]}),products:e.products===!0,caps:{per_session:Re(n.per_session),lifetime:Re(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 Ct=/^[a-z][a-z0-9_-]{0,31}$/;function Ve(e){if(!x(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>x(n)&&Ct.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:We.includes(e.format)?e.format:null,theme:x(e.theme)?e.theme:{},steps:s}}function je(e,s){let n=String(e).split("*").map(o=>o.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function Pt(e,s){let n=H(e?.include);return(!n.length||n.some(o=>je(o,s)))&&!H(e?.exclude).some(o=>je(o,s))}function Ye(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var He=e=>typeof e=="string"?Date.parse(e):Number.NaN,W=e=>e.trigger.type==="manual",he="outside its daily window",ze=(e,s)=>{let{daily:n}=e.window;return n.next.find(o=>o>s)-n.within_hours*36e5-s};function ge(e,s){let n=[];Pt(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),Fe(e.arrived_from,s.campaign)||n.push("not from its campaign"),!s.later&&!s.preview&&(Ne(e.page_facts,s.facts)||n.push(Q[0]),e.products&&!s.product&&n.push(Q[1]));let o=He(e.window.starts_at),u=He(e.window.ends_at);(s.now<o||s.now>=u)&&n.push("outside its dates");let{daily:l}=e.window;if(l&&!s.preview){let i=l.next?.find?.(r=>r>s.now)-s.now;i>0?!s.later&&i>l.within_hours*36e5&&n.push(he):n.push("no cut-off ahead")}if(e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(i=>s.audiences.includes(i))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||W(e))return n;let{seen:g}=s,{caps:c}=e;return g.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),c.per_session!==null&&g.session>=c.per_session&&n.push("per_session cap"),c.lifetime!==null&&g.lifetime>=c.lifetime&&n.push("lifetime cap"),c.after_close_days!==null&&g.closedAt&&s.now-g.closedAt<c.after_close_days*864e5&&n.push("closed recently"),n}var Ge=(e,s)=>s.priority-e.priority;var Nt=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function $t(){let e=[];return{on:(o,u,l,g={passive:!0})=>{o.addEventListener(u,l,g),e.push(()=>o.removeEventListener(u,l,g))},later:(o,u)=>{let l=setTimeout(o,u);e.push(()=>clearTimeout(l))},stop:()=>{for(let o of e.splice(0))o()}}}var qe=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},kt=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function Lt({on:e,later:s},n,o,u,l){let g=!1,c=!1,i=null,r=0;s(()=>{g=!0},o.delay_ms??5e3),e(l,"mousemove",p=>{p.clientY>u.innerHeight*.1&&(c=!0),i!==null&&(r=p.clientY-i),i=p.clientY}),e(l,"mouseout",p=>{g&&c&&!p.relatedTarget&&p.clientY<=0&&r<0&&!kt(l)&&n("exit")})}function Ft({on:e,later:s},n,o,u,l){let g=!1,c=0,i=u.scrollY,r=Date.now(),p=null,y=null;s(()=>{g=!0},o.delay_ms??5e3),e(u,"scroll",()=>{let b=u.scrollY,S=Date.now();if(c=Math.max(c,qe(u,l)),b<i){(!p||S-p.t>300)&&(p={y:i,t:r});let I=p.y-b;g&&c>=.3&&I>=120&&I/Math.max(1,S-p.t)>=.5&&n("exit_scroll")}else p=null;i=b,r=S}),e(l,"visibilitychange",()=>{l.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),l.visibilityState!=="hidden"&&(y=null)})}function Be(e,s,{device:n,win:o=window,doc:u=document}){let l=$t(),g=(e.seconds??30)*1e3;if(e.type==="entry"&&l.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&l.later(()=>s("time"),g),e.type==="exit"&&(n==="mobile"?Ft:Lt)(l,s,e,o,u),e.type==="scroll"){let c=e.depth??.5;l.on(o,"scroll",()=>qe(o,u)>=c&&s("scroll"))}if(e.type==="idle"){let c=null,i=()=>{clearTimeout(c),c=setTimeout(()=>s("idle"),g)};i();for(let r of Nt)l.on(r==="scroll"?o:u,r,i);return l.on(u,"visibilitychange",i),()=>{clearTimeout(c),l.stop()}}return l.stop}var Rt=E("onsite-values.min.js"),Je=()=>T(Rt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.values"));var Ut=E("onsite-wheel.min.js"),Ze=()=>T(Ut,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var Qe=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),X=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),jt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),Ht=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),ee=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-said"),et=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),tt={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},Wt=new Set(["decision-failed","no-creative","no-code","renderer-failed","products-failed","values-failed","error"]),nt=3e3,st={status:0,body:null},Xt=1500,ot=50,Kt=300,Vt=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},it=(e,s)=>e.steps.some(n=>n.blocks.some(s));function rt(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[X])return window[X];let n=typeof e?.[Qe]=="function"?e[Qe]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let o=s.settings??n.settings??{};n.started?.(o);let u=Ie(n,{...s,challenge:o.capture?.challenge}),l=n.preview?tt:Oe(n.storageKey,n.personalisation),g=()=>n.campaign?.()??null,c=new Map,i=()=>window[et]?.size>0,r=(t,a)=>{for(let d of window[Ht]?.[t]??[])try{d(a)}catch(h){console.warn(`[hp] onsite ${t} listener failed:`,h)}},p=Ye(window),y=n.debug||s.debug===!0||Vt(),b=new Map,S=new Map,I=[];for(let t of Array.isArray(o.forms)?o.forms:[]){let a=Ke(t);a?I.push(a):b.set(String(t?.slot??`form ${b.size+1}`),{slot:String(t?.slot??""),state:"invalid",code:"invalid",reasons:["not a form this SDK can show"]})}let we=()=>Me().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&I.some(t=>t.audiences.length>0)&&we().then(t=>t?.prefetch(u));let k=new Map,L=new Map,M=null,K=!1,me=new Set,at=t=>{for(let a of k.keys()){let d=c.get(a);if(!t||!d||d.modal?.())return a}return null},V=null,te=new Set,ne=Number.isInteger(o.overlay_gap_minutes)?o.overlay_gap_minutes:0,lt=()=>{let t=l.coveredAt();if(!(ne>0)||typeof t!="number")return null;let a=Math.max(0,Math.floor((Date.now()-t)/6e4));return a<ne?`a popup showed ${a} min ago; ${ne} min between them`:null},F=new Set,R=new Set,Y=new Map,_=(t,a,d,h=[])=>(b.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:a,code:d,reasons:h}),y&&console.info(`[hp] onsite ${t.slot}: ${a}${h.length?` (${h.join("; ")})`:""}`),{state:a,code:d}),D=(t,a,d,h)=>(k.delete(t.slot),_(t,a,d,h)),$=(t,a,d)=>{let h;return Promise.race([t,new Promise(m=>{h=setTimeout(m,a-Date.now(),d)})]).then(m=>Date.now()>a?d:m).finally(()=>clearTimeout(h))},ct=(t,a)=>{K||i()||(M??(M=t.slot),r("nothing",{slot:t.slot,format:t.format,code:a}))},ye=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},be=t=>({path:location.pathname,device:p,campaign:g(),facts:pe(),product:n.pageProduct?.(),now:Date.now(),seen:l.seen(t.slot),subscribed:l.subscribed()||s.subscribed?.()===!0,personalisation:n.personalisation(),preview:!!n.preview,audiences:ye()}),z=t=>{S.get(t.slot)?.(),S.delete(t.slot)};function N(t,a,d=!1,h=W(t),m=Date.now()+nt){if(c.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:h});let w=L.get(t.slot);return w?(w.asked||(w.asked=h),w.done):(w={asked:h},w.done=ut(t,a,d,h,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=>(L.delete(t.slot),{...v,asked:w.asked||w.opened})),L.set(t.slot,w),w.done)}async function ut(t,a,d,h,m){if(i())return _(t,"not shown","suppressed",[`suppressed: ${[...window[et]].join(", ")}`]);let w=ge(t,{...be(t),...d?{seen:tt.seen()}:{},asked:h});if(w.length){if(d&&w.every(f=>Q.includes(f))&&R.add(t),w.length===1&&w[0]===he&&!h&&!d&&!K){let f=t.trigger.type==="inline"||t.format==="inline";z(t);let de=setTimeout(()=>f?N(t,"inline"):oe(t),ze(t,Date.now()));S.set(t.slot,()=>clearTimeout(de))}return _(t,"not eligible","not-eligible",w)}R.delete(t);let v=Xe(t.format)&&!d,O=v&&!h&<();if(O)return _(t,"not shown","overlay-gap",[O]);if(v&&!n.preview&&n.consentAnswered?.()===!1)return Y.set(t,h),_(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let C=fe(t.format),Se=C&&at(h);if(Se)return _(t,"not shown","another-showing",[`${Se} is showing`]);if(C&&M&&!h)return _(t,"not shown","allowance-spent",[`${M} already showed on this page view`]);let G=null;if(!C){try{G=document.querySelector(t.trigger.selector??"")}catch{G=null}if(!G)return _(t,"not shown","no-element",["no element matches its selector"])}C&&k.set(t.slot,t),z(t),_(t,"asking for a decision","deciding",[a]);let ht=ke().catch(f=>(console.warn("[hp] onsite renderer not loaded:",f?.message??f),null)),q=t.visit_context===!0?J().catch(()=>null):null,ie=ye()??[],Ae={claims:[...new Set([...t.audiences,...ie])].filter(f=>ie.includes(f)).slice(0,100)},gt=t.audiences.length>0&&!n.preview&&n.personalisation()?await $(we().then(f=>f?f.visitAudiences(u,n.sessionSignals,t.audiences,ie):Ae),Math.min(m,Date.now()+Xt),Ae):null,j=Date.now()<m?await $(u.decide(t.slot,l.pin(t.slot),{visitAudiences:gt,visitCampaign:t.arrived_from.length?g():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:t.products?{product_id:n.pageProduct?.()}:null,pageFacts:t.page_facts.length?$e(t.page_facts,pe()):null,timeoutMs:m-Date.now()}),m,st):st,re=j.status===200?j.body?.decisions:null,A=Array.isArray(re)?re.find(f=>f?.slot===t.slot):null;A?.experiment&&A.arm&&A.split&&l.pin(t.slot,[A.experiment,A.arm,A.split]);let P=A&&A.holdout!==!0?Ve(A.payload):null,ve=P?.steps[0].blocks??[],Ee=A?.offer?.code??(n.preview?"PREVIEW":l.code()),wt=n.basketValue?.()??null,ae=ve.some(f=>f?.t==="code")&&!Ee&&"no code to remind of"||ve.some(f=>f?.t==="progress")&&!(wt>0)&&"the basket is empty";if(ae){let f=ae==="the basket is empty";return f&&F.add(t),D(t,"not shown",f?"empty-basket":"no-code",[ae])}if(F.delete(t),!P){let f=A?.holdout===!0;return f&&n.analytics()&&e.recordExposure(j.body),C&&f&&(M??(M=t.slot)),f&&!h&&r("held",{slot:t.slot,arm:A.arm??null,format:t.format}),f||Array.isArray(re)?D(t,f?"held out":"no decision",f?"held-out":"no-creative",["no creative for this visitor"]):D(t,"no decision","decision-failed",[`decisions answered ${j.status}`])}let le=await $(ht,m,null);if(!le)return D(t,"not shown","renderer-failed",["the renderer did not load"]);let Te=it(P,f=>f?.t==="products");Te&&(q??(q=J().catch(()=>null)));let mt=$(le.warm?.(t,P,P.steps[0].id,me),Math.min(m,Date.now()+Kt)),[yt,ce]=await Promise.all([!Te||$(q,m,null),it(P,f=>(f?.t==="heading"||f?.t==="text")&&Z(f.text))&&$(Je().catch(()=>null),m,null)]);if(!yt)return D(t,"not shown","products-failed",["its products did not load"]);if(ce===null)return D(t,"not shown","values-failed",["its values did not load"]);if(await mt,i())return D(t,"not shown","suppressed",["suppressed"]);let ue=(f,de={})=>r(f,{slot:t.slot,arm:A.arm??null,format:P.format??t.format,...de}),bt=le.mountForm({form:t,creative:P,decision:A,access:n,client:e,api:u,counters:l,loadWheel:Ze,loadAnswers:xe,loadProducts:()=>q??J(),container:G,warmed:me,coupon:Ee,basket:()=>n.basketValue?.()??null,fill:ce?ce.fillFor(t,n,s.values):void 0,emit:ue,onClose(f){c.delete(t.slot),k.delete(t.slot),_(t,"closed","closed",[f]),ue("closed",{reason:f})}});c.set(t.slot,bt),d||l.shown(t.slot),v&&l.covered(),C&&(M??(M=t.slot)),n.analytics()&&e.recordExposure(j.body);let _t=_(t,"shown","shown",[a]);return ue("shown"),_t}function se(t,a,d=W(t)){if(!fe(t.format))return N(t,a,!1,d);if(!V){let h={forms:[],taken:new Set,deadline:Date.now()+ot+nt};V=h,te.add(h),setTimeout(()=>{V=null,dt(h)},ot)}V.forms.push([t,a,d])}async function dt(t){let a=t.forms.sort(([h],[m])=>Ge(h,m)),d=null;for(let[h,[m,w,v]]of a.entries()){if(t.taken.has(m))continue;let O=await N(m,w,!1,v,t.deadline);if(!d&&Wt.has(O.code)&&!O.asked&&(d=[m,O.code]),O.state==="shown"||O.state==="held out"){for(let[C]of a.slice(h+1))_(C,"not shown","lower-priority",[`${m.slot} has a higher priority`]);d=null;break}}te.delete(t),d&&ct(...d)}for(let t of I){if(t.format==="teaser"&&l.tabOut(t.slot)){N(t,"tab kept from an earlier page",!0);continue}let a=ge(t,{...be(t),later:!0});if(a.length){_(t,"not eligible","not-eligible",a);continue}let d=t.trigger.type;d==="manual"?_(t,"waiting for hp.onsite.open","waiting-for-open"):d==="inline"||t.format==="inline"?N(t,"inline"):oe(t)}function oe(t){z(t),S.set(t.slot,Be(t.trigger,a=>{z(t),se(t,a)},{device:p})),_(t,"armed","armed",[`${t.trigger.type} on ${p}`])}let pt=n.onConsentAnswered?.(()=>{let t=[...Y];Y.clear();for(let[a,d]of t)c.has(a.slot)||(d?se(a,"manual",d):oe(a))}),_e=()=>{let t=[...R];R.clear();for(let a of t)Promise.resolve(L.get(a.slot)?.done).then(()=>K||c.has(a.slot)||N(a,"tab kept from an earlier page",!0))};(window[ee]??(window[ee]=new Set)).add(_e);let ft=n.onBasket?.(()=>{if(!((n.basketValue?.()??0)>0))return;let t=[...F];F.clear();for(let a of t)c.has(a.slot)||se(a,"the basket changed")}),U=Object.freeze({open(t){let a=I.find(w=>w.slot===t),d=a??I.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 te)w.taken.add(d);let h=N(d,"manual",!1,W(d)||!a),m=L.get(d.slot);return m&&(m.opened=!0),h.then(({state:w})=>w==="shown")},suppress(){for(let[t,a]of c){a.destroy(),c.delete(t),k.delete(t);let d=I.find(h=>h.slot===t);d&&_(d,"closed","suppressed",["suppressed"])}},debug:()=>[...b.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){K=!0;for(let t of S.values())t();S.clear(),ft?.(),pt?.(),F.clear(),Y.clear(),R.clear(),window[ee]?.delete(_e),window[X]===U&&delete window[X]}});window[X]=U;for(let{slot:t,resolve:a}of window[jt]?.splice(0)??[])a(U.open(t));return y&&console.table?.(U.debug()),U}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:rt};})();
|
|
1
|
+
(()=>{function v(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,o)=>{let d=document.createElement("script");d.src=e,d.async=!0,d.onload=()=>window[s]?n(window[s]):o(new Error(`${e} did not register`)),d.onerror=()=>o(new Error(`${e} did not load`)),document.head.append(d)}).finally(()=>Z.delete(s))),Z.get(s)):Promise.reject(new Error("the CDN script\u2019s own URL is unknown"))}var xt=v("onsite-answers.min.js"),Oe=()=>T(xt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.answers"));var It="/v1/capture/challenge",Mt=e=>typeof e=="string"&&/^\/v1\/[\w/-]+$/.test(e)?e:It;function Ne(e,s={}){let n=s.fetch??globalThis.fetch?.bind(globalThis),o=s.servingHost??e.servingHost,d=s.gatewayHost??e.gatewayHost;async function l(c,{method:i="GET",body:a,consent:p=!1,timeoutMs:y}={}){if(!n)return{status:0,body:null};try{let b=await n(c,{method:i,credentials:"omit",signal:y&&AbortSignal.timeout?.(y),headers:{accept:"application/json",authorization:`Bearer ${e.writeKey}`,...a?{"content-type":"application/json"}:{},...p?e.headers():{}},...a?{body:JSON.stringify(a)}:{}}),S=null;try{S=await b.json()}catch{}return{status:b.status,body:S}}catch{return{status:0,body:null}}}let g=(c,i)=>l(`${d}/v1/capture${c}`,{method:"POST",body:i}).then(a=>(a.status>=200&&a.status<300&&e.answered?.(i.answers,i.slot),a));return{decide:(c,i,{visitAudiences:a,visitCampaign:p,visitContext:y,pageFacts:b,timeoutMs:S=3e3}={})=>l(`${o}/v1/decisions`,{method:"POST",consent:!0,timeoutMs:Math.max(1,S),body:{slots:[i?{key:c,pin:{experiment:i[0],arm:i[1],split:i[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}:{},...a&&{visit_audiences:a.claims,...a.answered?.length&&{answered_audiences:a.answered}},...p?{visit_campaign:p}:{},...y?{visit_context:y}:{},...b?{page_facts:b}:{}}}),datafile:()=>l(`${o}/v1/audiences/datafile`,{timeoutMs:1500}),challenge:()=>l(`${d}${Mt(s.challenge)}`),capture:c=>g("",c),answers:c=>g("/answers",c),claim:c=>l(`${o}/v1/offers/claim`,{method:"POST",consent:!0,body:c,timeoutMs:8e3})}}var Ct=v("onsite-audiences.min.js"),Pe=()=>T(Ct,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.audiences"));function $e(e,s){let n={},o=()=>{try{let l=JSON.parse(e().getItem(s));l&&typeof l=="object"&&(n=l)}catch{}return n};return{read:o,write:l=>{let g=o();l(g),n=g;try{e().setItem(s,JSON.stringify(g))}catch{}}}}function ke(e,s=()=>!0){let n=$e(()=>sessionStorage,e),o=$e(()=>localStorage,e),d=()=>s()?o:n,l=()=>{let i=o.read();(i.sub!==void 0||i.k!==void 0)&&o.write(a=>{delete a.sub,delete a.k})},g=()=>s()?[n.read(),o.read()]:(l(),[n.read()]),c=(i,a)=>{var p;return i.f??(i.f={}),(p=i.f)[a]??(p[a]={}),i.f[a]};return{seen(i){let a=o.read().f?.[i]??{};return{session:n.read().f?.[i]?.n??0,lifetime:a.n??0,closedAt:a.c??null,submitted:a.s===1}},subscribed:()=>g().some(i=>i.sub===1),shown(i){n.write(a=>{let p=c(a,i);p.n=(p.n??0)+1}),o.write(a=>{let p=c(a,i);p.n=(p.n??0)+1})},closed(i,a=Date.now()){o.write(p=>{c(p,i).c=a})},tab(i,a){n.write(p=>{let y=c(p,i);a?y.t=1:delete y.t})},tabOut:i=>n.read().f?.[i]?.t===1,pin(i,a){if(a===void 0)return n.read().f?.[i]?.p??null;n.write(p=>{c(p,i).p=a})},coveredAt:()=>n.read().o??null,covered(i=Date.now()){n.write(a=>{a.o=i})},code(i,a=Date.now()){if(i===void 0){let[p]=g().flatMap(y=>y.k?[y.k]:[]).sort((y,b)=>b.at-y.at);return p&&a-p.at<14*864e5?p.c:null}return d().write(p=>{p.k={c:i,at:a}}),i},submitted(i){o.write(a=>{c(a,i).s=1}),d().write(a=>{a.sub=1})}}}var Dt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-facts");function fe(e=globalThis.window){let s=e?.[Dt];return s?.path===e?.location?.pathname?s.facts:{}}var Fe=e=>typeof e=="string"?e.slice(0,100):e,Le=e=>typeof e=="string"?e.trim().toLowerCase():e,Re=(e,s)=>e.every(n=>{let o=Fe(s?.[n.fact]),d=Array.isArray(n.values)?n.values:[];if(o==null||typeof o!=typeof d[0]||typeof o=="number"&&!Number.isFinite(o))return!1;let l=d.some(g=>Le(g)===Le(o));return n.op==="is"?l:n.op==="is_not"?!l:n.op==="at_least"?o>=d[0]:n.op==="at_most"&&o<=d[0]}),Ue=(e,s)=>Object.fromEntries(e.filter(n=>n.fact in s).map(n=>[n.fact,Fe(s[n.fact])]));var Ot=v("onsite-products.min.js"),Q=()=>T(Ot,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.products"));var Nt=v("onsite-render.min.js"),je=()=>T(Nt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.render"));var ee=(e,s=0)=>s<=6&&typeof e=="object"&&!!e&&(Array.isArray(e)?e.some(n=>ee(n,s+1)):typeof e.v=="string"||ee(e.b??e.i??e.a,s+1));var Pt=["source","medium","campaign","content","term"];var He=e=>String(e).trim().toLowerCase();function $t(e,s,n){let o=He(e),d=He(n);return s==="is"?o===d:s==="contains"&&d!==""&&o.includes(d)}function We(e,s){return(Array.isArray(e)?e:[]).every(n=>{let o=s?.[n?.field];return!Pt.includes(n?.field)||typeof o!="string"?!1:[].concat(n.values??[]).some(d=>$t(o,n.match,d))})}var te=["the page does not say so","not a product page"],ze=["popup","sheet","bar","teaser","inline","fullscreen"],kt=["entry","exit","scroll","time","idle","inline","manual"],he=e=>e!=="inline",Be=e=>e==="popup"||e==="sheet"||e==="fullscreen",x=e=>e!==null&&typeof e=="object"&&!Array.isArray(e),K=e=>Array.isArray(e)?e.filter(s=>typeof s=="string"):[],Ke=e=>Number.isInteger(e)&&e>=0?e:null,Xe=(e,s)=>e==null?[]:Array.isArray(e)&&e.every(x)?e:[s];function Ge(e){if(!x(e)||typeof e.slot!="string"||e.slot==="")return null;let s=x(e.trigger)?e.trigger:{};if(!ze.includes(e.format)||!kt.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:K(e.devices),aliases:K(e.aliases),audiences:K(e.audiences),arrived_from:Xe(e.arrived_from,{field:null,match:null,values:[]}),page_facts:Xe(e.page_facts,{fact:null,op:null,values:[]}),products:e.products===!0,caps:{per_session:Ke(n.per_session),lifetime:Ke(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 Lt=/^[a-z][a-z0-9_-]{0,31}$/;function qe(e){if(!x(e)||e.v!==1||!Array.isArray(e.steps))return null;let s=e.steps.filter(n=>x(n)&&Lt.test(n.id)&&Array.isArray(n.blocks));return s.length===0?null:{format:ze.includes(e.format)?e.format:null,theme:x(e.theme)?e.theme:{},steps:s}}function Ve(e,s){let n=String(e).split("*").map(o=>o.replace(/[.+?^${}()|[\]\\]/g,"\\$&")).join(".*");return new RegExp(`^${n}$`,"i").test(s)}function Ft(e,s){let n=K(e?.include);return(!n.length||n.some(o=>Ve(o,s)))&&!K(e?.exclude).some(o=>Ve(o,s))}function Je(e){return e.matchMedia?.("(hover: none) and (pointer: coarse)")?.matches===!0||e.innerWidth<768?"mobile":"desktop"}var Ye=e=>typeof e=="string"?Date.parse(e):Number.NaN,X=e=>e.trigger.type==="manual",ge="code in basket",we="outside its daily window",Ze=(e,s)=>{let{daily:n}=e.window;return n.next.find(o=>o>s)-n.within_hours*36e5-s};function me(e,s){let n=[];Ft(e.pages,s.path)||n.push("page not included"),e.devices.length&&!e.devices.includes(s.device)&&n.push(`not on ${s.device}`),We(e.arrived_from,s.campaign)||n.push("not from its campaign"),!s.later&&!s.preview&&(Re(e.page_facts,s.facts)||n.push(te[0]),e.products&&!s.product&&n.push(te[1]));let o=Ye(e.window.starts_at),d=Ye(e.window.ends_at);(s.now<o||s.now>=d)&&n.push("outside its dates");let{daily:l}=e.window;if(l&&!s.preview){let i=l.next?.find?.(a=>a>s.now)-s.now;i>0?!s.later&&i>l.within_hours*36e5&&n.push(we):n.push("no cut-off ahead")}if(e.audiences.length&&!s.preview&&(s.personalisation?s.audiences&&!e.audiences.some(i=>s.audiences.includes(i))&&n.push("not in its audiences"):n.push("audiences need personalisation consent")),s.preview||s.asked||X(e))return n;let{seen:g}=s,{caps:c}=e;return g.submitted&&n.push("already submitted"),e.exclude_subscribed===!0&&s.subscribed&&n.push("already subscribed"),e.exclude_code_applied===!0&&s.basketHasCode&&n.push(ge),c.per_session!==null&&g.session>=c.per_session&&n.push("per_session cap"),c.lifetime!==null&&g.lifetime>=c.lifetime&&n.push("lifetime cap"),c.after_close_days!==null&&g.closedAt&&s.now-g.closedAt<c.after_close_days*864e5&&n.push("closed recently"),n}var Qe=(e,s)=>s.priority-e.priority;var Rt=["mousemove","pointerdown","keydown","scroll","touchstart","wheel"];function Ut(){let e=[];return{on:(o,d,l,g={passive:!0})=>{o.addEventListener(d,l,g),e.push(()=>o.removeEventListener(d,l,g))},later:(o,d)=>{let l=setTimeout(o,d);e.push(()=>clearTimeout(l))},stop:()=>{for(let o of e.splice(0))o()}}}var et=(e,s)=>{let n=s.documentElement.scrollHeight||0;return n>0?(e.scrollY+e.innerHeight)/n:0},jt=e=>{let s=e.activeElement;return!!(s&&(/^(INPUT|TEXTAREA|SELECT)$/.test(s.tagName)||s.isContentEditable))};function Ht({on:e,later:s},n,o,d,l){let g=!1,c=!1,i=null,a=0;s(()=>{g=!0},o.delay_ms??5e3),e(l,"mousemove",p=>{p.clientY>d.innerHeight*.1&&(c=!0),i!==null&&(a=p.clientY-i),i=p.clientY}),e(l,"mouseout",p=>{g&&c&&!p.relatedTarget&&p.clientY<=0&&a<0&&!jt(l)&&n("exit")})}function Wt({on:e,later:s},n,o,d,l){let g=!1,c=0,i=d.scrollY,a=Date.now(),p=null,y=null;s(()=>{g=!0},o.delay_ms??5e3),e(d,"scroll",()=>{let b=d.scrollY,S=Date.now();if(c=Math.max(c,et(d,l)),b<i){(!p||S-p.t>300)&&(p={y:i,t:a});let I=p.y-b;g&&c>=.3&&I>=120&&I/Math.max(1,S-p.t)>=.5&&n("exit_scroll")}else p=null;i=b,a=S}),e(l,"visibilitychange",()=>{l.visibilityState==="hidden"?y=Date.now():y!==null&&Date.now()-y>=1e4&&n("return"),l.visibilityState!=="hidden"&&(y=null)})}function tt(e,s,{device:n,win:o=window,doc:d=document}){let l=Ut(),g=(e.seconds??30)*1e3;if(e.type==="entry"&&l.later(()=>s("entry"),e.delay_ms??0),e.type==="time"&&l.later(()=>s("time"),g),e.type==="exit"&&(n==="mobile"?Wt:Ht)(l,s,e,o,d),e.type==="scroll"){let c=e.depth??.5;l.on(o,"scroll",()=>et(o,d)>=c&&s("scroll"))}if(e.type==="idle"){let c=null,i=()=>{clearTimeout(c),c=setTimeout(()=>s("idle"),g)};i();for(let a of Rt)l.on(a==="scroll"?o:d,a,i);return l.on(d,"visibilitychange",i),()=>{clearTimeout(c),l.stop()}}return l.stop}var Kt=v("onsite-values.min.js"),nt=()=>T(Kt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.values"));var Xt=v("onsite-wheel.min.js"),st=()=>T(Xt,Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.wheel"));var ot=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite-access"),V=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite"),Vt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.pending"),Yt=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.listeners"),ne=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.page-said"),it=Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.suppressed"),rt={seen:()=>({session:0,lifetime:0,closedAt:null,submitted:!1}),subscribed:()=>!1,shown(){},closed(){},submitted(){},tab(){},tabOut:()=>!1,pin:()=>null,coveredAt:()=>null,covered(){},code:()=>null},zt=new Set(["decision-failed","no-creative","no-code","renderer-failed","products-failed","values-failed","error"]),at=3e3,lt={status:0,body:null},Bt=1500,ct=50,Gt=300,qt=()=>{try{return new URLSearchParams(location.search).get("hp_debug")==="onsite"}catch{return!1}},ut=(e,s)=>e.steps.some(n=>n.blocks.some(s));function dt(e,s={}){if(typeof window>"u"||typeof document>"u")return null;if(window[V])return window[V];let n=typeof e?.[ot]=="function"?e[ot]():null;if(!n)return console.warn("[hp] onsite: startOnsite needs the client bootstrap or createAnalytics made"),null;let o=s.settings??n.settings??{};n.started?.(o);let d=Ne(n,{...s,challenge:o.capture?.challenge}),l=n.preview?rt:ke(n.storageKey,n.personalisation),g=()=>n.campaign?.()??null,c=new Map,i=()=>window[it]?.size>0,a=(t,r)=>{for(let u of window[Yt]?.[t]??[])try{u(r)}catch(h){console.warn(`[hp] onsite ${t} listener failed:`,h)}},p=Je(window),y=n.debug||s.debug===!0||qt(),b=new Map,S=new Map,I=[];for(let t of Array.isArray(o.forms)?o.forms:[]){let r=Ge(t);r?I.push(r):b.set(String(t?.slot??`form ${b.size+1}`),{slot:String(t?.slot??""),state:"invalid",code:"invalid",reasons:["not a form this SDK can show"]})}let ye=()=>Pe().catch(t=>(console.warn("[hp] onsite audiences not loaded:",t?.message??t),null));n.personalisation()&&I.some(t=>t.audiences.length>0)&&ye().then(t=>t?.prefetch(d));let L=new Map,F=new Map,M=null,R=!1,be=new Set,pt=t=>{for(let r of L.keys()){let u=c.get(r);if(!t||!u||u.modal?.())return r}return null},Y=null,se=new Set,oe=Number.isInteger(o.overlay_gap_minutes)?o.overlay_gap_minutes:0,ft=()=>{let t=l.coveredAt();if(!(oe>0)||typeof t!="number")return null;let r=Math.max(0,Math.floor((Date.now()-t)/6e4));return r<oe?`a popup showed ${r} min ago; ${oe} min between them`:null},U=new Set,$=new Map,_e=()=>n.basketCodes?.()?.length>0,Se=(t,r,u)=>{r.includes(ge)&&$.set(t,u)},j=new Set,z=new Map,_=(t,r,u,h=[])=>(b.set(t.slot,{slot:t.slot,format:t.format,trigger:t.trigger.type,priority:t.priority,state:r,code:u,reasons:h}),y&&console.info(`[hp] onsite ${t.slot}: ${r}${h.length?` (${h.join("; ")})`:""}`),{state:r,code:u}),C=(t,r,u,h)=>(L.delete(t.slot),_(t,r,u,h)),k=(t,r,u)=>{let h;return Promise.race([t,new Promise(m=>{h=setTimeout(m,r-Date.now(),u)})]).then(m=>Date.now()>r?u:m).finally(()=>clearTimeout(h))},ht=(t,r)=>{R||i()||(M??(M=t.slot),a("nothing",{slot:t.slot,format:t.format,code:r}))},Ae=()=>{try{let t=s.audiences?.();return Array.isArray(t)?t:null}catch{return null}},Ee=t=>({path:location.pathname,device:p,campaign:g(),facts:fe(),product:n.pageProduct?.(),now:Date.now(),seen:l.seen(t.slot),subscribed:l.subscribed()||s.subscribed?.()===!0,basketHasCode:t.exclude_code_applied===!0&&_e(),personalisation:n.personalisation(),preview:!!n.preview,audiences:Ae()}),B=t=>{S.get(t.slot)?.(),S.delete(t.slot)};function P(t,r,u=!1,h=X(t),m=Date.now()+at){if(c.has(t.slot))return Promise.resolve({state:"shown",code:"shown",asked:h});let w=F.get(t.slot);return w?(w.asked||(w.asked=h),w.done):(w={asked:h},w.done=gt(t,r,u,h,m).catch(E=>c.has(t.slot)?{state:"shown",code:"shown"}:(console.warn("[hp] onsite form failed:",E?.message??E),C(t,"not shown","error",[`failed: ${E?.message??E}`]))).then(E=>(F.delete(t.slot),{...E,asked:w.asked||w.opened})),F.set(t.slot,w),w.done)}async function gt(t,r,u,h,m){if(i())return _(t,"not shown","suppressed",[`suppressed: ${[...window[it]].join(", ")}`]);let w=me(t,{...Ee(t),...u?{seen:rt.seen()}:{},asked:h});if(w.length){if(Se(t,w,!u),u&&w.every(f=>te.includes(f))&&j.add(t),w.length===1&&w[0]===we&&!h&&!u&&!R){let f=t.trigger.type==="inline"||t.format==="inline";B(t);let pe=setTimeout(()=>f?P(t,"inline"):ie(t),Ze(t,Date.now()));S.set(t.slot,()=>clearTimeout(pe))}return _(t,"not eligible","not-eligible",w)}j.delete(t);let E=Be(t.format)&&!u,D=E&&!h&&ft();if(D)return _(t,"not shown","overlay-gap",[D]);if(E&&!n.preview&&n.consentAnswered?.()===!1)return z.set(t,h),_(t,"not shown","awaiting-consent",["waiting for the consent banner"]);let O=he(t.format),xe=O&&pt(h);if(xe)return _(t,"not shown","another-showing",[`${xe} is showing`]);if(O&&M&&!h)return _(t,"not shown","allowance-spent",[`${M} already showed on this page view`]);let q=null;if(!O){try{q=document.querySelector(t.trigger.selector??"")}catch{q=null}if(!q)return _(t,"not shown","no-element",["no element matches its selector"])}O&&L.set(t.slot,t),B(t),_(t,"asking for a decision","deciding",[r]);let bt=je().catch(f=>(console.warn("[hp] onsite renderer not loaded:",f?.message??f),null)),J=t.visit_context===!0?Q().catch(()=>null):null,re=Ae()??[],Ie={claims:[...new Set([...t.audiences,...re])].filter(f=>re.includes(f)).slice(0,100)},_t=t.audiences.length>0&&!n.preview&&n.personalisation()?await k(ye().then(f=>f?f.visitAudiences(d,n.sessionSignals,t.audiences,re):Ie),Math.min(m,Date.now()+Bt),Ie):null,W=Date.now()<m?await k(d.decide(t.slot,l.pin(t.slot),{visitAudiences:_t,visitCampaign:t.arrived_from.length?g():null,visitContext:t.visit_context===!0?n.visitContext?.()??null:t.products?{product_id:n.pageProduct?.()}:null,pageFacts:t.page_facts.length?Ue(t.page_facts,fe()):null,timeoutMs:m-Date.now()}),m,lt):lt,ae=W.status===200?W.body?.decisions:null,A=Array.isArray(ae)?ae.find(f=>f?.slot===t.slot):null;A?.experiment&&A.arm&&A.split&&l.pin(t.slot,[A.experiment,A.arm,A.split]);let N=A&&A.holdout!==!0?qe(A.payload):null,Me=N?.steps[0].blocks??[],Ce=A?.offer?.code??(n.preview?"PREVIEW":l.code()),St=n.basketValue?.()??null,le=Me.some(f=>f?.t==="code")&&!Ce&&"no code to remind of"||Me.some(f=>f?.t==="progress")&&!(St>0)&&"the basket is empty";if(le){let f=le==="the basket is empty";return f&&U.add(t),C(t,"not shown",f?"empty-basket":"no-code",[le])}if(U.delete(t),$.delete(t),!N){let f=A?.holdout===!0;return f&&n.analytics()&&e.recordExposure(W.body),O&&f&&(M??(M=t.slot)),f&&!h&&a("held",{slot:t.slot,arm:A.arm??null,format:t.format}),f||Array.isArray(ae)?C(t,f?"held out":"no decision",f?"held-out":"no-creative",["no creative for this visitor"]):C(t,"no decision","decision-failed",[`decisions answered ${W.status}`])}let ce=await k(bt,m,null);if(!ce)return C(t,"not shown","renderer-failed",["the renderer did not load"]);let De=ut(N,f=>f?.t==="products");De&&(J??(J=Q().catch(()=>null)));let At=k(ce.warm?.(t,N,N.steps[0].id,be),Math.min(m,Date.now()+Gt)),[Et,ue]=await Promise.all([!De||k(J,m,null),ut(N,f=>(f?.t==="heading"||f?.t==="text")&&ee(f.text))&&k(nt().catch(()=>null),m,null)]);if(!Et)return C(t,"not shown","products-failed",["its products did not load"]);if(ue===null)return C(t,"not shown","values-failed",["its values did not load"]);if(await At,i())return C(t,"not shown","suppressed",["suppressed"]);let de=(f,pe={})=>a(f,{slot:t.slot,arm:A.arm??null,format:N.format??t.format,...pe}),vt=ce.mountForm({form:t,creative:N,decision:A,access:n,client:e,api:d,counters:l,loadWheel:st,loadAnswers:Oe,loadProducts:()=>J??Q(),container:q,warmed:be,coupon:Ce,basket:()=>n.basketValue?.()??null,fill:ue?ue.fillFor(t,n,s.values):void 0,emit:de,onClose(f){c.delete(t.slot),L.delete(t.slot),_(t,"closed","closed",[f]),de("closed",{reason:f})}});c.set(t.slot,vt),u||l.shown(t.slot),E&&l.covered(),O&&(M??(M=t.slot)),n.analytics()&&e.recordExposure(W.body);let Tt=_(t,"shown","shown",[r]);return de("shown"),Tt}function G(t,r,u=X(t)){if(!he(t.format))return P(t,r,!1,u);if(!Y){let h={forms:[],taken:new Set,deadline:Date.now()+ct+at};Y=h,se.add(h),setTimeout(()=>{Y=null,wt(h)},ct)}Y.forms.push([t,r,u])}async function wt(t){let r=t.forms.sort(([h],[m])=>Qe(h,m)),u=null;for(let[h,[m,w,E]]of r.entries()){if(t.taken.has(m))continue;let D=await P(m,w,!1,E,t.deadline);if(!u&&zt.has(D.code)&&!D.asked&&(u=[m,D.code]),D.state==="shown"||D.state==="held out"){for(let[O]of r.slice(h+1))_(O,"not shown","lower-priority",[`${m.slot} has a higher priority`]);u=null;break}}se.delete(t),u&&ht(...u)}function ve(t){if(t.format==="teaser"&&l.tabOut(t.slot))return P(t,"tab kept from an earlier page",!0);let r=me(t,{...Ee(t),later:!0});if(r.length)return Se(t,r,!1),_(t,"not eligible","not-eligible",r);let u=t.trigger.type;u==="manual"?_(t,"waiting for hp.onsite.open","waiting-for-open"):u==="inline"||t.format==="inline"?P(t,"inline"):ie(t)}for(let t of I)ve(t);function ie(t){B(t),S.set(t.slot,tt(t.trigger,r=>{B(t),G(t,r)},{device:p})),_(t,"armed","armed",[`${t.trigger.type} on ${p}`])}let mt=n.onConsentAnswered?.(()=>{let t=[...z];z.clear();for(let[r,u]of t)c.has(r.slot)||(u?G(r,"manual",u):ie(r))}),Te=()=>{let t=[...j];j.clear();for(let r of t)Promise.resolve(F.get(r.slot)?.done).then(()=>R||c.has(r.slot)||P(r,"tab kept from an earlier page",!0))};(window[ne]??(window[ne]=new Set)).add(Te);let yt=n.onBasket?.(()=>{if($.size&&!_e()){for(let[r,u]of $)setTimeout(()=>R||c.has(r.slot)||(u?G(r,"the basket changed"):ve(r)));$.clear()}if(!((n.basketValue?.()??0)>0))return;let t=[...U];U.clear();for(let r of t)c.has(r.slot)||G(r,"the basket changed")}),H=Object.freeze({open(t){let r=I.find(w=>w.slot===t),u=r??I.find(w=>w.aliases.includes(t));if(!u)return Promise.resolve(!1);if(c.has(u.slot))return Promise.resolve(!0);for(let w of se)w.taken.add(u);let h=P(u,"manual",!1,X(u)||!r),m=F.get(u.slot);return m&&(m.opened=!0),h.then(({state:w})=>w==="shown")},suppress(){for(let[t,r]of c){r.destroy(),c.delete(t),L.delete(t);let u=I.find(h=>h.slot===t);u&&_(u,"closed","suppressed",["suppressed"])}},debug:()=>[...b.values()].map(t=>({...t,reasons:[...t.reasons]})),stop(){R=!0;for(let t of S.values())t();S.clear(),yt?.(),mt?.(),U.clear(),$.clear(),z.clear(),j.clear(),window[ne]?.delete(Te),window[V]===H&&delete window[V]}});window[V]=H;for(let{slot:t,resolve:r}of window[Vt]?.splice(0)??[])r(H.open(t));return y&&console.table?.(H.debug()),H}window[Symbol.for("@thg-agentic/hyper-personalisation-web.onsite.module")]={startOnsite:dt};})();
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@thg-agentic/hyper-personalisation-web",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.35.0",
|
|
4
4
|
"description": "Browser SDK for the THG Hyper-Personalisation event specification: event tracking from a write key and remote settings, strict CMP-agnostic consent, a GA4 dataLayer bridge and in-session audience evaluation. Dependency-free ESM on the Segment wire protocol, a CDN script (dist/hp.min.js), and an optional @segment/analytics-next plugin path.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./src/index.js",
|
package/src/datalayer.js
CHANGED
|
@@ -180,7 +180,10 @@ function defaultMappings(steps) {
|
|
|
180
180
|
cart_id: text(p.ecommerce.cart_id),
|
|
181
181
|
value: p.value,
|
|
182
182
|
currency: p.currency,
|
|
183
|
-
|
|
183
|
+
// Only when the push names one: a missing coupon says nothing, and null is "no code".
|
|
184
|
+
...(p.ecommerce.coupon !== undefined
|
|
185
|
+
? { coupon: text(p.ecommerce.coupon) }
|
|
186
|
+
: {}),
|
|
184
187
|
// A view_cart without items says nothing about the basket; [] would claim it was empty.
|
|
185
188
|
...(p.itemsListed ? { products: p.products } : {}),
|
|
186
189
|
},
|
|
@@ -189,7 +192,9 @@ function defaultMappings(steps) {
|
|
|
189
192
|
needProducts('Checkout Started', {
|
|
190
193
|
value: p.value,
|
|
191
194
|
currency: p.currency,
|
|
192
|
-
|
|
195
|
+
...(p.ecommerce.coupon !== undefined
|
|
196
|
+
? { coupon: text(p.ecommerce.coupon) }
|
|
197
|
+
: {}),
|
|
193
198
|
products: p.products,
|
|
194
199
|
}),
|
|
195
200
|
add_shipping_info: (p) => ({
|
package/src/index.js
CHANGED
|
@@ -78,7 +78,12 @@ import {
|
|
|
78
78
|
recommendationContextFrom,
|
|
79
79
|
} from './recommendation-context.js';
|
|
80
80
|
import { sampledIn } from './sampling.js';
|
|
81
|
-
import {
|
|
81
|
+
import {
|
|
82
|
+
BASKET_CODE_EVENTS,
|
|
83
|
+
basketCodesAfter,
|
|
84
|
+
basketItemsOf,
|
|
85
|
+
recordSessionEvent,
|
|
86
|
+
} from './session/record.js';
|
|
82
87
|
import {
|
|
83
88
|
clearSessionSignals,
|
|
84
89
|
getSessionSignals,
|
|
@@ -546,6 +551,8 @@ export function createAnalytics(options) {
|
|
|
546
551
|
/** How many items it holds, when its lines say, and its currency, when it names one. */
|
|
547
552
|
let pageItems = null;
|
|
548
553
|
let pageCurrency = null;
|
|
554
|
+
/** The discount codes in the basket as this page reported them (`basketCodesAfter`), or null. */
|
|
555
|
+
let pageCodes = null;
|
|
549
556
|
/** The product this page is about: the last Product Viewed it sent, for an onsite form's products. */
|
|
550
557
|
let pageProduct = null;
|
|
551
558
|
const basketListeners = new Set();
|
|
@@ -559,7 +566,29 @@ export function createAnalytics(options) {
|
|
|
559
566
|
pageProduct = typeof id === 'string' && id ? id : pageProduct;
|
|
560
567
|
pageSaid();
|
|
561
568
|
}
|
|
562
|
-
if (partial.type !== 'track'
|
|
569
|
+
if (partial.type !== 'track') return;
|
|
570
|
+
// From the codes as they stand, the visit's kept ones until this page reports a basket, so a
|
|
571
|
+
// code taken out here of a basket from an earlier page is taken out of that one.
|
|
572
|
+
let codesChanged = false;
|
|
573
|
+
if (BASKET_CODE_EVENTS.has(partial.event))
|
|
574
|
+
try {
|
|
575
|
+
const before = basketCodes();
|
|
576
|
+
const codes = basketCodesAfter(
|
|
577
|
+
before,
|
|
578
|
+
partial.event,
|
|
579
|
+
partial.properties,
|
|
580
|
+
);
|
|
581
|
+
codesChanged = codes !== before;
|
|
582
|
+
// Kept for the page even when unchanged, so it outlasts a withdrawn consent.
|
|
583
|
+
pageCodes = codes;
|
|
584
|
+
} catch (err) {
|
|
585
|
+
// The event goes whatever its codes say.
|
|
586
|
+
if (cfg.debug) console.warn('[hp] basket codes not read', err);
|
|
587
|
+
}
|
|
588
|
+
if (partial.event !== 'Cart Updated') {
|
|
589
|
+
if (codesChanged) tellBasketListeners();
|
|
590
|
+
return;
|
|
591
|
+
}
|
|
563
592
|
const value = partial.properties?.value;
|
|
564
593
|
const lines = partial.properties?.products;
|
|
565
594
|
pageItems = Array.isArray(lines) ? basketItemsOf(lines) : null;
|
|
@@ -568,6 +597,19 @@ export function createAnalytics(options) {
|
|
|
568
597
|
typeof value === 'number' && Number.isFinite(value) && value >= 0
|
|
569
598
|
? value
|
|
570
599
|
: null;
|
|
600
|
+
tellBasketListeners();
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
/** The basket's codes: this page's, else the visit's kept ones, else null (none reported). */
|
|
604
|
+
function basketCodes() {
|
|
605
|
+
if (pageCodes !== null) return pageCodes;
|
|
606
|
+
// Kept only under personalisation consent, in the visit's own scope (a new page has none yet).
|
|
607
|
+
if (!personalisationGranted()) return null;
|
|
608
|
+
scopeVisit();
|
|
609
|
+
return getSessionSignals().basketCodes;
|
|
610
|
+
}
|
|
611
|
+
|
|
612
|
+
function tellBasketListeners() {
|
|
571
613
|
for (const listener of basketListeners)
|
|
572
614
|
try {
|
|
573
615
|
listener();
|
|
@@ -605,7 +647,8 @@ export function createAnalytics(options) {
|
|
|
605
647
|
context: buildContext(cfg, contextOverrides(ctxOverrides)),
|
|
606
648
|
};
|
|
607
649
|
|
|
608
|
-
if (event.properties)
|
|
650
|
+
if (event.properties)
|
|
651
|
+
event.properties = pruneProperties(event.properties, event.event);
|
|
609
652
|
if (typeof event.properties?.href === 'string')
|
|
610
653
|
event.properties.href = scrubHref(event.properties.href, cfg);
|
|
611
654
|
|
|
@@ -1263,6 +1306,11 @@ export function createAnalytics(options) {
|
|
|
1263
1306
|
const value = getSessionSignals().basketValue;
|
|
1264
1307
|
return pageBasket ?? (Number.isFinite(value) ? value : null);
|
|
1265
1308
|
},
|
|
1309
|
+
/**
|
|
1310
|
+
* The discount codes in the basket: the ones this page reported, else the ones this visit
|
|
1311
|
+
* kept (under personalisation consent), else null when no cart event has named them.
|
|
1312
|
+
*/
|
|
1313
|
+
basketCodes,
|
|
1266
1314
|
/**
|
|
1267
1315
|
* What a form's text may show (ADR 0064, shopper values): the basket's value and items,
|
|
1268
1316
|
* as for a basket bar, in the currency of the basket the value came from (else the
|
package/src/onsite/index.js
CHANGED
|
@@ -29,6 +29,7 @@ import {
|
|
|
29
29
|
ASKED,
|
|
30
30
|
blockers,
|
|
31
31
|
byPriority,
|
|
32
|
+
CODE_IN_BASKET,
|
|
32
33
|
deviceOf,
|
|
33
34
|
INTERRUPTS,
|
|
34
35
|
OUTSIDE_WINDOW,
|
|
@@ -233,6 +234,15 @@ export function startOnsite(client, options = {}) {
|
|
|
233
234
|
};
|
|
234
235
|
/** Forms whose trigger fired on an empty basket: they try again when the basket changes. */
|
|
235
236
|
const awaitingBasket = new Set();
|
|
237
|
+
/**
|
|
238
|
+
* Forms a code in the basket held back, and whether their trigger had fired: once it has none, a
|
|
239
|
+
* fired one competes to show at once and any other is started again.
|
|
240
|
+
*/
|
|
241
|
+
const awaitingNoCode = new Map();
|
|
242
|
+
const basketHasCode = () => access.basketCodes?.()?.length > 0;
|
|
243
|
+
const holdForCode = (form, reasons, fired) => {
|
|
244
|
+
if (reasons.includes(CODE_IN_BASKET)) awaitingNoCode.set(form, fired);
|
|
245
|
+
};
|
|
236
246
|
/**
|
|
237
247
|
* Teasers' tabs kept from an earlier page, held back only until the page says what it is about
|
|
238
248
|
* (its facts, its product), which it may do after onsite starts: they try again when it does.
|
|
@@ -307,6 +317,8 @@ export function startOnsite(client, options = {}) {
|
|
|
307
317
|
now: Date.now(),
|
|
308
318
|
seen: counters.seen(form.slot),
|
|
309
319
|
subscribed: counters.subscribed() || options.subscribed?.() === true,
|
|
320
|
+
// Read only for a form that asks: it reads the visit's kept signals.
|
|
321
|
+
basketHasCode: form.exclude_code_applied === true && basketHasCode(),
|
|
310
322
|
personalisation: access.personalisation(),
|
|
311
323
|
preview: Boolean(access.preview),
|
|
312
324
|
audiences: sessionAudiences(),
|
|
@@ -372,6 +384,7 @@ export function startOnsite(client, options = {}) {
|
|
|
372
384
|
asked,
|
|
373
385
|
});
|
|
374
386
|
if (reasons.length) {
|
|
387
|
+
holdForCode(form, reasons, !kept);
|
|
375
388
|
if (kept && reasons.every((r) => UNSAID.includes(r)))
|
|
376
389
|
awaitingPage.add(form);
|
|
377
390
|
// A trigger that fired before the form's daily window opened is watched again once it
|
|
@@ -532,6 +545,7 @@ export function startOnsite(client, options = {}) {
|
|
|
532
545
|
]);
|
|
533
546
|
}
|
|
534
547
|
awaitingBasket.delete(form);
|
|
548
|
+
awaitingNoCode.delete(form);
|
|
535
549
|
if (!creative) {
|
|
536
550
|
const held = decision?.holdout === true;
|
|
537
551
|
// A held-out visitor whose trigger fired is exposed to the default, as a treated one is,
|
|
@@ -688,19 +702,18 @@ export function startOnsite(client, options = {}) {
|
|
|
688
702
|
if (missed) say(...missed);
|
|
689
703
|
}
|
|
690
704
|
|
|
691
|
-
|
|
705
|
+
/** A form as the page starts it, and again once a code that held it back leaves the basket. */
|
|
706
|
+
function start(form) {
|
|
692
707
|
// A teaser's tab still out from an earlier page comes back whatever its caps and trigger.
|
|
693
|
-
if (form.format === 'teaser' && counters.tabOut(form.slot))
|
|
694
|
-
show(form, 'tab kept from an earlier page', true);
|
|
695
|
-
continue;
|
|
696
|
-
}
|
|
708
|
+
if (form.format === 'teaser' && counters.tabOut(form.slot))
|
|
709
|
+
return show(form, 'tab kept from an earlier page', true);
|
|
697
710
|
// What the page says, which product it is about, and whether its daily window is open may
|
|
698
711
|
// all change while the shopper is on it, so a form waits on its trigger for them; they are
|
|
699
712
|
// judged when it fires.
|
|
700
713
|
const reasons = blockers(form, { ...env(form), later: true });
|
|
701
714
|
if (reasons.length) {
|
|
702
|
-
|
|
703
|
-
|
|
715
|
+
holdForCode(form, reasons, false);
|
|
716
|
+
return note(form, 'not eligible', 'not-eligible', reasons);
|
|
704
717
|
}
|
|
705
718
|
const type = form.trigger.type;
|
|
706
719
|
if (type === 'manual')
|
|
@@ -709,6 +722,7 @@ export function startOnsite(client, options = {}) {
|
|
|
709
722
|
show(form, 'inline');
|
|
710
723
|
else arm(form);
|
|
711
724
|
}
|
|
725
|
+
for (const form of forms) start(form);
|
|
712
726
|
|
|
713
727
|
/** Watch a form's trigger; when it fires, the form competes to show. */
|
|
714
728
|
function arm(form) {
|
|
@@ -753,6 +767,17 @@ export function startOnsite(client, options = {}) {
|
|
|
753
767
|
(window[PAGE_SAID] ??= new Set()).add(heard);
|
|
754
768
|
|
|
755
769
|
const stopBasket = access.onBasket?.(() => {
|
|
770
|
+
if (awaitingNoCode.size && !basketHasCode()) {
|
|
771
|
+
// A task later, so an attempt that held one back has finished being opened.
|
|
772
|
+
for (const [form, fired] of awaitingNoCode)
|
|
773
|
+
setTimeout(
|
|
774
|
+
() =>
|
|
775
|
+
stopped ||
|
|
776
|
+
mounted.has(form.slot) ||
|
|
777
|
+
(fired ? fire(form, 'the basket changed') : start(form)),
|
|
778
|
+
);
|
|
779
|
+
awaitingNoCode.clear();
|
|
780
|
+
}
|
|
756
781
|
if (!((access.basketValue?.() ?? 0) > 0)) return;
|
|
757
782
|
// Out of the set before the decision is asked, so a second update cannot show them twice;
|
|
758
783
|
// covering ones compete on priority as any trigger does.
|
|
@@ -803,6 +828,7 @@ export function startOnsite(client, options = {}) {
|
|
|
803
828
|
stopBasket?.();
|
|
804
829
|
stopConsent?.();
|
|
805
830
|
awaitingBasket.clear();
|
|
831
|
+
awaitingNoCode.clear();
|
|
806
832
|
awaitingConsent.clear();
|
|
807
833
|
awaitingPage.clear();
|
|
808
834
|
window[PAGE_SAID]?.delete(heard);
|
package/src/onsite/rules.js
CHANGED
|
@@ -148,6 +148,9 @@ const at = (iso) => (typeof iso === 'string' ? Date.parse(iso) : Number.NaN);
|
|
|
148
148
|
*/
|
|
149
149
|
export const ASKED = (form) => form.trigger.type === 'manual';
|
|
150
150
|
|
|
151
|
+
/** Why a form that hides from a basket with a discount code in it is not shown. */
|
|
152
|
+
export const CODE_IN_BASKET = 'code in basket';
|
|
153
|
+
|
|
151
154
|
/** A form held back only until its daily window opens; `opensIn` says how long that is. */
|
|
152
155
|
export const OUTSIDE_WINDOW = 'outside its daily window';
|
|
153
156
|
export const opensIn = (form, now) => {
|
|
@@ -158,7 +161,7 @@ export const opensIn = (form, now) => {
|
|
|
158
161
|
/**
|
|
159
162
|
* Every reason `form` may not show now, empty when it may: its pages, devices, campaign, page
|
|
160
163
|
* facts and products, dates and daily cut-off, audiences and counters. `env` is the page:
|
|
161
|
-
* `{ path, device, campaign, facts, product, now, seen, subscribed, personalisation, preview,
|
|
164
|
+
* `{ path, device, campaign, facts, product, now, seen, subscribed, basketHasCode, personalisation, preview,
|
|
162
165
|
* audiences }`, where `campaign` is the visit's (`visitCampaign`), `facts` what the page said
|
|
163
166
|
* about itself (`hp.onsite.facts`), `product` the id of the product the page is about (its last
|
|
164
167
|
* Product Viewed), `seen` the slot's counters and `audiences` the
|
|
@@ -211,6 +214,8 @@ export function blockers(form, env) {
|
|
|
211
214
|
if (seen.submitted) reasons.push('already submitted');
|
|
212
215
|
if (form.exclude_subscribed === true && env.subscribed)
|
|
213
216
|
reasons.push('already subscribed');
|
|
217
|
+
if (form.exclude_code_applied === true && env.basketHasCode)
|
|
218
|
+
reasons.push(CODE_IN_BASKET);
|
|
214
219
|
if (caps.per_session !== null && seen.session >= caps.per_session)
|
|
215
220
|
reasons.push('per_session cap');
|
|
216
221
|
if (caps.lifetime !== null && seen.lifetime >= caps.lifetime)
|
package/src/segment.js
CHANGED
|
@@ -329,7 +329,8 @@ export function cdpPlugins(options = {}) {
|
|
|
329
329
|
context.identity_trust = event.anonymousId ? 'device' : 'none';
|
|
330
330
|
event.context = context;
|
|
331
331
|
|
|
332
|
-
if (event.properties)
|
|
332
|
+
if (event.properties)
|
|
333
|
+
event.properties = pruneProperties(event.properties, event.event);
|
|
333
334
|
return ctx;
|
|
334
335
|
}
|
|
335
336
|
|