{"version":3,"file":"push.js","sources":["../src/push/Messages.js","../src/push/Permission.js","../src/push/Util.js","../src/agents/AbstractAgent.js","../src/agents/DesktopAgent.js","../src/agents/MobileChromeAgent.js","../src/agents/MobileFirefoxAgent.js","../src/agents/MSAgent.js","../src/agents/WebKitAgent.js","../src/index.js","../src/push/Push.js"],"sourcesContent":["// @flow\nconst errorPrefix = 'PushError:';\n\nexport default {\n    errors: {\n        incompatible: `${errorPrefix} Push.js is incompatible with browser.`,\n        invalid_plugin: `${errorPrefix} plugin class missing from plugin manifest (invalid plugin). Please check the documentation.`,\n        invalid_title: `${errorPrefix} title of notification must be a string`,\n        permission_denied: `${errorPrefix} permission request declined`,\n        sw_notification_error: `${errorPrefix} could not show a ServiceWorker notification due to the following reason: `,\n        sw_registration_error: `${errorPrefix} could not register the ServiceWorker due to the following reason: `,\n        unknown_interface: `${errorPrefix} unable to create notification: unknown interface`\n    }\n};\n","// @flow\nimport type { Global } from 'types';\n\nexport default class Permission {\n    // Private members\n    _permissions: string[];\n    _win: Global;\n\n    // Public members\n    GRANTED: string;\n    DEFAULT: string;\n    DENIED: string;\n\n    constructor(win: Global) {\n        this._win = win;\n        this.GRANTED = 'granted';\n        this.DEFAULT = 'default';\n        this.DENIED = 'denied';\n        this._permissions = [this.GRANTED, this.DEFAULT, this.DENIED];\n    }\n\n    /**\n   * Requests permission for desktop notifications\n   * @param {Function} onGranted - Function to execute once permission is granted\n   * @param {Function} onDenied - Function to execute once permission is denied\n   * @return {void, Promise}\n   */\n    request(onGranted: () => void, onDenied: () => void) {\n        return arguments.length > 0\n            ? this._requestWithCallback(...arguments)\n            : this._requestAsPromise();\n    }\n\n    /**\n   * Old permissions implementation deprecated in favor of a promise based one\n   * @deprecated Since V1.0.4\n   * @param {Function} onGranted - Function to execute once permission is granted\n   * @param {Function} onDenied - Function to execute once permission is denied\n   * @return {void}\n   */\n    _requestWithCallback(onGranted: () => void, onDenied: () => void) {\n        const existing = this.get();\n\n        var resolved = false;\n        var resolve = (result = this._win.Notification.permission) => {\n            if (resolved) return;\n            resolved = true;\n            if (typeof result === 'undefined' && this._win.webkitNotifications)\n                result = this._win.webkitNotifications.checkPermission();\n            if (result === this.GRANTED || result === 0) {\n                if (onGranted) onGranted();\n            } else if (onDenied) onDenied();\n        };\n        var request;\n\n        /* Permissions already set */\n        if (existing !== this.DEFAULT) {\n            resolve(existing);\n        } else if (\n            this._win.webkitNotifications &&\n            this._win.webkitNotifications.checkPermission\n        ) {\n            /* Safari 6+, Legacy webkit browsers */\n            this._win.webkitNotifications.requestPermission(resolve);\n        } else if (\n            this._win.Notification &&\n            this._win.Notification.requestPermission\n        ) {\n            /* Safari 12+ */\n            /* This resolve argument will only be used in Safari */\n            /* CHrome, instead, returns a Promise */\n            request = this._win.Notification.requestPermission(resolve);\n            if (request && request.then) {\n                /* Chrome 23+ */\n                request.then(resolve).catch(function() {\n                    if (onDenied) onDenied();\n                });\n            }\n        } else if (onGranted) {\n            /* Let the user continue by default */\n            onGranted();\n        }\n    }\n\n    /**\n   * Requests permission for desktop notifications in a promise based way\n   * @return {Promise}\n   */\n    _requestAsPromise(): Promise<void> {\n        const existing = this.get();\n\n        let isGranted = result => result === this.GRANTED || result === 0;\n\n        /* Permissions already set */\n        var hasPermissions = existing !== this.DEFAULT;\n\n        /* Safari 6+, Chrome 23+ */\n        var isModernAPI =\n            this._win.Notification && this._win.Notification.requestPermission;\n\n        /* Legacy webkit browsers */\n        var isWebkitAPI =\n            this._win.webkitNotifications &&\n            this._win.webkitNotifications.checkPermission;\n\n        return new Promise((resolvePromise, rejectPromise) => {\n            var resolved = false;\n            var resolver = result => {\n                if (resolved) return;\n                resolved = true;\n                isGranted(result) ? resolvePromise() : rejectPromise();\n            };\n            var request;\n\n            if (hasPermissions) {\n                resolver(existing);\n            } else if (isWebkitAPI) {\n                this._win.webkitNotifications.requestPermission(result => {\n                    resolver(result);\n                });\n            } else if (isModernAPI) {\n                /* Safari 12+ */\n                /* This resolver argument will only be used in Safari */\n                /* CHrome, instead, returns a Promise */\n                request = this._win.Notification.requestPermission(resolver);\n                if (request && request.then) {\n                    /* Chrome 23+ */\n                    request.then(resolver).catch(rejectPromise);\n                }\n            } else resolvePromise();\n        });\n    }\n\n    /**\n   * Returns whether Push has been granted permission to run\n   * @return {Boolean}\n   */\n    has() {\n        return this.get() === this.GRANTED;\n    }\n\n    /**\n   * Gets the permission level\n   * @return {Permission} The permission level\n   */\n    get() {\n        let permission;\n\n        /* Safari 6+, Chrome 23+ */\n        if (this._win.Notification && this._win.Notification.permission)\n            permission = this._win.Notification.permission;\n        else if (\n            this._win.webkitNotifications &&\n            this._win.webkitNotifications.checkPermission\n        )\n            /* Legacy webkit browsers */\n            permission = this._permissions[\n                this._win.webkitNotifications.checkPermission()\n            ];\n        else if (navigator.mozNotification)\n            /* Firefox Mobile */\n            permission = this.GRANTED;\n        else if (this._win.external && this._win.external.msIsSiteMode)\n            /* IE9+ */\n            permission = this._win.external.msIsSiteMode()\n                ? this.GRANTED\n                : this.DEFAULT;\n        else permission = this.GRANTED;\n\n        return permission;\n    }\n}\n","// @flow\nexport default class Util {\n    static isUndefined(obj) {\n        return obj === undefined;\n    }\n\n    static isNull(obs) {\n        return obj === null;\n    }\n\n    static isString(obj) {\n        return typeof obj === 'string';\n    }\n\n    static isFunction(obj) {\n        return obj && {}.toString.call(obj) === '[object Function]';\n    }\n\n    static isObject(obj) {\n        return typeof obj === 'object';\n    }\n\n    static objectMerge(target, source) {\n        for (var key in source) {\n            if (\n                target.hasOwnProperty(key) &&\n                this.isObject(target[key]) &&\n                this.isObject(source[key])\n            ) {\n                this.objectMerge(target[key], source[key]);\n            } else {\n                target[key] = source[key];\n            }\n        }\n    }\n}\n","// @flow\nimport type { Global } from 'types';\n\nexport default class AbstractAgent {\n    _win: Global;\n\n    constructor(win: Global) {\n        this._win = win;\n    }\n}\n","// @flow\nimport { AbstractAgent } from 'agents';\nimport { Util } from 'push';\nimport type { PushOptions, GenericNotification, Global } from 'types';\n\n/**\n * Notification agent for modern desktop browsers:\n * Safari 6+, Firefox 22+, Chrome 22+, Opera 25+\n */\nexport default class DesktopAgent extends AbstractAgent {\n    _win: Global;\n\n    /**\n     * Returns a boolean denoting support\n     * @returns {Boolean} boolean denoting whether webkit notifications are supported\n     */\n    isSupported() {\n        return this._win.Notification !== undefined;\n    }\n\n    /**\n     * Creates a new notification\n     * @param title - notification title\n     * @param options - notification options array\n     * @returns {Notification}\n     */\n    create(title: string, options: PushOptions) {\n        return new this._win.Notification(title, {\n            icon:\n                Util.isString(options.icon) ||\n                Util.isUndefined(options.icon) ||\n                Util.isNull(options.icon)\n                    ? options.icon\n                    : options.icon.x32,\n            body: options.body,\n            tag: options.tag,\n            requireInteraction: options.requireInteraction\n        });\n    }\n\n    /**\n     * Close a given notification\n     * @param notification - notification to close\n     */\n    close(notification: GenericNotification) {\n        notification.close();\n    }\n}\n","// @flow\nimport { Util, Messages } from 'push';\nimport { AbstractAgent } from 'agents';\nimport type { Global, GenericNotification, PushOptions } from 'types';\n\n/**\n * Notification agent for modern desktop browsers:\n * Safari 6+, Firefox 22+, Chrome 22+, Opera 25+\n */\nexport default class MobileChromeAgent extends AbstractAgent {\n    _win: Global;\n\n    /**\n     * Returns a boolean denoting support\n     * @returns {Boolean} boolean denoting whether webkit notifications are supported\n     */\n    isSupported() {\n        return (\n            this._win.navigator !== undefined &&\n            this._win.navigator.serviceWorker !== undefined\n        );\n    }\n\n    /**\n     * Returns the function body as a string\n     * @param func\n     */\n    getFunctionBody(func: () => void) {\n        const str = func.toString().match(/function[^{]+{([\\s\\S]*)}$/);\n        return typeof str !== 'undefined' && str !== null && str.length > 1\n            ? str[1]\n            : null;\n    }\n\n    /**\n     * Creates a new notification\n     * @param id                ID of notification\n     * @param title             Title of notification\n     * @param options           Options object\n     * @param serviceWorker     ServiceWorker path\n     * @param callback          Callback function\n     */\n    create(\n        id: number,\n        title: string,\n        options: PushOptions,\n        serviceWorker: string,\n        callback: (GenericNotification[]) => void\n    ) {\n        /* Register ServiceWorker */\n        this._win.navigator.serviceWorker.register(serviceWorker);\n\n        this._win.navigator.serviceWorker.ready\n            .then(registration => {\n                /* Local data the service worker will use */\n                let localData = {\n                    id: id,\n                    link: options.link,\n                    origin: document.location.href,\n                    onClick: Util.isFunction(options.onClick)\n                        ? this.getFunctionBody(options.onClick)\n                        : '',\n                    onClose: Util.isFunction(options.onClose)\n                        ? this.getFunctionBody(options.onClose)\n                        : ''\n                };\n\n                /* Merge the local data with user-provided data */\n                if (options.data !== undefined && options.data !== null)\n                    localData = Object.assign(localData, options.data);\n\n                /* Show the notification */\n                registration\n                    .showNotification(title, {\n                        icon: options.icon,\n                        body: options.body,\n                        vibrate: options.vibrate,\n                        tag: options.tag,\n                        data: localData,\n                        requireInteraction: options.requireInteraction,\n                        silent: options.silent\n                    })\n                    .then(() => {\n                        registration.getNotifications().then(notifications => {\n                            /* Send an empty message so the ServiceWorker knows who the client is */\n                            registration.active.postMessage('');\n\n                            /* Trigger callback */\n                            callback(notifications);\n                        });\n                    })\n                    .catch(function(error) {\n                        throw new Error(\n                            Messages.errors.sw_notification_error +\n                                error.message\n                        );\n                    });\n            })\n            .catch(function(error) {\n                throw new Error(\n                    Messages.errors.sw_registration_error + error.message\n                );\n            });\n    }\n\n    /**\n     * Close all notification\n     */\n    close() {\n        // Can't do this with service workers\n    }\n}\n","// @flow\nimport { AbstractAgent } from 'agents';\nimport type { Global, PushOptions } from 'types';\n\n/**\n * Notification agent for modern desktop browsers:\n * Safari 6+, Firefox 22+, Chrome 22+, Opera 25+\n */\nexport default class MobileFirefoxAgent extends AbstractAgent {\n    _win: Global;\n\n    /**\n     * Returns a boolean denoting support\n     * @returns {Boolean} boolean denoting whether webkit notifications are supported\n     */\n    isSupported() {\n        return this._win.navigator.mozNotification !== undefined;\n    }\n\n    /**\n     * Creates a new notification\n     * @param title - notification title\n     * @param options - notification options array\n     * @returns {Notification}\n     */\n    create(title: string, options: PushOptions) {\n        let notification = this._win.navigator.mozNotification.createNotification(\n            title,\n            options.body,\n            options.icon\n        );\n\n        notification.show();\n\n        return notification;\n    }\n}\n","// @flow\nimport { AbstractAgent } from 'agents';\nimport { Util } from 'push';\nimport type { PushOptions, Global } from 'types';\n\n/**\n * Notification agent for IE9\n */\nexport default class MSAgent extends AbstractAgent {\n    _win: Global;\n\n    /**\n     * Returns a boolean denoting support\n     * @returns {Boolean} boolean denoting whether webkit notifications are supported\n     */\n    isSupported() {\n        return (\n            this._win.external !== undefined &&\n            this._win.external.msIsSiteMode !== undefined\n        );\n    }\n\n    /**\n     * Creates a new notification\n     * @param title - notification title\n     * @param options - notification options array\n     * @returns {Notification}\n     */\n    create(title: string, options: PushOptions) {\n        /* Clear any previous notifications */\n        this._win.external.msSiteModeClearIconOverlay();\n\n        this._win.external.msSiteModeSetIconOverlay(\n            Util.isString(options.icon) || Util.isUndefined(options.icon)\n                ? options.icon\n                : options.icon.x16,\n            title\n        );\n\n        this._win.external.msSiteModeActivate();\n\n        return null;\n    }\n\n    /**\n     * Close a given notification\n     * @param notification - notification to close\n     */\n    close() {\n        this._win.external.msSiteModeClearIconOverlay();\n    }\n}\n","// @flow\nimport { AbstractAgent } from 'agents';\nimport type { Global, GenericNotification, PushOptions } from 'types';\n\n/**\n * Notification agent for old Chrome versions (and some) Firefox\n */\nexport default class WebKitAgent extends AbstractAgent {\n    _win: Global;\n\n    /**\n     * Returns a boolean denoting support\n     * @returns {Boolean} boolean denoting whether webkit notifications are supported\n     */\n    isSupported() {\n        return this._win.webkitNotifications !== undefined;\n    }\n\n    /**\n     * Creates a new notification\n     * @param title - notification title\n     * @param options - notification options array\n     * @returns {Notification}\n     */\n    create(title: string, options: PushOptions) {\n        let notification = this._win.webkitNotifications.createNotification(\n            options.icon,\n            title,\n            options.body\n        );\n\n        notification.show();\n\n        return notification;\n    }\n\n    /**\n     * Close a given notification\n     * @param notification - notification to close\n     */\n    close(notification: GenericNotification) {\n        notification.cancel();\n    }\n}\n","// @flow\nimport { Push } from 'push';\n\nexport default new Push(typeof window !== 'undefined' ? window : global);\n","// @flow\nimport { Messages, Permission, Util } from 'push';\nimport type { PluginManifest, GenericNotification, PushOptions } from 'types';\n\n/* Import notification agents */\nimport {\n    DesktopAgent,\n    MobileChromeAgent,\n    MobileFirefoxAgent,\n    MSAgent,\n    WebKitAgent\n} from 'agents';\n\nexport default class Push {\n    // Private members\n    _agents: {\n        desktop: DesktopAgent,\n        chrome: MobileChromeAgent,\n        firefox: MobileFirefoxAgent,\n        ms: MSAgent,\n        webkit: WebKitAgent\n    };\n    _configuration: {\n        serviceWorker: string,\n        fallback: ({}) => void\n    };\n    _currentId: number;\n    _notifications: {};\n    _win: {};\n\n    // Public members\n    Permission: Permission;\n\n    constructor(win: {}) {\n        /* Private variables */\n\n        /* ID to use for new notifications */\n        this._currentId = 0;\n\n        /* Map of open notifications */\n        this._notifications = {};\n\n        /* Window object */\n        this._win = win;\n\n        /* Public variables */\n        this.Permission = new Permission(win);\n\n        /* Agents */\n        this._agents = {\n            desktop: new DesktopAgent(win),\n            chrome: new MobileChromeAgent(win),\n            firefox: new MobileFirefoxAgent(win),\n            ms: new MSAgent(win),\n            webkit: new WebKitAgent(win)\n        };\n\n        this._configuration = {\n            serviceWorker: '/serviceWorker.min.js',\n            fallback: function(payload) {}\n        };\n    }\n\n    /**\n     * Closes a notification\n     * @param id            ID of notification\n     * @returns {boolean}   denotes whether the operation was successful\n     * @private\n     */\n    _closeNotification(id: number | string) {\n        let success = true;\n        const notification = this._notifications[id];\n\n        if (notification !== undefined) {\n            success = this._removeNotification(id);\n\n            /* Safari 6+, Firefox 22+, Chrome 22+, Opera 25+ */\n            if (this._agents.desktop.isSupported())\n                this._agents.desktop.close(notification);\n            else if (this._agents.webkit.isSupported())\n                /* Legacy WebKit browsers */\n                this._agents.webkit.close(notification);\n            else if (this._agents.ms.isSupported())\n                /* IE9 */\n                this._agents.ms.close();\n            else {\n                success = false;\n                throw new Error(Messages.errors.unknown_interface);\n            }\n\n            return success;\n        }\n\n        return false;\n    }\n\n    /**\n   * Adds a notification to the global dictionary of notifications\n   * @param {Notification} notification\n   * @return {Integer} Dictionary key of the notification\n   * @private\n   */\n    _addNotification(notification: GenericNotification) {\n        const id = this._currentId;\n        this._notifications[id] = notification;\n        this._currentId++;\n        return id;\n    }\n\n    /**\n   * Removes a notification with the given ID\n   * @param  {Integer} id - Dictionary key/ID of the notification to remove\n   * @return {Boolean} boolean denoting success\n   * @private\n   */\n    _removeNotification(id: number | string) {\n        let success = false;\n\n        if (this._notifications.hasOwnProperty(id)) {\n            /* We're successful if we omit the given ID from the new array */\n            delete this._notifications[id];\n            success = true;\n        }\n\n        return success;\n    }\n\n    /**\n   * Creates the wrapper for a given notification\n   *\n   * @param {Integer} id - Dictionary key/ID of the notification\n   * @param {Map} options - Options used to create the notification\n   * @returns {Map} wrapper hashmap object\n   * @private\n   */\n    _prepareNotification(id: number, options: PushOptions) {\n        let wrapper;\n\n        /* Wrapper used to get/close notification later on */\n        wrapper = {\n            get: () => {\n                return this._notifications[id];\n            },\n\n            close: () => {\n                this._closeNotification(id);\n            }\n        };\n\n        /* Autoclose timeout */\n        if (options.timeout) {\n            setTimeout(() => {\n                wrapper.close();\n            }, options.timeout);\n        }\n\n        return wrapper;\n    }\n\n    /**\n   * Find the most recent notification from a ServiceWorker and add it to the global array\n   * @param notifications\n   * @private\n   */\n    _serviceWorkerCallback(\n        notifications: GenericNotification[],\n        options: PushOptions,\n        resolve: ({} | null) => void\n    ) {\n        let id = this._addNotification(notifications[notifications.length - 1]);\n\n        /* Listen for close requests from the ServiceWorker */\n        if (navigator && navigator.serviceWorker) {\n            navigator.serviceWorker.addEventListener('message', event => {\n                const data = JSON.parse(event.data);\n\n                if (data.action === 'close' && Number.isInteger(data.id))\n                    this._removeNotification(data.id);\n            });\n\n            resolve(this._prepareNotification(id, options));\n        }\n\n        resolve(null);\n    }\n\n    /**\n   * Callback function for the 'create' method\n   * @return {void}\n   * @private\n   */\n    _createCallback(\n        title: string,\n        options: PushOptions,\n        resolve: ({} | null) => void\n    ) {\n        let notification = null;\n        let onClose;\n\n        /* Set empty settings if none are specified */\n        options = options || {};\n\n        /* onClose event handler */\n        onClose = id => {\n            /* A bit redundant, but covers the cases when close() isn't explicitly called */\n            this._removeNotification(id);\n            if (Util.isFunction(options.onClose)) {\n                options.onClose.call(this, notification);\n            }\n        };\n\n        /* Safari 6+, Firefox 22+, Chrome 22+, Opera 25+ */\n        if (this._agents.desktop.isSupported()) {\n            try {\n                /* Create a notification using the API if possible */\n                notification = this._agents.desktop.create(title, options);\n            } catch (e) {\n                const id = this._currentId;\n                const sw = this.config().serviceWorker;\n                const cb = notifications =>\n                    this._serviceWorkerCallback(\n                        notifications,\n                        options,\n                        resolve\n                    );\n                /* Create a Chrome ServiceWorker notification if it isn't supported */\n                if (this._agents.chrome.isSupported()) {\n                    this._agents.chrome.create(id, title, options, sw, cb);\n                }\n            }\n            /* Legacy WebKit browsers */\n        } else if (this._agents.webkit.isSupported())\n            notification = this._agents.webkit.create(title, options);\n        else if (this._agents.firefox.isSupported())\n            /* Firefox Mobile */\n            this._agents.firefox.create(title, options);\n        else if (this._agents.ms.isSupported())\n            /* IE9 */\n            notification = this._agents.ms.create(title, options);\n        else {\n            /* Default fallback */\n            options.title = title;\n            this.config().fallback(options);\n        }\n\n        if (notification !== null) {\n            const id = this._addNotification(notification);\n            const wrapper = this._prepareNotification(id, options);\n\n            /* Notification callbacks */\n            if (Util.isFunction(options.onShow))\n                notification.addEventListener('show', options.onShow);\n\n            if (Util.isFunction(options.onError))\n                notification.addEventListener('error', options.onError);\n\n            if (Util.isFunction(options.onClick))\n                notification.addEventListener('click', options.onClick);\n\n            notification.addEventListener('close', () => {\n                onClose(id);\n            });\n\n            notification.addEventListener('cancel', () => {\n                onClose(id);\n            });\n\n            /* Return the wrapper so the user can call close() */\n            resolve(wrapper);\n        }\n\n        /* By default, pass an empty wrapper */\n        resolve(null);\n    }\n\n    /**\n   * Creates and displays a new notification\n   * @param {Array} options\n   * @return {Promise}\n   */\n    create(title: string, options: {}): Promise<void> {\n        let promiseCallback;\n\n        /* Fail if no or an invalid title is provided */\n        if (!Util.isString(title)) {\n            throw new Error(Messages.errors.invalid_title);\n        }\n\n        /* Request permission if it isn't granted */\n        if (!this.Permission.has()) {\n            promiseCallback = (resolve: () => void, reject: string => void) => {\n                this.Permission\n                    .request()\n                    .then(() => {\n                        this._createCallback(title, options, resolve);\n                    })\n                    .catch(() => {\n                        reject(Messages.errors.permission_denied);\n                    });\n            };\n        } else {\n            promiseCallback = (resolve: () => void, reject: string => void) => {\n                try {\n                    this._createCallback(title, options, resolve);\n                } catch (e) {\n                    reject(e);\n                }\n            };\n        }\n\n        return new Promise(promiseCallback);\n    }\n\n    /**\n   * Returns the notification count\n   * @return {Integer} The notification count\n   */\n    count() {\n        let count = 0;\n        let key;\n\n        for (key in this._notifications)\n            if (this._notifications.hasOwnProperty(key)) count++;\n\n        return count;\n    }\n\n    /**\n   * Closes a notification with the given tag\n   * @param {String} tag - Tag of the notification to close\n   * @return {Boolean} boolean denoting success\n   */\n    close(tag: string) {\n        let key, notification;\n\n        for (key in this._notifications) {\n            if (this._notifications.hasOwnProperty(key)) {\n                notification = this._notifications[key];\n\n                /* Run only if the tags match */\n                if (notification.tag === tag) {\n                    /* Call the notification's close() method */\n                    return this._closeNotification(key);\n                }\n            }\n        }\n    }\n\n    /**\n   * Clears all notifications\n   * @return {Boolean} boolean denoting whether the clear was successful in closing all notifications\n   */\n    clear() {\n        let key,\n            success = true;\n\n        for (key in this._notifications)\n            if (this._notifications.hasOwnProperty(key))\n                success = success && this._closeNotification(key);\n\n        return success;\n    }\n\n    /**\n   * Denotes whether Push is supported in the current browser\n   * @returns {boolean}\n   */\n    supported() {\n        let supported = false;\n\n        for (var agent in this._agents)\n            if (this._agents.hasOwnProperty(agent))\n                supported = supported || this._agents[agent].isSupported();\n\n        return supported;\n    }\n\n    /**\n   * Modifies settings or returns all settings if no parameter passed\n   * @param settings\n   */\n    config(settings?: {}) {\n        if (\n            typeof settings !== 'undefined' ||\n            (settings !== null && Util.isObject(settings))\n        )\n            Util.objectMerge(this._configuration, settings);\n\n        return this._configuration;\n    }\n\n    /**\n   * Copies the functions from a plugin to the main library\n   * @param plugin\n   */\n    extend(manifest: PluginManifest) {\n        var plugin,\n            Plugin,\n            hasProp = {}.hasOwnProperty;\n\n        if (!hasProp.call(manifest, 'plugin')) {\n            throw new Error(Messages.errors.invalid_plugin);\n        } else {\n            if (\n                hasProp.call(manifest, 'config') &&\n                Util.isObject(manifest.config) &&\n                manifest.config !== null\n            ) {\n                this.config(manifest.config);\n            }\n\n            Plugin = manifest.plugin;\n            plugin = new Plugin(this.config());\n\n            for (var member in plugin) {\n                if (\n                    hasProp.call(plugin, member) &&\n                    Util.isFunction(plugin[member])\n                )\n                    // $FlowFixMe\n                    this[member] = plugin[member];\n            }\n        }\n    }\n}\n"],"names":["errors","incompatible","invalid_plugin","invalid_title","permission_denied","sw_notification_error","sw_registration_error","unknown_interface","Permission","win","_win","GRANTED","DEFAULT","DENIED","_permissions","this","onGranted","onDenied","arguments","length","_requestWithCallback","_requestAsPromise","request","existing","get","resolved","resolve","result","_this","Notification","permission","webkitNotifications","checkPermission","requestPermission","then","hasPermissions","isModernAPI","isWebkitAPI","Promise","resolvePromise","rejectPromise","resolver","_this2","isGranted","navigator","mozNotification","external","msIsSiteMode","Util","obj","undefined","obs","toString","call","_typeof","target","source","key","hasOwnProperty","isObject","objectMerge","AbstractAgent","DesktopAgent","title","options","icon","isString","isUndefined","isNull","x32","body","tag","requireInteraction","notification","close","MobileChromeAgent","serviceWorker","func","str","match","id","callback","register","ready","registration","localData","link","origin","document","location","href","onClick","isFunction","getFunctionBody","onClose","data","Object","assign","showNotification","vibrate","silent","getNotifications","notifications","active","postMessage","error","Error","Messages","message","MobileFirefoxAgent","createNotification","show","MSAgent","msSiteModeClearIconOverlay","msSiteModeSetIconOverlay","x16","msSiteModeActivate","WebKitAgent","cancel","_currentId","_notifications","_agents","desktop","chrome","firefox","ms","webkit","_configuration","fallback","payload","success","_removeNotification","isSupported","wrapper","_closeNotification","timeout","setTimeout","_addNotification","addEventListener","event","JSON","parse","action","Number","isInteger","_prepareNotification","_this3","create","e","sw","config","_serviceWorkerCallback","onShow","onError","promiseCallback","has","reject","_this4","_createCallback","count","supported","agent","settings","manifest","plugin","hasProp","member","Plugin","window","global"],"mappings":"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"}