@occluze/tether 0.7.0 → 0.7.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 (132) hide show
  1. package/README.md +21 -21
  2. package/dist/esm/chunks/{account-UIPWJQ3Y.js → account-CXMA5RPZ.js} +1 -1
  3. package/dist/esm/chunks/{account-pages-6ROA6Y4V.js → account-pages-IZO7FEOZ.js} +1 -1
  4. package/dist/esm/chunks/{analytics-2V632IRV.js → analytics-PG5FPRDN.js} +1 -1
  5. package/dist/esm/chunks/{chunk-4GCXM764.js → chunk-4HD4J5JC.js} +1 -1
  6. package/dist/esm/chunks/{chunk-BFTZR4OB.js → chunk-6TFMLT4A.js} +2 -2
  7. package/dist/esm/chunks/{chunk-T44MUL4Y.js → chunk-BBVUVPMO.js} +1 -1
  8. package/dist/esm/chunks/chunk-EW5SYO6L.js +1 -0
  9. package/dist/esm/chunks/chunk-HJY2JSNB.js +1 -0
  10. package/dist/esm/chunks/chunk-MQYB6BH4.js +1 -0
  11. package/dist/esm/chunks/{chunk-5Z5O3767.js → chunk-N3V45JPS.js} +1 -1
  12. package/dist/esm/chunks/{chunk-YLUULATY.js → chunk-RPMBCAGS.js} +1 -1
  13. package/dist/esm/chunks/{chunk-MPDWM2NN.js → chunk-VFNHIGCS.js} +1 -1
  14. package/dist/esm/chunks/{chunk-6OZJCAGZ.js → chunk-WT7RGGJU.js} +1 -1
  15. package/dist/esm/chunks/chunk-YN6LEBEN.js +1 -0
  16. package/dist/esm/chunks/chunk-Z6HS3H7K.js +1 -0
  17. package/dist/esm/chunks/{diagnose-3FEKRIEK.js → diagnose-XCEBQKBO.js} +1 -1
  18. package/dist/esm/chunks/extras-4HU3VSBQ.js +1 -0
  19. package/dist/esm/chunks/{markets-ui-FD6NI2OG.js → markets-ui-M4IQ62CT.js} +1 -1
  20. package/dist/esm/chunks/search-A5DS2IOS.js +1 -0
  21. package/dist/esm/index.js +1 -1
  22. package/dist/esm/server.js +2 -2
  23. package/dist/tether.account-pages.js +13 -3
  24. package/dist/tether.account-pages.min.js +1 -1
  25. package/dist/tether.account.js +13 -3
  26. package/dist/tether.account.min.js +1 -1
  27. package/dist/tether.analytics.js +18 -3
  28. package/dist/tether.analytics.min.js +1 -1
  29. package/dist/tether.diagnose.js +18 -3
  30. package/dist/tether.diagnose.min.js +2 -2
  31. package/dist/tether.extras.js +19 -6
  32. package/dist/tether.extras.min.js +1 -1
  33. package/dist/tether.js +162 -112
  34. package/dist/tether.markets.js +18 -3
  35. package/dist/tether.markets.min.js +1 -1
  36. package/dist/tether.min.js +3 -3
  37. package/dist/tether.min.js.map +4 -4
  38. package/dist/tether.search.js +18 -3
  39. package/dist/tether.search.min.js +1 -1
  40. package/dist/types/server/src/shared/cart-id.d.ts +2 -0
  41. package/dist/types/src/cart/mutations.d.ts +6 -0
  42. package/dist/types/src/cart/store.d.ts +5 -2
  43. package/dist/types/src/cart.d.ts +2 -2
  44. package/dist/types/src/client.d.ts +53 -19
  45. package/dist/types/src/config.d.ts +6 -1
  46. package/dist/types/src/index.d.ts +2 -2
  47. package/dist/types/src/product-shape.d.ts +3 -1
  48. package/package.json +1 -2
  49. package/dist/esm/chunks/chunk-56FCLJJD.js +0 -1
  50. package/dist/esm/chunks/chunk-A5SYCVQM.js +0 -1
  51. package/dist/esm/chunks/chunk-BA4LQJJQ.js +0 -1
  52. package/dist/esm/chunks/chunk-C5JYQCWH.js +0 -1
  53. package/dist/esm/chunks/extras-6POFBNOP.js +0 -1
  54. package/dist/esm/chunks/search-UJ73YBQ5.js +0 -1
  55. package/src/account/addresses-view.ts +0 -58
  56. package/src/account/answers.ts +0 -79
  57. package/src/account/markup.ts +0 -36
  58. package/src/account/operations.ts +0 -145
  59. package/src/account/order-lines.ts +0 -75
  60. package/src/account/order-list.ts +0 -107
  61. package/src/account/order-page.ts +0 -137
  62. package/src/account/page-answers.ts +0 -317
  63. package/src/account/page-events.ts +0 -253
  64. package/src/account/server-client.ts +0 -183
  65. package/src/account/subscriptions-view.ts +0 -115
  66. package/src/account-api.ts +0 -98
  67. package/src/account-marks.ts +0 -35
  68. package/src/account-pages.ts +0 -81
  69. package/src/account.ts +0 -284
  70. package/src/amounts.ts +0 -64
  71. package/src/analytics-shopify.ts +0 -246
  72. package/src/analytics.ts +0 -315
  73. package/src/api-version.ts +0 -79
  74. package/src/astro.ts +0 -272
  75. package/src/cart/cart-shape.ts +0 -25
  76. package/src/cart/checkout.ts +0 -101
  77. package/src/cart/drawer.ts +0 -125
  78. package/src/cart/mutations.ts +0 -237
  79. package/src/cart/render.ts +0 -266
  80. package/src/cart/store.ts +0 -279
  81. package/src/cart.ts +0 -345
  82. package/src/client.ts +0 -391
  83. package/src/collection.ts +0 -175
  84. package/src/config-sections.ts +0 -284
  85. package/src/config.ts +0 -480
  86. package/src/controls/cart-controls.ts +0 -123
  87. package/src/controls/discount.ts +0 -75
  88. package/src/controls/extras.ts +0 -54
  89. package/src/controls/navigation.ts +0 -77
  90. package/src/diagnose-markup.ts +0 -298
  91. package/src/diagnose.ts +0 -294
  92. package/src/dom.ts +0 -268
  93. package/src/extras.ts +0 -136
  94. package/src/fragments.ts +0 -261
  95. package/src/globals.d.ts +0 -15
  96. package/src/images.ts +0 -91
  97. package/src/index.ts +0 -415
  98. package/src/initial.ts +0 -101
  99. package/src/lazy-iife.ts +0 -197
  100. package/src/lazy.ts +0 -42
  101. package/src/loader.ts +0 -363
  102. package/src/market-codes.ts +0 -6
  103. package/src/markets-ui.ts +0 -227
  104. package/src/markets.ts +0 -246
  105. package/src/markup.ts +0 -127
  106. package/src/mounting.ts +0 -264
  107. package/src/page-market.ts +0 -110
  108. package/src/part-integrity.ts +0 -7
  109. package/src/parts/account-pages.ts +0 -7
  110. package/src/parts/account.ts +0 -7
  111. package/src/parts/analytics.ts +0 -7
  112. package/src/parts/diagnose.ts +0 -7
  113. package/src/parts/extras.ts +0 -7
  114. package/src/parts/markets.ts +0 -7
  115. package/src/parts/search.ts +0 -7
  116. package/src/presets/barba.ts +0 -194
  117. package/src/product-events.ts +0 -115
  118. package/src/product-render.ts +0 -218
  119. package/src/product-shape.ts +0 -49
  120. package/src/product-state.ts +0 -318
  121. package/src/product.ts +0 -308
  122. package/src/repeaters.ts +0 -161
  123. package/src/search.ts +0 -305
  124. package/src/selling-plans.ts +0 -145
  125. package/src/server.ts +0 -211
  126. package/src/shopify-values.ts +0 -91
  127. package/src/status.ts +0 -106
  128. package/src/storage.ts +0 -34
  129. package/src/store-html.ts +0 -359
  130. package/src/storefront/catalog.ts +0 -196
  131. package/src/storefront/json-ld.ts +0 -144
  132. package/src/variant-render.ts +0 -139
