@shopify/hydrogen 2026.4.1 → 2026.4.2

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.
@@ -1,4 +1,4 @@
1
- import {createContext,forwardRef,lazy,useContext,useMemo,useEffect,useRef,useState,createElement,Fragment as Fragment$1,Suspense}from'react';import {createContext as createContext$1,useRevalidator,useFetcher,useFetchers,RouterContextProvider,createRequestHandler,useNavigation,useLocation,useNavigate,Link,useMatches}from'react-router';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useLoadScript,useShopifyCookies,getTrackingValues,createStorefrontClient,SHOPIFY_STOREFRONT_ID_HEADER,SHOPIFY_STOREFRONT_Y_HEADER,SHOPIFY_STOREFRONT_S_HEADER,SHOPIFY_UNIQUE_TOKEN_HEADER,SHOPIFY_VISIT_TOKEN_HEADER,flattenConnection,RichText,ShopPayButton,parseGid,sendShopifyAnalytics,AnalyticsEventName,AnalyticsPageType,getClientBrowserParameters}from'@shopify/hydrogen-react';export{AnalyticsEventName,AnalyticsPageType,ExternalVideo,IMAGE_FRAGMENT,Image,MediaFile,ModelViewer,Money,ShopifySalesChannel,Video,customerAccountApiCustomScalars,decodeEncodedVariant,flattenConnection,getAdjacentAndFirstAvailableVariants,getClientBrowserParameters,getProductOptions,getShopifyCookies,getTrackingValues,isOptionValueCombinationInEncodedVariant,mapSelectedProductOptionToObject,parseGid,parseMetafield,sendShopifyAnalytics,storefrontApiCustomScalars,useLoadScript,useMoney,useSelectedOptionInUrlParam,useShopifyCookies}from'@shopify/hydrogen-react';import {useLoadScript as useLoadScript$1}from'@shopify/hydrogen-react/load-script';import {createGraphQLClient}from'@shopify/graphql-client';import {parse,stringify}from'worktop/cookie';import Za from'content-security-policy-builder';function me(e){let{type:t,data:r={},customData:o}=e,n=useLocation(),{publish:a,cart:s,prevCart:c,shop:i,customData:u}=Z(),d=n.pathname+n.search,y={...r,customData:{...u,...o},cart:s,prevCart:c,shop:i};return useEffect(()=>{i?.shopId&&(y={...y,url:window.location.href},a(t,y));},[a,d,i?.shopId]),null}function Rr(e){return jsx(me,{...e,type:"page_viewed"})}function Ir(e){return jsx(me,{...e,type:"product_viewed"})}function Tr(e){return jsx(me,{...e,type:"collection_viewed"})}function Er(e){return jsx(me,{...e,type:"cart_viewed"})}function br(e){return jsx(me,{...e,type:"search_viewed"})}function wr(e){return jsx(me,{...e})}var G={PAGE_VIEWED:"page_viewed",PRODUCT_VIEWED:"product_viewed",COLLECTION_VIEWED:"collection_viewed",CART_VIEWED:"cart_viewed",SEARCH_VIEWED:"search_viewed",CART_UPDATED:"cart_updated",PRODUCT_ADD_TO_CART:"product_added_to_cart",PRODUCT_REMOVED_FROM_CART:"product_removed_from_cart",CUSTOM_EVENT:"custom_"};var Ee="Custom-Storefront-Request-Group-ID",be="X-Shopify-Storefront-Access-Token",St="X-SDK-Variant",Pt="X-SDK-Variant-Source",vt="X-SDK-Version",We="X-Shopify-Client-IP",Ce="X-Shopify-Client-IP-Sig",je="_sfapi_proxy",Ke="_server_tracking";function Zo(e){return Object.entries(e).map(([t,r])=>r?`${t};desc=${r}`:void 0).filter(Boolean).join(", ")}function we(e,t){let r=typeof t=="string"?t:Zo(t);r&&e.headers.append("Server-Timing",r);}var en=["_y","_s","_cmp"];function Dr(e){let t={};if(!e)return t;let r=new RegExp(`\\b(${en.join("|")});desc="?([^",]+)"?`,"g"),o;for(;(o=r.exec(e))!==null;)t[o[1]]=o[2];return t}function Or(e){if(typeof window>"u")return false;try{return !!window.performance.getEntriesByType("navigation")[0]?.serverTiming?.some(r=>r.name===e)}catch{return false}}function xr(){return Or(je)}function _r(){return Or(Ke)}var sn="https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js",cn="https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js";function It(e){console.error(`[h2:error:useCustomerPrivacy] Unable to setup Customer Privacy API: Missing consent.${e} configuration.`);}function Tt(e){let{withPrivacyBanner:t=false,onVisitorConsentCollected:r,onReady:o,checkoutDomain:n,storefrontAccessToken:a,country:s,locale:c,sameDomainForStorefrontApi:i}=e,u=useMemo(()=>i??xr(),[i]),d=useMemo(()=>u&&!_r(),[u]),y=useShopifyCookies({fetchTrackingValues:d,storefrontAccessToken:a,ignoreDeprecatedCookies:true}),m=useMemo(getTrackingValues,[y]),{revalidate:g}=useRevalidator();useLoadScript$1(t?cn:sn,{attributes:{id:"customer-privacy-api"}});let{observing:p,setLoaded:l,apisLoaded:P}=dn({withPrivacyBanner:t}),f=useMemo(()=>{n||It("checkoutDomain"),a||It("storefrontAccessToken"),(a.startsWith("shpat_")||a.length!==32)&&console.error("[h2:error:useCustomerPrivacy] It looks like you passed a private access token, make sure to use the public token");let h=pn(n);return {checkoutRootDomain:u&&typeof window<"u"?window.location.host:n,storefrontRootDomain:h?"."+h:void 0,storefrontAccessToken:a,country:s,locale:c}},[It,n,a,s,c]);useEffect(()=>{let h=S=>{let C=getTrackingValues();if((m.visitToken!==C.visitToken||m.uniqueToken!==C.uniqueToken)&&g().catch(()=>{console.warn("[h2:warn:useCustomerPrivacy] Revalidation failed after consent change.");}),r){let I=se();if(I?.shouldShowBanner()){let v=I.currentVisitorConsent();if(v&&v.marketing===""&&v.analytics===""&&v.preferences==="")return}r(S.detail);}};return document.addEventListener("visitorConsentCollected",h),()=>{document.removeEventListener("visitorConsentCollected",h);}},[r]),useEffect(()=>{if(!t||p.current.privacyBanner)return;p.current.privacyBanner=true;let h=window.privacyBanner||void 0;Object.defineProperty(window,"privacyBanner",{configurable:true,get(){return h},set(C){typeof C=="object"&&C!==null&&"showPreferences"in C&&"loadBanner"in C&&(h=kr({privacyBanner:C,config:f}),l.privacyBanner());}});},[t,f,kr,l.privacyBanner]),useEffect(()=>{if(p.current.customerPrivacy)return;p.current.customerPrivacy=true;let h=null,S=null,C=window.Shopify||void 0;Object.defineProperty(window,"Shopify",{configurable:true,get(){return C},set(I){typeof I=="object"&&I!==null&&Object.keys(I).length===0&&(C=I,h={backendConsentEnabled:true},Object.defineProperty(window.Shopify,"customerPrivacy",{configurable:true,get(){return S??h},set(v){if(typeof v=="object"&&v!==null&&"setTrackingConsent"in v){let U=v;S={...U,setTrackingConsent:Lr({customerPrivacy:U,config:f})},C={...C,customerPrivacy:S},l.customerPrivacy();}}}));}});},[f,Lr,l.customerPrivacy]),useEffect(()=>{if(!P||!y)return;let h=se();if(h&&!h.cachedConsent){let S=getTrackingValues();S.consent&&(h.cachedConsent=S.consent);}if(t){let S=De();S&&S.loadBanner(f);}un(),o?.();},[P,y]);let R={customerPrivacy:se()};return t&&(R.privacyBanner=De()),R}var Ur=false;function un(){if(Ur)return;Ur=true;let e=new CustomEvent("shopifyCustomerPrivacyApiLoaded");document.dispatchEvent(e);}function dn({withPrivacyBanner:e}){let t=useRef({customerPrivacy:false,privacyBanner:false}),[r,o]=useState(e?[false,false]:[false]),n=r.every(Boolean);return {observing:t,setLoaded:{customerPrivacy:()=>{o(e?s=>[true,s[1]]:()=>[true]);},privacyBanner:()=>{e&&o(s=>[s[0],true]);}},apisLoaded:n}}function pn(e){if(typeof window>"u")return;let t=window.location.host,r=e.split(".").reverse(),o=t.split(".").reverse(),n=[];return r.forEach((a,s)=>{a===o[s]&&n.push(a);}),n.reverse().join(".")||void 0}function Lr({customerPrivacy:e,config:t}){let r=e.setTrackingConsent,{locale:o,country:n,...a}=t;function s(c,i){r({...a,headlessStorefront:true,...c},i);}return s}function kr({privacyBanner:e,config:t}){let r=e.loadBanner,o=e.showPreferences;function n(s){if(typeof s=="object"){r({...t,...s});return}r(t);}function a(s){if(typeof s=="object"){o({...t,...s});return}o(t);}return {loadBanner:n,showPreferences:a}}function se(){try{let e=window.Shopify?.customerPrivacy;return e&&"setTrackingConsent"in e?e:null}catch{return null}}function De(){try{return window&&window?.privacyBanner?window.privacyBanner:null}catch{return null}}var Vr="2026.4.1";function Cn(){let e=se();if(!e)throw new Error("Shopify Customer Privacy API not available. Must be used within a useEffect. Make sure to load the Shopify Customer Privacy API with useCustomerPrivacy() or <AnalyticsProvider>.");return e}function Mr({consent:e,onReady:t,domain:r}){let{subscribe:o,register:n,canTrack:a}=Z(),[s,c]=useState(false),[i,u]=useState(false),[d,y]=useState(""),m=useRef(false),{checkoutDomain:g,storefrontAccessToken:p,language:l}=e,{ready:P}=n("Internal_Shopify_Analytics");Tt({...e,locale:l,checkoutDomain:g||"mock.shop",storefrontAccessToken:p||"abcdefghijklmnopqrstuvwxyz123456",onReady:()=>!e.withPrivacyBanner&&u(true),onVisitorConsentCollected:R=>{try{y(JSON.stringify(R));}catch{}u(true);}});let f=useMemo(()=>i?a():true,[i,a,d]);return useShopifyCookies({hasUserConsent:f,domain:r,checkoutDomain:g,fetchTrackingValues:false,ignoreDeprecatedCookies:!i}),useEffect(()=>{m.current||(m.current=true,o(G.PAGE_VIEWED,An),o(G.PRODUCT_VIEWED,Sn),o(G.COLLECTION_VIEWED,Pn),o(G.SEARCH_VIEWED,vn),o(G.PRODUCT_ADD_TO_CART,Rn),c(true));},[o]),useEffect(()=>{s&&i&&(P(),t());},[s,i,t]),null}function ze(e){console.error(`[h2:error:ShopifyAnalytics] Unable to send Shopify analytics: Missing shop.${e} configuration.`);}function _e(e){let t=Cn(),r=t.analyticsProcessingAllowed();if(!e?.shop?.shopId){ze("shopId");return}if(!e?.shop?.acceptedLanguage){ze("acceptedLanguage");return}if(!e?.shop?.currency){ze("currency");return}if(!e?.shop?.hydrogenSubchannelId){ze("hydrogenSubchannelId");return}return {shopifySalesChannel:"hydrogen",assetVersionId:Vr,...e.shop,hasUserConsent:r,...getClientBrowserParameters(),analyticsAllowed:t.analyticsProcessingAllowed(),marketingAllowed:t.marketingAllowed(),saleOfDataAllowed:t.saleOfDataAllowed(),ccpaEnforced:!t.saleOfDataAllowed(),gdprEnforced:!(t.marketingAllowed()&&t.analyticsProcessingAllowed())}}function hn(e,t){if(t===null)return;let r=_e(e);return r?{...r,cartId:t.id}:void 0}var ie={};function An(e){let t=_e(e);t&&(sendShopifyAnalytics({eventName:AnalyticsEventName.PAGE_VIEW_2,payload:{...t,...ie}}),ie={});}function Sn(e){let t=_e(e);if(t&&Fr({type:"product",products:e.products})){let r=bt(e.products);ie={pageType:AnalyticsPageType.product,resourceId:r[0].productGid},t={...t,...ie,products:bt(e.products)},sendShopifyAnalytics({eventName:AnalyticsEventName.PRODUCT_VIEW,payload:t});}}function Pn(e){let t=_e(e);t&&(ie={pageType:AnalyticsPageType.collection,resourceId:e.collection.id},t={...t,...ie,collectionHandle:e.collection.handle,collectionId:e.collection.id},sendShopifyAnalytics({eventName:AnalyticsEventName.COLLECTION_VIEW,payload:t}));}function vn(e){let t=_e(e);t&&(ie={pageType:AnalyticsPageType.search},t={...t,...ie,searchString:e.searchTerm},sendShopifyAnalytics({eventName:AnalyticsEventName.SEARCH_VIEW,payload:t}));}function Rn(e){let{cart:t,currentLine:r}=e,o=hn(e,t);!o||!r?.id||In({matchedLine:r,eventPayload:o});}function In({matchedLine:e,eventPayload:t}){let r={id:e.merchandise.product.id,variantId:e.merchandise.id,title:e.merchandise.product.title,variantTitle:e.merchandise.title,vendor:e.merchandise.product.vendor,price:e.merchandise.price.amount,quantity:e.quantity,productType:e.merchandise.product.productType,sku:e.merchandise.sku};Fr({type:"cart",products:[r]})&&sendShopifyAnalytics({eventName:AnalyticsEventName.ADD_TO_CART,payload:{...t,products:bt([r])}});}function pe(e,t,r,o){if(e==="cart"){let n=`${r?"merchandise":"merchandise.product"}.${t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up cart analytics events because the \`cart.lines[].${n}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartLine on CartLine\` is defined and make sure \`${n}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L25-L56.`);}else {let n=`${o||t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up product view analytics events because the \`${n}\` is missing from your \`<Analytics.ProductView>\`. Make sure \`${n}\` is part of your products data prop. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/routes/products.%24handle.tsx#L159-L165.`);}}function Fr({type:e,products:t}){return !t||t.length===0?(pe(e,"",false,"data.products"),false):(t.forEach(r=>{if(!r.id)return pe(e,"id",false),false;if(!r.title)return pe(e,"title",false),false;if(!r.price)return pe(e,"price.amount",true,"price"),false;if(!r.vendor)return pe(e,"vendor",false),false;if(!r.variantId)return pe(e,"id",true,"variantId"),false;if(!r.variantTitle)return pe(e,"title",true,"variantTitle"),false}),true)}function bt(e){return e.map(t=>{let r={productGid:t.id,variantGid:t.variantId,name:t.title,variantName:t.variantTitle,brand:t.vendor,price:t.price,quantity:t.quantity||1,category:t.productType};return t.sku&&(r.sku=t.sku),t.productType&&(r.category=t.productType),r})}function $r(e){console.error(`[h2:error:CartAnalytics] Can't set up cart analytics events because the \`cart.${e}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartApiQuery on Cart\` is defined and make sure \`${e}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L59.`);}function Gr({cart:e,setCarts:t}){let{publish:r,shop:o,customData:n,canTrack:a,cart:s,prevCart:c}=Z(),i=useRef(null);return useEffect(()=>{if(e)return Promise.resolve(e).then(u=>{if(u&&u.lines){if(!u.id){$r("id");return}if(!u.updatedAt){$r("updatedAt");return}}t(({cart:d,prevCart:y})=>u?.updatedAt!==d?.updatedAt?{cart:u,prevCart:d}:{cart:d,prevCart:y});}),()=>{}},[t,e]),useEffect(()=>{if(!s||!s?.updatedAt||s?.updatedAt===c?.updatedAt)return;let u;try{u=JSON.parse(localStorage.getItem("cartLastUpdatedAt")||"");}catch{u=null;}if(s.id===u?.id&&s.updatedAt===u?.updatedAt)return;let d={eventTimestamp:Date.now(),cart:s,prevCart:c,shop:o,customData:n};if(s.updatedAt===i.current)return;i.current=s.updatedAt,r("cart_updated",d),localStorage.setItem("cartLastUpdatedAt",JSON.stringify({id:s.id,updatedAt:s.updatedAt}));let y=c?.lines?flattenConnection(c?.lines):[],m=s.lines?flattenConnection(s.lines):[];y?.forEach(g=>{let p=m.filter(l=>g.id===l.id);if(p?.length===1){let l=p[0];g.quantity<l.quantity?r("product_added_to_cart",{...d,prevLine:g,currentLine:l}):g.quantity>l.quantity&&r("product_removed_from_cart",{...d,prevLine:g,currentLine:l});}else r("product_removed_from_cart",{...d,prevLine:g});}),m?.forEach(g=>{let p=y.filter(l=>g.id===l.id);(!p||p.length===0)&&r("product_added_to_cart",{...d,currentLine:g});});},[s,c,r,o,n,a]),null}var On="https://cdn.shopify.com/shopifycloud/perf-kit/shopify-perf-kit-spa.min.js";function Br({shop:e}){let t=useRef(false),{subscribe:r,register:o}=Z(),{ready:n}=o("Internal_Shopify_Perf_Kit"),a=useLoadScript(On,{attributes:{id:"perfkit","data-application":"hydrogen","data-shop-id":parseGid(e.shopId).id.toString(),"data-storefront-id":e.hydrogenSubchannelId,"data-monorail-region":"global","data-spa-mode":"true","data-resource-timing-sampling-rate":"100"}});return useEffect(()=>{a!=="done"||t.current||(t.current=true,r(G.PAGE_VIEWED,()=>{window.PerfKit?.navigate();}),r(G.PRODUCT_VIEWED,()=>{window.PerfKit?.setPageType("product");}),r(G.COLLECTION_VIEWED,()=>{window.PerfKit?.setPageType("collection");}),r(G.SEARCH_VIEWED,()=>{window.PerfKit?.setPageType("search");}),r(G.CART_VIEWED,()=>{window.PerfKit?.setPageType("cart");}),n());},[r,n,a]),null}var Qr=new Set,ee=e=>{Qr.has(e)||(console.warn(e),Qr.add(e));},Wr=new Set,Dt=e=>{Wr.has(e)||(console.error(new Error(e)),Wr.add(e));};var kn={canTrack:()=>false,cart:null,customData:{},prevCart:null,publish:()=>{},shop:null,subscribe:()=>{},register:()=>({ready:()=>{}}),customerPrivacy:null,privacyBanner:null},Xr=createContext(kn),Ze=new Map,Le={};function Zr(){return Object.values(Le).every(Boolean)}function jr(e,t){Ze.has(e)||Ze.set(e,new Map),Ze.get(e)?.set(t.toString(),t);}var et=new Map;function Kr(e,t){if(!Zr()){et.set(e,t);return}eo(e,t);}function eo(e,t){(Ze.get(e)??new Map).forEach((r,o)=>{try{r(t);}catch(n){typeof n=="object"&&n instanceof Error?console.error("Analytics publish error",n.message,o,n.stack):console.error("Analytics publish error",n,o);}});}function Yr(e){return Le.hasOwnProperty(e)||(Le[e]=false),{ready:()=>{Le[e]=true,Zr()&&et.size>0&&(et.forEach((t,r)=>{eo(r,t);}),et.clear());}}}function Jr(){try{return window.Shopify.customerPrivacy?.analyticsProcessingAllowed?.()??!1}catch{}return false}function zr(e,t){return `[h2:error:Analytics.Provider] - ${e} is required. Make sure ${t} is defined in your environment variables. See https://h2o.fyi/analytics/consent to learn how to setup environment variables in the Shopify admin.`}function Vn({canTrack:e,cart:t,children:r,consent:o,customData:n={},shop:a=null,cookieDomain:s}){let{shop:c}=Nn(a),[i,u]=useState(!!e),[d,y]=useState(false),[m,g]=useState({cart:null,prevCart:null}),[p,l]=useState(e?()=>e:()=>Jr);if(c)if(/\/68817551382$/.test(c.shopId))ee("[h2:error:Analytics.Provider] - Mock shop is used. Analytics will not work properly.");else {if(!o.checkoutDomain){let f=zr("consent.checkoutDomain","PUBLIC_CHECKOUT_DOMAIN");Dt(f);}if(!o.storefrontAccessToken){let f=zr("consent.storefrontAccessToken","PUBLIC_STOREFRONT_API_TOKEN");Dt(f);}o?.country||(o.country="US"),o?.language||(o.language="EN"),o.withPrivacyBanner===void 0&&(o.withPrivacyBanner=false);}let P=useMemo(()=>({canTrack:p,...m,customData:n,publish:p()?Kr:()=>{},shop:c,subscribe:jr,register:Yr,customerPrivacy:se(),privacyBanner:De()}),[i,p,m,m.cart?.updatedAt,m.prevCart,Kr,jr,n,c,Yr,JSON.stringify(Le),se,De]);return jsxs(Xr.Provider,{value:P,children:[r,!!c&&jsx(Rr,{}),!!c&&!!t&&jsx(Gr,{cart:t,setCarts:g}),!!c&&jsx(Mr,{consent:o,onReady:()=>{u(true),l(e?()=>e:()=>Jr),y(true);},domain:s}),!!c&&d&&jsx(Br,{shop:c})]})}function Z(){let e=useContext(Xr);if(!e)throw new Error("[h2:error:useAnalytics] 'useAnalytics()' must be a descendent of <AnalyticsProvider/>");return e}function Nn(e){let[t,r]=useState(null);return useEffect(()=>(Promise.resolve(e).then(r),()=>{}),[r,e]),{shop:t}}async function Mn({storefront:e,publicStorefrontId:t="0"}){return e.query(Fn,{cache:e.CacheLong()}).then(({shop:r,localization:o})=>({shopId:r.id,acceptedLanguage:o.language.isoCode,currency:o.country.currency.isoCode,hydrogenSubchannelId:t}))}var Fn=`#graphql
1
+ import {createContext,forwardRef,lazy,useContext,useMemo,useEffect,useRef,useState,createElement,Fragment as Fragment$1,Suspense}from'react';import {createContext as createContext$1,useRevalidator,useFetcher,useFetchers,RouterContextProvider,createRequestHandler,useNavigation,useLocation,useNavigate,Link,useMatches}from'react-router';import {jsx,jsxs,Fragment}from'react/jsx-runtime';import {useLoadScript,useShopifyCookies,getTrackingValues,createStorefrontClient,SHOPIFY_STOREFRONT_ID_HEADER,SHOPIFY_STOREFRONT_Y_HEADER,SHOPIFY_STOREFRONT_S_HEADER,SHOPIFY_UNIQUE_TOKEN_HEADER,SHOPIFY_VISIT_TOKEN_HEADER,flattenConnection,RichText,ShopPayButton,parseGid,sendShopifyAnalytics,AnalyticsEventName,AnalyticsPageType,getClientBrowserParameters}from'@shopify/hydrogen-react';export{AnalyticsEventName,AnalyticsPageType,ExternalVideo,IMAGE_FRAGMENT,Image,MediaFile,ModelViewer,Money,ShopifySalesChannel,Video,customerAccountApiCustomScalars,decodeEncodedVariant,flattenConnection,getAdjacentAndFirstAvailableVariants,getClientBrowserParameters,getProductOptions,getShopifyCookies,getTrackingValues,isOptionValueCombinationInEncodedVariant,mapSelectedProductOptionToObject,parseGid,parseMetafield,sendShopifyAnalytics,storefrontApiCustomScalars,useLoadScript,useMoney,useSelectedOptionInUrlParam,useShopifyCookies}from'@shopify/hydrogen-react';import {useLoadScript as useLoadScript$1}from'@shopify/hydrogen-react/load-script';import {createGraphQLClient}from'@shopify/graphql-client';import {parse,stringify}from'worktop/cookie';import Za from'content-security-policy-builder';function me(e){let{type:t,data:r={},customData:o}=e,n=useLocation(),{publish:a,cart:s,prevCart:c,shop:i,customData:u}=Z(),d=n.pathname+n.search,y={...r,customData:{...u,...o},cart:s,prevCart:c,shop:i};return useEffect(()=>{i?.shopId&&(y={...y,url:window.location.href},a(t,y));},[a,d,i?.shopId]),null}function Rr(e){return jsx(me,{...e,type:"page_viewed"})}function Ir(e){return jsx(me,{...e,type:"product_viewed"})}function Tr(e){return jsx(me,{...e,type:"collection_viewed"})}function Er(e){return jsx(me,{...e,type:"cart_viewed"})}function br(e){return jsx(me,{...e,type:"search_viewed"})}function wr(e){return jsx(me,{...e})}var G={PAGE_VIEWED:"page_viewed",PRODUCT_VIEWED:"product_viewed",COLLECTION_VIEWED:"collection_viewed",CART_VIEWED:"cart_viewed",SEARCH_VIEWED:"search_viewed",CART_UPDATED:"cart_updated",PRODUCT_ADD_TO_CART:"product_added_to_cart",PRODUCT_REMOVED_FROM_CART:"product_removed_from_cart",CUSTOM_EVENT:"custom_"};var Ee="Custom-Storefront-Request-Group-ID",be="X-Shopify-Storefront-Access-Token",St="X-SDK-Variant",Pt="X-SDK-Variant-Source",vt="X-SDK-Version",We="X-Shopify-Client-IP",Ce="X-Shopify-Client-IP-Sig",je="_sfapi_proxy",Ke="_server_tracking";function Zo(e){return Object.entries(e).map(([t,r])=>r?`${t};desc=${r}`:void 0).filter(Boolean).join(", ")}function we(e,t){let r=typeof t=="string"?t:Zo(t);r&&e.headers.append("Server-Timing",r);}var en=["_y","_s","_cmp"];function Dr(e){let t={};if(!e)return t;let r=new RegExp(`\\b(${en.join("|")});desc="?([^",]+)"?`,"g"),o;for(;(o=r.exec(e))!==null;)t[o[1]]=o[2];return t}function Or(e){if(typeof window>"u")return false;try{return !!window.performance.getEntriesByType("navigation")[0]?.serverTiming?.some(r=>r.name===e)}catch{return false}}function xr(){return Or(je)}function _r(){return Or(Ke)}var sn="https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js",cn="https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js";function It(e){console.error(`[h2:error:useCustomerPrivacy] Unable to setup Customer Privacy API: Missing consent.${e} configuration.`);}function Tt(e){let{withPrivacyBanner:t=false,onVisitorConsentCollected:r,onReady:o,checkoutDomain:n,storefrontAccessToken:a,country:s,locale:c,sameDomainForStorefrontApi:i}=e,u=useMemo(()=>i??xr(),[i]),d=useMemo(()=>u&&!_r(),[u]),y=useShopifyCookies({fetchTrackingValues:d,storefrontAccessToken:a,ignoreDeprecatedCookies:true}),m=useMemo(getTrackingValues,[y]),{revalidate:g}=useRevalidator();useLoadScript$1(t?cn:sn,{attributes:{id:"customer-privacy-api"}});let{observing:p,setLoaded:l,apisLoaded:P}=dn({withPrivacyBanner:t}),f=useMemo(()=>{n||It("checkoutDomain"),a||It("storefrontAccessToken"),(a.startsWith("shpat_")||a.length!==32)&&console.error("[h2:error:useCustomerPrivacy] It looks like you passed a private access token, make sure to use the public token");let h=pn(n);return {checkoutRootDomain:u&&typeof window<"u"?window.location.host:n,storefrontRootDomain:h?"."+h:void 0,storefrontAccessToken:a,country:s,locale:c}},[It,n,a,s,c]);useEffect(()=>{let h=S=>{let C=getTrackingValues();if((m.visitToken!==C.visitToken||m.uniqueToken!==C.uniqueToken)&&g().catch(()=>{console.warn("[h2:warn:useCustomerPrivacy] Revalidation failed after consent change.");}),r){let I=se();if(I?.shouldShowBanner()){let v=I.currentVisitorConsent();if(v&&v.marketing===""&&v.analytics===""&&v.preferences==="")return}r(S.detail);}};return document.addEventListener("visitorConsentCollected",h),()=>{document.removeEventListener("visitorConsentCollected",h);}},[r]),useEffect(()=>{if(!t||p.current.privacyBanner)return;p.current.privacyBanner=true;let h=window.privacyBanner||void 0;Object.defineProperty(window,"privacyBanner",{configurable:true,get(){return h},set(C){typeof C=="object"&&C!==null&&"showPreferences"in C&&"loadBanner"in C&&(h=kr({privacyBanner:C,config:f}),l.privacyBanner());}});},[t,f,kr,l.privacyBanner]),useEffect(()=>{if(p.current.customerPrivacy)return;p.current.customerPrivacy=true;let h=null,S=null,C=window.Shopify||void 0;Object.defineProperty(window,"Shopify",{configurable:true,get(){return C},set(I){typeof I=="object"&&I!==null&&Object.keys(I).length===0&&(C=I,h={backendConsentEnabled:true},Object.defineProperty(window.Shopify,"customerPrivacy",{configurable:true,get(){return S??h},set(v){if(typeof v=="object"&&v!==null&&"setTrackingConsent"in v){let U=v;S={...U,setTrackingConsent:Lr({customerPrivacy:U,config:f})},C={...C,customerPrivacy:S},l.customerPrivacy();}}}));}});},[f,Lr,l.customerPrivacy]),useEffect(()=>{if(!P||!y)return;let h=se();if(h&&!h.cachedConsent){let S=getTrackingValues();S.consent&&(h.cachedConsent=S.consent);}if(t){let S=De();S&&S.loadBanner(f);}un(),o?.();},[P,y]);let R={customerPrivacy:se()};return t&&(R.privacyBanner=De()),R}var Ur=false;function un(){if(Ur)return;Ur=true;let e=new CustomEvent("shopifyCustomerPrivacyApiLoaded");document.dispatchEvent(e);}function dn({withPrivacyBanner:e}){let t=useRef({customerPrivacy:false,privacyBanner:false}),[r,o]=useState(e?[false,false]:[false]),n=r.every(Boolean);return {observing:t,setLoaded:{customerPrivacy:()=>{o(e?s=>[true,s[1]]:()=>[true]);},privacyBanner:()=>{e&&o(s=>[s[0],true]);}},apisLoaded:n}}function pn(e){if(typeof window>"u")return;let t=window.location.host,r=e.split(".").reverse(),o=t.split(".").reverse(),n=[];return r.forEach((a,s)=>{a===o[s]&&n.push(a);}),n.reverse().join(".")||void 0}function Lr({customerPrivacy:e,config:t}){let r=e.setTrackingConsent,{locale:o,country:n,...a}=t;function s(c,i){r({...a,headlessStorefront:true,...c},i);}return s}function kr({privacyBanner:e,config:t}){let r=e.loadBanner,o=e.showPreferences;function n(s){if(typeof s=="object"){r({...t,...s});return}r(t);}function a(s){if(typeof s=="object"){o({...t,...s});return}o(t);}return {loadBanner:n,showPreferences:a}}function se(){try{let e=window.Shopify?.customerPrivacy;return e&&"setTrackingConsent"in e?e:null}catch{return null}}function De(){try{return window&&window?.privacyBanner?window.privacyBanner:null}catch{return null}}var Vr="2026.4.2";function Cn(){let e=se();if(!e)throw new Error("Shopify Customer Privacy API not available. Must be used within a useEffect. Make sure to load the Shopify Customer Privacy API with useCustomerPrivacy() or <AnalyticsProvider>.");return e}function Mr({consent:e,onReady:t,domain:r}){let{subscribe:o,register:n,canTrack:a}=Z(),[s,c]=useState(false),[i,u]=useState(false),[d,y]=useState(""),m=useRef(false),{checkoutDomain:g,storefrontAccessToken:p,language:l}=e,{ready:P}=n("Internal_Shopify_Analytics");Tt({...e,locale:l,checkoutDomain:g||"mock.shop",storefrontAccessToken:p||"abcdefghijklmnopqrstuvwxyz123456",onReady:()=>!e.withPrivacyBanner&&u(true),onVisitorConsentCollected:R=>{try{y(JSON.stringify(R));}catch{}u(true);}});let f=useMemo(()=>i?a():true,[i,a,d]);return useShopifyCookies({hasUserConsent:f,domain:r,checkoutDomain:g,fetchTrackingValues:false,ignoreDeprecatedCookies:!i}),useEffect(()=>{m.current||(m.current=true,o(G.PAGE_VIEWED,An),o(G.PRODUCT_VIEWED,Sn),o(G.COLLECTION_VIEWED,Pn),o(G.SEARCH_VIEWED,vn),o(G.PRODUCT_ADD_TO_CART,Rn),c(true));},[o]),useEffect(()=>{s&&i&&(P(),t());},[s,i,t]),null}function ze(e){console.error(`[h2:error:ShopifyAnalytics] Unable to send Shopify analytics: Missing shop.${e} configuration.`);}function _e(e){let t=Cn(),r=t.analyticsProcessingAllowed();if(!e?.shop?.shopId){ze("shopId");return}if(!e?.shop?.acceptedLanguage){ze("acceptedLanguage");return}if(!e?.shop?.currency){ze("currency");return}if(!e?.shop?.hydrogenSubchannelId){ze("hydrogenSubchannelId");return}return {shopifySalesChannel:"hydrogen",assetVersionId:Vr,...e.shop,hasUserConsent:r,...getClientBrowserParameters(),analyticsAllowed:t.analyticsProcessingAllowed(),marketingAllowed:t.marketingAllowed(),saleOfDataAllowed:t.saleOfDataAllowed(),ccpaEnforced:!t.saleOfDataAllowed(),gdprEnforced:!(t.marketingAllowed()&&t.analyticsProcessingAllowed())}}function hn(e,t){if(t===null)return;let r=_e(e);return r?{...r,cartId:t.id}:void 0}var ie={};function An(e){let t=_e(e);t&&(sendShopifyAnalytics({eventName:AnalyticsEventName.PAGE_VIEW_2,payload:{...t,...ie}}),ie={});}function Sn(e){let t=_e(e);if(t&&Fr({type:"product",products:e.products})){let r=bt(e.products);ie={pageType:AnalyticsPageType.product,resourceId:r[0].productGid},t={...t,...ie,products:bt(e.products)},sendShopifyAnalytics({eventName:AnalyticsEventName.PRODUCT_VIEW,payload:t});}}function Pn(e){let t=_e(e);t&&(ie={pageType:AnalyticsPageType.collection,resourceId:e.collection.id},t={...t,...ie,collectionHandle:e.collection.handle,collectionId:e.collection.id},sendShopifyAnalytics({eventName:AnalyticsEventName.COLLECTION_VIEW,payload:t}));}function vn(e){let t=_e(e);t&&(ie={pageType:AnalyticsPageType.search},t={...t,...ie,searchString:e.searchTerm},sendShopifyAnalytics({eventName:AnalyticsEventName.SEARCH_VIEW,payload:t}));}function Rn(e){let{cart:t,currentLine:r}=e,o=hn(e,t);!o||!r?.id||In({matchedLine:r,eventPayload:o});}function In({matchedLine:e,eventPayload:t}){let r={id:e.merchandise.product.id,variantId:e.merchandise.id,title:e.merchandise.product.title,variantTitle:e.merchandise.title,vendor:e.merchandise.product.vendor,price:e.merchandise.price.amount,quantity:e.quantity,productType:e.merchandise.product.productType,sku:e.merchandise.sku};Fr({type:"cart",products:[r]})&&sendShopifyAnalytics({eventName:AnalyticsEventName.ADD_TO_CART,payload:{...t,products:bt([r])}});}function pe(e,t,r,o){if(e==="cart"){let n=`${r?"merchandise":"merchandise.product"}.${t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up cart analytics events because the \`cart.lines[].${n}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartLine on CartLine\` is defined and make sure \`${n}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L25-L56.`);}else {let n=`${o||t}`;console.error(`[h2:error:ShopifyAnalytics] Can't set up product view analytics events because the \`${n}\` is missing from your \`<Analytics.ProductView>\`. Make sure \`${n}\` is part of your products data prop. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/routes/products.%24handle.tsx#L159-L165.`);}}function Fr({type:e,products:t}){return !t||t.length===0?(pe(e,"",false,"data.products"),false):(t.forEach(r=>{if(!r.id)return pe(e,"id",false),false;if(!r.title)return pe(e,"title",false),false;if(!r.price)return pe(e,"price.amount",true,"price"),false;if(!r.vendor)return pe(e,"vendor",false),false;if(!r.variantId)return pe(e,"id",true,"variantId"),false;if(!r.variantTitle)return pe(e,"title",true,"variantTitle"),false}),true)}function bt(e){return e.map(t=>{let r={productGid:t.id,variantGid:t.variantId,name:t.title,variantName:t.variantTitle,brand:t.vendor,price:t.price,quantity:t.quantity||1,category:t.productType};return t.sku&&(r.sku=t.sku),t.productType&&(r.category=t.productType),r})}function $r(e){console.error(`[h2:error:CartAnalytics] Can't set up cart analytics events because the \`cart.${e}\` value is missing from your GraphQL cart query. In your project, search for where \`fragment CartApiQuery on Cart\` is defined and make sure \`${e}\` is part of your cart query. Check the Hydrogen Skeleton template for reference: https://github.com/Shopify/hydrogen/blob/main/templates/skeleton/app/lib/fragments.ts#L59.`);}function Gr({cart:e,setCarts:t}){let{publish:r,shop:o,customData:n,canTrack:a,cart:s,prevCart:c}=Z(),i=useRef(null);return useEffect(()=>{if(e)return Promise.resolve(e).then(u=>{if(u&&u.lines){if(!u.id){$r("id");return}if(!u.updatedAt){$r("updatedAt");return}}t(({cart:d,prevCart:y})=>u?.updatedAt!==d?.updatedAt?{cart:u,prevCart:d}:{cart:d,prevCart:y});}),()=>{}},[t,e]),useEffect(()=>{if(!s||!s?.updatedAt||s?.updatedAt===c?.updatedAt)return;let u;try{u=JSON.parse(localStorage.getItem("cartLastUpdatedAt")||"");}catch{u=null;}if(s.id===u?.id&&s.updatedAt===u?.updatedAt)return;let d={eventTimestamp:Date.now(),cart:s,prevCart:c,shop:o,customData:n};if(s.updatedAt===i.current)return;i.current=s.updatedAt,r("cart_updated",d),localStorage.setItem("cartLastUpdatedAt",JSON.stringify({id:s.id,updatedAt:s.updatedAt}));let y=c?.lines?flattenConnection(c?.lines):[],m=s.lines?flattenConnection(s.lines):[];y?.forEach(g=>{let p=m.filter(l=>g.id===l.id);if(p?.length===1){let l=p[0];g.quantity<l.quantity?r("product_added_to_cart",{...d,prevLine:g,currentLine:l}):g.quantity>l.quantity&&r("product_removed_from_cart",{...d,prevLine:g,currentLine:l});}else r("product_removed_from_cart",{...d,prevLine:g});}),m?.forEach(g=>{let p=y.filter(l=>g.id===l.id);(!p||p.length===0)&&r("product_added_to_cart",{...d,currentLine:g});});},[s,c,r,o,n,a]),null}var On="https://cdn.shopify.com/shopifycloud/perf-kit/shopify-perf-kit-spa.min.js";function Br({shop:e}){let t=useRef(false),{subscribe:r,register:o}=Z(),{ready:n}=o("Internal_Shopify_Perf_Kit"),a=useLoadScript(On,{attributes:{id:"perfkit","data-application":"hydrogen","data-shop-id":parseGid(e.shopId).id.toString(),"data-storefront-id":e.hydrogenSubchannelId,"data-monorail-region":"global","data-spa-mode":"true","data-resource-timing-sampling-rate":"100"}});return useEffect(()=>{a!=="done"||t.current||(t.current=true,r(G.PAGE_VIEWED,()=>{window.PerfKit?.navigate();}),r(G.PRODUCT_VIEWED,()=>{window.PerfKit?.setPageType("product");}),r(G.COLLECTION_VIEWED,()=>{window.PerfKit?.setPageType("collection");}),r(G.SEARCH_VIEWED,()=>{window.PerfKit?.setPageType("search");}),r(G.CART_VIEWED,()=>{window.PerfKit?.setPageType("cart");}),n());},[r,n,a]),null}var Qr=new Set,ee=e=>{Qr.has(e)||(console.warn(e),Qr.add(e));},Wr=new Set,Dt=e=>{Wr.has(e)||(console.error(new Error(e)),Wr.add(e));};var kn={canTrack:()=>false,cart:null,customData:{},prevCart:null,publish:()=>{},shop:null,subscribe:()=>{},register:()=>({ready:()=>{}}),customerPrivacy:null,privacyBanner:null},Xr=createContext(kn),Ze=new Map,Le={};function Zr(){return Object.values(Le).every(Boolean)}function jr(e,t){Ze.has(e)||Ze.set(e,new Map),Ze.get(e)?.set(t.toString(),t);}var et=new Map;function Kr(e,t){if(!Zr()){et.set(e,t);return}eo(e,t);}function eo(e,t){(Ze.get(e)??new Map).forEach((r,o)=>{try{r(t);}catch(n){typeof n=="object"&&n instanceof Error?console.error("Analytics publish error",n.message,o,n.stack):console.error("Analytics publish error",n,o);}});}function Yr(e){return Le.hasOwnProperty(e)||(Le[e]=false),{ready:()=>{Le[e]=true,Zr()&&et.size>0&&(et.forEach((t,r)=>{eo(r,t);}),et.clear());}}}function Jr(){try{return window.Shopify.customerPrivacy?.analyticsProcessingAllowed?.()??!1}catch{}return false}function zr(e,t){return `[h2:error:Analytics.Provider] - ${e} is required. Make sure ${t} is defined in your environment variables. See https://h2o.fyi/analytics/consent to learn how to setup environment variables in the Shopify admin.`}function Vn({canTrack:e,cart:t,children:r,consent:o,customData:n={},shop:a=null,cookieDomain:s}){let{shop:c}=Nn(a),[i,u]=useState(!!e),[d,y]=useState(false),[m,g]=useState({cart:null,prevCart:null}),[p,l]=useState(e?()=>e:()=>Jr);if(c)if(/\/68817551382$/.test(c.shopId))ee("[h2:error:Analytics.Provider] - Mock shop is used. Analytics will not work properly.");else {if(!o.checkoutDomain){let f=zr("consent.checkoutDomain","PUBLIC_CHECKOUT_DOMAIN");Dt(f);}if(!o.storefrontAccessToken){let f=zr("consent.storefrontAccessToken","PUBLIC_STOREFRONT_API_TOKEN");Dt(f);}o?.country||(o.country="US"),o?.language||(o.language="EN"),o.withPrivacyBanner===void 0&&(o.withPrivacyBanner=false);}let P=useMemo(()=>({canTrack:p,...m,customData:n,publish:p()?Kr:()=>{},shop:c,subscribe:jr,register:Yr,customerPrivacy:se(),privacyBanner:De()}),[i,p,m,m.cart?.updatedAt,m.prevCart,Kr,jr,n,c,Yr,JSON.stringify(Le),se,De]);return jsxs(Xr.Provider,{value:P,children:[r,!!c&&jsx(Rr,{}),!!c&&!!t&&jsx(Gr,{cart:t,setCarts:g}),!!c&&jsx(Mr,{consent:o,onReady:()=>{u(true),l(e?()=>e:()=>Jr),y(true);},domain:s}),!!c&&d&&jsx(Br,{shop:c})]})}function Z(){let e=useContext(Xr);if(!e)throw new Error("[h2:error:useAnalytics] 'useAnalytics()' must be a descendent of <AnalyticsProvider/>");return e}function Nn(e){let[t,r]=useState(null);return useEffect(()=>(Promise.resolve(e).then(r),()=>{}),[r,e]),{shop:t}}async function Mn({storefront:e,publicStorefrontId:t="0"}){return e.query(Fn,{cache:e.CacheLong()}).then(({shop:r,localization:o})=>({shopId:r.id,acceptedLanguage:o.language.isoCode,currency:o.country.currency.isoCode,hydrogenSubchannelId:t}))}var Fn=`#graphql
2
2
  query ShopData(
3
3
  $country: CountryCode
4
4
  $language: LanguageCode
@@ -20,7 +20,7 @@ import {createContext,forwardRef,lazy,useContext,useMemo,useEffect,useRef,useSta
20
20
  `,Hn={CartView:Er,CollectionView:Tr,CustomView:wr,ProductView:Ir,Provider:Vn,SearchView:br};function Y(e,t){return Ot(e.headers,t)}function Ot(e,t){let r=e?.get?.(t)??e?.[t];return typeof r=="string"?r:null}function ce(e){return {requestId:e?Y(e,"request-id"):void 0,purpose:e?Y(e,"purpose"):void 0}}function to(e){return {requestGroupId:Y(e,"request-id"),buyerIp:Y(e,"oxygen-buyer-ip"),buyerIpSig:Y(e,Ce),cookie:Y(e,"cookie"),purpose:Y(e,"sec-purpose")||Y(e,"purpose")}}var xt=/^\/api\/(unstable|2\d{3}-\d{2})\/graphql\.json$/,ro=/^\/api\/mcp$/,tt=e=>{try{return new URL(e,"http://e.c").pathname}catch{return "/"}};function ke(e,t){return t.reduce((r,o)=>{let n=e(o);return n&&r.push([o,n]),r},[])}function he(e,t={}){let r=new Error,o=(n,a="Error")=>{let s=(r.stack??"").split(`
21
21
  `).slice(3+(t.stackOffset??0)).join(`
22
22
  `).replace(/ at loader(\d+) \(/,(c,i)=>c.replace(i,""));return `${a}: ${n}
23
- `+s};return e.then(n=>{if(n?.errors&&Array.isArray(n.errors)){let a=typeof t.logErrors=="function"?t.logErrors:()=>t.logErrors??false;n.errors.forEach(s=>{s&&(s.stack=o(s.message,s.name),a(s)&&console.error(s));});}return n}).catch(n=>{throw n&&(n.stack=o(n.message,n.name)),n})}var J=void 0;var rt="public",$n="private",_t="no-store",oo={maxAge:"max-age",staleWhileRevalidate:"stale-while-revalidate",sMaxAge:"s-maxage",staleIfError:"stale-if-error"};function Ve(e){let t=[];return Object.keys(e).forEach(r=>{r==="mode"?t.push(e[r]):oo[r]&&t.push(`${oo[r]}=${e[r]}`);}),t.join(", ")}function Ut(){return {mode:_t}}function Lt(e){if(e?.mode&&e?.mode!==rt&&e?.mode!==$n)throw Error("'mode' must be either 'public' or 'private'")}function le(e){return Lt(e),{mode:rt,maxAge:1,staleWhileRevalidate:9,...e}}function kt(e){return Lt(e),{mode:rt,maxAge:3600,staleWhileRevalidate:82800,...e}}function Ae(e){return Lt(e),{mode:rt,maxAge:1,staleWhileRevalidate:86399,...e}}function Vt(e){return e}function te(e){return String(e).includes("__proto__")?JSON.parse(e,Gn):JSON.parse(e)}function Gn(e,t){if(e!=="__proto__")return t}function ot(e,t){return e&&t?{...e,...t}:e||Ae()}function Nt(e){return Ve(ot(e))}async function Bn(e,t){if(!e)return;let r=await e.match(t);if(!r){return}return r}async function Qn(e,t,r,o){if(!e)return;let n=ot(o),a=Nt(ot(n,{maxAge:(n.maxAge||0)+(n.staleWhileRevalidate||0)})),s=Nt(ot(n));r.headers.set("cache-control",a),r.headers.set("real-cache-control",s),r.headers.set("cache-put-date",String(Date.now())),await e.put(t,r);}async function Wn(e,t){e&&await e.delete(t);}function jn(e,t){let r=e.headers.get("real-cache-control"),o=0;if(r){let a=r.match(/max-age=(\d*)/);a&&a.length>1&&(o=parseFloat(a[1]));}return [(Date.now()-Number(t))/1e3,o]}function Kn(e,t){let r=t.headers.get("cache-put-date");if(!r)return false;let[o,n]=jn(t,r),a=o>n;return a}var nt={get:Bn,set:Qn,delete:Wn,generateDefaultCacheControlHeader:Nt,isStale:Kn};function Ne(e){return `https://shopify.dev/?${e}`}function Yn(e){return e||Ae()}async function no(e,t){if(!e)return;let r=Ne(t),o=new Request(r),n=await nt.get(e,o);if(!n)return;let a=await n.text();try{return [te(a),n]}catch{return [a,n]}}async function ao(e,t,r,o){if(!e)return;let n=Ne(t),a=new Request(n),s=new Response(JSON.stringify(r));await nt.set(e,a,s,Yn(o));}function so(e,t){return nt.isStale(new Request(Ne(e)),t)}function io(e){let t=Array.isArray(e)?e:[e],r="";for(let o of t)o!=null&&(typeof o=="object"?r+=JSON.stringify(o):r+=o.toString());return encodeURIComponent(r)}var Mt=new Set;async function at(e,t,{strategy:r=le(),cacheInstance:o,shouldCacheResult:n=()=>true,waitUntil:a,debugInfo:s}){let i=io([...typeof e=="string"?[e]:e]),y=f=>{({displayName:f.displayName,url:f.response?.url,responseInit:{status:f.response?.status||0,statusText:f.response?.statusText||"",headers:Array.from(f.response?.headers.entries()||[])}});},g=void 0;if(!o||!r||r.mode===_t){let f=await t({addDebugData:y});return f}let p=f=>ao(o,i,{value:f,debugInfo:void 0},r),l=await no(o,i);if(l&&typeof l[0]!="string"){let[{value:f,debugInfo:R},h]=l;let S=so(i,h)?"STALE":"HIT";if(!Mt.has(i)&&S==="STALE"){Mt.add(i);let C=Promise.resolve().then(async()=>{let I=Date.now();try{let v=await t({addDebugData:y});n(v)&&(await p(v),g?.({result:v,cacheStatus:"PUT",overrideStartTime:I}));}catch(v){v.message&&(v.message="SWR in sub-request failed: "+v.message),console.error(v);}finally{Mt.delete(i);}});a?.(C);}return f}let P=await t({addDebugData:y});if(n(P)){let f=Promise.resolve().then(async()=>{await p(P);});a?.(f);}return P}var zn=["set-cookie","server-timing"];function co(e,t){return [e,{status:t.status,statusText:t.statusText,headers:[...t.headers].filter(([r])=>!zn.includes(r.toLowerCase()))}]}function uo([e,t]){return [e,new Response(e,t)]}async function st(e,t,{cacheInstance:r,cache:o,cacheKey:n=[e,t],shouldCacheResponse:a,waitUntil:s,debugInfo:c,streamConfig:i,onRawHeaders:u}){return !o&&(!t.method||t.method==="GET")&&(o=le()),at(n,async()=>{if(i){let m=null,p=await createGraphQLClient({url:e,customFetchApi:async(f,R)=>(m=await fetch(f,R),u?.(m.headers),m),headers:t.headers}).requestStream(i.query,{variables:i.variables}),l,P;for await(let f of p){let{data:R,errors:h}=f;l=R,P=h?.graphQLErrors??h;}return m?.ok?co({data:l,errors:P},m):m}let d=await fetch(e,t);if(u?.(d.headers),!d.ok)return d;let y=await d.text().catch(()=>"");try{y&&(y=te(y));}catch{}return co(y,d)},{cacheInstance:r,waitUntil:s,strategy:o??null,debugInfo:c,shouldCacheResult:d=>"ok"in d?!1:a(...uo(d))}).then(d=>"ok"in d?[null,d]:uo(d))}function Xn(e){let{cache:t,waitUntil:r,request:o}=e;return {run:({cacheKey:n,cacheStrategy:a,shouldCacheResult:s},c)=>at(n,c,{shouldCacheResult:s,strategy:a,cacheInstance:t,waitUntil:r,debugInfo:{...ce(o),stackInfo:J?.()}}),fetch:(n,a,s)=>st(n,a??{},{waitUntil:r,cacheKey:[n,a],cacheInstance:t,debugInfo:{url:n,...ce(o),stackInfo:J?.(),displayName:s?.displayName},cache:s.cacheStrategy,...s}).then(([c,i])=>({data:c,response:i}))}}var Ft=class{#e;constructor(){this.#e=new Map;}add(t){throw new Error("Method not implemented. Use `put` instead.")}addAll(t){throw new Error("Method not implemented. Use `put` instead.")}matchAll(t,r){throw new Error("Method not implemented. Use `match` instead.")}async put(t,r){if(t.method!=="GET")throw new TypeError("Cannot cache response to non-GET request.");if(r.status===206)throw new TypeError("Cannot cache response to a range request (206 Partial Content).");if(r.headers.get("vary")?.includes("*"))throw new TypeError("Cannot cache response with 'Vary: *' header.");this.#e.set(t.url,{body:new Uint8Array(await r.arrayBuffer()),status:r.status,headers:[...r.headers],timestamp:Date.now()});}async match(t){if(t.method!=="GET")return;let r=this.#e.get(t.url);if(!r)return;let{body:o,timestamp:n,...a}=r,s=new Headers(a.headers),c=s.get("cache-control")||s.get("real-cache-control")||"",i=parseInt(c.match(/max-age=(\d+)/)?.[1]||"0",10),u=parseInt(c.match(/stale-while-revalidate=(\d+)/)?.[1]||"0",10),d=(Date.now()-n)/1e3;if(d>i+u){this.#e.delete(t.url);return}let m=d>i;return s.set("cache",m?"STALE":"HIT"),s.set("date",new Date(n).toUTCString()),new Response(o,{status:a.status??200,headers:s})}async delete(t){return this.#e.has(t.url)?(this.#e.delete(t.url),true):false}keys(t){let r=[];for(let o of this.#e.keys())(!t||t.url===o)&&r.push(new Request(o));return Promise.resolve(r)}};var po="cartFormInput";function re({children:e,action:t,inputs:r,route:o,fetcherKey:n}){let a=useFetcher({key:n});return jsxs(a.Form,{action:o||"",method:"post",children:[(t||r)&&jsx("input",{type:"hidden",name:po,value:JSON.stringify({action:t,inputs:r})}),typeof e=="function"?e(a):e]})}re.INPUT_NAME=po;re.ACTIONS={AttributesUpdateInput:"AttributesUpdateInput",BuyerIdentityUpdate:"BuyerIdentityUpdate",Create:"Create",DiscountCodesUpdate:"DiscountCodesUpdate",GiftCardCodesUpdate:"GiftCardCodesUpdate",GiftCardCodesAdd:"GiftCardCodesAdd",GiftCardCodesRemove:"GiftCardCodesRemove",LinesAdd:"LinesAdd",LinesRemove:"LinesRemove",LinesUpdate:"LinesUpdate",NoteUpdate:"NoteUpdate",SelectedDeliveryOptionsUpdate:"SelectedDeliveryOptionsUpdate",MetafieldsSet:"MetafieldsSet",MetafieldDelete:"MetafieldDelete",DeliveryAddressesAdd:"DeliveryAddressesAdd",DeliveryAddressesUpdate:"DeliveryAddressesUpdate",DeliveryAddressesRemove:"DeliveryAddressesRemove",DeliveryAddressesReplace:"DeliveryAddressesReplace"};function ea(e){let t={};for(let s of e.entries()){let c=s[0],i=e.getAll(c);t[c]=i.length>1?i:s[1],t[c]==="on"?t[c]=true:t[c]==="off"&&(t[c]=false);}let{cartFormInput:r,...o}=t,{action:n,inputs:a}=r?JSON.parse(String(r)):{};return {action:n,inputs:{...a,...o}}}re.getFormInput=ea;var Ht=e=>{let t=parse(Ot(e,"Cookie")||"");return ()=>t.cart?`gid://shopify/Cart/${t.cart}`:void 0};var qt=e=>t=>{let r=new Headers;return r.append("Set-Cookie",stringify("cart",t.split("/").pop()||"",{path:"/",...e})),r};function it(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`weak-${Math.random().toString(16).substring(2)}`}var Me="2026.4.1";function Se(e){return e.replace(/\s*#.*$/gm,"").replace(/\s+/gm," ").trim()}var aa=/(^|}\s)query[\s({]/im,sa=/(^|}\s)mutation[\s({]/im;function ct(e,t){if(!aa.test(e))throw new Error(`[h2:error:${t}] Can only execute queries`)}function ut(e,t){if(!sa.test(e))throw new Error(`[h2:error:${t}] Can only execute mutations`)}var ye=class extends Error{locations;path;extensions;constructor(t,r={}){let n=(r.clientOperation?`[h2:error:${r.clientOperation}] `:"")+t+(r.requestId?` - Request ID: ${r.requestId}`:"");super(n),this.name="GraphQLError",this.extensions=r.extensions,this.locations=r.locations,this.path=r.path,this.stack=r.stack||void 0;try{this.cause=JSON.stringify({...typeof r.cause=="object"?r.cause:{},requestId:r.requestId});}catch{r.cause&&(this.cause=r.cause);}}get[Symbol.toStringTag](){return this.name}toString(){let t=`${this.name}: ${this.message}`;if(this.path)try{t+=` | path: ${JSON.stringify(this.path)}`;}catch{}if(this.extensions)try{t+=` | extensions: ${JSON.stringify(this.extensions)}`;}catch{}return t+=`
23
+ `+s};return e.then(n=>{if(n?.errors&&Array.isArray(n.errors)){let a=typeof t.logErrors=="function"?t.logErrors:()=>t.logErrors??false;n.errors.forEach(s=>{s&&(s.stack=o(s.message,s.name),a(s)&&console.error(s));});}return n}).catch(n=>{throw n&&(n.stack=o(n.message,n.name)),n})}var J=void 0;var rt="public",$n="private",_t="no-store",oo={maxAge:"max-age",staleWhileRevalidate:"stale-while-revalidate",sMaxAge:"s-maxage",staleIfError:"stale-if-error"};function Ve(e){let t=[];return Object.keys(e).forEach(r=>{r==="mode"?t.push(e[r]):oo[r]&&t.push(`${oo[r]}=${e[r]}`);}),t.join(", ")}function Ut(){return {mode:_t}}function Lt(e){if(e?.mode&&e?.mode!==rt&&e?.mode!==$n)throw Error("'mode' must be either 'public' or 'private'")}function le(e){return Lt(e),{mode:rt,maxAge:1,staleWhileRevalidate:9,...e}}function kt(e){return Lt(e),{mode:rt,maxAge:3600,staleWhileRevalidate:82800,...e}}function Ae(e){return Lt(e),{mode:rt,maxAge:1,staleWhileRevalidate:86399,...e}}function Vt(e){return e}function te(e){return String(e).includes("__proto__")?JSON.parse(e,Gn):JSON.parse(e)}function Gn(e,t){if(e!=="__proto__")return t}function ot(e,t){return e&&t?{...e,...t}:e||Ae()}function Nt(e){return Ve(ot(e))}async function Bn(e,t){if(!e)return;let r=await e.match(t);if(!r){return}return r}async function Qn(e,t,r,o){if(!e)return;let n=ot(o),a=Nt(ot(n,{maxAge:(n.maxAge||0)+(n.staleWhileRevalidate||0)})),s=Nt(ot(n));r.headers.set("cache-control",a),r.headers.set("real-cache-control",s),r.headers.set("cache-put-date",String(Date.now())),await e.put(t,r);}async function Wn(e,t){e&&await e.delete(t);}function jn(e,t){let r=e.headers.get("real-cache-control"),o=0;if(r){let a=r.match(/max-age=(\d*)/);a&&a.length>1&&(o=parseFloat(a[1]));}return [(Date.now()-Number(t))/1e3,o]}function Kn(e,t){let r=t.headers.get("cache-put-date");if(!r)return false;let[o,n]=jn(t,r),a=o>n;return a}var nt={get:Bn,set:Qn,delete:Wn,generateDefaultCacheControlHeader:Nt,isStale:Kn};function Ne(e){return `https://shopify.dev/?${e}`}function Yn(e){return e||Ae()}async function no(e,t){if(!e)return;let r=Ne(t),o=new Request(r),n=await nt.get(e,o);if(!n)return;let a=await n.text();try{return [te(a),n]}catch{return [a,n]}}async function ao(e,t,r,o){if(!e)return;let n=Ne(t),a=new Request(n),s=new Response(JSON.stringify(r));await nt.set(e,a,s,Yn(o));}function so(e,t){return nt.isStale(new Request(Ne(e)),t)}function io(e){let t=Array.isArray(e)?e:[e],r="";for(let o of t)o!=null&&(typeof o=="object"?r+=JSON.stringify(o):r+=o.toString());return encodeURIComponent(r)}var Mt=new Set;async function at(e,t,{strategy:r=le(),cacheInstance:o,shouldCacheResult:n=()=>true,waitUntil:a,debugInfo:s}){let i=io([...typeof e=="string"?[e]:e]),y=f=>{({displayName:f.displayName,url:f.response?.url,responseInit:{status:f.response?.status||0,statusText:f.response?.statusText||"",headers:Array.from(f.response?.headers.entries()||[])}});},g=void 0;if(!o||!r||r.mode===_t){let f=await t({addDebugData:y});return f}let p=f=>ao(o,i,{value:f,debugInfo:void 0},r),l=await no(o,i);if(l&&typeof l[0]!="string"){let[{value:f,debugInfo:R},h]=l;let S=so(i,h)?"STALE":"HIT";if(!Mt.has(i)&&S==="STALE"){Mt.add(i);let C=Promise.resolve().then(async()=>{let I=Date.now();try{let v=await t({addDebugData:y});n(v)&&(await p(v),g?.({result:v,cacheStatus:"PUT",overrideStartTime:I}));}catch(v){v.message&&(v.message="SWR in sub-request failed: "+v.message),console.error(v);}finally{Mt.delete(i);}});a?.(C);}return f}let P=await t({addDebugData:y});if(n(P)){let f=Promise.resolve().then(async()=>{await p(P);});a?.(f);}return P}var zn=["set-cookie","server-timing"];function co(e,t){return [e,{status:t.status,statusText:t.statusText,headers:[...t.headers].filter(([r])=>!zn.includes(r.toLowerCase()))}]}function uo([e,t]){return [e,new Response(e,t)]}async function st(e,t,{cacheInstance:r,cache:o,cacheKey:n=[e,t],shouldCacheResponse:a,waitUntil:s,debugInfo:c,streamConfig:i,onRawHeaders:u}){return !o&&(!t.method||t.method==="GET")&&(o=le()),at(n,async()=>{if(i){let m=null,p=await createGraphQLClient({url:e,customFetchApi:async(f,R)=>(m=await fetch(f,R),u?.(m.headers),m),headers:t.headers}).requestStream(i.query,{variables:i.variables}),l,P;for await(let f of p){let{data:R,errors:h}=f;l=R,P=h?.graphQLErrors??h;}return m?.ok?co({data:l,errors:P},m):m}let d=await fetch(e,t);if(u?.(d.headers),!d.ok)return d;let y=await d.text().catch(()=>"");try{y&&(y=te(y));}catch{}return co(y,d)},{cacheInstance:r,waitUntil:s,strategy:o??null,debugInfo:c,shouldCacheResult:d=>"ok"in d?!1:a(...uo(d))}).then(d=>"ok"in d?[null,d]:uo(d))}function Xn(e){let{cache:t,waitUntil:r,request:o}=e;return {run:({cacheKey:n,cacheStrategy:a,shouldCacheResult:s},c)=>at(n,c,{shouldCacheResult:s,strategy:a,cacheInstance:t,waitUntil:r,debugInfo:{...ce(o),stackInfo:J?.()}}),fetch:(n,a,s)=>st(n,a??{},{waitUntil:r,cacheKey:[n,a],cacheInstance:t,debugInfo:{url:n,...ce(o),stackInfo:J?.(),displayName:s?.displayName},cache:s.cacheStrategy,...s}).then(([c,i])=>({data:c,response:i}))}}var Ft=class{#e;constructor(){this.#e=new Map;}add(t){throw new Error("Method not implemented. Use `put` instead.")}addAll(t){throw new Error("Method not implemented. Use `put` instead.")}matchAll(t,r){throw new Error("Method not implemented. Use `match` instead.")}async put(t,r){if(t.method!=="GET")throw new TypeError("Cannot cache response to non-GET request.");if(r.status===206)throw new TypeError("Cannot cache response to a range request (206 Partial Content).");if(r.headers.get("vary")?.includes("*"))throw new TypeError("Cannot cache response with 'Vary: *' header.");this.#e.set(t.url,{body:new Uint8Array(await r.arrayBuffer()),status:r.status,headers:[...r.headers],timestamp:Date.now()});}async match(t){if(t.method!=="GET")return;let r=this.#e.get(t.url);if(!r)return;let{body:o,timestamp:n,...a}=r,s=new Headers(a.headers),c=s.get("cache-control")||s.get("real-cache-control")||"",i=parseInt(c.match(/max-age=(\d+)/)?.[1]||"0",10),u=parseInt(c.match(/stale-while-revalidate=(\d+)/)?.[1]||"0",10),d=(Date.now()-n)/1e3;if(d>i+u){this.#e.delete(t.url);return}let m=d>i;return s.set("cache",m?"STALE":"HIT"),s.set("date",new Date(n).toUTCString()),new Response(o,{status:a.status??200,headers:s})}async delete(t){return this.#e.has(t.url)?(this.#e.delete(t.url),true):false}keys(t){let r=[];for(let o of this.#e.keys())(!t||t.url===o)&&r.push(new Request(o));return Promise.resolve(r)}};var po="cartFormInput";function re({children:e,action:t,inputs:r,route:o,fetcherKey:n}){let a=useFetcher({key:n});return jsxs(a.Form,{action:o||"",method:"post",children:[(t||r)&&jsx("input",{type:"hidden",name:po,value:JSON.stringify({action:t,inputs:r})}),typeof e=="function"?e(a):e]})}re.INPUT_NAME=po;re.ACTIONS={AttributesUpdateInput:"AttributesUpdateInput",BuyerIdentityUpdate:"BuyerIdentityUpdate",Create:"Create",DiscountCodesUpdate:"DiscountCodesUpdate",GiftCardCodesUpdate:"GiftCardCodesUpdate",GiftCardCodesAdd:"GiftCardCodesAdd",GiftCardCodesRemove:"GiftCardCodesRemove",LinesAdd:"LinesAdd",LinesRemove:"LinesRemove",LinesUpdate:"LinesUpdate",NoteUpdate:"NoteUpdate",SelectedDeliveryOptionsUpdate:"SelectedDeliveryOptionsUpdate",MetafieldsSet:"MetafieldsSet",MetafieldDelete:"MetafieldDelete",DeliveryAddressesAdd:"DeliveryAddressesAdd",DeliveryAddressesUpdate:"DeliveryAddressesUpdate",DeliveryAddressesRemove:"DeliveryAddressesRemove",DeliveryAddressesReplace:"DeliveryAddressesReplace"};function ea(e){let t={};for(let s of e.entries()){let c=s[0],i=e.getAll(c);t[c]=i.length>1?i:s[1],t[c]==="on"?t[c]=true:t[c]==="off"&&(t[c]=false);}let{cartFormInput:r,...o}=t,{action:n,inputs:a}=r?JSON.parse(String(r)):{};return {action:n,inputs:{...a,...o}}}re.getFormInput=ea;var Ht=e=>{let t=parse(Ot(e,"Cookie")||"");return ()=>t.cart?`gid://shopify/Cart/${t.cart}`:void 0};var qt=e=>t=>{let r=new Headers;return r.append("Set-Cookie",stringify("cart",t.split("/").pop()||"",{path:"/",...e})),r};function it(){return typeof crypto<"u"&&crypto.randomUUID?crypto.randomUUID():`weak-${Math.random().toString(16).substring(2)}`}var Me="2026.4.2";function Se(e){return e.replace(/\s*#.*$/gm,"").replace(/\s+/gm," ").trim()}var aa=/(^|}\s)query[\s({]/im,sa=/(^|}\s)mutation[\s({]/im;function ct(e,t){if(!aa.test(e))throw new Error(`[h2:error:${t}] Can only execute queries`)}function ut(e,t){if(!sa.test(e))throw new Error(`[h2:error:${t}] Can only execute mutations`)}var ye=class extends Error{locations;path;extensions;constructor(t,r={}){let n=(r.clientOperation?`[h2:error:${r.clientOperation}] `:"")+t+(r.requestId?` - Request ID: ${r.requestId}`:"");super(n),this.name="GraphQLError",this.extensions=r.extensions,this.locations=r.locations,this.path=r.path,this.stack=r.stack||void 0;try{this.cause=JSON.stringify({...typeof r.cause=="object"?r.cause:{},requestId:r.requestId});}catch{r.cause&&(this.cause=r.cause);}}get[Symbol.toStringTag](){return this.name}toString(){let t=`${this.name}: ${this.message}`;if(this.path)try{t+=` | path: ${JSON.stringify(this.path)}`;}catch{}if(this.extensions)try{t+=` | extensions: ${JSON.stringify(this.extensions)}`;}catch{}return t+=`
24
24
  `,this.stack&&(t+=`${this.stack.slice(this.stack.indexOf(`
25
25
  `)+1)}
26
26
  `),t}toJSON(){return {name:"Error",message:""}}};function Fe({url:e,response:t,errors:r,type:o,query:n,queryVariables:a,ErrorConstructor:s=Error,client:c="storefront"}){let i=(typeof r=="string"?r:r?.map?.(d=>d.message).join(`