idmission-web-sdk 2.3.66 → 2.3.68

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 (63) hide show
  1. package/dist/components/common/InvisibleCanvas.d.ts +1 -0
  2. package/dist/components/common/InvisibleCanvas.d.ts.map +1 -1
  3. package/dist/components/id_capture/BarcodeReadabilityModelProvider.d.ts +29 -0
  4. package/dist/components/id_capture/BarcodeReadabilityModelProvider.d.ts.map +1 -0
  5. package/dist/components/id_capture/CapturedDocuments.d.ts +2 -1
  6. package/dist/components/id_capture/CapturedDocuments.d.ts.map +1 -1
  7. package/dist/components/id_capture/FocusModelProvider.d.ts.map +1 -1
  8. package/dist/components/id_capture/IdCapture.d.ts +1 -1
  9. package/dist/components/id_capture/IdCapture.d.ts.map +1 -1
  10. package/dist/components/id_capture/IdCaptureModelsProvider.d.ts +17 -1
  11. package/dist/components/id_capture/IdCaptureModelsProvider.d.ts.map +1 -1
  12. package/dist/components/id_capture/IdCaptureStateProvider.d.ts +7 -0
  13. package/dist/components/id_capture/IdCaptureStateProvider.d.ts.map +1 -1
  14. package/dist/components/id_capture/IdCaptureSuccess.d.ts.map +1 -1
  15. package/dist/components/id_capture/IdCaptureWizard.d.ts +1 -0
  16. package/dist/components/id_capture/IdCaptureWizard.d.ts.map +1 -1
  17. package/dist/components/submission/SubmissionProvider.d.ts +6 -0
  18. package/dist/components/submission/SubmissionProvider.d.ts.map +1 -1
  19. package/dist/components/submission/types.d.ts +2 -0
  20. package/dist/components/submission/types.d.ts.map +1 -1
  21. package/dist/lib/locales/de.d.ts +1 -0
  22. package/dist/lib/locales/de.d.ts.map +1 -1
  23. package/dist/lib/locales/es.d.ts +1 -0
  24. package/dist/lib/locales/es.d.ts.map +1 -1
  25. package/dist/lib/locales/fr.d.ts +1 -0
  26. package/dist/lib/locales/fr.d.ts.map +1 -1
  27. package/dist/lib/locales/index.d.ts +8 -0
  28. package/dist/lib/locales/index.d.ts.map +1 -1
  29. package/dist/lib/locales/it.d.ts +1 -0
  30. package/dist/lib/locales/it.d.ts.map +1 -1
  31. package/dist/lib/locales/ja.d.ts +1 -0
  32. package/dist/lib/locales/ja.d.ts.map +1 -1
  33. package/dist/lib/locales/pt.d.ts +1 -0
  34. package/dist/lib/locales/pt.d.ts.map +1 -1
  35. package/dist/lib/locales/ru.d.ts +1 -0
  36. package/dist/lib/locales/ru.d.ts.map +1 -1
  37. package/dist/lib/locales/zh.d.ts +1 -0
  38. package/dist/lib/locales/zh.d.ts.map +1 -1
  39. package/dist/lib/models/BarcodeReadability.d.ts +50 -0
  40. package/dist/lib/models/BarcodeReadability.d.ts.map +1 -0
  41. package/dist/lib/models/DocumentDetection.d.ts +1 -0
  42. package/dist/lib/models/DocumentDetection.d.ts.map +1 -1
  43. package/dist/lib/models/Focus.d.ts.map +1 -1
  44. package/dist/lib/models/defaults/BarcodeReadability.d.ts +2 -0
  45. package/dist/lib/models/defaults/BarcodeReadability.d.ts.map +1 -0
  46. package/dist/lib/models/defaults/index.d.ts +7 -0
  47. package/dist/lib/models/defaults/index.d.ts.map +1 -1
  48. package/dist/lib/models/preloadModels.d.ts +9 -5
  49. package/dist/lib/models/preloadModels.d.ts.map +1 -1
  50. package/dist/lib/utils/cropping.d.ts +3 -1
  51. package/dist/lib/utils/cropping.d.ts.map +1 -1
  52. package/dist/sdk2.cjs.development.js +1971 -1610
  53. package/dist/sdk2.cjs.development.js.map +1 -1
  54. package/dist/sdk2.cjs.production.js +1 -1
  55. package/dist/sdk2.cjs.production.js.map +1 -1
  56. package/dist/sdk2.esm.js +1972 -1611
  57. package/dist/sdk2.esm.js.map +1 -1
  58. package/dist/sdk2.umd.development.js +1624 -1263
  59. package/dist/sdk2.umd.development.js.map +1 -1
  60. package/dist/sdk2.umd.production.js +1 -1
  61. package/dist/sdk2.umd.production.js.map +1 -1
  62. package/dist/version.d.ts +1 -1
  63. package/package.json +1 -1
@@ -211,7 +211,7 @@
211
211
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
212
212
  };
213
213
 
214
- var webSdkVersion = '2.3.66';
214
+ var webSdkVersion = '2.3.68';
215
215
 
216
216
  function getPlatform() {
217
217
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -472,27 +472,27 @@
472
472
  if (!portalLocation) return element;
473
473
  return /*#__PURE__*/reactDom.createPortal(element, portalLocation);
474
474
  };
