diff --git a/gulpfile.js b/gulpfile.js index 4c09ee1cc9..1b9cb5f22e 100644 --- a/gulpfile.js +++ b/gulpfile.js @@ -88,14 +88,8 @@ gulp.task('embed-css', () => gulp.src('./dist/formio.embed.min.css').pipe(rename gulp.task('clean:embed-js', () => gulp.src('./dist/formio.embed.js', { read: false, allowEmpty: true }).pipe(clean())); gulp.task('embed-js', () => gulp.src('./dist/formio.embed.min.js').pipe(rename('formio.embed.js')).pipe(gulp.dest('./dist'))); -// Copy over the moment-timezones to the resource folder. -gulp.task('timezones', () => gulp.src('./node_modules/moment-timezone/data/packed/latest.json').pipe(gulp.dest('./resources'))); - // Create a new build. gulp.task('build', gulp.series( - gulp.parallel( - 'timezones' - ), gulp.parallel( 'styles-embed', 'styles-form', diff --git a/package.json b/package.json index c5b87390e6..febb60f540 100644 --- a/package.json +++ b/package.json @@ -82,7 +82,7 @@ "dependencies": { "@formio/bootstrap": "v3.0.0-dev.121.085d187", "@formio/choices.js": "^10.2.1", - "@formio/core": "v2.4.0-dev.2", + "@formio/core": "v2.4.0-dev.201.69b9c54", "@formio/text-mask-addons": "3.8.0-formio.4", "@formio/vanilla-text-mask": "^5.1.1-formio.1", "abortcontroller-polyfill": "^1.7.5", @@ -92,6 +92,7 @@ "browser-md5-file": "^1.1.1", "compare-versions": "^6.1.1", "core-js": "^3.37.1", + "dayjs": "^1.11.13", "dialog-polyfill": "^0.5.6", "dom-autoscroller": "^2.3.4", "dompurify": "^3.1.6", @@ -107,8 +108,6 @@ "jstimezonedetect": "^1.0.7", "jwt-decode": "^3.1.2", "lodash": "^4.17.21", - "moment": "^2.29.4", - "moment-timezone": "^0.5.44", "quill": "^2.0.2", "signature_pad": "^4.2.0", "string-hash": "^1.1.3", diff --git a/src/Element.js b/src/Element.js index f663ae9b44..8c2c17c994 100644 --- a/src/Element.js +++ b/src/Element.js @@ -3,7 +3,7 @@ import { Formio } from './Formio'; import * as FormioUtils from './utils/utils'; import { I18n } from './utils/i18n'; import _ from 'lodash'; -import moment from 'moment'; +import moment from './utils/moment-wrapper'; import maskInput from '@formio/vanilla-text-mask'; /** diff --git a/src/Webform.js b/src/Webform.js index 6bded91b0e..12b60d2c62 100644 --- a/src/Webform.js +++ b/src/Webform.js @@ -1,11 +1,13 @@ -import _ from 'lodash'; -import moment from 'moment'; -import { compareVersions } from 'compare-versions'; -import EventEmitter from './EventEmitter'; -import i18nDefaults from './i18n'; -import { Formio } from './Formio'; -import Components from './components/Components'; -import NestedDataComponent from './components/_classes/nesteddata/NestedDataComponent'; + +import _ from "lodash"; +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import { compareVersions } from "compare-versions"; +import EventEmitter from "./EventEmitter"; +import i18nDefaults from "./i18n"; +import { Formio } from "./Formio"; +import Components from "./components/Components"; +import NestedDataComponent from "./components/_classes/nesteddata/NestedDataComponent"; import { fastCloneDeep, currentTimezone, @@ -13,8 +15,10 @@ import { getStringFromComponentPath, convertStringToHTMLElement, getArrayFromComponentPath, -} from './utils/utils'; -import { eachComponent } from './utils/formUtils'; + +} from "./utils/utils"; +import { eachComponent } from "./utils/formUtils"; +dayjs.extend(utc); // We need this here because dragula pulls in CustomEvent class that requires global to exist. if (typeof window !== 'undefined' && typeof window.global === 'undefined') { @@ -1509,8 +1513,8 @@ export default class Webform extends NestedDataComponent { // Add in metadata about client submitting the form submission.metadata = submission.metadata || {}; _.defaults(submission.metadata, { - timezone: _.get(this, '_submission.metadata.timezone', currentTimezone()), - offset: parseInt(_.get(this, '_submission.metadata.offset', moment().utcOffset()), 10), + timezone: _.get(this, "_submission.metadata.timezone", currentTimezone()), + offset: parseInt(_.get(this, "_submission.metadata.offset", dayjs().utcOffset()), 10), origin: document.location.origin, referrer: document.referrer, browserName: navigator.appName, diff --git a/src/components/datetime/DateTime.js b/src/components/datetime/DateTime.js index d2961d7921..83d99c394a 100644 --- a/src/components/datetime/DateTime.js +++ b/src/components/datetime/DateTime.js @@ -1,8 +1,17 @@ import _ from 'lodash'; -import moment from 'moment'; +import moment from '../../utils/moment-wrapper'; +import dayjs from 'dayjs'; +import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/timezone"; +import customParseFormat from "dayjs/plugin/customParseFormat"; +import advancedFormat from 'dayjs/plugin/advancedFormat'; import FormioUtils from '../../utils'; import { componentValueTypes, fastCloneDeep, getComponentSavedTypes } from '../../utils/utils'; import Input from '../_classes/input/Input'; +dayjs.extend(utc); +dayjs.extend(timezone); +dayjs.extend(customParseFormat); +dayjs.extend(advancedFormat); export default class DateTimeComponent extends Input { static schema(...extend) { @@ -211,8 +220,8 @@ export default class DateTimeComponent extends Input { } if (Array.isArray(value) && this.component.multiple) { - return value.map(item => _.trim(moment(item).format(format))).join(', '); + return value.map(item => _.trim(dayjs(item).format(format))).join(', '); } - return (value ? _.trim(moment(value).format(format)) : value) || ''; + return (value ? _.trim(dayjs(value).format(format)) : value) || ''; } } diff --git a/src/components/day/Day.js b/src/components/day/Day.js index f40016acdf..44be704a2a 100644 --- a/src/components/day/Day.js +++ b/src/components/day/Day.js @@ -1,5 +1,5 @@ import _ from 'lodash'; -import moment from 'moment'; +import dayjs from 'dayjs'; import Field from '../_classes/field/Field'; import { boolValue, componentValueTypes, getComponentSavedTypes, getLocaleDateFormatInfo } from '../../utils/utils'; import { getDayFormat } from '@formio/core'; @@ -61,11 +61,12 @@ export default class DayComponent extends Field { constructor(component, options, data) { if (!options.inFormBuilder && !options.building) { if (component.maxDate && component.maxDate.indexOf('moment(') === -1) { - component.maxDate = moment(component.maxDate, 'YYYY-MM-DD').toISOString(); - } - if (component.minDate && component.minDate.indexOf('moment(') === -1) { - component.minDate = moment(component.minDate, 'YYYY-MM-DD').toISOString(); + component.maxDate = dayjs(component.maxDate, 'YYYY-MM-DD').toISOString(); + } + if (component.minDate && component.minDate.indexOf('moment(') === -1) { + component.minDate = dayjs(component.minDate, 'YYYY-MM-DD').toISOString(); } + } super(component, options, data); diff --git a/src/components/time/Time.js b/src/components/time/Time.js index c762985cfa..dfd6546f53 100644 --- a/src/components/time/Time.js +++ b/src/components/time/Time.js @@ -1,4 +1,4 @@ -import moment from 'moment'; +import moment from '../../utils/moment-wrapper'; import TextFieldComponent from '../textfield/TextField'; import { getBrowserInfo } from '../../utils/utils'; diff --git a/src/utils/calendarUtils.js b/src/utils/calendarUtils.js index ff33374646..ae5c79e0f5 100644 --- a/src/utils/calendarUtils.js +++ b/src/utils/calendarUtils.js @@ -1,4 +1,4 @@ -import moment from 'moment'; +import moment from './moment-wrapper'; import _ from 'lodash'; export const CALENDAR_ERROR_MESSAGES = { diff --git a/src/utils/conditionOperators/DateGreaterThan.js b/src/utils/conditionOperators/DateGreaterThan.js index dca3235296..54cc5664cf 100644 --- a/src/utils/conditionOperators/DateGreaterThan.js +++ b/src/utils/conditionOperators/DateGreaterThan.js @@ -1,5 +1,5 @@ import ConditionOperator from './ConditionOperator'; -import moment from 'moment'; +import moment from '../moment-wrapper'; export default class DateGeaterThan extends ConditionOperator { static get operatorKey() { return 'dateGreaterThan'; diff --git a/src/utils/moment-wrapper.js b/src/utils/moment-wrapper.js new file mode 100644 index 0000000000..9b6286a98d --- /dev/null +++ b/src/utils/moment-wrapper.js @@ -0,0 +1,36 @@ +import dayjs from "dayjs"; +import utc from "dayjs/plugin/utc"; +import timezone from "dayjs/plugin/timezone" +import customParseFormat from 'dayjs/plugin/customParseFormat'; +import advancedFormat from 'dayjs/plugin/advancedFormat'; +import duration from 'dayjs/plugin/duration'; +import isBetween from 'dayjs/plugin/isBetween'; + +dayjs.extend(utc); +dayjs.extend(timezone); +dayjs.extend(customParseFormat); +dayjs.extend(advancedFormat); +dayjs.extend(isBetween); +dayjs.extend(duration); + +/** + * + * @param {...any} args + */ +function moment(...args) { + return dayjs(...args).isValid() ? dayjs(...args) : dayjs('Invalid date'); +} + +moment.utc = () => dayjs.utc(); +moment.tz = (date, timezone) => dayjs.tz(date, timezone); + + +moment.toISOString = () => { + return dayjs.isValid() ? dayjs.toISOString() : "Invalid date"; +} + +moment.format = (formatStr) => { + return dayjs(this).format(formatStr); +}; + +export default moment; diff --git a/src/utils/utils.js b/src/utils/utils.js index f6aadfa20e..a9550ae86c 100644 --- a/src/utils/utils.js +++ b/src/utils/utils.js @@ -2,8 +2,10 @@ import _ from 'lodash'; import jsonLogic from 'json-logic-js'; -import moment from 'moment-timezone/moment-timezone'; -import jtz from 'jstimezonedetect'; +import moment from './moment-wrapper'; +import dayjs from 'dayjs'; +import utc from 'dayjs/plugin/utc'; +import timezone from 'dayjs/plugin/timezone'; import { lodashOperators } from './jsonlogic/operators'; import dompurify from 'dompurify'; import { getValue } from './formUtils'; @@ -13,22 +15,25 @@ const interpolate = Evaluator.interpolate; export * from './formUtils'; +dayjs.extend(utc); +dayjs.extend(timezone); + // Configure JsonLogic lodashOperators.forEach((name) => jsonLogic.add_operation(`_${name}`, _[name])); // Retrieve Any Date jsonLogic.add_operation('getDate', (date) => { - return moment(date).toISOString(); + return dayjs(date).toISOString(); }); // Set Relative Minimum Date jsonLogic.add_operation('relativeMinDate', (relativeMinDate) => { - return moment().subtract(relativeMinDate, 'days').toISOString(); + return dayjs().subtract(relativeMinDate, 'days').toISOString(); }); // Set Relative Maximum Date jsonLogic.add_operation('relativeMaxDate', (relativeMaxDate) => { - return moment().add(relativeMaxDate, 'days').toISOString(); + return dayjs().add(relativeMaxDate, 'days').toISOString(); }); export { jsonLogic, ConditionOperators, moment }; @@ -580,22 +585,22 @@ export function getDateSetting(date) { return date.isValid() ? date.toDate() : null; } - let dateSetting = ((typeof date !== 'string') || (date.indexOf('moment(') === -1)) ? moment(date) : null; + let dateSetting = ((typeof date !== 'string') || (date.indexOf('moment(') === -1)) ? dayjs(date) : null; if (dateSetting && dateSetting.isValid()) { return dateSetting.toDate(); } dateSetting = null; try { - const value = Evaluator.evaluator(`return ${date};`, 'moment')(moment); + const value = Evaluator.evaluator(`return ${date};`, 'moment')(dayjs); if (typeof value === 'string') { - dateSetting = moment(value); + dateSetting = dayjs(value); } else if (typeof value.toDate === 'function') { - dateSetting = moment(value.toDate().toUTCString()); + dateSetting = dayjs(value.toDate().toUTCString()); } else if (value instanceof Date) { - dateSetting = moment(value); + dateSetting = dayjs(value); } } catch (e) { @@ -628,11 +633,7 @@ export function isValidDate(date) { * @returns {string} - The current timezone. */ export function currentTimezone() { - if (moment.currentTimezone) { - return moment.currentTimezone; - } - moment.currentTimezone = jtz.determine().name(); - return moment.currentTimezone; + return dayjs.tz.guess(); } /** @@ -648,7 +649,7 @@ export function offsetDate(date, timezone) { abbr: 'UTC' }; } - const dateMoment = moment(date).tz(timezone); + const dateMoment = dayjs(date).tz(timezone); return { date: new Date(date.getTime() + ((dateMoment.utcOffset() + date.getTimezoneOffset()) * 60000)), abbr: dateMoment.format('z') @@ -660,7 +661,7 @@ export function offsetDate(date, timezone) { * @returns {boolean} - TRUE if the zones are loaded; FALSE otherwise. */ export function zonesLoaded() { - return moment.zonesLoaded; + return typeof dayjs.tz === 'function'; } /** @@ -712,15 +713,19 @@ export function loadZones(url, timezone) { * @param {object} options - The options object * @returns {Date} - The moment date object. */ -export function momentDate(value, format, timezone, options) { - const momentDate = moment(value); - if (!timezone) { - return momentDate; - } + +/** + * + * @param value + * @param format + * @param timezone + */ +export function momentDate(value, format, timezone) { + const momentDate = dayjs(value); if (timezone === 'UTC') { - timezone = 'Etc/UTC'; + return dayjs.utc(); } - if ((timezone !== currentTimezone() || (format && format.match(/\s(z$|z\s)/))) && (moment.zonesLoaded || options?.email)) { + if (timezone !== currentTimezone() || (format && format.match(/\s(z$|z\s)/))) { return momentDate.tz(timezone); } return momentDate; @@ -728,55 +733,33 @@ export function momentDate(value, format, timezone, options) { /** * Format a date provided a value, format, and timezone object. - * @param {string} timezonesUrl - The URL to load the timezone data from. * @param {string|Date} value - The value to format. * @param {string} format - The format to format the date to. * @param {string} timezone - The timezone to format the date to. * @param {string} flatPickrInputFormat - The format to use for flatpickr input. * @returns {string} - The formatted date. */ -export function formatDate(timezonesUrl, value, format, timezone, flatPickrInputFormat) { - const momentDate = moment(value, flatPickrInputFormat || undefined); - if (timezone === currentTimezone()) { - // See if our format contains a "z" timezone character. - if (format.match(/\s(z$|z\s)/)) { - loadZones(timezonesUrl); - if (moment.zonesLoaded) { - return momentDate.tz(timezone).format(convertFormatToMoment(format)); - } - else { - return momentDate.format(convertFormatToMoment(format.replace(/\s(z$|z\s)/, ''))); - } - } - - // Return the standard format. - return momentDate.format(convertFormatToMoment(format)); - } +export function formatDate(value, format, timezone, flatPickrInputFormat) { + const date = dayjs(value, flatPickrInputFormat); + const dayjsFormat = convertFormatToMoment(format); if (timezone === 'UTC') { - const offset = offsetDate(momentDate.toDate(), 'UTC'); - return `${moment(offset.date).format(convertFormatToMoment(format))} UTC`; - } - - // Load the zones since we need timezone information. - loadZones(timezonesUrl); - if (moment.zonesLoaded && timezone) { - return momentDate.tz(timezone).format(`${convertFormatToMoment(format)} z`); + return `${date.utc().format(dayjsFormat)} UTC`; } - else { - return momentDate.format(convertFormatToMoment(format)); + if (timezone) { + return date.tz(timezone).format(`${dayjsFormat} z`); } + return date.format(dayjsFormat); } /** * Pass a format function to format within a timezone. - * @param {string} timezonesUrl - The URL to load the timezone data from. * @param {Function} formatFn - The format function to use. * @param {Date|string} date - The date to format. * @param {string} format - The format to format the date to. * @param {string} timezone - The timezone to format the date to. * @returns {string} - The formatted date. */ -export function formatOffset(timezonesUrl, formatFn, date, format, timezone) { +export function formatOffset(formatFn, date, format, timezone) { if (timezone === currentTimezone()) { return formatFn(date, format); } @@ -784,15 +767,8 @@ export function formatOffset(timezonesUrl, formatFn, date, format, timezone) { return `${formatFn(offsetDate(date, 'UTC').date, format)} UTC`; } - // Load the zones since we need timezone information. - loadZones(timezonesUrl); - if (moment.zonesLoaded) { - const offset = offsetDate(date, timezone); - return `${formatFn(offset.date, format)} ${offset.abbr}`; - } - else { - return formatFn(date, format); - } + const offset = offsetDate(date, timezone); + return `${formatFn(offset.date, format)} ${offset.abbr}`; } /** diff --git a/src/widgets/CalendarWidget.js b/src/widgets/CalendarWidget.js index 105626531e..5f8fe46170 100644 --- a/src/widgets/CalendarWidget.js +++ b/src/widgets/CalendarWidget.js @@ -14,7 +14,7 @@ import { shouldLoadZones, loadZones, } from '../utils/utils'; -import moment from 'moment'; +import moment from '../utils/moment-wrapper'; import _ from 'lodash'; const DEFAULT_FORMAT = 'yyyy-MM-dd hh:mm a'; @@ -340,7 +340,7 @@ export default class CalendarWidget extends InputWidget { setValue(value) { const saveAsText = (this.settings.saveAs === 'text'); if (!this.calendar) { - value = value ? formatDate(this.timezonesUrl, value, convertFormatToMoment(this.settings.format), this.timezone, convertFormatToMoment(this.valueMomentFormat)) : value; + value = value ? formatDate(value, convertFormatToMoment(this.settings.format), this.timezone, convertFormatToMoment(this.valueMomentFormat)) : value; return super.setValue(value); } @@ -367,7 +367,7 @@ export default class CalendarWidget extends InputWidget { if (this.settings.saveAs === 'text' && this.componentInstance.parent && !this.settings.readOnly) { return moment(value, convertFormatToMoment(valueFormat)).format(convertFormatToMoment(valueFormat)); } - return formatDate(this.timezonesUrl, value, inputFormat, this.timezone, convertFormatToMoment(valueFormat)); + return formatDate(value, inputFormat, this.timezone, convertFormatToMoment(valueFormat)); } setErrorClasses(hasErrors) { @@ -538,9 +538,9 @@ export default class CalendarWidget extends InputWidget { const currentValue = new Date(this.getValue()); if (currentValue.toString() === date.toString()) { - return formatOffset(this.timezonesUrl, Flatpickr.formatDate.bind(Flatpickr), new Date(this.componentValue), format, this.timezone); + return formatOffset(Flatpickr.formatDate.bind(Flatpickr), new Date(this.componentValue), format, this.timezone); } - return formatOffset(this.timezonesUrl, Flatpickr.formatDate.bind(Flatpickr), date, format, this.timezone); + return formatOffset(Flatpickr.formatDate.bind(Flatpickr), date, format, this.timezone); } return Flatpickr.formatDate(date, format); diff --git a/test/forms/helpers/testBasicComponentSettings/settings.js b/test/forms/helpers/testBasicComponentSettings/settings.js index 11e4216283..f24cbdb74b 100644 --- a/test/forms/helpers/testBasicComponentSettings/settings.js +++ b/test/forms/helpers/testBasicComponentSettings/settings.js @@ -1,5 +1,5 @@ import _ from 'lodash'; -import moment from 'moment'; +import moment from '../../../../src/utils/moment-wrapper'; import basicValues from './basicValues'; export default { diff --git a/test/unit/DateTime.unit.js b/test/unit/DateTime.unit.js index 150a6a4133..9764502195 100644 --- a/test/unit/DateTime.unit.js +++ b/test/unit/DateTime.unit.js @@ -4,8 +4,7 @@ import DateTimeComponent from '../../src/components/datetime/DateTime'; import { Formio } from '../../src/Formio'; import _ from 'lodash'; import 'flatpickr'; -import moment from 'moment-timezone'; -import Form from '../../src/Form.js' +import moment from '../../src/utils/moment-wrapper'; import { comp1, comp2, diff --git a/yarn.lock b/yarn.lock index a817a41fa4..c2f33b5d33 100644 --- a/yarn.lock +++ b/yarn.lock @@ -223,22 +223,21 @@ fuse.js "^6.6.2" redux "^4.2.0" -"@formio/core@v2.4.0-dev.2": - version "2.4.0-dev.2" - resolved "https://registry.yarnpkg.com/@formio/core/-/core-2.4.0-dev.2.tgz#30ebab054e602c5ce7f487d853d195887e0f62b9" - integrity sha512-rodSO272z/bUqOulrCx1mkpCsuW7AHjcxV9tX5Ob7F97JV/6lxtsvxrmhPWFS63yXnecreZO5v67xrcHxBWVMg== +"@formio/core@v2.4.0-dev.201.69b9c54": + version "2.4.0-dev.201.69b9c54" + resolved "https://registry.yarnpkg.com/@formio/core/-/core-2.4.0-dev.201.69b9c54.tgz#b66016460ae575a1a6897110f6f24916755bd440" + integrity sha512-YA2u5xN83ER8aqCkN80UBT5Aw317kuFUlT2knF+ikOdzcqEPgbUE9J6yeMKERWQS+lUfw4sskbwS2vsOeJvyRA== dependencies: browser-cookies "^1.2.0" - core-js "^3.39.0" + core-js "^3.40.0" dayjs "^1.11.12" - dompurify "^3.2.3" + dompurify "^3.2.4" eventemitter3 "^5.0.0" fast-json-patch "^3.1.1" fetch-ponyfill "^7.1.0" inputmask "5.0.9" json-logic-js "^2.0.5" lodash "^4.17.21" - moment "^2.29.4" "@formio/text-mask-addons@3.8.0-formio.4": version "3.8.0-formio.4" @@ -2032,11 +2031,16 @@ core-js@^2.0.0: resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.6.12.tgz#d9333dfa7b065e347cc5682219d6f690859cc2ec" integrity sha512-Kb2wC0fvsWfQrgk8HU5lW6U/Lcs8+9aaYcy4ZFc6DDlo4nZ7n70dEgE5rtR0oG6ufKDUnrwfWL1mXR5ljDatrQ== -core-js@^3.0.0, core-js@^3.30.2, core-js@^3.37.1, core-js@^3.39.0: +core-js@^3.0.0, core-js@^3.30.2, core-js@^3.37.1: version "3.39.0" resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.39.0.tgz#57f7647f4d2d030c32a72ea23a0555b2eaa30f83" integrity sha512-raM0ew0/jJUqkJ0E6e8UDtl+y/7ktFivgWvqw8dNSQeNWoSDLvQ1H/RN3aPXB9tBd4/FhyR4RDPGhsNIMsAn7g== +core-js@^3.40.0: + version "3.40.0" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-3.40.0.tgz#2773f6b06877d8eda102fc42f828176437062476" + integrity sha512-7vsMc/Lty6AGnn7uFpYT56QesI5D2Y/UkgKounk87OP9Z2H9Z8kj6jzcSGAxFmUtDOS0ntK6lbQz+Nsa0Jj6mQ== + core-util-is@1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" @@ -2181,7 +2185,7 @@ date-format@^4.0.14: resolved "https://registry.yarnpkg.com/date-format/-/date-format-4.0.14.tgz#7a8e584434fb169a521c8b7aa481f355810d9400" integrity sha512-39BOQLs9ZjKh0/patS9nrT8wc3ioX3/eA/zgbKNopnF2wCqJEoxywwwElATYvRsXdnOxA/OQeQoFZ3rFjVajhg== -dayjs@^1.11.12: +dayjs@^1.11.12, dayjs@^1.11.13: version "1.11.13" resolved "https://registry.yarnpkg.com/dayjs/-/dayjs-1.11.13.tgz#92430b0139055c3ebb60150aa13e860a4b5a366c" integrity sha512-oaMBel6gjolK862uaPQOVTA7q3TZhuSvuMQAAglQDOWYO9A91IrAOUJEyKVlqJlHE0vq5p5UXxzdPfMH/x6xNg== @@ -2434,13 +2438,20 @@ domexception@^4.0.0: dependencies: webidl-conversions "^7.0.0" -dompurify@^3.1.6, dompurify@^3.2.3: +dompurify@^3.1.6: version "3.2.3" resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.3.tgz#05dd2175225324daabfca6603055a09b2382a4cd" integrity sha512-U1U5Hzc2MO0oW3DF+G9qYN0aT7atAou4AgI0XjWz061nyBPbdxkfdhfy5uMgGn6+oLFCfn44ZGbdDqCzVmlOWA== optionalDependencies: "@types/trusted-types" "^2.0.7" +dompurify@^3.2.4: + version "3.2.4" + resolved "https://registry.yarnpkg.com/dompurify/-/dompurify-3.2.4.tgz#af5a5a11407524431456cf18836c55d13441cd8e" + integrity sha512-ysFSFEDVduQpyhzAob/kkuJjf5zWkZD8/A9ywSp1byueyuCfHamrCBa14/Oc2iiB0e51B+NpxSl5gmzn+Ms/mg== + optionalDependencies: + "@types/trusted-types" "^2.0.7" + downloadjs@^1.4.7: version "1.4.7" resolved "https://registry.yarnpkg.com/downloadjs/-/downloadjs-1.4.7.tgz#f69f96f940e0d0553dac291139865a3cd0101e3c" @@ -5557,18 +5568,6 @@ mock-local-storage@^1.1.24: core-js "^3.30.2" global "^4.3.2" -moment-timezone@^0.5.44: - version "0.5.46" - resolved "https://registry.yarnpkg.com/moment-timezone/-/moment-timezone-0.5.46.tgz#a21aa6392b3c6b3ed916cd5e95858a28d893704a" - integrity sha512-ZXm9b36esbe7OmdABqIWJuBBiLLwAjrN7CE+7sYdCCx82Nabt1wHDj8TVseS59QIlfFPbOoiBPm6ca9BioG4hw== - dependencies: - moment "^2.29.4" - -moment@^2.29.4: - version "2.30.1" - resolved "https://registry.yarnpkg.com/moment/-/moment-2.30.1.tgz#f8c91c07b7a786e30c59926df530b4eac96974ae" - integrity sha512-uEmtNhbDOrWPFS+hdjFCBfy9f2YoyzRpwcl+DqpC6taX21FzsTLQVbMV/W7PzNSX6x/bhC1zA3c2UQ5NzH6how== - mrmime@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/mrmime/-/mrmime-2.0.0.tgz#151082a6e06e59a9a39b46b3e14d5cfe92b3abb4" @@ -7442,7 +7441,7 @@ string-replace-loader@^3.1.0: loader-utils "^2.0.0" schema-utils "^3.0.0" -"string-width-cjs@npm:string-width@^4.2.0": +"string-width-cjs@npm:string-width@^4.2.0", string-width@^4.1.0, string-width@^4.2.0: 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== @@ -7460,15 +7459,6 @@ string-width@^1.0.1, string-width@^1.0.2: is-fullwidth-code-point "^1.0.0" strip-ansi "^3.0.0" -string-width@^4.1.0, string-width@^4.2.0: - 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== - dependencies: - emoji-regex "^8.0.0" - is-fullwidth-code-point "^3.0.0" - strip-ansi "^6.0.1" - string-width@^5.0.1, string-width@^5.1.2: version "5.1.2" resolved "https://registry.yarnpkg.com/string-width/-/string-width-5.1.2.tgz#14f8daec6d81e7221d2a357e668cab73bdbca794" @@ -7533,7 +7523,7 @@ stringifier@^1.3.0: traverse "^0.6.6" type-name "^2.0.1" -"strip-ansi-cjs@npm:strip-ansi@^6.0.1": +"strip-ansi-cjs@npm: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== @@ -7554,13 +7544,6 @@ strip-ansi@^4.0.0: dependencies: ansi-regex "^3.0.0" -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== - dependencies: - ansi-regex "^5.0.1" - strip-ansi@^7.0.1: version "7.1.0" resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-7.1.0.tgz#d5b6568ca689d8561370b0707685d22434faff45" @@ -8657,7 +8640,7 @@ workerpool@^6.5.1: resolved "https://registry.yarnpkg.com/workerpool/-/workerpool-6.5.1.tgz#060f73b39d0caf97c6db64da004cd01b4c099544" integrity sha512-Fs4dNYcsdpYSAfVxhnl1L5zTksjvOJxtC5hzMNl+1t9B8hTJTdKDyZ5ju7ztgPy+ft9tBFXoOlDNiOT9WUXZlA== -"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0": +"wrap-ansi-cjs@npm:wrap-ansi@^7.0.0", wrap-ansi@^7.0.0: version "7.0.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== @@ -8683,15 +8666,6 @@ wrap-ansi@^6.2.0: string-width "^4.1.0" strip-ansi "^6.0.0" -wrap-ansi@^7.0.0: - version "7.0.0" - resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-7.0.0.tgz#67e145cff510a6a6984bdf1152911d69d2eb9e43" - integrity sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q== - dependencies: - ansi-styles "^4.0.0" - string-width "^4.1.0" - strip-ansi "^6.0.0" - wrap-ansi@^8.1.0: version "8.1.0" resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-8.1.0.tgz#56dc22368ee570face1b49819975d9b9a5ead214"