@primestyleai/tryon 5.10.108 → 5.10.109

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.
@@ -7816,7 +7816,7 @@ const it = {
7816
7816
  "Drag or scroll to set your height": "Trascina o scorri per impostare la tua altezza",
7817
7817
  "Drag or scroll to set your weight": "Trascina o scorri per impostare il tuo peso"
7818
7818
  };
7819
- const pt = {
7819
+ const pt$1 = {
7820
7820
  "Virtual Try-On": "Provador Virtual",
7821
7821
  "Find Your Size & See It On You": "Encontre seu tamanho e experimente",
7822
7822
  "Get the perfect fit, then try it on virtually": "Encontre o caimento perfeito e experimente virtualmente",
@@ -9240,7 +9240,7 @@ const locales = {
9240
9240
  fr,
9241
9241
  de,
9242
9242
  it,
9243
- pt,
9243
+ pt: pt$1,
9244
9244
  nl,
9245
9245
  ru,
9246
9246
  ar,
@@ -10589,16 +10589,29 @@ function getUnitLabel(unit) {
10589
10589
  return "";
10590
10590
  }
10591
10591
  const cache = /* @__PURE__ */ new Map();
10592
+ function pt(lm, key) {
10593
+ const v2 = lm[key];
10594
+ if (v2 && typeof v2 === "object" && typeof v2.x === "number" && typeof v2.y === "number") return v2;
10595
+ return null;
10596
+ }
10592
10597
  function scoreLandmarks(lm) {
10593
10598
  if (!lm) return 0;
10594
- let joints = 0;
10595
- for (const [k2, v2] of Object.entries(lm)) {
10596
- if (k2 === "imageWidth" || k2 === "imageHeight") continue;
10597
- if (v2 && typeof v2 === "object" && typeof v2.x === "number") joints++;
10598
- }
10599
- let score = joints * 10;
10600
- if (lm.nose) score += 50;
10601
- if (lm.leftAnkle && lm.rightAnkle) score += 5;
10599
+ const ankles = pt(lm, "leftAnkle") || pt(lm, "rightAnkle");
10600
+ const knees = pt(lm, "leftKnee") || pt(lm, "rightKnee");
10601
+ const hips = pt(lm, "leftHip") || pt(lm, "rightHip");
10602
+ const shoulders = pt(lm, "leftShoulder") || pt(lm, "rightShoulder");
10603
+ const nose = pt(lm, "nose");
10604
+ let score = 0;
10605
+ if (shoulders) score += 30;
10606
+ if (hips) score += 60;
10607
+ if (knees) score += 80;
10608
+ if (ankles) score += 200;
10609
+ const ys = [nose, shoulders, hips, knees, ankles].filter((p2) => !!p2).map((p2) => p2.y);
10610
+ if (ys.length >= 2) {
10611
+ const spread = Math.max(...ys) - Math.min(...ys);
10612
+ score += Math.round(spread * 80);
10613
+ }
10614
+ if (nose) score += 10;
10602
10615
  return score;
10603
10616
  }
10604
10617
  async function scoreImage(url) {
@@ -19858,7 +19871,8 @@ function SectionDetailView({
19858
19871
  internationalSizes,
19859
19872
  continueLabel,
19860
19873
  renderRaw = false,
19861
- sectionFound
19874
+ sectionFound,
19875
+ allSizes
19862
19876
  }) {
19863
19877
  const recSize = sectionResult?.recommendedSize || "";
19864
19878
  const [selectedSize, setSelectedSize] = reactExports.useState(null);
@@ -19896,7 +19910,7 @@ function SectionDetailView({
19896
19910
  return 0;
19897
19911
  }, [section]);
19898
19912
  const sizeHeader = section.headers[sizeColIdx] || "Size";
19899
- const allSizes = reactExports.useMemo(() => {
19913
+ const chartSizes = reactExports.useMemo(() => {
19900
19914
  const raw = section.rows.map((r2) => cellValFn(r2, sizeColIdx, sizeHeader)).filter(Boolean);
19901
19915
  return [...new Set(raw)];
19902
19916
  }, [section, sizeColIdx, sizeHeader]);
@@ -20058,26 +20072,32 @@ function SectionDetailView({
20058
20072
  return details.map((m2) => {
20059
20073
  if (isFromLength.has(m2.measurement)) {
20060
20074
  const userNum2 = userMeasurements[m2.measurement.toLowerCase()] || pNumFn(m2.userValue);
20075
+ const lookup2 = allSizes?.[displaySize]?.[m2.measurement];
20076
+ const chartRange2 = lookup2?.chartRange ?? m2.chartRange;
20077
+ const fit2 = lookup2?.fit ?? m2.fit ?? "good";
20061
20078
  return {
20062
20079
  area: m2.measurement,
20063
20080
  userNum: userNum2,
20064
- chartLabel: cleanNumFn(m2.chartRange),
20065
- fit: m2.fit || "good",
20081
+ chartLabel: cleanNumFn(chartRange2),
20082
+ fit: fit2,
20066
20083
  isLength: true
20067
20084
  };
20068
20085
  }
20069
20086
  const userNum = userMeasurements[m2.measurement.toLowerCase()] || pNumFn(m2.userValue);
20070
20087
  const measLower = m2.measurement.toLowerCase();
20071
20088
  const isDirectional = /length|inseam|sleeve|hem|rise/.test(measLower);
20089
+ const lookup = allSizes?.[displaySize]?.[m2.measurement];
20090
+ const chartRange = lookup?.chartRange ?? m2.chartRange;
20091
+ const fit = lookup?.fit ?? m2.fit ?? "good";
20072
20092
  return {
20073
20093
  area: m2.measurement,
20074
20094
  userNum,
20075
- chartLabel: cleanNumFn(m2.chartRange),
20076
- fit: m2.fit || "good",
20095
+ chartLabel: cleanNumFn(chartRange),
20096
+ fit,
20077
20097
  isLength: isDirectional
20078
20098
  };
20079
20099
  });
20080
- }, [sectionResult, lengthEntry, userMeasurements, renderRaw]);
20100
+ }, [sectionResult, lengthEntry, userMeasurements, renderRaw, allSizes, displaySize]);
20081
20101
  const goodCount = fitRows.filter(
20082
20102
  (r2) => r2.fit === "good" || r2.fit === "a-bit-tight" || r2.fit === "a-bit-loose"
20083
20103
  ).length;
@@ -20093,7 +20113,7 @@ function SectionDetailView({
20093
20113
  const backendAvailableSizes = secAny?.availableSizes || [];
20094
20114
  const backendAvailableLengths = secAny?.availableLengths || [];
20095
20115
  const finalDisplayLength = selectedLength || backendLength;
20096
- const finalAllSizes = backendAvailableSizes.length > 0 ? backendAvailableSizes : allSizes;
20116
+ const finalAllSizes = backendAvailableSizes.length > 0 ? backendAvailableSizes : chartSizes;
20097
20117
  const visibleSizes = (() => {
20098
20118
  if (finalAllSizes.length <= 3) return finalAllSizes;
20099
20119
  const idx = finalAllSizes.indexOf(recSize);
@@ -21120,7 +21140,8 @@ function SizeResultView({
21120
21140
  imgHeight: imgDims.h
21121
21141
  }
21122
21142
  ) : null,
21123
- t: t2
21143
+ t: t2,
21144
+ allSizes: sizingResult?.allSizes
21124
21145
  }
21125
21146
  )
21126
21147
  ] });
@@ -21148,7 +21169,8 @@ function SizeResultView({
21148
21169
  })(),
21149
21170
  onBack: () => setActiveSection(null),
21150
21171
  internationalSizes: entry.secResult?.internationalSizes,
21151
- t: t2
21172
+ t: t2,
21173
+ allSizes: sizingResult?.allSizes
21152
21174
  }
21153
21175
  )
21154
21176
  ] }, `detail-${activeSection}`)