475
- var GuidanceMessage = styled.div(templateObject_2$I || (templateObject_2$I = __makeTemplateObject(["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"], ["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"])), function (props) {
475
+ var GuidanceMessage = styled.div(templateObject_2$J || (templateObject_2$J = __makeTemplateObject(["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"], ["\n margin-left: auto;\n margin-right: auto;\n background: ", ";\n color: ", ";\n border-radius: 8px;\n z-index: 10001;\n padding: 16px 24px;\n font-size: 18px;\n font-weight: bold;\n box-shadow:\n 0 1px 3px 0 rgb(0 0 0 / 0.1),\n 0 1px 2px -1px rgb(0 0 0 / 0.1);\n"])), function (props) {
476
476
  var _a, _b, _c, _d, _e, _f;
477
477
  return (_f = (_a = props.$background) !== null && _a !== void 0 ? _a : (_e = (_c = (_b = props.theme) === null || _b === void 0 ? void 0 : _b.guidanceMessages) === null || _c === void 0 ? void 0 : _c[(_d = props.$variant) !== null && _d !== void 0 ? _d : 'default']) === null || _e === void 0 ? void 0 : _e.backgroundColor) !== null && _f !== void 0 ? _f : 'white';
478
478
  }, function (props) {
479
479
  var _a, _b, _c, _d, _e, _f;
480
480
  return (_f = (_a = props.$textColor) !== null && _a !== void 0 ? _a : (_e = (_c = (_b = props.theme) === null || _b === void 0 ? void 0 : _b.guidanceMessages) === null || _c === void 0 ? void 0 : _c[(_d = props.$variant) !== null && _d !== void 0 ? _d : 'default']) === null || _e === void 0 ? void 0 : _e.textColor) !== null && _f !== void 0 ? _f : 'black';
481
481
  });
482
- var templateObject_1$Q, templateObject_2$I;
482
+ var templateObject_1$Q, templateObject_2$J;
483
483
 
484
484
  var wavesAnimation = styled.keyframes(templateObject_1$P || (templateObject_1$P = __makeTemplateObject(["\n 0% {\n opacity: 0;\n transform: scale3d(1, 1, 1);\n }\n 80% {\n opacity: 1;\n }\n 100% {\n transform: scale3d(2, 2, 1);\n opacity: 0;\n }\n"], ["\n 0% {\n opacity: 0;\n transform: scale3d(1, 1, 1);\n }\n 80% {\n opacity: 1;\n }\n 100% {\n transform: scale3d(2, 2, 1);\n opacity: 0;\n }\n"])));
485
- var progressBarAnimation = styled.keyframes(templateObject_2$H || (templateObject_2$H = __makeTemplateObject(["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"], ["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"])));
485
+ var progressBarAnimation = styled.keyframes(templateObject_2$I || (templateObject_2$I = __makeTemplateObject(["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"], ["\n 0% {\n width: 0;\n }\n 100% {\n width: 100%;\n }\n"])));
486
486
  var dualRingSpinnerAnimation = styled.keyframes(templateObject_3$u || (templateObject_3$u = __makeTemplateObject(["\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n"], ["\n 0% {\n transform: rotate(0deg);\n }\n 100% {\n transform: rotate(360deg);\n }\n"])));
487
487
  var progressBorderAnimation = styled.keyframes(templateObject_4$n || (templateObject_4$n = __makeTemplateObject(["\n to {\n stroke-dashoffset: 0;\n }\n"], ["\n to {\n stroke-dashoffset: 0;\n }\n"])));
488
- var templateObject_1$P, templateObject_2$H, templateObject_3$u, templateObject_4$n;
488
+ var templateObject_1$P, templateObject_2$I, templateObject_3$u, templateObject_4$n;
489
489
 
490
490
  var OverlayContainer = styled.div(templateObject_1$O || (templateObject_1$O = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n display: flex;\n flex-direction: column;\n\n overflow-x: hidden;\n overflow-y: auto;\n\n background: ", ";\n ", "\n\n z-index: 10000;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n\n display: flex;\n flex-direction: column;\n\n overflow-x: hidden;\n overflow-y: auto;\n\n background: ", ";\n ", "\n\n z-index: 10000;\n"])), function (props) {
491
491
  return props.theme.background ? "".concat(props.theme.background) : "white";
492
492
  }, function (props) {
493
493
  return props.theme.textColor ? "color: ".concat(props.theme.textColor, ";") : "";
494
494
  });
495
- var OverlayInner$2 = styled.div(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"], ["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"])), function (props) {
495
+ var OverlayInner$2 = styled.div(templateObject_2$H || (templateObject_2$H = __makeTemplateObject(["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"], ["\n text-align: ", ";\n display: flex;\n flex-direction: column;\n flex-wrap: nowrap;\n width: 100%;\n height: 100%;\n ", "\n"])), function (props) {
496
496
  var _a;
497
497
  return (_a = props.theme.textAlign) !== null && _a !== void 0 ? _a : 'center';
498
498
  }, function (props) {
@@ -540,7 +540,7 @@
540
540
  var LoadingOverlayProgressContainer = styled.div(templateObject_20 || (templateObject_20 = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n"])));
541
541
  var LoadingOverlayCustomLoadingGraphic = styled.img(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n transform-style: preserve-3d;\n"], ["\n transform-style: preserve-3d;\n"])));
542
542
  var LoadingOverlayContinueButtonContainer = styled.div(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n display: flex;\n"], ["\n display: flex;\n"])));
543
- var templateObject_1$O, templateObject_2$G, templateObject_3$t, templateObject_4$m, templateObject_5$e, templateObject_6$9, templateObject_7$5, templateObject_8$4, templateObject_9$2, templateObject_10$1, templateObject_11$1, templateObject_12$1, templateObject_13$1, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22;
543
+ var templateObject_1$O, templateObject_2$H, templateObject_3$t, templateObject_4$m, templateObject_5$e, templateObject_6$9, templateObject_7$5, templateObject_8$4, templateObject_9$2, templateObject_10$1, templateObject_11$1, templateObject_12$1, templateObject_13$1, templateObject_14, templateObject_15, templateObject_16, templateObject_17, templateObject_18, templateObject_19, templateObject_20, templateObject_21, templateObject_22;
544
544
 
545
545
  function _extends() {
546
546
  return _extends = Object.assign ? Object.assign.bind() : function (n) {
@@ -2083,6 +2083,11 @@
2083
2083
  idFrontImage: null,
2084
2084
  idBackImage: null,
2085
2085
  passportImage: null,
2086
+ idFrontIrImage: null,
2087
+ idBackIrImage: null,
2088
+ idFrontUvImage: null,
2089
+ idBackUvImage: null,
2090
+ idBarcodeImage: null,
2086
2091
  selfieImage: null,
2087
2092
  signatureData: null,
2088
2093
  signatureVideoUrl: null,
@@ -2113,6 +2118,9 @@
2113
2118
  setIdBackUvImage: function setIdBackUvImage() {
2114
2119
  return null;
2115
2120
  },
2121
+ setIdBarcodeImage: function setIdBarcodeImage() {
2122
+ return null;
2123
+ },
2116
2124
  setSelfieImage: function setSelfieImage() {
2117
2125
  return null;
2118
2126
  },
@@ -2280,53 +2288,56 @@
2280
2288
  passportImage = _13[0],
2281
2289
  setPassportImage = _13[1];
2282
2290
  var _14 = React.useState(null),
2283
- selfieImage = _14[0],
2284
- setSelfieImage = _14[1];
2291
+ idBarcodeImage = _14[0],
2292
+ setIdBarcodeImage = _14[1];
2285
2293
  var _15 = React.useState(null),
2286
- signatureData = _15[0],
2287
- setSignatureData = _15[1];
2294
+ selfieImage = _15[0],
2295
+ setSelfieImage = _15[1];
2288
2296
  var _16 = React.useState(null),
2289
- signatureVideoUrl = _16[0],
2290
- setSignatureVideoUrl = _16[1];
2297
+ signatureData = _16[0],
2298
+ setSignatureData = _16[1];
2291
2299
  var _17 = React.useState(null),
2292
- idCaptureVideoUrl = _17[0],
2293
- setIdCaptureVideoUrl = _17[1];
2300
+ signatureVideoUrl = _17[0],
2301
+ setSignatureVideoUrl = _17[1];
2294
2302
  var _18 = React.useState(null),
2295
- idCaptureVideoIdFrontImage = _18[0],
2296
- setIdCaptureVideoIdFrontImage = _18[1];
2303
+ idCaptureVideoUrl = _18[0],
2304
+ setIdCaptureVideoUrl = _18[1];
2297
2305
  var _19 = React.useState(null),
2298
- idCaptureVideoIdBackImage = _19[0],
2299
- setIdCaptureVideoIdBackImage = _19[1];
2306
+ idCaptureVideoIdFrontImage = _19[0],
2307
+ setIdCaptureVideoIdFrontImage = _19[1];
2300
2308
  var _20 = React.useState(null),
2301
- idCaptureVideoAudioUrl = _20[0],
2302
- setIdCaptureVideoAudioUrl = _20[1];
2309
+ idCaptureVideoIdBackImage = _20[0],
2310
+ setIdCaptureVideoIdBackImage = _20[1];
2303
2311
  var _21 = React.useState(null),
2304
- idCaptureVideoAudioStartsAt = _21[0],
2305
- setIdCaptureVideoAudioStartsAt = _21[1];
2312
+ idCaptureVideoAudioUrl = _21[0],
2313
+ setIdCaptureVideoAudioUrl = _21[1];
2306
2314
  var _22 = React.useState(null),
2307
- expectedAudioText = _22[0],
2308
- setExpectedAudioText = _22[1];
2315
+ idCaptureVideoAudioStartsAt = _22[0],
2316
+ setIdCaptureVideoAudioStartsAt = _22[1];
2309
2317
  var _23 = React.useState(null),
2310
- additionalDocuments = _23[0],
2311
- setAdditionalDocuments = _23[1];
2318
+ expectedAudioText = _23[0],
2319
+ setExpectedAudioText = _23[1];
2312
2320
  var _24 = React.useState(null),
2313
- geolocationResult = _24[0],
2314
- setGeolocationResult = _24[1];
2315
- var _25 = React.useState(0),
2316
- geolocationAttempts = _25[0],
2317
- setGeolocationAttempts = _25[1];
2318
- var _26 = React.useState(false),
2319
- geolocationBlocked = _26[0],
2320
- setGeolocationBlocked = _26[1];
2321
- var _27 = React.useState([]),
2322
- idFrontCaptureAttempts = _27[0],
2323
- setIdFrontCaptureAttempts = _27[1];
2321
+ additionalDocuments = _24[0],
2322
+ setAdditionalDocuments = _24[1];
2323
+ var _25 = React.useState(null),
2324
+ geolocationResult = _25[0],
2325
+ setGeolocationResult = _25[1];
2326
+ var _26 = React.useState(0),
2327
+ geolocationAttempts = _26[0],
2328
+ setGeolocationAttempts = _26[1];
2329
+ var _27 = React.useState(false),
2330
+ geolocationBlocked = _27[0],
2331
+ setGeolocationBlocked = _27[1];
2324
2332
  var _28 = React.useState([]),
2325
- idBackCaptureAttempts = _28[0],
2326
- setIdBackCaptureAttempts = _28[1];
2333
+ idFrontCaptureAttempts = _28[0],
2334
+ setIdFrontCaptureAttempts = _28[1];
2327
2335
  var _29 = React.useState([]),
2328
- selfieCaptureAttempts = _29[0],
2329
- setSelfieCaptureAttempts = _29[1];
2336
+ idBackCaptureAttempts = _29[0],
2337
+ setIdBackCaptureAttempts = _29[1];
2338
+ var _30 = React.useState([]),
2339
+ selfieCaptureAttempts = _30[0],
2340
+ setSelfieCaptureAttempts = _30[1];
2330
2341
  var logIdFrontCaptureAttempt = React.useCallback(function (attempt) {
2331
2342
  setIdFrontCaptureAttempts(function (attempts) {
2332
2343
  return __spreadArray(__spreadArray([], attempts, true), [attempt], false);
@@ -2452,6 +2463,7 @@
2452
2463
  idFrontImage: idFrontImage,
2453
2464
  idBackImage: idBackImage,
2454
2465
  passportImage: passportImage,
2466
+ idBarcodeImage: idBarcodeImage,
2455
2467
  selfieImage: selfieImage
2456
2468
  };
2457
2469
  _a = signatureVideoUrl;
@@ -2557,6 +2569,9 @@
2557
2569
  if (documents.passportImage) {
2558
2570
  submissionRequest.customerData.idData.idImageFront = documents.passportImage;
2559
2571
  }
2572
+ if (documents.idBarcodeImage) {
2573
+ submissionRequest.customerData.idData.idBarcodeImage = documents.idBarcodeImage;
2574
+ }
2560
2575
  if (documents.idFrontIrImage) {
2561
2576
  submissionRequest.customerData.idData.idFrontIrImage = documents.idFrontIrImage;
2562
2577
  }
@@ -2645,7 +2660,7 @@
2645
2660
  }
2646
2661
  });
2647
2662
  });
2648
- }, [additionalDocuments, bypassAgeValidation, bypassNameMatching, cardData, clientRequestID, companyId, customerDataMatchConfig, deduplicationEnabled, deduplicationSynchronous, documentServiceUrl, enrollmentId, expectedAudioText, geolocationResult, idBackCaptureAttempts, idBackImage, idBackImageRequired, idBackIrImage, idBackUvImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idCardForFaceMatch, idData, idFrontCaptureAttempts, idFrontImage, idFrontIrImage, idFrontUvImage, idImageResolutionCheck, jobId, manualReviewRequired, needImmediateResponse, passportImage, personalData, selfieCaptureAttempts, selfieImage, signatureData, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
2663
+ }, [additionalDocuments, bypassAgeValidation, bypassNameMatching, cardData, clientRequestID, companyId, customerDataMatchConfig, deduplicationEnabled, deduplicationSynchronous, documentServiceUrl, enrollmentId, expectedAudioText, geolocationResult, idBackCaptureAttempts, idBackImage, idBackImageRequired, idBackIrImage, idBackUvImage, idBarcodeImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idCardForFaceMatch, idData, idFrontCaptureAttempts, idFrontImage, idFrontIrImage, idFrontUvImage, idImageResolutionCheck, jobId, manualReviewRequired, needImmediateResponse, passportImage, personalData, selfieCaptureAttempts, selfieImage, signatureData, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
2649
2664
  var defaultOnSubmit = React.useCallback(function () {
2650
2665
  return __awaiter(void 0, void 0, void 0, function () {
2651
2666
  var submissionResponse_1, payload, host, endpoint, response, statusMessage, submissionResponse_2, e_1, err;
@@ -2923,6 +2938,7 @@
2923
2938
  idFrontUvImage: idFrontUvImage,
2924
2939
  idBackUvImage: idBackUvImage,
2925
2940
  passportImage: passportImage,
2941
+ idBarcodeImage: idBarcodeImage,
2926
2942
  selfieImage: selfieImage,
2927
2943
  signatureData: signatureData,
2928
2944
  signatureVideoUrl: signatureVideoUrl,
@@ -2939,6 +2955,7 @@
2939
2955
  setIdBackIrImage: setIdBackIrImage,
2940
2956
  setIdFrontUvImage: setIdFrontUvImage,
2941
2957
  setIdBackUvImage: setIdBackUvImage,
2958
+ setIdBarcodeImage: setIdBarcodeImage,
2942
2959
  setSelfieImage: setSelfieImage,
2943
2960
  setSignatureData: setSignatureData,
2944
2961
  setSignatureVideoUrl: setSignatureVideoUrl,
@@ -2957,7 +2974,7 @@
2957
2974
  checkLiveness: checkLiveness,
2958
2975
  retryLocationAccess: retryLocationAccess
2959
2976
  };
2960
- }, [additionalDocuments, checkLiveness, environment, idBackImage, idBackIrImage, idBackUvImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idFrontImage, idFrontIrImage, idFrontUvImage, livenessCheckRequest, logIdBackCaptureAttempt, logIdFrontCaptureAttempt, logSelfieCaptureAttempt, passportImage, retryLocationAccess, selfieImage, signatureData, signatureVideoUrl, submissionError, submissionRequest, submissionResponse, submissionStatus, submit, uploadDocument]);
2977
+ }, [additionalDocuments, checkLiveness, environment, idBackImage, idBackIrImage, idBackUvImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idFrontImage, idFrontIrImage, idFrontUvImage, livenessCheckRequest, logIdBackCaptureAttempt, logIdFrontCaptureAttempt, logSelfieCaptureAttempt, idBarcodeImage, passportImage, retryLocationAccess, selfieImage, signatureData, signatureVideoUrl, submissionError, submissionRequest, submissionResponse, submissionStatus, submit, uploadDocument]);
2961
2978
  return /*#__PURE__*/React.createElement(SubmissionContext.Provider, {
2962
2979
  value: value
2963
2980
  }, geolocationRequired && geolocationBlocked ? ( /*#__PURE__*/React.createElement(GeolocationAccessDeniedOverlay, null)) : children, submissionError && ( /*#__PURE__*/React.createElement(SubmissionErrorOverlay, {
@@ -8075,97 +8092,6 @@
8075
8092
  });
8076
8093
  }
8077
8094
 
8078
- function getFrameDimensions(frame) {
8079
- var frameWidth = frame.width,
8080
- frameHeight = frame.height;
8081
- if (frame instanceof HTMLImageElement) {
8082
- frameWidth = frame.naturalWidth;
8083
- frameHeight = frame.naturalHeight;
8084
- }
8085
- if (frame instanceof HTMLVideoElement) {
8086
- frameWidth = frame.videoWidth;
8087
- frameHeight = frame.videoHeight;
8088
- }
8089
- return [frameWidth, frameHeight];
8090
- }
8091
-
8092
- var InvisibleCanvas = styled.canvas(templateObject_1$N || (templateObject_1$N = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
8093
- function drawToCanvas(canvas, frame, width, height) {
8094
- if (!canvas) return;
8095
- var ctx = canvas.getContext('2d');
8096
- if (!ctx) return;
8097
- if (!width || !height) {
8098
- var _a = getFrameDimensions(frame),
8099
- frameWidth = _a[0],
8100
- frameHeight = _a[1];
8101
- width || (width = frameWidth);
8102
- height || (height = frameHeight);
8103
- }
8104
- canvas.width = width;
8105
- canvas.height = height;
8106
- ctx.drawImage(frame, 0, 0, width, height);
8107
- }
8108
- function clearCanvas(canvas) {
8109
- var _a;
8110
- (_a = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.clearRect(0, 0, canvas === null || canvas === void 0 ? void 0 : canvas.width, canvas === null || canvas === void 0 ? void 0 : canvas.height);
8111
- }
8112
- var templateObject_1$N;
8113
-
8114
- function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
8115
- var _a;
8116
- if (quality === void 0) {
8117
- quality = 0.92;
8118
- }
8119
- if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
8120
- var rawCtx = rawCanvas.getContext('2d');
8121
- var cropCtx = cropCanvas.getContext('2d');
8122
- var resizeCtx = resizeCanvas.getContext('2d');
8123
- if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
8124
- rawCanvas.width = frame.width;
8125
- rawCanvas.height = frame.height;
8126
- rawCtx.putImageData(frame, 0, 0);
8127
- if (frame.height > frame.width) {
8128
- cropCanvas.width = frame.width;
8129
- cropCanvas.height = frame.height;
8130
- cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
8131
- } else {
8132
- var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
8133
- xMin: 0,
8134
- width: frame.width
8135
- },
8136
- xMin = _b.xMin,
8137
- width = _b.width;
8138
- var desiredWidth = frame.height * 0.6;
8139
- var faceCenterX = xMin + width / 2;
8140
- var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
8141
- cropCanvas.width = desiredWidth;
8142
- cropCanvas.height = frame.height;
8143
- cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
8144
- }
8145
- resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
8146
- resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
8147
- resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
8148
- var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
8149
- log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
8150
- clearCanvas(rawCanvas);
8151
- clearCanvas(cropCanvas);
8152
- clearCanvas(resizeCanvas);
8153
- return dataURL;
8154
- }
8155
- function cropToDetectedObjectBox(frame, box, canvas) {
8156
- canvas || (canvas = document.createElement('canvas'));
8157
- var ctx = canvas.getContext('2d');
8158
- if (!ctx) throw new Error('could not get 2d context');
8159
- var xMin = box.xMin,
8160
- yMin = box.yMin,
8161
- width = box.width,
8162
- height = box.height;
8163
- canvas.width = width;
8164
- canvas.height = height;
8165
- ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height);
8166
- return canvas;
8167
- }
8168
-
8169
8095
  var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
8170
8096
  var imageSegmenterModelSizeInBytes = 256440.32;
8171
8097
  // The idea here is that we globally set a cache key based on the time at page load. That way our built-in speed test
@@ -8295,6 +8221,192 @@
8295
8221
  });
8296
8222
  }
8297
8223
 
8224
+ var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
8225
+
8226
+ var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
8227
+
8228
+ var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
8229
+
8230
+ var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/blazeface20240207/blaze_face_short_range.tflite");
8231
+
8232
+ var defaultBarcodeReadabilityModelPath = "".concat(DEFAULT_CDN_URL, "/models/BarcodeReadability/BarcodeReadability-20250815_120417.tflite");
8233
+
8234
+ var defaultModelPaths = {
8235
+ documentDetector: defaultDocumentDetectorModelPath,
8236
+ focus: defaultFocusModelPath,
8237
+ faceDetection: defaultFaceDetectorModelPath,
8238
+ barcodeReadability: defaultBarcodeReadabilityModelPath
8239
+ };
8240
+
8241
+ var preloadModels = function preloadModels(_a) {
8242
+ return __awaiter(void 0, [_a], void 0, function (_b) {
8243
+ var preloadTasks;
8244
+ var _c = _b.documentDetectionModel,
8245
+ documentDetectionModel = _c === void 0 ? true : _c,
8246
+ _d = _b.focusModel,
8247
+ focusModel = _d === void 0 ? true : _d,
8248
+ _e = _b.faceDetectionModel,
8249
+ faceDetectionModel = _e === void 0 ? true : _e,
8250
+ _f = _b.barcodeReadabilityModel,
8251
+ barcodeReadabilityModel = _f === void 0 ? true : _f;
8252
+ return __generator(this, function (_g) {
8253
+ switch (_g.label) {
8254
+ case 0:
8255
+ return [4 /*yield*/, probeModelCapabilities()];
8256
+ case 1:
8257
+ _g.sent();
8258
+ preloadTasks = [];
8259
+ if (documentDetectionModel) {
8260
+ preloadTasks.push(preloadDocumentDetectorDependencies);
8261
+ }
8262
+ if (focusModel) {
8263
+ preloadTasks.push(preloadFocusModelDependencies);
8264
+ }
8265
+ if (faceDetectionModel) {
8266
+ preloadTasks.push(preloadFaceDetectorDependencies);
8267
+ }
8268
+ if (barcodeReadabilityModel) {
8269
+ preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
8270
+ }
8271
+ return [4 /*yield*/, Promise.all(preloadTasks)];
8272
+ case 2:
8273
+ _g.sent();
8274
+ return [2 /*return*/];
8275
+ }
8276
+ });
8277
+ });
8278
+ };
8279
+ var progressByUrl = {};
8280
+ var progressByUseCase = {
8281
+ visionRuntime: {
8282
+ loaded: 0,
8283
+ total: 0
8284
+ },
8285
+ documentDetector: {
8286
+ loaded: 0,
8287
+ total: 0
8288
+ },
8289
+ focus: {
8290
+ loaded: 0,
8291
+ total: 0
8292
+ },
8293
+ faceDetection: {
8294
+ loaded: 0,
8295
+ total: 0
8296
+ },
8297
+ barcodeReadability: {
8298
+ loaded: 0,
8299
+ total: 0
8300
+ }
8301
+ };
8302
+ function preloadDependency(url) {
8303
+ return __awaiter(this, void 0, void 0, function () {
8304
+ return __generator(this, function (_a) {
8305
+ return [2 /*return*/, new Promise(function (resolve, reject) {
8306
+ var req = new XMLHttpRequest();
8307
+ req.addEventListener('progress', function (event) {
8308
+ if (!event.lengthComputable) return;
8309
+ progressByUrl[url] = event;
8310
+ document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
8311
+ detail: {
8312
+ url: url,
8313
+ loaded: event.loaded,
8314
+ total: event.total
8315
+ }
8316
+ }));
8317
+ });
8318
+ req.addEventListener('loadend', function () {
8319
+ resolve(req.readyState === 4 && req.status === 200);
8320
+ });
8321
+ req.addEventListener('error', reject);
8322
+ req.open('GET', url, true);
8323
+ req.send();
8324
+ })];
8325
+ });
8326
+ });
8327
+ }
8328
+ var modelsPreloading = {
8329
+ documentDetector: false,
8330
+ focus: false,
8331
+ faceDetection: false,
8332
+ barcodeReadability: false
8333
+ };
8334
+ var preloadDocumentDetectorDependencies = function preloadDocumentDetectorDependencies() {
8335
+ return preloadModelDependencies('documentDetector');
8336
+ };
8337
+ var preloadFocusModelDependencies = function preloadFocusModelDependencies() {
8338
+ return preloadModelDependencies('focus');
8339
+ };
8340
+ var preloadFaceDetectorDependencies = function preloadFaceDetectorDependencies() {
8341
+ return preloadModelDependencies('faceDetection');
8342
+ };
8343
+ var preloadBarcodeReadabilityModelDependencies = function preloadBarcodeReadabilityModelDependencies() {
8344
+ return preloadModelDependencies('barcodeReadability');
8345
+ };
8346
+ function preloadModelDependencies(model) {
8347
+ return __awaiter(this, void 0, void 0, function () {
8348
+ function handleModelDownloadProgress(event) {
8349
+ var detail = event.detail;
8350
+ if (!dependencies.includes(detail.url)) return;
8351
+ progressByUseCase[model] = sumUpProgressForDependencies(dependencies);
8352
+ document.dispatchEvent(new CustomEvent("idmission.preloadProgress.".concat(model), {
8353
+ detail: progressByUseCase[model]
8354
+ }));
8355
+ }
8356
+ var dependencies;
8357
+ return __generator(this, function (_a) {
8358
+ switch (_a.label) {
8359
+ case 0:
8360
+ if (modelsPreloading[model]) return [2 /*return*/, new Promise(function (resolve) {
8361
+ var i = setInterval(function () {
8362
+ if (!modelsPreloading[model]) {
8363
+ clearInterval(i);
8364
+ resolve();
8365
+ }
8366
+ }, 100);
8367
+ })];
8368
+ modelsPreloading[model] = true;
8369
+ return [4 /*yield*/, probeModelCapabilities()];
8370
+ case 1:
8371
+ _a.sent();
8372
+ if (modelCapabilities.delegate === 'NONE') {
8373
+ throw new Error("No available delegate for ".concat(model, " model."));
8374
+ }
8375
+ dependencies = [defaultModelPaths[model]];
8376
+ document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8377
+ _a.label = 2;
8378
+ case 2:
8379
+ _a.trys.push([2,, 4, 5]);
8380
+ return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
8381
+ case 3:
8382
+ _a.sent();
8383
+ return [3 /*break*/, 5];
8384
+ case 4:
8385
+ document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8386
+ modelsPreloading[model] = false;
8387
+ return [7 /*endfinally*/];
8388
+ case 5:
8389
+ return [2 /*return*/];
8390
+ }
8391
+ });
8392
+ });
8393
+ }
8394
+ function progressToPercentage(progress) {
8395
+ return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
8396
+ }
8397
+ function sumUpProgressForDependencies(dependencies) {
8398
+ return dependencies.reduce(function (result, dependency) {
8399
+ var dependencyProgress = progressByUrl[dependency];
8400
+ if (!dependencyProgress) return result;
8401
+ result.loaded += dependencyProgress.loaded;
8402
+ result.total += dependencyProgress.total;
8403
+ return result;
8404
+ }, {
8405
+ loaded: 0,
8406
+ total: 0
8407
+ });
8408
+ }
8409
+
8298
8410
  function convertBoundingBox(box) {
8299
8411
  var _a, _b, _c, _d, _e, _f, _g, _h;
8300
8412
  return {
@@ -8349,53 +8461,50 @@
8349
8461
  return sum / len;
8350
8462
  }
8351
8463
 
8352
- var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
8353
-
8354
- var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
8355
-
8356
- var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
8357
-
8358
- var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/blazeface20240207/blaze_face_short_range.tflite");
8359
-
8360
- var defaultFocusModelLoadTimeoutMs = 45000;
8361
- var defaultFocusThresholds = {
8362
- idCardFront: {
8363
- desktop: 0,
8364
- mobile: 0.3
8365
- },
8366
- idCardBack: {
8367
- desktop: 0,
8368
- mobile: 0.3
8369
- },
8370
- passport: {
8371
- desktop: 0,
8372
- mobile: 0.3
8373
- },
8374
- singlePage: {
8375
- desktop: 0,
8376
- mobile: 0.3
8464
+ var defaultDocumentDetectionScoreThreshold = 0.1;
8465
+ var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
8466
+ var defaultDocumentDetectionThresholds = {
8467
+ idCardFront: 0.6,
8468
+ idCardBack: 0.6,
8469
+ passport: 0.4,
8470
+ singlePage: 0.4,
8471
+ stability: {
8472
+ idCardFront: 0.85,
8473
+ idCardBack: 0.85,
8474
+ passport: 0.5,
8475
+ singlePage: 0.5
8377
8476
  }
8378
8477
  };
8379
- var classifier = null;
8380
- var classifierSettings = null;
8381
- function loadFocusModel() {
8382
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
8478
+ var documentTypeDisplayNames = {
8479
+ idCardFront: 'ID card front',
8480
+ idCardBack: 'ID card back',
8481
+ passport: 'Passport',
8482
+ singlePage: 'Single page',
8483
+ none: 'None'
8484
+ };
8485
+ var detector$1 = null;
8486
+ var detectorSettings$1 = null;
8487
+ function loadDocumentDetector() {
8488
+ return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
8383
8489
  var _a, _b;
8384
8490
  if (modelAssetPath === void 0) {
8385
- modelAssetPath = defaultFocusModelPath;
8491
+ modelAssetPath = defaultDocumentDetectorModelPath;
8492
+ }
8493
+ if (scoreThreshold === void 0) {
8494
+ scoreThreshold = defaultDocumentDetectionScoreThreshold;
8386
8495
  }
8387
8496
  return __generator(this, function (_c) {
8388
8497
  switch (_c.label) {
8389
8498
  case 0:
8390
- if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
8391
- closeFocusModel();
8392
- return [4 /*yield*/, preloadFocusModelDependencies()];
8499
+ if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.scoreThreshold) === scoreThreshold) return [2 /*return*/, detector$1];
8500
+ closeDocumentDetector();
8501
+ return [4 /*yield*/, preloadDocumentDetectorDependencies()];
8393
8502
  case 1:
8394
8503
  _c.sent();
8395
8504
  if (modelCapabilities.delegate === 'NONE') {
8396
- throw new Error('No available delegate for focus detector.');
8505
+ throw new Error('No available delegate for document detector.');
8397
8506
  }
8398
- _b = (_a = Ua).createFromOptions;
8507
+ _b = (_a = lh).createFromOptions;
8399
8508
  return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
8400
8509
  case 2:
8401
8510
  return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
@@ -8404,44 +8513,48 @@
8404
8513
  delegate: modelCapabilities.delegate
8405
8514
  },
8406
8515
  // canvas: document.createElement('canvas'),
8516
+ scoreThreshold: scoreThreshold,
8407
8517
  runningMode: 'VIDEO'
8408
8518
  }])];
8409
8519
  case 3:
8410
- classifier = _c.sent();
8411
- classifierSettings = {
8412
- modelAssetPath: modelAssetPath
8520
+ detector$1 = _c.sent();
8521
+ detectorSettings$1 = {
8522
+ modelAssetPath: modelAssetPath,
8523
+ scoreThreshold: scoreThreshold
8413
8524
  };
8414
- return [2 /*return*/, classifier];
8525
+ return [2 /*return*/, detector$1];
8415
8526
  }
8416
8527
  });
8417
8528
  });
8418
8529
  }
