idmission-web-sdk 2.3.67 → 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 (45) 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/models/BarcodeReadability.d.ts +50 -0
  22. package/dist/lib/models/BarcodeReadability.d.ts.map +1 -0
  23. package/dist/lib/models/DocumentDetection.d.ts +1 -0
  24. package/dist/lib/models/DocumentDetection.d.ts.map +1 -1
  25. package/dist/lib/models/Focus.d.ts.map +1 -1
  26. package/dist/lib/models/defaults/BarcodeReadability.d.ts +2 -0
  27. package/dist/lib/models/defaults/BarcodeReadability.d.ts.map +1 -0
  28. package/dist/lib/models/defaults/index.d.ts +7 -0
  29. package/dist/lib/models/defaults/index.d.ts.map +1 -1
  30. package/dist/lib/models/preloadModels.d.ts +9 -5
  31. package/dist/lib/models/preloadModels.d.ts.map +1 -1
  32. package/dist/lib/utils/cropping.d.ts +3 -1
  33. package/dist/lib/utils/cropping.d.ts.map +1 -1
  34. package/dist/sdk2.cjs.development.js +1955 -1602
  35. package/dist/sdk2.cjs.development.js.map +1 -1
  36. package/dist/sdk2.cjs.production.js +1 -1
  37. package/dist/sdk2.cjs.production.js.map +1 -1
  38. package/dist/sdk2.esm.js +1956 -1603
  39. package/dist/sdk2.esm.js.map +1 -1
  40. package/dist/sdk2.umd.development.js +1608 -1255
  41. package/dist/sdk2.umd.development.js.map +1 -1
  42. package/dist/sdk2.umd.production.js +1 -1
  43. package/dist/sdk2.umd.production.js.map +1 -1
  44. package/dist/version.d.ts +1 -1
  45. package/package.json +1 -1
@@ -236,7 +236,7 @@ typeof SuppressedError === "function" ? SuppressedError : function (error, suppr
236
236
  return e.name = "SuppressedError", e.error = error, e.suppressed = suppressed, e;
237
237
  };
238
238
 
239
- var webSdkVersion = '2.3.67';
239
+ var webSdkVersion = '2.3.68';
240
240
 
241
241
  function getPlatform() {
242
242
  // eslint-disable-next-line @typescript-eslint/ban-ts-comment
@@ -497,27 +497,27 @@ var GuidanceMessageContainer = function GuidanceMessageContainer(props) {
497
497
  if (!portalLocation) return element;
498
498
  return /*#__PURE__*/reactDom.createPortal(element, portalLocation);
499
499
  };
500
- var GuidanceMessage = styled__default.default.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) {
500
+ var GuidanceMessage = styled__default.default.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) {
501
501
  var _a, _b, _c, _d, _e, _f;
502
502
  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';
503
503
  }, function (props) {
504
504
  var _a, _b, _c, _d, _e, _f;
505
505
  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';
506
506
  });
507
- var templateObject_1$Q, templateObject_2$I;
507
+ var templateObject_1$Q, templateObject_2$J;
508
508
 
509
509
  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"])));
510
- 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"])));
510
+ 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"])));
511
511
  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"])));
512
512
  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"])));
513
- var templateObject_1$P, templateObject_2$H, templateObject_3$u, templateObject_4$n;
513
+ var templateObject_1$P, templateObject_2$I, templateObject_3$u, templateObject_4$n;
514
514
 
515
515
  var OverlayContainer = styled__default.default.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) {
516
516
  return props.theme.background ? "".concat(props.theme.background) : "white";
517
517
  }, function (props) {
518
518
  return props.theme.textColor ? "color: ".concat(props.theme.textColor, ";") : "";
519
519
  });
520
- var OverlayInner$2 = styled__default.default.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) {
520
+ var OverlayInner$2 = styled__default.default.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) {
521
521
  var _a;
522
522
  return (_a = props.theme.textAlign) !== null && _a !== void 0 ? _a : 'center';
523
523
  }, function (props) {
@@ -565,7 +565,7 @@ var LoadingOverlayLoadingListItem = styled__default.default.li(templateObject_19
565
565
  var LoadingOverlayProgressContainer = styled__default.default.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"])));
566
566
  var LoadingOverlayCustomLoadingGraphic = styled__default.default.img(templateObject_21 || (templateObject_21 = __makeTemplateObject(["\n transform-style: preserve-3d;\n"], ["\n transform-style: preserve-3d;\n"])));
567
567
  var LoadingOverlayContinueButtonContainer = styled__default.default.div(templateObject_22 || (templateObject_22 = __makeTemplateObject(["\n display: flex;\n"], ["\n display: flex;\n"])));
568
- 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;
568
+ 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;
569
569
 
570
570
  var GeolocationAccessDeniedOverlay = function GeolocationAccessDeniedOverlay(_a) {
571
571
  var accessBlockedImageUrl = _a.accessBlockedImageUrl;
@@ -1134,6 +1134,11 @@ var SubmissionContext = /*#__PURE__*/React.createContext({
1134
1134
  idFrontImage: null,
1135
1135
  idBackImage: null,
1136
1136
  passportImage: null,
1137
+ idFrontIrImage: null,
1138
+ idBackIrImage: null,
1139
+ idFrontUvImage: null,
1140
+ idBackUvImage: null,
1141
+ idBarcodeImage: null,
1137
1142
  selfieImage: null,
1138
1143
  signatureData: null,
1139
1144
  signatureVideoUrl: null,
@@ -1164,6 +1169,9 @@ var SubmissionContext = /*#__PURE__*/React.createContext({
1164
1169
  setIdBackUvImage: function setIdBackUvImage() {
1165
1170
  return null;
1166
1171
  },
1172
+ setIdBarcodeImage: function setIdBarcodeImage() {
1173
+ return null;
1174
+ },
1167
1175
  setSelfieImage: function setSelfieImage() {
1168
1176
  return null;
1169
1177
  },
@@ -1331,53 +1339,56 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1331
1339
  passportImage = _13[0],
1332
1340
  setPassportImage = _13[1];
1333
1341
  var _14 = React.useState(null),
1334
- selfieImage = _14[0],
1335
- setSelfieImage = _14[1];
1342
+ idBarcodeImage = _14[0],
1343
+ setIdBarcodeImage = _14[1];
1336
1344
  var _15 = React.useState(null),
1337
- signatureData = _15[0],
1338
- setSignatureData = _15[1];
1345
+ selfieImage = _15[0],
1346
+ setSelfieImage = _15[1];
1339
1347
  var _16 = React.useState(null),
1340
- signatureVideoUrl = _16[0],
1341
- setSignatureVideoUrl = _16[1];
1348
+ signatureData = _16[0],
1349
+ setSignatureData = _16[1];
1342
1350
  var _17 = React.useState(null),
1343
- idCaptureVideoUrl = _17[0],
1344
- setIdCaptureVideoUrl = _17[1];
1351
+ signatureVideoUrl = _17[0],
1352
+ setSignatureVideoUrl = _17[1];
1345
1353
  var _18 = React.useState(null),
1346
- idCaptureVideoIdFrontImage = _18[0],
1347
- setIdCaptureVideoIdFrontImage = _18[1];
1354
+ idCaptureVideoUrl = _18[0],
1355
+ setIdCaptureVideoUrl = _18[1];
1348
1356
  var _19 = React.useState(null),
1349
- idCaptureVideoIdBackImage = _19[0],
1350
- setIdCaptureVideoIdBackImage = _19[1];
1357
+ idCaptureVideoIdFrontImage = _19[0],
1358
+ setIdCaptureVideoIdFrontImage = _19[1];
1351
1359
  var _20 = React.useState(null),
1352
- idCaptureVideoAudioUrl = _20[0],
1353
- setIdCaptureVideoAudioUrl = _20[1];
1360
+ idCaptureVideoIdBackImage = _20[0],
1361
+ setIdCaptureVideoIdBackImage = _20[1];
1354
1362
  var _21 = React.useState(null),
1355
- idCaptureVideoAudioStartsAt = _21[0],
1356
- setIdCaptureVideoAudioStartsAt = _21[1];
1363
+ idCaptureVideoAudioUrl = _21[0],
1364
+ setIdCaptureVideoAudioUrl = _21[1];
1357
1365
  var _22 = React.useState(null),
1358
- expectedAudioText = _22[0],
1359
- setExpectedAudioText = _22[1];
1366
+ idCaptureVideoAudioStartsAt = _22[0],
1367
+ setIdCaptureVideoAudioStartsAt = _22[1];
1360
1368
  var _23 = React.useState(null),
1361
- additionalDocuments = _23[0],
1362
- setAdditionalDocuments = _23[1];
1369
+ expectedAudioText = _23[0],
1370
+ setExpectedAudioText = _23[1];
1363
1371
  var _24 = React.useState(null),
1364
- geolocationResult = _24[0],
1365
- setGeolocationResult = _24[1];
1366
- var _25 = React.useState(0),
1367
- geolocationAttempts = _25[0],
1368
- setGeolocationAttempts = _25[1];
1369
- var _26 = React.useState(false),
1370
- geolocationBlocked = _26[0],
1371
- setGeolocationBlocked = _26[1];
1372
- var _27 = React.useState([]),
1373
- idFrontCaptureAttempts = _27[0],
1374
- setIdFrontCaptureAttempts = _27[1];
1372
+ additionalDocuments = _24[0],
1373
+ setAdditionalDocuments = _24[1];
1374
+ var _25 = React.useState(null),
1375
+ geolocationResult = _25[0],
1376
+ setGeolocationResult = _25[1];
1377
+ var _26 = React.useState(0),
1378
+ geolocationAttempts = _26[0],
1379
+ setGeolocationAttempts = _26[1];
1380
+ var _27 = React.useState(false),
1381
+ geolocationBlocked = _27[0],
1382
+ setGeolocationBlocked = _27[1];
1375
1383
  var _28 = React.useState([]),
1376
- idBackCaptureAttempts = _28[0],
1377
- setIdBackCaptureAttempts = _28[1];
1384
+ idFrontCaptureAttempts = _28[0],
1385
+ setIdFrontCaptureAttempts = _28[1];
1378
1386
  var _29 = React.useState([]),
1379
- selfieCaptureAttempts = _29[0],
1380
- setSelfieCaptureAttempts = _29[1];
1387
+ idBackCaptureAttempts = _29[0],
1388
+ setIdBackCaptureAttempts = _29[1];
1389
+ var _30 = React.useState([]),
1390
+ selfieCaptureAttempts = _30[0],
1391
+ setSelfieCaptureAttempts = _30[1];
1381
1392
  var logIdFrontCaptureAttempt = React.useCallback(function (attempt) {
1382
1393
  setIdFrontCaptureAttempts(function (attempts) {
1383
1394
  return __spreadArray(__spreadArray([], attempts, true), [attempt], false);
@@ -1503,6 +1514,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1503
1514
  idFrontImage: idFrontImage,
1504
1515
  idBackImage: idBackImage,
1505
1516
  passportImage: passportImage,
1517
+ idBarcodeImage: idBarcodeImage,
1506
1518
  selfieImage: selfieImage
1507
1519
  };
1508
1520
  _a = signatureVideoUrl;
@@ -1608,6 +1620,9 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1608
1620
  if (documents.passportImage) {
1609
1621
  submissionRequest.customerData.idData.idImageFront = documents.passportImage;
1610
1622
  }
1623
+ if (documents.idBarcodeImage) {
1624
+ submissionRequest.customerData.idData.idBarcodeImage = documents.idBarcodeImage;
1625
+ }
1611
1626
  if (documents.idFrontIrImage) {
1612
1627
  submissionRequest.customerData.idData.idFrontIrImage = documents.idFrontIrImage;
1613
1628
  }
@@ -1696,7 +1711,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1696
1711
  }
1697
1712
  });
1698
1713
  });
1699
- }, [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]);
1714
+ }, [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]);
1700
1715
  var defaultOnSubmit = React.useCallback(function () {
1701
1716
  return __awaiter(void 0, void 0, void 0, function () {
1702
1717
  var submissionResponse_1, payload, host, endpoint, response, statusMessage, submissionResponse_2, e_1, err;
@@ -1974,6 +1989,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1974
1989
  idFrontUvImage: idFrontUvImage,
1975
1990
  idBackUvImage: idBackUvImage,
1976
1991
  passportImage: passportImage,
1992
+ idBarcodeImage: idBarcodeImage,
1977
1993
  selfieImage: selfieImage,
1978
1994
  signatureData: signatureData,
1979
1995
  signatureVideoUrl: signatureVideoUrl,
@@ -1990,6 +2006,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
1990
2006
  setIdBackIrImage: setIdBackIrImage,
1991
2007
  setIdFrontUvImage: setIdFrontUvImage,
1992
2008
  setIdBackUvImage: setIdBackUvImage,
2009
+ setIdBarcodeImage: setIdBarcodeImage,
1993
2010
  setSelfieImage: setSelfieImage,
1994
2011
  setSignatureData: setSignatureData,
1995
2012
  setSignatureVideoUrl: setSignatureVideoUrl,
@@ -2008,7 +2025,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
2008
2025
  checkLiveness: checkLiveness,
2009
2026
  retryLocationAccess: retryLocationAccess
2010
2027
  };
2011
- }, [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]);
2028
+ }, [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]);
2012
2029
  return /*#__PURE__*/React__namespace.default.createElement(SubmissionContext.Provider, {
2013
2030
  value: value
2014
2031
  }, geolocationRequired && geolocationBlocked ? ( /*#__PURE__*/React__namespace.default.createElement(GeolocationAccessDeniedOverlay, null)) : children, submissionError && ( /*#__PURE__*/React__namespace.default.createElement(SubmissionErrorOverlay, {
@@ -2202,97 +2219,6 @@ function preloadVisionRuntime() {
2202
2219
  });
2203
2220
  }
2204
2221
 
2205
- function getFrameDimensions(frame) {
2206
- var frameWidth = frame.width,
2207
- frameHeight = frame.height;
2208
- if (frame instanceof HTMLImageElement) {
2209
- frameWidth = frame.naturalWidth;
2210
- frameHeight = frame.naturalHeight;
2211
- }
2212
- if (frame instanceof HTMLVideoElement) {
2213
- frameWidth = frame.videoWidth;
2214
- frameHeight = frame.videoHeight;
2215
- }
2216
- return [frameWidth, frameHeight];
2217
- }
2218
-
2219
- var InvisibleCanvas = styled__default.default.canvas(templateObject_1$N || (templateObject_1$N = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
2220
- function drawToCanvas(canvas, frame, width, height) {
2221
- if (!canvas) return;
2222
- var ctx = canvas.getContext('2d');
2223
- if (!ctx) return;
2224
- if (!width || !height) {
2225
- var _a = getFrameDimensions(frame),
2226
- frameWidth = _a[0],
2227
- frameHeight = _a[1];
2228
- width || (width = frameWidth);
2229
- height || (height = frameHeight);
2230
- }
2231
- canvas.width = width;
2232
- canvas.height = height;
2233
- ctx.drawImage(frame, 0, 0, width, height);
2234
- }
2235
- function clearCanvas(canvas) {
2236
- var _a;
2237
- (_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);
2238
- }
2239
- var templateObject_1$N;
2240
-
2241
- function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
2242
- var _a;
2243
- if (quality === void 0) {
2244
- quality = 0.92;
2245
- }
2246
- if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
2247
- var rawCtx = rawCanvas.getContext('2d');
2248
- var cropCtx = cropCanvas.getContext('2d');
2249
- var resizeCtx = resizeCanvas.getContext('2d');
2250
- if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
2251
- rawCanvas.width = frame.width;
2252
- rawCanvas.height = frame.height;
2253
- rawCtx.putImageData(frame, 0, 0);
2254
- if (frame.height > frame.width) {
2255
- cropCanvas.width = frame.width;
2256
- cropCanvas.height = frame.height;
2257
- cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
2258
- } else {
2259
- var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
2260
- xMin: 0,
2261
- width: frame.width
2262
- },
2263
- xMin = _b.xMin,
2264
- width = _b.width;
2265
- var desiredWidth = frame.height * 0.6;
2266
- var faceCenterX = xMin + width / 2;
2267
- var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
2268
- cropCanvas.width = desiredWidth;
2269
- cropCanvas.height = frame.height;
2270
- cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
2271
- }
2272
- resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
2273
- resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
2274
- resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
2275
- var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
2276
- log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
2277
- clearCanvas(rawCanvas);
2278
- clearCanvas(cropCanvas);
2279
- clearCanvas(resizeCanvas);
2280
- return dataURL;
2281
- }
2282
- function cropToDetectedObjectBox(frame, box, canvas) {
2283
- canvas || (canvas = document.createElement('canvas'));
2284
- var ctx = canvas.getContext('2d');
2285
- if (!ctx) throw new Error('could not get 2d context');
2286
- var xMin = box.xMin,
2287
- yMin = box.yMin,
2288
- width = box.width,
2289
- height = box.height;
2290
- canvas.width = width;
2291
- canvas.height = height;
2292
- ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height);
2293
- return canvas;
2294
- }
2295
-
2296
2222
  var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
2297
2223
  var imageSegmenterModelSizeInBytes = 256440.32;
2298
2224
  // 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
@@ -2422,6 +2348,192 @@ function giveUpAfter(maxTime) {
2422
2348
  });
2423
2349
  }
2424
2350
 
2351
+ var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
2352
+
2353
+ var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
2354
+
2355
+ var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
2356
+
2357
+ var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/blazeface20240207/blaze_face_short_range.tflite");
2358
+
2359
+ var defaultBarcodeReadabilityModelPath = "".concat(DEFAULT_CDN_URL, "/models/BarcodeReadability/BarcodeReadability-20250815_120417.tflite");
2360
+
2361
+ var defaultModelPaths = {
2362
+ documentDetector: defaultDocumentDetectorModelPath,
2363
+ focus: defaultFocusModelPath,
2364
+ faceDetection: defaultFaceDetectorModelPath,
2365
+ barcodeReadability: defaultBarcodeReadabilityModelPath
2366
+ };
2367
+
2368
+ var preloadModels = function preloadModels(_a) {
2369
+ return __awaiter(void 0, [_a], void 0, function (_b) {
2370
+ var preloadTasks;
2371
+ var _c = _b.documentDetectionModel,
2372
+ documentDetectionModel = _c === void 0 ? true : _c,
2373
+ _d = _b.focusModel,
2374
+ focusModel = _d === void 0 ? true : _d,
2375
+ _e = _b.faceDetectionModel,
2376
+ faceDetectionModel = _e === void 0 ? true : _e,
2377
+ _f = _b.barcodeReadabilityModel,
2378
+ barcodeReadabilityModel = _f === void 0 ? true : _f;
2379
+ return __generator(this, function (_g) {
2380
+ switch (_g.label) {
2381
+ case 0:
2382
+ return [4 /*yield*/, probeModelCapabilities()];
2383
+ case 1:
2384
+ _g.sent();
2385
+ preloadTasks = [];
2386
+ if (documentDetectionModel) {
2387
+ preloadTasks.push(preloadDocumentDetectorDependencies);
2388
+ }
2389
+ if (focusModel) {
2390
+ preloadTasks.push(preloadFocusModelDependencies);
2391
+ }
2392
+ if (faceDetectionModel) {
2393
+ preloadTasks.push(preloadFaceDetectorDependencies);
2394
+ }
2395
+ if (barcodeReadabilityModel) {
2396
+ preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
2397
+ }
2398
+ return [4 /*yield*/, Promise.all(preloadTasks)];
2399
+ case 2:
2400
+ _g.sent();
2401
+ return [2 /*return*/];
2402
+ }
2403
+ });
2404
+ });
2405
+ };
2406
+ var progressByUrl = {};
2407
+ var progressByUseCase = {
2408
+ visionRuntime: {
2409
+ loaded: 0,
2410
+ total: 0
2411
+ },
2412
+ documentDetector: {
2413
+ loaded: 0,
2414
+ total: 0
2415
+ },
2416
+ focus: {
2417
+ loaded: 0,
2418
+ total: 0
2419
+ },
2420
+ faceDetection: {
2421
+ loaded: 0,
2422
+ total: 0
2423
+ },
2424
+ barcodeReadability: {
2425
+ loaded: 0,
2426
+ total: 0
2427
+ }
2428
+ };
2429
+ function preloadDependency(url) {
2430
+ return __awaiter(this, void 0, void 0, function () {
2431
+ return __generator(this, function (_a) {
2432
+ return [2 /*return*/, new Promise(function (resolve, reject) {
2433
+ var req = new XMLHttpRequest();
2434
+ req.addEventListener('progress', function (event) {
2435
+ if (!event.lengthComputable) return;
2436
+ progressByUrl[url] = event;
2437
+ document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
2438
+ detail: {
2439
+ url: url,
2440
+ loaded: event.loaded,
2441
+ total: event.total
2442
+ }
2443
+ }));
2444
+ });
2445
+ req.addEventListener('loadend', function () {
2446
+ resolve(req.readyState === 4 && req.status === 200);
2447
+ });
2448
+ req.addEventListener('error', reject);
2449
+ req.open('GET', url, true);
2450
+ req.send();
2451
+ })];
2452
+ });
2453
+ });
2454
+ }
2455
+ var modelsPreloading = {
2456
+ documentDetector: false,
2457
+ focus: false,
2458
+ faceDetection: false,
2459
+ barcodeReadability: false
2460
+ };
2461
+ var preloadDocumentDetectorDependencies = function preloadDocumentDetectorDependencies() {
2462
+ return preloadModelDependencies('documentDetector');
2463
+ };
2464
+ var preloadFocusModelDependencies = function preloadFocusModelDependencies() {
2465
+ return preloadModelDependencies('focus');
2466
+ };
2467
+ var preloadFaceDetectorDependencies = function preloadFaceDetectorDependencies() {
2468
+ return preloadModelDependencies('faceDetection');
2469
+ };
2470
+ var preloadBarcodeReadabilityModelDependencies = function preloadBarcodeReadabilityModelDependencies() {
2471
+ return preloadModelDependencies('barcodeReadability');
2472
+ };
2473
+ function preloadModelDependencies(model) {
2474
+ return __awaiter(this, void 0, void 0, function () {
2475
+ function handleModelDownloadProgress(event) {
2476
+ var detail = event.detail;
2477
+ if (!dependencies.includes(detail.url)) return;
2478
+ progressByUseCase[model] = sumUpProgressForDependencies(dependencies);
2479
+ document.dispatchEvent(new CustomEvent("idmission.preloadProgress.".concat(model), {
2480
+ detail: progressByUseCase[model]
2481
+ }));
2482
+ }
2483
+ var dependencies;
2484
+ return __generator(this, function (_a) {
2485
+ switch (_a.label) {
2486
+ case 0:
2487
+ if (modelsPreloading[model]) return [2 /*return*/, new Promise(function (resolve) {
2488
+ var i = setInterval(function () {
2489
+ if (!modelsPreloading[model]) {
2490
+ clearInterval(i);
2491
+ resolve();
2492
+ }
2493
+ }, 100);
2494
+ })];
2495
+ modelsPreloading[model] = true;
2496
+ return [4 /*yield*/, probeModelCapabilities()];
2497
+ case 1:
2498
+ _a.sent();
2499
+ if (modelCapabilities.delegate === 'NONE') {
2500
+ throw new Error("No available delegate for ".concat(model, " model."));
2501
+ }
2502
+ dependencies = [defaultModelPaths[model]];
2503
+ document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
2504
+ _a.label = 2;
2505
+ case 2:
2506
+ _a.trys.push([2,, 4, 5]);
2507
+ return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
2508
+ case 3:
2509
+ _a.sent();
2510
+ return [3 /*break*/, 5];
2511
+ case 4:
2512
+ document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
2513
+ modelsPreloading[model] = false;
2514
+ return [7 /*endfinally*/];
2515
+ case 5:
2516
+ return [2 /*return*/];
2517
+ }
2518
+ });
2519
+ });
2520
+ }
2521
+ function progressToPercentage(progress) {
2522
+ return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
2523
+ }
2524
+ function sumUpProgressForDependencies(dependencies) {
2525
+ return dependencies.reduce(function (result, dependency) {
2526
+ var dependencyProgress = progressByUrl[dependency];
2527
+ if (!dependencyProgress) return result;
2528
+ result.loaded += dependencyProgress.loaded;
2529
+ result.total += dependencyProgress.total;
2530
+ return result;
2531
+ }, {
2532
+ loaded: 0,
2533
+ total: 0
2534
+ });
2535
+ }
2536
+
2425
2537
  function convertBoundingBox(box) {
2426
2538
  var _a, _b, _c, _d, _e, _f, _g, _h;
2427
2539
  return {
@@ -2476,53 +2588,50 @@ function average(arr) {
2476
2588
  return sum / len;
2477
2589
  }
2478
2590
 
2479
- var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
2480
-
2481
- var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
2482
-
2483
- var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
2484
-
2485
- var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/blazeface20240207/blaze_face_short_range.tflite");
2486
-
2487
- var defaultFocusModelLoadTimeoutMs = 45000;
2488
- var defaultFocusThresholds = {
2489
- idCardFront: {
2490
- desktop: 0,
2491
- mobile: 0.3
2492
- },
2493
- idCardBack: {
2494
- desktop: 0,
2495
- mobile: 0.3
2496
- },
2497
- passport: {
2498
- desktop: 0,
2499
- mobile: 0.3
2500
- },
2501
- singlePage: {
2502
- desktop: 0,
2503
- mobile: 0.3
2591
+ var defaultDocumentDetectionScoreThreshold = 0.1;
2592
+ var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
2593
+ var defaultDocumentDetectionThresholds = {
2594
+ idCardFront: 0.6,
2595
+ idCardBack: 0.6,
2596
+ passport: 0.4,
2597
+ singlePage: 0.4,
2598
+ stability: {
2599
+ idCardFront: 0.85,
2600
+ idCardBack: 0.85,
2601
+ passport: 0.5,
2602
+ singlePage: 0.5
2504
2603
  }
2505
2604
  };
2506
- var classifier = null;
2507
- var classifierSettings = null;
2508
- function loadFocusModel() {
2509
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
2605
+ var documentTypeDisplayNames = {
2606
+ idCardFront: 'ID card front',
2607
+ idCardBack: 'ID card back',
2608
+ passport: 'Passport',
2609
+ singlePage: 'Single page',
2610
+ none: 'None'
2611
+ };
2612
+ var detector$1 = null;
2613
+ var detectorSettings$1 = null;
2614
+ function loadDocumentDetector() {
2615
+ return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
2510
2616
  var _a, _b;
2511
2617
  if (modelAssetPath === void 0) {
2512
- modelAssetPath = defaultFocusModelPath;
2618
+ modelAssetPath = defaultDocumentDetectorModelPath;
2619
+ }
2620
+ if (scoreThreshold === void 0) {
2621
+ scoreThreshold = defaultDocumentDetectionScoreThreshold;
2513
2622
  }
2514
2623
  return __generator(this, function (_c) {
2515
2624
  switch (_c.label) {
2516
2625
  case 0:
2517
- if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
2518
- closeFocusModel();
2519
- return [4 /*yield*/, preloadFocusModelDependencies()];
2626
+ 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];
2627
+ closeDocumentDetector();
2628
+ return [4 /*yield*/, preloadDocumentDetectorDependencies()];
2520
2629
  case 1:
2521
2630
  _c.sent();
2522
2631
  if (modelCapabilities.delegate === 'NONE') {
2523
- throw new Error('No available delegate for focus detector.');
2632
+ throw new Error('No available delegate for document detector.');
2524
2633
  }
2525
- _b = (_a = tasksVision.ImageClassifier).createFromOptions;
2634
+ _b = (_a = tasksVision.ObjectDetector).createFromOptions;
2526
2635
  return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
2527
2636
  case 2:
2528
2637
  return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
@@ -2531,44 +2640,48 @@ function loadFocusModel() {
2531
2640
  delegate: modelCapabilities.delegate
2532
2641
  },
2533
2642
  // canvas: document.createElement('canvas'),
2643
+ scoreThreshold: scoreThreshold,
2534
2644
  runningMode: 'VIDEO'
2535
2645
  }])];
2536
2646
  case 3:
2537
- classifier = _c.sent();
2538
- classifierSettings = {
2539
- modelAssetPath: modelAssetPath
2647
+ detector$1 = _c.sent();
2648
+ detectorSettings$1 = {
2649
+ modelAssetPath: modelAssetPath,
2650
+ scoreThreshold: scoreThreshold
2540
2651
  };
2541
- return [2 /*return*/, classifier];
2652
+ return [2 /*return*/, detector$1];
2542
2653
  }
2543
2654
  });
2544
2655
  });
