xactsize-webcomponents 1.0.17 → 1.0.19

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.
@@ -1804,7 +1804,7 @@ let a = class extends X {
1804
1804
  "X-Tenant-Id": this.tenantId
1805
1805
  }
1806
1806
  })).json();
1807
- this.isFetching = !1, this.isLoading = !1, 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(() => {
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(() => {
1808
1808
  this.recommendedSize || (this.instructionMessage = q("Position yourself in front of the camera"), this.poolingTimeout = setTimeout(l, 0));
1809
1809
  }, 2e3));
1810
1810
  } catch {
@@ -1885,6 +1885,9 @@ let a = class extends X {
1885
1885
  .onRetry=${() => this.resetMeasurement()}
1886
1886
  .onAccept=${() => this.acceptMeasurement()}>
1887
1887
  </xact-step-result>
1888
+ <div>
1889
+ <p>${this.errorMessage}</p>
1890
+ </div>
1888
1891
  </div>
1889
1892
  ` : ""}
1890
1893
  <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,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("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`
753
753
  <xact-button @click=${this.openModal} label="${n("Find your Xactsize")}"></xact-button>
754
754
 
755
755
  ${this.showModal?J`
@@ -799,6 +799,9 @@
799
799
  .onRetry=${()=>this.resetMeasurement()}
800
800
  .onAccept=${()=>this.acceptMeasurement()}>
801
801
  </xact-step-result>
802
+ <div>
803
+ <p>${this.errorMessage}</p>
804
+ </div>
802
805
  </div>
803
806
  `:""}
804
807
  <xact-footer></xact-footer>
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xactsize-webcomponents",
3
- "version": "1.0.17",
3
+ "version": "1.0.19",
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",