8419
- function closeFocusModel() {
8420
- classifier === null || classifier === void 0 ? void 0 : classifier.close();
8421
- classifier = null;
8422
- classifierSettings = null;
8530
+ function closeDocumentDetector() {
8531
+ detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
8532
+ detector$1 = null;
8533
+ detectorSettings$1 = null;
8423
8534
  }
8424
- function useLoadFocusModel(_a) {
8425
- var _b = _a.modelPath,
8426
- modelPath = _b === void 0 ? defaultFocusModelPath : _b,
8427
- _c = _a.modelLoadTimeoutMs,
8428
- modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
8535
+ function useLoadDocumentDetector(_a) {
8536
+ var _b = _a.shouldLoadModels,
8537
+ shouldLoadModels = _b === void 0 ? true : _b,
8538
+ _c = _a.modelPath,
8539
+ modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
8540
+ _d = _a.modelLoadTimeoutMs,
8541
+ modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
8542
+ _e = _a.scoreThreshold,
8543
+ scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
8429
8544
  onModelError = _a.onModelError,
8430
- videoRef = _a.videoRef,
8431
- _d = _a.shouldLoadModels,
8432
- shouldLoadModels = _d === void 0 ? true : _d;
8433
- var _e = React.useState('not-started'),
8434
- modelLoadState = _e[0],
8435
- setModelLoadState = _e[1];
8436
- var _f = React.useState(0),
8437
- modelDownloadProgress = _f[0],
8438
- setModelDownloadProgress = _f[1];
8545
+ videoRef = _a.videoRef;
8546
+ var _f = React.useState('not-started'),
8547
+ modelLoadState = _f[0],
8548
+ setModelLoadState = _f[1];
8439
8549
  var _g = React.useState(null),
8440
8550
  modelWarmingStartedAt = _g[0],
8441
8551
  setModelWarmingStartedAt = _g[1];
8442
- var _h = React.useState(null),
8443
- modelError = _h[0],
8444
- setModelError = _h[1];
8552
+ var _h = React.useState(0),
8553
+ modelDownloadProgress = _h[0],
8554
+ setModelDownloadProgress = _h[1];
8555
+ var _j = React.useState(null),
8556
+ modelError = _j[0],
8557
+ setModelError = _j[1];
8445
8558
  React.useEffect(function loadModel() {
8446
8559
  var _this = this;
8447
8560
  if (!shouldLoadModels) return;
@@ -8450,21 +8563,24 @@
8450
8563
  function handleDownloadProgress(event) {
8451
8564
  setModelDownloadProgress(progressToPercentage(event.detail));
8452
8565
  }
8453
- document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
8566
+ document.addEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
8454
8567
  var modelLoadTimeout = setTimeout(function () {
8455
8568
  setModelError(new Error('Model loading time limit exceeded.'));
8456
8569
  }, modelLoadTimeoutMs);
8457
8570
  var cancelVideoReady = function cancelVideoReady() {};
8458
- loadFocusModel(modelPath).then(function (loadedModel) {
8571
+ loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
8459
8572
  return __awaiter(_this, void 0, void 0, function () {
8460
8573
  var _a, videoReady, cancel, cancelled;
8461
8574
  return __generator(this, function (_b) {
8462
8575
  switch (_b.label) {
8463
8576
  case 0:
8464
8577
  setModelDownloadProgress(100);
8465
- clearTimeout(modelLoadTimeout);
8466
8578
  setModelLoadState('warming');
8467
- setModelWarmingStartedAt(new Date().getTime());
8579
+ setModelWarmingStartedAt(performance.now());
8580
+ clearTimeout(modelLoadTimeout);
8581
+ return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
8582
+ case 1:
8583
+ _b.sent();
8468
8584
  _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
8469
8585
  cancelled = false;
8470
8586
  cancelVideoReady = function cancelVideoReady() {
@@ -8472,11 +8588,11 @@
8472
8588
  cancel();
8473
8589
  };
8474
8590
  return [4 /*yield*/, videoReady];
8475
- case 1:
8591
+ case 2:
8476
8592
  _b.sent();
8477
8593
  setTimeout(function () {
8478
8594
  if (cancelled) return;
8479
- loadedModel.classifyForVideo(videoRef.current, performance.now());
8595
+ model.detectForVideo(videoRef.current, performance.now());
8480
8596
  setModelLoadState('ready');
8481
8597
  }, 500);
8482
8598
  return [2 /*return*/];
@@ -8490,13 +8606,13 @@
8490
8606
  clearTimeout(modelLoadTimeout);
8491
8607
  });
8492
8608
  return function () {
8493
- log('unloading focus model');
8609
+ log('unloading document detection model');
8494
8610
  cancelVideoReady();
8495
- closeFocusModel();
8611
+ closeDocumentDetector();
8496
8612
  clearTimeout(modelLoadTimeout);
8497
- document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
8613
+ document.removeEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
8498
8614
  };
8499
- }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
8615
+ }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
8500
8616
  React.useEffect(function handleModelError() {
8501
8617
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
8502
8618
  }, [modelError, onModelError]);
@@ -8506,185 +8622,41 @@
8506
8622
  modelLoadState: modelLoadState,
8507
8623
  modelDownloadProgress: modelDownloadProgress,
8508
8624
  modelWarmingStartedAt: modelWarmingStartedAt,
8509
- modelError: modelError
8625
+ modelError: modelError,
8626
+ setModelError: setModelError
8510
8627
  };
8511
8628
  }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
8512
8629
  }
8513
- var lastFocusPredictionAt = 0;
8514
- var lastFocusPredictionTime = 0;
8515
- function setLastFocusPredictionAt(time) {
8516
- lastFocusPredictionTime = time - lastFocusPredictionAt;
8517
- lastFocusPredictionAt = time;
8518
- }
8519
- function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
8520
- var _a, _b, _c, _d, _e;
8521
- if (!classifier) return null;
8522
- var startedAt = new Date();
8523
- var image = cropIfNecessary(imageData, cropCanvas, rotateCanvas, box);
8524
- var result = classifier.classifyForVideo(image, performance.now());
8525
- var score = (_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.classifications) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.categories) === null || _c === void 0 ? void 0 : _c.find(function (c) {
8526
- return c.categoryName === 'focused';
8527
- })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
8528
- var predictionTime = new Date().getTime() - startedAt.getTime();
8529
- return {
8530
- score: score,
8531
- predictionTime: predictionTime
8532
- };
8533
- }
8534
- function cropIfNecessary(imageData, cropCanvas, rotateCanvas, box) {
8535
- if (!box) return imageData;
8536
- var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas);
8537
- var _a = [box.width, box.height],
8538
- bw = _a[0],
8539
- bh = _a[1];
8540
- if (bh <= bw) return cropped;
8541
- var ctx = rotateCanvas.getContext('2d');
8542
- if (!ctx) return cropped;
8543
- rotateCanvas.width = bh;
8544
- rotateCanvas.height = bw;
8545
- ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
8546
- ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
8547
- ctx.rotate(1.5708); // 90 deg in radians
8548
- ctx.drawImage(cropped, -bw / 2, -bh / 2);
8549
- return rotateCanvas;
8550
- }
8551
-
8552
- var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
8553
- var detector$1 = null;
8554
- var detectorSettings$1 = null;
8555
- function loadFaceDetector() {
8556
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
8557
- var _a, _b;
8558
- if (modelAssetPath === void 0) {
8559
- modelAssetPath = defaultFaceDetectorModelPath;
8560
- }
8561
- return __generator(this, function (_c) {
8562
- switch (_c.label) {
8563
- case 0:
8564
- if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector$1];
8565
- closeFaceDetector();
8566
- return [4 /*yield*/, preloadFaceDetectorDependencies()];
8567
- case 1:
8568
- _c.sent();
8569
- if (modelCapabilities.delegate === 'NONE') {
8570
- throw new Error('No available delegate for face detector.');
8571
- }
8572
- _b = (_a = ya).createFromOptions;
8573
- return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
8574
- case 2:
8575
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
8576
- // canvas: document.createElement('canvas'),
8577
- baseOptions: {
8578
- modelAssetPath: modelAssetPath,
8579
- delegate: modelCapabilities.delegate
8580
- },
8581
- runningMode: 'VIDEO'
8582
- }])];
8583
- case 3:
8584
- detector$1 = _c.sent();
8585
- detectorSettings$1 = {
8586
- modelAssetPath: modelAssetPath
8587
- };
8588
- return [2 /*return*/, detector$1];
8630
+ function makeDocumentDetectorPrediction(frame) {
8631
+ return __awaiter(this, void 0, void 0, function () {
8632
+ var startedAt, prediction, time, frameWidth, frameHeight;
8633
+ return __generator(this, function (_a) {
8634
+ if (!detector$1) return [2 /*return*/, null];
8635
+ startedAt = performance.now();
8636
+ // Detectors can throw errors, for example when using custom URLs that
8637
+ // contain a model that doesn't provide the expected output.
8638
+ try {
8639
+ prediction = detector$1.detectForVideo(frame, performance.now());
8640
+ time = performance.now() - startedAt;
8641
+ frameWidth = frame.width;
8642
+ frameHeight = frame.height;
8643
+ return [2 /*return*/, _assign(_assign({}, prediction), {
8644
+ time: time,
8645
+ frameWidth: frameWidth,
8646
+ frameHeight: frameHeight
8647
+ })];
8648
+ } catch (e) {
8649
+ error('caught object detection error', e);
8589
8650
  }
8651
+ return [2 /*return*/, null];
8590
8652
  });
8591
8653
  });
8592
8654
  }
8593
- function closeFaceDetector() {
8594
- detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
8595
- detector$1 = null;
8596
- detectorSettings$1 = null;
8597
- }
8598
- function useLoadFaceDetector(_a) {
8599
- var onModelError = _a.onModelError,
8600
- _b = _a.modelLoadTimeoutMs,
8601
- modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
8602
- videoRef = _a.videoRef;
8603
- var _c = React.useState('not-started'),
8604
- modelLoadState = _c[0],
8605
- setModelLoadState = _c[1];
8606
- var _d = React.useState(0),
8607
- modelDownloadProgress = _d[0],
8608
- setModelDownloadProgress = _d[1];
8609
- var _e = React.useState(null),
8610
- modelWarmingStartedAt = _e[0],
8611
- setModelWarmingStartedAt = _e[1];
8612
- var _f = React.useState(null),
8613
- modelError = _f[0],
8614
- setModelError = _f[1];
8615
- React.useEffect(function loadModel() {
8616
- var _this = this;
8617
- setModelLoadState('downloading');
8618
- setModelWarmingStartedAt(null);
8619
- var modelLoadTimeout = setTimeout(function () {
8620
- setModelError(new Error('Model loading time limit exceeded.'));
8621
- }, modelLoadTimeoutMs);
8622
- function handleDownloadProgress(event) {
8623
- setModelDownloadProgress(progressToPercentage(event.detail));
8624
- }
8625
- document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
8626
- var cancelVideoReady = function cancelVideoReady() {};
8627
- loadFaceDetector().then(function (model) {
8628
- return __awaiter(_this, void 0, void 0, function () {
8629
- var _a, videoReady, cancel, cancelled;
8630
- return __generator(this, function (_b) {
8631
- switch (_b.label) {
8632
- case 0:
8633
- setModelDownloadProgress(100);
8634
- clearTimeout(modelLoadTimeout);
8635
- setModelLoadState('warming');
8636
- setModelWarmingStartedAt(new Date().getTime());
8637
- return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
8638
- case 1:
8639
- _b.sent();
8640
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
8641
- cancelled = false;
8642
- cancelVideoReady = function cancelVideoReady() {
8643
- cancelled = true;
8644
- cancel();
8645
- };
8646
- return [4 /*yield*/, videoReady];
8647
- case 2:
8648
- _b.sent();
8649
- if (cancelled) return [2 /*return*/];
8650
- model.detectForVideo(videoRef.current, performance.now());
8651
- setModelLoadState('ready');
8652
- return [2 /*return*/];
8653
- }
8654
- });
8655
- });
8656
- })["catch"](function (e) {
8657
- setModelError(e);
8658
- setModelLoadState('error');
8659
- })["finally"](function () {
8660
- clearTimeout(modelLoadTimeout);
8661
- });
8662
- return function () {
8663
- log('unloading face detection model');
8664
- cancelVideoReady();
8665
- closeFaceDetector();
8666
- clearTimeout(modelLoadTimeout);
8667
- document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
8668
- };
8669
- }, [modelLoadTimeoutMs, videoRef]);
8670
- React.useEffect(function handleModelError() {
8671
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
8672
- }, [modelError, onModelError]);
8673
- return React.useMemo(function () {
8674
- return {
8675
- ready: modelLoadState === 'ready',
8676
- modelLoadState: modelLoadState,
8677
- modelDownloadProgress: modelDownloadProgress,
8678
- modelWarmingStartedAt: modelWarmingStartedAt,
8679
- modelError: modelError
8680
- };
8681
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
8682
- }
8683
- var lastFaceDetectionAt = 0;
8684
- var lastFaceDetectionTime = 0;
8685
- function setLastFaceDetectionAt(time) {
8686
- lastFaceDetectionTime = time - lastFaceDetectionAt;
8687
- lastFaceDetectionAt = time;
8655
+ var lastDetectionAt = 0;
8656
+ var lastDetectionTime = 0;
8657
+ function setLastDetectionAt(time) {
8658
+ lastDetectionTime = time - lastDetectionAt;
8659
+ lastDetectionAt = time;
8688
8660
  }
8689
8661
  var framesNeededSamples$1 = [];
8690
8662
  function trackFramesNeeded$1(value, bufferLength) {
@@ -8694,818 +8666,293 @@
8694
8666
  framesNeededSamples$1.unshift(value);
8695
8667
  if (framesNeededSamples$1.length > bufferLength) framesNeededSamples$1.length = bufferLength;
8696
8668
  }
8697
- var lastNFaces = [];
8669
+ var lastNBoxes = [];
8698
8670
  var lastNPairs$1 = [];
8699
- function trackFace(face, framesNeeded) {
8671
+ function trackBox(box, framesNeeded) {
8700
8672
  if (framesNeeded === void 0) {
8701
8673
  framesNeeded = 12;
8702
8674
  }
8703
- lastNFaces.unshift(face);
8704
- if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
8705
- if (lastNFaces.length > 1) {
8706
- var lastFace = lastNFaces[1];
8707
- var iou = calculateIoU(face.box, lastFace.box);
8675
+ lastNBoxes.unshift(box);
8676
+ if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
8677
+ if (lastNBoxes.length > 1) {
8678
+ var lastBox = lastNBoxes[1];
8679
+ var iou = calculateIoU(box, lastBox);
8708
8680
  lastNPairs$1.unshift({
8709
- a: face,
8710
- b: lastFace,
8681
+ a: box,
8682
+ b: lastBox,
8711
8683
  iou: iou
8712
8684
  });
8713
8685
  if (lastNPairs$1.length > framesNeeded - 1) lastNPairs$1.length = framesNeeded - 1;
8714
8686
  }
8715
8687
  }
8716
- function makeFaceDetectorPrediction(imageData) {
8717
- if (!detector$1) return null;
8718
- var prediction = detector$1.detectForVideo(imageData, performance.now());
8719
- var faces = prediction.detections.map(function (d) {
8720
- return {
8721
- box: convertBoundingBox(d.boundingBox),
8722
- keypoints: d.keypoints.map(function (k) {
8723
- var _a;
8724
- return _assign(_assign({}, k), {
8725
- x: k.x * imageData.width,
8726
- y: k.y * imageData.height,
8727
- name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
8728
- });
8729
- })
8730
- };
8688
+ var defaultDocumentDetectionBoundaries = {
8689
+ top: 20,
8690
+ bottom: 20,
8691
+ left: 20,
8692
+ right: 20
8693
+ };
8694
+ function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
8695
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
8696
+ if (boundaries === void 0) {
8697
+ boundaries = defaultDocumentDetectionBoundaries;
8698
+ }
8699
+ var detections = prediction.detections,
8700
+ frameWidth = prediction.frameWidth,
8701
+ frameHeight = prediction.frameHeight,
8702
+ time = prediction.time;
8703
+ var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
8704
+ var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
8705
+ var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
8706
+ var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
8707
+ var frameWidth80Pct = frameWidth * 0.8;
8708
+ var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
8709
+ return d.categories.map(function (category) {
8710
+ return {
8711
+ label: category === null || category === void 0 ? void 0 : category.categoryName,
8712
+ score: category === null || category === void 0 ? void 0 : category.score,
8713
+ box: convertBoundingBox(d.boundingBox)
8714
+ };
8715
+ });
8716
+ }), function (obj) {
8717
+ var _a = obj.box,
8718
+ xMin = _a.xMin,
8719
+ yMin = _a.yMin,
8720
+ width = _a.width,
8721
+ height = _a.height;
8722
+ return yMin > boundaryTop &&
8723
+ // Is it valid top edge of ID detected?
8724
+ yMin + height + boundaryBottom < frameHeight && (
8725
+ // Is it valid bottom edge less than max video height
8726
+ xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
8727
+ // If either the left side visible or if not, right edge of ID should be more than 80% of width.
8728
+ xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
8729
+ ;
8731
8730
  });
8732
- return _assign(_assign({}, prediction), {
8733
- faces: faces
8731
+ var allZero = detections.length > 0 && !detections.some(function (_a) {
8732
+ var boundingBox = _a.boundingBox;
8733
+ return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
8734
+ return n > 0;
8735
+ });
8734
8736
  });
8735
- }
8736
- function processFaceDetectorPrediction(_a) {
8737
- var faces = _a.faces,
8738
- videoWidth = _a.videoWidth,
8739
- videoHeight = _a.videoHeight,
8740
- _b = _a.requireVerticalFaceCentering,
8741
- requireVerticalFaceCentering = _b === void 0 ? true : _b,
8742
- _c = _a.stabilityThreshold,
8743
- stabilityThreshold = _c === void 0 ? 0.7 : _c;
8744
- var face = faces[0];
8745
- var faceNotDetected = faces.length === 0;
8746
- var faceNotCentered = false,
8747
- faceLookingAway = false,
8748
- faceTooClose = false,
8749
- faceTooFar = false;
8750
- if (face) {
8751
- // calculate centroids
8752
- var vCX = videoWidth / 2;
8753
- var vCY = videoHeight / 2;
8754
- var fCX = (face.box.xMin + face.box.xMax) / 2;
8755
- var fCY = (face.box.yMin + face.box.yMax) / 2;
8756
- // calculate thresholds
8757
- var vTX = videoWidth * 0.125;
8758
- var vTY = videoHeight * 0.125;
8759
- var fTW = face.box.width * 0.2;
8760
- var fTH = face.box.height * 0.2;
8761
- var nose = face.keypoints[2]; //.find((k) => k.name === 'noseTip')
8762
- if (nose) {
8763
- faceLookingAway = Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH;
8764
- var faceNotCenteredHorizontally = Math.abs(vCX - fCX) > vTX;
8765
- var faceNotCenteredVertically = Math.abs(vCY + 50 - fCY) > vTY;
8766
- faceNotCentered = faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
8767
- }
8768
- var isMobile = videoWidth < videoHeight;
8769
- var tooCloseMultiple = 1.5;
8770
- var tooFarMultiple = isMobile ? 6 : 7;
8771
- faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
8772
- faceTooFar = face.box.width < videoWidth / tooFarMultiple;
8737
+ var bestIdCardFront = detectedObjects.find(function (obj) {
8738
+ return obj.label === 'Document';
8739
+ });
8740
+ var bestIdCardBack = detectedObjects.find(function (obj) {
8741
+ return obj.label === 'Document back';
8742
+ });
8743
+ var bestPassportPage = detectedObjects.find(function (obj) {
8744
+ return obj.label === 'Passport page';
8745
+ });
8746
+ var bestSinglePage = detectedObjects.find(function (obj) {
8747
+ return obj.label === 'Single page';
8748
+ });
8749
+ var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
8750
+ var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
8751
+ var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
8752
+ var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
8753
+ var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
8754
+ var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
8755
+ var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
8756
+ var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
8757
+ var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
8758
+ var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
8759
+ var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
8760
+ var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
8761
+ var detectedDocumentType = 'none';
8762
+ if (singlePageDetectionThresholdMet) {
8763
+ detectedDocumentType = 'singlePage';
8764
+ } else if (passportDetectionThresholdMet) {
8765
+ detectedDocumentType = 'passport';
8766
+ } else if (idCardBackDetectionThresholdMet) {
8767
+ detectedDocumentType = 'idCardBack';
8768
+ } else if (detectionThresholdMet) {
8769
+ detectedDocumentType = 'idCardFront';
8773
8770
  }
8774
- var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
8775
- if (lastFaceDetectionTime > 0) {
8776
- trackFramesNeeded$1(500 / lastFaceDetectionTime);
8771
+ var documentInBounds = !!bestDocument;
8772
+ if (lastDetectionTime > 0) {
8773
+ trackFramesNeeded$1(1000 / lastDetectionTime);
8777
8774
  }
8778
- var faceIsStable = false;
8779
- if (faceInGuides) {
8780
- var framesNeeded = Math.ceil(average(framesNeededSamples$1));
8781
- trackFace(face, framesNeeded);
8782
- faceIsStable = lastNFaces.length >= framesNeeded && !lastNPairs$1.some(function (pair) {
8783
- return pair.iou < stabilityThreshold;
8775
+ var documentIsStable = false;
8776
+ var documentTooClose = false;
8777
+ if (bestDocument) {
8778
+ var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
8779
+ docWidth = _q[0],
8780
+ docHeight = _q[1];
8781
+ documentTooClose = docWidth > 0.85 || docHeight > 0.85;
8782
+ if (detectionThresholdMet && documentInBounds && !documentTooClose) {
8783
+ var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
8784
+ var threshold_1 = thresholdSet[detectedDocumentType];
8785
+ var framesNeeded = Math.ceil(average(framesNeededSamples$1));
8786
+ trackBox(bestDocument.box, framesNeeded);
8787
+ documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs$1.some(function (pair) {
8788
+ return pair.iou < threshold_1;
8789
+ });
8790
+ }
8791
+ }
8792
+ var bestPDF417;
8793
+ if (detectedObjects.length > 0) {
8794
+ bestPDF417 = detectedObjects.find(function (obj) {
8795
+ return obj.label === 'PDF417';
8784
8796
  });
8785
8797
  }
8786
- var faceReady = faceInGuides && faceIsStable;
8787
8798
  return {
8788
- face: face,
8789
- faceNotDetected: faceNotDetected,
8790
- faceNotCentered: faceNotCentered,
8791
- faceLookingAway: faceLookingAway,
8792
- faceTooClose: faceTooClose,
8793
- faceTooFar: faceTooFar,
8794
- faceReady: faceReady,
8795
- faceReadyAt: faceReady ? new Date() : null,
8796
- faceIsStable: faceIsStable
8797
- };
8798
- }
8799
- function testFaceDetectionAgainstKnownImage(detector) {
8800
- return new Promise(function (resolve, reject) {
8801
- var img = new Image();
8802
- img.crossOrigin = 'anonymous';
8803
- img.onload = function () {
8804
- var prediction = detector.detectForVideo(img, performance.now());
8805
- if (prediction.detections.length > 0) {
8806
- debug('face detection test result', prediction.detections);
8807
- resolve(void 0);
8808
- } else {
8809
- warn('face detection test failed');
8810
- reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
8811
- }
8812
- };
8813
- img.onerror = function () {
8814
- return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
8815
- };
8816
- img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
8817
- });
8818
- }
8819
-
8820
- var preloadModels = function preloadModels(_a) {
8821
- return __awaiter(void 0, [_a], void 0, function (_b) {
8822
- var preloadTasks;
8823
- var _c = _b.documentDetectionModel,
8824
- documentDetectionModel = _c === void 0 ? true : _c,
8825
- _d = _b.focusModel,
8826
- focusModel = _d === void 0 ? true : _d,
8827
- _e = _b.faceDetectionModel,
8828
- faceDetectionModel = _e === void 0 ? true : _e;
8829
- return __generator(this, function (_f) {
8830
- switch (_f.label) {
8831
- case 0:
8832
- return [4 /*yield*/, probeModelCapabilities()];
8833
- case 1:
8834
- _f.sent();
8835
- preloadTasks = [];
8836
- if (documentDetectionModel) {
8837
- preloadTasks.push(preloadDocumentDetectorDependencies);
8838
- }
8839
- if (focusModel) {
8840
- preloadTasks.push(preloadFocusModelDependencies);
8841
- }
8842
- if (faceDetectionModel) {
8843
- preloadTasks.push(preloadFaceDetectorDependencies);
8844
- }
8845
- return [4 /*yield*/, Promise.all(preloadTasks)];
8846
- case 2:
8847
- _f.sent();
8848
- return [2 /*return*/];
8849
- }
8850
- });
8851
- });
8852
- };
8853
- var progressByUrl = {};
8854
- var progressByUseCase = {
8855
- visionRuntime: {
8856
- loaded: 0,
8857
- total: 0
8858
- },
8859
- documentDetection: {
8860
- loaded: 0,
8861
- total: 0
8862
- },
8863
- focus: {
8864
- loaded: 0,
8865
- total: 0
8866
- },
8867
- faceDetection: {
8868
- loaded: 0,
8869
- total: 0
8870
- }
8871
- };
8872
- function preloadDependency(url) {
8873
- return __awaiter(this, void 0, void 0, function () {
8874
- return __generator(this, function (_a) {
8875
- return [2 /*return*/, new Promise(function (resolve, reject) {
8876
- var req = new XMLHttpRequest();
8877
- req.addEventListener('progress', function (event) {
8878
- if (!event.lengthComputable) return;
8879
- progressByUrl[url] = event;
8880
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
8881
- detail: {
8882
- url: url,
8883
- loaded: event.loaded,
8884
- total: event.total
8885
- }
8886
- }));
8887
- });
8888
- req.addEventListener('loadend', function () {
8889
- resolve(req.readyState === 4 && req.status === 200);
8890
- });
8891
- req.addEventListener('error', reject);
8892
- req.open('GET', url, true);
8893
- req.send();
8894
- })];
8895
- });
8896
- });
8799
+ prediction: prediction,
8800
+ detectedObjects: detectedObjects,
8801
+ detectionScore: detectionScore,
8802
+ detectionTime: time,
8803
+ detectionThresholdMet: detectionThresholdMet,
8804
+ detectedDocumentType: detectedDocumentType,
8805
+ idCardFrontDetectionScore: idCardFrontDetectionScore,
8806
+ idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
8807
+ idCardBackDetectionScore: idCardBackDetectionScore,
8808
+ idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
8809
+ passportDetectionScore: passportDetectionScore,
8810
+ passportDetectionThresholdMet: passportDetectionThresholdMet,
8811
+ singlePageDetectionScore: singlePageDetectionScore,
8812
+ singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
8813
+ bestDocument: bestDocument,
8814
+ bestPDF417: bestPDF417,
8815
+ documentInBounds: documentInBounds,
8816
+ documentTooClose: documentTooClose,
8817
+ documentIsStable: documentIsStable,
8818
+ frameWidth: frameWidth,
8819
+ frameHeight: frameHeight,
8820
+ allZero: allZero
8821
+ };
8897
8822
  }
8898
- var documentDetectorPreloading = false,
8899
- focusModelPreloading = false,
8900
- faceDetectorPreloading = false;
8901
- function preloadDocumentDetectorDependencies() {
8902
- return __awaiter(this, void 0, void 0, function () {
8903
- function handleDownloadProgress(event) {
8904
- var detail = event.detail;
8905
- if (!dependencies.includes(detail.url)) return;
8906
- progressByUseCase.documentDetection = sumUpProgressForDependencies(dependencies);
8907
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.documentDetection', {
8908
- detail: progressByUseCase.documentDetection
8909
- }));
8823
+ function applyNonMaxSuppression(detectedObjects, isGoodBox) {
8824
+ var maxes = {};
8825
+ detectedObjects.forEach(function (obj, i) {
8826
+ if (obj) {
8827
+ if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
8828
+ if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
8910
8829
  }
8911
- var dependencies;
8912
- return __generator(this, function (_a) {
8913
- switch (_a.label) {
8914
- case 0:
8915
- if (documentDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
8916
- var i = setInterval(function () {
8917
- if (!documentDetectorPreloading) {
8918
- clearInterval(i);
8919
- resolve();
8920
- }
8921
- }, 100);
8922
- })];
8923
- documentDetectorPreloading = true;
8924
- return [4 /*yield*/, probeModelCapabilities()];
8925
- case 1:
8926
- _a.sent();
8927
- if (modelCapabilities.delegate === 'NONE') {
8928
- throw new Error('No available delegate for document detector.');
8929
- }
8930
- dependencies = [defaultDocumentDetectorModelPath];
8931
- document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
8932
- _a.label = 2;
8933
- case 2:
8934
- _a.trys.push([2,, 4, 5]);
8935
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
8936
- case 3:
8937
- _a.sent();
8938
- return [3 /*break*/, 5];
8939
- case 4:
8940
- document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
8941
- documentDetectorPreloading = false;
8942
- return [7 /*endfinally*/];
8943
- case 5:
8944
- return [2 /*return*/];
8945
- }
8946
- });
8947
8830
  });
8948
- }
8949
- function preloadFocusModelDependencies() {
8950
- return __awaiter(this, void 0, void 0, function () {
8951
- function handleModelDownloadProgress(event) {
8952
- var detail = event.detail;
8953
- if (!dependencies.includes(detail.url)) return;
8954
- progressByUseCase.focus = sumUpProgressForDependencies(dependencies);
8955
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.focus', {
8956
- detail: progressByUseCase.focus
8957
- }));
8958
- }
8959
- var dependencies;
8960
- return __generator(this, function (_a) {
8961
- switch (_a.label) {
8962
- case 0:
8963
- if (focusModelPreloading) return [2 /*return*/, new Promise(function (resolve) {
8964
- var i = setInterval(function () {
8965
- if (!focusModelPreloading) {
8966
- clearInterval(i);
8967
- resolve();
8968
- }
8969
- }, 100);
8970
- })];
8971
- focusModelPreloading = true;
8972
- return [4 /*yield*/, probeModelCapabilities()];
8973
- case 1:
8974
- _a.sent();
8975
- if (modelCapabilities.delegate === 'NONE') {
8976
- throw new Error('No available delegate for document detector.');
8977
- }
8978
- dependencies = [defaultFocusModelPath];
8979
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8980
- _a.label = 2;
8981
- case 2:
8982
- _a.trys.push([2,, 4, 5]);
8983
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
8984
- case 3:
8985
- _a.sent();
8986
- return [3 /*break*/, 5];
8987
- case 4:
8988
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
8989
- focusModelPreloading = false;
8990
- return [7 /*endfinally*/];
8991
- case 5:
8992
- return [2 /*return*/];
8993
- }
8994
- });
8831
+ return Object.keys(maxes).map(function (label) {
8832
+ return detectedObjects[maxes[label][1]];
8833
+ }).filter(function (obj) {
8834
+ return !!obj;
8995
8835
  });
8996
8836
  }
8997
- function preloadFaceDetectorDependencies() {
8998
- return __awaiter(this, void 0, void 0, function () {
8999
- function handleModelDownloadProgress(event) {
9000
- var detail = event.detail;
9001
- if (!dependencies.includes(detail.url)) return;
9002
- progressByUseCase.faceDetection = sumUpProgressForDependencies(dependencies);
9003
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.faceDetection', {
9004
- detail: progressByUseCase.faceDetection
9005
- }));
9006
- }
9007
- var dependencies;
9008
- return __generator(this, function (_a) {
9009
- switch (_a.label) {
9010
- case 0:
9011
- if (faceDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
9012
- var i = setInterval(function () {
9013
- if (!faceDetectorPreloading) {
9014
- clearInterval(i);
9015
- resolve();
9016
- }
9017
- }, 100);
9018
- })];
9019
- faceDetectorPreloading = true;
9020
- return [4 /*yield*/, probeModelCapabilities()];
9021
- case 1:
9022
- _a.sent();
9023
- if (modelCapabilities.delegate === 'NONE') {
9024
- throw new Error('No available delegate for document detector.');
9025
- }
9026
- dependencies = [defaultFaceDetectorModelPath];
9027
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
9028
- _a.label = 2;
9029
- case 2:
9030
- _a.trys.push([2,, 4, 5]);
9031
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
9032
- case 3:
9033
- _a.sent();
9034
- return [3 /*break*/, 5];
9035
- case 4:
9036
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
9037
- faceDetectorPreloading = false;
9038
- return [7 /*endfinally*/];
9039
- case 5:
9040
- return [2 /*return*/];
8837
+ function testDocumentDetectionAgainstKnownImage(detector) {
8838
+ return new Promise(function (resolve, reject) {
8839
+ var img = new Image();
8840
+ img.crossOrigin = 'anonymous';
8841
+ img.onload = function () {
8842
+ var prediction = detector.detectForVideo(img, performance.now());
8843
+ if (prediction.detections.length > 0) {
8844
+ debug('document detection test result', prediction.detections);
8845
+ resolve(void 0);
8846
+ } else {
8847
+ warn('document detection test failed');
8848
+ reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
9041
8849
  }
9042
- });
9043
- });
9044
- }
9045
- function progressToPercentage(progress) {
9046
- return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
9047
- }
9048
- function sumUpProgressForDependencies(dependencies) {
9049
- return dependencies.reduce(function (result, dependency) {
9050
- var dependencyProgress = progressByUrl[dependency];
9051
- if (!dependencyProgress) return result;
9052
- result.loaded += dependencyProgress.loaded;
9053
- result.total += dependencyProgress.total;
9054
- return result;
9055
- }, {
9056
- loaded: 0,
9057
- total: 0
8850
+ };
8851
+ img.onerror = function () {
8852
+ return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
8853
+ };
8854
+ img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
9058
8855
  });
9059
8856
  }
9060
8857
 
9061
- var defaultDocumentDetectionScoreThreshold = 0.1;
9062
- var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
9063
- var defaultDocumentDetectionThresholds = {
9064
- idCardFront: 0.6,
9065
- idCardBack: 0.6,
9066
- passport: 0.4,
9067
- singlePage: 0.4,
9068
- stability: {
9069
- idCardFront: 0.85,
9070
- idCardBack: 0.85,
9071
- passport: 0.5,
9072
- singlePage: 0.5
8858
+ function getFrameDimensions(frame) {
8859
+ var frameWidth = frame.width,
8860
+ frameHeight = frame.height;
8861
+ if (frame instanceof HTMLImageElement) {
8862
+ frameWidth = frame.naturalWidth;
8863
+ frameHeight = frame.naturalHeight;
9073
8864
  }
9074
- };
9075
- var documentTypeDisplayNames = {
9076
- idCardFront: 'ID card front',
9077
- idCardBack: 'ID card back',
9078
- passport: 'Passport',
9079
- singlePage: 'Single page',
9080
- none: 'None'
9081
- };
9082
- var detector = null;
9083
- var detectorSettings = null;
9084
- function loadDocumentDetector() {
9085
- return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
9086
- var _a, _b;
9087
- if (modelAssetPath === void 0) {
9088
- modelAssetPath = defaultDocumentDetectorModelPath;
9089
- }
9090
- if (scoreThreshold === void 0) {
9091
- scoreThreshold = defaultDocumentDetectionScoreThreshold;
9092
- }
9093
- return __generator(this, function (_c) {
9094
- switch (_c.label) {
9095
- case 0:
9096
- if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.scoreThreshold) === scoreThreshold) return [2 /*return*/, detector];
9097
- closeDocumentDetector();
9098
- return [4 /*yield*/, preloadDocumentDetectorDependencies()];
9099
- case 1:
9100
- _c.sent();
9101
- if (modelCapabilities.delegate === 'NONE') {
9102
- throw new Error('No available delegate for document detector.');
9103
- }
9104
- _b = (_a = lh).createFromOptions;
9105
- return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
9106
- case 2:
9107
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
9108
- baseOptions: {
9109
- modelAssetPath: modelAssetPath,
9110
- delegate: modelCapabilities.delegate
9111
- },
9112
- // canvas: document.createElement('canvas'),
9113
- scoreThreshold: scoreThreshold,
9114
- runningMode: 'VIDEO'
9115
- }])];
9116
- case 3:
9117
- detector = _c.sent();
9118
- detectorSettings = {
9119
- modelAssetPath: modelAssetPath,
9120
- scoreThreshold: scoreThreshold
9121
- };
9122
- return [2 /*return*/, detector];
9123
- }
9124
- });
9125
- });
8865
+ if (frame instanceof HTMLVideoElement) {
8866
+ frameWidth = frame.videoWidth;
8867
+ frameHeight = frame.videoHeight;
8868
+ }
8869
+ return [frameWidth, frameHeight];
9126
8870
  }