2545
2656
  }
2546
- function closeFocusModel() {
2547
- classifier === null || classifier === void 0 ? void 0 : classifier.close();
2548
- classifier = null;
2549
- classifierSettings = null;
2657
+ function closeDocumentDetector() {
2658
+ detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
2659
+ detector$1 = null;
2660
+ detectorSettings$1 = null;
2550
2661
  }
2551
- function useLoadFocusModel(_a) {
2552
- var _b = _a.modelPath,
2553
- modelPath = _b === void 0 ? defaultFocusModelPath : _b,
2554
- _c = _a.modelLoadTimeoutMs,
2555
- modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
2662
+ function useLoadDocumentDetector(_a) {
2663
+ var _b = _a.shouldLoadModels,
2664
+ shouldLoadModels = _b === void 0 ? true : _b,
2665
+ _c = _a.modelPath,
2666
+ modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
2667
+ _d = _a.modelLoadTimeoutMs,
2668
+ modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
2669
+ _e = _a.scoreThreshold,
2670
+ scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
2556
2671
  onModelError = _a.onModelError,
2557
- videoRef = _a.videoRef,
2558
- _d = _a.shouldLoadModels,
2559
- shouldLoadModels = _d === void 0 ? true : _d;
2560
- var _e = React.useState('not-started'),
2561
- modelLoadState = _e[0],
2562
- setModelLoadState = _e[1];
2563
- var _f = React.useState(0),
2564
- modelDownloadProgress = _f[0],
2565
- setModelDownloadProgress = _f[1];
2672
+ videoRef = _a.videoRef;
2673
+ var _f = React.useState('not-started'),
2674
+ modelLoadState = _f[0],
2675
+ setModelLoadState = _f[1];
2566
2676
  var _g = React.useState(null),
2567
2677
  modelWarmingStartedAt = _g[0],
2568
2678
  setModelWarmingStartedAt = _g[1];
2569
- var _h = React.useState(null),
2570
- modelError = _h[0],
2571
- setModelError = _h[1];
2679
+ var _h = React.useState(0),
2680
+ modelDownloadProgress = _h[0],
2681
+ setModelDownloadProgress = _h[1];
2682
+ var _j = React.useState(null),
2683
+ modelError = _j[0],
2684
+ setModelError = _j[1];
2572
2685
  React.useEffect(function loadModel() {
2573
2686
  var _this = this;
2574
2687
  if (!shouldLoadModels) return;
@@ -2577,21 +2690,24 @@ function useLoadFocusModel(_a) {
2577
2690
  function handleDownloadProgress(event) {
2578
2691
  setModelDownloadProgress(progressToPercentage(event.detail));
2579
2692
  }
2580
- document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
2693
+ document.addEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
2581
2694
  var modelLoadTimeout = setTimeout(function () {
2582
2695
  setModelError(new Error('Model loading time limit exceeded.'));
2583
2696
  }, modelLoadTimeoutMs);
2584
2697
  var cancelVideoReady = function cancelVideoReady() {};
2585
- loadFocusModel(modelPath).then(function (loadedModel) {
2698
+ loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
2586
2699
  return __awaiter(_this, void 0, void 0, function () {
2587
2700
  var _a, videoReady, cancel, cancelled;
2588
2701
  return __generator(this, function (_b) {
2589
2702
  switch (_b.label) {
2590
2703
  case 0:
2591
2704
  setModelDownloadProgress(100);
2592
- clearTimeout(modelLoadTimeout);
2593
2705
  setModelLoadState('warming');
2594
- setModelWarmingStartedAt(new Date().getTime());
2706
+ setModelWarmingStartedAt(performance.now());
2707
+ clearTimeout(modelLoadTimeout);
2708
+ return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
2709
+ case 1:
2710
+ _b.sent();
2595
2711
  _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
2596
2712
  cancelled = false;
2597
2713
  cancelVideoReady = function cancelVideoReady() {
@@ -2599,11 +2715,11 @@ function useLoadFocusModel(_a) {
2599
2715
  cancel();
2600
2716
  };
2601
2717
  return [4 /*yield*/, videoReady];
2602
- case 1:
2718
+ case 2:
2603
2719
  _b.sent();
2604
2720
  setTimeout(function () {
2605
2721
  if (cancelled) return;
2606
- loadedModel.classifyForVideo(videoRef.current, performance.now());
2722
+ model.detectForVideo(videoRef.current, performance.now());
2607
2723
  setModelLoadState('ready');
2608
2724
  }, 500);
2609
2725
  return [2 /*return*/];
@@ -2617,13 +2733,13 @@ function useLoadFocusModel(_a) {
2617
2733
  clearTimeout(modelLoadTimeout);
2618
2734
  });
2619
2735
  return function () {
2620
- log('unloading focus model');
2736
+ log('unloading document detection model');
2621
2737
  cancelVideoReady();
2622
- closeFocusModel();
2738
+ closeDocumentDetector();
2623
2739
  clearTimeout(modelLoadTimeout);
2624
- document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
2740
+ document.removeEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
2625
2741
  };
2626
- }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
2742
+ }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
2627
2743
  React.useEffect(function handleModelError() {
2628
2744
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
2629
2745
  }, [modelError, onModelError]);
@@ -2633,185 +2749,41 @@ function useLoadFocusModel(_a) {
2633
2749
  modelLoadState: modelLoadState,
2634
2750
  modelDownloadProgress: modelDownloadProgress,
2635
2751
  modelWarmingStartedAt: modelWarmingStartedAt,
2636
- modelError: modelError
2752
+ modelError: modelError,
2753
+ setModelError: setModelError
2637
2754
  };
2638
2755
  }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
2639
2756
  }
2640
- var lastFocusPredictionAt = 0;
2641
- var lastFocusPredictionTime = 0;
2642
- function setLastFocusPredictionAt(time) {
2643
- lastFocusPredictionTime = time - lastFocusPredictionAt;
2644
- lastFocusPredictionAt = time;
2645
- }
2646
- function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
2647
- var _a, _b, _c, _d, _e;
2648
- if (!classifier) return null;
2649
- var startedAt = new Date();
2650
- var image = cropIfNecessary(imageData, cropCanvas, rotateCanvas, box);
2651
- var result = classifier.classifyForVideo(image, performance.now());
2652
- 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) {
2653
- return c.categoryName === 'focused';
2654
- })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
2655
- var predictionTime = new Date().getTime() - startedAt.getTime();
2656
- return {
2657
- score: score,
2658
- predictionTime: predictionTime
2659
- };
2660
- }
2661
- function cropIfNecessary(imageData, cropCanvas, rotateCanvas, box) {
2662
- if (!box) return imageData;
2663
- var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas);
2664
- var _a = [box.width, box.height],
2665
- bw = _a[0],
2666
- bh = _a[1];
2667
- if (bh <= bw) return cropped;
2668
- var ctx = rotateCanvas.getContext('2d');
2669
- if (!ctx) return cropped;
2670
- rotateCanvas.width = bh;
2671
- rotateCanvas.height = bw;
2672
- ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
2673
- ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
2674
- ctx.rotate(1.5708); // 90 deg in radians
2675
- ctx.drawImage(cropped, -bw / 2, -bh / 2);
2676
- return rotateCanvas;
2677
- }
2678
-
2679
- var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
2680
- var detector$1 = null;
2681
- var detectorSettings$1 = null;
2682
- function loadFaceDetector() {
2683
- return __awaiter(this, arguments, void 0, function (modelAssetPath) {
2684
- var _a, _b;
2685
- if (modelAssetPath === void 0) {
2686
- modelAssetPath = defaultFaceDetectorModelPath;
2687
- }
2688
- return __generator(this, function (_c) {
2689
- switch (_c.label) {
2690
- case 0:
2691
- if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector$1];
2692
- closeFaceDetector();
2693
- return [4 /*yield*/, preloadFaceDetectorDependencies()];
2694
- case 1:
2695
- _c.sent();
2696
- if (modelCapabilities.delegate === 'NONE') {
2697
- throw new Error('No available delegate for face detector.');
2698
- }
2699
- _b = (_a = tasksVision.FaceDetector).createFromOptions;
2700
- return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
2701
- case 2:
2702
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
2703
- // canvas: document.createElement('canvas'),
2704
- baseOptions: {
2705
- modelAssetPath: modelAssetPath,
2706
- delegate: modelCapabilities.delegate
2707
- },
2708
- runningMode: 'VIDEO'
2709
- }])];
2710
- case 3:
2711
- detector$1 = _c.sent();
2712
- detectorSettings$1 = {
2713
- modelAssetPath: modelAssetPath
2714
- };
2715
- return [2 /*return*/, detector$1];
2757
+ function makeDocumentDetectorPrediction(frame) {
2758
+ return __awaiter(this, void 0, void 0, function () {
2759
+ var startedAt, prediction, time, frameWidth, frameHeight;
2760
+ return __generator(this, function (_a) {
2761
+ if (!detector$1) return [2 /*return*/, null];
2762
+ startedAt = performance.now();
2763
+ // Detectors can throw errors, for example when using custom URLs that
2764
+ // contain a model that doesn't provide the expected output.
2765
+ try {
2766
+ prediction = detector$1.detectForVideo(frame, performance.now());
2767
+ time = performance.now() - startedAt;
2768
+ frameWidth = frame.width;
2769
+ frameHeight = frame.height;
2770
+ return [2 /*return*/, _assign(_assign({}, prediction), {
2771
+ time: time,
2772
+ frameWidth: frameWidth,
2773
+ frameHeight: frameHeight
2774
+ })];
2775
+ } catch (e) {
2776
+ error('caught object detection error', e);
2716
2777
  }
2778
+ return [2 /*return*/, null];
2717
2779
  });
2718
2780
  });
2719
2781
  }
2720
- function closeFaceDetector() {
2721
- detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
2722
- detector$1 = null;
2723
- detectorSettings$1 = null;
2724
- }
2725
- function useLoadFaceDetector(_a) {
2726
- var onModelError = _a.onModelError,
2727
- _b = _a.modelLoadTimeoutMs,
2728
- modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
2729
- videoRef = _a.videoRef;
2730
- var _c = React.useState('not-started'),
2731
- modelLoadState = _c[0],
2732
- setModelLoadState = _c[1];
2733
- var _d = React.useState(0),
2734
- modelDownloadProgress = _d[0],
2735
- setModelDownloadProgress = _d[1];
2736
- var _e = React.useState(null),
2737
- modelWarmingStartedAt = _e[0],
2738
- setModelWarmingStartedAt = _e[1];
2739
- var _f = React.useState(null),
2740
- modelError = _f[0],
2741
- setModelError = _f[1];
2742
- React.useEffect(function loadModel() {
2743
- var _this = this;
2744
- setModelLoadState('downloading');
2745
- setModelWarmingStartedAt(null);
2746
- var modelLoadTimeout = setTimeout(function () {
2747
- setModelError(new Error('Model loading time limit exceeded.'));
2748
- }, modelLoadTimeoutMs);
2749
- function handleDownloadProgress(event) {
2750
- setModelDownloadProgress(progressToPercentage(event.detail));
2751
- }
2752
- document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
2753
- var cancelVideoReady = function cancelVideoReady() {};
2754
- loadFaceDetector().then(function (model) {
2755
- return __awaiter(_this, void 0, void 0, function () {
2756
- var _a, videoReady, cancel, cancelled;
2757
- return __generator(this, function (_b) {
2758
- switch (_b.label) {
2759
- case 0:
2760
- setModelDownloadProgress(100);
2761
- clearTimeout(modelLoadTimeout);
2762
- setModelLoadState('warming');
2763
- setModelWarmingStartedAt(new Date().getTime());
2764
- return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
2765
- case 1:
2766
- _b.sent();
2767
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
2768
- cancelled = false;
2769
- cancelVideoReady = function cancelVideoReady() {
2770
- cancelled = true;
2771
- cancel();
2772
- };
2773
- return [4 /*yield*/, videoReady];
2774
- case 2:
2775
- _b.sent();
2776
- if (cancelled) return [2 /*return*/];
2777
- model.detectForVideo(videoRef.current, performance.now());
2778
- setModelLoadState('ready');
2779
- return [2 /*return*/];
2780
- }
2781
- });
2782
- });
2783
- })["catch"](function (e) {
2784
- setModelError(e);
2785
- setModelLoadState('error');
2786
- })["finally"](function () {
2787
- clearTimeout(modelLoadTimeout);
2788
- });
2789
- return function () {
2790
- log('unloading face detection model');
2791
- cancelVideoReady();
2792
- closeFaceDetector();
2793
- clearTimeout(modelLoadTimeout);
2794
- document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
2795
- };
2796
- }, [modelLoadTimeoutMs, videoRef]);
2797
- React.useEffect(function handleModelError() {
2798
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
2799
- }, [modelError, onModelError]);
2800
- return React.useMemo(function () {
2801
- return {
2802
- ready: modelLoadState === 'ready',
2803
- modelLoadState: modelLoadState,
2804
- modelDownloadProgress: modelDownloadProgress,
2805
- modelWarmingStartedAt: modelWarmingStartedAt,
2806
- modelError: modelError
2807
- };
2808
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
2809
- }
2810
- var lastFaceDetectionAt = 0;
2811
- var lastFaceDetectionTime = 0;
2812
- function setLastFaceDetectionAt(time) {
2813
- lastFaceDetectionTime = time - lastFaceDetectionAt;
2814
- lastFaceDetectionAt = time;
2782
+ var lastDetectionAt = 0;
2783
+ var lastDetectionTime = 0;
2784
+ function setLastDetectionAt(time) {
2785
+ lastDetectionTime = time - lastDetectionAt;
2786
+ lastDetectionAt = time;
2815
2787
  }
2816
2788
  var framesNeededSamples$1 = [];
2817
2789
  function trackFramesNeeded$1(value, bufferLength) {
@@ -2821,922 +2793,397 @@ function trackFramesNeeded$1(value, bufferLength) {
2821
2793
  framesNeededSamples$1.unshift(value);
2822
2794
  if (framesNeededSamples$1.length > bufferLength) framesNeededSamples$1.length = bufferLength;
2823
2795
  }
2824
- var lastNFaces = [];
2796
+ var lastNBoxes = [];
2825
2797
  var lastNPairs$1 = [];
2826
- function trackFace(face, framesNeeded) {
2798
+ function trackBox(box, framesNeeded) {
2827
2799
  if (framesNeeded === void 0) {
2828
2800
  framesNeeded = 12;
2829
2801
  }
2830
- lastNFaces.unshift(face);
2831
- if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
2832
- if (lastNFaces.length > 1) {
2833
- var lastFace = lastNFaces[1];
2834
- var iou = calculateIoU(face.box, lastFace.box);
2802
+ lastNBoxes.unshift(box);
2803
+ if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
2804
+ if (lastNBoxes.length > 1) {
2805
+ var lastBox = lastNBoxes[1];
2806
+ var iou = calculateIoU(box, lastBox);
2835
2807
  lastNPairs$1.unshift({
2836
- a: face,
2837
- b: lastFace,
2808
+ a: box,
2809
+ b: lastBox,
2838
2810
  iou: iou
2839
2811
  });
2840
2812
  if (lastNPairs$1.length > framesNeeded - 1) lastNPairs$1.length = framesNeeded - 1;
2841
2813
  }
2842
2814
  }
2843
- function makeFaceDetectorPrediction(imageData) {
2844
- if (!detector$1) return null;
2845
- var prediction = detector$1.detectForVideo(imageData, performance.now());
2846
- var faces = prediction.detections.map(function (d) {
2847
- return {
2848
- box: convertBoundingBox(d.boundingBox),
2849
- keypoints: d.keypoints.map(function (k) {
2850
- var _a;
2851
- return _assign(_assign({}, k), {
2852
- x: k.x * imageData.width,
2853
- y: k.y * imageData.height,
2854
- name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
2855
- });
2856
- })
2857
- };
2815
+ var defaultDocumentDetectionBoundaries = {
2816
+ top: 20,
2817
+ bottom: 20,
2818
+ left: 20,
2819
+ right: 20
2820
+ };
2821
+ function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
2822
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
2823
+ if (boundaries === void 0) {
2824
+ boundaries = defaultDocumentDetectionBoundaries;
2825
+ }
2826
+ var detections = prediction.detections,
2827
+ frameWidth = prediction.frameWidth,
2828
+ frameHeight = prediction.frameHeight,
2829
+ time = prediction.time;
2830
+ var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
2831
+ var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
2832
+ var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
2833
+ var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
2834
+ var frameWidth80Pct = frameWidth * 0.8;
2835
+ var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
2836
+ return d.categories.map(function (category) {
2837
+ return {
2838
+ label: category === null || category === void 0 ? void 0 : category.categoryName,
2839
+ score: category === null || category === void 0 ? void 0 : category.score,
2840
+ box: convertBoundingBox(d.boundingBox)
2841
+ };
2842
+ });
2843
+ }), function (obj) {
2844
+ var _a = obj.box,
2845
+ xMin = _a.xMin,
2846
+ yMin = _a.yMin,
2847
+ width = _a.width,
2848
+ height = _a.height;
2849
+ return yMin > boundaryTop &&
2850
+ // Is it valid top edge of ID detected?
2851
+ yMin + height + boundaryBottom < frameHeight && (
2852
+ // Is it valid bottom edge less than max video height
2853
+ xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
2854
+ // If either the left side visible or if not, right edge of ID should be more than 80% of width.
2855
+ xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
2856
+ ;
2858
2857
  });
2859
- return _assign(_assign({}, prediction), {
2860
- faces: faces
2858
+ var allZero = detections.length > 0 && !detections.some(function (_a) {
2859
+ var boundingBox = _a.boundingBox;
2860
+ return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
2861
+ return n > 0;
2862
+ });
2861
2863
  });
2862
- }
2863
- function processFaceDetectorPrediction(_a) {
2864
- var faces = _a.faces,
2865
- videoWidth = _a.videoWidth,
2866
- videoHeight = _a.videoHeight,
2867
- _b = _a.requireVerticalFaceCentering,
2868
- requireVerticalFaceCentering = _b === void 0 ? true : _b,
2869
- _c = _a.stabilityThreshold,
2870
- stabilityThreshold = _c === void 0 ? 0.7 : _c;
2871
- var face = faces[0];
2872
- var faceNotDetected = faces.length === 0;
2873
- var faceNotCentered = false,
2874
- faceLookingAway = false,
2875
- faceTooClose = false,
2876
- faceTooFar = false;
2877
- if (face) {
2878
- // calculate centroids
2879
- var vCX = videoWidth / 2;
2880
- var vCY = videoHeight / 2;
2881
- var fCX = (face.box.xMin + face.box.xMax) / 2;
2882
- var fCY = (face.box.yMin + face.box.yMax) / 2;
2883
- // calculate thresholds
2884
- var vTX = videoWidth * 0.125;
2885
- var vTY = videoHeight * 0.125;
2886
- var fTW = face.box.width * 0.2;
2887
- var fTH = face.box.height * 0.2;
2888
- var nose = face.keypoints[2]; //.find((k) => k.name === 'noseTip')
2889
- if (nose) {
2890
- faceLookingAway = Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH;
2891
- var faceNotCenteredHorizontally = Math.abs(vCX - fCX) > vTX;
2892
- var faceNotCenteredVertically = Math.abs(vCY + 50 - fCY) > vTY;
2893
- faceNotCentered = faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
2894
- }
2895
- var isMobile = videoWidth < videoHeight;
2896
- var tooCloseMultiple = 1.5;
2897
- var tooFarMultiple = isMobile ? 6 : 7;
2898
- faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
2899
- faceTooFar = face.box.width < videoWidth / tooFarMultiple;
2864
+ var bestIdCardFront = detectedObjects.find(function (obj) {
2865
+ return obj.label === 'Document';
2866
+ });
2867
+ var bestIdCardBack = detectedObjects.find(function (obj) {
2868
+ return obj.label === 'Document back';
2869
+ });
2870
+ var bestPassportPage = detectedObjects.find(function (obj) {
2871
+ return obj.label === 'Passport page';
2872
+ });
2873
+ var bestSinglePage = detectedObjects.find(function (obj) {
2874
+ return obj.label === 'Single page';
2875
+ });
2876
+ var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
2877
+ var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
2878
+ var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
2879
+ var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
2880
+ var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
2881
+ var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
2882
+ var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
2883
+ var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
2884
+ var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
2885
+ var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
2886
+ var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
2887
+ var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
2888
+ var detectedDocumentType = 'none';
2889
+ if (singlePageDetectionThresholdMet) {
2890
+ detectedDocumentType = 'singlePage';
2891
+ } else if (passportDetectionThresholdMet) {
2892
+ detectedDocumentType = 'passport';
2893
+ } else if (idCardBackDetectionThresholdMet) {
2894
+ detectedDocumentType = 'idCardBack';
2895
+ } else if (detectionThresholdMet) {
2896
+ detectedDocumentType = 'idCardFront';
2900
2897
  }
2901
- var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
2902
- if (lastFaceDetectionTime > 0) {
2903
- trackFramesNeeded$1(500 / lastFaceDetectionTime);
2898
+ var documentInBounds = !!bestDocument;
2899
+ if (lastDetectionTime > 0) {
2900
+ trackFramesNeeded$1(1000 / lastDetectionTime);
2904
2901
  }
2905
- var faceIsStable = false;
2906
- if (faceInGuides) {
2907
- var framesNeeded = Math.ceil(average(framesNeededSamples$1));
2908
- trackFace(face, framesNeeded);
2909
- faceIsStable = lastNFaces.length >= framesNeeded && !lastNPairs$1.some(function (pair) {
2910
- return pair.iou < stabilityThreshold;
2902
+ var documentIsStable = false;
2903
+ var documentTooClose = false;
2904
+ if (bestDocument) {
2905
+ var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
2906
+ docWidth = _q[0],
2907
+ docHeight = _q[1];
2908
+ documentTooClose = docWidth > 0.85 || docHeight > 0.85;
2909
+ if (detectionThresholdMet && documentInBounds && !documentTooClose) {
2910
+ var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
2911
+ var threshold_1 = thresholdSet[detectedDocumentType];
2912
+ var framesNeeded = Math.ceil(average(framesNeededSamples$1));
2913
+ trackBox(bestDocument.box, framesNeeded);
2914
+ documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs$1.some(function (pair) {
2915
+ return pair.iou < threshold_1;
2916
+ });
2917
+ }
2918
+ }
2919
+ var bestPDF417;
2920
+ if (detectedObjects.length > 0) {
2921
+ bestPDF417 = detectedObjects.find(function (obj) {
2922
+ return obj.label === 'PDF417';
2911
2923
  });
2912
2924
  }
2913
- var faceReady = faceInGuides && faceIsStable;
2914
2925
  return {
2915
- face: face,
2916
- faceNotDetected: faceNotDetected,
2917
- faceNotCentered: faceNotCentered,
2918
- faceLookingAway: faceLookingAway,
2919
- faceTooClose: faceTooClose,
2920
- faceTooFar: faceTooFar,
2921
- faceReady: faceReady,
2922
- faceReadyAt: faceReady ? new Date() : null,
2923
- faceIsStable: faceIsStable
2924
- };
2925
- }
2926
- function testFaceDetectionAgainstKnownImage(detector) {
2927
- return new Promise(function (resolve, reject) {
2928
- var img = new Image();
2929
- img.crossOrigin = 'anonymous';
2930
- img.onload = function () {
2931
- var prediction = detector.detectForVideo(img, performance.now());
2932
- if (prediction.detections.length > 0) {
2933
- debug('face detection test result', prediction.detections);
2934
- resolve(void 0);
2935
- } else {
2936
- warn('face detection test failed');
2937
- reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
2938
- }
2939
- };
2940
- img.onerror = function () {
2941
- return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
2942
- };
2943
- img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
2926
+ prediction: prediction,
2927
+ detectedObjects: detectedObjects,
2928
+ detectionScore: detectionScore,
2929
+ detectionTime: time,
2930
+ detectionThresholdMet: detectionThresholdMet,
2931
+ detectedDocumentType: detectedDocumentType,
2932
+ idCardFrontDetectionScore: idCardFrontDetectionScore,
2933
+ idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
2934
+ idCardBackDetectionScore: idCardBackDetectionScore,
2935
+ idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
2936
+ passportDetectionScore: passportDetectionScore,
2937
+ passportDetectionThresholdMet: passportDetectionThresholdMet,
2938
+ singlePageDetectionScore: singlePageDetectionScore,
2939
+ singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
2940
+ bestDocument: bestDocument,
2941
+ bestPDF417: bestPDF417,
2942
+ documentInBounds: documentInBounds,
2943
+ documentTooClose: documentTooClose,
2944
+ documentIsStable: documentIsStable,
2945
+ frameWidth: frameWidth,
2946
+ frameHeight: frameHeight,
2947
+ allZero: allZero
2948
+ };
2949
+ }
2950
+ function applyNonMaxSuppression(detectedObjects, isGoodBox) {
2951
+ var maxes = {};
2952
+ detectedObjects.forEach(function (obj, i) {
2953
+ if (obj) {
2954
+ if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
2955
+ if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
2956
+ }
2957
+ });
2958
+ return Object.keys(maxes).map(function (label) {
2959
+ return detectedObjects[maxes[label][1]];
2960
+ }).filter(function (obj) {
2961
+ return !!obj;
2944
2962
  });
2945
2963
  }
2946
-
2947
- var preloadModels = function preloadModels(_a) {
2948
- return __awaiter(void 0, [_a], void 0, function (_b) {
2949
- var preloadTasks;
2950
- var _c = _b.documentDetectionModel,
2951
- documentDetectionModel = _c === void 0 ? true : _c,
2952
- _d = _b.focusModel,
2953
- focusModel = _d === void 0 ? true : _d,
2954
- _e = _b.faceDetectionModel,
2955
- faceDetectionModel = _e === void 0 ? true : _e;
2956
- return __generator(this, function (_f) {
2957
- switch (_f.label) {
2958
- case 0:
2959
- return [4 /*yield*/, probeModelCapabilities()];
2960
- case 1:
2961
- _f.sent();
2962
- preloadTasks = [];
2963
- if (documentDetectionModel) {
2964
- preloadTasks.push(preloadDocumentDetectorDependencies);
2965
- }
2966
- if (focusModel) {
2967
- preloadTasks.push(preloadFocusModelDependencies);
2968
- }
2969
- if (faceDetectionModel) {
2970
- preloadTasks.push(preloadFaceDetectorDependencies);
2971
- }
2972
- return [4 /*yield*/, Promise.all(preloadTasks)];
2973
- case 2:
2974
- _f.sent();
2975
- return [2 /*return*/];
2964
+ function testDocumentDetectionAgainstKnownImage(detector) {
2965
+ return new Promise(function (resolve, reject) {
2966
+ var img = new Image();
2967
+ img.crossOrigin = 'anonymous';
2968
+ img.onload = function () {
2969
+ var prediction = detector.detectForVideo(img, performance.now());
2970
+ if (prediction.detections.length > 0) {
2971
+ debug('document detection test result', prediction.detections);
2972
+ resolve(void 0);
2973
+ } else {
2974
+ warn('document detection test failed');
2975
+ reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
2976
2976
  }
2977
- });
2977
+ };
2978
+ img.onerror = function () {
2979
+ return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
2980
+ };
2981
+ img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
2978
2982
  });
2979
- };
2980
- var progressByUrl = {};
2981
- var progressByUseCase = {
2982
- visionRuntime: {
2983
- loaded: 0,
2984
- total: 0
2985
- },
2986
- documentDetection: {
2987
- loaded: 0,
2988
- total: 0
2989
- },
2990
- focus: {
2991
- loaded: 0,
2992
- total: 0
2993
- },
2994
- faceDetection: {
2995
- loaded: 0,
2996
- total: 0
2983
+ }
2984
+
2985
+ function getFrameDimensions(frame) {
2986
+ var frameWidth = frame.width,
2987
+ frameHeight = frame.height;
2988
+ if (frame instanceof HTMLImageElement) {
2989
+ frameWidth = frame.naturalWidth;
2990
+ frameHeight = frame.naturalHeight;
2997
2991
  }
2998
- };
2999
- function preloadDependency(url) {
3000
- return __awaiter(this, void 0, void 0, function () {
3001
- return __generator(this, function (_a) {
3002
- return [2 /*return*/, new Promise(function (resolve, reject) {
3003
- var req = new XMLHttpRequest();
3004
- req.addEventListener('progress', function (event) {
3005
- if (!event.lengthComputable) return;
3006
- progressByUrl[url] = event;
3007
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
3008
- detail: {
3009
- url: url,
3010
- loaded: event.loaded,
3011
- total: event.total
3012
- }
3013
- }));
3014
- });
3015
- req.addEventListener('loadend', function () {
3016
- resolve(req.readyState === 4 && req.status === 200);
2992
+ if (frame instanceof HTMLVideoElement) {
2993
+ frameWidth = frame.videoWidth;
2994
+ frameHeight = frame.videoHeight;
2995
+ }
2996
+ return [frameWidth, frameHeight];
2997
+ }
2998
+
2999
+ var InvisibleCanvasContainer = styled__default.default.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"])));
3000
+ var InvisibleCanvas = styled__default.default.canvas(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
3001
+ function drawToCanvas(canvas, frame, width, height) {
3002
+ if (!canvas) return;
3003
+ var ctx = canvas.getContext('2d');
3004
+ if (!ctx) return;
3005
+ if (!width || !height) {
3006
+ var _a = getFrameDimensions(frame),
3007
+ frameWidth = _a[0],
3008
+ frameHeight = _a[1];
3009
+ width || (width = frameWidth);
3010
+ height || (height = frameHeight);
3011
+ }
3012
+ canvas.width = width;
3013
+ canvas.height = height;
3014
+ ctx.drawImage(frame, 0, 0, width, height);
3015
+ }
3016
+ function clearCanvas(canvas) {
3017
+ var _a;
3018
+ (_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);
3019
+ }
3020
+ var templateObject_1$N, templateObject_2$G;
3021
+
3022
+ function useFrameLoop(fn, options) {
3023
+ if (options === void 0) {
3024
+ options = {};
3025
+ }
3026
+ var _a = React.useState(false),
3027
+ running = _a[0],
3028
+ setRunning = _a[1];
3029
+ var startedAtRef = React.useRef(null);
3030
+ var loopId = React.useRef(0);
3031
+ var frameId = React.useRef(0);
3032
+ React.useEffect(function runFrameLoop() {
3033
+ if (!running) return;
3034
+ var timer;
3035
+ var currentLoopId = loopId.current;
3036
+ function hotLoop() {
3037
+ return __awaiter(this, void 0, void 0, function () {
3038
+ var start, timeRunning, took, amountToThrottle;
3039
+ var _a, _b, _c;
3040
+ return __generator(this, function (_d) {
3041
+ switch (_d.label) {
3042
+ case 0:
3043
+ if (currentLoopId !== loopId.current) return [2 /*return*/];
3044
+ start = new Date().getTime();
3045
+ timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
3046
+ return [4 /*yield*/, fn(frameId.current, timeRunning)];
3047
+ case 1:
3048
+ _d.sent();
3049
+ took = new Date().getTime() - start;
3050
+ amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
3051
+ timer = setTimeout(function () {
3052
+ frameId.current = requestAnimationFrame(hotLoop);
3053
+ }, amountToThrottle);
3054
+ return [2 /*return*/];
3055
+ }
3017
3056
  });
3018
- req.addEventListener('error', reject);
3019
- req.open('GET', url, true);
3020
- req.send();
3021
- })];
3022
- });
3023
- });
3057
+ });
3058
+ }
3059
+ void hotLoop();
3060
+ return function () {
3061
+ loopId.current += 1;
3062
+ if (frameId.current) cancelAnimationFrame(frameId.current);
3063
+ if (timer) clearTimeout(timer);
3064
+ };
3065
+ }, [fn, running, options.throttleMs]);
3066
+ var start = React.useCallback(function () {
3067
+ startedAtRef.current = new Date();
3068
+ setRunning(true);
3069
+ }, []);
3070
+ var stop = React.useCallback(function () {
3071
+ loopId.current += 1; // force the loop to stop immediately.
3072
+ setRunning(false);
3073
+ startedAtRef.current = null;
3074
+ }, []);
3075
+ React.useEffect(function startAutomatically() {
3076
+ if (options.autoStart) start();
3077
+ return stop;
3078
+ }, [options.autoStart, start, stop]);
3079
+ return {
3080
+ start: start,
3081
+ stop: stop
3082
+ };
3024
3083
  }
3025
- var documentDetectorPreloading = false,
3026
- focusModelPreloading = false,
3027
- faceDetectorPreloading = false;
3028
- function preloadDocumentDetectorDependencies() {
3029
- return __awaiter(this, void 0, void 0, function () {
3030
- function handleDownloadProgress(event) {
3031
- var detail = event.detail;
3032
- if (!dependencies.includes(detail.url)) return;
3033
- progressByUseCase.documentDetection = sumUpProgressForDependencies(dependencies);
3034
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.documentDetection', {
3035
- detail: progressByUseCase.documentDetection
3036
- }));
3084
+
3085
+ function listAvailableCameras(facingMode_1) {
3086
+ return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
3087
+ var cameraEnumerationStream, allDevices, allowedVideoDevices;
3088
+ if (requestMicAccess === void 0) {
3089
+ requestMicAccess = false;
3037
3090
  }
3038
- var dependencies;
3039
3091
  return __generator(this, function (_a) {
3040
3092
  switch (_a.label) {
3041
3093
  case 0:
3042
- if (documentDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
3043
- var i = setInterval(function () {
3044
- if (!documentDetectorPreloading) {
3045
- clearInterval(i);
3046
- resolve();
3094
+ return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
3095
+ video: {
3096
+ facingMode: {
3097
+ exact: facingMode
3047
3098
  }
3048
- }, 100);
3049
- })];
3050
- documentDetectorPreloading = true;
3051
- return [4 /*yield*/, probeModelCapabilities()];
3099
+ },
3100
+ audio: requestMicAccess
3101
+ })
3102
+ // This lists all available cameras attached to the user's device.
3103
+ ];
3052
3104
  case 1:
3053
- _a.sent();
3054
- if (modelCapabilities.delegate === 'NONE') {
3055
- throw new Error('No available delegate for document detector.');
3056
- }
3057
- dependencies = [defaultDocumentDetectorModelPath];
3058
- document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
3059
- _a.label = 2;
3105
+ cameraEnumerationStream = _a.sent();
3106
+ return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
3060
3107
  case 2:
3061
- _a.trys.push([2,, 4, 5]);
3062
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
3063
- case 3:
3064
- _a.sent();
3065
- return [3 /*break*/, 5];
3066
- case 4:
3067
- document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
3068
- documentDetectorPreloading = false;
3069
- return [7 /*endfinally*/];
3070
- case 5:
3071
- return [2 /*return*/];
3072
- }
3073
- });
3074
- });
3075
- }
3076
- function preloadFocusModelDependencies() {
3077
- return __awaiter(this, void 0, void 0, function () {
3078
- function handleModelDownloadProgress(event) {
3079
- var detail = event.detail;
3080
- if (!dependencies.includes(detail.url)) return;
3081
- progressByUseCase.focus = sumUpProgressForDependencies(dependencies);
3082
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.focus', {
3083
- detail: progressByUseCase.focus
3084
- }));
3085
- }
3086
- var dependencies;
3087
- return __generator(this, function (_a) {
3088
- switch (_a.label) {
3089
- case 0:
3090
- if (focusModelPreloading) return [2 /*return*/, new Promise(function (resolve) {
3091
- var i = setInterval(function () {
3092
- if (!focusModelPreloading) {
3093
- clearInterval(i);
3094
- resolve();
3095
- }
3096
- }, 100);
3097
- })];
3098
- focusModelPreloading = true;
3099
- return [4 /*yield*/, probeModelCapabilities()];
3100
- case 1:
3101
- _a.sent();
3102
- if (modelCapabilities.delegate === 'NONE') {
3103
- throw new Error('No available delegate for document detector.');
3104
- }
3105
- dependencies = [defaultFocusModelPath];
3106
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3107
- _a.label = 2;
3108
- case 2:
3109
- _a.trys.push([2,, 4, 5]);
3110
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
3111
- case 3:
3112
- _a.sent();
3113
- return [3 /*break*/, 5];
3114
- case 4:
3115
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3116
- focusModelPreloading = false;
3117
- return [7 /*endfinally*/];
3118
- case 5:
3119
- return [2 /*return*/];
3120
- }
3121
- });
3122
- });
3123
- }
3124
- function preloadFaceDetectorDependencies() {
3125
- return __awaiter(this, void 0, void 0, function () {
3126
- function handleModelDownloadProgress(event) {
3127
- var detail = event.detail;
3128
- if (!dependencies.includes(detail.url)) return;
3129
- progressByUseCase.faceDetection = sumUpProgressForDependencies(dependencies);
3130
- document.dispatchEvent(new CustomEvent('idmission.preloadProgress.faceDetection', {
3131
- detail: progressByUseCase.faceDetection
3132
- }));
3133
- }
3134
- var dependencies;
3135
- return __generator(this, function (_a) {
3136
- switch (_a.label) {
3137
- case 0:
3138
- if (faceDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
3139
- var i = setInterval(function () {
3140
- if (!faceDetectorPreloading) {
3141
- clearInterval(i);
3142
- resolve();
3143
- }
3144
- }, 100);
3145
- })];
3146
- faceDetectorPreloading = true;
3147
- return [4 /*yield*/, probeModelCapabilities()];
3148
- case 1:
3149
- _a.sent();
3150
- if (modelCapabilities.delegate === 'NONE') {
3151
- throw new Error('No available delegate for document detector.');
3152
- }
3153
- dependencies = [defaultFaceDetectorModelPath];
3154
- document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3155
- _a.label = 2;
3156
- case 2:
3157
- _a.trys.push([2,, 4, 5]);
3158
- return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
3159
- case 3:
3160
- _a.sent();
3161
- return [3 /*break*/, 5];
3162
- case 4:
3163
- document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
3164
- faceDetectorPreloading = false;
3165
- return [7 /*endfinally*/];
3166
- case 5:
3167
- return [2 /*return*/];
3108
+ allDevices = _a.sent();
3109
+ allowedVideoDevices = allDevices.filter(function (_a) {
3110
+ var kind = _a.kind,
3111
+ label = _a.label;
3112
+ return kind === 'videoinput' && !label.toLowerCase().includes('virtual');
3113
+ });
3114
+ // Release the access to the user's camera that we obtained for enumeration purposes.
3115
+ cameraEnumerationStream.getVideoTracks().forEach(function (track) {
3116
+ track.enabled = false;
3117
+ track.stop();
3118
+ });
3119
+ cameraEnumerationStream = null;
3120
+ return [2 /*return*/, allowedVideoDevices];
3168
3121
  }
3169
3122
  });
3170
3123
  });
3171
3124
  }
3172
- function progressToPercentage(progress) {
3173
- return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
3174
- }
3175
- function sumUpProgressForDependencies(dependencies) {
3176
- return dependencies.reduce(function (result, dependency) {
3177
- var dependencyProgress = progressByUrl[dependency];
3178
- if (!dependencyProgress) return result;
3179
- result.loaded += dependencyProgress.loaded;
3180
- result.total += dependencyProgress.total;
3181
- return result;
3182
- }, {
3183
- loaded: 0,
3184
- total: 0
3125
+ var frontCameraLabels = ['front', 'avant', 'anteriore', 'cameraaanvoorzijde', 'kamerapåframsidan', 'forsidekamera', 'kamerapåforsiden', 'aparatprzedni', 'etukamera', 'kameradepan', 'ÖnKamera', 'cameramặttrước', 'camerăfață', 'prednákamera', 'prednjakamera', 'előlapikamera', 'přednífotoaparát', 'μπροστινήκάμερα', 'переднякамера', 'передняякамера', 'преднакамера', 'алдыңғыкамера', 'מצלמה קדמית', 'الكاميرا الأمامية', 'फ़्रंटकैमरा', '前置相机', '前置鏡頭', '前面カメラ', '전면카메라', 'กล้องด้านหน้า'].map(function (s) {
3126
+ return s.toLocaleLowerCase().split(' ').join('');
3127
+ });
3128
+ var rearCameraLabels = ['back', 'rear', 'posterior', 'trasera', 'traseira', 'arrière', 'rückkamera', 'fotocamera(posteriore)', 'cameraaanachterzijde', 'kamerapåbaksidan', 'kamerapåbaksiden', 'bagsidekamera', 'aparattylny', 'takakamera', 'arkakamera', 'kamerabelakang', 'cameramặtsau', 'camerăspate', 'stražnjakamera', 'zadnákamera', 'hátoldalikamera', 'zadnífotoaparát', 'πίσωκάμερα', 'заднякамера', 'Задняякамера', 'заднакамера', 'артқыкамера', 'מצלמה אחורית', 'الكاميرا الخلفية', 'बैककैमरा', '后置相机', '後置鏡頭', '背面カメラ', '후면카메라', 'กล้องด้านหลัง'].map(function (s) {
3129
+ return s.toLocaleLowerCase().split(' ').join('');
3130
+ });
3131
+ var backUltraWideCameraLabels = ['backdualwidecamera', 'backultrawidecamera', 'ultraampliaposterior', 'ultra-angulartraseira', 'ultragrandeangulartraseira', 'ultragrandangle', 'ultragranangular', 'ultra-weitwinkelkamera', 'ultra-grandangolo', 'ultrabredecameraaanachterzijde', 'ultravidvinkelkamerapåbaksidan', 'ultravidvinkelkameraetpåbagsiden', 'ultravidvinkelkamerabak', 'ultragenişkameraarkayüzü', 'ultralaajakulmainentakakamera', 'tylnyaparatultraszerokokątny', 'cameracựcrộngmặtsau', 'camerăcuobiectivultra‑superangularspate', 'ultraszéleslátószögűkamera', 'kameraultralebarbelakang', 'stražnjaultraširokakamera', 'zadníultraširokoúhlýfotoaparát', 'ultraširokouhlá', 'πίσωυπερευρείακάμερα', 'заднянадширококутнакамера', 'Задняясверхширокоугольнаякамера', 'Задна свръх широкоъгълна камера', 'артқыультракеңбұрыштыкамера', 'מצלמה אולטרה רחבה אחורית', 'كاميرا خلفية عريضة جدًا', 'बैकअल्ट्रावाइडकैमरा', '后置超广角相机', '後置超廣角鏡頭相機', '背面超広角カメラ', '후면울트라와이드카메라', 'กล้องด้านหลังอัลตร้าไวด์'].map(function (s) {
3132
+ return s.toLocaleLowerCase().split(' ').join('');
3133
+ });
3134
+ var cameraLabelMatches = function cameraLabelMatches(labelOrDevice, labelSetOrLabel) {
3135
+ var label = labelOrDevice instanceof MediaDeviceInfo ? getDeviceLabel(labelOrDevice) : labelOrDevice;
3136
+ var labelSet = typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel;
3137
+ return labelSet.some(function (l) {
3138
+ return label.includes(l);
3185
3139
  });
3186
- }
3187
-
3188
- var defaultDocumentDetectionScoreThreshold = 0.1;
3189
- var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
3190
- var defaultDocumentDetectionThresholds = {
3191
- idCardFront: 0.6,
3192
- idCardBack: 0.6,
3193
- passport: 0.4,
3194
- singlePage: 0.4,
3195
- stability: {
3196
- idCardFront: 0.85,
3197
- idCardBack: 0.85,
3198
- passport: 0.5,
3199
- singlePage: 0.5
3200
- }
3201
3140
  };
3202
- var documentTypeDisplayNames = {
3203
- idCardFront: 'ID card front',
3204
- idCardBack: 'ID card back',
3205
- passport: 'Passport',
3206
- singlePage: 'Single page',
3207
- none: 'None'
3141
+ var getDeviceLabel = function getDeviceLabel(deviceInfo) {
3142
+ return deviceInfo.label.toLocaleLowerCase().split(' ').join('');
3208
3143
  };
3209
- var detector = null;
3210
- var detectorSettings = null;
3211
- function loadDocumentDetector() {
3212
- return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
3213
- var _a, _b;
3214
- if (modelAssetPath === void 0) {
3215
- modelAssetPath = defaultDocumentDetectorModelPath;
3216
- }
3217
- if (scoreThreshold === void 0) {
3218
- scoreThreshold = defaultDocumentDetectionScoreThreshold;
3219
- }
3220
- return __generator(this, function (_c) {
3221
- switch (_c.label) {
3222
- case 0:
3223
- 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];
3224
- closeDocumentDetector();
3225
- return [4 /*yield*/, preloadDocumentDetectorDependencies()];
3226
- case 1:
3227
- _c.sent();
3228
- if (modelCapabilities.delegate === 'NONE') {
3229
- throw new Error('No available delegate for document detector.');
3230
- }
3231
- _b = (_a = tasksVision.ObjectDetector).createFromOptions;
3232
- return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
3233
- case 2:
3234
- return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
3235
- baseOptions: {
3236
- modelAssetPath: modelAssetPath,
3237
- delegate: modelCapabilities.delegate
3238
- },
3239
- // canvas: document.createElement('canvas'),
3240
- scoreThreshold: scoreThreshold,
3241
- runningMode: 'VIDEO'
3242
- }])];
3243
- case 3:
3244
- detector = _c.sent();
3245
- detectorSettings = {
3246
- modelAssetPath: modelAssetPath,
3247
- scoreThreshold: scoreThreshold
3248
- };
3249
- return [2 /*return*/, detector];
3250
- }
3144
+ var currentCamera;
3145
+ function obtainCameraAccess(stream, deviceLabel, video) {
3146
+ releaseCameraAccess();
3147
+ log('obtaining camera access...');
3148
+ var _a = stream.getVideoTracks()[0].getSettings(),
3149
+ width = _a.width,
3150
+ height = _a.height;
3151
+ log('camera dimensions', width, height);
3152
+ var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
3153
+ log('camera label', label);
3154
+ var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
3155
+ log('is rear facing?', isRearFacing);
3156
+ var release = function release() {
3157
+ stream.getTracks().forEach(function (track) {
3158
+ track.enabled = false;
3159
+ track.stop();
3251
3160
  });
3252
- });
3161
+ if (video) {
3162
+ video.pause();
3163
+ video.srcObject = null;
3164
+ video.src = '';
3165
+ }
3166
+ };
3167
+ width || (width = 0);
3168
+ height || (height = 0);
3169
+ currentCamera = {
3170
+ label: deviceLabel,
3171
+ stream: stream,
3172
+ width: width,
3173
+ height: height,
3174
+ isRearFacing: isRearFacing,
3175
+ release: release
3176
+ };
3177
+ log('camera access granted');
3178
+ // if (video) video.srcObject = stream
3179
+ // log('video source initialized')
3180
+ return currentCamera;
3253
3181
  }
3254
- function closeDocumentDetector() {
3255
- detector === null || detector === void 0 ? void 0 : detector.close();
3256
- detector = null;
3257
- detectorSettings = null;
3258
- }
3259
- function useLoadDocumentDetector(_a) {
3260
- var _b = _a.shouldLoadModels,
3261
- shouldLoadModels = _b === void 0 ? true : _b,
3262
- _c = _a.modelPath,
3263
- modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
3264
- _d = _a.modelLoadTimeoutMs,
3265
- modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
3266
- _e = _a.scoreThreshold,
3267
- scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
3268
- onModelError = _a.onModelError,
3269
- videoRef = _a.videoRef;
3270
- var _f = React.useState('not-started'),
3271
- modelLoadState = _f[0],
3272
- setModelLoadState = _f[1];
3273
- var _g = React.useState(null),
3274
- modelWarmingStartedAt = _g[0],
3275
- setModelWarmingStartedAt = _g[1];
3276
- var _h = React.useState(0),
3277
- modelDownloadProgress = _h[0],
3278
- setModelDownloadProgress = _h[1];
3279
- var _j = React.useState(null),
3280
- modelError = _j[0],
3281
- setModelError = _j[1];
3282
- React.useEffect(function loadModel() {
3283
- var _this = this;
3284
- if (!shouldLoadModels) return;
3285
- setModelLoadState('downloading');
3286
- setModelWarmingStartedAt(null);
3287
- function handleDownloadProgress(event) {
3288
- setModelDownloadProgress(progressToPercentage(event.detail));
3289
- }
3290
- document.addEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
3291
- var modelLoadTimeout = setTimeout(function () {
3292
- setModelError(new Error('Model loading time limit exceeded.'));
3293
- }, modelLoadTimeoutMs);
3294
- var cancelVideoReady = function cancelVideoReady() {};
3295
- loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
3296
- return __awaiter(_this, void 0, void 0, function () {
3297
- var _a, videoReady, cancel, cancelled;
3298
- return __generator(this, function (_b) {
3299
- switch (_b.label) {
3300
- case 0:
3301
- setModelDownloadProgress(100);
3302
- setModelLoadState('warming');
3303
- setModelWarmingStartedAt(new Date().getTime());
3304
- clearTimeout(modelLoadTimeout);
3305
- return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
3306
- case 1:
3307
- _b.sent();
3308
- _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
3309
- cancelled = false;
3310
- cancelVideoReady = function cancelVideoReady() {
3311
- cancelled = true;
3312
- cancel();
3313
- };
3314
- return [4 /*yield*/, videoReady];
3315
- case 2:
3316
- _b.sent();
3317
- setTimeout(function () {
3318
- if (cancelled) return;
3319
- model.detectForVideo(videoRef.current, performance.now());
3320
- setModelLoadState('ready');
3321
- }, 500);
3322
- return [2 /*return*/];
3323
- }
3324
- });
3325
- });
3326
- })["catch"](function (e) {
3327
- setModelError(e);
3328
- setModelLoadState('error');
3329
- })["finally"](function () {
3330
- clearTimeout(modelLoadTimeout);
3331
- });
3332
- return function () {
3333
- log('unloading document detection model');
3334
- cancelVideoReady();
3335
- closeDocumentDetector();
3336
- clearTimeout(modelLoadTimeout);
3337
- document.removeEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
3338
- };
3339
- }, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
3340
- React.useEffect(function handleModelError() {
3341
- if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
3342
- }, [modelError, onModelError]);
3343
- return React.useMemo(function () {
3344
- return {
3345
- ready: modelLoadState === 'ready',
3346
- modelLoadState: modelLoadState,
3347
- modelDownloadProgress: modelDownloadProgress,
3348
- modelWarmingStartedAt: modelWarmingStartedAt,
3349
- modelError: modelError,
3350
- setModelError: setModelError
3351
- };
3352
- }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
3353
- }
3354
- function makeDocumentDetectorPrediction(frame) {
3355
- return __awaiter(this, void 0, void 0, function () {
3356
- var startedAt, prediction, time, frameWidth, frameHeight;
3357
- return __generator(this, function (_a) {
3358
- if (!detector) return [2 /*return*/, null];
3359
- startedAt = new Date();
3360
- // Detectors can throw errors, for example when using custom URLs that
3361
- // contain a model that doesn't provide the expected output.
3362
- try {
3363
- prediction = detector.detectForVideo(frame, performance.now());
3364
- time = new Date().getTime() - startedAt.getTime();
3365
- frameWidth = frame.width;
3366
- frameHeight = frame.height;
3367
- return [2 /*return*/, _assign(_assign({}, prediction), {
3368
- time: time,
3369
- frameWidth: frameWidth,
3370
- frameHeight: frameHeight
3371
- })];
3372
- } catch (e) {
3373
- error('caught object detection error', e);
3374
- }
3375
- return [2 /*return*/, null];
3376
- });
3377
- });
3378
- }
3379
- var lastDetectionAt = 0;
3380
- var lastDetectionTime = 0;
3381
- function setLastDetectionAt(time) {
3382
- lastDetectionTime = time - lastDetectionAt;
3383
- lastDetectionAt = time;
3384
- }
3385
- var framesNeededSamples = [];
3386
- function trackFramesNeeded(value, bufferLength) {
3387
- if (bufferLength === void 0) {
3388
- bufferLength = 25;
3389
- }
3390
- framesNeededSamples.unshift(value);
3391
- if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
3392
- }
3393
- var lastNBoxes = [];
3394
- var lastNPairs = [];
3395
- function trackBox(box, framesNeeded) {
3396
- if (framesNeeded === void 0) {
3397
- framesNeeded = 12;
3398
- }
3399
- lastNBoxes.unshift(box);
3400
- if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
3401
- if (lastNBoxes.length > 1) {
3402
- var lastBox = lastNBoxes[1];
3403
- var iou = calculateIoU(box, lastBox);
3404
- lastNPairs.unshift({
3405
- a: box,
3406
- b: lastBox,
3407
- iou: iou
3408
- });
3409
- if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
3410
- }
3411
- }
3412
- var defaultDocumentDetectionBoundaries = {
3413
- top: 20,
3414
- bottom: 20,
3415
- left: 20,
3416
- right: 20
3417
- };
3418
- function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
3419
- var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
3420
- if (boundaries === void 0) {
3421
- boundaries = defaultDocumentDetectionBoundaries;
3422
- }
3423
- var detections = prediction.detections,
3424
- frameWidth = prediction.frameWidth,
3425
- frameHeight = prediction.frameHeight,
3426
- time = prediction.time;
3427
- var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
3428
- var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
3429
- var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
3430
- var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
3431
- var frameWidth80Pct = frameWidth * 0.8;
3432
- var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
3433
- return d.categories.map(function (category) {
3434
- return {
3435
- label: category === null || category === void 0 ? void 0 : category.categoryName,
3436
- score: category === null || category === void 0 ? void 0 : category.score,
3437
- box: convertBoundingBox(d.boundingBox)
3438
- };
3439
- });
3440
- }), function (obj) {
3441
- var _a = obj.box,
3442
- xMin = _a.xMin,
3443
- yMin = _a.yMin,
3444
- width = _a.width,
3445
- height = _a.height;
3446
- return yMin > boundaryTop &&
3447
- // Is it valid top edge of ID detected?
3448
- yMin + height + boundaryBottom < frameHeight && (
3449
- // Is it valid bottom edge less than max video height
3450
- xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
3451
- // If either the left side visible or if not, right edge of ID should be more than 80% of width.
3452
- xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
3453
- ;
3454
- });
3455
- var allZero = detections.length > 0 && !detections.some(function (_a) {
3456
- var boundingBox = _a.boundingBox;
3457
- return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
3458
- return n > 0;
3459
- });
3460
- });
3461
- var bestIdCardFront = detectedObjects.find(function (obj) {
3462
- return obj.label === 'Document';
3463
- });
3464
- var bestIdCardBack = detectedObjects.find(function (obj) {
3465
- return obj.label === 'Document back';
3466
- });
3467
- var bestPassportPage = detectedObjects.find(function (obj) {
3468
- return obj.label === 'Passport page';
3469
- });
3470
- var bestSinglePage = detectedObjects.find(function (obj) {
3471
- return obj.label === 'Single page';
3472
- });
3473
- var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
3474
- var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
3475
- var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
3476
- var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
3477
- var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
3478
- var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
3479
- var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
3480
- var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
3481
- var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
3482
- var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
3483
- var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
3484
- var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
3485
- var detectedDocumentType = 'none';
3486
- if (singlePageDetectionThresholdMet) {
3487
- detectedDocumentType = 'singlePage';
3488
- } else if (passportDetectionThresholdMet) {
3489
- detectedDocumentType = 'passport';
3490
- } else if (idCardBackDetectionThresholdMet) {
3491
- detectedDocumentType = 'idCardBack';
3492
- } else if (detectionThresholdMet) {
3493
- detectedDocumentType = 'idCardFront';
3494
- }
3495
- var documentInBounds = !!bestDocument;
3496
- if (lastDetectionTime > 0) {
3497
- trackFramesNeeded(1000 / lastDetectionTime);
3498
- }
3499
- var documentIsStable = false;
3500
- var documentTooClose = false;
3501
- if (bestDocument) {
3502
- var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
3503
- docWidth = _q[0],
3504
- docHeight = _q[1];
3505
- documentTooClose = docWidth > 0.85 || docHeight > 0.85;
3506
- if (detectionThresholdMet && documentInBounds && !documentTooClose) {
3507
- var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
3508
- var threshold_1 = thresholdSet[detectedDocumentType];
3509
- var framesNeeded = Math.ceil(average(framesNeededSamples));
3510
- trackBox(bestDocument.box, framesNeeded);
3511
- documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
3512
- return pair.iou < threshold_1;
3513
- });
3514
- }
3515
- }
3516
- return {
3517
- prediction: prediction,
3518
- detectedObjects: detectedObjects,
3519
- detectionScore: detectionScore,
3520
- detectionTime: time,
3521
- detectionThresholdMet: detectionThresholdMet,
3522
- detectedDocumentType: detectedDocumentType,
3523
- idCardFrontDetectionScore: idCardFrontDetectionScore,
3524
- idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
3525
- idCardBackDetectionScore: idCardBackDetectionScore,
3526
- idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
3527
- passportDetectionScore: passportDetectionScore,
3528
- passportDetectionThresholdMet: passportDetectionThresholdMet,
3529
- singlePageDetectionScore: singlePageDetectionScore,
3530
- singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
3531
- bestDocument: bestDocument,
3532
- documentInBounds: documentInBounds,
3533
- documentTooClose: documentTooClose,
3534
- documentIsStable: documentIsStable,
3535
- frameWidth: frameWidth,
3536
- frameHeight: frameHeight,
3537
- allZero: allZero
3538
- };
3539
- }
3540
- function applyNonMaxSuppression(detectedObjects, isGoodBox) {
3541
- var maxes = {};
3542
- detectedObjects.forEach(function (obj, i) {
3543
- if (obj) {
3544
- if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
3545
- if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
3546
- }
3547
- });
3548
- return Object.keys(maxes).map(function (label) {
3549
- return detectedObjects[maxes[label][1]];
3550
- }).filter(function (obj) {
3551
- return !!obj;
3552
- });
3553
- }
3554
- function testDocumentDetectionAgainstKnownImage(detector) {
3555
- return new Promise(function (resolve, reject) {
3556
- var img = new Image();
3557
- img.crossOrigin = 'anonymous';
3558
- img.onload = function () {
3559
- var prediction = detector.detectForVideo(img, performance.now());
3560
- if (prediction.detections.length > 0) {
3561
- debug('document detection test result', prediction.detections);
3562
- resolve(void 0);
3563
- } else {
3564
- warn('document detection test failed');
3565
- reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
3566
- }
3567
- };
3568
- img.onerror = function () {
3569
- return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
3570
- };
3571
- img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
3572
- });
3573
- }
3574
-
3575
- function useFrameLoop(fn, options) {
3576
- if (options === void 0) {
3577
- options = {};
3578
- }
3579
- var _a = React.useState(false),
3580
- running = _a[0],
3581
- setRunning = _a[1];
3582
- var startedAtRef = React.useRef(null);
3583
- var loopId = React.useRef(0);
3584
- var frameId = React.useRef(0);
3585
- React.useEffect(function runFrameLoop() {
3586
- if (!running) return;
3587
- var timer;
3588
- var currentLoopId = loopId.current;
3589
- function hotLoop() {
3590
- return __awaiter(this, void 0, void 0, function () {
3591
- var start, timeRunning, took, amountToThrottle;
3592
- var _a, _b, _c;
3593
- return __generator(this, function (_d) {
3594
- switch (_d.label) {
3595
- case 0:
3596
- if (currentLoopId !== loopId.current) return [2 /*return*/];
3597
- start = new Date().getTime();
3598
- timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
3599
- return [4 /*yield*/, fn(frameId.current, timeRunning)];
3600
- case 1:
3601
- _d.sent();
3602
- took = new Date().getTime() - start;
3603
- amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
3604
- timer = setTimeout(function () {
3605
- frameId.current = requestAnimationFrame(hotLoop);
3606
- }, amountToThrottle);
3607
- return [2 /*return*/];
3608
- }
3609
- });
3610
- });
3611
- }
3612
- void hotLoop();
3613
- return function () {
3614
- loopId.current += 1;
3615
- if (frameId.current) cancelAnimationFrame(frameId.current);
3616
- if (timer) clearTimeout(timer);
3617
- };
3618
- }, [fn, running, options.throttleMs]);
3619
- var start = React.useCallback(function () {
3620
- startedAtRef.current = new Date();
3621
- setRunning(true);
3622
- }, []);
3623
- var stop = React.useCallback(function () {
3624
- loopId.current += 1; // force the loop to stop immediately.
3625
- setRunning(false);
3626
- startedAtRef.current = null;
3627
- }, []);
3628
- React.useEffect(function startAutomatically() {
3629
- if (options.autoStart) start();
3630
- return stop;
3631
- }, [options.autoStart, start, stop]);
3632
- return {
3633
- start: start,
3634
- stop: stop
3635
- };
3636
- }
3637
-
3638
- function listAvailableCameras(facingMode_1) {
3639
- return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
3640
- var cameraEnumerationStream, allDevices, allowedVideoDevices;
3641
- if (requestMicAccess === void 0) {
3642
- requestMicAccess = false;
3643
- }
3644
- return __generator(this, function (_a) {
3645
- switch (_a.label) {
3646
- case 0:
3647
- return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
3648
- video: {
3649
- facingMode: {
3650
- exact: facingMode
3651
- }
3652
- },
3653
- audio: requestMicAccess
3654
- })
3655
- // This lists all available cameras attached to the user's device.
3656
- ];
3657
- case 1:
3658
- cameraEnumerationStream = _a.sent();
3659
- return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
3660
- case 2:
3661
- allDevices = _a.sent();
3662
- allowedVideoDevices = allDevices.filter(function (_a) {
3663
- var kind = _a.kind,
3664
- label = _a.label;
3665
- return kind === 'videoinput' && !label.toLowerCase().includes('virtual');
3666
- });
3667
- // Release the access to the user's camera that we obtained for enumeration purposes.
3668
- cameraEnumerationStream.getVideoTracks().forEach(function (track) {
3669
- track.enabled = false;
3670
- track.stop();
3671
- });
3672
- cameraEnumerationStream = null;
3673
- return [2 /*return*/, allowedVideoDevices];
3674
- }
3675
- });
3676
- });
3677
- }
3678
- var frontCameraLabels = ['front', 'avant', 'anteriore', 'cameraaanvoorzijde', 'kamerapåframsidan', 'forsidekamera', 'kamerapåforsiden', 'aparatprzedni', 'etukamera', 'kameradepan', 'ÖnKamera', 'cameramặttrước', 'camerăfață', 'prednákamera', 'prednjakamera', 'előlapikamera', 'přednífotoaparát', 'μπροστινήκάμερα', 'переднякамера', 'передняякамера', 'преднакамера', 'алдыңғыкамера', 'מצלמה קדמית', 'الكاميرا الأمامية', 'फ़्रंटकैमरा', '前置相机', '前置鏡頭', '前面カメラ', '전면카메라', 'กล้องด้านหน้า'].map(function (s) {
3679
- return s.toLocaleLowerCase().split(' ').join('');
3680
- });
3681
- var rearCameraLabels = ['back', 'rear', 'posterior', 'trasera', 'traseira', 'arrière', 'rückkamera', 'fotocamera(posteriore)', 'cameraaanachterzijde', 'kamerapåbaksidan', 'kamerapåbaksiden', 'bagsidekamera', 'aparattylny', 'takakamera', 'arkakamera', 'kamerabelakang', 'cameramặtsau', 'camerăspate', 'stražnjakamera', 'zadnákamera', 'hátoldalikamera', 'zadnífotoaparát', 'πίσωκάμερα', 'заднякамера', 'Задняякамера', 'заднакамера', 'артқыкамера', 'מצלמה אחורית', 'الكاميرا الخلفية', 'बैककैमरा', '后置相机', '後置鏡頭', '背面カメラ', '후면카메라', 'กล้องด้านหลัง'].map(function (s) {
3682
- return s.toLocaleLowerCase().split(' ').join('');
3683
- });
3684
- var backUltraWideCameraLabels = ['backdualwidecamera', 'backultrawidecamera', 'ultraampliaposterior', 'ultra-angulartraseira', 'ultragrandeangulartraseira', 'ultragrandangle', 'ultragranangular', 'ultra-weitwinkelkamera', 'ultra-grandangolo', 'ultrabredecameraaanachterzijde', 'ultravidvinkelkamerapåbaksidan', 'ultravidvinkelkameraetpåbagsiden', 'ultravidvinkelkamerabak', 'ultragenişkameraarkayüzü', 'ultralaajakulmainentakakamera', 'tylnyaparatultraszerokokątny', 'cameracựcrộngmặtsau', 'camerăcuobiectivultra‑superangularspate', 'ultraszéleslátószögűkamera', 'kameraultralebarbelakang', 'stražnjaultraširokakamera', 'zadníultraširokoúhlýfotoaparát', 'ultraširokouhlá', 'πίσωυπερευρείακάμερα', 'заднянадширококутнакамера', 'Задняясверхширокоугольнаякамера', 'Задна свръх широкоъгълна камера', 'артқыультракеңбұрыштыкамера', 'מצלמה אולטרה רחבה אחורית', 'كاميرا خلفية عريضة جدًا', 'बैकअल्ट्रावाइडकैमरा', '后置超广角相机', '後置超廣角鏡頭相機', '背面超広角カメラ', '후면울트라와이드카메라', 'กล้องด้านหลังอัลตร้าไวด์'].map(function (s) {
3685
- return s.toLocaleLowerCase().split(' ').join('');
3686
- });
3687
- var cameraLabelMatches = function cameraLabelMatches(labelOrDevice, labelSetOrLabel) {
3688
- var label = labelOrDevice instanceof MediaDeviceInfo ? getDeviceLabel(labelOrDevice) : labelOrDevice;
3689
- var labelSet = typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel;
3690
- return labelSet.some(function (l) {
3691
- return label.includes(l);
3692
- });
3693
- };
3694
- var getDeviceLabel = function getDeviceLabel(deviceInfo) {
3695
- return deviceInfo.label.toLocaleLowerCase().split(' ').join('');
3696
- };
3697
- var currentCamera;
3698
- function obtainCameraAccess(stream, deviceLabel, video) {
3699
- releaseCameraAccess();
3700
- log('obtaining camera access...');
3701
- var _a = stream.getVideoTracks()[0].getSettings(),
3702
- width = _a.width,
3703
- height = _a.height;
3704
- log('camera dimensions', width, height);
3705
- var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
3706
- log('camera label', label);
3707
- var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
3708
- log('is rear facing?', isRearFacing);
3709
- var release = function release() {
3710
- stream.getTracks().forEach(function (track) {
3711
- track.enabled = false;
3712
- track.stop();
3713
- });
3714
- if (video) {
3715
- video.pause();
3716
- video.srcObject = null;
3717
- video.src = '';
3718
- }
3719
- };
3720
- width || (width = 0);
3721
- height || (height = 0);
3722
- currentCamera = {
3723
- label: deviceLabel,
3724
- stream: stream,
3725
- width: width,
3726
- height: height,
3727
- isRearFacing: isRearFacing,
3728
- release: release
3729
- };
3730
- log('camera access granted');
3731
- // if (video) video.srcObject = stream
3732
- // log('video source initialized')
3733
- return currentCamera;
3734
- }
3735
- function releaseCameraAccess() {
3736
- if (!currentCamera) return;
3737
- log('releasing camera access...');
3738
- currentCamera.release();
3739
- currentCamera = undefined;
3182
+ function releaseCameraAccess() {
3183
+ if (!currentCamera) return;
3184
+ log('releasing camera access...');
3185
+ currentCamera.release();
3186
+ currentCamera = undefined;
3740
3187
  }
3741
3188
 
3742
3189
  var en = {};
@@ -5343,224 +4790,768 @@ function CameraTamperSeal(_a) {
5343
4790
  className: classNames.message
5344
4791
  }, messageText)));
