@primestyleai/tryon 5.10.187 → 5.10.189
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/api-client.d.ts +6 -0
- package/dist/{index-CYT0nGWX.js → index-BlzviBfP.js} +101 -110
- package/dist/index-BlzviBfP.js.map +1 -0
- package/dist/primestyle-tryon.js +2 -2
- package/dist/react/PrimeStyleTryonInner.d.ts +1 -1
- package/dist/react/icons.d.ts +6 -0
- package/dist/react/index.d.ts +1 -1
- package/dist/react/index.js +7003 -6216
- package/dist/react/index.js.map +1 -1
- package/dist/react/styles.d.ts +1 -1
- package/dist/react/types.d.ts +23 -0
- package/dist/react/usePrimeStyleSize.d.ts +2 -0
- package/dist/react/utils/storage.d.ts +2 -0
- package/dist/react/views/BodyProfileView.d.ts +6 -1
- package/dist/react/views/CreateProfileWizard.d.ts +3 -1
- package/dist/react/views/MultiSectionMobile.d.ts +3 -1
- package/dist/react/views/NoChartView.d.ts +2 -1
- package/dist/react/views/PhotoStepMobile.d.ts +2 -1
- package/dist/react/views/SizeResultView.d.ts +7 -1
- package/dist/storefront/primestyle-tryon.js +1585 -638
- package/package.json +1 -1
- package/dist/index-CYT0nGWX.js.map +0 -1
|
@@ -275,7 +275,7 @@ var scheduler_production_min = {};
|
|
|
275
275
|
* This source code is licensed under the MIT license found in the
|
|
276
276
|
* LICENSE file in the root directory of this source tree.
|
|
277
277
|
*/
|
|
278
|
-
(function(exports
|
|
278
|
+
(function(exports) {
|
|
279
279
|
function f2(a, b) {
|
|
280
280
|
var c = a.length;
|
|
281
281
|
a.push(b);
|
|
@@ -308,12 +308,12 @@ var scheduler_production_min = {};
|
|
|
308
308
|
}
|
|
309
309
|
if ("object" === typeof performance && "function" === typeof performance.now) {
|
|
310
310
|
var l2 = performance;
|
|
311
|
-
exports
|
|
311
|
+
exports.unstable_now = function() {
|
|
312
312
|
return l2.now();
|
|
313
313
|
};
|
|
314
314
|
} else {
|
|
315
315
|
var p2 = Date, q2 = p2.now();
|
|
316
|
-
exports
|
|
316
|
+
exports.unstable_now = function() {
|
|
317
317
|
return p2.now() - q2;
|
|
318
318
|
};
|
|
319
319
|
}
|
|
@@ -349,7 +349,7 @@ var scheduler_production_min = {};
|
|
|
349
349
|
v2.callback = null;
|
|
350
350
|
y2 = v2.priorityLevel;
|
|
351
351
|
var e = d(v2.expirationTime <= b);
|
|
352
|
-
b = exports
|
|
352
|
+
b = exports.unstable_now();
|
|
353
353
|
"function" === typeof e ? v2.callback = e : v2 === h(r2) && k2(r2);
|
|
354
354
|
G2(b);
|
|
355
355
|
} else k2(r2);
|
|
@@ -368,11 +368,11 @@ var scheduler_production_min = {};
|
|
|
368
368
|
}
|
|
369
369
|
var N2 = false, O2 = null, L2 = -1, P2 = 5, Q2 = -1;
|
|
370
370
|
function M2() {
|
|
371
|
-
return exports
|
|
371
|
+
return exports.unstable_now() - Q2 < P2 ? false : true;
|
|
372
372
|
}
|
|
373
373
|
function R2() {
|
|
374
374
|
if (null !== O2) {
|
|
375
|
-
var a = exports
|
|
375
|
+
var a = exports.unstable_now();
|
|
376
376
|
Q2 = a;
|
|
377
377
|
var b = true;
|
|
378
378
|
try {
|
|
@@ -401,31 +401,31 @@ var scheduler_production_min = {};
|
|
|
401
401
|
}
|
|
402
402
|
function K2(a, b) {
|
|
403
403
|
L2 = D2(function() {
|
|
404
|
-
a(exports
|
|
404
|
+
a(exports.unstable_now());
|
|
405
405
|
}, b);
|
|
406
406
|
}
|
|
407
|
-
exports
|
|
408
|
-
exports
|
|
409
|
-
exports
|
|
410
|
-
exports
|
|
411
|
-
exports
|
|
412
|
-
exports
|
|
413
|
-
exports
|
|
407
|
+
exports.unstable_IdlePriority = 5;
|
|
408
|
+
exports.unstable_ImmediatePriority = 1;
|
|
409
|
+
exports.unstable_LowPriority = 4;
|
|
410
|
+
exports.unstable_NormalPriority = 3;
|
|
411
|
+
exports.unstable_Profiling = null;
|
|
412
|
+
exports.unstable_UserBlockingPriority = 2;
|
|
413
|
+
exports.unstable_cancelCallback = function(a) {
|
|
414
414
|
a.callback = null;
|
|
415
415
|
};
|
|
416
|
-
exports
|
|
416
|
+
exports.unstable_continueExecution = function() {
|
|
417
417
|
A2 || z2 || (A2 = true, I2(J2));
|
|
418
418
|
};
|
|
419
|
-
exports
|
|
419
|
+
exports.unstable_forceFrameRate = function(a) {
|
|
420
420
|
0 > a || 125 < a ? console.error("forceFrameRate takes a positive int between 0 and 125, forcing frame rates higher than 125 fps is not supported") : P2 = 0 < a ? Math.floor(1e3 / a) : 5;
|
|
421
421
|
};
|
|
422
|
-
exports
|
|
422
|
+
exports.unstable_getCurrentPriorityLevel = function() {
|
|
423
423
|
return y2;
|
|
424
424
|
};
|
|
425
|
-
exports
|
|
425
|
+
exports.unstable_getFirstCallbackNode = function() {
|
|
426
426
|
return h(r2);
|
|
427
427
|
};
|
|
428
|
-
exports
|
|
428
|
+
exports.unstable_next = function(a) {
|
|
429
429
|
switch (y2) {
|
|
430
430
|
case 1:
|
|
431
431
|
case 2:
|
|
@@ -443,11 +443,11 @@ var scheduler_production_min = {};
|
|
|
443
443
|
y2 = c;
|
|
444
444
|
}
|
|
445
445
|
};
|
|
446
|
-
exports
|
|
446
|
+
exports.unstable_pauseExecution = function() {
|
|
447
447
|
};
|
|
448
|
-
exports
|
|
448
|
+
exports.unstable_requestPaint = function() {
|
|
449
449
|
};
|
|
450
|
-
exports
|
|
450
|
+
exports.unstable_runWithPriority = function(a, b) {
|
|
451
451
|
switch (a) {
|
|
452
452
|
case 1:
|
|
453
453
|
case 2:
|
|
@@ -466,8 +466,8 @@ var scheduler_production_min = {};
|
|
|
466
466
|
y2 = c;
|
|
467
467
|
}
|
|
468
468
|
};
|
|
469
|
-
exports
|
|
470
|
-
var d = exports
|
|
469
|
+
exports.unstable_scheduleCallback = function(a, b, c) {
|
|
470
|
+
var d = exports.unstable_now();
|
|
471
471
|
"object" === typeof c && null !== c ? (c = c.delay, c = "number" === typeof c && 0 < c ? d + c : d) : c = d;
|
|
472
472
|
switch (a) {
|
|
473
473
|
case 1:
|
|
@@ -490,8 +490,8 @@ var scheduler_production_min = {};
|
|
|
490
490
|
c > d ? (a.sortIndex = c, f2(t2, a), null === h(r2) && a === h(t2) && (B2 ? (E2(L2), L2 = -1) : B2 = true, K2(H2, c - d))) : (a.sortIndex = e, f2(r2, a), A2 || z2 || (A2 = true, I2(J2)));
|
|
491
491
|
return a;
|
|
492
492
|
};
|
|
493
|
-
exports
|
|
494
|
-
exports
|
|
493
|
+
exports.unstable_shouldYield = M2;
|
|
494
|
+
exports.unstable_wrapCallback = function(a) {
|
|
495
495
|
var b = y2;
|
|
496
496
|
return function() {
|
|
497
497
|
var c = y2;
|
|
@@ -6979,7 +6979,7 @@ const es = {
|
|
|
6979
6979
|
"Virtual Try-On": "Probador Virtual",
|
|
6980
6980
|
"Find Your Size & See It On You": "Encuentra tu talla y pruébatelo",
|
|
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
6984
|
"Instant fit recommendation": "Recomendación de ajuste instantánea",
|
|
6985
6985
|
"Try It On": "Pruébatelo",
|
|
@@ -7014,8 +7014,9 @@ const es = {
|
|
|
7014
7014
|
"Edit measurements": "Editar medidas",
|
|
7015
7015
|
"Size guide": "Guía de tallas",
|
|
7016
7016
|
"Your fit": "Tu ajuste",
|
|
7017
|
+
"Your Size Recommendation": "Tu recomendación de talla",
|
|
7017
7018
|
"Your measure": "Tu medida",
|
|
7018
|
-
"
|
|
7019
|
+
"within range": "dentro del rango",
|
|
7019
7020
|
"too tight": "demasiado ajustado",
|
|
7020
7021
|
"tight": "ajustado",
|
|
7021
7022
|
"a bit tight": "un poco ajustado",
|
|
@@ -7118,8 +7119,6 @@ const es = {
|
|
|
7118
7119
|
"Loose": "Holgado",
|
|
7119
7120
|
"Short": "Corto",
|
|
7120
7121
|
"Long": "Largo",
|
|
7121
|
-
"Perfect": "Perfecto",
|
|
7122
|
-
"Perfect fit": "Ajuste perfecto",
|
|
7123
7122
|
"✓ Fit": "✓ Ajuste",
|
|
7124
7123
|
"too short": "demasiado corto",
|
|
7125
7124
|
"too long": "demasiado largo",
|
|
@@ -7236,7 +7235,7 @@ const fr = {
|
|
|
7236
7235
|
"Virtual Try-On": "Essayage Virtuel",
|
|
7237
7236
|
"Find Your Size & See It On You": "Trouvez votre taille et essayez-le",
|
|
7238
7237
|
"See Your Fit": "Voir votre ajustement",
|
|
7239
|
-
"
|
|
7238
|
+
"Check your size, then try it on virtually": "Vérifiez votre taille, puis essayez-le virtuellement",
|
|
7240
7239
|
"Get Your Size": "Votre taille",
|
|
7241
7240
|
"Instant fit recommendation": "Recommandation de coupe instantanée",
|
|
7242
7241
|
"Try It On": "Essayer",
|
|
@@ -7271,8 +7270,9 @@ const fr = {
|
|
|
7271
7270
|
"Edit measurements": "Modifier les mesures",
|
|
7272
7271
|
"Size guide": "Guide des tailles",
|
|
7273
7272
|
"Your fit": "Votre coupe",
|
|
7273
|
+
"Your Size Recommendation": "Votre recommandation de taille",
|
|
7274
7274
|
"Your measure": "Votre mesure",
|
|
7275
|
-
"
|
|
7275
|
+
"within range": "dans la plage",
|
|
7276
7276
|
"too tight": "trop serré",
|
|
7277
7277
|
"tight": "serré",
|
|
7278
7278
|
"a bit tight": "un peu serré",
|
|
@@ -7375,8 +7375,6 @@ const fr = {
|
|
|
7375
7375
|
"Loose": "Lâche",
|
|
7376
7376
|
"Short": "Court",
|
|
7377
7377
|
"Long": "Long",
|
|
7378
|
-
"Perfect": "Parfait",
|
|
7379
|
-
"Perfect fit": "Ajustement parfait",
|
|
7380
7378
|
"✓ Fit": "✓ Ajusté",
|
|
7381
7379
|
"too short": "trop court",
|
|
7382
7380
|
"too long": "trop long",
|
|
@@ -7493,7 +7491,7 @@ const de = {
|
|
|
7493
7491
|
"Virtual Try-On": "Virtuelle Anprobe",
|
|
7494
7492
|
"Find Your Size & See It On You": "Finden Sie Ihre Größe und probieren Sie es an",
|
|
7495
7493
|
"See Your Fit": "Ihre Passform ansehen",
|
|
7496
|
-
"
|
|
7494
|
+
"Check your size, then try it on virtually": "Prüfen Sie Ihre Größe und probieren Sie es virtuell an",
|
|
7497
7495
|
"Get Your Size": "Ihre Größe",
|
|
7498
7496
|
"Instant fit recommendation": "Sofortige Passformempfehlung",
|
|
7499
7497
|
"Try It On": "Anprobieren",
|
|
@@ -7528,8 +7526,9 @@ const de = {
|
|
|
7528
7526
|
"Edit measurements": "Maße bearbeiten",
|
|
7529
7527
|
"Size guide": "Größentabelle",
|
|
7530
7528
|
"Your fit": "Ihre Passform",
|
|
7529
|
+
"Your Size Recommendation": "Ihre Größenempfehlung",
|
|
7531
7530
|
"Your measure": "Ihr Maß",
|
|
7532
|
-
"
|
|
7531
|
+
"within range": "im Bereich",
|
|
7533
7532
|
"too tight": "zu eng",
|
|
7534
7533
|
"tight": "eng",
|
|
7535
7534
|
"a bit tight": "etwas eng",
|
|
@@ -7632,8 +7631,6 @@ const de = {
|
|
|
7632
7631
|
"Loose": "Locker",
|
|
7633
7632
|
"Short": "Kurz",
|
|
7634
7633
|
"Long": "Lang",
|
|
7635
|
-
"Perfect": "Perfekt",
|
|
7636
|
-
"Perfect fit": "Perfekte Passform",
|
|
7637
7634
|
"✓ Fit": "✓ Passt",
|
|
7638
7635
|
"too short": "zu kurz",
|
|
7639
7636
|
"too long": "zu lang",
|
|
@@ -7750,7 +7747,7 @@ const it = {
|
|
|
7750
7747
|
"Virtual Try-On": "Prova Virtuale",
|
|
7751
7748
|
"Find Your Size & See It On You": "Trova la tua taglia e provalo",
|
|
7752
7749
|
"See Your Fit": "Vedi la vestibilità",
|
|
7753
|
-
"
|
|
7750
|
+
"Check your size, then try it on virtually": "Controlla la tua taglia, poi provalo virtualmente",
|
|
7754
7751
|
"Get Your Size": "La tua taglia",
|
|
7755
7752
|
"Instant fit recommendation": "Raccomandazione vestibilità istantanea",
|
|
7756
7753
|
"Try It On": "Provalo",
|
|
@@ -7785,8 +7782,9 @@ const it = {
|
|
|
7785
7782
|
"Edit measurements": "Modifica misure",
|
|
7786
7783
|
"Size guide": "Guida alle taglie",
|
|
7787
7784
|
"Your fit": "La tua vestibilità",
|
|
7785
|
+
"Your Size Recommendation": "La tua taglia consigliata",
|
|
7788
7786
|
"Your measure": "La tua misura",
|
|
7789
|
-
"
|
|
7787
|
+
"within range": "entro l'intervallo",
|
|
7790
7788
|
"too tight": "troppo stretto",
|
|
7791
7789
|
"tight": "stretto",
|
|
7792
7790
|
"a bit tight": "un po' stretto",
|
|
@@ -7889,8 +7887,6 @@ const it = {
|
|
|
7889
7887
|
"Loose": "Largo",
|
|
7890
7888
|
"Short": "Corto",
|
|
7891
7889
|
"Long": "Lungo",
|
|
7892
|
-
"Perfect": "Perfetto",
|
|
7893
|
-
"Perfect fit": "Vestibilità perfetta",
|
|
7894
7890
|
"✓ Fit": "✓ Adatto",
|
|
7895
7891
|
"too short": "troppo corto",
|
|
7896
7892
|
"too long": "troppo lungo",
|
|
@@ -8007,7 +8003,7 @@ const pt$1 = {
|
|
|
8007
8003
|
"Virtual Try-On": "Provador Virtual",
|
|
8008
8004
|
"Find Your Size & See It On You": "Encontre seu tamanho e experimente",
|
|
8009
8005
|
"See Your Fit": "Veja seu ajuste",
|
|
8010
|
-
"
|
|
8006
|
+
"Check your size, then try it on virtually": "Confira seu tamanho e experimente virtualmente",
|
|
8011
8007
|
"Get Your Size": "Seu tamanho",
|
|
8012
8008
|
"Instant fit recommendation": "Recomendação de caimento instantânea",
|
|
8013
8009
|
"Try It On": "Experimentar",
|
|
@@ -8042,8 +8038,9 @@ const pt$1 = {
|
|
|
8042
8038
|
"Edit measurements": "Editar medidas",
|
|
8043
8039
|
"Size guide": "Guia de tamanhos",
|
|
8044
8040
|
"Your fit": "Seu caimento",
|
|
8041
|
+
"Your Size Recommendation": "Sua recomendação de tamanho",
|
|
8045
8042
|
"Your measure": "Sua medida",
|
|
8046
|
-
"
|
|
8043
|
+
"within range": "dentro da faixa",
|
|
8047
8044
|
"too tight": "muito apertado",
|
|
8048
8045
|
"tight": "apertado",
|
|
8049
8046
|
"a bit tight": "um pouco apertado",
|
|
@@ -8146,8 +8143,6 @@ const pt$1 = {
|
|
|
8146
8143
|
"Loose": "Folgado",
|
|
8147
8144
|
"Short": "Curto",
|
|
8148
8145
|
"Long": "Longo",
|
|
8149
|
-
"Perfect": "Perfeito",
|
|
8150
|
-
"Perfect fit": "Caimento perfeito",
|
|
8151
8146
|
"✓ Fit": "✓ Caimento",
|
|
8152
8147
|
"too short": "muito curto",
|
|
8153
8148
|
"too long": "muito longo",
|
|
@@ -8264,7 +8259,7 @@ const ja = {
|
|
|
8264
8259
|
"Virtual Try-On": "バーチャル試着",
|
|
8265
8260
|
"Find Your Size & See It On You": "あなたのサイズを見つけて試着",
|
|
8266
8261
|
"See Your Fit": "フィット感を見る",
|
|
8267
|
-
"
|
|
8262
|
+
"Check your size, then try it on virtually": "サイズを確認して、バーチャルで試着しましょう",
|
|
8268
8263
|
"Get Your Size": "サイズを確認",
|
|
8269
8264
|
"Instant fit recommendation": "瞬時にフィット提案",
|
|
8270
8265
|
"Try It On": "試着する",
|
|
@@ -8299,8 +8294,9 @@ const ja = {
|
|
|
8299
8294
|
"Edit measurements": "寸法を編集",
|
|
8300
8295
|
"Size guide": "サイズガイド",
|
|
8301
8296
|
"Your fit": "あなたのフィット",
|
|
8297
|
+
"Your Size Recommendation": "サイズのおすすめ",
|
|
8302
8298
|
"Your measure": "あなたの寸法",
|
|
8303
|
-
"
|
|
8299
|
+
"within range": "範囲内",
|
|
8304
8300
|
"too tight": "きつすぎる",
|
|
8305
8301
|
"tight": "きつい",
|
|
8306
8302
|
"a bit tight": "少しきつい",
|
|
@@ -8403,8 +8399,6 @@ const ja = {
|
|
|
8403
8399
|
"Loose": "ゆるい",
|
|
8404
8400
|
"Short": "短い",
|
|
8405
8401
|
"Long": "長い",
|
|
8406
|
-
"Perfect": "ぴったり",
|
|
8407
|
-
"Perfect fit": "ぴったりフィット",
|
|
8408
8402
|
"✓ Fit": "✓ フィット",
|
|
8409
8403
|
"too short": "短すぎる",
|
|
8410
8404
|
"too long": "長すぎる",
|
|
@@ -8521,7 +8515,7 @@ const zh = {
|
|
|
8521
8515
|
"Virtual Try-On": "虚拟试穿",
|
|
8522
8516
|
"Find Your Size & See It On You": "找到你的尺码并试穿",
|
|
8523
8517
|
"See Your Fit": "查看合身效果",
|
|
8524
|
-
"
|
|
8518
|
+
"Check your size, then try it on virtually": "确认尺码,然后虚拟试穿",
|
|
8525
8519
|
"Get Your Size": "获取尺码",
|
|
8526
8520
|
"Instant fit recommendation": "即时合身推荐",
|
|
8527
8521
|
"Try It On": "试穿",
|
|
@@ -8556,8 +8550,9 @@ const zh = {
|
|
|
8556
8550
|
"Edit measurements": "编辑尺寸",
|
|
8557
8551
|
"Size guide": "尺码指南",
|
|
8558
8552
|
"Your fit": "你的合身度",
|
|
8553
|
+
"Your Size Recommendation": "你的尺码建议",
|
|
8559
8554
|
"Your measure": "你的尺寸",
|
|
8560
|
-
"
|
|
8555
|
+
"within range": "在范围内",
|
|
8561
8556
|
"too tight": "太紧",
|
|
8562
8557
|
"tight": "偏紧",
|
|
8563
8558
|
"a bit tight": "略紧",
|
|
@@ -8660,8 +8655,6 @@ const zh = {
|
|
|
8660
8655
|
"Loose": "松",
|
|
8661
8656
|
"Short": "短",
|
|
8662
8657
|
"Long": "长",
|
|
8663
|
-
"Perfect": "完美",
|
|
8664
|
-
"Perfect fit": "完美合身",
|
|
8665
8658
|
"✓ Fit": "✓ 合身",
|
|
8666
8659
|
"too short": "太短",
|
|
8667
8660
|
"too long": "太长",
|
|
@@ -8778,7 +8771,7 @@ const ko = {
|
|
|
8778
8771
|
"Virtual Try-On": "가상 피팅",
|
|
8779
8772
|
"Find Your Size & See It On You": "사이즈를 찾고 입어보세요",
|
|
8780
8773
|
"See Your Fit": "핏 확인하기",
|
|
8781
|
-
"
|
|
8774
|
+
"Check your size, then try it on virtually": "사이즈를 확인하고 가상으로 입어보세요",
|
|
8782
8775
|
"Get Your Size": "사이즈 확인",
|
|
8783
8776
|
"Instant fit recommendation": "즉시 핏 추천",
|
|
8784
8777
|
"Try It On": "입어보기",
|
|
@@ -8813,8 +8806,9 @@ const ko = {
|
|
|
8813
8806
|
"Edit measurements": "치수 수정",
|
|
8814
8807
|
"Size guide": "사이즈 가이드",
|
|
8815
8808
|
"Your fit": "나의 핏",
|
|
8809
|
+
"Your Size Recommendation": "사이즈 추천",
|
|
8816
8810
|
"Your measure": "내 치수",
|
|
8817
|
-
"
|
|
8811
|
+
"within range": "범위 내",
|
|
8818
8812
|
"too tight": "너무 타이트",
|
|
8819
8813
|
"tight": "타이트",
|
|
8820
8814
|
"a bit tight": "약간 타이트",
|
|
@@ -8917,8 +8911,6 @@ const ko = {
|
|
|
8917
8911
|
"Loose": "헐렁한",
|
|
8918
8912
|
"Short": "짧은",
|
|
8919
8913
|
"Long": "긴",
|
|
8920
|
-
"Perfect": "완벽",
|
|
8921
|
-
"Perfect fit": "완벽한 핏",
|
|
8922
8914
|
"✓ Fit": "✓ 적합",
|
|
8923
8915
|
"too short": "너무 짧음",
|
|
8924
8916
|
"too long": "너무 김",
|
|
@@ -9035,7 +9027,7 @@ const ar = {
|
|
|
9035
9027
|
"Virtual Try-On": "تجربة افتراضية",
|
|
9036
9028
|
"Find Your Size & See It On You": "اعثر على مقاسك وجرّبه",
|
|
9037
9029
|
"See Your Fit": "شاهد الملاءمة",
|
|
9038
|
-
"
|
|
9030
|
+
"Check your size, then try it on virtually": "تحقق من مقاسك ثم جرّبه افتراضياً",
|
|
9039
9031
|
"Get Your Size": "مقاسك",
|
|
9040
9032
|
"Instant fit recommendation": "توصية فورية بالمقاس",
|
|
9041
9033
|
"Try It On": "جرّبه",
|
|
@@ -9070,8 +9062,9 @@ const ar = {
|
|
|
9070
9062
|
"Edit measurements": "تعديل القياسات",
|
|
9071
9063
|
"Size guide": "دليل المقاسات",
|
|
9072
9064
|
"Your fit": "ملاءمتك",
|
|
9065
|
+
"Your Size Recommendation": "توصية المقاس",
|
|
9073
9066
|
"Your measure": "قياسك",
|
|
9074
|
-
"
|
|
9067
|
+
"within range": "ضمن النطاق",
|
|
9075
9068
|
"too tight": "ضيق جداً",
|
|
9076
9069
|
"tight": "ضيق",
|
|
9077
9070
|
"a bit tight": "ضيق قليلاً",
|
|
@@ -9174,8 +9167,6 @@ const ar = {
|
|
|
9174
9167
|
"Loose": "فضفاض",
|
|
9175
9168
|
"Short": "قصير",
|
|
9176
9169
|
"Long": "طويل",
|
|
9177
|
-
"Perfect": "مثالي",
|
|
9178
|
-
"Perfect fit": "مقاس مثالي",
|
|
9179
9170
|
"✓ Fit": "✓ مناسب",
|
|
9180
9171
|
"too short": "قصير جداً",
|
|
9181
9172
|
"too long": "طويل جداً",
|
|
@@ -9465,16 +9456,20 @@ class ApiClient {
|
|
|
9465
9456
|
if (category && category !== "apparel") body.category = category;
|
|
9466
9457
|
if (context?.productId) body.productId = context.productId;
|
|
9467
9458
|
if (context?.productTitle) body.productTitle = context.productTitle;
|
|
9459
|
+
if (context?.productCategory) body.productCategory = context.productCategory;
|
|
9460
|
+
if (context?.productSubcategory) body.productSubcategory = context.productSubcategory;
|
|
9468
9461
|
if (context?.productFitType) body.productFitType = context.productFitType;
|
|
9469
9462
|
if (context?.productType) body.productType = context.productType;
|
|
9470
9463
|
if (context?.productTags?.length) body.productTags = context.productTags;
|
|
9471
9464
|
if (context?.productDescription) body.productDescription = context.productDescription;
|
|
9472
9465
|
if (context?.productMaterial) body.productMaterial = context.productMaterial;
|
|
9466
|
+
if (context?.garmentDetailImage && context.garmentDetailImage !== garmentImage) body.garmentDetailImage = context.garmentDetailImage;
|
|
9473
9467
|
if (context?.silhouetteContext) body.silhouetteContext = context.silhouetteContext;
|
|
9474
9468
|
if (context?.editFromPrevious) body.editFromPrevious = true;
|
|
9475
9469
|
console.log("[ps-sdk:api] POST /api/v1/tryon payload", {
|
|
9476
9470
|
modelImageBytes: modelImage.length,
|
|
9477
9471
|
garmentImageBytes: garmentImage.length,
|
|
9472
|
+
garmentDetailImageSet: !!body.garmentDetailImage,
|
|
9478
9473
|
category: category || "apparel",
|
|
9479
9474
|
fitInfo: fitInfo?.map((f2) => ({
|
|
9480
9475
|
area: f2.area,
|
|
@@ -10280,6 +10275,9 @@ function formatUserMeasurementValue(measurement, value) {
|
|
|
10280
10275
|
if (!isUnitlessShoeSizeMeasurement(measurement)) return value;
|
|
10281
10276
|
return value.replace(/\s*(cm|mm|in|inch|inches)\b/ig, "").trim();
|
|
10282
10277
|
}
|
|
10278
|
+
function normalizePromptSizeLabel(size) {
|
|
10279
|
+
return String(size || "").trim().replace(/\s+[–—-]\s+(?:UK|US|EU|IT|FR|DE|ES|JP|CN|KR|AU|BR)\s+.+$/i, "").replace(/\s*\((?:UK|US|EU|IT|FR|DE|ES|JP|CN|KR|AU|BR)\s+[^)]*\)\s*$/i, "").trim();
|
|
10280
|
+
}
|
|
10283
10281
|
function computeFit(userValue, chartRange, unit) {
|
|
10284
10282
|
const targetUnit = normalizeUnit(unit) || detectUnitFromText(chartRange) || "in";
|
|
10285
10283
|
const chartUnit = detectUnitFromText(chartRange);
|
|
@@ -10340,7 +10338,7 @@ function buildSilhouetteContext(sizingResult, sizeGuide, selectedSizeOverride, u
|
|
|
10340
10338
|
if (!sizingResult && !sizeGuide && !userHeight && !userWeight) return void 0;
|
|
10341
10339
|
const out = {};
|
|
10342
10340
|
const promptUnit = normalizeUnit(sizingResult?.unit) || detectUnitFromText(sizingResult?.matchDetails?.[0]?.userValue) || detectUnitFromText(Object.values(sizingResult?.sections || {})[0]?.matchDetails?.[0]?.userValue) || "in";
|
|
10343
|
-
const baseSize = (selectedSizeOverride || sizingResult?.recommendedSize || "")
|
|
10341
|
+
const baseSize = normalizePromptSizeLabel(selectedSizeOverride || sizingResult?.recommendedSize || "");
|
|
10344
10342
|
if (userHeight) out.userHeight = userHeight;
|
|
10345
10343
|
if (userWeight) out.userWeight = userWeight;
|
|
10346
10344
|
let chartRowLength = null;
|
|
@@ -10390,7 +10388,7 @@ function buildSilhouetteContext(sizingResult, sizeGuide, selectedSizeOverride, u
|
|
|
10390
10388
|
const labelParts = [];
|
|
10391
10389
|
const measurementParts = [];
|
|
10392
10390
|
for (const [secName, secResult] of sectionEntries) {
|
|
10393
|
-
const secSize = (secResult?.recommendedSize ?? "")
|
|
10391
|
+
const secSize = normalizePromptSizeLabel(secResult?.recommendedSize ?? "");
|
|
10394
10392
|
if (!secSize) continue;
|
|
10395
10393
|
const cleanSec = /\bsize\s*$/i.test(secName) ? secName.replace(/\s*\bsize\s*$/i, "").trim() : secName;
|
|
10396
10394
|
labelParts.push(`${cleanSec} ${secSize}`);
|
|
@@ -10496,6 +10494,24 @@ function lsSet(key, value) {
|
|
|
10496
10494
|
} catch {
|
|
10497
10495
|
}
|
|
10498
10496
|
}
|
|
10497
|
+
function lsRemove(key) {
|
|
10498
|
+
try {
|
|
10499
|
+
localStorage.removeItem(LS_PREFIX + key);
|
|
10500
|
+
} catch {
|
|
10501
|
+
}
|
|
10502
|
+
}
|
|
10503
|
+
function clearProfileLocalStorage() {
|
|
10504
|
+
lsRemove(PROFILES_KEY);
|
|
10505
|
+
lsRemove(ACTIVE_PROFILE_KEY);
|
|
10506
|
+
lsRemove("profile_completion_draft");
|
|
10507
|
+
try {
|
|
10508
|
+
localStorage.removeItem(PROFILES_KEY);
|
|
10509
|
+
localStorage.removeItem(ACTIVE_PROFILE_KEY);
|
|
10510
|
+
localStorage.removeItem("profile_completion_draft");
|
|
10511
|
+
} catch {
|
|
10512
|
+
}
|
|
10513
|
+
emitStorageChange("profile-clear");
|
|
10514
|
+
}
|
|
10499
10515
|
function getProfiles() {
|
|
10500
10516
|
return lsGet(PROFILES_KEY, []);
|
|
10501
10517
|
}
|
|
@@ -10510,19 +10526,6 @@ function setActiveProfileId(id2) {
|
|
|
10510
10526
|
lsSet(ACTIVE_PROFILE_KEY, id2);
|
|
10511
10527
|
emitStorageChange("active-profile");
|
|
10512
10528
|
}
|
|
10513
|
-
function getActiveProfile() {
|
|
10514
|
-
const profiles = getProfiles();
|
|
10515
|
-
if (profiles.length === 0) return null;
|
|
10516
|
-
const activeId = getActiveProfileId();
|
|
10517
|
-
if (activeId) {
|
|
10518
|
-
const found = profiles.find((p2) => p2.id === activeId);
|
|
10519
|
-
if (found) return found;
|
|
10520
|
-
}
|
|
10521
|
-
const sorted = [...profiles].sort(
|
|
10522
|
-
(a, b) => (b.lastUsedAt || b.createdAt || 0) - (a.lastUsedAt || a.createdAt || 0)
|
|
10523
|
-
);
|
|
10524
|
-
return sorted[0] || null;
|
|
10525
|
-
}
|
|
10526
10529
|
function updateProfile(id2, patch) {
|
|
10527
10530
|
const profiles = getProfiles();
|
|
10528
10531
|
const idx = profiles.findIndex((p2) => p2.id === id2);
|
|
@@ -10937,6 +10940,188 @@ function getApiUrl(override) {
|
|
|
10937
10940
|
}
|
|
10938
10941
|
return envUrl || "http://localhost:4000";
|
|
10939
10942
|
}
|
|
10943
|
+
const SESSION_KEY = "primestyle_profile_session";
|
|
10944
|
+
const AUTH_MESSAGE_TYPE = "PRIMESTYLE_SDK_AUTH";
|
|
10945
|
+
const POPUP_TIMEOUT_MS = 12e4;
|
|
10946
|
+
const POLL_INTERVAL_MS = 900;
|
|
10947
|
+
function emitProfileAuthChange(reason) {
|
|
10948
|
+
if (typeof window === "undefined") return;
|
|
10949
|
+
try {
|
|
10950
|
+
window.dispatchEvent(new CustomEvent(PS_STORAGE_CHANGE_EVENT, { detail: { reason } }));
|
|
10951
|
+
} catch {
|
|
10952
|
+
}
|
|
10953
|
+
}
|
|
10954
|
+
function isTrustedAuthOrigin(eventOrigin, expectedOrigin) {
|
|
10955
|
+
if (eventOrigin === expectedOrigin) return true;
|
|
10956
|
+
try {
|
|
10957
|
+
const host = new URL(eventOrigin).hostname;
|
|
10958
|
+
return host === "localhost" || host === "127.0.0.1" || host.endsWith(".primestyleai.com") || host.endsWith(".myaifitting.com");
|
|
10959
|
+
} catch {
|
|
10960
|
+
return false;
|
|
10961
|
+
}
|
|
10962
|
+
}
|
|
10963
|
+
function readStorage() {
|
|
10964
|
+
if (typeof window === "undefined") return null;
|
|
10965
|
+
try {
|
|
10966
|
+
return window.localStorage;
|
|
10967
|
+
} catch {
|
|
10968
|
+
return null;
|
|
10969
|
+
}
|
|
10970
|
+
}
|
|
10971
|
+
function createAuthRequestId() {
|
|
10972
|
+
try {
|
|
10973
|
+
const randomId = window.crypto?.randomUUID?.();
|
|
10974
|
+
if (randomId) return randomId;
|
|
10975
|
+
} catch {
|
|
10976
|
+
}
|
|
10977
|
+
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
10978
|
+
}
|
|
10979
|
+
async function readAuthStatus(statusUrl) {
|
|
10980
|
+
const response = await fetch(statusUrl.toString(), {
|
|
10981
|
+
method: "GET",
|
|
10982
|
+
credentials: "omit",
|
|
10983
|
+
cache: "no-store"
|
|
10984
|
+
});
|
|
10985
|
+
if (!response.ok) return null;
|
|
10986
|
+
const data = await response.json();
|
|
10987
|
+
return data.status === "done" ? data : null;
|
|
10988
|
+
}
|
|
10989
|
+
function getStoredProfileSession() {
|
|
10990
|
+
const storage = readStorage();
|
|
10991
|
+
if (!storage) return null;
|
|
10992
|
+
try {
|
|
10993
|
+
const raw = storage.getItem(SESSION_KEY);
|
|
10994
|
+
if (!raw) return null;
|
|
10995
|
+
const parsed = JSON.parse(raw);
|
|
10996
|
+
return parsed?.accessToken ? parsed : null;
|
|
10997
|
+
} catch {
|
|
10998
|
+
return null;
|
|
10999
|
+
}
|
|
11000
|
+
}
|
|
11001
|
+
function setStoredProfileSession(session) {
|
|
11002
|
+
const storage = readStorage();
|
|
11003
|
+
if (!storage) return;
|
|
11004
|
+
try {
|
|
11005
|
+
storage.setItem(SESSION_KEY, JSON.stringify(session));
|
|
11006
|
+
emitProfileAuthChange("profile-auth-set");
|
|
11007
|
+
} catch {
|
|
11008
|
+
}
|
|
11009
|
+
}
|
|
11010
|
+
function clearStoredProfileSession() {
|
|
11011
|
+
const storage = readStorage();
|
|
11012
|
+
if (!storage) return;
|
|
11013
|
+
try {
|
|
11014
|
+
storage.removeItem(SESSION_KEY);
|
|
11015
|
+
emitProfileAuthChange("profile-auth-clear");
|
|
11016
|
+
} catch {
|
|
11017
|
+
}
|
|
11018
|
+
}
|
|
11019
|
+
function startSocialProfileLogin(provider, apiUrl) {
|
|
11020
|
+
if (typeof window === "undefined") {
|
|
11021
|
+
return Promise.reject(new Error("Social login must run in the browser."));
|
|
11022
|
+
}
|
|
11023
|
+
const baseUrl = getApiUrl(apiUrl);
|
|
11024
|
+
const backendOrigin = new URL(baseUrl).origin;
|
|
11025
|
+
const authRequestId = createAuthRequestId();
|
|
11026
|
+
const startUrl = new URL(`${baseUrl.replace(/\/$/, "")}/api/sdk/v1/auth/${provider}/start`);
|
|
11027
|
+
startUrl.searchParams.set("origin", window.location.origin);
|
|
11028
|
+
startUrl.searchParams.set("requestId", authRequestId);
|
|
11029
|
+
const statusUrl = new URL(`${baseUrl.replace(/\/$/, "")}/api/sdk/v1/auth/${provider}/status`);
|
|
11030
|
+
statusUrl.searchParams.set("origin", window.location.origin);
|
|
11031
|
+
statusUrl.searchParams.set("requestId", authRequestId);
|
|
11032
|
+
const popup = window.open(
|
|
11033
|
+
startUrl.toString(),
|
|
11034
|
+
"primestyle-profile-login",
|
|
11035
|
+
"width=520,height=720"
|
|
11036
|
+
);
|
|
11037
|
+
if (!popup) {
|
|
11038
|
+
return Promise.reject(new Error("Popup was blocked. Please allow popups and try again."));
|
|
11039
|
+
}
|
|
11040
|
+
return new Promise((resolve, reject) => {
|
|
11041
|
+
let settled = false;
|
|
11042
|
+
const cleanup = () => {
|
|
11043
|
+
window.removeEventListener("message", onMessage);
|
|
11044
|
+
window.clearInterval(statusTimer);
|
|
11045
|
+
window.clearTimeout(timeout);
|
|
11046
|
+
};
|
|
11047
|
+
const finish = (fn) => {
|
|
11048
|
+
if (settled) return;
|
|
11049
|
+
settled = true;
|
|
11050
|
+
cleanup();
|
|
11051
|
+
fn();
|
|
11052
|
+
};
|
|
11053
|
+
const onMessage = (event) => {
|
|
11054
|
+
if (!isTrustedAuthOrigin(event.origin, backendOrigin)) return;
|
|
11055
|
+
const data = event.data;
|
|
11056
|
+
if (!data || data.type !== AUTH_MESSAGE_TYPE) return;
|
|
11057
|
+
if (!data.ok || !data.accessToken) {
|
|
11058
|
+
finish(() => reject(new Error(data.error || "Social login failed.")));
|
|
11059
|
+
return;
|
|
11060
|
+
}
|
|
11061
|
+
finish(() => resolve({
|
|
11062
|
+
accessToken: data.accessToken,
|
|
11063
|
+
isNewUser: Boolean(data.isNewUser),
|
|
11064
|
+
signedInAt: Date.now()
|
|
11065
|
+
}));
|
|
11066
|
+
};
|
|
11067
|
+
const handleAuthPayload = (data) => {
|
|
11068
|
+
if (!data.ok || !data.accessToken) {
|
|
11069
|
+
finish(() => reject(new Error(data.error || "Social login failed.")));
|
|
11070
|
+
return;
|
|
11071
|
+
}
|
|
11072
|
+
finish(() => resolve({
|
|
11073
|
+
accessToken: data.accessToken,
|
|
11074
|
+
isNewUser: Boolean(data.isNewUser),
|
|
11075
|
+
signedInAt: Date.now()
|
|
11076
|
+
}));
|
|
11077
|
+
};
|
|
11078
|
+
const statusTimer = window.setInterval(() => {
|
|
11079
|
+
readAuthStatus(statusUrl).then((data) => {
|
|
11080
|
+
if (data) handleAuthPayload(data);
|
|
11081
|
+
}).catch(() => {
|
|
11082
|
+
});
|
|
11083
|
+
}, POLL_INTERVAL_MS);
|
|
11084
|
+
const timeout = window.setTimeout(() => {
|
|
11085
|
+
finish(() => reject(new Error("Login did not finish. Please close the sign-in window and try again.")));
|
|
11086
|
+
}, POPUP_TIMEOUT_MS);
|
|
11087
|
+
window.addEventListener("message", onMessage);
|
|
11088
|
+
});
|
|
11089
|
+
}
|
|
11090
|
+
function endpoint(apiUrl) {
|
|
11091
|
+
return `${getApiUrl(apiUrl).replace(/\/$/, "")}/api/sdk/v1/profiles`;
|
|
11092
|
+
}
|
|
11093
|
+
function normalizeStore(data) {
|
|
11094
|
+
return {
|
|
11095
|
+
profiles: Array.isArray(data.profiles) ? data.profiles : [],
|
|
11096
|
+
activeProfileId: data.activeProfileId ?? null
|
|
11097
|
+
};
|
|
11098
|
+
}
|
|
11099
|
+
async function parseResponse(response) {
|
|
11100
|
+
const data = await response.json().catch(() => ({}));
|
|
11101
|
+
if (!response.ok) {
|
|
11102
|
+
const message = typeof data.message === "string" ? data.message : "Profile sync failed.";
|
|
11103
|
+
throw new Error(message);
|
|
11104
|
+
}
|
|
11105
|
+
return data;
|
|
11106
|
+
}
|
|
11107
|
+
async function fetchRemoteProfiles(apiUrl, accessToken) {
|
|
11108
|
+
const response = await fetch(endpoint(apiUrl), {
|
|
11109
|
+
method: "GET",
|
|
11110
|
+
headers: { Authorization: `Bearer ${accessToken}` }
|
|
11111
|
+
});
|
|
11112
|
+
return normalizeStore(await parseResponse(response));
|
|
11113
|
+
}
|
|
11114
|
+
async function saveRemoteProfiles(apiUrl, accessToken, profiles, activeProfileId) {
|
|
11115
|
+
const response = await fetch(endpoint(apiUrl), {
|
|
11116
|
+
method: "PUT",
|
|
11117
|
+
headers: {
|
|
11118
|
+
Authorization: `Bearer ${accessToken}`,
|
|
11119
|
+
"Content-Type": "application/json"
|
|
11120
|
+
},
|
|
11121
|
+
body: JSON.stringify({ profiles, activeProfileId })
|
|
11122
|
+
});
|
|
11123
|
+
return normalizeStore(await parseResponse(response));
|
|
11124
|
+
}
|
|
10940
11125
|
let cachedMP = null;
|
|
10941
11126
|
const MP_CACHE_TTL_MS = 6e4;
|
|
10942
11127
|
function setCachedMediaPipe(landmarks) {
|
|
@@ -10962,9 +11147,26 @@ async function recommendForProduct(input) {
|
|
|
10962
11147
|
const t0 = Date.now();
|
|
10963
11148
|
log("ENTER", { productId: input.productId, apiUrl: input.apiUrl, skipCache: !!input.skipCache });
|
|
10964
11149
|
const sessionId = getOrCreateSessionId();
|
|
10965
|
-
const
|
|
11150
|
+
const apiKey = input.apiKey ?? getApiKey();
|
|
11151
|
+
const apiUrl = (input.apiUrl ?? getApiUrl()).replace(/\/+$/, "");
|
|
11152
|
+
const session = getStoredProfileSession();
|
|
11153
|
+
if (!session) {
|
|
11154
|
+
log("no signed-in profile session — returning null");
|
|
11155
|
+
return null;
|
|
11156
|
+
}
|
|
11157
|
+
let remoteProfiles = [];
|
|
11158
|
+
let activeProfileId = null;
|
|
11159
|
+
try {
|
|
11160
|
+
const remoteStore = await fetchRemoteProfiles(apiUrl, session.accessToken);
|
|
11161
|
+
remoteProfiles = remoteStore.profiles;
|
|
11162
|
+
activeProfileId = remoteStore.activeProfileId;
|
|
11163
|
+
} catch (error) {
|
|
11164
|
+
log("remote profile fetch failed — returning null", error);
|
|
11165
|
+
return null;
|
|
11166
|
+
}
|
|
11167
|
+
const profile = input.profile && input.profile.id === activeProfileId ? input.profile : activeProfileId ? remoteProfiles.find((p2) => p2.id === activeProfileId) ?? null : null;
|
|
10966
11168
|
if (!profile) {
|
|
10967
|
-
log("no
|
|
11169
|
+
log("no selected backend profile — returning null");
|
|
10968
11170
|
return null;
|
|
10969
11171
|
}
|
|
10970
11172
|
log("profile resolved", {
|
|
@@ -11017,8 +11219,6 @@ async function recommendForProduct(input) {
|
|
|
11017
11219
|
}
|
|
11018
11220
|
}
|
|
11019
11221
|
log(`cache MISS — calling backend (elapsed in pre-flight: ${Date.now() - t0}ms)`);
|
|
11020
|
-
const apiKey = input.apiKey ?? getApiKey();
|
|
11021
|
-
const apiUrl = (input.apiUrl ?? getApiUrl()).replace(/\/+$/, "");
|
|
11022
11222
|
let sizeGuide = null;
|
|
11023
11223
|
if (input.sizeGuideData != null) {
|
|
11024
11224
|
const tSg = Date.now();
|
|
@@ -11063,6 +11263,34 @@ async function recommendForProduct(input) {
|
|
|
11063
11263
|
if (value != null) measurements[key] = value;
|
|
11064
11264
|
}
|
|
11065
11265
|
}
|
|
11266
|
+
const legacyKnownMeasurements = {};
|
|
11267
|
+
for (const key of [
|
|
11268
|
+
"chest",
|
|
11269
|
+
"bust",
|
|
11270
|
+
"waist",
|
|
11271
|
+
"hips",
|
|
11272
|
+
"shoulderWidth",
|
|
11273
|
+
"sleeveLength",
|
|
11274
|
+
"inseam",
|
|
11275
|
+
"neckCircumference",
|
|
11276
|
+
"thighCircumference",
|
|
11277
|
+
"wristCircumference",
|
|
11278
|
+
"footLengthCm"
|
|
11279
|
+
]) {
|
|
11280
|
+
const value = profile[key];
|
|
11281
|
+
if (typeof value === "number" && value > 0) {
|
|
11282
|
+
measurements[key] = value;
|
|
11283
|
+
legacyKnownMeasurements[key] = value;
|
|
11284
|
+
}
|
|
11285
|
+
}
|
|
11286
|
+
if (profile.customMeasurements) {
|
|
11287
|
+
for (const [key, value] of Object.entries(profile.customMeasurements)) {
|
|
11288
|
+
if (typeof value === "number" && value > 0) {
|
|
11289
|
+
measurements[key] = value;
|
|
11290
|
+
legacyKnownMeasurements[key] = value;
|
|
11291
|
+
}
|
|
11292
|
+
}
|
|
11293
|
+
}
|
|
11066
11294
|
if (profile.height != null) measurements.height = profile.height;
|
|
11067
11295
|
if (profile.weight != null) measurements.weight = profile.weight;
|
|
11068
11296
|
if (profile.heightUnit) measurements.heightUnit = profile.heightUnit;
|
|
@@ -11099,6 +11327,8 @@ async function recommendForProduct(input) {
|
|
|
11099
11327
|
}
|
|
11100
11328
|
if (profile.knownMeasurements) {
|
|
11101
11329
|
payload.knownMeasurements = profile.knownMeasurements;
|
|
11330
|
+
} else if (Object.keys(legacyKnownMeasurements).length > 0) {
|
|
11331
|
+
payload.knownMeasurements = legacyKnownMeasurements;
|
|
11102
11332
|
}
|
|
11103
11333
|
if (sizeGuide && sizeGuide.found) {
|
|
11104
11334
|
payload.sizeGuide = sizeGuide;
|
|
@@ -11146,7 +11376,7 @@ async function recommendForProduct(input) {
|
|
|
11146
11376
|
}
|
|
11147
11377
|
])
|
|
11148
11378
|
) : void 0;
|
|
11149
|
-
|
|
11379
|
+
const newHistoryEntry = {
|
|
11150
11380
|
productId: input.productId,
|
|
11151
11381
|
productTitle: input.productTitle,
|
|
11152
11382
|
productImage: input.productImage,
|
|
@@ -11156,6 +11386,15 @@ async function recommendForProduct(input) {
|
|
|
11156
11386
|
sectionsFull,
|
|
11157
11387
|
recommendedLength: result.recommendedLength || void 0,
|
|
11158
11388
|
savedAt: Date.now()
|
|
11389
|
+
};
|
|
11390
|
+
const updatedProfiles = remoteProfiles.map((p2) => {
|
|
11391
|
+
if (p2.id !== profile.id) return p2;
|
|
11392
|
+
const history = (p2.sizeHistory || []).filter((h) => h.productId !== input.productId);
|
|
11393
|
+
history.unshift(newHistoryEntry);
|
|
11394
|
+
return { ...p2, sizeHistory: history.slice(0, 50), lastUsedAt: Date.now() };
|
|
11395
|
+
});
|
|
11396
|
+
void saveRemoteProfiles(apiUrl, session.accessToken, updatedProfiles, activeProfileId).catch((error) => {
|
|
11397
|
+
log("remote size-history save failed", error);
|
|
11159
11398
|
});
|
|
11160
11399
|
setLastSizeSelection({
|
|
11161
11400
|
productId: input.productId,
|
|
@@ -11345,179 +11584,6 @@ async function pickBestGarmentImage(images) {
|
|
|
11345
11584
|
for (const s of scored) console.log(`[ps-sdk:garment-pick] ${s.score.toString().padStart(4, " ")} ${s.url}`);
|
|
11346
11585
|
return best;
|
|
11347
11586
|
}
|
|
11348
|
-
const SESSION_KEY = "primestyle_profile_session";
|
|
11349
|
-
const AUTH_MESSAGE_TYPE = "PRIMESTYLE_SDK_AUTH";
|
|
11350
|
-
const POPUP_TIMEOUT_MS = 12e4;
|
|
11351
|
-
const POLL_INTERVAL_MS = 900;
|
|
11352
|
-
function isTrustedAuthOrigin(eventOrigin, expectedOrigin) {
|
|
11353
|
-
if (eventOrigin === expectedOrigin) return true;
|
|
11354
|
-
try {
|
|
11355
|
-
const host = new URL(eventOrigin).hostname;
|
|
11356
|
-
return host === "localhost" || host === "127.0.0.1" || host.endsWith(".primestyleai.com") || host.endsWith(".myaifitting.com");
|
|
11357
|
-
} catch {
|
|
11358
|
-
return false;
|
|
11359
|
-
}
|
|
11360
|
-
}
|
|
11361
|
-
function readStorage() {
|
|
11362
|
-
if (typeof window === "undefined") return null;
|
|
11363
|
-
try {
|
|
11364
|
-
return window.localStorage;
|
|
11365
|
-
} catch {
|
|
11366
|
-
return null;
|
|
11367
|
-
}
|
|
11368
|
-
}
|
|
11369
|
-
function createAuthRequestId() {
|
|
11370
|
-
try {
|
|
11371
|
-
const randomId = window.crypto?.randomUUID?.();
|
|
11372
|
-
if (randomId) return randomId;
|
|
11373
|
-
} catch {
|
|
11374
|
-
}
|
|
11375
|
-
return `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 12)}`;
|
|
11376
|
-
}
|
|
11377
|
-
async function readAuthStatus(statusUrl) {
|
|
11378
|
-
const response = await fetch(statusUrl.toString(), {
|
|
11379
|
-
method: "GET",
|
|
11380
|
-
credentials: "omit",
|
|
11381
|
-
cache: "no-store"
|
|
11382
|
-
});
|
|
11383
|
-
if (!response.ok) return null;
|
|
11384
|
-
const data = await response.json();
|
|
11385
|
-
return data.status === "done" ? data : null;
|
|
11386
|
-
}
|
|
11387
|
-
function getStoredProfileSession() {
|
|
11388
|
-
const storage = readStorage();
|
|
11389
|
-
if (!storage) return null;
|
|
11390
|
-
try {
|
|
11391
|
-
const raw = storage.getItem(SESSION_KEY);
|
|
11392
|
-
if (!raw) return null;
|
|
11393
|
-
const parsed = JSON.parse(raw);
|
|
11394
|
-
return parsed?.accessToken ? parsed : null;
|
|
11395
|
-
} catch {
|
|
11396
|
-
return null;
|
|
11397
|
-
}
|
|
11398
|
-
}
|
|
11399
|
-
function setStoredProfileSession(session) {
|
|
11400
|
-
const storage = readStorage();
|
|
11401
|
-
if (!storage) return;
|
|
11402
|
-
try {
|
|
11403
|
-
storage.setItem(SESSION_KEY, JSON.stringify(session));
|
|
11404
|
-
} catch {
|
|
11405
|
-
}
|
|
11406
|
-
}
|
|
11407
|
-
function clearStoredProfileSession() {
|
|
11408
|
-
const storage = readStorage();
|
|
11409
|
-
if (!storage) return;
|
|
11410
|
-
try {
|
|
11411
|
-
storage.removeItem(SESSION_KEY);
|
|
11412
|
-
} catch {
|
|
11413
|
-
}
|
|
11414
|
-
}
|
|
11415
|
-
function startSocialProfileLogin(provider, apiUrl) {
|
|
11416
|
-
if (typeof window === "undefined") {
|
|
11417
|
-
return Promise.reject(new Error("Social login must run in the browser."));
|
|
11418
|
-
}
|
|
11419
|
-
const baseUrl = getApiUrl(apiUrl);
|
|
11420
|
-
const backendOrigin = new URL(baseUrl).origin;
|
|
11421
|
-
const authRequestId = createAuthRequestId();
|
|
11422
|
-
const startUrl = new URL(`${baseUrl.replace(/\/$/, "")}/api/sdk/v1/auth/${provider}/start`);
|
|
11423
|
-
startUrl.searchParams.set("origin", window.location.origin);
|
|
11424
|
-
startUrl.searchParams.set("requestId", authRequestId);
|
|
11425
|
-
const statusUrl = new URL(`${baseUrl.replace(/\/$/, "")}/api/sdk/v1/auth/${provider}/status`);
|
|
11426
|
-
statusUrl.searchParams.set("origin", window.location.origin);
|
|
11427
|
-
statusUrl.searchParams.set("requestId", authRequestId);
|
|
11428
|
-
const popup = window.open(
|
|
11429
|
-
startUrl.toString(),
|
|
11430
|
-
"primestyle-profile-login",
|
|
11431
|
-
"width=520,height=720"
|
|
11432
|
-
);
|
|
11433
|
-
if (!popup) {
|
|
11434
|
-
return Promise.reject(new Error("Popup was blocked. Please allow popups and try again."));
|
|
11435
|
-
}
|
|
11436
|
-
return new Promise((resolve, reject) => {
|
|
11437
|
-
let settled = false;
|
|
11438
|
-
const cleanup = () => {
|
|
11439
|
-
window.removeEventListener("message", onMessage);
|
|
11440
|
-
window.clearInterval(statusTimer);
|
|
11441
|
-
window.clearTimeout(timeout);
|
|
11442
|
-
};
|
|
11443
|
-
const finish = (fn) => {
|
|
11444
|
-
if (settled) return;
|
|
11445
|
-
settled = true;
|
|
11446
|
-
cleanup();
|
|
11447
|
-
fn();
|
|
11448
|
-
};
|
|
11449
|
-
const onMessage = (event) => {
|
|
11450
|
-
if (!isTrustedAuthOrigin(event.origin, backendOrigin)) return;
|
|
11451
|
-
const data = event.data;
|
|
11452
|
-
if (!data || data.type !== AUTH_MESSAGE_TYPE) return;
|
|
11453
|
-
if (!data.ok || !data.accessToken) {
|
|
11454
|
-
finish(() => reject(new Error(data.error || "Social login failed.")));
|
|
11455
|
-
return;
|
|
11456
|
-
}
|
|
11457
|
-
finish(() => resolve({
|
|
11458
|
-
accessToken: data.accessToken,
|
|
11459
|
-
isNewUser: Boolean(data.isNewUser),
|
|
11460
|
-
signedInAt: Date.now()
|
|
11461
|
-
}));
|
|
11462
|
-
};
|
|
11463
|
-
const handleAuthPayload = (data) => {
|
|
11464
|
-
if (!data.ok || !data.accessToken) {
|
|
11465
|
-
finish(() => reject(new Error(data.error || "Social login failed.")));
|
|
11466
|
-
return;
|
|
11467
|
-
}
|
|
11468
|
-
finish(() => resolve({
|
|
11469
|
-
accessToken: data.accessToken,
|
|
11470
|
-
isNewUser: Boolean(data.isNewUser),
|
|
11471
|
-
signedInAt: Date.now()
|
|
11472
|
-
}));
|
|
11473
|
-
};
|
|
11474
|
-
const statusTimer = window.setInterval(() => {
|
|
11475
|
-
readAuthStatus(statusUrl).then((data) => {
|
|
11476
|
-
if (data) handleAuthPayload(data);
|
|
11477
|
-
}).catch(() => {
|
|
11478
|
-
});
|
|
11479
|
-
}, POLL_INTERVAL_MS);
|
|
11480
|
-
const timeout = window.setTimeout(() => {
|
|
11481
|
-
finish(() => reject(new Error("Login did not finish. Please close the sign-in window and try again.")));
|
|
11482
|
-
}, POPUP_TIMEOUT_MS);
|
|
11483
|
-
window.addEventListener("message", onMessage);
|
|
11484
|
-
});
|
|
11485
|
-
}
|
|
11486
|
-
function endpoint(apiUrl) {
|
|
11487
|
-
return `${getApiUrl(apiUrl).replace(/\/$/, "")}/api/sdk/v1/profiles`;
|
|
11488
|
-
}
|
|
11489
|
-
function normalizeStore(data) {
|
|
11490
|
-
return {
|
|
11491
|
-
profiles: Array.isArray(data.profiles) ? data.profiles : [],
|
|
11492
|
-
activeProfileId: data.activeProfileId ?? null
|
|
11493
|
-
};
|
|
11494
|
-
}
|
|
11495
|
-
async function parseResponse(response) {
|
|
11496
|
-
const data = await response.json().catch(() => ({}));
|
|
11497
|
-
if (!response.ok) {
|
|
11498
|
-
const message = typeof data.message === "string" ? data.message : "Profile sync failed.";
|
|
11499
|
-
throw new Error(message);
|
|
11500
|
-
}
|
|
11501
|
-
return data;
|
|
11502
|
-
}
|
|
11503
|
-
async function fetchRemoteProfiles(apiUrl, accessToken) {
|
|
11504
|
-
const response = await fetch(endpoint(apiUrl), {
|
|
11505
|
-
method: "GET",
|
|
11506
|
-
headers: { Authorization: `Bearer ${accessToken}` }
|
|
11507
|
-
});
|
|
11508
|
-
return normalizeStore(await parseResponse(response));
|
|
11509
|
-
}
|
|
11510
|
-
async function saveRemoteProfiles(apiUrl, accessToken, profiles, activeProfileId) {
|
|
11511
|
-
const response = await fetch(endpoint(apiUrl), {
|
|
11512
|
-
method: "PUT",
|
|
11513
|
-
headers: {
|
|
11514
|
-
Authorization: `Bearer ${accessToken}`,
|
|
11515
|
-
"Content-Type": "application/json"
|
|
11516
|
-
},
|
|
11517
|
-
body: JSON.stringify({ profiles, activeProfileId })
|
|
11518
|
-
});
|
|
11519
|
-
return normalizeStore(await parseResponse(response));
|
|
11520
|
-
}
|
|
11521
11587
|
function normalizeProfilePhotoSource(value) {
|
|
11522
11588
|
if (!value) return null;
|
|
11523
11589
|
if (/^https?:\/\//i.test(value)) return value;
|
|
@@ -12239,8 +12305,9 @@ const STYLES = `
|
|
|
12239
12305
|
align-self: stretch;
|
|
12240
12306
|
height: 100%;
|
|
12241
12307
|
justify-content: flex-start;
|
|
12242
|
-
gap: 0.
|
|
12243
|
-
padding-bottom: clamp(
|
|
12308
|
+
gap: clamp(8px, 0.48vw, 12px);
|
|
12309
|
+
padding-bottom: clamp(4px, 0.35vw, 8px);
|
|
12310
|
+
overflow: hidden;
|
|
12244
12311
|
}
|
|
12245
12312
|
.ps-tryon-v2-result-panel .ps-tryon-v2-sep {
|
|
12246
12313
|
margin-bottom: 0;
|
|
@@ -12250,16 +12317,17 @@ const STYLES = `
|
|
|
12250
12317
|
min-height: 0;
|
|
12251
12318
|
}
|
|
12252
12319
|
.ps-tryon-v2-result-panel .ps-tryon-photo-strip {
|
|
12253
|
-
flex:
|
|
12320
|
+
flex: 1 1 auto;
|
|
12254
12321
|
min-height: 0;
|
|
12255
|
-
margin-top: clamp(
|
|
12256
|
-
margin-bottom: clamp(
|
|
12322
|
+
margin-top: clamp(18px, 1.25vw, 26px);
|
|
12323
|
+
margin-bottom: clamp(4px, 0.35vw, 8px);
|
|
12324
|
+
overflow: hidden;
|
|
12257
12325
|
}
|
|
12258
12326
|
.ps-tryon-v2-result-panel .ps-tryon-sr-card-v2 {
|
|
12259
|
-
min-height: clamp(
|
|
12327
|
+
min-height: clamp(118px, 8.6vw, 142px);
|
|
12260
12328
|
}
|
|
12261
12329
|
.ps-tryon-v2-result-panel .ps-tryon-sr-card-v2.ps-full {
|
|
12262
|
-
min-height: clamp(
|
|
12330
|
+
min-height: clamp(118px, 8.6vw, 142px);
|
|
12263
12331
|
}
|
|
12264
12332
|
.ps-tryon-v2-result-panel .ps-tryon-photo-strip-cell {
|
|
12265
12333
|
aspect-ratio: 1 / 1;
|
|
@@ -12270,10 +12338,33 @@ const STYLES = `
|
|
|
12270
12338
|
align-items: center;
|
|
12271
12339
|
justify-content: space-between;
|
|
12272
12340
|
margin-top: auto;
|
|
12273
|
-
padding-top: clamp(
|
|
12274
|
-
padding-bottom: 0;
|
|
12341
|
+
padding-top: clamp(6px, 0.45vw, 10px);
|
|
12342
|
+
padding-bottom: clamp(2px, 0.25vw, 6px);
|
|
12275
12343
|
gap: 0.5vw;
|
|
12276
12344
|
flex-shrink: 0;
|
|
12345
|
+
width: 100%;
|
|
12346
|
+
min-height: clamp(42px, 3.1vw, 52px);
|
|
12347
|
+
box-sizing: border-box;
|
|
12348
|
+
border-top: 1px solid rgba(15,23,42,0.06);
|
|
12349
|
+
}
|
|
12350
|
+
.ps-tryon-v2-result-actions > .ps-tryon-v2-action-group {
|
|
12351
|
+
flex: 0 1 min(26vw, 390px);
|
|
12352
|
+
min-width: 0;
|
|
12353
|
+
max-width: min(100%, 390px);
|
|
12354
|
+
margin-left: auto;
|
|
12355
|
+
}
|
|
12356
|
+
.ps-tryon-v2-result-actions .ps-tryon-v2-cta {
|
|
12357
|
+
flex: 1 1 0;
|
|
12358
|
+
min-width: 0;
|
|
12359
|
+
min-height: clamp(38px, 2.55vw, 44px);
|
|
12360
|
+
padding: 0 clamp(10px, 0.75vw, 14px);
|
|
12361
|
+
}
|
|
12362
|
+
.ps-tryon-v2-result-actions > .ps-tryon-v2-cta {
|
|
12363
|
+
flex: 0 1 min(18vw, 240px);
|
|
12364
|
+
margin-left: auto;
|
|
12365
|
+
}
|
|
12366
|
+
.ps-tryon-v2-result-actions > .ps-tryon-v2-action-group .ps-tryon-v2-cta {
|
|
12367
|
+
flex: 1 1 0;
|
|
12277
12368
|
}
|
|
12278
12369
|
@keyframes ps-v2-fade {
|
|
12279
12370
|
0% { opacity: 0; }
|
|
@@ -12417,12 +12508,12 @@ const STYLES = `
|
|
|
12417
12508
|
|
|
12418
12509
|
/* CTA button */
|
|
12419
12510
|
.ps-tryon-v2-cta {
|
|
12420
|
-
margin-top: 0.8vw; padding: 0.
|
|
12421
|
-
width: auto; min-width:
|
|
12511
|
+
margin-top: 0.8vw; padding: 0.55vw 1.05vw;
|
|
12512
|
+
width: auto; min-width: 9.2vw; min-height: 2.35vw; display: flex; align-items: center; justify-content: center; gap: 0.35vw;
|
|
12422
12513
|
background: var(--ps-accent); color: #fff;
|
|
12423
|
-
border: none; border-radius: 0.
|
|
12424
|
-
font-size: 0.
|
|
12425
|
-
letter-spacing: 0.
|
|
12514
|
+
border: none; border-radius: 0.42vw;
|
|
12515
|
+
font-size: clamp(10px, 0.64vw, 12px); font-weight: 750; font-family: inherit;
|
|
12516
|
+
letter-spacing: 0.07em; text-transform: uppercase;
|
|
12426
12517
|
cursor: pointer; transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
12427
12518
|
flex-shrink: 0;
|
|
12428
12519
|
}
|
|
@@ -12433,6 +12524,98 @@ const STYLES = `
|
|
|
12433
12524
|
transform: translateY(-1px);
|
|
12434
12525
|
}
|
|
12435
12526
|
.ps-tryon-v2-cta svg { width: 0.8vw; height: 0.8vw; stroke: currentColor; }
|
|
12527
|
+
.ps-tryon-v2-action-group {
|
|
12528
|
+
display: flex;
|
|
12529
|
+
align-items: center;
|
|
12530
|
+
justify-content: flex-end;
|
|
12531
|
+
gap: clamp(8px, 0.55vw, 12px);
|
|
12532
|
+
min-width: 0;
|
|
12533
|
+
}
|
|
12534
|
+
.ps-tryon-v2-action-group-history {
|
|
12535
|
+
flex: 0 0 auto !important;
|
|
12536
|
+
width: auto !important;
|
|
12537
|
+
max-width: none !important;
|
|
12538
|
+
}
|
|
12539
|
+
.ps-tryon-v2-cta-compact,
|
|
12540
|
+
.ps-tryon-v2-history-product-cta {
|
|
12541
|
+
flex: 0 0 auto !important;
|
|
12542
|
+
width: auto !important;
|
|
12543
|
+
min-width: 0 !important;
|
|
12544
|
+
min-height: clamp(34px, 2.25vw, 40px) !important;
|
|
12545
|
+
padding: 0 clamp(10px, 0.75vw, 14px) !important;
|
|
12546
|
+
letter-spacing: 0.03em;
|
|
12547
|
+
text-transform: none;
|
|
12548
|
+
font-weight: 750;
|
|
12549
|
+
}
|
|
12550
|
+
.ps-tryon-v2-history-product-cta {
|
|
12551
|
+
justify-content: center;
|
|
12552
|
+
}
|
|
12553
|
+
.ps-tryon-v2-add-bag-cta svg,
|
|
12554
|
+
.ps-tryon-v2-history-product-cta svg {
|
|
12555
|
+
flex: 0 0 auto;
|
|
12556
|
+
width: clamp(16px, 1vw, 18px);
|
|
12557
|
+
height: clamp(16px, 1vw, 18px);
|
|
12558
|
+
stroke-width: 2.1;
|
|
12559
|
+
}
|
|
12560
|
+
.ps-tryon-v2-add-bag-cta.is-added {
|
|
12561
|
+
background: #16a34a;
|
|
12562
|
+
color: #fff;
|
|
12563
|
+
}
|
|
12564
|
+
.ps-tryon-v2-add-bag-cta.is-added:disabled {
|
|
12565
|
+
opacity: 1;
|
|
12566
|
+
cursor: default;
|
|
12567
|
+
}
|
|
12568
|
+
.ps-tryon-v2-add-bag-cta.is-added svg {
|
|
12569
|
+
animation: ps-added-check 0.42s cubic-bezier(0.16, 1, 0.3, 1);
|
|
12570
|
+
}
|
|
12571
|
+
@keyframes ps-added-check {
|
|
12572
|
+
0% { transform: scale(0.45); opacity: 0; }
|
|
12573
|
+
55% { transform: scale(1.18); opacity: 1; }
|
|
12574
|
+
100% { transform: scale(1); opacity: 1; }
|
|
12575
|
+
}
|
|
12576
|
+
.ps-tryon-v2-cta-secondary {
|
|
12577
|
+
background: #FFFFFF;
|
|
12578
|
+
color: var(--ps-accent);
|
|
12579
|
+
border: 1px solid rgba(33,84,239,0.38);
|
|
12580
|
+
box-shadow: none;
|
|
12581
|
+
}
|
|
12582
|
+
.ps-tryon-v2-cta-secondary:hover {
|
|
12583
|
+
background: rgba(33,84,239,0.06);
|
|
12584
|
+
color: var(--ps-accent);
|
|
12585
|
+
border-color: var(--ps-accent);
|
|
12586
|
+
box-shadow: 0 0.25vw 1vw rgba(33,84,239,0.12);
|
|
12587
|
+
}
|
|
12588
|
+
@media (max-width: 768px) {
|
|
12589
|
+
.ps-tryon-v2-action-group {
|
|
12590
|
+
width: 100%;
|
|
12591
|
+
gap: 8px;
|
|
12592
|
+
}
|
|
12593
|
+
.ps-tryon-v2-action-group-history {
|
|
12594
|
+
width: auto !important;
|
|
12595
|
+
margin-left: auto;
|
|
12596
|
+
}
|
|
12597
|
+
.ps-tryon-v2-action-group .ps-tryon-v2-cta,
|
|
12598
|
+
.ps-msr-commerce-row > .ps-tryon-v2-cta {
|
|
12599
|
+
flex: 1 1 0;
|
|
12600
|
+
min-width: 0;
|
|
12601
|
+
padding: 11px 12px;
|
|
12602
|
+
border-radius: 10px;
|
|
12603
|
+
font-size: 11px;
|
|
12604
|
+
letter-spacing: 0.08em;
|
|
12605
|
+
white-space: nowrap;
|
|
12606
|
+
}
|
|
12607
|
+
.ps-tryon-v2-action-group-history .ps-tryon-v2-cta {
|
|
12608
|
+
flex: 0 0 auto !important;
|
|
12609
|
+
width: auto !important;
|
|
12610
|
+
padding: 10px 12px !important;
|
|
12611
|
+
letter-spacing: 0.02em;
|
|
12612
|
+
}
|
|
12613
|
+
.ps-tryon-v2-add-bag-cta svg,
|
|
12614
|
+
.ps-tryon-v2-history-product-cta svg {
|
|
12615
|
+
width: 17px;
|
|
12616
|
+
height: 17px;
|
|
12617
|
+
}
|
|
12618
|
+
}
|
|
12436
12619
|
|
|
12437
12620
|
/* ── Size result card rows (split layout) ── */
|
|
12438
12621
|
.ps-tryon-sr-cards-stack {
|
|
@@ -12515,39 +12698,132 @@ const STYLES = `
|
|
|
12515
12698
|
flex: 1 1 45%; max-width: 49%;
|
|
12516
12699
|
display: flex; flex-direction: column; align-items: center; justify-content: center;
|
|
12517
12700
|
text-align: center;
|
|
12518
|
-
background:
|
|
12519
|
-
border
|
|
12701
|
+
background: linear-gradient(180deg, #FFFFFF 0%, #FBFCFF 100%);
|
|
12702
|
+
border: 1px solid rgba(15,23,42,0.08);
|
|
12703
|
+
border-radius: clamp(12px, 0.72vw, 14px); padding: clamp(14px, 0.82vw, 18px);
|
|
12520
12704
|
cursor: pointer; font-family: inherit;
|
|
12521
12705
|
transition: all 0.3s cubic-bezier(0.4, 0, 0.2, 1);
|
|
12522
12706
|
animation: ps-card-in 0.4s cubic-bezier(0.16, 1, 0.3, 1) forwards;
|
|
12523
12707
|
opacity: 0; overflow: hidden; position: relative;
|
|
12524
12708
|
min-height: 7vw;
|
|
12525
12709
|
}
|
|
12526
|
-
.ps-tryon-sr-card-v2
|
|
12710
|
+
.ps-tryon-sr-card-v2::after {
|
|
12711
|
+
content: "";
|
|
12712
|
+
position: absolute;
|
|
12713
|
+
inset: 0;
|
|
12714
|
+
border-radius: inherit;
|
|
12715
|
+
pointer-events: none;
|
|
12716
|
+
background: radial-gradient(circle at 50% 0%, rgba(33,84,239,0.08), transparent 38%);
|
|
12717
|
+
opacity: 0.6;
|
|
12718
|
+
}
|
|
12719
|
+
.ps-tryon-sr-card-v2.ps-full { flex: 1 1 100%; max-width: 100%; min-height: 5vw; padding: clamp(14px, 0.82vw, 18px); }
|
|
12720
|
+
.ps-tryon-sr-card-v2.ps-summary-card {
|
|
12721
|
+
align-items: stretch;
|
|
12722
|
+
justify-content: center;
|
|
12723
|
+
text-align: left;
|
|
12724
|
+
min-height: clamp(112px, 7.4vw, 132px);
|
|
12725
|
+
padding: clamp(18px, 1.12vw, 24px) clamp(20px, 1.3vw, 28px);
|
|
12726
|
+
}
|
|
12527
12727
|
.ps-tryon-sr-card-v2:hover {
|
|
12528
12728
|
border-color: var(--ps-accent);
|
|
12529
|
-
background: rgba(33,84,239,0.
|
|
12729
|
+
background: linear-gradient(180deg, #FFFFFF 0%, rgba(33,84,239,0.045) 100%);
|
|
12530
12730
|
transform: translateY(-2px);
|
|
12531
|
-
box-shadow: 0 0.
|
|
12731
|
+
box-shadow: 0 0.45vw 1.4vw rgba(15,23,42,0.08);
|
|
12532
12732
|
}
|
|
12533
12733
|
.ps-tryon-sr-card-v2-text {
|
|
12534
|
-
display: flex; flex-direction: column; align-items: center; gap: 0.
|
|
12734
|
+
display: flex; flex-direction: column; align-items: center; gap: clamp(5px, 0.22vw, 7px); z-index: 1;
|
|
12735
|
+
}
|
|
12736
|
+
.ps-summary-card-layout {
|
|
12737
|
+
width: 100%;
|
|
12738
|
+
display: grid;
|
|
12739
|
+
grid-template-columns: minmax(0, 1fr) auto;
|
|
12740
|
+
grid-template-areas: "copy action";
|
|
12741
|
+
align-items: center;
|
|
12742
|
+
column-gap: clamp(18px, 1.25vw, 28px);
|
|
12743
|
+
row-gap: 0;
|
|
12744
|
+
}
|
|
12745
|
+
.ps-summary-card-copy {
|
|
12746
|
+
grid-area: copy;
|
|
12747
|
+
display: flex;
|
|
12748
|
+
flex-direction: column;
|
|
12749
|
+
align-items: flex-start;
|
|
12750
|
+
justify-content: center;
|
|
12751
|
+
min-width: 0;
|
|
12752
|
+
gap: clamp(8px, 0.48vw, 12px);
|
|
12753
|
+
}
|
|
12754
|
+
.ps-tryon-sr-card-v2-heading {
|
|
12755
|
+
grid-area: heading;
|
|
12756
|
+
display: flex;
|
|
12757
|
+
align-items: center;
|
|
12758
|
+
gap: clamp(8px, 0.55vw, 12px);
|
|
12759
|
+
min-width: 0;
|
|
12760
|
+
}
|
|
12761
|
+
.ps-tryon-sr-card-v2-main {
|
|
12762
|
+
display: flex;
|
|
12763
|
+
align-items: center;
|
|
12764
|
+
justify-content: flex-start;
|
|
12765
|
+
gap: clamp(9px, 0.6vw, 14px);
|
|
12766
|
+
min-width: 0;
|
|
12767
|
+
}
|
|
12768
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-open-pill {
|
|
12769
|
+
grid-area: action;
|
|
12770
|
+
margin-top: 0;
|
|
12771
|
+
white-space: nowrap;
|
|
12772
|
+
}
|
|
12773
|
+
.ps-tryon-sr-card-v2-summary-title {
|
|
12774
|
+
font-size: clamp(11px, 0.66vw, 12px);
|
|
12775
|
+
font-weight: 760;
|
|
12776
|
+
color: rgba(15,23,42,0.56);
|
|
12777
|
+
letter-spacing: 0.06em;
|
|
12778
|
+
text-transform: uppercase;
|
|
12779
|
+
line-height: 1.2;
|
|
12780
|
+
margin-bottom: clamp(2px, 0.08vw, 4px);
|
|
12781
|
+
}
|
|
12782
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-summary-title {
|
|
12783
|
+
margin-bottom: 0;
|
|
12784
|
+
white-space: nowrap;
|
|
12785
|
+
color: rgba(15,23,42,0.58);
|
|
12786
|
+
font-size: clamp(11px, 0.66vw, 12px);
|
|
12787
|
+
font-weight: 780;
|
|
12788
|
+
letter-spacing: 0.12em;
|
|
12789
|
+
text-transform: uppercase;
|
|
12790
|
+
}
|
|
12791
|
+
.ps-tryon-sr-card-v2-summary-subtitle {
|
|
12792
|
+
font-size: clamp(10px, 0.56vw, 11px);
|
|
12793
|
+
font-weight: 400;
|
|
12794
|
+
color: rgba(0,0,0,0.32);
|
|
12795
|
+
letter-spacing: 0.02em;
|
|
12796
|
+
line-height: 1.25;
|
|
12797
|
+
text-transform: none;
|
|
12798
|
+
margin-bottom: 0.35vw;
|
|
12535
12799
|
}
|
|
12536
12800
|
.ps-tryon-sr-card-v2-label {
|
|
12537
|
-
font-size: 0.
|
|
12538
|
-
text-transform: uppercase; letter-spacing: 0.
|
|
12801
|
+
font-size: clamp(10px, 0.56vw, 11px); font-weight: 650; color: rgba(15,23,42,0.58);
|
|
12802
|
+
text-transform: uppercase; letter-spacing: 0.08em;
|
|
12539
12803
|
display: inline-flex; align-items: center; gap: 0.5vw;
|
|
12540
12804
|
}
|
|
12805
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-label {
|
|
12806
|
+
min-width: 0;
|
|
12807
|
+
overflow: hidden;
|
|
12808
|
+
text-overflow: ellipsis;
|
|
12809
|
+
white-space: nowrap;
|
|
12810
|
+
}
|
|
12541
12811
|
.ps-tryon-sr-card-v2-label-icon {
|
|
12542
12812
|
width: 4.8vw; height: 4.8vw; object-fit: contain;
|
|
12543
12813
|
opacity: 1;
|
|
12544
12814
|
}
|
|
12545
12815
|
.ps-tryon-sr-card-v2-value {
|
|
12546
|
-
font-size: 2.
|
|
12816
|
+
font-size: clamp(30px, 2.18vw, 38px); font-weight: 260; color: var(--ps-text-primary);
|
|
12547
12817
|
line-height: 1; letter-spacing: -0.02em;
|
|
12548
12818
|
overflow-wrap: anywhere;
|
|
12549
12819
|
}
|
|
12550
|
-
.ps-tryon-sr-card-v2.ps-full .ps-tryon-sr-card-v2-value { font-size:
|
|
12820
|
+
.ps-tryon-sr-card-v2.ps-full .ps-tryon-sr-card-v2-value { font-size: clamp(30px, 2vw, 36px); }
|
|
12821
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-value {
|
|
12822
|
+
flex: 0 1 auto;
|
|
12823
|
+
font-size: clamp(38px, 2.55vw, 48px);
|
|
12824
|
+
min-width: 0;
|
|
12825
|
+
text-align: left;
|
|
12826
|
+
}
|
|
12551
12827
|
/* Long combined labels ("MISSY 12 / Standard", "PLUS 16W / Extra Length")
|
|
12552
12828
|
overflow the card at 2vw. Drop to ~1.3vw whenever the label is more
|
|
12553
12829
|
than ~12 chars so the whole thing fits on one line. */
|
|
@@ -12566,13 +12842,19 @@ const STYLES = `
|
|
|
12566
12842
|
}
|
|
12567
12843
|
.ps-tryon-sr-card-v2-rec-pill {
|
|
12568
12844
|
align-self: center;
|
|
12569
|
-
font-size: 0.
|
|
12570
|
-
text-transform: uppercase; letter-spacing: 0.
|
|
12845
|
+
font-size: clamp(9px, 0.52vw, 10px); font-weight: 780; color: var(--ps-accent);
|
|
12846
|
+
text-transform: uppercase; letter-spacing: 0.07em;
|
|
12571
12847
|
background: rgba(33, 84, 239, 0.10);
|
|
12572
12848
|
border: 1px solid rgba(33, 84, 239, 0.18);
|
|
12573
12849
|
border-radius: 2vw;
|
|
12574
|
-
padding: 0.18vw 0.
|
|
12575
|
-
margin-top: 0.
|
|
12850
|
+
padding: clamp(3px, 0.18vw, 4px) clamp(9px, 0.58vw, 12px);
|
|
12851
|
+
margin-top: clamp(2px, 0.12vw, 4px);
|
|
12852
|
+
}
|
|
12853
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-rec-pill {
|
|
12854
|
+
align-self: center;
|
|
12855
|
+
margin-top: 0;
|
|
12856
|
+
white-space: nowrap;
|
|
12857
|
+
background: #fff;
|
|
12576
12858
|
}
|
|
12577
12859
|
.ps-tryon-sr-card-v2-rec-pill.is-overridden {
|
|
12578
12860
|
color: #b45309;
|
|
@@ -12581,10 +12863,10 @@ const STYLES = `
|
|
|
12581
12863
|
}
|
|
12582
12864
|
.ps-tryon-sr-card-v2-view {
|
|
12583
12865
|
align-self: center;
|
|
12584
|
-
margin-top: 0.
|
|
12585
|
-
font-size: 0.
|
|
12866
|
+
margin-top: clamp(2px, 0.18vw, 5px);
|
|
12867
|
+
font-size: clamp(10px, 0.58vw, 11px); font-weight: 700;
|
|
12586
12868
|
color: var(--ps-accent);
|
|
12587
|
-
text-transform:
|
|
12869
|
+
text-transform: none; letter-spacing: 0.02em;
|
|
12588
12870
|
display: inline-flex; align-items: center; justify-content: center; gap: 0.2vw;
|
|
12589
12871
|
transition: gap 0.2s ease;
|
|
12590
12872
|
}
|
|
@@ -12595,6 +12877,60 @@ const STYLES = `
|
|
|
12595
12877
|
font-size: 0.85vw; line-height: 1; color: var(--ps-accent);
|
|
12596
12878
|
transform: translateY(-0.05vw);
|
|
12597
12879
|
}
|
|
12880
|
+
.ps-tryon-sr-card-v2-open-pill {
|
|
12881
|
+
margin-top: clamp(4px, 0.26vw, 7px);
|
|
12882
|
+
display: inline-flex;
|
|
12883
|
+
align-items: center;
|
|
12884
|
+
justify-content: center;
|
|
12885
|
+
gap: clamp(4px, 0.25vw, 6px);
|
|
12886
|
+
min-height: clamp(26px, 1.65vw, 32px);
|
|
12887
|
+
padding: 0 clamp(10px, 0.68vw, 14px);
|
|
12888
|
+
border-radius: 999px;
|
|
12889
|
+
background: #fff;
|
|
12890
|
+
border: 1px solid rgba(33,84,239,0.22);
|
|
12891
|
+
color: var(--ps-accent);
|
|
12892
|
+
font-size: clamp(10px, 0.58vw, 11px);
|
|
12893
|
+
font-weight: 760;
|
|
12894
|
+
letter-spacing: 0.01em;
|
|
12895
|
+
box-shadow: 0 0.18vw 0.8vw rgba(33,84,239,0.08);
|
|
12896
|
+
transition: transform 0.2s ease, border-color 0.2s ease, box-shadow 0.2s ease;
|
|
12897
|
+
}
|
|
12898
|
+
.ps-tryon-sr-card-v2-open-pill > span[aria-hidden="true"] {
|
|
12899
|
+
font-size: clamp(14px, 0.85vw, 16px);
|
|
12900
|
+
line-height: 1;
|
|
12901
|
+
transform: translateY(-0.03vw);
|
|
12902
|
+
}
|
|
12903
|
+
.ps-tryon-sr-card-v2:hover .ps-tryon-sr-card-v2-open-pill {
|
|
12904
|
+
transform: translateY(-1px);
|
|
12905
|
+
border-color: rgba(33,84,239,0.45);
|
|
12906
|
+
box-shadow: 0 0.24vw 1vw rgba(33,84,239,0.13);
|
|
12907
|
+
}
|
|
12908
|
+
@media (max-width: 768px) {
|
|
12909
|
+
.ps-tryon-sr-card-v2.ps-summary-card {
|
|
12910
|
+
min-height: 104px;
|
|
12911
|
+
padding: 16px;
|
|
12912
|
+
}
|
|
12913
|
+
.ps-summary-card-layout {
|
|
12914
|
+
grid-template-columns: minmax(0, 1fr);
|
|
12915
|
+
grid-template-areas:
|
|
12916
|
+
"copy"
|
|
12917
|
+
"action";
|
|
12918
|
+
row-gap: 12px;
|
|
12919
|
+
align-items: stretch;
|
|
12920
|
+
}
|
|
12921
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-main {
|
|
12922
|
+
width: 100%;
|
|
12923
|
+
justify-content: space-between;
|
|
12924
|
+
gap: 12px;
|
|
12925
|
+
}
|
|
12926
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-value {
|
|
12927
|
+
font-size: 34px;
|
|
12928
|
+
}
|
|
12929
|
+
.ps-summary-card-layout .ps-tryon-sr-card-v2-open-pill {
|
|
12930
|
+
width: 100%;
|
|
12931
|
+
min-height: 38px;
|
|
12932
|
+
}
|
|
12933
|
+
}
|
|
12598
12934
|
.ps-tryon-sr-card-v2-img { display: none; }
|
|
12599
12935
|
.ps-tryon-sr-card-v2-icon {
|
|
12600
12936
|
position: absolute; bottom: 0.35vw; right: 0.45vw;
|
|
@@ -16583,6 +16919,87 @@ const STYLES = `
|
|
|
16583
16919
|
}
|
|
16584
16920
|
.ps-bp-image-remove:hover { background: rgba(0,0,0,0.8); }
|
|
16585
16921
|
|
|
16922
|
+
.ps-bp-photo-help-chip {
|
|
16923
|
+
position: absolute;
|
|
16924
|
+
top: clamp(8px, 0.65vw, 12px);
|
|
16925
|
+
left: clamp(8px, 0.65vw, 12px);
|
|
16926
|
+
z-index: 3;
|
|
16927
|
+
display: inline-flex;
|
|
16928
|
+
align-items: center;
|
|
16929
|
+
gap: clamp(5px, 0.35vw, 7px);
|
|
16930
|
+
max-width: calc(100% - clamp(58px, 4.2vw, 78px));
|
|
16931
|
+
padding: clamp(5px, 0.38vw, 7px) clamp(8px, 0.62vw, 12px);
|
|
16932
|
+
border: 1px solid rgba(33, 84, 239, 0.22);
|
|
16933
|
+
border-radius: 999px;
|
|
16934
|
+
background: rgba(255, 255, 255, 0.92);
|
|
16935
|
+
color: var(--ps-accent);
|
|
16936
|
+
box-shadow: 0 8px 20px -16px rgba(17, 24, 39, 0.35);
|
|
16937
|
+
backdrop-filter: blur(8px);
|
|
16938
|
+
-webkit-backdrop-filter: blur(8px);
|
|
16939
|
+
font-family: inherit;
|
|
16940
|
+
font-size: clamp(10px, 0.6vw, 12px);
|
|
16941
|
+
font-weight: 800;
|
|
16942
|
+
letter-spacing: 0.04em;
|
|
16943
|
+
line-height: 1;
|
|
16944
|
+
white-space: nowrap;
|
|
16945
|
+
cursor: pointer;
|
|
16946
|
+
transition: background 0.15s, color 0.15s, border-color 0.15s;
|
|
16947
|
+
}
|
|
16948
|
+
.ps-bp-photo-help-chip.ps-active {
|
|
16949
|
+
background: var(--ps-accent);
|
|
16950
|
+
border-color: var(--ps-accent);
|
|
16951
|
+
color: #FFFFFF;
|
|
16952
|
+
}
|
|
16953
|
+
.ps-bp-photo-help-chip-mark {
|
|
16954
|
+
display: inline-flex;
|
|
16955
|
+
align-items: center;
|
|
16956
|
+
justify-content: center;
|
|
16957
|
+
width: clamp(14px, 0.9vw, 16px);
|
|
16958
|
+
height: clamp(14px, 0.9vw, 16px);
|
|
16959
|
+
flex: 0 0 auto;
|
|
16960
|
+
border-radius: 999px;
|
|
16961
|
+
background: var(--ps-accent);
|
|
16962
|
+
color: #FFFFFF;
|
|
16963
|
+
font-size: clamp(10px, 0.58vw, 11px);
|
|
16964
|
+
font-weight: 900;
|
|
16965
|
+
}
|
|
16966
|
+
.ps-bp-photo-help-chip.ps-active .ps-bp-photo-help-chip-mark {
|
|
16967
|
+
background: #FFFFFF;
|
|
16968
|
+
color: var(--ps-accent);
|
|
16969
|
+
}
|
|
16970
|
+
|
|
16971
|
+
.ps-bp-photo-details-head {
|
|
16972
|
+
display: flex;
|
|
16973
|
+
align-items: center;
|
|
16974
|
+
justify-content: space-between;
|
|
16975
|
+
gap: clamp(10px, 0.8vw, 16px);
|
|
16976
|
+
padding: 0 0 clamp(5px, 0.35vw, 8px);
|
|
16977
|
+
border-bottom: 1px solid var(--ps-border-subtle);
|
|
16978
|
+
}
|
|
16979
|
+
.ps-bp-photo-details-head h3 {
|
|
16980
|
+
margin: 0;
|
|
16981
|
+
color: var(--ps-text-primary);
|
|
16982
|
+
font-size: clamp(13px, 0.82vw, 16px);
|
|
16983
|
+
font-weight: 800;
|
|
16984
|
+
letter-spacing: 0.01em;
|
|
16985
|
+
line-height: 1.1;
|
|
16986
|
+
}
|
|
16987
|
+
.ps-bp-photo-details-head-simple {
|
|
16988
|
+
padding-bottom: clamp(8px, 0.55vw, 12px);
|
|
16989
|
+
}
|
|
16990
|
+
.ps-bp-photo-details-head-simple h3 {
|
|
16991
|
+
font-size: clamp(14px, 0.9vw, 17px);
|
|
16992
|
+
}
|
|
16993
|
+
.ps-bp-system-toggle-compact {
|
|
16994
|
+
margin: 0;
|
|
16995
|
+
gap: clamp(12px, 0.85vw, 18px);
|
|
16996
|
+
flex-shrink: 0;
|
|
16997
|
+
}
|
|
16998
|
+
.ps-bp-system-toggle-compact .ps-bp-system-btn {
|
|
16999
|
+
font-size: clamp(11px, 0.66vw, 13px);
|
|
17000
|
+
padding: 0 0 3px;
|
|
17001
|
+
}
|
|
17002
|
+
|
|
16586
17003
|
.ps-bp-root {
|
|
16587
17004
|
flex: 1; min-width: 0;
|
|
16588
17005
|
display: flex; flex-direction: column; gap: 0.6vw; padding: 0.2vw 0.5vw 0.3vw 0;
|
|
@@ -16611,7 +17028,7 @@ const STYLES = `
|
|
|
16611
17028
|
to { opacity: 1; }
|
|
16612
17029
|
}
|
|
16613
17030
|
|
|
16614
|
-
/*
|
|
17031
|
+
/* Active profile status above body details */
|
|
16615
17032
|
.ps-bp-profile-hint {
|
|
16616
17033
|
margin: 0; padding: 0;
|
|
16617
17034
|
text-align: center;
|
|
@@ -16631,6 +17048,98 @@ const STYLES = `
|
|
|
16631
17048
|
cursor: pointer; padding: 0;
|
|
16632
17049
|
}
|
|
16633
17050
|
.ps-bp-profile-hint-link:hover { color: var(--ps-text-secondary); }
|
|
17051
|
+
.ps-bp-profile-card {
|
|
17052
|
+
display: flex;
|
|
17053
|
+
align-items: center;
|
|
17054
|
+
justify-content: space-between;
|
|
17055
|
+
gap: clamp(8px, 0.65vw, 14px);
|
|
17056
|
+
width: min(100%, 500px);
|
|
17057
|
+
margin: 0 auto clamp(7px, 0.55vw, 12px);
|
|
17058
|
+
padding: clamp(7px, 0.55vw, 11px) clamp(10px, 0.8vw, 16px);
|
|
17059
|
+
border: 1px solid rgba(33, 84, 239, 0.18);
|
|
17060
|
+
border-radius: clamp(8px, 0.7vw, 12px);
|
|
17061
|
+
background: linear-gradient(135deg, rgba(33, 84, 239, 0.08), rgba(255, 255, 255, 0.96));
|
|
17062
|
+
box-shadow: 0 10px 28px -24px rgba(33, 84, 239, 0.55);
|
|
17063
|
+
}
|
|
17064
|
+
.ps-bp-profile-card-copy {
|
|
17065
|
+
display: flex;
|
|
17066
|
+
flex-direction: column;
|
|
17067
|
+
gap: clamp(1px, 0.12vw, 3px);
|
|
17068
|
+
min-width: 0;
|
|
17069
|
+
}
|
|
17070
|
+
.ps-bp-profile-card-eyebrow {
|
|
17071
|
+
font-size: clamp(8px, 0.55vw, 10px);
|
|
17072
|
+
font-weight: 800;
|
|
17073
|
+
letter-spacing: 0.14em;
|
|
17074
|
+
text-transform: uppercase;
|
|
17075
|
+
color: var(--ps-accent);
|
|
17076
|
+
}
|
|
17077
|
+
.ps-bp-profile-card-copy strong {
|
|
17078
|
+
font-size: clamp(12px, 0.85vw, 15px);
|
|
17079
|
+
line-height: 1.1;
|
|
17080
|
+
color: var(--ps-text-primary);
|
|
17081
|
+
overflow: hidden;
|
|
17082
|
+
text-overflow: ellipsis;
|
|
17083
|
+
white-space: nowrap;
|
|
17084
|
+
}
|
|
17085
|
+
.ps-bp-profile-card-copy span:last-child {
|
|
17086
|
+
font-size: clamp(9px, 0.58vw, 11px);
|
|
17087
|
+
line-height: 1.25;
|
|
17088
|
+
color: var(--ps-text-secondary);
|
|
17089
|
+
}
|
|
17090
|
+
.ps-bp-profile-card-action {
|
|
17091
|
+
flex-shrink: 0;
|
|
17092
|
+
border: 1px solid rgba(33, 84, 239, 0.22);
|
|
17093
|
+
background: #FFFFFF;
|
|
17094
|
+
color: var(--ps-accent);
|
|
17095
|
+
border-radius: 999px;
|
|
17096
|
+
padding: clamp(6px, 0.45vw, 8px) clamp(9px, 0.7vw, 14px);
|
|
17097
|
+
font-family: inherit;
|
|
17098
|
+
font-size: clamp(9px, 0.62vw, 11px);
|
|
17099
|
+
font-weight: 800;
|
|
17100
|
+
letter-spacing: 0.08em;
|
|
17101
|
+
text-transform: uppercase;
|
|
17102
|
+
cursor: pointer;
|
|
17103
|
+
transition: border-color 0.15s, background 0.15s, transform 0.15s;
|
|
17104
|
+
}
|
|
17105
|
+
.ps-bp-profile-card-action:hover {
|
|
17106
|
+
border-color: var(--ps-accent);
|
|
17107
|
+
background: rgba(33, 84, 239, 0.06);
|
|
17108
|
+
}
|
|
17109
|
+
.ps-bp-profile-card-action:active { transform: scale(0.98); }
|
|
17110
|
+
.ps-bp-profile-card-compact {
|
|
17111
|
+
margin: 0 auto clamp(3px, 0.32vw, 6px);
|
|
17112
|
+
padding: clamp(4px, 0.34vw, 6px) clamp(8px, 0.62vw, 12px);
|
|
17113
|
+
border-radius: clamp(7px, 0.55vw, 10px);
|
|
17114
|
+
box-shadow: none;
|
|
17115
|
+
}
|
|
17116
|
+
.ps-bp-profile-card-compact .ps-bp-profile-card-copy {
|
|
17117
|
+
display: grid;
|
|
17118
|
+
grid-template-columns: auto minmax(0, 1fr);
|
|
17119
|
+
align-items: baseline;
|
|
17120
|
+
gap: 2px clamp(6px, 0.45vw, 9px);
|
|
17121
|
+
}
|
|
17122
|
+
.ps-bp-profile-card-compact .ps-bp-profile-card-eyebrow {
|
|
17123
|
+
grid-column: 1 / -1;
|
|
17124
|
+
font-size: clamp(7px, 0.46vw, 9px);
|
|
17125
|
+
letter-spacing: 0.16em;
|
|
17126
|
+
line-height: 1;
|
|
17127
|
+
}
|
|
17128
|
+
.ps-bp-profile-card-compact .ps-bp-profile-card-copy strong {
|
|
17129
|
+
font-size: clamp(11px, 0.72vw, 13px);
|
|
17130
|
+
line-height: 1.05;
|
|
17131
|
+
}
|
|
17132
|
+
.ps-bp-profile-card-compact .ps-bp-profile-card-copy span:last-child {
|
|
17133
|
+
font-size: clamp(8px, 0.5vw, 10px);
|
|
17134
|
+
line-height: 1.1;
|
|
17135
|
+
overflow: hidden;
|
|
17136
|
+
text-overflow: ellipsis;
|
|
17137
|
+
white-space: nowrap;
|
|
17138
|
+
}
|
|
17139
|
+
.ps-bp-profile-card-compact .ps-bp-profile-card-action {
|
|
17140
|
+
padding: clamp(4px, 0.3vw, 6px) clamp(7px, 0.55vw, 11px);
|
|
17141
|
+
font-size: clamp(8px, 0.52vw, 10px);
|
|
17142
|
+
}
|
|
16634
17143
|
|
|
16635
17144
|
/* Typography */
|
|
16636
17145
|
.ps-bp-title {
|
|
@@ -17846,6 +18355,16 @@ const STYLES = `
|
|
|
17846
18355
|
.ps-msr-bottom-row {
|
|
17847
18356
|
display: flex; gap: 8px; align-items: stretch; justify-content: flex-end;
|
|
17848
18357
|
}
|
|
18358
|
+
.ps-msr-bottom-row.ps-msr-commerce-row {
|
|
18359
|
+
width: 100%;
|
|
18360
|
+
}
|
|
18361
|
+
.ps-msr-commerce-row .ps-tryon-v2-action-group {
|
|
18362
|
+
width: 100%;
|
|
18363
|
+
}
|
|
18364
|
+
.ps-msr-commerce-row .ps-tryon-v2-cta {
|
|
18365
|
+
flex: 1 1 0;
|
|
18366
|
+
min-width: 0;
|
|
18367
|
+
}
|
|
17849
18368
|
.ps-msr-bottom-row .ps-msr-tryon-cta {
|
|
17850
18369
|
flex: 0 0 auto; min-width: 94px; width: auto;
|
|
17851
18370
|
padding: 11px 14px; font-size: 12px;
|
|
@@ -19259,6 +19778,9 @@ const STYLES = `
|
|
|
19259
19778
|
background: var(--ps-bg-primary);
|
|
19260
19779
|
flex-shrink: 0;
|
|
19261
19780
|
}
|
|
19781
|
+
.ps-cpw-footer-no-back {
|
|
19782
|
+
justify-content: flex-end;
|
|
19783
|
+
}
|
|
19262
19784
|
.ps-cpw-back-btn {
|
|
19263
19785
|
background: none; border: none;
|
|
19264
19786
|
color: var(--ps-text-secondary);
|
|
@@ -19902,6 +20424,7 @@ const STYLES = `
|
|
|
19902
20424
|
display: flex; flex-direction: column;
|
|
19903
20425
|
gap: max(14px, 1.2vw);
|
|
19904
20426
|
min-width: 0; width: 100%;
|
|
20427
|
+
padding-bottom: clamp(78px, 5.4vw, 104px);
|
|
19905
20428
|
}
|
|
19906
20429
|
|
|
19907
20430
|
/* Basics list — height / weight / age, inline icon + label + value */
|
|
@@ -20137,12 +20660,12 @@ const STYLES = `
|
|
|
20137
20660
|
gap: clamp(8px, 0.7vw, 14px);
|
|
20138
20661
|
position: sticky;
|
|
20139
20662
|
bottom: 0;
|
|
20140
|
-
background: var(--ps-bg-primary);
|
|
20663
|
+
background: color-mix(in srgb, var(--ps-bg-primary) 96%, #FFFFFF);
|
|
20141
20664
|
border-top: 1px solid var(--ps-border-subtle);
|
|
20142
|
-
padding
|
|
20143
|
-
|
|
20144
|
-
z-index: 2;
|
|
20665
|
+
padding: clamp(10px, 0.8vw, 16px) clamp(4px, 0.35vw, 8px) calc(clamp(10px, 0.8vw, 16px) + env(safe-area-inset-bottom, 0px));
|
|
20666
|
+
z-index: 5;
|
|
20145
20667
|
margin-top: auto;
|
|
20668
|
+
box-shadow: 0 -14px 30px -28px rgba(17, 24, 39, 0.35);
|
|
20146
20669
|
}
|
|
20147
20670
|
.ps-pmv-actions-right {
|
|
20148
20671
|
display: flex; align-items: center;
|
|
@@ -20154,7 +20677,7 @@ const STYLES = `
|
|
|
20154
20677
|
background: none;
|
|
20155
20678
|
border: 1px solid var(--ps-border-color);
|
|
20156
20679
|
border-radius: clamp(4px, 0.35vw, 8px);
|
|
20157
|
-
padding: clamp(6px, 0.55vw, 12px) clamp(
|
|
20680
|
+
padding: clamp(6px, 0.55vw, 12px) clamp(13px, 1.05vw, 24px);
|
|
20158
20681
|
font-family: inherit;
|
|
20159
20682
|
font-size: clamp(9px, 0.65vw, 12px);
|
|
20160
20683
|
font-weight: 600;
|
|
@@ -20176,7 +20699,7 @@ const STYLES = `
|
|
|
20176
20699
|
background: var(--ps-accent); color: #FFFFFF;
|
|
20177
20700
|
border: none;
|
|
20178
20701
|
border-radius: clamp(4px, 0.35vw, 8px);
|
|
20179
|
-
padding: clamp(7px, 0.65vw, 14px) clamp(
|
|
20702
|
+
padding: clamp(7px, 0.65vw, 14px) clamp(15px, 1.15vw, 26px);
|
|
20180
20703
|
font-family: inherit;
|
|
20181
20704
|
font-size: clamp(9px, 0.65vw, 12px);
|
|
20182
20705
|
font-weight: 700;
|
|
@@ -20272,6 +20795,14 @@ const STYLES = `
|
|
|
20272
20795
|
opacity: 0.6;
|
|
20273
20796
|
cursor: default;
|
|
20274
20797
|
}
|
|
20798
|
+
.ps-msd-result-action-group {
|
|
20799
|
+
flex: 1 1 0;
|
|
20800
|
+
justify-content: flex-end;
|
|
20801
|
+
}
|
|
20802
|
+
.ps-msd-result-action-group .ps-tryon-v2-cta {
|
|
20803
|
+
flex: 1 1 0;
|
|
20804
|
+
min-width: 0;
|
|
20805
|
+
}
|
|
20275
20806
|
|
|
20276
20807
|
/* RECOMMENDED SIZE card */
|
|
20277
20808
|
.ps-msd-card {
|
|
@@ -20548,6 +21079,14 @@ const STYLES = `
|
|
|
20548
21079
|
display: flex; flex-direction: column; gap: 0.6vw;
|
|
20549
21080
|
z-index: 5;
|
|
20550
21081
|
}
|
|
21082
|
+
.ps-bp-photo-help-upload {
|
|
21083
|
+
top: clamp(46px, 3.2vw, 58px);
|
|
21084
|
+
left: clamp(12px, 0.85vw, 16px);
|
|
21085
|
+
right: auto;
|
|
21086
|
+
width: min(360px, calc(100% - clamp(24px, 1.7vw, 32px)));
|
|
21087
|
+
max-height: calc(100% - clamp(64px, 4.5vw, 82px));
|
|
21088
|
+
overflow-y: auto;
|
|
21089
|
+
}
|
|
20551
21090
|
.ps-bp-photo-help-handle { display: none; }
|
|
20552
21091
|
.ps-bp-photo-help-header { display: flex; align-items: center; justify-content: space-between; }
|
|
20553
21092
|
.ps-bp-photo-help-title { font-size: 0.8vw; font-weight: 700; color: var(--ps-text-primary); }
|
|
@@ -21299,6 +21838,21 @@ function UserIcon({ size = 16 }) {
|
|
|
21299
21838
|
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "7", r: "4" })
|
|
21300
21839
|
] });
|
|
21301
21840
|
}
|
|
21841
|
+
function ShoppingBagIcon({ size = 16 }) {
|
|
21842
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
21843
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M6 7h12l-1 14H7L6 7Z" }),
|
|
21844
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9 7a3 3 0 0 1 6 0" }),
|
|
21845
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M12 12v5" }),
|
|
21846
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M9.5 14.5h5" })
|
|
21847
|
+
] });
|
|
21848
|
+
}
|
|
21849
|
+
function ExternalLinkIcon({ size = 16 }) {
|
|
21850
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
21851
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M14 3h7v7" }),
|
|
21852
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M10 14 21 3" }),
|
|
21853
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M21 14v5a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5" })
|
|
21854
|
+
] });
|
|
21855
|
+
}
|
|
21302
21856
|
function ClockIcon({ size = 16 }) {
|
|
21303
21857
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("svg", { width: size, height: size, viewBox: "0 0 24 24", fill: "none", stroke: "currentColor", strokeWidth: 2, strokeLinecap: "round", strokeLinejoin: "round", children: [
|
|
21304
21858
|
/* @__PURE__ */ jsxRuntimeExports.jsx("circle", { cx: "12", cy: "12", r: "10" }),
|
|
@@ -21824,7 +22378,7 @@ function WelcomeView({
|
|
|
21824
22378
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-welcome-sparkle", children: /* @__PURE__ */ jsxRuntimeExports.jsx(SparkleIcon, { size: 20 }) })
|
|
21825
22379
|
] }),
|
|
21826
22380
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-tryon-welcome-title", children: t2("See Your Fit") }),
|
|
21827
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-welcome-sub", children: t2("
|
|
22381
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-welcome-sub", children: t2("Check your size, then try it on virtually") })
|
|
21828
22382
|
] }),
|
|
21829
22383
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-features", children: [
|
|
21830
22384
|
{ icon: /* @__PURE__ */ jsxRuntimeExports.jsx(RulerIcon$1, { size: 22 }), title: t2("Get Your Size"), desc: t2("Instant fit recommendation") },
|
|
@@ -22155,7 +22709,7 @@ function MobileScanningView({
|
|
|
22155
22709
|
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your recommendation."), viewfinderText: t2("FINALIZING") }
|
|
22156
22710
|
] : [
|
|
22157
22711
|
{ title: t2("DETECTING POSE"), desc: t2("Identifying body landmarks from your photo."), viewfinderText: t2("DETECTING POSE") },
|
|
22158
|
-
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions
|
|
22712
|
+
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions for a size recommendation."), viewfinderText: t2("SCANNING FRAME") },
|
|
22159
22713
|
{ title: t2("ANALYZING BODY"), desc: t2("Measuring shoulders, chest, waist and hips."), viewfinderText: t2("ANALYZING") },
|
|
22160
22714
|
{ title: t2("MATCHING SIZE"), desc: t2("Comparing your measurements to the size guide."), viewfinderText: t2("MATCHING SIZE") },
|
|
22161
22715
|
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your recommendation."), viewfinderText: t2("FINALIZING") }
|
|
@@ -22325,6 +22879,7 @@ function MultiSectionMobile({
|
|
|
22325
22879
|
tryOnDone,
|
|
22326
22880
|
onTryAgain,
|
|
22327
22881
|
onClose,
|
|
22882
|
+
resultActionNode,
|
|
22328
22883
|
overlayNode,
|
|
22329
22884
|
showLines,
|
|
22330
22885
|
onToggleLines,
|
|
@@ -22400,7 +22955,7 @@ function MultiSectionMobile({
|
|
|
22400
22955
|
}) }),
|
|
22401
22956
|
profileCompletionCta
|
|
22402
22957
|
] }),
|
|
22403
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-bottom", children: tryOnDone ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msr-bottom-row", children: [
|
|
22958
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-bottom", children: resultActionNode ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-msr-bottom-row ps-msr-commerce-row", children: resultActionNode }) : tryOnDone ? /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-msr-bottom-row", children: [
|
|
22404
22959
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22405
22960
|
"button",
|
|
22406
22961
|
{
|
|
@@ -22504,7 +23059,7 @@ function ProfileCompletionCta({
|
|
|
22504
23059
|
border: "1px solid rgba(33, 84, 239, 0.16)",
|
|
22505
23060
|
background: "linear-gradient(135deg, #FFFFFF 0%, rgba(33,84,239,0.055) 100%)",
|
|
22506
23061
|
borderRadius: isMobile ? 12 : "0.7vw",
|
|
22507
|
-
padding: isMobile ? "13px 14px" : isHeader ? "0.
|
|
23062
|
+
padding: isMobile ? "13px 14px" : isHeader ? "clamp(8px, 0.55vw, 10px) clamp(10px, 0.7vw, 14px)" : "0.5vw 0.7vw",
|
|
22508
23063
|
marginTop: isMobile ? 12 : isHeader ? 0 : "0.48vw",
|
|
22509
23064
|
cursor: "pointer",
|
|
22510
23065
|
fontFamily: "inherit",
|
|
@@ -22513,18 +23068,18 @@ function ProfileCompletionCta({
|
|
|
22513
23068
|
flexDirection: isMobile ? "column" : "row",
|
|
22514
23069
|
alignItems: isMobile ? "stretch" : "center",
|
|
22515
23070
|
justifyContent: "space-between",
|
|
22516
|
-
gap: isMobile ? 10 : isHeader ? "0.
|
|
23071
|
+
gap: isMobile ? 10 : isHeader ? "0.62vw" : "0.7vw",
|
|
22517
23072
|
boxShadow: "0 12px 28px -22px rgba(33,84,239,0.52)"
|
|
22518
23073
|
},
|
|
22519
23074
|
children: [
|
|
22520
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { display: "flex", alignItems: "center", gap: isMobile ? 10 : isHeader ? "0.
|
|
23075
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { display: "flex", alignItems: "center", gap: isMobile ? 10 : isHeader ? "0.5vw" : "0.6vw", minWidth: 0, width: isMobile || isHeader ? "100%" : "auto" }, children: [
|
|
22521
23076
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
22522
23077
|
"span",
|
|
22523
23078
|
{
|
|
22524
23079
|
"aria-hidden": "true",
|
|
22525
23080
|
style: {
|
|
22526
|
-
width: isMobile ? 32 : isHeader ? "1.
|
|
22527
|
-
height: isMobile ? 32 : isHeader ? "1.
|
|
23081
|
+
width: isMobile ? 32 : isHeader ? "clamp(26px, 1.65vw, 30px)" : "1.55vw",
|
|
23082
|
+
height: isMobile ? 32 : isHeader ? "clamp(26px, 1.65vw, 30px)" : "1.55vw",
|
|
22528
23083
|
borderRadius: "50%",
|
|
22529
23084
|
background: "var(--ps-accent)",
|
|
22530
23085
|
color: "#fff",
|
|
@@ -22533,12 +23088,12 @@ function ProfileCompletionCta({
|
|
|
22533
23088
|
justifyContent: "center",
|
|
22534
23089
|
flexShrink: 0
|
|
22535
23090
|
},
|
|
22536
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
23091
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsx(UserIcon, { size: isMobile ? 16 : isHeader ? 16 : 14 })
|
|
22537
23092
|
}
|
|
22538
23093
|
),
|
|
22539
23094
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { style: { minWidth: 0 }, children: [
|
|
22540
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "block", color: "var(--ps-text-primary)", fontSize: isMobile ? 14 : isHeader ? "0.
|
|
22541
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "block", color: "var(--ps-text-secondary)", fontSize: isMobile ? 12 : isHeader ? "0.
|
|
23095
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "block", color: "var(--ps-text-primary)", fontSize: isMobile ? 14 : isHeader ? "clamp(12px, 0.72vw, 14px)" : "0.68vw", fontWeight: 800, lineHeight: 1.15 }, children: title }),
|
|
23096
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: { display: "block", color: "var(--ps-text-secondary)", fontSize: isMobile ? 12 : isHeader ? "clamp(10px, 0.52vw, 11px)" : "0.56vw", lineHeight: 1.22, marginTop: isMobile ? 3 : "0.1vw" }, children: body })
|
|
22542
23097
|
] })
|
|
22543
23098
|
] }),
|
|
22544
23099
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
@@ -22550,7 +23105,7 @@ function ProfileCompletionCta({
|
|
|
22550
23105
|
border: isMobile ? "1px solid rgba(33,84,239,0.14)" : 0,
|
|
22551
23106
|
borderRadius: isMobile ? 999 : 0,
|
|
22552
23107
|
padding: isMobile ? "7px 10px" : 0,
|
|
22553
|
-
fontSize: isMobile ? 12 : isHeader ? "0.
|
|
23108
|
+
fontSize: isMobile ? 12 : isHeader ? "clamp(10px, 0.56vw, 11px)" : "0.62vw",
|
|
22554
23109
|
fontWeight: 800,
|
|
22555
23110
|
whiteSpace: "nowrap",
|
|
22556
23111
|
flexShrink: 0,
|
|
@@ -23168,10 +23723,10 @@ const cellValFn = (row, colIdx, header) => {
|
|
|
23168
23723
|
}
|
|
23169
23724
|
return "";
|
|
23170
23725
|
};
|
|
23171
|
-
const fitLabelFn = (fit, t2) => fit === "good" ? t2("
|
|
23726
|
+
const fitLabelFn = (fit, t2) => fit === "good" ? t2("within range") : fit === "too-tight" ? t2("too tight") : fit === "tight" ? t2("tight") : fit === "a-bit-tight" ? t2("a bit tight") : fit === "too-loose" ? t2("too loose") : fit === "loose" ? t2("loose") : t2("a bit loose");
|
|
23172
23727
|
const accessoryFitLabelFn = (fit, t2) => fit === "good" ? t2("within range") : fitLabelFn(fit, t2);
|
|
23173
23728
|
const lengthFitLabelFn = (fit, t2) => {
|
|
23174
|
-
if (fit === "good") return t2("
|
|
23729
|
+
if (fit === "good") return t2("within range");
|
|
23175
23730
|
if (fit === "too-short" || fit === "too-tight") return t2("too short");
|
|
23176
23731
|
if (fit === "short" || fit === "tight") return t2("short");
|
|
23177
23732
|
if (fit === "a-bit-short" || fit === "a-bit-tight") return t2("a bit short");
|
|
@@ -23249,6 +23804,7 @@ function SectionDetailView({
|
|
|
23249
23804
|
internationalSizes,
|
|
23250
23805
|
continueLabel,
|
|
23251
23806
|
onContinue,
|
|
23807
|
+
resultActionNode,
|
|
23252
23808
|
renderRaw = false,
|
|
23253
23809
|
sectionFound,
|
|
23254
23810
|
allSizes,
|
|
@@ -23901,7 +24457,7 @@ function SectionDetailView({
|
|
|
23901
24457
|
tryOnProcessing ? `${t2("Generating try-on…")}${tryOnElapsedS > 0 ? ` ${tryOnElapsedS}s` : ""}` : t2("Try It On")
|
|
23902
24458
|
]
|
|
23903
24459
|
}
|
|
23904
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24460
|
+
) : resultActionNode ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-action-group ps-msd-result-action-group", children: resultActionNode }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
23905
24461
|
"button",
|
|
23906
24462
|
{
|
|
23907
24463
|
type: "button",
|
|
@@ -24126,7 +24682,7 @@ function SectionDetailView({
|
|
|
24126
24682
|
tryOnProcessing ? `${t2("Generating try-on…")}${tryOnElapsedS > 0 ? ` ${tryOnElapsedS}s` : ""}` : t2("Try It On")
|
|
24127
24683
|
]
|
|
24128
24684
|
}
|
|
24129
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24685
|
+
) : resultActionNode ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-action-group", children: resultActionNode }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24130
24686
|
"button",
|
|
24131
24687
|
{
|
|
24132
24688
|
onClick: continueLabel ? onContinue || onBack : onBack,
|
|
@@ -24172,6 +24728,12 @@ function SizeResultView({
|
|
|
24172
24728
|
setView,
|
|
24173
24729
|
handleDownload,
|
|
24174
24730
|
onContinueShopping,
|
|
24731
|
+
isHistoryResult = false,
|
|
24732
|
+
onBackToProductPage,
|
|
24733
|
+
onAddToBag,
|
|
24734
|
+
addToBagLabel,
|
|
24735
|
+
continueShoppingLabel,
|
|
24736
|
+
backToProductPageLabel,
|
|
24175
24737
|
onTryOnFeedbackSubmit,
|
|
24176
24738
|
selectedFile,
|
|
24177
24739
|
previewUrl,
|
|
@@ -24203,6 +24765,101 @@ function SizeResultView({
|
|
|
24203
24765
|
const shoeUserGender = normalizeShoeGender(sizingResult?.userGender || sizingResult?.detectedGender) || void 0;
|
|
24204
24766
|
const [editVals, setEditVals] = reactExports.useState({});
|
|
24205
24767
|
const pRange = pRangeFn;
|
|
24768
|
+
const resolvedContinueShoppingLabel = continueShoppingLabel?.trim() || t2("Continue Shopping");
|
|
24769
|
+
const resolvedAddToBagLabel = addToBagLabel?.trim() || t2("Add to Bag");
|
|
24770
|
+
const resolvedBackToProductPageLabel = backToProductPageLabel?.trim() || t2("Back to product");
|
|
24771
|
+
const handleContinueAction = onContinueShopping || onClose;
|
|
24772
|
+
const handleBackToProductPageAction = onBackToProductPage || handleContinueAction;
|
|
24773
|
+
const canAddToBag = !!onAddToBag && !isHistoryResult && !!sizingResult && sizingResult.found !== false;
|
|
24774
|
+
const [addToBagState, setAddToBagState] = reactExports.useState("idle");
|
|
24775
|
+
reactExports.useEffect(() => {
|
|
24776
|
+
if (addToBagState !== "added") return;
|
|
24777
|
+
const timer = window.setTimeout(() => setAddToBagState("idle"), 1500);
|
|
24778
|
+
return () => window.clearTimeout(timer);
|
|
24779
|
+
}, [addToBagState]);
|
|
24780
|
+
const handleAddToBagClick = reactExports.useCallback(async () => {
|
|
24781
|
+
if (!onAddToBag || addToBagState !== "idle") return;
|
|
24782
|
+
setAddToBagState("adding");
|
|
24783
|
+
try {
|
|
24784
|
+
await onAddToBag();
|
|
24785
|
+
setAddToBagState("added");
|
|
24786
|
+
} catch {
|
|
24787
|
+
setAddToBagState("idle");
|
|
24788
|
+
}
|
|
24789
|
+
}, [addToBagState, onAddToBag]);
|
|
24790
|
+
const renderShoppingCta = reactExports.useCallback((options) => {
|
|
24791
|
+
if (isHistoryResult && handleBackToProductPageAction) {
|
|
24792
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-action-group ps-tryon-v2-action-group-history", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24793
|
+
"button",
|
|
24794
|
+
{
|
|
24795
|
+
className: "ps-tryon-v2-cta ps-tryon-v2-cta-secondary ps-tryon-v2-cta-compact ps-tryon-v2-history-product-cta",
|
|
24796
|
+
style: { marginTop: 0 },
|
|
24797
|
+
onClick: handleBackToProductPageAction,
|
|
24798
|
+
type: "button",
|
|
24799
|
+
children: [
|
|
24800
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(ExternalLinkIcon, { size: 13 }),
|
|
24801
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: resolvedBackToProductPageLabel })
|
|
24802
|
+
]
|
|
24803
|
+
}
|
|
24804
|
+
) });
|
|
24805
|
+
}
|
|
24806
|
+
const allowAddToBag = options?.allowAddToBag !== false;
|
|
24807
|
+
if (allowAddToBag && canAddToBag) {
|
|
24808
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-action-group", children: [
|
|
24809
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24810
|
+
"button",
|
|
24811
|
+
{
|
|
24812
|
+
className: "ps-tryon-v2-cta ps-tryon-v2-cta-secondary",
|
|
24813
|
+
style: { marginTop: 0 },
|
|
24814
|
+
onClick: handleContinueAction,
|
|
24815
|
+
type: "button",
|
|
24816
|
+
children: [
|
|
24817
|
+
resolvedContinueShoppingLabel,
|
|
24818
|
+
" →"
|
|
24819
|
+
]
|
|
24820
|
+
}
|
|
24821
|
+
),
|
|
24822
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24823
|
+
"button",
|
|
24824
|
+
{
|
|
24825
|
+
className: `ps-tryon-v2-cta ps-tryon-v2-add-bag-cta${addToBagState === "added" ? " is-added" : ""}`,
|
|
24826
|
+
style: { marginTop: 0 },
|
|
24827
|
+
onClick: handleAddToBagClick,
|
|
24828
|
+
type: "button",
|
|
24829
|
+
disabled: addToBagState !== "idle",
|
|
24830
|
+
children: [
|
|
24831
|
+
addToBagState === "added" ? /* @__PURE__ */ jsxRuntimeExports.jsx(CheckIcon$1, { size: 16 }) : /* @__PURE__ */ jsxRuntimeExports.jsx(ShoppingBagIcon, { size: 17 }),
|
|
24832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: addToBagState === "added" ? t2("Added to bag") : addToBagState === "adding" ? t2("Adding...") : resolvedAddToBagLabel })
|
|
24833
|
+
]
|
|
24834
|
+
}
|
|
24835
|
+
)
|
|
24836
|
+
] });
|
|
24837
|
+
}
|
|
24838
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24839
|
+
"button",
|
|
24840
|
+
{
|
|
24841
|
+
className: "ps-tryon-v2-cta",
|
|
24842
|
+
style: { marginTop: 0 },
|
|
24843
|
+
onClick: handleContinueAction,
|
|
24844
|
+
type: "button",
|
|
24845
|
+
children: [
|
|
24846
|
+
resolvedContinueShoppingLabel,
|
|
24847
|
+
" →"
|
|
24848
|
+
]
|
|
24849
|
+
}
|
|
24850
|
+
);
|
|
24851
|
+
}, [
|
|
24852
|
+
canAddToBag,
|
|
24853
|
+
addToBagState,
|
|
24854
|
+
handleBackToProductPageAction,
|
|
24855
|
+
handleAddToBagClick,
|
|
24856
|
+
handleContinueAction,
|
|
24857
|
+
isHistoryResult,
|
|
24858
|
+
resolvedAddToBagLabel,
|
|
24859
|
+
resolvedBackToProductPageLabel,
|
|
24860
|
+
resolvedContinueShoppingLabel,
|
|
24861
|
+
t2
|
|
24862
|
+
]);
|
|
24206
24863
|
const cellVal = reactExports.useCallback((row, colIdx, header) => {
|
|
24207
24864
|
return cellValFn(row, colIdx, header);
|
|
24208
24865
|
}, []);
|
|
@@ -24691,7 +25348,8 @@ function SizeResultView({
|
|
|
24691
25348
|
return lengthEntries.find((le2) => le2.section.headers.some((h) => /height|altezza|estatura|\(cm\)/i.test(h))) || null;
|
|
24692
25349
|
})(),
|
|
24693
25350
|
onBack: () => setActiveSection(null),
|
|
24694
|
-
onContinue:
|
|
25351
|
+
onContinue: handleContinueAction,
|
|
25352
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
24695
25353
|
internationalSizes: entry.secResult?.internationalSizes,
|
|
24696
25354
|
productImage: tryOnProcessing && previewUrl ? previewUrl : resultImageUrl || productImage,
|
|
24697
25355
|
productTitle,
|
|
@@ -24791,7 +25449,8 @@ function SizeResultView({
|
|
|
24791
25449
|
return lengthEntries.find((le2) => le2.section.headers.some((h) => /height|altezza|estatura|\(cm\)/i.test(h))) || null;
|
|
24792
25450
|
})(),
|
|
24793
25451
|
onBack: () => setActiveSection(null),
|
|
24794
|
-
onContinue:
|
|
25452
|
+
onContinue: handleContinueAction,
|
|
25453
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
24795
25454
|
internationalSizes: entry.secResult?.internationalSizes,
|
|
24796
25455
|
tryOnProcessing,
|
|
24797
25456
|
tryOnStartedAt,
|
|
@@ -24834,7 +25493,8 @@ function SizeResultView({
|
|
|
24834
25493
|
setGuideFile(selectedFile || null);
|
|
24835
25494
|
setShowPhotoGuide(true);
|
|
24836
25495
|
},
|
|
24837
|
-
onClose:
|
|
25496
|
+
onClose: handleContinueAction,
|
|
25497
|
+
resultActionNode: canAddToBag || isHistoryResult ? renderShoppingCta() : void 0,
|
|
24838
25498
|
showLines,
|
|
24839
25499
|
onToggleLines: suppressFitOverlayActions ? void 0 : () => setShowLines(!showLines),
|
|
24840
25500
|
onOpenImage: resultImageUrl && !tryOnProcessing ? () => setZoomImageUrl(resultImageUrl) : void 0,
|
|
@@ -24929,7 +25589,7 @@ function SizeResultView({
|
|
|
24929
25589
|
] }),
|
|
24930
25590
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-v2-panel ps-tryon-v2-result-panel", children: [
|
|
24931
25591
|
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: [
|
|
24932
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your
|
|
25592
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-v2-title", children: t2("Your Size Recommendation") }),
|
|
24933
25593
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-v2-subtitle", children: t2("Tap any section for detailed breakdown") })
|
|
24934
25594
|
] }),
|
|
24935
25595
|
mismatchNotice,
|
|
@@ -24978,29 +25638,7 @@ function SizeResultView({
|
|
|
24978
25638
|
" ",
|
|
24979
25639
|
t2("Back")
|
|
24980
25640
|
] }),
|
|
24981
|
-
resultImageUrl && !tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24982
|
-
"button",
|
|
24983
|
-
{
|
|
24984
|
-
className: "ps-tryon-v2-cta",
|
|
24985
|
-
style: { marginTop: 0 },
|
|
24986
|
-
onClick: onContinueShopping || onClose,
|
|
24987
|
-
children: [
|
|
24988
|
-
t2("Continue Shopping"),
|
|
24989
|
-
" →"
|
|
24990
|
-
]
|
|
24991
|
-
}
|
|
24992
|
-
) : vtoExcluded ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
24993
|
-
"button",
|
|
24994
|
-
{
|
|
24995
|
-
className: "ps-tryon-v2-cta",
|
|
24996
|
-
style: { marginTop: 0 },
|
|
24997
|
-
onClick: onContinueShopping || onClose,
|
|
24998
|
-
children: [
|
|
24999
|
-
t2("Continue Shopping"),
|
|
25000
|
-
" →"
|
|
25001
|
-
]
|
|
25002
|
-
}
|
|
25003
|
-
) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25641
|
+
canAddToBag || isHistoryResult || resultImageUrl && !tryOnProcessing || vtoExcluded ? renderShoppingCta() : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25004
25642
|
"button",
|
|
25005
25643
|
{
|
|
25006
25644
|
className: "ps-tryon-v2-cta",
|
|
@@ -25064,11 +25702,12 @@ function SizeResultView({
|
|
|
25064
25702
|
if (resultImageUrl) onResetTryOn?.();
|
|
25065
25703
|
setView("body-profile");
|
|
25066
25704
|
},
|
|
25067
|
-
onContinue:
|
|
25705
|
+
onContinue: handleContinueAction,
|
|
25068
25706
|
backLabel: t2("Back"),
|
|
25069
25707
|
internationalSizes: singleInternationalSizes,
|
|
25070
|
-
onTryOn: resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
25071
|
-
|
|
25708
|
+
onTryOn: canAddToBag || isHistoryResult || resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
25709
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
25710
|
+
continueLabel: resultImageUrl ? resolvedContinueShoppingLabel : void 0,
|
|
25072
25711
|
tryOnProcessing,
|
|
25073
25712
|
tryOnStartedAt,
|
|
25074
25713
|
productImage: resultImageUrl || productImage,
|
|
@@ -25158,18 +25797,14 @@ function SizeResultView({
|
|
|
25158
25797
|
chartUnit: resultUnit,
|
|
25159
25798
|
lengthEntry: null,
|
|
25160
25799
|
onBack: () => {
|
|
25161
|
-
|
|
25162
|
-
onResetTryOn?.();
|
|
25163
|
-
setView("body-profile");
|
|
25164
|
-
} else {
|
|
25165
|
-
setActiveSection(null);
|
|
25166
|
-
}
|
|
25800
|
+
setActiveSection(null);
|
|
25167
25801
|
},
|
|
25168
|
-
onContinue:
|
|
25802
|
+
onContinue: handleContinueAction,
|
|
25169
25803
|
backLabel: t2("Back"),
|
|
25170
25804
|
internationalSizes: singleInternationalSizes,
|
|
25171
|
-
onTryOn: resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
25172
|
-
|
|
25805
|
+
onTryOn: canAddToBag || isHistoryResult || resultImageUrl || vtoExcluded ? void 0 : handleSingleTryOn,
|
|
25806
|
+
resultActionNode: canAddToBag || isHistoryResult || !!resultImageUrl || vtoExcluded ? renderShoppingCta() : void 0,
|
|
25807
|
+
continueLabel: resultImageUrl ? resolvedContinueShoppingLabel : void 0,
|
|
25173
25808
|
tryOnProcessing,
|
|
25174
25809
|
tryOnStartedAt,
|
|
25175
25810
|
onFeedbackSubmit: onTryOnFeedbackSubmit,
|
|
@@ -25185,35 +25820,35 @@ function SizeResultView({
|
|
|
25185
25820
|
) : (
|
|
25186
25821
|
/* CARD VIEW — clickable summary card + gallery strip */
|
|
25187
25822
|
/* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
25188
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-result-head", children:
|
|
25189
|
-
|
|
25190
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-v2-subtitle", children: guideOnlyResult ? t2("Tap the card to view product measurements") : t2("Tap the card for detailed breakdown") })
|
|
25191
|
-
] }) }),
|
|
25192
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-sep" }),
|
|
25823
|
+
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 }) }) }) : null,
|
|
25824
|
+
profileCompletionCta ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-v2-sep" }) : null,
|
|
25193
25825
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-sr-cards-v2", children: /* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
25194
25826
|
"button",
|
|
25195
25827
|
{
|
|
25196
|
-
className: `ps-tryon-sr-card-v2 ps-full${pendingCustomSizes[sectionName] ? " ps-overridden" : ""}`,
|
|
25828
|
+
className: `ps-tryon-sr-card-v2 ps-summary-card ps-full${pendingCustomSizes[sectionName] ? " ps-overridden" : ""}`,
|
|
25197
25829
|
onClick: () => setActiveSection(sectionName),
|
|
25198
25830
|
type: "button",
|
|
25199
|
-
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-card-v2-text", children: [
|
|
25200
|
-
/* @__PURE__ */ jsxRuntimeExports.
|
|
25201
|
-
|
|
25202
|
-
|
|
25203
|
-
|
|
25204
|
-
|
|
25205
|
-
|
|
25206
|
-
|
|
25207
|
-
|
|
25208
|
-
|
|
25209
|
-
|
|
25210
|
-
|
|
25211
|
-
|
|
25212
|
-
|
|
25213
|
-
|
|
25214
|
-
|
|
25215
|
-
|
|
25216
|
-
|
|
25831
|
+
children: /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-sr-card-v2-text ps-summary-card-layout", children: [
|
|
25832
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ps-summary-card-copy", children: [
|
|
25833
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-tryon-sr-card-v2-summary-title", children: guideOnlyResult ? t2("Product Size Guide") : t2("Recommended size") }),
|
|
25834
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ps-tryon-sr-card-v2-main", children: [
|
|
25835
|
+
(() => {
|
|
25836
|
+
const rawLabelText = pendingCustomSizes[sectionName]?.displayLabel || singleResult.recommendedSize || singleResult.sizeLabel || (guideOnlyResult ? t2("One Size") : "—");
|
|
25837
|
+
const labelText = measurementType === "foot" ? formatShoeSizeLabel(rawLabelText, shoeUserGender) : rawLabelText;
|
|
25838
|
+
const isLong = labelText.length > 12;
|
|
25839
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: `ps-tryon-sr-card-v2-value${isLong ? " ps-long" : ""}`, children: labelText });
|
|
25840
|
+
})(),
|
|
25841
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
25842
|
+
"span",
|
|
25843
|
+
{
|
|
25844
|
+
className: `ps-tryon-sr-card-v2-rec-pill${pendingCustomSizes[sectionName] ? " is-overridden" : ""}`,
|
|
25845
|
+
children: guideOnlyResult ? t2("SIZE GUIDE") : pendingCustomSizes[sectionName] ? t2("YOUR SELECTION") : t2("RECOMMENDED")
|
|
25846
|
+
}
|
|
25847
|
+
)
|
|
25848
|
+
] })
|
|
25849
|
+
] }),
|
|
25850
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("span", { className: "ps-tryon-sr-card-v2-open-pill", children: [
|
|
25851
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: guideOnlyResult ? t2("View chart") : t2("View measurements") }),
|
|
25217
25852
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { "aria-hidden": "true", children: "›" })
|
|
25218
25853
|
] })
|
|
25219
25854
|
] })
|
|
@@ -25237,13 +25872,7 @@ function SizeResultView({
|
|
|
25237
25872
|
]
|
|
25238
25873
|
}
|
|
25239
25874
|
),
|
|
25240
|
-
resultImageUrl && !tryOnProcessing ? /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25241
|
-
t2("Continue Shopping"),
|
|
25242
|
-
" →"
|
|
25243
|
-
] }) : vtoExcluded ? /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { className: "ps-tryon-v2-cta", style: { marginTop: 0 }, onClick: onContinueShopping || onClose, children: [
|
|
25244
|
-
t2("Continue Shopping"),
|
|
25245
|
-
" →"
|
|
25246
|
-
] }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25875
|
+
canAddToBag || isHistoryResult || resultImageUrl && !tryOnProcessing || vtoExcluded ? renderShoppingCta() : /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
25247
25876
|
"button",
|
|
25248
25877
|
{
|
|
25249
25878
|
className: "ps-tryon-v2-cta",
|
|
@@ -26048,7 +26677,7 @@ function ProcessingView({
|
|
|
26048
26677
|
}
|
|
26049
26678
|
}, []);
|
|
26050
26679
|
const aiFacts = [
|
|
26051
|
-
t2("Our model is analyzing 150+ body landmarks for
|
|
26680
|
+
t2("Our model is analyzing 150+ body landmarks for your size recommendation"),
|
|
26052
26681
|
t2("Calibrating fabric drape against your body proportions"),
|
|
26053
26682
|
t2("Cross-checking fit against millions of garment patterns"),
|
|
26054
26683
|
t2("Rendering shadows and highlights to match your photo's lighting")
|
|
@@ -26151,20 +26780,22 @@ function ProcessingView({
|
|
|
26151
26780
|
function NoChartView({
|
|
26152
26781
|
productImage,
|
|
26153
26782
|
productTitle,
|
|
26783
|
+
reason = "no-chart",
|
|
26154
26784
|
onTryOn,
|
|
26155
26785
|
onClose,
|
|
26156
26786
|
t: t2
|
|
26157
26787
|
}) {
|
|
26158
26788
|
const isMobile = useIsMobile();
|
|
26789
|
+
const isNoMatch = reason === "no-match";
|
|
26159
26790
|
const RightColumn = /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-no-chart-content", children: [
|
|
26160
26791
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-tryon-no-chart-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: [
|
|
26161
26792
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M3 17l6 6 12-12-6-6L3 17z" }),
|
|
26162
26793
|
/* @__PURE__ */ jsxRuntimeExports.jsx("path", { d: "M14 4l-3 3M16 6l-2 2M18 8l-2 2M11 7l-2 2M13 9l-2 2M15 11l-2 2" })
|
|
26163
26794
|
] }) }),
|
|
26164
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-no-chart-title", children: t2("No size chart available") }),
|
|
26165
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-no-chart-msg", children: t2("The merchant hasn't uploaded sizing data for this product yet. You can still see how it looks on you with a virtual try-on.") }),
|
|
26795
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { className: "ps-tryon-no-chart-title", children: isNoMatch ? t2("No matching size available") : t2("No size chart available") }),
|
|
26796
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-tryon-no-chart-msg", children: isNoMatch ? t2("This product's size chart doesn't include a reliable fit for your measurements.") : t2("The merchant hasn't uploaded sizing data for this product yet. You can still see how it looks on you with a virtual try-on.") }),
|
|
26166
26797
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-tryon-no-chart-actions", children: [
|
|
26167
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-tryon-no-chart-cta", onClick: onTryOn, children: [
|
|
26798
|
+
!isNoMatch && /* @__PURE__ */ jsxRuntimeExports.jsxs("button", { type: "button", className: "ps-tryon-no-chart-cta", onClick: onTryOn, children: [
|
|
26168
26799
|
t2("See how it looks on you"),
|
|
26169
26800
|
" →"
|
|
26170
26801
|
] }),
|
|
@@ -26348,11 +26979,12 @@ function ProgressiveStep({
|
|
|
26348
26979
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-cpw-card-row", children })
|
|
26349
26980
|
] }, stepKey);
|
|
26350
26981
|
}
|
|
26351
|
-
function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiUrl, apiKey, onPhotoPreview, onEstimate, t: t2 }) {
|
|
26982
|
+
function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, directAnalysisFlow = false, apiUrl, apiKey, onPhotoPreview, onEstimate, t: t2 }) {
|
|
26352
26983
|
const seededUnit = draftUnit(initialDraft);
|
|
26353
26984
|
const seededHeight = draftHeightParts(initialDraft, seededUnit);
|
|
26354
26985
|
const seededGender = initialDraft?.gender === "female" ? "female" : "male";
|
|
26355
26986
|
const seededPhotoRef = reactExports.useRef(initialDraft?.photoBase64 || initialDraft?.photoUrl || null);
|
|
26987
|
+
const seededMeasurements = initialDraft?.measurements && Object.keys(initialDraft.measurements).length > 0 ? initialDraft.measurements : null;
|
|
26356
26988
|
const [mode, setMode] = reactExports.useState(initialMode ?? null);
|
|
26357
26989
|
const [manualStep, setManualStep] = reactExports.useState("identity");
|
|
26358
26990
|
const [imageStep, setImageStep] = reactExports.useState("name-photo");
|
|
@@ -26383,6 +27015,7 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26383
27015
|
const [scanStageIdx, setScanStageIdx] = reactExports.useState(0);
|
|
26384
27016
|
const [photoHelpOpen, setPhotoHelpOpen] = reactExports.useState(false);
|
|
26385
27017
|
const [uploadHoverCpw, setUploadHoverCpw] = reactExports.useState(false);
|
|
27018
|
+
const directAutoStartedRef = reactExports.useRef(false);
|
|
26386
27019
|
reactExports.useEffect(() => {
|
|
26387
27020
|
if (imageStep !== "calculating" || !photoBase64) return;
|
|
26388
27021
|
let cancelled = false;
|
|
@@ -26571,6 +27204,7 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26571
27204
|
bandSize: isWomen ? bandSize || void 0 : void 0,
|
|
26572
27205
|
cupSize: isWomen ? cupSize || void 0 : void 0,
|
|
26573
27206
|
...isWomen && bandSize && cupSize ? { braSizeRegion } : {},
|
|
27207
|
+
...initialDraft?.measurements ? { measurements: initialDraft.measurements, measurementsUnit: initialDraft.measurementsUnit || "cm" } : {},
|
|
26574
27208
|
...initialDraft?.customMeasurements ? { customMeasurements: initialDraft.customMeasurements } : {}
|
|
26575
27209
|
};
|
|
26576
27210
|
};
|
|
@@ -26590,6 +27224,7 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26590
27224
|
...isWomen && bandSize ? { bandSize } : {},
|
|
26591
27225
|
...isWomen && cupSize ? { cupSize } : {},
|
|
26592
27226
|
...isWomen && bandSize && cupSize ? { braSizeRegion } : {},
|
|
27227
|
+
...initialDraft?.measurements ? { measurements: initialDraft.measurements, measurementsUnit: initialDraft.measurementsUnit || "cm" } : {},
|
|
26593
27228
|
...initialDraft?.customMeasurements ? { customMeasurements: initialDraft.customMeasurements } : {},
|
|
26594
27229
|
photoBase64: photoBase64 || void 0
|
|
26595
27230
|
};
|
|
@@ -26662,13 +27297,14 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26662
27297
|
setError(t2("Please upload a photo"));
|
|
26663
27298
|
return;
|
|
26664
27299
|
}
|
|
26665
|
-
|
|
27300
|
+
const canUseSeededMeasurements = directAnalysisFlow && !!seededMeasurements;
|
|
27301
|
+
if (!canUseSeededMeasurements && unit === "in") {
|
|
26666
27302
|
const ft = parseFloat(heightFt);
|
|
26667
27303
|
if (!ft || ft < 3 || ft > 8) {
|
|
26668
27304
|
setError(t2("Please enter a valid height"));
|
|
26669
27305
|
return;
|
|
26670
27306
|
}
|
|
26671
|
-
} else {
|
|
27307
|
+
} else if (!canUseSeededMeasurements) {
|
|
26672
27308
|
const cm = parseFloat(heightVal);
|
|
26673
27309
|
if (!cm || cm < 100 || cm > 250) {
|
|
26674
27310
|
setError(t2("Please enter a valid height"));
|
|
@@ -26676,12 +27312,12 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26676
27312
|
}
|
|
26677
27313
|
}
|
|
26678
27314
|
const w2 = parseFloat(weightVal);
|
|
26679
|
-
if (!w2 || w2 <= 0) {
|
|
27315
|
+
if (!canUseSeededMeasurements && (!w2 || w2 <= 0)) {
|
|
26680
27316
|
setError(t2("Please enter a valid weight"));
|
|
26681
27317
|
return;
|
|
26682
27318
|
}
|
|
26683
27319
|
const a = parseFloat(ageVal);
|
|
26684
|
-
if (isWomen && (!bandSize || !cupSize)) {
|
|
27320
|
+
if (isWomen && !directAnalysisFlow && (!bandSize || !cupSize)) {
|
|
26685
27321
|
setError(t2("Please select your bra band and cup size"));
|
|
26686
27322
|
return;
|
|
26687
27323
|
}
|
|
@@ -26690,8 +27326,8 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26690
27326
|
setEstimating(true);
|
|
26691
27327
|
const MIN_HOLD_MS = 6e3;
|
|
26692
27328
|
const minHold = new Promise((r2) => setTimeout(r2, MIN_HOLD_MS));
|
|
26693
|
-
let liveEstimates =
|
|
26694
|
-
if (onEstimate && photoBase64) {
|
|
27329
|
+
let liveEstimates = seededMeasurements;
|
|
27330
|
+
if (!canUseSeededMeasurements && onEstimate && photoBase64) {
|
|
26695
27331
|
const heightRaw = unit === "in" ? (parseInt(heightFt, 10) || 0) * 12 + (parseInt(heightInch, 10) || 0) : parseFloat(heightVal);
|
|
26696
27332
|
try {
|
|
26697
27333
|
const result = await onEstimate({
|
|
@@ -26731,6 +27367,16 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26731
27367
|
}
|
|
26732
27368
|
onSave(payload);
|
|
26733
27369
|
};
|
|
27370
|
+
reactExports.useEffect(() => {
|
|
27371
|
+
if (!directAnalysisFlow || directAutoStartedRef.current) return;
|
|
27372
|
+
if (mode !== "image" || imageStep !== "name-photo") return;
|
|
27373
|
+
const hasHeight = unit === "in" ? parseFloat(heightFt) > 0 || parseFloat(heightInch) > 0 : parseFloat(heightVal) > 0;
|
|
27374
|
+
const hasWeight = parseFloat(weightVal) > 0;
|
|
27375
|
+
const canUseSeededMeasurements = directAnalysisFlow && !!seededMeasurements;
|
|
27376
|
+
if (!photoBase64 || !name.trim() || !canUseSeededMeasurements && (!hasHeight || !hasWeight)) return;
|
|
27377
|
+
directAutoStartedRef.current = true;
|
|
27378
|
+
void advanceImage();
|
|
27379
|
+
}, [directAnalysisFlow, mode, imageStep, photoBase64, name, heightFt, heightInch, heightVal, weightVal, unit]);
|
|
26734
27380
|
const goBackImage = () => {
|
|
26735
27381
|
setError("");
|
|
26736
27382
|
if (imageStep === "details") {
|
|
@@ -26772,9 +27418,12 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
26772
27418
|
if (photoBase64) pct += 50;
|
|
26773
27419
|
return pct;
|
|
26774
27420
|
})();
|
|
26775
|
-
const hideGlobalBack = mode === "image" && imageStep === "name-photo";
|
|
26776
|
-
|
|
26777
|
-
|
|
27421
|
+
const hideGlobalBack = mode === "image" && imageStep === "name-photo" && !directAnalysisFlow;
|
|
27422
|
+
const hideStepHeader = directAnalysisFlow && mode === "image";
|
|
27423
|
+
const hideFooter = directAnalysisFlow && mode === "image" && imageStep === "calculating" && estimating;
|
|
27424
|
+
const hideFooterBack = directAnalysisFlow && mode === "image";
|
|
27425
|
+
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-cpw-root${hideGlobalBack ? " ps-cpw-hide-global-back" : ""}${directAnalysisFlow ? " ps-cpw-direct-flow" : ""}`, children: [
|
|
27426
|
+
!hideStepHeader && !(mode === "image" && imageStep === "name-photo") && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-cpw-step-head", children: [
|
|
26778
27427
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-cpw-step-title", children: headerLabel }),
|
|
26779
27428
|
mode != null && /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-cpw-progress", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-cpw-progress-track", children: /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-cpw-progress-fill", style: { width: `${progressPct}%` } }) }) })
|
|
26780
27429
|
] }),
|
|
@@ -27702,7 +28351,7 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
27702
28351
|
mode === "image" && imageStep === "calculating" && (() => {
|
|
27703
28352
|
const stages = [
|
|
27704
28353
|
{ title: t2("DETECTING POSE"), desc: t2("Identifying body landmarks from your photo.") },
|
|
27705
|
-
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions
|
|
28354
|
+
{ title: t2("SCANNING FRAME"), desc: t2("Our AI is mapping your proportions for a size recommendation.") },
|
|
27706
28355
|
{ title: t2("ANALYZING BODY"), desc: t2("Measuring shoulders, chest, waist and hips.") },
|
|
27707
28356
|
{ title: t2("MATCHING SIZE"), desc: t2("Comparing your measurements to the size guide.") },
|
|
27708
28357
|
{ title: t2("FINALIZING RESULT"), desc: t2("Almost done — preparing your recommendation.") }
|
|
@@ -27790,13 +28439,13 @@ function CreateProfileWizard({ onSave, onCancel, initialMode, initialDraft, apiU
|
|
|
27790
28439
|
] }) }, "image-calculating");
|
|
27791
28440
|
})()
|
|
27792
28441
|
] }),
|
|
27793
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-cpw-footer"
|
|
27794
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-cpw-back-btn", onClick: handleBack, children: mode == null ? t2("Cancel") : `← ${t2("Back")}` }),
|
|
28442
|
+
!hideFooter && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-cpw-footer${hideFooterBack ? " ps-cpw-footer-no-back" : ""}`, children: [
|
|
28443
|
+
!hideFooterBack && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-cpw-back-btn", onClick: handleBack, children: mode == null ? t2("Cancel") : `← ${t2("Back")}` }),
|
|
27795
28444
|
mode === "manual" && !isAutoAdvanceStep && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-cpw-next-btn", onClick: advanceManual, children: isLastManualStep ? t2("CALCULATE MY FIT") : t2("Continue") }),
|
|
27796
28445
|
mode === "image" && imageStep === "name-photo" && (() => {
|
|
27797
28446
|
const heightOk = unit === "in" ? parseFloat(heightFt) > 0 || parseFloat(heightInch) > 0 : parseFloat(heightVal) > 0;
|
|
27798
28447
|
const weightOk = parseFloat(weightVal) > 0;
|
|
27799
|
-
const braOk = !isWomen || !!bandSize && !!cupSize;
|
|
28448
|
+
const braOk = !isWomen || directAnalysisFlow || !!bandSize && !!cupSize;
|
|
27800
28449
|
const nameOk = !!name.trim();
|
|
27801
28450
|
const photoOk = !!photoBase64;
|
|
27802
28451
|
const analyzing = photoUploading;
|
|
@@ -28252,6 +28901,7 @@ function MySizingProfilesView({
|
|
|
28252
28901
|
apiKey,
|
|
28253
28902
|
initialMode: initialCreateDraft ? "image" : void 0,
|
|
28254
28903
|
initialDraft: initialCreateDraft,
|
|
28904
|
+
directAnalysisFlow: !!initialCreateDraft,
|
|
28255
28905
|
onSave: (data) => {
|
|
28256
28906
|
onSaveNewProfile(data);
|
|
28257
28907
|
onProfileDraftConsumed?.();
|
|
@@ -28488,14 +29138,13 @@ function BasicsStepMobile({
|
|
|
28488
29138
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-bpm-title", children: t2("Body Measurements") }),
|
|
28489
29139
|
/* @__PURE__ */ jsxRuntimeExports.jsx("p", { className: "ps-bpm-subtitle", children: t2("Enter your details for a bespoke size recommendation") })
|
|
28490
29140
|
] }),
|
|
28491
|
-
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
28492
|
-
|
|
28493
|
-
|
|
28494
|
-
|
|
28495
|
-
|
|
28496
|
-
|
|
28497
|
-
|
|
28498
|
-
] })
|
|
29141
|
+
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card", children: [
|
|
29142
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card-copy", children: [
|
|
29143
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-profile-card-eyebrow", children: t2("Active Profile") }),
|
|
29144
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: activeProfileName }),
|
|
29145
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("Using saved measurements for this fit.") })
|
|
29146
|
+
] }),
|
|
29147
|
+
onStartFresh && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-bp-profile-card-action", onClick: onStartFresh, children: t2("Start Fresh") })
|
|
28499
29148
|
] }),
|
|
28500
29149
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bpm-toggle", children: [
|
|
28501
29150
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -28693,6 +29342,7 @@ function PhotoStepMobile({
|
|
|
28693
29342
|
photoStatus,
|
|
28694
29343
|
photoRejection,
|
|
28695
29344
|
onClearRejection,
|
|
29345
|
+
photoHelpSlot,
|
|
28696
29346
|
bodyContextSlot,
|
|
28697
29347
|
hideTabs = false,
|
|
28698
29348
|
t: t2
|
|
@@ -28717,6 +29367,7 @@ function PhotoStepMobile({
|
|
|
28717
29367
|
}
|
|
28718
29368
|
),
|
|
28719
29369
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-pm-preview${compactAgeGate ? " ps-pm-preview-tall" : ""}`, children: [
|
|
29370
|
+
!hasPhoto && photoHelpSlot,
|
|
28720
29371
|
hasPhoto ? /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
28721
29372
|
/* @__PURE__ */ jsxRuntimeExports.jsx("img", { src: photoPreview, alt: t2("Your photo"), className: "ps-pm-preview-img" }),
|
|
28722
29373
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
@@ -29273,6 +29924,7 @@ function BodyProfileView({
|
|
|
29273
29924
|
basicOnly = false,
|
|
29274
29925
|
initialStep,
|
|
29275
29926
|
simplePhotoOnly = false,
|
|
29927
|
+
simpleAccessoryLayout = false,
|
|
29276
29928
|
simpleQuestionMode = "heightWeight",
|
|
29277
29929
|
formRef,
|
|
29278
29930
|
sizingCountry,
|
|
@@ -29437,6 +30089,7 @@ function BodyProfileView({
|
|
|
29437
30089
|
setPhotoProcessing(true);
|
|
29438
30090
|
setPhotoStatus(t2("Analyzing photo…"));
|
|
29439
30091
|
setPhotoFile(file);
|
|
30092
|
+
setPhotoHelpOpen(false);
|
|
29440
30093
|
const previewUrl = URL.createObjectURL(file);
|
|
29441
30094
|
setPhotoPreview(previewUrl);
|
|
29442
30095
|
try {
|
|
@@ -29555,6 +30208,9 @@ function BodyProfileView({
|
|
|
29555
30208
|
formRef.current.weight = String(weightVal);
|
|
29556
30209
|
formRef.current.gender = gender;
|
|
29557
30210
|
if (age) formRef.current.age = age;
|
|
30211
|
+
if (chestProfile) formRef.current.chestProfile = chestProfile;
|
|
30212
|
+
if (midsectionProfile) formRef.current.midsectionProfile = midsectionProfile;
|
|
30213
|
+
if (hipProfile) formRef.current.hipProfile = hipProfile;
|
|
29558
30214
|
if (bandSize) formRef.current.bandSize = bandSize;
|
|
29559
30215
|
if (cupSize) formRef.current.cupSize = cupSize;
|
|
29560
30216
|
if (braSizeRegion) formRef.current.braSizeRegion = braSizeRegion;
|
|
@@ -29611,6 +30267,9 @@ function BodyProfileView({
|
|
|
29611
30267
|
weightUnit: isShoeReferenceMode ? "kg" : wUnit,
|
|
29612
30268
|
gender,
|
|
29613
30269
|
...ageForSubmit ? { age: ageForSubmit } : {},
|
|
30270
|
+
...chestProfile ? { chestProfile } : {},
|
|
30271
|
+
...midsectionProfile ? { midsectionProfile } : {},
|
|
30272
|
+
...hipProfile ? { hipProfile } : {},
|
|
29614
30273
|
...currentShoeReference ? {
|
|
29615
30274
|
extraMeasurements: {
|
|
29616
30275
|
referenceShoeBrandId: currentShoeReference.brandId,
|
|
@@ -30057,6 +30716,7 @@ function BodyProfileView({
|
|
|
30057
30716
|
}
|
|
30058
30717
|
const analyzeDisabled = analyzeMissing.length > 0;
|
|
30059
30718
|
const analyzeLabel = analyzeDisabled ? analyzeMissing[0] ?? t2("Analyze My Size") : t2("Analyze My Size");
|
|
30719
|
+
const compactHeightWeightAccessory = simplePhotoOnly && simpleAccessoryLayout && !isShoeReferenceMode;
|
|
30060
30720
|
if (isMobile) {
|
|
30061
30721
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-wrapper", children: [
|
|
30062
30722
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-scan-progress", children: [
|
|
@@ -30074,19 +30734,6 @@ function BodyProfileView({
|
|
|
30074
30734
|
] }),
|
|
30075
30735
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-scan-progress-spacer", "aria-hidden": "true" })
|
|
30076
30736
|
] }),
|
|
30077
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bp-scan-help-row", children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30078
|
-
"button",
|
|
30079
|
-
{
|
|
30080
|
-
type: "button",
|
|
30081
|
-
onClick: () => setPhotoHelpOpen((v2) => !v2),
|
|
30082
|
-
"aria-label": t2("How to take a good photo"),
|
|
30083
|
-
className: `ps-pm-help-pill ps-bp-scan-help-pill${photoHelpOpen ? " ps-active" : ""}`,
|
|
30084
|
-
children: [
|
|
30085
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-pm-help-pill-q", "aria-hidden": "true", children: "?" }),
|
|
30086
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("How to take a good photo") })
|
|
30087
|
-
]
|
|
30088
|
-
}
|
|
30089
|
-
) }),
|
|
30090
30737
|
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30091
30738
|
PhotoStepMobile,
|
|
30092
30739
|
{
|
|
@@ -30111,11 +30758,27 @@ function BodyProfileView({
|
|
|
30111
30758
|
photoStatus,
|
|
30112
30759
|
photoRejection,
|
|
30113
30760
|
onClearRejection: () => setPhotoRejection(null),
|
|
30761
|
+
photoHelpSlot: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30762
|
+
"button",
|
|
30763
|
+
{
|
|
30764
|
+
type: "button",
|
|
30765
|
+
onClick: (e) => {
|
|
30766
|
+
e.stopPropagation();
|
|
30767
|
+
setPhotoHelpOpen((v2) => !v2);
|
|
30768
|
+
},
|
|
30769
|
+
"aria-label": t2("How to take a good photo"),
|
|
30770
|
+
className: `ps-bp-photo-help-chip${photoHelpOpen ? " ps-active" : ""}`,
|
|
30771
|
+
children: [
|
|
30772
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-photo-help-chip-mark", "aria-hidden": "true", children: "?" }),
|
|
30773
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("How to take a good photo") })
|
|
30774
|
+
]
|
|
30775
|
+
}
|
|
30776
|
+
),
|
|
30114
30777
|
hideTabs: simplePhotoOnly,
|
|
30115
30778
|
t: t2
|
|
30116
30779
|
}
|
|
30117
30780
|
),
|
|
30118
|
-
photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
30781
|
+
!photoPreview && photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
30119
30782
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bp-photo-help-backdrop", onClick: () => setPhotoHelpOpen(false), "aria-hidden": "true" }),
|
|
30120
30783
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { role: "dialog", "aria-label": t2("How to take the best photo"), className: "ps-bp-photo-help", children: [
|
|
30121
30784
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bp-photo-help-handle", "aria-hidden": "true" }),
|
|
@@ -30175,7 +30838,7 @@ function BodyProfileView({
|
|
|
30175
30838
|
] });
|
|
30176
30839
|
}
|
|
30177
30840
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-wrapper", children: [
|
|
30178
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", gap: "1.2vw", padding: "1.5vw", width: "100%",
|
|
30841
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { display: "flex", gap: "1.2vw", padding: "1.5vw", width: "100%", flex: "1 1 auto", minHeight: 0, alignItems: "stretch", position: "relative", overflow: "hidden" }, children: [
|
|
30179
30842
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: { flex: 1, position: "relative", display: "flex", flexDirection: "column", gap: "0.7vw" }, children: /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30180
30843
|
"div",
|
|
30181
30844
|
{
|
|
@@ -30233,6 +30896,95 @@ function BodyProfileView({
|
|
|
30233
30896
|
overflow: "hidden"
|
|
30234
30897
|
},
|
|
30235
30898
|
children: [
|
|
30899
|
+
!photoPreview && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30900
|
+
"button",
|
|
30901
|
+
{
|
|
30902
|
+
type: "button",
|
|
30903
|
+
onClick: (e) => {
|
|
30904
|
+
e.stopPropagation();
|
|
30905
|
+
setPhotoHelpOpen((v2) => !v2);
|
|
30906
|
+
},
|
|
30907
|
+
"aria-label": t2("How to take a good photo"),
|
|
30908
|
+
title: t2("How to take a good photo"),
|
|
30909
|
+
className: `ps-bp-photo-help-chip${photoHelpOpen ? " ps-active" : ""}`,
|
|
30910
|
+
children: [
|
|
30911
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-photo-help-chip-mark", "aria-hidden": "true", children: "?" }),
|
|
30912
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("How to take a good photo") })
|
|
30913
|
+
]
|
|
30914
|
+
}
|
|
30915
|
+
),
|
|
30916
|
+
!photoPreview && photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30917
|
+
"div",
|
|
30918
|
+
{
|
|
30919
|
+
role: "dialog",
|
|
30920
|
+
"aria-label": t2("How to take the best photo"),
|
|
30921
|
+
className: "ps-bp-photo-help ps-bp-photo-help-upload",
|
|
30922
|
+
onClick: (e) => e.stopPropagation(),
|
|
30923
|
+
children: [
|
|
30924
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bp-photo-help-handle", "aria-hidden": "true" }),
|
|
30925
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-header", children: [
|
|
30926
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-photo-help-title", children: t2("How to take the best photo") }),
|
|
30927
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30928
|
+
"button",
|
|
30929
|
+
{
|
|
30930
|
+
type: "button",
|
|
30931
|
+
onClick: () => setPhotoHelpOpen(false),
|
|
30932
|
+
"aria-label": t2("Close"),
|
|
30933
|
+
className: "ps-bp-photo-help-close",
|
|
30934
|
+
children: "×"
|
|
30935
|
+
}
|
|
30936
|
+
)
|
|
30937
|
+
] }),
|
|
30938
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section ps-bp-photo-help-do", children: [
|
|
30939
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-label", children: [
|
|
30940
|
+
"✓ ",
|
|
30941
|
+
t2("Do")
|
|
30942
|
+
] }),
|
|
30943
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-body", children: [
|
|
30944
|
+
t2("Stand facing the camera with your full body in frame"),
|
|
30945
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30946
|
+
t2("Hold the phone at WAIST height (not eye level)"),
|
|
30947
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30948
|
+
t2("Stand with your HEELS against a wall for best accuracy"),
|
|
30949
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30950
|
+
t2("Use natural or even lighting (e.g. near a window)"),
|
|
30951
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30952
|
+
t2("Wear fitted, simple clothing (e.g. neutral colors)"),
|
|
30953
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30954
|
+
t2("Choose a plain background (a light wall is ideal)"),
|
|
30955
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30956
|
+
t2("Stand straight and still, arms relaxed by your sides")
|
|
30957
|
+
] })
|
|
30958
|
+
] }),
|
|
30959
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section ps-bp-photo-help-dont", children: [
|
|
30960
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-label", children: [
|
|
30961
|
+
"✗ ",
|
|
30962
|
+
t2("Don't")
|
|
30963
|
+
] }),
|
|
30964
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-body", children: [
|
|
30965
|
+
t2("Don't wear loose, baggy, or layered clothing"),
|
|
30966
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30967
|
+
t2("Don't sit, pose, or bend your body"),
|
|
30968
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30969
|
+
t2("Don't use strong backlighting"),
|
|
30970
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30971
|
+
t2("Don't take mirror photos or selfies"),
|
|
30972
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30973
|
+
t2("Don't apply filters, effects, or edits")
|
|
30974
|
+
] })
|
|
30975
|
+
] }),
|
|
30976
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section ps-bp-photo-help-tip", children: [
|
|
30977
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
|
30978
|
+
"💡 ",
|
|
30979
|
+
t2("Quick Tip"),
|
|
30980
|
+
":"
|
|
30981
|
+
] }),
|
|
30982
|
+
" ",
|
|
30983
|
+
t2("The simpler your photo is, the more accurate your virtual try-on results will be.")
|
|
30984
|
+
] })
|
|
30985
|
+
]
|
|
30986
|
+
}
|
|
30987
|
+
),
|
|
30236
30988
|
photoProcessing && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-overlay", onClick: (e) => e.stopPropagation(), children: [
|
|
30237
30989
|
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bp-photo-overlay-spinner", "aria-hidden": "true" }),
|
|
30238
30990
|
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-photo-overlay-label", children: photoStatus || t2("Analyzing photo…") })
|
|
@@ -30451,71 +31203,30 @@ function BodyProfileView({
|
|
|
30451
31203
|
background: "linear-gradient(to bottom, transparent 0%, var(--ps-border-subtle) 18%, var(--ps-border-subtle) 82%, transparent 100%)",
|
|
30452
31204
|
flexShrink: 0
|
|
30453
31205
|
} }),
|
|
30454
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: {
|
|
30455
|
-
|
|
30456
|
-
|
|
30457
|
-
|
|
30458
|
-
|
|
30459
|
-
|
|
30460
|
-
|
|
30461
|
-
|
|
30462
|
-
|
|
30463
|
-
|
|
30464
|
-
|
|
30465
|
-
|
|
30466
|
-
|
|
30467
|
-
|
|
30468
|
-
|
|
30469
|
-
padding: "0.4vw 0.7vw",
|
|
30470
|
-
background: photoHelpOpen ? "var(--ps-accent)" : "transparent",
|
|
30471
|
-
color: photoHelpOpen ? "#FFFFFF" : "var(--ps-accent)",
|
|
30472
|
-
border: `1.5px solid var(--ps-accent)`,
|
|
30473
|
-
borderRadius: "999px",
|
|
30474
|
-
cursor: "pointer",
|
|
30475
|
-
fontFamily: "inherit",
|
|
30476
|
-
fontSize: "0.58vw",
|
|
30477
|
-
fontWeight: 700,
|
|
30478
|
-
letterSpacing: "0.04em",
|
|
30479
|
-
whiteSpace: "nowrap",
|
|
30480
|
-
transition: "background 0.15s, color 0.15s",
|
|
30481
|
-
flexShrink: 0
|
|
30482
|
-
},
|
|
30483
|
-
children: [
|
|
30484
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { style: {
|
|
30485
|
-
display: "inline-flex",
|
|
30486
|
-
alignItems: "center",
|
|
30487
|
-
justifyContent: "center",
|
|
30488
|
-
width: "0.95vw",
|
|
30489
|
-
height: "0.95vw",
|
|
30490
|
-
minWidth: "14px",
|
|
30491
|
-
minHeight: "14px",
|
|
30492
|
-
borderRadius: "50%",
|
|
30493
|
-
background: photoHelpOpen ? "#FFFFFF" : "var(--ps-accent)",
|
|
30494
|
-
color: photoHelpOpen ? "var(--ps-accent)" : "#FFFFFF",
|
|
30495
|
-
fontSize: "0.65vw",
|
|
30496
|
-
fontWeight: 700,
|
|
30497
|
-
lineHeight: 1
|
|
30498
|
-
}, "aria-hidden": "true", children: "?" }),
|
|
30499
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("How to take a good photo") })
|
|
30500
|
-
]
|
|
30501
|
-
}
|
|
30502
|
-
)
|
|
30503
|
-
] }),
|
|
30504
|
-
/* @__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.") })
|
|
30505
|
-
] }),
|
|
30506
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-system-toggle", style: { alignSelf: "center", marginTop: "1.2vw" }, children: [
|
|
30507
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${!isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToMetric, type: "button", children: t2("Metric") }),
|
|
30508
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToImperial, type: "button", children: t2("Imperial") })
|
|
31206
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { style: {
|
|
31207
|
+
flex: compactHeightWeightAccessory ? "0 1 min(34vw, 360px)" : 1,
|
|
31208
|
+
display: "flex",
|
|
31209
|
+
flexDirection: "column",
|
|
31210
|
+
justifyContent: compactHeightWeightAccessory ? "center" : "flex-start",
|
|
31211
|
+
position: "relative",
|
|
31212
|
+
gap: compactHeightWeightAccessory ? "1.1vw" : "0.8vw",
|
|
31213
|
+
minWidth: compactHeightWeightAccessory ? "280px" : void 0
|
|
31214
|
+
}, children: isShoeReferenceMode ? /* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-shoe-ref-desktop", children: renderShoeReferenceFields() }) : /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
31215
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: `ps-bp-photo-details-head${compactHeightWeightAccessory ? " ps-bp-photo-details-head-simple" : ""}`, children: [
|
|
31216
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("h3", { children: t2("Body details") }),
|
|
31217
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-system-toggle ps-bp-system-toggle-compact", children: [
|
|
31218
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${!isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToMetric, type: "button", children: t2("Metric") }),
|
|
31219
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${isImperialMode ? " ps-bp-system-active" : ""}`, onClick: photoSwitchToImperial, type: "button", children: t2("Imperial") })
|
|
31220
|
+
] })
|
|
30509
31221
|
] }),
|
|
30510
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { marginTop: "
|
|
30511
|
-
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
30512
|
-
|
|
30513
|
-
|
|
30514
|
-
|
|
30515
|
-
|
|
30516
|
-
|
|
30517
|
-
|
|
30518
|
-
] })
|
|
31222
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { style: { marginTop: compactHeightWeightAccessory ? "0.35vw" : "0.15vw", marginBottom: 0, minHeight: 0 }, children: [
|
|
31223
|
+
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card ps-bp-profile-card-compact", children: [
|
|
31224
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card-copy", children: [
|
|
31225
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-profile-card-eyebrow", children: t2("Active Profile") }),
|
|
31226
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: activeProfileName }),
|
|
31227
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("Using saved measurements for this fit.") })
|
|
31228
|
+
] }),
|
|
31229
|
+
onStartFresh && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-bp-profile-card-action", onClick: handleClearFromProfile, children: t2("Start Fresh") })
|
|
30519
31230
|
] }),
|
|
30520
31231
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-inline-fields", children: [
|
|
30521
31232
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-inline-row", children: [
|
|
@@ -30593,87 +31304,6 @@ function BodyProfileView({
|
|
|
30593
31304
|
] })
|
|
30594
31305
|
] })
|
|
30595
31306
|
] })
|
|
30596
|
-
] }),
|
|
30597
|
-
photoHelpOpen && /* @__PURE__ */ jsxRuntimeExports.jsxs(jsxRuntimeExports.Fragment, { children: [
|
|
30598
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30599
|
-
"div",
|
|
30600
|
-
{
|
|
30601
|
-
className: "ps-bp-photo-help-backdrop",
|
|
30602
|
-
onClick: () => setPhotoHelpOpen(false),
|
|
30603
|
-
"aria-hidden": "true"
|
|
30604
|
-
}
|
|
30605
|
-
),
|
|
30606
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs(
|
|
30607
|
-
"div",
|
|
30608
|
-
{
|
|
30609
|
-
role: "dialog",
|
|
30610
|
-
"aria-label": t2("How to take the best photo"),
|
|
30611
|
-
className: "ps-bp-photo-help",
|
|
30612
|
-
children: [
|
|
30613
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("div", { className: "ps-bp-photo-help-handle", "aria-hidden": "true" }),
|
|
30614
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-header", children: [
|
|
30615
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-photo-help-title", children: t2("How to take the best photo") }),
|
|
30616
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx(
|
|
30617
|
-
"button",
|
|
30618
|
-
{
|
|
30619
|
-
type: "button",
|
|
30620
|
-
onClick: () => setPhotoHelpOpen(false),
|
|
30621
|
-
"aria-label": t2("Close"),
|
|
30622
|
-
className: "ps-bp-photo-help-close",
|
|
30623
|
-
children: "×"
|
|
30624
|
-
}
|
|
30625
|
-
)
|
|
30626
|
-
] }),
|
|
30627
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section ps-bp-photo-help-do", children: [
|
|
30628
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-label", children: [
|
|
30629
|
-
"✓ ",
|
|
30630
|
-
t2("Do")
|
|
30631
|
-
] }),
|
|
30632
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-body", children: [
|
|
30633
|
-
t2("Stand facing the camera with your full body in frame"),
|
|
30634
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30635
|
-
t2("Hold the phone at WAIST height (not eye level)"),
|
|
30636
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30637
|
-
t2("Stand with your HEELS against a wall for best accuracy"),
|
|
30638
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30639
|
-
t2("Use natural or even lighting (e.g. near a window)"),
|
|
30640
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30641
|
-
t2("Wear fitted, simple clothing (e.g. neutral colors)"),
|
|
30642
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30643
|
-
t2("Choose a plain background (a light wall is ideal)"),
|
|
30644
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30645
|
-
t2("Stand straight and still, arms relaxed by your sides")
|
|
30646
|
-
] })
|
|
30647
|
-
] }),
|
|
30648
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section ps-bp-photo-help-dont", children: [
|
|
30649
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-label", children: [
|
|
30650
|
-
"✗ ",
|
|
30651
|
-
t2("Don't")
|
|
30652
|
-
] }),
|
|
30653
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section-body", children: [
|
|
30654
|
-
t2("Don't wear loose, baggy, or layered clothing"),
|
|
30655
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30656
|
-
t2("Don't sit, pose, or bend your body"),
|
|
30657
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30658
|
-
t2("Don't use strong backlighting"),
|
|
30659
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30660
|
-
t2("Don't take mirror photos or selfies"),
|
|
30661
|
-
/* @__PURE__ */ jsxRuntimeExports.jsx("br", {}),
|
|
30662
|
-
t2("Don't apply filters, effects, or edits")
|
|
30663
|
-
] })
|
|
30664
|
-
] }),
|
|
30665
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-photo-help-section ps-bp-photo-help-tip", children: [
|
|
30666
|
-
/* @__PURE__ */ jsxRuntimeExports.jsxs("strong", { children: [
|
|
30667
|
-
"💡 ",
|
|
30668
|
-
t2("Quick Tip"),
|
|
30669
|
-
":"
|
|
30670
|
-
] }),
|
|
30671
|
-
" ",
|
|
30672
|
-
t2("The simpler your photo is, the more accurate your virtual try-on results will be.")
|
|
30673
|
-
] })
|
|
30674
|
-
]
|
|
30675
|
-
}
|
|
30676
|
-
)
|
|
30677
31307
|
] })
|
|
30678
31308
|
] }) })
|
|
30679
31309
|
] }),
|
|
@@ -30817,14 +31447,13 @@ function BodyProfileView({
|
|
|
30817
31447
|
}
|
|
30818
31448
|
return /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-step ps-bp-step-enter", children: [
|
|
30819
31449
|
/* @__PURE__ */ jsxRuntimeExports.jsx("h2", { className: "ps-bp-title", children: basicOnly || simplePhotoOnly ? t2("Your Details") : t2("Body Measurements") }),
|
|
30820
|
-
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("
|
|
30821
|
-
|
|
30822
|
-
|
|
30823
|
-
|
|
30824
|
-
|
|
30825
|
-
|
|
30826
|
-
|
|
30827
|
-
] })
|
|
31450
|
+
activeProfileName && /* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card", children: [
|
|
31451
|
+
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-profile-card-copy", children: [
|
|
31452
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { className: "ps-bp-profile-card-eyebrow", children: t2("Active Profile") }),
|
|
31453
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("strong", { children: activeProfileName }),
|
|
31454
|
+
/* @__PURE__ */ jsxRuntimeExports.jsx("span", { children: t2("Using saved measurements for this fit.") })
|
|
31455
|
+
] }),
|
|
31456
|
+
onStartFresh && /* @__PURE__ */ jsxRuntimeExports.jsx("button", { type: "button", className: "ps-bp-profile-card-action", onClick: handleClearFromProfile, children: t2("Start Fresh") })
|
|
30828
31457
|
] }),
|
|
30829
31458
|
/* @__PURE__ */ jsxRuntimeExports.jsxs("div", { className: "ps-bp-system-toggle", children: [
|
|
30830
31459
|
/* @__PURE__ */ jsxRuntimeExports.jsx("button", { className: `ps-bp-system-btn${!isImperialMode ? " ps-bp-system-active" : ""}`, onClick: switchToMetric, type: "button", children: t2("Metric") }),
|
|
@@ -32351,6 +32980,31 @@ function validMidsectionProfile(value) {
|
|
|
32351
32980
|
function validHipProfile(value) {
|
|
32352
32981
|
return value === "narrow" || value === "average" || value === "full" ? value : void 0;
|
|
32353
32982
|
}
|
|
32983
|
+
async function profilePhotoFromFile(file) {
|
|
32984
|
+
try {
|
|
32985
|
+
return await compressImage(file, { maxDimension: 1280, quality: 0.92 });
|
|
32986
|
+
} catch {
|
|
32987
|
+
return new Promise((resolve) => {
|
|
32988
|
+
try {
|
|
32989
|
+
const reader = new FileReader();
|
|
32990
|
+
reader.onload = () => resolve(typeof reader.result === "string" ? reader.result : null);
|
|
32991
|
+
reader.onerror = () => resolve(null);
|
|
32992
|
+
reader.readAsDataURL(file);
|
|
32993
|
+
} catch {
|
|
32994
|
+
resolve(null);
|
|
32995
|
+
}
|
|
32996
|
+
});
|
|
32997
|
+
}
|
|
32998
|
+
}
|
|
32999
|
+
function cleanProfileMeasurements(value) {
|
|
33000
|
+
if (!value || typeof value !== "object") return void 0;
|
|
33001
|
+
const measurements = {};
|
|
33002
|
+
for (const [key, raw] of Object.entries(value)) {
|
|
33003
|
+
const n2 = positiveNumber(raw);
|
|
33004
|
+
if (n2 != null) measurements[key] = n2;
|
|
33005
|
+
}
|
|
33006
|
+
return Object.keys(measurements).length > 0 ? measurements : void 0;
|
|
33007
|
+
}
|
|
32354
33008
|
function durableHistoryImageUrl(url) {
|
|
32355
33009
|
if (!url) return void 0;
|
|
32356
33010
|
const clean = url.trim();
|
|
@@ -32441,6 +33095,7 @@ function PrimeStyleTryonInner({
|
|
|
32441
33095
|
productImages,
|
|
32442
33096
|
productCarouselItems,
|
|
32443
33097
|
garmentReferenceImage,
|
|
33098
|
+
garmentDetailImage,
|
|
32444
33099
|
productTitle = "Product",
|
|
32445
33100
|
productUrl,
|
|
32446
33101
|
productId,
|
|
@@ -32472,6 +33127,10 @@ function PrimeStyleTryonInner({
|
|
|
32472
33127
|
onProcessing,
|
|
32473
33128
|
onComplete,
|
|
32474
33129
|
onError,
|
|
33130
|
+
onAddToBag,
|
|
33131
|
+
addToBagLabel,
|
|
33132
|
+
continueShoppingLabel,
|
|
33133
|
+
backToProductPageLabel,
|
|
32475
33134
|
sizeGuideData,
|
|
32476
33135
|
initialView,
|
|
32477
33136
|
initialBodyProfileStep
|
|
@@ -32600,6 +33259,7 @@ function PrimeStyleTryonInner({
|
|
|
32600
33259
|
setCssReady(true);
|
|
32601
33260
|
}, []);
|
|
32602
33261
|
const [view, setView] = reactExports.useState(initialView ?? "idle");
|
|
33262
|
+
const [noSizeReason, setNoSizeReason] = reactExports.useState("no-chart");
|
|
32603
33263
|
const [selectedFile, setSelectedFile] = reactExports.useState(null);
|
|
32604
33264
|
const [previewUrl, setPreviewUrl] = reactExports.useState(null);
|
|
32605
33265
|
const [resultImageUrl, setResultImageUrl] = reactExports.useState(null);
|
|
@@ -32679,7 +33339,11 @@ function PrimeStyleTryonInner({
|
|
|
32679
33339
|
const [estimationLoading, setEstimationLoading] = reactExports.useState(false);
|
|
32680
33340
|
const [profiles, setProfiles] = reactExports.useState(() => lsGet("profiles", []));
|
|
32681
33341
|
const [profileSession, setProfileSession] = reactExports.useState(() => getStoredProfileSession());
|
|
32682
|
-
const
|
|
33342
|
+
const profileSessionRef = reactExports.useRef(profileSession);
|
|
33343
|
+
const suppressNextProfilePersistRef = reactExports.useRef(false);
|
|
33344
|
+
const [profileCompletionDraft, setProfileCompletionDraft] = reactExports.useState(
|
|
33345
|
+
() => lsGet(PROFILE_COMPLETION_DRAFT_KEY, null)
|
|
33346
|
+
);
|
|
32683
33347
|
const [profileAuthError, setProfileAuthError] = reactExports.useState(null);
|
|
32684
33348
|
const [profileAuthLoadingProvider, setProfileAuthLoadingProvider] = reactExports.useState(null);
|
|
32685
33349
|
const [history, setHistory] = reactExports.useState(() => lsGet("history", []).map(normalizeHistoryEntry));
|
|
@@ -32693,13 +33357,17 @@ function PrimeStyleTryonInner({
|
|
|
32693
33357
|
const [restoredProductCarouselItems, setRestoredProductCarouselItems] = reactExports.useState(null);
|
|
32694
33358
|
const [restoredProductTitle, setRestoredProductTitle] = reactExports.useState(null);
|
|
32695
33359
|
const [restoredProductUrl, setRestoredProductUrl] = reactExports.useState(null);
|
|
33360
|
+
const [restoredHistoryEntryId, setRestoredHistoryEntryId] = reactExports.useState(null);
|
|
32696
33361
|
const [activeProfileId, setActiveProfileIdState] = reactExports.useState(() => getActiveProfileId());
|
|
32697
33362
|
const [estimatingProfileIds, setEstimatingProfileIds] = reactExports.useState(() => /* @__PURE__ */ new Set());
|
|
32698
33363
|
const [deleteConfirmId, setDeleteConfirmId] = reactExports.useState(null);
|
|
32699
33364
|
const setActiveProfileId$1 = reactExports.useCallback((id2) => {
|
|
32700
33365
|
setActiveProfileIdState(id2);
|
|
32701
|
-
setActiveProfileId(id2);
|
|
33366
|
+
if (!profileSessionRef.current) setActiveProfileId(id2);
|
|
32702
33367
|
}, []);
|
|
33368
|
+
reactExports.useEffect(() => {
|
|
33369
|
+
profileSessionRef.current = profileSession;
|
|
33370
|
+
}, [profileSession]);
|
|
32703
33371
|
const [profileSaved, setProfileSaved] = reactExports.useState(false);
|
|
32704
33372
|
const [drawer, setDrawer] = reactExports.useState(null);
|
|
32705
33373
|
const [profileDetail, setProfileDetail] = reactExports.useState(null);
|
|
@@ -32715,28 +33383,38 @@ function PrimeStyleTryonInner({
|
|
|
32715
33383
|
profilesGoBackRef.current = goBack;
|
|
32716
33384
|
}, []);
|
|
32717
33385
|
const clearProfileCompletionDraft = reactExports.useCallback(() => {
|
|
32718
|
-
|
|
33386
|
+
lsRemove(PROFILE_COMPLETION_DRAFT_KEY);
|
|
32719
33387
|
setProfileCompletionDraft(null);
|
|
32720
33388
|
}, []);
|
|
32721
|
-
const
|
|
33389
|
+
const buildProfileCompletionDraft = reactExports.useCallback((photoBase64) => {
|
|
32722
33390
|
const f2 = formRef.current || {};
|
|
32723
33391
|
const active = profiles.find((p2) => p2.id === activeProfileId) || null;
|
|
32724
33392
|
const gender = f2.gender === "female" || active?.gender === "female" ? "female" : "male";
|
|
32725
|
-
const profilePhoto = f2.photoBase64 || f2.bodyImage || active?.photoBase64 || active?.photoUrl;
|
|
32726
|
-
const normalizedProfilePhoto = profilePhoto ? normalizeProfilePhotoSource(profilePhoto) : null;
|
|
32727
33393
|
const customMeasurements = {};
|
|
32728
33394
|
const wristCircumference = positiveNumber(f2.wristCircumference);
|
|
32729
33395
|
if (wristCircumference != null) customMeasurements.wristCircumference = wristCircumference;
|
|
32730
|
-
const
|
|
33396
|
+
const resultMeasurements = cleanProfileMeasurements(sizingResult?.estimates);
|
|
33397
|
+
const resultMeasurementsUnit = sizingResult?.estimatesUnit === "in" ? "in" : "cm";
|
|
33398
|
+
const formHeight = positiveNumber(f2.height);
|
|
33399
|
+
const activeHeight = positiveNumber(active?.height ?? active?.heightCm);
|
|
33400
|
+
const estimateHeight = positiveNumber(resultMeasurements?.height);
|
|
33401
|
+
const formWeight = positiveNumber(f2.weight);
|
|
33402
|
+
const activeWeight = positiveNumber(active?.weight ?? active?.weightKg);
|
|
33403
|
+
const estimateWeight = positiveNumber(resultMeasurements?.weight);
|
|
33404
|
+
const height = formHeight ?? activeHeight ?? estimateHeight;
|
|
33405
|
+
const weight = formWeight ?? activeWeight ?? estimateWeight;
|
|
33406
|
+
const heightUnitForDraft = formHeight != null ? f2.heightUnit || active?.heightUnit || heightUnit : activeHeight != null ? active?.heightUnit || heightUnit : estimateHeight != null ? resultMeasurementsUnit : f2.heightUnit || active?.heightUnit || heightUnit;
|
|
33407
|
+
const weightUnitForDraft = formWeight != null ? f2.weightUnit || active?.weightUnit || weightUnit : activeWeight != null ? active?.weightUnit || weightUnit : estimateWeight != null ? resultMeasurementsUnit : f2.weightUnit || active?.weightUnit || weightUnit;
|
|
33408
|
+
return {
|
|
32731
33409
|
source: "size-result",
|
|
32732
33410
|
createdAt: Date.now(),
|
|
32733
33411
|
productId: effectiveProductId,
|
|
32734
33412
|
productTitle,
|
|
32735
33413
|
gender,
|
|
32736
|
-
height
|
|
32737
|
-
weight
|
|
32738
|
-
heightUnit:
|
|
32739
|
-
weightUnit:
|
|
33414
|
+
...height != null ? { height } : {},
|
|
33415
|
+
...weight != null ? { weight } : {},
|
|
33416
|
+
heightUnit: heightUnitForDraft,
|
|
33417
|
+
weightUnit: weightUnitForDraft,
|
|
32740
33418
|
sizingUnit: active?.sizingUnit || sizingUnit,
|
|
32741
33419
|
age: positiveNumber(f2.age) ?? positiveNumber(active?.age),
|
|
32742
33420
|
chestProfile: validChestProfile(f2.chestProfile || active?.chestProfile),
|
|
@@ -32745,34 +33423,44 @@ function PrimeStyleTryonInner({
|
|
|
32745
33423
|
bandSize: f2.bandSize || active?.bandSize,
|
|
32746
33424
|
cupSize: f2.cupSize || active?.cupSize,
|
|
32747
33425
|
braSizeRegion: f2.braSizeRegion || active?.braSizeRegion || "US",
|
|
32748
|
-
...
|
|
33426
|
+
...photoBase64 ? { photoBase64 } : {},
|
|
33427
|
+
...resultMeasurements ? { measurements: resultMeasurements, measurementsUnit: resultMeasurementsUnit } : {},
|
|
32749
33428
|
...Object.keys(customMeasurements).length > 0 ? { customMeasurements } : {}
|
|
32750
33429
|
};
|
|
33430
|
+
}, [activeProfileId, effectiveProductId, heightUnit, productTitle, profiles, sizingResult, sizingUnit, weightUnit]);
|
|
33431
|
+
const handleCompleteProfileFromResult = reactExports.useCallback(async () => {
|
|
33432
|
+
const f2 = formRef.current || {};
|
|
33433
|
+
const active = profiles.find((p2) => p2.id === activeProfileId) || null;
|
|
33434
|
+
const file = selectedFile || selectedFileRef.current;
|
|
33435
|
+
const profilePhoto = f2.photoBase64 || f2.bodyImage || (file ? await profilePhotoFromFile(file) : null) || active?.photoBase64 || active?.photoUrl;
|
|
33436
|
+
const normalizedProfilePhoto = profilePhoto ? normalizeProfilePhotoSource(profilePhoto) : null;
|
|
33437
|
+
const draft = buildProfileCompletionDraft(normalizedProfilePhoto);
|
|
32751
33438
|
lsSet(PROFILE_COMPLETION_DRAFT_KEY, draft);
|
|
32752
33439
|
setProfileCompletionDraft(draft);
|
|
32753
33440
|
setProfileAuthError(null);
|
|
32754
33441
|
setView("profiles");
|
|
32755
|
-
}, [activeProfileId,
|
|
32756
|
-
const applyProfileStore = reactExports.useCallback((nextProfiles, nextActiveProfileId) => {
|
|
32757
|
-
saveProfiles(nextProfiles);
|
|
33442
|
+
}, [activeProfileId, buildProfileCompletionDraft, profiles, selectedFile]);
|
|
33443
|
+
const applyProfileStore = reactExports.useCallback((nextProfiles, nextActiveProfileId, persistLocal = !profileSessionRef.current) => {
|
|
33444
|
+
if (persistLocal) saveProfiles(nextProfiles);
|
|
32758
33445
|
setProfiles(nextProfiles);
|
|
32759
|
-
|
|
33446
|
+
setActiveProfileIdState(nextActiveProfileId);
|
|
33447
|
+
if (persistLocal) setActiveProfileId(nextActiveProfileId);
|
|
32760
33448
|
profileSyncSnapshotRef.current = JSON.stringify({ profiles: nextProfiles, activeProfileId: nextActiveProfileId });
|
|
32761
|
-
}, [
|
|
33449
|
+
}, []);
|
|
32762
33450
|
const hydrateProfileStore = reactExports.useCallback(async (session, seedProfiles, seedActiveProfileId) => {
|
|
32763
33451
|
profileSyncHydratingRef.current = true;
|
|
32764
33452
|
try {
|
|
32765
33453
|
const remoteStore = await fetchRemoteProfiles(apiUrl, session.accessToken);
|
|
32766
33454
|
if (remoteStore.profiles.length > 0) {
|
|
32767
|
-
applyProfileStore(remoteStore.profiles, remoteStore.activeProfileId);
|
|
33455
|
+
applyProfileStore(remoteStore.profiles, remoteStore.activeProfileId, false);
|
|
32768
33456
|
return;
|
|
32769
33457
|
}
|
|
32770
33458
|
if (seedProfiles.length > 0) {
|
|
32771
33459
|
const savedStore = await saveRemoteProfiles(apiUrl, session.accessToken, seedProfiles, seedActiveProfileId);
|
|
32772
|
-
applyProfileStore(savedStore.profiles, savedStore.activeProfileId);
|
|
33460
|
+
applyProfileStore(savedStore.profiles, savedStore.activeProfileId, false);
|
|
32773
33461
|
return;
|
|
32774
33462
|
}
|
|
32775
|
-
applyProfileStore([], null);
|
|
33463
|
+
applyProfileStore([], null, false);
|
|
32776
33464
|
} finally {
|
|
32777
33465
|
profileSyncHydratingRef.current = false;
|
|
32778
33466
|
}
|
|
@@ -32783,8 +33471,12 @@ function PrimeStyleTryonInner({
|
|
|
32783
33471
|
try {
|
|
32784
33472
|
const session = await startSocialProfileLogin(provider, apiUrl);
|
|
32785
33473
|
setStoredProfileSession(session);
|
|
33474
|
+
profileSessionRef.current = session;
|
|
32786
33475
|
setProfileSession(session);
|
|
32787
33476
|
await hydrateProfileStore(session, profiles, activeProfileId);
|
|
33477
|
+
setProfileCompletionDraft(
|
|
33478
|
+
(current) => current ?? lsGet(PROFILE_COMPLETION_DRAFT_KEY, null)
|
|
33479
|
+
);
|
|
32788
33480
|
} catch (error) {
|
|
32789
33481
|
setProfileAuthError(error instanceof Error ? error.message : t2("Social login failed. Please try again."));
|
|
32790
33482
|
} finally {
|
|
@@ -32793,10 +33485,28 @@ function PrimeStyleTryonInner({
|
|
|
32793
33485
|
}, [activeProfileId, apiUrl, hydrateProfileStore, profiles, t2]);
|
|
32794
33486
|
const handleProfileLogout = reactExports.useCallback(() => {
|
|
32795
33487
|
clearStoredProfileSession();
|
|
33488
|
+
clearProfileLocalStorage();
|
|
33489
|
+
suppressNextProfilePersistRef.current = true;
|
|
33490
|
+
profileSessionRef.current = null;
|
|
32796
33491
|
setProfileSession(null);
|
|
33492
|
+
setProfiles([]);
|
|
33493
|
+
setActiveProfileIdState(null);
|
|
33494
|
+
setProfileCompletionDraft(null);
|
|
33495
|
+
setProfileSaved(false);
|
|
33496
|
+
setProfileDetail(null);
|
|
33497
|
+
formRef.current = {};
|
|
33498
|
+
setFormKey((k2) => k2 + 1);
|
|
33499
|
+
if (previewUrl) URL.revokeObjectURL(previewUrl);
|
|
33500
|
+
setSelectedFile(null);
|
|
33501
|
+
selectedFileRef.current = null;
|
|
33502
|
+
setPreviewUrl(null);
|
|
33503
|
+
setBodyLandmarks(null);
|
|
33504
|
+
setFaceLandmarks(null);
|
|
33505
|
+
setEstimatedValues(null);
|
|
33506
|
+
setEstimatingProfileIds(/* @__PURE__ */ new Set());
|
|
32797
33507
|
setProfileAuthError(null);
|
|
32798
33508
|
setProfileAuthLoadingProvider(null);
|
|
32799
|
-
}, []);
|
|
33509
|
+
}, [previewUrl]);
|
|
32800
33510
|
const fileInputRef = reactExports.useRef(null);
|
|
32801
33511
|
const apiRef = reactExports.useRef(null);
|
|
32802
33512
|
const sseRef = reactExports.useRef(null);
|
|
@@ -32811,6 +33521,7 @@ function PrimeStyleTryonInner({
|
|
|
32811
33521
|
const modelImageIdRef = reactExports.useRef(null);
|
|
32812
33522
|
const autoTryOnFiredRef = reactExports.useRef(false);
|
|
32813
33523
|
const bestGarmentImageRef = reactExports.useRef(null);
|
|
33524
|
+
const bestGarmentDetailImageRef = reactExports.useRef(null);
|
|
32814
33525
|
reactExports.useEffect(() => {
|
|
32815
33526
|
try {
|
|
32816
33527
|
const key = getApiKey();
|
|
@@ -32850,6 +33561,7 @@ function PrimeStyleTryonInner({
|
|
|
32850
33561
|
productTitle
|
|
32851
33562
|
});
|
|
32852
33563
|
bestGarmentImageRef.current = null;
|
|
33564
|
+
bestGarmentDetailImageRef.current = garmentDetailImage || null;
|
|
32853
33565
|
if (garmentReferenceImage) {
|
|
32854
33566
|
bestGarmentImageRef.current = garmentReferenceImage;
|
|
32855
33567
|
console.log(`[ps-sdk:pick] #${fireN} early-return — using prop override`);
|
|
@@ -32875,8 +33587,9 @@ function PrimeStyleTryonInner({
|
|
|
32875
33587
|
signal: ctrl.signal
|
|
32876
33588
|
}).then((r2) => r2.ok ? r2.json() : null).then((j) => {
|
|
32877
33589
|
if (j?.bestUrl) {
|
|
32878
|
-
bestGarmentImageRef.current = j.bestUrl;
|
|
32879
|
-
|
|
33590
|
+
bestGarmentImageRef.current = j.modelUrl || j.bestUrl;
|
|
33591
|
+
bestGarmentDetailImageRef.current = garmentDetailImage || j.detailUrl || null;
|
|
33592
|
+
console.log(`[ps-sdk:pick] #${fireN} ← OK in ${Date.now() - t0}ms → worn=${bestGarmentImageRef.current} detail=${bestGarmentDetailImageRef.current || "none"}`);
|
|
32880
33593
|
} else {
|
|
32881
33594
|
console.log(`[ps-sdk:pick] #${fireN} ← no bestUrl in response (${Date.now() - t0}ms)`);
|
|
32882
33595
|
}
|
|
@@ -32887,7 +33600,7 @@ function PrimeStyleTryonInner({
|
|
|
32887
33600
|
ctrl.abort();
|
|
32888
33601
|
console.log(`[ps-sdk:pick] #${fireN} cleanup — aborted in-flight fetch`);
|
|
32889
33602
|
};
|
|
32890
|
-
}, [effectiveProductImages, garmentReferenceImage, apiUrl, productTitle, toBackendFetchableImageUrl]);
|
|
33603
|
+
}, [effectiveProductImages, garmentReferenceImage, garmentDetailImage, apiUrl, productTitle, toBackendFetchableImageUrl]);
|
|
32891
33604
|
function summarizeSizeGuideForGender(value) {
|
|
32892
33605
|
if (!value || typeof value !== "object") return void 0;
|
|
32893
33606
|
const obj = value;
|
|
@@ -33079,6 +33792,11 @@ function PrimeStyleTryonInner({
|
|
|
33079
33792
|
};
|
|
33080
33793
|
}, [history]);
|
|
33081
33794
|
reactExports.useEffect(() => {
|
|
33795
|
+
if (suppressNextProfilePersistRef.current) {
|
|
33796
|
+
suppressNextProfilePersistRef.current = false;
|
|
33797
|
+
return;
|
|
33798
|
+
}
|
|
33799
|
+
if (profileSessionRef.current) return;
|
|
33082
33800
|
lsSet("profiles", profiles);
|
|
33083
33801
|
}, [profiles]);
|
|
33084
33802
|
reactExports.useEffect(() => {
|
|
@@ -33107,7 +33825,10 @@ function PrimeStyleTryonInner({
|
|
|
33107
33825
|
};
|
|
33108
33826
|
}, [activeProfileId, apiUrl, applyProfileStore, profileSession, profiles, t2]);
|
|
33109
33827
|
reactExports.useEffect(() => {
|
|
33110
|
-
const handler = () =>
|
|
33828
|
+
const handler = () => {
|
|
33829
|
+
if (profileSessionRef.current) return;
|
|
33830
|
+
setProfiles(lsGet("profiles", []));
|
|
33831
|
+
};
|
|
33111
33832
|
window.addEventListener(PS_STORAGE_CHANGE_EVENT, handler);
|
|
33112
33833
|
return () => window.removeEventListener(PS_STORAGE_CHANGE_EVENT, handler);
|
|
33113
33834
|
}, []);
|
|
@@ -33155,6 +33876,14 @@ function PrimeStyleTryonInner({
|
|
|
33155
33876
|
return 1;
|
|
33156
33877
|
}
|
|
33157
33878
|
}, [view]);
|
|
33879
|
+
const updateProfilesForCurrentSession = reactExports.useCallback((updater) => {
|
|
33880
|
+
setProfiles((prev) => {
|
|
33881
|
+
const source = profileSessionRef.current ? prev : lsGet("profiles", prev);
|
|
33882
|
+
const next = updater(source);
|
|
33883
|
+
if (!profileSessionRef.current) saveProfiles(next);
|
|
33884
|
+
return next;
|
|
33885
|
+
});
|
|
33886
|
+
}, []);
|
|
33158
33887
|
const persistResultToProfile = reactExports.useCallback(
|
|
33159
33888
|
(formData, recommendation, options) => {
|
|
33160
33889
|
let targetId = activeProfileId;
|
|
@@ -33164,27 +33893,63 @@ function PrimeStyleTryonInner({
|
|
|
33164
33893
|
return;
|
|
33165
33894
|
}
|
|
33166
33895
|
if (targetId && formData.gender === "female" && (formData.bandSize || formData.cupSize || formData.braSizeRegion)) {
|
|
33167
|
-
|
|
33896
|
+
const patch = {
|
|
33168
33897
|
...formData.bandSize ? { bandSize: formData.bandSize } : {},
|
|
33169
33898
|
...formData.cupSize ? { cupSize: formData.cupSize } : {},
|
|
33170
33899
|
...formData.braSizeRegion ? { braSizeRegion: formData.braSizeRegion } : {}
|
|
33171
|
-
}
|
|
33172
|
-
|
|
33900
|
+
};
|
|
33901
|
+
if (profileSessionRef.current) {
|
|
33902
|
+
updateProfilesForCurrentSession((list) => list.map((p2) => p2.id === targetId ? { ...p2, ...patch, lastEditedAt: Date.now() } : p2));
|
|
33903
|
+
} else {
|
|
33904
|
+
updateProfile(targetId, patch);
|
|
33905
|
+
setProfiles(lsGet("profiles", []));
|
|
33906
|
+
}
|
|
33173
33907
|
}
|
|
33908
|
+
const persistMeasurements = (est, unit) => {
|
|
33909
|
+
if (!targetId) return;
|
|
33910
|
+
if (profileSessionRef.current) {
|
|
33911
|
+
updateProfilesForCurrentSession((list) => list.map((p2) => p2.id === targetId ? {
|
|
33912
|
+
...p2,
|
|
33913
|
+
measurements: est,
|
|
33914
|
+
measurementsUnit: unit,
|
|
33915
|
+
lastEditedAt: Date.now()
|
|
33916
|
+
} : p2));
|
|
33917
|
+
} else {
|
|
33918
|
+
updateProfileMeasurements(targetId, est, unit);
|
|
33919
|
+
setProfiles(lsGet("profiles", []));
|
|
33920
|
+
}
|
|
33921
|
+
};
|
|
33922
|
+
const persistSizeHistory = (entry) => {
|
|
33923
|
+
if (!targetId) return;
|
|
33924
|
+
if (profileSessionRef.current) {
|
|
33925
|
+
updateProfilesForCurrentSession((list) => list.map((p2) => {
|
|
33926
|
+
if (p2.id !== targetId) return p2;
|
|
33927
|
+
const sizeHistory = (p2.sizeHistory || []).filter((h) => h.productId !== entry.productId);
|
|
33928
|
+
sizeHistory.unshift(entry);
|
|
33929
|
+
return {
|
|
33930
|
+
...p2,
|
|
33931
|
+
sizeHistory: sizeHistory.slice(0, 50),
|
|
33932
|
+
lastUsedAt: Date.now()
|
|
33933
|
+
};
|
|
33934
|
+
}));
|
|
33935
|
+
} else {
|
|
33936
|
+
addSizeToHistory(targetId, entry);
|
|
33937
|
+
setProfiles(lsGet("profiles", []));
|
|
33938
|
+
}
|
|
33939
|
+
};
|
|
33174
33940
|
if (options?.skipBodyEstimate) {
|
|
33175
33941
|
console.log("[ps-sdk:persist] skipping body estimates — face/head flow (no body context)");
|
|
33176
33942
|
} else if (targetId && recommendation?.estimates) {
|
|
33177
33943
|
const est = recommendation.estimates;
|
|
33178
33944
|
const unit = recommendation.estimatesUnit || "cm";
|
|
33179
|
-
|
|
33180
|
-
setProfiles(lsGet("profiles", []));
|
|
33945
|
+
persistMeasurements(est, unit);
|
|
33181
33946
|
}
|
|
33182
33947
|
setEstimationDone(true);
|
|
33183
33948
|
if (recommendation?.recommendedSize && targetId) {
|
|
33184
33949
|
const sectionsMap = recommendation.sections ? Object.fromEntries(
|
|
33185
33950
|
Object.entries(recommendation.sections).map(([name, sec]) => [name, sec.recommendedSize])
|
|
33186
33951
|
) : void 0;
|
|
33187
|
-
|
|
33952
|
+
persistSizeHistory({
|
|
33188
33953
|
productId: effectiveProductId,
|
|
33189
33954
|
productTitle,
|
|
33190
33955
|
productImage,
|
|
@@ -33193,10 +33958,9 @@ function PrimeStyleTryonInner({
|
|
|
33193
33958
|
sections: sectionsMap,
|
|
33194
33959
|
savedAt: Date.now()
|
|
33195
33960
|
});
|
|
33196
|
-
setProfiles(lsGet("profiles", []));
|
|
33197
33961
|
}
|
|
33198
33962
|
},
|
|
33199
|
-
[activeProfileId, profiles, productImage, productTitle, effectiveProductId]
|
|
33963
|
+
[activeProfileId, profiles, productImage, productTitle, effectiveProductId, updateProfilesForCurrentSession]
|
|
33200
33964
|
);
|
|
33201
33965
|
const snapSubmitRef = reactExports.useRef(null);
|
|
33202
33966
|
const [confirmProfile, setConfirmProfile] = reactExports.useState(null);
|
|
@@ -33205,7 +33969,7 @@ function PrimeStyleTryonInner({
|
|
|
33205
33969
|
const profileWeight = p2.weight ?? p2.weightKg ?? 0;
|
|
33206
33970
|
const hasStored = !!p2.measurements && Object.keys(p2.measurements).length > 0;
|
|
33207
33971
|
const storedPhoto = p2.photoUrl || p2.photoBase64;
|
|
33208
|
-
if (
|
|
33972
|
+
if (storedPhoto && profileHeight > 0 && snapSubmitRef.current) {
|
|
33209
33973
|
try {
|
|
33210
33974
|
const dataUrl = await profilePhotoToDataUrl(storedPhoto);
|
|
33211
33975
|
const blob = await fetch(dataUrl).then((r2) => r2.blob());
|
|
@@ -33219,6 +33983,7 @@ function PrimeStyleTryonInner({
|
|
|
33219
33983
|
weightUnit: p2.weightUnit || "kg",
|
|
33220
33984
|
gender: p2.gender,
|
|
33221
33985
|
age: p2.age,
|
|
33986
|
+
...hasStored && p2.measurements ? { knownMeasurements: p2.measurements } : {},
|
|
33222
33987
|
...snapBraFields({
|
|
33223
33988
|
gender: p2.gender,
|
|
33224
33989
|
bandSize: p2.bandSize,
|
|
@@ -33240,6 +34005,7 @@ function PrimeStyleTryonInner({
|
|
|
33240
34005
|
setRestoredProductCarouselItems(null);
|
|
33241
34006
|
setRestoredProductTitle(null);
|
|
33242
34007
|
setRestoredProductUrl(null);
|
|
34008
|
+
setRestoredHistoryEntryId(null);
|
|
33243
34009
|
setRestoredProductUrl(null);
|
|
33244
34010
|
setSizingLoading(true);
|
|
33245
34011
|
setEstimationDone(hasStored);
|
|
@@ -33262,6 +34028,7 @@ function PrimeStyleTryonInner({
|
|
|
33262
34028
|
}
|
|
33263
34029
|
}
|
|
33264
34030
|
setView("size-result");
|
|
34031
|
+
const minVisible = new Promise((resolve) => setTimeout(resolve, 6e3));
|
|
33265
34032
|
recommendForProduct({
|
|
33266
34033
|
productId: effectiveProductId,
|
|
33267
34034
|
productTitle,
|
|
@@ -33280,7 +34047,9 @@ function PrimeStyleTryonInner({
|
|
|
33280
34047
|
if (res?.raw) setSizingResult(res.raw);
|
|
33281
34048
|
setEstimationDone(true);
|
|
33282
34049
|
}).catch(() => {
|
|
33283
|
-
}).finally(() =>
|
|
34050
|
+
}).finally(() => {
|
|
34051
|
+
void minVisible.then(() => setSizingLoading(false));
|
|
34052
|
+
});
|
|
33284
34053
|
}, [effectiveProductId, productTitle, productImage, productCategory, productSubcategory, resolvedProductFitType, productType, productTagsList, productDescription, sizeGuideData, apiUrl, previewUrl]);
|
|
33285
34054
|
const handleUseActiveProfile = reactExports.useCallback(async () => {
|
|
33286
34055
|
const p2 = profiles.find((x2) => x2.id === activeProfileId);
|
|
@@ -33333,6 +34102,7 @@ function PrimeStyleTryonInner({
|
|
|
33333
34102
|
setRestoredProductCarouselItems(null);
|
|
33334
34103
|
setRestoredProductTitle(null);
|
|
33335
34104
|
setRestoredProductUrl(null);
|
|
34105
|
+
setRestoredHistoryEntryId(null);
|
|
33336
34106
|
if (!tryOnInFlight) {
|
|
33337
34107
|
setResultImageUrl(null);
|
|
33338
34108
|
setSizingResult(null);
|
|
@@ -33502,6 +34272,8 @@ function PrimeStyleTryonInner({
|
|
|
33502
34272
|
}, [sizeGuide, formGender]);
|
|
33503
34273
|
const submitSizing = reactExports.useCallback(async (methodOverride) => {
|
|
33504
34274
|
if (!apiRef.current) return;
|
|
34275
|
+
setActiveSection(null);
|
|
34276
|
+
noFitFoundRef.current = false;
|
|
33505
34277
|
const method = methodOverride || sizingMethod;
|
|
33506
34278
|
const baseUrl = getApiUrl(apiUrl);
|
|
33507
34279
|
const key = getApiKey();
|
|
@@ -33562,6 +34334,12 @@ function PrimeStyleTryonInner({
|
|
|
33562
34334
|
if (resp.ok) {
|
|
33563
34335
|
const data = await resp.json();
|
|
33564
34336
|
await minVisible;
|
|
34337
|
+
if (data?.found === false) {
|
|
34338
|
+
setNoSizeReason(data?.reasoning === "NO_SIZE_CHART" ? "no-chart" : "no-match");
|
|
34339
|
+
setView("no-chart");
|
|
34340
|
+
setEstimationDone(true);
|
|
34341
|
+
return;
|
|
34342
|
+
}
|
|
33565
34343
|
setSizingResult(data);
|
|
33566
34344
|
onComplete?.(data);
|
|
33567
34345
|
} else {
|
|
@@ -33623,6 +34401,10 @@ function PrimeStyleTryonInner({
|
|
|
33623
34401
|
if (formRef.current.shoeUS) m2.shoeUS = formRef.current.shoeUS;
|
|
33624
34402
|
if (formRef.current.shoeUK) m2.shoeUK = formRef.current.shoeUK;
|
|
33625
34403
|
if (formRef.current.fitPreference) m2.fitPreference = formRef.current.fitPreference;
|
|
34404
|
+
if (formRef.current.bodyType) m2.bodyType = formRef.current.bodyType;
|
|
34405
|
+
if (formRef.current.chestProfile) m2.chestProfile = formRef.current.chestProfile;
|
|
34406
|
+
if (formRef.current.midsectionProfile) m2.midsectionProfile = formRef.current.midsectionProfile;
|
|
34407
|
+
if (formRef.current.hipProfile) m2.hipProfile = formRef.current.hipProfile;
|
|
33626
34408
|
payload.measurements = m2;
|
|
33627
34409
|
console.log("[PS-SDK] FINAL measurements:", JSON.stringify(m2));
|
|
33628
34410
|
} else {
|
|
@@ -33661,7 +34443,8 @@ function PrimeStyleTryonInner({
|
|
|
33661
34443
|
if (res.ok) {
|
|
33662
34444
|
const data = await res.json();
|
|
33663
34445
|
console.log("[PS-SDK] Sizing recommend RESULT:", JSON.stringify(data));
|
|
33664
|
-
if (data?.found === false
|
|
34446
|
+
if (data?.found === false) {
|
|
34447
|
+
setNoSizeReason(data?.reasoning === "NO_SIZE_CHART" ? "no-chart" : "no-match");
|
|
33665
34448
|
setView("no-chart");
|
|
33666
34449
|
setEstimationDone(true);
|
|
33667
34450
|
return;
|
|
@@ -33750,6 +34533,7 @@ function PrimeStyleTryonInner({
|
|
|
33750
34533
|
setFaceLandmarks(null);
|
|
33751
34534
|
setSizingMethod("quick");
|
|
33752
34535
|
setSizingLoading(true);
|
|
34536
|
+
setActiveSection(null);
|
|
33753
34537
|
setView("size-result");
|
|
33754
34538
|
submitSizing("quick");
|
|
33755
34539
|
return;
|
|
@@ -33768,11 +34552,13 @@ function PrimeStyleTryonInner({
|
|
|
33768
34552
|
setResultImageUrl(null);
|
|
33769
34553
|
currentHistoryEntryIdRef.current = null;
|
|
33770
34554
|
currentTryOnJobIdRef.current = null;
|
|
34555
|
+
setActiveSection(null);
|
|
33771
34556
|
setRestoredProductImage(null);
|
|
33772
34557
|
setRestoredProductImages(null);
|
|
33773
34558
|
setRestoredProductCarouselItems(null);
|
|
33774
34559
|
setRestoredProductTitle(null);
|
|
33775
34560
|
setRestoredProductUrl(null);
|
|
34561
|
+
setRestoredHistoryEntryId(null);
|
|
33776
34562
|
if (previewUrl) URL.revokeObjectURL(previewUrl);
|
|
33777
34563
|
setSelectedFile(null);
|
|
33778
34564
|
selectedFileRef.current = null;
|
|
@@ -33834,6 +34620,7 @@ function PrimeStyleTryonInner({
|
|
|
33834
34620
|
setRestoredProductImages(null);
|
|
33835
34621
|
setRestoredProductCarouselItems(null);
|
|
33836
34622
|
setRestoredProductTitle(null);
|
|
34623
|
+
setRestoredHistoryEntryId(null);
|
|
33837
34624
|
completedRef.current = false;
|
|
33838
34625
|
modelImageIdRef.current = null;
|
|
33839
34626
|
noFitFoundRef.current = false;
|
|
@@ -33845,12 +34632,14 @@ function PrimeStyleTryonInner({
|
|
|
33845
34632
|
historyTryonSavedRef.current = false;
|
|
33846
34633
|
currentHistoryEntryIdRef.current = null;
|
|
33847
34634
|
currentTryOnJobIdRef.current = null;
|
|
34635
|
+
setActiveSection(null);
|
|
33848
34636
|
setSizingLoading(true);
|
|
33849
34637
|
setEstimationDone(false);
|
|
33850
34638
|
setView("size-result");
|
|
33851
34639
|
if (measurementType === "face" || measurementType === "head") {
|
|
33852
34640
|
setFaceLandmarks(null);
|
|
33853
34641
|
const minVisible2 = new Promise((r2) => setTimeout(r2, 4500));
|
|
34642
|
+
let landmarksVisibleMin = null;
|
|
33854
34643
|
try {
|
|
33855
34644
|
const faceResult = await detectFaceMeasurements(objUrl);
|
|
33856
34645
|
if (!faceResult) {
|
|
@@ -33863,7 +34652,10 @@ function PrimeStyleTryonInner({
|
|
|
33863
34652
|
setSizingLoading(false);
|
|
33864
34653
|
return;
|
|
33865
34654
|
}
|
|
33866
|
-
if (faceResult)
|
|
34655
|
+
if (faceResult) {
|
|
34656
|
+
setFaceLandmarks(faceResult.landmarks);
|
|
34657
|
+
landmarksVisibleMin = new Promise((r2) => setTimeout(r2, 1200));
|
|
34658
|
+
}
|
|
33867
34659
|
const facePayload = {
|
|
33868
34660
|
product: productContext,
|
|
33869
34661
|
sizeGuide: sizeGuide ?? { found: false },
|
|
@@ -33891,6 +34683,14 @@ function PrimeStyleTryonInner({
|
|
|
33891
34683
|
});
|
|
33892
34684
|
if (recRes.ok) {
|
|
33893
34685
|
const recData = await recRes.json();
|
|
34686
|
+
if (recData?.found === false) {
|
|
34687
|
+
await Promise.all([minVisible2, landmarksVisibleMin || Promise.resolve()]);
|
|
34688
|
+
setNoSizeReason(recData?.reasoning === "NO_SIZE_CHART" ? "no-chart" : "no-match");
|
|
34689
|
+
setView("no-chart");
|
|
34690
|
+
setEstimationDone(true);
|
|
34691
|
+
setSizingLoading(false);
|
|
34692
|
+
return;
|
|
34693
|
+
}
|
|
33894
34694
|
setSizingResult(recData);
|
|
33895
34695
|
onComplete?.(recData);
|
|
33896
34696
|
persistResultToProfile(
|
|
@@ -33908,7 +34708,7 @@ function PrimeStyleTryonInner({
|
|
|
33908
34708
|
{ skipBodyEstimate: true }
|
|
33909
34709
|
);
|
|
33910
34710
|
} else {
|
|
33911
|
-
await minVisible2;
|
|
34711
|
+
await Promise.all([minVisible2, landmarksVisibleMin || Promise.resolve()]);
|
|
33912
34712
|
const errBody = await recRes.text().catch(() => "");
|
|
33913
34713
|
console.error("[ps-sdk] face-recommend failed:", recRes.status, errBody);
|
|
33914
34714
|
setErrorMessage(t2("Unable to get size recommendation. Please try manual measurements."));
|
|
@@ -33919,14 +34719,14 @@ function PrimeStyleTryonInner({
|
|
|
33919
34719
|
}
|
|
33920
34720
|
} catch (err) {
|
|
33921
34721
|
console.error("[ps-sdk] face-recommend failed:", err);
|
|
33922
|
-
await minVisible2;
|
|
34722
|
+
await Promise.all([minVisible2, landmarksVisibleMin || Promise.resolve()]);
|
|
33923
34723
|
setErrorMessage(t2("Unable to get size recommendation. Please try manual measurements."));
|
|
33924
34724
|
setEstimationDone(true);
|
|
33925
34725
|
setSizingLoading(false);
|
|
33926
34726
|
setView("error");
|
|
33927
34727
|
return;
|
|
33928
34728
|
}
|
|
33929
|
-
await minVisible2;
|
|
34729
|
+
await Promise.all([minVisible2, landmarksVisibleMin || Promise.resolve()]);
|
|
33930
34730
|
setSizingLoading(false);
|
|
33931
34731
|
return;
|
|
33932
34732
|
}
|
|
@@ -34010,6 +34810,7 @@ function PrimeStyleTryonInner({
|
|
|
34010
34810
|
if (recRes.ok) {
|
|
34011
34811
|
const recData = await recRes.json();
|
|
34012
34812
|
if (recData?.found === false && recData?.reasoning === "NO_SIZE_CHART") {
|
|
34813
|
+
setNoSizeReason("no-chart");
|
|
34013
34814
|
setView("no-chart");
|
|
34014
34815
|
setEstimationDone(true);
|
|
34015
34816
|
setSizingLoading(false);
|
|
@@ -34023,8 +34824,13 @@ function PrimeStyleTryonInner({
|
|
|
34023
34824
|
noFitFoundRef.current = true;
|
|
34024
34825
|
setTryOnProcessing(false);
|
|
34025
34826
|
setTryOnStartedAt(null);
|
|
34827
|
+
setNoSizeReason("no-match");
|
|
34026
34828
|
setSizingResult({ ...recData, found: false });
|
|
34027
34829
|
onComplete?.({ ...recData, found: false });
|
|
34830
|
+
setView("no-chart");
|
|
34831
|
+
setEstimationDone(true);
|
|
34832
|
+
setSizingLoading(false);
|
|
34833
|
+
return;
|
|
34028
34834
|
} else {
|
|
34029
34835
|
setSizingResult(recData);
|
|
34030
34836
|
onComplete?.(recData);
|
|
@@ -34165,6 +34971,7 @@ function PrimeStyleTryonInner({
|
|
|
34165
34971
|
}
|
|
34166
34972
|
console.log("[ps-sdk:tryon] fitInfo built", { count: fitInfo?.length || 0, areas: fitInfo?.map((f2) => `${f2.area}(${f2.fit})`) });
|
|
34167
34973
|
let garmentImage = productImage;
|
|
34974
|
+
let detailImage = garmentDetailImage || bestGarmentDetailImageRef.current || null;
|
|
34168
34975
|
if (garmentReferenceImage) {
|
|
34169
34976
|
garmentImage = garmentReferenceImage;
|
|
34170
34977
|
} else if (bestGarmentImageRef.current) {
|
|
@@ -34177,6 +34984,9 @@ function PrimeStyleTryonInner({
|
|
|
34177
34984
|
garmentImage = best;
|
|
34178
34985
|
}
|
|
34179
34986
|
}
|
|
34987
|
+
if (!detailImage && effectiveProductImages?.length) {
|
|
34988
|
+
detailImage = effectiveProductImages.find((img) => img && img !== garmentImage) || null;
|
|
34989
|
+
}
|
|
34180
34990
|
const response = await apiRef.current.submitTryOn(
|
|
34181
34991
|
modelImage,
|
|
34182
34992
|
garmentImage,
|
|
@@ -34185,11 +34995,14 @@ function PrimeStyleTryonInner({
|
|
|
34185
34995
|
{
|
|
34186
34996
|
productId: effectiveProductId,
|
|
34187
34997
|
productTitle,
|
|
34998
|
+
productCategory,
|
|
34999
|
+
productSubcategory,
|
|
34188
35000
|
productFitType: resolvedProductFitType,
|
|
34189
35001
|
productType,
|
|
34190
35002
|
productTags: productTagsList,
|
|
34191
35003
|
productDescription,
|
|
34192
35004
|
productMaterial,
|
|
35005
|
+
...detailImage && detailImage !== garmentImage ? { garmentDetailImage: detailImage } : {},
|
|
34193
35006
|
silhouetteContext: buildSilhouetteContext(
|
|
34194
35007
|
sizingResult,
|
|
34195
35008
|
sizeGuide,
|
|
@@ -34253,7 +35066,7 @@ function PrimeStyleTryonInner({
|
|
|
34253
35066
|
setView("error");
|
|
34254
35067
|
onError?.({ message, code });
|
|
34255
35068
|
}
|
|
34256
|
-
}, [selectedFile, productImage, effectiveProductImages, garmentReferenceImage, productTitle, resolvedProductFitType, productType, productTagsList, productDescription, productMaterial, measurementType, sizingResult, sizeGuide, apiUrl, onProcessing, onError, handleVtoUpdate]);
|
|
35069
|
+
}, [selectedFile, productImage, effectiveProductImages, garmentReferenceImage, garmentDetailImage, productTitle, productCategory, productSubcategory, resolvedProductFitType, productType, productTagsList, productDescription, productMaterial, measurementType, sizingResult, sizeGuide, apiUrl, onProcessing, onError, handleVtoUpdate]);
|
|
34257
35070
|
reactExports.useEffect(() => {
|
|
34258
35071
|
if (view !== "size-result") {
|
|
34259
35072
|
autoTryOnFiredRef.current = false;
|
|
@@ -34286,17 +35099,86 @@ function PrimeStyleTryonInner({
|
|
|
34286
35099
|
}).catch(() => window.open(resultImageUrl, "_blank"));
|
|
34287
35100
|
}
|
|
34288
35101
|
}, [resultImageUrl]);
|
|
34289
|
-
const
|
|
34290
|
-
|
|
34291
|
-
if (historyUrl && typeof window !== "undefined") {
|
|
35102
|
+
const openProductPageUrl = reactExports.useCallback((url) => {
|
|
35103
|
+
if (url && typeof window !== "undefined") {
|
|
34292
35104
|
try {
|
|
34293
|
-
window.open(new URL(
|
|
35105
|
+
window.open(new URL(url, window.location.origin).href, "_blank", "noopener,noreferrer");
|
|
34294
35106
|
} catch {
|
|
34295
|
-
window.open(
|
|
35107
|
+
window.open(url, "_blank", "noopener,noreferrer");
|
|
34296
35108
|
}
|
|
34297
35109
|
}
|
|
35110
|
+
}, []);
|
|
35111
|
+
const handleContinueShopping = reactExports.useCallback(() => {
|
|
35112
|
+
handleClose();
|
|
35113
|
+
}, [handleClose]);
|
|
35114
|
+
const handleBackToProductPage = reactExports.useCallback(() => {
|
|
35115
|
+
const targetUrl = restoredProductUrl || effectiveProductUrl || "";
|
|
35116
|
+
if (targetUrl) {
|
|
35117
|
+
openProductPageUrl(targetUrl);
|
|
35118
|
+
return;
|
|
35119
|
+
}
|
|
34298
35120
|
handleClose();
|
|
34299
|
-
}, [handleClose, restoredProductUrl]);
|
|
35121
|
+
}, [effectiveProductUrl, handleClose, openProductPageUrl, restoredProductUrl]);
|
|
35122
|
+
const buildAddToBagSelectedSizes = reactExports.useCallback(() => {
|
|
35123
|
+
const overrides = Object.values(pendingCustomSizesRef.current);
|
|
35124
|
+
if (overrides.length) {
|
|
35125
|
+
return overrides.map((override) => ({
|
|
35126
|
+
sectionName: override.sectionName,
|
|
35127
|
+
selectedSize: override.selectedSize,
|
|
35128
|
+
selectedLength: override.selectedLength,
|
|
35129
|
+
displayLabel: override.displayLabel,
|
|
35130
|
+
isOverride: true
|
|
35131
|
+
}));
|
|
35132
|
+
}
|
|
35133
|
+
const sections = sizingResult?.sections;
|
|
35134
|
+
if (sections && typeof sections === "object") {
|
|
35135
|
+
const selected = Object.entries(sections).map(([sectionName, sectionResult]) => {
|
|
35136
|
+
const result = sectionResult;
|
|
35137
|
+
const selectedSize = result.size || result.recommendedSize || "";
|
|
35138
|
+
if (!selectedSize) return null;
|
|
35139
|
+
const displayLabel = [selectedSize, result.length].filter(Boolean).join(" / ");
|
|
35140
|
+
return {
|
|
35141
|
+
sectionName,
|
|
35142
|
+
selectedSize,
|
|
35143
|
+
selectedLength: result.length,
|
|
35144
|
+
displayLabel,
|
|
35145
|
+
isOverride: false
|
|
35146
|
+
};
|
|
35147
|
+
}).filter(Boolean);
|
|
35148
|
+
return selected.length ? selected : void 0;
|
|
35149
|
+
}
|
|
35150
|
+
const recommendedSize = sizingResult?.recommendedSize || "";
|
|
35151
|
+
if (!recommendedSize) return void 0;
|
|
35152
|
+
return [{
|
|
35153
|
+
sectionName: "Your Fit",
|
|
35154
|
+
selectedSize: recommendedSize,
|
|
35155
|
+
displayLabel: recommendedSize,
|
|
35156
|
+
isOverride: false
|
|
35157
|
+
}];
|
|
35158
|
+
}, [sizingResult]);
|
|
35159
|
+
const handleAddToBag = reactExports.useCallback(async () => {
|
|
35160
|
+
if (!onAddToBag || !sizingResult) return;
|
|
35161
|
+
await onAddToBag({
|
|
35162
|
+
productId,
|
|
35163
|
+
productTitle: restoredProductTitle || productTitle,
|
|
35164
|
+
productUrl: restoredProductUrl || effectiveProductUrl,
|
|
35165
|
+
recommendedSize: sizingResult.recommendedSize,
|
|
35166
|
+
sizingResult,
|
|
35167
|
+
resultImageUrl: resultImageUrlRef.current || resultImageUrl,
|
|
35168
|
+
historyEntryId: currentHistoryEntryIdRef.current ?? void 0,
|
|
35169
|
+
selectedSizes: buildAddToBagSelectedSizes()
|
|
35170
|
+
});
|
|
35171
|
+
}, [
|
|
35172
|
+
buildAddToBagSelectedSizes,
|
|
35173
|
+
effectiveProductUrl,
|
|
35174
|
+
onAddToBag,
|
|
35175
|
+
productId,
|
|
35176
|
+
productTitle,
|
|
35177
|
+
restoredProductTitle,
|
|
35178
|
+
restoredProductUrl,
|
|
35179
|
+
resultImageUrl,
|
|
35180
|
+
sizingResult
|
|
35181
|
+
]);
|
|
34300
35182
|
const handleTryOnFeedbackSubmit = reactExports.useCallback(async ({ rating, note }) => {
|
|
34301
35183
|
const profileLoggedIn = Boolean(profileSession);
|
|
34302
35184
|
const activeProfile = profileLoggedIn ? profiles.find((profile) => profile.id === activeProfileId) : null;
|
|
@@ -34355,6 +35237,7 @@ function PrimeStyleTryonInner({
|
|
|
34355
35237
|
setRestoredProductCarouselItems(null);
|
|
34356
35238
|
setRestoredProductTitle(null);
|
|
34357
35239
|
setRestoredProductUrl(null);
|
|
35240
|
+
setRestoredHistoryEntryId(null);
|
|
34358
35241
|
setErrorMessage(null);
|
|
34359
35242
|
setSizingMethod(null);
|
|
34360
35243
|
setSizingResult(null);
|
|
@@ -34487,6 +35370,7 @@ function PrimeStyleTryonInner({
|
|
|
34487
35370
|
}));
|
|
34488
35371
|
const latestResultImageUrl = resultImageUrlRef.current;
|
|
34489
35372
|
const durableResultUrl = durableHistoryImageUrl(latestResultImageUrl);
|
|
35373
|
+
const profileDraftSnapshot = buildProfileCompletionDraft(null);
|
|
34490
35374
|
const entry = {
|
|
34491
35375
|
id: id2,
|
|
34492
35376
|
productId,
|
|
@@ -34511,6 +35395,7 @@ function PrimeStyleTryonInner({
|
|
|
34511
35395
|
sections: sizeGuide.sections,
|
|
34512
35396
|
sectionImages: sizeGuide.sectionImages
|
|
34513
35397
|
} : void 0,
|
|
35398
|
+
profileCompletionDraft: profileDraftSnapshot,
|
|
34514
35399
|
date: Date.now(),
|
|
34515
35400
|
hasPhoto: hasPhoto || void 0,
|
|
34516
35401
|
hasResult: latestResultImageUrl ? true : void 0,
|
|
@@ -34527,7 +35412,7 @@ function PrimeStyleTryonInner({
|
|
|
34527
35412
|
return next;
|
|
34528
35413
|
});
|
|
34529
35414
|
return id2;
|
|
34530
|
-
}, [productId, productTitle, effectiveProductUrl, productImage, effectiveProductImages, effectiveProductCarouselItems, resultImageUrl, sizingResult, sizeGuide, activeProfileId, profiles, selectedFile]);
|
|
35415
|
+
}, [productId, productTitle, effectiveProductUrl, productImage, effectiveProductImages, effectiveProductCarouselItems, resultImageUrl, sizingResult, sizeGuide, activeProfileId, profiles, selectedFile, buildProfileCompletionDraft]);
|
|
34531
35416
|
const persistHistoryResult = reactExports.useCallback((entryId, imageUrl, cleanupWhenIdle) => {
|
|
34532
35417
|
void (async () => {
|
|
34533
35418
|
const durableResultUrl = durableHistoryImageUrl(imageUrl);
|
|
@@ -34642,6 +35527,33 @@ function PrimeStyleTryonInner({
|
|
|
34642
35527
|
);
|
|
34643
35528
|
setRestoredProductTitle(entry.productTitle || null);
|
|
34644
35529
|
setRestoredProductUrl(entry.productUrl || null);
|
|
35530
|
+
setRestoredHistoryEntryId(entry.id);
|
|
35531
|
+
if (entry.profileCompletionDraft) {
|
|
35532
|
+
const draft = entry.profileCompletionDraft;
|
|
35533
|
+
const restoredForm = { ...formRef.current };
|
|
35534
|
+
if (draft.gender) restoredForm.gender = draft.gender;
|
|
35535
|
+
if (draft.height != null) restoredForm.height = String(draft.height);
|
|
35536
|
+
if (draft.weight != null) restoredForm.weight = String(draft.weight);
|
|
35537
|
+
if (draft.heightUnit) restoredForm.heightUnit = String(draft.heightUnit);
|
|
35538
|
+
if (draft.weightUnit) restoredForm.weightUnit = String(draft.weightUnit);
|
|
35539
|
+
if (draft.age != null) restoredForm.age = String(draft.age);
|
|
35540
|
+
if (draft.chestProfile) restoredForm.chestProfile = draft.chestProfile;
|
|
35541
|
+
if (draft.midsectionProfile) restoredForm.midsectionProfile = draft.midsectionProfile;
|
|
35542
|
+
if (draft.hipProfile) restoredForm.hipProfile = draft.hipProfile;
|
|
35543
|
+
if (draft.bandSize) restoredForm.bandSize = draft.bandSize;
|
|
35544
|
+
if (draft.cupSize) restoredForm.cupSize = draft.cupSize;
|
|
35545
|
+
if (draft.braSizeRegion) restoredForm.braSizeRegion = draft.braSizeRegion;
|
|
35546
|
+
if (draft.customMeasurements) {
|
|
35547
|
+
for (const [key, value] of Object.entries(draft.customMeasurements)) {
|
|
35548
|
+
restoredForm[key] = String(value);
|
|
35549
|
+
}
|
|
35550
|
+
}
|
|
35551
|
+
formRef.current = restoredForm;
|
|
35552
|
+
setFormGender(restoredForm.gender || "male");
|
|
35553
|
+
if (draft.heightUnit) setHeightUnit(String(draft.heightUnit));
|
|
35554
|
+
if (draft.weightUnit) setWeightUnit(String(draft.weightUnit));
|
|
35555
|
+
if (draft.sizingUnit) setSizingUnit(String(draft.sizingUnit));
|
|
35556
|
+
}
|
|
34645
35557
|
if (entry.sizingResult) {
|
|
34646
35558
|
setSizingResult(entry.sizingResult);
|
|
34647
35559
|
} else if (entry.recommendedSize) {
|
|
@@ -34799,6 +35711,7 @@ function PrimeStyleTryonInner({
|
|
|
34799
35711
|
basicOnly: false,
|
|
34800
35712
|
initialStep: bodyProfileInitialStep === "basics" ? "basics" : void 0,
|
|
34801
35713
|
simplePhotoOnly,
|
|
35714
|
+
simpleAccessoryLayout: measurementType === "body-basic",
|
|
34802
35715
|
simpleQuestionMode: measurementType === "foot" ? "shoeReference" : "heightWeight",
|
|
34803
35716
|
formRef,
|
|
34804
35717
|
sizingCountry,
|
|
@@ -34901,6 +35814,12 @@ function PrimeStyleTryonInner({
|
|
|
34901
35814
|
setView,
|
|
34902
35815
|
handleDownload,
|
|
34903
35816
|
onContinueShopping: handleContinueShopping,
|
|
35817
|
+
isHistoryResult: !!restoredHistoryEntryId,
|
|
35818
|
+
onBackToProductPage: handleBackToProductPage,
|
|
35819
|
+
onAddToBag: onAddToBag ? handleAddToBag : void 0,
|
|
35820
|
+
addToBagLabel,
|
|
35821
|
+
continueShoppingLabel,
|
|
35822
|
+
backToProductPageLabel,
|
|
34904
35823
|
onTryOnFeedbackSubmit: handleTryOnFeedbackSubmit,
|
|
34905
35824
|
selectedFile,
|
|
34906
35825
|
previewUrl,
|
|
@@ -35000,12 +35919,31 @@ function PrimeStyleTryonInner({
|
|
|
35000
35919
|
setView("body-profile");
|
|
35001
35920
|
},
|
|
35002
35921
|
onSaveProfileMeasurements: (id2, measurements, unit) => {
|
|
35003
|
-
|
|
35004
|
-
|
|
35922
|
+
const nextUnit = unit ?? profiles.find((x2) => x2.id === id2)?.measurementsUnit ?? "cm";
|
|
35923
|
+
if (profileSessionRef.current) {
|
|
35924
|
+
updateProfilesForCurrentSession((list) => list.map((p2) => p2.id === id2 ? {
|
|
35925
|
+
...p2,
|
|
35926
|
+
measurements,
|
|
35927
|
+
measurementsUnit: nextUnit,
|
|
35928
|
+
lastEditedAt: Date.now()
|
|
35929
|
+
} : p2));
|
|
35930
|
+
} else {
|
|
35931
|
+
updateProfileMeasurements(id2, measurements, nextUnit);
|
|
35932
|
+
setProfiles(lsGet("profiles", []));
|
|
35933
|
+
}
|
|
35005
35934
|
},
|
|
35006
35935
|
onSaveBraSize: (id2, bandSize, cupSize) => {
|
|
35007
|
-
|
|
35008
|
-
|
|
35936
|
+
if (profileSessionRef.current) {
|
|
35937
|
+
updateProfilesForCurrentSession((list) => list.map((p2) => p2.id === id2 ? {
|
|
35938
|
+
...p2,
|
|
35939
|
+
bandSize,
|
|
35940
|
+
cupSize,
|
|
35941
|
+
lastEditedAt: Date.now()
|
|
35942
|
+
} : p2));
|
|
35943
|
+
} else {
|
|
35944
|
+
updateProfile(id2, { bandSize, cupSize });
|
|
35945
|
+
setProfiles(lsGet("profiles", []));
|
|
35946
|
+
}
|
|
35009
35947
|
},
|
|
35010
35948
|
onEditProfile: (p2) => {
|
|
35011
35949
|
setProfileDetail(p2);
|
|
@@ -35078,13 +36016,24 @@ function PrimeStyleTryonInner({
|
|
|
35078
36016
|
bodyLandmarks: landmarks ?? void 0
|
|
35079
36017
|
})).then((est) => {
|
|
35080
36018
|
if (est) {
|
|
35081
|
-
|
|
36019
|
+
if (profileSessionRef.current) {
|
|
36020
|
+
updateProfilesForCurrentSession((list) => list.map((p2) => p2.id === newProfile.id ? {
|
|
36021
|
+
...p2,
|
|
36022
|
+
measurements: est.estimates,
|
|
36023
|
+
measurementsUnit: est.unit,
|
|
36024
|
+
lastEditedAt: Date.now()
|
|
36025
|
+
} : p2));
|
|
36026
|
+
} else {
|
|
36027
|
+
updateProfileMeasurements(newProfile.id, est.estimates, est.unit);
|
|
36028
|
+
}
|
|
35082
36029
|
if (est.userEstimates) {
|
|
35083
|
-
const
|
|
35084
|
-
|
|
35085
|
-
|
|
36030
|
+
const userEstimates = est.userEstimates;
|
|
36031
|
+
updateProfilesForCurrentSession((list) => {
|
|
36032
|
+
const idx = list.findIndex((p2) => p2.id === newProfile.id);
|
|
36033
|
+
if (idx < 0) return list;
|
|
36034
|
+
const all = [...list];
|
|
35086
36035
|
const target = all[idx];
|
|
35087
|
-
const u2 =
|
|
36036
|
+
const u2 = userEstimates;
|
|
35088
36037
|
const patched = { ...target };
|
|
35089
36038
|
if (u2.height && !(target.height || target.heightCm)) {
|
|
35090
36039
|
patched.height = u2.height;
|
|
@@ -35100,10 +36049,10 @@ function PrimeStyleTryonInner({
|
|
|
35100
36049
|
patched.age = u2.age;
|
|
35101
36050
|
}
|
|
35102
36051
|
all[idx] = patched;
|
|
35103
|
-
|
|
35104
|
-
}
|
|
36052
|
+
return all;
|
|
36053
|
+
});
|
|
35105
36054
|
}
|
|
35106
|
-
setProfiles(lsGet("profiles", []));
|
|
36055
|
+
if (!profileSessionRef.current) setProfiles(lsGet("profiles", []));
|
|
35107
36056
|
}
|
|
35108
36057
|
}).catch(() => {
|
|
35109
36058
|
}).finally(() => {
|
|
@@ -35116,9 +36065,8 @@ function PrimeStyleTryonInner({
|
|
|
35116
36065
|
}
|
|
35117
36066
|
},
|
|
35118
36067
|
onDeleteProfile: (id2) => {
|
|
35119
|
-
|
|
36068
|
+
updateProfilesForCurrentSession((prev) => prev.filter((p2) => p2.id !== id2));
|
|
35120
36069
|
if (activeProfileId === id2) setActiveProfileId$1(null);
|
|
35121
|
-
lsSet("profiles", lsGet("profiles", []).filter((p2) => p2.id !== id2));
|
|
35122
36070
|
},
|
|
35123
36071
|
onRequestDelete: (id2) => setDeleteConfirmId(id2),
|
|
35124
36072
|
onLogout: handleProfileLogout,
|
|
@@ -35152,6 +36100,7 @@ function PrimeStyleTryonInner({
|
|
|
35152
36100
|
{
|
|
35153
36101
|
productImage,
|
|
35154
36102
|
productTitle,
|
|
36103
|
+
reason: noSizeReason,
|
|
35155
36104
|
onTryOn: () => setView("photo-guide"),
|
|
35156
36105
|
onClose: onClose ?? (() => {
|
|
35157
36106
|
}),
|
|
@@ -35378,9 +36327,7 @@ function PrimeStyleTryonInner({
|
|
|
35378
36327
|
{
|
|
35379
36328
|
onConfirm: () => {
|
|
35380
36329
|
const id2 = deleteConfirmId;
|
|
35381
|
-
|
|
35382
|
-
lsSet("profiles", updated);
|
|
35383
|
-
setProfiles(updated);
|
|
36330
|
+
updateProfilesForCurrentSession((prev) => prev.filter((p2) => p2.id !== id2));
|
|
35384
36331
|
if (activeProfileId === id2) setActiveProfileId$1(null);
|
|
35385
36332
|
setDeleteConfirmId(null);
|
|
35386
36333
|
},
|