From c14a2044cd55498f38110883636c8b13a2db9b41 Mon Sep 17 00:00:00 2001 From: or-else Date: Wed, 19 Sep 2018 17:52:29 +0300 Subject: [PATCH] push notifications work now --- package.json | 1 + src/webapp.jsx | 4 + umd/index.dev.js | 6933 ++++++++++++++++++++++++++++++++++++++++++++- umd/index.prod.js | 2 +- 4 files changed, 6865 insertions(+), 75 deletions(-) diff --git a/package.json b/package.json index 85065f7d..b9c8466f 100644 --- a/package.json +++ b/package.json @@ -63,6 +63,7 @@ "author": "Tinode Authors ", "license": "Apache-2.0", "dependencies": { + "firebase": "^5.5.0", "react": "^16.5.1", "react-dom": "^16.4.2", "tinode-sdk": "^0.15.6-rc3" diff --git a/src/webapp.jsx b/src/webapp.jsx index daee2aa6..2bbe5b0b 100644 --- a/src/webapp.jsx +++ b/src/webapp.jsx @@ -11,6 +11,10 @@ if (typeof require == 'function') { var Tinode = require('tinode-sdk'); var Drafty = Tinode.Drafty; } + if (typeof firebase == 'undefined') { + var firebase = require('firebase/app'); + require('firebase/messaging'); + } } // Name of this application, used in the User-Agent. diff --git a/umd/index.dev.js b/umd/index.dev.js index ccd10974..16b02d7a 100644 --- a/umd/index.dev.js +++ b/umd/index.dev.js @@ -1,4 +1,5844 @@ (function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.Webapp = f()}})(function(){var define,module,exports;return (function(){function r(e,n,t){function o(i,f){if(!n[i]){if(!e[i]){var c="function"==typeof require&&require;if(!f&&c)return c(i,!0);if(u)return u(i,!0);var a=new Error("Cannot find module '"+i+"'");throw a.code="MODULE_NOT_FOUND",a}var p=n[i]={exports:{}};e[i][0].call(p.exports,function(r){var n=e[i][1][r];return o(n||r)},p,p.exports,r,e,n,t)}return n[i].exports}for(var u="function"==typeof require&&require,i=0;i maxActions) { + console.warn("This browser only supports " + maxActions + " actions." + + "The remaining actions will not be displayed."); + } + return [2 /*return*/, reg.showNotification(notificationTitle, notificationDetails)]; + case 3: + if (!this.bgMessageHandler) return [3 /*break*/, 5]; + return [4 /*yield*/, this.bgMessageHandler(msgPayload)]; + case 4: + _a.sent(); + return [2 /*return*/]; + case 5: return [2 /*return*/]; + } + }); + }); + }; + SwController.prototype.onSubChange_ = function (event) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var registration, err_1, err_2, tokenDetailsModel, tokenDetails; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + _a.trys.push([0, 2, , 3]); + return [4 /*yield*/, this.getSWRegistration_()]; + case 1: + registration = _a.sent(); + return [3 /*break*/, 3]; + case 2: + err_1 = _a.sent(); + throw errorFactory.create(ERROR_CODES.UNABLE_TO_RESUBSCRIBE, { + message: err_1 + }); + case 3: + _a.trys.push([3, 5, , 8]); + return [4 /*yield*/, registration.pushManager.getSubscription()]; + case 4: + _a.sent(); + return [3 /*break*/, 8]; + case 5: + err_2 = _a.sent(); + tokenDetailsModel = this.getTokenDetailsModel(); + return [4 /*yield*/, tokenDetailsModel.getTokenDetailsFromSWScope(registration.scope)]; + case 6: + tokenDetails = _a.sent(); + if (!tokenDetails) { + // This should rarely occure, but could if indexedDB + // is corrupted or wiped + throw err_2; + } + // Attempt to delete the token if we know it's bad + return [4 /*yield*/, this.deleteToken(tokenDetails.fcmToken)]; + case 7: + // Attempt to delete the token if we know it's bad + _a.sent(); + throw err_2; + case 8: return [2 /*return*/]; + } + }); + }); + }; + SwController.prototype.onNotificationClick_ = function (event) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var msgPayload, link, windowClient, internalMsg; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!event.notification || + !event.notification.data || + !event.notification.data[FCM_MSG]) { + // Not an FCM notification, do nothing. + return [2 /*return*/]; + } + else if (event.action) { + // User clicked on an action button. + // This will allow devs to act on action button clicks by using a custom + // onNotificationClick listener that they define. + return [2 /*return*/]; + } + // Prevent other listeners from receiving the event + event.stopImmediatePropagation(); + event.notification.close(); + msgPayload = event.notification.data[FCM_MSG]; + if (!msgPayload.notification) { + // Nothing to do. + return [2 /*return*/]; + } + link = (msgPayload.fcmOptions && msgPayload.fcmOptions.link) || + msgPayload.notification.click_action; + if (!link) { + // Nothing to do. + return [2 /*return*/]; + } + return [4 /*yield*/, this.getWindowClient_(link)]; + case 1: + windowClient = _a.sent(); + if (!!windowClient) return [3 /*break*/, 3]; + return [4 /*yield*/, self.clients.openWindow(link)]; + case 2: + // Unable to find window client so need to open one. + windowClient = _a.sent(); + return [3 /*break*/, 5]; + case 3: return [4 /*yield*/, windowClient.focus()]; + case 4: + windowClient = _a.sent(); + _a.label = 5; + case 5: + if (!windowClient) { + // Window Client will not be returned if it's for a third party origin. + return [2 /*return*/]; + } + // Delete notification and fcmOptions data from payload before sending to + // the page. + delete msgPayload.notification; + delete msgPayload.fcmOptions; + internalMsg = createNewMsg(MessageType.NOTIFICATION_CLICKED, msgPayload); + // Attempt to send a message to the client to handle the data + // Is affected by: https://github.com/slightlyoff/ServiceWorker/issues/728 + return [2 /*return*/, this.attemptToMessageClient_(windowClient, internalMsg)]; + } + }); + }); + }; + // Visible for testing + // TODO: Make private + SwController.prototype.getNotificationData_ = function (msgPayload) { + if (!msgPayload) { + return; + } + if (typeof msgPayload.notification !== 'object') { + return; + } + var notificationInformation = tslib_1.__assign({}, msgPayload.notification); + // Put the message payload under FCM_MSG name so we can identify the + // notification as being an FCM notification vs a notification from + // somewhere else (i.e. normal web push or developer generated + // notification). + notificationInformation.data = tslib_1.__assign({}, msgPayload.notification.data, (_a = {}, _a[FCM_MSG] = msgPayload, _a)); + return notificationInformation; + var _a; + }; + /** + * Calling setBackgroundMessageHandler will opt in to some specific + * behaviours. + * 1.) If a notification doesn't need to be shown due to a window already + * being visible, then push messages will be sent to the page. + * 2.) If a notification needs to be shown, and the message contains no + * notification data this method will be called + * and the promise it returns will be passed to event.waitUntil. + * If you do not set this callback then all push messages will let and the + * developer can handle them in a their own 'push' event callback + * + * @param callback The callback to be called when a push message is received + * and a notification must be shown. The callback will be given the data from + * the push message. + */ + SwController.prototype.setBackgroundMessageHandler = function (callback) { + if (!callback || typeof callback !== 'function') { + throw errorFactory.create(ERROR_CODES.BG_HANDLER_FUNCTION_EXPECTED); + } + this.bgMessageHandler = callback; + }; + /** + * @param url The URL to look for when focusing a client. + * @return Returns an existing window client or a newly opened WindowClient. + */ + // Visible for testing + // TODO: Make private + SwController.prototype.getWindowClient_ = function (url) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var parsedURL, clientList, suitableClient, i, parsedClientUrl; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + parsedURL = new URL(url, self.location.href).href; + return [4 /*yield*/, getClientList()]; + case 1: + clientList = _a.sent(); + suitableClient = null; + for (i = 0; i < clientList.length; i++) { + parsedClientUrl = new URL(clientList[i].url, self.location.href) + .href; + if (parsedClientUrl === parsedURL) { + suitableClient = clientList[i]; + break; + } + } + return [2 /*return*/, suitableClient]; + } + }); + }); + }; + /** + * This message will attempt to send the message to a window client. + * @param client The WindowClient to send the message to. + * @param message The message to send to the client. + * @returns Returns a promise that resolves after sending the message. This + * does not guarantee that the message was successfully received. + */ + // Visible for testing + // TODO: Make private + SwController.prototype.attemptToMessageClient_ = function (client, message) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + return tslib_1.__generator(this, function (_a) { + // NOTE: This returns a promise in case this API is abstracted later on to + // do additional work + if (!client) { + throw errorFactory.create(ERROR_CODES.NO_WINDOW_CLIENT_TO_MSG); + } + client.postMessage(message); + return [2 /*return*/]; + }); + }); + }; + /** + * @returns If there is currently a visible WindowClient, this method will + * resolve to true, otherwise false. + */ + // Visible for testing + // TODO: Make private + SwController.prototype.hasVisibleClients_ = function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var clientList; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, getClientList()]; + case 1: + clientList = _a.sent(); + return [2 /*return*/, clientList.some(function (client) { return client.visibilityState === 'visible'; })]; + } + }); + }); + }; + /** + * @param msgPayload The data from the push event that should be sent to all + * available pages. + * @returns Returns a promise that resolves once the message has been sent to + * all WindowClients. + */ + // Visible for testing + // TODO: Make private + SwController.prototype.sendMessageToWindowClients_ = function (msgPayload) { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var _this = this; + var clientList, internalMsg; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, getClientList()]; + case 1: + clientList = _a.sent(); + internalMsg = createNewMsg(MessageType.PUSH_MSG_RECEIVED, msgPayload); + return [4 /*yield*/, Promise.all(clientList.map(function (client) { + return _this.attemptToMessageClient_(client, internalMsg); + }))]; + case 2: + _a.sent(); + return [2 /*return*/]; + } + }); + }); + }; + /** + * This will register the default service worker and return the registration. + * @return he service worker registration to be used for the push service. + */ + SwController.prototype.getSWRegistration_ = function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { + return tslib_1.__generator(this, function (_a) { + return [2 /*return*/, self.registration]; + }); + }); + }; + /** + * This will return the default VAPID key or the uint8array version of the + * public VAPID key provided by the developer. + */ + SwController.prototype.getPublicVapidKey_ = function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var swReg, vapidKeyFromDatabase; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: return [4 /*yield*/, this.getSWRegistration_()]; + case 1: + swReg = _a.sent(); + if (!swReg) { + throw errorFactory.create(ERROR_CODES.SW_REGISTRATION_EXPECTED); + } + return [4 /*yield*/, this.getVapidDetailsModel().getVapidFromSWScope(swReg.scope)]; + case 2: + vapidKeyFromDatabase = _a.sent(); + if (vapidKeyFromDatabase == null) { + return [2 /*return*/, DEFAULT_PUBLIC_VAPID_KEY]; + } + return [2 /*return*/, vapidKeyFromDatabase]; + } + }); + }); + }; + return SwController; +}(BaseController)); +function getClientList() { + return self.clients.matchAll({ + type: 'window', + includeUncontrolled: true + // TS doesn't know that "type: 'window'" means it'll return WindowClient[] + }); +} +function createNewMsg(msgType, msgData) { + return _a = {}, _a[MessageParameter.TYPE_OF_MSG] = msgType, _a[MessageParameter.DATA] = msgData, _a; + var _a; +} + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var DEFAULT_SW_PATH = '/firebase-messaging-sw.js'; +var DEFAULT_SW_SCOPE = '/firebase-cloud-messaging-push-scope'; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var WindowController = /** @class */ (function (_super) { + tslib_1.__extends(WindowController, _super); + /** + * A service that provides a MessagingService instance. + */ + function WindowController(app) { + var _this = _super.call(this, app) || this; + _this.registrationToUse = null; + _this.publicVapidKeyToUse = null; + _this.manifestCheckPromise = null; + _this.messageObserver = null; + // @ts-ignore: Unused variable error, this is not implemented yet. + _this.tokenRefreshObserver = null; + _this.onMessageInternal = util.createSubscribe(function (observer) { + _this.messageObserver = observer; + }); + _this.onTokenRefreshInternal = util.createSubscribe(function (observer) { + _this.tokenRefreshObserver = observer; + }); + _this.setupSWMessageListener_(); + return _this; + } + /** + * This method returns an FCM token if it can be generated. + * The return promise will reject if the browser doesn't support + * FCM, if permission is denied for notifications or it's not + * possible to generate a token. + * + * @return Returns a promise that resolves to an FCM token or null if + * permission isn't granted. + */ + WindowController.prototype.getToken = function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + if (!this.manifestCheckPromise) { + this.manifestCheckPromise = manifestCheck(); + } + return [4 /*yield*/, this.manifestCheckPromise]; + case 1: + _a.sent(); + return [2 /*return*/, _super.prototype.getToken.call(this)]; + } + }); + }); + }; + /** + * Request permission if it is not currently granted + * + * @return Resolves if the permission was granted, otherwise rejects + */ + WindowController.prototype.requestPermission = function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var permissionResult; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + if (this.getNotificationPermission_() === 'granted') { + return [2 /*return*/]; + } + return [4 /*yield*/, Notification.requestPermission()]; + case 1: + permissionResult = _a.sent(); + if (permissionResult === 'granted') { + return [2 /*return*/]; + } + else if (permissionResult === 'denied') { + throw errorFactory.create(ERROR_CODES.PERMISSION_BLOCKED); + } + else { + throw errorFactory.create(ERROR_CODES.PERMISSION_DEFAULT); + } + return [2 /*return*/]; + } + }); + }); + }; + /** + * This method allows a developer to override the default service worker and + * instead use a custom service worker. + * + * @param registration The service worker registration that should be used to + * receive the push messages. + */ + WindowController.prototype.useServiceWorker = function (registration) { + if (!(registration instanceof ServiceWorkerRegistration)) { + throw errorFactory.create(ERROR_CODES.SW_REGISTRATION_EXPECTED); + } + if (this.registrationToUse != null) { + throw errorFactory.create(ERROR_CODES.USE_SW_BEFORE_GET_TOKEN); + } + this.registrationToUse = registration; + }; + /** + * This method allows a developer to override the default vapid key + * and instead use a custom VAPID public key. + * + * @param publicKey A URL safe base64 encoded string. + */ + WindowController.prototype.usePublicVapidKey = function (publicKey) { + if (typeof publicKey !== 'string') { + throw errorFactory.create(ERROR_CODES.INVALID_PUBLIC_VAPID_KEY); + } + if (this.publicVapidKeyToUse != null) { + throw errorFactory.create(ERROR_CODES.USE_PUBLIC_KEY_BEFORE_GET_TOKEN); + } + var parsedKey = base64ToArrayBuffer(publicKey); + if (parsedKey.length !== 65) { + throw errorFactory.create(ERROR_CODES.PUBLIC_KEY_DECRYPTION_FAILED); + } + this.publicVapidKeyToUse = parsedKey; + }; + /** + * @export + * @param nextOrObserver An observer object or a function triggered on + * message. + * @param error A function triggered on message error. + * @param completed function triggered when the observer is removed. + * @return The unsubscribe function for the observer. + */ + WindowController.prototype.onMessage = function (nextOrObserver, error, completed) { + if (typeof nextOrObserver === 'function') { + return this.onMessageInternal(nextOrObserver, error, completed); + } + else { + return this.onMessageInternal(nextOrObserver); + } + }; + /** + * @param nextOrObserver An observer object or a function triggered on token + * refresh. + * @param error A function triggered on token refresh error. + * @param completed function triggered when the observer is removed. + * @return The unsubscribe function for the observer. + */ + WindowController.prototype.onTokenRefresh = function (nextOrObserver, error, completed) { + if (typeof nextOrObserver === 'function') { + return this.onTokenRefreshInternal(nextOrObserver, error, completed); + } + else { + return this.onTokenRefreshInternal(nextOrObserver); + } + }; + /** + * Given a registration, wait for the service worker it relates to + * become activer + * @param registration Registration to wait for service worker to become active + * @return Wait for service worker registration to become active + */ + // Visible for testing + // TODO: Make private + WindowController.prototype.waitForRegistrationToActivate_ = function (registration) { + var serviceWorker = registration.installing || registration.waiting || registration.active; + return new Promise(function (resolve, reject) { + if (!serviceWorker) { + // This is a rare scenario but has occured in firefox + reject(errorFactory.create(ERROR_CODES.NO_SW_IN_REG)); + return; + } + // Because the Promise function is called on next tick there is a + // small chance that the worker became active or redundant already. + if (serviceWorker.state === 'activated') { + resolve(registration); + return; + } + if (serviceWorker.state === 'redundant') { + reject(errorFactory.create(ERROR_CODES.SW_REG_REDUNDANT)); + return; + } + var stateChangeListener = function () { + if (serviceWorker.state === 'activated') { + resolve(registration); + } + else if (serviceWorker.state === 'redundant') { + reject(errorFactory.create(ERROR_CODES.SW_REG_REDUNDANT)); + } + else { + // Return early and wait to next state change + return; + } + serviceWorker.removeEventListener('statechange', stateChangeListener); + }; + serviceWorker.addEventListener('statechange', stateChangeListener); + }); + }; + /** + * This will register the default service worker and return the registration + * @return The service worker registration to be used for the push service. + */ + WindowController.prototype.getSWRegistration_ = function () { + var _this = this; + if (this.registrationToUse) { + return this.waitForRegistrationToActivate_(this.registrationToUse); + } + // Make the registration null so we know useServiceWorker will not + // use a new service worker as registrationToUse is no longer undefined + this.registrationToUse = null; + return navigator.serviceWorker + .register(DEFAULT_SW_PATH, { + scope: DEFAULT_SW_SCOPE + }) + .catch(function (err) { + throw errorFactory.create(ERROR_CODES.FAILED_DEFAULT_REGISTRATION, { + browserErrorMessage: err.message + }); + }) + .then(function (registration) { + return _this.waitForRegistrationToActivate_(registration).then(function () { + _this.registrationToUse = registration; + // We update after activation due to an issue with Firefox v49 where + // a race condition occassionally causes the service work to not + // install + registration.update(); + return registration; + }); + }); + }; + /** + * This will return the default VAPID key or the uint8array version of the public VAPID key + * provided by the developer. + */ + WindowController.prototype.getPublicVapidKey_ = function () { + return tslib_1.__awaiter(this, void 0, void 0, function () { + return tslib_1.__generator(this, function (_a) { + if (this.publicVapidKeyToUse) { + return [2 /*return*/, this.publicVapidKeyToUse]; + } + return [2 /*return*/, DEFAULT_PUBLIC_VAPID_KEY]; + }); + }); + }; + /** + * This method will set up a message listener to handle + * events from the service worker that should trigger + * events in the page. + */ + // Visible for testing + // TODO: Make private + WindowController.prototype.setupSWMessageListener_ = function () { + var _this = this; + navigator.serviceWorker.addEventListener('message', function (event) { + if (!event.data || !event.data[MessageParameter.TYPE_OF_MSG]) { + // Not a message from FCM + return; + } + var workerPageMessage = event.data; + switch (workerPageMessage[MessageParameter.TYPE_OF_MSG]) { + case MessageType.PUSH_MSG_RECEIVED: + case MessageType.NOTIFICATION_CLICKED: + var pushMessage = workerPageMessage[MessageParameter.DATA]; + if (_this.messageObserver) { + _this.messageObserver.next(pushMessage); + } + break; + default: + // Noop. + break; + } + }, false); + }; + return WindowController; +}(BaseController)); +/** + * The method checks that a manifest is defined and has the correct GCM + * sender ID. + * @return Returns a promise that resolves if the manifest matches + * our required sender ID + */ +// Exported for testing +function manifestCheck() { + return tslib_1.__awaiter(this, void 0, void 0, function () { + var manifestTag, manifestContent, response, e_1; + return tslib_1.__generator(this, function (_a) { + switch (_a.label) { + case 0: + manifestTag = document.querySelector('link[rel="manifest"]'); + if (!manifestTag) { + return [2 /*return*/]; + } + _a.label = 1; + case 1: + _a.trys.push([1, 4, , 5]); + return [4 /*yield*/, fetch(manifestTag.href)]; + case 2: + response = _a.sent(); + return [4 /*yield*/, response.json()]; + case 3: + manifestContent = _a.sent(); + return [3 /*break*/, 5]; + case 4: + e_1 = _a.sent(); + // If the download or parsing fails allow check. + // We only want to error if we KNOW that the gcm_sender_id is incorrect. + return [2 /*return*/]; + case 5: + if (!manifestContent || !manifestContent.gcm_sender_id) { + return [2 /*return*/]; + } + if (manifestContent.gcm_sender_id !== '103953800507') { + throw errorFactory.create(ERROR_CODES.INCORRECT_GCM_SENDER_ID); + } + return [2 /*return*/]; + } + }); + }); +} + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +function registerMessaging(instance) { + var messagingName = 'messaging'; + var factoryMethod = function (app) { + if (!isSupported()) { + throw errorFactory.create(ERROR_CODES.UNSUPPORTED_BROWSER); + } + if (self && 'ServiceWorkerGlobalScope' in self) { + // Running in ServiceWorker context + return new SwController(app); + } + else { + // Assume we are in the window context. + return new WindowController(app); + } + }; + var namespaceExports = { + isSupported: isSupported + }; + instance.INTERNAL.registerService(messagingName, factoryMethod, namespaceExports); +} +registerMessaging(firebase); +function isSupported() { + if (self && 'ServiceWorkerGlobalScope' in self) { + // Running in ServiceWorker context + return isSWControllerSupported(); + } + else { + // Assume we are in the window context. + return isWindowControllerSupported(); + } +} +/** + * Checks to see if the required APIs exist. + */ +function isWindowControllerSupported() { + return (navigator.cookieEnabled && + 'serviceWorker' in navigator && + 'PushManager' in window && + 'Notification' in window && + 'fetch' in window && + ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') && + PushSubscription.prototype.hasOwnProperty('getKey')); +} +/** + * Checks to see if the required APIs exist within SW Context. + */ +function isSWControllerSupported() { + return ('PushManager' in self && + 'Notification' in self && + ServiceWorkerRegistration.prototype.hasOwnProperty('showNotification') && + PushSubscription.prototype.hasOwnProperty('getKey')); +} + +exports.registerMessaging = registerMessaging; +exports.isSupported = isSupported; + +},{"@firebase/app":1,"@firebase/util":4,"tslib":31}],3:[function(require,module,exports){ +(function (global,setImmediate){ +'use strict'; + +require('whatwg-fetch'); + +// Store setTimeout reference so promise-polyfill will be unaffected by +// other code modifying setTimeout (like sinon.useFakeTimers()) +var setTimeoutFunc = setTimeout; + +function noop() {} + +// Polyfill for Function.prototype.bind +function bind(fn, thisArg) { + return function() { + fn.apply(thisArg, arguments); + }; +} + +function Promise(fn) { + if (!(this instanceof Promise)) + throw new TypeError('Promises must be constructed via new'); + if (typeof fn !== 'function') throw new TypeError('not a function'); + this._state = 0; + this._handled = false; + this._value = undefined; + this._deferreds = []; + + doResolve(fn, this); +} + +function handle(self, deferred) { + while (self._state === 3) { + self = self._value; + } + if (self._state === 0) { + self._deferreds.push(deferred); + return; + } + self._handled = true; + Promise._immediateFn(function() { + var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected; + if (cb === null) { + (self._state === 1 ? resolve : reject)(deferred.promise, self._value); + return; + } + var ret; + try { + ret = cb(self._value); + } catch (e) { + reject(deferred.promise, e); + return; + } + resolve(deferred.promise, ret); + }); +} + +function resolve(self, newValue) { + try { + // Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure + if (newValue === self) + throw new TypeError('A promise cannot be resolved with itself.'); + if ( + newValue && + (typeof newValue === 'object' || typeof newValue === 'function') + ) { + var then = newValue.then; + if (newValue instanceof Promise) { + self._state = 3; + self._value = newValue; + finale(self); + return; + } else if (typeof then === 'function') { + doResolve(bind(then, newValue), self); + return; + } + } + self._state = 1; + self._value = newValue; + finale(self); + } catch (e) { + reject(self, e); + } +} + +function reject(self, newValue) { + self._state = 2; + self._value = newValue; + finale(self); +} + +function finale(self) { + if (self._state === 2 && self._deferreds.length === 0) { + Promise._immediateFn(function() { + if (!self._handled) { + Promise._unhandledRejectionFn(self._value); + } + }); + } + + for (var i = 0, len = self._deferreds.length; i < len; i++) { + handle(self, self._deferreds[i]); + } + self._deferreds = null; +} + +function Handler(onFulfilled, onRejected, promise) { + this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null; + this.onRejected = typeof onRejected === 'function' ? onRejected : null; + this.promise = promise; +} + +/** + * Take a potentially misbehaving resolver function and make sure + * onFulfilled and onRejected are only called once. + * + * Makes no guarantees about asynchrony. + */ +function doResolve(fn, self) { + var done = false; + try { + fn( + function(value) { + if (done) return; + done = true; + resolve(self, value); + }, + function(reason) { + if (done) return; + done = true; + reject(self, reason); + } + ); + } catch (ex) { + if (done) return; + done = true; + reject(self, ex); + } +} + +Promise.prototype['catch'] = function(onRejected) { + return this.then(null, onRejected); +}; + +Promise.prototype.then = function(onFulfilled, onRejected) { + var prom = new this.constructor(noop); + + handle(this, new Handler(onFulfilled, onRejected, prom)); + return prom; +}; + +Promise.prototype['finally'] = function(callback) { + var constructor = this.constructor; + return this.then( + function(value) { + return constructor.resolve(callback()).then(function() { + return value; + }); + }, + function(reason) { + return constructor.resolve(callback()).then(function() { + return constructor.reject(reason); + }); + } + ); +}; + +Promise.all = function(arr) { + return new Promise(function(resolve, reject) { + if (!arr || typeof arr.length === 'undefined') + throw new TypeError('Promise.all accepts an array'); + var args = Array.prototype.slice.call(arr); + if (args.length === 0) return resolve([]); + var remaining = args.length; + + function res(i, val) { + try { + if (val && (typeof val === 'object' || typeof val === 'function')) { + var then = val.then; + if (typeof then === 'function') { + then.call( + val, + function(val) { + res(i, val); + }, + reject + ); + return; + } + } + args[i] = val; + if (--remaining === 0) { + resolve(args); + } + } catch (ex) { + reject(ex); + } + } + + for (var i = 0; i < args.length; i++) { + res(i, args[i]); + } + }); +}; + +Promise.resolve = function(value) { + if (value && typeof value === 'object' && value.constructor === Promise) { + return value; + } + + return new Promise(function(resolve) { + resolve(value); + }); +}; + +Promise.reject = function(value) { + return new Promise(function(resolve, reject) { + reject(value); + }); +}; + +Promise.race = function(values) { + return new Promise(function(resolve, reject) { + for (var i = 0, len = values.length; i < len; i++) { + values[i].then(resolve, reject); + } + }); +}; + +// Use polyfill for setImmediate for performance gains +Promise._immediateFn = + (typeof setImmediate === 'function' && + function(fn) { + setImmediate(fn); + }) || + function(fn) { + setTimeoutFunc(fn, 0); + }; + +Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) { + if (typeof console !== 'undefined' && console) { + console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console + } +}; + +var globalNS = (function() { + // the only reliable means to get the global object is + // `Function('return this')()` + // However, this causes CSP violations in Chrome apps. + if (typeof self !== 'undefined') { + return self; + } + if (typeof window !== 'undefined') { + return window; + } + if (typeof global !== 'undefined') { + return global; + } + throw new Error('unable to locate global object'); +})(); + +if (!globalNS.Promise) { + globalNS.Promise = Promise; +} + +function createCommonjsModule(fn, module) { + return module = { exports: {} }, fn(module, module.exports), module.exports; +} + +var _global = createCommonjsModule(function (module) { +// https://github.com/zloirock/core-js/issues/86#issuecomment-115759028 +var global = module.exports = typeof window != 'undefined' && window.Math == Math + ? window : typeof self != 'undefined' && self.Math == Math ? self + // eslint-disable-next-line no-new-func + : Function('return this')(); +if (typeof __g == 'number') __g = global; // eslint-disable-line no-undef +}); + +var _core = createCommonjsModule(function (module) { +var core = module.exports = { version: '2.5.5' }; +if (typeof __e == 'number') __e = core; // eslint-disable-line no-undef +}); +var _core_1 = _core.version; + +var _isObject = function (it) { + return typeof it === 'object' ? it !== null : typeof it === 'function'; +}; + +var _anObject = function (it) { + if (!_isObject(it)) throw TypeError(it + ' is not an object!'); + return it; +}; + +var _fails = function (exec) { + try { + return !!exec(); + } catch (e) { + return true; + } +}; + +// Thank's IE8 for his funny defineProperty +var _descriptors = !_fails(function () { + return Object.defineProperty({}, 'a', { get: function () { return 7; } }).a != 7; +}); + +var document = _global.document; +// typeof document.createElement is 'object' in old IE +var is = _isObject(document) && _isObject(document.createElement); +var _domCreate = function (it) { + return is ? document.createElement(it) : {}; +}; + +var _ie8DomDefine = !_descriptors && !_fails(function () { + return Object.defineProperty(_domCreate('div'), 'a', { get: function () { return 7; } }).a != 7; +}); + +// 7.1.1 ToPrimitive(input [, PreferredType]) + +// instead of the ES6 spec version, we didn't implement @@toPrimitive case +// and the second argument - flag - preferred type is a string +var _toPrimitive = function (it, S) { + if (!_isObject(it)) return it; + var fn, val; + if (S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val; + if (typeof (fn = it.valueOf) == 'function' && !_isObject(val = fn.call(it))) return val; + if (!S && typeof (fn = it.toString) == 'function' && !_isObject(val = fn.call(it))) return val; + throw TypeError("Can't convert object to primitive value"); +}; + +var dP = Object.defineProperty; + +var f = _descriptors ? Object.defineProperty : function defineProperty(O, P, Attributes) { + _anObject(O); + P = _toPrimitive(P, true); + _anObject(Attributes); + if (_ie8DomDefine) try { + return dP(O, P, Attributes); + } catch (e) { /* empty */ } + if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!'); + if ('value' in Attributes) O[P] = Attributes.value; + return O; +}; + +var _objectDp = { + f: f +}; + +var _propertyDesc = function (bitmap, value) { + return { + enumerable: !(bitmap & 1), + configurable: !(bitmap & 2), + writable: !(bitmap & 4), + value: value + }; +}; + +var _hide = _descriptors ? function (object, key, value) { + return _objectDp.f(object, key, _propertyDesc(1, value)); +} : function (object, key, value) { + object[key] = value; + return object; +}; + +var hasOwnProperty = {}.hasOwnProperty; +var _has = function (it, key) { + return hasOwnProperty.call(it, key); +}; + +var id = 0; +var px = Math.random(); +var _uid = function (key) { + return 'Symbol('.concat(key === undefined ? '' : key, ')_', (++id + px).toString(36)); +}; + +var _redefine = createCommonjsModule(function (module) { +var SRC = _uid('src'); +var TO_STRING = 'toString'; +var $toString = Function[TO_STRING]; +var TPL = ('' + $toString).split(TO_STRING); + +_core.inspectSource = function (it) { + return $toString.call(it); +}; + +(module.exports = function (O, key, val, safe) { + var isFunction = typeof val == 'function'; + if (isFunction) _has(val, 'name') || _hide(val, 'name', key); + if (O[key] === val) return; + if (isFunction) _has(val, SRC) || _hide(val, SRC, O[key] ? '' + O[key] : TPL.join(String(key))); + if (O === _global) { + O[key] = val; + } else if (!safe) { + delete O[key]; + _hide(O, key, val); + } else if (O[key]) { + O[key] = val; + } else { + _hide(O, key, val); + } +// add fake Function#toString for correct work wrapped methods / constructors with methods like LoDash isNative +})(Function.prototype, TO_STRING, function toString() { + return typeof this == 'function' && this[SRC] || $toString.call(this); +}); +}); + +var _aFunction = function (it) { + if (typeof it != 'function') throw TypeError(it + ' is not a function!'); + return it; +}; + +// optional / simple context binding + +var _ctx = function (fn, that, length) { + _aFunction(fn); + if (that === undefined) return fn; + switch (length) { + case 1: return function (a) { + return fn.call(that, a); + }; + case 2: return function (a, b) { + return fn.call(that, a, b); + }; + case 3: return function (a, b, c) { + return fn.call(that, a, b, c); + }; + } + return function (/* ...args */) { + return fn.apply(that, arguments); + }; +}; + +var PROTOTYPE = 'prototype'; + +var $export = function (type, name, source) { + var IS_FORCED = type & $export.F; + var IS_GLOBAL = type & $export.G; + var IS_STATIC = type & $export.S; + var IS_PROTO = type & $export.P; + var IS_BIND = type & $export.B; + var target = IS_GLOBAL ? _global : IS_STATIC ? _global[name] || (_global[name] = {}) : (_global[name] || {})[PROTOTYPE]; + var exports = IS_GLOBAL ? _core : _core[name] || (_core[name] = {}); + var expProto = exports[PROTOTYPE] || (exports[PROTOTYPE] = {}); + var key, own, out, exp; + if (IS_GLOBAL) source = name; + for (key in source) { + // contains in native + own = !IS_FORCED && target && target[key] !== undefined; + // export native or passed + out = (own ? target : source)[key]; + // bind timers to global for call from export context + exp = IS_BIND && own ? _ctx(out, _global) : IS_PROTO && typeof out == 'function' ? _ctx(Function.call, out) : out; + // extend global + if (target) _redefine(target, key, out, type & $export.U); + // export + if (exports[key] != out) _hide(exports, key, exp); + if (IS_PROTO && expProto[key] != out) expProto[key] = out; + } +}; +_global.core = _core; +// type bitmap +$export.F = 1; // forced +$export.G = 2; // global +$export.S = 4; // static +$export.P = 8; // proto +$export.B = 16; // bind +$export.W = 32; // wrap +$export.U = 64; // safe +$export.R = 128; // real proto method for `library` +var _export = $export; + +var toString = {}.toString; + +var _cof = function (it) { + return toString.call(it).slice(8, -1); +}; + +// fallback for non-array-like ES3 and non-enumerable old V8 strings + +// eslint-disable-next-line no-prototype-builtins +var _iobject = Object('z').propertyIsEnumerable(0) ? Object : function (it) { + return _cof(it) == 'String' ? it.split('') : Object(it); +}; + +// 7.2.1 RequireObjectCoercible(argument) +var _defined = function (it) { + if (it == undefined) throw TypeError("Can't call method on " + it); + return it; +}; + +// 7.1.13 ToObject(argument) + +var _toObject = function (it) { + return Object(_defined(it)); +}; + +// 7.1.4 ToInteger +var ceil = Math.ceil; +var floor = Math.floor; +var _toInteger = function (it) { + return isNaN(it = +it) ? 0 : (it > 0 ? floor : ceil)(it); +}; + +// 7.1.15 ToLength + +var min = Math.min; +var _toLength = function (it) { + return it > 0 ? min(_toInteger(it), 0x1fffffffffffff) : 0; // pow(2, 53) - 1 == 9007199254740991 +}; + +// 7.2.2 IsArray(argument) + +var _isArray = Array.isArray || function isArray(arg) { + return _cof(arg) == 'Array'; +}; + +var SHARED = '__core-js_shared__'; +var store = _global[SHARED] || (_global[SHARED] = {}); +var _shared = function (key) { + return store[key] || (store[key] = {}); +}; + +var _wks = createCommonjsModule(function (module) { +var store = _shared('wks'); + +var Symbol = _global.Symbol; +var USE_SYMBOL = typeof Symbol == 'function'; + +var $exports = module.exports = function (name) { + return store[name] || (store[name] = + USE_SYMBOL && Symbol[name] || (USE_SYMBOL ? Symbol : _uid)('Symbol.' + name)); +}; + +$exports.store = store; +}); + +var SPECIES = _wks('species'); + +var _arraySpeciesConstructor = function (original) { + var C; + if (_isArray(original)) { + C = original.constructor; + // cross-realm fallback + if (typeof C == 'function' && (C === Array || _isArray(C.prototype))) C = undefined; + if (_isObject(C)) { + C = C[SPECIES]; + if (C === null) C = undefined; + } + } return C === undefined ? Array : C; +}; + +// 9.4.2.3 ArraySpeciesCreate(originalArray, length) + + +var _arraySpeciesCreate = function (original, length) { + return new (_arraySpeciesConstructor(original))(length); +}; + +// 0 -> Array#forEach +// 1 -> Array#map +// 2 -> Array#filter +// 3 -> Array#some +// 4 -> Array#every +// 5 -> Array#find +// 6 -> Array#findIndex + + + + + +var _arrayMethods = function (TYPE, $create) { + var IS_MAP = TYPE == 1; + var IS_FILTER = TYPE == 2; + var IS_SOME = TYPE == 3; + var IS_EVERY = TYPE == 4; + var IS_FIND_INDEX = TYPE == 6; + var NO_HOLES = TYPE == 5 || IS_FIND_INDEX; + var create = $create || _arraySpeciesCreate; + return function ($this, callbackfn, that) { + var O = _toObject($this); + var self = _iobject(O); + var f = _ctx(callbackfn, that, 3); + var length = _toLength(self.length); + var index = 0; + var result = IS_MAP ? create($this, length) : IS_FILTER ? create($this, 0) : undefined; + var val, res; + for (;length > index; index++) if (NO_HOLES || index in self) { + val = self[index]; + res = f(val, index, O); + if (TYPE) { + if (IS_MAP) result[index] = res; // map + else if (res) switch (TYPE) { + case 3: return true; // some + case 5: return val; // find + case 6: return index; // findIndex + case 2: result.push(val); // filter + } else if (IS_EVERY) return false; // every + } + } + return IS_FIND_INDEX ? -1 : IS_SOME || IS_EVERY ? IS_EVERY : result; + }; +}; + +// 22.1.3.31 Array.prototype[@@unscopables] +var UNSCOPABLES = _wks('unscopables'); +var ArrayProto = Array.prototype; +if (ArrayProto[UNSCOPABLES] == undefined) _hide(ArrayProto, UNSCOPABLES, {}); +var _addToUnscopables = function (key) { + ArrayProto[UNSCOPABLES][key] = true; +}; + +// 22.1.3.8 Array.prototype.find(predicate, thisArg = undefined) + +var $find = _arrayMethods(5); +var KEY = 'find'; +var forced = true; +// Shouldn't skip holes +if (KEY in []) Array(1)[KEY](function () { forced = false; }); +_export(_export.P + _export.F * forced, 'Array', { + find: function find(callbackfn /* , that = undefined */) { + return $find(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); +_addToUnscopables(KEY); + +var find = _core.Array.find; + +// 22.1.3.9 Array.prototype.findIndex(predicate, thisArg = undefined) + +var $find$1 = _arrayMethods(6); +var KEY$1 = 'findIndex'; +var forced$1 = true; +// Shouldn't skip holes +if (KEY$1 in []) Array(1)[KEY$1](function () { forced$1 = false; }); +_export(_export.P + _export.F * forced$1, 'Array', { + findIndex: function findIndex(callbackfn /* , that = undefined */) { + return $find$1(this, callbackfn, arguments.length > 1 ? arguments[1] : undefined); + } +}); +_addToUnscopables(KEY$1); + +var findIndex = _core.Array.findIndex; + +// to indexed object, toObject with fallback for non-array-like ES3 strings + + +var _toIobject = function (it) { + return _iobject(_defined(it)); +}; + +var max = Math.max; +var min$1 = Math.min; +var _toAbsoluteIndex = function (index, length) { + index = _toInteger(index); + return index < 0 ? max(index + length, 0) : min$1(index, length); +}; + +// false -> Array#indexOf +// true -> Array#includes + + + +var _arrayIncludes = function (IS_INCLUDES) { + return function ($this, el, fromIndex) { + var O = _toIobject($this); + var length = _toLength(O.length); + var index = _toAbsoluteIndex(fromIndex, length); + var value; + // Array#includes uses SameValueZero equality algorithm + // eslint-disable-next-line no-self-compare + if (IS_INCLUDES && el != el) while (length > index) { + value = O[index++]; + // eslint-disable-next-line no-self-compare + if (value != value) return true; + // Array#indexOf ignores holes, Array#includes - not + } else for (;length > index; index++) if (IS_INCLUDES || index in O) { + if (O[index] === el) return IS_INCLUDES || index || 0; + } return !IS_INCLUDES && -1; + }; +}; + +var shared = _shared('keys'); + +var _sharedKey = function (key) { + return shared[key] || (shared[key] = _uid(key)); +}; + +var arrayIndexOf = _arrayIncludes(false); +var IE_PROTO = _sharedKey('IE_PROTO'); + +var _objectKeysInternal = function (object, names) { + var O = _toIobject(object); + var i = 0; + var result = []; + var key; + for (key in O) if (key != IE_PROTO) _has(O, key) && result.push(key); + // Don't enum bug & hidden keys + while (names.length > i) if (_has(O, key = names[i++])) { + ~arrayIndexOf(result, key) || result.push(key); + } + return result; +}; + +// IE 8- don't enum bug keys +var _enumBugKeys = ( + 'constructor,hasOwnProperty,isPrototypeOf,propertyIsEnumerable,toLocaleString,toString,valueOf' +).split(','); + +// 19.1.2.14 / 15.2.3.14 Object.keys(O) + + + +var _objectKeys = Object.keys || function keys(O) { + return _objectKeysInternal(O, _enumBugKeys); +}; + +var f$1 = Object.getOwnPropertySymbols; + +var _objectGops = { + f: f$1 +}; + +var f$2 = {}.propertyIsEnumerable; + +var _objectPie = { + f: f$2 +}; + +// 19.1.2.1 Object.assign(target, source, ...) + + + + + +var $assign = Object.assign; + +// should work with symbols and should have deterministic property order (V8 bug) +var _objectAssign = !$assign || _fails(function () { + var A = {}; + var B = {}; + // eslint-disable-next-line no-undef + var S = Symbol(); + var K = 'abcdefghijklmnopqrst'; + A[S] = 7; + K.split('').forEach(function (k) { B[k] = k; }); + return $assign({}, A)[S] != 7 || Object.keys($assign({}, B)).join('') != K; +}) ? function assign(target, source) { // eslint-disable-line no-unused-vars + var T = _toObject(target); + var aLen = arguments.length; + var index = 1; + var getSymbols = _objectGops.f; + var isEnum = _objectPie.f; + while (aLen > index) { + var S = _iobject(arguments[index++]); + var keys = getSymbols ? _objectKeys(S).concat(getSymbols(S)) : _objectKeys(S); + var length = keys.length; + var j = 0; + var key; + while (length > j) if (isEnum.call(S, key = keys[j++])) T[key] = S[key]; + } return T; +} : $assign; + +// 19.1.3.1 Object.assign(target, source) + + +_export(_export.S + _export.F, 'Object', { assign: _objectAssign }); + +var assign = _core.Object.assign; + +// 7.2.8 IsRegExp(argument) + + +var MATCH = _wks('match'); +var _isRegexp = function (it) { + var isRegExp; + return _isObject(it) && ((isRegExp = it[MATCH]) !== undefined ? !!isRegExp : _cof(it) == 'RegExp'); +}; + +// helper for String#{startsWith, endsWith, includes} + + + +var _stringContext = function (that, searchString, NAME) { + if (_isRegexp(searchString)) throw TypeError('String#' + NAME + " doesn't accept regex!"); + return String(_defined(that)); +}; + +var MATCH$1 = _wks('match'); +var _failsIsRegexp = function (KEY) { + var re = /./; + try { + '/./'[KEY](re); + } catch (e) { + try { + re[MATCH$1] = false; + return !'/./'[KEY](re); + } catch (f) { /* empty */ } + } return true; +}; + +var STARTS_WITH = 'startsWith'; +var $startsWith = ''[STARTS_WITH]; + +_export(_export.P + _export.F * _failsIsRegexp(STARTS_WITH), 'String', { + startsWith: function startsWith(searchString /* , position = 0 */) { + var that = _stringContext(this, searchString, STARTS_WITH); + var index = _toLength(Math.min(arguments.length > 1 ? arguments[1] : undefined, that.length)); + var search = String(searchString); + return $startsWith + ? $startsWith.call(that, search, index) + : that.slice(index, index + search.length) === search; + } +}); + +var startsWith = _core.String.startsWith; + +var _stringRepeat = function repeat(count) { + var str = String(_defined(this)); + var res = ''; + var n = _toInteger(count); + if (n < 0 || n == Infinity) throw RangeError("Count can't be negative"); + for (;n > 0; (n >>>= 1) && (str += str)) if (n & 1) res += str; + return res; +}; + +_export(_export.P, 'String', { + // 21.1.3.13 String.prototype.repeat(count) + repeat: _stringRepeat +}); + +var repeat = _core.String.repeat; + +var _meta = createCommonjsModule(function (module) { +var META = _uid('meta'); + + +var setDesc = _objectDp.f; +var id = 0; +var isExtensible = Object.isExtensible || function () { + return true; +}; +var FREEZE = !_fails(function () { + return isExtensible(Object.preventExtensions({})); +}); +var setMeta = function (it) { + setDesc(it, META, { value: { + i: 'O' + ++id, // object ID + w: {} // weak collections IDs + } }); +}; +var fastKey = function (it, create) { + // return primitive with prefix + if (!_isObject(it)) return typeof it == 'symbol' ? it : (typeof it == 'string' ? 'S' : 'P') + it; + if (!_has(it, META)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return 'F'; + // not necessary to add metadata + if (!create) return 'E'; + // add missing metadata + setMeta(it); + // return object ID + } return it[META].i; +}; +var getWeak = function (it, create) { + if (!_has(it, META)) { + // can't set metadata to uncaught frozen object + if (!isExtensible(it)) return true; + // not necessary to add metadata + if (!create) return false; + // add missing metadata + setMeta(it); + // return hash weak collections IDs + } return it[META].w; +}; +// add metadata on freeze-family methods calling +var onFreeze = function (it) { + if (FREEZE && meta.NEED && isExtensible(it) && !_has(it, META)) setMeta(it); + return it; +}; +var meta = module.exports = { + KEY: META, + NEED: false, + fastKey: fastKey, + getWeak: getWeak, + onFreeze: onFreeze +}; +}); +var _meta_1 = _meta.KEY; +var _meta_2 = _meta.NEED; +var _meta_3 = _meta.fastKey; +var _meta_4 = _meta.getWeak; +var _meta_5 = _meta.onFreeze; + +var def = _objectDp.f; + +var TAG = _wks('toStringTag'); + +var _setToStringTag = function (it, tag, stat) { + if (it && !_has(it = stat ? it : it.prototype, TAG)) def(it, TAG, { configurable: true, value: tag }); +}; + +var f$3 = _wks; + +var _wksExt = { + f: f$3 +}; + +var _library = false; + +var defineProperty = _objectDp.f; +var _wksDefine = function (name) { + var $Symbol = _core.Symbol || (_core.Symbol = _library ? {} : _global.Symbol || {}); + if (name.charAt(0) != '_' && !(name in $Symbol)) defineProperty($Symbol, name, { value: _wksExt.f(name) }); +}; + +// all enumerable object keys, includes symbols + + + +var _enumKeys = function (it) { + var result = _objectKeys(it); + var getSymbols = _objectGops.f; + if (getSymbols) { + var symbols = getSymbols(it); + var isEnum = _objectPie.f; + var i = 0; + var key; + while (symbols.length > i) if (isEnum.call(it, key = symbols[i++])) result.push(key); + } return result; +}; + +var _objectDps = _descriptors ? Object.defineProperties : function defineProperties(O, Properties) { + _anObject(O); + var keys = _objectKeys(Properties); + var length = keys.length; + var i = 0; + var P; + while (length > i) _objectDp.f(O, P = keys[i++], Properties[P]); + return O; +}; + +var document$1 = _global.document; +var _html = document$1 && document$1.documentElement; + +// 19.1.2.2 / 15.2.3.5 Object.create(O [, Properties]) + + + +var IE_PROTO$1 = _sharedKey('IE_PROTO'); +var Empty = function () { /* empty */ }; +var PROTOTYPE$1 = 'prototype'; + +// Create object with fake `null` prototype: use iframe Object with cleared prototype +var createDict = function () { + // Thrash, waste and sodomy: IE GC bug + var iframe = _domCreate('iframe'); + var i = _enumBugKeys.length; + var lt = '<'; + var gt = '>'; + var iframeDocument; + iframe.style.display = 'none'; + _html.appendChild(iframe); + iframe.src = 'javascript:'; // eslint-disable-line no-script-url + // createDict = iframe.contentWindow.Object; + // html.removeChild(iframe); + iframeDocument = iframe.contentWindow.document; + iframeDocument.open(); + iframeDocument.write(lt + 'script' + gt + 'document.F=Object' + lt + '/script' + gt); + iframeDocument.close(); + createDict = iframeDocument.F; + while (i--) delete createDict[PROTOTYPE$1][_enumBugKeys[i]]; + return createDict(); +}; + +var _objectCreate = Object.create || function create(O, Properties) { + var result; + if (O !== null) { + Empty[PROTOTYPE$1] = _anObject(O); + result = new Empty(); + Empty[PROTOTYPE$1] = null; + // add "__proto__" for Object.getPrototypeOf polyfill + result[IE_PROTO$1] = O; + } else result = createDict(); + return Properties === undefined ? result : _objectDps(result, Properties); +}; + +// 19.1.2.7 / 15.2.3.4 Object.getOwnPropertyNames(O) + +var hiddenKeys = _enumBugKeys.concat('length', 'prototype'); + +var f$4 = Object.getOwnPropertyNames || function getOwnPropertyNames(O) { + return _objectKeysInternal(O, hiddenKeys); +}; + +var _objectGopn = { + f: f$4 +}; + +// fallback for IE11 buggy Object.getOwnPropertyNames with iframe and window + +var gOPN = _objectGopn.f; +var toString$1 = {}.toString; + +var windowNames = typeof window == 'object' && window && Object.getOwnPropertyNames + ? Object.getOwnPropertyNames(window) : []; + +var getWindowNames = function (it) { + try { + return gOPN(it); + } catch (e) { + return windowNames.slice(); + } +}; + +var f$5 = function getOwnPropertyNames(it) { + return windowNames && toString$1.call(it) == '[object Window]' ? getWindowNames(it) : gOPN(_toIobject(it)); +}; + +var _objectGopnExt = { + f: f$5 +}; + +var gOPD = Object.getOwnPropertyDescriptor; + +var f$6 = _descriptors ? gOPD : function getOwnPropertyDescriptor(O, P) { + O = _toIobject(O); + P = _toPrimitive(P, true); + if (_ie8DomDefine) try { + return gOPD(O, P); + } catch (e) { /* empty */ } + if (_has(O, P)) return _propertyDesc(!_objectPie.f.call(O, P), O[P]); +}; + +var _objectGopd = { + f: f$6 +}; + +// ECMAScript 6 symbols shim + + + + + +var META = _meta.KEY; + + + + + + + + + + + + + + + + + + + +var gOPD$1 = _objectGopd.f; +var dP$1 = _objectDp.f; +var gOPN$1 = _objectGopnExt.f; +var $Symbol = _global.Symbol; +var $JSON = _global.JSON; +var _stringify = $JSON && $JSON.stringify; +var PROTOTYPE$2 = 'prototype'; +var HIDDEN = _wks('_hidden'); +var TO_PRIMITIVE = _wks('toPrimitive'); +var isEnum = {}.propertyIsEnumerable; +var SymbolRegistry = _shared('symbol-registry'); +var AllSymbols = _shared('symbols'); +var OPSymbols = _shared('op-symbols'); +var ObjectProto = Object[PROTOTYPE$2]; +var USE_NATIVE = typeof $Symbol == 'function'; +var QObject = _global.QObject; +// Don't use setters in Qt Script, https://github.com/zloirock/core-js/issues/173 +var setter = !QObject || !QObject[PROTOTYPE$2] || !QObject[PROTOTYPE$2].findChild; + +// fallback for old Android, https://code.google.com/p/v8/issues/detail?id=687 +var setSymbolDesc = _descriptors && _fails(function () { + return _objectCreate(dP$1({}, 'a', { + get: function () { return dP$1(this, 'a', { value: 7 }).a; } + })).a != 7; +}) ? function (it, key, D) { + var protoDesc = gOPD$1(ObjectProto, key); + if (protoDesc) delete ObjectProto[key]; + dP$1(it, key, D); + if (protoDesc && it !== ObjectProto) dP$1(ObjectProto, key, protoDesc); +} : dP$1; + +var wrap = function (tag) { + var sym = AllSymbols[tag] = _objectCreate($Symbol[PROTOTYPE$2]); + sym._k = tag; + return sym; +}; + +var isSymbol = USE_NATIVE && typeof $Symbol.iterator == 'symbol' ? function (it) { + return typeof it == 'symbol'; +} : function (it) { + return it instanceof $Symbol; +}; + +var $defineProperty = function defineProperty(it, key, D) { + if (it === ObjectProto) $defineProperty(OPSymbols, key, D); + _anObject(it); + key = _toPrimitive(key, true); + _anObject(D); + if (_has(AllSymbols, key)) { + if (!D.enumerable) { + if (!_has(it, HIDDEN)) dP$1(it, HIDDEN, _propertyDesc(1, {})); + it[HIDDEN][key] = true; + } else { + if (_has(it, HIDDEN) && it[HIDDEN][key]) it[HIDDEN][key] = false; + D = _objectCreate(D, { enumerable: _propertyDesc(0, false) }); + } return setSymbolDesc(it, key, D); + } return dP$1(it, key, D); +}; +var $defineProperties = function defineProperties(it, P) { + _anObject(it); + var keys = _enumKeys(P = _toIobject(P)); + var i = 0; + var l = keys.length; + var key; + while (l > i) $defineProperty(it, key = keys[i++], P[key]); + return it; +}; +var $create = function create(it, P) { + return P === undefined ? _objectCreate(it) : $defineProperties(_objectCreate(it), P); +}; +var $propertyIsEnumerable = function propertyIsEnumerable(key) { + var E = isEnum.call(this, key = _toPrimitive(key, true)); + if (this === ObjectProto && _has(AllSymbols, key) && !_has(OPSymbols, key)) return false; + return E || !_has(this, key) || !_has(AllSymbols, key) || _has(this, HIDDEN) && this[HIDDEN][key] ? E : true; +}; +var $getOwnPropertyDescriptor = function getOwnPropertyDescriptor(it, key) { + it = _toIobject(it); + key = _toPrimitive(key, true); + if (it === ObjectProto && _has(AllSymbols, key) && !_has(OPSymbols, key)) return; + var D = gOPD$1(it, key); + if (D && _has(AllSymbols, key) && !(_has(it, HIDDEN) && it[HIDDEN][key])) D.enumerable = true; + return D; +}; +var $getOwnPropertyNames = function getOwnPropertyNames(it) { + var names = gOPN$1(_toIobject(it)); + var result = []; + var i = 0; + var key; + while (names.length > i) { + if (!_has(AllSymbols, key = names[i++]) && key != HIDDEN && key != META) result.push(key); + } return result; +}; +var $getOwnPropertySymbols = function getOwnPropertySymbols(it) { + var IS_OP = it === ObjectProto; + var names = gOPN$1(IS_OP ? OPSymbols : _toIobject(it)); + var result = []; + var i = 0; + var key; + while (names.length > i) { + if (_has(AllSymbols, key = names[i++]) && (IS_OP ? _has(ObjectProto, key) : true)) result.push(AllSymbols[key]); + } return result; +}; + +// 19.4.1.1 Symbol([description]) +if (!USE_NATIVE) { + $Symbol = function Symbol() { + if (this instanceof $Symbol) throw TypeError('Symbol is not a constructor!'); + var tag = _uid(arguments.length > 0 ? arguments[0] : undefined); + var $set = function (value) { + if (this === ObjectProto) $set.call(OPSymbols, value); + if (_has(this, HIDDEN) && _has(this[HIDDEN], tag)) this[HIDDEN][tag] = false; + setSymbolDesc(this, tag, _propertyDesc(1, value)); + }; + if (_descriptors && setter) setSymbolDesc(ObjectProto, tag, { configurable: true, set: $set }); + return wrap(tag); + }; + _redefine($Symbol[PROTOTYPE$2], 'toString', function toString() { + return this._k; + }); + + _objectGopd.f = $getOwnPropertyDescriptor; + _objectDp.f = $defineProperty; + _objectGopn.f = _objectGopnExt.f = $getOwnPropertyNames; + _objectPie.f = $propertyIsEnumerable; + _objectGops.f = $getOwnPropertySymbols; + + if (_descriptors && !_library) { + _redefine(ObjectProto, 'propertyIsEnumerable', $propertyIsEnumerable, true); + } + + _wksExt.f = function (name) { + return wrap(_wks(name)); + }; +} + +_export(_export.G + _export.W + _export.F * !USE_NATIVE, { Symbol: $Symbol }); + +for (var es6Symbols = ( + // 19.4.2.2, 19.4.2.3, 19.4.2.4, 19.4.2.6, 19.4.2.8, 19.4.2.9, 19.4.2.10, 19.4.2.11, 19.4.2.12, 19.4.2.13, 19.4.2.14 + 'hasInstance,isConcatSpreadable,iterator,match,replace,search,species,split,toPrimitive,toStringTag,unscopables' +).split(','), j = 0; es6Symbols.length > j;)_wks(es6Symbols[j++]); + +for (var wellKnownSymbols = _objectKeys(_wks.store), k = 0; wellKnownSymbols.length > k;) _wksDefine(wellKnownSymbols[k++]); + +_export(_export.S + _export.F * !USE_NATIVE, 'Symbol', { + // 19.4.2.1 Symbol.for(key) + 'for': function (key) { + return _has(SymbolRegistry, key += '') + ? SymbolRegistry[key] + : SymbolRegistry[key] = $Symbol(key); + }, + // 19.4.2.5 Symbol.keyFor(sym) + keyFor: function keyFor(sym) { + if (!isSymbol(sym)) throw TypeError(sym + ' is not a symbol!'); + for (var key in SymbolRegistry) if (SymbolRegistry[key] === sym) return key; + }, + useSetter: function () { setter = true; }, + useSimple: function () { setter = false; } +}); + +_export(_export.S + _export.F * !USE_NATIVE, 'Object', { + // 19.1.2.2 Object.create(O [, Properties]) + create: $create, + // 19.1.2.4 Object.defineProperty(O, P, Attributes) + defineProperty: $defineProperty, + // 19.1.2.3 Object.defineProperties(O, Properties) + defineProperties: $defineProperties, + // 19.1.2.6 Object.getOwnPropertyDescriptor(O, P) + getOwnPropertyDescriptor: $getOwnPropertyDescriptor, + // 19.1.2.7 Object.getOwnPropertyNames(O) + getOwnPropertyNames: $getOwnPropertyNames, + // 19.1.2.8 Object.getOwnPropertySymbols(O) + getOwnPropertySymbols: $getOwnPropertySymbols +}); + +// 24.3.2 JSON.stringify(value [, replacer [, space]]) +$JSON && _export(_export.S + _export.F * (!USE_NATIVE || _fails(function () { + var S = $Symbol(); + // MS Edge converts symbol values to JSON as {} + // WebKit converts symbol values to JSON as null + // V8 throws on boxed symbols + return _stringify([S]) != '[null]' || _stringify({ a: S }) != '{}' || _stringify(Object(S)) != '{}'; +})), 'JSON', { + stringify: function stringify(it) { + var args = [it]; + var i = 1; + var replacer, $replacer; + while (arguments.length > i) args.push(arguments[i++]); + $replacer = replacer = args[1]; + if (!_isObject(replacer) && it === undefined || isSymbol(it)) return; // IE8 returns string on undefined + if (!_isArray(replacer)) replacer = function (key, value) { + if (typeof $replacer == 'function') value = $replacer.call(this, key, value); + if (!isSymbol(value)) return value; + }; + args[1] = replacer; + return _stringify.apply($JSON, args); + } +}); + +// 19.4.3.4 Symbol.prototype[@@toPrimitive](hint) +$Symbol[PROTOTYPE$2][TO_PRIMITIVE] || _hide($Symbol[PROTOTYPE$2], TO_PRIMITIVE, $Symbol[PROTOTYPE$2].valueOf); +// 19.4.3.5 Symbol.prototype[@@toStringTag] +_setToStringTag($Symbol, 'Symbol'); +// 20.2.1.9 Math[@@toStringTag] +_setToStringTag(Math, 'Math', true); +// 24.3.3 JSON[@@toStringTag] +_setToStringTag(_global.JSON, 'JSON', true); + +// getting tag from 19.1.3.6 Object.prototype.toString() + +var TAG$1 = _wks('toStringTag'); +// ES3 wrong here +var ARG = _cof(function () { return arguments; }()) == 'Arguments'; + +// fallback for IE11 Script Access Denied error +var tryGet = function (it, key) { + try { + return it[key]; + } catch (e) { /* empty */ } +}; + +var _classof = function (it) { + var O, T, B; + return it === undefined ? 'Undefined' : it === null ? 'Null' + // @@toStringTag case + : typeof (T = tryGet(O = Object(it), TAG$1)) == 'string' ? T + // builtinTag case + : ARG ? _cof(O) + // ES3 arguments fallback + : (B = _cof(O)) == 'Object' && typeof O.callee == 'function' ? 'Arguments' : B; +}; + +// 19.1.3.6 Object.prototype.toString() + +var test = {}; +test[_wks('toStringTag')] = 'z'; +if (test + '' != '[object z]') { + _redefine(Object.prototype, 'toString', function toString() { + return '[object ' + _classof(this) + ']'; + }, true); +} + +_wksDefine('asyncIterator'); + +_wksDefine('observable'); + +var symbol = _core.Symbol; + +// true -> String#at +// false -> String#codePointAt +var _stringAt = function (TO_STRING) { + return function (that, pos) { + var s = String(_defined(that)); + var i = _toInteger(pos); + var l = s.length; + var a, b; + if (i < 0 || i >= l) return TO_STRING ? '' : undefined; + a = s.charCodeAt(i); + return a < 0xd800 || a > 0xdbff || i + 1 === l || (b = s.charCodeAt(i + 1)) < 0xdc00 || b > 0xdfff + ? TO_STRING ? s.charAt(i) : a + : TO_STRING ? s.slice(i, i + 2) : (a - 0xd800 << 10) + (b - 0xdc00) + 0x10000; + }; +}; + +var _iterators = {}; + +var IteratorPrototype = {}; + +// 25.1.2.1.1 %IteratorPrototype%[@@iterator]() +_hide(IteratorPrototype, _wks('iterator'), function () { return this; }); + +var _iterCreate = function (Constructor, NAME, next) { + Constructor.prototype = _objectCreate(IteratorPrototype, { next: _propertyDesc(1, next) }); + _setToStringTag(Constructor, NAME + ' Iterator'); +}; + +// 19.1.2.9 / 15.2.3.2 Object.getPrototypeOf(O) + + +var IE_PROTO$2 = _sharedKey('IE_PROTO'); +var ObjectProto$1 = Object.prototype; + +var _objectGpo = Object.getPrototypeOf || function (O) { + O = _toObject(O); + if (_has(O, IE_PROTO$2)) return O[IE_PROTO$2]; + if (typeof O.constructor == 'function' && O instanceof O.constructor) { + return O.constructor.prototype; + } return O instanceof Object ? ObjectProto$1 : null; +}; + +var ITERATOR = _wks('iterator'); +var BUGGY = !([].keys && 'next' in [].keys()); // Safari has buggy iterators w/o `next` +var FF_ITERATOR = '@@iterator'; +var KEYS = 'keys'; +var VALUES = 'values'; + +var returnThis = function () { return this; }; + +var _iterDefine = function (Base, NAME, Constructor, next, DEFAULT, IS_SET, FORCED) { + _iterCreate(Constructor, NAME, next); + var getMethod = function (kind) { + if (!BUGGY && kind in proto) return proto[kind]; + switch (kind) { + case KEYS: return function keys() { return new Constructor(this, kind); }; + case VALUES: return function values() { return new Constructor(this, kind); }; + } return function entries() { return new Constructor(this, kind); }; + }; + var TAG = NAME + ' Iterator'; + var DEF_VALUES = DEFAULT == VALUES; + var VALUES_BUG = false; + var proto = Base.prototype; + var $native = proto[ITERATOR] || proto[FF_ITERATOR] || DEFAULT && proto[DEFAULT]; + var $default = $native || getMethod(DEFAULT); + var $entries = DEFAULT ? !DEF_VALUES ? $default : getMethod('entries') : undefined; + var $anyNative = NAME == 'Array' ? proto.entries || $native : $native; + var methods, key, IteratorPrototype; + // Fix native + if ($anyNative) { + IteratorPrototype = _objectGpo($anyNative.call(new Base())); + if (IteratorPrototype !== Object.prototype && IteratorPrototype.next) { + // Set @@toStringTag to native iterators + _setToStringTag(IteratorPrototype, TAG, true); + // fix for some old engines + if (!_library && typeof IteratorPrototype[ITERATOR] != 'function') _hide(IteratorPrototype, ITERATOR, returnThis); + } + } + // fix Array#{values, @@iterator}.name in V8 / FF + if (DEF_VALUES && $native && $native.name !== VALUES) { + VALUES_BUG = true; + $default = function values() { return $native.call(this); }; + } + // Define iterator + if ((!_library || FORCED) && (BUGGY || VALUES_BUG || !proto[ITERATOR])) { + _hide(proto, ITERATOR, $default); + } + // Plug for library + _iterators[NAME] = $default; + _iterators[TAG] = returnThis; + if (DEFAULT) { + methods = { + values: DEF_VALUES ? $default : getMethod(VALUES), + keys: IS_SET ? $default : getMethod(KEYS), + entries: $entries + }; + if (FORCED) for (key in methods) { + if (!(key in proto)) _redefine(proto, key, methods[key]); + } else _export(_export.P + _export.F * (BUGGY || VALUES_BUG), NAME, methods); + } + return methods; +}; + +var $at = _stringAt(true); + +// 21.1.3.27 String.prototype[@@iterator]() +_iterDefine(String, 'String', function (iterated) { + this._t = String(iterated); // target + this._i = 0; // next index +// 21.1.5.2.1 %StringIteratorPrototype%.next() +}, function () { + var O = this._t; + var index = this._i; + var point; + if (index >= O.length) return { value: undefined, done: true }; + point = $at(O, index); + this._i += point.length; + return { value: point, done: false }; +}); + +var _iterStep = function (done, value) { + return { value: value, done: !!done }; +}; + +// 22.1.3.4 Array.prototype.entries() +// 22.1.3.13 Array.prototype.keys() +// 22.1.3.29 Array.prototype.values() +// 22.1.3.30 Array.prototype[@@iterator]() +var es6_array_iterator = _iterDefine(Array, 'Array', function (iterated, kind) { + this._t = _toIobject(iterated); // target + this._i = 0; // next index + this._k = kind; // kind +// 22.1.5.2.1 %ArrayIteratorPrototype%.next() +}, function () { + var O = this._t; + var kind = this._k; + var index = this._i++; + if (!O || index >= O.length) { + this._t = undefined; + return _iterStep(1); + } + if (kind == 'keys') return _iterStep(0, index); + if (kind == 'values') return _iterStep(0, O[index]); + return _iterStep(0, [index, O[index]]); +}, 'values'); + +// argumentsList[@@iterator] is %ArrayProto_values% (9.4.4.6, 9.4.4.7) +_iterators.Arguments = _iterators.Array; + +_addToUnscopables('keys'); +_addToUnscopables('values'); +_addToUnscopables('entries'); + +var ITERATOR$1 = _wks('iterator'); +var TO_STRING_TAG = _wks('toStringTag'); +var ArrayValues = _iterators.Array; + +var DOMIterables = { + CSSRuleList: true, // TODO: Not spec compliant, should be false. + CSSStyleDeclaration: false, + CSSValueList: false, + ClientRectList: false, + DOMRectList: false, + DOMStringList: false, + DOMTokenList: true, + DataTransferItemList: false, + FileList: false, + HTMLAllCollection: false, + HTMLCollection: false, + HTMLFormElement: false, + HTMLSelectElement: false, + MediaList: true, // TODO: Not spec compliant, should be false. + MimeTypeArray: false, + NamedNodeMap: false, + NodeList: true, + PaintRequestList: false, + Plugin: false, + PluginArray: false, + SVGLengthList: false, + SVGNumberList: false, + SVGPathSegList: false, + SVGPointList: false, + SVGStringList: false, + SVGTransformList: false, + SourceBufferList: false, + StyleSheetList: true, // TODO: Not spec compliant, should be false. + TextTrackCueList: false, + TextTrackList: false, + TouchList: false +}; + +for (var collections = _objectKeys(DOMIterables), i = 0; i < collections.length; i++) { + var NAME = collections[i]; + var explicit = DOMIterables[NAME]; + var Collection = _global[NAME]; + var proto = Collection && Collection.prototype; + var key; + if (proto) { + if (!proto[ITERATOR$1]) _hide(proto, ITERATOR$1, ArrayValues); + if (!proto[TO_STRING_TAG]) _hide(proto, TO_STRING_TAG, NAME); + _iterators[NAME] = ArrayValues; + if (explicit) for (key in es6_array_iterator) if (!proto[key]) _redefine(proto, key, es6_array_iterator[key], true); + } +} + +var iterator = _wksExt.f('iterator'); + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {},require("timers").setImmediate) +},{"timers":36,"whatwg-fetch":32}],4:[function(require,module,exports){ +'use strict'; + +Object.defineProperty(exports, '__esModule', { value: true }); + +var tslib_1 = require('tslib'); + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @fileoverview Firebase constants. Some of these (@defines) can be overridden at compile-time. + */ +var CONSTANTS = { + /** + * @define {boolean} Whether this is the client Node.js SDK. + */ + NODE_CLIENT: false, + /** + * @define {boolean} Whether this is the Admin Node.js SDK. + */ + NODE_ADMIN: false, + /** + * Firebase SDK Version + */ + SDK_VERSION: '${JSCORE_VERSION}' +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Throws an error if the provided assertion is falsy + * @param {*} assertion The assertion to be tested for falsiness + * @param {!string} message The message to display if the check fails + */ +var assert = function (assertion, message) { + if (!assertion) { + throw assertionError(message); + } +}; +/** + * Returns an Error object suitable for throwing. + * @param {string} message + * @return {!Error} + */ +var assertionError = function (message) { + return new Error('Firebase Database (' + + CONSTANTS.SDK_VERSION + + ') INTERNAL ASSERT FAILED: ' + + message); +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var stringToByteArray = function (str) { + // TODO(user): Use native implementations if/when available + var out = [], p = 0; + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i); + if (c < 128) { + out[p++] = c; + } + else if (c < 2048) { + out[p++] = (c >> 6) | 192; + out[p++] = (c & 63) | 128; + } + else if ((c & 0xfc00) == 0xd800 && + i + 1 < str.length && + (str.charCodeAt(i + 1) & 0xfc00) == 0xdc00) { + // Surrogate Pair + c = 0x10000 + ((c & 0x03ff) << 10) + (str.charCodeAt(++i) & 0x03ff); + out[p++] = (c >> 18) | 240; + out[p++] = ((c >> 12) & 63) | 128; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; + } + else { + out[p++] = (c >> 12) | 224; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; + } + } + return out; +}; +/** + * Turns an array of numbers into the string given by the concatenation of the + * characters to which the numbers correspond. + * @param {Array} bytes Array of numbers representing characters. + * @return {string} Stringification of the array. + */ +var byteArrayToString = function (bytes) { + // TODO(user): Use native implementations if/when available + var out = [], pos = 0, c = 0; + while (pos < bytes.length) { + var c1 = bytes[pos++]; + if (c1 < 128) { + out[c++] = String.fromCharCode(c1); + } + else if (c1 > 191 && c1 < 224) { + var c2 = bytes[pos++]; + out[c++] = String.fromCharCode(((c1 & 31) << 6) | (c2 & 63)); + } + else if (c1 > 239 && c1 < 365) { + // Surrogate Pair + var c2 = bytes[pos++]; + var c3 = bytes[pos++]; + var c4 = bytes[pos++]; + var u = (((c1 & 7) << 18) | ((c2 & 63) << 12) | ((c3 & 63) << 6) | (c4 & 63)) - + 0x10000; + out[c++] = String.fromCharCode(0xd800 + (u >> 10)); + out[c++] = String.fromCharCode(0xdc00 + (u & 1023)); + } + else { + var c2 = bytes[pos++]; + var c3 = bytes[pos++]; + out[c++] = String.fromCharCode(((c1 & 15) << 12) | ((c2 & 63) << 6) | (c3 & 63)); + } + } + return out.join(''); +}; +// Static lookup maps, lazily populated by init_() +var base64 = { + /** + * Maps bytes to characters. + * @type {Object} + * @private + */ + byteToCharMap_: null, + /** + * Maps characters to bytes. + * @type {Object} + * @private + */ + charToByteMap_: null, + /** + * Maps bytes to websafe characters. + * @type {Object} + * @private + */ + byteToCharMapWebSafe_: null, + /** + * Maps websafe characters to bytes. + * @type {Object} + * @private + */ + charToByteMapWebSafe_: null, + /** + * Our default alphabet, shared between + * ENCODED_VALS and ENCODED_VALS_WEBSAFE + * @type {string} + */ + ENCODED_VALS_BASE: 'ABCDEFGHIJKLMNOPQRSTUVWXYZ' + 'abcdefghijklmnopqrstuvwxyz' + '0123456789', + /** + * Our default alphabet. Value 64 (=) is special; it means "nothing." + * @type {string} + */ + get ENCODED_VALS() { + return this.ENCODED_VALS_BASE + '+/='; + }, + /** + * Our websafe alphabet. + * @type {string} + */ + get ENCODED_VALS_WEBSAFE() { + return this.ENCODED_VALS_BASE + '-_.'; + }, + /** + * Whether this browser supports the atob and btoa functions. This extension + * started at Mozilla but is now implemented by many browsers. We use the + * ASSUME_* variables to avoid pulling in the full useragent detection library + * but still allowing the standard per-browser compilations. + * + * @type {boolean} + */ + HAS_NATIVE_SUPPORT: typeof atob === 'function', + /** + * Base64-encode an array of bytes. + * + * @param {Array|Uint8Array} input An array of bytes (numbers with + * value in [0, 255]) to encode. + * @param {boolean=} opt_webSafe Boolean indicating we should use the + * alternative alphabet. + * @return {string} The base64 encoded string. + */ + encodeByteArray: function (input, opt_webSafe) { + if (!Array.isArray(input)) { + throw Error('encodeByteArray takes an array as a parameter'); + } + this.init_(); + var byteToCharMap = opt_webSafe + ? this.byteToCharMapWebSafe_ + : this.byteToCharMap_; + var output = []; + for (var i = 0; i < input.length; i += 3) { + var byte1 = input[i]; + var haveByte2 = i + 1 < input.length; + var byte2 = haveByte2 ? input[i + 1] : 0; + var haveByte3 = i + 2 < input.length; + var byte3 = haveByte3 ? input[i + 2] : 0; + var outByte1 = byte1 >> 2; + var outByte2 = ((byte1 & 0x03) << 4) | (byte2 >> 4); + var outByte3 = ((byte2 & 0x0f) << 2) | (byte3 >> 6); + var outByte4 = byte3 & 0x3f; + if (!haveByte3) { + outByte4 = 64; + if (!haveByte2) { + outByte3 = 64; + } + } + output.push(byteToCharMap[outByte1], byteToCharMap[outByte2], byteToCharMap[outByte3], byteToCharMap[outByte4]); + } + return output.join(''); + }, + /** + * Base64-encode a string. + * + * @param {string} input A string to encode. + * @param {boolean=} opt_webSafe If true, we should use the + * alternative alphabet. + * @return {string} The base64 encoded string. + */ + encodeString: function (input, opt_webSafe) { + // Shortcut for Mozilla browsers that implement + // a native base64 encoder in the form of "btoa/atob" + if (this.HAS_NATIVE_SUPPORT && !opt_webSafe) { + return btoa(input); + } + return this.encodeByteArray(stringToByteArray(input), opt_webSafe); + }, + /** + * Base64-decode a string. + * + * @param {string} input to decode. + * @param {boolean=} opt_webSafe True if we should use the + * alternative alphabet. + * @return {string} string representing the decoded value. + */ + decodeString: function (input, opt_webSafe) { + // Shortcut for Mozilla browsers that implement + // a native base64 encoder in the form of "btoa/atob" + if (this.HAS_NATIVE_SUPPORT && !opt_webSafe) { + return atob(input); + } + return byteArrayToString(this.decodeStringToByteArray(input, opt_webSafe)); + }, + /** + * Base64-decode a string. + * + * In base-64 decoding, groups of four characters are converted into three + * bytes. If the encoder did not apply padding, the input length may not + * be a multiple of 4. + * + * In this case, the last group will have fewer than 4 characters, and + * padding will be inferred. If the group has one or two characters, it decodes + * to one byte. If the group has three characters, it decodes to two bytes. + * + * @param {string} input Input to decode. + * @param {boolean=} opt_webSafe True if we should use the web-safe alphabet. + * @return {!Array} bytes representing the decoded value. + */ + decodeStringToByteArray: function (input, opt_webSafe) { + this.init_(); + var charToByteMap = opt_webSafe + ? this.charToByteMapWebSafe_ + : this.charToByteMap_; + var output = []; + for (var i = 0; i < input.length;) { + var byte1 = charToByteMap[input.charAt(i++)]; + var haveByte2 = i < input.length; + var byte2 = haveByte2 ? charToByteMap[input.charAt(i)] : 0; + ++i; + var haveByte3 = i < input.length; + var byte3 = haveByte3 ? charToByteMap[input.charAt(i)] : 64; + ++i; + var haveByte4 = i < input.length; + var byte4 = haveByte4 ? charToByteMap[input.charAt(i)] : 64; + ++i; + if (byte1 == null || byte2 == null || byte3 == null || byte4 == null) { + throw Error(); + } + var outByte1 = (byte1 << 2) | (byte2 >> 4); + output.push(outByte1); + if (byte3 != 64) { + var outByte2 = ((byte2 << 4) & 0xf0) | (byte3 >> 2); + output.push(outByte2); + if (byte4 != 64) { + var outByte3 = ((byte3 << 6) & 0xc0) | byte4; + output.push(outByte3); + } + } + } + return output; + }, + /** + * Lazy static initialization function. Called before + * accessing any of the static map variables. + * @private + */ + init_: function () { + if (!this.byteToCharMap_) { + this.byteToCharMap_ = {}; + this.charToByteMap_ = {}; + this.byteToCharMapWebSafe_ = {}; + this.charToByteMapWebSafe_ = {}; + // We want quick mappings back and forth, so we precompute two maps. + for (var i = 0; i < this.ENCODED_VALS.length; i++) { + this.byteToCharMap_[i] = this.ENCODED_VALS.charAt(i); + this.charToByteMap_[this.byteToCharMap_[i]] = i; + this.byteToCharMapWebSafe_[i] = this.ENCODED_VALS_WEBSAFE.charAt(i); + this.charToByteMapWebSafe_[this.byteToCharMapWebSafe_[i]] = i; + // Be forgiving when decoding and correctly decode both encodings. + if (i >= this.ENCODED_VALS_BASE.length) { + this.charToByteMap_[this.ENCODED_VALS_WEBSAFE.charAt(i)] = i; + this.charToByteMapWebSafe_[this.ENCODED_VALS.charAt(i)] = i; + } + } + } + } +}; +/** + * URL-safe base64 encoding + * @param {!string} str + * @return {!string} + */ +var base64Encode = function (str) { + var utf8Bytes = stringToByteArray(str); + return base64.encodeByteArray(utf8Bytes, true); +}; +/** + * URL-safe base64 decoding + * + * NOTE: DO NOT use the global atob() function - it does NOT support the + * base64Url variant encoding. + * + * @param {string} str To be decoded + * @return {?string} Decoded result, if possible + */ +var base64Decode = function (str) { + try { + return base64.decodeString(str, true); + } + catch (e) { + console.error('base64Decode failed: ', e); + } + return null; +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Do a deep-copy of basic JavaScript Objects or Arrays. + */ +function deepCopy(value) { + return deepExtend(undefined, value); +} +/** + * Copy properties from source to target (recursively allows extension + * of Objects and Arrays). Scalar values in the target are over-written. + * If target is undefined, an object of the appropriate type will be created + * (and returned). + * + * We recursively copy all child properties of plain Objects in the source- so + * that namespace- like dictionaries are merged. + * + * Note that the target can be a function, in which case the properties in + * the source Object are copied onto it as static properties of the Function. + */ +function deepExtend(target, source) { + if (!(source instanceof Object)) { + return source; + } + switch (source.constructor) { + case Date: + // Treat Dates like scalars; if the target date object had any child + // properties - they will be lost! + var dateValue = source; + return new Date(dateValue.getTime()); + case Object: + if (target === undefined) { + target = {}; + } + break; + case Array: + // Always copy the array source and overwrite the target. + target = []; + break; + default: + // Not a plain Object - treat it as a scalar. + return source; + } + for (var prop in source) { + if (!source.hasOwnProperty(prop)) { + continue; + } + target[prop] = deepExtend(target[prop], source[prop]); + } + return target; +} +// TODO: Really needed (for JSCompiler type checking)? +function patchProperty(obj, prop, value) { + obj[prop] = value; +} + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +var Deferred = /** @class */ (function () { + function Deferred() { + var _this = this; + this.promise = new Promise(function (resolve, reject) { + _this.resolve = resolve; + _this.reject = reject; + }); + } + /** + * Our API internals are not promiseified and cannot because our callback APIs have subtle expectations around + * invoking promises inline, which Promises are forbidden to do. This method accepts an optional node-style callback + * and returns a node-style callback which will resolve or reject the Deferred's promise. + * @param {((?function(?(Error)): (?|undefined))| (?function(?(Error),?=): (?|undefined)))=} callback + * @return {!function(?(Error), ?=)} + */ + Deferred.prototype.wrapCallback = function (callback) { + var _this = this; + return function (error, value) { + if (error) { + _this.reject(error); + } + else { + _this.resolve(value); + } + if (typeof callback === 'function') { + // Attaching noop handler just in case developer wasn't expecting + // promises + _this.promise.catch(function () { }); + // Some of our callbacks don't expect a value and our own tests + // assert that the parameter length is 1 + if (callback.length === 1) { + callback(error); + } + else { + callback(error, value); + } + } + }; + }; + return Deferred; +}()); + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Returns navigator.userAgent string or '' if it's not defined. + * @return {string} user agent string + */ +var getUA = function () { + if (typeof navigator !== 'undefined' && + typeof navigator['userAgent'] === 'string') { + return navigator['userAgent']; + } + else { + return ''; + } +}; +/** + * Detect Cordova / PhoneGap / Ionic frameworks on a mobile device. + * + * Deliberately does not rely on checking `file://` URLs (as this fails PhoneGap in the Ripple emulator) nor + * Cordova `onDeviceReady`, which would normally wait for a callback. + * + * @return {boolean} isMobileCordova + */ +var isMobileCordova = function () { + return (typeof window !== 'undefined' && + !!(window['cordova'] || window['phonegap'] || window['PhoneGap']) && + /ios|iphone|ipod|ipad|android|blackberry|iemobile/i.test(getUA())); +}; +/** + * Detect React Native. + * + * @return {boolean} True if ReactNative environment is detected. + */ +var isReactNative = function () { + return (typeof navigator === 'object' && navigator['product'] === 'ReactNative'); +}; +/** + * Detect Node.js. + * + * @return {boolean} True if Node.js environment is detected. + */ +var isNodeSdk = function () { + return CONSTANTS.NODE_CLIENT === true || CONSTANTS.NODE_ADMIN === true; +}; + +var ERROR_NAME = 'FirebaseError'; +var captureStackTrace = Error + .captureStackTrace; +// Export for faking in tests +function patchCapture(captureFake) { + var result = captureStackTrace; + captureStackTrace = captureFake; + return result; +} +var FirebaseError = /** @class */ (function () { + function FirebaseError(code, message) { + this.code = code; + this.message = message; + // We want the stack value, if implemented by Error + if (captureStackTrace) { + // Patches this.stack, omitted calls above ErrorFactory#create + captureStackTrace(this, ErrorFactory.prototype.create); + } + else { + try { + // In case of IE11, stack will be set only after error is raised. + // https://docs.microsoft.com/en-us/scripting/javascript/reference/stack-property-error-javascript + throw Error.apply(this, arguments); + } + catch (err) { + this.name = ERROR_NAME; + // Make non-enumerable getter for the property. + Object.defineProperty(this, 'stack', { + get: function () { + return err.stack; + } + }); + } + } + } + return FirebaseError; +}()); +// Back-door inheritance +FirebaseError.prototype = Object.create(Error.prototype); +FirebaseError.prototype.constructor = FirebaseError; +FirebaseError.prototype.name = ERROR_NAME; +var ErrorFactory = /** @class */ (function () { + function ErrorFactory(service, serviceName, errors) { + this.service = service; + this.serviceName = serviceName; + this.errors = errors; + // Matches {$name}, by default. + this.pattern = /\{\$([^}]+)}/g; + // empty + } + ErrorFactory.prototype.create = function (code, data) { + if (data === undefined) { + data = {}; + } + var template = this.errors[code]; + var fullCode = this.service + '/' + code; + var message; + if (template === undefined) { + message = 'Error'; + } + else { + message = template.replace(this.pattern, function (match, key) { + var value = data[key]; + return value !== undefined ? value.toString() : '<' + key + '?>'; + }); + } + // Service: Error message (service/code). + message = this.serviceName + ': ' + message + ' (' + fullCode + ').'; + var err = new FirebaseError(fullCode, message); + // Populate the Error object with message parts for programmatic + // accesses (e.g., e.file). + for (var prop in data) { + if (!data.hasOwnProperty(prop) || prop.slice(-1) === '_') { + continue; + } + err[prop] = data[prop]; + } + return err; + }; + return ErrorFactory; +}()); + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Evaluates a JSON string into a javascript object. + * + * @param {string} str A string containing JSON. + * @return {*} The javascript object representing the specified JSON. + */ +function jsonEval(str) { + return JSON.parse(str); +} +/** + * Returns JSON representing a javascript object. + * @param {*} data Javascript object to be stringified. + * @return {string} The JSON contents of the object. + */ +function stringify(data) { + return JSON.stringify(data); +} + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Decodes a Firebase auth. token into constituent parts. + * + * Notes: + * - May return with invalid / incomplete claims if there's no native base64 decoding support. + * - Doesn't check if the token is actually valid. + * + * @param {?string} token + * @return {{header: *, claims: *, data: *, signature: string}} + */ +var decode = function (token) { + var header = {}, claims = {}, data = {}, signature = ''; + try { + var parts = token.split('.'); + header = jsonEval(base64Decode(parts[0]) || ''); + claims = jsonEval(base64Decode(parts[1]) || ''); + signature = parts[2]; + data = claims['d'] || {}; + delete claims['d']; + } + catch (e) { } + return { + header: header, + claims: claims, + data: data, + signature: signature + }; +}; +/** + * Decodes a Firebase auth. token and checks the validity of its time-based claims. Will return true if the + * token is within the time window authorized by the 'nbf' (not-before) and 'iat' (issued-at) claims. + * + * Notes: + * - May return a false negative if there's no native base64 decoding support. + * - Doesn't check if the token is actually valid. + * + * @param {?string} token + * @return {boolean} + */ +var isValidTimestamp = function (token) { + var claims = decode(token).claims, now = Math.floor(new Date().getTime() / 1000), validSince, validUntil; + if (typeof claims === 'object') { + if (claims.hasOwnProperty('nbf')) { + validSince = claims['nbf']; + } + else if (claims.hasOwnProperty('iat')) { + validSince = claims['iat']; + } + if (claims.hasOwnProperty('exp')) { + validUntil = claims['exp']; + } + else { + // token will expire after 24h by default + validUntil = validSince + 86400; + } + } + return (now && validSince && validUntil && now >= validSince && now <= validUntil); +}; +/** + * Decodes a Firebase auth. token and returns its issued at time if valid, null otherwise. + * + * Notes: + * - May return null if there's no native base64 decoding support. + * - Doesn't check if the token is actually valid. + * + * @param {?string} token + * @return {?number} + */ +var issuedAtTime = function (token) { + var claims = decode(token).claims; + if (typeof claims === 'object' && claims.hasOwnProperty('iat')) { + return claims['iat']; + } + return null; +}; +/** + * Decodes a Firebase auth. token and checks the validity of its format. Expects a valid issued-at time. + * + * Notes: + * - May return a false negative if there's no native base64 decoding support. + * - Doesn't check if the token is actually valid. + * + * @param {?string} token + * @return {boolean} + */ +var isValidFormat = function (token) { + var decoded = decode(token), claims = decoded.claims; + return !!claims && typeof claims === 'object' && claims.hasOwnProperty('iat'); +}; +/** + * Attempts to peer into an auth token and determine if it's an admin auth token by looking at the claims portion. + * + * Notes: + * - May return a false negative if there's no native base64 decoding support. + * - Doesn't check if the token is actually valid. + * + * @param {?string} token + * @return {boolean} + */ +var isAdmin = function (token) { + var claims = decode(token).claims; + return typeof claims === 'object' && claims['admin'] === true; +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// See http://www.devthought.com/2012/01/18/an-object-is-not-a-hash/ +var contains = function (obj, key) { + return Object.prototype.hasOwnProperty.call(obj, key); +}; +var safeGet = function (obj, key) { + if (Object.prototype.hasOwnProperty.call(obj, key)) + return obj[key]; + // else return undefined. +}; +/** + * Enumerates the keys/values in an object, excluding keys defined on the prototype. + * + * @param {?Object.} obj Object to enumerate. + * @param {!function(K, V)} fn Function to call for each key and value. + * @template K,V + */ +var forEach = function (obj, fn) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + fn(key, obj[key]); + } + } +}; +/** + * Copies all the (own) properties from one object to another. + * @param {!Object} objTo + * @param {!Object} objFrom + * @return {!Object} objTo + */ +var extend = function (objTo, objFrom) { + forEach(objFrom, function (key, value) { + objTo[key] = value; + }); + return objTo; +}; +/** + * Returns a clone of the specified object. + * @param {!Object} obj + * @return {!Object} cloned obj. + */ +var clone = function (obj) { + return extend({}, obj); +}; +/** + * Returns true if obj has typeof "object" and is not null. Unlike goog.isObject(), does not return true + * for functions. + * + * @param obj {*} A potential object. + * @returns {boolean} True if it's an object. + */ +var isNonNullObject = function (obj) { + return typeof obj === 'object' && obj !== null; +}; +var isEmpty = function (obj) { + for (var key in obj) { + return false; + } + return true; +}; +var getCount = function (obj) { + var rv = 0; + for (var key in obj) { + rv++; + } + return rv; +}; +var map = function (obj, f, opt_obj) { + var res = {}; + for (var key in obj) { + res[key] = f.call(opt_obj, obj[key], key, obj); + } + return res; +}; +var findKey = function (obj, fn, opt_this) { + for (var key in obj) { + if (fn.call(opt_this, obj[key], key, obj)) { + return key; + } + } + return undefined; +}; +var findValue = function (obj, fn, opt_this) { + var key = findKey(obj, fn, opt_this); + return key && obj[key]; +}; +var getAnyKey = function (obj) { + for (var key in obj) { + return key; + } +}; +var getValues = function (obj) { + var res = []; + var i = 0; + for (var key in obj) { + res[i++] = obj[key]; + } + return res; +}; +/** + * Tests whether every key/value pair in an object pass the test implemented + * by the provided function + * + * @param {?Object.} obj Object to test. + * @param {!function(K, V)} fn Function to call for each key and value. + * @template K,V + */ +var every = function (obj, fn) { + for (var key in obj) { + if (Object.prototype.hasOwnProperty.call(obj, key)) { + if (!fn(key, obj[key])) { + return false; + } + } + } + return true; +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Returns a querystring-formatted string (e.g. &arg=val&arg2=val2) from a params + * object (e.g. {arg: 'val', arg2: 'val2'}) + * Note: You must prepend it with ? when adding it to a URL. + * + * @param {!Object} querystringParams + * @return {string} + */ +var querystring = function (querystringParams) { + var params = []; + forEach(querystringParams, function (key, value) { + if (Array.isArray(value)) { + value.forEach(function (arrayVal) { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(arrayVal)); + }); + } + else { + params.push(encodeURIComponent(key) + '=' + encodeURIComponent(value)); + } + }); + return params.length ? '&' + params.join('&') : ''; +}; +/** + * Decodes a querystring (e.g. ?arg=val&arg2=val2) into a params object (e.g. {arg: 'val', arg2: 'val2'}) + * + * @param {string} querystring + * @return {!Object} + */ +var querystringDecode = function (querystring) { + var obj = {}; + var tokens = querystring.replace(/^\?/, '').split('&'); + tokens.forEach(function (token) { + if (token) { + var key = token.split('='); + obj[key[0]] = key[1]; + } + }); + return obj; +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Copyright 2011 The Closure Library Authors. All Rights Reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS-IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. +/** + * @fileoverview Abstract cryptographic hash interface. + * + * See Sha1 and Md5 for sample implementations. + * + */ +/** + * Create a cryptographic hash instance. + * + * @constructor + * @struct + */ +var Hash = /** @class */ (function () { + function Hash() { + /** + * The block size for the hasher. + * @type {number} + */ + this.blockSize = -1; + } + return Hash; +}()); + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * @fileoverview SHA-1 cryptographic hash. + * Variable names follow the notation in FIPS PUB 180-3: + * http://csrc.nist.gov/publications/fips/fips180-3/fips180-3_final.pdf. + * + * Usage: + * var sha1 = new sha1(); + * sha1.update(bytes); + * var hash = sha1.digest(); + * + * Performance: + * Chrome 23: ~400 Mbit/s + * Firefox 16: ~250 Mbit/s + * + */ +/** + * SHA-1 cryptographic hash constructor. + * + * The properties declared here are discussed in the above algorithm document. + * @constructor + * @extends {Hash} + * @final + * @struct + */ +var Sha1 = /** @class */ (function (_super) { + tslib_1.__extends(Sha1, _super); + function Sha1() { + var _this = _super.call(this) || this; + /** + * Holds the previous values of accumulated variables a-e in the compress_ + * function. + * @type {!Array} + * @private + */ + _this.chain_ = []; + /** + * A buffer holding the partially computed hash result. + * @type {!Array} + * @private + */ + _this.buf_ = []; + /** + * An array of 80 bytes, each a part of the message to be hashed. Referred to + * as the message schedule in the docs. + * @type {!Array} + * @private + */ + _this.W_ = []; + /** + * Contains data needed to pad messages less than 64 bytes. + * @type {!Array} + * @private + */ + _this.pad_ = []; + /** + * @private {number} + */ + _this.inbuf_ = 0; + /** + * @private {number} + */ + _this.total_ = 0; + _this.blockSize = 512 / 8; + _this.pad_[0] = 128; + for (var i = 1; i < _this.blockSize; ++i) { + _this.pad_[i] = 0; + } + _this.reset(); + return _this; + } + Sha1.prototype.reset = function () { + this.chain_[0] = 0x67452301; + this.chain_[1] = 0xefcdab89; + this.chain_[2] = 0x98badcfe; + this.chain_[3] = 0x10325476; + this.chain_[4] = 0xc3d2e1f0; + this.inbuf_ = 0; + this.total_ = 0; + }; + /** + * Internal compress helper function. + * @param {!Array|!Uint8Array|string} buf Block to compress. + * @param {number=} opt_offset Offset of the block in the buffer. + * @private + */ + Sha1.prototype.compress_ = function (buf, opt_offset) { + if (!opt_offset) { + opt_offset = 0; + } + var W = this.W_; + // get 16 big endian words + if (typeof buf === 'string') { + for (var i = 0; i < 16; i++) { + // TODO(user): [bug 8140122] Recent versions of Safari for Mac OS and iOS + // have a bug that turns the post-increment ++ operator into pre-increment + // during JIT compilation. We have code that depends heavily on SHA-1 for + // correctness and which is affected by this bug, so I've removed all uses + // of post-increment ++ in which the result value is used. We can revert + // this change once the Safari bug + // (https://bugs.webkit.org/show_bug.cgi?id=109036) has been fixed and + // most clients have been updated. + W[i] = + (buf.charCodeAt(opt_offset) << 24) | + (buf.charCodeAt(opt_offset + 1) << 16) | + (buf.charCodeAt(opt_offset + 2) << 8) | + buf.charCodeAt(opt_offset + 3); + opt_offset += 4; + } + } + else { + for (var i = 0; i < 16; i++) { + W[i] = + (buf[opt_offset] << 24) | + (buf[opt_offset + 1] << 16) | + (buf[opt_offset + 2] << 8) | + buf[opt_offset + 3]; + opt_offset += 4; + } + } + // expand to 80 words + for (var i = 16; i < 80; i++) { + var t = W[i - 3] ^ W[i - 8] ^ W[i - 14] ^ W[i - 16]; + W[i] = ((t << 1) | (t >>> 31)) & 0xffffffff; + } + var a = this.chain_[0]; + var b = this.chain_[1]; + var c = this.chain_[2]; + var d = this.chain_[3]; + var e = this.chain_[4]; + var f, k; + // TODO(user): Try to unroll this loop to speed up the computation. + for (var i = 0; i < 80; i++) { + if (i < 40) { + if (i < 20) { + f = d ^ (b & (c ^ d)); + k = 0x5a827999; + } + else { + f = b ^ c ^ d; + k = 0x6ed9eba1; + } + } + else { + if (i < 60) { + f = (b & c) | (d & (b | c)); + k = 0x8f1bbcdc; + } + else { + f = b ^ c ^ d; + k = 0xca62c1d6; + } + } + var t = (((a << 5) | (a >>> 27)) + f + e + k + W[i]) & 0xffffffff; + e = d; + d = c; + c = ((b << 30) | (b >>> 2)) & 0xffffffff; + b = a; + a = t; + } + this.chain_[0] = (this.chain_[0] + a) & 0xffffffff; + this.chain_[1] = (this.chain_[1] + b) & 0xffffffff; + this.chain_[2] = (this.chain_[2] + c) & 0xffffffff; + this.chain_[3] = (this.chain_[3] + d) & 0xffffffff; + this.chain_[4] = (this.chain_[4] + e) & 0xffffffff; + }; + Sha1.prototype.update = function (bytes, opt_length) { + // TODO(johnlenz): tighten the function signature and remove this check + if (bytes == null) { + return; + } + if (opt_length === undefined) { + opt_length = bytes.length; + } + var lengthMinusBlock = opt_length - this.blockSize; + var n = 0; + // Using local instead of member variables gives ~5% speedup on Firefox 16. + var buf = this.buf_; + var inbuf = this.inbuf_; + // The outer while loop should execute at most twice. + while (n < opt_length) { + // When we have no data in the block to top up, we can directly process the + // input buffer (assuming it contains sufficient data). This gives ~25% + // speedup on Chrome 23 and ~15% speedup on Firefox 16, but requires that + // the data is provided in large chunks (or in multiples of 64 bytes). + if (inbuf == 0) { + while (n <= lengthMinusBlock) { + this.compress_(bytes, n); + n += this.blockSize; + } + } + if (typeof bytes === 'string') { + while (n < opt_length) { + buf[inbuf] = bytes.charCodeAt(n); + ++inbuf; + ++n; + if (inbuf == this.blockSize) { + this.compress_(buf); + inbuf = 0; + // Jump to the outer loop so we use the full-block optimization. + break; + } + } + } + else { + while (n < opt_length) { + buf[inbuf] = bytes[n]; + ++inbuf; + ++n; + if (inbuf == this.blockSize) { + this.compress_(buf); + inbuf = 0; + // Jump to the outer loop so we use the full-block optimization. + break; + } + } + } + } + this.inbuf_ = inbuf; + this.total_ += opt_length; + }; + /** @override */ + Sha1.prototype.digest = function () { + var digest = []; + var totalBits = this.total_ * 8; + // Add pad 0x80 0x00*. + if (this.inbuf_ < 56) { + this.update(this.pad_, 56 - this.inbuf_); + } + else { + this.update(this.pad_, this.blockSize - (this.inbuf_ - 56)); + } + // Add # bits. + for (var i = this.blockSize - 1; i >= 56; i--) { + this.buf_[i] = totalBits & 255; + totalBits /= 256; // Don't use bit-shifting here! + } + this.compress_(this.buf_); + var n = 0; + for (var i = 0; i < 5; i++) { + for (var j = 24; j >= 0; j -= 8) { + digest[n] = (this.chain_[i] >> j) & 255; + ++n; + } + } + return digest; + }; + return Sha1; +}(Hash)); + +/** + * Helper to make a Subscribe function (just like Promise helps make a + * Thenable). + * + * @param executor Function which can make calls to a single Observer + * as a proxy. + * @param onNoObservers Callback when count of Observers goes to zero. + */ +function createSubscribe(executor, onNoObservers) { + var proxy = new ObserverProxy(executor, onNoObservers); + return proxy.subscribe.bind(proxy); +} +/** + * Implement fan-out for any number of Observers attached via a subscribe + * function. + */ +var ObserverProxy = /** @class */ (function () { + /** + * @param executor Function which can make calls to a single Observer + * as a proxy. + * @param onNoObservers Callback when count of Observers goes to zero. + */ + function ObserverProxy(executor, onNoObservers) { + var _this = this; + this.observers = []; + this.unsubscribes = []; + this.observerCount = 0; + // Micro-task scheduling by calling task.then(). + this.task = Promise.resolve(); + this.finalized = false; + this.onNoObservers = onNoObservers; + // Call the executor asynchronously so subscribers that are called + // synchronously after the creation of the subscribe function + // can still receive the very first value generated in the executor. + this.task + .then(function () { + executor(_this); + }) + .catch(function (e) { + _this.error(e); + }); + } + ObserverProxy.prototype.next = function (value) { + this.forEachObserver(function (observer) { + observer.next(value); + }); + }; + ObserverProxy.prototype.error = function (error) { + this.forEachObserver(function (observer) { + observer.error(error); + }); + this.close(error); + }; + ObserverProxy.prototype.complete = function () { + this.forEachObserver(function (observer) { + observer.complete(); + }); + this.close(); + }; + /** + * Subscribe function that can be used to add an Observer to the fan-out list. + * + * - We require that no event is sent to a subscriber sychronously to their + * call to subscribe(). + */ + ObserverProxy.prototype.subscribe = function (nextOrObserver, error, complete) { + var _this = this; + var observer; + if (nextOrObserver === undefined && + error === undefined && + complete === undefined) { + throw new Error('Missing Observer.'); + } + // Assemble an Observer object when passed as callback functions. + if (implementsAnyMethods(nextOrObserver, ['next', 'error', 'complete'])) { + observer = nextOrObserver; + } + else { + observer = { + next: nextOrObserver, + error: error, + complete: complete + }; + } + if (observer.next === undefined) { + observer.next = noop; + } + if (observer.error === undefined) { + observer.error = noop; + } + if (observer.complete === undefined) { + observer.complete = noop; + } + var unsub = this.unsubscribeOne.bind(this, this.observers.length); + // Attempt to subscribe to a terminated Observable - we + // just respond to the Observer with the final error or complete + // event. + if (this.finalized) { + this.task.then(function () { + try { + if (_this.finalError) { + observer.error(_this.finalError); + } + else { + observer.complete(); + } + } + catch (e) { + // nothing + } + return; + }); + } + this.observers.push(observer); + return unsub; + }; + // Unsubscribe is synchronous - we guarantee that no events are sent to + // any unsubscribed Observer. + ObserverProxy.prototype.unsubscribeOne = function (i) { + if (this.observers === undefined || this.observers[i] === undefined) { + return; + } + delete this.observers[i]; + this.observerCount -= 1; + if (this.observerCount === 0 && this.onNoObservers !== undefined) { + this.onNoObservers(this); + } + }; + ObserverProxy.prototype.forEachObserver = function (fn) { + if (this.finalized) { + // Already closed by previous event....just eat the additional values. + return; + } + // Since sendOne calls asynchronously - there is no chance that + // this.observers will become undefined. + for (var i = 0; i < this.observers.length; i++) { + this.sendOne(i, fn); + } + }; + // Call the Observer via one of it's callback function. We are careful to + // confirm that the observe has not been unsubscribed since this asynchronous + // function had been queued. + ObserverProxy.prototype.sendOne = function (i, fn) { + var _this = this; + // Execute the callback asynchronously + this.task.then(function () { + if (_this.observers !== undefined && _this.observers[i] !== undefined) { + try { + fn(_this.observers[i]); + } + catch (e) { + // Ignore exceptions raised in Observers or missing methods of an + // Observer. + // Log error to console. b/31404806 + if (typeof console !== 'undefined' && console.error) { + console.error(e); + } + } + } + }); + }; + ObserverProxy.prototype.close = function (err) { + var _this = this; + if (this.finalized) { + return; + } + this.finalized = true; + if (err !== undefined) { + this.finalError = err; + } + // Proxy is no longer needed - garbage collect references + this.task.then(function () { + _this.observers = undefined; + _this.onNoObservers = undefined; + }); + }; + return ObserverProxy; +}()); +/** Turn synchronous function into one called asynchronously. */ +function async(fn, onError) { + return function () { + var args = []; + for (var _i = 0; _i < arguments.length; _i++) { + args[_i] = arguments[_i]; + } + Promise.resolve(true) + .then(function () { + fn.apply(void 0, args); + }) + .catch(function (error) { + if (onError) { + onError(error); + } + }); + }; +} +/** + * Return true if the object passed in implements any of the named methods. + */ +function implementsAnyMethods(obj, methods) { + if (typeof obj !== 'object' || obj === null) { + return false; + } + for (var _i = 0, methods_1 = methods; _i < methods_1.length; _i++) { + var method = methods_1[_i]; + if (method in obj && typeof obj[method] === 'function') { + return true; + } + } + return false; +} +function noop() { + // do nothing +} + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +/** + * Check to make sure the appropriate number of arguments are provided for a public function. + * Throws an error if it fails. + * + * @param {!string} fnName The function name + * @param {!number} minCount The minimum number of arguments to allow for the function call + * @param {!number} maxCount The maximum number of argument to allow for the function call + * @param {!number} argCount The actual number of arguments provided. + */ +var validateArgCount = function (fnName, minCount, maxCount, argCount) { + var argError; + if (argCount < minCount) { + argError = 'at least ' + minCount; + } + else if (argCount > maxCount) { + argError = maxCount === 0 ? 'none' : 'no more than ' + maxCount; + } + if (argError) { + var error = fnName + + ' failed: Was called with ' + + argCount + + (argCount === 1 ? ' argument.' : ' arguments.') + + ' Expects ' + + argError + + '.'; + throw new Error(error); + } +}; +/** + * Generates a string to prefix an error message about failed argument validation + * + * @param {!string} fnName The function name + * @param {!number} argumentNumber The index of the argument + * @param {boolean} optional Whether or not the argument is optional + * @return {!string} The prefix to add to the error thrown for validation. + */ +function errorPrefix(fnName, argumentNumber, optional) { + var argName = ''; + switch (argumentNumber) { + case 1: + argName = optional ? 'first' : 'First'; + break; + case 2: + argName = optional ? 'second' : 'Second'; + break; + case 3: + argName = optional ? 'third' : 'Third'; + break; + case 4: + argName = optional ? 'fourth' : 'Fourth'; + break; + default: + throw new Error('errorPrefix called with argumentNumber > 4. Need to update it?'); + } + var error = fnName + ' failed: '; + error += argName + ' argument '; + return error; +} +/** + * @param {!string} fnName + * @param {!number} argumentNumber + * @param {!string} namespace + * @param {boolean} optional + */ +function validateNamespace(fnName, argumentNumber, namespace, optional) { + if (optional && !namespace) + return; + if (typeof namespace !== 'string') { + //TODO: I should do more validation here. We only allow certain chars in namespaces. + throw new Error(errorPrefix(fnName, argumentNumber, optional) + + 'must be a valid firebase namespace.'); + } +} +function validateCallback(fnName, argumentNumber, callback, optional) { + if (optional && !callback) + return; + if (typeof callback !== 'function') + throw new Error(errorPrefix(fnName, argumentNumber, optional) + + 'must be a valid function.'); +} +function validateContextObject(fnName, argumentNumber, context, optional) { + if (optional && !context) + return; + if (typeof context !== 'object' || context === null) + throw new Error(errorPrefix(fnName, argumentNumber, optional) + + 'must be a valid context object.'); +} + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +// Code originally came from goog.crypt.stringToUtf8ByteArray, but for some reason they +// automatically replaced '\r\n' with '\n', and they didn't handle surrogate pairs, +// so it's been modified. +// Note that not all Unicode characters appear as single characters in JavaScript strings. +// fromCharCode returns the UTF-16 encoding of a character - so some Unicode characters +// use 2 characters in Javascript. All 4-byte UTF-8 characters begin with a first +// character in the range 0xD800 - 0xDBFF (the first character of a so-called surrogate +// pair). +// See http://www.ecma-international.org/ecma-262/5.1/#sec-15.1.3 +/** + * @param {string} str + * @return {Array} + */ +var stringToByteArray$1 = function (str) { + var out = [], p = 0; + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i); + // Is this the lead surrogate in a surrogate pair? + if (c >= 0xd800 && c <= 0xdbff) { + var high = c - 0xd800; // the high 10 bits. + i++; + assert(i < str.length, 'Surrogate pair missing trail surrogate.'); + var low = str.charCodeAt(i) - 0xdc00; // the low 10 bits. + c = 0x10000 + (high << 10) + low; + } + if (c < 128) { + out[p++] = c; + } + else if (c < 2048) { + out[p++] = (c >> 6) | 192; + out[p++] = (c & 63) | 128; + } + else if (c < 65536) { + out[p++] = (c >> 12) | 224; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; + } + else { + out[p++] = (c >> 18) | 240; + out[p++] = ((c >> 12) & 63) | 128; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; + } + } + return out; +}; +/** + * Calculate length without actually converting; useful for doing cheaper validation. + * @param {string} str + * @return {number} + */ +var stringLength = function (str) { + var p = 0; + for (var i = 0; i < str.length; i++) { + var c = str.charCodeAt(i); + if (c < 128) { + p++; + } + else if (c < 2048) { + p += 2; + } + else if (c >= 0xd800 && c <= 0xdbff) { + // Lead surrogate of a surrogate pair. The pair together will take 4 bytes to represent. + p += 4; + i++; // skip trail surrogate. + } + else { + p += 3; + } + } + return p; +}; + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +exports.assert = assert; +exports.assertionError = assertionError; +exports.base64 = base64; +exports.base64Decode = base64Decode; +exports.base64Encode = base64Encode; +exports.CONSTANTS = CONSTANTS; +exports.deepCopy = deepCopy; +exports.deepExtend = deepExtend; +exports.patchProperty = patchProperty; +exports.Deferred = Deferred; +exports.getUA = getUA; +exports.isMobileCordova = isMobileCordova; +exports.isNodeSdk = isNodeSdk; +exports.isReactNative = isReactNative; +exports.ErrorFactory = ErrorFactory; +exports.FirebaseError = FirebaseError; +exports.patchCapture = patchCapture; +exports.jsonEval = jsonEval; +exports.stringify = stringify; +exports.decode = decode; +exports.isAdmin = isAdmin; +exports.issuedAtTime = issuedAtTime; +exports.isValidFormat = isValidFormat; +exports.isValidTimestamp = isValidTimestamp; +exports.clone = clone; +exports.contains = contains; +exports.every = every; +exports.extend = extend; +exports.findKey = findKey; +exports.findValue = findValue; +exports.forEach = forEach; +exports.getAnyKey = getAnyKey; +exports.getCount = getCount; +exports.getValues = getValues; +exports.isEmpty = isEmpty; +exports.isNonNullObject = isNonNullObject; +exports.map = map; +exports.safeGet = safeGet; +exports.querystring = querystring; +exports.querystringDecode = querystringDecode; +exports.Sha1 = Sha1; +exports.async = async; +exports.createSubscribe = createSubscribe; +exports.errorPrefix = errorPrefix; +exports.validateArgCount = validateArgCount; +exports.validateCallback = validateCallback; +exports.validateContextObject = validateContextObject; +exports.validateNamespace = validateNamespace; +exports.stringLength = stringLength; +exports.stringToByteArray = stringToByteArray$1; + +},{"tslib":31}],5:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * @@ -32,7 +5872,7 @@ var ExecutionEnvironment = { }; module.exports = ExecutionEnvironment; -},{}],2:[function(require,module,exports){ +},{}],6:[function(require,module,exports){ "use strict"; /** @@ -62,7 +5902,7 @@ function camelize(string) { } module.exports = camelize; -},{}],3:[function(require,module,exports){ +},{}],7:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * @@ -100,7 +5940,7 @@ function camelizeStyleName(string) { } module.exports = camelizeStyleName; -},{"./camelize":2}],4:[function(require,module,exports){ +},{"./camelize":6}],8:[function(require,module,exports){ 'use strict'; /** @@ -138,7 +5978,7 @@ function containsNode(outerNode, innerNode) { } module.exports = containsNode; -},{"./isTextNode":12}],5:[function(require,module,exports){ +},{"./isTextNode":16}],9:[function(require,module,exports){ "use strict"; /** @@ -175,7 +6015,7 @@ emptyFunction.thatReturnsArgument = function (arg) { }; module.exports = emptyFunction; -},{}],6:[function(require,module,exports){ +},{}],10:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2013-present, Facebook, Inc. @@ -195,7 +6035,7 @@ if (process.env.NODE_ENV !== 'production') { module.exports = emptyObject; }).call(this,require('_process')) -},{"_process":27}],7:[function(require,module,exports){ +},{"_process":35}],11:[function(require,module,exports){ 'use strict'; /** @@ -232,7 +6072,7 @@ function getActiveElement(doc) /*?DOMElement*/{ } module.exports = getActiveElement; -},{}],8:[function(require,module,exports){ +},{}],12:[function(require,module,exports){ 'use strict'; /** @@ -263,7 +6103,7 @@ function hyphenate(string) { } module.exports = hyphenate; -},{}],9:[function(require,module,exports){ +},{}],13:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * @@ -300,7 +6140,7 @@ function hyphenateStyleName(string) { } module.exports = hyphenateStyleName; -},{"./hyphenate":8}],10:[function(require,module,exports){ +},{"./hyphenate":12}],14:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2013-present, Facebook, Inc. @@ -356,7 +6196,7 @@ function invariant(condition, format, a, b, c, d, e, f) { module.exports = invariant; }).call(this,require('_process')) -},{"_process":27}],11:[function(require,module,exports){ +},{"_process":35}],15:[function(require,module,exports){ 'use strict'; /** @@ -379,7 +6219,7 @@ function isNode(object) { } module.exports = isNode; -},{}],12:[function(require,module,exports){ +},{}],16:[function(require,module,exports){ 'use strict'; /** @@ -402,7 +6242,7 @@ function isTextNode(object) { } module.exports = isTextNode; -},{"./isNode":11}],13:[function(require,module,exports){ +},{"./isNode":15}],17:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * @@ -468,7 +6308,7 @@ function shallowEqual(objA, objB) { } module.exports = shallowEqual; -},{}],14:[function(require,module,exports){ +},{}],18:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2014-present, Facebook, Inc. @@ -533,7 +6373,54 @@ if (process.env.NODE_ENV !== 'production') { module.exports = warning; }).call(this,require('_process')) -},{"./emptyFunction":5,"_process":27}],15:[function(require,module,exports){ +},{"./emptyFunction":9,"_process":35}],19:[function(require,module,exports){ +'use strict'; + +function _interopDefault (ex) { return (ex && (typeof ex === 'object') && 'default' in ex) ? ex['default'] : ex; } + +require('@firebase/polyfill'); +var firebase = _interopDefault(require('@firebase/app')); + +/** + * Copyright 2018 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +module.exports = firebase; + +},{"@firebase/app":1,"@firebase/polyfill":3}],20:[function(require,module,exports){ +'use strict'; + +require('@firebase/messaging'); + +/** + * Copyright 2017 Google Inc. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +},{"@firebase/messaging":2}],21:[function(require,module,exports){ /* object-assign (c) Sindre Sorhus @@ -625,7 +6512,7 @@ module.exports = shouldUseNative() ? Object.assign : function (target, source) { return to; }; -},{}],16:[function(require,module,exports){ +},{}],22:[function(require,module,exports){ (function (process){ /** * Copyright (c) 2013-present, Facebook, Inc. @@ -720,7 +6607,7 @@ function checkPropTypes(typeSpecs, values, location, componentName, getStack) { module.exports = checkPropTypes; }).call(this,require('_process')) -},{"./lib/ReactPropTypesSecret":17,"_process":27}],17:[function(require,module,exports){ +},{"./lib/ReactPropTypesSecret":23,"_process":35}],23:[function(require,module,exports){ /** * Copyright (c) 2013-present, Facebook, Inc. * @@ -734,7 +6621,7 @@ var ReactPropTypesSecret = 'SECRET_DO_NOT_PASS_THIS_OR_YOU_WILL_BE_FIRED'; module.exports = ReactPropTypesSecret; -},{}],18:[function(require,module,exports){ +},{}],24:[function(require,module,exports){ (function (process){ /** @license React v16.4.2 * react-dom.development.js @@ -18169,7 +24056,7 @@ module.exports = reactDom; } }).call(this,require('_process')) -},{"_process":27,"fbjs/lib/ExecutionEnvironment":1,"fbjs/lib/camelizeStyleName":3,"fbjs/lib/containsNode":4,"fbjs/lib/emptyFunction":5,"fbjs/lib/emptyObject":6,"fbjs/lib/getActiveElement":7,"fbjs/lib/hyphenateStyleName":9,"fbjs/lib/invariant":10,"fbjs/lib/shallowEqual":13,"fbjs/lib/warning":14,"object-assign":15,"prop-types/checkPropTypes":16,"react":23}],19:[function(require,module,exports){ +},{"_process":35,"fbjs/lib/ExecutionEnvironment":5,"fbjs/lib/camelizeStyleName":7,"fbjs/lib/containsNode":8,"fbjs/lib/emptyFunction":9,"fbjs/lib/emptyObject":10,"fbjs/lib/getActiveElement":11,"fbjs/lib/hyphenateStyleName":13,"fbjs/lib/invariant":14,"fbjs/lib/shallowEqual":17,"fbjs/lib/warning":18,"object-assign":21,"prop-types/checkPropTypes":22,"react":29}],25:[function(require,module,exports){ /** @license React v16.4.2 * react-dom.production.min.js * @@ -18411,7 +24298,7 @@ var wi={createPortal:vi,findDOMNode:function(a){return null==a?null:1===a.nodeTy arguments)},unstable_batchedUpdates:ci,unstable_deferredUpdates:Ih,unstable_interactiveUpdates:fi,flushSync:ei,unstable_flushControlled:gi,__SECRET_INTERNALS_DO_NOT_USE_OR_YOU_WILL_BE_FIRED:{EventPluginHub:Ka,EventPluginRegistry:va,EventPropagators:$a,ReactControlledComponent:Rb,ReactDOMComponentTree:Qa,ReactDOMEventListener:Od},unstable_createRoot:function(a,b){return new ri(a,!0,null!=b&&!0===b.hydrate)}};li({findFiberByHostInstance:Na,bundleType:0,version:"16.4.2",rendererPackageName:"react-dom"}); var Bi={default:wi},Ci=Bi&&wi||Bi;module.exports=Ci.default?Ci.default:Ci; -},{"fbjs/lib/ExecutionEnvironment":1,"fbjs/lib/containsNode":4,"fbjs/lib/emptyFunction":5,"fbjs/lib/emptyObject":6,"fbjs/lib/getActiveElement":7,"fbjs/lib/invariant":10,"fbjs/lib/shallowEqual":13,"object-assign":15,"react":23}],20:[function(require,module,exports){ +},{"fbjs/lib/ExecutionEnvironment":5,"fbjs/lib/containsNode":8,"fbjs/lib/emptyFunction":9,"fbjs/lib/emptyObject":10,"fbjs/lib/getActiveElement":11,"fbjs/lib/invariant":14,"fbjs/lib/shallowEqual":17,"object-assign":21,"react":29}],26:[function(require,module,exports){ (function (process){ 'use strict'; @@ -18453,7 +24340,7 @@ if (process.env.NODE_ENV === 'production') { } }).call(this,require('_process')) -},{"./cjs/react-dom.development.js":18,"./cjs/react-dom.production.min.js":19,"_process":27}],21:[function(require,module,exports){ +},{"./cjs/react-dom.development.js":24,"./cjs/react-dom.production.min.js":25,"_process":35}],27:[function(require,module,exports){ (function (process){ /** @license React v16.5.1 * react.development.js @@ -20183,7 +26070,7 @@ module.exports = react; } }).call(this,require('_process')) -},{"_process":27,"object-assign":15,"prop-types/checkPropTypes":16}],22:[function(require,module,exports){ +},{"_process":35,"object-assign":21,"prop-types/checkPropTypes":22}],28:[function(require,module,exports){ /** @license React v16.5.1 * react.production.min.js * @@ -20209,7 +26096,7 @@ _currentValue:a,_currentValue2:a,Provider:null,Consumer:null,unstable_read:null} var k=void 0;a.type&&a.type.defaultProps&&(k=a.type.defaultProps);for(c in b)J.call(b,c)&&!K.hasOwnProperty(c)&&(e[c]=void 0===b[c]&&void 0!==k?k[c]:b[c])}c=arguments.length-2;if(1===c)e.children=d;else if(1"},close:function(){return""}},EM:{open:function(){return""},close:function(){return""}},DL:{open:function(){return""},close:function(){return""}},CO:{open:function(){return""},close:function(){return""}},BR:{open:function(){return""},close:function(){return"
"}},LN:{open:function(e){return''},close:function(e){return""},props:function(e){return{href:e.url,target:"_blank"}}},MN:{open:function(e){return''},close:function(e){return""},props:function(e){return{name:e.val}}},HT:{open:function(e){return''},close:function(e){return""},props:function(e){return{name:e.val}}},IM:{open:function(e){var t=i(e.val,e.mime),n=e.ref?e.ref:t,s=(e.name?'':"")+'';return console.log("open: "+s),s},close:function(e){return e.name?"":""},props:function(e){return{src:i(e.val,e.mime),title:e.name,"data-width":e.width,"data-height":e.height,"data-name":e.name,"data-size":.75*e.val.length|0,"data-mime":e.mime}}}},a=function(){};a.parse=function(e){if("string"!=typeof e)return null;var s=e.split(/\r?\n/),i=[],r={},a=[];s.map(function(e){var s,o,c=[];if(t.map(function(t){c=c.concat(function(e,t,n,s){for(var i=[],r=0,a=e.slice(0);a.length>0;){var o=t.exec(a);if(null==o)break;var c=o.index+o[0].lastIndexOf(o[1]);a=a.slice(c+1),r=(c+=r)+1;var u=n?n.exec(a):null;if(null==u)break;var h=u.index+u[0].indexOf(u[1]);a=a.slice(h+1),r=(h+=r)+1,i.push({text:e.slice(c+1,h),children:[],start:c,end:h,type:s})}return i}(e,t.start,t.end,t.name))}),0==c.length)o={txt:e};else{c.sort(function(e,t){return e.start-t.start}),c=function e(t){if(0==t.length)return[];for(var n=[t[0]],s=t[0],i=1;is.end?(n.push(t[i]),s=t[i]):t[i].endn&&r.push({text:t.slice(n,o.start)});var c={type:o.type},u=e(t,o.start+1,o.end-1,o.children);u.length>0?c.children=u:c.text=o.text,r.push(c),n=o.end+1}return ni;return i=e.offset+e.len,t})}(o.txt)).length>0){var h=[];for(var l in s){var d=s[l],f=r[d.unique];f||(f=i.length,r[d.unique]=f,i.push({tp:d.type,data:d.data})),h.push({at:d.offset,len:d.len,key:f})}o.ent=h}a.push(o)});var o={txt:""};if(a.length>0){o.txt=a[0].txt,o.fmt=(a[0].fmt||[]).concat(a[0].ent||[]);for(var c=1;c0&&(o.ent=i)}return o},a.insertImage=function(e,t,n,s,i,r,a,o,c){return(e=e||{txt:" "}).ent=e.ent||[],e.fmt=e.fmt||[],e.fmt.push({at:t,len:1,key:e.ent.length}),e.ent.push({tp:"IM",data:{mime:n,val:s,width:i,height:r,name:a,ref:c,size:0|o}}),e},a.attachFile=function(e,t,n,s,i,r){(e=e||{txt:""}).ent=e.ent||[],e.fmt=e.fmt||[],e.fmt.push({at:-1,len:0,key:e.ent.length});let a={tp:"EX",data:{mime:t,val:n,name:s,ref:r,size:0|i}};return r instanceof Promise&&(a.data.ref=r.then(e=>{a.data.ref=e},e=>{})),e.ent.push(a),e},a.UNSAFE_toHTML=function(e){var t,n,s,{txt:i,fmt:a,ent:o}=e,c=[];if(a)for(var u in a){var h,l=a[u],d=l.tp;if(!d){var f=o[l.key];f&&(d=f.tp,h=f.data)}r[d]&&(c.push({idx:l.at+l.len,what:r[d].close(h)}),c.push({idx:l.at,what:r[d].open(h)}))}for(var u in c.sort(function(e,t){return t.idx-e.idx}),c)c[u].what&&(t=i,n=c[u].idx,s=c[u].what,i=t.slice(0,n)+s+t.slice(n));return i},a.format=function(e,t,n){var{txt:i,fmt:r,ent:a}=e;if(i=i||"",!r)return[i];var o=[].concat(r);return o.map(function(e){e.at=e.at||0,e.len=e.len||0}),o.sort(function(e,t){return e.at-t.at==0?t.len-e.len:e.at-t.at}),o=o.map(function(e){var t,n=e.tp;return n||(e.key=e.key||0,t=a[e.key].data,n=a[e.key].tp),{tp:n,data:t,at:e.at,len:e.len}}),function e(t,n,i,r,a,o){for(var c=[],u=0;u0)for(var t in e.ent)if("EX"==e.ent[t].tp)return!0;return!1},a.attachments=function(e,t,n){if(e.ent&&e.ent.length>0)for(var s in e.ent)"EX"==e.ent[s].tp&&t.call(n,e.ent[s].data,s)},a.getDownloadUrl=function(e){let t=null;return e.val?t=i(e.val,e.mime):"string"==typeof e.ref&&(t=e.ref),t},a.isUploading=function(e){return e.ref instanceof Promise},a.getPreviewUrl=function(e){return e.val?i(e.val,e.mime):null},a.getEntitySize=function(e){return e.size?e.size:e.val?.75*e.val.length|0:0},a.getEntityMimeType=function(e){return e.mime||"text/plain"},a.tagName=function(e){return s[e]?s[e].name:void 0},a.attrValue=function(e,t){if(t&&r[e])return r[e].props(t)},a.getContentType=function(){return"text/x-drafty"},e=a;var o={};if("function"==typeof require)var c="0.15.6-rc3";const u="0",h=c||"0.15",l="tinodejs/"+h;function d(e){return btoa(encodeURIComponent(e).replace(/%([0-9A-F]{2})/g,function(e,t){return String.fromCharCode("0x"+t)}))}function f(e,t,n){if(null==t)return e;if("object"!=typeof t)return t||e;if(t instanceof Date)return t;if(t instanceof S)return new S(t);if(t instanceof Array)return t.length>0?t:e;for(var s in e||(e=t.constructor()),t)!t.hasOwnProperty(s)||!t[s]&&!1!==t[s]||n&&n[s]||"_generated"==s||(e[s]=f(e[s],t[s]));return e}function p(e,t,n,s){return e[t]=f(e[t],n,s),e[t]}function g(){var e=null;if("withCredentials"in new XMLHttpRequest)e=new XMLHttpRequest;else{if("undefined"==typeof XDomainRequest)throw new Error("browser not supported");e=new XDomainRequest}return e}function _(e,t){if("ts"===e&&"string"==typeof t&&t.length>=20&&t.length<=24){var n=new Date(t);if(n)return n}else if("acs"===e&&"object"==typeof t)return new S(t);return t}function m(e,t){return"string"==typeof t&&t.length>128?"<"+t.length+", bytes: "+t.substring(0,12)+"..."+t.substring(t.length-12)+">":function(e,t){if(t instanceof Date)t=function(e){if(e&&0!=e.getTime()){var t=e.getUTCMilliseconds();return e.getUTCFullYear()+"-"+n(e.getUTCMonth()+1)+"-"+n(e.getUTCDate())+"T"+n(e.getUTCHours())+":"+n(e.getUTCMinutes())+":"+n(e.getUTCSeconds())+(t?"."+n(t,3):"")+"Z"}function n(e,t){return"0".repeat((t=t||2)-(""+e).length)+e}}(t);else if(null==t||!1===t||Array.isArray(t)&&0==t.length||"object"==typeof t&&0===Object.keys(t).length)return;return t}(0,t)}function v(e,t,n){var s=null;return"http"!==t&&"https"!==t&&"ws"!==t&&"wss"!==t||(s=t+"://","/"!==(s+=e).charAt(s.length-1)&&(s+="/"),s+="v"+u+"/channels","http"!==t&&"https"!==t||(s+="/lp"),s+="?apikey="+n),s}var b=function(e,t,n,s,i){let r=e,a=s,o=t;var c=i;const u=2e3,h=10,l=.3;let d=null,f=0,p=!1,m=e=>{this.logger&&this.logger(e)};function b(e){var t=null;e.connect=function(n){return t&&1===t.readyState?Promise.resolve():(n&&(r=n),new Promise(function(n,s){var i=v(r,a?"wss":"ws",o);m("Connecting to: "+i);var g=new WebSocket(i);g.onopen=function(t){p=!1,e.onOpen&&e.onOpen(),n(),c&&(window.clearTimeout(d),d=null,f=0)},g.onclose=function(n){t=null,e.onDisconnect&&e.onDisconnect(null),!p&&c&&function(){clearTimeout(d);var e=u*(Math.pow(2,f)*(1+l*Math.random()));f=f>=h?f:f+1,d=setTimeout(()=>{m("Reconnecting, iter="+f+", timeout="+e),p||this.connect().catch(function(){})},e)}.call(e)},g.onerror=function(e){s(e)},g.onmessage=function(t){e.onMessage&&e.onMessage(t.data)},t=g}))},e.disconnect=function(){t&&(p=!0,t.close()),t=null},e.sendText=function(e){if(!t||t.readyState!=t.OPEN)throw new Error("Websocket is not connected");t.send(e)},e.isConnected=function(){return t&&1===t.readyState}}function w(e){var t=null,n=null,s=null;e.connect=function(s){return s&&(r=s),new Promise(function(s,i){var c=v(r,a?"https":"http",o);m("Connecting to: "+c),(n=function n(s,i,r){var a=g();return a.onreadystatechange=function(o){if(4==a.readyState)if(201==a.status){var c=JSON.parse(a.responseText,_);a.responseText,t=s+"&sid="+c.ctrl.params.sid,(a=n(t)).send(null),e.onOpen&&e.onOpen(),i&&i()}else 200==a.status?(e.onMessage&&e.onMessage(a.responseText),(a=n(t)).send(null)):(r&&r(a.responseText),e.onMessage&&e.onMessage(a.responseText),e.onDisconnect&&e.onDisconnect(new Error(a.status+" "+a.responseText)))},a.open("GET",s,!0),a}(c,s,i)).send(null)}).catch(function(){})},e.disconnect=function(){s&&(s.abort(),s=null),n&&(n.abort(),n=null),e.onDisconnect&&e.onDisconnect(null),t=null},e.sendText=function(e){var n,i;if(n=t,(i=g()).onreadystatechange=function(e){if(4==i.readyState&&i.status>=400)throw new Error("LP sender failed, "+i.status)},i.open("POST",n,!0),!(s=i)||1!=s.readyState)throw new Error("Long poller failed to connect");s.send(e)},e.isConnected=function(){return n&&!0}}"lp"===n?w(this):"ws"===n?b(this):"object"==typeof window&&window.WebSocket?b(this):w(this),this.onMessage=void 0,this.onDisconnect=void 0,this.onOpen=void 0,this.logger=void 0},w=function(e,t,n,s,i){this._appName=e||"Undefined",this._apiKey=n,this._browser="",this._platform="undefined","undefined"!=typeof navigator&&(this._browser=function(e){var t,n=(e=(e||"").replace(" (KHTML, like Gecko)","")).match(/(AppleWebKit\/[.\d]+)/i);if(n){for(var s=["chrome","safari","mobile","version"],i=e.substr(n.index+n[0].length).split(" "),r=[],a=0;a0?r[0][0]+"/"+r[0][1]:n[1]}else t=/trident/i.test(e)?(n=/(?:\brv[ :]+([.\d]+))|(?:\bMSIE ([.\d]+))/g.exec(e))?"MSIE/"+(n[1]||n[2]):"MSIE/?":/firefox/i.test(e)?(n=/Firefox\/([.\d]+)/g.exec(e))?"Firefox/"+n[1]:"Firefox/?":/presto/i.test(e)?(n=/Opera\/([.\d]+)/g.exec(e))?"Opera/"+n[1]:"Opera/?":(n=/([\w.]+)\/([.\d]+)/.exec(e))?n[1]+"/"+n[2]:(n=e.split(" "))[0];if((n=t.split("/")).length>1){var c=n[1].split(".");t=n[0]+"/"+c[0]+(c[1]?"."+c[1]:"")}return t}(navigator.userAgent),this._platform=navigator.platform),this._loggingEnabled=!1,this._trimLongStrings=!1,this._myUID=null,this._authenticated=!1,this._login=null,this._authToken=null,this._inPacketCount=0,this._messageId=Math.floor(65535*Math.random()+65535),this._serverInfo=null,this._pendingPromises={},this._connection=new b(t,n,s,i,!0),this.logger=(e=>{if(this._loggingEnabled){var t=new Date,n=("0"+t.getUTCHours()).slice(-2)+":"+("0"+t.getUTCMinutes()).slice(-2)+":"+("0"+t.getUTCSeconds()).slice(-2)+":"+("0"+t.getUTCMilliseconds()).slice(-3);console.log("["+n+"] "+e)}}),this._connection.logger=this.logger,this._cache={};let r=this.cachePut=((e,t,n)=>{this._cache[e+":"+t]=n}),a=this.cacheGet=((e,t)=>this._cache[e+":"+t]),o=this.cacheDel=((e,t)=>{delete this._cache[e+":"+t]}),c=this.cacheMap=((e,t)=>{for(var n in this._cache)if(e(this._cache[n],n,t))break});this.attachCacheToTopic=(e=>{e._tinode=this,e._cacheGetUser=(e=>{var t=a("user",e);if(t)return{user:e,public:f({},t)}}),e._cachePutUser=((e,t)=>r("user",e,f({},t.public))),e._cacheDelUser=(e=>o("user",e)),e._cachePutSelf=(()=>r("topic",e.name,e)),e._cacheDelSelf=(()=>o("topic",e.name))});let u=(e,t,n,s)=>{var i=this._pendingPromises[e];i&&(delete this._pendingPromises[e],t>=200&&t<400?i.resolve&&i.resolve(n):i.reject&&i.reject(new Error("Error: "+s+" ("+t+")")))},d=e=>{var t=null;return e&&(t=new Promise((t,n)=>{this._pendingPromises[e]={resolve:t,reject:n}})),t},p=this.getNextUniqueId=(()=>0!=this._messageId?""+this._messageId++:void 0),g=()=>this._appName+" ("+(this._browser?this._browser+"; ":"")+this._platform+"); "+l;this.initPacket=((e,t)=>{switch(e){case"hi":return{hi:{id:p(),ver:h,ua:g()}};case"acc":return{acc:{id:p(),user:null,scheme:null,secret:null,login:!1,tags:null,desc:{},cred:{}}};case"login":return{login:{id:p(),scheme:null,secret:null}};case"sub":return{sub:{id:p(),topic:t,set:{},get:{}}};case"leave":return{leave:{id:p(),topic:t,unsub:!1}};case"pub":return{pub:{id:p(),topic:t,noecho:!1,head:null,content:{}}};case"get":return{get:{id:p(),topic:t,what:null,desc:{},sub:{},data:{}}};case"set":return{set:{id:p(),topic:t,desc:{},sub:{},tags:[]}};case"del":return{del:{id:p(),topic:t,what:null,delseq:null,user:null,hard:!1}};case"note":return{note:{topic:t,what:null,seq:void 0}};default:throw new Error("Unknown packet type requested: "+e)}}),this.send=((e,t)=>{let n;t&&(n=d(t)),e=function e(t){return Object.keys(t).forEach(function(n){"_"==n[0]?delete t[n]:t[n]?Array.isArray(t[n])&&0==t[n].length?delete t[n]:t[n]?"object"!=typeof t[n]||t[n]instanceof Date||(e(t[n]),0==Object.getOwnPropertyNames(t[n]).length&&delete t[n]):delete t[n]:delete t[n]}),t}(e);var s=JSON.stringify(e);return this.logger("out: "+(this._trimLongStrings?JSON.stringify(e,m):s)),this._connection.sendText(s),n}),this.loginSuccessful=(e=>{this._myUID=e.params.user,this._authenticated=e&&e.code>=200&&e.code<300,e.params&&e.params.token&&e.params.expires?this._authToken={token:e.params.token,expires:new Date(e.params.expires)}:this._authToken=null,this.onLogin&&this.onLogin(e.code,e.text)}),this._connection.onMessage=(e=>{if(e){this._inPacketCount++,this.onRawMessage&&this.onRawMessage(e);var t=JSON.parse(e,_);if(t)if(this.logger("in: "+(this._trimLongStrings?JSON.stringify(t,m):e)),this.onMessage&&this.onMessage(t),t.ctrl)this.onCtrlMessage&&this.onCtrlMessage(t.ctrl),t.ctrl.id&&u(t.ctrl.id,t.ctrl.code,t.ctrl,t.ctrl.text),t.ctrl.params&&"data"==t.ctrl.params.what&&(n=a("topic",t.ctrl.topic))&&n._allMessagesReceived(t.ctrl.params.count);else if(t.meta)(n=a("topic",t.meta.topic))&&n._routeMeta(t.meta),this.onMetaMessage&&this.onMetaMessage(t.meta);else if(t.data)(n=a("topic",t.data.topic))&&n._routeData(t.data),this.onDataMessage&&this.onDataMessage(t.data);else if(t.pres)(n=a("topic",t.pres.topic))&&n._routePres(t.pres),this.onPresMessage&&this.onPresMessage(t.pres);else if(t.info){var n;(n=a("topic",t.info.topic))&&n._routeInfo(t.info),this.onInfoMessage&&this.onInfoMessage(t.info)}else this.logger("ERROR: Unknown packet received.");else this.logger("in: "+e),this.logger("ERROR: failed to parse data")}}),this._connection.onOpen=(()=>{this.hello()}),this._connection.onDisconnect=(e=>{this._inPacketCount=0,this._serverInfo=null,this._authenticated=!1,c((e,t)=>{0===t.lastIndexOf("topic:",0)&&e._resetSub()}),this.onDisconnect&&this.onDisconnect(e)})};w.credential=function(e,t,n,s){return"object"==typeof e&&({val:t,params:n,resp:s,meth:e}=e),e&&(t||s)?[{meth:e,val:t,resp:s,params:n}]:null},w.topicType=function(e){return{me:"me",fnd:"fnd",grp:"grp",new:"grp",usr:"p2p"}["string"==typeof e?e.substring(0,3):"xxx"]},w.isNewGroupTopicName=function(e){return"string"==typeof e&&"new"==e.substring(0,3)},w.getVersion=function(){return h},w.getLibrary=function(){return l},w.MESSAGE_STATUS_NONE=0,w.MESSAGE_STATUS_QUEUED=1,w.MESSAGE_STATUS_SENDING=2,w.MESSAGE_STATUS_SENT=3,w.MESSAGE_STATUS_RECEIVED=4,w.MESSAGE_STATUS_READ=5,w.MESSAGE_STATUS_TO_ME=6,w.DEL_CHAR="\u2421",w.prototype={connect:function(e){return this._connection.connect(e)},disconnect:function(){this._connection&&this._connection.disconnect()},isConnected:function(){return this._connection&&this._connection.isConnected()},isAuthenticated:function(){return this._authenticated},account:function(e,t,n,s,i){var r=this.initPacket("acc");return r.acc.user=e,r.acc.scheme=t,r.acc.secret=n,r.acc.login=s,i&&(r.acc.desc.defacs=i.defacs,r.acc.desc.public=i.public,r.acc.desc.private=i.private,r.acc.tags=i.tags,r.acc.cred=i.cred),this.send(r,r.acc.id)},createAccount:function(e,t,n,s){var i=this.account("new",e,t,n,s);return n&&(i=i.then(e=>(this.loginSuccessful(e),e))),i},createAccountBasic:function(e,t,n){return e=e||"",t=t||"",this.createAccount("basic",d(e+":"+t),!0,n)},updateAccountBasic:function(e,t,n){return t=t||"",n=n||"",this.account(e,"basic",d(t+":"+n),!1,null)},hello:function(){var e=this.initPacket("hi");return this.send(e,e.hi.id).then(e=>(e.params&&(this._serverInfo=e.params),this.onConnect&&this.onConnect(),e)).catch(e=>{this.onDisconnect&&this.onDisconnect(e)})},login:function(e,t,n){var s=this.initPacket("login");return s.login.scheme=e,s.login.secret=t,s.login.cred=n,this.send(s,s.login.id).then(e=>(this.loginSuccessful(e),e))},loginBasic:function(e,t,n){return this.login("basic",d(e+":"+t),n).then(t=>(this._login=e,t))},loginToken:function(e,t){return this.login("token",e,t)},getAuthToken:function(){return this._authToken&&this._authToken.expires.getTime()>Date.now()?this._authToken:(this._authToken=null,null)},setAuthToken:function(e){this._authToken=e},subscribe:function(e,t,n){var s=this.initPacket("sub",e);return e||(e="new"),s.sub.get=t,n&&(n.sub&&(s.sub.set.sub=n.sub),w.isNewGroupTopicName(e)&&n.desc&&(s.sub.set.desc=n.desc),n.tags&&(s.sub.set.tags=n.tags)),this.send(s,s.sub.id)},leave:function(e,t){var n=this.initPacket("leave",e);return n.leave.unsub=t,this.send(n,n.leave.id)},createMessage:function(t,n,s){let i=this.initPacket("pub",t),r="string"==typeof n?e.parse(n):n;return r&&!e.isPlainText(r)&&(i.pub.head={mime:e.getContentType()},n=r),i.pub.noecho=s,i.pub.content=n,i.pub},publish:function(e,t,n){return this.publishMessage(this.createMessage(e,t,n))},publishMessage:function(e){return(e=Object.assign({},e)).seq=void 0,e.from=void 0,e.ts=void 0,this.send({pub:e},e.id)},getMeta:function(e,t){var n=this.initPacket("get",e);return n.get=f(n.get,t),this.send(n,n.get.id)},setMeta:function(e,t){var n=this.initPacket("set",e),s=[];return t&&["desc","sub","tags"].map(function(e){t.hasOwnProperty(e)&&(s.push(e),n.set[e]=t[e])}),0==s.length?Promise.reject(new Error("Invalid {set} parameters")):this.send(n,n.set.id)},delMessages:function(e,t,n){var s=this.initPacket("del",e);return s.del.what="msg",s.del.delseq=t,s.del.hard=n,this.send(s,s.del.id)},delTopic:function(e){var t=this.initPacket("del",e);return t.del.what="topic",this.send(t,t.del.id).then(t=>(this.cacheDel("topic",e),this.ctrl))},delSubscription:function(e,t){var n=this.initPacket("del",e);return n.del.what="sub",n.del.user=t,this.send(n,n.del.id)},note:function(e,t,n){if(n<=0||n>=268435455)throw new Error("Invalid message id "+n);var s=this.initPacket("note",e);s.note.what=t,s.note.seq=n,this.send(s)},noteKeyPress:function(e){var t=this.initPacket("note",e);t.note.what="kp",this.send(t)},getTopic:function(e){var t=this.cacheGet("topic",e);return!t&&e&&(t="me"==e?new y:"fnd"==e?new D:new T(e),this.cachePut("topic",e,t),this.attachCacheToTopic(t)),t},newTopic:function(e){var t=new T("new",e);return this.attachCacheToTopic(t),t},newGroupTopicName:function(){return"new"+this.getNextUniqueId()},newTopicWith:function(e,t){var n=new T(e,t);return this.attachCacheToTopic(n),n},getMeTopic:function(){return this.getTopic("me")},getFndTopic:function(){return this.getTopic("fnd")},getLargeFileHelper:function(){return new E(this)},getCurrentUserID:function(){return this._myUID},getCurrentLogin:function(){return this._login},getServerInfo:function(){return this._serverInfo},enableLogging:function(e,t){this._loggingEnabled=e,this._trimLongStrings=t},isTopicOnline:function(e){var t=this.getMeTopic(),n=t&&t.getContact(e);return n&&n.online},wantAkn:function(e){this._messageId=e?Math.floor(16777215*Math.random()+16777215):0},onWebsocketOpen:void 0,onConnect:void 0,onDisconnect:void 0,onLogin:void 0,onCtrlMessage:void 0,onDataMessage:void 0,onPresMessage:void 0,onMessage:void 0,onRawMessage:void 0};var M=function(e){this.topic=e;var t=e._tinode.getMeTopic();this.contact=t&&t.getContact(e.name),this.what={}};M.prototype={_get_ims:function(){let e=this.contact&&this.contact.updated,t=this.topic._lastDescUpdate||0;return e>t?e:t},withData:function(e,t,n){return this.what.data={since:e,before:t,limit:n},this},withLaterData:function(e){return this.withData(this.topic._maxSeq>0?this.topic._maxSeq+1:void 0,void 0,e)},withEarlierData:function(e){return this.withData(void 0,this.topic._minSeq>0?this.topic._minSeq:void 0,e)},withDesc:function(e){return this.what.desc={ims:e},this},withLaterDesc:function(){return this.withDesc(this._get_ims())},withSub:function(e,t,n){var s={ims:e,limit:t};return"me"==this.topic.getType()?s.topic=n:s.user=n,this.what.sub=s,this},withOneSub:function(e,t){return this.withSub(e,void 0,t)},withLaterOneSub:function(e){return this.withOneSub(this.topic._lastSubsUpdate,e)},withLaterSub:function(e){return this.withSub("p2p"==this.topic.getType()?this._get_ims():this.topic._lastSubsUpdate,e)},withTags:function(){return this.what.tags=!0,this},withDel:function(e,t){return(e||t)&&(this.what.del={since:e,limit:t}),this},withLaterDel:function(e){return this.withDel(this.topic._maxSeq>0?this.topic._maxDel+1:void 0,e)},build:function(){var e={},t=[],n=this;return["data","sub","desc","tags","del"].map(function(s){n.what.hasOwnProperty(s)&&(t.push(s),Object.getOwnPropertyNames(n.what[s]).length>0&&(e[s]=n.what[s]))}),t.length>0?e.what=t.join(" "):e=void 0,e}};var S=function(e){e&&(this.given="number"==typeof e.given?e.given:S.decode(e.given),this.want="number"==typeof e.want?e.want:S.decode(e.want),this.mode=e.mode?"number"==typeof e.mode?e.mode:S.decode(e.mode):this.given&this.want)};S._NONE=0,S._JOIN=1,S._READ=2,S._WRITE=4,S._PRES=8,S._APPROVE=16,S._SHARE=32,S._DELETE=64,S._OWNER=128,S._BITMASK=S._JOIN|S._READ|S._WRITE|S._PRES|S._APPROVE|S._SHARE|S._DELETE|S._OWNER,S._INVALID=1048576,S.decode=function(e){if(!e)return null;if("number"==typeof e)return e&S._BITMASK;if("N"===e||"n"===e)return S._NONE;for(var t={J:S._JOIN,R:S._READ,W:S._WRITE,P:S._PRES,A:S._APPROVE,S:S._SHARE,D:S._DELETE,O:S._OWNER},n=S._NONE,s=0;s0)){c=!0;break}r=a-1}return c?a:s?-1:o<0?a+1:a}function s(e,t){var s=n(e,t,!1);return t.splice(s,0,e),t}return e=e||function(e,t){return e===t?0:e0)return n[0]},delRange:function(e,n){return t.splice(e,n-e)},size:function(){return t.length},reset:function(e){t=[]},forEach:function(e,n,s,i){n|=0,s=s||t.length;for(var r=n;r{if(e.code>=300)return e;if(this._subscribed=!0,this.acs=e.params&&e.params.acs?e.params.acs:this.acs,this._new){this._new=!1,this.name=e.topic,this.created=e.ts,this.updated=e.ts,this.touched=e.ts,this._cachePutSelf();var n=this._tinode.getMeTopic();n&&n._processMetaSub([{_generated:!0,topic:this.name,created:e.ts,updated:e.ts,touched:e.ts,acs:this.acs}]),t&&t.desc&&(t.desc._generated=!0,this._processMetaDesc(t.desc))}return e})},publish:function(e,t){return this.publishMessage(this.createMessage(e,t))},createMessage:function(e,t){return this._tinode.createMessage(this.name,e,t)},publishMessage:function(t){if(!this._subscribed)return Promise.reject(new Error("Cannot publish on inactive topic"));if(e.hasAttachments(t.content)){let n=[];e.attachments(t.content,e=>{n.push(e.ref)}),t.head.attachments=n}return t._sending=!0,this._tinode.publishMessage(t)},publishDraft:function(e,t){return t||this._subscribed?(e.seq=this._getQueuedSeqId(),e._generated=!0,e.ts=new Date,e.from=this._tinode.getCurrentUserID(),e.noecho=!0,this._messages.put(e),this.onData&&this.onData(e),(t||Promise.resolve()).then(()=>e._cancelled?{code:300,text:"cancelled"}:this.publishMessage(e).then(t=>(e._sending=!1,e.seq=t.params.seq,e.ts=t.ts,this._routeData(e),t)),t=>{e._sending=!1,this._messages.delAt(this._messages.find(e)),this.onData&&this.onData()})):Promise.reject(new Error("Cannot publish on inactive topic"))},leave:function(e){return this._subscribed||e?this._tinode.leave(this.name,e).then(t=>(this._resetSub(),e&&this._gone(),t)):Promise.reject(new Error("Cannot leave inactive topic"))},getMeta:function(e){return this._subscribed?this._tinode.getMeta(this.name,e):Promise.reject(new Error("Cannot query inactive topic"))},getMessagesPage:function(e,t){var n=this.startMetaQuery();t?n.withLaterData(e):n.withEarlierData(e);var s=this.getMeta(n.build());return t||(s=s.then(e=>{e&&e.params&&!e.params.count&&(this._noEarlierMsgs=!0)})),s},setMeta:function(e){return this._subscribed?(e.tags&&(e.tags=function(e){var t=[];if(Array.isArray(e)){for(var n=0,s=e.length;n1&&t.push(i)}t.sort().filter(function(e,t,n){return!t||e!=n[t-1]})}return 0==t.length&&t.push(w.DEL_CHAR),t}(e.tags)),this._tinode.setMeta(this.name,e).then(t=>t&&t.code>=300?t:(e.sub&&(t.params&&t.params.acs&&(e.sub.acs=t.params.acs,e.sub.updated=t.ts),e.sub.user||(e.sub.user=this._tinode.getCurrentUserID(),e.desc||(e.desc={})),e.sub._generated=!0,this._processMetaSub([e.sub])),e.desc&&(t.params&&t.params.acs&&(e.desc.acs=t.params.acs,e.desc.updated=t.ts),this._processMetaDesc(e.desc)),e.tags&&this._processMetaTags(e.tags),t))):Promise.reject(new Error("Cannot update inactive topic"))},invite:function(e,t){return this.setMeta({sub:{user:e,mode:t}})},delMessages:function(e,t){if(!this._subscribed)return Promise.reject(new Error("Cannot delete messages in inactive topic"));e.sort(function(e,t){return e.low=t.hi)});let n,s=e.reduce((e,t)=>(t.low<268435455&&(!t.hi||t.hi<268435455?e.push(t):e.push({low:t.low,hi:this._maxSeq+1})),e),[]);return(n=e.length>0?this._tinode.delMessages(this.name,s,t):Promise.resolve({params:{del:0}})).then(t=>(t.params.del>this._maxDel&&(this._maxDel=t.params.del),e.map(e=>{e.hi?this.flushMessageRange(e.low,e.hi):this.flushMessage(e.low)}),this.onData&&this.onData(),t))},delMessagesAll:function(e){return this.delMessages([{low:1,hi:this._maxSeq+1,_all:!0}],e)},delMessagesList:function(e,t){e.sort((e,t)=>e-t);var n=e.reduce((e,t)=>{if(0==e.length)e.push({low:t});else{let n=e[e.length-1];!n.hi&&t!=n.low+1||t>n.hi?e.push({low:t}):n.hi=n.hi?Math.max(n.hi,t+1):t+1}return e},[]);return this.delMessages(n,t)},delTopic:function(){var e=this;return this._tinode.delTopic(this.name).then(function(t){return e._resetSub(),e._gone(),t})},delSubscription:function(e){return this._subscribed?this._tinode.delSubscription(this.name,e).then(t=>(delete this._users[e],this.onSubsUpdated&&this.onSubsUpdated(Object.keys(this._users)),t)):Promise.reject(new Error("Cannot delete subscription in inactive topic"))},note:function(e,t){var n=this._users[this._tinode.getCurrentUserID()];n?((!n[e]||n[e]0)for(var i in this._users){var r=this._users[i];r.user!==s&&r[e]>=t&&n++}return n},msgReadCount:function(e){return this.msgReceiptCount("read",e)},msgRecvCount:function(e){return this.msgReceiptCount("recv",e)},msgHasMoreMessages:function(e){return e?this.seq>this._maxSeq:this._minSeq>1&&!this._noEarlierMsgs},isNewMessage:function(e){return this._maxSeq<=e},flushMessage:function(e){let t=this._messages.find({seq:e});return t>=0?this._messages.delAt(t):void 0},flushMessageRange:function(e,t){let n=this._messages.find({seq:e});return n>=0?this._messages.delRange(n,this._messages.find({seq:t},!0)):[]},cancelSend:function(e){let t=this._messages.find({seq:e});if(t>=0){let e=this._messages.getAt(t);if(1==this.msgStatus(e))return e._cancelled=!0,this._messages.delAt(t),!0}return!1},getType:function(){return w.topicType(this.name)},getAccessMode:function(){return this.acs},getDefaultAccess:function(){return this.defacs},startMetaQuery:function(){return new M(this)},msgStatus:function(e){var t=0;return e.from==this._tinode.getCurrentUserID()?e._sending?t=2:e.seq>=268435455?t=1:this.msgReadCount(e.seq)>0?t=5:this.msgRecvCount(e.seq)>0?t=4:e.seq>0&&(t=3):t=6,t},_routeData:function(e){e.content&&((!this.touched||this.touchedthis._maxSeq&&(this._maxSeq=e.seq),(e.seq0&&(this._lastSubsUpdate=e.ts,this._processMetaSub(e.sub)),e.del&&this._processDelMessages(e.del.clear,e.del.delseq),e.tags&&this._processMetaTags(e.tags),this.onMeta&&this.onMeta(e)},_routePres:function(e){var t;switch(e.what){case"del":this._processDelMessages(e.clear,e.delseq);break;case"on":case"off":(t=this._users[e.src])?t.online="on"==e.what:this._tinode.logger("Presence update for an unknown user",this.name,e.src);break;case"acs":let s="me"==e.src?this._tinode.getCurrentUserID():e.src;if(t=this._users[s])t.acs.updateAll(e.dacs),s==this._tinode.getCurrentUserID()&&this.acs.updateAll(e.dacs),t.acs&&t.acs.mode!=S._NONE||("p2p"==this.getType()&&this.leave(),this._processMetaSub([{user:s,deleted:new Date,_generated:!0}]));else{var n=(new S).updateAll(e.dacs);n&&n.mode!=S._NONE&&((t=this._cacheGetUser(s))?t.acs=n:(t={user:s,acs:n},this.getMeta(this.startMetaQuery().withOneSub(void 0,s).build())),t._generated=!0,t.updated=new Date,this._processMetaSub([t]))}break;default:this._tinode.logger("Ignored presence update",e.what)}this.onPres&&this.onPres(e)},_routeInfo:function(e){if("kp"!==e.what){var t=this._users[e.from];t&&(t[e.what]=e.seq)}this.onInfo&&this.onInfo(e)},_processMetaDesc:function(e,t){if(f(this,e),"string"==typeof this.created&&(this.created=new Date(this.created)),"string"==typeof this.updated&&(this.updated=new Date(this.updated)),"string"==typeof this.touched&&(this.touched=new Date(this.touched)),"me"!==this.name&&!t&&!e._generated){var n=this._tinode.getMeTopic();n&&n._processMetaSub([{_generated:!0,topic:this.name,updated:this.updated,touched:this.touched,acs:this.acs,public:this.public,private:this.private}])}this.onMetaDesc&&this.onMetaDesc(this)},_processMetaSub:function(e){var t=void 0;for(var n in e){var s=e[n];if(s.user){s.updated=new Date(s.updated),s.deleted=s.deleted?new Date(s.deleted):null;var i=null;s.deleted?(delete this._users[s.user],i=s):((i=this._users[s.user])||(i=this._cacheGetUser(s.user)),i=this._updateCachedUser(s.user,s,s._generated)),this.onMetaSub&&this.onMetaSub(i)}else s._generated||(t=s)}t&&this.onMetaDesc&&this.onMetaDesc(t),this.onSubsUpdated&&this.onSubsUpdated(Object.keys(this._users))},_processMetaTags:function(e){1==e.length&&e[0]==w.DEL_CHAR&&(e=[]),this._tags=e,this.onTagsUpdated&&this.onTagsUpdated(e)},_processDelMessages:function(e,t){this._maxDel=Math.max(e,this._maxDel),this.clear=Math.max(e,this.clear);var n=this,s=0;Array.isArray(t)&&t.map(function(e){if(e.hi)for(var t=e.low;t0&&this.onData&&this.onData()},_allMessagesReceived:function(e){this.onAllMessagesReceived&&this.onAllMessagesReceived(e)},_resetSub:function(){this._subscribed=!1},_gone:function(){var e=this._tinode.getMeTopic();e&&e._routePres({_generated:!0,what:"gone",topic:"me",src:this.name}),this.onDeleteTopic&&this.onDeleteTopic()},_updateCachedUser:function(e,t,n){var s=this._cacheGetUser(e);return s?s=f(s,t):(n&&this.getMeta(this.startMetaQuery().withLaterOneSub(e).build()),s=f({},t)),this._cachePutUser(e,s),p(this._users,e,s)},_getQueuedSeqId:function(){return this._queuedSeqId++}};var y=function(e){T.call(this,"me",e),this._contacts={},e&&(this.onContactUpdate=e.onContactUpdate)};y.prototype=Object.create(T.prototype,{_processMetaSub:{value:function(e){var t=0;for(var n in e){var s=e[n],i=s.topic;if("fnd"!=i&&"me"!=i){s.updated=new Date(s.updated),s.touched=s.touched?new Date(s.touched):null,s.deleted=s.deleted?new Date(s.deleted):null,s.seq=0|s.seq,s.recv=0|s.recv,s.read=0|s.read,s.unread=s.seq-s.read;var r=null;if(s.deleted)r=s,delete this._contacts[i];else if(s.seen&&s.seen.when&&(s.seen.when=new Date(s.seen.when)),r=p(this._contacts,i,s),"p2p"==w.topicType(i)&&this._cachePutUser(i,r),!s._generated){var a=this._tinode.getTopic(i);a&&a._processMetaDesc(s,!0)}t++,this.onMetaSub&&this.onMetaSub(r)}}t>0&&this.onSubsUpdated&&this.onSubsUpdated(Object.keys(this._contacts))},enumerable:!0,configurable:!0,writable:!1},_routePres:{value:function(e){var t=this._contacts[e.src];if(t){switch(e.what){case"on":t.online=!0;break;case"off":t.online&&(t.online=!1,t.seen?t.seen.when=new Date:t.seen={when:new Date});break;case"msg":t.touched=new Date,t.seq=0|e.seq,t.unread=t.seq-t.read;break;case"upd":this.getMeta(this.startMetaQuery().withLaterOneSub(e.src).build());break;case"acs":t.acs?t.acs.updateAll(e.dacs):t.acs=(new S).updateAll(e.dacs);break;case"ua":t.seen={when:new Date,ua:e.ua};break;case"recv":t.recv=t.recv?Math.max(t.recv,e.seq):0|e.seq;break;case"read":t.read=t.read?Math.max(t.read,e.seq):0|e.seq,t.unread=t.seq-t.read;break;case"gone":delete this._contacts[e.src]}this.onContactUpdate&&this.onContactUpdate(e.what,t)}else if("acs"==e.what){var n=new S(e.dacs);if(!n||n.mode==S._INVALID)return void this._tinode.logger("Invalid access mode update",e.src,e.dacs);if(n.mode==S._NONE)return void this._tinode.logger("Removing non-existent subscription",e.src,e.dacs);this.getMeta(this.startMetaQuery().withOneSub(void 0,e.src).build()),this._contacts[e.src]={topic:e.src,online:!1,acs:n}}this.onPres&&this.onPres(e)},enumerable:!0,configurable:!0,writable:!1},publish:{value:function(){return Promise.reject(new Error("Publishing to 'me' is not supported"))},enumerable:!0,configurable:!0,writable:!1},contacts:{value:function(e,t){var n=e||this.onMetaSub;if(n)for(var s in this._contacts)n.call(t,this._contacts[s],s,this._contacts)},enumerable:!0,configurable:!0,writable:!0},setMsgReadRecv:{value:function(e,t,n,s){var i,r=this._contacts[e],a=!1;r&&(n|=0,"recv"===t?(i=r.recv,r.recv=r.recv?Math.max(r.recv,n):n,a=i!=r.recv):"read"===t?(i=r.read,r.read=r.read?Math.max(r.read,n):n,r.unread=r.seq-r.read,a=i!=r.read,r.recv0&&this.onSubsUpdated&&this.onSubsUpdated(Object.keys(this._contacts))},enumerable:!0,configurable:!0,writable:!1},publish:{value:function(){return Promise.reject(new Error("Publishing to 'fnd' is not supported"))},enumerable:!0,configurable:!0,writable:!1},setMeta:{value:function(e){var t=this;return Object.getPrototypeOf(D.prototype).setMeta.call(this,e).then(function(){Object.keys(t._contacts).length>0&&(t._contacts={},t.onSubsUpdated&&t.onSubsUpdated([]))})},enumerable:!0,configurable:!0,writable:!1},contacts:{value:function(e,t){var n=e||this.onMetaSub;if(n)for(var s in this._contacts)n.call(t,this._contacts[s],s,this._contacts)},enumerable:!0,configurable:!0,writable:!0}}),D.prototype.constructor=D;var E=function(e){this._tinode=e,this._apiKey=e._apiKey,this._authToken=e.getAuthToken(),this._msgId=e.getNextUniqueId(),this.xhr=g(),this.toResolve=null,this.toReject=null,this.onProgress=null,this.onSuccess=null,this.onFailure=null};E.prototype={upload:function(e,t,n,s){if(!this._authToken)throw new Error("Must authenticate first");var i=this;this.xhr.open("POST","/v"+u+"/file/u/",!0),this.xhr.setRequestHeader("X-Tinode-APIKey",this._apiKey),this.xhr.setRequestHeader("X-Tinode-Auth","Token "+this._authToken.token);var r=new Promise((e,t)=>{this.toResolve=e,this.toReject=t});this.onProgress=t,this.onSuccess=n,this.onFailure=s,this.xhr.upload.onprogress=function(e){e.lengthComputable&&i.onProgress&&i.onProgress(e.loaded/e.total)},this.xhr.onload=function(){var e;try{e=JSON.parse(this.response,_)}catch(e){i._tinode.logger("Invalid server response in LargeFileHelper",this.response)}this.status>=200&&this.status<300?(i.toResolve&&i.toResolve(e.ctrl.params.url),i.onSuccess&&i.onSuccess(e.ctrl)):this.status>=400?(i.toReject&&i.toReject(new Error(e.ctrl.text+" ("+e.ctrl.code+")")),i.onFailure&&i.onFailure(e.ctrl)):i._tinode.logger("Unexpected server response status",this.status,this.response)},this.xhr.onerror=function(e){i.toReject&&i.toReject(new Error("failed")),i.onFailure&&i.onFailure(null)},this.xhr.onabort=function(e){i.toReject&&i.toReject(new Error("upload cancelled by user")),i.onFailure&&i.onFailure(null)};try{var a=new FormData;a.append("file",e),a.set("id",this._msgId),this.xhr.send(a)}catch(e){this.toReject&&this.toReject(e),this.onFailure&&this.onFailure(null)}return r},download:function(e,t,n,s){if(/^(?:(?:[a-z]+:)?\/\/)/i.test(e))throw new Error("The URL '"+e+"' must be relative, not absolute");if(!this._authToken)throw new Error("Must authenticate first");var i=this;this.xhr.open("GET",e,!0),this.xhr.setRequestHeader("X-Tinode-APIKey",this._apiKey),this.xhr.setRequestHeader("X-Tinode-Auth","Token "+this._authToken.token),this.xhr.responseType="blob",this.onProgress=s,this.xhr.onprogress=function(e){i.onProgress&&i.onProgress(e.loaded)};var r=new Promise((e,t)=>{this.toResolve=e,this.toReject=t});this.xhr.onload=function(){if(200==this.status){var e=document.createElement("a");e.href=window.URL.createObjectURL(new Blob([this.response],{type:n})),e.style.display="none",e.setAttribute("download",t),document.body.appendChild(e),e.click(),document.body.removeChild(e),window.URL.revokeObjectURL(e.href),i.toResolve&&i.toResolve()}else if(this.status>=400&&i.toReject){var s=new FileReader;s.onload=function(){try{var e=JSON.parse(this.result,_);i.toReject(new Error(e.ctrl.text+" ("+e.ctrl.code+")"))}catch(e){i._tinode.logger("Invalid server response in LargeFileHelper",this.result),i.toReject(e)}},s.readAsText(this.response)}},this.xhr.onerror=function(e){i.toReject&&i.toReject(new Error("failed"))},this.xhr.onabort=function(){i.toReject&&i.toReject(null)};try{this.xhr.send()}catch(e){this.toReject&&this.toReject(e)}return r},cancel:function(){this.xhr&&this.xhr.readyState<4&&this.xhr.abort()},getId:function(){return this._msgId}};var x=function(e,t){this.status=x.STATUS_NONE,this.topic=e,this.content=t};return x.STATUS_NONE=0,x.STATUS_QUEUED=1,x.STATUS_SENDING=2,x.STATUS_SENT=3,x.STATUS_RECEIVED=4,x.STATUS_READ=5,x.STATUS_TO_ME=6,x.prototype={toJSON:function(){},fromJSON:function(e){}},x.prototype.constructor=x,(o=w).Drafty=e,o}); }).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) -},{}],25:[function(require,module,exports){ +},{}],31:[function(require,module,exports){ +(function (global){ +/*! ***************************************************************************** +Copyright (c) Microsoft Corporation. All rights reserved. +Licensed under the Apache License, Version 2.0 (the "License"); you may not use +this file except in compliance with the License. You may obtain a copy of the +License at http://www.apache.org/licenses/LICENSE-2.0 + +THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY IMPLIED +WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, +MERCHANTABLITY OR NON-INFRINGEMENT. + +See the Apache Version 2.0 License for specific language governing permissions +and limitations under the License. +***************************************************************************** */ +/* global global, define, System, Reflect, Promise */ +var __extends; +var __assign; +var __rest; +var __decorate; +var __param; +var __metadata; +var __awaiter; +var __generator; +var __exportStar; +var __values; +var __read; +var __spread; +var __await; +var __asyncGenerator; +var __asyncDelegator; +var __asyncValues; +var __makeTemplateObject; +var __importStar; +var __importDefault; +(function (factory) { + var root = typeof global === "object" ? global : typeof self === "object" ? self : typeof this === "object" ? this : {}; + if (typeof define === "function" && define.amd) { + define("tslib", ["exports"], function (exports) { factory(createExporter(root, createExporter(exports))); }); + } + else if (typeof module === "object" && typeof module.exports === "object") { + factory(createExporter(root, createExporter(module.exports))); + } + else { + factory(createExporter(root)); + } + function createExporter(exports, previous) { + if (exports !== root) { + if (typeof Object.create === "function") { + Object.defineProperty(exports, "__esModule", { value: true }); + } + else { + exports.__esModule = true; + } + } + return function (id, v) { return exports[id] = previous ? previous(id, v) : v; }; + } +}) +(function (exporter) { + var extendStatics = Object.setPrototypeOf || + ({ __proto__: [] } instanceof Array && function (d, b) { d.__proto__ = b; }) || + function (d, b) { for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p]; }; + + __extends = function (d, b) { + extendStatics(d, b); + function __() { this.constructor = d; } + d.prototype = b === null ? Object.create(b) : (__.prototype = b.prototype, new __()); + }; + + __assign = Object.assign || function (t) { + for (var s, i = 1, n = arguments.length; i < n; i++) { + s = arguments[i]; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; + } + return t; + }; + + __rest = function (s, e) { + var t = {}; + for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p) && e.indexOf(p) < 0) + t[p] = s[p]; + if (s != null && typeof Object.getOwnPropertySymbols === "function") + for (var i = 0, p = Object.getOwnPropertySymbols(s); i < p.length; i++) if (e.indexOf(p[i]) < 0) + t[p[i]] = s[p[i]]; + return t; + }; + + __decorate = function (decorators, target, key, desc) { + var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d; + if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc); + else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r; + return c > 3 && r && Object.defineProperty(target, key, r), r; + }; + + __param = function (paramIndex, decorator) { + return function (target, key) { decorator(target, key, paramIndex); } + }; + + __metadata = function (metadataKey, metadataValue) { + if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(metadataKey, metadataValue); + }; + + __awaiter = function (thisArg, _arguments, P, generator) { + return new (P || (P = Promise))(function (resolve, reject) { + function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } + function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } + function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } + step((generator = generator.apply(thisArg, _arguments || [])).next()); + }); + }; + + __generator = function (thisArg, body) { + var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; + return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; + function verb(n) { return function (v) { return step([n, v]); }; } + function step(op) { + if (f) throw new TypeError("Generator is already executing."); + while (_) try { + if (f = 1, y && (t = y[op[0] & 2 ? "return" : op[0] ? "throw" : "next"]) && !(t = t.call(y, op[1])).done) return t; + if (y = 0, t) op = [0, t.value]; + switch (op[0]) { + case 0: case 1: t = op; break; + case 4: _.label++; return { value: op[1], done: false }; + case 5: _.label++; y = op[1]; op = [0]; continue; + case 7: op = _.ops.pop(); _.trys.pop(); continue; + default: + if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } + if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } + if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } + if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } + if (t[2]) _.ops.pop(); + _.trys.pop(); continue; + } + op = body.call(thisArg, _); + } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } + if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; + } + }; + + __exportStar = function (m, exports) { + for (var p in m) if (!exports.hasOwnProperty(p)) exports[p] = m[p]; + }; + + __values = function (o) { + var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; + if (m) return m.call(o); + return { + next: function () { + if (o && i >= o.length) o = void 0; + return { value: o && o[i++], done: !o }; + } + }; + }; + + __read = function (o, n) { + var m = typeof Symbol === "function" && o[Symbol.iterator]; + if (!m) return o; + var i = m.call(o), r, ar = [], e; + try { + while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value); + } + catch (error) { e = { error: error }; } + finally { + try { + if (r && !r.done && (m = i["return"])) m.call(i); + } + finally { if (e) throw e.error; } + } + return ar; + }; + + __spread = function () { + for (var ar = [], i = 0; i < arguments.length; i++) + ar = ar.concat(__read(arguments[i])); + return ar; + }; + + __await = function (v) { + return this instanceof __await ? (this.v = v, this) : new __await(v); + }; + + __asyncGenerator = function (thisArg, _arguments, generator) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var g = generator.apply(thisArg, _arguments || []), i, q = []; + return i = {}, verb("next"), verb("throw"), verb("return"), i[Symbol.asyncIterator] = function () { return this; }, i; + function verb(n) { if (g[n]) i[n] = function (v) { return new Promise(function (a, b) { q.push([n, v, a, b]) > 1 || resume(n, v); }); }; } + function resume(n, v) { try { step(g[n](v)); } catch (e) { settle(q[0][3], e); } } + function step(r) { r.value instanceof __await ? Promise.resolve(r.value.v).then(fulfill, reject) : settle(q[0][2], r); } + function fulfill(value) { resume("next", value); } + function reject(value) { resume("throw", value); } + function settle(f, v) { if (f(v), q.shift(), q.length) resume(q[0][0], q[0][1]); } + }; + + __asyncDelegator = function (o) { + var i, p; + return i = {}, verb("next"), verb("throw", function (e) { throw e; }), verb("return"), i[Symbol.iterator] = function () { return this; }, i; + function verb(n, f) { if (o[n]) i[n] = function (v) { return (p = !p) ? { value: __await(o[n](v)), done: n === "return" } : f ? f(v) : v; }; } + }; + + __asyncValues = function (o) { + if (!Symbol.asyncIterator) throw new TypeError("Symbol.asyncIterator is not defined."); + var m = o[Symbol.asyncIterator]; + return m ? m.call(o) : typeof __values === "function" ? __values(o) : o[Symbol.iterator](); + }; + + __makeTemplateObject = function (cooked, raw) { + if (Object.defineProperty) { Object.defineProperty(cooked, "raw", { value: raw }); } else { cooked.raw = raw; } + return cooked; + }; + + __importStar = function (mod) { + if (mod && mod.__esModule) return mod; + var result = {}; + if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k]; + result["default"] = mod; + return result; + }; + + __importDefault = function (mod) { + return (mod && mod.__esModule) ? mod : { "default": mod }; + }; + + exporter("__extends", __extends); + exporter("__assign", __assign); + exporter("__rest", __rest); + exporter("__decorate", __decorate); + exporter("__param", __param); + exporter("__metadata", __metadata); + exporter("__awaiter", __awaiter); + exporter("__generator", __generator); + exporter("__exportStar", __exportStar); + exporter("__values", __values); + exporter("__read", __read); + exporter("__spread", __spread); + exporter("__await", __await); + exporter("__asyncGenerator", __asyncGenerator); + exporter("__asyncDelegator", __asyncDelegator); + exporter("__asyncValues", __asyncValues); + exporter("__makeTemplateObject", __makeTemplateObject); + exporter("__importStar", __importStar); + exporter("__importDefault", __importDefault); +}); + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) +},{}],32:[function(require,module,exports){ +(function(self) { + 'use strict'; + + if (self.fetch) { + return + } + + var support = { + searchParams: 'URLSearchParams' in self, + iterable: 'Symbol' in self && 'iterator' in Symbol, + blob: 'FileReader' in self && 'Blob' in self && (function() { + try { + new Blob() + return true + } catch(e) { + return false + } + })(), + formData: 'FormData' in self, + arrayBuffer: 'ArrayBuffer' in self + } + + if (support.arrayBuffer) { + var viewClasses = [ + '[object Int8Array]', + '[object Uint8Array]', + '[object Uint8ClampedArray]', + '[object Int16Array]', + '[object Uint16Array]', + '[object Int32Array]', + '[object Uint32Array]', + '[object Float32Array]', + '[object Float64Array]' + ] + + var isDataView = function(obj) { + return obj && DataView.prototype.isPrototypeOf(obj) + } + + var isArrayBufferView = ArrayBuffer.isView || function(obj) { + return obj && viewClasses.indexOf(Object.prototype.toString.call(obj)) > -1 + } + } + + function normalizeName(name) { + if (typeof name !== 'string') { + name = String(name) + } + if (/[^a-z0-9\-#$%&'*+.\^_`|~]/i.test(name)) { + throw new TypeError('Invalid character in header field name') + } + return name.toLowerCase() + } + + function normalizeValue(value) { + if (typeof value !== 'string') { + value = String(value) + } + return value + } + + // Build a destructive iterator for the value list + function iteratorFor(items) { + var iterator = { + next: function() { + var value = items.shift() + return {done: value === undefined, value: value} + } + } + + if (support.iterable) { + iterator[Symbol.iterator] = function() { + return iterator + } + } + + return iterator + } + + function Headers(headers) { + this.map = {} + + if (headers instanceof Headers) { + headers.forEach(function(value, name) { + this.append(name, value) + }, this) + } else if (Array.isArray(headers)) { + headers.forEach(function(header) { + this.append(header[0], header[1]) + }, this) + } else if (headers) { + Object.getOwnPropertyNames(headers).forEach(function(name) { + this.append(name, headers[name]) + }, this) + } + } + + Headers.prototype.append = function(name, value) { + name = normalizeName(name) + value = normalizeValue(value) + var oldValue = this.map[name] + this.map[name] = oldValue ? oldValue+','+value : value + } + + Headers.prototype['delete'] = function(name) { + delete this.map[normalizeName(name)] + } + + Headers.prototype.get = function(name) { + name = normalizeName(name) + return this.has(name) ? this.map[name] : null + } + + Headers.prototype.has = function(name) { + return this.map.hasOwnProperty(normalizeName(name)) + } + + Headers.prototype.set = function(name, value) { + this.map[normalizeName(name)] = normalizeValue(value) + } + + Headers.prototype.forEach = function(callback, thisArg) { + for (var name in this.map) { + if (this.map.hasOwnProperty(name)) { + callback.call(thisArg, this.map[name], name, this) + } + } + } + + Headers.prototype.keys = function() { + var items = [] + this.forEach(function(value, name) { items.push(name) }) + return iteratorFor(items) + } + + Headers.prototype.values = function() { + var items = [] + this.forEach(function(value) { items.push(value) }) + return iteratorFor(items) + } + + Headers.prototype.entries = function() { + var items = [] + this.forEach(function(value, name) { items.push([name, value]) }) + return iteratorFor(items) + } + + if (support.iterable) { + Headers.prototype[Symbol.iterator] = Headers.prototype.entries + } + + function consumed(body) { + if (body.bodyUsed) { + return Promise.reject(new TypeError('Already read')) + } + body.bodyUsed = true + } + + function fileReaderReady(reader) { + return new Promise(function(resolve, reject) { + reader.onload = function() { + resolve(reader.result) + } + reader.onerror = function() { + reject(reader.error) + } + }) + } + + function readBlobAsArrayBuffer(blob) { + var reader = new FileReader() + var promise = fileReaderReady(reader) + reader.readAsArrayBuffer(blob) + return promise + } + + function readBlobAsText(blob) { + var reader = new FileReader() + var promise = fileReaderReady(reader) + reader.readAsText(blob) + return promise + } + + function readArrayBufferAsText(buf) { + var view = new Uint8Array(buf) + var chars = new Array(view.length) + + for (var i = 0; i < view.length; i++) { + chars[i] = String.fromCharCode(view[i]) + } + return chars.join('') + } + + function bufferClone(buf) { + if (buf.slice) { + return buf.slice(0) + } else { + var view = new Uint8Array(buf.byteLength) + view.set(new Uint8Array(buf)) + return view.buffer + } + } + + function Body() { + this.bodyUsed = false + + this._initBody = function(body) { + this._bodyInit = body + if (!body) { + this._bodyText = '' + } else if (typeof body === 'string') { + this._bodyText = body + } else if (support.blob && Blob.prototype.isPrototypeOf(body)) { + this._bodyBlob = body + } else if (support.formData && FormData.prototype.isPrototypeOf(body)) { + this._bodyFormData = body + } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { + this._bodyText = body.toString() + } else if (support.arrayBuffer && support.blob && isDataView(body)) { + this._bodyArrayBuffer = bufferClone(body.buffer) + // IE 10-11 can't handle a DataView body. + this._bodyInit = new Blob([this._bodyArrayBuffer]) + } else if (support.arrayBuffer && (ArrayBuffer.prototype.isPrototypeOf(body) || isArrayBufferView(body))) { + this._bodyArrayBuffer = bufferClone(body) + } else { + throw new Error('unsupported BodyInit type') + } + + if (!this.headers.get('content-type')) { + if (typeof body === 'string') { + this.headers.set('content-type', 'text/plain;charset=UTF-8') + } else if (this._bodyBlob && this._bodyBlob.type) { + this.headers.set('content-type', this._bodyBlob.type) + } else if (support.searchParams && URLSearchParams.prototype.isPrototypeOf(body)) { + this.headers.set('content-type', 'application/x-www-form-urlencoded;charset=UTF-8') + } + } + } + + if (support.blob) { + this.blob = function() { + var rejected = consumed(this) + if (rejected) { + return rejected + } + + if (this._bodyBlob) { + return Promise.resolve(this._bodyBlob) + } else if (this._bodyArrayBuffer) { + return Promise.resolve(new Blob([this._bodyArrayBuffer])) + } else if (this._bodyFormData) { + throw new Error('could not read FormData body as blob') + } else { + return Promise.resolve(new Blob([this._bodyText])) + } + } + + this.arrayBuffer = function() { + if (this._bodyArrayBuffer) { + return consumed(this) || Promise.resolve(this._bodyArrayBuffer) + } else { + return this.blob().then(readBlobAsArrayBuffer) + } + } + } + + this.text = function() { + var rejected = consumed(this) + if (rejected) { + return rejected + } + + if (this._bodyBlob) { + return readBlobAsText(this._bodyBlob) + } else if (this._bodyArrayBuffer) { + return Promise.resolve(readArrayBufferAsText(this._bodyArrayBuffer)) + } else if (this._bodyFormData) { + throw new Error('could not read FormData body as text') + } else { + return Promise.resolve(this._bodyText) + } + } + + if (support.formData) { + this.formData = function() { + return this.text().then(decode) + } + } + + this.json = function() { + return this.text().then(JSON.parse) + } + + return this + } + + // HTTP methods whose capitalization should be normalized + var methods = ['DELETE', 'GET', 'HEAD', 'OPTIONS', 'POST', 'PUT'] + + function normalizeMethod(method) { + var upcased = method.toUpperCase() + return (methods.indexOf(upcased) > -1) ? upcased : method + } + + function Request(input, options) { + options = options || {} + var body = options.body + + if (input instanceof Request) { + if (input.bodyUsed) { + throw new TypeError('Already read') + } + this.url = input.url + this.credentials = input.credentials + if (!options.headers) { + this.headers = new Headers(input.headers) + } + this.method = input.method + this.mode = input.mode + if (!body && input._bodyInit != null) { + body = input._bodyInit + input.bodyUsed = true + } + } else { + this.url = String(input) + } + + this.credentials = options.credentials || this.credentials || 'omit' + if (options.headers || !this.headers) { + this.headers = new Headers(options.headers) + } + this.method = normalizeMethod(options.method || this.method || 'GET') + this.mode = options.mode || this.mode || null + this.referrer = null + + if ((this.method === 'GET' || this.method === 'HEAD') && body) { + throw new TypeError('Body not allowed for GET or HEAD requests') + } + this._initBody(body) + } + + Request.prototype.clone = function() { + return new Request(this, { body: this._bodyInit }) + } + + function decode(body) { + var form = new FormData() + body.trim().split('&').forEach(function(bytes) { + if (bytes) { + var split = bytes.split('=') + var name = split.shift().replace(/\+/g, ' ') + var value = split.join('=').replace(/\+/g, ' ') + form.append(decodeURIComponent(name), decodeURIComponent(value)) + } + }) + return form + } + + function parseHeaders(rawHeaders) { + var headers = new Headers() + // Replace instances of \r\n and \n followed by at least one space or horizontal tab with a space + // https://tools.ietf.org/html/rfc7230#section-3.2 + var preProcessedHeaders = rawHeaders.replace(/\r?\n[\t ]+/g, ' ') + preProcessedHeaders.split(/\r?\n/).forEach(function(line) { + var parts = line.split(':') + var key = parts.shift().trim() + if (key) { + var value = parts.join(':').trim() + headers.append(key, value) + } + }) + return headers + } + + Body.call(Request.prototype) + + function Response(bodyInit, options) { + if (!options) { + options = {} + } + + this.type = 'default' + this.status = options.status === undefined ? 200 : options.status + this.ok = this.status >= 200 && this.status < 300 + this.statusText = 'statusText' in options ? options.statusText : 'OK' + this.headers = new Headers(options.headers) + this.url = options.url || '' + this._initBody(bodyInit) + } + + Body.call(Response.prototype) + + Response.prototype.clone = function() { + return new Response(this._bodyInit, { + status: this.status, + statusText: this.statusText, + headers: new Headers(this.headers), + url: this.url + }) + } + + Response.error = function() { + var response = new Response(null, {status: 0, statusText: ''}) + response.type = 'error' + return response + } + + var redirectStatuses = [301, 302, 303, 307, 308] + + Response.redirect = function(url, status) { + if (redirectStatuses.indexOf(status) === -1) { + throw new RangeError('Invalid status code') + } + + return new Response(null, {status: status, headers: {location: url}}) + } + + self.Headers = Headers + self.Request = Request + self.Response = Response + + self.fetch = function(input, init) { + return new Promise(function(resolve, reject) { + var request = new Request(input, init) + var xhr = new XMLHttpRequest() + + xhr.onload = function() { + var options = { + status: xhr.status, + statusText: xhr.statusText, + headers: parseHeaders(xhr.getAllResponseHeaders() || '') + } + options.url = 'responseURL' in xhr ? xhr.responseURL : options.headers.get('X-Request-URL') + var body = 'response' in xhr ? xhr.response : xhr.responseText + resolve(new Response(body, options)) + } + + xhr.onerror = function() { + reject(new TypeError('Network request failed')) + } + + xhr.ontimeout = function() { + reject(new TypeError('Network request failed')) + } + + xhr.open(request.method, request.url, true) + + if (request.credentials === 'include') { + xhr.withCredentials = true + } else if (request.credentials === 'omit') { + xhr.withCredentials = false + } + + if ('responseType' in xhr && support.blob) { + xhr.responseType = 'blob' + } + + request.headers.forEach(function(value, name) { + xhr.setRequestHeader(name, value) + }) + + xhr.send(typeof request._bodyInit === 'undefined' ? null : request._bodyInit) + }) + } + self.fetch.polyfill = true +})(typeof self !== 'undefined' ? self : this); + +},{}],33:[function(require,module,exports){ // Put all packages together. // Used to generate umd/index.prod.js @@ -20237,7 +26837,7 @@ ReactDOM.render( document.getElementById('mountPoint') ); -},{"./webapp.js":26,"react":23,"react-dom":20}],26:[function(require,module,exports){ +},{"./webapp.js":34,"react":29,"react-dom":26}],34:[function(require,module,exports){ // Babel JSX 'use strict'; @@ -20251,6 +26851,10 @@ if (typeof require == 'function') { var Tinode = require('tinode-sdk'); var Drafty = Tinode.Drafty; } + if (typeof firebase == 'undefined') { + var firebase = require('firebase/app'); + require('firebase/messaging'); + } } // Name of this application, used in the User-Agent. @@ -20267,6 +26871,12 @@ const POP_SOUND = new Audio('audio/msg.mp3'); // API key. Use https://github.com/tinode/chat/tree/master/keygen to generate your own const API_KEY = "AQEAAAABAAD_rAp4DJh05a1HAwFT3A6K"; +// Firebase is used for desktop alerts (push notifications). +// If you deploy your own server, you must change these FIREBASE_... values to your own. +const FIREBASE_VAPID_KEY = "BOgQVPOMzIMXUpsYGpbVkZoEBc0ifKY_f2kSU5DNDGYI6i6CoKqqxDd7w7PJ3FaGRBgVGJffldETumOx831jl58"; +const FIREBASE_PUBLIC_API_KEY = "AIzaSyD6X4ULR-RUsobvs1zZ2bHdJuPz39q2tbQ"; +const FIREBASE_SENDER_ID = "114126160546"; + // Minimum time between two keypress notifications, milliseconds. const KEYPRESS_DELAY = 3 * 1000; // Delay before sending a {note} for reciving a message, milliseconds. @@ -20646,6 +27256,13 @@ function isSecureConnection() { return false; } +function isLocalHost() { + if (typeof window.location == 'object') { + return window.location.hostname == 'localhost'; + } + return false; +} + // Create VCard which represents topic 'public' info function vcard(fn, imageDataUrl) { var card = null; @@ -25316,6 +31933,9 @@ class TinodeWeb extends React.Component { this.handleUpdateAccountTagsRequest = this.handleUpdateAccountTagsRequest.bind(this); this.handleSettings = this.handleSettings.bind(this); this.handleGlobalSettings = this.handleGlobalSettings.bind(this); + this.initDesktopAlerts = this.initDesktopAlerts.bind(this); + this.togglePushToken = this.togglePushToken.bind(this); + this.requestPushToken = this.requestPushToken.bind(this); this.handleSidepanelCancel = this.handleSidepanelCancel.bind(this); this.handleNewTopic = this.handleNewTopic.bind(this); this.handleNewTopicRequest = this.handleNewTopicRequest.bind(this); @@ -25339,7 +31959,6 @@ class TinodeWeb extends React.Component { let settings = localStorage.getObject("settings") || {}; return { - tinode: null, connected: false, transport: settings.transport || null, serverAddress: settings.serverAddress || detectServerAddress(), @@ -25347,7 +31966,8 @@ class TinodeWeb extends React.Component { // "On" is the default, so saving the "off" state. messageSounds: !settings.messageSoundsOff, desktopAlerts: settings.desktopAlerts, - desktopAlertsEnabled: isSecureConnection(), + desktopAlertsEnabled: (isSecureConnection() || isLocalHost()) && typeof firebase != 'undefined' && typeof navigator != 'undefined', + firebaseToken: localStorage.getObject("firebase-token"), errorText: '', errorLevel: null, @@ -25402,22 +32022,50 @@ class TinodeWeb extends React.Component { this.setState({ viewportWidth: document.documentElement.clientWidth }); - let tinode = TinodeWeb.tnSetup(this.state.serverAddress, this.state.transport); + this.tinode = TinodeWeb.tnSetup(this.state.serverAddress, this.state.transport); - this.setState({ tinode: tinode }); + // Initialize desktop alerts. + if (this.state.desktopAlertsEnabled) { + try { + this.fbPush = firebase.initializeApp({ + apiKey: FIREBASE_PUBLIC_API_KEY, + messagingSenderId: FIREBASE_SENDER_ID + }, APP_NAME).messaging(); + this.fbPush.usePublicVapidKey(FIREBASE_VAPID_KEY); + navigator.serviceWorker.register('/service-worker.js').then(reg => { + this.fbPush.useServiceWorker(reg); + this.initDesktopAlerts(); + if (this.state.desktopAlerts) { + if (!this.state.firebaseToken) { + this.togglePushToken(true, null); + } else { + this.tinode.setDeviceToken(this.state.firebaseToken); + } + } + }).catch(err => { + // registration failed :( + console.log("Failed to register service worker:", err); + }); + } catch (err) { + this.handleError("Failed to initialize push notifications", "err"); + console.log("Failed to initialize push notifications", err); + this.setState({ desktopAlertsEnabled: false }); + } + } - tinode.enableLogging(true, true); - tinode.onConnect = this.handleConnected; - tinode.onDisconnect = this.handleDisconnect; - var token; + this.tinode.enableLogging(true, true); + this.tinode.onConnect = this.handleConnected; + this.tinode.onDisconnect = this.handleDisconnect; + let token, firebasePushToken; if (localStorage.getObject("keep-logged-in")) { token = localStorage.getObject("auth-token"); } + if (token) { // When reading from storage, date is returned as string. token.expires = new Date(token.expires); - tinode.setAuthToken(token); - tinode.connect().catch(err => { + this.tinode.setAuthToken(token); + this.tinode.connect().catch(err => { // Socket error this.handleError(err.message, "err"); }); @@ -25429,6 +32077,7 @@ class TinodeWeb extends React.Component { } else { navigateTo(""); } + this.readTimer = null; this.readTimerCallback = null; @@ -25530,10 +32179,10 @@ class TinodeWeb extends React.Component { this.setState({ loginDisabled: true, login: login, password: password }); this.handleError("", null); - if (this.state.tinode.isConnected()) { + if (this.tinode.isConnected()) { this.doLogin(login, password, { meth: this.state.credMethod, resp: this.state.credCode }); } else { - this.state.tinode.connect().catch(err => { + this.tinode.connect().catch(err => { // Socket error this.setState({ loginDisabled: false }); this.handleError(err.message, "err"); @@ -25543,7 +32192,7 @@ class TinodeWeb extends React.Component { // Connection succeeded. handleConnected() { - var params = this.state.tinode.getServerInfo(); + var params = this.tinode.getServerInfo(); this.setState({ serverVersion: params.ver + " " + (params.build ? params.build : "none") + "; " }); @@ -25551,7 +32200,7 @@ class TinodeWeb extends React.Component { } doLogin(login, password, cred) { - if (this.state.tinode.isAuthenticated()) { + if (this.tinode.isAuthenticated()) { // Already logged in. Go to default screen. navigateTo(""); return; @@ -25560,12 +32209,12 @@ class TinodeWeb extends React.Component { cred = Tinode.credential(cred); // Try to login with login/password. If they are not available, try token. If no token, ask for login/password. let promise = null; - let token = this.state.tinode.getAuthToken(); + let token = this.tinode.getAuthToken(); if (login && password) { this.setState({ password: null }); - promise = this.state.tinode.loginBasic(login, password, cred); + promise = this.tinode.loginBasic(login, password, cred); } else if (token) { - promise = this.state.tinode.loginToken(token.token, cred); + promise = this.tinode.loginToken(token.token, cred); } if (promise) { @@ -25605,10 +32254,10 @@ class TinodeWeb extends React.Component { // Refresh authentication token. if (localStorage.getObject("keep-logged-in")) { - localStorage.setObject("auth-token", this.state.tinode.getAuthToken()); + localStorage.setObject("auth-token", this.tinode.getAuthToken()); } // Logged in fine, subscribe to 'me' attaching callbacks from the contacts view. - var me = this.state.tinode.getMeTopic(); + var me = this.tinode.getMeTopic(); me.onMetaDesc = this.tnMeMetaDesc; me.onContactUpdate = this.tnMeContactUpdate; me.onSubsUpdated = this.tnMeSubsUpdated; @@ -25616,7 +32265,7 @@ class TinodeWeb extends React.Component { connected: true, credMethod: undefined, credCode: undefined, - myUserId: this.state.tinode.getCurrentUserID() + myUserId: this.tinode.getCurrentUserID() }); // Subscribe, fetch topic desc, the list of subscriptions. Messages are not fetched. me.subscribe(me.startMetaQuery().withLaterSub().withDesc().build()).catch(err => { @@ -25732,7 +32381,7 @@ class TinodeWeb extends React.Component { let newState = { chatList: [] }; - this.state.tinode.getMeTopic().contacts(c => { + this.tinode.getMeTopic().contacts(c => { newState.chatList.push(c); if (this.state.topicSelected == c.topic) { newState.topicSelectedOnline = c.online; @@ -25746,7 +32395,7 @@ class TinodeWeb extends React.Component { // Sending "received" notifications tnData(data) { - let topic = this.state.tinode.getTopic(data.topic); + let topic = this.tinode.getTopic(data.topic); if (topic.msgStatus(data) > Tinode.MESSAGE_STATUS_SENDING) { clearTimeout(this.receivedTimer); this.receivedTimer = setTimeout(() => { @@ -25758,7 +32407,7 @@ class TinodeWeb extends React.Component { /* Fnd topic: find contacts by tokens */ tnInitFind() { - let fnd = this.state.tinode.getFndTopic(); + let fnd = this.tinode.getFndTopic(); if (fnd.isSubscribed()) { this.setState({ contactsSearchQuery: '' }); this.tnFndSubsUpdated(); @@ -25773,7 +32422,7 @@ class TinodeWeb extends React.Component { tnFndSubsUpdated() { let foundContacts = []; // Don't attempt to create P2P topics which already exist. Server will reject the duplicates. - this.state.tinode.getFndTopic().contacts(s => { + this.tinode.getFndTopic().contacts(s => { foundContacts.push(s); }); this.setState({ @@ -25786,7 +32435,7 @@ class TinodeWeb extends React.Component { @param query {Array} is an array of contacts to search for */ handleSearchContacts(query) { - var fnd = this.state.tinode.getFndTopic(); + var fnd = this.tinode.getFndTopic(); this.setState({ contactsSearchQuery: query == Tinode.DEL_CHAR ? '' : query }); fnd.setMeta({ desc: { public: query } }).then(ctrl => { return fnd.getMeta(fnd.startMetaQuery().withSub().build()); @@ -25837,7 +32486,7 @@ class TinodeWeb extends React.Component { // User is sending a message, either plain text or a drafty object, possibly // with attachments. handleSendMessage(msg, promise, uploader) { - let topic = this.state.tinode.getTopic(this.state.topicSelected); + let topic = this.tinode.getTopic(this.state.topicSelected); msg = topic.createMessage(msg, false); // The uploader is used to show progress. @@ -25870,8 +32519,8 @@ class TinodeWeb extends React.Component { // Actual registration of a new account. handleNewAccountRequest(login_, password_, public_, cred_, tags_) { - this.state.tinode.connect(this.state.serverAddress).then(() => { - return this.state.tinode.createAccountBasic(login_, password_, { public: public_, tags: tags_, cred: Tinode.credential(cred_) }); + this.tinode.connect(this.state.serverAddress).then(() => { + return this.tinode.createAccountBasic(login_, password_, { public: public_, tags: tags_, cred: Tinode.credential(cred_) }); }).then(ctrl => { if (ctrl.code >= 300 && ctrl.text === "validate credentials") { this.handleCredentialsRequest(ctrl.params); @@ -25885,19 +32534,19 @@ class TinodeWeb extends React.Component { handleUpdateAccountRequest(password, pub, priv) { if (pub || priv) { - this.state.tinode.getMeTopic().setMeta({ desc: { public: pub, private: priv } }).catch(err => { + this.tinode.getMeTopic().setMeta({ desc: { public: pub, private: priv } }).catch(err => { this.handleError(err.message, "err"); }); } if (password) { - this.state.tinode.updateAccountBasic(null, this.state.tinode.getCurrentLogin(), password).catch(err => { + this.tinode.updateAccountBasic(null, this.tinode.getCurrentLogin(), password).catch(err => { this.handleError(err.message, "err"); }); } } handleUpdateAccountTagsRequest(tags) { - this.state.tinode.getFndTopic().setMeta({ tags: tags }).catch(err => { + this.tinode.getFndTopic().setMeta({ tags: tags }).catch(err => { this.handleError(err.message, "err"); }); } @@ -25912,24 +32561,81 @@ class TinodeWeb extends React.Component { let serverAddress = settings.serverAddress || this.state.serverAddress; let transport = settings.transport || this.state.transport; let messageSounds = typeof settings.messageSounds == 'boolean' ? settings.messageSounds : this.state.messageSounds; - let desktopAlerts = settings.desktopAlerts || this.state.desktopAlerts; + + if (settings.desktopAlerts != this.state.desktopAlerts) { + this.togglePushToken(settings.desktopAlerts, this.state.firebaseToken); + } this.setState({ serverAddress: serverAddress, transport: transport, messageSounds: messageSounds, - desktopAlerts: desktopAlerts, + desktopAlerts: settings.desktopAlerts, tinode: TinodeWeb.tnSetup(serverAddress, transport) }); - localStorage.setObject({ + localStorage.setObject("settings", { serverAddress: serverAddress, messageSoundsOff: !messageSounds, - transport: this.state.transport, - desktopAlerts: desktopAlerts + transport: transport, + desktopAlerts: settings.desktopAlerts }); + navigateTo(setUrlSidePanel(window.location.hash, '')); } + // Initialize desktop alerts = push notifications. + initDesktopAlerts() { + // Google could not be bothered to mention that + // onTokenRefresh is never called. + this.fbPush.onTokenRefresh(() => { + this.requestPushToken(this.state.firebaseToken, true); + }); + + this.fbPush.onMessage(payload => { + // No need to do anything about it. + // All the magic happends in the service worker. + }); + } + + togglePushToken(enabled, oldToken) { + if (enabled) { + if (!oldToken) { + this.fbPush.requestPermission().then(() => { + this.requestPushToken(oldToken); + }).catch(err => { + this.handleError(err.message, "err"); + this.setState({ desktopAlerts: false, firebaseToken: null }); + console.log("Failed to get permission to notify.", err); + }); + } + } else if (oldToken) { + this.fbPush.deleteToken(oldToken).then(() => { + let settings = localStorage.getObject("settings"); + settings.desktopAlerts = false; + localStorage.setObject("settings", settings); + localStorage.removeItem("firebase-token"); + this.setState({ desktopAlerts: false, firebaseToken: null }); + }).catch(err => { + console.log("Unable to delete token.", err); + }); + } else { + this.setState({ desktopAlerts: false, firebaseToken: null }); + } + } + + requestPushToken(oldToken, sendToServer) { + this.fbPush.getToken().then(refreshedToken => { + this.setState({ "firebaseToken": refreshedToken }); + if (refreshedToken != oldToken) { + localStorage.setObject("firebase-token", refreshedToken); + this.tinode.setDeviceToken(refreshedToken, sendToServer); + } + }).catch(err => { + this.handleError(err.message, "err"); + console.log("Failed to retrieve firebase token", err); + }); + } + // User clicked Cancel button in Setting or Sign Up panel. handleSidepanelCancel() { var parsed = parseUrlHash(window.location.hash); @@ -25950,7 +32656,7 @@ class TinodeWeb extends React.Component { // Request to start a new topic. New P2P topic requires peer's name. handleNewTopicRequest(peerName, pub, priv, tags) { - var topicName = peerName || this.state.tinode.newGroupTopicName(); + var topicName = peerName || this.tinode.newGroupTopicName(); if (!peerName) { this.setState({ newGroupTopicParams: { desc: { public: pub, private: { comment: priv } }, tags: tags } }, () => { this.handleTopicSelected(topicName); @@ -25973,7 +32679,7 @@ class TinodeWeb extends React.Component { } handleTopicUpdateRequest(topicName, pub, priv, permissions) { - var topic = this.state.tinode.getTopic(topicName); + var topic = this.tinode.getTopic(topicName); if (topic) { var params = {}; if (pub) { @@ -25992,7 +32698,7 @@ class TinodeWeb extends React.Component { } handleChangePermissions(topicName, mode, uid) { - var topic = this.state.tinode.getTopic(topicName); + var topic = this.tinode.getTopic(topicName); if (topic) { var am = topic.getAccessMode(); if (uid) { @@ -26009,7 +32715,7 @@ class TinodeWeb extends React.Component { } handleTagsUpdated(topicName, tags) { - var topic = this.state.tinode.getTopic(topicName); + var topic = this.tinode.getTopic(topicName); if (topic) { var instance = this; topic.setMeta({ tags: tags }).catch(err => { @@ -26026,7 +32732,7 @@ class TinodeWeb extends React.Component { } handleLeaveUnsubRequest(topicName) { - var topic = this.state.tinode.getTopic(topicName); + var topic = this.tinode.getTopic(topicName); if (!topic) { return; } @@ -26058,7 +32764,7 @@ class TinodeWeb extends React.Component { blocked = false, subscribed = false, deleter = false; - var topic = this.state.tinode.getTopic(topicName); + var topic = this.tinode.getTopic(topicName); if (topic) { if (topic.isSubscribed()) { subscribed = true; @@ -26096,7 +32802,7 @@ class TinodeWeb extends React.Component { return; } - var topic = this.state.tinode.getTopic(topicName); + var topic = this.tinode.getTopic(topicName); if (!topic) { return; } @@ -26128,7 +32834,7 @@ class TinodeWeb extends React.Component { 'div', { id: 'app-container' }, this.state.contextMenuVisible ? React.createElement(ContextMenu, { - tinode: this.state.tinode, + tinode: this.tinode, bounds: this.state.contextMenuBounds, clickAt: this.state.contextMenuClickAt, params: this.state.contextMenuParams, @@ -26137,7 +32843,7 @@ class TinodeWeb extends React.Component { onAction: this.handleContextMenuAction, onError: this.handleError }) : null, React.createElement(SidepanelView, { - tinode: this.state.tinode, + tinode: this.tinode, connected: this.state.connected, displayMobile: this.state.displayMobile, hideSelf: this.state.displayMobile && this.state.mobilePanel !== 'sidepanel', @@ -26182,7 +32888,7 @@ class TinodeWeb extends React.Component { showContextMenu: this.handleShowContextMenu }), React.createElement(MessagesView, { - tinode: this.state.tinode, + tinode: this.tinode, connected: this.state.connected, online: this.state.topicSelectedOnline, acs: this.state.topicSelectedAcs, @@ -26205,7 +32911,7 @@ class TinodeWeb extends React.Component { showContextMenu: this.handleShowContextMenu, sendMessage: this.handleSendMessage }), this.state.showInfoPanel ? React.createElement(InfoView, { - tinode: this.state.tinode, + tinode: this.tinode, connected: this.state.connected, displayMobile: this.state.displayMobile, topic: this.state.topicSelected, @@ -26232,7 +32938,7 @@ class TinodeWeb extends React.Component { module.exports = TinodeWeb; -},{"react":23,"react-dom":20,"tinode-sdk":24}],27:[function(require,module,exports){ +},{"firebase/app":19,"firebase/messaging":20,"react":29,"react-dom":26,"tinode-sdk":30}],35:[function(require,module,exports){ // shim for using process in browser var process = module.exports = {}; @@ -26418,5 +33124,84 @@ process.chdir = function (dir) { }; process.umask = function() { return 0; }; -},{}]},{},[25])(25) +},{}],36:[function(require,module,exports){ +(function (setImmediate,clearImmediate){ +var nextTick = require('process/browser.js').nextTick; +var apply = Function.prototype.apply; +var slice = Array.prototype.slice; +var immediateIds = {}; +var nextImmediateId = 0; + +// DOM APIs, for completeness + +exports.setTimeout = function() { + return new Timeout(apply.call(setTimeout, window, arguments), clearTimeout); +}; +exports.setInterval = function() { + return new Timeout(apply.call(setInterval, window, arguments), clearInterval); +}; +exports.clearTimeout = +exports.clearInterval = function(timeout) { timeout.close(); }; + +function Timeout(id, clearFn) { + this._id = id; + this._clearFn = clearFn; +} +Timeout.prototype.unref = Timeout.prototype.ref = function() {}; +Timeout.prototype.close = function() { + this._clearFn.call(window, this._id); +}; + +// Does not start the time, just sets up the members needed. +exports.enroll = function(item, msecs) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = msecs; +}; + +exports.unenroll = function(item) { + clearTimeout(item._idleTimeoutId); + item._idleTimeout = -1; +}; + +exports._unrefActive = exports.active = function(item) { + clearTimeout(item._idleTimeoutId); + + var msecs = item._idleTimeout; + if (msecs >= 0) { + item._idleTimeoutId = setTimeout(function onTimeout() { + if (item._onTimeout) + item._onTimeout(); + }, msecs); + } +}; + +// That's not how node.js implements it but the exposed api is the same. +exports.setImmediate = typeof setImmediate === "function" ? setImmediate : function(fn) { + var id = nextImmediateId++; + var args = arguments.length < 2 ? false : slice.call(arguments, 1); + + immediateIds[id] = true; + + nextTick(function onNextTick() { + if (immediateIds[id]) { + // fn.call() is faster so we optimize for the common use-case + // @see http://jsperf.com/call-apply-segu + if (args) { + fn.apply(null, args); + } else { + fn.call(null); + } + // Prevent ids from leaking + exports.clearImmediate(id); + } + }); + + return id; +}; + +exports.clearImmediate = typeof clearImmediate === "function" ? clearImmediate : function(id) { + delete immediateIds[id]; +}; +}).call(this,require("timers").setImmediate,require("timers").clearImmediate) +},{"process/browser.js":35,"timers":36}]},{},[33])(33) }); diff --git a/umd/index.prod.js b/umd/index.prod.js index a4c6915c..1d18e4d1 100644 --- a/umd/index.prod.js +++ b/umd/index.prod.js @@ -1 +1 @@ -!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).Webapp=e()}}(function(){return function(){return function e(t,n,r){function a(o,s){if(!n[o]){if(!t[o]){var l="function"==typeof require&&require;if(!s&&l)return l(o,!0);if(i)return i(o,!0);var c=new Error("Cannot find module '"+o+"'");throw c.code="MODULE_NOT_FOUND",c}var u=n[o]={exports:{}};t[o][0].call(u.exports,function(e){return a(t[o][1][e]||e)},u,u.exports,e,t,n,r)}return n[o].exports}for(var i="function"==typeof require&&require,o=0;o2?n-2:0),a=2;a1?t-1:0),r=1;r-1||n(!1,"EventPluginRegistry: Cannot inject event plugins that do not exist in the plugin ordering, `%s`.",e),!T[r]){t.extractEvents||n(!1,"EventPluginRegistry: Event plugins must implement an `extractEvents` method, but `%s` does not.",e),T[r]=t;var a=t.eventTypes;for(var i in a)S(a[i],t,i)||n(!1,"EventPluginRegistry: Failed to publish event `%s` for plugin `%s`.",i,e)}}}function S(e,t,r){x.hasOwnProperty(r)&&n(!1,"EventPluginHub: More than one plugin attempted to publish the same event name, `%s`.",r),x[r]=e;var a=e.phasedRegistrationNames;if(a){for(var i in a){if(a.hasOwnProperty(i))k(a[i],t,r)}return!0}return!!e.registrationName&&(k(e.registrationName,t,r),!0)}function k(e,t,r){_[e]&&n(!1,"EventPluginHub: More than one plugin attempted to publish the same registration name, `%s`.",e),_[e]=t,P[e]=t.eventTypes[r].dependencies;var a=e.toLowerCase();N[a]=e,"onDoubleClick"===e&&(N.ondblclick=e)}var T=[],x={},_={},P={},N={};function M(e){w&&n(!1,"EventPluginRegistry: Cannot inject event plugin ordering more than once. You are likely trying to load more than one copy of React."),w=Array.prototype.slice.call(e),C()}function R(e){var t=!1;for(var r in e)if(e.hasOwnProperty(r)){var a=e[r];E.hasOwnProperty(r)&&E[r]===a||(E[r]&&n(!1,"EventPluginRegistry: Cannot inject two different event plugins using the same name, `%s`.",r),E[r]=a,t=!0)}t&&C()}var U=Object.freeze({plugins:T,eventNameDispatchConfigs:x,registrationNameModules:_,registrationNameDependencies:P,possibleRegistrationNames:N,injectEventPluginOrder:M,injectEventPluginsByName:R}),D=null,I=null,A=null,O=function(e){D=e.getFiberCurrentPropsFromNode,I=e.getInstanceFromNode,(A=e.getNodeFromInstance)&&I||a(!1,"EventPluginUtils.injection.injectComponentTree(...): Injected module is missing getNodeFromInstance or getInstanceFromNode.")},F=void 0;function L(e,t,n,r){var a=e.type||"unknown-event";e.currentTarget=A(r),b.invokeGuardedCallbackAndCatchFirstError(a,n,void 0,e),e.currentTarget=null}function j(e,t){return null==t&&n(!1,"accumulateInto(...): Accumulated items must not be null or undefined."),null==e?t:Array.isArray(e)?Array.isArray(t)?(e.push.apply(e,t),e):(e.push(t),e):Array.isArray(t)?[e].concat(t):[e,t]}function z(e,t,n){Array.isArray(e)?e.forEach(t,n):e&&t.call(n,e)}F=function(e){var t=e._dispatchListeners,n=e._dispatchInstances,r=Array.isArray(t),i=r?t.length:t?1:0,o=Array.isArray(n),s=o?n.length:n?1:0;(o!==r||s!==i)&&a(!1,"EventPluginUtils: Invalid `event`.")};var W=null,q=function(e,t){e&&(!function(e,t){var n=e._dispatchListeners,r=e._dispatchInstances;if(F(e),Array.isArray(n))for(var a=0;a0;)t(r[a],"captured",n);for(a=0;a0;)e=we(e),n--;for(;a-n>0;)t=we(t),a--;for(var o=n;o--;){if(e===t||e===t.alternate)return e;e=we(e),t=we(t)}return null}(e,t):null,o=[];e&&e!==i;){var s=e.alternate;if(null!==s&&s===i)break;o.push(e),e=we(e)}for(var l=[];t&&t!==i;){var c=t.alternate;if(null!==c&&c===i)break;l.push(t),t=we(t)}for(var u=0;u0;)n(l[d],"captured",a)}function Se(e,t,n){e||a(!1,"Dispatching inst must not be null");var r=function(e,t,n){return G(e,t.dispatchConfig.phasedRegistrationNames[n])}(e,n,t);r&&(n._dispatchListeners=j(n._dispatchListeners,r),n._dispatchInstances=j(n._dispatchInstances,e))}function ke(e){e&&e.dispatchConfig.phasedRegistrationNames&&Ee(e._targetInst,Se,e)}function Te(e){if(e&&e.dispatchConfig.phasedRegistrationNames){var t=e._targetInst;Ee(t?we(t):null,Se,e)}}function xe(e,t,n){if(e&&n&&n.dispatchConfig.registrationName){var r=G(e,n.dispatchConfig.registrationName);r&&(n._dispatchListeners=j(n._dispatchListeners,r),n._dispatchInstances=j(n._dispatchInstances,e))}}function _e(e){e&&e.dispatchConfig.registrationName&&xe(e._targetInst,0,e)}function Pe(e){z(e,ke)}function Ne(e,t,n,r){Ce(n,r,xe,e,t)}var Me=Object.freeze({accumulateTwoPhaseDispatches:Pe,accumulateTwoPhaseDispatchesSkipTarget:function(e){z(e,Te)},accumulateEnterLeaveDispatches:Ne,accumulateDirectDispatches:function(e){z(e,_e)}});function Re(e){return e}function Ue(e,t){var n={};return n[e.toLowerCase()]=t.toLowerCase(),n["Webkit"+e]="webkit"+t,n["Moz"+e]="moz"+t,n["ms"+e]="MS"+t,n["O"+e]="o"+t.toLowerCase(),n}var De={animationend:Ue("Animation","AnimationEnd"),animationiteration:Ue("Animation","AnimationIteration"),animationstart:Ue("Animation","AnimationStart"),transitionend:Ue("Transition","TransitionEnd")},Ie={},Ae={};function Oe(e){if(Ie[e])return Ie[e];if(!De[e])return e;var t=De[e];for(var n in t)if(t.hasOwnProperty(n)&&n in Ae)return Ie[e]=t[n];return e}i.canUseDOM&&(Ae=document.createElement("div").style,"AnimationEvent"in window||(delete De.animationend.animation,delete De.animationiteration.animation,delete De.animationstart.animation),"TransitionEvent"in window||delete De.transitionend.transition);var Fe=Re("abort"),Le=Re(Oe("animationend")),je=Re(Oe("animationiteration")),ze=Re(Oe("animationstart")),We=Re("blur"),qe=Re("canplay"),Ve=Re("canplaythrough"),Be=Re("cancel"),He=Re("change"),Ge=Re("click"),Ke=Re("close"),$e=Re("compositionend"),Qe=Re("compositionstart"),Ye=Re("compositionupdate"),Xe=Re("contextmenu"),Je=Re("copy"),Ze=Re("cut"),et=Re("dblclick"),tt=Re("drag"),nt=Re("dragend"),rt=Re("dragenter"),at=Re("dragexit"),it=Re("dragleave"),ot=Re("dragover"),st=Re("dragstart"),lt=Re("drop"),ct=Re("durationchange"),ut=Re("emptied"),dt=Re("encrypted"),pt=Re("ended"),ht=Re("error"),ft=Re("focus"),mt=Re("gotpointercapture"),gt=Re("input"),vt=Re("invalid"),bt=Re("keydown"),yt=Re("keypress"),wt=Re("keyup"),Et=Re("load"),Ct=Re("loadstart"),St=Re("loadeddata"),kt=Re("loadedmetadata"),Tt=Re("lostpointercapture"),xt=Re("mousedown"),_t=Re("mousemove"),Pt=Re("mouseout"),Nt=Re("mouseover"),Mt=Re("mouseup"),Rt=Re("paste"),Ut=Re("pause"),Dt=Re("play"),It=Re("playing"),At=Re("pointercancel"),Ot=Re("pointerdown"),Ft=Re("pointermove"),Lt=Re("pointerout"),jt=Re("pointerover"),zt=Re("pointerup"),Wt=Re("progress"),qt=Re("ratechange"),Vt=Re("reset"),Bt=Re("scroll"),Ht=Re("seeked"),Gt=Re("seeking"),Kt=Re("selectionchange"),$t=Re("stalled"),Qt=Re("submit"),Yt=Re("suspend"),Xt=Re("textInput"),Jt=Re("timeupdate"),Zt=Re("toggle"),en=Re("touchcancel"),tn=Re("touchend"),nn=Re("touchmove"),rn=Re("touchstart"),an=Re(Oe("transitionend")),on=Re("volumechange"),sn=Re("waiting"),ln=Re("wheel"),cn=[Fe,qe,Ve,ct,ut,dt,pt,ht,St,kt,Ct,Ut,Dt,It,Wt,qt,Ht,Gt,$t,Yt,Jt,on,sn];function un(e){return function(e){return e}(e)}var dn=null;function pn(){return!dn&&i.canUseDOM&&(dn="textContent"in document.documentElement?"textContent":"innerText"),dn}var hn={_root:null,_startText:null,_fallbackText:null};function fn(){if(hn._fallbackText)return hn._fallbackText;var e=void 0,t=hn._startText,n=t.length,r=void 0,a=mn(),i=a.length;for(e=0;e1?1-r:void 0;return hn._fallbackText=a.slice(e,s),hn._fallbackText}function mn(){return"value"in hn._root?hn._root.value:hn._root[pn()]}var gn=!1,vn=10,bn=["dispatchConfig","_targetInst","nativeEvent","isDefaultPrevented","isPropagationStopped","_dispatchListeners","_dispatchInstances"],yn={type:null,target:null,currentTarget:s.thatReturnsNull,eventPhase:null,bubbles:null,cancelable:null,timeStamp:function(e){return e.timeStamp||Date.now()},defaultPrevented:null,isTrusted:null};function wn(e,t,n,r){delete this.nativeEvent,delete this.preventDefault,delete this.stopPropagation,this.dispatchConfig=e,this._targetInst=t,this.nativeEvent=n;var a=this.constructor.Interface;for(var i in a)if(a.hasOwnProperty(i)){delete this[i];var o=a[i];o?this[i]=o(n):"target"===i?this.target=r:this[i]=n[i]}var l=null!=n.defaultPrevented?n.defaultPrevented:!1===n.returnValue;return this.isDefaultPrevented=l?s.thatReturnsTrue:s.thatReturnsFalse,this.isPropagationStopped=s.thatReturnsFalse,this}function En(e,t){var n="function"==typeof t;return{configurable:!0,set:function(e){return r(n?"setting the method":"setting the property","This is effectively a no-op"),e},get:function(){return r(n?"accessing the method":"accessing the property",n?"This is a no-op function":"This is set to null"),t}};function r(t,n){a(!1,"This synthetic event is reused for performance reasons. If you're seeing this, you're %s `%s` on a released/nullified synthetic event. %s. If you must keep the original synthetic event around, use event.persist(). See https://fb.me/react-event-pooling for more information.",t,e,n)}}function Cn(e,t,n,r){if(this.eventPool.length){var a=this.eventPool.pop();return this.call(a,e,t,n,r),a}return new this(e,t,n,r)}function Sn(e){e instanceof this||n(!1,"Trying to release an event instance into a pool of a different type."),e.destructor(),this.eventPool.length8&&Rn<=11),In=32,An=String.fromCharCode(In),On={beforeInput:{phasedRegistrationNames:{bubbled:"onBeforeInput",captured:"onBeforeInputCapture"},dependencies:[$e,yt,Xt,Rt]},compositionEnd:{phasedRegistrationNames:{bubbled:"onCompositionEnd",captured:"onCompositionEndCapture"},dependencies:[We,$e,bt,yt,wt,xt]},compositionStart:{phasedRegistrationNames:{bubbled:"onCompositionStart",captured:"onCompositionStartCapture"},dependencies:[We,Qe,bt,yt,wt,xt]},compositionUpdate:{phasedRegistrationNames:{bubbled:"onCompositionUpdate",captured:"onCompositionUpdateCapture"},dependencies:[We,Ye,bt,yt,wt,xt]}},Fn=!1;function Ln(e,t){switch(e){case wt:return-1!==Pn.indexOf(t.keyCode);case bt:return t.keyCode!==Nn;case yt:case xt:case We:return!0;default:return!1}}function jn(e){var t=e.detail;return"object"==typeof t&&"data"in t?t.data:null}var zn=!1;function Wn(e,t,n,r){var a=void 0,i=void 0;if(Mn?a=function(e){switch(e){case Qe:return On.compositionStart;case $e:return On.compositionEnd;case Ye:return On.compositionUpdate}}(e):zn?Ln(e,n)&&(a=On.compositionEnd):function(e,t){return e===bt&&t.keyCode===Nn}(e,n)&&(a=On.compositionStart),!a)return null;Dn&&(zn||a!==On.compositionStart?a===On.compositionEnd&&zn&&(i=fn()):zn=function(e){return hn._root=e,hn._startText=mn(),!0}(r));var o=xn.getPooled(a,t,n,r);if(i)o.data=i;else{var s=jn(n);null!==s&&(o.data=s)}return Pe(o),o}function qn(e,t){if(zn){if(e===$e||!Mn&&Ln(e,t)){var n=fn();return hn._root=null,hn._startText=null,hn._fallbackText=null,zn=!1,n}return null}switch(e){case Rt:return null;case yt:if(!function(e){return(e.ctrlKey||e.altKey||e.metaKey)&&!(e.ctrlKey&&e.altKey)}(t)){if(t.char&&t.char.length>1)return t.char;if(t.which)return String.fromCharCode(t.which)}return null;case $e:return Dn?null:t.data;default:return null}}function Vn(e,t,n,r){var a=void 0;if(!(a=Un?function(e,t){switch(e){case $e:return jn(t);case yt:return t.which!==In?null:(Fn=!0,An);case Xt:var n=t.data;return n===An&&Fn?null:n;default:return null}}(e,n):qn(e,n)))return null;var i=_n.getPooled(On.beforeInput,t,n,r);return i.data=a,Pe(i),i}var Bn={eventTypes:On,extractEvents:function(e,t,n,r){var a=Wn(e,t,n,r),i=Vn(e,t,n,r);return null===a?i:null===i?a:[a,i]}},Hn=null,Gn=null,Kn=null;function $n(e){var t=I(e);if(t){Hn&&"function"==typeof Hn.restoreControlledState||n(!1,"Fiber needs to be injected to handle a fiber target for controlled events. This error is likely caused by a bug in React. Please file an issue.");var r=D(t.stateNode);Hn.restoreControlledState(t.stateNode,t.type,r)}}var Qn={injectFiberControlledHostComponent:function(e){Hn=e}};function Yn(e){Gn?Kn?Kn.push(e):Kn=[e]:Gn=e}function Xn(){return null!==Gn||null!==Kn}function Jn(){if(Gn){var e=Gn,t=Kn;if(Gn=null,Kn=null,$n(e),t)for(var n=0;n2&&("o"===e[0]||"O"===e[0])&&("n"===e[1]||"N"===e[1]))}function ra(e,t,n,r){if(null!==n&&n.type===qr)return!1;switch(typeof t){case"function":case"symbol":return!0;case"boolean":if(r)return!1;if(null!==n)return!n.acceptsBooleans;var a=e.toLowerCase().slice(0,5);return"data-"!==a&&"aria-"!==a;default:return!1}}function aa(e,t,n,r){if(null===t||void 0===t)return!0;if(ra(e,t,n,r))return!0;if(r)return!1;if(null!==n)switch(n.type){case Br:return!t;case Hr:return!1===t;case Gr:return isNaN(t);case Kr:return isNaN(t)||t<1}return!1}function ia(e){return sa.hasOwnProperty(e)?sa[e]:null}function oa(e,t,n,r,a){this.acceptsBooleans=t===Vr||t===Br||t===Hr,this.attributeName=r,this.attributeNamespace=a,this.mustUseProperty=n,this.propertyName=e,this.type=t}var sa={};["children","dangerouslySetInnerHTML","defaultValue","defaultChecked","innerHTML","suppressContentEditableWarning","suppressHydrationWarning","style"].forEach(function(e){sa[e]=new oa(e,qr,!1,e,null)}),[["acceptCharset","accept-charset"],["className","class"],["htmlFor","for"],["httpEquiv","http-equiv"]].forEach(function(e){var t=e[0],n=e[1];sa[t]=new oa(t,1,!1,n,null)}),["contentEditable","draggable","spellCheck","value"].forEach(function(e){sa[e]=new oa(e,Vr,!1,e.toLowerCase(),null)}),["autoReverse","externalResourcesRequired","preserveAlpha"].forEach(function(e){sa[e]=new oa(e,Vr,!1,e,null)}),["allowFullScreen","async","autoFocus","autoPlay","controls","default","defer","disabled","formNoValidate","hidden","loop","noModule","noValidate","open","playsInline","readOnly","required","reversed","scoped","seamless","itemScope"].forEach(function(e){sa[e]=new oa(e,Br,!1,e.toLowerCase(),null)}),["checked","multiple","muted","selected"].forEach(function(e){sa[e]=new oa(e,Br,!0,e.toLowerCase(),null)}),["capture","download"].forEach(function(e){sa[e]=new oa(e,Hr,!1,e.toLowerCase(),null)}),["cols","rows","size","span"].forEach(function(e){sa[e]=new oa(e,Kr,!1,e.toLowerCase(),null)}),["rowSpan","start"].forEach(function(e){sa[e]=new oa(e,Gr,!1,e.toLowerCase(),null)});var la=/[\-\:]([a-z])/g,ca=function(e){return e[1].toUpperCase()};function ua(e,t,n,r){if(r.mustUseProperty)return e[r.propertyName];var a=r.attributeName,i=null;if(r.type===Hr){if(e.hasAttribute(a)){var o=e.getAttribute(a);return""===o||(aa(t,n,r,!1)?o:o===""+n?n:o)}}else if(e.hasAttribute(a)){if(aa(t,n,r,!1))return e.getAttribute(a);if(r.type===Br)return n;i=e.getAttribute(a)}return aa(t,n,r,!1)?null===i?n:i:i===""+n?n:i}function da(e,t,n){if(ta(t)){if(!e.hasAttribute(t))return void 0===n?void 0:null;var r=e.getAttribute(t);return r===""+n?n:r}}function pa(e,t,n,r){var a=ia(t);if(!na(t,a,r))if(aa(t,n,a,r)&&(n=null),r||null===a){if(ta(t)){var i=t;null===n?e.removeAttribute(i):e.setAttribute(i,""+n)}}else if(a.mustUseProperty){var o=a.propertyName;if(null===n){var s=a.type;e[o]=s!==Br&&""}else e[o]=n}else{var l=a.attributeName,c=a.attributeNamespace;if(null===n)e.removeAttribute(l);else{var u=a.type,d=void 0;d=u===Br||u===Hr&&!0===n?"":""+n,c?e.setAttributeNS(c,l,d):e.setAttribute(l,d)}}}["accent-height","alignment-baseline","arabic-form","baseline-shift","cap-height","clip-path","clip-rule","color-interpolation","color-interpolation-filters","color-profile","color-rendering","dominant-baseline","enable-background","fill-opacity","fill-rule","flood-color","flood-opacity","font-family","font-size","font-size-adjust","font-stretch","font-style","font-variant","font-weight","glyph-name","glyph-orientation-horizontal","glyph-orientation-vertical","horiz-adv-x","horiz-origin-x","image-rendering","letter-spacing","lighting-color","marker-end","marker-mid","marker-start","overline-position","overline-thickness","paint-order","panose-1","pointer-events","rendering-intent","shape-rendering","stop-color","stop-opacity","strikethrough-position","strikethrough-thickness","stroke-dasharray","stroke-dashoffset","stroke-linecap","stroke-linejoin","stroke-miterlimit","stroke-opacity","stroke-width","text-anchor","text-decoration","text-rendering","underline-position","underline-thickness","unicode-bidi","unicode-range","units-per-em","v-alphabetic","v-hanging","v-ideographic","v-mathematical","vector-effect","vert-adv-y","vert-origin-x","vert-origin-y","word-spacing","writing-mode","xmlns:xlink","x-height"].forEach(function(e){var t=e.replace(la,ca);sa[t]=new oa(t,1,!1,e,null)}),["xlink:actuate","xlink:arcrole","xlink:href","xlink:role","xlink:show","xlink:title","xlink:type"].forEach(function(e){var t=e.replace(la,ca);sa[t]=new oa(t,1,!1,e,"http://www.w3.org/1999/xlink")}),["xml:base","xml:lang","xml:space"].forEach(function(e){var t=e.replace(la,ca);sa[t]=new oa(t,1,!1,e,"http://www.w3.org/XML/1998/namespace")}),sa.tabIndex=new oa("tabIndex",1,!1,"tabindex",null);var ha={checkPropTypes:null},fa={button:!0,checkbox:!0,image:!0,hidden:!0,radio:!0,reset:!0,submit:!0},ma={value:function(e,t,n){return!e[t]||fa[e.type]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `value` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultValue`. Otherwise, set either `onChange` or `readOnly`.")},checked:function(e,t,n){return!e[t]||e.onChange||e.readOnly||e.disabled?null:new Error("You provided a `checked` prop to a form field without an `onChange` handler. This will render a read-only field. If the field should be mutable use `defaultChecked`. Otherwise, set either `onChange` or `readOnly`.")}};ha.checkPropTypes=function(e,t,n){l(ma,t,"prop",e,n)};var ga=Wr.getCurrentFiberOwnerName,va=Wr.getCurrentFiberStackAddendum,ba=!1,ya=!1,wa=!1,Ea=!1;function Ca(e){return"checkbox"===e.type||"radio"===e.type?null!=e.checked:null!=e.value}function Sa(e,t){var n=e,r=t.checked;return o({},t,{defaultChecked:void 0,defaultValue:void 0,value:void 0,checked:null!=r?r:n._wrapperState.initialChecked})}function ka(e,t){ha.checkPropTypes("input",t,va),void 0===t.checked||void 0===t.defaultChecked||ya||(a(!1,"%s contains an input of type %s with both checked and defaultChecked props. Input elements must be either controlled or uncontrolled (specify either the checked prop, or the defaultChecked prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://fb.me/react-controlled-components",ga()||"A component",t.type),ya=!0),void 0===t.value||void 0===t.defaultValue||ba||(a(!1,"%s contains an input of type %s with both value and defaultValue props. Input elements must be either controlled or uncontrolled (specify either the value prop, or the defaultValue prop, but not both). Decide between using a controlled or uncontrolled input element and remove one of these props. More info: https://fb.me/react-controlled-components",ga()||"A component",t.type),ba=!0);var n=e,r=null==t.defaultValue?"":t.defaultValue;n._wrapperState={initialChecked:null!=t.checked?t.checked:t.defaultChecked,initialValue:Ma(null!=t.value?t.value:r),controlled:Ca(t)}}function Ta(e,t){var n=e,r=t.checked;null!=r&&pa(n,"checked",r,!1)}function xa(e,t){var n=e,r=Ca(t);n._wrapperState.controlled||!r||Ea||(a(!1,"A component is changing an uncontrolled input of type %s to be controlled. Input elements should not switch from uncontrolled to controlled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s",t.type,va()),Ea=!0),!n._wrapperState.controlled||r||wa||(a(!1,"A component is changing a controlled input of type %s to be uncontrolled. Input elements should not switch from controlled to uncontrolled (or vice versa). Decide between using a controlled or uncontrolled input element for the lifetime of the component. More info: https://fb.me/react-controlled-components%s",t.type,va()),wa=!0),Ta(e,t);var i=Ma(t.value);null!=i&&("number"===t.type?(0===i&&""===n.value||n.value!=i)&&(n.value=""+i):n.value!==""+i&&(n.value=""+i)),t.hasOwnProperty("value")?Na(n,t.type,i):t.hasOwnProperty("defaultValue")&&Na(n,t.type,Ma(t.defaultValue)),null==t.checked&&null!=t.defaultChecked&&(n.defaultChecked=!!t.defaultChecked)}function _a(e,t,n){var r=e;if(t.hasOwnProperty("value")||t.hasOwnProperty("defaultValue")){var a=""+r._wrapperState.initialValue,i=r.value;n||a!==i&&(r.value=a),r.defaultValue=a}var o=r.name;""!==o&&(r.name=""),r.defaultChecked=!r.defaultChecked,r.defaultChecked=!r.defaultChecked,""!==o&&(r.name=o)}function Pa(e,t){var r=e;xa(r,t),function(e,t){var r=t.name;if("radio"===t.type&&null!=r){for(var a=e;a.parentNode;)a=a.parentNode;for(var i=a.querySelectorAll("input[name="+JSON.stringify(""+r)+'][type="radio"]'),o=0;o9));var Ha={eventTypes:Ra,_isInputEventSupported:La,extractEvents:function(e,t,n,r){var a,i,o,s,l=t?ge(t):window,c=void 0,u=void 0;if("select"===(i=(a=l).nodeName&&a.nodeName.toLowerCase())||"input"===i&&"file"===a.type?c=Fa:sr(l)?La?c=Ba:(c=qa,u=Wa):function(e){var t=e.nodeName;return t&&"input"===t.toLowerCase()&&("checkbox"===e.type||"radio"===e.type)}(l)&&(c=Va),c){var d=c(e,t);if(d)return Ua(d,n,r)}u&&u(e,l,t),e===We&&(s=(o=l)._wrapperState)&&s.controlled&&"number"===o.type&&Na(o,"number",o.value)}},Ga=Tn.extend({view:null,detail:null}),Ka={Alt:"altKey",Control:"ctrlKey",Meta:"metaKey",Shift:"shiftKey"};function $a(e){var t=this.nativeEvent;if(t.getModifierState)return t.getModifierState(e);var n=Ka[e];return!!n&&!!t[n]}function Qa(e){return $a}var Ya=Ga.extend({screenX:null,screenY:null,clientX:null,clientY:null,pageX:null,pageY:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,getModifierState:Qa,button:null,buttons:null,relatedTarget:function(e){return e.relatedTarget||(e.fromElement===e.srcElement?e.toElement:e.fromElement)}}),Xa=Ya.extend({pointerId:null,width:null,height:null,pressure:null,tiltX:null,tiltY:null,pointerType:null,isPrimary:null}),Ja={mouseEnter:{registrationName:"onMouseEnter",dependencies:[Pt,Nt]},mouseLeave:{registrationName:"onMouseLeave",dependencies:[Pt,Nt]},pointerEnter:{registrationName:"onPointerEnter",dependencies:[Lt,jt]},pointerLeave:{registrationName:"onPointerLeave",dependencies:[Lt,jt]}},Za={eventTypes:Ja,extractEvents:function(e,t,n,r){var a=e===Nt||e===jt,i=e===Pt||e===Lt;if(a&&(n.relatedTarget||n.fromElement))return null;if(!i&&!a)return null;var o=void 0;if(r.window===r)o=r;else{var s=r.ownerDocument;o=s?s.defaultView||s.parentWindow:window}var l=void 0,c=void 0;if(i){l=t;var u=n.relatedTarget||n.toElement;c=u?fe(u):null}else l=null,c=t;if(l===c)return null;var d=void 0,p=void 0,h=void 0,f=void 0;e===Pt||e===Nt?(d=Ya,p=Ja.mouseLeave,h=Ja.mouseEnter,f="mouse"):e!==Lt&&e!==jt||(d=Xa,p=Ja.pointerLeave,h=Ja.pointerEnter,f="pointer");var m=null==l?o:ge(l),g=null==c?o:ge(c),v=d.getPooled(p,l,n,r);v.type=f+"leave",v.target=m,v.relatedTarget=g;var b=d.getPooled(h,c,n,r);return b.type=f+"enter",b.target=g,b.relatedTarget=m,Ne(v,b,l,c),[v,b]}};function ei(e){return e._reactInternalFiber}var ti=0,ni=1,ri=2,ai=4,ii=6,oi=8,si=16,li=32,ci=64,ui=128,di=256,pi=511,hi=512,fi=1024,mi=1,gi=2,vi=3;function bi(e){var t=e;if(e.alternate)for(;t.return;)t=t.return;else{if((t.effectTag&ri)!==ti)return mi;for(;t.return;)if(((t=t.return).effectTag&ri)!==ti)return mi}return t.tag===Z?gi:vi}function yi(e){return bi(e)===gi}function wi(e){bi(e)!==gi&&n(!1,"Unable to find node on an unmounted component.")}function Ei(e){var t=e.alternate;if(!t){var r=bi(e);return r===vi&&n(!1,"Unable to find node on an unmounted component."),r===mi?null:e}for(var a=e,i=t;;){var o=a.return,s=o?o.alternate:null;if(!o||!s)break;if(o.child===s.child){for(var l=o.child;l;){if(l===a)return wi(o),e;if(l===i)return wi(o),t;l=l.sibling}n(!1,"Unable to find node on an unmounted component.")}if(a.return!==i.return)a=o,i=s;else{for(var c=!1,u=o.child;u;){if(u===a){c=!0,a=o,i=s;break}if(u===i){c=!0,i=o,a=s;break}u=u.sibling}if(!c){for(u=s.child;u;){if(u===a){c=!0,a=s,i=o;break}if(u===i){c=!0,i=s,a=o;break}u=u.sibling}c||n(!1,"Child was not found in either parent set. This indicates a bug in React related to the return pointer. Please file an issue.")}}a.alternate!==i&&n(!1,"Return fibers should always be each others' alternates. This error is likely caused by a bug in React. Please file an issue.")}return a.tag!==Z&&n(!1,"Unable to find node on an unmounted component."),a.stateNode.current===a?e:t}function Ci(e){var t=Ei(e);if(!t)return null;for(var n=t;;){if(n.tag===te||n.tag===ne)return n;if(n.child)n.child.return=n,n=n.child;else{if(n===t)return null;for(;!n.sibling;){if(!n.return||n.return===t)return null;n=n.return}n.sibling.return=n.return,n=n.sibling}}return null}var Si=Tn.extend({animationName:null,elapsedTime:null,pseudoElement:null}),ki=Tn.extend({clipboardData:function(e){return"clipboardData"in e?e.clipboardData:window.clipboardData}}),Ti=Ga.extend({relatedTarget:null});function xi(e){var t=void 0,n=e.keyCode;return"charCode"in e?0===(t=e.charCode)&&13===n&&(t=13):t=n,10===t&&(t=13),t>=32||13===t?t:0}var _i={Esc:"Escape",Spacebar:" ",Left:"ArrowLeft",Up:"ArrowUp",Right:"ArrowRight",Down:"ArrowDown",Del:"Delete",Win:"OS",Menu:"ContextMenu",Apps:"ContextMenu",Scroll:"ScrollLock",MozPrintableKey:"Unidentified"},Pi={8:"Backspace",9:"Tab",12:"Clear",13:"Enter",16:"Shift",17:"Control",18:"Alt",19:"Pause",20:"CapsLock",27:"Escape",32:" ",33:"PageUp",34:"PageDown",35:"End",36:"Home",37:"ArrowLeft",38:"ArrowUp",39:"ArrowRight",40:"ArrowDown",45:"Insert",46:"Delete",112:"F1",113:"F2",114:"F3",115:"F4",116:"F5",117:"F6",118:"F7",119:"F8",120:"F9",121:"F10",122:"F11",123:"F12",144:"NumLock",145:"ScrollLock",224:"Meta"};var Ni=Ga.extend({key:function(e){if(e.key){var t=_i[e.key]||e.key;if("Unidentified"!==t)return t}if("keypress"===e.type){var n=xi(e);return 13===n?"Enter":String.fromCharCode(n)}return"keydown"===e.type||"keyup"===e.type?Pi[e.keyCode]||"Unidentified":""},location:null,ctrlKey:null,shiftKey:null,altKey:null,metaKey:null,repeat:null,locale:null,getModifierState:Qa,charCode:function(e){return"keypress"===e.type?xi(e):0},keyCode:function(e){return"keydown"===e.type||"keyup"===e.type?e.keyCode:0},which:function(e){return"keypress"===e.type?xi(e):"keydown"===e.type||"keyup"===e.type?e.keyCode:0}}),Mi=Ya.extend({dataTransfer:null}),Ri=Ga.extend({touches:null,targetTouches:null,changedTouches:null,altKey:null,metaKey:null,ctrlKey:null,shiftKey:null,getModifierState:Qa}),Ui=Tn.extend({propertyName:null,elapsedTime:null,pseudoElement:null}),Di=Ya.extend({deltaX:function(e){return"deltaX"in e?e.deltaX:"wheelDeltaX"in e?-e.wheelDeltaX:0},deltaY:function(e){return"deltaY"in e?e.deltaY:"wheelDeltaY"in e?-e.wheelDeltaY:"wheelDelta"in e?-e.wheelDelta:0},deltaZ:null,deltaMode:null}),Ii=[[Fe,"abort"],[Le,"animationEnd"],[je,"animationIteration"],[ze,"animationStart"],[qe,"canPlay"],[Ve,"canPlayThrough"],[tt,"drag"],[rt,"dragEnter"],[at,"dragExit"],[it,"dragLeave"],[ot,"dragOver"],[ct,"durationChange"],[ut,"emptied"],[dt,"encrypted"],[pt,"ended"],[ht,"error"],[mt,"gotPointerCapture"],[Et,"load"],[St,"loadedData"],[kt,"loadedMetadata"],[Ct,"loadStart"],[Tt,"lostPointerCapture"],[_t,"mouseMove"],[Pt,"mouseOut"],[Nt,"mouseOver"],[It,"playing"],[Ft,"pointerMove"],[Lt,"pointerOut"],[jt,"pointerOver"],[Wt,"progress"],[Bt,"scroll"],[Gt,"seeking"],[$t,"stalled"],[Yt,"suspend"],[Jt,"timeUpdate"],[Zt,"toggle"],[nn,"touchMove"],[an,"transitionEnd"],[sn,"waiting"],[ln,"wheel"]],Ai={},Oi={};function Fi(e,t){var n=e[0],r=e[1],a="on"+(r[0].toUpperCase()+r.slice(1)),i={phasedRegistrationNames:{bubbled:a,captured:a+"Capture"},dependencies:[n],isInteractive:t};Ai[r]=i,Oi[n]=i}[[We,"blur"],[Be,"cancel"],[Ge,"click"],[Ke,"close"],[Xe,"contextMenu"],[Je,"copy"],[Ze,"cut"],[et,"doubleClick"],[nt,"dragEnd"],[st,"dragStart"],[lt,"drop"],[ft,"focus"],[gt,"input"],[vt,"invalid"],[bt,"keyDown"],[yt,"keyPress"],[wt,"keyUp"],[xt,"mouseDown"],[Mt,"mouseUp"],[Rt,"paste"],[Ut,"pause"],[Dt,"play"],[At,"pointerCancel"],[Ot,"pointerDown"],[zt,"pointerUp"],[qt,"rateChange"],[Vt,"reset"],[Ht,"seeked"],[Qt,"submit"],[en,"touchCancel"],[tn,"touchEnd"],[rn,"touchStart"],[on,"volumeChange"]].forEach(function(e){Fi(e,!0)}),Ii.forEach(function(e){Fi(e,!1)});var Li=[Fe,Be,qe,Ve,Ke,ct,ut,dt,pt,ht,gt,vt,Et,St,kt,Ct,Ut,Dt,It,Wt,qt,Vt,Ht,Gt,$t,Qt,Yt,Jt,Zt,on,sn],ji={eventTypes:Ai,isInteractiveTopLevelEventType:function(e){var t=Oi[e];return void 0!==t&&!0===t.isInteractive},extractEvents:function(e,t,n,r){var i=Oi[e];if(!i)return null;var o=void 0;switch(e){case yt:if(0===xi(n))return null;case bt:case wt:o=Ni;break;case We:case ft:o=Ti;break;case Ge:if(2===n.button)return null;case et:case xt:case _t:case Mt:case Pt:case Nt:case Xe:o=Ya;break;case tt:case nt:case rt:case at:case it:case ot:case st:case lt:o=Mi;break;case en:case tn:case nn:case rn:o=Ri;break;case Le:case je:case ze:o=Si;break;case an:o=Ui;break;case Bt:o=Ga;break;case ln:o=Di;break;case Je:case Ze:case Rt:o=ki;break;case mt:case Tt:case At:case Ot:case Ft:case Lt:case jt:case zt:o=Xa;break;default:-1===Li.indexOf(e)&&a(!1,"SimpleEventPlugin: Unhandled event type, `%s`. This warning is likely caused by a bug in React. Please file an issue.",e),o=Tn}var s=o.getPooled(i,t,n,r);return Pe(s),s}},zi=ji.isInteractiveTopLevelEventType,Wi=10,qi=[];function Vi(e){for(;e.return;)e=e.return;return e.tag!==Z?null:e.stateNode.containerInfo}function Bi(e){var t=e.targetInst,n=t;do{if(!n){e.ancestors.push(n);break}var r=Vi(n);if(!r)break;e.ancestors.push(n),n=fe(r)}while(n);for(var a=0;a=t)return{node:n,offset:t-r};r=a}n=ro(ao(n))}}function oo(e){var t=window.getSelection&&window.getSelection();if(!t||0===t.rangeCount)return null;var n=t.anchorNode,r=t.anchorOffset,a=t.focusNode,i=t.focusOffset;try{n.nodeType,a.nodeType}catch(e){return null}return function(e,t,n,r,a){var i=0,o=-1,s=-1,l=0,c=0,u=e,d=null;e:for(;;){for(var p=null;u!==t||0!==n&&u.nodeType!==cr||(o=i+n),u!==r||0!==a&&u.nodeType!==cr||(s=i+a),u.nodeType===cr&&(i+=u.nodeValue.length),null!==(p=u.firstChild);)d=u,u=p;for(;;){if(u===e)break e;if(d===t&&++l===n&&(o=i),d===r&&++c===a&&(s=i),null!==(p=u.nextSibling))break;d=(u=d).parentNode}u=p}if(-1===o||-1===s)return null;return{start:o,end:s}}(e,n,r,a,i)}function so(e){var t=e&&e.nodeName&&e.nodeName.toLowerCase();return t&&("input"===t&&("text"===e.type||"search"===e.type||"tel"===e.type||"url"===e.type||"password"===e.type)||"textarea"===t||"true"===e.contentEditable)}function lo(){var e=c();return{focusedElem:e,selectionRange:so(e)?function(e){var t=void 0;t="selectionStart"in e?{start:e.selectionStart,end:e.selectionEnd}:oo(e);return t||{start:0,end:0}}(e):null}}function co(e){var t,n=c(),r=e.focusedElem,a=e.selectionRange;if(n!==r&&(t=r,d(document.documentElement,t))){null!==a&&so(r)&&function(e,t){var n=t.start,r=t.end;void 0===r&&(r=n);"selectionStart"in e?(e.selectionStart=n,e.selectionEnd=Math.min(r,e.value.length)):function(e,t){if(window.getSelection){var n=window.getSelection(),r=e[pn()].length,a=Math.min(t.start,r),i=void 0===t.end?a:Math.min(t.end,r);if(!n.extend&&a>i){var o=i;i=a,a=o}var s=io(e,a),l=io(e,i);if(s&&l){if(1===n.rangeCount&&n.anchorNode===s.node&&n.anchorOffset===s.offset&&n.focusNode===l.node&&n.focusOffset===l.offset)return;var c=document.createRange();c.setStart(s.node,s.offset),n.removeAllRanges(),a>i?(n.addRange(c),n.extend(l.node,l.offset)):(c.setEnd(l.node,l.offset),n.addRange(c))}}}(e,t)}(r,a);for(var i=[],o=r;o=o.parentNode;)o.nodeType===lr&&i.push({element:o,left:o.scrollLeft,top:o.scrollTop});"function"==typeof r.focus&&r.focus();for(var s=0;s0?e:0}},Fo=function(e,t){var n=e.scheduledCallback,r=!1;try{n(t),r=!0}finally{xo(e),r||(Ro=!0,window.postMessage(Lo,"*"))}},Lo="__reactIdleCallback$"+Math.random().toString(36).slice(2);window.addEventListener("message",function(e){if(e.source===window&&e.data===Lo&&(Ro=!1,null!==Po)){!function(){if(null!==Po){var e=So();if(!(-1===Mo||Mo>e)){for(var t=-1,n=[],r=Po;null!==r;){var a=r.timeoutTime;-1!==a&&a<=e?n.push(r):-1!==a&&(-1===t||a0){Oo.didTimeout=!0;for(var i=0,o=n.length;i0&&null!==Po;){var n=Po;Oo.didTimeout=!1,Fo(n,Oo),t=So()}null!==Po&&(Uo||(Uo=!0,_o(jo)))}},!1);var jo=function(e){Uo=!1;var t=e-Do+Ao;t instead of setting `selected` on