5345
4792
  }
5346
- var StyledOverlayInner$4 = styled__default.default(OverlayInner$2)(templateObject_1$M || (templateObject_1$M = __makeTemplateObject(["\n justify-content: center;\n"], ["\n justify-content: center;\n"])));
5347
- var StyledOverlayHeading = styled__default.default.h3(templateObject_2$F || (templateObject_2$F = __makeTemplateObject(["\n margin-bottom: 8px;\n"], ["\n margin-bottom: 8px;\n"])));
5348
- function useCameraStore(selector) {
5349
- var store = React.useContext(CameraStoreContext);
5350
- if (!store) throw new Error('useCameraStore cannot be used without Provider');
5351
- return zustand.useStore(store, selector);
4793
+ var StyledOverlayInner$4 = styled__default.default(OverlayInner$2)(templateObject_1$M || (templateObject_1$M = __makeTemplateObject(["\n justify-content: center;\n"], ["\n justify-content: center;\n"])));
4794
+ var StyledOverlayHeading = styled__default.default.h3(templateObject_2$F || (templateObject_2$F = __makeTemplateObject(["\n margin-bottom: 8px;\n"], ["\n margin-bottom: 8px;\n"])));
4795
+ function useCameraStore(selector) {
4796
+ var store = React.useContext(CameraStoreContext);
4797
+ if (!store) throw new Error('useCameraStore cannot be used without Provider');
4798
+ return zustand.useStore(store, selector);
4799
+ }
4800
+ var templateObject_1$M, templateObject_2$F;
4801
+
4802
+ var DocumentDetectionModelContext = /*#__PURE__*/React.createContext({
4803
+ startDocumentDetection: function startDocumentDetection() {
4804
+ return null;
4805
+ },
4806
+ stopDocumentDetection: function stopDocumentDetection() {
4807
+ return null;
4808
+ },
4809
+ loadDocumentDetectionModel: function loadDocumentDetectionModel() {
4810
+ return null;
4811
+ },
4812
+ documentDetectionModelState: 'not-started',
4813
+ documentDetectionModelDownloadProgress: 0,
4814
+ documentDetectionModelWarmingStartedAt: null,
4815
+ documentDetectionModelError: null,
4816
+ onDocumentDetected: function onDocumentDetected() {
4817
+ return null;
4818
+ },
4819
+ detectionTime: 0,
4820
+ documentDetectionThresholds: {},
4821
+ setDocumentDetectionThresholds: function setDocumentDetectionThresholds() {
4822
+ return null;
4823
+ },
4824
+ documentDetectionBoundaries: defaultDocumentDetectionBoundaries,
4825
+ setDocumentDetectionBoundaries: function setDocumentDetectionBoundaries() {
4826
+ return null;
4827
+ },
4828
+ documentDetectionLastPredictionCanvas: {
4829
+ current: null
4830
+ },
4831
+ clearDocumentDetectionLastPredictionCanvas: function clearDocumentDetectionLastPredictionCanvas() {
4832
+ return null;
4833
+ }
4834
+ });
4835
+ function DocumentDetectionModelProvider(_a) {
4836
+ var _this = this;
4837
+ var _b = _a.autoStart,
4838
+ autoStart = _b === void 0 ? true : _b,
4839
+ children = _a.children,
4840
+ _c = _a.throttleMs,
4841
+ throttleMs = _c === void 0 ? 16 : _c,
4842
+ _d = _a.delayAfterStartMs,
4843
+ delayAfterStartMs = _d === void 0 ? 0 : _d,
4844
+ _e = _a.documentDetectionModelPath,
4845
+ documentDetectionModelPath = _e === void 0 ? defaultDocumentDetectorModelPath : _e,
4846
+ _f = _a.documentDetectionModelScoreThreshold,
4847
+ documentDetectionModelScoreThreshold = _f === void 0 ? defaultDocumentDetectionScoreThreshold : _f,
4848
+ _g = _a.modelLoadTimeoutMs,
4849
+ modelLoadTimeoutMs = _g === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _g,
4850
+ onDocumentDetectionModelError = _a.onDocumentDetectionModelError,
4851
+ _h = _a.shouldLoadModels,
4852
+ shouldLoadModelsProp = _h === void 0 ? true : _h;
4853
+ var _j = useCameraStore(),
4854
+ videoRef = _j.videoRef,
4855
+ videoLoaded = _j.videoLoaded,
4856
+ cameraReady = _j.cameraReady;
4857
+ var lastPredictionCanvas = React.useRef(null);
4858
+ var onPredictionHandler = React.useRef();
4859
+ var _k = React.useState({}),
4860
+ documentDetectionThresholds = _k[0],
4861
+ setDocumentDetectionThresholds = _k[1];
4862
+ var _l = React.useState(defaultDocumentDetectionBoundaries),
4863
+ documentDetectionBoundaries = _l[0],
4864
+ setDocumentDetectionBoundaries = _l[1];
4865
+ var _m = React.useState(0),
4866
+ timesAllZero = _m[0],
4867
+ setTimesAllZero = _m[1];
4868
+ var _o = React.useState(0),
4869
+ canvasKey = _o[0],
4870
+ setCanvasKey = _o[1];
4871
+ var stopDetection = React.useRef(0);
4872
+ var _p = React.useState(shouldLoadModelsProp),
4873
+ shouldLoadModels = _p[0],
4874
+ setShouldLoadModels = _p[1];
4875
+ var load = React.useCallback(function () {
4876
+ return setShouldLoadModels(true);
4877
+ }, []);
4878
+ var _q = useLoadDocumentDetector({
4879
+ modelPath: documentDetectionModelPath,
4880
+ modelLoadTimeoutMs: modelLoadTimeoutMs,
4881
+ scoreThreshold: documentDetectionModelScoreThreshold,
4882
+ onModelError: onDocumentDetectionModelError,
4883
+ videoRef: videoRef,
4884
+ shouldLoadModels: shouldLoadModels
4885
+ }),
4886
+ ready = _q.ready,
4887
+ modelLoadState = _q.modelLoadState,
4888
+ modelDownloadProgress = _q.modelDownloadProgress,
4889
+ modelWarmingStartedAt = _q.modelWarmingStartedAt,
4890
+ modelError = _q.modelError,
4891
+ setModelError = _q.setModelError;
4892
+ var _r = useFrameLoop(React.useCallback(function (frameId, timeRunning) {
4893
+ return __awaiter(_this, void 0, void 0, function () {
4894
+ var stopDetectionAtStart, vw, vh, ctx, prediction, processedPrediction;
4895
+ var _a;
4896
+ return __generator(this, function (_b) {
4897
+ switch (_b.label) {
4898
+ case 0:
4899
+ if (!videoLoaded || !cameraReady || !ready || !videoRef.current || !lastPredictionCanvas.current) return [2 /*return*/];
4900
+ stopDetectionAtStart = stopDetection.current;
4901
+ vw = videoRef.current.videoWidth;
4902
+ vh = videoRef.current.videoHeight;
4903
+ lastPredictionCanvas.current.width = vw;
4904
+ lastPredictionCanvas.current.height = vh;
4905
+ ctx = lastPredictionCanvas.current.getContext('2d');
4906
+ if (!(ctx && videoRef.current.readyState === 4)) return [3 /*break*/, 3];
4907
+ if (stopDetectionAtStart !== stopDetection.current) return [2 /*return*/];
4908
+ ctx.drawImage(videoRef.current, 0, 0, vw, vh);
4909
+ return [4 /*yield*/, makeDocumentDetectorPrediction(lastPredictionCanvas.current)];
4910
+ case 1:
4911
+ prediction = _b.sent();
4912
+ if (!prediction) return [3 /*break*/, 3];
4913
+ processedPrediction = processDocumentDetectorPrediction(prediction, documentDetectionThresholds, documentDetectionBoundaries);
4914
+ processedPrediction.frameId = frameId;
4915
+ setLastDetectionAt(new Date().getTime());
4916
+ debug(processedPrediction);
4917
+ if (processedPrediction.allZero) setTimesAllZero(function (n) {
4918
+ return n + 1;
4919
+ });
4920
+ if (stopDetectionAtStart !== stopDetection.current) return [2 /*return*/];
4921
+ if (timeRunning < delayAfterStartMs) return [2 /*return*/];
4922
+ return [4 /*yield*/, (_a = onPredictionHandler.current) === null || _a === void 0 ? void 0 : _a.call(onPredictionHandler, processedPrediction)];
4923
+ case 2:
4924
+ _b.sent();
4925
+ _b.label = 3;
4926
+ case 3:
4927
+ return [2 /*return*/];
4928
+ }
4929
+ });
4930
+ });
4931
+ }, [cameraReady, delayAfterStartMs, documentDetectionBoundaries, documentDetectionThresholds, ready, videoLoaded, videoRef]), {
4932
+ throttleMs: throttleMs,
4933
+ autoStart: autoStart
4934
+ }),
4935
+ start = _r.start,
4936
+ stop = _r.stop;
4937
+ React.useEffect(function setErrorIfAllZero() {
4938
+ if (timesAllZero >= 2) {
4939
+ setModelError(new Error('model is returning all zeroes'));
4940
+ }
4941
+ }, [setModelError, timesAllZero]);
4942
+ var onDocumentDetected = React.useCallback(function (handler) {
4943
+ onPredictionHandler.current = handler;
4944
+ }, []);
4945
+ var clearDocumentDetectionLastPredictionCanvas = React.useCallback(function () {
4946
+ stopDetection.current += 1;
4947
+ setCanvasKey(function (n) {
4948
+ return n + 1;
4949
+ });
4950
+ }, []);
4951
+ var value = React.useMemo(function () {
4952
+ return {
4953
+ startDocumentDetection: start,
4954
+ stopDocumentDetection: stop,
4955
+ loadDocumentDetectionModel: load,
4956
+ documentDetectionModelState: modelLoadState,
4957
+ documentDetectionModelWarmingStartedAt: modelWarmingStartedAt,
4958
+ documentDetectionModelError: modelError,
4959
+ documentDetectionModelDownloadProgress: modelDownloadProgress,
4960
+ onDocumentDetected: onDocumentDetected,
4961
+ detectionTime: lastDetectionTime,
4962
+ documentDetectionThresholds: documentDetectionThresholds,
4963
+ setDocumentDetectionThresholds: setDocumentDetectionThresholds,
4964
+ documentDetectionBoundaries: documentDetectionBoundaries,
4965
+ setDocumentDetectionBoundaries: setDocumentDetectionBoundaries,
4966
+ documentDetectionLastPredictionCanvas: lastPredictionCanvas,
4967
+ clearDocumentDetectionLastPredictionCanvas: clearDocumentDetectionLastPredictionCanvas
4968
+ };
4969
+ }, [start, stop, load, modelLoadState, modelWarmingStartedAt, modelError, modelDownloadProgress, onDocumentDetected, documentDetectionThresholds, documentDetectionBoundaries, clearDocumentDetectionLastPredictionCanvas]);
4970
+ return /*#__PURE__*/React__namespace.createElement(DocumentDetectionModelContext.Provider, {
4971
+ value: value
4972
+ }, /*#__PURE__*/React__namespace.createElement(InvisibleCanvas, {
4973
+ key: canvasKey,
4974
+ ref: lastPredictionCanvas
4975
+ }), children);
4976
+ }
4977
+
4978
+ function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
4979
+ var _a;
4980
+ if (quality === void 0) {
4981
+ quality = 0.92;
4982
+ }
4983
+ if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
4984
+ var rawCtx = rawCanvas.getContext('2d');
4985
+ var cropCtx = cropCanvas.getContext('2d');
4986
+ var resizeCtx = resizeCanvas.getContext('2d');
4987
+ if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
4988
+ rawCanvas.width = frame.width;
4989
+ rawCanvas.height = frame.height;
4990
+ rawCtx.putImageData(frame, 0, 0);
4991
+ if (frame.height > frame.width) {
4992
+ cropCanvas.width = frame.width;
4993
+ cropCanvas.height = frame.height;
4994
+ cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
4995
+ } else {
4996
+ var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
4997
+ xMin: 0,
4998
+ width: frame.width
4999
+ },
5000
+ xMin = _b.xMin,
5001
+ width = _b.width;
5002
+ var desiredWidth = frame.height * 0.6;
5003
+ var faceCenterX = xMin + width / 2;
5004
+ var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
5005
+ cropCanvas.width = desiredWidth;
5006
+ cropCanvas.height = frame.height;
5007
+ cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
5008
+ }
5009
+ resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
5010
+ resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
5011
+ resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
5012
+ var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
5013
+ log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
5014
+ clearCanvas(rawCanvas);
5015
+ clearCanvas(cropCanvas);
5016
+ clearCanvas(resizeCanvas);
5017
+ return dataURL;
5018
+ }
5019
+ function cropToDetectedObjectBox(frame, box, canvas, padding) {
5020
+ if (padding === void 0) {
5021
+ padding = 0;
5022
+ }
5023
+ canvas || (canvas = document.createElement('canvas'));
5024
+ var ctx = canvas.getContext('2d');
5025
+ if (!ctx) throw new Error('could not get 2d context');
5026
+ var xMin = box.xMin,
5027
+ yMin = box.yMin,
5028
+ width = box.width,
5029
+ height = box.height;
5030
+ canvas.width = width + padding * 2;
5031
+ canvas.height = height + padding * 2;
5032
+ ctx.drawImage(frame, xMin - padding, yMin - padding, width + padding * 2, height + padding * 2, 0, 0, canvas.width, canvas.height);
5033
+ return canvas;
5034
+ }
5035
+ function cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box, padding) {
5036
+ if (padding === void 0) {
5037
+ padding = 0;
5038
+ }
5039
+ if (!box) return imageData;
5040
+ var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas, padding);
5041
+ var _a = [box.width, box.height],
5042
+ bw = _a[0],
5043
+ bh = _a[1];
5044
+ if (bh <= bw) return cropped;
5045
+ var ctx = rotateCanvas.getContext('2d');
5046
+ if (!ctx) return cropped;
5047
+ rotateCanvas.width = bh;
5048
+ rotateCanvas.height = bw;
5049
+ ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
5050
+ ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
5051
+ ctx.rotate(1.5708); // 90 deg in radians
5052
+ ctx.drawImage(cropped, -bw / 2, -bh / 2);
5053
+ return rotateCanvas;
5054
+ }
5055
+ function resizeIfNecessary(imageData, resizeCanvas, maxWidth) {
5056
+ var width = imageData.width,
5057
+ height = imageData.height;
5058
+ if (width <= maxWidth) return imageData;
5059
+ var resizeCtx = resizeCanvas.getContext('2d');
5060
+ if (!resizeCtx) return imageData;
5061
+ var scale = maxWidth / width;
5062
+ resizeCanvas.width = maxWidth;
5063
+ resizeCanvas.height = height * scale;
5064
+ resizeCtx.drawImage(imageData, 0, 0, resizeCanvas.width, resizeCanvas.height);
5065
+ return resizeCanvas;
5352
5066
  }
