diff --git a/BlinkID/package.json b/BlinkID/package.json index f63573e..300767e 100644 --- a/BlinkID/package.json +++ b/BlinkID/package.json @@ -1,6 +1,6 @@ { "name": "blinkid-cordova", - "version": "5.11.0", + "version": "5.12.0", "description": "A small and powerful ID card scanning library", "cordova": { "id": "blinkid-cordova", diff --git a/BlinkID/plugin.xml b/BlinkID/plugin.xml index cf9461b..1b28fd4 100644 --- a/BlinkID/plugin.xml +++ b/BlinkID/plugin.xml @@ -2,7 +2,7 @@ + version="5.12.0"> BlinkIdScanner A small and powerful ID card scanning library diff --git a/BlinkID/scripts/initIOSFramework.sh b/BlinkID/scripts/initIOSFramework.sh index 6f84358..9cca877 100755 --- a/BlinkID/scripts/initIOSFramework.sh +++ b/BlinkID/scripts/initIOSFramework.sh @@ -4,7 +4,7 @@ HERE="$(dirname "$(test -L "$0" && readlink "$0" || echo "$0")")" pushd "${HERE}/../src/ios/" > /dev/null -LINK='https://github.com/BlinkID/blinkid-ios/releases/download/v5.11.0/Microblink.xcframework.zip' +LINK='https://github.com/BlinkID/blinkid-ios/releases/download/v5.12.0/Microblink.xcframework.zip' FILENAME='Microblink.xcframework.zip' # check if Microblink framework and bundle already exist diff --git a/BlinkID/src/android/java/com/microblink/plugins/cordova/SerializationUtils.java b/BlinkID/src/android/java/com/microblink/plugins/cordova/SerializationUtils.java index c7fb4aa..9e056ff 100644 --- a/BlinkID/src/android/java/com/microblink/plugins/cordova/SerializationUtils.java +++ b/BlinkID/src/android/java/com/microblink/plugins/cordova/SerializationUtils.java @@ -11,7 +11,6 @@ import com.microblink.results.date.DateResult; import com.microblink.entities.Entity; import com.microblink.entities.recognizers.blinkid.imageoptions.extension.ImageExtensionFactors; -import com.microblink.entities.recognizers.blinkid.generic.RecognitionModeFilter; import org.json.JSONArray; import org.json.JSONException; @@ -124,18 +123,4 @@ public static ImageExtensionFactors deserializeExtensionFactors(JSONObject jsonE } } - public static RecognitionModeFilter deserializeRecognitionModeFilter(JSONObject json) { - if (json != null) { - boolean enableMrzId = (boolean)json.optBoolean("enableMrzId", true); - boolean enableMrzVisa = (boolean)json.optBoolean("enableMrzVisa", true); - boolean enableMrzPassport = (boolean)json.optBoolean("enableMrzPassport", true); - boolean enablePhotoId = (boolean)json.optBoolean("enablePhotoId", true); - boolean enableBarcodeId = (boolean)json.optBoolean("enableBarcodeId", true); - boolean enableFullDocumentRecognition = (boolean)json.optBoolean("enableFullDocumentRecognition", true); - return new RecognitionModeFilter(enableMrzId, enableMrzVisa, enableMrzPassport, enablePhotoId, enableBarcodeId, enableFullDocumentRecognition); - } else { - return new RecognitionModeFilter(); - } - } - } \ No newline at end of file diff --git a/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIDSerializationUtils.java b/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIDSerializationUtils.java index 4d3ea51..9320a3a 100644 --- a/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIDSerializationUtils.java +++ b/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIDSerializationUtils.java @@ -10,6 +10,7 @@ import com.microblink.entities.recognizers.blinkid.generic.barcode.BarcodeResult; import com.microblink.entities.recognizers.blinkid.idbarcode.BarcodeElements; import com.microblink.entities.recognizers.blinkid.idbarcode.BarcodeElementKey; +import com.microblink.entities.recognizers.blinkid.generic.RecognitionModeFilter; import org.json.JSONArray; import org.json.JSONException; @@ -158,4 +159,18 @@ public static JSONObject serializeBarcodeElements(BarcodeElements barcodeElement return jsonBarcodeElements; } + public static RecognitionModeFilter deserializeRecognitionModeFilter(JSONObject json) { + if (json != null) { + boolean enableMrzId = (boolean)json.optBoolean("enableMrzId", true); + boolean enableMrzVisa = (boolean)json.optBoolean("enableMrzVisa", true); + boolean enableMrzPassport = (boolean)json.optBoolean("enableMrzPassport", true); + boolean enablePhotoId = (boolean)json.optBoolean("enablePhotoId", true); + boolean enableBarcodeId = (boolean)json.optBoolean("enableBarcodeId", true); + boolean enableFullDocumentRecognition = (boolean)json.optBoolean("enableFullDocumentRecognition", true); + return new RecognitionModeFilter(enableMrzId, enableMrzVisa, enableMrzPassport, enablePhotoId, enableBarcodeId, enableFullDocumentRecognition); + } else { + return new RecognitionModeFilter(); + } + } + } \ No newline at end of file diff --git a/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdCombinedRecognizerSerialization.java b/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdCombinedRecognizerSerialization.java index b659142..cadd045 100644 --- a/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdCombinedRecognizerSerialization.java +++ b/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdCombinedRecognizerSerialization.java @@ -13,14 +13,16 @@ public final class BlinkIdCombinedRecognizerSerialization implements RecognizerS public Recognizer createRecognizer(JSONObject jsonObject) { com.microblink.entities.recognizers.blinkid.generic.BlinkIdCombinedRecognizer recognizer = new com.microblink.entities.recognizers.blinkid.generic.BlinkIdCombinedRecognizer(); recognizer.setAllowBlurFilter(jsonObject.optBoolean("allowBlurFilter", true)); + recognizer.setAllowUncertainFrontSideScan(jsonObject.optBoolean("allowUncertainFrontSideScan", false)); recognizer.setAllowUnparsedMrzResults(jsonObject.optBoolean("allowUnparsedMrzResults", false)); recognizer.setAllowUnverifiedMrzResults(jsonObject.optBoolean("allowUnverifiedMrzResults", true)); recognizer.setAnonymizationMode(com.microblink.entities.recognizers.blinkid.generic.AnonymizationMode.values()[jsonObject.optInt("anonymizationMode", 4) - 1]); recognizer.setFaceImageDpi(jsonObject.optInt("faceImageDpi", 250)); recognizer.setFullDocumentImageDpi(jsonObject.optInt("fullDocumentImageDpi", 250)); recognizer.setFullDocumentImageExtensionFactors(SerializationUtils.deserializeExtensionFactors(jsonObject.optJSONObject("fullDocumentImageExtensionFactors"))); + recognizer.setMaxAllowedMismatchesPerField(jsonObject.optInt("maxAllowedMismatchesPerField", 0)); recognizer.setPaddingEdge((float)jsonObject.optDouble("paddingEdge", 0.0)); - recognizer.setRecognitionModeFilter(SerializationUtils.deserializeRecognitionModeFilter(jsonObject.optJSONObject("recognitionModeFilter"))); + recognizer.setRecognitionModeFilter(BlinkIDSerializationUtils.deserializeRecognitionModeFilter(jsonObject.optJSONObject("recognitionModeFilter"))); recognizer.setReturnFaceImage(jsonObject.optBoolean("returnFaceImage", false)); recognizer.setReturnFullDocumentImage(jsonObject.optBoolean("returnFullDocumentImage", false)); recognizer.setReturnSignatureImage(jsonObject.optBoolean("returnSignatureImage", false)); @@ -43,6 +45,7 @@ public JSONObject serializeResult(Recognizer recognizer) { jsonResult.put("address", result.getAddress()); jsonResult.put("age", result.getAge()); jsonResult.put("backImageAnalysisResult", BlinkIDSerializationUtils.serializeImageAnalysisResult(result.getBackImageAnalysisResult())); + jsonResult.put("backProcessingStatus", SerializationUtils.serializeEnum(result.getBackProcessingStatus())); jsonResult.put("backVizResult", BlinkIDSerializationUtils.serializeVizResult(result.getBackVizResult())); jsonResult.put("barcodeResult", BlinkIDSerializationUtils.serializeBarcodeResult(result.getBarcodeResult())); jsonResult.put("classInfo", BlinkIDSerializationUtils.serializeClassInfo(result.getClassInfo())); @@ -62,6 +65,7 @@ public JSONObject serializeResult(Recognizer recognizer) { jsonResult.put("faceImage", SerializationUtils.encodeImageBase64(result.getFaceImage())); jsonResult.put("firstName", result.getFirstName()); jsonResult.put("frontImageAnalysisResult", BlinkIDSerializationUtils.serializeImageAnalysisResult(result.getFrontImageAnalysisResult())); + jsonResult.put("frontProcessingStatus", SerializationUtils.serializeEnum(result.getFrontProcessingStatus())); jsonResult.put("frontVizResult", BlinkIDSerializationUtils.serializeVizResult(result.getFrontVizResult())); jsonResult.put("fullDocumentBackImage", SerializationUtils.encodeImageBase64(result.getFullDocumentBackImage())); jsonResult.put("fullDocumentFrontImage", SerializationUtils.encodeImageBase64(result.getFullDocumentFrontImage())); diff --git a/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdRecognizerSerialization.java b/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdRecognizerSerialization.java index a5c3144..6930ed1 100644 --- a/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdRecognizerSerialization.java +++ b/BlinkID/src/android/java/com/microblink/plugins/cordova/recognizers/serialization/BlinkIdRecognizerSerialization.java @@ -20,7 +20,7 @@ public Recognizer createRecognizer(JSONObject jsonObject) { recognizer.setFullDocumentImageDpi(jsonObject.optInt("fullDocumentImageDpi", 250)); recognizer.setFullDocumentImageExtensionFactors(SerializationUtils.deserializeExtensionFactors(jsonObject.optJSONObject("fullDocumentImageExtensionFactors"))); recognizer.setPaddingEdge((float)jsonObject.optDouble("paddingEdge", 0.0)); - recognizer.setRecognitionModeFilter(SerializationUtils.deserializeRecognitionModeFilter(jsonObject.optJSONObject("recognitionModeFilter"))); + recognizer.setRecognitionModeFilter(BlinkIDSerializationUtils.deserializeRecognitionModeFilter(jsonObject.optJSONObject("recognitionModeFilter"))); recognizer.setReturnFaceImage(jsonObject.optBoolean("returnFaceImage", false)); recognizer.setReturnFullDocumentImage(jsonObject.optBoolean("returnFullDocumentImage", false)); recognizer.setReturnSignatureImage(jsonObject.optBoolean("returnSignatureImage", false)); diff --git a/BlinkID/src/android/libBlinkID.gradle b/BlinkID/src/android/libBlinkID.gradle index e66bfb2..4744cbe 100644 --- a/BlinkID/src/android/libBlinkID.gradle +++ b/BlinkID/src/android/libBlinkID.gradle @@ -2,11 +2,11 @@ repositories { jcenter() mavenCentral() //mavenLocal() - maven { url 'http://maven.microblink.com' } + maven { url 'https://maven.microblink.com' } } dependencies { - implementation('com.microblink:blinkid:5.11.0@aar') { + implementation('com.microblink:blinkid:5.12.0@aar') { transitive = true } } diff --git a/BlinkID/src/ios/sources/Overlays/MBOverlaySerializationUtils.m b/BlinkID/src/ios/sources/Overlays/MBOverlaySerializationUtils.m index a4c99c2..47c4063 100644 --- a/BlinkID/src/ios/sources/Overlays/MBOverlaySerializationUtils.m +++ b/BlinkID/src/ios/sources/Overlays/MBOverlaySerializationUtils.m @@ -32,8 +32,12 @@ +(void) extractCommonOverlaySettings:(NSDictionary *)jsonOverlaySettings overlay MBBaseOverlaySettings *baseOverlaySettings = (MBBaseOverlaySettings*)overlaySettings; { id enableBeep = [jsonOverlaySettings objectForKey:@"enableBeep"]; - if (enableBeep != nil && [(NSNumber*)enableBeep boolValue]) { - baseOverlaySettings.soundFilePath = @"PPBeep.wav"; + if ([enableBeep isKindOfClass:NSNumber.class]) { + if (((NSNumber*)enableBeep).boolValue) { + baseOverlaySettings.soundFilePath = @"PPBeep.wav"; + } else { + baseOverlaySettings.soundFilePath = @""; + } } } } diff --git a/BlinkID/src/ios/sources/Recognizers/Wrappers/MBBlinkIdCombinedRecognizerWrapper.m b/BlinkID/src/ios/sources/Recognizers/Wrappers/MBBlinkIdCombinedRecognizerWrapper.m index ced3cf0..1c7787a 100644 --- a/BlinkID/src/ios/sources/Recognizers/Wrappers/MBBlinkIdCombinedRecognizerWrapper.m +++ b/BlinkID/src/ios/sources/Recognizers/Wrappers/MBBlinkIdCombinedRecognizerWrapper.m @@ -23,6 +23,12 @@ -(MBRecognizer *) createRecognizer:(NSDictionary*) jsonRecognizer { recognizer.allowBlurFilter = [(NSNumber *)allowBlurFilter boolValue]; } } + { + id allowUncertainFrontSideScan = [jsonRecognizer valueForKey:@"allowUncertainFrontSideScan"]; + if (allowUncertainFrontSideScan != nil) { + recognizer.allowUncertainFrontSideScan = [(NSNumber *)allowUncertainFrontSideScan boolValue]; + } + } { id allowUnparsedMrzResults = [jsonRecognizer valueForKey:@"allowUnparsedMrzResults"]; if (allowUnparsedMrzResults != nil) { @@ -59,6 +65,12 @@ -(MBRecognizer *) createRecognizer:(NSDictionary*) jsonRecognizer { recognizer.fullDocumentImageExtensionFactors = [MBCommonSerializationUtils deserializeMBImageExtensionFactors:(NSDictionary*)fullDocumentImageExtensionFactors]; } } + { + id maxAllowedMismatchesPerField = [jsonRecognizer valueForKey:@"maxAllowedMismatchesPerField"]; + if (maxAllowedMismatchesPerField != nil) { + recognizer.maxAllowedMismatchesPerField = [(NSNumber *)maxAllowedMismatchesPerField integerValue]; + } + } { id paddingEdge = [jsonRecognizer valueForKey:@"paddingEdge"]; if (paddingEdge != nil) { @@ -137,6 +149,7 @@ -(NSDictionary *) serializeResult { [jsonResult setValue:self.result.address forKey:@"address"]; [jsonResult setValue:[NSNumber numberWithInteger:self.result.age] forKey:@"age"]; [jsonResult setValue:[MBBlinkIDSerializationUtils serializeImageAnalysisResult:self.result.backImageAnalysisResult] forKey:@"backImageAnalysisResult"]; + [jsonResult setValue:[NSNumber numberWithInteger:(self.result.backProcessingStatus + 1)] forKey:@"backProcessingStatus"]; [jsonResult setValue:[MBBlinkIDSerializationUtils serializeVizResult:self.result.backVizResult] forKey:@"backVizResult"]; [jsonResult setValue:[MBBlinkIDSerializationUtils serializeBarcodeResult:self.result.barcodeResult] forKey:@"barcodeResult"]; [jsonResult setValue:[MBBlinkIDSerializationUtils serializeClassInfo:self.result.classInfo] forKey:@"classInfo"]; @@ -156,6 +169,7 @@ -(NSDictionary *) serializeResult { [jsonResult setValue:[MBSerializationUtils encodeMBImage:self.result.faceImage] forKey:@"faceImage"]; [jsonResult setValue:self.result.firstName forKey:@"firstName"]; [jsonResult setValue:[MBBlinkIDSerializationUtils serializeImageAnalysisResult:self.result.frontImageAnalysisResult] forKey:@"frontImageAnalysisResult"]; + [jsonResult setValue:[NSNumber numberWithInteger:(self.result.frontProcessingStatus + 1)] forKey:@"frontProcessingStatus"]; [jsonResult setValue:[MBBlinkIDSerializationUtils serializeVizResult:self.result.frontVizResult] forKey:@"frontVizResult"]; [jsonResult setValue:[MBSerializationUtils encodeMBImage:self.result.fullDocumentBackImage] forKey:@"fullDocumentBackImage"]; [jsonResult setValue:[MBSerializationUtils encodeMBImage:self.result.fullDocumentFrontImage] forKey:@"fullDocumentFrontImage"]; diff --git a/BlinkID/www/blinkIdScanner.js b/BlinkID/www/blinkIdScanner.js index b0dd1a1..1616eb2 100644 --- a/BlinkID/www/blinkIdScanner.js +++ b/BlinkID/www/blinkIdScanner.js @@ -347,7 +347,10 @@ BlinkID.prototype.ProcessingStatus = Object.freeze( UnsupportedByLicense: 14, /** Front side recognition has completed successfully, and recognizer is waiting for the other side to be scanned. */ - AwaitingOtherSide: 15 + AwaitingOtherSide: 15, + + /** Side not scanned. */ + NotScanned: 16 } ); @@ -770,7 +773,12 @@ BlinkID.prototype.Region = Object.freeze( Tabasco: 106, TamilNadu: 107, Yucatan: 108, - Zacatecas: 109 + Zacatecas: 109, + Aguascalientes: 110, + BajaCaliforniaSur: 111, + Campeche: 112, + Colima: 113, + QuintanaRooBenitoJuarez: 114 } ); @@ -825,7 +833,8 @@ BlinkID.prototype.Type = Object.freeze( ProofOfAgeCard: 44, RefugeeId: 45, TribalId: 46, - VeteranId: 47 + VeteranId: 47, + CitizenshipCertificate: 48 } ); @@ -2055,25 +2064,6 @@ function BarcodeElements(nativeBarcodeElements) { this.values = nativeBarcodeElements.values; } -/** - * Result of the data matching algorithm for scanned parts/sides of the document. - */ -var DataMatchResult = Object.freeze( - { - /** Data matching has not been performed. */ - NotPerformed : 1, - /** Data does not match. */ - Failed : 2, - /** Data match. */ - Success : 3 - } -); - -/** - * Possible values for Document Data Match Result field. - */ -BlinkID.prototype.DataMatchResult = DataMatchResult - /** Possible supported detectors for documents containing face image */ var DocumentFaceDetectorType = Object.freeze( { @@ -2091,25 +2081,6 @@ var DocumentFaceDetectorType = Object.freeze( */ BlinkID.prototype.DocumentFaceDetectorType = DocumentFaceDetectorType; -/** - * Extension factors relative to corresponding dimension of the full image. For example, - * upFactor and downFactor define extensions relative to image height, e.g. - * when upFactor is 0.5, upper image boundary will be extended for half of image's full - * height. - */ -function ImageExtensionFactors() { - /** image extension factor relative to full image height in UP direction. */ - this.upFactor = 0.0; - /** image extension factor relative to full image height in RIGHT direction. */ - this.rightFactor = 0.0; - /** image extension factor relative to full image height in DOWN direction. */ - this.downFactor = 0.0; - /** image extension factor relative to full image height in LEFT direction. */ - this.leftFactor = 0.0; -} - -BlinkID.prototype.ImageExtensionFactors = ImageExtensionFactors; - /** * RecognitionModeFilter is used to enable/disable recognition of specific document groups. * Setting is taken into account only if the right for that document is purchased. @@ -2130,6 +2101,43 @@ function RecognitionModeFilter() { } BlinkID.prototype.RecognitionModeFilter = RecognitionModeFilter; +/** + * Result of the data matching algorithm for scanned parts/sides of the document. + */ +var DataMatchResult = Object.freeze( + { + /** Data matching has not been performed. */ + NotPerformed : 1, + /** Data does not match. */ + Failed : 2, + /** Data match. */ + Success : 3 + } +); + +/** + * Possible values for Document Data Match Result field. + */ +BlinkID.prototype.DataMatchResult = DataMatchResult + +/** + * Extension factors relative to corresponding dimension of the full image. For example, + * upFactor and downFactor define extensions relative to image height, e.g. + * when upFactor is 0.5, upper image boundary will be extended for half of image's full + * height. + */ +function ImageExtensionFactors() { + /** image extension factor relative to full image height in UP direction. */ + this.upFactor = 0.0; + /** image extension factor relative to full image height in RIGHT direction. */ + this.rightFactor = 0.0; + /** image extension factor relative to full image height in DOWN direction. */ + this.downFactor = 0.0; + /** image extension factor relative to full image height in LEFT direction. */ + this.leftFactor = 0.0; +} + +BlinkID.prototype.ImageExtensionFactors = ImageExtensionFactors; // COMMON CLASSES @@ -2381,6 +2389,11 @@ function BlinkIdCombinedRecognizerResult(nativeResult) { */ this.backImageAnalysisResult = nativeResult.backImageAnalysisResult; + /** + * Status of the last back side recognition process. + */ + this.backProcessingStatus = nativeResult.backProcessingStatus; + /** * Defines the data extracted from the back side visual inspection zone. */ @@ -2485,6 +2498,11 @@ function BlinkIdCombinedRecognizerResult(nativeResult) { */ this.frontImageAnalysisResult = nativeResult.frontImageAnalysisResult; + /** + * Status of the last front side recognition process. + */ + this.frontProcessingStatus = nativeResult.frontProcessingStatus; + /** * Defines the data extracted from the front side visual inspection zone. */ @@ -2610,6 +2628,14 @@ function BlinkIdCombinedRecognizer() { */ this.allowBlurFilter = true; + /** + * Proceed with scanning the back side even if the front side result is uncertain. + * This only works for still images - video feeds will ignore this setting. + * + * + */ + this.allowUncertainFrontSideScan = false; + /** * Defines whether returning of unparsed MRZ (Machine Readable Zone) results is allowed * @@ -2657,6 +2683,13 @@ function BlinkIdCombinedRecognizer() { */ this.fullDocumentImageExtensionFactors = new ImageExtensionFactors(); + /** + * Configure the number of characters per field that are allowed to be inconsistent in data match. + * + * + */ + this.maxAllowedMismatchesPerField = 0; + /** * Pading is a minimum distance from the edge of the frame and is defined as a percentage of the frame width. Default value is 0.0f and in that case * padding edge and image edge are the same. diff --git a/Release notes.md b/Release notes.md index 2526cda..b7f59d8 100644 --- a/Release notes.md +++ b/Release notes.md @@ -1,3 +1,6 @@ +## 5.12.0 +- Updated to [Android SDK v5.12.0](https://github.com/BlinkID/blinkid-android/releases/tag/v5.12.0) and [iOS SDK v5.12.0](https://github.com/BlinkID/blinkid-ios/releases/tag/v5.12.0) + ## 5.11.0 - Updated to [Android SDK v5.11.0](https://github.com/BlinkID/blinkid-android/releases/tag/v5.11.0) and [iOS SDK v5.11.0](https://github.com/BlinkID/blinkid-ios/releases/tag/v5.11.0) diff --git a/sample_files/www/js/index.js b/sample_files/www/js/index.js index e0f340d..2c435a1 100644 --- a/sample_files/www/js/index.js +++ b/sample_files/www/js/index.js @@ -77,8 +77,8 @@ var app = { // package name/bundleID com.microblink.sample var licenseKeys = { - android: 'sRwAAAAVY29tLm1pY3JvYmxpbmsuc2FtcGxlU9kJdZhZkGlTu9U3ORtDZCu0vFoxWJyF0dnv88NTiJO9pmEXPFZB9pVlO146QMSXVLAnYzACtQkatIeij7DU7ncIxLPulqRre/pOorG7HaWypuPGrotFAut0fJMJSckpf7QQC5N/97MV4Mdjk/JA6zeC83V0JqSEIMBisJRSeL4H1BqrcrDqhZpMjddPQQ+e8XVAmL2WxPsTubyqQDFvU6VSGE2nVIxbsXfpKApGRPSD7d+m46zsK6X86hMuMIu9sdtABD0AS0Bzm8HpaJZWkP51L6Ag9Dor9Iqluw0RTm+WgsQzycLBJ80iJwxryFiKOWtiPlvxQPAqn16CDT7J6h/z', - ios: 'sRwAAAEVY29tLm1pY3JvYmxpbmsuc2FtcGxl1BIcP4FpSuS/38JVOWaLMUMW+4CSRlPH5nVsy5f+xFjYutJX80GcvEyclw+SM7cjBwSazdaGilBWPcwulKICq141a1XBnYLt5nSyhDrP+PNnId8bqFT1ic1A71TubT8iroMgkbLhW7lnjNgPDyuw/2aqsS8U/pkkk8YgekN0IZm5M/0q1CSLtAehIswt5CoFtYcG1DIuGnaTvVNoRGUu7+HaVXAmxGFENiITmrOpLXFSJXFRdyBQHd3rfLgBDzIEPvTIGoGVD0ZUFFziRMkk+om4QIQE8bYHx0L8WFNbkXf5WMw2hlf3cUJmDOI04Xx1FYrTYKlbam6Q+5OsEHXjTIt5' + android: 'sRwAAAAVY29tLm1pY3JvYmxpbmsuc2FtcGxlU9kJdZhZkGlTu9U3Potlw+N+WELcAfo3ZNjCGrjwPbX72/Lj68v4Wsf9m+5MlNQBduVAB4w8aalo+BzHOMQomzhSX//WJlF+gsu8YbPc7YiWkKgmlubu9m4LOLM6yAaUWSoHauvy6imEIN0XB9ZOLRv/lN9+3zro2jbDglRX6TXDbLNjkYIUAZfmXEBW+smfQ0606630P6TBTps2nV8Dr/ZQcQ8H18tQOsG6nzFEbJoddztEOcWCp1pzNP8wHf3W848HxYiOqjTcXoA6GxzAJKyv6U2JUFZqlkiLNWok/qY6++srGoDsh0LXCu8xVwi/2MM8/DZ3Qqa9HkHIdJ6amkeifQ==', + ios: 'sRwAAAEVY29tLm1pY3JvYmxpbmsuc2FtcGxl1BIcP4FpSuS/38JVPpankFQ/Bcr7WvDAxkCq8h6GBBsKnan7jmJz5oRDF0VOwEv8zcz2tsAexgAWBzhWNxEvz2I2UYi7CSHjlbw0ppsdoL5WCQPrg6i+aiCRIxht1V8ObYlBvqTi69Pk0HXXwmpcIt7r01khjOlXdS7Mdn89IcW2R6bcYVIjID87iTpDG+SNFZ6ITQQsyv/c7VfkyEQ/2zl2J0Yln6a1OYGNCIDhfZjlTxK4H8ovNrrwvgR66jsKv0WBx2LLajjYOVdsMLueajw8caSpUlRtSpzCMAQB3FgD5OYEhDugRChfESwa4C8tAv7h9QUzU8TMpJeg7paXnee6MA==' }; function buildResult(result, key) {