diff --git a/.gitignore b/.gitignore index 0f7718c23..e22cbe74a 100644 --- a/.gitignore +++ b/.gitignore @@ -15,5 +15,6 @@ coverage # built example app dist -# secrets -config.yml +# secrets. Ignore any versions of config.yml, except for example. +*config.yml +!example-config.yml diff --git a/__tests__/actions/__snapshots__/api.js.snap b/__tests__/actions/__snapshots__/api.js.snap index 7a553df4e..3c1375d6c 100644 --- a/__tests__/actions/__snapshots__/api.js.snap +++ b/__tests__/actions/__snapshots__/api.js.snap @@ -6,6 +6,7 @@ Array [ Object { "payload": Object { "activeItinerary": 0, + "pending": 1, "routingType": "ITINERARY", "searchId": "abcd1234", }, @@ -19,6 +20,7 @@ Array [ Object { "payload": Object { "activeItinerary": 0, + "pending": 1, "routingType": "ITINERARY", "searchId": "abcd1235", }, @@ -37,6 +39,7 @@ Array [ Object { "payload": Object { "activeItinerary": 0, + "pending": 1, "routingType": "ITINERARY", "searchId": "abcd1234", }, diff --git a/__tests__/components/viewers/__snapshots__/stop-viewer.js.snap b/__tests__/components/viewers/__snapshots__/stop-viewer.js.snap index 612b1c1b7..a3c820713 100644 --- a/__tests__/components/viewers/__snapshots__/stop-viewer.js.snap +++ b/__tests__/components/viewers/__snapshots__/stop-viewer.js.snap @@ -281,24 +281,23 @@ exports[`components > viewers > stop viewer should render countdown times after } > - 00:17 + View + schedule @@ -322,10 +321,13 @@ exports[`components > viewers > stop viewer should render countdown times after className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > @@ -403,20 +405,23 @@ exports[`components > viewers > stop viewer should render countdown times after className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > viewers > stop viewer should render countdown times after title="To Location Icon" > viewers > stop viewer should render countdown times after title="To Location Icon" > viewers > stop viewer should render countdown times after "type": 3, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -791,6 +797,35 @@ exports[`components > viewers > stop viewer should render countdown times after Auto-refresh arrivals? + + + + + 00:17 + @@ -981,24 +1016,23 @@ exports[`components > viewers > stop viewer should render countdown times for st } > - 00:17 + View + schedule @@ -1022,10 +1056,13 @@ exports[`components > viewers > stop viewer should render countdown times for st className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > @@ -1103,20 +1140,23 @@ exports[`components > viewers > stop viewer should render countdown times for st className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > viewers > stop viewer should render countdown times for st title="To Location Icon" > viewers > stop viewer should render countdown times for st title="To Location Icon" > viewers > stop viewer should render countdown times for st "type": 3, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -1401,6 +1442,35 @@ exports[`components > viewers > stop viewer should render countdown times for st Auto-refresh arrivals? + + + + + 00:17 + @@ -1690,24 +1760,23 @@ exports[`components > viewers > stop viewer should render times after midnight w } > - 00:17 + View + schedule @@ -1731,10 +1800,13 @@ exports[`components > viewers > stop viewer should render times after midnight w className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > @@ -1812,20 +1884,23 @@ exports[`components > viewers > stop viewer should render times after midnight w className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > viewers > stop viewer should render times after midnight w title="To Location Icon" > viewers > stop viewer should render times after midnight w title="To Location Icon" > viewers > stop viewer should render times after midnight w "type": 3, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -2209,6 +2285,35 @@ exports[`components > viewers > stop viewer should render times after midnight w Auto-refresh arrivals? + + + + + 00:17 + @@ -2756,24 +2861,23 @@ exports[`components > viewers > stop viewer should render with OTP transit index } > - 17:50 + View + schedule @@ -2797,10 +2901,13 @@ exports[`components > viewers > stop viewer should render with OTP transit index className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > @@ -2878,20 +2985,23 @@ exports[`components > viewers > stop viewer should render with OTP transit index className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > viewers > stop viewer should render with OTP transit index title="To Location Icon" > viewers > stop viewer should render with OTP transit index title="To Location Icon" > viewers > stop viewer should render with OTP transit index "sortOrder": 2600, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -3268,6 +3379,7 @@ exports[`components > viewers > stop viewer should render with OTP transit index "sortOrder": 3900, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -3497,6 +3609,7 @@ exports[`components > viewers > stop viewer should render with OTP transit index "sortOrder": 9100, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -3780,6 +3893,7 @@ exports[`components > viewers > stop viewer should render with OTP transit index "sortOrder": 9100, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -4014,6 +4128,35 @@ exports[`components > viewers > stop viewer should render with OTP transit index Auto-refresh arrivals? + + + + + 17:50 + @@ -4556,24 +4699,23 @@ exports[`components > viewers > stop viewer should render with TriMet transit in } > - 17:38 + View + schedule @@ -4597,10 +4739,13 @@ exports[`components > viewers > stop viewer should render with TriMet transit in className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > @@ -4678,20 +4823,23 @@ exports[`components > viewers > stop viewer should render with TriMet transit in className="styled__LocationPickerSpan-p56b41-0 hDNuMB" > viewers > stop viewer should render with TriMet transit in title="To Location Icon" > viewers > stop viewer should render with TriMet transit in title="To Location Icon" > viewers > stop viewer should render with TriMet transit in "type": 3, } } + showScheduleView={false} stopTimes={ Array [ Object { @@ -5075,6 +5224,35 @@ exports[`components > viewers > stop viewer should render with TriMet transit in Auto-refresh arrivals? + + + + + 17:38 + diff --git a/__tests__/reducers/__snapshots__/create-otp-reducer.js.snap b/__tests__/reducers/__snapshots__/create-otp-reducer.js.snap index b414ffcd4..93507dd74 100644 --- a/__tests__/reducers/__snapshots__/create-otp-reducer.js.snap +++ b/__tests__/reducers/__snapshots__/create-otp-reducer.js.snap @@ -46,6 +46,13 @@ Object { "watts": 250, "wheelchair": false, }, + "filter": Object { + "filter": "ALL", + "sort": Object { + "direction": "ASC", + "type": "BEST", + }, + }, "location": Object { "currentPosition": Object { "coords": null, @@ -118,6 +125,7 @@ Object { "watts": 250, "wheelchair": false, }, + "expandAdvanced": false, "favoriteStops": Array [], "locations": Array [], "recentPlaces": Array [], diff --git a/example.css b/example.css index f92e76be2..ab6a1ea42 100644 --- a/example.css +++ b/example.css @@ -34,6 +34,8 @@ height: 100%; padding: 10px; overflow-y: scroll; + box-shadow: 3px 0px 12px #00000052; + z-index: 1000; } .map-container { diff --git a/example.js b/example.js index 93548ea9b..59a3f0dc8 100644 --- a/example.js +++ b/example.js @@ -16,11 +16,16 @@ import { Grid, Row, Col } from 'react-bootstrap' // import OTP-RR components import { + CallTakerControls, + CallTakerPanel, + CallTakerWindows, DefaultMainPanel, DesktopNav, + BatchRoutingPanel, Map, MobileMain, ResponsiveWebapp, + createCallTakerReducer, createOtpReducer, createUserReducer } from './lib' @@ -41,19 +46,8 @@ if (useCustomIcons) { MyModeIcon = CustomIcons.CustomModeIcon } -// create an initial query for demo/testing purposes -const initialQuery = { - from: { - lat: 45.5246, - lon: -122.6710 - }, - to: { - lat: 45.5307, - lon: -122.6647 - }, - type: 'ITINERARY' -} - +// Get the initial query from config (for demo/testing purposes). +const {initialQuery} = otpConfig const history = createHashHistory() const middleware = [ thunk, @@ -68,13 +62,13 @@ if (process.env.NODE_ENV === 'development') { // set up the Redux store const store = createStore( combineReducers({ - otp: createOtpReducer(otpConfig), + callTaker: createCallTakerReducer(), + otp: createOtpReducer(otpConfig, initialQuery), user: createUserReducer(), router: connectRouter(history) }), compose(applyMiddleware(...middleware)) ) - // define a simple responsive UI using Bootstrap and OTP-RR class OtpRRExample extends Component { render () { @@ -85,12 +79,24 @@ class OtpRRExample extends Component { - {/*
Needed for accessibility checks. TODO: Find a better place. */} + {/* + Note: the main tag provides a way for users of screen readers + to skip to the primary page content. + TODO: Find a better place. + */}
- + {/* TODO: extract the BATCH elements out of CallTakerPanel. */} + {otpConfig.datastoreUrl + ? + : otpConfig.routingTypes.find(t => t.key === 'BATCH') + ? + : + }
+ {otpConfig.datastoreUrl ? : null} + {otpConfig.datastoreUrl ? : null} diff --git a/lib/actions/api.js b/lib/actions/api.js index 1ac0b0c22..aaa27e6d9 100644 --- a/lib/actions/api.js +++ b/lib/actions/api.js @@ -58,15 +58,14 @@ function isStoredPlace (place) { * is specified in URL parameters, use that ID. Otherwise, use null/0. */ function getActiveItinerary (otpState) { - let activeItinerary = otpState.currentQuery.routingType === 'ITINERARY' ? 0 : null + const {currentQuery, searches} = otpState + let activeItinerary = currentQuery.routingType === 'ITINERARY' ? 0 : null // We cannot use window.history.state here to check for the active // itinerary param because it is unreliable in some states (e.g., // when the print layout component first loads). const urlParams = getUrlParams() - if ( - (!otpState.searches || Object.keys(otpState.searches).length === 0) && - urlParams.ui_activeItinerary - ) { + const hasSearches = !searches || Object.keys(searches).length === 0 + if (hasSearches && urlParams.ui_activeItinerary) { activeItinerary = +urlParams.ui_activeItinerary } return activeItinerary @@ -83,86 +82,98 @@ function getActiveItinerary (otpState) { */ export function routingQuery (searchId = null) { return async function (dispatch, getState) { + // FIXME: batchId is searchId for now. const state = getState() const otpState = state.otp const isNewSearch = !searchId if (isNewSearch) searchId = randId() - const routingType = otpState.currentQuery.routingType // Don't permit a routing query if the query is invalid if (!queryIsValid(otpState)) { console.warn('Query is invalid. Aborting routing query', otpState.currentQuery) return } const activeItinerary = getActiveItinerary(otpState) - dispatch(routingRequest({ activeItinerary, routingType, searchId })) - - // fetch a realtime route - const query = constructRoutingQuery(otpState) - fetch(query, getOtpFetchOptions(state)) - .then(getJsonAndCheckResponse) - .then(json => { - dispatch(routingResponse({ response: json, searchId })) - // If tracking is enabled, store locations and search after successful - // search is completed. - if (otpState.user.trackRecent) { - const { from, to } = otpState.currentQuery - if (!isStoredPlace(from)) { - dispatch(rememberPlace({ type: 'recent', location: formatRecentPlace(from) })) - } - if (!isStoredPlace(to)) { - dispatch(rememberPlace({ type: 'recent', location: formatRecentPlace(to) })) + const routingType = otpState.currentQuery.routingType + // For multiple mode combinations, gather injected params from config/query. + // Otherwise, inject nothing (rely on what's in current query) and perform + // one iteration. + const iterations = otpState.config.modes && otpState.config.modes.combinations + ? otpState.config.modes.combinations.map(({mode, params}) => ({mode, ...params})) + : [{}] + dispatch(routingRequest({ activeItinerary, routingType, searchId, pending: iterations.length })) + iterations.forEach((injectedParams, i) => { + const requestId = randId() + // fetch a realtime route + const query = constructRoutingQuery(otpState, false, injectedParams) + fetch(query, getOtpFetchOptions(state)) + .then(getJsonAndCheckResponse) + .then(json => { + dispatch(routingResponse({ response: json, requestId, searchId })) + // If tracking is enabled, store locations and search after successful + // search is completed. + if (otpState.user.trackRecent) { + const { from, to } = otpState.currentQuery + if (!isStoredPlace(from)) { + dispatch(rememberPlace({ type: 'recent', location: formatRecentPlace(from) })) + } + if (!isStoredPlace(to)) { + dispatch(rememberPlace({ type: 'recent', location: formatRecentPlace(to) })) + } + dispatch(rememberSearch(formatRecentSearch(query, otpState))) } - dispatch(rememberSearch(formatRecentSearch(query, otpState))) - } - }) - .catch(error => { - dispatch(routingError({ error, searchId })) - }) - // Update OTP URL params if a new search. In other words, if we're - // performing a search based on query params taken from the URL after a back - // button press, we don't need to update the OTP URL. - // TODO: For old searches that we are re-running, should we be **replacing** - // the URL params here (instead of **pushing** a new path to history like - // what currently happens in updateOtpUrlParams)? That way we could ensure - // that the path absolutely accurately reflects the app state. - const params = getUrlParams() - if (isNewSearch || params.ui_activeSearch !== searchId) { - dispatch(updateOtpUrlParams(otpState, searchId)) - } + }) + .catch(error => { + dispatch(routingError({ error, requestId, searchId })) + }) + // Update OTP URL params if a new search. In other words, if we're + // performing a search based on query params taken from the URL after a back + // button press, we don't need to update the OTP URL. + // TODO: For old searches that we are re-running, should we be **replacing** + // the URL params here (instead of **pushing** a new path to history like + // what currently happens in updateOtpUrlParams)? That way we could ensure + // that the path absolutely accurately reflects the app state. + const params = getUrlParams() + if (isNewSearch || params.ui_activeSearch !== searchId) { + dispatch(updateOtpUrlParams(otpState, searchId)) + } - // Also fetch a non-realtime route. - // - // FIXME: The statement below may no longer apply with future work - // involving realtime info embedded in the OTP response. - // (That action records an entry again in the middleware.) - // For users who opted in to store trip request history, - // to avoid recording the same trip request twice in the middleware, - // only add the user Authorization token to the request - // when querying the non-realtime route. - // - // The advantage of using non-realtime route is that the middleware will be able to - // record and provide the theoretical itinerary summary without having to query OTP again. - // FIXME: Interestingly, and this could be from a side effect elsewhere, - // when a logged-in user refreshes the page, the trip request in the URL is not recorded again - // (state.user stays unpopulated until after this function is called). - // - const { user } = state - const storeTripHistory = user && - user.loggedInUser && - user.loggedInUser.storeTripHistory - - fetch(constructRoutingQuery(otpState, true), getOtpFetchOptions(state, storeTripHistory)) - .then(getJsonAndCheckResponse) - .then(json => { - // FIXME: This is only performed when ignoring realtimeupdates currently, just - // to ensure it is not repeated twice. - dispatch(nonRealtimeRoutingResponse({ response: json, searchId })) - }) - .catch(error => { - console.error(error) - // do nothing - }) + // Also fetch a non-realtime route. + // + // FIXME: The statement below may no longer apply with future work + // involving realtime info embedded in the OTP response. + // (That action records an entry again in the middleware.) + // For users who opted in to store trip request history, + // to avoid recording the same trip request twice in the middleware, + // only add the user Authorization token to the request + // when querying the non-realtime route. + // + // The advantage of using non-realtime route is that the middleware will be able to + // record and provide the theoretical itinerary summary without having to query OTP again. + // FIXME: Interestingly, and this could be from a side effect elsewhere, + // when a logged-in user refreshes the page, the trip request in the URL is not recorded again + // (state.user stays unpopulated until after this function is called). + // + const { user } = state + const storeTripHistory = user && + user.loggedInUser && + user.loggedInUser.storeTripHistory + + fetch(constructRoutingQuery(otpState, true), getOtpFetchOptions(state, storeTripHistory)) + .then(getJsonAndCheckResponse) + .then(json => { + // FIXME: This is only performed when ignoring realtimeupdates currently, just + // to ensure it is not repeated twice. + // FIXME: We should check that the mode combination actually has + // realtime (or maybe this is set in the config file) to determine + // whether this extra query to OTP is needed. + dispatch(nonRealtimeRoutingResponse({ response: json, searchId })) + }) + .catch(error => { + console.error(error) + // do nothing + }) + }) } } @@ -208,7 +219,7 @@ function getOtpFetchOptions (state, includeToken = false) { } } -function constructRoutingQuery (otpState, ignoreRealtimeUpdates) { +function constructRoutingQuery (otpState, ignoreRealtimeUpdates, injectedParams = {}) { const { config, currentQuery } = otpState const routingType = currentQuery.routingType // Check for routingType-specific API config; if none, use default API @@ -217,13 +228,16 @@ function constructRoutingQuery (otpState, ignoreRealtimeUpdates) { const planEndpoint = `${api.host}${api.port ? ':' + api.port : ''}${api.path}/plan` - const params = getRoutingParams(otpState, ignoreRealtimeUpdates) - return `${planEndpoint}?${qs.stringify(params)}` + const params = { + ...getRoutingParams(currentQuery, ignoreRealtimeUpdates), + // Apply mode override, if specified (for batch routing). + ...injectedParams + } + return `${planEndpoint}?${qs.stringify(params, { arrayFormat: 'repeat' })}` } -function getRoutingParams (otpState, ignoreRealtimeUpdates) { - const { config, currentQuery } = otpState - const routingType = currentQuery.routingType +export function getRoutingParams (query, config, ignoreRealtimeUpdates) { + const routingType = query.routingType const isItinerary = routingType === 'ITINERARY' let params = {} @@ -235,8 +249,8 @@ function getRoutingParams (otpState, ignoreRealtimeUpdates) { // 2. Must be included in the current user-defined query // 3. Must pass the parameter's applicability test, if one is specified return qp.routingTypes.indexOf(routingType) !== -1 && - qp.name in currentQuery && - (typeof qp.applicable !== 'function' || qp.applicable(currentQuery, config)) + qp.name in query && + (typeof qp.applicable !== 'function' || qp.applicable(query, config)) }) .forEach(qp => { // Translate the applicable parameters according to their rewrite @@ -247,8 +261,8 @@ function getRoutingParams (otpState, ignoreRealtimeUpdates) { params = Object.assign( params, rewriteFunction - ? rewriteFunction(currentQuery[qp.name]) - : { [qp.name]: currentQuery[qp.name] } + ? rewriteFunction(query[qp.name]) + : { [qp.name]: query[qp.name] } ) }) @@ -986,7 +1000,7 @@ function createQueryAction (endpoint, responseAction, errorAction, options = {}) export function setUrlSearch (params, replaceCurrent = false) { return function (dispatch, getState) { const base = getState().router.location.pathname - const path = `${base}?${qs.stringify(params)}` + const path = `${base}?${qs.stringify(params, { arrayFormat: 'repeat' })}` if (replaceCurrent) dispatch(replace(path)) else dispatch(push(path)) } @@ -996,14 +1010,18 @@ export function setUrlSearch (params, replaceCurrent = false) { * Update the OTP Query parameters in the URL and ensure that the active search * is set correctly. Leaves any other existing URL parameters (e.g., UI) unchanged. */ -export function updateOtpUrlParams (otpState, searchId) { - const otpParams = getRoutingParams(otpState) +function updateOtpUrlParams (otpState, searchId) { + const {config, currentQuery} = otpState + // Get updated OTP params from current query. + const otpParams = getRoutingParams(currentQuery, config, true) return function (dispatch, getState) { const params = {} - // Get all OTP-specific params, which will be retained unchanged in the URL + // Get all URL params and ensure non-routing params (UI, sessionId) remain + // unchanged. const urlParams = getUrlParams() Object.keys(urlParams) - .filter(key => key.indexOf('_') !== -1) + // If param is non-routing, add to params to keep the same after update. + .filter(key => key.indexOf('_') !== -1 || key === 'sessionId') .forEach(key => { params[key] = urlParams[key] }) params.ui_activeSearch = searchId // Assumes this is a new search and the active itinerary should be reset. diff --git a/lib/actions/call-taker.js b/lib/actions/call-taker.js new file mode 100644 index 000000000..25ccb2ae7 --- /dev/null +++ b/lib/actions/call-taker.js @@ -0,0 +1,201 @@ +import { getUrlParams } from '@opentripplanner/core-utils/lib/query' +import qs from 'qs' +import { createAction } from 'redux-actions' + +import {searchToQuery} from '../util/call-taker' +import {URL_ROOT} from '../util/constants' +import {getTimestamp} from '../util/state' + +if (typeof (fetch) === 'undefined') require('isomorphic-fetch') + +/// PRIVATE ACTIONS + +const endingCall = createAction('END_CALL') +const receivedCalls = createAction('RECEIVED_CALLS') +const receivedQueries = createAction('RECEIVED_QUERIES') +const requestingCalls = createAction('REQUESTING_CALLS') +const requestingQueries = createAction('REQUESTING_QUERIES') +const storeSession = createAction('STORE_SESSION') + +/// PUBLIC ACTIONS + +export const beginCall = createAction('BEGIN_CALL') +export const toggleCallHistory = createAction('TOGGLE_CALL_HISTORY') + +/** + * End the active call and store the queries made during the call. + */ +export function endCall () { + return function (dispatch, getState) { + const {callTaker, otp} = getState() + const {activeCall, session} = callTaker + if (sessionIsInvalid(session)) return + // Make POST request to store call. + const callData = new FormData() + callData.append('sessionId', session.sessionId) + callData.append('call.startTime', activeCall.startTime) + callData.append('call.endTime', getTimestamp()) + fetch(`${otp.config.datastoreUrl}/calltaker/call`, + {method: 'POST', body: callData} + ) + .then(res => res.json()) + .then(id => { + // Inject call ID into active call and save queries. + dispatch(saveQueriesForCall({...activeCall, id})) + dispatch(fetchCalls()) + }) + .catch(err => { + console.error(err) + alert(`Could not save call: ${JSON.stringify(err)}`) + }) + dispatch(endingCall()) + } +} + +/** + * Initialize the Call Taker and Field Trip modules by checking the session + * query param against sessions in the datastore backend or initializing a new + * session via Trinet. + */ +export function initializeModules () { + return function (dispatch, getState) { + const {datastoreUrl, trinetReDirect} = getState().otp.config + // Initialize session if datastore enabled. + if (datastoreUrl && trinetReDirect) { + // TODO: Generalize for non-TriNet instances. + const sessionId = getUrlParams().sessionId + if (sessionId) { + // Initialize the session if found in URL query params. + dispatch(checkSession(datastoreUrl, sessionId)) + } else { + // No sessionId was passed in, so we must request one from server. + newSession(datastoreUrl, trinetReDirect, URL_ROOT) + } + } + } +} + +/** + * Handle initializing a new Trinet session by redirecting to Trinet auth and + * returning once authenticated successfully. + */ +function newSession (datastoreUrl, verifyLoginUrl, redirect) { + fetch(datastoreUrl + '/auth/newSession') + .then(res => res.json()) + .then(data => { + const {sessionId: session} = data + console.log('newSession success: ' + session) + const windowUrl = `${verifyLoginUrl}?${qs.stringify({session, redirect})}` + console.log('redirecting to: ' + windowUrl) + window.location = windowUrl + }) + .catch(error => { + console.error('newSession error', error) + }) +} + +/** + * Check that a particular session ID is valid and store resulting session + * data. + */ +function checkSession (datastoreUrl, sessionId) { + return function (dispatch, getState) { + fetch(datastoreUrl + `/auth/checkSession?sessionId=${sessionId}`) + .then(res => res.json()) + .then(session => dispatch(storeSession({session}))) + .catch(error => { + console.error('checkSession error', error) + dispatch(storeSession({session: null})) + }) + } +} + +/** + * Fetch latest calls for a particular session. + */ +export function fetchCalls () { + return function (dispatch, getState) { + dispatch(requestingCalls()) + const {callTaker, otp} = getState() + if (sessionIsInvalid(callTaker.session)) return + const {datastoreUrl} = otp.config + const {sessionId} = callTaker.session + const limit = 10 + fetch(`${datastoreUrl}/calltaker/call?${qs.stringify({limit, sessionId})}`) + .then(res => res.json()) + .then(calls => { + console.log('GET calls response', calls) + dispatch(receivedCalls({calls})) + }) + .catch(err => { + alert(`Could not fetch calls: ${JSON.stringify(err)}`) + }) + } +} + +/** + * @return {boolean} - whether a calltaker session is invalid + */ +function sessionIsInvalid (session) { + if (!session || !session.sessionId) { + console.error('No valid OTP datastore session found.') + return true + } + return false +} + +/** + * Store the trip queries made over the course of a call (to be called when the + * call terminates). + */ +export function saveQueriesForCall (call) { + return function (dispatch, getState) { + const {callTaker, otp} = getState() + const {datastoreUrl} = otp.config + if (sessionIsInvalid(callTaker.session)) return + if (!call) { + alert(`Could not find call for ${call.id}. Cancelling save queries request.`) + return + } + return Promise.all(call.searches.map(searchId => { + const search = otp.searches[searchId] + const query = searchToQuery(search, call, otp.config) + const {sessionId} = callTaker.session + const queryData = new FormData() + queryData.append('sessionId', sessionId) + queryData.append('query.queryParams', query.queryParams) + queryData.append('query.fromPlace', query.fromPlace) + queryData.append('query.toPlace', query.toPlace) + queryData.append('query.timeStamp', query.timeStamp) + queryData.append('query.call.id', call.id) + return fetch(`${datastoreUrl}/calltaker/callQuery?sessionId=${sessionId}`, + {method: 'POST', body: queryData} + ) + .then(res => res.json()) + .catch(err => { + alert(`Could not fetch calls: ${JSON.stringify(err)}`) + }) + })) + } +} + +/** + * Fetch the trip queries that were made during a particular call. + */ +export function fetchQueries (callId) { + return function (dispatch, getState) { + dispatch(requestingQueries()) + const {callTaker, otp} = getState() + const {datastoreUrl} = otp.config + if (sessionIsInvalid(callTaker.session)) return + const {sessionId} = callTaker.session + fetch(`${datastoreUrl}/calltaker/callQuery?sessionId=${sessionId}&call.id=${callId}`) + .then(res => res.json()) + .then(queries => { + dispatch(receivedQueries({callId, queries})) + }) + .catch(err => { + alert(`Could not fetch calls: ${JSON.stringify(err)}`) + }) + } +} diff --git a/lib/actions/narrative.js b/lib/actions/narrative.js index 56cc5279c..48a75d611 100644 --- a/lib/actions/narrative.js +++ b/lib/actions/narrative.js @@ -17,3 +17,7 @@ const settingActiveitinerary = createAction('SET_ACTIVE_ITINERARY') export const setActiveLeg = createAction('SET_ACTIVE_LEG') export const setActiveStep = createAction('SET_ACTIVE_STEP') export const setUseRealtimeResponse = createAction('SET_USE_REALTIME_RESPONSE') +// Set itinerary visible on map. This is used for mouse over effects with +// itineraries in the list. +export const setVisibleItinerary = createAction('SET_VISIBLE_ITINERARY') +export const updateItineraryFilter = createAction('UPDATE_ITINERARY_FILTER') diff --git a/lib/components/admin/call-record.js b/lib/components/admin/call-record.js new file mode 100644 index 000000000..602599109 --- /dev/null +++ b/lib/components/admin/call-record.js @@ -0,0 +1,85 @@ +import moment from 'moment' +import React, { Component } from 'react' + +import CallTimeCounter from './call-time-counter' +import Icon from '../narrative/icon' +import QueryRecord from './query-record' +import {searchToQuery} from '../../util/call-taker' + +/** + * Displays information for a particular call record in the Call Taker window. + */ +export default class CallRecord extends Component { + state = { + expanded: false + } + + _toggleExpanded = () => { + const {call, fetchQueries} = this.props + const {expanded} = this.state + if (!expanded) fetchQueries(call.id) + this.setState({expanded: !expanded}) + } + + render () { + // FIXME: consolidate red color with call taker controls + const RED = '#C35134' + const {call, index, inProgress, searches} = this.props + const {expanded} = this.state + if (!call) return null + if (inProgress) { + // Map search IDs made during active call to queries. + const activeQueries = call.searches + .map(searchId => searchToQuery(searches[searchId], call, {})) + return ( +
+
+ + +
+ {' '} + [Active call] +
+ + In progress... click to save{' '} + ({call.searches.length} searches) + +
+ {activeQueries.length > 0 + ? activeQueries.map((query, i) => ( + + )) + : 'No queries recorded.' + } +
+
+ ) + } + return ( +
+ + {expanded + ?
    + {call.queries && call.queries.length > 0 + ? call.queries.map((query, i) => ( + + )) + : 'No queries recorded.' + } +
+ : null + } +
+ ) + } +} diff --git a/lib/components/admin/call-taker-controls.js b/lib/components/admin/call-taker-controls.js new file mode 100644 index 000000000..d5b8f1833 --- /dev/null +++ b/lib/components/admin/call-taker-controls.js @@ -0,0 +1,150 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' + +import * as callTakerActions from '../../actions/call-taker' +import { routingQuery } from '../../actions/api' +import { setMainPanelContent } from '../../actions/ui' +import CallTimeCounter from './call-time-counter' +import Icon from '../narrative/icon' + +const RED = '#C35134' +const BLUE = '#1C4D89' +const GREEN = '#6B931B' + +/** + * This component displays the controls for the Call Taker/Field Trip modules, + * including: + * - start/end call button + * - view call list + * TODO + * - view field trip list + */ +class CallTakerControls extends Component { + componentWillReceiveProps (nextProps) { + const {session} = nextProps + // Once session is available, fetch calls. + if (session && !this.props.session) { + this.props.fetchCalls() + } + } + + _onClickCall = () => { + if (this._callInProgress()) this.props.endCall() + else this.props.beginCall() + } + + _renderCallButton = () => { + // Show stop button if call not in progress. + if (this._callInProgress()) { + return ( + + ) + } + // No call is in progress. + return ( + <> + + + + ) + } + + _onToggleCallHistory = () => this.props.toggleCallHistory() + + _callInProgress = () => Boolean(this.props.activeCall) + + render () { + const {session} = this.props + // If no valid session is found, do not show calltaker controls. + if (!session) return null + // FIXME: styled component + const circleButtonStyle = { + position: 'absolute', + zIndex: 999999, + color: 'white', + borderRadius: '50%', + border: 'none', + boxShadow: '2px 2px 4px #000000' + } + return ( + <> + {/* Start/End Call button */} + + {this._callInProgress() + ? + : null + } + {/* Call History toggle button */} + + {/* Field Trip toggle button TODO */} + + ) + } +} + +const mapStateToProps = (state, ownProps) => { + return { + activeCall: state.callTaker.activeCall, + session: state.callTaker.session + } +} + +const {beginCall, endCall, fetchCalls, toggleCallHistory} = callTakerActions + +const mapDispatchToProps = { + beginCall, + endCall, + fetchCalls, + routingQuery, + setMainPanelContent, + toggleCallHistory +} + +export default connect(mapStateToProps, mapDispatchToProps)(CallTakerControls) diff --git a/lib/components/admin/call-taker-windows.js b/lib/components/admin/call-taker-windows.js new file mode 100644 index 000000000..b575cc2ca --- /dev/null +++ b/lib/components/admin/call-taker-windows.js @@ -0,0 +1,68 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' + +import * as callTakerActions from '../../actions/call-taker' +import CallRecord from './call-record' +import DraggableWindow from './draggable-window' +import Icon from '../narrative/icon' + +/** + * Collects the various draggable windows used in the Call Taker module to + * display, for example, the call record list and (TODO) the list of field trips. + */ +class CallTakerWindows extends Component { + render () { + const {callTaker, fetchQueries, searches} = this.props + const {activeCall, callHistory} = callTaker + return ( + <> + {callHistory.visible + // Active call window + ? Call history} + onClickClose={this.props.toggleCallHistory} + > + {activeCall + ? + : null + } + {callHistory.calls.data.length > 0 + ? callHistory.calls.data.map((call, i) => ( + + )) + :
No calls in history
+ } +
+ : null + } + + ) + } +} + +const mapStateToProps = (state, ownProps) => { + return { + callTaker: state.callTaker, + currentQuery: state.otp.currentQuery, + searches: state.otp.searches + } +} + +const { + fetchQueries, + toggleCallHistory +} = callTakerActions + +const mapDispatchToProps = { fetchQueries, toggleCallHistory } + +export default connect(mapStateToProps, mapDispatchToProps)(CallTakerWindows) diff --git a/lib/components/admin/call-taker.css b/lib/components/admin/call-taker.css new file mode 100644 index 000000000..9f85cf73f --- /dev/null +++ b/lib/components/admin/call-taker.css @@ -0,0 +1,11 @@ +@keyframes fadeIn { + from { opacity: 0; } +} + +.otp .animate-flicker { + animation: fadeIn 1s infinite alternate; +} + +.otp .advanced-search-options { + box-shadow: 0px 5px 3px 0px rgba(0,0,0,0.32157); +} diff --git a/lib/components/admin/call-time-counter.js b/lib/components/admin/call-time-counter.js new file mode 100644 index 000000000..1d8dfe763 --- /dev/null +++ b/lib/components/admin/call-time-counter.js @@ -0,0 +1,53 @@ +// import moment from 'moment' +import React, { Component } from 'react' + +/** + * Component that displays the call time (ticking with each second) + * for an active call (assumes that mount time corresponds with call start). + */ +export default class CallTimeCounter extends Component { + state = { + counterString: 0 + } + + componentDidMount () { + this._startRefresh() + } + + componentWillUnmount () { + this._stopRefresh() + } + + /** + * Formats seconds as hh:mm:ss string. + */ + _formatSeconds = (seconds) => { + const date = new Date(0) + date.setSeconds(seconds) + return date.toISOString().substr(11, 8) + } + + _refreshCounter = () => { + const counterString = this.state.counterString + 1 + this.setState({counterString}) + } + + _startRefresh = () => { + // Set refresh to every second. + const timer = window.setInterval(this._refreshCounter, 1000) + this.setState({ timer }) + } + + _stopRefresh = () => { + window.clearInterval(this.state.timer) + } + + render () { + const {className, style} = this.props + return ( +
+ {this._formatSeconds(this.state.counterString)} +
+ ) + } +} diff --git a/lib/components/admin/draggable-window.js b/lib/components/admin/draggable-window.js new file mode 100644 index 000000000..1159cdd39 --- /dev/null +++ b/lib/components/admin/draggable-window.js @@ -0,0 +1,66 @@ +import React, { Component } from 'react' +import Draggable from 'react-draggable' + +import Icon from '../narrative/icon' + +const noop = () => {} + +export default class DraggableWindow extends Component { + render () { + const {children, draggableProps, header} = this.props + const GREY_BORDER = '#777 1.3px solid' + return ( + +
+
+ + {header} +
+
+ {children} +
+
+
+ ) + } +} + +DraggableWindow.defaultProps = { + onClickClose: noop +} diff --git a/lib/components/admin/query-record.js b/lib/components/admin/query-record.js new file mode 100644 index 000000000..df09a4c3c --- /dev/null +++ b/lib/components/admin/query-record.js @@ -0,0 +1,42 @@ +import React, { Component } from 'react' +import { connect } from 'react-redux' + +import * as formActions from '../../actions/form' +import Icon from '../narrative/icon' + +/** + * Displays information for a query stored for the Call Taker module. + */ +class QueryRecordLayout extends Component { + _viewQuery = () => { + const {parseUrlQueryString, query} = this.props + const params = JSON.parse(query.queryParams) + if ('arriveBy' in params) { + params.departArrive = params.arriveBy ? 'ARRIVE' : 'DEPART' + } + parseUrlQueryString(params) + } + + render () { + const {index} = this.props + return ( +
  • + {' '} + Query {index + 1} +
  • + ) + } +} + +const mapStateToProps = (state, ownProps) => { + return {} +} + +const {parseUrlQueryString} = formActions + +const mapDispatchToProps = { parseUrlQueryString } + +const QueryRecord = connect(mapStateToProps, mapDispatchToProps)(QueryRecordLayout) +export default QueryRecord diff --git a/lib/components/app/batch-routing-panel.js b/lib/components/app/batch-routing-panel.js new file mode 100644 index 000000000..80c4c95b4 --- /dev/null +++ b/lib/components/app/batch-routing-panel.js @@ -0,0 +1,132 @@ +import React, { Component } from 'react' +import { Button } from 'react-bootstrap' +import { connect } from 'react-redux' + +import * as apiActions from '../../actions/api' +import LocationField from '../form/connected-location-field' +import UserSettings from '../form/user-settings' +import Icon from '../narrative/icon' +import NarrativeItineraries from '../narrative/narrative-itineraries' +import { hasValidLocation, getActiveSearch, getShowUserSettings } from '../../util/state' +import ViewerContainer from '../viewers/viewer-container' + +/** + * Main panel for the batch/trip comparison form. + * @extends Component + */ +class BatchRoutingPanel extends Component { + _planTrip = () => { + const {currentQuery, routingQuery} = this.props + const issues = [] + if (!hasValidLocation(currentQuery, 'from')) issues.push('from') + if (!hasValidLocation(currentQuery, 'to')) issues.push('to') + if (issues.length > 0) { + // TODO: replace with less obtrusive validation. + window.alert(`Please define the following fields to plan a trip: ${issues.join(', ')}`) + return + } + routingQuery() + } + + render () { + const { + activeSearch, + itineraryFooter, + LegIcon, + mobile, + showUserSettings + } = this.props + const actionText = mobile ? 'tap' : 'click' + return ( + + + +
    + + + +
    + {!activeSearch && showUserSettings && + + } +
    + +
    +
    + ) + } +} + +// connect to the redux store +const mapStateToProps = (state, ownProps) => { + const showUserSettings = getShowUserSettings(state.otp) + return { + activeSearch: getActiveSearch(state.otp), + currentQuery: state.otp.currentQuery, + expandAdvanced: state.otp.user.expandAdvanced, + showUserSettings + } +} + +const mapDispatchToProps = { + routingQuery: apiActions.routingQuery +} + +export default connect(mapStateToProps, mapDispatchToProps)(BatchRoutingPanel) diff --git a/lib/components/app/call-taker-panel.js b/lib/components/app/call-taker-panel.js new file mode 100644 index 000000000..40459bae2 --- /dev/null +++ b/lib/components/app/call-taker-panel.js @@ -0,0 +1,669 @@ +import { + OTP_API_DATE_FORMAT, + OTP_API_TIME_FORMAT +} from '@opentripplanner/core-utils/lib/time' +import { hasBike, hasTransit } from '@opentripplanner/core-utils/lib/itinerary' +import { storeItem } from '@opentripplanner/core-utils/lib/storage' +import {SubmodeSelector} from '@opentripplanner/trip-form' +import * as TripFormClasses from '@opentripplanner/trip-form/lib/styled' +import moment from 'moment' +import React, { Component } from 'react' +import { Button } from 'react-bootstrap' +import { connect } from 'react-redux' +import Select from 'react-select' +import styled from 'styled-components' + +import * as apiActions from '../../actions/api' +import * as formActions from '../../actions/form' +import IntermediatePlace from '../form/intermediate-place-field' +import LocationField from '../form/connected-location-field' +import { modeButtonButtonCss } from '../form/styled' +import SwitchButton from '../form/switch-button' +import UserSettings from '../form/user-settings' +import NarrativeItineraries from '../narrative/narrative-itineraries' +import { hasValidLocation, getActiveSearch, getShowUserSettings } from '../../util/state' +import ViewerContainer from '../viewers/viewer-container' + +// FIXME: move to styled.js? +export const StyledSubmodeSelector = styled(SubmodeSelector)` + ${TripFormClasses.SubmodeSelector.Row} { + > * { + padding: 3px 5px 3px 0px; + } + > :last-child { + padding-right: 0px; + } + ${TripFormClasses.ModeButton.Button} { + padding: 6px 12px; + } + svg, + img { + margin-left: 0px; + } + } + ${TripFormClasses.SubmodeSelector.InlineRow} { + margin: -3px 0px; + } + + ${TripFormClasses.SubmodeSelector} { + ${modeButtonButtonCss} + } +` + +const departureOptions = [ + { + // Default option. + value: 'NOW', + children: 'Now' + }, + { + value: 'DEPART', + children: 'Depart at' + }, + { + value: 'ARRIVE', + children: 'Arrive by' + } +] + +const modeOptions = [ + { + // Default option. + value: 'TRANSIT', + children: 'Transit' + }, + { + value: 'WALK', + children: 'Walk only' + }, + { + value: 'BICYCLE', + children: 'Bike only' + }, + { + value: 'BICYCLE,TRANSIT', + children: 'Bike to transit' + } +] + +const metersToMiles = meters => Math.round(meters * 0.000621371 * 100) / 100 +const milesToMeters = miles => miles / 0.000621371 + +/** + * This is the main panel/sidebar for the Call Taker/Field Trip module. It + * currently also serves as the main panel for the FDOT RMCE trip comparison view + * which depends on the BATCH trip planning mode. + */ +class CallTakerPanel extends Component { + constructor (props) { + super(props) + this.state = { + expandAdvanced: props.expandAdvanced, + transitModes: props.modes.transitModes.map(m => m.mode) + } + } + + _planTrip = () => { + const {currentQuery, routingQuery} = this.props + const issues = [] + if (!hasValidLocation(currentQuery, 'from')) issues.push('from') + if (!hasValidLocation(currentQuery, 'to')) issues.push('to') + if (issues.length > 0) { + // TODO: replace with less obtrusive validation. + window.alert(`Please define the following fields to plan a trip: ${issues.join(', ')}`) + return + } + routingQuery() + } + + _setBannedRoutes = options => { + const bannedRoutes = options ? options.map(o => o.value).join(',') : '' + this.props.setQueryParam({ bannedRoutes }) + } + + modeToOptionValue = mode => { + const isTransit = hasTransit(mode) + const isBike = hasBike(mode) + if (isTransit && isBike) return 'BICYCLE,TRANSIT' + else if (isTransit) return 'TRANSIT' + // Currently handles bicycle + else return mode + } + + _addPlace = (result, index) => { + const intermediatePlaces = [...this.props.currentQuery.intermediatePlaces] || [] + if (result && index !== undefined) { + // If adding an actual intermediate place with location. Overwrite the + // placeholder with the new value. + intermediatePlaces.splice(index, 1, result.location) + } else { + // Otherwise, we're just adding a dummy place. + intermediatePlaces.push({}) + } + this.props.setQueryParam({intermediatePlaces}) + } + + _removePlace = ({index}) => { + const intermediatePlaces = [...this.props.currentQuery.intermediatePlaces] || [] + intermediatePlaces.splice(index, 1) + this.props.setQueryParam({intermediatePlaces}) + } + + _setMode = evt => { + const {value: mode} = evt.target + const transitIsSelected = mode.indexOf('TRANSIT') !== -1 + if (transitIsSelected) { + // Collect transit modes and selected access mode. + const accessMode = mode === 'TRANSIT' ? 'WALK' : 'BICYCLE' + // If no transit is selected, selected all available. Otherwise, default + // to state. + const transitModes = this.state.transitModes.length > 0 + ? this.state.transitModes + : this.props.modes.transitModes.map(m => m.mode) + const newModes = [accessMode, ...transitModes].join(',') + this.setState({transitModes}) + this.props.setQueryParam({ mode: newModes }) + } else { + this.props.setQueryParam({ mode }) + } + } + + _onHideAdvancedClick = () => { + const expandAdvanced = !this.state.expandAdvanced + // FIXME move logic to action + storeItem('expandAdvanced', expandAdvanced) + this.setState({expandAdvanced}) + } + + /** + * Key down listener that will submit a plan trip query when Enter is pressed. + * This listener can be passed to constituent form elements for easy + * keyboard-only operation of the trip planning form. Note: it generally should + * not be passed to buttons or other elements that natively rely on the Enter + * key. + * + * FIXME: Should we use a proper submit button instead? + */ + _handleFormKeyDown = (evt) => { + switch (evt.keyCode) { + case 13: // Enter + evt.preventDefault() + // Submit routing query. + this._planTrip() + break + default: + // Do nothing. + break + } + } + + render () { + const { + activeSearch, + currentQuery, + itineraryFooter, + LegIcon, + mainPanelContent, + mobile, + modes, + ModeIcon, + routes, + setQueryParam, + showUserSettings + } = this.props + // FIXME: Remove showPlanTripButton + const showPlanTripButton = mainPanelContent === 'EDIT_DATETIME' || + mainPanelContent === 'EDIT_SETTINGS' + // const mostRecentQuery = activeSearch ? activeSearch.query : null + // const planDisabled = isEqual(currentQuery, mostRecentQuery) + const { + departArrive, + date, + from, + intermediatePlaces, + mode, + time, + to + } = currentQuery + const actionText = mobile ? 'tap' : 'click' + const {expandAdvanced} = this.state + const advancedSearchStyle = { + zIndex: 99999, + background: 'white', + position: 'absolute', + right: '0px', + left: '0px', + padding: '0px 8px 5px', + display: expandAdvanced ? 'none' : undefined + } + // Only permit adding intermediate place if from/to is defined. + const maxPlacesDefined = intermediatePlaces.length >= 3 + const addIntermediateDisabled = !from || !to || maxPlacesDefined + return ( + + {/* FIXME: should this be a styled component */} +
    +
    + + {Array.isArray(intermediatePlaces) && intermediatePlaces.map((place, i) => { + return ( + this._addPlace(result, i)} + // FIXME: allow intermediate location type. + locationType='to' + inputPlaceholder={`Enter intermediate destination`} + showClearButton={!mobile} + /> + ) + })} + +
    + } /> +
    + +
    + + + +
    +
    + +
    + +
    +
    +
    + {!activeSearch && !showPlanTripButton && showUserSettings && + + } +
    + +
    +
    +
    + ) + } +} + +class CallTakerAdvancedOptions extends Component { + constructor (props) { + super(props) + this.state = { + expandAdvanced: props.expandAdvanced, + routeOptions: [], + transitModes: props.modes.transitModes.map(m => m.mode) + } + } + + componentWillMount () { + // Fetch routes for banned/preferred routes selectors. + this.props.findRoutes() + } + + componentWillReceiveProps (nextProps) { + const {routes} = nextProps + // Once routes are available, map them to the route options format. + if (routes && !this.props.routes) { + const routeOptions = Object.values(routes).map(this.routeToOption) + this.setState({routeOptions}) + } + } + + _setPreferredRoutes = options => { + const preferredRoutes = options ? options.map(o => (o.value)).join(',') : '' + this.props.setQueryParam({ preferredRoutes }) + } + + _isBannedRouteOptionDisabled = option => { + // Disable routes that are preferred already. + const preferredRoutes = this.getRouteList('preferredRoutes') + return preferredRoutes && preferredRoutes.find(o => o.value === option.value) + } + + _isPreferredRouteOptionDisabled = option => { + // Disable routes that are banned already. + const bannedRoutes = this.getRouteList('bannedRoutes') + return bannedRoutes && bannedRoutes.find(o => o.value === option.value) + } + + getDistanceStep = distanceInMeters => { + // Determine step for max walk/bike based on current value. Increment by a + // quarter mile if dealing with small values, whatever number will round off + // the number if it is not an integer, or default to one mile. + return metersToMiles(distanceInMeters) <= 2 + ? '.25' + : metersToMiles(distanceInMeters) % 1 !== 0 + ? `${metersToMiles(distanceInMeters) % 1}` + : '1' + } + + _onSubModeChange = changedMode => { + // Get previous transit modes from state and all modes from query. + const transitModes = [...this.state.transitModes] + const allModes = this.props.currentQuery.mode.split(',') + const index = transitModes.indexOf(changedMode) + if (index === -1) { + // If submode was not selected, add it. + transitModes.push(changedMode) + allModes.push(changedMode) + } else { + // Otherwise, remove it. + transitModes.splice(index, 1) + const i = allModes.indexOf(changedMode) + allModes.splice(i, 1) + } + // Update transit modes in state. + this.setState({transitModes}) + // Update all modes in query (set to walk if all transit modes inactive). + this.props.setQueryParam({ mode: allModes.join(',') || 'WALK' }) + } + + _setMaxWalkDistance = evt => { + this.props.setQueryParam({ maxWalkDistance: milesToMeters(evt.target.value) }) + } + + /** + * Get list of routes for specified key (either 'bannedRoutes' or + * 'preferredRoutes'). + */ + getRouteList = key => { + const routesParam = this.props.currentQuery[key] + const idList = routesParam ? routesParam.split(',') : [] + if (this.state.routeOptions) { + return this.state.routeOptions.filter(o => idList.indexOf(o.value) !== -1) + } else { + // If route list is not available, default labels to route IDs. + return idList.map(id => ({value: id, label: id})) + } + } + + routeToOption = route => { + if (!route) return null + const {id, longName, shortName} = route + // For some reason the OTP API expects route IDs in this double + // underscore format + // FIXME: This replace is flimsy! What if there are more colons? + const value = id.replace(':', '__') + const label = shortName + ? `${shortName}${longName ? ` - ${longName}` : ''}` + : longName + return {value, label} + } + + render () { + const {currentQuery, modes, ModeIcon} = this.props + const {maxBikeDistance, maxWalkDistance, mode} = currentQuery + const bannedRoutes = this.getRouteList('bannedRoutes') + const preferredRoutes = this.getRouteList('preferredRoutes') + const transitModes = modes.transitModes.map(modeObj => { + const modeStr = modeObj.mode || modeObj + return { + id: modeStr, + selected: this.state.transitModes.indexOf(modeStr) !== -1, + text: ( + + + + ), + title: modeObj.label + } + }) + // FIXME: Set units via config. + const unitsString = '(mi.)' + return ( +
    +
    + + {hasBike(mode) + ? + : null + } + +
    + +
    + ) + } +} + +const TIME_FORMATS = [ + 'HH:mm:ss', + 'h:mm:ss a', + 'h:mm:ssa', + 'h:mm a', + 'h:mma', + 'h:mm', + 'HHmm', + 'hmm', + 'ha', + 'h', + 'HH:mm' +].map(format => `YYYY-MM-DDT${format}`) + +class DateTimeOptions extends Component { + _setDepartArrive = evt => { + const {value: departArrive} = evt.target + if (departArrive === 'NOW') { + this.props.setQueryParam({ + departArrive, + date: moment().format(OTP_API_DATE_FORMAT), + time: moment().format(OTP_API_TIME_FORMAT) + }) + } else { + this.props.setQueryParam({ departArrive }) + } + } + + handleDateChange = evt => { + this.props.setQueryParam({ date: evt.target.value }) + } + + handleTimeChange = evt => { + const timeInput = evt.target.value + console.log(timeInput) + const date = moment().startOf('day').format('YYYY-MM-DD') + const time = moment(date + 'T' + timeInput, TIME_FORMATS) + this.props.setQueryParam({ time: time.format(OTP_API_TIME_FORMAT) }) + } + + render () { + const {date, departArrive, time} = this.props + const leaveNow = departArrive === 'NOW' && !date && !time + const dateTime = moment(`${date} ${time}`) + const cleanDate = dateTime.format('YYYY-MM-DD') + const cleanTime = dateTime.format('HH:mm') + return ( + <> + + {leaveNow + ? null + : + {cleanTime} + + + } + {leaveNow + ? null + : + } + + ) + } +} + +// connect to the redux store +const mapStateToProps = (state, ownProps) => { + const showUserSettings = getShowUserSettings(state.otp) + return { + activeSearch: getActiveSearch(state.otp), + currentQuery: state.otp.currentQuery, + expandAdvanced: state.otp.user.expandAdvanced, + mainPanelContent: state.otp.ui.mainPanelContent, + modes: state.otp.config.modes, + routes: state.otp.transitIndex.routes, + showUserSettings + } +} + +const mapDispatchToProps = { + findRoutes: apiActions.findRoutes, + routingQuery: apiActions.routingQuery, + setQueryParam: formActions.setQueryParam +} + +export default connect(mapStateToProps, mapDispatchToProps)(CallTakerPanel) diff --git a/lib/components/app/print-layout.js b/lib/components/app/print-layout.js index c140345d8..3d3fce9c7 100644 --- a/lib/components/app/print-layout.js +++ b/lib/components/app/print-layout.js @@ -14,7 +14,7 @@ class PrintLayout extends Component { static propTypes = { itinerary: PropTypes.object, LegIcon: PropTypes.elementType.isRequired, - parseQueryString: PropTypes.func + parseUrlQueryString: PropTypes.func } constructor (props) { diff --git a/lib/components/app/responsive-webapp.js b/lib/components/app/responsive-webapp.js index 7dff8032d..49466492c 100644 --- a/lib/components/app/responsive-webapp.js +++ b/lib/components/app/responsive-webapp.js @@ -10,11 +10,12 @@ import { Auth0Provider } from 'use-auth0-hooks' import PrintLayout from './print-layout' import * as authActions from '../../actions/auth' -import { setMapCenter, setMapZoom } from '../../actions/config' -import { formChanged, parseUrlQueryString } from '../../actions/form' -import { getCurrentPosition, receivedPositionResponse } from '../../actions/location' -import { setLocationToCurrent } from '../../actions/map' -import { handleBackButtonPress, matchContentToUrl } from '../../actions/ui' +import * as callTakerActions from '../../actions/call-taker' +import * as configActions from '../../actions/config' +import * as formActions from '../../actions/form' +import * as locationActions from '../../actions/location' +import * as mapActions from '../../actions/map' +import * as uiActions from '../../actions/ui' import { getAuth0Config } from '../../util/auth' import { AUTH0_AUDIENCE, AUTH0_SCOPE, URL_ROOT } from '../../util/constants' import { getActiveItinerary, getTitle } from '../../util/state' @@ -125,6 +126,8 @@ class ResponsiveWebapp extends Component { // in the URL. this.props.parseUrlQueryString() } + // Initialize call taker/field trip modules (check for valid auth session). + this.props.initializeModules() } componentWillUnmount () { @@ -156,15 +159,16 @@ const mapStateToProps = (state, ownProps) => { } const mapDispatchToProps = { - formChanged, - getCurrentPosition, - handleBackButtonPress, - matchContentToUrl, - parseUrlQueryString, - receivedPositionResponse, - setLocationToCurrent, - setMapCenter, - setMapZoom + formChanged: formActions.formChanged, + getCurrentPosition: locationActions.getCurrentPosition, + handleBackButtonPress: uiActions.handleBackButtonPress, + initializeModules: callTakerActions.initializeModules, + matchContentToUrl: uiActions.matchContentToUrl, + parseUrlQueryString: formActions.parseUrlQueryString, + receivedPositionResponse: locationActions.receivedPositionResponse, + setLocationToCurrent: mapActions.setLocationToCurrent, + setMapCenter: configActions.setMapCenter, + setMapZoom: configActions.setMapZoom } const history = createHashHistory() diff --git a/lib/components/form/connected-settings-selector-panel.js b/lib/components/form/connected-settings-selector-panel.js index 6d4f1d030..8f4934f99 100644 --- a/lib/components/form/connected-settings-selector-panel.js +++ b/lib/components/form/connected-settings-selector-panel.js @@ -23,7 +23,6 @@ class ConnectedSettingsSelectorPanel extends Component { setQueryParam, showUserSettings } = this.props - return (
    diff --git a/lib/components/form/form.css b/lib/components/form/form.css index 854b6bfb1..99d562fff 100644 --- a/lib/components/form/form.css +++ b/lib/components/form/form.css @@ -64,6 +64,15 @@ /* Date/Time selectors */ +/* Remove up/down arrows on date/time input (to save on width) */ +.otp .search-options input[type="date"]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + +.otp .search-options input[type="time"]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + .otp .date-time-selector .col-xs-4, .otp .date-time-selector .col-xs-6 { padding-left: 5px; diff --git a/lib/components/form/intermediate-place-field.js b/lib/components/form/intermediate-place-field.js new file mode 100644 index 000000000..9d3f9aaae --- /dev/null +++ b/lib/components/form/intermediate-place-field.js @@ -0,0 +1,104 @@ +import LocationField from '@opentripplanner/location-field' +import { + DropdownContainer, + FormGroup, + Input, + InputGroup, + InputGroupAddon, + MenuItemA +} from '@opentripplanner/location-field/lib/styled' +import React, {Component} from 'react' +import { connect } from 'react-redux' +import styled from 'styled-components' + +import { clearLocation } from '../../actions/map' +import { addLocationSearch, getCurrentPosition } from '../../actions/location' +import { findNearbyStops } from '../../actions/api' +import { getShowUserSettings } from '../../util/state' + +const StyledIntermediatePlace = styled(LocationField)` + width: 100%; + + ${DropdownContainer} { + display: table-cell; + vertical-align: middle; + width: 1%; + } + + ${FormGroup} { + display: table; + padding: 6px 12px; + width: 100%; + } + + ${Input} { + display: table-cell; + padding: 6px 12px; + width: 100%; + } + + ${InputGroup} { + width: 100%; + } + + ${InputGroupAddon} { + display: table-cell; + vertical-align: middle; + width: 1%; + } + + ${MenuItemA} { + text-decoration: none; + } + + ${MenuItemA}:hover { + color: #333; + } +` + +/** + * Component that leverages LocationField to allow selecting an intermediate + * place (e.g., stopover on the way from origin to the destination). + * TODO: move this to otp-ui? + */ +class IntermediatePlaceField extends Component { + _removeIntermediatePlace = () => { + const {index, location, onLocationCleared} = this.props + onLocationCleared && onLocationCleared({location, index}) + } + + render () { + const {index} = this.props + return ( + + ) + } +} + +// connect to redux store + +const mapStateToProps = (state, ownProps) => { + const { config, location, transitIndex, user } = state.otp + const { currentPosition, nearbyStops, sessionSearches } = location + return { + currentPosition, + geocoderConfig: config.geocoder, + nearbyStops, + sessionSearches, + showUserSettings: getShowUserSettings(state.otp), + stopsIndex: transitIndex.stops, + userLocationsAndRecentPlaces: [...user.locations, ...user.recentPlaces] + } +} + +const mapDispatchToProps = { + addLocationSearch, + findNearbyStops, + getCurrentPosition, + clearLocation +} + +export default connect(mapStateToProps, mapDispatchToProps)(IntermediatePlaceField) diff --git a/lib/components/form/styled.js b/lib/components/form/styled.js index 3d0909694..69755ffc4 100644 --- a/lib/components/form/styled.js +++ b/lib/components/form/styled.js @@ -37,7 +37,7 @@ const commonInputCss = css` transition: border-color ease-in-out .15s, box-shadow ease-in-out .15s; ` -const modeButtonButtonCss = css` +export const modeButtonButtonCss = css` ${TripFormClasses.ModeButton.Button} { ${commonButtonCss} } @@ -96,16 +96,16 @@ export const StyledSettingsSelectorPanel = styled(SettingsSelectorPanel)` box-shadow: none; outline: none; padding: 3px; - } + } ${TripFormClasses.ModeButton.Title} { font-size: 10px; line-height: 12px; padding: 4px 0px 0px; - + &.active { font-weight: 600; } - } + } } ${TripFormClasses.ModeSelector.MainRow} { box-sizing: border-box; @@ -117,7 +117,7 @@ export const StyledSettingsSelectorPanel = styled(SettingsSelectorPanel)` width: 100%; &.active { font-weight: 600; - } + } } } ${TripFormClasses.ModeSelector.SecondaryRow} { diff --git a/lib/components/map/bounds-updating-overlay.js b/lib/components/map/bounds-updating-overlay.js index 6472f62df..230ae68c8 100644 --- a/lib/components/map/bounds-updating-overlay.js +++ b/lib/components/map/bounds-updating-overlay.js @@ -1,5 +1,6 @@ import isEqual from 'lodash.isequal' import coreUtils from '@opentripplanner/core-utils' +import L from 'leaflet' import { MapLayer, withLeaflet } from 'react-leaflet' import { connect } from 'react-redux' @@ -9,6 +10,18 @@ import { } from '../../util/itinerary' import { getActiveItinerary, getActiveSearch } from '../../util/state' +/** + * Utility to extend input Leaflet bounds to include the list of places. + */ +function extendBoundsByPlaces (bounds, places = []) { + places + .filter(place => place) + .forEach(place => { + const coords = [place.lat, place.lon] + if (coreUtils.map.isValidLatLng(coords)) bounds.extend(coords) + }) +} + /** * This MapLayer component will automatically update the leaflet bounds * depending on what data is in the redux store. This component does not @@ -53,6 +66,9 @@ class BoundsUpdatingOverlay extends MapLayer { const oldTo = oldProps.query && oldProps.query.to const fromChanged = !isEqual(oldFrom, newFrom) const toChanged = !isEqual(oldTo, newTo) + const oldIntermediate = oldProps.query && oldProps.query.intermediatePlaces + const newIntermediate = newProps.query && newProps.query.intermediatePlaces + const intermediateChanged = !isEqual(oldIntermediate, newIntermediate) if ( (!oldItinBounds && newItinBounds) || (oldItinBounds && newItinBounds && !oldItinBounds.equals(newItinBounds)) @@ -81,9 +97,17 @@ class BoundsUpdatingOverlay extends MapLayer { // TODO: Fix this so mobile devices will also update the bounds to the // from/to locations. if (!coreUtils.ui.isMobile()) { - map.fitBounds([ + const bounds = L.bounds([ [newFrom.lat, newFrom.lon], [newTo.lat, newTo.lon] + ]) + // Ensure bounds extend to include intermediatePlaces + extendBoundsByPlaces(bounds, newIntermediate) + const { x: left, y: bottom } = bounds.getBottomLeft() + const { x: right, y: top } = bounds.getTopRight() + map.fitBounds([ + [left, bottom], + [right, top] ], { padding }) } @@ -93,6 +117,12 @@ class BoundsUpdatingOverlay extends MapLayer { } else if (newTo && toChanged) { map.panTo([newTo.lat, newTo.lon]) + // If intermediate place is added, extend bounds. + } else if (newIntermediate && intermediateChanged) { + const bounds = map.getBounds() + extendBoundsByPlaces(bounds, newIntermediate) + map.fitBounds(bounds) + // Pan to to itinerary step if made active (clicked) } else if ( newProps.itinerary && diff --git a/lib/components/map/connected-endpoints-overlay.js b/lib/components/map/connected-endpoints-overlay.js index c609ce12d..0e85d3d80 100644 --- a/lib/components/map/connected-endpoints-overlay.js +++ b/lib/components/map/connected-endpoints-overlay.js @@ -18,8 +18,12 @@ const mapStateToProps = (state, ownProps) => { const query = activeSearch ? activeSearch.query : state.otp.currentQuery const showUserSettings = getShowUserSettings(state.otp) const { from, to } = query + // Intermediate places doesn't trigger a re-plan, so for now default to + // current query. FIXME: Determine with TriMet if this is desired behavior. + const places = state.otp.currentQuery.intermediatePlaces.filter(p => p) return { fromLocation: from, + intermediatePlaces: places, locations: state.otp.user.locations, showUserSettings, toLocation: to, diff --git a/lib/components/map/connected-transitive-overlay.js b/lib/components/map/connected-transitive-overlay.js index aa7843fd2..9b2eed104 100644 --- a/lib/components/map/connected-transitive-overlay.js +++ b/lib/components/map/connected-transitive-overlay.js @@ -2,7 +2,7 @@ import coreUtils from '@opentripplanner/core-utils' import TransitiveCanvasOverlay from '@opentripplanner/transitive-overlay' import { connect } from 'react-redux' -import { getActiveSearch, getActiveItineraries } from '../../util/state' +import { getActiveSearch, getActiveItinerary, getActiveItineraries } from '../../util/state' // connect to the redux store @@ -13,11 +13,16 @@ const mapStateToProps = (state, ownProps) => { activeSearch && activeSearch.query.routingType === 'ITINERARY' && activeSearch.response && - activeSearch.response.plan + activeSearch.response.length > 0 ) { + // FIXME: This may need some simplification. const itins = getActiveItineraries(state.otp) + const visibleIndex = activeSearch.visibleItinerary !== undefined && activeSearch.visibleItinerary !== null + ? activeSearch.visibleItinerary + : activeSearch.activeItinerary // TODO: prevent itineraryToTransitive() from being called more than needed - transitiveData = coreUtils.map.itineraryToTransitive(itins[activeSearch.activeItinerary]) + const visibleItinerary = itins[visibleIndex] ? itins[visibleIndex] : getActiveItinerary(state.otp) + if (visibleItinerary) transitiveData = coreUtils.map.itineraryToTransitive(visibleItinerary) } else if ( activeSearch && activeSearch.response && diff --git a/lib/components/map/stylized-map.js b/lib/components/map/stylized-map.js index 54e25509c..48a8ee794 100644 --- a/lib/components/map/stylized-map.js +++ b/lib/components/map/stylized-map.js @@ -116,7 +116,8 @@ const mapStateToProps = (state, ownProps) => { activeSearch.response.plan ) { const itins = getActiveItineraries(state.otp) - transitiveData = coreUtils.map.itineraryToTransitive(itins[activeSearch.activeItinerary]) + const visibleItinerary = itins[activeSearch.activeItinerary] + if (visibleItinerary) transitiveData = coreUtils.map.itineraryToTransitive(visibleItinerary) } else if ( activeSearch && activeSearch.response && diff --git a/lib/components/narrative/default/default-itinerary.js b/lib/components/narrative/default/default-itinerary.js index f93f356c0..36170108e 100644 --- a/lib/components/narrative/default/default-itinerary.js +++ b/lib/components/narrative/default/default-itinerary.js @@ -2,56 +2,190 @@ import coreUtils from '@opentripplanner/core-utils' import React from 'react' import NarrativeItinerary from '../narrative-itinerary' +import ItineraryBody from '../line-itin/connected-itinerary-body' import ItinerarySummary from './itinerary-summary' -import ItineraryDetails from './itinerary-details' -import TripDetails from '../connected-trip-details' -import TripTools from '../trip-tools' -import LinkButton from '../../user/link-button' +import SimpleRealtimeAnnotation from '../simple-realtime-annotation' +import { getTotalFareAsString } from '../../../util/state' +const { isBicycle, isTransit } = coreUtils.itinerary const { formatDuration, formatTime } = coreUtils.time +// FIXME move to core utils +function getItineraryDescription (itinerary) { + let primaryTransitDuration = 0 + let mainMode = 'Walk' + let transitMode + itinerary.legs.forEach((leg, i) => { + const {duration, mode, rentedBike} = leg + if (isTransit(mode) && duration > primaryTransitDuration) { + // TODO: convert OTP's TRAM mode to the correct wording for Portland + primaryTransitDuration = duration + transitMode = mode.toLowerCase() + } + if (isBicycle(mode)) mainMode = 'Bike' + if (rentedBike) mainMode = 'Bikeshare' + if (mode === 'CAR') mainMode = 'Drive' + }) + let description = mainMode + if (transitMode) description += ` to ${transitMode}` + return description +} + +const ITINERARY_ATTRIBUTES = [ + { + alias: 'best', + id: 'duration', + order: 0, + render: (itinerary, options) => formatDuration(itinerary.duration) + }, + { + alias: 'departureTime', + id: 'arrivalTime', + order: 1, + render: (itinerary, options) => { + if (options.isSelected) { + if (options.selection === 'ARRIVALTIME') return formatTime(itinerary.endTime, options) + else return formatTime(itinerary.startTime, options) + } + return ( + + {formatTime(itinerary.startTime, options)} + — + {formatTime(itinerary.endTime, options)} + + ) + } + }, + { + id: 'cost', + order: 2, + render: (itinerary, options) => getTotalFareAsString(itinerary) + }, + { + id: 'walkTime', + order: 3, + render: (itinerary, options) => { + const leg = itinerary.legs[0] + const {LegIcon} = options + return ( + // FIXME: For CAR mode, walk time considers driving time. + + {formatDuration(itinerary.walkTime)}{' '} +
    + +
    +
    + ) + } + } +] + export default class DefaultItinerary extends NarrativeItinerary { + _onMouseEnter = () => { + const {active, index, setVisibleItinerary, visibleItinerary} = this.props + // Set this itinerary as visible if not already visible. + const visibleNotSet = visibleItinerary === null || visibleItinerary === undefined + const isVisible = visibleItinerary === index || + (active === index && visibleNotSet) + if (typeof setVisibleItinerary === 'function' && !isVisible) { + setVisibleItinerary({index}) + } + } + + _onMouseLeave = () => { + const {index, setVisibleItinerary, visibleItinerary} = this.props + if (typeof setVisibleItinerary === 'function' && visibleItinerary === index) { + setVisibleItinerary({index: null}) + } + } + + _isSortingOnAttribute = (attribute) => { + const {sort} = this.props + if (sort && sort.type) { + const type = sort.type.toLowerCase() + return attribute.id.toLowerCase() === type || + (attribute.alias && attribute.alias.toLowerCase() === type) + } + return false + } + render () { const { active, - activeLeg, - activeStep, expanded, - index, itinerary, LegIcon, - setActiveLeg, - setActiveStep, - user + showRealtimeAnnotation, + timeFormat } = this.props + const timeOptions = { + format: timeFormat, + offset: coreUtils.itinerary.getTimeZoneOffset(itinerary) + } return ( -
    +
    - {(active || expanded) && -
    - - - -
    + {(active && expanded) && + <> + {showRealtimeAnnotation && } + + }
    ) diff --git a/lib/components/narrative/default/itinerary-summary.js b/lib/components/narrative/default/itinerary-summary.js index a2e61a836..d088dbdea 100644 --- a/lib/components/narrative/default/itinerary-summary.js +++ b/lib/components/narrative/default/itinerary-summary.js @@ -1,6 +1,23 @@ import React, { Component } from 'react' import PropTypes from 'prop-types' +const modeColors = { + BICYCLE: '#E0C3E2', + BUS: '#CAC3DF', + CAR: '#E4CCCC', + PARK: '#E4CCCC', + RAIL: '#BDDAC0', + WALK: '#DFC486' +} +const DEFAULT_COLOR = 'grey' + +function getModeColor (mode) { + if (!mode) return DEFAULT_COLOR + let color = modeColors[mode.toUpperCase()] + if (typeof color === 'undefined') color = DEFAULT_COLOR + return color +} + export default class ItinerarySummary extends Component { static propTypes = { itinerary: PropTypes.object, @@ -23,29 +40,37 @@ export default class ItinerarySummary extends Component { } // Add the mode icon + let title = leg.mode + if (leg.transitLeg) { + title = leg.routeShortName + ? `${leg.routeShortName}${leg.routeLongName ? ` - ${leg.routeLongName}` : ''}` + : leg.routeLongName + } + const style = { + margin: '0px', + padding: '3px', + height: '24px', + width: '24px', + backgroundColor: getModeColor(leg.mode) + } + if (i === 0) { + style.borderTopLeftRadius = '4px' + style.borderBottomLeftRadius = '4px' + } + if (i === itinerary.legs.length - 1) { + style.borderTopRightRadius = '4px' + style.borderBottomRightRadius = '4px' + } blocks.push( -
    +
    ) - - // If a transit leg, add the name (preferably short; long if needed) - if (leg.transitLeg) { - blocks.push( -
    - - {leg.routeShortName || leg.routeLongName} - -
    - ) - } - - // If not the last leg, add a 'â–º' - if (i < itinerary.legs.length - 1) { - blocks.push( -
    â–º
    - ) - } }) return
    {blocks}
    diff --git a/lib/components/narrative/default/itinerary.css b/lib/components/narrative/default/itinerary.css index 407aa19d5..b4203ba0f 100644 --- a/lib/components/narrative/default/itinerary.css +++ b/lib/components/narrative/default/itinerary.css @@ -4,20 +4,24 @@ outline: none; } +/* If child component is focused, highlight itinerary option */ +.otp .option.default-itin:focus-within { + background-color: var(--hover-color); +} + .otp .option.default-itin { - margin-bottom: 16px; padding: 10px; - border: 2px solid #999; - border-radius: 4px - background-color: #eeeeee; + background-color: white; } -.otp .option:hover .default-itin { - background-color: var(--hover-color); +/* Only show border is not expanded */ +.otp .option.default-itin:not(.expanded) { + border-top: 1px solid grey; } -.otp .option.active .default-itin { - background-color: #EAF3F2; +/* FIXME: don't highlight if not active */ +.otp .option.default-itin:hover:not(.active) { + background-color: var(--hover-color); } .otp .option.default-itin > .header { @@ -26,11 +30,27 @@ } .otp .option.default-itin > .header > .title { - font-weight: bold; + font-weight: 500; + font-size: large; + display: inline; +} + +.otp .option.default-itin > .header > .itinerary-attributes { + display: inline; + float: right; +} + +.otp .option.default-itin > .header > .itinerary-attributes > li { + font-size: small; +} + +.otp .option.default-itin > .header > .itinerary-attributes > li.main { + font-weight: 500; + font-size: x-large; } .otp .option.default-itin > .header > .summary { - text-align: center; + /* text-align: center; */ margin: 8px 0px; } diff --git a/lib/components/narrative/line-itin/connected-itinerary-body.js b/lib/components/narrative/line-itin/connected-itinerary-body.js index 974fd10c0..09253d6f2 100644 --- a/lib/components/narrative/line-itin/connected-itinerary-body.js +++ b/lib/components/narrative/line-itin/connected-itinerary-body.js @@ -19,7 +19,7 @@ import TripTools from '../trip-tools' const noop = () => {} const ItineraryBodyContainer = styled.div` - padding: 20px 0px; + padding: 0px 0px; ` const StyledItineraryBody = styled(ItineraryBody)` @@ -42,7 +42,6 @@ class ConnectedItineraryBody extends Component { LegIcon, setActiveLeg, setViewedTrip, - showElevationProfile, setLegDiagram, timeOptions } = this.props @@ -61,7 +60,7 @@ class ConnectedItineraryBody extends Component { setLegDiagram={setLegDiagram} setViewedTrip={setViewedTrip} showAgencyInfo - showElevationProfile={showElevationProfile} + showElevationProfile={config.elevationProfile} showLegIcon showMapButtonColumn={false} showRouteFares={config.itinerary && config.itinerary.showRouteFares} diff --git a/lib/components/narrative/line-itin/line-itinerary.js b/lib/components/narrative/line-itin/line-itinerary.js index 05fc8f311..bdd28f893 100644 --- a/lib/components/narrative/line-itin/line-itinerary.js +++ b/lib/components/narrative/line-itin/line-itinerary.js @@ -86,6 +86,7 @@ export default class LineItinerary extends NarrativeItinerary { ? 2) { + const last = arr.pop() + return arr.join(', ') + ' and ' + last + } else { + return arr.join(' and ') + } +} class NarrativeItineraries extends Component { static propTypes = { @@ -22,58 +44,198 @@ class NarrativeItineraries extends Component { setActiveLeg: PropTypes.func, setActiveStep: PropTypes.func, setUseRealtimeResponse: PropTypes.func, - useRealtime: PropTypes.bool, - companies: PropTypes.string + useRealtime: PropTypes.bool } static defaultProps = { itineraryClass: DefaultItinerary } + state = {} + + _toggleDetailedItinerary = () => { + this.setState({showDetails: !this.state.showDetails}) + } + + _saveTrip = () => { + // FIXME: Replace with new save-trip functionality. + window.confirm('Are you sure you want to save this trip?') + } + + _onFilterChange = evt => { + const {sort, updateItineraryFilter} = this.props + const {value} = evt.target + updateItineraryFilter({filter: value, sort}) + } + + _onSortChange = evt => { + const {value: type} = evt.target + const {filter, sort, updateItineraryFilter} = this.props + updateItineraryFilter({filter, sort: {...sort, type}}) + } + + _onSortDirChange = () => { + const {filter, sort, updateItineraryFilter} = this.props + const direction = sort.direction === 'ASC' ? 'DESC' : 'ASC' + updateItineraryFilter({filter, sort: {...sort, direction}}) + } + _toggleRealtimeItineraryClick = (e) => { const {setUseRealtimeResponse, useRealtime} = this.props setUseRealtimeResponse({useRealtime: !useRealtime}) } + _renderLoadingDivs = () => { + const {itineraries, modes, pending} = this.props + if (!pending) return null + // Construct loading divs as placeholders while all itineraries load. + const count = modes.combinations + ? modes.combinations.length - itineraries.length + : 0 + return Array.from( + {length: count}, + (v, i) => +
    + + + +
    + ) + } + render () { const { activeItinerary, + activeSearch, + containerStyle, + errors, + filter, itineraries, itineraryClass, + pending, + persistence, realtimeEffects, - useRealtime, - user + sort, + useRealtime } = this.props - if (!itineraries) return null - + if (!activeSearch) return null + const itineraryIsExpanded = activeItinerary !== undefined && activeItinerary !== null && this.state.showDetails + const showRealtimeAnnotation = realtimeEffects.isAffectedByRealtimeData && ( + realtimeEffects.exceedsThreshold || + realtimeEffects.routesDiffer || + !useRealtime + ) + const resultText = pending + ? 'Finding your options...' + : `${itineraries.length} itineraries found.` return ( -
    -
    - We found {itineraries.length} itineraries: +
    +
    + {itineraryIsExpanded + ? <> + + {/* FIXME: only save if meets requirements (e.g., is transit + non-realtime mode) */} + {persistence && persistence.enabled + ? + Save trip + + : null + } + + : <> +
    + {resultText} +
    + { // FIXME: Enable only when ITINERARY/BATCH routing type enabled. + + } +
    + + +
    + + } +
    +
    + {itineraries.map((itinerary, index) => { + const active = index === activeItinerary + // Hide non-active itineraries. + if (!active && itineraryIsExpanded) return null + return React.createElement(itineraryClass, { + itinerary, + index, + key: index, + active, + routingType: 'ITINERARY', + sort, + expanded: this.state.showDetails, + onClick: active ? this._toggleDetailedItinerary : undefined, + showRealtimeAnnotation, + ...this.props + }) + })} + {/* FIXME: Flesh out error design/move to component? */} + {errors.map((e, i) => { + const mode = humanReadableMode(e.requestParameters.mode) + return ( +
    +

    + {' '} + No trip found for {mode} +

    +
    {e.error.msg}
    +
    + ) + })} + {this._renderLoadingDivs()}
    - - {realtimeEffects.isAffectedByRealtimeData && ( - realtimeEffects.exceedsThreshold || - realtimeEffects.routesDiffer || - !useRealtime) && ( - - ) - } - - {itineraries.map((itinerary, index) => { - return React.createElement(itineraryClass, { - itinerary, - index, - key: index, - active: index === activeItinerary, - routingType: 'ITINERARY', - user, - ...this.props - }) - })}
    ) } @@ -83,12 +245,16 @@ class NarrativeItineraries extends Component { const mapStateToProps = (state, ownProps) => { const activeSearch = getActiveSearch(state.otp) - // const { activeItinerary, activeLeg, activeStep } = activeSearch ? activeSearch.activeItinerary : {} - const pending = activeSearch ? activeSearch.pending : false + const {persistence} = state.otp.config + const {modes} = state.otp.config + const {filter, sort} = state.otp.filter + const pending = activeSearch ? Boolean(activeSearch.pending) : false const itineraries = getActiveItineraries(state.otp) const realtimeEffects = getRealtimeEffects(state.otp) const useRealtime = state.otp.useRealtime return { + activeSearch, + errors: getActiveErrors(state.otp), // swap out realtime itineraries with non-realtime depending on boolean itineraries, pending, @@ -96,9 +262,13 @@ const mapStateToProps = (state, ownProps) => { activeItinerary: activeSearch && activeSearch.activeItinerary, activeLeg: activeSearch && activeSearch.activeLeg, activeStep: activeSearch && activeSearch.activeStep, + filter, + modes, + persistence, + sort, + timeFormat: coreUtils.time.getTimeFormat(state.otp.config), useRealtime, - user: state.user.loggedInUser, - companies: state.otp.currentQuery.companies + visibleItinerary: activeSearch && activeSearch.visibleItinerary } } @@ -107,18 +277,18 @@ const mapDispatchToProps = (dispatch, ownProps) => { // so that only one argument is passed, // e.g. setActiveLeg({ index, leg }) return { - setActiveItinerary: index => { - dispatch(setActiveItinerary({index})) - }, + setActiveItinerary: payload => dispatch(setActiveItinerary(payload)), + // FIXME setActiveLeg: (index, leg) => { dispatch(setActiveLeg({index, leg})) }, + // FIXME setActiveStep: (index, step) => { dispatch(setActiveStep({index, step})) }, - setUseRealtimeResponse: ({useRealtime}) => { - dispatch(setUseRealtimeResponse({useRealtime})) - } + setUseRealtimeResponse: payload => dispatch(setUseRealtimeResponse(payload)), + setVisibleItinerary: payload => dispatch(setVisibleItinerary(payload)), + updateItineraryFilter: payload => dispatch(updateItineraryFilter(payload)) } } diff --git a/lib/components/narrative/narrative-itinerary.js b/lib/components/narrative/narrative-itinerary.js index bcf62eb79..dd51139ba 100644 --- a/lib/components/narrative/narrative-itinerary.js +++ b/lib/components/narrative/narrative-itinerary.js @@ -13,17 +13,18 @@ export default class NarrativeItinerary extends Component { routingType: PropTypes.string, setActiveItinerary: PropTypes.func, setActiveLeg: PropTypes.func, - setActiveStep: PropTypes.func + setActiveStep: PropTypes.func, + setVisibleItinerary: PropTypes.func } _onHeaderClick = () => { - const { active, index, onClick, routingType, setActiveItinerary } = this.props + const { active, index, onClick, setActiveItinerary } = this.props if (onClick) { onClick() } else if (!active) { - setActiveItinerary(index) - } else if (routingType === 'PROFILE') { - setActiveItinerary(null) + setActiveItinerary && setActiveItinerary({index}) + } else { + setActiveItinerary && setActiveItinerary({index: null}) } } diff --git a/lib/components/narrative/narrative-routing-results.js b/lib/components/narrative/narrative-routing-results.js index f16634d26..a3dcd9e4b 100644 --- a/lib/components/narrative/narrative-routing-results.js +++ b/lib/components/narrative/narrative-routing-results.js @@ -44,11 +44,12 @@ class NarrativeRoutingResults extends Component { const mapStateToProps = (state, ownProps) => { const activeSearch = getActiveSearch(state.otp) + const pending = activeSearch ? Boolean(activeSearch.pending) : false return { mainPanelContent: state.otp.ui.mainPanelContent, error: activeSearch && activeSearch.response && activeSearch.response.error, itineraries: getActiveItineraries(state.otp), - pending: activeSearch && activeSearch.pending, + pending, routingType: activeSearch && activeSearch.query.routingType } } diff --git a/lib/components/narrative/narrative.css b/lib/components/narrative/narrative.css index ac8c4effa..dbbd0a24d 100644 --- a/lib/components/narrative/narrative.css +++ b/lib/components/narrative/narrative.css @@ -3,11 +3,30 @@ } .otp .options > .header { - margin-top: 20px; - margin-bottom: 12px; + margin: 20px 10px 12px; font-size: 16px; } +/* Options scroll bar */ +.otp .options > .list::-webkit-scrollbar { + width: 10px; +} + +/* Track */ +.otp .options > .list::-webkit-scrollbar-track { + background: #f1f1f1; +} + +/* Handle */ +.otp .options > .list::-webkit-scrollbar-thumb { + background: #888; +} + +/* Handle on hover */ +.otp .options > .list::-webkit-scrollbar-thumb:hover { + background: #555; +} + /* REALTIME ALERT */ .otp .realtime-alert { diff --git a/lib/components/narrative/tabbed-itineraries.js b/lib/components/narrative/tabbed-itineraries.js index 739429e64..02dc0f2ee 100644 --- a/lib/components/narrative/tabbed-itineraries.js +++ b/lib/components/narrative/tabbed-itineraries.js @@ -4,7 +4,7 @@ import React, { Component } from 'react' import { Button } from 'react-bootstrap' import { connect } from 'react-redux' -import { setActiveItinerary, setActiveLeg, setActiveStep, setUseRealtimeResponse } from '../../actions/narrative' +import * as narrativeActions from '../../actions/narrative' import DefaultItinerary from './default/default-itinerary' import { getActiveSearch, getRealtimeEffects } from '../../util/state' @@ -39,9 +39,10 @@ class TabbedItineraries extends Component { itineraries, itineraryClass, realtimeEffects, - useRealtime, + setActiveItinerary, timeFormat, - user + useRealtime, + ...itineraryClassProps } = this.props if (!itineraries) return null @@ -52,60 +53,18 @@ class TabbedItineraries extends Component { realtimeEffects.routesDiffer || !useRealtime ) - return (
    {itineraries.map((itinerary, index) => { - const timeOptions = { - format: timeFormat, - offset: getTimeZoneOffset(itinerary) - } - const classNames = ['tab-button', 'clear-button-formatting'] - const { caloriesBurned } = calculatePhysicalActivity(itinerary) - const { - centsToString, - maxTNCFare, - minTNCFare, - transitFare - } = calculateFares(itinerary) - // TODO: support non-USD - let minTotalFare = minTNCFare * 100 + transitFare - const plus = maxTNCFare && maxTNCFare > minTNCFare ? '+' : '' - if (index === activeItinerary) classNames.push('selected') return ( - + ) })}
    @@ -116,17 +75,20 @@ class TabbedItineraries extends Component { useRealtime={useRealtime} /> */} - {/* Show the active itinerary */} - {(activeItinerary !== null) && React.createElement(itineraryClass, { - itinerary: itineraries[activeItinerary], - index: activeItinerary, - key: activeItinerary, - active: true, - routingType: 'ITINERARY', - showRealtimeAnnotation, - user, - ...this.props - })} + {/* Show active itin if itineraries exist and active itin is defined. */} + {(itineraries.length > 0 && activeItinerary >= 0) + ? React.createElement(itineraryClass, { + itinerary: itineraries[activeItinerary], + index: activeItinerary, + key: activeItinerary, + active: true, + expanded: true, + routingType: 'ITINERARY', + showRealtimeAnnotation, + ...itineraryClassProps + }) + : null + }
    ) @@ -156,17 +118,84 @@ const mapStateToProps = (state, ownProps) => { } } +class TabButton extends Component { + _onClick = () => { + const {index, onClick} = this.props + // FIXME: change signature once actions resolved with otp-ui + onClick(index) + } + + render () { + const {index, isActive, itinerary, timeFormat} = this.props + const timeOptions = { + format: timeFormat, + offset: getTimeZoneOffset(itinerary) + } + const classNames = ['tab-button', 'clear-button-formatting'] + const { caloriesBurned } = calculatePhysicalActivity(itinerary) + const { + centsToString, + maxTNCFare, + minTNCFare, + transitFare + } = calculateFares(itinerary) + // TODO: support non-USD + const minTotalFare = minTNCFare * 100 + transitFare + const plus = maxTNCFare && maxTNCFare > minTNCFare ? '+' : '' + if (isActive) classNames.push('selected') + return ( + + ) + } +} + const mapDispatchToProps = (dispatch, ownProps) => { + const {setActiveItinerary, setActiveLeg, setActiveStep, setUseRealtimeResponse} = narrativeActions return { - setActiveItinerary: index => { + // FIXME + setActiveItinerary: (index) => { dispatch(setActiveItinerary({index})) }, + // FIXME setActiveLeg: (index, leg) => { dispatch(setActiveLeg({index, leg})) }, + // FIXME setActiveStep: (index, step) => { dispatch(setActiveStep({index, step})) }, + // FIXME setUseRealtimeResponse: ({useRealtime}) => { dispatch(setUseRealtimeResponse({useRealtime})) } diff --git a/lib/components/user/link-button.js b/lib/components/user/link-button.js index 9231cb3be..ad7d4e431 100644 --- a/lib/components/user/link-button.js +++ b/lib/components/user/link-button.js @@ -7,10 +7,13 @@ import * as uiActions from '../../actions/ui' /** * This button provides basic redirecting functionality. - * FIXME: Replace this component with Link (react-router-dom) or LinkContainer (react-router-bootstrap). + * FIXME: Replace this component with Link (react-router-dom) or LinkContainer + * (react-router-bootstrap). */ class LinkButton extends Component { static propTypes = { + className: PropTypes.string, + componentClass: PropTypes.string, /** The destination url when clicking the button. */ to: PropTypes.string.isRequired } @@ -20,7 +23,13 @@ class LinkButton extends Component { } render () { - return + // Default componentClass to react-bootstrap Button (can be overridden + // with, e.g., 'button') + const { children, className, componentClass = Button } = this.props + return React.createElement( + componentClass, + { children, className, onClick: this._handleClick } + ) } } diff --git a/lib/components/viewers/pattern-row.js b/lib/components/viewers/pattern-row.js new file mode 100644 index 000000000..9d4843cc1 --- /dev/null +++ b/lib/components/viewers/pattern-row.js @@ -0,0 +1,214 @@ +import React, { Component } from 'react' +import { VelocityTransitionGroup } from 'velocity-react' + +import Icon from '../narrative/icon' +import { getFormattedStopTime, getStatusLabel } from '../../util/viewer' + +/** + * Represents a single pattern row for displaying arrival times in the stop + * viewer. + */ +export default class PatternRow extends Component { + constructor () { + super() + this.state = { expanded: false } + } + + _toggleExpandedView = () => { + this.setState({ expanded: !this.state.expanded }) + } + + _renderNextArrivalsView = () => { + const { + pattern, + route, + stopTimes, + homeTimezone, + stopViewerArriving, + stopViewerConfig, + timeFormat + } = this.props + // sort stop times by next departure + let sortedStopTimes = [] + const hasStopTimes = stopTimes && stopTimes.length > 0 + if (hasStopTimes) { + sortedStopTimes = stopTimes + .concat() + .sort((a, b) => { + const aTime = a.serviceDay + a.realtimeDeparture + const bTime = b.serviceDay + b.realtimeDeparture + return aTime - bTime + }) + // We request only x departures per pattern, but the patterns are merged + // according to shared headsigns, so we need to slice the stop times + // here as well to ensure only x times are shown per route/headsign combo. + // This is applied after the sort, so we're keeping the soonest departures. + .slice(0, stopViewerConfig.numberOfDepartures) + } else { + // Do not include pattern row if it has no stop times. + return null + } + const routeName = route.shortName ? route.shortName : route.longName + + return ( + <> + {/* header row */} +
    + {/* route name */} +
    + {routeName} To {pattern.headsign} +
    + {/* next departure preview */} + {hasStopTimes && ( +
    + {getFormattedStopTime(sortedStopTimes[0], homeTimezone, stopViewerArriving, timeFormat)} +
    + )} + + {/* expansion chevron button */} +
    + +
    +
    + + {/* expanded view */} + + {this.state.expanded && ( +
    +
    + {/* trips table header row */} +
    +
    +
    DEPARTURE
    +
    STATUS
    +
    + + {/* list of upcoming trips */} + {hasStopTimes && ( + sortedStopTimes.map((stopTime, i) => { + return ( +
    +
    + To {stopTime.headsign} +
    +
    + {getFormattedStopTime(stopTime, homeTimezone, stopViewerArriving, timeFormat)} +
    +
    + {stopTime.realtimeState === 'UPDATED' + ? getStatusLabel(stopTime.departureDelay) + :
    + Scheduled +
    + } +
    +
    + ) + }) + )} +
    +
    + )} + + + ) + } + + _renderScheduleView = () => { + const { + pattern, + route, + stopTimes, + homeTimezone, + stopViewerArriving, + stopViewerConfig, + timeFormat + } = this.props + // sort stop times by next departure + let sortedStopTimes = [] + const hasStopTimes = stopTimes && stopTimes.length > 0 + if (hasStopTimes) { + sortedStopTimes = stopTimes + .concat() + .sort((a, b) => { + const aTime = a.serviceDay + a.scheduledDeparture + const bTime = b.serviceDay + b.scheduledDeparture + return aTime - bTime + }) + // We request only x departures per pattern, but the patterns are merged + // according to shared headsigns, so we need to slice the stop times + // here as well to ensure only x times are shown per route/headsign combo. + // This is applied after the sort, so we're keeping the soonest departures. + .slice(0, stopViewerConfig.numberOfDepartures) + } else { + // Do not include pattern row if it has no stop times. + return null + } + const routeName = route.shortName ? route.shortName : route.longName + return ( + <> + {/* header row */} +
    + {/* route name */} +
    + {routeName} To {pattern.headsign} +
    +
    +
    +
    + {/* trips table header row */} +
    +
    +
    BLOCK
    +
    DEPARTURE
    +
    + + {/* list of upcoming trips */} + {hasStopTimes && ( + sortedStopTimes.map((stopTime, i) => { + // Get formatted scheduled departure time. + const time = getFormattedStopTime(stopTime, homeTimezone, stopViewerArriving, timeFormat, true) + return ( +
    +
    + To {stopTime.headsign} +
    +
    + {stopTime.blockId} +
    +
    + {time} +
    +
    + ) + }) + )} +
    +
    + + ) + } + + render () { + return ( +
    + {this.props.showScheduleView + ? this._renderScheduleView() + : this._renderNextArrivalsView() + } +
    + ) + } +} diff --git a/lib/components/viewers/route-viewer.js b/lib/components/viewers/route-viewer.js index 3cb3e6df5..cf3a51a83 100644 --- a/lib/components/viewers/route-viewer.js +++ b/lib/components/viewers/route-viewer.js @@ -58,7 +58,7 @@ class RouteViewer extends Component { viewedRoute } = this.props const sortedRoutes = routes - ? Object.values(routes).sort(coreUtils.itinerary.routeComparator) + ? Object.values(routes).sort(coreUtils.route.routeComparator) : [] const agencySortedRoutes = transitOperators.length > 0 ? sortedRoutes.sort((a, b) => { diff --git a/lib/components/viewers/stop-viewer.js b/lib/components/viewers/stop-viewer.js index ac668f353..242c12533 100644 --- a/lib/components/viewers/stop-viewer.js +++ b/lib/components/viewers/stop-viewer.js @@ -6,23 +6,28 @@ import PropTypes from 'prop-types' import React, { Component } from 'react' import { Button } from 'react-bootstrap' import { connect } from 'react-redux' -import { VelocityTransitionGroup } from 'velocity-react' import Icon from '../narrative/icon' import { setMainPanelContent, toggleAutoRefresh } from '../../actions/ui' import { findStop, findStopTimesForStop } from '../../actions/api' import { forgetStop, rememberStop, setLocation } from '../../actions/map' +import PatternRow from './pattern-row' import { getShowUserSettings, getStopViewerConfig } from '../../util/state' +import { getRouteIdForPattern, getStopTimesByPattern } from '../../util/viewer' const { - formatDuration, - formatSecondsAfterMidnight, getTimeFormat, - getUserTimezone + getUserTimezone, + OTP_API_DATE_FORMAT } = coreUtils.time +const defaultState = { + date: moment().format(OTP_API_DATE_FORMAT), + scheduleView: false +} + class StopViewer extends Component { - state = {} + state = defaultState static propTypes = { hideBackButton: PropTypes.bool, @@ -96,6 +101,26 @@ class StopViewer extends Component { else rememberStop(stopData) } + _toggleScheduleView = () => { + const { findStopTimesForStop, viewedStop } = this.props + const {date, scheduleView: isShowingScheduleView} = this.state + if (!isShowingScheduleView) { + // If not currently showing schedule view, fetch schedules for current + // date and turn off auto refresh. + this._stopAutoRefresh() + findStopTimesForStop({ + stopId: viewedStop.stopId, + startTime: this._getStartTimeForDate(date), + timeRange: 86400 + }) + } else { + // Otherwise, turn on auto refresh. + this._startAutoRefresh() + this._refreshStopTimes() + } + this.setState({scheduleView: !isShowingScheduleView}) + } + _isFavorite = () => this.props.stopData && this.props.favoriteStops.findIndex(s => s.id === this.props.stopData.id) !== -1 @@ -107,6 +132,8 @@ class StopViewer extends Component { this.props.viewedStop && prevProps.viewedStop.stopId !== this.props.viewedStop.stopId ) { + // Reset state to default if stop changes (i.e., show next arrivals). + this.setState(defaultState) this.props.findStop({ stopId: this.props.viewedStop.stopId }) } // Handle stopping or starting the auto refresh timer. @@ -114,396 +141,193 @@ class StopViewer extends Component { else if (!prevProps.autoRefreshStopTimes && this.props.autoRefreshStopTimes) this._startAutoRefresh() } - render () { - const { - hideBackButton, - homeTimezone, - showUserSettings, - stopData, - stopViewerArriving, - stopViewerConfig, - timeFormat - } = this.props - const { spin } = this.state + /** + * Get today at midnight (morning) in seconds since epoch. + * FIXME: handle timezone diffs? + */ + _getStartTimeForDate = date => moment(date).startOf('day').unix() + + handleDateChange = evt => { + const { findStopTimesForStop, viewedStop } = this.props + const date = evt.target.value + findStopTimesForStop({ + stopId: viewedStop.stopId, + startTime: this._getStartTimeForDate(date), + timeRange: 86400 + }) + this.setState({ date }) + } + + _renderHeader = () => { + const {hideBackButton, showUserSettings, stopData} = this.props + return ( +
    + {/* Back button */} + {!hideBackButton && ( +
    + +
    + )} + + {/* Header Text */} +
    + {stopData + ? {stopData.name} + : Loading Stop... + } + {showUserSettings + ? + : null + } +
    +
    +
    + ) + } + + /** + * Plan trip from/to here buttons, plus the schedule/next arrivals toggle. + * TODO: Can this use SetFromToButtons? + */ + _renderControls = () => { + const {stopData} = this.props + const {scheduleView} = this.state // Rewrite stop ID to not include Agency prefix, if present // TODO: make this functionality configurable? let stopId if (stopData && stopData.id) { stopId = stopData.id.includes(':') ? stopData.id.split(':')[1] : stopData.id } - // construct a lookup table mapping pattern (e.g. 'ROUTE_ID-HEADSIGN') to an array of stoptimes - const stopTimesByPattern = {} - if (stopData && stopData.routes && stopData.stopTimes) { - stopData.stopTimes.forEach(patternTimes => { - const routeId = getRouteIdForPattern(patternTimes.pattern) - const headsign = patternTimes.times[0] && patternTimes.times[0].headsign - patternTimes.pattern.headsign = headsign - const id = `${routeId}-${headsign}` - if (!(id in stopTimesByPattern)) { - const route = stopData.routes.find(r => r.id === routeId) - // in some cases, the TriMet transit index will not return all routes - // that serve a stop. Perhaps it doesn't return some routes if the - // route only performs a drop-off at the stop... not quite sure. So a - // check is needed to make sure we don't add data for routes not found - // from the routes query. - if (!route) { - console.warn(`Route with id ${routeId} not found in list of routes! No stop times from this route will be displayed.`) - return - } - stopTimesByPattern[id] = { - id, - route, - pattern: patternTimes.pattern, - times: [] - } - } - const filteredTimes = patternTimes.times.filter(stopTime => { - return stopTime.stopIndex < stopTime.stopCount - 1 // ensure that this isn't the last stop - }) - stopTimesByPattern[id].times = stopTimesByPattern[id].times.concat(filteredTimes) - }) - } return ( -
    - {/* Header Block */} -
    - {/* Back button */} - {!hideBackButton && ( -
    - -
    - )} - - {/* Header Text */} -
    - {stopData - ? {stopData.name} - : Loading Stop... - } - {showUserSettings - ? - : null - } -
    -
    +
    +
    + Stop ID: {stopId} +
    - - {stopData && ( -
    - {/* - Plan trip from/to here buttons. - TODO: Can this be combined w/ SetFromToButtons? - */ } -
    -
    - Stop ID: {stopId} - -
    - Plan a trip: - -
    - - {/* pattern listing */} - {stopData.stopTimes && stopData.routes && ( -
    - {Object.values(stopTimesByPattern) - .sort((a, b) => coreUtils.itinerary.routeComparator(a.route, b.route)) - .map(patternTimes => { - // Only add pattern row if route is found. - // FIXME: there is currently a bug with the alernative transit index - // where routes are not associated with the stop if the only stoptimes - // for the stop are drop off only. See https://github.com/ibi-group/trimet-mod-otp/issues/217 - if (!patternTimes.route) { - console.warn(`Cannot render stop times for missing route ID: ${getRouteIdForPattern(patternTimes.pattern)}`) - return null - } - return ( - - ) - }) - } -
    - )} -
    - -
    - {/* Future: add stop details */} -
    - )} + Plan a trip: + + {scheduleView && }
    ) } -} - -class PatternRow extends Component { - constructor () { - super() - this.state = { expanded: false } - } - - _toggleExpandedView = () => { - this.setState({ expanded: !this.state.expanded }) - } render () { const { - pattern, - route, - stopTimes, homeTimezone, + stopData, stopViewerArriving, stopViewerConfig, timeFormat } = this.props - // sort stop times by next departure - let sortedStopTimes = [] - const hasStopTimes = stopTimes && stopTimes.length > 0 - if (hasStopTimes) { - sortedStopTimes = stopTimes - .concat() - .sort((a, b) => { - const aTime = a.serviceDay + a.realtimeDeparture - const bTime = b.serviceDay + b.realtimeDeparture - return aTime - bTime - }) - // We request only x departures per pattern, but the patterns are merged - // according to shared headsigns, so we need to slice the stop times - // here as well to ensure only x times are shown per route/headsign combo. - // This is applied after the sort, so we're keeping the soonest departures. - .slice(0, stopViewerConfig.numberOfDepartures) - } else { - // Do not include pattern row if it has no stop times. - return null - } - const routeName = route.shortName ? route.shortName : route.longName - + const { scheduleView, spin } = this.state + const hasStopTimesAndRoutes = !!(stopData && stopData.stopTimes && stopData.stopTimes.length > 0 && stopData.routes) + // construct a lookup table mapping pattern (e.g. 'ROUTE_ID-HEADSIGN') to an array of stoptimes + const stopTimesByPattern = getStopTimesByPattern(stopData) return ( -
    - {/* header row */} -
    - {/* route name */} -
    - {/* */} -
    - - {/* next departure preview */} - {hasStopTimes && ( -
    - {getFormattedStopTime(sortedStopTimes[0], homeTimezone, stopViewerArriving, timeFormat)} -
    - )} - - {/* expansion chevron button */} -
    - -
    -
    +
    + {/* Header Block */} + {this._renderHeader()} - {/* expanded view */} - - {this.state.expanded && ( -
    -
    - {/* trips table header row */} -
    -
    -
    DEPARTURE
    -
    STATUS
    + {stopData && ( +
    + {this._renderControls()} + {hasStopTimesAndRoutes + ? <> +
    + {Object.values(stopTimesByPattern) + .sort((a, b) => coreUtils.route.routeComparator(a.route, b.route)) + .map(patternTimes => { + // Only add pattern row if route is found. + // FIXME: there is currently a bug with the alernative transit index + // where routes are not associated with the stop if the only stoptimes + // for the stop are drop off only. See https://github.com/ibi-group/trimet-mod-otp/issues/217 + if (!patternTimes.route) { + console.warn(`Cannot render stop times for missing route ID: ${getRouteIdForPattern(patternTimes.pattern)}`) + return null + } + return ( + + ) + }) + }
    - - {/* list of upcoming trips */} - {hasStopTimes && ( - sortedStopTimes.map((stopTime, i) => { - return ( -
    -
    - To {stopTime.headsign} -
    -
    - {getFormattedStopTime(stopTime, homeTimezone, stopViewerArriving, timeFormat)} -
    -
    - {stopTime.realtimeState === 'UPDATED' - ? getStatusLabel(stopTime.departureDelay) - :
    - Scheduled -
    - } -
    -
    - ) - }) - )} -
    -
    - )} - -
    - ) - } -} - -const ONE_HOUR_IN_SECONDS = 3600 -const ONE_DAY_IN_SECONDS = 86400 - -/** - * Helper method to generate stop time w/ status icon - * - * @param {object} stopTime A stopTime object as received from a transit index API - * @param {string} [homeTimezone] If configured, the timezone of the area - * @param {string} [soonText='Due'] The text to display for departure times - * about to depart in a short amount of time - * @param {string} timeFormat A valid moment.js formatting string - */ -function getFormattedStopTime (stopTime, homeTimezone, soonText = 'Due', timeFormat) { - const userTimeZone = getUserTimezone() - const inHomeTimezone = homeTimezone && homeTimezone === userTimeZone - - const now = moment().tz(homeTimezone) - const serviceDay = moment(stopTime.serviceDay * 1000).tz(homeTimezone) - // Determine if arrival occurs on different day, making sure to account for - // any extra days added to the service day if it arrives after midnight. Note: - // this can handle the rare (and non-existent?) case where an arrival occurs - // 48:00 hours (or more) from the start of the service day. - const departureTimeRemainder = stopTime.realtimeDeparture % ONE_DAY_IN_SECONDS - const daysAfterServiceDay = (stopTime.realtimeDeparture - departureTimeRemainder) / ONE_DAY_IN_SECONDS - const departureDay = serviceDay.add(daysAfterServiceDay, 'day') - const vehicleDepartsToday = now.dayOfYear() === departureDay.dayOfYear() - // Determine whether to show departure as countdown (e.g. "5 min") or as HH:mm - // time. - const secondsUntilDeparture = (stopTime.realtimeDeparture + stopTime.serviceDay) - now.unix() - // Determine if vehicle arrives after midnight in order to advance the day of - // the week when showing arrival time/day. - const departsInFuture = secondsUntilDeparture > 0 - // Show the exact time if the departure happens within an hour. - const showCountdown = secondsUntilDeparture < ONE_HOUR_IN_SECONDS && departsInFuture - - // Use "soon text" (e.g., Due) if vehicle is approaching. - const countdownString = secondsUntilDeparture < 60 - ? soonText - : formatDuration(secondsUntilDeparture) - const formattedTime = formatSecondsAfterMidnight( - stopTime.realtimeDeparture, - // Only show timezone (e.g., PDT) if user is not in home time zone (e.g., user - // in New York, but viewing a trip planner for service based in Los Angeles). - inHomeTimezone ? timeFormat : `${timeFormat} z` - ) - // We only want to show the day of the week if the arrival is on a - // different day and we're not showing the countdown string. This avoids - // cases such as when it's Wednesday at 11:55pm and an arrival occurs at - // Thursday 12:19am. We don't want the time to read: 'Thursday, 24 minutes'. - const showDayOfWeek = !vehicleDepartsToday && !showCountdown - return ( -
    -
    - {stopTime.realtimeState === 'UPDATED' - ? - : - } -
    -
    - {showDayOfWeek && -
    {departureDay.format('dddd')}
    - } -
    - {showCountdown - // Show countdown string (e.g., 3 min or Due) - ? countdownString - // Show formatted time (with timezone if user is not in home timezone) - : formattedTime - } -
    -
    -
    - ) -} - -function getRouteIdForPattern (pattern) { - const patternIdParts = pattern.id.split(':') - const routeId = patternIdParts[0] + ':' + patternIdParts[1] - return routeId -} - -// helper method to generate status label -function getStatusLabel (delay) { - // late departure - if (delay > 60) { - return ( -
    - {formatDuration(delay)} Late -
    - ) - } - - // early departure - if (delay < -60) { - return ( -
    - {formatDuration(Math.abs(delay))} Early + {!scheduleView + // If showing next arrivals, include auto update controls. + ?
    + + +
    + : null + } + + :
    No stop times found for date.
    + } + {/* Future: add stop details */} +
    + )}
    ) } - - // on-time departure - return ( -
    - On Time -
    - ) } // connect to redux store diff --git a/lib/components/viewers/viewers.css b/lib/components/viewers/viewers.css index 8c9e9d82c..9233de9f2 100644 --- a/lib/components/viewers/viewers.css +++ b/lib/components/viewers/viewers.css @@ -8,6 +8,11 @@ z-index: 1; /* Ensure sticky header stays on top of viewer body */ } +/* Remove arrows on date input */ +.otp .stop-viewer-body input[type="date"]::-webkit-inner-spin-button { + -webkit-appearance: none; +} + .otp .stop-viewer-body, .otp .trip-viewer-body { padding: 12px; } diff --git a/lib/index.css b/lib/index.css index 03c4e45e5..115a8c074 100644 --- a/lib/index.css +++ b/lib/index.css @@ -6,6 +6,7 @@ @import url(node_modules/transitive-js/lib/transitive.css); @import url(node_modules/leaflet.polylinemeasure/Leaflet.PolylineMeasure.css); +@import url(lib/components/admin/call-taker.css); @import url(lib/components/app/app.css); @import url(lib/components/map/map.css); @import url(lib/components/form/form.css); diff --git a/lib/index.js b/lib/index.js index 620c87193..c4b37bc47 100644 --- a/lib/index.js +++ b/lib/index.js @@ -1,3 +1,6 @@ +import CallTakerControls from './components/admin/call-taker-controls' +import CallTakerWindows from './components/admin/call-taker-windows' + import DateTimeModal from './components/form/date-time-modal' import DateTimePreview from './components/form/date-time-preview' import DefaultSearchForm from './components/form/default-search-form' @@ -36,6 +39,8 @@ import ViewerContainer from './components/viewers/viewer-container' import ResponsiveWebapp from './components/app/responsive-webapp' import AppMenu from './components/app/app-menu' +import BatchRoutingPanel from './components/app/batch-routing-panel' +import CallTakerPanel from './components/app/call-taker-panel' import DesktopNav from './components/app/desktop-nav' import DefaultMainPanel from './components/app/default-main-panel' @@ -45,6 +50,7 @@ import { setLocationToCurrent, clearLocation } from './actions/map' import { setUseRealtimeResponse } from './actions/narrative' import { findNearbyStops } from './actions/api' +import createCallTakerReducer from './reducers/call-taker' import createOtpReducer from './reducers/create-otp-reducer' import createUserReducer from './reducers/create-user-reducer' @@ -52,6 +58,8 @@ import otpUtils from './util' export { // form components + CallTakerControls, + CallTakerWindows, DateTimeModal, DateTimePreview, DefaultSearchForm, @@ -96,6 +104,8 @@ export { // app components, ResponsiveWebapp, AppMenu, + BatchRoutingPanel, + CallTakerPanel, DesktopNav, DefaultMainPanel, @@ -109,6 +119,7 @@ export { setUseRealtimeResponse, // redux utilities + createCallTakerReducer, createOtpReducer, createUserReducer, diff --git a/lib/reducers/call-taker.js b/lib/reducers/call-taker.js new file mode 100644 index 000000000..57f5e885c --- /dev/null +++ b/lib/reducers/call-taker.js @@ -0,0 +1,109 @@ +import coreUtils from '@opentripplanner/core-utils' +import update from 'immutability-helper' +import moment from 'moment' + +import {getTimestamp} from '../util/state' + +const { randId } = coreUtils.storage + +const UPPER_RIGHT_CORNER = {x: 604, y: 53} + +const FETCH_STATUS = { + UNFETCHED: 0, + FETCHING: 1, + FETCHED: 2, + ERROR: -1 +} + +function createCallTakerReducer () { + const initialState = { + activeCall: null, + callHistory: { + position: UPPER_RIGHT_CORNER, + visible: false, + calls: { + status: FETCH_STATUS.UNFETCHED, + data: [] + } + }, + fieldTrips: [], + session: null + } + return (state = initialState, action) => { + switch (action.type) { + case 'BEGIN_CALL': { + const newCall = { + startTime: getTimestamp(), + id: randId(), + searches: [] + } + // Initialize new call and show call history window. + return update(state, { + activeCall: { $set: newCall }, + callHistory: { visible: { $set: true } } + }) + } + case 'REQUESTING_CALLS': { + return update(state, { + callHistory: { calls: { status: { $set: FETCH_STATUS.FETCHING } } } + }) + } + case 'RECEIVED_CALLS': { + const data = action.payload.calls + const calls = { + status: FETCH_STATUS.FETCHED, + data: data.sort((a, b) => moment(b.endTime) - moment(a.endTime)) + } + return update(state, { + callHistory: { calls: { $set: calls } } + }) + } + case 'RECEIVED_QUERIES': { + const {callId, queries} = action.payload + const {data} = state.callHistory.calls + const index = data.findIndex(call => call.id === callId) + const call = {...data[index], queries} + return update(state, { + callHistory: { calls: { data: { [index]: { $set: call } } } } + }) + } + case 'ROUTING_RESPONSE': { + // If call is in progress, record search ID when a routing response is + // fulfilled. + // TODO: How should we handle routing errors. + if (state.activeCall) { + return update(state, { + activeCall: { searches: { $push: [action.payload.searchId] } } + }) + } + // Otherwise, ignore. + return state + } + case 'STORE_SESSION': { + const {session} = action.payload + if (!session || !session.username) { + const sessionId = session ? session.sessionId : 'N/A' + // Session is invalid if username is missing. + window.alert(`Session ID ${sessionId} is invalid!`) + // TODO: Should we return to URL_ROOT at this point? + return update(state, { session: { $set: null } }) + } + return update(state, { session: { $set: session } }) + } + case 'TOGGLE_CALL_HISTORY': { + return update(state, { + callHistory: { visible: { $set: !state.callHistory.visible } } + }) + } + case 'END_CALL': { + return update(state, { + activeCall: { $set: null } + }) + } + default: + return state + } + } +} + +export default createCallTakerReducer diff --git a/lib/reducers/create-otp-reducer.js b/lib/reducers/create-otp-reducer.js index 3ab796977..22c5d2a3e 100644 --- a/lib/reducers/create-otp-reducer.js +++ b/lib/reducers/create-otp-reducer.js @@ -5,6 +5,7 @@ import objectPath from 'object-path' import coreUtils from '@opentripplanner/core-utils' import { MainPanelContent, MobileScreens } from '../actions/ui' +import {getTimestamp} from '../util/state' const { isTransit, getTransitModes } = coreUtils.itinerary const { matchLatLon } = coreUtils.map @@ -105,6 +106,7 @@ export function getInitialState (userDefinedConfig, initialQuery) { const work = getItem('work') // Whether recent searches and places should be tracked in local storage. const trackRecent = getItem('trackRecent', false) + const expandAdvanced = getItem('expandAdvanced', false) // Recent places used in trip plan searches. const recentPlaces = getItem('recent', []) // List of user's favorite stops. @@ -155,6 +157,13 @@ export function getInitialState (userDefinedConfig, initialQuery) { return { config, currentQuery, + filter: { + filter: 'ALL', + sort: { + direction: 'ASC', + type: 'BEST' + } + }, location: { currentPosition: { error: null, @@ -168,6 +177,7 @@ export function getInitialState (userDefinedConfig, initialQuery) { autoRefreshStopTimes, // Do not store from/to or date/time in defaults defaults: getTripOptionsFromQuery(defaults), + expandAdvanced, favoriteStops, trackRecent, locations, @@ -217,15 +227,16 @@ export function getInitialState (userDefinedConfig, initialQuery) { function createOtpReducer (config, initialQuery) { const initialState = getInitialState(config, initialQuery) - // validate the inital state validateInitalState(initialState) return (state = initialState, action) => { const searchId = action.payload && action.payload.searchId + const requestId = action.payload && action.payload.requestId + const activeSearch = state.searches[searchId] switch (action.type) { case 'ROUTING_REQUEST': - const { activeItinerary } = action.payload + const { activeItinerary, pending } = action.payload return update(state, { searches: { [searchId]: { @@ -233,9 +244,11 @@ function createOtpReducer (config, initialQuery) { activeItinerary, activeLeg: null, activeStep: null, - pending: true, + pending, + // FIXME: get query from action payload? query: clone(state.currentQuery), - response: null + response: [], + timestamp: getTimestamp() } } }, @@ -246,11 +259,12 @@ function createOtpReducer (config, initialQuery) { searches: { [searchId]: { response: { - $set: { - error: action.payload.error - } + $push: [{ + error: action.payload.error, + requestId + }] }, - pending: { $set: false } + pending: { $set: activeSearch.pending - 1 } } } }) @@ -258,12 +272,12 @@ function createOtpReducer (config, initialQuery) { const response = (state.currentQuery.routingType === 'PROFILE') ? filterProfileOptions(action.payload.response) : action.payload.response - + response.requestId = requestId return update(state, { searches: { [searchId]: { - response: { $set: response }, - pending: { $set: false } + response: { $push: [response] }, + pending: { $set: activeSearch.pending - 1 } } }, ui: { @@ -358,6 +372,17 @@ function createOtpReducer (config, initialQuery) { }) } return state + case 'SET_VISIBLE_ITINERARY': + if (state.activeSearchId !== null) { + return update(state, { + searches: { + [state.activeSearchId]: { + visibleItinerary: { $set: action.payload.index } + } + } + }) + } + return state case 'SET_ACTIVE_LEG': if (state.activeSearchId !== null) { return update(state, { @@ -494,6 +519,13 @@ function createOtpReducer (config, initialQuery) { storeItem('favoriteStops', favoriteStops) return update(state, { user: { favoriteStops: { $set: favoriteStops } } }) } + // FIXME: set up action + case 'TOGGLE_ADVANCED_OPTIONS': + storeItem('expandAdvanced', action.payload) + if (!action.payload) removeItem('expandAdvanced') + return update(state, { user: { + expandAdvanced: { $set: action.payload } + } }) case 'TOGGLE_TRACKING': { storeItem('trackRecent', action.payload) let recentPlaces = clone(state.user.recentPlaces) @@ -883,6 +915,10 @@ function createOtpReducer (config, initialQuery) { ) default: return state + case 'UPDATE_ITINERARY_FILTER': + return update(state, + { filter: { $set: action.payload } } + ) } } } diff --git a/lib/util/call-taker.js b/lib/util/call-taker.js new file mode 100644 index 000000000..980c0cce3 --- /dev/null +++ b/lib/util/call-taker.js @@ -0,0 +1,22 @@ +import {getRoutingParams} from '../actions/api' + +function placeToLatLonStr (place) { + return `${place.lat.toFixed(6)},${place.lon.toFixed(6)}` +} + +/** + * Utility to map an OTP MOD UI search object to a Call Taker datastore query + * object. + */ +export function searchToQuery (search, call, otpConfig) { + // FIXME: how to handle realtime updates? + const queryParams = getRoutingParams(search.query, otpConfig, true) + const {from, to} = search.query + return { + queryParams: JSON.stringify(queryParams), + fromPlace: from.name || placeToLatLonStr(from), + toPlace: to.name || placeToLatLonStr(to), + timeStamp: search.query.timestamp, + call + } +} diff --git a/lib/util/state.js b/lib/util/state.js index cc22fc24c..813a247d8 100644 --- a/lib/util/state.js +++ b/lib/util/state.js @@ -1,8 +1,11 @@ import coreUtils from '@opentripplanner/core-utils' import isEqual from 'lodash.isequal' +import moment from 'moment' import { MainPanelContent } from '../actions/ui' +const { calculateFares, hasBike, isCar, isTransit, isWalk } = coreUtils.itinerary + /** * Get the active search object * @param {Object} otpState the OTP state object @@ -12,6 +15,32 @@ export function getActiveSearch (otpState) { return otpState.searches[otpState.activeSearchId] } +/** + * Get timestamp in the expected format used by otp-datastore (call taker + * back end). Defaults to now. + * TODO: move to OTP-UI? + */ +export function getTimestamp (time = moment()) { + return time.format('YYYY-MM-DDTHH:mm:ss') +} + +/** + * Gets the active errors returned for the OTP responses. + * @param {Object} otpState the OTP state object + * @return {Array} array of OTP plan responses with errors + */ +export function getActiveErrors (otpState) { + const search = getActiveSearch(otpState) + const errors = [] + const response = !search ? null : search.response + if (response) { + response.forEach(res => { + if (res && res.error) errors.push(res) + }) + } + return errors +} + /** * Get the active itineraries for the active search, which is dependent on * whether realtime or non-realtime results should be displayed @@ -21,13 +50,181 @@ export function getActiveSearch (otpState) { */ export function getActiveItineraries (otpState) { const search = getActiveSearch(otpState) - const { useRealtime } = otpState + const { config, useRealtime } = otpState // set response to use depending on useRealtime const response = !search ? null - : useRealtime ? search.response : search.nonRealtimeResponse - if (!response || !response.plan) return null - return response.plan.itineraries + : useRealtime + ? search.response + : search.nonRealtimeResponse + const itineraries = [] + if (response) { + response.forEach(res => { + if (res && res.plan) itineraries.push(...res.plan.itineraries) + }) + } + const {filter, sort} = otpState.filter + const {direction, type} = sort + return itineraries + .filter(itinerary => { + switch (filter) { + case 'ALL': + return true + case 'ACTIVE': + // ACTIVE filter checks that the only modes contained in the itinerary + // are 'active' (i.e., walk or bike). FIXME: add micromobility? + let allActiveModes = true + itinerary.legs.forEach(leg => { + if (!isWalk(leg.mode) && !hasBike(leg.mode)) allActiveModes = false + }) + return allActiveModes + case 'TRANSIT': + return itineraryHasTransit(itinerary) + case 'CAR': + let hasCar = false + itinerary.legs.forEach(leg => { + if (isCar(leg.mode)) hasCar = true + }) + return hasCar + default: + console.warn(`Filter (${filter}) not supported`) + return true + } + }) + .sort((a, b) => { + switch (type) { + case 'WALKTIME': + if (direction === 'ASC') return a.walkTime - b.walkTime + else return b.walkTime - a.walkTime + case 'ARRIVALTIME': + if (direction === 'ASC') return a.endTime - b.endTime + else return b.endTime - a.endTime + case 'DEPARTURETIME': + if (direction === 'ASC') return a.startTime - b.startTime + else return b.startTime - a.startTime + case 'DURATION': + if (direction === 'ASC') return a.duration - b.duration + else return b.duration - a.duration + case 'COST': + const aTotal = getTotalFare(a, config) + const bTotal = getTotalFare(b, config) + if (direction === 'ASC') return aTotal - bTotal + else return bTotal - aTotal + default: + if (type !== 'BEST') console.warn(`Sort (${type}) not supported. Defaulting to BEST.`) + // FIXME: Fully implement default sort algorithm. + const aCost = calculateItineraryCost(a, config) + const bCost = calculateItineraryCost(b, config) + if (direction === 'ASC') return aCost - bCost + else return bCost - aCost + } + }) +} + +/** + * Default constants for calculating itinerary "cost", i.e., how preferential a + * particular itinerary is based on factors like wait time, total fare, drive + * time, etc. + */ +const DEFAULT_WEIGHTS = { + walkReluctance: 0.1, + driveReluctance: 2, + durationFactor: 0.25, + fareFactor: 0.5, + waitReluctance: 0.1, + transferReluctance: 0.9 +} + +/** + * This calculates the "cost" (not the monetary cost, but the cost according to + * multiple factors like duration, total fare, and walking distance) for a + * particular itinerary, for use in sorting itineraries. + * FIXME: Do major testing to get this right. + */ +function calculateItineraryCost (itinerary, config = {}) { + // Initialize weights to default values. + const weights = DEFAULT_WEIGHTS + // If config contains values to override defaults, apply those. + const configWeights = config.itinerary && config.itinerary.weights + if (configWeights) Object.assign(weights, configWeights) + return getTotalFare(itinerary, config) * weights.fareFactor + + itinerary.duration * weights.durationFactor + + itinerary.walkDistance * weights.walkReluctance + + getDriveTime(itinerary) * weights.driveReluctance + + itinerary.waitingTime * weights.waitReluctance + + itinerary.transfers * weights.transferReluctance +} + +/** + * Get total drive time (i.e., total duration for legs with mode=CAR) for an + * itinerary. + */ +function getDriveTime (itinerary) { + if (!itinerary) return 0 + let driveTime = 0 + itinerary.legs.forEach(leg => { + if (leg.mode === 'CAR') driveTime += leg.duration + }) + return driveTime +} + +/** + * Default costs for modes that currently have no costs evaluated in + * OpenTripPlanner. + */ +const DEFAULT_COSTS = { + // $2 per trip? This is a made up number. + bikeshareTripCostCents: 2 * 100, + // $2 for 3 hours of parking? + carParkingCostCents: 3 * 2.00 * 100, + // FL per diem rate: https://www.flcourts.org/content/download/219314/1981830/TravelInformation.pdf + drivingCentsPerMile: 0.445 * 100 +} + +/** + * Returns total fare for itinerary (in cents) + * FIXME: Move to otp-ui? + * TODO: Add GBFS fares + */ +function getTotalFare (itinerary, config = {}) { + // Get transit/TNC fares. + const {maxTNCFare, transitFare} = calculateFares(itinerary) + // Start with default cost values. + const costs = DEFAULT_COSTS + // If config contains values to override defaults, apply those. + const configCosts = config.itinerary && config.itinerary.costs + if (configCosts) Object.assign(costs, configCosts) + // Calculate total cost from itinerary legs. + let drivingCost = 0 + let hasBikeshare = false + itinerary.legs.forEach(leg => { + if (leg.mode === 'CAR') { + // Convert meters to miles and multiple by cost per mile. + drivingCost += leg.distance * 0.000621371 * costs.drivingCentsPerMile + } + if (leg.mode === 'BICYCLE_RENT' || leg.mode === 'MICROMOBILITY' || leg.rentedBike) { + hasBikeshare = true + } + }) + const bikeshareCost = hasBikeshare ? costs.bikeshareTripCostCents : 0 + // If some leg uses driving, add parking cost to the total. + if (drivingCost > 0) drivingCost += costs.carParkingCostCents + return bikeshareCost + drivingCost + transitFare + maxTNCFare * 100 +} + +export function getTotalFareAsString (itinerary) { + // Get centsToString formatter. + const {centsToString} = calculateFares(itinerary) + // Return total fare as formatted string. + return centsToString(getTotalFare(itinerary)) +} + +function itineraryHasTransit (itinerary) { + let itinHasTransit = false + itinerary.legs.forEach(leg => { + if (isTransit(leg.mode)) itinHasTransit = true + }) + return itinHasTransit } /** @@ -39,7 +236,7 @@ export function getActiveItineraries (otpState) { export function getActiveItinerary (otpState) { const search = getActiveSearch(otpState) const itineraries = getActiveItineraries(otpState) - if (!itineraries) return null + if (!itineraries || !search) return null return itineraries.length > search.activeItinerary && search.activeItinerary >= 0 ? itineraries[search.activeItinerary] : null @@ -47,14 +244,14 @@ export function getActiveItinerary (otpState) { /** * Determine if the current query has a valid location, including lat/lon - * @param {Object} otpState the OTP state object + * @param {Object} query an OTP query object * @param {string} locationKey the location key ('from' or 'to') * @returns {boolean} */ -export function hasValidLocation (otpState, locationKey) { - return otpState.currentQuery[locationKey] && - otpState.currentQuery[locationKey].lat && - otpState.currentQuery[locationKey].lon +export function hasValidLocation (query, locationKey) { + return query[locationKey] && + query[locationKey].lat && + query[locationKey].lon } /** @@ -63,8 +260,9 @@ export function hasValidLocation (otpState, locationKey) { * @returns {boolean} */ export function queryIsValid (otpState) { - return hasValidLocation(otpState, 'from') && - hasValidLocation(otpState, 'to') + const {currentQuery} = otpState + return hasValidLocation(currentQuery, 'from') && + hasValidLocation(currentQuery, 'to') // TODO: add mode validation // TODO: add date/time validation } diff --git a/lib/util/viewer.js b/lib/util/viewer.js new file mode 100644 index 000000000..359dffefe --- /dev/null +++ b/lib/util/viewer.js @@ -0,0 +1,164 @@ +import coreUtils from '@opentripplanner/core-utils' +import moment from 'moment' +import 'moment-timezone' +import React from 'react' + +import Icon from '../components/narrative/icon' + +const { + formatDuration, + formatSecondsAfterMidnight, + getUserTimezone +} = coreUtils.time + +const ONE_HOUR_IN_SECONDS = 3600 +const ONE_DAY_IN_SECONDS = 86400 + +/** + * Helper method to generate stop time w/ status icon + * + * @param {Object} stopTime A stopTime object as received from a transit index API + * @param {string} [homeTimezone] If configured, the timezone of the area + * @param {string} [soonText='Due'] The text to display for departure times + * about to depart in a short amount of time + * @param {string} timeFormat A valid moment.js formatting string + * @param {boolean} useSchedule Whether to use scheduled departure (otherwise uses realtime) + */ +export function getFormattedStopTime (stopTime, homeTimezone, soonText = 'Due', timeFormat, useSchedule = false) { + const departureTime = useSchedule + ? stopTime.scheduledDeparture + : stopTime.realtimeDeparture + const userTimeZone = getUserTimezone() + const inHomeTimezone = homeTimezone && homeTimezone === userTimeZone + + const now = moment().tz(homeTimezone) + const serviceDay = moment(stopTime.serviceDay * 1000).tz(homeTimezone) + // Determine if arrival occurs on different day, making sure to account for + // any extra days added to the service day if it arrives after midnight. Note: + // this can handle the rare (and non-existent?) case where an arrival occurs + // 48:00 hours (or more) from the start of the service day. + const departureTimeRemainder = departureTime % ONE_DAY_IN_SECONDS + const daysAfterServiceDay = (departureTime - departureTimeRemainder) / ONE_DAY_IN_SECONDS + const departureDay = serviceDay.add(daysAfterServiceDay, 'day') + const vehicleDepartsToday = now.dayOfYear() === departureDay.dayOfYear() + // Determine whether to show departure as countdown (e.g. "5 min") or as HH:mm + // time. + const secondsUntilDeparture = (departureTime + stopTime.serviceDay) - now.unix() + // Determine if vehicle arrives after midnight in order to advance the day of + // the week when showing arrival time/day. + const departsInFuture = secondsUntilDeparture > 0 + // Show the exact time if the departure happens within an hour. + const showCountdown = secondsUntilDeparture < ONE_HOUR_IN_SECONDS && departsInFuture + + // Use "soon text" (e.g., Due) if vehicle is approaching. + const countdownString = secondsUntilDeparture < 60 + ? soonText + : formatDuration(secondsUntilDeparture) + const formattedTime = formatSecondsAfterMidnight( + departureTime, + // Only show timezone (e.g., PDT) if user is not in home time zone (e.g., user + // in New York, but viewing a trip planner for service based in Los Angeles). + inHomeTimezone ? timeFormat : `${timeFormat} z` + ) + // We only want to show the day of the week if the arrival is on a + // different day and we're not showing the countdown string. This avoids + // cases such as when it's Wednesday at 11:55pm and an arrival occurs at + // Thursday 12:19am. We don't want the time to read: 'Thursday, 24 minutes'. + const showDayOfWeek = !vehicleDepartsToday && !showCountdown + return ( +
    +
    + {stopTime.realtimeState === 'UPDATED' + ? + : + } +
    +
    + {showDayOfWeek && +
    {departureDay.format('dddd')}
    + } +
    + {showCountdown + // Show countdown string (e.g., 3 min or Due) + ? countdownString + // Show formatted time (with timezone if user is not in home timezone) + : formattedTime + } +
    +
    +
    + ) +} + +export function getRouteIdForPattern (pattern) { + const patternIdParts = pattern.id.split(':') + const routeId = patternIdParts[0] + ':' + patternIdParts[1] + return routeId +} + +// helper method to generate status label +export function getStatusLabel (delay) { + // late departure + if (delay > 60) { + return ( +
    + {formatDuration(delay)} Late +
    + ) + } + + // early departure + if (delay < -60) { + return ( +
    + {formatDuration(Math.abs(delay))} Early +
    + ) + } + + // on-time departure + return ( +
    + On Time +
    + ) +} + +export function getStopTimesByPattern (stopData) { + const stopTimesByPattern = {} + if (stopData && stopData.routes && stopData.stopTimes) { + stopData.stopTimes.forEach(patternTimes => { + const routeId = getRouteIdForPattern(patternTimes.pattern) + const headsign = patternTimes.times[0] && patternTimes.times[0].headsign + patternTimes.pattern.headsign = headsign + const id = `${routeId}-${headsign}` + if (!(id in stopTimesByPattern)) { + const route = stopData.routes.find(r => r.id === routeId) + // in some cases, the TriMet transit index will not return all routes + // that serve a stop. Perhaps it doesn't return some routes if the + // route only performs a drop-off at the stop... not quite sure. So a + // check is needed to make sure we don't add data for routes not found + // from the routes query. + if (!route) { + console.warn(`Route with id ${routeId} not found in list of routes! No stop times from this route will be displayed.`) + return + } + stopTimesByPattern[id] = { + id, + route, + pattern: patternTimes.pattern, + times: [] + } + } + const filteredTimes = patternTimes.times.filter(stopTime => { + return stopTime.stopIndex < stopTime.stopCount - 1 // ensure that this isn't the last stop + }) + stopTimesByPattern[id].times = stopTimesByPattern[id].times.concat(filteredTimes) + }) + } + return stopTimesByPattern +} diff --git a/package.json b/package.json index af3ec60b0..0a3caa852 100644 --- a/package.json +++ b/package.json @@ -28,15 +28,15 @@ "homepage": "https://github.com/opentripplanner/otp-react-redux#readme", "dependencies": { "@opentripplanner/base-map": "^1.0.2", - "@opentripplanner/core-utils": "^1.2.1", - "@opentripplanner/endpoints-overlay": "^1.0.1", + "@opentripplanner/core-utils": "^2.1.2", + "@opentripplanner/endpoints-overlay": "^1.0.2", "@opentripplanner/from-to-location-picker": "^1.0.1", "@opentripplanner/geocoder": "^1.0.2", "@opentripplanner/humanize-distance": "^0.0.22", "@opentripplanner/icons": "^1.0.1", "@opentripplanner/itinerary-body": "^1.2.0", "@opentripplanner/location-field": "^1.0.2", - "@opentripplanner/location-icon": "^1.0.0", + "@opentripplanner/location-icon": "^1.0.1", "@opentripplanner/park-and-ride-overlay": "^1.0.1", "@opentripplanner/printable-itinerary": "^1.0.0", "@opentripplanner/route-viewer-overlay": "^1.0.1", @@ -74,10 +74,13 @@ "react-bootstrap": "^0.32.1", "react-dates": "^6.0.2", "react-dom": "^16.9.0", + "react-draggable": "^4.4.3", "react-fontawesome": "^1.5.0", + "react-loading-skeleton": "^2.1.1", "react-redux": "^7.1.0", "react-resize-detector": "^2.1.0", "react-router": "^5.0.1", + "react-select": "^3.1.0", "react-swipeable-views": "^0.13.3", "redux": "^4.0.4", "redux-actions": "^1.2.1", @@ -88,7 +91,7 @@ "velocity-react": "^1.3.3" }, "devDependencies": { - "documentation": "^12.0.3", + "documentation": "^13.0.2", "enzyme": "^3.10.0", "enzyme-adapter-react-16": "^1.4.0", "enzyme-to-json": "^3.4.0", diff --git a/yarn.lock b/yarn.lock index 4ad4b8b1a..814264d1f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -15,65 +15,84 @@ promise-polyfill "^8.1.3" unfetch "^4.1.0" -"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.8.3.tgz#33e25903d7481181534e12ec0a25f16b6fcf419e" - integrity sha512-a9gxpmdXtZEInkCSHUJDLHZVBgb1QS0jhss4cPP93EW7s+uC5bikET2twEF3KV+7rDblJcmNvTR7VJejqd2C2g== +"@babel/code-frame@^7.0.0", "@babel/code-frame@^7.10.4", "@babel/code-frame@^7.5.5", "@babel/code-frame@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/code-frame/-/code-frame-7.10.4.tgz#168da1a36e90da68ae8d49c0f1b48c7c6249213a" + integrity sha512-vG6SvB6oYEhvgisZNFRmRCUkLz11c7rp+tbNTynGqc6mS1d5ATd/sGyV6W0KZZnXRKMTzZDRgQT3Ou9jhpAfUg== dependencies: - "@babel/highlight" "^7.8.3" + "@babel/highlight" "^7.10.4" -"@babel/core@^7.1.0", "@babel/core@^7.1.2", "@babel/core@^7.3.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.5.5.tgz#17b2686ef0d6bc58f963dddd68ab669755582c30" - integrity sha512-i4qoSr2KTtce0DmkuuQBV4AuQgGPUcPXMr9L5MyYAtk06z068lQ10a4O009fe5OB/DfNV+h+qqT7ddNV8UnRjg== - dependencies: - "@babel/code-frame" "^7.5.5" - "@babel/generator" "^7.5.5" - "@babel/helpers" "^7.5.5" - "@babel/parser" "^7.5.5" - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - convert-source-map "^1.1.0" +"@babel/compat-data@^7.10.4", "@babel/compat-data@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/compat-data/-/compat-data-7.11.0.tgz#e9f73efe09af1355b723a7f39b11bad637d7c99c" + integrity sha512-TPSvJfv73ng0pfnEOh17bYMPQbI95+nGWc71Ss4vZdRBHTDqmM9Z8ZV4rYz8Ks7sfzc95n30k6ODIq5UGnXcYQ== + dependencies: + browserslist "^4.12.0" + invariant "^2.2.4" + semver "^5.5.0" + +"@babel/core@^7.1.0", "@babel/core@^7.3.4", "@babel/core@^7.9.0": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.11.6.tgz#3a9455dc7387ff1bac45770650bc13ba04a15651" + integrity sha512-Wpcv03AGnmkgm6uS6k8iwhIwTrcP0m17TL1n1sy7qD0qelDu4XNeW0dN0mHfa+Gei211yDaLoEe/VlbXQzM4Bg== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.6" + "@babel/helper-module-transforms" "^7.11.0" + "@babel/helpers" "^7.10.4" + "@babel/parser" "^7.11.5" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.11.5" + "@babel/types" "^7.11.5" + convert-source-map "^1.7.0" debug "^4.1.0" - json5 "^2.1.0" - lodash "^4.17.13" + gensync "^1.0.0-beta.1" + json5 "^2.1.2" + lodash "^4.17.19" resolve "^1.3.2" semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.1.3", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5", "@babel/generator@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.8.6.tgz#57adf96d370c9a63c241cd719f9111468578537a" - integrity sha512-4bpOR5ZBz+wWcMeVtcf7FbjcFzCp+817z2/gHNncIRcM9MmKzUhtWCYAq27RAfUrAFwb+OCG1s9WEaVxfi6cjg== +"@babel/generator@^7.11.5", "@babel/generator@^7.11.6", "@babel/generator@^7.4.0", "@babel/generator@^7.5.5", "@babel/generator@^7.8.6", "@babel/generator@^7.9.4": + version "7.11.6" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.11.6.tgz#b868900f81b163b4d464ea24545c61cbac4dc620" + integrity sha512-DWtQ1PV3r+cLbySoHrwn9RWEgKMBLLma4OBQloPRyDYvc5msJM9kvTLo1YnlJd1P/ZuKbdli3ijr5q3FvAF3uA== dependencies: - "@babel/types" "^7.8.6" + "@babel/types" "^7.11.5" jsesc "^2.5.1" - lodash "^4.17.13" source-map "^0.5.0" -"@babel/helper-annotate-as-pure@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.0.0.tgz#323d39dd0b50e10c7c06ca7d7638e6864d8c5c32" - integrity sha512-3UYcJUj9kvSLbLbUIfQTqzcy5VX7GRZ/CCDrnOaZorFFM01aXp1+GJwuFGV4NDDoAS+mOUyHcO6UD/RfqOks3Q== +"@babel/helper-annotate-as-pure@^7.0.0", "@babel/helper-annotate-as-pure@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-annotate-as-pure/-/helper-annotate-as-pure-7.10.4.tgz#5bf0d495a3f757ac3bda48b5bf3b3ba309c72ba3" + integrity sha512-XQlqKQP4vXFB7BN8fEEerrmYvHp3fK/rBkRFz9jaJbzK0B1DSfej9Kc7ZzE8Z/OnId1jpJdNAZ3BFQjWG68rcA== dependencies: - "@babel/types" "^7.0.0" + "@babel/types" "^7.10.4" -"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.1.0.tgz#6b69628dfe4087798e0c4ed98e3d4a6b2fbd2f5f" - integrity sha512-qNSR4jrmJ8M1VMM9tibvyRAHXQs2PmaksQF7c1CGJNipfe3D8p+wgNwgso/P2A2r2mdgBWAXljNWR0QRZAMW8w== +"@babel/helper-builder-binary-assignment-operator-visitor@^7.1.0", "@babel/helper-builder-binary-assignment-operator-visitor@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-binary-assignment-operator-visitor/-/helper-builder-binary-assignment-operator-visitor-7.10.4.tgz#bb0b75f31bf98cbf9ff143c1ae578b87274ae1a3" + integrity sha512-L0zGlFrGWZK4PbT8AszSfLTM5sDU1+Az/En9VrdT8/LmEiJt4zXt+Jve9DCAnQcbqDhCI+29y/L93mrDzddCcg== dependencies: - "@babel/helper-explode-assignable-expression" "^7.1.0" - "@babel/types" "^7.0.0" + "@babel/helper-explode-assignable-expression" "^7.10.4" + "@babel/types" "^7.10.4" -"@babel/helper-builder-react-jsx@^7.3.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.3.0.tgz#a1ac95a5d2b3e88ae5e54846bf462eeb81b318a4" - integrity sha512-MjA9KgwCuPEkQd9ncSXvSyJ5y+j2sICHyrI0M3L+6fnS4wMSNDc1ARXsbTfbb2cXHn17VisSnU/sHFTCxVxSMw== +"@babel/helper-builder-react-jsx-experimental@^7.10.4", "@babel/helper-builder-react-jsx-experimental@^7.11.5": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx-experimental/-/helper-builder-react-jsx-experimental-7.11.5.tgz#4ea43dd63857b0a35cd1f1b161dc29b43414e79f" + integrity sha512-Vc4aPJnRZKWfzeCBsqTBnzulVNjABVdahSPhtdMD3Vs80ykx4a87jTHtF/VR+alSrDmNvat7l13yrRHauGcHVw== dependencies: - "@babel/types" "^7.3.0" - esutils "^2.0.0" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/types" "^7.11.5" + +"@babel/helper-builder-react-jsx@^7.10.4", "@babel/helper-builder-react-jsx@^7.3.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-builder-react-jsx/-/helper-builder-react-jsx-7.10.4.tgz#8095cddbff858e6fa9c326daee54a2f2732c1d5d" + integrity sha512-5nPcIZ7+KKDxT1427oBivl9V9YTal7qk0diccnh7RrcgrT/pGFOjgGw1dgryyx1GvHEpXVfoDF6Ak3rTiWh8Rg== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/types" "^7.10.4" "@babel/helper-call-delegate@^7.4.4": version "7.4.4" @@ -84,838 +103,946 @@ "@babel/traverse" "^7.4.4" "@babel/types" "^7.4.4" -"@babel/helper-create-class-features-plugin@^7.4.4", "@babel/helper-create-class-features-plugin@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.5.5.tgz#401f302c8ddbc0edd36f7c6b2887d8fa1122e5a4" - integrity sha512-ZsxkyYiRA7Bg+ZTRpPvB6AbOFKTFFK4LrvTet8lInm0V468MWCaSYJE+I7v2z2r8KNLtYiV+K5kTCnR7dvyZjg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" - -"@babel/helper-define-map@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.5.5.tgz#3dec32c2046f37e09b28c93eb0b103fd2a25d369" - integrity sha512-fTfxx7i0B5NJqvUOBBGREnrqbTxRh7zinBANpZXAVDlsZxYdclDp467G1sQ8VZYMnAURY3RpBUAgOYT9GfzHBg== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/types" "^7.5.5" - lodash "^4.17.13" - -"@babel/helper-explode-assignable-expression@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.1.0.tgz#537fa13f6f1674df745b0c00ec8fe4e99681c8f6" - integrity sha512-NRQpfHrJ1msCHtKjbzs9YcMmJZOg6mQMmGRB+hbamEdG5PNpaSm95275VD92DvJKuyl0s2sFiDmMZ+EnnvufqA== - dependencies: - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-function-name@^7.1.0", "@babel/helper-function-name@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.8.3.tgz#eeeb665a01b1f11068e9fb86ad56a1cb1a824cca" - integrity sha512-BCxgX1BC2hD/oBlIFUgOCQDOPV8nSINxCwM3o93xP4P9Fq6aV5sgv2cOOITDMtCfQ+3PvHp3l689XZvAM9QyOA== - dependencies: - "@babel/helper-get-function-arity" "^7.8.3" - "@babel/template" "^7.8.3" - "@babel/types" "^7.8.3" - -"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.8.3.tgz#b894b947bd004381ce63ea1db9f08547e920abd5" - integrity sha512-FVDR+Gd9iLjUMY1fzE2SR0IuaJToR4RkCDARVfsBBPSP53GEqSFjD8gNyxg246VUyc/ALRxFaAK8rVG7UT7xRA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-hoist-variables@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.4.4.tgz#0298b5f25c8c09c53102d52ac4a98f773eb2850a" - integrity sha512-VYk2/H/BnYbZDDg39hr3t2kKyifAm1W6zHRfhx8jGjIHpQEBv9dry7oQ2f3+J703TLu69nYdxsovl0XYfcnK4w== - dependencies: - "@babel/types" "^7.4.4" - -"@babel/helper-member-expression-to-functions@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.5.5.tgz#1fb5b8ec4453a93c439ee9fe3aeea4a84b76b590" - integrity sha512-5qZ3D1uMclSNqYcXqiHoA0meVdv+xUEex9em2fqMnrk/scphGlGgg66zjMrPJESPwrFJ6sbfFQYUSa0Mz7FabA== - dependencies: - "@babel/types" "^7.5.5" - -"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.0.0.tgz#96081b7111e486da4d2cd971ad1a4fe216cc2e3d" - integrity sha512-aP/hlLq01DWNEiDg4Jn23i+CXxW/owM4WpDLFUbpjxe4NS3BhLVZQ5i7E0ZrxuQ/vwekIeciyamgB1UIYxxM6A== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.5.5.tgz#f84ff8a09038dcbca1fd4355661a500937165b4a" - integrity sha512-jBeCvETKuJqeiaCdyaheF40aXnnU1+wkSiUs/IQg3tB85up1LyL8x77ClY8qJpuRJUcXQo+ZtdNESmZl4j56Pw== - dependencies: - "@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.5.5" - lodash "^4.17.13" - -"@babel/helper-optimise-call-expression@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.0.0.tgz#a2920c5702b073c15de51106200aa8cad20497d5" - integrity sha512-u8nd9NQePYNQV8iPWu/pLLYBqZBa4ZaY1YWRFMuxrid94wKI1QNt67NEZ7GAe5Kc/0LLScbim05xZFWkAdrj9g== - dependencies: - "@babel/types" "^7.0.0" - -"@babel/helper-plugin-utils@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.0.0.tgz#bbb3fbee98661c569034237cc03967ba99b4f250" - integrity sha512-CYAOUCARwExnEixLdB6sDm2dIJ/YgEAKDM1MOeMeZu9Ld/bDgVo8aiWrXwcY7OBh+1Ea2uUcVRcxKk0GJvW7QA== - -"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.4.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.5.5.tgz#0aa6824f7100a2e0e89c1527c23936c152cab351" - integrity sha512-CkCYQLkfkiugbRDO8eZn6lRuR8kzZoGXCg3149iTk5se7g6qykSpy3+hELSwquhu+TgHn8nkLiBwHvNX8Hofcw== - dependencies: - lodash "^4.17.13" - -"@babel/helper-remap-async-to-generator@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.1.0.tgz#361d80821b6f38da75bd3f0785ece20a88c5fe7f" - integrity sha512-3fOK0L+Fdlg8S5al8u/hWE6vhufGSn0bN09xm2LXMy//REAF8kDCrYoOBKYmA8m5Nom+sV9LyLCwrFynA8/slg== - dependencies: - "@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@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.5.5.tgz#f84ce43df031222d2bad068d2626cb5799c34bc2" - integrity sha512-XvRFWrNnlsow2u7jXDuH4jDDctkxbS7gXssrP4q2nUD606ukXHRvydj346wmNg+zAgpFx4MWf4+usfC93bElJg== - dependencies: - "@babel/helper-member-expression-to-functions" "^7.5.5" - "@babel/helper-optimise-call-expression" "^7.0.0" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" - -"@babel/helper-simple-access@^7.1.0": - version "7.1.0" - resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.1.0.tgz#65eeb954c8c245beaa4e859da6188f39d71e585c" - integrity sha512-Vk+78hNjRbsiu49zAPALxTb+JUQCz1aolpd8osOF16BGnLtseD21nbHgLPGUwrXEurZgiCOUmvs3ExTu4F5x6w== - dependencies: - "@babel/template" "^7.1.0" - "@babel/types" "^7.0.0" - -"@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.8.3.tgz#31a9f30070f91368a7182cf05f831781065fc7a9" - integrity sha512-3x3yOeyBhW851hroze7ElzdkeRXQYQbFIb7gLK1WQYsw2GWDay5gAJNw1sWJ0VFP6z5J1whqeXH/WCdCjZv6dA== - dependencies: - "@babel/types" "^7.8.3" - -"@babel/helper-wrap-function@^7.1.0", "@babel/helper-wrap-function@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.2.0.tgz#c4e0012445769e2815b55296ead43a958549f6fa" - integrity sha512-o9fP1BZLLSrYlxYEYyl2aS+Flun5gtjTIG8iln+XuEzQTs0PLagAGSXUcqruJwD5fM48jzIEggCKpIfWTcR7pQ== +"@babel/helper-compilation-targets@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-compilation-targets/-/helper-compilation-targets-7.10.4.tgz#804ae8e3f04376607cc791b9d47d540276332bd2" + integrity sha512-a3rYhlsGV0UHNDvrtOXBg8/OpfV0OKTkxKPzIplS1zpx7CygDcWWxckxZeDd3gzPzC4kUT0A4nVFDK0wGMh4MQ== dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/template" "^7.1.0" - "@babel/traverse" "^7.1.0" - "@babel/types" "^7.2.0" - -"@babel/helpers@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.5.5.tgz#63908d2a73942229d1e6685bc2a0e730dde3b75e" - integrity sha512-nRq2BUhxZFnfEn/ciJuhklHvFOqjJUD5wpx+1bxUF2axL9C+v4DE/dmp5sT2dKnpOs4orZWzpAZqlCy8QqE/7g== - dependencies: - "@babel/template" "^7.4.4" - "@babel/traverse" "^7.5.5" - "@babel/types" "^7.5.5" + "@babel/compat-data" "^7.10.4" + browserslist "^4.12.0" + invariant "^2.2.4" + levenary "^1.1.1" + semver "^5.5.0" -"@babel/highlight@^7.8.3": - version "7.8.3" - resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.8.3.tgz#28f173d04223eaaa59bc1d439a3836e6d1265797" - integrity sha512-PX4y5xQUvy0fnEVHrYOarRPXVWafSjTW9T0Hab8gVIawpl2Sj0ORyrygANq+KjcNlSSTw0YCLSNA8OyZ1I4yEg== - dependencies: +"@babel/helper-create-class-features-plugin@^7.10.4", "@babel/helper-create-class-features-plugin@^7.10.5", "@babel/helper-create-class-features-plugin@^7.5.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-create-class-features-plugin/-/helper-create-class-features-plugin-7.10.5.tgz#9f61446ba80e8240b0a5c85c6fdac8459d6f259d" + integrity sha512-0nkdeijB7VlZoLT3r/mY3bUkw3T8WG/hNw+FATs/6+pG2039IJWjTYL0VTISqsNHMUTEnwbVnc89WIJX9Qed0A== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-member-expression-to-functions" "^7.10.5" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" + +"@babel/helper-create-regexp-features-plugin@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-create-regexp-features-plugin/-/helper-create-regexp-features-plugin-7.10.4.tgz#fdd60d88524659a0b6959c0579925e425714f3b8" + integrity sha512-2/hu58IEPKeoLF45DBwx3XFqsbCXmkdAay4spVr2x0jYgRxrSNp+ePwvSsy9g6YSaNDcKIQVPXk1Ov8S2edk2g== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + regexpu-core "^4.7.0" + +"@babel/helper-define-map@^7.10.4", "@babel/helper-define-map@^7.5.5": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-define-map/-/helper-define-map-7.10.5.tgz#b53c10db78a640800152692b13393147acb9bb30" + integrity sha512-fMw4kgFB720aQFXSVaXr79pjjcW5puTCM16+rECJ/plGS+zByelE8l9nCpV1GibxTnFVmUuYG9U8wYfQHdzOEQ== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/types" "^7.10.5" + lodash "^4.17.19" + +"@babel/helper-explode-assignable-expression@^7.1.0", "@babel/helper-explode-assignable-expression@^7.10.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.11.4.tgz#2d8e3470252cc17aba917ede7803d4a7a276a41b" + integrity sha512-ux9hm3zR4WV1Y3xXxXkdG/0gxF9nvI0YVmKVhvK9AfMoaQkemL3sJpXw+Xbz65azo8qJiEz2XVDUpK3KYhH3ZQ== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-function-name@^7.1.0", "@babel/helper-function-name@^7.10.4", "@babel/helper-function-name@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.10.4.tgz#d2d3b20c59ad8c47112fa7d2a94bc09d5ef82f1a" + integrity sha512-YdaSyz1n8gY44EmN7x44zBn9zQ1Ry2Y+3GTA+3vH6Mizke1Vw0aWDM66FOYEPw8//qKkmqOckrGgTYa+6sceqQ== + dependencies: + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-get-function-arity@^7.0.0", "@babel/helper-get-function-arity@^7.10.4", "@babel/helper-get-function-arity@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.10.4.tgz#98c1cbea0e2332f33f9a4661b8ce1505b2c19ba2" + integrity sha512-EkN3YDB+SRDgiIUnNgcmiD361ti+AVbL3f3Henf6dqqUyr5dMsorno0lJWJuLhDhkI5sYEpgj6y9kB8AOU1I2A== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-hoist-variables@^7.10.4", "@babel/helper-hoist-variables@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-hoist-variables/-/helper-hoist-variables-7.10.4.tgz#d49b001d1d5a68ca5e6604dda01a6297f7c9381e" + integrity sha512-wljroF5PgCk2juF69kanHVs6vrLwIPNp6DLD+Lrl3hoQ3PpPPikaDRNFA+0t81NOoMt2DL6WW/mdU8k4k6ZzuA== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-member-expression-to-functions@^7.10.4", "@babel/helper-member-expression-to-functions@^7.10.5", "@babel/helper-member-expression-to-functions@^7.5.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-member-expression-to-functions/-/helper-member-expression-to-functions-7.11.0.tgz#ae69c83d84ee82f4b42f96e2a09410935a8f26df" + integrity sha512-JbFlKHFntRV5qKw3YC0CvQnDZ4XMwgzzBbld7Ly4Mj4cbFy3KywcR8NtNctRToMWJOVvLINJv525Gd6wwVEx/Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-module-imports@^7.0.0", "@babel/helper-module-imports@^7.0.0-beta.49", "@babel/helper-module-imports@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-module-imports/-/helper-module-imports-7.10.4.tgz#4c5c54be04bd31670a7382797d75b9fa2e5b5620" + integrity sha512-nEQJHqYavI217oD9+s5MUBzk6x1IlvoS9WTPfgG43CbMEeStE0v+r+TucWdx8KFGowPGvyOkDT9+7DHedIDnVw== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-module-transforms@^7.1.0", "@babel/helper-module-transforms@^7.10.4", "@babel/helper-module-transforms@^7.10.5", "@babel/helper-module-transforms@^7.11.0", "@babel/helper-module-transforms@^7.4.4": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-module-transforms/-/helper-module-transforms-7.11.0.tgz#b16f250229e47211abdd84b34b64737c2ab2d359" + integrity sha512-02EVu8COMuTRO1TAzdMtpBPbe6aQ1w/8fePD2YgQmxZU4gpNWaL9gK3Jp7dxlkUlUCJOTaSeA+Hrm1BRQwqIhg== + dependencies: + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/template" "^7.10.4" + "@babel/types" "^7.11.0" + lodash "^4.17.19" + +"@babel/helper-optimise-call-expression@^7.0.0", "@babel/helper-optimise-call-expression@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-optimise-call-expression/-/helper-optimise-call-expression-7.10.4.tgz#50dc96413d594f995a77905905b05893cd779673" + integrity sha512-n3UGKY4VXwXThEiKrgRAoVPBMqeoPgHVqiHZOanAJCG9nQUL2pLRQirUzl0ioKclHGpGqRgIOkgcIJaIWLpygg== + dependencies: + "@babel/types" "^7.10.4" + +"@babel/helper-plugin-utils@^7.0.0", "@babel/helper-plugin-utils@^7.10.4", "@babel/helper-plugin-utils@^7.8.0", "@babel/helper-plugin-utils@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-plugin-utils/-/helper-plugin-utils-7.10.4.tgz#2f75a831269d4f677de49986dff59927533cf375" + integrity sha512-O4KCvQA6lLiMU9l2eawBPMf1xPP8xPfB3iEQw150hOVTqj/rfXz0ThTb4HEzqQfs2Bmo5Ay8BzxfzVtBrr9dVg== + +"@babel/helper-regex@^7.0.0", "@babel/helper-regex@^7.10.4", "@babel/helper-regex@^7.4.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/helper-regex/-/helper-regex-7.10.5.tgz#32dfbb79899073c415557053a19bd055aae50ae0" + integrity sha512-68kdUAzDrljqBrio7DYAEgCoJHxppJOERHOgOrDN7WjOzP0ZQ1LsSDRXcemzVZaLvjaJsJEESb6qt+znNuENDg== + dependencies: + lodash "^4.17.19" + +"@babel/helper-remap-async-to-generator@^7.1.0", "@babel/helper-remap-async-to-generator@^7.10.4": + version "7.11.4" + resolved "https://registry.yarnpkg.com/@babel/helper-remap-async-to-generator/-/helper-remap-async-to-generator-7.11.4.tgz#4474ea9f7438f18575e30b0cac784045b402a12d" + integrity sha512-tR5vJ/vBa9wFy3m5LLv2faapJLnDFxNWff2SAYkSE4rLUdbp7CdObYFgI7wK4T/Mj4UzpjPwzR8Pzmr5m7MHGA== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-replace-supers@^7.10.4", "@babel/helper-replace-supers@^7.5.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-replace-supers/-/helper-replace-supers-7.10.4.tgz#d585cd9388ea06e6031e4cd44b6713cbead9e6cf" + integrity sha512-sPxZfFXocEymYTdVK1UNmFPBN+Hv5mJkLPsYWwGBxZAxaWfFu+xqp7b6qWD0yjNuNL2VKc6L5M18tOXUP7NU0A== + dependencies: + "@babel/helper-member-expression-to-functions" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-simple-access@^7.1.0", "@babel/helper-simple-access@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-simple-access/-/helper-simple-access-7.10.4.tgz#0f5ccda2945277a2a7a2d3a821e15395edcf3461" + integrity sha512-0fMy72ej/VEvF8ULmX6yb5MtHG4uH4Dbd6I/aHDb/JVg0bbivwt9Wg+h3uMvX+QSFtwr5MeItvazbrc4jtRAXw== + dependencies: + "@babel/template" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helper-skip-transparent-expression-wrappers@^7.11.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-skip-transparent-expression-wrappers/-/helper-skip-transparent-expression-wrappers-7.11.0.tgz#eec162f112c2f58d3af0af125e3bb57665146729" + integrity sha512-0XIdiQln4Elglgjbwo9wuJpL/K7AGCY26kmEt0+pRP0TAj4jjyNq1MjoRvikrTVqKcx4Gysxt4cXvVFXP/JO2Q== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-split-export-declaration@^7.10.4", "@babel/helper-split-export-declaration@^7.11.0", "@babel/helper-split-export-declaration@^7.4.4", "@babel/helper-split-export-declaration@^7.8.3": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.11.0.tgz#f8a491244acf6a676158ac42072911ba83ad099f" + integrity sha512-74Vejvp6mHkGE+m+k5vHY93FX2cAtrw1zXrZXRlG4l410Nm9PxfEiVTn1PjDPV5SnmieiueY4AFg2xqhNFuuZg== + dependencies: + "@babel/types" "^7.11.0" + +"@babel/helper-validator-identifier@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-validator-identifier/-/helper-validator-identifier-7.10.4.tgz#a78c7a7251e01f616512d31b10adcf52ada5e0d2" + integrity sha512-3U9y+43hz7ZM+rzG24Qe2mufW5KhvFg/NhnNph+i9mgCtdTCtMJuI1TMkrIUiK7Ix4PYlRF9I5dhqaLYA/ADXw== + +"@babel/helper-wrap-function@^7.1.0", "@babel/helper-wrap-function@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helper-wrap-function/-/helper-wrap-function-7.10.4.tgz#8a6f701eab0ff39f765b5a1cfef409990e624b87" + integrity sha512-6py45WvEF0MhiLrdxtRjKjufwLL1/ob2qDJgg5JgNdojBAZSAKnAjkyOCNug6n+OBl4VW76XjvgSFTdaMcW0Ug== + dependencies: + "@babel/helper-function-name" "^7.10.4" + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/helpers@^7.10.4", "@babel/helpers@^7.5.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.10.4.tgz#2abeb0d721aff7c0a97376b9e1f6f65d7a475044" + integrity sha512-L2gX/XeUONeEbI78dXSrJzGdz4GQ+ZTA/aazfUsFaWjSe95kiCuOZ5HsXvkiw3iwF+mFHSRUfJU8t6YavocdXA== + dependencies: + "@babel/template" "^7.10.4" + "@babel/traverse" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/highlight@^7.10.4", "@babel/highlight@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/highlight/-/highlight-7.10.4.tgz#7d1bdfd65753538fabe6c38596cdb76d9ac60143" + integrity sha512-i6rgnR/YgPEQzZZnbTHHuZdlE8qyoBNalD6F+q4vAFlcMEcqmkoG+mPqJYJCo63qPf74+Y1UZsl3l6f7/RIkmA== + dependencies: + "@babel/helper-validator-identifier" "^7.10.4" chalk "^2.0.0" - esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@7.1.3": - version "7.1.3" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.1.3.tgz#2c92469bac2b7fbff810b67fca07bd138b48af77" - integrity sha512-gqmspPZOMW3MIRb9HlrnbZHXI1/KHTOroBwN1NcLL6pWxzqzEKGvRTq0W/PxS45OtQGbaFikSQpkS5zbnsQm2w== - -"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.5.5", "@babel/parser@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.8.6.tgz#ba5c9910cddb77685a008e3c587af8d27b67962c" - integrity sha512-trGNYSfwq5s0SgM1BMEB8hX3NDmO7EP2wsDGDexiaKMB92BaRpS+qZfpkMqUBhcsOTBwNy9B/jieo4ad/t/z2g== - -"@babel/plugin-proposal-async-generator-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.2.0.tgz#b289b306669dce4ad20b0252889a15768c9d417e" - integrity sha512-+Dfo/SCQqrwx48ptLVGLdE39YtWRuKc/Y9I5Fy0P1DDBB9lsAHpjcEJQt+4IifuSOSTLBKJObJqMvaO1pIE8LQ== - dependencies: - "@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@^7.1.0", "@babel/plugin-proposal-class-properties@^7.3.4": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.5.5.tgz#a974cfae1e37c3110e71f3c6a2e48b8e71958cd4" - integrity sha512-AF79FsnWFxjlaosgdi421vmYG6/jg79bVD0dpD44QdgobzHKuLZ6S3vl8la9qIeSwGi8i1fS0O1mfuDAAdo1/A== - dependencies: - "@babel/helper-create-class-features-plugin" "^7.5.5" - "@babel/helper-plugin-utils" "^7.0.0" +"@babel/parser@7.10.2": + version "7.10.2" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.10.2.tgz#871807f10442b92ff97e4783b9b54f6a0ca812d0" + integrity sha512-PApSXlNMJyB4JiGVhCOlzKIif+TKFTvu0aQAhnTvfP/z3vVSN6ZypH5bfUNwFXXjRQtUEBNFd2PtmCmG2Py3qQ== + +"@babel/parser@^7.0.0", "@babel/parser@^7.1.0", "@babel/parser@^7.10.4", "@babel/parser@^7.11.5", "@babel/parser@^7.4.3", "@babel/parser@^7.5.5", "@babel/parser@^7.8.6": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.11.5.tgz#c7ff6303df71080ec7a4f5b8c003c58f1cf51037" + integrity sha512-X9rD8qqm695vgmeaQ4fvz/o3+Wk4ZzQvSHkDBgpYKxpD4qTAUm88ZKtHkVqIOsYFFbIQ6wQYhC6q7pjqVK0E0Q== -"@babel/plugin-proposal-decorators@^7.1.2": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.4.4.tgz#de9b2a1a8ab0196f378e2a82f10b6e2a36f21cc0" - integrity sha512-z7MpQz3XC/iQJWXH9y+MaWcLPNSMY9RQSthrLzak8R8hCj0fuyNk+Dzi9kfNe/JxxlWQ2g7wkABbgWjW36MTcw== +"@babel/plugin-proposal-async-generator-functions@^7.10.4", "@babel/plugin-proposal-async-generator-functions@^7.2.0": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-async-generator-functions/-/plugin-proposal-async-generator-functions-7.10.5.tgz#3491cabf2f7c179ab820606cec27fed15e0e8558" + integrity sha512-cNMCVezQbrRGvXJwm9fu/1sJj9bHdGAgKodZdLqOQIpfoH3raqmRPBM17+lh7CzhiKRRBrGtZL9WcjxSoGYUSg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + +"@babel/plugin-proposal-class-properties@^7.10.4", "@babel/plugin-proposal-class-properties@^7.3.4", "@babel/plugin-proposal-class-properties@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-class-properties/-/plugin-proposal-class-properties-7.10.4.tgz#a33bf632da390a59c7a8c570045d1115cd778807" + integrity sha512-vhwkEROxzcHGNu2mzUC0OFFNXdZ4M23ib8aRRcJSsW8BZK9pQMD7QB7csl97NBbgGZO7ZyHUyKDnxzOaP4IrCg== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-proposal-decorators@^7.8.3": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-decorators/-/plugin-proposal-decorators-7.10.5.tgz#42898bba478bc4b1ae242a703a953a7ad350ffb4" + integrity sha512-Sc5TAQSZuLzgY0664mMDn24Vw2P8g/VhyLyGPaWiHahhgLqeZvcGeyBZOrJW0oSKIK2mvQ22a1ENXBIQLhrEiQ== + dependencies: + "@babel/helper-create-class-features-plugin" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-decorators" "^7.10.4" + +"@babel/plugin-proposal-do-expressions@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-do-expressions/-/plugin-proposal-do-expressions-7.10.4.tgz#9a5190f3bf4818f83e41d673ee517ff76cf8e4ed" + integrity sha512-Gcc2wLVeMceRdP6m9tdDygP01lbUVmaQGBRoIRJZxzPfB5VTiUgmn1jGfORgqbEVgUpG0IQm/z4q5Y/qzG+8JQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-do-expressions" "^7.10.4" + +"@babel/plugin-proposal-dynamic-import@^7.10.4", "@babel/plugin-proposal-dynamic-import@^7.5.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.10.4.tgz#ba57a26cb98b37741e9d5bca1b8b0ddf8291f17e" + integrity sha512-up6oID1LeidOOASNXgv/CFbgBqTuKJ0cJjz6An5tWD+NVBNlp3VNSBxv2ZdU7SYl3NxJC7agAQDApZusV6uFwQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + +"@babel/plugin-proposal-export-default-from@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.10.4.tgz#08f66eef0067cbf6a7bc036977dcdccecaf0c6c5" + integrity sha512-G1l00VvDZ7Yk2yRlC5D8Ybvu3gmeHS3rCHoUYdjrqGYUtdeOBoRypnvDZ5KQqxyaiiGHWnVDeSEzA5F9ozItig== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-default-from" "^7.10.4" + +"@babel/plugin-proposal-export-namespace-from@^7.10.4", "@babel/plugin-proposal-export-namespace-from@^7.2.0", "@babel/plugin-proposal-export-namespace-from@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.10.4.tgz#570d883b91031637b3e2958eea3c438e62c05f54" + integrity sha512-aNdf0LY6/3WXkhh0Fdb6Zk9j1NMD8ovj3F6r0+3j837Pn1S1PdNtcwJ5EG9WkVPNHPxyJDaxMaAOVq4eki0qbg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + +"@babel/plugin-proposal-function-bind@^7.8.3": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.11.5.tgz#6ce571686dd1bc2f5c1ae7bdebad8aaa7fda3893" + integrity sha512-gkCyUqJp6jRPdHFAYZxGal6d6Poj17G+6FGbyUcHKew2sccp5HVilTgnreYqTzDsY10Ys0ZVB/U2knTnnJdkUQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-function-bind" "^7.10.4" + +"@babel/plugin-proposal-function-sent@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.10.4.tgz#05f2daef7b3f09b6c74c9e8a85b430272d206ac4" + integrity sha512-aBtve/DhQsVPAGnSDcgt33gF36rO0TK+KtHp9Hwtj3KwH+o1Cii9vfVVYeB9c6Jo1SXOgTRwRD7ljpTS0qbN8w== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-wrap-function" "^7.10.4" + "@babel/plugin-syntax-function-sent" "^7.10.4" + +"@babel/plugin-proposal-json-strings@^7.10.4", "@babel/plugin-proposal-json-strings@^7.2.0", "@babel/plugin-proposal-json-strings@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.10.4.tgz#593e59c63528160233bd321b1aebe0820c2341db" + integrity sha512-fCL7QF0Jo83uy1K0P2YXrfX11tj3lkpN7l4dMv9Y9VkowkhkQDwFHFd8IiwyK5MZjE8UpbgokkgtcReH88Abaw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-json-strings" "^7.8.0" + +"@babel/plugin-proposal-logical-assignment-operators@^7.11.0", "@babel/plugin-proposal-logical-assignment-operators@^7.8.3": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.11.0.tgz#9f80e482c03083c87125dee10026b58527ea20c8" + integrity sha512-/f8p4z+Auz0Uaf+i8Ekf1iM7wUNLcViFUGiPxKeXvxTSl63B875YPiVdUDdem7hREcI0E0kSpEhS8tF5RphK7Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + +"@babel/plugin-proposal-nullish-coalescing-operator@^7.10.4", "@babel/plugin-proposal-nullish-coalescing-operator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.10.4.tgz#02a7e961fc32e6d5b2db0649e01bf80ddee7e04a" + integrity sha512-wq5n1M3ZUlHl9sqT2ok1T2/MTt6AXE0e1Lz4WzWBr95LsAZ5qDXe4KnFuauYyEyLiohvXFMdbsOTMyLZs91Zlw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + +"@babel/plugin-proposal-numeric-separator@^7.10.4", "@babel/plugin-proposal-numeric-separator@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.10.4.tgz#ce1590ff0a65ad12970a609d78855e9a4c1aef06" + integrity sha512-73/G7QoRoeNkLZFxsoCCvlg4ezE4eM+57PnOqgaPOozd5myfj7p0muD1mRVJvbUWbOzD+q3No2bWbaKy+DJ8DA== dependencies: - "@babel/helper-create-class-features-plugin" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-decorators" "^7.2.0" - -"@babel/plugin-proposal-do-expressions@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-do-expressions/-/plugin-proposal-do-expressions-7.5.0.tgz#ceb594d4a618545b00aa0b5cd61cad4aaaeb7a5a" - integrity sha512-xe0QQrhm+DGj6H23a6XtwkJNimy1fo71O/YVBfrfvfSl0fsq9T9dfoQBIY4QceEIdUo7u9s7OPEdsWEuizfGeg== + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + +"@babel/plugin-proposal-object-rest-spread@^7.11.0", "@babel/plugin-proposal-object-rest-spread@^7.5.5": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.11.0.tgz#bd81f95a1f746760ea43b6c2d3d62b11790ad0af" + integrity sha512-wzch41N4yztwoRw0ak+37wxwJM2oiIiy6huGCoqkvSTA9acYWcPfn9Y4aJqmFFJ70KTJUu29f3DQ43uJ9HXzEA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-do-expressions" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-transform-parameters" "^7.10.4" -"@babel/plugin-proposal-dynamic-import@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-dynamic-import/-/plugin-proposal-dynamic-import-7.5.0.tgz#e532202db4838723691b10a67b8ce509e397c506" - integrity sha512-x/iMjggsKTFHYC6g11PL7Qy58IK8H5zqfm9e6hu4z1iH2IRyAp9u9dL80zA6R76yFovETFLKz2VJIC2iIPBuFw== +"@babel/plugin-proposal-optional-catch-binding@^7.10.4", "@babel/plugin-proposal-optional-catch-binding@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.10.4.tgz#31c938309d24a78a49d68fdabffaa863758554dd" + integrity sha512-LflT6nPh+GK2MnFiKDyLiqSqVHkQnVf7hdoAvyTnnKj9xB3docGRsdPuxp6qqqW19ifK3xgc9U5/FwrSaCNX5g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" -"@babel/plugin-proposal-export-default-from@^7.0.0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-default-from/-/plugin-proposal-export-default-from-7.5.2.tgz#2c0ac2dcc36e3b2443fead2c3c5fc796fb1b5145" - integrity sha512-wr9Itk05L1/wyyZKVEmXWCdcsp/e185WUNl6AfYZeEKYaUPPvHXRDqO5K1VH7/UamYqGJowFRuCv30aDYZawsg== +"@babel/plugin-proposal-optional-chaining@^7.11.0", "@babel/plugin-proposal-optional-chaining@^7.9.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.11.0.tgz#de5866d0646f6afdaab8a566382fe3a221755076" + integrity sha512-v9fZIu3Y8562RRwhm1BbMRxtqZNFmFA2EG+pT2diuU8PT3H6T/KXoZ54KgYisfOFZHV6PfvAiBIZ9Rcz+/JCxA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-export-default-from" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" -"@babel/plugin-proposal-export-namespace-from@^7.0.0", "@babel/plugin-proposal-export-namespace-from@^7.2.0": - version "7.5.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-export-namespace-from/-/plugin-proposal-export-namespace-from-7.5.2.tgz#ccd5ed05b06d700688ff1db01a9dd27155e0d2a0" - integrity sha512-TKUdOL07anjZEbR1iSxb5WFh810KyObdd29XLFLGo1IDsSuGrjH3ouWSbAxHNmrVKzr9X71UYl2dQ7oGGcRp0g== +"@babel/plugin-proposal-pipeline-operator@^7.8.3": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.10.5.tgz#0fa2871dbfb74efe19eeb17722032056cb5697f3" + integrity sha512-tCpZ46KUAHgFoXsH593k9sX/ZKsNb4NlTGNif8PdlmkGbtYdbTQi6zNv8yibpRf+3sQFElOBLyNo3I5ZwVu90g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-export-namespace-from" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-pipeline-operator" "^7.10.4" -"@babel/plugin-proposal-function-bind@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-bind/-/plugin-proposal-function-bind-7.2.0.tgz#94dc2cdc505cafc4e225c0014335a01648056bf7" - integrity sha512-qOFJ/eX1Is78sywwTxDcsntLOdb5ZlHVVqUz5xznq8ldAfOVIyZzp1JE2rzHnaksZIhrqMrwIpQL/qcEprnVbw== +"@babel/plugin-proposal-private-methods@^7.10.4", "@babel/plugin-proposal-private-methods@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-private-methods/-/plugin-proposal-private-methods-7.10.4.tgz#b160d972b8fdba5c7d111a145fc8c421fc2a6909" + integrity sha512-wh5GJleuI8k3emgTg5KkJK6kHNsGEr0uBTDBuQUBJwckk9xs1ez79ioheEVVxMLyPscB0LfkbVHslQqIzWV6Bw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-function-bind" "^7.2.0" + "@babel/helper-create-class-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-function-sent@^7.1.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-function-sent/-/plugin-proposal-function-sent-7.5.0.tgz#39233aa801145e7d8072077cdb2d25f781c1ffd7" - integrity sha512-JXdfiQpKoC6UgQliZkp3NX7K3MVec1o1nfTWiCCIORE5ag/QZXhL0aSD8/Y2K+hIHonSTxuJF9rh9zsB6hBi2A== +"@babel/plugin-proposal-throw-expressions@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.10.4.tgz#501154a3c1b33cb1ad5b899204481fa2859cd3f3" + integrity sha512-m7K9duXeH/rko36i9G9seLOg2AVdeVTn65k8nnTxgozex0hkDSUr6cktJxTO7jElGEpmMz410pTs0Jn8+empxw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-wrap-function" "^7.2.0" - "@babel/plugin-syntax-function-sent" "^7.2.0" - -"@babel/plugin-proposal-json-strings@^7.0.0", "@babel/plugin-proposal-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-json-strings/-/plugin-proposal-json-strings-7.2.0.tgz#568ecc446c6148ae6b267f02551130891e29f317" - integrity sha512-MAFV1CA/YVmYwZG0fBQyXhmj0BHCB5egZHCKWIFVv/XCxAeVGIHfos3SwDck4LvCllENIAg7xMKOG5kH0dzyUg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-json-strings" "^7.2.0" - -"@babel/plugin-proposal-logical-assignment-operators@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-logical-assignment-operators/-/plugin-proposal-logical-assignment-operators-7.2.0.tgz#8a5cea6c42a7c87446959e02fff5fad012c56f57" - integrity sha512-0w797xwdPXKk0m3Js74hDi0mCTZplIu93MOSfb1ZLd/XFe3abWypx1QknVk0J+ohnsjYpvjH4Gwfo2i3RicB6Q== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-logical-assignment-operators" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-throw-expressions" "^7.10.4" -"@babel/plugin-proposal-nullish-coalescing-operator@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-nullish-coalescing-operator/-/plugin-proposal-nullish-coalescing-operator-7.4.4.tgz#41c360d59481d88e0ce3a3f837df10121a769b39" - integrity sha512-Amph7Epui1Dh/xxUxS2+K22/MUi6+6JVTvy3P58tja3B6yKTSjwwx0/d83rF7551D6PVSSoplQb8GCwqec7HRw== +"@babel/plugin-proposal-unicode-property-regex@^7.10.4", "@babel/plugin-proposal-unicode-property-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.10.4.tgz#4483cda53041ce3413b7fe2f00022665ddfaa75d" + integrity sha512-H+3fOgPnEXFL9zGYtKQe4IDOPKYlZdF1kqFDQRRb8PK4B8af1vAGK04tF5iQAAsui+mHNBQSAtd2/ndEDe9wuA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-nullish-coalescing-operator" "^7.2.0" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-numeric-separator@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-numeric-separator/-/plugin-proposal-numeric-separator-7.2.0.tgz#646854daf4cd22fd6733f6076013a936310443ac" - integrity sha512-DohMOGDrZiMKS7LthjUZNNcWl8TAf5BZDwZAH4wpm55FuJTHgfqPGdibg7rZDmont/8Yg0zA03IgT6XLeP+4sg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-numeric-separator" "^7.2.0" - -"@babel/plugin-proposal-object-rest-spread@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-object-rest-spread/-/plugin-proposal-object-rest-spread-7.5.5.tgz#61939744f71ba76a3ae46b5eea18a54c16d22e58" - integrity sha512-F2DxJJSQ7f64FyTVl5cw/9MWn6naXGdk3Q3UhDbFEEHv+EilCPoeRD3Zh/Utx1CJz4uyKlQ4uH+bJPbEhMV7Zw== +"@babel/plugin-syntax-async-generators@^7.2.0", "@babel/plugin-syntax-async-generators@^7.8.0": + version "7.8.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.8.4.tgz#a983fb1aeb2ec3f6ed042a210f640e90e786fe0d" + integrity sha512-tycmZxkGfZaxhMRbXlPXuVFpdWlXpir2W4AMhSJgRKzk/eDlIXOhb2LHWoLpDF7TEHylV5zNhykX6KAgHJmTNw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-object-rest-spread" "^7.2.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-proposal-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-catch-binding/-/plugin-proposal-optional-catch-binding-7.2.0.tgz#135d81edb68a081e55e56ec48541ece8065c38f5" - integrity sha512-mgYj3jCcxug6KUcX4OBoOJz3CMrwRfQELPQ5560F70YQUBZB7uac9fqaWamKR1iWUzGiK2t0ygzjTScZnVz75g== +"@babel/plugin-syntax-class-properties@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-class-properties/-/plugin-syntax-class-properties-7.10.4.tgz#6644e6a0baa55a61f9e3231f6c9eeb6ee46c124c" + integrity sha512-GCSBF7iUle6rNugfURwNmCGG3Z/2+opxAMLs1nND4bhEG5PuxTIggDBoeYYSujAlLtsupzOHYJQgPS3pivwXIA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-catch-binding" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-optional-chaining@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-optional-chaining/-/plugin-proposal-optional-chaining-7.2.0.tgz#ae454f4c21c6c2ce8cb2397dc332ae8b420c5441" - integrity sha512-ea3Q6edZC/55wEBVZAEz42v528VulyO0eir+7uky/sT4XRcdkWJcFi1aPtitTlwUzGnECWJNExWww1SStt+yWw== +"@babel/plugin-syntax-decorators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.10.4.tgz#6853085b2c429f9d322d02f5a635018cdeb2360c" + integrity sha512-2NaoC6fAk2VMdhY1eerkfHV+lVYC1u8b+jmRJISqANCJlTxYy19HGdIkkQtix2UtkcPuPu+IlDgrVseZnU03bw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-optional-chaining" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-pipeline-operator@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-pipeline-operator/-/plugin-proposal-pipeline-operator-7.5.0.tgz#4100ec55ef4f6a4c2490b5f5a4f2a22dfa272c06" - integrity sha512-HFYuu/yGnkn69ligXxU0ohOVvQDsMNOUJs/c4PYLUVS6ntCYOyGmRQQaSYJARJ9rvc7/ulZKIzxd4wk91hN63A== +"@babel/plugin-syntax-do-expressions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-do-expressions/-/plugin-syntax-do-expressions-7.10.4.tgz#0c7ebb749500c6bfa99a9f926db3bfd6cdbaded9" + integrity sha512-HyvaTg1aiwGo2I+Pu0nyurRMjIP7J89GpuZ2mcQ0fhO6Jt3BnyhEPbNJFG1hRE99NAPNfPYh93/7HO+GPVkTKg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-pipeline-operator" "^7.5.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-proposal-throw-expressions@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-throw-expressions/-/plugin-proposal-throw-expressions-7.2.0.tgz#2d9e452d370f139000e51db65d0a85dc60c64739" - integrity sha512-adsydM8DQF4i5DLNO4ySAU5VtHTPewOtNBV3u7F4lNMPADFF9bWQ+iDtUUe8+033cYCUz+bFlQdXQJmJOwoLpw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-throw-expressions" "^7.2.0" - -"@babel/plugin-proposal-unicode-property-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-proposal-unicode-property-regex/-/plugin-proposal-unicode-property-regex-7.4.4.tgz#501ffd9826c0b91da22690720722ac7cb1ca9c78" - integrity sha512-j1NwnOqMG9mFUOH58JTFsA/+ZYzQLUZ/drqWUqxCYLGeu2JFZL8YrNC9hBxKmWtAuOCHPcRpgv7fhap09Fb4kA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" - -"@babel/plugin-syntax-async-generators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-async-generators/-/plugin-syntax-async-generators-7.2.0.tgz#69e1f0db34c6f5a0cf7e2b3323bf159a76c8cb7f" - integrity sha512-1ZrIRBv2t0GSlcwVoQ6VgSLpLgiN/FVQUzt9znxo7v2Ov4jJrs8RY8tv0wvDmFN3qIdMKWrmMMW6yZ0G19MfGg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-decorators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-decorators/-/plugin-syntax-decorators-7.2.0.tgz#c50b1b957dcc69e4b1127b65e1c33eef61570c1b" - integrity sha512-38QdqVoXdHUQfTpZo3rQwqQdWtCn5tMv4uV6r2RMfTqNBuv4ZBhz79SfaQWKTVmxHjeFv/DnXVC/+agHCklYWA== +"@babel/plugin-syntax-dynamic-import@^7.2.0", "@babel/plugin-syntax-dynamic-import@^7.8.0", "@babel/plugin-syntax-dynamic-import@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.8.3.tgz#62bf98b2da3cd21d626154fc96ee5b3cb68eacb3" + integrity sha512-5gdGbFon+PszYzqs83S3E5mpi7/y/8M9eC90MRTZfduQOYW76ig6SOSPNe41IG5LoP3FGBn2N0RjVDSQiS94kQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-do-expressions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-do-expressions/-/plugin-syntax-do-expressions-7.2.0.tgz#f3d4b01be05ecde2892086d7cfd5f1fa1ead5a2a" - integrity sha512-/u4rJ+XEmZkIhspVuKRS+7WLvm7Dky9j9TvGK5IgId8B3FKir9MG+nQxDZ9xLn10QMBvW58dZ6ABe2juSmARjg== +"@babel/plugin-syntax-export-default-from@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.10.4.tgz#e5494f95006355c10292a0ff1ce42a5746002ec8" + integrity sha512-79V6r6Pgudz0RnuMGp5xidu6Z+bPFugh8/Q9eDHonmLp4wKFAZDwygJwYgCzuDu8lFA/sYyT+mc5y2wkd7bTXA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-dynamic-import@^7.0.0", "@babel/plugin-syntax-dynamic-import@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-dynamic-import/-/plugin-syntax-dynamic-import-7.2.0.tgz#69c159ffaf4998122161ad8ebc5e6d1f55df8612" - integrity sha512-mVxuJ0YroI/h/tbFTPGZR8cv6ai+STMKNBq0f8hFxsxWjl94qqhsb+wXbpNMDPU3cfR1TIsVFzU3nXyZMqyK4w== +"@babel/plugin-syntax-export-namespace-from@^7.2.0", "@babel/plugin-syntax-export-namespace-from@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.8.3.tgz#028964a9ba80dbc094c915c487ad7c4e7a66465a" + integrity sha512-MXf5laXo6c1IbEbegDmzGPwGNTsHZmEy6QGznu5Sh2UCWvueywb2ee+CCE4zQiZstxU9BMoQO9i6zUFSY0Kj0Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.3" -"@babel/plugin-syntax-export-default-from@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-default-from/-/plugin-syntax-export-default-from-7.2.0.tgz#edd83b7adc2e0d059e2467ca96c650ab6d2f3820" - integrity sha512-c7nqUnNST97BWPtoe+Ssi+fJukc9P9/JMZ71IOMNQWza2E+Psrd46N6AEvtw6pqK+gt7ChjXyrw4SPDO79f3Lw== +"@babel/plugin-syntax-flow@^7.10.4", "@babel/plugin-syntax-flow@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.10.4.tgz#53351dd7ae01995e567d04ce42af1a6e0ba846a6" + integrity sha512-yxQsX1dJixF4qEEdzVbst3SZQ58Nrooz8NV9Z9GL4byTE25BvJgl5lf0RECUf0fh28rZBb/RYTWn/eeKwCMrZQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-export-namespace-from@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-export-namespace-from/-/plugin-syntax-export-namespace-from-7.2.0.tgz#8d257838c6b3b779db52c0224443459bd27fb039" - integrity sha512-1zGA3UNch6A+A11nIzBVEaE3DDJbjfB+eLIcf0GGOh/BJr/8NxL3546MGhV/r0RhH4xADFIEso39TKCfEMlsGA== +"@babel/plugin-syntax-function-bind@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.10.4.tgz#8378d94f3185ddd3008310c15fe0991cb0c85151" + integrity sha512-vF/K9yS0dpPNlT7mXSGhbdpb2f4DaLa/AYYbUqlxOggAug/oseIR1+LgAzwci4iJNlqWNmJ7aQ+llUMYjn9uhw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-flow@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-flow/-/plugin-syntax-flow-7.2.0.tgz#a765f061f803bc48f240c26f8747faf97c26bf7c" - integrity sha512-r6YMuZDWLtLlu0kqIim5o/3TNRAlWb073HwT3e2nKf9I8IIvOggPrnILYPsrrKilmn/mYEMCf/Z07w3yQJF6dg== +"@babel/plugin-syntax-function-sent@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.10.4.tgz#b551f38b629e2e20908e53624f96f9ab300f5061" + integrity sha512-dwElaRoDQhlVevbgKOlEUTe08QNJo4ZjWw3rqnMbEvH8NRJM+iPN2tTQtzyfNloXD8f3Jdiyf5Pn400B1U3SVA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-function-bind@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-function-bind/-/plugin-syntax-function-bind-7.2.0.tgz#68fe85b0c0da67125f87bf239c68051b06c66309" - integrity sha512-/WzU1lLU2l0wDfB42Wkg6tahrmtBbiD8C4H6EGSX0M4GAjzN6JiOpq/Uh8G6GSoR6lPMvhjM0MNiV6znj6y/zg== +"@babel/plugin-syntax-import-meta@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.10.4.tgz#ee601348c370fa334d2207be158777496521fd51" + integrity sha512-Yqfm+XDx0+Prh3VSeEQCPU81yC+JWZ2pDPFSS4ZdpfZhp4MkFMaDC1UqseovEKwSUpnIL7+vK+Clp7bfh0iD7g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-function-sent@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-function-sent/-/plugin-syntax-function-sent-7.2.0.tgz#91474d4d400604e4c6cbd4d77cd6cb3b8565576c" - integrity sha512-2MOVuJ6IMAifp2cf0RFkHQaOvHpbBYyWCvgtF/WVqXhTd7Bgtov8iXVCadLXp2FN1BrI2EFl+JXuwXy0qr3KoQ== +"@babel/plugin-syntax-json-strings@^7.2.0", "@babel/plugin-syntax-json-strings@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.8.3.tgz#01ca21b668cd8218c9e640cb6dd88c5412b2c96a" + integrity sha512-lY6kdGpWHvjoe2vk4WrAapEuBR69EMxZl+RoGRhrFGNYVK8mOPAW8VfbT/ZgrFbXlDNiiaxQnAtgVCZ6jv30EA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-import-meta@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-import-meta/-/plugin-syntax-import-meta-7.2.0.tgz#2333ef4b875553a3bcd1e93f8ebc09f5b9213a40" - integrity sha512-Hq6kFSZD7+PHkmBN8bCpHR6J8QEoCuEV/B38AIQscYjgMZkGlXB7cHNFzP5jR4RCh5545yP1ujHdmO7hAgKtBA== +"@babel/plugin-syntax-jsx@^7.10.4", "@babel/plugin-syntax-jsx@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.10.4.tgz#39abaae3cbf710c4373d8429484e6ba21340166c" + integrity sha512-KCg9mio9jwiARCB7WAcQ7Y1q+qicILjoK8LP/VkPkEKaf5dkaZZK1EcTe91a3JJlZ3qy6L5s9X52boEYi8DM9g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-json-strings@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-json-strings/-/plugin-syntax-json-strings-7.2.0.tgz#72bd13f6ffe1d25938129d2a186b11fd62951470" - integrity sha512-5UGYnMSLRE1dqqZwug+1LISpA403HzlSfsg6P9VXU6TBjcSHeNlw4DxDx7LgpF+iKZoOG/+uzqoRHTdcUpiZNg== +"@babel/plugin-syntax-logical-assignment-operators@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.10.4.tgz#ca91ef46303530448b906652bac2e9fe9941f699" + integrity sha512-d8waShlpFDinQ5MtvGU9xDAOzKH47+FFoney2baFIoMr952hKOLp1HR7VszoZvOsV/4+RRszNY7D17ba0te0ig== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-jsx@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-jsx/-/plugin-syntax-jsx-7.2.0.tgz#0b85a3b4bc7cdf4cc4b8bf236335b907ca22e7c7" - integrity sha512-VyN4QANJkRW6lDBmENzRszvZf3/4AXaj9YR7GwrWeeN9tEBPuXbmDYVU9bYBN0D70zCWVwUy0HWq2553VCb6Hw== +"@babel/plugin-syntax-nullish-coalescing-operator@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.8.3.tgz#167ed70368886081f74b5c36c65a88c03b66d1a9" + integrity sha512-aSff4zPII1u2QD7y+F8oDsz19ew4IGEJg9SVW+bqwpwtfFleiQDMdzA/R+UlWDzfnHFCxxleFT0PMIrR36XLNQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-logical-assignment-operators@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-logical-assignment-operators/-/plugin-syntax-logical-assignment-operators-7.2.0.tgz#fcab7388530e96c6f277ce494c55caa6c141fcfb" - integrity sha512-l/NKSlrnvd73/EL540t9hZhcSo4TULBrIPs9Palju8Oc/A8DXDO+xQf04whfeuZLpi8AuIvCAdpKmmubLN4EfQ== +"@babel/plugin-syntax-numeric-separator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.10.4.tgz#b9b070b3e33570cd9fd07ba7fa91c0dd37b9af97" + integrity sha512-9H6YdfkcK/uOnY/K7/aA2xpzaAgkQn37yzWUMRK7OaPOqOpGS1+n0H5hxT9AUw9EsSjPW8SVyMJwYRtWs3X3ug== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-nullish-coalescing-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-nullish-coalescing-operator/-/plugin-syntax-nullish-coalescing-operator-7.2.0.tgz#f75083dfd5ade73e783db729bbd87e7b9efb7624" - integrity sha512-lRCEaKE+LTxDQtgbYajI04ddt6WW0WJq57xqkAZ+s11h4YgfRHhVA/Y2VhfPzzFD4qeLHWg32DMp9HooY4Kqlg== +"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0", "@babel/plugin-syntax-object-rest-spread@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.8.3.tgz#60e225edcbd98a640332a2e72dd3e66f1af55871" + integrity sha512-XoqMijGZb9y3y2XskN+P1wUGiVwWZ5JmoDRwx5+3GmEplNyVM2s2Dg8ILFQm8rWM48orGy5YpI5Bl8U1y7ydlA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-numeric-separator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-numeric-separator/-/plugin-syntax-numeric-separator-7.2.0.tgz#7470fe070c2944469a756752a69a6963135018be" - integrity sha512-DroeVNkO/BnGpL2R7+ZNZqW+E24aR/4YWxP3Qb15d6lPU8KDzF8HlIUIRCOJRn4X77/oyW4mJY+7FHfY82NLtQ== +"@babel/plugin-syntax-optional-catch-binding@^7.2.0", "@babel/plugin-syntax-optional-catch-binding@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.8.3.tgz#6111a265bcfb020eb9efd0fdfd7d26402b9ed6c1" + integrity sha512-6VPD0Pc1lpTqw0aKoeRTMiB+kWhAoT24PA+ksWSBrFtl5SIRVpZlwN3NNPQjehA2E/91FV3RjLWoVTglWcSV3Q== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-object-rest-spread@^7.0.0", "@babel/plugin-syntax-object-rest-spread@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-object-rest-spread/-/plugin-syntax-object-rest-spread-7.2.0.tgz#3b7a3e733510c57e820b9142a6579ac8b0dfad2e" - integrity sha512-t0JKGgqk2We+9may3t0xDdmneaXmyxq0xieYcKHxIsrJO64n1OiMWNUtc5gQK1PA0NpdCRrtZp4z+IUaKugrSA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-syntax-optional-catch-binding@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-catch-binding/-/plugin-syntax-optional-catch-binding-7.2.0.tgz#a94013d6eda8908dfe6a477e7f9eda85656ecf5c" - integrity sha512-bDe4xKNhb0LI7IvZHiA13kff0KEfaGX/Hv4lMA9+7TEc63hMNvfKo6ZFpXhKuEp+II/q35Gc4NoMeDZyaUbj9w== +"@babel/plugin-syntax-optional-chaining@^7.8.0": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.8.3.tgz#4f69c2ab95167e0180cd5336613f8c5788f7d48a" + integrity sha512-KoK9ErH1MBlCPxV0VANkXW2/dw4vlbGDrFgz8bmUsBGYkFRcbRwMh6cIJubdPrkxRwuGdtCk0v/wPTKbQgBjkg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.8.0" -"@babel/plugin-syntax-optional-chaining@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-optional-chaining/-/plugin-syntax-optional-chaining-7.2.0.tgz#a59d6ae8c167e7608eaa443fda9fa8fa6bf21dff" - integrity sha512-HtGCtvp5Uq/jH/WNUPkK6b7rufnCPLLlDAFN7cmACoIjaOOiXxUt3SswU5loHqrhtqTsa/WoLQ1OQ1AGuZqaWA== +"@babel/plugin-syntax-pipeline-operator@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.10.4.tgz#31bf327cf780dd60e0444fd98561119795247a6c" + integrity sha512-QOmXevisZebt9pBkMdDdXWg+fndB8dT/puwSKKu/1K3P4oBwmydN/4dX1hdrNvPHbw4xE+ocIoEus7c4eh7Igg== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-pipeline-operator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-pipeline-operator/-/plugin-syntax-pipeline-operator-7.5.0.tgz#8ea7c2c22847c797748bf07752722a317079dc1e" - integrity sha512-5FVxPiMTMXWk4R7Kq9pt272nDu8VImJdaIzvXFSTcXFbgKWWaOdbic12TvUvl6cK+AE5EgnhwvxuWik4ZYYdzg== +"@babel/plugin-syntax-throw-expressions@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.10.4.tgz#a588df9fa2203207a3ac7e35f0db3b67bf68eca3" + integrity sha512-Yac/4W71+JdAiOV3aLbnUUe2R0NZzNvdy5EqdauFnBQTxIXT58M89lOplIFVELTSus6PxFMjmbi2vXaJDiV/PQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-syntax-throw-expressions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-throw-expressions/-/plugin-syntax-throw-expressions-7.2.0.tgz#79001ee2afe1b174b1733cdc2fc69c9a46a0f1f8" - integrity sha512-ngwynuqu1Rx0JUS9zxSDuPgW1K8TyVZCi2hHehrL4vyjqE7RGoNHWlZsS7KQT2vw9Yjk4YLa0+KldBXTRdPLRg== +"@babel/plugin-syntax-top-level-await@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-syntax-top-level-await/-/plugin-syntax-top-level-await-7.10.4.tgz#4bbeb8917b54fcf768364e0a81f560e33a3ef57d" + integrity sha512-ni1brg4lXEmWyafKr0ccFWkJG0CeMt4WV1oyeBW6EFObF4oOHclbkj5cARxAPQyAQ2UTuplJyK4nfkXIMMFvsQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-arrow-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.2.0.tgz#9aeafbe4d6ffc6563bf8f8372091628f00779550" - integrity sha512-ER77Cax1+8/8jCB9fo4Ud161OZzWN5qawi4GusDuRLcDbDG+bIGYY20zb2dfAFdTRGzrfq2xZPvF0R64EHnimg== +"@babel/plugin-transform-arrow-functions@^7.10.4", "@babel/plugin-transform-arrow-functions@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-arrow-functions/-/plugin-transform-arrow-functions-7.10.4.tgz#e22960d77e697c74f41c501d44d73dbf8a6a64cd" + integrity sha512-9J/oD1jV0ZCBcgnoFWFq1vJd4msoKb/TCpGNFyyLt0zABdcvgK3aYikZ8HjzB14c26bc7E3Q1yugpwGy2aTPNA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-async-to-generator@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.5.0.tgz#89a3848a0166623b5bc481164b5936ab947e887e" - integrity sha512-mqvkzwIGkq0bEF1zLRRiTdjfomZJDV33AH3oQzHVGkI2VzEmXLpKKOBvEVaFZBJdN0XTyH38s9j/Kiqr68dggg== +"@babel/plugin-transform-async-to-generator@^7.10.4", "@babel/plugin-transform-async-to-generator@^7.5.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-async-to-generator/-/plugin-transform-async-to-generator-7.10.4.tgz#41a5017e49eb6f3cda9392a51eef29405b245a37" + integrity sha512-F6nREOan7J5UXTLsDsZG3DXmZSVofr2tGNwfdrVwkDWHfQckbQXnXSPfD7iO+c/2HGqycwyLST3DnZ16n+cBJQ== dependencies: - "@babel/helper-module-imports" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-remap-async-to-generator" "^7.1.0" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-remap-async-to-generator" "^7.10.4" -"@babel/plugin-transform-block-scoped-functions@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.2.0.tgz#5d3cc11e8d5ddd752aa64c9148d0db6cb79fd190" - integrity sha512-ntQPR6q1/NKuphly49+QiQiTN0O63uOwjdD6dhIjSWBI5xlrbUFh720TIpzBhpnrLfv2tNH/BXvLIab1+BAI0w== +"@babel/plugin-transform-block-scoped-functions@^7.10.4", "@babel/plugin-transform-block-scoped-functions@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoped-functions/-/plugin-transform-block-scoped-functions-7.10.4.tgz#1afa595744f75e43a91af73b0d998ecfe4ebc2e8" + integrity sha512-WzXDarQXYYfjaV1szJvN3AD7rZgZzC1JtjJZ8dMHUyiK8mxPRahynp14zzNjU3VkPqPsO38CzxiWO1c9ARZ8JA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-block-scoping@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.5.5.tgz#a35f395e5402822f10d2119f6f8e045e3639a2ce" - integrity sha512-82A3CLRRdYubkG85lKwhZB0WZoHxLGsJdux/cOVaJCJpvYFl1LVzAIFyRsa7CvXqW8rBM4Zf3Bfn8PHt5DP0Sg== +"@babel/plugin-transform-block-scoping@^7.10.4", "@babel/plugin-transform-block-scoping@^7.5.5": + version "7.11.1" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-block-scoping/-/plugin-transform-block-scoping-7.11.1.tgz#5b7efe98852bef8d652c0b28144cd93a9e4b5215" + integrity sha512-00dYeDE0EVEHuuM+26+0w/SCL0BH2Qy7LwHuI4Hi4MH5gkC8/AqMN5uWFJIsoXZrAphiMm1iXzBw6L2T+eA0ew== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - lodash "^4.17.13" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-classes@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.5.5.tgz#d094299d9bd680a14a2a0edae38305ad60fb4de9" - integrity sha512-U2htCNK/6e9K7jGyJ++1p5XRU+LJjrwtoiVn9SzRlDT2KubcZ11OOwy3s24TjHxPgxNwonCYP7U2K51uVYCMDg== +"@babel/plugin-transform-classes@^7.10.4", "@babel/plugin-transform-classes@^7.5.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-classes/-/plugin-transform-classes-7.10.4.tgz#405136af2b3e218bc4a1926228bc917ab1a0adc7" + integrity sha512-2oZ9qLjt161dn1ZE0Ms66xBncQH4In8Sqw1YWgBUZuGVJJS5c0OFZXL6dP2MRHrkU/eKhWg8CzFJhRQl50rQxA== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-define-map" "^7.5.5" - "@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.5.5" - "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-define-map" "^7.10.4" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-optimise-call-expression" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.10.4" globals "^11.1.0" -"@babel/plugin-transform-computed-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.2.0.tgz#83a7df6a658865b1c8f641d510c6f3af220216da" - integrity sha512-kP/drqTxY6Xt3NNpKiMomfgkNn4o7+vKxK2DDKcBG9sHj51vHqMBGy8wbDS/J4lMxnqs153/T3+DmCEAkC5cpA== +"@babel/plugin-transform-computed-properties@^7.10.4", "@babel/plugin-transform-computed-properties@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-computed-properties/-/plugin-transform-computed-properties-7.10.4.tgz#9ded83a816e82ded28d52d4b4ecbdd810cdfc0eb" + integrity sha512-JFwVDXcP/hM/TbyzGq3l/XWGut7p46Z3QvqFMXTfk6/09m7xZHJUN9xHfsv7vqqD4YnfI5ueYdSJtXqqBLyjBw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-destructuring@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.5.0.tgz#f6c09fdfe3f94516ff074fe877db7bc9ef05855a" - integrity sha512-YbYgbd3TryYYLGyC7ZR+Tq8H/+bCmwoaxHfJHupom5ECstzbRLTch6gOQbhEY9Z4hiCNHEURgq06ykFv9JZ/QQ== +"@babel/plugin-transform-destructuring@^7.10.4", "@babel/plugin-transform-destructuring@^7.5.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-destructuring/-/plugin-transform-destructuring-7.10.4.tgz#70ddd2b3d1bea83d01509e9bb25ddb3a74fc85e5" + integrity sha512-+WmfvyfsyF603iPa6825mq6Qrb7uLjTOsa3XOFzlYcYDHSS4QmpOWOL0NNBY5qMbvrcf3tq0Cw+v4lxswOBpgA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-dotall-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.4.4.tgz#361a148bc951444312c69446d76ed1ea8e4450c3" - integrity sha512-P05YEhRc2h53lZDjRPk/OektxCVevFzZs2Gfjd545Wde3k+yFDbXORgl2e0xpbq8mLcKJ7Idss4fAg0zORN/zg== +"@babel/plugin-transform-dotall-regex@^7.10.4", "@babel/plugin-transform-dotall-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-dotall-regex/-/plugin-transform-dotall-regex-7.10.4.tgz#469c2062105c1eb6a040eaf4fac4b488078395ee" + integrity sha512-ZEAVvUTCMlMFAbASYSVQoxIbHm2OkG2MseW6bV2JjIygOjdVv8tuxrCTzj1+Rynh7ODb8GivUy7dzEXzEhuPaA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-duplicate-keys@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.5.0.tgz#c5dbf5106bf84cdf691222c0974c12b1df931853" - integrity sha512-igcziksHizyQPlX9gfSjHkE2wmoCH3evvD2qR5w29/Dk0SMKE/eOI7f1HhBdNhR/zxJDqrgpoDTq5YSLH/XMsQ== +"@babel/plugin-transform-duplicate-keys@^7.10.4", "@babel/plugin-transform-duplicate-keys@^7.5.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-duplicate-keys/-/plugin-transform-duplicate-keys-7.10.4.tgz#697e50c9fee14380fe843d1f306b295617431e47" + integrity sha512-GL0/fJnmgMclHiBTTWXNlYjYsA7rDrtsazHG6mglaGSTh0KsrW04qml+Bbz9FL0LcJIRwBWL5ZqlNHKTkU3xAA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-exponentiation-operator@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.2.0.tgz#a63868289e5b4007f7054d46491af51435766008" - integrity sha512-umh4hR6N7mu4Elq9GG8TOu9M0bakvlsREEC+ialrQN6ABS4oDQ69qJv1VtR3uxlKMCQMCvzk7vr17RHKcjx68A== +"@babel/plugin-transform-exponentiation-operator@^7.10.4", "@babel/plugin-transform-exponentiation-operator@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-exponentiation-operator/-/plugin-transform-exponentiation-operator-7.10.4.tgz#5ae338c57f8cf4001bdb35607ae66b92d665af2e" + integrity sha512-S5HgLVgkBcRdyQAHbKj+7KyuWx8C6t5oETmUuwz1pt3WTWJhsUV0WIIXuVvfXMxl/QQyHKlSCNNtaIamG8fysw== dependencies: - "@babel/helper-builder-binary-assignment-operator-visitor" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-builder-binary-assignment-operator-visitor" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-flow-strip-types@^7.0.0": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.4.4.tgz#d267a081f49a8705fc9146de0768c6b58dccd8f7" - integrity sha512-WyVedfeEIILYEaWGAUWzVNyqG4sfsNooMhXWsu/YzOvVGcsnPb5PguysjJqI3t3qiaYj0BR8T2f5njdjTGe44Q== +"@babel/plugin-transform-flow-strip-types@^7.0.0", "@babel/plugin-transform-flow-strip-types@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-flow-strip-types/-/plugin-transform-flow-strip-types-7.10.4.tgz#c497957f09e86e3df7296271e9eb642876bf7788" + integrity sha512-XTadyuqNst88UWBTdLjM+wEY7BFnY2sYtPyAidfC7M/QaZnSuIZpMvLxqGT7phAcnGyWh/XQFLKcGf04CnvxSQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-flow" "^7.2.0" - -"@babel/plugin-transform-for-of@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.4.4.tgz#0267fc735e24c808ba173866c6c4d1440fc3c556" - integrity sha512-9T/5Dlr14Z9TIEXLXkt8T1DU7F24cbhwhMNUziN3hB1AXoZcdzPcTiKGRn/6iOymDqtTKWnr/BtRKN9JwbKtdQ== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-function-name@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.4.4.tgz#e1436116abb0610c2259094848754ac5230922ad" - integrity sha512-iU9pv7U+2jC9ANQkKeNF6DrPy4GBa4NWQtl6dHB4Pb3izX2JOEvDTFarlNsBj/63ZEzNNIAMs3Qw4fNCcSOXJA== - dependencies: - "@babel/helper-function-name" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.2.0.tgz#690353e81f9267dad4fd8cfd77eafa86aba53ea1" - integrity sha512-2ThDhm4lI4oV7fVQ6pNNK+sx+c/GM5/SaML0w/r4ZB7sAneD/piDJtwdKlNckXeyGK7wlwg2E2w33C/Hh+VFCg== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-member-expression-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.2.0.tgz#fa10aa5c58a2cb6afcf2c9ffa8cb4d8b3d489a2d" - integrity sha512-HiU3zKkSU6scTidmnFJ0bMX8hz5ixC93b4MHMiYebmk2lUVNGOboPsqQvx5LzooihijUoLR/v7Nc1rbBtnc7FA== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - -"@babel/plugin-transform-modules-amd@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.5.0.tgz#ef00435d46da0a5961aa728a1d2ecff063e4fb91" - integrity sha512-n20UsQMKnWrltocZZm24cRURxQnWIvsABPJlw/fvoy9c6AgHZzoelAIzajDHAQrDpuKFFPPcFGd7ChsYuIUMpg== - dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-commonjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.5.0.tgz#425127e6045231360858eeaa47a71d75eded7a74" - integrity sha512-xmHq0B+ytyrWJvQTc5OWAC4ii6Dhr0s22STOoydokG51JjWhyYo5mRPXoi+ZmtHQhZZwuXNN+GG5jy5UZZJxIQ== - dependencies: - "@babel/helper-module-transforms" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-simple-access" "^7.1.0" - babel-plugin-dynamic-import-node "^2.3.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-flow" "^7.10.4" -"@babel/plugin-transform-modules-systemjs@^7.5.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.5.0.tgz#e75266a13ef94202db2a0620977756f51d52d249" - integrity sha512-Q2m56tyoQWmuNGxEtUyeEkm6qJYFqs4c+XyXH5RAuYxObRNz9Zgj/1g2GMnjYp2EUyEy7YTrxliGCXzecl/vJg== - dependencies: - "@babel/helper-hoist-variables" "^7.4.4" - "@babel/helper-plugin-utils" "^7.0.0" - babel-plugin-dynamic-import-node "^2.3.0" - -"@babel/plugin-transform-modules-umd@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.2.0.tgz#7678ce75169f0877b8eb2235538c074268dd01ae" - integrity sha512-BV3bw6MyUH1iIsGhXlOK6sXhmSarZjtJ/vMiD9dNmpY8QXFFQTj+6v92pcfy1iqa8DeAfJFwoxcrS/TUZda6sw== +"@babel/plugin-transform-for-of@^7.10.4", "@babel/plugin-transform-for-of@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-for-of/-/plugin-transform-for-of-7.10.4.tgz#c08892e8819d3a5db29031b115af511dbbfebae9" + integrity sha512-ItdQfAzu9AlEqmusA/65TqJ79eRcgGmpPPFvBnGILXZH975G0LNjP1yjHvGgfuCxqrPPueXOPe+FsvxmxKiHHQ== dependencies: - "@babel/helper-module-transforms" "^7.1.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.4.5.tgz#9d269fd28a370258199b4294736813a60bbdd106" - integrity sha512-z7+2IsWafTBbjNsOxU/Iv5CvTJlr5w4+HGu1HovKYTtgJ362f7kBcQglkfmlspKKZ3bgrbSGvLfNx++ZJgCWsg== +"@babel/plugin-transform-function-name@^7.10.4", "@babel/plugin-transform-function-name@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-function-name/-/plugin-transform-function-name-7.10.4.tgz#6a467880e0fc9638514ba369111811ddbe2644b7" + integrity sha512-OcDCq2y5+E0dVD5MagT5X+yTRbcvFjDI2ZVAottGH6tzqjx/LKpgkUepu3hp/u4tZBzxxpNGwLsAvGBvQ2mJzg== dependencies: - regexp-tree "^0.1.6" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-new-target@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.4.4.tgz#18d120438b0cc9ee95a47f2c72bc9768fbed60a5" - integrity sha512-r1z3T2DNGQwwe2vPGZMBNjioT2scgWzK9BCnDEh+46z8EEwXBq24uRzd65I7pjtugzPSj921aM15RpESgzsSuA== +"@babel/plugin-transform-literals@^7.10.4", "@babel/plugin-transform-literals@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-literals/-/plugin-transform-literals-7.10.4.tgz#9f42ba0841100a135f22712d0e391c462f571f3c" + integrity sha512-Xd/dFSTEVuUWnyZiMu76/InZxLTYilOSr1UlHV+p115Z/Le2Fi1KXkJUYz0b42DfndostYlPub3m8ZTQlMaiqQ== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-object-super@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.5.5.tgz#c70021df834073c65eb613b8679cc4a381d1a9f9" - integrity sha512-un1zJQAhSosGFBduPgN/YFNvWVpRuHKU7IHBglLoLZsGmruJPOo6pbInneflUdmq7YvSVqhpPs5zdBvLnteltQ== +"@babel/plugin-transform-member-expression-literals@^7.10.4", "@babel/plugin-transform-member-expression-literals@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-member-expression-literals/-/plugin-transform-member-expression-literals-7.10.4.tgz#b1ec44fcf195afcb8db2c62cd8e551c881baf8b7" + integrity sha512-0bFOvPyAoTBhtcJLr9VcwZqKmSjFml1iVxvPL0ReomGU53CX53HsM4h2SzckNdkQcHox1bpAqzxBI1Y09LlBSw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-replace-supers" "^7.5.5" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-parameters@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.4.4.tgz#7556cf03f318bd2719fe4c922d2d808be5571e16" - integrity sha512-oMh5DUO1V63nZcu/ZVLQFqiihBGo4OpxJxR1otF50GMeCLiRx5nUdtokd+u9SuVJrvvuIh9OosRFPP4pIPnwmw== +"@babel/plugin-transform-modules-amd@^7.10.4", "@babel/plugin-transform-modules-amd@^7.5.0": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-amd/-/plugin-transform-modules-amd-7.10.5.tgz#1b9cddaf05d9e88b3aad339cb3e445c4f020a9b1" + integrity sha512-elm5uruNio7CTLFItVC/rIzKLfQ17+fX7EVz5W0TMgIHFo1zY0Ozzx+lgwhL4plzl8OzVn6Qasx5DeEFyoNiRw== dependencies: - "@babel/helper-call-delegate" "^7.4.4" - "@babel/helper-get-function-arity" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-property-literals@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.2.0.tgz#03e33f653f5b25c4eb572c98b9485055b389e905" - integrity sha512-9q7Dbk4RhgcLp8ebduOpCbtjh7C0itoLYHXd9ueASKAG/is5PQtMR5VJGka9NKqGhYEGn5ITahd4h9QeBMylWQ== +"@babel/plugin-transform-modules-commonjs@^7.10.4", "@babel/plugin-transform-modules-commonjs@^7.5.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-commonjs/-/plugin-transform-modules-commonjs-7.10.4.tgz#66667c3eeda1ebf7896d41f1f16b17105a2fbca0" + integrity sha512-Xj7Uq5o80HDLlW64rVfDBhao6OX89HKUmb+9vWYaLXBZOma4gA6tw4Ni1O5qVDoZWUV0fxMYA0aYzOawz0l+1w== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-simple-access" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-react-display-name@^7.0.0", "@babel/plugin-transform-react-display-name@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.2.0.tgz#ebfaed87834ce8dc4279609a4f0c324c156e3eb0" - integrity sha512-Htf/tPa5haZvRMiNSQSFifK12gtr/8vwfr+A9y69uF0QcU77AVu4K7MiHEkTxF7lQoHOL0F9ErqgfNEAKgXj7A== +"@babel/plugin-transform-modules-systemjs@^7.10.4", "@babel/plugin-transform-modules-systemjs@^7.5.0": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-systemjs/-/plugin-transform-modules-systemjs-7.10.5.tgz#6270099c854066681bae9e05f87e1b9cadbe8c85" + integrity sha512-f4RLO/OL14/FP1AEbcsWMzpbUz6tssRaeQg11RH1BP/XnPpRoVwgeYViMFacnkaw4k4wjRSjn3ip1Uw9TaXuMw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-hoist-variables" "^7.10.4" + "@babel/helper-module-transforms" "^7.10.5" + "@babel/helper-plugin-utils" "^7.10.4" + babel-plugin-dynamic-import-node "^2.3.3" -"@babel/plugin-transform-react-jsx-self@^7.0.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.2.0.tgz#461e21ad9478f1031dd5e276108d027f1b5240ba" - integrity sha512-v6S5L/myicZEy+jr6ielB0OR8h+EH/1QFx/YJ7c7Ua+7lqsjj/vW6fD5FR9hB/6y7mGbfT4vAURn3xqBxsUcdg== +"@babel/plugin-transform-modules-umd@^7.10.4", "@babel/plugin-transform-modules-umd@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-modules-umd/-/plugin-transform-modules-umd-7.10.4.tgz#9a8481fe81b824654b3a0b65da3df89f3d21839e" + integrity sha512-mohW5q3uAEt8T45YT7Qc5ws6mWgJAaL/8BfWD9Dodo1A3RKWli8wTS+WiQ/knF+tXlPirW/1/MqzzGfCExKECA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-module-transforms" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-react-jsx-source@^7.0.0": - version "7.5.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.5.0.tgz#583b10c49cf057e237085bcbd8cc960bd83bd96b" - integrity sha512-58Q+Jsy4IDCZx7kqEZuSDdam/1oW8OdDX8f+Loo6xyxdfg1yF0GE2XNJQSTZCaMol93+FBzpWiPEwtbMloAcPg== +"@babel/plugin-transform-named-capturing-groups-regex@^7.10.4", "@babel/plugin-transform-named-capturing-groups-regex@^7.4.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-named-capturing-groups-regex/-/plugin-transform-named-capturing-groups-regex-7.10.4.tgz#78b4d978810b6f3bcf03f9e318f2fc0ed41aecb6" + integrity sha512-V6LuOnD31kTkxQPhKiVYzYC/Jgdq53irJC/xBSmqcNcqFGV+PER4l6rU5SH2Vl7bH9mLDHcc0+l9HUOe4RNGKA== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-create-regexp-features-plugin" "^7.10.4" -"@babel/plugin-transform-react-jsx@^7.0.0": - version "7.3.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.3.0.tgz#f2cab99026631c767e2745a5368b331cfe8f5290" - integrity sha512-a/+aRb7R06WcKvQLOu4/TpjKOdvVEKRLWFpKcNuHhiREPgGRB4TQJxq07+EZLS8LFVYpfq1a5lDUnuMdcCpBKg== +"@babel/plugin-transform-new-target@^7.10.4", "@babel/plugin-transform-new-target@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-new-target/-/plugin-transform-new-target-7.10.4.tgz#9097d753cb7b024cb7381a3b2e52e9513a9c6888" + integrity sha512-YXwWUDAH/J6dlfwqlWsztI2Puz1NtUAubXhOPLQ5gjR/qmQ5U96DY4FQO8At33JN4XPBhrjB8I4eMmLROjjLjw== dependencies: - "@babel/helper-builder-react-jsx" "^7.3.0" - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-syntax-jsx" "^7.2.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-regenerator@^7.4.5": - version "7.4.5" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.4.5.tgz#629dc82512c55cee01341fb27bdfcb210354680f" - integrity sha512-gBKRh5qAaCWntnd09S8QC7r3auLCqq5DI6O0DlfoyDjslSBVqBibrMdsqO+Uhmx3+BlOmE/Kw1HFxmGbv0N9dA== +"@babel/plugin-transform-object-super@^7.10.4", "@babel/plugin-transform-object-super@^7.5.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-object-super/-/plugin-transform-object-super-7.10.4.tgz#d7146c4d139433e7a6526f888c667e314a093894" + integrity sha512-5iTw0JkdRdJvr7sY0vHqTpnruUpTea32JHmq/atIWqsnNussbRzjEDyWep8UNztt1B5IusBYg8Irb0bLbiEBCQ== dependencies: - regenerator-transform "^0.14.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-replace-supers" "^7.10.4" -"@babel/plugin-transform-reserved-words@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.2.0.tgz#4792af87c998a49367597d07fedf02636d2e1634" - integrity sha512-fz43fqW8E1tAB3DKF19/vxbpib1fuyCwSPE418ge5ZxILnBhWyhtPgz8eh1RCGGJlwvksHkyxMxh0eenFi+kFw== +"@babel/plugin-transform-parameters@^7.10.4", "@babel/plugin-transform-parameters@^7.4.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-parameters/-/plugin-transform-parameters-7.10.5.tgz#59d339d58d0b1950435f4043e74e2510005e2c4a" + integrity sha512-xPHwUj5RdFV8l1wuYiu5S9fqWGM2DrYc24TMvUiRrPVm+SM3XeqU9BcokQX/kEUe+p2RBwy+yoiR1w/Blq6ubw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-get-function-arity" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-shorthand-properties@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.2.0.tgz#6333aee2f8d6ee7e28615457298934a3b46198f0" - integrity sha512-QP4eUM83ha9zmYtpbnyjTLAGKQritA5XW/iG9cjtuOI8s1RuL/3V6a3DeSHfKutJQ+ayUfeZJPcnCYEQzaPQqg== +"@babel/plugin-transform-property-literals@^7.10.4", "@babel/plugin-transform-property-literals@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-property-literals/-/plugin-transform-property-literals-7.10.4.tgz#f6fe54b6590352298785b83edd815d214c42e3c0" + integrity sha512-ofsAcKiUxQ8TY4sScgsGeR2vJIsfrzqvFb9GvJ5UdXDzl+MyYCaBj/FGzXuv7qE0aJcjWMILny1epqelnFlz8g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-spread@^7.2.0": - version "7.2.2" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.2.2.tgz#3103a9abe22f742b6d406ecd3cd49b774919b406" - integrity sha512-KWfky/58vubwtS0hLqEnrWJjsMGaOeSBn90Ezn5Jeg9Z8KKHmELbP1yGylMlm5N6TPKeY9A2+UaSYLdxahg01w== +"@babel/plugin-transform-react-display-name@^7.0.0", "@babel/plugin-transform-react-display-name@^7.10.4", "@babel/plugin-transform-react-display-name@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-display-name/-/plugin-transform-react-display-name-7.10.4.tgz#b5795f4e3e3140419c3611b7a2a3832b9aef328d" + integrity sha512-Zd4X54Mu9SBfPGnEcaGcOrVAYOtjT2on8QZkLKEq1S/tHexG39d9XXGZv19VfRrDjPJzFmPfTAqOQS1pfFOujw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" -"@babel/plugin-transform-sticky-regex@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.2.0.tgz#a1e454b5995560a9c1e0d537dfc15061fd2687e1" - integrity sha512-KKYCoGaRAf+ckH8gEL3JHUaFVyNHKe3ASNsZ+AlktgHevvxGigoIttrEJb8iKN03Q7Eazlv1s6cx2B2cQ3Jabw== +"@babel/plugin-transform-react-jsx-development@^7.10.4": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-development/-/plugin-transform-react-jsx-development-7.11.5.tgz#e1439e6a57ee3d43e9f54ace363fb29cefe5d7b6" + integrity sha512-cImAmIlKJ84sDmpQzm4/0q/2xrXlDezQoixy3qoz1NJeZL/8PRon6xZtluvr4H4FzwlDGI5tCcFupMnXGtr+qw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.0.0" + "@babel/helper-builder-react-jsx-experimental" "^7.11.5" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-template-literals@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.4.4.tgz#9d28fea7bbce637fb7612a0750989d8321d4bcb0" - integrity sha512-mQrEC4TWkhLN0z8ygIvEL9ZEToPhG5K7KDW3pzGqOfIGZ28Jb0POUkeWcoz8HnHvhFy6dwAT1j8OzqN8s804+g== +"@babel/plugin-transform-react-jsx-self@^7.0.0", "@babel/plugin-transform-react-jsx-self@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-self/-/plugin-transform-react-jsx-self-7.10.4.tgz#cd301a5fed8988c182ed0b9d55e9bd6db0bd9369" + integrity sha512-yOvxY2pDiVJi0axdTWHSMi5T0DILN+H+SaeJeACHKjQLezEzhLx9nEF9xgpBLPtkZsks9cnb5P9iBEi21En3gg== dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-plugin-utils" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" -"@babel/plugin-transform-typeof-symbol@^7.2.0": - version "7.2.0" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.2.0.tgz#117d2bcec2fbf64b4b59d1f9819894682d29f2b2" - integrity sha512-2LNhETWYxiYysBtrBTqL8+La0jIoQQnIScUJc74OYvUGRmkskNY4EzLCnjHBzdmb38wqtTaixpo1NctEcvMDZw== - dependencies: - "@babel/helper-plugin-utils" "^7.0.0" +"@babel/plugin-transform-react-jsx-source@^7.0.0", "@babel/plugin-transform-react-jsx-source@^7.10.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx-source/-/plugin-transform-react-jsx-source-7.10.5.tgz#34f1779117520a779c054f2cdd9680435b9222b4" + integrity sha512-wTeqHVkN1lfPLubRiZH3o73f4rfon42HpgxUSs86Nc+8QIcm/B9s8NNVXu/gwGcOyd7yDib9ikxoDLxJP0UiDA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + +"@babel/plugin-transform-react-jsx@^7.0.0", "@babel/plugin-transform-react-jsx@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-jsx/-/plugin-transform-react-jsx-7.10.4.tgz#673c9f913948764a4421683b2bef2936968fddf2" + integrity sha512-L+MfRhWjX0eI7Js093MM6MacKU4M6dnCRa/QPDwYMxjljzSCzzlzKzj9Pk4P3OtrPcxr2N3znR419nr3Xw+65A== + dependencies: + "@babel/helper-builder-react-jsx" "^7.10.4" + "@babel/helper-builder-react-jsx-experimental" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-syntax-jsx" "^7.10.4" + +"@babel/plugin-transform-react-pure-annotations@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-react-pure-annotations/-/plugin-transform-react-pure-annotations-7.10.4.tgz#3eefbb73db94afbc075f097523e445354a1c6501" + integrity sha512-+njZkqcOuS8RaPakrnR9KvxjoG1ASJWpoIv/doyWngId88JoFlPlISenGXjrVacZUIALGUr6eodRs1vmPnF23A== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-regenerator@^7.10.4", "@babel/plugin-transform-regenerator@^7.4.5": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-regenerator/-/plugin-transform-regenerator-7.10.4.tgz#2015e59d839074e76838de2159db421966fd8b63" + integrity sha512-3thAHwtor39A7C04XucbMg17RcZ3Qppfxr22wYzZNcVIkPHfpM9J0SO8zuCV6SZa265kxBJSrfKTvDCYqBFXGw== + dependencies: + regenerator-transform "^0.14.2" + +"@babel/plugin-transform-reserved-words@^7.10.4", "@babel/plugin-transform-reserved-words@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-reserved-words/-/plugin-transform-reserved-words-7.10.4.tgz#8f2682bcdcef9ed327e1b0861585d7013f8a54dd" + integrity sha512-hGsw1O6Rew1fkFbDImZIEqA8GoidwTAilwCyWqLBM9f+e/u/sQMQu7uX6dyokfOayRuuVfKOW4O7HvaBWM+JlQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-shorthand-properties@^7.10.4", "@babel/plugin-transform-shorthand-properties@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-shorthand-properties/-/plugin-transform-shorthand-properties-7.10.4.tgz#9fd25ec5cdd555bb7f473e5e6ee1c971eede4dd6" + integrity sha512-AC2K/t7o07KeTIxMoHneyX90v3zkm5cjHJEokrPEAGEy3UCp8sLKfnfOIGdZ194fyN4wfX/zZUWT9trJZ0qc+Q== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-spread@^7.11.0", "@babel/plugin-transform-spread@^7.2.0": + version "7.11.0" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-spread/-/plugin-transform-spread-7.11.0.tgz#fa84d300f5e4f57752fe41a6d1b3c554f13f17cc" + integrity sha512-UwQYGOqIdQJe4aWNyS7noqAnN2VbaczPLiEtln+zPowRNlD+79w3oi2TWfYe0eZgd+gjZCbsydN7lzWysDt+gw== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-skip-transparent-expression-wrappers" "^7.11.0" + +"@babel/plugin-transform-sticky-regex@^7.10.4", "@babel/plugin-transform-sticky-regex@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-sticky-regex/-/plugin-transform-sticky-regex-7.10.4.tgz#8f3889ee8657581130a29d9cc91d7c73b7c4a28d" + integrity sha512-Ddy3QZfIbEV0VYcVtFDCjeE4xwVTJWTmUtorAJkn6u/92Z/nWJNV+mILyqHKrUxXYKA2EoCilgoPePymKL4DvQ== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/helper-regex" "^7.10.4" + +"@babel/plugin-transform-template-literals@^7.10.4", "@babel/plugin-transform-template-literals@^7.4.4": + version "7.10.5" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-template-literals/-/plugin-transform-template-literals-7.10.5.tgz#78bc5d626a6642db3312d9d0f001f5e7639fde8c" + integrity sha512-V/lnPGIb+KT12OQikDvgSuesRX14ck5FfJXt6+tXhdkJ+Vsd0lDCVtF6jcB4rNClYFzaB2jusZ+lNISDk2mMMw== + dependencies: + "@babel/helper-annotate-as-pure" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-typeof-symbol@^7.10.4", "@babel/plugin-transform-typeof-symbol@^7.2.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-typeof-symbol/-/plugin-transform-typeof-symbol-7.10.4.tgz#9509f1a7eec31c4edbffe137c16cc33ff0bc5bfc" + integrity sha512-QqNgYwuuW0y0H+kUE/GWSR45t/ccRhe14Fs/4ZRouNNQsyd4o3PG4OtHiIrepbM2WKUBDAXKCAK/Lk4VhzTaGA== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-escapes@^7.10.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-escapes/-/plugin-transform-unicode-escapes-7.10.4.tgz#feae523391c7651ddac115dae0a9d06857892007" + integrity sha512-y5XJ9waMti2J+e7ij20e+aH+fho7Wb7W8rNuu72aKRwCHFqQdhkdU2lo3uZ9tQuboEJcUFayXdARhcxLQ3+6Fg== + dependencies: + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/plugin-transform-unicode-regex@^7.10.4", "@babel/plugin-transform-unicode-regex@^7.4.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.10.4.tgz#e56d71f9282fac6db09c82742055576d5e6d80a8" + integrity sha512-wNfsc4s8N2qnIwpO/WP2ZiSyjfpTamT2C9V9FDH/Ljub9zw6P3SjkXcFmc0RQUt96k2fmIvtla2MMjgTwIAC+A== + dependencies: + "@babel/helper-create-regexp-features-plugin" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + +"@babel/preset-env@^7.5.5", "@babel/preset-env@^7.9.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.11.5.tgz#18cb4b9379e3e92ffea92c07471a99a2914e4272" + integrity sha512-kXqmW1jVcnB2cdueV+fyBM8estd5mlNfaQi6lwLgRwCby4edpavgbFhiBNjmWA3JpB/yZGSISa7Srf+TwxDQoA== + dependencies: + "@babel/compat-data" "^7.11.0" + "@babel/helper-compilation-targets" "^7.10.4" + "@babel/helper-module-imports" "^7.10.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-proposal-async-generator-functions" "^7.10.4" + "@babel/plugin-proposal-class-properties" "^7.10.4" + "@babel/plugin-proposal-dynamic-import" "^7.10.4" + "@babel/plugin-proposal-export-namespace-from" "^7.10.4" + "@babel/plugin-proposal-json-strings" "^7.10.4" + "@babel/plugin-proposal-logical-assignment-operators" "^7.11.0" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.10.4" + "@babel/plugin-proposal-numeric-separator" "^7.10.4" + "@babel/plugin-proposal-object-rest-spread" "^7.11.0" + "@babel/plugin-proposal-optional-catch-binding" "^7.10.4" + "@babel/plugin-proposal-optional-chaining" "^7.11.0" + "@babel/plugin-proposal-private-methods" "^7.10.4" + "@babel/plugin-proposal-unicode-property-regex" "^7.10.4" + "@babel/plugin-syntax-async-generators" "^7.8.0" + "@babel/plugin-syntax-class-properties" "^7.10.4" + "@babel/plugin-syntax-dynamic-import" "^7.8.0" + "@babel/plugin-syntax-export-namespace-from" "^7.8.3" + "@babel/plugin-syntax-json-strings" "^7.8.0" + "@babel/plugin-syntax-logical-assignment-operators" "^7.10.4" + "@babel/plugin-syntax-nullish-coalescing-operator" "^7.8.0" + "@babel/plugin-syntax-numeric-separator" "^7.10.4" + "@babel/plugin-syntax-object-rest-spread" "^7.8.0" + "@babel/plugin-syntax-optional-catch-binding" "^7.8.0" + "@babel/plugin-syntax-optional-chaining" "^7.8.0" + "@babel/plugin-syntax-top-level-await" "^7.10.4" + "@babel/plugin-transform-arrow-functions" "^7.10.4" + "@babel/plugin-transform-async-to-generator" "^7.10.4" + "@babel/plugin-transform-block-scoped-functions" "^7.10.4" + "@babel/plugin-transform-block-scoping" "^7.10.4" + "@babel/plugin-transform-classes" "^7.10.4" + "@babel/plugin-transform-computed-properties" "^7.10.4" + "@babel/plugin-transform-destructuring" "^7.10.4" + "@babel/plugin-transform-dotall-regex" "^7.10.4" + "@babel/plugin-transform-duplicate-keys" "^7.10.4" + "@babel/plugin-transform-exponentiation-operator" "^7.10.4" + "@babel/plugin-transform-for-of" "^7.10.4" + "@babel/plugin-transform-function-name" "^7.10.4" + "@babel/plugin-transform-literals" "^7.10.4" + "@babel/plugin-transform-member-expression-literals" "^7.10.4" + "@babel/plugin-transform-modules-amd" "^7.10.4" + "@babel/plugin-transform-modules-commonjs" "^7.10.4" + "@babel/plugin-transform-modules-systemjs" "^7.10.4" + "@babel/plugin-transform-modules-umd" "^7.10.4" + "@babel/plugin-transform-named-capturing-groups-regex" "^7.10.4" + "@babel/plugin-transform-new-target" "^7.10.4" + "@babel/plugin-transform-object-super" "^7.10.4" + "@babel/plugin-transform-parameters" "^7.10.4" + "@babel/plugin-transform-property-literals" "^7.10.4" + "@babel/plugin-transform-regenerator" "^7.10.4" + "@babel/plugin-transform-reserved-words" "^7.10.4" + "@babel/plugin-transform-shorthand-properties" "^7.10.4" + "@babel/plugin-transform-spread" "^7.11.0" + "@babel/plugin-transform-sticky-regex" "^7.10.4" + "@babel/plugin-transform-template-literals" "^7.10.4" + "@babel/plugin-transform-typeof-symbol" "^7.10.4" + "@babel/plugin-transform-unicode-escapes" "^7.10.4" + "@babel/plugin-transform-unicode-regex" "^7.10.4" + "@babel/preset-modules" "^0.1.3" + "@babel/types" "^7.11.5" + browserslist "^4.12.0" + core-js-compat "^3.6.2" + invariant "^2.2.2" + levenary "^1.1.1" + semver "^5.5.0" -"@babel/plugin-transform-unicode-regex@^7.4.4": - version "7.4.4" - resolved "https://registry.yarnpkg.com/@babel/plugin-transform-unicode-regex/-/plugin-transform-unicode-regex-7.4.4.tgz#ab4634bb4f14d36728bf5978322b35587787970f" - integrity sha512-il+/XdNw01i93+M9J9u4T7/e/Ue/vWfNZE4IRUQjplu2Mqb/AFTDimkw2tdEdSH50wuQXZAbXSql0UphQke+vA== +"@babel/preset-flow@^7.0.0", "@babel/preset-flow@^7.9.0": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.10.4.tgz#e0d9c72f8cb02d1633f6a5b7b16763aa2edf659f" + integrity sha512-XI6l1CptQCOBv+ZKYwynyswhtOKwpZZp5n0LG1QKCo8erRhqjoQV6nvx61Eg30JHpysWQSBwA2AWRU3pBbSY5g== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/helper-regex" "^7.4.4" - regexpu-core "^4.5.4" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-flow-strip-types" "^7.10.4" -"@babel/preset-env@^7.1.0", "@babel/preset-env@^7.5.5": - version "7.5.5" - resolved "https://registry.yarnpkg.com/@babel/preset-env/-/preset-env-7.5.5.tgz#bc470b53acaa48df4b8db24a570d6da1fef53c9a" - integrity sha512-GMZQka/+INwsMz1A5UEql8tG015h5j/qjptpKY2gJ7giy8ohzU710YciJB5rcKsWGWHiW3RUnHib0E5/m3Tp3A== +"@babel/preset-modules@^0.1.3": + version "0.1.4" + resolved "https://registry.yarnpkg.com/@babel/preset-modules/-/preset-modules-0.1.4.tgz#362f2b68c662842970fdb5e254ffc8fc1c2e415e" + integrity sha512-J36NhwnfdzpmH41M1DrnkkgAqhZaqr/NBdPfQ677mLzlaXo+oDiv1deyCDtgAhz8p328otdob0Du7+xgHGZbKg== dependencies: - "@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-dynamic-import" "^7.5.0" - "@babel/plugin-proposal-json-strings" "^7.2.0" - "@babel/plugin-proposal-object-rest-spread" "^7.5.5" - "@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-dynamic-import" "^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.5.0" - "@babel/plugin-transform-block-scoped-functions" "^7.2.0" - "@babel/plugin-transform-block-scoping" "^7.5.5" - "@babel/plugin-transform-classes" "^7.5.5" - "@babel/plugin-transform-computed-properties" "^7.2.0" - "@babel/plugin-transform-destructuring" "^7.5.0" "@babel/plugin-transform-dotall-regex" "^7.4.4" - "@babel/plugin-transform-duplicate-keys" "^7.5.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.5.0" - "@babel/plugin-transform-modules-commonjs" "^7.5.0" - "@babel/plugin-transform-modules-systemjs" "^7.5.0" - "@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.5.5" - "@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.5.5" - browserslist "^4.6.0" - core-js-compat "^3.1.1" - invariant "^2.2.2" - js-levenshtein "^1.1.3" - semver "^5.5.0" + "@babel/types" "^7.4.4" + esutils "^2.0.2" -"@babel/preset-flow@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-flow/-/preset-flow-7.0.0.tgz#afd764835d9535ec63d8c7d4caf1c06457263da2" - integrity sha512-bJOHrYOPqJZCkPVbG1Lot2r5OSsB+iUOaxiHdlOeB1yPWS6evswVHwvkDLZ54WTaTRIk89ds0iHmGZSnxlPejQ== +"@babel/preset-react@^7.0.0", "@babel/preset-react@^7.9.4": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.10.4.tgz#92e8a66d816f9911d11d4cc935be67adfc82dbcf" + integrity sha512-BrHp4TgOIy4M19JAfO1LhycVXOPWdDbTRep7eVyatf174Hff+6Uk53sDyajqZPu8W1qXRBiYOfIamek6jA7YVw== dependencies: - "@babel/helper-plugin-utils" "^7.0.0" - "@babel/plugin-transform-flow-strip-types" "^7.0.0" + "@babel/helper-plugin-utils" "^7.10.4" + "@babel/plugin-transform-react-display-name" "^7.10.4" + "@babel/plugin-transform-react-jsx" "^7.10.4" + "@babel/plugin-transform-react-jsx-development" "^7.10.4" + "@babel/plugin-transform-react-jsx-self" "^7.10.4" + "@babel/plugin-transform-react-jsx-source" "^7.10.4" + "@babel/plugin-transform-react-pure-annotations" "^7.10.4" -"@babel/preset-react@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-react/-/preset-react-7.0.0.tgz#e86b4b3d99433c7b3e9e91747e2653958bc6b3c0" - integrity sha512-oayxyPS4Zj+hF6Et11BwuBkmpgT/zMxyuZgFrMeZID6Hdh3dGlk4sHCAhdBCpuCKW2ppBfl2uCCetlrUIJRY3w== - dependencies: - "@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/preset-stage-0@^7.0.0": - version "7.0.0" - resolved "https://registry.yarnpkg.com/@babel/preset-stage-0/-/preset-stage-0-7.0.0.tgz#999aaec79ee8f0a763042c68c06539c97c6e0646" - integrity sha512-FBMd0IiARPtH5aaOFUVki6evHiJQiY0pFy7fizyRF7dtwc+el3nwpzvhb9qBNzceG1OIJModG1xpE0DDFjPXwA== +"@babel/preset-stage-0@^7.8.3": + version "7.8.3" + resolved "https://registry.yarnpkg.com/@babel/preset-stage-0/-/preset-stage-0-7.8.3.tgz#b6a0eca1a3b72e07f9caf58f998e97568028f6f5" + integrity sha512-+l6FlG1j73t4wh78W41StbcCz0/9a1/y+vxfnjtHl060kSmcgMfGzK9MEkLvrCOXfhp9RCX+d88sm6rOqxEIEQ== "@babel/runtime-corejs2@^7.0.0", "@babel/runtime-corejs2@^7.5.5": version "7.5.5" @@ -932,44 +1059,44 @@ dependencies: regenerator-runtime "^0.12.0" -"@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.5", "@babel/runtime@^7.7.6": - version "7.8.4" - resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.8.4.tgz#d79f5a2040f7caa24d53e563aad49cbc05581308" - integrity sha512-neAp3zt80trRVBI1x0azq6c57aNBqYZH8KhMm3TaB7wEI5Q4A2SHfBHE8w9gOhI/lrqxtEbXZgQIrHP+wvSGwQ== - dependencies: - regenerator-runtime "^0.13.2" - -"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.8.3": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.8.6.tgz#86b22af15f828dfb086474f964dcc3e39c43ce2b" - integrity sha512-zbMsPMy/v0PWFZEhQJ66bqjhH+z0JgMoBWuikXybgG3Gkd/3t5oQ1Rw2WQhnSrsOmsKXnZOx15tkC4qON/+JPg== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" - -"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.1.4", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.8.6.tgz#acfe0c64e1cd991b3e32eae813a6eb564954b5ff" - integrity sha512-2B8l0db/DPi8iinITKuo7cbPznLCEk0kCxDoB9/N6gGNg/gxOXiR/IcymAFPiBwk5w6TtQ27w4wpElgp9btR9A== - dependencies: - "@babel/code-frame" "^7.8.3" - "@babel/generator" "^7.8.6" - "@babel/helper-function-name" "^7.8.3" - "@babel/helper-split-export-declaration" "^7.8.3" - "@babel/parser" "^7.8.6" - "@babel/types" "^7.8.6" +"@babel/runtime@^7.1.2", "@babel/runtime@^7.2.0", "@babel/runtime@^7.4.0", "@babel/runtime@^7.4.4", "@babel/runtime@^7.4.5", "@babel/runtime@^7.5.5", "@babel/runtime@^7.7.2", "@babel/runtime@^7.7.6", "@babel/runtime@^7.8.4", "@babel/runtime@^7.8.7", "@babel/runtime@^7.9.2": + version "7.11.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.11.2.tgz#f549c13c754cc40b87644b9fa9f09a6a95fe0736" + integrity sha512-TeWkU52so0mPtDcaCTxNBI/IHiz0pZgr8VEFqXFtZWpYD08ZB6FaSwVAS8MKRQAP3bYKiVjwysOJgMFY28o6Tw== + dependencies: + regenerator-runtime "^0.13.4" + +"@babel/template@^7.1.0", "@babel/template@^7.10.4", "@babel/template@^7.4.0", "@babel/template@^7.4.4", "@babel/template@^7.8.3": + version "7.10.4" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.10.4.tgz#3251996c4200ebc71d1a8fc405fba940f36ba278" + integrity sha512-ZCjD27cGJFUB6nmCB1Enki3r+L5kJveX9pq1SvAUKoICy6CZ9yD8xO086YXdYhvNjBdnekm4ZnaP5yC8Cs/1tA== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/parser" "^7.10.4" + "@babel/types" "^7.10.4" + +"@babel/traverse@^7.0.0", "@babel/traverse@^7.1.0", "@babel/traverse@^7.10.4", "@babel/traverse@^7.11.5", "@babel/traverse@^7.4.3", "@babel/traverse@^7.4.4", "@babel/traverse@^7.4.5", "@babel/traverse@^7.5.5", "@babel/traverse@^7.9.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.11.5.tgz#be777b93b518eb6d76ee2e1ea1d143daa11e61c3" + integrity sha512-EjiPXt+r7LiCZXEfRpSJd+jUMnBd4/9OUv7Nx3+0u9+eimMwJmG0Q98lw4/289JCoxSE8OolDMNZaaF/JZ69WQ== + dependencies: + "@babel/code-frame" "^7.10.4" + "@babel/generator" "^7.11.5" + "@babel/helper-function-name" "^7.10.4" + "@babel/helper-split-export-declaration" "^7.11.0" + "@babel/parser" "^7.11.5" + "@babel/types" "^7.11.5" debug "^4.1.0" globals "^11.1.0" - lodash "^4.17.13" + lodash "^4.17.19" -"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.1.3", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.8.3", "@babel/types@^7.8.6": - version "7.8.6" - resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.8.6.tgz#629ecc33c2557fcde7126e58053127afdb3e6d01" - integrity sha512-wqz7pgWMIrht3gquyEFPVXeXCti72Rm8ep9b5tQKz9Yg9LzJA3HxosF1SB3Kc81KD1A3XBkkVYtJvCKS2Z/QrA== +"@babel/types@^7.0.0", "@babel/types@^7.0.0-beta.49", "@babel/types@^7.10.4", "@babel/types@^7.10.5", "@babel/types@^7.11.0", "@babel/types@^7.11.5", "@babel/types@^7.2.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.5.5", "@babel/types@^7.8.3", "@babel/types@^7.8.6", "@babel/types@^7.9.0": + version "7.11.5" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.11.5.tgz#d9de577d01252d77c6800cee039ee64faf75662d" + integrity sha512-bvM7Qz6eKnJVFIn+1LPtjlBFPVN5jNDc1XmN15vWe7Q3DPBufWWsLiIvUu7xW87uTG6QoggpIDnUgLQvPheU+Q== dependencies: - esutils "^2.0.2" - lodash "^4.17.13" + "@babel/helper-validator-identifier" "^7.10.4" + lodash "^4.17.19" to-fast-properties "^2.0.0" "@cnakazawa/watch@^1.0.3": @@ -998,6 +1125,42 @@ resolved "https://registry.yarnpkg.com/@csstools/convert-colors/-/convert-colors-1.4.0.tgz#ad495dc41b12e75d588c6db8b9834f08fa131eb7" integrity sha512-5a6wqoJV/xEdbRNKVo6I4hO3VjyDq//8q2f9I6PBAvMesJHFauXDorcNCsr9RzvsZnaWi5NYCcfyqP1QeFHFbw== +"@emotion/cache@^10.0.27", "@emotion/cache@^10.0.9": + version "10.0.29" + resolved "https://registry.yarnpkg.com/@emotion/cache/-/cache-10.0.29.tgz#87e7e64f412c060102d589fe7c6dc042e6f9d1e0" + integrity sha512-fU2VtSVlHiF27empSbxi1O2JFdNWZO+2NFHfwO0pxgTep6Xa3uGb+3pVKfLww2l/IBGLNEZl5Xf/++A4wAYDYQ== + dependencies: + "@emotion/sheet" "0.9.4" + "@emotion/stylis" "0.8.5" + "@emotion/utils" "0.11.3" + "@emotion/weak-memoize" "0.2.5" + +"@emotion/core@^10.0.22", "@emotion/core@^10.0.9": + version "10.0.28" + resolved "https://registry.yarnpkg.com/@emotion/core/-/core-10.0.28.tgz#bb65af7262a234593a9e952c041d0f1c9b9bef3d" + integrity sha512-pH8UueKYO5jgg0Iq+AmCLxBsvuGtvlmiDCOuv8fGNYn3cowFpLN98L8zO56U0H1PjDIyAlXymgL3Wu7u7v6hbA== + dependencies: + "@babel/runtime" "^7.5.5" + "@emotion/cache" "^10.0.27" + "@emotion/css" "^10.0.27" + "@emotion/serialize" "^0.11.15" + "@emotion/sheet" "0.9.4" + "@emotion/utils" "0.11.3" + +"@emotion/css@^10.0.27", "@emotion/css@^10.0.9": + version "10.0.27" + resolved "https://registry.yarnpkg.com/@emotion/css/-/css-10.0.27.tgz#3a7458198fbbebb53b01b2b87f64e5e21241e14c" + integrity sha512-6wZjsvYeBhyZQYNrGoR5yPMYbMBNEnanDrqmsqS1mzDm1cOTu12shvl2j4QHNS36UaTE0USIJawCH9C8oW34Zw== + dependencies: + "@emotion/serialize" "^0.11.15" + "@emotion/utils" "0.11.3" + babel-plugin-emotion "^10.0.27" + +"@emotion/hash@0.8.0": + version "0.8.0" + resolved "https://registry.yarnpkg.com/@emotion/hash/-/hash-0.8.0.tgz#bbbff68978fefdbe68ccb533bc8cbe1d1afb5413" + integrity sha512-kBJtf7PH6aWwZ6fka3zQ0p6SBYzx4fl1LoZXE2RrnYST9Xljm7WfKJrU4g/Xr3Beg72MLrp1AWNUmuYJTL7Cow== + "@emotion/is-prop-valid@^0.8.3", "@emotion/is-prop-valid@^0.8.6": version "0.8.8" resolved "https://registry.yarnpkg.com/@emotion/is-prop-valid/-/is-prop-valid-0.8.8.tgz#db28b1c4368a259b60a97311d6a952d4fd01ac1a" @@ -1010,16 +1173,42 @@ resolved "https://registry.yarnpkg.com/@emotion/memoize/-/memoize-0.7.4.tgz#19bf0f5af19149111c40d98bb0cf82119f5d9eeb" integrity sha512-Ja/Vfqe3HpuzRsG1oBtWTHk2PGZ7GR+2Vz5iYGelAw8dx32K0y7PjVuxK6z1nMpZOqAFsRUPCkK1YjJ56qJlgw== -"@emotion/stylis@^0.8.4": +"@emotion/serialize@^0.11.15", "@emotion/serialize@^0.11.16": + version "0.11.16" + resolved "https://registry.yarnpkg.com/@emotion/serialize/-/serialize-0.11.16.tgz#dee05f9e96ad2fb25a5206b6d759b2d1ed3379ad" + integrity sha512-G3J4o8by0VRrO+PFeSc3js2myYNOXVJ3Ya+RGVxnshRYgsvErfAOglKAiy1Eo1vhzxqtUvjCyS5gtewzkmvSSg== + dependencies: + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/unitless" "0.7.5" + "@emotion/utils" "0.11.3" + csstype "^2.5.7" + +"@emotion/sheet@0.9.4": + version "0.9.4" + resolved "https://registry.yarnpkg.com/@emotion/sheet/-/sheet-0.9.4.tgz#894374bea39ec30f489bbfc3438192b9774d32e5" + integrity sha512-zM9PFmgVSqBw4zL101Q0HrBVTGmpAxFZH/pYx/cjJT5advXguvcgjHFTCaIO3enL/xr89vK2bh0Mfyj9aa0ANA== + +"@emotion/stylis@0.8.5", "@emotion/stylis@^0.8.4": version "0.8.5" resolved "https://registry.yarnpkg.com/@emotion/stylis/-/stylis-0.8.5.tgz#deacb389bd6ee77d1e7fcaccce9e16c5c7e78e04" integrity sha512-h6KtPihKFn3T9fuIrwvXXUOwlx3rfUvfZIcP5a6rh8Y7zjE3O06hT5Ss4S/YI1AYhuZ1kjaE/5EaOOI2NqSylQ== -"@emotion/unitless@^0.7.4": +"@emotion/unitless@0.7.5", "@emotion/unitless@^0.7.4": version "0.7.5" resolved "https://registry.yarnpkg.com/@emotion/unitless/-/unitless-0.7.5.tgz#77211291c1900a700b8a78cfafda3160d76949ed" integrity sha512-OWORNpfjMsSSUBVrRBVGECkhWcULOAJz9ZW8uK9qgxD+87M7jHRcvh/A96XXNhXTLmKcoYSQtBEX7lHMO7YRwg== +"@emotion/utils@0.11.3": + version "0.11.3" + resolved "https://registry.yarnpkg.com/@emotion/utils/-/utils-0.11.3.tgz#a759863867befa7e583400d322652a3f44820924" + integrity sha512-0o4l6pZC+hI88+bzuaX/6BgOvQVhbt2PfmxauVaYOGgbsAw14wdKyvMCZXnsnsHys94iadcF+RG/wZyx6+ZZBw== + +"@emotion/weak-memoize@0.2.5": + version "0.2.5" + resolved "https://registry.yarnpkg.com/@emotion/weak-memoize/-/weak-memoize-0.2.5.tgz#8eed982e2ee6f7f4e44c253e12962980791efd46" + integrity sha512-6U71C2Wp7r5XtFtQzYrW5iKFT67OixrSxjI4MptCHzdSVlgabczzqLe0ZSgnub/5Kp4hSbpDB1tMytZY9pwxxA== + "@iarna/cli@^1.2.0": version "1.2.0" resolved "https://registry.yarnpkg.com/@iarna/cli/-/cli-1.2.0.tgz#0f7af5e851afe895104583c4ca07377a8094d641" @@ -1261,24 +1450,10 @@ "@opentripplanner/core-utils" "^2.1.0" prop-types "^15.7.2" -"@opentripplanner/core-utils@^1.2.0", "@opentripplanner/core-utils@^1.2.1": - version "1.2.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-1.2.1.tgz#e21f1c6825a0922bd0fe1326fb5a7bbdac2db7f6" - integrity sha512-RHSPrGyu/sV9krVSTsuW1R8fTqj+l+CeHCTK8XLj5cYC4HbqkKLtnOXXwvWGGh21Cpt+jkVBiPcYtfluIX1qMQ== - dependencies: - "@mapbox/polyline" "^1.1.0" - "@turf/along" "^6.0.1" - bowser "^2.7.0" - lodash.isequal "^4.5.0" - moment "^2.24.0" - moment-timezone "^0.5.27" - prop-types "^15.7.2" - qs "^6.9.1" - -"@opentripplanner/core-utils@^2.1.0": - version "2.1.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-2.1.0.tgz#ab7271a2b560168b21b0dd26c78532f24fd031f5" - integrity sha512-sQ3oiZB7f01kCVuTj5SzqsPe4uchupNbla+onLWH+aO3wH+OLZNuLRZZ/7oFFFnvpcFBakyg4TePPxyyEyJlMA== +"@opentripplanner/core-utils@^1.2.0": + version "1.2.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-1.2.2.tgz#c943983d92c67b1aba2ad7b47f199fb46bbedc02" + integrity sha512-xISq454TA/mTu5wjMVvNRszHmeAKppS+jk5E3LRl+TaMWas5ovaNdKwlOXU62djGb41VOty4KYTnECliDPYDJw== dependencies: "@mapbox/polyline" "^1.1.0" "@turf/along" "^6.0.1" @@ -1289,7 +1464,7 @@ prop-types "^15.7.2" qs "^6.9.1" -"@opentripplanner/core-utils@^2.1.1": +"@opentripplanner/core-utils@^2.1.0", "@opentripplanner/core-utils@^2.1.1", "@opentripplanner/core-utils@^2.1.2": version "2.1.2" resolved "https://registry.yarnpkg.com/@opentripplanner/core-utils/-/core-utils-2.1.2.tgz#a19d5d788704f0a6c2aece5206a2c8997c251d16" integrity sha512-i+ADDdHhC+oJNYPrk7o9eu3F/2IMMZ5YAOXR2QGBJbS97kQOYeTAN4pVGfWKTm7ClTTIBG9/NDnVyQMzGuYInw== @@ -1303,13 +1478,13 @@ prop-types "^15.7.2" qs "^6.9.1" -"@opentripplanner/endpoints-overlay@^1.0.1": - version "1.0.1" - resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-1.0.1.tgz#d95f0bbfddc9382b593845799b963340eece2742" - integrity sha512-FMr8qwB4wDm/N1wWCu89TsPIBPWMepyuC7ZYb4zCrWYgi3/hZtuSUlFmqmg9497KM2jyqqq/41oSiVsG35a2pA== +"@opentripplanner/endpoints-overlay@^1.0.2": + version "1.0.2" + resolved "https://registry.yarnpkg.com/@opentripplanner/endpoints-overlay/-/endpoints-overlay-1.0.2.tgz#165817533832399c8e8c276fba2ec4fafe038853" + integrity sha512-ccwvaRYmkzz4VKlM52jVXklSAwu+5UfLiTB8q6lTN/sP3gdPPCWJMUVu4u00R9xNFPVVk6NOB/y6A3NUJzBVlA== dependencies: "@opentripplanner/core-utils" "^1.2.0" - "@opentripplanner/location-icon" "^1.0.0" + "@opentripplanner/location-icon" "^1.0.1" prop-types "^15.7.2" styled-icons "^9.1.0" @@ -1373,10 +1548,10 @@ styled-icons "^9.1.0" throttle-debounce "^2.1.0" -"@opentripplanner/location-icon@^1.0.0": - version "1.0.0" - resolved "https://registry.yarnpkg.com/@opentripplanner/location-icon/-/location-icon-1.0.0.tgz#7bdf55e486d9b2bb7519992d01da6677ab6d0f7c" - integrity sha512-fOTofupCyMUiqEF5lWQH6K/cMqt1lD1UCFWgP6pG7PFk8pUJ8idr8N9ml0lVT6tLJ2x/uVXPXi4VwZRST1XRKQ== +"@opentripplanner/location-icon@^1.0.0", "@opentripplanner/location-icon@^1.0.1": + version "1.0.1" + resolved "https://registry.yarnpkg.com/@opentripplanner/location-icon/-/location-icon-1.0.1.tgz#5a72f697eeebfb21202bfc205ca0da7c32dfe1d0" + integrity sha512-esHrqZBKxJNNPiZyb4XtrWYZhdVrUHcpAr4eCydf8pSDRUX9QVM/YqAPPn2SEwJiH2hi14CYLMMV5SjEHwwJMg== dependencies: styled-icons "^9.1.0" @@ -1810,6 +1985,11 @@ dependencies: "@babel/types" "^7.3.0" +"@types/color-name@^1.1.1": + version "1.1.1" + resolved "https://registry.yarnpkg.com/@types/color-name/-/color-name-1.1.1.tgz#1c1261bbeaa10a8055bbc5d8ab84b7b2afc846a0" + integrity sha512-rr+OQyAjxze7GgWrSaJwydHStIhHq2lvY3BOC2Mj7KnzI7XK0Uw1TOOdI9lDoajEbSWLiYgoo4f1R51erQfhPQ== + "@types/eslint-visitor-keys@^1.0.0": version "1.0.0" resolved "https://registry.yarnpkg.com/@types/eslint-visitor-keys/-/eslint-visitor-keys-1.0.0.tgz#1ee30d79544ca84d68d4b3cdb0af4f205663dd2d" @@ -1874,6 +2054,11 @@ resolved "https://registry.yarnpkg.com/@types/normalize-package-data/-/normalize-package-data-2.4.0.tgz#e486d0d97396d79beedd0a6e33f4534ff6b4973e" integrity sha512-f5j5b/Gf71L+dbqxIpQ4Z2WlmI/mPJ0fOkGGmFgtb6sAu97EPczzbS3/tJKxmcYDj55OX6ssqwDAWOHIYDRDGA== +"@types/parse-json@^4.0.0": + version "4.0.0" + resolved "https://registry.yarnpkg.com/@types/parse-json/-/parse-json-4.0.0.tgz#2f8bb441434d163b35fb8ffdccd7138927ffb8c0" + integrity sha512-//oorEZjL6sbPcKUaCdIGlIUeH26mgzimjBB77G6XRgnDl/L5wOnpyBGRe/Mmf5CVW3PwEBE1NjiMZ/ssFh4wA== + "@types/q@^1.5.1": version "1.5.2" resolved "https://registry.yarnpkg.com/@types/q/-/q-1.5.2.tgz#690a1475b84f2a884fd07cd797c00f5f31356ea8" @@ -2140,6 +2325,11 @@ ansi-regex@^4.0.0, ansi-regex@^4.1.0: resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-4.1.0.tgz#8b9f8f08cf1acb843756a839ca8c7e3168c51997" integrity sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg== +ansi-regex@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.0.tgz#388539f55179bf39339c81af30a654d69f87cb75" + integrity sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg== + ansi-styles@2.0.1: version "2.0.1" resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.0.1.tgz#b033f57f93e2d28adeb8bc11138fa13da0fd20a3" @@ -2162,6 +2352,14 @@ ansi-styles@^3.2.0, ansi-styles@^3.2.1: dependencies: color-convert "^1.9.0" +ansi-styles@^4.0.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-4.2.1.tgz#90ae75c424d008d2624c5bf29ead3177ebfcf359" + integrity sha512-9VGjrMsG1vePxcSweQsN20KY/c4zN0h9fLjqAbwbPfahM3t+NL+M9HC8xeXG2I8pX5NoamTGNuomEUFI7fcUjA== + dependencies: + "@types/color-name" "^1.1.1" + color-convert "^2.0.1" + ansicolors@~0.3.2: version "0.3.2" resolved "https://registry.yarnpkg.com/ansicolors/-/ansicolors-0.3.2.tgz#665597de86a9ffe3aa9bfbe6cae5c6ea426b4979" @@ -2188,6 +2386,14 @@ anymatch@^2.0.0: micromatch "^3.1.4" normalize-path "^2.1.1" +anymatch@~3.1.1: + version "3.1.1" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-3.1.1.tgz#c55ecf02185e2469259399310c173ce31233b142" + integrity sha512-mM8522psRCqzV+6LhomX5wgp25YVibjh8Wj23I5RPkPppSVSjyKD2A2mBJmWGa+KN7f2D6LNh9jkBCeyLktzjg== + dependencies: + normalize-path "^3.0.0" + picomatch "^2.0.4" + append-buffer@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/append-buffer/-/append-buffer-1.0.2.tgz#d8220cf466081525efea50614f3de6514dfa58f1" @@ -2778,13 +2984,29 @@ babel-plugin-check-es2015-constants@^6.22.0: dependencies: babel-runtime "^6.22.0" -babel-plugin-dynamic-import-node@^2.3.0: - version "2.3.0" - resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.0.tgz#f00f507bdaa3c3e3ff6e7e5e98d90a7acab96f7f" - integrity sha512-o6qFkpeQEBxcqt0XYlWzAVxNCSCZdUgcR8IRlhD/8DylxjjO4foPcvTW0GGKa/cVt3rvxZ7o5ippJ+/0nvLhlQ== +babel-plugin-dynamic-import-node@^2.3.0, babel-plugin-dynamic-import-node@^2.3.3: + version "2.3.3" + resolved "https://registry.yarnpkg.com/babel-plugin-dynamic-import-node/-/babel-plugin-dynamic-import-node-2.3.3.tgz#84fda19c976ec5c6defef57f9427b3def66e17a3" + integrity sha512-jZVI+s9Zg3IqA/kdi0i6UDCybUI3aSBLnglhYbSSjKlV7yF1F/5LWv8MakQmvYpnbJDS6fcBL2KzHSxNCMtWSQ== dependencies: object.assign "^4.1.0" +babel-plugin-emotion@^10.0.27: + version "10.0.33" + resolved "https://registry.yarnpkg.com/babel-plugin-emotion/-/babel-plugin-emotion-10.0.33.tgz#ce1155dcd1783bbb9286051efee53f4e2be63e03" + integrity sha512-bxZbTTGz0AJQDHm8k6Rf3RQJ8tX2scsfsRyKVgAbiUPUNIRtlK+7JxP+TAd1kRLABFxe0CFm2VdK4ePkoA9FxQ== + dependencies: + "@babel/helper-module-imports" "^7.0.0" + "@emotion/hash" "0.8.0" + "@emotion/memoize" "0.7.4" + "@emotion/serialize" "^0.11.16" + babel-plugin-macros "^2.0.0" + babel-plugin-syntax-jsx "^6.18.0" + convert-source-map "^1.5.0" + escape-string-regexp "^1.0.5" + find-root "^1.1.0" + source-map "^0.5.7" + babel-plugin-istanbul@^5.1.0: version "5.2.0" resolved "https://registry.yarnpkg.com/babel-plugin-istanbul/-/babel-plugin-istanbul-5.2.0.tgz#df4ade83d897a92df069c4d9a25cf2671293c854" @@ -2813,6 +3035,15 @@ babel-plugin-lodash@^3.3.4: lodash "^4.17.10" require-package-name "^2.0.1" +babel-plugin-macros@^2.0.0: + version "2.8.0" + resolved "https://registry.yarnpkg.com/babel-plugin-macros/-/babel-plugin-macros-2.8.0.tgz#0f958a7cc6556b1e65344465d99111a1e5e10138" + integrity sha512-SEP5kJpfGYqYKpBrj5XU3ahw5p5GOHJ0U5ssOSQ/WBVdwkD2Dzlce95exQTs3jOVWPPKLBN2rlEWkCK7dSmLvg== + dependencies: + "@babel/runtime" "^7.7.2" + cosmiconfig "^6.0.0" + resolve "^1.12.0" + babel-plugin-react-require@^3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/babel-plugin-react-require/-/babel-plugin-react-require-3.1.1.tgz#5c3d2564fa16b1e45212ed52519db147b1596106" @@ -3428,6 +3659,11 @@ binary-extensions@^1.0.0: resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.13.1.tgz#598afe54755b2868a5330d2aff9d4ebb53209b65" integrity sha512-Un7MIEDdUC5gNpcGDV97op1Ywk748MpHcFTHoYs6qnj1Z3j7I53VG3nwZhKzoBZmbdRNnb6WRdFlwl7tSDuZGw== +binary-extensions@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-2.1.0.tgz#30fa40c9e7fe07dbc895678cd287024dea241dd9" + integrity sha512-1Yj8h9Q+QDF5FzhMs/c9+6UntbD5MkRfRwac8DoEm9ZfUBZ7tZ55YcGVAzEe4bXsdQHEk+s9S5wsOKVdZrw0tQ== + bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5: version "3.7.2" resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-3.7.2.tgz#9f229c15be272454ffa973ace0dbee79a1b0c36f" @@ -3533,7 +3769,7 @@ braces@^2.3.1, braces@^2.3.2: split-string "^3.0.2" to-regex "^3.0.1" -braces@^3.0.1: +braces@^3.0.1, braces@~3.0.2: version "3.0.2" resolved "https://registry.yarnpkg.com/braces/-/braces-3.0.2.tgz#3454e1a462ee8d599e236df336cd9ea4f8afe107" integrity sha512-b8um+L1RzM3WDSzvhm6gIz1yfTbBt6YTlcEKAvsmqCZZFw46z626lVj9j1yEPW33H5H+lBQpZMP1k8l+78Ha0A== @@ -3706,14 +3942,15 @@ browserslist@^1.3.6, browserslist@^1.5.2, browserslist@^1.7.6: caniuse-db "^1.0.30000639" electron-to-chromium "^1.2.7" -browserslist@^4.0.0, browserslist@^4.6.0, browserslist@^4.6.2, browserslist@^4.6.3, browserslist@^4.6.4: - version "4.6.6" - resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.6.6.tgz#6e4bf467cde520bc9dbdf3747dafa03531cec453" - integrity sha512-D2Nk3W9JL9Fp/gIcWei8LrERCS+eXu9AM5cfXA8WEZ84lFks+ARnZ0q/R69m2SV3Wjma83QDDPxsNKXUwdIsyA== +browserslist@^4.0.0, browserslist@^4.12.0, browserslist@^4.6.0, browserslist@^4.6.2, browserslist@^4.6.3, browserslist@^4.6.4, browserslist@^4.8.5: + version "4.14.4" + resolved "https://registry.yarnpkg.com/browserslist/-/browserslist-4.14.4.tgz#66a18131439f9e16c3da7f352518dfa12f60b0e3" + integrity sha512-7FOuawafVdEwa5Jv4nzeik/PepAjVte6HmVGHsjt2bC237jeL9QlcTBDF3PnHEvcC6uHwLGYPwZHNZMB7wWAnw== dependencies: - caniuse-lite "^1.0.30000984" - electron-to-chromium "^1.3.191" - node-releases "^1.1.25" + caniuse-lite "^1.0.30001135" + electron-to-chromium "^1.3.570" + escalade "^3.1.0" + node-releases "^1.1.61" bser@^2.0.0: version "2.1.0" @@ -3968,10 +4205,10 @@ caniuse-db@^1.0.30000529, caniuse-db@^1.0.30000634, caniuse-db@^1.0.30000639: resolved "https://registry.yarnpkg.com/caniuse-db/-/caniuse-db-1.0.30000986.tgz#0439a4052bbd3243fa01c9998601b9226e7ea6b7" integrity sha512-8SKJ12AFwG0ReMjPwRH+keFsX/ucw2bi6LC7upeXBvxjgrMqHaTxgYhkRGm+eOwUWvVcqXDgqM7QNlRJMhvXZg== -caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000941, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000984: - version "1.0.30000986" - resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30000986.tgz#f34350e367cc900509511574817ac092112bf7ab" - integrity sha512-pM+LnkoAX0+QnIH3tpW5EnkmfpEoqOD8FAcoBvsl3Xh6DXkgctiCxeCbXphP/k3XJtJzm+zOAJbi6U6IVkpWZQ== +caniuse-lite@^1.0.0, caniuse-lite@^1.0.30000941, caniuse-lite@^1.0.30000980, caniuse-lite@^1.0.30000981, caniuse-lite@^1.0.30000984, caniuse-lite@^1.0.30001135: + version "1.0.30001135" + resolved "https://registry.yarnpkg.com/caniuse-lite/-/caniuse-lite-1.0.30001135.tgz#995b1eb94404a3c9a0d7600c113c9bb27f2cd8aa" + integrity sha512-ziNcheTGTHlu9g34EVoHQdIu5g4foc8EsxMGC7Xkokmvw0dqNtX8BS8RgCgFBaAiSp2IdjvBxNdh0ssib28eVQ== capture-exit@^2.0.0: version "2.0.0" @@ -4136,6 +4373,21 @@ chokidar@^2.0.2, chokidar@^2.0.4, chokidar@^2.1.1, chokidar@^2.1.2: optionalDependencies: fsevents "^1.2.7" +chokidar@^3.4.0: + version "3.4.2" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-3.4.2.tgz#38dc8e658dec3809741eb3ef7bb0a47fe424232d" + integrity sha512-IZHaDeBeI+sZJRX7lGcXsdzgvZqKv6sECqsbErJA4mHWfpRrD8B97kSFN4cQz6nGBGiuFia1MKR4d6c1o8Cv7A== + dependencies: + anymatch "~3.1.1" + braces "~3.0.2" + glob-parent "~5.1.0" + is-binary-path "~2.1.0" + is-glob "~4.0.1" + normalize-path "~3.0.0" + readdirp "~3.4.0" + optionalDependencies: + fsevents "~2.1.2" + chownr@^1.1.1, chownr@^1.1.2, chownr@^1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/chownr/-/chownr-1.1.4.tgz#6fc9d7b42d32a583596337666e7d08084da2cc6b" @@ -4271,6 +4523,15 @@ cliui@^5.0.0: strip-ansi "^5.2.0" wrap-ansi "^5.1.0" +cliui@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-6.0.0.tgz#511d702c0c4e41ca156d7d0e96021f23e13225b1" + integrity sha512-t6wbgtoCXvAzst7QgXxJYqPt0usEfbgQdftEPbLL/cvv6HPE5VgvqCuAIDR0NgU52ds6rFwqrgakNLrHEjCbrQ== + dependencies: + string-width "^4.2.0" + strip-ansi "^6.0.0" + wrap-ansi "^6.2.0" + clone-buffer@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/clone-buffer/-/clone-buffer-1.0.0.tgz#e3e25b207ac4e701af721e2cb5a16792cac3dc58" @@ -4354,12 +4615,19 @@ color-convert@^1.3.0, color-convert@^1.9.0, color-convert@^1.9.1: dependencies: color-name "1.1.3" +color-convert@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/color-convert/-/color-convert-2.0.1.tgz#72d3a68d598c9bdb3af2ad1e84f21d896abd4de3" + integrity sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ== + dependencies: + color-name "~1.1.4" + color-name@1.1.3: version "1.1.3" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.3.tgz#a7d0558bd89c42f795dd42328f740831ca53bc25" integrity sha1-p9BVi9icQveV3UIyj3QIMcpTvCU= -color-name@^1.0.0: +color-name@^1.0.0, color-name@~1.1.4: version "1.1.4" resolved "https://registry.yarnpkg.com/color-name/-/color-name-1.1.4.tgz#c2a09a87acbde69543de6f63fa3995c826c536a2" integrity sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA== @@ -4667,10 +4935,10 @@ conventional-commits-parser@^3.0.0: through2 "^2.0.0" trim-off-newlines "^1.0.0" -convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1: - version "1.6.0" - resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" - integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== +convert-source-map@^1.1.0, convert-source-map@^1.4.0, convert-source-map@^1.5.0, convert-source-map@^1.5.1, convert-source-map@^1.7.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" + integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== dependencies: safe-buffer "~5.1.1" @@ -4703,14 +4971,13 @@ copy-to-clipboard@^3.0.8: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.1.1: - version "3.1.4" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.1.4.tgz#e4d0c40fbd01e65b1d457980fe4112d4358a7408" - integrity sha512-Z5zbO9f1d0YrJdoaQhphVAnKPimX92D6z8lCGphH89MNRxlL1prI9ExJPqVwP0/kgkQCv8c4GJGT8X16yUncOg== +core-js-compat@^3.1.1, core-js-compat@^3.6.2: + version "3.6.5" + resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.6.5.tgz#2a51d9a4e25dfd6e690251aa81f99e3c05481f1c" + integrity sha512-7ItTKOhOZbznhXAQ2g/slGg1PJV5zDO/WdkTwi7UEOJmkvsE32PWvx6mKtDjiMpjnR2CNf6BAD6sSxIlv7ptng== dependencies: - browserslist "^4.6.2" - core-js-pure "3.1.4" - semver "^6.1.1" + browserslist "^4.8.5" + semver "7.0.0" core-js-pure@3.1.4: version "3.1.4" @@ -4747,6 +5014,17 @@ cosmiconfig@^5.0.0, cosmiconfig@^5.0.1: js-yaml "^3.13.1" parse-json "^4.0.0" +cosmiconfig@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/cosmiconfig/-/cosmiconfig-6.0.0.tgz#da4fee853c52f6b1e6935f41c1a2fc50bd4a9982" + integrity sha512-xb3ZL6+L8b9JLLCx3ZdoZy4+2ECphCMo2PwqgP1tlfVq6M6YReyzBJtvWWtbDSpNr9hn96pkCiZqUcFEc+54Qg== + dependencies: + "@types/parse-json" "^4.0.0" + import-fresh "^3.1.0" + parse-json "^5.0.0" + path-type "^4.0.0" + yaml "^1.7.2" + create-ecdh@^4.0.0: version "4.0.3" resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.3.tgz#c9111b6f33045c4697f144787f9254cdc77c45ff" @@ -5114,6 +5392,11 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" +csstype@^2.5.7, csstype@^2.6.7: + version "2.6.10" + resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.10.tgz#e63af50e66d7c266edb6b32909cfd0aabe03928b" + integrity sha512-D34BqZU4cIlMCY93rZHbrq9pjTAQJ3U8S8rfBqjwHxkGPThWFjzZDQpgMJY0QViLxth6ZKYiwFBo14RdN44U/w== + currency-formatter@^1.4.2, currency-formatter@^1.5.5: version "1.5.5" resolved "https://registry.yarnpkg.com/currency-formatter/-/currency-formatter-1.5.5.tgz#907790bb0b7f129c4a64d2924e0d7fa36db0cf52" @@ -5564,49 +5847,51 @@ doctrine@^3.0.0: dependencies: esutils "^2.0.2" -documentation@^12.0.3: - version "12.0.3" - resolved "https://registry.yarnpkg.com/documentation/-/documentation-12.0.3.tgz#32f91da8e5cb4104f69db9fd32c87773a1ad6240" - integrity sha512-RoqkH+mQ4Vi/nFMxG0BaqPAnjKfsJ9lbLWB8KqoKVAZy+urSpk1K1zBzaFesdDkKeaR3aBgeR3RjtHp8Ut/1Wg== - dependencies: - "@babel/core" "^7.1.2" - "@babel/generator" "^7.1.3" - "@babel/parser" "7.1.3" - "@babel/plugin-proposal-class-properties" "^7.1.0" - "@babel/plugin-proposal-decorators" "^7.1.2" - "@babel/plugin-proposal-do-expressions" "^7.0.0" - "@babel/plugin-proposal-export-default-from" "^7.0.0" - "@babel/plugin-proposal-export-namespace-from" "^7.0.0" - "@babel/plugin-proposal-function-bind" "^7.0.0" - "@babel/plugin-proposal-function-sent" "^7.1.0" - "@babel/plugin-proposal-json-strings" "^7.0.0" - "@babel/plugin-proposal-logical-assignment-operators" "^7.0.0" - "@babel/plugin-proposal-nullish-coalescing-operator" "^7.0.0" - "@babel/plugin-proposal-numeric-separator" "^7.0.0" - "@babel/plugin-proposal-optional-chaining" "^7.0.0" - "@babel/plugin-proposal-pipeline-operator" "^7.0.0" - "@babel/plugin-proposal-throw-expressions" "^7.0.0" - "@babel/plugin-syntax-dynamic-import" "^7.0.0" - "@babel/plugin-syntax-import-meta" "^7.0.0" - "@babel/preset-env" "^7.1.0" - "@babel/preset-flow" "^7.0.0" - "@babel/preset-react" "^7.0.0" - "@babel/preset-stage-0" "^7.0.0" - "@babel/traverse" "^7.1.4" - "@babel/types" "^7.1.3" +documentation@^13.0.2: + version "13.0.2" + resolved "https://registry.yarnpkg.com/documentation/-/documentation-13.0.2.tgz#fd1ec7a1daebfbd5b14a8dca8b9d36cba32f5b85" + integrity sha512-pupdwmk51DZyRFxhnadYfN8CxjH5g7L20sIyWkm0u+Zk3J2NByy4CmygVfhv22rm4gHrm69qiHI7SqQ6HuNbeQ== + dependencies: + "@babel/core" "^7.9.0" + "@babel/generator" "^7.9.4" + "@babel/parser" "7.10.2" + "@babel/plugin-proposal-class-properties" "^7.8.3" + "@babel/plugin-proposal-decorators" "^7.8.3" + "@babel/plugin-proposal-do-expressions" "^7.8.3" + "@babel/plugin-proposal-export-default-from" "^7.8.3" + "@babel/plugin-proposal-export-namespace-from" "^7.8.3" + "@babel/plugin-proposal-function-bind" "^7.8.3" + "@babel/plugin-proposal-function-sent" "^7.8.3" + "@babel/plugin-proposal-json-strings" "^7.8.3" + "@babel/plugin-proposal-logical-assignment-operators" "^7.8.3" + "@babel/plugin-proposal-nullish-coalescing-operator" "^7.8.3" + "@babel/plugin-proposal-numeric-separator" "^7.8.3" + "@babel/plugin-proposal-optional-chaining" "^7.9.0" + "@babel/plugin-proposal-pipeline-operator" "^7.8.3" + "@babel/plugin-proposal-private-methods" "^7.8.3" + "@babel/plugin-proposal-throw-expressions" "^7.8.3" + "@babel/plugin-syntax-dynamic-import" "^7.8.3" + "@babel/plugin-syntax-import-meta" "^7.8.3" + "@babel/preset-env" "^7.9.0" + "@babel/preset-flow" "^7.9.0" + "@babel/preset-react" "^7.9.4" + "@babel/preset-stage-0" "^7.8.3" + "@babel/traverse" "^7.9.0" + "@babel/types" "^7.9.0" ansi-html "^0.0.7" babelify "^10.0.0" chalk "^2.3.0" - chokidar "^2.0.4" + chokidar "^3.4.0" concat-stream "^1.6.0" diff "^4.0.1" doctrine-temporary-fork "2.1.0" - get-port "^4.0.0" - git-url-parse "^10.0.1" + get-port "^5.0.0" + git-url-parse "^11.1.2" github-slugger "1.2.0" glob "^7.1.2" globals-docs "^2.4.0" highlight.js "^9.15.5" + ini "^1.3.5" js-yaml "^3.10.0" lodash "^4.17.10" mdast-util-inject "^1.1.0" @@ -5614,13 +5899,12 @@ documentation@^12.0.3: mime "^2.2.0" module-deps-sortable "5.0.0" parse-filepath "^1.0.2" - pify "^4.0.0" + pify "^5.0.0" read-pkg-up "^4.0.0" remark "^9.0.0" remark-html "^8.0.0" remark-reference-links "^4.0.1" remark-toc "^5.0.0" - remote-origin-url "0.4.0" resolve "^1.8.1" stream-array "^1.1.2" strip-json-comments "^2.0.1" @@ -5633,7 +5917,7 @@ documentation@^12.0.3: vinyl "^2.1.0" vinyl-fs "^3.0.2" vue-template-compiler "^2.5.16" - yargs "^12.0.2" + yargs "^15.3.1" dom-helpers@^3.2.0, dom-helpers@^3.2.1, dom-helpers@^3.4.0: version "3.4.0" @@ -5642,6 +5926,14 @@ dom-helpers@^3.2.0, dom-helpers@^3.2.1, dom-helpers@^3.4.0: dependencies: "@babel/runtime" "^7.1.2" +dom-helpers@^5.0.1: + version "5.1.4" + resolved "https://registry.yarnpkg.com/dom-helpers/-/dom-helpers-5.1.4.tgz#4609680ab5c79a45f2531441f1949b79d6587f4b" + integrity sha512-TjMyeVUvNEnOnhzs6uAn9Ya47GmMo3qq7m+Lr/3ON0Rs5kHvb8I+SQYjLUSYn7qhEm0QjW0yrBkvz9yOrwwz1A== + dependencies: + "@babel/runtime" "^7.8.7" + csstype "^2.6.7" + dom-serializer@0, dom-serializer@~0.1.1: version "0.1.1" resolved "https://registry.yarnpkg.com/dom-serializer/-/dom-serializer-0.1.1.tgz#1ec4059e284babed36eec2941d4a970a189ce7c0" @@ -5749,10 +6041,10 @@ ee-first@1.1.1: resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" integrity sha1-WQxhFWsK4vTwJVcyoViyZrxWsh0= -electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.191: - version "1.3.204" - resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.204.tgz#1ea5c6d495bab77995aa135dbcbc1d383dd4e21e" - integrity sha512-T0eXE6hfbtpzRUaI7aHI/HYJ29Ndk84aVSborRAmXfWvBvz2EuB2OWYUxNcUX9d+jtqEIjgZjWMdoxS0hp5j1g== +electron-to-chromium@^1.2.7, electron-to-chromium@^1.3.191, electron-to-chromium@^1.3.570: + version "1.3.571" + resolved "https://registry.yarnpkg.com/electron-to-chromium/-/electron-to-chromium-1.3.571.tgz#e57977f1569f8326ae2a7905e26f3943536ba28f" + integrity sha512-UYEQ2Gtc50kqmyOmOVtj6Oqi38lm5yRJY3pLuWt6UIot0No1L09uu6Ja6/1XKwmz/p0eJFZTUZi+khd1PV1hHA== elliptic@^6.0.0: version "6.5.3" @@ -5987,6 +6279,11 @@ es6-promisify@^6.0.0: resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-6.0.1.tgz#6edaa45f3bd570ffe08febce66f7116be4b1cdb6" integrity sha512-J3ZkwbEnnO+fGAKrjVpeUAnZshAdfZvbhQpqfIH9kSAspReRC4nJnu8ewm55b4y9ElyeuhCTzJD0XiH8Tsbhlw== +escalade@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/escalade/-/escalade-3.1.0.tgz#e8e2d7c7a8b76f6ee64c2181d6b8151441602d4e" + integrity sha512-mAk+hPSO8fLDkhV7V0dXazH5pDc6MrjBTPyD3VeKzxnVFjH1MIxbCdqGZB9O8+EwWakZs3ZCbDS4IpRt79V1ig== + escape-html@^1.0.3, escape-html@~1.0.3: version "1.0.3" resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" @@ -6625,7 +6922,7 @@ find-npm-prefix@^1.0.2: resolved "https://registry.yarnpkg.com/find-npm-prefix/-/find-npm-prefix-1.0.2.tgz#8d8ce2c78b3b4b9e66c8acc6a37c231eb841cfdf" integrity sha512-KEftzJ+H90x6pcKtdXZEPsQse8/y/UnvzRKrOSQFprnrGaFuJ62fVkP34Iu2IYuMvyauCyoLTNkJZgrrGA2wkA== -find-root@1.1.0: +find-root@1.1.0, find-root@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/find-root/-/find-root-1.1.0.tgz#abcfc8ba76f708c42a97b3d685b7e9450bfb9ce4" integrity sha512-NKfW6bec6GfKc0SGx1e07QZY9PE99u0Bft/0rzSD5k3sO/vwkVUpDUKVm5Gpp5Ue3YfShPFTX2070tDs5kB9Ng== @@ -6867,6 +7164,11 @@ fsevents@^1.0.0, fsevents@^1.2.7: nan "^2.12.1" node-pre-gyp "^0.12.0" +fsevents@~2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-2.1.3.tgz#fb738703ae8d2f9fe900c33836ddebee8b97f23e" + integrity sha512-Auw9a4AxqWpa9GUfj370BMPzzyncfBABW8Mab7BGWBYDj4Isgq+cDKtx0i6u9jcX9pQDnswsaaOTgTmA5pEjuQ== + function-bind@^1.1.1: version "1.1.1" resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.1.tgz#a56899d3ea3c9bab874bb9773b7c5ede92f4895d" @@ -6927,6 +7229,11 @@ genfun@^5.0.0: resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" integrity sha512-KGDOARWVga7+rnB3z9Sd2Letx515owfk0hSxHGuqjANb1M+x2bGZGqHLiozPsYMdM2OubeMni/Hpwmjq6qIUhA== +gensync@^1.0.0-beta.1: + version "1.0.0-beta.1" + resolved "https://registry.yarnpkg.com/gensync/-/gensync-1.0.0-beta.1.tgz#58f4361ff987e5ff6e1e7a210827aa371eaac269" + integrity sha512-r8EC6NO1sngH/zdD9fiRDLdcgnbayXah+mLgManTaIZJqEC1MZstmnox8KpnI2/fxQwrp5OpCOYWLp4rBl4Jcg== + gentle-fs@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/gentle-fs/-/gentle-fs-2.3.1.tgz#11201bf66c18f930ddca72cf69460bdfa05727b1" @@ -6976,10 +7283,10 @@ get-func-name@^2.0.0: resolved "https://registry.yarnpkg.com/get-func-name/-/get-func-name-2.0.0.tgz#ead774abee72e20409433a066366023dd6887a41" integrity sha1-6td0q+5y4gQJQzoGY2YCPdaIekE= -get-port@^4.0.0: - version "4.2.0" - resolved "https://registry.yarnpkg.com/get-port/-/get-port-4.2.0.tgz#e37368b1e863b7629c43c5a323625f95cf24b119" - integrity sha512-/b3jarXkH8KJoOMQc3uVGHASwGLPq3gSFJ7tgJm2diza+bydJPTGOibin2steecKeOylE8oY2JERlVWkAJO6yw== +get-port@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/get-port/-/get-port-5.1.1.tgz#0469ed07563479de6efb986baf053dcd7d4e3193" + integrity sha512-g/Q1aTSDOxFpchXC4i8ZWvxA1lnPqx/JHqcpIw0/LX9T8x/GBbi6YnlN5nhaKIFkT8oFsscUKgDJYxfwfS6QsQ== get-ports@^1.0.2: version "1.0.3" @@ -7036,20 +7343,20 @@ git-log-parser@^1.2.0: through2 "~2.0.0" traverse "~0.6.6" -git-up@^2.0.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/git-up/-/git-up-2.1.0.tgz#2f14cfe78327e7c4a2b92fcac7bfc674fdfad40c" - integrity sha512-MJgwfcSd9qxgDyEYpRU/CDxNpUadrK80JHuEQDG4Urn0m7tpSOgCBrtiSIa9S9KH8Tbuo/TN8SSQmJBvsw1HkA== +git-up@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/git-up/-/git-up-4.0.2.tgz#10c3d731051b366dc19d3df454bfca3f77913a7c" + integrity sha512-kbuvus1dWQB2sSW4cbfTeGpCMd8ge9jx9RKnhXhuJ7tnvT+NIrTVfYZxjtflZddQYcmdOTlkAcjmx7bor+15AQ== dependencies: is-ssh "^1.3.0" - parse-url "^3.0.2" + parse-url "^5.0.0" -git-url-parse@^10.0.1: - version "10.1.0" - resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-10.1.0.tgz#a27813218f8777e91d15f1c121b83bf14721b67e" - integrity sha512-goZOORAtFjU1iG+4zZgWq+N7It09PqS3Xsy43ZwhP5unDD0tTSmXTpqULHodMdJXGejm3COwXIhIRT6Z8DYVZQ== +git-url-parse@^11.1.2: + version "11.2.0" + resolved "https://registry.yarnpkg.com/git-url-parse/-/git-url-parse-11.2.0.tgz#2955fd51befd6d96ea1389bbe2ef57e8e6042b04" + integrity sha512-KPoHZg8v+plarZvto4ruIzzJLFQoRx+sUs5DQSr07By9IBKguVd+e6jwrFR6/TP6xrCJlNV1tPqLO1aREc7O2g== dependencies: - git-up "^2.0.0" + git-up "^4.0.0" github-slugger@1.2.0: version "1.2.0" @@ -7088,10 +7395,10 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0: - version "5.0.0" - resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.0.0.tgz#1dc99f0f39b006d3e92c2c284068382f0c20e954" - integrity sha512-Z2RwiujPRGluePM6j699ktJYxmPpJKCfpGA13jz2hmFZC7gKetzrWvg5KN3+OsIFmydGyZ1AVwERCq1w/ZZwRg== +glob-parent@^5.0.0, glob-parent@~5.1.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.1.tgz#b6c1ef417c4e5663ea498f1c45afac6916bbc229" + integrity sha512-FnI+VGOpnlGHWZxthPGR+QhR78fuiK0sNLkHQv+bL9fQi57lNNdquIbna/WrfROrolq8GK5Ek6BiMwqL/voRYQ== dependencies: is-glob "^4.0.1" @@ -7629,10 +7936,10 @@ import-fresh@^2.0.0: caller-path "^2.0.0" resolve-from "^3.0.0" -import-fresh@^3.0.0: - version "3.1.0" - resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.1.0.tgz#6d33fa1dcef6df930fae003446f33415af905118" - integrity sha512-PpuksHKGt8rXfWEr9m9EHIpgyyaltBy8+eF6GJM0QCAxMgxCfucMF3mjecK2QsJr0amJW7gTqh5/wht0z2UhEQ== +import-fresh@^3.0.0, import-fresh@^3.1.0: + version "3.2.1" + resolved "https://registry.yarnpkg.com/import-fresh/-/import-fresh-3.2.1.tgz#633ff618506e793af5ac91bf48b72677e15cbe66" + integrity sha512-6e1q1cnWP2RXD9/keSkxHScg508CdXqXWgWBaETNhyuBFz+kUZlKboh+ISK+bU++DmbHimVBrOz/zzPe0sZ3sQ== dependencies: parent-module "^1.0.0" resolve-from "^4.0.0" @@ -7710,7 +8017,7 @@ inherits@2.0.3: resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4= -ini@^1.3.3, ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: +ini@^1.3.4, ini@^1.3.5, ini@~1.3.0: version "1.3.5" resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.5.tgz#eee25f56db1c9ec6085e0c22778083f596abf927" integrity sha512-RZY5huIKCMRWDUqZlEi72f/lmXKMvuszcMBduliQ3nnWbx9X/ZBQO7DijMEYS9EhHBb2qacRUMtC7svLwe0lcw== @@ -7912,6 +8219,13 @@ is-binary-path@^1.0.0: dependencies: binary-extensions "^1.0.0" +is-binary-path@~2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-2.1.0.tgz#ea1f7f3b80f064236e83470f86c09c254fb45b09" + integrity sha512-ZMERYes6pDydyuGidse7OsHxtbI7WVeUEozgR/g7rd0xUimYNlvZRE/K2MgZTjWy725IfelLeVcEM97mmtRGXw== + dependencies: + binary-extensions "^2.0.0" + is-boolean-object@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/is-boolean-object/-/is-boolean-object-1.0.0.tgz#98f8b28030684219a95f375cfbd88ce3405dff93" @@ -8089,7 +8403,7 @@ is-glob@^3.1.0: dependencies: is-extglob "^2.1.0" -is-glob@^4.0.0, is-glob@^4.0.1: +is-glob@^4.0.0, is-glob@^4.0.1, is-glob@~4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-4.0.1.tgz#7567dbe9f2f5e2467bc77ab83c4a29482407a5dc" integrity sha512-5G0tKtBTFImOqDnLB2hG6Bp2qcKEFduo4tZu9MT/H6NQv/ghhy30o55ufafxJ/LdH79LLs2Kfrn85TLKyA7BUg== @@ -8944,12 +9258,12 @@ json5@^1.0.1: dependencies: minimist "^1.2.0" -json5@^2.1.0: - version "2.1.0" - resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.0.tgz#e7a0c62c48285c628d20a10b85c89bb807c32850" - integrity sha512-8Mh9h6xViijj36g7Dxi+Y4S6hNGV96vcJZr/SrlHh1LR/pEn/8j/+qIBbs44YKl69Lrfctp4QD+AdWLTMqEZAQ== +json5@^2.1.0, json5@^2.1.2: + version "2.1.3" + resolved "https://registry.yarnpkg.com/json5/-/json5-2.1.3.tgz#c9b0f7fa9233bfe5807fe66fcf3a5617ed597d43" + integrity sha512-KXPvOm8K9IJKFM0bmdn8QXh7udDh1g/giieX0NLCaMnb4hEiVFqnop2ImTXCc5e0/oHz3LTqmHGtExn5hfMkOA== dependencies: - minimist "^1.2.0" + minimist "^1.2.5" jsonfile@^4.0.0: version "4.0.0" @@ -9092,6 +9406,18 @@ leven@^2.1.0: resolved "https://registry.yarnpkg.com/leven/-/leven-2.1.0.tgz#c2e7a9f772094dee9d34202ae8acce4687875580" integrity sha1-wuep93IJTe6dNCAq6KzORoeHVYA= +leven@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/leven/-/leven-3.1.0.tgz#77891de834064cccba82ae7842bb6b14a13ed7f2" + integrity sha512-qsda+H8jTaUaN/x5vzW2rzc+8Rw4TAQ/4KjB46IwK5VH+IlVeeeje/EoZRpiXvIqjFgK84QffqPztGI3VBLG1A== + +levenary@^1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/levenary/-/levenary-1.1.1.tgz#842a9ee98d2075aa7faeedbe32679e9205f46f77" + integrity sha512-mkAdOIt79FD6irqjYSs4rdbnlT5vRonMEvBVPVb3XmevfS8kgRXwfes0dhPdEtzTWD/1eNE/Bm/G1iRt6DcnQQ== + dependencies: + leven "^3.1.0" + levn@^0.3.0, levn@~0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" @@ -9560,10 +9886,10 @@ lodash@4.17.14: resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.14.tgz#9ce487ae66c96254fe20b599f21b6816028078ba" integrity sha512-mmKYbW3GLuJeX+iGP+Y7Gp1AiGHGbXHCOh/jZmrawMmsE7MS4znI3RL2FsjbqOyMayHInjOeykW7PEajUk1/xw== -lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1: - version "4.17.19" - resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.19.tgz#e48ddedbe30b3321783c5b4301fbd353bc1e4a4b" - integrity sha512-JNvd8XER9GQX0v2qJgsaN/mzFCNA5BRe/j8JN9d+tWyGLSodKQHKFicdwNYzWwI3wjRnaKPsGj1XkBjx/F96DQ== +lodash@^4.13.1, lodash@^4.15.0, lodash@^4.17.10, lodash@^4.17.11, lodash@^4.17.12, lodash@^4.17.13, lodash@^4.17.14, lodash@^4.17.15, lodash@^4.17.19, lodash@^4.17.4, lodash@^4.17.5, lodash@^4.2.1: + version "4.17.20" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.20.tgz#b44a9b6297bcb698f1c51a3545a2b3b368d59c52" + integrity sha512-PlhdFcillOINfeV7Ni6oF1TAEayyZBoZ8bcshTHqOYJYlrqzRK5hagpagky5o4HfCzzd1TRkXPMFq6cKk9rGmA== log-symbols@^2.2.0: version "2.2.0" @@ -9970,6 +10296,11 @@ mem@^4.0.0: mimic-fn "^2.0.0" p-is-promise "^2.0.0" +memoize-one@^5.0.0: + version "5.1.1" + resolved "https://registry.yarnpkg.com/memoize-one/-/memoize-one-5.1.1.tgz#047b6e3199b508eaec03504de71229b8eb1d75c0" + integrity sha512-HKeeBpWvqiVJD57ZUAsJNm71eHTykffzcLZVYWiVfQeI1rJtuEaS7hQiEpWfVVk18donPwJEcFKIkCmPJNOhHA== + memory-fs@^0.4.0, memory-fs@~0.4.1: version "0.4.1" resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" @@ -10555,12 +10886,10 @@ node-pre-gyp@^0.12.0: semver "^5.3.0" tar "^4" -node-releases@^1.1.25: - version "1.1.26" - resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.26.tgz#f30563edc5c7dc20cf524cc8652ffa7be0762937" - integrity sha512-fZPsuhhUHMTlfkhDLGtfY80DSJTjOcx+qD1j5pqPkuhUHVS7xHZIg9EE4DHK8O3f0zTxXHX5VIkDG8pu98/wfQ== - dependencies: - semver "^5.3.0" +node-releases@^1.1.25, node-releases@^1.1.61: + version "1.1.61" + resolved "https://registry.yarnpkg.com/node-releases/-/node-releases-1.1.61.tgz#707b0fca9ce4e11783612ba4a2fcba09047af16e" + integrity sha512-DD5vebQLg8jLCOzwupn954fbIiZht05DAZs0k2u8NStSe6h9XdsuIQL8hSRKYiU8WUQRznmSDrKGbv3ObOmC7g== nopt@^4.0.1, nopt@^4.0.3: version "4.0.3" @@ -10587,7 +10916,7 @@ normalize-path@^2.0.0, normalize-path@^2.0.1, normalize-path@^2.1.1: dependencies: remove-trailing-separator "^1.0.1" -normalize-path@^3.0.0: +normalize-path@^3.0.0, normalize-path@~3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-3.0.0.tgz#0dcd69ff23a1c9b11fd0978316644a0388216a65" integrity sha512-6eZs5Ls3WtCisHWp9S2GUy8dqkpGi4BVSz3GaqiE6ezub0512ESztXUwUB6C6IKbQkY2Pnb/mD4WYojCRwcwLA== @@ -10597,7 +10926,7 @@ normalize-range@^0.1.2: resolved "https://registry.yarnpkg.com/normalize-range/-/normalize-range-0.1.2.tgz#2d10c06bdfd312ea9777695a4d28439456b75942" integrity sha1-LRDAa9/TEuqXd2laTShDlFa3WUI= -normalize-url@^1.4.0, normalize-url@^1.9.1: +normalize-url@^1.4.0: version "1.9.1" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-1.9.1.tgz#2cc0d66b31ea23036458436e3620d85954c66c3c" integrity sha1-LMDWazHqIwNkWENuNiDYWVTGbDw= @@ -10607,7 +10936,7 @@ normalize-url@^1.4.0, normalize-url@^1.9.1: query-string "^4.1.0" sort-keys "^1.0.0" -normalize-url@^3.0.0: +normalize-url@^3.0.0, normalize-url@^3.3.0: version "3.3.0" resolved "https://registry.yarnpkg.com/normalize-url/-/normalize-url-3.3.0.tgz#b2e1c4dc4f7c6d57743df733a4f5978d18650559" integrity sha512-U+JJi7duF1o+u2pynbp2zXDW2/PADgC30f0GsHZtRh+HOcXHnw137TrNlyxxRvWW5fjKd3bcLHPxofWuCjaeZg== @@ -11376,13 +11705,6 @@ parse-filepath@^1.0.2: map-cache "^0.2.0" path-root "^0.1.1" -parse-git-config@^0.2.0: - version "0.2.0" - resolved "https://registry.yarnpkg.com/parse-git-config/-/parse-git-config-0.2.0.tgz#272833fdd15fea146fb75d336d236b963b6ff706" - integrity sha1-Jygz/dFf6hRvt10zbSNrljtv9wY= - dependencies: - ini "^1.3.3" - parse-github-url@^1.0.1: version "1.0.2" resolved "https://registry.yarnpkg.com/parse-github-url/-/parse-github-url-1.0.2.tgz#242d3b65cbcdda14bb50439e3242acf6971db395" @@ -11433,22 +11755,22 @@ parse-passwd@^1.0.0: resolved "https://registry.yarnpkg.com/parse-passwd/-/parse-passwd-1.0.0.tgz#6d5b934a456993b23d37f40a382d6f1666a8e5c6" integrity sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY= -parse-path@^3.0.1: - version "3.0.4" - resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-3.0.4.tgz#a48b7b529da41f34d9d1428602a39b29fc7180e4" - integrity sha512-wP70vtwv2DyrM2YoA7ZHVv4zIXa4P7dGgHlj+VwyXNDduLLVJ7NMY1zsFxjUUJ3DAwJLupGb1H5gMDDiNlJaxw== +parse-path@^4.0.0: + version "4.0.2" + resolved "https://registry.yarnpkg.com/parse-path/-/parse-path-4.0.2.tgz#ef14f0d3d77bae8dd4bc66563a4c151aac9e65aa" + integrity sha512-HSqVz6iuXSiL8C1ku5Gl1Z5cwDd9Wo0q8CoffdAghP6bz8pJa1tcMC+m4N+z6VAS8QdksnIGq1TB6EgR4vPR6w== dependencies: is-ssh "^1.3.0" protocols "^1.4.0" -parse-url@^3.0.2: - version "3.0.2" - resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-3.0.2.tgz#602787a7063a795d72b8673197505e72f60610be" - integrity sha1-YCeHpwY6eV1yuGcxl1BecvYGEL4= +parse-url@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/parse-url/-/parse-url-5.0.2.tgz#856a3be1fcdf78dc93fc8b3791f169072d898b59" + integrity sha512-Czj+GIit4cdWtxo3ISZCvLiUjErSo0iI3wJ+q9Oi3QuMYTI6OZu+7cewMWZ+C1YAnKhYTk6/TLuhIgCypLthPA== dependencies: is-ssh "^1.3.0" - normalize-url "^1.9.1" - parse-path "^3.0.1" + normalize-url "^3.3.0" + parse-path "^4.0.0" protocols "^1.4.0" parse5@4.0.0: @@ -11603,10 +11925,10 @@ performance-now@^2.1.0: resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b" integrity sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns= -picomatch@^2.0.5: - version "2.0.7" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.0.7.tgz#514169d8c7cd0bdbeecc8a2609e34a7163de69f6" - integrity sha512-oLHIdio3tZ0qH76NybpeneBhYVj0QFTfXEFTc/B3zKQspYfYYkWYgFsmzo+4kvId/bQRcNkVeguI3y+CD22BtA== +picomatch@^2.0.4, picomatch@^2.0.5, picomatch@^2.2.1: + version "2.2.2" + resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.2.2.tgz#21f333e9b6b8eaff02468f5146ea406d345f4dad" + integrity sha512-q0M/9eZHzmr0AulXyPwNfZjtwZ/RBZlbN3K3CErVrk50T2ASYI7Bye0EvekFY3IP1Nt2DHu0re+V2ZHIpMkuWg== pify@^2.0.0, pify@^2.3.0: version "2.3.0" @@ -11618,11 +11940,16 @@ pify@^3.0.0: resolved "https://registry.yarnpkg.com/pify/-/pify-3.0.0.tgz#e5a4acd2c101fdf3d9a4d07f0dbc4db49dd28176" integrity sha1-5aSs0sEB/fPZpNB/DbxNtJ3SgXY= -pify@^4.0.0, pify@^4.0.1: +pify@^4.0.1: version "4.0.1" resolved "https://registry.yarnpkg.com/pify/-/pify-4.0.1.tgz#4b2cd25c50d598735c50292224fd8c6df41e3231" integrity sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g== +pify@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-5.0.0.tgz#1f5eca3f5e87ebec28cc6d54a0e4aaf00acc127f" + integrity sha512-eW/gHNMlxdSP6dmG6uJip6FXN0EQBwm2clYYd8Wul42Cwu/DK8HEftzsapcNdYe2MfLiIwZqsDk2RDEsTE79hA== + pinkie-promise@^2.0.0: version "2.0.1" resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" @@ -13007,6 +13334,14 @@ react-dom@^16.9.0: prop-types "^15.6.2" scheduler "^0.15.0" +react-draggable@^4.4.3: + version "4.4.3" + resolved "https://registry.yarnpkg.com/react-draggable/-/react-draggable-4.4.3.tgz#0727f2cae5813e36b0e4962bf11b2f9ef2b406f3" + integrity sha512-jV4TE59MBuWm7gb6Ns3Q1mxX8Azffb7oTtDtBgFkxRvhDp38YAARmRplrj0+XGkhOJB5XziArX+4HUUABtyZ0w== + dependencies: + classnames "^2.2.5" + prop-types "^15.6.0" + react-event-listener@^0.6.0: version "0.6.6" resolved "https://registry.yarnpkg.com/react-event-listener/-/react-event-listener-0.6.6.tgz#758f7b991cad9086dd39fd29fad72127e1d8962a" @@ -13023,6 +13358,13 @@ react-fontawesome@^1.5.0: dependencies: prop-types "^15.5.6" +react-input-autosize@^2.2.2: + version "2.2.2" + resolved "https://registry.yarnpkg.com/react-input-autosize/-/react-input-autosize-2.2.2.tgz#fcaa7020568ec206bc04be36f4eb68e647c4d8c2" + integrity sha512-jQJgYCA3S0j+cuOwzuCd1OjmBmnZLdqQdiLKRYrsMMzbjUrVDS5RvJUDwJqA7sKuksDuzFtm6hZGKFu7Mjk5aw== + dependencies: + prop-types "^15.5.8" + react-is@^16.3.2, react-is@^16.6.0, react-is@^16.7.0, react-is@^16.8.1, react-is@^16.8.4, react-is@^16.8.6, react-is@^16.9.0: version "16.9.0" resolved "https://registry.yarnpkg.com/react-is/-/react-is-16.9.0.tgz#21ca9561399aad0ff1a7701c01683e8ca981edcb" @@ -13043,6 +13385,13 @@ react-lifecycles-compat@^3.0.4: resolved "https://registry.yarnpkg.com/react-lifecycles-compat/-/react-lifecycles-compat-3.0.4.tgz#4f1a273afdfc8f3488a8c516bfda78f872352362" integrity sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA== +react-loading-skeleton@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/react-loading-skeleton/-/react-loading-skeleton-2.1.1.tgz#2c075ea9683587c163408c8eec0703047c4203b1" + integrity sha512-+fGvgG9ieUw4D5QVgpqJkJ75jhzUdz96GRsA0HjTlR0Mpj9DJUEFc0AKELs7ZkqWVH8/DiroaaufSrOPld1kGA== + dependencies: + "@emotion/core" "^10.0.22" + react-moment-proptypes@^1.2.1: version "1.6.0" resolved "https://registry.yarnpkg.com/react-moment-proptypes/-/react-moment-proptypes-1.6.0.tgz#8ec266ee392a08ba3412d2df2eebf833ab1046df" @@ -13125,6 +13474,20 @@ react-router@^5.0.1: tiny-invariant "^1.0.2" tiny-warning "^1.0.0" +react-select@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/react-select/-/react-select-3.1.0.tgz#ab098720b2e9fe275047c993f0d0caf5ded17c27" + integrity sha512-wBFVblBH1iuCBprtpyGtd1dGMadsG36W5/t2Aj8OE6WbByDg5jIFyT7X5gT+l0qmT5TqWhxX+VsKJvCEl2uL9g== + dependencies: + "@babel/runtime" "^7.4.4" + "@emotion/cache" "^10.0.9" + "@emotion/core" "^10.0.9" + "@emotion/css" "^10.0.9" + memoize-one "^5.0.0" + prop-types "^15.6.0" + react-input-autosize "^2.2.2" + react-transition-group "^4.3.0" + react-swipeable-views-core@^0.13.1: version "0.13.1" resolved "https://registry.yarnpkg.com/react-swipeable-views-core/-/react-swipeable-views-core-0.13.1.tgz#8829a922462a8bdd701709cd1b385393d38f1527" @@ -13177,6 +13540,16 @@ react-transition-group@^2.0.0, react-transition-group@^2.2.0: prop-types "^15.6.2" react-lifecycles-compat "^3.0.4" +react-transition-group@^4.3.0: + version "4.4.1" + resolved "https://registry.yarnpkg.com/react-transition-group/-/react-transition-group-4.4.1.tgz#63868f9325a38ea5ee9535d828327f85773345c9" + integrity sha512-Djqr7OQ2aPUiYurhPalTrVy9ddmFCCzwhqQmtN+J3+3DzLO209Fdr70QrN8Z3DsglWql6iY1lDWAfpFiBtuKGw== + dependencies: + "@babel/runtime" "^7.5.5" + dom-helpers "^5.0.1" + loose-envify "^1.4.0" + prop-types "^15.6.2" + react@^16.9.0: version "16.9.0" resolved "https://registry.yarnpkg.com/react/-/react-16.9.0.tgz#40ba2f9af13bc1a38d75dbf2f4359a5185c4f7aa" @@ -13422,6 +13795,13 @@ readdirp@^2.0.0, readdirp@^2.2.1: micromatch "^3.1.10" readable-stream "^2.0.2" +readdirp@~3.4.0: + version "3.4.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-3.4.0.tgz#9fdccdf9e9155805449221ac645e8303ab5b9ada" + integrity sha512-0xe001vZBnJEK+uKcj8qOhyAKPzIT+gStxWr3LCB0DwcXR5NZJ3IaC+yGnHCYzB/S7ov3m3EEbZI2zeNvX+hGQ== + dependencies: + picomatch "^2.2.1" + realpath-native@^1.1.0: version "1.1.0" resolved "https://registry.yarnpkg.com/realpath-native/-/realpath-native-1.1.0.tgz#2003294fea23fb0672f2476ebe22fcf498a2d65c" @@ -13521,10 +13901,10 @@ reflect.ownkeys@^0.2.0: resolved "https://registry.yarnpkg.com/reflect.ownkeys/-/reflect.ownkeys-0.2.0.tgz#749aceec7f3fdf8b63f927a04809e90c5c0b3460" integrity sha1-dJrO7H8/34tj+SegSAnpDFwLNGA= -regenerate-unicode-properties@^8.0.2: - version "8.1.0" - resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.1.0.tgz#ef51e0f0ea4ad424b77bf7cb41f3e015c70a3f0e" - integrity sha512-LGZzkgtLY79GeXLm8Dp0BVLdQlWICzBnJz/ipWUgo59qBaZ+BHtq51P2q1uVZlppMuUAT37SDk39qUbjTWB7bA== +regenerate-unicode-properties@^8.0.2, regenerate-unicode-properties@^8.2.0: + version "8.2.0" + resolved "https://registry.yarnpkg.com/regenerate-unicode-properties/-/regenerate-unicode-properties-8.2.0.tgz#e5de7111d655e7ba60c057dbe9ff37c87e65cdec" + integrity sha512-F9DjY1vKLo/tPePDycuH3dn9H1OTPIkVD9Kz4LODu+F2C75mgjAJ7x/gwy6ZcSNRAAkhNlJSOHRe8k3p+K9WhA== dependencies: regenerate "^1.4.0" @@ -13548,10 +13928,10 @@ regenerator-runtime@^0.12.0: resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.12.1.tgz#fa1a71544764c036f8c49b13a08b2594c9f8a0de" integrity sha512-odxIc1/vDlo4iZcfXqRYFj0vpXFNoGdKMAUieAlFYO6m/nl5e9KR/beGf41z4a1FI+aQgtjhuaSlDxQ0hmkrHg== -regenerator-runtime@^0.13.2: - version "0.13.3" - resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" - integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== +regenerator-runtime@^0.13.2, regenerator-runtime@^0.13.4: + version "0.13.5" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.5.tgz#d878a1d094b4306d10b9096484b33ebd55e26697" + integrity sha512-ZS5w8CpKFinUzOwW3c83oPeVXoNsrLsaCoLtJvAClH135j/R77RuymhiSErhm2lKcwSCIpmvIWSbDkIfAqKQlA== regenerator-transform@^0.10.0: version "0.10.1" @@ -13562,12 +13942,12 @@ regenerator-transform@^0.10.0: babel-types "^6.19.0" private "^0.1.6" -regenerator-transform@^0.14.0: - version "0.14.1" - resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.1.tgz#3b2fce4e1ab7732c08f665dfdb314749c7ddd2fb" - integrity sha512-flVuee02C3FKRISbxhXl9mGzdbWUVHubl1SMaknjxkFB1/iqpJhArQUvRxOOPEc/9tAiX0BaQ28FJH10E4isSQ== +regenerator-transform@^0.14.0, regenerator-transform@^0.14.2: + version "0.14.5" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.14.5.tgz#c98da154683671c9c4dcb16ece736517e1b7feb4" + integrity sha512-eOf6vka5IO151Jfsw2NO9WpGX58W6wWmefK3I1zEGr0lOD0u8rwPaNqQL1aRxUaxLeKO3ArNh3VYg1KbaD+FFw== dependencies: - private "^0.1.6" + "@babel/runtime" "^7.8.4" regex-cache@^0.4.2: version "0.4.4" @@ -13612,17 +13992,17 @@ regexpu-core@^2.0.0: regjsgen "^0.2.0" regjsparser "^0.1.4" -regexpu-core@^4.5.4: - version "4.5.4" - resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.5.4.tgz#080d9d02289aa87fe1667a4f5136bc98a6aebaae" - integrity sha512-BtizvGtFQKGPUcTy56o3nk1bGRp4SZOTYrDtGNlqCQufptV5IkkLN6Emw+yunAJjzf+C9FQFtvq7IoA3+oMYHQ== +regexpu-core@^4.5.4, regexpu-core@^4.7.0: + version "4.7.1" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-4.7.1.tgz#2dea5a9a07233298fbf0db91fa9abc4c6e0f8ad6" + integrity sha512-ywH2VUraA44DZQuRKzARmw6S66mr48pQVva4LBeRhcOltJ6hExvWly5ZjFLYo67xbIxb6W1q4bAGtgfEl20zfQ== dependencies: regenerate "^1.4.0" - regenerate-unicode-properties "^8.0.2" - regjsgen "^0.5.0" - regjsparser "^0.6.0" + regenerate-unicode-properties "^8.2.0" + regjsgen "^0.5.1" + regjsparser "^0.6.4" unicode-match-property-ecmascript "^1.0.4" - unicode-match-property-value-ecmascript "^1.1.0" + unicode-match-property-value-ecmascript "^1.2.0" registry-auth-token@^3.0.1: version "3.4.0" @@ -13652,10 +14032,10 @@ regjsgen@^0.2.0: resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" integrity sha1-bAFq3qxVT3WCP+N6wFuS1aTtsfc= -regjsgen@^0.5.0: - version "0.5.0" - resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.0.tgz#a7634dc08f89209c2049adda3525711fb97265dd" - integrity sha512-RnIrLhrXCX5ow/E5/Mh2O4e/oa1/jW0eaBKTSy3LaCj+M3Bqvm97GWDp2yUtzIs4LEn65zR2yiYGFqb2ApnzDA== +regjsgen@^0.5.0, regjsgen@^0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.5.2.tgz#92ff295fb1deecbf6ecdab2543d207e91aa33733" + integrity sha512-OFFT3MfrH90xIW8OOSyUrk6QHD5E9JOTeGodiJeBS3J6IwlgzJMNE/1bZklWz5oTg+9dCMyEetclvCVXOPoN3A== regjsparser@^0.1.4: version "0.1.5" @@ -13664,10 +14044,10 @@ regjsparser@^0.1.4: dependencies: jsesc "~0.5.0" -regjsparser@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.0.tgz#f1e6ae8b7da2bae96c99399b868cd6c933a2ba9c" - integrity sha512-RQ7YyokLiQBomUJuUG8iGVvkgOLxwyZM8k6d3q5SAXpg4r5TZJZigKFvC6PpD+qQ98bCDC5YelPeA3EucDoNeQ== +regjsparser@^0.6.0, regjsparser@^0.6.4: + version "0.6.4" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.6.4.tgz#a769f8684308401a66e9b529d2436ff4d0666272" + integrity sha512-64O87/dPDgfk8/RQqC4gkZoGyyWFIEUTTh80CU6CWuK5vkCGyekIx+oKcEIYtP/RAxSQltCZHCNu/mdd7fqlJw== dependencies: jsesc "~0.5.0" @@ -13769,13 +14149,6 @@ remark@^9.0.0: argparse "~0.1.15" autolinker "~0.15.0" -remote-origin-url@0.4.0: - version "0.4.0" - resolved "https://registry.yarnpkg.com/remote-origin-url/-/remote-origin-url-0.4.0.tgz#4d3e2902f34e2d37d1c263d87710b77eb4086a30" - integrity sha1-TT4pAvNOLTfRwmPYdxC3frQIajA= - dependencies: - parse-git-config "^0.2.0" - remove-bom-buffer@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/remove-bom-buffer/-/remove-bom-buffer-3.0.0.tgz#c2bf1e377520d324f623892e33c10cac2c252b53" @@ -13954,7 +14327,7 @@ resolve@1.1.7: resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.1.7.tgz#203114d82ad2c5ed9e8e0411b3932875e889e97b" integrity sha1-IDEU2CrSxe2ejgQRs5ModeiJ6Xs= -resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1: +resolve@^1.1.3, resolve@^1.1.4, resolve@^1.1.6, resolve@^1.1.7, resolve@^1.10.0, resolve@^1.10.1, resolve@^1.11.0, resolve@^1.12.0, resolve@^1.3.2, resolve@^1.4.0, resolve@^1.5.0, resolve@^1.8.1: version "1.17.0" resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.17.0.tgz#b25941b54968231cc2d1bb76a79cb7f2c0bf8444" integrity sha512-ic+7JYiV8Vi2yzQGFWOkiZD5Z9z7O2Zhm9XMaTxdJExKasieFCr+yXZ/WmXsckHiKl12ar0y6XiXDx3m4RHn1w== @@ -14209,6 +14582,11 @@ semver@5.5.0: resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab" integrity sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA== +semver@7.0.0: + version "7.0.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-7.0.0.tgz#5f3ca35761e47e05b206c6daff2cf814f0316b8e" + integrity sha512-+GB6zVA9LWh6zovYQLALHwv5rb2PHGlJi3lfiqIHxR0uuwCgefcOJc59v9fv1w8GbStwxuuqqAjI9NMAOOgq1A== + semver@^6.0.0, semver@^6.1.1: version "6.3.0" resolved "https://registry.yarnpkg.com/semver/-/semver-6.3.0.tgz#ee0a64c8af5e8ceea67687b133761e1becbd1d3d" @@ -14798,14 +15176,14 @@ string-width@^3.0.0, string-width@^3.1.0: is-fullwidth-code-point "^2.0.0" strip-ansi "^5.1.0" -string-width@^4.0.0: - version "4.1.0" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.1.0.tgz#ba846d1daa97c3c596155308063e075ed1c99aff" - integrity sha512-NrX+1dVVh+6Y9dnQ19pR0pP4FiEIlUvdTGn8pw6CKTNq5sgib2nIhmUNT5TAmhWmvKr3WcxBcP3E8nWezuipuQ== +string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.0.tgz#952182c46cc7b2c313d1596e623992bd163b72b5" + integrity sha512-zUz5JD+tgqtuDjMhwIg5uFVV3dtqZ9yQJlZVfq4I01/K5Paj5UHj7VyrQOJvzawSVlKpObApbfD0Ed6yJc+1eg== dependencies: emoji-regex "^8.0.0" is-fullwidth-code-point "^3.0.0" - strip-ansi "^5.2.0" + strip-ansi "^6.0.0" string.prototype.trim@^1.1.2: version "1.2.0" @@ -14894,6 +15272,13 @@ strip-ansi@^5.0.0, strip-ansi@^5.1.0, strip-ansi@^5.2.0: dependencies: ansi-regex "^4.1.0" +strip-ansi@^6.0.0: + version "6.0.0" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.0.tgz#0b1571dd7669ccd4f3e06e14ef1eed26225ae532" + integrity sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w== + dependencies: + ansi-regex "^5.0.0" + strip-bom@3.0.0, strip-bom@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-3.0.0.tgz#2334c18e9c759f7bdd56fdef7e9ae3d588e68ed3" @@ -15637,10 +16022,10 @@ unicode-match-property-ecmascript@^1.0.4: unicode-canonical-property-names-ecmascript "^1.0.4" unicode-property-aliases-ecmascript "^1.0.4" -unicode-match-property-value-ecmascript@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.1.0.tgz#5b4b426e08d13a80365e0d657ac7a6c1ec46a277" - integrity sha512-hDTHvaBk3RmFzvSl0UVrUmC3PuW9wKVnpoUDYH0JDkSIovzw+J5viQmeYHxVSBptubnr7PbH2e0fnpDRQnQl5g== +unicode-match-property-value-ecmascript@^1.1.0, unicode-match-property-value-ecmascript@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/unicode-match-property-value-ecmascript/-/unicode-match-property-value-ecmascript-1.2.0.tgz#0d91f600eeeb3096aa962b1d6fc88876e64ea531" + integrity sha512-wjuQHGQVofmSJv1uVISKLE5zO2rNGzM/KCYZch/QQvez7C1hUhBIuZ701fYXExuufJFMPhv2SyL8CyoIfMLbIQ== unicode-property-aliases-ecmascript@^1.0.4: version "1.0.5" @@ -16429,6 +16814,15 @@ wrap-ansi@^5.1.0: string-width "^3.0.0" strip-ansi "^5.0.0" +wrap-ansi@^6.2.0: + version "6.2.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-6.2.0.tgz#e9393ba07102e6c91a3b221478f0257cd2856e53" + integrity sha512-r6lPcBGxZXlIcymEu7InxDMhdW0KDxpLgoFLcguasxCaJ/SOIZwINatK9KY/tf+ZrlywOKU0UDj3ATXUBfxJXA== + dependencies: + ansi-styles "^4.0.0" + string-width "^4.1.0" + strip-ansi "^6.0.0" + wrappy@1: version "1.0.2" resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" @@ -16527,6 +16921,13 @@ yallist@^3.0.0, yallist@^3.0.2, yallist@^3.0.3: resolved "https://registry.yarnpkg.com/yallist/-/yallist-3.1.1.tgz#dbb7daf9bfd8bac9ab45ebf602b8cbad0d5d08fd" integrity sha512-a4UGQaWPH59mOXUYnAG2ewncQS4i4F43Tv3JoAM+s2VDAmS9NsK8GpDMLrCHPksFT7h3K6TOoUNn2pb7RoXx4g== +yaml@^1.7.2: + version "1.9.2" + resolved "https://registry.yarnpkg.com/yaml/-/yaml-1.9.2.tgz#f0cfa865f003ab707663e4f04b3956957ea564ed" + integrity sha512-HPT7cGGI0DuRcsO51qC1j9O16Dh1mZ2bnXwsi0jrSpsLz0WxOLSLXfkABVl6bZO629py3CU+OMJtpNHDLB97kg== + dependencies: + "@babel/runtime" "^7.9.2" + yamljs@^0.3.0: version "0.3.0" resolved "https://registry.yarnpkg.com/yamljs/-/yamljs-0.3.0.tgz#dc060bf267447b39f7304e9b2bfbe8b5a7ddb03b" @@ -16551,7 +16952,7 @@ yargs-parser@^13.1.1: camelcase "^5.0.0" decamelize "^1.2.0" -yargs-parser@^18.1.3: +yargs-parser@^18.1.2, yargs-parser@^18.1.3: version "18.1.3" resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-18.1.3.tgz#be68c4975c6b2abf469236b0c870362fab09a7b0" integrity sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ== @@ -16632,6 +17033,23 @@ yargs@^13.1.0, yargs@^13.2.4: y18n "^4.0.0" yargs-parser "^13.1.1" +yargs@^15.3.1: + version "15.4.1" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-15.4.1.tgz#0d87a16de01aee9d8bec2bfbf74f67851730f4f8" + integrity sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A== + dependencies: + cliui "^6.0.0" + decamelize "^1.2.0" + find-up "^4.1.0" + get-caller-file "^2.0.1" + require-directory "^2.1.1" + require-main-filename "^2.0.0" + set-blocking "^2.0.0" + string-width "^4.2.0" + which-module "^2.0.0" + y18n "^4.0.0" + yargs-parser "^18.1.2" + yargs@^6.0.0: version "6.6.0" resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208"