5353
- var templateObject_1$M, templateObject_2$F;
5354
5067
 
5355
- var DocumentDetectionModelContext = /*#__PURE__*/React.createContext({
5356
- startDocumentDetection: function startDocumentDetection() {
5357
- return null;
5358
- },
5359
- stopDocumentDetection: function stopDocumentDetection() {
5360
- return null;
5361
- },
5362
- loadDocumentDetectionModel: function loadDocumentDetectionModel() {
5363
- return null;
5364
- },
5365
- documentDetectionModelState: 'not-started',
5366
- documentDetectionModelDownloadProgress: 0,
5367
- documentDetectionModelWarmingStartedAt: null,
5368
- documentDetectionModelError: null,
5369
- onDocumentDetected: function onDocumentDetected() {
5370
- return null;
5371
- },
5372
- detectionTime: 0,
5373
- documentDetectionThresholds: {},
5374
- setDocumentDetectionThresholds: function setDocumentDetectionThresholds() {
5375
- return null;
5068
+ var defaultFocusModelLoadTimeoutMs = 45000;
5069
+ var defaultFocusThresholds = {
5070
+ idCardFront: {
5071
+ desktop: 0,
5072
+ mobile: 0.3
5376
5073
  },
5377
- documentDetectionBoundaries: defaultDocumentDetectionBoundaries,
5378
- setDocumentDetectionBoundaries: function setDocumentDetectionBoundaries() {
5379
- return null;
5074
+ idCardBack: {
5075
+ desktop: 0,
5076
+ mobile: 0.3
5380
5077
  },
5381
- documentDetectionLastPredictionCanvas: {
5382
- current: null
5078
+ passport: {
5079
+ desktop: 0,
5080
+ mobile: 0.3
5383
5081
  },
5384
- clearDocumentDetectionLastPredictionCanvas: function clearDocumentDetectionLastPredictionCanvas() {
5385
- return null;
5082
+ singlePage: {
5083
+ desktop: 0,
5084
+ mobile: 0.3
5386
5085
  }
5387
- });
5388
- function DocumentDetectionModelProvider(_a) {
5389
- var _this = this;
5390
- var _b = _a.autoStart,
5391
- autoStart = _b === void 0 ? true : _b,
5392
- children = _a.children,
5393
- _c = _a.throttleMs,
5394
- throttleMs = _c === void 0 ? 16 : _c,
5395
- _d = _a.delayAfterStartMs,
5396
- delayAfterStartMs = _d === void 0 ? 0 : _d,
5397
- _e = _a.documentDetectionModelPath,
5398
- documentDetectionModelPath = _e === void 0 ? defaultDocumentDetectorModelPath : _e,
5399
- _f = _a.documentDetectionModelScoreThreshold,
5400
- documentDetectionModelScoreThreshold = _f === void 0 ? defaultDocumentDetectionScoreThreshold : _f,
5401
- _g = _a.modelLoadTimeoutMs,
5402
- modelLoadTimeoutMs = _g === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _g,
5403
- onDocumentDetectionModelError = _a.onDocumentDetectionModelError,
5404
- _h = _a.shouldLoadModels,
5405
- shouldLoadModelsProp = _h === void 0 ? true : _h;
5406
- var _j = useCameraStore(),
5407
- videoRef = _j.videoRef,
5408
- videoLoaded = _j.videoLoaded,
5409
- cameraReady = _j.cameraReady;
5410
- var lastPredictionCanvas = React.useRef(null);
5411
- var onPredictionHandler = React.useRef();
5412
- var _k = React.useState({}),
5413
- documentDetectionThresholds = _k[0],
5414
- setDocumentDetectionThresholds = _k[1];
5415
- var _l = React.useState(defaultDocumentDetectionBoundaries),
5416
- documentDetectionBoundaries = _l[0],
5417
- setDocumentDetectionBoundaries = _l[1];
5418
- var _m = React.useState(0),
5419
- timesAllZero = _m[0],
5420
- setTimesAllZero = _m[1];
5421
- var _o = React.useState(0),
5422
- canvasKey = _o[0],
5423
- setCanvasKey = _o[1];
5424
- var stopDetection = React.useRef(0);
5425
- var _p = React.useState(shouldLoadModelsProp),
5426
- shouldLoadModels = _p[0],
5427
- setShouldLoadModels = _p[1];
5086
+ };
5087
+ var classifier$1 = null;
5088
+ var classifierSettings$1 = null;
5089
+ function loadFocusModel() {
5090
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
5091
+ var _a, _b;
5092
+ if (modelAssetPath === void 0) {
5093
+ modelAssetPath = defaultFocusModelPath;
5094
+ }
5095
+ return __generator(this, function (_c) {
5096
+ switch (_c.label) {
5097
+ case 0:
5098
+ if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier$1];
5099
+ closeFocusModel();
5100
+ return [4 /*yield*/, preloadFocusModelDependencies()];
5101
+ case 1:
5102
+ _c.sent();
5103
+ if (modelCapabilities.delegate === 'NONE') {
5104
+ throw new Error('No available delegate for focus detector.');
5105
+ }
5106
+ _b = (_a = tasksVision.ImageClassifier).createFromOptions;
5107
+ return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
5108
+ case 2:
5109
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
5110
+ baseOptions: {
5111
+ modelAssetPath: modelAssetPath,
5112
+ delegate: modelCapabilities.delegate
5113
+ },
5114
+ // canvas: document.createElement('canvas'),
5115
+ runningMode: 'VIDEO'
5116
+ }])];
5117
+ case 3:
5118
+ classifier$1 = _c.sent();
5119
+ classifierSettings$1 = {
5120
+ modelAssetPath: modelAssetPath
5121
+ };
5122
+ return [2 /*return*/, classifier$1];
5123
+ }
5124
+ });
5125
+ });
5126
+ }
5127
+ function closeFocusModel() {
5128
+ classifier$1 === null || classifier$1 === void 0 ? void 0 : classifier$1.close();
5129
+ classifier$1 = null;
5130
+ classifierSettings$1 = null;
5131
+ }
5132
+ function useLoadFocusModel(_a) {
5133
+ var _b = _a.modelPath,
5134
+ modelPath = _b === void 0 ? defaultFocusModelPath : _b,
5135
+ _c = _a.modelLoadTimeoutMs,
5136
+ modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
5137
+ onModelError = _a.onModelError,
5138
+ videoRef = _a.videoRef,
5139
+ _d = _a.shouldLoadModels,
5140
+ shouldLoadModels = _d === void 0 ? true : _d;
5141
+ var _e = React.useState('not-started'),
5142
+ modelLoadState = _e[0],
5143
+ setModelLoadState = _e[1];
5144
+ var _f = React.useState(0),
5145
+ modelDownloadProgress = _f[0],
5146
+ setModelDownloadProgress = _f[1];
5147
+ var _g = React.useState(null),
5148
+ modelWarmingStartedAt = _g[0],
5149
+ setModelWarmingStartedAt = _g[1];
5150
+ var _h = React.useState(null),
5151
+ modelError = _h[0],
5152
+ setModelError = _h[1];
5153
+ React.useEffect(function loadModel() {
5154
+ var _this = this;
5155
+ if (!shouldLoadModels) return;
5156
+ setModelLoadState('downloading');
5157
+ setModelWarmingStartedAt(null);
5158
+ function handleDownloadProgress(event) {
5159
+ setModelDownloadProgress(progressToPercentage(event.detail));
5160
+ }
5161
+ document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
5162
+ var modelLoadTimeout = setTimeout(function () {
5163
+ setModelError(new Error('Model loading time limit exceeded.'));
5164
+ }, modelLoadTimeoutMs);
5165
+ var cancelVideoReady = function cancelVideoReady() {};
5166
+ loadFocusModel(modelPath).then(function (loadedModel) {
5167
+ return __awaiter(_this, void 0, void 0, function () {
5168
+ var _a, videoReady, cancel, cancelled;
5169
+ return __generator(this, function (_b) {
5170
+ switch (_b.label) {
5171
+ case 0:
5172
+ setModelDownloadProgress(100);
5173
+ clearTimeout(modelLoadTimeout);
5174
+ setModelLoadState('warming');
5175
+ setModelWarmingStartedAt(performance.now());
5176
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
5177
+ cancelled = false;
5178
+ cancelVideoReady = function cancelVideoReady() {
5179
+ cancelled = true;
5180
+ cancel();
5181
+ };
5182
+ return [4 /*yield*/, videoReady];
5183
+ case 1:
5184
+ _b.sent();
5185
+ setTimeout(function () {
5186
+ if (cancelled) return;
5187
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
5188
+ setModelLoadState('ready');
5189
+ }, 500);
5190
+ return [2 /*return*/];
5191
+ }
5192
+ });
5193
+ });
5194
+ })["catch"](function (e) {
5195
+ setModelError(e);
5196
+ setModelLoadState('error');
5197
+ })["finally"](function () {
5198
+ clearTimeout(modelLoadTimeout);
5199
+ });
5200
+ return function () {
5201
+ log('unloading focus model');
5202
+ cancelVideoReady();
5203
+ closeFocusModel();
5204
+ clearTimeout(modelLoadTimeout);
5205
+ document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
5206
+ };
5207
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
5208
+ React.useEffect(function handleModelError() {
5209
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
5210
+ }, [modelError, onModelError]);
5211
+ return React.useMemo(function () {
5212
+ return {
5213
+ ready: modelLoadState === 'ready',
5214
+ modelLoadState: modelLoadState,
5215
+ modelDownloadProgress: modelDownloadProgress,
5216
+ modelWarmingStartedAt: modelWarmingStartedAt,
5217
+ modelError: modelError
5218
+ };
5219
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
5220
+ }
5221
+ var lastFocusPredictionAt = 0;
5222
+ var lastFocusPredictionTime = 0;
5223
+ function setLastFocusPredictionAt(time) {
5224
+ lastFocusPredictionTime = time - lastFocusPredictionAt;
5225
+ lastFocusPredictionAt = time;
5226
+ }
5227
+ function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
5228
+ var _a, _b, _c, _d, _e;
5229
+ if (!classifier$1) return null;
5230
+ var startedAt = performance.now();
5231
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
5232
+ var result = classifier$1.classifyForVideo(image, performance.now());
5233
+ 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) {
5234
+ return c.categoryName === 'focused';
5235
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
5236
+ var predictionTime = performance.now() - startedAt;
5237
+ return {
5238
+ score: score,
5239
+ predictionTime: predictionTime
5240
+ };
5241
+ }
5242
+
5243
+ var FocusModelContext = /*#__PURE__*/React.createContext({
5244
+ loadFocusModel: function loadFocusModel() {
5245
+ return null;
5246
+ },
5247
+ focusModelState: 'not-started',
5248
+ focusModelDownloadProgress: 0,
5249
+ focusModelWarmingStartedAt: null,
5250
+ focusModelError: null,
5251
+ focusThresholds: {},
5252
+ setFocusThresholds: function setFocusThresholds() {
5253
+ return null;
5254
+ },
5255
+ makeFocusPrediction: function makeFocusPrediction() {
5256
+ return null;
5257
+ },
5258
+ focusPredictionTime: 0
5259
+ });
5260
+ function FocusModelProvider(_a) {
5261
+ var children = _a.children,
5262
+ _b = _a.focusModelPath,
5263
+ focusModelPath = _b === void 0 ? defaultFocusModelPath : _b,
5264
+ _c = _a.focusModelLoadTimeoutMs,
5265
+ focusModelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
5266
+ onFocusModelError = _a.onFocusModelError,
5267
+ _d = _a.showCanvases,
5268
+ showCanvases = _d === void 0 ? false : _d,
5269
+ _e = _a.shouldLoadModels,
5270
+ shouldLoadModelsProp = _e === void 0 ? true : _e;
5271
+ var cropCanvas = React.useRef(null);
5272
+ var rotateCanvas = React.useRef(null);
5273
+ var _f = React.useState({}),
5274
+ focusThresholds = _f[0],
5275
+ setFocusThresholds = _f[1];
5276
+ var videoRef = useCameraStore().videoRef;
5277
+ var _g = React.useState(shouldLoadModelsProp),
5278
+ shouldLoadModels = _g[0],
5279
+ setShouldLoadModels = _g[1];
5428
5280
  var load = React.useCallback(function () {
5429
5281
  return setShouldLoadModels(true);
5430
5282
  }, []);
5431
- var _q = useLoadDocumentDetector({
5432
- modelPath: documentDetectionModelPath,
5433
- modelLoadTimeoutMs: modelLoadTimeoutMs,
5434
- scoreThreshold: documentDetectionModelScoreThreshold,
5435
- onModelError: onDocumentDetectionModelError,
5283
+ var _h = useLoadFocusModel({
5284
+ modelPath: focusModelPath,
5285
+ modelLoadTimeoutMs: focusModelLoadTimeoutMs,
5286
+ onModelError: onFocusModelError,
5436
5287
  videoRef: videoRef,
5437
5288
  shouldLoadModels: shouldLoadModels
5438
5289
  }),
5439
- ready = _q.ready,
5440
- modelLoadState = _q.modelLoadState,
5441
- modelDownloadProgress = _q.modelDownloadProgress,
5442
- modelWarmingStartedAt = _q.modelWarmingStartedAt,
5443
- modelError = _q.modelError,
5444
- setModelError = _q.setModelError;
5445
- var _r = useFrameLoop(React.useCallback(function (frameId, timeRunning) {
5290
+ ready = _h.ready,
5291
+ modelLoadState = _h.modelLoadState,
5292
+ modelDownloadProgress = _h.modelDownloadProgress,
5293
+ modelWarmingStartedAt = _h.modelWarmingStartedAt,
5294
+ modelError = _h.modelError;
5295
+ var makeFocusPrediction = React.useCallback(function (imageData, box) {
5296
+ if (!ready) return null;
5297
+ var prediction = makeFocusModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, box);
5298
+ if (!prediction) return null;
5299
+ setLastFocusPredictionAt(prediction.predictionTime);
5300
+ return prediction;
5301
+ }, [ready]);
5302
+ var value = React.useMemo(function () {
5303
+ return {
5304
+ loadFocusModel: load,
5305
+ focusModelState: modelLoadState,
5306
+ focusModelDownloadProgress: modelDownloadProgress,
5307
+ focusModelWarmingStartedAt: modelWarmingStartedAt,
5308
+ focusModelError: modelError,
5309
+ makeFocusPrediction: makeFocusPrediction,
5310
+ focusPredictionTime: lastFocusPredictionTime,
5311
+ focusThresholds: focusThresholds,
5312
+ setFocusThresholds: setFocusThresholds
5313
+ };
5314
+ }, [focusThresholds, load, makeFocusPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
5315
+ return /*#__PURE__*/React__namespace.default.createElement(FocusModelContext.Provider, {
5316
+ value: value
5317
+ }, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5318
+ ref: rotateCanvas,
5319
+ style: showCanvases ? {
5320
+ display: 'block'
5321
+ } : undefined
5322
+ }), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5323
+ ref: cropCanvas,
5324
+ style: showCanvases ? {
5325
+ display: 'block'
5326
+ } : undefined
5327
+ })), children);
5328
+ }
5329
+
5330
+ function _isNavigatorDefined() {
5331
+ return typeof navigator !== 'undefined' && navigator != null;
5332
+ }
5333
+ var isMobileCache;
5334
+ function isMobile() {
5335
+ if (isMobileCache !== undefined) return isMobileCache;
5336
+ isMobileCache = evaluateIsMobile();
5337
+ return isMobileCache;
5338
+ }
5339
+ function evaluateIsMobile(nav) {
5340
+ if (nav || _isNavigatorDefined()) {
5341
+ if (!nav) {
5342
+ nav = navigator;
5343
+ }
5344
+ if (nav.product === 'ReactNative') {
5345
+ return true;
5346
+ }
5347
+ var a = nav.userAgent || nav.vendor || (
5348
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5349
+ // @ts-ignore
5350
+ typeof window !== 'undefined' ? window.opera : '');
5351
+ if (!a) {
5352
+ var navAny = nav;
5353
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5354
+ // @ts-ignore
5355
+ return navAny.userAgentData && navAny.userAgentData.mobile;
5356
+ }
5357
+ return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4));
5358
+ }
5359
+ return false;
5360
+ }
5361
+
5362
+ var defaultBarcodeReadabilityModelLoadTimeoutMs = 45000;
5363
+ var classifier = null;
5364
+ var classifierSettings = null;
5365
+ function loadBarcodeReadabilityModel() {
5366
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
5367
+ var _a, _b;
5368
+ if (modelAssetPath === void 0) {
5369
+ modelAssetPath = defaultBarcodeReadabilityModelPath;
5370
+ }
5371
+ return __generator(this, function (_c) {
5372
+ switch (_c.label) {
5373
+ case 0:
5374
+ if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
5375
+ closeBarcodeReadabilityModel();
5376
+ return [4 /*yield*/, preloadBarcodeReadabilityModelDependencies()];
5377
+ case 1:
5378
+ _c.sent();
5379
+ if (modelCapabilities.delegate === 'NONE') {
5380
+ throw new Error('No available delegate for barcode readability model.');
5381
+ }
5382
+ _b = (_a = tasksVision.ImageClassifier).createFromOptions;
5383
+ return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
5384
+ case 2:
5385
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
5386
+ baseOptions: {
5387
+ modelAssetPath: modelAssetPath,
5388
+ delegate: 'CPU'
5389
+ },
5390
+ runningMode: 'VIDEO',
5391
+ maxResults: 1
5392
+ }])];
5393
+ case 3:
5394
+ classifier = _c.sent();
5395
+ classifierSettings = {
5396
+ modelAssetPath: modelAssetPath
5397
+ };
5398
+ return [2 /*return*/, classifier];
5399
+ }
5400
+ });
5401
+ });
5402
+ }
5403
+ function closeBarcodeReadabilityModel() {
5404
+ classifier === null || classifier === void 0 ? void 0 : classifier.close();
5405
+ classifier = null;
5406
+ classifierSettings = null;
5407
+ }
5408
+ function useLoadBarcodeReadabilityModel(_a) {
5409
+ var _b = _a.modelPath,
5410
+ modelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
5411
+ _c = _a.modelLoadTimeoutMs,
5412
+ modelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
5413
+ onModelError = _a.onModelError,
5414
+ videoRef = _a.videoRef,
5415
+ _d = _a.shouldLoadModels,
5416
+ shouldLoadModels = _d === void 0 ? true : _d;
5417
+ var _e = React.useState('not-started'),
5418
+ modelLoadState = _e[0],
5419
+ setModelLoadState = _e[1];
5420
+ var _f = React.useState(0),
5421
+ modelDownloadProgress = _f[0],
5422
+ setModelDownloadProgress = _f[1];
5423
+ var _g = React.useState(null),
5424
+ modelWarmingStartedAt = _g[0],
5425
+ setModelWarmingStartedAt = _g[1];
5426
+ var _h = React.useState(null),
5427
+ modelError = _h[0],
5428
+ setModelError = _h[1];
5429
+ React.useEffect(function loadModel() {
5430
+ var _this = this;
5431
+ if (!shouldLoadModels) return;
5432
+ setModelLoadState('downloading');
5433
+ setModelWarmingStartedAt(null);
5434
+ function handleDownloadProgress(event) {
5435
+ setModelDownloadProgress(progressToPercentage(event.detail));
5436
+ }
5437
+ document.addEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
5438
+ var modelLoadTimeout = setTimeout(function () {
5439
+ setModelError(new Error('Model loading time limit exceeded.'));
5440
+ }, modelLoadTimeoutMs);
5441
+ var cancelVideoReady = function cancelVideoReady() {};
5442
+ loadBarcodeReadabilityModel(modelPath).then(function (loadedModel) {
5446
5443
  return __awaiter(_this, void 0, void 0, function () {
5447
- var stopDetectionAtStart, vw, vh, ctx, prediction, processedPrediction;
5448
- var _a;
5444
+ var _a, videoReady, cancel, cancelled;
5449
5445
  return __generator(this, function (_b) {
5450
5446
  switch (_b.label) {
5451
5447
  case 0:
5452
- if (!videoLoaded || !cameraReady || !ready || !videoRef.current || !lastPredictionCanvas.current) return [2 /*return*/];
5453
- stopDetectionAtStart = stopDetection.current;
5454
- vw = videoRef.current.videoWidth;
5455
- vh = videoRef.current.videoHeight;
5456
- lastPredictionCanvas.current.width = vw;
5457
- lastPredictionCanvas.current.height = vh;
5458
- ctx = lastPredictionCanvas.current.getContext('2d');
5459
- if (!(ctx && videoRef.current.readyState === 4)) return [3 /*break*/, 3];
5460
- if (stopDetectionAtStart !== stopDetection.current) return [2 /*return*/];
5461
- ctx.drawImage(videoRef.current, 0, 0, vw, vh);
5462
- return [4 /*yield*/, makeDocumentDetectorPrediction(lastPredictionCanvas.current)];
5448
+ setModelDownloadProgress(100);
5449
+ clearTimeout(modelLoadTimeout);
5450
+ setModelLoadState('warming');
5451
+ setModelWarmingStartedAt(new Date().getTime());
5452
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
5453
+ cancelled = false;
5454
+ cancelVideoReady = function cancelVideoReady() {
5455
+ cancelled = true;
5456
+ cancel();
5457
+ };
5458
+ return [4 /*yield*/, videoReady];
5463
5459
  case 1:
5464
- prediction = _b.sent();
5465
- if (!prediction) return [3 /*break*/, 3];
5466
- processedPrediction = processDocumentDetectorPrediction(prediction, documentDetectionThresholds, documentDetectionBoundaries);
5467
- processedPrediction.frameId = frameId;
5468
- setLastDetectionAt(new Date().getTime());
5469
- debug(processedPrediction);
5470
- if (processedPrediction.allZero) setTimesAllZero(function (n) {
5471
- return n + 1;
5472
- });
5473
- if (stopDetectionAtStart !== stopDetection.current) return [2 /*return*/];
5474
- if (timeRunning < delayAfterStartMs) return [2 /*return*/];
5475
- return [4 /*yield*/, (_a = onPredictionHandler.current) === null || _a === void 0 ? void 0 : _a.call(onPredictionHandler, processedPrediction)];
5476
- case 2:
5477
5460
  _b.sent();
5478
- _b.label = 3;
5479
- case 3:
5480
- return [2 /*return*/];
5481
- }
5482
- });
5483
- });
5484
- }, [cameraReady, delayAfterStartMs, documentDetectionBoundaries, documentDetectionThresholds, ready, videoLoaded, videoRef]), {
5485
- throttleMs: throttleMs,
5486
- autoStart: autoStart
5487
- }),
5488
- start = _r.start,
5489
- stop = _r.stop;
5490
- React.useEffect(function setErrorIfAllZero() {
5491
- if (timesAllZero >= 2) {
5492
- setModelError(new Error('model is returning all zeroes'));
5493
- }
5494
- }, [setModelError, timesAllZero]);
5495
- var onDocumentDetected = React.useCallback(function (handler) {
5496
- onPredictionHandler.current = handler;
5497
- }, []);
5498
- var clearDocumentDetectionLastPredictionCanvas = React.useCallback(function () {
5499
- stopDetection.current += 1;
5500
- setCanvasKey(function (n) {
5501
- return n + 1;
5461
+ setTimeout(function () {
5462
+ if (cancelled) return;
5463
+ loadedModel.classifyForVideo(videoRef.current, performance.now());
5464
+ setModelLoadState('ready');
5465
+ }, 500);
5466
+ return [2 /*return*/];
5467
+ }
5468
+ });
5469
+ });
5470
+ })["catch"](function (e) {
5471
+ setModelError(e);
5472
+ setModelLoadState('error');
5473
+ })["finally"](function () {
5474
+ clearTimeout(modelLoadTimeout);
5502
5475
  });
