@swan-admin/swan-dev-web-component 0.1.0-alpha.1775220535 → 0.1.0-alpha.1775222516
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/FaceScan-B160VNef.js +2 -0
- package/dist/FaceScan-BeMPl-gC.js +2 -0
- package/dist/FaceScan-BeWA_QfG.js +2 -0
- package/dist/FaceScan-CLnu4dJd.js +2 -0
- package/dist/FaceScan-CXm-ZRzF.js +2 -0
- package/dist/FaceScan-DHPn0Xfr.js +2 -0
- package/dist/FaceScan-H1sDaOF2.js +2 -0
- package/dist/FaceScan-Q8GZC46J.js +2 -0
- package/dist/FaceScan-dV6X6vuh.js +2 -0
- package/dist/FaceScan-mBiHNeqn.js +2 -0
- package/dist/faceScan.js +1 -1
- package/dist/faceScan.mjs +1 -1
- package/dist/index.js +1 -1
- package/dist/index.mjs +1 -1
- package/package.json +1 -1
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("./Modal-B_UR_mwU.js"),n=require("lucide-react"),o=require("@mui/material");let s=null,r=!1;function c({faceScanId:e,onValidPose:n,onScanComplete:o,onModelReady:c,onStartRecording:i,shopDomain:l,isError:d,isSuccess:u}){const f=t.useRef(null),[g,h]=t.useState(0),[m,p]=t.useState(0),[y,S]=t.useState(!1),[x,v]=t.useState(!1),b=t.useRef(null),w=t.useRef(g),C=t.useRef(m),F=t.useRef([]),j=t.useRef(""),_=t.useRef(0),N=t.useRef(!1),E=t.useRef(0),k="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),T=t.useMemo(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),I=t.useMemo(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{a.posthog.capture(`${l}/face_scan_pose_detection`,e)},4e3),[l]),R=t.useCallback((t,a,n,o,s,r)=>{const c=Date.now();if(!(c-E.current<4e3)){E.current=c;try{const c=t[0]||[0,0,0],i=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],f=t.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,h=a.map(e=>e[2]).filter(e=>e>0),m=h.length>0?h.reduce((e,t)=>e+t,0)/h.length:0,p=Math.abs(i[0]-l[0]),y=c[0]-l[0],S=i[0]-c[0];let x="frontal";1===n?x="left":2===n?x="right":3===n&&(x="frontal_smile");const v={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:s,consecutiveValid:r,avgFaceScore:parseFloat(g.toFixed(3)),avgBodyScore:parseFloat(m.toFixed(3)),faceKeypointsDetected:f.length,bodyKeypointsDetected:h.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(c[2].toFixed(3)),leftEyeScore:parseFloat(i[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:x})};I(v)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,I]),M=()=>{a.posthog.capture(`${l}/face_scan_detection_started`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current]}),setTimeout(()=>{v(!0)},1500)},P=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(s)return s;if(r)for(;r;)if(await new Promise(e=>setTimeout(e,100)),s)return s;r=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),Promise.resolve().then(function(){return require("./pose-detection.esm-2mkM0o4k.js")})]);await e.setBackend("webgl"),await e.ready();const n=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),o=document.createElement("canvas");o.width="number"==typeof a.videoConstraints.width?a.videoConstraints.width:a.videoConstraints.width.ideal??a.videoConstraints.width.max??1280,o.height="number"==typeof a.videoConstraints.height?a.videoConstraints.height:a.videoConstraints.height.ideal??a.videoConstraints.height.max??720;const r=o.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,o.width,o.height);try{await n.estimatePoses(o)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return s=n,n}catch(e){return console.error("Failed to preload detector:",e),null}finally{r=!1}})();e&&(f.current=e,console.log("Face scan model loaded successfully"),S(!0),c?.())}catch(e){console.error("Error initializing face scan:",e)}};return t.useEffect(()=>{if(!d&&!u)return P(),()=>{(async()=>{try{S(!1)}catch(e){console.error("Error disposing resources:",e)}finally{h(0),p(0),w.current=0,C.current=0,F.current=[]}})()}},[d,u]),t.useEffect(()=>{w.current=g},[g]),t.useEffect(()=>{C.current=m},[m]),{faceScanDetector:async(t,s)=>{if(f.current&&t.current&&y&&x&&!(t.current.readyState<2))try{const r=await f.current.estimatePoses(t.current);if(r.length>0){const t=[],c=[];if(r[0].keypoints.forEach((e,a)=>{const n=e.score??0,o=[e.x??-1,e.y??-1,n];a<=10?t.push(o):c.push(o)}),s?.current){const e=s.current.getContext("2d"),{width:t,height:a}=s.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const d=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,s=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,r=t[2][0]-t[5][0],c=t[0][0]-t[5][0],i=c>.4*r&&c<.6*r,l=c>.85*r,d=t[2][0]-t[0][0]>.85*r;switch(e){case 0:case 3:return!o&&s&&i;case 1:return!o&&s&&l;case 2:return!o&&s&&d;default:return!1}})(w.current,t),u=c.slice(2).filter(e=>e[2]>.7).length<=2;F.current.push(d&&u),F.current.length>10&&F.current.shift();if(F.current.filter(Boolean).length>=2){const e=C.current+1;p(e)}else p(Math.max(0,C.current-1));if(C.current>=2){n?.();const t=w.current+1;p(0),F.current=[],h(t),v(!1),(async()=>{if(await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Sound-effect.mp3`),a.posthog.capture(`${l}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:w.current,nextStage:t,timestamp:(new Date).toISOString(),totalStages:4,stageName:T[w.current]}),1===t&&i&&i(),t>=4)o?.();else{let e=null;switch(t){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/${e}`),M()}})()}R(t,c,w.current,d,u,C.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:g,setScanStage:h,consecutiveValid:m,isModelLoaded:y,resetScan:()=>{a.posthog.capture(`${l}/face_scan_reset`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current],consecutiveValid:C.current}),h(0),p(0),v(!1),w.current=0,C.current=0,F.current=[],j.current="",_.current=0,N.current=!1,b.current&&(speechSynthesis.cancel(),b.current=null)},enableVoiceCommands:()=>{if(N.current=!0,"undefined"!=typeof window&&k&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:M,isScanningActive:x}}function i({onRetry:o,loading:s}){const{translate:r}=t.useContext(a.LanguageContext)||{},c=a.useConfig();return e.jsx("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:c?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e.jsx(a.Header,{noTitle:!0}),e.jsxs("div",{className:"flex flex-col items-center w-full",children:[e.jsx("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:c?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:c?.style?.heading?.headingFontSize||"32px",color:c?.style?.heading?.headingColor||"#000",fontWeight:c?.style?.heading?.headingFontWeight||"normal"},children:r?.(a.LanguageKeys.scanFailed)}),e.jsx("p",{className:"mb-[1.5rem]",style:{fontFamily:c?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:c?.style?.subheading?.subheadingFontSize||"14px",color:c?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:c?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(a.LanguageKeys.clickToResetScan)}),e.jsx(a.SpecificButton,{disabled:s,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(a.LanguageKeys.resetScan),postfixIcon:e.jsx(n.ArrowRight,{}),buttonFunc:()=>o?.()})]})]})})}function l({stage:n,videoLoading:o,setVideoLoading:s,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=t.useContext(a.LanguageContext)||{},u=a.useConfig();return-1===n?e.jsxs("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.LanguageKeys.faceVisible)}),o&&e.jsx("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.loadingVideo)}),r&&e.jsx("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.videoLoadFailed)}),!r&&e.jsx("div",{className:" w-[100px] mx-auto",children:e.jsx("video",{src:i===a.GenderType.Male?a.maleGlassesOffVideo:a.glassesOffVideo,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>s(!1),onLoadStart:()=>s(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e.jsx("div",{className:"flex justify-center w-full p-[1rem]",children:e.jsx(a.SpecificButton,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e.jsx("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.directionMessages[n])}),e.jsxs("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e.jsx("div",{className:` w-[120px] overflow-hidden ${0===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.forward:a.FACE_SCAN_HEADSHOT.female.forward,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${1===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.left:a.FACE_SCAN_HEADSHOT.female.left,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${2===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.right:a.FACE_SCAN_HEADSHOT.female.right,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${3===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.smile:a.FACE_SCAN_HEADSHOT.female.smile,type:"video/mp4"})})})]})]})})}const d=({webcamRef:s,canvasRef:r})=>{const{isError:c,isSuccess:d,showLoader:u,hasError:f,resetScanState:g,showGuideCard:h,scanStage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,getButtonText:b,isScanning:w,startScan:C,isModelLoaded:F,isLandscape:j,onRetry:_}=t.useContext(a.ParamsContext),N=a.useConfig();return c?e.jsx(i,{onRetry:_}):d?e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}):e.jsxs(e.Fragment,{children:[e.jsx("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),j&&!u&&!f&&e.jsx("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:N?.style?.base?.backgroundColor||"#fff"},children:e.jsx(a.Modal,{variant:"portrait",config:N})}),u&&!f&&e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}),e.jsx("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:N?.style?.base?.backgroundColor},children:e.jsx("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:e.jsxs("div",{className:"w-full h-full",children:[e.jsx("video",{ref:s,autoPlay:!0,playsInline:!0,muted:!0,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e.jsx("canvas",{ref:r,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!u&&f&&e.jsx(i,{loading:u,onRetry:g}),h&&!f&&!u&&!j&&e.jsx(o.Drawer,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e.jsx(l,{stage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,btnConfig:{label:b(),onClick:w?g:C,isDisabled:u||!F,icon:w?e.jsx(n.ArrowRight,{}):e.jsx(e.Fragment,{})}})})]})};exports.FaceScan=n=>{const{onScanSuccess:o,onScanError:s,onRetry:r,onScanStart:i,onCaptureComplete:l,onUploadStart:u,onUploadEnd:f,onMeasurementSocketStart:g,onMeasurementSocketClose:h,config:m,isError:p,isSuccess:y}=n,S=n.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},x=n.token??"",v=t.useRef(null),b=t.useRef(null),w=t.useRef(null),C=t.useRef([]),F=t.useRef(null),j=t.useRef(null),[_,N]=t.useState(!1),[E,k]=t.useState(!1),[T,I]=t.useState(!1),[R,M]=t.useState(!0),[P,D]=t.useState(!1),[L,A]=t.useState(!1),[O,z]=t.useState(!1),[$,H]=t.useState(a.generateUuid()),V=t.useMemo(()=>a.getSwanService(x),[x]),{isLandscape:W}=a.usePortraitLock(),{email:K,gender:U,deviceFocalLength:B,shopDomain:q,callbackUrl:G,bodyScanId:J}=S,[X,Q]=t.useState([]),[Y,Z]=t.useState(a.videoConstraintsExact),ee=t.useMemo(()=>a.getPreferredMediaRecorderTypes(),[]),te=a.getRecordingMimeType(X),ae=a.getRecordingExtension(te);a.usePosthogPageview();const ne=t.useCallback(()=>{console.log("Stopping recording..."),w.current&&"recording"===w.current.state&&w.current.stop(),w.current=null},[]),oe=async()=>{if(l?.(),C.current){if(0===C.current.length)return console.error("No video data recorded"),z(!0),void N(!1);u?.(),N(!0);const e=new File(C.current,`${$}.${ae}`,{type:te}),t=j.current??await a.getVideoFPS(e),n=e.size,o=(n/1048576).toFixed(2),s=Math.round(n/1e4),r={video_size_mb:parseFloat(o),video_size_bytes:n,video_fps:t||0,blob_count:C.current.length,estimated_duration_seconds:s},c=[{gender:U},{face_scan_id:$},{focal_length:`${B}`},{customer_store_url:q},{scan_type:"face_scan"},{body_scan_id:J}];G&&c.push({callback_url:G}),a.handleScanTimeCapture({eventName:`${q}/face_scan_meta_data`,faceScanId:$,email:K,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_start`,faceScanId:$,email:K,startTime:i});try{const t=await V.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:$,email:K,contentType:e.type}),n=Date.now(),o=n-i;a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_complete`,faceScanId:$,email:K,completionTime:n,uploadDuration:o}),f?.(),console.log("✅ Upload successful",t),V.measurement.handlFaceScaneSocket({onPreopen:()=>{g?.(),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"pre_open",type:"faceScan_recommendation",email:K})},faceScanId:$,onOpen:()=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"open",type:"faceScan_recommendation",email:K}),console.log("websocket connect open")},onError:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"error",type:"faceScan_recommendation",email:K}),me(e)},onSuccess:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"success",type:"faceScan_recommendation",email:K}),pe(e)},onClose:()=>{h?.(),console.log("websocket connect close"),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"close",type:"faceScan_recommendation",email:K})}})}catch(e){f?.(),me(e)}}},se=t.useCallback(()=>{const e=v.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),s=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const r=document.createElement("video");r.srcObject=e,r.muted=!0,r.playsInline=!0,r.play();const c=()=>{a>n?(s?.save(),s?.translate(o.width,0),s?.rotate(Math.PI/2),s?.drawImage(r,0,0,n,a),s?.restore()):s?.drawImage(r,0,0,a,n),requestAnimationFrame(c)};c();const i=t.frameRate??10;j.current=i;const l=o.captureStream(i),d={videoBitsPerSecond:15e5};let u;X.length>0&&(d.mimeType=X[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),z(!0),void N(!1)}C.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&C.current&&C.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",C?.current?.length),oe()},u.start(100),w.current=u,console.log("Recording started successfully (portrait normalized)")},[X,oe]),{faceScanDetector:re,scanStage:ce,setScanStage:ie,resetScan:le,isModelLoaded:de,startScanSequence:ue}=c({faceScanId:$,shopDomain:q,isError:p,isSuccess:y,onScanComplete:()=>{ne()},onModelReady:()=>{k(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),se()}}),fe=t.useCallback(()=>{de&&(i?.(),ie(0),a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{I(!0),setTimeout(()=>{ue()},200)},200))},[ie,I,ue,de,i]),ge=t.useCallback(()=>{I(!1),M(!0),ne(),le(),r?.(),C.current=[],j.current=null,w.current&&(w.current=null),z(!1),ie(-1),H(a.generateUuid()),v.current&&F.current&&(v.current.srcObject=F.current,console.log("Camera stream restored after reset"))},[ie,I,M,ne,le,H]),he=t.useRef(!1);t.useEffect(()=>{!W||he.current||_||p||y||O||(a.speechService.stopAudio(),ge()),he.current=W},[W,_,p,y,O,ge]);const me=e=>{console.log(e,"ws error"),s?.(e),z(!0),N(!1),M(!1),a.handleScanTimeCapture({eventName:`${q}/faceScan`,faceScanId:$,status:"failed",email:K,data:JSON.stringify(e)})},pe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&a.handleScanTimeCapture({eventName:`${q}/faceScan_success/intermediate`,faceScanId:$,status:"success",email:K,data:JSON.stringify(e)}),o?.(e)};t.useEffect(()=>{if(!p&&!y)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Y}).then(e=>{F.current=e,v.current&&(v.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),Y!==a.videoConstraintsExact?z(!0):Z(a.videoConstraintsFallback)}),()=>{F.current&&F.current.getTracks().forEach(e=>e.stop())}},[p,y,Y]),t.useEffect(()=>{if(!E||!T)return;const e=setInterval(()=>{re(v,b)},500);return()=>clearInterval(e)},[re,E,T]);return console.log("Model ready:",E,"Has error:",O,"Is scanning:",T,"showLoader",_),t.useEffect(()=>{const e=a.getSupportedMediaRecorderTypes(ee,a.videoTypes);Q(e)},[ee]),t.useEffect(()=>{ie(-1)},[]),e.jsx(a.LanguageContextProvider,{children:e.jsx(a.ConfigProvider,{config:m,children:e.jsx(a.ParamsContext.Provider,{value:{isError:p,isSuccess:y,showLoader:_,hasError:O,resetScanState:ge,showGuideCard:R,scanStage:ce,videoLoading:P,setVideoLoading:D,videoError:L,setVideoError:A,gender:U,getButtonText:()=>T?a.LanguageKeys.reset:de?a.LanguageKeys.start:a.LanguageKeys.loading,isScanning:T,startScan:fe,isModelLoaded:de,isLandscape:W,onRetry:r},children:e.jsx(a.ShadowRoot,{children:e.jsx(d,{webcamRef:v,canvasRef:b})})})})})};
|
|
2
|
+
//# sourceMappingURL=FaceScan-B160VNef.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as o,useMemo as r,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,M as _,e as I,f as k,h as M,i as C,j as D,k as E,l as P,n as T,o as z,q as R,r as L,t as $,C as j,w as V,x as O,y as W,z as U}from"./Modal-6Y88Up1w.js";import{ArrowRight as B}from"lucide-react";import{Drawer as A}from"@mui/material";let q=null,J=!1;function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:h,shopDomain:f,isError:g,isSuccess:p}){const y=n(null),[S,b]=o(0),[w,v]=o(0),[x,F]=o(!1),[N,_]=o(!1),I=n(null),k=n(S),M=n(w),C=n([]),D=n(""),E=n(0),P=n(!1),T=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),R=r(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=r(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),$=c((t,a,n,o,r,c)=>{const i=Date.now();if(!(i-T.current<4e3)){T.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:r,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),j=()=>{l.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current]}),setTimeout(()=>{_(!0)},1500)},V=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(q)return q;if(J)for(;J;)if(await new Promise(e=>setTimeout(e,100)),q)return q;J=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-LvkS7dAF.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const o=n.getContext("2d");if(o){o.fillStyle="black",o.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return q=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{J=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return V(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),k.current=0,M.current=0,C.current=[]}})()}},[g,p]),i(()=>{k.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,o)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2))try{const r=await y.current.estimatePoses(n.current);if(r.length>0){const n=[],c=[];if(r[0].keypoints.forEach((e,t)=>{const a=e.score??0,o=[e.x??-1,e.y??-1,a];t<=10?n.push(o):c.push(o)}),o?.current){const e=o.current.getContext("2d"),{width:t,height:a}=o.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const i=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,r=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!o&&r&&s;case 1:return!o&&r&&l;case 2:return!o&&r&&d;default:return!1}})(k.current,n),s=c.slice(2).filter(e=>e[2]>.7).length<=2;C.current.push(i&&s),C.current.length>10&&C.current.shift();if(C.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=k.current+1;v(0),C.current=[],b(n),_(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:k.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:R[k.current]}),1===n&&h&&h(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),j()}})()}$(n,c,k.current,i,s,M.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current],consecutiveValid:M.current}),b(0),v(0),_(!1),k.current=0,M.current=0,C.current=[],D.current="",E.current=0,P.current=!1,I.current&&(speechSynthesis.cancel(),I.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:j,isScanningActive:N}}function K({onRetry:a,loading:n}){const{translate:o}=s(h)||{},r=f();return e("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:r?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:r?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:r?.style?.heading?.headingFontSize||"32px",color:r?.style?.heading?.headingColor||"#000",fontWeight:r?.style?.heading?.headingFontWeight||"normal"},children:o?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:r?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:r?.style?.subheading?.subheadingFontSize||"14px",color:r?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:r?.style?.subheading?.subheadingFontWeight||"normal"},children:o?.(p.clickToResetScan)}),e(y,{disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:o?.(p.resetScan),postfixIcon:e(B,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:o,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),r&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!r&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>o(!1),onLoadStart:()=>o(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:o})=>{const{isError:r,isSuccess:c,showLoader:i,hasError:l,resetScanState:d,showGuideCard:u,scanStage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,getButtonText:w,isScanning:v,startScan:x,isModelLoaded:I,isLandscape:k,onRetry:M}=s(F),C=f();return r?e(K,{onRetry:M}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),k&&!i&&!l&&e("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e(_,{variant:"portrait",config:C})}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:C?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)",visibility:k?"hidden":"visible"}}),e("canvas",{ref:o,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&e(K,{loading:i,onRetry:d}),u&&!l&&!i&&!k&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e(H,{stage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,btnConfig:{label:w(),onClick:v?d:x,isDisabled:i||!I,icon:e(v?B:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:m,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},N=t.token??"",_=n(null),B=n(null),A=n(null),q=n([]),J=n(null),K=n(null),[H,Q]=o(!1),[Y,Z]=o(!1),[ee,te]=o(!1),[ae,ne]=o(!0),[oe,re]=o(!1),[ce,ie]=o(!1),[se,le]=o(!1),[de,ue]=o(I()),me=r(()=>k(N),[N]),{isLandscape:he}=M(),{email:fe,gender:ge,deviceFocalLength:pe,shopDomain:ye,callbackUrl:Se,bodyScanId:be}=x,[we,ve]=o([]),[xe,Fe]=o(C),Ne=r(()=>D(),[]),_e=E(we),Ie=P(_e);T();const ke=c(()=>{console.log("Stopping recording..."),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),q.current){if(0===q.current.length)return console.error("No video data recorded"),le(!0),void Q(!1);f?.(),Q(!0);const e=new File(q.current,`${de}.${Ie}`,{type:_e}),t=K.current??await O(e),a=e.size,n=(a/1048576).toFixed(2),o=Math.round(a/1e4),r={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:q.current.length,estimated_duration_seconds:o},c=[{gender:ge},{face_scan_id:de},{focal_length:`${pe}`},{customer_store_url:ye},{scan_type:"face_scan"},{body_scan_id:be}];Se&&c.push({callback_url:Se}),W({eventName:`${ye}/face_scan_meta_data`,faceScanId:de,email:fe,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();W({eventName:`${ye}/face_scan_upload_start`,faceScanId:de,email:fe,startTime:i});try{const t=await me.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:de,email:fe,contentType:e.type}),a=Date.now();W({eventName:`${ye}/face_scan_upload_complete`,faceScanId:de,email:fe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),me.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"pre_open",type:"faceScan_recommendation",email:fe})},faceScanId:de,onOpen:()=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"open",type:"faceScan_recommendation",email:fe}),console.log("websocket connect open")},onError:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"error",type:"faceScan_recommendation",email:fe}),Ve(e)},onSuccess:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"success",type:"faceScan_recommendation",email:fe}),Oe(e)},onClose:()=>{S?.(),console.log("websocket connect close"),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"close",type:"faceScan_recommendation",email:fe})}})}catch(e){g?.(),Ve(e)}}},Ce=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),r=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play();const i=()=>{a>n?(r?.save(),r?.translate(o.width,0),r?.rotate(Math.PI/2),r?.drawImage(c,0,0,n,a),r?.restore()):r?.drawImage(c,0,0,a,n),requestAnimationFrame(i)};i();const s=t.frameRate??10;K.current=s;const l=o.captureStream(s),d={videoBitsPerSecond:15e5};let u;we.length>0&&(d.mimeType=we[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),le(!0),void Q(!1)}q.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&q.current&&q.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",q?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[we,Me]),{faceScanDetector:De,scanStage:Ee,setScanStage:Pe,resetScan:Te,isModelLoaded:ze,startScanSequence:Re}=G({faceScanId:de,shopDomain:ye,isError:w,isSuccess:v,onScanComplete:()=>{ke()},onModelReady:()=>{Z(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),Ce()}}),Le=c(()=>{ze&&(m?.(),Pe(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{te(!0),setTimeout(()=>{Re()},200)},200))},[Pe,te,Re,ze,m]),$e=c(()=>{te(!1),ne(!0),ke(),Te(),l?.(),q.current=[],K.current=null,A.current&&(A.current=null),le(!1),Pe(-1),ue(I()),_.current&&J.current&&(_.current.srcObject=J.current,console.log("Camera stream restored after reset"))},[Pe,te,ne,ke,Te,ue]),je=n(!1);i(()=>{!he||je.current||H||w||v||se||(d.stopAudio(),$e()),je.current=he},[he,H,w,v,se,$e]);const Ve=e=>{console.log(e,"ws error"),s?.(e),le(!0),Q(!1),ne(!1),W({eventName:`${ye}/faceScan`,faceScanId:de,status:"failed",email:fe,data:JSON.stringify(e)})},Oe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&W({eventName:`${ye}/faceScan_success/intermediate`,faceScanId:de,status:"success",email:fe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:xe}).then(e=>{J.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),xe!==C?le(!0):Fe(z)}),()=>{J.current&&J.current.getTracks().forEach(e=>e.stop())}},[w,v,xe]),i(()=>{if(!Y||!ee)return;const e=setInterval(()=>{De(_,B)},500);return()=>clearInterval(e)},[De,Y,ee]);return console.log("Model ready:",Y,"Has error:",se,"Is scanning:",ee,"showLoader",H),i(()=>{const e=R(Ne,L);ve(e)},[Ne]),i(()=>{Pe(-1)},[]),e($,{children:e(j,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:H,hasError:se,resetScanState:$e,showGuideCard:ae,scanStage:Ee,videoLoading:oe,setVideoLoading:re,videoError:ce,setVideoError:ie,gender:ge,getButtonText:()=>ee?p.reset:ze?p.start:p.loading,isScanning:ee,startScan:Le,isModelLoaded:ze,isLandscape:he,onRetry:l},children:e(V,{children:e(X,{webcamRef:_,canvasRef:B})})})})})};export{Q as F};
|
|
2
|
+
//# sourceMappingURL=FaceScan-BeMPl-gC.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as o,useMemo as r,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,M as _,e as I,f as k,h as M,i as C,j as D,k as E,l as P,n as T,o as z,q as R,r as L,t as $,C as j,w as V,x as O,y as W,z as U}from"./Modal-6Y88Up1w.js";import{ArrowRight as B}from"lucide-react";import{Drawer as A}from"@mui/material";let q=null,J=!1;function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:h,shopDomain:f,isError:g,isSuccess:p}){const y=n(null),[S,b]=o(0),[w,v]=o(0),[x,F]=o(!1),[N,_]=o(!1),I=n(null),k=n(S),M=n(w),C=n([]),D=n(""),E=n(0),P=n(!1),T=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),R=r(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=r(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),$=c((t,a,n,o,r,c)=>{const i=Date.now();if(!(i-T.current<4e3)){T.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:r,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),j=()=>{l.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current]}),setTimeout(()=>{_(!0)},1500)},V=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(q)return q;if(J)for(;J;)if(await new Promise(e=>setTimeout(e,100)),q)return q;J=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-LvkS7dAF.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const o=n.getContext("2d");if(o){o.fillStyle="black",o.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return q=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{J=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return V(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),k.current=0,M.current=0,C.current=[]}})()}},[g,p]),i(()=>{k.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,o)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2))try{const r=await y.current.estimatePoses(n.current);if(r.length>0){const n=[],c=[];if(r[0].keypoints.forEach((e,t)=>{const a=e.score??0,o=[e.x??-1,e.y??-1,a];t<=10?n.push(o):c.push(o)}),o?.current){const e=o.current.getContext("2d"),{width:t,height:a}=o.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const i=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,r=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!o&&r&&s;case 1:return!o&&r&&l;case 2:return!o&&r&&d;default:return!1}})(k.current,n),s=c.slice(2).filter(e=>e[2]>.7).length<=2;C.current.push(i&&s),C.current.length>10&&C.current.shift();if(C.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=k.current+1;v(0),C.current=[],b(n),_(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:k.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:R[k.current]}),1===n&&h&&h(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),j()}})()}$(n,c,k.current,i,s,M.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current],consecutiveValid:M.current}),b(0),v(0),_(!1),k.current=0,M.current=0,C.current=[],D.current="",E.current=0,P.current=!1,I.current&&(speechSynthesis.cancel(),I.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:j,isScanningActive:N}}function K({onRetry:a,loading:n}){const{translate:o}=s(h)||{},r=f();return e("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:r?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:r?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:r?.style?.heading?.headingFontSize||"32px",color:r?.style?.heading?.headingColor||"#000",fontWeight:r?.style?.heading?.headingFontWeight||"normal"},children:o?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:r?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:r?.style?.subheading?.subheadingFontSize||"14px",color:r?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:r?.style?.subheading?.subheadingFontWeight||"normal"},children:o?.(p.clickToResetScan)}),e(y,{disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:o?.(p.resetScan),postfixIcon:e(B,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:o,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),r&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!r&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>o(!1),onLoadStart:()=>o(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:o})=>{const{isError:r,isSuccess:c,showLoader:i,hasError:l,resetScanState:d,showGuideCard:u,scanStage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,getButtonText:w,isScanning:v,startScan:x,isModelLoaded:I,isLandscape:k,onRetry:M}=s(F),C=f();return r?e(K,{onRetry:M}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),k&&!i&&!l&&e("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e(_,{variant:"portrait",config:C})}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:C?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:o,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&e(K,{loading:i,onRetry:d}),u&&!l&&!i&&!k&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e(H,{stage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,btnConfig:{label:w(),onClick:v?d:x,isDisabled:i||!I,icon:e(v?B:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:m,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},N=t.token??"",_=n(null),B=n(null),A=n(null),q=n([]),J=n(null),K=n(null),[H,Q]=o(!1),[Y,Z]=o(!1),[ee,te]=o(!1),[ae,ne]=o(!0),[oe,re]=o(!1),[ce,ie]=o(!1),[se,le]=o(!1),[de,ue]=o(I()),me=r(()=>k(N),[N]),{isLandscape:he}=M(),{email:fe,gender:ge,deviceFocalLength:pe,shopDomain:ye,callbackUrl:Se,bodyScanId:be}=x,[we,ve]=o([]),[xe,Fe]=o(C),Ne=r(()=>D(),[]),_e=E(we),Ie=P(_e);T();const ke=c(()=>{console.log("Stopping recording..."),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),q.current){if(0===q.current.length)return console.error("No video data recorded"),le(!0),void Q(!1);f?.(),Q(!0);const e=new File(q.current,`${de}.${Ie}`,{type:_e}),t=K.current??await O(e),a=e.size,n=(a/1048576).toFixed(2),o=Math.round(a/1e4),r={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:q.current.length,estimated_duration_seconds:o},c=[{gender:ge},{face_scan_id:de},{focal_length:`${pe}`},{customer_store_url:ye},{scan_type:"face_scan"},{body_scan_id:be}];Se&&c.push({callback_url:Se}),W({eventName:`${ye}/face_scan_meta_data`,faceScanId:de,email:fe,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();W({eventName:`${ye}/face_scan_upload_start`,faceScanId:de,email:fe,startTime:i});try{const t=await me.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:de,email:fe,contentType:e.type}),a=Date.now();W({eventName:`${ye}/face_scan_upload_complete`,faceScanId:de,email:fe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),me.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"pre_open",type:"faceScan_recommendation",email:fe})},faceScanId:de,onOpen:()=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"open",type:"faceScan_recommendation",email:fe}),console.log("websocket connect open")},onError:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"error",type:"faceScan_recommendation",email:fe}),Ve(e)},onSuccess:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"success",type:"faceScan_recommendation",email:fe}),Oe(e)},onClose:()=>{S?.(),console.log("websocket connect close"),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"close",type:"faceScan_recommendation",email:fe})}})}catch(e){g?.(),Ve(e)}}},Ce=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),r=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play();const i=()=>{a>n?(r?.save(),r?.translate(o.width,0),r?.rotate(Math.PI/2),r?.drawImage(c,0,0,n,a),r?.restore()):r?.drawImage(c,0,0,a,n),requestAnimationFrame(i)};i();const s=t.frameRate??10;K.current=s;const l=o.captureStream(s),d={videoBitsPerSecond:15e5};let u;we.length>0&&(d.mimeType=we[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),le(!0),void Q(!1)}q.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&q.current&&q.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",q?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[we,Me]),{faceScanDetector:De,scanStage:Ee,setScanStage:Pe,resetScan:Te,isModelLoaded:ze,startScanSequence:Re}=G({faceScanId:de,shopDomain:ye,isError:w,isSuccess:v,onScanComplete:()=>{ke()},onModelReady:()=>{Z(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),Ce()}}),Le=c(()=>{ze&&(m?.(),Pe(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{te(!0),setTimeout(()=>{Re()},200)},200))},[Pe,te,Re,ze,m]),$e=c(()=>{te(!1),ne(!0),ke(),Te(),l?.(),q.current=[],K.current=null,A.current&&(A.current=null),le(!1),Pe(-1),ue(I()),_.current&&J.current&&(_.current.srcObject=J.current,console.log("Camera stream restored after reset"))},[Pe,te,ne,ke,Te,ue]),je=n(!1);i(()=>{!he||je.current||H||w||v||se||(d.stopAudio(),$e()),je.current=he},[he,H,w,v,se,$e]);const Ve=e=>{console.log(e,"ws error"),s?.(e),le(!0),Q(!1),ne(!1),W({eventName:`${ye}/faceScan`,faceScanId:de,status:"failed",email:fe,data:JSON.stringify(e)})},Oe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&W({eventName:`${ye}/faceScan_success/intermediate`,faceScanId:de,status:"success",email:fe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:xe}).then(e=>{J.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),xe!==C?le(!0):Fe(z)}),()=>{J.current&&J.current.getTracks().forEach(e=>e.stop())}},[w,v,xe]),i(()=>{if(!Y||!ee)return;const e=setInterval(()=>{De(_,B)},500);return()=>clearInterval(e)},[De,Y,ee]);return console.log("Model ready:",Y,"Has error:",se,"Is scanning:",ee,"showLoader",H),i(()=>{const e=R(Ne,L);ve(e)},[Ne]),i(()=>{Pe(-1)},[]),e($,{children:e(j,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:H,hasError:se,resetScanState:$e,showGuideCard:ae,scanStage:Ee,videoLoading:oe,setVideoLoading:re,videoError:ce,setVideoError:ie,gender:ge,getButtonText:()=>ee?p.reset:ze?p.start:p.loading,isScanning:ee,startScan:Le,isModelLoaded:ze,isLandscape:he,onRetry:l},children:e(V,{children:e(X,{webcamRef:_,canvasRef:B})})})})})};export{Q as F};
|
|
2
|
+
//# sourceMappingURL=FaceScan-BeWA_QfG.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("./Modal-B_UR_mwU.js"),n=require("lucide-react"),o=require("@mui/material");let r=null,s=!1;function c({faceScanId:e,onValidPose:n,onScanComplete:o,onModelReady:c,onStartRecording:i,shopDomain:l,isError:d,isSuccess:u}){const f=t.useRef(null),[g,h]=t.useState(0),[m,p]=t.useState(0),[y,S]=t.useState(!1),[x,v]=t.useState(!1),b=t.useRef(null),w=t.useRef(g),C=t.useRef(m),F=t.useRef([]),j=t.useRef(""),_=t.useRef(0),N=t.useRef(!1),E=t.useRef(0),k="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),T=t.useMemo(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),I=t.useMemo(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{a.posthog.capture(`${l}/face_scan_pose_detection`,e)},4e3),[l]),R=t.useCallback((t,a,n,o,r,s)=>{const c=Date.now();if(!(c-E.current<4e3)){E.current=c;try{const c=t[0]||[0,0,0],i=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],f=t.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,h=a.map(e=>e[2]).filter(e=>e>0),m=h.length>0?h.reduce((e,t)=>e+t,0)/h.length:0,p=Math.abs(i[0]-l[0]),y=c[0]-l[0],S=i[0]-c[0];let x="frontal";1===n?x="left":2===n?x="right":3===n&&(x="frontal_smile");const v={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:r,consecutiveValid:s,avgFaceScore:parseFloat(g.toFixed(3)),avgBodyScore:parseFloat(m.toFixed(3)),faceKeypointsDetected:f.length,bodyKeypointsDetected:h.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(c[2].toFixed(3)),leftEyeScore:parseFloat(i[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:x})};I(v)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,I]),M=()=>{a.posthog.capture(`${l}/face_scan_detection_started`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current]}),setTimeout(()=>{v(!0)},1500)},P=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(r)return r;if(s)for(;s;)if(await new Promise(e=>setTimeout(e,100)),r)return r;s=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),Promise.resolve().then(function(){return require("./pose-detection.esm-2mkM0o4k.js")})]);await e.setBackend("webgl"),await e.ready();const n=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),o=document.createElement("canvas");o.width="number"==typeof a.videoConstraints.width?a.videoConstraints.width:a.videoConstraints.width.ideal??a.videoConstraints.width.max??1280,o.height="number"==typeof a.videoConstraints.height?a.videoConstraints.height:a.videoConstraints.height.ideal??a.videoConstraints.height.max??720;const s=o.getContext("2d");if(s){s.fillStyle="black",s.fillRect(0,0,o.width,o.height);try{await n.estimatePoses(o)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return r=n,n}catch(e){return console.error("Failed to preload detector:",e),null}finally{s=!1}})();e&&(f.current=e,console.log("Face scan model loaded successfully"),S(!0),c?.())}catch(e){console.error("Error initializing face scan:",e)}};return t.useEffect(()=>{if(!d&&!u)return P(),()=>{(async()=>{try{S(!1)}catch(e){console.error("Error disposing resources:",e)}finally{h(0),p(0),w.current=0,C.current=0,F.current=[]}})()}},[d,u]),t.useEffect(()=>{w.current=g},[g]),t.useEffect(()=>{C.current=m},[m]),{faceScanDetector:async(t,r)=>{if(f.current&&t.current&&y&&x&&!(t.current.readyState<2))try{const s=await f.current.estimatePoses(t.current);if(s.length>0){const t=[],c=[];if(s[0].keypoints.forEach((e,a)=>{const n=e.score??0,o=[e.x??-1,e.y??-1,n];a<=10?t.push(o):c.push(o)}),r?.current){const e=r.current.getContext("2d"),{width:t,height:a}=r.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const d=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,r=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,s=t[2][0]-t[5][0],c=t[0][0]-t[5][0],i=c>.4*s&&c<.6*s,l=c>.85*s,d=t[2][0]-t[0][0]>.85*s;switch(e){case 0:case 3:return!o&&r&&i;case 1:return!o&&r&&l;case 2:return!o&&r&&d;default:return!1}})(w.current,t),u=c.slice(2).filter(e=>e[2]>.7).length<=2;F.current.push(d&&u),F.current.length>10&&F.current.shift();if(F.current.filter(Boolean).length>=2){const e=C.current+1;p(e)}else p(Math.max(0,C.current-1));if(C.current>=2){n?.();const t=w.current+1;p(0),F.current=[],h(t),v(!1),(async()=>{if(await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Sound-effect.mp3`),a.posthog.capture(`${l}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:w.current,nextStage:t,timestamp:(new Date).toISOString(),totalStages:4,stageName:T[w.current]}),1===t&&i&&i(),t>=4)o?.();else{let e=null;switch(t){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/${e}`),M()}})()}R(t,c,w.current,d,u,C.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:g,setScanStage:h,consecutiveValid:m,isModelLoaded:y,resetScan:()=>{a.posthog.capture(`${l}/face_scan_reset`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current],consecutiveValid:C.current}),h(0),p(0),v(!1),w.current=0,C.current=0,F.current=[],j.current="",_.current=0,N.current=!1,b.current&&(speechSynthesis.cancel(),b.current=null)},enableVoiceCommands:()=>{if(N.current=!0,"undefined"!=typeof window&&k&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:M,isScanningActive:x}}function i({onRetry:o,loading:r}){const{translate:s}=t.useContext(a.LanguageContext)||{},c=a.useConfig();return e.jsx("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:c?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e.jsx(a.Header,{noTitle:!0}),e.jsxs("div",{className:"flex flex-col items-center w-full",children:[e.jsx("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:c?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:c?.style?.heading?.headingFontSize||"32px",color:c?.style?.heading?.headingColor||"#000",fontWeight:c?.style?.heading?.headingFontWeight||"normal"},children:s?.(a.LanguageKeys.scanFailed)}),e.jsx("p",{className:"mb-[1.5rem]",style:{fontFamily:c?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:c?.style?.subheading?.subheadingFontSize||"14px",color:c?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:c?.style?.subheading?.subheadingFontWeight||"normal"},children:s?.(a.LanguageKeys.clickToResetScan)}),e.jsx(a.SpecificButton,{disabled:r,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:s?.(a.LanguageKeys.resetScan),postfixIcon:e.jsx(n.ArrowRight,{}),buttonFunc:()=>o?.()})]})]})})}function l({stage:n,videoLoading:o,setVideoLoading:r,videoError:s,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=t.useContext(a.LanguageContext)||{},u=a.useConfig();return-1===n?e.jsxs("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.LanguageKeys.faceVisible)}),o&&e.jsx("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.loadingVideo)}),s&&e.jsx("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.videoLoadFailed)}),!s&&e.jsx("div",{className:" w-[100px] mx-auto",children:e.jsx("video",{src:i===a.GenderType.Male?a.maleGlassesOffVideo:a.glassesOffVideo,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>r(!1),onLoadStart:()=>r(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e.jsx("div",{className:"flex justify-center w-full p-[1rem]",children:e.jsx(a.SpecificButton,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e.jsx("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.directionMessages[n])}),e.jsxs("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e.jsx("div",{className:` w-[120px] overflow-hidden ${0===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.forward:a.FACE_SCAN_HEADSHOT.female.forward,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${1===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.left:a.FACE_SCAN_HEADSHOT.female.left,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${2===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.right:a.FACE_SCAN_HEADSHOT.female.right,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${3===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.smile:a.FACE_SCAN_HEADSHOT.female.smile,type:"video/mp4"})})})]})]})})}const d=({webcamRef:r,canvasRef:s})=>{const{isError:c,isSuccess:d,showLoader:u,hasError:f,resetScanState:g,showGuideCard:h,scanStage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,getButtonText:b,isScanning:w,startScan:C,isModelLoaded:F,isLandscape:j,onRetry:_}=t.useContext(a.ParamsContext),N=a.useConfig();return c?e.jsx(i,{onRetry:_}):d?e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}):e.jsxs(e.Fragment,{children:[e.jsx("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),j&&!u&&!f&&e.jsx("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e.jsx(a.Modal,{variant:"portrait",config:N})}),u&&!f&&e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}),e.jsx("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:N?.style?.base?.backgroundColor},children:e.jsx("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:e.jsxs("div",{className:"w-full h-full",children:[e.jsx("video",{ref:r,autoPlay:!0,playsInline:!0,muted:!0,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)",visibility:j?"hidden":"visible"}}),e.jsx("canvas",{ref:s,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!u&&f&&e.jsx(i,{loading:u,onRetry:g}),h&&!f&&!u&&!j&&e.jsx(o.Drawer,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e.jsx(l,{stage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,btnConfig:{label:b(),onClick:w?g:C,isDisabled:u||!F,icon:w?e.jsx(n.ArrowRight,{}):e.jsx(e.Fragment,{})}})})]})};exports.FaceScan=n=>{const{onScanSuccess:o,onScanError:r,onRetry:s,onScanStart:i,onCaptureComplete:l,onUploadStart:u,onUploadEnd:f,onMeasurementSocketStart:g,onMeasurementSocketClose:h,config:m,isError:p,isSuccess:y}=n,S=n.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},x=n.token??"",v=t.useRef(null),b=t.useRef(null),w=t.useRef(null),C=t.useRef([]),F=t.useRef(null),j=t.useRef(null),[_,N]=t.useState(!1),[E,k]=t.useState(!1),[T,I]=t.useState(!1),[R,M]=t.useState(!0),[P,D]=t.useState(!1),[L,A]=t.useState(!1),[O,z]=t.useState(!1),[$,H]=t.useState(a.generateUuid()),V=t.useMemo(()=>a.getSwanService(x),[x]),{isLandscape:W}=a.usePortraitLock(),{email:K,gender:U,deviceFocalLength:B,shopDomain:q,callbackUrl:G,bodyScanId:J}=S,[X,Q]=t.useState([]),[Y,Z]=t.useState(a.videoConstraintsExact),ee=t.useMemo(()=>a.getPreferredMediaRecorderTypes(),[]),te=a.getRecordingMimeType(X),ae=a.getRecordingExtension(te);a.usePosthogPageview();const ne=t.useCallback(()=>{console.log("Stopping recording..."),w.current&&"recording"===w.current.state&&w.current.stop(),w.current=null},[]),oe=async()=>{if(l?.(),C.current){if(0===C.current.length)return console.error("No video data recorded"),z(!0),void N(!1);u?.(),N(!0);const e=new File(C.current,`${$}.${ae}`,{type:te}),t=j.current??await a.getVideoFPS(e),n=e.size,o=(n/1048576).toFixed(2),r=Math.round(n/1e4),s={video_size_mb:parseFloat(o),video_size_bytes:n,video_fps:t||0,blob_count:C.current.length,estimated_duration_seconds:r},c=[{gender:U},{face_scan_id:$},{focal_length:`${B}`},{customer_store_url:q},{scan_type:"face_scan"},{body_scan_id:J}];G&&c.push({callback_url:G}),a.handleScanTimeCapture({eventName:`${q}/face_scan_meta_data`,faceScanId:$,email:K,data:JSON.stringify({metaData:c,videoData:s})});const i=Date.now();a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_start`,faceScanId:$,email:K,startTime:i});try{const t=await V.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:$,email:K,contentType:e.type}),n=Date.now(),o=n-i;a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_complete`,faceScanId:$,email:K,completionTime:n,uploadDuration:o}),f?.(),console.log("✅ Upload successful",t),V.measurement.handlFaceScaneSocket({onPreopen:()=>{g?.(),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"pre_open",type:"faceScan_recommendation",email:K})},faceScanId:$,onOpen:()=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"open",type:"faceScan_recommendation",email:K}),console.log("websocket connect open")},onError:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"error",type:"faceScan_recommendation",email:K}),me(e)},onSuccess:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"success",type:"faceScan_recommendation",email:K}),pe(e)},onClose:()=>{h?.(),console.log("websocket connect close"),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"close",type:"faceScan_recommendation",email:K})}})}catch(e){f?.(),me(e)}}},re=t.useCallback(()=>{const e=v.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),r=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const s=document.createElement("video");s.srcObject=e,s.muted=!0,s.playsInline=!0,s.play();const c=()=>{a>n?(r?.save(),r?.translate(o.width,0),r?.rotate(Math.PI/2),r?.drawImage(s,0,0,n,a),r?.restore()):r?.drawImage(s,0,0,a,n),requestAnimationFrame(c)};c();const i=t.frameRate??10;j.current=i;const l=o.captureStream(i),d={videoBitsPerSecond:15e5};let u;X.length>0&&(d.mimeType=X[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),z(!0),void N(!1)}C.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&C.current&&C.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",C?.current?.length),oe()},u.start(100),w.current=u,console.log("Recording started successfully (portrait normalized)")},[X,oe]),{faceScanDetector:se,scanStage:ce,setScanStage:ie,resetScan:le,isModelLoaded:de,startScanSequence:ue}=c({faceScanId:$,shopDomain:q,isError:p,isSuccess:y,onScanComplete:()=>{ne()},onModelReady:()=>{k(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),re()}}),fe=t.useCallback(()=>{de&&(i?.(),ie(0),a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{I(!0),setTimeout(()=>{ue()},200)},200))},[ie,I,ue,de,i]),ge=t.useCallback(()=>{I(!1),M(!0),ne(),le(),s?.(),C.current=[],j.current=null,w.current&&(w.current=null),z(!1),ie(-1),H(a.generateUuid()),v.current&&F.current&&(v.current.srcObject=F.current,console.log("Camera stream restored after reset"))},[ie,I,M,ne,le,H]),he=t.useRef(!1);t.useEffect(()=>{!W||he.current||_||p||y||O||(a.speechService.stopAudio(),w.current&&(w.current.onstop=null,"recording"===w.current.state&&w.current.stop(),w.current=null),C.current=[],j.current=null,ge()),he.current=W},[W,_,p,y,O,ge]);const me=e=>{console.log(e,"ws error"),r?.(e),z(!0),N(!1),M(!1),a.handleScanTimeCapture({eventName:`${q}/faceScan`,faceScanId:$,status:"failed",email:K,data:JSON.stringify(e)})},pe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&a.handleScanTimeCapture({eventName:`${q}/faceScan_success/intermediate`,faceScanId:$,status:"success",email:K,data:JSON.stringify(e)}),o?.(e)};t.useEffect(()=>{if(!p&&!y)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Y}).then(e=>{F.current=e,v.current&&(v.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),Y!==a.videoConstraintsExact?z(!0):Z(a.videoConstraintsFallback)}),()=>{F.current&&F.current.getTracks().forEach(e=>e.stop())}},[p,y,Y]),t.useEffect(()=>{if(!E||!T)return;const e=setInterval(()=>{se(v,b)},500);return()=>clearInterval(e)},[se,E,T]);return console.log("Model ready:",E,"Has error:",O,"Is scanning:",T,"showLoader",_),t.useEffect(()=>{const e=a.getSupportedMediaRecorderTypes(ee,a.videoTypes);Q(e)},[ee]),t.useEffect(()=>{ie(-1)},[]),e.jsx(a.LanguageContextProvider,{children:e.jsx(a.ConfigProvider,{config:m,children:e.jsx(a.ParamsContext.Provider,{value:{isError:p,isSuccess:y,showLoader:_,hasError:O,resetScanState:ge,showGuideCard:R,scanStage:ce,videoLoading:P,setVideoLoading:D,videoError:L,setVideoError:A,gender:U,getButtonText:()=>T?a.LanguageKeys.reset:de?a.LanguageKeys.start:a.LanguageKeys.loading,isScanning:T,startScan:fe,isModelLoaded:de,isLandscape:W,onRetry:s},children:e.jsx(a.ShadowRoot,{children:e.jsx(d,{webcamRef:v,canvasRef:b})})})})})};
|
|
2
|
+
//# sourceMappingURL=FaceScan-CLnu4dJd.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("./LoadingScreen-B4IgJfiH.js"),n=require("lucide-react"),o=require("@mui/material");let s=null,r=!1;function c({faceScanId:e,onValidPose:n,onScanComplete:o,onModelReady:c,onStartRecording:i,shopDomain:l,isError:d,isSuccess:u}){const f=t.useRef(null),[g,h]=t.useState(0),[m,p]=t.useState(0),[y,S]=t.useState(!1),[x,v]=t.useState(!1),b=t.useRef(null),w=t.useRef(g),C=t.useRef(m),F=t.useRef([]),j=t.useRef(""),_=t.useRef(0),N=t.useRef(!1),E=t.useRef(0),k="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),T=t.useMemo(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),I=t.useMemo(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{a.posthog.capture(`${l}/face_scan_pose_detection`,e)},4e3),[l]),R=t.useCallback((t,a,n,o,s,r)=>{const c=Date.now();if(!(c-E.current<4e3)){E.current=c;try{const c=t[0]||[0,0,0],i=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],f=t.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,h=a.map(e=>e[2]).filter(e=>e>0),m=h.length>0?h.reduce((e,t)=>e+t,0)/h.length:0,p=Math.abs(i[0]-l[0]),y=c[0]-l[0],S=i[0]-c[0];let x="frontal";1===n?x="left":2===n?x="right":3===n&&(x="frontal_smile");const v={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:s,consecutiveValid:r,avgFaceScore:parseFloat(g.toFixed(3)),avgBodyScore:parseFloat(m.toFixed(3)),faceKeypointsDetected:f.length,bodyKeypointsDetected:h.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(c[2].toFixed(3)),leftEyeScore:parseFloat(i[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:x})};I(v)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,I]),M=()=>{a.posthog.capture(`${l}/face_scan_detection_started`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current]}),setTimeout(()=>{v(!0)},1500)},P=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(s)return s;if(r)for(;r;)if(await new Promise(e=>setTimeout(e,100)),s)return s;r=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),Promise.resolve().then(function(){return require("./pose-detection.esm-2mkM0o4k.js")})]);await e.setBackend("webgl"),await e.ready();const n=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),o=document.createElement("canvas");o.width="number"==typeof a.videoConstraints.width?a.videoConstraints.width:a.videoConstraints.width.ideal??a.videoConstraints.width.max??1280,o.height="number"==typeof a.videoConstraints.height?a.videoConstraints.height:a.videoConstraints.height.ideal??a.videoConstraints.height.max??720;const r=o.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,o.width,o.height);try{await n.estimatePoses(o)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return s=n,n}catch(e){return console.error("Failed to preload detector:",e),null}finally{r=!1}})();e&&(f.current=e,console.log("Face scan model loaded successfully"),S(!0),c?.())}catch(e){console.error("Error initializing face scan:",e)}};return t.useEffect(()=>{if(!d&&!u)return P(),()=>{(async()=>{try{S(!1)}catch(e){console.error("Error disposing resources:",e)}finally{h(0),p(0),w.current=0,C.current=0,F.current=[]}})()}},[d,u]),t.useEffect(()=>{w.current=g},[g]),t.useEffect(()=>{C.current=m},[m]),{faceScanDetector:async(t,s)=>{if(f.current&&t.current&&y&&x&&!(t.current.readyState<2))try{const r=await f.current.estimatePoses(t.current);if(r.length>0){const t=[],c=[];if(r[0].keypoints.forEach((e,a)=>{const n=e.score??0,o=[e.x??-1,e.y??-1,n];a<=10?t.push(o):c.push(o)}),s?.current){const e=s.current.getContext("2d"),{width:t,height:a}=s.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const d=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,s=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,r=t[2][0]-t[5][0],c=t[0][0]-t[5][0],i=c>.4*r&&c<.6*r,l=c>.85*r,d=t[2][0]-t[0][0]>.85*r;switch(e){case 0:case 3:return!o&&s&&i;case 1:return!o&&s&&l;case 2:return!o&&s&&d;default:return!1}})(w.current,t),u=c.slice(2).filter(e=>e[2]>.7).length<=2;F.current.push(d&&u),F.current.length>10&&F.current.shift();if(F.current.filter(Boolean).length>=2){const e=C.current+1;p(e)}else p(Math.max(0,C.current-1));if(C.current>=2){n?.();const t=w.current+1;p(0),F.current=[],h(t),v(!1),(async()=>{if(await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Sound-effect.mp3`),a.posthog.capture(`${l}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:w.current,nextStage:t,timestamp:(new Date).toISOString(),totalStages:4,stageName:T[w.current]}),1===t&&i&&i(),t>=4)o?.();else{let e=null;switch(t){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/${e}`),M()}})()}R(t,c,w.current,d,u,C.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:g,setScanStage:h,consecutiveValid:m,isModelLoaded:y,resetScan:()=>{a.posthog.capture(`${l}/face_scan_reset`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current],consecutiveValid:C.current}),h(0),p(0),v(!1),w.current=0,C.current=0,F.current=[],j.current="",_.current=0,N.current=!1,b.current&&(speechSynthesis.cancel(),b.current=null)},enableVoiceCommands:()=>{if(N.current=!0,"undefined"!=typeof window&&k&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:M,isScanningActive:x}}function i({onRetry:o,loading:s}){const{translate:r}=t.useContext(a.LanguageContext)||{},c=a.useConfig();return e.jsx("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:c?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e.jsx(a.Header,{noTitle:!0}),e.jsxs("div",{className:"flex flex-col items-center w-full",children:[e.jsx("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:c?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:c?.style?.heading?.headingFontSize||"32px",color:c?.style?.heading?.headingColor||"#000",fontWeight:c?.style?.heading?.headingFontWeight||"normal"},children:r?.(a.LanguageKeys.scanFailed)}),e.jsx("p",{className:"mb-[1.5rem]",style:{fontFamily:c?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:c?.style?.subheading?.subheadingFontSize||"14px",color:c?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:c?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(a.LanguageKeys.clickToResetScan)}),e.jsx(a.SpecificButton,{disabled:s,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(a.LanguageKeys.resetScan),postfixIcon:e.jsx(n.ArrowRight,{}),buttonFunc:()=>o?.()})]})]})})}function l({stage:n,videoLoading:o,setVideoLoading:s,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=t.useContext(a.LanguageContext)||{},u=a.useConfig();return-1===n?e.jsxs("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.LanguageKeys.faceVisible)}),o&&e.jsx("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.loadingVideo)}),r&&e.jsx("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.videoLoadFailed)}),!r&&e.jsx("div",{className:" w-[100px] mx-auto",children:e.jsx("video",{src:i===a.GenderType.Male?a.maleGlassesOffVideo:a.glassesOffVideo,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>s(!1),onLoadStart:()=>s(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e.jsx("div",{className:"flex justify-center w-full p-[1rem]",children:e.jsx(a.SpecificButton,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e.jsx("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.directionMessages[n])}),e.jsxs("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e.jsx("div",{className:` w-[120px] overflow-hidden ${0===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.forward:a.FACE_SCAN_HEADSHOT.female.forward,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${1===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.left:a.FACE_SCAN_HEADSHOT.female.left,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${2===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.right:a.FACE_SCAN_HEADSHOT.female.right,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${3===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.smile:a.FACE_SCAN_HEADSHOT.female.smile,type:"video/mp4"})})})]})]})})}const d=({webcamRef:s,canvasRef:r})=>{const{isError:c,isSuccess:d,showLoader:u,hasError:f,resetScanState:g,showGuideCard:h,scanStage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,getButtonText:b,isScanning:w,startScan:C,isModelLoaded:F,isLandscape:j,onRetry:_}=t.useContext(a.ParamsContext),N=a.useConfig();return c?e.jsx(i,{onRetry:_}):d?e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}):e.jsxs(e.Fragment,{children:[e.jsx("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),j&&!u&&!f&&e.jsx("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:N?.style?.base?.backgroundColor||"#fff"},children:e.jsx(a.Modal,{variant:"portrait",config:N})}),u&&!f&&e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}),e.jsx("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:N?.style?.base?.backgroundColor},children:e.jsx("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:e.jsxs("div",{className:"w-full h-full",children:[e.jsx("video",{ref:s,autoPlay:!0,playsInline:!0,muted:!0,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e.jsx("canvas",{ref:r,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!u&&f&&e.jsx(i,{loading:u,onRetry:g}),h&&!f&&!u&&!j&&e.jsx(o.Drawer,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e.jsx(l,{stage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,btnConfig:{label:b(),onClick:w?g:C,isDisabled:u||!F,icon:w?e.jsx(n.ArrowRight,{}):e.jsx(e.Fragment,{})}})})]})};exports.FaceScan=n=>{const{onScanSuccess:o,onScanError:s,onRetry:r,onScanStart:i,onCaptureComplete:l,onUploadStart:u,onUploadEnd:f,onMeasurementSocketStart:g,onMeasurementSocketClose:h,config:m,isError:p,isSuccess:y}=n,S=n.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},x=n.token??"",v=t.useRef(null),b=t.useRef(null),w=t.useRef(null),C=t.useRef([]),F=t.useRef(null),j=t.useRef(null),[_,N]=t.useState(!1),[E,k]=t.useState(!1),[T,I]=t.useState(!1),[R,M]=t.useState(!0),[P,D]=t.useState(!1),[L,A]=t.useState(!1),[O,z]=t.useState(!1),[$,H]=t.useState(a.generateUuid()),V=t.useMemo(()=>a.getSwanService(x),[x]),{isLandscape:W}=a.usePortraitLock(),{email:K,gender:U,deviceFocalLength:B,shopDomain:q,callbackUrl:G,bodyScanId:J}=S,[X,Q]=t.useState([]),[Y,Z]=t.useState(a.videoConstraintsExact),ee=t.useMemo(()=>a.getPreferredMediaRecorderTypes(),[]),te=a.getRecordingMimeType(X),ae=a.getRecordingExtension(te);a.usePosthogPageview();const ne=t.useCallback(()=>{console.log("Stopping recording..."),w.current&&"recording"===w.current.state&&w.current.stop(),w.current=null},[]),oe=async()=>{if(l?.(),C.current){if(0===C.current.length)return console.error("No video data recorded"),z(!0),void N(!1);u?.(),N(!0);const e=new File(C.current,`${$}.${ae}`,{type:te}),t=j.current??await a.getVideoFPS(e),n=e.size,o=(n/1048576).toFixed(2),s=Math.round(n/1e4),r={video_size_mb:parseFloat(o),video_size_bytes:n,video_fps:t||0,blob_count:C.current.length,estimated_duration_seconds:s},c=[{gender:U},{face_scan_id:$},{focal_length:`${B}`},{customer_store_url:q},{scan_type:"face_scan"},{body_scan_id:J}];G&&c.push({callback_url:G}),a.handleScanTimeCapture({eventName:`${q}/face_scan_meta_data`,faceScanId:$,email:K,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_start`,faceScanId:$,email:K,startTime:i});try{const t=await V.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:$,email:K,contentType:e.type}),n=Date.now(),o=n-i;a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_complete`,faceScanId:$,email:K,completionTime:n,uploadDuration:o}),f?.(),console.log("✅ Upload successful",t),V.measurement.handlFaceScaneSocket({onPreopen:()=>{g?.(),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"pre_open",type:"faceScan_recommendation",email:K})},faceScanId:$,onOpen:()=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"open",type:"faceScan_recommendation",email:K}),console.log("websocket connect open")},onError:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"error",type:"faceScan_recommendation",email:K}),he(e)},onSuccess:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"success",type:"faceScan_recommendation",email:K}),me(e)},onClose:()=>{h?.(),console.log("websocket connect close"),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"close",type:"faceScan_recommendation",email:K})}})}catch(e){f?.(),he(e)}}},se=t.useCallback(()=>{const e=v.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),s=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const r=document.createElement("video");r.srcObject=e,r.muted=!0,r.playsInline=!0,r.play();const c=()=>{a>n?(s?.save(),s?.translate(o.width,0),s?.rotate(Math.PI/2),s?.drawImage(r,0,0,n,a),s?.restore()):s?.drawImage(r,0,0,a,n),requestAnimationFrame(c)};c();const i=t.frameRate??10;j.current=i;const l=o.captureStream(i),d={videoBitsPerSecond:15e5};let u;X.length>0&&(d.mimeType=X[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),z(!0),void N(!1)}C.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&C.current&&C.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",C?.current?.length),oe()},u.start(100),w.current=u,console.log("Recording started successfully (portrait normalized)")},[X,oe]),{faceScanDetector:re,scanStage:ce,setScanStage:ie,resetScan:le,isModelLoaded:de,startScanSequence:ue}=c({faceScanId:$,shopDomain:q,isError:p,isSuccess:y,onScanComplete:()=>{ne()},onModelReady:()=>{k(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),se()}}),fe=t.useCallback(()=>{de&&(i?.(),ie(0),a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{I(!0),setTimeout(()=>{ue()},200)},200))},[ie,I,ue,de,i]),ge=t.useCallback(()=>{I(!1),M(!0),ne(),le(),r?.(),C.current=[],j.current=null,w.current&&(w.current=null),z(!1),ie(-1),H(a.generateUuid()),v.current&&F.current&&(v.current.srcObject=F.current,console.log("Camera stream restored after reset"))},[ie,I,M,ne,le,H]);t.useEffect(()=>{W&&!_&&ge()},[W,_,ge]);const he=e=>{console.log(e,"ws error"),s?.(e),z(!0),N(!1),M(!1),a.handleScanTimeCapture({eventName:`${q}/faceScan`,faceScanId:$,status:"failed",email:K,data:JSON.stringify(e)})},me=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&a.handleScanTimeCapture({eventName:`${q}/faceScan_success/intermediate`,faceScanId:$,status:"success",email:K,data:JSON.stringify(e)}),o?.(e)};t.useEffect(()=>{if(!p&&!y)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Y}).then(e=>{F.current=e,v.current&&(v.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),Y!==a.videoConstraintsExact?z(!0):Z(a.videoConstraintsFallback)}),()=>{F.current&&F.current.getTracks().forEach(e=>e.stop())}},[p,y,Y]),t.useEffect(()=>{if(!E||!T)return;const e=setInterval(()=>{re(v,b)},500);return()=>clearInterval(e)},[re,E,T]);return console.log("Model ready:",E,"Has error:",O,"Is scanning:",T,"showLoader",_),t.useEffect(()=>{const e=a.getSupportedMediaRecorderTypes(ee,a.videoTypes);Q(e)},[ee]),t.useEffect(()=>{ie(-1)},[]),e.jsx(a.LanguageContextProvider,{children:e.jsxs(a.ConfigProvider,{config:m,children:[W&&!_&&e.jsx(a.Modal,{variant:"portrait",config:m}),e.jsx(a.ParamsContext.Provider,{value:{isError:p,isSuccess:y,showLoader:_,hasError:O,resetScanState:ge,showGuideCard:R,scanStage:ce,videoLoading:P,setVideoLoading:D,videoError:L,setVideoError:A,gender:U,getButtonText:()=>T?a.LanguageKeys.reset:de?a.LanguageKeys.start:a.LanguageKeys.loading,isScanning:T,startScan:fe,isModelLoaded:de,onRetry:r},children:e.jsx(a.ShadowRoot,{children:e.jsx(d,{webcamRef:v,canvasRef:b})})})]})})};
|
|
2
|
+
//# sourceMappingURL=FaceScan-CXm-ZRzF.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("./Modal-B_UR_mwU.js"),n=require("lucide-react"),o=require("@mui/material");let s=null,r=!1;function c({faceScanId:e,onValidPose:n,onScanComplete:o,onModelReady:c,onStartRecording:i,shopDomain:l,isError:d,isSuccess:u}){const f=t.useRef(null),[g,h]=t.useState(0),[m,p]=t.useState(0),[y,S]=t.useState(!1),[x,v]=t.useState(!1),b=t.useRef(null),w=t.useRef(g),C=t.useRef(m),F=t.useRef([]),j=t.useRef(""),_=t.useRef(0),N=t.useRef(!1),E=t.useRef(0),k="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),T=t.useMemo(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),I=t.useMemo(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{a.posthog.capture(`${l}/face_scan_pose_detection`,e)},4e3),[l]),R=t.useCallback((t,a,n,o,s,r)=>{const c=Date.now();if(!(c-E.current<4e3)){E.current=c;try{const c=t[0]||[0,0,0],i=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],f=t.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,h=a.map(e=>e[2]).filter(e=>e>0),m=h.length>0?h.reduce((e,t)=>e+t,0)/h.length:0,p=Math.abs(i[0]-l[0]),y=c[0]-l[0],S=i[0]-c[0];let x="frontal";1===n?x="left":2===n?x="right":3===n&&(x="frontal_smile");const v={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:s,consecutiveValid:r,avgFaceScore:parseFloat(g.toFixed(3)),avgBodyScore:parseFloat(m.toFixed(3)),faceKeypointsDetected:f.length,bodyKeypointsDetected:h.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(c[2].toFixed(3)),leftEyeScore:parseFloat(i[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:x})};I(v)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,I]),M=()=>{a.posthog.capture(`${l}/face_scan_detection_started`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current]}),setTimeout(()=>{v(!0)},1500)},P=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(s)return s;if(r)for(;r;)if(await new Promise(e=>setTimeout(e,100)),s)return s;r=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),Promise.resolve().then(function(){return require("./pose-detection.esm-2mkM0o4k.js")})]);await e.setBackend("webgl"),await e.ready();const n=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),o=document.createElement("canvas");o.width="number"==typeof a.videoConstraints.width?a.videoConstraints.width:a.videoConstraints.width.ideal??a.videoConstraints.width.max??1280,o.height="number"==typeof a.videoConstraints.height?a.videoConstraints.height:a.videoConstraints.height.ideal??a.videoConstraints.height.max??720;const r=o.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,o.width,o.height);try{await n.estimatePoses(o)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return s=n,n}catch(e){return console.error("Failed to preload detector:",e),null}finally{r=!1}})();e&&(f.current=e,console.log("Face scan model loaded successfully"),S(!0),c?.())}catch(e){console.error("Error initializing face scan:",e)}};return t.useEffect(()=>{if(!d&&!u)return P(),()=>{(async()=>{try{S(!1)}catch(e){console.error("Error disposing resources:",e)}finally{h(0),p(0),w.current=0,C.current=0,F.current=[]}})()}},[d,u]),t.useEffect(()=>{w.current=g},[g]),t.useEffect(()=>{C.current=m},[m]),{faceScanDetector:async(t,s)=>{if(f.current&&t.current&&y&&x&&!(t.current.readyState<2))try{const r=await f.current.estimatePoses(t.current);if(r.length>0){const t=[],c=[];if(r[0].keypoints.forEach((e,a)=>{const n=e.score??0,o=[e.x??-1,e.y??-1,n];a<=10?t.push(o):c.push(o)}),s?.current){const e=s.current.getContext("2d"),{width:t,height:a}=s.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const d=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,s=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,r=t[2][0]-t[5][0],c=t[0][0]-t[5][0],i=c>.4*r&&c<.6*r,l=c>.85*r,d=t[2][0]-t[0][0]>.85*r;switch(e){case 0:case 3:return!o&&s&&i;case 1:return!o&&s&&l;case 2:return!o&&s&&d;default:return!1}})(w.current,t),u=c.slice(2).filter(e=>e[2]>.7).length<=2;F.current.push(d&&u),F.current.length>10&&F.current.shift();if(F.current.filter(Boolean).length>=2){const e=C.current+1;p(e)}else p(Math.max(0,C.current-1));if(C.current>=2){n?.();const t=w.current+1;p(0),F.current=[],h(t),v(!1),(async()=>{if(await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Sound-effect.mp3`),a.posthog.capture(`${l}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:w.current,nextStage:t,timestamp:(new Date).toISOString(),totalStages:4,stageName:T[w.current]}),1===t&&i&&i(),t>=4)o?.();else{let e=null;switch(t){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/${e}`),M()}})()}R(t,c,w.current,d,u,C.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:g,setScanStage:h,consecutiveValid:m,isModelLoaded:y,resetScan:()=>{a.posthog.capture(`${l}/face_scan_reset`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current],consecutiveValid:C.current}),h(0),p(0),v(!1),w.current=0,C.current=0,F.current=[],j.current="",_.current=0,N.current=!1,b.current&&(speechSynthesis.cancel(),b.current=null)},enableVoiceCommands:()=>{if(N.current=!0,"undefined"!=typeof window&&k&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:M,isScanningActive:x}}function i({onRetry:o,loading:s}){const{translate:r}=t.useContext(a.LanguageContext)||{},c=a.useConfig();return e.jsx("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:c?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e.jsx(a.Header,{noTitle:!0}),e.jsxs("div",{className:"flex flex-col items-center w-full",children:[e.jsx("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:c?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:c?.style?.heading?.headingFontSize||"32px",color:c?.style?.heading?.headingColor||"#000",fontWeight:c?.style?.heading?.headingFontWeight||"normal"},children:r?.(a.LanguageKeys.scanFailed)}),e.jsx("p",{className:"mb-[1.5rem]",style:{fontFamily:c?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:c?.style?.subheading?.subheadingFontSize||"14px",color:c?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:c?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(a.LanguageKeys.clickToResetScan)}),e.jsx(a.SpecificButton,{disabled:s,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(a.LanguageKeys.resetScan),postfixIcon:e.jsx(n.ArrowRight,{}),buttonFunc:()=>o?.()})]})]})})}function l({stage:n,videoLoading:o,setVideoLoading:s,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=t.useContext(a.LanguageContext)||{},u=a.useConfig();return-1===n?e.jsxs("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.LanguageKeys.faceVisible)}),o&&e.jsx("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.loadingVideo)}),r&&e.jsx("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.videoLoadFailed)}),!r&&e.jsx("div",{className:" w-[100px] mx-auto",children:e.jsx("video",{src:i===a.GenderType.Male?a.maleGlassesOffVideo:a.glassesOffVideo,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>s(!1),onLoadStart:()=>s(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e.jsx("div",{className:"flex justify-center w-full p-[1rem]",children:e.jsx(a.SpecificButton,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e.jsx("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.directionMessages[n])}),e.jsxs("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e.jsx("div",{className:` w-[120px] overflow-hidden ${0===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.forward:a.FACE_SCAN_HEADSHOT.female.forward,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${1===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.left:a.FACE_SCAN_HEADSHOT.female.left,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${2===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.right:a.FACE_SCAN_HEADSHOT.female.right,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${3===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:i===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.smile:a.FACE_SCAN_HEADSHOT.female.smile,type:"video/mp4"})})})]})]})})}const d=({webcamRef:s,canvasRef:r})=>{const{isError:c,isSuccess:d,showLoader:u,hasError:f,resetScanState:g,showGuideCard:h,scanStage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,getButtonText:b,isScanning:w,startScan:C,isModelLoaded:F,isLandscape:j,onRetry:_}=t.useContext(a.ParamsContext),N=a.useConfig();return c?e.jsx(i,{onRetry:_}):d?e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}):e.jsxs(e.Fragment,{children:[e.jsx("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),j&&!u&&!f&&e.jsx("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e.jsx(a.Modal,{variant:"portrait",config:N})}),u&&!f&&e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}),e.jsx("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:N?.style?.base?.backgroundColor},children:e.jsx("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:e.jsxs("div",{className:"w-full h-full",children:[e.jsx("video",{ref:s,autoPlay:!0,playsInline:!0,muted:!0,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e.jsx("canvas",{ref:r,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!u&&f&&e.jsx(i,{loading:u,onRetry:g}),h&&!f&&!u&&!j&&e.jsx(o.Drawer,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e.jsx(l,{stage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,btnConfig:{label:b(),onClick:w?g:C,isDisabled:u||!F,icon:w?e.jsx(n.ArrowRight,{}):e.jsx(e.Fragment,{})}})})]})};exports.FaceScan=n=>{const{onScanSuccess:o,onScanError:s,onRetry:r,onScanStart:i,onCaptureComplete:l,onUploadStart:u,onUploadEnd:f,onMeasurementSocketStart:g,onMeasurementSocketClose:h,config:m,isError:p,isSuccess:y}=n,S=n.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},x=n.token??"",v=t.useRef(null),b=t.useRef(null),w=t.useRef(null),C=t.useRef([]),F=t.useRef(null),j=t.useRef(null),[_,N]=t.useState(!1),[E,k]=t.useState(!1),[T,I]=t.useState(!1),[R,M]=t.useState(!0),[P,D]=t.useState(!1),[L,A]=t.useState(!1),[O,z]=t.useState(!1),[$,H]=t.useState(a.generateUuid()),V=t.useMemo(()=>a.getSwanService(x),[x]),{isLandscape:W}=a.usePortraitLock(),{email:K,gender:U,deviceFocalLength:B,shopDomain:q,callbackUrl:G,bodyScanId:J}=S,[X,Q]=t.useState([]),[Y,Z]=t.useState(a.videoConstraintsExact),ee=t.useMemo(()=>a.getPreferredMediaRecorderTypes(),[]),te=a.getRecordingMimeType(X),ae=a.getRecordingExtension(te);a.usePosthogPageview();const ne=t.useCallback(()=>{console.log("Stopping recording..."),w.current&&"recording"===w.current.state&&w.current.stop(),w.current=null},[]),oe=async()=>{if(l?.(),C.current){if(0===C.current.length)return console.error("No video data recorded"),z(!0),void N(!1);u?.(),N(!0);const e=new File(C.current,`${$}.${ae}`,{type:te}),t=j.current??await a.getVideoFPS(e),n=e.size,o=(n/1048576).toFixed(2),s=Math.round(n/1e4),r={video_size_mb:parseFloat(o),video_size_bytes:n,video_fps:t||0,blob_count:C.current.length,estimated_duration_seconds:s},c=[{gender:U},{face_scan_id:$},{focal_length:`${B}`},{customer_store_url:q},{scan_type:"face_scan"},{body_scan_id:J}];G&&c.push({callback_url:G}),a.handleScanTimeCapture({eventName:`${q}/face_scan_meta_data`,faceScanId:$,email:K,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_start`,faceScanId:$,email:K,startTime:i});try{const t=await V.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:$,email:K,contentType:e.type}),n=Date.now(),o=n-i;a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_complete`,faceScanId:$,email:K,completionTime:n,uploadDuration:o}),f?.(),console.log("✅ Upload successful",t),V.measurement.handlFaceScaneSocket({onPreopen:()=>{g?.(),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"pre_open",type:"faceScan_recommendation",email:K})},faceScanId:$,onOpen:()=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"open",type:"faceScan_recommendation",email:K}),console.log("websocket connect open")},onError:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"error",type:"faceScan_recommendation",email:K}),me(e)},onSuccess:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"success",type:"faceScan_recommendation",email:K}),pe(e)},onClose:()=>{h?.(),console.log("websocket connect close"),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"close",type:"faceScan_recommendation",email:K})}})}catch(e){f?.(),me(e)}}},se=t.useCallback(()=>{const e=v.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),s=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const r=document.createElement("video");r.srcObject=e,r.muted=!0,r.playsInline=!0,r.play();const c=()=>{a>n?(s?.save(),s?.translate(o.width,0),s?.rotate(Math.PI/2),s?.drawImage(r,0,0,n,a),s?.restore()):s?.drawImage(r,0,0,a,n),requestAnimationFrame(c)};c();const i=t.frameRate??10;j.current=i;const l=o.captureStream(i),d={videoBitsPerSecond:15e5};let u;X.length>0&&(d.mimeType=X[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),z(!0),void N(!1)}C.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&C.current&&C.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",C?.current?.length),oe()},u.start(100),w.current=u,console.log("Recording started successfully (portrait normalized)")},[X,oe]),{faceScanDetector:re,scanStage:ce,setScanStage:ie,resetScan:le,isModelLoaded:de,startScanSequence:ue}=c({faceScanId:$,shopDomain:q,isError:p,isSuccess:y,onScanComplete:()=>{ne()},onModelReady:()=>{k(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),se()}}),fe=t.useCallback(()=>{de&&(i?.(),ie(0),a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{I(!0),setTimeout(()=>{ue()},200)},200))},[ie,I,ue,de,i]),ge=t.useCallback(()=>{I(!1),M(!0),ne(),le(),r?.(),C.current=[],j.current=null,w.current&&(w.current=null),z(!1),ie(-1),H(a.generateUuid()),v.current&&F.current&&(v.current.srcObject=F.current,console.log("Camera stream restored after reset"))},[ie,I,M,ne,le,H]),he=t.useRef(!1);t.useEffect(()=>{!W||he.current||_||p||y||O||(a.speechService.stopAudio(),ge()),he.current=W},[W,_,p,y,O,ge]);const me=e=>{console.log(e,"ws error"),s?.(e),z(!0),N(!1),M(!1),a.handleScanTimeCapture({eventName:`${q}/faceScan`,faceScanId:$,status:"failed",email:K,data:JSON.stringify(e)})},pe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&a.handleScanTimeCapture({eventName:`${q}/faceScan_success/intermediate`,faceScanId:$,status:"success",email:K,data:JSON.stringify(e)}),o?.(e)};t.useEffect(()=>{if(!p&&!y)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Y}).then(e=>{F.current=e,v.current&&(v.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),Y!==a.videoConstraintsExact?z(!0):Z(a.videoConstraintsFallback)}),()=>{F.current&&F.current.getTracks().forEach(e=>e.stop())}},[p,y,Y]),t.useEffect(()=>{if(!E||!T)return;const e=setInterval(()=>{re(v,b)},500);return()=>clearInterval(e)},[re,E,T]);return console.log("Model ready:",E,"Has error:",O,"Is scanning:",T,"showLoader",_),t.useEffect(()=>{const e=a.getSupportedMediaRecorderTypes(ee,a.videoTypes);Q(e)},[ee]),t.useEffect(()=>{ie(-1)},[]),e.jsx(a.LanguageContextProvider,{children:e.jsx(a.ConfigProvider,{config:m,children:e.jsx(a.ParamsContext.Provider,{value:{isError:p,isSuccess:y,showLoader:_,hasError:O,resetScanState:ge,showGuideCard:R,scanStage:ce,videoLoading:P,setVideoLoading:D,videoError:L,setVideoError:A,gender:U,getButtonText:()=>T?a.LanguageKeys.reset:de?a.LanguageKeys.start:a.LanguageKeys.loading,isScanning:T,startScan:fe,isModelLoaded:de,isLandscape:W,onRetry:r},children:e.jsx(a.ShadowRoot,{children:e.jsx(d,{webcamRef:v,canvasRef:b})})})})})};
|
|
2
|
+
//# sourceMappingURL=FaceScan-DHPn0Xfr.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as o,useMemo as r,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as f,u as h,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,M as _,e as I,f as k,h as M,i as C,j as D,k as E,l as P,n as T,o as z,q as R,r as L,t as $,C as j,w as V,x as O,y as W,z as U}from"./LoadingScreen-CXfophtU.js";import{ArrowRight as B}from"lucide-react";import{Drawer as A}from"@mui/material";let q=null,J=!1;function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:f,shopDomain:h,isError:g,isSuccess:p}){const y=n(null),[S,b]=o(0),[w,v]=o(0),[x,F]=o(!1),[N,_]=o(!1),I=n(null),k=n(S),M=n(w),C=n([]),D=n(""),E=n(0),P=n(!1),T=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),R=r(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=r(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${h}/face_scan_pose_detection`,e)},4e3),[h]),$=c((t,a,n,o,r,c)=>{const i=Date.now();if(!(i-T.current<4e3)){T.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),f=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,h=a.map(e=>e[2]).filter(e=>e>0),g=h.length>0?h.reduce((e,t)=>e+t,0)/h.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:r,consecutiveValid:c,avgFaceScore:parseFloat(f.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:h.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),j=()=>{l.capture(`${h}/face_scan_detection_started`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current]}),setTimeout(()=>{_(!0)},1500)},V=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(q)return q;if(J)for(;J;)if(await new Promise(e=>setTimeout(e,100)),q)return q;J=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-LvkS7dAF.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const o=n.getContext("2d");if(o){o.fillStyle="black",o.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return q=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{J=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return V(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),k.current=0,M.current=0,C.current=[]}})()}},[g,p]),i(()=>{k.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,o)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2))try{const r=await y.current.estimatePoses(n.current);if(r.length>0){const n=[],c=[];if(r[0].keypoints.forEach((e,t)=>{const a=e.score??0,o=[e.x??-1,e.y??-1,a];t<=10?n.push(o):c.push(o)}),o?.current){const e=o.current.getContext("2d"),{width:t,height:a}=o.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const i=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,r=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!o&&r&&s;case 1:return!o&&r&&l;case 2:return!o&&r&&d;default:return!1}})(k.current,n),s=c.slice(2).filter(e=>e[2]>.7).length<=2;C.current.push(i&&s),C.current.length>10&&C.current.shift();if(C.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=k.current+1;v(0),C.current=[],b(n),_(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${h}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:k.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:R[k.current]}),1===n&&f&&f(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),j()}})()}$(n,c,k.current,i,s,M.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${h}/face_scan_reset`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current],consecutiveValid:M.current}),b(0),v(0),_(!1),k.current=0,M.current=0,C.current=[],D.current="",E.current=0,P.current=!1,I.current&&(speechSynthesis.cancel(),I.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:j,isScanningActive:N}}function K({onRetry:a,loading:n}){const{translate:o}=s(f)||{},r=h();return e("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:r?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:r?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:r?.style?.heading?.headingFontSize||"32px",color:r?.style?.heading?.headingColor||"#000",fontWeight:r?.style?.heading?.headingFontWeight||"normal"},children:o?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:r?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:r?.style?.subheading?.subheadingFontSize||"14px",color:r?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:r?.style?.subheading?.subheadingFontWeight||"normal"},children:o?.(p.clickToResetScan)}),e(y,{disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:o?.(p.resetScan),postfixIcon:e(B,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:o,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(f)||{},u=h();return-1===a?t("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),r&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!r&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>o(!1),onLoadStart:()=>o(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:o})=>{const{isError:r,isSuccess:c,showLoader:i,hasError:l,resetScanState:d,showGuideCard:u,scanStage:f,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,getButtonText:w,isScanning:v,startScan:x,isModelLoaded:I,isLandscape:k,onRetry:M}=s(F),C=h();return r?e(K,{onRetry:M}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),k&&!i&&!l&&e("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:C?.style?.base?.backgroundColor||"#fff"},children:e(_,{variant:"portrait",config:C})}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:C?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:o,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&e(K,{loading:i,onRetry:d}),u&&!l&&!i&&!k&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e(H,{stage:f,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,btnConfig:{label:w(),onClick:v?d:x,isDisabled:i||!I,icon:e(v?B:a,{})}})})]})},Q=a=>{const{onScanSuccess:s,onScanError:l,onRetry:m,onScanStart:f,onCaptureComplete:h,onUploadStart:g,onUploadEnd:y,onMeasurementSocketStart:S,onMeasurementSocketClose:b,config:w,isError:v,isSuccess:x}=a,N=a.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},B=a.token??"",A=n(null),q=n(null),J=n(null),K=n([]),H=n(null),Q=n(null),[Y,Z]=o(!1),[ee,te]=o(!1),[ae,ne]=o(!1),[oe,re]=o(!0),[ce,ie]=o(!1),[se,le]=o(!1),[de,ue]=o(!1),[me,fe]=o(I()),he=r(()=>k(B),[B]),{isLandscape:ge}=M(),{email:pe,gender:ye,deviceFocalLength:Se,shopDomain:be,callbackUrl:we,bodyScanId:ve}=N,[xe,Fe]=o([]),[Ne,_e]=o(C),Ie=r(()=>D(),[]),ke=E(xe),Me=P(ke);T();const Ce=c(()=>{console.log("Stopping recording..."),J.current&&"recording"===J.current.state&&J.current.stop(),J.current=null},[]),De=async()=>{if(h?.(),K.current){if(0===K.current.length)return console.error("No video data recorded"),ue(!0),void Z(!1);g?.(),Z(!0);const e=new File(K.current,`${me}.${Me}`,{type:ke}),t=Q.current??await O(e),a=e.size,n=(a/1048576).toFixed(2),o=Math.round(a/1e4),r={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:K.current.length,estimated_duration_seconds:o},c=[{gender:ye},{face_scan_id:me},{focal_length:`${Se}`},{customer_store_url:be},{scan_type:"face_scan"},{body_scan_id:ve}];we&&c.push({callback_url:we}),W({eventName:`${be}/face_scan_meta_data`,faceScanId:me,email:pe,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();W({eventName:`${be}/face_scan_upload_start`,faceScanId:me,email:pe,startTime:i});try{const t=await he.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:me,email:pe,contentType:e.type}),a=Date.now();W({eventName:`${be}/face_scan_upload_complete`,faceScanId:me,email:pe,completionTime:a,uploadDuration:a-i}),y?.(),console.log("✅ Upload successful",t),he.measurement.handlFaceScaneSocket({onPreopen:()=>{S?.(),U({eventName:`${be}/webSocket`,faceScanID:me,connection:"pre_open",type:"faceScan_recommendation",email:pe})},faceScanId:me,onOpen:()=>{U({eventName:`${be}/webSocket`,faceScanID:me,connection:"open",type:"faceScan_recommendation",email:pe}),console.log("websocket connect open")},onError:e=>{U({eventName:`${be}/webSocket`,faceScanID:me,connection:"error",type:"faceScan_recommendation",email:pe}),Oe(e)},onSuccess:e=>{U({eventName:`${be}/webSocket`,faceScanID:me,connection:"success",type:"faceScan_recommendation",email:pe}),We(e)},onClose:()=>{b?.(),console.log("websocket connect close"),U({eventName:`${be}/webSocket`,faceScanID:me,connection:"close",type:"faceScan_recommendation",email:pe})}})}catch(e){y?.(),Oe(e)}}},Ee=c(()=>{const e=A.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),r=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play();const i=()=>{a>n?(r?.save(),r?.translate(o.width,0),r?.rotate(Math.PI/2),r?.drawImage(c,0,0,n,a),r?.restore()):r?.drawImage(c,0,0,a,n),requestAnimationFrame(i)};i();const s=t.frameRate??10;Q.current=s;const l=o.captureStream(s),d={videoBitsPerSecond:15e5};let u;xe.length>0&&(d.mimeType=xe[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),ue(!0),void Z(!1)}K.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&K.current&&K.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",K?.current?.length),De()},u.start(100),J.current=u,console.log("Recording started successfully (portrait normalized)")},[xe,De]),{faceScanDetector:Pe,scanStage:Te,setScanStage:ze,resetScan:Re,isModelLoaded:Le,startScanSequence:$e}=G({faceScanId:me,shopDomain:be,isError:v,isSuccess:x,onScanComplete:()=>{Ce()},onModelReady:()=>{te(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),Ee()}}),je=c(()=>{Le&&(f?.(),ze(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{ne(!0),setTimeout(()=>{$e()},200)},200))},[ze,ne,$e,Le,f]),Ve=c(()=>{ne(!1),re(!0),Ce(),Re(),m?.(),K.current=[],Q.current=null,J.current&&(J.current=null),ue(!1),ze(-1),fe(I()),A.current&&H.current&&(A.current.srcObject=H.current,console.log("Camera stream restored after reset"))},[ze,ne,re,Ce,Re,fe]);i(()=>{ge&&!Y&&Ve()},[ge,Y,Ve]);const Oe=e=>{console.log(e,"ws error"),l?.(e),ue(!0),Z(!1),re(!1),W({eventName:`${be}/faceScan`,faceScanId:me,status:"failed",email:pe,data:JSON.stringify(e)})},We=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&W({eventName:`${be}/faceScan_success/intermediate`,faceScanId:me,status:"success",email:pe,data:JSON.stringify(e)}),s?.(e)};i(()=>{if(!v&&!x)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Ne}).then(e=>{H.current=e,A.current&&(A.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),Ne!==C?ue(!0):_e(z)}),()=>{H.current&&H.current.getTracks().forEach(e=>e.stop())}},[v,x,Ne]),i(()=>{if(!ee||!ae)return;const e=setInterval(()=>{Pe(A,q)},500);return()=>clearInterval(e)},[Pe,ee,ae]);return console.log("Model ready:",ee,"Has error:",de,"Is scanning:",ae,"showLoader",Y),i(()=>{const e=R(Ie,L);Fe(e)},[Ie]),i(()=>{ze(-1)},[]),e($,{children:t(j,{config:w,children:[ge&&!Y&&e(_,{variant:"portrait",config:w}),e(F.Provider,{value:{isError:v,isSuccess:x,showLoader:Y,hasError:de,resetScanState:Ve,showGuideCard:oe,scanStage:Te,videoLoading:ce,setVideoLoading:ie,videoError:se,setVideoError:le,gender:ye,getButtonText:()=>ae?p.reset:Le?p.start:p.loading,isScanning:ae,startScan:je,isModelLoaded:Le,onRetry:m},children:e(V,{children:e(X,{webcamRef:A,canvasRef:q})})})]})})};export{Q as F};
|
|
2
|
+
//# sourceMappingURL=FaceScan-H1sDaOF2.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as o,useMemo as r,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,M as _,e as I,f as k,h as M,i as C,j as D,k as E,l as P,n as T,o as z,q as R,r as L,t as $,C as j,w as V,x as O,y as W,z as U}from"./Modal-6Y88Up1w.js";import{ArrowRight as B}from"lucide-react";import{Drawer as A}from"@mui/material";let q=null,J=!1;function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:h,shopDomain:f,isError:g,isSuccess:p}){const y=n(null),[S,b]=o(0),[w,v]=o(0),[x,F]=o(!1),[N,_]=o(!1),I=n(null),k=n(S),M=n(w),C=n([]),D=n(""),E=n(0),P=n(!1),T=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),R=r(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=r(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),$=c((t,a,n,o,r,c)=>{const i=Date.now();if(!(i-T.current<4e3)){T.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:r,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),j=()=>{l.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current]}),setTimeout(()=>{_(!0)},1500)},V=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(q)return q;if(J)for(;J;)if(await new Promise(e=>setTimeout(e,100)),q)return q;J=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-LvkS7dAF.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const o=n.getContext("2d");if(o){o.fillStyle="black",o.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return q=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{J=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return V(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),k.current=0,M.current=0,C.current=[]}})()}},[g,p]),i(()=>{k.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,o)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2))try{const r=await y.current.estimatePoses(n.current);if(r.length>0){const n=[],c=[];if(r[0].keypoints.forEach((e,t)=>{const a=e.score??0,o=[e.x??-1,e.y??-1,a];t<=10?n.push(o):c.push(o)}),o?.current){const e=o.current.getContext("2d"),{width:t,height:a}=o.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const i=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,r=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!o&&r&&s;case 1:return!o&&r&&l;case 2:return!o&&r&&d;default:return!1}})(k.current,n),s=c.slice(2).filter(e=>e[2]>.7).length<=2;C.current.push(i&&s),C.current.length>10&&C.current.shift();if(C.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=k.current+1;v(0),C.current=[],b(n),_(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:k.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:R[k.current]}),1===n&&h&&h(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),j()}})()}$(n,c,k.current,i,s,M.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current],consecutiveValid:M.current}),b(0),v(0),_(!1),k.current=0,M.current=0,C.current=[],D.current="",E.current=0,P.current=!1,I.current&&(speechSynthesis.cancel(),I.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:j,isScanningActive:N}}function K({onRetry:a,loading:n}){const{translate:o}=s(h)||{},r=f();return e("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:r?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:r?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:r?.style?.heading?.headingFontSize||"32px",color:r?.style?.heading?.headingColor||"#000",fontWeight:r?.style?.heading?.headingFontWeight||"normal"},children:o?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:r?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:r?.style?.subheading?.subheadingFontSize||"14px",color:r?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:r?.style?.subheading?.subheadingFontWeight||"normal"},children:o?.(p.clickToResetScan)}),e(y,{disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:o?.(p.resetScan),postfixIcon:e(B,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:o,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),r&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!r&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>o(!1),onLoadStart:()=>o(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:o})=>{const{isError:r,isSuccess:c,showLoader:i,hasError:l,resetScanState:d,showGuideCard:u,scanStage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,getButtonText:w,isScanning:v,startScan:x,isModelLoaded:I,isLandscape:k,onRetry:M}=s(F),C=f();return r?e(K,{onRetry:M}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),k&&!i&&!l&&e("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:C?.style?.base?.backgroundColor||"#fff"},children:e(_,{variant:"portrait",config:C})}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:C?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)"}}),e("canvas",{ref:o,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&e(K,{loading:i,onRetry:d}),u&&!l&&!i&&!k&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e(H,{stage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,btnConfig:{label:w(),onClick:v?d:x,isDisabled:i||!I,icon:e(v?B:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:m,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},N=t.token??"",_=n(null),B=n(null),A=n(null),q=n([]),J=n(null),K=n(null),[H,Q]=o(!1),[Y,Z]=o(!1),[ee,te]=o(!1),[ae,ne]=o(!0),[oe,re]=o(!1),[ce,ie]=o(!1),[se,le]=o(!1),[de,ue]=o(I()),me=r(()=>k(N),[N]),{isLandscape:he}=M(),{email:fe,gender:ge,deviceFocalLength:pe,shopDomain:ye,callbackUrl:Se,bodyScanId:be}=x,[we,ve]=o([]),[xe,Fe]=o(C),Ne=r(()=>D(),[]),_e=E(we),Ie=P(_e);T();const ke=c(()=>{console.log("Stopping recording..."),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),q.current){if(0===q.current.length)return console.error("No video data recorded"),le(!0),void Q(!1);f?.(),Q(!0);const e=new File(q.current,`${de}.${Ie}`,{type:_e}),t=K.current??await O(e),a=e.size,n=(a/1048576).toFixed(2),o=Math.round(a/1e4),r={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:q.current.length,estimated_duration_seconds:o},c=[{gender:ge},{face_scan_id:de},{focal_length:`${pe}`},{customer_store_url:ye},{scan_type:"face_scan"},{body_scan_id:be}];Se&&c.push({callback_url:Se}),W({eventName:`${ye}/face_scan_meta_data`,faceScanId:de,email:fe,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();W({eventName:`${ye}/face_scan_upload_start`,faceScanId:de,email:fe,startTime:i});try{const t=await me.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:de,email:fe,contentType:e.type}),a=Date.now();W({eventName:`${ye}/face_scan_upload_complete`,faceScanId:de,email:fe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),me.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"pre_open",type:"faceScan_recommendation",email:fe})},faceScanId:de,onOpen:()=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"open",type:"faceScan_recommendation",email:fe}),console.log("websocket connect open")},onError:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"error",type:"faceScan_recommendation",email:fe}),Ve(e)},onSuccess:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"success",type:"faceScan_recommendation",email:fe}),Oe(e)},onClose:()=>{S?.(),console.log("websocket connect close"),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"close",type:"faceScan_recommendation",email:fe})}})}catch(e){g?.(),Ve(e)}}},Ce=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),r=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play();const i=()=>{a>n?(r?.save(),r?.translate(o.width,0),r?.rotate(Math.PI/2),r?.drawImage(c,0,0,n,a),r?.restore()):r?.drawImage(c,0,0,a,n),requestAnimationFrame(i)};i();const s=t.frameRate??10;K.current=s;const l=o.captureStream(s),d={videoBitsPerSecond:15e5};let u;we.length>0&&(d.mimeType=we[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),le(!0),void Q(!1)}q.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&q.current&&q.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",q?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[we,Me]),{faceScanDetector:De,scanStage:Ee,setScanStage:Pe,resetScan:Te,isModelLoaded:ze,startScanSequence:Re}=G({faceScanId:de,shopDomain:ye,isError:w,isSuccess:v,onScanComplete:()=>{ke()},onModelReady:()=>{Z(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),Ce()}}),Le=c(()=>{ze&&(m?.(),Pe(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{te(!0),setTimeout(()=>{Re()},200)},200))},[Pe,te,Re,ze,m]),$e=c(()=>{te(!1),ne(!0),ke(),Te(),l?.(),q.current=[],K.current=null,A.current&&(A.current=null),le(!1),Pe(-1),ue(I()),_.current&&J.current&&(_.current.srcObject=J.current,console.log("Camera stream restored after reset"))},[Pe,te,ne,ke,Te,ue]),je=n(!1);i(()=>{!he||je.current||H||w||v||se||(d.stopAudio(),$e()),je.current=he},[he,H,w,v,se,$e]);const Ve=e=>{console.log(e,"ws error"),s?.(e),le(!0),Q(!1),ne(!1),W({eventName:`${ye}/faceScan`,faceScanId:de,status:"failed",email:fe,data:JSON.stringify(e)})},Oe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&W({eventName:`${ye}/faceScan_success/intermediate`,faceScanId:de,status:"success",email:fe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:xe}).then(e=>{J.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),xe!==C?le(!0):Fe(z)}),()=>{J.current&&J.current.getTracks().forEach(e=>e.stop())}},[w,v,xe]),i(()=>{if(!Y||!ee)return;const e=setInterval(()=>{De(_,B)},500);return()=>clearInterval(e)},[De,Y,ee]);return console.log("Model ready:",Y,"Has error:",se,"Is scanning:",ee,"showLoader",H),i(()=>{const e=R(Ne,L);ve(e)},[Ne]),i(()=>{Pe(-1)},[]),e($,{children:e(j,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:H,hasError:se,resetScanState:$e,showGuideCard:ae,scanStage:Ee,videoLoading:oe,setVideoLoading:re,videoError:ce,setVideoError:ie,gender:ge,getButtonText:()=>ee?p.reset:ze?p.start:p.loading,isScanning:ee,startScan:Le,isModelLoaded:ze,isLandscape:he,onRetry:l},children:e(V,{children:e(X,{webcamRef:_,canvasRef:B})})})})})};export{Q as F};
|
|
2
|
+
//# sourceMappingURL=FaceScan-Q8GZC46J.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{jsx as e,jsxs as t,Fragment as a}from"react/jsx-runtime";import{useRef as n,useState as o,useMemo as r,useCallback as c,useEffect as i,useContext as s}from"react";import{p as l,s as d,v as u,a as m,L as h,u as f,H as g,b as p,S as y,m as S,g as b,G as w,d as v,F as x,P as F,c as N,M as _,e as I,f as k,h as M,i as C,j as D,k as E,l as P,n as T,o as z,q as R,r as L,t as $,C as j,w as V,x as O,y as W,z as U}from"./Modal-6Y88Up1w.js";import{ArrowRight as B}from"lucide-react";import{Drawer as A}from"@mui/material";let q=null,J=!1;function G({faceScanId:e,onValidPose:t,onScanComplete:a,onModelReady:s,onStartRecording:h,shopDomain:f,isError:g,isSuccess:p}){const y=n(null),[S,b]=o(0),[w,v]=o(0),[x,F]=o(!1),[N,_]=o(!1),I=n(null),k=n(S),M=n(w),C=n([]),D=n(""),E=n(0),P=n(!1),T=n(0),z="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),R=r(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),L=r(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{l.capture(`${f}/face_scan_pose_detection`,e)},4e3),[f]),$=c((t,a,n,o,r,c)=>{const i=Date.now();if(!(i-T.current<4e3)){T.current=i;try{const i=t[0]||[0,0,0],s=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],m=t.map(e=>e[2]).filter(e=>e>0),h=m.length>0?m.reduce((e,t)=>e+t,0)/m.length:0,f=a.map(e=>e[2]).filter(e=>e>0),g=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,p=Math.abs(s[0]-l[0]),y=i[0]-l[0],S=s[0]-i[0];let b="frontal";1===n?b="left":2===n?b="right":3===n&&(b="frontal_smile");const w={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:r,consecutiveValid:c,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(g.toFixed(3)),faceKeypointsDetected:m.length,bodyKeypointsDetected:f.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(s[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:b})};L(w)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,L]),j=()=>{l.capture(`${f}/face_scan_detection_started`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current]}),setTimeout(()=>{_(!0)},1500)},V=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(q)return q;if(J)for(;J;)if(await new Promise(e=>setTimeout(e,100)),q)return q;J=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),import("./pose-detection.esm-LvkS7dAF.js")]);await e.setBackend("webgl"),await e.ready();const a=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),n=document.createElement("canvas");n.width="number"==typeof m.width?m.width:m.width.ideal??m.width.max??1280,n.height="number"==typeof m.height?m.height:m.height.ideal??m.height.max??720;const o=n.getContext("2d");if(o){o.fillStyle="black",o.fillRect(0,0,n.width,n.height);try{await a.estimatePoses(n)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return q=a,a}catch(e){return console.error("Failed to preload detector:",e),null}finally{J=!1}})();e&&(y.current=e,console.log("Face scan model loaded successfully"),F(!0),s?.())}catch(e){console.error("Error initializing face scan:",e)}};return i(()=>{if(!g&&!p)return V(),()=>{(async()=>{try{F(!1)}catch(e){console.error("Error disposing resources:",e)}finally{b(0),v(0),k.current=0,M.current=0,C.current=[]}})()}},[g,p]),i(()=>{k.current=S},[S]),i(()=>{M.current=w},[w]),{faceScanDetector:async(n,o)=>{if(y.current&&n.current&&x&&N&&!(n.current.readyState<2))try{const r=await y.current.estimatePoses(n.current);if(r.length>0){const n=[],c=[];if(r[0].keypoints.forEach((e,t)=>{const a=e.score??0,o=[e.x??-1,e.y??-1,a];t<=10?n.push(o):c.push(o)}),o?.current){const e=o.current.getContext("2d"),{width:t,height:a}=o.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(M.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const i=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,r=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,c=t[2][0]-t[5][0],i=t[0][0]-t[5][0],s=i>.4*c&&i<.6*c,l=i>.85*c,d=t[2][0]-t[0][0]>.85*c;switch(e){case 0:case 3:return!o&&r&&s;case 1:return!o&&r&&l;case 2:return!o&&r&&d;default:return!1}})(k.current,n),s=c.slice(2).filter(e=>e[2]>.7).length<=2;C.current.push(i&&s),C.current.length>10&&C.current.shift();if(C.current.filter(Boolean).length>=2){const e=M.current+1;v(e)}else v(Math.max(0,M.current-1));if(M.current>=2){t?.();const n=k.current+1;v(0),C.current=[],b(n),_(!1),(async()=>{if(await d.playAudio(`${u}face-scan-vos/Sound-effect.mp3`),l.capture(`${f}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:k.current,nextStage:n,timestamp:(new Date).toISOString(),totalStages:4,stageName:R[k.current]}),1===n&&h&&h(),n>=4)a?.();else{let e=null;switch(n){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await d.playAudio(`${u}face-scan-vos/${e}`),j()}})()}$(n,c,k.current,i,s,M.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:S,setScanStage:b,consecutiveValid:w,isModelLoaded:x,resetScan:()=>{l.capture(`${f}/face_scan_reset`,{faceScanId:e,stage:k.current,timestamp:(new Date).toISOString(),stageName:R[k.current],consecutiveValid:M.current}),b(0),v(0),_(!1),k.current=0,M.current=0,C.current=[],D.current="",E.current=0,P.current=!1,I.current&&(speechSynthesis.cancel(),I.current=null)},enableVoiceCommands:()=>{if(P.current=!0,"undefined"!=typeof window&&z&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:j,isScanningActive:N}}function K({onRetry:a,loading:n}){const{translate:o}=s(h)||{},r=f();return e("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:r?.style?.base?.backgroundColor},children:t("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e(g,{noTitle:!0}),t("div",{className:"flex flex-col items-center w-full",children:[e("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:r?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:r?.style?.heading?.headingFontSize||"32px",color:r?.style?.heading?.headingColor||"#000",fontWeight:r?.style?.heading?.headingFontWeight||"normal"},children:o?.(p.scanFailed)}),e("p",{className:"mb-[1.5rem]",style:{fontFamily:r?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:r?.style?.subheading?.subheadingFontSize||"14px",color:r?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:r?.style?.subheading?.subheadingFontWeight||"normal"},children:o?.(p.clickToResetScan)}),e(y,{disabled:n,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:o?.(p.resetScan),postfixIcon:e(B,{}),buttonFunc:()=>a?.()})]})]})})}function H({stage:a,videoLoading:n,setVideoLoading:o,videoError:r,setVideoError:c,gender:i,btnConfig:l}){const{translate:d}=s(h)||{},u=f();return-1===a?t("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(p.faceVisible)}),n&&e("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.loadingVideo)}),r&&e("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(p.videoLoadFailed)}),!r&&e("div",{className:" w-[100px] mx-auto",children:e("video",{src:i===w.Male?S:b,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>o(!1),onLoadStart:()=>o(!0),onError:()=>c(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e("div",{className:"flex justify-center w-full p-[1rem]",children:e(y,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:t("div",{className:"w-full",children:[e(g,{noTitle:!0}),e("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(v[a])}),t("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e("div",{className:` w-[120px] overflow-hidden ${0===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.forward:x.female.forward,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${1===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.left:x.female.left,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${2===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.right:x.female.right,type:"video/mp4"})})}),e("div",{className:` w-[120px] overflow-hidden ${3===a?"opacity-100":"opacity-0 hidden"} `,children:e("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e("source",{src:i===w.Male?x.male.smile:x.female.smile,type:"video/mp4"})})})]})]})})}const X=({webcamRef:n,canvasRef:o})=>{const{isError:r,isSuccess:c,showLoader:i,hasError:l,resetScanState:d,showGuideCard:u,scanStage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,getButtonText:w,isScanning:v,startScan:x,isModelLoaded:I,isLandscape:k,onRetry:M}=s(F),C=f();return r?e(K,{onRetry:M}):c?e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}):t(a,{children:[e("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),k&&!i&&!l&&e("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e(_,{variant:"portrait",config:C})}),i&&!l&&e("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:C?.style?.base?.backgroundColor},children:e(N,{url:C?.loader,loaderType:"black"})}),e("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:C?.style?.base?.backgroundColor},children:e("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:t("div",{className:"w-full h-full",children:[e("video",{ref:n,autoPlay:!0,playsInline:!0,muted:!0,width:m.width.ideal,height:m.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)",visibility:k?"hidden":"visible"}}),e("canvas",{ref:o,width:m.width.ideal,height:m.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!i&&l&&e(K,{loading:i,onRetry:d}),u&&!l&&!i&&!k&&e(A,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e(H,{stage:h,videoLoading:g,setVideoLoading:p,videoError:y,setVideoError:S,gender:b,btnConfig:{label:w(),onClick:v?d:x,isDisabled:i||!I,icon:e(v?B:a,{})}})})]})},Q=t=>{const{onScanSuccess:a,onScanError:s,onRetry:l,onScanStart:m,onCaptureComplete:h,onUploadStart:f,onUploadEnd:g,onMeasurementSocketStart:y,onMeasurementSocketClose:S,config:b,isError:w,isSuccess:v}=t,x=t.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},N=t.token??"",_=n(null),B=n(null),A=n(null),q=n([]),J=n(null),K=n(null),[H,Q]=o(!1),[Y,Z]=o(!1),[ee,te]=o(!1),[ae,ne]=o(!0),[oe,re]=o(!1),[ce,ie]=o(!1),[se,le]=o(!1),[de,ue]=o(I()),me=r(()=>k(N),[N]),{isLandscape:he}=M(),{email:fe,gender:ge,deviceFocalLength:pe,shopDomain:ye,callbackUrl:Se,bodyScanId:be}=x,[we,ve]=o([]),[xe,Fe]=o(C),Ne=r(()=>D(),[]),_e=E(we),Ie=P(_e);T();const ke=c(()=>{console.log("Stopping recording..."),A.current&&"recording"===A.current.state&&A.current.stop(),A.current=null},[]),Me=async()=>{if(h?.(),q.current){if(0===q.current.length)return console.error("No video data recorded"),le(!0),void Q(!1);f?.(),Q(!0);const e=new File(q.current,`${de}.${Ie}`,{type:_e}),t=K.current??await O(e),a=e.size,n=(a/1048576).toFixed(2),o=Math.round(a/1e4),r={video_size_mb:parseFloat(n),video_size_bytes:a,video_fps:t||0,blob_count:q.current.length,estimated_duration_seconds:o},c=[{gender:ge},{face_scan_id:de},{focal_length:`${pe}`},{customer_store_url:ye},{scan_type:"face_scan"},{body_scan_id:be}];Se&&c.push({callback_url:Se}),W({eventName:`${ye}/face_scan_meta_data`,faceScanId:de,email:fe,data:JSON.stringify({metaData:c,videoData:r})});const i=Date.now();W({eventName:`${ye}/face_scan_upload_start`,faceScanId:de,email:fe,startTime:i});try{const t=await me.fileUpload.faceScanFileUploader({file:e,arrayMetaData:c,objectKey:de,email:fe,contentType:e.type}),a=Date.now();W({eventName:`${ye}/face_scan_upload_complete`,faceScanId:de,email:fe,completionTime:a,uploadDuration:a-i}),g?.(),console.log("✅ Upload successful",t),me.measurement.handlFaceScaneSocket({onPreopen:()=>{y?.(),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"pre_open",type:"faceScan_recommendation",email:fe})},faceScanId:de,onOpen:()=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"open",type:"faceScan_recommendation",email:fe}),console.log("websocket connect open")},onError:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"error",type:"faceScan_recommendation",email:fe}),Ve(e)},onSuccess:e=>{U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"success",type:"faceScan_recommendation",email:fe}),Oe(e)},onClose:()=>{S?.(),console.log("websocket connect close"),U({eventName:`${ye}/webSocket`,faceScanID:de,connection:"close",type:"faceScan_recommendation",email:fe})}})}catch(e){g?.(),Ve(e)}}},Ce=c(()=>{const e=_.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),r=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const c=document.createElement("video");c.srcObject=e,c.muted=!0,c.playsInline=!0,c.play();const i=()=>{a>n?(r?.save(),r?.translate(o.width,0),r?.rotate(Math.PI/2),r?.drawImage(c,0,0,n,a),r?.restore()):r?.drawImage(c,0,0,a,n),requestAnimationFrame(i)};i();const s=t.frameRate??10;K.current=s;const l=o.captureStream(s),d={videoBitsPerSecond:15e5};let u;we.length>0&&(d.mimeType=we[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),le(!0),void Q(!1)}q.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&q.current&&q.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",q?.current?.length),Me()},u.start(100),A.current=u,console.log("Recording started successfully (portrait normalized)")},[we,Me]),{faceScanDetector:De,scanStage:Ee,setScanStage:Pe,resetScan:Te,isModelLoaded:ze,startScanSequence:Re}=G({faceScanId:de,shopDomain:ye,isError:w,isSuccess:v,onScanComplete:()=>{ke()},onModelReady:()=>{Z(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),Ce()}}),Le=c(()=>{ze&&(m?.(),Pe(0),d.playAudio(`${u}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{te(!0),setTimeout(()=>{Re()},200)},200))},[Pe,te,Re,ze,m]),$e=c(()=>{te(!1),ne(!0),ke(),Te(),l?.(),q.current=[],K.current=null,A.current&&(A.current=null),le(!1),Pe(-1),ue(I()),_.current&&J.current&&(_.current.srcObject=J.current,console.log("Camera stream restored after reset"))},[Pe,te,ne,ke,Te,ue]),je=n(!1);i(()=>{!he||je.current||H||w||v||se||(d.stopAudio(),A.current&&(A.current.onstop=null,"recording"===A.current.state&&A.current.stop(),A.current=null),q.current=[],K.current=null,$e()),je.current=he},[he,H,w,v,se,$e]);const Ve=e=>{console.log(e,"ws error"),s?.(e),le(!0),Q(!1),ne(!1),W({eventName:`${ye}/faceScan`,faceScanId:de,status:"failed",email:fe,data:JSON.stringify(e)})},Oe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&W({eventName:`${ye}/faceScan_success/intermediate`,faceScanId:de,status:"success",email:fe,data:JSON.stringify(e)}),a?.(e)};i(()=>{if(!w&&!v)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:xe}).then(e=>{J.current=e,_.current&&(_.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),xe!==C?le(!0):Fe(z)}),()=>{J.current&&J.current.getTracks().forEach(e=>e.stop())}},[w,v,xe]),i(()=>{if(!Y||!ee)return;const e=setInterval(()=>{De(_,B)},500);return()=>clearInterval(e)},[De,Y,ee]);return console.log("Model ready:",Y,"Has error:",se,"Is scanning:",ee,"showLoader",H),i(()=>{const e=R(Ne,L);ve(e)},[Ne]),i(()=>{Pe(-1)},[]),e($,{children:e(j,{config:b,children:e(F.Provider,{value:{isError:w,isSuccess:v,showLoader:H,hasError:se,resetScanState:$e,showGuideCard:ae,scanStage:Ee,videoLoading:oe,setVideoLoading:re,videoError:ce,setVideoError:ie,gender:ge,getButtonText:()=>ee?p.reset:ze?p.start:p.loading,isScanning:ee,startScan:Le,isModelLoaded:ze,isLandscape:he,onRetry:l},children:e(V,{children:e(X,{webcamRef:_,canvasRef:B})})})})})};export{Q as F};
|
|
2
|
+
//# sourceMappingURL=FaceScan-dV6X6vuh.js.map
|
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
"use strict";var e=require("react/jsx-runtime"),t=require("react"),a=require("./Modal-B_UR_mwU.js"),n=require("lucide-react"),o=require("@mui/material");let s=null,r=!1;function i({faceScanId:e,onValidPose:n,onScanComplete:o,onModelReady:i,onStartRecording:c,shopDomain:l,isError:d,isSuccess:u}){const f=t.useRef(null),[h,g]=t.useState(0),[m,p]=t.useState(0),[y,S]=t.useState(!1),[x,v]=t.useState(!1),b=t.useRef(null),w=t.useRef(h),C=t.useRef(m),F=t.useRef([]),j=t.useRef(""),_=t.useRef(0),N=t.useRef(!1),E=t.useRef(0),k="undefined"!=typeof navigator&&(/iPad|iPhone|iPod/.test(navigator.userAgent)||"MacIntel"===navigator.platform&&navigator.maxTouchPoints>1),T=t.useMemo(()=>["Face front","Turn head fully left","Turn head fully right","Smile facing front"],[]),I=t.useMemo(()=>function(e,t){let a;return(...n)=>{a&&clearTimeout(a),a=setTimeout(()=>e(...n),t)}}(e=>{a.posthog.capture(`${l}/face_scan_pose_detection`,e)},4e3),[l]),R=t.useCallback((t,a,n,o,s,r)=>{const i=Date.now();if(!(i-E.current<4e3)){E.current=i;try{const i=t[0]||[0,0,0],c=t[2]||[0,0,0],l=t[5]||[0,0,0],d=t[9]||[0,0,0],u=t[10]||[0,0,0],f=t.map(e=>e[2]).filter(e=>e>0),h=f.length>0?f.reduce((e,t)=>e+t,0)/f.length:0,g=a.map(e=>e[2]).filter(e=>e>0),m=g.length>0?g.reduce((e,t)=>e+t,0)/g.length:0,p=Math.abs(c[0]-l[0]),y=i[0]-l[0],S=c[0]-i[0];let x="frontal";1===n?x="left":2===n?x="right":3===n&&(x="frontal_smile");const v={faceScanId:e,stage:n,timestamp:(new Date).toISOString(),data:JSON.stringify({headValid:o,bodyInvalid:s,consecutiveValid:r,avgFaceScore:parseFloat(h.toFixed(3)),avgBodyScore:parseFloat(m.toFixed(3)),faceKeypointsDetected:f.length,bodyKeypointsDetected:g.length,eyeDistance:parseFloat(p.toFixed(2)),noseToRightRatio:parseFloat((y/p).toFixed(3)),noseToLeftRatio:parseFloat((S/p).toFixed(3)),noseScore:parseFloat(i[2].toFixed(3)),leftEyeScore:parseFloat(c[2].toFixed(3)),rightEyeScore:parseFloat(l[2].toFixed(3)),leftMouthScore:parseFloat(d[2].toFixed(3)),rightMouthScore:parseFloat(u[2].toFixed(3)),expectedPosition:x})};I(v)}catch(e){console.warn("Failed to track pose detection:",e)}}},[e,I]),M=()=>{a.posthog.capture(`${l}/face_scan_detection_started`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current]}),setTimeout(()=>{v(!0)},1500)},P=async()=>{if("undefined"!=typeof window)try{console.log("Initializing Face Scan...");const e=await(async()=>{if("undefined"==typeof window)return null;if(s)return s;if(r)for(;r;)if(await new Promise(e=>setTimeout(e,100)),s)return s;r=!0;try{const[e,t]=await Promise.all([import("@tensorflow/tfjs"),Promise.resolve().then(function(){return require("./pose-detection.esm-2mkM0o4k.js")})]);await e.setBackend("webgl"),await e.ready();const n=await t.createDetector(t.SupportedModels.BlazePose,{runtime:"tfjs",modelType:"full"}),o=document.createElement("canvas");o.width="number"==typeof a.videoConstraints.width?a.videoConstraints.width:a.videoConstraints.width.ideal??a.videoConstraints.width.max??1280,o.height="number"==typeof a.videoConstraints.height?a.videoConstraints.height:a.videoConstraints.height.ideal??a.videoConstraints.height.max??720;const r=o.getContext("2d");if(r){r.fillStyle="black",r.fillRect(0,0,o.width,o.height);try{await n.estimatePoses(o)}catch(e){console.warn("Warmup frame failed (non-fatal):",e)}}return s=n,n}catch(e){return console.error("Failed to preload detector:",e),null}finally{r=!1}})();e&&(f.current=e,console.log("Face scan model loaded successfully"),S(!0),i?.())}catch(e){console.error("Error initializing face scan:",e)}};return t.useEffect(()=>{if(!d&&!u)return P(),()=>{(async()=>{try{S(!1)}catch(e){console.error("Error disposing resources:",e)}finally{g(0),p(0),w.current=0,C.current=0,F.current=[]}})()}},[d,u]),t.useEffect(()=>{w.current=h},[h]),t.useEffect(()=>{C.current=m},[m]),{faceScanDetector:async(t,s)=>{if(f.current&&t.current&&y&&x&&!(t.current.readyState<2))try{const r=await f.current.estimatePoses(t.current);if(r.length>0){const t=[],i=[];if(r[0].keypoints.forEach((e,a)=>{const n=e.score??0,o=[e.x??-1,e.y??-1,n];a<=10?t.push(o):i.push(o)}),s?.current){const e=s.current.getContext("2d"),{width:t,height:a}=s.current;if(e){e.clearRect(0,0,t,a);const n=Math.min(C.current/2,1),o=.35*a;e.beginPath(),e.strokeStyle="#00ff00",e.lineWidth=6,e.arc(t/2,a/2,o+10,-Math.PI/2,-Math.PI/2+2*n*Math.PI),e.stroke()}}const d=((e,t)=>{if(!t[0]||!t[2]||!t[5]||t[0][2]<.2||t[2][2]<.2||t[5][2]<.2)return!1;const a=.5*(t[10][1]+t[9][1])-.5*(t[5][1]+t[2][1]),n=(.5*(t[10][1]+t[9][1])-t[0][1])/a,o=n>.7||n<.3,s=Math.abs(t[2][1]-t[5][1])<.5*a&&Math.abs(t[9][1]-t[10][1])<.5*a,r=t[2][0]-t[5][0],i=t[0][0]-t[5][0],c=i>.4*r&&i<.6*r,l=i>.85*r,d=t[2][0]-t[0][0]>.85*r;switch(e){case 0:case 3:return!o&&s&&c;case 1:return!o&&s&&l;case 2:return!o&&s&&d;default:return!1}})(w.current,t),u=i.slice(2).filter(e=>e[2]>.7).length<=2;F.current.push(d&&u),F.current.length>10&&F.current.shift();if(F.current.filter(Boolean).length>=2){const e=C.current+1;p(e)}else p(Math.max(0,C.current-1));if(C.current>=2){n?.();const t=w.current+1;p(0),F.current=[],g(t),v(!1),(async()=>{if(await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Sound-effect.mp3`),a.posthog.capture(`${l}/face_scan_detection_stage_completed`,{faceScanId:e,completedStage:w.current,nextStage:t,timestamp:(new Date).toISOString(),totalStages:4,stageName:T[w.current]}),1===t&&c&&c(),t>=4)o?.();else{let e=null;switch(t){case 1:e="Left.mp3";break;case 2:e="Right.mp3";break;case 3:e="Smile.mp3"}e&&await a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/${e}`),M()}})()}R(t,i,w.current,d,u,C.current)}}catch(e){console.error("Pose detection error:",e)}},scanStage:h,setScanStage:g,consecutiveValid:m,isModelLoaded:y,resetScan:()=>{a.posthog.capture(`${l}/face_scan_reset`,{faceScanId:e,stage:w.current,timestamp:(new Date).toISOString(),stageName:T[w.current],consecutiveValid:C.current}),g(0),p(0),v(!1),w.current=0,C.current=0,F.current=[],j.current="",_.current=0,N.current=!1,b.current&&(speechSynthesis.cancel(),b.current=null)},enableVoiceCommands:()=>{if(N.current=!0,"undefined"!=typeof window&&k&&"speechSynthesis"in window){const e=new SpeechSynthesisUtterance("");e.volume=0,speechSynthesis.speak(e)}},startScanSequence:M,isScanningActive:x}}function c({onRetry:o,loading:s}){const{translate:r}=t.useContext(a.LanguageContext)||{},i=a.useConfig();return e.jsx("div",{className:"fixed common-ui-main top-[0] left-[0] z-[999] flex justify-center items-center w-full h-full",style:{background:i?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"flex flex-col w-full items-center p-[1rem] rounded-lg ",children:[e.jsx(a.Header,{noTitle:!0}),e.jsxs("div",{className:"flex flex-col items-center w-full",children:[e.jsx("h2",{className:"text-xl my-[0] font-semibold text-gray-800 ",style:{fontFamily:i?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:i?.style?.heading?.headingFontSize||"32px",color:i?.style?.heading?.headingColor||"#000",fontWeight:i?.style?.heading?.headingFontWeight||"normal"},children:r?.(a.LanguageKeys.scanFailed)}),e.jsx("p",{className:"mb-[1.5rem]",style:{fontFamily:i?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:i?.style?.subheading?.subheadingFontSize||"14px",color:i?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:i?.style?.subheading?.subheadingFontWeight||"normal"},children:r?.(a.LanguageKeys.clickToResetScan)}),e.jsx(a.SpecificButton,{disabled:s,className:"w-full h-[45px] shadow-[0px_1px_2px_0px_#00000040] text-[16px]",buttonText:r?.(a.LanguageKeys.resetScan),postfixIcon:e.jsx(n.ArrowRight,{}),buttonFunc:()=>o?.()})]})]})})}function l({stage:n,videoLoading:o,setVideoLoading:s,videoError:r,setVideoError:i,gender:c,btnConfig:l}){const{translate:d}=t.useContext(a.LanguageContext)||{},u=a.useConfig();return-1===n?e.jsxs("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:[e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h2",{className:"my-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.LanguageKeys.faceVisible)}),o&&e.jsx("div",{className:"mb-4 flex items-center justify-center",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:u?.style?.subheading?.subheadingColor||"#4b5563",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.loadingVideo)}),r&&e.jsx("div",{className:"mb-4 text-red-600",style:{fontFamily:u?.style?.subheading?.subheadingFontFamily||"'Inter', sans-serif",fontSize:u?.style?.subheading?.subheadingFontSize||"14px",color:"#ff0000",fontWeight:u?.style?.subheading?.subheadingFontWeight||"normal"},children:d?.(a.LanguageKeys.videoLoadFailed)}),!r&&e.jsx("div",{className:" w-[100px] mx-auto",children:e.jsx("video",{src:c===a.GenderType.Male?a.maleGlassesOffVideo:a.glassesOffVideo,autoPlay:!0,loop:!0,controls:!1,muted:!0,playsInline:!0,className:"h-full w-full object-contain border-none",onCanPlay:()=>s(!1),onLoadStart:()=>s(!0),onError:()=>i(!0),"aria-label":"Instructional video: Please remove your glasses before starting the scan."})})]}),e.jsx("div",{className:"flex justify-center w-full p-[1rem]",children:e.jsx(a.SpecificButton,{disabled:l.isDisabled,className:"!w-[60px] !h-[35px] !py-0 !px-0",buttonText:d?.(l.label),postfixIcon:l?.icon,buttonFunc:l.onClick})})]}):e.jsx("div",{className:"text-center common-ui-main p-[16px] w-full h-full",style:{background:u?.style?.base?.backgroundColor},children:e.jsxs("div",{className:"w-full",children:[e.jsx(a.Header,{noTitle:!0}),e.jsx("h3",{className:"mb-[0.5rem] mt-[0]",style:{fontFamily:u?.style?.heading?.headingFontFamily||"SeriouslyNostalgic Fn",fontSize:u?.style?.heading?.headingFontSize||"32px",color:u?.style?.heading?.headingColor||"#000",fontWeight:u?.style?.heading?.headingFontWeight||"normal"},children:d?.(a.directionMessages[n])}),e.jsxs("div",{className:"max-w-[400px] justify-center gap-1 mx-auto flex items-center",children:[e.jsx("div",{className:` w-[120px] overflow-hidden ${0===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:c===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.forward:a.FACE_SCAN_HEADSHOT.female.forward,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${1===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:c===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.left:a.FACE_SCAN_HEADSHOT.female.left,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${2===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:c===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.right:a.FACE_SCAN_HEADSHOT.female.right,type:"video/mp4"})})}),e.jsx("div",{className:` w-[120px] overflow-hidden ${3===n?"opacity-100":"opacity-0 hidden"} `,children:e.jsx("video",{className:"h-full w-full object-contain border-none",muted:!0,loop:!0,autoPlay:!0,playsInline:!0,children:e.jsx("source",{src:c===a.GenderType.Male?a.FACE_SCAN_HEADSHOT.male.smile:a.FACE_SCAN_HEADSHOT.female.smile,type:"video/mp4"})})})]})]})})}const d=({webcamRef:s,canvasRef:r})=>{const{isError:i,isSuccess:d,showLoader:u,hasError:f,resetScanState:h,showGuideCard:g,scanStage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,getButtonText:b,isScanning:w,startScan:C,isModelLoaded:F,isLandscape:j,onRetry:_}=t.useContext(a.ParamsContext),N=a.useConfig();return i?e.jsx(c,{onRetry:_}):d?e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}):e.jsxs(e.Fragment,{children:[e.jsx("audio",{id:"audioElement",crossOrigin:"anonymous",preload:"auto",style:{position:"absolute",zIndex:-99999},src:void 0}),j&&!u&&!f&&e.jsx("div",{className:"fixed inset-0 z-[9999] common-ui-main",style:{background:"#fff"},children:e.jsx(a.Modal,{variant:"portrait",config:N})}),u&&!f&&e.jsx("div",{className:"fixed z-[9] common-ui-main w-full h-full",style:{background:N?.style?.base?.backgroundColor},children:e.jsx(a.LoadingScreen,{url:N?.loader,loaderType:"black"})}),e.jsx("div",{className:"h-full flex-col common-ui-main relative w-full flex justify-center items-center text-center rounded-t-[20px]",style:{background:N?.style?.base?.backgroundColor},children:e.jsx("div",{className:"flex-1 w-full max-w-md overflow-hidden",children:e.jsxs("div",{className:"w-full h-full",children:[e.jsx("video",{ref:s,autoPlay:!0,playsInline:!0,muted:!0,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,className:"w-full h-full object-cover fixed left-0 top-0 z-0",style:{transform:"scaleX(-1)",visibility:j?"hidden":"visible"}}),e.jsx("canvas",{ref:r,width:a.videoConstraints.width.ideal,height:a.videoConstraints.height.ideal,style:{transform:"scaleX(-1)",opacity:"0"}})]})})}),!u&&f&&e.jsx(c,{loading:u,onRetry:h}),g&&!f&&!u&&!j&&e.jsx(o.Drawer,{open:!0,className:"face-scan-small camera-draw",anchor:"bottom",onClose:(e,t)=>{},disablePortal:!0,hideBackdrop:!0,children:e.jsx(l,{stage:m,videoLoading:p,setVideoLoading:y,videoError:S,setVideoError:x,gender:v,btnConfig:{label:b(),onClick:w?h:C,isDisabled:u||!F,icon:w?e.jsx(n.ArrowRight,{}):e.jsx(e.Fragment,{})}})})]})};exports.FaceScan=n=>{const{onScanSuccess:o,onScanError:s,onRetry:r,onScanStart:c,onCaptureComplete:l,onUploadStart:u,onUploadEnd:f,onMeasurementSocketStart:h,onMeasurementSocketClose:g,config:m,isError:p,isSuccess:y}=n,S=n.userDetails??{email:"",gender:"male",deviceFocalLength:0,shopDomain:"",bodyScanId:""},x=n.token??"",v=t.useRef(null),b=t.useRef(null),w=t.useRef(null),C=t.useRef([]),F=t.useRef(null),j=t.useRef(null),[_,N]=t.useState(!1),[E,k]=t.useState(!1),[T,I]=t.useState(!1),[R,M]=t.useState(!0),[P,D]=t.useState(!1),[L,A]=t.useState(!1),[O,z]=t.useState(!1),[$,H]=t.useState(a.generateUuid()),V=t.useMemo(()=>a.getSwanService(x),[x]),{isLandscape:W}=a.usePortraitLock(),{email:K,gender:U,deviceFocalLength:B,shopDomain:q,callbackUrl:G,bodyScanId:J}=S,[X,Q]=t.useState([]),[Y,Z]=t.useState(a.videoConstraintsExact),ee=t.useMemo(()=>a.getPreferredMediaRecorderTypes(),[]),te=a.getRecordingMimeType(X),ae=a.getRecordingExtension(te);a.usePosthogPageview();const ne=t.useCallback(()=>{console.log("Stopping recording..."),w.current&&"recording"===w.current.state&&w.current.stop(),w.current=null},[]),oe=async()=>{if(l?.(),C.current){if(0===C.current.length)return console.error("No video data recorded"),z(!0),void N(!1);u?.(),N(!0);const e=new File(C.current,`${$}.${ae}`,{type:te}),t=j.current??await a.getVideoFPS(e),n=e.size,o=(n/1048576).toFixed(2),s=Math.round(n/1e4),r={video_size_mb:parseFloat(o),video_size_bytes:n,video_fps:t||0,blob_count:C.current.length,estimated_duration_seconds:s},i=[{gender:U},{face_scan_id:$},{focal_length:`${B}`},{customer_store_url:q},{scan_type:"face_scan"},{body_scan_id:J}];G&&i.push({callback_url:G}),a.handleScanTimeCapture({eventName:`${q}/face_scan_meta_data`,faceScanId:$,email:K,data:JSON.stringify({metaData:i,videoData:r})});const c=Date.now();a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_start`,faceScanId:$,email:K,startTime:c});try{const t=await V.fileUpload.faceScanFileUploader({file:e,arrayMetaData:i,objectKey:$,email:K,contentType:e.type}),n=Date.now(),o=n-c;a.handleScanTimeCapture({eventName:`${q}/face_scan_upload_complete`,faceScanId:$,email:K,completionTime:n,uploadDuration:o}),f?.(),console.log("✅ Upload successful",t),V.measurement.handlFaceScaneSocket({onPreopen:()=>{h?.(),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"pre_open",type:"faceScan_recommendation",email:K})},faceScanId:$,onOpen:()=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"open",type:"faceScan_recommendation",email:K}),console.log("websocket connect open")},onError:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"error",type:"faceScan_recommendation",email:K}),me(e)},onSuccess:e=>{a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"success",type:"faceScan_recommendation",email:K}),pe(e)},onClose:()=>{g?.(),console.log("websocket connect close"),a.handleWebSocketCapture({eventName:`${q}/webSocket`,faceScanID:$,connection:"close",type:"faceScan_recommendation",email:K})}})}catch(e){f?.(),me(e)}}},se=t.useCallback(()=>{const e=v.current?.srcObject;if(!e)return;const t=e.getVideoTracks()[0].getSettings(),{width:a=1280,height:n=720}=t,o=document.createElement("canvas"),s=o.getContext("2d");a>n?(o.width=n,o.height=a):(o.width=a,o.height=n);const r=document.createElement("video");r.srcObject=e,r.muted=!0,r.playsInline=!0,r.play();const i=()=>{a>n?(s?.save(),s?.translate(o.width,0),s?.rotate(Math.PI/2),s?.drawImage(r,0,0,n,a),s?.restore()):s?.drawImage(r,0,0,a,n),requestAnimationFrame(i)};i();const c=t.frameRate??10;j.current=c;const l=o.captureStream(c),d={videoBitsPerSecond:15e5};let u;X.length>0&&(d.mimeType=X[0]);try{u=new MediaRecorder(l,d)}catch(e){return console.error("MediaRecorder init failed:",e),z(!0),void N(!1)}C.current=[],u.ondataavailable=e=>{e?.data&&e.data.size>0&&C.current&&C.current.push(e.data)},u.onstop=()=>{console.log("Recording stopped, total blobs:",C?.current?.length),oe()},u.start(100),w.current=u,console.log("Recording started successfully (portrait normalized)")},[X,oe]),{faceScanDetector:re,scanStage:ie,setScanStage:ce,resetScan:le,isModelLoaded:de,startScanSequence:ue}=i({faceScanId:$,shopDomain:q,isError:p,isSuccess:y,onScanComplete:()=>{ne()},onModelReady:()=>{k(!0)},onStartRecording:()=>{console.log("Stage 0 completed - starting recording for stages 1-3"),se()}}),fe=t.useCallback(()=>{de&&(c?.(),ce(0),a.speechService.playAudio(`${a.voiceOverAssetsPath}face-scan-vos/Face-forward.mp3`),setTimeout(()=>{I(!0),setTimeout(()=>{ue()},200)},200))},[ce,I,ue,de,c]),he=t.useCallback(()=>{I(!1),M(!0),ne(),le(),r?.(),C.current=[],j.current=null,w.current&&(w.current=null),z(!1),ce(-1),H(a.generateUuid()),v.current&&F.current&&(v.current.srcObject=F.current,console.log("Camera stream restored after reset"))},[ce,I,M,ne,le,H]),ge=t.useRef(!1);t.useEffect(()=>{!W||ge.current||_||p||y||O||(a.speechService.stopAudio(),he()),ge.current=W},[W,_,p,y,O,he]);const me=e=>{console.log(e,"ws error"),s?.(e),z(!0),N(!1),M(!1),a.handleScanTimeCapture({eventName:`${q}/faceScan`,faceScanId:$,status:"failed",email:K,data:JSON.stringify(e)})},pe=e=>{console.log(e,"ws success"),e&&"intermediate"===e?.resultType&&a.handleScanTimeCapture({eventName:`${q}/faceScan_success/intermediate`,faceScanId:$,status:"success",email:K,data:JSON.stringify(e)}),o?.(e)};t.useEffect(()=>{if(!p&&!y)return navigator.mediaDevices.getUserMedia&&navigator.mediaDevices.getUserMedia({video:Y}).then(e=>{F.current=e,v.current&&(v.current.srcObject=e)}).catch(e=>{console.error("Error accessing webcam:",e),Y!==a.videoConstraintsExact?z(!0):Z(a.videoConstraintsFallback)}),()=>{F.current&&F.current.getTracks().forEach(e=>e.stop())}},[p,y,Y]),t.useEffect(()=>{if(!E||!T)return;const e=setInterval(()=>{re(v,b)},500);return()=>clearInterval(e)},[re,E,T]);return console.log("Model ready:",E,"Has error:",O,"Is scanning:",T,"showLoader",_),t.useEffect(()=>{const e=a.getSupportedMediaRecorderTypes(ee,a.videoTypes);Q(e)},[ee]),t.useEffect(()=>{ce(-1)},[]),e.jsx(a.LanguageContextProvider,{children:e.jsx(a.ConfigProvider,{config:m,children:e.jsx(a.ParamsContext.Provider,{value:{isError:p,isSuccess:y,showLoader:_,hasError:O,resetScanState:he,showGuideCard:R,scanStage:ie,videoLoading:P,setVideoLoading:D,videoError:L,setVideoError:A,gender:U,getButtonText:()=>T?a.LanguageKeys.reset:de?a.LanguageKeys.start:a.LanguageKeys.loading,isScanning:T,startScan:fe,isModelLoaded:de,isLandscape:W,onRetry:r},children:e.jsx(a.ShadowRoot,{children:e.jsx(d,{webcamRef:v,canvasRef:b})})})})})};
|
|
2
|
+
//# sourceMappingURL=FaceScan-mBiHNeqn.js.map
|
package/dist/faceScan.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
"use strict";var e=require("./FaceScan-
|
|
1
|
+
"use strict";var e=require("./FaceScan-CLnu4dJd.js");require("react/jsx-runtime"),require("react"),require("./Modal-B_UR_mwU.js"),require("react-dom"),require("@emotion/react"),require("@emotion/cache"),require("@swan-admin/swan-ai-measurements"),require("@mui/material"),require("tailwind-merge"),require("clsx"),require("posthog-js"),require("mic-check"),require("uuid"),require("lucide-react"),exports.FaceScan=e.FaceScan;
|
|
2
2
|
//# sourceMappingURL=faceScan.js.map
|
package/dist/faceScan.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export{F as FaceScan}from"./FaceScan-
|
|
1
|
+
export{F as FaceScan}from"./FaceScan-dV6X6vuh.js";import"react/jsx-runtime";import"react";import"./Modal-6Y88Up1w.js";import"react-dom";import"@emotion/react";import"@emotion/cache";import"@swan-admin/swan-ai-measurements";import"@mui/material";import"tailwind-merge";import"clsx";import"posthog-js";import"mic-check";import"uuid";import"lucide-react";
|
|
2
2
|
//# sourceMappingURL=faceScan.mjs.map
|