@trustchex/react-native-sdk 1.374.0 → 1.381.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (35) hide show
  1. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +0 -9
  2. package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +636 -301
  3. package/ios/Camera/TrustchexCameraView.swift +8 -8
  4. package/ios/OpenCV/OpenCVHelper.h +0 -7
  5. package/ios/OpenCV/OpenCVHelper.mm +0 -60
  6. package/ios/OpenCV/OpenCVModule.h +0 -4
  7. package/ios/OpenCV/OpenCVModule.mm +440 -358
  8. package/lib/module/Shared/Components/DebugOverlay.js +541 -0
  9. package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +44 -0
  10. package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +270 -0
  11. package/lib/module/Shared/Components/IdentityDocumentCamera.js +679 -1701
  12. package/lib/module/Shared/Components/IdentityDocumentCamera.types.js +3 -0
  13. package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +273 -0
  14. package/lib/module/version.js +1 -1
  15. package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts +30 -0
  16. package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts.map +1 -0
  17. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +35 -0
  18. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -0
  19. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -56
  20. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  21. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +88 -0
  22. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -0
  23. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +116 -0
  24. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -0
  25. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +93 -0
  26. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -0
  27. package/lib/typescript/src/version.d.ts +1 -1
  28. package/package.json +1 -1
  29. package/src/Shared/Components/DebugOverlay.tsx +656 -0
  30. package/src/Shared/Components/IdentityDocumentCamera.constants.ts +44 -0
  31. package/src/Shared/Components/IdentityDocumentCamera.flows.ts +342 -0
  32. package/src/Shared/Components/IdentityDocumentCamera.tsx +1065 -2462
  33. package/src/Shared/Components/IdentityDocumentCamera.types.ts +136 -0
  34. package/src/Shared/Components/IdentityDocumentCamera.utils.ts +364 -0
  35. package/src/version.ts +1 -1
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+
3
+ export {};
@@ -0,0 +1,273 @@
1
+ "use strict";
2
+
3
+ import { Dimensions } from 'react-native';
4
+ import { SIGNATURE_REGEX, PASSPORT_MRZ_PATTERN } from "./IdentityDocumentCamera.constants.js";
5
+ import { debugLog, isDebugEnabled } from "../Libs/debug.utils.js";
6
+
7
+ /**
8
+ * Frame-to-screen coordinate transform using FILL_CENTER scaling
9
+ */
10
+ export function getFrameToScreenTransform(frameWidth, frameHeight) {
11
+ const screen = Dimensions.get('window');
12
+ const frameAspect = frameWidth / frameHeight;
13
+ const screenAspect = screen.width / screen.height;
14
+ let scale;
15
+ let offsetX = 0;
16
+ let offsetY = 0;
17
+ if (frameAspect > screenAspect) {
18
+ scale = screen.height / frameHeight;
19
+ offsetX = (frameWidth * scale - screen.width) / 2;
20
+ } else {
21
+ scale = screen.width / frameWidth;
22
+ offsetY = (frameHeight * scale - screen.height) / 2;
23
+ }
24
+ return {
25
+ scale,
26
+ offsetX,
27
+ offsetY,
28
+ screen
29
+ };
30
+ }
31
+
32
+ /**
33
+ * Compute scan area bounds in frame coordinates
34
+ */
35
+ export function getScanAreaBounds(frameWidth, frameHeight) {
36
+ const {
37
+ scale,
38
+ offsetX,
39
+ offsetY,
40
+ screen
41
+ } = getFrameToScreenTransform(frameWidth, frameHeight);
42
+ const scanLeft = (screen.width * 0.05 + offsetX) / scale;
43
+ const scanTop = (screen.height * 0.36 + offsetY) / scale;
44
+ const scanRight = (screen.width * 0.95 + offsetX) / scale;
45
+ const scanBottom = (screen.height * 0.64 + offsetY) / scale;
46
+ const isInsideScan = (x, y, w, h) => x >= scanLeft && y >= scanTop && x + w <= scanRight && y + h <= scanBottom;
47
+ return {
48
+ scanLeft,
49
+ scanTop,
50
+ scanRight,
51
+ scanBottom,
52
+ isInsideScan
53
+ };
54
+ }
55
+
56
+ /**
57
+ * Transform frame-space bounds to screen-space bounds
58
+ */
59
+ export function transformBoundsToScreen(bounds, scale, offsetX, offsetY) {
60
+ return {
61
+ x: bounds.x * scale - offsetX,
62
+ y: bounds.y * scale - offsetY,
63
+ width: bounds.width * scale,
64
+ height: bounds.height * scale
65
+ };
66
+ }
67
+
68
+ /**
69
+ * Unified status message logic used by both voice guidance and render text.
70
+ * Returns the appropriate i18n key arguments for the current scan state.
71
+ */
72
+ export function getStatusMessage(nextStep, status, detectedDocumentType, isBrightnessLow, isFrameBlurry, allElementsDetected, elementsOutsideScanArea, t) {
73
+ if (nextStep === 'COMPLETED') {
74
+ return t('identityDocumentCamera.scanCompleted');
75
+ }
76
+ if (status === 'INCORRECT') {
77
+ if (nextStep === 'SCAN_ID_FRONT_OR_PASSPORT') {
78
+ return t('identityDocumentCamera.alignIDFront');
79
+ }
80
+ if (nextStep === 'SCAN_ID_BACK') {
81
+ return t('identityDocumentCamera.alignIDBack');
82
+ }
83
+ if (nextStep === 'SCAN_HOLOGRAM') {
84
+ return t('identityDocumentCamera.alignIDFront');
85
+ }
86
+ return t('identityDocumentCamera.alignPhotoSide');
87
+ }
88
+ if (isBrightnessLow) {
89
+ return t('identityDocumentCamera.lowBrightness');
90
+ }
91
+ if (isFrameBlurry) {
92
+ return t('identityDocumentCamera.avoidBlur');
93
+ }
94
+ if (status === 'SCANNING' && allElementsDetected && elementsOutsideScanArea.length === 0) {
95
+ if (nextStep === 'SCAN_ID_BACK') {
96
+ return t('identityDocumentCamera.idCardBackDetected');
97
+ }
98
+ if (detectedDocumentType === 'PASSPORT') {
99
+ return t('identityDocumentCamera.passportDetected');
100
+ }
101
+ if (detectedDocumentType === 'ID_FRONT') {
102
+ return t('identityDocumentCamera.idCardFrontDetected');
103
+ }
104
+ if (nextStep === 'SCAN_HOLOGRAM') {
105
+ return t('identityDocumentCamera.alignHologram');
106
+ }
107
+ return t('identityDocumentCamera.readingDocument');
108
+ }
109
+ if (elementsOutsideScanArea.length > 0) {
110
+ return t('identityDocumentCamera.centerDocument');
111
+ }
112
+ if ((status === 'SCANNING' || status === 'SEARCHING') && !allElementsDetected) {
113
+ if (nextStep === 'SCAN_ID_BACK') {
114
+ return t('identityDocumentCamera.alignIDBack');
115
+ }
116
+ if (nextStep === 'SCAN_ID_FRONT_OR_PASSPORT') {
117
+ if (detectedDocumentType === 'PASSPORT') {
118
+ return t('identityDocumentCamera.alignPassport');
119
+ }
120
+ if (detectedDocumentType === 'ID_FRONT') {
121
+ return t('identityDocumentCamera.alignIDFront');
122
+ }
123
+ return t('identityDocumentCamera.alignPhotoSide');
124
+ }
125
+ if (nextStep === 'SCAN_HOLOGRAM') {
126
+ return t('identityDocumentCamera.alignHologram');
127
+ }
128
+ return t('identityDocumentCamera.readingDocument');
129
+ }
130
+
131
+ // Default fallback
132
+ if (nextStep === 'SCAN_ID_FRONT_OR_PASSPORT') {
133
+ return status === 'SCANNING' ? t('identityDocumentCamera.readingDocument') : t('identityDocumentCamera.alignPhotoSide');
134
+ }
135
+ if (nextStep === 'SCAN_HOLOGRAM') {
136
+ return t('identityDocumentCamera.alignHologram');
137
+ }
138
+ if (nextStep === 'SCAN_ID_BACK') {
139
+ return status === 'SCANNING' ? t('identityDocumentCamera.readingDocument') : t('identityDocumentCamera.alignIDBackSide');
140
+ }
141
+ return '';
142
+ }
143
+
144
+ /**
145
+ * Calculate angle from two points in degrees
146
+ */
147
+ export function angleBetweenPoints(p1, p2) {
148
+ const dx = p2.x - p1.x;
149
+ const dy = p2.y - p1.y;
150
+ return Math.atan2(dy, dx) * (180 / Math.PI);
151
+ }
152
+
153
+ /**
154
+ * Calculate distance between two points
155
+ */
156
+ export function distanceBetweenPoints(p1, p2) {
157
+ const dx = p2.x - p1.x;
158
+ const dy = p2.y - p1.y;
159
+ return Math.sqrt(dx * dx + dy * dy);
160
+ }
161
+
162
+ /**
163
+ * Detect document type based on faces, OCR text, and MRZ fields
164
+ */
165
+ export function detectDocumentType(faces, ocrText, mrzFields, frameWidth, mrzText) {
166
+ // Relaxed signature detection: matches signature/imza variants and OCR errors
167
+ const hasSignatureMatch = SIGNATURE_REGEX.test(ocrText);
168
+ if (isDebugEnabled()) {
169
+ debugLog('IdentityDocumentCamera.utils', '[DocType] Detection', {
170
+ faces: faces.length,
171
+ hasMRZ: !!mrzFields,
172
+ hasMRZText: !!mrzText,
173
+ textLength: ocrText?.length,
174
+ hasSignature: hasSignatureMatch
175
+ });
176
+ }
177
+
178
+ // ID Back: no face + ID MRZ
179
+ if (faces.length === 0 && mrzFields?.documentCode === 'I') {
180
+ return 'ID_BACK';
181
+ }
182
+
183
+ // Passport: face + passport MRZ
184
+ if (faces.length > 0 && mrzFields?.documentCode === 'P') {
185
+ return 'PASSPORT';
186
+ }
187
+
188
+ // Check for PASSPORT MRZ pattern BEFORE classifying as ID_FRONT
189
+ // Both passports and ID cards have face + signature, so we MUST check MRZ first
190
+ // Check BOTH parsed mrzText AND raw ocrText — MRZ parsing can fail while
191
+ // the raw OCR still contains P<TUR/P<USA pattern
192
+ const hasPassportMRZPattern = mrzText && mrzText.length > 20 && PASSPORT_MRZ_PATTERN.test(mrzText) || PASSPORT_MRZ_PATTERN.test(ocrText);
193
+ if (hasPassportMRZPattern) {
194
+ // Passport MRZ pattern detected (P<TUR, P<USA, etc.)
195
+ // Even if not fully parsed, this is definitely a passport, not ID card
196
+ return 'PASSPORT';
197
+ }
198
+
199
+ // ID Front: face detected
200
+ // CRITICAL: Only classify as ID_FRONT when we're confident it's NOT a passport
201
+ // This means we must have either:
202
+ // 1. MRZ code 'I' (definitive ID card), OR
203
+ // 2. Face + signature but NO passport MRZ pattern visible
204
+ if (faces.length > 0 && ocrText?.length >= 5) {
205
+ // Filter to card-sized faces only (min 5% of frame width to exclude tiny background faces)
206
+ const cardSizedFaces = frameWidth ? faces.filter(face => face.bounds.width >= frameWidth * 0.05 && face.bounds.height >= frameWidth * 0.05) : faces;
207
+ if (cardSizedFaces.length > 0) {
208
+ // If we have MRZ code 'I', it's definitely an ID card
209
+ if (mrzFields?.documentCode === 'I') {
210
+ return 'ID_FRONT';
211
+ }
212
+
213
+ // If signature present and NO passport MRZ pattern, likely ID_FRONT
214
+ // But we can't be 100% sure yet - passport MRZ might appear in next frames
215
+ const hasSignature = hasSignatureMatch;
216
+ if (hasSignature && !hasPassportMRZPattern) {
217
+ return 'ID_FRONT';
218
+ }
219
+ }
220
+ }
221
+ return 'UNKNOWN';
222
+ }
223
+
224
+ /**
225
+ * Determine the document type to set based on current frame analysis
226
+ * Handles correction of misdetections and passport pattern checking
227
+ */
228
+ export function determineDocumentTypeToSet(documentType, cardSizedFaces, parsedMRZFields, mrzText) {
229
+ // CRITICAL: Passport MRZ always takes precedence over other detections
230
+ const hasPassportMRZ = mrzText && mrzText.length > 20 && PASSPORT_MRZ_PATTERN.test(mrzText) || parsedMRZFields?.documentCode === 'P';
231
+ if (hasPassportMRZ) {
232
+ return 'PASSPORT';
233
+ }
234
+
235
+ // After passport MRZ check, accept the detected type directly
236
+ if (documentType === 'PASSPORT') return 'PASSPORT';
237
+ if (documentType === 'ID_FRONT') return 'ID_FRONT';
238
+ return 'UNKNOWN';
239
+ }
240
+
241
+ /**
242
+ * Compare MRZ field values (ignore raw text variations)
243
+ */
244
+ export function areMRZFieldsEqual(fields1, fields2) {
245
+ if (!fields1 || !fields2) return false;
246
+ // Compare critical fields that define document identity
247
+ return fields1.documentNumber === fields2.documentNumber && fields1.birthDate === fields2.birthDate && fields1.expirationDate === fields2.expirationDate && fields1.firstName === fields2.firstName && fields1.lastName === fields2.lastName && fields1.issuingState === fields2.issuingState;
248
+ }
249
+
250
+ /**
251
+ * Check if all required MRZ fields are present
252
+ */
253
+ export function hasRequiredMRZFields(fields) {
254
+ return !!fields?.firstName && !!fields?.lastName && !!fields?.documentNumber && !!fields?.birthDate;
255
+ }
256
+
257
+ /**
258
+ * Validate if face position has changed within acceptable tolerance
259
+ * Returns true if position is valid (within tolerance)
260
+ */
261
+ export function validateFacePosition(currentBounds, referenceBounds, isHologramStep) {
262
+ const xDiff = Math.abs(currentBounds.x - referenceBounds.x);
263
+ const yDiff = Math.abs(currentBounds.y - referenceBounds.y);
264
+ const widthDiff = Math.abs(currentBounds.width - referenceBounds.width);
265
+ const heightDiff = Math.abs(currentBounds.height - referenceBounds.height);
266
+
267
+ // Use looser tolerance during hologram step since flash toggling causes position jitter
268
+ const tolerance = isHologramStep ? 0.5 : 0.2;
269
+ const xTolerance = referenceBounds.width * tolerance;
270
+ const yTolerance = referenceBounds.height * tolerance;
271
+ const sizeTolerance = referenceBounds.width * tolerance;
272
+ return xDiff <= xTolerance && yDiff <= yTolerance && widthDiff <= sizeTolerance && heightDiff <= sizeTolerance;
273
+ }
@@ -2,4 +2,4 @@
2
2
 