@@ -21391,6 +21413,7 @@ function SizeResultView({
21391
21413
  productTitle,
21392
21414
  isMobile: true,
21393
21415
  renderRaw: isAccessory,
21416
+ allSizes: sizingResult?.allSizes,
21394
21417
  isTryOnImage: !!resultImageUrl,
21395
21418
  showLines,
21396
21419
  onToggleLines: isAccessory ? void 0 : () => setShowLines(!showLines),
@@ -21452,7 +21475,8 @@ function SizeResultView({
21452
21475
  tryOnProcessing,
21453
21476
  tryOnStartedAt,
21454
21477
  t: t2,
21455
- renderRaw: isAccessory
21478
+ renderRaw: isAccessory,
21479
+ allSizes: sizingResult?.allSizes
21456
21480
  }
21457
21481
  )
21458
21482
  ) : sizingResult?.found === false ? (
@@ -30285,13 +30309,14 @@ async function mount(el2) {
30285
30309
  const data = readDataAttrs(el2);
30286
30310
  console.log(`${TAG} read data attributes`, data);
30287
30311
  const props = buildPropsFromDataAttrs(data);
30312
+ const hadCachedSizeguide = !!data.cachedSizeguide;
30288
30313
  if (!props.sizeGuideData && props.productId && props.apiUrl) {
30289
30314
  const fetched = await fetchSizeGuideForProduct(props.apiUrl, props.productId);
30290
30315
  if (fetched) {
30291
30316
  props.sizeGuideData = fetched;
30292
30317
  }
30293
30318
  }
30294
- if (props.sizeGuideData) {
30319
+ if (hadCachedSizeguide && props.sizeGuideData) {
30295
30320
  try {
30296
30321
  const buttonStyles = props.buttonStyles;
30297
30322
  createSizeGuideButton(el2, props.sizeGuideData, {
package/dist/types.d.ts CHANGED
@@ -234,6 +234,15 @@ export interface SizingResult {
234
234
  * default path) or "photo" (free-measurement mode triggered by a
235
235
  * detected mismatch between the photo and entered weight). */
236
236
  measurementSource?: "inputs+photo" | "photo";
237
+ /** Per-size lookup: { sizeLabel: { measurement: { chartRange, fit } } }.
238
+ * When the user clicks a non-recommended size pill, the SDK reads from
239
+ * this map to swap the table cells + fit pills to that row's pre-
240
+ * classified values. NO client-side recomputation — the backend's
241
+ * matcher already classified every row + every measurement field. */
242
+ allSizes?: Record<string, Record<string, {
243
+ chartRange: string;
244
+ fit: string;
245
+ }>>;
237
246
  }
238
247
  /** Fit info for a body area — tells Gemini how the garment should render at this region */
239
248
  export interface FitAreaInfo {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@primestyleai/tryon",
3
- "version": "5.10.108",
3
+ "version": "5.10.109",
4
4
  "description": "PrimeStyle Virtual Try-On SDK — React component & Web Component",
5
5
  "type": "module",
6
6
  "main": "dist/primestyle-tryon.js",