summaryrefslogtreecommitdiffstats
path: root/npm_assets/node_modules/luxon/src/impl
diff options
context:
space:
mode:
Diffstat (limited to 'npm_assets/node_modules/luxon/src/impl')
-rw-r--r--npm_assets/node_modules/luxon/src/impl/conversions.js157
-rw-r--r--npm_assets/node_modules/luxon/src/impl/diff.js79
-rw-r--r--npm_assets/node_modules/luxon/src/impl/digits.js76
-rw-r--r--npm_assets/node_modules/luxon/src/impl/english.js233
-rw-r--r--npm_assets/node_modules/luxon/src/impl/formats.js191
-rw-r--r--npm_assets/node_modules/luxon/src/impl/formatter.js386
-rw-r--r--npm_assets/node_modules/luxon/src/impl/invalid.js14
-rw-r--r--npm_assets/node_modules/luxon/src/impl/locale.js469
-rw-r--r--npm_assets/node_modules/luxon/src/impl/regexParser.js319
-rw-r--r--npm_assets/node_modules/luxon/src/impl/tokenParser.js424
-rw-r--r--npm_assets/node_modules/luxon/src/impl/util.js286
-rw-r--r--npm_assets/node_modules/luxon/src/impl/zoneUtil.js36
12 files changed, 2670 insertions, 0 deletions
diff --git a/npm_assets/node_modules/luxon/src/impl/conversions.js b/npm_assets/node_modules/luxon/src/impl/conversions.js
new file mode 100644
index 0000000..cbe7172
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/conversions.js
@@ -0,0 +1,157 @@
+import {
+ integerBetween,
+ isLeapYear,
+ timeObject,
+ daysInYear,
+ daysInMonth,
+ weeksInWeekYear,
+ isInteger
+} from "./util.js";
+import Invalid from "./invalid.js";
+
+const nonLeapLadder = [0, 31, 59, 90, 120, 151, 181, 212, 243, 273, 304, 334],
+ leapLadder = [0, 31, 60, 91, 121, 152, 182, 213, 244, 274, 305, 335];
+
+function unitOutOfRange(unit, value) {
+ return new Invalid(
+ "unit out of range",
+ `you specified ${value} (of type ${typeof value}) as a ${unit}, which is invalid`
+ );
+}
+
+function dayOfWeek(year, month, day) {
+ const js = new Date(Date.UTC(year, month - 1, day)).getUTCDay();
+ return js === 0 ? 7 : js;
+}
+
+function computeOrdinal(year, month, day) {
+ return day + (isLeapYear(year) ? leapLadder : nonLeapLadder)[month - 1];
+}
+
+function uncomputeOrdinal(year, ordinal) {
+ const table = isLeapYear(year) ? leapLadder : nonLeapLadder,
+ month0 = table.findIndex(i => i < ordinal),
+ day = ordinal - table[month0];
+ return { month: month0 + 1, day };
+}
+
+/**
+ * @private
+ */
+
+export function gregorianToWeek(gregObj) {
+ const { year, month, day } = gregObj,
+ ordinal = computeOrdinal(year, month, day),
+ weekday = dayOfWeek(year, month, day);
+
+ let weekNumber = Math.floor((ordinal - weekday + 10) / 7),
+ weekYear;
+
+ if (weekNumber < 1) {
+ weekYear = year - 1;
+ weekNumber = weeksInWeekYear(weekYear);
+ } else if (weekNumber > weeksInWeekYear(year)) {
+ weekYear = year + 1;
+ weekNumber = 1;
+ } else {
+ weekYear = year;
+ }
+
+ return Object.assign({ weekYear, weekNumber, weekday }, timeObject(gregObj));
+}
+
+export function weekToGregorian(weekData) {
+ const { weekYear, weekNumber, weekday } = weekData,
+ weekdayOfJan4 = dayOfWeek(weekYear, 1, 4),
+ yearInDays = daysInYear(weekYear);
+
+ let ordinal = weekNumber * 7 + weekday - weekdayOfJan4 - 3,
+ year;
+
+ if (ordinal < 1) {
+ year = weekYear - 1;
+ ordinal += daysInYear(year);
+ } else if (ordinal > yearInDays) {
+ year = weekYear + 1;
+ ordinal -= daysInYear(weekYear);
+ } else {
+ year = weekYear;
+ }
+
+ const { month, day } = uncomputeOrdinal(year, ordinal);
+
+ return Object.assign({ year, month, day }, timeObject(weekData));
+}
+
+export function gregorianToOrdinal(gregData) {
+ const { year, month, day } = gregData,
+ ordinal = computeOrdinal(year, month, day);
+
+ return Object.assign({ year, ordinal }, timeObject(gregData));
+}
+
+export function ordinalToGregorian(ordinalData) {
+ const { year, ordinal } = ordinalData,
+ { month, day } = uncomputeOrdinal(year, ordinal);
+
+ return Object.assign({ year, month, day }, timeObject(ordinalData));
+}
+
+export function hasInvalidWeekData(obj) {
+ const validYear = isInteger(obj.weekYear),
+ validWeek = integerBetween(obj.weekNumber, 1, weeksInWeekYear(obj.weekYear)),
+ validWeekday = integerBetween(obj.weekday, 1, 7);
+
+ if (!validYear) {
+ return unitOutOfRange("weekYear", obj.weekYear);
+ } else if (!validWeek) {
+ return unitOutOfRange("week", obj.week);
+ } else if (!validWeekday) {
+ return unitOutOfRange("weekday", obj.weekday);
+ } else return false;
+}
+
+export function hasInvalidOrdinalData(obj) {
+ const validYear = isInteger(obj.year),
+ validOrdinal = integerBetween(obj.ordinal, 1, daysInYear(obj.year));
+
+ if (!validYear) {
+ return unitOutOfRange("year", obj.year);
+ } else if (!validOrdinal) {
+ return unitOutOfRange("ordinal", obj.ordinal);
+ } else return false;
+}
+
+export function hasInvalidGregorianData(obj) {
+ const validYear = isInteger(obj.year),
+ validMonth = integerBetween(obj.month, 1, 12),
+ validDay = integerBetween(obj.day, 1, daysInMonth(obj.year, obj.month));
+
+ if (!validYear) {
+ return unitOutOfRange("year", obj.year);
+ } else if (!validMonth) {
+ return unitOutOfRange("month", obj.month);
+ } else if (!validDay) {
+ return unitOutOfRange("day", obj.day);
+ } else return false;
+}
+
+export function hasInvalidTimeData(obj) {
+ const { hour, minute, second, millisecond } = obj;
+ const validHour =
+ integerBetween(hour, 0, 23) ||
+ (hour === 24 && minute === 0 && second === 0 && millisecond === 0),
+ validMinute = integerBetween(minute, 0, 59),
+ validSecond = integerBetween(second, 0, 59),
+ validMillisecond = integerBetween(millisecond, 0, 999);
+
+ if (!validHour) {
+ return unitOutOfRange("hour", hour);
+ } else if (!validMinute) {
+ return unitOutOfRange("minute", minute);
+ } else if (!validSecond) {
+ return unitOutOfRange("second", second);
+ } else if (!validMillisecond) {
+ return unitOutOfRange("millisecond", millisecond);
+ } else return false;
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/diff.js b/npm_assets/node_modules/luxon/src/impl/diff.js
new file mode 100644
index 0000000..57246dc
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/diff.js
@@ -0,0 +1,79 @@
+import Duration from "../duration.js";
+
+function dayDiff(earlier, later) {
+ const utcDayStart = dt =>
+ dt
+ .toUTC(0, { keepLocalTime: true })
+ .startOf("day")
+ .valueOf(),
+ ms = utcDayStart(later) - utcDayStart(earlier);
+ return Math.floor(Duration.fromMillis(ms).as("days"));
+}
+
+function highOrderDiffs(cursor, later, units) {
+ const differs = [
+ ["years", (a, b) => b.year - a.year],
+ ["months", (a, b) => b.month - a.month + (b.year - a.year) * 12],
+ [
+ "weeks",
+ (a, b) => {
+ const days = dayDiff(a, b);
+ return (days - (days % 7)) / 7;
+ }
+ ],
+ ["days", dayDiff]
+ ];
+
+ const results = {};
+ let lowestOrder, highWater;
+
+ for (const [unit, differ] of differs) {
+ if (units.indexOf(unit) >= 0) {
+ lowestOrder = unit;
+
+ let delta = differ(cursor, later);
+ highWater = cursor.plus({ [unit]: delta });
+
+ if (highWater > later) {
+ cursor = cursor.plus({ [unit]: delta - 1 });
+ delta -= 1;
+ } else {
+ cursor = highWater;
+ }
+
+ results[unit] = delta;
+ }
+ }
+
+ return [cursor, results, highWater, lowestOrder];
+}
+
+export default function(earlier, later, units, opts) {
+ let [cursor, results, highWater, lowestOrder] = highOrderDiffs(earlier, later, units);
+
+ const remainingMillis = later - cursor;
+
+ const lowerOrderUnits = units.filter(
+ u => ["hours", "minutes", "seconds", "milliseconds"].indexOf(u) >= 0
+ );
+
+ if (lowerOrderUnits.length === 0) {
+ if (highWater < later) {
+ highWater = cursor.plus({ [lowestOrder]: 1 });
+ }
+
+ if (highWater !== cursor) {
+ results[lowestOrder] = (results[lowestOrder] || 0) + remainingMillis / (highWater - cursor);
+ }
+ }
+
+ const duration = Duration.fromObject(Object.assign(results, opts));
+
+ if (lowerOrderUnits.length > 0) {
+ return Duration.fromMillis(remainingMillis, opts)
+ .shiftTo(...lowerOrderUnits)
+ .plus(duration);
+ } else {
+ return duration;
+ }
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/digits.js b/npm_assets/node_modules/luxon/src/impl/digits.js
new file mode 100644
index 0000000..0d081c2
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/digits.js
@@ -0,0 +1,76 @@
+const numberingSystems = {
+ arab: "[\u0660-\u0669]",
+ arabext: "[\u06F0-\u06F9]",
+ bali: "[\u1B50-\u1B59]",
+ beng: "[\u09E6-\u09EF]",
+ deva: "[\u0966-\u096F]",
+ fullwide: "[\uFF10-\uFF19]",
+ gujr: "[\u0AE6-\u0AEF]",
+ hanidec: "[〇|一|二|三|四|五|六|七|八|九]",
+ khmr: "[\u17E0-\u17E9]",
+ knda: "[\u0CE6-\u0CEF]",
+ laoo: "[\u0ED0-\u0ED9]",
+ limb: "[\u1946-\u194F]",
+ mlym: "[\u0D66-\u0D6F]",
+ mong: "[\u1810-\u1819]",
+ mymr: "[\u1040-\u1049]",
+ orya: "[\u0B66-\u0B6F]",
+ tamldec: "[\u0BE6-\u0BEF]",
+ telu: "[\u0C66-\u0C6F]",
+ thai: "[\u0E50-\u0E59]",
+ tibt: "[\u0F20-\u0F29]",
+ latn: "\\d"
+};
+
+const numberingSystemsUTF16 = {
+ arab: [1632, 1641],
+ arabext: [1776, 1785],
+ bali: [6992, 7001],
+ beng: [2534, 2543],
+ deva: [2406, 2415],
+ fullwide: [65296, 65303],
+ gujr: [2790, 2799],
+ khmr: [6112, 6121],
+ knda: [3302, 3311],
+ laoo: [3792, 3801],
+ limb: [6470, 6479],
+ mlym: [3430, 3439],
+ mong: [6160, 6169],
+ mymr: [4160, 4169],
+ orya: [2918, 2927],
+ tamldec: [3046, 3055],
+ telu: [3174, 3183],
+ thai: [3664, 3673],
+ tibt: [3872, 3881]
+};
+
+// eslint-disable-next-line
+const hanidecChars = numberingSystems.hanidec.replace(/[\[|\]]/g, "").split("");
+
+export function parseDigits(str) {
+ let value = parseInt(str, 10);
+ if (isNaN(value)) {
+ value = "";
+ for (let i = 0; i < str.length; i++) {
+ const code = str.charCodeAt(i);
+
+ if (str[i].search(numberingSystems.hanidec) !== -1) {
+ value += hanidecChars.indexOf(str[i]);
+ } else {
+ for (const key in numberingSystemsUTF16) {
+ const [min, max] = numberingSystemsUTF16[key];
+ if (code >= min && code <= max) {
+ value += code - min;
+ }
+ }
+ }
+ }
+ return parseInt(value, 10);
+ } else {
+ return value;
+ }
+}
+
+export function digitRegex({ numberingSystem }, append = "") {
+ return new RegExp(`${numberingSystems[numberingSystem || "latn"]}${append}`);
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/english.js b/npm_assets/node_modules/luxon/src/impl/english.js
new file mode 100644
index 0000000..633f594
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/english.js
@@ -0,0 +1,233 @@
+import * as Formats from "./formats.js";
+import { pick } from "./util.js";
+
+function stringify(obj) {
+ return JSON.stringify(obj, Object.keys(obj).sort());
+}
+
+/**
+ * @private
+ */
+
+export const monthsLong = [
+ "January",
+ "February",
+ "March",
+ "April",
+ "May",
+ "June",
+ "July",
+ "August",
+ "September",
+ "October",
+ "November",
+ "December"
+];
+
+export const monthsShort = [
+ "Jan",
+ "Feb",
+ "Mar",
+ "Apr",
+ "May",
+ "Jun",
+ "Jul",
+ "Aug",
+ "Sep",
+ "Oct",
+ "Nov",
+ "Dec"
+];
+
+export const monthsNarrow = ["J", "F", "M", "A", "M", "J", "J", "A", "S", "O", "N", "D"];
+
+export function months(length) {
+ switch (length) {
+ case "narrow":
+ return monthsNarrow;
+ case "short":
+ return monthsShort;
+ case "long":
+ return monthsLong;
+ case "numeric":
+ return ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10", "11", "12"];
+ case "2-digit":
+ return ["01", "02", "03", "04", "05", "06", "07", "08", "09", "10", "11", "12"];
+ default:
+ return null;
+ }
+}
+
+export const weekdaysLong = [
+ "Monday",
+ "Tuesday",
+ "Wednesday",
+ "Thursday",
+ "Friday",
+ "Saturday",
+ "Sunday"
+];
+
+export const weekdaysShort = ["Mon", "Tue", "Wed", "Thu", "Fri", "Sat", "Sun"];
+
+export const weekdaysNarrow = ["M", "T", "W", "T", "F", "S", "S"];
+
+export function weekdays(length) {
+ switch (length) {
+ case "narrow":
+ return weekdaysNarrow;
+ case "short":
+ return weekdaysShort;
+ case "long":
+ return weekdaysLong;
+ case "numeric":
+ return ["1", "2", "3", "4", "5", "6", "7"];
+ default:
+ return null;
+ }
+}
+
+export const meridiems = ["AM", "PM"];
+
+export const erasLong = ["Before Christ", "Anno Domini"];
+
+export const erasShort = ["BC", "AD"];
+
+export const erasNarrow = ["B", "A"];
+
+export function eras(length) {
+ switch (length) {
+ case "narrow":
+ return erasNarrow;
+ case "short":
+ return erasShort;
+ case "long":
+ return erasLong;
+ default:
+ return null;
+ }
+}
+
+export function meridiemForDateTime(dt) {
+ return meridiems[dt.hour < 12 ? 0 : 1];
+}
+
+export function weekdayForDateTime(dt, length) {
+ return weekdays(length)[dt.weekday - 1];
+}
+
+export function monthForDateTime(dt, length) {
+ return months(length)[dt.month - 1];
+}
+
+export function eraForDateTime(dt, length) {
+ return eras(length)[dt.year < 0 ? 0 : 1];
+}
+
+export function formatRelativeTime(unit, count, numeric = "always", narrow = false) {
+ const units = {
+ years: ["year", "yr."],
+ quarters: ["quarter", "qtr."],
+ months: ["month", "mo."],
+ weeks: ["week", "wk."],
+ days: ["day", "day", "days"],
+ hours: ["hour", "hr."],
+ minutes: ["minute", "min."],
+ seconds: ["second", "sec."]
+ };
+
+ const lastable = ["hours", "minutes", "seconds"].indexOf(unit) === -1;
+
+ if (numeric === "auto" && lastable) {
+ const isDay = unit === "days";
+ switch (count) {
+ case 1:
+ return isDay ? "tomorrow" : `next ${units[unit][0]}`;
+ case -1:
+ return isDay ? "yesterday" : `last ${units[unit][0]}`;
+ case 0:
+ return isDay ? "today" : `this ${units[unit][0]}`;
+ default: // fall through
+ }
+ }
+
+ const isInPast = Object.is(count, -0) || count < 0,
+ fmtValue = Math.abs(count),
+ singular = fmtValue === 1,
+ lilUnits = units[unit],
+ fmtUnit = narrow
+ ? singular
+ ? lilUnits[1]
+ : lilUnits[2] || lilUnits[1]
+ : singular
+ ? units[unit][0]
+ : unit;
+ return isInPast ? `${fmtValue} ${fmtUnit} ago` : `in ${fmtValue} ${fmtUnit}`;
+}
+
+export function formatString(knownFormat) {
+ // these all have the offsets removed because we don't have access to them
+ // without all the intl stuff this is backfilling
+ const filtered = pick(knownFormat, [
+ "weekday",
+ "era",
+ "year",
+ "month",
+ "day",
+ "hour",
+ "minute",
+ "second",
+ "timeZoneName",
+ "hour12"
+ ]),
+ key = stringify(filtered),
+ dateTimeHuge = "EEEE, LLLL d, yyyy, h:mm a";
+ switch (key) {
+ case stringify(Formats.DATE_SHORT):
+ return "M/d/yyyy";
+ case stringify(Formats.DATE_MED):
+ return "LLL d, yyyy";
+ case stringify(Formats.DATE_MED_WITH_WEEKDAY):
+ return "EEE, LLL d, yyyy";
+ case stringify(Formats.DATE_FULL):
+ return "LLLL d, yyyy";
+ case stringify(Formats.DATE_HUGE):
+ return "EEEE, LLLL d, yyyy";
+ case stringify(Formats.TIME_SIMPLE):
+ return "h:mm a";
+ case stringify(Formats.TIME_WITH_SECONDS):
+ return "h:mm:ss a";
+ case stringify(Formats.TIME_WITH_SHORT_OFFSET):
+ return "h:mm a";
+ case stringify(Formats.TIME_WITH_LONG_OFFSET):
+ return "h:mm a";
+ case stringify(Formats.TIME_24_SIMPLE):
+ return "HH:mm";
+ case stringify(Formats.TIME_24_WITH_SECONDS):
+ return "HH:mm:ss";
+ case stringify(Formats.TIME_24_WITH_SHORT_OFFSET):
+ return "HH:mm";
+ case stringify(Formats.TIME_24_WITH_LONG_OFFSET):
+ return "HH:mm";
+ case stringify(Formats.DATETIME_SHORT):
+ return "M/d/yyyy, h:mm a";
+ case stringify(Formats.DATETIME_MED):
+ return "LLL d, yyyy, h:mm a";
+ case stringify(Formats.DATETIME_FULL):
+ return "LLLL d, yyyy, h:mm a";
+ case stringify(Formats.DATETIME_HUGE):
+ return dateTimeHuge;
+ case stringify(Formats.DATETIME_SHORT_WITH_SECONDS):
+ return "M/d/yyyy, h:mm:ss a";
+ case stringify(Formats.DATETIME_MED_WITH_SECONDS):
+ return "LLL d, yyyy, h:mm:ss a";
+ case stringify(Formats.DATETIME_MED_WITH_WEEKDAY):
+ return "EEE, d LLL yyyy, h:mm a";
+ case stringify(Formats.DATETIME_FULL_WITH_SECONDS):
+ return "LLLL d, yyyy, h:mm:ss a";
+ case stringify(Formats.DATETIME_HUGE_WITH_SECONDS):
+ return "EEEE, LLLL d, yyyy, h:mm:ss a";
+ default:
+ return dateTimeHuge;
+ }
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/formats.js b/npm_assets/node_modules/luxon/src/impl/formats.js
new file mode 100644
index 0000000..25210f6
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/formats.js
@@ -0,0 +1,191 @@
+/**
+ * @private
+ */
+
+const n = "numeric",
+ s = "short",
+ l = "long";
+
+export const DATE_SHORT = {
+ year: n,
+ month: n,
+ day: n
+};
+
+export const DATE_MED = {
+ year: n,
+ month: s,
+ day: n
+};
+
+export const DATE_MED_WITH_WEEKDAY = {
+ year: n,
+ month: s,
+ day: n,
+ weekday: s
+};
+
+export const DATE_FULL = {
+ year: n,
+ month: l,
+ day: n
+};
+
+export const DATE_HUGE = {
+ year: n,
+ month: l,
+ day: n,
+ weekday: l
+};
+
+export const TIME_SIMPLE = {
+ hour: n,
+ minute: n
+};
+
+export const TIME_WITH_SECONDS = {
+ hour: n,
+ minute: n,
+ second: n
+};
+
+export const TIME_WITH_SHORT_OFFSET = {
+ hour: n,
+ minute: n,
+ second: n,
+ timeZoneName: s
+};
+
+export const TIME_WITH_LONG_OFFSET = {
+ hour: n,
+ minute: n,
+ second: n,
+ timeZoneName: l
+};
+
+export const TIME_24_SIMPLE = {
+ hour: n,
+ minute: n,
+ hour12: false
+};
+
+/**
+ * {@link toLocaleString}; format like '09:30:23', always 24-hour.
+ */
+export const TIME_24_WITH_SECONDS = {
+ hour: n,
+ minute: n,
+ second: n,
+ hour12: false
+};
+
+/**
+ * {@link toLocaleString}; format like '09:30:23 EDT', always 24-hour.
+ */
+export const TIME_24_WITH_SHORT_OFFSET = {
+ hour: n,
+ minute: n,
+ second: n,
+ hour12: false,
+ timeZoneName: s
+};
+
+/**
+ * {@link toLocaleString}; format like '09:30:23 Eastern Daylight Time', always 24-hour.
+ */
+export const TIME_24_WITH_LONG_OFFSET = {
+ hour: n,
+ minute: n,
+ second: n,
+ hour12: false,
+ timeZoneName: l
+};
+
+/**
+ * {@link toLocaleString}; format like '10/14/1983, 9:30 AM'. Only 12-hour if the locale is.
+ */
+export const DATETIME_SHORT = {
+ year: n,
+ month: n,
+ day: n,
+ hour: n,
+ minute: n
+};
+
+/**
+ * {@link toLocaleString}; format like '10/14/1983, 9:30:33 AM'. Only 12-hour if the locale is.
+ */
+export const DATETIME_SHORT_WITH_SECONDS = {
+ year: n,
+ month: n,
+ day: n,
+ hour: n,
+ minute: n,
+ second: n
+};
+
+export const DATETIME_MED = {
+ year: n,
+ month: s,
+ day: n,
+ hour: n,
+ minute: n
+};
+
+export const DATETIME_MED_WITH_SECONDS = {
+ year: n,
+ month: s,
+ day: n,
+ hour: n,
+ minute: n,
+ second: n
+};
+
+export const DATETIME_MED_WITH_WEEKDAY = {
+ year: n,
+ month: s,
+ day: n,
+ weekday: s,
+ hour: n,
+ minute: n
+};
+
+export const DATETIME_FULL = {
+ year: n,
+ month: l,
+ day: n,
+ hour: n,
+ minute: n,
+ timeZoneName: s
+};
+
+export const DATETIME_FULL_WITH_SECONDS = {
+ year: n,
+ month: l,
+ day: n,
+ hour: n,
+ minute: n,
+ second: n,
+ timeZoneName: s
+};
+
+export const DATETIME_HUGE = {
+ year: n,
+ month: l,
+ day: n,
+ weekday: l,
+ hour: n,
+ minute: n,
+ timeZoneName: l
+};
+
+export const DATETIME_HUGE_WITH_SECONDS = {
+ year: n,
+ month: l,
+ day: n,
+ weekday: l,
+ hour: n,
+ minute: n,
+ second: n,
+ timeZoneName: l
+};
diff --git a/npm_assets/node_modules/luxon/src/impl/formatter.js b/npm_assets/node_modules/luxon/src/impl/formatter.js
new file mode 100644
index 0000000..98872f9
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/formatter.js
@@ -0,0 +1,386 @@
+import * as English from "./english.js";
+import * as Formats from "./formats.js";
+import { hasFormatToParts, padStart } from "./util.js";
+
+function stringifyTokens(splits, tokenToString) {
+ let s = "";
+ for (const token of splits) {
+ if (token.literal) {
+ s += token.val;
+ } else {
+ s += tokenToString(token.val);
+ }
+ }
+ return s;
+}
+
+const macroTokenToFormatOpts = {
+ D: Formats.DATE_SHORT,
+ DD: Formats.DATE_MED,
+ DDD: Formats.DATE_FULL,
+ DDDD: Formats.DATE_HUGE,
+ t: Formats.TIME_SIMPLE,
+ tt: Formats.TIME_WITH_SECONDS,
+ ttt: Formats.TIME_WITH_SHORT_OFFSET,
+ tttt: Formats.TIME_WITH_LONG_OFFSET,
+ T: Formats.TIME_24_SIMPLE,
+ TT: Formats.TIME_24_WITH_SECONDS,
+ TTT: Formats.TIME_24_WITH_SHORT_OFFSET,
+ TTTT: Formats.TIME_24_WITH_LONG_OFFSET,
+ f: Formats.DATETIME_SHORT,
+ ff: Formats.DATETIME_MED,
+ fff: Formats.DATETIME_FULL,
+ ffff: Formats.DATETIME_HUGE,
+ F: Formats.DATETIME_SHORT_WITH_SECONDS,
+ FF: Formats.DATETIME_MED_WITH_SECONDS,
+ FFF: Formats.DATETIME_FULL_WITH_SECONDS,
+ FFFF: Formats.DATETIME_HUGE_WITH_SECONDS
+};
+
+/**
+ * @private
+ */
+
+export default class Formatter {
+ static create(locale, opts = {}) {
+ return new Formatter(locale, opts);
+ }
+
+ static parseFormat(fmt) {
+ let current = null,
+ currentFull = "",
+ bracketed = false;
+ const splits = [];
+ for (let i = 0; i < fmt.length; i++) {
+ const c = fmt.charAt(i);
+ if (c === "'") {
+ if (currentFull.length > 0) {
+ splits.push({ literal: bracketed, val: currentFull });
+ }
+ current = null;
+ currentFull = "";
+ bracketed = !bracketed;
+ } else if (bracketed) {
+ currentFull += c;
+ } else if (c === current) {
+ currentFull += c;
+ } else {
+ if (currentFull.length > 0) {
+ splits.push({ literal: false, val: currentFull });
+ }
+ currentFull = c;
+ current = c;
+ }
+ }
+
+ if (currentFull.length > 0) {
+ splits.push({ literal: bracketed, val: currentFull });
+ }
+
+ return splits;
+ }
+
+ static macroTokenToFormatOpts(token) {
+ return macroTokenToFormatOpts[token];
+ }
+
+ constructor(locale, formatOpts) {
+ this.opts = formatOpts;
+ this.loc = locale;
+ this.systemLoc = null;
+ }
+
+ formatWithSystemDefault(dt, opts) {
+ if (this.systemLoc === null) {
+ this.systemLoc = this.loc.redefaultToSystem();
+ }
+ const df = this.systemLoc.dtFormatter(dt, Object.assign({}, this.opts, opts));
+ return df.format();
+ }
+
+ formatDateTime(dt, opts = {}) {
+ const df = this.loc.dtFormatter(dt, Object.assign({}, this.opts, opts));
+ return df.format();
+ }
+
+ formatDateTimeParts(dt, opts = {}) {
+ const df = this.loc.dtFormatter(dt, Object.assign({}, this.opts, opts));
+ return df.formatToParts();
+ }
+
+ resolvedOptions(dt, opts = {}) {
+ const df = this.loc.dtFormatter(dt, Object.assign({}, this.opts, opts));
+ return df.resolvedOptions();
+ }
+
+ num(n, p = 0) {
+ // we get some perf out of doing this here, annoyingly
+ if (this.opts.forceSimple) {
+ return padStart(n, p);
+ }
+
+ const opts = Object.assign({}, this.opts);
+
+ if (p > 0) {
+ opts.padTo = p;
+ }
+
+ return this.loc.numberFormatter(opts).format(n);
+ }
+
+ formatDateTimeFromString(dt, fmt) {
+ const knownEnglish = this.loc.listingMode() === "en",
+ useDateTimeFormatter =
+ this.loc.outputCalendar && this.loc.outputCalendar !== "gregory" && hasFormatToParts(),
+ string = (opts, extract) => this.loc.extract(dt, opts, extract),
+ formatOffset = opts => {
+ if (dt.isOffsetFixed && dt.offset === 0 && opts.allowZ) {
+ return "Z";
+ }
+
+ return dt.isValid ? dt.zone.formatOffset(dt.ts, opts.format) : "";
+ },
+ meridiem = () =>
+ knownEnglish
+ ? English.meridiemForDateTime(dt)
+ : string({ hour: "numeric", hour12: true }, "dayperiod"),
+ month = (length, standalone) =>
+ knownEnglish
+ ? English.monthForDateTime(dt, length)
+ : string(standalone ? { month: length } : { month: length, day: "numeric" }, "month"),
+ weekday = (length, standalone) =>
+ knownEnglish
+ ? English.weekdayForDateTime(dt, length)
+ : string(
+ standalone ? { weekday: length } : { weekday: length, month: "long", day: "numeric" },
+ "weekday"
+ ),
+ maybeMacro = token => {
+ const formatOpts = Formatter.macroTokenToFormatOpts(token);
+ if (formatOpts) {
+ return this.formatWithSystemDefault(dt, formatOpts);
+ } else {
+ return token;
+ }
+ },
+ era = length =>
+ knownEnglish ? English.eraForDateTime(dt, length) : string({ era: length }, "era"),
+ tokenToString = token => {
+ // Where possible: http://cldr.unicode.org/translation/date-time#TOC-Stand-Alone-vs.-Format-Styles
+ switch (token) {
+ // ms
+ case "S":
+ return this.num(dt.millisecond);
+ case "u":
+ // falls through
+ case "SSS":
+ return this.num(dt.millisecond, 3);
+ // seconds
+ case "s":
+ return this.num(dt.second);
+ case "ss":
+ return this.num(dt.second, 2);
+ // minutes
+ case "m":
+ return this.num(dt.minute);
+ case "mm":
+ return this.num(dt.minute, 2);
+ // hours
+ case "h":
+ return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12);
+ case "hh":
+ return this.num(dt.hour % 12 === 0 ? 12 : dt.hour % 12, 2);
+ case "H":
+ return this.num(dt.hour);
+ case "HH":
+ return this.num(dt.hour, 2);
+ // offset
+ case "Z":
+ // like +6
+ return formatOffset({ format: "narrow", allowZ: this.opts.allowZ });
+ case "ZZ":
+ // like +06:00
+ return formatOffset({ format: "short", allowZ: this.opts.allowZ });
+ case "ZZZ":
+ // like +0600
+ return formatOffset({ format: "techie", allowZ: this.opts.allowZ });
+ case "ZZZZ":
+ // like EST
+ return dt.zone.offsetName(dt.ts, { format: "short", locale: this.loc.locale });
+ case "ZZZZZ":
+ // like Eastern Standard Time
+ return dt.zone.offsetName(dt.ts, { format: "long", locale: this.loc.locale });
+ // zone
+ case "z":
+ // like America/New_York
+ return dt.zoneName;
+ // meridiems
+ case "a":
+ return meridiem();
+ // dates
+ case "d":
+ return useDateTimeFormatter ? string({ day: "numeric" }, "day") : this.num(dt.day);
+ case "dd":
+ return useDateTimeFormatter ? string({ day: "2-digit" }, "day") : this.num(dt.day, 2);
+ // weekdays - standalone
+ case "c":
+ // like 1
+ return this.num(dt.weekday);
+ case "ccc":
+ // like 'Tues'
+ return weekday("short", true);
+ case "cccc":
+ // like 'Tuesday'
+ return weekday("long", true);
+ case "ccccc":
+ // like 'T'
+ return weekday("narrow", true);
+ // weekdays - format
+ case "E":
+ // like 1
+ return this.num(dt.weekday);
+ case "EEE":
+ // like 'Tues'
+ return weekday("short", false);
+ case "EEEE":
+ // like 'Tuesday'
+ return weekday("long", false);
+ case "EEEEE":
+ // like 'T'
+ return weekday("narrow", false);
+ // months - standalone
+ case "L":
+ // like 1
+ return useDateTimeFormatter
+ ? string({ month: "numeric", day: "numeric" }, "month")
+ : this.num(dt.month);
+ case "LL":
+ // like 01, doesn't seem to work
+ return useDateTimeFormatter
+ ? string({ month: "2-digit", day: "numeric" }, "month")
+ : this.num(dt.month, 2);
+ case "LLL":
+ // like Jan
+ return month("short", true);
+ case "LLLL":
+ // like January
+ return month("long", true);
+ case "LLLLL":
+ // like J
+ return month("narrow", true);
+ // months - format
+ case "M":
+ // like 1
+ return useDateTimeFormatter
+ ? string({ month: "numeric" }, "month")
+ : this.num(dt.month);
+ case "MM":
+ // like 01
+ return useDateTimeFormatter
+ ? string({ month: "2-digit" }, "month")
+ : this.num(dt.month, 2);
+ case "MMM":
+ // like Jan
+ return month("short", false);
+ case "MMMM":
+ // like January
+ return month("long", false);
+ case "MMMMM":
+ // like J
+ return month("narrow", false);
+ // years
+ case "y":
+ // like 2014
+ return useDateTimeFormatter ? string({ year: "numeric" }, "year") : this.num(dt.year);
+ case "yy":
+ // like 14
+ return useDateTimeFormatter
+ ? string({ year: "2-digit" }, "year")
+ : this.num(dt.year.toString().slice(-2), 2);
+ case "yyyy":
+ // like 0012
+ return useDateTimeFormatter
+ ? string({ year: "numeric" }, "year")
+ : this.num(dt.year, 4);
+ case "yyyyyy":
+ // like 000012
+ return useDateTimeFormatter
+ ? string({ year: "numeric" }, "year")
+ : this.num(dt.year, 6);
+ // eras
+ case "G":
+ // like AD
+ return era("short");
+ case "GG":
+ // like Anno Domini
+ return era("long");
+ case "GGGGG":
+ return era("narrow");
+ case "kk":
+ return this.num(dt.weekYear.toString().slice(-2), 2);
+ case "kkkk":
+ return this.num(dt.weekYear, 4);
+ case "W":
+ return this.num(dt.weekNumber);
+ case "WW":
+ return this.num(dt.weekNumber, 2);
+ case "o":
+ return this.num(dt.ordinal);
+ case "ooo":
+ return this.num(dt.ordinal, 3);
+ case "q":
+ // like 1
+ return this.num(dt.quarter);
+ case "qq":
+ // like 01
+ return this.num(dt.quarter, 2);
+ case "X":
+ return this.num(Math.floor(dt.ts / 1000));
+ case "x":
+ return this.num(dt.ts);
+ default:
+ return maybeMacro(token);
+ }
+ };
+
+ return stringifyTokens(Formatter.parseFormat(fmt), tokenToString);
+ }
+
+ formatDurationFromString(dur, fmt) {
+ const tokenToField = token => {
+ switch (token[0]) {
+ case "S":
+ return "millisecond";
+ case "s":
+ return "second";
+ case "m":
+ return "minute";
+ case "h":
+ return "hour";
+ case "d":
+ return "day";
+ case "M":
+ return "month";
+ case "y":
+ return "year";
+ default:
+ return null;
+ }
+ },
+ tokenToString = lildur => token => {
+ const mapped = tokenToField(token);
+ if (mapped) {
+ return this.num(lildur.get(mapped), token.length);
+ } else {
+ return token;
+ }
+ },
+ tokens = Formatter.parseFormat(fmt),
+ realTokens = tokens.reduce(
+ (found, { literal, val }) => (literal ? found : found.concat(val)),
+ []
+ ),
+ collapsed = dur.shiftTo(...realTokens.map(tokenToField).filter(t => t));
+ return stringifyTokens(tokens, tokenToString(collapsed));
+ }
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/invalid.js b/npm_assets/node_modules/luxon/src/impl/invalid.js
new file mode 100644
index 0000000..2a2c95b
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/invalid.js
@@ -0,0 +1,14 @@
+export default class Invalid {
+ constructor(reason, explanation) {
+ this.reason = reason;
+ this.explanation = explanation;
+ }
+
+ toMessage() {
+ if (this.explanation) {
+ return `${this.reason}: ${this.explanation}`;
+ } else {
+ return this.reason;
+ }
+ }
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/locale.js b/npm_assets/node_modules/luxon/src/impl/locale.js
new file mode 100644
index 0000000..0f797b1
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/locale.js
@@ -0,0 +1,469 @@
+import { hasFormatToParts, hasIntl, padStart, roundTo, hasRelative } from "./util.js";
+import * as English from "./english.js";
+import Settings from "../settings.js";
+import DateTime from "../datetime.js";
+import Formatter from "./formatter.js";
+
+let intlDTCache = {};
+function getCachedDTF(locString, opts = {}) {
+ const key = JSON.stringify([locString, opts]);
+ let dtf = intlDTCache[key];
+ if (!dtf) {
+ dtf = new Intl.DateTimeFormat(locString, opts);
+ intlDTCache[key] = dtf;
+ }
+ return dtf;
+}
+
+let intlNumCache = {};
+function getCachedINF(locString, opts = {}) {
+ const key = JSON.stringify([locString, opts]);
+ let inf = intlNumCache[key];
+ if (!inf) {
+ inf = new Intl.NumberFormat(locString, opts);
+ intlNumCache[key] = inf;
+ }
+ return inf;
+}
+
+let intlRelCache = {};
+function getCachedRTF(locString, opts = {}) {
+ const { base, ...cacheKeyOpts } = opts; // exclude `base` from the options
+ const key = JSON.stringify([locString, cacheKeyOpts]);
+ let inf = intlRelCache[key];
+ if (!inf) {
+ inf = new Intl.RelativeTimeFormat(locString, opts);
+ intlRelCache[key] = inf;
+ }
+ return inf;
+}
+
+let sysLocaleCache = null;
+function systemLocale() {
+ if (sysLocaleCache) {
+ return sysLocaleCache;
+ } else if (hasIntl()) {
+ const computedSys = new Intl.DateTimeFormat().resolvedOptions().locale;
+ // node sometimes defaults to "und". Override that because that is dumb
+ sysLocaleCache = !computedSys || computedSys === "und" ? "en-US" : computedSys;
+ return sysLocaleCache;
+ } else {
+ sysLocaleCache = "en-US";
+ return sysLocaleCache;
+ }
+}
+
+function parseLocaleString(localeStr) {
+ // I really want to avoid writing a BCP 47 parser
+ // see, e.g. https://github.com/wooorm/bcp-47
+ // Instead, we'll do this:
+
+ // a) if the string has no -u extensions, just leave it alone
+ // b) if it does, use Intl to resolve everything
+ // c) if Intl fails, try again without the -u
+
+ const uIndex = localeStr.indexOf("-u-");
+ if (uIndex === -1) {
+ return [localeStr];
+ } else {
+ let options;
+ const smaller = localeStr.substring(0, uIndex);
+ try {
+ options = getCachedDTF(localeStr).resolvedOptions();
+ } catch (e) {
+ options = getCachedDTF(smaller).resolvedOptions();
+ }
+
+ const { numberingSystem, calendar } = options;
+ // return the smaller one so that we can append the calendar and numbering overrides to it
+ return [smaller, numberingSystem, calendar];
+ }
+}
+
+function intlConfigString(localeStr, numberingSystem, outputCalendar) {
+ if (hasIntl()) {
+ if (outputCalendar || numberingSystem) {
+ localeStr += "-u";
+
+ if (outputCalendar) {
+ localeStr += `-ca-${outputCalendar}`;
+ }
+
+ if (numberingSystem) {
+ localeStr += `-nu-${numberingSystem}`;
+ }
+ return localeStr;
+ } else {
+ return localeStr;
+ }
+ } else {
+ return [];
+ }
+}
+
+function mapMonths(f) {
+ const ms = [];
+ for (let i = 1; i <= 12; i++) {
+ const dt = DateTime.utc(2016, i, 1);
+ ms.push(f(dt));
+ }
+ return ms;
+}
+
+function mapWeekdays(f) {
+ const ms = [];
+ for (let i = 1; i <= 7; i++) {
+ const dt = DateTime.utc(2016, 11, 13 + i);
+ ms.push(f(dt));
+ }
+ return ms;
+}
+
+function listStuff(loc, length, defaultOK, englishFn, intlFn) {
+ const mode = loc.listingMode(defaultOK);
+
+ if (mode === "error") {
+ return null;
+ } else if (mode === "en") {
+ return englishFn(length);
+ } else {
+ return intlFn(length);
+ }
+}
+
+function supportsFastNumbers(loc) {
+ if (loc.numberingSystem && loc.numberingSystem !== "latn") {
+ return false;
+ } else {
+ return (
+ loc.numberingSystem === "latn" ||
+ !loc.locale ||
+ loc.locale.startsWith("en") ||
+ (hasIntl() && new Intl.DateTimeFormat(loc.intl).resolvedOptions().numberingSystem === "latn")
+ );
+ }
+}
+
+/**
+ * @private
+ */
+
+class PolyNumberFormatter {
+ constructor(intl, forceSimple, opts) {
+ this.padTo = opts.padTo || 0;
+ this.floor = opts.floor || false;
+
+ if (!forceSimple && hasIntl()) {
+ const intlOpts = { useGrouping: false };
+ if (opts.padTo > 0) intlOpts.minimumIntegerDigits = opts.padTo;
+ this.inf = getCachedINF(intl, intlOpts);
+ }
+ }
+
+ format(i) {
+ if (this.inf) {
+ const fixed = this.floor ? Math.floor(i) : i;
+ return this.inf.format(fixed);
+ } else {
+ // to match the browser's numberformatter defaults
+ const fixed = this.floor ? Math.floor(i) : roundTo(i, 3);
+ return padStart(fixed, this.padTo);
+ }
+ }
+}
+
+/**
+ * @private
+ */
+
+class PolyDateFormatter {
+ constructor(dt, intl, opts) {
+ this.opts = opts;
+ this.hasIntl = hasIntl();
+
+ let z;
+ if (dt.zone.universal && this.hasIntl) {
+ // Chromium doesn't support fixed-offset zones like Etc/GMT+8 in its formatter,
+ // See https://bugs.chromium.org/p/chromium/issues/detail?id=364374.
+ // So we have to make do. Two cases:
+ // 1. The format options tell us to show the zone. We can't do that, so the best
+ // we can do is format the date in UTC.
+ // 2. The format options don't tell us to show the zone. Then we can adjust them
+ // the time and tell the formatter to show it to us in UTC, so that the time is right
+ // and the bad zone doesn't show up.
+ // We can clean all this up when Chrome fixes this.
+ z = "UTC";
+ if (opts.timeZoneName) {
+ this.dt = dt;
+ } else {
+ this.dt = dt.offset === 0 ? dt : DateTime.fromMillis(dt.ts + dt.offset * 60 * 1000);
+ }
+ } else if (dt.zone.type === "local") {
+ this.dt = dt;
+ } else {
+ this.dt = dt;
+ z = dt.zone.name;
+ }
+
+ if (this.hasIntl) {
+ const intlOpts = Object.assign({}, this.opts);
+ if (z) {
+ intlOpts.timeZone = z;
+ }
+ this.dtf = getCachedDTF(intl, intlOpts);
+ }
+ }
+
+ format() {
+ if (this.hasIntl) {
+ return this.dtf.format(this.dt.toJSDate());
+ } else {
+ const tokenFormat = English.formatString(this.opts),
+ loc = Locale.create("en-US");
+ return Formatter.create(loc).formatDateTimeFromString(this.dt, tokenFormat);
+ }
+ }
+
+ formatToParts() {
+ if (this.hasIntl && hasFormatToParts()) {
+ return this.dtf.formatToParts(this.dt.toJSDate());
+ } else {
+ // This is kind of a cop out. We actually could do this for English. However, we couldn't do it for intl strings
+ // and IMO it's too weird to have an uncanny valley like that
+ return [];
+ }
+ }
+
+ resolvedOptions() {
+ if (this.hasIntl) {
+ return this.dtf.resolvedOptions();
+ } else {
+ return {
+ locale: "en-US",
+ numberingSystem: "latn",
+ outputCalendar: "gregory"
+ };
+ }
+ }
+}
+
+/**
+ * @private
+ */
+class PolyRelFormatter {
+ constructor(intl, isEnglish, opts) {
+ this.opts = Object.assign({ style: "long" }, opts);
+ if (!isEnglish && hasRelative()) {
+ this.rtf = getCachedRTF(intl, opts);
+ }
+ }
+
+ format(count, unit) {
+ if (this.rtf) {
+ return this.rtf.format(count, unit);
+ } else {
+ return English.formatRelativeTime(unit, count, this.opts.numeric, this.opts.style !== "long");
+ }
+ }
+
+ formatToParts(count, unit) {
+ if (this.rtf) {
+ return this.rtf.formatToParts(count, unit);
+ } else {
+ return [];
+ }
+ }
+}
+
+/**
+ * @private
+ */
+
+export default class Locale {
+ static fromOpts(opts) {
+ return Locale.create(opts.locale, opts.numberingSystem, opts.outputCalendar, opts.defaultToEN);
+ }
+
+ static create(locale, numberingSystem, outputCalendar, defaultToEN = false) {
+ const specifiedLocale = locale || Settings.defaultLocale,
+ // the system locale is useful for human readable strings but annoying for parsing/formatting known formats
+ localeR = specifiedLocale || (defaultToEN ? "en-US" : systemLocale()),
+ numberingSystemR = numberingSystem || Settings.defaultNumberingSystem,
+ outputCalendarR = outputCalendar || Settings.defaultOutputCalendar;
+ return new Locale(localeR, numberingSystemR, outputCalendarR, specifiedLocale);
+ }
+
+ static resetCache() {
+ sysLocaleCache = null;
+ intlDTCache = {};
+ intlNumCache = {};
+ intlRelCache = {};
+ }
+
+ static fromObject({ locale, numberingSystem, outputCalendar } = {}) {
+ return Locale.create(locale, numberingSystem, outputCalendar);
+ }
+
+ constructor(locale, numbering, outputCalendar, specifiedLocale) {
+ const [parsedLocale, parsedNumberingSystem, parsedOutputCalendar] = parseLocaleString(locale);
+
+ this.locale = parsedLocale;
+ this.numberingSystem = numbering || parsedNumberingSystem || null;
+ this.outputCalendar = outputCalendar || parsedOutputCalendar || null;
+ this.intl = intlConfigString(this.locale, this.numberingSystem, this.outputCalendar);
+
+ this.weekdaysCache = { format: {}, standalone: {} };
+ this.monthsCache = { format: {}, standalone: {} };
+ this.meridiemCache = null;
+ this.eraCache = {};
+
+ this.specifiedLocale = specifiedLocale;
+ this.fastNumbersCached = null;
+ }
+
+ get fastNumbers() {
+ if (this.fastNumbersCached == null) {
+ this.fastNumbersCached = supportsFastNumbers(this);
+ }
+
+ return this.fastNumbersCached;
+ }
+
+ listingMode(defaultOK = true) {
+ const intl = hasIntl(),
+ hasFTP = intl && hasFormatToParts(),
+ isActuallyEn = this.isEnglish(),
+ hasNoWeirdness =
+ (this.numberingSystem === null || this.numberingSystem === "latn") &&
+ (this.outputCalendar === null || this.outputCalendar === "gregory");
+
+ if (!hasFTP && !(isActuallyEn && hasNoWeirdness) && !defaultOK) {
+ return "error";
+ } else if (!hasFTP || (isActuallyEn && hasNoWeirdness)) {
+ return "en";
+ } else {
+ return "intl";
+ }
+ }
+
+ clone(alts) {
+ if (!alts || Object.getOwnPropertyNames(alts).length === 0) {
+ return this;
+ } else {
+ return Locale.create(
+ alts.locale || this.specifiedLocale,
+ alts.numberingSystem || this.numberingSystem,
+ alts.outputCalendar || this.outputCalendar,
+ alts.defaultToEN || false
+ );
+ }
+ }
+
+ redefaultToEN(alts = {}) {
+ return this.clone(Object.assign({}, alts, { defaultToEN: true }));
+ }
+
+ redefaultToSystem(alts = {}) {
+ return this.clone(Object.assign({}, alts, { defaultToEN: false }));
+ }
+
+ months(length, format = false, defaultOK = true) {
+ return listStuff(this, length, defaultOK, English.months, () => {
+ const intl = format ? { month: length, day: "numeric" } : { month: length },
+ formatStr = format ? "format" : "standalone";
+ if (!this.monthsCache[formatStr][length]) {
+ this.monthsCache[formatStr][length] = mapMonths(dt => this.extract(dt, intl, "month"));
+ }
+ return this.monthsCache[formatStr][length];
+ });
+ }
+
+ weekdays(length, format = false, defaultOK = true) {
+ return listStuff(this, length, defaultOK, English.weekdays, () => {
+ const intl = format
+ ? { weekday: length, year: "numeric", month: "long", day: "numeric" }
+ : { weekday: length },
+ formatStr = format ? "format" : "standalone";
+ if (!this.weekdaysCache[formatStr][length]) {
+ this.weekdaysCache[formatStr][length] = mapWeekdays(dt =>
+ this.extract(dt, intl, "weekday")
+ );
+ }
+ return this.weekdaysCache[formatStr][length];
+ });
+ }
+
+ meridiems(defaultOK = true) {
+ return listStuff(
+ this,
+ undefined,
+ defaultOK,
+ () => English.meridiems,
+ () => {
+ // In theory there could be aribitrary day periods. We're gonna assume there are exactly two
+ // for AM and PM. This is probably wrong, but it's makes parsing way easier.
+ if (!this.meridiemCache) {
+ const intl = { hour: "numeric", hour12: true };
+ this.meridiemCache = [DateTime.utc(2016, 11, 13, 9), DateTime.utc(2016, 11, 13, 19)].map(
+ dt => this.extract(dt, intl, "dayperiod")
+ );
+ }
+
+ return this.meridiemCache;
+ }
+ );
+ }
+
+ eras(length, defaultOK = true) {
+ return listStuff(this, length, defaultOK, English.eras, () => {
+ const intl = { era: length };
+
+ // This is utter bullshit. Different calendars are going to define eras totally differently. What I need is the minimum set of dates
+ // to definitely enumerate them.
+ if (!this.eraCache[length]) {
+ this.eraCache[length] = [DateTime.utc(-40, 1, 1), DateTime.utc(2017, 1, 1)].map(dt =>
+ this.extract(dt, intl, "era")
+ );
+ }
+
+ return this.eraCache[length];
+ });
+ }
+
+ extract(dt, intlOpts, field) {
+ const df = this.dtFormatter(dt, intlOpts),
+ results = df.formatToParts(),
+ matching = results.find(m => m.type.toLowerCase() === field);
+ return matching ? matching.value : null;
+ }
+
+ numberFormatter(opts = {}) {
+ // this forcesimple option is never used (the only caller short-circuits on it, but it seems safer to leave)
+ // (in contrast, the rest of the condition is used heavily)
+ return new PolyNumberFormatter(this.intl, opts.forceSimple || this.fastNumbers, opts);
+ }
+
+ dtFormatter(dt, intlOpts = {}) {
+ return new PolyDateFormatter(dt, this.intl, intlOpts);
+ }
+
+ relFormatter(opts = {}) {
+ return new PolyRelFormatter(this.intl, this.isEnglish(), opts);
+ }
+
+ isEnglish() {
+ return (
+ this.locale === "en" ||
+ this.locale.toLowerCase() === "en-us" ||
+ (hasIntl() && new Intl.DateTimeFormat(this.intl).resolvedOptions().locale.startsWith("en-us"))
+ );
+ }
+
+ equals(other) {
+ return (
+ this.locale === other.locale &&
+ this.numberingSystem === other.numberingSystem &&
+ this.outputCalendar === other.outputCalendar
+ );
+ }
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/regexParser.js b/npm_assets/node_modules/luxon/src/impl/regexParser.js
new file mode 100644
index 0000000..74ba737
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/regexParser.js
@@ -0,0 +1,319 @@
+import {
+ untruncateYear,
+ signedOffset,
+ parseInteger,
+ parseMillis,
+ ianaRegex,
+ isUndefined
+} from "./util.js";
+import * as English from "./english.js";
+import FixedOffsetZone from "../zones/fixedOffsetZone.js";
+import IANAZone from "../zones/IANAZone.js";
+
+/*
+ * This file handles parsing for well-specified formats. Here's how it works:
+ * Two things go into parsing: a regex to match with and an extractor to take apart the groups in the match.
+ * An extractor is just a function that takes a regex match array and returns a { year: ..., month: ... } object
+ * parse() does the work of executing the regex and applying the extractor. It takes multiple regex/extractor pairs to try in sequence.
+ * Extractors can take a "cursor" representing the offset in the match to look at. This makes it easy to combine extractors.
+ * combineExtractors() does the work of combining them, keeping track of the cursor through multiple extractions.
+ * Some extractions are super dumb and simpleParse and fromStrings help DRY them.
+ */
+
+function combineRegexes(...regexes) {
+ const full = regexes.reduce((f, r) => f + r.source, "");
+ return RegExp(`^${full}$`);
+}
+
+function combineExtractors(...extractors) {
+ return m =>
+ extractors
+ .reduce(
+ ([mergedVals, mergedZone, cursor], ex) => {
+ const [val, zone, next] = ex(m, cursor);
+ return [Object.assign(mergedVals, val), mergedZone || zone, next];
+ },
+ [{}, null, 1]
+ )
+ .slice(0, 2);
+}
+
+function parse(s, ...patterns) {
+ if (s == null) {
+ return [null, null];
+ }
+
+ for (const [regex, extractor] of patterns) {
+ const m = regex.exec(s);
+ if (m) {
+ return extractor(m);
+ }
+ }
+ return [null, null];
+}
+
+function simpleParse(...keys) {
+ return (match, cursor) => {
+ const ret = {};
+ let i;
+
+ for (i = 0; i < keys.length; i++) {
+ ret[keys[i]] = parseInteger(match[cursor + i]);
+ }
+ return [ret, null, cursor + i];
+ };
+}
+
+// ISO and SQL parsing
+const offsetRegex = /(?:(Z)|([+-]\d\d)(?::?(\d\d))?)/,
+ isoTimeBaseRegex = /(\d\d)(?::?(\d\d)(?::?(\d\d)(?:[.,](\d{1,30}))?)?)?/,
+ isoTimeRegex = RegExp(`${isoTimeBaseRegex.source}${offsetRegex.source}?`),
+ isoTimeExtensionRegex = RegExp(`(?:T${isoTimeRegex.source})?`),
+ isoYmdRegex = /([+-]\d{6}|\d{4})(?:-?(\d\d)(?:-?(\d\d))?)?/,
+ isoWeekRegex = /(\d{4})-?W(\d\d)(?:-?(\d))?/,
+ isoOrdinalRegex = /(\d{4})-?(\d{3})/,
+ extractISOWeekData = simpleParse("weekYear", "weekNumber", "weekDay"),
+ extractISOOrdinalData = simpleParse("year", "ordinal"),
+ sqlYmdRegex = /(\d{4})-(\d\d)-(\d\d)/, // dumbed-down version of the ISO one
+ sqlTimeRegex = RegExp(
+ `${isoTimeBaseRegex.source} ?(?:${offsetRegex.source}|(${ianaRegex.source}))?`
+ ),
+ sqlTimeExtensionRegex = RegExp(`(?: ${sqlTimeRegex.source})?`);
+
+function int(match, pos, fallback) {
+ const m = match[pos];
+ return isUndefined(m) ? fallback : parseInteger(m);
+}
+
+function extractISOYmd(match, cursor) {
+ const item = {
+ year: int(match, cursor),
+ month: int(match, cursor + 1, 1),
+ day: int(match, cursor + 2, 1)
+ };
+
+ return [item, null, cursor + 3];
+}
+
+function extractISOTime(match, cursor) {
+ const item = {
+ hour: int(match, cursor, 0),
+ minute: int(match, cursor + 1, 0),
+ second: int(match, cursor + 2, 0),
+ millisecond: parseMillis(match[cursor + 3])
+ };
+
+ return [item, null, cursor + 4];
+}
+
+function extractISOOffset(match, cursor) {
+ const local = !match[cursor] && !match[cursor + 1],
+ fullOffset = signedOffset(match[cursor + 1], match[cursor + 2]),
+ zone = local ? null : FixedOffsetZone.instance(fullOffset);
+ return [{}, zone, cursor + 3];
+}
+
+function extractIANAZone(match, cursor) {
+ const zone = match[cursor] ? IANAZone.create(match[cursor]) : null;
+ return [{}, zone, cursor + 1];
+}
+
+// ISO duration parsing
+
+const isoDuration = /^-?P(?:(?:(-?\d{1,9})Y)?(?:(-?\d{1,9})M)?(?:(-?\d{1,9})W)?(?:(-?\d{1,9})D)?(?:T(?:(-?\d{1,9})H)?(?:(-?\d{1,9})M)?(?:(-?\d{1,20})(?:[.,](-?\d{1,9}))?S)?)?)$/;
+
+function extractISODuration(match) {
+ const [
+ s,
+ yearStr,
+ monthStr,
+ weekStr,
+ dayStr,
+ hourStr,
+ minuteStr,
+ secondStr,
+ millisecondsStr
+ ] = match;
+
+ const hasNegativePrefix = s[0] === "-";
+
+ const maybeNegate = num => (num && hasNegativePrefix ? -num : num);
+
+ return [
+ {
+ years: maybeNegate(parseInteger(yearStr)),
+ months: maybeNegate(parseInteger(monthStr)),
+ weeks: maybeNegate(parseInteger(weekStr)),
+ days: maybeNegate(parseInteger(dayStr)),
+ hours: maybeNegate(parseInteger(hourStr)),
+ minutes: maybeNegate(parseInteger(minuteStr)),
+ seconds: maybeNegate(parseInteger(secondStr)),
+ milliseconds: maybeNegate(parseMillis(millisecondsStr))
+ }
+ ];
+}
+
+// These are a little braindead. EDT *should* tell us that we're in, say, America/New_York
+// and not just that we're in -240 *right now*. But since I don't think these are used that often
+// I'm just going to ignore that
+const obsOffsets = {
+ GMT: 0,
+ EDT: -4 * 60,
+ EST: -5 * 60,
+ CDT: -5 * 60,
+ CST: -6 * 60,
+ MDT: -6 * 60,
+ MST: -7 * 60,
+ PDT: -7 * 60,
+ PST: -8 * 60
+};
+
+function fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr) {
+ const result = {
+ year: yearStr.length === 2 ? untruncateYear(parseInteger(yearStr)) : parseInteger(yearStr),
+ month: English.monthsShort.indexOf(monthStr) + 1,
+ day: parseInteger(dayStr),
+ hour: parseInteger(hourStr),
+ minute: parseInteger(minuteStr)
+ };
+
+ if (secondStr) result.second = parseInteger(secondStr);
+ if (weekdayStr) {
+ result.weekday =
+ weekdayStr.length > 3
+ ? English.weekdaysLong.indexOf(weekdayStr) + 1
+ : English.weekdaysShort.indexOf(weekdayStr) + 1;
+ }
+
+ return result;
+}
+
+// RFC 2822/5322
+const rfc2822 = /^(?:(Mon|Tue|Wed|Thu|Fri|Sat|Sun),\s)?(\d{1,2})\s(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)\s(\d{2,4})\s(\d\d):(\d\d)(?::(\d\d))?\s(?:(UT|GMT|[ECMP][SD]T)|([Zz])|(?:([+-]\d\d)(\d\d)))$/;
+
+function extractRFC2822(match) {
+ const [
+ ,
+ weekdayStr,
+ dayStr,
+ monthStr,
+ yearStr,
+ hourStr,
+ minuteStr,
+ secondStr,
+ obsOffset,
+ milOffset,
+ offHourStr,
+ offMinuteStr
+ ] = match,
+ result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
+
+ let offset;
+ if (obsOffset) {
+ offset = obsOffsets[obsOffset];
+ } else if (milOffset) {
+ offset = 0;
+ } else {
+ offset = signedOffset(offHourStr, offMinuteStr);
+ }
+
+ return [result, new FixedOffsetZone(offset)];
+}
+
+function preprocessRFC2822(s) {
+ // Remove comments and folding whitespace and replace multiple-spaces with a single space
+ return s
+ .replace(/\([^)]*\)|[\n\t]/g, " ")
+ .replace(/(\s\s+)/g, " ")
+ .trim();
+}
+
+// http date
+
+const rfc1123 = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun), (\d\d) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) (\d{4}) (\d\d):(\d\d):(\d\d) GMT$/,
+ rfc850 = /^(Monday|Tuesday|Wedsday|Thursday|Friday|Saturday|Sunday), (\d\d)-(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec)-(\d\d) (\d\d):(\d\d):(\d\d) GMT$/,
+ ascii = /^(Mon|Tue|Wed|Thu|Fri|Sat|Sun) (Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) ( \d|\d\d) (\d\d):(\d\d):(\d\d) (\d{4})$/;
+
+function extractRFC1123Or850(match) {
+ const [, weekdayStr, dayStr, monthStr, yearStr, hourStr, minuteStr, secondStr] = match,
+ result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
+ return [result, FixedOffsetZone.utcInstance];
+}
+
+function extractASCII(match) {
+ const [, weekdayStr, monthStr, dayStr, hourStr, minuteStr, secondStr, yearStr] = match,
+ result = fromStrings(weekdayStr, yearStr, monthStr, dayStr, hourStr, minuteStr, secondStr);
+ return [result, FixedOffsetZone.utcInstance];
+}
+
+const isoYmdWithTimeExtensionRegex = combineRegexes(isoYmdRegex, isoTimeExtensionRegex);
+const isoWeekWithTimeExtensionRegex = combineRegexes(isoWeekRegex, isoTimeExtensionRegex);
+const isoOrdinalWithTimeExtensionRegex = combineRegexes(isoOrdinalRegex, isoTimeExtensionRegex);
+const isoTimeCombinedRegex = combineRegexes(isoTimeRegex);
+
+const extractISOYmdTimeAndOffset = combineExtractors(
+ extractISOYmd,
+ extractISOTime,
+ extractISOOffset
+);
+const extractISOWeekTimeAndOffset = combineExtractors(
+ extractISOWeekData,
+ extractISOTime,
+ extractISOOffset
+);
+const extractISOOrdinalDataAndTime = combineExtractors(extractISOOrdinalData, extractISOTime);
+const extractISOTimeAndOffset = combineExtractors(extractISOTime, extractISOOffset);
+
+/**
+ * @private
+ */
+
+export function parseISODate(s) {
+ return parse(
+ s,
+ [isoYmdWithTimeExtensionRegex, extractISOYmdTimeAndOffset],
+ [isoWeekWithTimeExtensionRegex, extractISOWeekTimeAndOffset],
+ [isoOrdinalWithTimeExtensionRegex, extractISOOrdinalDataAndTime],
+ [isoTimeCombinedRegex, extractISOTimeAndOffset]
+ );
+}
+
+export function parseRFC2822Date(s) {
+ return parse(preprocessRFC2822(s), [rfc2822, extractRFC2822]);
+}
+
+export function parseHTTPDate(s) {
+ return parse(
+ s,
+ [rfc1123, extractRFC1123Or850],
+ [rfc850, extractRFC1123Or850],
+ [ascii, extractASCII]
+ );
+}
+
+export function parseISODuration(s) {
+ return parse(s, [isoDuration, extractISODuration]);
+}
+
+const sqlYmdWithTimeExtensionRegex = combineRegexes(sqlYmdRegex, sqlTimeExtensionRegex);
+const sqlTimeCombinedRegex = combineRegexes(sqlTimeRegex);
+
+const extractISOYmdTimeOffsetAndIANAZone = combineExtractors(
+ extractISOYmd,
+ extractISOTime,
+ extractISOOffset,
+ extractIANAZone
+);
+const extractISOTimeOffsetAndIANAZone = combineExtractors(
+ extractISOTime,
+ extractISOOffset,
+ extractIANAZone
+);
+
+export function parseSQL(s) {
+ return parse(
+ s,
+ [sqlYmdWithTimeExtensionRegex, extractISOYmdTimeOffsetAndIANAZone],
+ [sqlTimeCombinedRegex, extractISOTimeOffsetAndIANAZone]
+ );
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/tokenParser.js b/npm_assets/node_modules/luxon/src/impl/tokenParser.js
new file mode 100644
index 0000000..4ca0401
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/tokenParser.js
@@ -0,0 +1,424 @@
+import { parseMillis, isUndefined, untruncateYear, signedOffset, hasOwnProperty } from "./util.js";
+import Formatter from "./formatter.js";
+import FixedOffsetZone from "../zones/fixedOffsetZone.js";
+import IANAZone from "../zones/IANAZone.js";
+import DateTime from "../datetime.js";
+import { digitRegex, parseDigits } from "./digits.js";
+import { ConflictingSpecificationError } from "../errors.js";
+
+const MISSING_FTP = "missing Intl.DateTimeFormat.formatToParts support";
+
+function intUnit(regex, post = i => i) {
+ return { regex, deser: ([s]) => post(parseDigits(s)) };
+}
+
+const NBSP = String.fromCharCode(160);
+const spaceOrNBSP = `( |${NBSP})`;
+const spaceOrNBSPRegExp = new RegExp(spaceOrNBSP, "g");
+
+function fixListRegex(s) {
+ // make dots optional and also make them literal
+ // make space and non breakable space characters interchangeable
+ return s.replace(/\./g, "\\.?").replace(spaceOrNBSPRegExp, spaceOrNBSP);
+}
+
+function stripInsensitivities(s) {
+ return s
+ .replace(/\./g, "") // ignore dots that were made optional
+ .replace(spaceOrNBSPRegExp, " ") // interchange space and nbsp
+ .toLowerCase();
+}
+
+function oneOf(strings, startIndex) {
+ if (strings === null) {
+ return null;
+ } else {
+ return {
+ regex: RegExp(strings.map(fixListRegex).join("|")),
+ deser: ([s]) =>
+ strings.findIndex(i => stripInsensitivities(s) === stripInsensitivities(i)) + startIndex
+ };
+ }
+}
+
+function offset(regex, groups) {
+ return { regex, deser: ([, h, m]) => signedOffset(h, m), groups };
+}
+
+function simple(regex) {
+ return { regex, deser: ([s]) => s };
+}
+
+function escapeToken(value) {
+ // eslint-disable-next-line no-useless-escape
+ return value.replace(/[\-\[\]{}()*+?.,\\\^$|#\s]/g, "\\$&");
+}
+
+function unitForToken(token, loc) {
+ const one = digitRegex(loc),
+ two = digitRegex(loc, "{2}"),
+ three = digitRegex(loc, "{3}"),
+ four = digitRegex(loc, "{4}"),
+ six = digitRegex(loc, "{6}"),
+ oneOrTwo = digitRegex(loc, "{1,2}"),
+ oneToThree = digitRegex(loc, "{1,3}"),
+ oneToSix = digitRegex(loc, "{1,6}"),
+ oneToNine = digitRegex(loc, "{1,9}"),
+ twoToFour = digitRegex(loc, "{2,4}"),
+ fourToSix = digitRegex(loc, "{4,6}"),
+ literal = t => ({ regex: RegExp(escapeToken(t.val)), deser: ([s]) => s, literal: true }),
+ unitate = t => {
+ if (token.literal) {
+ return literal(t);
+ }
+ switch (t.val) {
+ // era
+ case "G":
+ return oneOf(loc.eras("short", false), 0);
+ case "GG":
+ return oneOf(loc.eras("long", false), 0);
+ // years
+ case "y":
+ return intUnit(oneToSix);
+ case "yy":
+ return intUnit(twoToFour, untruncateYear);
+ case "yyyy":
+ return intUnit(four);
+ case "yyyyy":
+ return intUnit(fourToSix);
+ case "yyyyyy":
+ return intUnit(six);
+ // months
+ case "M":
+ return intUnit(oneOrTwo);
+ case "MM":
+ return intUnit(two);
+ case "MMM":
+ return oneOf(loc.months("short", true, false), 1);
+ case "MMMM":
+ return oneOf(loc.months("long", true, false), 1);
+ case "L":
+ return intUnit(oneOrTwo);
+ case "LL":
+ return intUnit(two);
+ case "LLL":
+ return oneOf(loc.months("short", false, false), 1);
+ case "LLLL":
+ return oneOf(loc.months("long", false, false), 1);
+ // dates
+ case "d":
+ return intUnit(oneOrTwo);
+ case "dd":
+ return intUnit(two);
+ // ordinals
+ case "o":
+ return intUnit(oneToThree);
+ case "ooo":
+ return intUnit(three);
+ // time
+ case "HH":
+ return intUnit(two);
+ case "H":
+ return intUnit(oneOrTwo);
+ case "hh":
+ return intUnit(two);
+ case "h":
+ return intUnit(oneOrTwo);
+ case "mm":
+ return intUnit(two);
+ case "m":
+ return intUnit(oneOrTwo);
+ case "q":
+ return intUnit(oneOrTwo);
+ case "qq":
+ return intUnit(two);
+ case "s":
+ return intUnit(oneOrTwo);
+ case "ss":
+ return intUnit(two);
+ case "S":
+ return intUnit(oneToThree);
+ case "SSS":
+ return intUnit(three);
+ case "u":
+ return simple(oneToNine);
+ // meridiem
+ case "a":
+ return oneOf(loc.meridiems(), 0);
+ // weekYear (k)
+ case "kkkk":
+ return intUnit(four);
+ case "kk":
+ return intUnit(twoToFour, untruncateYear);
+ // weekNumber (W)
+ case "W":
+ return intUnit(oneOrTwo);
+ case "WW":
+ return intUnit(two);
+ // weekdays
+ case "E":
+ case "c":
+ return intUnit(one);
+ case "EEE":
+ return oneOf(loc.weekdays("short", false, false), 1);
+ case "EEEE":
+ return oneOf(loc.weekdays("long", false, false), 1);
+ case "ccc":
+ return oneOf(loc.weekdays("short", true, false), 1);
+ case "cccc":
+ return oneOf(loc.weekdays("long", true, false), 1);
+ // offset/zone
+ case "Z":
+ case "ZZ":
+ return offset(new RegExp(`([+-]${oneOrTwo.source})(?::(${two.source}))?`), 2);
+ case "ZZZ":
+ return offset(new RegExp(`([+-]${oneOrTwo.source})(${two.source})?`), 2);
+ // we don't support ZZZZ (PST) or ZZZZZ (Pacific Standard Time) in parsing
+ // because we don't have any way to figure out what they are
+ case "z":
+ return simple(/[a-z_+-/]{1,256}?/i);
+ default:
+ return literal(t);
+ }
+ };
+
+ const unit = unitate(token) || {
+ invalidReason: MISSING_FTP
+ };
+
+ unit.token = token;
+
+ return unit;
+}
+
+const partTypeStyleToTokenVal = {
+ year: {
+ "2-digit": "yy",
+ numeric: "yyyyy"
+ },
+ month: {
+ numeric: "M",
+ "2-digit": "MM",
+ short: "MMM",
+ long: "MMMM"
+ },
+ day: {
+ numeric: "d",
+ "2-digit": "dd"
+ },
+ weekday: {
+ short: "EEE",
+ long: "EEEE"
+ },
+ dayperiod: "a",
+ dayPeriod: "a",
+ hour: {
+ numeric: "h",
+ "2-digit": "hh"
+ },
+ minute: {
+ numeric: "m",
+ "2-digit": "mm"
+ },
+ second: {
+ numeric: "s",
+ "2-digit": "ss"
+ }
+};
+
+function tokenForPart(part, locale, formatOpts) {
+ const { type, value } = part;
+
+ if (type === "literal") {
+ return {
+ literal: true,
+ val: value
+ };
+ }
+
+ const style = formatOpts[type];
+
+ let val = partTypeStyleToTokenVal[type];
+ if (typeof val === "object") {
+ val = val[style];
+ }
+
+ if (val) {
+ return {
+ literal: false,
+ val
+ };
+ }
+
+ return undefined;
+}
+
+function buildRegex(units) {
+ const re = units.map(u => u.regex).reduce((f, r) => `${f}(${r.source})`, "");
+ return [`^${re}$`, units];
+}
+
+function match(input, regex, handlers) {
+ const matches = input.match(regex);
+
+ if (matches) {
+ const all = {};
+ let matchIndex = 1;
+ for (const i in handlers) {
+ if (hasOwnProperty(handlers, i)) {
+ const h = handlers[i],
+ groups = h.groups ? h.groups + 1 : 1;
+ if (!h.literal && h.token) {
+ all[h.token.val[0]] = h.deser(matches.slice(matchIndex, matchIndex + groups));
+ }
+ matchIndex += groups;
+ }
+ }
+ return [matches, all];
+ } else {
+ return [matches, {}];
+ }
+}
+
+function dateTimeFromMatches(matches) {
+ const toField = token => {
+ switch (token) {
+ case "S":
+ return "millisecond";
+ case "s":
+ return "second";
+ case "m":
+ return "minute";
+ case "h":
+ case "H":
+ return "hour";
+ case "d":
+ return "day";
+ case "o":
+ return "ordinal";
+ case "L":
+ case "M":
+ return "month";
+ case "y":
+ return "year";
+ case "E":
+ case "c":
+ return "weekday";
+ case "W":
+ return "weekNumber";
+ case "k":
+ return "weekYear";
+ case "q":
+ return "quarter";
+ default:
+ return null;
+ }
+ };
+
+ let zone;
+ if (!isUndefined(matches.Z)) {
+ zone = new FixedOffsetZone(matches.Z);
+ } else if (!isUndefined(matches.z)) {
+ zone = IANAZone.create(matches.z);
+ } else {
+ zone = null;
+ }
+
+ if (!isUndefined(matches.q)) {
+ matches.M = (matches.q - 1) * 3 + 1;
+ }
+
+ if (!isUndefined(matches.h)) {
+ if (matches.h < 12 && matches.a === 1) {
+ matches.h += 12;
+ } else if (matches.h === 12 && matches.a === 0) {
+ matches.h = 0;
+ }
+ }
+
+ if (matches.G === 0 && matches.y) {
+ matches.y = -matches.y;
+ }
+
+ if (!isUndefined(matches.u)) {
+ matches.S = parseMillis(matches.u);
+ }
+
+ const vals = Object.keys(matches).reduce((r, k) => {
+ const f = toField(k);
+ if (f) {
+ r[f] = matches[k];
+ }
+
+ return r;
+ }, {});
+
+ return [vals, zone];
+}
+
+let dummyDateTimeCache = null;
+
+function getDummyDateTime() {
+ if (!dummyDateTimeCache) {
+ dummyDateTimeCache = DateTime.fromMillis(1555555555555);
+ }
+
+ return dummyDateTimeCache;
+}
+
+function maybeExpandMacroToken(token, locale) {
+ if (token.literal) {
+ return token;
+ }
+
+ const formatOpts = Formatter.macroTokenToFormatOpts(token.val);
+
+ if (!formatOpts) {
+ return token;
+ }
+
+ const formatter = Formatter.create(locale, formatOpts);
+ const parts = formatter.formatDateTimeParts(getDummyDateTime());
+
+ const tokens = parts.map(p => tokenForPart(p, locale, formatOpts));
+
+ if (tokens.includes(undefined)) {
+ return token;
+ }
+
+ return tokens;
+}
+
+function expandMacroTokens(tokens, locale) {
+ return Array.prototype.concat(...tokens.map(t => maybeExpandMacroToken(t, locale)));
+}
+
+/**
+ * @private
+ */
+
+export function explainFromTokens(locale, input, format) {
+ const tokens = expandMacroTokens(Formatter.parseFormat(format), locale),
+ units = tokens.map(t => unitForToken(t, locale)),
+ disqualifyingUnit = units.find(t => t.invalidReason);
+
+ if (disqualifyingUnit) {
+ return { input, tokens, invalidReason: disqualifyingUnit.invalidReason };
+ } else {
+ const [regexString, handlers] = buildRegex(units),
+ regex = RegExp(regexString, "i"),
+ [rawMatches, matches] = match(input, regex, handlers),
+ [result, zone] = matches ? dateTimeFromMatches(matches) : [null, null];
+ if (hasOwnProperty(matches, "a") && hasOwnProperty(matches, "H")) {
+ throw new ConflictingSpecificationError(
+ "Can't include meridiem when specifying 24-hour format"
+ );
+ }
+ return { input, tokens, regex, rawMatches, matches, result, zone };
+ }
+}
+
+export function parseFromTokens(locale, input, format) {
+ const { result, zone, invalidReason } = explainFromTokens(locale, input, format);
+ return [result, zone, invalidReason];
+}
diff --git a/npm_assets/node_modules/luxon/src/impl/util.js b/npm_assets/node_modules/luxon/src/impl/util.js
new file mode 100644
index 0000000..b345c69
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/util.js
@@ -0,0 +1,286 @@
+/*
+ This is just a junk drawer, containing anything used across multiple classes.
+ Because Luxon is small(ish), this should stay small and we won't worry about splitting
+ it up into, say, parsingUtil.js and basicUtil.js and so on. But they are divided up by feature area.
+*/
+
+import { InvalidArgumentError } from "../errors.js";
+
+/**
+ * @private
+ */
+
+// TYPES
+
+export function isUndefined(o) {
+ return typeof o === "undefined";
+}
+
+export function isNumber(o) {
+ return typeof o === "number";
+}
+
+export function isInteger(o) {
+ return typeof o === "number" && o % 1 === 0;
+}
+
+export function isString(o) {
+ return typeof o === "string";
+}
+
+export function isDate(o) {
+ return Object.prototype.toString.call(o) === "[object Date]";
+}
+
+// CAPABILITIES
+
+export function hasIntl() {
+ try {
+ return typeof Intl !== "undefined" && Intl.DateTimeFormat;
+ } catch (e) {
+ return false;
+ }
+}
+
+export function hasFormatToParts() {
+ return !isUndefined(Intl.DateTimeFormat.prototype.formatToParts);
+}
+
+export function hasRelative() {
+ try {
+ return typeof Intl !== "undefined" && !!Intl.RelativeTimeFormat;
+ } catch (e) {
+ return false;
+ }
+}
+
+// OBJECTS AND ARRAYS
+
+export function maybeArray(thing) {
+ return Array.isArray(thing) ? thing : [thing];
+}
+
+export function bestBy(arr, by, compare) {
+ if (arr.length === 0) {
+ return undefined;
+ }
+ return arr.reduce((best, next) => {
+ const pair = [by(next), next];
+ if (!best) {
+ return pair;
+ } else if (compare(best[0], pair[0]) === best[0]) {
+ return best;
+ } else {
+ return pair;
+ }
+ }, null)[1];
+}
+
+export function pick(obj, keys) {
+ return keys.reduce((a, k) => {
+ a[k] = obj[k];
+ return a;
+ }, {});
+}
+
+export function hasOwnProperty(obj, prop) {
+ return Object.prototype.hasOwnProperty.call(obj, prop);
+}
+
+// NUMBERS AND STRINGS
+
+export function integerBetween(thing, bottom, top) {
+ return isInteger(thing) && thing >= bottom && thing <= top;
+}
+
+// x % n but takes the sign of n instead of x
+export function floorMod(x, n) {
+ return x - n * Math.floor(x / n);
+}
+
+export function padStart(input, n = 2) {
+ if (input.toString().length < n) {
+ return ("0".repeat(n) + input).slice(-n);
+ } else {
+ return input.toString();
+ }
+}
+
+export function parseInteger(string) {
+ if (isUndefined(string) || string === null || string === "") {
+ return undefined;
+ } else {
+ return parseInt(string, 10);
+ }
+}
+
+export function parseMillis(fraction) {
+ // Return undefined (instead of 0) in these cases, where fraction is not set
+ if (isUndefined(fraction) || fraction === null || fraction === "") {
+ return undefined;
+ } else {
+ const f = parseFloat("0." + fraction) * 1000;
+ return Math.floor(f);
+ }
+}
+
+export function roundTo(number, digits, towardZero = false) {
+ const factor = 10 ** digits,
+ rounder = towardZero ? Math.trunc : Math.round;
+ return rounder(number * factor) / factor;
+}
+
+// DATE BASICS
+
+export function isLeapYear(year) {
+ return year % 4 === 0 && (year % 100 !== 0 || year % 400 === 0);
+}
+
+export function daysInYear(year) {
+ return isLeapYear(year) ? 366 : 365;
+}
+
+export function daysInMonth(year, month) {
+ const modMonth = floorMod(month - 1, 12) + 1,
+ modYear = year + (month - modMonth) / 12;
+
+ if (modMonth === 2) {
+ return isLeapYear(modYear) ? 29 : 28;
+ } else {
+ return [31, null, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31][modMonth - 1];
+ }
+}
+
+// covert a calendar object to a local timestamp (epoch, but with the offset baked in)
+export function objToLocalTS(obj) {
+ let d = Date.UTC(
+ obj.year,
+ obj.month - 1,
+ obj.day,
+ obj.hour,
+ obj.minute,
+ obj.second,
+ obj.millisecond
+ );
+
+ // for legacy reasons, years between 0 and 99 are interpreted as 19XX; revert that
+ if (obj.year < 100 && obj.year >= 0) {
+ d = new Date(d);
+ d.setUTCFullYear(d.getUTCFullYear() - 1900);
+ }
+ return +d;
+}
+
+export function weeksInWeekYear(weekYear) {
+ const p1 =
+ (weekYear +
+ Math.floor(weekYear / 4) -
+ Math.floor(weekYear / 100) +
+ Math.floor(weekYear / 400)) %
+ 7,
+ last = weekYear - 1,
+ p2 = (last + Math.floor(last / 4) - Math.floor(last / 100) + Math.floor(last / 400)) % 7;
+ return p1 === 4 || p2 === 3 ? 53 : 52;
+}
+
+export function untruncateYear(year) {
+ if (year > 99) {
+ return year;
+ } else return year > 60 ? 1900 + year : 2000 + year;
+}
+
+// PARSING
+
+export function parseZoneInfo(ts, offsetFormat, locale, timeZone = null) {
+ const date = new Date(ts),
+ intlOpts = {
+ hour12: false,
+ year: "numeric",
+ month: "2-digit",
+ day: "2-digit",
+ hour: "2-digit",
+ minute: "2-digit"
+ };
+
+ if (timeZone) {
+ intlOpts.timeZone = timeZone;
+ }
+
+ const modified = Object.assign({ timeZoneName: offsetFormat }, intlOpts),
+ intl = hasIntl();
+
+ if (intl && hasFormatToParts()) {
+ const parsed = new Intl.DateTimeFormat(locale, modified)
+ .formatToParts(date)
+ .find(m => m.type.toLowerCase() === "timezonename");
+ return parsed ? parsed.value : null;
+ } else if (intl) {
+ // this probably doesn't work for all locales
+ const without = new Intl.DateTimeFormat(locale, intlOpts).format(date),
+ included = new Intl.DateTimeFormat(locale, modified).format(date),
+ diffed = included.substring(without.length),
+ trimmed = diffed.replace(/^[, \u200e]+/, "");
+ return trimmed;
+ } else {
+ return null;
+ }
+}
+
+// signedOffset('-5', '30') -> -330
+export function signedOffset(offHourStr, offMinuteStr) {
+ let offHour = parseInt(offHourStr, 10);
+
+ // don't || this because we want to preserve -0
+ if (Number.isNaN(offHour)) {
+ offHour = 0;
+ }
+
+ const offMin = parseInt(offMinuteStr, 10) || 0,
+ offMinSigned = offHour < 0 || Object.is(offHour, -0) ? -offMin : offMin;
+ return offHour * 60 + offMinSigned;
+}
+
+// COERCION
+
+export function asNumber(value) {
+ const numericValue = Number(value);
+ if (typeof value === "boolean" || value === "" || Number.isNaN(numericValue))
+ throw new InvalidArgumentError(`Invalid unit value ${value}`);
+ return numericValue;
+}
+
+export function normalizeObject(obj, normalizer, nonUnitKeys) {
+ const normalized = {};
+ for (const u in obj) {
+ if (hasOwnProperty(obj, u)) {
+ if (nonUnitKeys.indexOf(u) >= 0) continue;
+ const v = obj[u];
+ if (v === undefined || v === null) continue;
+ normalized[normalizer(u)] = asNumber(v);
+ }
+ }
+ return normalized;
+}
+
+export function formatOffset(offset, format) {
+ const hours = Math.trunc(Math.abs(offset / 60)),
+ minutes = Math.trunc(Math.abs(offset % 60)),
+ sign = offset >= 0 ? "+" : "-";
+
+ switch (format) {
+ case "short":
+ return `${sign}${padStart(hours, 2)}:${padStart(minutes, 2)}`;
+ case "narrow":
+ return `${sign}${hours}${minutes > 0 ? `:${minutes}` : ""}`;
+ case "techie":
+ return `${sign}${padStart(hours, 2)}${padStart(minutes, 2)}`;
+ default:
+ throw new RangeError(`Value format ${format} is out of range for property format`);
+ }
+}
+
+export function timeObject(obj) {
+ return pick(obj, ["hour", "minute", "second", "millisecond"]);
+}
+
+export const ianaRegex = /[A-Za-z_+-]{1,256}(:?\/[A-Za-z_+-]{1,256}(\/[A-Za-z_+-]{1,256})?)?/;
diff --git a/npm_assets/node_modules/luxon/src/impl/zoneUtil.js b/npm_assets/node_modules/luxon/src/impl/zoneUtil.js
new file mode 100644
index 0000000..c45e828
--- /dev/null
+++ b/npm_assets/node_modules/luxon/src/impl/zoneUtil.js
@@ -0,0 +1,36 @@
+/**
+ * @private
+ */
+
+import Zone from "../zone.js";
+import IANAZone from "../zones/IANAZone.js";
+import FixedOffsetZone from "../zones/fixedOffsetZone.js";
+import InvalidZone from "../zones/invalidZone.js";
+
+import { isUndefined, isString, isNumber } from "./util.js";
+
+export function normalizeZone(input, defaultZone) {
+ let offset;
+ if (isUndefined(input) || input === null) {
+ return defaultZone;
+ } else if (input instanceof Zone) {
+ return input;
+ } else if (isString(input)) {
+ const lowered = input.toLowerCase();
+ if (lowered === "local") return defaultZone;
+ else if (lowered === "utc" || lowered === "gmt") return FixedOffsetZone.utcInstance;
+ else if ((offset = IANAZone.parseGMTOffset(input)) != null) {
+ // handle Etc/GMT-4, which V8 chokes on
+ return FixedOffsetZone.instance(offset);
+ } else if (IANAZone.isValidSpecifier(lowered)) return IANAZone.create(input);
+ else return FixedOffsetZone.parseSpecifier(lowered) || new InvalidZone(input);
+ } else if (isNumber(input)) {
+ return FixedOffsetZone.instance(input);
+ } else if (typeof input === "object" && input.offset && typeof input.offset === "number") {
+ // This is dumb, but the instanceof check above doesn't seem to really work
+ // so we're duck checking it
+ return input;
+ } else {
+ return new InvalidZone(input);
+ }
+}