9127
- function closeDocumentDetector() {
9128
- detector === null || detector === void 0 ? void 0 : detector.close();
9129
- detector = null;
9130
- detectorSettings = null;
8871
+
8872
+ var InvisibleCanvasContainer = styled.div(templateObject_1$N || (templateObject_1$N = __makeTemplateObject(["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n"], ["\n position: absolute;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n justify-content: center;\n align-items: center;\n"])));
8873
+ var InvisibleCanvas = styled.canvas(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
8874
+ function drawToCanvas(canvas, frame, width, height) {
8875
+ if (!canvas) return;
8876
+ var ctx = canvas.getContext('2d');
8877
+ if (!ctx) return;
8878
+ if (!width || !height) {
8879
+ var _a = getFrameDimensions(frame),
8880
+ frameWidth = _a[0],
8881
+ frameHeight = _a[1];
8882
+ width || (width = frameWidth);
8883
+ height || (height = frameHeight);
8884
+ }
8885
+ canvas.width = width;
8886
+ canvas.height = height;
8887
+ ctx.drawImage(frame, 0, 0, width, height);
9131
8888
  }
9132
- function useLoadDocumentDetector(_a) {
9133
- var _b = _a.shouldLoadModels,
9134
- shouldLoadModels = _b === void 0 ? true : _b,
9135
- _c = _a.modelPath,
9136
- modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
9137
- _d = _a.modelLoadTimeoutMs,
9138
- modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
9139
- _e = _a.scoreThreshold,
9140
- scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
9141
- onModelError = _a.onModelError,
9142
- videoRef = _a.videoRef;
9143
- var _f = React.useState('not-started'),
9144
- modelLoadState = _f[0],
9145
- setModelLoadState = _f[1];
9146
- var _g = React.useState(null),
9147
- modelWarmingStartedAt = _g[0],
9148
- setModelWarmingStartedAt = _g[1];
9149
- var _h = React.useState(0),
9150
- modelDownloadProgress = _h[0],
9151
- setModelDownloadProgress = _h[1];
9152
- var _j = React.useState(null),
9153
- modelError = _j[0],
9154
- setModelError = _j[1];
9155
- React.useEffect(function loadModel() {
9156
- var _this = this;
9157
- if (!shouldLoadModels) return;
9158
- setModelLoadState('downloading');
9159
- setModelWarmingStartedAt(null);
9160
- function handleDownloadProgress(event) {
9161
- setModelDownloadProgress(progressToPercentage(event.detail));
9162
- }
9163
- document.addEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
9164
- var modelLoadTimeout = setTimeout(function () {
9165
- setModelError(new Error('Model loading time limit exceeded.'));
9166
- }, modelLoadTimeoutMs);
9167
- var cancelVideoReady = function cancelVideoReady() {};
9168
- loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
9169
- return __awaiter(_this, void 0, void 0, function () {
9170
- var _a, videoReady, cancel, cancelled;
9171
- return __generator(this, function (_b) {
9172
- switch (_b.label) {
8889
+ function clearCanvas(canvas) {
8890
+ var _a;
8891
+ (_a = canvas === null || canvas === void 0 ? void 0 : canvas.getContext('2d')) === null || _a === void 0 ? void 0 : _a.clearRect(0, 0, canvas === null || canvas === void 0 ? void 0 : canvas.width, canvas === null || canvas === void 0 ? void 0 : canvas.height);
8892
+ }
8893
+ var templateObject_1$N, templateObject_2$G;
8894
+
8895
+ function useFrameLoop(fn, options) {
8896
+ if (options === void 0) {
8897
+ options = {};
8898
+ }
8899
+ var _a = React.useState(false),
8900
+ running = _a[0],
8901
+ setRunning = _a[1];
8902
+ var startedAtRef = React.useRef(null);
8903
+ var loopId = React.useRef(0);
8904
+ var frameId = React.useRef(0);
8905
+ React.useEffect(function runFrameLoop() {
8906
+ if (!running) return;
8907
+ var timer;
8908
+ var currentLoopId = loopId.current;
8909
+ function hotLoop() {
8910
+ return __awaiter(this, void 0, void 0, function () {
8911
+ var start, timeRunning, took, amountToThrottle;
8912
+ var _a, _b, _c;
8913
+ return __generator(this, function (_d) {
8914
+ switch (_d.label) {
9173
8915
  case 0:
9174
- setModelDownloadProgress(100);
9175
- setModelLoadState('warming');
9176
- setModelWarmingStartedAt(new Date().getTime());
9177
- clearTimeout(modelLoadTimeout);
9178
- return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
8916
+ if (currentLoopId !== loopId.current) return [2 /*return*/];
8917
+ start = new Date().getTime();
8918
+ timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
8919
+ return [4 /*yield*/, fn(frameId.current, timeRunning)];
9179
8920
  case 1:
9180
- _b.sent();
9181
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
9182
- cancelled = false;
9183
- cancelVideoReady = function cancelVideoReady() {
9184
- cancelled = true;
9185
- cancel();
9186
- };
9187
- return [4 /*yield*/, videoReady];
9188
- case 2:
9189
- _b.sent();
9190
- setTimeout(function () {
9191
- if (cancelled) return;
9192
- model.detectForVideo(videoRef.current, performance.now());
9193
- setModelLoadState('ready');
9194
- }, 500);
8921
+ _d.sent();
8922
+ took = new Date().getTime() - start;
8923
+ amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
8924
+ timer = setTimeout(function () {
8925
+ frameId.current = requestAnimationFrame(hotLoop);
8926
+ }, amountToThrottle);
9195
8927
  return [2 /*return*/];
9196
8928
  }
9197
8929
  });
9198
8930
  });
9199
- })["catch"](function (e) {
9200
- setModelError(e);
9201
- setModelLoadState('error');
9202
- })["finally"](function () {
9203
- clearTimeout(modelLoadTimeout);
9204
- });
8931
+ }
8932
+ void hotLoop();
9205
8933
  return function () {
9206
- log('unloading document detection model');
9207
- cancelVideoReady();
9208
- closeDocumentDetector();
9209
- clearTimeout(modelLoadTimeout);
9210
- document.removeEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
9211
- };
9212
- }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
9213
- React.useEffect(function handleModelError() {
9214
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
9215
- }, [modelError, onModelError]);
9216
- return React.useMemo(function () {
9217
- return {
9218
- ready: modelLoadState === 'ready',
9219
- modelLoadState: modelLoadState,
9220
- modelDownloadProgress: modelDownloadProgress,
9221
- modelWarmingStartedAt: modelWarmingStartedAt,
9222
- modelError: modelError,
9223
- setModelError: setModelError
8934
+ loopId.current += 1;
8935
+ if (frameId.current) cancelAnimationFrame(frameId.current);
8936
+ if (timer) clearTimeout(timer);
9224
8937
  };
9225
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
9226
- }
9227
- function makeDocumentDetectorPrediction(frame) {
9228
- return __awaiter(this, void 0, void 0, function () {
9229
- var startedAt, prediction, time, frameWidth, frameHeight;
9230
- return __generator(this, function (_a) {
9231
- if (!detector) return [2 /*return*/, null];
9232
- startedAt = new Date();
9233
- // Detectors can throw errors, for example when using custom URLs that
9234
- // contain a model that doesn't provide the expected output.
9235
- try {
9236
- prediction = detector.detectForVideo(frame, performance.now());
9237
- time = new Date().getTime() - startedAt.getTime();
9238
- frameWidth = frame.width;
9239
- frameHeight = frame.height;
9240
- return [2 /*return*/, _assign(_assign({}, prediction), {
9241
- time: time,
9242
- frameWidth: frameWidth,
9243
- frameHeight: frameHeight
9244
- })];
9245
- } catch (e) {
9246
- error('caught object detection error', e);
9247
- }
9248
- return [2 /*return*/, null];
9249
- });
9250
- });
9251
- }
9252
- var lastDetectionAt = 0;
9253
- var lastDetectionTime = 0;
9254
- function setLastDetectionAt(time) {
9255
- lastDetectionTime = time - lastDetectionAt;
9256
- lastDetectionAt = time;
9257
- }
9258
- var framesNeededSamples = [];
9259
- function trackFramesNeeded(value, bufferLength) {
9260
- if (bufferLength === void 0) {
9261
- bufferLength = 25;
9262
- }
9263
- framesNeededSamples.unshift(value);
9264
- if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
9265
- }
9266
- var lastNBoxes = [];
9267
- var lastNPairs = [];
9268
- function trackBox(box, framesNeeded) {
9269
- if (framesNeeded === void 0) {
9270
- framesNeeded = 12;
9271
- }
9272
- lastNBoxes.unshift(box);
9273
- if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
9274
- if (lastNBoxes.length > 1) {
9275
- var lastBox = lastNBoxes[1];
9276
- var iou = calculateIoU(box, lastBox);
9277
- lastNPairs.unshift({
9278
- a: box,
9279
- b: lastBox,
9280
- iou: iou
9281
- });
9282
- if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
9283
- }
9284
- }
9285
- var defaultDocumentDetectionBoundaries = {
9286
- top: 20,
9287
- bottom: 20,
9288
- left: 20,
9289
- right: 20
9290
- };
9291
- function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
9292
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
9293
- if (boundaries === void 0) {
9294
- boundaries = defaultDocumentDetectionBoundaries;
9295
- }
9296
- var detections = prediction.detections,
9297
- frameWidth = prediction.frameWidth,
9298
- frameHeight = prediction.frameHeight,
9299
- time = prediction.time;
9300
- var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
9301
- var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
9302
- var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
9303
- var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
9304
- var frameWidth80Pct = frameWidth * 0.8;
9305
- var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
9306
- return d.categories.map(function (category) {
9307
- return {
9308
- label: category === null || category === void 0 ? void 0 : category.categoryName,
9309
- score: category === null || category === void 0 ? void 0 : category.score,
9310
- box: convertBoundingBox(d.boundingBox)
9311
- };
9312
- });
9313
- }), function (obj) {
9314
- var _a = obj.box,
9315
- xMin = _a.xMin,
9316
- yMin = _a.yMin,
9317
- width = _a.width,
9318
- height = _a.height;
9319
- return yMin > boundaryTop &&
9320
- // Is it valid top edge of ID detected?
9321
- yMin + height + boundaryBottom < frameHeight && (
9322
- // Is it valid bottom edge less than max video height
9323
- xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
9324
- // If either the left side visible or if not, right edge of ID should be more than 80% of width.
9325
- xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
9326
- ;
9327
- });
9328
- var allZero = detections.length > 0 && !detections.some(function (_a) {
9329
- var boundingBox = _a.boundingBox;
9330
- return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
9331
- return n > 0;
9332
- });
9333
- });
9334
- var bestIdCardFront = detectedObjects.find(function (obj) {
9335
- return obj.label === 'Document';
9336
- });
9337
- var bestIdCardBack = detectedObjects.find(function (obj) {
9338
- return obj.label === 'Document back';
9339
- });
9340
- var bestPassportPage = detectedObjects.find(function (obj) {
9341
- return obj.label === 'Passport page';
9342
- });
9343
- var bestSinglePage = detectedObjects.find(function (obj) {
9344
- return obj.label === 'Single page';
9345
- });
9346
- var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
9347
- var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
9348
- var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
9349
- var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
9350
- var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
9351
- var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
9352
- var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
9353
- var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
9354
- var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
9355
- var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
9356
- var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
9357
- var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
9358
- var detectedDocumentType = 'none';
9359
- if (singlePageDetectionThresholdMet) {
9360
- detectedDocumentType = 'singlePage';
9361
- } else if (passportDetectionThresholdMet) {
9362
- detectedDocumentType = 'passport';
9363
- } else if (idCardBackDetectionThresholdMet) {
9364
- detectedDocumentType = 'idCardBack';
9365
- } else if (detectionThresholdMet) {
9366
- detectedDocumentType = 'idCardFront';
9367
- }
9368
- var documentInBounds = !!bestDocument;
9369
- if (lastDetectionTime > 0) {
9370
- trackFramesNeeded(1000 / lastDetectionTime);
9371
- }
9372
- var documentIsStable = false;
9373
- var documentTooClose = false;
9374
- if (bestDocument) {
9375
- var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
9376
- docWidth = _q[0],
9377
- docHeight = _q[1];
9378
- documentTooClose = docWidth > 0.85 || docHeight > 0.85;
9379
- if (detectionThresholdMet && documentInBounds && !documentTooClose) {
9380
- var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
9381
- var threshold_1 = thresholdSet[detectedDocumentType];
9382
- var framesNeeded = Math.ceil(average(framesNeededSamples));
9383
- trackBox(bestDocument.box, framesNeeded);
9384
- documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
9385
- return pair.iou < threshold_1;
9386
- });
9387
- }
9388
- }
9389
- return {
9390
- prediction: prediction,
9391
- detectedObjects: detectedObjects,
9392
- detectionScore: detectionScore,
9393
- detectionTime: time,
9394
- detectionThresholdMet: detectionThresholdMet,
9395
- detectedDocumentType: detectedDocumentType,
9396
- idCardFrontDetectionScore: idCardFrontDetectionScore,
9397
- idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
9398
- idCardBackDetectionScore: idCardBackDetectionScore,
9399
- idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
9400
- passportDetectionScore: passportDetectionScore,
9401
- passportDetectionThresholdMet: passportDetectionThresholdMet,
9402
- singlePageDetectionScore: singlePageDetectionScore,
9403
- singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
9404
- bestDocument: bestDocument,
9405
- documentInBounds: documentInBounds,
9406
- documentTooClose: documentTooClose,
9407
- documentIsStable: documentIsStable,
9408
- frameWidth: frameWidth,
9409
- frameHeight: frameHeight,
9410
- allZero: allZero
9411
- };
9412
- }
9413
- function applyNonMaxSuppression(detectedObjects, isGoodBox) {
9414
- var maxes = {};
9415
- detectedObjects.forEach(function (obj, i) {
9416
- if (obj) {
9417
- if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
9418
- if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
9419
- }
9420
- });
9421
- return Object.keys(maxes).map(function (label) {
9422
- return detectedObjects[maxes[label][1]];
9423
- }).filter(function (obj) {
9424
- return !!obj;
9425
- });
9426
- }
9427
- function testDocumentDetectionAgainstKnownImage(detector) {
9428
- return new Promise(function (resolve, reject) {
9429
- var img = new Image();
9430
- img.crossOrigin = 'anonymous';
9431
- img.onload = function () {
9432
- var prediction = detector.detectForVideo(img, performance.now());
9433
- if (prediction.detections.length > 0) {
9434
- debug('document detection test result', prediction.detections);
9435
- resolve(void 0);
9436
- } else {
9437
- warn('document detection test failed');
9438
- reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
9439
- }
9440
- };
9441
- img.onerror = function () {
9442
- return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
9443
- };
9444
- img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
9445
- });
9446
- }
9447
-
9448
- function useFrameLoop(fn, options) {
9449
- if (options === void 0) {
9450
- options = {};
9451
- }
9452
- var _a = React.useState(false),
9453
- running = _a[0],
9454
- setRunning = _a[1];
9455
- var startedAtRef = React.useRef(null);
9456
- var loopId = React.useRef(0);
9457
- var frameId = React.useRef(0);
9458
- React.useEffect(function runFrameLoop() {
9459
- if (!running) return;
9460
- var timer;
9461
- var currentLoopId = loopId.current;
9462
- function hotLoop() {
9463
- return __awaiter(this, void 0, void 0, function () {
9464
- var start, timeRunning, took, amountToThrottle;
9465
- var _a, _b, _c;
9466
- return __generator(this, function (_d) {
9467
- switch (_d.label) {
9468
- case 0:
9469
- if (currentLoopId !== loopId.current) return [2 /*return*/];
9470
- start = new Date().getTime();
9471
- timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
9472
- return [4 /*yield*/, fn(frameId.current, timeRunning)];
9473
- case 1:
9474
- _d.sent();
9475
- took = new Date().getTime() - start;
9476
- amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
9477
- timer = setTimeout(function () {
9478
- frameId.current = requestAnimationFrame(hotLoop);
9479
- }, amountToThrottle);
9480
- return [2 /*return*/];
9481
- }
9482
- });
9483
- });
9484
- }
9485
- void hotLoop();
9486
- return function () {
9487
- loopId.current += 1;
9488
- if (frameId.current) cancelAnimationFrame(frameId.current);
9489
- if (timer) clearTimeout(timer);
9490
- };
9491
- }, [fn, running, options.throttleMs]);
9492
- var start = React.useCallback(function () {
9493
- startedAtRef.current = new Date();
9494
- setRunning(true);
9495
- }, []);
9496
- var stop = React.useCallback(function () {
9497
- loopId.current += 1; // force the loop to stop immediately.
9498
- setRunning(false);
9499
- startedAtRef.current = null;
9500
- }, []);
9501
- React.useEffect(function startAutomatically() {
9502
- if (options.autoStart) start();
9503
- return stop;
9504
- }, [options.autoStart, start, stop]);
9505
- return {
9506
- start: start,
9507
- stop: stop
9508
- };
8938
+ }, [fn, running, options.throttleMs]);
8939
+ var start = React.useCallback(function () {
8940
+ startedAtRef.current = new Date();
8941
+ setRunning(true);
8942
+ }, []);
8943
+ var stop = React.useCallback(function () {
8944
+ loopId.current += 1; // force the loop to stop immediately.
8945
+ setRunning(false);
8946
+ startedAtRef.current = null;
8947
+ }, []);
8948
+ React.useEffect(function startAutomatically() {
8949
+ if (options.autoStart) start();
8950
+ return stop;
8951
+ }, [options.autoStart, start, stop]);
8952
+ return {
8953
+ start: start,
8954
+ stop: stop
8955
+ };
9509
8956
  }
9510
8957
 
9511
8958
  var createStoreImpl = function createStoreImpl(createState) {
@@ -12595,7 +12042,8 @@
12595
12042
  Cancel: 'Cancelar',
12596
12043
  'Upload the back of the ID if it is not included in the front image.': 'Adjuntar el reverso de la ID si no se incluye en la imagen del frente',
12597
12044
  'Camera tampering detected': 'Se ha detectado un intento de manipulación de la cámara',
12598
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Lo sentimos, pero parece que la cámara está siendo manipulada. Por favor, verifique su dispositivo y vuelva a intentarlo recargando la página.'
12045
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Lo sentimos, pero parece que la cámara está siendo manipulada. Por favor, verifique su dispositivo y vuelva a intentarlo recargando la página.',
12046
+ 'Position your face in the circle and click to capture.': 'Enfoca tu cara en el círculo y da clic en capturar.'
12599
12047
  };
12600
12048
 
12601
12049
  var de = {
@@ -12724,7 +12172,8 @@
12724
12172
  Cancel: 'Abbrechen',
12725
12173
  'Upload the back of the ID if it is not included in the front image.': 'Laden Sie die Rückseite des Ausweises hoch, wenn diese nicht im Bild der Vorderseite enthalten ist.',
12726
12174
  'Camera tampering detected': 'Kamera manipuliert',
12727
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Leider scheint die Kamera manipuliert zu werden. Bitte prüfen Sie Ihr Gerät und laden Sie die Seite neu.'
12175
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Leider scheint die Kamera manipuliert zu werden. Bitte prüfen Sie Ihr Gerät und laden Sie die Seite neu.',
12176
+ 'Position your face in the circle and click to capture.': 'Stellen Sie Ihr Gesicht im Kreis ein und klicken Sie auf Erfassen.'
12728
12177
  };
12729
12178
 
12730
12179
  var fr = {
@@ -12853,7 +12302,8 @@
12853
12302
  Cancel: 'Annuler',
12854
12303
  'Upload the back of the ID if it is not included in the front image.': "Téléchargez le verso de la pièce d'identité si ce n'est pas inclus dans l'image du recto.",
12855
12304
  'Camera tampering detected': 'Manipulation de la caméra détectée',
12856
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Nous sommes désolés, mais il semble que la caméra soit manipulée. Veuillez vérifier votre appareil et réessayer en rechargeant la page.'
12305
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Nous sommes désolés, mais il semble que la caméra soit manipulée. Veuillez vérifier votre appareil et réessayer en rechargeant la page.',
12306
+ 'Position your face in the circle and click to capture.': 'Positionnez votre visage dans le cercle et cliquez pour capturer.'
12857
12307
  };
12858
12308
 
12859
12309
  var it = {
@@ -12982,7 +12432,8 @@
12982
12432
  Cancel: 'Annulla',
12983
12433
  'Upload the back of the ID if it is not included in the front image.': "Carica il retro dell'ID se non è incluso nell'immagine del fronte.",
12984
12434
  'Camera tampering detected': 'Manipolazione della fotocamera rilevata',
12985
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Siamo spiacenti, ma sembra che la fotocamera stia venendo manipolata. Controlla il tuo dispositivo e riprova ricaricando la pagina.'
12435
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Siamo spiacenti, ma sembra che la fotocamera stia venendo manipolata. Controlla il tuo dispositivo e riprova ricaricando la pagina.',
12436
+ 'Position your face in the circle and click to capture.': 'Posiziona il tuo volto nel cerchio e clicca per acquisire.'
12986
12437
  };
12987
12438
 
12988
12439
  var ja = {
@@ -13111,7 +12562,8 @@
13111
12562
  Cancel: 'キャンセル',
13112
12563
  'Upload the back of the ID if it is not included in the front image.': '表面画像に裏面が含まれていない場合は、裏面をアップロードしてください。',
13113
12564
  'Camera tampering detected': 'カメラの操作が検出されました',
13114
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'カメラの操作が検出されました。デバイスを確認し、ページを再読み込みしてください。'
12565
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'カメラの操作が検出されました。デバイスを確認し、ページを再読み込みしてください。',
12566
+ 'Position your face in the circle and click to capture.': '顔を円の中に合わせてクリックして撮影してください。'
13115
12567
  };
13116
12568
 
13117
12569
  var pt = {
@@ -13240,7 +12692,8 @@
13240
12692
  Cancel: 'Cancelar',
13241
12693
  'Upload the back of the ID if it is not included in the front image.': 'Carregue o verso do ID se não estiver incluído na imagem da frente.',
13242
12694
  'Camera tampering detected': 'Manipulação da câmera detectada',
13243
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Lamentamos, mas parece que a câmera está sendo manipulada. Verifique seu dispositivo e tente novamente recarregando a página.'
12695
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'Lamentamos, mas parece que a câmera está sendo manipulada. Verifique seu dispositivo e tente novamente recarregando a página.',
12696
+ 'Position your face in the circle and click to capture.': 'Posicione seu rosto no círculo e clique para capturar.'
13244
12697
  };
13245
12698
 
13246
12699
  var ru = {
@@ -13369,7 +12822,8 @@
13369
12822
  Cancel: 'Отменить',
13370
12823
  'Upload the back of the ID if it is not included in the front image.': 'Загрузите заднюю сторону удостоверения, если она не включена в изображение передней стороны.',
13371
12824
  'Camera tampering detected': 'Обнаружена манипуляция с камерой',
13372
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'К сожалению, кажется, что камера подвергается манипуляциям. Пожалуйста, проверьте свое устройство и попробуйте снова, перезагрузив страницу.'
12825
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": 'К сожалению, кажется, что камера подвергается манипуляциям. Пожалуйста, проверьте свое устройство и попробуйте снова, перезагрузив страницу.',
12826
+ 'Position your face in the circle and click to capture.': 'Поместите свое лицо в круг и нажмите для съемки.'
13373
12827
  };
13374
12828
 
13375
12829
  var zh = {
@@ -13498,7 +12952,8 @@
13498
12952
  Cancel: '取消',
13499
12953
  'Upload the back of the ID if it is not included in the front image.': '如果正面照片没有包含身份证背面,请上传背面照片。',
13500
12954
  'Camera tampering detected': '檢測到相機被篡改',
13501
- "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": '很抱歉,看起來相機被篡改了。請檢查您的設備並重新載入頁面。'
12955
+ "We're sorry, but it looks like the camera is being tampered with. Please check your device and try again by reloading the page.": '很抱歉,看起來相機被篡改了。請檢查您的設備並重新載入頁面。',
12956
+ 'Position your face in the circle and click to capture.': '將您的臉部置於圓圈中,點擊拍攝。'
13502
12957
  };
13503
12958
 
13504
12959
  function renderVerbiage(verbiage) {
@@ -14248,13 +13703,278 @@
14248
13703
  }), children);