5503
- }, []);
5504
- var value = React.useMemo(function () {
5476
+ return function () {
5477
+ log('unloading barcode readability model');
5478
+ cancelVideoReady();
5479
+ closeBarcodeReadabilityModel();
5480
+ clearTimeout(modelLoadTimeout);
5481
+ document.removeEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
5482
+ };
5483
+ }, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
5484
+ React.useEffect(function handleModelError() {
5485
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
5486
+ }, [modelError, onModelError]);
5487
+ return React.useMemo(function () {
5505
5488
  return {
5506
- startDocumentDetection: start,
5507
- stopDocumentDetection: stop,
5508
- loadDocumentDetectionModel: load,
5509
- documentDetectionModelState: modelLoadState,
5510
- documentDetectionModelWarmingStartedAt: modelWarmingStartedAt,
5511
- documentDetectionModelError: modelError,
5512
- documentDetectionModelDownloadProgress: modelDownloadProgress,
5513
- onDocumentDetected: onDocumentDetected,
5514
- detectionTime: lastDetectionTime,
5515
- documentDetectionThresholds: documentDetectionThresholds,
5516
- setDocumentDetectionThresholds: setDocumentDetectionThresholds,
5517
- documentDetectionBoundaries: documentDetectionBoundaries,
5518
- setDocumentDetectionBoundaries: setDocumentDetectionBoundaries,
5519
- documentDetectionLastPredictionCanvas: lastPredictionCanvas,
5520
- clearDocumentDetectionLastPredictionCanvas: clearDocumentDetectionLastPredictionCanvas
5489
+ ready: modelLoadState === 'ready',
5490
+ modelLoadState: modelLoadState,
5491
+ modelDownloadProgress: modelDownloadProgress,
5492
+ modelWarmingStartedAt: modelWarmingStartedAt,
5493
+ modelError: modelError
5521
5494
  };
5522
- }, [start, stop, load, modelLoadState, modelWarmingStartedAt, modelError, modelDownloadProgress, onDocumentDetected, documentDetectionThresholds, documentDetectionBoundaries, clearDocumentDetectionLastPredictionCanvas]);
5523
- return /*#__PURE__*/React__namespace.createElement(DocumentDetectionModelContext.Provider, {
5524
- value: value
5525
- }, /*#__PURE__*/React__namespace.createElement(InvisibleCanvas, {
5526
- key: canvasKey,
5527
- ref: lastPredictionCanvas
5528
- }), children);
5495
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
5496
+ }
5497
+ var lastBarcodeReadabilityPredictionAt = 0;
5498
+ var lastBarcodeReadabilityPredictionTime = 0;
5499
+ function setLastBarcodeReadabilityPredictionAt(time) {
5500
+ lastBarcodeReadabilityPredictionTime = time - lastBarcodeReadabilityPredictionAt;
5501
+ lastBarcodeReadabilityPredictionAt = time;
5502
+ }
5503
+ function makeBarcodeReadabilityModelPrediction(imageData, cropCanvas, rotateCanvas, resizeCanvas, box) {
5504
+ var _a, _b, _c, _d, _e;
5505
+ if (!classifier) return null;
5506
+ var startedAt = performance.now();
5507
+ var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
5508
+ var resized = resizeIfNecessary(image, resizeCanvas, 500);
5509
+ var result = classifier.classifyForVideo(resized, performance.now());
5510
+ 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) {
5511
+ return c.categoryName === 'blurry';
5512
+ })) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
5513
+ debug('barcode prediction', "".concat(performance.now() - startedAt, "ms"), score);
5514
+ var predictionTime = performance.now() - startedAt;
5515
+ return {
5516
+ score: score,
5517
+ predictionTime: predictionTime
5518
+ };
5529
5519
  }
