@occluze/tether 0.8.1 → 0.9.1

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 (73) hide show
  1. package/README.md +5 -5
  2. package/dist/esm/astro.js +1 -1
  3. package/dist/esm/chunks/account-LCMJ7QU5.js +1 -0
  4. package/dist/esm/chunks/{account-pages-XR6QZ3DX.js → account-pages-3C5KTPQV.js} +1 -1
  5. package/dist/esm/chunks/analytics-VWSZOX2D.js +1 -0
  6. package/dist/esm/chunks/{chunk-HXZSNZOV.js → chunk-2A2GN3Z7.js} +1 -1
  7. package/dist/esm/chunks/{chunk-A3GXCQJ4.js → chunk-2IGCUTG5.js} +1 -1
  8. package/dist/esm/chunks/{chunk-COQ6ATC6.js → chunk-3UCVDDK6.js} +1 -1
  9. package/dist/esm/chunks/chunk-D3MRWOFI.js +1 -0
  10. package/dist/esm/chunks/chunk-EUCFOBIT.js +1 -0
  11. package/dist/esm/chunks/{chunk-A2PCQK2F.js → chunk-F2BYVA7V.js} +1 -1
  12. package/dist/esm/chunks/chunk-HROQXZYN.js +1 -0
  13. package/dist/esm/chunks/{chunk-X2JZPXLF.js → chunk-MJNPD6LB.js} +1 -1
  14. package/dist/esm/chunks/{chunk-FM7ZLLVP.js → chunk-OURC3H6L.js} +1 -1
  15. package/dist/esm/chunks/chunk-P6DV24RG.js +1 -0
  16. package/dist/esm/chunks/chunk-P73VN3B6.js +1 -0
  17. package/dist/esm/chunks/chunk-S5BUUIB6.js +1 -0
  18. package/dist/esm/chunks/chunk-SOFWDTR7.js +1 -0
  19. package/dist/esm/chunks/{chunk-FPJGQ7Z5.js → chunk-XU27NSXT.js} +1 -1
  20. package/dist/esm/chunks/chunk-YJC3CSEG.js +1 -0
  21. package/dist/esm/chunks/chunk-ZBV2JSHE.js +1 -0
  22. package/dist/esm/chunks/{diagnose-IFRNCEYG.js → diagnose-TE72GNOO.js} +1 -1
  23. package/dist/esm/chunks/extras-7GTMJMOZ.js +1 -0
  24. package/dist/esm/chunks/lists-ZMVRGD6L.js +1 -0
  25. package/dist/esm/chunks/markets-ui-AAQM4PEE.js +1 -0
  26. package/dist/esm/chunks/search-PWF4YZQO.js +1 -0
  27. package/dist/esm/index.js +1 -1
  28. package/dist/esm/server.js +2 -2
  29. package/dist/tether.account-pages.js +2 -2
  30. package/dist/tether.account-pages.min.js +1 -1
  31. package/dist/tether.account.js +2 -2
  32. package/dist/tether.account.min.js +1 -1
  33. package/dist/tether.analytics.js +2 -2
  34. package/dist/tether.analytics.min.js +1 -1
  35. package/dist/tether.diagnose.js +4 -4
  36. package/dist/tether.diagnose.min.js +2 -2
  37. package/dist/tether.extras.js +1 -1
  38. package/dist/tether.extras.min.js +1 -1
  39. package/dist/tether.js +85 -201
  40. package/dist/tether.lists.js +268 -0
  41. package/dist/tether.lists.min.js +1 -0
  42. package/dist/tether.markets.js +3 -3
  43. package/dist/tether.markets.min.js +1 -1
  44. package/dist/tether.min.js +1 -1
  45. package/dist/tether.min.js.map +4 -4
  46. package/dist/tether.search.js +2 -2
  47. package/dist/tether.search.min.js +1 -1
  48. package/dist/types/src/client.d.ts +6 -6
  49. package/dist/types/src/collection.d.ts +7 -23
  50. package/dist/types/src/config-sections.d.ts +7 -0
  51. package/dist/types/src/config.d.ts +6 -0
  52. package/dist/types/src/index.d.ts +4 -3
  53. package/dist/types/src/lazy.d.ts +1 -0
  54. package/dist/types/src/lists.d.ts +20 -0
  55. package/dist/types/src/loader.d.ts +7 -27
  56. package/dist/types/src/mounting.d.ts +1 -6
  57. package/dist/types/src/product-shape.d.ts +13 -36
  58. package/dist/types/src/server.d.ts +5 -4
  59. package/dist/types/src/shopify-values.d.ts +6 -0
  60. package/dist/types/src/storefront/catalog.d.ts +2 -4
  61. package/dist/types/src/version.d.ts +1 -1
  62. package/package.json +7 -6
  63. package/dist/esm/chunks/account-BS5MCC2R.js +0 -1
  64. package/dist/esm/chunks/analytics-BYN3QHBA.js +0 -1
  65. package/dist/esm/chunks/chunk-2IVIZDT5.js +0 -1
  66. package/dist/esm/chunks/chunk-EGIDFV3T.js +0 -1
  67. package/dist/esm/chunks/chunk-EW3GKRT4.js +0 -1
  68. package/dist/esm/chunks/chunk-GXCCTPDF.js +0 -1
  69. package/dist/esm/chunks/chunk-MJFKAMFM.js +0 -1
  70. package/dist/esm/chunks/chunk-TE5PNI76.js +0 -1
  71. package/dist/esm/chunks/extras-3477M6Y7.js +0 -1
  72. package/dist/esm/chunks/markets-ui-3L2UZ7PK.js +0 -1
  73. package/dist/esm/chunks/search-YR73GIWY.js +0 -1
@@ -19,11 +19,11 @@
19
19
 
20
20
  // tether-core:client.ts
21
21
  var m2 = window.Tether.__core["client.ts"];
22
- var [endpoint, gql, orNull, shaped, TetherError] = m2;
22
+ var [endpoint, gql, matches, orNull, shaped, TetherError] = m2;
23
23
 
24
24
  // tether-core:dom.ts
25
25
  var m3 = window.Tether.__core["dom.ts"];
26
- var [ANALYTICS_EVENTS, attr, attributesFromJson, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, parseJSONAttr, productUrl, qsa, repeat, sel, setImage, setText, show] = m3;
26
+ var [ANALYTICS_EVENTS, attr, attributesFromJson, busy, emit, formatDate, formatMoney, get, has, hasTemplate, isOwnEvent, notifyLayoutChanged, parseJSONAttr, productUrl, qsa, repeat, scoped, sel, setImage, setStoreHtml, setText, show] = m3;
27
27
 
28
28
  // tether-core:mounting.ts
29
29
  var m4 = window.Tether.__core["mounting.ts"];
