(function (global, factory) {
    typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('@angular/common/http'), require('@angular/core'), require('@awesome-cordova-plugins/app-version/ngx'), require('@awesome-cordova-plugins/barcode-scanner/ngx'), require('@awesome-cordova-plugins/calendar/ngx'), require('@awesome-cordova-plugins/camera/ngx'), require('@awesome-cordova-plugins/file/ngx'), require('@awesome-cordova-plugins/file-opener/ngx'), require('@awesome-cordova-plugins/device/ngx'), require('@awesome-cordova-plugins/media-capture/ngx'), require('@awesome-cordova-plugins/geolocation/ngx'), require('@awesome-cordova-plugins/network/ngx'), require('@awesome-cordova-plugins/sqlite/ngx'), require('@awesome-cordova-plugins/vibration/ngx'), require('@awesome-cordova-plugins/location-accuracy/ngx'), require('@awesome-cordova-plugins/diagnostic/ngx'), require('@wm/core'), require('lodash-es'), require('@wm/components/base'), require('@wm/mobile/core'), require('@wm/mobile/offline'), require('@wm/security'), require('@wm/mobile/variables'), require('@wm/variables'), require('@wm/mobile/components/basic'), require('rxjs'), require('rxjs/operators'), require('@wm/mobile/components/basic/search'), require('@wm/mobile/components/containers/segmented-control'), require('@wm/mobile/components/data/media-list'), require('@wm/mobile/components/device/barcode-scanner'), require('@wm/mobile/components/device/camera'), require('@wm/mobile/components/input/file-upload'), require('@wm/mobile/components/page'), require('@wm/mobile/components/page/left-panel'), require('@wm/mobile/components/page/mobile-navbar'), require('@wm/mobile/components/page/tab-bar')) :
    typeof define === 'function' && define.amd ? define(['exports', '@angular/common/http', '@angular/core', '@awesome-cordova-plugins/app-version/ngx', '@awesome-cordova-plugins/barcode-scanner/ngx', '@awesome-cordova-plugins/calendar/ngx', '@awesome-cordova-plugins/camera/ngx', '@awesome-cordova-plugins/file/ngx', '@awesome-cordova-plugins/file-opener/ngx', '@awesome-cordova-plugins/device/ngx', '@awesome-cordova-plugins/media-capture/ngx', '@awesome-cordova-plugins/geolocation/ngx', '@awesome-cordova-plugins/network/ngx', '@awesome-cordova-plugins/sqlite/ngx', '@awesome-cordova-plugins/vibration/ngx', '@awesome-cordova-plugins/location-accuracy/ngx', '@awesome-cordova-plugins/diagnostic/ngx', '@wm/core', 'lodash-es', '@wm/components/base', '@wm/mobile/core', '@wm/mobile/offline', '@wm/security', '@wm/mobile/variables', '@wm/variables', '@wm/mobile/components/basic', 'rxjs', 'rxjs/operators', '@wm/mobile/components/basic/search', '@wm/mobile/components/containers/segmented-control', '@wm/mobile/components/data/media-list', '@wm/mobile/components/device/barcode-scanner', '@wm/mobile/components/device/camera', '@wm/mobile/components/input/file-upload', '@wm/mobile/components/page', '@wm/mobile/components/page/left-panel', '@wm/mobile/components/page/mobile-navbar', '@wm/mobile/components/page/tab-bar'], factory) :
    (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory((global.wm = global.wm || {}, global.wm.mobile = global.wm.mobile || {}, global.wm.mobile.runtime = {}), global.ng.common.http, global.ng.core, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.awesomeCordova.plugins, global.wm.core, global._, global.wm.components.base, global.wm.mobile.core, global.wm.mobile.offline, global.wm.security, global.wm.mobile.variables, global.wm.variables, global.wm.mobile.components.basic, global.rxjs, global.rxjs.operators, global.wm.mobile.components.basic.search, global.wm.mobile.components.containers.segmentedcontrol, global.wm.mobile.components.data.medialist, global.wm.mobile.components.device.barcodescanner, global.wm.mobile.components.device.camera, global.wm.mobile.components.input.fileupload, global.wm.mobile.components.page, global.wm.mobile.components.page.leftpanel, global.wm.mobile.components.page.mobilenavbar, global.wm.mobile.components.page.tabbar));
})(this, (function (exports, http, i0, ngx, ngx$1, ngx$2, ngx$3, i2, ngx$4, ngx$5, ngx$7, ngx$6, ngx$8, ngx$9, ngx$a, ngx$b, ngx$c, i1$1, lodashEs, base, i3, offline, i4, variables$1, variables, i1, rxjs, operators, search, segmentedControl, mediaList, barcodeScanner, camera, fileUpload, page, leftPanel, mobileNavbar, tabBar) { 'use strict';

    function _interopNamespaceDefault(e) {
        var n = Object.create(null);
        if (e) {
            Object.keys(e).forEach(function (k) {
                if (k !== 'default') {
                    var d = Object.getOwnPropertyDescriptor(e, k);
                    Object.defineProperty(n, k, d.get ? d : {
                        enumerable: true,
                        get: function () { return e[k]; }
                    });
                }
            });
        }
        n.default = e;
        return Object.freeze(n);
    }

    var i0__namespace = /*#__PURE__*/_interopNamespaceDefault(i0);
    var i2__namespace = /*#__PURE__*/_interopNamespaceDefault(i2);
    var i1$1__namespace = /*#__PURE__*/_interopNamespaceDefault(i1$1);
    var i3__namespace = /*#__PURE__*/_interopNamespaceDefault(i3);
    var i4__namespace = /*#__PURE__*/_interopNamespaceDefault(i4);
    var i1__namespace = /*#__PURE__*/_interopNamespaceDefault(i1);

    const STORAGE_KEY = 'wavemaker.persistedcookies';
    class CookieService {
        constructor() {
            this.cookieInfo = {};
            this.serviceName = 'CookeService';
        }
        static { this.SERVICE_NAME = 'CookieService'; }
        persistCookie(hostname, cookieName, cookieValue) {
            return new Promise((resolve, reject) => {
                if (cookieValue) {
                    resolve(cookieValue);
                }
                else {
                    this.getCookie(hostname, cookieName)
                        .then(data => resolve(data.cookieValue), reject);
                }
            }).then(value => {
                this.cookieInfo[hostname + '-' + cookieName] = {
                    hostname: hostname.replace(/:[0-9]+/, ''),
                    name: cookieName,
                    value: this.rotateLTR(value)
                };
                localStorage.setItem(STORAGE_KEY, JSON.stringify(this.cookieInfo));
            });
        }
        getCookie(hostname, cookieName) {
            return new Promise((resolve, reject) => {
                if (i1$1.isIos()) {
                    const cookieString = window['cordova'].plugin.http.getCookieString(hostname);
                    if (cookieString) {
                        const at = cookieString.indexOf(cookieName);
                        if (at >= 0) {
                            const start = at + cookieName.length + 1;
                            const end = cookieString.indexOf(';', start);
                            const cookieValue = cookieString.substring(start, end >= 0 ? end : undefined);
                            resolve({
                                cookieValue: cookieValue
                            });
                            return;
                        }
                    }
                    reject();
                }
                else {
                    window['cookieEmperor'].getCookie(hostname, cookieName, resolve, reject);
                }
            });
        }
        setCookie(hostname, cookieName, cookieValue) {
            return new Promise((resolve, reject) => {
                if (i1$1.isIos()) {
                    const cookieString = cookieName + '=' + cookieValue;
                    window['cordova'].plugin.http.setCookie(hostname, cookieString);
                    resolve();
                }
                else {
                    window['cookieEmperor'].setCookie(hostname, cookieName, cookieValue, resolve, reject);
                }
            });
        }
        clearAll() {
            return new Promise((resolve, reject) => {
                if (i1$1.isIos()) {
                    window['cordova'].plugin.http.clearCookies();
                    resolve('');
                }
                else {
                    window['cookieEmperor'].clearAll(resolve, reject);
                }
            });
        }
        /**
         * Loads persisted cookies from local storage and adds them to the browser.
         * @returns {*}
         */
        start() {
            const cookieInfoStr = localStorage.getItem(STORAGE_KEY), promises = [];
            if (cookieInfoStr) {
                const cookieInfo = JSON.parse(cookieInfoStr);
                lodashEs.forEach(cookieInfo, c => {
                    // @ts-ignore
                    if (c.name && c.value) {
                        // @ts-ignore
                        promises.push(this.getCookie(c.hostname, c.name).catch(() => {
                            return new Promise((resolve, reject) => {
                                // @ts-ignore
                                window['cookieEmperor'].setCookie(c.hostname, c.name, this.rotateRTL(c.value), resolve, reject);
                            });
                        }));
                    }
                });
            }
            return Promise.all(promises);
        }
        getServiceName() {
            return CookieService.SERVICE_NAME;
        }
        /**
         * Just rotates the given string exactly from 1/3 of string length in left to right direction.
         * @param str
         * @returns {string}
         */
        rotateLTR(str) {
            const arr = str.split(''), tArr = [], shift = Math.floor(str.length / 3);
            arr.forEach((v, i) => {
                tArr[(i + shift) % arr.length] = arr[i];
            });
            return tArr.join('');
        }
        /**
         * Just rotates the given string exactly from 1/3 of string length in  right to left direction..
         * @param str
         * @returns {string}
         */
        rotateRTL(str) {
            const arr = str.split(''), tArr = [], shift = Math.floor(str.length / 3);
            arr.forEach((v, i) => {
                tArr[(arr.length + i - shift) % arr.length] = arr[i];
            });
            return tArr.join('');
        }
        static { this.ɵfac = function CookieService_Factory(t) { return new (t || CookieService)(); }; }
        static { this.ɵprov = /*@__PURE__*/ i0__namespace.ɵɵdefineInjectable({ token: CookieService, factory: CookieService.ɵfac, providedIn: 'root' }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(CookieService, [{
            type: i0.Injectable,
            args: [{
                    providedIn: 'root'
                }]
        }], null, null); })();

    const _c0 = ["wmAppExt", ""];
    class AppExtComponent {
        constructor(elRef, fileSelectorService, processManagementService) {
            this.elRef = elRef;
            this.fileSelectorService = fileSelectorService;
            this.processManagementService = processManagementService;
        }
        ngAfterViewInit() {
            const mobileElements = $(this.elRef.nativeElement).find('>[wmNetworkInfoToaster], >[wmAppUpdate], >[wmMobileFileBrowser]');
            const $body = $('body');
            if (i1$1.hasCordova()) {
                mobileElements.appendTo($body);
                this.fileSelectorService.setFileBrowser(this.fileBrowserComponent);
            }
            else {
                mobileElements.remove();
            }
            $(this.elRef.nativeElement).find('>[wmProgressManager]').appendTo($body);
            this.processManagementService.setUIComponent(this.processManagerComponent);
        }
        static { this.ɵfac = function AppExtComponent_Factory(t) { return new (t || AppExtComponent)(i0__namespace.ɵɵdirectiveInject(i0__namespace.ElementRef), i0__namespace.ɵɵdirectiveInject(i1__namespace.FileSelectorService), i0__namespace.ɵɵdirectiveInject(i1__namespace.ProcessManagementService)); }; }
        static { this.ɵcmp = /*@__PURE__*/ i0__namespace.ɵɵdefineComponent({ type: AppExtComponent, selectors: [["", "wmAppExt", ""]], viewQuery: function AppExtComponent_Query(rf, ctx) { if (rf & 1) {
                i0__namespace.ɵɵviewQuery(i1.FileBrowserComponent, 5);
                i0__namespace.ɵɵviewQuery(i1.ProcessManagerComponent, 5);
            } if (rf & 2) {
                let _t;
                i0__namespace.ɵɵqueryRefresh(_t = i0__namespace.ɵɵloadQuery()) && (ctx.fileBrowserComponent = _t.first);
                i0__namespace.ɵɵqueryRefresh(_t = i0__namespace.ɵɵloadQuery()) && (ctx.processManagerComponent = _t.first);
            } }, attrs: _c0, decls: 5, vars: 0, consts: [["wmNetworkInfoToaster", ""], ["wmAppUpdate", ""], ["wmMobileFileBrowser", ""], ["wmProcessManager", ""]], template: function AppExtComponent_Template(rf, ctx) { if (rf & 1) {
                i0__namespace.ɵɵelementContainerStart(0);
                i0__namespace.ɵɵelement(1, "div", 0)(2, "div", 1)(3, "div", 2)(4, "div", 3);
                i0__namespace.ɵɵelementContainerEnd();
            } }, dependencies: [i1__namespace.AppUpdateComponent, i1__namespace.FileBrowserComponent, i1__namespace.NetworkInfoToasterComponent, i1__namespace.ProcessManagerComponent], encapsulation: 2 }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(AppExtComponent, [{
            type: i0.Component,
            args: [{
                    selector: '[wmAppExt]',
                    template: `<ng-container> 
        <div wmNetworkInfoToaster></div>
        <div wmAppUpdate></div>
        <div wmMobileFileBrowser></div>
        <div wmProcessManager></div>
    </ng-container>`
                }]
        }], () => [{ type: i0__namespace.ElementRef }, { type: i1__namespace.FileSelectorService }, { type: i1__namespace.ProcessManagementService }], { fileBrowserComponent: [{
                type: i0.ViewChild,
                args: [i1.FileBrowserComponent]
            }], processManagerComponent: [{
                type: i0.ViewChild,
                args: [i1.ProcessManagerComponent]
            }] }); })();
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassDebugInfo(AppExtComponent, { className: "AppExtComponent", filePath: "components/app-ext.component.ts", lineNumber: 15 }); })();

    class MobileHttpInterceptor {
        constructor(app, file, deviceFileDownloadService, deviceService, networkService, securityService) {
            this.app = app;
            this.deviceService = deviceService;
            this.networkService = networkService;
            this.requestInterceptors = [];
            if (i1$1.hasCordova()) {
                this.requestInterceptors.push(new SecurityInterceptor(app, file, securityService));
                this.requestInterceptors.push(new ServiceCallInterceptor(app));
            }
        }
        intercept(request, next) {
            new rxjs.Subject();
            const token = localStorage.getItem(variables.CONSTANTS.XSRF_COOKIE_NAME);
            const xsrfHeaderName = i1$1.getWmProjectProperties().xsrf_header_name;
            if (token
                && xsrfHeaderName
                && this.app.deployedUrl
                && (request.url.indexOf('://') < 0
                    || request.url.startsWith(this.app.deployedUrl))) {
                // Clone the request to add the new header
                request = request.clone({ headers: request.headers.set(xsrfHeaderName, token) });
            }
            const data = { request: request };
            // invoke the request only when device is ready.
            const obs = rxjs.from(this.deviceService.whenReady()
                .then(() => i1$1.executePromiseChain(this.getInterceptors(), [data])));
            return obs.pipe(operators.mergeMap(() => {
                return next.handle(data.request);
            }));
        }
        getInterceptors() {
            return this.requestInterceptors.map(i => {
                return (data) => i.intercept(data.request).then(req => data.request = req);
            });
        }
        onHttpError(response) {
            if (i1$1.hasCordova
                && (!response || !response.status || response.status < 0 || response.status === 404)
                && (this.networkService.isConnected())) {
                this.networkService.isAvailable(true);
            }
        }
        static { this.ɵfac = function MobileHttpInterceptor_Factory(t) { return new (t || MobileHttpInterceptor)(i0__namespace.ɵɵinject(i1$1__namespace.App), i0__namespace.ɵɵinject(i2__namespace.File), i0__namespace.ɵɵinject(i3__namespace.DeviceFileDownloadService), i0__namespace.ɵɵinject(i3__namespace.DeviceService), i0__namespace.ɵɵinject(i3__namespace.NetworkService), i0__namespace.ɵɵinject(i4__namespace.SecurityService)); }; }
        static { this.ɵprov = /*@__PURE__*/ i0__namespace.ɵɵdefineInjectable({ token: MobileHttpInterceptor, factory: MobileHttpInterceptor.ɵfac }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(MobileHttpInterceptor, [{
            type: i0.Injectable
        }], () => [{ type: i1$1__namespace.App }, { type: i2__namespace.File }, { type: i3__namespace.DeviceFileDownloadService }, { type: i3__namespace.DeviceService }, { type: i3__namespace.NetworkService }, { type: i4__namespace.SecurityService }], null); })();
    class ServiceCallInterceptor {
        static { this.REMOTE_SERVICE_URL_PATTERNS = [
            new RegExp('^((./)|/)?services/'),
            new RegExp('j_spring_security_check'),
            new RegExp('j_spring_security_logout')
        ]; }
        constructor(app) {
            this.app = app;
        }
        intercept(request) {
            let modifiedRequest = request;
            let url = request.url;
            // if necessary, prepend deployed url
            if (url.indexOf('://') < 0
                && ServiceCallInterceptor.REMOTE_SERVICE_URL_PATTERNS.find(r => r.test(url))) {
                url = this.app.deployedUrl + url;
            }
            url = i1$1.removeExtraSlashes(url);
            if (url !== request.url) {
                modifiedRequest = request.clone({
                    url: url
                });
            }
            return Promise.resolve(modifiedRequest);
        }
    }
    class SecurityInterceptor {
        static { this.PAGE_URL_PATTERN = new RegExp('page.min.json$'); }
        static { this.PREFAB_URL_PATTERN = new RegExp('^app/prefabs/.*/page.min.json$'); }
        constructor(app, file, securityService) {
            this.app = app;
            this.file = file;
            this.securityService = securityService;
            this.initialized = false;
        }
        intercept(request) {
            return new Promise((resolve, reject) => {
                if (!SecurityInterceptor.PREFAB_URL_PATTERN.test(request.url)
                    && SecurityInterceptor.PAGE_URL_PATTERN.test(request.url)) {
                    return Promise.resolve().then(() => {
                        if (!this.initialized) {
                            return this.init();
                        }
                    }).then(() => {
                        const urlSplits = lodashEs.split(request.url, '/');
                        const pageName = urlSplits[urlSplits.length - 2];
                        if (!this.publicPages || this.publicPages[pageName]) {
                            return Promise.resolve(request);
                        }
                        else {
                            this.securityService.getConfig(config => {
                                if (!config.securityEnabled || config.authenticated) {
                                    resolve(request);
                                }
                                else {
                                    reject(`Page '${pageName}' is not accessible to the user.`);
                                    this.app.notify('http401', { page: pageName });
                                }
                            }, () => reject(`Security call failed.`));
                        }
                        return Promise.resolve(request);
                    }).then(resolve, reject);
                }
                return resolve(request);
            });
        }
        /**
         * loads public pages from 'metadata/app/public-pages.info' and overrides canAccess method SecurityService
         */
        init() {
            const folderPath = cordova.file.applicationDirectory + 'www/metadata/app', fileName = 'public-pages.json';
            return this.file.readAsText(folderPath, fileName).then(text => {
                if (!this.initialized) {
                    this.publicPages = {};
                    this.initialized = true;
                    lodashEs.forEach(JSON.parse(text), pageName => this.publicPages[pageName] = true);
                }
            }).catch(() => {
                this.initialized = true;
            });
        }
    }

    class WebProcessService {
        constructor(app, httpService, extAppMessageService) {
            this.app = app;
            this.httpService = httpService;
            this.extAppMessageService = extAppMessageService;
        }
        execute(process, hookUrl, useSystemBrowser = false) {
            return this.httpService.get(`/services/webprocess/prepare?processName=${process}&hookUrl=${hookUrl}&requestSourceType=MOBILE`)
                .then((processInfo) => {
                if (useSystemBrowser) {
                    return this.executeWithSystemBrowser(processInfo);
                }
                else {
                    return this.executeWithInAppBrowser(processInfo, process);
                }
            }).then(output => {
                return this.httpService.get('/services/webprocess/decode?encodedProcessdata=' + output);
            });
        }
        executeWithSystemBrowser(processInfo) {
            return new Promise((resolve) => {
                const oauthAdress = '^services/webprocess/LOGIN';
                const deregister = this.extAppMessageService.subscribe(oauthAdress, message => {
                    resolve(message.data['process_output']);
                    deregister();
                });
                window.open(this.app.deployedUrl + 'services/webprocess/start?process=' + encodeURIComponent(processInfo), '_system');
            });
        }
        executeWithInAppBrowser(processInfo, process) {
            return new Promise((resolve, reject) => {
                const ref = cordova.InAppBrowser.open(this.app.deployedUrl + 'services/webprocess/start?process=' + encodeURIComponent(processInfo), '_blank', 'location=yes,clearcache=yes');
                let isSuccess = false;
                ref.addEventListener('loadstop', () => {
                    ref.executeScript({ code: this.getScriptToInject(process) }, output => {
                        if (output && output[0]) {
                            isSuccess = true;
                            ref.close();
                            resolve(output[0]);
                        }
                    });
                });
                ref.addEventListener('exit', () => {
                    if (!isSuccess) {
                        reject('Login process is stopped');
                    }
                });
            });
        }
        getScriptToInject(process) {
            return `
            (function() {
                var elements = document.querySelectorAll('body.flex>a.link');
                for (var i = 0; i < elements.length; i++) {
                    var href = elements[i].href;
                    if (href && href.indexOf('://services/webprocess/${process}?process_output=')) {
                        return href.split('process_output=')[1];
                    }
                }
                window.isWebLoginProcess = true;
            })();
        `;
        }
        static { this.ɵfac = function WebProcessService_Factory(t) { return new (t || WebProcessService)(i0__namespace.ɵɵinject(i1$1__namespace.App), i0__namespace.ɵɵinject(i1$1__namespace.AbstractHttpService), i0__namespace.ɵɵinject(i3__namespace.ExtAppMessageService)); }; }
        static { this.ɵprov = /*@__PURE__*/ i0__namespace.ɵɵdefineInjectable({ token: WebProcessService, factory: WebProcessService.ɵfac }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(WebProcessService, [{
            type: i0.Injectable
        }], () => [{ type: i1$1__namespace.App }, { type: i1$1__namespace.AbstractHttpService }, { type: i3__namespace.ExtAppMessageService }], null); })();

    const MAX_WAIT_TIME_4_OAUTH_MESSAGE = 60000;
    const MINIMUM_TAB_WIDTH = 768;
    const KEYBOARD_CLASS = 'keyboard';
    const cordovaServices = [
        ngx.AppVersion,
        ngx$1.BarcodeScanner,
        ngx$2.Calendar,
        ngx$3.Camera,
        i2.File,
        ngx$4.FileOpener,
        ngx$5.Device,
        ngx$6.Geolocation,
        ngx$7.MediaCapture,
        ngx$8.Network,
        ngx$9.SQLite,
        ngx$a.Vibration,
        ngx$b.LocationAccuracy,
        ngx$c.Diagnostic
    ];
    const MOBILE_COMPONENT_MODULES = [
        i1.BasicModule,
        i3.MobileCoreModule,
        offline.OfflineModule,
        variables$1.VariablesModule,
        search.SearchModule,
        segmentedControl.SegmentedControlModule,
        mediaList.MediaListModule,
        barcodeScanner.BarcodeScannerModule,
        camera.CameraModule,
        fileUpload.FileUploadModule,
        page.PageModule,
        leftPanel.LeftPanelModule,
        mobileNavbar.MobileNavbarModule,
        tabBar.TabBarModule
    ];
    class MobileRuntimeModule {
        static forRoot() {
            /* add all providers that are required for mobile here. This is to simplify placeholder.*/
            return {
                ngModule: MobileRuntimeModule,
                providers: [
                    WebProcessService,
                    {
                        provide: http.HTTP_INTERCEPTORS,
                        useClass: MobileHttpInterceptor,
                        multi: true
                    },
                    ...cordovaServices,
                    base.FileExtensionFromMimePipe,
                    { provide: offline.PushService, useClass: offline.PushServiceImpl }
                ]
            };
        }
        static { this.initialized = false; }
        // Startup services have to be added only once in the app life-cycle.
        static initializeRuntime(runtimeModule, app, deviceFileOpenerService, deviceService) {
            if (this.initialized) {
                return;
            }
            this.initialized = true;
            app.deployedUrl = runtimeModule.getDeployedUrl();
            if (i1$1.hasCordova()) {
                const unsubscribe = app.subscribe('pageReady', (page) => {
                    navigator.splashscreen.hide();
                    unsubscribe();
                });
                app.subscribe('userLoggedIn', () => {
                    cordova && cordova.wavemaker.syncCookies();
                });
                runtimeModule.handleKeyBoardClass();
                app.subscribe('device-file-download', (data) => {
                    deviceFileOpenerService.openRemoteFile(data.url, data.extension, data.name, data.headers).then(data.successCb, data.errorCb);
                });
                const __zone_symbol__FileReader = window['__zone_symbol__FileReader'];
                if (__zone_symbol__FileReader && __zone_symbol__FileReader.READ_CHUNK_SIZE) {
                    // cordova File Reader is required. Otherwise, file operations are failing.
                    window['FileReader'] = __zone_symbol__FileReader;
                }
                window.open = window['cordova']['InAppBrowser']['open'];
                runtimeModule.addAuthInBrowser();
            }
            deviceService.start();
            deviceService.whenReady().then(() => {
                if (i1$1.hasCordova()) {
                    runtimeModule._$appEl.addClass('cordova');
                    runtimeModule.exposeOAuthService();
                    // Fix for issue: ios device is not considering the background style, eventhough value is set in config.xml.
                    if (window['StatusBar']) {
                        window['StatusBar'].overlaysWebView(false);
                    }
                }
            });
        }
        constructor(app, cookieService, deviceFileOpenerService, deviceService, securityService, httpService, extAppMessageService, networkService, webProcessService) {
            this.app = app;
            this.cookieService = cookieService;
            this.deviceFileOpenerService = deviceFileOpenerService;
            this.deviceService = deviceService;
            this.securityService = securityService;
            this.httpService = httpService;
            this.extAppMessageService = extAppMessageService;
            this.networkService = networkService;
            this.webProcessService = webProcessService;
            this._$appEl = $('.wm-app').first();
            if (this._$appEl.width() >= MINIMUM_TAB_WIDTH) {
                app.isTabletApplicationType = true;
                this._$appEl.addClass('wm-tablet-app');
            }
            else {
                this._$appEl.addClass('wm-mobile-app');
            }
            // applying os theme on getting os details
            app.subscribe('on-viewport-details', os => {
                this.applyOSTheme(os);
            });
            MobileRuntimeModule.initializeRuntime(this, this.app, this.deviceFileOpenerService, this.deviceService);
        }
        exposeOAuthService() {
            window['OAuthInMobile'] = (providerId) => {
                return new Promise((resolve, reject) => {
                    const oauthAdress = '^services/oauth/' + providerId + '$';
                    const deregister = this.extAppMessageService.subscribe(oauthAdress, message => {
                        resolve(message.data['access_token']);
                        deregister();
                        clearTimeout(timerId);
                    });
                    const timerId = setTimeout(function () {
                        deregister();
                        reject(`Time out for oauth message after ${MAX_WAIT_TIME_4_OAUTH_MESSAGE % 1000} seconds`);
                    }, MAX_WAIT_TIME_4_OAUTH_MESSAGE);
                });
            };
            const handleOpenURL = window['handleOpenURL'];
            handleOpenURL.isReady = true;
            handleOpenURL(handleOpenURL.lastURL);
        }
        applyOSTheme(os) {
            let oldStyleSheet = $('link[theme="wmtheme"][href ^="themes"][href $="/style.css"]').first();
            if (oldStyleSheet.length) {
                const themeUrl = oldStyleSheet.attr('href').replace(new RegExp('/[a-z]*/style.css$'), `/${os.toLowerCase()}/style.css`), newStyleSheet = i1$1.loadStyleSheet(themeUrl, { name: 'theme', value: 'wmtheme' });
                oldStyleSheet = oldStyleSheet.length > 0 && oldStyleSheet[0];
                if (newStyleSheet && oldStyleSheet) {
                    i1$1.insertAfter(newStyleSheet, oldStyleSheet);
                    i1$1.removeNode(oldStyleSheet);
                }
            }
            // In angular development, styleSheet will point to .js files
            // In angular production, styleSheet will point to 'wm-android-styles.css' or 'wm-ios-styles.css'
            const removeTheme = os.toLowerCase() === 'android' ? 'wm-ios-styles' : 'wm-android-styles';
            let isDevBuild;
            const useTheme = 'wm-' + os.toLowerCase() + '-styles';
            let unusedStyleSheet = $('link[href *=' + removeTheme + ']').first();
            if (!unusedStyleSheet.length) {
                isDevBuild = true;
                unusedStyleSheet = $('script[src *=' + removeTheme + ']').first();
            }
            if (unusedStyleSheet.length) {
                let newStyleSheet;
                if (isDevBuild) {
                    newStyleSheet = unusedStyleSheet.clone();
                    newStyleSheet = newStyleSheet[0];
                    newStyleSheet.src = newStyleSheet.src.replace(removeTheme, useTheme);
                    i1$1.loadScript(newStyleSheet.src, false);
                    unusedStyleSheet = unusedStyleSheet[0];
                    i1$1.insertAfter(newStyleSheet, unusedStyleSheet);
                    i1$1.removeNode(unusedStyleSheet);
                }
                else {
                    newStyleSheet = $('link[href *=' + useTheme + ']').first();
                    newStyleSheet = newStyleSheet[0];
                    i1$1.loadStyleSheet(newStyleSheet.href, { name: 'theme', value: 'wmtheme' });
                    i1$1.removeNode(unusedStyleSheet[0]);
                }
            }
        }
        handleKeyBoardClass() {
            const initialScreenSize = window.innerHeight;
            // keyboard class is added when keyboard is open.
            window.addEventListener('resize', () => {
                if (window.innerHeight < initialScreenSize) {
                    this._$appEl.addClass(KEYBOARD_CLASS);
                }
                else {
                    this._$appEl.removeClass(KEYBOARD_CLASS);
                }
            });
        }
        getDeployedUrl() {
            let deployedUrl = variables.$rootScope.project.deployedUrl;
            if (i1$1.hasCordova()) {
                const baseUrl = $('meta[name="liveSync.deployedUrl"]').attr('value');
                const config = this.deviceService.getConfig();
                if (baseUrl) {
                    deployedUrl = baseUrl;
                }
                else {
                    deployedUrl = this.deviceService.getBaseUrl();
                }
                this.app.customUrlScheme = config.customUrlScheme;
            }
            if (deployedUrl !== 'NONE' && !deployedUrl.endsWith('/')) {
                deployedUrl = deployedUrl + '/';
            }
            variables.$rootScope.project.deployedUrl = deployedUrl;
            return deployedUrl;
        }
        addAuthInBrowser() {
            let isAuthenticating = false;
            this.securityService.authInBrowser = () => {
                if (!this.networkService.isConnected()) {
                    return Promise.reject('In offline, app cannot contact the server.');
                }
                if (isAuthenticating) {
                    return Promise.reject('Authentication is in process.');
                }
                isAuthenticating = true;
                return this.webProcessService.execute('LOGIN', '/', true)
                    .then(output => {
                    output = JSON.parse(output && output.replace(/&quot;/g, "\""));
                    if (output[variables.CONSTANTS.XSRF_COOKIE_NAME]) {
                        localStorage.setItem(variables.CONSTANTS.XSRF_COOKIE_NAME, output[variables.CONSTANTS.XSRF_COOKIE_NAME]);
                    }
                    isAuthenticating = false;
                    return this.cookieService.clearAll()
                        .then(() => {
                        const promises = lodashEs.keys(output).map(k => {
                            return this.cookieService.setCookie(this.app.deployedUrl, k, output[k]);
                        });
                        return Promise.all(promises);
                    });
                })
                    .then(() => this.app.notify('userLoggedIn', {}))
                    .catch((e) => {
                    isAuthenticating = false;
                    return Promise.reject(e);
                });
            };
        }
        static { this.ɵfac = function MobileRuntimeModule_Factory(t) { return new (t || MobileRuntimeModule)(i0__namespace.ɵɵinject(i1$1__namespace.App), i0__namespace.ɵɵinject(CookieService), i0__namespace.ɵɵinject(i3__namespace.DeviceFileOpenerService), i0__namespace.ɵɵinject(i3__namespace.DeviceService), i0__namespace.ɵɵinject(i4__namespace.SecurityService), i0__namespace.ɵɵinject(i1$1__namespace.AbstractHttpService), i0__namespace.ɵɵinject(i3__namespace.ExtAppMessageService), i0__namespace.ɵɵinject(i3__namespace.NetworkService), i0__namespace.ɵɵinject(WebProcessService)); }; }
        static { this.ɵmod = /*@__PURE__*/ i0__namespace.ɵɵdefineNgModule({ type: MobileRuntimeModule }); }
        static { this.ɵinj = /*@__PURE__*/ i0__namespace.ɵɵdefineInjector({ imports: [i3.MobileCoreModule,
                variables$1.VariablesModule,
                i1.BasicModule, MOBILE_COMPONENT_MODULES, i1.BasicModule,
                i3.MobileCoreModule,
                offline.OfflineModule,
                variables$1.VariablesModule,
                search.SearchModule,
                segmentedControl.SegmentedControlModule,
                mediaList.MediaListModule,
                barcodeScanner.BarcodeScannerModule,
                camera.CameraModule,
                fileUpload.FileUploadModule,
                page.PageModule,
                leftPanel.LeftPanelModule,
                mobileNavbar.MobileNavbarModule,
                tabBar.TabBarModule] }); }
    }
    (() => { (typeof ngDevMode === "undefined" || ngDevMode) && i0__namespace.ɵsetClassMetadata(MobileRuntimeModule, [{
            type: i0.NgModule,
            args: [{
                    declarations: [
                        AppExtComponent
                    ],
                    exports: [
                        AppExtComponent,
                        ...MOBILE_COMPONENT_MODULES
                    ],
                    imports: [
                        i3.MobileCoreModule,
                        variables$1.VariablesModule,
                        i1.BasicModule,
                        ...MOBILE_COMPONENT_MODULES
                    ],
                    bootstrap: []
                }]
        }], () => [{ type: i1$1__namespace.App }, { type: CookieService }, { type: i3__namespace.DeviceFileOpenerService }, { type: i3__namespace.DeviceService }, { type: i4__namespace.SecurityService }, { type: i1$1__namespace.AbstractHttpService }, { type: i3__namespace.ExtAppMessageService }, { type: i3__namespace.NetworkService }, { type: WebProcessService }], null); })();
    (function () { (typeof ngJitMode === "undefined" || ngJitMode) && i0__namespace.ɵɵsetNgModuleScope(MobileRuntimeModule, { declarations: [AppExtComponent], imports: [i3.MobileCoreModule,
            variables$1.VariablesModule,
            i1.BasicModule, i1.BasicModule,
            i3.MobileCoreModule,
            offline.OfflineModule,
            variables$1.VariablesModule,
            search.SearchModule,
            segmentedControl.SegmentedControlModule,
            mediaList.MediaListModule,
            barcodeScanner.BarcodeScannerModule,
            camera.CameraModule,
            fileUpload.FileUploadModule,
            page.PageModule,
            leftPanel.LeftPanelModule,
            mobileNavbar.MobileNavbarModule,
            tabBar.TabBarModule], exports: [AppExtComponent, i1.BasicModule,
            i3.MobileCoreModule,
            offline.OfflineModule,
            variables$1.VariablesModule,
            search.SearchModule,
            segmentedControl.SegmentedControlModule,
            mediaList.MediaListModule,
            barcodeScanner.BarcodeScannerModule,
            camera.CameraModule,
            fileUpload.FileUploadModule,
            page.PageModule,
            leftPanel.LeftPanelModule,
            mobileNavbar.MobileNavbarModule,
            tabBar.TabBarModule] }); })();

    exports.AppExtComponent = AppExtComponent;
    exports.CookieService = CookieService;
    exports.MAX_WAIT_TIME_4_OAUTH_MESSAGE = MAX_WAIT_TIME_4_OAUTH_MESSAGE;
    exports.MOBILE_COMPONENT_MODULES = MOBILE_COMPONENT_MODULES;
    exports.MobileHttpInterceptor = MobileHttpInterceptor;
    exports.MobileRuntimeModule = MobileRuntimeModule;
    exports.WebProcessService = WebProcessService;

}));
