@primestyleai/tryon 5.10.193 → 5.10.195
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/dist/PrimeStyleTryon.d.ts +5 -0
- package/dist/api-client.d.ts +30 -1
- package/dist/{index-D9sdGV4C.js → index-D_9-KLXy.js} +198 -142
- package/dist/index-D_9-KLXy.js.map +1 -0
- package/dist/primestyle-tryon.js +232 -164
- package/dist/primestyle-tryon.js.map +1 -1
- package/dist/react/index.js +6010 -5609
- package/dist/react/index.js.map +1 -1
- package/dist/react/recommendForProduct.d.ts +4 -4
- package/dist/react/styles.d.ts +1 -1
- package/dist/react/usePrimeStyleSize.d.ts +2 -2
- package/dist/react/views/SizeResultView.d.ts +2 -1
- package/dist/storefront/primestyle-tryon.js +683 -201
- package/package.json +1 -1
- package/dist/index-D9sdGV4C.js.map +0 -1
|
@@ -6981,7 +6981,7 @@ const es = {
|
|
|
6981
6981
|
"See Your Fit": "Ver tu ajuste",
|
|
6982
6982
|
"Check your size, then try it on virtually": "Comprueba tu talla y pruébatelo virtualmente",
|
|
6983
6983
|
"Get Your Size": "Tu talla",
|
|
6984
|
-
"Instant fit
|
|
6984
|
+
"Instant fit suggestion": "Sugerencia de ajuste instantánea",
|
|
6985
6985
|
"Try It On": "Pruébatelo",
|
|
6986
6986
|
"See how it looks on you": "Mira cómo te queda",
|
|
6987
6987
|
"Find My Size": "Encontrar mi talla",
|
|
@@ -7009,12 +7009,12 @@ const es = {
|
|
|
7009
7009
|
"Please fill in all required fields": "Por favor, completa todos los campos obligatorios",
|
|
7010
7010
|
"Next": "Siguiente",
|
|
7011
7011
|
"Analyzing your size...": "Analizando tu talla...",
|
|
7012
|
-
"
|
|
7013
|
-
"NOT
|
|
7012
|
+
"SUGGESTED SIZE": "TALLA SUGERIDA",
|
|
7013
|
+
"NOT SUGGESTED": "NO SUGERIDA",
|
|
7014
7014
|
"Edit measurements": "Editar medidas",
|
|
7015
7015
|
"Size guide": "Guía de tallas",
|
|
7016
7016
|
"Your fit": "Tu ajuste",
|
|
7017
|
-
"Your Size
|
|
7017
|
+
"Your Suggested Size": "Tu talla sugerida",
|
|
7018
7018
|
"Your measure": "Tu medida",
|
|
7019
7019
|
"within range": "dentro del rango",
|
|
7020
7020
|
"too tight": "demasiado ajustado",
|
|
@@ -7237,7 +7237,7 @@ const fr = {
|
|
|
7237
7237
|
"See Your Fit": "Voir votre ajustement",
|
|
7238
7238
|
"Check your size, then try it on virtually": "Vérifiez votre taille, puis essayez-le virtuellement",
|
|
7239
7239
|
"Get Your Size": "Votre taille",
|
|
7240
|
-
"Instant fit
|
|
7240
|
+
"Instant fit suggestion": "Suggestion de coupe instantanée",
|
|
7241
7241
|
"Try It On": "Essayer",
|
|
7242
7242
|
"See how it looks on you": "Voyez comment ça vous va",
|
|
7243
7243
|
"Find My Size": "Trouver ma taille",
|
|
@@ -7265,12 +7265,12 @@ const fr = {
|
|
|
7265
7265
|
"Please fill in all required fields": "Veuillez remplir tous les champs obligatoires",
|
|
7266
7266
|
"Next": "Suivant",
|
|
7267
7267
|
"Analyzing your size...": "Analyse de votre taille...",
|
|
7268
|
-
"
|
|
7269
|
-
"NOT
|
|
7268
|
+
"SUGGESTED SIZE": "TAILLE SUGGÉRÉE",
|
|
7269
|
+
"NOT SUGGESTED": "NON SUGGÉRÉE",
|
|
7270
7270
|
"Edit measurements": "Modifier les mesures",
|
|
7271
7271
|
"Size guide": "Guide des tailles",
|
|
7272
7272
|
"Your fit": "Votre coupe",
|
|
7273
|
-
"Your Size
|
|
7273
|
+
"Your Suggested Size": "Votre taille suggérée",
|
|
7274
7274
|
"Your measure": "Votre mesure",
|
|
7275
7275
|
"within range": "dans la plage",
|
|
7276
7276
|
"too tight": "trop serré",
|
|
@@ -7493,7 +7493,7 @@ const de = {
|
|
|
7493
7493
|
"See Your Fit": "Ihre Passform ansehen",
|
|
7494
7494
|
"Check your size, then try it on virtually": "Prüfen Sie Ihre Größe und probieren Sie es virtuell an",
|
|
7495
7495
|
"Get Your Size": "Ihre Größe",
|
|
7496
|
-
"Instant fit
|
|
7496
|
+
"Instant fit suggestion": "Sofortiger Passformvorschlag",
|
|
7497
7497
|
"Try It On": "Anprobieren",
|
|
7498
7498
|
"See how it looks on you": "Sehen Sie, wie es Ihnen steht",
|
|
7499
7499
|
"Find My Size": "Meine Größe finden",
|
|
@@ -7521,12 +7521,12 @@ const de = {
|
|
|
7521
7521
|
"Please fill in all required fields": "Bitte alle Pflichtfelder ausfüllen",
|
|
7522
7522
|
"Next": "Weiter",
|
|
7523
7523
|
"Analyzing your size...": "Ihre Größe wird analysiert...",
|
|
7524
|
-
"
|
|
7525
|
-
"NOT
|
|
7524
|
+
"SUGGESTED SIZE": "VORGESCHLAGENE GRÖSSE",
|
|
7525
|
+
"NOT SUGGESTED": "NICHT VORGESCHLAGEN",
|
|
7526
7526
|
"Edit measurements": "Maße bearbeiten",
|
|
7527
7527
|
"Size guide": "Größentabelle",
|
|
7528
7528
|
"Your fit": "Ihre Passform",
|
|
7529
|
-
"Your Size
|
|
7529
|
+
"Your Suggested Size": "Ihre vorgeschlagene Größe",
|
|
7530
7530
|
"Your measure": "Ihr Maß",
|
|
7531
7531
|
"within range": "im Bereich",
|
|
7532
7532
|
"too tight": "zu eng",
|
|
@@ -7749,7 +7749,7 @@ const it = {
|
|
|
7749
7749
|
"See Your Fit": "Vedi la vestibilità",
|
|
7750
7750
|
"Check your size, then try it on virtually": "Controlla la tua taglia, poi provalo virtualmente",
|
|
7751
7751
|
"Get Your Size": "La tua taglia",
|
|
7752
|
-
"Instant fit
|
|
7752
|
+
"Instant fit suggestion": "Suggerimento vestibilità istantaneo",
|
|
7753
7753
|
"Try It On": "Provalo",
|
|
7754
7754
|
"See how it looks on you": "Guarda come ti sta",
|
|
7755
7755
|
"Find My Size": "Trova la mia taglia",
|
|
@@ -7777,12 +7777,12 @@ const it = {
|
|
|
7777
7777
|
"Please fill in all required fields": "Compila tutti i campi obbligatori",
|
|
7778
7778
|
"Next": "Avanti",
|
|
7779
7779
|
"Analyzing your size...": "Analisi della tua taglia...",
|
|
7780
|
-
"
|
|
7781
|
-
"NOT
|
|
7780
|
+
"SUGGESTED SIZE": "TAGLIA SUGGERITA",
|
|
7781
|
+
"NOT SUGGESTED": "NON SUGGERITA",
|
|
7782
7782
|
"Edit measurements": "Modifica misure",
|
|
7783
7783
|
"Size guide": "Guida alle taglie",
|
|
7784
7784
|
"Your fit": "La tua vestibilità",
|
|
7785
|
-
"Your Size
|
|
7785
|
+
"Your Suggested Size": "La tua taglia suggerita",
|
|
7786
7786
|
"Your measure": "La tua misura",
|
|
7787
7787
|
"within range": "entro l'intervallo",
|
|
7788
7788
|
"too tight": "troppo stretto",
|
|
@@ -8005,7 +8005,7 @@ const pt$1 = {
|
|
|
8005
8005
|
"See Your Fit": "Veja seu ajuste",
|
|
8006
8006
|
"Check your size, then try it on virtually": "Confira seu tamanho e experimente virtualmente",
|
|
8007
8007
|
"Get Your Size": "Seu tamanho",
|
|
8008
|
-
"Instant fit
|
|
8008
|
+
"Instant fit suggestion": "Sugestão de caimento instantânea",
|
|
8009
8009
|
"Try It On": "Experimentar",
|
|
8010
8010
|
"See how it looks on you": "Veja como fica em você",
|
|
8011
8011
|
"Find My Size": "Encontrar meu tamanho",
|
|
@@ -8033,12 +8033,12 @@ const pt$1 = {
|
|
|
8033
8033
|
"Please fill in all required fields": "Por favor, preencha todos os campos obrigatórios",
|
|
8034
8034
|
"Next": "Próximo",
|
|
8035
8035
|
"Analyzing your size...": "Analisando seu tamanho...",
|
|
8036
|
-
"
|
|
8037
|
-
"NOT
|
|
8036
|
+
"SUGGESTED SIZE": "TAMANHO SUGERIDO",
|
|
8037
|
+
"NOT SUGGESTED": "NÃO SUGERIDO",
|
|
8038
8038
|
"Edit measurements": "Editar medidas",
|
|
8039
8039
|
"Size guide": "Guia de tamanhos",
|
|
8040
8040
|
"Your fit": "Seu caimento",
|
|
8041
|
-
"Your Size
|
|
8041
|
+
"Your Suggested Size": "Seu tamanho sugerido",
|
|
8042
8042
|
"Your measure": "Sua medida",
|
|
8043
8043
|
"within range": "dentro da faixa",
|
|
8044
8044
|
"too tight": "muito apertado",
|
|
@@ -8261,7 +8261,7 @@ const ja = {
|
|
|
8261
8261
|
"See Your Fit": "フィット感を見る",
|
|
8262
8262
|
"Check your size, then try it on virtually": "サイズを確認して、バーチャルで試着しましょう",
|
|
8263
8263
|
"Get Your Size": "サイズを確認",
|
|
8264
|
-
"Instant fit
|
|
8264
|
+
"Instant fit suggestion": "瞬時にフィット提案",
|
|
8265
8265
|
"Try It On": "試着する",
|
|
8266
8266
|
"See how it looks on you": "自分に似合うか確認",
|
|
8267
8267
|
"Find My Size": "自分のサイズを見つける",
|
|
@@ -8289,12 +8289,12 @@ const ja = {
|
|
|
8289
8289
|
"Please fill in all required fields": "すべての必須項目を入力してください",
|
|
8290
8290
|
"Next": "次へ",
|
|
8291
8291
|
"Analyzing your size...": "サイズを分析中...",
|
|
8292
|
-
"
|
|
8293
|
-
"NOT
|
|
8292
|
+
"SUGGESTED SIZE": "提案サイズ",
|
|
8293
|
+
"NOT SUGGESTED": "提案外",
|
|
8294
8294
|
"Edit measurements": "寸法を編集",
|
|
8295
8295
|
"Size guide": "サイズガイド",
|
|
8296
8296
|
"Your fit": "あなたのフィット",
|
|
8297
|
-
"Your Size
|
|
8297
|
+
"Your Suggested Size": "提案サイズ",
|
|
8298
8298
|
"Your measure": "あなたの寸法",
|
|
8299
8299
|
"within range": "範囲内",
|
|
8300
8300
|
"too tight": "きつすぎる",
|
|
@@ -8517,7 +8517,7 @@ const zh = {
|
|
|
8517
8517
|
"See Your Fit": "查看合身效果",
|
|
8518
8518
|
"Check your size, then try it on virtually": "确认尺码,然后虚拟试穿",
|
|
8519
8519
|
"Get Your Size": "获取尺码",
|
|
8520
|
-
"Instant fit
|
|
8520
|
+
"Instant fit suggestion": "即时合身建议",
|
|
8521
8521
|
"Try It On": "试穿",
|
|
8522
8522
|
"See how it looks on you": "看看穿在你身上的效果",
|
|
8523
8523
|
"Find My Size": "找到我的尺码",
|
|
@@ -8545,12 +8545,12 @@ const zh = {
|
|
|
8545
8545
|
"Please fill in all required fields": "请填写所有必填项",
|
|
8546
8546
|
"Next": "下一步",
|
|
8547
8547
|
"Analyzing your size...": "正在分析你的尺码...",
|
|
8548
|
-
"
|
|
8549
|
-
"NOT
|
|
8548
|
+
"SUGGESTED SIZE": "建议尺码",
|
|
8549
|
+
"NOT SUGGESTED": "不建议",
|
|
8550
8550
|
"Edit measurements": "编辑尺寸",
|
|
8551
8551
|
"Size guide": "尺码指南",
|
|
8552
8552
|
"Your fit": "你的合身度",
|
|
8553
|
-
"Your Size
|
|
8553
|
+
"Your Suggested Size": "你的建议尺码",
|
|
8554
8554
|
"Your measure": "你的尺寸",
|
|
8555
8555
|
"within range": "在范围内",
|
|
8556
8556
|
"too tight": "太紧",
|
|
@@ -8773,7 +8773,7 @@ const ko = {
|
|
|
8773
8773
|
"See Your Fit": "핏 확인하기",
|
|
8774
8774
|
"Check your size, then try it on virtually": "사이즈를 확인하고 가상으로 입어보세요",
|
|
8775
8775
|
"Get Your Size": "사이즈 확인",
|
|
8776
|
-
"Instant fit
|
|
8776
|
+
"Instant fit suggestion": "즉시 핏 제안",
|
|
8777
8777
|
"Try It On": "입어보기",
|
|
8778
8778
|
"See how it looks on you": "어떻게 보이는지 확인",
|
|
8779
8779
|
"Find My Size": "내 사이즈 찾기",
|
|
@@ -8801,12 +8801,12 @@ const ko = {
|
|
|
8801
8801
|
"Please fill in all required fields": "모든 필수 항목을 입력해주세요",
|
|
8802
8802
|
"Next": "다음",
|
|
8803
8803
|
"Analyzing your size...": "사이즈 분석 중...",
|
|
8804
|
-
"
|
|
8805
|
-
"NOT
|
|
8804
|
+
"SUGGESTED SIZE": "제안 사이즈",
|
|
8805
|
+
"NOT SUGGESTED": "제안 아님",
|
|
8806
8806
|
"Edit measurements": "치수 수정",
|
|
8807
8807
|
"Size guide": "사이즈 가이드",
|
|
8808
8808
|
"Your fit": "나의 핏",
|
|
8809
|
-
"Your Size
|
|
8809
|
+
"Your Suggested Size": "제안 사이즈",
|
|
8810
8810
|
"Your measure": "내 치수",
|
|
8811
8811
|
"within range": "범위 내",
|
|
8812
8812
|
"too tight": "너무 타이트",
|
|
@@ -9029,7 +9029,7 @@ const ar = {
|
|
|
9029
9029
|
"See Your Fit": "شاهد الملاءمة",
|
|
9030
9030
|
"Check your size, then try it on virtually": "تحقق من مقاسك ثم جرّبه افتراضياً",
|
|
9031
9031
|
"Get Your Size": "مقاسك",
|
|
9032
|
-
"Instant fit
|
|
9032
|
+
"Instant fit suggestion": "اقتراح فوري للمقاس",
|
|
9033
9033
|
"Try It On": "جرّبه",
|
|
9034
9034
|
"See how it looks on you": "شاهد كيف يبدو عليك",
|
|
9035
9035
|
"Find My Size": "اعثر على مقاسي",
|
|
@@ -9057,12 +9057,12 @@ const ar = {
|
|
|
9057
9057
|
"Please fill in all required fields": "يرجى ملء جميع الحقول المطلوبة",
|
|
9058
9058
|
"Next": "التالي",
|
|
9059
9059
|
"Analyzing your size...": "جارٍ تحليل مقاسك...",
|
|
9060
|
-
"
|
|
9061
|
-
"NOT
|
|
9060
|
+
"SUGGESTED SIZE": "المقاس المقترح",
|
|
9061
|
+
"NOT SUGGESTED": "غير مقترح",
|
|
9062
9062
|
"Edit measurements": "تعديل القياسات",
|
|
9063
9063
|
"Size guide": "دليل المقاسات",
|
|
9064
9064
|
"Your fit": "ملاءمتك",
|
|
9065
|
-
"Your Size
|
|
9065
|
+
"Your Suggested Size": "المقاس المقترح",
|
|
9066
9066
|
"Your measure": "قياسك",
|
|
9067
9067
|
"within range": "ضمن النطاق",
|
|
9068
9068
|
"too tight": "ضيق جداً",
|
|
@@ -9321,53 +9321,6 @@ reactJsxRuntime_production_min.jsxs = q;
|
|
|
9321
9321
|
jsxRuntime.exports = reactJsxRuntime_production_min;
|
|
9322
9322
|
}
|
|
9323
9323
|
var jsxRuntimeExports = jsxRuntime.exports;
|
|
9324
|
-
function cx(base, override) {
|
|
9325
|
-
return override ? `${base} ${override}` : base;
|
|
9326
|
-
}
|
|
9327
|
-
const MOBILE_BREAKPOINT = 768;
|
|
9328
|
-
function useIsMobile() {
|
|
9329
|
-
const [isMobile, setIsMobile] = reactExports.useState(false);
|
|
9330
|
-
reactExports.useEffect(() => {
|
|
9331
|
-
if (typeof window === "undefined") return;
|
|
9332
|
-
const check = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
9333
|
-
check();
|
|
9334
|
-
window.addEventListener("resize", check);
|
|
9335
|
-
return () => window.removeEventListener("resize", check);
|
|
9336
|
-
}, []);
|
|
9337
|
-
return isMobile;
|
|
9338
|
-
}
|
|
9339
|
-
function ErrorView({
|
|
9340
|
-
productImage,
|
|
9341
|
-
productTitle,
|
|
9342
|
-
onManualMeasurements,
|
|
9343
|
-
cn,
|
|
9344
|
-
t: t2
|
|
9345
|
-
}) {
|
|
9346
|
-
const isMobile = useIsMobile();
|
|
9347
|
-
const RightColumn = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cx("ps-tryon-no-chart-content ps-tryon-error-fallback", cn.error), children: [
|
|
9348
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-icon ps-tryon-error-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", width: "44", height: "44", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
9349
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 3l8.5 15H3.5L12 3z" }),
|
|
9350
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 9v4" }),
|
|
9351
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 17h.01" })
|
|
9352
|
-
] }) }),
|
|
9353
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-no-chart-title", children: t2("We couldn't find a matching size for you") }),
|
|
9354
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cx("ps-tryon-no-chart-msg", cn.errorText), children: t2("Please try the manual measurement screen so we can calculate your fit from your measurements.") }),
|
|
9355
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: onManualMeasurements, className: cx("ps-tryon-no-chart-cta", cn.submitButton), children: [
|
|
9356
|
-
t2("Try manual measurements"),
|
|
9357
|
-
" →"
|
|
9358
|
-
] }) })
|
|
9359
|
-
] });
|
|
9360
|
-
if (isMobile) {
|
|
9361
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr", children: [
|
|
9362
|
-
productImage && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-col", style: { flex: "0 0 auto", maxHeight: "38vh" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: productImage, alt: productTitle || "", className: "ps-tryon-sr-product-img" }) }),
|
|
9363
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-right-col", children: RightColumn })
|
|
9364
|
-
] });
|
|
9365
|
-
}
|
|
9366
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-split", children: [
|
|
9367
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-col", children: productImage && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: productImage, alt: productTitle || "", className: "ps-tryon-sr-product-img" }) }),
|
|
9368
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-right-col ps-tryon-no-chart-right-col", children: RightColumn })
|
|
9369
|
-
] }) });
|
|
9370
|
-
}
|
|
9371
9324
|
const STORAGE_KEY = "ps_session";
|
|
9372
9325
|
const MAX_AGE_MS = 30 * 24 * 60 * 60 * 1e3;
|
|
9373
9326
|
const FALLBACK_PREFIX = "ps_mem_";
|
|
@@ -9412,6 +9365,14 @@ function writeRecord(record) {
|
|
|
9412
9365
|
} catch {
|
|
9413
9366
|
}
|
|
9414
9367
|
}
|
|
9368
|
+
function attachReplaySession(sessionId) {
|
|
9369
|
+
if (typeof window === "undefined") return;
|
|
9370
|
+
try {
|
|
9371
|
+
const clarity = window.clarity;
|
|
9372
|
+
if (typeof clarity === "function") clarity("set", STORAGE_KEY, sessionId);
|
|
9373
|
+
} catch {
|
|
9374
|
+
}
|
|
9375
|
+
}
|
|
9415
9376
|
function getOrCreateSessionId() {
|
|
9416
9377
|
const now = Date.now();
|
|
9417
9378
|
const existing = readRecord();
|
|
@@ -9419,10 +9380,12 @@ function getOrCreateSessionId() {
|
|
|
9419
9380
|
if (now - existing.lastSeenAt > 5 * 60 * 1e3) {
|
|
9420
9381
|
writeRecord({ ...existing, lastSeenAt: now });
|
|
9421
9382
|
}
|
|
9383
|
+
attachReplaySession(existing.id);
|
|
9422
9384
|
return existing.id;
|
|
9423
9385
|
}
|
|
9424
9386
|
const fresh = { id: uuid(), issuedAt: now, lastSeenAt: now };
|
|
9425
9387
|
writeRecord(fresh);
|
|
9388
|
+
attachReplaySession(fresh.id);
|
|
9426
9389
|
return fresh.id;
|
|
9427
9390
|
}
|
|
9428
9391
|
function getDeviceHint() {
|
|
@@ -9544,8 +9507,49 @@ class ApiClient {
|
|
|
9544
9507
|
}
|
|
9545
9508
|
return res.json();
|
|
9546
9509
|
}
|
|
9547
|
-
|
|
9548
|
-
const
|
|
9510
|
+
async reportEvent(input) {
|
|
9511
|
+
const res = await fetch(`${this.baseUrl}/api/v1/tryon/event`, {
|
|
9512
|
+
method: "POST",
|
|
9513
|
+
headers: this.headers,
|
|
9514
|
+
keepalive: true,
|
|
9515
|
+
body: JSON.stringify({
|
|
9516
|
+
...input,
|
|
9517
|
+
sessionId: getOrCreateSessionId(),
|
|
9518
|
+
deviceHint: getDeviceHint()
|
|
9519
|
+
})
|
|
9520
|
+
});
|
|
9521
|
+
if (!res.ok) {
|
|
9522
|
+
const data = await res.json().catch(() => ({}));
|
|
9523
|
+
throw new PrimeStyleError(
|
|
9524
|
+
data.message || "Failed to report SDK event",
|
|
9525
|
+
"EVENT_REPORT_FAILED"
|
|
9526
|
+
);
|
|
9527
|
+
}
|
|
9528
|
+
return res.json();
|
|
9529
|
+
}
|
|
9530
|
+
async reportClientError(input) {
|
|
9531
|
+
const res = await fetch(`${this.baseUrl}/api/v1/tryon/client-error`, {
|
|
9532
|
+
method: "POST",
|
|
9533
|
+
headers: this.headers,
|
|
9534
|
+
keepalive: true,
|
|
9535
|
+
body: JSON.stringify({
|
|
9536
|
+
...input,
|
|
9537
|
+
sessionId: getOrCreateSessionId(),
|
|
9538
|
+
deviceHint: getDeviceHint()
|
|
9539
|
+
})
|
|
9540
|
+
});
|
|
9541
|
+
if (!res.ok) {
|
|
9542
|
+
const data = await res.json().catch(() => ({}));
|
|
9543
|
+
throw new PrimeStyleError(
|
|
9544
|
+
data.message || "Failed to report SDK client error",
|
|
9545
|
+
"CLIENT_ERROR_REPORT_FAILED"
|
|
9546
|
+
);
|
|
9547
|
+
}
|
|
9548
|
+
return res.json();
|
|
9549
|
+
}
|
|
9550
|
+
getStreamUrl(jobId) {
|
|
9551
|
+
const streamPath = jobId ? `/api/v1/tryon/stream/${encodeURIComponent(jobId)}` : "/api/v1/tryon/stream";
|
|
9552
|
+
const streamUrl = `${this.baseUrl}${streamPath}`;
|
|
9549
9553
|
return this.apiKey ? `${streamUrl}?key=${encodeURIComponent(this.apiKey)}` : streamUrl;
|
|
9550
9554
|
}
|
|
9551
9555
|
}
|
|
@@ -9561,6 +9565,89 @@ class PrimeStyleError extends Error {
|
|
|
9561
9565
|
this.code = code;
|
|
9562
9566
|
}
|
|
9563
9567
|
}
|
|
9568
|
+
function detectLocale() {
|
|
9569
|
+
if (typeof navigator === "undefined") return "US";
|
|
9570
|
+
const lang = navigator.language || "";
|
|
9571
|
+
const region = lang.split("-")[1]?.toUpperCase();
|
|
9572
|
+
if (region === "GB") return "UK";
|
|
9573
|
+
if (region) return region;
|
|
9574
|
+
const map = {
|
|
9575
|
+
en: "US",
|
|
9576
|
+
ja: "JP",
|
|
9577
|
+
ko: "KR",
|
|
9578
|
+
zh: "CN",
|
|
9579
|
+
fr: "FR",
|
|
9580
|
+
it: "IT",
|
|
9581
|
+
de: "DE",
|
|
9582
|
+
es: "ES",
|
|
9583
|
+
pt: "BR"
|
|
9584
|
+
};
|
|
9585
|
+
return map[lang.split("-")[0].toLowerCase()] || "US";
|
|
9586
|
+
}
|
|
9587
|
+
function getApiKey() {
|
|
9588
|
+
let key = "";
|
|
9589
|
+
try {
|
|
9590
|
+
key = "shopify-proxy";
|
|
9591
|
+
} catch {
|
|
9592
|
+
}
|
|
9593
|
+
return key;
|
|
9594
|
+
}
|
|
9595
|
+
function getApiUrl(override) {
|
|
9596
|
+
if (override) return override;
|
|
9597
|
+
let envUrl = "";
|
|
9598
|
+
try {
|
|
9599
|
+
envUrl = "";
|
|
9600
|
+
} catch {
|
|
9601
|
+
}
|
|
9602
|
+
return envUrl || "http://localhost:4000";
|
|
9603
|
+
}
|
|
9604
|
+
function cx(base, override) {
|
|
9605
|
+
return override ? `${base} ${override}` : base;
|
|
9606
|
+
}
|
|
9607
|
+
const MOBILE_BREAKPOINT = 768;
|
|
9608
|
+
function useIsMobile() {
|
|
9609
|
+
const [isMobile, setIsMobile] = reactExports.useState(false);
|
|
9610
|
+
reactExports.useEffect(() => {
|
|
9611
|
+
if (typeof window === "undefined") return;
|
|
9612
|
+
const check = () => setIsMobile(window.innerWidth < MOBILE_BREAKPOINT);
|
|
9613
|
+
check();
|
|
9614
|
+
window.addEventListener("resize", check);
|
|
9615
|
+
return () => window.removeEventListener("resize", check);
|
|
9616
|
+
}, []);
|
|
9617
|
+
return isMobile;
|
|
9618
|
+
}
|
|
9619
|
+
function ErrorView({
|
|
9620
|
+
productImage,
|
|
9621
|
+
productTitle,
|
|
9622
|
+
onManualMeasurements,
|
|
9623
|
+
cn,
|
|
9624
|
+
t: t2
|
|
9625
|
+
}) {
|
|
9626
|
+
const isMobile = useIsMobile();
|
|
9627
|
+
const RightColumn = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: cx("ps-tryon-no-chart-content ps-tryon-error-fallback", cn.error), children: [
|
|
9628
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-icon ps-tryon-error-fallback-icon", "aria-hidden": "true", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { viewBox: "0 0 24 24", width: "44", height: "44", fill: "none", stroke: "currentColor", strokeWidth: "1.5", strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
9629
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 3l8.5 15H3.5L12 3z" }),
|
|
9630
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 9v4" }),
|
|
9631
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 17h.01" })
|
|
9632
|
+
] }) }),
|
|
9633
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-no-chart-title", children: t2("We couldn't find a matching size for you") }),
|
|
9634
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: cx("ps-tryon-no-chart-msg", cn.errorText), children: t2("Please try the manual measurement screen so we can calculate your fit from your measurements.") }),
|
|
9635
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", onClick: onManualMeasurements, className: cx("ps-tryon-no-chart-cta", cn.submitButton), children: [
|
|
9636
|
+
t2("Try manual measurements"),
|
|
9637
|
+
" →"
|
|
9638
|
+
] }) })
|
|
9639
|
+
] });
|
|
9640
|
+
if (isMobile) {
|
|
9641
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr", children: [
|
|
9642
|
+
productImage && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-col", style: { flex: "0 0 auto", maxHeight: "38vh" }, children: /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: productImage, alt: productTitle || "", className: "ps-tryon-sr-product-img" }) }),
|
|
9643
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-right-col", children: RightColumn })
|
|
9644
|
+
] });
|
|
9645
|
+
}
|
|
9646
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr", children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-split", children: [
|
|
9647
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-col", children: productImage && /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: productImage, alt: productTitle || "", className: "ps-tryon-sr-product-img" }) }),
|
|
9648
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-right-col ps-tryon-no-chart-right-col", children: RightColumn })
|
|
9649
|
+
] }) });
|
|
9650
|
+
}
|
|
9564
9651
|
class SseClient {
|
|
9565
9652
|
constructor(streamUrl) {
|
|
9566
9653
|
this.eventSource = null;
|
|
@@ -10932,42 +11019,6 @@ function installCartHook() {
|
|
|
10932
11019
|
}
|
|
10933
11020
|
console.log(TAG$1, "attribution hook installed");
|
|
10934
11021
|
}
|
|
10935
|
-
function detectLocale() {
|
|
10936
|
-
if (typeof navigator === "undefined") return "US";
|
|
10937
|
-
const lang = navigator.language || "";
|
|
10938
|
-
const region = lang.split("-")[1]?.toUpperCase();
|
|
10939
|
-
if (region === "GB") return "UK";
|
|
10940
|
-
if (region) return region;
|
|
10941
|
-
const map = {
|
|
10942
|
-
en: "US",
|
|
10943
|
-
ja: "JP",
|
|
10944
|
-
ko: "KR",
|
|
10945
|
-
zh: "CN",
|
|
10946
|
-
fr: "FR",
|
|
10947
|
-
it: "IT",
|
|
10948
|
-
de: "DE",
|
|
10949
|
-
es: "ES",
|
|
10950
|
-
pt: "BR"
|
|
10951
|
-
};
|
|
10952
|
-
return map[lang.split("-")[0].toLowerCase()] || "US";
|
|
10953
|
-
}
|
|
10954
|
-
function getApiKey() {
|
|
10955
|
-
let key = "";
|
|
10956
|
-
try {
|
|
10957
|
-
key = "shopify-proxy";
|
|
10958
|
-
} catch {
|
|
10959
|
-
}
|
|
10960
|
-
return key;
|
|
10961
|
-
}
|
|
10962
|
-
function getApiUrl(override) {
|
|
10963
|
-
if (override) return override;
|
|
10964
|
-
let envUrl = "";
|
|
10965
|
-
try {
|
|
10966
|
-
envUrl = "";
|
|
10967
|
-
} catch {
|
|
10968
|
-
}
|
|
10969
|
-
return envUrl || "http://localhost:4000";
|
|
10970
|
-
}
|
|
10971
11022
|
const SESSION_KEY = "primestyle_profile_session";
|
|
10972
11023
|
const AUTH_MESSAGE_TYPE = "PRIMESTYLE_SDK_AUTH";
|
|
10973
11024
|
const POPUP_TIMEOUT_MS = 12e4;
|
|
@@ -11150,6 +11201,30 @@ async function saveRemoteProfiles(apiUrl, accessToken, profiles, activeProfileId
|
|
|
11150
11201
|
});
|
|
11151
11202
|
return normalizeStore(await parseResponse(response));
|
|
11152
11203
|
}
|
|
11204
|
+
function shouldUseShopifyProxy(apiUrl) {
|
|
11205
|
+
if (typeof window === "undefined") return false;
|
|
11206
|
+
try {
|
|
11207
|
+
const w2 = window;
|
|
11208
|
+
if (w2.Shopify?.shop) return true;
|
|
11209
|
+
return /\/apps\/primestyle\/?$/.test(apiUrl);
|
|
11210
|
+
} catch {
|
|
11211
|
+
return false;
|
|
11212
|
+
}
|
|
11213
|
+
}
|
|
11214
|
+
function reportDirectSdkEvent(apiUrl, apiKey, body) {
|
|
11215
|
+
if (!apiKey || shouldUseShopifyProxy(apiUrl)) return;
|
|
11216
|
+
void fetch(`${apiUrl}/api/v1/tryon/event`, {
|
|
11217
|
+
method: "POST",
|
|
11218
|
+
headers: jsonHeaders(apiKey),
|
|
11219
|
+
keepalive: true,
|
|
11220
|
+
body: JSON.stringify({
|
|
11221
|
+
...body,
|
|
11222
|
+
sessionId: getOrCreateSessionId(),
|
|
11223
|
+
deviceHint: getDeviceHint()
|
|
11224
|
+
})
|
|
11225
|
+
}).catch(() => {
|
|
11226
|
+
});
|
|
11227
|
+
}
|
|
11153
11228
|
let cachedMP = null;
|
|
11154
11229
|
const MP_CACHE_TTL_MS = 6e4;
|
|
11155
11230
|
function setCachedMediaPipe(landmarks) {
|
|
@@ -11223,6 +11298,13 @@ async function recommendForProduct(input) {
|
|
|
11223
11298
|
recommendedSize: cached.recommendedSize,
|
|
11224
11299
|
fromCache: true
|
|
11225
11300
|
});
|
|
11301
|
+
reportDirectSdkEvent(apiUrl, apiKey, {
|
|
11302
|
+
eventType: "SIZE_RECOMMENDATION_SHOWN",
|
|
11303
|
+
productId: input.productId,
|
|
11304
|
+
productTitle: input.productTitle,
|
|
11305
|
+
recommendedSize: cached.recommendedSize,
|
|
11306
|
+
metadata: { fromCache: true, profileId: profile.id }
|
|
11307
|
+
});
|
|
11226
11308
|
const reconstructedRaw = cached.sectionsFull ? {
|
|
11227
11309
|
recommendedSize: cached.recommendedSize,
|
|
11228
11310
|
confidence: cached.confidence || "high",
|
|
@@ -11434,6 +11516,19 @@ async function recommendForProduct(input) {
|
|
|
11434
11516
|
size: result.recommendedSize,
|
|
11435
11517
|
recommendedSize: result.recommendedSize
|
|
11436
11518
|
});
|
|
11519
|
+
logSizeShown({
|
|
11520
|
+
productId: input.productId,
|
|
11521
|
+
productTitle: input.productTitle,
|
|
11522
|
+
recommendedSize: result.recommendedSize,
|
|
11523
|
+
fromCache: false
|
|
11524
|
+
});
|
|
11525
|
+
reportDirectSdkEvent(apiUrl, apiKey, {
|
|
11526
|
+
eventType: "SIZE_RECOMMENDATION_SHOWN",
|
|
11527
|
+
productId: input.productId,
|
|
11528
|
+
productTitle: input.productTitle,
|
|
11529
|
+
recommendedSize: result.recommendedSize,
|
|
11530
|
+
metadata: { fromCache: false, profileId: profile.id, found: result.found }
|
|
11531
|
+
});
|
|
11437
11532
|
return {
|
|
11438
11533
|
recommendedSize: result.recommendedSize,
|
|
11439
11534
|
confidence: result.confidence,
|
|
@@ -11785,7 +11880,8 @@ function productFitTypeToMeasurementType(fitType) {
|
|
|
11785
11880
|
if (fitType === "shoe") return "foot";
|
|
11786
11881
|
if (fitType === "hat") return "head";
|
|
11787
11882
|
if (fitType === "sunglasses") return "face";
|
|
11788
|
-
if (fitType === "
|
|
11883
|
+
if (fitType === "watch") return "wrist";
|
|
11884
|
+
if (fitType === "bracelet") return "body-basic";
|
|
11789
11885
|
if (fitType === "bag" || fitType === "belt" || fitType === "earring" || fitType === "necklace" || fitType === "ring" || fitType === "accessory") {
|
|
11790
11886
|
return "body-basic";
|
|
11791
11887
|
}
|
|
@@ -12344,6 +12440,9 @@ const STYLES = `
|
|
|
12344
12440
|
.ps-tryon-v2-result-panel .ps-tryon-v2-sep {
|
|
12345
12441
|
margin-bottom: 0;
|
|
12346
12442
|
}
|
|
12443
|
+
.ps-tryon-v2-multi-result-panel .ps-tryon-v2-result-copy {
|
|
12444
|
+
flex: 0 0 auto;
|
|
12445
|
+
}
|
|
12347
12446
|
.ps-tryon-v2-result-panel .ps-tryon-sr-cards-v2 {
|
|
12348
12447
|
flex: 0 0 auto;
|
|
12349
12448
|
min-height: 0;
|
|
@@ -14690,6 +14789,34 @@ const STYLES = `
|
|
|
14690
14789
|
.ps-tryon-sec-detail .ps-tryon-sr-fit-table td { padding: 0.9vw 0; }
|
|
14691
14790
|
.ps-tryon-sec-detail .ps-tryon-sr-fit-table th { padding: 0.4vw 0 0.6vw; }
|
|
14692
14791
|
.ps-tryon-sec-detail .ps-tryon-sr-chips { gap: 0.4vw; margin: 0.3vw 0; }
|
|
14792
|
+
.ps-tryon-sec-detail-footer {
|
|
14793
|
+
gap: clamp(16px, 1.1vw, 22px);
|
|
14794
|
+
min-height: clamp(44px, 3vw, 54px);
|
|
14795
|
+
}
|
|
14796
|
+
.ps-tryon-sec-detail-footer .ps-bp-back-btn {
|
|
14797
|
+
flex: 0 0 auto;
|
|
14798
|
+
min-width: 0;
|
|
14799
|
+
white-space: nowrap;
|
|
14800
|
+
}
|
|
14801
|
+
.ps-tryon-sec-detail-footer .ps-tryon-v2-action-group {
|
|
14802
|
+
flex: 1 1 auto;
|
|
14803
|
+
max-width: min(430px, 100%);
|
|
14804
|
+
margin-left: auto;
|
|
14805
|
+
gap: clamp(16px, 1vw, 20px);
|
|
14806
|
+
}
|
|
14807
|
+
.ps-tryon-sec-detail-footer .ps-tryon-v2-action-group-single {
|
|
14808
|
+
flex: 0 0 auto;
|
|
14809
|
+
max-width: none;
|
|
14810
|
+
}
|
|
14811
|
+
.ps-tryon-sec-detail-footer .ps-tryon-v2-action-group > .ps-tryon-v2-cta {
|
|
14812
|
+
flex: 1 1 0;
|
|
14813
|
+
min-width: clamp(140px, 9.5vw, 178px);
|
|
14814
|
+
margin-top: 0;
|
|
14815
|
+
}
|
|
14816
|
+
.ps-tryon-sec-detail-footer .ps-tryon-v2-action-group-single > .ps-tryon-v2-cta {
|
|
14817
|
+
flex: 0 0 auto;
|
|
14818
|
+
min-width: clamp(150px, 10vw, 190px);
|
|
14819
|
+
}
|
|
14693
14820
|
|
|
14694
14821
|
/* Length inline selector (inside section detail) */
|
|
14695
14822
|
.ps-tryon-sec-length-row {
|
|
@@ -15018,7 +15145,7 @@ const STYLES = `
|
|
|
15018
15145
|
transform: translateY(-1px);
|
|
15019
15146
|
}
|
|
15020
15147
|
|
|
15021
|
-
/* Size chip
|
|
15148
|
+
/* Size chip suggested dot */
|
|
15022
15149
|
.ps-tryon-sr-chip { position: relative; }
|
|
15023
15150
|
.ps-tryon-sr-rec-dot {
|
|
15024
15151
|
position: absolute; bottom: -0.3vw; left: 50%; transform: translateX(-50%);
|
|
@@ -17064,6 +17191,13 @@ const STYLES = `
|
|
|
17064
17191
|
font-size: clamp(11px, 0.66vw, 13px);
|
|
17065
17192
|
padding: 0 0 3px;
|
|
17066
17193
|
}
|
|
17194
|
+
.ps-bp-system-toggle-large {
|
|
17195
|
+
gap: clamp(18px, 1.1vw, 24px);
|
|
17196
|
+
}
|
|
17197
|
+
.ps-bp-system-toggle-large .ps-bp-system-btn {
|
|
17198
|
+
font-size: clamp(13px, 0.78vw, 15px);
|
|
17199
|
+
padding-bottom: 4px;
|
|
17200
|
+
}
|
|
17067
17201
|
|
|
17068
17202
|
.ps-bp-root {
|
|
17069
17203
|
flex: 1; min-width: 0;
|
|
@@ -20869,7 +21003,7 @@ const STYLES = `
|
|
|
20869
21003
|
min-width: 0;
|
|
20870
21004
|
}
|
|
20871
21005
|
|
|
20872
|
-
/*
|
|
21006
|
+
/* SUGGESTED SIZE card */
|
|
20873
21007
|
.ps-msd-card {
|
|
20874
21008
|
background: var(--ps-bg-primary);
|
|
20875
21009
|
border: 1px solid var(--ps-border-subtle);
|
|
@@ -21135,20 +21269,23 @@ const STYLES = `
|
|
|
21135
21269
|
.ps-bp-photo-help-backdrop { display: none; }
|
|
21136
21270
|
.ps-bp-photo-help {
|
|
21137
21271
|
position: absolute; top: 2.2vw; right: 0;
|
|
21138
|
-
width: min(
|
|
21272
|
+
width: min(520px, 34vw);
|
|
21139
21273
|
background: #FFFFFF;
|
|
21140
21274
|
border: 1px solid var(--ps-border-subtle);
|
|
21141
21275
|
border-radius: 0.8vw;
|
|
21142
21276
|
box-shadow: 0 20px 40px -12px rgba(17,24,39,0.25), 0 8px 16px -8px rgba(17,24,39,0.15);
|
|
21143
21277
|
padding: 0.8vw 1vw;
|
|
21144
21278
|
display: flex; flex-direction: column; gap: 0.6vw;
|
|
21279
|
+
max-height: min(70dvh, 520px);
|
|
21280
|
+
overflow-y: auto;
|
|
21281
|
+
-webkit-overflow-scrolling: touch;
|
|
21145
21282
|
z-index: 5;
|
|
21146
21283
|
}
|
|
21147
21284
|
.ps-bp-photo-help-upload {
|
|
21148
21285
|
top: clamp(46px, 3.2vw, 58px);
|
|
21149
21286
|
left: clamp(12px, 0.85vw, 16px);
|
|
21150
21287
|
right: auto;
|
|
21151
|
-
width: min(
|
|
21288
|
+
width: min(620px, calc(100% - clamp(24px, 1.7vw, 32px)));
|
|
21152
21289
|
max-height: calc(100% - clamp(64px, 4.5vw, 82px));
|
|
21153
21290
|
overflow-y: auto;
|
|
21154
21291
|
}
|
|
@@ -23672,7 +23809,7 @@ function WelcomeView({
|
|
|
23672
23809
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-welcome-sub", children: t2("Check your size, then try it on virtually") })
|
|
23673
23810
|
] }),
|
|
23674
23811
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-features", children: [
|
|
23675
|
-
{ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(RulerIcon$1, { size: 22 }), title: t2("Get Your Size"), desc: t2("Instant fit
|
|
23812
|
+
{ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(RulerIcon$1, { size: 22 }), title: t2("Get Your Size"), desc: t2("Instant fit suggestion") },
|
|
23676
23813
|
{ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(CameraIcon$1, { size: 22 }), title: t2("Try It On"), desc: t2("See how it looks on you") }
|
|
23677
23814
|
].map((f2, i) => /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-feature", children: [
|
|
23678
23815
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-feature-icon", children: f2.icon }),
|
|
@@ -23991,24 +24128,24 @@ function MobileScanningView({
|
|
|
23991
24128
|
{ title: t2("DETECTING HEAD"), desc: t2("Reading head landmarks from your photo."), viewfinderText: t2("DETECTING HEAD") },
|
|
23992
24129
|
{ title: t2("MAPPING CIRCUMFERENCE"), desc: t2("Estimating head width and depth."), viewfinderText: t2("MAPPING") },
|
|
23993
24130
|
{ title: t2("MATCHING HAT SIZE"), desc: t2("Comparing your circumference to the size chart."), viewfinderText: t2("MATCHING SIZE") },
|
|
23994
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24131
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size."), viewfinderText: t2("FINALIZING") }
|
|
23995
24132
|
] : [
|
|
23996
24133
|
{ title: t2("DETECTING FACE"), desc: t2("Identifying face landmarks in your photo."), viewfinderText: t2("DETECTING FACE") },
|
|
23997
24134
|
{ title: t2("CALIBRATING SCALE"), desc: t2("Using iris size as the pixel-to-mm anchor."), viewfinderText: t2("CALIBRATING") },
|
|
23998
24135
|
{ title: t2("MEASURING FRAME"), desc: t2("Mapping bridge, frame width and temple fit."), viewfinderText: t2("MEASURING") },
|
|
23999
24136
|
{ title: t2("MATCHING FRAME SIZE"), desc: t2("Comparing your measurements to the size chart."), viewfinderText: t2("MATCHING SIZE") },
|
|
24000
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24137
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size."), viewfinderText: t2("FINALIZING") }
|
|
24001
24138
|
] : [
|
|
24002
24139
|
{ title: t2("DETECTING POSE"), desc: t2("Identifying body landmarks from your photo."), viewfinderText: t2("DETECTING POSE") },
|
|
24003
|
-
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions for a size
|
|
24140
|
+
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions for a size suggestion."), viewfinderText: t2("SCANNING FRAME") },
|
|
24004
24141
|
{ title: t2("ANALYZING BODY"), desc: t2("Measuring shoulders, chest, waist and hips."), viewfinderText: t2("ANALYZING") },
|
|
24005
24142
|
{ title: t2("MATCHING SIZE"), desc: t2("Comparing your measurements to the size guide."), viewfinderText: t2("MATCHING SIZE") },
|
|
24006
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24143
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size."), viewfinderText: t2("FINALIZING") }
|
|
24007
24144
|
] : [
|
|
24008
24145
|
{ title: t2("READING YOUR PROFILE"), desc: t2("Loading your saved measurements and body shape answers."), viewfinderText: t2("READING PROFILE") },
|
|
24009
24146
|
{ title: t2("ESTIMATING BODY"), desc: t2("Computing chest, waist, hips, sleeve and inseam from your basics."), viewfinderText: t2("ESTIMATING BODY") },
|
|
24010
24147
|
{ title: t2("MATCHING SIZE"), desc: t2("Comparing your measurements to the garment's size guide."), viewfinderText: t2("MATCHING SIZE") },
|
|
24011
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24148
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size."), viewfinderText: t2("FINALIZING") }
|
|
24012
24149
|
];
|
|
24013
24150
|
const [dims, setDims] = reactExports.useState({ w: 800, h: 1200 });
|
|
24014
24151
|
const handleImgLoad = (e) => {
|
|
@@ -24236,7 +24373,7 @@ function MultiSectionMobile({
|
|
|
24236
24373
|
marginTop: "4px",
|
|
24237
24374
|
color: isOverridden ? "#b45309" : "var(--ps-text-secondary, #6b7280)"
|
|
24238
24375
|
},
|
|
24239
|
-
children: isOverridden ? t2("your selection · not
|
|
24376
|
+
children: isOverridden ? t2("your selection · not suggested") : t2("suggested")
|
|
24240
24377
|
}
|
|
24241
24378
|
)
|
|
24242
24379
|
]
|
|
@@ -24735,13 +24872,13 @@ function StageCycler({
|
|
|
24735
24872
|
{ title: t2("DETECTING HEAD"), desc: t2("Reading head landmarks from your photo.") },
|
|
24736
24873
|
{ title: t2("MAPPING CIRCUMFERENCE"), desc: t2("Estimating head width and depth.") },
|
|
24737
24874
|
{ title: t2("MATCHING HAT SIZE"), desc: t2("Comparing your circumference to the size chart.") },
|
|
24738
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24875
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size.") }
|
|
24739
24876
|
] : category === "face" ? [
|
|
24740
24877
|
{ title: t2("DETECTING FACE"), desc: t2("Identifying 478 face landmarks in your photo.") },
|
|
24741
24878
|
{ title: t2("CALIBRATING SCALE"), desc: t2("Using iris size as the pixel-to-mm anchor.") },
|
|
24742
24879
|
{ title: t2("MEASURING FRAME"), desc: t2("Mapping bridge, lens width and temple length.") },
|
|
24743
24880
|
{ title: t2("MATCHING FRAME SIZE"), desc: t2("Comparing your measurements to the size chart.") },
|
|
24744
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24881
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size.") }
|
|
24745
24882
|
] : [
|
|
24746
24883
|
// Body + foot fall through here — broadest set of stages so long
|
|
24747
24884
|
// Gemini estimates still have fresh text to cycle through.
|
|
@@ -24749,7 +24886,7 @@ function StageCycler({
|
|
|
24749
24886
|
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions.") },
|
|
24750
24887
|
{ title: t2("ANALYZING BODY"), desc: t2("Measuring shoulders, chest, waist and hips.") },
|
|
24751
24888
|
{ title: t2("MATCHING SIZE"), desc: t2("Comparing your measurements to the size guide.") },
|
|
24752
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
24889
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size.") }
|
|
24753
24890
|
];
|
|
24754
24891
|
const TOTAL_MS = 6e3;
|
|
24755
24892
|
const LAST_HOLD_MS = 1e3;
|
|
@@ -25186,7 +25323,7 @@ function SectionDetailView({
|
|
|
25186
25323
|
const details = sectionResult?.matchDetails ?? [];
|
|
25187
25324
|
const BAD_FIT = /tight|loose|large|small|very/i;
|
|
25188
25325
|
const hasBadFit = details.some((d) => BAD_FIT.test(d.fit || ""));
|
|
25189
|
-
return hasBadFit ? t2("Not
|
|
25326
|
+
return hasBadFit ? t2("Not Suggested") : t2("Your Selection");
|
|
25190
25327
|
}, [isRecommended, sectionResult, t2]);
|
|
25191
25328
|
const sizeFitPrefix = (() => {
|
|
25192
25329
|
if (renderRaw || isFootwear) return "";
|
|
@@ -25587,7 +25724,7 @@ function SectionDetailView({
|
|
|
25587
25724
|
{
|
|
25588
25725
|
className: "ps-msd-card-eyebrow",
|
|
25589
25726
|
style: displaySize !== backendSize ? { color: "#b45309", fontWeight: 700 } : void 0,
|
|
25590
|
-
children: displaySize === backendSize ? t2("
|
|
25727
|
+
children: displaySize === backendSize ? t2("SUGGESTED SIZE") : t2("YOUR CHOICE · NOT SUGGESTED")
|
|
25591
25728
|
}
|
|
25592
25729
|
),
|
|
25593
25730
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "10px", marginTop: "6px", marginBottom: "4px" }, children: [
|
|
@@ -25778,7 +25915,7 @@ function SectionDetailView({
|
|
|
25778
25915
|
] })
|
|
25779
25916
|
] }) });
|
|
25780
25917
|
}
|
|
25781
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sec-detail", style: { padding: "1.
|
|
25918
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sec-detail", style: { padding: "1.2vw 0.95vw 1vw", display: "flex", flexDirection: "column", height: "100%", background: "#F8F9FA" }, children: [
|
|
25782
25919
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1, minHeight: 0, overflowY: "auto", scrollbarWidth: "thin", scrollbarColor: "rgba(0,0,0,0.04) transparent", display: sectionFound === false ? "flex" : "block", alignItems: sectionFound === false ? "center" : void 0, justifyContent: sectionFound === false ? "center" : void 0 }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
25783
25920
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
25784
25921
|
"span",
|
|
@@ -25790,7 +25927,7 @@ function SectionDetailView({
|
|
|
25790
25927
|
textTransform: "uppercase",
|
|
25791
25928
|
letterSpacing: "0.12em"
|
|
25792
25929
|
},
|
|
25793
|
-
children: guideOnly ? t2("Size Guide") : isRecommended ? t2("
|
|
25930
|
+
children: guideOnly ? t2("Size Guide") : isRecommended ? t2("Suggested Size") : t2("Your Choice · Not Suggested")
|
|
25794
25931
|
}
|
|
25795
25932
|
),
|
|
25796
25933
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", gap: "0.5vw", marginTop: "0.35vw", marginBottom: "0.4vw" }, children: [
|
|
@@ -25950,11 +26087,11 @@ function SectionDetailView({
|
|
|
25950
26087
|
] })
|
|
25951
26088
|
] }) }),
|
|
25952
26089
|
profileCompletionCta && /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, t: t2 }),
|
|
25953
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between", paddingTop: "0.6vw", borderTop: "1px solid rgba(0,0,0,0.06)", flexShrink: 0 }, children: [
|
|
26090
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sec-detail-footer", style: { display: "flex", alignItems: "center", justifyContent: "space-between", paddingTop: "0.6vw", borderTop: "1px solid rgba(0,0,0,0.06)", flexShrink: 0 }, children: [
|
|
25954
26091
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-bp-back-btn", onClick: onBack, type: "button", style: { fontSize: "0.7vw" }, children: [
|
|
25955
26092
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-back-arrow", children: "←" }),
|
|
25956
26093
|
" ",
|
|
25957
|
-
backLabel || t2("Back
|
|
26094
|
+
backLabel || t2("Back")
|
|
25958
26095
|
] }),
|
|
25959
26096
|
onTryOn ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25960
26097
|
"button",
|
|
@@ -25988,7 +26125,7 @@ function SectionDetailView({
|
|
|
25988
26125
|
tryOnProcessing ? `${t2("Generating try-on…")}${tryOnElapsedS > 0 ? ` ${tryOnElapsedS}s` : ""}` : t2("Try It On")
|
|
25989
26126
|
]
|
|
25990
26127
|
}
|
|
25991
|
-
) : resultActionNode ?
|
|
26128
|
+
) : resultActionNode ? resultActionNode : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25992
26129
|
"button",
|
|
25993
26130
|
{
|
|
25994
26131
|
onClick: continueLabel ? onContinue || onBack : onBack,
|
|
@@ -26051,6 +26188,7 @@ function SizeResultView({
|
|
|
26051
26188
|
bodyLandmarks,
|
|
26052
26189
|
faceLandmarks = null,
|
|
26053
26190
|
measurementType = "body",
|
|
26191
|
+
isAccessoryProduct = false,
|
|
26054
26192
|
estimationDone = false,
|
|
26055
26193
|
activeSection,
|
|
26056
26194
|
setActiveSection,
|
|
@@ -26110,9 +26248,10 @@ function SizeResultView({
|
|
|
26110
26248
|
) });
|
|
26111
26249
|
}
|
|
26112
26250
|
const allowAddToBag = options?.allowAddToBag !== false;
|
|
26251
|
+
const showContinue = options?.showContinue !== false;
|
|
26113
26252
|
if (allowAddToBag && canAddToBag) {
|
|
26114
|
-
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-action-group"
|
|
26115
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
26253
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-tryon-v2-action-group${!showContinue ? " ps-tryon-v2-action-group-single" : ""}`, children: [
|
|
26254
|
+
showContinue && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
26116
26255
|
"button",
|
|
26117
26256
|
{
|
|
26118
26257
|
className: "ps-tryon-v2-cta ps-tryon-v2-cta-secondary",
|
|
@@ -26141,6 +26280,9 @@ function SizeResultView({
|
|
|
26141
26280
|
)
|
|
26142
26281
|
] });
|
|
26143
26282
|
}
|
|
26283
|
+
if (!showContinue) {
|
|
26284
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-action-group ps-tryon-v2-action-group-single", "aria-hidden": "true" });
|
|
26285
|
+
}
|
|
26144
26286
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
26145
26287
|
"button",
|
|
26146
26288
|
{
|
|
@@ -26177,13 +26319,13 @@ function SizeResultView({
|
|
|
26177
26319
|
return /^standard(?:\s+size)?$/i.test(cleaned);
|
|
26178
26320
|
});
|
|
26179
26321
|
if (standardIdx >= 0) return standardIdx;
|
|
26180
|
-
const
|
|
26181
|
-
if (
|
|
26322
|
+
const suggested = String(sizingResult?.recommendedSize || "").trim();
|
|
26323
|
+
if (suggested) {
|
|
26182
26324
|
const byRecommendedValue = sizeGuide.headers.findIndex((h, c) => {
|
|
26183
26325
|
const cleaned = h.trim().replace(/\(.*?\)/g, "").trim();
|
|
26184
26326
|
const sizeLikeHeader = /^(size|sizes|taglia|größe|taille|standard)$/i.test(cleaned);
|
|
26185
26327
|
const alphaSizeColumn = rows.some((r2) => /^(XXS|XS|S|M|L|XL|XXL|XXXL|[3-9]XL|ONE SIZE)$/i.test(cellVal(r2, c, h)));
|
|
26186
|
-
return (sizeLikeHeader || alphaSizeColumn) && rows.some((r2) => cellVal(r2, c, h) ===
|
|
26328
|
+
return (sizeLikeHeader || alphaSizeColumn) && rows.some((r2) => cellVal(r2, c, h) === suggested);
|
|
26187
26329
|
});
|
|
26188
26330
|
if (byRecommendedValue >= 0) return byRecommendedValue;
|
|
26189
26331
|
}
|
|
@@ -26481,7 +26623,7 @@ function SizeResultView({
|
|
|
26481
26623
|
const profileCompletionCta = showProfileCompletionCta && onProfileCompletionCta ? { onClick: onProfileCompletionCta } : null;
|
|
26482
26624
|
const carouselItems = productCarouselItems?.filter((item) => item.image) ?? [];
|
|
26483
26625
|
const hasCarousel = carouselItems.length > 0 || !!(productImages && productImages.length > 0);
|
|
26484
|
-
const isAccessory = measurementType === "face" || measurementType === "head" || measurementType === "wrist";
|
|
26626
|
+
const isAccessory = isAccessoryProduct || measurementType === "face" || measurementType === "head" || measurementType === "wrist";
|
|
26485
26627
|
const suppressFitOverlayActions = isAccessory || measurementType === "foot";
|
|
26486
26628
|
const noFit = sizingResult?.found === false;
|
|
26487
26629
|
const guideOnlyResult = !!(sizingResult?.guideOnly || sizingResult?.oneSize);
|
|
@@ -26583,7 +26725,7 @@ function SizeResultView({
|
|
|
26583
26725
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-col", children: /* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: productImage, alt: productTitle, className: "ps-tryon-sr-product-img" }) }),
|
|
26584
26726
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-right-col", style: { display: "flex", flexDirection: "column", alignItems: "center", justifyContent: "center", gap: "0.8vw" }, children: [
|
|
26585
26727
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-size-loading-spinner" }),
|
|
26586
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--ps-text-muted)", fontSize: "0.8vw" }, children: t2("Generating your size
|
|
26728
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { color: "var(--ps-text-muted)", fontSize: "0.8vw" }, children: t2("Generating your suggested size...") })
|
|
26587
26729
|
] })
|
|
26588
26730
|
] }),
|
|
26589
26731
|
isMobile && isSnapProcessing && previewUrl && /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -26655,7 +26797,7 @@ function SizeResultView({
|
|
|
26655
26797
|
})(),
|
|
26656
26798
|
onBack: () => setActiveSection(null),
|
|
26657
26799
|
onContinue: handleContinueAction,
|
|
26658
|
-
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
26800
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta({ showContinue: false }) : void 0,
|
|
26659
26801
|
internationalSizes: entry.secResult?.internationalSizes,
|
|
26660
26802
|
productImage: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
|
|
26661
26803
|
productTitle,
|
|
@@ -26756,7 +26898,7 @@ function SizeResultView({
|
|
|
26756
26898
|
})(),
|
|
26757
26899
|
onBack: () => setActiveSection(null),
|
|
26758
26900
|
onContinue: handleContinueAction,
|
|
26759
|
-
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
26901
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta({ showContinue: false }) : void 0,
|
|
26760
26902
|
internationalSizes: entry.secResult?.internationalSizes,
|
|
26761
26903
|
tryOnProcessing,
|
|
26762
26904
|
tryOnStartedAt,
|
|
@@ -26893,9 +27035,9 @@ function SizeResultView({
|
|
|
26893
27035
|
resultImageUrl && !tryOnProcessing && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-img-actions", children: /* @__PURE__ */ jsxRuntimeExports.jsx(TryOnExperienceFeedback, { t: t2, onSubmit: onTryOnFeedbackSubmit }) })
|
|
26894
27036
|
] })
|
|
26895
27037
|
] }),
|
|
26896
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel ps-tryon-v2-result-panel", children: [
|
|
27038
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel ps-tryon-v2-result-panel ps-tryon-v2-multi-result-panel", children: [
|
|
26897
27039
|
profileCompletionCta ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-profile-head ps-expanded", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, placement: "header", t: t2 }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-result-copy", children: [
|
|
26898
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Size
|
|
27040
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Suggested Size") }),
|
|
26899
27041
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-v2-subtitle", children: t2("Tap any section for detailed breakdown") })
|
|
26900
27042
|
] }),
|
|
26901
27043
|
mismatchNotice,
|
|
@@ -26926,7 +27068,7 @@ function SizeResultView({
|
|
|
26926
27068
|
"span",
|
|
26927
27069
|
{
|
|
26928
27070
|
className: `ps-tryon-sr-card-v2-rec-pill${isOverridden ? " is-overridden" : ""}`,
|
|
26929
|
-
children: isOverridden ? t2("YOUR SELECTION") : t2("
|
|
27071
|
+
children: isOverridden ? t2("YOUR SELECTION") : t2("SUGGESTED")
|
|
26930
27072
|
}
|
|
26931
27073
|
),
|
|
26932
27074
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ps-tryon-sr-card-v2-view", children: [
|
|
@@ -27012,7 +27154,7 @@ function SizeResultView({
|
|
|
27012
27154
|
backLabel: t2("Back"),
|
|
27013
27155
|
internationalSizes: singleInternationalSizes,
|
|
27014
27156
|
onTryOn: canAddToBag || isHistoryResult || resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
27015
|
-
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
27157
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta({ showContinue: false }) : void 0,
|
|
27016
27158
|
continueLabel: resultImageUrl ? resolvedContinueShoppingLabel : void 0,
|
|
27017
27159
|
tryOnProcessing,
|
|
27018
27160
|
tryOnStartedAt,
|
|
@@ -27109,7 +27251,7 @@ function SizeResultView({
|
|
|
27109
27251
|
backLabel: t2("Back"),
|
|
27110
27252
|
internationalSizes: singleInternationalSizes,
|
|
27111
27253
|
onTryOn: canAddToBag || isHistoryResult || resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
27112
|
-
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
27254
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta({ showContinue: false }) : void 0,
|
|
27113
27255
|
continueLabel: resultImageUrl ? resolvedContinueShoppingLabel : void 0,
|
|
27114
27256
|
tryOnProcessing,
|
|
27115
27257
|
tryOnStartedAt,
|
|
@@ -27131,10 +27273,10 @@ function SizeResultView({
|
|
|
27131
27273
|
const rawLabelText = pendingCustomSizes[sectionName]?.displayLabel || singleResult.recommendedSize || singleResult.sizeLabel || (guideOnlyResult ? t2("One Size") : "—");
|
|
27132
27274
|
const labelText = measurementType === "foot" ? formatShoeSizeLabel(rawLabelText, shoeUserGender) : rawLabelText;
|
|
27133
27275
|
const isLong = labelText.length > 12;
|
|
27134
|
-
const badgeText = guideOnlyResult ? t2("SIZE GUIDE") : pendingCustomSizes[sectionName] ? t2("YOUR SELECTION") : t2("
|
|
27276
|
+
const badgeText = guideOnlyResult ? t2("SIZE GUIDE") : pendingCustomSizes[sectionName] ? t2("YOUR SELECTION") : t2("SUGGESTED");
|
|
27135
27277
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27136
27278
|
profileCompletionCta ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-result-head", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-profile-head ps-expanded", children: /* @__PURE__ */ jsxRuntimeExports.jsx(ProfileCompletionCta, { onClick: profileCompletionCta.onClick, placement: "header", t: t2 }) }) }) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-result-copy ps-single-result-copy", children: [
|
|
27137
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Size
|
|
27279
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Suggested Size") }),
|
|
27138
27280
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-v2-subtitle", children: t2("Tap the card for detailed breakdown") })
|
|
27139
27281
|
] }),
|
|
27140
27282
|
profileCompletionCta ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-sep" }) : null,
|
|
@@ -27271,7 +27413,7 @@ function SizeResultView({
|
|
|
27271
27413
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Leave space above your head") }),
|
|
27272
27414
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Good lighting, plain background") })
|
|
27273
27415
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27274
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("
|
|
27416
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Wear fitted, simple clothing") }),
|
|
27275
27417
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Standing 2-3 meters from camera") }),
|
|
27276
27418
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Neutral background with good lighting") })
|
|
27277
27419
|
] }) })
|
|
@@ -27807,7 +27949,7 @@ function PhotoGuideView({
|
|
|
27807
27949
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Leave space above your head") }),
|
|
27808
27950
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Good lighting, plain background") })
|
|
27809
27951
|
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
27810
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("
|
|
27952
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Wear fitted, simple clothing") }),
|
|
27811
27953
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Standing 2-3 meters from camera") }),
|
|
27812
27954
|
/* @__PURE__ */ jsxRuntimeExports.jsx("li", { children: t2("Neutral background with good lighting") })
|
|
27813
27955
|
] }) })
|
|
@@ -27987,7 +28129,7 @@ function ProcessingView({
|
|
|
27987
28129
|
}
|
|
27988
28130
|
}, []);
|
|
27989
28131
|
const aiFacts = [
|
|
27990
|
-
t2("Our model is analyzing 150+ body landmarks for your size
|
|
28132
|
+
t2("Our model is analyzing 150+ body landmarks for your size suggestion"),
|
|
27991
28133
|
t2("Calibrating fabric drape against your body proportions"),
|
|
27992
28134
|
t2("Cross-checking fit against millions of garment patterns"),
|
|
27993
28135
|
t2("Rendering shadows and highlights to match your photo's lighting")
|
|
@@ -28227,7 +28369,7 @@ function MiniSelect$1({
|
|
|
28227
28369
|
isOpen,
|
|
28228
28370
|
onToggle,
|
|
28229
28371
|
onSelect,
|
|
28230
|
-
direction = "
|
|
28372
|
+
direction = "up"
|
|
28231
28373
|
}) {
|
|
28232
28374
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-mini-select", "data-open": isOpen ? "true" : "false", "data-dir": direction, children: [
|
|
28233
28375
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -29661,10 +29803,10 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, dire
|
|
|
29661
29803
|
mode === "image" && imageStep === "calculating" && (() => {
|
|
29662
29804
|
const stages = [
|
|
29663
29805
|
{ title: t2("DETECTING POSE"), desc: t2("Identifying body landmarks from your photo.") },
|
|
29664
|
-
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions for a size
|
|
29806
|
+
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions for a size suggestion.") },
|
|
29665
29807
|
{ title: t2("ANALYZING BODY"), desc: t2("Measuring shoulders, chest, waist and hips.") },
|
|
29666
29808
|
{ title: t2("MATCHING SIZE"), desc: t2("Comparing your measurements to the size guide.") },
|
|
29667
|
-
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your
|
|
29809
|
+
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your suggested size.") }
|
|
29668
29810
|
];
|
|
29669
29811
|
const stage = stages[Math.min(scanStageIdx, stages.length - 1)] ?? stages[0];
|
|
29670
29812
|
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-cpw-fade-in", style: { display: "flex", flexDirection: "column", flex: 1, overflow: "auto" }, children: estimating ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", gap: "1.2vw", padding: "1.5vw", flex: 1 }, children: [
|
|
@@ -30444,7 +30586,7 @@ function BasicsStepMobile({
|
|
|
30444
30586
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bpm-root", children: [
|
|
30445
30587
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bpm-header", children: [
|
|
30446
30588
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-bpm-title", children: t2("Body Measurements") }),
|
|
30447
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-bpm-subtitle", children: t2("Enter your details for a bespoke size
|
|
30589
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-bpm-subtitle", children: t2("Enter your details for a bespoke size suggestion") })
|
|
30448
30590
|
] }),
|
|
30449
30591
|
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card", children: [
|
|
30450
30592
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card-copy", children: [
|
|
@@ -31179,7 +31321,7 @@ function MiniSelect({
|
|
|
31179
31321
|
isOpen,
|
|
31180
31322
|
onToggle,
|
|
31181
31323
|
onSelect,
|
|
31182
|
-
direction = "
|
|
31324
|
+
direction = "up"
|
|
31183
31325
|
}) {
|
|
31184
31326
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-mini-select", "data-open": isOpen ? "true" : "false", "data-dir": direction, children: [
|
|
31185
31327
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -31990,7 +32132,8 @@ function BodyProfileView({
|
|
|
31990
32132
|
setBandSize(null);
|
|
31991
32133
|
setCupSize(null);
|
|
31992
32134
|
setInlineBraOpen(null);
|
|
31993
|
-
}
|
|
32135
|
+
},
|
|
32136
|
+
direction: "up"
|
|
31994
32137
|
}
|
|
31995
32138
|
) })
|
|
31996
32139
|
] }),
|
|
@@ -32007,7 +32150,8 @@ function BodyProfileView({
|
|
|
32007
32150
|
onSelect: (v2) => {
|
|
32008
32151
|
setBandSize(v2);
|
|
32009
32152
|
setInlineBraOpen(null);
|
|
32010
|
-
}
|
|
32153
|
+
},
|
|
32154
|
+
direction: "up"
|
|
32011
32155
|
}
|
|
32012
32156
|
) })
|
|
32013
32157
|
] }),
|
|
@@ -32066,6 +32210,7 @@ function BodyProfileView({
|
|
|
32066
32210
|
const analyzeDisabled = analyzeMissing.length > 0;
|
|
32067
32211
|
const analyzeLabel = analyzeDisabled ? analyzeMissing[0] ?? t2("Analyze My Size") : t2("Analyze My Size");
|
|
32068
32212
|
const compactHeightWeightAccessory = simplePhotoOnly && simpleAccessoryLayout && !isShoeReferenceMode;
|
|
32213
|
+
const maleStandardPhotoDetails = !isWomen && !simplePhotoOnly && !isShoeReferenceMode;
|
|
32069
32214
|
if (isMobile) {
|
|
32070
32215
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-wrapper", children: [
|
|
32071
32216
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-scan-progress", children: [
|
|
@@ -32245,7 +32390,7 @@ function BodyProfileView({
|
|
|
32245
32390
|
overflow: "hidden"
|
|
32246
32391
|
},
|
|
32247
32392
|
children: [
|
|
32248
|
-
!photoPreview && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32393
|
+
!photoPreview && !compactHeightWeightAccessory && !maleStandardPhotoDetails && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32249
32394
|
"button",
|
|
32250
32395
|
{
|
|
32251
32396
|
type: "button",
|
|
@@ -32262,7 +32407,7 @@ function BodyProfileView({
|
|
|
32262
32407
|
]
|
|
32263
32408
|
}
|
|
32264
32409
|
),
|
|
32265
|
-
!photoPreview && photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32410
|
+
!photoPreview && !compactHeightWeightAccessory && !maleStandardPhotoDetails && photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32266
32411
|
"div",
|
|
32267
32412
|
{
|
|
32268
32413
|
role: "dialog",
|
|
@@ -32556,19 +32701,118 @@ function BodyProfileView({
|
|
|
32556
32701
|
flex: compactHeightWeightAccessory ? "0 1 min(34vw, 360px)" : 1,
|
|
32557
32702
|
display: "flex",
|
|
32558
32703
|
flexDirection: "column",
|
|
32559
|
-
justifyContent:
|
|
32704
|
+
justifyContent: "flex-start",
|
|
32560
32705
|
position: "relative",
|
|
32561
|
-
gap: compactHeightWeightAccessory ? "
|
|
32706
|
+
gap: compactHeightWeightAccessory ? "0.8vw" : "0.8vw",
|
|
32562
32707
|
minWidth: compactHeightWeightAccessory ? "280px" : void 0
|
|
32563
32708
|
}, children: isShoeReferenceMode ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-shoe-ref-desktop", children: renderShoeReferenceFields() }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
32564
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", {
|
|
32565
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
32566
|
-
|
|
32567
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
32568
|
-
|
|
32569
|
-
|
|
32709
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { children: [
|
|
32710
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-bp-photo-details-head${compactHeightWeightAccessory || maleStandardPhotoDetails ? " ps-bp-photo-details-head-simple" : ""}`, children: [
|
|
32711
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: t2("Body details") }),
|
|
32712
|
+
compactHeightWeightAccessory || maleStandardPhotoDetails ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32713
|
+
"button",
|
|
32714
|
+
{
|
|
32715
|
+
type: "button",
|
|
32716
|
+
onClick: (e) => {
|
|
32717
|
+
e.stopPropagation();
|
|
32718
|
+
setPhotoHelpOpen((v2) => !v2);
|
|
32719
|
+
},
|
|
32720
|
+
"aria-label": t2("How to take a good photo"),
|
|
32721
|
+
title: t2("How to take a good photo"),
|
|
32722
|
+
className: `ps-bp-photo-help-chip${photoHelpOpen ? " ps-active" : ""}`,
|
|
32723
|
+
style: { position: "static", maxWidth: "none", flexShrink: 0 },
|
|
32724
|
+
children: [
|
|
32725
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-photo-help-chip-mark", "aria-hidden": "true", children: "?" }),
|
|
32726
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("How to take a good photo") })
|
|
32727
|
+
]
|
|
32728
|
+
}
|
|
32729
|
+
) : /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-system-toggle ps-bp-system-toggle-compact", children: [
|
|
32730
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${!isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToMetric, type: "button", children: t2("Metric") }),
|
|
32731
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToImperial, type: "button", children: t2("Imperial") })
|
|
32732
|
+
] })
|
|
32733
|
+
] }),
|
|
32734
|
+
(compactHeightWeightAccessory || maleStandardPhotoDetails) && /* @__PURE__ */ jsxRuntimeExports.jsx("p", { style: { margin: "0.2vw 0 0", fontSize: "0.65vw", color: "var(--ps-text-muted)" }, children: t2("These calibrate the AI — all required.") })
|
|
32735
|
+
] }),
|
|
32736
|
+
(compactHeightWeightAccessory || maleStandardPhotoDetails) && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-bp-system-toggle ps-bp-system-toggle-compact${maleStandardPhotoDetails ? " ps-bp-system-toggle-large" : ""}`, style: { alignSelf: "center", marginTop: "1.2vw" }, children: [
|
|
32737
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${!isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToMetric, type: "button", children: t2("Metric") }),
|
|
32738
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToImperial, type: "button", children: t2("Imperial") })
|
|
32570
32739
|
] }),
|
|
32571
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32740
|
+
(compactHeightWeightAccessory || maleStandardPhotoDetails) && photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
32741
|
+
"div",
|
|
32742
|
+
{
|
|
32743
|
+
role: "dialog",
|
|
32744
|
+
"aria-label": t2("How to take the best photo"),
|
|
32745
|
+
style: {
|
|
32746
|
+
position: "absolute",
|
|
32747
|
+
top: "2.2vw",
|
|
32748
|
+
right: 0,
|
|
32749
|
+
width: "min(360px, 22vw)",
|
|
32750
|
+
background: "#FFFFFF",
|
|
32751
|
+
border: "1px solid var(--ps-border-subtle)",
|
|
32752
|
+
borderRadius: "0.8vw",
|
|
32753
|
+
boxShadow: "0 20px 40px -12px rgba(17,24,39,0.25), 0 8px 16px -8px rgba(17,24,39,0.15)",
|
|
32754
|
+
padding: "0.8vw 1vw",
|
|
32755
|
+
display: "flex",
|
|
32756
|
+
flexDirection: "column",
|
|
32757
|
+
gap: "0.6vw",
|
|
32758
|
+
maxHeight: "min(70dvh, 520px)",
|
|
32759
|
+
overflowY: "auto",
|
|
32760
|
+
zIndex: 5
|
|
32761
|
+
},
|
|
32762
|
+
children: [
|
|
32763
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", alignItems: "center", justifyContent: "space-between" }, children: [
|
|
32764
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { fontSize: "0.8vw", fontWeight: 700, color: "var(--ps-text-primary)" }, children: t2("How to take the best photo") }),
|
|
32765
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
32766
|
+
"button",
|
|
32767
|
+
{
|
|
32768
|
+
type: "button",
|
|
32769
|
+
onClick: () => setPhotoHelpOpen(false),
|
|
32770
|
+
"aria-label": t2("Close"),
|
|
32771
|
+
style: { width: "1.4vw", height: "1.4vw", borderRadius: "50%", background: "transparent", border: "none", color: "var(--ps-text-muted)", cursor: "pointer", fontSize: "1vw", lineHeight: 1 },
|
|
32772
|
+
children: "×"
|
|
32773
|
+
}
|
|
32774
|
+
)
|
|
32775
|
+
] }),
|
|
32776
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { background: "#ddfbe7", borderRadius: "0.5vw", padding: "0.55vw 0.75vw" }, children: [
|
|
32777
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { color: "#1c9d4c", fontSize: "0.7vw", fontWeight: 700, marginBottom: "0.3vw" }, children: [
|
|
32778
|
+
"✓ ",
|
|
32779
|
+
t2("Do")
|
|
32780
|
+
] }),
|
|
32781
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { fontSize: "0.6vw", color: "var(--ps-text-primary)", lineHeight: 1.6 }, children: [
|
|
32782
|
+
t2("Stand facing the camera with your full body in frame"),
|
|
32783
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
32784
|
+
t2("Use natural or even lighting"),
|
|
32785
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
32786
|
+
t2("Wear fitted, simple clothing"),
|
|
32787
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
32788
|
+
t2("Choose a plain background")
|
|
32789
|
+
] })
|
|
32790
|
+
] }),
|
|
32791
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { background: "#fee2e2", borderRadius: "0.5vw", padding: "0.55vw 0.75vw" }, children: [
|
|
32792
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { color: "#dc2626", fontSize: "0.7vw", fontWeight: 700, marginBottom: "0.3vw" }, children: [
|
|
32793
|
+
"✕ ",
|
|
32794
|
+
t2("Don't")
|
|
32795
|
+
] }),
|
|
32796
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { fontSize: "0.6vw", color: "var(--ps-text-primary)", lineHeight: 1.6 }, children: [
|
|
32797
|
+
t2("Don't wear loose, baggy, or layered clothing"),
|
|
32798
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
32799
|
+
t2("Don't sit, pose, or bend your body"),
|
|
32800
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
32801
|
+
t2("Don't use strong backlighting")
|
|
32802
|
+
] })
|
|
32803
|
+
] }),
|
|
32804
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { background: "#dbeafe", borderRadius: "0.5vw", padding: "0.55vw 0.75vw", fontSize: "0.58vw", color: "var(--ps-text-primary)", lineHeight: 1.5 }, children: [
|
|
32805
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
|
32806
|
+
t2("Quick Tip"),
|
|
32807
|
+
":"
|
|
32808
|
+
] }),
|
|
32809
|
+
" ",
|
|
32810
|
+
t2("The simpler your photo is, the more accurate your virtual try-on results will be.")
|
|
32811
|
+
] })
|
|
32812
|
+
]
|
|
32813
|
+
}
|
|
32814
|
+
),
|
|
32815
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { marginTop: compactHeightWeightAccessory || maleStandardPhotoDetails ? "auto" : "0.15vw", marginBottom: compactHeightWeightAccessory || maleStandardPhotoDetails ? "auto" : 0, minHeight: 0 }, children: [
|
|
32572
32816
|
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card ps-bp-profile-card-compact", children: [
|
|
32573
32817
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card-copy", children: [
|
|
32574
32818
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-profile-card-eyebrow", children: t2("Active Profile") }),
|
|
@@ -32612,7 +32856,8 @@ function BodyProfileView({
|
|
|
32612
32856
|
setBandSize(null);
|
|
32613
32857
|
setCupSize(null);
|
|
32614
32858
|
setInlineBraOpen(null);
|
|
32615
|
-
}
|
|
32859
|
+
},
|
|
32860
|
+
direction: "up"
|
|
32616
32861
|
}
|
|
32617
32862
|
) })
|
|
32618
32863
|
] }),
|
|
@@ -32629,7 +32874,8 @@ function BodyProfileView({
|
|
|
32629
32874
|
onSelect: (v2) => {
|
|
32630
32875
|
setBandSize(v2);
|
|
32631
32876
|
setInlineBraOpen(null);
|
|
32632
|
-
}
|
|
32877
|
+
},
|
|
32878
|
+
direction: "up"
|
|
32633
32879
|
}
|
|
32634
32880
|
) })
|
|
32635
32881
|
] }),
|
|
@@ -34880,7 +35126,7 @@ function PrimeStyleTryonInner({
|
|
|
34880
35126
|
const key = getApiKey();
|
|
34881
35127
|
const url = getApiUrl(apiUrl);
|
|
34882
35128
|
apiRef.current = new ApiClient(key, url);
|
|
34883
|
-
sseRef.current =
|
|
35129
|
+
sseRef.current = null;
|
|
34884
35130
|
} catch {
|
|
34885
35131
|
}
|
|
34886
35132
|
return () => {
|
|
@@ -34889,6 +35135,52 @@ function PrimeStyleTryonInner({
|
|
|
34889
35135
|
if (pollingRef.current) clearInterval(pollingRef.current);
|
|
34890
35136
|
};
|
|
34891
35137
|
}, [apiUrl]);
|
|
35138
|
+
const reportSdkEvent = reactExports.useCallback((eventType, input = {}) => {
|
|
35139
|
+
if (shouldUseShopifyCartAttribution(apiUrl)) return;
|
|
35140
|
+
const client = apiRef.current;
|
|
35141
|
+
if (!client) return;
|
|
35142
|
+
void client.reportEvent({
|
|
35143
|
+
eventType,
|
|
35144
|
+
productId: effectiveProductId,
|
|
35145
|
+
productTitle: restoredProductTitle || productTitle,
|
|
35146
|
+
productUrl: restoredProductUrl || effectiveProductUrl,
|
|
35147
|
+
jobId: input.jobId ?? currentTryOnJobIdRef.current ?? void 0,
|
|
35148
|
+
recommendedSize: input.recommendedSize ?? sizingResultRef.current?.recommendedSize,
|
|
35149
|
+
metadata: input.metadata
|
|
35150
|
+
}).catch(() => {
|
|
35151
|
+
});
|
|
35152
|
+
}, [apiUrl, effectiveProductId, effectiveProductUrl, productTitle, restoredProductTitle, restoredProductUrl]);
|
|
35153
|
+
const reportSdkClientError = reactExports.useCallback((input) => {
|
|
35154
|
+
if (shouldUseShopifyCartAttribution(apiUrl)) return;
|
|
35155
|
+
const client = apiRef.current;
|
|
35156
|
+
if (!client) return;
|
|
35157
|
+
void client.reportClientError({
|
|
35158
|
+
...input,
|
|
35159
|
+
productId: effectiveProductId,
|
|
35160
|
+
productTitle: restoredProductTitle || productTitle,
|
|
35161
|
+
productUrl: restoredProductUrl || effectiveProductUrl,
|
|
35162
|
+
jobId: input.jobId ?? currentTryOnJobIdRef.current ?? void 0
|
|
35163
|
+
}).catch(() => {
|
|
35164
|
+
});
|
|
35165
|
+
}, [apiUrl, effectiveProductId, effectiveProductUrl, productTitle, restoredProductTitle, restoredProductUrl]);
|
|
35166
|
+
const productViewLoggedRef = reactExports.useRef(null);
|
|
35167
|
+
reactExports.useEffect(() => {
|
|
35168
|
+
const key = `${effectiveProductId || ""}|${effectiveProductUrl || ""}`;
|
|
35169
|
+
if (!key.trim() || productViewLoggedRef.current === key) return;
|
|
35170
|
+
productViewLoggedRef.current = key;
|
|
35171
|
+
if (shouldUseShopifyCartAttribution(apiUrl)) {
|
|
35172
|
+
logProductView({ productId: effectiveProductId, productTitle });
|
|
35173
|
+
return;
|
|
35174
|
+
}
|
|
35175
|
+
reportSdkEvent("PRODUCT_VIEW", {
|
|
35176
|
+
metadata: {
|
|
35177
|
+
productUrl: effectiveProductUrl,
|
|
35178
|
+
productFitType: resolvedProductFitType,
|
|
35179
|
+
productCategory,
|
|
35180
|
+
productSubcategory
|
|
35181
|
+
}
|
|
35182
|
+
});
|
|
35183
|
+
}, [apiUrl, effectiveProductId, effectiveProductUrl, productCategory, productSubcategory, productTitle, reportSdkEvent, resolvedProductFitType]);
|
|
34892
35184
|
const pickFireCountRef = reactExports.useRef(0);
|
|
34893
35185
|
const toBackendFetchableImageUrl = reactExports.useCallback((url) => {
|
|
34894
35186
|
const trimmed = String(url || "").trim();
|
|
@@ -35429,10 +35721,11 @@ function PrimeStyleTryonInner({
|
|
|
35429
35721
|
});
|
|
35430
35722
|
const handleOpen = reactExports.useCallback(() => {
|
|
35431
35723
|
console.log("[ps-sdk] handleOpen fired — opening modal");
|
|
35724
|
+
reportSdkEvent("SDK_OPENED", { metadata: { view: "body-profile" } });
|
|
35432
35725
|
setBodyProfileInitialStep(null);
|
|
35433
35726
|
setView("body-profile");
|
|
35434
35727
|
onOpen?.();
|
|
35435
|
-
}, [onOpen]);
|
|
35728
|
+
}, [onOpen, reportSdkEvent]);
|
|
35436
35729
|
const handleClose = reactExports.useCallback(() => {
|
|
35437
35730
|
const tryOnInFlight = tryOnProcessing;
|
|
35438
35731
|
setView("idle");
|
|
@@ -35522,12 +35815,28 @@ function PrimeStyleTryonInner({
|
|
|
35522
35815
|
if (!isValidImageFile(file)) {
|
|
35523
35816
|
setErrorMessage(t2("Please upload a JPEG, PNG, or WebP image."));
|
|
35524
35817
|
setView("error");
|
|
35818
|
+
reportSdkClientError({
|
|
35819
|
+
message: "Invalid image file type",
|
|
35820
|
+
code: "INVALID_FILE",
|
|
35821
|
+
component: "PhotoUpload",
|
|
35822
|
+
view,
|
|
35823
|
+
severity: "low",
|
|
35824
|
+
metadata: { fileType: file.type, fileSize: file.size }
|
|
35825
|
+
});
|
|
35525
35826
|
onError?.({ message: "Invalid file type", code: "INVALID_FILE" });
|
|
35526
35827
|
return;
|
|
35527
35828
|
}
|
|
35528
35829
|
if (file.size > 10 * 1024 * 1024) {
|
|
35529
35830
|
setErrorMessage(t2("Image must be under 10MB."));
|
|
35530
35831
|
setView("error");
|
|
35832
|
+
reportSdkClientError({
|
|
35833
|
+
message: "Image file too large",
|
|
35834
|
+
code: "FILE_TOO_LARGE",
|
|
35835
|
+
component: "PhotoUpload",
|
|
35836
|
+
view,
|
|
35837
|
+
severity: "low",
|
|
35838
|
+
metadata: { fileType: file.type, fileSize: file.size }
|
|
35839
|
+
});
|
|
35531
35840
|
onError?.({ message: "File too large", code: "FILE_TOO_LARGE" });
|
|
35532
35841
|
return;
|
|
35533
35842
|
}
|
|
@@ -35536,13 +35845,23 @@ function PrimeStyleTryonInner({
|
|
|
35536
35845
|
modelImageIdRef.current = null;
|
|
35537
35846
|
const objUrl = URL.createObjectURL(file);
|
|
35538
35847
|
setPreviewUrl(objUrl);
|
|
35848
|
+
reportSdkEvent("PHOTO_UPLOADED", {
|
|
35849
|
+
metadata: { fileType: file.type, fileSize: file.size, view }
|
|
35850
|
+
});
|
|
35539
35851
|
onUpload?.(file);
|
|
35540
35852
|
modelPoseRef.current = null;
|
|
35541
35853
|
detectMeasurementLines(objUrl).then((lines) => {
|
|
35542
35854
|
modelPoseRef.current = lines;
|
|
35543
|
-
}).catch(() => {
|
|
35855
|
+
}).catch((error) => {
|
|
35856
|
+
reportSdkClientError({
|
|
35857
|
+
message: error instanceof Error ? error.message : "Pose detection failed",
|
|
35858
|
+
code: "POSE_DETECTION_FAILED",
|
|
35859
|
+
component: "MediaPipe",
|
|
35860
|
+
view,
|
|
35861
|
+
severity: "low"
|
|
35862
|
+
});
|
|
35544
35863
|
});
|
|
35545
|
-
}, [onUpload, onError]);
|
|
35864
|
+
}, [onUpload, onError, reportSdkClientError, reportSdkEvent, t2, view]);
|
|
35546
35865
|
const handleRemovePreview = reactExports.useCallback(() => {
|
|
35547
35866
|
setSelectedFile(null);
|
|
35548
35867
|
if (previewUrl) URL.revokeObjectURL(previewUrl);
|
|
@@ -35611,12 +35930,21 @@ function PrimeStyleTryonInner({
|
|
|
35611
35930
|
setTryOnProcessing(false);
|
|
35612
35931
|
setTryOnStartedAt(null);
|
|
35613
35932
|
const msg = update.error || t2("Try-on generation failed");
|
|
35933
|
+
reportSdkClientError({
|
|
35934
|
+
message: msg,
|
|
35935
|
+
code: "TRYON_GENERATION_FAILED",
|
|
35936
|
+
component: "TryOn",
|
|
35937
|
+
view,
|
|
35938
|
+
severity: "medium",
|
|
35939
|
+
jobId: update.galleryId,
|
|
35940
|
+
metadata: { status: update.status }
|
|
35941
|
+
});
|
|
35614
35942
|
setErrorMessage(msg);
|
|
35615
35943
|
setView("error");
|
|
35616
35944
|
onError?.({ message: msg });
|
|
35617
35945
|
}
|
|
35618
35946
|
}
|
|
35619
|
-
}, [apiUrl, effectiveProductId, productTitle, onComplete, onError, cleanupJob]);
|
|
35947
|
+
}, [apiUrl, effectiveProductId, productTitle, onComplete, onError, cleanupJob, reportSdkClientError, t2, view]);
|
|
35620
35948
|
const dynamicFields = reactExports.useMemo(() => {
|
|
35621
35949
|
if (sizeGuide?.found && sizeGuide.requiredFields && sizeGuide.requiredFields.length > 0) {
|
|
35622
35950
|
return sizeGuide.requiredFields;
|
|
@@ -35630,6 +35958,14 @@ function PrimeStyleTryonInner({
|
|
|
35630
35958
|
const method = methodOverride || sizingMethod;
|
|
35631
35959
|
const baseUrl = getApiUrl(apiUrl);
|
|
35632
35960
|
const key = getApiKey();
|
|
35961
|
+
reportSdkEvent("SIZING_STARTED", {
|
|
35962
|
+
metadata: {
|
|
35963
|
+
method,
|
|
35964
|
+
measurementType,
|
|
35965
|
+
productFitType: resolvedProductFitType,
|
|
35966
|
+
hasSizeGuide: !!sizeGuide?.found
|
|
35967
|
+
}
|
|
35968
|
+
});
|
|
35633
35969
|
if (measurementType === "face" || measurementType === "head") {
|
|
35634
35970
|
const f2 = formRef.current;
|
|
35635
35971
|
const toNum = (v2) => {
|
|
@@ -35688,23 +36024,61 @@ function PrimeStyleTryonInner({
|
|
|
35688
36024
|
const data = await resp.json();
|
|
35689
36025
|
await minVisible;
|
|
35690
36026
|
if (data?.found === false) {
|
|
36027
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36028
|
+
metadata: {
|
|
36029
|
+
reason: data?.reasoning || "NO_MATCH",
|
|
36030
|
+
measurementType,
|
|
36031
|
+
found: false
|
|
36032
|
+
}
|
|
36033
|
+
});
|
|
35691
36034
|
setNoSizeReason(data?.reasoning === "NO_SIZE_CHART" ? "no-chart" : "no-match");
|
|
35692
36035
|
setView("no-chart");
|
|
35693
36036
|
setEstimationDone(true);
|
|
35694
36037
|
return;
|
|
35695
36038
|
}
|
|
35696
36039
|
setSizingResult(data);
|
|
36040
|
+
reportSdkEvent("SIZE_RECOMMENDATION_SHOWN", {
|
|
36041
|
+
recommendedSize: data?.recommendedSize,
|
|
36042
|
+
metadata: {
|
|
36043
|
+
confidence: data?.confidence,
|
|
36044
|
+
measurementType,
|
|
36045
|
+
source: "face-recommend"
|
|
36046
|
+
}
|
|
36047
|
+
});
|
|
35697
36048
|
onComplete?.(data);
|
|
35698
36049
|
} else {
|
|
35699
36050
|
const body = await resp.text().catch(() => "");
|
|
35700
36051
|
console.error("[PS-SDK] face-recommend failed:", resp.status, body);
|
|
36052
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36053
|
+
metadata: { status: resp.status, measurementType, source: "face-recommend" }
|
|
36054
|
+
});
|
|
36055
|
+
reportSdkClientError({
|
|
36056
|
+
message: body || "Face/head sizing request failed",
|
|
36057
|
+
code: "FACE_RECOMMEND_FAILED",
|
|
36058
|
+
component: "Sizing",
|
|
36059
|
+
view,
|
|
36060
|
+
severity: "medium",
|
|
36061
|
+
metadata: { status: resp.status, measurementType }
|
|
36062
|
+
});
|
|
35701
36063
|
await minVisible;
|
|
35702
|
-
setErrorMessage(t2("Unable to get size
|
|
36064
|
+
setErrorMessage(t2("Unable to get a size suggestion. Please try again."));
|
|
35703
36065
|
setView("error");
|
|
35704
36066
|
setEstimationDone(true);
|
|
35705
36067
|
}
|
|
35706
36068
|
} catch (err) {
|
|
35707
36069
|
console.error("[PS-SDK] face-recommend network error:", err);
|
|
36070
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36071
|
+
metadata: { measurementType, source: "face-recommend", network: true }
|
|
36072
|
+
});
|
|
36073
|
+
reportSdkClientError({
|
|
36074
|
+
message: err instanceof Error ? err.message : "Face/head sizing network error",
|
|
36075
|
+
code: "FACE_RECOMMEND_NETWORK_ERROR",
|
|
36076
|
+
stack: err instanceof Error ? err.stack : void 0,
|
|
36077
|
+
component: "Sizing",
|
|
36078
|
+
view,
|
|
36079
|
+
severity: "medium",
|
|
36080
|
+
metadata: { measurementType }
|
|
36081
|
+
});
|
|
35708
36082
|
await minVisible;
|
|
35709
36083
|
setErrorMessage(t2("Unable to connect to sizing service. Please try again."));
|
|
35710
36084
|
setView("error");
|
|
@@ -35765,6 +36139,17 @@ function PrimeStyleTryonInner({
|
|
|
35765
36139
|
const qWeight = parseFloat(formRef.current.weight || "0");
|
|
35766
36140
|
if (!qHeight || !qWeight) {
|
|
35767
36141
|
console.error("[PS-SDK] submitSizing ABORT — qHeight:", qHeight, "qWeight:", qWeight, "formRef:", JSON.stringify(formRef.current));
|
|
36142
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36143
|
+
metadata: { reason: "missing_height_or_weight", method, measurementType }
|
|
36144
|
+
});
|
|
36145
|
+
reportSdkClientError({
|
|
36146
|
+
message: "Sizing submitted without height or weight",
|
|
36147
|
+
code: "SIZING_INPUT_MISSING",
|
|
36148
|
+
component: "Sizing",
|
|
36149
|
+
view,
|
|
36150
|
+
severity: "low",
|
|
36151
|
+
metadata: { method, measurementType, qHeight, qWeight }
|
|
36152
|
+
});
|
|
35768
36153
|
setSizingLoading(false);
|
|
35769
36154
|
return;
|
|
35770
36155
|
}
|
|
@@ -35797,12 +36182,29 @@ function PrimeStyleTryonInner({
|
|
|
35797
36182
|
const data = await res.json();
|
|
35798
36183
|
console.log("[PS-SDK] Sizing recommend RESULT:", JSON.stringify(data));
|
|
35799
36184
|
if (data?.found === false) {
|
|
36185
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36186
|
+
metadata: {
|
|
36187
|
+
reason: data?.reasoning || "NO_MATCH",
|
|
36188
|
+
method,
|
|
36189
|
+
measurementType,
|
|
36190
|
+
found: false
|
|
36191
|
+
}
|
|
36192
|
+
});
|
|
35800
36193
|
setNoSizeReason(data?.reasoning === "NO_SIZE_CHART" ? "no-chart" : "no-match");
|
|
35801
36194
|
setView("no-chart");
|
|
35802
36195
|
setEstimationDone(true);
|
|
35803
36196
|
return;
|
|
35804
36197
|
}
|
|
35805
36198
|
setSizingResult(data);
|
|
36199
|
+
reportSdkEvent("SIZE_RECOMMENDATION_SHOWN", {
|
|
36200
|
+
recommendedSize: data?.recommendedSize,
|
|
36201
|
+
metadata: {
|
|
36202
|
+
confidence: data?.confidence,
|
|
36203
|
+
method,
|
|
36204
|
+
measurementType,
|
|
36205
|
+
found: data?.found
|
|
36206
|
+
}
|
|
36207
|
+
});
|
|
35806
36208
|
onComplete?.(data);
|
|
35807
36209
|
const m2 = payload.measurements || {};
|
|
35808
36210
|
const qe2 = payload.quickEstimate || {};
|
|
@@ -35830,26 +36232,49 @@ function PrimeStyleTryonInner({
|
|
|
35830
36232
|
} else {
|
|
35831
36233
|
const errBody = await res.text().catch(() => "");
|
|
35832
36234
|
console.error("[PS-SDK] Sizing recommend failed:", res.status, errBody);
|
|
35833
|
-
|
|
36235
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36236
|
+
metadata: { status: res.status, method, measurementType, source: "sizing-recommend" }
|
|
36237
|
+
});
|
|
36238
|
+
reportSdkClientError({
|
|
36239
|
+
message: errBody || "Sizing request failed",
|
|
36240
|
+
code: "SIZING_RECOMMEND_FAILED",
|
|
36241
|
+
component: "Sizing",
|
|
36242
|
+
view,
|
|
36243
|
+
severity: "medium",
|
|
36244
|
+
metadata: { status: res.status, method, measurementType }
|
|
36245
|
+
});
|
|
36246
|
+
setErrorMessage(t2("Unable to get a size suggestion. Please try again."));
|
|
35834
36247
|
setView("error");
|
|
35835
36248
|
setEstimationDone(true);
|
|
35836
36249
|
}
|
|
35837
36250
|
} catch (err) {
|
|
35838
36251
|
console.error("[PS-SDK] Sizing recommend network error:", err);
|
|
36252
|
+
reportSdkEvent("SIZING_FAILED", {
|
|
36253
|
+
metadata: { method, measurementType, source: "sizing-recommend", network: true }
|
|
36254
|
+
});
|
|
36255
|
+
reportSdkClientError({
|
|
36256
|
+
message: err instanceof Error ? err.message : "Sizing network error",
|
|
36257
|
+
code: "SIZING_RECOMMEND_NETWORK_ERROR",
|
|
36258
|
+
stack: err instanceof Error ? err.stack : void 0,
|
|
36259
|
+
component: "Sizing",
|
|
36260
|
+
view,
|
|
36261
|
+
severity: "medium",
|
|
36262
|
+
metadata: { method, measurementType }
|
|
36263
|
+
});
|
|
35839
36264
|
setErrorMessage(t2("Unable to connect to sizing service. Please try again."));
|
|
35840
36265
|
setView("error");
|
|
35841
36266
|
setEstimationDone(true);
|
|
35842
36267
|
} finally {
|
|
35843
36268
|
setSizingLoading(false);
|
|
35844
36269
|
}
|
|
35845
|
-
}, [apiUrl, sizingMethod, sizingCountry, heightUnit, weightUnit, sizingUnit, sizeGuide, productContext, measurementType, dynamicFields, persistResultToProfile]);
|
|
36270
|
+
}, [apiUrl, sizingMethod, sizingCountry, heightUnit, weightUnit, sizingUnit, sizeGuide, productContext, measurementType, resolvedProductFitType, dynamicFields, persistResultToProfile, reportSdkClientError, reportSdkEvent, t2, view]);
|
|
35846
36271
|
const handleQuickEstimate = reactExports.useCallback(async (height, weight, heightUnit2, weightUnit2, gender, age, bodyType, chestProfile, midsectionProfile, hipProfile, bodyImage) => {
|
|
35847
36272
|
if (!apiRef.current) {
|
|
35848
36273
|
const msg = t2("SDK not configured. Please refresh and try again.");
|
|
35849
36274
|
console.warn("[ps-sdk] handleQuickEstimate BAILED — apiRef is null. API key not loaded.");
|
|
35850
36275
|
setErrorMessage(msg);
|
|
35851
36276
|
setView("error");
|
|
35852
|
-
onError?.({ message: msg, code: "SDK_NOT_CONFIGURED" });
|
|
36277
|
+
onError?.({ message: msg, code: !apiRef.current ? "SDK_NOT_CONFIGURED" : "PHOTO_MISSING" });
|
|
35853
36278
|
return;
|
|
35854
36279
|
}
|
|
35855
36280
|
getApiUrl(apiUrl);
|
|
@@ -36064,7 +36489,7 @@ function PrimeStyleTryonInner({
|
|
|
36064
36489
|
await Promise.all([minVisible2, landmarksVisibleMin || Promise.resolve()]);
|
|
36065
36490
|
const errBody = await recRes.text().catch(() => "");
|
|
36066
36491
|
console.error("[ps-sdk] face-recommend failed:", recRes.status, errBody);
|
|
36067
|
-
setErrorMessage(t2("Unable to get size
|
|
36492
|
+
setErrorMessage(t2("Unable to get a size suggestion. Please try manual measurements."));
|
|
36068
36493
|
setEstimationDone(true);
|
|
36069
36494
|
setSizingLoading(false);
|
|
36070
36495
|
setView("error");
|
|
@@ -36073,7 +36498,7 @@ function PrimeStyleTryonInner({
|
|
|
36073
36498
|
} catch (err) {
|
|
36074
36499
|
console.error("[ps-sdk] face-recommend failed:", err);
|
|
36075
36500
|
await Promise.all([minVisible2, landmarksVisibleMin || Promise.resolve()]);
|
|
36076
|
-
setErrorMessage(t2("Unable to get size
|
|
36501
|
+
setErrorMessage(t2("Unable to get a size suggestion. Please try manual measurements."));
|
|
36077
36502
|
setEstimationDone(true);
|
|
36078
36503
|
setSizingLoading(false);
|
|
36079
36504
|
setView("error");
|
|
@@ -36204,7 +36629,7 @@ function PrimeStyleTryonInner({
|
|
|
36204
36629
|
} else {
|
|
36205
36630
|
const errBody = await recRes.text().catch(() => "");
|
|
36206
36631
|
console.error("[ps-sdk] Sizing recommend failed:", recRes.status, errBody);
|
|
36207
|
-
setErrorMessage(t2("Unable to get size
|
|
36632
|
+
setErrorMessage(t2("Unable to get a size suggestion. Please try manual measurements."));
|
|
36208
36633
|
setEstimationDone(true);
|
|
36209
36634
|
setSizingLoading(false);
|
|
36210
36635
|
setView("error");
|
|
@@ -36228,6 +36653,13 @@ function PrimeStyleTryonInner({
|
|
|
36228
36653
|
const msg = !apiRef.current ? t2("SDK not configured. Please provide an API key.") : t2("Please upload a photo first.");
|
|
36229
36654
|
setErrorMessage(msg);
|
|
36230
36655
|
setView("error");
|
|
36656
|
+
reportSdkClientError({
|
|
36657
|
+
message: msg,
|
|
36658
|
+
code: !apiRef.current ? "SDK_NOT_CONFIGURED" : "PHOTO_MISSING",
|
|
36659
|
+
component: "TryOn",
|
|
36660
|
+
view,
|
|
36661
|
+
severity: !apiRef.current ? "high" : "low"
|
|
36662
|
+
});
|
|
36231
36663
|
onError?.({ message: msg, code: "SDK_NOT_CONFIGURED" });
|
|
36232
36664
|
return;
|
|
36233
36665
|
}
|
|
@@ -36385,9 +36817,9 @@ function PrimeStyleTryonInner({
|
|
|
36385
36817
|
if (response.modelImageId) modelImageIdRef.current = response.modelImageId;
|
|
36386
36818
|
onProcessing?.(response.jobId);
|
|
36387
36819
|
const usePollingOnly = shouldUseShopifyCartAttribution(apiUrl);
|
|
36388
|
-
if (!usePollingOnly
|
|
36820
|
+
if (!usePollingOnly) {
|
|
36389
36821
|
sseRef.current?.disconnect();
|
|
36390
|
-
sseRef.current = new SseClient(response.streamUrl);
|
|
36822
|
+
sseRef.current = new SseClient(response.streamUrl || apiRef.current.getStreamUrl(response.jobId));
|
|
36391
36823
|
}
|
|
36392
36824
|
unsubRef.current?.();
|
|
36393
36825
|
unsubRef.current = usePollingOnly ? null : sseRef.current?.onJob(response.jobId, handleVtoUpdate) ?? null;
|
|
@@ -36415,11 +36847,19 @@ function PrimeStyleTryonInner({
|
|
|
36415
36847
|
} catch (err) {
|
|
36416
36848
|
const message = err instanceof Error ? err.message : t2("Failed to start try-on");
|
|
36417
36849
|
const code = err instanceof PrimeStyleError ? err.code : void 0;
|
|
36850
|
+
reportSdkClientError({
|
|
36851
|
+
message,
|
|
36852
|
+
code: code || "TRYON_SUBMIT_FAILED",
|
|
36853
|
+
stack: err instanceof Error ? err.stack : void 0,
|
|
36854
|
+
component: "TryOn",
|
|
36855
|
+
view,
|
|
36856
|
+
severity: "medium"
|
|
36857
|
+
});
|
|
36418
36858
|
setErrorMessage(message);
|
|
36419
36859
|
setView("error");
|
|
36420
36860
|
onError?.({ message, code });
|
|
36421
36861
|
}
|
|
36422
|
-
}, [selectedFile, productImage, effectiveProductImages, garmentReferenceImage, garmentDetailImage, productTitle, productCategory, productSubcategory, resolvedProductFitType, productType, productTagsList, productDescription, productMaterial, measurementType, sizingResult, sizeGuide, apiUrl, onProcessing, onError, handleVtoUpdate]);
|
|
36862
|
+
}, [selectedFile, productImage, effectiveProductImages, garmentReferenceImage, garmentDetailImage, productTitle, productCategory, productSubcategory, resolvedProductFitType, productType, productTagsList, productDescription, productMaterial, measurementType, sizingResult, sizeGuide, apiUrl, onProcessing, onError, handleVtoUpdate, reportSdkClientError, t2, view]);
|
|
36423
36863
|
reactExports.useEffect(() => {
|
|
36424
36864
|
if (view !== "size-result") {
|
|
36425
36865
|
autoTryOnFiredRef.current = false;
|
|
@@ -36511,7 +36951,7 @@ function PrimeStyleTryonInner({
|
|
|
36511
36951
|
}, [sizingResult]);
|
|
36512
36952
|
const handleAddToBag = reactExports.useCallback(async () => {
|
|
36513
36953
|
if (!onAddToBag || !sizingResult) return;
|
|
36514
|
-
|
|
36954
|
+
const payload = {
|
|
36515
36955
|
productId,
|
|
36516
36956
|
productTitle: restoredProductTitle || productTitle,
|
|
36517
36957
|
productUrl: restoredProductUrl || effectiveProductUrl,
|
|
@@ -36520,7 +36960,33 @@ function PrimeStyleTryonInner({
|
|
|
36520
36960
|
resultImageUrl: resultImageUrlRef.current || resultImageUrl,
|
|
36521
36961
|
historyEntryId: currentHistoryEntryIdRef.current ?? void 0,
|
|
36522
36962
|
selectedSizes: buildAddToBagSelectedSizes()
|
|
36523
|
-
}
|
|
36963
|
+
};
|
|
36964
|
+
try {
|
|
36965
|
+
await onAddToBag(payload);
|
|
36966
|
+
reportSdkEvent("SIZE_RECOMMENDATION_ACCEPTED", {
|
|
36967
|
+
recommendedSize: sizingResult.recommendedSize,
|
|
36968
|
+
metadata: { selectedSizes: payload.selectedSizes }
|
|
36969
|
+
});
|
|
36970
|
+
reportSdkEvent("ADD_TO_CART_FROM_TRYON", {
|
|
36971
|
+
recommendedSize: sizingResult.recommendedSize,
|
|
36972
|
+
metadata: {
|
|
36973
|
+
selectedSizes: payload.selectedSizes,
|
|
36974
|
+
historyEntryId: payload.historyEntryId,
|
|
36975
|
+
hasResult: Boolean(payload.resultImageUrl)
|
|
36976
|
+
}
|
|
36977
|
+
});
|
|
36978
|
+
} catch (error) {
|
|
36979
|
+
reportSdkClientError({
|
|
36980
|
+
message: error instanceof Error ? error.message : "Add to bag failed",
|
|
36981
|
+
code: "ADD_TO_BAG_FAILED",
|
|
36982
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
36983
|
+
component: "ResultActions",
|
|
36984
|
+
view,
|
|
36985
|
+
severity: "medium",
|
|
36986
|
+
metadata: { selectedSizes: payload.selectedSizes }
|
|
36987
|
+
});
|
|
36988
|
+
throw error;
|
|
36989
|
+
}
|
|
36524
36990
|
}, [
|
|
36525
36991
|
buildAddToBagSelectedSizes,
|
|
36526
36992
|
effectiveProductUrl,
|
|
@@ -36530,7 +36996,10 @@ function PrimeStyleTryonInner({
|
|
|
36530
36996
|
restoredProductTitle,
|
|
36531
36997
|
restoredProductUrl,
|
|
36532
36998
|
resultImageUrl,
|
|
36533
|
-
|
|
36999
|
+
reportSdkClientError,
|
|
37000
|
+
reportSdkEvent,
|
|
37001
|
+
sizingResult,
|
|
37002
|
+
view
|
|
36534
37003
|
]);
|
|
36535
37004
|
const handleTryOnFeedbackSubmit = reactExports.useCallback(async ({ rating, note }) => {
|
|
36536
37005
|
const profileLoggedIn = Boolean(profileSession);
|
|
@@ -37195,6 +37664,7 @@ function PrimeStyleTryonInner({
|
|
|
37195
37664
|
bodyLandmarks,
|
|
37196
37665
|
faceLandmarks,
|
|
37197
37666
|
measurementType: measurementType === "body-basic" ? "body" : measurementType,
|
|
37667
|
+
isAccessoryProduct: measurementType === "body-basic" || measurementType === "face" || measurementType === "head" || measurementType === "wrist",
|
|
37198
37668
|
activeSection,
|
|
37199
37669
|
setActiveSection,
|
|
37200
37670
|
onResetTryOn: () => {
|
|
@@ -37739,8 +38209,20 @@ class PrimeStyleTryonErrorBoundary extends reactExports.Component {
|
|
|
37739
38209
|
}
|
|
37740
38210
|
componentDidCatch(error) {
|
|
37741
38211
|
console.error("[ps-sdk] PrimeStyleTryon render failed:", error);
|
|
38212
|
+
const message = error instanceof Error ? error.message : "PrimeStyleTryon render failed";
|
|
38213
|
+
void new ApiClient(getApiKey(), getApiUrl(this.props.apiUrl)).reportClientError({
|
|
38214
|
+
message,
|
|
38215
|
+
code: "RENDER_ERROR",
|
|
38216
|
+
stack: error instanceof Error ? error.stack : void 0,
|
|
38217
|
+
component: "PrimeStyleTryon",
|
|
38218
|
+
productId: this.props.productId || this.props.productImage,
|
|
38219
|
+
productTitle: this.props.productTitle,
|
|
38220
|
+
productUrl: this.props.productUrl,
|
|
38221
|
+
severity: "high"
|
|
38222
|
+
}).catch(() => {
|
|
38223
|
+
});
|
|
37742
38224
|
this.props.onError?.({
|
|
37743
|
-
message
|
|
38225
|
+
message,
|
|
37744
38226
|
code: "RENDER_ERROR"
|
|
37745
38227
|
});
|
|
37746
38228
|
}
|