diff --git a/__snapshots__/storybook.test.ts.snap b/__snapshots__/storybook.test.ts.snap index 605b0fe0c..f56de3147 100644 --- a/__snapshots__/storybook.test.ts.snap +++ b/__snapshots__/storybook.test.ts.snap @@ -89272,8 +89272,9 @@ exports[`Storyshots ItineraryBody/otp-ui Walk Transit Walk Itinerary With Custom onClick={[Function]} > - Ride - 3 min + Ride for a custom duration of + 3.583 + minutes (2 stops) @@ -94475,7 +94476,7 @@ exports[`Storyshots LocationField/Mobile Context With Custom Icons 2`] = ` className="c12" >
1st & Main ( @@ -94536,7 +94537,7 @@ exports[`Storyshots LocationField/Mobile Context With Custom Icons 2`] = ` className="c12" >
Main & 2nd ( @@ -94662,7 +94663,8 @@ exports[`Storyshots LocationField/Mobile Context With Custom Icons 2`] = `
- Home (456 Suburb St) + Home + (456 Suburb St) @@ -94711,7 +94713,8 @@ exports[`Storyshots LocationField/Mobile Context With Custom Icons 2`] = `
- Work (789 Busy St) + Work + (789 Busy St) @@ -95158,7 +95161,7 @@ exports[`Storyshots LocationField/Mobile Context With Nearby Stops 2`] = ` className="c13" >
1st & Main ( @@ -95219,7 +95222,7 @@ exports[`Storyshots LocationField/Mobile Context With Nearby Stops 2`] = ` className="c13" >
Main & 2nd ( @@ -95945,7 +95948,8 @@ exports[`Storyshots LocationField/Mobile Context With User Settings 2`] = `
- Home (456 Suburb St) + Home + (456 Suburb St) @@ -95994,7 +95998,8 @@ exports[`Storyshots LocationField/Mobile Context With User Settings 2`] = `
- Work (789 Busy St) + Work + (789 Busy St) @@ -215463,8 +215468,8 @@ Array [ itinerary creates transit fares object for fares with multiple currencies 1`] = ` -Object { - "maxTNCFare": 19, - "minTNCFare": 17, - "tncCurrencyCode": "USD", - "transitFares": Object { - "electronicYouth": Object { - "centsToString": [Function], - "currencyCode": "USD", - "dollarsToString": [Function], - "transitFare": 175, - }, - "regular": Object { - "centsToString": [Function], - "currencyCode": "USD", - "dollarsToString": [Function], - "transitFare": 575, - }, - "senior": Object { - "centsToString": [Function], - "currencyCode": "GBP", - "dollarsToString": [Function], - "transitFare": 200, - }, - }, -} -`; +exports[`util > itinerary getTransitFare should return defaults with missing fare 1`] = `0`; -exports[`util > itinerary getTransitFare should return defaults with missing fare 1`] = `"$1.00"`; - -exports[`util > itinerary getTransitFare should return defaults with missing fare 2`] = `"$0.00"`; - -exports[`util > itinerary getTransitFare should return defaults with missing fare 3`] = `"$1.00"`; - -exports[`util > itinerary getTransitFare should return defaults with missing fare 4`] = `0`; - -exports[`util > itinerary getTransitFare should work with valid fare component 1`] = `"$5.75"`; - -exports[`util > itinerary getTransitFare should work with valid fare component 2`] = `575`; +exports[`util > itinerary getTransitFare should work with valid fare component 1`] = `575`; diff --git a/packages/core-utils/src/__tests__/__snapshots__/time.js.snap b/packages/core-utils/src/__tests__/__snapshots__/time.js.snap index b3097d14d..dabc7a719 100644 --- a/packages/core-utils/src/__tests__/__snapshots__/time.js.snap +++ b/packages/core-utils/src/__tests__/__snapshots__/time.js.snap @@ -10,18 +10,12 @@ exports[`time getCurrentTime should return time at specified timezone 2`] = `"19 exports[`time getUserTimezone should get the correct timezone from the testing environment 1`] = `"America/Los_Angeles"`; -exports[`time time format functions should correctly format 0 seconds as a duration with seconds 1`] = `"0 min"`; - -exports[`time time format functions should correctly format 0 seconds as a duration without seconds 1`] = `"0 min"`; - -exports[`time time format functions should correctly format 35 seconds as a duration with seconds 1`] = `"35 sec"`; - -exports[`time time format functions should correctly format 35 seconds as a duration without seconds 1`] = `"0 min"`; - exports[`time time format functions should correctly format 9401 seconds as a duration since midnight 1`] = `"02:36"`; -exports[`time time format functions should correctly format 9401 seconds as a duration with seconds 1`] = `"2 hr 36 min 41 sec"`; - -exports[`time time format functions should correctly format 9401 seconds as a duration without seconds 1`] = `"2 hr 36 min"`; - -exports[`time time format functions should correctly format 9401 seconds as a narrative 1`] = `"16:00"`; +exports[`time toHoursMinutesSeconds should correctly break down 9401 in hours, minutes, and seconds 1`] = ` +Object { + "hours": 2, + "minutes": 36, + "seconds": 41, +} +`; diff --git a/packages/core-utils/src/__tests__/itinerary.js b/packages/core-utils/src/__tests__/itinerary.js index 12ca2daf2..f92a17c12 100644 --- a/packages/core-utils/src/__tests__/itinerary.js +++ b/packages/core-utils/src/__tests__/itinerary.js @@ -1,5 +1,5 @@ import { - calculateFares, + calculateTncFares, getCompanyFromLeg, getTransitFare, isTransit @@ -7,70 +7,57 @@ import { const bikeRentalItinerary = require("./__mocks__/bike-rental-itinerary.json"); const tncItinerary = require("./__mocks__/tnc-itinerary.json"); -const multiCurrencyItinerary = require("./__mocks__/multi-currency-itinerary.json"); describe("util > itinerary", () => { - it("isTransit should work", () => { - expect(isTransit("CAR")).toBeFalsy(); + describe("isTransit", () => { + it("should work", () => { + expect(isTransit("CAR")).toBeFalsy(); + expect(isTransit("BUS")).toBeTruthy(); + }); }); - it("getCompanyFromLeg should return company for bike rental leg", () => { - const company = getCompanyFromLeg(bikeRentalItinerary.legs[1]); - expect(company).toEqual("GBFS"); - }); - - it("getCompanyFromLeg should return company for TNC leg", () => { - const company = getCompanyFromLeg(tncItinerary.legs[0]); - expect(company).toEqual("UBER"); - }); - - it("getTransitFare should return defaults with missing fare", () => { - const { centsToString, dollarsToString, transitFare } = getTransitFare( - null - ); - // Make sure cents to string and dollars to string return same result - expect(dollarsToString(1)).toEqual(centsToString(100)); - // Snapshot tests - expect(centsToString(100)).toMatchSnapshot(); - expect(centsToString(transitFare)).toMatchSnapshot(); - expect(dollarsToString(1)).toMatchSnapshot(); - // transit fare value should be zero - expect(transitFare).toMatchSnapshot(); - }); + describe("getCompanyFromLeg", () => { + it("should return company for bike rental leg", () => { + const company = getCompanyFromLeg(bikeRentalItinerary.legs[1]); + expect(company).toEqual("GBFS"); + }); - it("getTransitFare should work with valid fare component", () => { - const fareComponent = { - currency: { - currency: "USD", - defaultFractionDigits: 2, - currencyCode: "USD", - symbol: "$" - }, - cents: 575 - }; - const { - centsToString, - currencyCode, - dollarsToString, - transitFare - } = getTransitFare(fareComponent); - // Make sure cents to string and dollars to string return same result - expect(dollarsToString(transitFare / 100)).toEqual( - centsToString(transitFare) - ); - expect(currencyCode).toEqual(fareComponent.currency.currencyCode); - // Snapshot tests - expect(centsToString(transitFare)).toMatchSnapshot(); - expect(transitFare).toMatchSnapshot(); + it("should return company for TNC leg", () => { + const company = getCompanyFromLeg(tncItinerary.legs[0]); + expect(company).toEqual("UBER"); + }); }); - it("calculateFare should return the correct currency code for TNC leg", () => { - const fareResult = calculateFares(tncItinerary, true); - expect(fareResult.tncCurrencyCode).toEqual("USD"); + describe("getTransitFare", () => { + it("should return defaults with missing fare", () => { + const { transitFare } = getTransitFare(null); + // transit fare value should be zero + expect(transitFare).toMatchSnapshot(); + }); + + it("should work with valid fare component", () => { + const fareComponent = { + currency: { + currency: "USD", + defaultFractionDigits: 2, + currencyCode: "USD", + symbol: "$" + }, + cents: 575 + }; + const { currencyCode, transitFare } = getTransitFare(fareComponent); + expect(currencyCode).toEqual(fareComponent.currency.currencyCode); + // Snapshot tests + expect(transitFare).toMatchSnapshot(); + }); }); - it("creates transit fares object for fares with multiple currencies", () => { - const fareResult = calculateFares(multiCurrencyItinerary, true); - expect(fareResult).toMatchSnapshot(); + describe("calculateTncFares", () => { + it("should return the correct amounts and currency for an itinerary with TNC", () => { + const fareResult = calculateTncFares(tncItinerary, true); + expect(fareResult.currencyCode).toEqual("USD"); + expect(fareResult.maxTNCFare).toEqual(19); + expect(fareResult.minTNCFare).toEqual(17); + }); }); }); diff --git a/packages/core-utils/src/__tests__/time.js b/packages/core-utils/src/__tests__/time.js index 6b47f6a64..ab868998f 100644 --- a/packages/core-utils/src/__tests__/time.js +++ b/packages/core-utils/src/__tests__/time.js @@ -4,14 +4,12 @@ import { } from "../../../../test-utils/time"; import { - formatDuration, - formatDurationWithSeconds, formatSecondsAfterMidnight, - formatTime, getCurrentDate, getCurrentTime, getTimeFormat, - getUserTimezone + getUserTimezone, + toHoursMinutesSeconds } from "../time"; describe("time", () => { @@ -35,35 +33,17 @@ describe("time", () => { describe("time format functions", () => { const durationInSeconds = 9401; - it(`should correctly format ${durationInSeconds} seconds as a duration with seconds`, () => { - expect(formatDurationWithSeconds(durationInSeconds)).toMatchSnapshot(); - }); - it(`should correctly format ${durationInSeconds} seconds as a duration without seconds`, () => { - expect(formatDuration(durationInSeconds)).toMatchSnapshot(); - }); - it(`should correctly format ${durationInSeconds} seconds as a narrative`, () => { - expect(formatTime(durationInSeconds)).toMatchSnapshot(); - }); it(`should correctly format ${durationInSeconds} seconds as a duration since midnight`, () => { expect( formatSecondsAfterMidnight(durationInSeconds, getTimeFormat()) ).toMatchSnapshot(); }); + }); - // test 0 - it(`should correctly format 0 seconds as a duration with seconds`, () => { - expect(formatDurationWithSeconds(0)).toMatchSnapshot(); - }); - it(`should correctly format 0 seconds as a duration without seconds`, () => { - expect(formatDuration(0)).toMatchSnapshot(); - }); - - // test 35 - it(`should correctly format 35 seconds as a duration with seconds`, () => { - expect(formatDurationWithSeconds(35)).toMatchSnapshot(); - }); - it(`should correctly format 35 seconds as a duration without seconds`, () => { - expect(formatDuration(35)).toMatchSnapshot(); + describe("toHoursMinutesSeconds", () => { + const durationInSeconds = 9401; + it(`should correctly break down ${durationInSeconds} in hours, minutes, and seconds`, () => { + expect(toHoursMinutesSeconds(durationInSeconds)).toMatchSnapshot(); }); }); diff --git a/packages/core-utils/src/deprecated-with-types.ts b/packages/core-utils/src/deprecated-with-types.ts deleted file mode 100644 index ecaca3c68..000000000 --- a/packages/core-utils/src/deprecated-with-types.ts +++ /dev/null @@ -1,62 +0,0 @@ -/* eslint-disable import/no-cycle */ -import { TimeOptions } from "@opentripplanner/types"; -import { format } from "date-fns"; - -import { logDeprecationWarning } from "./deprecated"; -import { - formatDurationLikeMoment, - offsetTime, - OTP_API_TIME_FORMAT -} from "./time"; - -// time.ts - -/** - * Formats a time value for display in narrative - * TODO: internationalization/timezone - * @param {number} ms epoch time value in milliseconds - * @returns {string} formatted text representation - */ -export function formatTime(ms: number, options: TimeOptions): string { - logDeprecationWarning("formatTime", "formatjs"); - - return format( - offsetTime(ms, options), - options?.format || OTP_API_TIME_FORMAT - ); -} - -/** - * Formats an elapsed time duration for display in narrative. - * TODO: internationalization - * @param {number} seconds duration in seconds - * @returns {string} formatted text representation - */ -// TS TODO: region as type? -export function formatDuration(seconds: number, region: string): string { - logDeprecationWarning("formatDuration", "formatjs"); - - return formatDurationLikeMoment(seconds, false, { - enabled: true, - code: region - }); -} - -/** - * Formats an elapsed time in seconds, minutes, hours duration for display in narrative - * @param {number} seconds duration in seconds - * @param {object} region an object that allows internationalization of the time - * @returns {string} formatted text representation - */ -// TS TODO: region as type? -export function formatDurationWithSeconds( - seconds: number, - region: string -): string { - logDeprecationWarning("formatDurationWithSeconds", "formatjs"); - - return formatDurationLikeMoment(seconds, true, { - enabled: true, - code: region - }); -} diff --git a/packages/core-utils/src/deprecated.js b/packages/core-utils/src/deprecated.js deleted file mode 100644 index 6c821c6f5..000000000 --- a/packages/core-utils/src/deprecated.js +++ /dev/null @@ -1,334 +0,0 @@ -import moment from "moment"; - -/** - * To disable cyclic dependency resolution we need to require() within methods - * This is a good reason to disable this eslint-rule - */ -/* eslint-disable global-require */ - -/** - * Generates a warning to tell developer that they are using deprecated methods! - */ -export function logDeprecationWarning(method, alternative) { - console.warn( - `${method || - "This method"} is deprecated and will be removed in a future otp-ui release. All language functionality should be handled using react-intl. - ${ - alternative - ? ` - - Use ${alternative} instead, which provides a new interface that doesn't return English strings.` - : "" - }` - ); -} - -// itinerary.js - -export function getStepDirection(step) { - logDeprecationWarning("getStepDirection"); - - switch (step.relativeDirection) { - case "DEPART": - return `Head ${step.absoluteDirection.toLowerCase()}`; - case "LEFT": - return "Left"; - case "HARD_LEFT": - return "Hard left"; - case "SLIGHTLY_LEFT": - return "Slight left"; - case "CONTINUE": - return "Continue"; - case "SLIGHTLY_RIGHT": - return "Slight right"; - case "RIGHT": - return "Right"; - case "HARD_RIGHT": - return "Hard right"; - case "CIRCLE_CLOCKWISE": - return "Follow circle clockwise"; - case "CIRCLE_COUNTERCLOCKWISE": - return "Follow circle counterclockwise"; - case "ELEVATOR": - return "Take elevator"; - case "UTURN_LEFT": - return "Left U-turn"; - case "UTURN_RIGHT": - return "Right U-turn"; - default: - return step.relativeDirection; - } -} - -export function getStepInstructions(step) { - logDeprecationWarning("getStepInstructions"); - - const conjunction = step.relativeDirection === "ELEVATOR" ? "to" : "on"; - return `${getStepDirection(step)} ${conjunction} ${step.streetName}`; -} - -export function getStepStreetName(step) { - logDeprecationWarning("getStepStreetName"); - - if (step.streetName === "road") return "Unnamed Road"; - if (step.streetName === "path") return "Unnamed Path"; - return step.streetName; -} - -export function getLegModeLabel(leg) { - logDeprecationWarning("getLegModeLabel"); - - switch (leg.mode) { - case "BICYCLE_RENT": - return "Biketown"; - case "CAR": - return leg.hailedCar ? "Ride" : "Drive"; - case "GONDOLA": - return "Aerial Tram"; - case "TRAM": - if (leg.routeLongName.toLowerCase().indexOf("streetcar") !== -1) - return "Streetcar"; - return "Light Rail"; - case "MICROMOBILITY": - case "SCOOTER": - return "Ride"; - default: - return require("./itinerary").toSentenceCase(leg.mode); - } -} - -/** - * Returns mode name by checking the vertex type (VertexType class in OTP) for - * the provided place. NOTE: this is currently only intended for vehicles at - * the moment (not transit or walking). - * - * @param {string} place place from itinerary leg - */ -export function getModeForPlace(place) { - logDeprecationWarning("getModeForPlace"); - - switch (place.vertexType) { - case "CARSHARE": - return "car"; - case "VEHICLERENTAL": - return "E-scooter"; - // TODO: Should the type change depending on bike vertex type? - case "BIKESHARE": - case "BIKEPARK": - return "bike"; - // If company offers more than one mode, default to `vehicle` string. - default: - return "vehicle"; - } -} - -export function getPlaceName(place, companies) { - logDeprecationWarning("getPlaceName"); - - // If address is provided (i.e. for carshare station, use it) - if (place.address) return place.address.split(",")[0]; - if (place.networks && place.vertexType === "VEHICLERENTAL") { - // For vehicle rental pick up, do not use the place name. Rather, use - // company name + vehicle type (e.g., SPIN E-scooter). Place name is often just - // a UUID that has no relevance to the actual vehicle. For bikeshare, however, - // there are often hubs or bikes that have relevant names to the user. - const company = require("./itinerary").getCompanyForNetwork( - place.networks[0], - companies - ); - if (company) { - return `${company.label} ${getModeForPlace(place)}`; - } - } - // Default to place name - return place.name; -} - -/** - * For a given fare component (either total fare or component parts), returns - * an object with string formatters and the fare value (in cents). - */ -export function getTransitFare(fareComponent) { - logDeprecationWarning("getTransitFare", "the fare object and getTncFare"); - - // Default values (if fare component is not valid). - let digits = 2; - let transitFare = 0; - let symbol = "$"; - let currencyCode = "USD"; - if (fareComponent) { - // Assign values without declaration. See: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Destructuring_assignment#assignment_without_declaration - ({ - currencyCode, - defaultFractionDigits: digits, - symbol - } = fareComponent.currency); - transitFare = fareComponent.cents; - } - // For cents to string conversion, use digits from fare component. - const centsToString = cents => { - const dollars = (cents / 10 ** digits).toFixed(digits); - return `${symbol}${dollars}`; - }; - // For dollars to string conversion, assume we're rounding to two digits. - const dollarsToString = dollars => `${symbol}${dollars.toFixed(2)}`; - return { - centsToString, - currencyCode, - dollarsToString, - transitFare - }; -} - -/** - * For an itinerary, calculates the transit/TNC fares and returns an object with - * these values, currency info, as well as string formatters. - * It is assumed that the same currency is used for transit and TNC legs. - * - * multiple being set to true will change the output behavior: - * - dollarsToString and centsToString will be returned as part of each fare - * - currencyCode will be returned separately for each fare - * - tnc currency code will be returned separately - * - each fare type will be returned separately within a new transitFares property - * - * FIXME: a new approach to fare calculation must be found: - * the current approach is not sustainable, as centsToString and DollarsToString - * must be replaced by i18n anyway. - * - * However, the current behavior should ideally be kept to avoid a breaking change. - * The "multiple" mode is helpful, but only prevents tnc fare calculation from being duplicated. - * This method could be split out into a new one, along with tnc fare calculation. - * If this is done, the individual fare calculation should also be modified to support - * a default fare not being called "regular". However, this again would be a breaking change. - * This breaking change is avoided by adding the "multiple" parameter. - * - * When centsToString and dollarsToString are removed, this method should be split into - * individual fare calculation on a variable fare key, fare calculation of an entire leg, - * which will get fares for every fare key in the leg, and a method to calculate the fare of - * a tnc ride within the leg. This will make typescripting easier, as the types will be cleaner. - */ -export function calculateFares(itinerary, multiple = false) { - logDeprecationWarning("calculateFares", "the fare object and getTncFare"); - - // Process any TNC fares - let minTNCFare = 0; - let maxTNCFare = 0; - let tncCurrencyCode; - itinerary.legs.forEach(leg => { - if (leg.mode === "CAR" && leg.hailedCar && leg.tncData) { - const { currency, maxCost, minCost } = leg.tncData; - // TODO: Support non-USD - minTNCFare += minCost; - maxTNCFare += maxCost; - tncCurrencyCode = currency; - } - }); - - if (multiple) { - // Return object of fares - const transitFares = {}; - if (itinerary && itinerary.fare && itinerary.fare.fare) { - Object.keys(itinerary.fare.fare).forEach(fareKey => { - const fareComponent = itinerary.fare.fare[fareKey]; - transitFares[fareKey] = getTransitFare(fareComponent); - }); - } - - return { - maxTNCFare, - minTNCFare, - tncCurrencyCode, - transitFares - }; - } - - // Extract fare total from itinerary fares. - const fareComponent = - itinerary.fare && itinerary.fare.fare && itinerary.fare.fare.regular; - // Get string formatters and itinerary fare. - const { - centsToString, - currencyCode: transitCurrencyCode, - dollarsToString, - transitFare - } = getTransitFare(fareComponent); - - return { - centsToString, - currencyCode: transitCurrencyCode || tncCurrencyCode, - dollarsToString, - maxTNCFare, - minTNCFare, - transitFare - }; -} - -// map.js - -export function latlngToString(latlng) { - logDeprecationWarning("latlngToString", "the latlng object"); - - return ( - latlng && - `${latlng.lat.toFixed(5)}, ${(latlng.lng || latlng.lon).toFixed(5)}` - ); -} - -export function coordsToString(coords) { - logDeprecationWarning("coordsToString", "the coords object"); - - return coords.length && coords.map(c => (+c).toFixed(5)).join(", "); -} - -export function getDetailText(location) { - let detailText; - if (location.type === "home" || location.type === "work") { - detailText = location.name; - } - if (location.type === "stop") { - detailText = location.id; - } else if (location.type === "recent" && location.timestamp) { - detailText = moment(location.timestamp).fromNow(); - } - return detailText; -} - -// query.js - -export function summarizeQuery(query, locations = []) { - logDeprecationWarning("summarizeQuery"); - - function findLocationType( - location, - ls = [], - types = ["home", "work", "suggested"] - ) { - const match = ls.find(l => require("./map").matchLatLon(l, location)); - return match && types.indexOf(match.type) !== -1 ? match.type : null; - } - - const from = - findLocationType(query.from, locations) || query.from.name.split(",")[0]; - const to = - findLocationType(query.to, locations) || query.to.name.split(",")[0]; - const mode = require("./itinerary").hasTransit(query.mode) - ? "Transit" - : require("./itinerary").toSentenceCase(query.mode); - return `${mode} from ${from} to ${to}`; -} - -export function getTimeZoneOffset(itinerary) { - logDeprecationWarning("getTimeZoneOffset"); - - if (!itinerary.legs || !itinerary.legs.length) return 0; - - // Determine if there is a DST offset between now and the itinerary start date - const dstOffset = - new Date(itinerary.startTime).getTimezoneOffset() - - new Date().getTimezoneOffset(); - - return ( - itinerary.legs[0].agencyTimeZoneOffset + - (new Date().getTimezoneOffset() + dstOffset) * 60000 - ); -} diff --git a/packages/core-utils/src/itinerary.ts b/packages/core-utils/src/itinerary.ts index 65c6494da..c9b587366 100644 --- a/packages/core-utils/src/itinerary.ts +++ b/packages/core-utils/src/itinerary.ts @@ -7,34 +7,12 @@ import { Itinerary, LatLngArray, Leg, - Step + Money, + Step, + TncFare } from "@opentripplanner/types"; import turfAlong from "@turf/along"; -import { - calculateFares, - getLegModeLabel, - getModeForPlace, - getPlaceName, - getStepDirection, - getStepInstructions, - getStepStreetName, - getTimeZoneOffset, - getTransitFare -} from "./deprecated"; - -export { - calculateFares, - getLegModeLabel, - getModeForPlace, - getPlaceName, - getStepDirection, - getStepInstructions, - getStepStreetName, - getTimeZoneOffset, - getTransitFare -}; - // All OTP transit modes export const transitModes = [ "TRAM", @@ -445,6 +423,53 @@ export function calculatePhysicalActivity( }; } +/** + * For an itinerary, calculates the TNC fares and returns an object with + * these values and currency info. + * It is assumed that the same currency is used for all TNC legs. + */ +export function calculateTncFares(itinerary: Itinerary): TncFare { + return itinerary.legs + .filter(leg => leg.mode === "CAR" && leg.hailedCar && leg.tncData) + .reduce( + ({ maxTNCFare, minTNCFare }, { tncData }) => { + const { currency, maxCost, minCost } = tncData; + return { + // Assumes a single currency for entire itinerary. + currencyCode: currency, + maxTNCFare: maxTNCFare + maxCost, + minTNCFare: minTNCFare + minCost + }; + }, + { + currencyCode: null, + maxTNCFare: 0, + minTNCFare: 0 + } + ); +} + +/** + * For a given fare component (either total fare or component parts), returns + * an object with the fare value (in cents). + */ +export function getTransitFare( + fareComponent: Money +): { + currencyCode: string; + transitFare: number; +} { + return fareComponent + ? { + currencyCode: fareComponent.currency.currencyCode, + transitFare: fareComponent.cents + } + : { + currencyCode: "USD", + transitFare: 0 + }; +} + /** * Sources: * - https://www.itf-oecd.org/sites/default/files/docs/environmental-performance-new-mobility.pdf @@ -508,13 +533,3 @@ export function calculateEmissions( return totalCarbon; } } - -export function calculateTncFares(itinerary) { - // TODO: don't rely on deprecated methods! - // At the moment this is safe as none of these exported variables contain strings - const { maxTNCFare, minTNCFare, tncCurrencyCode } = calculateFares( - itinerary, - true - ); - return { maxTNCFare, minTNCFare, tncCurrencyCode }; -} diff --git a/packages/core-utils/src/map.ts b/packages/core-utils/src/map.ts index 38adbf7e9..ea5f6f098 100644 --- a/packages/core-utils/src/map.ts +++ b/packages/core-utils/src/map.ts @@ -1,14 +1,4 @@ import { LatLngArray, Location, UserPosition } from "@opentripplanner/types"; -import { toSentenceCase } from "./itinerary"; - -import { - coordsToString, - getDetailText, - latlngToString, - logDeprecationWarning -} from "./deprecated"; - -export { coordsToString, getDetailText, latlngToString }; export function currentPositionToLocation( currentPosition: UserPosition @@ -26,6 +16,12 @@ export function currentPositionToLocation( }; } +// TRICKY: This method is used in query.js and in the context of +// otp-rr actions where the intl context is not available/does not apply. +export function coordsToString(coords: number[]): string { + return coords.length && coords.map(c => (+c).toFixed(5)).join(", "); +} + export function stringToCoords(str: string): number[] { return (str && str.split(",").map(c => +c)) || []; } @@ -40,25 +36,6 @@ export function constructLocation(latlng: { }; } -export function formatStoredPlaceName( - location: Location, - withDetails = true -): string { - if (withDetails) { - logDeprecationWarning("the formatStoredPlaceName withDetails parameter"); - } - - let displayName = - location.type === "home" || location.type === "work" - ? toSentenceCase(location.type) - : location.name; - if (withDetails) { - const detailText = getDetailText(location); - if (detailText) displayName += ` (${detailText})`; - } - return displayName; -} - export function matchLatLon(location1: Location, location2: Location): boolean { if (!location1 || !location2) return location1 === location2; return location1.lat === location2.lat && location1.lon === location2.lon; diff --git a/packages/core-utils/src/query.js b/packages/core-utils/src/query.js index 3e5990407..7db913d01 100644 --- a/packages/core-utils/src/query.js +++ b/packages/core-utils/src/query.js @@ -1,9 +1,9 @@ -import moment from "moment"; +import { format, isMatch, parse } from "date-fns"; import getGeocoder from "@opentripplanner/geocoder/lib"; import qs from "qs"; import { getTransitModes, hasCar, isAccessMode } from "./itinerary"; -import { stringToCoords } from "./map"; +import { coordsToString, stringToCoords } from "./map"; import queryParams from "./query-params"; import { getCurrentTime, @@ -12,10 +12,6 @@ import { OTP_API_TIME_FORMAT } from "./time"; -import { coordsToString, summarizeQuery } from "./deprecated"; - -export { summarizeQuery }; - /* The list of default parameters considered in the settings panel */ export const defaultParams = [ @@ -315,9 +311,15 @@ export function planParamsToQuery(params) { break; case "time": { - const parsedTime = moment(params.time, TIME_FORMATS); - query.time = parsedTime.isValid() - ? parsedTime.format(OTP_API_TIME_FORMAT) + // Match one of the supported time formats + const matchedTimeFormat = TIME_FORMATS.find(timeFormat => + isMatch(params.time, timeFormat) + ); + query.time = matchedTimeFormat + ? format( + parse(params.time, matchedTimeFormat, new Date()), + OTP_API_TIME_FORMAT + ) : getCurrentTime(); } break; @@ -421,8 +423,8 @@ export function getRoutingParams(config, currentQuery, ignoreRealtimeUpdates) { } // check date/time validity; ignore both if either is invalid - const dateValid = moment(params.date, OTP_API_DATE_FORMAT).isValid(); - const timeValid = moment(params.time, OTP_API_TIME_FORMAT).isValid(); + const dateValid = isMatch(params.date, OTP_API_DATE_FORMAT); + const timeValid = isMatch(params.time, OTP_API_TIME_FORMAT); if (!dateValid || !timeValid) { delete params.time; @@ -447,11 +449,8 @@ export function getRoutingParams(config, currentQuery, ignoreRealtimeUpdates) { // Additional processing specific to PROFILE mode } else { // check start and end time validity; ignore both if either is invalid - const startTimeValid = moment( - params.startTime, - OTP_API_TIME_FORMAT - ).isValid(); - const endTimeValid = moment(params.endTime, OTP_API_TIME_FORMAT).isValid(); + const startTimeValid = isMatch(params.startTime, OTP_API_TIME_FORMAT); + const endTimeValid = isMatch(params.endTime, OTP_API_TIME_FORMAT); if (!startTimeValid || !endTimeValid) { delete params.startTimeValid; diff --git a/packages/core-utils/src/time.ts b/packages/core-utils/src/time.ts index 0a8404a95..2fcd2ae92 100644 --- a/packages/core-utils/src/time.ts +++ b/packages/core-utils/src/time.ts @@ -1,96 +1,28 @@ import { Config } from "@opentripplanner/types"; -import { - startOfDay, - add, - format, - formatDuration as dateFnsFormatDuration -} from "date-fns"; +import { startOfDay, add, format } from "date-fns"; import { utcToZonedTime } from "date-fns-tz"; -/* eslint-disable import/no-cycle */ -import { - formatTime, - formatDurationWithSeconds, - formatDuration -} from "./deprecated-with-types"; - -export { formatTime, formatDuration, formatDurationWithSeconds }; - -// special constants for making sure the following date format is always sent to -// OTP regardless of whatever the user has configured as the display format -export const OTP_API_DATE_FORMAT = "YYYY-MM-DD"; -// Date-Fns uses a different string format than moment.js -// see https://github.com/date-fns/date-fns/blob/master/docs/unicodeTokens.md -export const OTP_API_DATE_FORMAT_DATE_FNS = "yyyy-MM-dd"; +// Date/time formats (per date-fns) when sending/receiving date from OTP +// regardless of whatever the user has configured as the display format. +export const OTP_API_DATE_FORMAT = "yyyy-MM-dd"; export const OTP_API_TIME_FORMAT = "HH:mm"; -/** - * To ease the transition away from moment.js, this method uses date-fns to format durations - * the way moment.js did. - * @param {number} seconds The number of seconds to format - * @param {boolean} showSeconds Whether to render seconds or not - * @param {boolean} localize If true, will create output like moment.js using date-fns locale. - * Otherwise, uses date-fns default - * @returns Formatted duration - */ -export function formatDurationLikeMoment( - seconds: number, - showSeconds: boolean, - localize: { enabled: boolean; code: string } = { - enabled: true, - code: "en-US" - } -): string { - // date-fns doesn't do this automatically - if ((!showSeconds && seconds < 60) || seconds === 0) { - return "0 min"; - } - - const hours = Math.floor(seconds / 3600); - const minutes = Math.floor((seconds - hours * 3600) / 60); - const secondsLeftOver = showSeconds - ? seconds - hours * 3600 - minutes * 60 - : 0; - const specLookup = { - xHours: "hr", - xMinutes: "min", - xSeconds: "sec" - }; - const locale = localize - ? { - // Maintain backwards compatibility when called with localize=true - code: localize?.code || "en-US", - formatDistance: (spec, val) => { - return `${val} ${specLookup[spec]}`; - } - } - : undefined; - - return dateFnsFormatDuration( - { - hours, - minutes, - seconds: secondsLeftOver - }, - { - format: ["hours", "minutes", "seconds"], - locale - } - ); -} - /** * Breaks up a duration in seconds into hours, minutes, and seconds. * @param {number} seconds The number of seconds to break up * @returns an object with fields with the corresponding, hours, minutes, seconds. */ -export function toHoursMinutesSeconds(seconds) { - const hours = Math.floor(seconds / 3600); - const minutes = Math.floor((seconds - hours * 3600) / 60); +export function toHoursMinutesSeconds( + seconds: number +): { + hours: number; + minutes: number; + seconds: number; +} { return { - hours, - minutes, - seconds: seconds - hours * 3600 - minutes * 60 + hours: Math.floor(seconds / 3600), + minutes: Math.floor(seconds / 60) % 60, + seconds: seconds % 60 }; } @@ -154,8 +86,5 @@ export function getCurrentTime(timezone = getUserTimezone()): string { * The conversion to the user's timezone is needed for testing purposes. */ export function getCurrentDate(timezone = getUserTimezone()): string { - return format( - utcToZonedTime(Date.now(), timezone), - OTP_API_DATE_FORMAT_DATE_FNS - ); + return format(utcToZonedTime(Date.now(), timezone), OTP_API_DATE_FORMAT); } diff --git a/packages/core-utils/tsconfig.json b/packages/core-utils/tsconfig.json index 21c29ba27..f2d4970a8 100644 --- a/packages/core-utils/tsconfig.json +++ b/packages/core-utils/tsconfig.json @@ -6,10 +6,5 @@ "rootDir": "./src", "skipLibCheck": true }, - "include": ["src/**/*"], - "references": [ - { - "path": "../types" - } - ] + "include": ["src/**/*"] } diff --git a/packages/endpoints-overlay/package.json b/packages/endpoints-overlay/package.json index c51e8c4df..85d1d31cb 100644 --- a/packages/endpoints-overlay/package.json +++ b/packages/endpoints-overlay/package.json @@ -20,7 +20,7 @@ }, "dependencies": { "@opentripplanner/location-icon": "^1.4.0", - "@opentripplanner/core-utils": "^4.11.5", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "flat": "^5.0.2", "@styled-icons/fa-solid": "^10.34.0" }, diff --git a/packages/icons/package.json b/packages/icons/package.json index c4c2358a4..2b5d36889 100644 --- a/packages/icons/package.json +++ b/packages/icons/package.json @@ -10,7 +10,7 @@ "license": "MIT", "private": false, "dependencies": { - "@opentripplanner/core-utils": "^4.5.0", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "prop-types": "^15.7.2" }, "peerDependencies": { diff --git a/packages/itinerary-body/package.json b/packages/itinerary-body/package.json index 4a68e012a..2b5520247 100644 --- a/packages/itinerary-body/package.json +++ b/packages/itinerary-body/package.json @@ -10,18 +10,20 @@ "license": "MIT", "private": false, "dependencies": { - "@opentripplanner/core-utils": "^5.0.0", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "@opentripplanner/humanize-distance": "^1.2.0", "@opentripplanner/icons": "^1.2.2", "@opentripplanner/location-icon": "^1.4.0", "@styled-icons/fa-solid": "^10.34.0", "@styled-icons/foundation": "^10.34.0", + "date-fns": "^2.28.0", + "date-fns-tz": "^1.2.2", "flat": "^5.0.2", - "moment": "^2.24.0", "react-resize-detector": "^4.2.1", "velocity-react": "^1.4.3" }, "devDependencies": { + "@opentripplanner/types": "^3.0.0-alpha.4", "@types/flat": "^5.0.2" }, "peerDependencies": { diff --git a/packages/itinerary-body/src/ItineraryBody/place-row.tsx b/packages/itinerary-body/src/ItineraryBody/place-row.tsx index 89b03da9c..a3f1bdef5 100755 --- a/packages/itinerary-body/src/ItineraryBody/place-row.tsx +++ b/packages/itinerary-body/src/ItineraryBody/place-row.tsx @@ -121,6 +121,7 @@ export default function PlaceRow({ setViewedTrip={setViewedTrip} showAgencyInfo={showAgencyInfo} showViewTripButton={showViewTripButton} + timeZone={config.homeTimezone} TransitLegSubheader={TransitLegSubheader} TransitLegSummary={TransitLegSummary} transitOperator={coreUtils.route.getTransitOperatorFromLeg( diff --git a/packages/itinerary-body/src/TransitLegBody/alerts-body.tsx b/packages/itinerary-body/src/TransitLegBody/alerts-body.tsx index aae6e5574..c3b499732 100644 --- a/packages/itinerary-body/src/TransitLegBody/alerts-body.tsx +++ b/packages/itinerary-body/src/TransitLegBody/alerts-body.tsx @@ -1,4 +1,6 @@ -import moment from "moment"; +import { differenceInCalendarDays } from "date-fns"; +import { toDate, utcToZonedTime } from "date-fns-tz"; +import coreUtils from "@opentripplanner/core-utils"; import { Alert } from "@opentripplanner/types"; import React, { FunctionComponent, ReactElement } from "react"; import { FormattedMessage } from "react-intl"; @@ -6,14 +8,18 @@ import { FormattedMessage } from "react-intl"; import * as S from "../styled"; import { defaultMessages } from "../util"; +const { getUserTimezone, getCurrentDate } = coreUtils.time; + interface Props { alerts: Alert[]; AlertIcon?: FunctionComponent; + timeZone?: string; } export default function AlertsBody({ alerts, - AlertIcon = S.DefaultAlertBodyIcon + AlertIcon = S.DefaultAlertBodyIcon, + timeZone = getUserTimezone() }: Props): ReactElement { return ( @@ -31,9 +37,16 @@ export default function AlertsBody({ ) => { // If alert is effective as of +/- one day, use today, tomorrow, or // yesterday with time. Otherwise, use long date format. - // FIXME: adding 24 hours to a date that is "today" can lead moment to - // report the result to still be "today" (see OTP-RR story). - const dayDiff = moment(effectiveStartDate).diff(moment(), "days"); + // The difference is expressed in calendar days based on the agency's time zone. + // Note: Previously, we used moment.diff(..., "days"), which reports the number of whole 24-hour periods + // between two timestamps/dates (not considering timezones or daylight time changes). + const today = toDate(getCurrentDate(timeZone)); + const compareDate = utcToZonedTime( + new Date(effectiveStartDate), + timeZone + ); + const dayDiff = differenceInCalendarDays(compareDate, today); + return ( diff --git a/packages/itinerary-body/src/TransitLegBody/index.tsx b/packages/itinerary-body/src/TransitLegBody/index.tsx index 39bf677a7..bb3b290a2 100644 --- a/packages/itinerary-body/src/TransitLegBody/index.tsx +++ b/packages/itinerary-body/src/TransitLegBody/index.tsx @@ -42,6 +42,7 @@ interface Props { setViewedTrip: SetViewedTripFunction; showAgencyInfo: boolean; showViewTripButton: boolean; + timeZone: string; TransitLegSubheader?: FunctionComponent; TransitLegSummary: FunctionComponent; transitOperator?: TransitOperator; @@ -98,6 +99,7 @@ class TransitLegBody extends Component { setViewedTrip, showAgencyInfo, showViewTripButton, + timeZone, TransitLegSubheader, TransitLegSummary, transitOperator @@ -213,7 +215,11 @@ class TransitLegBody extends Component { leave={{ animation: "slideUp" }} > {expandAlerts && ( - + )} {/* The "Ride X Min / X Stops" Row, including IntermediateStops body */} diff --git a/packages/itinerary-body/src/demos/index.tsx b/packages/itinerary-body/src/demos/index.tsx index fa69baa18..ee8216158 100644 --- a/packages/itinerary-body/src/demos/index.tsx +++ b/packages/itinerary-body/src/demos/index.tsx @@ -1,4 +1,3 @@ -import coreUtils from "@opentripplanner/core-utils"; import { Place } from "@opentripplanner/types"; import React, { ReactElement } from "react"; import { FormattedTime } from "react-intl"; @@ -59,7 +58,9 @@ export function CustomTransitLegSummary({ /* eslint-disable jsx-a11y/no-static-element-interactions, jsx-a11y/click-events-have-key-events */
{leg.duration && ( - Ride {coreUtils.time.formatDuration(leg.duration, "en-US")} + + Ride for a custom duration of {(leg.duration / 60).toFixed(3)} minutes + )} {leg.intermediateStops && ( diff --git a/packages/itinerary-body/src/stories/OtpRrItineraryBody.story.tsx b/packages/itinerary-body/src/stories/OtpRrItineraryBody.story.tsx index db044a4d6..5ec4a5c42 100644 --- a/packages/itinerary-body/src/stories/OtpRrItineraryBody.story.tsx +++ b/packages/itinerary-body/src/stories/OtpRrItineraryBody.story.tsx @@ -42,9 +42,7 @@ if (!isRunningJest()) { const now = todayWithTime.valueOf(); alerts[0].effectiveStartDate = now; // Today alerts[1].effectiveStartDate = now - 24 * 3600000; // Yesterday - // FIXME: Fix the criterion that decides what constitutes "tomorrow" - // (Adding 24 hours so that a timestamp occurs next day may not be enough). - alerts[2].effectiveStartDate = now + 36 * 3600000; // Tomorrow + alerts[2].effectiveStartDate = now + 24 * 3600000; // Tomorrow } interface StoryWrapperProps { diff --git a/packages/location-field/i18n/en-US.yml b/packages/location-field/i18n/en-US.yml index 715e96895..4a6356fa3 100644 --- a/packages/location-field/i18n/en-US.yml +++ b/packages/location-field/i18n/en-US.yml @@ -14,6 +14,7 @@ otpUi: currentLocationUnavailable: Current location not available ({error}) fetchingLocation: Fetching location... geocoderUnreachable: Could not reach geocoder{error, select, undefined {} other { ({error})}} + homeLocation: Home myPlaces: My Places nearby: Nearby Stops noResultsFound: > @@ -21,9 +22,11 @@ otpUi: null {your query} other {{input}} } + placeNameWithDetails: "{placeName} ({details})" # Note to translator: This is an implicit plural (as in "Other results"). other: Other recentlySearched: Recently Searched stations: Stations stops: Stops useCurrentLocation: Use Current Location + workLocation: Work diff --git a/packages/location-field/i18n/fr.yml b/packages/location-field/i18n/fr.yml index 7d14d044d..7a5916a2e 100644 --- a/packages/location-field/i18n/fr.yml +++ b/packages/location-field/i18n/fr.yml @@ -14,6 +14,7 @@ otpUi: currentLocationUnavailable: Position actuelle non disponible ({error}) fetchingLocation: Chargement du lieu... geocoderUnreachable: Géocodeur introuvable{error, select, undefined {} other { ({error})}} + homeLocation: Domicile myPlaces: Mes lieux nearby: Arrêts à proximité noResultsFound: > @@ -21,9 +22,11 @@ otpUi: null {votre requête} other {{input}} } + placeNameWithDetails: "{placeName} ({details})" # Note to translator: This is an implicit plural (as in "Other results"). other: Autres recentlySearched: Recherches récentes stations: Stations stops: Arrêts useCurrentLocation: Utiliser ma position actuelle + workLocation: Lieu de travail diff --git a/packages/location-field/package.json b/packages/location-field/package.json index 11b2de02a..c8b29a061 100644 --- a/packages/location-field/package.json +++ b/packages/location-field/package.json @@ -10,7 +10,7 @@ "private": false, "dependencies": { "@conveyal/geocoder-arcgis-geojson": "^0.0.3", - "@opentripplanner/core-utils": "^4.11.0", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "@opentripplanner/geocoder": "^1.2.0", "@opentripplanner/humanize-distance": "^1.1.0", "@opentripplanner/location-icon": "^1.4.0", diff --git a/packages/location-field/src/index.tsx b/packages/location-field/src/index.tsx index 7950c8df9..29f18fbf4 100644 --- a/packages/location-field/src/index.tsx +++ b/packages/location-field/src/index.tsx @@ -20,6 +20,7 @@ import type { LocationFieldProps, ResultType } from "./types"; import { GeocodedOptionIcon, Option, + StoredPlaceName, TransitStopOption, UserLocationIcon } from "./options"; @@ -593,8 +594,7 @@ const LocationField = ({ isActive={itemIndex === activeIndex} key={optionKey++} onClick={locationSelected} - // @ts-ignore Fixed in another PR - title={coreUtils.map.formatStoredPlaceName(userLocation)} + title={} /> ); itemIndex++; diff --git a/packages/location-field/src/options.tsx b/packages/location-field/src/options.tsx index 6ef3425a1..85a6bb4e5 100644 --- a/packages/location-field/src/options.tsx +++ b/packages/location-field/src/options.tsx @@ -1,6 +1,7 @@ import coreUtils from "@opentripplanner/core-utils"; import { humanizeDistanceStringImperial } from "@opentripplanner/humanize-distance"; -import React from "react"; +import React, { ReactElement } from "react"; +import { FormattedMessage } from "react-intl"; import { Bus } from "@styled-icons/fa-solid/Bus"; import { Briefcase } from "@styled-icons/fa-solid/Briefcase"; import { Home } from "@styled-icons/fa-solid/Home"; @@ -9,7 +10,6 @@ import { MapPin } from "@styled-icons/fa-solid/MapPin"; import { Stop, UserLocation } from "@opentripplanner/types"; import * as S from "./styled"; -// eslint-disable-next-line prettier/prettier export function GeocodedOptionIcon({ feature = {} @@ -115,3 +115,60 @@ export function UserLocationIcon({ if (userLocation.icon === "home") return ; return ; } + +function LocationName({ location }: { location: UserLocation }): ReactElement { + switch (location.type) { + case "home": + return ( + + ); + case "work": + return ( + + ); + default: + return <>{location.name}; + } +} + +export function StoredPlaceName({ + location, + withDetails = true +}: { + location: UserLocation; + withDetails?: boolean; +}): React.ReactElement { + let detailText; + if (withDetails) { + if (location.type === "home" || location.type === "work") { + detailText = location.name; + } else if (location.type === "stop") { + detailText = location.id; + } + // The case below for recent searches is not currently being used. + // } else if (location.type === "recent" && location.timestamp) { + // detailText = moment(location.timestamp).fromNow(); + } + + return detailText && detailText !== "" ? ( + + }} + /> + ) : ( + + ); +} diff --git a/packages/route-viewer-overlay/package.json b/packages/route-viewer-overlay/package.json index 2506481be..c83327bbd 100644 --- a/packages/route-viewer-overlay/package.json +++ b/packages/route-viewer-overlay/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@mapbox/polyline": "^1.1.0", - "@opentripplanner/core-utils": "^4.5.0", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "point-in-polygon": "^1.1.0", "prop-types": "^15.7.2" }, diff --git a/packages/stop-viewer-overlay/package.json b/packages/stop-viewer-overlay/package.json index 771505184..5db300ed7 100644 --- a/packages/stop-viewer-overlay/package.json +++ b/packages/stop-viewer-overlay/package.json @@ -18,7 +18,7 @@ "url": "https://github.com/opentripplanner/otp-ui/issues" }, "dependencies": { - "@opentripplanner/core-utils": "^4.5.0", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "prop-types": "^15.7.2" }, "peerDependencies": { diff --git a/packages/transit-vehicle-overlay/i18n/en-US.yml b/packages/transit-vehicle-overlay/i18n/en-US.yml index 05d3e244b..7f344f1c2 100644 --- a/packages/transit-vehicle-overlay/i18n/en-US.yml +++ b/packages/transit-vehicle-overlay/i18n/en-US.yml @@ -12,12 +12,19 @@ otpUi: TransitVehicleOverlay: date: "Date: {date}" durationAgo: "{duration} ago" + durationWithSeconds: "{hours, plural, + =0 {} + other {# hr }}{minutes, plural, + =0 {{seconds, plural, =0 {# min} other {}}} + other {# min}}{seconds, plural, + =0 {} + other { # sec}}" genericRouteFormat: "Line {route}" lastSeen: "Last seen: {durationText}" status: "Status: {status}" statusEnRoute: "en-route to stop #{stopId}" statusAtStart: "start route at stop #{stopId}" - statusAtStop: "at stop #${stopId}" + statusAtStop: "at stop #{stopId}" statusUnknown: unknown tooltipRouteLabel: "{routeLabel}:" trackStart: Track Vehicle diff --git a/packages/transit-vehicle-overlay/i18n/fr.yml b/packages/transit-vehicle-overlay/i18n/fr.yml index 481a3d48b..3c77eb5ff 100644 --- a/packages/transit-vehicle-overlay/i18n/fr.yml +++ b/packages/transit-vehicle-overlay/i18n/fr.yml @@ -12,6 +12,13 @@ otpUi: TransitVehicleOverlay: date: "Date : {date}" durationAgo: "il y a {duration}" + durationWithSeconds: "{hours, plural, + =0 {} + other {# hr }}{minutes, plural, + =0 {{seconds, plural, =0 {# mn} other {}}} + other {# mn}}{seconds, plural, + =0 {} + other { # s}}" genericRouteFormat: "Ligne {route}" lastSeen: Mis à jour {durationText} status: "État : {status}" diff --git a/packages/transit-vehicle-overlay/package.json b/packages/transit-vehicle-overlay/package.json index 458edac1a..87e70793c 100644 --- a/packages/transit-vehicle-overlay/package.json +++ b/packages/transit-vehicle-overlay/package.json @@ -9,7 +9,7 @@ "module": "esm/index.js", "private": false, "dependencies": { - "@opentripplanner/core-utils": "^4.5.0", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "@opentripplanner/icons": "^1.2.1", "@opentripplanner/zoom-based-markers": "^1.2.1", "@turf/helpers": "^6.5.0", diff --git a/packages/transit-vehicle-overlay/src/components/popups/CustomTooltip/index.js b/packages/transit-vehicle-overlay/src/components/popups/CustomTooltip/index.js index 6b57046bc..1c800a3f9 100644 --- a/packages/transit-vehicle-overlay/src/components/popups/CustomTooltip/index.js +++ b/packages/transit-vehicle-overlay/src/components/popups/CustomTooltip/index.js @@ -2,6 +2,7 @@ /* eslint-disable react/forbid-prop-types */ import React from "react"; import PropTypes from "prop-types"; +import { useIntl } from "react-intl"; import { Tooltip } from "react-leaflet"; import L from "leaflet"; @@ -19,10 +20,13 @@ export default function CustomTooltip(props) { permanent, direction } = props; + const intl = useIntl(); // note: only build tooltip content if we're about to render it on a tooltip let tooltipContent = null; - if (isTracked || allMarkers) tooltipContent = getContent(vehicle, isTracked); + if (isTracked || allMarkers) { + tooltipContent = getContent(vehicle, isTracked, intl); + } // the custom "rotation" tooltip orientation is either top or bottom let dir = direction; diff --git a/packages/transit-vehicle-overlay/src/components/popups/VehiclePopup/index.js b/packages/transit-vehicle-overlay/src/components/popups/VehiclePopup/index.js index 450f8d90d..d440787d5 100644 --- a/packages/transit-vehicle-overlay/src/components/popups/VehiclePopup/index.js +++ b/packages/transit-vehicle-overlay/src/components/popups/VehiclePopup/index.js @@ -1,6 +1,5 @@ // Removed as core-utils is typescripted. TODO: Remove when typescripting! /* eslint-disable react/forbid-prop-types */ -import coreUtils from "@opentripplanner/core-utils"; import React from "react"; import PropTypes from "prop-types"; import { FormattedDate, FormattedMessage } from "react-intl"; @@ -9,8 +8,7 @@ import { Popup } from "react-leaflet"; import { PopupStyle } from "../styled"; import VehicleTracker from "../vehicle-tracker"; import { defaultMessages, linterIgnoreTheseProps } from "../../../utils"; - -const { formatDurationWithSeconds } = coreUtils.time; +import FormattedDurationWithSeconds from "../../../utils/formatted-duration-with-seconds"; /** * view component for vehicle marker popup @@ -108,8 +106,7 @@ export default function VehiclePopup({ isTracked, setTracked, vehicle }) { description="Text describing a past duration" id="otpUi.TransitVehicleOverlay.durationAgo" values={{ - // FIXME: also localize formatDurationWithSeconds - duration: formatDurationWithSeconds(seconds) + duration: }} /> ) diff --git a/packages/transit-vehicle-overlay/src/components/popups/VehicleTooltip/index.js b/packages/transit-vehicle-overlay/src/components/popups/VehicleTooltip/index.js index 5e3b2f5f2..848af1508 100644 --- a/packages/transit-vehicle-overlay/src/components/popups/VehicleTooltip/index.js +++ b/packages/transit-vehicle-overlay/src/components/popups/VehicleTooltip/index.js @@ -1,6 +1,5 @@ // Removed as core-utils is typescripted. TODO: Remove when typescripting! /* eslint-disable react/forbid-prop-types */ -import coreUtils from "@opentripplanner/core-utils"; import React from "react"; import PropTypes from "prop-types"; import { FormattedMessage } from "react-intl"; @@ -9,8 +8,7 @@ import L from "leaflet"; import { TooltipStyle } from "../styled"; import { defaultMessages, linterIgnoreTheseProps } from "../../../utils"; - -const { formatDurationWithSeconds } = coreUtils.time; +import FormattedDurationWithSeconds from "../../../utils/formatted-duration-with-seconds"; /** will show a (leaflet) map tooltip on a vehicle, showing route and update recency */ export default function VehicleTooltip(props) { @@ -61,8 +59,7 @@ export default function VehicleTooltip(props) { description="Text describing a past duration" id="otpUi.TransitVehicleOverlay.durationAgo" values={{ - // FIXME: also localize formatDurationWithSeconds - duration: formatDurationWithSeconds(seconds) + duration: }} /> diff --git a/packages/transit-vehicle-overlay/src/index.story.js b/packages/transit-vehicle-overlay/src/index.story.js index a8869d57f..619e00df5 100644 --- a/packages/transit-vehicle-overlay/src/index.story.js +++ b/packages/transit-vehicle-overlay/src/index.story.js @@ -1,6 +1,5 @@ // FIXME: refactor all these stories to 1) remove knobs (deprecated) and 2) un-disable them (remove invalid useState()) import BaseMap from "@opentripplanner/base-map"; -import coreUtils from "@opentripplanner/core-utils"; import React from "react"; import { action } from "@storybook/addon-actions"; @@ -22,6 +21,7 @@ import VehicleTooltip from "./components/popups/VehicleTooltip"; import VehiclePopup from "./components/popups/VehiclePopup"; import * as utils from "./utils"; +import FormattedDurationWithSeconds from "./utils/formatted-duration-with-seconds"; import * as proprietary from "../__mocks__/proprietaryFetchUtils"; const geom = require("../__mocks__/lineGeom100.json"); @@ -152,25 +152,21 @@ function rectangles(popup = true) { } }; - // silly function used to change the arrival time (tooltip) in this example - function makeRandomDate() { + // tooltip content callback function + function getTooltipContent(vehicle, isTracked) { + utils.linterIgnoreTheseProps(isTracked); + // Randomly change the arrival time (tooltip) in this example const secs = Date.now() % 379; - const prettyDate = coreUtils.time.formatDurationWithSeconds(secs); - return prettyDate; + const prettyDate = ; + return ( + <> + {vehicle && vehicle.routeShortName ? vehicle.routeShortName : "Vehicle"}{" "} + is arriving in {prettyDate} + + ); } - // tooltip content callback function - CustomTooltip.defaultProps.getContent = (vehicle, isTracked) => { - utils.linterIgnoreTheseProps(isTracked); - const prettyDate = makeRandomDate(); - let retVal; - if (vehicle && vehicle.routeShortName) { - retVal = `${vehicle.routeShortName} is arriving in ${prettyDate}`; - } else { - retVal = `Vehicle is arriving in ${prettyDate}`; - } - return retVal; - }; + CustomTooltip.defaultProps.getContent = getTooltipContent; // if there's a popup, place the tooltip on bottom of marker (since popup opens on top) CustomTooltip.defaultProps.direction = popup ? "bottom" : "rotation"; diff --git a/packages/transit-vehicle-overlay/src/utils/formatted-duration-with-seconds.tsx b/packages/transit-vehicle-overlay/src/utils/formatted-duration-with-seconds.tsx new file mode 100644 index 000000000..ed6ac916e --- /dev/null +++ b/packages/transit-vehicle-overlay/src/utils/formatted-duration-with-seconds.tsx @@ -0,0 +1,25 @@ +import coreUtils from "@opentripplanner/core-utils"; +import React from "react"; +import { FormattedMessage } from "react-intl"; + +import defaultMessages from "./default-messages"; + +/** + * Formats hours/minutes/seconds. + */ +export default function FormattedDurationWithSeconds({ + seconds +}: { + seconds: number; +}): React.ReactElement { + return ( + + ); +} diff --git a/packages/transitive-overlay/package.json b/packages/transitive-overlay/package.json index bbcfc2a2c..358bdd7a2 100644 --- a/packages/transitive-overlay/package.json +++ b/packages/transitive-overlay/package.json @@ -19,7 +19,7 @@ }, "dependencies": { "@opentripplanner/itinerary-body": "^4.0.0", - "@opentripplanner/core-utils": "^5.0.1", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "lodash.isequal": "^4.5.0", "transitive-js": "^0.14.1" }, diff --git a/packages/trip-details/package.json b/packages/trip-details/package.json index 496b628ac..dcc3f29d1 100644 --- a/packages/trip-details/package.json +++ b/packages/trip-details/package.json @@ -11,13 +11,13 @@ "license": "MIT", "private": false, "dependencies": { - "@opentripplanner/core-utils": "^5.0.1", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "@styled-icons/fa-solid": "^10.34.0", "flat": "^5.0.2", "velocity-react": "^1.4.3" }, "devDependencies": { - "@opentripplanner/types": "^2.0.0", + "@opentripplanner/types": "^3.0.0-alpha.4", "@types/flat": "^5.0.2" }, "peerDependencies": { diff --git a/packages/trip-details/src/index.tsx b/packages/trip-details/src/index.tsx index 15b1b4b0d..61f14550a 100644 --- a/packages/trip-details/src/index.tsx +++ b/packages/trip-details/src/index.tsx @@ -111,7 +111,7 @@ export function TripDetails({ }: TripDetailsProps): ReactElement { // process the transit fare const fareResult = coreUtils.itinerary.calculateTncFares(itinerary); - const { maxTNCFare, minTNCFare, tncCurrencyCode } = fareResult; + const { currencyCode, maxTNCFare, minTNCFare } = fareResult; const transitFares = itinerary?.fare?.fare; const fareDetails = itinerary.fare?.details; @@ -195,8 +195,8 @@ export function TripDetails({ {companies.toLowerCase()} ), - maxTNCFare: renderFare(tncCurrencyCode, maxTNCFare), - minTNCFare: renderFare(tncCurrencyCode, minTNCFare), + maxTNCFare: renderFare(currencyCode, maxTNCFare), + minTNCFare: renderFare(currencyCode, minTNCFare), strong: boldText }} /> diff --git a/packages/trip-form/package.json b/packages/trip-form/package.json index 4f820e8c7..5ac02fc3c 100644 --- a/packages/trip-form/package.json +++ b/packages/trip-form/package.json @@ -10,14 +10,14 @@ "types": "lib/index.d.ts", "private": false, "dependencies": { - "@opentripplanner/core-utils": "^4.11.2", + "@opentripplanner/core-utils": "^7.0.0-alpha.3", "@opentripplanner/icons": "^1.2.2", "@styled-icons/bootstrap": "^10.34.0", "@styled-icons/boxicons-regular": "^10.38.0", "@styled-icons/fa-regular": "^10.34.0", "@styled-icons/fa-solid": "^10.34.0", + "date-fns": "^2.28.0", "flat": "^5.0.2", - "moment": "^2.17.1", "react-indiana-drag-scroll": "^2.0.1", "react-inlinesvg": "^2.3.0" }, diff --git a/packages/trip-form/src/DateTimeSelector/index.tsx b/packages/trip-form/src/DateTimeSelector/index.tsx index 276287f33..5cf39ceda 100644 --- a/packages/trip-form/src/DateTimeSelector/index.tsx +++ b/packages/trip-form/src/DateTimeSelector/index.tsx @@ -1,6 +1,6 @@ import CSS from "csstype"; +import { format, parse } from "date-fns"; import flatten from "flat"; -import moment from "moment"; import coreUtils from "@opentripplanner/core-utils"; import React, { ChangeEvent, ReactElement, ReactNode, useCallback } from "react"; import { FormattedMessage } from "react-intl"; @@ -96,6 +96,11 @@ function isInputTypeSupported(type: string): boolean { const supportsDateTimeInputs = isInputTypeSupported("date") && isInputTypeSupported("time"); +/** + * Reference date for parsing. + */ +const referenceDate = new Date(); + /** * The `DateTimeSelector` component lets the OTP user chose a departure or arrival date/time. * (The departure can be right now.) @@ -150,9 +155,7 @@ export default function DateTimeSelector({ const handleTimeChangeLegacy = useCallback( (evt: ChangeEvent): void => { - const newTime = moment(evt.target.value, timeFormatLegacy).format( - OTP_API_TIME_FORMAT - ); + const newTime = format(parse(evt.target.value, timeFormatLegacy, referenceDate), OTP_API_TIME_FORMAT); handleQueryParamChange({ newTime }); }, [onQueryParamChange] @@ -160,9 +163,7 @@ export default function DateTimeSelector({ const handleDateChangeLegacy = useCallback( (evt: ChangeEvent): void => { - const newDate = moment(evt.target.value, dateFormatLegacy).format( - OTP_API_DATE_FORMAT - ); + const newDate = format(parse(evt.target.value, dateFormatLegacy, referenceDate), OTP_API_DATE_FORMAT); handleQueryParamChange({ newDate }); }, [onQueryParamChange] @@ -265,9 +266,7 @@ export default function DateTimeSelector({
= 8", "@types/node@^15.0.0": - version "15.6.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08" - integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA== +"@types/node@*", "@types/node@14 || 16 || 17", "@types/node@>= 8": + version "17.0.31" + resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d" + integrity sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q== -"@types/node@14": +"@types/node@14", "@types/node@^14.0.10": version "14.17.11" resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.11.tgz#82d266d657aec5ff01ca59f2ffaff1bb43f7bf0f" integrity sha512-n2OQ+0Bz6WEsUjrvcHD1xZ8K+Kgo4cn9/w94s1bJS690QMUWfJPW/m7CCb7gPkA1fcYwL2UpjXP/rq/Eo41m6w== -"@types/node@14 || 16 || 17": - version "17.0.31" - resolved "https://registry.yarnpkg.com/@types/node/-/node-17.0.31.tgz#a5bb84ecfa27eec5e1c802c6bbf8139bdb163a5d" - integrity sha512-AR0x5HbXGqkEx9CadRH3EBYx/VkiUgZIhP4wvPn/+5KIsgpNoyFaRlVe0Zlx9gRtg8fA06a9tskE2MSN7TcG4Q== - -"@types/node@^14.0.10": - version "14.17.1" - resolved "https://registry.yarnpkg.com/@types/node/-/node-14.17.1.tgz#5e07e0cb2ff793aa7a1b41deae76221e6166049f" - integrity sha512-/tpUyFD7meeooTRwl3sYlihx2BrJE7q9XF71EguPFIySj9B7qgnRtHsHTho+0AUm4m1SvWGm6uSncrR94q6Vtw== +"@types/node@^15.0.0": + version "15.6.1" + resolved "https://registry.yarnpkg.com/@types/node/-/node-15.6.1.tgz#32d43390d5c62c5b6ec486a9bc9c59544de39a08" + integrity sha512-7EIraBEyRHEe7CH+Fm1XvgqU6uwZN8Q7jppJGcqjROMT29qhAuuOxYB1uEY5UMYQKEmA5D+5tBnhdaPXSsLONA== "@types/normalize-package-data@^2.4.0": version "2.4.0" @@ -4863,16 +4559,7 @@ dependencies: "@types/react" "*" -"@types/react@*": - version "17.0.7" - resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.7.tgz#5f2ca73d8baee8c286e96c95df557799ac0d1996" - integrity sha512-lBc3fY20hRFQ/pXQT2XdtmpJeXZnRH8N+WPnEzEfPTzuKmaJTA7k/xGWHBaPvKceKpbf0ZnMlLWY/0sFZ5rfkw== - dependencies: - "@types/prop-types" "*" - "@types/scheduler" "*" - csstype "^3.0.2" - -"@types/react@16 || 17": +"@types/react@*", "@types/react@16 || 17": version "17.0.39" resolved "https://registry.yarnpkg.com/@types/react/-/react-17.0.39.tgz#d0f4cde092502a6db00a1cded6e6bf2abb7633ce" integrity sha512-UVavlfAxDd/AgAacMa60Azl7ygyQNRwC/DsHZmKgNvPmRR5p70AJ5Q9EAmL2NWOJmeV+vVUI4IAP7GZrN8h8Ug== @@ -5044,7 +4731,7 @@ eslint-scope "^5.1.1" eslint-utils "^3.0.0" -"@typescript-eslint/parser@^4.28.3": +"@typescript-eslint/parser@^4.28.3", "@typescript-eslint/parser@^4.4.1": version "4.29.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.29.2.tgz#1c7744f4c27aeb74610c955d3dce9250e95c370a" integrity sha512-WQ6BPf+lNuwteUuyk1jD/aHKqMQ9jrdCn7Gxt9vvBnzbpj7aWEf+aZsJ1zvTjx5zFxGCt000lsbD9tQPEL8u6g== @@ -5054,24 +4741,6 @@ "@typescript-eslint/typescript-estree" "4.29.2" debug "^4.3.1" -"@typescript-eslint/parser@^4.4.1": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/parser/-/parser-4.25.0.tgz#6b2cb6285aa3d55bfb263c650739091b0f19aceb" - integrity sha512-OZFa1SKyEJpAhDx8FcbWyX+vLwh7OEtzoo2iQaeWwxucyfbi0mT4DijbOSsTgPKzGHr6GrF2V5p/CEpUH/VBxg== - dependencies: - "@typescript-eslint/scope-manager" "4.25.0" - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/typescript-estree" "4.25.0" - debug "^4.1.1" - -"@typescript-eslint/scope-manager@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.25.0.tgz#9d86a5bcc46ef40acd03d85ad4e908e5aab8d4ca" - integrity sha512-2NElKxMb/0rya+NJG1U71BuNnp1TBd1JgzYsldsdA83h/20Tvnf/HrwhiSlNmuq6Vqa0EzidsvkTArwoq+tH6w== - dependencies: - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/visitor-keys" "4.25.0" - "@typescript-eslint/scope-manager@4.29.2": version "4.29.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/scope-manager/-/scope-manager-4.29.2.tgz#442b0f029d981fa402942715b1718ac7fcd5aa1b" @@ -5080,29 +4749,11 @@ "@typescript-eslint/types" "4.29.2" "@typescript-eslint/visitor-keys" "4.29.2" -"@typescript-eslint/types@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.25.0.tgz#0e444a5c5e3c22d7ffa5e16e0e60510b3de5af87" - integrity sha512-+CNINNvl00OkW6wEsi32wU5MhHti2J25TJsJJqgQmJu3B3dYDBcmOxcE5w9cgoM13TrdE/5ND2HoEnBohasxRQ== - "@typescript-eslint/types@4.29.2": version "4.29.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/types/-/types-4.29.2.tgz#fc0489c6b89773f99109fb0aa0aaddff21f52fcd" integrity sha512-K6ApnEXId+WTGxqnda8z4LhNMa/pZmbTFkDxEBLQAbhLZL50DjeY0VIDCml/0Y3FlcbqXZrABqrcKxq+n0LwzQ== -"@typescript-eslint/typescript-estree@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.25.0.tgz#942e4e25888736bff5b360d9b0b61e013d0cfa25" - integrity sha512-1B8U07TGNAFMxZbSpF6jqiDs1cVGO0izVkf18Q/SPcUAc9LhHxzvSowXDTvkHMWUVuPpagupaW63gB6ahTXVlg== - dependencies: - "@typescript-eslint/types" "4.25.0" - "@typescript-eslint/visitor-keys" "4.25.0" - debug "^4.1.1" - globby "^11.0.1" - is-glob "^4.0.1" - semver "^7.3.2" - tsutils "^3.17.1" - "@typescript-eslint/typescript-estree@4.29.2": version "4.29.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/typescript-estree/-/typescript-estree-4.29.2.tgz#a0ea8b98b274adbb2577100ba545ddf8bf7dc219" @@ -5116,14 +4767,6 @@ semver "^7.3.5" tsutils "^3.21.0" -"@typescript-eslint/visitor-keys@4.25.0": - version "4.25.0" - resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.25.0.tgz#863e7ed23da4287c5b469b13223255d0fde6aaa7" - integrity sha512-AmkqV9dDJVKP/TcZrbf6s6i1zYXt5Hl8qOLrRDTFfRNae4+LB8A4N3i+FLZPW85zIxRy39BgeWOfMS3HoH5ngg== - dependencies: - "@typescript-eslint/types" "4.25.0" - eslint-visitor-keys "^2.0.0" - "@typescript-eslint/visitor-keys@4.29.2": version "4.29.2" resolved "https://registry.yarnpkg.com/@typescript-eslint/visitor-keys/-/visitor-keys-4.29.2.tgz#d2da7341f3519486f50655159f4e5ecdcb2cd1df" @@ -5142,17 +4785,6 @@ estree-walker "^2.0.2" source-map "^0.6.1" -"@vue/compiler-core@3.2.4", "@vue/compiler-core@^3.0.5": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@vue/compiler-core/-/compiler-core-3.2.4.tgz#a98d295771998c1e8dccc4ee3d52feb14b02aea9" - integrity sha512-c8NuQq7mUXXxA4iqD5VUKpyVeklK53+DMbojYMyZ0VPPrb0BUWrZWFiqSDT+MFDv0f6Hv3QuLiHWb1BWMXBbrw== - dependencies: - "@babel/parser" "^7.12.0" - "@babel/types" "^7.12.0" - "@vue/shared" "3.2.4" - estree-walker "^2.0.1" - source-map "^0.6.1" - "@vue/compiler-dom@3.2.33": version "3.2.33" resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.33.tgz#6db84296f949f18e5d3e7fd5e80f943dbed7d5ec" @@ -5161,14 +4793,6 @@ "@vue/compiler-core" "3.2.33" "@vue/shared" "3.2.33" -"@vue/compiler-dom@3.2.4": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@vue/compiler-dom/-/compiler-dom-3.2.4.tgz#3a43de243eba127abbe57e796a0b969d2df78c08" - integrity sha512-uj1nwO4794fw2YsYas5QT+FU/YGrXbS0Qk+1c7Kp1kV7idhZIghWLTjyvYibpGoseFbYLPd+sW2/noJG5H04EQ== - dependencies: - "@vue/compiler-core" "3.2.4" - "@vue/shared" "3.2.4" - "@vue/compiler-sfc@3.2.33": version "3.2.33" resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.33.tgz#7ce01dc947a8b76c099811dc6ca58494d4dc773d" @@ -5185,29 +4809,6 @@ postcss "^8.1.10" source-map "^0.6.1" -"@vue/compiler-sfc@^3.0.5": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@vue/compiler-sfc/-/compiler-sfc-3.2.4.tgz#9807868cc950291f163c3930a81bb16e870df097" - integrity sha512-GM+ouDdDzhqgkLmBH4bgq4kiZxJQArSppJiZHWHIx9XRaefHLmc1LBNPmN8ivm4SVfi2i7M2t9k8ZnjsScgzPQ== - dependencies: - "@babel/parser" "^7.13.9" - "@babel/types" "^7.13.0" - "@types/estree" "^0.0.48" - "@vue/compiler-core" "3.2.4" - "@vue/compiler-dom" "3.2.4" - "@vue/compiler-ssr" "3.2.4" - "@vue/shared" "3.2.4" - consolidate "^0.16.0" - estree-walker "^2.0.1" - hash-sum "^2.0.0" - lru-cache "^5.1.1" - magic-string "^0.25.7" - merge-source-map "^1.1.0" - postcss "^8.1.10" - postcss-modules "^4.0.0" - postcss-selector-parser "^6.0.4" - source-map "^0.6.1" - "@vue/compiler-ssr@3.2.33": version "3.2.33" resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.33.tgz#3e820267e4eea48fde9519f006dedca3f5e42e71" @@ -5216,14 +4817,6 @@ "@vue/compiler-dom" "3.2.33" "@vue/shared" "3.2.33" -"@vue/compiler-ssr@3.2.4": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@vue/compiler-ssr/-/compiler-ssr-3.2.4.tgz#be51f219c2042b3e530373e60bc126ada6bb1cc0" - integrity sha512-bKZuXu9/4XwsFHFWIKQK+5kN7mxIIWmMmT2L4VVek7cvY/vm3p4WTsXYDGZJy0htOTXvM2ifr6sflg012T0hsw== - dependencies: - "@vue/compiler-dom" "3.2.4" - "@vue/shared" "3.2.4" - "@vue/reactivity-transform@3.2.33": version "3.2.33" resolved "https://registry.yarnpkg.com/@vue/reactivity-transform/-/reactivity-transform-3.2.33.tgz#286063f44ca56150ae9b52f8346a26e5913fa699" @@ -5272,11 +4865,6 @@ resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.33.tgz#69a8c99ceb37c1b031d5cc4aec2ff1dc77e1161e" integrity sha512-UBc1Pg1T3yZ97vsA2ueER0F6GbJebLHYlEi4ou1H5YL4KWvMOOWwpYo9/QpWq93wxKG6Wo13IY74Hcn/f7c7Bg== -"@vue/shared@3.2.4": - version "3.2.4" - resolved "https://registry.yarnpkg.com/@vue/shared/-/shared-3.2.4.tgz#ba2a09527afff27b28d08f921b4a597e9504ca7a" - integrity sha512-j2j1MRmjalVKr3YBTxl/BClSIc8UQ8NnPpLYclxerK65JIowI4O7n8O8lElveEtEoHxy1d7BelPUDI0Q4bumqg== - "@webassemblyjs/ast@1.9.0": version "1.9.0" resolved "https://registry.yarnpkg.com/@webassemblyjs/ast/-/ast-1.9.0.tgz#bd850604b4042459a5a41cd7d338cbed695ed964" @@ -5701,12 +5289,7 @@ 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-regex@^5.0.1: +ansi-regex@^5.0.0, ansi-regex@^5.0.1: version "5.0.1" resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-5.0.1.tgz#082cb2c89c9fe8659a311a53bd6a4dc5301db304" integrity sha512-quJQXlTSUGL2LH9SUXo8VwsY4soanhgo6LNSm84E1LBcE8s3O0wpdiRzyR9z/ZZJMlMWv37qOOb9pdJlMUEKFQ== @@ -6111,12 +5694,7 @@ aws4@^1.8.0: resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.11.0.tgz#d61f46d83b2519250e2784daf5b09479a8b41c59" integrity sha512-xh1Rl34h6Fi1DC2WWKfxUTVqRsNnr6LsKz2+hfwDxQJWmrx8+c7ylaqBMcHfl1U1r2dsifOvKX3LQuLNZ+XSvA== -axe-core@^4.2.0: - version "4.3.1" - resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.1.tgz#0c6a076e4a1c3e0544ba6a9479158f9be7a7928e" - integrity sha512-3WVgVPs/7OnKU3s+lqMtkv3wQlg3WxK1YifmpJSDO0E1aPBrZWlrrTO6cxRqCXLuX2aYgCljqXIQd0VnRidV0g== - -axe-core@^4.2.3: +axe-core@^4.2.0, axe-core@^4.2.3: version "4.3.2" resolved "https://registry.yarnpkg.com/axe-core/-/axe-core-4.3.2.tgz#fcf8777b82c62cfc69c7e9f32c0d2226287680e7" integrity sha512-5LMaDRWm8ZFPAEdzTYmgjjEdj1YnQcpfrVajO/sn/LhbpGp0Y0H64c2hLZI1gRMxfA+w1S71Uc/nHaOXgcCvGg== @@ -6372,7 +5950,7 @@ babel-loader@^6.2.1: mkdirp "^0.5.1" object-assign "^4.0.1" -babel-loader@^8.0.0: +babel-loader@^8.0.0, babel-loader@^8.0.6: version "8.2.3" resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.3.tgz#8986b40f1a64cacfcb4b8429320085ef68b1342d" integrity sha512-n4Zeta8NC3QAsuyiizu0GkmRcQ6clkV9WFUnUf1iXP//IeSKbWjofW3UHyZVwlOB4y039YQKefawyTn64Zwbuw== @@ -6382,16 +5960,6 @@ babel-loader@^8.0.0: make-dir "^3.1.0" schema-utils "^2.6.5" -babel-loader@^8.0.6: - version "8.2.2" - resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-8.2.2.tgz#9363ce84c10c9a40e6c753748e1441b60c8a0b81" - integrity sha512-JvTd0/D889PQBtUXJ2PXaKU/pjZDMtHA9V2ecm+eNRmmBCMR09a+fmpGTNwnJtFmFl5Ei7Vy47LjBb+L0wQ99g== - dependencies: - find-cache-dir "^3.3.1" - loader-utils "^1.4.0" - make-dir "^3.1.0" - schema-utils "^2.6.5" - babel-messages@^6.23.0: version "6.23.0" resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" @@ -6500,16 +6068,7 @@ babel-plugin-named-asset-import@^0.3.1: resolved "https://registry.yarnpkg.com/babel-plugin-named-asset-import/-/babel-plugin-named-asset-import-0.3.7.tgz#156cd55d3f1228a5765774340937afc8398067dd" integrity sha512-squySRkf+6JGnvjoUtDEjSREJEBirnXi9NqP6rjSYsylxQxqBTz+pkmf395i9E2zsvmYUaI40BHo6SqZUdydlw== -babel-plugin-polyfill-corejs2@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.1.tgz#ae2cf6d6f1aa7c0edcf04a25180e8856a6d1184f" - integrity sha512-hXGSPbr6IbjeMyGew+3uGIAkRjBFSOJ9FLDZNOfHuyJZCcoia4nd/72J0bSgvfytcVfUcP/dxEVcUhVJuQRtSw== - dependencies: - "@babel/compat-data" "^7.13.11" - "@babel/helper-define-polyfill-provider" "^0.2.1" - semver "^6.1.1" - -babel-plugin-polyfill-corejs2@^0.2.2: +babel-plugin-polyfill-corejs2@^0.2.0, babel-plugin-polyfill-corejs2@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs2/-/babel-plugin-polyfill-corejs2-0.2.2.tgz#e9124785e6fd94f94b618a7954e5693053bf5327" integrity sha512-kISrENsJ0z5dNPq5eRvcctITNHYXWOA4DUZRFYCz3jYCcvTb/A546LIddmoGNMVYg2U38OyFeNosQwI9ENTqIQ== @@ -6526,15 +6085,7 @@ babel-plugin-polyfill-corejs3@^0.1.0: "@babel/helper-define-polyfill-provider" "^0.1.5" core-js-compat "^3.8.1" -babel-plugin-polyfill-corejs3@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.1.tgz#786f40218040030f0edecfd48e6e59f1ee9bef53" - integrity sha512-WZCqF3DLUhdTD/P381MDJfuP18hdCZ+iqJ+wHtzhWENpsiof284JJ1tMQg1CE+hfCWyG48F7e5gDMk2c3Laz7w== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.1" - core-js-compat "^3.9.1" - -babel-plugin-polyfill-corejs3@^0.2.2: +babel-plugin-polyfill-corejs3@^0.2.0, babel-plugin-polyfill-corejs3@^0.2.2: version "0.2.3" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-corejs3/-/babel-plugin-polyfill-corejs3-0.2.3.tgz#72add68cf08a8bf139ba6e6dfc0b1d504098e57b" integrity sha512-rCOFzEIJpJEAU14XCcV/erIf/wZQMmMT5l5vXOpL5uoznyOGfDIjPj6FVytMvtzaKSTSVKouOCTPJ5OMUZH30g== @@ -6542,14 +6093,7 @@ babel-plugin-polyfill-corejs3@^0.2.2: "@babel/helper-define-polyfill-provider" "^0.2.2" core-js-compat "^3.14.0" -babel-plugin-polyfill-regenerator@^0.2.0: - version "0.2.1" - resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.1.tgz#ca9595d7d5f3afefec2d83126148b90db751a091" - integrity sha512-T3bYyL3Sll2EtC94v3f+fA8M28q7YPTOZdB++SRHjvYZTvtd+WorMUq3tDTD4Q7Kjk1LG0gGromslKjcO5p2TA== - dependencies: - "@babel/helper-define-polyfill-provider" "^0.2.1" - -babel-plugin-polyfill-regenerator@^0.2.2: +babel-plugin-polyfill-regenerator@^0.2.0, babel-plugin-polyfill-regenerator@^0.2.2: version "0.2.2" resolved "https://registry.yarnpkg.com/babel-plugin-polyfill-regenerator/-/babel-plugin-polyfill-regenerator-0.2.2.tgz#b310c8d642acada348c1fa3b3e6ce0e851bee077" integrity sha512-Goy5ghsc21HgPDFtzRkSirpZVW35meGoTmTOb2bxqdl60ghub4xOidgNTHaZfQ2FaxQsKmwvXtOAkcIS4SMBWg== @@ -6565,7 +6109,7 @@ babel-plugin-react-docgen@^4.2.1: lodash "^4.17.15" react-docgen "^5.0.0" -"babel-plugin-styled-components@>= 1.12.0": +"babel-plugin-styled-components@>= 1.12.0", babel-plugin-styled-components@^1.10.0: version "1.13.2" resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.13.2.tgz#ebe0e6deff51d7f93fceda1819e9b96aeb88278d" integrity sha512-Vb1R3d4g+MUfPQPVDMCGjm3cDocJEUTR7Xq7QS95JWWeksN1wdFRYpD2kulDgI3Huuaf1CZd+NK4KQmqUFh5dA== @@ -6575,16 +6119,6 @@ babel-plugin-react-docgen@^4.2.1: babel-plugin-syntax-jsx "^6.18.0" lodash "^4.17.11" -babel-plugin-styled-components@^1.10.0: - version "1.12.0" - resolved "https://registry.yarnpkg.com/babel-plugin-styled-components/-/babel-plugin-styled-components-1.12.0.tgz#1dec1676512177de6b827211e9eda5a30db4f9b9" - integrity sha512-FEiD7l5ZABdJPpLssKXjBUJMYqzbcNzBowfXDCdJhOpbhWiewapUaY+LZGT8R4Jg2TwOjGjG4RKeyrO5p9sBkA== - dependencies: - "@babel/helper-annotate-as-pure" "^7.0.0" - "@babel/helper-module-imports" "^7.0.0" - babel-plugin-syntax-jsx "^6.18.0" - lodash "^4.17.11" - babel-plugin-syntax-async-functions@^6.8.0: version "6.13.0" resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" @@ -7213,7 +6747,7 @@ bl@^4.0.3, bl@^4.1.0: inherits "^2.0.4" readable-stream "^3.4.0" -bluebird@^3.3.5, bluebird@^3.5.1, bluebird@^3.5.3, bluebird@^3.5.5, bluebird@^3.7.2: +bluebird@^3.3.5, 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" integrity sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg== @@ -7762,15 +7296,7 @@ chalk@^2.0.0, chalk@^2.0.1, chalk@^2.3.1, chalk@^2.3.2, chalk@^2.4.1, chalk@^2.4 escape-string-regexp "^1.0.5" supports-color "^5.3.0" -chalk@^4.0.0, chalk@^4.1.0: - version "4.1.1" - resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.1.tgz#c80b3fab28bf6371e6863325eee67e618b77e6ad" - integrity sha512-diHzdDKxcU+bAsUboHLPEDQiw0qEe0qd7SYUn3HgcFlWgbDcfLGswOHYeGrHKzG9z6UYf01d9VFMfZxPM1xZSg== - dependencies: - ansi-styles "^4.1.0" - supports-color "^7.1.0" - -chalk@^4.1.1: +chalk@^4.0.0, chalk@^4.1.0, chalk@^4.1.1: version "4.1.2" resolved "https://registry.yarnpkg.com/chalk/-/chalk-4.1.2.tgz#aac4e2b7734a740867aeb16bf02aad556a1e7a01" integrity sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA== @@ -7954,17 +7480,7 @@ cli-spinners@^2.5.0: resolved "https://registry.yarnpkg.com/cli-spinners/-/cli-spinners-2.6.0.tgz#36c7dc98fb6a9a76bd6238ec3f77e2425627e939" integrity sha512-t+4/y50K/+4xcCRosKkA7W4gTr1MySvLV0q+PxmG7FJ5g+66ChKurYjxBCjHggHH3HA5Hh9cy+lcUGWDqVH+4Q== -cli-table3@^0.6.0: - version "0.6.0" - resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.0.tgz#b7b1bc65ca8e7b5cef9124e13dc2b21e2ce4faee" - integrity sha512-gnB85c3MGC7Nm9I/FkiasNBOKjOiO1RNuXXarQms37q4QMpWdlbBgD/VnOStA2faG1dpXMv31RFApjX1/QdgWQ== - dependencies: - object-assign "^4.1.0" - string-width "^4.2.0" - optionalDependencies: - colors "^1.1.2" - -cli-table3@^0.6.1: +cli-table3@^0.6.0, cli-table3@^0.6.1: version "0.6.1" resolved "https://registry.yarnpkg.com/cli-table3/-/cli-table3-0.6.1.tgz#36ce9b7af4847f288d3cdd081fbd09bf7bd237b8" integrity sha512-w0q/enDHhPLq44ovMGdQeeDLvwxwavsJX7oQGYt/LrBlYsyaxyDnp6z3QzFut/6kLLKnlcUVJLrpB7KBfgG/RA== @@ -8174,7 +7690,7 @@ colors@1.0.3: resolved "https://registry.yarnpkg.com/colors/-/colors-1.0.3.tgz#0433f44d809680fdeb60ed260f1b0c262e82a40b" integrity sha1-BDP0TYCWgP3rYO0mDxsMJi6CpAs= -colors@1.4.0, colors@^1.1.2: +colors@1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/colors/-/colors-1.4.0.tgz#c50491479d4c1bdaed2c9ced32cf7c7dc2360f78" integrity sha512-a+UqTh4kgZg/SlGvfbzDHpgRu7AAQOmmqRHJnxhRZICKFUT91brVhNNt58CMWU9PsBbv3PDCZUHbVxuDiH2mtA== @@ -8348,13 +7864,6 @@ console-control-strings@^1.0.0, console-control-strings@^1.1.0, console-control- resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" integrity sha1-PXz0Rk22RG6mRL9LOVB/mFEAjo4= -consolidate@^0.16.0: - version "0.16.0" - resolved "https://registry.yarnpkg.com/consolidate/-/consolidate-0.16.0.tgz#a11864768930f2f19431660a65906668f5fbdc16" - integrity sha512-Nhl1wzCslqXYTJVDyJCu3ODohy9OfBMB5uD2BiBTzd7w+QY0lBzafkR8y8755yMYHAaMD4NuzbAw03/xzfw+eQ== - dependencies: - bluebird "^3.7.2" - constants-browserify@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" @@ -8501,7 +8010,7 @@ copy-to-clipboard@^3.3.1: dependencies: toggle-selection "^1.0.6" -core-js-compat@^3.14.0: +core-js-compat@^3.14.0, core-js-compat@^3.8.1, core-js-compat@^3.9.0: version "3.15.2" resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.15.2.tgz#47272fbb479880de14b4e6081f71f3492f5bd3cb" integrity sha512-Wp+BJVvwopjI+A1EFqm2dwUmWYXrvucmtIB2LgXn/Rb+gWPKYxtmb4GKHGKG/KGF1eK9jfjzT38DITbTOCX/SQ== @@ -8509,24 +8018,11 @@ core-js-compat@^3.14.0: browserslist "^4.16.6" semver "7.0.0" -core-js-compat@^3.8.1, core-js-compat@^3.9.0, core-js-compat@^3.9.1: - version "3.13.0" - resolved "https://registry.yarnpkg.com/core-js-compat/-/core-js-compat-3.13.0.tgz#a88f5fa81d8e9b15d7f98abc4447a4dfca2a358f" - integrity sha512-jhbI2zpVskgfDC9mGRaDo1gagd0E0i/kYW0+WvibL/rafEHKAHO653hEXIxJHqRlRLITluXtRH3AGTL5qJmifQ== - dependencies: - browserslist "^4.16.6" - semver "7.0.0" - -core-js-pure@^3.8.1: +core-js-pure@^3.8.1, core-js-pure@^3.8.2: version "3.21.1" resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.21.1.tgz#8c4d1e78839f5f46208de7230cebfb72bc3bdb51" integrity sha512-12VZfFIu+wyVbBebyHmRTuEE/tZrB4tJToWcwAMcsp3h4+sHR+fMJWbKpYiCRWlhFBq+KNyO8rIV9rTkeVmznQ== -core-js-pure@^3.8.2: - version "3.13.0" - resolved "https://registry.yarnpkg.com/core-js-pure/-/core-js-pure-3.13.0.tgz#9d267fb47d1d7046cfbc05e7b67bb235b6735355" - integrity sha512-7VTvXbsMxROvzPAVczLgfizR8CyYnvWPrb1eGrtlZAJfjQWEHLofVfCKljLHdpazTfpaziRORwUH/kfGDKvpdA== - core-js@2, core-js@^2.4.0, core-js@^2.5.0: version "2.6.12" resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" @@ -8851,12 +8347,7 @@ cssstyle@^1.0.0: dependencies: cssom "0.3.x" -csstype@^2.5.7: - version "2.6.17" - resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.17.tgz#4cf30eb87e1d1a005d8b6510f95292413f6a1c0e" - integrity sha512-u1wmTI1jJGzCJzWndZo8mk4wnPTZd1eOIYTYvuEyOQGfmDl3TrabCCfKnOC86FZwW/9djqTl933UF/cS425i9A== - -csstype@^2.6.8: +csstype@^2.5.7, csstype@^2.6.8: version "2.6.20" resolved "https://registry.yarnpkg.com/csstype/-/csstype-2.6.20.tgz#9229c65ea0b260cf4d3d997cb06288e36a8d6dda" integrity sha512-/WwNkdXfckNgw6S5R125rrW8ez139lBHWouiBvX8dfMFtcn6V81REDqnH7+CRpRipfYlyU1CmOnOxrmGcFOjeA== @@ -8911,20 +8402,20 @@ data-urls@^1.0.0: whatwg-mimetype "^2.2.0" whatwg-url "^7.0.0" -date-fns-tz@^1.1.4: - version "1.1.4" - resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-1.1.4.tgz#38282c2bfab08946a4e9bb89d733451e5525048b" - integrity sha512-lQ+FF7xUxxRuRqIY7H/lagnT3PhhSnnvtGHzjE5WZKwRyLU7glJfLys05SZ7zHlEr6RXWiqkmgWq4nCkcElR+g== +date-fns-tz@^1.2.2: + version "1.3.6" + resolved "https://registry.yarnpkg.com/date-fns-tz/-/date-fns-tz-1.3.6.tgz#4195a58a2f86eda55ea69fb477f3ed8a6e2188ac" + integrity sha512-C8q7mErvG4INw1ZwAFmPlGjEo5Sv4udjKVbTc03zpP9cu6cp5AemFzKhz0V68LGcWEtX5mJudzzg3G04emIxLA== date-fns@^1.27.2: version "1.30.1" resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-1.30.1.tgz#2e71bf0b119153dbb4cc4e88d9ea5acfb50dc05c" integrity sha512-hBSVCvSmWC+QypYObzwGOd9wqdDpOt+0wl0KbU+R+uuZBS1jN8VsD1ss3irQDknRj5NvxiTF6oj/nDRnN/UQNw== -date-fns@^2.23.0: - version "2.23.0" - resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.23.0.tgz#4e886c941659af0cf7b30fafdd1eaa37e88788a9" - integrity sha512-5ycpauovVyAk0kXNZz6ZoB9AYMZB4DObse7P3BPWmyEjXNORTI8EJ6X0uaSAq4sCHzM1uajzrkr6HnsLQpxGXA== +date-fns@^2.28.0: + version "2.29.1" + resolved "https://registry.yarnpkg.com/date-fns/-/date-fns-2.29.1.tgz#9667c2615525e552b5135a3116b95b1961456e60" + integrity sha512-dlLD5rKaKxpFdnjrs+5azHDFOPEu4ANy/LTh04A1DTzMM7qoajmKCBc8pkKRFT41CNzw+4gQh79X5C+Jq27HAw== dateformat@^3.0.0: version "3.0.3" @@ -8950,7 +8441,14 @@ debug@3.1.0: dependencies: ms "2.0.0" -debug@4, debug@4.3.1, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1: +debug@4, debug@^4.0.0, debug@^4.0.1, debug@^4.1.0, debug@^4.1.1, debug@^4.3.1, debug@^4.3.2: + version "4.3.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" + integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== + dependencies: + ms "2.1.2" + +debug@4.3.1: version "4.3.1" resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.1.tgz#f0d229c505e0c6d8c49ac553d1b13dc183f6b2ee" integrity sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ== @@ -8964,13 +8462,6 @@ debug@^3.0.0, debug@^3.1.0, debug@^3.2.7: dependencies: ms "^2.1.1" -debug@^4.3.1, debug@^4.3.2: - version "4.3.2" - resolved "https://registry.yarnpkg.com/debug/-/debug-4.3.2.tgz#f0a49c18ac8779e31d4a0c6029dfb76873c7428b" - integrity sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw== - dependencies: - ms "2.1.2" - debuglog@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/debuglog/-/debuglog-1.0.1.tgz#aa24ffb9ac3df9a2351837cfb2d279360cd78492" @@ -9949,7 +9440,7 @@ estree-to-babel@^3.1.0: "@babel/types" "^7.2.0" c8 "^7.6.0" -estree-walker@^2.0.1, estree-walker@^2.0.2: +estree-walker@^2.0.2: version "2.0.2" resolved "https://registry.yarnpkg.com/estree-walker/-/estree-walker-2.0.2.tgz#52f010178c2a4c117a7757cfe942adb7d2da4cac" integrity sha512-Rfkk/Mp/DL7JVje3u18FxFujQlTNR2q6QfMSMB7AvCBx91NGj/ba3kCfza0f6dVDbw7YlRf/nDrn7pQrCCyQ/w== @@ -10240,19 +9731,7 @@ fast-glob@^2.2.6: merge2 "^1.2.3" micromatch "^3.1.10" -fast-glob@^3.1.1: - version "3.2.5" - resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.5.tgz#7939af2a656de79a4f1901903ee8adcaa7cb9661" - integrity sha512-2DtFcgT68wiTTiwZ2hNdJfcHNke9XOfnwmBRWXhmeKM8rF0TGwmC/Qto3S7RoZKp5cilZbxzO5iTNTQsJ+EeDg== - dependencies: - "@nodelib/fs.stat" "^2.0.2" - "@nodelib/fs.walk" "^1.2.3" - glob-parent "^5.1.0" - merge2 "^1.3.0" - micromatch "^4.0.2" - picomatch "^2.2.1" - -fast-glob@^3.2.7: +fast-glob@^3.1.1, fast-glob@^3.2.7: version "3.2.7" resolved "https://registry.yarnpkg.com/fast-glob/-/fast-glob-3.2.7.tgz#fd6cb7a2d7e9aa7a7846111e85a196d6b2f766a1" integrity sha512-rYGMRwip6lUMvYD3BTScMwT1HtAs2d71SMv66Vrxs0IekGZEjhM0pcMfjQPnknBt2zeCwQMEupiN02ZP4DiT1Q== @@ -10859,13 +10338,6 @@ gauge@~2.7.3: strip-ansi "^3.0.1" wide-align "^1.1.0" -generic-names@^2.0.1: - version "2.0.1" - resolved "https://registry.yarnpkg.com/generic-names/-/generic-names-2.0.1.tgz#f8a378ead2ccaa7a34f0317b05554832ae41b872" - integrity sha512-kPCHWa1m9wGG/OwQpeweTwM/PYiQLrUIxXbt/P4Nic3LbGjCP0YwrALHW1uNLKZ0LIMg+RF+XRlj2ekT9ZlZAQ== - dependencies: - loader-utils "^1.1.0" - genfun@^5.0.0: version "5.0.0" resolved "https://registry.yarnpkg.com/genfun/-/genfun-5.0.0.tgz#9dd9710a06900a5c4a5bf57aca5da4e52fe76537" @@ -11091,7 +10563,7 @@ glob-parent@^3.1.0: is-glob "^3.1.0" path-dirname "^1.0.0" -glob-parent@^5.0.0, glob-parent@^5.1.0, glob-parent@^5.1.2, glob-parent@~5.1.0: +glob-parent@^5.0.0, glob-parent@^5.1.2, glob-parent@~5.1.0: version "5.1.2" resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-5.1.2.tgz#869832c58034fe68a4093c17dc15e8340d8401c4" integrity sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow== @@ -11193,19 +10665,7 @@ globalthis@^1.0.0: dependencies: define-properties "^1.1.3" -globby@^11.0.0, globby@^11.0.1: - version "11.0.3" - resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.3.tgz#9b1f0cb523e171dd1ad8c7b2a9fb4b644b9593cb" - integrity sha512-ffdmosjA807y7+lA1NM0jELARVmYul/715xiILEjo3hBLPTcirgQNnXECn5g3mtR8TOLCVbkfua1Hpen25/Xcg== - dependencies: - array-union "^2.1.0" - dir-glob "^3.0.1" - fast-glob "^3.1.1" - ignore "^5.1.4" - merge2 "^1.3.0" - slash "^3.0.0" - -globby@^11.0.2, globby@^11.0.3: +globby@^11.0.0, globby@^11.0.1, globby@^11.0.2, globby@^11.0.3: version "11.0.4" resolved "https://registry.yarnpkg.com/globby/-/globby-11.0.4.tgz#2cbaff77c2f2a62e71e9b2813a67b97a3a3001a5" integrity sha512-9O4MVG9ioZJ08ffbcyVYyLOJLk5JQ688pJ4eMGLpdWLHq/Wr1D9BlriLQyL0E+jbkuePVZXYFj47QM/v093wHg== @@ -11407,11 +10867,6 @@ hash-base@^3.0.0: readable-stream "^3.6.0" safe-buffer "^5.2.0" -hash-sum@^2.0.0: - version "2.0.0" - resolved "https://registry.yarnpkg.com/hash-sum/-/hash-sum-2.0.0.tgz#81d01bb5de8ea4a214ad5d6ead1b523460b0b45a" - integrity sha512-WdZTbAByD+pHfl/g9QSsBIIwy8IT+EsPiKDs0KNX+zSHhdDLFKdZu0BQHljvO+0QI/BasbMSUa8wYNCZTvhslg== - hash.js@^1.0.0, hash.js@^1.0.3: version "1.1.7" resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.1.7.tgz#0babca538e8d4ee4a0f8988d68866537a003cf42" @@ -11768,11 +11223,6 @@ icss-utils@^4.0.0, icss-utils@^4.1.1: dependencies: postcss "^7.0.14" -icss-utils@^5.0.0: - version "5.1.0" - resolved "https://registry.yarnpkg.com/icss-utils/-/icss-utils-5.1.0.tgz#c6be6858abd013d768e98366ae47e25d5887b1ae" - integrity sha512-soFhflCVWLfRNOPU3iv5Z9VUdT44xFRbzjLsEzSr5AQmgqPMTHdU3PMT1Cf1ssx8fLNJDA1juftYl+PUcv3MqA== - identity-obj-proxy@^3.0.0: version "3.0.0" resolved "https://registry.yarnpkg.com/identity-obj-proxy/-/identity-obj-proxy-3.0.0.tgz#94d2bda96084453ef36fbc5aaec37e0f79f1fc14" @@ -13865,7 +13315,7 @@ loader-utils@^0.2.16, loader-utils@~0.2.2, loader-utils@~0.2.5: json5 "^0.5.0" object-assign "^4.0.1" -loader-utils@^1.0.2, loader-utils@^1.1.0, loader-utils@^1.2.3, loader-utils@^1.4.0: +loader-utils@^1.0.2, loader-utils@^1.2.3, loader-utils@^1.4.0: version "1.4.0" resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.4.0.tgz#c579b5e34cb34b1a74edc6c1fb36bfa371d5a613" integrity sha512-qH0WSMBtn/oHuwjy/NucEgbx5dbxxnxup9s4PVXJUDHZBQY+s0NWA9rJf53RBnQZxfch7euUui7hpoAPvALZdA== @@ -13934,11 +13384,6 @@ lodash.camelcase@^3.0.1: dependencies: lodash._createcompounder "^3.0.0" -lodash.camelcase@^4.3.0: - version "4.3.0" - resolved "https://registry.yarnpkg.com/lodash.camelcase/-/lodash.camelcase-4.3.0.tgz#b28aa6288a2b9fc651035c7711f65ab6190331a6" - integrity sha1-soqmKIorn8ZRA1x3EfZathkDMaY= - lodash.capitalize@^4.2.1: version "4.2.1" resolved "https://registry.yarnpkg.com/lodash.capitalize/-/lodash.capitalize-4.2.1.tgz#f826c9b4e2a8511d84e3aca29db05e1a4f3b72a9" @@ -14564,13 +14009,6 @@ merge-descriptors@1.0.1: resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" integrity sha1-sAqqVW3YtEVoFQ7J0blT8/kMu2E= -merge-source-map@^1.1.0: - version "1.1.0" - resolved "https://registry.yarnpkg.com/merge-source-map/-/merge-source-map-1.1.0.tgz#2fdde7e6020939f70906a68f2d7ae685e4c8c646" - integrity sha512-Qkcp7P2ygktpMPh2mCQZaf3jhN6D3Z/qVZHSdWvQ+2Ef5HgRAPBO57A77+ENm0CPx2+1Ce/MYKi3ymqdfuqibw== - dependencies: - source-map "^0.6.1" - merge-stream@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/merge-stream/-/merge-stream-2.0.0.tgz#52823629a14dd00c9770fb6ad47dc6310f2c1f60" @@ -14879,11 +14317,6 @@ modify-values@^1.0.0: resolved "https://registry.yarnpkg.com/modify-values/-/modify-values-1.0.1.tgz#b3939fa605546474e3e3e3c63d64bd43b4ee6022" integrity sha512-xV2bxeN6F7oYjZWTe/YPAy6MN2M+sL4u/Rlm2AHCIVGfo2p1yGmBHQ6vHehl4bRTZBdHu3TSkWdYgkwpYzAGSw== -moment@^2.17.1, moment@^2.24.0: - version "2.29.2" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.29.2.tgz#00910c60b20843bcba52d37d58c628b47b1f20e4" - integrity sha512-UgzG4rvxYpN15jgCmVJwac49h9ly9NurikMWGPdVxm8GZD6XjkKPxDTjQQ43gtGgnV3X0cAyWDdP2Wexoquifg== - move-concurrently@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/move-concurrently/-/move-concurrently-1.0.1.tgz#be2c005fda32e0b29af1f05d7c4b33214c701f92" @@ -16239,12 +15672,7 @@ 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.4, picomatch@^2.2.1, picomatch@^2.2.3: - version "2.3.0" - resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.0.tgz#f1f061de8f6a4bf022892e2d128234fb98302972" - integrity sha512-lY1Q/PiJGC2zOv/z391WOTD+Z02bCgsFfvxoXXf6h7kv9o+WmsmzYqrAwY63sNgOxE4xEdq0WyUnXfKeBrSvYw== - -picomatch@^2.3.0: +picomatch@^2.0.4, picomatch@^2.2.1, picomatch@^2.2.3, picomatch@^2.3.0: version "2.3.1" resolved "https://registry.yarnpkg.com/picomatch/-/picomatch-2.3.1.tgz#3ba3833733646d9d3e4995946c1365a67fb07a42" integrity sha512-JU3teHTNjmE2VCGFzuY8EXzCDVwEqB2a8fsIvwaStHhAWJEeVd1o1QD80CU6+ZdEXXSLbSsuLwJjkCBWqRQUVA== @@ -16590,11 +16018,6 @@ postcss-modules-extract-imports@^2.0.0: dependencies: postcss "^7.0.5" -postcss-modules-extract-imports@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-extract-imports/-/postcss-modules-extract-imports-3.0.0.tgz#cda1f047c0ae80c97dbe28c3e76a43b88025741d" - integrity sha512-bdHleFnP3kZ4NYDhuGlVK+CMrQ/pqUm8bx/oGL93K6gVwiclvX5x0n76fYMKuIGKzlABOy13zsvqjb0f92TEXw== - postcss-modules-local-by-default@^1.0.1: version "1.2.0" resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-1.2.0.tgz#f7d80c398c5a393fa7964466bd19500a7d61c069" @@ -16613,15 +16036,6 @@ postcss-modules-local-by-default@^3.0.2: postcss-selector-parser "^6.0.2" postcss-value-parser "^4.1.0" -postcss-modules-local-by-default@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-local-by-default/-/postcss-modules-local-by-default-4.0.0.tgz#ebbb54fae1598eecfdf691a02b3ff3b390a5a51c" - integrity sha512-sT7ihtmGSF9yhm6ggikHdV0hlziDTX7oFoXtuVWeDd3hHObNkcHRo9V3yg7vCAY7cONyxJC/XXCmmiHHcvX7bQ== - dependencies: - icss-utils "^5.0.0" - postcss-selector-parser "^6.0.2" - postcss-value-parser "^4.1.0" - postcss-modules-scope@^1.0.0: version "1.1.0" resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-1.1.0.tgz#d6ea64994c79f97b62a72b426fbe6056a194bb90" @@ -16638,13 +16052,6 @@ postcss-modules-scope@^2.2.0: postcss "^7.0.6" postcss-selector-parser "^6.0.0" -postcss-modules-scope@^3.0.0: - version "3.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-scope/-/postcss-modules-scope-3.0.0.tgz#9ef3151456d3bbfa120ca44898dfca6f2fa01f06" - integrity sha512-hncihwFA2yPath8oZ15PZqvWGkWf+XUfQgUGamS4LqoP1anQLOsOJw0vr7J7IwLpoY9fatA2qiGUGmuZL0Iqlg== - dependencies: - postcss-selector-parser "^6.0.4" - postcss-modules-values@^1.1.0: version "1.3.0" resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-1.3.0.tgz#ecffa9d7e192518389f42ad0e83f72aec456ea20" @@ -16661,27 +16068,6 @@ postcss-modules-values@^3.0.0: icss-utils "^4.0.0" postcss "^7.0.6" -postcss-modules-values@^4.0.0: - version "4.0.0" - resolved "https://registry.yarnpkg.com/postcss-modules-values/-/postcss-modules-values-4.0.0.tgz#d7c5e7e68c3bb3c9b27cbf48ca0bb3ffb4602c9c" - integrity sha512-RDxHkAiEGI78gS2ofyvCsu7iycRv7oqw5xMWn9iMoR0N/7mf9D50ecQqUo5BZ9Zh2vH4bCUR/ktCqbB9m8vJjQ== - dependencies: - icss-utils "^5.0.0" - -postcss-modules@^4.0.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/postcss-modules/-/postcss-modules-4.2.2.tgz#5e7777c5a8964ea176919d90b2e54ef891321ce5" - integrity sha512-/H08MGEmaalv/OU8j6bUKi/kZr2kqGF6huAW8m9UAgOLWtpFdhA14+gPBoymtqyv+D4MLsmqaF2zvIegdCxJXg== - dependencies: - generic-names "^2.0.1" - icss-replace-symbols "^1.1.0" - lodash.camelcase "^4.3.0" - postcss-modules-extract-imports "^3.0.0" - postcss-modules-local-by-default "^4.0.0" - postcss-modules-scope "^3.0.0" - postcss-modules-values "^4.0.0" - string-hash "^1.1.1" - postcss-normalize-charset@^1.1.0: version "1.1.1" resolved "https://registry.yarnpkg.com/postcss-normalize-charset/-/postcss-normalize-charset-1.1.1.tgz#ef9ee71212d7fe759c78ed162f61ed62b5cb93f1" @@ -16786,7 +16172,7 @@ postcss-selector-parser@^3.1.0: indexes-of "^1.0.1" uniq "^1.0.1" -postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2, postcss-selector-parser@^6.0.4: +postcss-selector-parser@^6.0.0, postcss-selector-parser@^6.0.2: version "6.0.6" resolved "https://registry.yarnpkg.com/postcss-selector-parser/-/postcss-selector-parser-6.0.6.tgz#2c5bba8174ac2f6981ab631a42ab0ee54af332ea" integrity sha512-9LXrvaaX3+mcv5xkg5kFwqSzSH1JIObIx51PrndZwlmznwXRfxMddDvo9gve3gVR8ZTKgoFDdWkbRFmEhT4PMg== @@ -16856,16 +16242,7 @@ postcss@^6.0.1: source-map "^0.6.1" supports-color "^5.4.0" -postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: - version "7.0.35" - resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.35.tgz#d2be00b998f7f211d8a276974079f2e92b970e24" - integrity sha512-3QT8bBJeX/S5zKTTjTCIjRF3If4avAT6kqxcASlTWEtAFCb9NH0OUxNDfgZSWdP5fJnBYCMEWkIFfWeugjzYMg== - dependencies: - chalk "^2.4.2" - source-map "^0.6.1" - supports-color "^6.1.0" - -postcss@^7.0.36: +postcss@^7.0.1, postcss@^7.0.14, postcss@^7.0.2, postcss@^7.0.26, postcss@^7.0.32, postcss@^7.0.36, postcss@^7.0.5, postcss@^7.0.6, postcss@^7.0.7: version "7.0.36" resolved "https://registry.yarnpkg.com/postcss/-/postcss-7.0.36.tgz#056f8cffa939662a8f5905950c07d5285644dfcb" integrity sha512-BebJSIUMwJHRH0HAQoxN4u1CN86glsrwsW0q7T+/m44eXOUAxSNdHRkNZPYz5vVUbg17hFgOQDE7fZk7li3pZw== @@ -19249,11 +18626,6 @@ string-argv@^0.0.2: resolved "https://registry.yarnpkg.com/string-argv/-/string-argv-0.0.2.tgz#dac30408690c21f3c3630a3ff3a05877bdcbd736" integrity sha1-2sMECGkMIfPDYwo/86BYd73L1zY= -string-hash@^1.1.1: - version "1.1.3" - resolved "https://registry.yarnpkg.com/string-hash/-/string-hash-1.1.3.tgz#e8aafc0ac1855b4666929ed7dd1275df5d6c811b" - integrity sha1-6Kr8CsGFW0Zmkp7X3RJ1311sgRs= - string-length@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/string-length/-/string-length-2.0.0.tgz#d40dbb686a3ace960c1cffca562bf2c45f8363ed" @@ -19271,15 +18643,7 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -"string-width@^1.0.2 || 2", string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: - version "2.1.1" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" - integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== - dependencies: - is-fullwidth-code-point "^2.0.0" - strip-ansi "^4.0.0" - -"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.2.2, string-width@^4.2.3: +"string-width@^1.0.2 || 2 || 3 || 4", string-width@^4.0.0, string-width@^4.1.0, string-width@^4.2.0, string-width@^4.2.2, string-width@^4.2.3: version "4.2.3" resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.3.tgz#269c7117d27b05ad2e536830a8ec895ef9c6d010" integrity sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g== @@ -19288,6 +18652,14 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^3.0.0" strip-ansi "^6.0.1" +string-width@^2.0.0, string-width@^2.1.0, string-width@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-2.1.1.tgz#ab93f27a8dc13d28cac815c462143a6d9012ae9e" + integrity sha512-nOqH59deCq9SRHlxq1Aw85Jnt4w6KvLKqWVik6oA9ZklXLNIOlqg4F2yrT1MVaTjAqvVwdfeZ7w7aCvJD7ugkw== + dependencies: + is-fullwidth-code-point "^2.0.0" + strip-ansi "^4.0.0" + string-width@^3.0.0, string-width@^3.1.0: version "3.1.0" resolved "https://registry.yarnpkg.com/string-width/-/string-width-3.1.0.tgz#22767be21b62af1081574306f69ac51b62203961" @@ -19297,15 +18669,6 @@ 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, string-width@^4.1.0, string-width@^4.2.0: - version "4.2.2" - resolved "https://registry.yarnpkg.com/string-width/-/string-width-4.2.2.tgz#dafd4f9559a7585cfba529c6a0a4f73488ebd4c5" - integrity sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.0" - "string.prototype.matchall@^4.0.0 || ^3.0.1": version "4.0.5" resolved "https://registry.yarnpkg.com/string.prototype.matchall/-/string.prototype.matchall-4.0.5.tgz#59370644e1db7e4c0c045277690cf7b01203c4da" @@ -19413,14 +18776,7 @@ 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-ansi@^6.0.1: +strip-ansi@^6.0.0, strip-ansi@^6.0.1: version "6.0.1" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-6.0.1.tgz#9e26c63d30f53443e9489495b2105d37b67a85d9" integrity sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A== @@ -20230,12 +19586,7 @@ tslib@^1.8.1, tslib@^1.9.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-1.14.1.tgz#cf2d38bdc34a134bcaf1091c41f6619e2f672d00" integrity sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg== -tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3: - version "2.2.0" - resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.2.0.tgz#fb2c475977e35e241311ede2693cee1ec6698f5c" - integrity sha512-gS9GVHRU+RGn5KQM2rllAlR3dU6m7AcpJKdtH8gFvQiC4Otgk98XnmMU+nZenHt/+VhnBPWwgrJsyrdcw6i23w== - -tslib@^2.1.0: +tslib@^2.0.0, tslib@^2.0.1, tslib@^2.0.3, tslib@^2.1.0: version "2.3.0" resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.3.0.tgz#803b8cdab3e12ba581a4ca41c8839bbb0dacb09e" integrity sha512-N82ooyxVNm6h1riLCoyS9e3fuJ3AMG2zIZs2Gd1ATcSFjSA23Q0fzjjZeh0jbJvWVDZ0cJT8yaNNaaXHzueNjg== @@ -20245,7 +19596,7 @@ tslib@~2.1.0: resolved "https://registry.yarnpkg.com/tslib/-/tslib-2.1.0.tgz#da60860f1c2ecaa5703ab7d39bc05b6bf988b97a" integrity sha512-hcVC3wYEziELGGmEEXue7D75zbwIIVUMWAVbHItGPx0ziyXxrOMQx4rQEVEV45Ut/1IotuEvwqPopzIOkDMf0A== -tsutils@^3.17.1, tsutils@^3.21.0: +tsutils@^3.21.0: version "3.21.0" resolved "https://registry.yarnpkg.com/tsutils/-/tsutils-3.21.0.tgz#b48717d394cea6c1e096983eed58e9d61715b623" integrity sha512-mHKK3iUXL+3UF6xL5k0PEhKRUBKPBCv/+RkEOpjRWxxx27KKRBmmA60A9pgOUvMi8GKhRMPEmjBRPzs2W7O1OA== @@ -20348,17 +19699,7 @@ typedarray@^0.0.6: resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" integrity sha1-hnrHTjhkGHsdPUfZlqeOxciDB3c= -typescript@4: - version "4.3.5" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.3.5.tgz#4d1c37cc16e893973c45a06886b7113234f119f4" - integrity sha512-DqQgihaQ9cUrskJo9kIyW/+g0Vxsk8cDtZ52a3NGh0YNTfpUSArXSohyUGnvbPazEPLu398C0UxmKSOrPumUzA== - -typescript@^4.2.4: - version "4.2.4" - resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.2.4.tgz#8610b59747de028fda898a8aef0e103f156d0961" - integrity sha512-V+evlYHZnQkaz8TRBuxTA92yZBPotr5H+WhQ7bD3hZUndx5tGOa1fuCgeSjxAzM1RiN5IzvadIXTVefuuwZCRg== - -typescript@^4.5: +typescript@^4.2.4, typescript@^4.5: version "4.6.4" resolved "https://registry.yarnpkg.com/typescript/-/typescript-4.6.4.tgz#caa78bbc3a59e6a5c510d35703f6a09877ce45e9" integrity sha512-9ia/jWHIEbo49HfjrLGfKbZSuWo9iTMwXO+Ca3pRsSpbsMbc7/IU8NKdCZVRRBafVPGnoJeFL76ZOAA84I9fEg== @@ -21194,14 +20535,7 @@ which@^2.0.1, which@^2.0.2: dependencies: isexe "^2.0.0" -wide-align@^1.1.0: - version "1.1.3" - resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.3.tgz#ae074e6bdc0c14a431e804e624549c633b000457" - integrity sha512-QGkOQc8XL6Bt5PwnsExKBPuMKBxnGxWWW3fU55Xt4feHozMUhdUMaBCk290qpm/wG5u/RSKzwdAC4i51YigihA== - dependencies: - string-width "^1.0.2 || 2" - -wide-align@^1.1.2: +wide-align@^1.1.0, wide-align@^1.1.2: version "1.1.5" resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.5.tgz#df1d4c206854369ecf3c9a4898f1b23fbd9d15d3" integrity sha512-eDMORYaPNZ4sQIuuYPDHdQvf4gyCF9rEEV/yPxGfwPkRodwEgiMUUXTx/dex+Me0wxx53S+NgUHaP7y3MGlDmg==