@@ -29,6 +29,10 @@
29
29
  var m4 = window.Tether.__core["cart.ts"];
30
30
  var [Cart] = m4;
31
31
 
32
+ // tether-core:page-market.ts
33
+ var m5 = window.Tether.__core["page-market.ts"];
34
+ var [setCountry] = m5;
35
+
32
36
  // server/src/shared/json.ts
33
37
  function isRecord(value) {
34
38
  return value !== null && typeof value === "object" && !Array.isArray(value);
@@ -88,10 +92,9 @@
88
92
  }
89
93
  if (event.key !== `${cfg.prefix}:market:${cfg.domain}` || !event.newValue) return;
90
94
  const market = parseStoredMarket(event.newValue);
91
- const tether = Reflect.get(window, "Tether");
92
- if (!market || !tether) return;
95
+ if (!market) return;
93
96
  const options = { language: market.language, locale: market.locale, remember: false };
94
- tether.setCountry(market.country, options).catch((error) => {
97
+ setCountry(market.country, options).catch((error) => {
95
98
  reportError(error, "market from another tab");
96
99
  });
97
100
  }
@@ -117,8 +120,18 @@
117
120
  replaceUrlIfAllowed(url);
118
121
  }
119
122
 
123
+ // src/part-registry.ts
124
+ function isTetherInternals(value) {
125
+ return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
126
+ }
127
+ function registerPart(name, part) {
128
+ const tether = Reflect.get(window, "Tether");
129
+ if (!isTetherInternals(tether)) {
130
+ throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
131
+ }
132
+ tether.__parts[name] = part;
133
+ }
134
+
120
135
  // src/parts/extras.ts
121
- var { Tether } = window;
122
- if (!Tether) throw new Error("tether.extras.js runs after the Tether script, which loads it");
123
- Tether.__parts.extras = extras_exports;
136
+ registerPart("extras", extras_exports);
124
137
  })();
@@ -1 +1 @@
1
- (()=>{var E=Object.defineProperty;var A=(t,r)=>{for(var n in r)E(t,n,{get:r[n],enumerable:!0})};var f={};A(f,{addGroup:()=>U,onStorage:()=>I,writeVariantUrl:()=>P});var C=window.Tether.__core["config.ts"],[i,q,F,K,V,u,d]=C;var O=window.Tether.__core["dom.ts"],[z,D,g,m,G,W,w,y,Y,Z,h,v,k,B,l,H,Q,X]=O;var M=window.Tether.__core["product.ts"],[x]=M;var N=window.Tether.__core["cart.ts"],[p]=N;function T(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function R(t,r){let n=g(h(t,"line-attributes"));return r?[{key:"_group",value:r},...n]:n}async function U(t){let r=t.closest(l("group"));if(!r)return null;let n=w(r,"group"),o=R(r,n),e=k(r,l("product")).flatMap(a=>{let s=x.get(a);if(!s?.variant?.availableForSale||s.quantity<=0)return[];let c=s.getLine();return c?[{...c,attributes:[...c.attributes??[],...o]}]:[]});if(!e.length)return d("group-add: nothing selected"),null;try{let a=await p.add(e);return m("group-added",{group:n,lines:e},r),a}catch(a){return u(a,"group add"),null}}function L(t){let r;try{r=JSON.parse(t)}catch{return null}if(!T(r))return null;let{country:n,language:o,locale:e}=r;return typeof n!="string"||!n?null:{country:n,language:typeof o=="string"?o:null,locale:typeof e=="string"?e:void 0}}function I(t){if(t.key===i.storageKey||t.key===`${i.storageKey}:seen`){p.init().catch(e=>{u(e,"cart from another tab")});return}if(t.key!==`${i.prefix}:market:${i.domain}`||!t.newValue)return;let r=L(t.newValue),n=Reflect.get(window,"Tether");if(!r||!n)return;let o={language:r.language,locale:r.locale,remember:!1};n.setCountry(r.country,o).catch(e=>{u(e,"market from another tab")})}var b=new WeakMap,S=t=>t.split("/").pop()??t;function J(t){try{window.history.replaceState(window.history.state,"",t)}catch{}}function P(t,{variant:r,sellingPlanId:n}){let o=`${r.id}|${n??""}`,e=b.get(t);if(b.set(t,o),!e||e===o)return;let a=i.variantUrl&&document.querySelector(l("product"))===t;if(!y(t,"variant-url")&&!a)return;let s=new URL(window.location.href);s.searchParams.set("variant",S(r.id)),n?s.searchParams.set("selling_plan",S(n)):s.searchParams.delete("selling_plan"),J(s)}var{Tether:_}=window;if(!_)throw new Error("tether.extras.js runs after the Tether script, which loads it");_.__parts.extras=f;})();
1
+ (()=>{var N=Object.defineProperty;var A=(t,r)=>{for(var e in r)N(t,e,{get:r[e],enumerable:!0})};var m={};A(m,{addGroup:()=>I,onStorage:()=>$,writeVariantUrl:()=>q});var O=window.Tether.__core["config.ts"],[i,V,j,z,D,c,d]=O;var P=window.Tether.__core["dom.ts"],[W,Y,g,w,Z,v,h,y,B,H,k,Q,x,X,l,tt,rt,et]=P;var C=window.Tether.__core["product.ts"],[T]=C;var M=window.Tether.__core["cart.ts"],[f]=M;var R=window.Tether.__core["page-market.ts"],[_]=R;function u(t){return t!==null&&typeof t=="object"&&!Array.isArray(t)}function U(t,r){let e=g(k(t,"line-attributes"));return r?[{key:"_group",value:r},...e]:e}async function I(t){let r=t.closest(l("group"));if(!r)return null;let e=h(r,"group"),n=U(r,e),o=x(r,l("product")).flatMap(a=>{let s=T.get(a);if(!s?.variant?.availableForSale||s.quantity<=0)return[];let p=s.getLine();return p?[{...p,attributes:[...p.attributes??[],...n]}]:[]});if(!o.length)return d("group-add: nothing selected"),null;try{let a=await f.add(o);return w("group-added",{group:e,lines:o},r),a}catch(a){return c(a,"group add"),null}}function L(t){let r;try{r=JSON.parse(t)}catch{return null}if(!u(r))return null;let{country:e,language:n,locale:o}=r;return typeof e!="string"||!e?null:{country:e,language:typeof n=="string"?n:null,locale:typeof o=="string"?o:void 0}}function $(t){if(t.key===i.storageKey||t.key===`${i.storageKey}:seen`){f.init().catch(n=>{c(n,"cart from another tab")});return}if(t.key!==`${i.prefix}:market:${i.domain}`||!t.newValue)return;let r=L(t.newValue);if(!r)return;let e={language:r.language,locale:r.locale,remember:!1};_(r.country,e).catch(n=>{c(n,"market from another tab")})}var b=new WeakMap,S=t=>t.split("/").pop()??t;function J(t){try{window.history.replaceState(window.history.state,"",t)}catch{}}function q(t,{variant:r,sellingPlanId:e}){let n=`${r.id}|${e??""}`,o=b.get(t);if(b.set(t,n),!o||o===n)return;let a=i.variantUrl&&document.querySelector(l("product"))===t;if(!y(t,"variant-url")&&!a)return;let s=new URL(window.location.href);s.searchParams.set("variant",S(r.id)),e?s.searchParams.set("selling_plan",S(e)):s.searchParams.delete("selling_plan"),J(s)}function F(t){return u(t)&&u(t.__core)&&u(t.__parts)}function E(t,r){let e=Reflect.get(window,"Tether");if(!F(e))throw new Error(`tether.${t}.js runs after the Tether script, which loads it, and needs its window.Tether`);e.__parts[t]=r}E("extras",m);})();
package/dist/tether.js CHANGED
@@ -452,7 +452,7 @@
452
452
  if (typeof shape === "function") return shape(value);
453
453
  if (typeof shape === "string") return shape === "object" ? isRecord(value) : typeof value === shape;
454
454
  if (isShapeList(shape)) return Array.isArray(value) && value.every((item) => matches(item, shape[0]));
455
- return isRecord(value) && Object.entries(shape).every(([key, inner]) => matches(value[key], inner));
455
+ return isRecord(value) && Object.entries(shape).every(([key, inner]) => inner === void 0 || matches(value[key], inner));
456
456
  }
