diff --git a/.babelrc b/.babelrc index 7222309..8d40400 100644 --- a/.babelrc +++ b/.babelrc @@ -1,3 +1,9 @@ { - "presets": ["env", "react-app"] + "presets": [ + "@babel/preset-env", + "@babel/preset-react" + ], + "plugins": [ + "@babel/plugin-proposal-class-properties" + ] } diff --git a/.eslintrc.json b/.eslintrc.json index c3749a6..b135de2 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -3,7 +3,6 @@ "browser": true }, "extends": "airbnb", - "parser": "babel-eslint", "rules": { "camelcase": 0, "import/prefer-default-export": 0, diff --git a/lib/adal.js b/lib/adal.js index 899de01..c32a71f 100644 --- a/lib/adal.js +++ b/lib/adal.js @@ -1,6 +1,6 @@ -'use strict'; +"use strict"; -var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol" ? function (obj) { return typeof obj; } : function (obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } //---------------------------------------------------------------------- // AdalJS v1.0.17 @@ -20,1889 +20,2067 @@ var _typeof = typeof Symbol === "function" && typeof Symbol.iterator === "symbol // See the License for the specific language governing permissions and // limitations under the License. //---------------------------------------------------------------------- - var _AuthenticationContext = function () { + 'use strict'; + /** + * Configuration options for Authentication Context. + * @class config + * @property {string} tenant - Your target tenant. + * @property {string} clientId - Client ID assigned to your app by Azure Active Directory. + * @property {string} redirectUri - Endpoint at which you expect to receive tokens.Defaults to `window.location.href`. + * @property {string} instance - Azure Active Directory Instance.Defaults to `https://login.microsoftonline.com/`. + * @property {Array} endpoints - Collection of {Endpoint-ResourceId} used for automatically attaching tokens in webApi calls. + * @property {Boolean} popUp - Set this to true to enable login in a popup winodow instead of a full redirect.Defaults to `false`. + * @property {string} localLoginUrl - Set this to redirect the user to a custom login page. + * @property {function} displayCall - User defined function of handling the navigation to Azure AD authorization endpoint in case of login. Defaults to 'null'. + * @property {string} postLogoutRedirectUri - Redirects the user to postLogoutRedirectUri after logout. Defaults is 'redirectUri'. + * @property {string} cacheLocation - Sets browser storage to either 'localStorage' or sessionStorage'. Defaults to 'sessionStorage'. + * @property {Array.} anonymousEndpoints Array of keywords or URI's. Adal will not attach a token to outgoing requests that have these keywords or uri. Defaults to 'null'. + * @property {number} expireOffsetSeconds If the cached token is about to be expired in the expireOffsetSeconds (in seconds), Adal will renew the token instead of using the cached token. Defaults to 300 seconds. + * @property {string} correlationId Unique identifier used to map the request with the response. Defaults to RFC4122 version 4 guid (128 bits). + * @property {number} loadFrameTimeout The number of milliseconds of inactivity before a token renewal response from AAD should be considered timed out. + */ + + /** + * Creates a new AuthenticationContext object. + * @constructor + * @param {config} config Configuration options for AuthenticationContext + */ + + _AuthenticationContext = function AuthenticationContext(config) { + /** + * Enum for request type + * @enum {string} + */ + this.REQUEST_TYPE = { + LOGIN: 'LOGIN', + RENEW_TOKEN: 'RENEW_TOKEN', + UNKNOWN: 'UNKNOWN' + }; + this.RESPONSE_TYPE = { + ID_TOKEN_TOKEN: 'id_token token', + TOKEN: 'token' + }; + /** + * Enum for storage constants + * @enum {string} + */ + + this.CONSTANTS = { + ACCESS_TOKEN: 'access_token', + EXPIRES_IN: 'expires_in', + ID_TOKEN: 'id_token', + ERROR_DESCRIPTION: 'error_description', + SESSION_STATE: 'session_state', + ERROR: 'error', + STORAGE: { + TOKEN_KEYS: 'adal.token.keys', + ACCESS_TOKEN_KEY: 'adal.access.token.key', + EXPIRATION_KEY: 'adal.expiration.key', + STATE_LOGIN: 'adal.state.login', + STATE_RENEW: 'adal.state.renew', + NONCE_IDTOKEN: 'adal.nonce.idtoken', + SESSION_STATE: 'adal.session.state', + USERNAME: 'adal.username', + IDTOKEN: 'adal.idtoken', + ERROR: 'adal.error', + ERROR_DESCRIPTION: 'adal.error.description', + LOGIN_REQUEST: 'adal.login.request', + LOGIN_ERROR: 'adal.login.error', + RENEW_STATUS: 'adal.token.renew.status', + ANGULAR_LOGIN_REQUEST: 'adal.angular.login.request' + }, + RESOURCE_DELIMETER: '|', + CACHE_DELIMETER: '||', + LOADFRAME_TIMEOUT: 6000, + TOKEN_RENEW_STATUS_CANCELED: 'Canceled', + TOKEN_RENEW_STATUS_COMPLETED: 'Completed', + TOKEN_RENEW_STATUS_IN_PROGRESS: 'In Progress', + LOGGING_LEVEL: { + ERROR: 0, + WARN: 1, + INFO: 2, + VERBOSE: 3 + }, + LEVEL_STRING_MAP: { + 0: 'ERROR:', + 1: 'WARNING:', + 2: 'INFO:', + 3: 'VERBOSE:' + }, + POPUP_WIDTH: 483, + POPUP_HEIGHT: 600 + }; + + if (_AuthenticationContext.prototype._singletonInstance) { + return _AuthenticationContext.prototype._singletonInstance; + } - 'use strict'; + _AuthenticationContext.prototype._singletonInstance = this; // public + + this.instance = 'https://login.microsoftonline.com/'; + this.config = {}; + this.callback = null; + this.popUp = false; + this.isAngular = false; // private + + this._user = null; + this._activeRenewals = {}; + this._loginInProgress = false; + this._acquireTokenInProgress = false; + this._renewStates = []; + this._callBackMappedToRenewStates = {}; + this._callBacksMappedToRenewStates = {}; + this._openedWindows = []; + this._requestType = this.REQUEST_TYPE.LOGIN; + window._adalInstance = this; // validate before constructor assignments + + if (config.displayCall && typeof config.displayCall !== 'function') { + throw new Error('displayCall is not a function'); + } - /** - * Configuration options for Authentication Context. - * @class config - * @property {string} tenant - Your target tenant. - * @property {string} clientId - Client ID assigned to your app by Azure Active Directory. - * @property {string} redirectUri - Endpoint at which you expect to receive tokens.Defaults to `window.location.href`. - * @property {string} instance - Azure Active Directory Instance.Defaults to `https://login.microsoftonline.com/`. - * @property {Array} endpoints - Collection of {Endpoint-ResourceId} used for automatically attaching tokens in webApi calls. - * @property {Boolean} popUp - Set this to true to enable login in a popup winodow instead of a full redirect.Defaults to `false`. - * @property {string} localLoginUrl - Set this to redirect the user to a custom login page. - * @property {function} displayCall - User defined function of handling the navigation to Azure AD authorization endpoint in case of login. Defaults to 'null'. - * @property {string} postLogoutRedirectUri - Redirects the user to postLogoutRedirectUri after logout. Defaults is 'redirectUri'. - * @property {string} cacheLocation - Sets browser storage to either 'localStorage' or sessionStorage'. Defaults to 'sessionStorage'. - * @property {Array.} anonymousEndpoints Array of keywords or URI's. Adal will not attach a token to outgoing requests that have these keywords or uri. Defaults to 'null'. - * @property {number} expireOffsetSeconds If the cached token is about to be expired in the expireOffsetSeconds (in seconds), Adal will renew the token instead of using the cached token. Defaults to 300 seconds. - * @property {string} correlationId Unique identifier used to map the request with the response. Defaults to RFC4122 version 4 guid (128 bits). - * @property {number} loadFrameTimeout The number of milliseconds of inactivity before a token renewal response from AAD should be considered timed out. - */ + if (!config.clientId) { + throw new Error('clientId is required'); + } - /** - * Creates a new AuthenticationContext object. - * @constructor - * @param {config} config Configuration options for AuthenticationContext - */ + this.config = this._cloneConfig(config); + if (this.config.navigateToLoginRequestUrl === undefined) this.config.navigateToLoginRequestUrl = true; + if (this.config.popUp) this.popUp = true; + if (this.config.callback && typeof this.config.callback === 'function') this.callback = this.config.callback; - _AuthenticationContext = function AuthenticationContext(config) { - /** - * Enum for request type - * @enum {string} - */ - this.REQUEST_TYPE = { - LOGIN: 'LOGIN', - RENEW_TOKEN: 'RENEW_TOKEN', - UNKNOWN: 'UNKNOWN' - }; + if (this.config.instance) { + this.instance = this.config.instance; + } // App can request idtoken for itself using clientid as resource - this.RESPONSE_TYPE = { - ID_TOKEN_TOKEN: 'id_token token', - TOKEN: 'token' - }; - /** - * Enum for storage constants - * @enum {string} - */ - this.CONSTANTS = { - ACCESS_TOKEN: 'access_token', - EXPIRES_IN: 'expires_in', - ID_TOKEN: 'id_token', - ERROR_DESCRIPTION: 'error_description', - SESSION_STATE: 'session_state', - ERROR: 'error', - STORAGE: { - TOKEN_KEYS: 'adal.token.keys', - ACCESS_TOKEN_KEY: 'adal.access.token.key', - EXPIRATION_KEY: 'adal.expiration.key', - STATE_LOGIN: 'adal.state.login', - STATE_RENEW: 'adal.state.renew', - NONCE_IDTOKEN: 'adal.nonce.idtoken', - SESSION_STATE: 'adal.session.state', - USERNAME: 'adal.username', - IDTOKEN: 'adal.idtoken', - ERROR: 'adal.error', - ERROR_DESCRIPTION: 'adal.error.description', - LOGIN_REQUEST: 'adal.login.request', - LOGIN_ERROR: 'adal.login.error', - RENEW_STATUS: 'adal.token.renew.status', - ANGULAR_LOGIN_REQUEST: 'adal.angular.login.request' - }, - RESOURCE_DELIMETER: '|', - CACHE_DELIMETER: '||', - LOADFRAME_TIMEOUT: 6000, - TOKEN_RENEW_STATUS_CANCELED: 'Canceled', - TOKEN_RENEW_STATUS_COMPLETED: 'Completed', - TOKEN_RENEW_STATUS_IN_PROGRESS: 'In Progress', - LOGGING_LEVEL: { - ERROR: 0, - WARN: 1, - INFO: 2, - VERBOSE: 3 - }, - LEVEL_STRING_MAP: { - 0: 'ERROR:', - 1: 'WARNING:', - 2: 'INFO:', - 3: 'VERBOSE:' - }, - POPUP_WIDTH: 483, - POPUP_HEIGHT: 600 - }; + if (!this.config.loginResource) { + this.config.loginResource = this.config.clientId; + } // redirect and logout_redirect are set to current location by default - if (_AuthenticationContext.prototype._singletonInstance) { - return _AuthenticationContext.prototype._singletonInstance; - } - _AuthenticationContext.prototype._singletonInstance = this; - - // public - this.instance = 'https://login.microsoftonline.com/'; - this.config = {}; - this.callback = null; - this.popUp = false; - this.isAngular = false; - - // private - this._user = null; - this._activeRenewals = {}; - this._loginInProgress = false; - this._acquireTokenInProgress = false; - this._renewStates = []; - this._callBackMappedToRenewStates = {}; - this._callBacksMappedToRenewStates = {}; - this._openedWindows = []; - this._requestType = this.REQUEST_TYPE.LOGIN; - window._adalInstance = this; - - // validate before constructor assignments - if (config.displayCall && typeof config.displayCall !== 'function') { - throw new Error('displayCall is not a function'); - } - if (!config.clientId) { - throw new Error('clientId is required'); - } + if (!this.config.redirectUri) { + // strip off query parameters or hashes from the redirect uri as AAD does not allow those. + this.config.redirectUri = window.location.href.split("?")[0].split("#")[0]; + } - this.config = this._cloneConfig(config); + if (!this.config.postLogoutRedirectUri) { + // strip off query parameters or hashes from the post logout redirect uri as AAD does not allow those. + this.config.postLogoutRedirectUri = window.location.href.split("?")[0].split("#")[0]; + } - if (this.config.navigateToLoginRequestUrl === undefined) this.config.navigateToLoginRequestUrl = true; + if (!this.config.anonymousEndpoints) { + this.config.anonymousEndpoints = []; + } - if (this.config.popUp) this.popUp = true; + if (this.config.isAngular) { + this.isAngular = this.config.isAngular; + } - if (this.config.callback && typeof this.config.callback === 'function') this.callback = this.config.callback; + if (this.config.loadFrameTimeout) { + this.CONSTANTS.LOADFRAME_TIMEOUT = this.config.loadFrameTimeout; + } + }; - if (this.config.instance) { - this.instance = this.config.instance; - } + if (typeof window !== 'undefined') { + window.Logging = { + piiLoggingEnabled: false, + level: 0, + log: function log(message) {} + }; + } + /** + * Initiates the login process by redirecting the user to Azure AD authorization endpoint. + */ - // App can request idtoken for itself using clientid as resource - if (!this.config.loginResource) { - this.config.loginResource = this.config.clientId; - } - // redirect and logout_redirect are set to current location by default - if (!this.config.redirectUri) { - // strip off query parameters or hashes from the redirect uri as AAD does not allow those. - this.config.redirectUri = window.location.href.split("?")[0].split("#")[0]; - } + _AuthenticationContext.prototype.login = function () { + if (this._loginInProgress) { + this.info("Login in progress"); + return; + } - if (!this.config.postLogoutRedirectUri) { - // strip off query parameters or hashes from the post logout redirect uri as AAD does not allow those. - this.config.postLogoutRedirectUri = window.location.href.split("?")[0].split("#")[0]; - } + this._loginInProgress = true; // Token is not present and user needs to login - if (!this.config.anonymousEndpoints) { - this.config.anonymousEndpoints = []; - } + var expectedState = this._guid(); - if (this.config.isAngular) { - this.isAngular = this.config.isAngular; - } + this.config.state = expectedState; + this._idTokenNonce = this._guid(); - if (this.config.loadFrameTimeout) { - this.CONSTANTS.LOADFRAME_TIMEOUT = this.config.loadFrameTimeout; - } - }; + var loginStartPage = this._getItem(this.CONSTANTS.STORAGE.ANGULAR_LOGIN_REQUEST); - if (typeof window !== 'undefined') { - window.Logging = { - piiLoggingEnabled: false, - level: 0, - log: function log(message) {} - }; + if (!loginStartPage || loginStartPage === "") { + loginStartPage = window.location.href; + } else { + this._saveItem(this.CONSTANTS.STORAGE.ANGULAR_LOGIN_REQUEST, ""); } - /** - * Initiates the login process by redirecting the user to Azure AD authorization endpoint. - */ - _AuthenticationContext.prototype.login = function () { - if (this._loginInProgress) { - this.info("Login in progress"); - return; - } + this.verbose('Expected state: ' + expectedState + ' startPage:' + loginStartPage); - this._loginInProgress = true; + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, loginStartPage); - // Token is not present and user needs to login - var expectedState = this._guid(); - this.config.state = expectedState; - this._idTokenNonce = this._guid(); - var loginStartPage = this._getItem(this.CONSTANTS.STORAGE.ANGULAR_LOGIN_REQUEST); + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, ''); - if (!loginStartPage || loginStartPage === "") { - loginStartPage = window.location.href; - } else { - this._saveItem(this.CONSTANTS.STORAGE.ANGULAR_LOGIN_REQUEST, ""); - } + this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, expectedState, true); - this.verbose('Expected state: ' + expectedState + ' startPage:' + loginStartPage); - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, loginStartPage); - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, ''); - this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, expectedState, true); - this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce, true); - this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); - var urlNavigate = this._getNavigateUrl('id_token', null) + '&nonce=' + encodeURIComponent(this._idTokenNonce); - - if (this.config.displayCall) { - // User defined way of handling the navigation - this.config.displayCall(urlNavigate); - } else if (this.popUp) { - this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, ''); // so requestInfo does not match redirect case - this._renewStates.push(expectedState); - this.registerCallback(expectedState, this.config.clientId, this.callback); - this._loginPopup(urlNavigate); - } else { - this.promptUser(urlNavigate); - } - }; + this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce, true); - /** - * Configures popup window for login. - * @ignore - */ - _AuthenticationContext.prototype._openPopup = function (urlNavigate, title, popUpWidth, popUpHeight) { - try { - /** - * adding winLeft and winTop to account for dual monitor - * using screenLeft and screenTop for IE8 and earlier - */ - var winLeft = window.screenLeft ? window.screenLeft : window.screenX; - var winTop = window.screenTop ? window.screenTop : window.screenY; - /** - * window.innerWidth displays browser window's height and width excluding toolbars - * using document.documentElement.clientWidth for IE8 and earlier - */ - var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; - var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; - var left = width / 2 - popUpWidth / 2 + winLeft; - var top = height / 2 - popUpHeight / 2 + winTop; - - var popupWindow = window.open(urlNavigate, title, 'width=' + popUpWidth + ', height=' + popUpHeight + ', top=' + top + ', left=' + left); - - if (popupWindow.focus) { - popupWindow.focus(); - } + this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); - return popupWindow; - } catch (e) { - this.warn('Error opening popup, ' + e.message); - this._loginInProgress = false; - this._acquireTokenInProgress = false; - return null; - } - }; + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); - _AuthenticationContext.prototype._handlePopupError = function (loginCallback, resource, error, errorDesc, loginError) { - this.warn(errorDesc); - this._saveItem(this.CONSTANTS.STORAGE.ERROR, error); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, errorDesc); - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, loginError); + var urlNavigate = this._getNavigateUrl('id_token', null) + '&nonce=' + encodeURIComponent(this._idTokenNonce); - if (resource && this._activeRenewals[resource]) { - this._activeRenewals[resource] = null; - } + if (this.config.displayCall) { + // User defined way of handling the navigation + this.config.displayCall(urlNavigate); + } else if (this.popUp) { + this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, ''); // so requestInfo does not match redirect case - this._loginInProgress = false; - this._acquireTokenInProgress = false; - if (loginCallback) { - loginCallback(errorDesc, null, error); - } - }; + this._renewStates.push(expectedState); - /** - * After authorization, the user will be sent to your specified redirect_uri with the user's bearer token - * attached to the URI fragment as an id_token field. It closes popup window after redirection. - * @ignore - */ - _AuthenticationContext.prototype._loginPopup = function (urlNavigate, resource, callback) { - var popupWindow = this._openPopup(urlNavigate, "login", this.CONSTANTS.POPUP_WIDTH, this.CONSTANTS.POPUP_HEIGHT); - var loginCallback = callback || this.callback; - - if (popupWindow == null) { - var error = 'Error opening popup'; - var errorDesc = 'Popup Window is null. This can happen if you are using IE'; - this._handlePopupError(loginCallback, resource, error, errorDesc, errorDesc); - return; - } + this.registerCallback(expectedState, this.config.clientId, this.callback); - this._openedWindows.push(popupWindow); + this._loginPopup(urlNavigate); + } else { + this.promptUser(urlNavigate); + } + }; + /** + * Configures popup window for login. + * @ignore + */ + + + _AuthenticationContext.prototype._openPopup = function (urlNavigate, title, popUpWidth, popUpHeight) { + try { + /** + * adding winLeft and winTop to account for dual monitor + * using screenLeft and screenTop for IE8 and earlier + */ + var winLeft = window.screenLeft ? window.screenLeft : window.screenX; + var winTop = window.screenTop ? window.screenTop : window.screenY; + /** + * window.innerWidth displays browser window's height and width excluding toolbars + * using document.documentElement.clientWidth for IE8 and earlier + */ + + var width = window.innerWidth || document.documentElement.clientWidth || document.body.clientWidth; + var height = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight; + var left = width / 2 - popUpWidth / 2 + winLeft; + var top = height / 2 - popUpHeight / 2 + winTop; + var popupWindow = window.open(urlNavigate, title, 'width=' + popUpWidth + ', height=' + popUpHeight + ', top=' + top + ', left=' + left); + + if (popupWindow.focus) { + popupWindow.focus(); + } + + return popupWindow; + } catch (e) { + this.warn('Error opening popup, ' + e.message); + this._loginInProgress = false; + this._acquireTokenInProgress = false; + return null; + } + }; - if (this.config.redirectUri.indexOf('#') != -1) { - var registeredRedirectUri = this.config.redirectUri.split("#")[0]; - } else { - var registeredRedirectUri = this.config.redirectUri; - } + _AuthenticationContext.prototype._handlePopupError = function (loginCallback, resource, error, errorDesc, loginError) { + this.warn(errorDesc); - var that = this; + this._saveItem(this.CONSTANTS.STORAGE.ERROR, error); - var pollTimer = window.setInterval(function () { - if (!popupWindow || popupWindow.closed || popupWindow.closed === undefined) { - var error = 'Popup Window closed'; - var errorDesc = 'Popup Window closed by UI action/ Popup Window handle destroyed due to cross zone navigation in IE/Edge'; + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, errorDesc); - if (that.isAngular) { - that._broadcast('adal:popUpClosed', errorDesc + that.CONSTANTS.RESOURCE_DELIMETER + error); - } + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, loginError); - that._handlePopupError(loginCallback, resource, error, errorDesc, errorDesc); - window.clearInterval(pollTimer); - return; - } - try { - var popUpWindowLocation = popupWindow.location; - if (encodeURI(popUpWindowLocation.href).indexOf(encodeURI(registeredRedirectUri)) != -1) { - if (that.isAngular) { - that._broadcast('adal:popUpHashChanged', popUpWindowLocation.hash); - } else { - that.handleWindowCallback(popUpWindowLocation.hash); - } - - window.clearInterval(pollTimer); - that._loginInProgress = false; - that._acquireTokenInProgress = false; - that.info("Closing popup window"); - that._openedWindows = []; - popupWindow.close(); - return; - } - } catch (e) {} - }, 1); - }; + if (resource && this._activeRenewals[resource]) { + this._activeRenewals[resource] = null; + } - _AuthenticationContext.prototype._broadcast = function (eventName, data) { - // Custom Event is not supported in IE, below IIFE will polyfill the CustomEvent() constructor functionality in Internet Explorer 9 and higher - (function () { + this._loginInProgress = false; + this._acquireTokenInProgress = false; - if (typeof window.CustomEvent === "function") { - return false; - } + if (loginCallback) { + loginCallback(errorDesc, null, error); + } + }; + /** + * After authorization, the user will be sent to your specified redirect_uri with the user's bearer token + * attached to the URI fragment as an id_token field. It closes popup window after redirection. + * @ignore + */ - function CustomEvent(event, params) { - params = params || { bubbles: false, cancelable: false, detail: undefined }; - var evt = document.createEvent('CustomEvent'); - evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); - return evt; - } - CustomEvent.prototype = window.Event.prototype; - window.CustomEvent = CustomEvent; - })(); + _AuthenticationContext.prototype._loginPopup = function (urlNavigate, resource, callback) { + var popupWindow = this._openPopup(urlNavigate, "login", this.CONSTANTS.POPUP_WIDTH, this.CONSTANTS.POPUP_HEIGHT); - var evt = new CustomEvent(eventName, { detail: data }); - window.dispatchEvent(evt); - }; + var loginCallback = callback || this.callback; - _AuthenticationContext.prototype.loginInProgress = function () { - return this._loginInProgress; - }; + if (popupWindow == null) { + var error = 'Error opening popup'; + var errorDesc = 'Popup Window is null. This can happen if you are using IE'; - /** - * Checks for the resource in the cache. By default, cache location is Session Storage - * @ignore - * @returns {Boolean} 'true' if login is in progress, else returns 'false'. - */ - _AuthenticationContext.prototype._hasResource = function (key) { - var keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS); - return keys && !this._isEmpty(keys) && keys.indexOf(key + this.CONSTANTS.RESOURCE_DELIMETER) > -1; - }; + this._handlePopupError(loginCallback, resource, error, errorDesc, errorDesc); - /** - * Gets token for the specified resource from the cache. - * @param {string} resource A URI that identifies the resource for which the token is requested. - * @returns {string} token if if it exists and not expired, otherwise null. - */ - _AuthenticationContext.prototype.getCachedToken = function (resource) { - if (!this._hasResource(resource)) { - return null; - } + return; + } - var token = this._getItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource); - var expiry = this._getItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource); + this._openedWindows.push(popupWindow); - // If expiration is within offset, it will force renew - var offset = this.config.expireOffsetSeconds || 300; + if (this.config.redirectUri.indexOf('#') != -1) { + var registeredRedirectUri = this.config.redirectUri.split("#")[0]; + } else { + var registeredRedirectUri = this.config.redirectUri; + } - if (expiry && expiry > this._now() + offset) { - return token; - } else { - this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, ''); - this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, 0); - return null; + var that = this; + var pollTimer = window.setInterval(function () { + if (!popupWindow || popupWindow.closed || popupWindow.closed === undefined) { + var error = 'Popup Window closed'; + var errorDesc = 'Popup Window closed by UI action/ Popup Window handle destroyed due to cross zone navigation in IE/Edge'; + + if (that.isAngular) { + that._broadcast('adal:popUpClosed', errorDesc + that.CONSTANTS.RESOURCE_DELIMETER + error); } - }; - /** - * User information from idtoken. - * @class User - * @property {string} userName - username assigned from upn or email. - * @property {object} profile - properties parsed from idtoken. - */ + that._handlePopupError(loginCallback, resource, error, errorDesc, errorDesc); - /** - * If user object exists, returns it. Else creates a new user object by decoding id_token from the cache. - * @returns {User} user object - */ - _AuthenticationContext.prototype.getCachedUser = function () { - if (this._user) { - return this._user; - } + window.clearInterval(pollTimer); + return; + } - var idtoken = this._getItem(this.CONSTANTS.STORAGE.IDTOKEN); - this._user = this._createUser(idtoken); - return this._user; - }; + try { + var popUpWindowLocation = popupWindow.location; - /** - * Adds the passed callback to the array of callbacks for the specified resource and puts the array on the window object. - * @param {string} resource A URI that identifies the resource for which the token is requested. - * @param {string} expectedState A unique identifier (guid). - * @param {tokenCallback} callback - The callback provided by the caller. It will be called with token or error. - */ - _AuthenticationContext.prototype.registerCallback = function (expectedState, resource, callback) { - this._activeRenewals[resource] = expectedState; + if (encodeURI(popUpWindowLocation.href).indexOf(encodeURI(registeredRedirectUri)) != -1) { + if (that.isAngular) { + that._broadcast('adal:popUpHashChanged', popUpWindowLocation.hash); + } else { + that.handleWindowCallback(popUpWindowLocation.hash); + } - if (!this._callBacksMappedToRenewStates[expectedState]) { - this._callBacksMappedToRenewStates[expectedState] = []; + window.clearInterval(pollTimer); + that._loginInProgress = false; + that._acquireTokenInProgress = false; + that.info("Closing popup window"); + that._openedWindows = []; + popupWindow.close(); + return; } + } catch (e) {} + }, 1); + }; - var self = this; - this._callBacksMappedToRenewStates[expectedState].push(callback); + _AuthenticationContext.prototype._broadcast = function (eventName, data) { + // Custom Event is not supported in IE, below IIFE will polyfill the CustomEvent() constructor functionality in Internet Explorer 9 and higher + (function () { + if (typeof window.CustomEvent === "function") { + return false; + } - if (!this._callBackMappedToRenewStates[expectedState]) { - this._callBackMappedToRenewStates[expectedState] = function (errorDesc, token, error, tokenType) { - self._activeRenewals[resource] = null; + function CustomEvent(event, params) { + params = params || { + bubbles: false, + cancelable: false, + detail: undefined + }; + var evt = document.createEvent('CustomEvent'); + evt.initCustomEvent(event, params.bubbles, params.cancelable, params.detail); + return evt; + } + + CustomEvent.prototype = window.Event.prototype; + window.CustomEvent = CustomEvent; + })(); + + var evt = new CustomEvent(eventName, { + detail: data + }); + window.dispatchEvent(evt); + }; + + _AuthenticationContext.prototype.loginInProgress = function () { + return this._loginInProgress; + }; + /** + * Checks for the resource in the cache. By default, cache location is Session Storage + * @ignore + * @returns {Boolean} 'true' if login is in progress, else returns 'false'. + */ + + + _AuthenticationContext.prototype._hasResource = function (key) { + var keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS); + + return keys && !this._isEmpty(keys) && keys.indexOf(key + this.CONSTANTS.RESOURCE_DELIMETER) > -1; + }; + /** + * Gets token for the specified resource from the cache. + * @param {string} resource A URI that identifies the resource for which the token is requested. + * @returns {string} token if if it exists and not expired, otherwise null. + */ + + + _AuthenticationContext.prototype.getCachedToken = function (resource) { + if (!this._hasResource(resource)) { + return null; + } - for (var i = 0; i < self._callBacksMappedToRenewStates[expectedState].length; ++i) { - try { - self._callBacksMappedToRenewStates[expectedState][i](errorDesc, token, error, tokenType); - } catch (error) { - self.warn(error); - } - } + var token = this._getItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource); - self._callBacksMappedToRenewStates[expectedState] = null; - self._callBackMappedToRenewStates[expectedState] = null; - }; - } - }; + var expiry = this._getItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource); // If expiration is within offset, it will force renew - // var errorResponse = {error:'', error_description:''}; - // var token = 'string token'; - // callback(errorResponse, token) - // with callback - /** - * Acquires access token with hidden iframe - * @ignore - */ - _AuthenticationContext.prototype._renewToken = function (resource, callback, responseType) { - // use iframe to try to renew token - // use given resource to create new authz url - this.info('renewToken is called for resource:' + resource); - var frameHandle = this._addAdalFrame('adalRenewFrame' + resource); - var expectedState = this._guid() + '|' + resource; - this.config.state = expectedState; - // renew happens in iframe, so it keeps javascript context - this._renewStates.push(expectedState); - this.verbose('Renew token Expected state: ' + expectedState); - // remove the existing prompt=... query parameter and add prompt=none - responseType = responseType || 'token'; - var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl(responseType, resource), 'prompt'); - - if (responseType === this.RESPONSE_TYPE.ID_TOKEN_TOKEN) { - this._idTokenNonce = this._guid(); - this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce, true); - urlNavigate += '&nonce=' + encodeURIComponent(this._idTokenNonce); - } - urlNavigate = urlNavigate + '&prompt=none'; - urlNavigate = this._addHintParameters(urlNavigate); - this.registerCallback(expectedState, resource, callback); - this.verbosePii('Navigate to:' + urlNavigate); - frameHandle.src = 'about:blank'; - this._loadFrameTimeout(urlNavigate, 'adalRenewFrame' + resource, resource); - }; + var offset = this.config.expireOffsetSeconds || 300; - /** - * Renews idtoken for app's own backend when resource is clientId and calls the callback with token/error - * @ignore - */ - _AuthenticationContext.prototype._renewIdToken = function (callback, responseType) { - // use iframe to try to renew token - this.info('renewIdToken is called'); - var frameHandle = this._addAdalFrame('adalIdTokenFrame'); - var expectedState = this._guid() + '|' + this.config.clientId; - this._idTokenNonce = this._guid(); - this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce, true); - this.config.state = expectedState; - // renew happens in iframe, so it keeps javascript context - this._renewStates.push(expectedState); - this.verbose('Renew Idtoken Expected state: ' + expectedState); - // remove the existing prompt=... query parameter and add prompt=none - var resource = responseType === null || typeof responseType === "undefined" ? null : this.config.clientId; - var responseType = responseType || 'id_token'; - var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl(responseType, resource), 'prompt'); - urlNavigate = urlNavigate + '&prompt=none'; - urlNavigate = this._addHintParameters(urlNavigate); - urlNavigate += '&nonce=' + encodeURIComponent(this._idTokenNonce); - this.registerCallback(expectedState, this.config.clientId, callback); - this.verbosePii('Navigate to:' + urlNavigate); - frameHandle.src = 'about:blank'; - this._loadFrameTimeout(urlNavigate, 'adalIdTokenFrame', this.config.clientId); - }; + if (expiry && expiry > this._now() + offset) { + return token; + } else { + this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, ''); - /** - * Checks if the authorization endpoint URL contains query string parameters - * @ignore - */ - _AuthenticationContext.prototype._urlContainsQueryStringParameter = function (name, url) { - // regex to detect pattern of a ? or & followed by the name parameter and an equals character - var regex = new RegExp("[\\?&]" + name + "="); - return regex.test(url); - }; + this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, 0); - /** - * Removes the query string parameter from the authorization endpoint URL if it exists - * @ignore - */ - _AuthenticationContext.prototype._urlRemoveQueryStringParameter = function (url, name) { - // we remove &name=value, name=value& and name=value - // &name=value - var regex = new RegExp('(\\&' + name + '=)[^\&]+'); - url = url.replace(regex, ''); - // name=value& - regex = new RegExp('(' + name + '=)[^\&]+&'); - url = url.replace(regex, ''); - // name=value - regex = new RegExp('(' + name + '=)[^\&]+'); - url = url.replace(regex, ''); - return url; - }; + return null; + } + }; + /** + * User information from idtoken. + * @class User + * @property {string} userName - username assigned from upn or email. + * @property {object} profile - properties parsed from idtoken. + */ + + /** + * If user object exists, returns it. Else creates a new user object by decoding id_token from the cache. + * @returns {User} user object + */ + + + _AuthenticationContext.prototype.getCachedUser = function () { + if (this._user) { + return this._user; + } - // Calling _loadFrame but with a timeout to signal failure in loadframeStatus. Callbacks are left - // registered when network errors occur and subsequent token requests for same resource are registered to the pending request - /** - * @ignore - */ - _AuthenticationContext.prototype._loadFrameTimeout = function (urlNavigation, frameName, resource) { - //set iframe session to pending - this.verbose('Set loading state to pending for: ' + resource); - this._saveItem(this.CONSTANTS.STORAGE.RENEW_STATUS + resource, this.CONSTANTS.TOKEN_RENEW_STATUS_IN_PROGRESS); - this._loadFrame(urlNavigation, frameName); - var self = this; - - setTimeout(function () { - if (self._getItem(self.CONSTANTS.STORAGE.RENEW_STATUS + resource) === self.CONSTANTS.TOKEN_RENEW_STATUS_IN_PROGRESS) { - // fail the iframe session if it's in pending state - self.verbose('Loading frame has timed out after: ' + self.CONSTANTS.LOADFRAME_TIMEOUT / 1000 + ' seconds for resource ' + resource); - var expectedState = self._activeRenewals[resource]; - - if (expectedState && self._callBackMappedToRenewStates[expectedState]) { - self._callBackMappedToRenewStates[expectedState]('Token renewal operation failed due to timeout', null, 'Token Renewal Failed'); - } - - self._saveItem(self.CONSTANTS.STORAGE.RENEW_STATUS + resource, self.CONSTANTS.TOKEN_RENEW_STATUS_CANCELED); - } - }, self.CONSTANTS.LOADFRAME_TIMEOUT); - }; + var idtoken = this._getItem(this.CONSTANTS.STORAGE.IDTOKEN); - /** - * Loads iframe with authorization endpoint URL - * @ignore - */ - _AuthenticationContext.prototype._loadFrame = function (urlNavigate, frameName) { - // This trick overcomes iframe navigation in IE - // IE does not load the page consistently in iframe - var self = this; - self.info('LoadFrame: ' + frameName); - var frameCheck = frameName; - setTimeout(function () { - var frameHandle = self._addAdalFrame(frameCheck); - - if (frameHandle.src === '' || frameHandle.src === 'about:blank') { - frameHandle.src = urlNavigate; - self._loadFrame(urlNavigate, frameCheck); - } - }, 500); - }; + this._user = this._createUser(idtoken); + return this._user; + }; + /** + * Adds the passed callback to the array of callbacks for the specified resource and puts the array on the window object. + * @param {string} resource A URI that identifies the resource for which the token is requested. + * @param {string} expectedState A unique identifier (guid). + * @param {tokenCallback} callback - The callback provided by the caller. It will be called with token or error. + */ - /** - * @callback tokenCallback - * @param {string} error_description error description returned from AAD if token request fails. - * @param {string} token token returned from AAD if token request is successful. - * @param {string} error error message returned from AAD if token request fails. - */ - /** - * Acquires token from the cache if it is not expired. Otherwise sends request to AAD to obtain a new token. - * @param {string} resource ResourceUri identifying the target resource - * @param {tokenCallback} callback - The callback provided by the caller. It will be called with token or error. - */ - _AuthenticationContext.prototype.acquireToken = function (resource, callback) { - if (this._isEmpty(resource)) { - this.warn('resource is required'); - callback('resource is required', null, 'resource is required'); - return; - } + _AuthenticationContext.prototype.registerCallback = function (expectedState, resource, callback) { + this._activeRenewals[resource] = expectedState; - var token = this.getCachedToken(resource); + if (!this._callBacksMappedToRenewStates[expectedState]) { + this._callBacksMappedToRenewStates[expectedState] = []; + } - if (token) { - this.info('Token is already in cache for resource:' + resource); - callback(null, token, null); - return; - } + var self = this; - if (!this._user && !(this.config.extraQueryParameter && this.config.extraQueryParameter.indexOf('login_hint') !== -1)) { - this.warn('User login is required'); - callback('User login is required', null, 'login required'); - return; - } + this._callBacksMappedToRenewStates[expectedState].push(callback); - // renew attempt with iframe - // Already renewing for this resource, callback when we get the token. - if (this._activeRenewals[resource]) { - // Active renewals contains the state for each renewal. - this.registerCallback(this._activeRenewals[resource], resource, callback); - } else { - this._requestType = this.REQUEST_TYPE.RENEW_TOKEN; - if (resource === this.config.clientId) { - // App uses idtoken to send to api endpoints - // Default resource is tracked as clientid to store this token - if (this._user) { - this.verbose('renewing idtoken'); - this._renewIdToken(callback); - } else { - this.verbose('renewing idtoken and access_token'); - this._renewIdToken(callback, this.RESPONSE_TYPE.ID_TOKEN_TOKEN); - } - } else { - if (this._user) { - this.verbose('renewing access_token'); - this._renewToken(resource, callback); - } else { - this.verbose('renewing idtoken and access_token'); - this._renewToken(resource, callback, this.RESPONSE_TYPE.ID_TOKEN_TOKEN); - } - } - } - }; + if (!this._callBackMappedToRenewStates[expectedState]) { + this._callBackMappedToRenewStates[expectedState] = function (errorDesc, token, error, tokenType) { + self._activeRenewals[resource] = null; - /** - * Acquires token (interactive flow using a popUp window) by sending request to AAD to obtain a new token. - * @param {string} resource ResourceUri identifying the target resource - * @param {string} extraQueryParameters extraQueryParameters to add to the authentication request - * @param {tokenCallback} callback - The callback provided by the caller. It will be called with token or error. - */ - _AuthenticationContext.prototype.acquireTokenPopup = function (resource, extraQueryParameters, claims, callback) { - if (this._isEmpty(resource)) { - this.warn('resource is required'); - callback('resource is required', null, 'resource is required'); - return; + for (var i = 0; i < self._callBacksMappedToRenewStates[expectedState].length; ++i) { + try { + self._callBacksMappedToRenewStates[expectedState][i](errorDesc, token, error, tokenType); + } catch (error) { + self.warn(error); + } } - if (!this._user) { - this.warn('User login is required'); - callback('User login is required', null, 'login required'); - return; - } + self._callBacksMappedToRenewStates[expectedState] = null; + self._callBackMappedToRenewStates[expectedState] = null; + }; + } + }; // var errorResponse = {error:'', error_description:''}; + // var token = 'string token'; + // callback(errorResponse, token) + // with callback - if (this._acquireTokenInProgress) { - this.warn("Acquire token interactive is already in progress"); - callback("Acquire token interactive is already in progress", null, "Acquire token interactive is already in progress"); - return; - } + /** + * Acquires access token with hidden iframe + * @ignore + */ - var expectedState = this._guid() + '|' + resource; - this.config.state = expectedState; - this._renewStates.push(expectedState); - this._requestType = this.REQUEST_TYPE.RENEW_TOKEN; - this.verbose('Renew token Expected state: ' + expectedState); - // remove the existing prompt=... query parameter and add prompt=select_account - var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl('token', resource), 'prompt'); - urlNavigate = urlNavigate + '&prompt=select_account'; - - if (extraQueryParameters) { - urlNavigate += extraQueryParameters; - } - if (claims && urlNavigate.indexOf("&claims") === -1) { - urlNavigate += '&claims=' + encodeURIComponent(claims); - } else if (claims && urlNavigate.indexOf("&claims") !== -1) { - throw new Error('Claims cannot be passed as an extraQueryParameter'); - } + _AuthenticationContext.prototype._renewToken = function (resource, callback, responseType) { + // use iframe to try to renew token + // use given resource to create new authz url + this.info('renewToken is called for resource:' + resource); - urlNavigate = this._addHintParameters(urlNavigate); - this._acquireTokenInProgress = true; - this.info('acquireToken interactive is called for the resource ' + resource); - this.registerCallback(expectedState, resource, callback); - this._loginPopup(urlNavigate, resource, callback); - }; + var frameHandle = this._addAdalFrame('adalRenewFrame' + resource); - /** - * Acquires token (interactive flow using a redirect) by sending request to AAD to obtain a new token. In this case the callback passed in the Authentication - * request constructor will be called. - * @param {string} resource ResourceUri identifying the target resource - * @param {string} extraQueryParameters extraQueryParameters to add to the authentication request - */ - _AuthenticationContext.prototype.acquireTokenRedirect = function (resource, extraQueryParameters, claims) { - if (this._isEmpty(resource)) { - this.warn('resource is required'); - callback('resource is required', null, 'resource is required'); - return; - } + var expectedState = this._guid() + '|' + resource; + this.config.state = expectedState; // renew happens in iframe, so it keeps javascript context - var callback = this.callback; + this._renewStates.push(expectedState); - if (!this._user) { - this.warn('User login is required'); - callback('User login is required', null, 'login required'); - return; - } + this.verbose('Renew token Expected state: ' + expectedState); // remove the existing prompt=... query parameter and add prompt=none - if (this._acquireTokenInProgress) { - this.warn("Acquire token interactive is already in progress"); - callback("Acquire token interactive is already in progress", null, "Acquire token interactive is already in progress"); - return; - } + responseType = responseType || 'token'; - var expectedState = this._guid() + '|' + resource; - this.config.state = expectedState; - this.verbose('Renew token Expected state: ' + expectedState); + var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl(responseType, resource), 'prompt'); - // remove the existing prompt=... query parameter and add prompt=select_account - var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl('token', resource), 'prompt'); - urlNavigate = urlNavigate + '&prompt=select_account'; - if (extraQueryParameters) { - urlNavigate += extraQueryParameters; - } + if (responseType === this.RESPONSE_TYPE.ID_TOKEN_TOKEN) { + this._idTokenNonce = this._guid(); - if (claims && urlNavigate.indexOf("&claims") === -1) { - urlNavigate += '&claims=' + encodeURIComponent(claims); - } else if (claims && urlNavigate.indexOf("&claims") !== -1) { - throw new Error('Claims cannot be passed as an extraQueryParameter'); - } + this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce, true); - urlNavigate = this._addHintParameters(urlNavigate); - this._acquireTokenInProgress = true; - this.info('acquireToken interactive is called for the resource ' + resource); - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, window.location.href); - this._saveItem(this.CONSTANTS.STORAGE.STATE_RENEW, expectedState, true); - this.promptUser(urlNavigate); - }; - /** - * Redirects the browser to Azure AD authorization endpoint. - * @param {string} urlNavigate Url of the authorization endpoint. - */ - _AuthenticationContext.prototype.promptUser = function (urlNavigate) { - if (urlNavigate) { - this.infoPii('Navigate to:' + urlNavigate); - window.location.replace(urlNavigate); - } else { - this.info('Navigate url is empty'); - } - }; + urlNavigate += '&nonce=' + encodeURIComponent(this._idTokenNonce); + } - /** - * Clears cache items. - */ - _AuthenticationContext.prototype.clearCache = function () { - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, ''); - this._saveItem(this.CONSTANTS.STORAGE.ANGULAR_LOGIN_REQUEST, ''); - this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, ''); - this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, ''); - this._saveItem(this.CONSTANTS.STORAGE.STATE_RENEW, ''); - this._renewStates = []; - this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, ''); - this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, ''); - this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, ''); - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, ''); - var keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS); - - if (!this._isEmpty(keys)) { - keys = keys.split(this.CONSTANTS.RESOURCE_DELIMETER); - for (var i = 0; i < keys.length && keys[i] !== ""; i++) { - this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + keys[i], ''); - this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + keys[i], 0); - } - } + urlNavigate = urlNavigate + '&prompt=none'; + urlNavigate = this._addHintParameters(urlNavigate); + this.registerCallback(expectedState, resource, callback); + this.verbosePii('Navigate to:' + urlNavigate); + frameHandle.src = 'about:blank'; - this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, ''); - }; + this._loadFrameTimeout(urlNavigate, 'adalRenewFrame' + resource, resource); + }; + /** + * Renews idtoken for app's own backend when resource is clientId and calls the callback with token/error + * @ignore + */ - /** - * Clears cache items for a given resource. - * @param {string} resource a URI that identifies the resource. - */ - _AuthenticationContext.prototype.clearCacheForResource = function (resource) { - this._saveItem(this.CONSTANTS.STORAGE.STATE_RENEW, ''); - this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); - - if (this._hasResource(resource)) { - this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, ''); - this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, 0); - } - }; - /** - * Redirects user to logout endpoint. - * After logout, it will redirect to postLogoutRedirectUri if added as a property on the config object. - */ - _AuthenticationContext.prototype.logOut = function () { - this.clearCache(); - this._user = null; - var urlNavigate; + _AuthenticationContext.prototype._renewIdToken = function (callback, responseType) { + // use iframe to try to renew token + this.info('renewIdToken is called'); - if (this.config.logOutUri) { - urlNavigate = this.config.logOutUri; - } else { - var tenant = 'common'; - var logout = ''; + var frameHandle = this._addAdalFrame('adalIdTokenFrame'); - if (this.config.tenant) { - tenant = this.config.tenant; - } + var expectedState = this._guid() + '|' + this.config.clientId; + this._idTokenNonce = this._guid(); - if (this.config.postLogoutRedirectUri) { - logout = 'post_logout_redirect_uri=' + encodeURIComponent(this.config.postLogoutRedirectUri); - } + this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, this._idTokenNonce, true); - urlNavigate = this.instance + tenant + '/oauth2/logout?' + logout; - } + this.config.state = expectedState; // renew happens in iframe, so it keeps javascript context - this.infoPii('Logout navigate to: ' + urlNavigate); - this.promptUser(urlNavigate); - }; + this._renewStates.push(expectedState); - _AuthenticationContext.prototype._isEmpty = function (str) { - return typeof str === 'undefined' || !str || 0 === str.length; - }; + this.verbose('Renew Idtoken Expected state: ' + expectedState); // remove the existing prompt=... query parameter and add prompt=none - /** - * @callback userCallback - * @param {string} error error message if user info is not available. - * @param {User} user user object retrieved from the cache. - */ + var resource = responseType === null || typeof responseType === "undefined" ? null : this.config.clientId; + var responseType = responseType || 'id_token'; - /** - * Calls the passed in callback with the user object or error message related to the user. - * @param {userCallback} callback - The callback provided by the caller. It will be called with user or error. - */ - _AuthenticationContext.prototype.getUser = function (callback) { - // IDToken is first call - if (typeof callback !== 'function') { - throw new Error('callback is not a function'); - } + var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl(responseType, resource), 'prompt'); - // user in memory - if (this._user) { - callback(null, this._user); - return; - } + urlNavigate = urlNavigate + '&prompt=none'; + urlNavigate = this._addHintParameters(urlNavigate); + urlNavigate += '&nonce=' + encodeURIComponent(this._idTokenNonce); + this.registerCallback(expectedState, this.config.clientId, callback); + this.verbosePii('Navigate to:' + urlNavigate); + frameHandle.src = 'about:blank'; - // frame is used to get idtoken - var idtoken = this._getItem(this.CONSTANTS.STORAGE.IDTOKEN); + this._loadFrameTimeout(urlNavigate, 'adalIdTokenFrame', this.config.clientId); + }; + /** + * Checks if the authorization endpoint URL contains query string parameters + * @ignore + */ - if (!this._isEmpty(idtoken)) { - this.info('User exists in cache: '); - this._user = this._createUser(idtoken); - callback(null, this._user); - } else { - this.warn('User information is not available'); - callback('User information is not available', null); - } - }; - /** - * Adds login_hint to authorization URL which is used to pre-fill the username field of sign in page for the user if known ahead of time. - * domain_hint can be one of users/organisations which when added skips the email based discovery process of the user. - * @ignore - */ - _AuthenticationContext.prototype._addHintParameters = function (urlNavigate) { - //If you don�t use prompt=none, then if the session does not exist, there will be a failure. - //If sid is sent alongside domain or login hints, there will be a failure since request is ambiguous. - //If sid is sent with a prompt value other than none or attempt_none, there will be a failure since the request is ambiguous. - - if (this._user && this._user.profile) { - if (this._user.profile.sid && urlNavigate.indexOf('&prompt=none') !== -1) { - // don't add sid twice if user provided it in the extraQueryParameter value - if (!this._urlContainsQueryStringParameter("sid", urlNavigate)) { - // add sid - urlNavigate += '&sid=' + encodeURIComponent(this._user.profile.sid); - } - } else if (this._user.profile.upn) { - // don't add login_hint twice if user provided it in the extraQueryParameter value - if (!this._urlContainsQueryStringParameter("login_hint", urlNavigate)) { - // add login_hint - urlNavigate += '&login_hint=' + encodeURIComponent(this._user.profile.upn); - } - // don't add domain_hint twice if user provided it in the extraQueryParameter value - if (!this._urlContainsQueryStringParameter("domain_hint", urlNavigate) && this._user.profile.upn.indexOf('@') > -1) { - var parts = this._user.profile.upn.split('@'); - // local part can include @ in quotes. Sending last part handles that. - urlNavigate += '&domain_hint=' + encodeURIComponent(parts[parts.length - 1]); - } - } - } + _AuthenticationContext.prototype._urlContainsQueryStringParameter = function (name, url) { + // regex to detect pattern of a ? or & followed by the name parameter and an equals character + var regex = new RegExp("[\\?&]" + name + "="); + return regex.test(url); + }; + /** + * Removes the query string parameter from the authorization endpoint URL if it exists + * @ignore + */ - return urlNavigate; - }; - /** - * Creates a user object by decoding the id_token - * @ignore - */ - _AuthenticationContext.prototype._createUser = function (idToken) { - var user = null; - var parsedJson = this._extractIdToken(idToken); - if (parsedJson && parsedJson.hasOwnProperty('aud')) { - if (parsedJson.aud.toLowerCase() === this.config.clientId.toLowerCase()) { - - user = { - userName: '', - profile: parsedJson - }; - - if (parsedJson.hasOwnProperty('upn')) { - user.userName = parsedJson.upn; - } else if (parsedJson.hasOwnProperty('email')) { - user.userName = parsedJson.email; - } - } else { - this.warn('IdToken has invalid aud field'); - } - } + _AuthenticationContext.prototype._urlRemoveQueryStringParameter = function (url, name) { + // we remove &name=value, name=value& and name=value + // &name=value + var regex = new RegExp('(\\&' + name + '=)[^\&]+'); + url = url.replace(regex, ''); // name=value& - return user; - }; + regex = new RegExp('(' + name + '=)[^\&]+&'); + url = url.replace(regex, ''); // name=value - /** - * Returns the anchor part(#) of the URL - * @ignore - */ - _AuthenticationContext.prototype._getHash = function (hash) { - if (hash.indexOf('#/') > -1) { - hash = hash.substring(hash.indexOf('#/') + 2); - } else if (hash.indexOf('#') > -1) { - hash = hash.substring(1); - } + regex = new RegExp('(' + name + '=)[^\&]+'); + url = url.replace(regex, ''); + return url; + }; // Calling _loadFrame but with a timeout to signal failure in loadframeStatus. Callbacks are left + // registered when network errors occur and subsequent token requests for same resource are registered to the pending request - return hash; - }; + /** + * @ignore + */ - /** - * Checks if the URL fragment contains access token, id token or error_description. - * @param {string} hash - Hash passed from redirect page - * @returns {Boolean} true if response contains id_token, access_token or error, false otherwise. - */ - _AuthenticationContext.prototype.isCallback = function (hash) { - hash = this._getHash(hash); - var parameters = this._deserialize(hash); - return parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION) || parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN) || parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN); - }; - /** - * Gets login error - * @returns {string} error message related to login. - */ - _AuthenticationContext.prototype.getLoginError = function () { - return this._getItem(this.CONSTANTS.STORAGE.LOGIN_ERROR); - }; + _AuthenticationContext.prototype._loadFrameTimeout = function (urlNavigation, frameName, resource) { + //set iframe session to pending + this.verbose('Set loading state to pending for: ' + resource); - /** - * Request info object created from the response received from AAD. - * @class RequestInfo - * @property {object} parameters - object comprising of fields such as id_token/error, session_state, state, e.t.c. - * @property {REQUEST_TYPE} requestType - either LOGIN, RENEW_TOKEN or UNKNOWN. - * @property {boolean} stateMatch - true if state is valid, false otherwise. - * @property {string} stateResponse - unique guid used to match the response with the request. - * @property {boolean} valid - true if requestType contains id_token, access_token or error, false otherwise. - */ + this._saveItem(this.CONSTANTS.STORAGE.RENEW_STATUS + resource, this.CONSTANTS.TOKEN_RENEW_STATUS_IN_PROGRESS); - /** - * Creates a requestInfo object from the URL fragment and returns it. - * @returns {RequestInfo} an object created from the redirect response from AAD comprising of the keys - parameters, requestType, stateMatch, stateResponse and valid. - */ - _AuthenticationContext.prototype.getRequestInfo = function (hash) { - hash = this._getHash(hash); - var parameters = this._deserialize(hash); - var requestInfo = { - valid: false, - parameters: {}, - stateMatch: false, - stateResponse: '', - requestType: this.REQUEST_TYPE.UNKNOWN - }; + this._loadFrame(urlNavigation, frameName); - if (parameters) { - requestInfo.parameters = parameters; - if (parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION) || parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN) || parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) { - - requestInfo.valid = true; - - // which call - var stateResponse = ''; - if (parameters.hasOwnProperty('state')) { - this.verbose('State: ' + parameters.state); - stateResponse = parameters.state; - } else { - this.warn('No state returned'); - return requestInfo; - } - - requestInfo.stateResponse = stateResponse; - - // async calls can fire iframe and login request at the same time if developer does not use the API as expected - // incoming callback needs to be looked up to find the request type - if (this._matchState(requestInfo)) { - // loginRedirect or acquireTokenRedirect - return requestInfo; - } - - // external api requests may have many renewtoken requests for different resource - if (!requestInfo.stateMatch && window.parent) { - requestInfo.requestType = this._requestType; - var statesInParentContext = this._renewStates; - for (var i = 0; i < statesInParentContext.length; i++) { - if (statesInParentContext[i] === requestInfo.stateResponse) { - requestInfo.stateMatch = true; - break; - } - } - } - } - } - return requestInfo; - }; + var self = this; + setTimeout(function () { + if (self._getItem(self.CONSTANTS.STORAGE.RENEW_STATUS + resource) === self.CONSTANTS.TOKEN_RENEW_STATUS_IN_PROGRESS) { + // fail the iframe session if it's in pending state + self.verbose('Loading frame has timed out after: ' + self.CONSTANTS.LOADFRAME_TIMEOUT / 1000 + ' seconds for resource ' + resource); + var expectedState = self._activeRenewals[resource]; - /** - * Matches nonce from the request with the response. - * @ignore - */ - _AuthenticationContext.prototype._matchNonce = function (user) { - var requestNonce = this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN); - - if (requestNonce) { - requestNonce = requestNonce.split(this.CONSTANTS.CACHE_DELIMETER); - for (var i = 0; i < requestNonce.length; i++) { - if (requestNonce[i] === user.profile.nonce) { - return true; - } - } + if (expectedState && self._callBackMappedToRenewStates[expectedState]) { + self._callBackMappedToRenewStates[expectedState]('Token renewal operation failed due to timeout', null, 'Token Renewal Failed'); } - return false; - }; - - /** - * Matches state from the request with the response. - * @ignore - */ - _AuthenticationContext.prototype._matchState = function (requestInfo) { - var loginStates = this._getItem(this.CONSTANTS.STORAGE.STATE_LOGIN); - - if (loginStates) { - loginStates = loginStates.split(this.CONSTANTS.CACHE_DELIMETER); - for (var i = 0; i < loginStates.length; i++) { - if (loginStates[i] === requestInfo.stateResponse) { - requestInfo.requestType = this.REQUEST_TYPE.LOGIN; - requestInfo.stateMatch = true; - return true; - } - } - } + self._saveItem(self.CONSTANTS.STORAGE.RENEW_STATUS + resource, self.CONSTANTS.TOKEN_RENEW_STATUS_CANCELED); + } + }, self.CONSTANTS.LOADFRAME_TIMEOUT); + }; + /** + * Loads iframe with authorization endpoint URL + * @ignore + */ + - var acquireTokenStates = this._getItem(this.CONSTANTS.STORAGE.STATE_RENEW); + _AuthenticationContext.prototype._loadFrame = function (urlNavigate, frameName) { + // This trick overcomes iframe navigation in IE + // IE does not load the page consistently in iframe + var self = this; + self.info('LoadFrame: ' + frameName); + var frameCheck = frameName; + setTimeout(function () { + var frameHandle = self._addAdalFrame(frameCheck); - if (acquireTokenStates) { - acquireTokenStates = acquireTokenStates.split(this.CONSTANTS.CACHE_DELIMETER); - for (var i = 0; i < acquireTokenStates.length; i++) { - if (acquireTokenStates[i] === requestInfo.stateResponse) { - requestInfo.requestType = this.REQUEST_TYPE.RENEW_TOKEN; - requestInfo.stateMatch = true; - return true; - } - } - } + if (frameHandle.src === '' || frameHandle.src === 'about:blank') { + frameHandle.src = urlNavigate; + + self._loadFrame(urlNavigate, frameCheck); + } + }, 500); + }; + /** + * @callback tokenCallback + * @param {string} error_description error description returned from AAD if token request fails. + * @param {string} token token returned from AAD if token request is successful. + * @param {string} error error message returned from AAD if token request fails. + */ + + /** + * Acquires token from the cache if it is not expired. Otherwise sends request to AAD to obtain a new token. + * @param {string} resource ResourceUri identifying the target resource + * @param {tokenCallback} callback - The callback provided by the caller. It will be called with token or error. + */ + + + _AuthenticationContext.prototype.acquireToken = function (resource, callback) { + if (this._isEmpty(resource)) { + this.warn('resource is required'); + callback('resource is required', null, 'resource is required'); + return; + } - return false; - }; + var token = this.getCachedToken(resource); - /** - * Extracts resource value from state. - * @ignore - */ - _AuthenticationContext.prototype._getResourceFromState = function (state) { - if (state) { - var splitIndex = state.indexOf('|'); + if (token) { + this.info('Token is already in cache for resource:' + resource); + callback(null, token, null); + return; + } - if (splitIndex > -1 && splitIndex + 1 < state.length) { - return state.substring(splitIndex + 1); - } - } + if (!this._user && !(this.config.extraQueryParameter && this.config.extraQueryParameter.indexOf('login_hint') !== -1)) { + this.warn('User login is required'); + callback('User login is required', null, 'login required'); + return; + } // renew attempt with iframe + // Already renewing for this resource, callback when we get the token. - return ''; - }; - /** - * Saves token or error received in the response from AAD in the cache. In case of id_token, it also creates the user object. - */ - _AuthenticationContext.prototype.saveTokenFromHash = function (requestInfo) { - this.info('State status:' + requestInfo.stateMatch + '; Request type:' + requestInfo.requestType); - this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); - - var resource = this._getResourceFromState(requestInfo.stateResponse); - - // Record error - if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION)) { - this.infoPii('Error :' + requestInfo.parameters.error + '; Error description:' + requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); - this._saveItem(this.CONSTANTS.STORAGE.ERROR, requestInfo.parameters.error); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); - - if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { - this._loginInProgress = false; - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, requestInfo.parameters.error_description); - } - } else { - // It must verify the state from redirect - if (requestInfo.stateMatch) { - // record tokens to storage if exists - this.info('State is right'); - if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.SESSION_STATE)) { - this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, requestInfo.parameters[this.CONSTANTS.SESSION_STATE]); - } - - var keys; - - if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN)) { - this.info('Fragment has access token'); - - if (!this._hasResource(resource)) { - keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || ''; - this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER); - } - - // save token with related resource - this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ACCESS_TOKEN]); - this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._expiresIn(requestInfo.parameters[this.CONSTANTS.EXPIRES_IN])); - } - - if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) { - this.info('Fragment has id token'); - this._loginInProgress = false; - this._user = this._createUser(requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); - if (this._user && this._user.profile) { - if (!this._matchNonce(this._user)) { - this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'Nonce received: ' + this._user.profile.nonce + ' is not same as requested: ' + this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN)); - this._user = null; - } else { - this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); - - // Save idtoken as access token for app itself - resource = this.config.loginResource ? this.config.loginResource : this.config.clientId; - - if (!this._hasResource(resource)) { - keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || ''; - this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER); - } - - this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); - this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._user.profile.exp); - } - } else { - requestInfo.parameters['error'] = 'invalid id_token'; - requestInfo.parameters['error_description'] = 'Invalid id_token. id_token: ' + requestInfo.parameters[this.CONSTANTS.ID_TOKEN]; - this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'invalid id_token'); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid id_token. id_token: ' + requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); - } - } - } else { - requestInfo.parameters['error'] = 'Invalid_state'; - requestInfo.parameters['error_description'] = 'Invalid_state. state: ' + requestInfo.stateResponse; - this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'Invalid_state'); - this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid_state. state: ' + requestInfo.stateResponse); - } - } + if (this._activeRenewals[resource]) { + // Active renewals contains the state for each renewal. + this.registerCallback(this._activeRenewals[resource], resource, callback); + } else { + this._requestType = this.REQUEST_TYPE.RENEW_TOKEN; - this._saveItem(this.CONSTANTS.STORAGE.RENEW_STATUS + resource, this.CONSTANTS.TOKEN_RENEW_STATUS_COMPLETED); - }; + if (resource === this.config.clientId) { + // App uses idtoken to send to api endpoints + // Default resource is tracked as clientid to store this token + if (this._user) { + this.verbose('renewing idtoken'); - /** - * Gets resource for given endpoint if mapping is provided with config. - * @param {string} endpoint - The URI for which the resource Id is requested. - * @returns {string} resource for this API endpoint. - */ - _AuthenticationContext.prototype.getResourceForEndpoint = function (endpoint) { - - // if user specified list of anonymous endpoints, no need to send token to these endpoints, return null. - if (this.config && this.config.anonymousEndpoints) { - for (var i = 0; i < this.config.anonymousEndpoints.length; i++) { - if (endpoint.indexOf(this.config.anonymousEndpoints[i]) > -1) { - return null; - } - } - } + this._renewIdToken(callback); + } else { + this.verbose('renewing idtoken and access_token'); - if (this.config && this.config.endpoints) { - for (var configEndpoint in this.config.endpoints) { - // configEndpoint is like /api/Todo requested endpoint can be /api/Todo/1 - if (endpoint.indexOf(configEndpoint) > -1) { - return this.config.endpoints[configEndpoint]; - } - } + this._renewIdToken(callback, this.RESPONSE_TYPE.ID_TOKEN_TOKEN); } + } else { + if (this._user) { + this.verbose('renewing access_token'); - // default resource will be clientid if nothing specified - // App will use idtoken for calls to itself - // check if it's staring from http or https, needs to match with app host - if (endpoint.indexOf('http://') > -1 || endpoint.indexOf('https://') > -1) { - if (this._getHostFromUri(endpoint) === this._getHostFromUri(this.config.redirectUri)) { - return this.config.loginResource; - } + this._renewToken(resource, callback); } else { - // in angular level, the url for $http interceptor call could be relative url, - // if it's relative call, we'll treat it as app backend call. - return this.config.loginResource; + this.verbose('renewing idtoken and access_token'); + + this._renewToken(resource, callback, this.RESPONSE_TYPE.ID_TOKEN_TOKEN); } + } + } + }; + /** + * Acquires token (interactive flow using a popUp window) by sending request to AAD to obtain a new token. + * @param {string} resource ResourceUri identifying the target resource + * @param {string} extraQueryParameters extraQueryParameters to add to the authentication request + * @param {tokenCallback} callback - The callback provided by the caller. It will be called with token or error. + */ + + + _AuthenticationContext.prototype.acquireTokenPopup = function (resource, extraQueryParameters, claims, callback) { + if (this._isEmpty(resource)) { + this.warn('resource is required'); + callback('resource is required', null, 'resource is required'); + return; + } - // if not the app's own backend or not a domain listed in the endpoints structure - return null; - }; + if (!this._user) { + this.warn('User login is required'); + callback('User login is required', null, 'login required'); + return; + } - /** - * Strips the protocol part of the URL and returns it. - * @ignore - */ - _AuthenticationContext.prototype._getHostFromUri = function (uri) { - // remove http:// or https:// from uri - var extractedUri = String(uri).replace(/^(https?:)\/\//, ''); - extractedUri = extractedUri.split('/')[0]; - return extractedUri; - }; + if (this._acquireTokenInProgress) { + this.warn("Acquire token interactive is already in progress"); + callback("Acquire token interactive is already in progress", null, "Acquire token interactive is already in progress"); + return; + } - /** - * This method must be called for processing the response received from AAD. It extracts the hash, processes the token or error, saves it in the cache and calls the registered callbacks with the result. - * @param {string} [hash=window.location.hash] - Hash fragment of Url. - */ - _AuthenticationContext.prototype.handleWindowCallback = function (hash) { - // This is for regular javascript usage for redirect handling - // need to make sure this is for callback - if (hash == null) { - hash = window.location.hash; - } + var expectedState = this._guid() + '|' + resource; + this.config.state = expectedState; - if (this.isCallback(hash)) { - var self = null; - var isPopup = false; + this._renewStates.push(expectedState); - if (this._openedWindows.length > 0 && this._openedWindows[this._openedWindows.length - 1].opener && this._openedWindows[this._openedWindows.length - 1].opener._adalInstance) { - self = this._openedWindows[this._openedWindows.length - 1].opener._adalInstance; - isPopup = true; - } else if (window.parent && window.parent._adalInstance) { - self = window.parent._adalInstance; - } + this._requestType = this.REQUEST_TYPE.RENEW_TOKEN; + this.verbose('Renew token Expected state: ' + expectedState); // remove the existing prompt=... query parameter and add prompt=select_account - var requestInfo = self.getRequestInfo(hash); - var token, - tokenReceivedCallback, - tokenType = null; + var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl('token', resource), 'prompt'); - if (isPopup || window.parent !== window) { - tokenReceivedCallback = self._callBackMappedToRenewStates[requestInfo.stateResponse]; - } else { - tokenReceivedCallback = self.callback; - } + urlNavigate = urlNavigate + '&prompt=select_account'; - self.info("Returned from redirect url"); - self.saveTokenFromHash(requestInfo); - - if (requestInfo.requestType === this.REQUEST_TYPE.RENEW_TOKEN && window.parent) { - if (window.parent !== window) { - self.verbose("Window is in iframe, acquiring token silently"); - } else { - self.verbose("acquiring token interactive in progress"); - } - - token = requestInfo.parameters[self.CONSTANTS.ACCESS_TOKEN] || requestInfo.parameters[self.CONSTANTS.ID_TOKEN]; - tokenType = self.CONSTANTS.ACCESS_TOKEN; - } else if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { - token = requestInfo.parameters[self.CONSTANTS.ID_TOKEN]; - tokenType = self.CONSTANTS.ID_TOKEN; - } + if (extraQueryParameters) { + urlNavigate += extraQueryParameters; + } - var errorDesc = requestInfo.parameters[self.CONSTANTS.ERROR_DESCRIPTION]; - var error = requestInfo.parameters[self.CONSTANTS.ERROR]; - try { - if (tokenReceivedCallback) { - tokenReceivedCallback(errorDesc, token, error, tokenType); - } - } catch (err) { - self.error("Error occurred in user defined callback function: " + err); - } + if (claims && urlNavigate.indexOf("&claims") === -1) { + urlNavigate += '&claims=' + encodeURIComponent(claims); + } else if (claims && urlNavigate.indexOf("&claims") !== -1) { + throw new Error('Claims cannot be passed as an extraQueryParameter'); + } - if (window.parent === window && !isPopup) { - if (self.config.navigateToLoginRequestUrl) { - window.location.href = self._getItem(self.CONSTANTS.STORAGE.LOGIN_REQUEST); - } else window.location.hash = ''; - } - } - }; + urlNavigate = this._addHintParameters(urlNavigate); + this._acquireTokenInProgress = true; + this.info('acquireToken interactive is called for the resource ' + resource); + this.registerCallback(expectedState, resource, callback); + + this._loginPopup(urlNavigate, resource, callback); + }; + /** + * Acquires token (interactive flow using a redirect) by sending request to AAD to obtain a new token. In this case the callback passed in the Authentication + * request constructor will be called. + * @param {string} resource ResourceUri identifying the target resource + * @param {string} extraQueryParameters extraQueryParameters to add to the authentication request + */ + + + _AuthenticationContext.prototype.acquireTokenRedirect = function (resource, extraQueryParameters, claims) { + if (this._isEmpty(resource)) { + this.warn('resource is required'); + callback('resource is required', null, 'resource is required'); + return; + } - /** - * Constructs the authorization endpoint URL and returns it. - * @ignore - */ - _AuthenticationContext.prototype._getNavigateUrl = function (responseType, resource) { - var tenant = 'common'; - if (this.config.tenant) { - tenant = this.config.tenant; + var callback = this.callback; + + if (!this._user) { + this.warn('User login is required'); + callback('User login is required', null, 'login required'); + return; + } + + if (this._acquireTokenInProgress) { + this.warn("Acquire token interactive is already in progress"); + callback("Acquire token interactive is already in progress", null, "Acquire token interactive is already in progress"); + return; + } + + var expectedState = this._guid() + '|' + resource; + this.config.state = expectedState; + this.verbose('Renew token Expected state: ' + expectedState); // remove the existing prompt=... query parameter and add prompt=select_account + + var urlNavigate = this._urlRemoveQueryStringParameter(this._getNavigateUrl('token', resource), 'prompt'); + + urlNavigate = urlNavigate + '&prompt=select_account'; + + if (extraQueryParameters) { + urlNavigate += extraQueryParameters; + } + + if (claims && urlNavigate.indexOf("&claims") === -1) { + urlNavigate += '&claims=' + encodeURIComponent(claims); + } else if (claims && urlNavigate.indexOf("&claims") !== -1) { + throw new Error('Claims cannot be passed as an extraQueryParameter'); + } + + urlNavigate = this._addHintParameters(urlNavigate); + this._acquireTokenInProgress = true; + this.info('acquireToken interactive is called for the resource ' + resource); + + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, window.location.href); + + this._saveItem(this.CONSTANTS.STORAGE.STATE_RENEW, expectedState, true); + + this.promptUser(urlNavigate); + }; + /** + * Redirects the browser to Azure AD authorization endpoint. + * @param {string} urlNavigate Url of the authorization endpoint. + */ + + + _AuthenticationContext.prototype.promptUser = function (urlNavigate) { + if (urlNavigate) { + this.infoPii('Navigate to:' + urlNavigate); + window.location.replace(urlNavigate); + } else { + this.info('Navigate url is empty'); + } + }; + /** + * Clears cache items. + */ + + + _AuthenticationContext.prototype.clearCache = function () { + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_REQUEST, ''); + + this._saveItem(this.CONSTANTS.STORAGE.ANGULAR_LOGIN_REQUEST, ''); + + this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, ''); + + this._saveItem(this.CONSTANTS.STORAGE.STATE_LOGIN, ''); + + this._saveItem(this.CONSTANTS.STORAGE.STATE_RENEW, ''); + + this._renewStates = []; + + this._saveItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN, ''); + + this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, ''); + + this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); + + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); + + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, ''); + + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, ''); + + var keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS); + + if (!this._isEmpty(keys)) { + keys = keys.split(this.CONSTANTS.RESOURCE_DELIMETER); + + for (var i = 0; i < keys.length && keys[i] !== ""; i++) { + this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + keys[i], ''); + + this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + keys[i], 0); + } + } + + this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, ''); + }; + /** + * Clears cache items for a given resource. + * @param {string} resource a URI that identifies the resource. + */ + + + _AuthenticationContext.prototype.clearCacheForResource = function (resource) { + this._saveItem(this.CONSTANTS.STORAGE.STATE_RENEW, ''); + + this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); + + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); + + if (this._hasResource(resource)) { + this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, ''); + + this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, 0); + } + }; + /** + * Redirects user to logout endpoint. + * After logout, it will redirect to postLogoutRedirectUri if added as a property on the config object. + */ + + + _AuthenticationContext.prototype.logOut = function () { + this.clearCache(); + this._user = null; + var urlNavigate; + + if (this.config.logOutUri) { + urlNavigate = this.config.logOutUri; + } else { + var tenant = 'common'; + var logout = ''; + + if (this.config.tenant) { + tenant = this.config.tenant; + } + + if (this.config.postLogoutRedirectUri) { + logout = 'post_logout_redirect_uri=' + encodeURIComponent(this.config.postLogoutRedirectUri); + } + + urlNavigate = this.instance + tenant + '/oauth2/logout?' + logout; + } + + this.infoPii('Logout navigate to: ' + urlNavigate); + this.promptUser(urlNavigate); + }; + + _AuthenticationContext.prototype._isEmpty = function (str) { + return typeof str === 'undefined' || !str || 0 === str.length; + }; + /** + * @callback userCallback + * @param {string} error error message if user info is not available. + * @param {User} user user object retrieved from the cache. + */ + + /** + * Calls the passed in callback with the user object or error message related to the user. + * @param {userCallback} callback - The callback provided by the caller. It will be called with user or error. + */ + + + _AuthenticationContext.prototype.getUser = function (callback) { + // IDToken is first call + if (typeof callback !== 'function') { + throw new Error('callback is not a function'); + } // user in memory + + + if (this._user) { + callback(null, this._user); + return; + } // frame is used to get idtoken + + + var idtoken = this._getItem(this.CONSTANTS.STORAGE.IDTOKEN); + + if (!this._isEmpty(idtoken)) { + this.info('User exists in cache: '); + this._user = this._createUser(idtoken); + callback(null, this._user); + } else { + this.warn('User information is not available'); + callback('User information is not available', null); + } + }; + /** + * Adds login_hint to authorization URL which is used to pre-fill the username field of sign in page for the user if known ahead of time. + * domain_hint can be one of users/organisations which when added skips the email based discovery process of the user. + * @ignore + */ + + + _AuthenticationContext.prototype._addHintParameters = function (urlNavigate) { + //If you don�t use prompt=none, then if the session does not exist, there will be a failure. + //If sid is sent alongside domain or login hints, there will be a failure since request is ambiguous. + //If sid is sent with a prompt value other than none or attempt_none, there will be a failure since the request is ambiguous. + if (this._user && this._user.profile) { + if (this._user.profile.sid && urlNavigate.indexOf('&prompt=none') !== -1) { + // don't add sid twice if user provided it in the extraQueryParameter value + if (!this._urlContainsQueryStringParameter("sid", urlNavigate)) { + // add sid + urlNavigate += '&sid=' + encodeURIComponent(this._user.profile.sid); } + } else if (this._user.profile.upn) { + // don't add login_hint twice if user provided it in the extraQueryParameter value + if (!this._urlContainsQueryStringParameter("login_hint", urlNavigate)) { + // add login_hint + urlNavigate += '&login_hint=' + encodeURIComponent(this._user.profile.upn); + } // don't add domain_hint twice if user provided it in the extraQueryParameter value - var urlNavigate = this.instance + tenant + '/oauth2/authorize' + this._serialize(responseType, this.config, resource) + this._addLibMetadata(); - this.info('Navigate url:' + urlNavigate); - return urlNavigate; - }; - /** - * Returns the decoded id_token. - * @ignore - */ - _AuthenticationContext.prototype._extractIdToken = function (encodedIdToken) { - // id token will be decoded to get the username - var decodedToken = this._decodeJwt(encodedIdToken); + if (!this._urlContainsQueryStringParameter("domain_hint", urlNavigate) && this._user.profile.upn.indexOf('@') > -1) { + var parts = this._user.profile.upn.split('@'); // local part can include @ in quotes. Sending last part handles that. + - if (!decodedToken) { - return null; + urlNavigate += '&domain_hint=' + encodeURIComponent(parts[parts.length - 1]); } + } + } - try { - var base64IdToken = decodedToken.JWSPayload; - var base64Decoded = this._base64DecodeStringUrlSafe(base64IdToken); + return urlNavigate; + }; + /** + * Creates a user object by decoding the id_token + * @ignore + */ - if (!base64Decoded) { - this.info('The returned id_token could not be base64 url safe decoded.'); - return null; - } - // ECMA script has JSON built-in support - return JSON.parse(base64Decoded); - } catch (err) { - this.error('The returned id_token could not be decoded', err); + _AuthenticationContext.prototype._createUser = function (idToken) { + var user = null; + + var parsedJson = this._extractIdToken(idToken); + + if (parsedJson && parsedJson.hasOwnProperty('aud')) { + if (parsedJson.aud.toLowerCase() === this.config.clientId.toLowerCase()) { + user = { + userName: '', + profile: parsedJson + }; + + if (parsedJson.hasOwnProperty('upn')) { + user.userName = parsedJson.upn; + } else if (parsedJson.hasOwnProperty('email')) { + user.userName = parsedJson.email; } + } else { + this.warn('IdToken has invalid aud field'); + } + } - return null; + return user; + }; + /** + * Returns the anchor part(#) of the URL + * @ignore + */ + + + _AuthenticationContext.prototype._getHash = function (hash) { + if (hash.indexOf('#/') > -1) { + hash = hash.substring(hash.indexOf('#/') + 2); + } else if (hash.indexOf('#') > -1) { + hash = hash.substring(1); + } + + return hash; + }; + /** + * Checks if the URL fragment contains access token, id token or error_description. + * @param {string} hash - Hash passed from redirect page + * @returns {Boolean} true if response contains id_token, access_token or error, false otherwise. + */ + + + _AuthenticationContext.prototype.isCallback = function (hash) { + hash = this._getHash(hash); + + var parameters = this._deserialize(hash); + + return parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION) || parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN) || parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN); + }; + /** + * Gets login error + * @returns {string} error message related to login. + */ + + + _AuthenticationContext.prototype.getLoginError = function () { + return this._getItem(this.CONSTANTS.STORAGE.LOGIN_ERROR); + }; + /** + * Request info object created from the response received from AAD. + * @class RequestInfo + * @property {object} parameters - object comprising of fields such as id_token/error, session_state, state, e.t.c. + * @property {REQUEST_TYPE} requestType - either LOGIN, RENEW_TOKEN or UNKNOWN. + * @property {boolean} stateMatch - true if state is valid, false otherwise. + * @property {string} stateResponse - unique guid used to match the response with the request. + * @property {boolean} valid - true if requestType contains id_token, access_token or error, false otherwise. + */ + + /** + * Creates a requestInfo object from the URL fragment and returns it. + * @returns {RequestInfo} an object created from the redirect response from AAD comprising of the keys - parameters, requestType, stateMatch, stateResponse and valid. + */ + + + _AuthenticationContext.prototype.getRequestInfo = function (hash) { + hash = this._getHash(hash); + + var parameters = this._deserialize(hash); + + var requestInfo = { + valid: false, + parameters: {}, + stateMatch: false, + stateResponse: '', + requestType: this.REQUEST_TYPE.UNKNOWN }; - /** - * Decodes a string of data which has been encoded using base-64 encoding. - * @ignore - */ - _AuthenticationContext.prototype._base64DecodeStringUrlSafe = function (base64IdToken) { - // html5 should support atob function for decoding - base64IdToken = base64IdToken.replace(/-/g, '+').replace(/_/g, '/'); + if (parameters) { + requestInfo.parameters = parameters; + + if (parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION) || parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN) || parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) { + requestInfo.valid = true; // which call - if (window.atob) { - return decodeURIComponent(escape(window.atob(base64IdToken))); // jshint ignore:line + var stateResponse = ''; + + if (parameters.hasOwnProperty('state')) { + this.verbose('State: ' + parameters.state); + stateResponse = parameters.state; } else { - return decodeURIComponent(escape(this._decode(base64IdToken))); + this.warn('No state returned'); + return requestInfo; } - }; - //Take https://cdnjs.cloudflare.com/ajax/libs/Base64/0.3.0/base64.js and https://en.wikipedia.org/wiki/Base64 as reference. - _AuthenticationContext.prototype._decode = function (base64IdToken) { - var codes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; - base64IdToken = String(base64IdToken).replace(/=+$/, ''); + requestInfo.stateResponse = stateResponse; // async calls can fire iframe and login request at the same time if developer does not use the API as expected + // incoming callback needs to be looked up to find the request type - var length = base64IdToken.length; + if (this._matchState(requestInfo)) { + // loginRedirect or acquireTokenRedirect + return requestInfo; + } // external api requests may have many renewtoken requests for different resource - if (length % 4 === 1) { - throw new Error('The token to be decoded is not correctly encoded.'); - } - var h1, - h2, - h3, - h4, - bits, - c1, - c2, - c3, - decoded = ''; - - for (var i = 0; i < length; i += 4) { - //Every 4 base64 encoded character will be converted to 3 byte string, which is 24 bits - // then 6 bits per base64 encoded character - h1 = codes.indexOf(base64IdToken.charAt(i)); - h2 = codes.indexOf(base64IdToken.charAt(i + 1)); - h3 = codes.indexOf(base64IdToken.charAt(i + 2)); - h4 = codes.indexOf(base64IdToken.charAt(i + 3)); - - // For padding, if last two are '=' - if (i + 2 === length - 1) { - bits = h1 << 18 | h2 << 12 | h3 << 6; - c1 = bits >> 16 & 255; - c2 = bits >> 8 & 255; - decoded += String.fromCharCode(c1, c2); - break; + if (!requestInfo.stateMatch && window.parent) { + requestInfo.requestType = this._requestType; + var statesInParentContext = this._renewStates; + + for (var i = 0; i < statesInParentContext.length; i++) { + if (statesInParentContext[i] === requestInfo.stateResponse) { + requestInfo.stateMatch = true; + break; } - // if last one is '=' - else if (i + 1 === length - 1) { - bits = h1 << 18 | h2 << 12; - c1 = bits >> 16 & 255; - decoded += String.fromCharCode(c1); - break; - } - - bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; - - // then convert to 3 byte chars - c1 = bits >> 16 & 255; - c2 = bits >> 8 & 255; - c3 = bits & 255; - - decoded += String.fromCharCode(c1, c2, c3); + } } + } + } - return decoded; - }; + return requestInfo; + }; + /** + * Matches nonce from the request with the response. + * @ignore + */ - /** - * Decodes an id token into an object with header, payload and signature fields. - * @ignore - */ - // Adal.node js crack function - _AuthenticationContext.prototype._decodeJwt = function (jwtToken) { - if (this._isEmpty(jwtToken)) { - return null; - }; - var idTokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/; + _AuthenticationContext.prototype._matchNonce = function (user) { + var requestNonce = this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN); - var matches = idTokenPartsRegex.exec(jwtToken); + if (requestNonce) { + requestNonce = requestNonce.split(this.CONSTANTS.CACHE_DELIMETER); - if (!matches || matches.length < 4) { - this.warn('The returned id_token is not parseable.'); - return null; + for (var i = 0; i < requestNonce.length; i++) { + if (requestNonce[i] === user.profile.nonce) { + return true; } + } + } - var crackedToken = { - header: matches[1], - JWSPayload: matches[2], - JWSSig: matches[3] - }; + return false; + }; + /** + * Matches state from the request with the response. + * @ignore + */ - return crackedToken; - }; - /** - * Converts string to represent binary data in ASCII string format by translating it into a radix-64 representation and returns it - * @ignore - */ - _AuthenticationContext.prototype._convertUrlSafeToRegularBase64EncodedString = function (str) { - return str.replace('-', '+').replace('_', '/'); - }; + _AuthenticationContext.prototype._matchState = function (requestInfo) { + var loginStates = this._getItem(this.CONSTANTS.STORAGE.STATE_LOGIN); - /** - * Serializes the parameters for the authorization endpoint URL and returns the serialized uri string. - * @ignore - */ - _AuthenticationContext.prototype._serialize = function (responseType, obj, resource) { - var str = []; - - if (obj !== null) { - str.push('?response_type=' + responseType); - str.push('client_id=' + encodeURIComponent(obj.clientId)); - if (resource) { - str.push('resource=' + encodeURIComponent(resource)); - } + if (loginStates) { + loginStates = loginStates.split(this.CONSTANTS.CACHE_DELIMETER); - str.push('redirect_uri=' + encodeURIComponent(obj.redirectUri)); - str.push('state=' + encodeURIComponent(obj.state)); + for (var i = 0; i < loginStates.length; i++) { + if (loginStates[i] === requestInfo.stateResponse) { + requestInfo.requestType = this.REQUEST_TYPE.LOGIN; + requestInfo.stateMatch = true; + return true; + } + } + } - if (obj.hasOwnProperty('slice')) { - str.push('slice=' + encodeURIComponent(obj.slice)); - } + var acquireTokenStates = this._getItem(this.CONSTANTS.STORAGE.STATE_RENEW); - if (obj.hasOwnProperty('extraQueryParameter')) { - str.push(obj.extraQueryParameter); - } + if (acquireTokenStates) { + acquireTokenStates = acquireTokenStates.split(this.CONSTANTS.CACHE_DELIMETER); - var correlationId = obj.correlationId ? obj.correlationId : this._guid(); - str.push('client-request-id=' + encodeURIComponent(correlationId)); + for (var i = 0; i < acquireTokenStates.length; i++) { + if (acquireTokenStates[i] === requestInfo.stateResponse) { + requestInfo.requestType = this.REQUEST_TYPE.RENEW_TOKEN; + requestInfo.stateMatch = true; + return true; } + } + } - return str.join('&'); - }; + return false; + }; + /** + * Extracts resource value from state. + * @ignore + */ - /** - * Parses the query string parameters into a key-value pair object. - * @ignore - */ - _AuthenticationContext.prototype._deserialize = function (query) { - var match, - pl = /\+/g, - // Regex for replacing addition symbol with a space - search = /([^&=]+)=([^&]*)/g, - decode = function decode(s) { - return decodeURIComponent(s.replace(pl, ' ')); - }, - obj = {}; - match = search.exec(query); - - while (match) { - obj[decode(match[1])] = decode(match[2]); - match = search.exec(query); - } - return obj; - }; + _AuthenticationContext.prototype._getResourceFromState = function (state) { + if (state) { + var splitIndex = state.indexOf('|'); - /** - * Converts decimal value to hex equivalent - * @ignore - */ - _AuthenticationContext.prototype._decimalToHex = function (number) { - var hex = number.toString(16); + if (splitIndex > -1 && splitIndex + 1 < state.length) { + return state.substring(splitIndex + 1); + } + } - while (hex.length < 2) { - hex = '0' + hex; - } - return hex; - }; + return ''; + }; + /** + * Saves token or error received in the response from AAD in the cache. In case of id_token, it also creates the user object. + */ - /** - * Generates RFC4122 version 4 guid (128 bits) - * @ignore - */ - /* jshint ignore:start */ - _AuthenticationContext.prototype._guid = function () { - // RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or - // pseudo-random numbers. - // The algorithm is as follows: - // Set the two most significant bits (bits 6 and 7) of the - // clock_seq_hi_and_reserved to zero and one, respectively. - // Set the four most significant bits (bits 12 through 15) of the - // time_hi_and_version field to the 4-bit version number from - // Section 4.1.3. Version4 - // Set all the other bits to randomly (or pseudo-randomly) chosen - // values. - // UUID = time-low "-" time-mid "-"time-high-and-version "-"clock-seq-reserved and low(2hexOctet)"-" node - // time-low = 4hexOctet - // time-mid = 2hexOctet - // time-high-and-version = 2hexOctet - // clock-seq-and-reserved = hexOctet: - // clock-seq-low = hexOctet - // node = 6hexOctet - // Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx - // y could be 1000, 1001, 1010, 1011 since most significant two bits needs to be 10 - // y values are 8, 9, A, B - var cryptoObj = window.crypto || window.msCrypto; // for IE 11 - if (cryptoObj && cryptoObj.getRandomValues) { - var buffer = new Uint8Array(16); - cryptoObj.getRandomValues(buffer); - //buffer[6] and buffer[7] represents the time_hi_and_version field. We will set the four most significant bits (4 through 7) of buffer[6] to represent decimal number 4 (UUID version number). - buffer[6] |= 0x40; //buffer[6] | 01000000 will set the 6 bit to 1. - buffer[6] &= 0x4f; //buffer[6] & 01001111 will set the 4, 5, and 7 bit to 0 such that bits 4-7 == 0100 = "4". - //buffer[8] represents the clock_seq_hi_and_reserved field. We will set the two most significant bits (6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively. - buffer[8] |= 0x80; //buffer[8] | 10000000 will set the 7 bit to 1. - buffer[8] &= 0xbf; //buffer[8] & 10111111 will set the 6 bit to 0. - return this._decimalToHex(buffer[0]) + this._decimalToHex(buffer[1]) + this._decimalToHex(buffer[2]) + this._decimalToHex(buffer[3]) + '-' + this._decimalToHex(buffer[4]) + this._decimalToHex(buffer[5]) + '-' + this._decimalToHex(buffer[6]) + this._decimalToHex(buffer[7]) + '-' + this._decimalToHex(buffer[8]) + this._decimalToHex(buffer[9]) + '-' + this._decimalToHex(buffer[10]) + this._decimalToHex(buffer[11]) + this._decimalToHex(buffer[12]) + this._decimalToHex(buffer[13]) + this._decimalToHex(buffer[14]) + this._decimalToHex(buffer[15]); - } else { - var guidHolder = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; - var hex = '0123456789abcdef'; - var r = 0; - var guidResponse = ""; - for (var i = 0; i < 36; i++) { - if (guidHolder[i] !== '-' && guidHolder[i] !== '4') { - // each x and y needs to be random - r = Math.random() * 16 | 0; - } - if (guidHolder[i] === 'x') { - guidResponse += hex[r]; - } else if (guidHolder[i] === 'y') { - // clock-seq-and-reserved first hex is filtered and remaining hex values are random - r &= 0x3; // bit and with 0011 to set pos 2 to zero ?0?? - r |= 0x8; // set pos 3 to 1 as 1??? - guidResponse += hex[r]; - } else { - guidResponse += guidHolder[i]; - } - } - return guidResponse; - } - }; - /* jshint ignore:end */ - /** - * Calculates the expires in value in milliseconds for the acquired token - * @ignore - */ - _AuthenticationContext.prototype._expiresIn = function (expires) { - // if AAD did not send "expires_in" property, use default expiration of 3599 seconds, for some reason AAD sends 3599 as "expires_in" value instead of 3600 - if (!expires) expires = 3599; - return this._now() + parseInt(expires, 10); - }; + _AuthenticationContext.prototype.saveTokenFromHash = function (requestInfo) { + this.info('State status:' + requestInfo.stateMatch + '; Request type:' + requestInfo.requestType); - /** - * Return the number of milliseconds since 1970/01/01 - * @ignore - */ - _AuthenticationContext.prototype._now = function () { - return Math.round(new Date().getTime() / 1000.0); - }; + this._saveItem(this.CONSTANTS.STORAGE.ERROR, ''); - /** - * Adds the hidden iframe for silent token renewal - * @ignore - */ - _AuthenticationContext.prototype._addAdalFrame = function (iframeId) { - if (typeof iframeId === 'undefined') { - return; - } + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, ''); - this.info('Add adal frame to document:' + iframeId); - var adalFrame = document.getElementById(iframeId); - - if (!adalFrame) { - if (document.createElement && document.documentElement && (window.opera || window.navigator.userAgent.indexOf('MSIE 5.0') === -1)) { - var ifr = document.createElement('iframe'); - ifr.setAttribute('id', iframeId); - ifr.setAttribute('aria-hidden', 'true'); - ifr.style.visibility = 'hidden'; - ifr.style.position = 'absolute'; - ifr.style.width = ifr.style.height = ifr.borderWidth = '0px'; - - adalFrame = document.getElementsByTagName('body')[0].appendChild(ifr); - } else if (document.body && document.body.insertAdjacentHTML) { - document.body.insertAdjacentHTML('beforeEnd', ''); - } - if (window.frames && window.frames[iframeId]) { - adalFrame = window.frames[iframeId]; - } - } + var resource = this._getResourceFromState(requestInfo.stateResponse); // Record error - return adalFrame; - }; - /** - * Saves the key-value pair in the cache - * @ignore - */ - _AuthenticationContext.prototype._saveItem = function (key, obj, preserve) { + if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ERROR_DESCRIPTION)) { + this.infoPii('Error :' + requestInfo.parameters.error + '; Error description:' + requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); - if (this.config && this.config.cacheLocation && this.config.cacheLocation === 'localStorage') { + this._saveItem(this.CONSTANTS.STORAGE.ERROR, requestInfo.parameters.error); - if (!this._supportsLocalStorage()) { - this.info('Local storage is not supported'); - return false; - } + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, requestInfo.parameters[this.CONSTANTS.ERROR_DESCRIPTION]); - if (preserve) { - var value = this._getItem(key) || ''; - localStorage.setItem(key, value + obj + this.CONSTANTS.CACHE_DELIMETER); - } else { - localStorage.setItem(key, obj); - } + if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { + this._loginInProgress = false; + + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, requestInfo.parameters.error_description); + } + } else { + // It must verify the state from redirect + if (requestInfo.stateMatch) { + // record tokens to storage if exists + this.info('State is right'); - return true; + if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.SESSION_STATE)) { + this._saveItem(this.CONSTANTS.STORAGE.SESSION_STATE, requestInfo.parameters[this.CONSTANTS.SESSION_STATE]); } - // Default as session storage - if (!this._supportsSessionStorage()) { - this.info('Session storage is not supported'); - return false; + var keys; + + if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ACCESS_TOKEN)) { + this.info('Fragment has access token'); + + if (!this._hasResource(resource)) { + keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || ''; + + this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER); + } // save token with related resource + + + this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ACCESS_TOKEN]); + + this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._expiresIn(requestInfo.parameters[this.CONSTANTS.EXPIRES_IN])); } - sessionStorage.setItem(key, obj); - return true; - }; + if (requestInfo.parameters.hasOwnProperty(this.CONSTANTS.ID_TOKEN)) { + this.info('Fragment has id token'); + this._loginInProgress = false; + this._user = this._createUser(requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); - /** - * Searches the value for the given key in the cache - * @ignore - */ - _AuthenticationContext.prototype._getItem = function (key) { + if (this._user && this._user.profile) { + if (!this._matchNonce(this._user)) { + this._saveItem(this.CONSTANTS.STORAGE.LOGIN_ERROR, 'Nonce received: ' + this._user.profile.nonce + ' is not same as requested: ' + this._getItem(this.CONSTANTS.STORAGE.NONCE_IDTOKEN)); - if (this.config && this.config.cacheLocation && this.config.cacheLocation === 'localStorage') { + this._user = null; + } else { + this._saveItem(this.CONSTANTS.STORAGE.IDTOKEN, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); // Save idtoken as access token for app itself + + + resource = this.config.loginResource ? this.config.loginResource : this.config.clientId; + + if (!this._hasResource(resource)) { + keys = this._getItem(this.CONSTANTS.STORAGE.TOKEN_KEYS) || ''; + + this._saveItem(this.CONSTANTS.STORAGE.TOKEN_KEYS, keys + resource + this.CONSTANTS.RESOURCE_DELIMETER); + } - if (!this._supportsLocalStorage()) { - this.info('Local storage is not supported'); - return null; + this._saveItem(this.CONSTANTS.STORAGE.ACCESS_TOKEN_KEY + resource, requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); + + this._saveItem(this.CONSTANTS.STORAGE.EXPIRATION_KEY + resource, this._user.profile.exp); } + } else { + requestInfo.parameters['error'] = 'invalid id_token'; + requestInfo.parameters['error_description'] = 'Invalid id_token. id_token: ' + requestInfo.parameters[this.CONSTANTS.ID_TOKEN]; - return localStorage.getItem(key); - } + this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'invalid id_token'); - // Default as session storage - if (!this._supportsSessionStorage()) { - this.info('Session storage is not supported'); - return null; + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid id_token. id_token: ' + requestInfo.parameters[this.CONSTANTS.ID_TOKEN]); + } } + } else { + requestInfo.parameters['error'] = 'Invalid_state'; + requestInfo.parameters['error_description'] = 'Invalid_state. state: ' + requestInfo.stateResponse; - return sessionStorage.getItem(key); - }; + this._saveItem(this.CONSTANTS.STORAGE.ERROR, 'Invalid_state'); - /** - * Returns true if browser supports localStorage, false otherwise. - * @ignore - */ - _AuthenticationContext.prototype._supportsLocalStorage = function () { - try { - if (!window.localStorage) return false; // Test availability - window.localStorage.setItem('storageTest', 'A'); // Try write - if (window.localStorage.getItem('storageTest') != 'A') return false; // Test read/write - window.localStorage.removeItem('storageTest'); // Try delete - if (window.localStorage.getItem('storageTest')) return false; // Test delete - return true; // Success - } catch (e) { - return false; - } - }; + this._saveItem(this.CONSTANTS.STORAGE.ERROR_DESCRIPTION, 'Invalid_state. state: ' + requestInfo.stateResponse); + } + } - /** - * Returns true if browser supports sessionStorage, false otherwise. - * @ignore - */ - _AuthenticationContext.prototype._supportsSessionStorage = function () { - try { - if (!window.sessionStorage) return false; // Test availability - window.sessionStorage.setItem('storageTest', 'A'); // Try write - if (window.sessionStorage.getItem('storageTest') != 'A') return false; // Test read/write - window.sessionStorage.removeItem('storageTest'); // Try delete - if (window.sessionStorage.getItem('storageTest')) return false; // Test delete - return true; // Success - } catch (e) { - return false; + this._saveItem(this.CONSTANTS.STORAGE.RENEW_STATUS + resource, this.CONSTANTS.TOKEN_RENEW_STATUS_COMPLETED); + }; + /** + * Gets resource for given endpoint if mapping is provided with config. + * @param {string} endpoint - The URI for which the resource Id is requested. + * @returns {string} resource for this API endpoint. + */ + + + _AuthenticationContext.prototype.getResourceForEndpoint = function (endpoint) { + // if user specified list of anonymous endpoints, no need to send token to these endpoints, return null. + if (this.config && this.config.anonymousEndpoints) { + for (var i = 0; i < this.config.anonymousEndpoints.length; i++) { + if (endpoint.indexOf(this.config.anonymousEndpoints[i]) > -1) { + return null; } - }; + } + } - /** - * Returns a cloned copy of the passed object. - * @ignore - */ - _AuthenticationContext.prototype._cloneConfig = function (obj) { - if (null === obj || 'object' !== (typeof obj === 'undefined' ? 'undefined' : _typeof(obj))) { - return obj; + if (this.config && this.config.endpoints) { + for (var configEndpoint in this.config.endpoints) { + // configEndpoint is like /api/Todo requested endpoint can be /api/Todo/1 + if (endpoint.indexOf(configEndpoint) > -1) { + return this.config.endpoints[configEndpoint]; + } + } + } // default resource will be clientid if nothing specified + // App will use idtoken for calls to itself + // check if it's staring from http or https, needs to match with app host + + + if (endpoint.indexOf('http://') > -1 || endpoint.indexOf('https://') > -1) { + if (this._getHostFromUri(endpoint) === this._getHostFromUri(this.config.redirectUri)) { + return this.config.loginResource; + } + } else { + // in angular level, the url for $http interceptor call could be relative url, + // if it's relative call, we'll treat it as app backend call. + return this.config.loginResource; + } // if not the app's own backend or not a domain listed in the endpoints structure + + + return null; + }; + /** + * Strips the protocol part of the URL and returns it. + * @ignore + */ + + + _AuthenticationContext.prototype._getHostFromUri = function (uri) { + // remove http:// or https:// from uri + var extractedUri = String(uri).replace(/^(https?:)\/\//, ''); + extractedUri = extractedUri.split('/')[0]; + return extractedUri; + }; + /** + * This method must be called for processing the response received from AAD. It extracts the hash, processes the token or error, saves it in the cache and calls the registered callbacks with the result. + * @param {string} [hash=window.location.hash] - Hash fragment of Url. + */ + + + _AuthenticationContext.prototype.handleWindowCallback = function (hash) { + // This is for regular javascript usage for redirect handling + // need to make sure this is for callback + if (hash == null) { + hash = window.location.hash; + } + + if (this.isCallback(hash)) { + var self = null; + var isPopup = false; + + if (this._openedWindows.length > 0 && this._openedWindows[this._openedWindows.length - 1].opener && this._openedWindows[this._openedWindows.length - 1].opener._adalInstance) { + self = this._openedWindows[this._openedWindows.length - 1].opener._adalInstance; + isPopup = true; + } else if (window.parent && window.parent._adalInstance) { + self = window.parent._adalInstance; + } + + var requestInfo = self.getRequestInfo(hash); + var token, + tokenReceivedCallback, + tokenType = null; + + if (isPopup || window.parent !== window) { + tokenReceivedCallback = self._callBackMappedToRenewStates[requestInfo.stateResponse]; + } else { + tokenReceivedCallback = self.callback; + } + + self.info("Returned from redirect url"); + self.saveTokenFromHash(requestInfo); + + if (requestInfo.requestType === this.REQUEST_TYPE.RENEW_TOKEN && window.parent) { + if (window.parent !== window) { + self.verbose("Window is in iframe, acquiring token silently"); + } else { + self.verbose("acquiring token interactive in progress"); } - var copy = {}; - for (var attr in obj) { - if (obj.hasOwnProperty(attr)) { - copy[attr] = obj[attr]; - } + token = requestInfo.parameters[self.CONSTANTS.ACCESS_TOKEN] || requestInfo.parameters[self.CONSTANTS.ID_TOKEN]; + tokenType = self.CONSTANTS.ACCESS_TOKEN; + } else if (requestInfo.requestType === this.REQUEST_TYPE.LOGIN) { + token = requestInfo.parameters[self.CONSTANTS.ID_TOKEN]; + tokenType = self.CONSTANTS.ID_TOKEN; + } + + var errorDesc = requestInfo.parameters[self.CONSTANTS.ERROR_DESCRIPTION]; + var error = requestInfo.parameters[self.CONSTANTS.ERROR]; + + try { + if (tokenReceivedCallback) { + tokenReceivedCallback(errorDesc, token, error, tokenType); } - return copy; - }; + } catch (err) { + self.error("Error occurred in user defined callback function: " + err); + } - /** - * Adds the library version and returns it. - * @ignore - */ - _AuthenticationContext.prototype._addLibMetadata = function () { - // x-client-SKU - // x-client-Ver - return '&x-client-SKU=Js&x-client-Ver=' + this._libVersion(); + if (window.parent === window && !isPopup) { + if (self.config.navigateToLoginRequestUrl) { + window.location.href = self._getItem(self.CONSTANTS.STORAGE.LOGIN_REQUEST); + } else window.location.hash = ''; + } + } + }; + /** + * Constructs the authorization endpoint URL and returns it. + * @ignore + */ + + + _AuthenticationContext.prototype._getNavigateUrl = function (responseType, resource) { + var tenant = 'common'; + + if (this.config.tenant) { + tenant = this.config.tenant; + } + + var urlNavigate = this.instance + tenant + '/oauth2/authorize' + this._serialize(responseType, this.config, resource) + this._addLibMetadata(); + + this.info('Navigate url:' + urlNavigate); + return urlNavigate; + }; + /** + * Returns the decoded id_token. + * @ignore + */ + + + _AuthenticationContext.prototype._extractIdToken = function (encodedIdToken) { + // id token will be decoded to get the username + var decodedToken = this._decodeJwt(encodedIdToken); + + if (!decodedToken) { + return null; + } + + try { + var base64IdToken = decodedToken.JWSPayload; + + var base64Decoded = this._base64DecodeStringUrlSafe(base64IdToken); + + if (!base64Decoded) { + this.info('The returned id_token could not be base64 url safe decoded.'); + return null; + } // ECMA script has JSON built-in support + + + return JSON.parse(base64Decoded); + } catch (err) { + this.error('The returned id_token could not be decoded', err); + } + + return null; + }; + /** + * Decodes a string of data which has been encoded using base-64 encoding. + * @ignore + */ + + + _AuthenticationContext.prototype._base64DecodeStringUrlSafe = function (base64IdToken) { + // html5 should support atob function for decoding + base64IdToken = base64IdToken.replace(/-/g, '+').replace(/_/g, '/'); + + if (window.atob) { + return decodeURIComponent(escape(window.atob(base64IdToken))); // jshint ignore:line + } else { + return decodeURIComponent(escape(this._decode(base64IdToken))); + } + }; //Take https://cdnjs.cloudflare.com/ajax/libs/Base64/0.3.0/base64.js and https://en.wikipedia.org/wiki/Base64 as reference. + + + _AuthenticationContext.prototype._decode = function (base64IdToken) { + var codes = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/='; + base64IdToken = String(base64IdToken).replace(/=+$/, ''); + var length = base64IdToken.length; + + if (length % 4 === 1) { + throw new Error('The token to be decoded is not correctly encoded.'); + } + + var h1, + h2, + h3, + h4, + bits, + c1, + c2, + c3, + decoded = ''; + + for (var i = 0; i < length; i += 4) { + //Every 4 base64 encoded character will be converted to 3 byte string, which is 24 bits + // then 6 bits per base64 encoded character + h1 = codes.indexOf(base64IdToken.charAt(i)); + h2 = codes.indexOf(base64IdToken.charAt(i + 1)); + h3 = codes.indexOf(base64IdToken.charAt(i + 2)); + h4 = codes.indexOf(base64IdToken.charAt(i + 3)); // For padding, if last two are '=' + + if (i + 2 === length - 1) { + bits = h1 << 18 | h2 << 12 | h3 << 6; + c1 = bits >> 16 & 255; + c2 = bits >> 8 & 255; + decoded += String.fromCharCode(c1, c2); + break; + } // if last one is '=' + else if (i + 1 === length - 1) { + bits = h1 << 18 | h2 << 12; + c1 = bits >> 16 & 255; + decoded += String.fromCharCode(c1); + break; + } + + bits = h1 << 18 | h2 << 12 | h3 << 6 | h4; // then convert to 3 byte chars + + c1 = bits >> 16 & 255; + c2 = bits >> 8 & 255; + c3 = bits & 255; + decoded += String.fromCharCode(c1, c2, c3); + } + + return decoded; + }; + /** + * Decodes an id token into an object with header, payload and signature fields. + * @ignore + */ + // Adal.node js crack function + + + _AuthenticationContext.prototype._decodeJwt = function (jwtToken) { + if (this._isEmpty(jwtToken)) { + return null; + } + + ; + var idTokenPartsRegex = /^([^\.\s]*)\.([^\.\s]+)\.([^\.\s]*)$/; + var matches = idTokenPartsRegex.exec(jwtToken); + + if (!matches || matches.length < 4) { + this.warn('The returned id_token is not parseable.'); + return null; + } + + var crackedToken = { + header: matches[1], + JWSPayload: matches[2], + JWSSig: matches[3] }; + return crackedToken; + }; + /** + * Converts string to represent binary data in ASCII string format by translating it into a radix-64 representation and returns it + * @ignore + */ - /** - * Checks the Logging Level, constructs the Log message and logs it. Users need to implement/override this method to turn on Logging. - * @param {number} level - Level can be set 0,1,2 and 3 which turns on 'error', 'warning', 'info' or 'verbose' level logging respectively. - * @param {string} message - Message to log. - * @param {string} error - Error to log. - */ - _AuthenticationContext.prototype.log = function (level, message, error, containsPii) { - if (level <= Logging.level) { + _AuthenticationContext.prototype._convertUrlSafeToRegularBase64EncodedString = function (str) { + return str.replace('-', '+').replace('_', '/'); + }; + /** + * Serializes the parameters for the authorization endpoint URL and returns the serialized uri string. + * @ignore + */ - if (!Logging.piiLoggingEnabled && containsPii) return; - var timestamp = new Date().toUTCString(); - var formattedMessage = ''; + _AuthenticationContext.prototype._serialize = function (responseType, obj, resource) { + var str = []; - if (this.config.correlationId) formattedMessage = timestamp + ':' + this.config.correlationId + '-' + this._libVersion() + '-' + this.CONSTANTS.LEVEL_STRING_MAP[level] + ' ' + message;else formattedMessage = timestamp + ':' + this._libVersion() + '-' + this.CONSTANTS.LEVEL_STRING_MAP[level] + ' ' + message; + if (obj !== null) { + str.push('?response_type=' + responseType); + str.push('client_id=' + encodeURIComponent(obj.clientId)); - if (error) { - formattedMessage += '\nstack:\n' + error.stack; - } + if (resource) { + str.push('resource=' + encodeURIComponent(resource)); + } - Logging.log(formattedMessage); + str.push('redirect_uri=' + encodeURIComponent(obj.redirectUri)); + str.push('state=' + encodeURIComponent(obj.state)); + + if (obj.hasOwnProperty('slice')) { + str.push('slice=' + encodeURIComponent(obj.slice)); + } + + if (obj.hasOwnProperty('extraQueryParameter')) { + str.push(obj.extraQueryParameter); + } + + var correlationId = obj.correlationId ? obj.correlationId : this._guid(); + str.push('client-request-id=' + encodeURIComponent(correlationId)); + } + + return str.join('&'); + }; + /** + * Parses the query string parameters into a key-value pair object. + * @ignore + */ + + + _AuthenticationContext.prototype._deserialize = function (query) { + var match, + pl = /\+/g, + // Regex for replacing addition symbol with a space + search = /([^&=]+)=([^&]*)/g, + decode = function decode(s) { + return decodeURIComponent(s.replace(pl, ' ')); + }, + obj = {}; + + match = search.exec(query); + + while (match) { + obj[decode(match[1])] = decode(match[2]); + match = search.exec(query); + } + + return obj; + }; + /** + * Converts decimal value to hex equivalent + * @ignore + */ + + + _AuthenticationContext.prototype._decimalToHex = function (number) { + var hex = number.toString(16); + + while (hex.length < 2) { + hex = '0' + hex; + } + + return hex; + }; + /** + * Generates RFC4122 version 4 guid (128 bits) + * @ignore + */ + + /* jshint ignore:start */ + + + _AuthenticationContext.prototype._guid = function () { + // RFC4122: The version 4 UUID is meant for generating UUIDs from truly-random or + // pseudo-random numbers. + // The algorithm is as follows: + // Set the two most significant bits (bits 6 and 7) of the + // clock_seq_hi_and_reserved to zero and one, respectively. + // Set the four most significant bits (bits 12 through 15) of the + // time_hi_and_version field to the 4-bit version number from + // Section 4.1.3. Version4 + // Set all the other bits to randomly (or pseudo-randomly) chosen + // values. + // UUID = time-low "-" time-mid "-"time-high-and-version "-"clock-seq-reserved and low(2hexOctet)"-" node + // time-low = 4hexOctet + // time-mid = 2hexOctet + // time-high-and-version = 2hexOctet + // clock-seq-and-reserved = hexOctet: + // clock-seq-low = hexOctet + // node = 6hexOctet + // Format: xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx + // y could be 1000, 1001, 1010, 1011 since most significant two bits needs to be 10 + // y values are 8, 9, A, B + var cryptoObj = window.crypto || window.msCrypto; // for IE 11 + + if (cryptoObj && cryptoObj.getRandomValues) { + var buffer = new Uint8Array(16); + cryptoObj.getRandomValues(buffer); //buffer[6] and buffer[7] represents the time_hi_and_version field. We will set the four most significant bits (4 through 7) of buffer[6] to represent decimal number 4 (UUID version number). + + buffer[6] |= 0x40; //buffer[6] | 01000000 will set the 6 bit to 1. + + buffer[6] &= 0x4f; //buffer[6] & 01001111 will set the 4, 5, and 7 bit to 0 such that bits 4-7 == 0100 = "4". + //buffer[8] represents the clock_seq_hi_and_reserved field. We will set the two most significant bits (6 and 7) of the clock_seq_hi_and_reserved to zero and one, respectively. + + buffer[8] |= 0x80; //buffer[8] | 10000000 will set the 7 bit to 1. + + buffer[8] &= 0xbf; //buffer[8] & 10111111 will set the 6 bit to 0. + + return this._decimalToHex(buffer[0]) + this._decimalToHex(buffer[1]) + this._decimalToHex(buffer[2]) + this._decimalToHex(buffer[3]) + '-' + this._decimalToHex(buffer[4]) + this._decimalToHex(buffer[5]) + '-' + this._decimalToHex(buffer[6]) + this._decimalToHex(buffer[7]) + '-' + this._decimalToHex(buffer[8]) + this._decimalToHex(buffer[9]) + '-' + this._decimalToHex(buffer[10]) + this._decimalToHex(buffer[11]) + this._decimalToHex(buffer[12]) + this._decimalToHex(buffer[13]) + this._decimalToHex(buffer[14]) + this._decimalToHex(buffer[15]); + } else { + var guidHolder = 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'; + var hex = '0123456789abcdef'; + var r = 0; + var guidResponse = ""; + + for (var i = 0; i < 36; i++) { + if (guidHolder[i] !== '-' && guidHolder[i] !== '4') { + // each x and y needs to be random + r = Math.random() * 16 | 0; + } + + if (guidHolder[i] === 'x') { + guidResponse += hex[r]; + } else if (guidHolder[i] === 'y') { + // clock-seq-and-reserved first hex is filtered and remaining hex values are random + r &= 0x3; // bit and with 0011 to set pos 2 to zero ?0?? + + r |= 0x8; // set pos 3 to 1 as 1??? + + guidResponse += hex[r]; + } else { + guidResponse += guidHolder[i]; } - }; + } - /** - * Logs messages when Logging Level is set to 0. - * @param {string} message - Message to log. - * @param {string} error - Error to log. - */ - _AuthenticationContext.prototype.error = function (message, error) { - this.log(this.CONSTANTS.LOGGING_LEVEL.ERROR, message, error); - }; + return guidResponse; + } + }; + /* jshint ignore:end */ + + /** + * Calculates the expires in value in milliseconds for the acquired token + * @ignore + */ + + + _AuthenticationContext.prototype._expiresIn = function (expires) { + // if AAD did not send "expires_in" property, use default expiration of 3599 seconds, for some reason AAD sends 3599 as "expires_in" value instead of 3600 + if (!expires) expires = 3599; + return this._now() + parseInt(expires, 10); + }; + /** + * Return the number of milliseconds since 1970/01/01 + * @ignore + */ + + + _AuthenticationContext.prototype._now = function () { + return Math.round(new Date().getTime() / 1000.0); + }; + /** + * Adds the hidden iframe for silent token renewal + * @ignore + */ + + + _AuthenticationContext.prototype._addAdalFrame = function (iframeId) { + if (typeof iframeId === 'undefined') { + return; + } - /** - * Logs messages when Logging Level is set to 1. - * @param {string} message - Message to log. - */ - _AuthenticationContext.prototype.warn = function (message) { - this.log(this.CONSTANTS.LOGGING_LEVEL.WARN, message, null); - }; + this.info('Add adal frame to document:' + iframeId); + var adalFrame = document.getElementById(iframeId); + + if (!adalFrame) { + if (document.createElement && document.documentElement && (window.opera || window.navigator.userAgent.indexOf('MSIE 5.0') === -1)) { + var ifr = document.createElement('iframe'); + ifr.setAttribute('id', iframeId); + ifr.setAttribute('aria-hidden', 'true'); + ifr.style.visibility = 'hidden'; + ifr.style.position = 'absolute'; + ifr.style.width = ifr.style.height = ifr.borderWidth = '0px'; + adalFrame = document.getElementsByTagName('body')[0].appendChild(ifr); + } else if (document.body && document.body.insertAdjacentHTML) { + document.body.insertAdjacentHTML('beforeEnd', ''); + } + + if (window.frames && window.frames[iframeId]) { + adalFrame = window.frames[iframeId]; + } + } - /** - * Logs messages when Logging Level is set to 2. - * @param {string} message - Message to log. - */ - _AuthenticationContext.prototype.info = function (message) { - this.log(this.CONSTANTS.LOGGING_LEVEL.INFO, message, null); - }; + return adalFrame; + }; + /** + * Saves the key-value pair in the cache + * @ignore + */ - /** - * Logs messages when Logging Level is set to 3. - * @param {string} message - Message to log. - */ - _AuthenticationContext.prototype.verbose = function (message) { - this.log(this.CONSTANTS.LOGGING_LEVEL.VERBOSE, message, null); - }; - /** - * Logs Pii messages when Logging Level is set to 0 and window.piiLoggingEnabled is set to true. - * @param {string} message - Message to log. - * @param {string} error - Error to log. - */ - _AuthenticationContext.prototype.errorPii = function (message, error) { - this.log(this.CONSTANTS.LOGGING_LEVEL.ERROR, message, error, true); - }; + _AuthenticationContext.prototype._saveItem = function (key, obj, preserve) { + if (this.config && this.config.cacheLocation && this.config.cacheLocation === 'localStorage') { + if (!this._supportsLocalStorage()) { + this.info('Local storage is not supported'); + return false; + } - /** - * Logs Pii messages when Logging Level is set to 1 and window.piiLoggingEnabled is set to true. - * @param {string} message - Message to log. - */ - _AuthenticationContext.prototype.warnPii = function (message) { - this.log(this.CONSTANTS.LOGGING_LEVEL.WARN, message, null, true); - }; + if (preserve) { + var value = this._getItem(key) || ''; + localStorage.setItem(key, value + obj + this.CONSTANTS.CACHE_DELIMETER); + } else { + localStorage.setItem(key, obj); + } - /** - * Logs messages when Logging Level is set to 2 and window.piiLoggingEnabled is set to true. - * @param {string} message - Message to log. - */ - _AuthenticationContext.prototype.infoPii = function (message) { - this.log(this.CONSTANTS.LOGGING_LEVEL.INFO, message, null, true); - }; + return true; + } // Default as session storage - /** - * Logs messages when Logging Level is set to 3 and window.piiLoggingEnabled is set to true. - * @param {string} message - Message to log. - */ - _AuthenticationContext.prototype.verbosePii = function (message) { - this.log(this.CONSTANTS.LOGGING_LEVEL.VERBOSE, message, null, true); - }; - /** - * Returns the library version. - * @ignore - */ - _AuthenticationContext.prototype._libVersion = function () { - return '1.0.17'; - }; - /** - * Returns a reference of Authentication Context as a result of a require call. - * @ignore - */ - if (typeof module !== 'undefined' && module.exports) { - module.exports = _AuthenticationContext; - module.exports.inject = function (conf) { - return new _AuthenticationContext(conf); - }; + if (!this._supportsSessionStorage()) { + this.info('Session storage is not supported'); + return false; + } + + sessionStorage.setItem(key, obj); + return true; + }; + /** + * Searches the value for the given key in the cache + * @ignore + */ + + + _AuthenticationContext.prototype._getItem = function (key) { + if (this.config && this.config.cacheLocation && this.config.cacheLocation === 'localStorage') { + if (!this._supportsLocalStorage()) { + this.info('Local storage is not supported'); + return null; + } + + return localStorage.getItem(key); + } // Default as session storage + + + if (!this._supportsSessionStorage()) { + this.info('Session storage is not supported'); + return null; + } + + return sessionStorage.getItem(key); + }; + /** + * Returns true if browser supports localStorage, false otherwise. + * @ignore + */ + + + _AuthenticationContext.prototype._supportsLocalStorage = function () { + try { + if (!window.localStorage) return false; // Test availability + + window.localStorage.setItem('storageTest', 'A'); // Try write + + if (window.localStorage.getItem('storageTest') != 'A') return false; // Test read/write + + window.localStorage.removeItem('storageTest'); // Try delete + + if (window.localStorage.getItem('storageTest')) return false; // Test delete + + return true; // Success + } catch (e) { + return false; + } + }; + /** + * Returns true if browser supports sessionStorage, false otherwise. + * @ignore + */ + + + _AuthenticationContext.prototype._supportsSessionStorage = function () { + try { + if (!window.sessionStorage) return false; // Test availability + + window.sessionStorage.setItem('storageTest', 'A'); // Try write + + if (window.sessionStorage.getItem('storageTest') != 'A') return false; // Test read/write + + window.sessionStorage.removeItem('storageTest'); // Try delete + + if (window.sessionStorage.getItem('storageTest')) return false; // Test delete + + return true; // Success + } catch (e) { + return false; + } + }; + /** + * Returns a cloned copy of the passed object. + * @ignore + */ + + + _AuthenticationContext.prototype._cloneConfig = function (obj) { + if (null === obj || 'object' !== _typeof(obj)) { + return obj; } - return _AuthenticationContext; + var copy = {}; + + for (var attr in obj) { + if (obj.hasOwnProperty(attr)) { + copy[attr] = obj[attr]; + } + } + + return copy; + }; + /** + * Adds the library version and returns it. + * @ignore + */ + + + _AuthenticationContext.prototype._addLibMetadata = function () { + // x-client-SKU + // x-client-Ver + return '&x-client-SKU=Js&x-client-Ver=' + this._libVersion(); + }; + /** + * Checks the Logging Level, constructs the Log message and logs it. Users need to implement/override this method to turn on Logging. + * @param {number} level - Level can be set 0,1,2 and 3 which turns on 'error', 'warning', 'info' or 'verbose' level logging respectively. + * @param {string} message - Message to log. + * @param {string} error - Error to log. + */ + + + _AuthenticationContext.prototype.log = function (level, message, error, containsPii) { + if (level <= Logging.level) { + if (!Logging.piiLoggingEnabled && containsPii) return; + var timestamp = new Date().toUTCString(); + var formattedMessage = ''; + if (this.config.correlationId) formattedMessage = timestamp + ':' + this.config.correlationId + '-' + this._libVersion() + '-' + this.CONSTANTS.LEVEL_STRING_MAP[level] + ' ' + message;else formattedMessage = timestamp + ':' + this._libVersion() + '-' + this.CONSTANTS.LEVEL_STRING_MAP[level] + ' ' + message; + + if (error) { + formattedMessage += '\nstack:\n' + error.stack; + } + + Logging.log(formattedMessage); + } + }; + /** + * Logs messages when Logging Level is set to 0. + * @param {string} message - Message to log. + * @param {string} error - Error to log. + */ + + + _AuthenticationContext.prototype.error = function (message, error) { + this.log(this.CONSTANTS.LOGGING_LEVEL.ERROR, message, error); + }; + /** + * Logs messages when Logging Level is set to 1. + * @param {string} message - Message to log. + */ + + + _AuthenticationContext.prototype.warn = function (message) { + this.log(this.CONSTANTS.LOGGING_LEVEL.WARN, message, null); + }; + /** + * Logs messages when Logging Level is set to 2. + * @param {string} message - Message to log. + */ + + + _AuthenticationContext.prototype.info = function (message) { + this.log(this.CONSTANTS.LOGGING_LEVEL.INFO, message, null); + }; + /** + * Logs messages when Logging Level is set to 3. + * @param {string} message - Message to log. + */ + + + _AuthenticationContext.prototype.verbose = function (message) { + this.log(this.CONSTANTS.LOGGING_LEVEL.VERBOSE, message, null); + }; + /** + * Logs Pii messages when Logging Level is set to 0 and window.piiLoggingEnabled is set to true. + * @param {string} message - Message to log. + * @param {string} error - Error to log. + */ + + + _AuthenticationContext.prototype.errorPii = function (message, error) { + this.log(this.CONSTANTS.LOGGING_LEVEL.ERROR, message, error, true); + }; + /** + * Logs Pii messages when Logging Level is set to 1 and window.piiLoggingEnabled is set to true. + * @param {string} message - Message to log. + */ + + + _AuthenticationContext.prototype.warnPii = function (message) { + this.log(this.CONSTANTS.LOGGING_LEVEL.WARN, message, null, true); + }; + /** + * Logs messages when Logging Level is set to 2 and window.piiLoggingEnabled is set to true. + * @param {string} message - Message to log. + */ + + + _AuthenticationContext.prototype.infoPii = function (message) { + this.log(this.CONSTANTS.LOGGING_LEVEL.INFO, message, null, true); + }; + /** + * Logs messages when Logging Level is set to 3 and window.piiLoggingEnabled is set to true. + * @param {string} message - Message to log. + */ + + + _AuthenticationContext.prototype.verbosePii = function (message) { + this.log(this.CONSTANTS.LOGGING_LEVEL.VERBOSE, message, null, true); + }; + /** + * Returns the library version. + * @ignore + */ + + + _AuthenticationContext.prototype._libVersion = function () { + return '1.0.17'; + }; + /** + * Returns a reference of Authentication Context as a result of a require call. + * @ignore + */ + + + if (typeof module !== 'undefined' && module.exports) { + module.exports = _AuthenticationContext; + + module.exports.inject = function (conf) { + return new _AuthenticationContext(conf); + }; + } + + return _AuthenticationContext; }(); \ No newline at end of file diff --git a/lib/react-adal.js b/lib/react-adal.js index 401d9f0..3a8bd51 100644 --- a/lib/react-adal.js +++ b/lib/react-adal.js @@ -1,43 +1,49 @@ -'use strict'; +"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); -exports.withAdalLogin = exports.AuthenticationContext = undefined; - -var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }(); - exports.adalGetToken = adalGetToken; exports.runWithAdal = runWithAdal; exports.adalFetch = adalFetch; +exports.withAdalLogin = exports.AuthenticationContext = void 0; -var _react = require('react'); +var _react = _interopRequireDefault(require("react")); -var _react2 = _interopRequireDefault(_react); +var _adal = _interopRequireDefault(require("./adal")); -var _adal = require('./adal'); +function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } -var _adal2 = _interopRequireDefault(_adal); - -function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; } +function _typeof(obj) { if (typeof Symbol === "function" && typeof Symbol.iterator === "symbol") { _typeof = function _typeof(obj) { return typeof obj; }; } else { _typeof = function _typeof(obj) { return obj && typeof Symbol === "function" && obj.constructor === Symbol && obj !== Symbol.prototype ? "symbol" : typeof obj; }; } return _typeof(obj); } function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } } -function _possibleConstructorReturn(self, call) { if (!self) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return call && (typeof call === "object" || typeof call === "function") ? call : self; } +function _defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } + +function _createClass(Constructor, protoProps, staticProps) { if (protoProps) _defineProperties(Constructor.prototype, protoProps); if (staticProps) _defineProperties(Constructor, staticProps); return Constructor; } + +function _possibleConstructorReturn(self, call) { if (call && (_typeof(call) === "object" || typeof call === "function")) { return call; } return _assertThisInitialized(self); } + +function _getPrototypeOf(o) { _getPrototypeOf = Object.setPrototypeOf ? Object.getPrototypeOf : function _getPrototypeOf(o) { return o.__proto__ || Object.getPrototypeOf(o); }; return _getPrototypeOf(o); } + +function _assertThisInitialized(self) { if (self === void 0) { throw new ReferenceError("this hasn't been initialised - super() hasn't been called"); } return self; } -function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function, not " + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } // eslint-disable-next-line +function _inherits(subClass, superClass) { if (typeof superClass !== "function" && superClass !== null) { throw new TypeError("Super expression must either be null or a function"); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, writable: true, configurable: true } }); if (superClass) _setPrototypeOf(subClass, superClass); } +function _setPrototypeOf(o, p) { _setPrototypeOf = Object.setPrototypeOf || function _setPrototypeOf(o, p) { o.__proto__ = p; return o; }; return _setPrototypeOf(o, p); } -var AuthenticationContext = exports.AuthenticationContext = _adal2.default; +function _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; } +var AuthenticationContext = _adal["default"]; +exports.AuthenticationContext = AuthenticationContext; var redirectMessages = ['AADSTS16002', // old sid - https://github.com/salvoravida/react-adal/issues/46 'AADSTS50076', // MFA support - https://github.com/salvoravida/react-adal/pull/45 'AADSTS50079']; function shouldAcquireNewToken(message) { - return redirectMessages.reduce(function (a, v) { - return a || message.includes(v); - }, false); + return redirectMessages.some(function (v) { + return message.indexOf(v) !== -1; + }); } function adalGetToken(authContext, resourceGuiId, callback) { @@ -53,7 +59,11 @@ function adalGetToken(authContext, resourceGuiId, callback) { } else { authContext.acquireTokenRedirect(resourceGuiId); } - } else reject({ message: message, msg: msg }); // eslint-disable-line + } else reject({ + message: message, + msg: msg + }); // eslint-disable-line + }); }); } @@ -63,11 +73,11 @@ function runWithAdal(authContext, app, doNotLogin) { if (typeof window === 'undefined') { if (doNotLogin) app(); return; - } - //it must run in iframe too for refreshToken (parsing hash and get token) - authContext.handleWindowCallback(); + } //it must run in iframe too for refreshToken (parsing hash and get token) + + + authContext.handleWindowCallback(); //prevent iframe double app !!! - //prevent iframe double app !!! if (window === window.parent) { if (!authContext.isCallback(window.location.hash)) { if (!authContext.getCachedToken(authContext.config.clientId) || !authContext.getCachedUser()) { @@ -87,74 +97,89 @@ function adalFetch(authContext, resourceGuiId, fetch, url, options) { return adalGetToken(authContext, resourceGuiId).then(function (token) { var o = options || {}; if (!o.headers) o.headers = {}; - o.headers.Authorization = 'Bearer ' + token; + o.headers.Authorization = "Bearer ".concat(token); return fetch(url, o); }); -} +} // eslint-disable-next-line -// eslint-disable-next-line -var withAdalLogin = exports.withAdalLogin = function withAdalLogin(authContext, resourceId) { + +var withAdalLogin = function withAdalLogin(authContext, resourceId) { // eslint-disable-next-line return function (WrappedComponent, renderLoading, renderError) { - return function (_React$Component) { - _inherits(_class2, _React$Component); + var _temp; + + return _temp = + /*#__PURE__*/ + function (_React$Component) { + _inherits(_temp, _React$Component); - function _class2(props) { - _classCallCheck(this, _class2); + function _temp(props) { + var _this; - var _this = _possibleConstructorReturn(this, (_class2.__proto__ || Object.getPrototypeOf(_class2)).call(this, props)); + _classCallCheck(this, _temp); - _this.componentDidMount = function () { + _this = _possibleConstructorReturn(this, _getPrototypeOf(_temp).call(this, props)); + + _defineProperty(_assertThisInitialized(_this), "componentDidMount", function () { _this.mounted = true; + if (_this.todoSetState) { _this.setState(_this.todoSetState); } - }; + }); - _this.componentWillUnmount = function () { + _defineProperty(_assertThisInitialized(_this), "componentWillUnmount", function () { _this.mounted = false; - }; + }); _this.state = { logged: false, error: null }; - adalGetToken(authContext, resourceId).then(function () { if (_this.mounted) { - _this.setState({ logged: true }); + _this.setState({ + logged: true + }); } else { - _this.todoSetState = { logged: true }; + _this.todoSetState = { + logged: true + }; } - }).catch(function (error) { + })["catch"](function (error) { var msg = error.msg; - console.log(error); // eslint-disable-line + if (msg === 'login required') { authContext.login(); } else if (_this.mounted) { - _this.setState({ error: error }); + _this.setState({ + error: error + }); } else { - _this.todoSetState = { error: error }; + _this.todoSetState = { + error: error + }; } }); return _this; } - _createClass(_class2, [{ - key: 'render', + _createClass(_temp, [{ + key: "render", value: function render() { - var _state = this.state, - logged = _state.logged, - error = _state.error; - - if (logged) return _react2.default.createElement(WrappedComponent, this.props); + var _this$state = this.state, + logged = _this$state.logged, + error = _this$state.error; + if (logged) return _react["default"].createElement(WrappedComponent, this.props); if (error) return typeof renderError === 'function' ? renderError(error) : null; return typeof renderLoading === 'function' ? renderLoading() : null; } }]); - return _class2; - }(_react2.default.Component); + return _temp; + }(_react["default"].Component), _temp; }; -}; \ No newline at end of file +}; + +exports.withAdalLogin = withAdalLogin; \ No newline at end of file diff --git a/package-lock.json b/package-lock.json new file mode 100644 index 0000000..7d00479 --- /dev/null +++ b/package-lock.json @@ -0,0 +1,4648 @@ +{ + "name": "react-adal", + "version": "0.4.23", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "@babel/cli": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/cli/-/cli-7.4.4.tgz", + "integrity": "sha512-XGr5YjQSjgTa6OzQZY57FAJsdeVSAKR/u/KA5exWIz66IKtv/zXtHy+fIZcMry/EgYegwuHE7vzGnrFhjdIAsQ==", + "dev": true, + "requires": { + "chokidar": "^2.0.4", + "commander": "^2.8.1", + "convert-source-map": "^1.1.0", + "fs-readdir-recursive": "^1.1.0", + "glob": "^7.0.0", + "lodash": "^4.17.11", + "mkdirp": "^0.5.1", + "output-file-sync": "^2.0.0", + "slash": "^2.0.0", + "source-map": "^0.5.0" + } + }, + "@babel/code-frame": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz", + "integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==", + "dev": true, + "requires": { + "@babel/highlight": "^7.0.0" + } + }, + "@babel/core": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.4.5.tgz", + "integrity": "sha512-OvjIh6aqXtlsA8ujtGKfC7LYWksYSX8yQcM8Ay3LuvVeQ63lcOKgoZWVqcpFwkd29aYU9rVx7jxhfhiEDV9MZA==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helpers": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.5", + "@babel/types": "^7.4.4", + "convert-source-map": "^1.1.0", + "debug": "^4.1.0", + "json5": "^2.1.0", + "lodash": "^4.17.11", + "resolve": "^1.3.2", + "semver": "^5.4.1", + "source-map": "^0.5.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.4.4.tgz", + "integrity": "sha512-53UOLK6TVNqKxf7RUh8NE851EHRxOOeVXKbK2bivdb+iziMyk03Sr4eaE9OELCbyZAAafAKPDwF2TPUES5QbxQ==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4", + "jsesc": "^2.5.1", + "lodash": "^4.17.11", + "source-map": "^0.5.0", + "trim-right": "^1.0.1" + } + }, + "@babel/helper-annotate-as-pure": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz", + "integrity": "sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-binary-assignment-operator-visitor": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz", + "integrity": "sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w==", + "dev": true, + "requires": { + "@babel/helper-explode-assignable-expression": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-builder-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz", + "integrity": "sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw==", + "dev": true, + "requires": { + "@babel/types": "^7.3.0", + "esutils": "^2.0.0" + } + }, + "@babel/helper-call-delegate": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-call-delegate/-/helper-call-delegate-7.4.4.tgz", + "integrity": "sha512-l79boDFJ8S1c5hvQvG+rc+wHw6IuH7YldmRKsYtpbawsxURu/paVy57FZMomGK22/JckepaikOkY0MoAmdyOlQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-create-class-features-plugin": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.4.4.tgz", + "integrity": "sha512-UbBHIa2qeAGgyiNR9RszVF7bUHEdgS4JAUNT8SiqrAN6YJVxlOxeLr5pBzb5kan302dejJ9nla4RyKcR1XT6XA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4" + } + }, + "@babel/helper-define-map": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-define-map/-/helper-define-map-7.4.4.tgz", + "integrity": "sha512-IX3Ln8gLhZpSuqHJSnTNBWGDE9kdkTEWl21A/K7PQ00tseBwbqCHTvNLHSBd9M0R5rER4h5Rsvj9vw0R5SieBg==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "@babel/helper-explode-assignable-expression": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz", + "integrity": "sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA==", + "dev": true, + "requires": { + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-function-name": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz", + "integrity": "sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw==", + "dev": true, + "requires": { + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-get-function-arity": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz", + "integrity": "sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-hoist-variables": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz", + "integrity": "sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-member-expression-to-functions": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.0.0.tgz", + "integrity": "sha512-avo+lm/QmZlv27Zsi0xEor2fKcqWG56D5ae9dzklpIaY7cQMK5N8VSpaNVPPagiqmy7LrEjK1IWdGMOqPu5csg==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-imports": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz", + "integrity": "sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-module-transforms": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-module-transforms/-/helper-module-transforms-7.4.4.tgz", + "integrity": "sha512-3Z1yp8TVQf+B4ynN7WoHPKS8EkdTbgAEy0nU0rs/1Kw4pDgmvYH3rz3aI11KgxKCba2cn7N+tqzV1mY2HMN96w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/template": "^7.4.4", + "@babel/types": "^7.4.4", + "lodash": "^4.17.11" + } + }, + "@babel/helper-optimise-call-expression": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz", + "integrity": "sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g==", + "dev": true, + "requires": { + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-plugin-utils": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz", + "integrity": "sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA==", + "dev": true + }, + "@babel/helper-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-regex/-/helper-regex-7.4.4.tgz", + "integrity": "sha512-Y5nuB/kESmR3tKjU8Nkn1wMGEx1tjJX076HBMeL3XLQCu6vA/YRzuTW0bbb+qRnXvQGn+d6Rx953yffl8vEy7Q==", + "dev": true, + "requires": { + "lodash": "^4.17.11" + } + }, + "@babel/helper-remap-async-to-generator": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz", + "integrity": "sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-wrap-function": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-replace-supers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-replace-supers/-/helper-replace-supers-7.4.4.tgz", + "integrity": "sha512-04xGEnd+s01nY1l15EuMS1rfKktNF+1CkKmHoErDppjAAZL+IUBZpzT748x262HF7fibaQPhbvWUl5HeSt1EXg==", + "dev": true, + "requires": { + "@babel/helper-member-expression-to-functions": "^7.0.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-simple-access": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz", + "integrity": "sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w==", + "dev": true, + "requires": { + "@babel/template": "^7.1.0", + "@babel/types": "^7.0.0" + } + }, + "@babel/helper-split-export-declaration": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz", + "integrity": "sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q==", + "dev": true, + "requires": { + "@babel/types": "^7.4.4" + } + }, + "@babel/helper-wrap-function": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz", + "integrity": "sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/template": "^7.1.0", + "@babel/traverse": "^7.1.0", + "@babel/types": "^7.2.0" + } + }, + "@babel/helpers": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.4.4.tgz", + "integrity": "sha512-igczbR/0SeuPR8RFfC7tGrbdTbFL3QTvH6D+Z6zNxnTe//GyqmtHmDkzrqDmyZ3eSwPqB/LhyKoU5DXsp+Vp2A==", + "dev": true, + "requires": { + "@babel/template": "^7.4.4", + "@babel/traverse": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/highlight": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz", + "integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==", + "dev": true, + "requires": { + "chalk": "^2.0.0", + "esutils": "^2.0.2", + "js-tokens": "^4.0.0" + } + }, + "@babel/parser": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.4.5.tgz", + "integrity": "sha512-9mUqkL1FF5T7f0WDFfAoDdiMVPWsdD1gZYzSnaXsxUCUqzuch/8of9G3VUSNiZmMBoRxT3neyVsqeiL/ZPcjew==", + "dev": true + }, + "@babel/plugin-proposal-async-generator-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz", + "integrity": "sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0", + "@babel/plugin-syntax-async-generators": "^7.2.0" + } + }, + "@babel/plugin-proposal-class-properties": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.4.4.tgz", + "integrity": "sha512-WjKTI8g8d5w1Bc9zgwSz2nfrsNQsXcCf9J9cdCvrJV6RF56yztwm4TmJC0MgJ9tvwO9gUA/mcYe89bLdGfiXFg==", + "dev": true, + "requires": { + "@babel/helper-create-class-features-plugin": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-proposal-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz", + "integrity": "sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-json-strings": "^7.2.0" + } + }, + "@babel/plugin-proposal-object-rest-spread": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.4.4.tgz", + "integrity": "sha512-dMBG6cSPBbHeEBdFXeQ2QLc5gUpg4Vkaz8octD4aoW/ISO+jBOcsuxYL7bsb5WSu8RLP6boxrBIALEHgoHtO9g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0" + } + }, + "@babel/plugin-proposal-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0" + } + }, + "@babel/plugin-proposal-unicode-property-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz", + "integrity": "sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-syntax-async-generators": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz", + "integrity": "sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-json-strings": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz", + "integrity": "sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-jsx": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz", + "integrity": "sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-object-rest-spread": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz", + "integrity": "sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-syntax-optional-catch-binding": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz", + "integrity": "sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-arrow-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz", + "integrity": "sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-async-to-generator": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.4.4.tgz", + "integrity": "sha512-YiqW2Li8TXmzgbXw+STsSqPBPFnGviiaSp6CYOq55X8GQ2SGVLrXB6pNid8HkqkZAzOH6knbai3snhP7v0fNwA==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-remap-async-to-generator": "^7.1.0" + } + }, + "@babel/plugin-transform-block-scoped-functions": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz", + "integrity": "sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-block-scoping": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.4.4.tgz", + "integrity": "sha512-jkTUyWZcTrwxu5DD4rWz6rDB5Cjdmgz6z7M7RLXOJyCUkFBawssDGcGh8M/0FTSB87avyJI1HsTwUXp9nKA1PA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "lodash": "^4.17.11" + } + }, + "@babel/plugin-transform-classes": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-classes/-/plugin-transform-classes-7.4.4.tgz", + "integrity": "sha512-/e44eFLImEGIpL9qPxSRat13I5QNRgBLu2hOQJCF7VLy/otSM/sypV1+XaIw5+502RX/+6YaSAPmldk+nhHDPw==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-define-map": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-optimise-call-expression": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.4.4", + "@babel/helper-split-export-declaration": "^7.4.4", + "globals": "^11.1.0" + } + }, + "@babel/plugin-transform-computed-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz", + "integrity": "sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-destructuring": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.4.4.tgz", + "integrity": "sha512-/aOx+nW0w8eHiEHm+BTERB2oJn5D127iye/SUQl7NjHy0lf+j7h4MKMMSOwdazGq9OxgiNADncE+SRJkCxjZpQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-dotall-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz", + "integrity": "sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/plugin-transform-duplicate-keys": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.2.0.tgz", + "integrity": "sha512-q+yuxW4DsTjNceUiTzK0L+AfQ0zD9rWaTLiUqHA8p0gxx7lu1EylenfzjeIWNkPy6e/0VG/Wjw9uf9LueQwLOw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-exponentiation-operator": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz", + "integrity": "sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A==", + "dev": true, + "requires": { + "@babel/helper-builder-binary-assignment-operator-visitor": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-for-of": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz", + "integrity": "sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-function-name": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz", + "integrity": "sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA==", + "dev": true, + "requires": { + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz", + "integrity": "sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-member-expression-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz", + "integrity": "sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-amd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.2.0.tgz", + "integrity": "sha512-mK2A8ucqz1qhrdqjS9VMIDfIvvT2thrEsIQzbaTdc5QFzhDjQv2CkJJ5f6BXIkgbmaoax3zBr2RyvV/8zeoUZw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-commonjs": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.4.4.tgz", + "integrity": "sha512-4sfBOJt58sEo9a2BQXnZq+Q3ZTSAUXyK3E30o36BOGnJ+tvJ6YSxF0PG6kERvbeISgProodWuI9UVG3/FMY6iw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-simple-access": "^7.1.0" + } + }, + "@babel/plugin-transform-modules-systemjs": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.4.4.tgz", + "integrity": "sha512-MSiModfILQc3/oqnG7NrP1jHaSPryO6tA2kOMmAQApz5dayPxWiHqmq4sWH2xF5LcQK56LlbKByCd8Aah/OIkQ==", + "dev": true, + "requires": { + "@babel/helper-hoist-variables": "^7.4.4", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-modules-umd": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz", + "integrity": "sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw==", + "dev": true, + "requires": { + "@babel/helper-module-transforms": "^7.1.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-named-capturing-groups-regex": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz", + "integrity": "sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg==", + "dev": true, + "requires": { + "regexp-tree": "^0.1.6" + } + }, + "@babel/plugin-transform-new-target": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz", + "integrity": "sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-object-super": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.2.0.tgz", + "integrity": "sha512-VMyhPYZISFZAqAPVkiYb7dUe2AsVi2/wCT5+wZdsNO31FojQJa9ns40hzZ6U9f50Jlq4w6qwzdBB2uwqZ00ebg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-replace-supers": "^7.1.0" + } + }, + "@babel/plugin-transform-parameters": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz", + "integrity": "sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw==", + "dev": true, + "requires": { + "@babel/helper-call-delegate": "^7.4.4", + "@babel/helper-get-function-arity": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-property-literals": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz", + "integrity": "sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-display-name": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz", + "integrity": "sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-react-jsx": { + "version": "7.3.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz", + "integrity": "sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg==", + "dev": true, + "requires": { + "@babel/helper-builder-react-jsx": "^7.3.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-self": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz", + "integrity": "sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-react-jsx-source": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.2.0.tgz", + "integrity": "sha512-A32OkKTp4i5U6aE88GwwcuV4HAprUgHcTq0sSafLxjr6AW0QahrCRCjxogkbbcdtpbXkuTOlgpjophCxb6sh5g==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-syntax-jsx": "^7.2.0" + } + }, + "@babel/plugin-transform-regenerator": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz", + "integrity": "sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA==", + "dev": true, + "requires": { + "regenerator-transform": "^0.14.0" + } + }, + "@babel/plugin-transform-reserved-words": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz", + "integrity": "sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-shorthand-properties": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz", + "integrity": "sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-spread": { + "version": "7.2.2", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz", + "integrity": "sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-sticky-regex": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz", + "integrity": "sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.0.0" + } + }, + "@babel/plugin-transform-template-literals": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz", + "integrity": "sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g==", + "dev": true, + "requires": { + "@babel/helper-annotate-as-pure": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-typeof-symbol": { + "version": "7.2.0", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz", + "integrity": "sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0" + } + }, + "@babel/plugin-transform-unicode-regex": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz", + "integrity": "sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/helper-regex": "^7.4.4", + "regexpu-core": "^4.5.4" + } + }, + "@babel/polyfill": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/polyfill/-/polyfill-7.4.4.tgz", + "integrity": "sha512-WlthFLfhQQhh+A2Gn5NSFl0Huxz36x86Jn+E9OW7ibK8edKPq+KLy4apM1yDpQ8kJOVi1OVjpP4vSDLdrI04dg==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/preset-env": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/preset-env/-/preset-env-7.4.5.tgz", + "integrity": "sha512-f2yNVXM+FsR5V8UwcFeIHzHWgnhXg3NpRmy0ADvALpnhB0SLbCvrCRr4BLOUYbQNLS+Z0Yer46x9dJXpXewI7w==", + "dev": true, + "requires": { + "@babel/helper-module-imports": "^7.0.0", + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-proposal-async-generator-functions": "^7.2.0", + "@babel/plugin-proposal-json-strings": "^7.2.0", + "@babel/plugin-proposal-object-rest-spread": "^7.4.4", + "@babel/plugin-proposal-optional-catch-binding": "^7.2.0", + "@babel/plugin-proposal-unicode-property-regex": "^7.4.4", + "@babel/plugin-syntax-async-generators": "^7.2.0", + "@babel/plugin-syntax-json-strings": "^7.2.0", + "@babel/plugin-syntax-object-rest-spread": "^7.2.0", + "@babel/plugin-syntax-optional-catch-binding": "^7.2.0", + "@babel/plugin-transform-arrow-functions": "^7.2.0", + "@babel/plugin-transform-async-to-generator": "^7.4.4", + "@babel/plugin-transform-block-scoped-functions": "^7.2.0", + "@babel/plugin-transform-block-scoping": "^7.4.4", + "@babel/plugin-transform-classes": "^7.4.4", + "@babel/plugin-transform-computed-properties": "^7.2.0", + "@babel/plugin-transform-destructuring": "^7.4.4", + "@babel/plugin-transform-dotall-regex": "^7.4.4", + "@babel/plugin-transform-duplicate-keys": "^7.2.0", + "@babel/plugin-transform-exponentiation-operator": "^7.2.0", + "@babel/plugin-transform-for-of": "^7.4.4", + "@babel/plugin-transform-function-name": "^7.4.4", + "@babel/plugin-transform-literals": "^7.2.0", + "@babel/plugin-transform-member-expression-literals": "^7.2.0", + "@babel/plugin-transform-modules-amd": "^7.2.0", + "@babel/plugin-transform-modules-commonjs": "^7.4.4", + "@babel/plugin-transform-modules-systemjs": "^7.4.4", + "@babel/plugin-transform-modules-umd": "^7.2.0", + "@babel/plugin-transform-named-capturing-groups-regex": "^7.4.5", + "@babel/plugin-transform-new-target": "^7.4.4", + "@babel/plugin-transform-object-super": "^7.2.0", + "@babel/plugin-transform-parameters": "^7.4.4", + "@babel/plugin-transform-property-literals": "^7.2.0", + "@babel/plugin-transform-regenerator": "^7.4.5", + "@babel/plugin-transform-reserved-words": "^7.2.0", + "@babel/plugin-transform-shorthand-properties": "^7.2.0", + "@babel/plugin-transform-spread": "^7.2.0", + "@babel/plugin-transform-sticky-regex": "^7.2.0", + "@babel/plugin-transform-template-literals": "^7.4.4", + "@babel/plugin-transform-typeof-symbol": "^7.2.0", + "@babel/plugin-transform-unicode-regex": "^7.4.4", + "@babel/types": "^7.4.4", + "browserslist": "^4.6.0", + "core-js-compat": "^3.1.1", + "invariant": "^2.2.2", + "js-levenshtein": "^1.1.3", + "semver": "^5.5.0" + } + }, + "@babel/preset-react": { + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/@babel/preset-react/-/preset-react-7.0.0.tgz", + "integrity": "sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w==", + "dev": true, + "requires": { + "@babel/helper-plugin-utils": "^7.0.0", + "@babel/plugin-transform-react-display-name": "^7.0.0", + "@babel/plugin-transform-react-jsx": "^7.0.0", + "@babel/plugin-transform-react-jsx-self": "^7.0.0", + "@babel/plugin-transform-react-jsx-source": "^7.0.0" + } + }, + "@babel/runtime-corejs2": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs2/-/runtime-corejs2-7.4.5.tgz", + "integrity": "sha512-5yLuwzvIDecKwYMzJtiarky4Fb5643H3Ao5jwX0HrMR5oM5mn2iHH9wSZonxwNK0oAjAFUQAiOd4jT7/9Y2jMQ==", + "dev": true, + "requires": { + "core-js": "^2.6.5", + "regenerator-runtime": "^0.13.2" + } + }, + "@babel/template": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.4.4.tgz", + "integrity": "sha512-CiGzLN9KgAvgZsnivND7rkA+AeJ9JB0ciPOD4U59GKbQP2iQl+olF1l76kJOupqidozfZ32ghwBEJDhnk9MEcw==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/parser": "^7.4.4", + "@babel/types": "^7.4.4" + } + }, + "@babel/traverse": { + "version": "7.4.5", + "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.4.5.tgz", + "integrity": "sha512-Vc+qjynwkjRmIFGxy0KYoPj4FdVDxLej89kMHFsWScq999uX+pwcX4v9mWRjW0KcAYTPAuVQl2LKP1wEVLsp+A==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "@babel/generator": "^7.4.4", + "@babel/helper-function-name": "^7.1.0", + "@babel/helper-split-export-declaration": "^7.4.4", + "@babel/parser": "^7.4.5", + "@babel/types": "^7.4.4", + "debug": "^4.1.0", + "globals": "^11.1.0", + "lodash": "^4.17.11" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "@babel/types": { + "version": "7.4.4", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.4.4.tgz", + "integrity": "sha512-dOllgYdnEFOebhkKCjzSVFqw/PmmB8pH6RGOWkY4GsboQNd47b1fBThBSwlHAq9alF9vc1M3+6oqR47R50L0tQ==", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "lodash": "^4.17.11", + "to-fast-properties": "^2.0.0" + } + }, + "acorn": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/acorn/-/acorn-6.1.1.tgz", + "integrity": "sha512-jPTiwtOxaHNaAPg/dmrJ/beuzLRnXtB0kQPQ8JpotKJgTB6rX6c8mlf315941pyjBSaPg8NHXS9fhP4u17DpGA==", + "dev": true + }, + "acorn-jsx": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/acorn-jsx/-/acorn-jsx-5.0.1.tgz", + "integrity": "sha512-HJ7CfNHrfJLlNTzIEUTj43LNWGkqpRLxm3YjAlcD0ACydk9XynzYsCBHxut+iqt+1aBXkx9UP/w/ZqMr13XIzg==", + "dev": true + }, + "ajv": { + "version": "6.10.0", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz", + "integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==", + "dev": true, + "requires": { + "fast-deep-equal": "^2.0.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + } + }, + "ansi-escapes": { + "version": "3.2.0", + "resolved": "https://registry.npmjs.org/ansi-escapes/-/ansi-escapes-3.2.0.tgz", + "integrity": "sha512-cBhpre4ma+U0T1oM5fXg7Dy1Jw7zzwv7lt/GoCpr+hDQJoYnKVPLL4dCvSEFMmQurOQvSrwT7SL/DAlhBI97RQ==", + "dev": true + }, + "ansi-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.0.tgz", + "integrity": "sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "anymatch": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/anymatch/-/anymatch-2.0.0.tgz", + "integrity": "sha512-5teOsQWABXHHBFP9y3skS5P3d/WfWXpv3FUpy+LorMrNYaT9pI4oLMQX7jzQ2KklNpGpWHzdCXTDT2Y3XGlZBw==", + "dev": true, + "optional": true, + "requires": { + "micromatch": "^3.1.4", + "normalize-path": "^2.1.1" + }, + "dependencies": { + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha1-GrKLVW4Zg2Oowab35vogE3/mrtk=", + "dev": true, + "optional": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + } + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "aria-query": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-3.0.0.tgz", + "integrity": "sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w=", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7", + "commander": "^2.11.0" + } + }, + "arr-diff": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/arr-diff/-/arr-diff-4.0.0.tgz", + "integrity": "sha1-1kYQdP6/7HHn4VI1dhoyml3HxSA=", + "dev": true, + "optional": true + }, + "arr-flatten": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/arr-flatten/-/arr-flatten-1.1.0.tgz", + "integrity": "sha512-L3hKV5R/p5o81R7O02IGnwpDmkp6E982XhtbuwSe3O4qOtMMMtodicASA1Cny2U+aCXcNpml+m4dPsvsJ3jatg==", + "dev": true, + "optional": true + }, + "arr-union": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/arr-union/-/arr-union-3.1.0.tgz", + "integrity": "sha1-45sJrqne+Gao8gbiiK9jkZuuOcQ=", + "dev": true, + "optional": true + }, + "array-includes": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/array-includes/-/array-includes-3.0.3.tgz", + "integrity": "sha1-GEtI9i2S10UrsxsyMWXH+L0CJm0=", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.7.0" + } + }, + "array-unique": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/array-unique/-/array-unique-0.3.2.tgz", + "integrity": "sha1-qJS3XUvE9s1nnvMkSp/Y9Gri1Cg=", + "dev": true, + "optional": true + }, + "assign-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/assign-symbols/-/assign-symbols-1.0.0.tgz", + "integrity": "sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c=", + "dev": true, + "optional": true + }, + "ast-types-flow": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/ast-types-flow/-/ast-types-flow-0.0.7.tgz", + "integrity": "sha1-9wtzXGvKGlycItmCw+Oef+ujva0=", + "dev": true + }, + "astral-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/astral-regex/-/astral-regex-1.0.0.tgz", + "integrity": "sha512-+Ryf6g3BKoRc7jfp7ad8tM4TtMiaWvbF/1/sQcZPkkS7ag3D5nMBCe2UfOTONtAkaG0tO0ij3C5Lwmf1EiyjHg==", + "dev": true + }, + "async-each": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/async-each/-/async-each-1.0.3.tgz", + "integrity": "sha512-z/WhQ5FPySLdvREByI2vZiTWwCnF0moMJ1hK9YQwDTHKh6I7/uSckMetoRGb5UBZPC1z0jlw+n/XCgjeH7y1AQ==", + "dev": true, + "optional": true + }, + "atob": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", + "integrity": "sha512-Wm6ukoaOGJi/73p/cl2GvLjTI5JM1k/O14isD73YML8StrH/7/lRFgmg8nICZgD3bZZvjwCGxtMOD3wWNAu8cg==", + "dev": true, + "optional": true + }, + "axobject-query": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-2.0.2.tgz", + "integrity": "sha512-MCeek8ZH7hKyO1rWUbKNQBbl4l2eY0ntk7OGi+q0RlafrCnfPxC06WZA+uebCfmYp4mNU9jRBP1AhGyf8+W3ww==", + "dev": true, + "requires": { + "ast-types-flow": "0.0.7" + } + }, + "balanced-match": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz", + "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=", + "dev": true + }, + "base": { + "version": "0.11.2", + "resolved": "https://registry.npmjs.org/base/-/base-0.11.2.tgz", + "integrity": "sha512-5T6P4xPgpp0YDFvSWwEZ4NoE3aM4QBQXDzmVbraCkFj8zHM+mba8SyqB5DbZWyR7mYHo6Y7BdQo3MoA4m0TeQg==", + "dev": true, + "optional": true, + "requires": { + "cache-base": "^1.0.1", + "class-utils": "^0.3.5", + "component-emitter": "^1.2.1", + "define-property": "^1.0.0", + "isobject": "^3.0.1", + "mixin-deep": "^1.2.0", + "pascalcase": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "binary-extensions": { + "version": "1.13.1", + "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-1.13.1.tgz", + "integrity": "sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw==", + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "braces": { + "version": "2.3.2", + "resolved": "https://registry.npmjs.org/braces/-/braces-2.3.2.tgz", + "integrity": "sha512-aNdbnj9P8PjdXU4ybaWLK2IF3jc/EoDYbC7AazW6to3TRsfXxscC9UXOB5iDiEQrkyIbWp2SLQda4+QAa7nc3w==", + "dev": true, + "optional": true, + "requires": { + "arr-flatten": "^1.1.0", + "array-unique": "^0.3.2", + "extend-shallow": "^2.0.1", + "fill-range": "^4.0.0", + "isobject": "^3.0.1", + "repeat-element": "^1.1.2", + "snapdragon": "^0.8.1", + "snapdragon-node": "^2.0.1", + "split-string": "^3.0.2", + "to-regex": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "browserslist": { + "version": "4.6.2", + "resolved": "https://registry.npmjs.org/browserslist/-/browserslist-4.6.2.tgz", + "integrity": "sha512-2neU/V0giQy9h3XMPwLhEY3+Ao0uHSwHvU8Q1Ea6AgLVL1sXbX3dzPrJ8NWe5Hi4PoTkCYXOtVR9rfRLI0J/8Q==", + "dev": true, + "requires": { + "caniuse-lite": "^1.0.30000974", + "electron-to-chromium": "^1.3.150", + "node-releases": "^1.1.23" + } + }, + "cache-base": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/cache-base/-/cache-base-1.0.1.tgz", + "integrity": "sha512-AKcdTnFSWATd5/GCPRxr2ChwIJ85CeyrEyjRHlKxQ56d4XJMGym0uAiKn0xbLOGOl3+yRpOTi484dVCEc5AUzQ==", + "dev": true, + "optional": true, + "requires": { + "collection-visit": "^1.0.0", + "component-emitter": "^1.2.1", + "get-value": "^2.0.6", + "has-value": "^1.0.0", + "isobject": "^3.0.1", + "set-value": "^2.0.0", + "to-object-path": "^0.3.0", + "union-value": "^1.0.0", + "unset-value": "^1.0.0" + } + }, + "callsites": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/callsites/-/callsites-3.1.0.tgz", + "integrity": "sha512-P8BjAsXvZS+VIDUI11hHCQEv74YT67YUi5JJFNWIqL235sBmjX4+qx9Muvls5ivyNENctx46xQLQ3aTuE7ssaQ==", + "dev": true + }, + "caniuse-lite": { + "version": "1.0.30000974", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30000974.tgz", + "integrity": "sha512-xc3rkNS/Zc3CmpMKuczWEdY2sZgx09BkAxfvkxlAEBTqcMHeL8QnPqhKse+5sRTi3nrw2pJwToD2WvKn1Uhvww==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "chardet": { + "version": "0.7.0", + "resolved": "https://registry.npmjs.org/chardet/-/chardet-0.7.0.tgz", + "integrity": "sha512-mT8iDcrh03qDGRRmoA2hmBJnxpllMR+0/0qlzjqZES6NdiWDcZkCNAk4rPFZ9Q85r27unkiNNg8ZOiwZXBHwcA==", + "dev": true + }, + "chokidar": { + "version": "2.1.6", + "resolved": "https://registry.npmjs.org/chokidar/-/chokidar-2.1.6.tgz", + "integrity": "sha512-V2jUo67OKkc6ySiRpJrjlpJKl9kDuG+Xb8VgsGzb+aEouhgS1D0weyPU4lEzdAcsCAvrih2J2BqyXqHWvVLw5g==", + "dev": true, + "optional": true, + "requires": { + "anymatch": "^2.0.0", + "async-each": "^1.0.1", + "braces": "^2.3.2", + "fsevents": "^1.2.7", + "glob-parent": "^3.1.0", + "inherits": "^2.0.3", + "is-binary-path": "^1.0.0", + "is-glob": "^4.0.0", + "normalize-path": "^3.0.0", + "path-is-absolute": "^1.0.0", + "readdirp": "^2.2.1", + "upath": "^1.1.1" + } + }, + "class-utils": { + "version": "0.3.6", + "resolved": "https://registry.npmjs.org/class-utils/-/class-utils-0.3.6.tgz", + "integrity": "sha512-qOhPa/Fj7s6TY8H8esGu5QNpMMQxz79h+urzrNYN6mn+9BnxlDGf5QZ+XeCDsxSjPqsSR56XOZOJmpeurnLMeg==", + "dev": true, + "optional": true, + "requires": { + "arr-union": "^3.1.0", + "define-property": "^0.2.5", + "isobject": "^3.0.0", + "static-extend": "^0.1.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "cli-cursor": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-2.1.0.tgz", + "integrity": "sha1-s12sN2R5+sw+lHR9QdDQ9SOP/LU=", + "dev": true, + "requires": { + "restore-cursor": "^2.0.0" + } + }, + "cli-width": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/cli-width/-/cli-width-2.2.0.tgz", + "integrity": "sha1-/xnt6Kml5XkyQUewwR8PvLq+1jk=", + "dev": true + }, + "collection-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/collection-visit/-/collection-visit-1.0.0.tgz", + "integrity": "sha1-S8A3PBZLwykbTTaMgpzxqApZ3KA=", + "dev": true, + "optional": true, + "requires": { + "map-visit": "^1.0.0", + "object-visit": "^1.0.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "dev": true + }, + "commander": { + "version": "2.20.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz", + "integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==", + "dev": true + }, + "component-emitter": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.0.tgz", + "integrity": "sha512-Rd3se6QB+sO1TwqZjscQrurpEPIfO0/yYnSin6Q/rD3mOutHvUrCAhJub3r90uNb+SESBuE0QYoB90YdfatsRg==", + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=", + "dev": true + }, + "contains-path": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/contains-path/-/contains-path-0.1.0.tgz", + "integrity": "sha1-/ozxhP9mcLa67wGp1IYaXL7EEgo=", + "dev": true + }, + "convert-source-map": { + "version": "1.6.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.6.0.tgz", + "integrity": "sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "copy-descriptor": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/copy-descriptor/-/copy-descriptor-0.1.1.tgz", + "integrity": "sha1-Z29us8OZl8LuGsOpJP1hJHSPV40=", + "dev": true, + "optional": true + }, + "core-js": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/core-js/-/core-js-2.6.9.tgz", + "integrity": "sha512-HOpZf6eXmnl7la+cUdMnLvUxKNqLUzJvgIziQ0DiF3JwSImNphIqdGqzj6hIKyX04MmV0poclQ7+wjWvxQyR2A==", + "dev": true + }, + "core-js-compat": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/core-js-compat/-/core-js-compat-3.1.3.tgz", + "integrity": "sha512-EP018pVhgwsKHz3YoN1hTq49aRe+h017Kjz0NQz3nXV0cCRMvH3fLQl+vEPGr4r4J5sk4sU3tUC7U1aqTCeJeA==", + "dev": true, + "requires": { + "browserslist": "^4.6.0", + "core-js-pure": "3.1.3", + "semver": "^6.1.0" + }, + "dependencies": { + "semver": { + "version": "6.1.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.1.1.tgz", + "integrity": "sha512-rWYq2e5iYW+fFe/oPPtYJxYgjBm8sC4rmoGdUOgBB7VnwKt6HrL793l2voH1UlsyYZpJ4g0wfjnTEO1s1NP2eQ==", + "dev": true + } + } + }, + "core-js-pure": { + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.1.3.tgz", + "integrity": "sha512-k3JWTrcQBKqjkjI0bkfXS0lbpWPxYuHWfMMjC1VDmzU4Q58IwSbuXSo99YO/hUHlw/EB4AlfA2PVxOGkrIq6dA==", + "dev": true + }, + "core-util-is": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", + "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "dev": true, + "optional": true + }, + "cross-env": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/cross-env/-/cross-env-5.2.0.tgz", + "integrity": "sha512-jtdNFfFW1hB7sMhr/H6rW1Z45LFqyI431m3qU6bFXcQ3Eh7LtBuG3h74o7ohHZ3crrRkkqHlo4jYHFPcjroANg==", + "dev": true, + "requires": { + "cross-spawn": "^6.0.5", + "is-windows": "^1.0.0" + } + }, + "cross-spawn": { + "version": "6.0.5", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-6.0.5.tgz", + "integrity": "sha512-eTVLrBSt7fjbDygz805pMnstIs2VTBNkRm0qxZd+M7A5XDdxVRWO5MxGBXZhjY4cqLYLdtrGqRf8mBPmzwSpWQ==", + "dev": true, + "requires": { + "nice-try": "^1.0.4", + "path-key": "^2.0.1", + "semver": "^5.5.0", + "shebang-command": "^1.2.0", + "which": "^1.2.9" + } + }, + "damerau-levenshtein": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/damerau-levenshtein/-/damerau-levenshtein-1.0.5.tgz", + "integrity": "sha512-CBCRqFnpu715iPmw1KrdOrzRqbdFwQTwAWyyyYS42+iAgHCuXZ+/TdMgQkUENPomxEz9z1BEzuQU2Xw0kUuAgA==", + "dev": true + }, + "debug": { + "version": "2.6.9", + "resolved": "https://registry.npmjs.org/debug/-/debug-2.6.9.tgz", + "integrity": "sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==", + "dev": true, + "requires": { + "ms": "2.0.0" + } + }, + "decode-uri-component": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/decode-uri-component/-/decode-uri-component-0.2.0.tgz", + "integrity": "sha1-6zkTMzRYd1y4TNGh+uBiEGu4dUU=", + "dev": true, + "optional": true + }, + "deep-is": { + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/deep-is/-/deep-is-0.1.3.tgz", + "integrity": "sha1-s2nW+128E+7PUk+RsHD+7cNXzzQ=", + "dev": true + }, + "define-properties": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/define-properties/-/define-properties-1.1.3.tgz", + "integrity": "sha512-3MqfYKj2lLzdMSf8ZIZE/V+Zuy+BgD6f164e8K2w7dgnpKArBDerGYpM46IYYcjnkdPNMjPk9A6VFB8+3SKlXQ==", + "dev": true, + "requires": { + "object-keys": "^1.0.12" + } + }, + "define-property": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-2.0.2.tgz", + "integrity": "sha512-jwK2UV4cnPpbcG7+VRARKTZPUWowwXA8bzH5NP6ud0oeAxyYPuGZUAC7hMugpCdz4BeSZl2Dl9k66CHJ/46ZYQ==", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^1.0.2", + "isobject": "^3.0.1" + }, + "dependencies": { + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "doctrine": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-3.0.0.tgz", + "integrity": "sha512-yS+Q5i3hBf7GBkd4KG8a7eBNNWNGLTaEwwYWUijIYM7zrlYDM0BFXHjjPWlWZ1Rg7UaddZeIDmi9jF3HmqiQ2w==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + }, + "electron-to-chromium": { + "version": "1.3.152", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.3.152.tgz", + "integrity": "sha512-Ah10cGMWIXYD8aUTH2Y7lGRhaOFQLyWuxvXmCPCZCbUIGJ4swnNmT6P4aA8RTgUmNw9kmcDL6SoU8TZC4YuZGg==", + "dev": true + }, + "emoji-regex": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-7.0.3.tgz", + "integrity": "sha512-CwBLREIQ7LvYFB0WyRvwhq5N5qPhc6PMjD6bYggFlI5YyDgl+0vxq5VHbMOFqLg7hfWzmu8T5Z1QofhmTIhItA==", + "dev": true + }, + "error-ex": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/error-ex/-/error-ex-1.3.2.tgz", + "integrity": "sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==", + "dev": true, + "requires": { + "is-arrayish": "^0.2.1" + } + }, + "es-abstract": { + "version": "1.13.0", + "resolved": "https://registry.npmjs.org/es-abstract/-/es-abstract-1.13.0.tgz", + "integrity": "sha512-vDZfg/ykNxQVwup/8E1BZhVzFfBxs9NqMzGcvIJrqg5k2/5Za2bWo40dK2J1pgLngZ7c+Shh8lwYtLGyrwPutg==", + "dev": true, + "requires": { + "es-to-primitive": "^1.2.0", + "function-bind": "^1.1.1", + "has": "^1.0.3", + "is-callable": "^1.1.4", + "is-regex": "^1.0.4", + "object-keys": "^1.0.12" + } + }, + "es-to-primitive": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/es-to-primitive/-/es-to-primitive-1.2.0.tgz", + "integrity": "sha512-qZryBOJjV//LaxLTV6UC//WewneB3LcXOL9NP++ozKVXsIIIpm/2c13UDiD9Jp2eThsecw9m3jPqDwTyobcdbg==", + "dev": true, + "requires": { + "is-callable": "^1.1.4", + "is-date-object": "^1.0.1", + "is-symbol": "^1.0.2" + } + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "dev": true + }, + "eslint": { + "version": "5.16.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-5.16.0.tgz", + "integrity": "sha512-S3Rz11i7c8AA5JPv7xAH+dOyq/Cu/VXHiHXBPOU1k/JAM5dXqQPt3qcrhpHSorXmrpu2g0gkIBVXAqCpzfoZIg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "ajv": "^6.9.1", + "chalk": "^2.1.0", + "cross-spawn": "^6.0.5", + "debug": "^4.0.1", + "doctrine": "^3.0.0", + "eslint-scope": "^4.0.3", + "eslint-utils": "^1.3.1", + "eslint-visitor-keys": "^1.0.0", + "espree": "^5.0.1", + "esquery": "^1.0.1", + "esutils": "^2.0.2", + "file-entry-cache": "^5.0.1", + "functional-red-black-tree": "^1.0.1", + "glob": "^7.1.2", + "globals": "^11.7.0", + "ignore": "^4.0.6", + "import-fresh": "^3.0.0", + "imurmurhash": "^0.1.4", + "inquirer": "^6.2.2", + "js-yaml": "^3.13.0", + "json-stable-stringify-without-jsonify": "^1.0.1", + "levn": "^0.3.0", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.1", + "natural-compare": "^1.4.0", + "optionator": "^0.8.2", + "path-is-inside": "^1.0.2", + "progress": "^2.0.0", + "regexpp": "^2.0.1", + "semver": "^5.5.1", + "strip-ansi": "^4.0.0", + "strip-json-comments": "^2.0.1", + "table": "^5.2.3", + "text-table": "^0.2.0" + }, + "dependencies": { + "debug": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz", + "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==", + "dev": true, + "requires": { + "ms": "^2.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + } + } + }, + "eslint-config-airbnb": { + "version": "17.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb/-/eslint-config-airbnb-17.1.0.tgz", + "integrity": "sha512-R9jw28hFfEQnpPau01NO5K/JWMGLi6aymiF6RsnMURjTk+MqZKllCqGK/0tOvHkPi/NWSSOU2Ced/GX++YxLnw==", + "dev": true, + "requires": { + "eslint-config-airbnb-base": "^13.1.0", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4" + } + }, + "eslint-config-airbnb-base": { + "version": "13.1.0", + "resolved": "https://registry.npmjs.org/eslint-config-airbnb-base/-/eslint-config-airbnb-base-13.1.0.tgz", + "integrity": "sha512-XWwQtf3U3zIoKO1BbHh6aUhJZQweOwSt4c2JrPDg9FP3Ltv3+YfEv7jIDB8275tVnO/qOHbfuYg3kzw6Je7uWw==", + "dev": true, + "requires": { + "eslint-restricted-globals": "^0.1.1", + "object.assign": "^4.1.0", + "object.entries": "^1.0.4" + } + }, + "eslint-config-defaults": { + "version": "9.0.0", + "resolved": "https://registry.npmjs.org/eslint-config-defaults/-/eslint-config-defaults-9.0.0.tgz", + "integrity": "sha1-oJCtwTspNeP0OzzQSKknAWVOWtU=", + "dev": true + }, + "eslint-import-resolver-node": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/eslint-import-resolver-node/-/eslint-import-resolver-node-0.3.2.tgz", + "integrity": "sha512-sfmTqJfPSizWu4aymbPr4Iidp5yKm8yDkHp+Ir3YiTHiiDfxh69mOUsmiqW6RZ9zRXFaF64GtYmN7e+8GHBv6Q==", + "dev": true, + "requires": { + "debug": "^2.6.9", + "resolve": "^1.5.0" + } + }, + "eslint-module-utils": { + "version": "2.4.0", + "resolved": "https://registry.npmjs.org/eslint-module-utils/-/eslint-module-utils-2.4.0.tgz", + "integrity": "sha512-14tltLm38Eu3zS+mt0KvILC3q8jyIAH518MlG+HO0p+yK885Lb1UHTY/UgR91eOyGdmxAPb+OLoW4znqIT6Ndw==", + "dev": true, + "requires": { + "debug": "^2.6.8", + "pkg-dir": "^2.0.0" + } + }, + "eslint-plugin-import": { + "version": "2.17.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-import/-/eslint-plugin-import-2.17.3.tgz", + "integrity": "sha512-qeVf/UwXFJbeyLbxuY8RgqDyEKCkqV7YC+E5S5uOjAp4tOc8zj01JP3ucoBM8JcEqd1qRasJSg6LLlisirfy0Q==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "contains-path": "^0.1.0", + "debug": "^2.6.9", + "doctrine": "1.5.0", + "eslint-import-resolver-node": "^0.3.2", + "eslint-module-utils": "^2.4.0", + "has": "^1.0.3", + "lodash": "^4.17.11", + "minimatch": "^3.0.4", + "read-pkg-up": "^2.0.0", + "resolve": "^1.11.0" + }, + "dependencies": { + "doctrine": { + "version": "1.5.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-1.5.0.tgz", + "integrity": "sha1-N53Ocw9hZvds76TmcHoVmwLFpvo=", + "dev": true, + "requires": { + "esutils": "^2.0.2", + "isarray": "^1.0.0" + } + } + } + }, + "eslint-plugin-jsx-a11y": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/eslint-plugin-jsx-a11y/-/eslint-plugin-jsx-a11y-6.2.1.tgz", + "integrity": "sha512-cjN2ObWrRz0TTw7vEcGQrx+YltMvZoOEx4hWU8eEERDnBIU00OTq7Vr+jA7DFKxiwLNv4tTh5Pq2GUNEa8b6+w==", + "dev": true, + "requires": { + "aria-query": "^3.0.0", + "array-includes": "^3.0.3", + "ast-types-flow": "^0.0.7", + "axobject-query": "^2.0.2", + "damerau-levenshtein": "^1.0.4", + "emoji-regex": "^7.0.2", + "has": "^1.0.3", + "jsx-ast-utils": "^2.0.1" + } + }, + "eslint-plugin-react": { + "version": "7.13.0", + "resolved": "https://registry.npmjs.org/eslint-plugin-react/-/eslint-plugin-react-7.13.0.tgz", + "integrity": "sha512-uA5LrHylu8lW/eAH3bEQe9YdzpPaFd9yAJTwTi/i/BKTD7j6aQMKVAdGM/ML72zD6womuSK7EiGtMKuK06lWjQ==", + "dev": true, + "requires": { + "array-includes": "^3.0.3", + "doctrine": "^2.1.0", + "has": "^1.0.3", + "jsx-ast-utils": "^2.1.0", + "object.fromentries": "^2.0.0", + "prop-types": "^15.7.2", + "resolve": "^1.10.1" + }, + "dependencies": { + "doctrine": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/doctrine/-/doctrine-2.1.0.tgz", + "integrity": "sha512-35mSku4ZXK0vfCuHEDAwt55dg2jNajHZ1odvF+8SSr82EsZY4QmXfuWso8oEd8zRhVObSN18aM0CjSdoBX7zIw==", + "dev": true, + "requires": { + "esutils": "^2.0.2" + } + } + } + }, + "eslint-restricted-globals": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/eslint-restricted-globals/-/eslint-restricted-globals-0.1.1.tgz", + "integrity": "sha1-NfDVy8ZMLj7WLpO0saevBbp+1Nc=", + "dev": true + }, + "eslint-scope": { + "version": "4.0.3", + "resolved": "https://registry.npmjs.org/eslint-scope/-/eslint-scope-4.0.3.tgz", + "integrity": "sha512-p7VutNr1O/QrxysMo3E45FjYDTeXBy0iTltPFNSqKAIfjDSXC+4dj+qfyuD8bfAXrW/y6lW3O76VaYNPKfpKrg==", + "dev": true, + "requires": { + "esrecurse": "^4.1.0", + "estraverse": "^4.1.1" + } + }, + "eslint-utils": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/eslint-utils/-/eslint-utils-1.3.1.tgz", + "integrity": "sha512-Z7YjnIldX+2XMcjr7ZkgEsOj/bREONV60qYeB/bjMAqqqZ4zxKyWX+BOUkdmRmA9riiIPVvo5x86m5elviOk0Q==", + "dev": true + }, + "eslint-visitor-keys": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz", + "integrity": "sha512-qzm/XxIbxm/FHyH341ZrbnMUpe+5Bocte9xkmFMzPMjRaZMcXww+MpBptFvtU+79L362nqiLhekCxCxDPaUMBQ==", + "dev": true + }, + "espree": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-5.0.1.tgz", + "integrity": "sha512-qWAZcWh4XE/RwzLJejfcofscgMc9CamR6Tn1+XRXNzrvUSSbiAjGOI/fggztjIi7y9VLPqnICMIPiGyr8JaZ0A==", + "dev": true, + "requires": { + "acorn": "^6.0.7", + "acorn-jsx": "^5.0.0", + "eslint-visitor-keys": "^1.0.0" + } + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "esquery": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/esquery/-/esquery-1.0.1.tgz", + "integrity": "sha512-SmiyZ5zIWH9VM+SRUReLS5Q8a7GxtRdxEBVZpm98rJM7Sb+A9DVCndXfkeFUd3byderg+EbDkfnevfCwynWaNA==", + "dev": true, + "requires": { + "estraverse": "^4.0.0" + } + }, + "esrecurse": { + "version": "4.2.1", + "resolved": "https://registry.npmjs.org/esrecurse/-/esrecurse-4.2.1.tgz", + "integrity": "sha512-64RBB++fIOAXPw3P9cy89qfMlvZEXZkqqJkjqqXIvzP5ezRZjW+lPWjw35UX/3EhUPFYbg5ER4JYgDw4007/DQ==", + "dev": true, + "requires": { + "estraverse": "^4.1.0" + } + }, + "estraverse": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/estraverse/-/estraverse-4.2.0.tgz", + "integrity": "sha1-De4/7TH81GlhjOc0IJn8GvoL2xM=", + "dev": true + }, + "esutils": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz", + "integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=", + "dev": true + }, + "expand-brackets": { + "version": "2.1.4", + "resolved": "https://registry.npmjs.org/expand-brackets/-/expand-brackets-2.1.4.tgz", + "integrity": "sha1-t3c14xXOMPa27/D4OwQVGiJEliI=", + "dev": true, + "optional": true, + "requires": { + "debug": "^2.3.3", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "posix-character-classes": "^0.1.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "extend-shallow": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-3.0.2.tgz", + "integrity": "sha1-Jqcarwc7OfshJxcnRhMcJwQCjbg=", + "dev": true, + "optional": true, + "requires": { + "assign-symbols": "^1.0.0", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "optional": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "external-editor": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/external-editor/-/external-editor-3.0.3.tgz", + "integrity": "sha512-bn71H9+qWoOQKyZDo25mOMVpSmXROAsTJVVVYzrrtol3d4y+AsKjf4Iwl2Q+IuT0kFSQ1qo166UuIwqYq7mGnA==", + "dev": true, + "requires": { + "chardet": "^0.7.0", + "iconv-lite": "^0.4.24", + "tmp": "^0.0.33" + } + }, + "extglob": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/extglob/-/extglob-2.0.4.tgz", + "integrity": "sha512-Nmb6QXkELsuBr24CJSkilo6UHHgbekK5UiZgfE6UHD3Eb27YC6oD+bhcT+tJ6cl8dmsgdQxnWlcry8ksBIBLpw==", + "dev": true, + "optional": true, + "requires": { + "array-unique": "^0.3.2", + "define-property": "^1.0.0", + "expand-brackets": "^2.1.4", + "extend-shallow": "^2.0.1", + "fragment-cache": "^0.2.1", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "fast-deep-equal": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz", + "integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=", + "dev": true + }, + "fast-json-stable-stringify": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz", + "integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=", + "dev": true + }, + "fast-levenshtein": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz", + "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=", + "dev": true + }, + "figures": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/figures/-/figures-2.0.0.tgz", + "integrity": "sha1-OrGi0qYsi/tDGgyUy3l6L84nyWI=", + "dev": true, + "requires": { + "escape-string-regexp": "^1.0.5" + } + }, + "file-entry-cache": { + "version": "5.0.1", + "resolved": "https://registry.npmjs.org/file-entry-cache/-/file-entry-cache-5.0.1.tgz", + "integrity": "sha512-bCg29ictuBaKUwwArK4ouCaqDgLZcysCFLmM/Yn/FDoqndh/9vNuQfXRDvTuXKLxfD/JtZQGKFT8MGcJBK644g==", + "dev": true, + "requires": { + "flat-cache": "^2.0.1" + } + }, + "fill-range": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/fill-range/-/fill-range-4.0.0.tgz", + "integrity": "sha1-1USBHUKPmOsGpj3EAtJAPDKMOPc=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-number": "^3.0.0", + "repeat-string": "^1.6.1", + "to-regex-range": "^2.1.0" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "find-up": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-2.1.0.tgz", + "integrity": "sha1-RdG35QbHF93UgndaK3eSCjwMV6c=", + "dev": true, + "requires": { + "locate-path": "^2.0.0" + } + }, + "flat-cache": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/flat-cache/-/flat-cache-2.0.1.tgz", + "integrity": "sha512-LoQe6yDuUMDzQAEH8sgmh4Md6oZnc/7PjtwjNFSzveXqSHt6ka9fPBuso7IGf9Rz4uqnSnWiFH2B/zj24a5ReA==", + "dev": true, + "requires": { + "flatted": "^2.0.0", + "rimraf": "2.6.3", + "write": "1.0.3" + } + }, + "flatted": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/flatted/-/flatted-2.0.0.tgz", + "integrity": "sha512-R+H8IZclI8AAkSBRQJLVOsxwAoHd6WC40b4QTNWIjzAa6BXOBfQcM587MXDTVPeYaopFNWHUFLx7eNmHDSxMWg==", + "dev": true + }, + "for-in": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/for-in/-/for-in-1.0.2.tgz", + "integrity": "sha1-gQaNKVqBQuwKxybG4iAMMPttXoA=", + "dev": true, + "optional": true + }, + "fragment-cache": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/fragment-cache/-/fragment-cache-0.2.1.tgz", + "integrity": "sha1-QpD60n8T6Jvn8zeZxrxaCr//DRk=", + "dev": true, + "optional": true, + "requires": { + "map-cache": "^0.2.2" + } + }, + "fs-readdir-recursive": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fs-readdir-recursive/-/fs-readdir-recursive-1.1.0.tgz", + "integrity": "sha512-GNanXlVr2pf02+sPN40XN8HG+ePaNcvM0q5mZBd668Obwb0yD5GiUbZOFgwn8kGMY6I3mdyDJzieUy3PTYyTRA==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=", + "dev": true + }, + "fsevents": { + "version": "1.2.9", + "resolved": "https://registry.npmjs.org/fsevents/-/fsevents-1.2.9.tgz", + "integrity": "sha512-oeyj2H3EjjonWcFjD5NvZNE9Rqe4UW+nQBU2HNeKw0koVLEFIhtyETyAakeAM3de7Z/SW5kcA+fZUait9EApnw==", + "dev": true, + "optional": true, + "requires": { + "nan": "^2.12.1", + "node-pre-gyp": "^0.12.0" + }, + "dependencies": { + "abbrev": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "ansi-regex": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "aproba": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + }, + "are-we-there-yet": { + "version": "1.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "delegates": "^1.0.0", + "readable-stream": "^2.0.6" + } + }, + "balanced-match": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "brace-expansion": { + "version": "1.1.11", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "chownr": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "code-point-at": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "concat-map": { + "version": "0.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "console-control-strings": { + "version": "1.1.0", + "bundled": true, + "dev": true, + "optional": true + }, + "core-util-is": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "debug": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ms": "^2.1.1" + } + }, + "deep-extend": { + "version": "0.6.0", + "bundled": true, + "dev": true, + "optional": true + }, + "delegates": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "detect-libc": { + "version": "1.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "fs-minipass": { + "version": "1.2.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "fs.realpath": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "gauge": { + "version": "2.7.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "aproba": "^1.0.3", + "console-control-strings": "^1.0.0", + "has-unicode": "^2.0.0", + "object-assign": "^4.1.0", + "signal-exit": "^3.0.0", + "string-width": "^1.0.1", + "strip-ansi": "^3.0.1", + "wide-align": "^1.1.0" + } + }, + "glob": { + "version": "7.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has-unicode": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "iconv-lite": { + "version": "0.4.24", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore-walk": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimatch": "^3.0.4" + } + }, + "inflight": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "bundled": true, + "dev": true, + "optional": true + }, + "ini": { + "version": "1.3.5", + "bundled": true, + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "number-is-nan": "^1.0.0" + } + }, + "isarray": { + "version": "1.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "minimatch": { + "version": "3.0.4", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "bundled": true, + "dev": true, + "optional": true + }, + "minipass": { + "version": "2.3.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "^5.1.2", + "yallist": "^3.0.0" + } + }, + "minizlib": { + "version": "1.2.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minipass": "^2.2.1" + } + }, + "mkdirp": { + "version": "0.5.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "needle": { + "version": "2.3.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "debug": "^4.1.0", + "iconv-lite": "^0.4.4", + "sax": "^1.2.4" + } + }, + "node-pre-gyp": { + "version": "0.12.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "detect-libc": "^1.0.2", + "mkdirp": "^0.5.1", + "needle": "^2.2.1", + "nopt": "^4.0.1", + "npm-packlist": "^1.1.6", + "npmlog": "^4.0.2", + "rc": "^1.2.7", + "rimraf": "^2.6.1", + "semver": "^5.3.0", + "tar": "^4" + } + }, + "nopt": { + "version": "4.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "abbrev": "1", + "osenv": "^0.1.4" + } + }, + "npm-bundled": { + "version": "1.0.6", + "bundled": true, + "dev": true, + "optional": true + }, + "npm-packlist": { + "version": "1.4.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ignore-walk": "^3.0.1", + "npm-bundled": "^1.0.1" + } + }, + "npmlog": { + "version": "4.1.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "are-we-there-yet": "~1.1.2", + "console-control-strings": "~1.1.0", + "gauge": "~2.7.3", + "set-blocking": "~2.0.0" + } + }, + "number-is-nan": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "bundled": true, + "dev": true, + "optional": true + }, + "once": { + "version": "1.4.0", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "wrappy": "1" + } + }, + "os-homedir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "os-tmpdir": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "osenv": { + "version": "0.1.5", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "os-homedir": "^1.0.0", + "os-tmpdir": "^1.0.0" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "process-nextick-args": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "rc": { + "version": "1.2.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "deep-extend": "^0.6.0", + "ini": "~1.3.0", + "minimist": "^1.2.0", + "strip-json-comments": "~2.0.1" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "readable-stream": { + "version": "2.3.6", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "rimraf": { + "version": "2.6.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "glob": "^7.1.3" + } + }, + "safe-buffer": { + "version": "5.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "safer-buffer": { + "version": "2.1.2", + "bundled": true, + "dev": true, + "optional": true + }, + "sax": { + "version": "1.2.4", + "bundled": true, + "dev": true, + "optional": true + }, + "semver": { + "version": "5.7.0", + "bundled": true, + "dev": true, + "optional": true + }, + "set-blocking": { + "version": "2.0.0", + "bundled": true, + "dev": true, + "optional": true + }, + "signal-exit": { + "version": "3.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "string-width": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "code-point-at": "^1.0.0", + "is-fullwidth-code-point": "^1.0.0", + "strip-ansi": "^3.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "3.0.1", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "ansi-regex": "^2.0.0" + } + }, + "strip-json-comments": { + "version": "2.0.1", + "bundled": true, + "dev": true, + "optional": true + }, + "tar": { + "version": "4.4.8", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "chownr": "^1.1.1", + "fs-minipass": "^1.2.5", + "minipass": "^2.3.4", + "minizlib": "^1.1.1", + "mkdirp": "^0.5.0", + "safe-buffer": "^5.1.2", + "yallist": "^3.0.2" + } + }, + "util-deprecate": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "wide-align": { + "version": "1.1.3", + "bundled": true, + "dev": true, + "optional": true, + "requires": { + "string-width": "^1.0.2 || 2" + } + }, + "wrappy": { + "version": "1.0.2", + "bundled": true, + "dev": true, + "optional": true + }, + "yallist": { + "version": "3.0.3", + "bundled": true, + "dev": true, + "optional": true + } + } + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "functional-red-black-tree": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/functional-red-black-tree/-/functional-red-black-tree-1.0.1.tgz", + "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=", + "dev": true + }, + "get-value": { + "version": "2.0.6", + "resolved": "https://registry.npmjs.org/get-value/-/get-value-2.0.6.tgz", + "integrity": "sha1-3BXKHGcjh8p2vTesCjlbogQqLCg=", + "dev": true, + "optional": true + }, + "glob": { + "version": "7.1.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz", + "integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "glob-parent": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-3.1.0.tgz", + "integrity": "sha1-nmr2KZ2NO9K9QEMIMr0RPfkGxa4=", + "dev": true, + "optional": true, + "requires": { + "is-glob": "^3.1.0", + "path-dirname": "^1.0.0" + }, + "dependencies": { + "is-glob": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-3.1.0.tgz", + "integrity": "sha1-e6WuJCF4BKxwcHuWkiVnSGzD6Eo=", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.0" + } + } + } + }, + "globals": { + "version": "11.12.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-11.12.0.tgz", + "integrity": "sha512-WOBp/EEGUiIsJSp7wcv/y6MO+lV9UoncWqxuFfm8eBwzWNgyfBd6Gz+IeKQ9jCmyhoH99g15M3T+QaVHFjizVA==", + "dev": true + }, + "graceful-fs": { + "version": "4.1.15", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.1.15.tgz", + "integrity": "sha512-6uHUhOPEBgQ24HM+r6b/QwWfZq+yiFcipKFrOFiBEnWdy5sdzYoi+pJeQaPI5qOLRFqWmAXUPQNsielzdLoecA==", + "dev": true + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", + "dev": true + }, + "has-symbols": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-symbols/-/has-symbols-1.0.0.tgz", + "integrity": "sha1-uhqPGvKg/DllD1yFA2dwQSIGO0Q=", + "dev": true + }, + "has-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-1.0.0.tgz", + "integrity": "sha1-GLKB2lhbHFxR3vJMkw7SmgvmsXc=", + "dev": true, + "optional": true, + "requires": { + "get-value": "^2.0.6", + "has-values": "^1.0.0", + "isobject": "^3.0.0" + } + }, + "has-values": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-1.0.0.tgz", + "integrity": "sha1-lbC2P+whRmGab+V/51Yo1aOe/k8=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "kind-of": "^4.0.0" + }, + "dependencies": { + "kind-of": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-4.0.0.tgz", + "integrity": "sha1-IIE989cSkosgc3hpGkUGb65y3Vc=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "hosted-git-info": { + "version": "2.7.1", + "resolved": "https://registry.npmjs.org/hosted-git-info/-/hosted-git-info-2.7.1.tgz", + "integrity": "sha512-7T/BxH19zbcCTa8XkMlbK5lTo1WtgkFi3GvdWEyNuc4Vex7/9Dqbnpsf4JMydcfj9HCg4zUWFTL3Za6lapg5/w==", + "dev": true + }, + "iconv-lite": { + "version": "0.4.24", + "resolved": "https://registry.npmjs.org/iconv-lite/-/iconv-lite-0.4.24.tgz", + "integrity": "sha512-v3MXnZAcvnywkTUEZomIActle7RXXeedOR31wwl7VlyoXO4Qi9arvSenNQWne1TcRwhCL1HwLI21bEqdpj8/rA==", + "dev": true, + "requires": { + "safer-buffer": ">= 2.1.2 < 3" + } + }, + "ignore": { + "version": "4.0.6", + "resolved": "https://registry.npmjs.org/ignore/-/ignore-4.0.6.tgz", + "integrity": "sha512-cyFDKrqc/YdcWFniJhzI42+AzS+gNwmUzOSFcRCQYwySuBBBy/KjuxWLZ/FHEH6Moq1NizMOBWyTcv8O4OZIMg==", + "dev": true + }, + "import-fresh": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/import-fresh/-/import-fresh-3.0.0.tgz", + "integrity": "sha512-pOnA9tfM3Uwics+SaBLCNyZZZbK+4PTu0OPZtLlMIrv17EdBoC15S9Kn8ckJ9TZTyKb3ywNE5y1yeDxxGA7nTQ==", + "dev": true, + "requires": { + "parent-module": "^1.0.0", + "resolve-from": "^4.0.0" + } + }, + "imurmurhash": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/imurmurhash/-/imurmurhash-0.1.4.tgz", + "integrity": "sha1-khi5srkoojixPcT7a21XbyMUU+o=", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz", + "integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=", + "dev": true + }, + "inquirer": { + "version": "6.3.1", + "resolved": "https://registry.npmjs.org/inquirer/-/inquirer-6.3.1.tgz", + "integrity": "sha512-MmL624rfkFt4TG9y/Jvmt8vdmOo836U7Y0Hxr2aFk3RelZEGX4Igk0KabWrcaaZaTv9uzglOqWh1Vly+FAWAXA==", + "dev": true, + "requires": { + "ansi-escapes": "^3.2.0", + "chalk": "^2.4.2", + "cli-cursor": "^2.1.0", + "cli-width": "^2.0.0", + "external-editor": "^3.0.3", + "figures": "^2.0.0", + "lodash": "^4.17.11", + "mute-stream": "0.0.7", + "run-async": "^2.2.0", + "rxjs": "^6.4.0", + "string-width": "^2.1.0", + "strip-ansi": "^5.1.0", + "through": "^2.3.6" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "invariant": { + "version": "2.2.4", + "resolved": "https://registry.npmjs.org/invariant/-/invariant-2.2.4.tgz", + "integrity": "sha512-phJfQVBuaJM5raOpJjSfkiD6BpbCE4Ns//LaXl6wGYtUBY83nWS6Rf9tXm2e8VaK60JEjYldbPif/A2B1C2gNA==", + "dev": true, + "requires": { + "loose-envify": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-0.1.6.tgz", + "integrity": "sha1-qeEss66Nh2cn7u84Q/igiXtcmNY=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-arrayish": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/is-arrayish/-/is-arrayish-0.2.1.tgz", + "integrity": "sha1-d8mYQFJ6qOyxqLppe4BkWnqSap0=", + "dev": true + }, + "is-binary-path": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-binary-path/-/is-binary-path-1.0.1.tgz", + "integrity": "sha1-dfFmQrSA8YenEcgUFh/TpKdlWJg=", + "dev": true, + "optional": true, + "requires": { + "binary-extensions": "^1.0.0" + } + }, + "is-buffer": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/is-buffer/-/is-buffer-1.1.6.tgz", + "integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==", + "dev": true, + "optional": true + }, + "is-callable": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/is-callable/-/is-callable-1.1.4.tgz", + "integrity": "sha512-r5p9sxJjYnArLjObpjA4xu5EKI3CuKHkJXMhT7kwbpUyIFD1n5PMAsoPvWnvtZiNz7LjkYDRZhd7FlI0eMijEA==", + "dev": true + }, + "is-data-descriptor": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-0.1.4.tgz", + "integrity": "sha1-C17mSDiOLIYCgueT8YVv7D8wG1Y=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-date-object": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-date-object/-/is-date-object-1.0.1.tgz", + "integrity": "sha1-mqIOtq7rv/d/vTPnTKAbM1gdOhY=", + "dev": true + }, + "is-descriptor": { + "version": "0.1.6", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-0.1.6.tgz", + "integrity": "sha512-avDYr0SB3DwO9zsMov0gKCESFYqCnE4hq/4z3TdUlukEy5t9C0YRq7HLrsN52NAcqXKaepeCD0n+B0arnVG3Hg==", + "dev": true, + "optional": true, + "requires": { + "is-accessor-descriptor": "^0.1.6", + "is-data-descriptor": "^0.1.4", + "kind-of": "^5.0.0" + }, + "dependencies": { + "kind-of": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-5.1.0.tgz", + "integrity": "sha512-NGEErnH6F2vUuXDh+OlbcKW7/wOcfdRHaZ7VWtqCztfHri/++YKmP51OdWeGPuqCOba6kk2OTe5d02VmTB80Pw==", + "dev": true, + "optional": true + } + } + }, + "is-extendable": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-0.1.1.tgz", + "integrity": "sha1-YrEQ4omkcUGOPsNqYX1HLjAd/Ik=", + "dev": true, + "optional": true + }, + "is-extglob": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/is-extglob/-/is-extglob-2.1.1.tgz", + "integrity": "sha1-qIwCU1eR8C7TfHahueqXc8gz+MI=", + "dev": true, + "optional": true + }, + "is-fullwidth-code-point": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz", + "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=", + "dev": true + }, + "is-glob": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.1.tgz", + "integrity": "sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg==", + "dev": true, + "optional": true, + "requires": { + "is-extglob": "^2.1.1" + } + }, + "is-number": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-number/-/is-number-3.0.0.tgz", + "integrity": "sha1-JP1iAaR4LPUFYcgQJ2r8fRLXEZU=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "is-plain-obj": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/is-plain-obj/-/is-plain-obj-1.1.0.tgz", + "integrity": "sha1-caUMhCnfync8kqOQpKA7OfzVHT4=", + "dev": true + }, + "is-plain-object": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/is-plain-object/-/is-plain-object-2.0.4.tgz", + "integrity": "sha512-h5PpgXkWitc38BBMYawTYMWJHFZJVnBquFE57xFpjB8pJFiF6gZ+bU+WyI/yqXiFR5mdLsgYNaPe8uao6Uv9Og==", + "dev": true, + "optional": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "is-promise": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/is-promise/-/is-promise-2.1.0.tgz", + "integrity": "sha1-eaKp7OfwlugPNtKy87wWwf9L8/o=", + "dev": true + }, + "is-regex": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/is-regex/-/is-regex-1.0.4.tgz", + "integrity": "sha1-VRdIm1RwkbCTDglWVM7SXul+lJE=", + "dev": true, + "requires": { + "has": "^1.0.1" + } + }, + "is-symbol": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-symbol/-/is-symbol-1.0.2.tgz", + "integrity": "sha512-HS8bZ9ox60yCJLH9snBpIwv9pYUAkcuLhSA1oero1UB5y9aiQpRA8y2ex945AOtCZL1lJDeIk3G5LthswI46Lw==", + "dev": true, + "requires": { + "has-symbols": "^1.0.0" + } + }, + "is-windows": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-windows/-/is-windows-1.0.2.tgz", + "integrity": "sha512-eXK1UInq2bPmjyX6e3VHIzMLobc4J94i4AWn+Hpq3OU5KkrRC96OAcR3PRJ/pGu6m8TRnBHP9dkXQVsT/COVIA==", + "dev": true + }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, + "isexe": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", + "integrity": "sha1-6PvzdNxVb/iUehDcsFctYz8s+hA=", + "dev": true + }, + "isobject": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-3.0.1.tgz", + "integrity": "sha1-TkMekrEalzFjaqH5yNHMvP2reN8=", + "dev": true, + "optional": true + }, + "js-levenshtein": { + "version": "1.1.6", + "resolved": "https://registry.npmjs.org/js-levenshtein/-/js-levenshtein-1.1.6.tgz", + "integrity": "sha512-X2BB11YZtrRqY4EnQcLX5Rh373zbK4alC1FW7D7MBhL2gtcC17cTnr6DmfHZeS0s2rTHjUTMMHfG7gO8SSdw+g==", + "dev": true + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.13.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", + "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "jsesc": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-2.5.2.tgz", + "integrity": "sha512-OYu7XEzjkCQ3C5Ps3QIZsQfNpqoJyZZA99wd9aWd05NCtC5pWOkShK2mkL6HXQR6/Cy2lbNdPlZBpuQHXE63gA==", + "dev": true + }, + "json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true + }, + "json-stable-stringify-without-jsonify": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/json-stable-stringify-without-jsonify/-/json-stable-stringify-without-jsonify-1.0.1.tgz", + "integrity": "sha1-nbe1lJatPzz+8wp1FC0tkwrXJlE=", + "dev": true + }, + "json5": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/json5/-/json5-2.1.0.tgz", + "integrity": "sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ==", + "dev": true, + "requires": { + "minimist": "^1.2.0" + }, + "dependencies": { + "minimist": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz", + "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=", + "dev": true + } + } + }, + "jsx-ast-utils": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/jsx-ast-utils/-/jsx-ast-utils-2.1.0.tgz", + "integrity": "sha512-yDGDG2DS4JcqhA6blsuYbtsT09xL8AoLuUR2Gb5exrw7UEM19sBcOTq+YBBhrNbl0PUC4R4LnFu+dHg2HKeVvA==", + "dev": true, + "requires": { + "array-includes": "^3.0.3" + } + }, + "kind-of": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-6.0.2.tgz", + "integrity": "sha512-s5kLOcnH0XqDO+FvuaLX8DDjZ18CGFk7VygH40QoKPUQhW4e2rvM0rwUq0t8IQDOwYSeLK01U90OjzBTme2QqA==", + "dev": true, + "optional": true + }, + "levn": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", + "integrity": "sha1-OwmSTt+fCDwEkP3UwLxEIeBHZO4=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2" + } + }, + "load-json-file": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/load-json-file/-/load-json-file-2.0.0.tgz", + "integrity": "sha1-eUfkIUmvgNaWy/eXvKq8/h/inKg=", + "dev": true, + "requires": { + "graceful-fs": "^4.1.2", + "parse-json": "^2.2.0", + "pify": "^2.0.0", + "strip-bom": "^3.0.0" + } + }, + "locate-path": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-2.0.0.tgz", + "integrity": "sha1-K1aLJl7slExtnA3pw9u7ygNUzY4=", + "dev": true, + "requires": { + "p-locate": "^2.0.0", + "path-exists": "^3.0.0" + } + }, + "lodash": { + "version": "4.17.11", + "resolved": "https://registry.npmjs.org/lodash/-/lodash-4.17.11.tgz", + "integrity": "sha512-cQKh8igo5QUhZ7lg38DYWAxMvjSAKG0A8wGSVimP07SIUEK2UO+arSRKbRZWtelMtN5V0Hkwh5ryOto/SshYIg==", + "dev": true + }, + "loose-envify": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", + "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", + "dev": true, + "requires": { + "js-tokens": "^3.0.0 || ^4.0.0" + } + }, + "map-cache": { + "version": "0.2.2", + "resolved": "https://registry.npmjs.org/map-cache/-/map-cache-0.2.2.tgz", + "integrity": "sha1-wyq9C9ZSXZsFFkW7TyasXcmKDb8=", + "dev": true, + "optional": true + }, + "map-visit": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/map-visit/-/map-visit-1.0.0.tgz", + "integrity": "sha1-7Nyo8TFE5mDxtb1B8S80edmN+48=", + "dev": true, + "optional": true, + "requires": { + "object-visit": "^1.0.0" + } + }, + "micromatch": { + "version": "3.1.10", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-3.1.10.tgz", + "integrity": "sha512-MWikgl9n9M3w+bpsY3He8L+w9eF9338xRl8IAO5viDizwSzziFEyUzo2xrrloB64ADbTf8uA8vRqqttDTOmccg==", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "braces": "^2.3.1", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "extglob": "^2.0.4", + "fragment-cache": "^0.2.1", + "kind-of": "^6.0.2", + "nanomatch": "^1.2.9", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.2" + } + }, + "mimic-fn": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-1.2.0.tgz", + "integrity": "sha512-jf84uxzwiuiIVKiOLpfYk7N46TSy8ubTonmneY9vrpHNAnp0QBt2BxWV9dO3/j+BoVAb+a5G6YDPW3M5HOdMWQ==", + "dev": true + }, + "minimatch": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz", + "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "0.0.8", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz", + "integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=", + "dev": true + }, + "mixin-deep": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/mixin-deep/-/mixin-deep-1.3.1.tgz", + "integrity": "sha512-8ZItLHeEgaqEvd5lYBXfm4EZSFCX29Jb9K+lAHhDKzReKBQKj3R+7NOF6tjqYi9t4oI8VUfaWITJQm86wnXGNQ==", + "dev": true, + "optional": true, + "requires": { + "for-in": "^1.0.2", + "is-extendable": "^1.0.1" + }, + "dependencies": { + "is-extendable": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/is-extendable/-/is-extendable-1.0.1.tgz", + "integrity": "sha512-arnXMxT1hhoKo9k1LZdmlNyJdDDfy2v0fXjFlmok4+i8ul/6WlbVge9bhM74OpNPQPMGUToDtz+KXa1PneJxOA==", + "dev": true, + "optional": true, + "requires": { + "is-plain-object": "^2.0.4" + } + } + } + }, + "mkdirp": { + "version": "0.5.1", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz", + "integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=", + "dev": true, + "requires": { + "minimist": "0.0.8" + } + }, + "ms": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", + "integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=", + "dev": true + }, + "mute-stream": { + "version": "0.0.7", + "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz", + "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s=", + "dev": true + }, + "nan": { + "version": "2.14.0", + "resolved": "https://registry.npmjs.org/nan/-/nan-2.14.0.tgz", + "integrity": "sha512-INOFj37C7k3AfaNTtX8RhsTw7qRy7eLET14cROi9+5HAVbbHuIWUHEauBv5qT4Av2tWasiTY1Jw6puUNqRJXQg==", + "dev": true, + "optional": true + }, + "nanomatch": { + "version": "1.2.13", + "resolved": "https://registry.npmjs.org/nanomatch/-/nanomatch-1.2.13.tgz", + "integrity": "sha512-fpoe2T0RbHwBTBUOftAfBPaDEi06ufaUai0mE6Yn1kacc3SnTErfb/h+X94VXzI64rKFHYImXSvdwGGCmwOqCA==", + "dev": true, + "optional": true, + "requires": { + "arr-diff": "^4.0.0", + "array-unique": "^0.3.2", + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "fragment-cache": "^0.2.1", + "is-windows": "^1.0.2", + "kind-of": "^6.0.2", + "object.pick": "^1.3.0", + "regex-not": "^1.0.0", + "snapdragon": "^0.8.1", + "to-regex": "^3.0.1" + } + }, + "natural-compare": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/natural-compare/-/natural-compare-1.4.0.tgz", + "integrity": "sha1-Sr6/7tdUHywnrPspvbvRXI1bpPc=", + "dev": true + }, + "nice-try": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/nice-try/-/nice-try-1.0.5.tgz", + "integrity": "sha512-1nh45deeb5olNY7eX82BkPO7SSxR5SSYJiPTrTdFUVYwAl8CKMA5N9PjTYkHiRjisVcxcQ1HXdLhx2qxxJzLNQ==", + "dev": true + }, + "node-releases": { + "version": "1.1.23", + "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.23.tgz", + "integrity": "sha512-uq1iL79YjfYC0WXoHbC/z28q/9pOl8kSHaXdWmAAc8No+bDwqkZbzIJz55g/MUsPgSGm9LZ7QSUbzTcH5tz47w==", + "dev": true, + "requires": { + "semver": "^5.3.0" + } + }, + "normalize-package-data": { + "version": "2.5.0", + "resolved": "https://registry.npmjs.org/normalize-package-data/-/normalize-package-data-2.5.0.tgz", + "integrity": "sha512-/5CMN3T0R4XTj4DcGaexo+roZSdSFW/0AOOTROrjxzCG1wrWXEsGbRKevjlIL+ZDE4sZlJr5ED4YW0yqmkK+eA==", + "dev": true, + "requires": { + "hosted-git-info": "^2.1.4", + "resolve": "^1.10.0", + "semver": "2 || 3 || 4 || 5", + "validate-npm-package-license": "^3.0.1" + } + }, + "normalize-path": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-3.0.0.tgz", + "integrity": "sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA==", + "dev": true, + "optional": true + }, + "object-assign": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/object-assign/-/object-assign-4.1.1.tgz", + "integrity": "sha1-IQmtx5ZYh8/AXLvUQsrIv7s2CGM=", + "dev": true + }, + "object-copy": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/object-copy/-/object-copy-0.1.0.tgz", + "integrity": "sha1-fn2Fi3gb18mRpBupde04EnVOmYw=", + "dev": true, + "optional": true, + "requires": { + "copy-descriptor": "^0.1.0", + "define-property": "^0.2.5", + "kind-of": "^3.0.3" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "object-keys": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/object-keys/-/object-keys-1.1.1.tgz", + "integrity": "sha512-NuAESUOUMrlIXOfHKzD6bpPu3tYt3xvjNdRIQ+FeT0lNb4K8WR70CaDxhuNguS2XG+GjkyMwOzsN5ZktImfhLA==", + "dev": true + }, + "object-visit": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/object-visit/-/object-visit-1.0.1.tgz", + "integrity": "sha1-95xEk68MU3e1n+OdOV5BBC3QRbs=", + "dev": true, + "optional": true, + "requires": { + "isobject": "^3.0.0" + } + }, + "object.assign": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/object.assign/-/object.assign-4.1.0.tgz", + "integrity": "sha512-exHJeq6kBKj58mqGyTQ9DFvrZC/eR6OwxzoM9YRoGBqrXYonaFyGiFMuc9VZrXf7DarreEwMpurG3dd+CNyW5w==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "function-bind": "^1.1.1", + "has-symbols": "^1.0.0", + "object-keys": "^1.0.11" + } + }, + "object.entries": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/object.entries/-/object.entries-1.1.0.tgz", + "integrity": "sha512-l+H6EQ8qzGRxbkHOd5I/aHRhHDKoQXQ8g0BYt4uSweQU1/J6dZUOyWh9a2Vky35YCKjzmgxOzta2hH6kf9HuXA==", + "dev": true, + "requires": { + "define-properties": "^1.1.3", + "es-abstract": "^1.12.0", + "function-bind": "^1.1.1", + "has": "^1.0.3" + } + }, + "object.fromentries": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/object.fromentries/-/object.fromentries-2.0.0.tgz", + "integrity": "sha512-9iLiI6H083uiqUuvzyY6qrlmc/Gz8hLQFOcb/Ri/0xXFkSNS3ctV+CbE6yM2+AnkYfOB3dGjdzC0wrMLIhQICA==", + "dev": true, + "requires": { + "define-properties": "^1.1.2", + "es-abstract": "^1.11.0", + "function-bind": "^1.1.1", + "has": "^1.0.1" + } + }, + "object.pick": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/object.pick/-/object.pick-1.3.0.tgz", + "integrity": "sha1-h6EKxMFpS9Lhy/U1kaZhQftd10c=", + "dev": true, + "optional": true, + "requires": { + "isobject": "^3.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "onetime": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-2.0.1.tgz", + "integrity": "sha1-BnQoIw/WdEOyeUsiu6UotoZ5YtQ=", + "dev": true, + "requires": { + "mimic-fn": "^1.0.0" + } + }, + "optionator": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/optionator/-/optionator-0.8.2.tgz", + "integrity": "sha1-NkxeQJ0/TWMB1sC0wFu6UBgK62Q=", + "dev": true, + "requires": { + "deep-is": "~0.1.3", + "fast-levenshtein": "~2.0.4", + "levn": "~0.3.0", + "prelude-ls": "~1.1.2", + "type-check": "~0.3.2", + "wordwrap": "~1.0.0" + } + }, + "os-tmpdir": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/os-tmpdir/-/os-tmpdir-1.0.2.tgz", + "integrity": "sha1-u+Z0BseaqFxc/sdm/lc0VV36EnQ=", + "dev": true + }, + "output-file-sync": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/output-file-sync/-/output-file-sync-2.0.1.tgz", + "integrity": "sha512-mDho4qm7WgIXIGf4eYU1RHN2UU5tPfVYVSRwDJw0uTmj35DQUt/eNp19N7v6T3SrR0ESTEf2up2CGO73qI35zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.11", + "is-plain-obj": "^1.1.0", + "mkdirp": "^0.5.1" + } + }, + "p-limit": { + "version": "1.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-1.3.0.tgz", + "integrity": "sha512-vvcXsLAJ9Dr5rQOPk7toZQZJApBl2K4J6dANSsEuh6QI41JYcsS/qhTGa9ErIUUgK3WNQoJYvylxvjqmiqEA9Q==", + "dev": true, + "requires": { + "p-try": "^1.0.0" + } + }, + "p-locate": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-2.0.0.tgz", + "integrity": "sha1-IKAQOyIqcMj9OcwuWAaA893l7EM=", + "dev": true, + "requires": { + "p-limit": "^1.1.0" + } + }, + "p-try": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-1.0.0.tgz", + "integrity": "sha1-y8ec26+P1CKOE/Yh8rGiN8GyB7M=", + "dev": true + }, + "parent-module": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/parent-module/-/parent-module-1.0.1.tgz", + "integrity": "sha512-GQ2EWRpQV8/o+Aw8YqtfZZPfNRWZYkbidE9k5rpl/hC3vtHHBfGm2Ifi6qWV+coDGkrUKZAxE3Lot5kcsRlh+g==", + "dev": true, + "requires": { + "callsites": "^3.0.0" + } + }, + "parse-json": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/parse-json/-/parse-json-2.2.0.tgz", + "integrity": "sha1-9ID0BDTvgHQfhGkJn43qGPVaTck=", + "dev": true, + "requires": { + "error-ex": "^1.2.0" + } + }, + "pascalcase": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/pascalcase/-/pascalcase-0.1.1.tgz", + "integrity": "sha1-s2PlXoAGym/iF4TS2yK9FdeRfxQ=", + "dev": true, + "optional": true + }, + "path-dirname": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-dirname/-/path-dirname-1.0.2.tgz", + "integrity": "sha1-zDPSTVJeCZpTiMAzbG4yuRYGCeA=", + "dev": true, + "optional": true + }, + "path-exists": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-3.0.0.tgz", + "integrity": "sha1-zg6+ql94yxiSXqfYENe1mwEP1RU=", + "dev": true + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=", + "dev": true + }, + "path-is-inside": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/path-is-inside/-/path-is-inside-1.0.2.tgz", + "integrity": "sha1-NlQX3t5EQw0cEa9hAn+s8HS9/FM=", + "dev": true + }, + "path-key": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-2.0.1.tgz", + "integrity": "sha1-QRyttXTFoUDTpLGRDUDYDMn0C0A=", + "dev": true + }, + "path-parse": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz", + "integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==", + "dev": true + }, + "path-type": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/path-type/-/path-type-2.0.0.tgz", + "integrity": "sha1-8BLMuEFbcJb8LaoQVMPXI4lZTHM=", + "dev": true, + "requires": { + "pify": "^2.0.0" + } + }, + "pify": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/pify/-/pify-2.3.0.tgz", + "integrity": "sha1-7RQaasBDqEnqWISY59yosVMw6Qw=", + "dev": true + }, + "pkg-dir": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-2.0.0.tgz", + "integrity": "sha1-9tXREJ4Z1j7fQo4L1X4Sd3YVM0s=", + "dev": true, + "requires": { + "find-up": "^2.1.0" + } + }, + "posix-character-classes": { + "version": "0.1.1", + "resolved": "https://registry.npmjs.org/posix-character-classes/-/posix-character-classes-0.1.1.tgz", + "integrity": "sha1-AerA/jta9xoqbAL+q7jB/vfgDqs=", + "dev": true, + "optional": true + }, + "prelude-ls": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/prelude-ls/-/prelude-ls-1.1.2.tgz", + "integrity": "sha1-IZMqVJ9eUv/ZqCf1cOBL5iqX2lQ=", + "dev": true + }, + "private": { + "version": "0.1.8", + "resolved": "https://registry.npmjs.org/private/-/private-0.1.8.tgz", + "integrity": "sha512-VvivMrbvd2nKkiG38qjULzlc+4Vx4wm/whI9pQD35YrARNnhxeiRktSOhSukRLFNlzg6Br/cJPet5J/u19r/mg==", + "dev": true + }, + "process-nextick-args": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", + "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==", + "dev": true, + "optional": true + }, + "progress": { + "version": "2.0.3", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", + "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "dev": true + }, + "prop-types": { + "version": "15.7.2", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", + "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "dev": true, + "requires": { + "loose-envify": "^1.4.0", + "object-assign": "^4.1.1", + "react-is": "^16.8.1" + } + }, + "punycode": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz", + "integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==", + "dev": true + }, + "react": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react/-/react-16.8.6.tgz", + "integrity": "sha512-pC0uMkhLaHm11ZSJULfOBqV4tIZkx87ZLvbbQYunNixAAvjnC+snJCg0XQXn9VIsttVsbZP/H/ewzgsd5fxKXw==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-dom": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-dom/-/react-dom-16.8.6.tgz", + "integrity": "sha512-1nL7PIq9LTL3fthPqwkvr2zY7phIPjYrT0jp4HjyEQrEROnw4dG41VVwi/wfoCneoleqrNX7iAD+pXebJZwrwA==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1", + "prop-types": "^15.6.2", + "scheduler": "^0.13.6" + } + }, + "react-is": { + "version": "16.8.6", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.8.6.tgz", + "integrity": "sha512-aUk3bHfZ2bRSVFFbbeVS4i+lNPZr3/WM5jT2J5omUVV1zzcs1nAaf3l51ctA5FFvCRbhrH0bdAsRRQddFJZPtA==", + "dev": true + }, + "read-pkg": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg/-/read-pkg-2.0.0.tgz", + "integrity": "sha1-jvHAYjxqbbDcZxPEv6xGMysjaPg=", + "dev": true, + "requires": { + "load-json-file": "^2.0.0", + "normalize-package-data": "^2.3.2", + "path-type": "^2.0.0" + } + }, + "read-pkg-up": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/read-pkg-up/-/read-pkg-up-2.0.0.tgz", + "integrity": "sha1-a3KoBImE4MQeeVEP1en6mbO1Sb4=", + "dev": true, + "requires": { + "find-up": "^2.0.0", + "read-pkg": "^2.0.0" + } + }, + "readable-stream": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.6.tgz", + "integrity": "sha512-tQtKA9WIAhBF3+VLAseyMqZeBjW0AHJoxOtYqSUZNJxauErmLbVm2FW1y+J/YA9dUrAC39ITejlZWhVIwawkKw==", + "dev": true, + "optional": true, + "requires": { + "core-util-is": "~1.0.0", + "inherits": "~2.0.3", + "isarray": "~1.0.0", + "process-nextick-args": "~2.0.0", + "safe-buffer": "~5.1.1", + "string_decoder": "~1.1.1", + "util-deprecate": "~1.0.1" + } + }, + "readdirp": { + "version": "2.2.1", + "resolved": "https://registry.npmjs.org/readdirp/-/readdirp-2.2.1.tgz", + "integrity": "sha512-1JU/8q+VgFZyxwrJ+SVIOsh+KywWGpds3NTqikiKpDMZWScmAYyKIgqkO+ARvNWJfXeXR1zxz7aHF4u4CyH6vQ==", + "dev": true, + "optional": true, + "requires": { + "graceful-fs": "^4.1.11", + "micromatch": "^3.1.10", + "readable-stream": "^2.0.2" + } + }, + "regenerate": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/regenerate/-/regenerate-1.4.0.tgz", + "integrity": "sha512-1G6jJVDWrt0rK99kBjvEtziZNCICAuvIPkSiUFIQxVP06RCVpq3dmDo2oi6ABpYaDYaTRr67BEhL8r1wgEZZKg==", + "dev": true + }, + "regenerate-unicode-properties": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz", + "integrity": "sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA==", + "dev": true, + "requires": { + "regenerate": "^1.4.0" + } + }, + "regenerator-runtime": { + "version": "0.13.2", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.2.tgz", + "integrity": "sha512-S/TQAZJO+D3m9xeN1WTI8dLKBBiRgXBlTJvbWjCThHWZj9EvHK70Ff50/tYj2J/fvBY6JtFVwRuazHN2E7M9BA==", + "dev": true + }, + "regenerator-transform": { + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/regenerator-transform/-/regenerator-transform-0.14.0.tgz", + "integrity": "sha512-rtOelq4Cawlbmq9xuMR5gdFmv7ku/sFoB7sRiywx7aq53bc52b4j6zvH7Te1Vt/X2YveDKnCGUbioieU7FEL3w==", + "dev": true, + "requires": { + "private": "^0.1.6" + } + }, + "regex-not": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/regex-not/-/regex-not-1.0.2.tgz", + "integrity": "sha512-J6SDjUgDxQj5NusnOtdFxDwN/+HWykR8GELwctJ7mdqhcyy1xEc4SRFHUXvxTp661YaVKAjfRLZ9cCqS6tn32A==", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^3.0.2", + "safe-regex": "^1.1.0" + } + }, + "regexp-tree": { + "version": "0.1.10", + "resolved": "https://registry.npmjs.org/regexp-tree/-/regexp-tree-0.1.10.tgz", + "integrity": "sha512-K1qVSbcedffwuIslMwpe6vGlj+ZXRnGkvjAtFHfDZZZuEdA/h0dxljAPu9vhUo6Rrx2U2AwJ+nSQ6hK+lrP5MQ==", + "dev": true + }, + "regexpp": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/regexpp/-/regexpp-2.0.1.tgz", + "integrity": "sha512-lv0M6+TkDVniA3aD1Eg0DVpfU/booSu7Eev3TDO/mZKHBfVjgCGTV4t4buppESEYDtkArYFOxTJWv6S5C+iaNw==", + "dev": true + }, + "regexpu-core": { + "version": "4.5.4", + "resolved": "https://registry.npmjs.org/regexpu-core/-/regexpu-core-4.5.4.tgz", + "integrity": "sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ==", + "dev": true, + "requires": { + "regenerate": "^1.4.0", + "regenerate-unicode-properties": "^8.0.2", + "regjsgen": "^0.5.0", + "regjsparser": "^0.6.0", + "unicode-match-property-ecmascript": "^1.0.4", + "unicode-match-property-value-ecmascript": "^1.1.0" + } + }, + "regjsgen": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/regjsgen/-/regjsgen-0.5.0.tgz", + "integrity": "sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA==", + "dev": true + }, + "regjsparser": { + "version": "0.6.0", + "resolved": "https://registry.npmjs.org/regjsparser/-/regjsparser-0.6.0.tgz", + "integrity": "sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ==", + "dev": true, + "requires": { + "jsesc": "~0.5.0" + }, + "dependencies": { + "jsesc": { + "version": "0.5.0", + "resolved": "https://registry.npmjs.org/jsesc/-/jsesc-0.5.0.tgz", + "integrity": "sha1-597mbjXW/Bb3EP6R1c9p9w8IkR0=", + "dev": true + } + } + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha1-wkvOKig62tW8P1jg1IJJuSN52O8=", + "dev": true, + "optional": true + }, + "repeat-element": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/repeat-element/-/repeat-element-1.1.3.tgz", + "integrity": "sha512-ahGq0ZnV5m5XtZLMb+vP76kcAM5nkLqk0lpqAuojSKGgQtn4eRi4ZZGm2olo2zKFH+sMsWaqOCW1dqAnOru72g==", + "dev": true, + "optional": true + }, + "repeat-string": { + "version": "1.6.1", + "resolved": "https://registry.npmjs.org/repeat-string/-/repeat-string-1.6.1.tgz", + "integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=", + "dev": true, + "optional": true + }, + "resolve": { + "version": "1.11.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.11.1.tgz", + "integrity": "sha512-vIpgF6wfuJOZI7KKKSP+HmiKggadPQAdsp5HiC1mvqnfp0gF1vdwgBWZIdrVft9pgqoMFQN+R7BSWZiBxx+BBw==", + "dev": true, + "requires": { + "path-parse": "^1.0.6" + } + }, + "resolve-from": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-4.0.0.tgz", + "integrity": "sha512-pb/MYmXstAkysRFx8piNI1tGFNQIFA3vkE3Gq4EuA1dF6gHp/+vgZqsCGJapvy8N3Q+4o7FwvquPJcnZ7RYy4g==", + "dev": true + }, + "resolve-url": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/resolve-url/-/resolve-url-0.2.1.tgz", + "integrity": "sha1-LGN/53yJOv0qZj/iGqkIAGjiBSo=", + "dev": true, + "optional": true + }, + "restore-cursor": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/restore-cursor/-/restore-cursor-2.0.0.tgz", + "integrity": "sha1-n37ih/gv0ybU/RYpI9YhKe7g368=", + "dev": true, + "requires": { + "onetime": "^2.0.0", + "signal-exit": "^3.0.2" + } + }, + "ret": { + "version": "0.1.15", + "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz", + "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg==", + "dev": true, + "optional": true + }, + "rimraf": { + "version": "2.6.3", + "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz", + "integrity": "sha512-mwqeW5XsA2qAejG46gYdENaxXjx9onRNCfn7L0duuP4hCuTIi/QO7PDK07KJfp1d+izWPrzEJDcSqBa0OZQriA==", + "dev": true, + "requires": { + "glob": "^7.1.3" + } + }, + "run-async": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/run-async/-/run-async-2.3.0.tgz", + "integrity": "sha1-A3GrSuC91yDUFm19/aZP96RFpsA=", + "dev": true, + "requires": { + "is-promise": "^2.1.0" + } + }, + "rxjs": { + "version": "6.5.2", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.5.2.tgz", + "integrity": "sha512-HUb7j3kvb7p7eCUHE3FqjoDsC1xfZQ4AHFWfTKSpZ+sAhhz5X1WX0ZuUqWbzB2QhSLp3DoLUG+hMdEDKqWo2Zg==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "safe-buffer": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz", + "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==", + "dev": true + }, + "safe-regex": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz", + "integrity": "sha1-QKNmnzsHfR6UPURinhV91IAjvy4=", + "dev": true, + "optional": true, + "requires": { + "ret": "~0.1.10" + } + }, + "safer-buffer": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz", + "integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==", + "dev": true + }, + "scheduler": { + "version": "0.13.6", + "resolved": "https://registry.npmjs.org/scheduler/-/scheduler-0.13.6.tgz", + "integrity": "sha512-IWnObHt413ucAYKsD9J1QShUKkbKLQQHdxRyw73sw4FN26iWr3DY/H34xGPe4nmL1DwXyWmSWmMrA9TfQbE/XQ==", + "dev": true, + "requires": { + "loose-envify": "^1.1.0", + "object-assign": "^4.1.1" + } + }, + "semver": { + "version": "5.7.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz", + "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==", + "dev": true + }, + "set-value": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-2.0.0.tgz", + "integrity": "sha512-hw0yxk9GT/Hr5yJEYnHNKYXkIA8mVJgd9ditYZCe16ZczcaELYYcfvaXesNACk2O8O0nTiPQcQhGUQj8JLzeeg==", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.3", + "split-string": "^3.0.1" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "shebang-command": { + "version": "1.2.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-1.2.0.tgz", + "integrity": "sha1-RKrGW2lbAzmJaMOfNj/uXer98eo=", + "dev": true, + "requires": { + "shebang-regex": "^1.0.0" + } + }, + "shebang-regex": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-1.0.0.tgz", + "integrity": "sha1-2kL0l0DAtC2yypcoVxyxkMmO/qM=", + "dev": true + }, + "signal-exit": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.2.tgz", + "integrity": "sha1-tf3AjxKH6hF4Yo5BXiUTK3NkbG0=", + "dev": true + }, + "slash": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/slash/-/slash-2.0.0.tgz", + "integrity": "sha512-ZYKh3Wh2z1PpEXWr0MpSBZ0V6mZHAQfYevttO11c51CaWjGTaadiKZ+wVt1PbMlDV5qhMFslpZCemhwOK7C89A==", + "dev": true + }, + "slice-ansi": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/slice-ansi/-/slice-ansi-2.1.0.tgz", + "integrity": "sha512-Qu+VC3EwYLldKa1fCxuuvULvSJOKEgk9pi8dZeCVK7TqBfUNTH4sFkk4joj8afVSfAYgJoSOetjx9QWOJ5mYoQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.0", + "astral-regex": "^1.0.0", + "is-fullwidth-code-point": "^2.0.0" + } + }, + "snapdragon": { + "version": "0.8.2", + "resolved": "https://registry.npmjs.org/snapdragon/-/snapdragon-0.8.2.tgz", + "integrity": "sha512-FtyOnWN/wCHTVXOMwvSv26d+ko5vWlIDD6zoUJ7LW8vh+ZBC8QdljveRP+crNrtBwioEUWy/4dMtbBjA4ioNlg==", + "dev": true, + "optional": true, + "requires": { + "base": "^0.11.1", + "debug": "^2.2.0", + "define-property": "^0.2.5", + "extend-shallow": "^2.0.1", + "map-cache": "^0.2.2", + "source-map": "^0.5.6", + "source-map-resolve": "^0.5.0", + "use": "^3.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + }, + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + } + } + }, + "snapdragon-node": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/snapdragon-node/-/snapdragon-node-2.1.1.tgz", + "integrity": "sha512-O27l4xaMYt/RSQ5TR3vpWCAB5Kb/czIcqUFOM/C4fYcLnbZUc1PkjTAMjof2pBWaSTwOUd6qUHcFGVGj7aIwnw==", + "dev": true, + "optional": true, + "requires": { + "define-property": "^1.0.0", + "isobject": "^3.0.0", + "snapdragon-util": "^3.0.1" + }, + "dependencies": { + "define-property": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-1.0.0.tgz", + "integrity": "sha1-dp66rz9KY6rTr56NMEybvnm/sOY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^1.0.0" + } + }, + "is-accessor-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-accessor-descriptor/-/is-accessor-descriptor-1.0.0.tgz", + "integrity": "sha512-m5hnHTkcVsPfqx3AKlyttIPb7J+XykHvJP2B9bZDjlhLIoEq4XoK64Vg7boZlVWYK6LUY94dYPEE7Lh0ZkZKcQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-data-descriptor": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/is-data-descriptor/-/is-data-descriptor-1.0.0.tgz", + "integrity": "sha512-jbRXy1FmtAoCjQkVmIVYwuuqDFUbaOeDjmed1tOGPrsMhtJA4rD9tkgA0F1qJ3gRFRXcHYVkdeaP50Q5rE/jLQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^6.0.0" + } + }, + "is-descriptor": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/is-descriptor/-/is-descriptor-1.0.2.tgz", + "integrity": "sha512-2eis5WqQGV7peooDyLmNEPUrps9+SXX5c9pL3xEB+4e9HnGuDa7mB7kHxHw4CbqS9k1T2hOH3miL8n8WtiYVtg==", + "dev": true, + "optional": true, + "requires": { + "is-accessor-descriptor": "^1.0.0", + "is-data-descriptor": "^1.0.0", + "kind-of": "^6.0.2" + } + } + } + }, + "snapdragon-util": { + "version": "3.0.1", + "resolved": "https://registry.npmjs.org/snapdragon-util/-/snapdragon-util-3.0.1.tgz", + "integrity": "sha512-mbKkMdQKsjX4BAL4bRYTj21edOf8cN7XHdYUJEe+Zn99hVEYcMvKPct1IqNe7+AZPirn8BCDOQBHQZknqmKlZQ==", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.2.0" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "source-map": { + "version": "0.5.7", + "resolved": "https://registry.npmjs.org/source-map/-/source-map-0.5.7.tgz", + "integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=", + "dev": true + }, + "source-map-resolve": { + "version": "0.5.2", + "resolved": "https://registry.npmjs.org/source-map-resolve/-/source-map-resolve-0.5.2.tgz", + "integrity": "sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA==", + "dev": true, + "optional": true, + "requires": { + "atob": "^2.1.1", + "decode-uri-component": "^0.2.0", + "resolve-url": "^0.2.1", + "source-map-url": "^0.4.0", + "urix": "^0.1.0" + } + }, + "source-map-url": { + "version": "0.4.0", + "resolved": "https://registry.npmjs.org/source-map-url/-/source-map-url-0.4.0.tgz", + "integrity": "sha1-PpNdfd1zYxuXZZlW1VEo6HtQhKM=", + "dev": true, + "optional": true + }, + "spdx-correct": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/spdx-correct/-/spdx-correct-3.1.0.tgz", + "integrity": "sha512-lr2EZCctC2BNR7j7WzJ2FpDznxky1sjfxvvYEyzxNyb6lZXHODmEoJeFu4JupYlkfha1KZpJyoqiJ7pgA1qq8Q==", + "dev": true, + "requires": { + "spdx-expression-parse": "^3.0.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-exceptions": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/spdx-exceptions/-/spdx-exceptions-2.2.0.tgz", + "integrity": "sha512-2XQACfElKi9SlVb1CYadKDXvoajPgBVPn/gOQLrTvHdElaVhr7ZEbqJaRnJLVNeaI4cMEAgVCeBMKF6MWRDCRA==", + "dev": true + }, + "spdx-expression-parse": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/spdx-expression-parse/-/spdx-expression-parse-3.0.0.tgz", + "integrity": "sha512-Yg6D3XpRD4kkOmTpdgbUiEJFKghJH03fiC1OPll5h/0sO6neh2jqRDVHOQ4o/LMea0tgCkbMgea5ip/e+MkWyg==", + "dev": true, + "requires": { + "spdx-exceptions": "^2.1.0", + "spdx-license-ids": "^3.0.0" + } + }, + "spdx-license-ids": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/spdx-license-ids/-/spdx-license-ids-3.0.4.tgz", + "integrity": "sha512-7j8LYJLeY/Yb6ACbQ7F76qy5jHkp0U6jgBfJsk97bwWlVUnUWsAgpyaCvo17h0/RQGnQ036tVDomiwoI4pDkQA==", + "dev": true + }, + "split-string": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/split-string/-/split-string-3.1.0.tgz", + "integrity": "sha512-NzNVhJDYpwceVVii8/Hu6DKfD2G+NrQHlS/V/qgv763EYudVwEcMQNxd2lh+0VrUByXN/oJkl5grOhYWvQUYiw==", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^3.0.0" + } + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=", + "dev": true + }, + "static-extend": { + "version": "0.1.2", + "resolved": "https://registry.npmjs.org/static-extend/-/static-extend-0.1.2.tgz", + "integrity": "sha1-YICcOcv/VTNyJv1eC1IPNB8ftcY=", + "dev": true, + "optional": true, + "requires": { + "define-property": "^0.2.5", + "object-copy": "^0.1.0" + }, + "dependencies": { + "define-property": { + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/define-property/-/define-property-0.2.5.tgz", + "integrity": "sha1-w1se+RjsPJkPmlvFe+BKrOxcgRY=", + "dev": true, + "optional": true, + "requires": { + "is-descriptor": "^0.1.0" + } + } + } + }, + "string-width": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-2.1.1.tgz", + "integrity": "sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw==", + "dev": true, + "requires": { + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^4.0.0" + } + }, + "string_decoder": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", + "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", + "dev": true, + "optional": true, + "requires": { + "safe-buffer": "~5.1.0" + } + }, + "strip-ansi": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-4.0.0.tgz", + "integrity": "sha1-qEeQIusaw2iocTibY1JixQXuNo8=", + "dev": true, + "requires": { + "ansi-regex": "^3.0.0" + } + }, + "strip-bom": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-3.0.0.tgz", + "integrity": "sha1-IzTBjpx1n3vdVv3vfprj1YjmjtM=", + "dev": true + }, + "strip-json-comments": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-2.0.1.tgz", + "integrity": "sha1-PFMZQukIwml8DsNEhYwobHygpgo=", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "table": { + "version": "5.4.0", + "resolved": "https://registry.npmjs.org/table/-/table-5.4.0.tgz", + "integrity": "sha512-nHFDrxmbrkU7JAFKqKbDJXfzrX2UBsWmrieXFTGxiI5e4ncg3VqsZeI4EzNmX0ncp4XNGVeoxIWJXfCIXwrsvw==", + "dev": true, + "requires": { + "ajv": "^6.9.1", + "lodash": "^4.17.11", + "slice-ansi": "^2.1.0", + "string-width": "^3.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz", + "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==", + "dev": true + }, + "string-width": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", + "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==", + "dev": true, + "requires": { + "emoji-regex": "^7.0.1", + "is-fullwidth-code-point": "^2.0.0", + "strip-ansi": "^5.1.0" + } + }, + "strip-ansi": { + "version": "5.2.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz", + "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==", + "dev": true, + "requires": { + "ansi-regex": "^4.1.0" + } + } + } + }, + "text-table": { + "version": "0.2.0", + "resolved": "https://registry.npmjs.org/text-table/-/text-table-0.2.0.tgz", + "integrity": "sha1-f17oI66AUgfACvLfSoTsP8+lcLQ=", + "dev": true + }, + "through": { + "version": "2.3.8", + "resolved": "https://registry.npmjs.org/through/-/through-2.3.8.tgz", + "integrity": "sha1-DdTJ/6q8NXlgsbckEV1+Doai4fU=", + "dev": true + }, + "tmp": { + "version": "0.0.33", + "resolved": "https://registry.npmjs.org/tmp/-/tmp-0.0.33.tgz", + "integrity": "sha512-jRCJlojKnZ3addtTOjdIqoRuPEKBvNXcGYqzO6zWZX8KfKEpnGY5jfggJQ3EjKuu8D4bJRr0y+cYJFmYbImXGw==", + "dev": true, + "requires": { + "os-tmpdir": "~1.0.2" + } + }, + "to-fast-properties": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/to-fast-properties/-/to-fast-properties-2.0.0.tgz", + "integrity": "sha1-3F5pjL0HkmW8c+A3doGk5Og/YW4=", + "dev": true + }, + "to-object-path": { + "version": "0.3.0", + "resolved": "https://registry.npmjs.org/to-object-path/-/to-object-path-0.3.0.tgz", + "integrity": "sha1-KXWIt7Dn4KwI4E5nL4XB9JmeF68=", + "dev": true, + "optional": true, + "requires": { + "kind-of": "^3.0.2" + }, + "dependencies": { + "kind-of": { + "version": "3.2.2", + "resolved": "https://registry.npmjs.org/kind-of/-/kind-of-3.2.2.tgz", + "integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=", + "dev": true, + "optional": true, + "requires": { + "is-buffer": "^1.1.5" + } + } + } + }, + "to-regex": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/to-regex/-/to-regex-3.0.2.tgz", + "integrity": "sha512-FWtleNAtZ/Ki2qtqej2CXTOayOH9bHDQF+Q48VpWyDXjbYxA4Yz8iDB31zXOBUlOHHKidDbqGVrTUvQMPmBGBw==", + "dev": true, + "optional": true, + "requires": { + "define-property": "^2.0.2", + "extend-shallow": "^3.0.2", + "regex-not": "^1.0.2", + "safe-regex": "^1.1.0" + } + }, + "to-regex-range": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/to-regex-range/-/to-regex-range-2.1.1.tgz", + "integrity": "sha1-fIDBe53+vlmeJzZ+DU3VWQFB2zg=", + "dev": true, + "optional": true, + "requires": { + "is-number": "^3.0.0", + "repeat-string": "^1.6.1" + } + }, + "trim-right": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/trim-right/-/trim-right-1.0.1.tgz", + "integrity": "sha1-yy4SAwZ+DI3h9hQJS5/kVwTqYAM=", + "dev": true + }, + "tslib": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz", + "integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==", + "dev": true + }, + "type-check": { + "version": "0.3.2", + "resolved": "https://registry.npmjs.org/type-check/-/type-check-0.3.2.tgz", + "integrity": "sha1-WITKtRLPHTVeP7eE8wgEsrUg23I=", + "dev": true, + "requires": { + "prelude-ls": "~1.1.2" + } + }, + "unicode-canonical-property-names-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-1.0.4.tgz", + "integrity": "sha512-jDrNnXWHd4oHiTZnx/ZG7gtUTVp+gCcTTKr8L0HjlwphROEW3+Him+IpvC+xcJEFegapiMZyZe02CyuOnRmbnQ==", + "dev": true + }, + "unicode-match-property-ecmascript": { + "version": "1.0.4", + "resolved": "https://registry.npmjs.org/unicode-match-property-ecmascript/-/unicode-match-property-ecmascript-1.0.4.tgz", + "integrity": "sha512-L4Qoh15vTfntsn4P1zqnHulG0LdXgjSO035fEpdtp6YxXhMT51Q6vgM5lYdG/5X3MjS+k/Y9Xw4SFCY9IkR0rg==", + "dev": true, + "requires": { + "unicode-canonical-property-names-ecmascript": "^1.0.4", + "unicode-property-aliases-ecmascript": "^1.0.4" + } + }, + "unicode-match-property-value-ecmascript": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz", + "integrity": "sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g==", + "dev": true + }, + "unicode-property-aliases-ecmascript": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/unicode-property-aliases-ecmascript/-/unicode-property-aliases-ecmascript-1.0.5.tgz", + "integrity": "sha512-L5RAqCfXqAwR3RriF8pM0lU0w4Ryf/GgzONwi6KnL1taJQa7x1TCxdJnILX59WIGOwR57IVxn7Nej0fz1Ny6fw==", + "dev": true + }, + "union-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/union-value/-/union-value-1.0.0.tgz", + "integrity": "sha1-XHHDTLW61dzr4+oM0IIHulqhrqQ=", + "dev": true, + "optional": true, + "requires": { + "arr-union": "^3.1.0", + "get-value": "^2.0.6", + "is-extendable": "^0.1.1", + "set-value": "^0.4.3" + }, + "dependencies": { + "extend-shallow": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extend-shallow/-/extend-shallow-2.0.1.tgz", + "integrity": "sha1-Ua99YUrZqfYQ6huvu5idaxxWiQ8=", + "dev": true, + "optional": true, + "requires": { + "is-extendable": "^0.1.0" + } + }, + "set-value": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/set-value/-/set-value-0.4.3.tgz", + "integrity": "sha1-fbCPnT0i3H945Trzw79GZuzfzPE=", + "dev": true, + "optional": true, + "requires": { + "extend-shallow": "^2.0.1", + "is-extendable": "^0.1.1", + "is-plain-object": "^2.0.1", + "to-object-path": "^0.3.0" + } + } + } + }, + "unset-value": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/unset-value/-/unset-value-1.0.0.tgz", + "integrity": "sha1-g3aHP30jNRef+x5vw6jtDfyKtVk=", + "dev": true, + "optional": true, + "requires": { + "has-value": "^0.3.1", + "isobject": "^3.0.0" + }, + "dependencies": { + "has-value": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/has-value/-/has-value-0.3.1.tgz", + "integrity": "sha1-ex9YutpiyoJ+wKIHgCVlSEWZXh8=", + "dev": true, + "optional": true, + "requires": { + "get-value": "^2.0.3", + "has-values": "^0.1.4", + "isobject": "^2.0.0" + }, + "dependencies": { + "isobject": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/isobject/-/isobject-2.1.0.tgz", + "integrity": "sha1-8GVWEJaj8dou9GJy+BXIQNh+DIk=", + "dev": true, + "optional": true, + "requires": { + "isarray": "1.0.0" + } + } + } + }, + "has-values": { + "version": "0.1.4", + "resolved": "https://registry.npmjs.org/has-values/-/has-values-0.1.4.tgz", + "integrity": "sha1-bWHeldkd/Km5oCCJrThL/49it3E=", + "dev": true, + "optional": true + } + } + }, + "upath": { + "version": "1.1.2", + "resolved": "https://registry.npmjs.org/upath/-/upath-1.1.2.tgz", + "integrity": "sha512-kXpym8nmDmlCBr7nKdIx8P2jNBa+pBpIUFRnKJ4dr8htyYGJFokkr2ZvERRtUN+9SY+JqXouNgUPtv6JQva/2Q==", + "dev": true, + "optional": true + }, + "uri-js": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz", + "integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==", + "dev": true, + "requires": { + "punycode": "^2.1.0" + } + }, + "urix": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/urix/-/urix-0.1.0.tgz", + "integrity": "sha1-2pN/emLiH+wf0Y1Js1wpNQZ6bHI=", + "dev": true, + "optional": true + }, + "use": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/use/-/use-3.1.1.tgz", + "integrity": "sha512-cwESVXlO3url9YWlFW/TA9cshCEhtu7IKJ/p5soJ/gGpj7vbvFrAY/eIioQ6Dw23KjZhYgiIo8HOs1nQ2vr/oQ==", + "dev": true, + "optional": true + }, + "util-deprecate": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/util-deprecate/-/util-deprecate-1.0.2.tgz", + "integrity": "sha1-RQ1Nyfpw3nMnYvvS1KKJgUGaDM8=", + "dev": true, + "optional": true + }, + "validate-npm-package-license": { + "version": "3.0.4", + "resolved": "https://registry.npmjs.org/validate-npm-package-license/-/validate-npm-package-license-3.0.4.tgz", + "integrity": "sha512-DpKm2Ui/xN7/HQKCtpZxoRWBhZ9Z0kqtygG8XCgNQ8ZlDnxuQmWhj566j8fN4Cu3/JmbhsDo7fcAJq4s9h27Ew==", + "dev": true, + "requires": { + "spdx-correct": "^3.0.0", + "spdx-expression-parse": "^3.0.0" + } + }, + "which": { + "version": "1.3.1", + "resolved": "https://registry.npmjs.org/which/-/which-1.3.1.tgz", + "integrity": "sha512-HxJdYWq1MTIQbJ3nw0cqssHoTNU267KlrDuGZ1WYlxDStUtKUhOaJmh112/TZmHxxUfuJqPXSOm7tDyas0OSIQ==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + }, + "wordwrap": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/wordwrap/-/wordwrap-1.0.0.tgz", + "integrity": "sha1-J1hIEIkUVqQXHI0CJkQa3pDLyus=", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=", + "dev": true + }, + "write": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/write/-/write-1.0.3.tgz", + "integrity": "sha512-/lg70HAjtkUgWPVZhZcm+T4hkL8Zbtp1nFNOn3lRrxnlv50SRBv7cR7RqR+GMsd3hUXy9hWBo4CHTbFTcOYwig==", + "dev": true, + "requires": { + "mkdirp": "^0.5.1" + } + } + } +} diff --git a/package.json b/package.json index e3aa880..dd6c130 100644 --- a/package.json +++ b/package.json @@ -36,23 +36,21 @@ "react": "^15.0.0 || ^16.0.0" }, "devDependencies": { - "babel-cli": "^6.26.0", - "babel-core": "^6.26.3", - "babel-eslint": "^10.0.1", - "babel-jest": "23.6.0", - "babel-loader": "8.0.4", - "babel-plugin-import": "^1.2.1", - "babel-polyfill": "^6.26.0", - "babel-preset-env": "^1.6.1", - "babel-preset-react-app": "^3.0.0", - "babel-runtime": "^6.26.0", - "cross-env": "^5.1.4", - "eslint": "^5.6.1", + "@babel/cli": "^7.4.4", + "@babel/core": "^7.4.5", + "@babel/polyfill": "^7.4.4", + "@babel/preset-env": "^7.4.5", + "@babel/preset-react": "^7.0.0", + "@babel/runtime-corejs2": "^7.4.5", + "@babel/plugin-proposal-class-properties": "^7.4.4", + "cross-env": "^5.2.0", + "eslint": "^5.16.0", "eslint-config-airbnb": "^17.1.0", "eslint-config-defaults": "^9.0.0", - "eslint-plugin-import": "^2.8.0", - "eslint-plugin-jsx-a11y": "^6.0.2", - "eslint-plugin-react": "^7.5.1", - "lodash": "^4.17.11" + "eslint-plugin-import": "^2.17.3", + "eslint-plugin-react": "^7.13.0", + "eslint-plugin-jsx-a11y": "^6.2.1", + "react": "^16.8.6", + "react-dom": "^16.8.6" } }