1class SmartWishlistSDK{static readyPromise=null;static resolveReady=null;static ready=!1;static{this.readyPromise=new Promise(resolve=>{this.resolveReady=resolve}),typeof window.SmartWishlistMain=="function"?this.markAsReady():(window.addEventListener("smartwishlist:ready",()=>this.markAsReady(),{once:!0}),this.observeScriptLoad())}static markAsReady(){this.ready||(this.ready=!0,this.resolveReady())}static observeScriptLoad(){let smartWishlistMain=window.SmartWishlistMain;Object.defineProperty(window,"SmartWishlistMain",{get:()=>smartWishlistMain,set:value=>{smartWishlistMain=value,typeof value=="function"&&this.markAsReady()},configurable:!0})}static whenReady(){return this.readyPromise}static get isReady(){return this.ready}}class PoWishlistUtils{static mergePromise=null;static get metaStorageKey(){return`${WISHLIST_CONSTANTS.localStorageKey}_meta`}static get pendingMergeKey(){return`${WISHLIST_CONSTANTS.localStorageKey}_pending`}static get customerId(){return ShopifyAnalytics?.meta?.page?.customerId?String(ShopifyAnalytics.meta.page.customerId):null}static get sessionMeta(){try{return JSON.parse(localStorage.getItem(this.metaStorageKey))||null}catch{return null}}static set sessionMeta(meta){try{meta?localStorage.setItem(this.metaStorageKey,JSON.stringify(meta)):localStorage.removeItem(this.metaStorageKey)}catch{}}static get pendingMerge(){try{return JSON.parse(localStorage.getItem(this.pendingMergeKey))||null}catch{return null}}static set pendingMerge(data){try{data?localStorage.setItem(this.pendingMergeKey,JSON.stringify(data)):localStorage.removeItem(this.pendingMergeKey)}catch{}}static clearLocalWishlist(){try{localStorage.removeItem(WISHLIST_CONSTANTS.localStorageKey)}catch{}}static clearWishlistCookie(){try{document.cookie="wishlist_id=; path=/; expires=Thu, 01 Jan 1970 00:00:00 GMT"}catch{}}static initSessionSync(){try{this.handleSessionTransition()}catch(e){console.error("[Wishlist] Session sync failed:",e)}}static handleSessionTransition(){const customerId=this.customerId,meta=this.sessionMeta,pending=this.pendingMerge,cached=this.cachedWishlist||[];if(!customerId){(meta?.ownerType==="customer"||pending)&&(this.clearLocalWishlist(),this.pendingMerge=null,this.clearWishlistCookie(),publish(PUB_SUB_EVENTS.updateWishlist,{wishlist:[]})),(!meta||meta.ownerType!=="guest")&&(this.sessionMeta={ownerType:"guest",customerId:null,lastCustomerId:meta?.customerId||meta?.lastCustomerId||null});return}meta?.lastCustomerId&&meta.lastCustomerId!==customerId&&(this.clearLocalWishlist(),this.pendingMerge=null),meta?.ownerType==="customer"&&meta.customerId&&meta.customerId!==customerId&&this.clearLocalWishlist();let itemsToMerge=[];pending?.customerId===customerId?itemsToMerge=pending.items||[]:cached.length>0&&meta?.ownerType!=="customer"?(itemsToMerge=cached,this.pendingMerge={customerId,items:itemsToMerge,createdAt:new Date().toISOString()}):pending&&pending.customerId!==customerId&&(this.pendingMerge=null),this.sessionMeta={ownerType:"customer",customerId,lastCustomerId:customerId},itemsToMerge.length&&this.startMerge(itemsToMerge)}static normalizeWishlistItem(item){return{productId:item?.product_id||item?.productId||null,variantId:item?.variant_id||item?.variantId||null,productHandle:item?.handle||item?.productHandle||null}}static startMerge(items){return this.mergePromise?this.mergePromise:(this.mergePromise=(async()=>{try{await SmartWishlistSDK.whenReady();const existing=await this.fetchWishlist(),existingIds=new Set(existing.map(item=>String(item.variant_id)));for(const rawItem of items){const wlItem=this.normalizeWishlistItem(rawItem);!wlItem.productId||!wlItem.variantId||existingIds.has(String(wlItem.variantId))||await this.callWishlistAPI(WISHLIST_CONSTANTS.eventKeyAdd,wlItem)}this.pendingMerge=null;const updated=await this.fetchWishlist();publish(PUB_SUB_EVENTS.updateWishlist,{wishlist:updated}),this.clearWishlistCookie()}catch(error){console.error("[Wishlist] Merge failed:",error)}finally{this.mergePromise=null}})(),this.mergePromise)}static get cachedWishlist(){const wl=localStorage.getItem(WISHLIST_CONSTANTS.localStorageKey)||null;return wl&&JSON.parse(wl)}static set cachedWishlist(wl){try{if(wl==null){localStorage.removeItem(WISHLIST_CONSTANTS.localStorageKey);return}localStorage.setItem(WISHLIST_CONSTANTS.localStorageKey,JSON.stringify(wl))}catch{}}static get wishlistUrl(){const customerId=ShopifyAnalytics.meta.page.customerId,baseUrl=`${Shopify.routes.root}a/wishlist?type=api&version=1`;return customerId?`${baseUrl}&customerid=${customerId}`:`${baseUrl}&wishlistid=${this.wishlistId}`}static get wishlistId(){return decodeURIComponent(document.cookie).split(";").find(c=>c.trim().startsWith("wishlist_id="))?.trim().substring(12)||null}static async retrieveWishlist(){this.initSessionSync();const cached=this.cachedWishlist;return cached??this.fetchWishlist()}static async fetchWishlist(){if(!this.wishlistId&&!ShopifyAnalytics.meta.page.customerId)return console.warn("[Wishlist] No wishlist ID or customer ID \u2014 skipping fetch."),[];try{const response=await fetch(this.wishlistUrl);if(!response.ok)throw new Error(`HTTP ${response.status}`);const{items:wlItems=[]}=await response.json();return localStorage.setItem(WISHLIST_CONSTANTS.localStorageKey,JSON.stringify(wlItems)),wlItems}catch(error){return console.error("[Wishlist] Error fetching:",error),this.cachedWishlist||[]}}static async isItemInWishlist(variantId){return(await this.retrieveWishlist()).some(item=>item.variant_id===variantId)}static async updateWishlist(eventKey,item){this.sessionMeta={ownerType:this.customerId?"customer":"guest",customerId:this.customerId};const pending=this.pendingMerge;if(pending?.customerId===this.customerId&&Array.isArray(pending.items)){const variantId=String(item?.variantId||""),filtered=pending.items.filter(p=>String(p?.variant_id||p?.variantId||"")!==variantId);filtered.length!==pending.items.length&&(this.pendingMerge=filtered.length?{...pending,items:filtered}:null)}const currentWl=this.applyOptimisticUpdate(eventKey,item);return publish(PUB_SUB_EVENTS.updateWishlist,{wishlist:currentWl}
1),this.callWishlistAPI(eventKey,item).catch(error=>{console.error("[Wishlist] API call failed:",error)}),currentWl}static applyOptimisticUpdate(eventKey,item){let currentWl=this.cachedWishlist||[];return eventKey===WISHLIST_CONSTANTS.eventKeyAdd?currentWl.some(wlItem=>wlItem.variant_id===item.variantId)||(currentWl=[...currentWl,{product_id:item.productId,variant_id:item.variantId,handle:item.productHandle}]):eventKey===WISHLIST_CONSTANTS.eventKeyRemove&&(currentWl=currentWl.filter(wlItem=>wlItem.variant_id!==item.variantId)),localStorage.setItem(WISHLIST_CONSTANTS.localStorageKey,JSON.stringify(currentWl)),currentWl}static async callWishlistAPI(eventKey,item){await SmartWishlistSDK.whenReady();const fnName={[WISHLIST_CONSTANTS.eventKeyAdd]:"AddToSmartWishlist",[WISHLIST_CONSTANTS.eventKeyRemove]:"RemoveFromSmartWishlist"}[eventKey];fnName&&typeof window[fnName]=="function"&&await window[fnName](item.productId,item.variantId)}}class PoWishlist extends HTMLElement{constructor(){super(),this.customerId=ShopifyAnalytics.meta.page.customerId||null,this.wishlistData=[],this.unsubscribe=null}get loader(){return this.querySelector("[data-wishlist-loader]")}get itemCountDisplay(){return this.querySelector("[data-wishlist-item-count]")}async connectedCallback(){await this.loadWishlist(),this.unsubscribe=subscribe(PUB_SUB_EVENTS.updateWishlist,()=>{this.loadWishlist()})}disconnectedCallback(){this.unsubscribe?.()}async loadWishlist(){this.wishlistData=await PoWishlistUtils.retrieveWishlist(),await this.renderWishlistItems()}hideLoader(){this.loader&&(this.loader.style.display="none")}async renderWishlistItems(){const emptyWrapper=this.querySelector("#wishlist-empty-wrapper"),productsWrapper=this.querySelector("#wishlist-products-wrapper"),container=this.querySelector("#wishlist-products");if(this.updateItemCount(),this.wishlistData.length===0){emptyWrapper?.classList.remove("hidden"),productsWrapper?.classList.add("hidden"),this.hideLoader();return}try{const fragment=await this.fetchWishlistItemsHTML();container&&(container.innerHTML="",container.appendChild(fragment),this.handleLoginCard(container)),emptyWrapper?.classList.add("hidden"),productsWrapper?.classList.remove("hidden")}catch(error){console.error("[Wishlist] Error loading items:",error)}this.hideLoader()}updateItemCount(){if(!this.itemCountDisplay)return;const count=this.wishlistData.length;this.itemCountDisplay.textContent=count>0?`(${count})`:"",this.itemCountDisplay.toggleAttribute("data-visible",count>0)}async fetchWishlistItemsHTML(){const fetchPromises=this.wishlistData.map(item=>fetch(`${Shopify.routes.root}products/${item.handle}/?sections=po-wishlist-item&variant=${item.variant_id}`)),responses=await Promise.all(fetchPromises),jsonResponses=await Promise.all(responses.map(res=>res.json())),fragment=document.createDocumentFragment();return jsonResponses.forEach(response=>{const wishlistItem=new DOMParser().parseFromString(response["po-wishlist-item"],"text/html").querySelector("[data-po-wishlist-item]");wishlistItem&&fragment.appendChild(wishlistItem)}),fragment}handleLoginCard(container){if(!container||this.customerId)return;container.querySelector(".wishlist-login-card")?.remove();const loginCard=this.createLoginCard();if(!loginCard)return;const productItems=container.querySelectorAll("[data-po-wishlist-item]"),insertAfterIndex=Math.min(productItems.length,2)-1;insertAfterIndex>=0?productItems[insertAfterIndex].insertAdjacentElement("afterend",loginCard):container.appendChild(loginCard),this.initLoginCardModal(loginCard)}createLoginCard(){const template=document.getElementById("wishlist-login-template");if(!template)return null;const card=document.createElement("div");return card.className="wishlist-login-card",card.innerHTML=template.innerHTML,card}initLoginCardModal(cardEl){const loginModal=document.querySelector("#login-overlay-modal");!loginModal||typeof loginModal.showModal!="function"||cardEl.querySelectorAll("[data-login-trigger]").forEach(trigger=>{trigger.addEventListener("click",e=>{e.preventDefault(),loginModal.dataset.position==="right"&&loginModal.classList.add("tw-animate-slide-left"),loginModal.showModal()})})}}customElements.get("po-wishlist")||customElements.define("po-wishlist",PoWishlist);class PoWishlistToggleButton extends HTMLElement{constructor(){super(),this.wishlistItem={productId:this.dataset.productId,variantId:this.dataset.variantId,productHandle:this.dataset.handle,variantSku:this.dataset.sku||this.dataset.variantSku||null},this.isInWishlist=!1,this.unsubscribers=[]}async connectedCallback(){await this.init()}
1disconnectedCallback(){this.unsubscribers.forEach(unsub=>unsub?.())}async init(){await this.syncWishlist(),await this.enableWhenSDKReady(),this.setupSubscriptions(),this.setupEventListeners()}async enableWhenSDKReady(){await SmartWishlistSDK.whenReady(),this.removeAttribute("disabled")}setupSubscriptions(){this.unsubscribers.push(subscribe(PUB_SUB_EVENTS.updateWishlist,()=>this.checkWishlistItemPresence()),subscribe(PUB_SUB_EVENTS.variantChange,payload=>this.handleVariantChange(payload)))}setupEventListeners(){this.addEventListener("click",this.handleClick.bind(this)),this.addEventListener("keydown",this.handleKeydown.bind(this))}handleVariantChange(payload){const{productId,variant}=payload.data;this.wishlistItem.productId===productId&&this.wishlistItem.variantId!==String(variant.id)&&(this.wishlistItem.variantId=String(variant.id),this.wishlistItem.variantSku=variant?.sku||null,this.checkWishlistItemPresence())}syncAriaPressed(){this.hasAttribute("aria-pressed")&&this.setAttribute("aria-pressed",this.hasAttribute("active")?"true":"false")}handleClick(evt){evt.preventDefault(),this.toggleAttribute("active"),this.syncAriaPressed();const eventKey=this.isInWishlist?WISHLIST_CONSTANTS.eventKeyRemove:WISHLIST_CONSTANTS.eventKeyAdd;this.sendTealiumTracking(eventKey),PoWishlistUtils.updateWishlist(eventKey,this.wishlistItem)}getDirectTealiumProductKeyCandidate(){return this.wishlistItem.variantSku||this.wishlistItem.variantId||this.wishlistItem.productId}getTealiumProductKey(){const tealiumProductEntry=this.getTealiumProductEntry();return tealiumProductEntry?tealiumProductEntry.key:this.getDirectTealiumProductKeyCandidate()}getDatasetTealiumProductData(){if(!this.dataset.trackingProduct)return null;try{return JSON.parse(this.dataset.trackingProduct)}catch{return null}}normalizeTealiumCategory(value){const normalizedValue=String(value||"").trim().replace(/[_-]+/g," ").replace(/\s+/g," ").toLowerCase(),categoryMap={accessories:"ACCESSORIES",accessory:"ACCESSORIES",optics:"OPTICS",optical:"OPTICS",eyeglasses:"OPTICS",eyeglass:"OPTICS",sun:"SUN",sunglasses:"SUN",sunglass:"SUN",afa:"AFA",eyewear:"EYEWEAR",electronics:"Electronics",electronic:"Electronics",giftcard:"GIFTCARD","gift card":"GIFTCARD","gift cards":"GIFTCARD","contact lens":"CONTACT LENSES","contact lenses":"CONTACT LENSES",vas:"VAS",service:"VAS",services:"VAS","value added service":"VAS","value added services":"VAS"};return categoryMap[normalizedValue]?categoryMap[normalizedValue]:normalizedValue.includes("contact lens")?"CONTACT LENSES":normalizedValue.includes("gift card")?"GIFTCARD":normalizedValue.includes("electronic")?"Electronics":normalizedValue.includes("accessor")?"ACCESSORIES":normalizedValue.includes("optic")||normalizedValue.includes("eyeglass")?"OPTICS":normalizedValue.includes("sun")?"SUN":normalizedValue.includes("afa")?"AFA":normalizedValue.includes("vas")?"VAS":"EYEWEAR"}getTealiumProductEntry(){if(typeof window.poResolveTealiumProductEntry=="function"){const resolvedEntry=window.poResolveTealiumProductEntry({productHandle:this.wishlistItem.productHandle,variantSku:this.wishlistItem.variantSku,productId:this.wishlistItem.productId,variantId:this.wishlistItem.variantId,productData:this.getDatasetTealiumProductData()});if(resolvedEntry?.key)return resolvedEntry}const tealiumProducts=window.tealium?.products;if(!tealiumProducts||typeof tealiumProducts!="object")return null;const currentProductId=window.tealium?.currentProductId||"",currentProduct=currentProductId?tealiumProducts[currentProductId]:null,directProductKey=this.getDirectTealiumProductKeyCandidate(),firstProductEntry=Object.entries(tealiumProducts).find(([,product])=>product&&typeof product=="object")||null;if(directProductKey&&tealiumProducts[directProductKey])return{key:directProductKey,data:tealiumProducts[directProductKey]};if(currentProductId&¤tProduct)return{key:currentProductId,data:currentProduct};const matchedEntry=Object.entries(tealiumProducts).find(([,product])=>{const handle=String(product?.Handle||product?.handle||"").trim().toLowerCase();return handle&&handle===String(this.wishlistItem.productHandle||"").trim().toLowerCase()});return matchedEntry?{key:matchedEntry[0],data:matchedEntry[1]}:firstProductEntry?{key:firstProductEntry[0],data:firstProductEntry[1]}:null}getTealiumPriceFields(eventKey=WISHLIST_CONSTANTS.eventKeyAdd){const productPrice
1=window.opTealiumPrices?.find(item=>item.productHandle===this.wishlistItem.productHandle),tealiumProduct=this.getTealiumProductEntry()?.data||this.getDatasetTealiumProductData(),priceFields=tealiumProduct&&typeof tealiumProduct=="object"?{...tealiumProduct}:{},formatCentsPrice=value=>{const numericValue=Number(value);return Number.isFinite(numericValue)?(numericValue/100).toFixed(2):""};return productPrice?.price!==void 0?(priceFields.Price=formatCentsPrice(productPrice.price),priceFields.PriceNet=formatCentsPrice(productPrice.price)):tealiumProduct?.Price&&(priceFields.Price=String(tealiumProduct.Price),tealiumProduct?.PriceNet&&(priceFields.PriceNet=String(tealiumProduct.PriceNet))),productPrice?.priceFull!==void 0?(priceFields.PriceFull=formatCentsPrice(productPrice.priceFull),priceFields.PriceFullNet=formatCentsPrice(productPrice.priceFull)):tealiumProduct?.PriceFull&&(priceFields.PriceFull=String(tealiumProduct.PriceFull),tealiumProduct?.PriceFullNet&&(priceFields.PriceFullNet=String(tealiumProduct.PriceFullNet))),priceFields.LensType||(priceFields.LensType="PLANO"),priceFields.Category&&(priceFields.Category=this.normalizeTealiumCategory(priceFields.Category)),eventKey===WISHLIST_CONSTANTS.eventKeyAdd&&(delete priceFields.PriceNet,delete priceFields.PriceFullNet),priceFields}sendTealiumTracking(eventKey=WISHLIST_CONSTANTS.eventKeyAdd){const productKey=this.getTealiumProductKey();if(!productKey)return;const tealiumEvent={id:"Event",[eventKey===WISHLIST_CONSTANTS.eventKeyRemove?"Events_ProdFavRem":"Events_ProdFavAdd"]:"1",Products:{[productKey]:this.getTealiumPriceFields(eventKey)}};typeof window.sendTealiumEvent=="function"?window.sendTealiumEvent(tealiumEvent):typeof window.tealium_data2track<"u"&&typeof window.tealium_data2track.push=="function"&&window.tealium_data2track.push({...tealiumEvent})}handleKeydown(event){document.activeElement===this&&["Enter"," ","Spacebar"].includes(event.key)&&(event.preventDefault(),this.click())}async checkWishlistItemPresence(){this.isInWishlist=await PoWishlistUtils.isItemInWishlist(this.wishlistItem.variantId),this.toggleAttribute("active",this.isInWishlist),this.syncAriaPressed()}async syncWishlist(){const wl=await PoWishlistUtils.retrieveWishlist();this.isInWishlist=wl.some(item=>item.variant_id===this.wishlistItem.variantId),this.toggleAttribute("active",this.isInWishlist),this.syncAriaPressed()}}customElements.get("po-wishlist-toggle-button")||customElements.define("po-wishlist-toggle-button",PoWishlistToggleButton);class PoWishlistHeaderIcon extends HTMLElement{constructor(){super(),this.url=this.dataset.url||"#",this.unsubscribe=null}async connectedCallback(){await this.syncWishlist(),this.unsubscribe=subscribe(PUB_SUB_EVENTS.updateWishlist,({wishlist})=>{this.setAttribute("active",wishlist.length>0)}),this.addEventListener("click",()=>{window.location=this.url})}disconnectedCallback(){this.unsubscribe?.()}async syncWishlist(){const wl=await PoWishlistUtils.retrieveWishlist();this.setAttribute("active",wl.length>0)}}customElements.get("po-wishlist-header-icon")||customElements.define("po-wishlist-header-icon",PoWishlistHeaderIcon),window.addEventListener("pageshow",event=>{event.persisted&&(document.querySelectorAll("po-wishlist-toggle-button").forEach(btn=>btn.syncWishlist()),document.querySelectorAll("po-wishlist-header-icon").forEach(icon=>icon.syncWishlist()))}); 2//# sourceMappingURL=/cdn/shop/t/2/assets/po-wishlist.js.map?v=163793289951613231381790845654
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.