@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
@@ -240,8 +240,23 @@
240
240
  }
241
241
  }
242
242
 
243
+ // server/src/shared/json.ts
244
+ function isRecord(value) {
245
+ return value !== null && typeof value === "object" && !Array.isArray(value);
246
+ }
247
+
248
+ // src/part-registry.ts
249
+ function isTetherInternals(value) {
250
+ return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
251
+ }
252
+ function registerPart(name, part) {
253
+ const tether = Reflect.get(window, "Tether");
254
+ if (!isTetherInternals(tether)) {
255
+ throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
256
+ }
257
+ tether.__parts[name] = part;
258
+ }
259
+
243
260
  // src/parts/search.ts
244
- var { Tether } = window;
245
- if (!Tether) throw new Error("tether.search.js runs after the Tether script, which loads it");
246
- Tether.__parts.search = search_exports;
261
+ registerPart("search", search_exports);
247
262
  })();
@@ -1 +1 @@
1
- (()=>{var T=Object.defineProperty;var D=(i,t,e)=>t in i?T(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var V=(i,t)=>{for(var e in t)T(i,e,{get:t[e],enumerable:!0})};var a=(i,t,e)=>D(i,typeof t!="symbol"?t+"":t,e);var g={};V(g,{mountSearch:()=>W});var O=window.Tether.__core["config.ts"],[u,X,b,Z,tt,y,et]=O;var F=window.Tether.__core["client.ts"],[it,E,w,A,st]=F;var K=window.Tether.__core["dom.ts"],[at,I,ot,L,lt,x,m,ct,ht,ut,mt,C,h,q,l,M,v,d]=K;var Q=window.Tether.__core["mounting.ts"],[pt,ft,gt,St,Tt,R]=Q;var j=A({predictiveSearch:w({products:[{priceRange:"object"}],collections:["object"],queries:[{text:"string"}]})}),Y="query TetherPredictive($q:String!,$limit:Int!){predictiveSearch(query:$q,limit:$limit,limitScope:EACH,types:[PRODUCT,COLLECTION,QUERY]){products{id handle title availableForSale featuredImage{url altText}priceRange{minVariantPrice{amount currencyCode}}}collections{handle title image{url altText}}queries{text}}}",B=6,J=2,z="/search",N=new WeakSet,P=0;function _(i,t,e){return parseInt(m(i,t)||"",10)||e}var U=i=>i.tagName==="A"?i:i.querySelector("a");function p(i,t){h(i,l("search-bind")).forEach(e=>{let r=m(e,"search-bind");r==="image"?M(e,t.image?.url,t.image?.altText||t.title):(r==="title"||r==="price"||r==="text")&&t[r]!=null&&v(e,t[r])})}function k(i,t){let e=U(i);e&&(t&&e.setAttribute("href",t),e.setAttribute("role","option"))}var f=class{constructor(t,e,r){a(this,"root");a(this,"input");a(this,"results");a(this,"limit");a(this,"minCharacters");a(this,"resultsId");a(this,"searchNumber",0);a(this,"timer");a(this,"lastTerm","");a(this,"cache",new Map);this.root=t,this.input=e,this.results=r,this.limit=_(t,"search-limit",B),this.minCharacters=_(t,"search-min",J),r.id||(P+=1,r.id=`${u.prefix}-search-${P}`),this.resultsId=r.id,this.setUpAria(),this.listen()}setUpAria(){this.input.setAttribute("role","combobox"),this.input.setAttribute("aria-autocomplete","list"),this.input.setAttribute("aria-controls",this.resultsId),this.input.setAttribute("aria-expanded","false"),this.input.setAttribute("autocomplete","off"),this.results.hasAttribute("role")||this.results.setAttribute("role","listbox"),this.results.hidden=!0}listen(){this.input.addEventListener("input",()=>{let t=this.input.value.trim();t!==this.lastTerm&&(this.lastTerm=t,clearTimeout(this.timer),this.timer=setTimeout(()=>void this.search(t),u.searchDelay))}),this.input.addEventListener("focus",()=>{this.input.value.trim().length>=this.minCharacters&&this.options().length&&this.open(!0)}),this.input.addEventListener("keydown",t=>{this.onKeydown(t)}),document.addEventListener("click",t=>{this.root.contains(t.target)||this.open(!1)})}setState(t){this.root.setAttribute(I("search-state"),t)}open(t){this.root.classList.toggle("is-open",t),this.results.hidden=!t,this.input.setAttribute("aria-expanded",String(t)),t||this.input.removeAttribute("aria-activedescendant")}options(){return h(this.results,'[role="option"]')}async fetchResults(t){let e=this.cache.get(t);if(e)return e;let r=await E(Y,{q:t,limit:this.limit},j);return this.cache.set(t,r.predictiveSearch),r.predictiveSearch}async search(t){this.searchNumber+=1;let e=this.searchNumber;if(t.length<this.minCharacters){this.open(!1),this.setState("idle");return}this.setState("loading");try{let r=await this.fetchResults(t);e===this.searchNumber&&this.render(r,t)}catch(r){if(e!==this.searchNumber){b("a superseded search failed",r);return}this.setState("error"),y(r,"search")}}fillList(t,e,r){h(this.results,l(t)).forEach(o=>{q(o,e,r),d(o,e.length>0)})}queryUrl(t){let e=this.root.getAttribute("action")||z,r=e.includes("?")?"&":"?";return`${e}${r}${this.input.name||"q"}=${encodeURIComponent(t)}`}render(t,e){let r=t?.products??[],o=t?.collections??[],c=(t?.queries??[]).filter(n=>n.text.toLowerCase()!==e.toLowerCase());this.fillList("search-products",r,(n,s)=>{let H=x(s.priceRange.minVariantPrice);p(n,{title:s.title,price:H,image:s.featuredImage}),k(n,C(s.handle,s.id)),n.classList.toggle("is-sold-out",!s.availableForSale)}),this.fillList("search-collections",o,(n,s)=>{p(n,{title:s.title,image:s.image}),k(n,`${(u.collectionPath||"/collection").replace(/\/$/,"")}/${s.handle}`)}),this.fillList("search-queries",c,(n,s)=>{p(n,{text:s.text}),U(n)?.setAttribute("href",this.queryUrl(s.text))});let S=r.length+o.length+c.length;this.showCount(S),this.setState(S?"ready":"empty"),this.open(!0),L("search",{term:e,products:r,collections:o,queries:c},this.root)}showCount(t){h(this.root,l("show")).forEach(e=>{let r=m(e,"show");r==="search-empty"&&d(e,t===0),r==="search-results"&&d(e,t>0)}),this.options().forEach((e,r)=>{e.id||(e.id=`${this.resultsId}-${r}`),e.setAttribute("aria-selected","false")})}highlight(t,e){t.forEach((o,c)=>{o.setAttribute("aria-selected",String(c===e))});let r=t[e];r&&(this.input.setAttribute("aria-activedescendant",r.id),r.scrollIntoView?.({block:"nearest"}))}onKeydown(t){let e=this.options(),r=e.findIndex(o=>o.getAttribute("aria-selected")==="true");t.key==="ArrowDown"&&e.length?(t.preventDefault(),this.open(!0),this.highlight(e,(r+1)%e.length)):t.key==="ArrowUp"&&e.length?(t.preventDefault(),this.highlight(e,r<=0?e.length-1:r-1)):t.key==="Enter"&&r>=0?(t.preventDefault(),e[r]?.click()):t.key==="Escape"&&this.open(!1)}};function W(i=document){for(let t of R(i,l("search"))){if(N.has(t))continue;N.add(t);let e=t.querySelector(l("search-input"))??t.querySelector("input"),r=t.querySelector(l("search-results"));e&&r&&new f(t,e,r)}}var{Tether:$}=window;if(!$)throw new Error("tether.search.js runs after the Tether script, which loads it");$.__parts.search=g;})();
1
+ (()=>{var y=Object.defineProperty;var D=(i,t,e)=>t in i?y(i,t,{enumerable:!0,configurable:!0,writable:!0,value:e}):i[t]=e;var V=(i,t)=>{for(var e in t)y(i,e,{get:t[e],enumerable:!0})};var o=(i,t,e)=>D(i,typeof t!="symbol"?t+"":t,e);var w={};V(w,{mountSearch:()=>Z});var F=window.Tether.__core["config.ts"],[u,tt,b,et,rt,S,it]=F;var j=window.Tether.__core["client.ts"],[st,E,x,A,ot]=j;var K=window.Tether.__core["dom.ts"],[lt,I,ct,L,ht,k,m,ut,mt,dt,pt,N,h,R,l,C,P,d]=K;var Q=window.Tether.__core["mounting.ts"],[gt,wt,Tt,yt,bt,q]=Q;var Y=A({predictiveSearch:x({products:[{priceRange:"object"}],collections:["object"],queries:[{text:"string"}]})}),B="query TetherPredictive($q:String!,$limit:Int!){predictiveSearch(query:$q,limit:$limit,limitScope:EACH,types:[PRODUCT,COLLECTION,QUERY]){products{id handle title availableForSale featuredImage{url altText}priceRange{minVariantPrice{amount currencyCode}}}collections{handle title image{url altText}}queries{text}}}",J=6,z=2,W="/search",M=new WeakSet,_=0;function $(i,t,e){return parseInt(m(i,t)||"",10)||e}var H=i=>i.tagName==="A"?i:i.querySelector("a");function f(i,t){h(i,l("search-bind")).forEach(e=>{let r=m(e,"search-bind");r==="image"?C(e,t.image?.url,t.image?.altText||t.title):(r==="title"||r==="price"||r==="text")&&t[r]!=null&&P(e,t[r])})}function U(i,t){let e=H(i);e&&(t&&e.setAttribute("href",t),e.setAttribute("role","option"))}var g=class{constructor(t,e,r){o(this,"root");o(this,"input");o(this,"results");o(this,"limit");o(this,"minCharacters");o(this,"resultsId");o(this,"searchNumber",0);o(this,"timer");o(this,"lastTerm","");o(this,"cache",new Map);this.root=t,this.input=e,this.results=r,this.limit=$(t,"search-limit",J),this.minCharacters=$(t,"search-min",z),r.id||(_+=1,r.id=`${u.prefix}-search-${_}`),this.resultsId=r.id,this.setUpAria(),this.listen()}setUpAria(){this.input.setAttribute("role","combobox"),this.input.setAttribute("aria-autocomplete","list"),this.input.setAttribute("aria-controls",this.resultsId),this.input.setAttribute("aria-expanded","false"),this.input.setAttribute("autocomplete","off"),this.results.hasAttribute("role")||this.results.setAttribute("role","listbox"),this.results.hidden=!0}listen(){this.input.addEventListener("input",()=>{let t=this.input.value.trim();t!==this.lastTerm&&(this.lastTerm=t,clearTimeout(this.timer),this.timer=setTimeout(()=>void this.search(t),u.searchDelay))}),this.input.addEventListener("focus",()=>{this.input.value.trim().length>=this.minCharacters&&this.options().length&&this.open(!0)}),this.input.addEventListener("keydown",t=>{this.onKeydown(t)}),document.addEventListener("click",t=>{this.root.contains(t.target)||this.open(!1)})}setState(t){this.root.setAttribute(I("search-state"),t)}open(t){this.root.classList.toggle("is-open",t),this.results.hidden=!t,this.input.setAttribute("aria-expanded",String(t)),t||this.input.removeAttribute("aria-activedescendant")}options(){return h(this.results,'[role="option"]')}async fetchResults(t){let e=this.cache.get(t);if(e)return e;let r=await E(B,{q:t,limit:this.limit},Y);return this.cache.set(t,r.predictiveSearch),r.predictiveSearch}async search(t){this.searchNumber+=1;let e=this.searchNumber;if(t.length<this.minCharacters){this.open(!1),this.setState("idle");return}this.setState("loading");try{let r=await this.fetchResults(t);e===this.searchNumber&&this.render(r,t)}catch(r){if(e!==this.searchNumber){b("a superseded search failed",r);return}this.setState("error"),S(r,"search")}}fillList(t,e,r){h(this.results,l(t)).forEach(a=>{R(a,e,r),d(a,e.length>0)})}queryUrl(t){let e=this.root.getAttribute("action")||W,r=e.includes("?")?"&":"?";return`${e}${r}${this.input.name||"q"}=${encodeURIComponent(t)}`}render(t,e){let r=t?.products??[],a=t?.collections??[],c=(t?.queries??[]).filter(s=>s.text.toLowerCase()!==e.toLowerCase());this.fillList("search-products",r,(s,n)=>{let O=k(n.priceRange.minVariantPrice);f(s,{title:n.title,price:O,image:n.featuredImage}),U(s,N(n.handle,n.id)),s.classList.toggle("is-sold-out",!n.availableForSale)}),this.fillList("search-collections",a,(s,n)=>{f(s,{title:n.title,image:n.image}),U(s,`${(u.collectionPath||"/collection").replace(/\/$/,"")}/${n.handle}`)}),this.fillList("search-queries",c,(s,n)=>{f(s,{text:n.text}),H(s)?.setAttribute("href",this.queryUrl(n.text))});let T=r.length+a.length+c.length;this.showCount(T),this.setState(T?"ready":"empty"),this.open(!0),L("search",{term:e,products:r,collections:a,queries:c},this.root)}showCount(t){h(this.root,l("show")).forEach(e=>{let r=m(e,"show");r==="search-empty"&&d(e,t===0),r==="search-results"&&d(e,t>0)}),this.options().forEach((e,r)=>{e.id||(e.id=`${this.resultsId}-${r}`),e.setAttribute("aria-selected","false")})}highlight(t,e){t.forEach((a,c)=>{a.setAttribute("aria-selected",String(c===e))});let r=t[e];r&&(this.input.setAttribute("aria-activedescendant",r.id),r.scrollIntoView?.({block:"nearest"}))}onKeydown(t){let e=this.options(),r=e.findIndex(a=>a.getAttribute("aria-selected")==="true");t.key==="ArrowDown"&&e.length?(t.preventDefault(),this.open(!0),this.highlight(e,(r+1)%e.length)):t.key==="ArrowUp"&&e.length?(t.preventDefault(),this.highlight(e,r<=0?e.length-1:r-1)):t.key==="Enter"&&r>=0?(t.preventDefault(),e[r]?.click()):t.key==="Escape"&&this.open(!1)}};function Z(i=document){for(let t of q(i,l("search"))){if(M.has(t))continue;M.add(t);let e=t.querySelector(l("search-input"))??t.querySelector("input"),r=t.querySelector(l("search-results"));e&&r&&new g(t,e,r)}}function p(i){return i!==null&&typeof i=="object"&&!Array.isArray(i)}function G(i){return p(i)&&p(i.__core)&&p(i.__parts)}function v(i,t){let e=Reflect.get(window,"Tether");if(!G(e))throw new Error(`tether.${i}.js runs after the Tether script, which loads it, and needs its window.Tether`);e.__parts[i]=t}v("search",w);})();
@@ -0,0 +1,2 @@
1
+ /** A Storefront cart id: what the browser keeps for the visitor's cart and sends the Worker to link or unlink it. */
2
+ export declare const CART_ID: RegExp;
@@ -26,6 +26,12 @@ export interface CartLineInput {
26
26
  * a line it refused), after which the saved cart is still good.
27
27
  */
28
28
  export declare function isCartGone(error: unknown): boolean;
29
+ /**
30
+ * @returns True when a change failed without saying whether Shopify applied it: no answer or no whole body came (the
31
+ * network), a 2xx whose body isn't valid, or a server error (a 5xx, or a 2xx with `SERVER_ERROR`), which can come
32
+ * after the change was committed. Shopify's user errors and a 4xx are clear.
33
+ */
34
+ export declare function isUnclearFailure(error: unknown): boolean;
29
35
  /**
30
36
  * @param input A variant id, or a line.
31
37
  * @param quantity For a variant id.
@@ -136,8 +136,11 @@ export declare const cartStatus: () => CartStatus;
136
136
  /** The cart as Shopify last sent it. */
137
137
  export declare function currentCart(): ShopifyCart | null;
138
138
  export declare const currentWarnings: () => readonly CartWarning[];
139
- /** The id of the visitor's cart, kept across pages. */
140
- export declare const savedCartId: () => string | null;
139
+ /**
140
+ * The id of the visitor's cart, kept across pages. A stored value that isn't a cart id (written by another script,
141
+ * or edited by hand) is forgotten, so it is never sent to Shopify or the Worker and the next change starts a new cart.
142
+ */
143
+ export declare function savedCartId(): string | null;
141
144
  /** Forgets the saved cart, which Shopify no longer has. */
142
145
  export declare function forgetSavedCart(): void;
143
146
  /** Keeps a cart Shopify sent without showing it, for an answer a newer change will replace. */
@@ -1,6 +1,6 @@
1
1
  import { checkout, setCheckoutResolver } from './cart/checkout.js';
2
2
  import { isOpen, openCart, closeCart, toggleCart, trapFocus } from './cart/drawer.js';
3
- import { render, subscribe } from './cart/store.js';
3
+ import { render, savedCartId, subscribe } from './cart/store.js';
4
4
  import type { CartWarning } from './config.js';
5
5
  import type { Attributes, LineSpec, LinePatch } from './cart/mutations.js';
6
6
  import type { ShopifyCart, ShopifyCartLine, CartStatus } from './cart/store.js';
@@ -20,7 +20,7 @@ declare function init(): Promise<ShopifyCart | null>;
20
20
  export declare const Cart: {
21
21
  init: typeof init;
22
22
  /** The saved cart's id. */
23
- id: () => string | null;
23
+ id: typeof savedCartId;
24
24
  readonly status: CartStatus;
25
25
  readonly state: ShopifyCart | null;
26
26
  /** The cart's lines, a copy: changing it changes nothing in the cart. */
@@ -68,6 +68,7 @@ export declare const Cart: {
68
68
  /** The quantity to show: the one asked for while an update is on its way. */
69
69
  quantityOf: (line: ShopifyCartLine) => number;
70
70
  removeLine(lineIds: string | string[]): Promise<ShopifyCart | null>;
71
+ /** Removes the lines the cart has when the change runs, so one queued just before it is cleared too. */
71
72
  clear(): Promise<ShopifyCart | null>;
72
73
  setNote(note: string | null | undefined): Promise<ShopifyCart | null>;
73
74
  /**
@@ -1,5 +1,5 @@
1
1
  import type { TetherConfig } from './config.js';
2
- export type TetherErrorCode = 'NOT_FOUND' | 'NETWORK' | 'NOT_CONFIGURED' | 'NOT_LOGGED_IN' | 'INVALID' | 'INVALID_COUNTRY' | 'INVALID_DISCOUNT' | 'ERROR' | `HTTP_${number}`;
2
+ export type TetherErrorCode = 'NOT_FOUND' | 'NETWORK' | 'NOT_CONFIGURED' | 'NOT_LOGGED_IN' | 'INVALID' | 'INVALID_COUNTRY' | 'INVALID_DISCOUNT' | 'INVALID_RESPONSE' | 'SERVER_ERROR' | 'ERROR' | `HTTP_${number}`;
3
3
  export interface GraphQLError {
4
4
  message: string;
5
5
  extensions?: {
@@ -13,20 +13,20 @@ export interface UserError {
13
13
  }
14
14
  interface TetherErrorDetails {
15
15
  /** Default `HTTP_<status>` with a status, else `ERROR`. */
16
- code?: TetherErrorCode;
16
+ code?: TetherErrorCode | undefined;
17
17
  /** The HTTP status of the response that failed. */
18
18
  status?: number;
19
19
  /** The GraphQL errors of that response. */
20
- errors?: GraphQLError[];
20
+ errors?: readonly GraphQLError[];
21
21
  /** A mutation's user errors. */
22
22
  userErrors?: readonly UserError[];
23
23
  }
24
24
  export declare class TetherError extends Error {
25
- name: "TetherError";
26
- code: TetherErrorCode;
27
- status: number | undefined;
28
- errors: GraphQLError[] | undefined;
29
- userErrors: readonly UserError[] | undefined;
25
+ readonly name: "TetherError";
26
+ readonly code: TetherErrorCode;
27
+ readonly status: number | undefined;
28
+ readonly errors: readonly GraphQLError[] | undefined;
29
+ readonly userErrors: readonly UserError[] | undefined;
30
30
  constructor(message: string, { status, errors, userErrors, code }?: TetherErrorDetails);
31
31
  }
32
32
  /** What a request needs from a config: the browser's `cfg`, or a config the server helpers build. */
@@ -38,20 +38,46 @@ export type DataCheck<T> = (data: unknown) => data is T;
38
38
  /**
39
39
  * The structure of JSON a check accepts: a `typeof` name, `'object'` for a plain object, `[item]` for a list of
40
40
  * items, an object's fields, or a check of its own. Fields it doesn't name aren't checked, so a shape names only what
41
- * its reader walks without a fallback.
41
+ * its reader walks without a fallback. A field's `undefined` is the type of one `ShapeOf` leaves out, and checks
42
+ * nothing.
42
43
  */
43
44
  export type Shape = 'string' | 'number' | 'boolean' | 'object' | ((value: unknown) => boolean) | readonly [Shape] | {
44
- readonly [key: string]: Shape;
45
+ readonly [key: string]: Shape | undefined;
45
46
  };
46
47
  /** @returns True when `value` has the structure `shape` describes. */
47
48
  export declare function matches(value: unknown, shape: Shape): boolean;
48
- /** @returns The shape of `null` or a value with the structure `shape` describes. */
49
- export declare const orNull: (shape: Shape) => (value: unknown) => boolean;
50
- /** @returns A check that `data` has the structure `shape` describes, which `T` states. */
51
- export declare const shaped: <T>(shape: Shape) => DataCheck<T>;
52
- /** `context: false` sends the query without `@inContext`. */
49
+ /**
50
+ * The shapes that describe a `T`: every structure such a shape names is one `T` declares at that place, and a check
51
+ * in it is a type guard for a type `T` accepts there. A shape for `T` therefore can't name a field `T` lacks or claim
52
+ * a type `T` contradicts, so a change to `T` that its shape no longer agrees with fails to compile. Fields of `T` the
53
+ * shape doesn't name stay unchecked (`Shape`).
54
+ */
55
+ export type ShapeOf<T> = unknown extends T ? Shape : KnownShapeOf<T>;
56
+ type KnownShapeOf<T> = DataCheck<T> | (string extends T ? 'string' : never) | (number extends T ? 'number' : never) | (boolean extends T ? 'boolean' : never) | ListShapeOf<T> | FieldsShapeOf<T>;
57
+ type ListShapeOf<T> = T extends readonly (infer Item)[] ? readonly [ShapeOf<Item>] : never;
58
+ type FieldsShapeOf<T> = T extends readonly unknown[] ? never : T extends object ? 'object' | {
59
+ readonly [Key in keyof T]?: ShapeOf<T[Key]>;
60
+ } : never;
61
+ /** @returns A check that `value` is `null` or has the structure `shape` describes. */
62
+ export declare const orNull: <T>(shape: ShapeOf<T>) => DataCheck<T | null>;
63
+ /**
64
+ * @returns A check that `data` has the structure `shape` describes. `ShapeOf` ties `shape` to `T`; fields `shape`
65
+ * doesn't name are `T`'s claim.
66
+ */
67
+ export declare const shaped: <T>(shape: ShapeOf<T>) => DataCheck<T>;
68
+ /**
69
+ * What an operation does to the store, which decides what is safe to retry. A query only reads, so a failure that may
70
+ * pass is retried: the network (no answer, or a body that stopped arriving), a 429, a 5xx, `THROTTLED` and
71
+ * `INTERNAL_SERVER_ERROR`. Shopify may have applied a mutation before a server error or a dropped connection, so a
72
+ * mutation is retried only when Shopify answers that it didn't run it (429 or `THROTTLED`): sending it again could add
73
+ * a line twice. Other failures (a 4xx, a 430, an answer that isn't valid, other GraphQL errors) are never retried.
74
+ */
75
+ export type Operation = 'query' | 'mutation';
53
76
  interface RequestOptions {
77
+ /** `false` sends the query without `@inContext`. */
54
78
  context?: boolean;
79
+ /** Default `'query'`. */
80
+ operation?: Operation;
55
81
  }
56
82
  /** What the store's token may read beyond the defaults. */
57
83
  export interface StoreAccess {
@@ -59,11 +85,17 @@ export interface StoreAccess {
59
85
  }
60
86
  /**
61
87
  * A query's text, or a function that writes it for what the token may read: Tether's own queries, built from
62
- * `fragments.ts`, leave out inventory for a token that can't read it.
88
+ * `fragments.ts`, leave out inventory for a token that can't read it. Documents Tether didn't write are strings.
63
89
  */
64
90
  export type QueryText = string | ((access: StoreAccess) => string);
65
91
  /** @returns The Storefront GraphQL endpoint of `conf`'s store. */
66
92
  export declare function endpoint(conf?: Pick<TetherConfig, 'domain' | 'apiVersion'>): string;
93
+ /**
94
+ * The operation of a document Tether didn't write (`Tether.query()`, the server's `query()`). Outside strings and
95
+ * comments, any `mutation` keyword makes it a mutation: a document that starts with a fragment still has its
96
+ * operation found, and a misread errs on the side that is never sent twice.
97
+ */
98
+ export declare function operationOf(document: string): Operation;
67
99
  /**
68
100
  * `inContext` for any country and language, as the public `Tether.withContext` takes them: one that isn't a valid
69
101
  * code is left out, so page input never becomes query text.
@@ -76,19 +108,26 @@ export declare function withContext(query: string, ctx?: {
76
108
  * One Storefront API request, for any config: the browser's shared one (`gql`) or one the server helpers build.
77
109
  * Queries carry a time bucket so Shopify's cache of an identical query text is at most `maxAge` seconds old. A query
78
110
  * written for the store's access leaves out inventory once the token turns out not to read it (`INVENTORY_FIELD`);
79
- * a fixed query text is the caller's own, and that refusal is its error.
111
+ * a fixed query text is the caller's own, and that refusal is its error, as is a refusal of a text written without
112
+ * inventory, so the refusal costs at most one extra request. How often a failure is retried is
113
+ * `conf.retries`; which failures are retried is the operation's (`Operation`).
80
114
  *
81
115
  * @param isData Checks that `data` has what the caller then reads, so a malformed answer fails here.
82
- * @throws {TetherError} `NOT_CONFIGURED` without a domain or token, `NETWORK` when the store can't be reached,
83
- * `HTTP_<status>` for an HTTP or GraphQL failure, or for `data` that `isData` refuses.
116
+ * @throws {TetherError} `NOT_CONFIGURED` without a domain or token, `NETWORK` when the store can't be reached or
117
+ * the answer's body stops arriving, `INVALID_RESPONSE` for a 2xx whose body isn't valid (not JSON, not in the
118
+ * GraphQL shape, or `data` that `isData` refuses), `SERVER_ERROR` for a 2xx whose GraphQL errors leave open
119
+ * whether Shopify ran it (a top-level `INTERNAL_SERVER_ERROR`, or a mutation's errors without `data`),
120
+ * `HTTP_<status>` for any other HTTP or GraphQL failure.
84
121
  */
85
- export declare function request<T>(conf: StorefrontConfig, query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, { context }?: RequestOptions): Promise<T>;
122
+ export declare function request<T>(conf: StorefrontConfig, query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, { context, operation }?: RequestOptions): Promise<T>;
86
123
  /** `request` with the browser's shared config. */
87
124
  export declare function gql<T>(query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, options?: RequestOptions): Promise<T>;
88
125
  /** The check of `Tether.query()` and the server's `query()`, whose callers read `data` themselves. */
89
126
  export declare const hasData: (data: unknown) => data is object;
90
- /** `Tether.query()`: the caller's own query text decides the shape of `data`, and the caller's `T` states it. */
91
- export declare function query<T>(text: QueryText, variables?: Record<string, unknown>, options?: RequestOptions): Promise<T>;
127
+ /** `Tether.query()` and the server's `query()`: a document Tether didn't write, sent with `conf`. */
128
+ export declare function untypedQuery<T>(conf: StorefrontConfig, text: string, variables?: Record<string, unknown>, options?: Omit<RequestOptions, 'operation'>): Promise<T>;
129
+ /** `Tether.query()`: `untypedQuery` with the browser's shared config. */
130
+ export declare function query<T>(text: string, variables?: Record<string, unknown>, options?: Omit<RequestOptions, 'operation'>): Promise<T>;
92
131
  /**
93
132
  * @param payload A mutation's payload.
94
133
  * @param name The mutation, for the error message.
@@ -91,7 +91,12 @@ export interface TetherConfig {
91
91
  sellingPlanGroupsFirst: number;
92
92
  sellingPlansFirst: number;
93
93
  collectionFirst: number;
94
- /** Retries of a request that failed on the network, a 429/5xx or Shopify's throttling. */
94
+ /**
95
+ * How many times a failed request is sent again. A query is retried after a network error (no answer, or a body that
96
+ * stopped arriving), a 429, a 5xx or Shopify's `THROTTLED`. A mutation, a cart change included, is retried only
97
+ * after a 429 or `THROTTLED`, which Shopify sends without running it: after a network error or a 5xx it may
98
+ * already have applied the change.
99
+ */
95
100
  retries: number;
96
101
  /** Refresh server-rendered products once in the background. */
97
102
  revalidate: boolean;
@@ -33,7 +33,7 @@ export type { AddressFields as CustomerAddressInput } from './account/operations
33
33
  export type { CustomerAddress, Fulfillment, MailingAddress, OrderDetail, OrderDetailLine, SubscriptionContract, SubscriptionLine, } from './account/page-answers.js';
34
34
  /** The helpers for selling plans, `Tether.plans`. */
35
35
  export type SellingPlanHelpers = typeof plans;
36
- export declare const VERSION = "0.7.0";
36
+ export declare const VERSION = "0.7.2";
37
37
  /**
38
38
  * Mounts every product scope and product list inside `root`. Safe to call repeatedly.
39
39
  *
@@ -70,7 +70,7 @@ declare const publicApi: {
70
70
  withContext: typeof withContext;
71
71
  cart: {
72
72
  init: () => Promise<ShopifyCart | null>;
73
- id: () => string | null;
73
+ id: typeof import("./cart/store.js").savedCartId;
74
74
  readonly status: import("./cart/store.js").CartStatus;
75
75
  readonly state: ShopifyCart | null;
76
76
  readonly lines: import("./cart/store.js").ShopifyCartLine[];
@@ -50,8 +50,15 @@ export interface Localization {
50
50
  /** The localStorage key of the visitor's market: `<prefix>:market:<domain>`. */
51
51
  export declare const storageKey: () => string;
52
52
  /**
53
- * The visitor's saved market (`setCountry()`, `tether-country-select`), validated: storage is written by other tabs,
54
- * older versions and other scripts too.
53
+ * A market as `rememberMarket` stores it, validated: storage is written by other tabs, older versions and other
54
+ * scripts too.
55
+ *
56
+ * @param text The value stored under `storageKey()`.
57
+ * @returns `null` when it isn't a valid market.
58
+ */
59
+ export declare const parseSavedMarket: (text: string) => Market | null;
60
+ /**
61
+ * The visitor's saved market (`setCountry()`, `tether-country-select`).
55
62
  *
56
63
  * @param storage Default `localStorage`.
57
64
  * @returns `null` when nothing valid is saved.
@@ -85,4 +85,6 @@ export declare const isProductShape: (value: unknown) => value is Product;
85
85
  * A node a lookup by gid answers: a product, or a node of another type, for which `... on Product` selects no field
86
86
  * (no `id`).
87
87
  */
88
- export declare const PRODUCT_NODE: (node: unknown) => boolean;
88
+ export declare const PRODUCT_NODE: (node: unknown) => node is Product | {
89
+ id?: undefined;
90
+ };
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Decoding of percent-escaped text the page hands Tether (a path segment, a cookie value), which nothing guarantees
3
+ * is well formed.
4
+ */
5
+ /** @returns `text` decoded, or as written when it has a malformed escape (`%E0%A4%A`). */
6
+ export declare function decodeOrKeep(text: string): string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@occluze/tether",
3
- "version": "0.7.0",
3
+ "version": "0.7.2",
4
4
  "description": "Free, open-source alternative to Smootify and Storesynk (Shopyflow): Shopify products, cart and subscriptions in Webflow with HTML attributes. Optional Shopify to Webflow CMS sync.",
5
5
  "type": "module",
6
6
  "main": "dist/esm/index.js",
@@ -26,7 +26,6 @@
26
26
  },
27
27
  "files": [
28
28
  "dist",
29
- "src",
30
29
  "LICENSE",
31
30
  "README.md"
32
31
  ],
@@ -38,17 +37,17 @@
38
37
  "lint": "eslint .",
39
38
  "typecheck": "tsc -b",
40
39
  "knip": "knip",
41
- "deps": "depcruise src server/src server/bin server/scripts scripts",
40
+ "deps": "depcruise --config .config/dependency-cruiser.cjs src server/src server/bin server/scripts scripts",
42
41
  "check": "npm run format:check && npm run lint && npm run typecheck && npm run knip && npm run deps && npm test",
43
42
  "prepare": "lefthook install",
44
43
  "test": "node --experimental-strip-types --test test/*.test.js server/test/*.test.js && npm run test:types",
45
- "test:types": "tsc -p types/tsconfig.json",
44
+ "test:types": "tsc -p test/types/tsconfig.json",
46
45
  "smoke": "node --experimental-strip-types scripts/smoke.ts",
47
46
  "pretest": "node --experimental-strip-types scripts/build.ts --out .test-dist",
48
47
  "presmoke": "node --experimental-strip-types scripts/build.ts",
49
48
  "release": "node --experimental-strip-types scripts/release.ts",
50
- "e2e:build": "npm run build && cd examples/astro && (test -f .env || cp .env.example .env) && npm install --no-audit --no-fund && npm install --no-save ../.. && npx astro build",
51
- "e2e": "npm run e2e:build && playwright test -c e2e/playwright.config.js"
49
+ "e2e:build": "npm run build && cd examples/astro && (test -f .env || cp .env.example .env) && npm install --no-save --no-audit --no-fund --ignore-scripts ../.. && npx astro build",
50
+ "e2e": "npm run e2e:build && playwright test -c test/e2e/playwright.config.js"
52
51
  },
53
52
  "devDependencies": {
54
53
  "@eslint/js": "10.0.1",
@@ -119,5 +118,54 @@
119
118
  },
120
119
  "engines": {
121
120
  "node": ">=22.18"
121
+ },
122
+ "prettier": {
123
+ "printWidth": 120,
124
+ "singleQuote": true,
125
+ "trailingComma": "all",
126
+ "overrides": [
127
+ {
128
+ "files": "*.md",
129
+ "options": {
130
+ "embeddedLanguageFormatting": "off"
131
+ }
132
+ },
133
+ {
134
+ "files": "CHANGELOG.md",
135
+ "options": {
136
+ "proseWrap": "always",
137
+ "printWidth": 100
138
+ }
139
+ }
140
+ ]
141
+ },
142
+ "knip": {
143
+ "entry": [
144
+ "src/index.ts",
145
+ "src/server.ts",
146
+ "src/astro.ts",
147
+ "src/presets/barba.ts",
148
+ "src/parts/*.ts",
149
+ "src/lazy-iife.ts",
150
+ "server/src/entry.{js,ts}",
151
+ "server/src/index.ts",
152
+ "server/bin/tether-sync.{js,ts}",
153
+ "server/scripts/*.{mjs,ts}",
154
+ "scripts/*.ts",
155
+ "test/**/*.js",
156
+ "server/test/**/*.js",
157
+ "test/e2e/*.{js,mjs}",
158
+ "test/types/check.ts"
159
+ ],
160
+ "project": [
161
+ "src/**/*.ts",
162
+ "server/src/**/*.{js,ts}",
163
+ "server/bin/*.{js,ts}",
164
+ "server/scripts/*.{mjs,ts}",
165
+ "scripts/*.ts"
166
+ ],
167
+ "ignoreBinaries": [
168
+ "tsc"
169
+ ]
122
170
  }
123
171
  }
