@incodetech/core 2.2.0-rc.8 → 2.3.0-rc.0

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.
Files changed (258) hide show
  1. package/THIRD_PARTY_NOTICES.txt +281 -0
  2. package/dist/BaseWasmProvider-Dyi6dKp1.d.ts +65 -0
  3. package/dist/{BrowserDiagnosticsCryptoProvider-DslcXorZ.esm.js → BrowserDiagnosticsCryptoProvider-C_9o3L2L.esm.js} +1 -1
  4. package/dist/{BrowserVisibilityObserverProvider-BX1BiLDK.esm.js → BrowserVisibilityObserverProvider-BrJN1B8A.esm.js} +2 -0
  5. package/dist/FaceDetectionProvider-DTetAE8H.esm.js +476 -0
  6. package/dist/FaceDetectionProvider-LdZ47bWy.d.ts +36 -0
  7. package/dist/{IIdCaptureCapability-DHTT3FC2.d.ts → IIdCaptureCapability-RNiFhvXR.d.ts} +7 -33
  8. package/dist/IWasmUtilCapability-CXXDA5l1.d.ts +159 -0
  9. package/dist/{MotionSensorProvider-DGiV77J_.esm.js → MotionSensorProvider-BgTYwg9L.esm.js} +1 -1
  10. package/dist/{deepsightService-DLVQS_RH.d.ts → StreamCanvasCapture-B3YT2Bt6.d.ts} +54 -41
  11. package/dist/{StreamCanvasCapture-D2XcXCZ4.esm.js → StreamCanvasCapture-C9jtgBdT.esm.js} +2 -2
  12. package/dist/{addressSearch-D1XpBdUS.esm.js → addressSearch-BRSu_aGA.esm.js} +1 -1
  13. package/dist/advanceableErrors-CpF2cBy6.esm.js +21 -0
  14. package/dist/ae-signature.d.ts +4 -2
  15. package/dist/ae-signature.esm.js +1 -1
  16. package/dist/antifraud.esm.js +2 -2
  17. package/dist/{antifraudManager-CQFNgSPt.esm.js → antifraudManager-Bg9ynGum.esm.js} +2 -2
  18. package/dist/{antifraudStateMachine-Bf_JVNwn.esm.js → antifraudStateMachine-BHxehiJZ.esm.js} +1 -1
  19. package/dist/{apiError-D4rZe9BR.esm.js → apiError-D0v5hFyN.esm.js} +14 -2
  20. package/dist/authentication.d.ts +3 -3
  21. package/dist/authentication.esm.js +2 -2
  22. package/dist/{authenticationManager-EfCuQy_Y.esm.js → authenticationManager-C4B4-29g.esm.js} +5 -5
  23. package/dist/{authenticationManager-BBMGTcwW.d.ts → authenticationManager-DXTIUcma.d.ts} +7 -1
  24. package/dist/{authenticationStateMachine-B9l3sHEg.esm.js → authenticationStateMachine-DJ0zUm-A.esm.js} +6 -62
  25. package/dist/avatar.d.ts +1 -2
  26. package/dist/avatar.esm.js +1 -1
  27. package/dist/{backCameraStream-CUeYm5eu.esm.js → backCameraStream-BOtyQowf.esm.js} +83 -22
  28. package/dist/{camera-_2sXMXiF.esm.js → camera-sIa9ceW2.esm.js} +19 -1
  29. package/dist/camera.esm.js +1 -1
  30. package/dist/{canvas-E1zGkel4.esm.js → canvas-BxFzWTt-.esm.js} +19 -0
  31. package/dist/certificate-issuance.d.ts +2 -302
  32. package/dist/certificate-issuance.esm.js +3 -66
  33. package/dist/certificateIssuanceManager-Bfvkq7Cy.esm.js +69 -0
  34. package/dist/certificateIssuanceManager-DCgEidHz.d.ts +312 -0
  35. package/dist/{certificateIssuanceStateMachine-D_R92TYu.esm.js → certificateIssuanceStateMachine-BBD5h8c4.esm.js} +1 -1
  36. package/dist/consent.d.ts +1 -1
  37. package/dist/consent.esm.js +2 -2
  38. package/dist/{consentManager-BxjpLZAG.esm.js → consentManager-B5Vqdez-.esm.js} +2 -2
  39. package/dist/{consentManager-3Pbtj-RV.d.ts → consentManager-uhDPdU6i.d.ts} +4 -4
  40. package/dist/{consentStateMachine-D9D4ON8Z.esm.js → consentStateMachine-DbUmqWgV.esm.js} +1 -1
  41. package/dist/createCameraCycleOwnership-DQ5-F2oW.esm.js +826 -0
  42. package/dist/{createFaceAvatar-DQKaRise.esm.js → createFaceAvatar-BNHdeFj8.esm.js} +2 -2
  43. package/dist/createFaceAvatar-BlcTYgJv.d.ts +497 -0
  44. package/dist/cross-document-data-match.esm.js +1 -1
  45. package/dist/{crossDocumentDataMatchManager-CGT0V6RV.esm.js → crossDocumentDataMatchManager-QMOGwHXR.esm.js} +2 -2
  46. package/dist/curp-validation.d.ts +1 -1
  47. package/dist/curp-validation.esm.js +2 -2
  48. package/dist/{curpValidationManager-6Nmkn5u1.esm.js → curpValidationManager-D1ppROcF.esm.js} +2 -2
  49. package/dist/{curpValidationManager-DVGr7Fq7.d.ts → curpValidationManager-SSKNrm5Z.d.ts} +1 -1
  50. package/dist/{curpValidationStateMachine-Ds7KMacK.esm.js → curpValidationStateMachine-DvUPC_8S.esm.js} +1 -1
  51. package/dist/custom-fields.d.ts +2 -114
  52. package/dist/custom-fields.esm.js +2 -232
  53. package/dist/custom-watchlist.d.ts +2 -51
  54. package/dist/custom-watchlist.esm.js +3 -70
  55. package/dist/customFieldsManager-2j_PBq4U.esm.js +264 -0
  56. package/dist/customFieldsManager-8-W2KY4n.d.ts +141 -0
  57. package/dist/customWatchlistManager-DUVrEdw9.esm.js +73 -0
  58. package/dist/customWatchlistManager-PBWHr_oM.d.ts +64 -0
  59. package/dist/{customWatchlistStateMachine-YWSgKLbF.esm.js → customWatchlistStateMachine-qZVgkKgP.esm.js} +1 -1
  60. package/dist/{deepsightLoader-DEcRUKfT.esm.js → deepsightLoader-Dm7ejW4v.esm.js} +27 -71
  61. package/dist/device.d.ts +25 -2
  62. package/dist/device.esm.js +69 -7
  63. package/dist/document-capture.d.ts +2 -2
  64. package/dist/document-capture.esm.js +2 -2
  65. package/dist/{documentCaptureManager-DsQQhWry.esm.js → documentCaptureManager-DR_Wv-3H.esm.js} +2 -2
  66. package/dist/{documentCaptureManager-B3t0ydtg.d.ts → documentCaptureManager-DensIj5F.d.ts} +83 -83
  67. package/dist/{documentCaptureStateMachine-BM4Ex_5x.esm.js → documentCaptureStateMachine-CWOATHfE.esm.js} +5 -5
  68. package/dist/dynamic-forms.d.ts +1 -1
  69. package/dist/dynamic-forms.esm.js +2 -2
  70. package/dist/{dynamicFormsManager-fhK0yINk.d.ts → dynamicFormsManager-D5R_uxLQ.d.ts} +25 -3
  71. package/dist/{dynamicFormsManager-CmvBSrzC.esm.js → dynamicFormsManager-Dt98SDfV.esm.js} +16 -5
  72. package/dist/{dynamicFormsStateMachine-C37Rtz1G.esm.js → dynamicFormsStateMachine-obKr4IIp.esm.js} +35 -3
  73. package/dist/ekyb.d.ts +1 -1
  74. package/dist/ekyb.esm.js +3 -3
  75. package/dist/{ekybManager-Bx6dG89U.esm.js → ekybManager-DNZKrKF3.esm.js} +2 -2
  76. package/dist/{ekybStateMachine-uscz9zIj.esm.js → ekybStateMachine-DjhHQXZ8.esm.js} +3 -3
  77. package/dist/ekyc.esm.js +2 -2
  78. package/dist/{ekycManager-DgT48ky6.esm.js → ekycManager-CmQBpeiI.esm.js} +2 -2
  79. package/dist/{ekycStateMachine-CQwqiR-R.esm.js → ekycStateMachine-CmdW2gVm.esm.js} +2 -2
  80. package/dist/electronic-signature.d.ts +3 -3
  81. package/dist/electronic-signature.esm.js +2 -2
  82. package/dist/electronicSignatureManager-Ds-KEVTq.d.ts +2786 -0
  83. package/dist/{electronicSignatureManager-_QiHi1U5.esm.js → electronicSignatureManager-DzulxM4_.esm.js} +357 -51
  84. package/dist/email.esm.js +2 -2
  85. package/dist/{emailManager-BY0jeYwR.esm.js → emailManager-B5ek_UfM.esm.js} +2 -2
  86. package/dist/{emailStateMachine-Crw8QVmc.esm.js → emailStateMachine-CyPFZ7dW.esm.js} +1 -1
  87. package/dist/{endpoints-CCzL3XD_.esm.js → endpoints-D3B9mUHh.esm.js} +24 -7
  88. package/dist/{events-DYiyoSlx.esm.js → events-ijlbX_Wx.esm.js} +2 -2
  89. package/dist/events.d.ts +1 -1
  90. package/dist/events.esm.js +1 -1
  91. package/dist/extensibility.d.ts +24 -64
  92. package/dist/extensibility.esm.js +35 -29
  93. package/dist/face-match.esm.js +2 -2
  94. package/dist/{faceCaptureManagerFactory-BxWPpxyd.d.ts → faceCaptureManagerFactory-CvtqcLxs.d.ts} +87 -54
  95. package/dist/{faceCaptureManagerFactory-Bkueb8mk.esm.js → faceCaptureManagerFactory-pCmG4MeF.esm.js} +68 -7
  96. package/dist/faceCaptureSetup-BSextack.esm.js +2106 -0
  97. package/dist/{faceMatchManager-Ri4UbNz0.esm.js → faceMatchManager-Caal2zyV.esm.js} +2 -2
  98. package/dist/{faceMatchStateMachine-20DdZ3jg.esm.js → faceMatchStateMachine-BUc5FXYy.esm.js} +1 -1
  99. package/dist/{feature-management-B3Uygq6K.esm.js → feature-management-B0sGlozZ.esm.js} +32 -7
  100. package/dist/feature-management.d.ts +1 -1
  101. package/dist/feature-management.esm.js +1 -1
  102. package/dist/field-comparison.esm.js +1 -1
  103. package/dist/{fieldComparisonManager-Cg6kPQQx.esm.js → fieldComparisonManager-BIs6HPJG.esm.js} +2 -2
  104. package/dist/fiscal-qr.d.ts +2 -56
  105. package/dist/fiscal-qr.esm.js +2 -308
  106. package/dist/fiscalQrManager-Bp_-3LJr.esm.js +34131 -0
  107. package/dist/fiscalQrManager-CHcBJwUM.d.ts +68 -0
  108. package/dist/flow-events.d.ts +1 -1
  109. package/dist/flow.d.ts +212 -185
  110. package/dist/flow.esm.js +119 -30
  111. package/dist/{flowCompletionService-UakxNaeg.esm.js → flowCompletionService-CLtbWhSK.esm.js} +2 -2
  112. package/dist/{flowServices-CD5m8HqZ.esm.js → flowServices-B5FwukTQ.esm.js} +91 -26
  113. package/dist/geolocation.esm.js +2 -2
  114. package/dist/{geolocationManager-Bz6wJrfI.esm.js → geolocationManager-DIw-xq9a.esm.js} +2 -2
  115. package/dist/{geolocationStateMachine-psEJIVjN.esm.js → geolocationStateMachine-DpG0TFOU.esm.js} +3 -3
  116. package/dist/getBrowser-CBiibsL-.esm.js +19 -0
  117. package/dist/{getBrowser-DNrQeL4T.esm.js → getBrowser-Cbe1C4Tn.esm.js} +2 -1
  118. package/dist/{getDeviceClass-9y-kbVDw.esm.js → getDeviceClass-5NYZg9s6.esm.js} +2 -2
  119. package/dist/getParsedUserAgent-B2iFDql1.esm.js +1278 -0
  120. package/dist/government-validation.d.ts +2 -85
  121. package/dist/government-validation.esm.js +3 -120
  122. package/dist/governmentValidationManager-D02vT4yY.d.ts +63 -0
  123. package/dist/governmentValidationManager-TjC9iVjH.esm.js +79 -0
  124. package/dist/governmentValidationStateMachine-D1ZnEqdd.esm.js +54 -0
  125. package/dist/home.d.ts +1 -1
  126. package/dist/home.esm.js +1 -1
  127. package/dist/id-ocr.d.ts +2 -2
  128. package/dist/id-ocr.esm.js +2 -2
  129. package/dist/id-selfie-flow.d.ts +3 -2
  130. package/dist/id-selfie-flow.esm.js +11 -10
  131. package/dist/id-verification.esm.js +2 -2
  132. package/dist/id.d.ts +29 -5
  133. package/dist/id.esm.js +48 -46
  134. package/dist/idCaptureDefaults-BcxjQDI3.esm.js +484 -0
  135. package/dist/{idCaptureManager-CqrqSjJV.d.ts → idCaptureManager-CvmHOWWd.d.ts} +227 -39
  136. package/dist/{idCaptureManager-BJAquKfp.esm.js → idCaptureManager-Vby8oYqh.esm.js} +259 -46
  137. package/dist/{idCaptureServices-CM6ki4IH.esm.js → idCaptureServices-CJIxD9ep.esm.js} +342 -31
  138. package/dist/idCaptureStateMachine-CmqihkUy.esm.js +5343 -0
  139. package/dist/{idOcrManager-DXc_xRN7.d.ts → idOcrManager-BF_cXZq8.d.ts} +1 -1
  140. package/dist/{idOcrManager-BIQYQXXj.esm.js → idOcrManager-DHU22hVn.esm.js} +2 -2
  141. package/dist/{idOcrStateMachine-cSxzHpHt.esm.js → idOcrStateMachine-33UvRAHE.esm.js} +1 -1
  142. package/dist/{idVerificationManager-JpV_SAsl.esm.js → idVerificationManager-CyaixD0D.esm.js} +2 -2
  143. package/dist/{idVerificationStateMachine-nPeUNyFq.esm.js → idVerificationStateMachine-BPGrQZEm.esm.js} +1 -1
  144. package/dist/identity-reuse.esm.js +2 -2
  145. package/dist/{identityReuseManager-kNCg9AbD.esm.js → identityReuseManager-CWaNHBO3.esm.js} +2 -2
  146. package/dist/{identityReuseStateMachine-DyulxDjP.esm.js → identityReuseStateMachine-CQgnATo5.esm.js} +1 -1
  147. package/dist/{index-CLMF0QLQ.d.ts → index-DLcJT5YP.d.ts} +1 -1
  148. package/dist/index.d.ts +1 -1
  149. package/dist/index.esm.js +1 -1
  150. package/dist/{invokeOnCaptureCallback-GpvMuz9o.esm.js → invokeOnCaptureCallback-BjzPjJ_p.esm.js} +1 -1
  151. package/dist/mandatory-consent.d.ts +2 -2
  152. package/dist/mandatory-consent.esm.js +2 -2
  153. package/dist/{mandatoryConsentManager-DyPzUmsZ.d.ts → mandatoryConsentManager-CJSyhTpi.d.ts} +5 -5
  154. package/dist/{mandatoryConsentManager-B4Niyg_u.esm.js → mandatoryConsentManager-Du-m-tZ_.esm.js} +2 -2
  155. package/dist/{mandatoryConsentStateMachine-B4-1u-L8.esm.js → mandatoryConsentStateMachine-DSDAk7WZ.esm.js} +1 -1
  156. package/dist/multipartRecordingService-B3C_zlev.esm.js +594 -0
  157. package/dist/{permissionGuards-KINpmKtI.esm.js → permissionGuards-uYZYFu4J.esm.js} +1 -1
  158. package/dist/{permissionServices-UvUcOSRb.esm.js → permissionServices-Bj_fyWtv.esm.js} +5 -5
  159. package/dist/personhood.d.ts +6 -5
  160. package/dist/personhood.esm.js +10 -10
  161. package/dist/phone.esm.js +2 -2
  162. package/dist/{phoneManager-FsJ0W2Ei.esm.js → phoneManager-N1-sbrY4.esm.js} +2 -2
  163. package/dist/{phoneStateMachine-Ba0wKHyX.esm.js → phoneStateMachine-jl8LJKCo.esm.js} +1 -1
  164. package/dist/{platform-BJrm5nzZ.esm.js → platform-DkcRc9JV.esm.js} +29 -1
  165. package/dist/qe-signature.d.ts +5 -3
  166. package/dist/qe-signature.esm.js +2 -2
  167. package/dist/recordingsRepository-CCWy13M-.esm.js +72 -0
  168. package/dist/redirect-to-mobile.esm.js +2 -2
  169. package/dist/{redirectToMobileManager-y4VQB11M.esm.js → redirectToMobileManager-DsFzdTwA.esm.js} +2 -2
  170. package/dist/{redirectToMobileStateMachine-Cyv2x0PP.esm.js → redirectToMobileStateMachine-v3otpT-L.esm.js} +1 -1
  171. package/dist/{rolldown-runtime-FZ4Itg2g.esm.js → rolldown-runtime-FDOR9p9I.esm.js} +1 -19
  172. package/dist/{runChildModule-BR2RIfRg.esm.js → runChildModule-TuyGE00X.esm.js} +3 -21
  173. package/dist/safeStorage-B-trhxg6.esm.js +423 -0
  174. package/dist/{sdkVersion-BWOdgLZ1.esm.js → sdkVersion-CLxKvdyz.esm.js} +1 -1
  175. package/dist/selfie.d.ts +5 -5
  176. package/dist/selfie.esm.js +14 -76
  177. package/dist/{selfieErrorUtils-C2PYBVsp.esm.js → selfieErrorUtils-C77GXJH6.esm.js} +30 -4
  178. package/dist/{selfieManager-BlImAV-k.esm.js → selfieManager-CihVnODO.esm.js} +5 -5
  179. package/dist/{selfieManager-DwlCppg0.d.ts → selfieManager-D1KRJ39M.d.ts} +8 -11
  180. package/dist/selfieStateMachine-fwMmNtOi.esm.js +69 -0
  181. package/dist/{session-Bp17qJsu.esm.js → session-BHIeAamR.esm.js} +4 -5
  182. package/dist/session.d.ts +21 -11
  183. package/dist/session.esm.js +5 -5
  184. package/dist/{sessionInitializer-CcqQD9Q4.esm.js → sessionInitializer-BLoK7SP9.esm.js} +187 -68
  185. package/dist/{setup-BgoWtvIS.d.ts → setup-Cv-JM9QC.d.ts} +63 -69
  186. package/dist/{setup-CXj5ozZN.esm.js → setup-msLybMbC.esm.js} +226 -100
  187. package/dist/signature.esm.js +2 -2
  188. package/dist/{signatureManager-Ca43yhwk.esm.js → signatureManager-ChsB-nMD.esm.js} +2 -2
  189. package/dist/{signatureStateMachine-K1LMRrxG.esm.js → signatureStateMachine-BHPwkJZS.esm.js} +1 -1
  190. package/dist/{src-0Jurt29N.esm.js → src-35ekGRzK.esm.js} +1 -1
  191. package/dist/{stats-B0nFKawG.esm.js → stats-DkK-f8JT.esm.js} +1 -1
  192. package/dist/stats.esm.js +1 -1
  193. package/dist/{trueSightService-D05SY_Ij.esm.js → trueSightService-CKrrfV0Q.esm.js} +7 -7
  194. package/dist/trust-graph.esm.js +1 -1
  195. package/dist/{types-BX_XkMsQ2.d.ts → types-9_esGTPj.d.ts} +1 -1
  196. package/dist/types-BT_Oalip.d.ts +1 -0
  197. package/dist/{types-DelMqZLe.d.ts → types-BjSly8cp.d.ts} +1 -1
  198. package/dist/{types-Hmd7U0JA.d.ts → types-CM-jtjJ2.d.ts} +6 -81
  199. package/dist/{types-Bdf8_LYB2.d.ts → types-CjKBS37a2.d.ts} +303 -13
  200. package/dist/{types-DVmXIdzW.d.ts → types-D0gekt4U.d.ts} +38 -5
  201. package/dist/types-DgDvvzg0.d.ts +10 -0
  202. package/dist/{types-KPvmag_B.d.ts → types-Do5rEXij.d.ts} +7 -4
  203. package/dist/types-ZT1XFIJ8.d.ts +6 -0
  204. package/dist/video-selfie.d.ts +59 -35
  205. package/dist/video-selfie.esm.js +510 -601
  206. package/dist/{videoSelfieCameraWarmer-BhTWYfGn.esm.js → videoSelfieCameraWarmer-CB1IzZkt.esm.js} +14 -153
  207. package/dist/videoSelfieFlowModuleMachine-BUe2uACW.esm.js +32 -0
  208. package/dist/{videoSelfieStepDetector-D3oo2ofo.d.ts → videoSelfieStepDetector-5YHFe0Mq.d.ts} +21 -5
  209. package/dist/virtualCameraCheck-WOloJ-do.esm.js +48 -0
  210. package/dist/warmup-CUUnwYxe.esm.js +714 -0
  211. package/dist/warmup-Cis2p6O0.d.ts +128 -0
  212. package/dist/wasm.d.ts +30 -6
  213. package/dist/wasm.esm.js +36 -4
  214. package/dist/{wasmDsFlagSync-BqUCwLY8.esm.js → wasmDsFlagSync-B2e8p268.esm.js} +2 -2
  215. package/dist/{wasmWebClient-DM8lkb0z.esm.js → wasmWebClient-B7baE-Wf.esm.js} +358 -28
  216. package/dist/watchlist-for-business.d.ts +2 -78
  217. package/dist/watchlist-for-business.esm.js +3 -102
  218. package/dist/watchlist.esm.js +2 -2
  219. package/dist/watchlistForBusinessManager-CpuuB1J2.esm.js +107 -0
  220. package/dist/watchlistForBusinessManager-CsnJnG-C.d.ts +99 -0
  221. package/dist/{watchlistForBusinessStateMachine-CxFnlshm.esm.js → watchlistForBusinessStateMachine-DEzgjz7C.esm.js} +13 -6
  222. package/dist/{watchlistManager-LoNZH9qm.esm.js → watchlistManager-CI8BHFob.esm.js} +2 -2
  223. package/dist/{watchlistStateMachine-DIKQDoUT.esm.js → watchlistStateMachine-DvOby3a-.esm.js} +1 -1
  224. package/dist/workflow.d.ts +12 -8
  225. package/dist/workflow.esm.js +48 -39
  226. package/package.json +4 -10
  227. package/dist/BrowserStorageProvider-k-FDkC4W.esm.js +0 -67
  228. package/dist/FaceDetectionProvider-Mh6q3EbA.d.ts +0 -349
  229. package/dist/IFaceAvatarCapability-BrL19G0s.d.ts +0 -23
  230. package/dist/IStorageCapability-ORkQfK3F.d.ts +0 -242
  231. package/dist/OpenViduRecordingProvider-Du98qevC.esm.js +0 -85
  232. package/dist/createFaceAvatar-BEj18KXi.d.ts +0 -50
  233. package/dist/document-upload.d.ts +0 -325
  234. package/dist/document-upload.esm.js +0 -197
  235. package/dist/electronicSignatureManager-CcUXQZS7.d.ts +0 -1300
  236. package/dist/faceCaptureSetup-BECAis8R.esm.js +0 -863
  237. package/dist/getBrowser-Cb8Zgrgp.esm.js +0 -7
  238. package/dist/getParsedUserAgent-pJjATANs.esm.js +0 -1622
  239. package/dist/governmentValidationStateMachine-CK9DrZXX.esm.js +0 -226
  240. package/dist/idCaptureDefaults-WeHbQM7W.esm.js +0 -225
  241. package/dist/idCaptureStateMachine-fi-Gq1AH.esm.js +0 -3342
  242. package/dist/lib-DAyUtOTj.esm.js +0 -12420
  243. package/dist/manualReviewService-D4IkipnN.esm.js +0 -15
  244. package/dist/mediaRecorderOptions-dALSV8af.esm.js +0 -40
  245. package/dist/onDeviceFaceResults-CB62pUQf.esm.js +0 -646
  246. package/dist/openviduLazy-CCDpFWg1.esm.js +0 -10
  247. package/dist/recordingService-BRgmVnUT.esm.js +0 -329
  248. package/dist/safeStorage-Ep56I-f_.esm.js +0 -982
  249. package/dist/selfieStateMachine-CPXEC4wV.esm.js +0 -55
  250. package/dist/trueSight-CY0Ibfm9.esm.js +0 -1
  251. package/dist/types-EELWyWpd.d.ts +0 -6
  252. package/dist/types-Vb4P9ovf.d.ts +0 -22
  253. package/dist/warmup-Dv2alr2-.d.ts +0 -82
  254. package/dist/wasmDefaults-DTUrftxR.esm.js +0 -125
  255. package/dist/{Face2DProvider-UUQt_vRC.esm.js → Face2DProvider-BF48sz5c.esm.js} +1 -1
  256. package/dist/{PrivacyLensProvider-D8PS7AJa.esm.js → PrivacyLensProvider-EwnC_C5n.esm.js} +1 -1
  257. /package/dist/{types-BfgmV7s72.d.ts → types-BfgmV7s7.d.ts} +0 -0
  258. /package/dist/{types-CJ7Yl9K-2.d.ts → types-CJ7Yl9K-.d.ts} +0 -0