3
3
  // This file is auto-generated. Do not edit manually.
4
4
  // Version is synced from package.json during build.
5
- export const SDK_VERSION = '1.374.0';
5
+ export const SDK_VERSION = '1.381.0';
@@ -0,0 +1,30 @@
1
+ import React from 'react';
2
+ import type { ScanStep, ScanStatus, DocumentType, BoundsWithRotation, BoundsWithAngle } from './IdentityDocumentCamera.types';
3
+ export interface DebugOverlayProps {
4
+ nextStep: ScanStep;
5
+ status: ScanStatus;
6
+ detectedDocumentType: DocumentType;
7
+ isBrightnessLow: boolean;
8
+ isFrameBlurry: boolean;
9
+ isTorchOn: boolean;
10
+ documentPlaneBounds: BoundsWithRotation | null;
11
+ secondaryFaceBounds: BoundsWithRotation | null;
12
+ barcodeBounds: BoundsWithAngle | null;
13
+ mrzBounds: BoundsWithAngle | null;
14
+ signatureBounds: BoundsWithAngle | null;
15
+ currentFaceImage?: string;
16
+ currentSecondaryFaceImage?: string;
17
+ currentHologramImage?: string;
18
+ currentHologramMaskImage?: string;
19
+ latestHologramFaceImage?: string;
20
+ hologramImageCount: number;
21
+ allElementsDetected: boolean;
22
+ elementsOutsideScanArea: string[];
23
+ }
24
+ declare const DebugOverlay: React.NamedExoticComponent<DebugOverlayProps>;
25
+ export interface TestModePanelProps {
26
+ mrzText: string;
27
+ }
28
+ export declare const TestModePanel: React.NamedExoticComponent<TestModePanelProps>;
29
+ export default DebugOverlay;
30
+ //# sourceMappingURL=DebugOverlay.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"DebugOverlay.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/DebugOverlay.tsx"],"names":[],"mappings":"AACA,OAAO,KAAK,MAAM,OAAO,CAAC;AAG1B,OAAO,KAAK,EACV,QAAQ,EACR,UAAU,EACV,YAAY,EACZ,kBAAkB,EAClB,eAAe,EAChB,MAAM,gCAAgC,CAAC;AA2PxC,MAAM,WAAW,iBAAiB;IAChC,QAAQ,EAAE,QAAQ,CAAC;IACnB,MAAM,EAAE,UAAU,CAAC;IACnB,oBAAoB,EAAE,YAAY,CAAC;IACnC,eAAe,EAAE,OAAO,CAAC;IACzB,aAAa,EAAE,OAAO,CAAC;IACvB,SAAS,EAAE,OAAO,CAAC;IACnB,mBAAmB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC/C,mBAAmB,EAAE,kBAAkB,GAAG,IAAI,CAAC;IAC/C,aAAa,EAAE,eAAe,GAAG,IAAI,CAAC;IACtC,SAAS,EAAE,eAAe,GAAG,IAAI,CAAC;IAClC,eAAe,EAAE,eAAe,GAAG,IAAI,CAAC;IACxC,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,yBAAyB,CAAC,EAAE,MAAM,CAAC;IACnC,oBAAoB,CAAC,EAAE,MAAM,CAAC;IAC9B,wBAAwB,CAAC,EAAE,MAAM,CAAC;IAClC,uBAAuB,CAAC,EAAE,MAAM,CAAC;IACjC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,mBAAmB,EAAE,OAAO,CAAC;IAC7B,uBAAuB,EAAE,MAAM,EAAE,CAAC;CACnC;AAED,QAAA,MAAM,YAAY,+CAyThB,CAAC;AAIH,MAAM,WAAW,kBAAkB;IACjC,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,eAAO,MAAM,aAAa,gDAiDxB,CAAC;AAEH,eAAe,YAAY,CAAC"}
@@ -0,0 +1,35 @@
1
+ export declare const HOLOGRAM_IMAGE_COUNT = 16;
2
+ export declare const HOLOGRAM_DETECTION_THRESHOLD = 1000;
3
+ export declare const HOLOGRAM_DETECTION_RETRY_COUNT = 3;
4
+ export declare const HOLOGRAM_CAPTURE_INTERVAL = 250;
5
+ export declare const HOLOGRAM_MAX_FRAMES_WITHOUT_FACE = 30;
6
+ export declare const MIN_BRIGHTNESS_THRESHOLD = 45;
7
+ export declare const MAX_BRIGHTNESS_THRESHOLD = 210;
8
+ export declare const MAX_CONSECUTIVE_QUALITY_FAILURES = 30;
9
+ export declare const FACE_EDGE_MARGIN_PERCENT = 0.08;
10
+ export declare const MIN_CARD_FACE_SIZE_PERCENT = 0.05;
11
+ export declare const MIN_MLI_FACE_SIZE_PERCENT = 0.01;
12
+ export declare const REQUIRED_CONSISTENT_MRZ_READS = 2;
13
+ export declare const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
14
+ export declare const SIGNATURE_REGEX: RegExp;
15
+ export declare const SIGNATURE_TEXT_REGEX: RegExp;
16
+ export declare const MRZ_BLOCK_PATTERN: RegExp;
17
+ export declare const PASSPORT_MRZ_PATTERN: RegExp;
18
+ export declare const MIN_SECURITY_FEATURES_REQUIRED = 4;
19
+ export declare const SECURITY_FEATURE_NAMES: {
20
+ readonly icao_photo: "ICAO Uyumlu Fotoğraf (ICAO Compliant Photo)";
21
+ readonly barcode: "Barkod (Barcode)";
22
+ readonly hologram: "DOVID/OVD (Hologram)";
23
+ readonly wet_signature: "Islak İmza (Wet Signature)";
24
+ readonly guilloche: "Giyoş (Guilloche Pattern)";
25
+ readonly rainbow_print: "Gökkuşağı Baskı (Rainbow Print)";
26
+ readonly ovi: "Optik Değişken Mürekkep (OVI)";
27
+ readonly latent_image: "Gizli Görüntü (Latent Image)";
28
+ readonly microtext: "Mikro Yazı (Microtext)";
29
+ };
30
+ export declare const FACE_SHAPE_MATCH_THRESHOLD = 0.5;
31
+ export declare const FACE_VISUAL_SIMILARITY_THRESHOLD = 0.5;
32
+ export declare const FACE_ASPECT_RATIO_TOLERANCE = 0.15;
33
+ export declare const FACE_SIZE_RATIO_MIN = 0.7;
34
+ export declare const FACE_SIZE_RATIO_MAX = 1.3;
35
+ //# sourceMappingURL=IdentityDocumentCamera.constants.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdentityDocumentCamera.constants.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.constants.ts"],"names":[],"mappings":"AAAA,eAAO,MAAM,oBAAoB,KAAK,CAAC;AACvC,eAAO,MAAM,4BAA4B,OAAO,CAAC;AACjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,yBAAyB,MAAM,CAAC;AAC7C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AAEnD,eAAO,MAAM,wBAAwB,KAAK,CAAC;AAC3C,eAAO,MAAM,wBAAwB,MAAM,CAAC;AAC5C,eAAO,MAAM,gCAAgC,KAAK,CAAC;AACnD,eAAO,MAAM,wBAAwB,OAAO,CAAC;AAC7C,eAAO,MAAM,0BAA0B,OAAO,CAAC;AAC/C,eAAO,MAAM,yBAAyB,OAAO,CAAC;AAE9C,eAAO,MAAM,6BAA6B,IAAI,CAAC;AAC/C,eAAO,MAAM,sCAAsC,IAAI,CAAC;AAExD,eAAO,MAAM,eAAe,QAAkC,CAAC;AAC/D,eAAO,MAAM,oBAAoB,QAAyB,CAAC;AAC3D,eAAO,MAAM,iBAAiB,QAAsB,CAAC;AACrD,eAAO,MAAM,oBAAoB,QAAe,CAAC;AAIjD,eAAO,MAAM,8BAA8B,IAAI,CAAC;AAChD,eAAO,MAAM,sBAAsB;;;;;;;;;;CAUzB,CAAC;AAKX,eAAO,MAAM,0BAA0B,MAAM,CAAC;AAC9C,eAAO,MAAM,gCAAgC,MAAM,CAAC;AACpD,eAAO,MAAM,2BAA2B,OAAO,CAAC;AAChD,eAAO,MAAM,mBAAmB,MAAM,CAAC;AACvC,eAAO,MAAM,mBAAmB,MAAM,CAAC"}
@@ -1,59 +1,6 @@
1
- import type { MRZFields } from '../Types/mrzFields';
2
- export type DocumentScannedData = {
3
- documentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN';
4
- image: string;
5
- faceImage?: string;
6
- secondaryFaceImage?: string;
7
- hologramImage?: string;
8
- barcodeValue?: string;
9
- mrzText?: string;
10
- mrzFields?: MRZFields;
11
- };
12
- export type BlockText = {
13
- blocks: BlocksData[];
14
- resultText: string;
15
- mrzOnlyText?: string;
16
- };
17
- type BlocksData = {
18
- blockFrame: FrameType;
19
- blockCornerPoints: CornerPointsType;
20
- lines: LinesData;
21
- blockLanguages: string[] | [];
22
- blockText: string;
23
- };
24
- type CornerPointsType = [{
25
- x: number;
26
- y: number;
27
- }];
28
- type FrameType = {
29
- boundingCenterX: number;
30
- boundingCenterY: number;
31
- height: number;
32
- width: number;
33
- x: number;
34
- y: number;
35
- };
36
- type LinesData = [
37
- lineCornerPoints: CornerPointsType,
38
- elements: ElementsData,
39
- lineFrame: FrameType,
40
- lineLanguages: string[] | [],
41
- lineText: string
42
- ];
43
- type ElementsData = [
44
- elementCornerPoints: CornerPointsType,
45
- elementFrame: FrameType,
46
- elementText: string
47
- ];
48
- export type PhotoOptions = {
49
- uri: string;
50
- orientation?: 'landscapeRight' | 'portrait' | 'portraitUpsideDown' | 'landscapeLeft';
51
- };
52
- export interface IdentityDocumentCameraProps {
53
- onlyMRZScan: boolean;
54
- onIdentityDocumentScanned: (scannedData: DocumentScannedData) => void;
55
- testMode?: boolean;
56
- }
1
+ import type { DocumentScannedData, BlockText, IdentityDocumentCameraProps } from './IdentityDocumentCamera.types';
2
+ export type { DocumentScannedData, BlockText, IdentityDocumentCameraProps };
3
+ export type { PhotoOptions } from './IdentityDocumentCamera.types';
57
4
  declare const IdentityDocumentCamera: ({ onlyMRZScan, onIdentityDocumentScanned, testMode, }: IdentityDocumentCameraProps) => import("react/jsx-runtime").JSX.Element;
