xactsize-webcomponents 1.0.10 → 1.0.11

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.
@@ -1531,7 +1531,8 @@ let d = class extends C {
1531
1531
  Accept: "application/json",
1532
1532
  // Ensure JSON response
1533
1533
  "Cache-Control": "no-store",
1534
- Pragma: "no-cache"
1534
+ Pragma: "no-cache",
1535
+ "X-Api-Key": this.apiKey
1535
1536
  }
1536
1537
  })).json();
1537
1538
  this.isFetching = !1, this.isLoading = !1, h.success ? (this.measurements = h.measurements, this.recommendedSize = h.chosenSize, this.instructionMessage = a("Measurement successful!"), this.stopPolling(), this.step = 3) : (this.instructionMessage = this.getTranslatedMessage(h.message || "UNKNOWN_ERROR"), this.instructionMessageTimeout = setTimeout(() => {
@@ -512,7 +512,7 @@
512
512
  max-width: 50%;
513
513
  }
514
514
  }
515
- `,q([_({type:String})],O.prototype,"productName",2),q([_({type:String})],O.prototype,"recommendedSize",2),q([_({type:Function})],O.prototype,"onAccept",2),q([_({type:Function})],O.prototype,"onRetry",2),O=q([G("xact-step-result"),J()],O);const je="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",Nt="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",Ut="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 Vt=Object.defineProperty,zt=Object.getOwnPropertyDescriptor,u=(o,e,t,i)=>{for(var s=i>1?void 0:i?zt(e,t):e,r=o.length-1,n;r>=0;r--)(n=o[r])&&(s=(i?n(e,t,s):n(s))||s);return i&&s&&Vt(e,t,s),s};const{getLocale:jt,setLocale:ge}=bt({sourceLocale:ze,targetLocales:At,loadLocale:o=>H(Object.assign({"./generated/locales/pt-BR.ts":()=>Promise.resolve().then(()=>Ft)}),`./generated/locales/${o}.ts`,4)});c.BodyMeasurer=class extends y{constructor(){super(...arguments),this.spinnerFrame=0,this.apiKey="",this._culture="pt-BR",this._isLocaleLoading=!1,this.skus=[],this.productName="",this.showModal=!1,this.step=1,this.height=0,this.recommendedSize="",this.measurements={},this.errorMessage="",this.instructionMessage=l("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 e=[Ut,Nt,je];this.spinnerInterval=setInterval(()=>{var i;const t=(i=this.shadowRoot)==null?void 0:i.querySelector(".spinner");t&&(t.src=e[this.spinnerFrame],this.spinnerFrame=(this.spinnerFrame+1)%e.length)},300)}get culture(){return this._culture}set culture(e){const t=this._culture;this._culture=e,this.requestUpdate("culture",t),this._applyLocale(e).catch(console.error)}async _applyLocale(e){try{this._isLocaleLoading=!0,this.requestUpdate(),await ge(e)}catch(t){console.error("Failed to load locale",e,t),await ge(ze)}finally{this._isLocaleLoading=!1,this.requestUpdate()}}get errorMap(){return{ERR_RIGHT_ARM_TOO_HIGH:l("Lower your right arm",{id:"ERR_RIGHT_ARM_TOO_HIGH"}),ERR_LEFT_ARM_TOO_HIGH:l("Lower your left arm",{id:"ERR_LEFT_ARM_TOO_HIGH"}),ERR_ARMS_NOT_RAISED:l("Raise both arms to a 45-degree angle",{id:"ERR_ARMS_NOT_RAISED"}),ERR_RIGHT_ARM_NOT_RAISED:l("Raise your right arm to a 45-degree angle",{id:"ERR_RIGHT_ARM_NOT_RAISED"}),ERR_LEFT_ARM_NOT_RAISED:l("Raise your left arm to a 45-degree angle",{id:"ERR_LEFT_ARM_NOT_RAISED"}),ERR_BODY_LANDMARKS_NOT_DETECTED:l("Ensure your full body is visible in the camera",{id:"ERR_BODY_LANDMARKS_NOT_DETECTED"}),ERR_HIPS_NOT_VISIBLE:l("Adjust your position to show your hips",{id:"ERR_HIPS_NOT_VISIBLE"}),ERR_TOO_CLOSE_TO_CAMERA:l("Step back from the camera",{id:"ERR_TOO_CLOSE_TO_CAMERA"}),ERR_NOT_SIDE_VIEW:l("Turn to show your side profile",{id:"ERR_NOT_SIDE_VIEW"}),ERR_INVALID_CLOTHING_TYPE:l("This clothing type is not supported; please contact support",{id:"ERR_INVALID_CLOTHING_TYPE"}),ERR_UPPER_BODY_NOT_VISIBLE:l("Adjust your position to show your upper body",{id:"ERR_UPPER_BODY_NOT_VISIBLE"}),ERR_HEAD_TOO_CLOSE_TO_EDGE:l("Move your head away from the edge of the frame",{id:"ERR_HEAD_TOO_CLOSE_TO_EDGE"}),ERR_LOWER_BODY_NOT_VISIBLE:l("Adjust your position to show your lower body",{id:"ERR_LOWER_BODY_NOT_VISIBLE"}),ERR_FEET_TOO_CLOSE_TO_EDGE:l("Move your feet away from the edge of the frame",{id:"ERR_FEET_TOO_CLOSE_TO_EDGE"}),ERR_BODY_TOO_CLOSE_TO_EDGE:l("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:l("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:l("Move to the right to center your body",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_RIGHT"}),ERR_SHOULDERS_NOT_VISIBLE:l("Adjust your position to show your shoulders",{id:"ERR_SHOULDERS_NOT_VISIBLE"}),ERR_HEIGHT_MEASUREMENT_FAILED:l("Stand straight and ensure your full body is visible",{id:"ERR_HEIGHT_MEASUREMENT_FAILED"}),ERR_HEAD_POINT_NOT_DETECTED:l("Ensure your head is fully visible in the frame",{id:"ERR_HEAD_POINT_NOT_DETECTED"}),ERR_INCORRECT_POSTURE:l("Stand straight with your shoulders back",{id:"ERR_INCORRECT_POSTURE"}),ERR_HEM_MEASUREMENT_FAILED:l("Ensure your clothing hem is visible and clear",{id:"ERR_HEM_MEASUREMENT_FAILED"}),ERR_SHOULDER_MEASUREMENT_FAILED:l("Keep your shoulders relaxed and visible",{id:"ERR_SHOULDER_MEASUREMENT_FAILED"}),ERR_ARM_NOT_STRETCHED:l("Stretch your arms fully",{id:"ERR_ARM_NOT_STRETCHED"}),ERR_LEGS_NOT_DETECTED:l("Ensure your legs are fully visible in the frame",{id:"ERR_LEGS_NOT_DETECTED"}),ERR_HIPS_MEASUREMENT_FAILED:l("Stand straight and ensure your hips are visible",{id:"ERR_HIPS_MEASUREMENT_FAILED"}),ERR_WAIST_MEASUREMENT_FAILED:l("Stand straight and ensure your waist is visible",{id:"ERR_WAIST_MEASUREMENT_FAILED"}),ERR_INVALID_MEASURE_SIDE_VIEW:l("Turn to show a clear side profile",{id:"ERR_INVALID_MEASURE_SIDE_VIEW"}),ERR_INVALID_BODY_HEIGHT_TYPE:l("Ensure your full body is visible for height measurement",{id:"ERR_INVALID_BODY_HEIGHT_TYPE"}),ERR_IMAGE_LOAD_FAILED:l("Try again later; the image could not be processed",{id:"ERR_IMAGE_LOAD_FAILED"}),ERR_HEIGHT_INVALID:l("Height must be between 50 and 300 cm",{id:"ERR_HEIGHT_INVALID"})}}getTranslatedMessage(e){const t=this.errorMap[e];return t||(console.info("Error code is missing",e),l("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(e){e.key==="Escape"&&this.showModal&&this.closeModal()}openModal(){this.showModal=!0,this.step=1,this.height=0,this.instructionMessage=l("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 startMeasurement(){if(this.height<50||this.height>300){this.errorMessage=this.getTranslatedMessage("ERR_HEIGHT_INVALID");return}this.step=2,this.errorMessage="",this.shouldStartMeasurement=!0}updated(e){super.updated(e),e.has("step")&&this.step===2&&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=l("Error accessing webcam")}}async loadCameras(){try{const e=await navigator.mediaDevices.enumerateDevices();this.cameras=e.filter(t=>t.kind==="videoinput"),this.cameras.length>0&&(this.currentCameraId=this.cameras[0].deviceId)}catch(e){console.error("Error enumerating devices:",e)}}async flipCamera(){if(this.cameras.length<2)return;this.isLoading=!0,this.stopPolling();const t=(this.cameras.findIndex(i=>i.deviceId===this.currentCameraId)+1)%this.cameras.length;this.currentCameraId=this.cameras[t].deviceId;try{this.stream&&this.stream.getTracks().forEach(i=>i.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=l("Error switching camera")}finally{this.isLoading=!1}}async startPolling(){const e=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 i=t.getContext("2d");i==null||i.drawImage(this.videoElement,0,0,t.width,t.height);const s=await new Promise(d=>t.toBlob(a=>d(a),"image/jpeg")),r=new File([s],"frame.jpg",{type:"image/jpeg"}),n=new FormData;n.append("image",r),n.append("height",this.height.toString()),n.append("type","shirt"),n.append("skus",JSON.stringify(this.skus));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 a=await(await fetch("https://xactsize-api-923169850574.southamerica-east1.run.app/api/measurer/measure/body",{method:"POST",body:n,headers:{Accept:"application/json","Cache-Control":"no-store",Pragma:"no-cache"}})).json();this.isFetching=!1,this.isLoading=!1,a.success?(this.measurements=a.measurements,this.recommendedSize=a.chosenSize,this.instructionMessage=l("Measurement successful!"),this.stopPolling(),this.step=3):(this.instructionMessage=this.getTranslatedMessage(a.message||"UNKNOWN_ERROR"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=l("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(e,0))},2e3))}catch{this.isFetching=!1,this.isLoading=!1,this.instructionMessage=l("Error processing measurement"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=l("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(e,0))},2e3)}};e()}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(e=>e.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?E`<div hidden></div>`:E`
515
+ `,q([_({type:String})],O.prototype,"productName",2),q([_({type:String})],O.prototype,"recommendedSize",2),q([_({type:Function})],O.prototype,"onAccept",2),q([_({type:Function})],O.prototype,"onRetry",2),O=q([G("xact-step-result"),J()],O);const je="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",Nt="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",Ut="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 Vt=Object.defineProperty,zt=Object.getOwnPropertyDescriptor,u=(o,e,t,i)=>{for(var s=i>1?void 0:i?zt(e,t):e,r=o.length-1,n;r>=0;r--)(n=o[r])&&(s=(i?n(e,t,s):n(s))||s);return i&&s&&Vt(e,t,s),s};const{getLocale:jt,setLocale:ge}=bt({sourceLocale:ze,targetLocales:At,loadLocale:o=>H(Object.assign({"./generated/locales/pt-BR.ts":()=>Promise.resolve().then(()=>Ft)}),`./generated/locales/${o}.ts`,4)});c.BodyMeasurer=class extends y{constructor(){super(...arguments),this.spinnerFrame=0,this.apiKey="",this._culture="pt-BR",this._isLocaleLoading=!1,this.skus=[],this.productName="",this.showModal=!1,this.step=1,this.height=0,this.recommendedSize="",this.measurements={},this.errorMessage="",this.instructionMessage=l("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 e=[Ut,Nt,je];this.spinnerInterval=setInterval(()=>{var i;const t=(i=this.shadowRoot)==null?void 0:i.querySelector(".spinner");t&&(t.src=e[this.spinnerFrame],this.spinnerFrame=(this.spinnerFrame+1)%e.length)},300)}get culture(){return this._culture}set culture(e){const t=this._culture;this._culture=e,this.requestUpdate("culture",t),this._applyLocale(e).catch(console.error)}async _applyLocale(e){try{this._isLocaleLoading=!0,this.requestUpdate(),await ge(e)}catch(t){console.error("Failed to load locale",e,t),await ge(ze)}finally{this._isLocaleLoading=!1,this.requestUpdate()}}get errorMap(){return{ERR_RIGHT_ARM_TOO_HIGH:l("Lower your right arm",{id:"ERR_RIGHT_ARM_TOO_HIGH"}),ERR_LEFT_ARM_TOO_HIGH:l("Lower your left arm",{id:"ERR_LEFT_ARM_TOO_HIGH"}),ERR_ARMS_NOT_RAISED:l("Raise both arms to a 45-degree angle",{id:"ERR_ARMS_NOT_RAISED"}),ERR_RIGHT_ARM_NOT_RAISED:l("Raise your right arm to a 45-degree angle",{id:"ERR_RIGHT_ARM_NOT_RAISED"}),ERR_LEFT_ARM_NOT_RAISED:l("Raise your left arm to a 45-degree angle",{id:"ERR_LEFT_ARM_NOT_RAISED"}),ERR_BODY_LANDMARKS_NOT_DETECTED:l("Ensure your full body is visible in the camera",{id:"ERR_BODY_LANDMARKS_NOT_DETECTED"}),ERR_HIPS_NOT_VISIBLE:l("Adjust your position to show your hips",{id:"ERR_HIPS_NOT_VISIBLE"}),ERR_TOO_CLOSE_TO_CAMERA:l("Step back from the camera",{id:"ERR_TOO_CLOSE_TO_CAMERA"}),ERR_NOT_SIDE_VIEW:l("Turn to show your side profile",{id:"ERR_NOT_SIDE_VIEW"}),ERR_INVALID_CLOTHING_TYPE:l("This clothing type is not supported; please contact support",{id:"ERR_INVALID_CLOTHING_TYPE"}),ERR_UPPER_BODY_NOT_VISIBLE:l("Adjust your position to show your upper body",{id:"ERR_UPPER_BODY_NOT_VISIBLE"}),ERR_HEAD_TOO_CLOSE_TO_EDGE:l("Move your head away from the edge of the frame",{id:"ERR_HEAD_TOO_CLOSE_TO_EDGE"}),ERR_LOWER_BODY_NOT_VISIBLE:l("Adjust your position to show your lower body",{id:"ERR_LOWER_BODY_NOT_VISIBLE"}),ERR_FEET_TOO_CLOSE_TO_EDGE:l("Move your feet away from the edge of the frame",{id:"ERR_FEET_TOO_CLOSE_TO_EDGE"}),ERR_BODY_TOO_CLOSE_TO_EDGE:l("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:l("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:l("Move to the right to center your body",{id:"ERR_BODY_TOO_CLOSE_TO_EDGE_MOVE_RIGHT"}),ERR_SHOULDERS_NOT_VISIBLE:l("Adjust your position to show your shoulders",{id:"ERR_SHOULDERS_NOT_VISIBLE"}),ERR_HEIGHT_MEASUREMENT_FAILED:l("Stand straight and ensure your full body is visible",{id:"ERR_HEIGHT_MEASUREMENT_FAILED"}),ERR_HEAD_POINT_NOT_DETECTED:l("Ensure your head is fully visible in the frame",{id:"ERR_HEAD_POINT_NOT_DETECTED"}),ERR_INCORRECT_POSTURE:l("Stand straight with your shoulders back",{id:"ERR_INCORRECT_POSTURE"}),ERR_HEM_MEASUREMENT_FAILED:l("Ensure your clothing hem is visible and clear",{id:"ERR_HEM_MEASUREMENT_FAILED"}),ERR_SHOULDER_MEASUREMENT_FAILED:l("Keep your shoulders relaxed and visible",{id:"ERR_SHOULDER_MEASUREMENT_FAILED"}),ERR_ARM_NOT_STRETCHED:l("Stretch your arms fully",{id:"ERR_ARM_NOT_STRETCHED"}),ERR_LEGS_NOT_DETECTED:l("Ensure your legs are fully visible in the frame",{id:"ERR_LEGS_NOT_DETECTED"}),ERR_HIPS_MEASUREMENT_FAILED:l("Stand straight and ensure your hips are visible",{id:"ERR_HIPS_MEASUREMENT_FAILED"}),ERR_WAIST_MEASUREMENT_FAILED:l("Stand straight and ensure your waist is visible",{id:"ERR_WAIST_MEASUREMENT_FAILED"}),ERR_INVALID_MEASURE_SIDE_VIEW:l("Turn to show a clear side profile",{id:"ERR_INVALID_MEASURE_SIDE_VIEW"}),ERR_INVALID_BODY_HEIGHT_TYPE:l("Ensure your full body is visible for height measurement",{id:"ERR_INVALID_BODY_HEIGHT_TYPE"}),ERR_IMAGE_LOAD_FAILED:l("Try again later; the image could not be processed",{id:"ERR_IMAGE_LOAD_FAILED"}),ERR_HEIGHT_INVALID:l("Height must be between 50 and 300 cm",{id:"ERR_HEIGHT_INVALID"})}}getTranslatedMessage(e){const t=this.errorMap[e];return t||(console.info("Error code is missing",e),l("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(e){e.key==="Escape"&&this.showModal&&this.closeModal()}openModal(){this.showModal=!0,this.step=1,this.height=0,this.instructionMessage=l("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 startMeasurement(){if(this.height<50||this.height>300){this.errorMessage=this.getTranslatedMessage("ERR_HEIGHT_INVALID");return}this.step=2,this.errorMessage="",this.shouldStartMeasurement=!0}updated(e){super.updated(e),e.has("step")&&this.step===2&&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=l("Error accessing webcam")}}async loadCameras(){try{const e=await navigator.mediaDevices.enumerateDevices();this.cameras=e.filter(t=>t.kind==="videoinput"),this.cameras.length>0&&(this.currentCameraId=this.cameras[0].deviceId)}catch(e){console.error("Error enumerating devices:",e)}}async flipCamera(){if(this.cameras.length<2)return;this.isLoading=!0,this.stopPolling();const t=(this.cameras.findIndex(i=>i.deviceId===this.currentCameraId)+1)%this.cameras.length;this.currentCameraId=this.cameras[t].deviceId;try{this.stream&&this.stream.getTracks().forEach(i=>i.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=l("Error switching camera")}finally{this.isLoading=!1}}async startPolling(){const e=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 i=t.getContext("2d");i==null||i.drawImage(this.videoElement,0,0,t.width,t.height);const s=await new Promise(d=>t.toBlob(a=>d(a),"image/jpeg")),r=new File([s],"frame.jpg",{type:"image/jpeg"}),n=new FormData;n.append("image",r),n.append("height",this.height.toString()),n.append("type","shirt"),n.append("skus",JSON.stringify(this.skus));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 a=await(await fetch("https://xactsize-api-923169850574.southamerica-east1.run.app/api/measurer/measure/body",{method:"POST",body:n,headers:{Accept:"application/json","Cache-Control":"no-store",Pragma:"no-cache","X-Api-Key":this.apiKey}})).json();this.isFetching=!1,this.isLoading=!1,a.success?(this.measurements=a.measurements,this.recommendedSize=a.chosenSize,this.instructionMessage=l("Measurement successful!"),this.stopPolling(),this.step=3):(this.instructionMessage=this.getTranslatedMessage(a.message||"UNKNOWN_ERROR"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=l("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(e,0))},2e3))}catch{this.isFetching=!1,this.isLoading=!1,this.instructionMessage=l("Error processing measurement"),this.instructionMessageTimeout=setTimeout(()=>{this.recommendedSize||(this.instructionMessage=l("Position yourself in front of the camera"),this.poolingTimeout=setTimeout(e,0))},2e3)}};e()}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(e=>e.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?E`<div hidden></div>`:E`
516
516
  <xact-button @click=${this.openModal} label="${l("Find your Xactsize")}"></xact-button>
517
517
 
518
518
  ${this.showModal?E`
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "xactsize-webcomponents",
3
- "version": "1.0.10",
3
+ "version": "1.0.11",
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",