457
457
  var isShapeList = (shape) => Array.isArray(shape);
458
458
  var orNull = (shape) => (value) => value === null || matches(value, shape);
@@ -462,6 +462,9 @@
462
462
  }
463
463
  var STRINGS_AND_COMMENTS = /"(?:\\.|[^"\\\n])*"|#[^\n]*/g;
464
464
  var OPERATION_START = /^\s*(?:query|mutation)(?:\s+\w+)?\s*(?:\([^)]*\))?/;
465
+ function operationOf(document2) {
466
+ return /\bmutation\b/.test(document2.replace(STRINGS_AND_COMMENTS, "")) ? "mutation" : "query";
467
+ }
465
468
  function inContext(query2, { country, language }) {
466
469
  const args = [];
467
470
  if (country) args.push(`country: ${country}`);
@@ -489,10 +492,10 @@
489
492
  var INVENTORY_FIELD = "quantityAvailable";
490
493
  var storesWithoutInventory = /* @__PURE__ */ new Set();
491
494
  var storeOf = (conf) => `${conf.domain} ${conf.apiVersion} ${conf.token}`;
492
- function queryText(conf, query2, access, context) {
495
+ function queryText(conf, query2, access, { context, operation }) {
493
496
  const written = typeof query2 === "string" ? query2 : query2(access);
494
497
  const text2 = context ? inContext(written, conf) : written;
495
- if (conf.maxAge <= 0 || /^\s*mutation\b/.test(text2)) return text2;
498
+ if (conf.maxAge <= 0 || operation === "mutation") return text2;
496
499
  return `${text2} #${Math.floor(Date.now() / (conf.maxAge * MS_PER_SECOND))}`;
497
500
  }
498
501
  var sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms));
@@ -520,8 +523,7 @@
520
523
  return { data, errors: errors.map(toGraphQLError) };
521
524
  }
522
525
  function invalidResponse(res, conf) {
523
- const text2 = res.ok ? `Invalid response (${res.status})` : statusText(res.status, conf);
524
- return new TetherError(text2, { status: res.status });
526
+ return res.ok ? new TetherError(`Invalid response (${res.status})`, { code: "INVALID_RESPONSE", status: res.status }) : new TetherError(statusText(res.status, conf), { status: res.status });
525
527
  }
526
528
  function graphQLFailure(res, errors, conf) {
527
529
  const message = errors.map((error) => error.message).filter(Boolean).join(" | ");
@@ -529,7 +531,11 @@
529
531
  if (!res.ok) text2 = res.status === 401 || res.status === 403 || !message ? statusText(res.status, conf) : message;
530
532
  return new TetherError(text2, { status: res.status, errors });
531
533
  }