5530
5520
 
5531
- var FocusModelContext = /*#__PURE__*/React.createContext({
5532
- loadFocusModel: function loadFocusModel() {
5521
+ var BarcodeReadabilityModelContext = /*#__PURE__*/React.createContext({
5522
+ loadBarcodeReadabilityModel: function loadBarcodeReadabilityModel() {
5533
5523
  return null;
5534
5524
  },
5535
- focusModelState: 'not-started',
5536
- focusModelDownloadProgress: 0,
5537
- focusModelWarmingStartedAt: null,
5538
- focusModelError: null,
5539
- focusThresholds: {},
5540
- setFocusThresholds: function setFocusThresholds() {
5525
+ barcodeReadabilityModelState: 'not-started',
5526
+ barcodeReadabilityModelDownloadProgress: 0,
5527
+ barcodeReadabilityModelWarmingStartedAt: null,
5528
+ barcodeReadabilityModelError: null,
5529
+ barcodeReadabilityThresholds: {},
5530
+ setBarcodeReadabilityThresholds: function setBarcodeReadabilityThresholds() {
5541
5531
  return null;
5542
5532
  },
5543
- makeFocusPrediction: function makeFocusPrediction() {
5533
+ makeBarcodeReadabilityPrediction: function makeBarcodeReadabilityPrediction() {
5544
5534
  return null;
5545
5535
  },
5546
- focusPredictionTime: 0
5536
+ barcodeReadabilityPredictionTime: 0
5547
5537
  });
5548
- function FocusModelProvider(_a) {
5538
+ function BarcodeReadabilityModelProvider(_a) {
5549
5539
  var children = _a.children,
5550
- _b = _a.focusModelPath,
5551
- focusModelPath = _b === void 0 ? defaultFocusModelPath : _b,
5552
- _c = _a.focusModelLoadTimeoutMs,
5553
- focusModelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
5554
- onFocusModelError = _a.onFocusModelError,
5540
+ _b = _a.barcodeReadabilityModelPath,
5541
+ barcodeReadabilityModelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
5542
+ _c = _a.barcodeReadabilityModelLoadTimeoutMs,
5543
+ barcodeReadabilityModelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
5544
+ onBarcodeReadabilityModelError = _a.onBarcodeReadabilityModelError,
5555
5545
  _d = _a.showCanvases,
5556
5546
  showCanvases = _d === void 0 ? false : _d,
5557
5547
  _e = _a.shouldLoadModels,
5558
5548
  shouldLoadModelsProp = _e === void 0 ? true : _e;
5559
5549
  var cropCanvas = React.useRef(null);
5560
5550
  var rotateCanvas = React.useRef(null);
5551
+ var resizeCanvas = React.useRef(null);
5561
5552
  var _f = React.useState({}),
5562
- focusThresholds = _f[0],
5563
- setFocusThresholds = _f[1];
5553
+ barcodeReadabilityThresholds = _f[0],
5554
+ setBarcodeReadabilityThresholds = _f[1];
5564
5555
  var videoRef = useCameraStore().videoRef;
5565
5556
  var _g = React.useState(shouldLoadModelsProp),
5566
5557
  shouldLoadModels = _g[0],
@@ -5568,10 +5559,10 @@ function FocusModelProvider(_a) {
5568
5559
  var load = React.useCallback(function () {
5569
5560
  return setShouldLoadModels(true);
5570
5561
  }, []);
5571
- var _h = useLoadFocusModel({
5572
- modelPath: focusModelPath,
5573
- modelLoadTimeoutMs: focusModelLoadTimeoutMs,
5574
- onModelError: onFocusModelError,
5562
+ var _h = useLoadBarcodeReadabilityModel({
5563
+ modelPath: barcodeReadabilityModelPath,
5564
+ modelLoadTimeoutMs: barcodeReadabilityModelLoadTimeoutMs,
5565
+ onModelError: onBarcodeReadabilityModelError,
5575
5566
  videoRef: videoRef,
5576
5567
  shouldLoadModels: shouldLoadModels
5577
5568
  }),
@@ -5580,71 +5571,45 @@ function FocusModelProvider(_a) {
5580
5571
  modelDownloadProgress = _h.modelDownloadProgress,
5581
5572
  modelWarmingStartedAt = _h.modelWarmingStartedAt,
5582
5573
  modelError = _h.modelError;
5583
- var makeFocusPrediction = React.useCallback(function (imageData, box) {
5574
+ var makeBarcodeReadabilityPrediction = React.useCallback(function (imageData, box) {
5584
5575
  if (!ready) return null;
5585
- var prediction = makeFocusModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, box);
5576
+ var prediction = makeBarcodeReadabilityModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, resizeCanvas.current, box);
5586
5577
  if (!prediction) return null;
5587
- setLastFocusPredictionAt(prediction.predictionTime);
5578
+ setLastBarcodeReadabilityPredictionAt(prediction.predictionTime);
5588
5579
  return prediction;
5589
5580
  }, [ready]);
5590
5581
  var value = React.useMemo(function () {
5591
5582
  return {
5592
- loadFocusModel: load,
5593
- focusModelState: modelLoadState,
5594
- focusModelDownloadProgress: modelDownloadProgress,
5595
- focusModelWarmingStartedAt: modelWarmingStartedAt,
5596
- focusModelError: modelError,
5597
- makeFocusPrediction: makeFocusPrediction,
5598
- focusPredictionTime: lastFocusPredictionTime,
5599
- focusThresholds: focusThresholds,
5600
- setFocusThresholds: setFocusThresholds
5583
+ loadBarcodeReadabilityModel: load,
5584
+ barcodeReadabilityModelState: modelLoadState,
5585
+ barcodeReadabilityModelDownloadProgress: modelDownloadProgress,
5586
+ barcodeReadabilityModelWarmingStartedAt: modelWarmingStartedAt,
5587
+ barcodeReadabilityModelError: modelError,
5588
+ makeBarcodeReadabilityPrediction: makeBarcodeReadabilityPrediction,
5589
+ barcodeReadabilityPredictionTime: lastBarcodeReadabilityPredictionTime,
5590
+ barcodeReadabilityThresholds: barcodeReadabilityThresholds,
5591
+ setBarcodeReadabilityThresholds: setBarcodeReadabilityThresholds
5601
5592
  };
5602
- }, [focusThresholds, load, makeFocusPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
5603
- return /*#__PURE__*/React__namespace.default.createElement(FocusModelContext.Provider, {
5593
+ }, [barcodeReadabilityThresholds, load, makeBarcodeReadabilityPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
5594
+ return /*#__PURE__*/React__namespace.default.createElement(BarcodeReadabilityModelContext.Provider, {
5604
5595
  value: value
5605
- }, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5606
- ref: rotateCanvas,
5607
- style: showCanvases ? {
5608
- display: 'block'
5609
- } : undefined
5596
+ }, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5597
+ ref: rotateCanvas
5610
5598
  }), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5611
- ref: cropCanvas,
5599
+ ref: cropCanvas
5600
+ }), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5601
+ ref: resizeCanvas,
5612
5602
  style: showCanvases ? {
5613
5603
  display: 'block'
5614
5604
  } : undefined
5615
- }), children);
5616
- }
5617
-
5618
- function _isNavigatorDefined() {
5619
- return typeof navigator !== 'undefined' && navigator != null;
5605
+ })), children);
5620
5606
  }
5621
- var isMobileCache;
5622
- function isMobile() {
5623
- if (isMobileCache !== undefined) return isMobileCache;
5624
- isMobileCache = evaluateIsMobile();
5625
- return isMobileCache;
5626
- }
5627
- function evaluateIsMobile(nav) {
5628
- if (nav || _isNavigatorDefined()) {
5629
- if (!nav) {
5630
- nav = navigator;
5631
- }
5632
- if (nav.product === 'ReactNative') {
5633
- return true;
5634
- }
5635
- var a = nav.userAgent || nav.vendor || (
5636
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5637
- // @ts-ignore
5638
- typeof window !== 'undefined' ? window.opera : '');
5639
- if (!a) {
5640
- var navAny = nav;
5641
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
5642
- // @ts-ignore
5643
- return navAny.userAgentData && navAny.userAgentData.mobile;
5644
- }
5645
- return /(android|bb\d+|meego).+mobile|avantgo|bada\/|blackberry|blazer|compal|elaine|fennec|hiptop|iemobile|ip(hone|od)|iris|kindle|lge |maemo|midp|mmp|mobile.+firefox|netfront|opera m(ob|in)i|palm( os)?|phone|p(ixi|re)\/|plucker|pocket|psp|series(4|6)0|symbian|treo|up\.(browser|link)|vodafone|wap|windows ce|xda|xiino/i.test(a) || /1207|6310|6590|3gso|4thp|50[1-6]i|770s|802s|a wa|abac|ac(er|oo|s\-)|ai(ko|rn)|al(av|ca|co)|amoi|an(ex|ny|yw)|aptu|ar(ch|go)|as(te|us)|attw|au(di|\-m|r |s )|avan|be(ck|ll|nq)|bi(lb|rd)|bl(ac|az)|br(e|v)w|bumb|bw\-(n|u)|c55\/|capi|ccwa|cdm\-|cell|chtm|cldc|cmd\-|co(mp|nd)|craw|da(it|ll|ng)|dbte|dc\-s|devi|dica|dmob|do(c|p)o|ds(12|\-d)|el(49|ai)|em(l2|ul)|er(ic|k0)|esl8|ez([4-7]0|os|wa|ze)|fetc|fly(\-|_)|g1 u|g560|gene|gf\-5|g\-mo|go(\.w|od)|gr(ad|un)|haie|hcit|hd\-(m|p|t)|hei\-|hi(pt|ta)|hp( i|ip)|hs\-c|ht(c(\-| |_|a|g|p|s|t)|tp)|hu(aw|tc)|i\-(20|go|ma)|i230|iac( |\-|\/)|ibro|idea|ig01|ikom|im1k|inno|ipaq|iris|ja(t|v)a|jbro|jemu|jigs|kddi|keji|kgt( |\/)|klon|kpt |kwc\-|kyo(c|k)|le(no|xi)|lg( g|\/(k|l|u)|50|54|\-[a-w])|libw|lynx|m1\-w|m3ga|m50\/|ma(te|ui|xo)|mc(01|21|ca)|m\-cr|me(rc|ri)|mi(o8|oa|ts)|mmef|mo(01|02|bi|de|do|t(\-| |o|v)|zz)|mt(50|p1|v )|mwbp|mywa|n10[0-2]|n20[2-3]|n30(0|2)|n50(0|2|5)|n7(0(0|1)|10)|ne((c|m)\-|on|tf|wf|wg|wt)|nok(6|i)|nzph|o2im|op(ti|wv)|oran|owg1|p800|pan(a|d|t)|pdxg|pg(13|\-([1-8]|c))|phil|pire|pl(ay|uc)|pn\-2|po(ck|rt|se)|prox|psio|pt\-g|qa\-a|qc(07|12|21|32|60|\-[2-7]|i\-)|qtek|r380|r600|raks|rim9|ro(ve|zo)|s55\/|sa(ge|ma|mm|ms|ny|va)|sc(01|h\-|oo|p\-)|sdk\/|se(c(\-|0|1)|47|mc|nd|ri)|sgh\-|shar|sie(\-|m)|sk\-0|sl(45|id)|sm(al|ar|b3|it|t5)|so(ft|ny)|sp(01|h\-|v\-|v )|sy(01|mb)|t2(18|50)|t6(00|10|18)|ta(gt|lk)|tcl\-|tdg\-|tel(i|m)|tim\-|t\-mo|to(pl|sh)|ts(70|m\-|m3|m5)|tx\-9|up(\.b|g1|si)|utst|v400|v750|veri|vi(rg|te)|vk(40|5[0-3]|\-v)|vm40|voda|vulc|vx(52|53|60|61|70|80|81|83|85|98)|w3c(\-| )|webc|whit|wi(g |nc|nw)|wmlb|wonu|x700|yas\-|your|zeto|zte\-/i.test(a.substr(0, 4));
5607
+ function useBarcodeReadabilityModelContext() {
5608
+ var context = React.useContext(BarcodeReadabilityModelContext);
5609
+ if (!context) {
5610
+ throw new Error('useBarcodeReadabilityModelContext must be used within an BarcodeReadabilityModelProvider');
5646
5611
  }
5647
- return false;
5612
+ return context;
5648
5613
  }
5649
5614
 
5650
5615
  var onMobile = isMobile();
@@ -5680,6 +5645,7 @@ var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
5680
5645
  },
5681
5646
  detectionTime: 0,
5682
5647
  focusPredictionTime: 0,
5648
+ barcodeReadabilityPredictionTime: 0,
5683
5649
  bestFrameDetails: {
5684
5650
  current: null
5685
5651
  },
@@ -5689,55 +5655,78 @@ var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
5689
5655
  resetBestFrame: function resetBestFrame() {
5690
5656
  return null;
5691
5657
  },
5658
+ bestBarcodeDetails: {
5659
+ current: null
5660
+ },
5661
+ getBestBarcode: function getBestBarcode() {
5662
+ return null;
5663
+ },
5692
5664
  requiredDocumentType: 'none',
5693
5665
  setRequiredDocumentType: function setRequiredDocumentType() {
5694
5666
  return null;
5695
5667
  }
5696
5668
  });
5697
5669
  function IdCaptureModelsProviderInner(_a) {
5670
+ var _b;
5698
5671
  var children = _a.children,
5699
5672
  onModelError = _a.onModelError,
5700
- _b = _a.allowSinglePageIdCapture,
5701
- allowSinglePageIdCapture = _b === void 0 ? false : _b;
5702
- var _c = React.useContext(DocumentDetectionModelContext),
5703
- documentDetectionModelState = _c.documentDetectionModelState,
5704
- documentDetectionModelDownloadProgress = _c.documentDetectionModelDownloadProgress,
5705
- documentDetectionModelWarmingStartedAt = _c.documentDetectionModelWarmingStartedAt,
5706
- startDocumentDetection = _c.startDocumentDetection,
5707
- stopDocumentDetection = _c.stopDocumentDetection,
5708
- loadDocumentDetectionModel = _c.loadDocumentDetectionModel,
5709
- lastPredictionCanvas = _c.documentDetectionLastPredictionCanvas,
5710
- clearDocumentDetectionLastPredictionCanvas = _c.clearDocumentDetectionLastPredictionCanvas,
5711
- onDocumentDetected = _c.onDocumentDetected,
5712
- detectionTime = _c.detectionTime,
5713
- documentDetectionThresholds = _c.documentDetectionThresholds,
5714
- setDocumentDetectionThresholds = _c.setDocumentDetectionThresholds,
5715
- documentDetectionBoundaries = _c.documentDetectionBoundaries,
5716
- setDocumentDetectionBoundaries = _c.setDocumentDetectionBoundaries,
5717
- documentDetectionModelError = _c.documentDetectionModelError;
5718
- var _d = React.useContext(FocusModelContext),
5719
- loadFocusModel = _d.loadFocusModel,
5720
- focusModelState = _d.focusModelState,
5721
- focusModelDownloadProgress = _d.focusModelDownloadProgress,
5722
- focusModelWarmingStartedAt = _d.focusModelWarmingStartedAt,
5723
- makeFocusPrediction = _d.makeFocusPrediction,
5724
- focusThresholds = _d.focusThresholds,
5725
- setFocusThresholds = _d.setFocusThresholds,
5726
- focusPredictionTime = _d.focusPredictionTime,
5727
- focusModelError = _d.focusModelError;
5673
+ _c = _a.allowSinglePageIdCapture,
5674
+ allowSinglePageIdCapture = _c === void 0 ? false : _c,
5675
+ _d = _a.enableBarcodeReadabilityModel,
5676
+ enableBarcodeReadabilityModel = _d === void 0 ? true : _d;
5677
+ var _e = React.useContext(DocumentDetectionModelContext),
5678
+ documentDetectionModelState = _e.documentDetectionModelState,
5679
+ documentDetectionModelDownloadProgress = _e.documentDetectionModelDownloadProgress,
5680
+ documentDetectionModelWarmingStartedAt = _e.documentDetectionModelWarmingStartedAt,
5681
+ startDocumentDetection = _e.startDocumentDetection,
5682
+ stopDocumentDetection = _e.stopDocumentDetection,
5683
+ loadDocumentDetectionModel = _e.loadDocumentDetectionModel,
5684
+ lastPredictionCanvas = _e.documentDetectionLastPredictionCanvas,
5685
+ clearDocumentDetectionLastPredictionCanvas = _e.clearDocumentDetectionLastPredictionCanvas,
5686
+ onDocumentDetected = _e.onDocumentDetected,
5687
+ detectionTime = _e.detectionTime,
5688
+ documentDetectionThresholds = _e.documentDetectionThresholds,
5689
+ setDocumentDetectionThresholds = _e.setDocumentDetectionThresholds,
5690
+ documentDetectionBoundaries = _e.documentDetectionBoundaries,
5691
+ setDocumentDetectionBoundaries = _e.setDocumentDetectionBoundaries,
5692
+ documentDetectionModelError = _e.documentDetectionModelError;
5693
+ var _f = React.useContext(FocusModelContext),
5694
+ loadFocusModel = _f.loadFocusModel,
5695
+ focusModelState = _f.focusModelState,
5696
+ focusModelDownloadProgress = _f.focusModelDownloadProgress,
5697
+ focusModelWarmingStartedAt = _f.focusModelWarmingStartedAt,
5698
+ makeFocusPrediction = _f.makeFocusPrediction,
5699
+ focusThresholds = _f.focusThresholds,
5700
+ setFocusThresholds = _f.setFocusThresholds,
5701
+ focusPredictionTime = _f.focusPredictionTime,
5702
+ focusModelError = _f.focusModelError;
5703
+ var _g = useBarcodeReadabilityModelContext(),
5704
+ loadBarcodeReadabilityModel = _g.loadBarcodeReadabilityModel,
5705
+ barcodeReadabilityModelState = _g.barcodeReadabilityModelState,
5706
+ barcodeReadabilityModelDownloadProgress = _g.barcodeReadabilityModelDownloadProgress,
5707
+ barcodeReadabilityModelWarmingStartedAt = _g.barcodeReadabilityModelWarmingStartedAt,
5708
+ makeBarcodeReadabilityPrediction = _g.makeBarcodeReadabilityPrediction,
5709
+ barcodeReadabilityThresholds = _g.barcodeReadabilityThresholds,
5710
+ setBarcodeReadabilityThresholds = _g.setBarcodeReadabilityThresholds,
5711
+ barcodeReadabilityPredictionTime = _g.barcodeReadabilityPredictionTime,
5712
+ barcodeReadabilityModelError = _g.barcodeReadabilityModelError;
5728
5713
  var onPredictionHandler = React.useRef();
5729
5714
  var bestFrameDetails = React.useRef(null);
5715
+ var bestBarcodeDetails = React.useRef(null);
5730
5716
  var bestPredictionCanvas = React.useRef(null);
5717
+ var bestBarcodeCanvas = React.useRef(null);
5731
5718
  var bestFocusScore = React.useRef(0);
5719
+ var bestBarcodeScore = React.useRef(0);
5732
5720
  var stopDetection = React.useRef(0);
5733
- var _e = React.useState('none'),
5734
- requiredDocumentType = _e[0],
5735
- setRequiredDocumentType = _e[1];
5721
+ var _h = React.useState('none'),
5722
+ requiredDocumentType = _h[0],
5723
+ setRequiredDocumentType = _h[1];
5736
5724
  var thresholds = React.useMemo(function () {
5737
5725
  return _assign(_assign({}, documentDetectionThresholds), {
5738
- focus: focusThresholds
5726
+ focus: focusThresholds,
5727
+ barcodeReadability: barcodeReadabilityThresholds
5739
5728
  });
5740
- }, [documentDetectionThresholds, focusThresholds]);
5729
+ }, [documentDetectionThresholds, focusThresholds, barcodeReadabilityThresholds]);
5741
5730
  var setThresholds = React.useCallback(function (thresholds) {
5742
5731
  if (thresholds.detection) {
5743
5732
  setDocumentDetectionThresholds(thresholds.detection);
@@ -5745,17 +5734,20 @@ function IdCaptureModelsProviderInner(_a) {
5745
5734
  if (thresholds.focus) {
5746
5735
  setFocusThresholds(thresholds.focus);
5747
5736
  }
5748
- }, [setDocumentDetectionThresholds, setFocusThresholds]);
5737
+ if (thresholds.barcodeReadability) {
5738
+ setBarcodeReadabilityThresholds(thresholds.barcodeReadability);
5739
+ }
5740
+ }, [setBarcodeReadabilityThresholds, setDocumentDetectionThresholds, setFocusThresholds]);
5749
5741
  React.useEffect(function handleDetections() {
5750
5742
  var _this = this;
5751
5743
  onDocumentDetected(function (prediction) {
5752
5744
  return __awaiter(_this, void 0, void 0, function () {
5753
- var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold;
5754
- var _a, _b, _c, _d, _e, _f, _g;
5755
- return __generator(this, function (_h) {
5745
+ var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold, pdf417Prediction, barcodeReadabilityThresholdSet, barcodeReadabilityThreshold;
5746
+ var _a, _b, _c, _d, _e, _f, _g, _h;
5747
+ return __generator(this, function (_j) {
5756
5748
  if (!lastPredictionCanvas.current) return [2 /*return*/];
5757
5749
  stopDetectionAtStart = stopDetection.current;
5758
- focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false;
5750
+ focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false, pdf417PredictionTime = 0, pdf417PredictionScore = 0, pdf417PredictionThresholdMet = false;
5759
5751
  isSinglePage = prediction.detectedDocumentType === 'singlePage';
5760
5752
  if (!allowSinglePageIdCapture && isSinglePage) {
5761
5753
  prediction.detectedDocumentType = 'passport';
@@ -5774,28 +5766,51 @@ function IdCaptureModelsProviderInner(_a) {
5774
5766
  focusThresholdSet = (_d = thresholds.focus) === null || _d === void 0 ? void 0 : _d[prediction.detectedDocumentType];
5775
5767
  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;
5776
5768
  focusThresholdMet = focusScore >= focusThreshold;
5777
- if (bestFocusScore.current <= focusScore && stopDetectionAtStart === stopDetection.current) {
5778
- bestFocusScore.current = focusScore;
5779
- drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
5780
- bestFrameDetails.current = {
5781
- boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
5782
- documentType: prediction.detectedDocumentType,
5783
- detectionScore: prediction.detectionScore,
5784
- focusScore: focusScore
5785
- };
5769
+ if (stopDetectionAtStart === stopDetection.current) {
5770
+ if (bestFocusScore.current <= focusScore) {
5771
+ bestFocusScore.current = focusScore;
5772
+ drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
5773
+ bestFrameDetails.current = {
5774
+ boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
5775
+ documentType: prediction.detectedDocumentType,
5776
+ detectionScore: prediction.detectionScore,
5777
+ focusScore: focusScore
5778
+ };
5779
+ }
5780
+ if (enableBarcodeReadabilityModel && prediction.bestPDF417) {
5781
+ pdf417Prediction = makeBarcodeReadabilityPrediction(lastPredictionCanvas.current, prediction.bestPDF417.box);
5782
+ if (pdf417Prediction) {
5783
+ pdf417PredictionTime = pdf417Prediction.predictionTime;
5784
+ pdf417PredictionScore = pdf417Prediction.score;
5785
+ if (bestBarcodeScore.current <= pdf417Prediction.score) {
5786
+ bestBarcodeScore.current = pdf417Prediction.score;
5787
+ bestBarcodeDetails.current = {
5788
+ boundingBox: prediction.bestPDF417.box,
5789
+ score: pdf417Prediction.score
5790
+ };
5791
+ drawToCanvas(bestBarcodeCanvas.current, cropToDetectedObjectBox(lastPredictionCanvas.current, prediction.bestPDF417.box, undefined, 16));
5792
+ barcodeReadabilityThresholdSet = barcodeReadabilityThresholds[prediction.detectedDocumentType];
5793
+ 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;
5794
+ pdf417PredictionThresholdMet = pdf417PredictionScore >= barcodeReadabilityThreshold;
5795
+ }
5796
+ }
5797
+ }
5786
5798
  }
5787
5799
  }
5788
- (_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
5800
+ (_h = onPredictionHandler.current) === null || _h === void 0 ? void 0 : _h.call(onPredictionHandler, _assign(_assign({}, prediction), {
5789
5801
  focusScore: focusScore,
5790
5802
  focusPredictionTime: focusPredictionTime,
5791
- focusThresholdMet: focusThresholdMet
5803
+ focusThresholdMet: focusThresholdMet,
5804
+ pdf417PredictionTime: pdf417PredictionTime,
5805
+ pdf417PredictionScore: pdf417PredictionScore,
5806
+ pdf417PredictionThresholdMet: pdf417PredictionThresholdMet
5792
5807
  }));
5793
5808
  return [2 /*return*/];
5794
5809
  });
5795
5810
  });
5796
5811
  });
5797
- }, [allowSinglePageIdCapture, lastPredictionCanvas, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
5798
- var modelError = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError;
5812
+ }, [allowSinglePageIdCapture, barcodeReadabilityThresholds, enableBarcodeReadabilityModel, lastPredictionCanvas, makeBarcodeReadabilityPrediction, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
5813
+ var modelError = (_b = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError) !== null && _b !== void 0 ? _b : barcodeReadabilityModelError;
5799
5814
  React.useEffect(function handleModelErrors() {
5800
5815
  if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
5801
5816
  }, [modelError, onModelError]);
@@ -5808,9 +5823,15 @@ function IdCaptureModelsProviderInner(_a) {
5808
5823
  canvas: bestPredictionCanvas.current
5809
5824
  });
5810
5825
  }, []);
5811
- var _f = React.useState(0),
5812
- canvasKey = _f[0],
5813
- setCanvasKey = _f[1];
5826
+ var getBestBarcode = React.useCallback(function () {
5827
+ if (!bestBarcodeDetails.current || !bestBarcodeCanvas.current) return null;
5828
+ return _assign(_assign({}, bestBarcodeDetails.current), {
5829
+ canvas: bestBarcodeCanvas.current
5830
+ });
5831
+ }, []);
5832
+ var _j = React.useState(0),
5833
+ canvasKey = _j[0],
5834
+ setCanvasKey = _j[1];
5814
5835
  var resetBestFrame = React.useCallback(function () {
5815
5836
  stopDetection.current += 1;
5816
5837
  setCanvasKey(function (n) {
@@ -5826,16 +5847,45 @@ function IdCaptureModelsProviderInner(_a) {
5826
5847
  var load = React.useCallback(function () {
5827
5848
  loadDocumentDetectionModel();
5828
5849
  loadFocusModel();
5829
- }, [loadDocumentDetectionModel, loadFocusModel]);
5830
- var ready = documentDetectionModelState === 'ready' && focusModelState === 'ready';
5831
- var modelLoadState = ready ? 'ready' : documentDetectionModelState === 'warming' || focusModelState === 'warming' ? 'warming' : focusModelState === 'downloading' || documentDetectionModelState === 'downloading' ? 'downloading' : 'not-started';
5832
- var modelWarmingStartedAt = !documentDetectionModelWarmingStartedAt && !focusModelWarmingStartedAt ? null : Math.min.apply(Math, [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt].filter(function (v) {
5833
- return v !== null;
5834
- }));
5850
+ if (enableBarcodeReadabilityModel) loadBarcodeReadabilityModel();
5851
+ }, [enableBarcodeReadabilityModel, loadBarcodeReadabilityModel, loadDocumentDetectionModel, loadFocusModel]);
5852
+ var _k = React.useMemo(function () {
5853
+ var modelStates = [documentDetectionModelState, focusModelState];
5854
+ var modelWarmingStartedAts = [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt];
5855
+ var modelDownloadProgresses = [documentDetectionModelDownloadProgress, focusModelDownloadProgress];
5856
+ if (enableBarcodeReadabilityModel) {
5857
+ modelStates.push(barcodeReadabilityModelState);
5858
+ modelWarmingStartedAts.push(barcodeReadabilityModelWarmingStartedAt);
5859
+ modelDownloadProgresses.push(barcodeReadabilityModelDownloadProgress);
5860
+ }
5861
+ var ready = modelStates.every(function (state) {
5862
+ return state === 'ready';
5863
+ });
5864
+ return {
5865
+ ready: ready,
5866
+ modelLoadState: ready ? 'ready' : modelStates.some(function (state) {
5867
+ return state === 'warming';
5868
+ }) ? 'warming' : modelStates.some(function (state) {
5869
+ return state === 'downloading';
5870
+ }) ? 'downloading' : 'not-started',
5871
+ modelWarmingStartedAt: modelWarmingStartedAts.every(function (v) {
5872
+ return v === null;
5873
+ }) ? null : Math.min.apply(Math, modelWarmingStartedAts.filter(function (v) {
5874
+ return v !== null;
5875
+ })),
5876
+ modelDownloadProgress: modelDownloadProgresses.reduce(function (a, b) {
5877
+ return a + b;
5878
+ }, 0) / modelDownloadProgresses.length
5879
+ };
5880
+ }, [barcodeReadabilityModelDownloadProgress, barcodeReadabilityModelState, barcodeReadabilityModelWarmingStartedAt, documentDetectionModelDownloadProgress, documentDetectionModelState, documentDetectionModelWarmingStartedAt, enableBarcodeReadabilityModel, focusModelDownloadProgress, focusModelState, focusModelWarmingStartedAt]),
5881
+ ready = _k.ready,
5882
+ modelLoadState = _k.modelLoadState,
5883
+ modelWarmingStartedAt = _k.modelWarmingStartedAt,
5884
+ modelDownloadProgress = _k.modelDownloadProgress;
5835
5885
  var value = React.useMemo(function () {
5836
5886
  return {
5837
5887
  ready: ready,
5838
- modelDownloadProgress: (documentDetectionModelDownloadProgress + focusModelDownloadProgress) / 2,
5888
+ modelDownloadProgress: modelDownloadProgress,
5839
5889
  modelLoadState: modelLoadState,
5840
5890
  modelWarmingStartedAt: modelWarmingStartedAt,
5841
5891
  modelError: modelError,
@@ -5849,24 +5899,32 @@ function IdCaptureModelsProviderInner(_a) {
5849
5899
  onPredictionMade: onPredictionMade,
5850
5900
  detectionTime: detectionTime,
5851
5901
  focusPredictionTime: focusPredictionTime,
5902
+ barcodeReadabilityPredictionTime: barcodeReadabilityPredictionTime,
5852
5903
  getBestFrame: getBestFrame,
5853
5904
  resetBestFrame: resetBestFrame,
5854
5905
  bestFrameDetails: bestFrameDetails,
5906
+ bestBarcodeDetails: bestBarcodeDetails,
5907
+ getBestBarcode: getBestBarcode,
5855
5908
  requiredDocumentType: requiredDocumentType,
5856
5909
  setRequiredDocumentType: setRequiredDocumentType
5857
5910
  };
5858
- }, [detectionTime, documentDetectionBoundaries, documentDetectionModelDownloadProgress, focusModelDownloadProgress, focusPredictionTime, getBestFrame, load, modelLoadState, modelError, modelWarmingStartedAt, onPredictionMade, ready, requiredDocumentType, resetBestFrame, setDocumentDetectionBoundaries, setThresholds, startDocumentDetection, stopDocumentDetection, thresholds]);
5911
+ }, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, requiredDocumentType]);
5859
5912
  return /*#__PURE__*/React__namespace.default.createElement(IdCaptureModelsContext.Provider, {
5860
5913
  value: value
5861
5914
  }, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5862
- key: canvasKey,
5915
+ key: "bf-".concat(canvasKey),
5863
5916
  ref: bestPredictionCanvas
5917
+ }), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
5918
+ key: "bb-".concat(canvasKey),
5919
+ ref: bestBarcodeCanvas
5864
5920
  }), children);
5865
5921
  }
5866
5922
  function IdCaptureModelsProvider(_a) {
5867
5923
  var children = _a.children,
5868
5924
  props = __rest(_a, ["children"]);
5869
- return /*#__PURE__*/React__namespace.default.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React__namespace.default.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React__namespace.default.createElement(IdCaptureModelsProviderInner, _assign({}, props), children)));
5925
+ return /*#__PURE__*/React__namespace.default.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React__namespace.default.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React__namespace.default.createElement(BarcodeReadabilityModelProvider, _assign({}, props, {
5926
+ shouldLoadModels: props.enableBarcodeReadabilityModel
5927
+ }), /*#__PURE__*/React__namespace.default.createElement(IdCaptureModelsProviderInner, _assign({}, props), children))));
5870
5928
  }
