xactsize-webcomponents 1.0.19 → 1.0.20

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.
@@ -297,7 +297,7 @@ m.elementStyles = [], m.shadowRootOptions = { mode: "open" }, m[z("elementProper
297
297
  */
298
298
  const G = globalThis, $ = G.trustedTypes, UA = $ ? $.createPolicy("lit-html", { createHTML: (l) => l }) : void 0, NA = "$lit$", W = `lit$${Math.random().toFixed(9).slice(2)}$`, RA = "?" + W, tt = `<${RA}>`, L = document, F = () => L.createComment(""), M = (l) => l === null || typeof l != "object" && typeof l != "function", cA = Array.isArray, lt = (l) => cA(l) || typeof (l == null ? void 0 : l[Symbol.iterator]) == "function", rA = `[
299
299
  \f\r]`, H = /<(?:(!--|\/[^a-zA-Z])|(\/?[a-zA-Z][^>\s]*)|(\/?$))/g, WA = /-->/g, sA = />/g, i = RegExp(`>|${rA}(?:([^\\s"'>=/]+)(${rA}*=${rA}*(?:[^
300
- \f\r"'\`<>=]|("|')|))|$)`, "g"), iA = /'/g, vA = /"/g, HA = /^(?:script|style|textarea|title)$/i, et = (l) => (A, ...t) => ({ _$litType$: l, strings: A, values: t }), T = et(1), f = Symbol.for("lit-noChange"), c = Symbol.for("lit-nothing"), OA = /* @__PURE__ */ new WeakMap(), O = L.createTreeWalker(L, 129);
300
+ \f\r"'\`<>=]|("|')|))|$)`, "g"), iA = /'/g, OA = /"/g, HA = /^(?:script|style|textarea|title)$/i, et = (l) => (A, ...t) => ({ _$litType$: l, strings: A, values: t }), T = et(1), f = Symbol.for("lit-noChange"), c = Symbol.for("lit-nothing"), vA = /* @__PURE__ */ new WeakMap(), v = L.createTreeWalker(L, 129);
301
301
  function zA(l, A) {
302
302
  if (!cA(l) || !l.hasOwnProperty("raw")) throw Error("invalid template strings array");
303
303
  return UA !== void 0 ? UA.createHTML(A) : A;
@@ -308,7 +308,7 @@ const rt = (l, A) => {
308
308
  for (let S = 0; S < t; S++) {
309
309
  const n = l[S];
310
310
  let d, k, y = -1, x = 0;
311
- for (; x < n.length && (V.lastIndex = x, k = V.exec(n), k !== null); ) x = V.lastIndex, V === H ? k[1] === "!--" ? V = WA : k[1] !== void 0 ? V = sA : k[2] !== void 0 ? (HA.test(k[2]) && (e = RegExp("</" + k[2], "g")), V = i) : k[3] !== void 0 && (V = i) : V === i ? k[0] === ">" ? (V = e ?? H, y = -1) : k[1] === void 0 ? y = -2 : (y = V.lastIndex - k[2].length, d = k[1], V = k[3] === void 0 ? i : k[3] === '"' ? vA : iA) : V === vA || V === iA ? V = i : V === WA || V === sA ? V = H : (V = i, e = void 0);
311
+ for (; x < n.length && (V.lastIndex = x, k = V.exec(n), k !== null); ) x = V.lastIndex, V === H ? k[1] === "!--" ? V = WA : k[1] !== void 0 ? V = sA : k[2] !== void 0 ? (HA.test(k[2]) && (e = RegExp("</" + k[2], "g")), V = i) : k[3] !== void 0 && (V = i) : V === i ? k[0] === ">" ? (V = e ?? H, y = -1) : k[1] === void 0 ? y = -2 : (y = V.lastIndex - k[2].length, d = k[1], V = k[3] === void 0 ? i : k[3] === '"' ? OA : iA) : V === OA || V === iA ? V = i : V === WA || V === sA ? V = H : (V = i, e = void 0);
312
312
  const U = V === i && l[S + 1].startsWith("/>") ? " " : "";
313
313
  p += V === H ? n + tt : y >= 0 ? (r.push(d), n.slice(0, y) + NA + n.slice(y) + W + U) : n + W + (y === -2 ? S : U);
314
314
  }
@@ -320,11 +320,11 @@ class h {
320
320
  this.parts = [];
321
321
  let p = 0, V = 0;
322
322
  const S = A.length - 1, n = this.parts, [d, k] = rt(A, t);
323
- if (this.el = h.createElement(d, r), O.currentNode = this.el.content, t === 2 || t === 3) {
323
+ if (this.el = h.createElement(d, r), v.currentNode = this.el.content, t === 2 || t === 3) {
324
324
  const y = this.el.content.firstChild;
325
325
  y.replaceWith(...y.childNodes);
326
326
  }
327
- for (; (e = O.nextNode()) !== null && n.length < S; ) {
327
+ for (; (e = v.nextNode()) !== null && n.length < S; ) {
328
328
  if (e.nodeType === 1) {
329
329
  if (e.hasAttributes()) for (const y of e.getAttributeNames()) if (y.endsWith(NA)) {
330
330
  const x = k[V++], U = e.getAttribute(y).split(W), Q = /([.?@])?(.*)/.exec(x);
@@ -334,7 +334,7 @@ class h {
334
334
  const y = e.textContent.split(W), x = y.length - 1;
335
335
  if (x > 0) {
336
336
  e.textContent = $ ? $.emptyScript : "";
337
- for (let U = 0; U < x; U++) e.append(y[U], F()), O.nextNode(), n.push({ type: 2, index: ++p });
337
+ for (let U = 0; U < x; U++) e.append(y[U], F()), v.nextNode(), n.push({ type: 2, index: ++p });
338
338
  e.append(y[x], F());
339
339
  }
340
340
  }
@@ -370,16 +370,16 @@ class pt {
370
370
  }
371
371
  u(A) {
372
372
  const { el: { content: t }, parts: r } = this._$AD, e = ((A == null ? void 0 : A.creationScope) ?? L).importNode(t, !0);
373
- O.currentNode = e;
374
- let p = O.nextNode(), V = 0, S = 0, n = r[0];
373
+ v.currentNode = e;
374
+ let p = v.nextNode(), V = 0, S = 0, n = r[0];
375
375
  for (; n !== void 0; ) {
376
376
  if (V === n.index) {
377
377
  let d;
378
378
  n.type === 2 ? d = new w(p, p.nextSibling, this, A) : n.type === 1 ? d = new n.ctor(p, n.name, n.strings, this, A) : n.type === 6 && (d = new St(p, this, A)), this._$AV.push(d), n = r[++S];
379
379
  }
380
- V !== (n == null ? void 0 : n.index) && (p = O.nextNode(), V++);
380
+ V !== (n == null ? void 0 : n.index) && (p = v.nextNode(), V++);
381
381
  }
382
- return O.currentNode = L, e;
382
+ return v.currentNode = L, e;
383
383
  }
384
384
  p(A) {
385
385
  let t = 0;
@@ -427,8 +427,8 @@ class w {
427
427
  }
428
428
  }
429
429
  _$AC(A) {
430
- let t = OA.get(A.strings);
431
- return t === void 0 && OA.set(A.strings, t = new h(A)), t;
430
+ let t = vA.get(A.strings);
431
+ return t === void 0 && vA.set(A.strings, t = new h(A)), t;
432
432
  }
433
433
  k(A) {
434
434
  cA(this._$AH) || (this._$AH = [], this._$AR());
@@ -751,32 +751,32 @@ function st(l) {
751
751
  function qA(l) {
752
752
  window.dispatchEvent(new CustomEvent(SA, { detail: l }));
753
753
  }
754
- let AA = "", nA, hA, tA, aA, EA, v = new MA();
755
- v.resolve();
754
+ let AA = "", nA, hA, tA, aA, EA, O = new MA();
755
+ O.resolve();
756
756
  let g = 0;
757
- const it = (l) => (jt((A, t) => Wt(EA, A, t)), AA = hA = l.sourceLocale, tA = new Set(l.targetLocales), tA.add(l.sourceLocale), aA = l.loadLocale, { getLocale: vt, setLocale: Ot }), vt = () => AA, Ot = (l) => {
757
+ const it = (l) => (jt((A, t) => Wt(EA, A, t)), AA = hA = l.sourceLocale, tA = new Set(l.targetLocales), tA.add(l.sourceLocale), aA = l.loadLocale, { getLocale: Ot, setLocale: vt }), Ot = () => AA, vt = (l) => {
758
758
  if (l === (nA ?? AA))
759
- return v.promise;
759
+ return O.promise;
760
760
  if (!tA || !aA)
761
761
  throw new Error("Internal error");
762
762
  if (!tA.has(l))
763
763
  throw new Error("Invalid locale code");
764
764
  g++;
765
765
  const A = g;
766
- return nA = l, v.settled && (v = new MA()), qA({ status: "loading", loadingLocale: l }), (l === hA ? (
766
+ return nA = l, O.settled && (O = new MA()), qA({ status: "loading", loadingLocale: l }), (l === hA ? (
767
767
  // We could switch to the source locale synchronously, but we prefer to
768
768
  // queue it on a microtask so that switching locales is consistently
769
769
  // asynchronous.
770
770
  Promise.resolve({ templates: void 0 })
771
771
  ) : aA(l)).then((r) => {
772
- g === A && (AA = l, nA = void 0, EA = r.templates, qA({ status: "ready", readyLocale: l }), v.resolve());
772
+ g === A && (AA = l, nA = void 0, EA = r.templates, qA({ status: "ready", readyLocale: l }), O.resolve());
773
773
  }, (r) => {
774
774
  g === A && (qA({
775
775
  status: "error",
776
776
  errorLocale: l,
777
777
  errorMessage: r.toString()
778
- }), v.reject(r));
779
- }), v.promise;
778
+ }), O.reject(r));
779
+ }), O.promise;
780
780
  }, IA = "en", bt = [
781
781
  "pt-BR"
782
782
  ];
@@ -1790,7 +1790,7 @@ let a = class extends X {
1790
1790
  const r = await new Promise(
1791
1791
  (V) => A.toBlob((S) => V(S), "image/jpeg")
1792
1792
  ), e = new File([r], "frame.jpg", { type: "image/jpeg" }), p = new FormData();
1793
- p.append("image", e), p.append("height", this.height.toString()), p.append("product_sku", this.productSku), this.measurerKey && p.append("measurerKey", this.measurerKey);
1793
+ p.append("image", e), p.append("height", this.height.toString()), p.append("productSku", this.productSku), this.measurerKey && p.append("measurerKey", this.measurerKey);
1794
1794
  try {
1795
1795
  this.isFetching = !0, this.isLoading = !0, this.poolingTimeout !== null && (clearTimeout(this.poolingTimeout), this.poolingTimeout = null), this.instructionMessageTimeout !== null && (clearTimeout(this.instructionMessageTimeout), this.instructionMessageTimeout = null);
1796
1796
  const S = await (await fetch(this.apiUrl, {
@@ -1800,11 +1800,10 @@ let a = class extends X {
1800
1800
  Accept: "application/json",
1801
1801
  "Cache-Control": "no-store",
1802
1802
  Pragma: "no-cache",
1803
- "X-Api-Key": this.apiKey,
1804
- "X-Tenant-Id": this.tenantId
1803
+ "X-Api-Key": this.apiKey
1805
1804
  }
1806
1805
  })).json();
1807
- this.isFetching = !1, this.isLoading = !1, this.errorMessage = S, S.success ? (this.measurements = S.measurements, this.recommendedSize = S.ChosenSize, this.instructionMessage = q("Measurement successful!"), this.stopPolling(), this.step = 4) : (this.instructionMessage = this.getTranslatedMessage(S.message || "UNKNOWN_ERROR"), this.instructionMessageTimeout = setTimeout(() => {
1806
+ this.isFetching = !1, this.isLoading = !1, this.errorMessage = JSON.stringify(S), S.success ? (this.measurements = S.measurements, this.recommendedSize = S.chosenSize, this.instructionMessage = q("Measurement successful!"), this.stopPolling(), this.step = 4) : (this.instructionMessage = this.getTranslatedMessage(S.message || "UNKNOWN_ERROR"), this.instructionMessageTimeout = setTimeout(() => {
1808
1807
  this.recommendedSize || (this.instructionMessage = q("Position yourself in front of the camera"), this.poolingTimeout = setTimeout(l, 0));
1809
1808
  }, 2e3));
1810
1809
  } catch {
@@ -1884,10 +1883,7 @@ let a = class extends X {
1884
1883
  .recommendedSize=${this.recommendedSize}
1885
1884
  .onRetry=${() => this.resetMeasurement()}
1886
1885
  .onAccept=${() => this.acceptMeasurement()}>
1887
- </xact-step-result>
1888
- <div>
1889
- <p>${this.errorMessage}</p>
1890
- </div>
1886
+ </xact-step-result>
1891
1887
  </div>
1892
1888
  ` : ""}
1893
1889
  <xact-footer></xact-footer>
@@ -749,7 +749,7 @@
749
749
  }
750
750
  }
751
751
 
752
- `,JA([j({type:Number})],Q.prototype,"height",2),JA([j({type:Function})],Q.prototype,"onStep2advancement",2),Q=JA([R("xact-step-informs"),w()],Q);const IA="data:image/svg+xml,%3csvg%20width='22'%20height='40'%20viewBox='0%200%2022%2040'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.517%200L0%2013.3362V0H21.517Z'%20fill='white'/%3e%3cpath%20d='M21.517%2013.339L0%2026.6724V13.3362H21.517V13.339Z'%20fill='white'/%3e%3cpath%20d='M21.517%2026.6755L0%2040.0089V26.6726H21.517V26.6755Z'%20fill='%231C28BA'/%3e%3c/svg%3e",ht="data:image/svg+xml,%3csvg%20width='22'%20height='41'%20viewBox='0%200%2022%2041'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.517%200.00878906L0%2013.345V0.00878906H21.517Z'%20fill='white'/%3e%3cpath%20d='M21.517%2013.3478L0%2026.6812V13.345H21.517V13.3478Z'%20fill='%231C28BA'/%3e%3cpath%20d='M21.517%2026.6843L0%2040.0176V26.6814H21.517V26.6843Z'%20fill='white'/%3e%3c/svg%3e",Et="data:image/svg+xml,%3csvg%20width='22'%20height='41'%20viewBox='0%200%2022%2041'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.517%200.0204381L0%2013.3538V0.0175781H21.517V0.0204381Z'%20fill='%231C28BA'/%3e%3cpath%20d='M21.517%2013.3538L0%2026.69V13.3538H21.517Z'%20fill='white'/%3e%3cpath%20d='M21.517%2026.693L0%2040.0264V26.6902H21.517V26.693Z'%20fill='white'/%3e%3c/svg%3e";var It=Object.defineProperty,wt=Object.getOwnPropertyDescriptor,y=(r,A,t,l)=>{for(var e=l>1?void 0:l?wt(A,t):A,p=r.length-1,V;p>=0;p--)(V=r[p])&&(e=(l?V(A,t,e):V(e))||e);return l&&e&&It(A,t,e),e};const{getLocale:Yt,setLocale:XA}=Ut({sourceLocale:EA,targetLocales:vt,loadLocale:r=>H(Object.assign({"./generated/locales/pt-BR.ts":()=>Promise.resolve().then(()=>Ct)}),`./generated/locales/${r}.ts`,4)});a.BodyMeasurer=class extends X{constructor(){super(...arguments),this.spinnerFrame=0,this.apiKey="DB8mP9gStPfvdyeYbbuCV4Zf3SH745dI",this.tenantId="1",this.productSku="",this.apiUrl="https://xactsize-dotnet-api-923169850574.southamerica-east1.run.app/api/measurer/measure/body",this._culture="pt-BR",this.measurerKey="",this._isLocaleLoading=!1,this.showModal=!1,this.step=1,this.height=0,this.recommendedSize="",this.measurements={},this.errorMessage="",this.instructionMessage=n("Position yourself in front of the camera"),this.shouldStartMeasurement=!1,this.isLoading=!1,this.isFetching=!1,this.videoElement=null,this.stream=null,this.poolingTimeout=null,this.instructionMessageTimeout=null,this.cameras=[],this.currentCameraId=null}firstUpdated(){this.startSpinnerAnimation()}startSpinnerAnimation(){const A=[Et,ht,IA];this.spinnerInterval=setInterval(()=>{var l;const t=(l=this.shadowRoot)==null?void 0:l.querySelector(".spinner");t&&(t.src=A[this.spinnerFrame],this.spinnerFrame=(this.spinnerFrame+1)%A.length)},300)}get culture(){return this._culture}set culture(A){const t=this._culture;this._culture=A,this.requestUpdate("culture",t),this._applyLocale(A).catch(console.error)}async _applyLocale(A){try{this._isLocaleLoading=!0,this.requestUpdate(),await XA(A)}catch(t){console.error("Failed to load locale",A,t),await XA(EA)}finally{this._isLocaleLoading=!1,this.requestUpdate()}}get errorMap(){return{ERR_RIGHT_ARM_TOO_HIGH:n("Lower your right arm",{id:"ERR_RIGHT_ARM_TOO_HIGH"}),ERR_LEFT_ARM_TOO_HIGH:n("Lower your left arm",{id:"ERR_LEFT_ARM_TOO_HIGH"}),ERR_ARMS_NOT_RAISED:n("Raise both arms to a 45-degree angle",{id:"ERR_ARMS_NOT_RAISED"}),ERR_RIGHT_ARM_NOT_RAISED:n("Raise your right arm to a 45-degree angle",{id:"ERR_RIGHT_ARM_NOT_RAISED"}),ERR_LEFT_ARM_NOT_RAISED:n("Raise your left arm to a 45-degree angle",{id:"ERR_LEFT_ARM_NOT_RAISED"}),ERR_BODY_LANDMARKS_NOT_DETECTED:n("Ensure your full body is visible in the camera",{id:"ERR_BODY_LANDMARKS_NOT_DETECTED"}),ERR_HIPS_NOT_VISIBLE:n("Adjust your position to show your hips",{id:"ERR_HIPS_NOT_VISIBLE"}),ERR_TOO_CLOSE_TO_CAMERA:n("Step back from the camera",{id:"ERR_TOO_CLOSE_TO_CAMERA"}),ERR_NOT_SIDE_VIEW:n("Turn to show your side profile",{id:"ERR_NOT_SIDE_VIEW"}),ERR_INVALID_CLOTHING_TYPE:n("This clothing type is not supported; please contact support",{id:"ERR_INVALID_CLOTHING_TYPE"}),ERR_UPPER_BODY_NOT_VISIBLE:n("Adjust your position to show your upper body",{id:"ERR_UPPER_BODY_NOT_VISIBLE"}),ERR_HEAD_TOO_CLOSE_TO_EDGE:n("Move your head away from the edge of the frame",{id:"ERR_HEAD_TOO_CLOSE_TO_EDGE"}),ERR_LOWER_BODY_NOT_VISIBLE:n("Adjust your position to show your lower body",{id:"ERR_LOWER_BODY_NOT_VISIBLE"}),ERR_FEET_TOO_CLOSE_TO_EDGE:n("Move your feet away from the edge of the frame",{id:"ERR_FEET_TOO_CLOSE_TO_EDGE"}),ERR_BODY_TOO_CLOSE_TO_EDGE:n("Move your body away from the edge of the frame",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE"}),ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_LEFT:n("Move to the left to center your body",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_LEFT"}),ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_RIGHT:n("Move to the right to center your body",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_RIGHT"}),ERR_SHOULDERS_NOT_VISIBLE:n("Adjust your position to show your shoulders",{id:"ERR_SHOULDERS_NOT_VISIBLE"}),ERR_HEIGHT_MEASUREMENT_FAILED:n("Stand straight and ensure your full body is visible",{id:"ERR_HEIGHT_MEASUREMENT_FAILED"}),ERR_HEAD_POINT_NOT_DETECTED:n("Ensure your head is fully visible in the frame",{id:"ERR_HEAD_POINT_NOT_DETECTED"}),ERR_INCORRECT_POSTURE:n("Stand straight with your shoulders back",{id:"ERR_INCORRECT_POSTURE"}),ERR_HEM_MEASUREMENT_FAILED:n("Ensure your clothing hem is visible and clear",{id:"ERR_HEM_MEASUREMENT_FAILED"}),ERR_SHOULDER_MEASUREMENT_FAILED:n("Keep your shoulders relaxed and visible",{id:"ERR_SHOULDER_MEASUREMENT_FAILED"}),ERR_ARM_NOT_STRETCHED:n("Stretch your arms fully",{id:"ERR_ARM_NOT_STRETCHED"}),ERR_LEGS_NOT_DETECTED:n("Ensure your legs are fully visible in the frame",{id:"ERR_LEGS_NOT_DETECTED"}),ERR_HIPS_MEASUREMENT_FAILED:n("Stand straight and ensure your hips are visible",{id:"ERR_HIPS_MEASUREMENT_FAILED"}),ERR_WAIST_MEASUREMENT_FAILED:n("Stand straight and ensure your waist is visible",{id:"ERR_WAIST_MEASUREMENT_FAILED"}),ERR_INVALID_MEASURE_SIDE_VIEW:n("Turn to show a clear side profile",{id:"ERR_INVALID_MEASURE_SIDE_VIEW"}),ERR_INVALID_BODY_HEIGHT_TYPE:n("Ensure your full body is visible for height measurement",{id:"ERR_INVALID_BODY_HEIGHT_TYPE"}),ERR_IMAGE_LOAD_FAILED:n("Try again later; the image could not be processed",{id:"ERR_IMAGE_LOAD_FAILED"}),ERR_HEIGHT_INVALID:n("Height must be between 50 and 300 cm",{id:"ERR_HEIGHT_INVALID"})}}getTranslatedMessage(A){const t=this.errorMap[A];return t||(console.info("Error code is missing",A),n("An unexpected error occurred"))}connectedCallback(){super.connectedCallback(),document.addEventListener("keydown",this.handleEscKey.bind(this))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleEscKey.bind(this)),this.stopPolling(),clearInterval(this.spinnerInterval)}handleEscKey(A){A.key==="Escape"&&this.showModal&&this.closeModal()}openModal(){this.showModal=!0,this.step=1,this.height=0,this.instructionMessage=n("Position yourself in front of the camera")}closeModal(){this.showModal=!1,this.onMeasurementCanceled&&typeof this.onMeasurementCanceled=="function"&&this.onMeasurementCanceled(),this.stopPolling(),this.dispatchEvent(new CustomEvent("measurementCanceled",{detail:{}}))}async step2advancement(){if(this.height<50||this.height>300){this.errorMessage=this.getTranslatedMessage("ERR_HEIGHT_INVALID");return}this.step=3,this.errorMessage=""}async startMeasurement(){this.step=2,this.errorMessage="",this.shouldStartMeasurement=!0}updated(A){super.updated(A),A.has("step")&&this.step===3&&this.shouldStartMeasurement&&(this.initializeMeasurement(),this.shouldStartMeasurement=!1)}async initializeMeasurement(){this.videoElement=this.shadowRoot.querySelector("video");try{this.stream=await navigator.mediaDevices.getUserMedia({video:!0}),this.videoElement&&(this.videoElement.srcObject=this.stream,await this.videoElement.play(),await this.loadCameras(),this.startPolling())}catch{this.errorMessage=n("Error accessing webcam")}}async loadCameras(){try{const A=await navigator.mediaDevices.enumerateDevices();this.cameras=A.filter(t=>t.kind==="videoinput"),this.cameras.length>0&&(this.currentCameraId=this.cameras[0].deviceId)}catch(A){console.error("Error enumerating devices:",A)}}async flipCamera(){if(this.cameras.length<2)return;this.isLoading=!0,this.stopPolling();const t=(this.cameras.findIndex(l=>l.deviceId===this.currentCameraId)+1)%this.cameras.length;this.currentCameraId=this.cameras[t].deviceId;try{this.stream&&this.stream.getTracks().forEach(l=>l.stop()),this.stream=await navigator.mediaDevices.getUserMedia({video:{deviceId:{exact:this.currentCameraId}}}),this.videoElement&&(this.videoElement.srcObject=this.stream,await this.videoElement.play(),this.startPolling())}catch{this.errorMessage=n("Error switching camera")}finally{this.isLoading=!1}}async startPolling(){const A=async()=>{if(!this.videoElement||!this.stream||this.isFetching)return;const t=document.createElement("canvas");t.width=this.videoElement.videoWidth,t.height=this.videoElement.videoHeight;const l=t.getContext("2d");l==null||l.drawImage(this.videoElement,0,0,t.width,t.height);const e=await new Promise(S=>t.toBlob(q=>S(q),"image/jpeg")),p=new File([e],"frame.jpg",{type:"image/jpeg"}),V=new FormData;V.append("image",p),V.append("height",this.height.toString()),V.append("product_sku",this.productSku),this.measurerKey&&V.append("measurerKey",this.measurerKey);try{this.isFetching=!0,this.isLoading=!0,this.poolingTimeout!==null&&(clearTimeout(this.poolingTimeout),this.poolingTimeout=null),this.instructionMessageTimeout!==null&&(clearTimeout(this.instructionMessageTimeout),this.instructionMessageTimeout=null);const q=await(await fetch(this.apiUrl,{method:"POST",body:V,headers:{Accept:"application/json","Cache-Control":"no-store",Pragma:"no-cache","X-Api-Key":this.apiKey,"X-Tenant-Id":this.tenantId}})).json();this.isFetching=!1,this.isLoading=!1,this.errorMessage=q,q.success?(this.measurements=q.measurements,this.recommendedSize=q.ChosenSize,this.instructionMessage=n("Measurement successful!"),this.stopPolling(),this.step=4):(this.instructionMessage=this.getTranslatedMessage(q.message||"UNKNOWN_ERROR"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=n("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(A,0))},2e3))}catch{this.isFetching=!1,this.isLoading=!1,this.instructionMessage=n("Error processing measurement"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=n("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(A,0))},2e3)}};A()}stopPolling(){this.poolingTimeout!==null&&(clearTimeout(this.poolingTimeout),this.poolingTimeout=null),this.instructionMessageTimeout!==null&&(clearTimeout(this.instructionMessageTimeout),this.instructionMessageTimeout=null),this.stream&&(this.stream.getTracks().forEach(A=>A.stop()),this.stream=null)}acceptMeasurement(){this.dispatchEvent(new CustomEvent("measurementAccepted",{detail:{size:this.recommendedSize}})),this.onMeasurementAccepted&&typeof this.onMeasurementAccepted=="function"&&this.onMeasurementAccepted(),this.showModal=!1,this.stopPolling()}resetMeasurement(){this.step=1,this.height=0,this.recommendedSize="",this.measurements={},this.stopPolling()}stopMeasurement(){this.resetMeasurement(),this.showModal=!1}render(){return this._isLocaleLoading?J`<div hidden></div>`:J`
752
+ `,JA([j({type:Number})],Q.prototype,"height",2),JA([j({type:Function})],Q.prototype,"onStep2advancement",2),Q=JA([R("xact-step-informs"),w()],Q);const IA="data:image/svg+xml,%3csvg%20width='22'%20height='40'%20viewBox='0%200%2022%2040'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.517%200L0%2013.3362V0H21.517Z'%20fill='white'/%3e%3cpath%20d='M21.517%2013.339L0%2026.6724V13.3362H21.517V13.339Z'%20fill='white'/%3e%3cpath%20d='M21.517%2026.6755L0%2040.0089V26.6726H21.517V26.6755Z'%20fill='%231C28BA'/%3e%3c/svg%3e",ht="data:image/svg+xml,%3csvg%20width='22'%20height='41'%20viewBox='0%200%2022%2041'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.517%200.00878906L0%2013.345V0.00878906H21.517Z'%20fill='white'/%3e%3cpath%20d='M21.517%2013.3478L0%2026.6812V13.345H21.517V13.3478Z'%20fill='%231C28BA'/%3e%3cpath%20d='M21.517%2026.6843L0%2040.0176V26.6814H21.517V26.6843Z'%20fill='white'/%3e%3c/svg%3e",Et="data:image/svg+xml,%3csvg%20width='22'%20height='41'%20viewBox='0%200%2022%2041'%20fill='none'%20xmlns='http://www.w3.org/2000/svg'%3e%3cpath%20d='M21.517%200.0204381L0%2013.3538V0.0175781H21.517V0.0204381Z'%20fill='%231C28BA'/%3e%3cpath%20d='M21.517%2013.3538L0%2026.69V13.3538H21.517Z'%20fill='white'/%3e%3cpath%20d='M21.517%2026.693L0%2040.0264V26.6902H21.517V26.693Z'%20fill='white'/%3e%3c/svg%3e";var It=Object.defineProperty,wt=Object.getOwnPropertyDescriptor,y=(r,A,t,l)=>{for(var e=l>1?void 0:l?wt(A,t):A,p=r.length-1,V;p>=0;p--)(V=r[p])&&(e=(l?V(A,t,e):V(e))||e);return l&&e&&It(A,t,e),e};const{getLocale:Yt,setLocale:XA}=Ut({sourceLocale:EA,targetLocales:vt,loadLocale:r=>H(Object.assign({"./generated/locales/pt-BR.ts":()=>Promise.resolve().then(()=>Ct)}),`./generated/locales/${r}.ts`,4)});a.BodyMeasurer=class extends X{constructor(){super(...arguments),this.spinnerFrame=0,this.apiKey="DB8mP9gStPfvdyeYbbuCV4Zf3SH745dI",this.tenantId="1",this.productSku="",this.apiUrl="https://xactsize-dotnet-api-923169850574.southamerica-east1.run.app/api/measurer/measure/body",this._culture="pt-BR",this.measurerKey="",this._isLocaleLoading=!1,this.showModal=!1,this.step=1,this.height=0,this.recommendedSize="",this.measurements={},this.errorMessage="",this.instructionMessage=n("Position yourself in front of the camera"),this.shouldStartMeasurement=!1,this.isLoading=!1,this.isFetching=!1,this.videoElement=null,this.stream=null,this.poolingTimeout=null,this.instructionMessageTimeout=null,this.cameras=[],this.currentCameraId=null}firstUpdated(){this.startSpinnerAnimation()}startSpinnerAnimation(){const A=[Et,ht,IA];this.spinnerInterval=setInterval(()=>{var l;const t=(l=this.shadowRoot)==null?void 0:l.querySelector(".spinner");t&&(t.src=A[this.spinnerFrame],this.spinnerFrame=(this.spinnerFrame+1)%A.length)},300)}get culture(){return this._culture}set culture(A){const t=this._culture;this._culture=A,this.requestUpdate("culture",t),this._applyLocale(A).catch(console.error)}async _applyLocale(A){try{this._isLocaleLoading=!0,this.requestUpdate(),await XA(A)}catch(t){console.error("Failed to load locale",A,t),await XA(EA)}finally{this._isLocaleLoading=!1,this.requestUpdate()}}get errorMap(){return{ERR_RIGHT_ARM_TOO_HIGH:n("Lower your right arm",{id:"ERR_RIGHT_ARM_TOO_HIGH"}),ERR_LEFT_ARM_TOO_HIGH:n("Lower your left arm",{id:"ERR_LEFT_ARM_TOO_HIGH"}),ERR_ARMS_NOT_RAISED:n("Raise both arms to a 45-degree angle",{id:"ERR_ARMS_NOT_RAISED"}),ERR_RIGHT_ARM_NOT_RAISED:n("Raise your right arm to a 45-degree angle",{id:"ERR_RIGHT_ARM_NOT_RAISED"}),ERR_LEFT_ARM_NOT_RAISED:n("Raise your left arm to a 45-degree angle",{id:"ERR_LEFT_ARM_NOT_RAISED"}),ERR_BODY_LANDMARKS_NOT_DETECTED:n("Ensure your full body is visible in the camera",{id:"ERR_BODY_LANDMARKS_NOT_DETECTED"}),ERR_HIPS_NOT_VISIBLE:n("Adjust your position to show your hips",{id:"ERR_HIPS_NOT_VISIBLE"}),ERR_TOO_CLOSE_TO_CAMERA:n("Step back from the camera",{id:"ERR_TOO_CLOSE_TO_CAMERA"}),ERR_NOT_SIDE_VIEW:n("Turn to show your side profile",{id:"ERR_NOT_SIDE_VIEW"}),ERR_INVALID_CLOTHING_TYPE:n("This clothing type is not supported; please contact support",{id:"ERR_INVALID_CLOTHING_TYPE"}),ERR_UPPER_BODY_NOT_VISIBLE:n("Adjust your position to show your upper body",{id:"ERR_UPPER_BODY_NOT_VISIBLE"}),ERR_HEAD_TOO_CLOSE_TO_EDGE:n("Move your head away from the edge of the frame",{id:"ERR_HEAD_TOO_CLOSE_TO_EDGE"}),ERR_LOWER_BODY_NOT_VISIBLE:n("Adjust your position to show your lower body",{id:"ERR_LOWER_BODY_NOT_VISIBLE"}),ERR_FEET_TOO_CLOSE_TO_EDGE:n("Move your feet away from the edge of the frame",{id:"ERR_FEET_TOO_CLOSE_TO_EDGE"}),ERR_BODY_TOO_CLOSE_TO_EDGE:n("Move your body away from the edge of the frame",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE"}),ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_LEFT:n("Move to the left to center your body",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_LEFT"}),ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_RIGHT:n("Move to the right to center your body",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_RIGHT"}),ERR_SHOULDERS_NOT_VISIBLE:n("Adjust your position to show your shoulders",{id:"ERR_SHOULDERS_NOT_VISIBLE"}),ERR_HEIGHT_MEASUREMENT_FAILED:n("Stand straight and ensure your full body is visible",{id:"ERR_HEIGHT_MEASUREMENT_FAILED"}),ERR_HEAD_POINT_NOT_DETECTED:n("Ensure your head is fully visible in the frame",{id:"ERR_HEAD_POINT_NOT_DETECTED"}),ERR_INCORRECT_POSTURE:n("Stand straight with your shoulders back",{id:"ERR_INCORRECT_POSTURE"}),ERR_HEM_MEASUREMENT_FAILED:n("Ensure your clothing hem is visible and clear",{id:"ERR_HEM_MEASUREMENT_FAILED"}),ERR_SHOULDER_MEASUREMENT_FAILED:n("Keep your shoulders relaxed and visible",{id:"ERR_SHOULDER_MEASUREMENT_FAILED"}),ERR_ARM_NOT_STRETCHED:n("Stretch your arms fully",{id:"ERR_ARM_NOT_STRETCHED"}),ERR_LEGS_NOT_DETECTED:n("Ensure your legs are fully visible in the frame",{id:"ERR_LEGS_NOT_DETECTED"}),ERR_HIPS_MEASUREMENT_FAILED:n("Stand straight and ensure your hips are visible",{id:"ERR_HIPS_MEASUREMENT_FAILED"}),ERR_WAIST_MEASUREMENT_FAILED:n("Stand straight and ensure your waist is visible",{id:"ERR_WAIST_MEASUREMENT_FAILED"}),ERR_INVALID_MEASURE_SIDE_VIEW:n("Turn to show a clear side profile",{id:"ERR_INVALID_MEASURE_SIDE_VIEW"}),ERR_INVALID_BODY_HEIGHT_TYPE:n("Ensure your full body is visible for height measurement",{id:"ERR_INVALID_BODY_HEIGHT_TYPE"}),ERR_IMAGE_LOAD_FAILED:n("Try again later; the image could not be processed",{id:"ERR_IMAGE_LOAD_FAILED"}),ERR_HEIGHT_INVALID:n("Height must be between 50 and 300 cm",{id:"ERR_HEIGHT_INVALID"})}}getTranslatedMessage(A){const t=this.errorMap[A];return t||(console.info("Error code is missing",A),n("An unexpected error occurred"))}connectedCallback(){super.connectedCallback(),document.addEventListener("keydown",this.handleEscKey.bind(this))}disconnectedCallback(){super.disconnectedCallback(),document.removeEventListener("keydown",this.handleEscKey.bind(this)),this.stopPolling(),clearInterval(this.spinnerInterval)}handleEscKey(A){A.key==="Escape"&&this.showModal&&this.closeModal()}openModal(){this.showModal=!0,this.step=1,this.height=0,this.instructionMessage=n("Position yourself in front of the camera")}closeModal(){this.showModal=!1,this.onMeasurementCanceled&&typeof this.onMeasurementCanceled=="function"&&this.onMeasurementCanceled(),this.stopPolling(),this.dispatchEvent(new CustomEvent("measurementCanceled",{detail:{}}))}async step2advancement(){if(this.height<50||this.height>300){this.errorMessage=this.getTranslatedMessage("ERR_HEIGHT_INVALID");return}this.step=3,this.errorMessage=""}async startMeasurement(){this.step=2,this.errorMessage="",this.shouldStartMeasurement=!0}updated(A){super.updated(A),A.has("step")&&this.step===3&&this.shouldStartMeasurement&&(this.initializeMeasurement(),this.shouldStartMeasurement=!1)}async initializeMeasurement(){this.videoElement=this.shadowRoot.querySelector("video");try{this.stream=await navigator.mediaDevices.getUserMedia({video:!0}),this.videoElement&&(this.videoElement.srcObject=this.stream,await this.videoElement.play(),await this.loadCameras(),this.startPolling())}catch{this.errorMessage=n("Error accessing webcam")}}async loadCameras(){try{const A=await navigator.mediaDevices.enumerateDevices();this.cameras=A.filter(t=>t.kind==="videoinput"),this.cameras.length>0&&(this.currentCameraId=this.cameras[0].deviceId)}catch(A){console.error("Error enumerating devices:",A)}}async flipCamera(){if(this.cameras.length<2)return;this.isLoading=!0,this.stopPolling();const t=(this.cameras.findIndex(l=>l.deviceId===this.currentCameraId)+1)%this.cameras.length;this.currentCameraId=this.cameras[t].deviceId;try{this.stream&&this.stream.getTracks().forEach(l=>l.stop()),this.stream=await navigator.mediaDevices.getUserMedia({video:{deviceId:{exact:this.currentCameraId}}}),this.videoElement&&(this.videoElement.srcObject=this.stream,await this.videoElement.play(),this.startPolling())}catch{this.errorMessage=n("Error switching camera")}finally{this.isLoading=!1}}async startPolling(){const A=async()=>{if(!this.videoElement||!this.stream||this.isFetching)return;const t=document.createElement("canvas");t.width=this.videoElement.videoWidth,t.height=this.videoElement.videoHeight;const l=t.getContext("2d");l==null||l.drawImage(this.videoElement,0,0,t.width,t.height);const e=await new Promise(S=>t.toBlob(q=>S(q),"image/jpeg")),p=new File([e],"frame.jpg",{type:"image/jpeg"}),V=new FormData;V.append("image",p),V.append("height",this.height.toString()),V.append("productSku",this.productSku),this.measurerKey&&V.append("measurerKey",this.measurerKey);try{this.isFetching=!0,this.isLoading=!0,this.poolingTimeout!==null&&(clearTimeout(this.poolingTimeout),this.poolingTimeout=null),this.instructionMessageTimeout!==null&&(clearTimeout(this.instructionMessageTimeout),this.instructionMessageTimeout=null);const q=await(await fetch(this.apiUrl,{method:"POST",body:V,headers:{Accept:"application/json","Cache-Control":"no-store",Pragma:"no-cache","X-Api-Key":this.apiKey}})).json();this.isFetching=!1,this.isLoading=!1,this.errorMessage=JSON.stringify(q),q.success?(this.measurements=q.measurements,this.recommendedSize=q.chosenSize,this.instructionMessage=n("Measurement successful!"),this.stopPolling(),this.step=4):(this.instructionMessage=this.getTranslatedMessage(q.message||"UNKNOWN_ERROR"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=n("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(A,0))},2e3))}catch{this.isFetching=!1,this.isLoading=!1,this.instructionMessage=n("Error processing measurement"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=n("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(A,0))},2e3)}};A()}stopPolling(){this.poolingTimeout!==null&&(clearTimeout(this.poolingTimeout),this.poolingTimeout=null),this.instructionMessageTimeout!==null&&(clearTimeout(this.instructionMessageTimeout),this.instructionMessageTimeout=null),this.stream&&(this.stream.getTracks().forEach(A=>A.stop()),this.stream=null)}acceptMeasurement(){this.dispatchEvent(new CustomEvent("measurementAccepted",{detail:{size:this.recommendedSize}})),this.onMeasurementAccepted&&typeof this.onMeasurementAccepted=="function"&&this.onMeasurementAccepted(),this.showModal=!1,this.stopPolling()}resetMeasurement(){this.step=1,this.height=0,this.recommendedSize="",this.measurements={},this.stopPolling()}stopMeasurement(){this.resetMeasurement(),this.showModal=!1}render(){return this._isLocaleLoading?J`<div hidden></div>`:J`
753
753
  <xact-button @click=${this.openModal} label="${n("Find your Xactsize")}"></xact-button>
754
754
 
755
755
  ${this.showModal?J`
@@ -798,10 +798,7 @@
798
798
  .recommendedSize=${this.recommendedSize}
799
799
  .onRetry=${()=>this.resetMeasurement()}
800
800
  .onAccept=${()=>this.acceptMeasurement()}>
801
- </xact-step-result>
802
- <div>
803
- <p>${this.errorMessage}</p>
804
- </div>
801
+ </xact-step-result>
805
802
  </div>
806
803
  `:""}
807
804
  <xact-footer></xact-footer>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xactsize-webcomponents",
3
- "version": "1.0.19",
3
+ "version": "1.0.20",
4
4
  "description": "A web component for body measurements and size recommendations",
5
5
  "main": "dist/body-measurer.umd.js",
6
6
  "module": "dist/body-measurer.es.js",