@incodetech/core 2.1.0-rc.2 → 2.1.0-rc.3

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 (259) hide show
  1. package/dist/3dAvatarProvider-ChciZmjE.esm.js +28214 -0
  2. package/dist/{BrowserStorageProvider-D5xc7Lqo.esm.js → BrowserStorageProvider-CrrN540a.esm.js} +1 -25
  3. package/dist/BrowserVisibilityObserverProvider-rim9Jrz-.esm.js +25 -0
  4. package/dist/Face2DProvider-BeLlYBbB.esm.js +824 -0
  5. package/dist/FaceDetectionProvider-B78455D4.d.ts +119 -0
  6. package/dist/IVisibilityObserverCapability-BbWjgpiF.d.ts +12 -0
  7. package/dist/IWasmUtilCapability-d2XvzaCk.d.ts +145 -0
  8. package/dist/IpifyProvider-BRW14_uo.esm.js +51 -0
  9. package/dist/{Manager-B2OEDYqf.d.ts → Manager-CJ3G2zqi.d.ts} +1 -4
  10. package/dist/{OpenViduRecordingProvider-DF7A4ZNJ.esm.js → OpenViduRecordingProvider-B_0GKkzc.esm.js} +1 -1
  11. package/dist/PrivacyLensProvider-hDzaDzZ6.esm.js +339 -0
  12. package/dist/StateMachine-C_AY4cs7.d.ts +2 -0
  13. package/dist/{StreamCanvasCapture-Dr5n_iK1.esm.js → StreamCanvasCapture-Bz17q4FP.esm.js} +1 -1
  14. package/dist/StreamCanvasCapture-DS1TOoiH.d.ts +42 -0
  15. package/dist/{WasmUtilProvider-CIu373BZ.esm.js → WasmUtilProvider-ADG54T6M.esm.js} +16 -1
  16. package/dist/{addressSearch-BH96a3fq.esm.js → addressSearch-DJyNTg5S.esm.js} +4 -4
  17. package/dist/{ae-signature-CDEN8y-w.esm.js → ae-signature-DlElqFrZ.esm.js} +1 -1
  18. package/dist/ae-signature.d.ts +4 -3
  19. package/dist/ae-signature.esm.js +10 -9
  20. package/dist/antifraud.d.ts +4 -3
  21. package/dist/antifraud.esm.js +7 -6
  22. package/dist/{antifraudManager-DZifA5zX.esm.js → antifraudManager-BKdQoMFf.esm.js} +4 -3
  23. package/dist/{antifraudManager-B7WQTIdu.d.ts → antifraudManager-DpIvbrZP.d.ts} +2 -2
  24. package/dist/{antifraudStateMachine-DlKrK2hL.esm.js → antifraudStateMachine-C0NGnP9W.esm.js} +3 -3
  25. package/dist/{api-DUZwyz0o.esm.js → api-DsbUi7TO.esm.js} +21 -2
  26. package/dist/authentication.d.ts +19 -12
  27. package/dist/authentication.esm.js +33 -27
  28. package/dist/{authenticationManager-Dve7mGLe.d.ts → authenticationManager-CdPbNS2H.d.ts} +3 -3
  29. package/dist/{authenticationManager-BM4LzyV7.esm.js → authenticationManager-Dtl1vcET.esm.js} +6 -6
  30. package/dist/{authenticationStateMachine-Chx3ySdT.esm.js → authenticationStateMachine-D-hOlg8p.esm.js} +8 -8
  31. package/dist/avatar.d.ts +3 -0
  32. package/dist/avatar.esm.js +3 -0
  33. package/dist/{backCameraStream-iftkf3rd.esm.js → backCameraStream-ZyqrFyjO.esm.js} +3 -3
  34. package/dist/{browser-DlFgHpoC-7tbRR1aR.esm.js → browser-DlFgHpoC-qLKs75Qp.esm.js} +1 -1
  35. package/dist/{browserSimulation-CGjpdNA1.esm.js → browserSimulation-TsSoavQv.esm.js} +153 -1216
  36. package/dist/camera-DUkgmYMo.esm.js +79 -0
  37. package/dist/camera.d.ts +7 -1
  38. package/dist/camera.esm.js +4 -4
  39. package/dist/{StreamCanvasCapture-Ctgyx-oD.d.ts → canvas-CJUmoXSD.d.ts} +1 -41
  40. package/dist/certificate-issuance.d.ts +31 -30
  41. package/dist/certificate-issuance.esm.js +8 -7
  42. package/dist/{certificateIssuanceStateMachine-CLNXtXaC.esm.js → certificateIssuanceStateMachine-C07m7qtP.esm.js} +4 -4
  43. package/dist/clientLifecycle-Ct7h9uxx.esm.js +534 -0
  44. package/dist/consent.d.ts +4 -3
  45. package/dist/consent.esm.js +7 -6
  46. package/dist/{consentManager-psDCeJ0E.esm.js → consentManager-BtnPZUW4.esm.js} +4 -3
  47. package/dist/{consentManager-BqUGU_YD.d.ts → consentManager-DufVo9D9.d.ts} +52 -52
  48. package/dist/{consentStateMachine-DRsFFSHE.esm.js → consentStateMachine-DO2JqoZW.esm.js} +3 -3
  49. package/dist/cpf-ocr.d.ts +4 -3
  50. package/dist/cpf-ocr.esm.js +7 -6
  51. package/dist/{cpfOcrManager-BxcgxvgO.esm.js → cpfOcrManager-C4rLgKsu.esm.js} +6 -5
  52. package/dist/{cpfOcrManager-B2u9hMzd.d.ts → cpfOcrManager-DqZZ94Gt.d.ts} +19 -19
  53. package/dist/createFaceAvatar-B8pFpy6o.d.ts +401 -0
  54. package/dist/createFaceAvatar-BOHDKQRq.esm.js +46 -0
  55. package/dist/cross-document-data-match.d.ts +2 -1
  56. package/dist/cross-document-data-match.esm.js +6 -5
  57. package/dist/curp-validation.d.ts +10 -7
  58. package/dist/curp-validation.esm.js +7 -6
  59. package/dist/{curpValidationManager-BgLDw0Ub.esm.js → curpValidationManager-BafobPXC.esm.js} +4 -3
  60. package/dist/{curpValidationManager-Bt6CVD8b.d.ts → curpValidationManager-Co6LZAHT.d.ts} +3 -3
  61. package/dist/{curpValidationStateMachine-BK_wJ48C.esm.js → curpValidationStateMachine-DXTPK6vI.esm.js} +3 -3
  62. package/dist/custom-fields.d.ts +3 -2
  63. package/dist/custom-fields.esm.js +6 -5
  64. package/dist/custom-watchlist.d.ts +2 -1
  65. package/dist/custom-watchlist.esm.js +6 -5
  66. package/dist/{customWatchlistStateMachine-Bi4P59HM.esm.js → customWatchlistStateMachine-B4G3Chkx.esm.js} +3 -3
  67. package/dist/{deepsightLoader-BMmvk0X6.esm.js → deepsightLoader-DHSVD776.esm.js} +14 -13
  68. package/dist/{deepsightService-CEZrdiW0.esm.js → deepsightService-CDahSjGP.esm.js} +9 -38
  69. package/dist/deepsightService-CMB9XjES.d.ts +69 -0
  70. package/dist/device.d.ts +9 -1
  71. package/dist/device.esm.js +5 -5
  72. package/dist/document-capture.d.ts +175 -174
  73. package/dist/document-capture.esm.js +14 -13
  74. package/dist/document-upload.d.ts +48 -47
  75. package/dist/document-upload.esm.js +9 -8
  76. package/dist/{documentCaptureStateMachine-MpwpJO7t.esm.js → documentCaptureStateMachine-DSOX2epf.esm.js} +7 -7
  77. package/dist/dynamic-forms.d.ts +4 -192
  78. package/dist/dynamic-forms.esm.js +8 -160
  79. package/dist/dynamicFormsManager-BOefZbyF.esm.js +168 -0
  80. package/dist/dynamicFormsManager-CUYLOj9g.d.ts +239 -0
  81. package/dist/{dynamicFormsStateMachine-Do84A4uU.esm.js → dynamicFormsStateMachine-BXHcaocI.esm.js} +4 -4
  82. package/dist/ekyb.d.ts +9 -6
  83. package/dist/ekyb.esm.js +20 -17
  84. package/dist/{ekybStateMachine-nsuPOw3f.esm.js → ekybStateMachine-CCSeqjCt.esm.js} +5 -5
  85. package/dist/ekyc.d.ts +4 -3
  86. package/dist/ekyc.esm.js +9 -8
  87. package/dist/{ekycStateMachine-DcynX0rj.esm.js → ekycStateMachine-DkLVTOyA.esm.js} +5 -5
  88. package/dist/electronic-signature.d.ts +4 -3
  89. package/dist/electronic-signature.esm.js +9 -8
  90. package/dist/{electronicSignatureManager-B63aAuI5.esm.js → electronicSignatureManager-DjzUzqZj.esm.js} +50 -87
  91. package/dist/email.d.ts +5 -4
  92. package/dist/email.esm.js +9 -8
  93. package/dist/{emailManager-DxHjAe5u.esm.js → emailManager-B_XzEsXH.esm.js} +5 -4
  94. package/dist/{emailManager-C6D2u4mQ.d.ts → emailManager-fHASH6uo.d.ts} +3 -3
  95. package/dist/{emailStateMachine-758f34gg.esm.js → emailStateMachine-fqJ42b19.esm.js} +5 -5
  96. package/dist/{endpoints-BM2_j_IE.esm.js → endpoints-BzMJFAPV.esm.js} +13 -0
  97. package/dist/{events-DN-u67gb.esm.js → events-CqGY1yMq.esm.js} +2 -188
  98. package/dist/events.d.ts +2 -0
  99. package/dist/events.esm.js +3 -2
  100. package/dist/extensibility.d.ts +37 -26
  101. package/dist/extensibility.esm.js +74 -59
  102. package/dist/{externalFetch-crimxkN9.esm.js → externalFetch-CyhBfD-n.esm.js} +1 -1
  103. package/dist/face-match.d.ts +2 -2
  104. package/dist/face-match.esm.js +6 -5
  105. package/dist/{faceCaptureManagerFactory-BNXZchWX.esm.js → faceCaptureManagerFactory-2brKTzMb.esm.js} +25 -16
  106. package/dist/faceCaptureManagerFactory-CGKbf7zt.d.ts +400 -0
  107. package/dist/{faceCaptureSetup-Dqb09D24.esm.js → faceCaptureSetup-CDUVU1nl.esm.js} +97 -13
  108. package/dist/{faceMatchStateMachine-FikRaUZH.esm.js → faceMatchStateMachine-DUeUjEPx.esm.js} +3 -3
  109. package/dist/field-comparison.d.ts +4 -3
  110. package/dist/field-comparison.esm.js +6 -5
  111. package/dist/{fieldComparisonManager-Dic0DVgl.esm.js → fieldComparisonManager-B9W0a9A5.esm.js} +5 -4
  112. package/dist/{fieldComparisonManager-BXc6-DJv.d.ts → fieldComparisonManager-DdLqDeB2.d.ts} +2 -2
  113. package/dist/fiscal-qr.d.ts +5 -3
  114. package/dist/fiscal-qr.esm.js +13 -12
  115. package/dist/flow-events.d.ts +8 -6
  116. package/dist/flow.d.ts +21 -13
  117. package/dist/flow.esm.js +28 -19
  118. package/dist/{flowCompletionService-CdGDKv0z.d.ts → flowCompletionService-BIqSTZcd.d.ts} +2 -1
  119. package/dist/{flowCompletionService-D_CsiDZM.esm.js → flowCompletionService-qEqh_g14.esm.js} +3 -3
  120. package/dist/{flowServices-ar5DXv71.esm.js → flowServices-C4piblgx.esm.js} +24 -9
  121. package/dist/geolocation.d.ts +4 -127
  122. package/dist/geolocation.esm.js +8 -115
  123. package/dist/geolocationManager-BP2Do9O-.esm.js +123 -0
  124. package/dist/geolocationManager-Cs50eRlC.d.ts +156 -0
  125. package/dist/{geolocationStateMachine-BWjrMGS_.esm.js → geolocationStateMachine-BYfOOOG0.esm.js} +4 -4
  126. package/dist/{getDeviceClass-rXKlXywy.esm.js → getDeviceClass-DGGzzfqm.esm.js} +1 -1
  127. package/dist/getDeviceData-TrKM8NPh.esm.js +101 -0
  128. package/dist/government-validation.d.ts +4 -3
  129. package/dist/government-validation.esm.js +8 -7
  130. package/dist/{governmentValidationStateMachine-BoF7U1of.esm.js → governmentValidationStateMachine-CwoPPO8b.esm.js} +5 -5
  131. package/dist/home.d.ts +18 -15
  132. package/dist/home.esm.js +4 -3
  133. package/dist/http.esm.js +2 -2
  134. package/dist/id-ocr.d.ts +4 -625
  135. package/dist/id-ocr.esm.js +8 -84
  136. package/dist/id-verification.d.ts +28 -27
  137. package/dist/id-verification.esm.js +6 -5
  138. package/dist/id.d.ts +16 -11
  139. package/dist/id.esm.js +39 -32
  140. package/dist/idCaptureDefaults-DNJON8Xo.esm.js +188 -0
  141. package/dist/{idCaptureManager-BvGUSN2e.d.ts → idCaptureManager-BVdvfJys.d.ts} +40 -10
  142. package/dist/{idCaptureManager-Bm6Wm6Qv.esm.js → idCaptureManager-Bo9DCQSU.esm.js} +14 -11
  143. package/dist/{idCaptureStateMachine-D1YhOj6n.esm.js → idCaptureStateMachine-BeDidMLU.esm.js} +395 -382
  144. package/dist/idOcrManager-BkRDrpZu.esm.js +92 -0
  145. package/dist/idOcrManager-CJzrmM91.d.ts +641 -0
  146. package/dist/{idOcrStateMachine-YMCDGplq.esm.js → idOcrStateMachine-DRZc4FBl.esm.js} +5 -5
  147. package/dist/{idVerificationStateMachine-Bo1IYuZH.esm.js → idVerificationStateMachine-oqiERKpg.esm.js} +3 -3
  148. package/dist/identity-reuse.d.ts +4 -3
  149. package/dist/identity-reuse.esm.js +7 -6
  150. package/dist/{identityReuseManager-D0knIrOy.esm.js → identityReuseManager-Bu62LToE.esm.js} +4 -3
  151. package/dist/{identityReuseManager-DcWSvC-A.d.ts → identityReuseManager-TWKbXuvY.d.ts} +33 -33
  152. package/dist/{identityReuseStateMachine-CSQfZOqD.esm.js → identityReuseStateMachine-BmONeF6B.esm.js} +3 -3
  153. package/dist/{index-BgxYUYuD.d.ts → index-DtUlD-bz.d.ts} +2 -2
  154. package/dist/{index-DV134v62.d.ts → index-Icld-cKW.d.ts} +175 -295
  155. package/dist/index.d.ts +3 -3
  156. package/dist/index.esm.js +16 -13
  157. package/dist/{invokeOnCaptureCallback-Dzemudhk.esm.js → invokeOnCaptureCallback-v_PV_IJz.esm.js} +1 -1
  158. package/dist/{lib-7ZQ9BdKH.esm.js → lib-B050WTth.esm.js} +1 -1
  159. package/dist/mandatory-consent.d.ts +10 -7
  160. package/dist/mandatory-consent.esm.js +7 -6
  161. package/dist/{mandatoryConsentManager-Tzl5Qd35.d.ts → mandatoryConsentManager-Bmdjo14S.d.ts} +50 -50
  162. package/dist/{mandatoryConsentManager-Lon46nPQ.esm.js → mandatoryConsentManager-CQ3jirlZ.esm.js} +4 -3
  163. package/dist/{mandatoryConsentStateMachine-D_dZ7IF6.esm.js → mandatoryConsentStateMachine-DkJJLHqC.esm.js} +3 -3
  164. package/dist/mediaRecorderOptions-C3NAkVgK.esm.js +42 -0
  165. package/dist/mediapipeShared-CRAKVElv.esm.js +67 -0
  166. package/dist/{recordingService-CxMJP4tQ.esm.js → onDeviceFaceResults-DVBggeq8.esm.js} +71 -389
  167. package/dist/{openviduLazy-oAXXI9w_.esm.js → openviduLazy-BTOIauGP.esm.js} +2 -2
  168. package/dist/openviduLazy-Dov8oKfL.esm.js +3 -0
  169. package/dist/{permissionGuards-D-Z-lgNj.esm.js → permissionGuards-BR2oN573.esm.js} +1 -1
  170. package/dist/{permissionServices-CPDboRoE.esm.js → permissionServices-BJhGL13R.esm.js} +7 -4
  171. package/dist/personhood.d.ts +534 -0
  172. package/dist/personhood.esm.js +1494 -0
  173. package/dist/phone.d.ts +5 -4
  174. package/dist/phone.esm.js +9 -8
  175. package/dist/{phoneManager-TSq1Ief6.d.ts → phoneManager-BOTcjXgs.d.ts} +3 -3
  176. package/dist/{phoneManager-Blt4Oc2P.esm.js → phoneManager-BWlxqbyD.esm.js} +5 -4
  177. package/dist/{phoneStateMachine-W3c6Z8sj.esm.js → phoneStateMachine-B_V9nODs.esm.js} +5 -5
  178. package/dist/{qe-signature-CQLK6LKE.esm.js → qe-signature-BhFnI9pT.esm.js} +1 -1
  179. package/dist/qe-signature.d.ts +4 -3
  180. package/dist/qe-signature.esm.js +10 -9
  181. package/dist/recordingService-m_1xCthr.esm.js +347 -0
  182. package/dist/redirect-to-mobile.d.ts +4 -3
  183. package/dist/redirect-to-mobile.esm.js +9 -8
  184. package/dist/{redirectToMobileManager-DCvpKdkD.esm.js → redirectToMobileManager-BaAo9rgi.esm.js} +5 -4
  185. package/dist/{redirectToMobileManager-yOHAmwg-.d.ts → redirectToMobileManager-Br0KZK1G.d.ts} +2 -2
  186. package/dist/{redirectToMobileStateMachine-DC9z4Vfu.esm.js → redirectToMobileStateMachine-DoAnf2ql.esm.js} +10 -12
  187. package/dist/{runChildModule-C9G0wfVC.esm.js → runChildModule-0nQfjVVo.esm.js} +3 -3
  188. package/dist/selfie.d.ts +19 -12
  189. package/dist/selfie.esm.js +34 -28
  190. package/dist/{selfieManager-BRL6c_Oc.esm.js → selfieManager-D_ZFERsE.esm.js} +6 -6
  191. package/dist/{selfieManager-imY2dAcH.d.ts → selfieManager-R0Jw5sjb.d.ts} +3 -3
  192. package/dist/{selfieStateMachine-D2Q0uwDK.esm.js → selfieStateMachine-CIgeeiN9.esm.js} +4 -4
  193. package/dist/{session-Be_IA1e0.esm.js → session-9jIfKFCc.esm.js} +3 -3
  194. package/dist/session.d.ts +7 -5
  195. package/dist/session.esm.js +16 -14
  196. package/dist/{sessionInitializer-CaiGA8GP.esm.js → sessionInitializer-C_TYIgyk.esm.js} +11 -107
  197. package/dist/{setup-BJZAkajt.d.ts → setup-CpRnXxn8.d.ts} +16 -3
  198. package/dist/setup-DHc6OaHm.esm.js +562 -0
  199. package/dist/signature.d.ts +3 -2
  200. package/dist/signature.esm.js +6 -5
  201. package/dist/{signatureStateMachine-DAxXmMrk.esm.js → signatureStateMachine-DtoiPzys.esm.js} +3 -3
  202. package/dist/{stats-DntyIiGr.esm.js → stats-CYcScXcO.esm.js} +2 -2
  203. package/dist/stats.esm.js +3 -3
  204. package/dist/thumbmarkAdapter-fHBUDlAP.esm.js +1194 -0
  205. package/dist/{tri-CtxWthxz.esm.js → tri-BG1iJsr4.esm.js} +12 -2
  206. package/dist/tri.d.ts +1 -1
  207. package/dist/{tri.esm-CrWAulDi.esm.js → tri.esm-DUC01NgO.esm.js} +27 -23
  208. package/dist/tri.esm.js +2 -2
  209. package/dist/trust-graph.d.ts +4 -3
  210. package/dist/trust-graph.esm.js +4 -3
  211. package/dist/{types-DpTWgfKY.d.ts → types-BklZ_Wne.d.ts} +1 -1
  212. package/dist/{types-Dv-9WPJX.d.ts → types-BsYXnC5s.d.ts} +39 -3
  213. package/dist/types-CxW2e0Ar.d.ts +132 -0
  214. package/dist/{types-Z9wv19v2.d.ts → types-DgGlgyZT.d.ts} +1 -1
  215. package/dist/types-ElOJAGaM.esm.js +189 -0
  216. package/dist/video-C2WIj6TS.esm.js +36 -0
  217. package/dist/video-selfie.d.ts +351 -0
  218. package/dist/video-selfie.esm.js +1509 -0
  219. package/dist/videoSelfieSteps-7M5vxKn-.esm.js +58 -0
  220. package/dist/{warmup--6HA3yUR.d.ts → warmup-BJZPQIiX.d.ts} +5 -1
  221. package/dist/wasm.d.ts +4 -4
  222. package/dist/wasm.esm.js +17 -14
  223. package/dist/watchlist-for-business.d.ts +2 -1
  224. package/dist/watchlist-for-business.esm.js +6 -5
  225. package/dist/watchlist.d.ts +2 -1
  226. package/dist/watchlist.esm.js +6 -5
  227. package/dist/{watchlistForBusinessStateMachine-DtefJb-D.esm.js → watchlistForBusinessStateMachine-DvEunDxs.esm.js} +3 -3
  228. package/dist/{watchlistStateMachine-B0aIS2_n.esm.js → watchlistStateMachine-AHXVf-TB.esm.js} +3 -3
  229. package/dist/workflow.d.ts +230 -98
  230. package/dist/workflow.esm.js +123 -79
  231. package/dist/{xstate.esm-Dkm1jy5u.esm.js → xstate.esm-Bomq1a0z.esm.js} +41 -1
  232. package/package.json +16 -1
  233. package/dist/IpifyProvider-oZf7Ke1O.esm.js +0 -167
  234. package/dist/camera-x4LjGTjZ.esm.js +0 -22
  235. package/dist/deepsightService-ByNKY5Jv.d.ts +0 -276
  236. package/dist/faceCaptureManagerFactory-CL-7T_vH.d.ts +0 -731
  237. package/dist/getBrowser-Dv8LZyHE.esm.js +0 -8
  238. package/dist/openviduLazy-B_s6jnEk.esm.js +0 -3
  239. package/dist/setup-C7tintPc.esm.js +0 -1064
  240. /package/dist/{Actor-fIPLXfoi.d.ts → Actor-CGEelYtQ.d.ts} +0 -0
  241. /package/dist/{BrowserTimerProvider-BVgutW_b.esm.js → BrowserTimerProvider-CHloo0eQ.esm.js} +0 -0
  242. /package/dist/{ITimerCapability-BvH0pDwp.esm.js → ITimerCapability-pltuG1E8.esm.js} +0 -0
  243. /package/dist/{MotionSensorProvider-C9fPAJdS.esm.js → MotionSensorProvider-DCbId4De.esm.js} +0 -0
  244. /package/dist/{apiError-D-GTvFrH.esm.js → apiError-DNS2OCEX.esm.js} +0 -0
  245. /package/dist/{camera-biGPWlmx.d.ts → camera-CNVUo-bC.d.ts} +0 -0
  246. /package/dist/{canvas-7uX2izHb.esm.js → canvas-_I95hkPg.esm.js} +0 -0
  247. /package/dist/{chunk-BK1xu56N.esm.js → chunk-CIKcdghV.esm.js} +0 -0
  248. /package/dist/{cpf-xBg-DFNn.esm.js → cpf-BKaho0j_.esm.js} +0 -0
  249. /package/dist/{dateUtils-8dCcuArE.esm.js → dateUtils-7-tQYRNN.esm.js} +0 -0
  250. /package/dist/{getDeviceClass-C0zrM97a.esm.js → getDeviceClass-DavNdcxh.esm.js} +0 -0
  251. /package/dist/{http-CfVTgMfU.esm.js → http-BkiUT7EB.esm.js} +0 -0
  252. /package/dist/{index-52_qi4bd.d.ts → index-XTtxaahe.d.ts} +0 -0
  253. /package/dist/{otp-D87RTwrx.esm.js → otp-Bfnzf7I3.esm.js} +0 -0
  254. /package/dist/{otp-BHJnjEEc.d.ts → otp-M4iy57XY.d.ts} +0 -0
  255. /package/dist/{platform-BfoqeM61.esm.js → platform-uIVQUnJP.esm.js} +0 -0
  256. /package/dist/{types-BdVOWGGW.esm.js → types-CMcxlSmH.esm.js} +0 -0
  257. /package/dist/{types-DYZja-k9.d.ts → types-D_IceWxT.d.ts} +0 -0
  258. /package/dist/{types-F0IXbaCB.d.ts → types-Duy2rDxF.d.ts} +0 -0
  259. /package/dist/{urlUtils-8RNHyW3x.esm.js → urlUtils-BZqFU9rR.esm.js} +0 -0