58
5
  export default IdentityDocumentCamera;
59
6
  //# sourceMappingURL=IdentityDocumentCamera.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AA0BA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAiBpD,MAAM,MAAM,mBAAmB,GAAG;IAChC,YAAY,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,CAAC;IAC9D,KAAK,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,SAAS,CAAC;CACvB,CAAC;AAEF,MAAM,MAAM,SAAS,GAAG;IACtB,MAAM,EAAE,UAAU,EAAE,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,KAAK,UAAU,GAAG;IAChB,UAAU,EAAE,SAAS,CAAC;IACtB,iBAAiB,EAAE,gBAAgB,CAAC;IACpC,KAAK,EAAE,SAAS,CAAC;IACjB,cAAc,EAAE,MAAM,EAAE,GAAG,EAAE,CAAC;IAC9B,SAAS,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,KAAK,gBAAgB,GAAG,CAAC;IAAE,CAAC,EAAE,MAAM,CAAC;IAAC,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC,CAAC;AAEnD,KAAK,SAAS,GAAG;IACf,eAAe,EAAE,MAAM,CAAC;IACxB,eAAe,EAAE,MAAM,CAAC;IACxB,MAAM,EAAE,MAAM,CAAC;IACf,KAAK,EAAE,MAAM,CAAC;IACd,CAAC,EAAE,MAAM,CAAC;IACV,CAAC,EAAE,MAAM,CAAC;CACX,CAAC;AAEF,KAAK,SAAS,GAAG;IACf,gBAAgB,EAAE,gBAAgB;IAClC,QAAQ,EAAE,YAAY;IACtB,SAAS,EAAE,SAAS;IACpB,aAAa,EAAE,MAAM,EAAE,GAAG,EAAE;IAC5B,QAAQ,EAAE,MAAM;CACjB,CAAC;AAEF,KAAK,YAAY,GAAG;IAClB,mBAAmB,EAAE,gBAAgB;IACrC,YAAY,EAAE,SAAS;IACvB,WAAW,EAAE,MAAM;CACpB,CAAC;AAEF,MAAM,MAAM,YAAY,GAAG;IACzB,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,CAAC,EACR,gBAAgB,GAChB,UAAU,GACV,oBAAoB,GACpB,eAAe,CAAC;CACrB,CAAC;AAEF,MAAM,WAAW,2BAA2B;IAC1C,WAAW,EAAE,OAAO,CAAC;IACrB,yBAAyB,EAAE,CAAC,WAAW,EAAE,mBAAmB,KAAK,IAAI,CAAC;IACtE,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB;AA2BD,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CAylH7B,CAAC;AAgLF,eAAe,sBAAsB,CAAC"}
