@trustchex/react-native-sdk 1.374.0 → 1.409.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 (137) hide show
  1. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +1 -21
  2. package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +1 -1
  3. package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +636 -301
  4. package/ios/Camera/TrustchexCameraView.swift +9 -20
  5. package/ios/MLKit/MLKitModule.swift +1 -1
  6. package/ios/OpenCV/OpenCVHelper.h +0 -7
  7. package/ios/OpenCV/OpenCVHelper.mm +0 -60
  8. package/ios/OpenCV/OpenCVModule.h +0 -4
  9. package/ios/OpenCV/OpenCVModule.mm +440 -358
  10. package/lib/module/Screens/Debug/BarcodeTestScreen.js +308 -0
  11. package/lib/module/Screens/Debug/MRZTestScreen.js +105 -13
  12. package/lib/module/Screens/Dynamic/ContractAcceptanceScreen.js +49 -29
  13. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +5 -0
  14. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +5 -0
  15. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +26 -6
  16. package/lib/module/Screens/Dynamic/VideoCallScreen.js +676 -0
  17. package/lib/module/Screens/Static/OTPVerificationScreen.js +6 -0
  18. package/lib/module/Screens/Static/QrCodeScanningScreen.js +7 -1
  19. package/lib/module/Screens/Static/ResultScreen.js +27 -13
  20. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +51 -51
  21. package/lib/module/Shared/Animations/video-call.json +1 -0
  22. package/lib/module/Shared/Components/DebugNavigationPanel.js +180 -14
  23. package/lib/module/Shared/Components/DebugOverlay.js +541 -0
  24. package/lib/module/Shared/Components/EIDScanner.js +1 -4
  25. package/lib/module/Shared/Components/IdentityDocumentCamera.constants.js +44 -0
  26. package/lib/module/Shared/Components/IdentityDocumentCamera.flows.js +270 -0
  27. package/lib/module/Shared/Components/IdentityDocumentCamera.js +702 -1703
  28. package/lib/module/Shared/Components/IdentityDocumentCamera.types.js +3 -0
  29. package/lib/module/Shared/Components/IdentityDocumentCamera.utils.js +273 -0
  30. package/lib/module/Shared/Components/NavigationManager.js +15 -3
  31. package/lib/module/Shared/Contexts/AppContext.js +1 -0
  32. package/lib/module/Shared/Libs/SignalingClient.js +128 -0
  33. package/lib/module/Shared/Libs/analytics.utils.js +4 -0
  34. package/lib/module/Shared/Libs/deeplink.utils.js +9 -1
  35. package/lib/module/Shared/Libs/http-client.js +9 -0
  36. package/lib/module/Shared/Libs/promise.utils.js +16 -2
  37. package/lib/module/Shared/Libs/status-bar.utils.js +21 -0
  38. package/lib/module/Shared/Services/DataUploadService.js +294 -0
  39. package/lib/module/Shared/Services/VideoSessionService.js +156 -0
  40. package/lib/module/Shared/Services/WebRTCService.js +510 -0
  41. package/lib/module/Shared/Types/analytics.types.js +2 -0
  42. package/lib/module/Translation/Resources/en.js +20 -0
  43. package/lib/module/Translation/Resources/tr.js +20 -0
  44. package/lib/module/Trustchex.js +10 -0
  45. package/lib/module/version.js +1 -1
  46. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts +3 -0
  47. package/lib/typescript/src/Screens/Debug/BarcodeTestScreen.d.ts.map +1 -0
  48. package/lib/typescript/src/Screens/Debug/MRZTestScreen.d.ts.map +1 -1
  49. package/lib/typescript/src/Screens/Dynamic/ContractAcceptanceScreen.d.ts.map +1 -1
  50. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  51. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  52. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  53. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts +3 -0
  54. package/lib/typescript/src/Screens/Dynamic/VideoCallScreen.d.ts.map +1 -0
  55. package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
  56. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  57. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  58. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  59. package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
  60. package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts +30 -0
  61. package/lib/typescript/src/Shared/Components/DebugOverlay.d.ts.map +1 -0
  62. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  63. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts +35 -0
  64. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.constants.d.ts.map +1 -0
  65. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -56
  66. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  67. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts +88 -0
  68. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.flows.d.ts.map +1 -0
  69. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts +116 -0
  70. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.types.d.ts.map +1 -0
  71. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts +93 -0
  72. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.utils.d.ts.map +1 -0
  73. package/lib/typescript/src/Shared/Components/NavigationManager.d.ts.map +1 -1
  74. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts +1 -0
  75. package/lib/typescript/src/Shared/Contexts/AppContext.d.ts.map +1 -1
  76. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts +24 -0
  77. package/lib/typescript/src/Shared/Libs/SignalingClient.d.ts.map +1 -0
  78. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
  79. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  80. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  81. package/lib/typescript/src/Shared/Libs/promise.utils.d.ts.map +1 -1
  82. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts +9 -0
  83. package/lib/typescript/src/Shared/Libs/status-bar.utils.d.ts.map +1 -0
  84. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts +25 -0
  85. package/lib/typescript/src/Shared/Services/DataUploadService.d.ts.map +1 -0
  86. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts +33 -0
  87. package/lib/typescript/src/Shared/Services/VideoSessionService.d.ts.map +1 -0
  88. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts +58 -0
  89. package/lib/typescript/src/Shared/Services/WebRTCService.d.ts.map +1 -0
  90. package/lib/typescript/src/Shared/Types/analytics.types.d.ts +2 -0
  91. package/lib/typescript/src/Shared/Types/analytics.types.d.ts.map +1 -1
  92. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +4 -1
  93. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
  94. package/lib/typescript/src/Translation/Resources/en.d.ts +20 -0
  95. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  96. package/lib/typescript/src/Translation/Resources/tr.d.ts +20 -0
  97. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  98. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  99. package/lib/typescript/src/version.d.ts +1 -1
  100. package/package.json +29 -2
  101. package/src/Screens/Debug/BarcodeTestScreen.tsx +317 -0
  102. package/src/Screens/Debug/MRZTestScreen.tsx +107 -13
  103. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +59 -33
  104. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +6 -0
  105. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +6 -0
  106. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +34 -6
  107. package/src/Screens/Dynamic/VideoCallScreen.tsx +764 -0
  108. package/src/Screens/Static/OTPVerificationScreen.tsx +6 -0
  109. package/src/Screens/Static/QrCodeScanningScreen.tsx +7 -1
  110. package/src/Screens/Static/ResultScreen.tsx +58 -23
  111. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +58 -72
  112. package/src/Shared/Animations/video-call.json +1 -0
  113. package/src/Shared/Components/DebugNavigationPanel.tsx +185 -9
  114. package/src/Shared/Components/DebugOverlay.tsx +656 -0
  115. package/src/Shared/Components/EIDScanner.tsx +1 -5
  116. package/src/Shared/Components/IdentityDocumentCamera.constants.ts +44 -0
  117. package/src/Shared/Components/IdentityDocumentCamera.flows.ts +342 -0
  118. package/src/Shared/Components/IdentityDocumentCamera.tsx +1089 -2465
  119. package/src/Shared/Components/IdentityDocumentCamera.types.ts +136 -0
  120. package/src/Shared/Components/IdentityDocumentCamera.utils.ts +364 -0
  121. package/src/Shared/Components/NavigationManager.tsx +14 -1
  122. package/src/Shared/Contexts/AppContext.ts +2 -0
  123. package/src/Shared/Libs/SignalingClient.ts +189 -0
  124. package/src/Shared/Libs/analytics.utils.ts +4 -0
  125. package/src/Shared/Libs/deeplink.utils.ts +12 -1
  126. package/src/Shared/Libs/http-client.ts +10 -0
  127. package/src/Shared/Libs/promise.utils.ts +16 -2
  128. package/src/Shared/Libs/status-bar.utils.ts +19 -0
  129. package/src/Shared/Services/DataUploadService.ts +395 -0
  130. package/src/Shared/Services/VideoSessionService.ts +190 -0
  131. package/src/Shared/Services/WebRTCService.ts +636 -0
  132. package/src/Shared/Types/analytics.types.ts +2 -0
  133. package/src/Shared/Types/identificationInfo.ts +5 -1
  134. package/src/Translation/Resources/en.ts +25 -0
  135. package/src/Translation/Resources/tr.ts +27 -0
  136. package/src/Trustchex.tsx +12 -2
  137. package/src/version.ts +1 -1
