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

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