UNPKG

vega-format

Version:

JavaScript string formatting utilities for Vega.

1,343 lines (1,284 loc) 47.2 kB
(function (global, factory) { typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports, require('vega-time'), require('vega-util')) : typeof define === 'function' && define.amd ? define(['exports', 'vega-time', 'vega-util'], factory) : (global = typeof globalThis !== 'undefined' ? globalThis : global || self, factory(global.vega = {}, global.vega, global.vega)); })(this, (function (exports, vegaTime, vegaUtil) { 'use strict'; function memoize (method) { const cache = {}; return spec => cache[spec] || (cache[spec] = method(spec)); } const e10 = Math.sqrt(50), e5 = Math.sqrt(10), e2 = Math.sqrt(2); function tickSpec(start, stop, count) { const step = (stop - start) / Math.max(0, count), power = Math.floor(Math.log10(step)), error = step / Math.pow(10, power), factor = error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1; let i1, i2, inc; if (power < 0) { inc = Math.pow(10, -power) / factor; i1 = Math.round(start * inc); i2 = Math.round(stop * inc); if (i1 / inc < start) ++i1; if (i2 / inc > stop) --i2; inc = -inc; } else { inc = Math.pow(10, power) * factor; i1 = Math.round(start / inc); i2 = Math.round(stop / inc); if (i1 * inc < start) ++i1; if (i2 * inc > stop) --i2; } if (i2 < i1 && 0.5 <= count && count < 2) return tickSpec(start, stop, count * 2); return [i1, i2, inc]; } function tickIncrement(start, stop, count) { stop = +stop, start = +start, count = +count; return tickSpec(start, stop, count)[2]; } function tickStep(start, stop, count) { stop = +stop, start = +start, count = +count; const reverse = stop < start, inc = reverse ? tickIncrement(stop, start, count) : tickIncrement(start, stop, count); return (reverse ? -1 : 1) * (inc < 0 ? 1 / -inc : inc); } function formatDecimal (x) { return Math.abs(x = Math.round(x)) >= 1e21 ? x.toLocaleString("en").replace(/,/g, "") : x.toString(10); } // Computes the decimal coefficient and exponent of the specified number x with // significant digits p, where x is positive and p is in [1, 21] or undefined. // For example, formatDecimalParts(1.23) returns ["123", 0]. function formatDecimalParts(x, p) { if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity var i, coefficient = x.slice(0, i); // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). return [coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, +x.slice(i + 1)]; } function exponent (x) { return x = formatDecimalParts(Math.abs(x)), x ? x[1] : NaN; } function formatGroup (grouping, thousands) { return function (value, width) { var i = value.length, t = [], j = 0, g = grouping[0], length = 0; while (i > 0 && g > 0) { if (length + g + 1 > width) g = Math.max(1, width - length); t.push(value.substring(i -= g, i + g)); if ((length += g + 1) > width) break; g = grouping[j = (j + 1) % grouping.length]; } return t.reverse().join(thousands); }; } function formatNumerals (numerals) { return function (value) { return value.replace(/[0-9]/g, function (i) { return numerals[+i]; }); }; } // [[fill]align][sign][symbol][0][width][,][.precision][~][type] var re = /^(?:(.)?([<>=^]))?([+\-( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?(~)?([a-z%])?$/i; function formatSpecifier(specifier) { if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); var match; return new FormatSpecifier({ fill: match[1], align: match[2], sign: match[3], symbol: match[4], zero: match[5], width: match[6], comma: match[7], precision: match[8] && match[8].slice(1), trim: match[9], type: match[10] }); } formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof function FormatSpecifier(specifier) { this.fill = specifier.fill === undefined ? " " : specifier.fill + ""; this.align = specifier.align === undefined ? ">" : specifier.align + ""; this.sign = specifier.sign === undefined ? "-" : specifier.sign + ""; this.symbol = specifier.symbol === undefined ? "" : specifier.symbol + ""; this.zero = !!specifier.zero; this.width = specifier.width === undefined ? undefined : +specifier.width; this.comma = !!specifier.comma; this.precision = specifier.precision === undefined ? undefined : +specifier.precision; this.trim = !!specifier.trim; this.type = specifier.type === undefined ? "" : specifier.type + ""; } FormatSpecifier.prototype.toString = function () { return this.fill + this.align + this.sign + this.symbol + (this.zero ? "0" : "") + (this.width === undefined ? "" : Math.max(1, this.width | 0)) + (this.comma ? "," : "") + (this.precision === undefined ? "" : "." + Math.max(0, this.precision | 0)) + (this.trim ? "~" : "") + this.type; }; // Trims insignificant zeros, e.g., replaces 1.2000k with 1.2k. function formatTrim (s) { out: for (var n = s.length, i = 1, i0 = -1, i1; i < n; ++i) { switch (s[i]) { case ".": i0 = i1 = i; break; case "0": if (i0 === 0) i0 = i; i1 = i; break; default: if (!+s[i]) break out; if (i0 > 0) i0 = 0; break; } } return i0 > 0 ? s.slice(0, i0) + s.slice(i1 + 1) : s; } var prefixExponent; function formatPrefixAuto (x, p) { var d = formatDecimalParts(x, p); if (!d) return x + ""; var coefficient = d[0], exponent = d[1], i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, n = coefficient.length; return i === n ? coefficient : i > n ? coefficient + new Array(i - n + 1).join("0") : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) : "0." + new Array(1 - i).join("0") + formatDecimalParts(x, Math.max(0, p + i - 1))[0]; // less than 1y! } function formatRounded (x, p) { var d = formatDecimalParts(x, p); if (!d) return x + ""; var coefficient = d[0], exponent = d[1]; return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) : coefficient + new Array(exponent - coefficient.length + 2).join("0"); } var formatTypes = { "%": (x, p) => (x * 100).toFixed(p), "b": x => Math.round(x).toString(2), "c": x => x + "", "d": formatDecimal, "e": (x, p) => x.toExponential(p), "f": (x, p) => x.toFixed(p), "g": (x, p) => x.toPrecision(p), "o": x => Math.round(x).toString(8), "p": (x, p) => formatRounded(x * 100, p), "r": formatRounded, "s": formatPrefixAuto, "X": x => Math.round(x).toString(16).toUpperCase(), "x": x => Math.round(x).toString(16) }; function identity (x) { return x; } var map = Array.prototype.map, prefixes = ["y", "z", "a", "f", "p", "n", "µ", "m", "", "k", "M", "G", "T", "P", "E", "Z", "Y"]; function d3_formatLocale (locale) { var group = locale.grouping === undefined || locale.thousands === undefined ? identity : formatGroup(map.call(locale.grouping, Number), locale.thousands + ""), currencyPrefix = locale.currency === undefined ? "" : locale.currency[0] + "", currencySuffix = locale.currency === undefined ? "" : locale.currency[1] + "", decimal = locale.decimal === undefined ? "." : locale.decimal + "", numerals = locale.numerals === undefined ? identity : formatNumerals(map.call(locale.numerals, String)), percent = locale.percent === undefined ? "%" : locale.percent + "", minus = locale.minus === undefined ? "−" : locale.minus + "", nan = locale.nan === undefined ? "NaN" : locale.nan + ""; function newFormat(specifier) { specifier = formatSpecifier(specifier); var fill = specifier.fill, align = specifier.align, sign = specifier.sign, symbol = specifier.symbol, zero = specifier.zero, width = specifier.width, comma = specifier.comma, precision = specifier.precision, trim = specifier.trim, type = specifier.type; // The "n" type is an alias for ",g". if (type === "n") comma = true, type = "g"; // The "" type, and any invalid type, is an alias for ".12~g". else if (!formatTypes[type]) precision === undefined && (precision = 12), trim = true, type = "g"; // If zero fill is specified, padding goes after sign and before digits. if (zero || fill === "0" && align === "=") zero = true, fill = "0", align = "="; // Compute the prefix and suffix. // For SI-prefix, the suffix is lazily computed. var prefix = symbol === "$" ? currencyPrefix : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", suffix = symbol === "$" ? currencySuffix : /[%p]/.test(type) ? percent : ""; // What format function should we use? // Is this an integer type? // Can this type generate exponential notation? var formatType = formatTypes[type], maybeSuffix = /[defgprs%]/.test(type); // Set the default precision if not specified, // or clamp the specified precision to the supported range. // For significant precision, it must be in [1, 21]. // For fixed precision, it must be in [0, 20]. precision = precision === undefined ? 6 : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) : Math.max(0, Math.min(20, precision)); function format(value) { var valuePrefix = prefix, valueSuffix = suffix, i, n, c; if (type === "c") { valueSuffix = formatType(value) + valueSuffix; value = ""; } else { value = +value; // Determine the sign. -0 is not less than 0, but 1 / -0 is! var valueNegative = value < 0 || 1 / value < 0; // Perform the initial formatting. value = isNaN(value) ? nan : formatType(Math.abs(value), precision); // Trim insignificant zeros. if (trim) value = formatTrim(value); // If a negative value rounds to zero after formatting, and no explicit positive sign is requested, hide the sign. if (valueNegative && +value === 0 && sign !== "+") valueNegative = false; // Compute the prefix and suffix. valuePrefix = (valueNegative ? sign === "(" ? sign : minus : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); // Break the formatted value into the integer “value” part that can be // grouped, and fractional or exponential “suffix” part that is not. if (maybeSuffix) { i = -1, n = value.length; while (++i < n) { if (c = value.charCodeAt(i), 48 > c || c > 57) { valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; value = value.slice(0, i); break; } } } } // If the fill character is not "0", grouping is applied before padding. if (comma && !zero) value = group(value, Infinity); // Compute the padding. var length = valuePrefix.length + value.length + valueSuffix.length, padding = length < width ? new Array(width - length + 1).join(fill) : ""; // If the fill character is "0", grouping is applied after padding. if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; // Reconstruct the final output based on the desired alignment. switch (align) { case "<": value = valuePrefix + value + valueSuffix + padding; break; case "=": value = valuePrefix + padding + value + valueSuffix; break; case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; default: value = padding + valuePrefix + value + valueSuffix; break; } return numerals(value); } format.toString = function () { return specifier + ""; }; return format; } function formatPrefix(specifier, value) { var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, k = Math.pow(10, -e), prefix = prefixes[8 + e / 3]; return function (value) { return f(k * value) + prefix; }; } return { format: newFormat, formatPrefix: formatPrefix }; } var locale$2; var format; var formatPrefix; defaultLocale$2({ thousands: ",", grouping: [3], currency: ["$", ""] }); function defaultLocale$2(definition) { locale$2 = d3_formatLocale(definition); format = locale$2.format; formatPrefix = locale$2.formatPrefix; return locale$2; } function precisionFixed (step) { return Math.max(0, -exponent(Math.abs(step))); } function precisionPrefix (step, value) { return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); } function precisionRound (step, max) { step = Math.abs(step), max = Math.abs(max) - step; return Math.max(0, exponent(max) - exponent(step)) + 1; } function trimZeroes(numberFormat, decimalChar) { return x => { const str = numberFormat(x), dec = str.indexOf(decimalChar); if (dec < 0) return str; let idx = rightmostDigit(str, dec); const end = idx < str.length ? str.slice(idx) : ''; while (--idx > dec) if (str[idx] !== '0') { ++idx; break; } return str.slice(0, idx) + end; }; } function rightmostDigit(str, dec) { let i = str.lastIndexOf('e'), c; if (i > 0) return i; for (i = str.length; --i > dec;) { c = str.charCodeAt(i); if (c >= 48 && c <= 57) return i + 1; // is digit } } function numberLocale(locale) { const format = memoize(locale.format), formatPrefix = locale.formatPrefix; return { format, formatPrefix, formatFloat(spec) { const s = formatSpecifier(spec || ','); if (s.precision == null) { s.precision = 12; switch (s.type) { case '%': s.precision -= 2; break; case 'e': s.precision -= 1; break; } return trimZeroes(format(s), // number format format('.1f')(1)[1] // decimal point character ); } else { return format(s); } }, formatSpan(start, stop, count, specifier) { specifier = formatSpecifier(specifier == null ? ',f' : specifier); const step = tickStep(start, stop, count), value = Math.max(Math.abs(start), Math.abs(stop)); let precision; if (specifier.precision == null) { switch (specifier.type) { case 's': { if (!isNaN(precision = precisionPrefix(step, value))) { specifier.precision = precision; } return formatPrefix(specifier, value); } case '': case 'e': case 'g': case 'p': case 'r': { if (!isNaN(precision = precisionRound(step, value))) { specifier.precision = precision - (specifier.type === 'e'); } break; } case 'f': case '%': { if (!isNaN(precision = precisionFixed(step))) { specifier.precision = precision - (specifier.type === '%') * 2; } break; } } } return format(specifier); } }; } let defaultNumberLocale; resetNumberFormatDefaultLocale(); function resetNumberFormatDefaultLocale() { return defaultNumberLocale = numberLocale({ format: format, formatPrefix: formatPrefix }); } function numberFormatLocale(definition) { return numberLocale(d3_formatLocale(definition)); } function numberFormatDefaultLocale(definition) { return arguments.length ? defaultNumberLocale = numberFormatLocale(definition) : defaultNumberLocale; } const t0 = new Date(), t1 = new Date(); function timeInterval(floori, offseti, count, field) { function interval(date) { return floori(date = arguments.length === 0 ? new Date() : new Date(+date)), date; } interval.floor = date => { return floori(date = new Date(+date)), date; }; interval.ceil = date => { return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; }; interval.round = date => { const d0 = interval(date), d1 = interval.ceil(date); return date - d0 < d1 - date ? d0 : d1; }; interval.offset = (date, step) => { return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; }; interval.range = (start, stop, step) => { const range = []; start = interval.ceil(start); step = step == null ? 1 : Math.floor(step); if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date let previous; do range.push(previous = new Date(+start)), offseti(start, step), floori(start); while (previous < start && start < stop); return range; }; interval.filter = test => { return timeInterval(date => { if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); }, (date, step) => { if (date >= date) { if (step < 0) while (++step <= 0) { while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty } else while (--step >= 0) { while (offseti(date, 1), !test(date)) {} // eslint-disable-line no-empty } } }); }; if (count) { interval.count = (start, end) => { t0.setTime(+start), t1.setTime(+end); floori(t0), floori(t1); return Math.floor(count(t0, t1)); }; interval.every = step => { step = Math.floor(step); return !isFinite(step) || !(step > 0) ? null : !(step > 1) ? interval : interval.filter(field ? d => field(d) % step === 0 : d => interval.count(0, d) % step === 0); }; } return interval; } const durationSecond = 1000; const durationMinute = durationSecond * 60; const durationHour = durationMinute * 60; const durationDay = durationHour * 24; const durationWeek = durationDay * 7; const timeDay = timeInterval(date => date.setHours(0, 0, 0, 0), (date, step) => date.setDate(date.getDate() + step), (start, end) => (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay, date => date.getDate() - 1); timeDay.range; const utcDay = timeInterval(date => { date.setUTCHours(0, 0, 0, 0); }, (date, step) => { date.setUTCDate(date.getUTCDate() + step); }, (start, end) => { return (end - start) / durationDay; }, date => { return date.getUTCDate() - 1; }); utcDay.range; const unixDay = timeInterval(date => { date.setUTCHours(0, 0, 0, 0); }, (date, step) => { date.setUTCDate(date.getUTCDate() + step); }, (start, end) => { return (end - start) / durationDay; }, date => { return Math.floor(date / durationDay); }); unixDay.range; function timeWeekday(i) { return timeInterval(date => { date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); date.setHours(0, 0, 0, 0); }, (date, step) => { date.setDate(date.getDate() + step * 7); }, (start, end) => { return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek; }); } const timeSunday = timeWeekday(0); const timeMonday = timeWeekday(1); const timeTuesday = timeWeekday(2); const timeWednesday = timeWeekday(3); const timeThursday = timeWeekday(4); const timeFriday = timeWeekday(5); const timeSaturday = timeWeekday(6); timeSunday.range; timeMonday.range; timeTuesday.range; timeWednesday.range; timeThursday.range; timeFriday.range; timeSaturday.range; function utcWeekday(i) { return timeInterval(date => { date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); date.setUTCHours(0, 0, 0, 0); }, (date, step) => { date.setUTCDate(date.getUTCDate() + step * 7); }, (start, end) => { return (end - start) / durationWeek; }); } const utcSunday = utcWeekday(0); const utcMonday = utcWeekday(1); const utcTuesday = utcWeekday(2); const utcWednesday = utcWeekday(3); const utcThursday = utcWeekday(4); const utcFriday = utcWeekday(5); const utcSaturday = utcWeekday(6); utcSunday.range; utcMonday.range; utcTuesday.range; utcWednesday.range; utcThursday.range; utcFriday.range; utcSaturday.range; const timeYear = timeInterval(date => { date.setMonth(0, 1); date.setHours(0, 0, 0, 0); }, (date, step) => { date.setFullYear(date.getFullYear() + step); }, (start, end) => { return end.getFullYear() - start.getFullYear(); }, date => { return date.getFullYear(); }); // An optimized implementation for this simple case. timeYear.every = k => { return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval(date => { date.setFullYear(Math.floor(date.getFullYear() / k) * k); date.setMonth(0, 1); date.setHours(0, 0, 0, 0); }, (date, step) => { date.setFullYear(date.getFullYear() + step * k); }); }; timeYear.range; const utcYear = timeInterval(date => { date.setUTCMonth(0, 1); date.setUTCHours(0, 0, 0, 0); }, (date, step) => { date.setUTCFullYear(date.getUTCFullYear() + step); }, (start, end) => { return end.getUTCFullYear() - start.getUTCFullYear(); }, date => { return date.getUTCFullYear(); }); // An optimized implementation for this simple case. utcYear.every = k => { return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : timeInterval(date => { date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); date.setUTCMonth(0, 1); date.setUTCHours(0, 0, 0, 0); }, (date, step) => { date.setUTCFullYear(date.getUTCFullYear() + step * k); }); }; utcYear.range; function localDate(d) { if (0 <= d.y && d.y < 100) { var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); date.setFullYear(d.y); return date; } return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); } function utcDate(d) { if (0 <= d.y && d.y < 100) { var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); date.setUTCFullYear(d.y); return date; } return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); } function newDate(y, m, d) { return { y: y, m: m, d: d, H: 0, M: 0, S: 0, L: 0 }; } function formatLocale(locale) { var locale_dateTime = locale.dateTime, locale_date = locale.date, locale_time = locale.time, locale_periods = locale.periods, locale_weekdays = locale.days, locale_shortWeekdays = locale.shortDays, locale_months = locale.months, locale_shortMonths = locale.shortMonths; var periodRe = formatRe(locale_periods), periodLookup = formatLookup(locale_periods), weekdayRe = formatRe(locale_weekdays), weekdayLookup = formatLookup(locale_weekdays), shortWeekdayRe = formatRe(locale_shortWeekdays), shortWeekdayLookup = formatLookup(locale_shortWeekdays), monthRe = formatRe(locale_months), monthLookup = formatLookup(locale_months), shortMonthRe = formatRe(locale_shortMonths), shortMonthLookup = formatLookup(locale_shortMonths); var formats = { "a": formatShortWeekday, "A": formatWeekday, "b": formatShortMonth, "B": formatMonth, "c": null, "d": formatDayOfMonth, "e": formatDayOfMonth, "f": formatMicroseconds, "g": formatYearISO, "G": formatFullYearISO, "H": formatHour24, "I": formatHour12, "j": formatDayOfYear, "L": formatMilliseconds, "m": formatMonthNumber, "M": formatMinutes, "p": formatPeriod, "q": formatQuarter, "Q": formatUnixTimestamp, "s": formatUnixTimestampSeconds, "S": formatSeconds, "u": formatWeekdayNumberMonday, "U": formatWeekNumberSunday, "V": formatWeekNumberISO, "w": formatWeekdayNumberSunday, "W": formatWeekNumberMonday, "x": null, "X": null, "y": formatYear, "Y": formatFullYear, "Z": formatZone, "%": formatLiteralPercent }; var utcFormats = { "a": formatUTCShortWeekday, "A": formatUTCWeekday, "b": formatUTCShortMonth, "B": formatUTCMonth, "c": null, "d": formatUTCDayOfMonth, "e": formatUTCDayOfMonth, "f": formatUTCMicroseconds, "g": formatUTCYearISO, "G": formatUTCFullYearISO, "H": formatUTCHour24, "I": formatUTCHour12, "j": formatUTCDayOfYear, "L": formatUTCMilliseconds, "m": formatUTCMonthNumber, "M": formatUTCMinutes, "p": formatUTCPeriod, "q": formatUTCQuarter, "Q": formatUnixTimestamp, "s": formatUnixTimestampSeconds, "S": formatUTCSeconds, "u": formatUTCWeekdayNumberMonday, "U": formatUTCWeekNumberSunday, "V": formatUTCWeekNumberISO, "w": formatUTCWeekdayNumberSunday, "W": formatUTCWeekNumberMonday, "x": null, "X": null, "y": formatUTCYear, "Y": formatUTCFullYear, "Z": formatUTCZone, "%": formatLiteralPercent }; var parses = { "a": parseShortWeekday, "A": parseWeekday, "b": parseShortMonth, "B": parseMonth, "c": parseLocaleDateTime, "d": parseDayOfMonth, "e": parseDayOfMonth, "f": parseMicroseconds, "g": parseYear, "G": parseFullYear, "H": parseHour24, "I": parseHour24, "j": parseDayOfYear, "L": parseMilliseconds, "m": parseMonthNumber, "M": parseMinutes, "p": parsePeriod, "q": parseQuarter, "Q": parseUnixTimestamp, "s": parseUnixTimestampSeconds, "S": parseSeconds, "u": parseWeekdayNumberMonday, "U": parseWeekNumberSunday, "V": parseWeekNumberISO, "w": parseWeekdayNumberSunday, "W": parseWeekNumberMonday, "x": parseLocaleDate, "X": parseLocaleTime, "y": parseYear, "Y": parseFullYear, "Z": parseZone, "%": parseLiteralPercent }; // These recursive directive definitions must be deferred. formats.x = newFormat(locale_date, formats); formats.X = newFormat(locale_time, formats); formats.c = newFormat(locale_dateTime, formats); utcFormats.x = newFormat(locale_date, utcFormats); utcFormats.X = newFormat(locale_time, utcFormats); utcFormats.c = newFormat(locale_dateTime, utcFormats); function newFormat(specifier, formats) { return function (date) { var string = [], i = -1, j = 0, n = specifier.length, c, pad, format; if (!(date instanceof Date)) date = new Date(+date); while (++i < n) { if (specifier.charCodeAt(i) === 37) { string.push(specifier.slice(j, i)); if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i);else pad = c === "e" ? " " : "0"; if (format = formats[c]) c = format(date, pad); string.push(c); j = i + 1; } } string.push(specifier.slice(j, i)); return string.join(""); }; } function newParse(specifier, Z) { return function (string) { var d = newDate(1900, undefined, 1), i = parseSpecifier(d, specifier, string += "", 0), week, day; if (i != string.length) return null; // If a UNIX timestamp is specified, return it. if ("Q" in d) return new Date(d.Q); if ("s" in d) return new Date(d.s * 1000 + ("L" in d ? d.L : 0)); // If this is utcParse, never use the local timezone. if (Z && !("Z" in d)) d.Z = 0; // The am-pm flag is 0 for AM, and 1 for PM. if ("p" in d) d.H = d.H % 12 + d.p * 12; // If the month was not specified, inherit from the quarter. if (d.m === undefined) d.m = "q" in d ? d.q : 0; // Convert day-of-week and week-of-year to day-of-year. if ("V" in d) { if (d.V < 1 || d.V > 53) return null; if (!("w" in d)) d.w = 1; if ("Z" in d) { week = utcDate(newDate(d.y, 0, 1)), day = week.getUTCDay(); week = day > 4 || day === 0 ? utcMonday.ceil(week) : utcMonday(week); week = utcDay.offset(week, (d.V - 1) * 7); d.y = week.getUTCFullYear(); d.m = week.getUTCMonth(); d.d = week.getUTCDate() + (d.w + 6) % 7; } else { week = localDate(newDate(d.y, 0, 1)), day = week.getDay(); week = day > 4 || day === 0 ? timeMonday.ceil(week) : timeMonday(week); week = timeDay.offset(week, (d.V - 1) * 7); d.y = week.getFullYear(); d.m = week.getMonth(); d.d = week.getDate() + (d.w + 6) % 7; } } else if ("W" in d || "U" in d) { if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0; day = "Z" in d ? utcDate(newDate(d.y, 0, 1)).getUTCDay() : localDate(newDate(d.y, 0, 1)).getDay(); d.m = 0; d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day + 5) % 7 : d.w + d.U * 7 - (day + 6) % 7; } // If a time zone is specified, all fields are interpreted as UTC and then // offset according to the specified time zone. if ("Z" in d) { d.H += d.Z / 100 | 0; d.M += d.Z % 100; return utcDate(d); } // Otherwise, all fields are in local time. return localDate(d); }; } function parseSpecifier(d, specifier, string, j) { var i = 0, n = specifier.length, m = string.length, c, parse; while (i < n) { if (j >= m) return -1; c = specifier.charCodeAt(i++); if (c === 37) { c = specifier.charAt(i++); parse = parses[c in pads ? specifier.charAt(i++) : c]; if (!parse || (j = parse(d, string, j)) < 0) return -1; } else if (c != string.charCodeAt(j++)) { return -1; } } return j; } function parsePeriod(d, string, i) { var n = periodRe.exec(string.slice(i)); return n ? (d.p = periodLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function parseShortWeekday(d, string, i) { var n = shortWeekdayRe.exec(string.slice(i)); return n ? (d.w = shortWeekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function parseWeekday(d, string, i) { var n = weekdayRe.exec(string.slice(i)); return n ? (d.w = weekdayLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function parseShortMonth(d, string, i) { var n = shortMonthRe.exec(string.slice(i)); return n ? (d.m = shortMonthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function parseMonth(d, string, i) { var n = monthRe.exec(string.slice(i)); return n ? (d.m = monthLookup.get(n[0].toLowerCase()), i + n[0].length) : -1; } function parseLocaleDateTime(d, string, i) { return parseSpecifier(d, locale_dateTime, string, i); } function parseLocaleDate(d, string, i) { return parseSpecifier(d, locale_date, string, i); } function parseLocaleTime(d, string, i) { return parseSpecifier(d, locale_time, string, i); } function formatShortWeekday(d) { return locale_shortWeekdays[d.getDay()]; } function formatWeekday(d) { return locale_weekdays[d.getDay()]; } function formatShortMonth(d) { return locale_shortMonths[d.getMonth()]; } function formatMonth(d) { return locale_months[d.getMonth()]; } function formatPeriod(d) { return locale_periods[+(d.getHours() >= 12)]; } function formatQuarter(d) { return 1 + ~~(d.getMonth() / 3); } function formatUTCShortWeekday(d) { return locale_shortWeekdays[d.getUTCDay()]; } function formatUTCWeekday(d) { return locale_weekdays[d.getUTCDay()]; } function formatUTCShortMonth(d) { return locale_shortMonths[d.getUTCMonth()]; } function formatUTCMonth(d) { return locale_months[d.getUTCMonth()]; } function formatUTCPeriod(d) { return locale_periods[+(d.getUTCHours() >= 12)]; } function formatUTCQuarter(d) { return 1 + ~~(d.getUTCMonth() / 3); } return { format: function (specifier) { var f = newFormat(specifier += "", formats); f.toString = function () { return specifier; }; return f; }, parse: function (specifier) { var p = newParse(specifier += "", false); p.toString = function () { return specifier; }; return p; }, utcFormat: function (specifier) { var f = newFormat(specifier += "", utcFormats); f.toString = function () { return specifier; }; return f; }, utcParse: function (specifier) { var p = newParse(specifier += "", true); p.toString = function () { return specifier; }; return p; } }; } var pads = { "-": "", "_": " ", "0": "0" }, numberRe = /^\s*\d+/, // note: ignores next directive percentRe = /^%/, requoteRe = /[\\^$*+?|[\]().{}]/g; function pad(value, fill, width) { var sign = value < 0 ? "-" : "", string = (sign ? -value : value) + "", length = string.length; return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); } function requote(s) { return s.replace(requoteRe, "\\$&"); } function formatRe(names) { return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); } function formatLookup(names) { return new Map(names.map((name, i) => [name.toLowerCase(), i])); } function parseWeekdayNumberSunday(d, string, i) { var n = numberRe.exec(string.slice(i, i + 1)); return n ? (d.w = +n[0], i + n[0].length) : -1; } function parseWeekdayNumberMonday(d, string, i) { var n = numberRe.exec(string.slice(i, i + 1)); return n ? (d.u = +n[0], i + n[0].length) : -1; } function parseWeekNumberSunday(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.U = +n[0], i + n[0].length) : -1; } function parseWeekNumberISO(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.V = +n[0], i + n[0].length) : -1; } function parseWeekNumberMonday(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.W = +n[0], i + n[0].length) : -1; } function parseFullYear(d, string, i) { var n = numberRe.exec(string.slice(i, i + 4)); return n ? (d.y = +n[0], i + n[0].length) : -1; } function parseYear(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; } function parseZone(d, string, i) { var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6)); return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; } function parseQuarter(d, string, i) { var n = numberRe.exec(string.slice(i, i + 1)); return n ? (d.q = n[0] * 3 - 3, i + n[0].length) : -1; } function parseMonthNumber(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.m = n[0] - 1, i + n[0].length) : -1; } function parseDayOfMonth(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.d = +n[0], i + n[0].length) : -1; } function parseDayOfYear(d, string, i) { var n = numberRe.exec(string.slice(i, i + 3)); return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; } function parseHour24(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.H = +n[0], i + n[0].length) : -1; } function parseMinutes(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.M = +n[0], i + n[0].length) : -1; } function parseSeconds(d, string, i) { var n = numberRe.exec(string.slice(i, i + 2)); return n ? (d.S = +n[0], i + n[0].length) : -1; } function parseMilliseconds(d, string, i) { var n = numberRe.exec(string.slice(i, i + 3)); return n ? (d.L = +n[0], i + n[0].length) : -1; } function parseMicroseconds(d, string, i) { var n = numberRe.exec(string.slice(i, i + 6)); return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1; } function parseLiteralPercent(d, string, i) { var n = percentRe.exec(string.slice(i, i + 1)); return n ? i + n[0].length : -1; } function parseUnixTimestamp(d, string, i) { var n = numberRe.exec(string.slice(i)); return n ? (d.Q = +n[0], i + n[0].length) : -1; } function parseUnixTimestampSeconds(d, string, i) { var n = numberRe.exec(string.slice(i)); return n ? (d.s = +n[0], i + n[0].length) : -1; } function formatDayOfMonth(d, p) { return pad(d.getDate(), p, 2); } function formatHour24(d, p) { return pad(d.getHours(), p, 2); } function formatHour12(d, p) { return pad(d.getHours() % 12 || 12, p, 2); } function formatDayOfYear(d, p) { return pad(1 + timeDay.count(timeYear(d), d), p, 3); } function formatMilliseconds(d, p) { return pad(d.getMilliseconds(), p, 3); } function formatMicroseconds(d, p) { return formatMilliseconds(d, p) + "000"; } function formatMonthNumber(d, p) { return pad(d.getMonth() + 1, p, 2); } function formatMinutes(d, p) { return pad(d.getMinutes(), p, 2); } function formatSeconds(d, p) { return pad(d.getSeconds(), p, 2); } function formatWeekdayNumberMonday(d) { var day = d.getDay(); return day === 0 ? 7 : day; } function formatWeekNumberSunday(d, p) { return pad(timeSunday.count(timeYear(d) - 1, d), p, 2); } function dISO(d) { var day = d.getDay(); return day >= 4 || day === 0 ? timeThursday(d) : timeThursday.ceil(d); } function formatWeekNumberISO(d, p) { d = dISO(d); return pad(timeThursday.count(timeYear(d), d) + (timeYear(d).getDay() === 4), p, 2); } function formatWeekdayNumberSunday(d) { return d.getDay(); } function formatWeekNumberMonday(d, p) { return pad(timeMonday.count(timeYear(d) - 1, d), p, 2); } function formatYear(d, p) { return pad(d.getFullYear() % 100, p, 2); } function formatYearISO(d, p) { d = dISO(d); return pad(d.getFullYear() % 100, p, 2); } function formatFullYear(d, p) { return pad(d.getFullYear() % 10000, p, 4); } function formatFullYearISO(d, p) { var day = d.getDay(); d = day >= 4 || day === 0 ? timeThursday(d) : timeThursday.ceil(d); return pad(d.getFullYear() % 10000, p, 4); } function formatZone(d) { var z = d.getTimezoneOffset(); return (z > 0 ? "-" : (z *= -1, "+")) + pad(z / 60 | 0, "0", 2) + pad(z % 60, "0", 2); } function formatUTCDayOfMonth(d, p) { return pad(d.getUTCDate(), p, 2); } function formatUTCHour24(d, p) { return pad(d.getUTCHours(), p, 2); } function formatUTCHour12(d, p) { return pad(d.getUTCHours() % 12 || 12, p, 2); } function formatUTCDayOfYear(d, p) { return pad(1 + utcDay.count(utcYear(d), d), p, 3); } function formatUTCMilliseconds(d, p) { return pad(d.getUTCMilliseconds(), p, 3); } function formatUTCMicroseconds(d, p) { return formatUTCMilliseconds(d, p) + "000"; } function formatUTCMonthNumber(d, p) { return pad(d.getUTCMonth() + 1, p, 2); } function formatUTCMinutes(d, p) { return pad(d.getUTCMinutes(), p, 2); } function formatUTCSeconds(d, p) { return pad(d.getUTCSeconds(), p, 2); } function formatUTCWeekdayNumberMonday(d) { var dow = d.getUTCDay(); return dow === 0 ? 7 : dow; } function formatUTCWeekNumberSunday(d, p) { return pad(utcSunday.count(utcYear(d) - 1, d), p, 2); } function UTCdISO(d) { var day = d.getUTCDay(); return day >= 4 || day === 0 ? utcThursday(d) : utcThursday.ceil(d); } function formatUTCWeekNumberISO(d, p) { d = UTCdISO(d); return pad(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2); } function formatUTCWeekdayNumberSunday(d) { return d.getUTCDay(); } function formatUTCWeekNumberMonday(d, p) { return pad(utcMonday.count(utcYear(d) - 1, d), p, 2); } function formatUTCYear(d, p) { return pad(d.getUTCFullYear() % 100, p, 2); } function formatUTCYearISO(d, p) { d = UTCdISO(d); return pad(d.getUTCFullYear() % 100, p, 2); } function formatUTCFullYear(d, p) { return pad(d.getUTCFullYear() % 10000, p, 4); } function formatUTCFullYearISO(d, p) { var day = d.getUTCDay(); d = day >= 4 || day === 0 ? utcThursday(d) : utcThursday.ceil(d); return pad(d.getUTCFullYear() % 10000, p, 4); } function formatUTCZone() { return "+0000"; } function formatLiteralPercent() { return "%"; } function formatUnixTimestamp(d) { return +d; } function formatUnixTimestampSeconds(d) { return Math.floor(+d / 1000); } var locale$1; var timeFormat; var timeParse; var utcFormat; var utcParse; defaultLocale$1({ dateTime: "%x, %X", date: "%-m/%-d/%Y", time: "%-I:%M:%S %p", periods: ["AM", "PM"], days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] }); function defaultLocale$1(definition) { locale$1 = formatLocale(definition); timeFormat = locale$1.format; timeParse = locale$1.parse; utcFormat = locale$1.utcFormat; utcParse = locale$1.utcParse; return locale$1; } function timeMultiFormat(format, interval, spec) { spec = spec || {}; if (!vegaUtil.isObject(spec)) { vegaUtil.error(`Invalid time multi-format specifier: ${spec}`); } const second = interval(vegaTime.SECONDS), minute = interval(vegaTime.MINUTES), hour = interval(vegaTime.HOURS), day = interval(vegaTime.DATE), week = interval(vegaTime.WEEK), month = interval(vegaTime.MONTH), quarter = interval(vegaTime.QUARTER), year = interval(vegaTime.YEAR), L = format(spec[vegaTime.MILLISECONDS] || '.%L'), S = format(spec[vegaTime.SECONDS] || ':%S'), M = format(spec[vegaTime.MINUTES] || '%I:%M'), H = format(spec[vegaTime.HOURS] || '%I %p'), d = format(spec[vegaTime.DATE] || spec[vegaTime.DAY] || '%a %d'), w = format(spec[vegaTime.WEEK] || '%b %d'), m = format(spec[vegaTime.MONTH] || '%B'), q = format(spec[vegaTime.QUARTER] || '%B'), y = format(spec[vegaTime.YEAR] || '%Y'); return date => (second(date) < date ? L : minute(date) < date ? S : hour(date) < date ? M : day(date) < date ? H : month(date) < date ? week(date) < date ? d : w : year(date) < date ? quarter(date) < date ? m : q : y)(date); } function timeLocale(locale) { const timeFormat = memoize(locale.format), utcFormat = memoize(locale.utcFormat); return { timeFormat: spec => vegaUtil.isString(spec) ? timeFormat(spec) : timeMultiFormat(timeFormat, vegaTime.timeInterval, spec), utcFormat: spec => vegaUtil.isString(spec) ? utcFormat(spec) : timeMultiFormat(utcFormat, vegaTime.utcInterval, spec), timeParse: memoize(locale.parse), utcParse: memoize(locale.utcParse) }; } let defaultTimeLocale; resetTimeFormatDefaultLocale(); function resetTimeFormatDefaultLocale() { return defaultTimeLocale = timeLocale({ format: timeFormat, parse: timeParse, utcFormat: utcFormat, utcParse: utcParse }); } function timeFormatLocale(definition) { return timeLocale(formatLocale(definition)); } function timeFormatDefaultLocale(definition) { return arguments.length ? defaultTimeLocale = timeFormatLocale(definition) : defaultTimeLocale; } const createLocale = (number, time) => vegaUtil.extend({}, number, time); function locale(numberSpec, timeSpec) { const number = numberSpec ? numberFormatLocale(numberSpec) : numberFormatDefaultLocale(); const time = timeSpec ? timeFormatLocale(timeSpec) : timeFormatDefaultLocale(); return createLocale(number, time); } function defaultLocale(numberSpec, timeSpec) { const args = arguments.length; if (args && args !== 2) { vegaUtil.error('defaultLocale expects either zero or two arguments.'); } return args ? createLocale(numberFormatDefaultLocale(numberSpec), timeFormatDefaultLocale(timeSpec)) : createLocale(numberFormatDefaultLocale(), timeFormatDefaultLocale()); } function resetDefaultLocale() { resetNumberFormatDefaultLocale(); resetTimeFormatDefaultLocale(); return defaultLocale(); } exports.defaultLocale = defaultLocale; exports.locale = locale; exports.numberFormatDefaultLocale = numberFormatDefaultLocale; exports.numberFormatLocale = numberFormatLocale; exports.resetDefaultLocale = resetDefaultLocale; exports.resetNumberFormatDefaultLocale = resetNumberFormatDefaultLocale; exports.resetTimeFormatDefaultLocale = resetTimeFormatDefaultLocale; exports.timeFormatDefaultLocale = timeFormatDefaultLocale; exports.timeFormatLocale = timeFormatLocale; }));