@@ -0,0 +1,2106 @@
1
+ import { t as getTimestamp } from "./IBrowserEnvironmentCapability-DEaRRk-R.esm.js";
2
+ import { r as getToken } from "./api-Bx3gKW_y.esm.js";
3
+ import { l as trueSightLog, m as isTrueSightTesting } from "./trueSightService-CKrrfV0Q.esm.js";
4
+ import "./sessionInitializer-BLoK7SP9.esm.js";
5
+ import { t as addDeviceStats } from "./stats-DkK-f8JT.esm.js";
6
+ import { t as isAndroid } from "./platform-DkcRc9JV.esm.js";
7
+ import { i as assign, n as enqueueActions, r as sendTo, t as setup } from "./xstate.esm-BuFLFuzz.esm.js";
8
+ import { n as fromPromise, t as fromCallback } from "./xstate-actors.esm-BXeQ-Ucz.esm.js";
9
+ import { n as invokeRequestPermissionActor, t as checkPermission } from "./permissionServices-Bj_fyWtv.esm.js";
10
+ import { a as sendLabelInspectionEvent, c as stopRecording, i as initializeDeepsightSession, l as stopStream, r as initializeCamera, s as startRecordingSession, t as FaceDetectionProvider } from "./FaceDetectionProvider-DTetAE8H.esm.js";
11
+ import { t as FACE_ERROR_CODES } from "./types-BN5RPPIZ.esm.js";
12
+ import { a as flagFaceManualReview, i as imageFileToDataUrl, n as runProtectedAttempt, r as cameraCycleProvider, s as PROTECTED_CAPTURE_TARGET, t as createCameraCycleOwnership } from "./createCameraCycleOwnership-DQ5-F2oW.esm.js";
13
+ import { n as releaseFaceAvatarWarmup, r as warmFaceAvatar, t as createFaceAvatar } from "./createFaceAvatar-BNHdeFj8.esm.js";
14
+ import { t as IncodeCanvas } from "./canvas-BxFzWTt-.esm.js";
15
+ import { n as needsMotionPrimeOnlyFromPermission, r as resolveStoredPermissionResult, t as isReadyForCaptureFromPermission } from "./permissionGuards-uYZYFu4J.esm.js";
16
+ import { i as uploadDeepsightVideo } from "./recordingsRepository-CCWy13M-.esm.js";
17
+ import { t as getDeviceClass } from "./getDeviceClass-5NYZg9s6.esm.js";
18
+ import { n as getAdaptiveMediaRecorderOptions, t as MultipartRecordingService } from "./multipartRecordingService-B3C_zlev.esm.js";
19
+ //#region src/internal/avatar/concealment.ts
20
+ /**
21
+ * Maps a backend concealment option to the internal avatar flags. `OPTION_NONE`
22
+ * — and any absent or unknown value, for forward-compat safety — yields the live
23
+ * video (no avatar). The other three map 1:1 onto the shipped avatar catalog:
24
+ * - `OPTION_3D` → `avatar-3d` (3D VRM)
25
+ * - `OPTION_2D` → `avatar-2d` (stylized 2D face)
26
+ * - `OPTION_SILHOUETTE` → `privacy-lens` (WebGL frosted-glass conceal)
27
+ */
28
+ function concealmentToAvatar(option) {
29
+ switch (option) {
30
+ case "OPTION_3D": return {
31
+ obfuscateWithAvatar: true,
32
+ avatarVariant: "avatar-3d"
33
+ };
34
+ case "OPTION_2D": return {
35
+ obfuscateWithAvatar: true,
36
+ avatarVariant: "avatar-2d"
37
+ };
38
+ case "OPTION_SILHOUETTE": return {
39
+ obfuscateWithAvatar: true,
40
+ avatarVariant: "privacy-lens"
41
+ };
42
+ default: return {
43
+ obfuscateWithAvatar: false,
44
+ avatarVariant: void 0
45
+ };
46
+ }
47
+ }
48
+ //#endregion
49
+ //#region src/internal/faceCapture/manualUpload/errors.ts
50
+ /**
51
+ * Reuses the `notifications.*` copy that `errorModal.tsx` shows for the same
52
+ * codes on the camera path, plus the ID manual-upload keys. Only the `title`
53
+ * half of each notification pair is used — the inline error is one line.
54
+ */
55
+ const MANUAL_FACE_UPLOAD_ERROR_KEYS = {
56
+ /** The one new string; ID accepts any image type so there was none to reuse. */
57
+ typeError: "selfiev2.manualUpload.typeError",
58
+ fileTooBig: "manualIdUpload.fileTooBig",
59
+ generic: "manualIdUpload.generic",
60
+ faceNotFound: "notifications.faceNotFound",
61
+ multipleFaces: "notifications.multiple",
62
+ lowQualityImage: "notifications.lowQualityImage",
63
+ brightness: "notifications.brightness",
64
+ lenses: "notifications.lenses",
65
+ mask: "notifications.mask",
66
+ removeHeadwear: "notifications.removeHeadwear",
67
+ closedEyes: "notifications.closedEyes",
68
+ spoof: "notifications.spoof",
69
+ accessDenied: "notifications.accessDenied",
70
+ nonexistentCustomer: "notifications.nonexistentCustomer",
71
+ hintNotProvided: "notifications.hintNotProvided",
72
+ selfieImageLowQuality: "notifications.selfieImageLowQuality"
73
+ };
74
+ /** Mirrors `errorContent` in `errorModal.tsx`; omissions resolve to `generic`. */
75
+ const ERROR_KEY_BY_FACE_ERROR_CODE = {
76
+ [FACE_ERROR_CODES.FACE_NOT_FOUND]: MANUAL_FACE_UPLOAD_ERROR_KEYS.faceNotFound,
77
+ [FACE_ERROR_CODES.MULTIPLE_FACES]: MANUAL_FACE_UPLOAD_ERROR_KEYS.multipleFaces,
78
+ [FACE_ERROR_CODES.BAD_PHOTO_QUALITY]: MANUAL_FACE_UPLOAD_ERROR_KEYS.lowQualityImage,
79
+ [FACE_ERROR_CODES.SELFIE_IMAGE_LOW_QUALITY]: MANUAL_FACE_UPLOAD_ERROR_KEYS.selfieImageLowQuality,
80
+ [FACE_ERROR_CODES.BRIGHTNESS]: MANUAL_FACE_UPLOAD_ERROR_KEYS.brightness,
81
+ [FACE_ERROR_CODES.FACE_TOO_DARK]: MANUAL_FACE_UPLOAD_ERROR_KEYS.brightness,
82
+ [FACE_ERROR_CODES.LENSES]: MANUAL_FACE_UPLOAD_ERROR_KEYS.lenses,
83
+ [FACE_ERROR_CODES.LENSES_DETECTED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.lenses,
84
+ [FACE_ERROR_CODES.MASK]: MANUAL_FACE_UPLOAD_ERROR_KEYS.mask,
85
+ [FACE_ERROR_CODES.FACE_MASK_DETECTED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.mask,
86
+ [FACE_ERROR_CODES.HEAD_COVER]: MANUAL_FACE_UPLOAD_ERROR_KEYS.removeHeadwear,
87
+ [FACE_ERROR_CODES.HEAD_COVER_DETECTED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.removeHeadwear,
88
+ [FACE_ERROR_CODES.CLOSED_EYES]: MANUAL_FACE_UPLOAD_ERROR_KEYS.closedEyes,
89
+ [FACE_ERROR_CODES.CLOSED_EYES_DETECTED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.closedEyes,
90
+ [FACE_ERROR_CODES.LIVENESS]: MANUAL_FACE_UPLOAD_ERROR_KEYS.spoof,
91
+ [FACE_ERROR_CODES.SPOOF_ATTEMPT_DETECTED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.spoof,
92
+ [FACE_ERROR_CODES.FACE_TOO_BLURRY]: MANUAL_FACE_UPLOAD_ERROR_KEYS.spoof,
93
+ [FACE_ERROR_CODES.USER_IS_NOT_RECOGNIZED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.accessDenied,
94
+ [FACE_ERROR_CODES.NONEXISTENT_CUSTOMER]: MANUAL_FACE_UPLOAD_ERROR_KEYS.nonexistentCustomer,
95
+ [FACE_ERROR_CODES.HINT_NOT_PROVIDED]: MANUAL_FACE_UPLOAD_ERROR_KEYS.hintNotProvided
96
+ };
97
+ function mapFaceErrorCodeToErrorKey(code) {
98
+ if (!code) return MANUAL_FACE_UPLOAD_ERROR_KEYS.generic;
99
+ return ERROR_KEY_BY_FACE_ERROR_CODE[code] ?? MANUAL_FACE_UPLOAD_ERROR_KEYS.generic;
100
+ }
101
+ /** Enforced in core because the picker's `accept` filter is bypassable. */
102
+ const MANUAL_FACE_UPLOAD_ACCEPTED_MIME_TYPES = ["image/png", "image/jpeg"];
103
+ //#endregion
104
+ //#region src/internal/faceCapture/manualUpload/prepareFile.ts
105
+ const isAcceptedMimeType = (type) => MANUAL_FACE_UPLOAD_ACCEPTED_MIME_TYPES.includes(type);
106
+ const stripDataUrlPrefix = (dataUrl) => {
107
+ const commaIndex = dataUrl.indexOf(",");
108
+ return commaIndex === -1 ? dataUrl : dataUrl.slice(commaIndex + 1);
109
+ };
110
+ /** Duplicated from the ID manual upload; consolidate if a third caller appears. */
111
+ const getBase64PayloadByteLength = (payload) => {
112
+ const normalized = payload.replace(/\s/g, "");
113
+ let padding = 0;
114
+ if (normalized.endsWith("==")) padding = 2;
115
+ else if (normalized.endsWith("=")) padding = 1;
116
+ return Math.max(0, Math.floor(normalized.length * 3 / 4) - padding);
117
+ };
118
+ /**
119
+ * Every client-side check, run before any network call so a rejection here
120
+ * never costs the user a retry.
121
+ */
122
+ async function prepareManualFaceUpload(file) {
123
+ if (!isAcceptedMimeType(file.type)) return {
124
+ ok: false,
125
+ errorKey: MANUAL_FACE_UPLOAD_ERROR_KEYS.typeError
126
+ };
127
+ if (file.size > 5242880) return {
128
+ ok: false,
129
+ errorKey: MANUAL_FACE_UPLOAD_ERROR_KEYS.fileTooBig
130
+ };
131
+ const base64Image = stripDataUrlPrefix(await imageFileToDataUrl(file));
132
+ if (getBase64PayloadByteLength(base64Image) > 5242880) return {
133
+ ok: false,
134
+ errorKey: MANUAL_FACE_UPLOAD_ERROR_KEYS.fileTooBig
135
+ };
136
+ return {
137
+ ok: true,
138
+ base64Image
139
+ };
140
+ }
141
+ //#endregion
142
+ //#region src/internal/faceCapture/manualUpload/manualFaceUploadStateMachine.ts
143
+ const prepareFileActor = fromPromise(async ({ input }) => prepareManualFaceUpload(input.file));
144
+ const getPreparedFromEvent = (event) => "output" in event ? event.output : void 0;
145
+ const getErrorMessageFromEvent = (event) => {
146
+ const { error } = event;
147
+ if (error instanceof Error) return error.message;
148
+ return typeof error === "string" ? error : "";
149
+ };
150
+ const manualFaceUploadMachine = setup({
151
+ types: {
152
+ context: {},
153
+ events: {},
154
+ input: {},
155
+ output: {}
156
+ },
157
+ actors: {
158
+ prepareFile: prepareFileActor,
159
+ uploadFile: fromPromise(async () => {
160
+ throw new Error("uploadFile must be provided by variant");
161
+ })
162
+ },
163
+ actions: {
164
+ storeSelectedFile: assign(({ event }) => {
165
+ if (event.type !== "MANUAL_UPLOAD_FILE_SELECTED") return {};
166
+ return {
167
+ file: event.file,
168
+ errorKey: null,
169
+ uploaded: false
170
+ };
171
+ }),
172
+ storePreparedImage: assign(({ event }) => {
173
+ const prepared = getPreparedFromEvent(event);
174
+ return prepared?.ok ? { base64Image: prepared.base64Image } : {};
175
+ }),
176
+ setErrorFromPrepare: assign(({ event }) => {
177
+ const prepared = getPreparedFromEvent(event);
178
+ return { errorKey: prepared && !prepared.ok ? prepared.errorKey : MANUAL_FACE_UPLOAD_ERROR_KEYS.generic };
179
+ }),
180
+ setGenericError: assign(() => ({ errorKey: MANUAL_FACE_UPLOAD_ERROR_KEYS.generic })),
181
+ setErrorFromUploadFailure: assign(({ event }) => ({ errorKey: mapFaceErrorCodeToErrorKey(getErrorMessageFromEvent(event)) })),
182
+ markUploaded: assign(() => ({
183
+ uploaded: true,
184
+ errorKey: null
185
+ })),
186
+ decrementRetries: assign(({ context }) => ({ retriesLeft: Math.max(0, context.retriesLeft - 1) })),
187
+ reset: assign(({ context }) => ({
188
+ file: null,
189
+ base64Image: null,
190
+ uploaded: false,
191
+ errorKey: null,
192
+ retriesLeft: context.captureAttempts
193
+ })),
194
+ markSucceeded: assign(() => ({ outcome: "success" })),
195
+ markExhausted: assign(() => ({ outcome: "exhausted" }))
196
+ },
197
+ guards: {
198
+ isPrepareRejected: ({ event }) => getPreparedFromEvent(event)?.ok === false,
199
+ retriesExhausted: ({ context }) => context.retriesLeft <= 0,
200
+ canContinue: ({ context }) => context.uploaded
201
+ }
202
+ }).createMachine({
203
+ id: "manualFaceUpload",
204
+ initial: "selecting",
205
+ context: ({ input }) => ({
206
+ config: input.config,
207
+ dependencies: input.dependencies,
208
+ captureAttempts: input.captureAttempts,
209
+ retriesLeft: input.captureAttempts,
210
+ file: null,
211
+ base64Image: null,
212
+ uploaded: false,
213
+ errorKey: null,
214
+ outcome: null
215
+ }),
216
+ output: ({ context }) => ({ result: context.outcome === "success" ? "success" : "exhausted" }),
217
+ on: { MANUAL_UPLOAD_RESET: {
218
+ target: ".selecting",
219
+ actions: ["reset"]
220
+ } },
221
+ states: {
222
+ selecting: { on: {
223
+ MANUAL_UPLOAD_FILE_SELECTED: {
224
+ target: "preparing",
225
+ actions: ["storeSelectedFile"]
226
+ },
227
+ MANUAL_UPLOAD_CONTINUE: {
228
+ guard: "canContinue",
229
+ target: "finished",
230
+ actions: ["markSucceeded"]
231
+ }
232
+ } },
233
+ preparing: { invoke: {
234
+ id: "prepareFile",
235
+ src: "prepareFile",
236
+ input: ({ context }) => ({ file: context.file }),
237
+ onDone: [{
238
+ guard: "isPrepareRejected",
239
+ target: "selecting",
240
+ actions: ["setErrorFromPrepare"]
241
+ }, {
242
+ target: "uploading",
243
+ actions: ["storePreparedImage"]
244
+ }],
245
+ onError: {
246
+ target: "selecting",
247
+ actions: ["setGenericError"]
248
+ }
249
+ } },
250
+ uploading: { invoke: {
251
+ id: "uploadFile",
252
+ src: "uploadFile",
253
+ input: ({ context }) => ({
254
+ base64Image: context.base64Image,
255
+ config: context.config,
256
+ dependencies: context.dependencies
257
+ }),
258
+ onDone: {
259
+ target: "selecting",
260
+ actions: ["markUploaded"]
261
+ },
262
+ onError: {
263
+ target: "checkRetries",
264
+ actions: ["decrementRetries", "setErrorFromUploadFailure"]
265
+ }
266
+ } },
267
+ checkRetries: { always: [{
268
+ guard: "retriesExhausted",
269
+ target: "exhausted",
270
+ actions: ["markExhausted"]
271
+ }, { target: "selecting" }] },
272
+ exhausted: { type: "final" },
273
+ finished: { type: "final" }
274
+ }
275
+ });
276
+ //#endregion
277
+ //#region ../infra/src/providers/wasm/createProtectedFaceCaptureCapabilities.ts
278
+ /**
279
+ * Infrastructure composition boundary for one protected still-face attempt.
280
+ * Core receives capability interfaces and never constructs or reaches for the
281
+ * process-wide WASM providers directly.
282
+ */
283
+ function createProtectedFaceCaptureCapabilities() {
284
+ return {
285
+ cycle: cameraCycleProvider,
286
+ faceDetection: new FaceDetectionProvider()
287
+ };
288
+ }
289
+ //#endregion
290
+ //#region src/internal/faceCapture/faceCaptureDiagnostics.ts
291
+ const FACE_CAMERA_DIAGNOSTIC_PREFIX = "[Incode face camera]";
292
+ /**
293
+ * Emits one bounded lifecycle line only for SDK testing sessions. The payload
294
+ * deliberately excludes media, native results, tokens, request data, and
295
+ * errors so a browser console recording cannot retain capture data.
296
+ */
297
+ function logFaceCameraDiagnostic(event, fields) {
298
+ if (!isTrueSightTesting()) return;
299
+ console.debug(`${FACE_CAMERA_DIAGNOSTIC_PREFIX} ${event} ${JSON.stringify(fields)}`);
300
+ }
301
+ //#endregion
302
+ //#region ../infra/src/media/VideoTrimmer.ts
303
+ async function getDurationBySeek(videoBlob) {
304
+ const video = document.createElement("video");
305
+ video.preload = "metadata";
306
+ video.src = URL.createObjectURL(videoBlob);
307
+ try {
308
+ if (!Number.isFinite(video.duration)) {
309
+ video.currentTime = Number.MAX_SAFE_INTEGER;
310
+ await new Promise((resolve) => {
311
+ const onDurationChange = () => {
312
+ if (Number.isFinite(video.duration)) {
313
+ video.removeEventListener("durationchange", onDurationChange);
314
+ video.removeEventListener("timeupdate", onTimeUpdate);
315
+ resolve(video.duration);
316
+ }
317
+ };
318
+ const onTimeUpdate = () => {
319
+ if (Number.isFinite(video.duration)) {
320
+ video.removeEventListener("timeupdate", onTimeUpdate);
321
+ video.removeEventListener("durationchange", onDurationChange);
322
+ resolve(video.duration);
323
+ }
324
+ };
325
+ video.addEventListener("durationchange", onDurationChange);
326
+ video.addEventListener("timeupdate", onTimeUpdate);
327
+ });
328
+ }
329
+ const duration = video.duration;
330
+ return Number.isFinite(duration) ? duration : null;
331
+ } finally {
332
+ URL.revokeObjectURL(video.src);
333
+ video.src = "";
334
+ }
335
+ }
336
+ async function trimLastNSecondsUsingPlayback(videoBlob, seconds) {
337
+ const video = document.createElement("video");
338
+ video.preload = "metadata";
339
+ video.playsInline = true;
340
+ video.muted = true;
341
+ const videoURL = URL.createObjectURL(videoBlob);
342
+ video.src = videoURL;
343
+ const duration = await getDurationBySeek(videoBlob);
344
+ if (!duration || duration < seconds) {
345
+ URL.revokeObjectURL(videoURL);
346
+ return videoBlob;
347
+ }
348
+ const startTime = Math.max(0, Math.floor(duration) - seconds);
349
+ await new Promise((resolve) => {
350
+ if (video.readyState >= 2) resolve();
351
+ else video.addEventListener("loadedmetadata", () => resolve(), { once: true });
352
+ });
353
+ const canvas = document.createElement("canvas");
354
+ canvas.width = 230;
355
+ canvas.height = 320;
356
+ const captureFps = isAndroid() ? 15 : 24;
357
+ const stream = canvas.captureStream(captureFps);
358
+ const ctx = canvas.getContext("2d");
359
+ video.currentTime = startTime;
360
+ await new Promise((resolve) => {
361
+ video.addEventListener("seeked", () => resolve(), { once: true });
362
+ });
363
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
364
+ const mimeType = videoBlob.type || (MediaRecorder.isTypeSupported("video/webm") ? "video/webm" : "video/mp4");
365
+ const mediaRecorder = new MediaRecorder(stream.clone(), {
366
+ mimeType,
367
+ videoBitsPerSecond: 5e5,
368
+ bitsPerSecond: 5e5
369
+ });
370
+ const chunks = [];
371
+ mediaRecorder.ondataavailable = (event) => {
372
+ if (event.data.size > 0) chunks.push(event.data);
373
+ };
374
+ const recordingPromise = new Promise((resolve) => {
375
+ mediaRecorder.onstop = () => {
376
+ const trimmedBlob = new Blob(chunks, { type: mimeType });
377
+ URL.revokeObjectURL(videoURL);
378
+ mediaRecorder.stream?.getTracks().forEach((track) => track.stop());
379
+ stream.getTracks().forEach((track) => track.stop());
380
+ video.src = "";
381
+ resolve(trimmedBlob);
382
+ };
383
+ });
384
+ video.addEventListener("play", () => {
385
+ function drawVideo() {
386
+ if (video.currentTime >= duration) {
387
+ mediaRecorder.stop();
388
+ video.pause();
389
+ return;
390
+ }
391
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
392
+ requestAnimationFrame(drawVideo);
393
+ }
394
+ drawVideo();
395
+ setTimeout(() => {
396
+ mediaRecorder.start(100);
397
+ }, 500);
398
+ });
399
+ video.play().catch(() => {
400
+ URL.revokeObjectURL(videoURL);
401
+ });
402
+ const trimmedBlob = await recordingPromise;
403
+ console.timeEnd("trimLastNSecondsUsingPlayback");
404
+ return trimmedBlob;
405
+ }
406
+ async function trimLastNSeconds(videoBlob, seconds) {
407
+ return await trimLastNSecondsUsingPlayback(videoBlob, seconds);
408
+ }
409
+ //#endregion
410
+ //#region ../infra/src/providers/browser/LocalRecordingProvider.ts
411
+ function toBase64(videoBlob) {
412
+ return new Promise((resolve, reject) => {
413
+ const reader = new FileReader();
414
+ reader.onloadend = () => {
415
+ const base64 = reader.result.split(",")[1];
416
+ resolve(base64);
417
+ };
418
+ reader.onerror = () => reject(reader.error ?? /* @__PURE__ */ new Error("FileReader error"));
419
+ reader.readAsDataURL(videoBlob);
420
+ });
421
+ }
422
+ var LocalRecordingProvider = class {
423
+ constructor() {
424
+ this.mediaRecorder = null;
425
+ this._isRecording = false;
426
+ this._hasError = false;
427
+ this._error = null;
428
+ this.mimeType = "";
429
+ this.stream = null;
430
+ this.pauseRecordingBound = this.pauseRecording.bind(this);
431
+ }
432
+ get isRecording() {
433
+ return this._isRecording;
434
+ }
435
+ get hasError() {
436
+ return this._hasError;
437
+ }
438
+ get error() {
439
+ return this._error;
440
+ }
441
+ startRecording(stream) {
442
+ this.reset();
443
+ this.registerEventListeners();
444
+ this.stream = stream;
445
+ try {
446
+ const options = getAdaptiveMediaRecorderOptions();
447
+ this.mimeType = options.mimeType;
448
+ const recorder = new MediaRecorder(stream.clone(), options);
449
+ recorder.onerror = (event) => {
450
+ this._error = `Recording error: ${event}`;
451
+ this._isRecording = false;
452
+ this._hasError = true;
453
+ };
454
+ recorder.start();
455
+ this.mediaRecorder = recorder;
456
+ this._isRecording = true;
457
+ this._error = null;
458
+ this._hasError = false;
459
+ } catch (err) {
460
+ this._error = `Failed to start recording: ${err}`;
461
+ this._hasError = true;
462
+ }
463
+ }
464
+ async stopRecording(trimSeconds, encrypt, generateChecksum) {
465
+ const recorder = this.mediaRecorder;
466
+ return new Promise((resolve, reject) => {
467
+ this.removeEventListeners();
468
+ if (recorder && this._isRecording) {
469
+ const chunks = [];
470
+ recorder.ondataavailable = (event) => {
471
+ if (event.data.size > 0) chunks.push(event.data);
472
+ };
473
+ recorder.onstop = async () => {
474
+ try {
475
+ const trimmedVideo = await trimLastNSeconds(new Blob(chunks, { type: this.mimeType }), trimSeconds);
476
+ const encryptedVideoBase64 = encrypt(await toBase64(trimmedVideo));
477
+ generateChecksum(await trimmedVideo.arrayBuffer());
478
+ this._isRecording = false;
479
+ resolve({
480
+ trimmedBlob: trimmedVideo,
481
+ encryptedVideo: encryptedVideoBase64
482
+ });
483
+ } catch (error) {
484
+ this._isRecording = false;
485
+ this._error = `Recording stop failed: ${error}`;
486
+ this._hasError = true;
487
+ reject(error);
488
+ }
489
+ };
490
+ recorder.stop();
491
+ this._isRecording = false;
492
+ } else resolve({
493
+ trimmedBlob: new Blob([], { type: this.mimeType }),
494
+ encryptedVideo: ""
495
+ });
496
+ recorder?.stream?.getTracks().forEach((track) => track.stop());
497
+ });
498
+ }
499
+ reset() {
500
+ this._isRecording = false;
501
+ this._error = null;
502
+ this._hasError = false;
503
+ }
504
+ pauseRecording() {
505
+ if (!this._isRecording) return;
506
+ if (this.mediaRecorder?.state === "recording") try {
507
+ this.mediaRecorder.pause();
508
+ } catch {}
509
+ }
510
+ registerEventListeners() {
511
+ document.addEventListener("visibilitychange", this.pauseRecordingBound);
512
+ }
513
+ removeEventListeners() {
514
+ document.removeEventListener("visibilitychange", this.pauseRecordingBound);
515
+ }
516
+ };
517
+ //#endregion
518
+ //#region src/internal/faceCapture/recordingService.ts
519
+ /**
520
+ * Records on-device and uploads encrypted video for liveness.
521
+ */
522
+ var LocalRecordingService = class {
523
+ constructor(wasmUtil, sessionToken) {
524
+ this.recorder = new LocalRecordingProvider();
525
+ this.sessionToken = sessionToken;
526
+ this.wasmUtil = wasmUtil;
527
+ }
528
+ async start(stream) {
529
+ this.recorder.startRecording(stream);
530
+ this.wasmUtil.osv();
531
+ }
532
+ async stop() {
533
+ if (!this.recorder.isRecording) return { recordingId: null };
534
+ this.wasmUtil.oev();
535
+ const result = await this.recorder.stopRecording(10, (base64) => this.wasmUtil.encryptImage(base64), (buffer) => this.wasmUtil.ckvcks(buffer));
536
+ if (!this.sessionToken) return { recordingId: null };
537
+ return { recordingId: await uploadDeepsightVideo(result.encryptedVideo, this.sessionToken) };
538
+ }
539
+ prepareUpload() {
540
+ return this.stop();
541
+ }
542
+ async stopAndGetVideo() {
543
+ if (!this.recorder.isRecording) return { videoBase64: void 0 };
544
+ try {
545
+ this.wasmUtil.oev();
546
+ const videoBase64 = (await this.recorder.stopRecording(10, (base64) => base64, () => {})).encryptedVideo;
547
+ return { videoBase64: videoBase64 ? videoBase64 : void 0 };
548
+ } catch {
549
+ return { videoBase64: void 0 };
550
+ }
551
+ }
552
+ cleanup() {
553
+ this.recorder.reset();
554
+ }
555
+ };
556
+ /**
557
+ * Records a regular Selfie capture locally and streams it through the scoped
558
+ * video-selfie-service multipart protocol. The recording is associated with
559
+ * the interview asynchronously by the backend's `selfie` scope consumer, so
560
+ * its upload id must not be forwarded to `/omni/add/face` as a legacy
561
+ * `recordingId`.
562
+ */
563
+ var MultipartFaceRecordingService = class {
564
+ constructor() {
565
+ this.service = new MultipartRecordingService("selfie");
566
+ this.pausedForAttempt = false;
567
+ }
568
+ async start(stream) {
569
+ if (this.pausedForAttempt) {
570
+ if (!this.service.resume()) throw new Error("Face recording did not resume");
571
+ this.pausedForAttempt = false;
572
+ return;
573
+ }
574
+ await this.service.start(stream);
575
+ }
576
+ async prepareUpload() {
577
+ this.pausedForAttempt = this.service.pause();
578
+ return { recordingId: null };
579
+ }
580
+ async stop() {
581
+ try {
582
+ await this.service.stop();
583
+ } finally {
584
+ this.pausedForAttempt = false;
585
+ }
586
+ return { recordingId: null };
587
+ }
588
+ pauseForBackground() {
589
+ this.service.pause();
590
+ }
591
+ async resumeFromBackground() {
592
+ this.service.resume();
593
+ }
594
+ async stopAndGetVideo() {
595
+ try {
596
+ await this.service.stop();
597
+ } finally {
598
+ this.pausedForAttempt = false;
599
+ }
600
+ return { videoBase64: void 0 };
601
+ }
602
+ cleanup() {
603
+ this.pausedForAttempt = false;
604
+ this.service.cleanup();
605
+ }
606
+ };
607
+ /**
608
+ * Records through a consumer-injected remote provider and manages its session.
609
+ */
610
+ var InjectedRecordingService = class {
611
+ constructor(config) {
612
+ this.config = config;
613
+ }
614
+ async start(stream) {
615
+ if (this.session) return;
616
+ this.session = await startRecordingSession({
617
+ config: this.config,
618
+ clonedStream: stream.clone()
619
+ });
620
+ }
621
+ async prepareUpload() {
622
+ return { recordingId: null };
623
+ }
624
+ async stop() {
625
+ if (this.session) {
626
+ stopRecording(this.session);
627
+ this.session = void 0;
628
+ }
629
+ return { recordingId: null };
630
+ }
631
+ async stopAndGetVideo() {
632
+ if (this.session) {
633
+ stopRecording(this.session);
634
+ this.session = void 0;
635
+ }
636
+ return { videoBase64: void 0 };
637
+ }
638
+ cleanup() {
639
+ if (this.session) stopRecording(this.session);
640
+ }
641
+ };
642
+ /**
643
+ * Creates the recording service for the current configuration.
644
+ *
645
+ * Order of precedence:
646
+ * 1. `onDeviceFaceResultsSubmissionEnabled === true` → no recording. The
647
+ * on-device workflow never uploads media, only the staged face-results
648
+ * JSON via `WebApi.postFaceResults`. Mirrors V1's
649
+ * `FaceFlowManager.setRecorders()` early return.
650
+ * 2. `deepsightLiveness === 'VIDEOLIVENESS'` → local Deepsight recorder.
651
+ * 3. `enableFaceRecording === true` → scoped multipart recorder. A custom
652
+ * injected recording capability remains supported for backwards-compatible
653
+ * dependency injection.
654
+ * 4. otherwise → no recording.
655
+ */
656
+ function createRecordingService(params) {
657
+ if (params.config.onDeviceFaceResultsSubmissionEnabled === true) return;
658
+ if (params.localDelivery === true) return params.config.enableFaceRecording === true || params.config.deepsightLiveness === "VIDEOLIVENESS" ? new LocalRecordingService(params.wasmUtil, null) : void 0;
659
+ if (params.config.deepsightLiveness === "VIDEOLIVENESS") return new LocalRecordingService(params.wasmUtil, params.sessionToken);
660
+ if (params.config.enableFaceRecording === true) return params.config.recording?.capability ? new InjectedRecordingService(params.config) : new MultipartFaceRecordingService();
661
+ }
662
+ //#endregion
663
+ //#region src/internal/faceCapture/protectedFaceAttempt.ts
664
+ const ON_DEVICE_MANUAL_CAPTURE_TIMEOUT_MS = 2147483647;
665
+ var ProtectedFaceRecorderHooks = class {
666
+ constructor(config, dependencies, delivery) {
667
+ this.config = config;
668
+ this.dependencies = dependencies;
669
+ this.delivery = delivery;
670
+ this.mode = config.onDeviceFaceResultsSubmissionEnabled === true || config.enableFaceRecording !== true && config.deepsightLiveness !== "VIDEOLIVENESS" ? "none" : "finalizeBeforePoc";
671
+ }
672
+ async start(unprotectedStream) {
673
+ if (this.mode === "none") return;
674
+ const wasmUtil = await this.dependencies.getWasmUtil();
675
+ this.service = createRecordingService({
676
+ config: this.config,
677
+ wasmUtil,
678
+ sessionToken: getToken(),
679
+ localDelivery: this.delivery === "local"
680
+ });
681
+ await this.service?.start(unprotectedStream);
682
+ }
683
+ async prepareForPoc() {
684
+ if (!this.service) return {};
685
+ if (this.delivery === "local") {
686
+ try {
687
+ const result = await this.service.stopAndGetVideo();
688
+ this.captureOnlyVideoBase64 = result.videoBase64;
689
+ } catch {
690
+ this.captureOnlyVideoBase64 = void 0;
691
+ }
692
+ return {};
693
+ }
694
+ return this.service.stop();
695
+ }
696
+ async resumeAfterPoc() {}
697
+ pauseForBackground() {
698
+ this.service?.pauseForBackground?.();
699
+ }
700
+ async resumeFromBackground(unprotectedStream) {
701
+ await this.service?.resumeFromBackground?.(unprotectedStream);
702
+ }
703
+ dispose() {
704
+ try {
705
+ this.service?.cleanup();
706
+ } finally {
707
+ this.service = void 0;
708
+ }
709
+ }
710
+ takeCaptureOnlyVideo() {
711
+ const video = this.captureOnlyVideoBase64;
712
+ this.captureOnlyVideoBase64 = void 0;
713
+ return video;
714
+ }
715
+ };
716
+ let nextAttemptNumber = 1;
717
+ /**
718
+ * Private composition object for one still-face attempt. It owns provider
719
+ * callbacks and raw-stream handoff outside XState; the machine sees only the
720
+ * presentation stream/canvas and allowlisted semantic results.
721
+ */
722
+ var ProtectedFaceAttemptRuntime = class ProtectedFaceAttemptRuntime {
723
+ constructor(options) {
724
+ this.options = options;
725
+ this.attemptId = `face-${nextAttemptNumber++}`;
726
+ this.acquiredUsingBackCamera = false;
727
+ this.rawHandedOff = false;
728
+ this.rawStreamReleased = false;
729
+ this.released = false;
730
+ this.recorderTransferred = false;
731
+ this.pendingSignals = [];
732
+ this.provider = options.faceDetection;
733
+ this.recorder = new ProtectedFaceRecorderHooks(options.config, options.dependencies, options.delivery);
734
+ this.cycleOwnership = createCameraCycleOwnership(options.cycle);
735
+ }
736
+ get delivery() {
737
+ return this.options.delivery;
738
+ }
739
+ get usingBackCamera() {
740
+ return this.acquiredUsingBackCamera;
741
+ }
742
+ setDeepsightService(service) {
743
+ if (this.released || this.deepsightService) return;
744
+ this.deepsightService = service;
745
+ }
746
+ async preAcquire() {
747
+ await this.acquireRawStream();
748
+ }
749
+ subscribeSignals(listener) {
750
+ if (this.released) return () => void 0;
751
+ this.signalListener = listener;
752
+ const queued = this.pendingSignals;
753
+ this.pendingSignals = [];
754
+ queued.forEach(listener);
755
+ return () => {
756
+ if (this.signalListener === listener) this.signalListener = void 0;
757
+ };
758
+ }
759
+ toActorInput(onStartupTiming) {
760
+ this.recorderTransferred = true;
761
+ return {
762
+ attemptId: this.attemptId,
763
+ target: this.options.target,
764
+ workflow: this.options.config.onDeviceFaceResultsSubmissionEnabled === true ? 5 : 4,
765
+ streamSource: {
766
+ kind: "acquire",
767
+ acquire: async () => {
768
+ const result = await this.acquireRawStream();
769
+ this.rawHandedOff = true;
770
+ return {
771
+ stream: result.stream,
772
+ constraints: result.constraints
773
+ };
774
+ }
775
+ },
776
+ cycle: this.options.cycle,
777
+ cycleOwnership: this.cycleOwnership,
778
+ recorder: this.recorder,
779
+ releaseUnadoptedStream: (stream) => stopStream(stream),
780
+ configureWorkflow: () => this.configureWorkflow(),
781
+ runPrc: () => this.runPrc(),
782
+ runPoc: () => this.runPoc(),
783
+ onStartupTiming,
784
+ faceResults: this.provider
785
+ };
786
+ }
787
+ createUploadCommand(recordingId) {
788
+ const token = getToken();
789
+ const config = {
790
+ headers: token ? { "X-Incode-Hardware-Id": token } : void 0,
791
+ timeout: 3e4
792
+ };
793
+ if (this.options.config.onDeviceFaceResultsSubmissionEnabled === true) return {
794
+ type: "UPLOAD_FACE_RESULTS",
795
+ config
796
+ };
797
+ const validRecordingId = recordingId && recordingId.trim().length > 0 ? recordingId : void 0;
798
+ if (this.options.target === PROTECTED_CAPTURE_TARGET.authentication) return {
799
+ type: "UPLOAD_PROTECTED",
800
+ request: {
801
+ target: PROTECTED_CAPTURE_TARGET.authentication,
802
+ extras: {
803
+ deviceClass: getDeviceClass(),
804
+ hint: this.options.authHint,
805
+ ...validRecordingId ? { recordingId: validRecordingId } : {}
806
+ },
807
+ config
808
+ }
809
+ };
810
+ return {
811
+ type: "UPLOAD_PROTECTED",
812
+ request: {
813
+ target: PROTECTED_CAPTURE_TARGET.selfie,
814
+ extras: { deviceClass: getDeviceClass() },
815
+ config: {
816
+ ...config,
817
+ params: {
818
+ imageType: "selfie",
819
+ ...validRecordingId ? { recordingId: validRecordingId } : {}
820
+ }
821
+ }
822
+ }
823
+ };
824
+ }
825
+ mapProtectedResult(result) {
826
+ if (result.kind === "onDeviceFace") return {};
827
+ if (result.kind === "authentication") return {
828
+ overallStatus: result.overallStatus,
829
+ captureAttemptsLimit: {
830
+ max: this.options.config.captureAttempts ?? this.options.config.numberOfAttempts ?? 3,
831
+ remaining: result.attemptsRemaining ?? 0
832
+ },
833
+ candidate: "",
834
+ error: {
835
+ name: result.errorName ?? "",
836
+ message: result.errorName ?? ""
837
+ }
838
+ };
839
+ return result;
840
+ }
841
+ takeCaptureOnlyVideo() {
842
+ return this.recorder.takeCaptureOnlyVideo();
843
+ }
844
+ next() {
845
+ return new ProtectedFaceAttemptRuntime(this.options);
846
+ }
847
+ release() {
848
+ if (this.released) return;
849
+ this.released = true;
850
+ this.signalListener = void 0;
851
+ this.pendingSignals = [];
852
+ if (!this.recorderTransferred) try {
853
+ this.recorder.dispose();
854
+ } catch {}
855
+ try {
856
+ Promise.resolve(this.provider.dispose()).catch(() => void 0);
857
+ } catch {}
858
+ this.cycleOwnership.releaseByController();
859
+ if (!this.rawHandedOff) this.acquired?.then(({ stream }) => this.releaseRawStream(stream), () => void 0);
860
+ }
861
+ async acquireRawStream() {
862
+ if (!this.acquired) this.acquired = this.options.acquireCamera(this.provider);
863
+ const result = await this.acquired;
864
+ this.acquiredUsingBackCamera = result.usingBackCamera;
865
+ if (this.released) {
866
+ this.releaseRawStream(result.stream);
867
+ throw new Error("Protected face attempt was released");
868
+ }
869
+ return result;
870
+ }
871
+ async configureWorkflow() {
872
+ await this.provider.initialize({
873
+ autocaptureInterval: this.options.config.onDeviceFaceResultsSubmissionEnabled === true ? ON_DEVICE_MANUAL_CAPTURE_TIMEOUT_MS : this.options.config.autoCaptureTimeout * 1e3,
874
+ useOnDeviceWorkflow: this.options.config.onDeviceFaceResultsSubmissionEnabled === true
875
+ });
876
+ if (this.released) return;
877
+ this.provider.setChecksEnabled({
878
+ lenses: this.options.config.validateLenses ?? false,
879
+ mask: this.options.config.validateFaceMask ?? false,
880
+ closedEyes: this.options.config.validateClosedEyes ?? false,
881
+ headWear: this.options.config.validateHeadCover ?? false,
882
+ occlusion: false
883
+ });
884
+ this.provider.setCallbacks({
885
+ onFarAway: () => this.emitDetection("tooFar"),
886
+ onTooClose: () => this.emitDetection("tooClose"),
887
+ onTooManyFaces: () => this.emitDetection("tooManyFaces"),
888
+ onNoFace: () => this.emitDetection("idle"),
889
+ onCenterFace: () => this.emitDetection("centerFace"),
890
+ onGetReady: () => this.emitDetection("getReady"),
891
+ onGetReadyFinished: () => this.emitDetection("getReadyFinished"),
892
+ onDark: () => {
893
+ if (this.options.config.validateBrightness) this.emitDetection("dark");
894
+ },
895
+ onBlur: () => this.emitDetection("blur"),
896
+ onFaceAngle: () => this.emitDetection("faceAngle"),
897
+ onLenses: () => {
898
+ if (this.options.config.validateLenses) this.emitDetection("lenses");
899
+ },
900
+ onMask: () => {
901
+ if (this.options.config.validateFaceMask) this.emitDetection("faceMask");
902
+ },
903
+ onEyesClosed: () => {
904
+ if (this.options.config.validateClosedEyes) this.emitDetection("eyesClosed");
905
+ },
906
+ onHeadWear: () => {
907
+ if (this.options.config.validateHeadCover) this.emitDetection("headWear");
908
+ },
909
+ onFaceOccluded: () => this.emitDetection("faceOcclusion"),
910
+ onSwitchToManualCapture: () => {
911
+ if (this.options.config.onDeviceFaceResultsSubmissionEnabled !== true) this.emitDetection("manualCapture");
912
+ },
913
+ onCapture: (canvas) => {
914
+ this.emit({
915
+ type: "autoCapture",
916
+ preview: canvas.canvas
917
+ });
918
+ }
919
+ });
920
+ this.emitDetection("detecting");
921
+ }
922
+ async runPrc() {
923
+ if (this.options.delivery === "protected") await this.attachProtectedCameraMetadata();
924
+ if (this.released) return;
925
+ const wasmUtil = await this.options.dependencies.getWasmUtil();
926
+ if (this.released) return;
927
+ await wasmUtil.prc();
928
+ }
929
+ async runPoc() {
930
+ if (this.options.delivery === "local") return;
931
+ const deepsight = this.deepsightService;
932
+ if (!deepsight) throw new Error("Protected face Deepsight is not ready");
933
+ await deepsight.performVirtualCameraCheck(getToken(), "SELFIE");
934
+ if (this.released) return;
935
+ try {
936
+ await deepsight.finalizeProtectedCaptureMetadata();
937
+ } catch {
938
+ trueSightLog("warning", "deepsight", "faceScan", "protected capture metadata finalization failed");
939
+ }
940
+ if (this.released) return;
941
+ try {
942
+ addDeviceStats({
943
+ frontIdStatsAnalysisStatus: "",
944
+ backIdStatsAnalysisStatus: "",
945
+ selfieStatsAnalysisStatus: deepsight.getAnalysisStatus(),
946
+ motionStatus: deepsight.getMotionStatus()
947
+ });
948
+ } catch {}
949
+ const logs = deepsight.getPipelineState();
950
+ this.options.dependencies.trackCaptureAttemptFinished?.({ logs });
951
+ }
952
+ async attachProtectedCameraMetadata() {
953
+ const deepsight = this.deepsightService;
954
+ if (!deepsight) return;
955
+ try {
956
+ const { stream } = await this.acquireRawStream();
957
+ const [videoTrack] = stream.getVideoTracks();
958
+ if (videoTrack) await deepsight.checkVirtualCamera(videoTrack);
959
+ } catch {
960
+ trueSightLog("warning", "deepsight", "faceScan", "protected camera metadata attachment failed");
961
+ }
962
+ }
963
+ emitDetection(status) {
964
+ this.emit({
965
+ type: "detection",
966
+ status
967
+ });
968
+ }
969
+ emit(signal) {
970
+ if (this.released) return;
971
+ if (this.signalListener) this.signalListener(signal);
972
+ else this.pendingSignals.push(signal);
973
+ }
974
+ releaseRawStream(stream) {
975
+ if (this.rawHandedOff || this.rawStreamReleased) return;
976
+ this.rawStreamReleased = true;
977
+ try {
978
+ stopStream(stream);
979
+ } catch {}
980
+ }
981
+ };
982
+ //#endregion
983
+ //#region src/internal/faceCapture/protectedFaceController.ts
984
+ /**
985
+ * Binds one face-machine variant to a fixed native target and delivery mode.
986
+ * The capability-bearing runtime and lifecycle input never leave this callback
987
+ * actor's closure, so parent snapshots contain only presentation/output data.
988
+ */
989
+ function createProtectedFaceControllerActor(options) {
990
+ return fromCallback(({ sendBack, receive }) => {
991
+ let controllerInput;
992
+ let runtime;
993
+ let deepsightService;
994
+ let deepsightState = "idle";
995
+ let signalCleanup;
996
+ let lifecycleCleanup;
997
+ let sendLifecycle;
998
+ let committedPreview;
999
+ let pendingAutoPreview;
1000
+ let recording = {};
1001
+ let generation = 0;
1002
+ let active = true;
1003
+ let diagnosticAttempt = 0;
1004
+ let diagnosticStartedAt;
1005
+ const logDiagnostic = (event, fields = {}) => {
1006
+ if (diagnosticStartedAt === void 0) return;
1007
+ logFaceCameraDiagnostic(event, {
1008
+ attempt: diagnosticAttempt,
1009
+ target: options.target === PROTECTED_CAPTURE_TARGET.authentication ? "authentication" : "selfie",
1010
+ delivery: options.delivery,
1011
+ elapsedMs: Math.round(getTimestamp() - diagnosticStartedAt),
1012
+ ...fields
1013
+ });
1014
+ };
1015
+ const getControllerInput = () => {
1016
+ if (!controllerInput) throw new Error("Protected face controller is not bound");
1017
+ return controllerInput;
1018
+ };
1019
+ const ensureRuntime = () => {
1020
+ if (!runtime) {
1021
+ const input = getControllerInput();
1022
+ const capabilities = options.createCapabilities();
1023
+ runtime = new ProtectedFaceAttemptRuntime({
1024
+ config: input.config,
1025
+ dependencies: input.dependencies,
1026
+ target: options.target,
1027
+ delivery: options.delivery,
1028
+ authHint: input.authHint,
1029
+ faceDetection: capabilities.faceDetection,
1030
+ cycle: capabilities.cycle,
1031
+ acquireCamera: (provider) => initializeCamera({
1032
+ config: input.config,
1033
+ provider
1034
+ })
1035
+ });
1036
+ if (deepsightService) runtime.setDeepsightService(deepsightService);
1037
+ }
1038
+ return runtime;
1039
+ };
1040
+ const releaseCurrent = (reason) => {
1041
+ logDiagnostic("attempt-release", { releaseReason: reason });
1042
+ diagnosticStartedAt = void 0;
1043
+ generation += 1;
1044
+ signalCleanup?.();
1045
+ signalCleanup = void 0;
1046
+ sendLifecycle?.({
1047
+ type: "RELEASE",
1048
+ reason
1049
+ });
1050
+ sendLifecycle = void 0;
1051
+ lifecycleCleanup?.();
1052
+ lifecycleCleanup = void 0;
1053
+ runtime?.release();
1054
+ runtime = void 0;
1055
+ try {
1056
+ deepsightService?.cleanup();
1057
+ } catch {}
1058
+ deepsightService = void 0;
1059
+ deepsightState = "idle";
1060
+ committedPreview = void 0;
1061
+ pendingAutoPreview = void 0;
1062
+ recording = {};
1063
+ };
1064
+ const initializeDeepsight = () => {
1065
+ if (deepsightState === "ready") {
1066
+ sendBack({ type: "PROTECTED_DEEPSIGHT_READY" });
1067
+ return;
1068
+ }
1069
+ if (deepsightState === "initializing") return;
1070
+ deepsightState = "initializing";
1071
+ const input = getControllerInput();
1072
+ const ownerGeneration = generation;
1073
+ options.initializeDeepsight({
1074
+ ds: input.config.ds,
1075
+ storage: input.dependencies.storage
1076
+ }).then((service) => {
1077
+ if (!active || generation !== ownerGeneration) {
1078
+ try {
1079
+ service.cleanup();
1080
+ } catch {}
1081
+ return;
1082
+ }
1083
+ deepsightService = service;
1084
+ deepsightState = "ready";
1085
+ runtime?.setDeepsightService(service);
1086
+ sendBack({ type: "PROTECTED_DEEPSIGHT_READY" });
1087
+ const preview = pendingAutoPreview;
1088
+ pendingAutoPreview = void 0;
1089
+ if (preview) queueMicrotask(() => {
1090
+ if (active && generation === ownerGeneration) sendBack({
1091
+ type: "PROTECTED_NATIVE_AUTO_CAPTURE",
1092
+ preview
1093
+ });
1094
+ });
1095
+ }, () => {
1096
+ if (!active || generation !== ownerGeneration) return;
1097
+ deepsightState = "failed";
1098
+ sendBack({ type: "PROTECTED_DEEPSIGHT_FAILED" });
1099
+ }).finally(() => {
1100
+ if (generation === ownerGeneration) {}
1101
+ });
1102
+ };
1103
+ const finalizeLocalCapture = async (owner, ownerGeneration) => {
1104
+ const preview = committedPreview;
1105
+ if (!preview) throw new Error("selfieCaptureOnly: no captured image");
1106
+ let metadata = "";
1107
+ try {
1108
+ metadata = deepsightService?.getMetadata() ?? "";
1109
+ } catch {
1110
+ metadata = "";
1111
+ }
1112
+ const canvas = new IncodeCanvas(preview);
1113
+ const blobData = canvas.getBlobData();
1114
+ if (!blobData) throw new Error("selfieCaptureOnly: failed to build image blob");
1115
+ const result = {
1116
+ imageBase64: canvas.getBase64Image() ?? "",
1117
+ blob: blobData.blob,
1118
+ url: blobData.url,
1119
+ metadata,
1120
+ videoBase64: owner.takeCaptureOnlyVideo()
1121
+ };
1122
+ if (active && runtime === owner && generation === ownerGeneration) {
1123
+ sendBack({
1124
+ type: "PROTECTED_LOCAL_DONE",
1125
+ attemptId: owner.attemptId,
1126
+ result
1127
+ });
1128
+ logDiagnostic("upload-complete");
1129
+ }
1130
+ };
1131
+ const forwardLifecycleEvent = (event, owner, ownerGeneration) => {
1132
+ if (!active || runtime !== owner || generation !== ownerGeneration) return;
1133
+ switch (event.type) {
1134
+ case "PROTECTED_ATTEMPT_READY":
1135
+ logDiagnostic("camera-ready");
1136
+ sendBack({
1137
+ ...event,
1138
+ usingBackCamera: owner.usingBackCamera
1139
+ });
1140
+ return;
1141
+ case "PROTECTED_AUTO_COMMITTED":
1142
+ case "PROTECTED_MANUAL_COMMITTED":
1143
+ logDiagnostic("capture-selected", { captureKind: event.type === "PROTECTED_AUTO_COMMITTED" ? "auto" : "manual" });
1144
+ committedPreview = event.preview;
1145
+ sendBack(event);
1146
+ return;
1147
+ case "PROTECTED_ATTEMPT_FINALIZED":
1148
+ logDiagnostic("attempt-finalized");
1149
+ recording = event.recording;
1150
+ sendBack(event);
1151
+ return;
1152
+ case "PROTECTED_UPLOAD_DONE":
1153
+ if (event.result.kind === "id") {
1154
+ sendBack({
1155
+ type: "PROTECTED_ATTEMPT_FAILED",
1156
+ attemptId: event.attemptId,
1157
+ failure: {
1158
+ stage: "upload",
1159
+ code: "protected-attempt-unexpected-result"
1160
+ }
1161
+ });
1162
+ return;
1163
+ }
1164
+ sendBack({
1165
+ type: "PROTECTED_UPLOAD_MAPPED",
1166
+ attemptId: event.attemptId,
1167
+ response: owner.mapProtectedResult(event.result)
1168
+ });
1169
+ logDiagnostic("upload-complete");
1170
+ return;
1171
+ case "PROTECTED_ATTEMPT_FAILED":
1172
+ logDiagnostic("attempt-failed", {
1173
+ failureStage: event.failure.stage,
1174
+ failureCode: event.failure.code
1175
+ });
1176
+ sendBack(event);
1177
+ return;
1178
+ default: sendBack(event);
1179
+ }
1180
+ };
1181
+ const start = (visible) => {
1182
+ if (lifecycleCleanup) {
1183
+ sendLifecycle?.({ type: visible ? "FOREGROUND" : "BACKGROUND" });
1184
+ return;
1185
+ }
1186
+ const owner = ensureRuntime();
1187
+ diagnosticAttempt += 1;
1188
+ diagnosticStartedAt = getTimestamp();
1189
+ logDiagnostic("attempt-start");
1190
+ const ownerGeneration = generation;
1191
+ signalCleanup = owner.subscribeSignals((signal) => {
1192
+ if (!active || runtime !== owner || generation !== ownerGeneration) return;
1193
+ if (signal.type === "detection") {
1194
+ sendBack({
1195
+ type: "DETECTION_UPDATE",
1196
+ status: signal.status
1197
+ });
1198
+ return;
1199
+ }
1200
+ if (deepsightState === "ready") sendBack({
1201
+ type: "PROTECTED_NATIVE_AUTO_CAPTURE",
1202
+ preview: signal.preview
1203
+ });
1204
+ else pendingAutoPreview ??= signal.preview;
1205
+ });
1206
+ lifecycleCleanup = runProtectedAttempt({
1207
+ input: owner.toActorInput((timing) => {
1208
+ logDiagnostic("camera-startup", timing);
1209
+ }),
1210
+ sendBack: (event) => forwardLifecycleEvent(event, owner, ownerGeneration),
1211
+ receive: (listener) => {
1212
+ sendLifecycle = listener;
1213
+ }
1214
+ });
1215
+ sendLifecycle?.({ type: visible ? "FOREGROUND" : "BACKGROUND" });
1216
+ };
1217
+ receive((command) => {
1218
+ if (command.type === "BIND_PROTECTED_FACE_CONTROLLER") {
1219
+ controllerInput ??= command.input;
1220
+ return;
1221
+ }
1222
+ switch (command.type) {
1223
+ case "INITIALIZE_DEEPSIGHT":
1224
+ initializeDeepsight();
1225
+ return;
1226
+ case "PRE_ACQUIRE": {
1227
+ const owner = ensureRuntime();
1228
+ const ownerGeneration = generation;
1229
+ owner.preAcquire().then(() => {
1230
+ if (active && runtime === owner && generation === ownerGeneration) sendBack({
1231
+ type: "PROTECTED_PRE_ACQUIRE_DONE",
1232
+ usingBackCamera: owner.usingBackCamera
1233
+ });
1234
+ }, (error) => {
1235
+ if (active && runtime === owner && generation === ownerGeneration) sendBack({
1236
+ type: "PROTECTED_PRE_ACQUIRE_FAILED",
1237
+ error
1238
+ });
1239
+ });
1240
+ return;
1241
+ }
1242
+ case "START":
1243
+ start(command.visible);
1244
+ return;
1245
+ case "AUTO_CAPTURED":
1246
+ case "MANUAL_CAPTURE":
1247
+ case "FINALIZE":
1248
+ if (deepsightState !== "ready") return;
1249
+ sendLifecycle?.(command);
1250
+ return;
1251
+ case "BACKGROUND":
1252
+ case "FOREGROUND":
1253
+ sendLifecycle?.(command);
1254
+ return;
1255
+ case "UPLOAD": {
1256
+ const owner = runtime;
1257
+ if (!owner) return;
1258
+ logDiagnostic("upload-start");
1259
+ if (options.delivery === "protected") {
1260
+ sendLifecycle?.(owner.createUploadCommand(recording.recordingId));
1261
+ return;
1262
+ }
1263
+ finalizeLocalCapture(owner, generation).catch(() => {
1264
+ if (active && runtime === owner) sendBack({
1265
+ type: "PROTECTED_ATTEMPT_FAILED",
1266
+ attemptId: owner.attemptId,
1267
+ failure: {
1268
+ stage: "upload",
1269
+ code: "protected-attempt-local-finalize-failed"
1270
+ }
1271
+ });
1272
+ });
1273
+ return;
1274
+ }
1275
+ case "RESET":
1276
+ releaseCurrent("retry");
1277
+ return;
1278
+ case "RELEASE": releaseCurrent(command.reason);
1279
+ }
1280
+ });
1281
+ return () => {
1282
+ active = false;
1283
+ releaseCurrent("externalStop");
1284
+ };
1285
+ });
1286
+ }
1287
+ //#endregion
1288
+ //#region src/internal/faceCapture/protectedFaceComposition.ts
1289
+ /**
1290
+ * Private composition root for protected still-face variants. Provider
1291
+ * construction remains in Infra; the controller receives only capability
1292
+ * interfaces/factories and owns them in its callback closure.
1293
+ */
1294
+ function createDefaultProtectedFaceControllerActor(options) {
1295
+ return createProtectedFaceControllerActor({
1296
+ ...options,
1297
+ createCapabilities: createProtectedFaceCaptureCapabilities,
1298
+ initializeDeepsight: initializeDeepsightSession
1299
+ });
1300
+ }
1301
+ //#endregion
1302
+ //#region src/internal/faceCapture/faceCaptureSetup.ts
1303
+ const getAttemptsFromConfig = (config) => {
1304
+ return config.captureAttempts ?? config.numberOfAttempts ?? 3;
1305
+ };
1306
+ /**
1307
+ * The protected face controller is invoked at the machine root, so a started
1308
+ * machine has it for its whole lifetime and every guarded send below behaves
1309
+ * like a plain `sendTo`. Harnesses that start the machine from a resolved
1310
+ * snapshot carry no children (the Storybook state stories seed managers that
1311
+ * way), and XState throws on a send to a missing actor, so each send checks
1312
+ * for the controller first.
1313
+ *
1314
+ * Only sends that run after the machine has started may use this guard. A
1315
+ * root `entry` action runs inside the initial transition, before the actor
1316
+ * has a committed snapshot; XState delivers a plain `sendTo` from there
1317
+ * through its deferred-actor path, whereas this check cannot see the child
1318
+ * yet and would skip the send.
1319
+ */
1320
+ function isProtectedFaceControllerRunning(self) {
1321
+ return self.getSnapshot()?.children?.["protectedFaceController"] !== void 0;
1322
+ }
1323
+ const faceCaptureMachine = setup({
1324
+ types: {
1325
+ context: {},
1326
+ events: {},
1327
+ input: {}
1328
+ },
1329
+ actors: {
1330
+ checkPermission: fromPromise(async () => {
1331
+ return checkPermission();
1332
+ }),
1333
+ requestPermission: fromPromise(async ({ input }) => {
1334
+ return invokeRequestPermissionActor(input);
1335
+ }),
1336
+ protectedFaceController: createDefaultProtectedFaceControllerActor({
1337
+ target: PROTECTED_CAPTURE_TARGET.selfie,
1338
+ delivery: "protected"
1339
+ }),
1340
+ runAvatar: fromCallback(({ input, sendBack }) => {
1341
+ const { obfuscateWithAvatar, avatarVariant } = concealmentToAvatar(input.config.selfieConcealmentOption);
1342
+ if (!obfuscateWithAvatar || !input.stream) return () => {};
1343
+ const stream = input.stream;
1344
+ const variant = avatarVariant ?? "avatar-3d";
1345
+ let handle = null;
1346
+ let cancelled = false;
1347
+ (async () => {
1348
+ try {
1349
+ const created = await createFaceAvatar({
1350
+ variant,
1351
+ stream,
1352
+ assets: input.config.avatarAssets
1353
+ });
1354
+ if (cancelled) {
1355
+ created.stop();
1356
+ return;
1357
+ }
1358
+ handle = created;
1359
+ sendBack({
1360
+ type: "AVATAR_READY",
1361
+ canvas: created.canvas
1362
+ });
1363
+ } catch (err) {
1364
+ console.warn("[face-avatar] failed to start avatar overlay", err);
1365
+ }
1366
+ })();
1367
+ return () => {
1368
+ cancelled = true;
1369
+ handle?.stop();
1370
+ };
1371
+ }),
1372
+ manualUploadMachine: manualFaceUploadMachine,
1373
+ prepareFaceUpload: fromPromise(async () => {
1374
+ throw new Error("prepareFaceUpload must be provided by variant");
1375
+ }),
1376
+ uploadFace: fromPromise(async () => new Promise(() => {})),
1377
+ processFace: fromPromise(async () => {
1378
+ throw new Error("processFace must be provided by variant");
1379
+ })
1380
+ },
1381
+ actions: {
1382
+ bindProtectedFaceController: sendTo("protectedFaceController", ({ context }) => ({
1383
+ type: "BIND_PROTECTED_FACE_CONTROLLER",
1384
+ input: {
1385
+ config: context.config,
1386
+ dependencies: context.dependencies,
1387
+ authHint: context.authHint
1388
+ }
1389
+ })),
1390
+ stopMediaStream: assign(() => {
1391
+ return {
1392
+ stream: void 0,
1393
+ avatarCanvas: void 0,
1394
+ usingBackCamera: false
1395
+ };
1396
+ }),
1397
+ setCameraPreAcquired: assign({ usingBackCamera: ({ event }) => event.usingBackCamera }),
1398
+ trackTutorial: () => void 0,
1399
+ trackContinue: () => {},
1400
+ resetContext: assign(({ context }) => {
1401
+ return {
1402
+ stream: void 0,
1403
+ usingBackCamera: false,
1404
+ error: void 0,
1405
+ detectionStatus: "idle",
1406
+ capturedImage: void 0,
1407
+ faceCoordinates: void 0,
1408
+ uploadResponse: void 0,
1409
+ processResponse: void 0,
1410
+ attemptsRemaining: getAttemptsFromConfig(context.config),
1411
+ uploadError: void 0,
1412
+ permissionResult: void 0,
1413
+ deepsightReady: false,
1414
+ manualCaptureTriggered: false,
1415
+ captureOnlyResult: void 0,
1416
+ avatarCanvas: void 0
1417
+ };
1418
+ }),
1419
+ clearUploadFailure: assign({
1420
+ uploadError: () => void 0,
1421
+ detectionStatus: () => "idle",
1422
+ capturedImage: () => void 0
1423
+ }),
1424
+ clearProtectedAttempt: assign(() => {
1425
+ return {
1426
+ stream: void 0,
1427
+ avatarCanvas: void 0,
1428
+ usingBackCamera: false
1429
+ };
1430
+ }),
1431
+ decrementAttemptsRemaining: assign(({ context }) => ({ attemptsRemaining: context.attemptsRemaining - 1 })),
1432
+ setUploadErrorFromUploadValidation: assign({ uploadError: () => FACE_ERROR_CODES.SERVER }),
1433
+ setTerminalError: assign({ error: () => "Authentication failed" }),
1434
+ cleanup: () => void 0,
1435
+ setPermissionResultFromEvent: assign({ permissionResult: ({ event }) => event.output }),
1436
+ setPermissionDenied: assign({ permissionResult: () => "denied" }),
1437
+ setPermissionPrompt: assign({ permissionResult: () => "prompt" }),
1438
+ setPermissionRefresh: assign({ permissionResult: () => "refresh" }),
1439
+ setDeepsightReady: assign({ deepsightReady: () => true }),
1440
+ setDeepsightNotReady: assign({ deepsightReady: () => false }),
1441
+ setErrorFromEvent: assign({ error: ({ event }) => String(event.error) }),
1442
+ setDetectionStatusDetecting: assign({ detectionStatus: ({ context }) => context.manualCaptureTriggered ? "manualCapture" : "detecting" }),
1443
+ setDetectionStatusFromEvent: assign({ detectionStatus: ({ event }) => event.status }),
1444
+ setManualCaptureTriggered: assign({ manualCaptureTriggered: ({ context, event }) => {
1445
+ const status = event.status;
1446
+ return context.manualCaptureTriggered || status === "manualCapture";
1447
+ } }),
1448
+ setAvatarCanvas: assign({ avatarCanvas: ({ event }) => event.canvas }),
1449
+ clearAvatarCanvas: assign({ avatarCanvas: () => void 0 }),
1450
+ setCapturedImageFromEvent: assign({
1451
+ capturedImage: ({ event }) => event.canvas,
1452
+ faceCoordinates: ({ event }) => event.faceCoordinates
1453
+ }),
1454
+ setProtectedAttemptReady: assign({
1455
+ stream: ({ event }) => event.displayStream,
1456
+ usingBackCamera: ({ event }) => event.usingBackCamera
1457
+ }),
1458
+ setProtectedCommittedPreview: assign({
1459
+ capturedImage: ({ event }) => new IncodeCanvas(event.preview),
1460
+ faceCoordinates: () => void 0,
1461
+ detectionStatus: () => "success"
1462
+ }),
1463
+ setProtectedFinalization: assign({
1464
+ uploadRecordingId: ({ event }) => event.recording.recordingId ?? null,
1465
+ stream: ({ context, event }) => event.displayStream ?? context.stream
1466
+ }),
1467
+ setProtectedUploadResponse: assign({ uploadResponse: ({ event }) => event.response }),
1468
+ setProtectedLocalResult: assign({ captureOnlyResult: ({ event }) => event.result }),
1469
+ setProtectedFailure: assign({ error: ({ event }) => event.failure.code }),
1470
+ setProtectedVisibility: assign({ protectedVisible: ({ event }) => event.visible }),
1471
+ setUploadPreparationFromEvent: assign({
1472
+ encryptedBase64Image: ({ event }) => event.output.encryptedBase64Image,
1473
+ uploadRecordingId: ({ event }) => event.output.recordingId
1474
+ }),
1475
+ setUploadResponseFromEvent: assign({ uploadResponse: ({ event }) => event.output }),
1476
+ setProcessResponseFromEvent: assign({ processResponse: ({ event }) => event.output }),
1477
+ setServerErrorAndDecrement: assign(({ context }) => ({
1478
+ uploadError: FACE_ERROR_CODES.SERVER,
1479
+ attemptsRemaining: context.attemptsRemaining - 1
1480
+ })),
1481
+ sendLabelInspection: () => {
1482
+ sendLabelInspectionEvent();
1483
+ },
1484
+ flagFaceManualReview: () => {
1485
+ flagFaceManualReview();
1486
+ },
1487
+ preloadRecordingProvider: () => void 0,
1488
+ warmAvatarProvider: ({ context }) => {
1489
+ const { obfuscateWithAvatar, avatarVariant } = concealmentToAvatar(context.config.selfieConcealmentOption);
1490
+ if (!obfuscateWithAvatar || !avatarVariant) return;
1491
+ warmFaceAvatar({
1492
+ variant: avatarVariant,
1493
+ assets: context.config.avatarAssets
1494
+ });
1495
+ },
1496
+ releaseAvatarWarmup: () => {
1497
+ releaseFaceAvatarWarmup();
1498
+ },
1499
+ noOp: () => void 0,
1500
+ forwardToManualUpload: sendTo("manualUpload", ({ event }) => event),
1501
+ sendProtectedPreAcquire: enqueueActions(({ enqueue, self }) => {
1502
+ if (!isProtectedFaceControllerRunning(self)) return;
1503
+ enqueue.sendTo("protectedFaceController", { type: "PRE_ACQUIRE" });
1504
+ }),
1505
+ startProtectedAttempt: enqueueActions(({ enqueue, self, context }) => {
1506
+ if (!isProtectedFaceControllerRunning(self)) return;
1507
+ enqueue.sendTo("protectedFaceController", {
1508
+ type: "START",
1509
+ visible: context.protectedVisible
1510
+ });
1511
+ }),
1512
+ initializeProtectedDeepsight: enqueueActions(({ enqueue, self }) => {
1513
+ if (!isProtectedFaceControllerRunning(self)) return;
1514
+ enqueue.sendTo("protectedFaceController", { type: "INITIALIZE_DEEPSIGHT" });
1515
+ }),
1516
+ resetProtectedController: enqueueActions(({ enqueue, self }) => {
1517
+ if (!isProtectedFaceControllerRunning(self)) return;
1518
+ enqueue.sendTo("protectedFaceController", { type: "RESET" });
1519
+ }),
1520
+ sendProtectedAutoCapture: enqueueActions(({ enqueue, self, event }) => {
1521
+ if (!isProtectedFaceControllerRunning(self)) return;
1522
+ enqueue.sendTo("protectedFaceController", {
1523
+ type: "AUTO_CAPTURED",
1524
+ preview: event.preview
1525
+ });
1526
+ }),
1527
+ sendProtectedManualCapture: enqueueActions(({ enqueue, self }) => {
1528
+ if (!isProtectedFaceControllerRunning(self)) return;
1529
+ enqueue.sendTo("protectedFaceController", { type: "MANUAL_CAPTURE" });
1530
+ }),
1531
+ sendProtectedFinalize: enqueueActions(({ enqueue, self }) => {
1532
+ if (!isProtectedFaceControllerRunning(self)) return;
1533
+ enqueue.sendTo("protectedFaceController", { type: "FINALIZE" });
1534
+ }),
1535
+ sendProtectedUploadIfNeeded: enqueueActions(({ enqueue, self }) => {
1536
+ if (!isProtectedFaceControllerRunning(self)) return;
1537
+ enqueue.sendTo("protectedFaceController", { type: "UPLOAD" });
1538
+ }),
1539
+ sendProtectedVisibility: enqueueActions(({ enqueue, self, event }) => {
1540
+ if (!isProtectedFaceControllerRunning(self)) return;
1541
+ enqueue.sendTo("protectedFaceController", { type: event.visible ? "FOREGROUND" : "BACKGROUND" });
1542
+ }),
1543
+ releaseProtectedAttempt: enqueueActions(({ enqueue, self, event }) => {
1544
+ if (!isProtectedFaceControllerRunning(self)) return;
1545
+ enqueue.sendTo("protectedFaceController", {
1546
+ type: "RELEASE",
1547
+ reason: event.reason ?? "externalStop"
1548
+ });
1549
+ })
1550
+ },
1551
+ guards: {
1552
+ hasShowTutorial: ({ context }) => context.config.showTutorial,
1553
+ hasAgeAssurance: ({ context }) => context.config.ageAssurance === true,
1554
+ hasManualUploadEnabled: () => false,
1555
+ isManualUploadExhausted: ({ event }) => event.output?.result === "exhausted",
1556
+ isPermissionGranted: ({ event }) => {
1557
+ if ("output" in event) return event.output === "granted";
1558
+ return false;
1559
+ },
1560
+ isReadyForCapture: ({ context, event }) => {
1561
+ return isReadyForCaptureFromPermission(resolveStoredPermissionResult("output" in event ? event.output : void 0, context.permissionResult), context.config.ds);
1562
+ },
1563
+ needsMotionPrimeOnly: ({ context, event }) => {
1564
+ return needsMotionPrimeOnlyFromPermission(resolveStoredPermissionResult("output" in event ? event.output : void 0, context.permissionResult), context.config.ds);
1565
+ },
1566
+ isPermissionDeniedError: ({ event }) => {
1567
+ if ("error" in event) {
1568
+ const error = event.error;
1569
+ return error?.name === "NotAllowedError" || error?.name === "PermissionDeniedError";
1570
+ }
1571
+ return false;
1572
+ },
1573
+ hasStream: ({ context }) => context.stream !== void 0,
1574
+ isCameraAndDeepsightReady: ({ context }) => context.stream !== void 0 && context.deepsightReady,
1575
+ hasAttemptsRemaining: ({ context }) => context.attemptsRemaining > 0,
1576
+ hasCapturedImage: ({ context }) => context.capturedImage !== void 0,
1577
+ canCommitProtectedManual: ({ context }) => context.manualCaptureTriggered && context.config.onDeviceFaceResultsSubmissionEnabled !== true,
1578
+ isProtectedManualRefusal: ({ event }) => event.failure.stage === "manualCommit",
1579
+ isProtectedUploadFailure: ({ event }) => event.failure.stage === "upload",
1580
+ hasUploadValidationError: () => false,
1581
+ isTerminalUploadError: () => false,
1582
+ isNoAttemptsTerminal: () => false
1583
+ }
1584
+ }).createMachine({
1585
+ id: "faceCapture",
1586
+ initial: "idle",
1587
+ entry: "bindProtectedFaceController",
1588
+ context: ({ input }) => ({
1589
+ config: input.config,
1590
+ dependencies: input.dependencies,
1591
+ authHint: input.authHint,
1592
+ stream: void 0,
1593
+ usingBackCamera: false,
1594
+ error: void 0,
1595
+ detectionStatus: "idle",
1596
+ capturedImage: void 0,
1597
+ faceCoordinates: void 0,
1598
+ uploadResponse: void 0,
1599
+ processResponse: void 0,
1600
+ attemptsRemaining: getAttemptsFromConfig(input.config),
1601
+ uploadError: void 0,
1602
+ permissionResult: void 0,
1603
+ deepsightReady: false,
1604
+ encryptedBase64Image: void 0,
1605
+ uploadRecordingId: void 0,
1606
+ manualCaptureTriggered: false,
1607
+ captureOnlyResult: void 0,
1608
+ avatarCanvas: void 0,
1609
+ faceFeed: void 0,
1610
+ protectedVisible: true
1611
+ }),
1612
+ invoke: {
1613
+ id: "protectedFaceController",
1614
+ src: "protectedFaceController"
1615
+ },
1616
+ on: {
1617
+ QUIT: { target: "#faceCapture.closed" },
1618
+ PROTECTED_VISIBILITY: { actions: "setProtectedVisibility" },
1619
+ PROTECTED_DEEPSIGHT_READY: { actions: "setDeepsightReady" },
1620
+ PROTECTED_DEEPSIGHT_FAILED: { actions: "setDeepsightNotReady" }
1621
+ },
1622
+ states: {
1623
+ idle: { on: { LOAD: [
1624
+ {
1625
+ target: "tutorial",
1626
+ guard: "hasShowTutorial"
1627
+ },
1628
+ {
1629
+ target: "tutorial",
1630
+ guard: "hasAgeAssurance"
1631
+ },
1632
+ { target: "loading" }
1633
+ ] } },
1634
+ loading: {
1635
+ entry: [
1636
+ "preloadRecordingProvider",
1637
+ "warmAvatarProvider",
1638
+ "initializeProtectedDeepsight"
1639
+ ],
1640
+ invoke: {
1641
+ id: "checkPermissionLoading",
1642
+ src: "checkPermission",
1643
+ onDone: [{
1644
+ target: "capture",
1645
+ guard: "isReadyForCapture",
1646
+ actions: "setPermissionResultFromEvent"
1647
+ }, {
1648
+ target: "permissions",
1649
+ actions: "setPermissionResultFromEvent"
1650
+ }]
1651
+ }
1652
+ },
1653
+ tutorial: {
1654
+ initial: "checkingPermission",
1655
+ entry: [
1656
+ "trackTutorial",
1657
+ "preloadRecordingProvider",
1658
+ "warmAvatarProvider"
1659
+ ],
1660
+ on: { GO_TO_MANUAL_UPLOAD: {
1661
+ guard: "hasManualUploadEnabled",
1662
+ target: "#faceCapture.manualUpload"
1663
+ } },
1664
+ states: {
1665
+ checkingPermission: { invoke: {
1666
+ id: "checkPermissionTutorial",
1667
+ src: "checkPermission",
1668
+ onDone: [{
1669
+ target: "initializingCamera",
1670
+ guard: "isReadyForCapture",
1671
+ actions: "setPermissionResultFromEvent"
1672
+ }, {
1673
+ target: "ready",
1674
+ actions: "setPermissionResultFromEvent"
1675
+ }]
1676
+ } },
1677
+ initializingCamera: {
1678
+ type: "parallel",
1679
+ states: {
1680
+ cameraInit: {
1681
+ initial: "initializingDeepsight",
1682
+ states: {
1683
+ initializingDeepsight: {
1684
+ entry: "initializeProtectedDeepsight",
1685
+ on: {
1686
+ PROTECTED_DEEPSIGHT_READY: {
1687
+ target: "initializingStream",
1688
+ actions: "setDeepsightReady"
1689
+ },
1690
+ PROTECTED_DEEPSIGHT_FAILED: {
1691
+ target: "#faceCapture.tutorial.ready",
1692
+ actions: "setDeepsightNotReady"
1693
+ }
1694
+ }
1695
+ },
1696
+ initializingStream: {
1697
+ entry: "sendProtectedPreAcquire",
1698
+ on: {
1699
+ PROTECTED_PRE_ACQUIRE_DONE: {
1700
+ target: "ready",
1701
+ actions: "setCameraPreAcquired"
1702
+ },
1703
+ PROTECTED_PRE_ACQUIRE_FAILED: [{
1704
+ target: "#faceCapture.tutorial.ready",
1705
+ guard: "isPermissionDeniedError",
1706
+ actions: "setPermissionDenied"
1707
+ }, {
1708
+ target: "#faceCapture.tutorial.ready",
1709
+ actions: "setErrorFromEvent"
1710
+ }]
1711
+ }
1712
+ },
1713
+ ready: { type: "final" }
1714
+ }
1715
+ },
1716
+ userIntent: {
1717
+ initial: "waiting",
1718
+ states: {
1719
+ waiting: { on: { NEXT_STEP: {
1720
+ target: "clicked",
1721
+ actions: "trackContinue"
1722
+ } } },
1723
+ clicked: { type: "final" }
1724
+ }
1725
+ }
1726
+ },
1727
+ onDone: { target: "#faceCapture.capture" }
1728
+ },
1729
+ ready: {
1730
+ initial: "idle",
1731
+ states: {
1732
+ idle: { always: [{
1733
+ target: "initializingDeepsight",
1734
+ guard: ({ context }) => !context.deepsightReady
1735
+ }, { target: "readyForNext" }] },
1736
+ initializingDeepsight: {
1737
+ entry: "initializeProtectedDeepsight",
1738
+ on: {
1739
+ PROTECTED_DEEPSIGHT_READY: {
1740
+ target: "readyForNext",
1741
+ actions: "setDeepsightReady"
1742
+ },
1743
+ PROTECTED_DEEPSIGHT_FAILED: {
1744
+ target: "readyForNext",
1745
+ actions: "setDeepsightNotReady"
1746
+ }
1747
+ }
1748
+ },
1749
+ readyForNext: { on: { NEXT_STEP: {
1750
+ target: "#faceCapture.tutorial.waitingForPermission",
1751
+ actions: "trackContinue"
1752
+ } } }
1753
+ }
1754
+ },
1755
+ waitingForPermission: { invoke: {
1756
+ id: "checkPermissionWaiting",
1757
+ src: "checkPermission",
1758
+ onDone: [
1759
+ {
1760
+ target: "#faceCapture.capture",
1761
+ guard: "isReadyForCapture",
1762
+ actions: "setPermissionResultFromEvent"
1763
+ },
1764
+ {
1765
+ target: "#faceCapture.permissions.requesting",
1766
+ guard: "needsMotionPrimeOnly",
1767
+ actions: "setPermissionResultFromEvent"
1768
+ },
1769
+ {
1770
+ target: "#faceCapture.permissions",
1771
+ actions: "setPermissionResultFromEvent"
1772
+ }
1773
+ ]
1774
+ } }
1775
+ }
1776
+ },
1777
+ permissions: {
1778
+ entry: [
1779
+ "preloadRecordingProvider",
1780
+ "warmAvatarProvider",
1781
+ "initializeProtectedDeepsight"
1782
+ ],
1783
+ initial: "checkingDeepsight",
1784
+ states: {
1785
+ checkingDeepsight: { always: [{
1786
+ target: "initializingDeepsight",
1787
+ guard: ({ context }) => !context.deepsightReady
1788
+ }, { target: "idle" }] },
1789
+ initializingDeepsight: {
1790
+ entry: "initializeProtectedDeepsight",
1791
+ on: {
1792
+ PROTECTED_DEEPSIGHT_READY: {
1793
+ target: "idle",
1794
+ actions: "setDeepsightReady"
1795
+ },
1796
+ PROTECTED_DEEPSIGHT_FAILED: {
1797
+ target: "idle",
1798
+ actions: "setDeepsightNotReady"
1799
+ }
1800
+ }
1801
+ },
1802
+ idle: {
1803
+ invoke: {
1804
+ id: "checkPermissionIdle",
1805
+ src: "checkPermission",
1806
+ onDone: [
1807
+ {
1808
+ target: "#faceCapture.capture",
1809
+ guard: "isReadyForCapture",
1810
+ actions: "setPermissionResultFromEvent"
1811
+ },
1812
+ {
1813
+ target: "denied",
1814
+ guard: ({ event }) => event.output === "denied",
1815
+ actions: "setPermissionResultFromEvent"
1816
+ },
1817
+ {
1818
+ target: "motionOnly",
1819
+ guard: "needsMotionPrimeOnly",
1820
+ actions: "setPermissionResultFromEvent"
1821
+ },
1822
+ {
1823
+ target: "waitingForUser",
1824
+ actions: "setPermissionResultFromEvent"
1825
+ }
1826
+ ],
1827
+ onError: {
1828
+ target: "waitingForUser",
1829
+ actions: "setPermissionPrompt"
1830
+ }
1831
+ },
1832
+ on: {
1833
+ REQUEST_PERMISSION: "requesting",
1834
+ GO_TO_LEARN_MORE: "learnMore"
1835
+ }
1836
+ },
1837
+ waitingForUser: { on: {
1838
+ REQUEST_PERMISSION: "requesting",
1839
+ GO_TO_LEARN_MORE: "learnMore"
1840
+ } },
1841
+ motionOnly: { on: { REQUEST_PERMISSION: "requesting" } },
1842
+ learnMore: { on: {
1843
+ BACK: "idle",
1844
+ REQUEST_PERMISSION: "requesting"
1845
+ } },
1846
+ requesting: { invoke: {
1847
+ id: "requestPermission",
1848
+ src: "requestPermission",
1849
+ input: ({ context }) => ({
1850
+ permissionResult: context.permissionResult === "refresh" ? void 0 : context.permissionResult,
1851
+ requestMotionPermission: context.config.ds === true
1852
+ }),
1853
+ onDone: [
1854
+ {
1855
+ target: "#faceCapture.capture",
1856
+ guard: "isReadyForCapture",
1857
+ actions: "setPermissionResultFromEvent"
1858
+ },
1859
+ {
1860
+ target: "denied",
1861
+ guard: ({ event }) => event.output === "denied",
1862
+ actions: "setPermissionResultFromEvent"
1863
+ },
1864
+ {
1865
+ target: "waitingForUser",
1866
+ actions: "setPermissionResultFromEvent"
1867
+ }
1868
+ ],
1869
+ onError: { target: "denied" }
1870
+ } },
1871
+ denied: { entry: "setPermissionRefresh" }
1872
+ }
1873
+ },
1874
+ capture: {
1875
+ entry: [
1876
+ "preloadRecordingProvider",
1877
+ "warmAvatarProvider",
1878
+ "initializeProtectedDeepsight",
1879
+ "startProtectedAttempt"
1880
+ ],
1881
+ initial: "checkingDeepsight",
1882
+ exit: [
1883
+ "releaseProtectedAttempt",
1884
+ "stopMediaStream",
1885
+ "cleanup"
1886
+ ],
1887
+ on: {
1888
+ PROTECTED_ATTEMPT_READY: { actions: "setProtectedAttemptReady" },
1889
+ PROTECTED_VISIBILITY: { actions: ["setProtectedVisibility", "sendProtectedVisibility"] },
1890
+ PROTECTED_APPLY_VISIBILITY: { actions: "sendProtectedVisibility" },
1891
+ PROTECTED_ATTEMPT_FAILED: [
1892
+ {
1893
+ target: ".detecting",
1894
+ guard: "isProtectedManualRefusal"
1895
+ },
1896
+ {
1897
+ target: ".uploadError",
1898
+ guard: "isProtectedUploadFailure",
1899
+ actions: "setServerErrorAndDecrement"
1900
+ },
1901
+ {
1902
+ target: "#faceCapture.error",
1903
+ actions: "setProtectedFailure"
1904
+ }
1905
+ ],
1906
+ PROTECTED_ATTEMPT_RELEASED: { actions: "noOp" }
1907
+ },
1908
+ states: {
1909
+ checkingDeepsight: { always: [{
1910
+ target: "initializingDeepsight",
1911
+ guard: ({ context }) => !context.deepsightReady
1912
+ }, { target: "initializing" }] },
1913
+ initializingDeepsight: {
1914
+ entry: "initializeProtectedDeepsight",
1915
+ on: {
1916
+ PROTECTED_DEEPSIGHT_READY: {
1917
+ target: "initializing",
1918
+ actions: "setDeepsightReady"
1919
+ },
1920
+ PROTECTED_DEEPSIGHT_FAILED: {
1921
+ target: "#faceCapture.permissions",
1922
+ actions: "setDeepsightNotReady"
1923
+ }
1924
+ }
1925
+ },
1926
+ checkingStream: { always: "initializing" },
1927
+ initializing: { always: {
1928
+ target: "detecting",
1929
+ guard: "isCameraAndDeepsightReady"
1930
+ } },
1931
+ detecting: {
1932
+ entry: ["setDetectionStatusDetecting"],
1933
+ invoke: {
1934
+ id: "runAvatar",
1935
+ src: "runAvatar",
1936
+ input: ({ context }) => ({
1937
+ stream: context.stream,
1938
+ config: context.config,
1939
+ faceFeed: context.faceFeed
1940
+ })
1941
+ },
1942
+ exit: ["clearAvatarCanvas"],
1943
+ on: {
1944
+ DETECTION_UPDATE: { actions: ["setDetectionStatusFromEvent", "setManualCaptureTriggered"] },
1945
+ AVATAR_READY: { actions: "setAvatarCanvas" },
1946
+ PROTECTED_NATIVE_AUTO_CAPTURE: { actions: "sendProtectedAutoCapture" },
1947
+ PROTECTED_AUTO_COMMITTED: {
1948
+ target: "capturing",
1949
+ actions: "setProtectedCommittedPreview"
1950
+ },
1951
+ MANUAL_CAPTURE: {
1952
+ target: "capturingManual",
1953
+ guard: "canCommitProtectedManual",
1954
+ actions: "sendProtectedManualCapture"
1955
+ }
1956
+ }
1957
+ },
1958
+ capturing: {
1959
+ entry: ["sendProtectedFinalize"],
1960
+ on: { PROTECTED_ATTEMPT_FINALIZED: {
1961
+ target: "preparingUpload",
1962
+ actions: "setProtectedFinalization"
1963
+ } }
1964
+ },
1965
+ capturingManual: { on: {
1966
+ PROTECTED_MANUAL_COMMITTED: { actions: ["setProtectedCommittedPreview", "sendProtectedFinalize"] },
1967
+ PROTECTED_ATTEMPT_FINALIZED: {
1968
+ target: "preparingUpload",
1969
+ actions: "setProtectedFinalization"
1970
+ }
1971
+ } },
1972
+ preparingUpload: { always: "uploading" },
1973
+ uploading: {
1974
+ entry: "sendProtectedUploadIfNeeded",
1975
+ on: {
1976
+ PROTECTED_UPLOAD_MAPPED: {
1977
+ target: "validatingUpload",
1978
+ actions: "setProtectedUploadResponse"
1979
+ },
1980
+ PROTECTED_LOCAL_DONE: {
1981
+ target: "validatingUpload",
1982
+ actions: "setProtectedLocalResult"
1983
+ }
1984
+ }
1985
+ },
1986
+ validatingUpload: { always: [
1987
+ {
1988
+ target: "#faceCapture.error",
1989
+ guard: "isTerminalUploadError",
1990
+ actions: "setTerminalError"
1991
+ },
1992
+ {
1993
+ target: "uploadError",
1994
+ guard: "hasUploadValidationError",
1995
+ actions: ["setUploadErrorFromUploadValidation", "decrementAttemptsRemaining"]
1996
+ },
1997
+ { target: "success" }
1998
+ ] },
1999
+ uploadError: { on: { RETRY_CAPTURE: [
2000
+ {
2001
+ target: "#faceCapture.capture",
2002
+ reenter: true,
2003
+ guard: "hasAttemptsRemaining",
2004
+ actions: [
2005
+ "clearUploadFailure",
2006
+ "setDeepsightNotReady",
2007
+ "resetProtectedController",
2008
+ "clearProtectedAttempt"
2009
+ ]
2010
+ },
2011
+ {
2012
+ target: "#faceCapture.error",
2013
+ guard: "isNoAttemptsTerminal",
2014
+ actions: ["setTerminalError"]
2015
+ },
2016
+ {
2017
+ target: "#faceCapture.terminalProcessing",
2018
+ actions: ["flagFaceManualReview"]
2019
+ }
2020
+ ] } },
2021
+ success: {
2022
+ entry: "cleanup",
2023
+ after: { 3e3: { target: "#faceCapture.processing" } }
2024
+ }
2025
+ }
2026
+ },
2027
+ manualUpload: {
2028
+ entry: [
2029
+ "releaseProtectedAttempt",
2030
+ "stopMediaStream",
2031
+ "releaseAvatarWarmup"
2032
+ ],
2033
+ invoke: {
2034
+ id: "manualUpload",
2035
+ src: "manualUploadMachine",
2036
+ input: ({ context }) => ({
2037
+ config: context.config,
2038
+ dependencies: context.dependencies,
2039
+ captureAttempts: getAttemptsFromConfig(context.config)
2040
+ }),
2041
+ onSnapshot: { actions: "noOp" },
2042
+ onDone: [{
2043
+ guard: "isManualUploadExhausted",
2044
+ target: "terminalProcessing"
2045
+ }, { target: "processing" }],
2046
+ onError: {
2047
+ target: "error",
2048
+ actions: "setErrorFromEvent"
2049
+ }
2050
+ },
2051
+ on: {
2052
+ MANUAL_UPLOAD_FILE_SELECTED: { actions: "forwardToManualUpload" },
2053
+ MANUAL_UPLOAD_CONTINUE: { actions: "forwardToManualUpload" },
2054
+ MANUAL_UPLOAD_RESET: { actions: "forwardToManualUpload" }
2055
+ }
2056
+ },
2057
+ processing: { invoke: {
2058
+ id: "processFace",
2059
+ src: "processFace",
2060
+ input: ({ context }) => context,
2061
+ onDone: {
2062
+ target: "finished",
2063
+ actions: "setProcessResponseFromEvent"
2064
+ },
2065
+ onError: { target: "finished" }
2066
+ } },
2067
+ terminalProcessing: {
2068
+ entry: "cleanup",
2069
+ invoke: {
2070
+ id: "processFace",
2071
+ src: "processFace",
2072
+ input: ({ context }) => context,
2073
+ onDone: {
2074
+ target: "finished",
2075
+ actions: "setProcessResponseFromEvent"
2076
+ },
2077
+ onError: { target: "finished" }
2078
+ }
2079
+ },
2080
+ finished: {
2081
+ entry: [
2082
+ "releaseProtectedAttempt",
2083
+ "stopMediaStream",
2084
+ "releaseAvatarWarmup"
2085
+ ],
2086
+ type: "final"
2087
+ },
2088
+ closed: {
2089
+ entry: [
2090
+ "releaseProtectedAttempt",
2091
+ "stopMediaStream",
2092
+ "releaseAvatarWarmup"
2093
+ ],
2094
+ type: "final"
2095
+ },
2096
+ error: {
2097
+ entry: ["stopMediaStream", "releaseAvatarWarmup"],
2098
+ on: { RESET: {
2099
+ target: "idle",
2100
+ actions: ["resetProtectedController", "resetContext"]
2101
+ } }
2102
+ }
2103
+ }
2104
+ });
2105
+ //#endregion
2106
+ export { concealmentToAvatar as i, createDefaultProtectedFaceControllerActor as n, manualFaceUploadMachine as r, faceCaptureMachine as t };