@occluze/tether 0.7.0 → 0.7.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.
Files changed (139) hide show
  1. package/README.md +51 -109
  2. package/dist/esm/astro.js +1 -1
  3. package/dist/esm/chunks/{account-UIPWJQ3Y.js → account-W4FBRKXA.js} +1 -1
  4. package/dist/esm/chunks/{account-pages-6ROA6Y4V.js → account-pages-IM3OQTOP.js} +1 -1
  5. package/dist/esm/chunks/analytics-QDVOLZY3.js +1 -0
  6. package/dist/esm/chunks/{chunk-T44MUL4Y.js → chunk-AUVAN3KZ.js} +1 -1
  7. package/dist/esm/chunks/chunk-BMDYNMRC.js +1 -0
  8. package/dist/esm/chunks/chunk-CUL66KRA.js +1 -0
  9. package/dist/esm/chunks/{chunk-6OZJCAGZ.js → chunk-CVNRODH3.js} +1 -1
  10. package/dist/esm/chunks/{chunk-5Z5O3767.js → chunk-CXHPBT7N.js} +1 -1
  11. package/dist/esm/chunks/chunk-GF6JTI65.js +1 -0
  12. package/dist/esm/chunks/chunk-MRSDJPBC.js +1 -0
  13. package/dist/esm/chunks/chunk-NYDZPTLP.js +1 -0
  14. package/dist/esm/chunks/chunk-QDHLXXAZ.js +1 -0
  15. package/dist/esm/chunks/{chunk-4GCXM764.js → chunk-QUECUXHD.js} +1 -1
  16. package/dist/esm/chunks/chunk-RJY76ESL.js +1 -0
  17. package/dist/esm/chunks/chunk-RPI5C3EJ.js +1 -0
  18. package/dist/esm/chunks/{chunk-BFTZR4OB.js → chunk-YC4JXWRG.js} +2 -2
  19. package/dist/esm/chunks/{diagnose-3FEKRIEK.js → diagnose-3XHPZZNP.js} +1 -1
  20. package/dist/esm/chunks/extras-C724KKG6.js +1 -0
  21. package/dist/esm/chunks/{markets-ui-FD6NI2OG.js → markets-ui-WBWWQAGU.js} +1 -1
  22. package/dist/esm/chunks/{search-UJ73YBQ5.js → search-5NFIZBPJ.js} +1 -1
  23. package/dist/esm/index.js +1 -1
  24. package/dist/esm/server.js +2 -2
  25. package/dist/tether.account-pages.js +13 -3
  26. package/dist/tether.account-pages.min.js +1 -1
  27. package/dist/tether.account.js +13 -3
  28. package/dist/tether.account.min.js +1 -1
  29. package/dist/tether.analytics.js +18 -3
  30. package/dist/tether.analytics.min.js +1 -1
  31. package/dist/tether.diagnose.js +20 -5
  32. package/dist/tether.diagnose.min.js +2 -2
  33. package/dist/tether.extras.js +52 -28
  34. package/dist/tether.extras.min.js +1 -1
  35. package/dist/tether.js +353 -288
  36. package/dist/tether.markets.js +31 -5
  37. package/dist/tether.markets.min.js +1 -1
  38. package/dist/tether.min.js +2 -2
  39. package/dist/tether.min.js.map +4 -4
  40. package/dist/tether.search.js +18 -3
  41. package/dist/tether.search.min.js +1 -1
  42. package/dist/types/server/src/shared/cart-id.d.ts +2 -0
  43. package/dist/types/src/cart/mutations.d.ts +6 -0
  44. package/dist/types/src/cart/store.d.ts +5 -2
  45. package/dist/types/src/cart.d.ts +3 -2
  46. package/dist/types/src/client.d.ts +61 -22
  47. package/dist/types/src/config.d.ts +6 -1
  48. package/dist/types/src/index.d.ts +2 -2
  49. package/dist/types/src/markets.d.ts +9 -2
  50. package/dist/types/src/product-shape.d.ts +3 -1
  51. package/dist/types/src/uri.d.ts +6 -0
  52. package/package.json +54 -6
  53. package/dist/esm/chunks/analytics-2V632IRV.js +0 -1
  54. package/dist/esm/chunks/chunk-56FCLJJD.js +0 -1
  55. package/dist/esm/chunks/chunk-A5SYCVQM.js +0 -1
  56. package/dist/esm/chunks/chunk-BA4LQJJQ.js +0 -1
  57. package/dist/esm/chunks/chunk-C5JYQCWH.js +0 -1
  58. package/dist/esm/chunks/chunk-E5YO6274.js +0 -1
  59. package/dist/esm/chunks/chunk-MPDWM2NN.js +0 -1
  60. package/dist/esm/chunks/chunk-YLUULATY.js +0 -1
  61. package/dist/esm/chunks/extras-6POFBNOP.js +0 -1
  62. package/src/account/addresses-view.ts +0 -58
  63. package/src/account/answers.ts +0 -79
  64. package/src/account/markup.ts +0 -36
  65. package/src/account/operations.ts +0 -145
  66. package/src/account/order-lines.ts +0 -75
  67. package/src/account/order-list.ts +0 -107
  68. package/src/account/order-page.ts +0 -137
  69. package/src/account/page-answers.ts +0 -317
  70. package/src/account/page-events.ts +0 -253
  71. package/src/account/server-client.ts +0 -183
  72. package/src/account/subscriptions-view.ts +0 -115
  73. package/src/account-api.ts +0 -98
  74. package/src/account-marks.ts +0 -35
  75. package/src/account-pages.ts +0 -81
  76. package/src/account.ts +0 -284
  77. package/src/amounts.ts +0 -64
  78. package/src/analytics-shopify.ts +0 -246
  79. package/src/analytics.ts +0 -315
  80. package/src/api-version.ts +0 -79
  81. package/src/astro.ts +0 -272
  82. package/src/cart/cart-shape.ts +0 -25
  83. package/src/cart/checkout.ts +0 -101
  84. package/src/cart/drawer.ts +0 -125
  85. package/src/cart/mutations.ts +0 -237
  86. package/src/cart/render.ts +0 -266
  87. package/src/cart/store.ts +0 -279
  88. package/src/cart.ts +0 -345
  89. package/src/client.ts +0 -391
  90. package/src/collection.ts +0 -175
  91. package/src/config-sections.ts +0 -284
  92. package/src/config.ts +0 -480
  93. package/src/controls/cart-controls.ts +0 -123
  94. package/src/controls/discount.ts +0 -75
  95. package/src/controls/extras.ts +0 -54
  96. package/src/controls/navigation.ts +0 -77
  97. package/src/diagnose-markup.ts +0 -298
  98. package/src/diagnose.ts +0 -294
  99. package/src/dom.ts +0 -268
  100. package/src/extras.ts +0 -136
  101. package/src/fragments.ts +0 -261
  102. package/src/globals.d.ts +0 -15
  103. package/src/images.ts +0 -91
  104. package/src/index.ts +0 -415
  105. package/src/initial.ts +0 -101
  106. package/src/lazy-iife.ts +0 -197
  107. package/src/lazy.ts +0 -42
  108. package/src/loader.ts +0 -363
  109. package/src/market-codes.ts +0 -6
  110. package/src/markets-ui.ts +0 -227
  111. package/src/markets.ts +0 -246
  112. package/src/markup.ts +0 -127
  113. package/src/mounting.ts +0 -264
  114. package/src/page-market.ts +0 -110
  115. package/src/part-integrity.ts +0 -7
  116. package/src/parts/account-pages.ts +0 -7
  117. package/src/parts/account.ts +0 -7
  118. package/src/parts/analytics.ts +0 -7
  119. package/src/parts/diagnose.ts +0 -7
  120. package/src/parts/extras.ts +0 -7
  121. package/src/parts/markets.ts +0 -7
  122. package/src/parts/search.ts +0 -7
  123. package/src/presets/barba.ts +0 -194
  124. package/src/product-events.ts +0 -115
  125. package/src/product-render.ts +0 -218
  126. package/src/product-shape.ts +0 -49
  127. package/src/product-state.ts +0 -318
  128. package/src/product.ts +0 -308
  129. package/src/repeaters.ts +0 -161
  130. package/src/search.ts +0 -305
  131. package/src/selling-plans.ts +0 -145
  132. package/src/server.ts +0 -211
  133. package/src/shopify-values.ts +0 -91
  134. package/src/status.ts +0 -106
  135. package/src/storage.ts +0 -34
  136. package/src/store-html.ts +0 -359
  137. package/src/storefront/catalog.ts +0 -196
  138. package/src/storefront/json-ld.ts +0 -144
  139. package/src/variant-render.ts +0 -139