14249
13704
  }
14250
13705
 
14251
- var FocusModelContext = /*#__PURE__*/React.createContext({
14252
- loadFocusModel: function loadFocusModel() {
14253
- return null;
14254
- },
14255
- focusModelState: 'not-started',
14256
- focusModelDownloadProgress: 0,
14257
- focusModelWarmingStartedAt: null,
13706
+ function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
13707
+ var _a;
13708
+ if (quality === void 0) {
13709
+ quality = 0.92;
13710
+ }
13711
+ if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
13712
+ var rawCtx = rawCanvas.getContext('2d');
13713
+ var cropCtx = cropCanvas.getContext('2d');
13714
+ var resizeCtx = resizeCanvas.getContext('2d');
13715
+ if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
13716
+ rawCanvas.width = frame.width;
13717
+ rawCanvas.height = frame.height;
13718
+ rawCtx.putImageData(frame, 0, 0);
13719
+ if (frame.height > frame.width) {
13720
+ cropCanvas.width = frame.width;
13721
+ cropCanvas.height = frame.height;
13722
+ cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
13723
+ } else {
13724
+ var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
13725
+ xMin: 0,
13726
+ width: frame.width
13727
+ },
13728
+ xMin = _b.xMin,
13729
+ width = _b.width;
13730
+ var desiredWidth = frame.height * 0.6;
13731
+ var faceCenterX = xMin + width / 2;
13732
+ var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
13733
+ cropCanvas.width = desiredWidth;
13734
+ cropCanvas.height = frame.height;
13735
+ cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
13736
+ }
13737
+ resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
13738
+ resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
13739
+ resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
13740
+ var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
13741
+ log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
13742
+ clearCanvas(rawCanvas);
13743
+ clearCanvas(cropCanvas);
13744
+ clearCanvas(resizeCanvas);
13745
+ return dataURL;
13746
+ }
13747
+ function cropToDetectedObjectBox(frame, box, canvas, padding) {
13748
+ if (padding === void 0) {
13749
+ padding = 0;
13750
+ }
13751
+ canvas || (canvas = document.createElement('canvas'));
13752
+ var ctx = canvas.getContext('2d');
13753
+ if (!ctx) throw new Error('could not get 2d context');
13754
+ var xMin = box.xMin,
13755
+ yMin = box.yMin,
13756
+ width = box.width,
13757
+ height = box.height;
13758
+ canvas.width = width + padding * 2;
13759
+ canvas.height = height + padding * 2;
13760
+ ctx.drawImage(frame, xMin - padding, yMin - padding, width + padding * 2, height + padding * 2, 0, 0, canvas.width, canvas.height);
13761
+ return canvas;
13762
+ }
13763
+ function cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box, padding) {
13764
+ if (padding === void 0) {
13765
+ padding = 0;
13766
+ }
13767
+ if (!box) return imageData;
13768
+ var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas, padding);
13769
+ var _a = [box.width, box.height],
13770
+ bw = _a[0],
13771
+ bh = _a[1];
13772
+ if (bh <= bw) return cropped;
13773
+ var ctx = rotateCanvas.getContext('2d');
13774
+ if (!ctx) return cropped;
13775
+ rotateCanvas.width = bh;
13776
+ rotateCanvas.height = bw;
13777
+ ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
13778
+ ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
13779
+ ctx.rotate(1.5708); // 90 deg in radians
13780
+ ctx.drawImage(cropped, -bw / 2, -bh / 2);
13781
+ return rotateCanvas;
13782
+ }
13783
+ function resizeIfNecessary(imageData, resizeCanvas, maxWidth) {
13784
+ var width = imageData.width,
13785
+ height = imageData.height;
13786
+ if (width <= maxWidth) return imageData;
13787
+ var resizeCtx = resizeCanvas.getContext('2d');
13788
+ if (!resizeCtx) return imageData;
13789
+ var scale = maxWidth / width;
13790
+ resizeCanvas.width = maxWidth;
13791
+ resizeCanvas.height = height * scale;
13792
+ resizeCtx.drawImage(imageData, 0, 0, resizeCanvas.width, resizeCanvas.height);
13793
+ return resizeCanvas;
13794
+ }
13795
+
13796
+ var defaultFocusModelLoadTimeoutMs = 45000;
13797
+ var defaultFocusThresholds = {
13798
+ idCardFront: {
13799
+ desktop: 0,
13800
+ mobile: 0.3
13801
+ },
13802
+ idCardBack: {
13803
+ desktop: 0,
13804
+ mobile: 0.3
13805
+ },
13806
+ passport: {
13807
+ desktop: 0,
13808
+ mobile: 0.3
13809
+ },
13810
+ singlePage: {
13811
+ desktop: 0,
13812
+ mobile: 0.3
13813
+ }
13814
+ };
13815
+ var classifier$1 = null;
13816
+ var classifierSettings$1 = null;
13817
+ function loadFocusModel() {
13818
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
13819
+ var _a, _b;
13820
+ if (modelAssetPath === void 0) {
13821
+ modelAssetPath = defaultFocusModelPath;
13822
+ }
13823
+ return __generator(this, function (_c) {
13824
+ switch (_c.label) {
13825
+ case 0:
13826
+ if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier$1];
13827
+ closeFocusModel();
13828
+ return [4 /*yield*/, preloadFocusModelDependencies()];
13829
+ case 1:
13830
+ _c.sent();
13831
+ if (modelCapabilities.delegate === 'NONE') {
13832
+ throw new Error('No available delegate for focus detector.');
13833
+ }
13834
+ _b = (_a = Ua).createFromOptions;
13835
+ return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
13836
+ case 2:
13837
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
13838
+ baseOptions: {
13839
+ modelAssetPath: modelAssetPath,
13840
+ delegate: modelCapabilities.delegate
13841
+ },
13842
+ // canvas: document.createElement('canvas'),
13843
+ runningMode: 'VIDEO'
13844
+ }])];
13845
+ case 3:
13846
+ classifier$1 = _c.sent();
13847
+ classifierSettings$1 = {
13848
+ modelAssetPath: modelAssetPath
13849
+ };
13850
+ return [2 /*return*/, classifier$1];
13851
+ }
13852
+ });
13853
+ });
13854
+ }
13855
+ function closeFocusModel() {
13856
+ classifier$1 === null || classifier$1 === void 0 ? void 0 : classifier$1.close();
13857
+ classifier$1 = null;
13858
+ classifierSettings$1 = null;
13859
+ }
13860
+ function useLoadFocusModel(_a) {
13861
+ var _b = _a.modelPath,
13862
+ modelPath = _b === void 0 ? defaultFocusModelPath : _b,
13863
+ _c = _a.modelLoadTimeoutMs,
13864
+ modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
13865
+ onModelError = _a.onModelError,
13866
+ videoRef = _a.videoRef,
13867
+ _d = _a.shouldLoadModels,
13868
+ shouldLoadModels = _d === void 0 ? true : _d;
13869
+ var _e = React.useState('not-started'),
13870
+ modelLoadState = _e[0],
13871
+ setModelLoadState = _e[1];
13872
+ var _f = React.useState(0),
13873
+ modelDownloadProgress = _f[0],
13874
+ setModelDownloadProgress = _f[1];
13875
+ var _g = React.useState(null),
13876
+ modelWarmingStartedAt = _g[0],
13877
+ setModelWarmingStartedAt = _g[1];
13878
+ var _h = React.useState(null),
13879
+ modelError = _h[0],
13880
+ setModelError = _h[1];
13881
+ React.useEffect(function loadModel() {
13882
+ var _this = this;
13883
+ if (!shouldLoadModels) return;
13884
+ setModelLoadState('downloading');
13885
+ setModelWarmingStartedAt(null);
13886
+ function handleDownloadProgress(event) {
13887
+ setModelDownloadProgress(progressToPercentage(event.detail));
13888
+ }
13889
+ document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
13890
+ var modelLoadTimeout = setTimeout(function () {
13891
+ setModelError(new Error('Model loading time limit exceeded.'));
13892
+ }, modelLoadTimeoutMs);
13893
+ var cancelVideoReady = function cancelVideoReady() {};
13894
+ loadFocusModel(modelPath).then(function (loadedModel) {
13895
+ return __awaiter(_this, void 0, void 0, function () {
13896
+ var _a, videoReady, cancel, cancelled;
13897
+ return __generator(this, function (_b) {
13898
+ switch (_b.label) {
13899
+ case 0:
13900
+ setModelDownloadProgress(100);
13901
+ clearTimeout(modelLoadTimeout);
13902
+ setModelLoadState('warming');
13903
+ setModelWarmingStartedAt(performance.now());
13904
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
13905
+ cancelled = false;
13906
+ cancelVideoReady = function cancelVideoReady() {
13907
+ cancelled = true;
13908
+ cancel();
13909
+ };
13910
+ return [4 /*yield*/, videoReady];
13911
+ case 1:
13912
+ _b.sent();
13913
+ setTimeout(function () {
13914
+ if (cancelled) return;
13915
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
13916
+ setModelLoadState('ready');
13917
+ }, 500);
13918
+ return [2 /*return*/];
13919
+ }
13920
+ });
13921
+ });
13922
+ })["catch"](function (e) {
13923
+ setModelError(e);
13924
+ setModelLoadState('error');
13925
+ })["finally"](function () {
13926
+ clearTimeout(modelLoadTimeout);
13927
+ });
13928
+ return function () {
13929
+ log('unloading focus model');
13930
+ cancelVideoReady();
13931
+ closeFocusModel();
13932
+ clearTimeout(modelLoadTimeout);
13933
+ document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
13934
+ };
13935
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
13936
+ React.useEffect(function handleModelError() {
13937
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
13938
+ }, [modelError, onModelError]);
13939
+ return React.useMemo(function () {
13940
+ return {
13941
+ ready: modelLoadState === 'ready',
13942
+ modelLoadState: modelLoadState,
13943
+ modelDownloadProgress: modelDownloadProgress,
13944
+ modelWarmingStartedAt: modelWarmingStartedAt,
13945
+ modelError: modelError
13946
+ };
13947
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
13948
+ }
13949
+ var lastFocusPredictionAt = 0;
13950
+ var lastFocusPredictionTime = 0;
13951
+ function setLastFocusPredictionAt(time) {
13952
+ lastFocusPredictionTime = time - lastFocusPredictionAt;
13953
+ lastFocusPredictionAt = time;
13954
+ }
13955
+ function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
13956
+ var _a, _b, _c, _d, _e;
13957
+ if (!classifier$1) return null;
13958
+ var startedAt = performance.now();
13959
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
13960
+ var result = classifier$1.classifyForVideo(image, performance.now());
13961
+ var score = (_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.classifications) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.categories) === null || _c === void 0 ? void 0 : _c.find(function (c) {
13962
+ return c.categoryName === 'focused';
13963
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
13964
+ var predictionTime = performance.now() - startedAt;
13965
+ return {
13966
+ score: score,
13967
+ predictionTime: predictionTime
13968
+ };
13969
+ }
13970
+
13971
+ var FocusModelContext = /*#__PURE__*/React.createContext({
13972
+ loadFocusModel: function loadFocusModel() {
13973
+ return null;
13974
+ },
13975
+ focusModelState: 'not-started',
13976
+ focusModelDownloadProgress: 0,
13977
+ focusModelWarmingStartedAt: null,
14258
13978
  focusModelError: null,
14259
13979
  focusThresholds: {},
14260
13980
  setFocusThresholds: function setFocusThresholds() {
@@ -14322,7 +14042,7 @@
14322
14042
  }, [focusThresholds, load, makeFocusPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
14323
14043
  return /*#__PURE__*/React.createElement(FocusModelContext.Provider, {
14324
14044
  value: value
14325
- }, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14045
+ }, /*#__PURE__*/React.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14326
14046
  ref: rotateCanvas,
14327
14047
  style: showCanvases ? {
14328
14048
  display: 'block'
@@ -14332,7 +14052,7 @@
14332
14052
  style: showCanvases ? {
14333
14053
  display: 'block'
14334
14054
  } : undefined
14335
- }), children);
14055
+ })), children);
14336
14056
  }
