@trustchex/react-native-sdk 1.355.1 → 1.357.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 (254) hide show
  1. package/README.md +2 -9
  2. package/TrustchexSDK.podspec +5 -4
  3. package/android/build.gradle +6 -4
  4. package/android/src/main/AndroidManifest.xml +1 -1
  5. package/android/src/main/java/com/trustchex/reactnativesdk/TrustchexSDKPackage.kt +45 -25
  6. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraManager.kt +168 -0
  7. package/android/src/main/java/com/trustchex/reactnativesdk/camera/TrustchexCameraView.kt +871 -0
  8. package/android/src/main/java/com/trustchex/reactnativesdk/mlkit/MLKitModule.kt +245 -0
  9. package/android/src/main/java/com/trustchex/reactnativesdk/mrz/MRZValidationModule.kt +785 -0
  10. package/android/src/main/java/com/trustchex/reactnativesdk/mrz/MRZValidator.kt +419 -0
  11. package/android/src/main/java/com/trustchex/reactnativesdk/opencv/OpenCVModule.kt +818 -0
  12. package/ios/Camera/TrustchexCameraManager.m +37 -0
  13. package/ios/Camera/TrustchexCameraManager.swift +125 -0
  14. package/ios/Camera/TrustchexCameraView.swift +1176 -0
  15. package/ios/MLKit/MLKitModule.m +23 -0
  16. package/ios/MLKit/MLKitModule.swift +250 -0
  17. package/ios/MRZValidation.m +39 -0
  18. package/ios/MRZValidation.swift +802 -0
  19. package/ios/MRZValidator.swift +466 -0
  20. package/ios/OpenCV/OpenCVModule.h +4 -0
  21. package/ios/OpenCV/OpenCVModule.mm +810 -0
  22. package/lib/module/Screens/Dynamic/IdentityDocumentEIDScanningScreen.js +2 -3
  23. package/lib/module/Screens/Dynamic/IdentityDocumentScanningScreen.js +1 -2
  24. package/lib/module/Screens/Dynamic/LivenessDetectionScreen.js +418 -193
  25. package/lib/module/Screens/Static/OTPVerificationScreen.js +11 -11
  26. package/lib/module/Screens/Static/QrCodeScanningScreen.js +5 -1
  27. package/lib/module/Screens/Static/ResultScreen.js +25 -2
  28. package/lib/module/Screens/Static/VerificationSessionCheckScreen.js +25 -7
  29. package/lib/module/Shared/Components/DebugNavigationPanel.js +234 -24
  30. package/lib/module/Shared/Components/EIDScanner.js +99 -9
  31. package/lib/module/Shared/Components/FaceCamera.js +170 -179
  32. package/lib/module/Shared/Components/IdentityDocumentCamera.js +2151 -771
  33. package/lib/module/Shared/Components/QrCodeScannerCamera.js +109 -107
  34. package/lib/module/Shared/Components/TrustchexCamera.js +122 -0
  35. package/lib/module/Shared/EIDReader/tlv/tlv.helpers.js +91 -0
  36. package/lib/module/Shared/EIDReader/tlv/tlv.utils.js +2 -124
  37. package/lib/module/Shared/EIDReader/tlv/tlvInputStream.js +4 -4
  38. package/lib/module/Shared/EIDReader/tlv/tlvOutputState.js +4 -4
  39. package/lib/module/Shared/EIDReader/tlv/tlvOutputStream.js +4 -4
  40. package/lib/module/Shared/Libs/analytics.utils.js +2 -2
  41. package/lib/module/Shared/Libs/debug.utils.js +132 -0
  42. package/lib/module/Shared/Libs/deeplink.utils.js +6 -5
  43. package/lib/module/Shared/Libs/demo.utils.js +13 -3
  44. package/lib/module/Shared/Libs/mrz.utils.js +1 -175
  45. package/lib/module/Shared/Libs/native-device-info.utils.js +12 -6
  46. package/lib/module/Shared/Libs/tts.utils.js +40 -6
  47. package/lib/module/Shared/Services/AnalyticsService.js +9 -8
  48. package/lib/module/Shared/Types/mrzFields.js +1 -0
  49. package/lib/module/Translation/Resources/en.js +87 -88
  50. package/lib/module/Translation/Resources/tr.js +84 -85
  51. package/lib/module/Trustchex.js +9 -2
  52. package/lib/module/index.js +1 -0
  53. package/lib/module/version.js +1 -1
  54. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.d.ts.map +1 -1
  55. package/lib/typescript/src/Screens/Dynamic/IdentityDocumentScanningScreen.d.ts.map +1 -1
  56. package/lib/typescript/src/Screens/Dynamic/LivenessDetectionScreen.d.ts.map +1 -1
  57. package/lib/typescript/src/Screens/Static/OTPVerificationScreen.d.ts.map +1 -1
  58. package/lib/typescript/src/Screens/Static/QrCodeScanningScreen.d.ts.map +1 -1
  59. package/lib/typescript/src/Screens/Static/ResultScreen.d.ts.map +1 -1
  60. package/lib/typescript/src/Screens/Static/VerificationSessionCheckScreen.d.ts.map +1 -1
  61. package/lib/typescript/src/Shared/Components/DebugNavigationPanel.d.ts.map +1 -1
  62. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts +2 -2
  63. package/lib/typescript/src/Shared/Components/EIDScanner.d.ts.map +1 -1
  64. package/lib/typescript/src/Shared/Components/FaceCamera.d.ts +18 -4
  65. package/lib/typescript/src/Shared/Components/FaceCamera.d.ts.map +1 -1
  66. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts +3 -4
  67. package/lib/typescript/src/Shared/Components/IdentityDocumentCamera.d.ts.map +1 -1
  68. package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts +2 -1
  69. package/lib/typescript/src/Shared/Components/QrCodeScannerCamera.d.ts.map +1 -1
  70. package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts +124 -0
  71. package/lib/typescript/src/Shared/Components/TrustchexCamera.d.ts.map +1 -0
  72. package/lib/typescript/src/Shared/EIDReader/tlv/tlv.helpers.d.ts +11 -0
  73. package/lib/typescript/src/Shared/EIDReader/tlv/tlv.helpers.d.ts.map +1 -0
  74. package/lib/typescript/src/Shared/EIDReader/tlv/tlv.utils.d.ts +2 -39
  75. package/lib/typescript/src/Shared/EIDReader/tlv/tlv.utils.d.ts.map +1 -1
  76. package/lib/typescript/src/Shared/Libs/analytics.utils.d.ts.map +1 -1
  77. package/lib/typescript/src/Shared/Libs/debug.utils.d.ts +42 -0
  78. package/lib/typescript/src/Shared/Libs/debug.utils.d.ts.map +1 -0
  79. package/lib/typescript/src/Shared/Libs/deeplink.utils.d.ts.map +1 -1
  80. package/lib/typescript/src/Shared/Libs/demo.utils.d.ts.map +1 -1
  81. package/lib/typescript/src/Shared/Libs/http-client.d.ts.map +1 -1
  82. package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts +0 -4
  83. package/lib/typescript/src/Shared/Libs/mrz.utils.d.ts.map +1 -1
  84. package/lib/typescript/src/Shared/Libs/native-device-info.utils.d.ts.map +1 -1
  85. package/lib/typescript/src/Shared/Libs/tts.utils.d.ts +4 -3
  86. package/lib/typescript/src/Shared/Libs/tts.utils.d.ts.map +1 -1
  87. package/lib/typescript/src/Shared/Services/AnalyticsService.d.ts.map +1 -1
  88. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts +2 -2
  89. package/lib/typescript/src/Shared/Types/identificationInfo.d.ts.map +1 -1
  90. package/lib/typescript/src/Shared/Types/mrzFields.d.ts +11 -0
  91. package/lib/typescript/src/Shared/Types/mrzFields.d.ts.map +1 -0
  92. package/lib/typescript/src/Translation/Resources/en.d.ts +4 -5
  93. package/lib/typescript/src/Translation/Resources/en.d.ts.map +1 -1
  94. package/lib/typescript/src/Translation/Resources/tr.d.ts +4 -5
  95. package/lib/typescript/src/Translation/Resources/tr.d.ts.map +1 -1
  96. package/lib/typescript/src/Trustchex.d.ts +2 -0
  97. package/lib/typescript/src/Trustchex.d.ts.map +1 -1
  98. package/lib/typescript/src/index.d.ts +1 -0
  99. package/lib/typescript/src/index.d.ts.map +1 -1
  100. package/lib/typescript/src/version.d.ts +1 -1
  101. package/package.json +4 -35
  102. package/src/Screens/Dynamic/ContractAcceptanceScreen.tsx +1 -1
  103. package/src/Screens/Dynamic/IdentityDocumentEIDScanningScreen.tsx +7 -5
  104. package/src/Screens/Dynamic/IdentityDocumentScanningScreen.tsx +2 -3
  105. package/src/Screens/Dynamic/LivenessDetectionScreen.tsx +498 -216
  106. package/src/Screens/Static/OTPVerificationScreen.tsx +37 -31
  107. package/src/Screens/Static/QrCodeScanningScreen.tsx +8 -1
  108. package/src/Screens/Static/ResultScreen.tsx +136 -88
  109. package/src/Screens/Static/VerificationSessionCheckScreen.tsx +46 -13
  110. package/src/Shared/Components/DebugNavigationPanel.tsx +290 -34
  111. package/src/Shared/Components/EIDScanner.tsx +94 -16
  112. package/src/Shared/Components/FaceCamera.tsx +236 -203
  113. package/src/Shared/Components/IdentityDocumentCamera.tsx +3073 -1030
  114. package/src/Shared/Components/QrCodeScannerCamera.tsx +133 -127
  115. package/src/Shared/Components/TrustchexCamera.tsx +289 -0
  116. package/src/Shared/Config/camera-enhancement.config.ts +2 -2
  117. package/src/Shared/EIDReader/tlv/tlv.helpers.ts +96 -0
  118. package/src/Shared/EIDReader/tlv/tlv.utils.ts +2 -125
  119. package/src/Shared/EIDReader/tlv/tlvInputStream.ts +4 -4
  120. package/src/Shared/EIDReader/tlv/tlvOutputState.ts +4 -4
  121. package/src/Shared/EIDReader/tlv/tlvOutputStream.ts +4 -4
  122. package/src/Shared/Libs/analytics.utils.ts +48 -20
  123. package/src/Shared/Libs/debug.utils.ts +149 -0
  124. package/src/Shared/Libs/deeplink.utils.ts +7 -5
  125. package/src/Shared/Libs/demo.utils.ts +4 -0
  126. package/src/Shared/Libs/http-client.ts +12 -8
  127. package/src/Shared/Libs/mrz.utils.ts +1 -163
  128. package/src/Shared/Libs/native-device-info.utils.ts +12 -6
  129. package/src/Shared/Libs/tts.utils.ts +48 -6
  130. package/src/Shared/Services/AnalyticsService.ts +69 -24
  131. package/src/Shared/Types/identificationInfo.ts +2 -2
  132. package/src/Shared/Types/mrzFields.ts +29 -0
  133. package/src/Translation/Resources/en.ts +90 -100
  134. package/src/Translation/Resources/tr.ts +89 -97
  135. package/src/Translation/index.ts +1 -1
  136. package/src/Trustchex.tsx +21 -4
  137. package/src/index.tsx +14 -0
  138. package/src/version.ts +1 -1
  139. package/android/src/main/java/com/trustchex/reactnativesdk/visioncameraplugins/barcodescanner/BarcodeScannerFrameProcessorPlugin.kt +0 -301
  140. package/android/src/main/java/com/trustchex/reactnativesdk/visioncameraplugins/cropper/BitmapUtils.kt +0 -205
  141. package/android/src/main/java/com/trustchex/reactnativesdk/visioncameraplugins/cropper/CropperPlugin.kt +0 -72
  142. package/android/src/main/java/com/trustchex/reactnativesdk/visioncameraplugins/cropper/FrameMetadata.kt +0 -4
  143. package/android/src/main/java/com/trustchex/reactnativesdk/visioncameraplugins/facedetector/FaceDetectorFrameProcessorPlugin.kt +0 -303
  144. package/android/src/main/java/com/trustchex/reactnativesdk/visioncameraplugins/textrecognition/TextRecognitionFrameProcessorPlugin.kt +0 -115
  145. package/ios/VisionCameraPlugins/BarcodeScanner/BarcodeScannerFrameProcessorPlugin-Bridging-Header.h +0 -9
  146. package/ios/VisionCameraPlugins/BarcodeScanner/BarcodeScannerFrameProcessorPlugin.mm +0 -22
  147. package/ios/VisionCameraPlugins/BarcodeScanner/BarcodeScannerFrameProcessorPlugin.swift +0 -188
  148. package/ios/VisionCameraPlugins/Cropper/Cropper-Bridging-Header.h +0 -13
  149. package/ios/VisionCameraPlugins/Cropper/Cropper.h +0 -20
  150. package/ios/VisionCameraPlugins/Cropper/Cropper.mm +0 -22
  151. package/ios/VisionCameraPlugins/Cropper/Cropper.swift +0 -145
  152. package/ios/VisionCameraPlugins/Cropper/CropperUtils.swift +0 -49
  153. package/ios/VisionCameraPlugins/FaceDetector/FaceDetectorFrameProcessorPlugin-Bridging-Header.h +0 -4
  154. package/ios/VisionCameraPlugins/FaceDetector/FaceDetectorFrameProcessorPlugin.mm +0 -22
  155. package/ios/VisionCameraPlugins/FaceDetector/FaceDetectorFrameProcessorPlugin.swift +0 -320
  156. package/ios/VisionCameraPlugins/TextRecognition/TextRecognitionFrameProcessorPlugin-Bridging-Header.h +0 -4
  157. package/ios/VisionCameraPlugins/TextRecognition/TextRecognitionFrameProcessorPlugin.mm +0 -27
  158. package/ios/VisionCameraPlugins/TextRecognition/TextRecognitionFrameProcessorPlugin.swift +0 -144
  159. package/lib/module/Shared/Libs/camera.utils.js +0 -308
  160. package/lib/module/Shared/Libs/frame-enhancement.utils.js +0 -133
  161. package/lib/module/Shared/Libs/opencv.utils.js +0 -21
  162. package/lib/module/Shared/Libs/worklet.utils.js +0 -68
  163. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useBarcodeScanner.js +0 -46
  164. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.js +0 -35
  165. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/index.js +0 -19
  166. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.js +0 -26
  167. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/types.js +0 -3
  168. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/utils/convert.js +0 -197
  169. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/utils/geometry.js +0 -101
  170. package/lib/module/Shared/VisionCameraPlugins/BarcodeScanner/utils/highlights.js +0 -60
  171. package/lib/module/Shared/VisionCameraPlugins/Cropper/index.js +0 -47
  172. package/lib/module/Shared/VisionCameraPlugins/FaceDetector/Camera.js +0 -42
  173. package/lib/module/Shared/VisionCameraPlugins/FaceDetector/detectFaces.js +0 -35
  174. package/lib/module/Shared/VisionCameraPlugins/FaceDetector/index.js +0 -4
  175. package/lib/module/Shared/VisionCameraPlugins/FaceDetector/types.js +0 -3
  176. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/Camera.js +0 -56
  177. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/PhotoRecognizer.js +0 -20
  178. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/RemoveLanguageModel.js +0 -9
  179. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/index.js +0 -6
  180. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/scanText.js +0 -20
  181. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/translateText.js +0 -19
  182. package/lib/module/Shared/VisionCameraPlugins/TextRecognition/types.js +0 -3
  183. package/lib/typescript/src/Shared/Libs/camera.utils.d.ts +0 -87
  184. package/lib/typescript/src/Shared/Libs/camera.utils.d.ts.map +0 -1
  185. package/lib/typescript/src/Shared/Libs/frame-enhancement.utils.d.ts +0 -25
  186. package/lib/typescript/src/Shared/Libs/frame-enhancement.utils.d.ts.map +0 -1
  187. package/lib/typescript/src/Shared/Libs/opencv.utils.d.ts +0 -3
  188. package/lib/typescript/src/Shared/Libs/opencv.utils.d.ts.map +0 -1
  189. package/lib/typescript/src/Shared/Libs/worklet.utils.d.ts +0 -9
  190. package/lib/typescript/src/Shared/Libs/worklet.utils.d.ts.map +0 -1
  191. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useBarcodeScanner.d.ts +0 -13
  192. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useBarcodeScanner.d.ts.map +0 -1
  193. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.d.ts +0 -6
  194. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.d.ts.map +0 -1
  195. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/index.d.ts +0 -12
  196. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/index.d.ts.map +0 -1
  197. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.d.ts +0 -3
  198. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.d.ts.map +0 -1
  199. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/types.d.ts +0 -52
  200. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/types.d.ts.map +0 -1
  201. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/convert.d.ts +0 -62
  202. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/convert.d.ts.map +0 -1
  203. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/geometry.d.ts +0 -34
  204. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/geometry.d.ts.map +0 -1
  205. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/highlights.d.ts +0 -32
  206. package/lib/typescript/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/highlights.d.ts.map +0 -1
  207. package/lib/typescript/src/Shared/VisionCameraPlugins/Cropper/index.d.ts +0 -23
  208. package/lib/typescript/src/Shared/VisionCameraPlugins/Cropper/index.d.ts.map +0 -1
  209. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/Camera.d.ts +0 -9
  210. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/Camera.d.ts.map +0 -1
  211. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/detectFaces.d.ts +0 -3
  212. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/detectFaces.d.ts.map +0 -1
  213. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/index.d.ts +0 -3
  214. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/index.d.ts.map +0 -1
  215. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/types.d.ts +0 -79
  216. package/lib/typescript/src/Shared/VisionCameraPlugins/FaceDetector/types.d.ts.map +0 -1
  217. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/Camera.d.ts +0 -6
  218. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/Camera.d.ts.map +0 -1
  219. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/PhotoRecognizer.d.ts +0 -3
  220. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/PhotoRecognizer.d.ts.map +0 -1
  221. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/RemoveLanguageModel.d.ts +0 -3
  222. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/RemoveLanguageModel.d.ts.map +0 -1
  223. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/index.d.ts +0 -5
  224. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/index.d.ts.map +0 -1
  225. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/scanText.d.ts +0 -3
  226. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/scanText.d.ts.map +0 -1
  227. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/translateText.d.ts +0 -3
  228. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/translateText.d.ts.map +0 -1
  229. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/types.d.ts +0 -67
  230. package/lib/typescript/src/Shared/VisionCameraPlugins/TextRecognition/types.d.ts.map +0 -1
  231. package/src/Shared/Libs/camera.utils.ts +0 -345
  232. package/src/Shared/Libs/frame-enhancement.utils.ts +0 -217
  233. package/src/Shared/Libs/opencv.utils.ts +0 -40
  234. package/src/Shared/Libs/worklet.utils.ts +0 -72
  235. package/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useBarcodeScanner.ts +0 -79
  236. package/src/Shared/VisionCameraPlugins/BarcodeScanner/hooks/useCameraPermissions.ts +0 -46
  237. package/src/Shared/VisionCameraPlugins/BarcodeScanner/index.ts +0 -60
  238. package/src/Shared/VisionCameraPlugins/BarcodeScanner/scanCodes.ts +0 -32
  239. package/src/Shared/VisionCameraPlugins/BarcodeScanner/types.ts +0 -82
  240. package/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/convert.ts +0 -195
  241. package/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/geometry.ts +0 -135
  242. package/src/Shared/VisionCameraPlugins/BarcodeScanner/utils/highlights.ts +0 -84
  243. package/src/Shared/VisionCameraPlugins/Cropper/index.ts +0 -78
  244. package/src/Shared/VisionCameraPlugins/FaceDetector/Camera.tsx +0 -63
  245. package/src/Shared/VisionCameraPlugins/FaceDetector/detectFaces.ts +0 -44
  246. package/src/Shared/VisionCameraPlugins/FaceDetector/index.ts +0 -3
  247. package/src/Shared/VisionCameraPlugins/FaceDetector/types.ts +0 -99
  248. package/src/Shared/VisionCameraPlugins/TextRecognition/Camera.tsx +0 -76
  249. package/src/Shared/VisionCameraPlugins/TextRecognition/PhotoRecognizer.ts +0 -18
  250. package/src/Shared/VisionCameraPlugins/TextRecognition/RemoveLanguageModel.ts +0 -7
  251. package/src/Shared/VisionCameraPlugins/TextRecognition/index.ts +0 -7
  252. package/src/Shared/VisionCameraPlugins/TextRecognition/scanText.ts +0 -27
  253. package/src/Shared/VisionCameraPlugins/TextRecognition/translateText.ts +0 -21
  254. package/src/Shared/VisionCameraPlugins/TextRecognition/types.ts +0 -141