@@ -1 +1 @@
1
- (()=>{var j=Object.defineProperty;var U=(t,e)=>{for(var n in e)j(t,n,{get:e[n],enumerable:!0})};var _={};U(_,{startAnalytics:()=>mt});var $=window.Tether.__core["config.ts"],[a,ht,w,gt,vt,l,bt]=$;var G=window.Tether.__core["dom.ts"],[C,_t,wt,Ct,Et,kt,St,At,Pt,E,xt,Lt,It,Nt,p,Rt,Vt,Dt]=G;var W=window.Tether.__core["cart.ts"],[g]=W;var Y=window.Tether.__core["product.ts"],[k]=Y;var H=window.Tether.__core["client.ts"],[Ot,S,Ft,A,jt]=H;var J=500,P={"default-banner":"https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js",other:"https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js"},z="https://cdn.shopify.com/storefront/analytics/shopify.js",L=()=>window,y=()=>L().Shopify;function I(){let t=a.analytics?.shopify;return typeof t=="object"?t:{}}function N(){try{let t=y()?.customerPrivacy;return t?.consentStatus==="loaded"&&t.currentVisitorConsent?.()?.analytics!=="no"&&!!t.analyticsProcessingAllowed?.()}catch{return!1}}function K(t){let e=`hydrogen:${t}`;return{getTrackingValues:()=>{let n=N()?y()?.customerPrivacy?.__internal:void 0;return{uniqueToken:n?.uniqueToken?.({generateFallback:!0,tag:e})??"",visitToken:n?.visitToken?.({generateFallback:!0,tag:e})??""}}}}var X=t=>(e,n)=>{let i=t.subscribers.get(e)??new Set;return t.subscribers.set(e,i),i.add(n),()=>t.subscribers.get(e)?.delete(n)};function Z(t){let e=[],n=[],i={shop:{shopId:t,channel:"headless"},consent:{mode:I().consent||"no-banner"}},o=()=>{if(N())for(let r of e)for(;r.next<n.length;r.next+=1){let s=n[r.next];s&&Q(r,s)}},c={getConfig:()=>i,publish(r,s={}){if(n.push({event:r,payload:{shop:i.shop,url:window.location.href,...s}}),n.length>J){n.shift();for(let d of e)d.next=Math.max(0,d.next-1)}o()},addDestination(r){let s={name:r.name,next:0,subscribers:new Map,context:K(r.name)};return Promise.resolve(r.setup?.({subscribe:X(s),getConfig:c.getConfig})).then(()=>{e.push(s),o()}).catch(d=>{l(d,`analytics ${r.name}`)}),()=>{let d=e.indexOf(s);d>=0&&e.splice(d,1)}}};return document.addEventListener("consentTrackingApiLoaded",o),document.addEventListener("visitorConsentCollected",o),c}function Q(t,{event:e,payload:n}){t.subscribers.get(e)?.forEach(i=>{try{i(n,t.context)}catch(o){l(o,`analytics ${t.name}`)}})}function x(t){let e=document.createElement("script");e.src=t,e.async=!0,document.head.appendChild(e)}async function R(t){let e=y();if(e?.analytics)return e.analytics;let n=await S("query TetherShopId { shop { id } }",{},A({shop:{id:"string"}}),{context:!1}),i=y()??{};L().Shopify=i,i.country=a.country??"US";let[o="en"]=(a.locale||"en").split("-");i.locale=o.toLowerCase(),i.shop=a.domain,i.routes={root:"/",match:()=>({pageTemplateName:t()?"product":"page"}),...i.routes};let{proxy:c,consent:r}=I();i.customerPrivacy={...i.customerPrivacy,config:c?{isHeadless:!0,asyncConsent:!0,asyncVisitorState:!0,consentDomain:window.location.host}:{isHeadless:!0,storefrontAccessToken:a.token,checkoutRootDomain:a.domain}};let s=Z(n.shop.id);return i.analytics=s,x(r==="default-banner"?P["default-banner"]:P.other),x(z),w("shopify analytics ready",n.shop.id),s}var tt="Default Title",V=100,et=200,nt=t=>t?parseFloat(t.amount):0,D=t=>(t??"").split("/").pop()??"";function T(t,e,n=1,i){let o={item_id:e?.sku||D(e?.id)||D(t.id),item_name:t.title,item_variant:e?.title===tt?void 0:e?.title,item_brand:t.vendor||void 0,item_category:t.productType||void 0,price:nt(e?.price??t.priceRange?.minVariantPrice),quantity:n};return i!=null&&(o.index=i),o}var h=(t,e=t.quantity)=>T(t.merchandise.product,t.merchandise,e);function f(t){let e=t.reduce((n,i)=>n+i.price*(i.quantity||1),0);return Math.round(e*V)/V}var it=(t,e,n=1)=>({id:t.id,title:t.title,price:e.price,vendor:t.vendor||"",variantId:e.id,variantTitle:e.title,quantity:n,sku:e.sku||void 0,productType:t.productType||void 0}),M=t=>({id:t.id,quantity:t.quantity,merchandise:{id:t.merchandise.id,title:t.merchandise.title,price:t.merchandise.price,sku:t.merchandise.sku,product:{id:t.merchandise.product.id,title:t.merchandise.product.title,vendor:t.merchandise.product.vendor||"",handle:t.merchandise.product.handle}}});function ot(){let{dataLayer:t}=a.analytics??{},e=typeof t=="string"?t:"dataLayer",n=Reflect.get(window,e);if(Array.isArray(n))return n;let i=[];return Reflect.set(window,e,i),i}function rt(t,e){let n=ot();if(!e){n.push({event:t});return}n.push({ecommerce:null}),n.push({event:t,ecommerce:e})}var m=null,v=null,B=null,b=new WeakSet;function u(t,e,n,i){a.analytics?.dataLayer&&rt(t,e),m&&n&&m.publish(n,i);try{a.analytics?.onEvent?.(t,e)}catch(o){l(o,"analytics onEvent")}}function O(){let t=document.querySelector(p("product"));return!t||t.closest(`${p("collection")},${p("products")},${p("recommendations")}`)?null:k.get(t)??null}function st({product:t,scope:e}){if(b.has(e.root)||O()!==e)return;b.add(e.root);let n=e.variant??t.variants.nodes[0],i=[T(t,n)],o=n?[it(t,n)]:[];u("view_item",{currency:n?.price.currencyCode,value:f(i),items:i},"product_viewed",{products:o})}function at({products:t,collection:e}){let n=t.slice(0,et).map((o,c)=>T(o,o.variants.nodes[0],1,c)),i={item_list_id:e?.handle||"products",item_list_name:e?.title||"Products"};if(!e){u("view_item_list",{...i,items:n});return}u("view_item_list",{...i,items:n},"collection_viewed",{collection:{id:e.id,handle:e.handle}})}function ct(t,e,n){let i=t?.cost.totalAmount.currencyCode;e.forEach((o,c)=>{let r=n.get(c),s=o.quantity-(r?.quantity??0);if(s<=0)return;let d=[h(o,s)];u("add_to_cart",{currency:i,value:f(d),items:d},"product_added_to_cart",{cart:t,prevCart:B,currentLine:M(o),prevLine:r?M(r):void 0})}),n.forEach((o,c)=>{let r=o.quantity-(e.get(c)?.quantity??0);if(r<=0)return;let s=[h(o,r)];u("remove_from_cart",{currency:i,value:f(s),items:s})})}function dt({cart:t,reason:e}){let n=new Map((t?.lines.nodes??[]).map(i=>[i.merchandise.id,i]));v&&e!=="load"&&e!=="pending"&&ct(t,n,v),v=n,B=t}function ut(){let t=g.lines.map(e=>h(e));u("view_cart",{currency:g.state?.cost.totalAmount.currencyCode,value:f(t),items:t})}function lt({cart:t}){if(!t)return;let e=t.lines.nodes.map(i=>h(i)),n=t.discountCodes.filter(i=>i.applicable).map(i=>i.code);u("begin_checkout",{currency:t.cost.totalAmount.currencyCode,value:f(e),coupon:n.join(",")||void 0,items:e})}var pt={"product-ready":st,"list-ready":at,"cart-updated":dt,"cart-toggled":({open:t})=>{t&&ut()},checkout:lt,search:({term:t})=>{t&&u("search",{search_term:t},"search_viewed",{searchTerm:t})}};function ft(t,e){pt[e](t.detail)}function q(t){if(t.type==="astro:page-load"){b=new WeakSet,m?.publish("page_viewed",{});return}C.forEach(e=>{E(t,e)&&ft(t,e)})}async function mt(t){a.analytics?.shopify&&(m=await R(()=>O()!=null).catch(e=>(l(e,"shopify analytics"),null))),m?.publish("page_viewed",{}),t.splice(0).forEach(q),t.push=(...e)=>(e.forEach(q),t.length)}var{Tether:F}=window;if(!F)throw new Error("tether.analytics.js runs after the Tether script, which loads it");F.__parts.analytics=_;})();
1
+ (()=>{var U=Object.defineProperty;var $=(t,n)=>{for(var e in n)U(t,e,{get:n[e],enumerable:!0})};var k={};$(k,{startAnalytics:()=>yt});var G=window.Tether.__core["config.ts"],[a,bt,_,vt,wt,l,Tt]=G;var W=window.Tether.__core["dom.ts"],[C,_t,Ct,Et,xt,At,Pt,St,Lt,E,Nt,It,Rt,Vt,p,Dt,Mt,qt]=W;var Y=window.Tether.__core["cart.ts"],[b]=Y;var H=window.Tether.__core["product.ts"],[x]=H;var J=window.Tether.__core["client.ts"],[jt,A,Ut,P,$t]=J;var Z=500,S={"default-banner":"https://cdn.shopify.com/shopifycloud/privacy-banner/storefront-banner.js",other:"https://cdn.shopify.com/shopifycloud/consent-tracking-api/v0.2/consent-tracking-api.js"},z="https://cdn.shopify.com/storefront/analytics/shopify.js",N=()=>window,y=()=>N().Shopify;function I(){let t=a.analytics?.shopify;return typeof t=="object"?t:{}}function R(){try{let t=y()?.customerPrivacy;return t?.consentStatus==="loaded"&&t.currentVisitorConsent?.()?.analytics!=="no"&&!!t.analyticsProcessingAllowed?.()}catch{return!1}}function K(t){let n=`hydrogen:${t}`;return{getTrackingValues:()=>{let e=R()?y()?.customerPrivacy?.__internal:void 0;return{uniqueToken:e?.uniqueToken?.({generateFallback:!0,tag:n})??"",visitToken:e?.visitToken?.({generateFallback:!0,tag:n})??""}}}}var X=t=>(n,e)=>{let r=t.subscribers.get(n)??new Set;return t.subscribers.set(n,r),r.add(e),()=>t.subscribers.get(n)?.delete(e)};function Q(t){let n=[],e=[],r={shop:{shopId:t,channel:"headless"},consent:{mode:I().consent||"no-banner"}},o=()=>{if(R())for(let i of n)for(;i.next<e.length;i.next+=1){let s=e[i.next];s&&tt(i,s)}},c={getConfig:()=>r,publish(i,s={}){if(e.push({event:i,payload:{shop:r.shop,url:window.location.href,...s}}),e.length>Z){e.shift();for(let u of n)u.next=Math.max(0,u.next-1)}o()},addDestination(i){let s={name:i.name,next:0,subscribers:new Map,context:K(i.name)};return Promise.resolve(i.setup?.({subscribe:X(s),getConfig:c.getConfig})).then(()=>{n.push(s),o()}).catch(u=>{l(u,`analytics ${i.name}`)}),()=>{let u=n.indexOf(s);u>=0&&n.splice(u,1)}}};return document.addEventListener("consentTrackingApiLoaded",o),document.addEventListener("visitorConsentCollected",o),c}function tt(t,{event:n,payload:e}){t.subscribers.get(n)?.forEach(r=>{try{r(e,t.context)}catch(o){l(o,`analytics ${t.name}`)}})}function L(t){let n=document.createElement("script");n.src=t,n.async=!0,document.head.appendChild(n)}async function V(t){let n=y();if(n?.analytics)return n.analytics;let e=await A("query TetherShopId { shop { id } }",{},P({shop:{id:"string"}}),{context:!1}),r=y()??{};N().Shopify=r,r.country=a.country??"US";let[o="en"]=(a.locale||"en").split("-");r.locale=o.toLowerCase(),r.shop=a.domain,r.routes={root:"/",match:()=>({pageTemplateName:t()?"product":"page"}),...r.routes};let{proxy:c,consent:i}=I();r.customerPrivacy={...r.customerPrivacy,config:c?{isHeadless:!0,asyncConsent:!0,asyncVisitorState:!0,consentDomain:window.location.host}:{isHeadless:!0,storefrontAccessToken:a.token,checkoutRootDomain:a.domain}};let s=Q(e.shop.id);return r.analytics=s,L(i==="default-banner"?S["default-banner"]:S.other),L(z),_("shopify analytics ready",e.shop.id),s}var nt="Default Title",D=100,et=200,rt=t=>t?parseFloat(t.amount):0,M=t=>(t??"").split("/").pop()??"";function T(t,n,e=1,r){let o={item_id:n?.sku||M(n?.id)||M(t.id),item_name:t.title,item_variant:n?.title===nt?void 0:n?.title,item_brand:t.vendor||void 0,item_category:t.productType||void 0,price:rt(n?.price??t.priceRange?.minVariantPrice),quantity:e};return r!=null&&(o.index=r),o}var h=(t,n=t.quantity)=>T(t.merchandise.product,t.merchandise,n);function f(t){let n=t.reduce((e,r)=>e+r.price*(r.quantity||1),0);return Math.round(n*D)/D}var ot=(t,n,e=1)=>({id:t.id,title:t.title,price:n.price,vendor:t.vendor||"",variantId:n.id,variantTitle:n.title,quantity:e,sku:n.sku||void 0,productType:t.productType||void 0}),q=t=>({id:t.id,quantity:t.quantity,merchandise:{id:t.merchandise.id,title:t.merchandise.title,price:t.merchandise.price,sku:t.merchandise.sku,product:{id:t.merchandise.product.id,title:t.merchandise.product.title,vendor:t.merchandise.product.vendor||"",handle:t.merchandise.product.handle}}});function it(){let{dataLayer:t}=a.analytics??{},n=typeof t=="string"?t:"dataLayer",e=Reflect.get(window,n);if(Array.isArray(e))return e;let r=[];return Reflect.set(window,n,r),r}function st(t,n){let e=it();if(!n){e.push({event:t});return}e.push({ecommerce:null}),e.push({event:t,ecommerce:n})}var m=null,v=null,O=null,w=new WeakSet;function d(t,n,e,r){a.analytics?.dataLayer&&st(t,n),m&&e&&m.publish(e,r);try{a.analytics?.onEvent?.(t,n)}catch(o){l(o,"analytics onEvent")}}function F(){let t=document.querySelector(p("product"));return!t||t.closest(`${p("collection")},${p("products")},${p("recommendations")}`)?null:x.get(t)??null}function at({product:t,scope:n}){if(w.has(n.root)||F()!==n)return;w.add(n.root);let e=n.variant??t.variants.nodes[0],r=[T(t,e)],o=e?[ot(t,e)]:[];d("view_item",{currency:e?.price.currencyCode,value:f(r),items:r},"product_viewed",{products:o})}function ct({products:t,collection:n}){let e=t.slice(0,et).map((o,c)=>T(o,o.variants.nodes[0],1,c)),r={item_list_id:n?.handle||"products",item_list_name:n?.title||"Products"};if(!n){d("view_item_list",{...r,items:e});return}d("view_item_list",{...r,items:e},"collection_viewed",{collection:{id:n.id,handle:n.handle}})}function ut(t,n,e){let r=t?.cost.totalAmount.currencyCode;n.forEach((o,c)=>{let i=e.get(c),s=o.quantity-(i?.quantity??0);if(s<=0)return;let u=[h(o,s)];d("add_to_cart",{currency:r,value:f(u),items:u},"product_added_to_cart",{cart:t,prevCart:O,currentLine:q(o),prevLine:i?q(i):void 0})}),e.forEach((o,c)=>{let i=o.quantity-(n.get(c)?.quantity??0);if(i<=0)return;let s=[h(o,i)];d("remove_from_cart",{currency:r,value:f(s),items:s})})}function dt({cart:t,reason:n}){let e=new Map((t?.lines.nodes??[]).map(r=>[r.merchandise.id,r]));v&&n!=="load"&&n!=="pending"&&ut(t,e,v),v=e,O=t}function lt(){let t=b.lines.map(n=>h(n));d("view_cart",{currency:b.state?.cost.totalAmount.currencyCode,value:f(t),items:t})}function pt({cart:t}){if(!t)return;let n=t.lines.nodes.map(r=>h(r)),e=t.discountCodes.filter(r=>r.applicable).map(r=>r.code);d("begin_checkout",{currency:t.cost.totalAmount.currencyCode,value:f(n),coupon:e.join(",")||void 0,items:n})}var ft={"product-ready":at,"list-ready":ct,"cart-updated":dt,"cart-toggled":({open:t})=>{t&&lt()},checkout:pt,search:({term:t})=>{t&&d("search",{search_term:t},"search_viewed",{searchTerm:t})}};function mt(t,n){ft[n](t.detail)}function B(t){if(t.type==="astro:page-load"){w=new WeakSet,m?.publish("page_viewed",{});return}C.forEach(n=>{E(t,n)&&mt(t,n)})}async function yt(t){a.analytics?.shopify&&(m=await V(()=>F()!=null).catch(n=>(l(n,"shopify analytics"),null))),m?.publish("page_viewed",{}),t.splice(0).forEach(B),t.push=(...n)=>(n.forEach(B),t.length)}function g(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function ht(t){return g(t)&&g(t.__core)&&g(t.__parts)}function j(t,n){let e=Reflect.get(window,"Tether");if(!ht(e))throw new Error(`tether.${t}.js runs after the Tether script, which loads it, and needs its window.Tether`);e.__parts[t]=n}j("analytics",k);})();
@@ -70,9 +70,9 @@
70
70
  let note = `supported until about ${supportedUntil.toISOString().slice(0, 7)}`;
71
71
  if (!isReleased) note = "not released yet (release candidate at best)";
72
72
  else if (monthsLeft <= 0) {
73
- note = "no longer supported: Shopify falls back to the oldest supported version. Upgrade (see README)";
73
+ note = "no longer supported: Shopify falls back to the oldest supported version. Upgrade (see docs/reference.md)";
74
74
  } else if (monthsLeft < UPGRADE_WARNING_MONTHS) {
75
- note = `${note}: plan the upgrade to ${nextApiVersion(version)} or later (see README)`;
75
+ note = `${note}: plan the upgrade to ${nextApiVersion(version)} or later (see docs/reference.md)`;
76
76
  }
77
77
  return {
78
78
  version,
@@ -522,8 +522,23 @@
522
522
  console.groupEnd();
523
523
  }
524
524
 
525
+ // server/src/shared/json.ts
526
+ function isRecord(value) {
527
+ return value !== null && typeof value === "object" && !Array.isArray(value);
528
+ }
529
+
530
+ // src/part-registry.ts
531
+ function isTetherInternals(value) {
532
+ return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
533
+ }
534
+ function registerPart(name, part) {
535
+ const tether = Reflect.get(window, "Tether");
536
+ if (!isTetherInternals(tether)) {
537
+ throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
538
+ }
539
+ tether.__parts[name] = part;
540
+ }
541
+
525
542
  // src/parts/diagnose.ts
526
- var { Tether } = window;
527
- if (!Tether) throw new Error("tether.diagnose.js runs after the Tether script, which loads it");
528
- Tether.__parts.diagnose = diagnose_exports;
543
+ registerPart("diagnose", diagnose_exports);
529
544
  })();