14337
14057
 
14338
14058
  function _isNavigatorDefined() {
@@ -14367,23 +14087,276 @@
14367
14087
  return false;
14368
14088
  }
14369
14089
 
14370
- var onMobile = isMobile();
14371
- var defaultIdCaptureThresholds = {
14372
- detection: defaultDocumentDetectionThresholds,
14373
- focus: defaultFocusThresholds
14374
- };
14375
- var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
14376
- ready: false,
14377
- start: function start() {
14378
- return null;
14379
- },
14380
- stop: function stop() {
14381
- return null;
14382
- },
14383
- load: function load() {
14384
- return null;
14385
- },
14386
- modelDownloadProgress: 0,
14090
+ var defaultBarcodeReadabilityModelLoadTimeoutMs = 45000;
14091
+ var classifier = null;
14092
+ var classifierSettings = null;
14093
+ function loadBarcodeReadabilityModel() {
14094
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
14095
+ var _a, _b;
14096
+ if (modelAssetPath === void 0) {
14097
+ modelAssetPath = defaultBarcodeReadabilityModelPath;
14098
+ }
14099
+ return __generator(this, function (_c) {
14100
+ switch (_c.label) {
14101
+ case 0:
14102
+ if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
14103
+ closeBarcodeReadabilityModel();
14104
+ return [4 /*yield*/, preloadBarcodeReadabilityModelDependencies()];
14105
+ case 1:
14106
+ _c.sent();
14107
+ if (modelCapabilities.delegate === 'NONE') {
14108
+ throw new Error('No available delegate for barcode readability model.');
14109
+ }
14110
+ _b = (_a = Ua).createFromOptions;
14111
+ return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
14112
+ case 2:
14113
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
14114
+ baseOptions: {
14115
+ modelAssetPath: modelAssetPath,
14116
+ delegate: 'CPU'
14117
+ },
14118
+ runningMode: 'VIDEO',
14119
+ maxResults: 1
14120
+ }])];
14121
+ case 3:
14122
+ classifier = _c.sent();
14123
+ classifierSettings = {
14124
+ modelAssetPath: modelAssetPath
14125
+ };
14126
+ return [2 /*return*/, classifier];
14127
+ }
14128
+ });
14129
+ });
14130
+ }
14131
+ function closeBarcodeReadabilityModel() {
14132
+ classifier === null || classifier === void 0 ? void 0 : classifier.close();
14133
+ classifier = null;
14134
+ classifierSettings = null;
14135
+ }
14136
+ function useLoadBarcodeReadabilityModel(_a) {
14137
+ var _b = _a.modelPath,
14138
+ modelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
14139
+ _c = _a.modelLoadTimeoutMs,
14140
+ modelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
14141
+ onModelError = _a.onModelError,
14142
+ videoRef = _a.videoRef,
14143
+ _d = _a.shouldLoadModels,
14144
+ shouldLoadModels = _d === void 0 ? true : _d;
14145
+ var _e = React.useState('not-started'),
14146
+ modelLoadState = _e[0],
14147
+ setModelLoadState = _e[1];
14148
+ var _f = React.useState(0),
14149
+ modelDownloadProgress = _f[0],
14150
+ setModelDownloadProgress = _f[1];
14151
+ var _g = React.useState(null),
14152
+ modelWarmingStartedAt = _g[0],
14153
+ setModelWarmingStartedAt = _g[1];
14154
+ var _h = React.useState(null),
14155
+ modelError = _h[0],
14156
+ setModelError = _h[1];
14157
+ React.useEffect(function loadModel() {
14158
+ var _this = this;
14159
+ if (!shouldLoadModels) return;
14160
+ setModelLoadState('downloading');
14161
+ setModelWarmingStartedAt(null);
14162
+ function handleDownloadProgress(event) {
14163
+ setModelDownloadProgress(progressToPercentage(event.detail));
14164
+ }
14165
+ document.addEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
14166
+ var modelLoadTimeout = setTimeout(function () {
14167
+ setModelError(new Error('Model loading time limit exceeded.'));
14168
+ }, modelLoadTimeoutMs);
14169
+ var cancelVideoReady = function cancelVideoReady() {};
14170
+ loadBarcodeReadabilityModel(modelPath).then(function (loadedModel) {
14171
+ return __awaiter(_this, void 0, void 0, function () {
14172
+ var _a, videoReady, cancel, cancelled;
14173
+ return __generator(this, function (_b) {
14174
+ switch (_b.label) {
14175
+ case 0:
14176
+ setModelDownloadProgress(100);
14177
+ clearTimeout(modelLoadTimeout);
14178
+ setModelLoadState('warming');
14179
+ setModelWarmingStartedAt(new Date().getTime());
14180
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
14181
+ cancelled = false;
14182
+ cancelVideoReady = function cancelVideoReady() {
14183
+ cancelled = true;
14184
+ cancel();
14185
+ };
14186
+ return [4 /*yield*/, videoReady];
14187
+ case 1:
14188
+ _b.sent();
14189
+ setTimeout(function () {
14190
+ if (cancelled) return;
14191
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
14192
+ setModelLoadState('ready');
14193
+ }, 500);
14194
+ return [2 /*return*/];
14195
+ }
14196
+ });
14197
+ });
14198
+ })["catch"](function (e) {
14199
+ setModelError(e);
14200
+ setModelLoadState('error');
14201
+ })["finally"](function () {
14202
+ clearTimeout(modelLoadTimeout);
14203
+ });
14204
+ return function () {
14205
+ log('unloading barcode readability model');
14206
+ cancelVideoReady();
14207
+ closeBarcodeReadabilityModel();
14208
+ clearTimeout(modelLoadTimeout);
14209
+ document.removeEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
14210
+ };
14211
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
14212
+ React.useEffect(function handleModelError() {
14213
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
14214
+ }, [modelError, onModelError]);
14215
+ return React.useMemo(function () {
14216
+ return {
14217
+ ready: modelLoadState === 'ready',
14218
+ modelLoadState: modelLoadState,
14219
+ modelDownloadProgress: modelDownloadProgress,
14220
+ modelWarmingStartedAt: modelWarmingStartedAt,
14221
+ modelError: modelError
14222
+ };
14223
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
14224
+ }
14225
+ var lastBarcodeReadabilityPredictionAt = 0;
14226
+ var lastBarcodeReadabilityPredictionTime = 0;
14227
+ function setLastBarcodeReadabilityPredictionAt(time) {
14228
+ lastBarcodeReadabilityPredictionTime = time - lastBarcodeReadabilityPredictionAt;
14229
+ lastBarcodeReadabilityPredictionAt = time;
14230
+ }
14231
+ function makeBarcodeReadabilityModelPrediction(imageData, cropCanvas, rotateCanvas, resizeCanvas, box) {
14232
+ var _a, _b, _c, _d, _e;
14233
+ if (!classifier) return null;
14234
+ var startedAt = performance.now();
14235
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
14236
+ var resized = resizeIfNecessary(image, resizeCanvas, 500);
14237
+ var result = classifier.classifyForVideo(resized, performance.now());
14238
+ var score = (_e = (_d = (_c = (_b = (_a = result === null || result === void 0 ? void 0 : result.classifications) === null || _a === void 0 ? void 0 : _a[0]) === null || _b === void 0 ? void 0 : _b.categories) === null || _c === void 0 ? void 0 : _c.find(function (c) {
14239
+ return c.categoryName === 'blurry';
14240
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
14241
+ debug('barcode prediction', "".concat(performance.now() - startedAt, "ms"), score);
14242
+ var predictionTime = performance.now() - startedAt;
14243
+ return {
14244
+ score: score,
14245
+ predictionTime: predictionTime
14246
+ };
14247
+ }
14248
+
14249
+ var BarcodeReadabilityModelContext = /*#__PURE__*/React.createContext({
14250
+ loadBarcodeReadabilityModel: function loadBarcodeReadabilityModel() {
14251
+ return null;
14252
+ },
14253
+ barcodeReadabilityModelState: 'not-started',
14254
+ barcodeReadabilityModelDownloadProgress: 0,
14255
+ barcodeReadabilityModelWarmingStartedAt: null,
14256
+ barcodeReadabilityModelError: null,
14257
+ barcodeReadabilityThresholds: {},
14258
+ setBarcodeReadabilityThresholds: function setBarcodeReadabilityThresholds() {
14259
+ return null;
14260
+ },
14261
+ makeBarcodeReadabilityPrediction: function makeBarcodeReadabilityPrediction() {
14262
+ return null;
14263
+ },
14264
+ barcodeReadabilityPredictionTime: 0
14265
+ });
14266
+ function BarcodeReadabilityModelProvider(_a) {
14267
+ var children = _a.children,
14268
+ _b = _a.barcodeReadabilityModelPath,
14269
+ barcodeReadabilityModelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
14270
+ _c = _a.barcodeReadabilityModelLoadTimeoutMs,
14271
+ barcodeReadabilityModelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
14272
+ onBarcodeReadabilityModelError = _a.onBarcodeReadabilityModelError,
14273
+ _d = _a.showCanvases,
14274
+ showCanvases = _d === void 0 ? false : _d,
14275
+ _e = _a.shouldLoadModels,
14276
+ shouldLoadModelsProp = _e === void 0 ? true : _e;
14277
+ var cropCanvas = React.useRef(null);
14278
+ var rotateCanvas = React.useRef(null);
14279
+ var resizeCanvas = React.useRef(null);
14280
+ var _f = React.useState({}),
14281
+ barcodeReadabilityThresholds = _f[0],
14282
+ setBarcodeReadabilityThresholds = _f[1];
14283
+ var videoRef = useCameraStore().videoRef;
14284
+ var _g = React.useState(shouldLoadModelsProp),
14285
+ shouldLoadModels = _g[0],
14286
+ setShouldLoadModels = _g[1];
14287
+ var load = React.useCallback(function () {
14288
+ return setShouldLoadModels(true);
14289
+ }, []);
14290
+ var _h = useLoadBarcodeReadabilityModel({
14291
+ modelPath: barcodeReadabilityModelPath,
14292
+ modelLoadTimeoutMs: barcodeReadabilityModelLoadTimeoutMs,
14293
+ onModelError: onBarcodeReadabilityModelError,
14294
+ videoRef: videoRef,
14295
+ shouldLoadModels: shouldLoadModels
14296
+ }),
14297
+ ready = _h.ready,
14298
+ modelLoadState = _h.modelLoadState,
14299
+ modelDownloadProgress = _h.modelDownloadProgress,
14300
+ modelWarmingStartedAt = _h.modelWarmingStartedAt,
14301
+ modelError = _h.modelError;
14302
+ var makeBarcodeReadabilityPrediction = React.useCallback(function (imageData, box) {
14303
+ if (!ready) return null;
14304
+ var prediction = makeBarcodeReadabilityModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, resizeCanvas.current, box);
14305
+ if (!prediction) return null;
14306
+ setLastBarcodeReadabilityPredictionAt(prediction.predictionTime);
14307
+ return prediction;
14308
+ }, [ready]);
14309
+ var value = React.useMemo(function () {
14310
+ return {
14311
+ loadBarcodeReadabilityModel: load,
14312
+ barcodeReadabilityModelState: modelLoadState,
14313
+ barcodeReadabilityModelDownloadProgress: modelDownloadProgress,
14314
+ barcodeReadabilityModelWarmingStartedAt: modelWarmingStartedAt,
14315
+ barcodeReadabilityModelError: modelError,
14316
+ makeBarcodeReadabilityPrediction: makeBarcodeReadabilityPrediction,
14317
+ barcodeReadabilityPredictionTime: lastBarcodeReadabilityPredictionTime,
14318
+ barcodeReadabilityThresholds: barcodeReadabilityThresholds,
14319
+ setBarcodeReadabilityThresholds: setBarcodeReadabilityThresholds
14320
+ };
14321
+ }, [barcodeReadabilityThresholds, load, makeBarcodeReadabilityPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
14322
+ return /*#__PURE__*/React.createElement(BarcodeReadabilityModelContext.Provider, {
14323
+ value: value
14324
+ }, /*#__PURE__*/React.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14325
+ ref: rotateCanvas
14326
+ }), /*#__PURE__*/React.createElement(InvisibleCanvas, {
14327
+ ref: cropCanvas
14328
+ }), /*#__PURE__*/React.createElement(InvisibleCanvas, {
14329
+ ref: resizeCanvas,
14330
+ style: showCanvases ? {
14331
+ display: 'block'
14332
+ } : undefined
14333
+ })), children);
14334
+ }
14335
+ function useBarcodeReadabilityModelContext() {
14336
+ var context = React.useContext(BarcodeReadabilityModelContext);
14337
+ if (!context) {
14338
+ throw new Error('useBarcodeReadabilityModelContext must be used within an BarcodeReadabilityModelProvider');
14339
+ }
14340
+ return context;
14341
+ }
14342
+
14343
+ var onMobile = isMobile();
14344
+ var defaultIdCaptureThresholds = {
14345
+ detection: defaultDocumentDetectionThresholds,
14346
+ focus: defaultFocusThresholds
14347
+ };
14348
+ var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
14349
+ ready: false,
14350
+ start: function start() {
14351
+ return null;
14352
+ },
14353
+ stop: function stop() {
14354
+ return null;
14355
+ },
14356
+ load: function load() {
14357
+ return null;
14358
+ },
14359
+ modelDownloadProgress: 0,
14387
14360
  modelLoadState: 'not-started',
14388
14361
  modelWarmingStartedAt: null,
14389
14362
  modelError: null,
@@ -14400,6 +14373,7 @@
14400
14373
  },
14401
14374
  detectionTime: 0,
14402
14375
  focusPredictionTime: 0,
14376
+ barcodeReadabilityPredictionTime: 0,
14403
14377
  bestFrameDetails: {
14404
14378
  current: null
14405
14379
  },
@@ -14409,55 +14383,78 @@
14409
14383
  resetBestFrame: function resetBestFrame() {
14410
14384
  return null;
14411
14385
  },
14386
+ bestBarcodeDetails: {
14387
+ current: null
14388
+ },
14389
+ getBestBarcode: function getBestBarcode() {
14390
+ return null;
14391
+ },
14412
14392
  requiredDocumentType: 'none',
14413
14393
  setRequiredDocumentType: function setRequiredDocumentType() {
14414
14394
  return null;
14415
14395
  }
14416
14396
  });
14417
14397
  function IdCaptureModelsProviderInner(_a) {
14398
+ var _b;
14418
14399
  var children = _a.children,
14419
14400
  onModelError = _a.onModelError,
14420
- _b = _a.allowSinglePageIdCapture,
14421
- allowSinglePageIdCapture = _b === void 0 ? false : _b;
14422
- var _c = React.useContext(DocumentDetectionModelContext),
14423
- documentDetectionModelState = _c.documentDetectionModelState,
14424
- documentDetectionModelDownloadProgress = _c.documentDetectionModelDownloadProgress,
14425
- documentDetectionModelWarmingStartedAt = _c.documentDetectionModelWarmingStartedAt,
14426
- startDocumentDetection = _c.startDocumentDetection,
14427
- stopDocumentDetection = _c.stopDocumentDetection,
14428
- loadDocumentDetectionModel = _c.loadDocumentDetectionModel,
14429
- lastPredictionCanvas = _c.documentDetectionLastPredictionCanvas,
14430
- clearDocumentDetectionLastPredictionCanvas = _c.clearDocumentDetectionLastPredictionCanvas,
14431
- onDocumentDetected = _c.onDocumentDetected,
14432
- detectionTime = _c.detectionTime,
14433
- documentDetectionThresholds = _c.documentDetectionThresholds,
14434
- setDocumentDetectionThresholds = _c.setDocumentDetectionThresholds,
14435
- documentDetectionBoundaries = _c.documentDetectionBoundaries,
14436
- setDocumentDetectionBoundaries = _c.setDocumentDetectionBoundaries,
14437
- documentDetectionModelError = _c.documentDetectionModelError;
14438
- var _d = React.useContext(FocusModelContext),
14439
- loadFocusModel = _d.loadFocusModel,
14440
- focusModelState = _d.focusModelState,
14441
- focusModelDownloadProgress = _d.focusModelDownloadProgress,
14442
- focusModelWarmingStartedAt = _d.focusModelWarmingStartedAt,
14443
- makeFocusPrediction = _d.makeFocusPrediction,
14444
- focusThresholds = _d.focusThresholds,
14445
- setFocusThresholds = _d.setFocusThresholds,
14446
- focusPredictionTime = _d.focusPredictionTime,
14447
- focusModelError = _d.focusModelError;
14401
+ _c = _a.allowSinglePageIdCapture,
14402
+ allowSinglePageIdCapture = _c === void 0 ? false : _c,
14403
+ _d = _a.enableBarcodeReadabilityModel,
14404
+ enableBarcodeReadabilityModel = _d === void 0 ? true : _d;
14405
+ var _e = React.useContext(DocumentDetectionModelContext),
14406
+ documentDetectionModelState = _e.documentDetectionModelState,
14407
+ documentDetectionModelDownloadProgress = _e.documentDetectionModelDownloadProgress,
14408
+ documentDetectionModelWarmingStartedAt = _e.documentDetectionModelWarmingStartedAt,
14409
+ startDocumentDetection = _e.startDocumentDetection,
14410
+ stopDocumentDetection = _e.stopDocumentDetection,
14411
+ loadDocumentDetectionModel = _e.loadDocumentDetectionModel,
14412
+ lastPredictionCanvas = _e.documentDetectionLastPredictionCanvas,
14413
+ clearDocumentDetectionLastPredictionCanvas = _e.clearDocumentDetectionLastPredictionCanvas,
14414
+ onDocumentDetected = _e.onDocumentDetected,
14415
+ detectionTime = _e.detectionTime,
14416
+ documentDetectionThresholds = _e.documentDetectionThresholds,
14417
+ setDocumentDetectionThresholds = _e.setDocumentDetectionThresholds,
14418
+ documentDetectionBoundaries = _e.documentDetectionBoundaries,
14419
+ setDocumentDetectionBoundaries = _e.setDocumentDetectionBoundaries,
14420
+ documentDetectionModelError = _e.documentDetectionModelError;
14421
+ var _f = React.useContext(FocusModelContext),
14422
+ loadFocusModel = _f.loadFocusModel,
14423
+ focusModelState = _f.focusModelState,
14424
+ focusModelDownloadProgress = _f.focusModelDownloadProgress,
14425
+ focusModelWarmingStartedAt = _f.focusModelWarmingStartedAt,
14426
+ makeFocusPrediction = _f.makeFocusPrediction,
14427
+ focusThresholds = _f.focusThresholds,
14428
+ setFocusThresholds = _f.setFocusThresholds,
14429
+ focusPredictionTime = _f.focusPredictionTime,
14430
+ focusModelError = _f.focusModelError;
14431
+ var _g = useBarcodeReadabilityModelContext(),
14432
+ loadBarcodeReadabilityModel = _g.loadBarcodeReadabilityModel,
14433
+ barcodeReadabilityModelState = _g.barcodeReadabilityModelState,
14434
+ barcodeReadabilityModelDownloadProgress = _g.barcodeReadabilityModelDownloadProgress,
14435
+ barcodeReadabilityModelWarmingStartedAt = _g.barcodeReadabilityModelWarmingStartedAt,
14436
+ makeBarcodeReadabilityPrediction = _g.makeBarcodeReadabilityPrediction,
14437
+ barcodeReadabilityThresholds = _g.barcodeReadabilityThresholds,
14438
+ setBarcodeReadabilityThresholds = _g.setBarcodeReadabilityThresholds,
14439
+ barcodeReadabilityPredictionTime = _g.barcodeReadabilityPredictionTime,
14440
+ barcodeReadabilityModelError = _g.barcodeReadabilityModelError;
14448
14441
  var onPredictionHandler = React.useRef();
14449
14442
  var bestFrameDetails = React.useRef(null);
14443
+ var bestBarcodeDetails = React.useRef(null);
14450
14444
  var bestPredictionCanvas = React.useRef(null);
14445
+ var bestBarcodeCanvas = React.useRef(null);
14451
14446
  var bestFocusScore = React.useRef(0);
14447
+ var bestBarcodeScore = React.useRef(0);
14452
14448
  var stopDetection = React.useRef(0);
14453
- var _e = React.useState('none'),
14454
- requiredDocumentType = _e[0],
14455
- setRequiredDocumentType = _e[1];
14449
+ var _h = React.useState('none'),
14450
+ requiredDocumentType = _h[0],
14451
+ setRequiredDocumentType = _h[1];
14456
14452
  var thresholds = React.useMemo(function () {
14457
14453
  return _assign(_assign({}, documentDetectionThresholds), {
14458
- focus: focusThresholds
14454
+ focus: focusThresholds,
14455
+ barcodeReadability: barcodeReadabilityThresholds
14459
14456
  });
14460
- }, [documentDetectionThresholds, focusThresholds]);
14457
+ }, [documentDetectionThresholds, focusThresholds, barcodeReadabilityThresholds]);
14461
14458
  var setThresholds = React.useCallback(function (thresholds) {
14462
14459
  if (thresholds.detection) {
14463
14460
  setDocumentDetectionThresholds(thresholds.detection);
@@ -14465,17 +14462,20 @@
14465
14462
  if (thresholds.focus) {
14466
14463
  setFocusThresholds(thresholds.focus);
14467
14464
  }
14468
- }, [setDocumentDetectionThresholds, setFocusThresholds]);
14465
+ if (thresholds.barcodeReadability) {
14466
+ setBarcodeReadabilityThresholds(thresholds.barcodeReadability);
14467
+ }
14468
+ }, [setBarcodeReadabilityThresholds, setDocumentDetectionThresholds, setFocusThresholds]);
14469
14469
  React.useEffect(function handleDetections() {
14470
14470
  var _this = this;
14471
14471
  onDocumentDetected(function (prediction) {
14472
14472
  return __awaiter(_this, void 0, void 0, function () {
14473
- var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold;
14474
- var _a, _b, _c, _d, _e, _f, _g;
14475
- return __generator(this, function (_h) {
14473
+ var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold, pdf417Prediction, barcodeReadabilityThresholdSet, barcodeReadabilityThreshold;
14474
+ var _a, _b, _c, _d, _e, _f, _g, _h;
14475
+ return __generator(this, function (_j) {
14476
14476
  if (!lastPredictionCanvas.current) return [2 /*return*/];
14477
14477
  stopDetectionAtStart = stopDetection.current;
14478
- focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false;
14478
+ focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false, pdf417PredictionTime = 0, pdf417PredictionScore = 0, pdf417PredictionThresholdMet = false;
14479
14479
  isSinglePage = prediction.detectedDocumentType === 'singlePage';
14480
14480
  if (!allowSinglePageIdCapture && isSinglePage) {
14481
14481
  prediction.detectedDocumentType = 'passport';
@@ -14494,28 +14494,51 @@
14494
14494
  focusThresholdSet = (_d = thresholds.focus) === null || _d === void 0 ? void 0 : _d[prediction.detectedDocumentType];
14495
14495
  focusThreshold = (_e = onMobile ? focusThresholdSet === null || focusThresholdSet === void 0 ? void 0 : focusThresholdSet.mobile : focusThresholdSet === null || focusThresholdSet === void 0 ? void 0 : focusThresholdSet.desktop) !== null && _e !== void 0 ? _e : 0;
14496
14496
  focusThresholdMet = focusScore >= focusThreshold;
14497
- if (bestFocusScore.current <= focusScore && stopDetectionAtStart === stopDetection.current) {
14498
- bestFocusScore.current = focusScore;
14499
- drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
14500
- bestFrameDetails.current = {
14501
- boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
14502
- documentType: prediction.detectedDocumentType,
14503
- detectionScore: prediction.detectionScore,
14504
- focusScore: focusScore
14505
- };
14497
+ if (stopDetectionAtStart === stopDetection.current) {
14498
+ if (bestFocusScore.current <= focusScore) {
14499
+ bestFocusScore.current = focusScore;
14500
+ drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
14501
+ bestFrameDetails.current = {
14502
+ boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
14503
+ documentType: prediction.detectedDocumentType,
14504
+ detectionScore: prediction.detectionScore,
14505
+ focusScore: focusScore
14506
+ };
14507
+ }
14508
+ if (enableBarcodeReadabilityModel && prediction.bestPDF417) {
14509
+ pdf417Prediction = makeBarcodeReadabilityPrediction(lastPredictionCanvas.current, prediction.bestPDF417.box);
14510
+ if (pdf417Prediction) {
14511
+ pdf417PredictionTime = pdf417Prediction.predictionTime;
14512
+ pdf417PredictionScore = pdf417Prediction.score;
14513
+ if (bestBarcodeScore.current <= pdf417Prediction.score) {
14514
+ bestBarcodeScore.current = pdf417Prediction.score;
14515
+ bestBarcodeDetails.current = {
14516
+ boundingBox: prediction.bestPDF417.box,
14517
+ score: pdf417Prediction.score
14518
+ };
14519
+ drawToCanvas(bestBarcodeCanvas.current, cropToDetectedObjectBox(lastPredictionCanvas.current, prediction.bestPDF417.box, undefined, 16));
14520
+ barcodeReadabilityThresholdSet = barcodeReadabilityThresholds[prediction.detectedDocumentType];
14521
+ barcodeReadabilityThreshold = (_g = onMobile ? barcodeReadabilityThresholdSet === null || barcodeReadabilityThresholdSet === void 0 ? void 0 : barcodeReadabilityThresholdSet.mobile : barcodeReadabilityThresholdSet === null || barcodeReadabilityThresholdSet === void 0 ? void 0 : barcodeReadabilityThresholdSet.desktop) !== null && _g !== void 0 ? _g : 0;
14522
+ pdf417PredictionThresholdMet = pdf417PredictionScore >= barcodeReadabilityThreshold;
14523
+ }
14524
+ }
14525
+ }
14506
14526
  }
14507
14527
  }
14508
- (_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
14528
+ (_h = onPredictionHandler.current) === null || _h === void 0 ? void 0 : _h.call(onPredictionHandler, _assign(_assign({}, prediction), {
14509
14529
  focusScore: focusScore,
14510
14530
  focusPredictionTime: focusPredictionTime,
14511
- focusThresholdMet: focusThresholdMet
14531
+ focusThresholdMet: focusThresholdMet,
14532
+ pdf417PredictionTime: pdf417PredictionTime,
14533
+ pdf417PredictionScore: pdf417PredictionScore,
14534
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet
14512
14535
  }));
14513
14536
  return [2 /*return*/];
14514
14537
  });
14515
14538
  });
14516
14539
  });
14517
- }, [allowSinglePageIdCapture, lastPredictionCanvas, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
14518
- var modelError = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError;
14540
+ }, [allowSinglePageIdCapture, barcodeReadabilityThresholds, enableBarcodeReadabilityModel, lastPredictionCanvas, makeBarcodeReadabilityPrediction, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
14541
+ var modelError = (_b = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError) !== null && _b !== void 0 ? _b : barcodeReadabilityModelError;
14519
14542
  React.useEffect(function handleModelErrors() {
14520
14543
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
14521
14544
  }, [modelError, onModelError]);
@@ -14528,9 +14551,15 @@
14528
14551
  canvas: bestPredictionCanvas.current
14529
14552
  });
14530
14553
  }, []);
14531
- var _f = React.useState(0),
14532
- canvasKey = _f[0],
14533
- setCanvasKey = _f[1];
14554
+ var getBestBarcode = React.useCallback(function () {
14555
+ if (!bestBarcodeDetails.current || !bestBarcodeCanvas.current) return null;
14556
+ return _assign(_assign({}, bestBarcodeDetails.current), {
14557
+ canvas: bestBarcodeCanvas.current
14558
+ });
14559
+ }, []);
14560
+ var _j = React.useState(0),
14561
+ canvasKey = _j[0],
14562
+ setCanvasKey = _j[1];
14534
14563
  var resetBestFrame = React.useCallback(function () {
14535
14564
  stopDetection.current += 1;
14536
14565
  setCanvasKey(function (n) {
@@ -14546,16 +14575,45 @@
14546
14575
  var load = React.useCallback(function () {
14547
14576
  loadDocumentDetectionModel();
14548
14577
  loadFocusModel();
14549
- }, [loadDocumentDetectionModel, loadFocusModel]);
14550
- var ready = documentDetectionModelState === 'ready' && focusModelState === 'ready';
14551
- var modelLoadState = ready ? 'ready' : documentDetectionModelState === 'warming' || focusModelState === 'warming' ? 'warming' : focusModelState === 'downloading' || documentDetectionModelState === 'downloading' ? 'downloading' : 'not-started';
14552
- var modelWarmingStartedAt = !documentDetectionModelWarmingStartedAt && !focusModelWarmingStartedAt ? null : Math.min.apply(Math, [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt].filter(function (v) {
14553
- return v !== null;
14554
- }));
14578
+ if (enableBarcodeReadabilityModel) loadBarcodeReadabilityModel();
14579
+ }, [enableBarcodeReadabilityModel, loadBarcodeReadabilityModel, loadDocumentDetectionModel, loadFocusModel]);
14580
+ var _k = React.useMemo(function () {
14581
+ var modelStates = [documentDetectionModelState, focusModelState];
14582
+ var modelWarmingStartedAts = [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt];
14583
+ var modelDownloadProgresses = [documentDetectionModelDownloadProgress, focusModelDownloadProgress];
14584
+ if (enableBarcodeReadabilityModel) {
14585
+ modelStates.push(barcodeReadabilityModelState);
14586
+ modelWarmingStartedAts.push(barcodeReadabilityModelWarmingStartedAt);
14587
+ modelDownloadProgresses.push(barcodeReadabilityModelDownloadProgress);
14588
+ }
14589
+ var ready = modelStates.every(function (state) {
14590
+ return state === 'ready';
14591
+ });
14592
+ return {
14593
+ ready: ready,
14594
+ modelLoadState: ready ? 'ready' : modelStates.some(function (state) {
14595
+ return state === 'warming';
14596
+ }) ? 'warming' : modelStates.some(function (state) {
14597
+ return state === 'downloading';
14598
+ }) ? 'downloading' : 'not-started',
14599
+ modelWarmingStartedAt: modelWarmingStartedAts.every(function (v) {
14600
+ return v === null;
14601
+ }) ? null : Math.min.apply(Math, modelWarmingStartedAts.filter(function (v) {
14602
+ return v !== null;
14603
+ })),
14604
+ modelDownloadProgress: modelDownloadProgresses.reduce(function (a, b) {
14605
+ return a + b;
14606
+ }, 0) / modelDownloadProgresses.length
14607
+ };
14608
+ }, [barcodeReadabilityModelDownloadProgress, barcodeReadabilityModelState, barcodeReadabilityModelWarmingStartedAt, documentDetectionModelDownloadProgress, documentDetectionModelState, documentDetectionModelWarmingStartedAt, enableBarcodeReadabilityModel, focusModelDownloadProgress, focusModelState, focusModelWarmingStartedAt]),
14609
+ ready = _k.ready,
14610
+ modelLoadState = _k.modelLoadState,
14611
+ modelWarmingStartedAt = _k.modelWarmingStartedAt,
14612
+ modelDownloadProgress = _k.modelDownloadProgress;
14555
14613
  var value = React.useMemo(function () {
14556
14614
  return {
14557
14615
  ready: ready,
14558
- modelDownloadProgress: (documentDetectionModelDownloadProgress + focusModelDownloadProgress) / 2,
14616
+ modelDownloadProgress: modelDownloadProgress,
14559
14617
  modelLoadState: modelLoadState,
14560
14618
  modelWarmingStartedAt: modelWarmingStartedAt,
14561
14619
  modelError: modelError,
@@ -14569,24 +14627,32 @@
14569
14627
  onPredictionMade: onPredictionMade,
14570
14628
  detectionTime: detectionTime,
14571
14629
  focusPredictionTime: focusPredictionTime,
14630
+ barcodeReadabilityPredictionTime: barcodeReadabilityPredictionTime,
14572
14631
  getBestFrame: getBestFrame,
14573
14632
  resetBestFrame: resetBestFrame,
14574
14633
  bestFrameDetails: bestFrameDetails,
14634
+ bestBarcodeDetails: bestBarcodeDetails,
14635
+ getBestBarcode: getBestBarcode,
14575
14636
  requiredDocumentType: requiredDocumentType,
14576
14637
  setRequiredDocumentType: setRequiredDocumentType
14577
14638
  };
14578
- }, [detectionTime, documentDetectionBoundaries, documentDetectionModelDownloadProgress, focusModelDownloadProgress, focusPredictionTime, getBestFrame, load, modelLoadState, modelError, modelWarmingStartedAt, onPredictionMade, ready, requiredDocumentType, resetBestFrame, setDocumentDetectionBoundaries, setThresholds, startDocumentDetection, stopDocumentDetection, thresholds]);
14639
+ }, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, requiredDocumentType]);
14579
14640
  return /*#__PURE__*/React.createElement(IdCaptureModelsContext.Provider, {
14580
14641
  value: value
14581
14642
  }, /*#__PURE__*/React.createElement(InvisibleCanvas, {
14582
- key: canvasKey,
14643
+ key: "bf-".concat(canvasKey),
14583
14644
  ref: bestPredictionCanvas
14645
+ }), /*#__PURE__*/React.createElement(InvisibleCanvas, {
14646
+ key: "bb-".concat(canvasKey),
14647
+ ref: bestBarcodeCanvas
14584
14648
  }), children);
14585
14649
  }
14586
14650
  function IdCaptureModelsProvider(_a) {
14587
14651
  var children = _a.children,
14588
14652
  props = __rest(_a, ["children"]);
14589
- return /*#__PURE__*/React.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(IdCaptureModelsProviderInner, _assign({}, props), children)));
14653
+ return /*#__PURE__*/React.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React.createElement(BarcodeReadabilityModelProvider, _assign({}, props, {
14654
+ shouldLoadModels: props.enableBarcodeReadabilityModel
14655
+ }), /*#__PURE__*/React.createElement(IdCaptureModelsProviderInner, _assign({}, props), children))));
14590
14656
  }
