UNPKG

@microblink/blinkid-in-browser-sdk

Version:

A simple ID scanning library for WebAssembly-enabled browsers.

966 lines 107 kB
/** * Copyright (c) Microblink Ltd. All rights reserved. */ import { Host, h, } from "@stencil/core"; import { CameraExperienceState, Code, MultiSideImageType, FeedbackCode, ImageRecognitionType, RecognitionStatus, SDKError, } from "../../../utils/data-structures"; import * as ErrorTypes from "../../../utils/error-structures"; import { sdkErrors, ErrorCodes, LicenseErrorType, } from "@microblink/blinkid-in-browser-sdk"; import * as DeviceHelpers from "../../../utils/device.helpers"; import * as GenericHelpers from "../../../utils/generic.helpers"; import * as Utils from "./mb-component.utils"; export class MbComponent { constructor() { this.screens = { action: null, error: null, loading: null, processing: null, }; this.overlays = { camera: null, draganddrop: null, processing: null, modal: null, }; this.gracePeriodEntered = false; this.scanReset = false; this.detectionSuccessLock = false; this.isBackSide = false; this.cameraChangeInProgress = false; this.blocked = false; this.multiSideGalleryOpened = false; this.areHelpScreensOpen = false; this.galleryImageFirstFile = null; this.galleryImageSecondFile = null; this.isCameraActive = false; this.terminateHelpScreens = async () => { this.areHelpScreensOpen = false; await this.cameraExperience.terminateHelpScreens(); }; this.initializeHelpScreensAndStartOnboarding = async () => { this.areHelpScreensOpen = false; await this.cameraExperience.initializeHelpScreens({ onOpen: () => { this.areHelpScreensOpen = true; this.sdkService.videoRecognizer.pauseRecognition(); }, onClose: () => { this.areHelpScreensOpen = false; this.sdkService.videoRecognizer.resumeRecognition(false); }, }); await this.cameraExperience.openHelpScreensOnboarding(); }; this.galleryExperienceModalErrorWindowVisible = false; this.clearIsCameraActive = false; this.apiProcessStatusVisible = false; this.apiProcessStatusState = "NONE"; this.allowHelloMessage = true; this.engineLocation = ""; this.workerLocation = ""; this.licenseKey = undefined; this.wasmType = undefined; this.blinkIdVariant = undefined; this.recognizers = undefined; this.recognizerOptions = undefined; this.recognitionTimeout = undefined; this.recognitionPauseTimeout = undefined; this.cameraExperienceStateDurations = null; this.includeSuccessFrame = false; this.enableDrag = true; this.hideLoadingAndErrorUi = false; this.rtl = false; this.scanFromCamera = true; this.scanFromImage = true; this.thoroughScanFromImage = false; this.galleryOverlayType = "INLINE"; this.galleryDropType = "INLINE"; this.showActionLabels = false; this.showModalWindows = false; this.showCameraFeedbackBarcodeMessage = false; this.showScanningLine = false; this.iconCameraDefault = 'data:image/svg+xml;utf8,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.32151 2.98816C6.63407 2.6756 7.05799 2.5 7.50002 2.5H12.5C12.942 2.5 13.366 2.6756 13.6785 2.98816C13.9911 3.30072 14.1667 3.72464 14.1667 4.16667C14.1667 4.38768 14.2545 4.59964 14.4108 4.75592C14.567 4.9122 14.779 5 15 5H15.8334C16.4964 5 17.1323 5.26339 17.6011 5.73223C18.07 6.20107 18.3334 6.83696 18.3334 7.5V15C18.3334 15.663 18.07 16.2989 17.6011 16.7678C17.1323 17.2366 16.4964 17.5 15.8334 17.5H4.16669C3.50365 17.5 2.86776 17.2366 2.39892 16.7678C1.93008 16.2989 1.66669 15.663 1.66669 15V7.5C1.66669 6.83696 1.93008 6.20107 2.39892 5.73223C2.86776 5.26339 3.50365 5 4.16669 5H5.00002C5.22103 5 5.433 4.9122 5.58928 4.75592C5.74556 4.59964 5.83335 4.38768 5.83335 4.16667C5.83335 3.72464 6.00895 3.30072 6.32151 2.98816ZM4.16669 6.66667C3.94567 6.66667 3.73371 6.75446 3.57743 6.91074C3.42115 7.06702 3.33335 7.27899 3.33335 7.5V15C3.33335 15.221 3.42115 15.433 3.57743 15.5893C3.73371 15.7455 3.94567 15.8333 4.16669 15.8333H15.8334C16.0544 15.8333 16.2663 15.7455 16.4226 15.5893C16.5789 15.433 16.6667 15.221 16.6667 15V7.5C16.6667 7.27899 16.5789 7.06702 16.4226 6.91074C16.2663 6.75446 16.0544 6.66667 15.8334 6.66667H15C14.337 6.66667 13.7011 6.40327 13.2323 5.93443C12.7634 5.46559 12.5 4.82971 12.5 4.16667L7.50002 4.16667C7.50002 4.82971 7.23663 5.46559 6.76779 5.93443C6.29895 6.40327 5.66306 6.66667 5.00002 6.66667H4.16669Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M10 9.16667C9.07955 9.16667 8.33335 9.91286 8.33335 10.8333C8.33335 11.7538 9.07955 12.5 10 12.5C10.9205 12.5 11.6667 11.7538 11.6667 10.8333C11.6667 9.91286 10.9205 9.16667 10 9.16667ZM6.66669 10.8333C6.66669 8.99238 8.15907 7.5 10 7.5C11.841 7.5 13.3334 8.99238 13.3334 10.8333C13.3334 12.6743 11.841 14.1667 10 14.1667C8.15907 14.1667 6.66669 12.6743 6.66669 10.8333Z" fill="black"/></svg>'; this.iconCameraActive = 'data:image/svg+xml;utf8,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M6.32151 2.98816C6.63407 2.6756 7.05799 2.5 7.50002 2.5H12.5C12.942 2.5 13.366 2.6756 13.6785 2.98816C13.9911 3.30072 14.1667 3.72464 14.1667 4.16667C14.1667 4.38768 14.2545 4.59964 14.4108 4.75592C14.567 4.9122 14.779 5 15 5H15.8334C16.4964 5 17.1323 5.26339 17.6011 5.73223C18.07 6.20107 18.3334 6.83696 18.3334 7.5V15C18.3334 15.663 18.07 16.2989 17.6011 16.7678C17.1323 17.2366 16.4964 17.5 15.8334 17.5H4.16669C3.50365 17.5 2.86776 17.2366 2.39892 16.7678C1.93008 16.2989 1.66669 15.663 1.66669 15V7.5C1.66669 6.83696 1.93008 6.20107 2.39892 5.73223C2.86776 5.26339 3.50365 5 4.16669 5H5.00002C5.22103 5 5.433 4.9122 5.58928 4.75592C5.74556 4.59964 5.83335 4.38768 5.83335 4.16667C5.83335 3.72464 6.00895 3.30072 6.32151 2.98816ZM4.16669 6.66667C3.94567 6.66667 3.73371 6.75446 3.57743 6.91074C3.42115 7.06702 3.33335 7.27899 3.33335 7.5V15C3.33335 15.221 3.42115 15.433 3.57743 15.5893C3.73371 15.7455 3.94567 15.8333 4.16669 15.8333H15.8334C16.0544 15.8333 16.2663 15.7455 16.4226 15.5893C16.5789 15.433 16.6667 15.221 16.6667 15V7.5C16.6667 7.27899 16.5789 7.06702 16.4226 6.91074C16.2663 6.75446 16.0544 6.66667 15.8334 6.66667H15C14.337 6.66667 13.7011 6.40327 13.2323 5.93443C12.7634 5.46559 12.5 4.82971 12.5 4.16667L7.50002 4.16667C7.50002 4.82971 7.23663 5.46559 6.76779 5.93443C6.29895 6.40327 5.66306 6.66667 5.00002 6.66667H4.16669Z" fill="%2348B2E8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M10 9.16667C9.07955 9.16667 8.33335 9.91286 8.33335 10.8333C8.33335 11.7538 9.07955 12.5 10 12.5C10.9205 12.5 11.6667 11.7538 11.6667 10.8333C11.6667 9.91286 10.9205 9.16667 10 9.16667ZM6.66669 10.8333C6.66669 8.99238 8.15907 7.5 10 7.5C11.841 7.5 13.3334 8.99238 13.3334 10.8333C13.3334 12.6743 11.841 14.1667 10 14.1667C8.15907 14.1667 6.66669 12.6743 6.66669 10.8333Z" fill="%2348B2E8"/></svg>'; this.iconGalleryDefault = 'data:image/svg+xml;utf8,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.6667 6.66666C11.6667 6.20642 12.0398 5.83333 12.5 5.83333H12.5084C12.9686 5.83333 13.3417 6.20642 13.3417 6.66666C13.3417 7.1269 12.9686 7.5 12.5084 7.5H12.5C12.0398 7.5 11.6667 7.1269 11.6667 6.66666Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5.83333 4.16667C4.91286 4.16667 4.16667 4.91286 4.16667 5.83333V14.1667C4.16667 15.0871 4.91286 15.8333 5.83333 15.8333H14.1667C15.0871 15.8333 15.8333 15.0871 15.8333 14.1667V5.83333C15.8333 4.91286 15.0871 4.16667 14.1667 4.16667H5.83333ZM2.5 5.83333C2.5 3.99238 3.99238 2.5 5.83333 2.5H14.1667C16.0076 2.5 17.5 3.99238 17.5 5.83333V14.1667C17.5 16.0076 16.0076 17.5 14.1667 17.5H5.83333C3.99238 17.5 2.5 16.0076 2.5 14.1667V5.83333Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.24972 9.76212L3.92259 13.0892C3.59715 13.4147 3.06951 13.4147 2.74408 13.0892C2.41864 12.7638 2.41864 12.2362 2.74408 11.9107L6.07741 8.57741L6.08885 8.56618C6.59083 8.08315 7.22016 7.7751 7.91667 7.7751C8.61317 7.7751 9.2425 8.08315 9.74448 8.56618L9.75592 8.57741L13.9226 12.7441C14.248 13.0695 14.248 13.5971 13.9226 13.9226C13.5972 14.248 13.0695 14.248 12.7441 13.9226L8.58361 9.76212C8.32758 9.51773 8.09662 9.44177 7.91667 9.44177C7.73672 9.44177 7.50575 9.51773 7.24972 9.76212Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M13.083 11.4288L12.2559 12.2559C11.9305 12.5814 11.4028 12.5814 11.0774 12.2559C10.752 11.9305 10.752 11.4028 11.0774 11.0774L11.9107 10.2441L11.9222 10.2329C12.4241 9.74982 13.0535 9.44177 13.75 9.44177C14.4465 9.44177 15.0758 9.74982 15.5778 10.2329L15.5892 10.2441L17.2559 11.9107C17.5813 12.2362 17.5813 12.7638 17.2559 13.0893C16.9305 13.4147 16.4028 13.4147 16.0774 13.0893L14.4169 11.4288C14.1609 11.1844 13.9299 11.1084 13.75 11.1084C13.57 11.1084 13.3391 11.1844 13.083 11.4288Z" fill="black"/></svg>'; this.iconDragAndDropGalleryDefault = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xNCA4QzE0IDcuNDQ3NzIgMTQuNDQ3NyA3IDE1IDdIMTUuMDFDMTUuNTYyMyA3IDE2LjAxIDcuNDQ3NzIgMTYuMDEgOEMxNi4wMSA4LjU1MjI4IDE1LjU2MjMgOSAxNS4wMSA5SDE1QzE0LjQ0NzcgOSAxNCA4LjU1MjI4IDE0IDhaIiBmaWxsPSIjMDA2MkYyIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNNyA1QzUuODk1NDMgNSA1IDUuODk1NDMgNSA3VjE3QzUgMTguMTA0NiA1Ljg5NTQzIDE5IDcgMTlIMTdDMTguMTA0NiAxOSAxOSAxOC4xMDQ2IDE5IDE3VjdDMTkgNS44OTU0MyAxOC4xMDQ2IDUgMTcgNUg3Wk0zIDdDMyA0Ljc5MDg2IDQuNzkwODYgMyA3IDNIMTdDMTkuMjA5MSAzIDIxIDQuNzkwODYgMjEgN1YxN0MyMSAxOS4yMDkxIDE5LjIwOTEgMjEgMTcgMjFIN0M0Ljc5MDg2IDIxIDMgMTkuMjA5MSAzIDE3VjdaIiBmaWxsPSIjMDA2MkYyIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNOC42OTk2NiAxMS43MTQ1TDQuNzA3MTEgMTUuNzA3MUM0LjMxNjU4IDE2LjA5NzYgMy42ODM0MiAxNi4wOTc2IDMuMjkyODkgMTUuNzA3MUMyLjkwMjM3IDE1LjMxNjUgMi45MDIzNyAxNC42ODM0IDMuMjkyODkgMTQuMjkyOEw3LjI5Mjg5IDEwLjI5MjhMNy4zMDY2MiAxMC4yNzk0QzcuOTA5IDkuNjk5NzQgOC42NjQxOSA5LjMzMDA4IDkuNSA5LjMzMDA4QzEwLjMzNTggOS4zMzAwOCAxMS4wOTEgOS42OTk3NCAxMS42OTM0IDEwLjI3OTRMMTEuNzA3MSAxMC4yOTI4TDE2LjcwNzEgMTUuMjkyOEMxNy4wOTc2IDE1LjY4MzQgMTcuMDk3NiAxNi4zMTY1IDE2LjcwNzEgMTYuNzA3MUMxNi4zMTY2IDE3LjA5NzYgMTUuNjgzNCAxNy4wOTc2IDE1LjI5MjkgMTYuNzA3MUwxMC4zMDAzIDExLjcxNDVDOS45OTMxIDExLjQyMTIgOS43MTU5NCAxMS4zMzAxIDkuNSAxMS4zMzAxQzkuMjg0MDYgMTEuMzMwMSA5LjAwNjkgMTEuNDIxMiA4LjY5OTY2IDExLjcxNDVaIiBmaWxsPSIjMDA2MkYyIi8+CjxwYXRoIGZpbGwtcnVsZT0iZXZlbm9kZCIgY2xpcC1ydWxlPSJldmVub2RkIiBkPSJNMTUuNjk5NyAxMy43MTQ1TDE0LjcwNzEgMTQuNzA3MUMxNC4zMTY2IDE1LjA5NzYgMTMuNjgzNCAxNS4wOTc2IDEzLjI5MjkgMTQuNzA3MUMxMi45MDI0IDE0LjMxNjUgMTIuOTAyNCAxMy42ODM0IDEzLjI5MjkgMTMuMjkyOEwxNC4yOTI5IDEyLjI5MjhMMTQuMzA2NiAxMi4yNzk0QzE0LjkwOSAxMS42OTk3IDE1LjY2NDIgMTEuMzMwMSAxNi41IDExLjMzMDFDMTcuMzM1OCAxMS4zMzAxIDE4LjA5MSAxMS42OTk3IDE4LjY5MzQgMTIuMjc5NEwxOC43MDcxIDEyLjI5MjhMMjAuNzA3MSAxNC4yOTI4QzIxLjA5NzYgMTQuNjgzNCAyMS4wOTc2IDE1LjMxNjUgMjAuNzA3MSAxNS43MDcxQzIwLjMxNjYgMTYuMDk3NiAxOS42ODM0IDE2LjA5NzYgMTkuMjkyOSAxNS43MDcxTDE3LjMwMDMgMTMuNzE0NUMxNi45OTMxIDEzLjQyMTIgMTYuNzE1OSAxMy4zMzAxIDE2LjUgMTMuMzMwMUMxNi4yODQxIDEzLjMzMDEgMTYuMDA2OSAxMy40MjEyIDE1LjY5OTcgMTMuNzE0NVoiIGZpbGw9IiMwMDYyRjIiLz4KPC9zdmc+Cg=="; this.iconDragAndDropWarningDefault = "data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iMjQiIGhlaWdodD0iMjQiIHZpZXdCb3g9IjAgMCAyNCAyNCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMiA4QzEyLjU1MjMgOCAxMyA4LjQ0NzcyIDEzIDlWMTFDMTMgMTEuNTUyMyAxMi41NTIzIDEyIDEyIDEyQzExLjQ0NzcgMTIgMTEgMTEuNTUyMyAxMSAxMVY5QzExIDguNDQ3NzIgMTEuNDQ3NyA4IDEyIDhaTTEyIDE0QzEyLjU1MjMgMTQgMTMgMTQuNDQ3NyAxMyAxNVYxNS4wMUMxMyAxNS41NjIzIDEyLjU1MjMgMTYuMDEgMTIgMTYuMDFDMTEuNDQ3NyAxNi4wMSAxMSAxNS41NjIzIDExIDE1LjAxVjE1QzExIDE0LjQ0NzcgMTEuNDQ3NyAxNCAxMiAxNFoiIGZpbGw9IiNFMTFENDgiLz4KPHBhdGggZmlsbC1ydWxlPSJldmVub2RkIiBjbGlwLXJ1bGU9ImV2ZW5vZGQiIGQ9Ik0xMC40NzY0IDIuMzgzOTdDMTAuOTM4MSAyLjExMTgxIDExLjQ2NDIgMS45NjgyNiAxMi4wMDAxIDEuOTY4MjZDMTIuNTM1OSAxLjk2ODI2IDEzLjA2MjEgMi4xMTE4MSAxMy41MjM3IDIuMzgzOTdDMTMuOTgzMSAyLjY1NDg1IDE0LjM2MiAzLjA0MzMgMTQuNjIxNCAzLjUwOTI1TDIxLjYxODMgMTUuNzUzOUMyMS42NDA0IDE1Ljc5MjUgMjEuNjU5OCAxNS44MzI1IDIxLjY3NjUgMTUuODczN0MyMS44NTY2IDE2LjMxNzEgMjEuOTI4IDE2Ljc5NzEgMjEuODg0OCAxNy4yNzM3QzIxLjg0MTYgMTcuNzUwMiAyMS42ODUgMTguMjA5NiAyMS40MjgxIDE4LjYxMzNDMjEuMTcxMSAxOS4wMTcgMjAuODIxNCAxOS4zNTM0IDIwLjQwOCAxOS41OTQ0QzE5Ljk5NDUgMTkuODM1NCAxOS41Mjk0IDE5Ljk3NDEgMTkuMDUxNSAxOS45OTg3QzE5LjAzNDQgMTkuOTk5NiAxOS4wMTcyIDIwIDE5LjAwMDEgMjBINS4wNzAwNUM1LjA1ODU3IDIwIDUuMDQ3MTQgMTkuOTk5OCA1LjAzNTc1IDE5Ljk5OTRDNS4wMDY5NiAyMC4wMDA0IDQuOTc3ODggMjAuMDAwMiA0Ljk0ODU3IDE5Ljk5ODdDNC40NzA2NiAxOS45NzQxIDQuMDA1NTggMTkuODM1NCAzLjU5MjE2IDE5LjU5NDRDMy4xNzg3MyAxOS4zNTM0IDIuODI4OTYgMTkuMDE3IDIuNTcyMDQgMTguNjEzM0MyLjMxNTEzIDE4LjIwOTYgMi4xNTg1MiAxNy43NTAyIDIuMTE1MjkgMTcuMjczN0MyLjA3MjA3IDE2Ljc5NzEgMi4xNDM0OCAxNi4zMTcxIDIuMzIzNTcgMTUuODczN0MyLjM0MDMgMTUuODMyNSAyLjM1OTc1IDE1Ljc5MjUgMi4zODE4MSAxNS43NTM5TDkuMzc4NzQgMy41MDkyNUM5LjYzODA4IDMuMDQzMyAxMC4wMTcgMi42NTQ4NSAxMC40NzY0IDIuMzgzOTdaTTUuMDM3NjcgMTguMDAwNUM1LjA0ODQyIDE4LjAwMDIgNS4wNTkyMiAxOCA1LjA3MDA1IDE4SDE4Ljk2OTlDMTkuMTIxNyAxNy45ODg5IDE5LjI2OTEgMTcuOTQzMyAxOS40MDA3IDE3Ljg2NjZDMTkuNTM4NSAxNy43ODYzIDE5LjY1NTEgMTcuNjc0MSAxOS43NDA3IDE3LjUzOTVDMTkuODI2NCAxNy40MDUgMTkuODc4NiAxNy4yNTE5IDE5Ljg5MyAxNy4wOTNDMTkuOTA1NyAxNi45NTI1IDE5Ljg4ODYgMTYuODExMiAxOS44NDMgMTYuNjc4MkwxMi44NzUgNC40ODQxOEMxMi43ODg1IDQuMzI3ODggMTIuNjYxOCA0LjE5NzU1IDEyLjUwNzkgNC4xMDY4M0MxMi4zNTQxIDQuMDE2MTEgMTIuMTc4NyAzLjk2ODI2IDEyLjAwMDEgMy45NjgyNkMxMS44MjE0IDMuOTY4MjYgMTEuNjQ2MSA0LjAxNjExIDExLjQ5MjIgNC4xMDY4M0MxMS4zMzgzIDQuMTk3NTUgMTEuMjExNSA0LjMyNzg0IDExLjEyNTEgNC40ODQxNEwxMS4xMTg0IDQuNDk2Mkw0LjE1NzE0IDE2LjY3ODJDNC4xMTE1MSAxNi44MTEyIDQuMDk0MzggMTYuOTUyNSA0LjEwNzEyIDE3LjA5M0M0LjEyMTUyIDE3LjI1MTkgNC4xNzM3MyAxNy40MDUgNC4yNTkzNyAxNy41Mzk1QzQuMzQ1MDEgMTcuNjc0MSA0LjQ2MTYgMTcuNzg2MyA0LjU5OTQgMTcuODY2NkM0LjczMzIxIDE3Ljk0NDYgNC44ODMyNCAxNy45OTA0IDUuMDM3NjcgMTguMDAwNVoiIGZpbGw9IiNFMTFENDgiLz4KPC9zdmc+Cg=="; this.iconGalleryActive = 'data:image/svg+xml;utf8,<svg width="20" height="20" viewBox="0 0 20 20" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M11.6667 6.66667C11.6667 6.20643 12.0398 5.83334 12.5 5.83334H12.5084C12.9686 5.83334 13.3417 6.20643 13.3417 6.66667C13.3417 7.12691 12.9686 7.5 12.5084 7.5H12.5C12.0398 7.5 11.6667 7.12691 11.6667 6.66667Z" fill="%2348B2E8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M5.83333 4.16667C4.91286 4.16667 4.16667 4.91286 4.16667 5.83333V14.1667C4.16667 15.0871 4.91286 15.8333 5.83333 15.8333H14.1667C15.0871 15.8333 15.8333 15.0871 15.8333 14.1667V5.83333C15.8333 4.91286 15.0871 4.16667 14.1667 4.16667H5.83333ZM2.5 5.83333C2.5 3.99238 3.99238 2.5 5.83333 2.5H14.1667C16.0076 2.5 17.5 3.99238 17.5 5.83333V14.1667C17.5 16.0076 16.0076 17.5 14.1667 17.5H5.83333C3.99238 17.5 2.5 16.0076 2.5 14.1667V5.83333Z" fill="%2348B2E8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M7.24972 9.76213L3.92259 13.0893C3.59715 13.4147 3.06951 13.4147 2.74408 13.0893C2.41864 12.7638 2.41864 12.2362 2.74408 11.9107L6.07741 8.57741L6.08885 8.56619C6.59083 8.08316 7.22016 7.77511 7.91667 7.77511C8.61317 7.77511 9.2425 8.08316 9.74448 8.56619L9.75592 8.57741L13.9226 12.7441C14.248 13.0695 14.248 13.5972 13.9226 13.9226C13.5972 14.248 13.0695 14.248 12.7441 13.9226L8.58361 9.76213C8.32758 9.51774 8.09662 9.44177 7.91667 9.44177C7.73672 9.44177 7.50575 9.51774 7.24972 9.76213Z" fill="%2348B2E8"/><path fill-rule="evenodd" clip-rule="evenodd" d="M13.083 11.4288L12.2559 12.2559C11.9305 12.5814 11.4028 12.5814 11.0774 12.2559C10.752 11.9305 10.752 11.4028 11.0774 11.0774L11.9107 10.2441L11.9222 10.2329C12.4241 9.74982 13.0535 9.44177 13.75 9.44177C14.4465 9.44177 15.0758 9.74982 15.5778 10.2329L15.5892 10.2441L17.2559 11.9107C17.5813 12.2362 17.5813 12.7638 17.2559 13.0893C16.9305 13.4147 16.4028 13.4147 16.0774 13.0893L14.4169 11.4288C14.1609 11.1844 13.9299 11.1084 13.75 11.1084C13.57 11.1084 13.3391 11.1844 13.083 11.4288Z" fill="%2348B2E8"/></svg>'; this.iconInvalidFormat = 'data:image/svg+xml;utf8,<svg width="24" height="24" viewBox="0 0 24 24" fill="none" xmlns="http://www.w3.org/2000/svg"><path fill-rule="evenodd" clip-rule="evenodd" d="M12 4C7.58172 4 4 7.58172 4 12C4 16.4183 7.58172 20 12 20C16.4183 20 20 16.4183 20 12C20 7.58172 16.4183 4 12 4ZM2 12C2 6.47715 6.47715 2 12 2C17.5228 2 22 6.47715 22 12C22 17.5228 17.5228 22 12 22C6.47715 22 2 17.5228 2 12Z" fill="black"/><path fill-rule="evenodd" clip-rule="evenodd" d="M9.29289 9.29289C9.68342 8.90237 10.3166 8.90237 10.7071 9.29289L12 10.5858L13.2929 9.29289C13.6834 8.90237 14.3166 8.90237 14.7071 9.29289C15.0976 9.68342 15.0976 10.3166 14.7071 10.7071L13.4142 12L14.7071 13.2929C15.0976 13.6834 15.0976 14.3166 14.7071 14.7071C14.3166 15.0976 13.6834 15.0976 13.2929 14.7071L12 13.4142L10.7071 14.7071C10.3166 15.0976 9.68342 15.0976 9.29289 14.7071C8.90237 14.3166 8.90237 13.6834 9.29289 13.2929L10.5858 12L9.29289 10.7071C8.90237 10.3166 8.90237 9.68342 9.29289 9.29289Z" fill="black"/></svg>'; this.iconSpinnerScreenLoading = undefined; this.iconSpinnerFromGalleryExperience = undefined; this.iconGalleryScanningCompleted = undefined; this.sdkService = undefined; this.translationService = undefined; this.cameraId = null; this.allowHelpScreens = false; this.allowHelpScreensFab = false; this.allowHelpScreensOnboarding = false; this.allowHelpScreensOnboardingPerpetuity = false; this.helpScreensTooltipPauseTimeout = 15000; this.pingProxyUrl = null; } componentDidLoad() { // Set `exportparts` attribute on root `mb-component` element to enable ::part() CSS customization GenericHelpers.setWebComponentParts(this.hostEl); const parts = GenericHelpers.getWebComponentParts(this.hostEl.shadowRoot); const exportedParts = GenericHelpers.getWebComponentExportedParts(this.hostEl.shadowRoot); this.hostEl.setAttribute("exportparts", parts.concat(exportedParts).join(", ")); this.init(); } componentDidUpdate() { this.init(); } disconnectedCallback() { this.sdkService?.stopRecognition(); } handleKeyUp(ev) { if (ev.key === "Escape" || ev.code === "Escape") { if (this.overlays.camera.visible && this.isCameraActive) { this.abortScan(); this.handleSetIsCameraActive(false); this.clearIsCameraActive = true; } } } handleSetIsCameraActive(isCameraActive) { this.isCameraActive = isCameraActive; this.clearIsCameraActive = false; } /** * Starts camera scan using camera overlay with usage instructions. */ async startCameraScan() { this.startScanFromCamera(); } /** * Starts image scan, emits results from provided file. * * @param file File to scan */ async startImageScan(file) { this.startScanFromImage(file); } /** * Starts multi-side image scan, emits results from provided files. * * @param firstFile File to scan as first image * @param secondFile File to scan as second image */ async startMultiSideImageScan(firstFile, secondFile) { this.startScanFromImageMultiSide(firstFile, secondFile); } /** * Method is exposed outside which allow us to control UI state from parent component. * * In case of state `ERROR` and if `showModalWindows` is set to `true`, modal window * with error message will be displayed. */ async setUiState(state) { window.setTimeout(() => { if (this.overlays.camera.visible) { if (state === "ERROR" && !this.showModalWindows) { this.apiProcessStatusState = "NONE"; this.apiProcessStatusVisible = false; this.stopRecognition(); return; } this.apiProcessStatusState = state; this.apiProcessStatusVisible = true; if (state !== "ERROR") { this.cameraExperience.classList.add("is-muted"); } else { this.cameraExperience.classList.add("is-error"); } this.cameraExperience.apiState = state; } else if (this.overlays.processing.visible) { if (state === "ERROR") { if (this.showModalWindows) { this.galleryExperienceModalErrorWindowVisible = true; } else { this.galleryExperienceModalErrorWindowVisible = false; this.stopRecognition(); } } } if (state === "SUCCESS") { window.setTimeout(() => this.stopRecognition(), 400); } if (state === "ERROR") { this.hideScanFromImageUi(false); this.clearInputImages(); } }, 400); } async closeApiProcessStatus(restart = false) { window.setTimeout(() => { this.apiProcessStatusVisible = false; this.apiProcessStatusState = "NONE"; this.cameraExperience.classList.remove("is-muted"); this.cameraExperience.classList.remove("is-error"); }, 600); if (restart) { await this.checkInputProperties() .then(() => this.sdkService.resumeRecognition()) .then(() => { window.setTimeout(() => (this.cameraExperience.apiState = ""), 400); this.isBackSide = false; this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide, true); }); } } async init() { if (!this.hideLoadingAndErrorUi) { this.showScreen("loading"); this.showOverlay(""); } if (this.blocked) { return; } const internetIsAvailable = navigator.onLine; if (!internetIsAvailable) { this.setFatalError(new SDKError({ code: ErrorTypes.ErrorCodes.InternetNotAvailable, message: this.translationService .i("check-internet-connection") .toString(), })); return; } const hasMandatoryProperties = await this.checkInputProperties(); if (!hasMandatoryProperties) { return; } const hasMandatoryCapabilities = await DeviceHelpers.checkMandatoryCapabilites(); if (!hasMandatoryCapabilities) { this.setFatalError(new SDKError(ErrorTypes.componentErrors.browserNotSupported)); return; } this.blocked = true; this.block.emit(true); const initEvent = await this.sdkService.initialize(this.licenseKey, { allowHelloMessage: this.allowHelloMessage, engineLocation: this.engineLocation, workerLocation: this.workerLocation, wasmType: Utils.getSDKWasmType(this.wasmType), blinkIdVariant: this.blinkIdVariant, }); this.cameraExperience.showOverlay = this.sdkService.showOverlay; if (initEvent instanceof SDKError) { this.setFatalError(initEvent); return; } if (this.showActionLabels) { this.scanFromCameraButton.label = this.translationService .i("action-message-camera") .toString(); this.scanFromImageButton.label = this.translationService .i("action-message-image") .toString(); } if (this.scanFromCamera) { this.scanFromCameraButton.visible = true; const hasVideoDevices = await DeviceHelpers.hasVideoDevices(); this.scanFromCameraButton.disabled = !hasVideoDevices; if (!hasVideoDevices) { this.feedback.emit({ code: FeedbackCode.CameraDisabled, state: "FEEDBACK_INFO", message: this.translationService.i("camera-disabled").toString(), }); if (this.showActionLabels) { this.scanFromCameraButton.label = this.translationService .i("action-message-camera-disabled") .toString(); } } } if (this.scanFromImage) { this.scanFromImageButton.visible = true; const imageScanIsAvailable = this.sdkService.isScanFromImageAvailable(this.recognizers, this.recognizerOptions); this.scanFromImageButton.disabled = !imageScanIsAvailable; if (imageScanIsAvailable) { this.imageRecognitionType = this.sdkService.getScanFromImageType(this.recognizers, this.recognizerOptions); if (this.imageRecognitionType === ImageRecognitionType.SingleSide) { this.screens.processing.setAttribute("data-type", "single-sinde"); } if (this.imageRecognitionType === ImageRecognitionType.MultiSide) { this.screens.processing.setAttribute("data-type", "multi-side"); } } else { if (this.showActionLabels) { this.scanFromImageButton.label = this.translationService .i("action-message-image-not-supported") .toString(); } } } this.ready.emit(initEvent); this.blocked = false; this.block.emit(false); this.showScreen("action"); if (this.enableDrag) { this.setDragAndDrop(); } } async flipCameraAction() { await this.sdkService.flipCamera(); const cameraFlipped = await this.sdkService.isCameraFlipped(); this.cameraExperience.setCameraFlipState(cameraFlipped); } async changeCameraDevice(camera) { if (this.cameraChangeInProgress) { return; } this.cameraChangeInProgress = true; await this.sdkService.changeCameraDevice(camera.details); this.cameraChangeInProgress = false; } async checkInputProperties() { if (!this.licenseKey) { this.setFatalError(new SDKError(sdkErrors.licenseKeyMissing)); return false; } // Recognizers const conclusion = this.sdkService.checkRecognizers(this.recognizers); if (!conclusion.status) { const fatalError = new SDKError({ code: ErrorTypes.ErrorCodes.InvalidRecognizers, message: conclusion.message, }); this.setFatalError(fatalError); return false; } this.cameraExperience.type = this.sdkService.getDesiredCameraExperience(this.recognizers, this.recognizerOptions); return true; } async startScanFromCamera() { const configuration = { pingProxyUrl: this.pingProxyUrl, recognizers: this.recognizers, successFrame: this.includeSuccessFrame, cameraFeed: this.videoElement, cameraId: this.cameraId, }; if (this.recognizerOptions && Object.keys(this.recognizerOptions).length > 0) { configuration.recognizerOptions = this.recognizerOptions; } if (this.recognitionTimeout && typeof this.recognitionTimeout === "number") { configuration.recognitionTimeout = this.recognitionTimeout; } this.isBackSide = false; const eventHandler = async (recognitionEvent) => { switch (recognitionEvent.status) { case RecognitionStatus.Preparing: this.feedback.emit({ code: FeedbackCode.ScanStarted, state: "FEEDBACK_OK", message: "", }); this.showOverlay("camera"); this.cameraExperience.setState(CameraExperienceState.Default); break; case RecognitionStatus.Ready: this.cameraExperience.setActiveCamera(this.sdkService.videoRecognizer.deviceId); break; case RecognitionStatus.Processing: // Just keep working break; case RecognitionStatus.EmptyResultState: if (!recognitionEvent.data.initiatedByUser) { this.scanError.emit({ code: Code.EmptyResult, fatal: false, message: "Could not extract information from video feed!", recognizerName: recognitionEvent.data.recognizerName, }); this.feedback.emit({ code: FeedbackCode.ScanUnsuccessful, state: "FEEDBACK_ERROR", message: this.translationService .i("feedback-scan-unsuccessful") .toString(), }); } this.showOverlay(""); break; case RecognitionStatus.UnknownError: // Do nothing, RecognitionStatus.EmptyResultState will handle negative outcome break; case RecognitionStatus.DetectionFailed: this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); this.detectionSuccessLock = false; break; case RecognitionStatus.DetectionStatusFail: this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); break; case RecognitionStatus.DetectionStatusSuccess: this.detectionSuccessLock = true; window.setTimeout(() => { if (this.detectionSuccessLock) { this.cameraExperience.setState(CameraExperienceState.Detection); this.scanReset = false; } }, 100); break; case RecognitionStatus.DetectionStatusCameraTooHigh: this.cameraExperience .setState(CameraExperienceState.MoveCloser) .then(() => { this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); }); break; case RecognitionStatus.DetectionStatusCameraAtAngle: this.cameraExperience .setState(CameraExperienceState.AdjustAngle) .then(() => { this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); }); break; case RecognitionStatus.DetectionStatusCameraTooNear: case RecognitionStatus.DetectionStatusDocumentTooCloseToEdge: case RecognitionStatus.DetectionStatusPartial: this.cameraExperience .setState(CameraExperienceState.MoveFarther) .then(() => { this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); }); break; case RecognitionStatus.GlareDetected: this.cameraExperience.setState(CameraExperienceState.GlareDetected); break; case RecognitionStatus.BlurDetected: this.cameraExperience.setState(CameraExperienceState.BlurDetected); break; case RecognitionStatus.WrongSide: this.cameraExperience.setState(CameraExperienceState.WrongSide); break; // scan passport - error spinner case RecognitionStatus.MovePassportDownError: { if (this.gracePeriodEntered) { this.cameraExperience.setState(CameraExperienceState.ScanPassportDown); } else { this.cameraExperience.setState(CameraExperienceState.MovePassportDownError); } break; } case RecognitionStatus.MovePassportUpError: { if (this.gracePeriodEntered) { this.cameraExperience.setState(CameraExperienceState.ScanPassportUp); } else { this.cameraExperience.setState(CameraExperienceState.MovePassportUpError); } break; } case RecognitionStatus.MovePassportLeftError: { if (this.gracePeriodEntered) { this.cameraExperience.setState(CameraExperienceState.ScanPassportLeft); } else { this.cameraExperience.setState(CameraExperienceState.MovePassportLeftError); } break; } case RecognitionStatus.MovePassportRightError: { if (this.gracePeriodEntered) { this.cameraExperience.setState(CameraExperienceState.ScanPassportRight); } else { this.cameraExperience.setState(CameraExperienceState.MovePassportRightError); } break; } case RecognitionStatus.FacePhotoCovered: this.cameraExperience.setState(CameraExperienceState.FacePhotoCovered); break; case RecognitionStatus.BarcodeScanningStarted: this.cameraExperience .setState(CameraExperienceState.BarcodeScanning, this.isBackSide, true) .then(() => { this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); }); break; case RecognitionStatus.DocumentClassified: this.cameraExperience.setState(CameraExperienceState.Classification); break; // passport // "flip" passport case RecognitionStatus.MovePassportDown: case RecognitionStatus.MovePassportUp: case RecognitionStatus.MovePassportLeft: case RecognitionStatus.MovePassportRight: { // handle all as "flip card" this.sdkService.videoRecognizer.pauseRecognition(); window.setTimeout(async () => { if (this.areHelpScreensOpen) { return; // help screens close will resume } await this.sdkService.videoRecognizer.resumeRecognition(false); }, this.recognitionPauseTimeout); // This state doesn't seem to do anything await this.cameraExperience.setState(CameraExperienceState.Done, false, true); // treat each case separately here if (recognitionEvent.status === RecognitionStatus.MovePassportDown) { await this.cameraExperience.setState(CameraExperienceState.MovePassportDown); } if (recognitionEvent.status === RecognitionStatus.MovePassportUp) { await this.cameraExperience.setState(CameraExperienceState.MovePassportUp); } if (recognitionEvent.status === RecognitionStatus.MovePassportLeft) { await this.cameraExperience.setState(CameraExperienceState.MovePassportLeft); } if (recognitionEvent.status === RecognitionStatus.MovePassportRight) { await this.cameraExperience.setState(CameraExperienceState.MovePassportRight); } this.gracePeriodEntered = true; window.setTimeout(() => { this.gracePeriodEntered = false; }, 3000); if (!this.scanReset) { this.isBackSide = true; this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); } break; } // just "scan" passport case RecognitionStatus.ScanPassportDown: this.cameraExperience.setState(CameraExperienceState.ScanPassportDown); break; case RecognitionStatus.ScanPassportUp: this.cameraExperience.setState(CameraExperienceState.ScanPassportUp); break; case RecognitionStatus.ScanPassportLeft: this.cameraExperience.setState(CameraExperienceState.ScanPassportLeft); break; case RecognitionStatus.ScanPassportRight: this.cameraExperience.setState(CameraExperienceState.ScanPassportRight); break; // handle flipping of other documents case RecognitionStatus.OnFirstSideResult: this.sdkService.videoRecognizer.pauseRecognition(); window.setTimeout(async () => { if (this.areHelpScreensOpen) { return; // help screens close will resume } await this.sdkService.videoRecognizer.resumeRecognition(false); }, this.recognitionPauseTimeout); this.cameraExperience // This state doesn't seem to do anything .setState(CameraExperienceState.Done, false, true) .then(() => { this.cameraExperience .setState(CameraExperienceState.Flip, this.isBackSide, true) .then(() => { if (!this.scanReset) { this.isBackSide = true; this.cameraExperience.setState(CameraExperienceState.Default, this.isBackSide); } }); }); break; case RecognitionStatus.ScanSuccessful: this.cameraExperience .setState(CameraExperienceState.DoneAll, false, true) .then(() => { this.cameraExperience.resetState(); this.terminateHelpScreens(); this.cameraExperience.classList.add("hide"); this.scanSuccess.emit(recognitionEvent.data?.result); this.feedback.emit({ code: FeedbackCode.ScanSuccessful, state: "FEEDBACK_OK", message: "", }); this.showOverlay(""); }); break; case RecognitionStatus.CameraNotAllowed: this.scanError.emit({ code: Code.CameraNotAllowed, fatal: true, message: "Cannot access camera!", recognizerName: "", }); this.feedback.emit({ code: FeedbackCode.CameraNotAllowed, state: "FEEDBACK_ERROR", message: this.translationService.i("camera-not-allowed").toString(), }); window.setTimeout(() => { this.scanFromCameraButton.disabled = true; if (this.showActionLabels) { this.scanFromCameraButton.label = this.translationService .i("action-message-camera-not-allowed") .toString(); } }, 10); this.showOverlay(""); break; case RecognitionStatus.CameraInUse: this.scanError.emit({ code: Code.CameraInUse, fatal: true, message: "Camera already in use!", recognizerName: "", }); this.feedback.emit({ code: FeedbackCode.CameraInUse, state: "FEEDBACK_ERROR", message: this.translationService.i("camera-in-use").toString(), }); window.setTimeout(() => { this.scanFromCameraButton.disabled = true; if (this.showActionLabels) { this.scanFromCameraButton.label = this.translationService .i("action-message-camera-in-use") .toString(); } }, 10); this.showOverlay(""); break; case RecognitionStatus.NoSupportForMediaDevices: case RecognitionStatus.CameraNotFound: case RecognitionStatus.UnableToAccessCamera: this.scanError.emit({ code: Code.CameraGenericError, fatal: true, message: `There was a problem while accessing camera ${recognitionEvent.status}`, recognizerName: "", }); this.feedback.emit({ code: FeedbackCode.CameraGenericError, state: "FEEDBACK_ERROR", message: this.translationService .i("camera-generic-error") .toString(), }); window.setTimeout(() => { this.scanFromCameraButton.disabled = true; if (this.showActionLabels) { this.scanFromCameraButton.label = this.translationService .i("action-message-camera-disabled") .toString(); } }, 10); this.showOverlay(""); break; default: // console.warn('Unhandled video recognition status:', recognitionEvent.status); } }; try { this.cameraExperience.classList.remove("hide"); this.cameraScanStarted.emit(); void this.cameraExperience.populateCameraDevices(); await this.sdkService.scanFromCamera(configuration, eventHandler); const cameraFlipped = this.sdkService.isCameraFlipped(); this.cameraExperience.setCameraFlipState(cameraFlipped); this.initializeHelpScreensAndStartOnboarding(); } catch (error) { this.handleScanError(error); this.showOverlay(""); } } async startScanFromImage(file) { const configuration = { pingProxyUrl: this.pingProxyUrl, recognizers: this.recognizers, file: file || this.scanFromImageInput.files[0], }; if (this.recognizerOptions && Object.keys(this.recognizerOptions).length > 0) { configuration.recognizerOptions = this.recognizerOptions; } const eventHandler = (recognitionEvent) => { switch (recognitionEvent.status) { case RecognitionStatus.Preparing: this.feedback.emit({ code: FeedbackCode.ScanStarted, state: "FEEDBACK_OK", message: "", }); this.showScanFromImageUi(); break; case RecognitionStatus.Processing: // Just keep working break; case RecognitionStatus.NoImageFileFound: this.scanError.emit({ code: Code.NoImageFileFound, fatal: true, message: "No image file was provided to SDK service!", recognizerName: "", }); this.feedback.emit({ code: FeedbackCode.ScanUnsuccessful, state: "FEEDBACK_ERROR", message: this.translationService .i("feedback-scan-unsuccessful") .toString(), }); this.hideScanFromImageUi(false); this.clearInputImages(); break; case RecognitionStatus.DetectionFailed: // Do nothing, RecognitionStatus.EmptyResultState will handle negative outcome this.clearInputImages(); break; case RecognitionStatus.EmptyResultState: this.scanError.emit({ code: Code.EmptyResult, fatal: false, message: "Could not extract information from image!", recognizerName: recognitionEvent.data.recognizerName, }); this.feedback.emit({ code: FeedbackCode.ScanUnsuccessful, state: "FEEDBACK_ERROR", message: this.translationService .i("feedback-scan-unsuccessful") .toString(), }); this.hideScanFromImageUi(false); this.clearInputImages(); break; case RecognitionStatus.UnknownError: // Do nothing, RecognitionStatus.EmptyResultState will handle negative outcome this.clearInputImages(); break; case RecognitionStatus.ScanSuccessful: this.scanSuccess.emit(recognitionEvent.data); this.feedback.emit({ code: FeedbackCode.ScanSuccessful, state: "FEEDBACK_OK", message: "", }); this.clearInputImages(); this.hideScanFromImageUi(true); break; default: //console.warn('Unhandled image recognition status:', recognitionEvent.status); } }; try { this.imageScanStarted.emit(); if (this.thoroughScanFromImage) { configuration.thoroughScan = true; } await this.sdkService.scanFromImage(configuration, eventHandler); } catch (error) { this.handleScanError(error); this.hideScanFromImageUi(false); } } async startScanFromImageMultiSide(firstFile, secondFile) { const configuration = { pingProxyUrl: this.pingProxyUrl, recognizers: this.recognizers, firstFile: firstFile || this.galleryImageFirstFile, secondFile: secondFile || this.galleryImageSecondFile, }; if (this.recognizerOptions) { configuration.recognizerOptions = this.recognizerOptions; } const eventHandler = (recognitionEvent) => { switch (recognitionEvent.status) { case RecognitionStatus.Preparing: this.showScanFromImageUi(); this.feedback.emit({ code: FeedbackCode.ScanStarted, state: "FEEDBACK_OK", message: "", }); break; case RecognitionStatus.Ready: this.cameraExperience.setActiveCamera(this.sdkService.videoRecognizer.deviceId); break; case RecognitionStatus.Processing: // Just keep working break; case RecognitionStatus.NoFirstImageFileFound: this.scanError.emit({ code: Code.NoFirstImageFileFound, fatal: true, message: "First image file is missing!", recognizerName: "", }); this.feedback.emit({ code: FeedbackCode.ScanUnsuccessful, state: "FEEDBACK_ERROR", message: this.translationService .i("feedback-scan-unsuccessful") .toString(), }); this.hideScanFromImageUi(false); this.clearInputImages(); break; case RecognitionStatus.NoSecondImageFileFound: this.scanError.emit({ code: Code.NoSecondImageFileFound, fatal: true, message: "Second image file is missing!", recognizerName: "", }); this.feedback.emit({ code: FeedbackCode.ScanUnsuccessful, state: "FEEDBACK_ERROR", message: this.translationService .i("feedback-scan-unsuccessful") .toString(), }); this.hideScanFromImageUi(false); this.clearInputImages(); break; case RecognitionStatus.DetectionFailed: // Do nothing, RecognitionStatus.EmptyResultState will handle negative outcome this.clearInputImages(); break; case RecognitionStatus.EmptyResultState: this.scanError.emit({ code: Code.EmptyResult, fatal: false, message: "Could not extract information from image!", recognizerName: recognitionEvent.data.recognizerName, }); this.feedback.emit({ code: FeedbackCode.ScanUnsuccessful, state: "FEEDBACK_ERROR", message: this.translationService .i("feedback-scan-unsuccessful") .toString(), }); this.hideScanFromImageUi(false); this.clearInputImages(); break; case RecognitionStatus.UnknownError: // Do nothing, RecognitionStatus.EmptyResultState will handle negative outcome this.clearInputImages(); break; case RecognitionStatus.ScanSuccessful: this.scanSuccess.emit(recognitionEvent.data); this.feedback.emit({ code: FeedbackCode.ScanSuccessful, state: "FEEDBACK_OK", message: "", }); this.clearInputImages(); this.hideScanFromImageUi(true); break; default: //console.warn('Unhandled image recognition status:', recognitionEvent.status); } }; try { this.imageScanStarted.emit(); if (this.thoroughScanFromImage) { configuration.thoroughScan = true; } await this.sdkService.scanFromImageMultiSide(configuration, eventHandler); } catch (error) { this.handleScanError(error); this.hideScanFromImageUi(false); } } handleScanError(error) { const isAvailable = navigator.onLine; if (!isAvailable) { const fatalError = new SDKError({ code: ErrorTypes.ErrorCodes.InternetNotAvailable, message: this.translationService .i("check-internet-connection") .toString(), }); this.setFatalError(fatalError); this.showLicenseInfoModal(this.translationService.i("check-internet-connection").toString()); return; } if (error?.code === ErrorCodes.INVALID_PING_PROXY_URL) { this.setFatalError(new SDKError(ErrorTypes.componentErrors.pingProxyErrors.invalidProxyUrl, error)); } else if (error?.code === ErrorCodes.PING_PROXY_PERMISSION_NOT_GRANTED) { this.setFatalError(new SDKError(ErrorTypes.componentErrors.pingProxyErrors.permissionNotGranted, error)); } else if (error?.code === ErrorCodes.LICENSE_UNLOCK_ERROR) { this.setFatalError(new SDKError(ErrorTypes.componentErrors.licenseError, error)); this.showLicenseInfoModal(error); } else { this.scanError.emit({ code: Code.GenericScanError, fatal: true, message: "There was a problem during scan action.", recognizerName: "", details: error, }); this.feedback.emit({ code: FeedbackCode.GenericScanError, state: "FEEDBACK_ERROR", message: this.translationService.i("feedback-error-generic").toString(), }); this.showOverlay(""); } } showLicenseInfoModal(error) { if (typeof error === "string") { this.licenseExperienceModal.content = error; } else { if (error.type === "NETWORK_ERROR") { this.licenseExperienceModal.content = this.translationService .i("network-error") .toString(); } else { this.licenseExperienceModal.content = this.translationService .i("scanning-not-available") .toString(); } } this.showOverlay("modal"); } showScreen(screenName) { for (const screenKey in this.screens) { if (this.screens[screenKey]) { this.screens[screenKey].visible = screenName === screenKey; } } } showOverlay(overlayName) { if (overlayName === "camera") { this.initialBodyOverflowValue = document.body.style.overflow; document.body.style.overflow = "hidden"; } else { document.body.style.overflow = this.initialBodyOverflowValue; } for (const overlayKey in this.overlays) { if (this.overlays[overlayKey]) { this.overlays[overlayKey].visible = overlayName === overlayKey; } } } setDragAndDrop() { const dropTarget = this.galleryDropType === "FULLSCREEN" ? window : this.hostEl; const lockTimeout = 3000; let lockDragAndDrop = false; if (this.galleryDropType === "INLINE") { this.overlays.draganddrop.classList.add("inline"); } const closeOverlay = () => { if (lockDragAndDrop) { window.setTimeout(() => { this.hostEl.style.borderStyle = "solid"; this.overlays.draganddrop.classList.add("hidden"); this.showOverlay(""); window.setTimeout(() => { this.overlays.draganddrop.classList.remo