@@ -0,0 +1,1509 @@
1
+ import { t as WasmUtilProvider } from "./WasmUtilProvider-ADG54T6M.esm.js";
2
+ import { t as ensureWasmPipelines } from "./setup-DHc6OaHm.esm.js";
3
+ import { t as BrowserTimerProvider } from "./BrowserTimerProvider-CHloo0eQ.esm.js";
4
+ import { t as api } from "./api-DsbUi7TO.esm.js";
5
+ import "./clientLifecycle-Ct7h9uxx.esm.js";
6
+ import "./events-CqGY1yMq.esm.js";
7
+ import "./types-ElOJAGaM.esm.js";
8
+ import { t as endpoints } from "./endpoints-BzMJFAPV.esm.js";
9
+ import "./stats-CYcScXcO.esm.js";
10
+ import "./browserSimulation-TsSoavQv.esm.js";
11
+ import "./sessionInitializer-C_TYIgyk.esm.js";
12
+ import "./getDeviceData-TrKM8NPh.esm.js";
13
+ import "./thumbmarkAdapter-fHBUDlAP.esm.js";
14
+ import "./IpifyProvider-BRW14_uo.esm.js";
15
+ import "./platform-uIVQUnJP.esm.js";
16
+ import "./tri-BG1iJsr4.esm.js";
17
+ import { a as fromPromise, i as fromCallback, l as createManager, r as assign, s as createActor, t as setup } from "./xstate.esm-Bomq1a0z.esm.js";
18
+ import "./MotionSensorProvider-DCbId4De.esm.js";
19
+ import { t as checkPermission } from "./permissionServices-BJhGL13R.esm.js";
20
+ import { i as requestCameraWithFallback } from "./camera-DUkgmYMo.esm.js";
21
+ import { a as encryptSelfieImage, b as FaceDetectionProvider, l as startDetection, m as uploadSelfie, p as processFace, y as StreamCanvasProcessingSession } from "./onDeviceFaceResults-DVBggeq8.esm.js";
22
+ import "./ITimerCapability-pltuG1E8.esm.js";
23
+ import "./canvas-_I95hkPg.esm.js";
24
+ import "./backCameraStream-ZyqrFyjO.esm.js";
25
+ import "./video-C2WIj6TS.esm.js";
26
+ import { n as getWindowDimensions } from "./getDeviceClass-DavNdcxh.esm.js";
27
+ import "./deepsightService-CDahSjGP.esm.js";
28
+ import "./getDeviceClass-DGGzzfqm.esm.js";
29
+ import "./types-CMcxlSmH.esm.js";
30
+ import { t as StreamCanvasCapture } from "./StreamCanvasCapture-Bz17q4FP.esm.js";
31
+ import { n as getSupportedMediaRecorderMimeType } from "./mediaRecorderOptions-C3NAkVgK.esm.js";
32
+ import { n as resolveVideoSelfieSteps, r as videoSelfieWasmPipelines, t as facingModeForStep } from "./videoSelfieSteps-7M5vxKn-.esm.js";
33
+ import { i as IdCaptureProvider, n as DEFAULT_ID_CAPTURE_MODEL_VERSION, r as DEFAULT_ID_CAPTURE_THRESHOLDS, t as DEFAULT_ID_CAPTURE_GEOMETRY } from "./idCaptureDefaults-DNJON8Xo.esm.js";
34
+
35
+ //#region src/modules/video-selfie/videoSelfieCompareService.ts
36
+ async function postVideoSelfieCompare(endpoint, base64Image) {
37
+ return (await api.post(endpoint, { base64Image })).data;
38
+ }
39
+ /** Compare a front-ID frame from the video selfie against the captured ID. */
40
+ const compareVideoSelfieId = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareId, base64Image);
41
+ /** Compare OCR from a front-ID frame against the captured ID's OCR. */
42
+ const compareVideoSelfieOcr = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareOcr, base64Image);
43
+ /** Compare a back-ID frame from the video selfie against the captured ID. */
44
+ const compareVideoSelfieBackId = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareBackId, base64Image);
45
+ /** Compare OCR from a back-ID frame against the captured ID's OCR. */
46
+ const compareVideoSelfieBackOcr = (base64Image) => postVideoSelfieCompare(endpoints.videoSelfieCompareBackOcr, base64Image);
47
+
48
+ //#endregion
49
+ //#region src/modules/video-selfie/videoSelfieStepDetector.ts
50
+ /** Default autocapture window for the selfie step when the config omits one. */
51
+ const SELFIE_AUTOCAPTURE_MS = 1e4;
52
+ /**
53
+ * Whether the backend reported a confident face match on a front-ID compare.
54
+ * The backend normalizes `faceRecognitionConfidence` to 0 (no match) or 1 (match).
55
+ */
56
+ function isFaceRecognitionMatch(confidence) {
57
+ if (typeof confidence !== "number") return true;
58
+ return confidence >= 1;
59
+ }
60
+ /**
61
+ * Max selfie capture attempts before the step fails. Each backend rejection
62
+ * (e.g. 4077 low quality / liveness) re-arms the pipeline and scans again;
63
+ * after this many tries the step rejects. Mirrors V1's `numberOfTries`.
64
+ */
65
+ const MAX_SELFIE_ATTEMPTS = 3;
66
+ /**
67
+ * How long the ID step holds on the "success" state (green check) after the
68
+ * backend validates a side, before advancing. Gives the user a beat to see the
69
+ * capture succeeded instead of the step jumping silently. Mirrors V1's
70
+ * IdVideoSelfie success flash.
71
+ */
72
+ const ID_SUCCESS_DWELL_MS = 900;
73
+ /**
74
+ * How long an ID step holds the "show the front / back of your ID" instruction
75
+ * before autocapture is armed. No frame is captured or validated during this
76
+ * window, so the guidance can't be overwritten by capture feedback before the
77
+ * user has read it. Mirrors the UI's `ID_INSTRUCTION_DWELL_MS` message pin.
78
+ */
79
+ const ID_INSTRUCTION_DWELL_MS = 3e3;
80
+ /** Resolves after `ms`, or rejects early if `signal` aborts. */
81
+ function delay(ms, signal) {
82
+ const timerProvider = BrowserTimerProvider.getInstance();
83
+ return new Promise((resolve, reject) => {
84
+ const timer = timerProvider.setTimeout(() => {
85
+ signal.removeEventListener("abort", onAbort);
86
+ resolve();
87
+ }, ms);
88
+ const onAbort = () => {
89
+ timerProvider.clearTimeout(timer);
90
+ reject(/* @__PURE__ */ new Error("aborted"));
91
+ };
92
+ signal.addEventListener("abort", onAbort, { once: true });
93
+ });
94
+ }
95
+ /**
96
+ * Builds the default per-step detector from the module config. Today it
97
+ * auto-captures the `selfie` step (face detection → `add/face` → `process/face`);
98
+ * ID / proof-of-address / questions / speech advance manually until their
99
+ * detectors land.
100
+ */
101
+ function createDefaultStepDetector(config, deps) {
102
+ return ({ step, stream, signal, onStatus }) => {
103
+ if (step === "selfie") return detectSelfie({
104
+ config,
105
+ deps,
106
+ stream,
107
+ signal,
108
+ onStatus
109
+ });
110
+ if (step === "frontId" || step === "backId") return detectId({
111
+ step,
112
+ config,
113
+ stream,
114
+ signal,
115
+ onStatus
116
+ });
117
+ return new Promise(() => {});
118
+ };
119
+ }
120
+ async function detectSelfie(params) {
121
+ const { config, deps, stream, signal, onStatus } = params;
122
+ const provider = new FaceDetectionProvider();
123
+ await provider.initialize({
124
+ autocaptureInterval: SELFIE_AUTOCAPTURE_MS,
125
+ useOnDeviceWorkflow: false,
126
+ videoSelfie: true
127
+ });
128
+ provider.setChecksEnabled({
129
+ lenses: config.validateLenses ?? false,
130
+ mask: config.validateFaceMask ?? false,
131
+ closedEyes: config.validateClosedEyes ?? false,
132
+ headWear: config.validateHeadCover ?? false,
133
+ occlusion: false
134
+ });
135
+ const imageType = config.useAsSelfie === true ? "selfie" : "videoSelfie";
136
+ const capturer = new StreamCanvasCapture(stream);
137
+ const detectionConfig = {
138
+ showTutorial: false,
139
+ validateBrightness: false,
140
+ validateLenses: config.validateLenses ?? false,
141
+ validateFaceMask: config.validateFaceMask ?? false,
142
+ validateClosedEyes: config.validateClosedEyes ?? false,
143
+ validateHeadCover: config.validateHeadCover ?? false,
144
+ autoCaptureTimeout: SELFIE_AUTOCAPTURE_MS / 1e3
145
+ };
146
+ const runAttempt = () => new Promise((resolve, reject) => {
147
+ const onAbort = () => {
148
+ detection.cleanup();
149
+ reject(/* @__PURE__ */ new Error("aborted"));
150
+ };
151
+ const settle = (run) => {
152
+ signal.removeEventListener("abort", onAbort);
153
+ run();
154
+ };
155
+ signal.addEventListener("abort", onAbort, { once: true });
156
+ const detection = startDetection({
157
+ config: detectionConfig,
158
+ capturer,
159
+ provider,
160
+ onUpdate: (status) => onStatus?.(status),
161
+ onSuccess: (canvas, faceCoordinates) => {
162
+ (async () => {
163
+ try {
164
+ await uploadSelfie({
165
+ encryptedBase64Image: await encryptSelfieImage({
166
+ canvas,
167
+ dependencies: { getWasmUtil: async () => deps.getWasmUtil() }
168
+ }),
169
+ faceCoordinates,
170
+ imageType
171
+ });
172
+ await processFace(imageType);
173
+ settle(resolve);
174
+ } catch (error$1) {
175
+ settle(() => reject(error$1 instanceof Error ? error$1 : new Error(String(error$1))));
176
+ }
177
+ })();
178
+ }
179
+ });
180
+ });
181
+ try {
182
+ for (let attempt = 1; attempt <= MAX_SELFIE_ATTEMPTS; attempt++) try {
183
+ await runAttempt();
184
+ return;
185
+ } catch (error$1) {
186
+ if (signal.aborted || attempt >= MAX_SELFIE_ATTEMPTS) throw error$1;
187
+ onStatus?.("error");
188
+ provider.reset();
189
+ await delay(1500, signal);
190
+ }
191
+ } finally {
192
+ capturer.dispose();
193
+ provider.dispose();
194
+ }
195
+ }
196
+ async function detectId(params) {
197
+ const { step, config, stream, signal, onStatus } = params;
198
+ const provider = new IdCaptureProvider();
199
+ await provider.initialize({ videoSelfie: true });
200
+ const windowDimensions = getWindowDimensions();
201
+ provider.setGeometry({
202
+ ...DEFAULT_ID_CAPTURE_GEOMETRY,
203
+ windowOuterWidth: windowDimensions.outerWidth,
204
+ windowOuterHeight: windowDimensions.outerHeight,
205
+ windowInnerWidth: windowDimensions.innerWidth,
206
+ windowInnerHeight: windowDimensions.innerHeight
207
+ });
208
+ provider.setSettings({
209
+ isFixedMask: false,
210
+ isIPhone14OrHigher: false,
211
+ idType: step === "backId" ? "BackId" : "FrontId",
212
+ blurCheckEnabled: true,
213
+ glareCheckEnabled: false,
214
+ faceQualityCheckEnabled: false,
215
+ iouCheckEnabled: true,
216
+ fpsLimitEnabled: false
217
+ });
218
+ provider.setThresholds(DEFAULT_ID_CAPTURE_THRESHOLDS);
219
+ provider.setModelType(DEFAULT_ID_CAPTURE_MODEL_VERSION);
220
+ const capturer = new StreamCanvasCapture(stream);
221
+ return new Promise((resolve, reject) => {
222
+ let validating = false;
223
+ let armed = false;
224
+ provider.setCallbacks({
225
+ onFarAway: () => {
226
+ if (armed && !validating) onStatus?.("tooFar");
227
+ },
228
+ onBlur: () => {
229
+ if (armed && !validating) onStatus?.("blur");
230
+ },
231
+ onCapturing: () => {
232
+ if (!armed || validating) return;
233
+ const base64Image = capturer.getLatestCanvas()?.getBase64Image();
234
+ if (!base64Image) return;
235
+ validating = true;
236
+ onStatus?.("capturing");
237
+ (async () => {
238
+ try {
239
+ if (await validateIdFrame(step, config, base64Image)) {
240
+ onStatus?.("success");
241
+ await delay(ID_SUCCESS_DWELL_MS, signal);
242
+ teardown();
243
+ resolve();
244
+ return;
245
+ }
246
+ validating = false;
247
+ } catch (error$1) {
248
+ teardown();
249
+ reject(error$1 instanceof Error ? error$1 : new Error(String(error$1)));
250
+ }
251
+ })();
252
+ }
253
+ });
254
+ const session = new StreamCanvasProcessingSession({
255
+ capturer,
256
+ provider
257
+ });
258
+ let toreDown = false;
259
+ const teardown = () => {
260
+ if (toreDown) return;
261
+ toreDown = true;
262
+ session.dispose();
263
+ capturer.dispose();
264
+ provider.dispose();
265
+ };
266
+ signal.addEventListener("abort", () => {
267
+ teardown();
268
+ reject(/* @__PURE__ */ new Error("aborted"));
269
+ }, { once: true });
270
+ delay(ID_INSTRUCTION_DWELL_MS, signal).then(() => {
271
+ if (toreDown || signal.aborted) return;
272
+ armed = true;
273
+ onStatus?.("detecting");
274
+ }).catch(() => {});
275
+ });
276
+ }
277
+ /** Runs the configured ID/OCR comparisons for a captured ID frame. */
278
+ async function validateIdFrame(step, config, base64Image) {
279
+ if (step === "backId") {
280
+ if (config.compareBackIdEnabled) {
281
+ const result = await compareVideoSelfieBackId(base64Image);
282
+ if (result.idSideMatched === false || result.success === false) return false;
283
+ }
284
+ if (config.compareBackOcrEnabled) {
285
+ if ((await compareVideoSelfieBackOcr(base64Image)).success === false) return false;
286
+ }
287
+ return true;
288
+ }
289
+ if (config.compareIdEnabled) {
290
+ const result = await compareVideoSelfieId(base64Image);
291
+ if (result.idTypeMatched === false) return false;
292
+ if (typeof result.faceRecognitionConfidence === "number" && !isFaceRecognitionMatch(result.faceRecognitionConfidence)) return false;
293
+ }
294
+ if (config.compareOcrEnabled) {
295
+ if ((await compareVideoSelfieOcr(base64Image)).success === false) return false;
296
+ }
297
+ return true;
298
+ }
299
+
300
+ //#endregion
301
+ //#region ../infra/src/media/CameraCompositor.ts
302
+ /**
303
+ * Composites the *active* camera into a canvas and exposes the canvas as a
304
+ * single, stable `MediaStream` to record. Switching cameras (front ↔ back)
305
+ * just repoints what the canvas draws — the output stream and its audio track
306
+ * are never replaced — so a single `MediaRecorder` produces one continuous
307
+ * video that follows the camera switches (V1 parity), instead of restarting
308
+ * per camera.
309
+ *
310
+ * The audio track from the initial stream is carried through unchanged across
311
+ * video switches, so there's no audio glitch when the camera flips.
312
+ */
313
+ var CameraCompositor = class {
314
+ constructor(options = {}) {
315
+ this.canvas = null;
316
+ this.ctx = null;
317
+ this.video = null;
318
+ this.rafId = null;
319
+ this.audioTrack = null;
320
+ this.videoTrack = null;
321
+ this.composite = null;
322
+ this.fps = options.fps ?? 30;
323
+ }
324
+ /**
325
+ * Begin compositing `stream` and return the composite stream to record. The
326
+ * stream's audio track (if any) is carried through unchanged across later
327
+ * `switchVideo` calls.
328
+ */
329
+ start(stream) {
330
+ this.canvas = document.createElement("canvas");
331
+ this.ctx = this.canvas.getContext("2d");
332
+ this.video = document.createElement("video");
333
+ this.video.muted = true;
334
+ this.video.playsInline = true;
335
+ this.audioTrack = stream.getAudioTracks()[0] ?? null;
336
+ this.setVideoSource(stream);
337
+ const composite = this.canvas.captureStream(this.fps);
338
+ if (this.audioTrack) composite.addTrack(this.audioTrack);
339
+ this.composite = composite;
340
+ this.startDrawLoop();
341
+ return composite;
342
+ }
343
+ /**
344
+ * Swap the camera feeding the canvas without interrupting the composite
345
+ * stream. Pass a video-only stream (audio is kept from `start`). The previous
346
+ * video track is stopped.
347
+ */
348
+ switchVideo(stream) {
349
+ if (!this.composite) return;
350
+ const previousVideoTrack = this.videoTrack;
351
+ this.setVideoSource(stream);
352
+ if (previousVideoTrack) previousVideoTrack.stop();
353
+ }
354
+ /** The composite stream being recorded, if compositing is active. */
355
+ get stream() {
356
+ return this.composite ?? void 0;
357
+ }
358
+ /** Stop compositing and release the canvas, audio, and video tracks. */
359
+ stop() {
360
+ if (this.rafId !== null) {
361
+ cancelAnimationFrame(this.rafId);
362
+ this.rafId = null;
363
+ }
364
+ this.videoTrack?.stop();
365
+ this.audioTrack?.stop();
366
+ this.composite?.getTracks().forEach((track) => track.stop());
367
+ if (this.video) this.video.srcObject = null;
368
+ this.canvas = null;
369
+ this.ctx = null;
370
+ this.video = null;
371
+ this.videoTrack = null;
372
+ this.audioTrack = null;
373
+ this.composite = null;
374
+ }
375
+ setVideoSource(stream) {
376
+ this.videoTrack = stream.getVideoTracks()[0] ?? null;
377
+ const video = this.video;
378
+ if (!video) return;
379
+ video.srcObject = new MediaStream(stream.getVideoTracks());
380
+ video.play().catch(() => {});
381
+ }
382
+ startDrawLoop() {
383
+ const draw = () => {
384
+ const video = this.video;
385
+ const canvas = this.canvas;
386
+ const ctx = this.ctx;
387
+ if (video && canvas && ctx && video.videoWidth > 0) {
388
+ if (canvas.width !== video.videoWidth || canvas.height !== video.videoHeight) {
389
+ canvas.width = video.videoWidth;
390
+ canvas.height = video.videoHeight;
391
+ }
392
+ ctx.drawImage(video, 0, 0, canvas.width, canvas.height);
393
+ }
394
+ this.rafId = requestAnimationFrame(draw);
395
+ };
396
+ this.rafId = requestAnimationFrame(draw);
397
+ }
398
+ };
399
+
400
+ //#endregion
401
+ //#region ../infra/src/providers/browser/MultipartRecordingProvider.ts
402
+ /**
403
+ * S3 multipart requires every part except the last to be at least 5 MB, so we
404
+ * buffer recorded data until it crosses this threshold before emitting a part.
405
+ */
406
+ const MIN_PART_SIZE_BYTES = 5 * 1024 * 1024;
407
+ /**
408
+ * How often `MediaRecorder` hands us buffered data (incremental blobs).
409
+ */
410
+ const TIMESLICE_MS = 1e3;
411
+ /**
412
+ * Encoder target for the full video-selfie session. Higher than the
413
+ * short-clip liveness path (0.5–1 Mbps) so a multi-minute session keeps usable
414
+ * quality and accumulates past the 5 MB part threshold instead of compressing a
415
+ * near-static face down to a single sub-5 MB part. It's a ceiling — a still
416
+ * scene still encodes well below it.
417
+ */
418
+ const VIDEO_BITS_PER_SECOND = 25e5;
419
+ /**
420
+ * Records a stream and streams it out as size-bounded parts for S3 multipart
421
+ * upload. Parts are emitted during recording (not buffered to the end), so the
422
+ * client never holds more than ~one part in memory regardless of video length.
423
+ *
424
+ * Unlike the short-clip liveness recorder, this does NOT auto-pause on
425
+ * `visibilitychange`: a video-selfie session must record continuously, and a
426
+ * pause with no resume would silently truncate the recording the moment the
427
+ * tab lost visibility.
428
+ */
429
+ var MultipartRecordingProvider = class {
430
+ constructor() {
431
+ this.mediaRecorder = null;
432
+ this._isRecording = false;
433
+ this._hasError = false;
434
+ this._error = null;
435
+ this.mimeType = "";
436
+ this.buffer = [];
437
+ this.bufferedBytes = 0;
438
+ this.partNumber = 0;
439
+ this.onPart = null;
440
+ }
441
+ get isRecording() {
442
+ return this._isRecording;
443
+ }
444
+ get hasError() {
445
+ return this._hasError;
446
+ }
447
+ get error() {
448
+ return this._error;
449
+ }
450
+ startRecording(stream, onPart) {
451
+ this.reset();
452
+ this.buffer = [];
453
+ this.bufferedBytes = 0;
454
+ this.partNumber = 0;
455
+ this.onPart = onPart;
456
+ try {
457
+ this.mimeType = getSupportedMediaRecorderMimeType();
458
+ const recorder = new MediaRecorder(stream.clone(), {
459
+ mimeType: this.mimeType,
460
+ videoBitsPerSecond: VIDEO_BITS_PER_SECOND
461
+ });
462
+ recorder.ondataavailable = (event) => {
463
+ if (event.data.size > 0) {
464
+ this.buffer.push(event.data);
465
+ this.bufferedBytes += event.data.size;
466
+ if (this.bufferedBytes >= MIN_PART_SIZE_BYTES) this.flushPart();
467
+ }
468
+ };
469
+ recorder.onerror = (event) => {
470
+ this._error = `Recording error: ${event instanceof ErrorEvent && event.error instanceof Error ? event.error.message : event.type}`;
471
+ this._isRecording = false;
472
+ this._hasError = true;
473
+ };
474
+ recorder.start(TIMESLICE_MS);
475
+ this.mediaRecorder = recorder;
476
+ this._isRecording = true;
477
+ this._error = null;
478
+ this._hasError = false;
479
+ } catch (err) {
480
+ this._error = `Failed to start recording: ${err instanceof Error ? err.message : String(err)}`;
481
+ this._hasError = true;
482
+ }
483
+ }
484
+ stopRecording() {
485
+ const recorder = this.mediaRecorder;
486
+ return new Promise((resolve) => {
487
+ if (recorder && this._isRecording) {
488
+ recorder.onstop = () => {
489
+ this.flushPart();
490
+ resolve();
491
+ };
492
+ recorder.stop();
493
+ this._isRecording = false;
494
+ } else resolve();
495
+ recorder?.stream?.getTracks().forEach((track) => track.stop());
496
+ });
497
+ }
498
+ reset() {
499
+ const recorder = this.mediaRecorder;
500
+ if (recorder) {
501
+ recorder.ondataavailable = null;
502
+ recorder.onerror = null;
503
+ recorder.onstop = null;
504
+ if (recorder.state !== "inactive") recorder.stop();
505
+ recorder.stream.getTracks().forEach((track) => track.stop());
506
+ this.mediaRecorder = null;
507
+ }
508
+ this.onPart = null;
509
+ this.buffer = [];
510
+ this.bufferedBytes = 0;
511
+ this._isRecording = false;
512
+ this._error = null;
513
+ this._hasError = false;
514
+ }
515
+ flushPart() {
516
+ if (this.bufferedBytes === 0 || !this.onPart) return;
517
+ const chunk = new Blob(this.buffer, { type: this.mimeType });
518
+ this.partNumber += 1;
519
+ this.onPart({
520
+ chunk,
521
+ partNumber: this.partNumber
522
+ });
523
+ this.buffer = [];
524
+ this.bufferedBytes = 0;
525
+ }
526
+ };
527
+
528
+ //#endregion
529
+ //#region src/internal/recordings/videoSelfieUploadService.ts
530
+ /**
531
+ * Opens a multipart video-selfie upload session. The returned `uploadId`
532
+ * identifies the session for subsequent part uploads and completion.
533
+ */
534
+ async function initiateVideoSelfieUpload() {
535
+ return (await api.post(endpoints.videoSelfieUploadInitiate, {})).data.uploadId;
536
+ }
537
+ /**
538
+ * Uploads a single chunk as a multipart part. The body is the raw video bytes
539
+ * (no base64, no client-side encryption — encryption at rest is server-side
540
+ * S3 SSE). Returns the part number + `eTag` needed to complete the upload.
541
+ */
542
+ async function uploadVideoSelfiePart(uploadId, partNumber, chunk) {
543
+ const response = await api.post(endpoints.videoSelfieUploadPart, chunk, {
544
+ query: {
545
+ uploadId,
546
+ partNumber
547
+ },
548
+ headers: { "Content-Type": "application/octet-stream" }
549
+ });
550
+ return {
551
+ partNumber: response.data.partNumber,
552
+ eTag: response.data.eTag
553
+ };
554
+ }
555
+ /**
556
+ * Finalizes the upload. `parts` must be in ascending `partNumber` order, or
557
+ * S3 reassembly fails. Returns the server-reported status.
558
+ */
559
+ async function completeVideoSelfieUpload(uploadId, parts) {
560
+ return (await api.post(endpoints.videoSelfieUploadComplete, {
561
+ uploadId,
562
+ parts
563
+ })).data.status;
564
+ }
565
+
566
+ //#endregion
567
+ //#region src/internal/recordings/multipartRecordingService.ts
568
+ /**
569
+ * Records the camera on-device and streams it to the backend as it is
570
+ * captured, using the S3 multipart upload protocol
571
+ * (`/omni/video-selfie/upload/*`).
572
+ *
573
+ * This is the Video Selfie module's client-side recorder and is deliberately
574
+ * independent of the face-capture recording services (`LocalRecordingService`
575
+ * / `OpenViduRecordingService`) — it is the replacement for server-side
576
+ * (OpenVidu) recording, not a sibling of it.
577
+ *
578
+ * Parts upload concurrently with recording, so `stop()` only flushes the final
579
+ * part and finalizes — keeping the whole session inside the server's
580
+ * video-selfie timeout regardless of length, with client memory bounded to
581
+ * ~one part. No client-side encryption: video is encrypted at rest server-side
582
+ * (S3 SSE-AES-256).
583
+ */
584
+ var MultipartRecordingService = class {
585
+ constructor() {
586
+ this.recorder = new MultipartRecordingProvider();
587
+ this.uploadId = null;
588
+ this.parts = [];
589
+ this.inflight = [];
590
+ this.uploadFailed = false;
591
+ }
592
+ get isRecording() {
593
+ return this.recorder.isRecording;
594
+ }
595
+ async start(stream) {
596
+ this.uploadId = await initiateVideoSelfieUpload();
597
+ this.parts = [];
598
+ this.inflight = [];
599
+ this.uploadFailed = false;
600
+ this.recorder.startRecording(stream, ({ chunk, partNumber }) => {
601
+ const uploadId = this.uploadId;
602
+ if (!uploadId) return;
603
+ const task = uploadVideoSelfiePart(uploadId, partNumber, chunk).then((part) => {
604
+ this.parts.push(part);
605
+ }).catch(() => {
606
+ this.uploadFailed = true;
607
+ });
608
+ this.inflight.push(task);
609
+ });
610
+ }
611
+ async stop() {
612
+ const uploadId = this.uploadId;
613
+ if (!this.recorder.isRecording || !uploadId) return { recordingId: null };
614
+ await this.recorder.stopRecording();
615
+ await Promise.all(this.inflight);
616
+ if (this.uploadFailed || this.parts.length === 0) return { recordingId: null };
617
+ const orderedParts = [...this.parts].sort((a, b) => a.partNumber - b.partNumber);
618
+ try {
619
+ await completeVideoSelfieUpload(uploadId, orderedParts);
620
+ return { recordingId: uploadId };
621
+ } catch {
622
+ return { recordingId: null };
623
+ }
624
+ }
625
+ cleanup() {
626
+ this.recorder.reset();
627
+ }
628
+ };
629
+
630
+ //#endregion
631
+ //#region src/modules/video-selfie/videoSelfieRecordingMachine.ts
632
+ /** A detector that never settles — used when a step has no auto-capture yet. */
633
+ const manualStepDetector = () => new Promise(() => {});
634
+ function defaultAcquireCamera(facingMode, withAudio) {
635
+ return requestCameraWithFallback({
636
+ video: { facingMode },
637
+ audio: withAudio
638
+ });
639
+ }
640
+ function eventOutputStream(event) {
641
+ return event.output;
642
+ }
643
+ function recordingIdFromEvent(event) {
644
+ return event.output.recordingId;
645
+ }
646
+ function errorFromEvent(event) {
647
+ return String(event.error);
648
+ }
649
+ function detectionStatusFromEvent(event) {
650
+ return event.status;
651
+ }
652
+ function detectionErrorFromEvent(event) {
653
+ return event.error;
654
+ }
655
+ /**
656
+ * Orchestrates a multi-step Video Selfie session as ONE continuous recording
657
+ * that follows the camera between steps AND auto-advances per step:
658
+ *
659
+ * idle ─START▶ acquiringCamera ─▶ starting ─▶ recording ⇄ switchingCamera
660
+ * │ (capture validated → DETECTION_DONE,
661
+ * │ or manual NEXT_STEP)
662
+ * last step ─▶ finalizing ─▶ finished
663
+ *
664
+ * While `recording`, a per-step detector runs WASM auto-capture + backend
665
+ * validation; success advances the step (switching the camera when the next
666
+ * step's facing differs), and the final step finalizes the multipart upload.
667
+ *
668
+ * Teardown: `ABORT` is accepted from ANY non-final state and every terminal
669
+ * state runs `cleanup` on entry, so no settled path leaves camera or mic
670
+ * tracks running. XState v5 executes NO exit actions on an external
671
+ * `actor.stop()`, so the manager sends `ABORT` before stopping the actor —
672
+ * never stop this actor directly without aborting first.
673
+ */
674
+ const videoSelfieRecordingSetup = setup({
675
+ types: {
676
+ context: {},
677
+ events: {},
678
+ input: {}
679
+ },
680
+ actors: {
681
+ acquireCamera: fromPromise(async ({ input, signal }) => {
682
+ const stream = await input.acquire(input.facingMode, input.withAudio);
683
+ if (signal.aborted) {
684
+ stream.getTracks().forEach((track) => track.stop());
685
+ throw new Error("Camera acquire cancelled");
686
+ }
687
+ return stream;
688
+ }),
689
+ startRecording: fromPromise(async ({ input }) => {
690
+ await input.service.start(input.stream);
691
+ }),
692
+ finalizeRecording: fromPromise(async ({ input }) => input.service.stop()),
693
+ detectStep: fromCallback(({ input, sendBack }) => {
694
+ const controller = new AbortController();
695
+ input.detect({
696
+ step: input.step,
697
+ stream: input.stream,
698
+ signal: controller.signal,
699
+ onStatus: (status) => sendBack({
700
+ type: "DETECTION_STATUS",
701
+ status
702
+ })
703
+ }).then(() => sendBack({ type: "DETECTION_DONE" })).catch((err) => {
704
+ if (!controller.signal.aborted) sendBack({
705
+ type: "DETECTION_FAILED",
706
+ error: String(err)
707
+ });
708
+ });
709
+ return () => controller.abort();
710
+ })
711
+ },
712
+ actions: {
713
+ advanceStep: assign({ stepIndex: ({ context: context$1 }) => context$1.stepIndex + 1 }),
714
+ setDetectionStatus: assign({ detectionStatus: ({ event }) => detectionStatusFromEvent(event) }),
715
+ setDetectionError: assign({ detectionError: ({ event }) => detectionErrorFromEvent(event) }),
716
+ setErrorFromDetection: assign({ error: ({ event }) => detectionErrorFromEvent(event) }),
717
+ clearDetectionFeedback: assign({
718
+ detectionStatus: () => void 0,
719
+ detectionError: () => void 0
720
+ }),
721
+ setUploadFailedError: assign({ error: () => "Video upload failed" }),
722
+ cleanup: ({ context: context$1 }) => {
723
+ context$1.service.cleanup();
724
+ context$1.compositor.stop();
725
+ context$1.stream?.getTracks().forEach((track) => track.stop());
726
+ }
727
+ },
728
+ guards: {
729
+ isLastStep: ({ context: context$1 }) => context$1.stepIndex >= context$1.steps.length - 1,
730
+ nextStepFlipsCamera: ({ context: context$1 }) => facingModeForStep(context$1.steps[context$1.stepIndex]) !== facingModeForStep(context$1.steps[context$1.stepIndex + 1]),
731
+ uploadReturnedNoRecordingId: ({ event }) => recordingIdFromEvent(event) === null
732
+ }
733
+ });
734
+ const ADVANCE_TRANSITIONS = [
735
+ {
736
+ target: "finalizing",
737
+ guard: "isLastStep"
738
+ },
739
+ {
740
+ target: "switchingCamera",
741
+ guard: "nextStepFlipsCamera",
742
+ actions: "advanceStep"
743
+ },
744
+ {
745
+ target: "recording",
746
+ reenter: true,
747
+ actions: "advanceStep"
748
+ }
749
+ ];
750
+ const _videoSelfieRecordingMachine = videoSelfieRecordingSetup.createMachine({
751
+ id: "videoSelfieRecording",
752
+ initial: "idle",
753
+ context: ({ input }) => ({
754
+ service: input.dependencies?.createRecordingService?.() ?? new MultipartRecordingService(),
755
+ compositor: input.dependencies?.createCompositor?.() ?? new CameraCompositor(),
756
+ acquireCamera: input.dependencies?.acquireCamera ?? defaultAcquireCamera,
757
+ detect: input.dependencies?.detect ?? manualStepDetector,
758
+ steps: input.steps && input.steps.length > 0 ? input.steps : ["selfie"],
759
+ stepIndex: 0,
760
+ stream: void 0,
761
+ composite: void 0,
762
+ detectionStatus: void 0,
763
+ detectionError: void 0,
764
+ recordingId: null,
765
+ error: void 0
766
+ }),
767
+ on: { ABORT: { target: ".aborted" } },
768
+ states: {
769
+ idle: { on: { START: { target: "acquiringCamera" } } },
770
+ acquiringCamera: { invoke: {
771
+ src: "acquireCamera",
772
+ input: ({ context: context$1 }) => ({
773
+ acquire: context$1.acquireCamera,
774
+ facingMode: facingModeForStep(context$1.steps[context$1.stepIndex]),
775
+ withAudio: true
776
+ }),
777
+ onDone: {
778
+ target: "starting",
779
+ actions: [({ context: context$1, event }) => {
780
+ context$1.compositor.start(eventOutputStream(event));
781
+ }, assign({
782
+ stream: ({ event }) => eventOutputStream(event),
783
+ composite: ({ context: context$1 }) => context$1.compositor.stream
784
+ })]
785
+ },
786
+ onError: {
787
+ target: "error",
788
+ actions: assign({ error: ({ event }) => errorFromEvent(event) })
789
+ }
790
+ } },
791
+ starting: { invoke: {
792
+ src: "startRecording",
793
+ input: ({ context: context$1 }) => ({
794
+ service: context$1.service,
795
+ stream: context$1.composite
796
+ }),
797
+ onDone: { target: "recording" },
798
+ onError: {
799
+ target: "error",
800
+ actions: assign({ error: ({ event }) => errorFromEvent(event) })
801
+ }
802
+ } },
803
+ recording: {
804
+ entry: "clearDetectionFeedback",
805
+ invoke: {
806
+ src: "detectStep",
807
+ input: ({ context: context$1 }) => ({
808
+ detect: context$1.detect,
809
+ step: context$1.steps[context$1.stepIndex],
810
+ stream: context$1.stream
811
+ })
812
+ },
813
+ on: {
814
+ DETECTION_STATUS: { actions: "setDetectionStatus" },
815
+ DETECTION_DONE: ADVANCE_TRANSITIONS,
816
+ NEXT_STEP: ADVANCE_TRANSITIONS,
817
+ DETECTION_FAILED: {
818
+ target: "error",
819
+ actions: "setErrorFromDetection"
820
+ }
821
+ }
822
+ },
823
+ switchingCamera: { invoke: {
824
+ src: "acquireCamera",
825
+ input: ({ context: context$1 }) => ({
826
+ acquire: context$1.acquireCamera,
827
+ facingMode: facingModeForStep(context$1.steps[context$1.stepIndex]),
828
+ withAudio: false
829
+ }),
830
+ onDone: {
831
+ target: "recording",
832
+ actions: [({ context: context$1, event }) => {
833
+ context$1.compositor.switchVideo(eventOutputStream(event));
834
+ }, assign({ stream: ({ event }) => eventOutputStream(event) })]
835
+ },
836
+ onError: {
837
+ target: "error",
838
+ actions: assign({ error: ({ event }) => errorFromEvent(event) })
839
+ }
840
+ } },
841
+ finalizing: { invoke: {
842
+ src: "finalizeRecording",
843
+ input: ({ context: context$1 }) => ({ service: context$1.service }),
844
+ onDone: [{
845
+ target: "error",
846
+ guard: "uploadReturnedNoRecordingId",
847
+ actions: [assign({ recordingId: ({ event }) => recordingIdFromEvent(event) }), "setUploadFailedError"]
848
+ }, {
849
+ target: "finished",
850
+ actions: assign({ recordingId: ({ event }) => recordingIdFromEvent(event) })
851
+ }],
852
+ onError: {
853
+ target: "error",
854
+ actions: assign({ error: ({ event }) => errorFromEvent(event) })
855
+ }
856
+ } },
857
+ finished: {
858
+ type: "final",
859
+ entry: "cleanup"
860
+ },
861
+ error: {
862
+ type: "final",
863
+ entry: "cleanup"
864
+ },
865
+ aborted: {
866
+ type: "final",
867
+ entry: "cleanup"
868
+ }
869
+ }
870
+ });
871
+ const videoSelfieRecordingMachine = _videoSelfieRecordingMachine;
872
+
873
+ //#endregion
874
+ //#region src/modules/video-selfie/videoSelfieRecordingActor.ts
875
+ function createVideoSelfieRecordingActor(options = {}) {
876
+ const config = options.config;
877
+ const detect = options.dependencies?.detect ?? (config ? createDefaultStepDetector(config, { getWasmUtil: () => WasmUtilProvider.getInstance() }) : void 0);
878
+ return createActor(videoSelfieRecordingMachine, { input: {
879
+ steps: config ? resolveVideoSelfieSteps(config) : void 0,
880
+ dependencies: {
881
+ ...options.dependencies,
882
+ detect
883
+ }
884
+ } }).start();
885
+ }
886
+
887
+ //#endregion
888
+ //#region src/modules/video-selfie/videoSelfieRecordingManager.ts
889
+ function mapState(snapshot) {
890
+ const value = typeof snapshot.value === "string" ? snapshot.value : "idle";
891
+ const { context: context$1 } = snapshot;
892
+ const status = value === "acquiringCamera" ? "starting" : value;
893
+ const steps = context$1.steps;
894
+ const stepIndex = context$1.stepIndex;
895
+ return {
896
+ status,
897
+ step: steps[stepIndex],
898
+ stepIndex,
899
+ isLastStep: stepIndex >= steps.length - 1,
900
+ stream: context$1.stream,
901
+ composite: context$1.composite,
902
+ detectionStatus: context$1.detectionStatus,
903
+ recordingId: context$1.recordingId,
904
+ error: context$1.error
905
+ };
906
+ }
907
+ function createApi({ actor }) {
908
+ return {
909
+ start() {
910
+ actor.send({ type: "START" });
911
+ },
912
+ nextStep() {
913
+ actor.send({ type: "NEXT_STEP" });
914
+ },
915
+ abort() {
916
+ actor.send({ type: "ABORT" });
917
+ }
918
+ };
919
+ }
920
+ /**
921
+ * Creates a manager for a multi-step, camera-switching Video Selfie recording.
922
+ *
923
+ * The whole session records as one continuous video that follows the camera
924
+ * across steps (front for selfie, rear for ID). Exposes `getState()` /
925
+ * `subscribe()` (status, step, preview `stream`, `recordingId`) plus `start()`,
926
+ * `nextStep()`, and `abort()`.
927
+ */
928
+ function createVideoSelfieRecordingManager(options = {}) {
929
+ const actor = createVideoSelfieRecordingActor(options);
930
+ const manager = createManager({
931
+ actor,
932
+ mapState,
933
+ createApi
934
+ });
935
+ return {
936
+ ...manager,
937
+ stop() {
938
+ if (actor.getSnapshot().status === "active") actor.send({ type: "ABORT" });
939
+ manager.stop();
940
+ }
941
+ };
942
+ }
943
+
944
+ //#endregion
945
+ //#region src/modules/video-selfie/videoSelfieWasm.ts
946
+ /**
947
+ * Warms the WASM pipelines the Video Selfie flow needs (face detection, plus the
948
+ * ID-capture pipeline when `checkIdScan` is on), reusing the WASM config stored
949
+ * by `setup({ wasm })`.
950
+ *
951
+ * Idempotent and safe to call eagerly — the UI invokes it when the tutorial
952
+ * mounts so the models finish loading while the user reads the instructions, and
953
+ * detection is ready the instant recording starts (mirrors how the selfie and ID
954
+ * modules warm up during their tutorials). No-op when WASM was not configured.
955
+ */
956
+ function warmupVideoSelfieWasm(config) {
957
+ return ensureWasmPipelines(videoSelfieWasmPipelines(config));
958
+ }
959
+
960
+ //#endregion
961
+ //#region src/modules/video-selfie/videoSelfieCameraWarmer.ts
962
+ function defaultAcquire(facingMode, withAudio) {
963
+ return requestCameraWithFallback({
964
+ video: { facingMode },
965
+ audio: withAudio
966
+ });
967
+ }
968
+ function stopStream(stream) {
969
+ stream?.getTracks().forEach((track) => track.stop());
970
+ }
971
+ /**
972
+ * Creates a {@link VideoSelfieCameraWarmer} for the given config. The first
973
+ * camera (and whether it needs audio) is derived from the resolved step order —
974
+ * the same first acquire the recording machine performs on `START`.
975
+ */
976
+ function createVideoSelfieCameraWarmer(config) {
977
+ const firstFacing = facingModeForStep(resolveVideoSelfieSteps(config)[0] ?? "selfie");
978
+ let warming = null;
979
+ let warmed = null;
980
+ let consumed = false;
981
+ return {
982
+ warm() {
983
+ if (warming) return;
984
+ warming = (async () => {
985
+ try {
986
+ if (await checkPermission() !== "granted") return null;
987
+ warmed = await defaultAcquire(firstFacing, true);
988
+ return warmed;
989
+ } catch {
990
+ return null;
991
+ }
992
+ })();
993
+ },
994
+ async acquireCamera(facingMode, withAudio) {
995
+ if (!consumed && facingMode === firstFacing && withAudio) {
996
+ consumed = true;
997
+ const stream = warmed ?? (warming ? await warming : null);
998
+ warmed = null;
999
+ if (stream) return stream;
1000
+ }
1001
+ return defaultAcquire(facingMode, withAudio);
1002
+ },
1003
+ dispose() {
1004
+ if (consumed) return;
1005
+ if (warmed) {
1006
+ stopStream(warmed);
1007
+ warmed = null;
1008
+ } else if (warming) warming.then((stream) => {
1009
+ if (!consumed) stopStream(stream);
1010
+ });
1011
+ }
1012
+ };
1013
+ }
1014
+
1015
+ //#endregion
1016
+ //#region src/modules/video-selfie/videoSelfieSpeechService.ts
1017
+ /**
1018
+ * Fetches `count` random challenge questions the user answers out loud. The
1019
+ * spoken answers are captured in the main video recording (no separate upload)
1020
+ * and verified server-side.
1021
+ */
1022
+ async function getVideoSelfieQuestions(count) {
1023
+ return (await api.get(endpoints.questionAndAnswer, { query: {
1024
+ numberOfQuestions: count,
1025
+ returnVoiceConsentQuestion: false
1026
+ } })).data.questionAndAnswers ?? [];
1027
+ }
1028
+ /**
1029
+ * Fetches the voice-consent phrase the user must read aloud. The phrase is the
1030
+ * `answer` of the consent question returned when `returnVoiceConsentQuestion`
1031
+ * is requested with no challenge questions.
1032
+ */
1033
+ async function getVoiceConsentPhrase() {
1034
+ return (await api.get(endpoints.questionAndAnswer, { query: {
1035
+ numberOfQuestions: 0,
1036
+ returnVoiceConsentQuestion: true
1037
+ } })).data.questionAndAnswers?.[0]?.answer ?? "";
1038
+ }
1039
+ /**
1040
+ * Uploads the recorded consent audio (base64 MP3) for speech-to-text
1041
+ * validation. Resolves `{ success: false }` on a network/validation error so
1042
+ * the UI can drive its retry loop instead of throwing.
1043
+ */
1044
+ async function addSpeech(base64Mp3) {
1045
+ try {
1046
+ return { success: (await api.post(endpoints.addSpeechV2, {
1047
+ base64Media: base64Mp3,
1048
+ audioOnly: true
1049
+ })).data.success === true };
1050
+ } catch {
1051
+ return { success: false };
1052
+ }
1053
+ }
1054
+
1055
+ //#endregion
1056
+ //#region ../../node_modules/.pnpm/audio-recorder-polyfill@0.4.1/node_modules/audio-recorder-polyfill/wave-encoder/index.js
1057
+ var wave_encoder_default = () => {
1058
+ let BYTES_PER_SAMPLE = 2;
1059
+ let recorded = [];
1060
+ function encode(buffer) {
1061
+ let length = buffer.length;
1062
+ let data = new Uint8Array(length * BYTES_PER_SAMPLE);
1063
+ for (let i = 0; i < length; i++) {
1064
+ let index = i * BYTES_PER_SAMPLE;
1065
+ let sample = buffer[i];
1066
+ if (sample > 1) sample = 1;
1067
+ else if (sample < -1) sample = -1;
1068
+ sample = sample * 32768;
1069
+ data[index] = sample;
1070
+ data[index + 1] = sample >> 8;
1071
+ }
1072
+ recorded.push(data);
1073
+ }
1074
+ function dump(sampleRate) {
1075
+ let bufferLength = recorded.length ? recorded[0].length : 0;
1076
+ let length = recorded.length * bufferLength;
1077
+ let wav = new Uint8Array(44 + length);
1078
+ let view = new DataView(wav.buffer);
1079
+ view.setUint32(0, 1380533830, false);
1080
+ view.setUint32(4, 36 + length, true);
1081
+ view.setUint32(8, 1463899717, false);
1082
+ view.setUint32(12, 1718449184, false);
1083
+ view.setUint32(16, 16, true);
1084
+ view.setUint16(20, 1, true);
1085
+ view.setUint16(22, 1, true);
1086
+ view.setUint32(24, sampleRate, true);
1087
+ view.setUint32(28, sampleRate * BYTES_PER_SAMPLE, true);
1088
+ view.setUint16(32, BYTES_PER_SAMPLE, true);
1089
+ view.setUint16(34, 8 * BYTES_PER_SAMPLE, true);
1090
+ view.setUint32(36, 1684108385, false);
1091
+ view.setUint32(40, length, true);
1092
+ for (let i = 0; i < recorded.length; i++) wav.set(recorded[i], i * bufferLength + 44);
1093
+ recorded = [];
1094
+ postMessage(wav.buffer, [wav.buffer]);
1095
+ }
1096
+ onmessage = (e) => {
1097
+ if (e.data[0] === "encode") encode(e.data[1]);
1098
+ else if (e.data[0] === "dump") dump(e.data[1]);
1099
+ };
1100
+ };
1101
+
1102
+ //#endregion
1103
+ //#region ../../node_modules/.pnpm/audio-recorder-polyfill@0.4.1/node_modules/audio-recorder-polyfill/index.js
1104
+ let AudioContext = window.AudioContext || window.webkitAudioContext;
1105
+ let createWorker = (fn) => {
1106
+ let js = fn.toString().replace(/^(\(\)\s*=>|function\s*\(\))\s*{/, "").replace(/}$/, "");
1107
+ let blob = new Blob([js]);
1108
+ return new Worker(URL.createObjectURL(blob));
1109
+ };
1110
+ let error = (method) => {
1111
+ let event = new Event("error");
1112
+ event.data = /* @__PURE__ */ new Error("Wrong state for " + method);
1113
+ return event;
1114
+ };
1115
+ let context;
1116
+ /**
1117
+ * Audio Recorder with MediaRecorder API.
1118
+ *
1119
+ * @example
1120
+ * navigator.mediaDevices.getUserMedia({ audio: true }).then(stream => {
1121
+ * let recorder = new MediaRecorder(stream)
1122
+ * })
1123
+ */
1124
+ var MediaRecorder$1 = class MediaRecorder$1 {
1125
+ /**
1126
+ * @param {MediaStream} stream The audio stream to record.
1127
+ */
1128
+ constructor(stream, config = null) {
1129
+ /**
1130
+ * The `MediaStream` passed into the constructor.
1131
+ * @type {MediaStream}
1132
+ */
1133
+ this.stream = stream;
1134
+ this.config = config;
1135
+ /**
1136
+ * The current state of recording process.
1137
+ * @type {"inactive"|"recording"|"paused"}
1138
+ */
1139
+ this.state = "inactive";
1140
+ this.em = document.createDocumentFragment();
1141
+ this.encoder = createWorker(MediaRecorder$1.encoder);
1142
+ let recorder = this;
1143
+ this.encoder.addEventListener("message", (e) => {
1144
+ let event = new Event("dataavailable");
1145
+ event.data = new Blob([e.data], { type: recorder.mimeType });
1146
+ recorder.em.dispatchEvent(event);
1147
+ if (recorder.state === "inactive") recorder.em.dispatchEvent(new Event("stop"));
1148
+ });
1149
+ }
1150
+ /**
1151
+ * Begins recording media.
1152
+ *
1153
+ * @param {number} [timeslice] The milliseconds to record into each `Blob`.
1154
+ * If this parameter isn’t included, single `Blob`
1155
+ * will be recorded.
1156
+ *
1157
+ * @return {undefined}
1158
+ *
1159
+ * @example
1160
+ * recordButton.addEventListener('click', () => {
1161
+ * recorder.start()
1162
+ * })
1163
+ */
1164
+ start(timeslice) {
1165
+ if (this.state !== "inactive") return this.em.dispatchEvent(error("start"));
1166
+ this.state = "recording";
1167
+ if (!context) context = new AudioContext(this.config);
1168
+ this.clone = this.stream.clone();
1169
+ this.input = context.createMediaStreamSource(this.clone);
1170
+ this.processor = context.createScriptProcessor(2048, 1, 1);
1171
+ this.encoder.postMessage(["init", context.sampleRate]);
1172
+ this.processor.onaudioprocess = (e) => {
1173
+ if (this.state === "recording") this.encoder.postMessage(["encode", e.inputBuffer.getChannelData(0)]);
1174
+ };
1175
+ this.input.connect(this.processor);
1176
+ this.processor.connect(context.destination);
1177
+ this.em.dispatchEvent(new Event("start"));
1178
+ if (timeslice) this.slicing = setInterval(() => {
1179
+ if (this.state === "recording") this.requestData();
1180
+ }, timeslice);
1181
+ }
1182
+ /**
1183
+ * Stop media capture and raise `dataavailable` event with recorded data.
1184
+ *
1185
+ * @return {undefined}
1186
+ *
1187
+ * @example
1188
+ * finishButton.addEventListener('click', () => {
1189
+ * recorder.stop()
1190
+ * })
1191
+ */
1192
+ stop() {
1193
+ if (this.state === "inactive") return this.em.dispatchEvent(error("stop"));
1194
+ this.requestData();
1195
+ this.state = "inactive";
1196
+ this.clone.getTracks().forEach((track) => {
1197
+ track.stop();
1198
+ });
1199
+ this.processor.disconnect();
1200
+ this.input.disconnect();
1201
+ return clearInterval(this.slicing);
1202
+ }
1203
+ /**
1204
+ * Pauses recording of media streams.
1205
+ *
1206
+ * @return {undefined}
1207
+ *
1208
+ * @example
1209
+ * pauseButton.addEventListener('click', () => {
1210
+ * recorder.pause()
1211
+ * })
1212
+ */
1213
+ pause() {
1214
+ if (this.state !== "recording") return this.em.dispatchEvent(error("pause"));
1215
+ this.state = "paused";
1216
+ return this.em.dispatchEvent(new Event("pause"));
1217
+ }
1218
+ /**
1219
+ * Resumes media recording when it has been previously paused.
1220
+ *
1221
+ * @return {undefined}
1222
+ *
1223
+ * @example
1224
+ * resumeButton.addEventListener('click', () => {
1225
+ * recorder.resume()
1226
+ * })
1227
+ */
1228
+ resume() {
1229
+ if (this.state !== "paused") return this.em.dispatchEvent(error("resume"));
1230
+ this.state = "recording";
1231
+ return this.em.dispatchEvent(new Event("resume"));
1232
+ }
1233
+ /**
1234
+ * Raise a `dataavailable` event containing the captured media.
1235
+ *
1236
+ * @return {undefined}
1237
+ *
1238
+ * @example
1239
+ * this.on('nextData', () => {
1240
+ * recorder.requestData()
1241
+ * })
1242
+ */
1243
+ requestData() {
1244
+ if (this.state === "inactive") return this.em.dispatchEvent(error("requestData"));
1245
+ return this.encoder.postMessage(["dump", context.sampleRate]);
1246
+ }
1247
+ /**
1248
+ * Add listener for specified event type.
1249
+ *
1250
+ * @param {"start"|"stop"|"pause"|"resume"|"dataavailable"|"error"}
1251
+ * type Event type.
1252
+ * @param {function} listener The listener function.
1253
+ *
1254
+ * @return {undefined}
1255
+ *
1256
+ * @example
1257
+ * recorder.addEventListener('dataavailable', e => {
1258
+ * audio.src = URL.createObjectURL(e.data)
1259
+ * })
1260
+ */
1261
+ addEventListener(...args) {
1262
+ this.em.addEventListener(...args);
1263
+ }
1264
+ /**
1265
+ * Remove event listener.
1266
+ *
1267
+ * @param {"start"|"stop"|"pause"|"resume"|"dataavailable"|"error"}
1268
+ * type Event type.
1269
+ * @param {function} listener The same function used in `addEventListener`.
1270
+ *
1271
+ * @return {undefined}
1272
+ */
1273
+ removeEventListener(...args) {
1274
+ this.em.removeEventListener(...args);
1275
+ }
1276
+ /**
1277
+ * Calls each of the listeners registered for a given event.
1278
+ *
1279
+ * @param {Event} event The event object.
1280
+ *
1281
+ * @return {boolean} Is event was no canceled by any listener.
1282
+ */
1283
+ dispatchEvent(...args) {
1284
+ this.em.dispatchEvent(...args);
1285
+ }
1286
+ };
1287
+ /**
1288
+ * The MIME type that is being used for recording.
1289
+ * @type {string}
1290
+ */
1291
+ MediaRecorder$1.prototype.mimeType = "audio/wav";
1292
+ /**
1293
+ * Returns `true` if the MIME type specified is one the polyfill can record.
1294
+ *
1295
+ * This polyfill supports `audio/wav` and `audio/mpeg`.
1296
+ *
1297
+ * @param {string} mimeType The mimeType to check.
1298
+ *
1299
+ * @return {boolean} `true` on `audio/wav` and `audio/mpeg` MIME type.
1300
+ */
1301
+ MediaRecorder$1.isTypeSupported = (mimeType) => {
1302
+ return MediaRecorder$1.prototype.mimeType === mimeType;
1303
+ };
1304
+ /**
1305
+ * `true` if MediaRecorder can not be polyfilled in the current browser.
1306
+ * @type {boolean}
1307
+ *
1308
+ * @example
1309
+ * if (MediaRecorder.notSupported) {
1310
+ * showWarning('Audio recording is not supported in this browser')
1311
+ * }
1312
+ */
1313
+ MediaRecorder$1.notSupported = !navigator.mediaDevices || !AudioContext;
1314
+ /**
1315
+ * Converts RAW audio buffer to compressed audio files.
1316
+ * It will be loaded to Web Worker.
1317
+ * By default, WAVE encoder will be used.
1318
+ * @type {function}
1319
+ *
1320
+ * @example
1321
+ * MediaRecorder.prototype.mimeType = 'audio/ogg'
1322
+ * MediaRecorder.encoder = oggEncoder
1323
+ */
1324
+ MediaRecorder$1.encoder = wave_encoder_default;
1325
+ var audio_recorder_polyfill_default = MediaRecorder$1;
1326
+
1327
+ //#endregion
1328
+ //#region ../../node_modules/.pnpm/audio-recorder-polyfill@0.4.1/node_modules/audio-recorder-polyfill/mpeg-encoder/index.js
1329
+ var mpeg_encoder_default = () => {
1330
+ importScripts("https://cdnjs.cloudflare.com/ajax/libs/lamejs/1.2.0/lame.min.js");
1331
+ let CHANNELS = 1;
1332
+ let KBPS = 128;
1333
+ let DEFAULT_SAMPLE_RATE = 44100;
1334
+ let encoder;
1335
+ let recorded = new Int8Array();
1336
+ function concat(a, b) {
1337
+ if (b.length === 0) return a;
1338
+ let c = new Int8Array(a.length + b.length);
1339
+ c.set(a);
1340
+ c.set(b, a.length);
1341
+ return c;
1342
+ }
1343
+ function init(sampleRate) {
1344
+ encoder = new lamejs.Mp3Encoder(CHANNELS, sampleRate || DEFAULT_SAMPLE_RATE, KBPS);
1345
+ }
1346
+ function encode(buffer) {
1347
+ for (let i = 0; i < buffer.length; i++) buffer[i] = buffer[i] * 32767.5;
1348
+ let buf = encoder.encodeBuffer(buffer);
1349
+ recorded = concat(recorded, buf);
1350
+ }
1351
+ function dump() {
1352
+ let buf = encoder.flush();
1353
+ recorded = concat(recorded, buf);
1354
+ let buffer = recorded.buffer;
1355
+ recorded = new Int8Array();
1356
+ postMessage(buffer, [buffer]);
1357
+ }
1358
+ onmessage = (e) => {
1359
+ if (e.data[0] === "init") init(e.data[1]);
1360
+ else if (e.data[0] === "encode") encode(e.data[1]);
1361
+ else dump(e.data[1]);
1362
+ };
1363
+ };
1364
+
1365
+ //#endregion
1366
+ //#region ../infra/src/media/blobEncoding.ts
1367
+ /** Encodes a blob as raw base64 bytes (no `data:...;base64,` prefix). */
1368
+ function blobToRawBase64(blob) {
1369
+ return new Promise((resolve, reject) => {
1370
+ const reader = new FileReader();
1371
+ reader.onloadend = () => {
1372
+ const result = reader.result;
1373
+ if (typeof result !== "string") {
1374
+ reject(/* @__PURE__ */ new Error("Failed to encode blob as base64"));
1375
+ return;
1376
+ }
1377
+ const commaIndex = result.indexOf(",");
1378
+ resolve(commaIndex >= 0 ? result.slice(commaIndex + 1) : result);
1379
+ };
1380
+ reader.onerror = () => {
1381
+ reject(reader.error ?? /* @__PURE__ */ new Error("Failed to read blob"));
1382
+ };
1383
+ reader.readAsDataURL(blob);
1384
+ });
1385
+ }
1386
+
1387
+ //#endregion
1388
+ //#region ../infra/src/providers/browser/VoiceRecordingProvider.ts
1389
+ const AudioRecorderPolyfill = audio_recorder_polyfill_default;
1390
+ AudioRecorderPolyfill.encoder = mpeg_encoder_default;
1391
+ AudioRecorderPolyfill.prototype.mimeType = "audio/mpeg";
1392
+ const MIME_TYPE = "audio/mpeg";
1393
+ /**
1394
+ * Records the audio of a stream and produces a single MP3 blob. Used by the
1395
+ * Video Selfie voice-consent step to capture the spoken consent phrase
1396
+ * independently of the main video recording (which keeps running on its own
1397
+ * recorder).
1398
+ *
1399
+ * Records from a clone of the supplied stream so stopping this recorder never
1400
+ * tears down tracks the main recording is still using.
1401
+ */
1402
+ var VoiceRecordingProvider = class {
1403
+ constructor() {
1404
+ this.recorder = null;
1405
+ this.chunks = [];
1406
+ this._isRecording = false;
1407
+ }
1408
+ get isRecording() {
1409
+ return this._isRecording;
1410
+ }
1411
+ start(stream) {
1412
+ this.reset();
1413
+ this.chunks = [];
1414
+ const recorder = new AudioRecorderPolyfill(new MediaStream(stream.getAudioTracks()).clone());
1415
+ recorder.mimeType = MIME_TYPE;
1416
+ recorder.addEventListener("dataavailable", (event) => {
1417
+ if (event.data.size > 0) this.chunks.push(event.data);
1418
+ });
1419
+ recorder.start();
1420
+ this.recorder = recorder;
1421
+ this._isRecording = true;
1422
+ }
1423
+ stop() {
1424
+ const recorder = this.recorder;
1425
+ return new Promise((resolve) => {
1426
+ if (!recorder || !this._isRecording) {
1427
+ resolve(new Blob([], { type: MIME_TYPE }));
1428
+ return;
1429
+ }
1430
+ recorder.addEventListener("stop", () => {
1431
+ this._isRecording = false;
1432
+ recorder.stream?.getTracks().forEach((track) => track.stop());
1433
+ this.recorder = null;
1434
+ resolve(new Blob(this.chunks, { type: MIME_TYPE }));
1435
+ });
1436
+ recorder.stop();
1437
+ });
1438
+ }
1439
+ async stopAsBase64() {
1440
+ const blob = await this.stop();
1441
+ if (blob.size === 0) return "";
1442
+ return blobToRawBase64(blob);
1443
+ }
1444
+ reset() {
1445
+ const recorder = this.recorder;
1446
+ if (recorder && this._isRecording) {
1447
+ try {
1448
+ recorder.stop();
1449
+ } catch {}
1450
+ recorder.stream?.getTracks().forEach((track) => track.stop());
1451
+ }
1452
+ this.recorder = null;
1453
+ this._isRecording = false;
1454
+ }
1455
+ };
1456
+
1457
+ //#endregion
1458
+ //#region src/modules/video-selfie/videoSelfieConsentRecorder.ts
1459
+ function createConsentRecorder() {
1460
+ const provider = new VoiceRecordingProvider();
1461
+ return {
1462
+ start(stream) {
1463
+ provider.start(stream);
1464
+ },
1465
+ async submit() {
1466
+ const base64 = await provider.stopAsBase64();
1467
+ if (base64.length === 0) return { success: false };
1468
+ return addSpeech(base64);
1469
+ },
1470
+ cancel() {
1471
+ provider.reset();
1472
+ }
1473
+ };
1474
+ }
1475
+
1476
+ //#endregion
1477
+ //#region src/modules/video-selfie/videoSelfieFlowModuleMachine.ts
1478
+ /**
1479
+ * Parked flow-module machine for the `VIDEO_ONBOARDING` step.
1480
+ *
1481
+ * The video-selfie UI component owns the entire capture / streaming / upload
1482
+ * lifecycle (it creates its own {@link createVideoSelfieRecordingManager}) and
1483
+ * signals completion to the flow via `flowManager.completeModule()`
1484
+ * (`MODULE_COMPLETE`). This machine therefore only needs to hold the step open:
1485
+ * it starts in a non-final `running` state and never transitions, so the
1486
+ * orchestrated flow stays in `runningModule` until the UI advances it.
1487
+ *
1488
+ * **Completion contract:** the L2 `incode-video-selfie` web component MUST call
1489
+ * `flowManager.completeModule()` once the recording manager reaches `finished`
1490
+ * (success) or `error` (terminal failure). Until that event is sent, the flow
1491
+ * orchestrator remains in `runningModule` — this is intentional.
1492
+ *
1493
+ * **Abort / unmount:** if the user closes the module or the web component
1494
+ * unmounts before completion, the orchestrated flow manager's existing close /
1495
+ * abort path (`MODULE_CLOSE` / session teardown) is responsible for exiting the
1496
+ * step. This parked machine does not model those paths itself.
1497
+ *
1498
+ * Contrast {@link noOpFlowModuleMachine}, whose initial state is `final` — that
1499
+ * is used for headless steps (e.g. `IP_ADDRESS`) that must complete instantly
1500
+ * with no UI. Using a no-op here would skip the video-selfie UI entirely.
1501
+ */
1502
+ const videoSelfieFlowModuleMachine = setup({}).createMachine({
1503
+ id: "videoSelfieFlowModule",
1504
+ initial: "running",
1505
+ states: { running: {} }
1506
+ });
1507
+
1508
+ //#endregion
1509
+ export { createConsentRecorder, createVideoSelfieCameraWarmer, createVideoSelfieRecordingManager, facingModeForStep, getVideoSelfieQuestions, getVoiceConsentPhrase, resolveVideoSelfieSteps, videoSelfieFlowModuleMachine, videoSelfieWasmPipelines, warmupVideoSelfieWasm };