14591
14657
  function useIdCaptureModelsContext() {
14592
14658
  var context = React.useContext(IdCaptureModelsContext);
@@ -14679,7 +14745,7 @@
14679
14745
  });
14680
14746
  }
14681
14747
 
14682
- var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
14748
+ var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage', 'idBarcodeImage'];
14683
14749
 
14684
14750
  var acceptedDocumentTypesForIdCaptureRequirementOption = {
14685
14751
  idCardFront: ['idCardFront'],
@@ -15045,6 +15111,7 @@
15045
15111
  capturing: false,
15046
15112
  captureFailed: false,
15047
15113
  imageUrl: null,
15114
+ idBarcodeImage: null,
15048
15115
  captureState: 'initializing',
15049
15116
  capturedDocuments: {},
15050
15117
  captureRequirement: 'idCardOrPassport',
@@ -15324,6 +15391,17 @@
15324
15391
  }
15325
15392
  return newState;
15326
15393
  }
15394
+ case 'barcodeCaptured':
15395
+ return _reducer(state, {
15396
+ type: 'documentCaptured',
15397
+ payload: {
15398
+ imageData: action.payload.imageUrl,
15399
+ documentType: 'idBarcodeImage',
15400
+ width: 0,
15401
+ height: 0,
15402
+ barcodeReadabilityScore: action.payload.barcodeReadabilityScore
15403
+ }
15404
+ });
15327
15405
  case 'flipRequestCompleted':