5871
5929
  function useIdCaptureModelsContext() {
5872
5930
  var context = React.useContext(IdCaptureModelsContext);
@@ -5876,7 +5934,7 @@ function useIdCaptureModelsContext() {
5876
5934
  return context;
5877
5935
  }
5878
5936
 
5879
- var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
5937
+ var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage', 'idBarcodeImage'];
5880
5938
 
5881
5939
  var acceptedDocumentTypesForIdCaptureRequirementOption = {
5882
5940
  idCardFront: ['idCardFront'],
@@ -5962,6 +6020,7 @@ var initialState$5 = {
5962
6020
  capturing: false,
5963
6021
  captureFailed: false,
5964
6022
  imageUrl: null,
6023
+ idBarcodeImage: null,
5965
6024
  captureState: 'initializing',
5966
6025
  capturedDocuments: {},
5967
6026
  captureRequirement: 'idCardOrPassport',
@@ -6241,6 +6300,17 @@ var _reducer = function reducer(state, action) {
6241
6300
  }
6242
6301
  return newState;
6243
6302
  }
6303
+ case 'barcodeCaptured':
6304
+ return _reducer(state, {
6305
+ type: 'documentCaptured',
6306
+ payload: {
6307
+ imageData: action.payload.imageUrl,
6308
+ documentType: 'idBarcodeImage',
6309
+ width: 0,
6310
+ height: 0,
6311
+ barcodeReadabilityScore: action.payload.barcodeReadabilityScore
6312
+ }
6313
+ });
6244
6314
  case 'flipRequestCompleted':
6245
6315
  return _assign(_assign({}, state), {
6246
6316
  captureState: 'capturing',
@@ -6732,12 +6802,13 @@ var IdCapture = function IdCapture(_a) {
6732
6802
  height = _q === void 0 ? 1 : _q;
6733
6803
  var state = useIdCaptureStore();
6734
6804
  var isRearFacing = useCameraStore().isRearFacing;
6735
- var _r = React.useContext(IdCaptureModelsContext),
6805
+ var _r = useIdCaptureModelsContext(),
6736
6806
  modelsReady = _r.ready,
6737
6807
  setThresholds = _r.setThresholds,
6738
6808
  detectionTime = _r.detectionTime,
6739
6809
  focusPredictionTime = _r.focusPredictionTime,
6740
- getBestFrame = _r.getBestFrame;
6810
+ getBestFrame = _r.getBestFrame,
6811
+ getBestBarcode = _r.getBestBarcode;
6741
6812
  React.useEffect(function () {
6742
6813
  return dispatchIdCaptureAction({
6743
6814
  type: 'captureInitialized'
@@ -6776,6 +6847,16 @@ var IdCapture = function IdCapture(_a) {
6776
6847
  });
6777
6848
  return;
6778
6849
  }
6850
+ var bestBarcode = getBestBarcode();
6851
+ if (bestBarcode) {
6852
+ dispatchIdCaptureAction({
6853
+ type: 'barcodeCaptured',
6854
+ payload: {
6855
+ imageUrl: bestBarcode.canvas.toDataURL('image/jpeg', 0.95),
6856
+ barcodeReadabilityScore: bestBarcode.score
6857
+ }
6858
+ });
6859
+ }
6779
6860
  var canvas = bestFrame.canvas,
6780
6861
  documentType = bestFrame.documentType,
6781
6862
  boundingBox = bestFrame.boundingBox,
@@ -6792,21 +6873,22 @@ var IdCapture = function IdCapture(_a) {
6792
6873
  });
6793
6874
  var capturedDocumentType = documentType;
6794
6875
  setTimeout(function () {
6795
- var _a;
6796
- var captureTime = new Date().getTime() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
6876
+ var _a, _b;
6877
+ var captureTime = performance.now() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
6797
6878
  var metadata = {
6798
6879
  autoCapture: 'Y',
6799
6880
  captureTime: captureTime,
6800
6881
  boundingBox: boundingBox,
6801
6882
  bestDetectionScore: detectionScore,
6802
- bestFocusScore: focusScore
6883
+ bestFocusScore: focusScore,
6884
+ bestBarcodeScore: (_b = bestBarcode === null || bestBarcode === void 0 ? void 0 : bestBarcode.score) !== null && _b !== void 0 ? _b : 0
6803
6885
  };
6804
6886
  onCapture === null || onCapture === void 0 ? void 0 : onCapture(imageUrl, width, height, capturedDocumentType, metadata);
6805
6887
  dispatchIdCaptureAction({
6806
6888
  type: 'captured'
6807
6889
  });
6808
6890
  }, 0);
6809
- }, [getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
6891
+ }, [getBestBarcode, getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
6810
6892
  var theme = styled.useTheme();
6811
6893
  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');
6812
6894
  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');
@@ -7944,7 +8026,7 @@ var Card = styled__default.default.div(templateObject_1$E || (templateObject_1$E
7944
8026
  var FlexCard = styled__default.default(Card)(templateObject_2$y || (templateObject_2$y = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n"], ["\n display: flex;\n flex-direction: column;\n"])));
7945
8027
  var templateObject_1$E, templateObject_2$y;
7946
8028
 
7947
- var imageDisplayOrder = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
8029
+ var imageDisplayOrder = ['idCardFront', 'idCardBack', 'idBarcodeImage', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
7948
8030
  var IdCaptureSuccess = function IdCaptureSuccess(_a) {
7949
8031
  var capturedDocuments = _a.capturedDocuments,
7950
8032
  onSubmitClick = _a.onSubmitClick,
@@ -7986,7 +8068,7 @@ var IdCaptureSuccess = function IdCaptureSuccess(_a) {
7986
8068
  image: doc,
7987
8069
  className: classNames.image,
7988
8070
  alt: doc.documentType
7989
- }), debugMode && ( /*#__PURE__*/React__namespace.default.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)))));
8071
+ }), debugMode && ( /*#__PURE__*/React__namespace.default.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)))));
7990
8072
  }))), /*#__PURE__*/React__namespace.default.createElement(ButtonsColumn, {
7991
8073
  className: classNames.buttonsRow
7992
8074
  }, /*#__PURE__*/React__namespace.default.createElement(WideButton, {
@@ -10598,7 +10680,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10598
10680
  var _5 = React.useState(false),
10599
10681
  overlayDismissed = _5[0],
10600
10682
  setOverlayDismissed = _5[1];
10601
- var _6 = React.useContext(SubmissionContext),
10683
+ var _6 = useSubmissionContext(),
10602
10684
  submissionStatus = _6.submissionStatus,
10603
10685
  setIdFrontImage = _6.setIdFrontImage,
10604
10686
  setIdBackImage = _6.setIdBackImage,
@@ -10607,6 +10689,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10607
10689
  setIdBackIrImage = _6.setIdBackIrImage,
10608
10690
  setIdFrontUvImage = _6.setIdFrontUvImage,
10609
10691
  setIdBackUvImage = _6.setIdBackUvImage,
10692
+ setIdBarcodeImage = _6.setIdBarcodeImage,
10610
10693
  logIdFrontCaptureAttempt = _6.logIdFrontCaptureAttempt,
10611
10694
  logIdBackCaptureAttempt = _6.logIdBackCaptureAttempt;
10612
10695
  var _7 = useIdCaptureModelsContext(),
@@ -10697,7 +10780,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10697
10780
  });
10698
10781
  }, [logCaptureMetadata, onDocumentCaptured]);
