@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.
- package/README.md +21 -21
- package/dist/esm/chunks/{account-UIPWJQ3Y.js → account-CXMA5RPZ.js} +1 -1
- package/dist/esm/chunks/{account-pages-6ROA6Y4V.js → account-pages-IZO7FEOZ.js} +1 -1
- package/dist/esm/chunks/{analytics-2V632IRV.js → analytics-PG5FPRDN.js} +1 -1
- package/dist/esm/chunks/{chunk-4GCXM764.js → chunk-4HD4J5JC.js} +1 -1
- package/dist/esm/chunks/{chunk-BFTZR4OB.js → chunk-6TFMLT4A.js} +2 -2
- package/dist/esm/chunks/{chunk-T44MUL4Y.js → chunk-BBVUVPMO.js} +1 -1
- package/dist/esm/chunks/chunk-EW5SYO6L.js +1 -0
- package/dist/esm/chunks/chunk-HJY2JSNB.js +1 -0
- package/dist/esm/chunks/chunk-MQYB6BH4.js +1 -0
- package/dist/esm/chunks/{chunk-5Z5O3767.js → chunk-N3V45JPS.js} +1 -1
- package/dist/esm/chunks/{chunk-YLUULATY.js → chunk-RPMBCAGS.js} +1 -1
- package/dist/esm/chunks/{chunk-MPDWM2NN.js → chunk-VFNHIGCS.js} +1 -1
- package/dist/esm/chunks/{chunk-6OZJCAGZ.js → chunk-WT7RGGJU.js} +1 -1
- package/dist/esm/chunks/chunk-YN6LEBEN.js +1 -0
- package/dist/esm/chunks/chunk-Z6HS3H7K.js +1 -0
- package/dist/esm/chunks/{diagnose-3FEKRIEK.js → diagnose-XCEBQKBO.js} +1 -1
- package/dist/esm/chunks/extras-4HU3VSBQ.js +1 -0
- package/dist/esm/chunks/{markets-ui-FD6NI2OG.js → markets-ui-M4IQ62CT.js} +1 -1
- package/dist/esm/chunks/search-A5DS2IOS.js +1 -0
- package/dist/esm/index.js +1 -1
- package/dist/esm/server.js +2 -2
- package/dist/tether.account-pages.js +13 -3
- package/dist/tether.account-pages.min.js +1 -1
- package/dist/tether.account.js +13 -3
- package/dist/tether.account.min.js +1 -1
- package/dist/tether.analytics.js +18 -3
- package/dist/tether.analytics.min.js +1 -1
- package/dist/tether.diagnose.js +18 -3
- package/dist/tether.diagnose.min.js +2 -2
- package/dist/tether.extras.js +19 -6
- package/dist/tether.extras.min.js +1 -1
- package/dist/tether.js +162 -112
- package/dist/tether.markets.js +18 -3
- package/dist/tether.markets.min.js +1 -1
- package/dist/tether.min.js +3 -3
- package/dist/tether.min.js.map +4 -4
- package/dist/tether.search.js +18 -3
- package/dist/tether.search.min.js +1 -1
- package/dist/types/server/src/shared/cart-id.d.ts +2 -0
- package/dist/types/src/cart/mutations.d.ts +6 -0
- package/dist/types/src/cart/store.d.ts +5 -2
- package/dist/types/src/cart.d.ts +2 -2
- package/dist/types/src/client.d.ts +53 -19
- package/dist/types/src/config.d.ts +6 -1
- package/dist/types/src/index.d.ts +2 -2
- package/dist/types/src/product-shape.d.ts +3 -1
- package/package.json +1 -2
- package/dist/esm/chunks/chunk-56FCLJJD.js +0 -1
- package/dist/esm/chunks/chunk-A5SYCVQM.js +0 -1
- package/dist/esm/chunks/chunk-BA4LQJJQ.js +0 -1
- package/dist/esm/chunks/chunk-C5JYQCWH.js +0 -1
- package/dist/esm/chunks/extras-6POFBNOP.js +0 -1
- package/dist/esm/chunks/search-UJ73YBQ5.js +0 -1
- package/src/account/addresses-view.ts +0 -58
- package/src/account/answers.ts +0 -79
- package/src/account/markup.ts +0 -36
- package/src/account/operations.ts +0 -145
- package/src/account/order-lines.ts +0 -75
- package/src/account/order-list.ts +0 -107
- package/src/account/order-page.ts +0 -137
- package/src/account/page-answers.ts +0 -317
- package/src/account/page-events.ts +0 -253
- package/src/account/server-client.ts +0 -183
- package/src/account/subscriptions-view.ts +0 -115
- package/src/account-api.ts +0 -98
- package/src/account-marks.ts +0 -35
- package/src/account-pages.ts +0 -81
- package/src/account.ts +0 -284
- package/src/amounts.ts +0 -64
- package/src/analytics-shopify.ts +0 -246
- package/src/analytics.ts +0 -315
- package/src/api-version.ts +0 -79
- package/src/astro.ts +0 -272
- package/src/cart/cart-shape.ts +0 -25
- package/src/cart/checkout.ts +0 -101
- package/src/cart/drawer.ts +0 -125
- package/src/cart/mutations.ts +0 -237
- package/src/cart/render.ts +0 -266
- package/src/cart/store.ts +0 -279
- package/src/cart.ts +0 -345
- package/src/client.ts +0 -391
- package/src/collection.ts +0 -175
- package/src/config-sections.ts +0 -284
- package/src/config.ts +0 -480
- package/src/controls/cart-controls.ts +0 -123
- package/src/controls/discount.ts +0 -75
- package/src/controls/extras.ts +0 -54
- package/src/controls/navigation.ts +0 -77
- package/src/diagnose-markup.ts +0 -298
- package/src/diagnose.ts +0 -294
- package/src/dom.ts +0 -268
- package/src/extras.ts +0 -136
- package/src/fragments.ts +0 -261
- package/src/globals.d.ts +0 -15
- package/src/images.ts +0 -91
- package/src/index.ts +0 -415
- package/src/initial.ts +0 -101
- package/src/lazy-iife.ts +0 -197
- package/src/lazy.ts +0 -42
- package/src/loader.ts +0 -363
- package/src/market-codes.ts +0 -6
- package/src/markets-ui.ts +0 -227
- package/src/markets.ts +0 -246
- package/src/markup.ts +0 -127
- package/src/mounting.ts +0 -264
- package/src/page-market.ts +0 -110
- package/src/part-integrity.ts +0 -7
- package/src/parts/account-pages.ts +0 -7
- package/src/parts/account.ts +0 -7
- package/src/parts/analytics.ts +0 -7
- package/src/parts/diagnose.ts +0 -7
- package/src/parts/extras.ts +0 -7
- package/src/parts/markets.ts +0 -7
- package/src/parts/search.ts +0 -7
- package/src/presets/barba.ts +0 -194
- package/src/product-events.ts +0 -115
- package/src/product-render.ts +0 -218
- package/src/product-shape.ts +0 -49
- package/src/product-state.ts +0 -318
- package/src/product.ts +0 -308
- package/src/repeaters.ts +0 -161
- package/src/search.ts +0 -305
- package/src/selling-plans.ts +0 -145
- package/src/server.ts +0 -211
- package/src/shopify-values.ts +0 -91
- package/src/status.ts +0 -106
- package/src/storage.ts +0 -34
- package/src/store-html.ts +0 -359
- package/src/storefront/catalog.ts +0 -196
- package/src/storefront/json-ld.ts +0 -144
- package/src/variant-render.ts +0 -139
package/dist/tether.extras.js
CHANGED
|
@@ -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
|
-
|
|
92
|
-
if (!market || !tether) return;
|
|
95
|
+
if (!market) return;
|
|
93
96
|
const options = { language: market.language, locale: market.locale, remember: false };
|
|
94
|
-
|
|
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
|
-
|
|
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
|
|
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 ||
|
|
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
|
-
|
|
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
|
-
|
|
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
|
-
|
|
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 (
|
|
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 (
|
|
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
|
|
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
|
-
|
|
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 = {
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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
|
|
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-
|
|
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
|
|
3537
|
-
const part =
|
|
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
|
-
|
|
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.
|
|
4004
|
+
var VERSION = "0.7.1";
|
|
3955
4005
|
var OBSERVE_DEBOUNCE_MS = 50;
|
|
3956
4006
|
function pageConfig() {
|
|
3957
4007
|
const config = pageGlobal("TETHER_CONFIG");
|
package/dist/tether.markets.js
CHANGED
|
@@ -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
|
-
|
|
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
|
|
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);})();
|