15328
15406
  return _assign(_assign({}, state), {
15329
15407
  captureState: 'capturing',
@@ -15815,12 +15893,13 @@
15815
15893
  height = _q === void 0 ? 1 : _q;
15816
15894
  var state = useIdCaptureStore();
15817
15895
  var isRearFacing = useCameraStore().isRearFacing;
15818
- var _r = React.useContext(IdCaptureModelsContext),
15896
+ var _r = useIdCaptureModelsContext(),
15819
15897
  modelsReady = _r.ready,
15820
15898
  setThresholds = _r.setThresholds,
15821
15899
  detectionTime = _r.detectionTime,
15822
15900
  focusPredictionTime = _r.focusPredictionTime,
15823
- getBestFrame = _r.getBestFrame;
15901
+ getBestFrame = _r.getBestFrame,
15902
+ getBestBarcode = _r.getBestBarcode;
15824
15903
  React.useEffect(function () {
15825
15904
  return dispatchIdCaptureAction({
15826
15905
  type: 'captureInitialized'
@@ -15859,6 +15938,16 @@
15859
15938
  });
15860
15939
  return;
15861
15940
  }
15941
+ var bestBarcode = getBestBarcode();
15942
+ if (bestBarcode) {
15943
+ dispatchIdCaptureAction({
15944
+ type: 'barcodeCaptured',
15945
+ payload: {
15946
+ imageUrl: bestBarcode.canvas.toDataURL('image/jpeg', 0.95),
15947
+ barcodeReadabilityScore: bestBarcode.score
15948
+ }
15949
+ });
15950
+ }
15862
15951
  var canvas = bestFrame.canvas,
15863
15952
  documentType = bestFrame.documentType,
15864
15953
  boundingBox = bestFrame.boundingBox,
@@ -15875,21 +15964,22 @@
15875
15964
  });
15876
15965
  var capturedDocumentType = documentType;
15877
15966
  setTimeout(function () {
15878
- var _a;
15879
- var captureTime = new Date().getTime() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
15967
+ var _a, _b;
15968
+ var captureTime = performance.now() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
15880
15969
  var metadata = {
15881
15970
  autoCapture: 'Y',
15882
15971
  captureTime: captureTime,
15883
15972
  boundingBox: boundingBox,
15884
15973
  bestDetectionScore: detectionScore,
15885
- bestFocusScore: focusScore
15974
+ bestFocusScore: focusScore,
15975
+ bestBarcodeScore: (_b = bestBarcode === null || bestBarcode === void 0 ? void 0 : bestBarcode.score) !== null && _b !== void 0 ? _b : 0
15886
15976
  };
15887
15977
  onCapture === null || onCapture === void 0 ? void 0 : onCapture(imageUrl, width, height, capturedDocumentType, metadata);
15888
15978
  dispatchIdCaptureAction({
15889
15979
  type: 'captured'
15890
15980
  });
15891
15981
  }, 0);
15892
- }, [getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
15982
+ }, [getBestBarcode, getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
15893
15983
  var theme = styled.useTheme();
15894
15984
  colors.guideBoxUnsatisfiedColor || (colors.guideBoxUnsatisfiedColor = (_d = (_c = (_b = theme.idCapture) === null || _b === void 0 ? void 0 : _b.guideBox) === null || _c === void 0 ? void 0 : _c.unsatisfiedColor) !== null && _d !== void 0 ? _d : 'white');
15895
15985
  colors.guideBoxSatisfiedColor || (colors.guideBoxSatisfiedColor = (_g = (_f = (_e = theme.idCapture) === null || _e === void 0 ? void 0 : _e.guideBox) === null || _f === void 0 ? void 0 : _f.satisfiedColor) !== null && _g !== void 0 ? _g : 'green');
@@ -17042,7 +17132,7 @@
17042
17132
  var FlexCard = styled(Card)(templateObject_2$y || (templateObject_2$y = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n"], ["\n display: flex;\n flex-direction: column;\n"])));
17043
17133
  var templateObject_1$E, templateObject_2$y;
17044
17134
 
17045
- var imageDisplayOrder = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
17135
+ var imageDisplayOrder = ['idCardFront', 'idCardBack', 'idBarcodeImage', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
17046
17136
  var IdCaptureSuccess = function IdCaptureSuccess(_a) {
17047
17137
  var capturedDocuments = _a.capturedDocuments,
17048
17138
  onSubmitClick = _a.onSubmitClick,
@@ -17084,7 +17174,7 @@
17084
17174
  image: doc,
17085
17175
  className: classNames.image,
17086
17176
  alt: doc.documentType
17087
- }), debugMode && ( /*#__PURE__*/React.createElement(DebugPre, null, "Document Type: ".concat(doc.documentType, "\nDetection Score: ").concat(doc.detectionScore, "\nFocus Score: ").concat(doc.focusScore, "\nBounding Box: ").concat(JSON.stringify(doc.boundingBox)))));
17177
+ }), debugMode && ( /*#__PURE__*/React.createElement(DebugPre, null, name === 'idBarcodeImage' ? "Document Type: ".concat(doc.documentType, "\nReadability Score: ").concat(doc.barcodeReadabilityScore) : "Document Type: ".concat(doc.documentType, "\nDetection Score: ").concat(doc.detectionScore, "\nFocus Score: ").concat(doc.focusScore, "\nBounding Box: ").concat(JSON.stringify(doc.boundingBox)))));
17088
17178
  }))), /*#__PURE__*/React.createElement(ButtonsColumn, {
17089
17179
  className: classNames.buttonsRow
17090
17180
  }, /*#__PURE__*/React.createElement(WideButton, {
@@ -19696,7 +19786,7 @@
19696
19786
  var _5 = React.useState(false),
19697
19787
  overlayDismissed = _5[0],
19698
19788
  setOverlayDismissed = _5[1];
19699
- var _6 = React.useContext(SubmissionContext),
19789
+ var _6 = useSubmissionContext(),
19700
19790
  submissionStatus = _6.submissionStatus,
19701
19791
  setIdFrontImage = _6.setIdFrontImage,
19702
19792
  setIdBackImage = _6.setIdBackImage,
@@ -19705,6 +19795,7 @@
19705
19795
  setIdBackIrImage = _6.setIdBackIrImage,
19706
19796
  setIdFrontUvImage = _6.setIdFrontUvImage,
19707
19797
  setIdBackUvImage = _6.setIdBackUvImage,
19798
+ setIdBarcodeImage = _6.setIdBarcodeImage,
19708
19799
  logIdFrontCaptureAttempt = _6.logIdFrontCaptureAttempt,
19709
19800
  logIdBackCaptureAttempt = _6.logIdBackCaptureAttempt;
19710
19801
  var _7 = useIdCaptureModelsContext(),
@@ -19795,7 +19886,7 @@
19795
19886
  });
19796
19887
  }, [logCaptureMetadata, onDocumentCaptured]);
19797
19888
  var onSubmitClick = React.useCallback(function () {
19798
- var _a, _b, _c, _d, _e, _f, _g, _h;
19889
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
19799
19890
  var docs = state.capturedDocuments;
19800
19891
  var submission = {
19801
19892
  idFrontImage: maybeDataUrlToBase64Sync((_a = docs.idCardFront) === null || _a === void 0 ? void 0 : _a.imageData),
@@ -19805,7 +19896,8 @@
19805
19896
  idFrontIrImage: maybeDataUrlToBase64Sync((_e = docs.idFrontIrImage) === null || _e === void 0 ? void 0 : _e.imageData),
19806
19897
  idBackIrImage: maybeDataUrlToBase64Sync((_f = docs.idBackIrImage) === null || _f === void 0 ? void 0 : _f.imageData),
19807
19898
  idFrontUvImage: maybeDataUrlToBase64Sync((_g = docs.idFrontUvImage) === null || _g === void 0 ? void 0 : _g.imageData),
19808
- idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData)
19899
+ idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData),
19900
+ idBarcodeImage: maybeDataUrlToBase64Sync((_j = docs.idBarcodeImage) === null || _j === void 0 ? void 0 : _j.imageData)
19809
19901
  };
19810
19902
  if (submission.idFrontImage) setIdFrontImage(submission.idFrontImage);
19811
19903
  if (submission.idBackImage) setIdBackImage(submission.idBackImage);
@@ -19815,11 +19907,12 @@
19815
19907
  if (submission.idBackIrImage) setIdBackIrImage(submission.idBackIrImage);
19816
19908
  if (submission.idFrontUvImage) setIdFrontUvImage(submission.idFrontUvImage);
19817
19909
  if (submission.idBackUvImage) setIdBackUvImage(submission.idBackUvImage);
19910
+ if (submission.idBarcodeImage) setIdBarcodeImage(submission.idBarcodeImage);
19818
19911
  if (releaseCameraAccessOnExit) releaseCameraAccess();
19819
19912
  setTimeout(function () {
19820
19913
  return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(submission);
19821
19914
  }, 0);
19822
- }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
19915
+ }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBarcodeImage, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
19823
19916
  var showSuccessScreen = useShowSuccessScreen(skipSuccessScreen, state.captureState === 'complete', onSubmitClick);
19824
19917
  var onRetryClick = React.useCallback(function () {
19825
19918
  return dispatchIdCaptureAction({
@@ -20663,6 +20756,274 @@
20663
20756
  };
20664
20757
  var templateObject_1$o, templateObject_2$l;
20665
20758
 
20759
+ var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
20760
+ var detector = null;
20761
+ var detectorSettings = null;
20762
+ function loadFaceDetector() {
20763
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
20764
+ var _a, _b;
20765
+ if (modelAssetPath === void 0) {
20766
+ modelAssetPath = defaultFaceDetectorModelPath;
20767
+ }
20768
+ return __generator(this, function (_c) {
20769
+ switch (_c.label) {
20770
+ case 0:
20771
+ if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector];
20772
+ closeFaceDetector();
20773
+ return [4 /*yield*/, preloadFaceDetectorDependencies()];
20774
+ case 1:
20775
+ _c.sent();
20776
+ if (modelCapabilities.delegate === 'NONE') {
20777
+ throw new Error('No available delegate for face detector.');
20778
+ }
20779
+ _b = (_a = ya).createFromOptions;
20780
+ return [4 /*yield*/, ao.forVisionTasks(visionTasksBasePath)];
20781
+ case 2:
20782
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
20783
+ // canvas: document.createElement('canvas'),
20784
+ baseOptions: {
20785
+ modelAssetPath: modelAssetPath,
20786
+ delegate: modelCapabilities.delegate
20787
+ },
20788
+ runningMode: 'VIDEO'
20789
+ }])];
20790
+ case 3:
20791
+ detector = _c.sent();
20792
+ detectorSettings = {
20793
+ modelAssetPath: modelAssetPath
20794
+ };
20795
+ return [2 /*return*/, detector];
20796
+ }
20797
+ });
20798
+ });
20799
+ }
20800
+ function closeFaceDetector() {
20801
+ detector === null || detector === void 0 ? void 0 : detector.close();
20802
+ detector = null;
20803
+ detectorSettings = null;
20804
+ }
20805
+ function useLoadFaceDetector(_a) {
20806
+ var onModelError = _a.onModelError,
20807
+ _b = _a.modelLoadTimeoutMs,
20808
+ modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
20809
+ videoRef = _a.videoRef;
20810
+ var _c = React.useState('not-started'),
20811
+ modelLoadState = _c[0],
20812
+ setModelLoadState = _c[1];
20813
+ var _d = React.useState(0),
20814
+ modelDownloadProgress = _d[0],
20815
+ setModelDownloadProgress = _d[1];
20816
+ var _e = React.useState(null),
20817
+ modelWarmingStartedAt = _e[0],
20818
+ setModelWarmingStartedAt = _e[1];
20819
+ var _f = React.useState(null),
20820
+ modelError = _f[0],
20821
+ setModelError = _f[1];
20822
+ React.useEffect(function loadModel() {
20823
+ var _this = this;
20824
+ setModelLoadState('downloading');
20825
+ setModelWarmingStartedAt(null);
20826
+ var modelLoadTimeout = setTimeout(function () {
20827
+ setModelError(new Error('Model loading time limit exceeded.'));
20828
+ }, modelLoadTimeoutMs);
20829
+ function handleDownloadProgress(event) {
20830
+ setModelDownloadProgress(progressToPercentage(event.detail));
20831
+ }
20832
+ document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
20833
+ var cancelVideoReady = function cancelVideoReady() {};
20834
+ loadFaceDetector().then(function (model) {
20835
+ return __awaiter(_this, void 0, void 0, function () {
20836
+ var _a, videoReady, cancel, cancelled;
20837
+ return __generator(this, function (_b) {
20838
+ switch (_b.label) {
20839
+ case 0:
20840
+ setModelDownloadProgress(100);
20841
+ clearTimeout(modelLoadTimeout);
20842
+ setModelLoadState('warming');
20843
+ setModelWarmingStartedAt(performance.now());
20844
+ return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
20845
+ case 1:
20846
+ _b.sent();
20847
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
20848
+ cancelled = false;
20849
+ cancelVideoReady = function cancelVideoReady() {
20850
+ cancelled = true;
20851
+ cancel();
20852
+ };
20853
+ return [4 /*yield*/, videoReady];
20854
+ case 2:
20855
+ _b.sent();
20856
+ if (cancelled) return [2 /*return*/];
20857
+ model.detectForVideo(videoRef.current, performance.now());
20858
+ setModelLoadState('ready');
20859
+ return [2 /*return*/];
20860
+ }
20861
+ });
20862
+ });
20863
+ })["catch"](function (e) {
20864
+ setModelError(e);
20865
+ setModelLoadState('error');
20866
+ })["finally"](function () {
20867
+ clearTimeout(modelLoadTimeout);
20868
+ });
20869
+ return function () {
20870
+ log('unloading face detection model');
20871
+ cancelVideoReady();
20872
+ closeFaceDetector();
20873
+ clearTimeout(modelLoadTimeout);
20874
+ document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
20875
+ };
20876
+ }, [modelLoadTimeoutMs, videoRef]);
20877
+ React.useEffect(function handleModelError() {
20878
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
20879
+ }, [modelError, onModelError]);
20880
+ return React.useMemo(function () {
20881
+ return {
20882
+ ready: modelLoadState === 'ready',
20883
+ modelLoadState: modelLoadState,
20884
+ modelDownloadProgress: modelDownloadProgress,
20885
+ modelWarmingStartedAt: modelWarmingStartedAt,
20886
+ modelError: modelError
20887
+ };
20888
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
20889
+ }
20890
+ var lastFaceDetectionAt = 0;
20891
+ var lastFaceDetectionTime = 0;
20892
+ function setLastFaceDetectionAt(time) {
20893
+ lastFaceDetectionTime = time - lastFaceDetectionAt;
20894
+ lastFaceDetectionAt = time;
20895
+ }
20896
+ var framesNeededSamples = [];
20897
+ function trackFramesNeeded(value, bufferLength) {
20898
+ if (bufferLength === void 0) {
20899
+ bufferLength = 25;
20900
+ }
20901
+ framesNeededSamples.unshift(value);
20902
+ if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
20903
+ }
20904
+ var lastNFaces = [];
20905
+ var lastNPairs = [];
20906
+ function trackFace(face, framesNeeded) {
20907
+ if (framesNeeded === void 0) {
20908
+ framesNeeded = 12;
20909
+ }
20910
+ lastNFaces.unshift(face);
20911
+ if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
20912
+ if (lastNFaces.length > 1) {
20913
+ var lastFace = lastNFaces[1];
20914
+ var iou = calculateIoU(face.box, lastFace.box);
20915
+ lastNPairs.unshift({
20916
+ a: face,
20917
+ b: lastFace,
20918
+ iou: iou
20919
+ });
20920
+ if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
20921
+ }
20922
+ }
20923
+ function makeFaceDetectorPrediction(imageData) {
20924
+ if (!detector) return null;
20925
+ var prediction = detector.detectForVideo(imageData, performance.now());
20926
+ var faces = prediction.detections.map(function (d) {
20927
+ return {
20928
+ box: convertBoundingBox(d.boundingBox),
20929
+ keypoints: d.keypoints.map(function (k) {
20930
+ var _a;
20931
+ return _assign(_assign({}, k), {
20932
+ x: k.x * imageData.width,
20933
+ y: k.y * imageData.height,
20934
+ name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
20935
+ });
20936
+ })
20937
+ };
20938
+ });
20939
+ return _assign(_assign({}, prediction), {
20940
+ faces: faces
20941
+ });
20942
+ }
20943
+ function processFaceDetectorPrediction(_a) {
20944
+ var faces = _a.faces,
20945
+ videoWidth = _a.videoWidth,
20946
+ videoHeight = _a.videoHeight,
20947
+ _b = _a.requireVerticalFaceCentering,
20948
+ requireVerticalFaceCentering = _b === void 0 ? true : _b,
20949
+ _c = _a.stabilityThreshold,
20950
+ stabilityThreshold = _c === void 0 ? 0.7 : _c;
20951
+ var face = faces[0];
20952
+ var faceNotDetected = faces.length === 0;
20953
+ var faceNotCentered = false,
20954
+ faceLookingAway = false,
20955
+ faceTooClose = false,
20956
+ faceTooFar = false;
20957
+ if (face) {
20958
+ // calculate centroids
20959
+ var vCX = videoWidth / 2;
20960
+ var vCY = videoHeight / 2;
20961
+ var fCX = (face.box.xMin + face.box.xMax) / 2;
20962
+ var fCY = (face.box.yMin + face.box.yMax) / 2;
20963
+ // calculate thresholds
20964
+ var vTX = videoWidth * 0.125;
20965
+ var vTY = videoHeight * 0.125;
20966
+ var fTW = face.box.width * 0.2;
20967
+ var fTH = face.box.height * 0.2;
20968
+ var nose = face.keypoints[2]; //.find((k) => k.name === 'noseTip')
20969
+ if (nose) {
20970
+ faceLookingAway = Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH;
20971
+ var faceNotCenteredHorizontally = Math.abs(vCX - fCX) > vTX;
20972
+ var faceNotCenteredVertically = Math.abs(vCY + 50 - fCY) > vTY;
20973
+ faceNotCentered = faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
20974
+ }
20975
+ var isMobile = videoWidth < videoHeight;
20976
+ var tooCloseMultiple = 1.5;
20977
+ var tooFarMultiple = isMobile ? 6 : 7;
20978
+ faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
20979
+ faceTooFar = face.box.width < videoWidth / tooFarMultiple;
20980
+ }
20981
+ var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
20982
+ if (lastFaceDetectionTime > 0) {
20983
+ trackFramesNeeded(500 / lastFaceDetectionTime);
20984
+ }
20985
+ var faceIsStable = false;
20986
+ if (faceInGuides) {
20987
+ var framesNeeded = Math.ceil(average(framesNeededSamples));
20988
+ trackFace(face, framesNeeded);
20989
+ faceIsStable = lastNFaces.length >= framesNeeded && !lastNPairs.some(function (pair) {
20990
+ return pair.iou < stabilityThreshold;
20991
+ });
20992
+ }
20993
+ var faceReady = faceInGuides && faceIsStable;
20994
+ return {
20995
+ face: face,
20996
+ faceNotDetected: faceNotDetected,
20997
+ faceNotCentered: faceNotCentered,
20998
+ faceLookingAway: faceLookingAway,
20999
+ faceTooClose: faceTooClose,
21000
+ faceTooFar: faceTooFar,
21001
+ faceReady: faceReady,
21002
+ faceReadyAt: faceReady ? new Date() : null,
21003
+ faceIsStable: faceIsStable
21004
+ };
21005
+ }
21006
+ function testFaceDetectionAgainstKnownImage(detector) {
21007
+ return new Promise(function (resolve, reject) {
21008
+ var img = new Image();
21009
+ img.crossOrigin = 'anonymous';
21010
+ img.onload = function () {
21011
+ var prediction = detector.detectForVideo(img, performance.now());
21012
+ if (prediction.detections.length > 0) {
21013
+ debug('face detection test result', prediction.detections);
21014
+ resolve(void 0);
21015
+ } else {
21016
+ warn('face detection test failed');
21017
+ reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
21018
+ }
21019
+ };
21020
+ img.onerror = function () {
21021
+ return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
21022
+ };
21023
+ img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
21024
+ });
21025
+ }
21026
+
20666
21027
  var SelfieGuidanceModelsContext = /*#__PURE__*/React.createContext({
20667
21028
  start: function start() {
20668
21029
  return null;