@@ -1,4 +1,4 @@
1
- (()=>{var H=Object.defineProperty;var L=(e,n)=>{for(var t in n)H(e,t,{get:n[t],enumerable:!0})};var P={};L(P,{apiVersionStatus:()=>b,checkMarkup:()=>w,diagnose:()=>we,didYouMean:()=>h});var Y=window.Tether.__core["config.ts"],[a,E,Ee,Se,$e,Re,ve]=Y;var G=window.Tether.__core["client.ts"],[S,$,Te,R,_e]=G;var B=window.Tether.__core["dom.ts"],[Ne,p,De,xe,Ve,Oe,m,Ue,v,Ce,Ie,qe,d,He,l,Le,Ye,Ge]=B;var Q=window.Tether.__core["loader.ts"],[Qe,A]=Q;var K=window.Tether.__core["selling-plans.ts"],[T]=K;var j=window.Tether.__core["status.ts"],[_,f]=j;var W=/^(\d{4})-(01|04|07|10)$/;function N(e){let n=W.exec(typeof e=="string"?e:"");return n?{year:Number(n[1]),month:Number(n[2])}:null}var z=(e,n)=>`${e}-${String(n).padStart(2,"0")}`;function M(e,n=1){let t=N(e);if(!t)throw new Error(`not a quarterly Shopify API version: ${e}`);let r=t.year*4+(t.month-1)/3+n;return z(Math.floor(r/4),r%4*3+1)}function b(e,n=new Date){if(e==="unstable")return{version:e,ok:!1,note:'"unstable" changes without notice: pin a dated version such as 2026-07'};let t=N(e);if(!t)return{version:e,ok:!1,note:"not a quarterly version (YYYY-01, -04, -07 or -10)"};let r=new Date(Date.UTC(t.year,t.month-1,1)),s=new Date(Date.UTC(t.year,t.month-1+12,1)),o=(s.getTime()-n.getTime())/2630016e3,i=r<=n,c=`supported until about ${s.toISOString().slice(0,7)}`;return i?o<=0?c="no longer supported: Shopify falls back to the oldest supported version. Upgrade (see README)":o<3&&(c=`${c}: plan the upgrade to ${M(e)} or later (see README)`):c="not released yet (release candidate at best)",{version:e,ok:i&&o>0,monthsLeft:Math.round(o),next:M(e),note:c}}var F=window.Tether.__core["lazy.ts"],[D]=F;var x=new Set(["in-stock","out-of-stock","backorder","low-stock","plenty-in-stock","on-sale","not-on-sale","has-variants","single-variant","subscription-available","subscription-unavailable","subscription-only","one-time-available","subscription-selected","one-time-selected","has-savings","loading","ready","error","not-found","cart-empty","cart-filled","cart-has-subscription","cart-no-subscription","cart-has-discount","cart-error","cart-warning","list-empty","list-filled","search-empty","search-results","logged-in","logged-out","orders-empty","orders-loading","addresses-loading","addresses-empty","addresses-error","subscriptions-loading","subscriptions-empty","subscriptions-error"]),V=new Set(["title","description","description-text","vendor","type","handle","published-at","price","total-price","compare-at-price","unit-price","min-price","max-price","discount-percentage","discount-amount","variant-title","variant-id","sku","barcode","stock","quantity","featured-image","variant-image","images","tags","link","url","one-time-price","subscription-price","subscription-savings","subscription-savings-amount","checkout-charge","plan-name","plan-description","plan-group","option-value","swatch","image"]),O=new Set(`account account-bind account-link account-login account-logout add-label add-to-cart adding-text
1
+ (()=>{var L=Object.defineProperty;var Y=(e,n)=>{for(var t in n)L(e,t,{get:n[t],enumerable:!0})};var P={};Y(P,{apiVersionStatus:()=>y,checkMarkup:()=>k,diagnose:()=>ke,didYouMean:()=>f});var G=window.Tether.__core["config.ts"],[a,E,$e,Re,Te,Ae,_e]=G;var B=window.Tether.__core["client.ts"],[$,R,Ne,T,xe]=B;var Q=window.Tether.__core["dom.ts"],[De,p,Oe,Ve,Ue,Ie,m,Ce,A,qe,He,Le,d,Ye,l,Ge,Be,Qe]=Q;var j=window.Tether.__core["loader.ts"],[Ke,_]=j;var K=window.Tether.__core["selling-plans.ts"],[v]=K;var W=window.Tether.__core["status.ts"],[N,h]=W;var F=/^(\d{4})-(01|04|07|10)$/;function M(e){let n=F.exec(typeof e=="string"?e:"");return n?{year:Number(n[1]),month:Number(n[2])}:null}var z=(e,n)=>`${e}-${String(n).padStart(2,"0")}`;function x(e,n=1){let t=M(e);if(!t)throw new Error(`not a quarterly Shopify API version: ${e}`);let r=t.year*4+(t.month-1)/3+n;return z(Math.floor(r/4),r%4*3+1)}function y(e,n=new Date){if(e==="unstable")return{version:e,ok:!1,note:'"unstable" changes without notice: pin a dated version such as 2026-07'};let t=M(e);if(!t)return{version:e,ok:!1,note:"not a quarterly version (YYYY-01, -04, -07 or -10)"};let r=new Date(Date.UTC(t.year,t.month-1,1)),s=new Date(Date.UTC(t.year,t.month-1+12,1)),o=(s.getTime()-n.getTime())/2630016e3,i=r<=n,c=`supported until about ${s.toISOString().slice(0,7)}`;return i?o<=0?c="no longer supported: Shopify falls back to the oldest supported version. Upgrade (see docs/reference.md)":o<3&&(c=`${c}: plan the upgrade to ${x(e)} or later (see docs/reference.md)`):c="not released yet (release candidate at best)",{version:e,ok:i&&o>0,monthsLeft:Math.round(o),next:x(e),note:c}}var J=window.Tether.__core["lazy.ts"],[D]=J;var O=new Set(["in-stock","out-of-stock","backorder","low-stock","plenty-in-stock","on-sale","not-on-sale","has-variants","single-variant","subscription-available","subscription-unavailable","subscription-only","one-time-available","subscription-selected","one-time-selected","has-savings","loading","ready","error","not-found","cart-empty","cart-filled","cart-has-subscription","cart-no-subscription","cart-has-discount","cart-error","cart-warning","list-empty","list-filled","search-empty","search-results","logged-in","logged-out","orders-empty","orders-loading","addresses-loading","addresses-empty","addresses-error","subscriptions-loading","subscriptions-empty","subscriptions-error"]),V=new Set(["title","description","description-text","vendor","type","handle","published-at","price","total-price","compare-at-price","unit-price","min-price","max-price","discount-percentage","discount-amount","variant-title","variant-id","sku","barcode","stock","quantity","featured-image","variant-image","images","tags","link","url","one-time-price","subscription-price","subscription-savings","subscription-savings-amount","checkout-charge","plan-name","plan-description","plan-group","option-value","swatch","image"]),U=new Set(`account account-bind account-link account-login account-logout add-label add-to-cart adding-text
2
2
  always-enabled bind cart-checkout-charge cart-clear cart-close cart-count cart-discounts cart-drawer cart-label cart-lines
3
3
  cart-note cart-open cart-subtotal cart-total cart-warning checkout code collection collection-bind countries country
4
4
  country-bind country-label country-select default-plan default-purchase discount discount-code discount-form discount-input
@@ -11,4 +11,4 @@
11
11
  plan-value product products purchase purchase-mode qty qty-minus qty-plus quantity recommendations reverse search
12
12
  search-bind search-collections search-input search-limit search-min search-products search-queries search-results
13
13
  search-state show soldout-text sort state subscribe-text variant variant-select variant-url max-width max-height crop
14
- sig label hydrated busy`.split(/\s+/).filter(Boolean)),J=["bind","option-list","option","variant-select","add-to-cart","purchase","plan-list","plan","qty","line-attribute"],X=["option-list","plan-list","cart-lines","list"],y="metafield:",Z=/^image:\d+$/,ee=2;function te(e,n){let t=Array.from({length:n.length+1},(r,s)=>s);for(let r=1;r<=e.length;r++){let s=[r];for(let o=1;o<=n.length;o++){let i=(t[o-1]??0)+(e[r-1]===n[o-1]?0:1);s.push(Math.min((t[o]??0)+1,(s[o-1]??0)+1,i))}t=s}return t[n.length]??0}function h(e,n,t=""){let r=null,s=1/0;for(let i of n){let c=te(e,i);c<s&&(s=c,r=i)}let o=Math.max(2,Math.floor(e.length/4));return r!==null&&s<=o?` Did you mean "${t}${r}"?`:""}function ne(e){let n=e.id?`#${e.id}`:"",t=e.className&&typeof e.className=="string"?e.className.trim().split(/\s+/):[],r=t.length?`.${t.slice(0,ee).join(".")}`:"";return`<${e.tagName.toLowerCase()}${n}${r}>`}var U=()=>`${l("collection")},${l("products")},${l("recommendations")}`;function re(e,n){d(e,l("product")).forEach(t=>{if(t.closest(U())&&t.closest(l("list")))return;let{key:r,fromUrl:s,raw:o}=f(t);o?s&&!r&&n("warn",`${p("product")}="${o}" but this URL has no value for it (e.g. ?handle=my-product).`,t):n("error",`${p("product")} has no value. Bind it to the Shopify handle (CMS field), or use "url:handle".`,t)})}function oe(e,n){for(let t of J)d(e,l(t)).forEach(r=>{r.closest(l("product"))||t==="line-attribute"&&r.closest(l("group"))||n("warn",`${p(t)} outside any ${p("product")}: it does nothing here.`,r)});d(e,l("group-add")).forEach(t=>{t.closest(l("group"))||n("warn",`${p("group-add")} outside a ${p("group")}.`,t)});for(let t of X)d(e,l(t)).forEach(r=>{!r.firstElementChild&&!v(r)&&n("warn",`${p(t)} without a template child: put one example element inside it.`,r)});d(e,U()).forEach(t=>{d(t,l("list")).length||n("error",`List without a ${p("list")} child: products have nowhere to render.`,t)})}function se(e,n){d(e,l("show")).forEach(t=>{let r=m(t,"show")??"";x.has(r)||n("warn",`Unknown ${p("show")}="${r}".${h(r,x)}`,t)}),d(e,l("bind")).forEach(t=>{let r=m(t,"bind")||"";!r||V.has(r)||Z.test(r)||r.startsWith(y)||n("warn",`Unknown ${p("bind")}="${r}": it stays empty.${h(r,V)}`,t)})}function ie(e,n){d(e,l("bind")).forEach(t=>{let r=m(t,"bind")||"";if(!r.startsWith(y))return;let s=r.slice(y.length);a.metafields.some(i=>(typeof i=="string"?i:`${i.namespace}.${i.key}`)===s)||n("error",`${p("bind")}="${r}" but "${s}" is not in config.metafields, so it stays empty.`,t)})}function ae(e,n){let t=`${a.prefix}-`,r=new Set;d(e,"*").forEach(s=>{for(let{name:o}of s.attributes){if(!o.startsWith(t))continue;let i=o.slice(t.length);O.has(i)||r.has(i)||(r.add(i),n("warn",`Unknown attribute ${o}: Tether ignores it.${h(i,O,t)}`,s))}})}function ce(e,n){let t=d(e,l("cart-drawer")).length;d(e,l("cart-open")).length&&!t&&n("warn",`${p("cart-open")} exists but there is no ${p("cart-drawer")} on this page.`),t>1&&n("warn",`More than one ${p("cart-drawer")}.`),d(e,`[${p("state")}="error"]`).forEach(r=>{r.matches(_())&&n("error",`Scope failed to load (${m(r,"error")||"error"}).`,r)})}function w(e=document){let n=[],t=(r,s,o)=>{n.push(o?{level:r,message:s,element:ne(o),el:o}:{level:r,message:s})};return re(e,t),oe(e,t),se(e,t),ae(e,t),ie(e,t),ce(e,t),n}var le=20,ue=3,C=4;function de(e){return e?`${e.slice(0,C)}\u2026${e.slice(-C)} (${e.length} chars)`:"(missing)"}function I(e,n){if(e instanceof Error&&e.message)return e.message;let t=typeof e=="object"&&e!==null?Reflect.get(e,"code"):void 0;return typeof t=="string"&&t?t:n}function pe(){return{domain:a.domain||"(missing)",token:de(a.token),apiVersion:a.apiVersion,endpoint:a.domain?S():null,country:a.country,language:a.language,locale:a.locale,markets:a.markets,prefix:a.prefix,productPath:a.productPath,metafields:a.metafields,autoMount:a.autoMount,observe:a.observe,onError:typeof a.onError=="function"}}async function me(){return{country:a.country||null,language:a.language||null,locale:a.locale||null,detected:a.markets?.detect?(await D("markets")).detectMarket(a.markets):null}}function he({ok:e,monthsLeft:n,note:t}){return e&&(n===void 0||n>=ue)?null:{level:e?"warn":"error",message:`apiVersion ${a.apiVersion}: ${t}`}}var ge=R({shop:{name:"string",primaryDomain:{url:"string"},paymentSettings:{currencyCode:"string"}}});async function fe(){if(!E())return{kind:"not-configured"};let e=Date.now();try{let n=await $("query TetherDiagnose { shop { name primaryDomain { url } paymentSettings { currencyCode } } }",{},ge,{context:!1});return{kind:"reachable",shop:{name:n.shop.name,url:n.shop.primaryDomain.url,currency:n.shop.paymentSettings.currencyCode},latencyMs:Date.now()-e}}catch(n){return{kind:"unreachable",error:n,latencyMs:Date.now()-e}}}function be(e,n,t){let r=[],s=t.options.map(i=>i.name),o=d(e,l("product")).filter(i=>f(i).key===n&&i.querySelector(l("add-to-cart")));for(let i of o){let c=new Set(d(i,`${l("option-list")},select${l("option")}`).map(u=>m(u,"option-list")||m(u,"option")));if(!(!c.size&&d(i,`select${l("variant-select")}`).length)){if(!a.language)for(let u of c)!u||s.includes(u)||r.push({level:"warn",message:`Product "${t.handle}" has no option "${u}" (its options: ${s.join(", ")||"none"}).${h(u,s)}`});for(let u of t.options)u.optionValues.length<=1||c.has(u.name)||r.push({level:"warn",message:`Product "${t.handle}": option "${u.name}" (${u.optionValues.length} values) has no tether-option-list, so visitors can't choose it.`})}}return r}async function ye(e,n){let t=d(e,l("product")).map(o=>f(o).key),r=[...new Set(t.filter(o=>o!==null&&o!==""))].slice(0,le);(await Promise.allSettled(r.map(o=>A(o)))).forEach((o,i)=>{let c=r[i]??"";if(o.status==="rejected"){let g=I(o.reason,"not loaded");n.products.push({key:c,error:o.reason instanceof Error?o.reason.message:void 0}),n.problems.push({level:"error",message:`Product "${c}": ${g}. Is it published to the Headless channel?`});return}let u=o.value,k=T(u);n.products.push({key:c,handle:u.handle,title:u.title,plans:k.length,requiresSellingPlan:u.requiresSellingPlan});for(let g of k)n.sellingPlans.push({product:u.handle,group:g.group.name,plan:g.name,id:g.id});n.problems.push(...be(e,c,u))})}async function we({root:e=document,silent:n=!1,version:t="",now:r=new Date}={}){let s=await fe(),o={version:t,config:pe(),apiVersion:b(a.apiVersion,r),market:await me(),reachable:s.kind==="reachable",shop:s.kind==="reachable"?s.shop:null,latencyMs:s.kind==="not-configured"?null:s.latencyMs,products:[],sellingPlans:[],problems:[]};switch(s.kind){case"not-configured":o.problems.push({level:"error",message:"TETHER_CONFIG needs domain and token."});break;case"unreachable":o.problems.push({level:"error",message:`Storefront API not reachable: ${I(s.error,"unknown error")}`});break;case"reachable":await ye(e,o);break}let i=he(o.apiVersion);return i&&o.problems.push(i),typeof document<"u"&&o.problems.push(...w(e)),n||Pe(o),o}function Pe(e){let n=e.problems.filter(c=>c.level==="error").length,t=e.problems.length-n;console.group(`[${a.prefix}] diagnose: ${n?`${n} error(s)`:"no errors"}, ${t} warning(s)`),console.log("version",e.version,"| API",e.apiVersion.version,`(${e.apiVersion.note})`),console.log("config",e.config);let{country:r,language:s,detected:o}=e.market,i=[r,s].filter(Boolean).join(" / ")||"the store default";console.log("market",`in use: ${i}`,o?`(detection picks ${JSON.stringify(o)})`:""),console.log(e.shop?`Storefront API reachable: ${e.shop.name} (${e.latencyMs??0} ms)`:"Storefront API NOT reachable"),e.products.length&&console.table(e.products),e.sellingPlans.length?console.table(e.sellingPlans):e.reachable&&console.log("No selling plans on the products of this page.");for(let c of e.problems)c.level==="error"?console.error(c.message,c.el??""):console.warn(c.message,c.el??"");console.groupEnd()}var{Tether:q}=window;if(!q)throw new Error("tether.diagnose.js runs after the Tether script, which loads it");q.__parts.diagnose=P;})();
14
+ sig label hydrated busy`.split(/\s+/).filter(Boolean)),X=["bind","option-list","option","variant-select","add-to-cart","purchase","plan-list","plan","qty","line-attribute"],Z=["option-list","plan-list","cart-lines","list"],w="metafield:",ee=/^image:\d+$/,te=2;function ne(e,n){let t=Array.from({length:n.length+1},(r,s)=>s);for(let r=1;r<=e.length;r++){let s=[r];for(let o=1;o<=n.length;o++){let i=(t[o-1]??0)+(e[r-1]===n[o-1]?0:1);s.push(Math.min((t[o]??0)+1,(s[o-1]??0)+1,i))}t=s}return t[n.length]??0}function f(e,n,t=""){let r=null,s=1/0;for(let i of n){let c=ne(e,i);c<s&&(s=c,r=i)}let o=Math.max(2,Math.floor(e.length/4));return r!==null&&s<=o?` Did you mean "${t}${r}"?`:""}function re(e){let n=e.id?`#${e.id}`:"",t=e.className&&typeof e.className=="string"?e.className.trim().split(/\s+/):[],r=t.length?`.${t.slice(0,te).join(".")}`:"";return`<${e.tagName.toLowerCase()}${n}${r}>`}var I=()=>`${l("collection")},${l("products")},${l("recommendations")}`;function oe(e,n){d(e,l("product")).forEach(t=>{if(t.closest(I())&&t.closest(l("list")))return;let{key:r,fromUrl:s,raw:o}=h(t);o?s&&!r&&n("warn",`${p("product")}="${o}" but this URL has no value for it (e.g. ?handle=my-product).`,t):n("error",`${p("product")} has no value. Bind it to the Shopify handle (CMS field), or use "url:handle".`,t)})}function se(e,n){for(let t of X)d(e,l(t)).forEach(r=>{r.closest(l("product"))||t==="line-attribute"&&r.closest(l("group"))||n("warn",`${p(t)} outside any ${p("product")}: it does nothing here.`,r)});d(e,l("group-add")).forEach(t=>{t.closest(l("group"))||n("warn",`${p("group-add")} outside a ${p("group")}.`,t)});for(let t of Z)d(e,l(t)).forEach(r=>{!r.firstElementChild&&!A(r)&&n("warn",`${p(t)} without a template child: put one example element inside it.`,r)});d(e,I()).forEach(t=>{d(t,l("list")).length||n("error",`List without a ${p("list")} child: products have nowhere to render.`,t)})}function ie(e,n){d(e,l("show")).forEach(t=>{let r=m(t,"show")??"";O.has(r)||n("warn",`Unknown ${p("show")}="${r}".${f(r,O)}`,t)}),d(e,l("bind")).forEach(t=>{let r=m(t,"bind")||"";!r||V.has(r)||ee.test(r)||r.startsWith(w)||n("warn",`Unknown ${p("bind")}="${r}": it stays empty.${f(r,V)}`,t)})}function ae(e,n){d(e,l("bind")).forEach(t=>{let r=m(t,"bind")||"";if(!r.startsWith(w))return;let s=r.slice(w.length);a.metafields.some(i=>(typeof i=="string"?i:`${i.namespace}.${i.key}`)===s)||n("error",`${p("bind")}="${r}" but "${s}" is not in config.metafields, so it stays empty.`,t)})}function ce(e,n){let t=`${a.prefix}-`,r=new Set;d(e,"*").forEach(s=>{for(let{name:o}of s.attributes){if(!o.startsWith(t))continue;let i=o.slice(t.length);U.has(i)||r.has(i)||(r.add(i),n("warn",`Unknown attribute ${o}: Tether ignores it.${f(i,U,t)}`,s))}})}function le(e,n){let t=d(e,l("cart-drawer")).length;d(e,l("cart-open")).length&&!t&&n("warn",`${p("cart-open")} exists but there is no ${p("cart-drawer")} on this page.`),t>1&&n("warn",`More than one ${p("cart-drawer")}.`),d(e,`[${p("state")}="error"]`).forEach(r=>{r.matches(N())&&n("error",`Scope failed to load (${m(r,"error")||"error"}).`,r)})}function k(e=document){let n=[],t=(r,s,o)=>{n.push(o?{level:r,message:s,element:re(o),el:o}:{level:r,message:s})};return oe(e,t),se(e,t),ie(e,t),ce(e,t),ae(e,t),le(e,t),n}var ue=20,de=3,C=4;function pe(e){return e?`${e.slice(0,C)}\u2026${e.slice(-C)} (${e.length} chars)`:"(missing)"}function q(e,n){if(e instanceof Error&&e.message)return e.message;let t=typeof e=="object"&&e!==null?Reflect.get(e,"code"):void 0;return typeof t=="string"&&t?t:n}function me(){return{domain:a.domain||"(missing)",token:pe(a.token),apiVersion:a.apiVersion,endpoint:a.domain?$():null,country:a.country,language:a.language,locale:a.locale,markets:a.markets,prefix:a.prefix,productPath:a.productPath,metafields:a.metafields,autoMount:a.autoMount,observe:a.observe,onError:typeof a.onError=="function"}}async function fe(){return{country:a.country||null,language:a.language||null,locale:a.locale||null,detected:a.markets?.detect?(await D("markets")).detectMarket(a.markets):null}}function ge({ok:e,monthsLeft:n,note:t}){return e&&(n===void 0||n>=de)?null:{level:e?"warn":"error",message:`apiVersion ${a.apiVersion}: ${t}`}}var he=T({shop:{name:"string",primaryDomain:{url:"string"},paymentSettings:{currencyCode:"string"}}});async function be(){if(!E())return{kind:"not-configured"};let e=Date.now();try{let n=await R("query TetherDiagnose { shop { name primaryDomain { url } paymentSettings { currencyCode } } }",{},he,{context:!1});return{kind:"reachable",shop:{name:n.shop.name,url:n.shop.primaryDomain.url,currency:n.shop.paymentSettings.currencyCode},latencyMs:Date.now()-e}}catch(n){return{kind:"unreachable",error:n,latencyMs:Date.now()-e}}}function ye(e,n,t){let r=[],s=t.options.map(i=>i.name),o=d(e,l("product")).filter(i=>h(i).key===n&&i.querySelector(l("add-to-cart")));for(let i of o){let c=new Set(d(i,`${l("option-list")},select${l("option")}`).map(u=>m(u,"option-list")||m(u,"option")));if(!(!c.size&&d(i,`select${l("variant-select")}`).length)){if(!a.language)for(let u of c)!u||s.includes(u)||r.push({level:"warn",message:`Product "${t.handle}" has no option "${u}" (its options: ${s.join(", ")||"none"}).${f(u,s)}`});for(let u of t.options)u.optionValues.length<=1||c.has(u.name)||r.push({level:"warn",message:`Product "${t.handle}": option "${u.name}" (${u.optionValues.length} values) has no tether-option-list, so visitors can't choose it.`})}}return r}async function we(e,n){let t=d(e,l("product")).map(o=>h(o).key),r=[...new Set(t.filter(o=>o!==null&&o!==""))].slice(0,ue);(await Promise.allSettled(r.map(o=>_(o)))).forEach((o,i)=>{let c=r[i]??"";if(o.status==="rejected"){let g=q(o.reason,"not loaded");n.products.push({key:c,error:o.reason instanceof Error?o.reason.message:void 0}),n.problems.push({level:"error",message:`Product "${c}": ${g}. Is it published to the Headless channel?`});return}let u=o.value,S=v(u);n.products.push({key:c,handle:u.handle,title:u.title,plans:S.length,requiresSellingPlan:u.requiresSellingPlan});for(let g of S)n.sellingPlans.push({product:u.handle,group:g.group.name,plan:g.name,id:g.id});n.problems.push(...ye(e,c,u))})}async function ke({root:e=document,silent:n=!1,version:t="",now:r=new Date}={}){let s=await be(),o={version:t,config:me(),apiVersion:y(a.apiVersion,r),market:await fe(),reachable:s.kind==="reachable",shop:s.kind==="reachable"?s.shop:null,latencyMs:s.kind==="not-configured"?null:s.latencyMs,products:[],sellingPlans:[],problems:[]};switch(s.kind){case"not-configured":o.problems.push({level:"error",message:"TETHER_CONFIG needs domain and token."});break;case"unreachable":o.problems.push({level:"error",message:`Storefront API not reachable: ${q(s.error,"unknown error")}`});break;case"reachable":await we(e,o);break}let i=ge(o.apiVersion);return i&&o.problems.push(i),typeof document<"u"&&o.problems.push(...k(e)),n||Pe(o),o}function Pe(e){let n=e.problems.filter(c=>c.level==="error").length,t=e.problems.length-n;console.group(`[${a.prefix}] diagnose: ${n?`${n} error(s)`:"no errors"}, ${t} warning(s)`),console.log("version",e.version,"| API",e.apiVersion.version,`(${e.apiVersion.note})`),console.log("config",e.config);let{country:r,language:s,detected:o}=e.market,i=[r,s].filter(Boolean).join(" / ")||"the store default";console.log("market",`in use: ${i}`,o?`(detection picks ${JSON.stringify(o)})`:""),console.log(e.shop?`Storefront API reachable: ${e.shop.name} (${e.latencyMs??0} ms)`:"Storefront API NOT reachable"),e.products.length&&console.table(e.products),e.sellingPlans.length?console.table(e.sellingPlans):e.reachable&&console.log("No selling plans on the products of this page.");for(let c of e.problems)c.level==="error"?console.error(c.message,c.el??""):console.warn(c.message,c.el??"");console.groupEnd()}function b(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Se(e){return b(e)&&b(e.__core)&&b(e.__parts)}function H(e,n){let t=Reflect.get(window,"Tether");if(!Se(t))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);t.__parts[e]=n}H("diagnose",P);})();
@@ -29,10 +29,36 @@
29
29
  var m4 = window.Tether.__core["cart.ts"];
30
30
  var [Cart] = m4;
31
31
 
32
- // server/src/shared/json.ts
33
- function isRecord(value) {
34
- return value !== null && typeof value === "object" && !Array.isArray(value);
32
+ // tether-core:page-market.ts
33
+ var m5 = window.Tether.__core["page-market.ts"];
34
+ var [setCountry] = m5;
35
+
36
+ // tether-core:market-codes.ts
37
+ var m6 = window.Tether.__core["market-codes.ts"];
38
+ var [toCountry, toLanguage] = m6;
39
+
40
+ // src/markets.ts
41
+ var storageKey = () => `${cfg.prefix}:market:${cfg.domain}`;
42
+ function parseJsonOrNull(text) {
43
+ try {
44
+ return JSON.parse(text);
45
+ } catch (error) {
46
+ if (error instanceof SyntaxError) return null;
47
+ throw error;
48
+ }
35
49
  }
50
+ function toMarket(value) {
51
+ if (typeof value !== "object" || value === null) return null;
52
+ const country = toCountry(Reflect.get(value, "country"));
53
+ if (!country) return null;
54
+ const locale = Reflect.get(value, "locale");
55
+ return {
56
+ country,
57
+ language: toLanguage(Reflect.get(value, "language")) ?? void 0,
58
+ locale: typeof locale === "string" && locale ? locale : void 0
59
+ };
60
+ }
61
+ var parseSavedMarket = (text) => toMarket(parseJsonOrNull(text));
36
62
 
37
63
  // src/extras.ts
38
64
  function groupAttributes(group, name) {
@@ -63,22 +89,6 @@
63
89
  return null;
64
90
  }
65
91
  }
66
- function parseStoredMarket(text) {
67
- let value;
68
- try {
69
- value = JSON.parse(text);
70
- } catch {
71
- return null;
72
- }
73
- if (!isRecord(value)) return null;
74
- const { country, language, locale } = value;
75
- if (typeof country !== "string" || !country) return null;
76
- return {
77
- country,
78
- language: typeof language === "string" ? language : null,
79
- locale: typeof locale === "string" ? locale : void 0
80
- };
81
- }
82
92
  function onStorage(event) {
83
93
  if (event.key === cfg.storageKey || event.key === `${cfg.storageKey}:seen`) {
84
94
  Cart.init().catch((error) => {
@@ -86,12 +96,11 @@
86
96
  });
87
97
  return;
88
98
  }
89
- if (event.key !== `${cfg.prefix}:market:${cfg.domain}` || !event.newValue) return;
90
- const market = parseStoredMarket(event.newValue);
91
- const tether = Reflect.get(window, "Tether");
92
- if (!market || !tether) return;
93
- const options = { language: market.language, locale: market.locale, remember: false };
94
- tether.setCountry(market.country, options).catch((error) => {
99
+ if (event.key !== storageKey() || !event.newValue) return;
100
+ const market = parseSavedMarket(event.newValue);
101
+ if (!market) return;
102
+ const options = { language: market.language ?? null, locale: market.locale, remember: false };
103
+ setCountry(market.country, options).catch((error) => {
95
104
  reportError(error, "market from another tab");
96
105
  });
97
106
  }
@@ -117,8 +126,23 @@
117
126
  replaceUrlIfAllowed(url);
118
127
  }
119
128
 
129
+ // server/src/shared/json.ts
130
+ function isRecord(value) {
131
+ return value !== null && typeof value === "object" && !Array.isArray(value);
132
+ }
133
+
134
+ // src/part-registry.ts
135
+ function isTetherInternals(value) {
136
+ return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
137
+ }
138
+ function registerPart(name, part) {
139
+ const tether = Reflect.get(window, "Tether");
140
+ if (!isTetherInternals(tether)) {
141
+ throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
142
+ }
143
+ tether.__parts[name] = part;
144
+ }
145
+
120
146
  // src/parts/extras.ts
121
- var { Tether } = window;
122
- if (!Tether) throw new Error("tether.extras.js runs after the Tether script, which loads it");
123
- Tether.__parts.extras = extras_exports;
147
+ registerPart("extras", extras_exports);
124
148
  })();
@@ -1 +1 @@
1
- (()=>{var E=Object.defineProperty;var A=(t,r)=>{for(var n in r)E(t,n,{get:r[n],enumerable:!0})};var f={};A(f,{addGroup:()=>U,onStorage:()=>I,writeVariantUrl:()=>P});var C=window.Tether.__core["config.ts"],[i,q,F,K,V,u,d]=C;var O=window.Tether.__core["dom.ts"],[z,D,g,m,G,W,w,y,Y,Z,h,v,k,B,l,H,Q,X]=O;var M=window.Tether.__core["product.ts"],[x]=M;var N=window.Tether.__core["cart.ts"],[p]=N;function T(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function R(t,r){let n=g(h(t,"line-attributes"));return r?[{key:"_group",value:r},...n]:n}async function U(t){let r=t.closest(l("group"));if(!r)return null;let n=w(r,"group"),o=R(r,n),e=k(r,l("product")).flatMap(a=>{let s=x.get(a);if(!s?.variant?.availableForSale||s.quantity<=0)return[];let c=s.getLine();return c?[{...c,attributes:[...c.attributes??[],...o]}]:[]});if(!e.length)return d("group-add: nothing selected"),null;try{let a=await p.add(e);return m("group-added",{group:n,lines:e},r),a}catch(a){return u(a,"group add"),null}}function L(t){let r;try{r=JSON.parse(t)}catch{return null}if(!T(r))return null;let{country:n,language:o,locale:e}=r;return typeof n!="string"||!n?null:{country:n,language:typeof o=="string"?o:null,locale:typeof e=="string"?e:void 0}}function I(t){if(t.key===i.storageKey||t.key===`${i.storageKey}:seen`){p.init().catch(e=>{u(e,"cart from another tab")});return}if(t.key!==`${i.prefix}:market:${i.domain}`||!t.newValue)return;let r=L(t.newValue),n=Reflect.get(window,"Tether");if(!r||!n)return;let o={language:r.language,locale:r.locale,remember:!1};n.setCountry(r.country,o).catch(e=>{u(e,"market from another tab")})}var b=new WeakMap,S=t=>t.split("/").pop()??t;function J(t){try{window.history.replaceState(window.history.state,"",t)}catch{}}function P(t,{variant:r,sellingPlanId:n}){let o=`${r.id}|${n??""}`,e=b.get(t);if(b.set(t,o),!e||e===o)return;let a=i.variantUrl&&document.querySelector(l("product"))===t;if(!y(t,"variant-url")&&!a)return;let s=new URL(window.location.href);s.searchParams.set("variant",S(r.id)),n?s.searchParams.set("selling_plan",S(n)):s.searchParams.delete("selling_plan"),J(s)}var{Tether:_}=window;if(!_)throw new Error("tether.extras.js runs after the Tether script, which loads it");_.__parts.extras=f;})();
1
+ (()=>{var N=Object.defineProperty;var R=(e,t)=>{for(var n in t)N(e,n,{get:t[n],enumerable:!0})};var f={};R(f,{addGroup:()=>q,onStorage:()=>j,writeVariantUrl:()=>V});var O=window.Tether.__core["config.ts"],[c,Y,Z,P,I,i,p]=O;var v=window.Tether.__core["dom.ts"],[Q,X,m,y,ee,te,k,w,ne,re,h,oe,S,ae,s,ce,ue,ie]=v;var U=window.Tether.__core["product.ts"],[C]=U;var K=window.Tether.__core["cart.ts"],[d]=K;var F=window.Tether.__core["page-market.ts"],[M]=F;var H=window.Tether.__core["market-codes.ts"],[x,b]=H;var E=()=>`${c.prefix}:market:${c.domain}`;function $(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function D(e){if(typeof e!="object"||e===null)return null;let t=x(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:b(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}var T=e=>D($(e));function J(e,t){let n=m(h(e,"line-attributes"));return t?[{key:"_group",value:t},...n]:n}async function q(e){let t=e.closest(s("group"));if(!t)return null;let n=k(t,"group"),r=J(t,n),u=S(t,s("product")).flatMap(a=>{let o=C.get(a);if(!o?.variant?.availableForSale||o.quantity<=0)return[];let g=o.getLine();return g?[{...g,attributes:[...g.attributes??[],...r]}]:[]});if(!u.length)return p("group-add: nothing selected"),null;try{let a=await d.add(u);return y("group-added",{group:n,lines:u},t),a}catch(a){return i(a,"group add"),null}}function j(e){if(e.key===c.storageKey||e.key===`${c.storageKey}:seen`){d.init().catch(r=>{i(r,"cart from another tab")});return}if(e.key!==E()||!e.newValue)return;let t=T(e.newValue);if(!t)return;let n={language:t.language??null,locale:t.locale,remember:!1};M(t.country,n).catch(r=>{i(r,"market from another tab")})}var _=new WeakMap,L=e=>e.split("/").pop()??e;function z(e){try{window.history.replaceState(window.history.state,"",e)}catch{}}function V(e,{variant:t,sellingPlanId:n}){let r=`${t.id}|${n??""}`,u=_.get(e);if(_.set(e,r),!u||u===r)return;let a=c.variantUrl&&document.querySelector(s("product"))===e;if(!w(e,"variant-url")&&!a)return;let o=new URL(window.location.href);o.searchParams.set("variant",L(t.id)),n?o.searchParams.set("selling_plan",L(n)):o.searchParams.delete("selling_plan"),z(o)}function l(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function W(e){return l(e)&&l(e.__core)&&l(e.__parts)}function A(e,t){let n=Reflect.get(window,"Tether");if(!W(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}A("extras",f);})();