idmission-web-sdk 2.3.171-feature-barcode-recapture-d495693 → 2.3.171-feature-barcode-recapture-658bede

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.
@@ -502,7 +502,7 @@
502
502
  });
503
503
  var OverlayImageContainer = styled.div(templateObject_3$w || (templateObject_3$w = __makeTemplateObject(["\n position: relative;\n display: flex;\n flex-grow: 1;\n padding-bottom: 25px;\n overflow: hidden;\n\n & > img,\n & > svg {\n margin: 0 auto;\n width: max-content;\n max-width: 100%;\n max-height: 100%;\n aspect-ratio: initial;\n object-fit: contain;\n display: block;\n }\n"], ["\n position: relative;\n display: flex;\n flex-grow: 1;\n padding-bottom: 25px;\n overflow: hidden;\n\n & > img,\n & > svg {\n margin: 0 auto;\n width: max-content;\n max-width: 100%;\n max-height: 100%;\n aspect-ratio: initial;\n object-fit: contain;\n display: block;\n }\n"])));
504
504
  var OverlayImageRow = styled.div(templateObject_4$q || (templateObject_4$q = __makeTemplateObject(["\n display: flex;\n margin: auto;\n\n & > div {\n max-height: calc(100% - 320px);\n\n & > img {\n width: 100%;\n max-height: 100%;\n height: auto;\n object-fit: contain;\n }\n }\n"], ["\n display: flex;\n margin: auto;\n\n & > div {\n max-height: calc(100% - 320px);\n\n & > img {\n width: 100%;\n max-height: 100%;\n height: auto;\n object-fit: contain;\n }\n }\n"])));
505
- var GrayOverlayContainer = styled(OverlayContainer)(templateObject_5$i || (templateObject_5$i = __makeTemplateObject(["\n background: #f7f6fb;\n"], ["\n background: #f7f6fb;\n"])));
505
+ var GrayOverlayContainer = styled(OverlayContainer)(templateObject_5$j || (templateObject_5$j = __makeTemplateObject(["\n background: #f7f6fb;\n"], ["\n background: #f7f6fb;\n"])));
506
506
  var ButtonsColumn = styled.div(templateObject_6$b || (templateObject_6$b = __makeTemplateObject(["\n display: flex;\n flex-direction: column;\n gap: 15px 0;\n justify-content: center;\n margin-top: 24px;\n"], ["\n display: flex;\n flex-direction: column;\n gap: 15px 0;\n justify-content: center;\n margin-top: 24px;\n"])));
507
507
  var WideButton = styled(LoaderButton)(templateObject_7$7 || (templateObject_7$7 = __makeTemplateObject(["\n width: 100%;\n border-radius: 30px;\n"], ["\n width: 100%;\n border-radius: 30px;\n"])));