@@ -1 +0,0 @@
1
- import{a as A}from"./chunk-56FCLJJD.js";import"./chunk-T44MUL4Y.js";import"./chunk-MPDWM2NN.js";import{e as h}from"./chunk-A5SYCVQM.js";import"./chunk-BFTZR4OB.js";import{d as k,h as E,m as p,r as _,s as w}from"./chunk-BA4LQJJQ.js";import{r as a,x as T,z as l}from"./chunk-E5YO6274.js";var F=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"},O="https://cdn.shopify.com/storefront/analytics/shopify.js",x=()=>window,m=()=>x().Shopify;function L(){let t=a.analytics?.shopify;return typeof t=="object"?t:{}}function I(){try{let t=m()?.customerPrivacy;return t?.consentStatus==="loaded"&&t.currentVisitorConsent?.()?.analytics!=="no"&&!!t.analyticsProcessingAllowed?.()}catch{return!1}}function j(t){let e=`hydrogen:${t}`;return{getTrackingValues:()=>{let n=I()?m()?.customerPrivacy?.__internal:void 0;return{uniqueToken:n?.uniqueToken?.({generateFallback:!0,tag:e})??"",visitToken:n?.visitToken?.({generateFallback:!0,tag:e})??""}}}}var $=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 U(t){let e=[],n=[],i={shop:{shopId:t,channel:"headless"},consent:{mode:L().consent||"no-banner"}},o=()=>{if(I())for(let r of e)for(;r.next<n.length;r.next+=1){let s=n[r.next];s&&G(r,s)}},c={getConfig:()=>i,publish(r,s={}){if(n.push({event:r,payload:{shop:i.shop,url:window.location.href,...s}}),n.length>F){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:j(r.name)};return Promise.resolve(r.setup?.({subscribe:$(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 G(t,{event:e,payload:n}){t.subscribers.get(e)?.forEach(i=>{try{i(n,t.context)}catch(o){l(o,`analytics ${t.name}`)}})}function P(t){let e=document.createElement("script");e.src=t,e.async=!0,document.head.appendChild(e)}async function R(t){let e=m();if(e?.analytics)return e.analytics;let n=await E("query TetherShopId { shop { id } }",{},k({shop:{id:"string"}}),{context:!1}),i=m()??{};x().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}=L();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=U(n.shop.id);return i.analytics=s,P(r==="default-banner"?S["default-banner"]:S.other),P(O),T("shopify analytics ready",n.shop.id),s}var W="Default Title",V=100,H=200,Y=t=>t?parseFloat(t.amount):0,N=t=>(t??"").split("/").pop()??"";function C(t,e,n=1,i){let o={item_id:e?.sku||N(e?.id)||N(t.id),item_name:t.title,item_variant:e?.title===W?void 0:e?.title,item_brand:t.vendor||void 0,item_category:t.productType||void 0,price:Y(e?.price??t.priceRange?.minVariantPrice),quantity:n};return i!=null&&(o.index=i),o}var g=(t,e=t.quantity)=>C(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 X=(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}),D=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 Z(){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 z(t,e){let n=Z();if(!e){n.push({event:t});return}n.push({ecommerce:null}),n.push({event:t,ecommerce:e})}var y=null,v=null,q=null,b=new WeakSet;function u(t,e,n,i){a.analytics?.dataLayer&&z(t,e),y&&n&&y.publish(n,i);try{a.analytics?.onEvent?.(t,e)}catch(o){l(o,"analytics onEvent")}}function M(){let t=document.querySelector(p("product"));return!t||t.closest(`${p("collection")},${p("products")},${p("recommendations")}`)?null:A.get(t)??null}function J({product:t,scope:e}){if(b.has(e.root)||M()!==e)return;b.add(e.root);let n=e.variant??t.variants.nodes[0],i=[C(t,n)],o=n?[X(t,n)]:[];u("view_item",{currency:n?.price.currencyCode,value:f(i),items:i},"product_viewed",{products:o})}function K({products:t,collection:e}){let n=t.slice(0,H).map((o,c)=>C(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 Q(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=[g(o,s)];u("add_to_cart",{currency:i,value:f(d),items:d},"product_added_to_cart",{cart:t,prevCart:q,currentLine:D(o),prevLine:r?D(r):void 0})}),n.forEach((o,c)=>{let r=o.quantity-(e.get(c)?.quantity??0);if(r<=0)return;let s=[g(o,r)];u("remove_from_cart",{currency:i,value:f(s),items:s})})}function tt({cart:t,reason:e}){let n=new Map((t?.lines.nodes??[]).map(i=>[i.merchandise.id,i]));v&&e!=="load"&&e!=="pending"&&Q(t,n,v),v=n,q=t}function et(){let t=h.lines.map(e=>g(e));u("view_cart",{currency:h.state?.cost.totalAmount.currencyCode,value:f(t),items:t})}function nt({cart:t}){if(!t)return;let e=t.lines.nodes.map(i=>g(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 it={"product-ready":J,"list-ready":K,"cart-updated":tt,"cart-toggled":({open:t})=>{t&&et()},checkout:nt,search:({term:t})=>{t&&u("search",{search_term:t},"search_viewed",{searchTerm:t})}};function ot(t,e){it[e](t.detail)}function B(t){if(t.type==="astro:page-load"){b=new WeakSet,y?.publish("page_viewed",{});return}_.forEach(e=>{w(t,e)&&ot(t,e)})}async function ft(t){a.analytics?.shopify&&(y=await R(()=>M()!=null).catch(e=>(l(e,"shopify analytics"),null))),y?.publish("page_viewed",{}),t.splice(0).forEach(B),t.push=(...e)=>(e.forEach(B),t.length)}export{ft as startAnalytics};
@@ -1 +0,0 @@
1
- import{a as M,b as z,c as H,d as C,e as Z,f as tt,g as et,h as nt,i as it}from"./chunk-T44MUL4Y.js";import{b as $,e as rt}from"./chunk-MPDWM2NN.js";import{e as Y}from"./chunk-A5SYCVQM.js";import{g as J,h as N,i as S,n as K}from"./chunk-BFTZR4OB.js";import{A as D,B,C as L,D as U,E as G,F as d,H as x,I,K as V,L as j,M as Q,N as W,O as X,l as p,m as o,n as l,o as T,p as f,q as R,t as v,v as _,w as g,x as F,y}from"./chunk-BA4LQJJQ.js";import{b as h,r as A,z as w}from"./chunk-E5YO6274.js";var ft=/^image:(\d+)$/,at="metafield:",gt=/^(rich_text|multi_line_text)_field$/,vt=["","true","all","*"],q=t=>t.tagName==="SELECT",b=(t,e)=>t.$(`select${e}`).filter(q);function bt(t,e){let n=e.images.nodes,i=[...t.children].map(a=>a.tagName==="IMG"?a:a.querySelector("img"));!F(t)&&i.length===n.length&&i.every((a,s)=>_(a?.getAttribute("src"),n[s]?.url))||y(t,n,(a,s)=>{let c=a.matches(`img,${o("bind","image")}`)?a:f(a,"img")[0]??a;g(c,s.url,s.altText||e.title)})}function Et(t,e,n){let i=n.indexOf("."),r=n.slice(0,i),a=n.slice(i+1),s=(e.metafields??[]).find(u=>u?.namespace===r&&u.key===a);if(!s){d(t,"");return}let c=s.reference?.image;if(c){g(t,c.url,c.altText);return}gt.test(s.type)&&(t.style.whiteSpace="pre-line"),d(t,s.value)}var Pt=new Map(Object.entries({title:t=>t.title,"description-text":t=>t.description,vendor:t=>t.vendor,type:t=>t.productType,handle:t=>t.handle,"published-at":t=>U(t.publishedAt),"min-price":t=>L(t.priceRange.minVariantPrice),"max-price":t=>L(t.priceRange.maxVariantPrice)}));function Tt(t,e){let n=(t.getAttribute("exclude")??"").split(",").map(r=>r.trim()).filter(Boolean),i=e.tags.filter(r=>!n.includes(r));y(t,i,(r,a)=>{d(r,a)})}function yt(t,e,n){let i=Pt.get(e);if(i){d(t,i(n));return}switch(e){case"description":G(t,n.descriptionHtml);break;case"featured-image":g(t,n.featuredImage?.url,n.featuredImage?.altText||n.title);break;case"url":case"link":{let r=D(n.handle,n.id);r&&t.setAttribute("href",r),e==="url"&&!t.firstElementChild&&!t.textContent.trim()&&d(t,n.title);break}case"images":bt(t,n);break;case"tags":Tt(t,n);break;default:Lt(t,e,n)}}function Lt(t,e,n){let i=ft.exec(e);if(i){let r=n.images.nodes[Number(i[1])-1]??n.featuredImage;g(t,r?.url,r?.altText||n.title)}else e.startsWith(at)&&Et(t,n,e.slice(at.length))}function xt(t){let{product:e}=t;t.$(o("option-list")).forEach(n=>{let i=t.optName(l(n,"option-list")),r=e.options.find(a=>a.name===i);if(!r||r.optionValues.length<=1&&T(n,"hide-single")){x(n,!1);return}y(n,r.optionValues,(a,s)=>{a.setAttribute(p("option-value"),s.name);let c=f(a,o("bind","option-value"))[0];c?d(c,s.name):a.firstElementChild||d(a,s.name);let u=f(a,o("bind","swatch"))[0],{swatch:m}=s;!u||!m||(m.color&&(u.style.backgroundColor=m.color),m.image?.previewImage&&g(u,m.image.previewImage.url,s.name))})})}function It(t){let{product:e}=t;b(t,o("option")).forEach(n=>{let i=e.options.find(r=>r.name===t.optName(l(n,"option")));if(!i){x(n,!1);return}n.replaceChildren(...i.optionValues.map(r=>new Option(r.name,r.name)))}),b(t,o("variant-select")).forEach(n=>{n.replaceChildren(...e.variants.nodes.map(i=>new Option(i.title,i.id)))}),b(t,o("plan")).forEach(n=>{let i=t.plans.map(s=>new Option(s.name,s.id)),r=!e.requiresSellingPlan&&l(n,"plan")!=="subscription-only",a=n.getAttribute(p("one-time-label"))||"One-time purchase";n.replaceChildren(...r?[new Option(a,"")]:[],...i)})}function St(t){t.$(o("plan-list")).forEach(e=>{let n=(l(e,"plan-list")??"").trim(),i=vt.includes(n.toLowerCase())?null:n,r=t.plans.filter(a=>!i||a.group.name===i);y(e,r,(a,s)=>{a.setAttribute(p("plan-value"),s.id),!a.firstElementChild&&!a.querySelector(o("plan-bind"))&&d(a,s.name)})})}function st(t){t.$(o("bind")).forEach(e=>{yt(e,l(e,"bind")??"",t.product)}),xt(t),It(t),St(t)}var ot={money:L,percent:B},Mt=t=>t.tagName==="INPUT";function O(t){let e=f(t,o("add-label"))[0]??t,n=e.dataset.tetherLabel??(Mt(e)?e.value:e.textContent);return e.dataset.tetherLabel=n,{label:e,original:n}}function kt(t,e){let{product:n}=t,i=r=>e.selected[t.optName(r)]??"";t.$(o("option-selected")).forEach(r=>{d(r,i(l(r,"option-selected")))}),t.$(o("option-list")).forEach(r=>{let a=t.optName(l(r,"option-list"));f(r,o("option-value")).forEach(s=>{let c=l(s,"option-value")??"";I(s,e.selected[a]===c);let u=!z(n,e.selected,a,c);s.classList.toggle("is-unavailable",u),s.setAttribute("data-unavailable",u?"true":"false")})}),b(t,o("option")).forEach(r=>{r.value=i(l(r,"option"))}),b(t,o("variant-select")).forEach(r=>{r.value=e.variant.id})}function At(t,e){let{variant:n,purchase:i,line:r}=e;t.$(o("purchase")).forEach(a=>{if(q(a)){a.value=i.kind;return}let s=l(a,"purchase");I(a,s===i.kind);let c=s==="subscription"?!e.subscriptionAvailable:t.product.requiresSellingPlan;a.classList.toggle("is-unavailable",c)}),t.$(o("plan-value")).forEach(a=>{let s=l(a,"plan-value")??"";I(a,r.kind==="subscription"&&s===r.planId),a.classList.toggle("is-unavailable",!S(n,s));let c=t.plans.find(m=>m.id===s),u=it(n,s,c,ot);f(a,o("plan-bind")).forEach(m=>{let E=u.get(l(m,"plan-bind")??"");E&&d(m,E())})}),b(t,o("plan")).forEach(a=>{a.value=r.kind==="subscription"?r.planId:""})}function wt(t,e){let n=new Map(Object.entries(e.show));$.forEach(i=>n.set(i,i==="ready")),t.$(o("show")).forEach(i=>{let r=l(i,"show")??"",a=n.get(r);a!==void 0&&($.some(s=>s===r)&&!rt(i,t.root)||x(i,a))})}function Vt(t,e){let n=!e.variant.availableForSale;t.$(o("add-to-cart")).forEach(i=>{i.classList.toggle("is-disabled",n),i.setAttribute("aria-disabled",String(n)),"disabled"in i&&(i.disabled=n);let r=l(i,"soldout-text"),a=l(i,"subscribe-text");if(!r&&!a)return;let{label:s,original:c}=O(i),u=c;e.line.kind==="subscription"&&a&&(u=a),n&&r&&(u=r),i.getAttribute("aria-busy")!=="true"&&d(s,u)})}function lt(t,e){let{variant:n}=e,{product:i}=t,r=nt(e,ot);t.$(o("bind")).forEach(a=>{let s=l(a,"bind")??"";if(s==="variant-image"){g(a,n.image?.url||i.featuredImage?.url,n.image?.altText||i.title);return}let c=r.get(s);c&&d(a,c())}),kt(t,e),At(t,e),wt(t,e),t.root.classList.toggle("is-subscription",e.line.kind==="subscription"),t.root.setAttribute(p("purchase-mode"),e.line.kind),Vt(t,e)}var ut=()=>o("product"),Nt=t=>t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA",ct=t=>t instanceof window.Element;function P(t,e,n){let i=e.closest(n);return i?.closest(ut())===t.root?i:null}function Ht(t,e){let{label:n,original:i}=O(e),r=l(e,"adding-text");Q(e,async()=>{r&&d(n,r);try{await t.addToCart()}catch(a){w(a,"add to cart failed"),v("error",{error:a,context:"add-to-cart"},t.root)}finally{r&&d(n,i)}}).then(()=>{t.renderVariant()}).catch(a=>{w(a,"add to cart render")})}function Ct(t,e,n){let i=P(t,n,o("option-value")),r=i?.closest(o("option-list"));if(i&&r){e.preventDefault(),t.select(t.optName(l(r,"option-list")),l(i,"option-value")??"");return}let a=P(t,n,o("plan-value"));if(a){e.preventDefault(),t.selectPlan(l(a,"plan-value"));return}let s=P(t,n,`${o("purchase")}:not(select)`);if(s){s.tagName!=="INPUT"&&e.preventDefault(),t.setPurchase(dt(l(s,"purchase")));return}let c=P(t,n,o("qty-plus")),u=c?null:P(t,n,o("qty-minus"));if(c||u){e.preventDefault(),t.setQuantity(t.quantity+(c?1:-1));return}let m=P(t,n,o("add-to-cart"));m&&(e.preventDefault(),Ht(t,m))}var dt=t=>t==="subscription"?"subscription":"one-time";function $t(t,e){let n=Nt(e)?e.value:"";e.matches(`select${o("option")}`)?t.select(t.optName(l(e,"option")),n):e.matches(`select${o("variant-select")}`)?t.selectVariant(n):e.matches(`select${o("plan")}`)?n?t.selectPlan(n):t.setPurchase("one-time"):e.matches(`select${o("purchase")}`)?t.setPurchase(dt(n)):e.matches(o("qty"))&&t.setQuantity(n)}function mt(t){t.root.addEventListener("click",e=>{ct(e.target)&&Ct(t,e,e.target)}),t.root.addEventListener("change",e=>{let{target:n}=e;ct(n)&&n.closest(ut())===t.root&&$t(t,n)})}var qt=new WeakMap,Ot=()=>o("product"),k=new Map;function Rt(t){t.forEach(e=>{k.has(e.handle)||k.set(e.handle,e.options.map(n=>n.name))})}var pt=t=>t.tagName==="INPUT",_t=t=>t.tagName==="INPUT"||t.tagName==="SELECT"||t.tagName==="TEXTAREA";function Ft(t){return pt(t)&&t.type==="checkbox"?t.checked?t.value&&t.value!=="on"?t.value:"Yes":null:pt(t)&&t.type==="radio"?t.checked?t.value:null:_t(t)&&t.value||null}var ht=class{constructor(e,n){h(this,"root");h(this,"product");h(this,"plans");h(this,"selected");h(this,"purchase");h(this,"variant");h(this,"quantity");this.root=e,this.product=n,this.plans=N(n);let i=new URLSearchParams(window.location.search),r=tt(n,{variant:i.get("variant")||l(e,"variant"),sellingPlan:i.get("selling_plan"),defaultPlan:l(e,"default-plan"),defaultPurchase:l(e,"default-purchase")||A.defaultPurchase});this.selected=r.selected,this.purchase=r.purchase,this.variant=null,this.quantity=T(e,"quantity")?Math.max(0,parseInt(l(e,"quantity")??"",10)||0):1,qt.set(e,this),e.setAttribute(p("state"),"ready"),e.removeAttribute(p("error")),this.renderProduct(),mt(this),this.renderVariant(),j(e,"product"),V("product"),v("product-ready",{product:n,scope:this},e)}update(e){let n=this.variant?.id;this.product=e,this.plans=N(e);let i=e.variants.nodes.find(r=>r.id===n);i&&(this.selected=M(i)),this.root.setAttribute(p("state"),"ready"),this.root.removeAttribute(p("error")),this.renderProduct(),this.renderVariant(),V("product"),v("product-updated",{product:e,scope:this},this.root)}$(e){let n=R(this.root,e,Ot());return this.root.matches(e)?[this.root,...n]:n}optName(e){if(!e)return"";let{options:n}=this.product;if(n.some(r=>r.name===e))return e;let i=(k.get(this.product.handle)??[]).indexOf(e);return n[i]?.name??e}get plan(){let e=H(this.purchase);return this.plans.find(n=>n.id===e)??null}get subscriptionAvailable(){return this.plans.some(e=>S(this.variant,e.id))}get isSubscription(){return C(this.purchase,this.variant).kind==="subscription"}getLine(){if(!this.variant)return null;let e={merchandiseId:this.variant.id,quantity:this.quantity},n=C(this.purchase,this.variant);n.kind==="subscription"&&(e.sellingPlanId=n.planId);let i=this.collectAttributes();return i.length&&(e.attributes=i),e}collectAttributes(){let e=X(W(this.root,"line-attributes")),n=this.$(o("line-attribute")).flatMap(i=>{let r=Ft(i);return r===null?[]:[{key:l(i,"line-attribute")??"",value:r}]});return[...e,...n]}select(e,n){if(this.selected[e]===n)return;let i=this.product.variants.nodes.filter(s=>s.selectedOptions.some(c=>c.name===e&&c.value===n)),[r]=i;if(!r)return;let a={...this.selected,[e]:n};if(!i.some(s=>s.selectedOptions.every(c=>a[c.name]===c.value))){let s=u=>u.selectedOptions.filter(E=>E.name!==e&&this.selected[E.name]===E.value).length*2+(u.availableForSale?1:0),c=i.reduce((u,m)=>s(m)>s(u)?m:u,r);Object.assign(a,M(c))}this.selected=a,this.renderVariant()}selectVariant(e){let n=this.product.variants.nodes.find(i=>i.id===J.variant(e));n&&(this.selected=M(n),this.renderVariant())}setPurchase(e){let n=Z(this.product,this.variant,e,H(this.purchase));n.kind!==this.purchase.kind&&(this.purchase=n,this.renderVariant())}selectPlan(e){let n=K(this.product,e);n&&(this.purchase={kind:"subscription",planId:n.id},this.renderVariant())}setQuantity(e){let n=T(this.root,"quantity")?0:1;this.quantity=Math.max(n,parseInt(String(e),10)||0),this.$(o("qty")).forEach(i=>{d(i,this.quantity)}),this.renderVariant()}async addToCart(){if(!this.variant?.availableForSale)return null;let e=this.getLine();if(!e||e.quantity<1)return null;let n=await Y.add(e);return v("product-added",{product:this.product,variant:this.variant,line:e},this.root),n}renderProduct(){let{product:e}=this;k.has(e.handle)||this.$(`${o("option-list")},select${o("option")}`).map(i=>l(i,"option-list")||l(i,"option")).some(i=>e.options.some(r=>r.name===i))&&Rt([e]),st(this)}renderVariant(){let e=et(this.product,{selected:this.selected,purchase:this.purchase,quantity:this.quantity},A.lowStock);if(!e){this.variant=null;return}this.variant=e.variant,this.selected=e.selected,this.purchase=e.purchase,lt(this,e),v("variant-changed",{product:this.product,variant:e.variant,selected:{...e.selected},purchase:e.purchase.kind,sellingPlanId:e.line.kind==="subscription"?e.line.planId:null},this.root)}};export{qt as a,Rt as b,ht as c};
@@ -1 +0,0 @@
1
- import{b as Y,d as ht,g as q,h as Ct,p as x,v as bt}from"./chunk-BFTZR4OB.js";import{A as gt,C as I,F as G,G as v,H as N,K as yt,P as M,a as y,c as $,d as R,h as W,k as lt,l as F,m as s,n as w,p as l,t as f,w as mt,y as pt,z as ft}from"./chunk-BA4LQJJQ.js";import{C as dt,r as a,x as ct,z as S}from"./chunk-E5YO6274.js";var jt={id:"string",quantity:"number",attributes:["object"],cost:{totalAmount:x,subtotalAmount:x,amountPerQuantity:x},merchandise:{id:"string",selectedOptions:["object"],product:"object"}},X={id:"string",checkoutUrl:"string",totalQuantity:"number",attributes:["object"],discountCodes:["object"],cost:{totalAmount:x,subtotalAmount:x},lines:{nodes:[jt]}};var Ht='a[href],button:not([disabled]),input:not([disabled]),select:not([disabled]),textarea:not([disabled]),[tabindex]:not([tabindex="-1"])',Bt=60,z=!1,K=null,Gt=t=>t!==null&&"focus"in t,St=t=>l(t,Ht).filter(n=>n.offsetParent!==null||n===document.activeElement),k=()=>l(document,s("cart-drawer")),J=t=>t.classList.contains(a.cartDrawerOpenClass);function g(){let t=k();return t.length?t.some(J):z}function V(t){l(document,s("cart-open")).forEach(n=>{n.setAttribute("aria-expanded",String(t))}),k().forEach(n=>{n.hasAttribute("role")||n.setAttribute("role","dialog"),!n.hasAttribute("aria-label")&&!n.hasAttribute("aria-labelledby")&&n.setAttribute("aria-label",w(n,"cart-label")||"Cart"),n.setAttribute("aria-modal",String(t)),!J(n)&&(n.setAttribute("aria-hidden","true"),a.cartFocus&&(n.inert=!0))})}function Yt(t){let n=St(t)[0]??t;n===t&&!t.hasAttribute("tabindex")&&(t.tabIndex=-1),n.focus({preventScroll:!0})}function _(){if(g())return;z=!0;let t=k().filter(e=>w(e,"cart-drawer")!=="manual");t.forEach(e=>{e.inert=!1,e.classList.add(a.cartDrawerOpenClass),e.setAttribute("aria-hidden","false")}),V(!0);let[n]=t;a.cartFocus&&n&&(K=Gt(document.activeElement)?document.activeElement:null,setTimeout(()=>{Yt(n)},Bt)),a.onCartOpen?.(t),f("cart-toggled",{open:!0})}function Z(){if(!g())return;z=!1;let t=k(),n=t.some(e=>e.contains(document.activeElement));t.forEach(e=>{e.classList.remove(a.cartDrawerOpenClass),e.setAttribute("aria-hidden","true"),a.cartFocus&&(e.inert=!0)}),V(!1),n&&K?.isConnected&&K.focus({preventScroll:!0}),K=null,a.onCartClose?.(t),f("cart-toggled",{open:!1})}function wt(){g()?Z():_()}function Xt(t){if(t.key!=="Tab"||!a.cartFocus||!g())return;let n=k().find(J);if(!n)return;let e=St(n),r=e[0],i=e.at(-1);if(!r||!i)return;let o=document.activeElement,u=t.shiftKey?o===r:o===i;n.contains(o)&&!u||(t.preventDefault(),(t.shiftKey?i:r).focus())}var vt="Default Title",tt=(t,n)=>n.get(t.id)?.quantity??t.quantity,At=t=>t.split("/").pop()??t;function zt(t){let n=t.merchandise,e=gt(n.product.handle,n.product.id);if(!e)return null;let r=new URLSearchParams;r.set("variant",At(n.id));let i=t.sellingPlanAllocation?.sellingPlan.id;return i&&r.set("selling_plan",At(i)),`${e}${e.includes("?")?"&":"?"}${r.toString()}`}var kt=t=>t.merchandise.product.title,Lt={title:kt,"product-title":kt,"variant-title":t=>t.merchandise.title===vt?"":t.merchandise.title,options:t=>t.merchandise.selectedOptions.filter(n=>n.value!==vt).map(n=>`${n.name}: ${n.value}`).join(", "),vendor:t=>t.merchandise.product.vendor,sku:t=>t.merchandise.sku??"",price:t=>I(t.cost.amountPerQuantity),"compare-at-price":t=>I(t.cost.compareAtAmountPerQuantity??t.merchandise.compareAtPrice),"line-total":t=>I(t.cost.totalAmount),"line-subtotal":t=>I(t.cost.subtotalAmount),quantity:(t,n)=>tt(t,n.pending),plan:t=>t.sellingPlanAllocation?.sellingPlan.name??"","plan-description":t=>t.sellingPlanAllocation?.sellingPlan.description??"",components:t=>(t.lineComponents??[]).map(n=>`${n.quantity} \xD7 ${n.merchandise.product.title}`).join(", ")},Pt="attribute:";function Jt(t,n,e){if(Object.hasOwn(Lt,n))return Lt[n]?.(t,e);if(!n.startsWith(Pt))return;let r=n.slice(Pt.length);return t.attributes.find(i=>i.key===r)?.value??""}function Zt(t,n,e){let r=Ct(e),i=!e.requiresSellingPlan&&w(t,"line-plan")!=="subscription-only",o={value:"",label:t.getAttribute(F("one-time-label"))||"One-time purchase"},u=[...i?[o]:[],...r.map(m=>({value:m.id,label:m.name}))],c=u.map(m=>m.value).join("|");t.dataset.tetherSig!==c&&(t.replaceChildren(...u.map(m=>{let b=document.createElement("option");return b.value=m.value,b.textContent=m.label,b})),t.dataset.tetherSig=c),t.value=n.sellingPlanAllocation?.sellingPlan.id??"",N(t,r.length>0)}function tn(t,n,e){let r=!!n.sellingPlanAllocation;t.classList.toggle("is-subscription",r);let i=e.warnings.find(c=>c.target===n.id);t.classList.toggle("is-warning",!!i);let o=e.pending.has(n.id);t.classList.toggle("is-busy",o),o?t.setAttribute("aria-busy","true"):t.removeAttribute("aria-busy"),l(t,s("line","warning")).forEach(c=>{v(c,i?.message??"")});let u=new Map([["subscription",r],["one-time",!r],["on-sale",ht(n.cost.compareAtAmountPerQuantity?.amount,n.cost.amountPerQuantity.amount)],["has-components",(n.lineComponents??[]).length>0],["warning",!!i]]);l(t,s("line-show")).forEach(c=>{let m=w(c,"line-show"),b=m===null?void 0:u.get(m);b!==void 0&&N(c,b)})}function nn(t,n,e){let r=n.merchandise;t.setAttribute(F("line-id"),n.id),l(t,s("line")).forEach(i=>{let o=w(i,"line")??"";if(o==="image"){mt(i,r.image?.url??r.product.featuredImage?.url,r.product.title);return}if(o==="url"){let c=zt(n);c&&i.setAttribute("href",c);return}let u=Jt(n,o,e);u!==void 0&&v(i,u)}),tn(t,n,e),l(t,`select${s("line-plan")}`).forEach(i=>{bt(r.product.handle).then(o=>{Zt(i,n,o)}).catch(o=>{S(o,"line plan options")})})}function en(t,n){let e=t?.totalQuantity??0,r=(t?.lines.nodes??[]).some(o=>o.sellingPlanAllocation),i=new Map([["cart-empty",e===0],["cart-filled",e>0],["cart-has-subscription",r],["cart-no-subscription",!r],["cart-has-discount",(t?.discountCodes??[]).some(o=>o.applicable)],["cart-error",n.failed],["cart-warning",n.warnings.length>0]]);l(document,s("show")).forEach(o=>{let u=w(o,"show"),c=u===null?void 0:i.get(u);c===void 0||o.closest(s("product"))||N(o,c)}),l(document,s("checkout")).forEach(o=>{o.classList.toggle("is-disabled",!e),o.setAttribute("aria-disabled",String(!e))})}function rn(t){l(document,`textarea${s("cart-note")},input${s("cart-note")}`).forEach(n=>{document.activeElement!==n&&G(n,t?.note??"")}),l(document,s("cart-discounts")).forEach(n=>{pt(n,t?.discountCodes??[],(e,r)=>{e.setAttribute(F("discount-code"),r.code);let i=e.querySelector(s("discount","code"))??(e.firstElementChild?null:e);i&&G(i,r.code),e.classList.toggle("is-inapplicable",!r.applicable)})})}function It(t){let{cart:n}=t,e=r=>n?I(n.cost[r]):"";V(g()),l(document,s("cart-count")).forEach(r=>{v(r,n?.totalQuantity??0)}),l(document,s("cart-subtotal")).forEach(r=>{v(r,e("subtotalAmount"))}),l(document,s("cart-total")).forEach(r=>{v(r,e("totalAmount"))}),l(document,s("cart-checkout-charge")).forEach(r=>{v(r,e("checkoutChargeAmount"))}),en(n,t),l(document,s("cart-warning")).forEach(r=>{v(r,[...new Set(t.warnings.map(i=>i.message))].join(" "))}),rn(n),l(document,s("cart-lines")).forEach(r=>{ft(r,n?.lines.nodes??[],i=>i.id,(i,o)=>{nn(i,o,t)},{onEnter:a.onLineEnter,onLeave:a.onLineLeave})}),n&&yt("cart")}function xt(t){l(document,s("cart-count")).forEach(n=>{/^\s*0?\s*$/.test(n.textContent)&&(n.textContent=String(t))})}function nt(t,n="localStorage"){try{return window[n].getItem(t)}catch{return null}}function et(t,n,e="localStorage"){try{window[e].setItem(t,n)}catch{}}function Et(t,n="localStorage"){try{window[n].removeItem(t)}catch{}}var p={kind:"unknown"},E=[],L=new Map,j=()=>p;function d(){switch(p.kind){case"ready":case"error":return p.cart;case"unknown":case"empty":return null}}var $t=()=>E,rt=t=>t?{kind:"ready",cart:t}:{kind:"empty"},Mt=()=>`${a.storageKey}:seen`,P=()=>nt(a.storageKey)||null;function T(){Et(a.storageKey)}function it(t){p=rt(t),t&&et(a.storageKey,t.id)}function U(){It({cart:d(),warnings:E,pending:L,failed:p.kind==="error"})}function O(t){U(),f("cart-updated",{cart:d(),reason:t})}function h(t,n){return it(t),et(Mt(),`${Date.now()}|${t?.totalQuantity??0}`),O(n),t}function Q(t){p=t.kind==="loaded"?rt(t.cart):{kind:"error",error:t.error,cart:null},O("load")}function on(){let t=nt(Mt())?.split("|")[1]??"",n=Number(t);return/^\d+$/.test(t)&&Number.isSafeInteger(n)?n:null}function qt(){if(p.kind!=="unknown")return;let t=on();t!==null&&xt(t)}function Ut(t){E=t.filter((n,e)=>t.findIndex(r=>r.message===n.message)===e).map(n=>({...n,message:a.warningText?.(n)||n.message})),E.length&&f("cart-warning",{warnings:E})}var Tt=()=>{};function an(){let t=Promise.resolve();return n=>{let e=t.then(n);return t=e.then(Tt,Tt),e}}var sn=an();function C(t){return sn(t).then(n=>(p.kind==="error"&&(p=rt(p.cart),U()),n),n=>{throw p={kind:"error",error:n,cart:d()},U(),f("cart-error",{error:n}),n})}var ot=t=>tt(t,L),un=()=>({open:g(),count:d()?.totalQuantity??0,loaded:p.kind!=="unknown",warnings:[...E]});function Ot(t){let n=["cart-updated","cart-toggled"].map(r=>`${a.prefix}:${r}`),e=()=>{t(d(),un())};return n.forEach(r=>{document.addEventListener(r,e)}),e(),()=>{n.forEach(r=>{document.removeEventListener(r,e)})}}var cn=/does not exist|not found|invalid id/i,ln=t=>R({[t]:$({cart:$(X)})});function H(t){return t instanceof y?t.userErrors?.some(n=>n.field?.[0]==="cartId")?!0:(t.errors??[]).some(n=>cn.test(n.message)):!1}function Dt(t,n=1,e={}){let r=typeof t=="object"&&t!==null?t:{...e,quantity:n,...t==null?{}:{variantId:t}},i=q.variant(r.merchandiseId||r.variantId||r.id);if(!i)throw new y("add(): variantId is required");let o=parseInt(String(r.quantity??1),10),u={merchandiseId:i,quantity:Math.max(1,o||1)},c=q.sellingPlan(r.sellingPlanId||r.sellingPlan);c&&(u.sellingPlanId=c);let m=M(r.attributes);return m.length&&(u.attributes=m),u}function dn(t,n,e){return r=>`mutation Tether_${t}(${n}){${t}(${e}){cart{...TetherCart}userErrors{field message}warnings{code message target}}}${Y(r)}`}async function Rt(t,n,e,r){let i=await W(dn(t,n,e),r,ln(t)),o=lt(i[t],t);return Ut(o.warnings??[]),o.cart}function Qt(t){let n=a.country?{buyerIdentity:{countryCode:a.country},...t}:t;return Rt("cartCreate","$input: CartInput!","input: $input",{input:n})}async function A({name:t,args:n,inner:e,variables:r,createInput:i}){let o=P();if(!o)return i?Qt(i):null;try{return await Rt(t,`$cartId: ID!, ${n}`,`cartId: $cartId, ${e}`,{...r,cartId:o})}catch(u){if(!H(u)||(T(),!i))throw u;return ct("cart expired, creating a new one"),Qt(i)}}async function Wt(t){return(await W(e=>`query TetherCart($id:ID!){cart(id:$id){...TetherCart}}${Y(e)}`,{id:t},R({cart:$(X)}))).cart}async function Ft(t){return(await W("query TetherCheckout($id: ID!) { cart(id: $id) { checkoutUrl } }",{id:t},R({cart:$({checkoutUrl:"string"})}))).cart?.checkoutUrl??null}function Nt(t,n){let e=typeof n=="number"?{quantity:n}:n,r={id:t};e.quantity!==void 0&&(r.quantity=e.quantity),"sellingPlanId"in e&&(r.sellingPlanId=e.sellingPlanId?q.sellingPlan(e.sellingPlanId):null),e.attributes&&(r.attributes=M(e.attributes));let i=e.merchandiseId||e.variantId;return i&&(r.merchandiseId=q.variant(i)),r}var at=t=>A({name:"cartLinesUpdate",args:"$lines: [CartLineUpdateInput!]!",inner:"lines: $lines",variables:{lines:t},createInput:null}),st=t=>A({name:"cartLinesRemove",args:"$lineIds: [ID!]!",inner:"lineIds: $lineIds",variables:{lineIds:t},createInput:null}),Kt=(t,n)=>n>0?at([{id:t,quantity:n}]):st([t]);var ut=null;function Vt(t){ut=t}var mn=t=>Ft(t).then(n=>({kind:"url",url:n}),n=>({kind:"failed",error:n}));async function pn(){if(!ut)return null;try{let t=await ut();return t&&`${t}${t.includes("?")?"&":"?"}logged_in=true`}catch(t){return S(t,"account checkout"),null}}async function fn(t){let n=mn(t),e=await pn();if(e)return e;let r=await n;if(r.kind==="failed")throw r.error;if(!r.url)throw new y("No checkoutUrl (cart empty or expired)");return r.url}function gn(t){try{t.opener=null}catch{}}async function _t(t=a.checkoutTarget){let n=P(),e=d();if(!n||e&&!e.totalQuantity)return null;let r=t==="_blank"?window.open("","_blank"):null;r&&gn(r);try{let i=await fn(n);if(!dt(i))throw new y("The checkout URL is not https: not opened");return f("checkout",{url:i,cart:d()}),r&&!r.closed?r.location.href=i:window.location.href=i,i}catch(i){return r?.close(),S(i,"checkout failed"),null}}var B=()=>d()?.lines.nodes??[];function yn(t,n){let e=B().find(c=>c.id===t);if(!e)return Promise.resolve(d());let r=Math.max(0,ot(e)+n),i={quantity:r};L.set(t,i),O("pending");let o=()=>L.get(t)===i;return C(async()=>{if(!o())return d();if(B().find(b=>b.id===t)?.quantity===r)return d();let m=await Kt(t,r);return o()?h(m,r>0?"update":"remove"):(it(m),m)}).finally(()=>{o()&&(L.delete(t),O("settled"))})}function hn(t){let n=(d()?.discountCodes??[]).map(r=>r.code),e=typeof t=="function"?t(n):t;return(Array.isArray(e)?e:[e]).map(r=>r.trim()).filter(Boolean)}function Cn(t){let n=new Map((d()?.attributes??[]).map(e=>[e.key,e.value]));return M(t).forEach(e=>n.set(e.key,e.value)),[...n].filter(([,e])=>e!=="").map(([e,r])=>({key:e,value:r}))}async function bn(){let t=P();if(!t)return Q({kind:"loaded",cart:null}),null;qt();try{let n=await Wt(t);n||T(),Q({kind:"loaded",cart:n})}catch(n){S(n,"cart load failed"),H(n)&&T(),Q({kind:"failed",error:n})}return d()}var D={init:bn,id:P,get status(){return j()},get state(){return d()},get lines(){return[...B()]},get count(){return d()?.totalQuantity??0},get loaded(){return j().kind!=="unknown"},get lastError(){let t=j();return t.kind!=="error"?null:t.error instanceof Error?t.error:new Error(String(t.error))},get warnings(){return[...$t()]},get pendingQty(){return L},setCheckoutResolver:Vt,forgetSaved(){T(),Q({kind:"loaded",cart:null})},render:U,subscribe:Ot,add(t,n=1,e={}){let r=(Array.isArray(t)?t:[t]).map(i=>Dt(i,n,e));return C(async()=>{let i=await A({name:"cartLinesAdd",args:"$lines: [CartLineInput!]!",inner:"lines: $lines",variables:{lines:r},createInput:{lines:r}});if(!i)throw new y("Shopify answered the add without a cart");return h(i,"add"),f("added",{cart:i,lines:r}),a.openCartOnAdd&&_(),i})},updateLine(t,n){let e=typeof n=="number"?n:n.quantity;if(e!==void 0&&e<=0)return D.removeLine(t);let r=Nt(t,n);return C(async()=>h(await at([r]),"update"))},changeQuantity:yn,quantityOf:ot,removeLine(t){let n=Array.isArray(t)?t:[t];return C(async()=>h(await st(n),"remove"))},clear(){let t=B().map(n=>n.id);return t.length?D.removeLine(t):Promise.resolve(d())},setNote(t){let n={note:t??""};return C(async()=>h(await A({name:"cartNoteUpdate",args:"$note: String!",inner:"note: $note",variables:n,createInput:n}),"note"))},setAttributes(t){return C(async()=>{let n={attributes:Cn(t)},e=await A({name:"cartAttributesUpdate",args:"$attributes: [AttributeInput!]!",inner:"attributes: $attributes",variables:n,createInput:n});return h(e,"attributes")})},setDiscountCodes(t){return C(async()=>{let n={discountCodes:hn(t)},e=await A({name:"cartDiscountCodesUpdate",args:"$discountCodes: [String!]!",inner:"discountCodes: $discountCodes",variables:n,createInput:n});return h(e,"discount")})},async applyDiscount(t){let n=await D.setDiscountCodes(i=>[...new Set([...i,t])]),e=t.toLowerCase();if((n?.discountCodes??[]).find(i=>i.code.toLowerCase()===e)?.applicable)return n;try{await D.removeDiscount(t)}catch(i){S(i,"removing a discount code Shopify refused")}throw new y(`Discount code not valid: ${t}`,{code:"INVALID_DISCOUNT"})},removeDiscount(t){let n=t.toLowerCase();return D.setDiscountCodes(e=>e.filter(r=>r.toLowerCase()!==n))},setBuyerIdentity(t,{create:n=!0}={}){return C(async()=>{let e=await A({name:"cartBuyerIdentityUpdate",args:"$buyerIdentity: CartBuyerIdentityInput!",inner:"buyerIdentity: $buyerIdentity",variables:{buyerIdentity:t},createInput:n?{buyerIdentity:t}:null}).catch(r=>{if(n||!H(r))throw r;return null});return h(e,"buyer-identity")})},checkout:_t,drawers:k,isOpen:g,open:_,close:Z,toggle:wt};export{Xt as a,nt as b,et as c,Et as d,D as e};
@@ -1 +0,0 @@
1
- import{A as G,E as j,F as Q,b as y,d as h,e as S,o as F,p as V,r as u,x as C,y as T,z as E}from"./chunk-E5YO6274.js";var p=class extends Error{constructor(r,{status:n,errors:i,userErrors:o,code:s}={}){super(r);y(this,"name","TetherError");y(this,"code");y(this,"status");y(this,"errors");y(this,"userErrors");this.code=s??(n?`HTTP_${n}`:"ERROR"),this.status=n,this.errors=i,this.userErrors=o}};function x(t,e){return typeof e=="function"?e(t):typeof e=="string"?e==="object"?h(t):typeof t===e:mt(e)?Array.isArray(t)&&t.every(r=>x(r,e[0])):h(t)&&Object.entries(e).every(([r,n])=>x(t[r],n))}var mt=t=>Array.isArray(t),Re=t=>e=>e===null||x(e,t),Oe=t=>e=>x(e,t);function ht(t=u){return`https://${t.domain}/api/${t.apiVersion}/graphql.json`}var yt=/"(?:\\.|[^"\\\n])*"|#[^\n]*/g,Et=/^\s*(?:query|mutation)(?:\s+\w+)?\s*(?:\([^)]*\))?/;function Y(t,{country:e,language:r}){let n=[];if(e&&n.push(`country: ${e}`),r&&n.push(`language: ${r}`),!n.length)return t;let i=`@inContext(${n.join(", ")})`,o=t.replace(yt,d=>" ".repeat(d.length)),s=o.indexOf("{");if(o.slice(0,s).includes("@inContext"))return t;if(o.trimStart().startsWith("{"))return`query ${i} ${t.slice(s)}`;let c=Et.exec(o);if(!c)return t;let l=c[0].length;return`${t.slice(0,l).trimEnd()} ${i} ${t.slice(l).trimStart()}`}function Pe(t,e=u){let r=F(e.country)??void 0,n=V(e.language)??void 0;return Y(t,{country:r,language:n})}var W=300,Tt=500,B=430,bt=1e3,I="quantityAvailable",q=new Set,wt=t=>`${t.domain} ${t.apiVersion} ${t.token}`;function At(t,e,r,n){let i=typeof e=="string"?e:e(r),o=n?Y(i,t):i;return t.maxAge<=0||/^\s*mutation\b/.test(o)?o:`${o} #${Math.floor(Date.now()/(t.maxAge*bt))}`}var St=t=>new Promise(e=>setTimeout(e,t));function R(t,e){if(t===401||t===403){let r=e.token.startsWith("shpat_")?", not an Admin API token (shpat_\u2026)":"";return`Shopify rejected the Storefront token for ${e.domain} (${t}): use the public Storefront API token (Headless channel)${r}`}return t===404?`Store or API version not found (404): check domain ${e.domain} and apiVersion ${e.apiVersion}`:`HTTP ${t} from ${e.domain}`}function xt(t){let e=S(t,"message"),r=S(S(t,"extensions"),"code"),n=typeof e=="string"?e:"";return typeof r=="string"?{message:n,extensions:{code:r}}:{message:n}}function vt(t){if(!h(t))return null;let{data:e,errors:r}=t;return r==null?{data:e}:Array.isArray(r)?{data:e,errors:r.map(xt)}:null}function N(t,e){let r=t.ok?`Invalid response (${t.status})`:R(t.status,e);return new p(r,{status:t.status})}function z(t,e,r){let n=e.map(o=>o.message).filter(Boolean).join(" | "),i=n||"Storefront API error";return t.ok||(i=t.status===401||t.status===403||!n?R(t.status,r):n),new p(i,{status:t.status,errors:e})}async function kt(t,e,r,n,i){let o;try{o=await(t.fetch??fetch)(ht(t),{method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Storefront-Access-Token":t.token},body:JSON.stringify({query:e,variables:r})})}catch(f){if(i)return{kind:"retry",backoffMs:W};throw new p(`Network error: ${G(f)}`,{code:"NETWORK"})}if(o.status===B)throw new p("Shopify security rejection (430)",{status:B});if(i&&(o.status===429||o.status>=500))return{kind:"retry",backoffMs:W};let s;try{s=await o.json()}catch{throw N(o,t)}let c=vt(s);if(!c)throw N(o,t);let{data:l,errors:d=[]}=c;if(d.length){if(e.includes(I)&&d.some(f=>f.message.includes(I)))return{kind:"inventory-refused",error:z(o,d,t)};if(i&&d.some(f=>f.extensions?.code==="THROTTLED"))return{kind:"retry",backoffMs:Tt};throw z(o,d,t)}if(!o.ok)throw new p(R(o.status,t),{status:o.status});if(!n(l))throw N(o,t);return{kind:"data",data:l}}async function Lt(t,e,r,n,{context:i=!0}={}){if(!t.domain||!t.token)throw new p("Tether is not configured: domain and token are required",{code:"NOT_CONFIGURED"});let o=wt(t),s=0;for(;;){let c=At(t,e,{inventory:!q.has(o)},i),l=await kt(t,c,r,n,s<t.retries);switch(l.kind){case"data":return l.data;case"inventory-refused":if(typeof e=="string")throw l.error;C(`the token can't read inventory: ${I} is left out from now on`),q.add(o);break;case"retry":s+=1,C("retry",s),await St(l.backoffMs*2**s);break}}}function Ct(t,e,r,n){return Lt(u,t,e,r,n)}var Nt=t=>typeof t=="object"&&t!==null;function Me(t,e={},r){return Ct(t,e,Nt,r)}function _e(t,e){if(!t)throw new p(`${e}: empty response`);let r=t.userErrors??[];if(r.length)throw new p(r.map(n=>n.message).join(" | "),{userErrors:r});return t}var g=t=>`${u.prefix}-${t}`,It=(t,e)=>e===void 0?`[${g(t)}]`:`[${g(t)}="${e}"]`,O=(t,e)=>t.getAttribute(g(e)),Rt=(t,e)=>t.hasAttribute(g(e));function K(t,e){return t?[...t.querySelectorAll(e)]:[]}var Ot=(t,e,r)=>K(t,e).filter(n=>n.closest(r)===t),Pt=["product-ready","list-ready","cart-updated","cart-toggled","checkout","search"],J=new WeakMap;function X(t,e){let r=new CustomEvent(`${u.prefix}:${t}`,{detail:e,bubbles:!0});return J.set(r,t),r}function Mt(t,e){return J.get(t)===e}function P(t,e,r=document){r.dispatchEvent(X(t,e))}function tt(t,{width:e,height:r,crop:n}={}){if(!t)return t;let i;try{i=new URL(t)}catch(o){if(o instanceof TypeError)return t;throw o}return e&&i.searchParams.set("width",String(e)),r&&i.searchParams.set("height",String(r)),n&&i.searchParams.set("crop",n),i.toString()}function M(t,e){return t.getAttribute(e)??t.getAttribute(g(e))??t.getAttribute(`data-${e}`)}function et(t,e){if(!t||!e)return t;let r=M(e,"max-width"),n=M(e,"max-height");return tt(t,{width:r,height:n,crop:r||n?M(e,"crop"):null})}var Z=t=>t.replace(/\?.*$/,"");function rt(t,e){return!t||!e?!1:Z(t)===Z(e)}function _t(t){return/^\s*[a-z][a-z0-9+.-]*:/i.test(t)&&!/^\s*(https?:|data:image\/)/i.test(t)?"none":`url("${t.replace(/["\\\n\r\f]/g,n=>`\\${n.charCodeAt(0).toString(16)} `)}")`}function Ht(t,e,r){if(!e)return;let n=et(e,t);if(t.tagName!=="IMG"){t.style.backgroundImage=_t(n);return}if(rt(t.getAttribute("src"),n)){r!=null&&!t.getAttribute("alt")&&t.setAttribute("alt",r);return}t.removeAttribute("srcset"),t.removeAttribute("sizes"),t.setAttribute("src",n),r!=null&&t.setAttribute("alt",r),t.getAttribute("loading")||t.setAttribute("loading","lazy")}var _=new WeakMap,Ut=t=>!!_.get(t),H=t=>t.cloneNode(!0);function nt(t){let e=_.get(t);if(e!==void 0)return e;let r=t.firstElementChild,n=r?H(r):null;return _.set(t,n),t.replaceChildren(),n}function $t(t,e,r){let n=nt(t);if(!n){e.length&&T("repeater without a template child",t);return}t.replaceChildren(),e.forEach((i,o)=>{let s=H(n);r(s,i,o),t.appendChild(s)})}function Dt(t,e){let r=()=>{t.remove()};if(!e){r();return}try{e(t,r)}catch(n){E(n,"repeater onLeave"),r()}}function Ft(t,e,r,n){e.forEach((i,o)=>{if(!r.has(i))return;let s=e[o-1];if(s?.parentNode===t?s.after(i):t.prepend(i),!!n)try{n(i)}catch(c){E(c,"repeater onEnter")}})}function Vt(t,e,r,n,{onEnter:i,onLeave:o}={}){let s=nt(t);if(!s){T("repeater without a template child",t);return}let c=`data-${u.prefix}-key`,l=`data-${u.prefix}-leaving`,d=()=>[...t.children].filter(a=>a.hasAttribute(c)&&!a.hasAttribute(l)),f=new Map(d().map(a=>[a.getAttribute(c),a])),b=[],w=new Set;e.forEach((a,A)=>{let L=String(r(a,A)),m=f.get(L);m?f.delete(L):(m=H(s),m.setAttribute(c,L),w.add(m)),n(m,a,A,w.has(m)),b.push(m)});let k=b.filter(a=>!w.has(a)),D=d().filter(a=>k.includes(a));if(!(D.length===k.length&&D.every((a,A)=>a===k[A]))){f.forEach(a=>{a.remove()}),b.forEach(a=>t.appendChild(a));return}Ft(t,b,w,i),f.forEach(a=>{a.setAttribute(l,""),a.removeAttribute(c),a.style.pointerEvents="none",a.inert=!0,Dt(a,o)})}var Gt="http://www.w3.org/1999/xhtml",jt=new Set(["h1","h2","h3","h4","h5","h6","p","span","div","br","hr","blockquote","code","pre","strong","em","b","i","u","s","small","sub","sup","ul","ol","li","dl","dt","dd","table","caption","colgroup","col","thead","tbody","tfoot","tr","th","td","a","img","picture","source","video","figure","figcaption","iframe"]),Qt=new Set(["script","style","template","noscript","textarea","select","title"]),Wt=new Set(["style","title","lang","dir","role","align","width","height"]),Bt=new Map([["a",new Set(["href","target","rel","hreflang"])],["img",new Set(["src","srcset","sizes","alt","loading","decoding"])],["source",new Set(["src","srcset","sizes","type","media"])],["video",new Set(["src","poster","controls","autoplay","muted","loop","playsinline","preload"])],["iframe",new Set(["src","allow","allowfullscreen","frameborder","loading"])],["blockquote",new Set(["cite"])],["ol",new Set(["start","type","reversed"])],["li",new Set(["value"])],["table",new Set(["border","cellpadding","cellspacing","summary"])],["col",new Set(["span"])],["colgroup",new Set(["span"])],["th",new Set(["colspan","rowspan","headers","scope","valign"])],["td",new Set(["colspan","rowspan","headers","valign"])]]),qt=new Set(["href","src","poster","cite"]),zt=/^(javascript|vbscript|data):/i,Yt=/^data:image\/(png|gif|jpeg|webp|avif);/i,Kt=new Set(["position","top","right","bottom","left","z-index","-webkit-box-reflect"]),Jt=["inset","transform","translate","rotate","scale","offset"],Xt=/\d(?:[sld]?v|cq)(?:w|h|i|b|min|max)\b/i,Zt=/^(?:outline|box-shadow|text-shadow|filter|text-decoration|text-underline-offset|text-stroke)|^(?:border-image|mask-border|mask-box-image)(?:-outset)?$/,ot=40,te=new Map([["letter-spacing",{px:4,em:.25}],["word-spacing",{px:4,em:.25}],["text-indent",{px:ot}]]),it=/(?<![\w#.-])[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?(%|[a-z]+)?/gi,ee=/(?<![\w-])(?!drop-shadow\(|blur\()[\w-]+\([^()]*\)/g,st=/(?:var|calc|min|max|clamp|env|attr)\(/i,re=/url\(|expression\(|@import/i,ne=/[\u0000- ]/g,oe="allow-scripts allow-same-origin allow-popups allow-presentation",ie=new Set(["autoplay","encrypted-media","picture-in-picture","fullscreen","clipboard-write","accelerometer","gyroscope","web-share"]),se="strict-origin-when-cross-origin",ae=["https://www.youtube.com","https://www.youtube-nocookie.com","https://player.vimeo.com","https://www.loom.com","https://fast.wistia.net"];function ue(t,e){return Wt.has(e)||e.startsWith("aria-")||(Bt.get(t)?.has(e)??!1)}function ce(t,e,r){let n=r.replace(ne,"");return zt.test(n)?t==="img"&&e==="src"&&Yt.test(n):!0}function at(t,e){try{return new URL(t,e)}catch{return null}}function le(t,e,r){let n=t.baseURI,i=at(n)?.origin??"null";return{origin:i==="null"?null:i,baseUrl:n,styleParser:e,embedOrigins:new Set([...ae,...r])}}function de(t,e){let r=at(t.trim(),e.baseUrl);return r!==null&&r.origin!==e.origin&&e.embedOrigins.has(r.origin)}function fe(t){let e=t.split(";").map(r=>r.trim().split(/\s+/)[0]?.toLowerCase()??"");return[...new Set(e.filter(r=>ie.has(r)))].join("; ")}function pe(t,e){if(Kt.has(t)||Jt.some(n=>t.startsWith(n))||Xt.test(e))return!0;let r=te.get(t);return r?st.test(e)||ge(e,r):t.startsWith("margin")&&e.includes("-")}function ge(t,e){return[...t.matchAll(it)].some(([r="",n=""])=>{let i=parseFloat(r);if(i>=0)return!1;let o=e[n.toLowerCase()];return o===void 0||-i>o})}function me(t,e){return Zt.test(t.replace(/^-webkit-/,""))?st.test(e)?!0:[...e.replace(ee,"").matchAll(it)].some(([r="",n=""])=>{let i=Math.abs(parseFloat(r));return i!==0&&(n.toLowerCase()!=="px"||i>ot)}):!1}function he(t,e){let r=e.style;r.cssText=t;let n=Array.from({length:r.length},(o,s)=>r.item(s));for(let o of n){let s=r.getPropertyValue(o);(pe(o,s)||me(o,s)||re.test(s))&&r.removeProperty(o)}let i=r.cssText;return e.removeAttribute("style"),i}function ye(t,e){let r=t.localName;for(let o of[...t.attributes]){let s=o.name.toLowerCase(),c=qt.has(s);ue(r,s)&&(!c||ce(r,s,o.value))||t.removeAttribute(o.name)}let n=t.getAttribute("style");if(n===null)return;let i=he(n,e.styleParser);i===""?t.removeAttribute("style"):t.setAttribute("style",i)}function Ee(t){if(t.localName==="iframe"){let r=fe(t.getAttribute("allow")??"");r===""?t.removeAttribute("allow"):t.setAttribute("allow",r),t.setAttribute("sandbox",oe),t.setAttribute("referrerpolicy",se);return}if(t.localName!=="a"||t.getAttribute("target")?.toLowerCase()!=="_blank")return;let e=new Set((t.getAttribute("rel")??"").split(/\s+/).filter(Boolean));e.add("noopener"),e.add("noreferrer"),t.setAttribute("rel",[...e].join(" "))}function Te(t,e){let r=t.localName,n=t.namespaceURI===Gt;if(n&&Qt.has(r)){t.remove();return}if(!n||!jt.has(r)){t.replaceWith(...t.childNodes);return}if(r==="iframe"&&!de(t.getAttribute("src")??"",e)){t.remove();return}ye(t,e),Ee(t)}function ut(t,e=globalThis.document,r=[]){let n=e.createElement("template");n.innerHTML=t??"";let i=le(e,n,r);for(let o of[...n.content.querySelectorAll("*")])Te(o,i);return n.content}var ct="data-tether-seen",$="data-tether-shown",v="data-tether-prev-display",be=120;function Ke(t,e){return Q(u.productPath||"/product",t,e)}function pt(t,e){try{return t()}catch(r){if(r instanceof RangeError)return e;throw r}}function Je(t,e=u.locale){return t?pt(()=>new Intl.NumberFormat(e||void 0,{style:"percent",maximumFractionDigits:0}).format(t/100),`${t}%`):""}function Xe(t){return t?u.formatMoney?u.formatMoney(t,u.locale):j(t,u.locale):""}function Ze(t){return t?pt(()=>new Date(t).toLocaleDateString(u.locale||void 0),""):""}function tr(t,e){t.replaceChildren(ut(e,t.ownerDocument,u.embedOrigins))}var gt=t=>t.tagName==="INPUT"||t.tagName==="TEXTAREA",lt=t=>t.tagName==="INPUT";function we(t,e){let r=e==null?"":String(e);gt(t)?t.value=r:t.textContent=r}var dt=t=>gt(t)?t.value:t.textContent;function er(t,e){let r=dt(t);if(we(t,e),r!==dt(t)&&t.hasAttribute(ct)&&u.onValueChange)try{u.onValueChange(t,r)}catch(n){E(n,"onValueChange")}t.setAttribute(ct,"1")}function Ae(t){if(t.hasAttribute($))return;t.setAttribute($,""),t.removeAttribute("hidden");let e=t.getAttribute(v);e!==null?(t.style.display=e,t.removeAttribute(v)):t.style.display==="none"&&(t.style.display=""),typeof getComputedStyle=="function"&&getComputedStyle(t).display==="none"&&(t.style.display=t.getAttribute(g("display"))||"block")}function rr(t,e){if(e){Ae(t);return}t.removeAttribute($),!t.hasAttribute(v)&&t.style.display!=="none"&&t.setAttribute(v,t.style.display),t.style.display="none"}function nr(t,e){t.classList.toggle("is-selected",e),t.setAttribute("aria-pressed",e?"true":"false"),lt(t)&&(t.type==="radio"||t.type==="checkbox")&&(t.checked=e);let r=t.querySelector('input[type="radio"],input[type="checkbox"]');r&&lt(r)&&(r.checked=e)}var ft,Se=t=>Reflect.get(window,t);function xe(){let t=Se("ScrollTrigger");if(typeof t!="function")return;let e=Reflect.get(t,"refresh");typeof e=="function"&&Reflect.apply(e,t,[])}function ve(t){clearTimeout(ft),ft=setTimeout(()=>{try{u.onLayoutChange?u.onLayoutChange(t):xe()}catch(e){E(e,"layout-changed")}P("layout-changed",{reason:t})},be)}function or(t,e){let r=[...t.querySelectorAll("img")].filter(o=>!o.complete),n=r.length,i=()=>{n-=1,n===0&&ve(`${e}:images`)};r.forEach(o=>{o.addEventListener("load",i,{once:!0}),o.addEventListener("error",i,{once:!0})})}function ir(t,e){return t.getAttribute("aria-busy")==="true"?Promise.resolve(void 0):(t.setAttribute("aria-busy","true"),Promise.resolve().then(e).finally(()=>{t.removeAttribute("aria-busy")}))}function sr(t,e){let r=t?O(t,e):null;if(!r)return null;try{return JSON.parse(r)}catch{return T(`invalid JSON in ${g(e)}`,t),null}}function U(t){return t==null?"":typeof t=="string"?t:typeof t=="number"||typeof t=="boolean"?String(t):JSON.stringify(t)}function ar(t){return Array.isArray(t)?t.filter(h).map(r=>({key:U(r.key),value:U(r.value)})):h(t)?Object.entries(t).map(([e,r])=>({key:e,value:U(r)})):[]}function ur(t){return t?Array.isArray(t)?t.map(e=>({key:String(e.key),value:String(e.value??"")})):Object.entries(t).map(([e,r])=>({key:e,value:String(r??"")})):[]}export{p as a,x as b,Re as c,Oe as d,ht as e,Pe as f,Lt as g,Ct as h,Nt as i,Me as j,_e as k,g as l,It as m,O as n,Rt as o,K as p,Ot as q,Pt as r,Mt as s,P as t,tt as u,rt as v,Ht as w,Ut as x,$t as y,Vt as z,Ke as A,Je as B,Xe as C,Ze as D,tr as E,we as F,er as G,rr as H,nr as I,Se as J,ve as K,or as L,ir as M,sr as N,ar as O,ur as P};
@@ -1 +0,0 @@
1
- var e={diagnose:()=>import("./diagnose-3FEKRIEK.js"),markets:()=>import("./markets-ui-FD6NI2OG.js"),search:()=>import("./search-UJ73YBQ5.js"),extras:()=>import("./extras-6POFBNOP.js"),account:()=>import("./account-UIPWJQ3Y.js"),"account-pages":()=>import("./account-pages-6ROA6Y4V.js"),analytics:()=>import("./analytics-2V632IRV.js")},a=t=>e[t](),r=void 0;export{a,r as b};