1
+ {"version":3,"file":"IdentityDocumentCamera.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.tsx"],"names":[],"mappings":"AAsEA,OAAO,KAAK,EACV,mBAAmB,EACnB,SAAS,EACT,2BAA2B,EAK5B,MAAM,gCAAgC,CAAC;AAGxC,YAAY,EAAE,mBAAmB,EAAE,SAAS,EAAE,2BAA2B,EAAE,CAAC;AAC5E,YAAY,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAMnE,QAAA,MAAM,sBAAsB,GAAI,uDAI7B,2BAA2B,4CAg0E7B,CAAC;AAiIF,eAAe,sBAAsB,CAAC"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Document scanning flow handlers
3
+ *
4
+ * This file contains the logic for handling different document type flows:
5
+ *
6
+ * KEY DISTINGUISHING FEATURES:
7
+ * =============================
8
+ * PASSPORT: Has MRZ on FRONT with pattern P<XXX (e.g., P<TUR, P<USA)
9
+ * ID CARD: Has NO MRZ on front; MRZ only on BACK with code 'I'
10
+ *
11
+ * IMPORTANT: Both passports and ID cards have signature sections!
12
+ * Signature presence is NOT a distinguishing feature between document types.
13
+ * The ONLY reliable distinguisher is the passport MRZ pattern (P<XXX).
14
+ *
15
+ * PASSPORT FLOW:
16
+ * 1. SCAN_ID_FRONT_OR_PASSPORT: Detect face + MRZ with code 'P' (passport MRZ pattern)
17
+ * 2. SCAN_HOLOGRAM (optional, skipped if onlyMRZScan): Collect hologram images
18
+ * 3. COMPLETED: No back side for passports
19
+ *
20
+ * ID CARD FLOW:
21
+ * 1. SCAN_ID_FRONT_OR_PASSPORT: Detect face + NO passport MRZ pattern
22
+ * 2. SCAN_HOLOGRAM: Collect hologram images from front
23
+ * 3. SCAN_ID_BACK: Detect MRZ with code 'I' + barcode
24
+ * 4. COMPLETED
25
+ *
26
+ * ID BACK DETECTION:
27
+ * - Only occurs during SCAN_ID_BACK step
28
+ * - No face, has MRZ with code 'I'
29
+ */
30
+ import type { Face } from './IdentityDocumentCamera.types';
31
+ import type { MRZFields } from '../Types/mrzFields';
32
+ export interface PassportFlowResult {
33
+ shouldProceed: boolean;
34
+ reason?: string;
35
+ nextAction?: 'WAIT_FOR_ELEMENTS' | 'WAIT_FOR_MRZ' | 'PROCEED_TO_HOLOGRAM' | 'PROCEED_TO_COMPLETED';
36
+ }
37
+ export interface IDFrontFlowResult {
38
+ shouldProceed: boolean;
39
+ reason?: string;
40
+ nextAction?: 'WAIT_FOR_ELEMENTS' | 'REJECT_AS_PASSPORT' | 'PROCEED_TO_HOLOGRAM';
41
+ }
42
+ export interface IDBackFlowResult {
43
+ shouldProceed: boolean;
44
+ reason?: string;
45
+ nextAction?: 'WAIT_FOR_MRZ' | 'WAIT_FOR_BARCODE' | 'PROCEED_TO_COMPLETED';
46
+ }
47
+ /**
48
+ * Handle PASSPORT flow during SCAN_ID_FRONT_OR_PASSPORT step
49
+ *
50
+ * Requirements:
51
+ * - Face must be detected AND captured
52
+ * - MRZ must be present with document code 'P'
53
+ * - MRZ must be stable (consistent reads) even in normal mode
54
+ * - All required MRZ fields must be present
55
+ */
56
+ export declare function handlePassportFlow(faces: Face[], mrzText: string | null, mrzFields: MRZFields | undefined, mrzStableAndValid: boolean, onlyMRZScan: boolean, hasRequiredFields: boolean, faceCaptured: boolean): PassportFlowResult;
57
+ /**
58
+ * Handle ID CARD FRONT flow during SCAN_ID_FRONT_OR_PASSPORT step
59
+ *
60
+ * CRITICAL: The KEY distinguishing feature is the ABSENCE of passport MRZ pattern.
61
+ * Both passports and ID cards have signatures, so signature is NOT used to distinguish
62
+ * between document types. Signature is only checked to ensure we're viewing the front
63
+ * side of the document (not the back).
64
+ *
65
+ * Requirements:
66
+ * - Face must be detected (front side indicator)
67
+ * - Must NOT have passport MRZ pattern (P<XXX) - this is the CRITICAL check
68
+ * - Signature text should be present (confirms front side, or retry threshold reached)
69
+ * - If MRZ code is present, it must be 'I' (ID card) not 'P' (passport)
70
+ */
71
+ export declare function handleIDFrontFlow(faces: Face[], text: string, mrzText: string | null, mrzFields: MRZFields | undefined, retryCount: number): IDFrontFlowResult;
72
+ /**
73
+ * Handle ID CARD BACK flow during SCAN_ID_BACK step
74
+ *
75
+ * Requirements:
76
+ * - MRZ must be present, valid, stable, and have all required fields
77
+ * - Barcode must be in frame (unless onlyMRZScan)
78
+ * - Barcode must match MRZ optional1 serial number (lenient comparison)
79
+ */
80
+ export declare function handleIDBackFlow(mrzText: string | null, mrzFields: MRZFields | undefined, mrzValid: boolean, mrzStableAndValid: boolean, hasRequiredFields: boolean, barcodeValue: string | undefined, onlyMRZScan: boolean): IDBackFlowResult;
81
+ /**
82
+ * Determine next step after SCAN_HOLOGRAM based on document type
83
+ *
84
+ * PASSPORT: → COMPLETED (no back side)
85
+ * ID CARD: → SCAN_ID_BACK
86
+ */
87
+ export declare function getNextStepAfterHologram(detectedDocumentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', currentFrameDocType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN', mrzDocCode: string | undefined): 'COMPLETED' | 'SCAN_ID_BACK';
88
+ //# sourceMappingURL=IdentityDocumentCamera.flows.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdentityDocumentCamera.flows.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.flows.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAEH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gCAAgC,CAAC;AAC3D,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,oBAAoB,CAAC;AAUpD,MAAM,WAAW,kBAAkB;IACjC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,cAAc,GACd,qBAAqB,GACrB,sBAAsB,CAAC;CAC5B;AAED,MAAM,WAAW,iBAAiB;IAChC,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EACP,mBAAmB,GACnB,oBAAoB,GACpB,qBAAqB,CAAC;CAC3B;AAED,MAAM,WAAW,gBAAgB;IAC/B,aAAa,EAAE,OAAO,CAAC;IACvB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,UAAU,CAAC,EAAE,cAAc,GAAG,kBAAkB,GAAG,sBAAsB,CAAC;CAC3E;AAED;;;;;;;;GAQG;AACH,wBAAgB,kBAAkB,CAChC,KAAK,EAAE,IAAI,EAAE,EACb,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,iBAAiB,EAAE,OAAO,EAC1B,WAAW,EAAE,OAAO,EACpB,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,OAAO,GACpB,kBAAkB,CAgEpB;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAC/B,KAAK,EAAE,IAAI,EAAE,EACb,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,UAAU,EAAE,MAAM,GACjB,iBAAiB,CAuEnB;AAED;;;;;;;GAOG;AACH,wBAAgB,gBAAgB,CAC9B,OAAO,EAAE,MAAM,GAAG,IAAI,EACtB,SAAS,EAAE,SAAS,GAAG,SAAS,EAChC,QAAQ,EAAE,OAAO,EACjB,iBAAiB,EAAE,OAAO,EAC1B,iBAAiB,EAAE,OAAO,EAC1B,YAAY,EAAE,MAAM,GAAG,SAAS,EAChC,WAAW,EAAE,OAAO,GACnB,gBAAgB,CA2DlB;AAED;;;;;GAKG;AACH,wBAAgB,wBAAwB,CACtC,oBAAoB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACrE,mBAAmB,EAAE,UAAU,GAAG,SAAS,GAAG,UAAU,GAAG,SAAS,EACpE,UAAU,EAAE,MAAM,GAAG,SAAS,GAC7B,WAAW,GAAG,cAAc,CAY9B"}
@@ -0,0 +1,116 @@
1
+ export type SecurityFeature = 'icao_photo' | 'barcode' | 'hologram' | 'wet_signature' | 'guilloche' | 'rainbow_print' | 'ovi' | 'latent_image' | 'microtext';
2
+ export type DocumentScannedData = {
3
+ documentType: 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN';
4
+ image: string;
5
+ faceImage?: string;
6
+ secondaryFaceImage?: string;
7
+ hologramImage?: string;
8
+ barcodeValue?: string;
9
+ mrzText?: string;
10
+ mrzFields?: MRZFields;
11
+ securityFeaturesDetected?: SecurityFeature[];
12
+ documentTiltValidated?: boolean;
13
+ interactiveTouchValidated?: boolean;
14
+ serialNumberVerified?: boolean;
15
+ transitionPointsValidated?: boolean;
16
+ };
17
+ export type BlockText = {
18
+ blocks: BlocksData[];
19
+ resultText: string;
20
+ mrzOnlyText?: string;
21
+ };
22
+ export type BlocksData = {
23
+ blockFrame: FrameType;
24
+ blockCornerPoints: CornerPointsType;
25
+ lines: LinesData;
26
+ blockLanguages: string[] | [];
27
+ blockText: string;
28
+ };
29
+ export type CornerPointsType = [{
30
+ x: number;
31
+ y: number;
32
+ }];
33
+ export type FrameType = {
34
+ boundingCenterX: number;
35
+ boundingCenterY: number;
36
+ height: number;
37
+ width: number;
38
+ x: number;
39
+ y: number;
40
+ };
41
+ export type LinesData = [
42
+ lineCornerPoints: CornerPointsType,
43
+ elements: ElementsData,
44
+ lineFrame: FrameType,
45
+ lineLanguages: string[] | [],
46
+ lineText: string
47
+ ];
48
+ export type ElementsData = [
49
+ elementCornerPoints: CornerPointsType,
50
+ elementFrame: FrameType,
51
+ elementText: string
52
+ ];
53
+ export type PhotoOptions = {
54
+ uri: string;
55
+ orientation?: 'landscapeRight' | 'portrait' | 'portraitUpsideDown' | 'landscapeLeft';
56
+ };
57
+ export interface IdentityDocumentCameraProps {
58
+ onlyMRZScan: boolean;
59
+ onIdentityDocumentScanned: (scannedData: DocumentScannedData) => void;
60
+ testMode?: boolean;
61
+ }
62
+ export interface Face {
63
+ bounds: {
64
+ x: number;
65
+ y: number;
66
+ width: number;
67
+ height: number;
68
+ };
69
+ rollAngle?: number;
70
+ pitchAngle?: number;
71
+ yawAngle?: number;
72
+ leftEyeOpenProbability?: number;
73
+ rightEyeOpenProbability?: number;
74
+ smilingProbability?: number;
75
+ }
76
+ export interface Barcode {
77
+ rawValue: string;
78
+ displayValue: string;
79
+ format: number;
80
+ boundingBox: {
81
+ left: number;
82
+ top: number;
83
+ right: number;
84
+ bottom: number;
85
+ };
86
+ cornerPoints: Array<{
87
+ x: number;
88
+ y: number;
89
+ }>;
90
+ value?: string;
91
+ }
92
+ import type { MRZFields } from '../Types/mrzFields';
93
+ export type ScanStep = 'SCAN_ID_FRONT_OR_PASSPORT' | 'SCAN_ID_BACK' | 'SCAN_HOLOGRAM' | 'COMPLETED';
94
+ export type ScanStatus = 'SEARCHING' | 'SCANNING' | 'SCANNED' | 'INCORRECT';
95
+ export type DocumentType = 'ID_FRONT' | 'ID_BACK' | 'PASSPORT' | 'UNKNOWN';
96
+ export type CompletedStep = 'SCAN_ID_FRONT_OR_PASSPORT' | 'SCAN_ID_BACK' | 'SCAN_HOLOGRAM' | null;
97
+ export type BoundsWithRotation = {
98
+ x: number;
99
+ y: number;
100
+ width: number;
101
+ height: number;
102
+ rollAngle?: number;
103
+ cropPadding?: number;
104
+ };
105
+ export type BoundsWithAngle = {
106
+ x: number;
107
+ y: number;
108
+ width: number;
109
+ height: number;
110
+ angle?: number;
111
+ corners?: Array<{
112
+ x: number;
113
+ y: number;
114
+ }>;
115
+ };
116
+ //# sourceMappingURL=IdentityDocumentCamera.types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"IdentityDocumentCamera.types.d.ts","sourceRoot":"","sources":["../../../../../src/Shared/Components/IdentityDocumentCamera.types.ts"],"names":[],"mappings":"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"}