idmission-web-sdk 2.3.89 → 2.3.90
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.
- package/dist/components/common/InvisibleCanvas.d.ts +1 -0
- package/dist/components/common/InvisibleCanvas.d.ts.map +1 -1
- package/dist/components/id_capture/BarcodeReadabilityModelProvider.d.ts +29 -0
- package/dist/components/id_capture/BarcodeReadabilityModelProvider.d.ts.map +1 -0
- package/dist/components/id_capture/CapturedDocuments.d.ts +2 -1
- package/dist/components/id_capture/CapturedDocuments.d.ts.map +1 -1
- package/dist/components/id_capture/FocusModelProvider.d.ts.map +1 -1
- package/dist/components/id_capture/IdCapture.d.ts +1 -1
- package/dist/components/id_capture/IdCapture.d.ts.map +1 -1
- package/dist/components/id_capture/IdCaptureModelsProvider.d.ts +17 -1
- package/dist/components/id_capture/IdCaptureModelsProvider.d.ts.map +1 -1
- package/dist/components/id_capture/IdCaptureStateProvider.d.ts +7 -0
- package/dist/components/id_capture/IdCaptureStateProvider.d.ts.map +1 -1
- package/dist/components/id_capture/IdCaptureSuccess.d.ts.map +1 -1
- package/dist/components/id_capture/IdCaptureWizard.d.ts +1 -0
- package/dist/components/id_capture/IdCaptureWizard.d.ts.map +1 -1
- package/dist/components/submission/SubmissionProvider.d.ts +6 -0
- package/dist/components/submission/SubmissionProvider.d.ts.map +1 -1
- package/dist/components/submission/types.d.ts +2 -0
- package/dist/components/submission/types.d.ts.map +1 -1
- package/dist/lib/models/BarcodeReadability.d.ts +50 -0
- package/dist/lib/models/BarcodeReadability.d.ts.map +1 -0
- package/dist/lib/models/DocumentDetection.d.ts +1 -0
- package/dist/lib/models/DocumentDetection.d.ts.map +1 -1
- package/dist/lib/models/Focus.d.ts.map +1 -1
- package/dist/lib/models/defaults/BarcodeReadability.d.ts +2 -0
- package/dist/lib/models/defaults/BarcodeReadability.d.ts.map +1 -0
- package/dist/lib/models/defaults/index.d.ts +7 -0
- package/dist/lib/models/defaults/index.d.ts.map +1 -1
- package/dist/lib/models/preloadModels.d.ts +9 -5
- package/dist/lib/models/preloadModels.d.ts.map +1 -1
- package/dist/lib/utils/cropping.d.ts +3 -1
- package/dist/lib/utils/cropping.d.ts.map +1 -1
- package/dist/sdk2.cjs.development.js +1971 -1490
- package/dist/sdk2.cjs.development.js.map +1 -1
- package/dist/sdk2.cjs.production.js +1 -1
- package/dist/sdk2.cjs.production.js.map +1 -1
- package/dist/sdk2.esm.js +1972 -1491
- package/dist/sdk2.esm.js.map +1 -1
- package/dist/sdk2.umd.development.js +2434 -1953
- package/dist/sdk2.umd.development.js.map +1 -1
- package/dist/sdk2.umd.production.js +1 -1
- package/dist/sdk2.umd.production.js.map +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +3 -3
|
@@ -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.
|
|
239
|
+
var webSdkVersion = '2.3.90';
|
|
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$
|
|
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$P, templateObject_2$
|
|
507
|
+
var templateObject_1$P, templateObject_2$J;
|
|
508
508
|
|
|
509
509
|
var wavesAnimation = styled.keyframes(templateObject_1$O || (templateObject_1$O = __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$
|
|
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$o || (templateObject_4$o = __makeTemplateObject(["\n to {\n stroke-dashoffset: 0;\n }\n"], ["\n to {\n stroke-dashoffset: 0;\n }\n"])));
|
|
513
|
-
var templateObject_1$O, templateObject_2$
|
|
513
|
+
var templateObject_1$O, templateObject_2$I, templateObject_3$u, templateObject_4$o;
|
|
514
514
|
|
|
515
515
|
var OverlayContainer = 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\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$
|
|
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$N, templateObject_2$
|
|
568
|
+
var templateObject_1$N, templateObject_2$H, templateObject_3$t, templateObject_4$n, templateObject_5$f, 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
|
},
|
|
@@ -1337,59 +1345,62 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
1337
1345
|
passportImage = _13[0],
|
|
1338
1346
|
setPassportImage = _13[1];
|
|
1339
1347
|
var _14 = React.useState(null),
|
|
1340
|
-
|
|
1341
|
-
|
|
1348
|
+
idBarcodeImage = _14[0],
|
|
1349
|
+
setIdBarcodeImage = _14[1];
|
|
1342
1350
|
var _15 = React.useState(null),
|
|
1343
|
-
|
|
1344
|
-
|
|
1351
|
+
selfieImage = _15[0],
|
|
1352
|
+
setSelfieImage = _15[1];
|
|
1345
1353
|
var _16 = React.useState(null),
|
|
1346
|
-
|
|
1347
|
-
|
|
1354
|
+
signatureData = _16[0],
|
|
1355
|
+
setSignatureData = _16[1];
|
|
1348
1356
|
var _17 = React.useState(null),
|
|
1349
|
-
|
|
1350
|
-
|
|
1357
|
+
signatureVideoUrl = _17[0],
|
|
1358
|
+
setSignatureVideoUrl = _17[1];
|
|
1351
1359
|
var _18 = React.useState(null),
|
|
1352
|
-
|
|
1353
|
-
|
|
1360
|
+
signatureStartTimestamp = _18[0],
|
|
1361
|
+
setSignatureStartTimestamp = _18[1];
|
|
1354
1362
|
var _19 = React.useState(null),
|
|
1355
|
-
|
|
1356
|
-
|
|
1363
|
+
signatureEndTimestamp = _19[0],
|
|
1364
|
+
setSignatureEndTimestamp = _19[1];
|
|
1357
1365
|
var _20 = React.useState(null),
|
|
1358
|
-
|
|
1359
|
-
|
|
1366
|
+
idCaptureVideoUrl = _20[0],
|
|
1367
|
+
setIdCaptureVideoUrl = _20[1];
|
|
1360
1368
|
var _21 = React.useState(null),
|
|
1361
|
-
|
|
1362
|
-
|
|
1369
|
+
idCaptureVideoIdFrontImage = _21[0],
|
|
1370
|
+
setIdCaptureVideoIdFrontImage = _21[1];
|
|
1363
1371
|
var _22 = React.useState(null),
|
|
1364
|
-
|
|
1365
|
-
|
|
1372
|
+
idCaptureVideoIdBackImage = _22[0],
|
|
1373
|
+
setIdCaptureVideoIdBackImage = _22[1];
|
|
1366
1374
|
var _23 = React.useState(null),
|
|
1367
|
-
|
|
1368
|
-
|
|
1375
|
+
idCaptureVideoAudioUrl = _23[0],
|
|
1376
|
+
setIdCaptureVideoAudioUrl = _23[1];
|
|
1369
1377
|
var _24 = React.useState(null),
|
|
1370
|
-
|
|
1371
|
-
|
|
1378
|
+
idCaptureVideoAudioStartsAt = _24[0],
|
|
1379
|
+
setIdCaptureVideoAudioStartsAt = _24[1];
|
|
1372
1380
|
var _25 = React.useState(null),
|
|
1373
|
-
|
|
1374
|
-
|
|
1381
|
+
expectedAudioText = _25[0],
|
|
1382
|
+
setExpectedAudioText = _25[1];
|
|
1375
1383
|
var _26 = React.useState(null),
|
|
1376
|
-
|
|
1377
|
-
|
|
1378
|
-
var _27 = React.useState(
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
var _28 = React.useState(
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
var _29 = React.useState(
|
|
1385
|
-
|
|
1386
|
-
|
|
1384
|
+
additionalDocuments = _26[0],
|
|
1385
|
+
setAdditionalDocuments = _26[1];
|
|
1386
|
+
var _27 = React.useState(null),
|
|
1387
|
+
geolocationResult = _27[0],
|
|
1388
|
+
setGeolocationResult = _27[1];
|
|
1389
|
+
var _28 = React.useState(0),
|
|
1390
|
+
geolocationAttempts = _28[0],
|
|
1391
|
+
setGeolocationAttempts = _28[1];
|
|
1392
|
+
var _29 = React.useState(false),
|
|
1393
|
+
geolocationBlocked = _29[0],
|
|
1394
|
+
setGeolocationBlocked = _29[1];
|
|
1387
1395
|
var _30 = React.useState([]),
|
|
1388
|
-
|
|
1389
|
-
|
|
1396
|
+
idFrontCaptureAttempts = _30[0],
|
|
1397
|
+
setIdFrontCaptureAttempts = _30[1];
|
|
1390
1398
|
var _31 = React.useState([]),
|
|
1391
|
-
|
|
1392
|
-
|
|
1399
|
+
idBackCaptureAttempts = _31[0],
|
|
1400
|
+
setIdBackCaptureAttempts = _31[1];
|
|
1401
|
+
var _32 = React.useState([]),
|
|
1402
|
+
selfieCaptureAttempts = _32[0],
|
|
1403
|
+
setSelfieCaptureAttempts = _32[1];
|
|
1393
1404
|
var logIdFrontCaptureAttempt = React.useCallback(function (attempt) {
|
|
1394
1405
|
setIdFrontCaptureAttempts(function (attempts) {
|
|
1395
1406
|
return __spreadArray(__spreadArray([], attempts, true), [attempt], false);
|
|
@@ -1515,6 +1526,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
1515
1526
|
idFrontImage: idFrontImage,
|
|
1516
1527
|
idBackImage: idBackImage,
|
|
1517
1528
|
passportImage: passportImage,
|
|
1529
|
+
idBarcodeImage: idBarcodeImage,
|
|
1518
1530
|
selfieImage: selfieImage
|
|
1519
1531
|
};
|
|
1520
1532
|
_a = signatureVideoUrl;
|
|
@@ -1620,6 +1632,9 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
1620
1632
|
if (documents.passportImage) {
|
|
1621
1633
|
submissionRequest.customerData.idData.idImageFront = documents.passportImage;
|
|
1622
1634
|
}
|
|
1635
|
+
if (documents.idBarcodeImage) {
|
|
1636
|
+
submissionRequest.customerData.idData.idBarcodeImage = documents.idBarcodeImage;
|
|
1637
|
+
}
|
|
1623
1638
|
if (documents.idFrontIrImage) {
|
|
1624
1639
|
submissionRequest.customerData.idData.idFrontIrImage = documents.idFrontIrImage;
|
|
1625
1640
|
}
|
|
@@ -1714,7 +1729,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
1714
1729
|
}
|
|
1715
1730
|
});
|
|
1716
1731
|
});
|
|
1717
|
-
}, [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, signatureEndTimestamp, signatureStartTimestamp, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
|
|
1732
|
+
}, [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, signatureEndTimestamp, signatureStartTimestamp, signatureVideoUrl, uploadDocument, verifyIdWithExternalDatabases, webhooksClientTraceId, webhooksEnabled, webhooksFireOnReview, webhooksFireOnReviewURL, webhooksSendInputImages, webhooksSendProcessedImages, webhooksStripSpecialCharacters, webhooksURL]);
|
|
1718
1733
|
var defaultOnSubmit = React.useCallback(function () {
|
|
1719
1734
|
return __awaiter(void 0, void 0, void 0, function () {
|
|
1720
1735
|
var submissionResponse_1, payload, host, endpoint, response, statusMessage, submissionResponse_2, e_1, err;
|
|
@@ -1992,6 +2007,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
1992
2007
|
idFrontUvImage: idFrontUvImage,
|
|
1993
2008
|
idBackUvImage: idBackUvImage,
|
|
1994
2009
|
passportImage: passportImage,
|
|
2010
|
+
idBarcodeImage: idBarcodeImage,
|
|
1995
2011
|
selfieImage: selfieImage,
|
|
1996
2012
|
signatureData: signatureData,
|
|
1997
2013
|
signatureVideoUrl: signatureVideoUrl,
|
|
@@ -2008,6 +2024,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
2008
2024
|
setIdBackIrImage: setIdBackIrImage,
|
|
2009
2025
|
setIdFrontUvImage: setIdFrontUvImage,
|
|
2010
2026
|
setIdBackUvImage: setIdBackUvImage,
|
|
2027
|
+
setIdBarcodeImage: setIdBarcodeImage,
|
|
2011
2028
|
setSelfieImage: setSelfieImage,
|
|
2012
2029
|
setSignatureData: setSignatureData,
|
|
2013
2030
|
setSignatureVideoUrl: setSignatureVideoUrl,
|
|
@@ -2028,7 +2045,7 @@ var SubmissionProvider = function SubmissionProvider(_a) {
|
|
|
2028
2045
|
checkLiveness: checkLiveness,
|
|
2029
2046
|
retryLocationAccess: retryLocationAccess
|
|
2030
2047
|
};
|
|
2031
|
-
}, [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]);
|
|
2048
|
+
}, [additionalDocuments, checkLiveness, environment, idBackImage, idBackIrImage, idBackUvImage, idBarcodeImage, idCaptureVideoAudioStartsAt, idCaptureVideoAudioUrl, idCaptureVideoIdBackImage, idCaptureVideoIdFrontImage, idCaptureVideoUrl, idFrontImage, idFrontIrImage, idFrontUvImage, livenessCheckRequest, logIdBackCaptureAttempt, logIdFrontCaptureAttempt, logSelfieCaptureAttempt, passportImage, retryLocationAccess, selfieImage, signatureData, signatureVideoUrl, submissionError, submissionRequest, submissionResponse, submissionStatus, submit, uploadDocument]);
|
|
2032
2049
|
return /*#__PURE__*/React__namespace.default.createElement(SubmissionContext.Provider, {
|
|
2033
2050
|
value: value
|
|
2034
2051
|
}, geolocationRequired && geolocationBlocked ? ( /*#__PURE__*/React__namespace.default.createElement(GeolocationAccessDeniedOverlay, null)) : children, submissionError && ( /*#__PURE__*/React__namespace.default.createElement(SubmissionErrorOverlay, {
|
|
@@ -2222,97 +2239,6 @@ function preloadVisionRuntime() {
|
|
|
2222
2239
|
});
|
|
2223
2240
|
}
|
|
2224
2241
|
|
|
2225
|
-
function getFrameDimensions(frame) {
|
|
2226
|
-
var frameWidth = frame.width,
|
|
2227
|
-
frameHeight = frame.height;
|
|
2228
|
-
if (frame instanceof HTMLImageElement) {
|
|
2229
|
-
frameWidth = frame.naturalWidth;
|
|
2230
|
-
frameHeight = frame.naturalHeight;
|
|
2231
|
-
}
|
|
2232
|
-
if (frame instanceof HTMLVideoElement) {
|
|
2233
|
-
frameWidth = frame.videoWidth;
|
|
2234
|
-
frameHeight = frame.videoHeight;
|
|
2235
|
-
}
|
|
2236
|
-
return [frameWidth, frameHeight];
|
|
2237
|
-
}
|
|
2238
|
-
|
|
2239
|
-
var InvisibleCanvas = styled__default.default.canvas(templateObject_1$M || (templateObject_1$M = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
|
|
2240
|
-
function drawToCanvas(canvas, frame, width, height) {
|
|
2241
|
-
if (!canvas) return;
|
|
2242
|
-
var ctx = canvas.getContext('2d');
|
|
2243
|
-
if (!ctx) return;
|
|
2244
|
-
if (!width || !height) {
|
|
2245
|
-
var _a = getFrameDimensions(frame),
|
|
2246
|
-
frameWidth = _a[0],
|
|
2247
|
-
frameHeight = _a[1];
|
|
2248
|
-
width || (width = frameWidth);
|
|
2249
|
-
height || (height = frameHeight);
|
|
2250
|
-
}
|
|
2251
|
-
canvas.width = width;
|
|
2252
|
-
canvas.height = height;
|
|
2253
|
-
ctx.drawImage(frame, 0, 0, width, height);
|
|
2254
|
-
}
|
|
2255
|
-
function clearCanvas(canvas) {
|
|
2256
|
-
var _a;
|
|
2257
|
-
(_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);
|
|
2258
|
-
}
|
|
2259
|
-
var templateObject_1$M;
|
|
2260
|
-
|
|
2261
|
-
function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
|
|
2262
|
-
var _a;
|
|
2263
|
-
if (quality === void 0) {
|
|
2264
|
-
quality = 0.92;
|
|
2265
|
-
}
|
|
2266
|
-
if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
|
|
2267
|
-
var rawCtx = rawCanvas.getContext('2d');
|
|
2268
|
-
var cropCtx = cropCanvas.getContext('2d');
|
|
2269
|
-
var resizeCtx = resizeCanvas.getContext('2d');
|
|
2270
|
-
if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
|
|
2271
|
-
rawCanvas.width = frame.width;
|
|
2272
|
-
rawCanvas.height = frame.height;
|
|
2273
|
-
rawCtx.putImageData(frame, 0, 0);
|
|
2274
|
-
if (frame.height > frame.width) {
|
|
2275
|
-
cropCanvas.width = frame.width;
|
|
2276
|
-
cropCanvas.height = frame.height;
|
|
2277
|
-
cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
|
|
2278
|
-
} else {
|
|
2279
|
-
var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
|
|
2280
|
-
xMin: 0,
|
|
2281
|
-
width: frame.width
|
|
2282
|
-
},
|
|
2283
|
-
xMin = _b.xMin,
|
|
2284
|
-
width = _b.width;
|
|
2285
|
-
var desiredWidth = frame.height * 0.6;
|
|
2286
|
-
var faceCenterX = xMin + width / 2;
|
|
2287
|
-
var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
|
|
2288
|
-
cropCanvas.width = desiredWidth;
|
|
2289
|
-
cropCanvas.height = frame.height;
|
|
2290
|
-
cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
|
|
2291
|
-
}
|
|
2292
|
-
resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
|
|
2293
|
-
resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
|
|
2294
|
-
resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
|
|
2295
|
-
var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
|
|
2296
|
-
log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
|
|
2297
|
-
clearCanvas(rawCanvas);
|
|
2298
|
-
clearCanvas(cropCanvas);
|
|
2299
|
-
clearCanvas(resizeCanvas);
|
|
2300
|
-
return dataURL;
|
|
2301
|
-
}
|
|
2302
|
-
function cropToDetectedObjectBox(frame, box, canvas) {
|
|
2303
|
-
canvas || (canvas = document.createElement('canvas'));
|
|
2304
|
-
var ctx = canvas.getContext('2d');
|
|
2305
|
-
if (!ctx) throw new Error('could not get 2d context');
|
|
2306
|
-
var xMin = box.xMin,
|
|
2307
|
-
yMin = box.yMin,
|
|
2308
|
-
width = box.width,
|
|
2309
|
-
height = box.height;
|
|
2310
|
-
canvas.width = width;
|
|
2311
|
-
canvas.height = height;
|
|
2312
|
-
ctx.drawImage(frame, xMin, yMin, width, height, 0, 0, width, height);
|
|
2313
|
-
return canvas;
|
|
2314
|
-
}
|
|
2315
|
-
|
|
2316
2242
|
var defaultImageSegmenterModelPath = 'https://websdk-cdn-dev.idmission.com/assets/models/selfiesegmenter20240524/selfie_segmenter.tflite';
|
|
2317
2243
|
var imageSegmenterModelSizeInBytes = 256440.32;
|
|
2318
2244
|
// 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
|
|
@@ -2442,6 +2368,192 @@ function giveUpAfter(maxTime) {
|
|
|
2442
2368
|
});
|
|
2443
2369
|
}
|
|
2444
2370
|
|
|
2371
|
+
var DEFAULT_CDN_URL = 'https://websdk-cdn-dev.idmission.com/assets';
|
|
2372
|
+
|
|
2373
|
+
var defaultDocumentDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/DocumentDetector/DocumentDetector-20250815_115859.tflite");
|
|
2374
|
+
|
|
2375
|
+
var defaultFocusModelPath = "".concat(DEFAULT_CDN_URL, "/models/Focus/Focus-20241008_102708.tflite");
|
|
2376
|
+
|
|
2377
|
+
var defaultFaceDetectorModelPath = "".concat(DEFAULT_CDN_URL, "/models/FaceDetector/FaceDetector-20250820_154546.tflite");
|
|
2378
|
+
|
|
2379
|
+
var defaultBarcodeReadabilityModelPath = "".concat(DEFAULT_CDN_URL, "/models/BarcodeReadability/BarcodeReadability-20250815_120417.tflite");
|
|
2380
|
+
|
|
2381
|
+
var defaultModelPaths = {
|
|
2382
|
+
documentDetector: defaultDocumentDetectorModelPath,
|
|
2383
|
+
focus: defaultFocusModelPath,
|
|
2384
|
+
faceDetection: defaultFaceDetectorModelPath,
|
|
2385
|
+
barcodeReadability: defaultBarcodeReadabilityModelPath
|
|
2386
|
+
};
|
|
2387
|
+
|
|
2388
|
+
var preloadModels = function preloadModels(_a) {
|
|
2389
|
+
return __awaiter(void 0, [_a], void 0, function (_b) {
|
|
2390
|
+
var preloadTasks;
|
|
2391
|
+
var _c = _b.documentDetectionModel,
|
|
2392
|
+
documentDetectionModel = _c === void 0 ? true : _c,
|
|
2393
|
+
_d = _b.focusModel,
|
|
2394
|
+
focusModel = _d === void 0 ? true : _d,
|
|
2395
|
+
_e = _b.faceDetectionModel,
|
|
2396
|
+
faceDetectionModel = _e === void 0 ? true : _e,
|
|
2397
|
+
_f = _b.barcodeReadabilityModel,
|
|
2398
|
+
barcodeReadabilityModel = _f === void 0 ? true : _f;
|
|
2399
|
+
return __generator(this, function (_g) {
|
|
2400
|
+
switch (_g.label) {
|
|
2401
|
+
case 0:
|
|
2402
|
+
return [4 /*yield*/, probeModelCapabilities()];
|
|
2403
|
+
case 1:
|
|
2404
|
+
_g.sent();
|
|
2405
|
+
preloadTasks = [];
|
|
2406
|
+
if (documentDetectionModel) {
|
|
2407
|
+
preloadTasks.push(preloadDocumentDetectorDependencies);
|
|
2408
|
+
}
|
|
2409
|
+
if (focusModel) {
|
|
2410
|
+
preloadTasks.push(preloadFocusModelDependencies);
|
|
2411
|
+
}
|
|
2412
|
+
if (faceDetectionModel) {
|
|
2413
|
+
preloadTasks.push(preloadFaceDetectorDependencies);
|
|
2414
|
+
}
|
|
2415
|
+
if (barcodeReadabilityModel) {
|
|
2416
|
+
preloadTasks.push(preloadBarcodeReadabilityModelDependencies);
|
|
2417
|
+
}
|
|
2418
|
+
return [4 /*yield*/, Promise.all(preloadTasks)];
|
|
2419
|
+
case 2:
|
|
2420
|
+
_g.sent();
|
|
2421
|
+
return [2 /*return*/];
|
|
2422
|
+
}
|
|
2423
|
+
});
|
|
2424
|
+
});
|
|
2425
|
+
};
|
|
2426
|
+
var progressByUrl = {};
|
|
2427
|
+
var progressByUseCase = {
|
|
2428
|
+
visionRuntime: {
|
|
2429
|
+
loaded: 0,
|
|
2430
|
+
total: 0
|
|
2431
|
+
},
|
|
2432
|
+
documentDetector: {
|
|
2433
|
+
loaded: 0,
|
|
2434
|
+
total: 0
|
|
2435
|
+
},
|
|
2436
|
+
focus: {
|
|
2437
|
+
loaded: 0,
|
|
2438
|
+
total: 0
|
|
2439
|
+
},
|
|
2440
|
+
faceDetection: {
|
|
2441
|
+
loaded: 0,
|
|
2442
|
+
total: 0
|
|
2443
|
+
},
|
|
2444
|
+
barcodeReadability: {
|
|
2445
|
+
loaded: 0,
|
|
2446
|
+
total: 0
|
|
2447
|
+
}
|
|
2448
|
+
};
|
|
2449
|
+
function preloadDependency(url) {
|
|
2450
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2451
|
+
return __generator(this, function (_a) {
|
|
2452
|
+
return [2 /*return*/, new Promise(function (resolve, reject) {
|
|
2453
|
+
var req = new XMLHttpRequest();
|
|
2454
|
+
req.addEventListener('progress', function (event) {
|
|
2455
|
+
if (!event.lengthComputable) return;
|
|
2456
|
+
progressByUrl[url] = event;
|
|
2457
|
+
document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
|
|
2458
|
+
detail: {
|
|
2459
|
+
url: url,
|
|
2460
|
+
loaded: event.loaded,
|
|
2461
|
+
total: event.total
|
|
2462
|
+
}
|
|
2463
|
+
}));
|
|
2464
|
+
});
|
|
2465
|
+
req.addEventListener('loadend', function () {
|
|
2466
|
+
resolve(req.readyState === 4 && req.status === 200);
|
|
2467
|
+
});
|
|
2468
|
+
req.addEventListener('error', reject);
|
|
2469
|
+
req.open('GET', url, true);
|
|
2470
|
+
req.send();
|
|
2471
|
+
})];
|
|
2472
|
+
});
|
|
2473
|
+
});
|
|
2474
|
+
}
|
|
2475
|
+
var modelsPreloading = {
|
|
2476
|
+
documentDetector: false,
|
|
2477
|
+
focus: false,
|
|
2478
|
+
faceDetection: false,
|
|
2479
|
+
barcodeReadability: false
|
|
2480
|
+
};
|
|
2481
|
+
var preloadDocumentDetectorDependencies = function preloadDocumentDetectorDependencies() {
|
|
2482
|
+
return preloadModelDependencies('documentDetector');
|
|
2483
|
+
};
|
|
2484
|
+
var preloadFocusModelDependencies = function preloadFocusModelDependencies() {
|
|
2485
|
+
return preloadModelDependencies('focus');
|
|
2486
|
+
};
|
|
2487
|
+
var preloadFaceDetectorDependencies = function preloadFaceDetectorDependencies() {
|
|
2488
|
+
return preloadModelDependencies('faceDetection');
|
|
2489
|
+
};
|
|
2490
|
+
var preloadBarcodeReadabilityModelDependencies = function preloadBarcodeReadabilityModelDependencies() {
|
|
2491
|
+
return preloadModelDependencies('barcodeReadability');
|
|
2492
|
+
};
|
|
2493
|
+
function preloadModelDependencies(model) {
|
|
2494
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2495
|
+
function handleModelDownloadProgress(event) {
|
|
2496
|
+
var detail = event.detail;
|
|
2497
|
+
if (!dependencies.includes(detail.url)) return;
|
|
2498
|
+
progressByUseCase[model] = sumUpProgressForDependencies(dependencies);
|
|
2499
|
+
document.dispatchEvent(new CustomEvent("idmission.preloadProgress.".concat(model), {
|
|
2500
|
+
detail: progressByUseCase[model]
|
|
2501
|
+
}));
|
|
2502
|
+
}
|
|
2503
|
+
var dependencies;
|
|
2504
|
+
return __generator(this, function (_a) {
|
|
2505
|
+
switch (_a.label) {
|
|
2506
|
+
case 0:
|
|
2507
|
+
if (modelsPreloading[model]) return [2 /*return*/, new Promise(function (resolve) {
|
|
2508
|
+
var i = setInterval(function () {
|
|
2509
|
+
if (!modelsPreloading[model]) {
|
|
2510
|
+
clearInterval(i);
|
|
2511
|
+
resolve();
|
|
2512
|
+
}
|
|
2513
|
+
}, 100);
|
|
2514
|
+
})];
|
|
2515
|
+
modelsPreloading[model] = true;
|
|
2516
|
+
return [4 /*yield*/, probeModelCapabilities()];
|
|
2517
|
+
case 1:
|
|
2518
|
+
_a.sent();
|
|
2519
|
+
if (modelCapabilities.delegate === 'NONE') {
|
|
2520
|
+
throw new Error("No available delegate for ".concat(model, " model."));
|
|
2521
|
+
}
|
|
2522
|
+
dependencies = [defaultModelPaths[model]];
|
|
2523
|
+
document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
|
|
2524
|
+
_a.label = 2;
|
|
2525
|
+
case 2:
|
|
2526
|
+
_a.trys.push([2,, 4, 5]);
|
|
2527
|
+
return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
|
|
2528
|
+
case 3:
|
|
2529
|
+
_a.sent();
|
|
2530
|
+
return [3 /*break*/, 5];
|
|
2531
|
+
case 4:
|
|
2532
|
+
document.removeEventListener('idmission.preloadProgress', handleModelDownloadProgress);
|
|
2533
|
+
modelsPreloading[model] = false;
|
|
2534
|
+
return [7 /*endfinally*/];
|
|
2535
|
+
case 5:
|
|
2536
|
+
return [2 /*return*/];
|
|
2537
|
+
}
|
|
2538
|
+
});
|
|
2539
|
+
});
|
|
2540
|
+
}
|
|
2541
|
+
function progressToPercentage(progress) {
|
|
2542
|
+
return progress.total > 0 ? Math.round(100.0 * progress.loaded / progress.total) : 0;
|
|
2543
|
+
}
|
|
2544
|
+
function sumUpProgressForDependencies(dependencies) {
|
|
2545
|
+
return dependencies.reduce(function (result, dependency) {
|
|
2546
|
+
var dependencyProgress = progressByUrl[dependency];
|
|
2547
|
+
if (!dependencyProgress) return result;
|
|
2548
|
+
result.loaded += dependencyProgress.loaded;
|
|
2549
|
+
result.total += dependencyProgress.total;
|
|
2550
|
+
return result;
|
|
2551
|
+
}, {
|
|
2552
|
+
loaded: 0,
|
|
2553
|
+
total: 0
|
|
2554
|
+
});
|
|
2555
|
+
}
|
|
2556
|
+
|
|
2445
2557
|
function convertBoundingBox(box) {
|
|
2446
2558
|
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
2447
2559
|
return {
|
|
@@ -2496,53 +2608,50 @@ function average(arr) {
|
|
|
2496
2608
|
return sum / len;
|
|
2497
2609
|
}
|
|
2498
2610
|
|
|
2499
|
-
var
|
|
2500
|
-
|
|
2501
|
-
var
|
|
2502
|
-
|
|
2503
|
-
|
|
2504
|
-
|
|
2505
|
-
|
|
2506
|
-
|
|
2507
|
-
|
|
2508
|
-
|
|
2509
|
-
|
|
2510
|
-
|
|
2511
|
-
mobile: 0.3
|
|
2512
|
-
},
|
|
2513
|
-
idCardBack: {
|
|
2514
|
-
desktop: 0,
|
|
2515
|
-
mobile: 0.3
|
|
2516
|
-
},
|
|
2517
|
-
passport: {
|
|
2518
|
-
desktop: 0,
|
|
2519
|
-
mobile: 0.3
|
|
2520
|
-
},
|
|
2521
|
-
singlePage: {
|
|
2522
|
-
desktop: 0,
|
|
2523
|
-
mobile: 0.3
|
|
2611
|
+
var defaultDocumentDetectionScoreThreshold = 0.1;
|
|
2612
|
+
var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
|
|
2613
|
+
var defaultDocumentDetectionThresholds = {
|
|
2614
|
+
idCardFront: 0.6,
|
|
2615
|
+
idCardBack: 0.6,
|
|
2616
|
+
passport: 0.4,
|
|
2617
|
+
singlePage: 0.4,
|
|
2618
|
+
stability: {
|
|
2619
|
+
idCardFront: 0.85,
|
|
2620
|
+
idCardBack: 0.85,
|
|
2621
|
+
passport: 0.5,
|
|
2622
|
+
singlePage: 0.5
|
|
2524
2623
|
}
|
|
2525
2624
|
};
|
|
2526
|
-
var
|
|
2527
|
-
|
|
2528
|
-
|
|
2529
|
-
|
|
2625
|
+
var documentTypeDisplayNames = {
|
|
2626
|
+
idCardFront: 'ID card front',
|
|
2627
|
+
idCardBack: 'ID card back',
|
|
2628
|
+
passport: 'Passport',
|
|
2629
|
+
singlePage: 'Single page',
|
|
2630
|
+
none: 'None'
|
|
2631
|
+
};
|
|
2632
|
+
var detector$1 = null;
|
|
2633
|
+
var detectorSettings$1 = null;
|
|
2634
|
+
function loadDocumentDetector() {
|
|
2635
|
+
return __awaiter(this, arguments, void 0, function (modelAssetPath, scoreThreshold) {
|
|
2530
2636
|
var _a, _b;
|
|
2531
2637
|
if (modelAssetPath === void 0) {
|
|
2532
|
-
modelAssetPath =
|
|
2638
|
+
modelAssetPath = defaultDocumentDetectorModelPath;
|
|
2639
|
+
}
|
|
2640
|
+
if (scoreThreshold === void 0) {
|
|
2641
|
+
scoreThreshold = defaultDocumentDetectionScoreThreshold;
|
|
2533
2642
|
}
|
|
2534
2643
|
return __generator(this, function (_c) {
|
|
2535
2644
|
switch (_c.label) {
|
|
2536
2645
|
case 0:
|
|
2537
|
-
if (
|
|
2538
|
-
|
|
2539
|
-
return [4 /*yield*/,
|
|
2646
|
+
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];
|
|
2647
|
+
closeDocumentDetector();
|
|
2648
|
+
return [4 /*yield*/, preloadDocumentDetectorDependencies()];
|
|
2540
2649
|
case 1:
|
|
2541
2650
|
_c.sent();
|
|
2542
2651
|
if (modelCapabilities.delegate === 'NONE') {
|
|
2543
|
-
throw new Error('No available delegate for
|
|
2652
|
+
throw new Error('No available delegate for document detector.');
|
|
2544
2653
|
}
|
|
2545
|
-
_b = (_a = tasksVision.
|
|
2654
|
+
_b = (_a = tasksVision.ObjectDetector).createFromOptions;
|
|
2546
2655
|
return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
|
|
2547
2656
|
case 2:
|
|
2548
2657
|
return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
|
|
@@ -2551,44 +2660,48 @@ function loadFocusModel() {
|
|
|
2551
2660
|
delegate: modelCapabilities.delegate
|
|
2552
2661
|
},
|
|
2553
2662
|
// canvas: document.createElement('canvas'),
|
|
2663
|
+
scoreThreshold: scoreThreshold,
|
|
2554
2664
|
runningMode: 'VIDEO'
|
|
2555
2665
|
}])];
|
|
2556
2666
|
case 3:
|
|
2557
|
-
|
|
2558
|
-
|
|
2559
|
-
modelAssetPath: modelAssetPath
|
|
2667
|
+
detector$1 = _c.sent();
|
|
2668
|
+
detectorSettings$1 = {
|
|
2669
|
+
modelAssetPath: modelAssetPath,
|
|
2670
|
+
scoreThreshold: scoreThreshold
|
|
2560
2671
|
};
|
|
2561
|
-
return [2 /*return*/,
|
|
2672
|
+
return [2 /*return*/, detector$1];
|
|
2562
2673
|
}
|
|
2563
2674
|
});
|
|
2564
2675
|
});
|
|
2565
2676
|
}
|
|
2566
|
-
function
|
|
2567
|
-
|
|
2568
|
-
|
|
2569
|
-
|
|
2677
|
+
function closeDocumentDetector() {
|
|
2678
|
+
detector$1 === null || detector$1 === void 0 ? void 0 : detector$1.close();
|
|
2679
|
+
detector$1 = null;
|
|
2680
|
+
detectorSettings$1 = null;
|
|
2570
2681
|
}
|
|
2571
|
-
function
|
|
2572
|
-
var _b = _a.
|
|
2573
|
-
|
|
2574
|
-
_c = _a.
|
|
2575
|
-
|
|
2682
|
+
function useLoadDocumentDetector(_a) {
|
|
2683
|
+
var _b = _a.shouldLoadModels,
|
|
2684
|
+
shouldLoadModels = _b === void 0 ? true : _b,
|
|
2685
|
+
_c = _a.modelPath,
|
|
2686
|
+
modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
|
|
2687
|
+
_d = _a.modelLoadTimeoutMs,
|
|
2688
|
+
modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
|
|
2689
|
+
_e = _a.scoreThreshold,
|
|
2690
|
+
scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
|
|
2576
2691
|
onModelError = _a.onModelError,
|
|
2577
|
-
videoRef = _a.videoRef
|
|
2578
|
-
|
|
2579
|
-
|
|
2580
|
-
|
|
2581
|
-
modelLoadState = _e[0],
|
|
2582
|
-
setModelLoadState = _e[1];
|
|
2583
|
-
var _f = React.useState(0),
|
|
2584
|
-
modelDownloadProgress = _f[0],
|
|
2585
|
-
setModelDownloadProgress = _f[1];
|
|
2692
|
+
videoRef = _a.videoRef;
|
|
2693
|
+
var _f = React.useState('not-started'),
|
|
2694
|
+
modelLoadState = _f[0],
|
|
2695
|
+
setModelLoadState = _f[1];
|
|
2586
2696
|
var _g = React.useState(null),
|
|
2587
2697
|
modelWarmingStartedAt = _g[0],
|
|
2588
2698
|
setModelWarmingStartedAt = _g[1];
|
|
2589
|
-
var _h = React.useState(
|
|
2590
|
-
|
|
2591
|
-
|
|
2699
|
+
var _h = React.useState(0),
|
|
2700
|
+
modelDownloadProgress = _h[0],
|
|
2701
|
+
setModelDownloadProgress = _h[1];
|
|
2702
|
+
var _j = React.useState(null),
|
|
2703
|
+
modelError = _j[0],
|
|
2704
|
+
setModelError = _j[1];
|
|
2592
2705
|
React.useEffect(function loadModel() {
|
|
2593
2706
|
var _this = this;
|
|
2594
2707
|
if (!shouldLoadModels) return;
|
|
@@ -2597,21 +2710,24 @@ function useLoadFocusModel(_a) {
|
|
|
2597
2710
|
function handleDownloadProgress(event) {
|
|
2598
2711
|
setModelDownloadProgress(progressToPercentage(event.detail));
|
|
2599
2712
|
}
|
|
2600
|
-
document.addEventListener('idmission.preloadProgress.
|
|
2713
|
+
document.addEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
|
|
2601
2714
|
var modelLoadTimeout = setTimeout(function () {
|
|
2602
2715
|
setModelError(new Error('Model loading time limit exceeded.'));
|
|
2603
2716
|
}, modelLoadTimeoutMs);
|
|
2604
2717
|
var cancelVideoReady = function cancelVideoReady() {};
|
|
2605
|
-
|
|
2718
|
+
loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
|
|
2606
2719
|
return __awaiter(_this, void 0, void 0, function () {
|
|
2607
2720
|
var _a, videoReady, cancel, cancelled;
|
|
2608
2721
|
return __generator(this, function (_b) {
|
|
2609
2722
|
switch (_b.label) {
|
|
2610
2723
|
case 0:
|
|
2611
2724
|
setModelDownloadProgress(100);
|
|
2612
|
-
clearTimeout(modelLoadTimeout);
|
|
2613
2725
|
setModelLoadState('warming');
|
|
2614
|
-
setModelWarmingStartedAt(
|
|
2726
|
+
setModelWarmingStartedAt(performance.now());
|
|
2727
|
+
clearTimeout(modelLoadTimeout);
|
|
2728
|
+
return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
|
|
2729
|
+
case 1:
|
|
2730
|
+
_b.sent();
|
|
2615
2731
|
_a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
|
|
2616
2732
|
cancelled = false;
|
|
2617
2733
|
cancelVideoReady = function cancelVideoReady() {
|
|
@@ -2619,11 +2735,11 @@ function useLoadFocusModel(_a) {
|
|
|
2619
2735
|
cancel();
|
|
2620
2736
|
};
|
|
2621
2737
|
return [4 /*yield*/, videoReady];
|
|
2622
|
-
case
|
|
2738
|
+
case 2:
|
|
2623
2739
|
_b.sent();
|
|
2624
2740
|
setTimeout(function () {
|
|
2625
2741
|
if (cancelled) return;
|
|
2626
|
-
|
|
2742
|
+
model.detectForVideo(videoRef.current, performance.now());
|
|
2627
2743
|
setModelLoadState('ready');
|
|
2628
2744
|
}, 500);
|
|
2629
2745
|
return [2 /*return*/];
|
|
@@ -2637,13 +2753,13 @@ function useLoadFocusModel(_a) {
|
|
|
2637
2753
|
clearTimeout(modelLoadTimeout);
|
|
2638
2754
|
});
|
|
2639
2755
|
return function () {
|
|
2640
|
-
log('unloading
|
|
2756
|
+
log('unloading document detection model');
|
|
2641
2757
|
cancelVideoReady();
|
|
2642
|
-
|
|
2758
|
+
closeDocumentDetector();
|
|
2643
2759
|
clearTimeout(modelLoadTimeout);
|
|
2644
|
-
document.removeEventListener('idmission.preloadProgress.
|
|
2760
|
+
document.removeEventListener('idmission.preloadProgress.documentDetector', handleDownloadProgress);
|
|
2645
2761
|
};
|
|
2646
|
-
}, [
|
|
2762
|
+
}, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
|
|
2647
2763
|
React.useEffect(function handleModelError() {
|
|
2648
2764
|
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
2649
2765
|
}, [modelError, onModelError]);
|
|
@@ -2653,185 +2769,41 @@ function useLoadFocusModel(_a) {
|
|
|
2653
2769
|
modelLoadState: modelLoadState,
|
|
2654
2770
|
modelDownloadProgress: modelDownloadProgress,
|
|
2655
2771
|
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
2656
|
-
modelError: modelError
|
|
2772
|
+
modelError: modelError,
|
|
2773
|
+
setModelError: setModelError
|
|
2657
2774
|
};
|
|
2658
2775
|
}, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
|
|
2659
2776
|
}
|
|
2660
|
-
|
|
2661
|
-
|
|
2662
|
-
|
|
2663
|
-
|
|
2664
|
-
|
|
2665
|
-
|
|
2666
|
-
|
|
2667
|
-
|
|
2668
|
-
|
|
2669
|
-
|
|
2670
|
-
|
|
2671
|
-
|
|
2672
|
-
|
|
2673
|
-
|
|
2674
|
-
|
|
2675
|
-
|
|
2676
|
-
|
|
2677
|
-
|
|
2678
|
-
|
|
2679
|
-
|
|
2680
|
-
}
|
|
2681
|
-
function cropIfNecessary(imageData, cropCanvas, rotateCanvas, box) {
|
|
2682
|
-
if (!box) return imageData;
|
|
2683
|
-
var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas);
|
|
2684
|
-
var _a = [box.width, box.height],
|
|
2685
|
-
bw = _a[0],
|
|
2686
|
-
bh = _a[1];
|
|
2687
|
-
if (bh <= bw) return cropped;
|
|
2688
|
-
var ctx = rotateCanvas.getContext('2d');
|
|
2689
|
-
if (!ctx) return cropped;
|
|
2690
|
-
rotateCanvas.width = bh;
|
|
2691
|
-
rotateCanvas.height = bw;
|
|
2692
|
-
ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
|
|
2693
|
-
ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
|
|
2694
|
-
ctx.rotate(1.5708); // 90 deg in radians
|
|
2695
|
-
ctx.drawImage(cropped, -bw / 2, -bh / 2);
|
|
2696
|
-
return rotateCanvas;
|
|
2697
|
-
}
|
|
2698
|
-
|
|
2699
|
-
var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
|
|
2700
|
-
var detector$1 = null;
|
|
2701
|
-
var detectorSettings$1 = null;
|
|
2702
|
-
function loadFaceDetector() {
|
|
2703
|
-
return __awaiter(this, arguments, void 0, function (modelAssetPath) {
|
|
2704
|
-
var _a, _b;
|
|
2705
|
-
if (modelAssetPath === void 0) {
|
|
2706
|
-
modelAssetPath = defaultFaceDetectorModelPath;
|
|
2707
|
-
}
|
|
2708
|
-
return __generator(this, function (_c) {
|
|
2709
|
-
switch (_c.label) {
|
|
2710
|
-
case 0:
|
|
2711
|
-
if (detector$1 && (detectorSettings$1 === null || detectorSettings$1 === void 0 ? void 0 : detectorSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector$1];
|
|
2712
|
-
closeFaceDetector();
|
|
2713
|
-
return [4 /*yield*/, preloadFaceDetectorDependencies()];
|
|
2714
|
-
case 1:
|
|
2715
|
-
_c.sent();
|
|
2716
|
-
if (modelCapabilities.delegate === 'NONE') {
|
|
2717
|
-
throw new Error('No available delegate for face detector.');
|
|
2718
|
-
}
|
|
2719
|
-
_b = (_a = tasksVision.FaceDetector).createFromOptions;
|
|
2720
|
-
return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
|
|
2721
|
-
case 2:
|
|
2722
|
-
return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
|
|
2723
|
-
// canvas: document.createElement('canvas'),
|
|
2724
|
-
baseOptions: {
|
|
2725
|
-
modelAssetPath: modelAssetPath,
|
|
2726
|
-
delegate: modelCapabilities.delegate
|
|
2727
|
-
},
|
|
2728
|
-
runningMode: 'VIDEO'
|
|
2729
|
-
}])];
|
|
2730
|
-
case 3:
|
|
2731
|
-
detector$1 = _c.sent();
|
|
2732
|
-
detectorSettings$1 = {
|
|
2733
|
-
modelAssetPath: modelAssetPath
|
|
2734
|
-
};
|
|
2735
|
-
return [2 /*return*/, detector$1];
|
|
2777
|
+
function makeDocumentDetectorPrediction(frame) {
|
|
2778
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
2779
|
+
var startedAt, prediction, time, frameWidth, frameHeight;
|
|
2780
|
+
return __generator(this, function (_a) {
|
|
2781
|
+
if (!detector$1) return [2 /*return*/, null];
|
|
2782
|
+
startedAt = performance.now();
|
|
2783
|
+
// Detectors can throw errors, for example when using custom URLs that
|
|
2784
|
+
// contain a model that doesn't provide the expected output.
|
|
2785
|
+
try {
|
|
2786
|
+
prediction = detector$1.detectForVideo(frame, performance.now());
|
|
2787
|
+
time = performance.now() - startedAt;
|
|
2788
|
+
frameWidth = frame.width;
|
|
2789
|
+
frameHeight = frame.height;
|
|
2790
|
+
return [2 /*return*/, _assign(_assign({}, prediction), {
|
|
2791
|
+
time: time,
|
|
2792
|
+
frameWidth: frameWidth,
|
|
2793
|
+
frameHeight: frameHeight
|
|
2794
|
+
})];
|
|
2795
|
+
} catch (e) {
|
|
2796
|
+
error('caught object detection error', e);
|
|
2736
2797
|
}
|
|
2798
|
+
return [2 /*return*/, null];
|
|
2737
2799
|
});
|
|
2738
2800
|
});
|
|
2739
2801
|
}
|
|
2740
|
-
|
|
2741
|
-
|
|
2742
|
-
|
|
2743
|
-
|
|
2744
|
-
|
|
2745
|
-
function useLoadFaceDetector(_a) {
|
|
2746
|
-
var onModelError = _a.onModelError,
|
|
2747
|
-
_b = _a.modelLoadTimeoutMs,
|
|
2748
|
-
modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
|
|
2749
|
-
videoRef = _a.videoRef;
|
|
2750
|
-
var _c = React.useState('not-started'),
|
|
2751
|
-
modelLoadState = _c[0],
|
|
2752
|
-
setModelLoadState = _c[1];
|
|
2753
|
-
var _d = React.useState(0),
|
|
2754
|
-
modelDownloadProgress = _d[0],
|
|
2755
|
-
setModelDownloadProgress = _d[1];
|
|
2756
|
-
var _e = React.useState(null),
|
|
2757
|
-
modelWarmingStartedAt = _e[0],
|
|
2758
|
-
setModelWarmingStartedAt = _e[1];
|
|
2759
|
-
var _f = React.useState(null),
|
|
2760
|
-
modelError = _f[0],
|
|
2761
|
-
setModelError = _f[1];
|
|
2762
|
-
React.useEffect(function loadModel() {
|
|
2763
|
-
var _this = this;
|
|
2764
|
-
setModelLoadState('downloading');
|
|
2765
|
-
setModelWarmingStartedAt(null);
|
|
2766
|
-
var modelLoadTimeout = setTimeout(function () {
|
|
2767
|
-
setModelError(new Error('Model loading time limit exceeded.'));
|
|
2768
|
-
}, modelLoadTimeoutMs);
|
|
2769
|
-
function handleDownloadProgress(event) {
|
|
2770
|
-
setModelDownloadProgress(progressToPercentage(event.detail));
|
|
2771
|
-
}
|
|
2772
|
-
document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
|
|
2773
|
-
var cancelVideoReady = function cancelVideoReady() {};
|
|
2774
|
-
loadFaceDetector().then(function (model) {
|
|
2775
|
-
return __awaiter(_this, void 0, void 0, function () {
|
|
2776
|
-
var _a, videoReady, cancel, cancelled;
|
|
2777
|
-
return __generator(this, function (_b) {
|
|
2778
|
-
switch (_b.label) {
|
|
2779
|
-
case 0:
|
|
2780
|
-
setModelDownloadProgress(100);
|
|
2781
|
-
clearTimeout(modelLoadTimeout);
|
|
2782
|
-
setModelLoadState('warming');
|
|
2783
|
-
setModelWarmingStartedAt(new Date().getTime());
|
|
2784
|
-
return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
|
|
2785
|
-
case 1:
|
|
2786
|
-
_b.sent();
|
|
2787
|
-
_a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
|
|
2788
|
-
cancelled = false;
|
|
2789
|
-
cancelVideoReady = function cancelVideoReady() {
|
|
2790
|
-
cancelled = true;
|
|
2791
|
-
cancel();
|
|
2792
|
-
};
|
|
2793
|
-
return [4 /*yield*/, videoReady];
|
|
2794
|
-
case 2:
|
|
2795
|
-
_b.sent();
|
|
2796
|
-
if (cancelled) return [2 /*return*/];
|
|
2797
|
-
model.detectForVideo(videoRef.current, performance.now());
|
|
2798
|
-
setModelLoadState('ready');
|
|
2799
|
-
return [2 /*return*/];
|
|
2800
|
-
}
|
|
2801
|
-
});
|
|
2802
|
-
});
|
|
2803
|
-
})["catch"](function (e) {
|
|
2804
|
-
setModelError(e);
|
|
2805
|
-
setModelLoadState('error');
|
|
2806
|
-
})["finally"](function () {
|
|
2807
|
-
clearTimeout(modelLoadTimeout);
|
|
2808
|
-
});
|
|
2809
|
-
return function () {
|
|
2810
|
-
log('unloading face detection model');
|
|
2811
|
-
cancelVideoReady();
|
|
2812
|
-
closeFaceDetector();
|
|
2813
|
-
clearTimeout(modelLoadTimeout);
|
|
2814
|
-
document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
|
|
2815
|
-
};
|
|
2816
|
-
}, [modelLoadTimeoutMs, videoRef]);
|
|
2817
|
-
React.useEffect(function handleModelError() {
|
|
2818
|
-
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
2819
|
-
}, [modelError, onModelError]);
|
|
2820
|
-
return React.useMemo(function () {
|
|
2821
|
-
return {
|
|
2822
|
-
ready: modelLoadState === 'ready',
|
|
2823
|
-
modelLoadState: modelLoadState,
|
|
2824
|
-
modelDownloadProgress: modelDownloadProgress,
|
|
2825
|
-
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
2826
|
-
modelError: modelError
|
|
2827
|
-
};
|
|
2828
|
-
}, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
|
|
2829
|
-
}
|
|
2830
|
-
var lastFaceDetectionAt = 0;
|
|
2831
|
-
var lastFaceDetectionTime = 0;
|
|
2832
|
-
function setLastFaceDetectionAt(time) {
|
|
2833
|
-
lastFaceDetectionTime = time - lastFaceDetectionAt;
|
|
2834
|
-
lastFaceDetectionAt = time;
|
|
2802
|
+
var lastDetectionAt = 0;
|
|
2803
|
+
var lastDetectionTime = 0;
|
|
2804
|
+
function setLastDetectionAt(time) {
|
|
2805
|
+
lastDetectionTime = time - lastDetectionAt;
|
|
2806
|
+
lastDetectionAt = time;
|
|
2835
2807
|
}
|
|
2836
2808
|
var framesNeededSamples$1 = [];
|
|
2837
2809
|
function trackFramesNeeded$1(value, bufferLength) {
|
|
@@ -2841,970 +2813,375 @@ function trackFramesNeeded$1(value, bufferLength) {
|
|
|
2841
2813
|
framesNeededSamples$1.unshift(value);
|
|
2842
2814
|
if (framesNeededSamples$1.length > bufferLength) framesNeededSamples$1.length = bufferLength;
|
|
2843
2815
|
}
|
|
2844
|
-
var
|
|
2845
|
-
var
|
|
2846
|
-
|
|
2847
|
-
var lastNNosePairs = [];
|
|
2848
|
-
function trackFace(face, framesNeeded, frameWidth, frameHeight) {
|
|
2816
|
+
var lastNBoxes = [];
|
|
2817
|
+
var lastNPairs = [];
|
|
2818
|
+
function trackBox(box, framesNeeded) {
|
|
2849
2819
|
if (framesNeeded === void 0) {
|
|
2850
2820
|
framesNeeded = 12;
|
|
2851
2821
|
}
|
|
2852
|
-
|
|
2853
|
-
if (
|
|
2854
|
-
|
|
2855
|
-
|
|
2856
|
-
|
|
2857
|
-
|
|
2858
|
-
|
|
2859
|
-
|
|
2860
|
-
var iou = calculateIoU(face.box, lastFace.box);
|
|
2861
|
-
lastNFacePairs.unshift({
|
|
2862
|
-
a: face,
|
|
2863
|
-
b: lastFace,
|
|
2822
|
+
lastNBoxes.unshift(box);
|
|
2823
|
+
if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
|
|
2824
|
+
if (lastNBoxes.length > 1) {
|
|
2825
|
+
var lastBox = lastNBoxes[1];
|
|
2826
|
+
var iou = calculateIoU(box, lastBox);
|
|
2827
|
+
lastNPairs.unshift({
|
|
2828
|
+
a: box,
|
|
2829
|
+
b: lastBox,
|
|
2864
2830
|
iou: iou
|
|
2865
2831
|
});
|
|
2866
|
-
if (
|
|
2832
|
+
if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
|
|
2867
2833
|
}
|
|
2868
|
-
|
|
2869
|
-
|
|
2870
|
-
|
|
2871
|
-
|
|
2872
|
-
|
|
2873
|
-
|
|
2874
|
-
|
|
2834
|
+
}
|
|
2835
|
+
var defaultDocumentDetectionBoundaries = {
|
|
2836
|
+
top: 20,
|
|
2837
|
+
bottom: 20,
|
|
2838
|
+
left: 20,
|
|
2839
|
+
right: 20
|
|
2840
|
+
};
|
|
2841
|
+
function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
|
|
2842
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
2843
|
+
if (boundaries === void 0) {
|
|
2844
|
+
boundaries = defaultDocumentDetectionBoundaries;
|
|
2845
|
+
}
|
|
2846
|
+
var detections = prediction.detections,
|
|
2847
|
+
frameWidth = prediction.frameWidth,
|
|
2848
|
+
frameHeight = prediction.frameHeight,
|
|
2849
|
+
time = prediction.time;
|
|
2850
|
+
var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
|
|
2851
|
+
var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
|
|
2852
|
+
var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
|
|
2853
|
+
var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
|
|
2854
|
+
var frameWidth80Pct = frameWidth * 0.8;
|
|
2855
|
+
var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
|
|
2856
|
+
return d.categories.map(function (category) {
|
|
2857
|
+
return {
|
|
2858
|
+
label: category === null || category === void 0 ? void 0 : category.categoryName,
|
|
2859
|
+
score: category === null || category === void 0 ? void 0 : category.score,
|
|
2860
|
+
box: convertBoundingBox(d.boundingBox)
|
|
2861
|
+
};
|
|
2862
|
+
});
|
|
2863
|
+
}), function (obj) {
|
|
2864
|
+
var _a = obj.box,
|
|
2865
|
+
xMin = _a.xMin,
|
|
2866
|
+
yMin = _a.yMin,
|
|
2867
|
+
width = _a.width,
|
|
2868
|
+
height = _a.height;
|
|
2869
|
+
return yMin > boundaryTop &&
|
|
2870
|
+
// Is it valid top edge of ID detected?
|
|
2871
|
+
yMin + height + boundaryBottom < frameHeight && (
|
|
2872
|
+
// Is it valid bottom edge less than max video height
|
|
2873
|
+
xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
|
|
2874
|
+
// If either the left side visible or if not, right edge of ID should be more than 80% of width.
|
|
2875
|
+
xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
|
|
2876
|
+
;
|
|
2877
|
+
});
|
|
2878
|
+
var allZero = detections.length > 0 && !detections.some(function (_a) {
|
|
2879
|
+
var boundingBox = _a.boundingBox;
|
|
2880
|
+
return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
|
|
2881
|
+
return n > 0;
|
|
2882
|
+
});
|
|
2883
|
+
});
|
|
2884
|
+
var bestIdCardFront = detectedObjects.find(function (obj) {
|
|
2885
|
+
return obj.label === 'Document';
|
|
2886
|
+
});
|
|
2887
|
+
var bestIdCardBack = detectedObjects.find(function (obj) {
|
|
2888
|
+
return obj.label === 'Document back';
|
|
2889
|
+
});
|
|
2890
|
+
var bestPassportPage = detectedObjects.find(function (obj) {
|
|
2891
|
+
return obj.label === 'Passport page';
|
|
2892
|
+
});
|
|
2893
|
+
var bestSinglePage = detectedObjects.find(function (obj) {
|
|
2894
|
+
return obj.label === 'Single page';
|
|
2895
|
+
});
|
|
2896
|
+
var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
|
|
2897
|
+
var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
|
|
2898
|
+
var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
|
|
2899
|
+
var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
|
|
2900
|
+
var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
|
|
2901
|
+
var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
|
|
2902
|
+
var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
|
|
2903
|
+
var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
|
|
2904
|
+
var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
|
|
2905
|
+
var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
|
|
2906
|
+
var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
|
|
2907
|
+
var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
|
|
2908
|
+
var detectedDocumentType = 'none';
|
|
2909
|
+
if (singlePageDetectionThresholdMet) {
|
|
2910
|
+
detectedDocumentType = 'singlePage';
|
|
2911
|
+
} else if (passportDetectionThresholdMet) {
|
|
2912
|
+
detectedDocumentType = 'passport';
|
|
2913
|
+
} else if (idCardBackDetectionThresholdMet) {
|
|
2914
|
+
detectedDocumentType = 'idCardBack';
|
|
2915
|
+
} else if (detectionThresholdMet) {
|
|
2916
|
+
detectedDocumentType = 'idCardFront';
|
|
2917
|
+
}
|
|
2918
|
+
var documentInBounds = !!bestDocument;
|
|
2919
|
+
if (lastDetectionTime > 0) {
|
|
2920
|
+
trackFramesNeeded$1(1000 / lastDetectionTime);
|
|
2921
|
+
}
|
|
2922
|
+
var documentIsStable = false;
|
|
2923
|
+
var documentTooClose = false;
|
|
2924
|
+
if (bestDocument) {
|
|
2925
|
+
var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
|
|
2926
|
+
docWidth = _q[0],
|
|
2927
|
+
docHeight = _q[1];
|
|
2928
|
+
documentTooClose = docWidth > 0.85 || docHeight > 0.85;
|
|
2929
|
+
if (detectionThresholdMet && documentInBounds && !documentTooClose) {
|
|
2930
|
+
var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
|
|
2931
|
+
var threshold_1 = thresholdSet[detectedDocumentType];
|
|
2932
|
+
var framesNeeded = Math.ceil(average(framesNeededSamples$1));
|
|
2933
|
+
trackBox(bestDocument.box, framesNeeded);
|
|
2934
|
+
documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
|
|
2935
|
+
return pair.iou < threshold_1;
|
|
2936
|
+
});
|
|
2937
|
+
}
|
|
2938
|
+
}
|
|
2939
|
+
var bestPDF417;
|
|
2940
|
+
if (detectedObjects.length > 0) {
|
|
2941
|
+
bestPDF417 = detectedObjects.find(function (obj) {
|
|
2942
|
+
return obj.label === 'PDF417';
|
|
2875
2943
|
});
|
|
2876
|
-
if (lastNNosePairs.length > framesNeeded - 1) lastNNosePairs.length = framesNeeded - 1;
|
|
2877
2944
|
}
|
|
2945
|
+
return {
|
|
2946
|
+
prediction: prediction,
|
|
2947
|
+
detectedObjects: detectedObjects,
|
|
2948
|
+
detectionScore: detectionScore,
|
|
2949
|
+
detectionTime: time,
|
|
2950
|
+
detectionThresholdMet: detectionThresholdMet,
|
|
2951
|
+
detectedDocumentType: detectedDocumentType,
|
|
2952
|
+
idCardFrontDetectionScore: idCardFrontDetectionScore,
|
|
2953
|
+
idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
|
|
2954
|
+
idCardBackDetectionScore: idCardBackDetectionScore,
|
|
2955
|
+
idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
|
|
2956
|
+
passportDetectionScore: passportDetectionScore,
|
|
2957
|
+
passportDetectionThresholdMet: passportDetectionThresholdMet,
|
|
2958
|
+
singlePageDetectionScore: singlePageDetectionScore,
|
|
2959
|
+
singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
|
|
2960
|
+
bestDocument: bestDocument,
|
|
2961
|
+
bestPDF417: bestPDF417,
|
|
2962
|
+
documentInBounds: documentInBounds,
|
|
2963
|
+
documentTooClose: documentTooClose,
|
|
2964
|
+
documentIsStable: documentIsStable,
|
|
2965
|
+
frameWidth: frameWidth,
|
|
2966
|
+
frameHeight: frameHeight,
|
|
2967
|
+
allZero: allZero
|
|
2968
|
+
};
|
|
2878
2969
|
}
|
|
2879
|
-
function
|
|
2880
|
-
|
|
2881
|
-
|
|
2882
|
-
|
|
2883
|
-
|
|
2884
|
-
|
|
2885
|
-
|
|
2886
|
-
var _a;
|
|
2887
|
-
return _assign(_assign({}, k), {
|
|
2888
|
-
x: k.x * imageData.width,
|
|
2889
|
-
y: k.y * imageData.height,
|
|
2890
|
-
name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
|
|
2891
|
-
});
|
|
2892
|
-
})
|
|
2893
|
-
};
|
|
2970
|
+
function applyNonMaxSuppression(detectedObjects, isGoodBox) {
|
|
2971
|
+
var maxes = {};
|
|
2972
|
+
detectedObjects.forEach(function (obj, i) {
|
|
2973
|
+
if (obj) {
|
|
2974
|
+
if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
|
|
2975
|
+
if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
|
|
2976
|
+
}
|
|
2894
2977
|
});
|
|
2895
|
-
return
|
|
2896
|
-
|
|
2978
|
+
return Object.keys(maxes).map(function (label) {
|
|
2979
|
+
return detectedObjects[maxes[label][1]];
|
|
2980
|
+
}).filter(function (obj) {
|
|
2981
|
+
return !!obj;
|
|
2897
2982
|
});
|
|
2898
2983
|
}
|
|
2899
|
-
function
|
|
2900
|
-
var faces = _a.faces,
|
|
2901
|
-
videoWidth = _a.videoWidth,
|
|
2902
|
-
videoHeight = _a.videoHeight,
|
|
2903
|
-
_b = _a.requireVerticalFaceCentering,
|
|
2904
|
-
requireVerticalFaceCentering = _b === void 0 ? true : _b,
|
|
2905
|
-
_c = _a.stabilityThreshold,
|
|
2906
|
-
stabilityThreshold = _c === void 0 ? 0.7 : _c,
|
|
2907
|
-
_d = _a.noseDistanceThreshold,
|
|
2908
|
-
noseDistanceThreshold = _d === void 0 ? 0.025 : _d,
|
|
2909
|
-
_e = _a.xBoundary,
|
|
2910
|
-
xBoundary = _e === void 0 ? 0.01 : _e,
|
|
2911
|
-
// this represents the edge that the sides of the face box should not cross -- 1% of video width
|
|
2912
|
-
_f = _a.yBoundary,
|
|
2913
|
-
// this represents the edge that the sides of the face box should not cross -- 1% of video width
|
|
2914
|
-
yBoundary = _f === void 0 ? 0.01 : _f,
|
|
2915
|
-
// this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
|
|
2916
|
-
_g = _a.xCentroidBoundary,
|
|
2917
|
-
// this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
|
|
2918
|
-
xCentroidBoundary = _g === void 0 ? 0.125 : _g,
|
|
2919
|
-
// this represents the edge that the centroid of the face should not cross -- 12.5% of video width
|
|
2920
|
-
_h = _a.yCentroidBoundary,
|
|
2921
|
-
// this represents the edge that the centroid of the face should not cross -- 12.5% of video width
|
|
2922
|
-
yCentroidBoundary = _h === void 0 ? 0.125 : _h,
|
|
2923
|
-
// this represents the edge that the centroid of the face should not cross -- 12.5% of video height
|
|
2924
|
-
_j = _a.foreheadRatio,
|
|
2925
|
-
// this represents the edge that the centroid of the face should not cross -- 12.5% of video height
|
|
2926
|
-
foreheadRatio = _j === void 0 ? 0.275 : _j,
|
|
2927
|
-
// we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
|
|
2928
|
-
_k = _a.noseTrackingThreshold,
|
|
2929
|
-
// we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
|
|
2930
|
-
noseTrackingThreshold = _k === void 0 ? 0.2 : _k,
|
|
2931
|
-
// this represents the maximum distance that the nose can be from the center of the face box -- 20% of the face box width or height
|
|
2932
|
-
minCaptureBrightnessThreshold = _a.minCaptureBrightnessThreshold,
|
|
2933
|
-
minCaptureRangeThreshold = _a.minCaptureRangeThreshold,
|
|
2934
|
-
minCaptureVarianceThreshold = _a.minCaptureVarianceThreshold,
|
|
2935
|
-
brightness = _a.brightness,
|
|
2936
|
-
range = _a.range,
|
|
2937
|
-
variance = _a.variance;
|
|
2938
|
-
var face = faces[0];
|
|
2939
|
-
var faceNotDetected = faces.length === 0;
|
|
2940
|
-
var faceNotCentered = false,
|
|
2941
|
-
faceLookingAway = false,
|
|
2942
|
-
faceTooClose = false,
|
|
2943
|
-
faceTooFar = false,
|
|
2944
|
-
faceVisibilityTooLow = false;
|
|
2945
|
-
var hasAnyThreshold = minCaptureBrightnessThreshold !== undefined || minCaptureRangeThreshold !== undefined || minCaptureVarianceThreshold !== undefined;
|
|
2946
|
-
if (hasAnyThreshold) {
|
|
2947
|
-
var tooDark = minCaptureBrightnessThreshold !== undefined && brightness !== undefined && brightness < minCaptureBrightnessThreshold;
|
|
2948
|
-
var tooLowRange = minCaptureRangeThreshold !== undefined && range !== undefined && range < minCaptureRangeThreshold;
|
|
2949
|
-
var tooLowVariance = minCaptureVarianceThreshold !== undefined && variance !== undefined && variance < minCaptureVarianceThreshold;
|
|
2950
|
-
faceVisibilityTooLow = !!(tooDark || tooLowRange || tooLowVariance);
|
|
2951
|
-
}
|
|
2952
|
-
if (face && !faceVisibilityTooLow) {
|
|
2953
|
-
// calculate frame centroids
|
|
2954
|
-
var frameCX = videoWidth / 2;
|
|
2955
|
-
var frameCY = videoHeight / 2;
|
|
2956
|
-
// calculate head bounding box, with forehead extension
|
|
2957
|
-
var foreheadSize = face.box.height * foreheadRatio;
|
|
2958
|
-
var headXMin = face.box.xMin;
|
|
2959
|
-
var headXMax = face.box.xMax;
|
|
2960
|
-
var headYMin = face.box.yMin - foreheadSize;
|
|
2961
|
-
var headYMax = face.box.yMax;
|
|
2962
|
-
// calculate head centroids
|
|
2963
|
-
var headCX = (headXMin + headXMax) / 2;
|
|
2964
|
-
var headCY = (headYMin + headYMax) / 2;
|
|
2965
|
-
// calculate thresholds
|
|
2966
|
-
var vTX = videoWidth * xBoundary;
|
|
2967
|
-
var vTY = videoHeight * yBoundary;
|
|
2968
|
-
var vCTX = videoWidth * xCentroidBoundary;
|
|
2969
|
-
var vCTY = videoHeight * yCentroidBoundary;
|
|
2970
|
-
var faceNotCenteredHorizontally = Math.abs(frameCX - headCX) > vCTX;
|
|
2971
|
-
var faceNotCenteredVertically = Math.abs(frameCY - headCY) > vCTY;
|
|
2972
|
-
var faceViolatesHorizontalBoundary = headXMin < vTX || headXMax > videoWidth - vTX;
|
|
2973
|
-
var faceViolatesVerticalBoundary = headYMin < vTY || headYMax > videoHeight - vTY;
|
|
2974
|
-
faceNotCentered = faceViolatesHorizontalBoundary || faceViolatesVerticalBoundary || faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
|
|
2975
|
-
var isMobile = videoWidth < videoHeight;
|
|
2976
|
-
var tooCloseMultiple = 1.5;
|
|
2977
|
-
var tooFarMultiple = isMobile ? 6 : 7;
|
|
2978
|
-
faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
|
|
2979
|
-
faceTooFar = face.box.width < videoWidth / tooFarMultiple;
|
|
2980
|
-
var nose = face.keypoints[2];
|
|
2981
|
-
var fTW = face.box.width * noseTrackingThreshold;
|
|
2982
|
-
var fTH = face.box.height * noseTrackingThreshold;
|
|
2983
|
-
faceLookingAway = !nose || Math.abs(headCX - nose.x) > fTW || Math.abs(headCY - nose.y) > fTH;
|
|
2984
|
-
}
|
|
2985
|
-
var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
|
|
2986
|
-
if (lastFaceDetectionTime > 0) {
|
|
2987
|
-
trackFramesNeeded$1(500 / lastFaceDetectionTime);
|
|
2988
|
-
}
|
|
2989
|
-
var faceIsStable = false,
|
|
2990
|
-
noseIsStable = false;
|
|
2991
|
-
if (faceInGuides && !faceVisibilityTooLow) {
|
|
2992
|
-
var framesNeeded = Math.max(Math.ceil(average(framesNeededSamples$1)), 5);
|
|
2993
|
-
trackFace(face, framesNeeded, videoWidth, videoHeight);
|
|
2994
|
-
faceIsStable = lastNFaces.length >= framesNeeded && !lastNFacePairs.some(function (pair) {
|
|
2995
|
-
return pair.iou < stabilityThreshold;
|
|
2996
|
-
});
|
|
2997
|
-
noseIsStable = lastNNoses.length >= framesNeeded && !lastNNosePairs.some(function (pair) {
|
|
2998
|
-
return pair.distance > noseDistanceThreshold;
|
|
2999
|
-
});
|
|
3000
|
-
}
|
|
3001
|
-
var faceReady = faceInGuides && faceIsStable && noseIsStable && !faceVisibilityTooLow;
|
|
3002
|
-
return {
|
|
3003
|
-
face: face,
|
|
3004
|
-
faceNotDetected: faceNotDetected,
|
|
3005
|
-
faceNotCentered: faceNotCentered,
|
|
3006
|
-
faceLookingAway: faceLookingAway,
|
|
3007
|
-
faceTooClose: faceTooClose,
|
|
3008
|
-
faceTooFar: faceTooFar,
|
|
3009
|
-
faceReady: faceReady,
|
|
3010
|
-
faceReadyAt: faceReady ? new Date() : null,
|
|
3011
|
-
faceIsStable: faceIsStable,
|
|
3012
|
-
noseIsStable: noseIsStable,
|
|
3013
|
-
faceVisibilityTooLow: faceVisibilityTooLow
|
|
3014
|
-
};
|
|
3015
|
-
}
|
|
3016
|
-
function testFaceDetectionAgainstKnownImage(detector) {
|
|
2984
|
+
function testDocumentDetectionAgainstKnownImage(detector) {
|
|
3017
2985
|
return new Promise(function (resolve, reject) {
|
|
3018
2986
|
var img = new Image();
|
|
3019
2987
|
img.crossOrigin = 'anonymous';
|
|
3020
2988
|
img.onload = function () {
|
|
3021
2989
|
var prediction = detector.detectForVideo(img, performance.now());
|
|
3022
2990
|
if (prediction.detections.length > 0) {
|
|
3023
|
-
debug('
|
|
2991
|
+
debug('document detection test result', prediction.detections);
|
|
3024
2992
|
resolve(void 0);
|
|
3025
2993
|
} else {
|
|
3026
|
-
warn('
|
|
3027
|
-
reject(new Error('
|
|
2994
|
+
warn('document detection test failed');
|
|
2995
|
+
reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
|
|
3028
2996
|
}
|
|
3029
2997
|
};
|
|
3030
2998
|
img.onerror = function () {
|
|
3031
|
-
return reject(new Error('
|
|
2999
|
+
return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
|
|
3032
3000
|
};
|
|
3033
|
-
img.src = "".concat(DEFAULT_CDN_URL, "/
|
|
3001
|
+
img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
|
|
3034
3002
|
});
|
|
3035
3003
|
}
|
|
3036
3004
|
|
|
3037
|
-
|
|
3038
|
-
|
|
3039
|
-
|
|
3040
|
-
|
|
3041
|
-
|
|
3042
|
-
|
|
3043
|
-
focusModel = _d === void 0 ? true : _d,
|
|
3044
|
-
_e = _b.faceDetectionModel,
|
|
3045
|
-
faceDetectionModel = _e === void 0 ? true : _e;
|
|
3046
|
-
return __generator(this, function (_f) {
|
|
3047
|
-
switch (_f.label) {
|
|
3048
|
-
case 0:
|
|
3049
|
-
return [4 /*yield*/, probeModelCapabilities()];
|
|
3050
|
-
case 1:
|
|
3051
|
-
_f.sent();
|
|
3052
|
-
preloadTasks = [];
|
|
3053
|
-
if (documentDetectionModel) {
|
|
3054
|
-
preloadTasks.push(preloadDocumentDetectorDependencies);
|
|
3055
|
-
}
|
|
3056
|
-
if (focusModel) {
|
|
3057
|
-
preloadTasks.push(preloadFocusModelDependencies);
|
|
3058
|
-
}
|
|
3059
|
-
if (faceDetectionModel) {
|
|
3060
|
-
preloadTasks.push(preloadFaceDetectorDependencies);
|
|
3061
|
-
}
|
|
3062
|
-
return [4 /*yield*/, Promise.all(preloadTasks)];
|
|
3063
|
-
case 2:
|
|
3064
|
-
_f.sent();
|
|
3065
|
-
return [2 /*return*/];
|
|
3066
|
-
}
|
|
3067
|
-
});
|
|
3068
|
-
});
|
|
3069
|
-
};
|
|
3070
|
-
var progressByUrl = {};
|
|
3071
|
-
var progressByUseCase = {
|
|
3072
|
-
visionRuntime: {
|
|
3073
|
-
loaded: 0,
|
|
3074
|
-
total: 0
|
|
3075
|
-
},
|
|
3076
|
-
documentDetection: {
|
|
3077
|
-
loaded: 0,
|
|
3078
|
-
total: 0
|
|
3079
|
-
},
|
|
3080
|
-
focus: {
|
|
3081
|
-
loaded: 0,
|
|
3082
|
-
total: 0
|
|
3083
|
-
},
|
|
3084
|
-
faceDetection: {
|
|
3085
|
-
loaded: 0,
|
|
3086
|
-
total: 0
|
|
3005
|
+
function getFrameDimensions(frame) {
|
|
3006
|
+
var frameWidth = frame.width,
|
|
3007
|
+
frameHeight = frame.height;
|
|
3008
|
+
if (frame instanceof HTMLImageElement) {
|
|
3009
|
+
frameWidth = frame.naturalWidth;
|
|
3010
|
+
frameHeight = frame.naturalHeight;
|
|
3087
3011
|
}
|
|
3088
|
-
|
|
3089
|
-
|
|
3090
|
-
|
|
3091
|
-
|
|
3092
|
-
|
|
3093
|
-
var req = new XMLHttpRequest();
|
|
3094
|
-
req.addEventListener('progress', function (event) {
|
|
3095
|
-
if (!event.lengthComputable) return;
|
|
3096
|
-
progressByUrl[url] = event;
|
|
3097
|
-
document.dispatchEvent(new CustomEvent('idmission.preloadProgress', {
|
|
3098
|
-
detail: {
|
|
3099
|
-
url: url,
|
|
3100
|
-
loaded: event.loaded,
|
|
3101
|
-
total: event.total
|
|
3102
|
-
}
|
|
3103
|
-
}));
|
|
3104
|
-
});
|
|
3105
|
-
req.addEventListener('loadend', function () {
|
|
3106
|
-
resolve(req.readyState === 4 && req.status === 200);
|
|
3107
|
-
});
|
|
3108
|
-
req.addEventListener('error', reject);
|
|
3109
|
-
req.open('GET', url, true);
|
|
3110
|
-
req.send();
|
|
3111
|
-
})];
|
|
3112
|
-
});
|
|
3113
|
-
});
|
|
3012
|
+
if (frame instanceof HTMLVideoElement) {
|
|
3013
|
+
frameWidth = frame.videoWidth;
|
|
3014
|
+
frameHeight = frame.videoHeight;
|
|
3015
|
+
}
|
|
3016
|
+
return [frameWidth, frameHeight];
|
|
3114
3017
|
}
|
|
3115
|
-
|
|
3116
|
-
|
|
3117
|
-
|
|
3118
|
-
function
|
|
3119
|
-
|
|
3120
|
-
|
|
3121
|
-
|
|
3122
|
-
|
|
3123
|
-
|
|
3124
|
-
|
|
3125
|
-
|
|
3126
|
-
|
|
3127
|
-
|
|
3128
|
-
|
|
3129
|
-
|
|
3130
|
-
|
|
3131
|
-
|
|
3132
|
-
if (documentDetectorPreloading) return [2 /*return*/, new Promise(function (resolve) {
|
|
3133
|
-
var i = setInterval(function () {
|
|
3134
|
-
if (!documentDetectorPreloading) {
|
|
3135
|
-
clearInterval(i);
|
|
3136
|
-
resolve();
|
|
3137
|
-
}
|
|
3138
|
-
}, 100);
|
|
3139
|
-
})];
|
|
3140
|
-
documentDetectorPreloading = true;
|
|
3141
|
-
return [4 /*yield*/, probeModelCapabilities()];
|
|
3142
|
-
case 1:
|
|
3143
|
-
_a.sent();
|
|
3144
|
-
if (modelCapabilities.delegate === 'NONE') {
|
|
3145
|
-
throw new Error('No available delegate for document detector.');
|
|
3146
|
-
}
|
|
3147
|
-
dependencies = [defaultDocumentDetectorModelPath];
|
|
3148
|
-
document.addEventListener('idmission.preloadProgress', handleDownloadProgress);
|
|
3149
|
-
_a.label = 2;
|
|
3150
|
-
case 2:
|
|
3151
|
-
_a.trys.push([2,, 4, 5]);
|
|
3152
|
-
return [4 /*yield*/, Promise.all(dependencies.map(preloadDependency))];
|
|
3153
|
-
case 3:
|
|
3154
|
-
_a.sent();
|
|
3155
|
-
return [3 /*break*/, 5];
|
|
3156
|
-
case 4:
|
|
3157
|
-
document.removeEventListener('idmission.preloadProgress', handleDownloadProgress);
|
|
3158
|
-
documentDetectorPreloading = false;
|
|
3159
|
-
return [7 /*endfinally*/];
|
|
3160
|
-
case 5:
|
|
3161
|
-
return [2 /*return*/];
|
|
3162
|
-
}
|
|
3163
|
-
});
|
|
3164
|
-
});
|
|
3018
|
+
|
|
3019
|
+
var InvisibleCanvasContainer = styled__default.default.div(templateObject_1$M || (templateObject_1$M = __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 pointer-events: none;\n user-select: none;\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 pointer-events: none;\n user-select: none;\n"])));
|
|
3020
|
+
var InvisibleCanvas = styled__default.default.canvas(templateObject_2$G || (templateObject_2$G = __makeTemplateObject(["\n display: none;\n"], ["\n display: none;\n"])));
|
|
3021
|
+
function drawToCanvas(canvas, frame, width, height) {
|
|
3022
|
+
if (!canvas) return;
|
|
3023
|
+
var ctx = canvas.getContext('2d');
|
|
3024
|
+
if (!ctx) return;
|
|
3025
|
+
if (!width || !height) {
|
|
3026
|
+
var _a = getFrameDimensions(frame),
|
|
3027
|
+
frameWidth = _a[0],
|
|
3028
|
+
frameHeight = _a[1];
|
|
3029
|
+
width || (width = frameWidth);
|
|
3030
|
+
height || (height = frameHeight);
|
|
3031
|
+
}
|
|
3032
|
+
canvas.width = width;
|
|
3033
|
+
canvas.height = height;
|
|
3034
|
+
ctx.drawImage(frame, 0, 0, width, height);
|
|
3165
3035
|
}
|
|
3166
|
-
function
|
|
3167
|
-
|
|
3168
|
-
|
|
3169
|
-
|
|
3170
|
-
|
|
3171
|
-
|
|
3172
|
-
|
|
3173
|
-
|
|
3174
|
-
|
|
3175
|
-
|
|
3176
|
-
|
|
3177
|
-
|
|
3178
|
-
|
|
3179
|
-
|
|
3180
|
-
|
|
3181
|
-
|
|
3182
|
-
|
|
3183
|
-
|
|
3184
|
-
|
|
3185
|
-
|
|
3186
|
-
|
|
3187
|
-
|
|
3188
|
-
|
|
3189
|
-
|
|
3190
|
-
|
|
3191
|
-
|
|
3192
|
-
|
|
3193
|
-
|
|
3036
|
+
function clearCanvas(canvas) {
|
|
3037
|
+
var _a;
|
|
3038
|
+
(_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);
|
|
3039
|
+
}
|
|
3040
|
+
var templateObject_1$M, templateObject_2$G;
|
|
3041
|
+
|
|
3042
|
+
function useFrameLoop(fn, options) {
|
|
3043
|
+
if (options === void 0) {
|
|
3044
|
+
options = {};
|
|
3045
|
+
}
|
|
3046
|
+
var _a = React.useState(false),
|
|
3047
|
+
running = _a[0],
|
|
3048
|
+
setRunning = _a[1];
|
|
3049
|
+
var startedAtRef = React.useRef(null);
|
|
3050
|
+
var loopId = React.useRef(0);
|
|
3051
|
+
var frameId = React.useRef(0);
|
|
3052
|
+
React.useEffect(function runFrameLoop() {
|
|
3053
|
+
if (!running) return;
|
|
3054
|
+
var timer;
|
|
3055
|
+
var currentLoopId = loopId.current;
|
|
3056
|
+
function hotLoop() {
|
|
3057
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
3058
|
+
var start, timeRunning, took, amountToThrottle;
|
|
3059
|
+
var _a, _b, _c;
|
|
3060
|
+
return __generator(this, function (_d) {
|
|
3061
|
+
switch (_d.label) {
|
|
3062
|
+
case 0:
|
|
3063
|
+
if (currentLoopId !== loopId.current) return [2 /*return*/];
|
|
3064
|
+
start = new Date().getTime();
|
|
3065
|
+
timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
|
|
3066
|
+
return [4 /*yield*/, fn(frameId.current, timeRunning)];
|
|
3067
|
+
case 1:
|
|
3068
|
+
_d.sent();
|
|
3069
|
+
took = new Date().getTime() - start;
|
|
3070
|
+
amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
|
|
3071
|
+
timer = setTimeout(function () {
|
|
3072
|
+
frameId.current = requestAnimationFrame(hotLoop);
|
|
3073
|
+
}, amountToThrottle);
|
|
3074
|
+
return [2 /*return*/];
|
|
3194
3075
|
}
|
|
3195
|
-
|
|
3196
|
-
|
|
3197
|
-
|
|
3198
|
-
|
|
3199
|
-
|
|
3200
|
-
|
|
3201
|
-
|
|
3202
|
-
|
|
3203
|
-
|
|
3204
|
-
|
|
3205
|
-
|
|
3206
|
-
|
|
3207
|
-
|
|
3208
|
-
|
|
3209
|
-
|
|
3210
|
-
|
|
3211
|
-
|
|
3212
|
-
|
|
3076
|
+
});
|
|
3077
|
+
});
|
|
3078
|
+
}
|
|
3079
|
+
void hotLoop();
|
|
3080
|
+
return function () {
|
|
3081
|
+
loopId.current += 1;
|
|
3082
|
+
if (frameId.current) cancelAnimationFrame(frameId.current);
|
|
3083
|
+
if (timer) clearTimeout(timer);
|
|
3084
|
+
};
|
|
3085
|
+
}, [fn, running, options.throttleMs]);
|
|
3086
|
+
var start = React.useCallback(function () {
|
|
3087
|
+
startedAtRef.current = new Date();
|
|
3088
|
+
setRunning(true);
|
|
3089
|
+
}, []);
|
|
3090
|
+
var stop = React.useCallback(function () {
|
|
3091
|
+
loopId.current += 1; // force the loop to stop immediately.
|
|
3092
|
+
setRunning(false);
|
|
3093
|
+
startedAtRef.current = null;
|
|
3094
|
+
}, []);
|
|
3095
|
+
React.useEffect(function startAutomatically() {
|
|
3096
|
+
if (options.autoStart) start();
|
|
3097
|
+
return stop;
|
|
3098
|
+
}, [options.autoStart, start, stop]);
|
|
3099
|
+
return {
|
|
3100
|
+
start: start,
|
|
3101
|
+
stop: stop
|
|
3102
|
+
};
|
|
3213
3103
|
}
|
|
3214
|
-
|
|
3215
|
-
|
|
3216
|
-
|
|
3217
|
-
|
|
3218
|
-
|
|
3219
|
-
|
|
3220
|
-
document.dispatchEvent(new CustomEvent('idmission.preloadProgress.faceDetection', {
|
|
3221
|
-
detail: progressByUseCase.faceDetection
|
|
3222
|
-
}));
|
|
3104
|
+
|
|
3105
|
+
function listAvailableCameras(facingMode_1) {
|
|
3106
|
+
return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
|
|
3107
|
+
var cameraEnumerationStream, allDevices, allowedVideoDevices;
|
|
3108
|
+
if (requestMicAccess === void 0) {
|
|
3109
|
+
requestMicAccess = false;
|
|
3223
3110
|
}
|
|
3224
|
-
var dependencies;
|
|
3225
3111
|
return __generator(this, function (_a) {
|
|
3226
3112
|
switch (_a.label) {
|
|
3227
3113
|
case 0:
|
|
3228
|
-
|
|
3229
|
-
|
|
3230
|
-
|
|
3231
|
-
|
|
3232
|
-
resolve();
|
|
3114
|
+
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
|
|
3115
|
+
video: {
|
|
3116
|
+
facingMode: {
|
|
3117
|
+
exact: facingMode
|
|
3233
3118
|
}
|
|
3234
|
-
},
|
|
3235
|
-
|
|
3236
|
-
|
|
3237
|
-
|
|
3119
|
+
},
|
|
3120
|
+
audio: requestMicAccess
|
|
3121
|
+
})
|
|
3122
|
+
// This lists all available cameras attached to the user's device.
|
|
3123
|
+
];
|
|
3238
3124
|
case 1:
|
|
3239
|
-
_a.sent();
|
|
3240
|
-
|
|
3241
|
-
throw new Error('No available delegate for document detector.');
|
|
3242
|
-
}
|
|
3243
|
-
dependencies = [defaultFaceDetectorModelPath];
|
|
3244
|
-
document.addEventListener('idmission.preloadProgress', handleModelDownloadProgress);
|
|
3245
|
-
_a.label = 2;
|
|
3125
|
+
cameraEnumerationStream = _a.sent();
|
|
3126
|
+
return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
|
|
3246
3127
|
case 2:
|
|
3247
|
-
_a.
|
|
3248
|
-
|
|
3249
|
-
|
|
3250
|
-
|
|
3251
|
-
|
|
3252
|
-
|
|
3253
|
-
|
|
3254
|
-
|
|
3255
|
-
|
|
3256
|
-
|
|
3257
|
-
|
|
3128
|
+
allDevices = _a.sent();
|
|
3129
|
+
allowedVideoDevices = allDevices.filter(function (_a) {
|
|
3130
|
+
var kind = _a.kind,
|
|
3131
|
+
label = _a.label;
|
|
3132
|
+
return kind === 'videoinput' && !label.toLowerCase().includes('virtual');
|
|
3133
|
+
});
|
|
3134
|
+
// Release the access to the user's camera that we obtained for enumeration purposes.
|
|
3135
|
+
cameraEnumerationStream.getVideoTracks().forEach(function (track) {
|
|
3136
|
+
track.enabled = false;
|
|
3137
|
+
track.stop();
|
|
3138
|
+
});
|
|
3139
|
+
cameraEnumerationStream = null;
|
|
3140
|
+
return [2 /*return*/, allowedVideoDevices];
|
|
3258
3141
|
}
|
|
3259
3142
|
});
|
|
3260
3143
|
});
|
|
3261
3144
|
}
|
|
3262
|
-
function
|
|
3263
|
-
return
|
|
3264
|
-
}
|
|
3265
|
-
function
|
|
3266
|
-
return
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
|
|
3274
|
-
|
|
3145
|
+
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) {
|
|
3146
|
+
return s.toLocaleLowerCase().split(' ').join('');
|
|
3147
|
+
});
|
|
3148
|
+
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) {
|
|
3149
|
+
return s.toLocaleLowerCase().split(' ').join('');
|
|
3150
|
+
});
|
|
3151
|
+
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) {
|
|
3152
|
+
return s.toLocaleLowerCase().split(' ').join('');
|
|
3153
|
+
});
|
|
3154
|
+
var cameraLabelMatches = function cameraLabelMatches(labelOrDevice, labelSetOrLabel) {
|
|
3155
|
+
var label = labelOrDevice instanceof MediaDeviceInfo ? getDeviceLabel(labelOrDevice) : labelOrDevice;
|
|
3156
|
+
var labelSet = typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel;
|
|
3157
|
+
return labelSet.some(function (l) {
|
|
3158
|
+
return label.includes(l);
|
|
3275
3159
|
});
|
|
3276
|
-
}
|
|
3277
|
-
|
|
3278
|
-
var defaultDocumentDetectionScoreThreshold = 0.1;
|
|
3279
|
-
var defaultDocumentDetectionModelLoadTimeoutMs = 45000;
|
|
3280
|
-
var defaultDocumentDetectionThresholds = {
|
|
3281
|
-
idCardFront: 0.6,
|
|
3282
|
-
idCardBack: 0.6,
|
|
3283
|
-
passport: 0.4,
|
|
3284
|
-
singlePage: 0.4,
|
|
3285
|
-
stability: {
|
|
3286
|
-
idCardFront: 0.85,
|
|
3287
|
-
idCardBack: 0.85,
|
|
3288
|
-
passport: 0.5,
|
|
3289
|
-
singlePage: 0.5
|
|
3290
|
-
}
|
|
3291
3160
|
};
|
|
3292
|
-
var
|
|
3293
|
-
|
|
3294
|
-
idCardBack: 'ID card back',
|
|
3295
|
-
passport: 'Passport',
|
|
3296
|
-
singlePage: 'Single page',
|
|
3297
|
-
none: 'None'
|
|
3161
|
+
var getDeviceLabel = function getDeviceLabel(deviceInfo) {
|
|
3162
|
+
return deviceInfo.label.toLocaleLowerCase().split(' ').join('');
|
|
3298
3163
|
};
|
|
3299
|
-
var
|
|
3300
|
-
|
|
3301
|
-
|
|
3302
|
-
|
|
3303
|
-
|
|
3304
|
-
|
|
3305
|
-
|
|
3306
|
-
|
|
3307
|
-
|
|
3308
|
-
|
|
3309
|
-
|
|
3310
|
-
|
|
3311
|
-
|
|
3312
|
-
|
|
3313
|
-
|
|
3314
|
-
|
|
3315
|
-
|
|
3316
|
-
|
|
3317
|
-
|
|
3318
|
-
|
|
3319
|
-
|
|
3320
|
-
}
|
|
3321
|
-
_b = (_a = tasksVision.ObjectDetector).createFromOptions;
|
|
3322
|
-
return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
|
|
3323
|
-
case 2:
|
|
3324
|
-
return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
|
|
3325
|
-
baseOptions: {
|
|
3326
|
-
modelAssetPath: modelAssetPath,
|
|
3327
|
-
delegate: modelCapabilities.delegate
|
|
3328
|
-
},
|
|
3329
|
-
// canvas: document.createElement('canvas'),
|
|
3330
|
-
scoreThreshold: scoreThreshold,
|
|
3331
|
-
runningMode: 'VIDEO'
|
|
3332
|
-
}])];
|
|
3333
|
-
case 3:
|
|
3334
|
-
detector = _c.sent();
|
|
3335
|
-
detectorSettings = {
|
|
3336
|
-
modelAssetPath: modelAssetPath,
|
|
3337
|
-
scoreThreshold: scoreThreshold
|
|
3338
|
-
};
|
|
3339
|
-
return [2 /*return*/, detector];
|
|
3340
|
-
}
|
|
3341
|
-
});
|
|
3342
|
-
});
|
|
3343
|
-
}
|
|
3344
|
-
function closeDocumentDetector() {
|
|
3345
|
-
detector === null || detector === void 0 ? void 0 : detector.close();
|
|
3346
|
-
detector = null;
|
|
3347
|
-
detectorSettings = null;
|
|
3348
|
-
}
|
|
3349
|
-
function useLoadDocumentDetector(_a) {
|
|
3350
|
-
var _b = _a.shouldLoadModels,
|
|
3351
|
-
shouldLoadModels = _b === void 0 ? true : _b,
|
|
3352
|
-
_c = _a.modelPath,
|
|
3353
|
-
modelPath = _c === void 0 ? defaultDocumentDetectorModelPath : _c,
|
|
3354
|
-
_d = _a.modelLoadTimeoutMs,
|
|
3355
|
-
modelLoadTimeoutMs = _d === void 0 ? defaultDocumentDetectionModelLoadTimeoutMs : _d,
|
|
3356
|
-
_e = _a.scoreThreshold,
|
|
3357
|
-
scoreThreshold = _e === void 0 ? defaultDocumentDetectionScoreThreshold : _e,
|
|
3358
|
-
onModelError = _a.onModelError,
|
|
3359
|
-
videoRef = _a.videoRef;
|
|
3360
|
-
var _f = React.useState('not-started'),
|
|
3361
|
-
modelLoadState = _f[0],
|
|
3362
|
-
setModelLoadState = _f[1];
|
|
3363
|
-
var _g = React.useState(null),
|
|
3364
|
-
modelWarmingStartedAt = _g[0],
|
|
3365
|
-
setModelWarmingStartedAt = _g[1];
|
|
3366
|
-
var _h = React.useState(0),
|
|
3367
|
-
modelDownloadProgress = _h[0],
|
|
3368
|
-
setModelDownloadProgress = _h[1];
|
|
3369
|
-
var _j = React.useState(null),
|
|
3370
|
-
modelError = _j[0],
|
|
3371
|
-
setModelError = _j[1];
|
|
3372
|
-
React.useEffect(function loadModel() {
|
|
3373
|
-
var _this = this;
|
|
3374
|
-
if (!shouldLoadModels) return;
|
|
3375
|
-
setModelLoadState('downloading');
|
|
3376
|
-
setModelWarmingStartedAt(null);
|
|
3377
|
-
function handleDownloadProgress(event) {
|
|
3378
|
-
setModelDownloadProgress(progressToPercentage(event.detail));
|
|
3379
|
-
}
|
|
3380
|
-
document.addEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
|
|
3381
|
-
var modelLoadTimeout = setTimeout(function () {
|
|
3382
|
-
setModelError(new Error('Model loading time limit exceeded.'));
|
|
3383
|
-
}, modelLoadTimeoutMs);
|
|
3384
|
-
var cancelVideoReady = function cancelVideoReady() {};
|
|
3385
|
-
loadDocumentDetector(modelPath, scoreThreshold).then(function (model) {
|
|
3386
|
-
return __awaiter(_this, void 0, void 0, function () {
|
|
3387
|
-
var _a, videoReady, cancel, cancelled;
|
|
3388
|
-
return __generator(this, function (_b) {
|
|
3389
|
-
switch (_b.label) {
|
|
3390
|
-
case 0:
|
|
3391
|
-
setModelDownloadProgress(100);
|
|
3392
|
-
setModelLoadState('warming');
|
|
3393
|
-
setModelWarmingStartedAt(new Date().getTime());
|
|
3394
|
-
clearTimeout(modelLoadTimeout);
|
|
3395
|
-
return [4 /*yield*/, testDocumentDetectionAgainstKnownImage(model)];
|
|
3396
|
-
case 1:
|
|
3397
|
-
_b.sent();
|
|
3398
|
-
_a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
|
|
3399
|
-
cancelled = false;
|
|
3400
|
-
cancelVideoReady = function cancelVideoReady() {
|
|
3401
|
-
cancelled = true;
|
|
3402
|
-
cancel();
|
|
3403
|
-
};
|
|
3404
|
-
return [4 /*yield*/, videoReady];
|
|
3405
|
-
case 2:
|
|
3406
|
-
_b.sent();
|
|
3407
|
-
setTimeout(function () {
|
|
3408
|
-
if (cancelled) return;
|
|
3409
|
-
model.detectForVideo(videoRef.current, performance.now());
|
|
3410
|
-
setModelLoadState('ready');
|
|
3411
|
-
}, 500);
|
|
3412
|
-
return [2 /*return*/];
|
|
3413
|
-
}
|
|
3414
|
-
});
|
|
3415
|
-
});
|
|
3416
|
-
})["catch"](function (e) {
|
|
3417
|
-
setModelError(e);
|
|
3418
|
-
setModelLoadState('error');
|
|
3419
|
-
})["finally"](function () {
|
|
3420
|
-
clearTimeout(modelLoadTimeout);
|
|
3421
|
-
});
|
|
3422
|
-
return function () {
|
|
3423
|
-
log('unloading document detection model');
|
|
3424
|
-
cancelVideoReady();
|
|
3425
|
-
closeDocumentDetector();
|
|
3426
|
-
clearTimeout(modelLoadTimeout);
|
|
3427
|
-
document.removeEventListener('idmission.preloadProgress.documentDetection', handleDownloadProgress);
|
|
3428
|
-
};
|
|
3429
|
-
}, [shouldLoadModels, modelLoadTimeoutMs, modelPath, scoreThreshold, videoRef]);
|
|
3430
|
-
React.useEffect(function handleModelError() {
|
|
3431
|
-
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
3432
|
-
}, [modelError, onModelError]);
|
|
3433
|
-
return React.useMemo(function () {
|
|
3434
|
-
return {
|
|
3435
|
-
ready: modelLoadState === 'ready',
|
|
3436
|
-
modelLoadState: modelLoadState,
|
|
3437
|
-
modelDownloadProgress: modelDownloadProgress,
|
|
3438
|
-
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
3439
|
-
modelError: modelError,
|
|
3440
|
-
setModelError: setModelError
|
|
3441
|
-
};
|
|
3442
|
-
}, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
|
|
3443
|
-
}
|
|
3444
|
-
function makeDocumentDetectorPrediction(frame) {
|
|
3445
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3446
|
-
var startedAt, prediction, time, frameWidth, frameHeight;
|
|
3447
|
-
return __generator(this, function (_a) {
|
|
3448
|
-
if (!detector) return [2 /*return*/, null];
|
|
3449
|
-
startedAt = new Date();
|
|
3450
|
-
// Detectors can throw errors, for example when using custom URLs that
|
|
3451
|
-
// contain a model that doesn't provide the expected output.
|
|
3452
|
-
try {
|
|
3453
|
-
prediction = detector.detectForVideo(frame, performance.now());
|
|
3454
|
-
time = new Date().getTime() - startedAt.getTime();
|
|
3455
|
-
frameWidth = frame.width;
|
|
3456
|
-
frameHeight = frame.height;
|
|
3457
|
-
return [2 /*return*/, _assign(_assign({}, prediction), {
|
|
3458
|
-
time: time,
|
|
3459
|
-
frameWidth: frameWidth,
|
|
3460
|
-
frameHeight: frameHeight
|
|
3461
|
-
})];
|
|
3462
|
-
} catch (e) {
|
|
3463
|
-
error('caught object detection error', e);
|
|
3464
|
-
}
|
|
3465
|
-
return [2 /*return*/, null];
|
|
3466
|
-
});
|
|
3467
|
-
});
|
|
3468
|
-
}
|
|
3469
|
-
var lastDetectionAt = 0;
|
|
3470
|
-
var lastDetectionTime = 0;
|
|
3471
|
-
function setLastDetectionAt(time) {
|
|
3472
|
-
lastDetectionTime = time - lastDetectionAt;
|
|
3473
|
-
lastDetectionAt = time;
|
|
3474
|
-
}
|
|
3475
|
-
var framesNeededSamples = [];
|
|
3476
|
-
function trackFramesNeeded(value, bufferLength) {
|
|
3477
|
-
if (bufferLength === void 0) {
|
|
3478
|
-
bufferLength = 25;
|
|
3479
|
-
}
|
|
3480
|
-
framesNeededSamples.unshift(value);
|
|
3481
|
-
if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
|
|
3482
|
-
}
|
|
3483
|
-
var lastNBoxes = [];
|
|
3484
|
-
var lastNPairs = [];
|
|
3485
|
-
function trackBox(box, framesNeeded) {
|
|
3486
|
-
if (framesNeeded === void 0) {
|
|
3487
|
-
framesNeeded = 12;
|
|
3488
|
-
}
|
|
3489
|
-
lastNBoxes.unshift(box);
|
|
3490
|
-
if (lastNBoxes.length > framesNeeded) lastNBoxes.length = framesNeeded;
|
|
3491
|
-
if (lastNBoxes.length > 1) {
|
|
3492
|
-
var lastBox = lastNBoxes[1];
|
|
3493
|
-
var iou = calculateIoU(box, lastBox);
|
|
3494
|
-
lastNPairs.unshift({
|
|
3495
|
-
a: box,
|
|
3496
|
-
b: lastBox,
|
|
3497
|
-
iou: iou
|
|
3498
|
-
});
|
|
3499
|
-
if (lastNPairs.length > framesNeeded - 1) lastNPairs.length = framesNeeded - 1;
|
|
3500
|
-
}
|
|
3501
|
-
}
|
|
3502
|
-
var defaultDocumentDetectionBoundaries = {
|
|
3503
|
-
top: 20,
|
|
3504
|
-
bottom: 20,
|
|
3505
|
-
left: 20,
|
|
3506
|
-
right: 20
|
|
3507
|
-
};
|
|
3508
|
-
function processDocumentDetectorPrediction(prediction, thresholds, boundaries) {
|
|
3509
|
-
var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p;
|
|
3510
|
-
if (boundaries === void 0) {
|
|
3511
|
-
boundaries = defaultDocumentDetectionBoundaries;
|
|
3512
|
-
}
|
|
3513
|
-
var detections = prediction.detections,
|
|
3514
|
-
frameWidth = prediction.frameWidth,
|
|
3515
|
-
frameHeight = prediction.frameHeight,
|
|
3516
|
-
time = prediction.time;
|
|
3517
|
-
var boundaryTop = (_a = boundaries.top) !== null && _a !== void 0 ? _a : 20;
|
|
3518
|
-
var boundaryLeft = (_b = boundaries.left) !== null && _b !== void 0 ? _b : 20;
|
|
3519
|
-
var boundaryRight = (_c = boundaries.right) !== null && _c !== void 0 ? _c : 20;
|
|
3520
|
-
var boundaryBottom = (_d = boundaries.bottom) !== null && _d !== void 0 ? _d : 20;
|
|
3521
|
-
var frameWidth80Pct = frameWidth * 0.8;
|
|
3522
|
-
var detectedObjects = applyNonMaxSuppression(detections.flatMap(function (d) {
|
|
3523
|
-
return d.categories.map(function (category) {
|
|
3524
|
-
return {
|
|
3525
|
-
label: category === null || category === void 0 ? void 0 : category.categoryName,
|
|
3526
|
-
score: category === null || category === void 0 ? void 0 : category.score,
|
|
3527
|
-
box: convertBoundingBox(d.boundingBox)
|
|
3528
|
-
};
|
|
3529
|
-
});
|
|
3530
|
-
}), function (obj) {
|
|
3531
|
-
var _a = obj.box,
|
|
3532
|
-
xMin = _a.xMin,
|
|
3533
|
-
yMin = _a.yMin,
|
|
3534
|
-
width = _a.width,
|
|
3535
|
-
height = _a.height;
|
|
3536
|
-
return yMin > boundaryTop &&
|
|
3537
|
-
// Is it valid top edge of ID detected?
|
|
3538
|
-
yMin + height + boundaryBottom < frameHeight && (
|
|
3539
|
-
// Is it valid bottom edge less than max video height
|
|
3540
|
-
xMin > boundaryLeft || xMin + width > frameWidth80Pct) &&
|
|
3541
|
-
// If either the left side visible or if not, right edge of ID should be more than 80% of width.
|
|
3542
|
-
xMin + width + boundaryRight < frameWidth // Valid right edge if it's less than video width.
|
|
3543
|
-
;
|
|
3544
|
-
});
|
|
3545
|
-
var allZero = detections.length > 0 && !detections.some(function (_a) {
|
|
3546
|
-
var boundingBox = _a.boundingBox;
|
|
3547
|
-
return Object.values(boundingBox !== null && boundingBox !== void 0 ? boundingBox : {}).some(function (n) {
|
|
3548
|
-
return n > 0;
|
|
3549
|
-
});
|
|
3550
|
-
});
|
|
3551
|
-
var bestIdCardFront = detectedObjects.find(function (obj) {
|
|
3552
|
-
return obj.label === 'Document';
|
|
3553
|
-
});
|
|
3554
|
-
var bestIdCardBack = detectedObjects.find(function (obj) {
|
|
3555
|
-
return obj.label === 'Document back';
|
|
3556
|
-
});
|
|
3557
|
-
var bestPassportPage = detectedObjects.find(function (obj) {
|
|
3558
|
-
return obj.label === 'Passport page';
|
|
3559
|
-
});
|
|
3560
|
-
var bestSinglePage = detectedObjects.find(function (obj) {
|
|
3561
|
-
return obj.label === 'Single page';
|
|
3562
|
-
});
|
|
3563
|
-
var idCardFrontDetectionScore = (_e = bestIdCardFront === null || bestIdCardFront === void 0 ? void 0 : bestIdCardFront.score) !== null && _e !== void 0 ? _e : 0;
|
|
3564
|
-
var idCardBackDetectionScore = (_f = bestIdCardBack === null || bestIdCardBack === void 0 ? void 0 : bestIdCardBack.score) !== null && _f !== void 0 ? _f : 0;
|
|
3565
|
-
var passportDetectionScore = (_g = bestPassportPage === null || bestPassportPage === void 0 ? void 0 : bestPassportPage.score) !== null && _g !== void 0 ? _g : 0;
|
|
3566
|
-
var singlePageDetectionScore = (_h = bestSinglePage === null || bestSinglePage === void 0 ? void 0 : bestSinglePage.score) !== null && _h !== void 0 ? _h : 0;
|
|
3567
|
-
var idCardFrontDetectionThresholdMet = idCardFrontDetectionScore >= ((_j = thresholds.idCardFront) !== null && _j !== void 0 ? _j : 0);
|
|
3568
|
-
var idCardBackDetectionThresholdMet = idCardBackDetectionScore >= ((_k = thresholds.idCardBack) !== null && _k !== void 0 ? _k : 0);
|
|
3569
|
-
var passportDetectionThresholdMet = passportDetectionScore >= ((_l = thresholds.passport) !== null && _l !== void 0 ? _l : 0);
|
|
3570
|
-
var singlePageDetectionThresholdMet = singlePageDetectionScore >= ((_m = thresholds.singlePage) !== null && _m !== void 0 ? _m : 0);
|
|
3571
|
-
var bestDocument = singlePageDetectionThresholdMet ? bestSinglePage : passportDetectionThresholdMet ? bestPassportPage : idCardBackDetectionThresholdMet ? bestIdCardBack : bestIdCardFront;
|
|
3572
|
-
var detectionThreshold = singlePageDetectionThresholdMet ? thresholds.singlePage : passportDetectionThresholdMet ? thresholds.passport : idCardBackDetectionThresholdMet ? thresholds.idCardBack : thresholds.idCardFront;
|
|
3573
|
-
var detectionScore = (_o = bestDocument === null || bestDocument === void 0 ? void 0 : bestDocument.score) !== null && _o !== void 0 ? _o : 0;
|
|
3574
|
-
var detectionThresholdMet = detectionScore >= (detectionThreshold !== null && detectionThreshold !== void 0 ? detectionThreshold : 0);
|
|
3575
|
-
var detectedDocumentType = 'none';
|
|
3576
|
-
if (singlePageDetectionThresholdMet) {
|
|
3577
|
-
detectedDocumentType = 'singlePage';
|
|
3578
|
-
} else if (passportDetectionThresholdMet) {
|
|
3579
|
-
detectedDocumentType = 'passport';
|
|
3580
|
-
} else if (idCardBackDetectionThresholdMet) {
|
|
3581
|
-
detectedDocumentType = 'idCardBack';
|
|
3582
|
-
} else if (detectionThresholdMet) {
|
|
3583
|
-
detectedDocumentType = 'idCardFront';
|
|
3584
|
-
}
|
|
3585
|
-
var documentInBounds = !!bestDocument;
|
|
3586
|
-
if (lastDetectionTime > 0) {
|
|
3587
|
-
trackFramesNeeded(1000 / lastDetectionTime);
|
|
3588
|
-
}
|
|
3589
|
-
var documentIsStable = false;
|
|
3590
|
-
var documentTooClose = false;
|
|
3591
|
-
if (bestDocument) {
|
|
3592
|
-
var _q = [bestDocument.box.width / frameWidth, bestDocument.box.height / frameHeight],
|
|
3593
|
-
docWidth = _q[0],
|
|
3594
|
-
docHeight = _q[1];
|
|
3595
|
-
documentTooClose = docWidth > 0.85 || docHeight > 0.85;
|
|
3596
|
-
if (detectionThresholdMet && documentInBounds && !documentTooClose) {
|
|
3597
|
-
var thresholdSet = (_p = thresholds.stability) !== null && _p !== void 0 ? _p : defaultDocumentDetectionThresholds.stability;
|
|
3598
|
-
var threshold_1 = thresholdSet[detectedDocumentType];
|
|
3599
|
-
var framesNeeded = Math.ceil(average(framesNeededSamples));
|
|
3600
|
-
trackBox(bestDocument.box, framesNeeded);
|
|
3601
|
-
documentIsStable = lastNBoxes.length >= framesNeeded && !lastNPairs.some(function (pair) {
|
|
3602
|
-
return pair.iou < threshold_1;
|
|
3603
|
-
});
|
|
3604
|
-
}
|
|
3605
|
-
}
|
|
3606
|
-
return {
|
|
3607
|
-
prediction: prediction,
|
|
3608
|
-
detectedObjects: detectedObjects,
|
|
3609
|
-
detectionScore: detectionScore,
|
|
3610
|
-
detectionTime: time,
|
|
3611
|
-
detectionThresholdMet: detectionThresholdMet,
|
|
3612
|
-
detectedDocumentType: detectedDocumentType,
|
|
3613
|
-
idCardFrontDetectionScore: idCardFrontDetectionScore,
|
|
3614
|
-
idCardFrontDetectionThresholdMet: idCardFrontDetectionThresholdMet,
|
|
3615
|
-
idCardBackDetectionScore: idCardBackDetectionScore,
|
|
3616
|
-
idCardBackDetectionThresholdMet: idCardBackDetectionThresholdMet,
|
|
3617
|
-
passportDetectionScore: passportDetectionScore,
|
|
3618
|
-
passportDetectionThresholdMet: passportDetectionThresholdMet,
|
|
3619
|
-
singlePageDetectionScore: singlePageDetectionScore,
|
|
3620
|
-
singlePageDetectionThresholdMet: singlePageDetectionThresholdMet,
|
|
3621
|
-
bestDocument: bestDocument,
|
|
3622
|
-
documentInBounds: documentInBounds,
|
|
3623
|
-
documentTooClose: documentTooClose,
|
|
3624
|
-
documentIsStable: documentIsStable,
|
|
3625
|
-
frameWidth: frameWidth,
|
|
3626
|
-
frameHeight: frameHeight,
|
|
3627
|
-
allZero: allZero
|
|
3628
|
-
};
|
|
3629
|
-
}
|
|
3630
|
-
function applyNonMaxSuppression(detectedObjects, isGoodBox) {
|
|
3631
|
-
var maxes = {};
|
|
3632
|
-
detectedObjects.forEach(function (obj, i) {
|
|
3633
|
-
if (obj) {
|
|
3634
|
-
if (!maxes[obj.label]) maxes[obj.label] = [0, -1];
|
|
3635
|
-
if (obj.score > maxes[obj.label][0] && (isGoodBox === null || isGoodBox === void 0 ? void 0 : isGoodBox(obj))) maxes[obj.label] = [obj.score, i];
|
|
3636
|
-
}
|
|
3637
|
-
});
|
|
3638
|
-
return Object.keys(maxes).map(function (label) {
|
|
3639
|
-
return detectedObjects[maxes[label][1]];
|
|
3640
|
-
}).filter(function (obj) {
|
|
3641
|
-
return !!obj;
|
|
3642
|
-
});
|
|
3643
|
-
}
|
|
3644
|
-
function testDocumentDetectionAgainstKnownImage(detector) {
|
|
3645
|
-
return new Promise(function (resolve, reject) {
|
|
3646
|
-
var img = new Image();
|
|
3647
|
-
img.crossOrigin = 'anonymous';
|
|
3648
|
-
img.onload = function () {
|
|
3649
|
-
var prediction = detector.detectForVideo(img, performance.now());
|
|
3650
|
-
if (prediction.detections.length > 0) {
|
|
3651
|
-
debug('document detection test result', prediction.detections);
|
|
3652
|
-
resolve(void 0);
|
|
3653
|
-
} else {
|
|
3654
|
-
warn('document detection test failed');
|
|
3655
|
-
reject(new Error('testDocumentDetectionAgainstKnownImage failed to predict'));
|
|
3656
|
-
}
|
|
3657
|
-
};
|
|
3658
|
-
img.onerror = function () {
|
|
3659
|
-
return reject(new Error('testDocumentDetectionAgainstKnownImage failed to load image'));
|
|
3660
|
-
};
|
|
3661
|
-
img.src = "".concat(DEFAULT_CDN_URL, "/id-card-test.jpg");
|
|
3662
|
-
});
|
|
3663
|
-
}
|
|
3664
|
-
|
|
3665
|
-
function useFrameLoop(fn, options) {
|
|
3666
|
-
if (options === void 0) {
|
|
3667
|
-
options = {};
|
|
3668
|
-
}
|
|
3669
|
-
var _a = React.useState(false),
|
|
3670
|
-
running = _a[0],
|
|
3671
|
-
setRunning = _a[1];
|
|
3672
|
-
var startedAtRef = React.useRef(null);
|
|
3673
|
-
var loopId = React.useRef(0);
|
|
3674
|
-
var frameId = React.useRef(0);
|
|
3675
|
-
React.useEffect(function runFrameLoop() {
|
|
3676
|
-
if (!running) return;
|
|
3677
|
-
var timer;
|
|
3678
|
-
var currentLoopId = loopId.current;
|
|
3679
|
-
function hotLoop() {
|
|
3680
|
-
return __awaiter(this, void 0, void 0, function () {
|
|
3681
|
-
var start, timeRunning, took, amountToThrottle;
|
|
3682
|
-
var _a, _b, _c;
|
|
3683
|
-
return __generator(this, function (_d) {
|
|
3684
|
-
switch (_d.label) {
|
|
3685
|
-
case 0:
|
|
3686
|
-
if (currentLoopId !== loopId.current) return [2 /*return*/];
|
|
3687
|
-
start = new Date().getTime();
|
|
3688
|
-
timeRunning = start - ((_b = (_a = startedAtRef.current) === null || _a === void 0 ? void 0 : _a.getTime()) !== null && _b !== void 0 ? _b : 0);
|
|
3689
|
-
return [4 /*yield*/, fn(frameId.current, timeRunning)];
|
|
3690
|
-
case 1:
|
|
3691
|
-
_d.sent();
|
|
3692
|
-
took = new Date().getTime() - start;
|
|
3693
|
-
amountToThrottle = Math.max(((_c = options.throttleMs) !== null && _c !== void 0 ? _c : 0) - took, 0);
|
|
3694
|
-
timer = setTimeout(function () {
|
|
3695
|
-
frameId.current = requestAnimationFrame(hotLoop);
|
|
3696
|
-
}, amountToThrottle);
|
|
3697
|
-
return [2 /*return*/];
|
|
3698
|
-
}
|
|
3699
|
-
});
|
|
3700
|
-
});
|
|
3701
|
-
}
|
|
3702
|
-
void hotLoop();
|
|
3703
|
-
return function () {
|
|
3704
|
-
loopId.current += 1;
|
|
3705
|
-
if (frameId.current) cancelAnimationFrame(frameId.current);
|
|
3706
|
-
if (timer) clearTimeout(timer);
|
|
3707
|
-
};
|
|
3708
|
-
}, [fn, running, options.throttleMs]);
|
|
3709
|
-
var start = React.useCallback(function () {
|
|
3710
|
-
startedAtRef.current = new Date();
|
|
3711
|
-
setRunning(true);
|
|
3712
|
-
}, []);
|
|
3713
|
-
var stop = React.useCallback(function () {
|
|
3714
|
-
loopId.current += 1; // force the loop to stop immediately.
|
|
3715
|
-
setRunning(false);
|
|
3716
|
-
startedAtRef.current = null;
|
|
3717
|
-
}, []);
|
|
3718
|
-
React.useEffect(function startAutomatically() {
|
|
3719
|
-
if (options.autoStart) start();
|
|
3720
|
-
return stop;
|
|
3721
|
-
}, [options.autoStart, start, stop]);
|
|
3722
|
-
return {
|
|
3723
|
-
start: start,
|
|
3724
|
-
stop: stop
|
|
3725
|
-
};
|
|
3726
|
-
}
|
|
3727
|
-
|
|
3728
|
-
function listAvailableCameras(facingMode_1) {
|
|
3729
|
-
return __awaiter(this, arguments, void 0, function (facingMode, requestMicAccess) {
|
|
3730
|
-
var cameraEnumerationStream, allDevices, allowedVideoDevices;
|
|
3731
|
-
if (requestMicAccess === void 0) {
|
|
3732
|
-
requestMicAccess = false;
|
|
3733
|
-
}
|
|
3734
|
-
return __generator(this, function (_a) {
|
|
3735
|
-
switch (_a.label) {
|
|
3736
|
-
case 0:
|
|
3737
|
-
return [4 /*yield*/, navigator.mediaDevices.getUserMedia({
|
|
3738
|
-
video: {
|
|
3739
|
-
facingMode: {
|
|
3740
|
-
exact: facingMode
|
|
3741
|
-
}
|
|
3742
|
-
},
|
|
3743
|
-
audio: requestMicAccess
|
|
3744
|
-
})
|
|
3745
|
-
// This lists all available cameras attached to the user's device.
|
|
3746
|
-
];
|
|
3747
|
-
case 1:
|
|
3748
|
-
cameraEnumerationStream = _a.sent();
|
|
3749
|
-
return [4 /*yield*/, navigator.mediaDevices.enumerateDevices()];
|
|
3750
|
-
case 2:
|
|
3751
|
-
allDevices = _a.sent();
|
|
3752
|
-
allowedVideoDevices = allDevices.filter(function (_a) {
|
|
3753
|
-
var kind = _a.kind,
|
|
3754
|
-
label = _a.label;
|
|
3755
|
-
return kind === 'videoinput' && !label.toLowerCase().includes('virtual');
|
|
3756
|
-
});
|
|
3757
|
-
// Release the access to the user's camera that we obtained for enumeration purposes.
|
|
3758
|
-
cameraEnumerationStream.getVideoTracks().forEach(function (track) {
|
|
3759
|
-
track.enabled = false;
|
|
3760
|
-
track.stop();
|
|
3761
|
-
});
|
|
3762
|
-
cameraEnumerationStream = null;
|
|
3763
|
-
return [2 /*return*/, allowedVideoDevices];
|
|
3764
|
-
}
|
|
3765
|
-
});
|
|
3766
|
-
});
|
|
3767
|
-
}
|
|
3768
|
-
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) {
|
|
3769
|
-
return s.toLocaleLowerCase().split(' ').join('');
|
|
3770
|
-
});
|
|
3771
|
-
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) {
|
|
3772
|
-
return s.toLocaleLowerCase().split(' ').join('');
|
|
3773
|
-
});
|
|
3774
|
-
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) {
|
|
3775
|
-
return s.toLocaleLowerCase().split(' ').join('');
|
|
3776
|
-
});
|
|
3777
|
-
var cameraLabelMatches = function cameraLabelMatches(labelOrDevice, labelSetOrLabel) {
|
|
3778
|
-
var label = labelOrDevice instanceof MediaDeviceInfo ? getDeviceLabel(labelOrDevice) : labelOrDevice;
|
|
3779
|
-
var labelSet = typeof labelSetOrLabel === 'string' ? [labelSetOrLabel] : labelSetOrLabel;
|
|
3780
|
-
return labelSet.some(function (l) {
|
|
3781
|
-
return label.includes(l);
|
|
3782
|
-
});
|
|
3783
|
-
};
|
|
3784
|
-
var getDeviceLabel = function getDeviceLabel(deviceInfo) {
|
|
3785
|
-
return deviceInfo.label.toLocaleLowerCase().split(' ').join('');
|
|
3786
|
-
};
|
|
3787
|
-
var currentCamera;
|
|
3788
|
-
function obtainCameraAccess(stream, deviceLabel, video) {
|
|
3789
|
-
releaseCameraAccess();
|
|
3790
|
-
log('obtaining camera access...');
|
|
3791
|
-
var _a = stream.getVideoTracks()[0].getSettings(),
|
|
3792
|
-
width = _a.width,
|
|
3793
|
-
height = _a.height;
|
|
3794
|
-
log('camera dimensions', width, height);
|
|
3795
|
-
var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
|
|
3796
|
-
log('camera label', label);
|
|
3797
|
-
var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
|
|
3798
|
-
log('is rear facing?', isRearFacing);
|
|
3799
|
-
var release = function release() {
|
|
3800
|
-
stream.getTracks().forEach(function (track) {
|
|
3801
|
-
track.enabled = false;
|
|
3802
|
-
track.stop();
|
|
3803
|
-
});
|
|
3804
|
-
if (video) {
|
|
3805
|
-
video.pause();
|
|
3806
|
-
video.srcObject = null;
|
|
3807
|
-
video.src = '';
|
|
3164
|
+
var currentCamera;
|
|
3165
|
+
function obtainCameraAccess(stream, deviceLabel, video) {
|
|
3166
|
+
releaseCameraAccess();
|
|
3167
|
+
log('obtaining camera access...');
|
|
3168
|
+
var _a = stream.getVideoTracks()[0].getSettings(),
|
|
3169
|
+
width = _a.width,
|
|
3170
|
+
height = _a.height;
|
|
3171
|
+
log('camera dimensions', width, height);
|
|
3172
|
+
var label = deviceLabel.toLocaleLowerCase().split(' ').join('');
|
|
3173
|
+
log('camera label', label);
|
|
3174
|
+
var isRearFacing = cameraLabelMatches(label, __spreadArray(__spreadArray(__spreadArray([], rearCameraLabels, true), backUltraWideCameraLabels, true), ['iphone'], false));
|
|
3175
|
+
log('is rear facing?', isRearFacing);
|
|
3176
|
+
var release = function release() {
|
|
3177
|
+
stream.getTracks().forEach(function (track) {
|
|
3178
|
+
track.enabled = false;
|
|
3179
|
+
track.stop();
|
|
3180
|
+
});
|
|
3181
|
+
if (video) {
|
|
3182
|
+
video.pause();
|
|
3183
|
+
video.srcObject = null;
|
|
3184
|
+
video.src = '';
|
|
3808
3185
|
}
|
|
3809
3186
|
};
|
|
3810
3187
|
width || (width = 0);
|
|
@@ -5609,29 +4986,294 @@ function DocumentDetectionModelProvider(_a) {
|
|
|
5609
4986
|
}, []);
|
|
5610
4987
|
var value = React.useMemo(function () {
|
|
5611
4988
|
return {
|
|
5612
|
-
startDocumentDetection: start,
|
|
5613
|
-
stopDocumentDetection: stop,
|
|
5614
|
-
loadDocumentDetectionModel: load,
|
|
5615
|
-
documentDetectionModelState: modelLoadState,
|
|
5616
|
-
documentDetectionModelWarmingStartedAt: modelWarmingStartedAt,
|
|
5617
|
-
documentDetectionModelError: modelError,
|
|
5618
|
-
documentDetectionModelDownloadProgress: modelDownloadProgress,
|
|
5619
|
-
onDocumentDetected: onDocumentDetected,
|
|
5620
|
-
detectionTime: lastDetectionTime,
|
|
5621
|
-
documentDetectionThresholds: documentDetectionThresholds,
|
|
5622
|
-
setDocumentDetectionThresholds: setDocumentDetectionThresholds,
|
|
5623
|
-
documentDetectionBoundaries: documentDetectionBoundaries,
|
|
5624
|
-
setDocumentDetectionBoundaries: setDocumentDetectionBoundaries,
|
|
5625
|
-
documentDetectionLastPredictionCanvas: lastPredictionCanvas,
|
|
5626
|
-
clearDocumentDetectionLastPredictionCanvas: clearDocumentDetectionLastPredictionCanvas
|
|
4989
|
+
startDocumentDetection: start,
|
|
4990
|
+
stopDocumentDetection: stop,
|
|
4991
|
+
loadDocumentDetectionModel: load,
|
|
4992
|
+
documentDetectionModelState: modelLoadState,
|
|
4993
|
+
documentDetectionModelWarmingStartedAt: modelWarmingStartedAt,
|
|
4994
|
+
documentDetectionModelError: modelError,
|
|
4995
|
+
documentDetectionModelDownloadProgress: modelDownloadProgress,
|
|
4996
|
+
onDocumentDetected: onDocumentDetected,
|
|
4997
|
+
detectionTime: lastDetectionTime,
|
|
4998
|
+
documentDetectionThresholds: documentDetectionThresholds,
|
|
4999
|
+
setDocumentDetectionThresholds: setDocumentDetectionThresholds,
|
|
5000
|
+
documentDetectionBoundaries: documentDetectionBoundaries,
|
|
5001
|
+
setDocumentDetectionBoundaries: setDocumentDetectionBoundaries,
|
|
5002
|
+
documentDetectionLastPredictionCanvas: lastPredictionCanvas,
|
|
5003
|
+
clearDocumentDetectionLastPredictionCanvas: clearDocumentDetectionLastPredictionCanvas
|
|
5004
|
+
};
|
|
5005
|
+
}, [start, stop, load, modelLoadState, modelWarmingStartedAt, modelError, modelDownloadProgress, onDocumentDetected, documentDetectionThresholds, documentDetectionBoundaries, clearDocumentDetectionLastPredictionCanvas]);
|
|
5006
|
+
return /*#__PURE__*/React__namespace.createElement(DocumentDetectionModelContext.Provider, {
|
|
5007
|
+
value: value
|
|
5008
|
+
}, /*#__PURE__*/React__namespace.createElement(InvisibleCanvas, {
|
|
5009
|
+
key: canvasKey,
|
|
5010
|
+
ref: lastPredictionCanvas
|
|
5011
|
+
}), children);
|
|
5012
|
+
}
|
|
5013
|
+
|
|
5014
|
+
function cropToShoulders(rawCanvas, cropCanvas, resizeCanvas, frame, face, quality, maxHeight) {
|
|
5015
|
+
var _a;
|
|
5016
|
+
if (quality === void 0) {
|
|
5017
|
+
quality = 0.92;
|
|
5018
|
+
}
|
|
5019
|
+
if (!rawCanvas || !cropCanvas || !resizeCanvas) return '';
|
|
5020
|
+
var rawCtx = rawCanvas.getContext('2d');
|
|
5021
|
+
var cropCtx = cropCanvas.getContext('2d');
|
|
5022
|
+
var resizeCtx = resizeCanvas.getContext('2d');
|
|
5023
|
+
if (!rawCtx || !cropCtx || !resizeCtx) throw new Error('could not get 2d context');
|
|
5024
|
+
rawCanvas.width = frame.width;
|
|
5025
|
+
rawCanvas.height = frame.height;
|
|
5026
|
+
rawCtx.putImageData(frame, 0, 0);
|
|
5027
|
+
if (frame.height > frame.width) {
|
|
5028
|
+
cropCanvas.width = frame.width;
|
|
5029
|
+
cropCanvas.height = frame.height;
|
|
5030
|
+
cropCtx.drawImage(rawCanvas, 0, 0, cropCanvas.width, cropCanvas.height);
|
|
5031
|
+
} else {
|
|
5032
|
+
var _b = (_a = face === null || face === void 0 ? void 0 : face.box) !== null && _a !== void 0 ? _a : {
|
|
5033
|
+
xMin: 0,
|
|
5034
|
+
width: frame.width
|
|
5035
|
+
},
|
|
5036
|
+
xMin = _b.xMin,
|
|
5037
|
+
width = _b.width;
|
|
5038
|
+
var desiredWidth = frame.height * 0.6;
|
|
5039
|
+
var faceCenterX = xMin + width / 2;
|
|
5040
|
+
var xPos = Math.max(0, faceCenterX - desiredWidth / 2);
|
|
5041
|
+
cropCanvas.width = desiredWidth;
|
|
5042
|
+
cropCanvas.height = frame.height;
|
|
5043
|
+
cropCtx.drawImage(rawCanvas, xPos, 0, cropCanvas.width, cropCanvas.height, 0, 0, cropCanvas.width, cropCanvas.height);
|
|
5044
|
+
}
|
|
5045
|
+
resizeCanvas.height = maxHeight !== null && maxHeight !== void 0 ? maxHeight : cropCanvas.height;
|
|
5046
|
+
resizeCanvas.width = cropCanvas.width * (resizeCanvas.height / cropCanvas.height);
|
|
5047
|
+
resizeCtx === null || resizeCtx === void 0 ? void 0 : resizeCtx.drawImage(cropCanvas, 0, 0, resizeCanvas.width, resizeCanvas.height);
|
|
5048
|
+
var dataURL = resizeCanvas.toDataURL('image/jpeg', quality);
|
|
5049
|
+
log('cropToShoulders size', new TextEncoder().encode(dataURL).length);
|
|
5050
|
+
clearCanvas(rawCanvas);
|
|
5051
|
+
clearCanvas(cropCanvas);
|
|
5052
|
+
clearCanvas(resizeCanvas);
|
|
5053
|
+
return dataURL;
|
|
5054
|
+
}
|
|
5055
|
+
function cropToDetectedObjectBox(frame, box, canvas, padding) {
|
|
5056
|
+
if (padding === void 0) {
|
|
5057
|
+
padding = 0;
|
|
5058
|
+
}
|
|
5059
|
+
canvas || (canvas = document.createElement('canvas'));
|
|
5060
|
+
var ctx = canvas.getContext('2d');
|
|
5061
|
+
if (!ctx) throw new Error('could not get 2d context');
|
|
5062
|
+
var xMin = box.xMin,
|
|
5063
|
+
yMin = box.yMin,
|
|
5064
|
+
width = box.width,
|
|
5065
|
+
height = box.height;
|
|
5066
|
+
canvas.width = width + padding * 2;
|
|
5067
|
+
canvas.height = height + padding * 2;
|
|
5068
|
+
ctx.drawImage(frame, xMin - padding, yMin - padding, width + padding * 2, height + padding * 2, 0, 0, canvas.width, canvas.height);
|
|
5069
|
+
return canvas;
|
|
5070
|
+
}
|
|
5071
|
+
function cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box, padding) {
|
|
5072
|
+
if (padding === void 0) {
|
|
5073
|
+
padding = 0;
|
|
5074
|
+
}
|
|
5075
|
+
if (!box) return imageData;
|
|
5076
|
+
var cropped = cropToDetectedObjectBox(imageData, box, cropCanvas, padding);
|
|
5077
|
+
var _a = [box.width, box.height],
|
|
5078
|
+
bw = _a[0],
|
|
5079
|
+
bh = _a[1];
|
|
5080
|
+
if (bh <= bw) return cropped;
|
|
5081
|
+
var ctx = rotateCanvas.getContext('2d');
|
|
5082
|
+
if (!ctx) return cropped;
|
|
5083
|
+
rotateCanvas.width = bh;
|
|
5084
|
+
rotateCanvas.height = bw;
|
|
5085
|
+
ctx.clearRect(0, 0, rotateCanvas.width, rotateCanvas.height);
|
|
5086
|
+
ctx.translate(rotateCanvas.width / 2, rotateCanvas.height / 2);
|
|
5087
|
+
ctx.rotate(1.5708); // 90 deg in radians
|
|
5088
|
+
ctx.drawImage(cropped, -bw / 2, -bh / 2);
|
|
5089
|
+
return rotateCanvas;
|
|
5090
|
+
}
|
|
5091
|
+
function resizeIfNecessary(imageData, resizeCanvas, maxWidth) {
|
|
5092
|
+
var width = imageData.width,
|
|
5093
|
+
height = imageData.height;
|
|
5094
|
+
if (width <= maxWidth) return imageData;
|
|
5095
|
+
var resizeCtx = resizeCanvas.getContext('2d');
|
|
5096
|
+
if (!resizeCtx) return imageData;
|
|
5097
|
+
var scale = maxWidth / width;
|
|
5098
|
+
resizeCanvas.width = maxWidth;
|
|
5099
|
+
resizeCanvas.height = height * scale;
|
|
5100
|
+
resizeCtx.drawImage(imageData, 0, 0, resizeCanvas.width, resizeCanvas.height);
|
|
5101
|
+
return resizeCanvas;
|
|
5102
|
+
}
|
|
5103
|
+
|
|
5104
|
+
var defaultFocusModelLoadTimeoutMs = 45000;
|
|
5105
|
+
var defaultFocusThresholds = {
|
|
5106
|
+
idCardFront: {
|
|
5107
|
+
desktop: 0,
|
|
5108
|
+
mobile: 0.3
|
|
5109
|
+
},
|
|
5110
|
+
idCardBack: {
|
|
5111
|
+
desktop: 0,
|
|
5112
|
+
mobile: 0.3
|
|
5113
|
+
},
|
|
5114
|
+
passport: {
|
|
5115
|
+
desktop: 0,
|
|
5116
|
+
mobile: 0.3
|
|
5117
|
+
},
|
|
5118
|
+
singlePage: {
|
|
5119
|
+
desktop: 0,
|
|
5120
|
+
mobile: 0.3
|
|
5121
|
+
}
|
|
5122
|
+
};
|
|
5123
|
+
var classifier$1 = null;
|
|
5124
|
+
var classifierSettings$1 = null;
|
|
5125
|
+
function loadFocusModel() {
|
|
5126
|
+
return __awaiter(this, arguments, void 0, function (modelAssetPath) {
|
|
5127
|
+
var _a, _b;
|
|
5128
|
+
if (modelAssetPath === void 0) {
|
|
5129
|
+
modelAssetPath = defaultFocusModelPath;
|
|
5130
|
+
}
|
|
5131
|
+
return __generator(this, function (_c) {
|
|
5132
|
+
switch (_c.label) {
|
|
5133
|
+
case 0:
|
|
5134
|
+
if (classifier$1 && (classifierSettings$1 === null || classifierSettings$1 === void 0 ? void 0 : classifierSettings$1.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier$1];
|
|
5135
|
+
closeFocusModel();
|
|
5136
|
+
return [4 /*yield*/, preloadFocusModelDependencies()];
|
|
5137
|
+
case 1:
|
|
5138
|
+
_c.sent();
|
|
5139
|
+
if (modelCapabilities.delegate === 'NONE') {
|
|
5140
|
+
throw new Error('No available delegate for focus detector.');
|
|
5141
|
+
}
|
|
5142
|
+
_b = (_a = tasksVision.ImageClassifier).createFromOptions;
|
|
5143
|
+
return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
|
|
5144
|
+
case 2:
|
|
5145
|
+
return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
|
|
5146
|
+
baseOptions: {
|
|
5147
|
+
modelAssetPath: modelAssetPath,
|
|
5148
|
+
delegate: modelCapabilities.delegate
|
|
5149
|
+
},
|
|
5150
|
+
// canvas: document.createElement('canvas'),
|
|
5151
|
+
runningMode: 'VIDEO'
|
|
5152
|
+
}])];
|
|
5153
|
+
case 3:
|
|
5154
|
+
classifier$1 = _c.sent();
|
|
5155
|
+
classifierSettings$1 = {
|
|
5156
|
+
modelAssetPath: modelAssetPath
|
|
5157
|
+
};
|
|
5158
|
+
return [2 /*return*/, classifier$1];
|
|
5159
|
+
}
|
|
5160
|
+
});
|
|
5161
|
+
});
|
|
5162
|
+
}
|
|
5163
|
+
function closeFocusModel() {
|
|
5164
|
+
classifier$1 === null || classifier$1 === void 0 ? void 0 : classifier$1.close();
|
|
5165
|
+
classifier$1 = null;
|
|
5166
|
+
classifierSettings$1 = null;
|
|
5167
|
+
}
|
|
5168
|
+
function useLoadFocusModel(_a) {
|
|
5169
|
+
var _b = _a.modelPath,
|
|
5170
|
+
modelPath = _b === void 0 ? defaultFocusModelPath : _b,
|
|
5171
|
+
_c = _a.modelLoadTimeoutMs,
|
|
5172
|
+
modelLoadTimeoutMs = _c === void 0 ? defaultFocusModelLoadTimeoutMs : _c,
|
|
5173
|
+
onModelError = _a.onModelError,
|
|
5174
|
+
videoRef = _a.videoRef,
|
|
5175
|
+
_d = _a.shouldLoadModels,
|
|
5176
|
+
shouldLoadModels = _d === void 0 ? true : _d;
|
|
5177
|
+
var _e = React.useState('not-started'),
|
|
5178
|
+
modelLoadState = _e[0],
|
|
5179
|
+
setModelLoadState = _e[1];
|
|
5180
|
+
var _f = React.useState(0),
|
|
5181
|
+
modelDownloadProgress = _f[0],
|
|
5182
|
+
setModelDownloadProgress = _f[1];
|
|
5183
|
+
var _g = React.useState(null),
|
|
5184
|
+
modelWarmingStartedAt = _g[0],
|
|
5185
|
+
setModelWarmingStartedAt = _g[1];
|
|
5186
|
+
var _h = React.useState(null),
|
|
5187
|
+
modelError = _h[0],
|
|
5188
|
+
setModelError = _h[1];
|
|
5189
|
+
React.useEffect(function loadModel() {
|
|
5190
|
+
var _this = this;
|
|
5191
|
+
if (!shouldLoadModels) return;
|
|
5192
|
+
setModelLoadState('downloading');
|
|
5193
|
+
setModelWarmingStartedAt(null);
|
|
5194
|
+
function handleDownloadProgress(event) {
|
|
5195
|
+
setModelDownloadProgress(progressToPercentage(event.detail));
|
|
5196
|
+
}
|
|
5197
|
+
document.addEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
|
|
5198
|
+
var modelLoadTimeout = setTimeout(function () {
|
|
5199
|
+
setModelError(new Error('Model loading time limit exceeded.'));
|
|
5200
|
+
}, modelLoadTimeoutMs);
|
|
5201
|
+
var cancelVideoReady = function cancelVideoReady() {};
|
|
5202
|
+
loadFocusModel(modelPath).then(function (loadedModel) {
|
|
5203
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
5204
|
+
var _a, videoReady, cancel, cancelled;
|
|
5205
|
+
return __generator(this, function (_b) {
|
|
5206
|
+
switch (_b.label) {
|
|
5207
|
+
case 0:
|
|
5208
|
+
setModelDownloadProgress(100);
|
|
5209
|
+
clearTimeout(modelLoadTimeout);
|
|
5210
|
+
setModelLoadState('warming');
|
|
5211
|
+
setModelWarmingStartedAt(performance.now());
|
|
5212
|
+
_a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
|
|
5213
|
+
cancelled = false;
|
|
5214
|
+
cancelVideoReady = function cancelVideoReady() {
|
|
5215
|
+
cancelled = true;
|
|
5216
|
+
cancel();
|
|
5217
|
+
};
|
|
5218
|
+
return [4 /*yield*/, videoReady];
|
|
5219
|
+
case 1:
|
|
5220
|
+
_b.sent();
|
|
5221
|
+
setTimeout(function () {
|
|
5222
|
+
if (cancelled) return;
|
|
5223
|
+
loadedModel.classifyForVideo(videoRef.current, performance.now());
|
|
5224
|
+
setModelLoadState('ready');
|
|
5225
|
+
}, 500);
|
|
5226
|
+
return [2 /*return*/];
|
|
5227
|
+
}
|
|
5228
|
+
});
|
|
5229
|
+
});
|
|
5230
|
+
})["catch"](function (e) {
|
|
5231
|
+
setModelError(e);
|
|
5232
|
+
setModelLoadState('error');
|
|
5233
|
+
})["finally"](function () {
|
|
5234
|
+
clearTimeout(modelLoadTimeout);
|
|
5235
|
+
});
|
|
5236
|
+
return function () {
|
|
5237
|
+
log('unloading focus model');
|
|
5238
|
+
cancelVideoReady();
|
|
5239
|
+
closeFocusModel();
|
|
5240
|
+
clearTimeout(modelLoadTimeout);
|
|
5241
|
+
document.removeEventListener('idmission.preloadProgress.focus', handleDownloadProgress);
|
|
5242
|
+
};
|
|
5243
|
+
}, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
|
|
5244
|
+
React.useEffect(function handleModelError() {
|
|
5245
|
+
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
5246
|
+
}, [modelError, onModelError]);
|
|
5247
|
+
return React.useMemo(function () {
|
|
5248
|
+
return {
|
|
5249
|
+
ready: modelLoadState === 'ready',
|
|
5250
|
+
modelLoadState: modelLoadState,
|
|
5251
|
+
modelDownloadProgress: modelDownloadProgress,
|
|
5252
|
+
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
5253
|
+
modelError: modelError
|
|
5627
5254
|
};
|
|
5628
|
-
}, [
|
|
5629
|
-
|
|
5630
|
-
|
|
5631
|
-
|
|
5632
|
-
|
|
5633
|
-
|
|
5634
|
-
|
|
5255
|
+
}, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
|
|
5256
|
+
}
|
|
5257
|
+
var lastFocusPredictionAt = 0;
|
|
5258
|
+
var lastFocusPredictionTime = 0;
|
|
5259
|
+
function setLastFocusPredictionAt(time) {
|
|
5260
|
+
lastFocusPredictionTime = time - lastFocusPredictionAt;
|
|
5261
|
+
lastFocusPredictionAt = time;
|
|
5262
|
+
}
|
|
5263
|
+
function makeFocusModelPrediction(imageData, cropCanvas, rotateCanvas, box) {
|
|
5264
|
+
var _a, _b, _c, _d, _e;
|
|
5265
|
+
if (!classifier$1) return null;
|
|
5266
|
+
var startedAt = performance.now();
|
|
5267
|
+
var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
|
|
5268
|
+
var result = classifier$1.classifyForVideo(image, performance.now());
|
|
5269
|
+
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) {
|
|
5270
|
+
return c.categoryName === 'focused';
|
|
5271
|
+
})) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
|
|
5272
|
+
var predictionTime = performance.now() - startedAt;
|
|
5273
|
+
return {
|
|
5274
|
+
score: score,
|
|
5275
|
+
predictionTime: predictionTime
|
|
5276
|
+
};
|
|
5635
5277
|
}
|
|
5636
5278
|
|
|
5637
5279
|
var FocusModelContext = /*#__PURE__*/React.createContext({
|
|
@@ -5708,52 +5350,424 @@ function FocusModelProvider(_a) {
|
|
|
5708
5350
|
}, [focusThresholds, load, makeFocusPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
|
|
5709
5351
|
return /*#__PURE__*/React__namespace.default.createElement(FocusModelContext.Provider, {
|
|
5710
5352
|
value: value
|
|
5711
|
-
}, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5353
|
+
}, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5712
5354
|
ref: rotateCanvas,
|
|
5713
5355
|
style: showCanvases ? {
|
|
5714
5356
|
display: 'block'
|
|
5715
5357
|
} : undefined
|
|
5716
5358
|
}), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5717
|
-
ref: cropCanvas,
|
|
5359
|
+
ref: cropCanvas,
|
|
5360
|
+
style: showCanvases ? {
|
|
5361
|
+
display: 'block'
|
|
5362
|
+
} : undefined
|
|
5363
|
+
})), children);
|
|
5364
|
+
}
|
|
5365
|
+
|
|
5366
|
+
function _isNavigatorDefined() {
|
|
5367
|
+
return typeof navigator !== 'undefined' && navigator != null;
|
|
5368
|
+
}
|
|
5369
|
+
var isMobileCache;
|
|
5370
|
+
function isMobile() {
|
|
5371
|
+
if (isMobileCache !== undefined) return isMobileCache;
|
|
5372
|
+
isMobileCache = evaluateIsMobile();
|
|
5373
|
+
return isMobileCache;
|
|
5374
|
+
}
|
|
5375
|
+
function evaluateIsMobile(nav) {
|
|
5376
|
+
if (nav || _isNavigatorDefined()) {
|
|
5377
|
+
if (!nav) {
|
|
5378
|
+
nav = navigator;
|
|
5379
|
+
}
|
|
5380
|
+
if (nav.product === 'ReactNative') {
|
|
5381
|
+
return true;
|
|
5382
|
+
}
|
|
5383
|
+
var a = nav.userAgent || nav.vendor || (
|
|
5384
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5385
|
+
// @ts-ignore
|
|
5386
|
+
typeof window !== 'undefined' ? window.opera : '');
|
|
5387
|
+
if (!a) {
|
|
5388
|
+
var navAny = nav;
|
|
5389
|
+
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5390
|
+
// @ts-ignore
|
|
5391
|
+
return navAny.userAgentData && navAny.userAgentData.mobile;
|
|
5392
|
+
}
|
|
5393
|
+
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));
|
|
5394
|
+
}
|
|
5395
|
+
return false;
|
|
5396
|
+
}
|
|
5397
|
+
|
|
5398
|
+
var defaultBarcodeReadabilityModelLoadTimeoutMs = 45000;
|
|
5399
|
+
var classifier = null;
|
|
5400
|
+
var classifierSettings = null;
|
|
5401
|
+
function loadBarcodeReadabilityModel() {
|
|
5402
|
+
return __awaiter(this, arguments, void 0, function (modelAssetPath) {
|
|
5403
|
+
var _a, _b;
|
|
5404
|
+
if (modelAssetPath === void 0) {
|
|
5405
|
+
modelAssetPath = defaultBarcodeReadabilityModelPath;
|
|
5406
|
+
}
|
|
5407
|
+
return __generator(this, function (_c) {
|
|
5408
|
+
switch (_c.label) {
|
|
5409
|
+
case 0:
|
|
5410
|
+
if (classifier && (classifierSettings === null || classifierSettings === void 0 ? void 0 : classifierSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, classifier];
|
|
5411
|
+
closeBarcodeReadabilityModel();
|
|
5412
|
+
return [4 /*yield*/, preloadBarcodeReadabilityModelDependencies()];
|
|
5413
|
+
case 1:
|
|
5414
|
+
_c.sent();
|
|
5415
|
+
if (modelCapabilities.delegate === 'NONE') {
|
|
5416
|
+
throw new Error('No available delegate for barcode readability model.');
|
|
5417
|
+
}
|
|
5418
|
+
_b = (_a = tasksVision.ImageClassifier).createFromOptions;
|
|
5419
|
+
return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
|
|
5420
|
+
case 2:
|
|
5421
|
+
return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
|
|
5422
|
+
baseOptions: {
|
|
5423
|
+
modelAssetPath: modelAssetPath,
|
|
5424
|
+
delegate: 'CPU'
|
|
5425
|
+
},
|
|
5426
|
+
runningMode: 'VIDEO',
|
|
5427
|
+
maxResults: 1
|
|
5428
|
+
}])];
|
|
5429
|
+
case 3:
|
|
5430
|
+
classifier = _c.sent();
|
|
5431
|
+
classifierSettings = {
|
|
5432
|
+
modelAssetPath: modelAssetPath
|
|
5433
|
+
};
|
|
5434
|
+
return [2 /*return*/, classifier];
|
|
5435
|
+
}
|
|
5436
|
+
});
|
|
5437
|
+
});
|
|
5438
|
+
}
|
|
5439
|
+
function closeBarcodeReadabilityModel() {
|
|
5440
|
+
classifier === null || classifier === void 0 ? void 0 : classifier.close();
|
|
5441
|
+
classifier = null;
|
|
5442
|
+
classifierSettings = null;
|
|
5443
|
+
}
|
|
5444
|
+
function useLoadBarcodeReadabilityModel(_a) {
|
|
5445
|
+
var _b = _a.modelPath,
|
|
5446
|
+
modelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
|
|
5447
|
+
_c = _a.modelLoadTimeoutMs,
|
|
5448
|
+
modelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
|
|
5449
|
+
onModelError = _a.onModelError,
|
|
5450
|
+
videoRef = _a.videoRef,
|
|
5451
|
+
_d = _a.shouldLoadModels,
|
|
5452
|
+
shouldLoadModels = _d === void 0 ? true : _d;
|
|
5453
|
+
var _e = React.useState('not-started'),
|
|
5454
|
+
modelLoadState = _e[0],
|
|
5455
|
+
setModelLoadState = _e[1];
|
|
5456
|
+
var _f = React.useState(0),
|
|
5457
|
+
modelDownloadProgress = _f[0],
|
|
5458
|
+
setModelDownloadProgress = _f[1];
|
|
5459
|
+
var _g = React.useState(null),
|
|
5460
|
+
modelWarmingStartedAt = _g[0],
|
|
5461
|
+
setModelWarmingStartedAt = _g[1];
|
|
5462
|
+
var _h = React.useState(null),
|
|
5463
|
+
modelError = _h[0],
|
|
5464
|
+
setModelError = _h[1];
|
|
5465
|
+
React.useEffect(function loadModel() {
|
|
5466
|
+
var _this = this;
|
|
5467
|
+
if (!shouldLoadModels) return;
|
|
5468
|
+
setModelLoadState('downloading');
|
|
5469
|
+
setModelWarmingStartedAt(null);
|
|
5470
|
+
function handleDownloadProgress(event) {
|
|
5471
|
+
setModelDownloadProgress(progressToPercentage(event.detail));
|
|
5472
|
+
}
|
|
5473
|
+
document.addEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
|
|
5474
|
+
var modelLoadTimeout = setTimeout(function () {
|
|
5475
|
+
setModelError(new Error('Model loading time limit exceeded.'));
|
|
5476
|
+
}, modelLoadTimeoutMs);
|
|
5477
|
+
var cancelVideoReady = function cancelVideoReady() {};
|
|
5478
|
+
loadBarcodeReadabilityModel(modelPath).then(function (loadedModel) {
|
|
5479
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
5480
|
+
var _a, videoReady, cancel, cancelled;
|
|
5481
|
+
return __generator(this, function (_b) {
|
|
5482
|
+
switch (_b.label) {
|
|
5483
|
+
case 0:
|
|
5484
|
+
setModelDownloadProgress(100);
|
|
5485
|
+
clearTimeout(modelLoadTimeout);
|
|
5486
|
+
setModelLoadState('warming');
|
|
5487
|
+
setModelWarmingStartedAt(new Date().getTime());
|
|
5488
|
+
_a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
|
|
5489
|
+
cancelled = false;
|
|
5490
|
+
cancelVideoReady = function cancelVideoReady() {
|
|
5491
|
+
cancelled = true;
|
|
5492
|
+
cancel();
|
|
5493
|
+
};
|
|
5494
|
+
return [4 /*yield*/, videoReady];
|
|
5495
|
+
case 1:
|
|
5496
|
+
_b.sent();
|
|
5497
|
+
setTimeout(function () {
|
|
5498
|
+
if (cancelled) return;
|
|
5499
|
+
loadedModel.classifyForVideo(videoRef.current, performance.now());
|
|
5500
|
+
setModelLoadState('ready');
|
|
5501
|
+
}, 500);
|
|
5502
|
+
return [2 /*return*/];
|
|
5503
|
+
}
|
|
5504
|
+
});
|
|
5505
|
+
});
|
|
5506
|
+
})["catch"](function (e) {
|
|
5507
|
+
setModelError(e);
|
|
5508
|
+
setModelLoadState('error');
|
|
5509
|
+
})["finally"](function () {
|
|
5510
|
+
clearTimeout(modelLoadTimeout);
|
|
5511
|
+
});
|
|
5512
|
+
return function () {
|
|
5513
|
+
log('unloading barcode readability model');
|
|
5514
|
+
cancelVideoReady();
|
|
5515
|
+
closeBarcodeReadabilityModel();
|
|
5516
|
+
clearTimeout(modelLoadTimeout);
|
|
5517
|
+
document.removeEventListener('idmission.preloadProgress.barcodeReadability', handleDownloadProgress);
|
|
5518
|
+
};
|
|
5519
|
+
}, [modelPath, modelLoadTimeoutMs, videoRef, shouldLoadModels]);
|
|
5520
|
+
React.useEffect(function handleModelError() {
|
|
5521
|
+
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
5522
|
+
}, [modelError, onModelError]);
|
|
5523
|
+
return React.useMemo(function () {
|
|
5524
|
+
return {
|
|
5525
|
+
ready: modelLoadState === 'ready',
|
|
5526
|
+
modelLoadState: modelLoadState,
|
|
5527
|
+
modelDownloadProgress: modelDownloadProgress,
|
|
5528
|
+
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
5529
|
+
modelError: modelError
|
|
5530
|
+
};
|
|
5531
|
+
}, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
|
|
5532
|
+
}
|
|
5533
|
+
var lastBarcodeReadabilityPredictionAt = 0;
|
|
5534
|
+
var lastBarcodeReadabilityPredictionTime = 0;
|
|
5535
|
+
function setLastBarcodeReadabilityPredictionAt(time) {
|
|
5536
|
+
lastBarcodeReadabilityPredictionTime = time - lastBarcodeReadabilityPredictionAt;
|
|
5537
|
+
lastBarcodeReadabilityPredictionAt = time;
|
|
5538
|
+
}
|
|
5539
|
+
function makeBarcodeReadabilityModelPrediction(imageData, cropCanvas, rotateCanvas, resizeCanvas, box) {
|
|
5540
|
+
var _a, _b, _c, _d, _e;
|
|
5541
|
+
if (!classifier) return null;
|
|
5542
|
+
var startedAt = performance.now();
|
|
5543
|
+
var image = cropAndRotateIfNecessary(imageData, cropCanvas, rotateCanvas, box);
|
|
5544
|
+
var resized = resizeIfNecessary(image, resizeCanvas, 500);
|
|
5545
|
+
var result = classifier.classifyForVideo(resized, performance.now());
|
|
5546
|
+
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) {
|
|
5547
|
+
return c.categoryName === 'blurry';
|
|
5548
|
+
})) === null || _d === void 0 ? void 0 : _d.score) !== null && _e !== void 0 ? _e : 0;
|
|
5549
|
+
debug('barcode prediction', "".concat(performance.now() - startedAt, "ms"), score);
|
|
5550
|
+
var predictionTime = performance.now() - startedAt;
|
|
5551
|
+
return {
|
|
5552
|
+
score: score,
|
|
5553
|
+
predictionTime: predictionTime
|
|
5554
|
+
};
|
|
5555
|
+
}
|
|
5556
|
+
|
|
5557
|
+
var BarcodeReadabilityModelContext = /*#__PURE__*/React.createContext({
|
|
5558
|
+
loadBarcodeReadabilityModel: function loadBarcodeReadabilityModel() {
|
|
5559
|
+
return null;
|
|
5560
|
+
},
|
|
5561
|
+
barcodeReadabilityModelState: 'not-started',
|
|
5562
|
+
barcodeReadabilityModelDownloadProgress: 0,
|
|
5563
|
+
barcodeReadabilityModelWarmingStartedAt: null,
|
|
5564
|
+
barcodeReadabilityModelError: null,
|
|
5565
|
+
barcodeReadabilityThresholds: {},
|
|
5566
|
+
setBarcodeReadabilityThresholds: function setBarcodeReadabilityThresholds() {
|
|
5567
|
+
return null;
|
|
5568
|
+
},
|
|
5569
|
+
makeBarcodeReadabilityPrediction: function makeBarcodeReadabilityPrediction() {
|
|
5570
|
+
return null;
|
|
5571
|
+
},
|
|
5572
|
+
barcodeReadabilityPredictionTime: 0
|
|
5573
|
+
});
|
|
5574
|
+
function BarcodeReadabilityModelProvider(_a) {
|
|
5575
|
+
var children = _a.children,
|
|
5576
|
+
_b = _a.barcodeReadabilityModelPath,
|
|
5577
|
+
barcodeReadabilityModelPath = _b === void 0 ? defaultBarcodeReadabilityModelPath : _b,
|
|
5578
|
+
_c = _a.barcodeReadabilityModelLoadTimeoutMs,
|
|
5579
|
+
barcodeReadabilityModelLoadTimeoutMs = _c === void 0 ? defaultBarcodeReadabilityModelLoadTimeoutMs : _c,
|
|
5580
|
+
onBarcodeReadabilityModelError = _a.onBarcodeReadabilityModelError,
|
|
5581
|
+
_d = _a.showCanvases,
|
|
5582
|
+
showCanvases = _d === void 0 ? false : _d,
|
|
5583
|
+
_e = _a.shouldLoadModels,
|
|
5584
|
+
shouldLoadModelsProp = _e === void 0 ? true : _e;
|
|
5585
|
+
var cropCanvas = React.useRef(null);
|
|
5586
|
+
var rotateCanvas = React.useRef(null);
|
|
5587
|
+
var resizeCanvas = React.useRef(null);
|
|
5588
|
+
var _f = React.useState({}),
|
|
5589
|
+
barcodeReadabilityThresholds = _f[0],
|
|
5590
|
+
setBarcodeReadabilityThresholds = _f[1];
|
|
5591
|
+
var videoRef = useCameraStore().videoRef;
|
|
5592
|
+
var _g = React.useState(shouldLoadModelsProp),
|
|
5593
|
+
shouldLoadModels = _g[0],
|
|
5594
|
+
setShouldLoadModels = _g[1];
|
|
5595
|
+
var load = React.useCallback(function () {
|
|
5596
|
+
return setShouldLoadModels(true);
|
|
5597
|
+
}, []);
|
|
5598
|
+
var _h = useLoadBarcodeReadabilityModel({
|
|
5599
|
+
modelPath: barcodeReadabilityModelPath,
|
|
5600
|
+
modelLoadTimeoutMs: barcodeReadabilityModelLoadTimeoutMs,
|
|
5601
|
+
onModelError: onBarcodeReadabilityModelError,
|
|
5602
|
+
videoRef: videoRef,
|
|
5603
|
+
shouldLoadModels: shouldLoadModels
|
|
5604
|
+
}),
|
|
5605
|
+
ready = _h.ready,
|
|
5606
|
+
modelLoadState = _h.modelLoadState,
|
|
5607
|
+
modelDownloadProgress = _h.modelDownloadProgress,
|
|
5608
|
+
modelWarmingStartedAt = _h.modelWarmingStartedAt,
|
|
5609
|
+
modelError = _h.modelError;
|
|
5610
|
+
var makeBarcodeReadabilityPrediction = React.useCallback(function (imageData, box) {
|
|
5611
|
+
if (!ready) return null;
|
|
5612
|
+
var prediction = makeBarcodeReadabilityModelPrediction(imageData, cropCanvas.current, rotateCanvas.current, resizeCanvas.current, box);
|
|
5613
|
+
if (!prediction) return null;
|
|
5614
|
+
setLastBarcodeReadabilityPredictionAt(prediction.predictionTime);
|
|
5615
|
+
return prediction;
|
|
5616
|
+
}, [ready]);
|
|
5617
|
+
var value = React.useMemo(function () {
|
|
5618
|
+
return {
|
|
5619
|
+
loadBarcodeReadabilityModel: load,
|
|
5620
|
+
barcodeReadabilityModelState: modelLoadState,
|
|
5621
|
+
barcodeReadabilityModelDownloadProgress: modelDownloadProgress,
|
|
5622
|
+
barcodeReadabilityModelWarmingStartedAt: modelWarmingStartedAt,
|
|
5623
|
+
barcodeReadabilityModelError: modelError,
|
|
5624
|
+
makeBarcodeReadabilityPrediction: makeBarcodeReadabilityPrediction,
|
|
5625
|
+
barcodeReadabilityPredictionTime: lastBarcodeReadabilityPredictionTime,
|
|
5626
|
+
barcodeReadabilityThresholds: barcodeReadabilityThresholds,
|
|
5627
|
+
setBarcodeReadabilityThresholds: setBarcodeReadabilityThresholds
|
|
5628
|
+
};
|
|
5629
|
+
}, [barcodeReadabilityThresholds, load, makeBarcodeReadabilityPrediction, modelDownloadProgress, modelError, modelLoadState, modelWarmingStartedAt]);
|
|
5630
|
+
return /*#__PURE__*/React__namespace.default.createElement(BarcodeReadabilityModelContext.Provider, {
|
|
5631
|
+
value: value
|
|
5632
|
+
}, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5633
|
+
ref: rotateCanvas
|
|
5634
|
+
}), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5635
|
+
ref: cropCanvas
|
|
5636
|
+
}), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5637
|
+
ref: resizeCanvas,
|
|
5718
5638
|
style: showCanvases ? {
|
|
5719
5639
|
display: 'block'
|
|
5720
5640
|
} : undefined
|
|
5721
|
-
}), children);
|
|
5722
|
-
}
|
|
5723
|
-
|
|
5724
|
-
function _isNavigatorDefined() {
|
|
5725
|
-
return typeof navigator !== 'undefined' && navigator != null;
|
|
5641
|
+
})), children);
|
|
5726
5642
|
}
|
|
5727
|
-
|
|
5728
|
-
|
|
5729
|
-
if (
|
|
5730
|
-
|
|
5731
|
-
return isMobileCache;
|
|
5732
|
-
}
|
|
5733
|
-
function evaluateIsMobile(nav) {
|
|
5734
|
-
if (nav || _isNavigatorDefined()) {
|
|
5735
|
-
if (!nav) {
|
|
5736
|
-
nav = navigator;
|
|
5737
|
-
}
|
|
5738
|
-
if (nav.product === 'ReactNative') {
|
|
5739
|
-
return true;
|
|
5740
|
-
}
|
|
5741
|
-
var a = nav.userAgent || nav.vendor || (
|
|
5742
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5743
|
-
// @ts-ignore
|
|
5744
|
-
typeof window !== 'undefined' ? window.opera : '');
|
|
5745
|
-
if (!a) {
|
|
5746
|
-
var navAny = nav;
|
|
5747
|
-
// eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
5748
|
-
// @ts-ignore
|
|
5749
|
-
return navAny.userAgentData && navAny.userAgentData.mobile;
|
|
5750
|
-
}
|
|
5751
|
-
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));
|
|
5643
|
+
function useBarcodeReadabilityModelContext() {
|
|
5644
|
+
var context = React.useContext(BarcodeReadabilityModelContext);
|
|
5645
|
+
if (!context) {
|
|
5646
|
+
throw new Error('useBarcodeReadabilityModelContext must be used within a BarcodeReadabilityModelProvider');
|
|
5752
5647
|
}
|
|
5753
|
-
return
|
|
5648
|
+
return context;
|
|
5754
5649
|
}
|
|
5755
5650
|
|
|
5756
5651
|
var onMobile = isMobile();
|
|
5652
|
+
/**
|
|
5653
|
+
* Analyzes barcode readability for a detected document
|
|
5654
|
+
* @param prediction The document detection prediction
|
|
5655
|
+
* @param lastPredictionCanvas The canvas containing the original frame
|
|
5656
|
+
* @param croppedDocumentCanvas Canvas for storing cropped document
|
|
5657
|
+
* @param bestBarcodeCanvas Canvas for storing best barcode crop
|
|
5658
|
+
* @param currentBestBarcodeScore Current best barcode score
|
|
5659
|
+
* @param documentDetectionThresholds Thresholds for document detection
|
|
5660
|
+
* @param makeBarcodeReadabilityPrediction Function to make barcode readability predictions
|
|
5661
|
+
* @param barcodeReadabilityThresholds Thresholds for barcode readability
|
|
5662
|
+
* @returns Object containing barcode analysis results
|
|
5663
|
+
*/
|
|
5664
|
+
function analyzeBarcodeReadability(prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore, documentDetectionThresholds, makeBarcodeReadabilityPrediction, barcodeReadabilityThreshold) {
|
|
5665
|
+
return __awaiter(this, void 0, void 0, function () {
|
|
5666
|
+
var pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, newBestBarcodeScore, newBestBarcodeDetails, documentCroppedPrediction, processedCroppedPrediction, pdf417Prediction;
|
|
5667
|
+
var _a;
|
|
5668
|
+
return __generator(this, function (_b) {
|
|
5669
|
+
switch (_b.label) {
|
|
5670
|
+
case 0:
|
|
5671
|
+
pdf417PredictionTime = 0;
|
|
5672
|
+
pdf417PredictionScore = 0;
|
|
5673
|
+
pdf417PredictionThresholdMet = false;
|
|
5674
|
+
if (!prediction.bestDocument || !((_a = prediction.bestPDF417) === null || _a === void 0 ? void 0 : _a.box) || !bestBarcodeCanvas) {
|
|
5675
|
+
return [2 /*return*/, {
|
|
5676
|
+
pdf417PredictionTime: pdf417PredictionTime,
|
|
5677
|
+
pdf417PredictionScore: pdf417PredictionScore,
|
|
5678
|
+
pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
|
|
5679
|
+
newBestBarcodeScore: newBestBarcodeScore,
|
|
5680
|
+
newBestBarcodeDetails: newBestBarcodeDetails
|
|
5681
|
+
}];
|
|
5682
|
+
}
|
|
5683
|
+
/**
|
|
5684
|
+
* Step 1: Crop the full frame to just the document area
|
|
5685
|
+
* This removes background noise and focuses analysis on the document
|
|
5686
|
+
*/
|
|
5687
|
+
cropToDetectedObjectBox(lastPredictionCanvas, prediction.bestDocument.box, croppedDocumentCanvas);
|
|
5688
|
+
return [4 /*yield*/, makeDocumentDetectorPrediction(croppedDocumentCanvas)];
|
|
5689
|
+
case 1:
|
|
5690
|
+
documentCroppedPrediction = _b.sent();
|
|
5691
|
+
if (!documentCroppedPrediction) {
|
|
5692
|
+
// error occurred during prediction (error logged by callee)
|
|
5693
|
+
return [2 /*return*/, {
|
|
5694
|
+
pdf417PredictionTime: pdf417PredictionTime,
|
|
5695
|
+
pdf417PredictionScore: pdf417PredictionScore,
|
|
5696
|
+
pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
|
|
5697
|
+
newBestBarcodeScore: newBestBarcodeScore,
|
|
5698
|
+
newBestBarcodeDetails: newBestBarcodeDetails
|
|
5699
|
+
}];
|
|
5700
|
+
}
|
|
5701
|
+
processedCroppedPrediction = processDocumentDetectorPrediction(documentCroppedPrediction, documentDetectionThresholds);
|
|
5702
|
+
if (processedCroppedPrediction.bestPDF417) {
|
|
5703
|
+
pdf417Prediction = makeBarcodeReadabilityPrediction(croppedDocumentCanvas, processedCroppedPrediction.bestPDF417.box);
|
|
5704
|
+
if (pdf417Prediction) {
|
|
5705
|
+
pdf417PredictionTime = pdf417Prediction.predictionTime;
|
|
5706
|
+
pdf417PredictionScore = pdf417Prediction.score;
|
|
5707
|
+
if (pdf417Prediction.score > currentBestBarcodeScore) {
|
|
5708
|
+
/**
|
|
5709
|
+
* Step 5: Update best barcode
|
|
5710
|
+
*/
|
|
5711
|
+
newBestBarcodeScore = pdf417Prediction.score;
|
|
5712
|
+
newBestBarcodeDetails = {
|
|
5713
|
+
boundingBox: prediction.bestPDF417.box,
|
|
5714
|
+
score: pdf417Prediction.score
|
|
5715
|
+
};
|
|
5716
|
+
if (pdf417PredictionScore >= barcodeReadabilityThreshold) {
|
|
5717
|
+
pdf417PredictionThresholdMet = true;
|
|
5718
|
+
}
|
|
5719
|
+
cropToDetectedObjectBox(croppedDocumentCanvas, processedCroppedPrediction.bestPDF417.box, bestBarcodeCanvas, 16);
|
|
5720
|
+
}
|
|
5721
|
+
}
|
|
5722
|
+
}
|
|
5723
|
+
return [2 /*return*/, {
|
|
5724
|
+
pdf417PredictionTime: pdf417PredictionTime,
|
|
5725
|
+
pdf417PredictionScore: pdf417PredictionScore,
|
|
5726
|
+
pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
|
|
5727
|
+
newBestBarcodeScore: newBestBarcodeScore,
|
|
5728
|
+
newBestBarcodeDetails: newBestBarcodeDetails
|
|
5729
|
+
}];
|
|
5730
|
+
}
|
|
5731
|
+
});
|
|
5732
|
+
});
|
|
5733
|
+
}
|
|
5734
|
+
/**
|
|
5735
|
+
* Calculates the barcode readability threshold for a given document type
|
|
5736
|
+
* @param detectedDocumentType The type of document detected
|
|
5737
|
+
* @param barcodeReadabilityThresholds The threshold configuration object
|
|
5738
|
+
* @returns The appropriate threshold value for the current platform (mobile/desktop)
|
|
5739
|
+
*/
|
|
5740
|
+
function calculateBarcodeReadabilityThreshold(detectedDocumentType, barcodeReadabilityThresholds) {
|
|
5741
|
+
var barcodeReadabilityThresholdSet = detectedDocumentType in barcodeReadabilityThresholds ? barcodeReadabilityThresholds[detectedDocumentType] : undefined;
|
|
5742
|
+
if (barcodeReadabilityThresholdSet) {
|
|
5743
|
+
return onMobile ? barcodeReadabilityThresholdSet.mobile || 0 : barcodeReadabilityThresholdSet.desktop || 0;
|
|
5744
|
+
}
|
|
5745
|
+
return 0;
|
|
5746
|
+
}
|
|
5747
|
+
/**
|
|
5748
|
+
* Hook that calculates the barcode readability threshold for a given document type
|
|
5749
|
+
*/
|
|
5750
|
+
function useBarcodeReadabilityThreshold() {
|
|
5751
|
+
var barcodeReadabilityThresholds = useBarcodeReadabilityModelContext().barcodeReadabilityThresholds;
|
|
5752
|
+
return React.useCallback(function (detectedDocumentType) {
|
|
5753
|
+
return calculateBarcodeReadabilityThreshold(detectedDocumentType, barcodeReadabilityThresholds);
|
|
5754
|
+
}, [barcodeReadabilityThresholds]);
|
|
5755
|
+
}
|
|
5756
|
+
function useBarcodeReadabilityAnalysis() {
|
|
5757
|
+
var _this = this;
|
|
5758
|
+
var documentDetectionThresholds = React.useContext(DocumentDetectionModelContext).documentDetectionThresholds;
|
|
5759
|
+
var makeBarcodeReadabilityPrediction = useBarcodeReadabilityModelContext().makeBarcodeReadabilityPrediction;
|
|
5760
|
+
var getBarcodeReadabilityThreshold = useBarcodeReadabilityThreshold();
|
|
5761
|
+
return React.useCallback(function (prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore) {
|
|
5762
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
5763
|
+
var barcodeReadabilityThreshold;
|
|
5764
|
+
return __generator(this, function (_a) {
|
|
5765
|
+
barcodeReadabilityThreshold = getBarcodeReadabilityThreshold(prediction.detectedDocumentType);
|
|
5766
|
+
return [2 /*return*/, analyzeBarcodeReadability(prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore, documentDetectionThresholds, makeBarcodeReadabilityPrediction, barcodeReadabilityThreshold)];
|
|
5767
|
+
});
|
|
5768
|
+
});
|
|
5769
|
+
}, [documentDetectionThresholds, makeBarcodeReadabilityPrediction, getBarcodeReadabilityThreshold]);
|
|
5770
|
+
}
|
|
5757
5771
|
var defaultIdCaptureThresholds = {
|
|
5758
5772
|
detection: defaultDocumentDetectionThresholds,
|
|
5759
5773
|
focus: defaultFocusThresholds
|
|
@@ -5786,6 +5800,7 @@ var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
|
|
|
5786
5800
|
},
|
|
5787
5801
|
detectionTime: 0,
|
|
5788
5802
|
focusPredictionTime: 0,
|
|
5803
|
+
barcodeReadabilityPredictionTime: 0,
|
|
5789
5804
|
bestFrameDetails: {
|
|
5790
5805
|
current: null
|
|
5791
5806
|
},
|
|
@@ -5795,55 +5810,80 @@ var IdCaptureModelsContext = /*#__PURE__*/React.createContext({
|
|
|
5795
5810
|
resetBestFrame: function resetBestFrame() {
|
|
5796
5811
|
return null;
|
|
5797
5812
|
},
|
|
5813
|
+
bestBarcodeDetails: {
|
|
5814
|
+
current: null
|
|
5815
|
+
},
|
|
5816
|
+
getBestBarcode: function getBestBarcode() {
|
|
5817
|
+
return null;
|
|
5818
|
+
},
|
|
5798
5819
|
requiredDocumentType: 'none',
|
|
5799
5820
|
setRequiredDocumentType: function setRequiredDocumentType() {
|
|
5800
5821
|
return null;
|
|
5801
5822
|
}
|
|
5802
5823
|
});
|
|
5803
5824
|
function IdCaptureModelsProviderInner(_a) {
|
|
5825
|
+
var _b;
|
|
5804
5826
|
var children = _a.children,
|
|
5805
5827
|
onModelError = _a.onModelError,
|
|
5806
|
-
|
|
5807
|
-
allowSinglePageIdCapture =
|
|
5808
|
-
|
|
5809
|
-
|
|
5810
|
-
|
|
5811
|
-
|
|
5812
|
-
|
|
5813
|
-
|
|
5814
|
-
|
|
5815
|
-
|
|
5816
|
-
|
|
5817
|
-
|
|
5818
|
-
|
|
5819
|
-
|
|
5820
|
-
|
|
5821
|
-
|
|
5822
|
-
|
|
5823
|
-
|
|
5824
|
-
|
|
5825
|
-
|
|
5826
|
-
|
|
5827
|
-
|
|
5828
|
-
|
|
5829
|
-
|
|
5830
|
-
|
|
5831
|
-
|
|
5832
|
-
|
|
5833
|
-
|
|
5828
|
+
_c = _a.allowSinglePageIdCapture,
|
|
5829
|
+
allowSinglePageIdCapture = _c === void 0 ? false : _c,
|
|
5830
|
+
_d = _a.enableBarcodeReadabilityModel,
|
|
5831
|
+
enableBarcodeReadabilityModel = _d === void 0 ? true : _d;
|
|
5832
|
+
var _e = React.useContext(DocumentDetectionModelContext),
|
|
5833
|
+
documentDetectionModelState = _e.documentDetectionModelState,
|
|
5834
|
+
documentDetectionModelDownloadProgress = _e.documentDetectionModelDownloadProgress,
|
|
5835
|
+
documentDetectionModelWarmingStartedAt = _e.documentDetectionModelWarmingStartedAt,
|
|
5836
|
+
startDocumentDetection = _e.startDocumentDetection,
|
|
5837
|
+
stopDocumentDetection = _e.stopDocumentDetection,
|
|
5838
|
+
loadDocumentDetectionModel = _e.loadDocumentDetectionModel,
|
|
5839
|
+
lastPredictionCanvas = _e.documentDetectionLastPredictionCanvas,
|
|
5840
|
+
clearDocumentDetectionLastPredictionCanvas = _e.clearDocumentDetectionLastPredictionCanvas,
|
|
5841
|
+
onDocumentDetected = _e.onDocumentDetected,
|
|
5842
|
+
detectionTime = _e.detectionTime,
|
|
5843
|
+
documentDetectionThresholds = _e.documentDetectionThresholds,
|
|
5844
|
+
setDocumentDetectionThresholds = _e.setDocumentDetectionThresholds,
|
|
5845
|
+
documentDetectionBoundaries = _e.documentDetectionBoundaries,
|
|
5846
|
+
setDocumentDetectionBoundaries = _e.setDocumentDetectionBoundaries,
|
|
5847
|
+
documentDetectionModelError = _e.documentDetectionModelError;
|
|
5848
|
+
var _f = React.useContext(FocusModelContext),
|
|
5849
|
+
loadFocusModel = _f.loadFocusModel,
|
|
5850
|
+
focusModelState = _f.focusModelState,
|
|
5851
|
+
focusModelDownloadProgress = _f.focusModelDownloadProgress,
|
|
5852
|
+
focusModelWarmingStartedAt = _f.focusModelWarmingStartedAt,
|
|
5853
|
+
makeFocusPrediction = _f.makeFocusPrediction,
|
|
5854
|
+
focusThresholds = _f.focusThresholds,
|
|
5855
|
+
setFocusThresholds = _f.setFocusThresholds,
|
|
5856
|
+
focusPredictionTime = _f.focusPredictionTime,
|
|
5857
|
+
focusModelError = _f.focusModelError;
|
|
5858
|
+
var _g = useBarcodeReadabilityModelContext(),
|
|
5859
|
+
loadBarcodeReadabilityModel = _g.loadBarcodeReadabilityModel,
|
|
5860
|
+
barcodeReadabilityModelState = _g.barcodeReadabilityModelState,
|
|
5861
|
+
barcodeReadabilityModelDownloadProgress = _g.barcodeReadabilityModelDownloadProgress,
|
|
5862
|
+
barcodeReadabilityModelWarmingStartedAt = _g.barcodeReadabilityModelWarmingStartedAt,
|
|
5863
|
+
makeBarcodeReadabilityPrediction = _g.makeBarcodeReadabilityPrediction,
|
|
5864
|
+
barcodeReadabilityThresholds = _g.barcodeReadabilityThresholds,
|
|
5865
|
+
setBarcodeReadabilityThresholds = _g.setBarcodeReadabilityThresholds,
|
|
5866
|
+
barcodeReadabilityPredictionTime = _g.barcodeReadabilityPredictionTime,
|
|
5867
|
+
barcodeReadabilityModelError = _g.barcodeReadabilityModelError;
|
|
5834
5868
|
var onPredictionHandler = React.useRef();
|
|
5835
5869
|
var bestFrameDetails = React.useRef(null);
|
|
5870
|
+
var bestBarcodeDetails = React.useRef(null);
|
|
5836
5871
|
var bestPredictionCanvas = React.useRef(null);
|
|
5872
|
+
var bestBarcodeCanvas = React.useRef(null);
|
|
5873
|
+
var croppedDocumentCanvas = React.useRef(null);
|
|
5837
5874
|
var bestFocusScore = React.useRef(0);
|
|
5875
|
+
var bestBarcodeScore = React.useRef(0);
|
|
5838
5876
|
var stopDetection = React.useRef(0);
|
|
5839
|
-
var
|
|
5840
|
-
|
|
5841
|
-
|
|
5877
|
+
var analyzeBarcodeReadability = useBarcodeReadabilityAnalysis();
|
|
5878
|
+
var _h = React.useState('none'),
|
|
5879
|
+
requiredDocumentType = _h[0],
|
|
5880
|
+
setRequiredDocumentType = _h[1];
|
|
5842
5881
|
var thresholds = React.useMemo(function () {
|
|
5843
5882
|
return _assign(_assign({}, documentDetectionThresholds), {
|
|
5844
|
-
focus: focusThresholds
|
|
5883
|
+
focus: focusThresholds,
|
|
5884
|
+
barcodeReadability: barcodeReadabilityThresholds
|
|
5845
5885
|
});
|
|
5846
|
-
}, [documentDetectionThresholds, focusThresholds]);
|
|
5886
|
+
}, [documentDetectionThresholds, focusThresholds, barcodeReadabilityThresholds]);
|
|
5847
5887
|
var setThresholds = React.useCallback(function (thresholds) {
|
|
5848
5888
|
if (thresholds.detection) {
|
|
5849
5889
|
setDocumentDetectionThresholds(thresholds.detection);
|
|
@@ -5851,57 +5891,87 @@ function IdCaptureModelsProviderInner(_a) {
|
|
|
5851
5891
|
if (thresholds.focus) {
|
|
5852
5892
|
setFocusThresholds(thresholds.focus);
|
|
5853
5893
|
}
|
|
5854
|
-
|
|
5894
|
+
if (thresholds.barcodeReadability) {
|
|
5895
|
+
setBarcodeReadabilityThresholds(thresholds.barcodeReadability);
|
|
5896
|
+
}
|
|
5897
|
+
}, [setBarcodeReadabilityThresholds, setDocumentDetectionThresholds, setFocusThresholds]);
|
|
5855
5898
|
React.useEffect(function handleDetections() {
|
|
5856
5899
|
var _this = this;
|
|
5857
5900
|
onDocumentDetected(function (prediction) {
|
|
5858
5901
|
return __awaiter(_this, void 0, void 0, function () {
|
|
5859
|
-
var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold;
|
|
5902
|
+
var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, focusPrediction, focusThresholdSet, focusThreshold, barcodeAnalysisResult;
|
|
5860
5903
|
var _a, _b, _c, _d, _e, _f, _g;
|
|
5861
5904
|
return __generator(this, function (_h) {
|
|
5862
|
-
|
|
5863
|
-
|
|
5864
|
-
|
|
5865
|
-
|
|
5866
|
-
|
|
5867
|
-
|
|
5868
|
-
|
|
5869
|
-
|
|
5870
|
-
|
|
5871
|
-
|
|
5872
|
-
|
|
5873
|
-
|
|
5874
|
-
|
|
5875
|
-
|
|
5876
|
-
|
|
5877
|
-
|
|
5878
|
-
|
|
5879
|
-
|
|
5880
|
-
|
|
5881
|
-
|
|
5882
|
-
|
|
5883
|
-
|
|
5884
|
-
|
|
5885
|
-
|
|
5886
|
-
|
|
5887
|
-
|
|
5888
|
-
|
|
5889
|
-
|
|
5890
|
-
|
|
5891
|
-
|
|
5892
|
-
|
|
5905
|
+
switch (_h.label) {
|
|
5906
|
+
case 0:
|
|
5907
|
+
if (!lastPredictionCanvas.current) return [2 /*return*/];
|
|
5908
|
+
stopDetectionAtStart = stopDetection.current;
|
|
5909
|
+
focusPredictionTime = 0, focusScore = 0, focusThresholdMet = false, pdf417PredictionTime = 0, pdf417PredictionScore = 0, pdf417PredictionThresholdMet = false;
|
|
5910
|
+
isSinglePage = prediction.detectedDocumentType === 'singlePage';
|
|
5911
|
+
if (!allowSinglePageIdCapture && isSinglePage) {
|
|
5912
|
+
prediction.detectedDocumentType = 'passport';
|
|
5913
|
+
prediction.passportDetectionScore = prediction.singlePageDetectionScore;
|
|
5914
|
+
prediction.passportDetectionThresholdMet = prediction.singlePageDetectionThresholdMet;
|
|
5915
|
+
prediction.singlePageDetectionScore = 0;
|
|
5916
|
+
prediction.singlePageDetectionThresholdMet = false;
|
|
5917
|
+
}
|
|
5918
|
+
isRequiredDocumentType = requiredDocumentType === 'none' || prediction.detectedDocumentType === requiredDocumentType || ((_a = requiredDocumentType.includes) === null || _a === void 0 ? void 0 : _a.call(requiredDocumentType, prediction.detectedDocumentType)) || allowSinglePageIdCapture && isSinglePage && ((_b = requiredDocumentType.includes) === null || _b === void 0 ? void 0 : _b.call(requiredDocumentType, 'idCardFront'));
|
|
5919
|
+
if (!(isRequiredDocumentType && prediction.detectedDocumentType !== 'none' && prediction.detectionThresholdMet && prediction.documentInBounds && !prediction.documentTooClose && prediction.documentIsStable)) return [3 /*break*/, 2];
|
|
5920
|
+
focusPrediction = makeFocusPrediction(lastPredictionCanvas.current, (_c = prediction.bestDocument) === null || _c === void 0 ? void 0 : _c.box);
|
|
5921
|
+
if (focusPrediction) {
|
|
5922
|
+
focusScore = focusPrediction.score;
|
|
5923
|
+
focusPredictionTime = focusPrediction.predictionTime;
|
|
5924
|
+
}
|
|
5925
|
+
focusThresholdSet = (_d = thresholds.focus) === null || _d === void 0 ? void 0 : _d[prediction.detectedDocumentType];
|
|
5926
|
+
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;
|
|
5927
|
+
focusThresholdMet = focusScore >= focusThreshold;
|
|
5928
|
+
if (!(stopDetectionAtStart === stopDetection.current)) return [3 /*break*/, 2];
|
|
5929
|
+
if (bestFocusScore.current <= focusScore) {
|
|
5930
|
+
bestFocusScore.current = focusScore;
|
|
5931
|
+
drawToCanvas(bestPredictionCanvas.current, lastPredictionCanvas.current);
|
|
5932
|
+
bestFrameDetails.current = {
|
|
5933
|
+
boundingBox: (_f = prediction.bestDocument) === null || _f === void 0 ? void 0 : _f.box,
|
|
5934
|
+
documentType: prediction.detectedDocumentType,
|
|
5935
|
+
detectionScore: prediction.detectionScore,
|
|
5936
|
+
focusScore: focusScore
|
|
5937
|
+
};
|
|
5938
|
+
}
|
|
5939
|
+
if (!(enableBarcodeReadabilityModel && prediction.bestDocument && prediction.bestPDF417 && croppedDocumentCanvas.current)) return [3 /*break*/, 2];
|
|
5940
|
+
return [4 /*yield*/, analyzeBarcodeReadability(prediction, lastPredictionCanvas.current, croppedDocumentCanvas.current, bestBarcodeCanvas.current, bestBarcodeScore.current)];
|
|
5941
|
+
case 1:
|
|
5942
|
+
barcodeAnalysisResult = _h.sent();
|
|
5943
|
+
pdf417PredictionTime = barcodeAnalysisResult.pdf417PredictionTime;
|
|
5944
|
+
pdf417PredictionScore = barcodeAnalysisResult.pdf417PredictionScore;
|
|
5945
|
+
pdf417PredictionThresholdMet = barcodeAnalysisResult.pdf417PredictionThresholdMet;
|
|
5946
|
+
if (barcodeAnalysisResult.newBestBarcodeScore) {
|
|
5947
|
+
bestBarcodeScore.current = barcodeAnalysisResult.newBestBarcodeScore;
|
|
5948
|
+
}
|
|
5949
|
+
if (barcodeAnalysisResult.newBestBarcodeDetails) {
|
|
5950
|
+
bestBarcodeDetails.current = barcodeAnalysisResult.newBestBarcodeDetails;
|
|
5951
|
+
}
|
|
5952
|
+
_h.label = 2;
|
|
5953
|
+
case 2:
|
|
5954
|
+
/**
|
|
5955
|
+
* @note
|
|
5956
|
+
* This should ALWAYS be called.
|
|
5957
|
+
* Do not return early from this function unless
|
|
5958
|
+
* lastPredictionCanvas.current is not set
|
|
5959
|
+
*/
|
|
5960
|
+
(_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
|
|
5961
|
+
focusScore: focusScore,
|
|
5962
|
+
focusPredictionTime: focusPredictionTime,
|
|
5963
|
+
focusThresholdMet: focusThresholdMet,
|
|
5964
|
+
pdf417PredictionTime: pdf417PredictionTime,
|
|
5965
|
+
pdf417PredictionScore: pdf417PredictionScore,
|
|
5966
|
+
pdf417PredictionThresholdMet: pdf417PredictionThresholdMet
|
|
5967
|
+
}));
|
|
5968
|
+
return [2 /*return*/];
|
|
5893
5969
|
}
|
|
5894
|
-
(_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
|
|
5895
|
-
focusScore: focusScore,
|
|
5896
|
-
focusPredictionTime: focusPredictionTime,
|
|
5897
|
-
focusThresholdMet: focusThresholdMet
|
|
5898
|
-
}));
|
|
5899
|
-
return [2 /*return*/];
|
|
5900
5970
|
});
|
|
5901
5971
|
});
|
|
5902
5972
|
});
|
|
5903
|
-
}, [allowSinglePageIdCapture, lastPredictionCanvas, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
|
|
5904
|
-
var modelError = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError;
|
|
5973
|
+
}, [allowSinglePageIdCapture, analyzeBarcodeReadability, barcodeReadabilityThresholds, enableBarcodeReadabilityModel, lastPredictionCanvas, makeBarcodeReadabilityPrediction, makeFocusPrediction, onDocumentDetected, requiredDocumentType, thresholds.focus]);
|
|
5974
|
+
var modelError = (_b = documentDetectionModelError !== null && documentDetectionModelError !== void 0 ? documentDetectionModelError : focusModelError) !== null && _b !== void 0 ? _b : barcodeReadabilityModelError;
|
|
5905
5975
|
React.useEffect(function handleModelErrors() {
|
|
5906
5976
|
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
5907
5977
|
}, [modelError, onModelError]);
|
|
@@ -5914,9 +5984,15 @@ function IdCaptureModelsProviderInner(_a) {
|
|
|
5914
5984
|
canvas: bestPredictionCanvas.current
|
|
5915
5985
|
});
|
|
5916
5986
|
}, []);
|
|
5917
|
-
var
|
|
5918
|
-
|
|
5919
|
-
|
|
5987
|
+
var getBestBarcode = React.useCallback(function () {
|
|
5988
|
+
if (!bestBarcodeDetails.current || !bestBarcodeCanvas.current) return null;
|
|
5989
|
+
return _assign(_assign({}, bestBarcodeDetails.current), {
|
|
5990
|
+
canvas: bestBarcodeCanvas.current
|
|
5991
|
+
});
|
|
5992
|
+
}, []);
|
|
5993
|
+
var _j = React.useState(0),
|
|
5994
|
+
canvasKey = _j[0],
|
|
5995
|
+
setCanvasKey = _j[1];
|
|
5920
5996
|
var resetBestFrame = React.useCallback(function () {
|
|
5921
5997
|
stopDetection.current += 1;
|
|
5922
5998
|
setCanvasKey(function (n) {
|
|
@@ -5932,16 +6008,45 @@ function IdCaptureModelsProviderInner(_a) {
|
|
|
5932
6008
|
var load = React.useCallback(function () {
|
|
5933
6009
|
loadDocumentDetectionModel();
|
|
5934
6010
|
loadFocusModel();
|
|
5935
|
-
|
|
5936
|
-
|
|
5937
|
-
var
|
|
5938
|
-
|
|
5939
|
-
|
|
5940
|
-
|
|
6011
|
+
if (enableBarcodeReadabilityModel) loadBarcodeReadabilityModel();
|
|
6012
|
+
}, [enableBarcodeReadabilityModel, loadBarcodeReadabilityModel, loadDocumentDetectionModel, loadFocusModel]);
|
|
6013
|
+
var _k = React.useMemo(function () {
|
|
6014
|
+
var modelStates = [documentDetectionModelState, focusModelState];
|
|
6015
|
+
var modelWarmingStartedAts = [documentDetectionModelWarmingStartedAt, focusModelWarmingStartedAt];
|
|
6016
|
+
var modelDownloadProgresses = [documentDetectionModelDownloadProgress, focusModelDownloadProgress];
|
|
6017
|
+
if (enableBarcodeReadabilityModel) {
|
|
6018
|
+
modelStates.push(barcodeReadabilityModelState);
|
|
6019
|
+
modelWarmingStartedAts.push(barcodeReadabilityModelWarmingStartedAt);
|
|
6020
|
+
modelDownloadProgresses.push(barcodeReadabilityModelDownloadProgress);
|
|
6021
|
+
}
|
|
6022
|
+
var ready = modelStates.every(function (state) {
|
|
6023
|
+
return state === 'ready';
|
|
6024
|
+
});
|
|
6025
|
+
return {
|
|
6026
|
+
ready: ready,
|
|
6027
|
+
modelLoadState: ready ? 'ready' : modelStates.some(function (state) {
|
|
6028
|
+
return state === 'warming';
|
|
6029
|
+
}) ? 'warming' : modelStates.some(function (state) {
|
|
6030
|
+
return state === 'downloading';
|
|
6031
|
+
}) ? 'downloading' : 'not-started',
|
|
6032
|
+
modelWarmingStartedAt: modelWarmingStartedAts.every(function (v) {
|
|
6033
|
+
return v === null;
|
|
6034
|
+
}) ? null : Math.min.apply(Math, modelWarmingStartedAts.filter(function (v) {
|
|
6035
|
+
return v !== null;
|
|
6036
|
+
})),
|
|
6037
|
+
modelDownloadProgress: modelDownloadProgresses.reduce(function (a, b) {
|
|
6038
|
+
return a + b;
|
|
6039
|
+
}, 0) / modelDownloadProgresses.length
|
|
6040
|
+
};
|
|
6041
|
+
}, [barcodeReadabilityModelDownloadProgress, barcodeReadabilityModelState, barcodeReadabilityModelWarmingStartedAt, documentDetectionModelDownloadProgress, documentDetectionModelState, documentDetectionModelWarmingStartedAt, enableBarcodeReadabilityModel, focusModelDownloadProgress, focusModelState, focusModelWarmingStartedAt]),
|
|
6042
|
+
ready = _k.ready,
|
|
6043
|
+
modelLoadState = _k.modelLoadState,
|
|
6044
|
+
modelWarmingStartedAt = _k.modelWarmingStartedAt,
|
|
6045
|
+
modelDownloadProgress = _k.modelDownloadProgress;
|
|
5941
6046
|
var value = React.useMemo(function () {
|
|
5942
6047
|
return {
|
|
5943
6048
|
ready: ready,
|
|
5944
|
-
modelDownloadProgress:
|
|
6049
|
+
modelDownloadProgress: modelDownloadProgress,
|
|
5945
6050
|
modelLoadState: modelLoadState,
|
|
5946
6051
|
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
5947
6052
|
modelError: modelError,
|
|
@@ -5955,24 +6060,35 @@ function IdCaptureModelsProviderInner(_a) {
|
|
|
5955
6060
|
onPredictionMade: onPredictionMade,
|
|
5956
6061
|
detectionTime: detectionTime,
|
|
5957
6062
|
focusPredictionTime: focusPredictionTime,
|
|
6063
|
+
barcodeReadabilityPredictionTime: barcodeReadabilityPredictionTime,
|
|
5958
6064
|
getBestFrame: getBestFrame,
|
|
5959
6065
|
resetBestFrame: resetBestFrame,
|
|
5960
6066
|
bestFrameDetails: bestFrameDetails,
|
|
6067
|
+
bestBarcodeDetails: bestBarcodeDetails,
|
|
6068
|
+
getBestBarcode: getBestBarcode,
|
|
5961
6069
|
requiredDocumentType: requiredDocumentType,
|
|
5962
6070
|
setRequiredDocumentType: setRequiredDocumentType
|
|
5963
6071
|
};
|
|
5964
|
-
}, [
|
|
6072
|
+
}, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, requiredDocumentType]);
|
|
5965
6073
|
return /*#__PURE__*/React__namespace.default.createElement(IdCaptureModelsContext.Provider, {
|
|
5966
6074
|
value: value
|
|
5967
|
-
}, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
5968
|
-
key: canvasKey,
|
|
6075
|
+
}, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
6076
|
+
key: "bf-".concat(canvasKey),
|
|
5969
6077
|
ref: bestPredictionCanvas
|
|
5970
|
-
}),
|
|
6078
|
+
}), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
6079
|
+
key: "bb-".concat(canvasKey),
|
|
6080
|
+
ref: bestBarcodeCanvas
|
|
6081
|
+
}), /*#__PURE__*/React__namespace.default.createElement(InvisibleCanvas, {
|
|
6082
|
+
key: "cd-".concat(canvasKey),
|
|
6083
|
+
ref: croppedDocumentCanvas
|
|
6084
|
+
})), children);
|
|
5971
6085
|
}
|
|
5972
6086
|
function IdCaptureModelsProvider(_a) {
|
|
5973
6087
|
var children = _a.children,
|
|
5974
6088
|
props = __rest(_a, ["children"]);
|
|
5975
|
-
return /*#__PURE__*/React__namespace.default.createElement(DocumentDetectionModelProvider, _assign({}, props), /*#__PURE__*/React__namespace.default.createElement(FocusModelProvider, _assign({}, props), /*#__PURE__*/React__namespace.default.createElement(
|
|
6089
|
+
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, {
|
|
6090
|
+
shouldLoadModels: props.enableBarcodeReadabilityModel
|
|
6091
|
+
}), /*#__PURE__*/React__namespace.default.createElement(IdCaptureModelsProviderInner, _assign({}, props), children))));
|
|
5976
6092
|
}
|
|
5977
6093
|
function useIdCaptureModelsContext() {
|
|
5978
6094
|
var context = React.useContext(IdCaptureModelsContext);
|
|
@@ -5982,7 +6098,7 @@ function useIdCaptureModelsContext() {
|
|
|
5982
6098
|
return context;
|
|
5983
6099
|
}
|
|
5984
6100
|
|
|
5985
|
-
var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
|
|
6101
|
+
var CapturedDocumentTypeValues = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'selfie', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage', 'idBarcodeImage'];
|
|
5986
6102
|
|
|
5987
6103
|
var acceptedDocumentTypesForIdCaptureRequirementOption = {
|
|
5988
6104
|
idCardFront: ['idCardFront'],
|
|
@@ -6068,6 +6184,7 @@ var initialState$5 = {
|
|
|
6068
6184
|
capturing: false,
|
|
6069
6185
|
captureFailed: false,
|
|
6070
6186
|
imageUrl: null,
|
|
6187
|
+
idBarcodeImage: null,
|
|
6071
6188
|
captureState: 'initializing',
|
|
6072
6189
|
capturedDocuments: {},
|
|
6073
6190
|
captureRequirement: 'idCardOrPassport',
|
|
@@ -6347,6 +6464,17 @@ var _reducer = function reducer(state, action) {
|
|
|
6347
6464
|
}
|
|
6348
6465
|
return newState;
|
|
6349
6466
|
}
|
|
6467
|
+
case 'barcodeCaptured':
|
|
6468
|
+
return _reducer(state, {
|
|
6469
|
+
type: 'documentCaptured',
|
|
6470
|
+
payload: {
|
|
6471
|
+
imageData: action.payload.imageUrl,
|
|
6472
|
+
documentType: 'idBarcodeImage',
|
|
6473
|
+
width: 0,
|
|
6474
|
+
height: 0,
|
|
6475
|
+
barcodeReadabilityScore: action.payload.barcodeReadabilityScore
|
|
6476
|
+
}
|
|
6477
|
+
});
|
|
6350
6478
|
case 'flipRequestCompleted':
|
|
6351
6479
|
return _assign(_assign({}, state), {
|
|
6352
6480
|
captureState: 'capturing',
|
|
@@ -6838,12 +6966,13 @@ var IdCapture = function IdCapture(_a) {
|
|
|
6838
6966
|
height = _q === void 0 ? 1 : _q;
|
|
6839
6967
|
var state = useIdCaptureStore();
|
|
6840
6968
|
var isRearFacing = useCameraStore().isRearFacing;
|
|
6841
|
-
var _r =
|
|
6969
|
+
var _r = useIdCaptureModelsContext(),
|
|
6842
6970
|
modelsReady = _r.ready,
|
|
6843
6971
|
setThresholds = _r.setThresholds,
|
|
6844
6972
|
detectionTime = _r.detectionTime,
|
|
6845
6973
|
focusPredictionTime = _r.focusPredictionTime,
|
|
6846
|
-
getBestFrame = _r.getBestFrame
|
|
6974
|
+
getBestFrame = _r.getBestFrame,
|
|
6975
|
+
getBestBarcode = _r.getBestBarcode;
|
|
6847
6976
|
React.useEffect(function () {
|
|
6848
6977
|
return dispatchIdCaptureAction({
|
|
6849
6978
|
type: 'captureInitialized'
|
|
@@ -6882,6 +7011,16 @@ var IdCapture = function IdCapture(_a) {
|
|
|
6882
7011
|
});
|
|
6883
7012
|
return;
|
|
6884
7013
|
}
|
|
7014
|
+
var bestBarcode = getBestBarcode();
|
|
7015
|
+
if (bestBarcode) {
|
|
7016
|
+
dispatchIdCaptureAction({
|
|
7017
|
+
type: 'barcodeCaptured',
|
|
7018
|
+
payload: {
|
|
7019
|
+
imageUrl: bestBarcode.canvas.toDataURL('image/jpeg', 0.95),
|
|
7020
|
+
barcodeReadabilityScore: bestBarcode.score
|
|
7021
|
+
}
|
|
7022
|
+
});
|
|
7023
|
+
}
|
|
6885
7024
|
var canvas = bestFrame.canvas,
|
|
6886
7025
|
documentType = bestFrame.documentType,
|
|
6887
7026
|
boundingBox = bestFrame.boundingBox,
|
|
@@ -6898,21 +7037,22 @@ var IdCapture = function IdCapture(_a) {
|
|
|
6898
7037
|
});
|
|
6899
7038
|
var capturedDocumentType = documentType;
|
|
6900
7039
|
setTimeout(function () {
|
|
6901
|
-
var _a;
|
|
6902
|
-
var captureTime =
|
|
7040
|
+
var _a, _b;
|
|
7041
|
+
var captureTime = performance.now() - ((_a = state.captureStartedAt) !== null && _a !== void 0 ? _a : new Date()).getTime();
|
|
6903
7042
|
var metadata = {
|
|
6904
7043
|
autoCapture: 'Y',
|
|
6905
7044
|
captureTime: captureTime,
|
|
6906
7045
|
boundingBox: boundingBox,
|
|
6907
7046
|
bestDetectionScore: detectionScore,
|
|
6908
|
-
bestFocusScore: focusScore
|
|
7047
|
+
bestFocusScore: focusScore,
|
|
7048
|
+
bestBarcodeScore: (_b = bestBarcode === null || bestBarcode === void 0 ? void 0 : bestBarcode.score) !== null && _b !== void 0 ? _b : 0
|
|
6909
7049
|
};
|
|
6910
7050
|
onCapture === null || onCapture === void 0 ? void 0 : onCapture(imageUrl, width, height, capturedDocumentType, metadata);
|
|
6911
7051
|
dispatchIdCaptureAction({
|
|
6912
7052
|
type: 'captured'
|
|
6913
7053
|
});
|
|
6914
7054
|
}, 0);
|
|
6915
|
-
}, [getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
|
|
7055
|
+
}, [getBestBarcode, getBestFrame, onCapture, shouldCapture, state.captureStartedAt, state.requestedDocumentType]);
|
|
6916
7056
|
var theme = styled.useTheme();
|
|
6917
7057
|
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');
|
|
6918
7058
|
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');
|
|
@@ -7712,7 +7852,7 @@ var IdCaptureLoadingOverlayDefault = function IdCaptureLoadingOverlayDefault(_a)
|
|
|
7712
7852
|
};
|
|
7713
7853
|
}, [ready]);
|
|
7714
7854
|
var imageRef = React.useRef(null);
|
|
7715
|
-
var timeSinceWarmingStarted = modelWarmingStartedAt ?
|
|
7855
|
+
var timeSinceWarmingStarted = modelWarmingStartedAt ? performance.now() - modelWarmingStartedAt : 0;
|
|
7716
7856
|
var warmingProgress = timeSinceWarmingStarted / 5000.0;
|
|
7717
7857
|
var modelLoadProgress = modelsReady ? 100 : modelDownloadProgress * 0.5 + warmingProgress * 49.0;
|
|
7718
7858
|
useLoadProgressHooks({
|
|
@@ -8050,7 +8190,7 @@ var Card = styled__default.default.div(templateObject_1$D || (templateObject_1$D
|
|
|
8050
8190
|
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"])));
|
|
8051
8191
|
var templateObject_1$D, templateObject_2$y;
|
|
8052
8192
|
|
|
8053
|
-
var imageDisplayOrder = ['idCardFront', 'idCardBack', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
|
|
8193
|
+
var imageDisplayOrder = ['idCardFront', 'idCardBack', 'idBarcodeImage', 'passport', 'singlePage', 'idFrontIrImage', 'idBackIrImage', 'idFrontUvImage', 'idBackUvImage'];
|
|
8054
8194
|
var IdCaptureSuccess = function IdCaptureSuccess(_a) {
|
|
8055
8195
|
var capturedDocuments = _a.capturedDocuments,
|
|
8056
8196
|
onSubmitClick = _a.onSubmitClick,
|
|
@@ -8092,7 +8232,7 @@ var IdCaptureSuccess = function IdCaptureSuccess(_a) {
|
|
|
8092
8232
|
image: doc,
|
|
8093
8233
|
className: classNames.image,
|
|
8094
8234
|
alt: doc.documentType
|
|
8095
|
-
}), 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)))));
|
|
8235
|
+
}), 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)))));
|
|
8096
8236
|
}))), /*#__PURE__*/React__namespace.default.createElement(ButtonsColumn, {
|
|
8097
8237
|
className: classNames.buttonsRow
|
|
8098
8238
|
}, /*#__PURE__*/React__namespace.default.createElement(WideButton, {
|
|
@@ -10714,7 +10854,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
|
|
|
10714
10854
|
var _6 = React.useState(false),
|
|
10715
10855
|
overlayDismissed = _6[0],
|
|
10716
10856
|
setOverlayDismissed = _6[1];
|
|
10717
|
-
var _7 =
|
|
10857
|
+
var _7 = useSubmissionContext(),
|
|
10718
10858
|
submissionStatus = _7.submissionStatus,
|
|
10719
10859
|
setIdFrontImage = _7.setIdFrontImage,
|
|
10720
10860
|
setIdBackImage = _7.setIdBackImage,
|
|
@@ -10723,6 +10863,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
|
|
|
10723
10863
|
setIdBackIrImage = _7.setIdBackIrImage,
|
|
10724
10864
|
setIdFrontUvImage = _7.setIdFrontUvImage,
|
|
10725
10865
|
setIdBackUvImage = _7.setIdBackUvImage,
|
|
10866
|
+
setIdBarcodeImage = _7.setIdBarcodeImage,
|
|
10726
10867
|
logIdFrontCaptureAttempt = _7.logIdFrontCaptureAttempt,
|
|
10727
10868
|
logIdBackCaptureAttempt = _7.logIdBackCaptureAttempt;
|
|
10728
10869
|
var _8 = useIdCaptureModelsContext(),
|
|
@@ -10823,7 +10964,7 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
|
|
|
10823
10964
|
});
|
|
10824
10965
|
}, [logCaptureMetadata, onDocumentCaptured]);
|
|
10825
10966
|
var onSubmitClick = React.useCallback(function () {
|
|
10826
|
-
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
10967
|
+
var _a, _b, _c, _d, _e, _f, _g, _h, _j;
|
|
10827
10968
|
var docs = state.capturedDocuments;
|
|
10828
10969
|
var submission = {
|
|
10829
10970
|
idFrontImage: maybeDataUrlToBase64Sync((_a = docs.idCardFront) === null || _a === void 0 ? void 0 : _a.imageData),
|
|
@@ -10833,7 +10974,8 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
|
|
|
10833
10974
|
idFrontIrImage: maybeDataUrlToBase64Sync((_e = docs.idFrontIrImage) === null || _e === void 0 ? void 0 : _e.imageData),
|
|
10834
10975
|
idBackIrImage: maybeDataUrlToBase64Sync((_f = docs.idBackIrImage) === null || _f === void 0 ? void 0 : _f.imageData),
|
|
10835
10976
|
idFrontUvImage: maybeDataUrlToBase64Sync((_g = docs.idFrontUvImage) === null || _g === void 0 ? void 0 : _g.imageData),
|
|
10836
|
-
idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData)
|
|
10977
|
+
idBackUvImage: maybeDataUrlToBase64Sync((_h = docs.idBackUvImage) === null || _h === void 0 ? void 0 : _h.imageData),
|
|
10978
|
+
idBarcodeImage: maybeDataUrlToBase64Sync((_j = docs.idBarcodeImage) === null || _j === void 0 ? void 0 : _j.imageData)
|
|
10837
10979
|
};
|
|
10838
10980
|
if (submission.idFrontImage) setIdFrontImage(submission.idFrontImage);
|
|
10839
10981
|
if (submission.idBackImage) setIdBackImage(submission.idBackImage);
|
|
@@ -10843,11 +10985,12 @@ var IdCaptureWizard = function IdCaptureWizard(_a) {
|
|
|
10843
10985
|
if (submission.idBackIrImage) setIdBackIrImage(submission.idBackIrImage);
|
|
10844
10986
|
if (submission.idFrontUvImage) setIdFrontUvImage(submission.idFrontUvImage);
|
|
10845
10987
|
if (submission.idBackUvImage) setIdBackUvImage(submission.idBackUvImage);
|
|
10988
|
+
if (submission.idBarcodeImage) setIdBarcodeImage(submission.idBarcodeImage);
|
|
10846
10989
|
if (releaseCameraAccessOnExit) releaseCameraAccess();
|
|
10847
10990
|
setTimeout(function () {
|
|
10848
10991
|
return onSuccess === null || onSuccess === void 0 ? void 0 : onSuccess(submission);
|
|
10849
10992
|
}, 0);
|
|
10850
|
-
}, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
|
|
10993
|
+
}, [onSuccess, releaseCameraAccess, releaseCameraAccessOnExit, setIdBarcodeImage, setIdBackImage, setIdBackIrImage, setIdBackUvImage, setIdFrontImage, setIdFrontIrImage, setIdFrontUvImage, setPassportImage, state.capturedDocuments]);
|
|
10851
10994
|
var showSuccessScreen = useShowSuccessScreen(skipSuccessScreen, state.captureState === 'complete', onSubmitClick);
|
|
10852
10995
|
var onRetryClick = React.useCallback(function () {
|
|
10853
10996
|
return dispatchIdCaptureAction({
|
|
@@ -11656,40 +11799,378 @@ function SelfieCaptureAnimatedMaskWithStatus(_a) {
|
|
|
11656
11799
|
});
|
|
11657
11800
|
}, 250);
|
|
11658
11801
|
return function () {
|
|
11659
|
-
clearInterval(interval);
|
|
11802
|
+
clearInterval(interval);
|
|
11803
|
+
};
|
|
11804
|
+
}, [status]);
|
|
11805
|
+
return /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMask, _assign({}, props, {
|
|
11806
|
+
frame: frame,
|
|
11807
|
+
status: status
|
|
11808
|
+
}));
|
|
11809
|
+
}
|
|
11810
|
+
var templateObject_1$o, templateObject_2$m, templateObject_3$g;
|
|
11811
|
+
|
|
11812
|
+
var FaceCaptureGuideContainer = styled__default.default.div(templateObject_1$n || (templateObject_1$n = __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"])));
|
|
11813
|
+
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"])));
|
|
11814
|
+
var FaceCaptureGuideOverlay = function FaceCaptureGuideOverlay(_a) {
|
|
11815
|
+
var _b = _a.classNames,
|
|
11816
|
+
classNames = _b === void 0 ? {} : _b,
|
|
11817
|
+
_c = _a.status,
|
|
11818
|
+
status = _c === void 0 ? 'ready' : _c,
|
|
11819
|
+
_d = _a.borderWidth,
|
|
11820
|
+
borderWidth = _d === void 0 ? 5 : _d,
|
|
11821
|
+
_e = _a.borderColor,
|
|
11822
|
+
borderColor = _e === void 0 ? 'white' : _e,
|
|
11823
|
+
_f = _a.borderOpacity,
|
|
11824
|
+
borderOpacity = _f === void 0 ? 0.8 : _f;
|
|
11825
|
+
return /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideContainer, {
|
|
11826
|
+
className: classNames.container
|
|
11827
|
+
}, /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideInner, null, /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMaskWithStatus, {
|
|
11828
|
+
status: status,
|
|
11829
|
+
borderColor: borderColor,
|
|
11830
|
+
borderWidth: borderWidth,
|
|
11831
|
+
borderOpacity: borderOpacity,
|
|
11832
|
+
verticalAlign: "center"
|
|
11833
|
+
})));
|
|
11834
|
+
};
|
|
11835
|
+
var templateObject_1$n, templateObject_2$l;
|
|
11836
|
+
|
|
11837
|
+
var defaultSelfieCaptureModelLoadTimeoutMs = 45000;
|
|
11838
|
+
var detector = null;
|
|
11839
|
+
var detectorSettings = null;
|
|
11840
|
+
function loadFaceDetector() {
|
|
11841
|
+
return __awaiter(this, arguments, void 0, function (modelAssetPath) {
|
|
11842
|
+
var _a, _b;
|
|
11843
|
+
if (modelAssetPath === void 0) {
|
|
11844
|
+
modelAssetPath = defaultFaceDetectorModelPath;
|
|
11845
|
+
}
|
|
11846
|
+
return __generator(this, function (_c) {
|
|
11847
|
+
switch (_c.label) {
|
|
11848
|
+
case 0:
|
|
11849
|
+
if (detector && (detectorSettings === null || detectorSettings === void 0 ? void 0 : detectorSettings.modelAssetPath) === modelAssetPath) return [2 /*return*/, detector];
|
|
11850
|
+
closeFaceDetector();
|
|
11851
|
+
return [4 /*yield*/, preloadFaceDetectorDependencies()];
|
|
11852
|
+
case 1:
|
|
11853
|
+
_c.sent();
|
|
11854
|
+
if (modelCapabilities.delegate === 'NONE') {
|
|
11855
|
+
throw new Error('No available delegate for face detector.');
|
|
11856
|
+
}
|
|
11857
|
+
_b = (_a = tasksVision.FaceDetector).createFromOptions;
|
|
11858
|
+
return [4 /*yield*/, tasksVision.FilesetResolver.forVisionTasks(visionTasksBasePath)];
|
|
11859
|
+
case 2:
|
|
11860
|
+
return [4 /*yield*/, _b.apply(_a, [_c.sent(), {
|
|
11861
|
+
// canvas: document.createElement('canvas'),
|
|
11862
|
+
baseOptions: {
|
|
11863
|
+
modelAssetPath: modelAssetPath,
|
|
11864
|
+
delegate: modelCapabilities.delegate
|
|
11865
|
+
},
|
|
11866
|
+
runningMode: 'VIDEO'
|
|
11867
|
+
}])];
|
|
11868
|
+
case 3:
|
|
11869
|
+
detector = _c.sent();
|
|
11870
|
+
detectorSettings = {
|
|
11871
|
+
modelAssetPath: modelAssetPath
|
|
11872
|
+
};
|
|
11873
|
+
return [2 /*return*/, detector];
|
|
11874
|
+
}
|
|
11875
|
+
});
|
|
11876
|
+
});
|
|
11877
|
+
}
|
|
11878
|
+
function closeFaceDetector() {
|
|
11879
|
+
detector === null || detector === void 0 ? void 0 : detector.close();
|
|
11880
|
+
detector = null;
|
|
11881
|
+
detectorSettings = null;
|
|
11882
|
+
}
|
|
11883
|
+
function useLoadFaceDetector(_a) {
|
|
11884
|
+
var onModelError = _a.onModelError,
|
|
11885
|
+
_b = _a.modelLoadTimeoutMs,
|
|
11886
|
+
modelLoadTimeoutMs = _b === void 0 ? defaultSelfieCaptureModelLoadTimeoutMs : _b,
|
|
11887
|
+
videoRef = _a.videoRef;
|
|
11888
|
+
var _c = React.useState('not-started'),
|
|
11889
|
+
modelLoadState = _c[0],
|
|
11890
|
+
setModelLoadState = _c[1];
|
|
11891
|
+
var _d = React.useState(0),
|
|
11892
|
+
modelDownloadProgress = _d[0],
|
|
11893
|
+
setModelDownloadProgress = _d[1];
|
|
11894
|
+
var _e = React.useState(null),
|
|
11895
|
+
modelWarmingStartedAt = _e[0],
|
|
11896
|
+
setModelWarmingStartedAt = _e[1];
|
|
11897
|
+
var _f = React.useState(null),
|
|
11898
|
+
modelError = _f[0],
|
|
11899
|
+
setModelError = _f[1];
|
|
11900
|
+
React.useEffect(function loadModel() {
|
|
11901
|
+
var _this = this;
|
|
11902
|
+
setModelLoadState('downloading');
|
|
11903
|
+
setModelWarmingStartedAt(null);
|
|
11904
|
+
var modelLoadTimeout = setTimeout(function () {
|
|
11905
|
+
setModelError(new Error('Model loading time limit exceeded.'));
|
|
11906
|
+
}, modelLoadTimeoutMs);
|
|
11907
|
+
function handleDownloadProgress(event) {
|
|
11908
|
+
setModelDownloadProgress(progressToPercentage(event.detail));
|
|
11909
|
+
}
|
|
11910
|
+
document.addEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
|
|
11911
|
+
var cancelVideoReady = function cancelVideoReady() {};
|
|
11912
|
+
loadFaceDetector().then(function (model) {
|
|
11913
|
+
return __awaiter(_this, void 0, void 0, function () {
|
|
11914
|
+
var _a, videoReady, cancel, cancelled;
|
|
11915
|
+
return __generator(this, function (_b) {
|
|
11916
|
+
switch (_b.label) {
|
|
11917
|
+
case 0:
|
|
11918
|
+
setModelDownloadProgress(100);
|
|
11919
|
+
clearTimeout(modelLoadTimeout);
|
|
11920
|
+
setModelLoadState('warming');
|
|
11921
|
+
setModelWarmingStartedAt(performance.now());
|
|
11922
|
+
return [4 /*yield*/, testFaceDetectionAgainstKnownImage(model)];
|
|
11923
|
+
case 1:
|
|
11924
|
+
_b.sent();
|
|
11925
|
+
_a = waitForVideoReady(videoRef), videoReady = _a[0], cancel = _a[1];
|
|
11926
|
+
cancelled = false;
|
|
11927
|
+
cancelVideoReady = function cancelVideoReady() {
|
|
11928
|
+
cancelled = true;
|
|
11929
|
+
cancel();
|
|
11930
|
+
};
|
|
11931
|
+
return [4 /*yield*/, videoReady];
|
|
11932
|
+
case 2:
|
|
11933
|
+
_b.sent();
|
|
11934
|
+
if (cancelled) return [2 /*return*/];
|
|
11935
|
+
model.detectForVideo(videoRef.current, performance.now());
|
|
11936
|
+
setModelLoadState('ready');
|
|
11937
|
+
return [2 /*return*/];
|
|
11938
|
+
}
|
|
11939
|
+
});
|
|
11940
|
+
});
|
|
11941
|
+
})["catch"](function (e) {
|
|
11942
|
+
setModelError(e);
|
|
11943
|
+
setModelLoadState('error');
|
|
11944
|
+
})["finally"](function () {
|
|
11945
|
+
clearTimeout(modelLoadTimeout);
|
|
11946
|
+
});
|
|
11947
|
+
return function () {
|
|
11948
|
+
log('unloading face detection model');
|
|
11949
|
+
cancelVideoReady();
|
|
11950
|
+
closeFaceDetector();
|
|
11951
|
+
clearTimeout(modelLoadTimeout);
|
|
11952
|
+
document.removeEventListener('idmission.preloadProgress.faceDetection', handleDownloadProgress);
|
|
11660
11953
|
};
|
|
11661
|
-
}, [
|
|
11662
|
-
|
|
11663
|
-
|
|
11664
|
-
|
|
11665
|
-
|
|
11954
|
+
}, [modelLoadTimeoutMs, videoRef]);
|
|
11955
|
+
React.useEffect(function handleModelError() {
|
|
11956
|
+
if (modelError) onModelError === null || onModelError === void 0 ? void 0 : onModelError(modelError);
|
|
11957
|
+
}, [modelError, onModelError]);
|
|
11958
|
+
return React.useMemo(function () {
|
|
11959
|
+
return {
|
|
11960
|
+
ready: modelLoadState === 'ready',
|
|
11961
|
+
modelLoadState: modelLoadState,
|
|
11962
|
+
modelDownloadProgress: modelDownloadProgress,
|
|
11963
|
+
modelWarmingStartedAt: modelWarmingStartedAt,
|
|
11964
|
+
modelError: modelError
|
|
11965
|
+
};
|
|
11966
|
+
}, [modelLoadState, modelDownloadProgress, modelWarmingStartedAt, modelError]);
|
|
11967
|
+
}
|
|
11968
|
+
var lastFaceDetectionAt = 0;
|
|
11969
|
+
var lastFaceDetectionTime = 0;
|
|
11970
|
+
function setLastFaceDetectionAt(time) {
|
|
11971
|
+
lastFaceDetectionTime = time - lastFaceDetectionAt;
|
|
11972
|
+
lastFaceDetectionAt = time;
|
|
11973
|
+
}
|
|
11974
|
+
var framesNeededSamples = [];
|
|
11975
|
+
function trackFramesNeeded(value, bufferLength) {
|
|
11976
|
+
if (bufferLength === void 0) {
|
|
11977
|
+
bufferLength = 25;
|
|
11978
|
+
}
|
|
11979
|
+
framesNeededSamples.unshift(value);
|
|
11980
|
+
if (framesNeededSamples.length > bufferLength) framesNeededSamples.length = bufferLength;
|
|
11981
|
+
}
|
|
11982
|
+
var lastNFaces = [];
|
|
11983
|
+
var lastNFacePairs = [];
|
|
11984
|
+
var lastNNoses = [];
|
|
11985
|
+
var lastNNosePairs = [];
|
|
11986
|
+
function trackFace(face, framesNeeded, frameWidth, frameHeight) {
|
|
11987
|
+
if (framesNeeded === void 0) {
|
|
11988
|
+
framesNeeded = 12;
|
|
11989
|
+
}
|
|
11990
|
+
var nose = face.keypoints[2];
|
|
11991
|
+
if (!nose) return;
|
|
11992
|
+
lastNFaces.unshift(face);
|
|
11993
|
+
lastNNoses.unshift(nose);
|
|
11994
|
+
if (lastNFaces.length > framesNeeded) lastNFaces.length = framesNeeded;
|
|
11995
|
+
if (lastNNoses.length > framesNeeded) lastNNoses.length = framesNeeded;
|
|
11996
|
+
if (lastNFaces.length > 1) {
|
|
11997
|
+
var lastFace = lastNFaces[1];
|
|
11998
|
+
var iou = calculateIoU(face.box, lastFace.box);
|
|
11999
|
+
lastNFacePairs.unshift({
|
|
12000
|
+
a: face,
|
|
12001
|
+
b: lastFace,
|
|
12002
|
+
iou: iou
|
|
12003
|
+
});
|
|
12004
|
+
if (lastNFacePairs.length > framesNeeded - 1) lastNFacePairs.length = framesNeeded - 1;
|
|
12005
|
+
}
|
|
12006
|
+
if (lastNNoses.length > 1) {
|
|
12007
|
+
var lastNose = lastNNoses[1];
|
|
12008
|
+
var noseDistance = Math.sqrt(Math.pow((nose.x - lastNose.x) / frameWidth, 2) + Math.pow((nose.y - lastNose.y) / frameHeight, 2));
|
|
12009
|
+
lastNNosePairs.unshift({
|
|
12010
|
+
a: nose,
|
|
12011
|
+
b: lastNose,
|
|
12012
|
+
distance: noseDistance
|
|
12013
|
+
});
|
|
12014
|
+
if (lastNNosePairs.length > framesNeeded - 1) lastNNosePairs.length = framesNeeded - 1;
|
|
12015
|
+
}
|
|
12016
|
+
}
|
|
12017
|
+
function makeFaceDetectorPrediction(imageData) {
|
|
12018
|
+
if (!detector) return null;
|
|
12019
|
+
var prediction = detector.detectForVideo(imageData, performance.now());
|
|
12020
|
+
var faces = prediction.detections.map(function (d) {
|
|
12021
|
+
return {
|
|
12022
|
+
box: convertBoundingBox(d.boundingBox),
|
|
12023
|
+
keypoints: d.keypoints.map(function (k) {
|
|
12024
|
+
var _a;
|
|
12025
|
+
return _assign(_assign({}, k), {
|
|
12026
|
+
x: k.x * imageData.width,
|
|
12027
|
+
y: k.y * imageData.height,
|
|
12028
|
+
name: (_a = k.label) !== null && _a !== void 0 ? _a : ''
|
|
12029
|
+
});
|
|
12030
|
+
})
|
|
12031
|
+
};
|
|
12032
|
+
});
|
|
12033
|
+
return _assign(_assign({}, prediction), {
|
|
12034
|
+
faces: faces
|
|
12035
|
+
});
|
|
12036
|
+
}
|
|
12037
|
+
function processFaceDetectorPrediction(_a) {
|
|
12038
|
+
var faces = _a.faces,
|
|
12039
|
+
videoWidth = _a.videoWidth,
|
|
12040
|
+
videoHeight = _a.videoHeight,
|
|
12041
|
+
_b = _a.requireVerticalFaceCentering,
|
|
12042
|
+
requireVerticalFaceCentering = _b === void 0 ? true : _b,
|
|
12043
|
+
_c = _a.stabilityThreshold,
|
|
12044
|
+
stabilityThreshold = _c === void 0 ? 0.7 : _c,
|
|
12045
|
+
_d = _a.noseDistanceThreshold,
|
|
12046
|
+
noseDistanceThreshold = _d === void 0 ? 0.025 : _d,
|
|
12047
|
+
_e = _a.xBoundary,
|
|
12048
|
+
xBoundary = _e === void 0 ? 0.01 : _e,
|
|
12049
|
+
// this represents the edge that the sides of the face box should not cross -- 1% of video width
|
|
12050
|
+
_f = _a.yBoundary,
|
|
12051
|
+
// this represents the edge that the sides of the face box should not cross -- 1% of video width
|
|
12052
|
+
yBoundary = _f === void 0 ? 0.01 : _f,
|
|
12053
|
+
// this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
|
|
12054
|
+
_g = _a.xCentroidBoundary,
|
|
12055
|
+
// this represents the edge that the top or bottom of the face box should not cross -- 1% of video height
|
|
12056
|
+
xCentroidBoundary = _g === void 0 ? 0.125 : _g,
|
|
12057
|
+
// this represents the edge that the centroid of the face should not cross -- 12.5% of video width
|
|
12058
|
+
_h = _a.yCentroidBoundary,
|
|
12059
|
+
// this represents the edge that the centroid of the face should not cross -- 12.5% of video width
|
|
12060
|
+
yCentroidBoundary = _h === void 0 ? 0.125 : _h,
|
|
12061
|
+
// this represents the edge that the centroid of the face should not cross -- 12.5% of video height
|
|
12062
|
+
_j = _a.foreheadRatio,
|
|
12063
|
+
// this represents the edge that the centroid of the face should not cross -- 12.5% of video height
|
|
12064
|
+
foreheadRatio = _j === void 0 ? 0.275 : _j,
|
|
12065
|
+
// we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
|
|
12066
|
+
_k = _a.noseTrackingThreshold,
|
|
12067
|
+
// we found that the bounding box ends at the brow and misses the forehead. this ratio represents how much we should extend the box to include the forehead.
|
|
12068
|
+
noseTrackingThreshold = _k === void 0 ? 0.2 : _k,
|
|
12069
|
+
// this represents the maximum distance that the nose can be from the center of the face box -- 20% of the face box width or height
|
|
12070
|
+
minCaptureBrightnessThreshold = _a.minCaptureBrightnessThreshold,
|
|
12071
|
+
minCaptureRangeThreshold = _a.minCaptureRangeThreshold,
|
|
12072
|
+
minCaptureVarianceThreshold = _a.minCaptureVarianceThreshold,
|
|
12073
|
+
brightness = _a.brightness,
|
|
12074
|
+
range = _a.range,
|
|
12075
|
+
variance = _a.variance;
|
|
12076
|
+
var face = faces[0];
|
|
12077
|
+
var faceNotDetected = faces.length === 0;
|
|
12078
|
+
var faceNotCentered = false,
|
|
12079
|
+
faceLookingAway = false,
|
|
12080
|
+
faceTooClose = false,
|
|
12081
|
+
faceTooFar = false,
|
|
12082
|
+
faceVisibilityTooLow = false;
|
|
12083
|
+
var hasAnyThreshold = minCaptureBrightnessThreshold !== undefined || minCaptureRangeThreshold !== undefined || minCaptureVarianceThreshold !== undefined;
|
|
12084
|
+
if (hasAnyThreshold) {
|
|
12085
|
+
var tooDark = minCaptureBrightnessThreshold !== undefined && brightness !== undefined && brightness < minCaptureBrightnessThreshold;
|
|
12086
|
+
var tooLowRange = minCaptureRangeThreshold !== undefined && range !== undefined && range < minCaptureRangeThreshold;
|
|
12087
|
+
var tooLowVariance = minCaptureVarianceThreshold !== undefined && variance !== undefined && variance < minCaptureVarianceThreshold;
|
|
12088
|
+
faceVisibilityTooLow = !!(tooDark || tooLowRange || tooLowVariance);
|
|
12089
|
+
}
|
|
12090
|
+
if (face && !faceVisibilityTooLow) {
|
|
12091
|
+
// calculate frame centroids
|
|
12092
|
+
var frameCX = videoWidth / 2;
|
|
12093
|
+
var frameCY = videoHeight / 2;
|
|
12094
|
+
// calculate head bounding box, with forehead extension
|
|
12095
|
+
var foreheadSize = face.box.height * foreheadRatio;
|
|
12096
|
+
var headXMin = face.box.xMin;
|
|
12097
|
+
var headXMax = face.box.xMax;
|
|
12098
|
+
var headYMin = face.box.yMin - foreheadSize;
|
|
12099
|
+
var headYMax = face.box.yMax;
|
|
12100
|
+
// calculate head centroids
|
|
12101
|
+
var headCX = (headXMin + headXMax) / 2;
|
|
12102
|
+
var headCY = (headYMin + headYMax) / 2;
|
|
12103
|
+
// calculate thresholds
|
|
12104
|
+
var vTX = videoWidth * xBoundary;
|
|
12105
|
+
var vTY = videoHeight * yBoundary;
|
|
12106
|
+
var vCTX = videoWidth * xCentroidBoundary;
|
|
12107
|
+
var vCTY = videoHeight * yCentroidBoundary;
|
|
12108
|
+
var faceNotCenteredHorizontally = Math.abs(frameCX - headCX) > vCTX;
|
|
12109
|
+
var faceNotCenteredVertically = Math.abs(frameCY - headCY) > vCTY;
|
|
12110
|
+
var faceViolatesHorizontalBoundary = headXMin < vTX || headXMax > videoWidth - vTX;
|
|
12111
|
+
var faceViolatesVerticalBoundary = headYMin < vTY || headYMax > videoHeight - vTY;
|
|
12112
|
+
faceNotCentered = faceViolatesHorizontalBoundary || faceViolatesVerticalBoundary || faceNotCenteredHorizontally || requireVerticalFaceCentering && faceNotCenteredVertically;
|
|
12113
|
+
var isMobile = videoWidth < videoHeight;
|
|
12114
|
+
var tooCloseMultiple = 1.5;
|
|
12115
|
+
var tooFarMultiple = isMobile ? 6 : 7;
|
|
12116
|
+
faceTooClose = face.box.width > videoWidth / tooCloseMultiple;
|
|
12117
|
+
faceTooFar = face.box.width < videoWidth / tooFarMultiple;
|
|
12118
|
+
var nose = face.keypoints[2];
|
|
12119
|
+
var fTW = face.box.width * noseTrackingThreshold;
|
|
12120
|
+
var fTH = face.box.height * noseTrackingThreshold;
|
|
12121
|
+
faceLookingAway = !nose || Math.abs(headCX - nose.x) > fTW || Math.abs(headCY - nose.y) > fTH;
|
|
12122
|
+
}
|
|
12123
|
+
var faceInGuides = !faceNotDetected && !faceNotCentered && !faceLookingAway && !faceTooClose && !faceTooFar;
|
|
12124
|
+
if (lastFaceDetectionTime > 0) {
|
|
12125
|
+
trackFramesNeeded(500 / lastFaceDetectionTime);
|
|
12126
|
+
}
|
|
12127
|
+
var faceIsStable = false,
|
|
12128
|
+
noseIsStable = false;
|
|
12129
|
+
if (faceInGuides && !faceVisibilityTooLow) {
|
|
12130
|
+
var framesNeeded = Math.max(Math.ceil(average(framesNeededSamples)), 5);
|
|
12131
|
+
trackFace(face, framesNeeded, videoWidth, videoHeight);
|
|
12132
|
+
faceIsStable = lastNFaces.length >= framesNeeded && !lastNFacePairs.some(function (pair) {
|
|
12133
|
+
return pair.iou < stabilityThreshold;
|
|
12134
|
+
});
|
|
12135
|
+
noseIsStable = lastNNoses.length >= framesNeeded && !lastNNosePairs.some(function (pair) {
|
|
12136
|
+
return pair.distance > noseDistanceThreshold;
|
|
12137
|
+
});
|
|
12138
|
+
}
|
|
12139
|
+
var faceReady = faceInGuides && faceIsStable && noseIsStable && !faceVisibilityTooLow;
|
|
12140
|
+
return {
|
|
12141
|
+
face: face,
|
|
12142
|
+
faceNotDetected: faceNotDetected,
|
|
12143
|
+
faceNotCentered: faceNotCentered,
|
|
12144
|
+
faceLookingAway: faceLookingAway,
|
|
12145
|
+
faceTooClose: faceTooClose,
|
|
12146
|
+
faceTooFar: faceTooFar,
|
|
12147
|
+
faceReady: faceReady,
|
|
12148
|
+
faceReadyAt: faceReady ? new Date() : null,
|
|
12149
|
+
faceIsStable: faceIsStable,
|
|
12150
|
+
noseIsStable: noseIsStable,
|
|
12151
|
+
faceVisibilityTooLow: faceVisibilityTooLow
|
|
12152
|
+
};
|
|
12153
|
+
}
|
|
12154
|
+
function testFaceDetectionAgainstKnownImage(detector) {
|
|
12155
|
+
return new Promise(function (resolve, reject) {
|
|
12156
|
+
var img = new Image();
|
|
12157
|
+
img.crossOrigin = 'anonymous';
|
|
12158
|
+
img.onload = function () {
|
|
12159
|
+
var prediction = detector.detectForVideo(img, performance.now());
|
|
12160
|
+
if (prediction.detections.length > 0) {
|
|
12161
|
+
debug('face detection test result', prediction.detections);
|
|
12162
|
+
resolve(void 0);
|
|
12163
|
+
} else {
|
|
12164
|
+
warn('face detection test failed');
|
|
12165
|
+
reject(new Error('testFaceDetectionAgainstKnownImage failed to predict'));
|
|
12166
|
+
}
|
|
12167
|
+
};
|
|
12168
|
+
img.onerror = function () {
|
|
12169
|
+
return reject(new Error('testFaceDetectionAgainstKnownImage failed to load image'));
|
|
12170
|
+
};
|
|
12171
|
+
img.src = "".concat(DEFAULT_CDN_URL, "/head-test.jpg");
|
|
12172
|
+
});
|
|
11666
12173
|
}
|
|
11667
|
-
var templateObject_1$o, templateObject_2$m, templateObject_3$g;
|
|
11668
|
-
|
|
11669
|
-
var FaceCaptureGuideContainer = styled__default.default.div(templateObject_1$n || (templateObject_1$n = __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"])));
|
|
11670
|
-
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"])));
|
|
11671
|
-
var FaceCaptureGuideOverlay = function FaceCaptureGuideOverlay(_a) {
|
|
11672
|
-
var _b = _a.classNames,
|
|
11673
|
-
classNames = _b === void 0 ? {} : _b,
|
|
11674
|
-
_c = _a.status,
|
|
11675
|
-
status = _c === void 0 ? 'ready' : _c,
|
|
11676
|
-
_d = _a.borderWidth,
|
|
11677
|
-
borderWidth = _d === void 0 ? 5 : _d,
|
|
11678
|
-
_e = _a.borderColor,
|
|
11679
|
-
borderColor = _e === void 0 ? 'white' : _e,
|
|
11680
|
-
_f = _a.borderOpacity,
|
|
11681
|
-
borderOpacity = _f === void 0 ? 0.8 : _f;
|
|
11682
|
-
return /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideContainer, {
|
|
11683
|
-
className: classNames.container
|
|
11684
|
-
}, /*#__PURE__*/React__namespace.default.createElement(FaceCaptureGuideInner, null, /*#__PURE__*/React__namespace.default.createElement(SelfieCaptureAnimatedMaskWithStatus, {
|
|
11685
|
-
status: status,
|
|
11686
|
-
borderColor: borderColor,
|
|
11687
|
-
borderWidth: borderWidth,
|
|
11688
|
-
borderOpacity: borderOpacity,
|
|
11689
|
-
verticalAlign: "center"
|
|
11690
|
-
})));
|
|
11691
|
-
};
|
|
11692
|
-
var templateObject_1$n, templateObject_2$l;
|
|
11693
12174
|
|
|
11694
12175
|
function detectBrightnessAndContrast(frame, brightnessAverager) {
|
|
11695
12176
|
var ctx = frame.getContext('2d');
|
|
@@ -12983,7 +13464,7 @@ var SelfieCaptureLoadingOverlayDefault = function SelfieCaptureLoadingOverlayDef
|
|
|
12983
13464
|
});
|
|
12984
13465
|
}, 3000);
|
|
12985
13466
|
}, []);
|
|
12986
|
-
var timeSinceWarmingStarted = modelWarmingStartedAt ?
|
|
13467
|
+
var timeSinceWarmingStarted = modelWarmingStartedAt ? performance.now() - modelWarmingStartedAt : 0;
|
|
12987
13468
|
var warmingProgress = timeSinceWarmingStarted / 5000.0;
|
|
12988
13469
|
var _o = React.useState(false),
|
|
12989
13470
|
overrideModelsReady = _o[0],
|