@@ -0,0 +1,466 @@
1
+ import Foundation
2
+
3
+ /**
4
+ * Pure MRZ validation logic with no React Native dependencies.
5
+ * Used by both MRZValidation and TrustchexCameraView.
6
+ */
7
+ class MRZValidator {
8
+
9
+ enum MRZFormat: String {
10
+ case TD1 = "TD1"
11
+ case TD2 = "TD2"
12
+ case TD3 = "TD3"
13
+ case UNKNOWN = "UNKNOWN"
14
+ }
15
+
16
+ struct MRZResult {
17
+ let valid: Bool
18
+ let format: String
19
+ let error: String?
20
+ let documentCode: String?
21
+ let issuingState: String?
22
+ let documentNumber: String?
23
+ let lastName: String?
24
+ let firstName: String?
25
+ let birthDate: String?
26
+ let sex: String?
27
+ let expirationDate: String?
28
+ let nationality: String?
29
+ let optional1: String?
30
+ let optional2: String?
31
+ let rawLines: String?
32
+
33
+ func toDictionary() -> [String: Any] {
34
+ var dict: [String: Any] = ["valid": valid, "format": format]
35
+ if let e = error { dict["error"] = e }
36
+ if let v = documentCode { dict["documentCode"] = v }
37
+ if let v = issuingState { dict["issuingState"] = v }
38
+ if let v = documentNumber { dict["documentNumber"] = v }
39
+ if let v = lastName { dict["lastName"] = v }
40
+ if let v = firstName { dict["firstName"] = v }
41
+ if let v = birthDate { dict["birthDate"] = v }
42
+ if let v = sex { dict["sex"] = v }
43
+ if let v = expirationDate { dict["expirationDate"] = v }
44
+ if let v = nationality { dict["nationality"] = v }
45
+ if let v = optional1 { dict["optional1"] = v }
46
+ if let v = optional2 { dict["optional2"] = v }
47
+ if let v = rawLines { dict["rawLines"] = v }
48
+ return dict
49
+ }
50
+ }
51
+
52
+ func validateWithCorrections(_ ocrText: String) -> MRZResult {
53
+ let fixedText = fixMRZ(ocrText)
54
+ var lines = fixedText.trimmingCharacters(in: .whitespacesAndNewlines)
55
+ .components(separatedBy: "\n")
56
+ .map { $0.trimmingCharacters(in: .whitespaces) }
57
+
58
+ if lines.isEmpty || fixedText.count < 60 {
59
+ return MRZResult(valid: false, format: "UNKNOWN", error: "MRZ text too short",
60
+ documentCode: nil, issuingState: nil, documentNumber: nil, lastName: nil,
61
+ firstName: nil, birthDate: nil, sex: nil, expirationDate: nil,
62
+ nationality: nil, optional1: nil, optional2: nil, rawLines: nil)
63
+ }
64
+
65
+ let format = detectMRZFormat(lines)
66
+ guard format != .UNKNOWN else {
67
+ return MRZResult(valid: false, format: "UNKNOWN", error: "Unknown MRZ format",
68
+ documentCode: nil, issuingState: nil, documentNumber: nil, lastName: nil,
69
+ firstName: nil, birthDate: nil, sex: nil, expirationDate: nil,
70
+ nationality: nil, optional1: nil, optional2: nil, rawLines: nil)
71
+ }
72
+
73
+ // Phase 1
74
+ var result = parseMRZ(fixedText)
75
+ if result.valid { return result }
76
+
77
+ // Phase 2: composite brute-force
78
+ let compositePos: (line: Int, pos: Int)?
79
+ switch format {
80
+ case .TD1: compositePos = (1, 29)
81
+ case .TD2: compositePos = (1, 35)
82
+ case .TD3: compositePos = (1, 43)
83
+ case .UNKNOWN: compositePos = nil
84
+ }
85
+ if let pos = compositePos {
86
+ for digit in 0...9 {
87
+ var testLines = lines
88
+ var chars = Array(testLines[pos.line])
89
+ chars[pos.pos] = Character(String(digit))
90
+ testLines[pos.line] = String(chars)
91
+ let testResult = parseMRZ(testLines.joined(separator: "\n"))
92
+ if testResult.valid { return testResult }
93
+ }
94
+ }
95
+
96
+ // Phase 3: O/0 permutations
97
+ for permutation in generateO0Permutations(fixedText) {
98
+ let testResult = parseMRZ(permutation)
99
+ if testResult.valid { return testResult }
100
+ }
101
+
102
+ // Phase 4: I/1 permutations
103
+ for permutation in generateI1Permutations(fixedText) {
104
+ let testResult = parseMRZ(permutation)
105
+ if testResult.valid { return testResult }
106
+ }
107
+
108
+ // Phase 5: S/5 permutations
109
+ for permutation in generatePairPermutations(fixedText, letter: "S", digit: "5") {
110
+ let testResult = parseMRZ(permutation)
111
+ if testResult.valid { return testResult }
112
+ }
113
+
114
+ // Phase 6: B/8 permutations
115
+ for permutation in generatePairPermutations(fixedText, letter: "B", digit: "8") {
116
+ let testResult = parseMRZ(permutation)
117
+ if testResult.valid { return testResult }
118
+ }
119
+
120
+ // Phase 7: Z/2 permutations
121
+ for permutation in generatePairPermutations(fixedText, letter: "Z", digit: "2") {
122
+ let testResult = parseMRZ(permutation)
123
+ if testResult.valid { return testResult }
124
+ }
125
+
126
+ // Phase 8: G/6 permutations
127
+ for permutation in generatePairPermutations(fixedText, letter: "G", digit: "6") {
128
+ let testResult = parseMRZ(permutation)
129
+ if testResult.valid { return testResult }
130
+ }
131
+
132
+ return result
133
+ }
134
+
135
+ private func parseMRZ(_ rawText: String) -> MRZResult {
136
+ let lines = rawText.trimmingCharacters(in: .whitespacesAndNewlines)
137
+ .components(separatedBy: "\n")
138
+ .map { $0.trimmingCharacters(in: .whitespaces) }
139
+
140
+ let format = detectMRZFormat(lines)
141
+ guard format != .UNKNOWN else {
142
+ return MRZResult(valid: false, format: "UNKNOWN", error: "Unknown MRZ format",
143
+ documentCode: nil, issuingState: nil, documentNumber: nil, lastName: nil,
144
+ firstName: nil, birthDate: nil, sex: nil, expirationDate: nil,
145
+ nationality: nil, optional1: nil, optional2: nil, rawLines: nil)
146
+ }
147
+
148
+ let fields: MRZResult
149
+ switch format {
150
+ case .TD1: fields = parseTD1(lines, format: format)
151
+ case .TD2: fields = parseTD2(lines, format: format)
152
+ case .TD3: fields = parseTD3(lines, format: format)
153
+ case .UNKNOWN:
154
+ return MRZResult(valid: false, format: "UNKNOWN", error: "Unsupported format",
155
+ documentCode: nil, issuingState: nil, documentNumber: nil, lastName: nil,
156
+ firstName: nil, birthDate: nil, sex: nil, expirationDate: nil,
157
+ nationality: nil, optional1: nil, optional2: nil, rawLines: nil)
158
+ }
159
+
160
+ let allValid = validateChecksums(format: format, lines: lines)
161
+ return MRZResult(valid: allValid, format: format.rawValue, error: fields.error,
162
+ documentCode: fields.documentCode, issuingState: fields.issuingState,
163
+ documentNumber: fields.documentNumber, lastName: fields.lastName,
164
+ firstName: fields.firstName, birthDate: fields.birthDate, sex: fields.sex,
165
+ expirationDate: fields.expirationDate, nationality: fields.nationality,
166
+ optional1: fields.optional1, optional2: fields.optional2,
167
+ rawLines: allValid ? rawText.trimmingCharacters(in: .whitespacesAndNewlines) : nil)
168
+ }
169
+
170
+ private func detectMRZFormat(_ lines: [String]) -> MRZFormat {
171
+ if lines.count == 3 && lines.allSatisfy({ $0.count == 30 }) { return .TD1 }
172
+ if lines.count == 2 && lines.allSatisfy({ $0.count == 36 }) { return .TD2 }
173
+ if lines.count == 2 && lines.allSatisfy({ $0.count == 44 }) { return .TD3 }
174
+ return .UNKNOWN
175
+ }
176
+
177
+ private func str(_ s: String, from: Int, length: Int) -> String {
178
+ let start = s.index(s.startIndex, offsetBy: from)
179
+ let end = s.index(start, offsetBy: length)
180
+ return String(s[start..<end]).replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces)
181
+ }
182
+
183
+ private func raw(_ s: String, from: Int, length: Int) -> String {
184
+ let start = s.index(s.startIndex, offsetBy: from)
185
+ let end = s.index(start, offsetBy: length)
186
+ return String(s[start..<end])
187
+ }
188
+
189
+ private func parseTD1(_ lines: [String], format: MRZFormat) -> MRZResult {
190
+ let names = lines[2].components(separatedBy: "<<")
191
+ return MRZResult(valid: false, format: format.rawValue, error: nil,
192
+ documentCode: str(lines[0], from: 0, length: 2),
193
+ issuingState: str(lines[0], from: 2, length: 3),
194
+ documentNumber: str(lines[0], from: 5, length: 9),
195
+ lastName: names[0].replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces),
196
+ firstName: names.count > 1 ? names[1].replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces) : "",
197
+ birthDate: raw(lines[1], from: 0, length: 6),
198
+ sex: raw(lines[1], from: 7, length: 1),
199
+ expirationDate: raw(lines[1], from: 8, length: 6),
200
+ nationality: str(lines[1], from: 15, length: 3),
201
+ optional1: str(lines[0], from: 15, length: 15),
202
+ optional2: str(lines[1], from: 18, length: 11), rawLines: nil)
203
+ }
204
+
205
+ private func parseTD2(_ lines: [String], format: MRZFormat) -> MRZResult {
206
+ let names = String(lines[0].dropFirst(5)).components(separatedBy: "<<")
207
+ return MRZResult(valid: false, format: format.rawValue, error: nil,
208
+ documentCode: str(lines[0], from: 0, length: 2),
209
+ issuingState: str(lines[0], from: 2, length: 3),
210
+ documentNumber: str(lines[1], from: 0, length: 9),
211
+ lastName: names[0].replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces),
212
+ firstName: names.count > 1 ? names[1].replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces) : "",
213
+ birthDate: raw(lines[1], from: 13, length: 6),
214
+ sex: raw(lines[1], from: 20, length: 1),
215
+ expirationDate: raw(lines[1], from: 21, length: 6),
216
+ nationality: str(lines[1], from: 10, length: 3),
217
+ optional1: str(lines[1], from: 28, length: 7),
218
+ optional2: nil, rawLines: nil)
219
+ }
220
+
221
+ private func parseTD3(_ lines: [String], format: MRZFormat) -> MRZResult {
222
+ let names = String(lines[0].dropFirst(5)).components(separatedBy: "<<")
223
+ return MRZResult(valid: false, format: format.rawValue, error: nil,
224
+ documentCode: str(lines[0], from: 0, length: 2),
225
+ issuingState: str(lines[0], from: 2, length: 3),
226
+ documentNumber: str(lines[1], from: 0, length: 9),
227
+ lastName: names[0].replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces),
228
+ firstName: names.count > 1 ? names[1].replacingOccurrences(of: "<", with: " ").trimmingCharacters(in: .whitespaces) : "",
229
+ birthDate: raw(lines[1], from: 13, length: 6),
230
+ sex: raw(lines[1], from: 20, length: 1),
231
+ expirationDate: raw(lines[1], from: 21, length: 6),
232
+ nationality: str(lines[1], from: 10, length: 3),
233
+ optional1: str(lines[1], from: 28, length: 14),
234
+ optional2: nil, rawLines: nil)
235
+ }
236
+
237
+ private func validateChecksums(format: MRZFormat, lines: [String]) -> Bool {
238
+ guard lines.count >= (format == .TD1 ? 3 : 2) else { return false }
239
+ do {
240
+ switch format {
241
+ case .TD1:
242
+ let l0 = lines[0], l1 = lines[1]
243
+ let docValid = try calculateChecksum(raw(l0, from: 5, length: 9)) == l0[l0.index(l0.startIndex, offsetBy: 14)]
244
+ let birthValid = try calculateChecksum(raw(l1, from: 0, length: 6)) == l1[l1.index(l1.startIndex, offsetBy: 6)]
245
+ let expiryValid = try calculateChecksum(raw(l1, from: 8, length: 6)) == l1[l1.index(l1.startIndex, offsetBy: 14)]
246
+ let composite = String(l0.dropFirst(5)) + String(l1.prefix(7)) + String(l1.dropFirst(8).prefix(7)) + String(l1.dropFirst(18).prefix(11))
247
+ let compValid = try calculateChecksum(composite) == l1[l1.index(l1.startIndex, offsetBy: 29)]
248
+ return docValid && birthValid && expiryValid && compValid
249
+ case .TD2:
250
+ let l = lines[1]
251
+ let docValid = try calculateChecksum(raw(l, from: 0, length: 9)) == l[l.index(l.startIndex, offsetBy: 9)]
252
+ let birthValid = try calculateChecksum(raw(l, from: 13, length: 6)) == l[l.index(l.startIndex, offsetBy: 19)]
253
+ let expiryValid = try calculateChecksum(raw(l, from: 21, length: 6)) == l[l.index(l.startIndex, offsetBy: 27)]
254
+ let composite = String(l.prefix(10)) + String(l.dropFirst(13).prefix(7)) + String(l.dropFirst(21).prefix(14))
255
+ let compValid = try calculateChecksum(composite) == l[l.index(l.startIndex, offsetBy: 35)]
256
+ return docValid && birthValid && expiryValid && compValid
257
+ case .TD3:
258
+ let l = lines[1]
259
+ let docValid = try calculateChecksum(raw(l, from: 0, length: 9)) == l[l.index(l.startIndex, offsetBy: 9)]
260
+ let birthValid = try calculateChecksum(raw(l, from: 13, length: 6)) == l[l.index(l.startIndex, offsetBy: 19)]
261
+ let expiryValid = try calculateChecksum(raw(l, from: 21, length: 6)) == l[l.index(l.startIndex, offsetBy: 27)]
262
+ let personalValid = try calculateChecksum(raw(l, from: 28, length: 14)) == l[l.index(l.startIndex, offsetBy: 42)]
263
+ let composite = String(l.prefix(10)) + String(l.dropFirst(13).prefix(7)) + String(l.dropFirst(21).prefix(22))
264
+ let compValid = try calculateChecksum(composite) == l[l.index(l.startIndex, offsetBy: 43)]
265
+ return docValid && birthValid && expiryValid && personalValid && compValid
266
+ case .UNKNOWN:
267
+ return false
268
+ }
269
+ } catch {
270
+ return false
271
+ }
272
+ }
273
+
274
+ private func calculateChecksum(_ data: String) throws -> Character {
275
+ let weights = [7, 3, 1]
276
+ var sum = 0
277
+ for (index, char) in data.enumerated() {
278
+ let value: Int
279
+ switch char {
280
+ case "0"..."9": value = Int(char.asciiValue! - Character("0").asciiValue!)
281
+ case "A"..."Z": value = Int(char.asciiValue! - Character("A").asciiValue!) + 10
282
+ default: value = 0
283
+ }
284
+ sum += value * weights[index % 3]
285
+ }
286
+ return Character(String(sum % 10))
287
+ }
288
+
289
+ func fixMRZ(_ rawText: String) -> String {
290
+ var fixed = rawText
291
+ .replacingOccurrences(of: " ", with: "")
292
+ .replacingOccurrences(of: "«", with: "")
293
+ if let regex = try? NSRegularExpression(pattern: "<K+|r+K+|<r+K+") {
294
+ fixed = regex.stringByReplacingMatches(in: fixed, range: NSRange(fixed.startIndex..., in: fixed), withTemplate: "")
295
+ }
296
+ if let regex = try? NSRegularExpression(pattern: "\\bI<TUR([A-Z0-9]{3})0([A-Z0-9]{6})\\b") {
297
+ fixed = regex.stringByReplacingMatches(in: fixed, range: NSRange(fixed.startIndex..., in: fixed), withTemplate: "I<TUR$1O$2")
298
+ }
299
+ let mrzCharRegex = try? NSRegularExpression(pattern: "^[A-Z0-9<]+$")
300
+ let allLines = fixed.components(separatedBy: "\n").map { $0.trimmingCharacters(in: .whitespaces) }
301
+
302
+ // Extract only lines that are exact MRZ lengths with valid MRZ characters
303
+ let mrzLines = allLines.filter { line in
304
+ (line.count == 30 || line.count == 36 || line.count == 44) &&
305
+ mrzCharRegex?.firstMatch(in: line, range: NSRange(line.startIndex..., in: line)) != nil
306
+ }
307
+
308
+ // Fall back to lines containing '<' if no exact-length lines found
309
+ let candidateLines = mrzLines.isEmpty ? allLines.filter { $0.contains("<") } : mrzLines
310
+
311
+ let targetLength: Int
312
+ if candidateLines.allSatisfy({ $0.count <= 30 }) { targetLength = 30 }
313
+ else if candidateLines.allSatisfy({ $0.count <= 36 }) { targetLength = 36 }
314
+ else if candidateLines.allSatisfy({ $0.count <= 44 }) { targetLength = 44 }
315
+ else { return rawText }
316
+
317
+ // Keep only lines that fit the target length and have valid MRZ characters
318
+ let filteredLines = candidateLines.filter { line in
319
+ line.count <= targetLength &&
320
+ mrzCharRegex?.firstMatch(in: line, range: NSRange(line.startIndex..., in: line)) != nil
321
+ }
322
+ if filteredLines.isEmpty { return rawText }
323
+
324
+ let paddedLines = filteredLines.map { line in
325
+ line.count < targetLength ? line.padding(toLength: targetLength, withPad: "<", startingAt: 0) : line
326
+ }
327
+ return applyOCRCorrections(paddedLines.joined(separator: "\n"))
328
+ }
329
+
330
+ private func applyOCRCorrections(_ mrzText: String) -> String {
331
+ var lines = mrzText.components(separatedBy: "\n")
332
+ if lines.isEmpty { return mrzText }
333
+ let format = detectMRZFormat(lines)
334
+ if format == .UNKNOWN { return mrzText }
335
+ switch format {
336
+ case .TD1:
337
+ lines[0] = correctLetterPositions(lines[0], ranges: [0...1, 2...4])
338
+ lines[0] = correctCheckDigitPositions(lines[0], positions: [14])
339
+ lines[1] = correctDigitPositions(lines[1], ranges: [0...5, 8...13])
340
+ lines[1] = correctCheckDigitPositions(lines[1], positions: [6, 14, 29])
341
+ lines[1] = correctLetterPositions(lines[1], ranges: [7...7, 15...17])
342
+ lines[2] = correctLetterPositions(lines[2], ranges: [0...29])
343
+ case .TD2:
344
+ lines[0] = correctLetterPositions(lines[0], ranges: [0...1, 2...4, 5...35])
345
+ lines[1] = correctDigitPositions(lines[1], ranges: [13...18, 21...26])
346
+ lines[1] = correctCheckDigitPositions(lines[1], positions: [9, 19, 27, 35])
347
+ lines[1] = correctLetterPositions(lines[1], ranges: [10...12, 20...20])
348
+ case .TD3:
349
+ lines[0] = correctLetterPositions(lines[0], ranges: [0...1, 2...4, 5...43])
350
+ lines[1] = correctDigitPositions(lines[1], ranges: [13...18, 21...26])
351
+ lines[1] = correctCheckDigitPositions(lines[1], positions: [9, 19, 27, 42])
352
+ lines[1] = correctLetterPositions(lines[1], ranges: [10...12, 20...20])
353
+ case .UNKNOWN: break
354
+ }
355
+ return lines.joined(separator: "\n")
356
+ }
357
+
358
+ private func correctDigitPositions(_ line: String, ranges: [ClosedRange<Int>]) -> String {
359
+ var c = Array(line)
360
+ ranges.forEach { r in r.forEach { i in
361
+ if i < c.count {
362
+ switch c[i] {
363
+ case "O", "o": c[i] = "0"
364
+ case "I", "l": c[i] = "1"
365
+ case "Z": c[i] = "2"
366
+ case "S": c[i] = "5"
367
+ case "G": c[i] = "6"
368
+ case "B": c[i] = "8"
369
+ case "D", "Q": c[i] = "0"
370
+ default: break
371
+ }
372
+ }
373
+ }}
374
+ return String(c)
375
+ }
376
+
377
+ private func correctLetterPositions(_ line: String, ranges: [ClosedRange<Int>]) -> String {
378
+ var c = Array(line)
379
+ ranges.forEach { r in r.forEach { i in
380
+ if i < c.count {
381
+ switch c[i] {
382
+ case "0": c[i] = "O"
383
+ case "1": c[i] = "I"
384
+ case "5": c[i] = "S"
385
+ case "8": c[i] = "B"
386
+ case "2": c[i] = "Z"
387
+ case "6": c[i] = "G"
388
+ default: break
389
+ }
390
+ }
391
+ }}
392
+ return String(c)
393
+ }
394
+
395
+ private func correctCheckDigitPositions(_ line: String, positions: [Int]) -> String {
396
+ var c = Array(line)
397
+ positions.forEach { i in
398
+ if i < c.count {
399
+ switch c[i] {
400
+ case "O", "o": c[i] = "0"
401
+ case "I", "l": c[i] = "1"
402
+ case "Z": c[i] = "2"
403
+ case "S": c[i] = "5"
404
+ case "G": c[i] = "6"
405
+ case "B": c[i] = "8"
406
+ default: break
407
+ }
408
+ }
409
+ }
410
+ return String(c)
411
+ }
412
+
413
+ private func generateO0Permutations(_ mrzText: String, maxPermutations: Int = 100) -> [String] {
414
+ var permutations = Set<String>([mrzText])
415
+ let positions = Array(mrzText.enumerated().compactMap { (i, c) in
416
+ (c == "O" || c == "o" || c == "0") ? i : nil
417
+ }.prefix(7))
418
+ let limit = min(1 << positions.count, maxPermutations)
419
+ for i in 0..<limit {
420
+ var variant = Array(mrzText)
421
+ for (j, pos) in positions.enumerated() {
422
+ let useZero = (i & (1 << j)) != 0
423
+ if useZero && variant[pos] != "0" { variant[pos] = "0" }
424
+ else if !useZero && variant[pos] != "O" { variant[pos] = "O" }
425
+ }
426
+ permutations.insert(String(variant))
427
+ }
428
+ return Array(permutations)
429
+ }
430
+
431
+ private func generatePairPermutations(_ mrzText: String, letter: Character, digit: Character, maxPermutations: Int = 30) -> [String] {
432
+ var permutations = Set<String>([mrzText])
433
+ let positions = Array(mrzText.enumerated().compactMap { (i, c) in
434
+ (c == letter || c == Character(letter.lowercased()) || c == digit) ? i : nil
435
+ }.prefix(5))
436
+ let limit = min(1 << positions.count, maxPermutations)
437
+ for i in 0..<limit {
438
+ var variant = Array(mrzText)
439
+ for (j, pos) in positions.enumerated() {
440
+ let useDigit = (i & (1 << j)) != 0
441
+ if useDigit && variant[pos] != digit { variant[pos] = digit }
442
+ else if !useDigit && variant[pos] != letter { variant[pos] = letter }
443
+ }
444
+ permutations.insert(String(variant))
445
+ }
446
+ return Array(permutations)
447
+ }
448
+
449
+ private func generateI1Permutations(_ mrzText: String, maxPermutations: Int = 50) -> [String] {
450
+ var permutations = Set<String>([mrzText])
451
+ let positions = Array(mrzText.enumerated().compactMap { (i, c) in
452
+ (c == "I" || c == "i" || c == "l" || c == "1") ? i : nil
453
+ }.prefix(6))
454
+ let limit = min(1 << positions.count, maxPermutations)
455
+ for i in 0..<limit {
456
+ var variant = Array(mrzText)
457
+ for (j, pos) in positions.enumerated() {
458
+ let useOne = (i & (1 << j)) != 0
459
+ if useOne && variant[pos] != "1" { variant[pos] = "1" }
460
+ else if !useOne && (variant[pos] == "1" || variant[pos] == "l" || variant[pos] == "i") { variant[pos] = "I" }
461
+ }
462
+ permutations.insert(String(variant))
463
+ }
464
+ return Array(permutations)
465
+ }
466
+ }
@@ -0,0 +1,4 @@
1
+ #import <React/RCTBridgeModule.h>
2
+
3
+ @interface OpenCVModule : NSObject <RCTBridgeModule>
4
+ @end