@@ -1 +1 @@
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);})();
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 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,ot,x,A,at]=j;var K=window.Tether.__core["dom.ts"],[ct,L,ht,ut,I,mt,k,m,dt,pt,ft,gt,wt,N,h,C,yt,l,R,Tt,P,d]=K;var Q=window.Tether.__core["mounting.ts"],[St,Et,xt,At,Lt,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 U=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"?R(e,t.image?.url,t.image?.altText||t.title):(r==="title"||r==="price"||r==="text")&&t[r]!=null&&P(e,t[r])})}function H(i,t){let e=U(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(L("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=>{C(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}),H(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}),H(s,`${(u.collectionPath||"/collection").replace(/\/$/,"")}/${n.handle}`)}),this.fillList("search-queries",c,(s,n)=>{f(s,{text:n.text}),U(s)?.setAttribute("href",this.queryUrl(n.text))});let y=r.length+a.length+c.length;this.showCount(y),this.setState(y?"ready":"empty"),this.open(!0),I("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);})();
@@ -30,7 +30,7 @@ export declare class TetherError extends Error {
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. */
33
- export type StorefrontConfig = Pick<TetherConfig, 'domain' | 'token' | 'apiVersion' | 'country' | 'language' | 'maxAge' | 'retries'> & {
33
+ export type StorefrontConfig = Pick<TetherConfig, 'domain' | 'token' | 'apiVersion' | 'country' | 'language' | 'maxAge' | 'retries' | 'requestTimeout'> & {
34
34
  fetch?: typeof fetch;
35
35
  };
36
36
  /** Checks a query's `data` before its caller reads it as a `T`. */
@@ -113,11 +113,11 @@ export declare function withContext(query: string, ctx?: {
113
113
  * `conf.retries`; which failures are retried is the operation's (`Operation`).
114
114
  *
115
115
  * @param isData Checks that `data` has what the caller then reads, so a malformed answer fails here.
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.
116
+ * @throws {TetherError} `NOT_CONFIGURED` without a domain or token, `NETWORK` when the store can't be reached, the
117
+ * answer's body stops arriving or the whole answer takes longer than `conf.requestTimeout`, `INVALID_RESPONSE` for
118
+ * a 2xx whose body isn't valid (not JSON, not in the GraphQL shape, or `data` that `isData` refuses),
119
+ * `SERVER_ERROR` for a 2xx whose GraphQL errors leave open whether Shopify ran it (a top-level
120
+ * `INTERNAL_SERVER_ERROR`, or a mutation's errors without `data`), `HTTP_<status>` for any other HTTP or GraphQL failure.
121
121
  */
122
122
  export declare function request<T>(conf: StorefrontConfig, query: QueryText, variables: Record<string, unknown>, isData: DataCheck<T>, { context, operation }?: RequestOptions): Promise<T>;
123
123
  /** `request` with the browser's shared config. */
@@ -1,25 +1,9 @@
1
- import type { Product } from './fragments.js';
2
- import type { Collection, PageInfo, ProductQuery } from './loader.js';
3
1
  export declare const listSelector: () => string;
4
- export declare class ListScope {
5
- readonly root: HTMLElement;
6
- products: Product[];
7
- pageInfo: PageInfo | null;
8
- collection: Collection | null;
9
- /** Counts loads, so only the latest one renders. */
10
- loadToken: number;
11
- constructor(root: HTMLElement);
12
- $(selector: string): HTMLElement[];
13
- /** The collection or search query of the list's attributes. */
14
- options(): ProductQuery;
15
- /**
16
- * The product of a recommendations list: a handle, `url:…` (one dynamic product page), or empty inside a product
17
- * scope for that product.
18
- *
19
- * @throws {TetherError} `NOT_FOUND` when there is no product to recommend for.
20
- */
21
- loadRecommendations(): Promise<Product[]>;
22
- /** @param more Appends the next page instead of replacing the products. */
23
- load(more?: boolean): Promise<void>;
24
- render(): void;
2
+ /** A mounted list: its root, and loading its products again (after a country switch, or back online). */
3
+ export interface MountedList {
4
+ root: HTMLElement;
5
+ /** Never rejects: a failure shows in the list's state and is reported. */
6
+ load: () => Promise<void>;
25
7
  }
8
+ /** @returns The list at `root`, in its loading state until its first load renders it. */
9
+ export declare function mountedList(root: HTMLElement): MountedList;
@@ -30,6 +30,13 @@ export declare function embedOriginsOption(value: unknown, invalid: Invalid): st
30
30
  export declare function toMetafieldIdentifier(ref: unknown): MetafieldIdentifier | null;
31
31
  /** @returns The refs that name a valid identifier, as written; each other one is skipped with a warning. */
32
32
  export declare function metafieldsOption(value: unknown, invalid: Invalid): MetafieldRef[];
33
+ /** How each field of a nested option is read: the field's value when it is of the right kind, else `undefined`. */
34
+ type Schema<Section extends object> = {
35
+ [Key in keyof Section]-?: (value: unknown) => Section[Key] | undefined;
36
+ };
37
+ export declare const ACCOUNT: Schema<Partial<AccountConfig>>;
38
+ export declare const MARKETS: Schema<MarketsConfig>;
39
+ export declare const ANALYTICS: Schema<AnalyticsConfig>;
33
40
  /**
34
41
  * @param warn Says why an `account` without a usable `server` is off.
35
42
  * @returns `null` without a usable `account.server`: nothing of the account part loads.
@@ -98,6 +98,12 @@ export interface TetherConfig {
98
98
  * already have applied the change.
99
99
  */
100
100
  retries: number;
101
+ /**
102
+ * Milliseconds a Storefront request may take, its body included, before it counts as a network error (0: no limit;
103
+ * at most 2147483647, the longest delay a timer keeps). A query is then retried; a mutation isn't, and a cart change
104
+ * loads the cart again.
105
+ */
106
+ requestTimeout: number;
101
107
  /** Refresh server-rendered products once in the background. */
102
108
  revalidate: boolean;
103
109
  /** The localStorage key of the cart id (default `<prefix>:cart:<domain>`). */
@@ -1,6 +1,6 @@
1
1
  /// <reference path="./globals.d.ts" />
2
2
  import { query, TetherError, withContext } from './client.js';
3
- import { getProduct, getProducts, getRecommendations, clearProductCache, primeProduct } from './loader.js';
3
+ import { getProduct, clearProductCache, primeProduct } from './loader.js';
4
4
  import * as plans from './selling-plans.js';
5
5
  import { resolveProductKey } from './status.js';
6
6
  import { formatMoney, imageUrl } from './dom.js';
@@ -12,6 +12,7 @@ import type { ShopifyCart } from './cart/store.js';
12
12
  import type { ProductScope } from './product.js';
13
13
  import type { DiagnoseOptions } from './diagnose.js';
14
14
  import type { TetherEvents } from './markup.js';
15
+ import type { ProductQuery } from './loader.js';
15
16
  export { addGroup, setCountry, VERSION };
16
17
  export type { TetherOptions as TetherConfig, TetherConfig as ResolvedTetherConfig } from './config.js';
17
18
  export type { MarketsConfig, CartWarning } from './config.js';
@@ -111,8 +112,8 @@ declare const publicApi: {
111
112
  toggle: typeof import("./cart/drawer.js").toggleCart;
112
113
  };
113
114
  getProduct: typeof getProduct;
114
- getProducts: typeof getProducts;
115
- getRecommendations: typeof getRecommendations;
115
+ getProducts: (query?: ProductQuery) => Promise<import("./loader.js").ProductPage>;
116
+ getRecommendations: typeof import("./lists.js").getRecommendations;
116
117
  getScope: typeof getScope;
117
118
  addGroup: (button: Element) => Promise<ShopifyCart | null>;
118
119
  account: {
@@ -7,6 +7,7 @@ export interface Parts {
7
7
  diagnose: typeof import('./diagnose.js');
8
8
  markets: typeof import('./markets-ui.js');
9
9
  search: typeof import('./search.js');
10
+ lists: typeof import('./lists.js');
10
11
  extras: typeof import('./extras.js');
11
12
  account: typeof import('./account.js');
12
13
  'account-pages': typeof import('./account-pages.js');
@@ -0,0 +1,20 @@
1
+ import type { Product } from './fragments.js';
2
+ import type { ProductRef, RecommendationIntent } from './shopify-values.js';
3
+ import type { ProductPage, ProductQuery } from './loader.js';
4
+ /**
5
+ * A page of products from a collection (by handle) or from a search. Every product on it is cached.
6
+ *
7
+ * @throws {TetherError} `NOT_FOUND` for a collection the store doesn't have.
8
+ */
9
+ export declare function getProducts({ collection, query, first, after, sortKey, reverse, filters, }?: ProductQuery): Promise<ProductPage>;
10
+ /**
11
+ * Shopify's recommendations for a product. Every product in them is cached.
12
+ *
13
+ * @throws {TetherError} `NOT_FOUND` when `product` names no product (empty, `null` or `undefined`).
14
+ */
15
+ export declare function getRecommendations(product: ProductRef | null | undefined, intent?: RecommendationIntent): Promise<Product[]>;
16
+ /**
17
+ * Loads the products of the list at `root` and renders them, replacing what it shows. Never rejects: a failure shows
18
+ * in the list's state and is reported.
19
+ */
20
+ export declare function loadList(root: HTMLElement): Promise<void>;
@@ -1,6 +1,6 @@
1
1
  import { productKey } from './shopify-values.js';
2
2
  import type { Product, Image } from './fragments.js';
3
- import type { ProductConnection } from './product-shape.js';
3
+ import type { QueryText } from './client.js';
4
4
  /** Accepts a handle, numeric id, gid or a full product URL. */
5
5
  export declare const normalizeProductKey: typeof productKey;
6
6
  /** Puts a product the page already has (from a collection query) in the cache, under its handle and its id. */
@@ -10,6 +10,12 @@ export declare function primeProduct(product: Product | null | undefined): void;
10
10
  * @throws {TetherError} `NOT_FOUND` (rejected) for an empty key or a product the store doesn't have.
11
11
  */
12
12
  export declare function getProduct(rawKey: string | number | null | undefined): Promise<Product>;
13
+ /**
14
+ * @param operation An operation that spreads `...TetherProduct`.
15
+ * @returns The operation with the product fragment (which starts on its own line), written for what the token may
16
+ * read.
17
+ */
18
+ export declare const withProductFragment: (operation: string) => QueryText;
13
19
  /** Forgets every product, for a new market: requests already sent no longer fill the cache. */
14
20
  export declare function clearProductCache(): void;
15
21
  /**
@@ -56,29 +62,3 @@ export interface ProductQuery {
56
62
  /** `ProductFilter` values, for a collection. */
57
63
  filters?: unknown[];
58
64
  }
59
- /** A collection's answer: `null` for a handle the store doesn't have. Its other fields are written as text. */
60
- export declare const isCollectionAnswer: import("./client.js").DataCheck<{
61
- collection: (Collection & {
62
- products: ProductConnection;
63
- }) | null;
64
- }>;
65
- export declare const isSearchAnswer: import("./client.js").DataCheck<{
66
- products: ProductConnection;
67
- }>;
68
- export declare const isRecommendationsAnswer: import("./client.js").DataCheck<{
69
- productRecommendations: Product[] | null;
70
- }>;
71
- /**
72
- * A page of products from a collection (by handle) or from a search. Every product on it is cached.
73
- *
74
- * @throws {TetherError} `NOT_FOUND` for a collection the store doesn't have.
75
- */
76
- export declare function getProducts({ collection, query, first, after, sortKey, reverse, filters, }?: ProductQuery): Promise<ProductPage>;
77
- /**
78
- * Shopify's recommendations for a product. Every product in them is cached.
79
- *
80
- * @param product A product, or its handle, id or gid.
81
- */
82
- export declare function getRecommendations(product: string | number | {
83
- id: string;
84
- } | null | undefined, intent?: 'RELATED' | 'COMPLEMENTARY'): Promise<Product[]>;
@@ -1,8 +1,4 @@
1
- /** A mounted `ListScope`. */
2
- interface MountedList {
3
- root: Element;
4
- load: (more?: boolean) => Promise<unknown>;
5
- }
1
+ import type { MountedList } from './collection.js';
6
2
  export declare const mountedProducts: WeakSet<Element>;
7
3
  export declare const mountedLists: WeakSet<Element>;
8
4
  /** Product roots to re-render after a country switch; pruned once disconnected. */
@@ -43,4 +39,3 @@ export declare function settleMarket(): void;
43
39
  * added elements for `observe`.
44
40
  */
45
41
  export declare function hydrateFromPage(root?: Document | Element): void;
46
- export {};
@@ -1,5 +1,5 @@
1
1
  import type { Product } from './fragments.js';
2
- import type { PageInfo } from './loader.js';
2
+ import type { Collection, PageInfo } from './loader.js';
3
3
  /** A page of a GraphQL connection of products. */
4
4
  export interface ProductConnection {
5
5
  nodes: Product[];
@@ -44,41 +44,6 @@ export declare const PRODUCT: {
44
44
  }];
45
45
  };
46
46
  };
47
- /** A page of products, with the `pageInfo` paging reads. */
48
- export declare const PRODUCT_CONNECTION: {
49
- readonly nodes: readonly [{
50
- readonly id: "string";
51
- readonly handle: "string";
52
- readonly title: "string";
53
- readonly options: readonly ["object"];
54
- readonly images: {
55
- readonly nodes: readonly ["object"];
56
- };
57
- readonly priceRange: {
58
- readonly minVariantPrice: {
59
- readonly amount: "string";
60
- readonly currencyCode: "string";
61
- };
62
- readonly maxVariantPrice: {
63
- readonly amount: "string";
64
- readonly currencyCode: "string";
65
- };
66
- };
67
- readonly variants: {
68
- readonly nodes: readonly [{
69
- readonly id: "string";
70
- readonly price: {
71
- readonly amount: "string";
72
- readonly currencyCode: "string";
73
- };
74
- readonly selectedOptions: readonly ["object"];
75
- }];
76
- };
77
- }];
78
- readonly pageInfo: {
79
- readonly hasNextPage: "boolean";
80
- };
81
- };
82
47
  /** True for a value with the structure of `PRODUCT` and a non-empty id and handle. */
83
48
  export declare const isProductShape: (value: unknown) => value is Product;
84
49
  /**
@@ -88,3 +53,15 @@ export declare const isProductShape: (value: unknown) => value is Product;
88
53
  export declare const PRODUCT_NODE: (node: unknown) => node is Product | {
89
54
  id?: undefined;
90
55
  };
56
+ /** A collection's answer: `null` for a handle the store doesn't have. Its other fields are written as text. */
57
+ export declare const isCollectionAnswer: import("./client.js").DataCheck<{
58
+ collection: (Collection & {
59
+ products: ProductConnection;
60
+ }) | null;
61
+ }>;
62
+ export declare const isSearchAnswer: import("./client.js").DataCheck<{
63
+ products: ProductConnection;
64
+ }>;
65
+ export declare const isRecommendationsAnswer: import("./client.js").DataCheck<{
66
+ productRecommendations: Product[] | null;
67
+ }>;
@@ -22,7 +22,10 @@ export type { JsonLdOptions } from './storefront/json-ld.js';
22
22
  export type Storefront = ReturnType<typeof createStorefront>;
23
23
  /** The options only a storefront has. */
24
24
  interface ServerOptions {
25
- /** Replaces the global `fetch` (tests, caching). */
25
+ /**
26
+ * Replaces the global `fetch` (tests, caching). It must pass `init.signal` on to the request: `requestTimeout` ends a
27
+ * stalled request through that signal, and a request that ignores it is never ended.
28
+ */
26
29
  fetch?: typeof fetch;
27
30
  /** Products per request for `allProducts()` (default 25). */
28
31
  pageSize?: number;
@@ -78,9 +81,7 @@ export declare function createStorefront(options?: StorefrontOptions): {
78
81
  pageInfo: import("./loader.js").PageInfo;
79
82
  }) | null>;
80
83
  allCollections: () => Promise<import("./loader.js").Collection[]>;
81
- getRecommendations: (product: string | number | {
82
- id: string;
83
- } | null | undefined, intent?: "RELATED" | "COMPLEMENTARY") => Promise<Product[]>;
84
+ getRecommendations: (product: import("./shopify-values.js").ProductRef | null | undefined, intent?: import("./shopify-values.js").RecommendationIntent) => Promise<Product[]>;
84
85
  config: ServerConfig;
85
86
  query: (query: string, variables?: Record<string, unknown>, requestOptions?: {
86
87
  context?: boolean;
@@ -38,6 +38,12 @@ export declare function formatMoney(money: Money | null | undefined, locale: str
38
38
  * @returns `null` when the path needs a handle or an id the product lacks: no link beats a wrong one.
39
39
  */
40
40
  export declare function productUrl(productPath: string, handle: string | null | undefined, id?: string | null): string | null;
41
+ /** A product to recommend for: the product itself, or its handle, numeric id or gid. */
42
+ export type ProductRef = string | number | {
43
+ id: string;
44
+ };
45
+ /** Shopify's `ProductRecommendationIntent`. */
46
+ export type RecommendationIntent = 'RELATED' | 'COMPLEMENTARY';
41
47
  /**
42
48
  * The key Tether loads a product by: a handle, or a product gid.
43
49
  *
@@ -1,5 +1,6 @@
1
1
  import type { StorefrontConfig } from '../client.js';
2
2
  import type { ProductFragmentConfig, Product } from '../fragments.js';
3
+ import type { ProductRef, RecommendationIntent } from '../shopify-values.js';
3
4
  import type { Collection, PageInfo, ProductPage } from '../loader.js';
4
5
  /** What the catalog needs of a storefront's config. */
5
6
  type CatalogConfig = StorefrontConfig & ProductFragmentConfig;
@@ -23,7 +24,6 @@ type CollectionWithProducts = Collection & {
23
24
  products: Product[];
24
25
  pageInfo: PageInfo;
25
26
  };
26
- type RecommendationIntent = 'RELATED' | 'COMPLEMENTARY';
27
27
  /** @param pageSize Products per page when a query doesn't say. */
28
28
  export declare function createCatalog(conf: CatalogConfig, pageSize: number): {
29
29
  getProduct: (raw: string | number | null | undefined) => Promise<Product | null>;
@@ -31,8 +31,6 @@ export declare function createCatalog(conf: CatalogConfig, pageSize: number): {
31
31
  allProducts: (options?: Omit<CatalogQuery, "first" | "after">) => Promise<Product[]>;
32
32
  getCollection: (handle: string, options?: Omit<CatalogQuery, "collection">) => Promise<CollectionWithProducts | null>;
33
33
  allCollections: () => Promise<Collection[]>;
34
- getRecommendations: (product: string | number | {
35
- id: string;
36
- } | null | undefined, intent?: RecommendationIntent) => Promise<Product[]>;
34
+ getRecommendations: (product: ProductRef | null | undefined, intent?: RecommendationIntent) => Promise<Product[]>;
37
35
  };
38
36
  export {};
@@ -1 +1 @@
1
- export declare const VERSION = "0.8.1";
1
+ export declare const VERSION = "0.9.1";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@occluze/tether",
3
- "version": "0.8.1",
3
+ "version": "0.9.1",
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",
@@ -22,7 +22,7 @@
22
22
  "types": "./dist/types/src/presets/barba.d.ts",
23
23
  "default": "./dist/presets/barba.esm.js"
24
24
  },
25
- "./dist/*": "./dist/*"
25
+ "./dist/tether.*": "./dist/tether.*"
26
26
  },
27
27
  "files": [
28
28
  "dist",
@@ -37,19 +37,21 @@
37
37
  "lint": "eslint .",
38
38
  "typecheck": "tsc -b",
39
39
  "knip": "knip",
40
+ "lint:workflows": "node --experimental-strip-types scripts/lint-workflows.ts",
40
41
  "deps": "depcruise --config .config/dependency-cruiser.cjs src server/src server/bin server/scripts scripts",
41
42
  "check": "npm run format:check && npm run lint && npm run typecheck && npm run knip && npm run deps && npm test",
42
43
  "prepare": "lefthook install",
43
- "test": "node --experimental-strip-types --test test/*.test.js server/test/*.test.js && npm run test:types",
44
+ "test": "node --experimental-strip-types --import ./scripts/test-leaks.ts --test --test-timeout=300000 --test-force-exit --test-reporter=spec --test-reporter-destination=stdout --test-reporter=./scripts/test-leaks.ts --test-reporter-destination=stderr test/*.test.js server/test/*.test.js && npm run test:types",
44
45
  "test:types": "tsc -p test/types/tsconfig.json",
45
46
  "smoke": "node --experimental-strip-types scripts/smoke.ts",
46
47
  "pretest": "node --experimental-strip-types scripts/build.ts --out .test-dist",
47
48
  "presmoke": "node --experimental-strip-types scripts/build.ts",
48
49
  "release": "node --experimental-strip-types scripts/release.ts",
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:build": "npm run build && node --experimental-strip-types scripts/e2e-build.ts && cd examples/astro && npm install --no-save --no-audit --no-fund --ignore-scripts ../.. && npx astro build",
50
51
  "e2e": "npm run e2e:build && playwright test -c test/e2e/playwright.config.js"
51
52
  },
52
53
  "devDependencies": {
54
+ "@eslint-community/eslint-plugin-eslint-comments": "4.8.1",
53
55
  "@eslint/js": "10.0.1",
54
56
  "@playwright/test": "1.64.1",
55
57
  "@tsconfig/strictest": "2.0.8",
@@ -154,8 +156,7 @@
154
156
  "scripts/*.ts",
155
157
  "test/**/*.js",
156
158
  "server/test/**/*.js",
157
- "test/e2e/*.{js,mjs}",
158
- "test/types/check.ts"
159
+ "test/e2e/*.{js,mjs}"
159
160
  ],
160
161
  "project": [
161
162
  "src/**/*.ts",
@@ -1 +0,0 @@
1
- import{f as j,g as V,h as G,i as R,m as v,n as H}from"./chunk-FM7ZLLVP.js";import{a as O,c as M}from"./chunk-X2JZPXLF.js";import{a as W}from"./chunk-EGIDFV3T.js";import{f as q,g as F,h as P}from"./chunk-MJFKAMFM.js";import"./chunk-2IVIZDT5.js";import{C as $,D as _,F as A,H as L,a as f,m as c,n as l,p as d,t as h,w as N,y as D}from"./chunk-EW3GKRT4.js";import{A as T,C as U,d as I,g as y,r as i,x as E,z as m}from"./chunk-GXCCTPDF.js";var g=null;function X(){let e=i.account?.server;if(!e)throw new f("Customer accounts need the Worker: set account.server",{code:"NOT_CONFIGURED"});return new URL(e,window.location.href).href.replace(/\/$/,"")}function B(e){e?q(O(),"1"):F(O())}async function ae(e,t){try{return await fetch(e,t)}catch(r){throw new f(`Network error: ${T(r)}`,{code:"NETWORK"})}}async function ue(e){let t;try{t=await e.json()}catch{return{}}return I(t)?t:{}}async function p(e,{method:t="GET",body:r}={}){let n={method:t,credentials:"include"};t==="POST"&&(n.headers={"Content-Type":"application/json","X-Tether-Account":"1"}),r&&(n.body=JSON.stringify(r));let s=await ae(`${X()}${e}`,n);if(s.status===401)return{kind:"logged-out"};let o=await ue(s);if(!s.ok){let u=y(o.error)??String(s.status),w=G(o.userErrors);throw new f(`Customer accounts: ${u}`,{status:s.status,...w.length>0&&{userErrors:w},...o.code==="INVALID"&&{code:"INVALID"}})}return{kind:"answer",data:o}}async function k(){if(!g){let e=await p("/me");g=e.kind==="answer"&&e.data.loggedIn===!0?{loggedIn:!0,customer:j(e.data.customer)}:{loggedIn:!1}}return B(g.loggedIn),g}var J=()=>g?.loggedIn===!0;function K(){g=null}function z(e){let t=i.account?.navigate;t?t(e):window.location.assign(e)}var de=e=>e||i.account?.locale||(i.locale||"").split("-")[0]||"";function Q({returnTo:e,locale:t}){let r=new URL(`${X()}/login`);r.searchParams.set("returnTo",e);let n=de(t);n&&r.searchParams.set("locale",n),i.country&&r.searchParams.set("country",i.country.toUpperCase()),z(r.toString())}async function Y(){let e=P.id();if(!(await k()).loggedIn||!e)return null;let t=await p("/cart",{method:"POST",body:{cartId:e}});return t.kind==="logged-out"?null:y(t.data.checkoutUrl)}async function Z(e){let t=await p("/logout",{method:"POST",body:{returnTo:e,cartId:P.id()}});g=null,B(!1),h("account-logout",{});let r=t.kind==="answer"?y(t.data.logoutUrl):null;return r?(z(r),"redirected"):"stayed"}var b=10,S=50,ee=e=>typeof e=="number"&&Number.isInteger(e)&&e>=1&&e<=S;function le(e){let t=Number.parseInt(e||String(b),10)||b;return Math.min(Math.max(t,1),S)}var me=e=>e.replace(/\?.*$/,"").replace(/^.*\//,"");function ge(e){let t=i.account?.orderUrl;if(t)return t.replaceAll("{id}",encodeURIComponent(me(e.id)));let r=e.statusPageUrl;return r!==null&&U(r)?r:null}var fe=e=>({name:e.name??"",date:_(e.processedAt),total:$(e.totalPrice),status:e.financialStatus?.toLowerCase(),fulfillment:e.fulfillmentStatus?.toLowerCase(),items:e.lineItems.nodes.map(t=>`${String(t.quantity)}\xD7 ${t.title??""}`).join(", ")});function pe(e,t){let r=t.lineItems.nodes,n=ge(t),s=fe(t);d(e,c("order-bind")).forEach(o=>{let u=l(o,"order-bind")??"";if(u==="url"){n&&o.setAttribute("href",n);return}if(u==="image"){let x=r.find(ce=>ce.image)?.image;x&&N(o,x.url,x.altText||r[0]?.title||"");return}let w=v(s,u);w!==void 0&&A(o,w)}),d(e,c("order-lines")).forEach(o=>{H(o,r,null)}),l(e,"order-bind")==="url"&&n&&e.setAttribute("href",n)}async function te(e,t){let r=d(e,c("orders")),n=r[0];if(!n)return;R(e,"show",{"orders-loading":!0,"orders-empty":!1});let s=le(l(n,"limit")),o;try{o=await t(s)}catch(u){m(u,"orders"),o=null}R(e,"show",{"orders-loading":!1,"orders-empty":o?.length===0}),r.forEach(u=>{D(u,o??[],pe)})}var we=["order","addresses","subscriptions","profile-form","address-form"],he=J;function Pe({returnTo:e=window.location.href,locale:t}={}){return new Promise(r=>{Q({returnTo:e,locale:t}),r()})}async function se(){let e=await k();return e.loggedIn?e.customer:null}async function ye({first:e=b}={}){if(!ee(e))throw new f(`Customer accounts: orders() takes first from 1 to ${String(S)}`,{code:"INVALID"});let t=await p(`/orders?${new URLSearchParams({first:String(e)}).toString()}`);return t.kind==="logged-out"?[]:V(t.data.orders)}async function Ae({returnTo:e=i.account?.logoutUrl||`${window.location.origin}/`}={}){await Z(e)==="stayed"&&await C(document)}async function ve(){try{return(await k()).loggedIn?{kind:"logged-in"}:{kind:"logged-out"}}catch(e){return{kind:"unknown",error:e}}}var re=e=>we.some(t=>d(e,c(t)).length>0);function ke(e){d(e,c("account-link")).forEach(t=>{t.setAttribute("href",be(l(t,"account-link")))})}function be(e){let t=i.account,r=`https://${i.domain}/account`;return e==="payment"?t?.paymentUrl||t?.subscriptionsUrl||r:e==="subscriptions"&&t?.subscriptionsUrl||r}async function C(e=document){let t=await ve();t.kind==="unknown"&&m(t.error,"account");let r=t.kind==="logged-in";if(d(e,c("show")).forEach(n=>{let s=l(n,"show");s==="logged-in"&&L(n,r),s==="logged-out"&&L(n,!r)}),ke(e),t.kind==="unknown"&&re(e)){(await a()).showUnavailable(e);return}r&&(await ie(e),await Promise.all([te(e,n=>ye({first:n})),re(e)?a().then(n=>n.renderPages(e)):null]))}async function ie(e){let t=d(e,c("account-bind"));if(!t.length)return;let r;try{r=await se()}catch(s){m(s,"account");return}if(!r)return;let n={"first-name":r.firstName,"last-name":r.lastName,name:r.displayName,email:r.emailAddress?.emailAddress,address:r.defaultAddress?.formatted.join(", ")};t.forEach(s=>{let o=v(n,l(s,"account-bind")??"");o!=null&&A(s,o)})}var ne=null;function a(){return ne??(ne=W("account-pages").then(e=>(e.setup({serverFetch:p,customer:se,bindCustomer:ie,reset:K}),e))),ne}var Ye=e=>a().then(t=>t.order(e)),Ze=e=>a().then(t=>t.updateProfile(e)),et=()=>a().then(e=>e.addresses()),tt=(e,t)=>a().then(r=>r.saveAddress(e,t)),rt=e=>a().then(t=>t.deleteAddress(e)),nt=()=>a().then(e=>e.subscriptions()),ot=(e,t)=>a().then(r=>r.subscriptionAction(e,t)),st=(e,t)=>a().then(r=>r.requestReturn(e,t));function Se(e){let t=e.target;t instanceof window.Element&&(t.closest(c("account-login"))?(e.preventDefault(),Pe().catch(r=>{m(r,"login")})):t.closest(c("account-logout"))&&(e.preventDefault(),Ae().catch(r=>{m(r,"logout")})))}function xe(){let e=new URL(window.location.href),t=e.searchParams.get("account");if(M(t))switch(e.searchParams.delete("account"),window.history.replaceState(window.history.state,"",e),t){case"in":h("account-login",{});break;case"expired":case"error":h("account-error",{error:t});break}}var oe=!1;async function it(e=document){if(oe){await C(e);return}oe=!0,document.addEventListener("click",Se),xe(),P.setCheckoutResolver(Y),await C(e),E("account",he()?"logged in":"logged out")}export{et as addresses,se as customer,rt as deleteAddress,he as isLoggedIn,Pe as login,Ae as logout,it as mountAccount,Ye as order,ye as orders,C as render,st as requestReturn,tt as saveAddress,ot as subscriptionAction,nt as subscriptions,Ze as updateProfile};
@@ -1 +0,0 @@
1
- import{a as A}from"./chunk-A2PCQK2F.js";import"./chunk-FPJGQ7Z5.js";import"./chunk-A3GXCQJ4.js";import{h}from"./chunk-MJFKAMFM.js";import"./chunk-2IVIZDT5.js";import{d as k,h as E,m as p,r as _,s as w}from"./chunk-EW3GKRT4.js";import{r as a,x as T,z as l}from"./chunk-GXCCTPDF.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 b,b as h,c as y,d as v,h as $}from"./chunk-EW3GKRT4.js";import{G as k,a as te,d as x,e as T,n as _,r as P,x as V}from"./chunk-GXCCTPDF.js";var de={};te(de,{GID:()=>Q,allPlans:()=>I,allocationFor:()=>M,findPlan:()=>ue,hasPlans:()=>oe,planAdjustment:()=>ce,planCheckoutCharge:()=>se,planPrice:()=>B,planSavings:()=>ae,plansForVariant:()=>le,toGid:()=>C});var re=/^(-?)(\d+)(?:\.(\d+))?$/;function G(e,n){let t=re.exec(e.trim());if(!t)return null;let[,r="",o="0",l=""]=t,u=BigInt(`${o}${l.padEnd(n,"0")}`);return r==="-"?-u:u}var L=e=>e.split(".")[1]?.length??0;function Fe(e,n){if(e==null||n==null)return!1;let t=Math.max(L(e.trim()),L(n.trim())),r=G(e,t),o=G(n,t);return r===null||o===null?!1:r>o}var q=2,U=new Map;function W(e){let n=U.get(e);if(n!==void 0)return n;let t=q;try{t=new Intl.NumberFormat("en",{style:"currency",currency:e}).resolvedOptions().maximumFractionDigits??q}catch{}return U.set(e,t),t}function O(e){return Math.round(parseFloat(e.amount)*10**W(e.currencyCode))}function K(e,n){let t=W(n);return{amount:(e/10**t).toFixed(t),currencyCode:n}}var ie=100;function C(e,n){let t=typeof e=="string"||typeof e=="number"?String(e).trim():"";return t?t.startsWith("gid://")?t:/^\d+$/.test(t)?`gid://shopify/${n}/${t}`:t:null}var Q={product:e=>C(e,"Product"),variant:e=>C(e,"ProductVariant"),sellingPlan:e=>C(e,"SellingPlan")};function I(e){return(e?.sellingPlanGroups?.nodes??[]).flatMap(t=>t.sellingPlans.nodes.map(r=>({...r,group:t})))}function oe(e){return I(e).length>0}function M(e,n){return!e||!n?null:(e.sellingPlanAllocations?.nodes??[]).find(r=>r.sellingPlan.id===n)??null}function le(e,n){return I(e).filter(t=>M(n,t.id))}function B(e,n){let t=M(e,n)?.priceAdjustments[0];return t?.perDeliveryPrice??t?.price??e?.price??null}function se(e,n){let t=M(e,n);return t?.checkoutChargeAmount??t?.priceAdjustments[0]?.price??e?.price??null}function ae(e,n){let t=B(e,n);if(!e||!t)return{amount:null,percentage:0};let r=parseFloat(e.price.amount),o=parseFloat(t.amount);if(!Number.isFinite(r)||!Number.isFinite(o)||r<=0||o>=r)return{amount:null,percentage:0};let l=O(e.price)-O(t);return{amount:K(l,e.price.currencyCode),percentage:Math.round((1-o/r)*ie)}}function ce(e){let n=e?.priceAdjustments[0]?.adjustmentValue;if(!n)return null;switch(n.__typename){case"SellingPlanPercentagePriceAdjustment":return{type:"percentage",value:n.adjustmentPercentage};case"SellingPlanFixedAmountPriceAdjustment":return{type:"amount",value:n.adjustmentAmount};case"SellingPlanFixedPriceAdjustment":return{type:"price",value:n.price};default:return null}}function ue(e,n){if(!n)return null;let t=I(e),r=Q.sellingPlan(n),o=n.trim().toLowerCase();return t.find(l=>l.id===r)??t.find(l=>l.name.toLowerCase()===o)??t.find(l=>l.options.some(u=>u.value.toLowerCase()===o))??null}var i="amount currencyCode",H={inventory:!0},Y=e=>e.inventory?"quantityAvailable":"",g="url altText width height";function pe(e){let n=[];for(let r of e){let o=_(r);o&&n.push(o)}return n.length?`metafields(identifiers:[${n.map(({namespace:r,key:o})=>`{namespace: ${JSON.stringify(r)}, key: ${JSON.stringify(o)}}`).join(", ")}]){namespace key type value reference{... on MediaImage{image{${g}}}}}`:""}var ge=` id name description recurringDeliveries options{name value}priceAdjustments{orderCount adjustmentValue{__typename ... on SellingPlanPercentagePriceAdjustment{adjustmentPercentage}... on SellingPlanFixedAmountPriceAdjustment{adjustmentAmount{${i}}}... on SellingPlanFixedPriceAdjustment{price{${i}}}}}`,me=` sellingPlan{id}checkoutChargeAmount{${i}}remainingBalanceChargeAmount{${i}}priceAdjustments{price{${i}}compareAtPrice{${i}}perDeliveryPrice{${i}}unitPrice{${i}}}`;function z(e=P,n=H){return` fragment TetherProduct on Product{id handle title description descriptionHtml productType vendor tags availableForSale publishedAt onlineStoreUrl requiresSellingPlan seo{title description}featuredImage{${g}}images(first:${e.imagesFirst}){nodes{${g}}}options{name optionValues{name swatch{color image{previewImage{${g}}}}}}priceRange{minVariantPrice{${i}}maxVariantPrice{${i}}}compareAtPriceRange{minVariantPrice{${i}}maxVariantPrice{${i}}}${pe(e.metafields)} sellingPlanGroups(first:${e.sellingPlanGroupsFirst}){nodes{name appName options{name values}sellingPlans(first:${e.sellingPlansFirst}){nodes{${ge}}}}}variants(first:${e.variantsFirst}){nodes{id title availableForSale currentlyNotInStock ${Y(n)} sku barcode selectedOptions{name value}image{${g}}price{${i}}compareAtPrice{${i}}unitPrice{${i}}sellingPlanAllocations(first:${e.sellingPlansFirst}){nodes{${me}}}}}}`}function Ne(e=H){return` fragment TetherCart on Cart{id checkoutUrl totalQuantity note createdAt updatedAt attributes{key value}buyerIdentity{countryCode email}discountCodes{code applicable}cost{subtotalAmount{${i}}totalAmount{${i}}checkoutChargeAmount{${i}}}lines(first:100){nodes{id quantity attributes{key value}cost{totalAmount{${i}}subtotalAmount{${i}}amountPerQuantity{${i}}compareAtAmountPerQuantity{${i}}}discountAllocations{discountedAmount{${i}}}sellingPlanAllocation{sellingPlan{id name description recurringDeliveries options{name value}}checkoutChargeAmount{${i}}priceAdjustments{price{${i}}compareAtPrice{${i}}perDeliveryPrice{${i}}}}merchandise{... on ProductVariant{id title sku availableForSale requiresShipping ${Y(e)} image{${g}}price{${i}}compareAtPrice{${i}}selectedOptions{name value}product{id title handle vendor featuredImage{${g}}}}}... on ComponentizableCartLine{lineComponents{id quantity merchandise{... on ProductVariant{id title product{title handle}}}}}}}}`}function J(){return` id handle title description descriptionHtml image{${g}}seo{title description}`}var N={amount:"string",currencyCode:"string"},f={id:"string",handle:"string",title:"string",options:["object"],images:{nodes:["object"]},priceRange:{minVariantPrice:N,maxVariantPrice:N},variants:{nodes:[{id:"string",price:N,selectedOptions:["object"]}]}},D={nodes:[f],pageInfo:{hasNextPage:"boolean"}},_e=e=>T(e,"id")!==""&&T(e,"handle")!==""&&h(e,f),X=e=>x(e)&&(e.id===void 0||h(e,f));var fe=1e4,Pe=6e4,c=new Map,E=new Map,m=new Set,F=new Map,ne=[],R=!1,A=0,Z=e=>e.startsWith("gid://"),j=k;function S(e){if(!e)return;let n=Promise.resolve(e);c.set(e.handle,n),c.set(e.id,n)}function he(e){let n=j(e);if(!n)return Promise.reject(new b("empty product key",{code:"NOT_FOUND"}));let t=c.get(n);if(t)return t;let r=new Promise((o,l)=>{E.set(n,{resolve:o,reject:l}),ne.push(n),R||(R=!0,setTimeout(()=>void Se(),0))});return c.set(n,r),r}var w=e=>n=>`${e}${z(P,n)}`;function ye(e){let n=e.filter(Z),t=e.filter(p=>!Z(p)),r=[],o=[],l={};return n.length&&(r.push("$ids: [ID!]!"),l.ids=n,o.push("byId:nodes(ids:$ids){... on Product{...TetherProduct}}")),t.forEach((p,s)=>{r.push(`$h${s}: String!`),l[`h${s}`]=p,o.push(`h${s}:product(handle:$h${s}){...TetherProduct}`)}),{query:w(`query TetherProducts(${r.join(",")}){${o.join(" ")}}`),variables:l,handles:t}}function ee(e,n){let t=E.get(e);E.delete(e),t&&n(t)}function $e(e,n){if(n!==A)return;let t=c.get(e);setTimeout(()=>{c.get(e)===t&&c.delete(e)},fe)}function Ae(e){if(!x(e))return!1;let{byId:n=[],...t}=e;return h(n,[y(X)])&&Object.values(t).every(y(f))}async function Se(){R=!1;let e=A,n=ne.splice(0);if(!n.length)return;let{query:t,variables:r,handles:o}=ye(n);V("fetch products",n);let l;try{l=await $(t,r,Ae)}catch(s){n.forEach(d=>{ee(d,a=>{e===A&&c.delete(d),a.reject(s)})});return}let u=new Map;for(let s of l.byId??[])s?.id&&u.set(s.id,s);o.forEach((s,d)=>{let a=l[`h${d}`];a&&u.set(s,a)});let p=Date.now();n.forEach(s=>{ee(s,d=>{let a=u.get(s);if(!a){$e(s,e),d.reject(new b(`Product not found: ${s}`,{code:"NOT_FOUND"}));return}e===A&&(S(a),F.set(a.handle,p),F.set(a.id,p)),d.resolve(a)})})}function Ke(){c.clear(),A+=1,m.clear(),F.clear()}function Qe(e){for(let n of e??[])!n.id||!n.handle||Date.now()-(F.get(n.handle)??0)<Pe&&c.has(n.handle)||(S(n),m.add(n.handle),m.add(n.id))}function Be(e){let n=j(e);return!n||!m.has(n)?!1:(m.delete(n),c.get(n)?.then(t=>{m.delete(t.handle),m.delete(t.id)},xe),!0)}function xe(){}function He(e){let n=j(e);return n&&c.delete(n),he(e)}var be=v({collection:y({handle:"string",products:D})}),ve=v({products:D}),Ce=v({productRecommendations:y([f])}),Ie=`query TetherCollection($handle:String!,$first:Int!,$after:String,$sortKey:ProductCollectionSortKeys,$reverse:Boolean,$filters:[ProductFilter!]){collection(handle:$handle){${J()} products(first:$first,after:$after,sortKey:$sortKey,reverse:$reverse,filters:$filters){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}}`,Me="query TetherSearch($first:Int!,$after:String,$query:String,$sortKey:ProductSortKeys,$reverse:Boolean){products(first:$first,after:$after,query:$query,sortKey:$sortKey,reverse:$reverse){nodes{...TetherProduct}pageInfo{hasNextPage endCursor}}}";async function Ye({collection:e,query:n,first:t=P.collectionFirst,after:r=null,sortKey:o,reverse:l=!1,filters:u}={}){if(e){let s=await $(w(Ie),{handle:e,first:t,after:r,sortKey:o||void 0,reverse:l,filters:u??void 0},be);if(!s.collection)throw new b(`Collection not found: ${e}`,{code:"NOT_FOUND"});let{products:d,...a}=s.collection;return d.nodes.forEach(S),{collection:a,products:d.nodes,pageInfo:d.pageInfo}}let p=await $(w(Me),{first:t,after:r,query:n||void 0,sortKey:o||void 0,reverse:l},ve);return p.products.nodes.forEach(S),{collection:null,products:p.products.nodes,pageInfo:p.products.pageInfo}}async function ze(e,n="RELATED"){let t=j(typeof e=="object"?e?.id:e),r=t?.startsWith("gid://")??!1,l=(await $(w(`query TetherRecs(${r?"$id: ID!":"$handle: String!"},$intent:ProductRecommendationIntent){productRecommendations(${r?"productId: $id":"productHandle: $handle"},intent:$intent){...TetherProduct}}`),r?{id:t,intent:n}:{handle:t,intent:n},Ce)).productRecommendations??[];return l.forEach(S),l}export{z as a,Ne as b,J as c,Fe as d,O as e,K as f,Q as g,I as h,M as i,B as j,se as k,ae as l,ce as m,ue as n,de as o,N as p,f as q,_e as r,X as s,j as t,S as u,he as v,Ke as w,Qe as x,Be as y,He as z,be as A,ve as B,Ce as C,Ye as D,ze as E};
@@ -1 +0,0 @@
1
- var e={diagnose:()=>import("./diagnose-IFRNCEYG.js"),markets:()=>import("./markets-ui-3L2UZ7PK.js"),search:()=>import("./search-YR73GIWY.js"),extras:()=>import("./extras-3477M6Y7.js"),account:()=>import("./account-BS5MCC2R.js"),"account-pages":()=>import("./account-pages-XR6QZ3DX.js"),analytics:()=>import("./analytics-BYN3QHBA.js")},a=t=>e[t](),r=void 0;export{a,r as b};
@@ -1 +0,0 @@
1
- import{A as j,E as Q,F as q,b as T,d as E,e as x,o as V,p as G,r as u,x as O,y as w,z as b}from"./chunk-GXCCTPDF.js";var g=class extends Error{constructor(r,{status:n,errors:o,userErrors:i,code:s}={}){super(r);T(this,"name","TetherError");T(this,"code");T(this,"status");T(this,"errors");T(this,"userErrors");this.code=s??(n?`HTTP_${n}`:"ERROR"),this.status=n,this.errors=o,this.userErrors=i}};function A(t,e){return typeof e=="function"?e(t):typeof e=="string"?e==="object"?E(t):typeof t===e:Et(e)?Array.isArray(t)&&t.every(r=>A(r,e[0])):E(t)&&Object.entries(e).every(([r,n])=>n===void 0||A(t[r],n))}var Et=t=>Array.isArray(t),Me=t=>e=>e===null||A(e,t),_e=t=>e=>A(e,t);function Tt(t=u){return`https://${t.domain}/api/${t.apiVersion}/graphql.json`}var Y=/"(?:\\.|[^"\\\n])*"|#[^\n]*/g,bt=/^\s*(?:query|mutation)(?:\s+\w+)?\s*(?:\([^)]*\))?/;function wt(t){return/\bmutation\b/.test(t.replace(Y,""))?"mutation":"query"}function J(t,{country:e,language:r}){let n=[];if(e&&n.push(`country: ${e}`),r&&n.push(`language: ${r}`),!n.length)return t;let o=`@inContext(${n.join(", ")})`,i=t.replace(Y,d=>" ".repeat(d.length)),s=i.indexOf("{");if(i.slice(0,s).includes("@inContext"))return t;if(i.trimStart().startsWith("{"))return`query ${o} ${t.slice(s)}`;let c=bt.exec(i);if(!c)return t;let l=c[0].length;return`${t.slice(0,l).trimEnd()} ${o} ${t.slice(l).trimStart()}`}function Ue(t,e=u){let r=V(e.country)??void 0,n=G(e.language)??void 0;return J(t,{country:r,language:n})}var N=300,St=500,W=430,xt=1e3,C="quantityAvailable",B=new Set,At=t=>`${t.domain} ${t.apiVersion} ${t.token}`;function vt(t,e,r,{context:n,operation:o}){let i=typeof e=="string"?e:e(r),s=n?J(i,t):i;return t.maxAge<=0||o==="mutation"?s:`${s} #${Math.floor(Date.now()/(t.maxAge*xt))}`}var kt=t=>new Promise(e=>setTimeout(e,t));function I(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 Rt(t){let e=x(t,"message"),r=x(x(t,"extensions"),"code"),n=typeof e=="string"?e:"";return typeof r=="string"?{message:n,extensions:{code:r}}:{message:n}}function Ot(t){if(!E(t))return null;let{data:e,errors:r}=t;return r==null?{data:e}:Array.isArray(r)?{data:e,errors:r.map(Rt)}:null}function L(t,e){return t.ok?new g(`Invalid response (${t.status})`,{code:"INVALID_RESPONSE",status:t.status}):new g(I(t.status,e),{status:t.status})}function K(t,e,r,n){let o=e.map(s=>s.message).filter(Boolean).join(" | "),i=o||"Storefront API error";return t.ok||(i=t.status===401||t.status===403||!o?I(t.status,r):o),new g(i,{status:t.status,errors:e,code:n})}function z(t,e){if(e==="any")return{kind:"retry",backoffMs:N};throw new g(`Network error: ${j(t)}`,{code:"NETWORK"})}function Lt(t,e,r,n,o,i,s){if(r.includes(C)&&n.some(f=>f.message.includes(C)))return{kind:"inventory-refused",error:K(t,n,e)};let c=n.map(f=>f.extensions?.code);if(i!=="none"&&c.includes("THROTTLED"))return{kind:"retry",backoffMs:St};let l=c.includes("INTERNAL_SERVER_ERROR");if(i==="any"&&l)return{kind:"retry",backoffMs:N};let d=t.ok&&(l||s==="mutation"&&o==null);throw K(t,n,e,d?"SERVER_ERROR":void 0)}async function Ct(t,e,r,n,o,i){let s;try{s=await(t.fetch??fetch)(Tt(t),{method:"POST",headers:{"Content-Type":"application/json","X-Shopify-Storefront-Access-Token":t.token},body:JSON.stringify({query:e,variables:r})})}catch(p){return z(p,o)}if(s.status===W)throw new g("Shopify security rejection (430)",{status:W});if(o!=="none"&&s.status===429||o==="any"&&s.status>=500)return{kind:"retry",backoffMs:N};let c;try{c=await s.json()}catch(p){if(p instanceof SyntaxError)throw L(s,t);return z(p,o)}let l=Ot(c);if(!l)throw L(s,t);let{data:d,errors:f=[]}=l;if(f.length)return Lt(s,t,e,f,d,o,i);if(!s.ok)throw new g(I(s.status,t),{status:s.status});if(!n(d))throw L(s,t);return{kind:"data",data:d}}async function X(t,e,r,n,{context:o=!0,operation:i="query"}={}){if(!t.domain||!t.token)throw new g("Tether is not configured: domain and token are required",{code:"NOT_CONFIGURED"});let s=At(t),c=i==="mutation"?"not-run":"any",l=0;for(;;){let d={inventory:!B.has(s)},f=vt(t,e,d,{context:o,operation:i}),p=l<t.retries?c:"none",h=await Ct(t,f,r,n,p,i);switch(h.kind){case"data":return h.data;case"inventory-refused":if(typeof e=="string"||!d.inventory)throw h.error;O(`the token can't read inventory: ${C} is left out from now on`),B.add(s);break;case"retry":l+=1,O("retry",l),await kt(h.backoffMs*2**l);break}}}function He(t,e,r,n){return X(u,t,e,r,n)}var Nt=t=>typeof t=="object"&&t!==null;function It(t,e,r={},n){return X(t,e,r,Nt,{...n,operation:wt(e)})}function $e(t,e,r){return It(u,t,e,r)}function De(t,e){if(!t)throw new g(`${e}: empty response`);let r=t.userErrors??[];if(r.length)throw new g(r.map(n=>n.message).join(" | "),{userErrors:r});return t}var m=t=>`${u.prefix}-${t}`,Pt=(t,e)=>e===void 0?`[${m(t)}]`:`[${m(t)}="${e}"]`,P=(t,e)=>t.getAttribute(m(e)),Mt=(t,e)=>t.hasAttribute(m(e));function Z(t,e){return t?[...t.querySelectorAll(e)]:[]}var _t=(t,e,r)=>Z(t,e).filter(n=>n.closest(r)===t),Ut=["product-ready","list-ready","cart-updated","cart-toggled","checkout","search"],tt=new WeakMap;function et(t,e){let r=new CustomEvent(`${u.prefix}:${t}`,{detail:e,bubbles:!0});return tt.set(r,t),r}function Ht(t,e){return tt.get(t)===e}function M(t,e,r=document){r.dispatchEvent(et(t,e))}function nt(t,{width:e,height:r,crop:n}={}){if(!t)return t;let o;try{o=new URL(t)}catch(i){if(i instanceof TypeError)return t;throw i}return e&&o.searchParams.set("width",String(e)),r&&o.searchParams.set("height",String(r)),n&&o.searchParams.set("crop",n),o.toString()}function _(t,e){return t.getAttribute(e)??t.getAttribute(m(e))??t.getAttribute(`data-${e}`)}function ot(t,e){if(!t||!e)return t;let r=_(e,"max-width"),n=_(e,"max-height");return nt(t,{width:r,height:n,crop:r||n?_(e,"crop"):null})}var rt=t=>t.replace(/\?.*$/,"");function it(t,e){return!t||!e?!1:rt(t)===rt(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 Dt(t,e,r){if(!e)return;let n=ot(e,t);if(t.tagName!=="IMG"){t.style.backgroundImage=$t(n);return}if(it(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 U=new WeakMap,Ft=t=>!!U.get(t),H=t=>t.cloneNode(!0);function st(t){let e=U.get(t);if(e!==void 0)return e;let r=t.firstElementChild,n=r?H(r):null;return U.set(t,n),t.replaceChildren(),n}function Vt(t,e,r){let n=st(t);if(!n){e.length&&w("repeater without a template child",t);return}t.replaceChildren(),e.forEach((o,i)=>{let s=H(n);r(s,o,i),t.appendChild(s)})}function Gt(t,e){let r=()=>{t.remove()};if(!e){r();return}try{e(t,r)}catch(n){b(n,"repeater onLeave"),r()}}function jt(t,e,r,n){e.forEach((o,i)=>{if(!r.has(o))return;let s=e[i-1];if(s?.parentNode===t?s.after(o):t.prepend(o),!!n)try{n(o)}catch(c){b(c,"repeater onEnter")}})}function Qt(t,e,r,n,{onEnter:o,onLeave:i}={}){let s=st(t);if(!s){w("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])),p=[],h=new Set;e.forEach((a,S)=>{let R=String(r(a,S)),y=f.get(R);y?f.delete(R):(y=H(s),y.setAttribute(c,R),h.add(y)),n(y,a,S,h.has(y)),p.push(y)});let k=p.filter(a=>!h.has(a)),F=d().filter(a=>k.includes(a));if(!(F.length===k.length&&F.every((a,S)=>a===k[S]))){f.forEach(a=>{a.remove()}),p.forEach(a=>t.appendChild(a));return}jt(t,p,h,o),f.forEach(a=>{a.setAttribute(l,""),a.removeAttribute(c),a.style.pointerEvents="none",a.inert=!0,Gt(a,i)})}var qt="http://www.w3.org/1999/xhtml",Wt=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"]),Bt=new Set(["script","style","template","noscript","textarea","select","title"]),Kt=new Set(["style","title","lang","dir","role","align","width","height"]),zt=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"])]]),Yt=new Set(["href","src","poster","cite"]),Jt=/^(javascript|vbscript|data):/i,Xt=/^data:image\/(png|gif|jpeg|webp|avif);/i,Zt=new Set(["position","top","right","bottom","left","z-index","-webkit-box-reflect"]),te=["inset","transform","translate","rotate","scale","offset"],ee=/\d(?:[sld]?v|cq)(?:w|h|i|b|min|max)\b/i,re=/^(?:outline|box-shadow|text-shadow|filter|text-decoration|text-underline-offset|text-stroke)|^(?:border-image|mask-border|mask-box-image)(?:-outset)?$/,at=40,ne=new Map([["letter-spacing",{px:4,em:.25}],["word-spacing",{px:4,em:.25}],["text-indent",{px:at}]]),ut=/(?<![\w#.-])[+-]?(?:\d+\.?\d*|\.\d+)(?:e[+-]?\d+)?(%|[a-z]+)?/gi,oe=/(?<![\w-])(?!drop-shadow\(|blur\()[\w-]+\([^()]*\)/g,ct=/(?:var|calc|min|max|clamp|env|attr)\(/i,ie=/url\(|expression\(|@import/i,se=/[\u0000- ]/g,ae="allow-scripts allow-same-origin allow-popups allow-presentation",ue=new Set(["autoplay","encrypted-media","picture-in-picture","fullscreen","clipboard-write","accelerometer","gyroscope","web-share"]),ce="strict-origin-when-cross-origin",le=["https://www.youtube.com","https://www.youtube-nocookie.com","https://player.vimeo.com","https://www.loom.com","https://fast.wistia.net"];function de(t,e){return Kt.has(e)||e.startsWith("aria-")||(zt.get(t)?.has(e)??!1)}function fe(t,e,r){let n=r.replace(se,"");return Jt.test(n)?t==="img"&&e==="src"&&Xt.test(n):!0}function lt(t,e){try{return new URL(t,e)}catch{return null}}function pe(t,e,r){let n=t.baseURI,o=lt(n)?.origin??"null";return{origin:o==="null"?null:o,baseUrl:n,styleParser:e,embedOrigins:new Set([...le,...r])}}function ge(t,e){let r=lt(t.trim(),e.baseUrl);return r!==null&&r.origin!==e.origin&&e.embedOrigins.has(r.origin)}function me(t){let e=t.split(";").map(r=>r.trim().split(/\s+/)[0]?.toLowerCase()??"");return[...new Set(e.filter(r=>ue.has(r)))].join("; ")}function he(t,e){if(Zt.has(t)||te.some(n=>t.startsWith(n))||ee.test(e))return!0;let r=ne.get(t);return r?ct.test(e)||ye(e,r):t.startsWith("margin")&&e.includes("-")}function ye(t,e){return[...t.matchAll(ut)].some(([r="",n=""])=>{let o=parseFloat(r);if(o>=0)return!1;let i=e[n.toLowerCase()];return i===void 0||-o>i})}function Ee(t,e){return re.test(t.replace(/^-webkit-/,""))?ct.test(e)?!0:[...e.replace(oe,"").matchAll(ut)].some(([r="",n=""])=>{let o=Math.abs(parseFloat(r));return o!==0&&(n.toLowerCase()!=="px"||o>at)}):!1}function Te(t,e){let r=e.style;r.cssText=t;let n=Array.from({length:r.length},(i,s)=>r.item(s));for(let i of n){let s=r.getPropertyValue(i);(he(i,s)||Ee(i,s)||ie.test(s))&&r.removeProperty(i)}let o=r.cssText;return e.removeAttribute("style"),o}function be(t,e){let r=t.localName;for(let i of[...t.attributes]){let s=i.name.toLowerCase(),c=Yt.has(s);de(r,s)&&(!c||fe(r,s,i.value))||t.removeAttribute(i.name)}let n=t.getAttribute("style");if(n===null)return;let o=Te(n,e.styleParser);o===""?t.removeAttribute("style"):t.setAttribute("style",o)}function we(t){if(t.localName==="iframe"){let r=me(t.getAttribute("allow")??"");r===""?t.removeAttribute("allow"):t.setAttribute("allow",r),t.setAttribute("sandbox",ae),t.setAttribute("referrerpolicy",ce);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 Se(t,e){let r=t.localName,n=t.namespaceURI===qt;if(n&&Bt.has(r)){t.remove();return}if(!n||!Wt.has(r)){t.replaceWith(...t.childNodes);return}if(r==="iframe"&&!ge(t.getAttribute("src")??"",e)){t.remove();return}be(t,e),we(t)}function dt(t,e=globalThis.document,r=[]){let n=e.createElement("template");n.innerHTML=t??"";let o=pe(e,n,r);for(let i of[...n.content.querySelectorAll("*")])Se(i,o);return n.content}var ft="data-tether-seen",D="data-tether-shown",v="data-tether-prev-display",xe=120;function tr(t,e){return q(u.productPath||"/product",t,e)}function ht(t,e){try{return t()}catch(r){if(r instanceof RangeError)return e;throw r}}function er(t,e=u.locale){return t?ht(()=>new Intl.NumberFormat(e||void 0,{style:"percent",maximumFractionDigits:0}).format(t/100),`${t}%`):""}function rr(t){return t?u.formatMoney?u.formatMoney(t,u.locale):Q(t,u.locale):""}function nr(t){return t?ht(()=>new Date(t).toLocaleDateString(u.locale||void 0),""):""}function or(t,e){t.replaceChildren(dt(e,t.ownerDocument,u.embedOrigins))}var yt=t=>t.tagName==="INPUT"||t.tagName==="TEXTAREA",pt=t=>t.tagName==="INPUT";function Ae(t,e){let r=e==null?"":String(e);yt(t)?t.value=r:t.textContent=r}var gt=t=>yt(t)?t.value:t.textContent;function ir(t,e){let r=gt(t);if(Ae(t,e),r!==gt(t)&&t.hasAttribute(ft)&&u.onValueChange)try{u.onValueChange(t,r)}catch(n){b(n,"onValueChange")}t.setAttribute(ft,"1")}function ve(t){if(t.hasAttribute(D))return;t.setAttribute(D,""),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(m("display"))||"block")}function sr(t,e){if(e){ve(t);return}t.removeAttribute(D),!t.hasAttribute(v)&&t.style.display!=="none"&&t.setAttribute(v,t.style.display),t.style.display="none"}function ar(t,e){t.classList.toggle("is-selected",e),t.setAttribute("aria-pressed",e?"true":"false"),pt(t)&&(t.type==="radio"||t.type==="checkbox")&&(t.checked=e);let r=t.querySelector('input[type="radio"],input[type="checkbox"]');r&&pt(r)&&(r.checked=e)}var mt,ke=t=>Reflect.get(window,t);function Re(){let t=ke("ScrollTrigger");if(typeof t!="function")return;let e=Reflect.get(t,"refresh");typeof e=="function"&&Reflect.apply(e,t,[])}function Oe(t){clearTimeout(mt),mt=setTimeout(()=>{try{u.onLayoutChange?u.onLayoutChange(t):Re()}catch(e){b(e,"layout-changed")}M("layout-changed",{reason:t})},xe)}function ur(t,e){let r=[...t.querySelectorAll("img")].filter(i=>!i.complete),n=r.length,o=()=>{n-=1,n===0&&Oe(`${e}:images`)};r.forEach(i=>{i.addEventListener("load",o,{once:!0}),i.addEventListener("error",o,{once:!0})})}function cr(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 lr(t,e){let r=t?P(t,e):null;if(!r)return null;try{return JSON.parse(r)}catch{return w(`invalid JSON in ${m(e)}`,t),null}}function $(t){return t==null?"":typeof t=="string"?t:typeof t=="number"||typeof t=="boolean"?String(t):JSON.stringify(t)}function dr(t){return Array.isArray(t)?t.filter(E).map(r=>({key:$(r.key),value:$(r.value)})):E(t)?Object.entries(t).map(([e,r])=>({key:e,value:$(r)})):[]}function fr(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{g as a,A as b,Me as c,_e as d,Tt as e,Ue as f,X as g,He as h,It as i,$e as j,De as k,m as l,Pt as m,P as n,Mt as o,Z as p,_t as q,Ut as r,Ht as s,M as t,nt as u,it as v,Dt as w,Ft as x,Vt as y,Qt as z,tr as A,er as B,rr as C,nr as D,or as E,Ae as F,ir as G,sr as H,ar as I,ke as J,Oe as K,ur as L,cr as M,lr as N,dr as O,fr as P};
@@ -1 +0,0 @@
1
- var b=Object.defineProperty;var Y=(n,e,t)=>e in n?b(n,e,{enumerable:!0,configurable:!0,writable:!0,value:t}):n[e]=t;var Ln=(n,e)=>{for(var t in e)b(n,t,{get:e[t],enumerable:!0})};var Un=(n,e,t)=>Y(n,typeof e!="symbol"?e+"":e,t);var G=/^(\d{4})-(01|04|07|10)$/;function C(n){let e=G.exec(typeof n=="string"?n:"");return e?{year:Number(e[1]),month:Number(e[2])}:null}var S=n=>C(n)!==null,z=(n,e)=>`${n}-${String(e).padStart(2,"0")}`;function A(n,e=1){let t=C(n);if(!t)throw new Error(`not a quarterly Shopify API version: ${n}`);let o=t.year*4+(t.month-1)/3+e;return z(Math.floor(o/4),o%4*3+1)}function Fn(n,e=new Date){if(n==="unstable")return{version:n,ok:!1,note:'"unstable" changes without notice: pin a dated version such as 2026-07'};let t=C(n);if(!t)return{version:n,ok:!1,note:"not a quarterly version (YYYY-01, -04, -07 or -10)"};let o=new Date(Date.UTC(t.year,t.month-1,1)),r=new Date(Date.UTC(t.year,t.month-1+12,1)),i=(r.getTime()-e.getTime())/2630016e3,f=o<=e,u=`supported until about ${r.toISOString().slice(0,7)}`;return f?i<=0?u="no longer supported: Shopify falls back to the oldest supported version. Upgrade (see docs/reference.md)":i<3&&(u=`${u}: plan the upgrade to ${A(n)} or later (see docs/reference.md)`):u="not released yet (release candidate at best)",{version:n,ok:f&&i>0,monthsLeft:Math.round(i),next:A(n),note:u}}function O(n){return n!==null&&typeof n=="object"&&!Array.isArray(n)}function j(n,e){return O(n)?n[e]:void 0}function v(n){return Array.isArray(n)?n:[]}function Q(n){return typeof n=="string"&&n!==""?n:null}var Z=n=>typeof n=="number"&&Number.isFinite(n)?n:null,Vn=n=>Z(n)??0,x=(n,e)=>v(n).map(t=>e(t)),Hn=(n,e)=>({nodes:x(j(n,"nodes"),e)}),Dn=n=>x(n,Q).filter(e=>e!==null);var B=/^[A-Z]{2}$/,W=new Set(["XX","T1"]),J=new Set(["PT_BR","PT_PT","ZH_CN","ZH_TW"]),X=/^[A-Z]{2,3}$/;function h(n){let e=(typeof n=="string"?n:"").trim().toUpperCase();return!B.test(e)||W.has(e)?null:e}function T(n){let e=(typeof n=="string"?n:"").trim().replace("-","_").toUpperCase();if(J.has(e))return e;let t=e.split("_")[0]??"";return X.test(t)?t:null}var E="2026-07";var q=/^[A-Za-z0-9_.-]+$/,nn=/^(\$app(:[A-Za-z0-9_-]+)?|[A-Za-z0-9_.-]+)$/,en=/^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)*$/i,tn=/^[!#$%&'*+\-.^_`|~0-9A-Za-z]+$/,on=/^[A-Za-z_$][\w$]*$/,R="https://site.invalid",rn=new Set(["localhost","127.0.0.1","[::1]"]),N=["saved","server","webflow"],sn=["no-banner","default-banner","custom-banner"],y=n=>typeof n=="string"&&n!=="",an=n=>typeof n=="function";function P(n,e){if(typeof n!="string"||!n)return"";let t=n.replace(/^https?:\/\//,"").replace(/\/.*$/,"");return fn(t)?t:(e("domain",n),"")}function M(n){if(!y(n))return!1;try{let e=new URL(n,`${R}/`);return e.origin===R?!0:e.protocol==="https:"||e.protocol==="http:"&&rn.has(e.hostname)}catch{return!1}}function L(n,e){return n==null||n===""?null:typeof n=="string"&&(M(n)||un(n))?n:(e("partsUrl",n),null)}function un(n){if(typeof location>"u")return!1;try{return new URL(n).origin===location.origin}catch{return!1}}function ln(n){if(typeof n!="string")return null;try{let e=new URL(n);return e.protocol==="https:"&&e.href===new URL(e.origin).href?e.origin:null}catch{return null}}function U(n,e){if(!Array.isArray(n))return e("embedOrigins",n),[];let t=[],o=n;for(let r of o){let i=ln(r);i?t.push(i):e("embedOrigin",r)}return t}function cn(n){let e,t;if(typeof n=="string"){let o=n.indexOf(".");e=o>0?n.slice(0,o):"",t=n.slice(o+1)}else typeof n=="object"&&n!==null&&(e=Reflect.get(n,"namespace"),t=Reflect.get(n,"key"));return typeof e!="string"||typeof t!="string"?null:nn.test(e)&&q.test(t)?{namespace:e,key:t}:null}function I(n,e){if(!Array.isArray(n))return e("metafields",n),[];let t=[],o=n;for(let r of o){let i=cn(r);i?t.push(typeof r=="string"?r:i):e("metafield",r)}return t}var d=n=>e=>n(e)?e:void 0,fn=n=>y(n)&&en.test(n),dn=n=>y(n)&&tn.test(n),pn=n=>typeof n=="boolean"||y(n)&&on.test(n),g=d(M),k=d(y),_=d(n=>typeof n=="boolean"),F=d(an);function m(n,e,t,o){if(e==null)return null;if(!O(e))return o(n,e),null;let r={};for(let i in t){let f=e[i];if(f===void 0)continue;let u=t[i](f);u===void 0?o(`${n}.${i}`,f):r[i]=u}return r}var gn={server:g,orderUrl:g,subscriptionsUrl:g,paymentUrl:g,logoutUrl:g,locale:k,navigate:F},yn="customer accounts need the Worker since 0.7.0: set account.server",mn={country:k,language:k,locale:k},On={detect:n=>{if(typeof n=="boolean")return n;let e=Array.isArray(n)?n:[n];return typeof n=="string"||Array.isArray(n)?N.filter(t=>e.includes(t)):void 0},locales:n=>{if(!O(n))return;let e={};for(let[t,o]of Object.entries(n)){let r=m(`markets.locales.${t}`,o,mn,()=>{});r&&(e[t]=r)}return e},cookie:d(dn),remember:_,strict:_},kn={consent:n=>sn.find(e=>e===n),proxy:n=>n!==void 0&&!!n},Cn={dataLayer:d(pn),shopify:n=>typeof n=="boolean"?n:m("analytics.shopify",n,kn,()=>{})??void 0,onEvent:F};function $(n,e,t){let o=m("account",n,gn,e);if(o===null)return null;let{server:r}=o;return r===void 0?(t(yn),null):{...o,server:r}}var w=(n,e)=>m("markets",n,On,e),V=(n,e)=>m("analytics",n,Cn,e);var l={domain:"",token:"",apiVersion:E,country:void 0,language:void 0,locale:void 0,markets:null,prefix:"tether",productPath:"/product",collectionPath:"/collection",metafields:[],embedOrigins:[],imagesFirst:25,variantsFirst:100,sellingPlanGroupsFirst:10,sellingPlansFirst:25,collectionFirst:24,retries:2,revalidate:!0,storageKey:"",cartDrawerOpenClass:"is-open",openCartOnAdd:!0,cartFocus:!0,checkoutTarget:"_self",defaultPurchase:"one-time",variantUrl:!1,maxAge:60,lowStock:5,searchDelay:150,autoMount:!0,observe:!1,astro:!0,partsUrl:null,analytics:null,account:null,warningText:null,formatMoney:null,onLayoutChange:null,onCartOpen:null,onCartClose:null,onLineEnter:null,onLineLeave:null,onValueChange:null,onError:null,debug:!1},a={...l};function K(n){let e=t=>(c(`Tether.config is read-only (${String(t)}): pass options to Tether.init() instead`),!1);return new Proxy(n,{get(t,o){let r=Reflect.get(t,o);return typeof r=="object"&&r!==null?K(r):r},set:(t,o)=>e(o),deleteProperty:(t,o)=>e(o),defineProperty:(t,o)=>e(o)})}var Xn=K(a),hn=/^[a-z][a-z0-9-]*$/,Tn=["revalidate","openCartOnAdd","cartFocus","variantUrl","autoMount","observe","astro","debug"],wn=["token","productPath","collectionPath","cartDrawerOpenClass"],bn=["imagesFirst","variantsFirst","sellingPlanGroupsFirst","sellingPlansFirst","collectionFirst","retries","maxAge","lowStock","searchDelay"],An=["warningText","formatMoney","onLayoutChange","onCartOpen","onCartClose","onLineEnter","onLineLeave","onValueChange","onError"];function p(n,e,t){return e!==void 0&&c(`invalid ${n} ${JSON.stringify(e)}: using ${JSON.stringify(t)}`),t}function s(n,e){c(`invalid ${n} ${JSON.stringify(e)}: ignored`)}function Sn(n){for(let e of Object.keys(n))e in l||c(`unknown option ${JSON.stringify(e)}: ignored`)}function xn(n,e,t){typeof t=="function"?n[e]=t:t!=null&&s(e,t)}function En(n,e){return typeof e=="number"&&Number.isInteger(e)&&e>=0?e:p(n,e,l[n])}function Rn(n,e){return typeof e=="boolean"?e:p(n,e,l[n])}function _n(n,e){return typeof e=="string"?e:p(n,e,l[n])}function Nn(n){if(!(n==null||n==="")){try{if(typeof n=="string"&&Intl.getCanonicalLocales(n).length)return n}catch{}s("locale",n)}}function H(n,e,t){return t.find(o=>o===e)??p(n,e,t[0])}function Pn(n){return n==="unstable"?(c('apiVersion "unstable" changes without notice. Pin a dated version (e.g. 2026-07).'),n):S(n)?n:p("apiVersion",n,l.apiVersion)}function D(n,e,t){if(e==null||e==="")return;let o=t(e);if(o!==null)return o;s(n,e)}function Mn(n){Sn(n);let e=P(n.domain,s),t=typeof n.prefix=="string"&&hn.test(n.prefix)?n.prefix:p("prefix",n.prefix,l.prefix),o={...l,domain:e,apiVersion:Pn(n.apiVersion),country:D("country",n.country,h),locale:Nn(n.locale),partsUrl:L(n.partsUrl,s),language:D("language",n.language,T),markets:w(n.markets,s),analytics:V(n.analytics,s),account:$(n.account,s,c),prefix:t,storageKey:typeof n.storageKey=="string"&&n.storageKey?n.storageKey:`${t}:cart:${e}`,metafields:I(n.metafields??[],s),embedOrigins:U(n.embedOrigins??[],s),checkoutTarget:H("checkoutTarget",n.checkoutTarget,["_self","_blank"]),defaultPurchase:H("defaultPurchase",n.defaultPurchase,["one-time","subscription"])};for(let r of bn)o[r]=En(r,n[r]);for(let r of Tn)o[r]=Rn(r,n[r]);for(let r of wn)o[r]=_n(r,n[r]);for(let r of An)xn(o,r,n[r]);return o}var qn=n=>w(n,s);function ne(n={}){let e=Mn(n);for(let t of Object.keys(a))t in e||Reflect.deleteProperty(a,t);return Object.assign(a,e)}var ee=()=>!!(a.domain&&a.token);function te(...n){a.debug&&console.log(`[${a.prefix}]`,...n)}function c(...n){console.warn(`[${a.prefix}]`,...n)}function oe(n,e){if(c(e,n instanceof Error&&n.message?n.message:n),!!a.onError)try{a.onError(n,e)}catch(t){c("onError threw",t)}}function se(n){return n instanceof Error?n.message:String(n)}var ue={domain:["PUBLIC_SHOPIFY_DOMAIN","PUBLIC_SHOPIFY_STORE_DOMAIN","SHOPIFY_DOMAIN"],token:["PUBLIC_SHOPIFY_STOREFRONT_TOKEN","PUBLIC_SHOPIFY_STOREFRONT_ACCESS_TOKEN","SHOPIFY_STOREFRONT_TOKEN"]};function le(n){if(typeof n!="string")return!1;try{return new URL(n).protocol==="https:"}catch{return!1}}function ce(n){return/^shp[a-z]{2}_/.test(n.trim())}function fe(n,e){if(!n)return"";let t=parseFloat(n.amount);if(Number.isNaN(t))return"";try{return new Intl.NumberFormat(e||void 0,{style:"currency",currency:n.currencyCode}).format(t)}catch{return`${n.currencyCode} ${t.toFixed(2)}`}}function de(n,e,t){if(!/\{(handle|id)\}/.test(n))return e?`${n.replace(/\/$/,"")}/${encodeURIComponent(e)}`:null;let o=t?t.split("/").at(-1)??"":"";return n.includes("{handle}")&&!e||n.includes("{id}")&&!o?null:n.replace(/\{handle\}/g,encodeURIComponent(e??"")).replace(/\{id\}/g,encodeURIComponent(o))}function pe(n){let e=String(n??"").trim();return e?e.startsWith("gid://")?e:/^\d+$/.test(e)?`gid://shopify/Product/${e}`:/\/products\/([^/?#]+)/.exec(e)?.[1]??e:null}export{Ln as a,Un as b,Fn as c,O as d,j as e,v as f,Q as g,Z as h,Vn as i,x as j,Hn as k,Dn as l,N as m,cn as n,h as o,T as p,l as q,a as r,Xn as s,Mn as t,qn as u,ne as v,ee as w,te as x,c as y,oe as z,se as A,ue as B,le as C,ce as D,fe as E,de as F,pe as G};