1import{AlgoliaProductFetcher,formatAlgoliaProductHit}from"@lyle/algolia-product-fetcher";import{createMoneyFormatter,escapeHtml,formatMoney,imageUrl,isSameProduct,isWhiteSwatch,metafieldValue,parseJson}from"@lyle/algolia-product-utils";const QUICK_VIEW_OPEN_DELAY=450,QUANTITY_UPDATE_DELAY=100,NEWSLETTER_MODAL_TIMEOUT=5e3,LOYALTY_CLAIM_TIMEOUT=8e3;class LyleCartDrawer extends HTMLElement{#abortController=null;#claimHandler=claimedReward=>this.#handleRewardClaimed(claimedReward);#config=null;#fetcher=null;#loyaltyObserver=null;#loyaltyTimer=null;#moneyFormatter=null;#newsletterObserver=null;#newsletterTimer=null;#openTimer=null;#popup=null;#quickView=null;#quickViewPromise=null;#quantityAbortController=null;#recommendationsLoaded=!1;#reconcilingGifts=!1;#restoreDrawerAfterNewsletter=()=>{requestAnimationFrame(()=>{this.isConnected&&!this.#popup.matches(":popover-open")&&this.#popup.showPopover()})};#reward=null;#upsellFallback=null;#upsellSplide=null;connectedCallback(){if(this.#config=parseJson(this.querySelector("[data-cart-drawer-config]")?.textContent),this.#popup=this.querySelector("#CartDrawer"),!this.#config||!this.#popup)return;this.#abortController=new AbortController;const{signal}=this.#abortController;this.#moneyFormatter=createMoneyFormatter(this.#config.market),this.#fetcher=new AlgoliaProductFetcher({config:this.#config,signal}),this.addEventListener("click",this.#handleClick,{signal}),this.addEventListener("change",this.#handleChange,{signal}),this.addEventListener("submit",this.#handleSubmit,{signal}),this.#popup.addEventListener("toggle",this.#handleToggle,{signal}),this.querySelector("[data-quick-view-overlay]")?.addEventListener("toggle",event=>this.#quickView?.handleToggle(event),{signal}),document.addEventListener("click",this.#handleDocumentClick,{signal}),document.addEventListener("cart:add",this.#handleCartEvent,{signal}),document.addEventListener("cart:refresh",this.#handleCartEvent,{signal}),this.#updateCartCounts(this.#config.cart.itemCount),this.#initLoyaltyLion(),this.#reconcileGifts(),new URLSearchParams(window.location.search).get("openCart")==="true"&&this.open()}disconnectedCallback(){this.#abortController?.abort(),this.#quantityAbortController?.abort(),this.#loyaltyObserver?.disconnect(),this.#newsletterObserver?.disconnect(),this.#upsellSplide?.destroy(),window.clearTimeout(this.#loyaltyTimer),window.clearTimeout(this.#newsletterTimer),window.clearTimeout(this.#openTimer),window._llCartClaimHandler===this.#claimHandler&&(window._llCartClaimHandler=null),this.#upsellSplide=null,this.#upsellFallback=null}open(){return typeof this.#popup?.showPopover!="function"?!1:(this.#closeHeaderOverlays(),this.#popup.matches(":popover-open")||this.#popup.showPopover(),!0)}#handleDocumentClick=event=>{!event.target.closest("[data-cart-drawer-trigger]")||typeof this.#popup?.showPopover!="function"||(event.preventDefault(),this.open())};#handleCartEvent=event=>{if(window.clearTimeout(this.#openTimer),event.detail?.optimistic){this.#showOptimisticAdd(event.detail.optimistic);return}if(event.detail?.rollback){this.#clearOptimisticAdd(),this.#popup.hidePopover?.();return}const delay=event.type==="cart:refresh"?QUICK_VIEW_OPEN_DELAY:0,sectionHtml=event.detail?.sections?.[this.#config.sectionId];this.#openTimer=window.setTimeout(()=>{this.#refresh(sectionHtml)},delay)};#showOptimisticAdd(item){this.#clearOptimisticAdd(),this.#updateCartCounts(this.#config.cart.itemCount+item.quantity),this.querySelector(".cart-drawer__header")?.classList.remove("cart-drawer__header--empty");let list=this.querySelector(".cart-drawer__items");if(!list){list=document.createElement("ul"),list.className="cart-drawer__items",list.setAttribute("data-cart-optimistic-items","");const emptyState=this.querySelector(".cart-drawer__empty");emptyState?.setAttribute("data-cart-optimistic-state",""),emptyState?emptyState.prepend(list):this.querySelector("[data-cart-error]")?.after(list)}const options=item.options.filter(option=>option&&option!=="Default Title").map(option=>`<span>${escapeHtml(option)}</span>`).join('<span class="cart-drawer-line-item__separator" aria-hidden="true"></span>'),image=item.imageUrl?`<img class="cart-drawer-line-item__image" src="${escapeHtml(item.imageUrl)}" alt="${escapeHtml(item.imageAlt||item.title)}" width="112" height="140">`:"";list.insertAdjacentHTML("afterbegin",`<li class="cart-drawer-line-item" data-cart-optimistic-add> 2 <a class="cart-drawer-line-item__image-link" href="${escapeHtml(item.url)}" tabindex="-1" aria-hidden="true">${image}</a> 3 <div class="cart-drawer-line-item__content"> 4 <div class="cart-drawer-line-item__header"> 5 <div class="cart-drawer-line-item__identity"> 6 <a class="cart-drawer-line-item__title text-body-sm" href="${escapeHtml(item.url)}">${escapeHtml(item.title)}</a> 7 ${options?`<div class="cart-drawer-line-item__variants text-body-xs">${options}</div>`:""} 8 </div> 9 <div class="cart-drawer-line-item__price-group"> 10 <div class="cart-drawer-line-item__prices text-body-sm"><span class="cart-drawer-line-item__price">${escapeHtml(item.price)}</span></div> 11 </div> 12 </div> 13 </div> 14 </li>`),this.open()}#clearOptimisticAdd(){this.querySelector("[data-cart-optimistic-add]")?.remove(),this.querySelector("[data-cart-optimistic-items]")?.remove(),this.querySelector(".cart-drawer__empty")?.removeAttribute("data-cart-optimistic-state"),this.querySelector(".cart-drawer__header")?.classList.toggle("cart-drawer__header--empty",this.#config.cart.itemCount===0),this.#updateCartCounts(this.#config.cart.itemCount)}#handleToggle=()=>{this.#popup.matches(":popover-open")&&(this.#closeHeaderOverlays(),this.#initUpsell(),this.#loadRecommendations(),this.#syncLoyaltyLion())};#handleClick=event=>{const quantityButton=event.target.closest("[data-cart-quantity]"),removeButton=event.target.closest("[data-cart-remove]");if(this.getAttribute("aria-busy")==="true"&&(!quantityButton&&!removeButton||!this.#quantityAbortController))return;const newsletter=event.target.closest("[data-cart-newsletter]"),marketSwitcher=event.target.closest("[data-cart-market-switcher]"),loyaltyApply=event.target.closest("[data-cart-loyalty-apply]"),quickView=event.target.closest("[data-quick-view]"),quickViewClose=event.target.closest("[data-quick-view-close]"),quickViewAdd=event.target.closest("[data-quick-view-add]"),quickViewArrow=event.target.closest("[data-quick-view-arrow]"),quickViewSize=event.target.closest("[data-quick-view-size]"),quickViewSwatch=event.target.closest("[data-quick-view-swatch]"),upsellSwatch=event.target.closest("[data-cart-upsell-swatch]");if(upsellSwatch){this.#selectUpsellSwatch(upsellSwatch);return}if(quickView){this.#openQuickView(quickView);return}if(quickViewClose){this.#quickView?.close();return}if(quickViewAdd){this.#quickView?.add(quickViewAdd);return}if(quickViewArrow){this.#quickView?.scrollGallery();return}if(quickViewSize){this.#quickView?.selectVariant(quickViewSize);return}if(quickViewSwatch){this.#quickView?.selectSwatch(quickViewSwatch);return}if(quantityButton){const line=quantityButton.closest("[data-cart-line]"),input=line?.querySelector("[data-cart-quantity-input]");if(!line||!input)return;const change=quantityButton.dataset.cartQuantity==="increase"?1:-1,quantity=Math.max(1,(Number(input.value)||Number(input.min)||1)+change),max=Number(input.max)||1/0;this.#changeLine(line,Math.min(quantity,max));return}if(removeButton){const line=removeButton.closest("[data-cart-line]");line&&this.#changeLine(line,0);return}if(newsletter){this.#openNewsletter(newsletter.dataset.cartNewsletter);return}if(marketSwitcher){this.#popup.hidePopover?.(),document.querySelector("#MarketSwitcherCountryDrawer")?.showPopover?.();return}loyaltyApply&&this.#claimLoyaltyReward()};async#openQuickView(button){this.#quickViewPromise||(this.#quickViewPromise=import("@lyle/algolia-product-card-quick-view"));const{AlgoliaProductCardQuickView}=await this.#quickViewPromise;this.isConnected&&(this.#quickView||(this.#quickView=new AlgoliaProductCardQuickView({callbacks:{cardProduct:card=>this.#cardProduct(card),familyTag:product=>this.#fetcher.familyTag(product),fetchProductJson:handle=>this.#fetcher.fetchProductJson(handle),fetchRelatedProductsBatch:tags=>this.#fetcher.fetchRelatedProductsBatch(tags),filterColourProducts:(product,relatedProducts)=>this.#fetcher.filterColourProducts(product,relatedProducts),formatMoney:value=>this.#formatMoney(value),sendConversionEvent:()=>{}},config:this.#config,icons:window.icons||{},root:this})),await this.#quickView.open(button))}#openNewsletter(formId){this.#newsletterObserver?.disconnect(),window.clearTimeout(this.#newsletterTimer);const promoteModal=()=>{const modal=document.querySelector('[data-testid="POPUP"]')?.closest('[role="dialog"]');if(!(!modal||typeof modal.showPopover!="function")){modal.setAttribute("popover","manual");try{modal.matches(":popover-open")&&modal.hidePopover(),modal.showPopover()}catch{return}modal.querySelector('button[aria-label="Close dialog"]')?.addEventListener("click",this.#restoreDrawerAfterNewsletter,{once:!0}),modal.addEventListener("keydown",event=>{event.key==="Escape"&&this.#restoreDrawerAfterNewsletter()}),this.#newsletterObserver?.disconnect(),this.#newsletterObserver=null,window.clearTimeout(this.#newsletterTimer)}};this.#newsletterObserver=new MutationObserver(promoteModal),this.#newsletterObserver.observe(document.body,{childList:!0,subtree:!0}),this.#newsletterTimer=window.setTimeout(()=>{this.#newsletterObserver?.disconnect(),this.#newsletterObserver=null},NEWSLETTER_MODAL_TIMEOUT),window._klOnsite=window._klOnsite||[],window._klOnsite.push(["openForm",formId]),promoteModal()}#handleChange=event=>{const input=event.target.closest("[data-cart-quantity-input]"),line=input?.closest("[data-cart-line]");if(!input||!line||this.getAttribute("aria-busy")==="true"&&!this.#quantityAbortController)return;const min=Number(input.min)||1,max=Number(input.max)||1/0,quantity=Math.min(Math.max(Number(input.value)||min,min),max);this.#changeLine(line,quantity)};#handleSubmit=event=>{const giftForm=event.target.closest("[data-cart-gift-form]");if(giftForm){event.preventDefault(),this.getAttribute("aria-busy")!=="true"&&this.#addGift(giftForm);return}const form=event.target.closest("[data-cart-discount-form]");form&&(event.preventDefault(),this.getAttribute("aria-busy")!=="true"&&this.#a
14pplyDiscount(form))};async#addGift(form){const variantId=Number(new FormData(form).get("id")),giftId=form.dataset.giftId;if(!(!variantId||!giftId)){this.#setBusy(!0);try{const cart=await this.#cartRequest(this.#config.routes.add,{items:[{id:variantId,quantity:1,properties:{__gift:giftId,__gift_discount:100,__gift_message:this.#config.strings.giftLine}}]});await this.#refresh(cart.sections?.[this.#config.sectionId])}catch{this.#showError(this.#config.strings.error)}finally{this.isConnected&&this.#setBusy(!1)}}}async#changeLine(line,quantity){const input=line.querySelector("[data-cart-quantity-input]"),confirmedQuantity=Number(input?.defaultValue)||1;input&&quantity>0?this.#setLineQuantity(line,quantity):quantity===0&&this.#setLineRemoving(line,!0);const updates=Object.fromEntries([...this.querySelectorAll("[data-cart-line]")].map(cartLine=>[cartLine.dataset.lineKey,cartLine.hasAttribute("data-cart-removing")?0:Number(cartLine.querySelector("[data-cart-quantity-input]")?.value??cartLine.dataset.cartLineQuantity)]));this.#quantityAbortController?.abort();const abortController=new AbortController;this.#quantityAbortController=abortController,this.#setBusy(!0);try{if(quantity>0&&(await new Promise(resolve=>window.setTimeout(resolve,QUANTITY_UPDATE_DELAY)),abortController.signal.aborted))return;let cart;try{cart=await this.#cartRequest(this.#config.routes.update,{updates},abortController.signal)}catch(error){if(error.status!==422||!this.querySelector("[data-cart-removing]"))throw error;cart=await this.#retryLineUpdate(updates,abortController.signal)}this.#updateCartCounts(cart.item_count),await this.#refresh(cart.sections?.[this.#config.sectionId])}catch{if(abortController.signal.aborted)return;input&&this.#setLineQuantity(line,confirmedQuantity),quantity===0&&this.#setLineRemoving(line,!1),await this.#refresh(),this.#showError(this.#config.strings.error)}finally{if(this.#quantityAbortController!==abortController)return;this.#quantityAbortController=null,this.isConnected&&this.#setBusy(!1)}}async#retryLineUpdate(updates,signal){const response=await fetch(`${this.#config.routes.cart}.js`,{credentials:"same-origin",headers:{Accept:"application/json"},signal});if(!response.ok)throw new Error("Cart request failed");const cart=await response.json(),currentKeys=new Set(cart.items.map(item=>item.key)),rebasedUpdates=Object.fromEntries(Object.entries(updates).filter(([key])=>currentKeys.has(key)));return Object.keys(rebasedUpdates).length?this.#cartRequest(this.#config.routes.update,{updates:rebasedUpdates},signal):cart}#setLineQuantity(line,quantity){const input=line.querySelector("[data-cart-quantity-input]");input&&(input.value=quantity,line.querySelector('[data-cart-quantity="decrease"]').disabled=quantity<=(Number(input.min)||1),line.querySelector('[data-cart-quantity="increase"]').disabled=quantity>=(Number(input.max)||1/0),this.#updateOptimisticCount())}#setLineRemoving(line,removing){line.toggleAttribute("data-cart-removing",removing),line.hidden=removing,this.#updateOptimisticCount()}#updateOptimisticCount(){const itemCount=[...this.querySelectorAll("[data-cart-line]")].reduce((count,line)=>{const confirmedQuantity=Number(line.dataset.cartLineQuantity),quantity=line.hasAttribute("data-cart-removing")?0:Number(line.querySelector("[data-cart-quantity-input]")?.value??confirmedQuantity);return count+quantity-confirmedQuantity},this.#config.cart.itemCount);this.#updateCartCounts(itemCount)}async#applyDiscount(form,loyalty=null){const details=form?.closest(".cart-drawer__discount"),input=form?.querySelector("[data-cart-discount-input]"),code=loyalty?.code||input?.value.trim();if(!code)return!1;this.#setBusy(!0),this.#showDiscountMessage("",!1,details);try{const codes=[...new Set([...this.#config.cart.discountCodes,code])],cart=await this.#cartRequest(this.#config.routes.update,{discount:codes.join(",")});if(!cart.discount_codes?.find(discount=>discount.code?.toLowerCase()===code.toLowerCase())?.applicable){const message=loyalty?this.#config.strings.loyaltyError:form?.dataset.errorMessage||this.#config.strings.discountError;return loyalty?this.#showError(message):this.#showDiscountMessage(message,!0,details),!1}if(loyalty)try{localStorage.setItem("ll_redeemed",JSON.stringify({code,reward:loyalty.reward}))}catch{}this.#updateCartCounts(cart.item_count);const replacement=await this.#refresh(cart.sections?.[this.#config.sectionId]);return replacement&&replacement.#showDiscountMessage(form?.dataset.successMessage||"",!1),!!replacement}catch{const message=loyalty?this.#config.strings.loyaltyError:form?.dataset.errorMessage||this.#config.strings.discountError;return loyalty?this.#showError(message):this.#showDiscountMessage(message,!0,details),!1}finally{this.isConnected&&this.#setBusy(!1)}}
14async#cartRequest(url,body,signal){const response=await fetch(url,{method:"POST",credentials:"same-origin",headers:{Accept:"application/json","Content-Type":"application/json"},signal,body:JSON.stringify({...body,sections:this.#config.sectionId})}),cart=await response.json();if(!response.ok||cart.status){const error=new Error("Cart request failed");throw error.status=response.status,error}return cart}async#refresh(sectionHtml=null){this.#setBusy(!0);try{if(!sectionHtml){const url=new URL(this.#config.routes.cart,window.location.origin);url.searchParams.set("section_id",this.#config.sectionId);const response=await fetch(url,{credentials:"same-origin",headers:{Accept:"text/html"}});if(!response.ok)throw new Error("Cart section request failed");sectionHtml=await response.text()}const replacement=new DOMParser().parseFromString(sectionHtml,"text/html").querySelector("lyle-cart-drawer"),nextPopup=replacement?.querySelector("#CartDrawer"),currentBody=this.#popup.querySelector(".popup-drawer__body"),nextBody=nextPopup?.querySelector(".popup-drawer__body"),currentState=currentBody?.querySelector(".cart-drawer__filled, .cart
14-drawer__empty"),nextState=nextBody?.querySelector(".cart-drawer__filled, .cart-drawer__empty"),nextConfigScript=replacement?.querySelector("[data-cart-drawer-config]"),nextConfig=parseJson(nextConfigScript?.textContent);if(!currentBody||!nextBody||!currentState||!nextState||!nextConfig)throw new Error("Cart section missing");const wasOpen=this.#popup.matches(":popover-open"),scrollTop=currentBody.querySelector(".cart-drawer__scroll, .cart-drawer__empty")?.scrollTop,currentUpsell=currentBody.querySelector("[data-cart-upsell]"),nextUpsell=nextBody.querySelector("[data-cart-upsell]");if(currentUpsell&&nextUpsell){const currentProducts=currentUpsell.querySelector("[data-cart-upsell-products]"),nextProducts=nextUpsell.querySelector("[data-cart-upsell-products]"),keepCurrentProducts=nextConfig.upsell?.enabled&¤tProducts?.querySelector("[data-cart-upsell-card]");this.#holdUpsellHeight(currentUpsell),this.#upsellFallback=keepCurrentProducts?nextProducts?.cloneNode(!0):null,!keepCurrentProducts&¤tProducts&&nextProducts&¤tProducts.replaceChildren(...nextProducts.childNodes),currentUpsell.hidden=keepCurrentProducts?!1:nextUpsell.hidden,nextUpsell.replaceWith(currentUpsell)}else this.#upsellSplide?.destroy(),this.#upsellFallback=null,this.#upsellSplide=null;this.#recommendationsLoaded=!1,currentBody.querySelector("[data-cart-optimistic-items]")?.remove(),currentState.replaceWith(nextState),currentBody.querySelector(".cart-drawer__header").className=nextBody.querySelector(".cart-drawer__header").className;const error=currentBody.querySelector("[data-cart-error]");error.textContent="",error.hidden=!0,this.#popup.toggleAttribute("scroll-lock",nextPopup.hasAttribute("scroll-lock")),Object.assign(this.#config,nextConfig),this.querySelector("[data-cart-drawer-config]").textContent=nextConfigScript.textContent;const count=this.#config.cart.itemCount;if(Number.isFinite(count)&&this.#updateCartCounts(count),await this.#reconcileGifts())return this;wasOpen?this.#handleToggle():requestAnimationFrame(()=>this.open());const nextScroll=currentBody.querySelector(".cart-drawer__scroll, .cart-drawer__empty");return nextScroll&&Number.isFinite(scrollTop)&&(nextScroll.scrollTop=scrollTop,requestAnimationFrame(()=>{nextScroll.isConnected&&(nextScroll.scrollTop=scrollTop)})),this}catch{return this.#showError(this.#config.strings.error),null}finally{this.isConnected&&this.#setBusy(!1)}}async#reconcileGifts(){if(this.#reconcilingGifts)return!1;const eligibleGiftIds=new Set([...this.querySelectorAll("[data-cart-gift-eligible]")].map(marker=>marker.dataset.cartGiftEligible)),updates=Object.fromEntries([...this.querySelectorAll("[data-cart-line][data-cart-gift-id]")].filter(line=>!eligibleGiftIds.has(line.dataset.cartGiftId)).map(line=>[line.dataset.lineKey,0]));if(!Object.keys(updates).length)return!1;this.#reconcilingGifts=!0,this.#setBusy(!0);try{const cart=await this.#cartRequest(this.#config.routes.update,{updates});return await this.#refresh(cart.sections?.[this.#config.sectionId]),!0}catch{return this.#showError(this.#config.strings.error),!1}finally{this.#reconcilingGifts=!1,this.isConnected&&this.#setBusy(!1)}}#setBusy(busy){this.setAttribute("aria-busy",String(busy));const live=this.querySelector("[data-cart-live]");live&&(live.textContent=busy?this.dataset.loadingMessage:"")}#showError(message){this.#setBusy(!1);const error=this.querySelector("[data-cart-error]");error&&(error.textContent=message||this.dataset.errorMessage,error.hidden=!1)}#showDiscountMessage(message,isError,details=null){const messageElement=(details||this).querySelector("[data-cart-discount-message]");messageElement&&(messageElement.textContent=message,messageElement.hidden=!message,messageElement.classList.toggle("is-error",isError))}#updateCartCounts(count){document.querySelectorAll("[data-cart-count]").forEach(badge=>{badge.textContent=count,badge.hidden=count<1})}#closeHeaderOverlays(){const header=document.querySelector("lyle-site-header");header?.dispatchEvent(new CustomEvent("header-search:open")),header?.dispatchEvent(new CustomEvent("site-header:menu-open"))}async#initUpsell(){const carousel=this.querySelector("[data-cart-upsell]"),slides=carousel?.querySelectorAll(".splide__slide")||[];if(!carousel||!slides.length){carousel&&(carousel.hidden=!0),this.#upsellSplide?.destroy(),this.#upsellSplide=null;return}
14carousel.hidden=!1,this.#hydrateUpsellSwatches();const{default:Splide}=await import("@splidejs/splide");if(!carousel.isConnected)return;if(this.#upsellSplide){const index=this.#upsellSplide.index;this.#upsellSplide.options={drag:slides.length>1},this.#upsellSplide.refresh(),this.#upsellSplide.go(Math.min(index,slides.length-1));return}const speed=Number(this.#config.upsell?.carouselSpeed),reducedMotion=window.matchMedia("(prefers-reduced-motion: reduce)").matches,interval=Number.isFinite(speed)?speed*1e3:0,autoplay=!!(interval&&!reducedMotion);this.#upsellSplide=new Splide(carousel,{arrows:!0,autoplay,drag:!0,gap:20,interval,mediaQuery:"min",padding:{left:16,right:16},pagination:!1,fixedWidth:"70%",perMove:1,flickPower:300,dragMinThreshold:{mouse:0,touch:5},breakpoints:{768:{fixedWidth:null,padding:{left:24,right:24},perPage:2}}}),this.#upsellSplide.mount()}#holdUpsellHeight(carousel){const height=carousel?.offsetHeight;height&&(carousel.style.minHeight=`${height}px`,requestAnimationFrame(()=>{requestAnimationFrame(()=>carousel.style.removeProperty("min-height"))}))}async#loadRecommendations(){const recommendation=this.#config.upsell,container=this.querySelector("[data-cart-upsell-products]");if(!this.#recommendationsLoaded){if(!recommendation?.enabled||!container||!this.#config.algolia.appId||!this.#config.algolia.apiKey||!this.#config.algolia.indexName){this.#restoreUpsellFallback();return}this.#recommendationsLoaded=!0;try{const recommendationProductId=this.#config.cart.lastProductId;if(!recommendationProductId&&container.querySelector("[data-cart-upsell-card]")&&!this.#upsellFallback){await this.#initUpsell();return}const recommendationModel=recommendationProductId?recommendation.type:"trending-items",queryFilters=String(recommendation.queryFilters||"").trim(),fallbackFilters=String(recommendation.fallbackFilters||"").trim(),rules=(recommendation.rules||[]).map(rule=>String(rule||"").trim()).filter(Boolean),request={indexName:this.#config.algolia.indexName,model:recommendationModel,threshold:Number(recommendation.threshold)||0,maxRecommendations:20,queryParameters:{filters:queryFilters?`${queryFilters} AND ${this.#config.algolia.defaultFilters}`:this.#config.algolia.defaultFilters}};recommendationProductId&&recommendationModel!=="trending-items"&&(request.objectID=String(recommendationProductId)),rules.length&&(request.queryParameters.ruleContexts=rules),fallbackFilters&&(request.fallbackParameters={filters:fallbackFilters});const response=await fetch(`https://${this.#config.algolia.appId}.algolia.net/1/indexes/*/recommendations`,{method:"POST",signal:this.#abortController.signal,headers:{"Content-Type":"application/json","x-algolia-api-key":this.#config.algolia.apiKey,"x-algolia-application-id":this.#config.algolia.appId},body:JSON.stringify({requests:[request]})});if(!response.ok){this.#restoreUpsellFallback();return}const data=await response.json(),cartProductIds=new Set(this.#config.cart.productIds.map(String)),cartProductHandles=new Set(this.#config.cart.productHandles||[]),products=(data.results?.[0]?.hits||[]).filter(hit=>{const id=String(hit.productId||hit.id||hit.objectID);return!cartProductIds.has(id)&&!cartProductHandles.has(hit.handle)}).slice(0,recommendation.max).map(hit=>formatAlgoliaProductHit(hit,this.#config));if(!products.length){this.#restoreUpsellFallback();return}const content=document.createElement("template");content.innerHTML=products.map(product=>this.#renderUpsellProduct(product)).join(""),this.#upsellFallback=null,this.#replaceUpsellProducts(content.content)}catch(error){error.name!=="AbortError"&&(this.#recommendationsLoaded=!1,this.#restoreUpsellFallback())}}}#restoreUpsellFallback(){if(!this.#upsellFallback)return;const fallback=this.#upsellFallback;this.#upsellFallback=null,this.#replaceUpsellProducts(fallback)}#replaceUpsellProducts(products){const container=this.querySelector("[data-cart-upsell-products]");if(!container)return;const scroll=container.closest(".cart-drawer__scroll, .cart-drawer__empty"),scrollTop=scroll?.scrollTop;this.#holdUpsellHeight(container.closest("[data-cart-upsell]")),container.replaceChildren(...products.childNodes),this.#initUpsell(),scroll&&Number.isFinite(scrollTop)&&(scroll.scrollTop=scrollTop,requestAnimationFrame(()=>{scroll.isConnected&&(scroll.scrollTop=scrollTop)}))}#renderUpsellProduct(product){const image=this.#upsellImage(product),swatch=metafieldValue(product,"swatch_code"),familySize=Number(metafieldValue(product,"colour_family_size"))||0,hiddenSwatches=Math.max(0,familySize-1),priceAmount=Number(product.price?.min??product.price?.amount??0),compareAtPriceAmount=Number(product.compareAtPrice?.min??product.compareAtPrice?.amount??0),onSale=compareAtPriceAmount>priceAmount,priceOptions={currencySymbol:this.#config.market.currencySymbol,formatter:this.#moneyFormatter},price=formatMoney(priceAmount,priceOptions),compareAtPrice=onSale?formatMoney(compareAtPriceAmount,priceOptions):"",url=escapeHtml(product.url),title=escapeHtml(product.title),bag=window.icons?.["bag-add"]||window.icons?.bag||"",colourLabel=escapeHtml(this.#config.strings.colorCount.replace("__count__",Math.max(1,familySize))),productImageUrl=image?imageUrl(image,258):"",colours=`<div class="cart-drawer-upsell-card__colours" data-cart-upsell-swatches> 15 ${swatch?`<button class="cart-drawer-upsell-card__swatch is-active${isWhiteSwatch(swatch)?" cart-drawer-upsell-card__swatch--white":""}" type="button" data-cart-upsell-swatch data-image-url="${escapeHtml(productImageUrl)}" data-image-alt="${escapeHtml(image?.alt||product.title)}" aria-label="${title}" aria-current="true"><span class="cart-drawer-upsell-card__swatch-inner" style="--swatch-color: ${escapeHtml(swatch)}"></span></button>`:""} 16 ${hiddenSwatches>0?`<a class="cart-drawer-upsell-card__swatch-count text-eyebrow-2xs" href="${url}" aria-label="${colourLabel}">+${hiddenSwatches}</a>`:""} 17 </div>`;return` 18 <li class="cart-drawer-upsell-card splide__slide" data-cart-upsell-card data-product-card data-product-id="${escapeHtml(product.id)}" data-product-handle="${escapeHtml(product.handle)}" data-product-url="${url}"> 19 <a class="cart-drawer-upsell-card__image-link" href="${url}" tabindex="-1" aria-hidden="true"> 20 ${image?`<img class="cart-drawer-upsell-card__image" src="${escapeHtml(productImageUrl)}" alt="${title}" width="86" height="107" loading="lazy">`:""} 21 </a> 22 <div class="cart-drawer-upsell-card__content"> 23 <div class="cart-drawer-upsell-card__details text-body-xs"> 24 <a class="cart-drawer-upsell-card__title" href="${url}">${title}</a>
25 <span class="cart-drawer-upsell-card__price product-prices">${onSale?`<span class="product-prices__compare-at-price">${escapeHtml(compareAtPrice)}</span><span class="product-prices__price product-prices__price--on-sale text-body-xs-bold">${escapeHtml(price)}</span>`:`<span class="product-prices__price">${escapeHtml(price)}</span>`}</span> 26 </div> 27 28 <div class="cart-drawer-upsell-card__actions"> 29 ${colours} 30 <button class="cart-drawer-upsell-card__add" type="button" data-quick-view aria-label="${escapeHtml(this.#config.strings.quickAdd)}: ${title}"> 31 <span aria-hidden="true">${bag}</span> 32 </button> 33 </div> 34 </div> 35 <script type="application/json" data-product-card-json>${JSON.stringify(product).replace(/</g,"\\u003c")}<\/script> 36 </li> 37 `}async#hydrateUpsellSwatches(){const entries=[...this.querySelectorAll("[data-cart-upsell-card]")].filter(card=>!card.hasAttribute("data-upsell-swatches-loaded")&&!card.hasAttribute("data-upsell-swatches-loading")).map(card=>{const product=this.#cardProduct(card);return{card,product,tag:this.#fetcher.familyTag(product)}}).filter(({product,tag})=>product&&tag);if(entries.length){entries.forEach(({card})=>card.setAttribute("data-upsell-swatches-loading",""));try{const productsByTag=await this.#fetcher.fetchRelatedProductsBatch(entries.map(({tag})=>tag));entries.forEach(({card,product,tag})=>{const swatches=this.#fetcher.filterColourProducts(product,productsByTag.get(tag)||[]),visible=this.#visibleUpsellSwatches(swatches,product),container=card.querySelector("[data-cart-upsell-swatches]");if(container&&visible.length){const hiddenCount=swatches.length-visible.length,colourLabel=escapeHtml(this.#config.strings.colorCount.replace("__count__",swatches.length));container.innerHTML=`${visible.map(swatch=>this.#upsellSwatchMarkup(swatch,product)).join("")}${hiddenCount>0?`<a class="cart-drawer-upsell-card__swatch-count text-eyebrow-2xs" href="${escapeHtml(product.url)}" aria-label="${colourLabel}">+${hiddenCount}</a>`:""}`}card.removeAttribute("data-upsell-swatches-loading"),card.setAttribute("data-upsell-swatches-loaded","")})}catch{entries.forEach(({card})=>card.removeAttribute("data-upsell-swatches-loading"))}}}#visibleUpsellSwatches(swatches,product){const visible=swatches.slice(0,3),active=swatches.find(swatch=>isSameProduct(swatch,product));return!active||visible.some(swatch=>isSameProduct(swatch,product))?visible:[active,...swatches.filter(swatch=>!isSameProduct(swatch,active))].slice(0,3)}#upsellSwatchMarkup(swatch,product){const active=isSameProduct(swatch,product),colour=metafieldValue(swatch,"swatch_code")||"#ffffff",image=this.#upsellImage(swatch),imageSrc=image?imageUrl(image,258):"";return`<button class="cart-drawer-upsell-card__swatch${active?" is-active":""}${isWhiteSwatch(colour)?" cart-drawer-upsell-card__swatch--white":""}" type="button" data-cart-upsell-swatch data-product='${escapeHtml(JSON.stringify(swatch))}' data-image-url="${escapeHtml(imageSrc)}" data-image-alt="${escapeHtml(image?.alt||swatch.title)}" aria-label="${escapeHtml(swatch.title)}"${active?' aria-current="true"':""}><span class="cart-drawer-upsell-card__swatch-inner" style="--swatch-color: ${escapeHtml(colour)}"></span></button>`}#selectUpsellSwatch(swatch){const card=swatch.closest("[data-cart-upsell-card]"),image=card?.querySelector(".cart-drawer-upsell-card__image");!image||!swatch.dataset.imageUrl||(image.removeAttribute("srcset"),image.removeAttribute("sizes"),image.src=swatch.dataset.imageUrl,image.alt=swatch.dataset.imageAlt||"",card.querySelectorAll("[data-cart-upsell-swatch]").forEach(button=>{const active=button===swatch;button.classList.toggle("is-active",active),button.toggleAttribute("aria-current",active)}))}#upsellImage(product){const images=product.images||[],flatLay=images.find(image=>image.alt?.toLowerCase().includes("flat-lay"));if(flatLay)return flatLay;const altLanding=images.find(image=>image.alt?.includes("alt_landing_image"));if(this.#config.productCard.useAltImage&&altLanding)return altLanding;const standard=images.filter(image=>!image.alt?.includes("alt_landing_image"));return this.#config.productCard.imageOrder==="flat"?standard.at(-1)||images[0]:standard[0]||images[0]}#cardProduct(card){return parseJson(card?.querySelector("[data-cart-upsell-swatch].is-active[data-product]")?.dataset.product||card?.querySelector("[data-product-card-json]")?.textContent)}#formatMoney(value){return formatMoney(value,{currencySymbol:this.#config.market.currencySymbol,formatter:this.#moneyFormatter})}#initLoyaltyLion(){if(!this.#config.customer||!this.#config.loyaltyRewards.length)return;const onReady=()=>{this.isConnected&&(this.#registerLoyaltyHook(),this.#syncLoyaltyLion())};window._llReady||window.loyaltylion?.customer?onReady():typeof window.loyaltylion?.on=="function"?window.loyaltylion.on("sdkReady",onReady):(window._llReadyCallbacks=window._llReadyCallbacks||[],window._llReadyCallbacks.push(onReady));const rewardsList=document.querySelector("#ll-rewards-list");rewardsList&&typeof MutationObserver<"u"&&(this.#loyaltyObserver=new MutationObserver(()=>this.#syncLoyaltyLion()),this.#loyaltyObserver.observe(rewardsList,{childList:!0,subtree:!0}))}#registerLoyaltyHook(){window._llCartClaimHandler=this.#claimHandler,!(window._llCartClaimHookRegistered||typeof window.loyaltylion?.registerHook!="function")&&(window._llCartClaimHookRegistered=!0,window.loyaltylion.registerHook("customers.rewards.claimed",({claimedReward})=>(window._llCartClaimHandler?.(claimedReward),{action:"hide_claim_modal"})))}#syncLoyaltyLion(){const loyalty=this.querySelector("[data-cart-loyalty]"),earned=this.querySelector("[data-cart-points-earned]");if(!loyalty||!earned)return;const tierId=window._llCustomerTierId,tierRate=Number(window._llTierPointsMap?.[String(tierId)])||3,pointsEarned=Math.round(this.#config.cart.totalPrice/100*tierRate);earned.textContent=`${pointsEarned} ${this.#config.strings.points}`;const stored=this.#storedLoyaltyReward();if(stored?.code&&this.#config.cart.discountCodes.some(code=>code.toLowerCase()===stored.code.toLowerCase())){this.#renderLoyaltyMessage(this.#config.strings.pointsRedeemed,stored.reward,!1);return}const balance=Number(window.loyaltylion?.customer?.pointsApproved)||0,rewards=[...this.#config.loyaltyRewards].sort((first,second)=>second.points-first.points);if(this.#reward=rewards.find(reward=>{if(!reward.rewardId||balance<reward.points)return!1;const button=this.#loyaltyButton(reward.rewardId);return button&&!button.classList.contains("lion-action-button--disabled")}),!this.#reward){loyalty.hidden=!0;return}this.#renderLoyaltyMessage(this.#config.strings.pointsRedeem,this.#reward,!0)}#renderLoyaltyMessage(template,reward,showApply){const loyalty=this.querySelector("[data-cart-loyalty]"),message=loyalty?.querySelector("[data-cart-loyalty-message]"),apply=loyalty?.querySelector("[data-cart-loyalty-apply]");
37if(!loyalty||!message||!apply||!reward)return;const amount=new Intl.NumberFormat(this.#config.currency.language||document.documentElement.lang,{style:"currency",currency:this.#config.currency.code}).format(reward.amount*(Number(window.Shopify?.currency?.rate)||1)),values={"{{ points }}":String(reward.points),"{{ amount }}":amount};message.replaceChildren(...template.split(/(\{\{ points \}\}|\{\{ amount \}\})/).map(part=>{if(!values[part])return document.createTextNode(part);const strong=document.createElement("strong");return strong.textContent=values[part],strong})),apply.hidden=!showApply,loyalty.hidden=!1;const color=window._llTierColorMap?.[String(window._llCustomerTierId)];color&&(loyalty.style.backgroundColor=color)}#loyaltyButton(rewardId){return document.querySelector(`#ll-rewards-list [data-reward-id="${CSS.escape(String(rewardId))}"] button`)}#storedLoyaltyReward(){try{return JSON.parse(localStorage.getItem("ll_redeemed")||"null")}catch{return localStorage.removeItem("ll_redeemed"),null}}#claimLoyaltyReward(){const button=this.#loyaltyButton(this.#reward?.rewardId);if(!button||button.classList.contains("lion-action-button--disabled")){this.#showError(this.#config.strings.loyaltyError);return}this.#setBusy(!0),window.clearTimeout(this.#loyaltyTimer),this.#loyaltyTimer=window.setTimeout(()=>{this.isConnected&&this.#showError(this.#config.strings.loyaltyError)},LOYALTY_CLAIM_TIMEOUT),button.click()}async#handleRewardClaimed(claimedReward){window.clearTimeout(this.#loyaltyTimer);const code=claimedReward?.redeemable?.code;if(!code||!this.#reward){this.#showError(this.#config.strings.loyaltyError);return}await this.#applyDiscount(null,{code,reward:this.#reward})}}customElements.get("lyle-cart-drawer")||customElements.define("lyle-cart-drawer",LyleCartDrawer); 38//# sourceMappingURL=/cdn/shop/t/458/assets/lyle-cart-drawer.js.map?v=122591635777252006871788364388
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.