532
- async function attempt(conf, query2, variables, isData, canRetry) {
534
+ function networkFailure(error, retry) {
535
+ if (retry === "any") return { kind: "retry", backoffMs: RETRY_BACKOFF_MS };
536
+ throw new TetherError(`Network error: ${messageOf(error)}`, { code: "NETWORK" });
537
+ }
538
+ async function attempt(conf, query2, variables, isData, retry) {
533
539
  let res;
534
540
  try {
535
541
  res = await (conf.fetch ?? fetch)(endpoint(conf), {
@@ -538,22 +544,20 @@
538
544
  body: JSON.stringify({ query: query2, variables })
539
545
  });
540
546
  } catch (error) {
541
- if (canRetry) return { kind: "retry", backoffMs: RETRY_BACKOFF_MS };
542
- throw new TetherError(`Network error: ${messageOf(error)}`, {
543
- code: "NETWORK"
544
- });
547
+ return networkFailure(error, retry);
545
548
  }
546
549
  if (res.status === SECURITY_REJECTION) {
547
550
  throw new TetherError("Shopify security rejection (430)", { status: SECURITY_REJECTION });
548
551
  }
549
- if (canRetry && (res.status === 429 || res.status >= 500)) {
552
+ if (retry !== "none" && res.status === 429 || retry === "any" && res.status >= 500) {
550
553
  return { kind: "retry", backoffMs: RETRY_BACKOFF_MS };
551
554
  }
552
555
  let json;
553
556
  try {
554
557
  json = await res.json();
555
- } catch {
556
- throw invalidResponse(res, conf);
558
+ } catch (error) {
559
+ if (error instanceof SyntaxError) throw invalidResponse(res, conf);
560
+ return networkFailure(error, retry);
557
561
  }
558
562
  const body = toGraphQLResponse(json);
559
563
  if (!body) throw invalidResponse(res, conf);
@@ -562,7 +566,7 @@
562
566
  if (query2.includes(INVENTORY_FIELD) && errors.some((error) => error.message.includes(INVENTORY_FIELD))) {
563
567
  return { kind: "inventory-refused", error: graphQLFailure(res, errors, conf) };
564
568
  }
565
- if (canRetry && errors.some((error) => error.extensions?.code === "THROTTLED")) {
569
+ if (retry !== "none" && errors.some((error) => error.extensions?.code === "THROTTLED")) {
566
570
  return { kind: "retry", backoffMs: THROTTLE_BACKOFF_MS };
567
571
  }
568
572
  throw graphQLFailure(res, errors, conf);
@@ -571,15 +575,17 @@
571
575
  if (!isData(data)) throw invalidResponse(res, conf);
572
576
  return { kind: "data", data };
573
577
  }
574
- async function request(conf, query2, variables, isData, { context = true } = {}) {
578
+ async function request(conf, query2, variables, isData, { context = true, operation = "query" } = {}) {
575
579
  if (!conf.domain || !conf.token) {
576
580
  throw new TetherError("Tether is not configured: domain and token are required", { code: "NOT_CONFIGURED" });
577
581
  }
578
582
  const store = storeOf(conf);
583
+ const retryWhileLeft = operation === "mutation" ? "not-run" : "any";
579
584
  let retries = 0;
580
585
  for (; ; ) {
581
- const sent = queryText(conf, query2, { inventory: !storesWithoutInventory.has(store) }, context);
582
- const outcome = await attempt(conf, sent, variables, isData, retries < conf.retries);
586
+ const sent = queryText(conf, query2, { inventory: !storesWithoutInventory.has(store) }, { context, operation });
587
+ const retry = retries < conf.retries ? retryWhileLeft : "none";
588
+ const outcome = await attempt(conf, sent, variables, isData, retry);
583
589
  switch (outcome.kind) {
584
590
  case "data":
585
591
  return outcome.data;
@@ -601,7 +607,8 @@
601
607
  }
602
608
  var hasData = (data) => typeof data === "object" && data !== null;
603
609
  function query(text2, variables = {}, options) {
604
- return gql(text2, variables, hasData, options);
610
+ const operation = operationOf(typeof text2 === "string" ? text2 : text2({ inventory: true }));
611
+ return gql(text2, variables, hasData, { ...options, operation });
605
612
  }
606
613
  function unwrap(payload, name) {
607
614
  if (!payload) throw new TetherError(`${name}: empty response`);
@@ -1354,7 +1361,10 @@
1354
1361
  priceRange: { minVariantPrice: MONEY2, maxVariantPrice: MONEY2 },
1355
1362
  variants: { nodes: [{ id: "string", price: MONEY2, selectedOptions: ["object"] }] }
1356
1363
  };
1357
- var PRODUCT_CONNECTION = { nodes: [PRODUCT], pageInfo: { hasNextPage: "boolean" } };
1364
+ var PRODUCT_CONNECTION = {
1365
+ nodes: [PRODUCT],
1366
+ pageInfo: { hasNextPage: "boolean" }
1367
+ };
1358
1368
  var isProductShape = (value) => field(value, "id") !== "" && field(value, "handle") !== "" && matches(value, PRODUCT);
1359
1369
  var PRODUCT_NODE = (node) => isRecord(node) && (node["id"] === void 0 || matches(node, PRODUCT));
1360
1370
 
@@ -1876,6 +1886,9 @@
1876
1886
  }
1877
1887
  }
1878
1888
 
1889
+ // server/src/shared/cart-id.ts
1890
+ var CART_ID = /^gid:\/\/shopify\/Cart\/[\w-]+(\?key=[\w-]+)?$/;
1891
+
1879
1892
  // src/cart/store.ts
1880
1893
  var status = { kind: "unknown" };
1881
1894
  var warnings = [];
@@ -1894,7 +1907,13 @@
1894
1907
  var currentWarnings = () => warnings;
1895
1908
  var statusOf = (cart) => cart ? { kind: "ready", cart } : { kind: "empty" };
1896
1909
  var seenKey = () => `${cfg.storageKey}:seen`;
1897
- var savedCartId = () => getStored(cfg.storageKey) || null;
1910
+ function savedCartId() {
1911
+ const stored = getStored(cfg.storageKey);
1912
+ if (!stored) return null;
1913
+ if (CART_ID.test(stored)) return stored;
1914
+ forgetSavedCart();
1915
+ return null;
1916
+ }
1898
1917
  function forgetSavedCart() {
1899
1918
  removeStored(cfg.storageKey);
1900
1919
  }
@@ -1996,6 +2015,9 @@
1996
2015
  if (error.userErrors?.some((userError) => userError.field?.[0] === "cartId")) return true;
1997
2016
  return (error.errors ?? []).some((graphQLError) => UNKNOWN_CART_MESSAGE.test(graphQLError.message));
1998
2017
  }
2018
+ function isUnclearFailure(error) {
2019
+ return error instanceof TetherError && (error.code === "NETWORK" || error.code === "INVALID_RESPONSE" || (error.status ?? 0) >= 500);
2020
+ }
1999
2021
  function toLineInput(input, quantity = 1, options = {}) {
2000
2022
  const spec = typeof input === "object" && input !== null ? input : { ...options, quantity, ...input === null || input === void 0 ? {} : { variantId: input } };
2001
2023
  const merchandiseId = GID.variant(spec.merchandiseId || spec.variantId || spec.id);
@@ -2012,7 +2034,7 @@
2012
2034
  return (access) => `mutation Tether_${name}(${args}){${name}(${inner}){cart{...TetherCart}userErrors{field message}warnings{code message target}}}${cartFragment(access)}`;
2013
2035
  }
2014
2036
  async function send(name, args, inner, variables) {
2015
- const data = await gql(mutationText(name, args, inner), variables, isPayloadOf(name));
2037
+ const data = await gql(mutationText(name, args, inner), variables, isPayloadOf(name), { operation: "mutation" });
2016
2038
  const payload = unwrap(data[name], name);
2017
2039
  setWarnings(payload.warnings ?? []);
2018
2040
  return payload.cart;
@@ -2139,6 +2161,25 @@
2139
2161
 
2140
2162
  // src/cart.ts
2141
2163
  var currentLines = () => currentCart()?.lines.nodes ?? [];
2164
+ async function reloadAfterUnclearFailure() {
2165
+ const id = savedCartId();
2166
+ if (!id) return;
2167
+ try {
2168
+ const cart = await fetchCart(id);
2169
+ if (!cart) forgetSavedCart();
2170
+ commit(cart, "load");
2171
+ } catch (error) {
2172
+ reportError(error, "cart reload after a failed change");
2173
+ }
2174
+ }
2175
+ function runChange(task) {
2176
+ return enqueue(
2177
+ () => task().catch(async (error) => {
2178
+ if (isUnclearFailure(error)) await reloadAfterUnclearFailure();
2179
+ throw error;
2180
+ })
2181
+ );
2182
+ }
2142
2183
  function changeQuantity(lineId, delta) {
2143
2184
  const line = currentLines().find((candidate) => candidate.id === lineId);
2144
2185
  if (!line) return Promise.resolve(currentCart());
@@ -2147,7 +2188,7 @@
2147
2188
  pendingQuantities.set(lineId, job);
2148
2189
  announce("pending");
2149
2190
  const isLatest = () => pendingQuantities.get(lineId) === job;
2150
- const sent = enqueue(async () => {
2191
+ const sent = runChange(async () => {
2151
2192
  if (!isLatest()) return currentCart();
2152
2193
  const now = currentLines().find((candidate) => candidate.id === lineId);
2153
2194
  if (now?.quantity === target) return currentCart();
@@ -2255,7 +2296,7 @@
2255
2296
  const lines = (Array.isArray(input) ? input : [input]).map(
2256
2297
  (line) => toLineInput(line, quantity, options)
2257
2298
  );
2258
- return enqueue(async () => {
2299
+ return runChange(async () => {
2259
2300
  const cart = await mutateCart({
2260
2301
  name: "cartLinesAdd",
2261
2302
  args: "$lines: [CartLineInput!]!",
@@ -2279,14 +2320,14 @@
2279
2320
  const quantity = typeof patch === "number" ? patch : patch.quantity;
2280
2321
  if (quantity !== void 0 && quantity <= 0) return Cart.removeLine(lineId);
2281
2322
  const line = toLineUpdate(lineId, patch);
2282
- return enqueue(async () => commit(await updateLines([line]), "update"));
2323
+ return runChange(async () => commit(await updateLines([line]), "update"));
2283
2324
  },
2284
2325
  changeQuantity,
2285
2326
  /** The quantity to show: the one asked for while an update is on its way. */
2286
2327
  quantityOf: pendingQuantityOf,
2287
2328
  removeLine(lineIds) {
2288
2329
  const ids = Array.isArray(lineIds) ? lineIds : [lineIds];
2289
- return enqueue(async () => commit(await removeLines(ids), "remove"));
2330
+ return runChange(async () => commit(await removeLines(ids), "remove"));
2290
2331
  },
2291
2332
  clear() {
2292
2333
  const ids = currentLines().map((line) => line.id);
@@ -2295,7 +2336,7 @@
2295
2336
  },
2296
2337
  setNote(note) {
2297
2338
  const variables = { note: note ?? "" };
2298
- return enqueue(
2339
+ return runChange(
2299
2340
  async () => commit(
2300
2341
  await mutateCart({
2301
2342
  name: "cartNoteUpdate",
@@ -2314,7 +2355,7 @@
2314
2355
  * @param attributes The value `''` removes a key.
2315
2356
  */
2316
2357
  setAttributes(attributes) {
2317
- return enqueue(async () => {
2358
+ return runChange(async () => {
2318
2359
  const variables = { attributes: mergedAttributes(attributes) };
2319
2360
  const cart = await mutateCart({
2320
2361
  name: "cartAttributesUpdate",
@@ -2328,7 +2369,7 @@
2328
2369
  },
2329
2370
  /** Replaces the discount codes; `[]` removes them all. */
2330
2371
  setDiscountCodes(codes) {
2331
- return enqueue(async () => {
2372
+ return runChange(async () => {
2332
2373
  const variables = { discountCodes: discountCodesFrom(codes) };
2333
2374
  const cart = await mutateCart({
2334
2375
  name: "cartDiscountCodesUpdate",
@@ -2367,7 +2408,7 @@
2367
2408
  * @param options `create: false` forgets an expired cart instead of creating an empty one.
2368
2409
  */
2369
2410
  setBuyerIdentity(buyerIdentity, { create = true } = {}) {
2370
- return enqueue(async () => {
2411
+ return runChange(async () => {
2371
2412
  const cart = await mutateCart({
2372
2413
  name: "cartBuyerIdentityUpdate",
2373
2414
  args: "$buyerIdentity: CartBuyerIdentityInput!",
@@ -3447,8 +3488,91 @@
3447
3488
  });
3448
3489
  }
3449
3490
 
3491
+ // src/markets.ts
3492
+ var storageKey = () => `${cfg.prefix}:market:${cfg.domain}`;
3493
+ var pageStorage = { getItem: (key) => getStored(key) };
3494
+ function parseJsonOrNull(text2) {
3495
+ try {
3496
+ return JSON.parse(text2);
3497
+ } catch (error) {
3498
+ if (error instanceof SyntaxError) return null;
3499
+ throw error;
3500
+ }
3501
+ }
3502
+ function toMarket(value) {
3503
+ if (typeof value !== "object" || value === null) return null;
3504
+ const country = toCountry(Reflect.get(value, "country"));
3505
+ if (!country) return null;
3506
+ const locale = Reflect.get(value, "locale");
3507
+ return {
3508
+ country,
3509
+ language: toLanguage(Reflect.get(value, "language")) ?? void 0,
3510
+ locale: typeof locale === "string" && locale ? locale : void 0
3511
+ };
3512
+ }
3513
+ function readSavedMarket(storage = pageStorage) {
3514
+ const text2 = storage.getItem(storageKey());
3515
+ return text2 ? toMarket(parseJsonOrNull(text2)) : null;
3516
+ }
3517
+
3518
+ // src/page-market.ts
3519
+ var configuredMarket = { country: void 0, language: void 0, locale: void 0 };
3520
+ var lastPageHadOwnMarket = false;
3521
+ function pageMarket() {
3522
+ const meta2 = (name) => document.querySelector(`meta[name="${cfg.prefix}-page-${name}"]`)?.getAttribute("content") || void 0;
3523
+ const country = toCountry(meta2("country"));
3524
+ if (!country) return null;
3525
+ return { country, language: toLanguage(meta2("language")) ?? void 0, locale: meta2("locale") };
3526
+ }
3527
+ async function visitorMarket() {
3528
+ const markets = cfg.markets ?? {};
3529
+ if (markets.detect === false) return null;
3530
+ if (!markets.detect) return markets.remember === false ? null : readSavedMarket();
3531
+ try {
3532
+ return (await loadPart("markets")).detectMarket(markets);
3533
+ } catch (error) {
3534
+ reportError(error, "markets");
3535
+ return null;
3536
+ }
3537
+ }
3538
+ async function applyStartMarket(overrides) {
3539
+ configuredMarket = { country: cfg.country, language: cfg.language, locale: cfg.locale };
3540
+ const page = pageMarket();
3541
+ lastPageHadOwnMarket = page !== null;
3542
+ if (page) {
3543
+ cfg.country = page.country;
3544
+ cfg.language = page.language;
3545
+ if (page.locale) cfg.locale = page.locale;
3546
+ return;
3547
+ }
3548
+ const market = await visitorMarket();
3549
+ if (!market) return;
3550
+ if (market.country) cfg.country = market.country;
3551
+ if (market.language) cfg.language = market.language;
3552
+ if (market.locale && !overrides.locale) cfg.locale = market.locale;
3553
+ log("market", market);
3554
+ }
3555
+ var sameCode = (a, b) => (a ?? "").toUpperCase() === (b ?? "").toUpperCase();
3556
+ function marketForArrival() {
3557
+ const page = pageMarket();
3558
+ const leftOwnMarket = page === null && lastPageHadOwnMarket;
3559
+ lastPageHadOwnMarket = page !== null;
3560
+ const target = page ?? (leftOwnMarket ? readSavedMarket() ?? configuredMarket : null);
3561
+ if (!target?.country) return null;
3562
+ if (sameCode(target.country, cfg.country) && sameCode(target.language, cfg.language)) return null;
3563
+ return { country: target.country, language: target.language, locale: target.locale };
3564
+ }
3565
+ function setCountry(code, options) {
3566
+ return loadPart("markets").then((part) => part.setCountry(code, options));
3567
+ }
3568
+
3450
3569
  // src/part-integrity.ts
3451
- var PART_INTEGRITY = { "tether.diagnose.js": "sha384-OKLlZJrSZ5IF9SOjKnEe485fi5xZlb4oLLvSfGjAssABzqd3h9JH1yA/hDczhkjJ", "tether.markets.js": "sha384-QVvTGiZJKx2hOPIpQPrGycWnKVTfDMEJ8z9heHIYSqib+6WyUoTmzKf2oBiFE3le", "tether.search.js": "sha384-P63pnKFjWTIVS8kEbBr4sfZZI91u1tImDTe+y50l2pdOM+W/KQsMymB6YRH801Dc", "tether.extras.js": "sha384-DJwYPZWf7o63ooQuDRvvhLrl5quZwhWO1YQ9RpySNQKjlDIS3uCwxDpDfZYiEjla", "tether.account.js": "sha384-q3UfPH5vDMbKm05wkvEPTDoA/aaIPmRQBDrqmXA4cNF4VFZAo4dgt61TmrNM69mi", "tether.account-pages.js": "sha384-YiSgDwM6qeHXJBcbWLRuk50h2ntAamNadS0MrZByc3cl5PKXZO297l38zYWm0lLe", "tether.analytics.js": "sha384-I93erLFdRG9uy3t+mnaDk/MgECoYOSG3q+9TfIQ39NROWZLvFjYrpHOAnBfsXaJc" };
3570
+ var PART_INTEGRITY = { "tether.diagnose.js": "sha384-My35ltXsPvspuBHm0xCTu7wl6C4ORwigmKQMCaTKI6VP9ELMCCLYCETpAYW3Fus+", "tether.markets.js": "sha384-m9u+yVeYzqljJYufGt6C6E2xCgqgBSJstvmjU5a2lXZLK3q2saH19EYgP/EC5ox3", "tether.search.js": "sha384-ZrByfRsWNOHbbWOocY4WOD2RWe4QI2qQRZ4Eb+fM5v/UHIQ8mlWxbSwrxJt8yLbc", "tether.extras.js": "sha384-sE3c2fclN/3LKtuYUtC4CjVk76Zu0Mv/jR3p8YYLisAvyDvqJxpx4nj8PbJ3KzXH", "tether.account.js": "sha384-UF36poTg1vnXE7Pg+FYFGMJ4qjKhx9mbOug9bqTYhzgqRppOKS9M/1uY5D/cz9KF", "tether.account-pages.js": "sha384-jJYvZswrRw+pGDYrk0FswWcYqGpZkbR6ooxJGFu0lTYkUlVOcsCXuLLLU6M5kO54", "tether.analytics.js": "sha384-10v5pBMzgfF7BuLGQBg3cdbgMk701Uto5rGjhByiRD2jI9+/WF8DFcSWplIcdRNg" };
3571
+
3572
+ // src/part-registry.ts
3573
+ function isTetherInternals(value) {
3574
+ return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
3575
+ }
3452
3576
 
3453
3577
  // src/lazy-iife.ts
3454
3578
  var coreModules = {
@@ -3504,6 +3628,9 @@
3504
3628
  get "market-codes.ts"() {
3505
3629
  return [toCountry, toLanguage];
3506
3630
  },
3631
+ get "page-market.ts"() {
3632
+ return [setCountry];
3633
+ },
3507
3634
  get "shopify-values.ts"() {
3508
3635
  return [isHttpsUrl];
3509
3636
  },
@@ -3533,14 +3660,15 @@
3533
3660
  script.async = true;
3534
3661
  applyIntegrity(script, integrity);
3535
3662
  script.onload = () => {
3536
- const { Tether } = window;
3537
- const part = Tether?.__parts[name];
3663
+ const tether = Reflect.get(window, "Tether");
3664
+ const part = isTetherInternals(tether) ? tether.__parts[name] : void 0;
3538
3665
  if (part) {
3539
3666
  resolve(part);
3540
3667
  return;
3541
3668
  }
3542
3669
  parts.delete(name);
3543
- reject(new Error(`${url2} did not register`));
3670
+ const problem = isTetherInternals(tether) ? "did not register" : "can't register: window.Tether is no longer this Tether script's, another script replaced it";
3671
+ reject(new Error(`${url2} ${problem}`));
3544
3672
  };
3545
3673
  script.onerror = () => {
3546
3674
  parts.delete(name);
@@ -3574,84 +3702,6 @@
3574
3702
  return loading;
3575
3703
  }
3576
3704
 
3577
- // src/markets.ts
3578
- var storageKey = () => `${cfg.prefix}:market:${cfg.domain}`;
3579
- var pageStorage = { getItem: (key) => getStored(key) };
3580
- function parseJsonOrNull(text2) {
3581
- try {
3582
- return JSON.parse(text2);
3583
- } catch (error) {
3584
- if (error instanceof SyntaxError) return null;
3585
- throw error;
3586
- }
3587
- }
3588
- function toMarket(value) {
3589
- if (typeof value !== "object" || value === null) return null;
3590
- const country = toCountry(Reflect.get(value, "country"));
3591
- if (!country) return null;
3592
- const locale = Reflect.get(value, "locale");
3593
- return {
3594
- country,
3595
- language: toLanguage(Reflect.get(value, "language")) ?? void 0,
3596
- locale: typeof locale === "string" && locale ? locale : void 0
3597
- };
3598
- }
3599
- function readSavedMarket(storage = pageStorage) {
3600
- const text2 = storage.getItem(storageKey());
3601
- return text2 ? toMarket(parseJsonOrNull(text2)) : null;
3602
- }
3603
-
3604
- // src/page-market.ts
3605
- var configuredMarket = { country: void 0, language: void 0, locale: void 0 };
3606
- var lastPageHadOwnMarket = false;
3607
- function pageMarket() {
3608
- const meta2 = (name) => document.querySelector(`meta[name="${cfg.prefix}-page-${name}"]`)?.getAttribute("content") || void 0;
3609
- const country = toCountry(meta2("country"));
3610
- if (!country) return null;
3611
- return { country, language: toLanguage(meta2("language")) ?? void 0, locale: meta2("locale") };
3612
- }
3613
- async function visitorMarket() {
3614
- const markets = cfg.markets ?? {};
3615
- if (markets.detect === false) return null;
3616
- if (!markets.detect) return markets.remember === false ? null : readSavedMarket();
3617
- try {
3618
- return (await loadPart("markets")).detectMarket(markets);
3619
- } catch (error) {
3620
- reportError(error, "markets");
3621
- return null;
3622
- }
3623
- }
3624
- async function applyStartMarket(overrides) {
3625
- configuredMarket = { country: cfg.country, language: cfg.language, locale: cfg.locale };
3626
- const page = pageMarket();
3627
- lastPageHadOwnMarket = page !== null;
3628
- if (page) {
3629
- cfg.country = page.country;
3630
- cfg.language = page.language;
3631
- if (page.locale) cfg.locale = page.locale;
3632
- return;
3633
- }
3634
- const market = await visitorMarket();
3635
- if (!market) return;
3636
- if (market.country) cfg.country = market.country;
3637
- if (market.language) cfg.language = market.language;
3638
- if (market.locale && !overrides.locale) cfg.locale = market.locale;
3639
- log("market", market);
3640
- }
3641
- var sameCode = (a, b) => (a ?? "").toUpperCase() === (b ?? "").toUpperCase();
3642
- function marketForArrival() {
3643
- const page = pageMarket();
3644
- const leftOwnMarket = page === null && lastPageHadOwnMarket;
3645
- lastPageHadOwnMarket = page !== null;
3646
- const target = page ?? (leftOwnMarket ? readSavedMarket() ?? configuredMarket : null);
3647
- if (!target?.country) return null;
3648
- if (sameCode(target.country, cfg.country) && sameCode(target.language, cfg.language)) return null;
3649
- return { country: target.country, language: target.language, locale: target.locale };
3650
- }
3651
- function setCountry(code, options) {
3652
- return loadPart("markets").then((part) => part.setCountry(code, options));
3653
- }
3654
-
3655
3705
  // src/account-marks.ts
3656
3706
  var hintKey = () => `${cfg.prefix}:account-hint:${cfg.domain}`;
3657
3707
  function removeFromBothAreas(key) {
@@ -3951,7 +4001,7 @@
3951
4001
  }
3952
4002
 
3953
4003
  // src/index.ts
3954
- var VERSION = "0.7.0";
4004
+ var VERSION = "0.7.1";
3955
4005
  var OBSERVE_DEBOUNCE_MS = 50;
3956
4006
  function pageConfig() {
3957
4007
  const config = pageGlobal("TETHER_CONFIG");
@@ -294,8 +294,23 @@
294
294
  return Cart.state;
295
295
  }
296
296
 
297
+ // server/src/shared/json.ts
298
+ function isRecord(value) {
299
+ return value !== null && typeof value === "object" && !Array.isArray(value);
300
+ }
301
+
302
+ // src/part-registry.ts
303
+ function isTetherInternals(value) {
304
+ return isRecord(value) && isRecord(value["__core"]) && isRecord(value["__parts"]);
305
+ }
306
+ function registerPart(name, part) {
307
+ const tether = Reflect.get(window, "Tether");
308
+ if (!isTetherInternals(tether)) {
309
+ throw new Error(`tether.${name}.js runs after the Tether script, which loads it, and needs its window.Tether`);
310
+ }
311
+ tether.__parts[name] = part;
312
+ }
313
+
297
314
  // src/parts/markets.ts
298
- var { Tether } = window;
299
- if (!Tether) throw new Error("tether.markets.js runs after the Tether script, which loads it");
300
- Tether.__parts.markets = markets_ui_exports;
315
+ registerPart("markets", markets_ui_exports);
301
316
  })();
@@ -1 +1 @@
1
- (()=>{var K=Object.defineProperty;var W=(e,t)=>{for(var n in t)K(e,n,{get:t[n],enumerable:!0})};var L={};W(L,{detectMarket:()=>F,getLocalization:()=>$,renderCountrySelects:()=>h,setCountry:()=>be});var G=window.Tether.__core["config.ts"],[c,Te,ve,M,S,p,xe]=G;var V=window.Tether.__core["client.ts"],[Pe,b,Ae,E,T]=V;var Q=window.Tether.__core["cart.ts"],[g]=Q;var Z=window.Tether.__core["collection.ts"],[v]=Z;var X=window.Tether.__core["loader.ts"],[x,Oe]=X;var ee=window.Tether.__core["dom.ts"],[Ue,m,He,_,De,Fe,P,je,qe,$e,Je,Ye,Be,Ke,C,We,Ge,Ve]=ee;var te=window.Tether.__core["mounting.ts"],[A,I,z,N,O,w]=te;var ne=window.Tether.__core["market-codes.ts"],[s,d]=ne;function R(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function U(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}var oe="tether_country",H=()=>`${c.prefix}:market:${c.domain}`,D={getItem:e=>R(e)};function re(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:D,global:e?window:{}}}function ae(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function ce(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}function ie(e=D){let t=e.getItem(H());return t?ce(ae(t)):null}function le(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?decodeURIComponent(n.slice(t.length+1)):null}function k(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function ue(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),i=n("tether-country")||le(t.document,e.cookie||oe);return{country:a||i,language:o||n("tether-language")}}function se(e,t){let n=(t.location?.pathname??"/").split("/").find(l=>l!==""),a=k(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let i=k(e.locales,o)??k(e.locales,o.split("-")[0]);if(i)return{locale:o,...i};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function de(e,t,n){switch(e){case"saved":return t.remember===!1?null:ie(n.storage);case"server":return ue(t,n);case"webflow":return se(t,n)}}function ge(e){return e?e===!0?M:e:["saved"]}function F(e=c.markets,t=re()){let n=(e===c.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let i of ge(n.detect)){let r=de(i,n,t);if(!r)continue;let l=s(r.country),u=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;l&&!o.country&&(o.country=l,a.country=i),u&&!o.language&&(o.language=u,a.language=i),f&&!o.locale&&(o.locale=f,a.locale=i)}return o}function j(e){if(c.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};U(H(),JSON.stringify(t))}var fe="{name} ({currency})",me="name",y=null;function ye(){y=null}var pe="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},Ce=E({localization:{country:q,availableCountries:[q]}});function $(){return y??(y=b(pe,{},Ce).then(e=>e.localization,e=>{throw y=null,e})),y}function J(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var we=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>J(t,a));function ke(e,t,n){let a=e.getAttribute(m("country-label"))||fe,o=(e.getAttribute(m("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),i=o.length?o.map(r=>t.find(l=>l.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...i.map(r=>new Option(we(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=i.length<2&&!e.hasAttribute(m("always-enabled"))}function he(e,t,n){let a=(c.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,l)=>r.name.localeCompare(l.name,c.locale||void 0)),i=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{ke(r,o,a)}),t.forEach(r=>{r.textContent=J(i,P(r,"country-bind")||me)})}function h(e=document){let t=w(e,`select${C("country-select")}`),n=w(e,C("country-bind"));return!t.length&&!n.length?Promise.resolve():$().then(a=>{he(t,n,a)}).catch(a=>{p(a,"country select")})}var Le=e=>Object.values(c.markets?.locales??{}).find(t=>s(t.country)===e);function Me(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:c.language}function Se(e){x();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{p(n,"cart country")})),O(),A.forEach(n=>t.push(n.load())),I.forEach(n=>{n.closest(v())||(z.delete(n),N(n))}),t}async function be(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new T(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let i=Le(o),r=n||i?.locale,l=r||c.locale,u=Me(t,i),f=o!==c.country||u!==c.language||l!==c.locale;if(c.country=o,c.language=u||void 0,c.locale=l,a&&j({country:o,language:u,locale:r}),!f)return h(),g.state;t!==void 0&&ye();let B=Se(o);return h(),_("country-changed",{country:o,language:c.language}),await Promise.all(B),g.state}var{Tether:Y}=window;if(!Y)throw new Error("tether.markets.js runs after the Tether script, which loads it");Y.__parts.markets=L;})();
1
+ (()=>{var W=Object.defineProperty;var G=(e,t)=>{for(var n in t)W(e,n,{get:t[n],enumerable:!0})};var b={};G(b,{detectMarket:()=>j,getLocalization:()=>J,renderCountrySelects:()=>L,setCountry:()=>xe});var V=window.Tether.__core["config.ts"],[c,_e,Pe,M,S,C,Ae]=V;var Z=window.Tether.__core["client.ts"],[ve,x,Oe,T,E]=Z;var Q=window.Tether.__core["cart.ts"],[g]=Q;var X=window.Tether.__core["collection.ts"],[_]=X;var ee=window.Tether.__core["loader.ts"],[P,Ue]=ee;var te=window.Tether.__core["dom.ts"],[De,m,Fe,A,je,$e,N,qe,Je,Ye,Be,Ke,We,Ge,w,Ve,Ze,Qe]=te;var ne=window.Tether.__core["mounting.ts"],[v,O,I,z,R,k]=ne;var oe=window.Tether.__core["market-codes.ts"],[s,d]=oe;function U(e,t="localStorage"){try{return window[t].getItem(e)}catch{return null}}function H(e,t,n="localStorage"){try{window[n].setItem(e,t)}catch{}}var re="tether_country",D=()=>`${c.prefix}:market:${c.domain}`,F={getItem:e=>U(e)};function ae(){let e=typeof window<"u";return{document:typeof document<"u"?document:null,location:e?window.location:null,storage:F,global:e?window:{}}}function ce(e){try{return JSON.parse(e)}catch(t){if(t instanceof SyntaxError)return null;throw t}}function ie(e){if(typeof e!="object"||e===null)return null;let t=s(Reflect.get(e,"country"));if(!t)return null;let n=Reflect.get(e,"locale");return{country:t,language:d(Reflect.get(e,"language"))??void 0,locale:typeof n=="string"&&n?n:void 0}}function ue(e=F){let t=e.getItem(D());return t?ie(ce(t)):null}function le(e,t){if(!e||!t)return null;let n=e.cookie.split(";").map(a=>a.trim()).find(a=>a.startsWith(`${t}=`));return n?decodeURIComponent(n.slice(t.length+1)):null}function h(e,t){if(!e||!t)return null;let n=t.toLowerCase(),a=Object.keys(e).find(o=>o.toLowerCase()===n);return a?e[a]??null:null}function se(e,t){let n=r=>t.document?.querySelector(`meta[name="${r}"]`)?.getAttribute("content"),a=Reflect.get(t.global,"TETHER_COUNTRY"),o=Reflect.get(t.global,"TETHER_LANGUAGE"),i=n("tether-country")||le(t.document,e.cookie||re);return{country:a||i,language:o||n("tether-language")}}function de(e,t){let n=(t.location?.pathname??"/").split("/").find(u=>u!==""),a=h(e.locales,n);if(a)return a;let o=t.document?.documentElement.getAttribute("lang");if(!o)return null;let i=h(e.locales,o)??h(e.locales,o.split("-")[0]);if(i)return{locale:o,...i};if(e.locales&&e.strict)return null;let r=o.split("-")[1];return{language:o,country:r?.length===2?r:null,locale:o}}function ge(e,t,n){switch(e){case"saved":return t.remember===!1?null:ue(n.storage);case"server":return se(t,n);case"webflow":return de(t,n)}}function fe(e){return e?e===!0?M:e:["saved"]}function j(e=c.markets,t=ae()){let n=(e===c.markets?e:S(e))??{};if(n.detect===!1)return{};let a={},o={sources:a};for(let i of fe(n.detect)){let r=ge(i,n,t);if(!r)continue;let u=s(r.country),l=d(r.language),f=typeof r.locale=="string"&&r.locale?r.locale:null;u&&!o.country&&(o.country=u,a.country=i),l&&!o.language&&(o.language=l,a.language=i),f&&!o.locale&&(o.locale=f,a.locale=i)}return o}function $(e){if(c.markets?.remember===!1)return;let t={country:e.country,language:e.language||void 0,locale:e.locale||void 0};H(D(),JSON.stringify(t))}var me="{name} ({currency})",pe="name",p=null;function ye(){p=null}var Ce="query TetherLocalization{localization{country{isoCode name currency{isoCode symbol}}language{isoCode name}availableCountries{isoCode name currency{isoCode symbol}availableLanguages{isoCode name}}}}",q={isoCode:"string",name:"string",currency:"object"},we=T({localization:{country:q,availableCountries:[q]}});function J(){return p??(p=x(Ce,{},we).then(e=>e.localization,e=>{throw p=null,e})),p}function Y(e,t){switch(t){case"name":return e.name;case"code":return e.isoCode;case"currency":return e.currency.isoCode;case"symbol":return e.currency.symbol;default:return""}}var ke=(e,t)=>e.replace(/\{(name|code|currency|symbol)\}/g,(n,a)=>Y(t,a));function he(e,t,n){let a=e.getAttribute(m("country-label"))||me,o=(e.getAttribute(m("countries"))||"").toUpperCase().split(/[\s,]+/).filter(Boolean),i=o.length?o.map(r=>t.find(u=>u.isoCode===r)).filter(r=>r!==void 0):t;e.replaceChildren(...i.map(r=>new Option(ke(a,r),r.isoCode))),e.value=n,e.value!==n&&(e.selectedIndex=-1),e.disabled=i.length<2&&!e.hasAttribute(m("always-enabled"))}function Le(e,t,n){let a=(c.country||n.country.isoCode).toUpperCase(),o=[...n.availableCountries].sort((r,u)=>r.name.localeCompare(u.name,c.locale||void 0)),i=o.find(r=>r.isoCode===a)??n.country;e.forEach(r=>{he(r,o,a)}),t.forEach(r=>{r.textContent=Y(i,N(r,"country-bind")||pe)})}function L(e=document){let t=k(e,`select${w("country-select")}`),n=k(e,w("country-bind"));return!t.length&&!n.length?Promise.resolve():J().then(a=>{Le(t,n,a)}).catch(a=>{C(a,"country select")})}var be=e=>Object.values(c.markets?.locales??{}).find(t=>s(t.country)===e);function Me(e,t){return e!==void 0?d(e):t?t.language?d(t.language):void 0:c.language}function Se(e){P();let t=[];return g.id()&&t.push(g.setBuyerIdentity({countryCode:e},{create:!1}).catch(n=>{C(n,"cart country")})),R(),v.forEach(n=>t.push(n.load())),O.forEach(n=>{n.closest(_())||(I.delete(n),z(n))}),t}async function xe(e,{language:t,locale:n,remember:a=!0}={}){let o=s(e);if(!o)throw new E(`Not a country code: ${e}`,{code:"INVALID_COUNTRY"});let i=be(o),r=n||i?.locale,u=r||c.locale,l=Me(t,i),f=o!==c.country||l!==c.language||u!==c.locale;if(c.country=o,c.language=l||void 0,c.locale=u,a&&$({country:o,language:l,locale:r}),!f)return L(),g.state;t!==void 0&&ye();let K=Se(o);return L(),A("country-changed",{country:o,language:c.language}),await Promise.all(K),g.state}function y(e){return e!==null&&typeof e=="object"&&!Array.isArray(e)}function Te(e){return y(e)&&y(e.__core)&&y(e.__parts)}function B(e,t){let n=Reflect.get(window,"Tether");if(!Te(n))throw new Error(`tether.${e}.js runs after the Tether script, which loads it, and needs its window.Tether`);n.__parts[e]=t}B("markets",b);})();