@@ -0,0 +1,541 @@
1
+ "use strict";
2
+
3
+ /* eslint-disable react-native/no-inline-styles */
4
+ import React from 'react';
5
+ import { View, Text as TextView, Image, ScrollView } from 'react-native';
6
+ import { useSafeAreaInsets } from 'react-native-safe-area-context';
7
+ import { HOLOGRAM_IMAGE_COUNT } from "./IdentityDocumentCamera.constants.js";
8
+ import { angleBetweenPoints, distanceBetweenPoints } from "./IdentityDocumentCamera.utils.js";
9
+
10
+ // --- Shared overlay sub-components ---
11
+
12
+ /**
13
+ * Renders a rotated face bounds overlay with optional crop padding border.
14
+ */
15
+ import { jsx as _jsx, jsxs as _jsxs, Fragment as _Fragment } from "react/jsx-runtime";
16
+ function FaceBoundsOverlay({
17
+ bounds,
18
+ color
19
+ }) {
20
+ const dashColor = color.replace(')', ', 0.5)').replace('rgb', 'rgba');
21
+ return /*#__PURE__*/_jsxs(_Fragment, {
22
+ children: [!!bounds.cropPadding && /*#__PURE__*/_jsx(View, {
23
+ style: {
24
+ position: 'absolute',
25
+ left: bounds.x - bounds.cropPadding,
26
+ top: bounds.y - bounds.cropPadding,
27
+ width: bounds.width + 2 * bounds.cropPadding,
28
+ height: bounds.height + 2 * bounds.cropPadding,
29
+ borderWidth: 2,
30
+ borderColor: dashColor,
31
+ borderStyle: 'dashed',
32
+ borderRadius: 8,
33
+ backgroundColor: 'transparent',
34
+ transform: [{
35
+ rotate: `${-(bounds.rollAngle || 0)}deg`
36
+ }],
37
+ transformOrigin: 'center'
38
+ }
39
+ }), /*#__PURE__*/_jsx(View, {
40
+ style: {
41
+ position: 'absolute',
42
+ left: bounds.x,
43
+ top: bounds.y,
44
+ width: bounds.width,
45
+ height: bounds.height,
46
+ borderWidth: 3,
47
+ borderColor: color,
48
+ borderRadius: 8,
49
+ backgroundColor: 'transparent',
50
+ transform: [{
51
+ rotate: `${-(bounds.rollAngle || 0)}deg`
52
+ }],
53
+ transformOrigin: 'center'
54
+ },
55
+ children: !!bounds.rollAngle && Math.abs(bounds.rollAngle) > 5 && /*#__PURE__*/_jsxs(TextView, {
56
+ style: {
57
+ position: 'absolute',
58
+ top: -20,
59
+ left: 0,
60
+ color: color,
61
+ fontSize: 10,
62
+ fontWeight: 'bold',
63
+ backgroundColor: 'rgba(0,0,0,0.7)',
64
+ paddingHorizontal: 4,
65
+ paddingVertical: 2,
66
+ borderRadius: 2
67
+ },
68
+ children: [bounds.rollAngle.toFixed(1), "\xB0"]
69
+ })
70
+ })]
71
+ });
72
+ }
73
+
74
+ /**
75
+ * Renders bounds with corner points (for barcode, MRZ, signature).
76
+ * Falls back to a rotated rectangle when corners aren't available.
77
+ */
78
+ function CornerBoundsOverlay({
79
+ bounds,
80
+ color
81
+ }) {
82
+ if (bounds.corners && bounds.corners.length >= 2) {
83
+ return /*#__PURE__*/_jsxs(_Fragment, {
84
+ children: [bounds.corners.map((corner, idx) => {
85
+ const nextCorner = bounds.corners[(idx + 1) % bounds.corners.length];
86
+ const length = distanceBetweenPoints(corner, nextCorner);
87
+ const angle = angleBetweenPoints(corner, nextCorner);
88
+ return /*#__PURE__*/_jsx(View, {
89
+ style: {
90
+ position: 'absolute',
91
+ left: corner.x,
92
+ top: corner.y,
93
+ width: length,
94
+ height: 3,
95
+ backgroundColor: color,
96
+ transform: [{
97
+ rotate: `${angle}deg`
98
+ }],
99
+ transformOrigin: 'top left'
100
+ }
101
+ }, idx);
102
+ }), bounds.corners.length >= 4 && bounds.corners.map((corner, idx) => /*#__PURE__*/_jsx(View, {
103
+ style: {
104
+ position: 'absolute',
105
+ left: corner.x - 4,
106
+ top: corner.y - 4,
107
+ width: 8,
108
+ height: 8,
109
+ borderRadius: 4,
110
+ backgroundColor: color
111
+ }
112
+ }, `corner-${idx}`)), !!bounds.angle && Math.abs(bounds.angle) > 5 && /*#__PURE__*/_jsxs(TextView, {
113
+ style: {
114
+ position: 'absolute',
115
+ left: bounds.x,
116
+ top: bounds.y - 20,
117
+ color: color,
118
+ fontSize: 10,
119
+ fontWeight: 'bold',
120
+ backgroundColor: 'rgba(0,0,0,0.7)',
121
+ paddingHorizontal: 4,
122
+ paddingVertical: 2,
123
+ borderRadius: 2
124
+ },
125
+ children: [bounds.angle.toFixed(1), "\xB0"]
126
+ })]
127
+ });
128
+ }
129
+
130
+ // Fallback: rotated rectangle
131
+ return /*#__PURE__*/_jsx(View, {
132
+ style: {
133
+ position: 'absolute',
134
+ left: bounds.x + bounds.width / 2,
135
+ top: bounds.y + bounds.height / 2,
136
+ width: bounds.width,
137
+ height: bounds.height,
138
+ marginLeft: -bounds.width / 2,
139
+ marginTop: -bounds.height / 2,
140
+ borderWidth: 3,
141
+ borderColor: color,
142
+ borderRadius: 8,
143
+ backgroundColor: 'transparent',
144
+ transform: [{
145
+ rotate: `${bounds.angle || 0}deg`
146
+ }]
147
+ },
148
+ children: !!bounds.angle && Math.abs(bounds.angle) > 5 && /*#__PURE__*/_jsxs(TextView, {
149
+ style: {
150
+ position: 'absolute',
151
+ top: -20,
152
+ left: 0,
153
+ color: color,
154
+ fontSize: 10,
155
+ fontWeight: 'bold',
156
+ backgroundColor: 'rgba(0,0,0,0.7)',
157
+ paddingHorizontal: 4,
158
+ paddingVertical: 2,
159
+ borderRadius: 2
160
+ },
161
+ children: [bounds.angle.toFixed(1), "\xB0"]
162
+ })
163
+ });
164
+ }
165
+
166
+ /**
167
+ * Debug image thumbnail with label
168
+ */
169
+ function DebugImageThumbnail({
170
+ image,
171
+ label,
172
+ activeColor,
173
+ borderColor
174
+ }) {
175
+ return /*#__PURE__*/_jsxs(View, {
176
+ style: {
177
+ alignItems: 'center'
178
+ },
179
+ children: [image ? /*#__PURE__*/_jsx(Image, {
180
+ source: {
181
+ uri: `data:image/jpeg;base64,${image}`
182
+ },
183
+ style: {
184
+ width: 40,
185
+ height: 48,
186
+ borderRadius: 2,
187
+ borderWidth: 1,
188
+ borderColor
189
+ }
190
+ }) : /*#__PURE__*/_jsx(View, {
191
+ style: {
192
+ width: 40,
193
+ height: 48,
194
+ borderRadius: 2,
195
+ borderWidth: 1,
196
+ borderColor: '#666',
197
+ backgroundColor: '#222',
198
+ justifyContent: 'center',
199
+ alignItems: 'center'
200
+ },
201
+ children: /*#__PURE__*/_jsx(TextView, {
202
+ style: {
203
+ color: '#666',
204
+ fontSize: 7
205
+ },
206
+ children: "\u2014"
207
+ })
208
+ }), /*#__PURE__*/_jsx(TextView, {
209
+ style: {
210
+ color: image ? activeColor : '#999',
211
+ fontSize: 7,
212
+ marginTop: 1,
213
+ fontWeight: 'bold'
214
+ },
215
+ children: `${image ? '✓' : '○'} ${label}`
216
+ })]
217
+ });
218
+ }
219
+
220
+ // --- Main DebugOverlay ---
221
+
222
+ const DebugOverlay = /*#__PURE__*/React.memo(function DebugOverlay({
223
+ nextStep,
224
+ status,
225
+ detectedDocumentType,
226
+ isBrightnessLow,
227
+ isFrameBlurry,
228
+ isTorchOn,
229
+ documentPlaneBounds,
230
+ secondaryFaceBounds,
231
+ barcodeBounds,
232
+ mrzBounds,
233
+ signatureBounds,
234
+ currentFaceImage,
235
+ currentSecondaryFaceImage,
236
+ currentHologramImage,
237
+ currentHologramMaskImage,
238
+ latestHologramFaceImage,
239
+ hologramImageCount,
240
+ elementsOutsideScanArea
241
+ }) {
242
+ const insets = useSafeAreaInsets();
243
+ return /*#__PURE__*/_jsxs(_Fragment, {
244
+ children: [documentPlaneBounds && nextStep !== 'COMPLETED' && /*#__PURE__*/_jsx(FaceBoundsOverlay, {
245
+ bounds: documentPlaneBounds,
246
+ color: "#4CAF50"
247
+ }), secondaryFaceBounds && nextStep !== 'COMPLETED' && /*#__PURE__*/_jsx(FaceBoundsOverlay, {
248
+ bounds: secondaryFaceBounds,
249
+ color: "#2196F3"
250
+ }), barcodeBounds && nextStep !== 'COMPLETED' && /*#__PURE__*/_jsx(CornerBoundsOverlay, {
251
+ bounds: barcodeBounds,
252
+ color: "#FF9800"
253
+ }), mrzBounds && nextStep !== 'COMPLETED' && /*#__PURE__*/_jsx(CornerBoundsOverlay, {
254
+ bounds: mrzBounds,
255
+ color: "#9C27B0"
256
+ }), signatureBounds && nextStep !== 'COMPLETED' && /*#__PURE__*/_jsx(CornerBoundsOverlay, {
257
+ bounds: signatureBounds,
258
+ color: "#00BCD4"
259
+ }), /*#__PURE__*/_jsx(View, {
260
+ style: {
261
+ position: 'absolute',
262
+ top: 0,
263
+ left: 0,
264
+ right: 0,
265
+ paddingTop: insets.top,
266
+ alignItems: 'center',
267
+ pointerEvents: 'none'
268
+ },
269
+ children: /*#__PURE__*/_jsxs(View, {
270
+ style: {
271
+ marginTop: 8,
272
+ marginHorizontal: 8,
273
+ backgroundColor: 'rgba(0, 0, 0, 0.9)',
274
+ padding: 8,
275
+ borderRadius: 6,
276
+ borderWidth: 1,
277
+ borderColor: 'rgba(255, 82, 82, 0.5)',
278
+ minWidth: 220,
279
+ maxWidth: '92%'
280
+ },
281
+ children: [/*#__PURE__*/_jsxs(View, {
282
+ style: {
283
+ flexDirection: 'row',
284
+ justifyContent: 'space-between',
285
+ marginBottom: 4
286
+ },
287
+ children: [/*#__PURE__*/_jsx(TextView, {
288
+ style: {
289
+ color: '#88D8B0',
290
+ fontSize: 10,
291
+ fontWeight: 'bold'
292
+ },
293
+ children: `Status: ${status}`
294
+ }), /*#__PURE__*/_jsx(TextView, {
295
+ style: {
296
+ color: '#FFEB3B',
297
+ fontSize: 10,
298
+ fontWeight: 'bold'
299
+ },
300
+ children: `Step: ${nextStep}`
301
+ })]
302
+ }), /*#__PURE__*/_jsxs(View, {
303
+ style: {
304
+ flexDirection: 'row',
305
+ justifyContent: 'space-between',
306
+ marginBottom: 4,
307
+ gap: 3
308
+ },
309
+ children: [/*#__PURE__*/_jsx(View, {
310
+ style: {
311
+ backgroundColor: isBrightnessLow ? '#f44336' : '#4CAF50',
312
+ paddingHorizontal: 6,
313
+ paddingVertical: 1,
314
+ borderRadius: 3
315
+ },
316
+ children: /*#__PURE__*/_jsx(TextView, {
317
+ style: {
318
+ color: '#FFFFFF',
319
+ fontSize: 8,
320
+ fontWeight: 'bold'
321
+ },
322
+ children: isBrightnessLow ? 'Low Light' : 'Good Light'
323
+ })
324
+ }), /*#__PURE__*/_jsx(View, {
325
+ style: {
326
+ backgroundColor: isFrameBlurry ? '#f44336' : '#4CAF50',
327
+ paddingHorizontal: 6,
328
+ paddingVertical: 1,
329
+ borderRadius: 3
330
+ },
331
+ children: /*#__PURE__*/_jsx(TextView, {
332
+ style: {
333
+ color: '#FFFFFF',
334
+ fontSize: 8,
335
+ fontWeight: 'bold'
336
+ },
337
+ children: isFrameBlurry ? 'Blurry' : 'Sharp'
338
+ })
339
+ })]
340
+ }), /*#__PURE__*/_jsx(TextView, {
341
+ style: {
342
+ color: elementsOutsideScanArea.length === 0 ? '#4CAF50' : '#FFA500',
343
+ fontSize: 8,
344
+ marginBottom: 3
345
+ },
346
+ children: elementsOutsideScanArea.length === 0 ? 'All elements in frame' : `Outside: ${elementsOutsideScanArea.join(', ')}`
347
+ }), /*#__PURE__*/_jsx(TextView, {
348
+ style: {
349
+ color: 'rgba(255, 255, 255, 0.7)',
350
+ fontSize: 8,
351
+ marginBottom: 3
352
+ },
353
+ children: `Face: ${documentPlaneBounds ? '✓' : '✗'}, MRZ: ${mrzBounds ? '✓' : '✗'}, Sig: ${signatureBounds ? '✓' : '✗'}`
354
+ }), nextStep === 'SCAN_HOLOGRAM' && hologramImageCount > 0 && /*#__PURE__*/_jsx(TextView, {
355
+ style: {
356
+ color: '#9C27B0',
357
+ fontSize: 8,
358
+ fontWeight: 'bold',
359
+ marginBottom: 3
360
+ },
361
+ children: `Hologram: ${hologramImageCount}/${HOLOGRAM_IMAGE_COUNT}`
362
+ }), /*#__PURE__*/_jsxs(View, {
363
+ style: {
364
+ flexDirection: 'row',
365
+ gap: 8,
366
+ paddingTop: 3,
367
+ borderTopWidth: 1,
368
+ borderTopColor: 'rgba(255, 255, 255, 0.2)',
369
+ marginBottom: 4
370
+ },
371
+ children: [/*#__PURE__*/_jsx(TextView, {
372
+ style: {
373
+ color: 'rgba(255, 255, 255, 0.7)',
374
+ fontSize: 8,
375
+ marginTop: 3
376
+ },
377
+ children: `Doc: ${detectedDocumentType}`
378
+ }), /*#__PURE__*/_jsx(TextView, {
379
+ style: {
380
+ color: 'rgba(255, 255, 255, 0.7)',
381
+ fontSize: 8,
382
+ marginTop: 3
383
+ },
384
+ children: `Flash: ${isTorchOn ? '🔦' : '○'}`
385
+ })]
386
+ }), /*#__PURE__*/_jsxs(View, {
387
+ style: {
388
+ flexDirection: 'row',
389
+ flexWrap: 'wrap',
390
+ gap: 4,
391
+ justifyContent: 'center'
392
+ },
393
+ children: [/*#__PURE__*/_jsx(DebugImageThumbnail, {
394
+ image: currentFaceImage,
395
+ label: "Face",
396
+ activeColor: "#4CAF50",
397
+ borderColor: "#4CAF50"
398
+ }), /*#__PURE__*/_jsx(DebugImageThumbnail, {
399
+ image: currentSecondaryFaceImage,
400
+ label: "2nd",
401
+ activeColor: "#2196F3",
402
+ borderColor: "#2196F3"
403
+ }), /*#__PURE__*/_jsxs(View, {
404
+ style: {
405
+ alignItems: 'center'
406
+ },
407
+ children: [currentHologramImage ? /*#__PURE__*/_jsx(Image, {
408
+ source: {
409
+ uri: `data:image/jpeg;base64,${currentHologramImage}`
410
+ },
411
+ style: {
412
+ width: 40,
413
+ height: 48,
414
+ borderRadius: 2,
415
+ borderWidth: 1,
416
+ borderColor: '#9C27B0'
417
+ }
418
+ }) : latestHologramFaceImage && hologramImageCount > 0 ? /*#__PURE__*/_jsxs(View, {
419
+ style: {
420
+ position: 'relative'
421
+ },
422
+ children: [/*#__PURE__*/_jsx(Image, {
423
+ source: {
424
+ uri: `data:image/jpeg;base64,${latestHologramFaceImage}`
425
+ },
426
+ style: {
427
+ width: 40,
428
+ height: 48,
429
+ borderRadius: 2,
430
+ borderWidth: 1,
431
+ borderColor: '#FFA500',
432
+ opacity: 0.7
433
+ }
434
+ }), /*#__PURE__*/_jsx(View, {
435
+ style: {
436
+ position: 'absolute',
437
+ bottom: 1,
438
+ left: 1,
439
+ right: 1,
440
+ backgroundColor: 'rgba(0,0,0,0.8)',
441
+ paddingVertical: 0,
442
+ borderRadius: 1
443
+ },
444
+ children: /*#__PURE__*/_jsxs(TextView, {
445
+ style: {
446
+ color: '#FFA500',
447
+ fontSize: 6,
448
+ textAlign: 'center',
449
+ fontWeight: 'bold'
450
+ },
451
+ children: [hologramImageCount, "/", HOLOGRAM_IMAGE_COUNT]
452
+ })
453
+ })]
454
+ }) : /*#__PURE__*/_jsx(View, {
455
+ style: {
456
+ width: 40,
457
+ height: 48,
458
+ borderRadius: 2,
459
+ borderWidth: 1,
460
+ borderColor: '#666',
461
+ backgroundColor: '#222',
462
+ justifyContent: 'center',
463
+ alignItems: 'center'
464
+ },
465
+ children: /*#__PURE__*/_jsx(TextView, {
466
+ style: {
467
+ color: '#666',
468
+ fontSize: 7
469
+ },
470
+ children: "\u2014"
471
+ })
472
+ }), /*#__PURE__*/_jsx(TextView, {
473
+ style: {
474
+ color: currentHologramImage ? '#9C27B0' : latestHologramFaceImage ? '#FFA500' : '#999',
475
+ fontSize: 7,
476
+ marginTop: 1,
477
+ fontWeight: 'bold'
478
+ },
479
+ children: `${currentHologramImage ? '✓' : latestHologramFaceImage ? '⏳' : '○'} Holo`
480
+ })]
481
+ }), /*#__PURE__*/_jsx(DebugImageThumbnail, {
482
+ image: currentHologramMaskImage,
483
+ label: "Mask",
484
+ activeColor: "#FF6B6B",
485
+ borderColor: "#FF6B6B"
486
+ })]
487
+ })]
488
+ })
489
+ })]
490
+ });
491
+ });
492
+
493
+ // --- Test Mode Panel ---
494
+
495
+ export const TestModePanel = /*#__PURE__*/React.memo(function TestModePanel({
496
+ mrzText
497
+ }) {
498
+ const insets = useSafeAreaInsets();
499
+ return /*#__PURE__*/_jsx(View, {
500
+ style: {
501
+ position: 'absolute',
502
+ bottom: 0,
503
+ left: 0,
504
+ right: 0,
505
+ maxHeight: '40%',
506
+ paddingBottom: insets.bottom,
507
+ backgroundColor: 'rgba(0, 0, 0, 0.95)',
508
+ borderTopWidth: 2,
509
+ borderTopColor: '#FFA500'
510
+ },
511
+ children: /*#__PURE__*/_jsx(ScrollView, {
512
+ style: {
513
+ flex: 1
514
+ },
515
+ children: /*#__PURE__*/_jsxs(View, {
516
+ style: {
517
+ padding: 10
518
+ },
519
+ children: [/*#__PURE__*/_jsx(TextView, {
520
+ style: {
521
+ color: '#FFA500',
522
+ fontSize: 12,
523
+ fontWeight: 'bold',
524
+ marginBottom: 8,
525
+ textAlign: 'center'
526
+ },
527
+ children: "MRZ Text Read"
528
+ }), /*#__PURE__*/_jsx(TextView, {
529
+ style: {
530
+ color: '#FFFFFF',
531
+ fontSize: 9,
532
+ fontFamily: 'monospace',
533
+ lineHeight: 16
534
+ },
535
+ children: mrzText.split('\n').map((line, i) => `Line ${i + 1}: ${line} (${line.length} chars)`).join('\n')
536
+ })]
537
+ })
538
+ })
539
+ });
540
+ });
541
+ export default DebugOverlay;
@@ -73,7 +73,6 @@ const EIDScanner = ({
73
73
  const appContext = React.useContext(AppContext);
74
74
  const [voiceGuidanceMessage, setVoiceGuidanceMessage] = useState();
75
75
  const [attemptNumber, setAttemptNumber] = useState(0);
76
- const lastVoiceGuidanceMessage = useRef('');
77
76
  const readNFC = useCallback(async () => {
78
77
  const startTime = Date.now();
79
78
  const currentAttempt = attemptNumber + 1;
@@ -82,7 +81,6 @@ const EIDScanner = ({
82
81
  setIsScanned(false);
83
82
  setProgress(0);
84
83
  setProgressStage('');
85
- lastVoiceGuidanceMessage.current = '';
86
84
  resetLastMessage();
87
85
 
88
86
  // Track EID scan start using analytics helper
@@ -241,8 +239,7 @@ const EIDScanner = ({
241
239
  }
242
240
  }, [isScanning, progress, pulseAnim]);
243
241
  useEffect(() => {
244
- if (voiceGuidanceMessage && appContext.currentWorkflowStep?.data?.voiceGuidanceActive && voiceGuidanceMessage !== lastVoiceGuidanceMessage.current) {
245
- lastVoiceGuidanceMessage.current = voiceGuidanceMessage;
242
+ if (voiceGuidanceMessage && appContext.currentWorkflowStep?.data?.voiceGuidanceActive) {
246
243
  speak(voiceGuidanceMessage, true);
247
244
  }
248
245
  }, [voiceGuidanceMessage, appContext.currentWorkflowStep?.data?.voiceGuidanceActive]);
@@ -0,0 +1,44 @@
1
+ "use strict";
2
+
3
+ export const HOLOGRAM_IMAGE_COUNT = 16;
4
+ export const HOLOGRAM_DETECTION_THRESHOLD = 1000;
5
+ export const HOLOGRAM_DETECTION_RETRY_COUNT = 3;
6
+ export const HOLOGRAM_CAPTURE_INTERVAL = 250;
7
+ export const HOLOGRAM_MAX_FRAMES_WITHOUT_FACE = 30;
8
+ export const MIN_BRIGHTNESS_THRESHOLD = 45;
9
+ export const MAX_BRIGHTNESS_THRESHOLD = 210; // Glare detection threshold
10
+ export const MAX_CONSECUTIVE_QUALITY_FAILURES = 30;
11
+ export const FACE_EDGE_MARGIN_PERCENT = 0.08; // Minimum 8% margin from edges
12
+ export const MIN_CARD_FACE_SIZE_PERCENT = 0.05; // Main face: min 5% of frame width
13
+ export const MIN_MLI_FACE_SIZE_PERCENT = 0.01; // MLI (Multi Layer Image): min 1% of frame width - lowered for better detection
14
+
15
+ export const REQUIRED_CONSISTENT_MRZ_READS = 2;
16
+ export const REQUIRED_CONSISTENT_DOCTYPE_DETECTIONS = 3;
17
+ export const SIGNATURE_REGEX = /s[gi]g?n[au]?t[u]?r|imz[a]s?/i;
18
+ export const SIGNATURE_TEXT_REGEX = /signature|imza|İmza/i;
19
+ export const MRZ_BLOCK_PATTERN = /[A-Z0-9<]{8,}.*</i;
20
+ export const PASSPORT_MRZ_PATTERN = /P<[A-Z]{3}/;
21
+
22
+ // BDDK Madde 7 - Security Feature Validation
23
+ // When NFC chip reading unavailable, must verify at least 4 visual security features
24
+ export const MIN_SECURITY_FEATURES_REQUIRED = 4;
25
+ export const SECURITY_FEATURE_NAMES = {
26
+ icao_photo: 'ICAO Uyumlu Fotoğraf (ICAO Compliant Photo)',
27
+ barcode: 'Barkod (Barcode)',
28
+ hologram: 'DOVID/OVD (Hologram)',
29
+ wet_signature: 'Islak İmza (Wet Signature)',
30
+ guilloche: 'Giyoş (Guilloche Pattern)',
31
+ rainbow_print: 'Gökkuşağı Baskı (Rainbow Print)',
32
+ ovi: 'Optik Değişken Mürekkep (OVI)',
33
+ latent_image: 'Gizli Görüntü (Latent Image)',
34
+ microtext: 'Mikro Yazı (Microtext)'
35
+ };
36
+
37
+ // BDDK Madde 8 - Device-side Face Shape & Visual Similarity Thresholds
38
+ // Backend does full FaceNet biometric matching
39
+ // Relaxed thresholds for device-side pre-filtering only
40
+ export const FACE_SHAPE_MATCH_THRESHOLD = 0.5; // Facial geometry similarity (0-1) - very lenient
41
+ export const FACE_VISUAL_SIMILARITY_THRESHOLD = 0.5; // Pixel-level similarity (0-1) - very lenient
42
+ export const FACE_ASPECT_RATIO_TOLERANCE = 0.15; // 15% tolerance for width/height ratio
43
+ export const FACE_SIZE_RATIO_MIN = 0.7; // Minimum 70% of primary face area
44
+ export const FACE_SIZE_RATIO_MAX = 1.3; // Maximum 130% of primary face area