10699
10782
  var onSubmitClick = React.useCallback(function () {
10700
- var _a, _b, _c, _d, _e, _f, _g, _h;
10783
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j;
10701
10784
  var docs = state.capturedDocuments;
10702
10785
  var submission = {
10703
10786
  idFrontImage: maybeDataUrlToBase64Sync((_a = docs.idCardFront) === null || _a === void 0 ? void 0 : _a.imageData),
@@ -10707,7 +10790,8 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10707
10790
  idFrontIrImage: maybeDataUrlToBase64Sync((_e = docs.idFrontIrImage) === null || _e === void 0 ? void 0 : _e.imageData),
10708
10791
  idBackIrImage: maybeDataUrlToBase64Sync((_f = docs.idBackIrImage) === null || _f === void 0 ? void 0 : _f.imageData),
10709
10792
  idFrontUvImage: maybeDataUrlToBase64Sync((_g = docs.idFrontUvImage) === null || _g === void 0 ? void 0 : _g.imageData),
10710
- idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData)
10793
+ idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData),
10794
+ idBarcodeImage: maybeDataUrlToBase64Sync((_j = docs.idBarcodeImage) === null || _j === void 0 ? void 0 : _j.imageData)
10711
10795
  };
10712
10796
  if (submission.idFrontImage) setIdFrontImage(submission.idFrontImage);
10713
10797
  if (submission.idBackImage) setIdBackImage(submission.idBackImage);
@@ -10717,11 +10801,12 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
10717
10801
  if (submission.idBackIrImage) setIdBackIrImage(submission.idBackIrImage);
10718
10802
  if (submission.idFrontUvImage) setIdFrontUvImage(submission.idFrontUvImage);
10719
10803
  if (submission.idBackUvImage) setIdBackUvImage(submission.idBackUvImage);
10804
+ if (submission.idBarcodeImage) setIdBarcodeImage(submission.idBarcodeImage);
10720
10805
  if (releaseCameraAccessOnExit) releaseCameraAccess();
10721
10806
  setTimeout(function () {
10722
10807
  return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(submission);
10723
10808
  }, 0);
10724
- }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
10809
+ }, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBarcodeImage, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
10725
10810
  var showSuccessScreen = useShowSuccessScreen(skipSuccessScreen, state.captureState === 'complete', onSubmitClick);
10726
10811
  var onRetryClick = React.useCallback(function () {
10727
10812
  return dispatchIdCaptureAction({
@@ -11523,47 +11608,315 @@ function SelfieCaptureAnimatedMaskWithStatus(_a) {
11523
11608
  setFrame(0);
11524
11609
  return;
11525
11610
  }
11526
- setFrame(1);
11527
- var interval = setInterval(function () {
11528
- setFrame(function (n) {
11529
- return (n + 1) % 6;
11611
+ setFrame(1);
11612
+ var interval = setInterval(function () {
11613
+ setFrame(function (n) {
11614
+ return (n + 1) % 6;
11615
+ });
11616
+ }, 250);
11617
+ return function () {
11618
+ clearInterval(interval);
11619
+ };
11620
+ }, [status]);
11621
+ return /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMask, _assign({}, props, {
11622
+ frame: frame,
11623
+ status: status
11624
+ }));
11625
+ }
11626
+ var templateObject_1$p, templateObject_2$m, templateObject_3$g;
11627
+
11628
+ var FaceCaptureGuideContainer = styled__default.default.div(templateObject_1$o || (templateObject_1$o = __makeTemplateObject(["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"], ["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"])));
11629
+ var FaceCaptureGuideInner = styled__default.default.div(templateObject_2$l || (templateObject_2$l = __makeTemplateObject(["\n position: relative;\n height: 60%;\n"], ["\n position: relative;\n height: 60%;\n"])));
11630
+ var FaceCaptureGuideOverlay = function FaceCaptureGuideOverlay(_a) {
11631
+ var _b = _a.classNames,
11632
+ classNames = _b === void 0 ? {} : _b,
11633
+ _c = _a.status,
11634
+ status = _c === void 0 ? 'ready' : _c,
11635
+ _d = _a.borderWidth,
11636
+ borderWidth = _d === void 0 ? 5 : _d,
11637
+ _e = _a.borderColor,
11638
+ borderColor = _e === void 0 ? 'white' : _e,
11639
+ _f = _a.borderOpacity,
11640
+ borderOpacity = _f === void 0 ? 0.8 : _f;
11641
+ return /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideContainer, {
11642
+ className: classNames.container
11643
+ }, /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideInner, null, /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMaskWithStatus, {
11644
+ status: status,
11645
+ borderColor: borderColor,
11646
+ borderWidth: borderWidth,
11647
+ borderOpacity: borderOpacity,
11648
+ verticalAlign: "center"
11649
+ })));
11650
+ };
11651
+ var templateObject_1$o, templateObject_2$l;
11652
+
11653
+ var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
11654
+ var detector = null;
11655
+ var detectorSettings = null;
11656
+ function loadFaceDetector() {
11657
+ return __awaiter(this, arguments, void 0, function (modelAssetPath) {
11658
+ var _a, _b;
11659
+ if (modelAssetPath === void 0) {
11660
+ modelAssetPath = defaultFaceDetectorModelPath;
11661
+ }
11662
+ return __generator(this, function (_c) {
11663
+ switch (_c.label) {
11664
+ case 0:
11665
+ if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector];
11666
+ closeFaceDetector();
11667
+ return [4 /*yield*/, preloadFaceDetectorDependencies()];
11668
+ case 1:
11669
+ _c.sent();
11670
+ if (modelCapabilities.delegate === 'NONE') {
11671
+ throw new Error('No available delegate for face detector.');
11672
+ }
11673
+ _b = (_a = tasksVision.FaceDetector).createFromOptions;
11674
+ return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
11675
+ case 2:
11676
+ return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
11677
+ // canvas: document.createElement('canvas'),
11678
+ baseOptions: {
11679
+ modelAssetPath: modelAssetPath,
11680
+ delegate: modelCapabilities.delegate
11681
+ },
11682
+ runningMode: 'VIDEO'
11683
+ }])];
11684
+ case 3:
11685
+ detector = _c.sent();
11686
+ detectorSettings = {
11687
+ modelAssetPath: modelAssetPath
11688
+ };
11689
+ return [2 /*return*/, detector];
11690
+ }
11691
+ });
11692
+ });
11693
+ }
11694
+ function closeFaceDetector() {
11695
+ detector === null || detector === void 0 ? void 0 : detector.close();
11696
+ detector = null;
11697
+ detectorSettings = null;
11698
+ }
11699
+ function useLoadFaceDetector(_a) {
11700
+ var onModelError = _a.onModelError,
11701
+ _b = _a.modelLoadTimeoutMs,
11702
+ modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
11703
+ videoRef = _a.videoRef;
11704
+ var _c = React.useState('not-started'),
11705
+ modelLoadState = _c[0],
11706
+ setModelLoadState = _c[1];
11707
+ var _d = React.useState(0),
11708
+ modelDownloadProgress = _d[0],
11709
+ setModelDownloadProgress = _d[1];
11710
+ var _e = React.useState(null),
11711
+ modelWarmingStartedAt = _e[0],
11712
+ setModelWarmingStartedAt = _e[1];
11713
+ var _f = React.useState(null),
11714
+ modelError = _f[0],
11715
+ setModelError = _f[1];
11716
+ React.useEffect(function loadModel() {
11717
+ var _this = this;
11718
+ setModelLoadState('downloading');
11719
+ setModelWarmingStartedAt(null);
11720
+ var modelLoadTimeout = setTimeout(function () {
11721
+ setModelError(new Error('Model loading time limit exceeded.'));
11722
+ }, modelLoadTimeoutMs);
11723
+ function handleDownloadProgress(event) {
11724
+ setModelDownloadProgress(progressToPercentage(event.detail));
11725
+ }
11726
+ document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
11727
+ var cancelVideoReady = function cancelVideoReady() {};
11728
+ loadFaceDetector().then(function (model) {
11729
+ return __awaiter(_this, void 0, void 0, function () {
11730
+ var _a, videoReady, cancel, cancelled;
11731
+ return __generator(this, function (_b) {
11732
+ switch (_b.label) {
11733
+ case 0:
11734
+ setModelDownloadProgress(100);
11735
+ clearTimeout(modelLoadTimeout);
11736
+ setModelLoadState('warming');
11737
+ setModelWarmingStartedAt(performance.now());
11738
+ return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
11739
+ case 1:
11740
+ _b.sent();
11741
+ _a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
11742
+ cancelled = false;
11743
+ cancelVideoReady = function cancelVideoReady() {
11744
+ cancelled = true;
11745
+ cancel();
11746
+ };
11747
+ return [4 /*yield*/, videoReady];
11748
+ case 2:
11749
+ _b.sent();
11750
+ if (cancelled) return [2 /*return*/];
11751
+ model.detectForVideo(videoRef.current, performance.now());
11752
+ setModelLoadState('ready');
11753
+ return [2 /*return*/];
11754
+ }
11755
+ });
11530
11756
  });
11531
- }, 250);
11757
+ })["catch"](function (e) {
11758
+ setModelError(e);
11759
+ setModelLoadState('error');
11760
+ })["finally"](function () {
11761
+ clearTimeout(modelLoadTimeout);
11762
+ });
11532
11763
  return function () {
11533
- clearInterval(interval);
11764
+ log('unloading face detection model');
11765
+ cancelVideoReady();
11766
+ closeFaceDetector();
11767
+ clearTimeout(modelLoadTimeout);
11768
+ document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
11534
11769
  };
11535
- }, [status]);
11536
- return /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMask, _assign({}, props, {
11537
- frame: frame,
11538
- status: status
11539
- }));
11770
+ }, [modelLoadTimeoutMs, videoRef]);
11771
+ React.useEffect(function handleModelError() {
11772
+ if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
11773
+ }, [modelError, onModelError]);
11774
+ return React.useMemo(function () {
11775
+ return {
11776
+ ready: modelLoadState === 'ready',
11777
+ modelLoadState: modelLoadState,
11778
+ modelDownloadProgress: modelDownloadProgress,
11779
+ modelWarmingStartedAt: modelWarmingStartedAt,
11780
+ modelError: modelError
11781
+ };
11782
+ }, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
11783
+ }
11784
+ var lastFaceDetectionAt = 0;
11785
+ var lastFaceDetectionTime = 0;
11786
+ function setLastFaceDetectionAt(time) {
11787
+ lastFaceDetectionTime = time - lastFaceDetectionAt;
11788
+ lastFaceDetectionAt = time;
11789
+ }
11790
+ var framesNeededSamples = [];
11791
+ function trackFramesNeeded(value, bufferLength) {
11792
+ if (bufferLength === void 0) {
11793
+ bufferLength = 25;
11794
+ }
11795
+ framesNeededSamples.unshift(value);
11796
+ if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
11797
+ }
11798
+ var lastNFaces = [];
11799
+ var lastNPairs = [];
11800
+ function trackFace(face, framesNeeded) {
11801
+ if (framesNeeded === void 0) {
11802
+ framesNeeded = 12;
11803
+ }
11804
+ lastNFaces.unshift(face);
11805
+ if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
11806
+ if (lastNFaces.length > 1) {
11807
+ var lastFace = lastNFaces[1];
11808
+ var iou = calculateIoU(face.box, lastFace.box);
11809
+ lastNPairs.unshift({
11810
+ a: face,
11811
+ b: lastFace,
11812
+ iou: iou
11813
+ });
11814
+ if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
11815
+ }
11816
+ }
11817
+ function makeFaceDetectorPrediction(imageData) {
11818
+ if (!detector) return null;
11819
+ var prediction = detector.detectForVideo(imageData, performance.now());
11820
+ var faces = prediction.detections.map(function (d) {
11821
+ return {
11822
+ box: convertBoundingBox(d.boundingBox),
11823
+ keypoints: d.keypoints.map(function (k) {
11824
+ var _a;
11825
+ return _assign(_assign({}, k), {
11826
+ x: k.x * imageData.width,
11827
+ y: k.y * imageData.height,
11828
+ name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
11829
+ });
11830
+ })
11831
+ };
11832
+ });
11833
+ return _assign(_assign({}, prediction), {
11834
+ faces: faces
11835
+ });
11836
+ }
11837
+ function processFaceDetectorPrediction(_a) {
11838
+ var faces = _a.faces,
11839
+ videoWidth = _a.videoWidth,
11840
+ videoHeight = _a.videoHeight,
11841
+ _b = _a.requireVerticalFaceCentering,
11842
+ requireVerticalFaceCentering = _b === void 0 ? true : _b,
11843
+ _c = _a.stabilityThreshold,
11844
+ stabilityThreshold = _c === void 0 ? 0.7 : _c;
11845
+ var face = faces[0];
11846
+ var faceNotDetected = faces.length === 0;
11847
+ var faceNotCentered = false,
11848
+ faceLookingAway = false,
11849
+ faceTooClose = false,
11850
+ faceTooFar = false;
11851
+ if (face) {
11852
+ // calculate centroids
11853
+ var vCX = videoWidth / 2;
11854
+ var vCY = videoHeight / 2;
11855
+ var fCX = (face.box.xMin + face.box.xMax) / 2;
11856
+ var fCY = (face.box.yMin + face.box.yMax) / 2;
11857
+ // calculate thresholds
11858
+ var vTX = videoWidth * 0.125;
11859
+ var vTY = videoHeight * 0.125;
11860
+ var fTW = face.box.width * 0.2;
11861
+ var fTH = face.box.height * 0.2;
11862
+ var nose = face.keypoints[2]; //.find((k) => k.name === 'noseTip')
11863
+ if (nose) {
11864
+ faceLookingAway = Math.abs(fCX - nose.x) > fTW || Math.abs(fCY - nose.y) > fTH;
11865
+ var faceNotCenteredHorizontally = Math.abs(vCX - fCX) > vTX;
11866
+ var faceNotCenteredVertically = Math.abs(vCY + 50 - fCY) > vTY;
11867
+ faceNotCentered = faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
11868
+ }
11869
+ var isMobile = videoWidth < videoHeight;
11870
+ var tooCloseMultiple = 1.5;
11871
+ var tooFarMultiple = isMobile ? 6 : 7;
11872
+ faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
11873
+ faceTooFar = face.box.width < videoWidth / tooFarMultiple;
11874
+ }
11875
+ var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
11876
+ if (lastFaceDetectionTime > 0) {
11877
+ trackFramesNeeded(500 / lastFaceDetectionTime);
11878
+ }
11879
+ var faceIsStable = false;
11880
+ if (faceInGuides) {
11881
+ var framesNeeded = Math.ceil(average(framesNeededSamples));
11882
+ trackFace(face, framesNeeded);
11883
+ faceIsStable = lastNFaces.length >= framesNeeded && !lastNPairs.some(function (pair) {
11884
+ return pair.iou < stabilityThreshold;
11885
+ });
11886
+ }
11887
+ var faceReady = faceInGuides && faceIsStable;
11888
+ return {
11889
+ face: face,
11890
+ faceNotDetected: faceNotDetected,
11891
+ faceNotCentered: faceNotCentered,
11892
+ faceLookingAway: faceLookingAway,
11893
+ faceTooClose: faceTooClose,
11894
+ faceTooFar: faceTooFar,
11895
+ faceReady: faceReady,
11896
+ faceReadyAt: faceReady ? new Date() : null,
11897
+ faceIsStable: faceIsStable
11898
+ };
11899
+ }
11900
+ function testFaceDetectionAgainstKnownImage(detector) {
11901
+ return new Promise(function (resolve, reject) {
11902
+ var img = new Image();
11903
+ img.crossOrigin = 'anonymous';
11904
+ img.onload = function () {
11905
+ var prediction = detector.detectForVideo(img, performance.now());
11906
+ if (prediction.detections.length > 0) {
11907
+ debug('face detection test result', prediction.detections);
11908
+ resolve(void 0);
11909
+ } else {
11910
+ warn('face detection test failed');
11911
+ reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
11912
+ }
11913
+ };
11914
+ img.onerror = function () {
11915
+ return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
11916
+ };
11917
+ img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
11918
+ });
11540
11919
  }
11541
- var templateObject_1$p, templateObject_2$m, templateObject_3$g;
11542
-
11543
- var FaceCaptureGuideContainer = styled__default.default.div(templateObject_1$o || (templateObject_1$o = __makeTemplateObject(["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"], ["\n position: absolute;\n z-index: 1000;\n top: 0;\n left: 0;\n width: 100%;\n height: 100%;\n display: flex;\n flex-direction: column;\n align-items: center;\n justify-content: center;\n padding: 40px;\n box-sizing: border-box;\n"])));
11544
- var FaceCaptureGuideInner = styled__default.default.div(templateObject_2$l || (templateObject_2$l = __makeTemplateObject(["\n position: relative;\n height: 60%;\n"], ["\n position: relative;\n height: 60%;\n"])));
11545
- var FaceCaptureGuideOverlay = function FaceCaptureGuideOverlay(_a) {
11546
- var _b = _a.classNames,
11547
- classNames = _b === void 0 ? {} : _b,
11548
- _c = _a.status,
11549
- status = _c === void 0 ? 'ready' : _c,
11550
- _d = _a.borderWidth,
11551
- borderWidth = _d === void 0 ? 5 : _d,
11552
- _e = _a.borderColor,
11553
- borderColor = _e === void 0 ? 'white' : _e,
11554
- _f = _a.borderOpacity,
11555
- borderOpacity = _f === void 0 ? 0.8 : _f;
11556
- return /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideContainer, {
11557
- className: classNames.container
11558
- }, /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideInner, null, /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMaskWithStatus, {
11559
- status: status,
11560
- borderColor: borderColor,
11561
- borderWidth: borderWidth,
11562
- borderOpacity: borderOpacity,
11563
- verticalAlign: "center"
11564
- })));
11565
- };
11566
- var templateObject_1$o, templateObject_2$l;
11567
11920
 
11568
11921
  var SelfieGuidanceModelsContext = /*#__PURE__*/React.createContext({
11569
11922
  start: function start() {