508
508
  var WideBorderButton = styled(WideButton)(templateObject_8$6 || (templateObject_8$6 = __makeTemplateObject(["\n color: ", ";\n background: ", ";\n border: 1px solid\n ", ";\n box-sizing: border-box;\n"], ["\n color: ", ";\n background: ", ";\n border: 1px solid\n ", ";\n box-sizing: border-box;\n"])), function (props) {
@@ -542,7 +542,7 @@
542
542
  var LoadingOverlayProgressContainer = styled.div(templateObject_20$2 || (templateObject_20$2 = __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"])));
543
543
  var LoadingOverlayCustomLoadingGraphic = styled.img(templateObject_21$2 || (templateObject_21$2 = __makeTemplateObject(["\n transform-style: preserve-3d;\n"], ["\n transform-style: preserve-3d;\n"])));
544
544
  var LoadingOverlayContinueButtonContainer = styled.div(templateObject_22$2 || (templateObject_22$2 = __makeTemplateObject(["\n display: flex;\n"], ["\n display: flex;\n"])));
545
- var templateObject_1$P, templateObject_2$K, templateObject_3$w, templateObject_4$q, templateObject_5$i, templateObject_6$b, templateObject_7$7, templateObject_8$6, templateObject_9$4, templateObject_10$3, templateObject_11$3, templateObject_12$3, templateObject_13$3, templateObject_14$2, templateObject_15$2, templateObject_16$2, templateObject_17$2, templateObject_18$2, templateObject_19$2, templateObject_20$2, templateObject_21$2, templateObject_22$2;
545
+ var templateObject_1$P, templateObject_2$K, templateObject_3$w, templateObject_4$q, templateObject_5$j, templateObject_6$b, templateObject_7$7, templateObject_8$6, templateObject_9$4, templateObject_10$3, templateObject_11$3, templateObject_12$3, templateObject_13$3, templateObject_14$2, templateObject_15$2, templateObject_16$2, templateObject_17$2, templateObject_18$2, templateObject_19$2, templateObject_20$2, templateObject_21$2, templateObject_22$2;
546
546
 
547
547
  function _extends() {
548
548
  return _extends = Object.assign ? Object.assign.bind() : function (n) {
@@ -14690,9 +14690,9 @@
14690
14690
  function analyzeBarcodeReadability(prediction, lastPredictionCanvas, croppedDocumentCanvas, bestBarcodeCanvas, currentBestBarcodeScore, documentDetectionThresholds, makeBarcodeReadabilityPrediction, barcodeReadabilityThreshold) {
14691
14691
  return __awaiter(this, void 0, void 0, function () {
14692
14692
  var pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, newBestBarcodeScore, newBestBarcodeDetails, documentCroppedPrediction, processedCroppedPrediction, pdf417Prediction;
14693
- var _a;
14694
- return __generator(this, function (_b) {
14695
- switch (_b.label) {
14693
+ var _a, _b;
14694
+ return __generator(this, function (_c) {
14695
+ switch (_c.label) {
14696
14696
  case 0:
14697
14697
  pdf417PredictionTime = 0;
14698
14698
  pdf417PredictionScore = 0;
@@ -14703,7 +14703,8 @@
14703
14703
  pdf417PredictionScore: pdf417PredictionScore,
14704
14704
  pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
14705
14705
  newBestBarcodeScore: newBestBarcodeScore,
14706
- newBestBarcodeDetails: newBestBarcodeDetails
14706
+ newBestBarcodeDetails: newBestBarcodeDetails,
14707
+ processedBarcodeBoundingBox: undefined
14707
14708
  }];
14708
14709
  }
14709
14710
  /**
@@ -14713,7 +14714,7 @@
14713
14714
  cropToDetectedObjectBox(lastPredictionCanvas, prediction.bestDocument.box, croppedDocumentCanvas);
14714
14715
  return [4 /*yield*/, makeDocumentDetectorPrediction(croppedDocumentCanvas)];
14715
14716
  case 1:
14716
- documentCroppedPrediction = _b.sent();
14717
+ documentCroppedPrediction = _c.sent();
14717
14718
  if (!documentCroppedPrediction) {
14718
14719
  // error occurred during prediction (error logged by callee)
14719
14720
  return [2 /*return*/, {
@@ -14721,7 +14722,8 @@
14721
14722
  pdf417PredictionScore: pdf417PredictionScore,
14722
14723
  pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
14723
14724
  newBestBarcodeScore: newBestBarcodeScore,
14724
- newBestBarcodeDetails: newBestBarcodeDetails
14725
+ newBestBarcodeDetails: newBestBarcodeDetails,
14726
+ processedBarcodeBoundingBox: undefined
14725
14727
  }];
14726
14728
  }
14727
14729
  processedCroppedPrediction = processDocumentDetectorPrediction(documentCroppedPrediction, documentDetectionThresholds);
@@ -14751,7 +14753,9 @@
14751
14753
  pdf417PredictionScore: pdf417PredictionScore,
14752
14754
  pdf417PredictionThresholdMet: pdf417PredictionThresholdMet,
14753
14755
  newBestBarcodeScore: newBestBarcodeScore,
14754
- newBestBarcodeDetails: newBestBarcodeDetails
14756
+ newBestBarcodeDetails: newBestBarcodeDetails,
14757
+ // Return processed barcode bounding box for recapture tracking (valid even when not a new best)
14758
+ processedBarcodeBoundingBox: (_b = processedCroppedPrediction === null || processedCroppedPrediction === void 0 ? void 0 : processedCroppedPrediction.bestPDF417) === null || _b === void 0 ? void 0 : _b.box
14755
14759
  }];
14756
14760
  }
14757
14761
  });
@@ -14842,6 +14846,9 @@
14842
14846
  getBestBarcode: function getBestBarcode() {
14843
14847
  return null;
14844
14848
  },
14849
+ resetBestBarcode: function resetBestBarcode() {
14850
+ return null;
14851
+ },
14845
14852
  startBarcodeRecapturePhase: function startBarcodeRecapturePhase() {
14846
14853
  return null;
14847
14854
  },
@@ -14942,10 +14949,10 @@
14942
14949
  var _this = this;
14943
14950
  onDocumentDetected(function (prediction) {
14944
14951
  return __awaiter(_this, void 0, void 0, function () {
14945
- var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, isInRecapturePhase, shouldRunBarcodeAnalysisDuringRecapture, focusPrediction, focusThresholdSet, focusThreshold, barcodeAnalysisResult, ctx, barcodeAnalysisResult, ctx;
14946
- var _a, _b, _c, _d, _e, _f, _g, _h, _j;
14947
- return __generator(this, function (_k) {
14948
- switch (_k.label) {
14952
+ var stopDetectionAtStart, focusPredictionTime, focusScore, focusThresholdMet, pdf417PredictionTime, pdf417PredictionScore, pdf417PredictionThresholdMet, isSinglePage, isRequiredDocumentType, isInRecapturePhase, shouldRunBarcodeAnalysisDuringRecapture, focusPrediction, focusThresholdSet, focusThreshold, barcodeAnalysisResult, barcodeAnalysisResult;
14953
+ var _a, _b, _c, _d, _e, _f, _g;
14954
+ return __generator(this, function (_h) {
14955
+ switch (_h.label) {
14949
14956
  case 0:
14950
14957
  if (!lastPredictionCanvas.current) return [2 /*return*/];
14951
14958
  stopDetectionAtStart = stopDetection.current;
@@ -14960,7 +14967,7 @@
14960
14967
  }
14961
14968
  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'));
14962
14969
  isInRecapturePhase = isRecapturePhase.current;
14963
- shouldRunBarcodeAnalysisDuringRecapture = isInRecapturePhase && isRequiredDocumentType && prediction.detectedDocumentType !== 'none' && prediction.detectionThresholdMet && prediction.documentIsStable && prediction.bestDocument && prediction.bestPDF417;
14970
+ shouldRunBarcodeAnalysisDuringRecapture = isInRecapturePhase && isRequiredDocumentType && prediction.detectedDocumentType !== 'none' && prediction.detectionThresholdMet && prediction.bestDocument && prediction.bestPDF417;
14964
14971
  if (!(isRequiredDocumentType && prediction.detectedDocumentType !== 'none' && prediction.detectionThresholdMet && prediction.documentInBounds && !prediction.documentTooClose && prediction.documentIsStable)) return [3 /*break*/, 3];
14965
14972
  focusPrediction = makeFocusPrediction(lastPredictionCanvas.current, (_c = prediction.bestDocument) === null || _c === void 0 ? void 0 : _c.box);
14966
14973
  if (focusPrediction) {
@@ -14984,7 +14991,7 @@
14984
14991
  if (!(enableBarcodeReadabilityModel && prediction.bestDocument && prediction.bestPDF417 && croppedDocumentCanvas.current)) return [3 /*break*/, 2];
14985
14992
  return [4 /*yield*/, analyzeBarcodeReadability(prediction, lastPredictionCanvas.current, croppedDocumentCanvas.current, bestBarcodeCanvas.current, bestBarcodeScore.current)];
14986
14993
  case 1:
14987
- barcodeAnalysisResult = _k.sent();
14994
+ barcodeAnalysisResult = _h.sent();
14988
14995
  pdf417PredictionTime = barcodeAnalysisResult.pdf417PredictionTime;
14989
14996
  pdf417PredictionScore = barcodeAnalysisResult.pdf417PredictionScore;
14990
14997
  pdf417PredictionThresholdMet = barcodeAnalysisResult.pdf417PredictionThresholdMet;
@@ -14996,19 +15003,23 @@
14996
15003
  }
14997
15004
  // During recapture phase, also track best barcode separately for recapture sequence
14998
15005
  if (isRecapturePhase.current && recaptureBarcodeCanvas.current && pdf417PredictionScore > recaptureBarcodeScore.current) {
15006
+ log("[IdCaptureModelsProvider] Recapture tracking: new best score ".concat(pdf417PredictionScore, " (was ").concat(recaptureBarcodeScore.current, ")"));
14999
15007
  recaptureBarcodeScore.current = pdf417PredictionScore;
15000
- recaptureBarcodeDetails.current = (_g = barcodeAnalysisResult.newBestBarcodeDetails) !== null && _g !== void 0 ? _g : null;
15001
- // Copy the current best barcode canvas to recapture canvas
15002
- if (bestBarcodeCanvas.current) {
15003
- ctx = recaptureBarcodeCanvas.current.getContext('2d');
15004
- if (ctx) {
15005
- recaptureBarcodeCanvas.current.width = bestBarcodeCanvas.current.width;
15006
- recaptureBarcodeCanvas.current.height = bestBarcodeCanvas.current.height;
15007
- ctx.drawImage(bestBarcodeCanvas.current, 0, 0);
15008
- }
15008
+ // Create details directly from current prediction (not newBestBarcodeDetails which
15009
+ // is only set when score beats overall best, not just recapture best)
15010
+ recaptureBarcodeDetails.current = {
15011
+ boundingBox: prediction.bestPDF417.box,
15012
+ score: pdf417PredictionScore
15013
+ };
15014
+ // Crop barcode from croppedDocumentCanvas using the processed bounding box
15015
+ // (can't use bestBarcodeCanvas since it's only updated for overall best)
15016
+ if (croppedDocumentCanvas.current && barcodeAnalysisResult.processedBarcodeBoundingBox) {
15017
+ cropToDetectedObjectBox(croppedDocumentCanvas.current, barcodeAnalysisResult.processedBarcodeBoundingBox, recaptureBarcodeCanvas.current, 16);
15018
+ } else {
15019
+ log("[IdCaptureModelsProvider] Recapture tracking: could not crop barcode - croppedDocumentCanvas=".concat(!!croppedDocumentCanvas.current, ", processedBarcodeBoundingBox=").concat(!!barcodeAnalysisResult.processedBarcodeBoundingBox));
15009
15020
  }
15010
15021
  }
15011
- _k.label = 2;
15022
+ _h.label = 2;
15012
15023
  case 2:
15013
15024
  return [3 /*break*/, 5];
15014
15025
  case 3:
@@ -15016,7 +15027,7 @@
15016
15027
  if (!(enableBarcodeReadabilityModel && croppedDocumentCanvas.current && stopDetectionAtStart === stopDetection.current)) return [3 /*break*/, 5];
15017
15028
  return [4 /*yield*/, analyzeBarcodeReadability(prediction, lastPredictionCanvas.current, croppedDocumentCanvas.current, bestBarcodeCanvas.current, bestBarcodeScore.current)];
15018
15029
  case 4:
15019
- barcodeAnalysisResult = _k.sent();
15030
+ barcodeAnalysisResult = _h.sent();
15020
15031
  pdf417PredictionTime = barcodeAnalysisResult.pdf417PredictionTime;
15021
15032
  pdf417PredictionScore = barcodeAnalysisResult.pdf417PredictionScore;
15022
15033
  pdf417PredictionThresholdMet = barcodeAnalysisResult.pdf417PredictionThresholdMet;
@@ -15028,19 +15039,23 @@
15028
15039
  }
15029
15040
  // Track best barcode separately for recapture sequence
15030
15041
  if (recaptureBarcodeCanvas.current && pdf417PredictionScore > recaptureBarcodeScore.current) {
15042
+ log("[IdCaptureModelsProvider] Recapture tracking (relaxed): new best score ".concat(pdf417PredictionScore, " (was ").concat(recaptureBarcodeScore.current, ")"));
15031
15043
  recaptureBarcodeScore.current = pdf417PredictionScore;
15032
- recaptureBarcodeDetails.current = (_h = barcodeAnalysisResult.newBestBarcodeDetails) !== null && _h !== void 0 ? _h : null;
15033
- // Copy the current best barcode canvas to recapture canvas
15034
- if (bestBarcodeCanvas.current) {
15035
- ctx = recaptureBarcodeCanvas.current.getContext('2d');
15036
- if (ctx) {
15037
- recaptureBarcodeCanvas.current.width = bestBarcodeCanvas.current.width;
15038
- recaptureBarcodeCanvas.current.height = bestBarcodeCanvas.current.height;
15039
- ctx.drawImage(bestBarcodeCanvas.current, 0, 0);
15040
- }
15044
+ // Create details directly from current prediction (not newBestBarcodeDetails which
15045
+ // is only set when score beats overall best, not just recapture best)
15046
+ recaptureBarcodeDetails.current = {
15047
+ boundingBox: prediction.bestPDF417.box,
15048
+ score: pdf417PredictionScore
15049
+ };
15050
+ // Crop barcode from croppedDocumentCanvas using the processed bounding box
15051
+ // (can't use bestBarcodeCanvas since it's only updated for overall best)
15052
+ if (croppedDocumentCanvas.current && barcodeAnalysisResult.processedBarcodeBoundingBox) {
15053
+ cropToDetectedObjectBox(croppedDocumentCanvas.current, barcodeAnalysisResult.processedBarcodeBoundingBox, recaptureBarcodeCanvas.current, 16);
15054
+ } else {
15055
+ log("[IdCaptureModelsProvider] Recapture tracking (relaxed): could not crop barcode - croppedDocumentCanvas=".concat(!!croppedDocumentCanvas.current, ", processedBarcodeBoundingBox=").concat(!!barcodeAnalysisResult.processedBarcodeBoundingBox));
15041
15056
  }
15042
15057
  }
15043
- _k.label = 5;
15058
+ _h.label = 5;
15044
15059
  case 5:
15045
15060
  /**
15046
15061
  * @note
@@ -15048,7 +15063,7 @@
15048
15063
  * Do not return early from this function unless
15049
15064
  * lastPredictionCanvas.current is not set
15050
15065
  */
15051
- (_j = onPredictionHandler.current) === null || _j === void 0 ? void 0 : _j.call(onPredictionHandler, _assign(_assign({}, prediction), {
15066
+ (_g = onPredictionHandler.current) === null || _g === void 0 ? void 0 : _g.call(onPredictionHandler, _assign(_assign({}, prediction), {
15052
15067
  focusScore: focusScore,
15053
15068
  focusPredictionTime: focusPredictionTime,
15054
15069
  focusThresholdMet: focusThresholdMet,
@@ -15081,7 +15096,29 @@
15081
15096
  canvas: bestBarcodeCanvas.current
15082
15097
  });
15083
15098
  }, []);
15099
+ var resetBestBarcode = React.useCallback(function () {
15100
+ // Light-weight reset that only clears barcode tracking without disrupting detection
15101
+ bestBarcodeScore.current = 0;
15102
+ bestBarcodeDetails.current = null;
15103
+ // Also reset recapture tracking so early frames during move-closer window are ignored
15104
+ recaptureBarcodeScore.current = 0;
15105
+ recaptureBarcodeDetails.current = null;
15106
+ // Clear the canvas content but don't recreate it
15107
+ if (bestBarcodeCanvas.current) {
15108
+ var ctx = bestBarcodeCanvas.current.getContext('2d');
15109
+ if (ctx) {
15110
+ ctx.clearRect(0, 0, bestBarcodeCanvas.current.width, bestBarcodeCanvas.current.height);
15111
+ }
15112
+ }
15113
+ if (recaptureBarcodeCanvas.current) {
15114
+ var ctx = recaptureBarcodeCanvas.current.getContext('2d');
15115
+ if (ctx) {
15116
+ ctx.clearRect(0, 0, recaptureBarcodeCanvas.current.width, recaptureBarcodeCanvas.current.height);
15117
+ }
15118
+ }
15119
+ }, []);
15084
15120
  var startBarcodeRecapturePhase = React.useCallback(function () {
15121
+ log("[IdCaptureModelsProvider] Starting barcode recapture phase. Initial best score: ".concat(bestBarcodeScore.current));
15085
15122
  // Snapshot current best barcode to initial capture canvas
15086
15123
  if (bestBarcodeCanvas.current && initialCaptureBarcodeCanvas.current) {
15087
15124
  var ctx = initialCaptureBarcodeCanvas.current.getContext('2d');
@@ -15198,13 +15235,14 @@
15198
15235
  bestFrameDetails: bestFrameDetails,
15199
15236
  bestBarcodeDetails: bestBarcodeDetails,
15200
15237
  getBestBarcode: getBestBarcode,
15238
+ resetBestBarcode: resetBestBarcode,
15201
15239
  startBarcodeRecapturePhase: startBarcodeRecapturePhase,
15202
15240
  getInitialCaptureBestBarcode: getInitialCaptureBestBarcode,
15203
15241
  getRecaptureBestBarcode: getRecaptureBestBarcode,
15204
15242
  requiredDocumentType: requiredDocumentType,
15205
15243
  setRequiredDocumentType: setRequiredDocumentType
15206
15244
  };
15207
- }, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, startBarcodeRecapturePhase, getInitialCaptureBestBarcode, getRecaptureBestBarcode, requiredDocumentType]);
15245
+ }, [ready, modelDownloadProgress, modelLoadState, modelWarmingStartedAt, modelError, startDocumentDetection, stopDocumentDetection, load, thresholds, setThresholds, documentDetectionBoundaries, setDocumentDetectionBoundaries, onPredictionMade, detectionTime, focusPredictionTime, barcodeReadabilityPredictionTime, getBestFrame, resetBestFrame, getBestBarcode, resetBestBarcode, startBarcodeRecapturePhase, getInitialCaptureBestBarcode, getRecaptureBestBarcode, requiredDocumentType]);
15208
15246
  return /*#__PURE__*/React.createElement(IdCaptureModelsContext.Provider, {
15209
15247
  value: value
15210
15248
  }, /*#__PURE__*/React.createElement(InvisibleCanvasContainer, null, /*#__PURE__*/React.createElement(InvisibleCanvas, {
@@ -16152,7 +16190,11 @@
16152
16190
  var $flipX = _a.$flipX;
16153
16191
  return $flipX ? 'transform: scaleX(-1);' : '';
16154
16192
  });
16155
- var FaceDetectionKeypointMarker = styled.div(templateObject_4$p || (templateObject_4$p = __makeTemplateObject(["\n position: absolute;\n width: 4px;\n height: 4px;\n border: 2px solid ", ";\n font: 10px monospace;\n color: ", ";\n border-radius: 50%;\n ", "\n transform-style: preserve-3d;\n"], ["\n position: absolute;\n width: 4px;\n height: 4px;\n border: 2px solid ", ";\n font: 10px monospace;\n color: ", ";\n border-radius: 50%;\n ", "\n transform-style: preserve-3d;\n"])), function (_a) {
16193
+ var ObjectDetectionDebugLabel = styled.span(templateObject_4$p || (templateObject_4$p = __makeTemplateObject(["\n position: absolute;\n top: -1px;\n left: -1px;\n background: ", ";\n color: black;\n font: bold 9px monospace;\n padding: 1px 3px;\n white-space: nowrap;\n transform: translateY(-100%);\n"], ["\n position: absolute;\n top: -1px;\n left: -1px;\n background: ", ";\n color: black;\n font: bold 9px monospace;\n padding: 1px 3px;\n white-space: nowrap;\n transform: translateY(-100%);\n"])), function (_a) {
16194
+ var $color = _a.$color;
16195
+ return $color !== null && $color !== void 0 ? $color : 'green';
16196
+ });
16197
+ var FaceDetectionKeypointMarker = styled.div(templateObject_5$i || (templateObject_5$i = __makeTemplateObject(["\n position: absolute;\n width: 4px;\n height: 4px;\n border: 2px solid ", ";\n font: 10px monospace;\n color: ", ";\n border-radius: 50%;\n ", "\n transform-style: preserve-3d;\n"], ["\n position: absolute;\n width: 4px;\n height: 4px;\n border: 2px solid ", ";\n font: 10px monospace;\n color: ", ";\n border-radius: 50%;\n ", "\n transform-style: preserve-3d;\n"])), function (_a) {
16156
16198
  var $color = _a.$color;
16157
16199
  return $color !== null && $color !== void 0 ? $color : 'red';
16158
16200
  }, function (_a) {
@@ -16264,7 +16306,9 @@
16264
16306
  width: width,
16265
16307
  height: height
16266
16308
  }
16267
- });
16309
+ }, /*#__PURE__*/React.createElement(ObjectDetectionDebugLabel, {
16310
+ "$color": color
16311
+ }, obj.label, " ", obj.score.toFixed(2)));
16268
16312
  }
16269
16313
  function SelfieCaptureFaceDebugBox(_a) {
16270
16314
  var face = _a.face,
@@ -16350,7 +16394,7 @@
16350
16394
  }
16351
16395
  });
16352
16396
  }
16353
- var templateObject_1$M, templateObject_2$H, templateObject_3$v, templateObject_4$p;
16397
+ var templateObject_1$M, templateObject_2$H, templateObject_3$v, templateObject_4$p, templateObject_5$i;
16354
16398
 
16355
16399
  function OverrideWrongDocumentTypeGuidanceDialog(_a) {
16356
16400
  var _b = _a.classNames,
@@ -20813,6 +20857,7 @@
20813
20857
  setRequiredDocumentType = _18.setRequiredDocumentType,
20814
20858
  modelError = _18.modelError,
20815
20859
  resetBestFrame = _18.resetBestFrame,
20860
+ resetBestBarcode = _18.resetBestBarcode,
20816
20861
  documentDetectionBoundaries = _18.documentDetectionBoundaries,
20817
20862
  setDocumentDetectionBoundaries = _18.setDocumentDetectionBoundaries,
20818
20863
  getBestBarcode = _18.getBestBarcode,
@@ -21086,44 +21131,63 @@
21086
21131
  initialCaptureBarcodeImage: initialBarcodeImage
21087
21132
  }
21088
21133
  });
21089
- }, [state.captureState, (_d = state.capturedDocuments.idBarcodeImage) === null || _d === void 0 ? void 0 : _d.imageData, state.initialBarcodeScore, state.initialCaptureBarcodeImage]);
21134
+ // Start recapture phase immediately so barcode analysis runs with relaxed conditions
21135
+ // (don't require document in bounds since user is zooming in)
21136
+ startBarcodeRecapturePhase();
21137
+ }, [startBarcodeRecapturePhase, state.captureState, (_d = state.capturedDocuments.idBarcodeImage) === null || _d === void 0 ? void 0 : _d.imageData, state.initialBarcodeScore, state.initialCaptureBarcodeImage]);
21138
+ // Reset best barcode after 1 second delay to ignore early frames before user has time to move closer
21139
+ React.useEffect(function () {
21140
+ if (state.captureState !== 'requestingBetterBarcode') return;
21141
+ var t = setTimeout(function () {
21142
+ log('[IdCaptureWizard] Resetting best barcode after 1s delay in move-closer window');
21143
+ resetBestBarcode();
21144
+ }, 1000);
21145
+ return function () {
21146
+ return clearTimeout(t);
21147
+ };
21148
+ }, [resetBestBarcode, state.captureState]);
21090
21149
  // Handle barcode recapture timeout
21091
21150
  React.useEffect(function () {
21092
21151
  if (state.captureState !== 'requestingBetterBarcode') return;
21093
21152
  // Continue detection to try to get a better barcode
21094
21153
  setTimeout(start, 100);
21095
21154
  var t = setTimeout(function () {
21096
- // Move-closer window expired before recapture began
21155
+ var _a, _b;
21156
+ // Move-closer window expired before growth requirement was met
21097
21157
  if (recapturePhaseStartedRef.current) return;
21098
- var bestBarcode = getBestBarcode();
21099
- var improved = !!bestBarcode && bestBarcode.score > state.initialBarcodeScore;
21158
+ // Use recapture tracking since we start tracking with relaxed conditions immediately
21159
+ var recaptureBarcode = getRecaptureBestBarcode();
21160
+ var recaptureScore = (_a = recaptureBarcode === null || recaptureBarcode === void 0 ? void 0 : recaptureBarcode.score) !== null && _a !== void 0 ? _a : null;
21161
+ var improved = !!recaptureBarcode && recaptureBarcode.score > state.initialBarcodeScore;
21100
21162
  if (improved) {
21101
- log("[IdCaptureWizard] Barcode recapture move-closer window timed out. Found better barcode anyway: ".concat(bestBarcode.score.toFixed(3), " (was ").concat(state.initialBarcodeScore.toFixed(3), ")"));
21102
- // Persist the "after" image for debug visual comparison, even if the
21103
- // model-provider recapture tracker was never started.
21104
- dispatchIdCaptureAction({
21105
- type: 'recaptureBarcodeImageCaptured',
21106
- payload: {
21107
- recaptureBarcodeImage: bestBarcode.canvas.toDataURL('image/jpeg', 0.95)
21108
- }
21109
- });
21163
+ log("[IdCaptureWizard] Barcode recapture move-closer window timed out. Found better barcode anyway: ".concat(recaptureBarcode.score.toFixed(3), " (was ").concat(state.initialBarcodeScore.toFixed(3), ")"));
21110
21164
  dispatchIdCaptureAction({
21111
21165
  type: 'barcodeCaptured',
21112
21166
  payload: {
21113
- imageUrl: bestBarcode.canvas.toDataURL('image/jpeg', 0.95),
21114
- barcodeReadabilityScore: bestBarcode.score
21167
+ imageUrl: recaptureBarcode.canvas.toDataURL('image/jpeg', 0.95),
21168
+ barcodeReadabilityScore: recaptureBarcode.score
21115
21169
  }
21116
21170
  });
21117
21171
  } else {
21118
- log("[IdCaptureWizard] Barcode recapture move-closer window timed out. No better barcode found. Initial score: ".concat(state.initialBarcodeScore.toFixed(3)));
21172
+ log("[IdCaptureWizard] Barcode recapture move-closer window timed out. No better barcode found. Best score during window: ".concat((_b = recaptureScore === null || recaptureScore === void 0 ? void 0 : recaptureScore.toFixed(3)) !== null && _b !== void 0 ? _b : 'none', ", initial score: ").concat(state.initialBarcodeScore.toFixed(3)));
21119
21173
  }
21120
- // Record that recapture was attempted (for diagnostics)
21174
+ // Record recapture attempt data for diagnostics - always store the best score
21175
+ // from the move-closer window so debug info shows what was actually captured
21121
21176
  dispatchIdCaptureAction({
21122
21177
  type: 'barcodeRecaptureScoreUpdated',
21123
21178
  payload: {
21124
- recaptureBarcodeScore: improved ? bestBarcode.score : state.initialBarcodeScore
21179
+ recaptureBarcodeScore: recaptureScore
21125
21180
  }
21126
21181
  });
21182
+ // Persist the barcode image from move-closer window for debug visual comparison
21183
+ if (recaptureBarcode) {
21184
+ dispatchIdCaptureAction({
21185
+ type: 'recaptureBarcodeImageCaptured',
21186
+ payload: {
21187
+ recaptureBarcodeImage: recaptureBarcode.canvas.toDataURL('image/jpeg', 0.95)
21188
+ }
21189
+ });
21190
+ }
21127
21191
  dispatchIdCaptureAction({
21128
21192
  type: 'barcodeRecaptureCompleted'
21129
21193
  });
@@ -21131,7 +21195,7 @@
21131
21195
  return function () {
21132
21196
  return clearTimeout(t);
21133
21197
  };
21134
- }, [barcodeRecaptureMoveCloserTimeoutMs, getBestBarcode, start, state.captureState, state.initialBarcodeScore]);
21198
+ }, [barcodeRecaptureMoveCloserTimeoutMs, getRecaptureBestBarcode, start, state.captureState, state.initialBarcodeScore]);
21135
21199
  React.useEffect(function () {
21136
21200
  if (state.captureState !== 'requestingBetterBarcode') return;
21137
21201
  if (!barcodeRecaptureGrowthSatisfied) return;
@@ -21142,11 +21206,14 @@
21142
21206
  var bestBarcode = getBestBarcode();
21143
21207
  var recaptureScore = (_a = recaptureBarcode === null || recaptureBarcode === void 0 ? void 0 : recaptureBarcode.score) !== null && _a !== void 0 ? _a : null;
21144
21208
  var improved = !!bestBarcode && bestBarcode.score > state.initialBarcodeScore;
21209
+ log("[IdCaptureWizard] Recapture timeout debug: recaptureBarcode=".concat(!!recaptureBarcode, ", recaptureScore=").concat(recaptureScore, ", bestBarcode=").concat(!!bestBarcode, ", bestBarcodeScore=").concat(bestBarcode === null || bestBarcode === void 0 ? void 0 : bestBarcode.score, ", initialScore=").concat(state.initialBarcodeScore, ", improved=").concat(improved));
21145
21210
  // Store the recapture score for diagnostic purposes
21211
+ // Always use actual recapture score (even if worse than initial) so debug info
21212
+ // shows what was actually captured during each sequence
21146
21213
  dispatchIdCaptureAction({
21147
21214
  type: 'barcodeRecaptureScoreUpdated',
21148
21215
  payload: {
21149
- recaptureBarcodeScore: improved ? bestBarcode.score : recaptureScore !== null && recaptureScore !== void 0 ? recaptureScore : state.initialBarcodeScore
21216
+ recaptureBarcodeScore: recaptureScore
21150
21217
  }
21151
21218
  });
21152
21219
  // Store the recapture barcode image if we found one