|
@@ -1,6285 +0,0 @@
|
|
|
-(function (global, factory) {
|
|
|
- typeof exports === 'object' && typeof module !== 'undefined' ? module.exports = factory() :
|
|
|
- typeof define === 'function' && define.amd ? define(factory) :
|
|
|
- (global = typeof globalThis !== 'undefined' ? globalThis : global || self, global.MessageFormat = factory());
|
|
|
-})(this, (function () { 'use strict';
|
|
|
-
|
|
|
- /******************************************************************************
|
|
|
- Copyright (c) Microsoft Corporation.
|
|
|
-
|
|
|
- Permission to use, copy, modify, and/or distribute this software for any
|
|
|
- purpose with or without fee is hereby granted.
|
|
|
-
|
|
|
- THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH
|
|
|
- REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
|
|
|
- AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT,
|
|
|
- INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
|
|
|
- LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR
|
|
|
- OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
|
|
|
- PERFORMANCE OF THIS SOFTWARE.
|
|
|
- ***************************************************************************** */
|
|
|
- /* global Reflect, Promise */
|
|
|
-
|
|
|
- var __assign = function () {
|
|
|
- __assign = Object.assign || function __assign(t) {
|
|
|
- for (var s, i = 1, n = arguments.length; i < n; i++) {
|
|
|
- s = arguments[i];
|
|
|
- for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p];
|
|
|
- }
|
|
|
- return t;
|
|
|
- };
|
|
|
- return __assign.apply(this, arguments);
|
|
|
- };
|
|
|
- function __values(o) {
|
|
|
- var s = typeof Symbol === "function" && Symbol.iterator,
|
|
|
- m = s && o[s],
|
|
|
- i = 0;
|
|
|
- if (m) return m.call(o);
|
|
|
- if (o && typeof o.length === "number") return {
|
|
|
- next: function () {
|
|
|
- if (o && i >= o.length) o = void 0;
|
|
|
- return {
|
|
|
- value: o && o[i++],
|
|
|
- done: !o
|
|
|
- };
|
|
|
- }
|
|
|
- };
|
|
|
- throw new TypeError(s ? "Object is not iterable." : "Symbol.iterator is not defined.");
|
|
|
- }
|
|
|
- function __read(o, n) {
|
|
|
- var m = typeof Symbol === "function" && o[Symbol.iterator];
|
|
|
- if (!m) return o;
|
|
|
- var i = m.call(o),
|
|
|
- r,
|
|
|
- ar = [],
|
|
|
- e;
|
|
|
- try {
|
|
|
- while ((n === void 0 || n-- > 0) && !(r = i.next()).done) ar.push(r.value);
|
|
|
- } catch (error) {
|
|
|
- e = {
|
|
|
- error: error
|
|
|
- };
|
|
|
- } finally {
|
|
|
- try {
|
|
|
- if (r && !r.done && (m = i["return"])) m.call(i);
|
|
|
- } finally {
|
|
|
- if (e) throw e.error;
|
|
|
- }
|
|
|
- }
|
|
|
- return ar;
|
|
|
- }
|
|
|
- function __spreadArray(to, from, pack) {
|
|
|
- if (pack || arguments.length === 2) for (var i = 0, l = from.length, ar; i < l; i++) {
|
|
|
- if (ar || !(i in from)) {
|
|
|
- if (!ar) ar = Array.prototype.slice.call(from, 0, i);
|
|
|
- ar[i] = from[i];
|
|
|
- }
|
|
|
- }
|
|
|
- return to.concat(ar || Array.prototype.slice.call(from));
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Parent class for errors.
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * Errors with `type: "warning"` do not necessarily indicate that the parser
|
|
|
- * encountered an error. In addition to a human-friendly `message`, may also
|
|
|
- * includes the `token` at which the error was encountered.
|
|
|
- *
|
|
|
- * @public
|
|
|
- */
|
|
|
- class DateFormatError extends Error {
|
|
|
- /** @internal */
|
|
|
- constructor(msg, token, type) {
|
|
|
- super(msg);
|
|
|
- this.token = token;
|
|
|
- this.type = type || 'error';
|
|
|
- }
|
|
|
- }
|
|
|
- const alpha = width => width < 4 ? 'short' : width === 4 ? 'long' : 'narrow';
|
|
|
- const numeric = width => width % 2 === 0 ? '2-digit' : 'numeric';
|
|
|
- function yearOptions(token, onError) {
|
|
|
- switch (token.char) {
|
|
|
- case 'y':
|
|
|
- return {
|
|
|
- year: numeric(token.width)
|
|
|
- };
|
|
|
- case 'r':
|
|
|
- return {
|
|
|
- calendar: 'gregory',
|
|
|
- year: 'numeric'
|
|
|
- };
|
|
|
- case 'u':
|
|
|
- case 'U':
|
|
|
- case 'Y':
|
|
|
- default:
|
|
|
- onError(`${token.desc} is not supported; falling back to year:numeric`, DateFormatError.WARNING);
|
|
|
- return {
|
|
|
- year: 'numeric'
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
- function monthStyle(token, onError) {
|
|
|
- switch (token.width) {
|
|
|
- case 1:
|
|
|
- return 'numeric';
|
|
|
- case 2:
|
|
|
- return '2-digit';
|
|
|
- case 3:
|
|
|
- return 'short';
|
|
|
- case 4:
|
|
|
- return 'long';
|
|
|
- case 5:
|
|
|
- return 'narrow';
|
|
|
- default:
|
|
|
- onError(`${token.desc} is not supported with width ${token.width}`);
|
|
|
- return undefined;
|
|
|
- }
|
|
|
- }
|
|
|
- function dayStyle(token, onError) {
|
|
|
- const {
|
|
|
- char,
|
|
|
- desc,
|
|
|
- width
|
|
|
- } = token;
|
|
|
- if (char === 'd') return numeric(width);else {
|
|
|
- onError(`${desc} is not supported`);
|
|
|
- return undefined;
|
|
|
- }
|
|
|
- }
|
|
|
- function weekdayStyle(token, onError) {
|
|
|
- const {
|
|
|
- char,
|
|
|
- desc,
|
|
|
- width
|
|
|
- } = token;
|
|
|
- if ((char === 'c' || char === 'e') && width < 3) {
|
|
|
- // ignoring stand-alone-ness
|
|
|
- const msg = `Numeric value is not supported for ${desc}; falling back to weekday:short`;
|
|
|
- onError(msg, DateFormatError.WARNING);
|
|
|
- }
|
|
|
- // merging narrow styles
|
|
|
- return alpha(width);
|
|
|
- }
|
|
|
- function hourOptions(token) {
|
|
|
- const hour = numeric(token.width);
|
|
|
- let hourCycle;
|
|
|
- switch (token.char) {
|
|
|
- case 'h':
|
|
|
- hourCycle = 'h12';
|
|
|
- break;
|
|
|
- case 'H':
|
|
|
- hourCycle = 'h23';
|
|
|
- break;
|
|
|
- case 'k':
|
|
|
- hourCycle = 'h24';
|
|
|
- break;
|
|
|
- case 'K':
|
|
|
- hourCycle = 'h11';
|
|
|
- break;
|
|
|
- }
|
|
|
- return hourCycle ? {
|
|
|
- hour,
|
|
|
- hourCycle
|
|
|
- } : {
|
|
|
- hour
|
|
|
- };
|
|
|
- }
|
|
|
- function timeZoneNameStyle(token, onError) {
|
|
|
- // so much fallback behaviour here
|
|
|
- const {
|
|
|
- char,
|
|
|
- desc,
|
|
|
- width
|
|
|
- } = token;
|
|
|
- switch (char) {
|
|
|
- case 'v':
|
|
|
- case 'z':
|
|
|
- return width === 4 ? 'long' : 'short';
|
|
|
- case 'V':
|
|
|
- if (width === 4) return 'long';
|
|
|
- onError(`${desc} is not supported with width ${width}`);
|
|
|
- return undefined;
|
|
|
- case 'X':
|
|
|
- onError(`${desc} is not supported`);
|
|
|
- return undefined;
|
|
|
- }
|
|
|
- return 'short';
|
|
|
- }
|
|
|
- function compileOptions(token, onError) {
|
|
|
- switch (token.field) {
|
|
|
- case 'era':
|
|
|
- return {
|
|
|
- era: alpha(token.width)
|
|
|
- };
|
|
|
- case 'year':
|
|
|
- return yearOptions(token, onError);
|
|
|
- case 'month':
|
|
|
- return {
|
|
|
- month: monthStyle(token, onError)
|
|
|
- };
|
|
|
- case 'day':
|
|
|
- return {
|
|
|
- day: dayStyle(token, onError)
|
|
|
- };
|
|
|
- case 'weekday':
|
|
|
- return {
|
|
|
- weekday: weekdayStyle(token, onError)
|
|
|
- };
|
|
|
- case 'period':
|
|
|
- return undefined;
|
|
|
- case 'hour':
|
|
|
- return hourOptions(token);
|
|
|
- case 'min':
|
|
|
- return {
|
|
|
- minute: numeric(token.width)
|
|
|
- };
|
|
|
- case 'sec':
|
|
|
- return {
|
|
|
- second: numeric(token.width)
|
|
|
- };
|
|
|
- case 'tz':
|
|
|
- return {
|
|
|
- timeZoneName: timeZoneNameStyle(token, onError)
|
|
|
- };
|
|
|
- case 'quarter':
|
|
|
- case 'week':
|
|
|
- case 'sec-frac':
|
|
|
- case 'ms':
|
|
|
- onError(`${token.desc} is not supported`);
|
|
|
- }
|
|
|
- return undefined;
|
|
|
- }
|
|
|
- function getDateFormatOptions(tokens) {
|
|
|
- let onError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : error => {
|
|
|
- throw error;
|
|
|
- };
|
|
|
- const options = {};
|
|
|
- const fields = [];
|
|
|
- for (const token of tokens) {
|
|
|
- const {
|
|
|
- error,
|
|
|
- field,
|
|
|
- str
|
|
|
- } = token;
|
|
|
- if (error) {
|
|
|
- const dte = new DateFormatError(error.message, token);
|
|
|
- dte.stack = error.stack;
|
|
|
- onError(dte);
|
|
|
- }
|
|
|
- if (str) {
|
|
|
- const msg = `Ignoring string part: ${str}`;
|
|
|
- onError(new DateFormatError(msg, token, DateFormatError.WARNING));
|
|
|
- }
|
|
|
- if (field) {
|
|
|
- if (fields.indexOf(field) === -1) fields.push(field);else onError(new DateFormatError(`Duplicate ${field} token`, token));
|
|
|
- }
|
|
|
- const opt = compileOptions(token, (msg, isWarning) => onError(new DateFormatError(msg, token, isWarning)));
|
|
|
- if (opt) Object.assign(options, opt);
|
|
|
- }
|
|
|
- return options;
|
|
|
- }
|
|
|
-
|
|
|
- const fields = {
|
|
|
- G: {
|
|
|
- field: 'era',
|
|
|
- desc: 'Era'
|
|
|
- },
|
|
|
- y: {
|
|
|
- field: 'year',
|
|
|
- desc: 'Year'
|
|
|
- },
|
|
|
- Y: {
|
|
|
- field: 'year',
|
|
|
- desc: 'Year of "Week of Year"'
|
|
|
- },
|
|
|
- u: {
|
|
|
- field: 'year',
|
|
|
- desc: 'Extended year'
|
|
|
- },
|
|
|
- U: {
|
|
|
- field: 'year',
|
|
|
- desc: 'Cyclic year name'
|
|
|
- },
|
|
|
- r: {
|
|
|
- field: 'year',
|
|
|
- desc: 'Related Gregorian year'
|
|
|
- },
|
|
|
- Q: {
|
|
|
- field: 'quarter',
|
|
|
- desc: 'Quarter'
|
|
|
- },
|
|
|
- q: {
|
|
|
- field: 'quarter',
|
|
|
- desc: 'Stand-alone quarter'
|
|
|
- },
|
|
|
- M: {
|
|
|
- field: 'month',
|
|
|
- desc: 'Month in year'
|
|
|
- },
|
|
|
- L: {
|
|
|
- field: 'month',
|
|
|
- desc: 'Stand-alone month in year'
|
|
|
- },
|
|
|
- w: {
|
|
|
- field: 'week',
|
|
|
- desc: 'Week of year'
|
|
|
- },
|
|
|
- W: {
|
|
|
- field: 'week',
|
|
|
- desc: 'Week of month'
|
|
|
- },
|
|
|
- d: {
|
|
|
- field: 'day',
|
|
|
- desc: 'Day in month'
|
|
|
- },
|
|
|
- D: {
|
|
|
- field: 'day',
|
|
|
- desc: 'Day of year'
|
|
|
- },
|
|
|
- F: {
|
|
|
- field: 'day',
|
|
|
- desc: 'Day of week in month'
|
|
|
- },
|
|
|
- g: {
|
|
|
- field: 'day',
|
|
|
- desc: 'Modified julian day'
|
|
|
- },
|
|
|
- E: {
|
|
|
- field: 'weekday',
|
|
|
- desc: 'Day of week'
|
|
|
- },
|
|
|
- e: {
|
|
|
- field: 'weekday',
|
|
|
- desc: 'Local day of week'
|
|
|
- },
|
|
|
- c: {
|
|
|
- field: 'weekday',
|
|
|
- desc: 'Stand-alone local day of week'
|
|
|
- },
|
|
|
- a: {
|
|
|
- field: 'period',
|
|
|
- desc: 'AM/PM marker'
|
|
|
- },
|
|
|
- b: {
|
|
|
- field: 'period',
|
|
|
- desc: 'AM/PM/noon/midnight marker'
|
|
|
- },
|
|
|
- B: {
|
|
|
- field: 'period',
|
|
|
- desc: 'Flexible day period'
|
|
|
- },
|
|
|
- h: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in AM/PM (1~12)'
|
|
|
- },
|
|
|
- H: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in day (0~23)'
|
|
|
- },
|
|
|
- k: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in day (1~24)'
|
|
|
- },
|
|
|
- K: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in AM/PM (0~11)'
|
|
|
- },
|
|
|
- j: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in preferred cycle'
|
|
|
- },
|
|
|
- J: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in preferred cycle without marker'
|
|
|
- },
|
|
|
- C: {
|
|
|
- field: 'hour',
|
|
|
- desc: 'Hour in preferred cycle with flexible marker'
|
|
|
- },
|
|
|
- m: {
|
|
|
- field: 'min',
|
|
|
- desc: 'Minute in hour'
|
|
|
- },
|
|
|
- s: {
|
|
|
- field: 'sec',
|
|
|
- desc: 'Second in minute'
|
|
|
- },
|
|
|
- S: {
|
|
|
- field: 'sec-frac',
|
|
|
- desc: 'Fractional second'
|
|
|
- },
|
|
|
- A: {
|
|
|
- field: 'ms',
|
|
|
- desc: 'Milliseconds in day'
|
|
|
- },
|
|
|
- z: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone: specific non-location'
|
|
|
- },
|
|
|
- Z: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone'
|
|
|
- },
|
|
|
- O: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone: localized'
|
|
|
- },
|
|
|
- v: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone: generic non-location'
|
|
|
- },
|
|
|
- V: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone: ID'
|
|
|
- },
|
|
|
- X: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone: ISO8601 with Z'
|
|
|
- },
|
|
|
- x: {
|
|
|
- field: 'tz',
|
|
|
- desc: 'Time Zone: ISO8601'
|
|
|
- }
|
|
|
- };
|
|
|
- const isLetter = char => char >= 'A' && char <= 'Z' || char >= 'a' && char <= 'z';
|
|
|
- function readFieldToken(src, pos) {
|
|
|
- const char = src[pos];
|
|
|
- let width = 1;
|
|
|
- while (src[++pos] === char) ++width;
|
|
|
- const field = fields[char];
|
|
|
- if (!field) {
|
|
|
- const msg = `The letter ${char} is not a valid field identifier`;
|
|
|
- return {
|
|
|
- char,
|
|
|
- error: new Error(msg),
|
|
|
- width
|
|
|
- };
|
|
|
- }
|
|
|
- return {
|
|
|
- char,
|
|
|
- field: field.field,
|
|
|
- desc: field.desc,
|
|
|
- width
|
|
|
- };
|
|
|
- }
|
|
|
- function readQuotedToken(src, pos) {
|
|
|
- let str = src[++pos];
|
|
|
- let width = 2;
|
|
|
- if (str === "'") return {
|
|
|
- char: "'",
|
|
|
- str,
|
|
|
- width
|
|
|
- };
|
|
|
- while (true) {
|
|
|
- const next = src[++pos];
|
|
|
- ++width;
|
|
|
- if (next === undefined) {
|
|
|
- const msg = `Unterminated quoted literal in pattern: ${str || src}`;
|
|
|
- return {
|
|
|
- char: "'",
|
|
|
- error: new Error(msg),
|
|
|
- str,
|
|
|
- width
|
|
|
- };
|
|
|
- } else if (next === "'") {
|
|
|
- if (src[++pos] !== "'") return {
|
|
|
- char: "'",
|
|
|
- str,
|
|
|
- width
|
|
|
- };else ++width;
|
|
|
- }
|
|
|
- str += next;
|
|
|
- }
|
|
|
- }
|
|
|
- function readToken(src, pos) {
|
|
|
- const char = src[pos];
|
|
|
- if (!char) return null;
|
|
|
- if (isLetter(char)) return readFieldToken(src, pos);
|
|
|
- if (char === "'") return readQuotedToken(src, pos);
|
|
|
- let str = char;
|
|
|
- let width = 1;
|
|
|
- while (true) {
|
|
|
- const next = src[++pos];
|
|
|
- if (!next || isLetter(next) || next === "'") return {
|
|
|
- char,
|
|
|
- str,
|
|
|
- width
|
|
|
- };
|
|
|
- str += next;
|
|
|
- width += 1;
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Parse an {@link http://userguide.icu-project.org/formatparse/datetime | ICU
|
|
|
- * DateFormat skeleton} string into a {@link DateToken} array.
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * Errors will not be thrown, but if encountered are included as the relevant
|
|
|
- * token's `error` value.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param src - The skeleton string
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { parseDateTokens } from '@messageformat/date-skeleton'
|
|
|
- *
|
|
|
- * parseDateTokens('GrMMMdd', console.error)
|
|
|
- * // [
|
|
|
- * // { char: 'G', field: 'era', desc: 'Era', width: 1 },
|
|
|
- * // { char: 'r', field: 'year', desc: 'Related Gregorian year', width: 1 },
|
|
|
- * // { char: 'M', field: 'month', desc: 'Month in year', width: 3 },
|
|
|
- * // { char: 'd', field: 'day', desc: 'Day in month', width: 2 }
|
|
|
- * // ]
|
|
|
- * ```
|
|
|
- */
|
|
|
- function parseDateTokens(src) {
|
|
|
- const tokens = [];
|
|
|
- let pos = 0;
|
|
|
- while (true) {
|
|
|
- const token = readToken(src, pos);
|
|
|
- if (!token) return tokens;
|
|
|
- tokens.push(token);
|
|
|
- pos += token.width;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns a date formatter function for the given locales and date skeleton
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * Uses `Intl.DateTimeFormat` internally.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param locales - One or more valid BCP 47 language tags, e.g. `fr` or `en-CA`
|
|
|
- * @param tokens - An ICU DateFormat skeleton string, or an array or parsed
|
|
|
- * `DateToken` tokens
|
|
|
- * @param onError - If defined, will be called separately for each encountered
|
|
|
- * parsing error and unsupported feature.
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { getDateFormatter } from '@messageformat/date-skeleton'
|
|
|
- *
|
|
|
- * // 2006 Jan 2, 15:04:05.789 in local time
|
|
|
- * const date = new Date(2006, 0, 2, 15, 4, 5, 789)
|
|
|
- *
|
|
|
- * let fmt = getDateFormatter('en-CA', 'GrMMMdd', console.error)
|
|
|
- * fmt(date) // 'Jan. 02, 2006 AD'
|
|
|
- *
|
|
|
- * fmt = getDateFormatter('en-CA', 'hamszzzz', console.error)
|
|
|
- * fmt(date) // '3:04:05 p.m. Newfoundland Daylight Time'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function getDateFormatter(locales, tokens, onError) {
|
|
|
- if (typeof tokens === 'string') tokens = parseDateTokens(tokens);
|
|
|
- const opt = getDateFormatOptions(tokens, onError);
|
|
|
- const dtf = new Intl.DateTimeFormat(locales, opt);
|
|
|
- return date => dtf.format(date);
|
|
|
- }
|
|
|
- /**
|
|
|
- * Returns a string of JavaScript source that evaluates to a date formatter
|
|
|
- * function with the same `(date: Date | number) => string` signature as the
|
|
|
- * function returned by {@link getDateFormatter}.
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * The returned function will memoize an `Intl.DateTimeFormat` instance.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param locales - One or more valid BCP 47 language tags, e.g. `fr` or `en-CA`
|
|
|
- * @param tokens - An ICU DateFormat skeleton string, or an array or parsed
|
|
|
- * `DateToken` tokens
|
|
|
- * @param onError - If defined, will be called separately for each encountered
|
|
|
- * parsing error and unsupported feature.
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { getDateFormatterSource } from '@messageformat/date-skeleton'
|
|
|
- *
|
|
|
- * getDateFormatterSource('en-CA', 'GrMMMdd', console.error)
|
|
|
- * // '(function() {\n' +
|
|
|
- * // ' var opt = {"era":"short","calendar":"gregory","year":"numeric",' +
|
|
|
- * // '"month":"short","day":"2-digit"};\n' +
|
|
|
- * // ' var dtf = new Intl.DateTimeFormat("en-CA", opt);\n' +
|
|
|
- * // ' return function(value) { return dtf.format(value); }\n' +
|
|
|
- * // '})()'
|
|
|
- *
|
|
|
- * const src = getDateFormatterSource('en-CA', 'hamszzzz', console.error)
|
|
|
- * // '(function() {\n' +
|
|
|
- * // ' var opt = {"hour":"numeric","hourCycle":"h12","minute":"numeric",' +
|
|
|
- * // '"second":"numeric","timeZoneName":"long"};\n' +
|
|
|
- * // ' var dtf = new Intl.DateTimeFormat("en-CA", opt);\n' +
|
|
|
- * // ' return function(value) { return dtf.format(value); }\n' +
|
|
|
- * // '})()'
|
|
|
- *
|
|
|
- * const fmt = new Function(`return ${src}`)()
|
|
|
- * const date = new Date(2006, 0, 2, 15, 4, 5, 789)
|
|
|
- * fmt(date) // '3:04:05 p.m. Newfoundland Daylight Time'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function getDateFormatterSource(locales, tokens, onError) {
|
|
|
- if (typeof tokens === 'string') tokens = parseDateTokens(tokens);
|
|
|
- const opt = getDateFormatOptions(tokens, onError);
|
|
|
- const lines = [`(function() {`, `var opt = ${JSON.stringify(opt)};`, `var dtf = new Intl.DateTimeFormat(${JSON.stringify(locales)}, opt);`, `return function(value) { return dtf.format(value); }`];
|
|
|
- return lines.join('\n ') + '\n})()';
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Base class for errors. In addition to a `code` and a human-friendly
|
|
|
- * `message`, may also includes the token `stem` as well as other fields.
|
|
|
- *
|
|
|
- * @public
|
|
|
- */
|
|
|
- class NumberFormatError extends Error {
|
|
|
- /** @internal */
|
|
|
- constructor(code, msg) {
|
|
|
- super(msg);
|
|
|
- this.code = code;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class BadOptionError extends NumberFormatError {
|
|
|
- constructor(stem, opt) {
|
|
|
- super('BAD_OPTION', `Unknown ${stem} option: ${opt}`);
|
|
|
- this.stem = stem;
|
|
|
- this.option = opt;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class BadStemError extends NumberFormatError {
|
|
|
- constructor(stem) {
|
|
|
- super('BAD_STEM', `Unknown stem: ${stem}`);
|
|
|
- this.stem = stem;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class MaskedValueError extends NumberFormatError {
|
|
|
- constructor(type, prev) {
|
|
|
- super('MASKED_VALUE', `Value for ${type} is set multiple times`);
|
|
|
- this.type = type;
|
|
|
- this.prev = prev;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class MissingOptionError extends NumberFormatError {
|
|
|
- constructor(stem) {
|
|
|
- super('MISSING_OPTION', `Required option missing for ${stem}`);
|
|
|
- this.stem = stem;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class PatternError extends NumberFormatError {
|
|
|
- constructor(char, msg) {
|
|
|
- super('BAD_PATTERN', msg);
|
|
|
- this.char = char;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class TooManyOptionsError extends NumberFormatError {
|
|
|
- constructor(stem, options, maxOpt) {
|
|
|
- const maxOptStr = maxOpt > 1 ? `${maxOpt} options` : 'one option';
|
|
|
- super('TOO_MANY_OPTIONS', `Token ${stem} only supports ${maxOptStr} (got ${options.length})`);
|
|
|
- this.stem = stem;
|
|
|
- this.options = options;
|
|
|
- }
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- class UnsupportedError extends NumberFormatError {
|
|
|
- constructor(stem, source) {
|
|
|
- super('UNSUPPORTED', `The stem ${stem} is not supported`);
|
|
|
- this.stem = stem;
|
|
|
- if (source) {
|
|
|
- this.message += ` with value ${source}`;
|
|
|
- this.source = source;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Add
|
|
|
- * {@link https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Intl#Locale_identification_and_negotiation | numbering-system tags}
|
|
|
- * to locale identifiers
|
|
|
- *
|
|
|
- * @internal
|
|
|
- */
|
|
|
- function getNumberFormatLocales(locales, _ref) {
|
|
|
- let {
|
|
|
- numberingSystem
|
|
|
- } = _ref;
|
|
|
- if (!Array.isArray(locales)) locales = [locales];
|
|
|
- return numberingSystem ? locales.map(lc => {
|
|
|
- const ext = lc.indexOf('-u-') === -1 ? 'u-nu' : 'nu';
|
|
|
- return `${lc}-${ext}-${numberingSystem}`;
|
|
|
- }).concat(locales) : locales;
|
|
|
- }
|
|
|
-
|
|
|
- // from https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Math/round
|
|
|
- function round(x, precision) {
|
|
|
- const y = +x + precision / 2;
|
|
|
- return y - y % +precision;
|
|
|
- }
|
|
|
- function getNumberFormatMultiplier(_ref) {
|
|
|
- let {
|
|
|
- scale,
|
|
|
- unit
|
|
|
- } = _ref;
|
|
|
- let mult = typeof scale === 'number' && scale >= 0 ? scale : 1;
|
|
|
- if (unit && unit.style === 'percent') mult *= 0.01;
|
|
|
- return mult;
|
|
|
- }
|
|
|
- /**
|
|
|
- * Determine a modifier for the input value to account for any `scale`,
|
|
|
- * `percent`, and `precision-increment` tokens in the skeleton.
|
|
|
- *
|
|
|
- * @internal
|
|
|
- * @remarks
|
|
|
- * With ICU NumberFormatter, the `percent` skeleton would style `25` as "25%".
|
|
|
- * To achieve the same with `Intl.NumberFormat`, the input value must be `0.25`.
|
|
|
- */
|
|
|
- function getNumberFormatModifier(skeleton) {
|
|
|
- const mult = getNumberFormatMultiplier(skeleton);
|
|
|
- const {
|
|
|
- precision
|
|
|
- } = skeleton;
|
|
|
- if (precision && precision.style === 'precision-increment') {
|
|
|
- return n => round(n, precision.increment) * mult;
|
|
|
- } else {
|
|
|
- return n => n * mult;
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Returns a string of JavaScript source that evaluates to a modifier for the
|
|
|
- * input value to account for any `scale`, `percent`, and `precision-increment`
|
|
|
- * tokens in the skeleton.
|
|
|
- *
|
|
|
- * @internal
|
|
|
- * @remarks
|
|
|
- * With ICU NumberFormatter, the `percent` skeleton would style `25` as "25%".
|
|
|
- * To achieve the same with `Intl.NumberFormat`, the input value must be `0.25`.
|
|
|
- */
|
|
|
- function getNumberFormatModifierSource(skeleton) {
|
|
|
- const mult = getNumberFormatMultiplier(skeleton);
|
|
|
- const {
|
|
|
- precision
|
|
|
- } = skeleton;
|
|
|
- if (precision && precision.style === 'precision-increment') {
|
|
|
- // see round() above for source
|
|
|
- const setX = `+n + ${precision.increment / 2}`;
|
|
|
- let res = `x - (x % +${precision.increment})`;
|
|
|
- if (mult !== 1) res = `(${res}) * ${mult}`;
|
|
|
- return `function(n) { var x = ${setX}; return ${res}; }`;
|
|
|
- }
|
|
|
- return mult !== 1 ? `function(n) { return n * ${mult}; }` : null;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Given an input ICU NumberFormatter skeleton, does its best to construct a
|
|
|
- * corresponding `Intl.NumberFormat` options structure.
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * Some features depend on `Intl.NumberFormat` features defined in ES2020.
|
|
|
- *
|
|
|
- * @internal
|
|
|
- * @param onUnsupported - If defined, called when encountering unsupported (but
|
|
|
- * valid) tokens, such as `decimal-always` or `permille`. The error `source`
|
|
|
- * may specify the source of an unsupported option.
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import {
|
|
|
- * getNumberFormatOptions,
|
|
|
- * parseNumberSkeleton
|
|
|
- * } from '@messageformat/number-skeleton'
|
|
|
- *
|
|
|
- * const src = 'currency/CAD unit-width-narrow'
|
|
|
- * const skeleton = parseNumberSkeleton(src, console.error)
|
|
|
- * // {
|
|
|
- * // unit: { style: 'currency', currency: 'CAD' },
|
|
|
- * // unitWidth: 'unit-width-narrow'
|
|
|
- * // }
|
|
|
- *
|
|
|
- * getNumberFormatOptions(skeleton, console.error)
|
|
|
- * // {
|
|
|
- * // style: 'currency',
|
|
|
- * // currency: 'CAD',
|
|
|
- * // currencyDisplay: 'narrowSymbol',
|
|
|
- * // unitDisplay: 'narrow'
|
|
|
- * // }
|
|
|
- *
|
|
|
- * const sk2 = parseNumberSkeleton('group-min2')
|
|
|
- * // { group: 'group-min2' }
|
|
|
- *
|
|
|
- * getNumberFormatOptions(sk2, console.error)
|
|
|
- * // Error: The stem group-min2 is not supported
|
|
|
- * // at UnsupportedError.NumberFormatError ... {
|
|
|
- * // code: 'UNSUPPORTED',
|
|
|
- * // stem: 'group-min2'
|
|
|
- * // }
|
|
|
- * // {}
|
|
|
- * ```
|
|
|
- */
|
|
|
- function getNumberFormatOptions(skeleton, onUnsupported) {
|
|
|
- const {
|
|
|
- decimal,
|
|
|
- group,
|
|
|
- integerWidth,
|
|
|
- notation,
|
|
|
- precision,
|
|
|
- roundingMode,
|
|
|
- sign,
|
|
|
- unit,
|
|
|
- unitPer,
|
|
|
- unitWidth
|
|
|
- } = skeleton;
|
|
|
- const fail = (stem, source) => {
|
|
|
- if (onUnsupported) onUnsupported(new UnsupportedError(stem, source));
|
|
|
- };
|
|
|
- const opt = {};
|
|
|
- if (unit) {
|
|
|
- switch (unit.style) {
|
|
|
- case 'base-unit':
|
|
|
- opt.style = 'decimal';
|
|
|
- break;
|
|
|
- case 'currency':
|
|
|
- opt.style = 'currency';
|
|
|
- opt.currency = unit.currency;
|
|
|
- break;
|
|
|
- case 'measure-unit':
|
|
|
- opt.style = 'unit';
|
|
|
- opt.unit = unit.unit.replace(/.*-/, '');
|
|
|
- if (unitPer) opt.unit += '-per-' + unitPer.replace(/.*-/, '');
|
|
|
- break;
|
|
|
- case 'percent':
|
|
|
- opt.style = 'percent';
|
|
|
- break;
|
|
|
- case 'permille':
|
|
|
- fail('permille');
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- switch (unitWidth) {
|
|
|
- case 'unit-width-full-name':
|
|
|
- opt.currencyDisplay = 'name';
|
|
|
- opt.unitDisplay = 'long';
|
|
|
- break;
|
|
|
- case 'unit-width-hidden':
|
|
|
- fail(unitWidth);
|
|
|
- break;
|
|
|
- case 'unit-width-iso-code':
|
|
|
- opt.currencyDisplay = 'code';
|
|
|
- break;
|
|
|
- case 'unit-width-narrow':
|
|
|
- opt.currencyDisplay = 'narrowSymbol';
|
|
|
- opt.unitDisplay = 'narrow';
|
|
|
- break;
|
|
|
- case 'unit-width-short':
|
|
|
- opt.currencyDisplay = 'symbol';
|
|
|
- opt.unitDisplay = 'short';
|
|
|
- break;
|
|
|
- }
|
|
|
- switch (group) {
|
|
|
- case 'group-off':
|
|
|
- opt.useGrouping = false;
|
|
|
- break;
|
|
|
- case 'group-auto':
|
|
|
- opt.useGrouping = true;
|
|
|
- break;
|
|
|
- case 'group-min2':
|
|
|
- case 'group-on-aligned':
|
|
|
- case 'group-thousands':
|
|
|
- fail(group);
|
|
|
- opt.useGrouping = true;
|
|
|
- break;
|
|
|
- }
|
|
|
- if (precision) {
|
|
|
- switch (precision.style) {
|
|
|
- case 'precision-fraction':
|
|
|
- {
|
|
|
- const {
|
|
|
- minFraction: minF,
|
|
|
- maxFraction: maxF,
|
|
|
- minSignificant: minS,
|
|
|
- maxSignificant: maxS,
|
|
|
- source
|
|
|
- } = precision;
|
|
|
- if (typeof minF === 'number') {
|
|
|
- opt.minimumFractionDigits = minF;
|
|
|
- if (typeof minS === 'number') fail('precision-fraction', source);
|
|
|
- }
|
|
|
- if (typeof maxF === 'number') opt.maximumFractionDigits = maxF;
|
|
|
- if (typeof minS === 'number') opt.minimumSignificantDigits = minS;
|
|
|
- if (typeof maxS === 'number') opt.maximumSignificantDigits = maxS;
|
|
|
- break;
|
|
|
- }
|
|
|
- case 'precision-integer':
|
|
|
- opt.maximumFractionDigits = 0;
|
|
|
- break;
|
|
|
- case 'precision-unlimited':
|
|
|
- opt.maximumFractionDigits = 20;
|
|
|
- break;
|
|
|
- case 'precision-increment':
|
|
|
- break;
|
|
|
- case 'precision-currency-standard':
|
|
|
- opt.trailingZeroDisplay = precision.trailingZero;
|
|
|
- break;
|
|
|
- case 'precision-currency-cash':
|
|
|
- fail(precision.style);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- if (notation) {
|
|
|
- switch (notation.style) {
|
|
|
- case 'compact-short':
|
|
|
- opt.notation = 'compact';
|
|
|
- opt.compactDisplay = 'short';
|
|
|
- break;
|
|
|
- case 'compact-long':
|
|
|
- opt.notation = 'compact';
|
|
|
- opt.compactDisplay = 'long';
|
|
|
- break;
|
|
|
- case 'notation-simple':
|
|
|
- opt.notation = 'standard';
|
|
|
- break;
|
|
|
- case 'scientific':
|
|
|
- case 'engineering':
|
|
|
- {
|
|
|
- const {
|
|
|
- expDigits,
|
|
|
- expSign,
|
|
|
- source,
|
|
|
- style
|
|
|
- } = notation;
|
|
|
- opt.notation = style;
|
|
|
- if (expDigits && expDigits > 1 || expSign && expSign !== 'sign-auto') fail(style, source);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (integerWidth) {
|
|
|
- const {
|
|
|
- min,
|
|
|
- max,
|
|
|
- source
|
|
|
- } = integerWidth;
|
|
|
- if (min > 0) opt.minimumIntegerDigits = min;
|
|
|
- if (Number(max) > 0) {
|
|
|
- const hasExp = opt.notation === 'engineering' || opt.notation === 'scientific';
|
|
|
- if (max === 3 && hasExp) opt.notation = 'engineering';else fail('integer-width', source);
|
|
|
- }
|
|
|
- }
|
|
|
- switch (sign) {
|
|
|
- case 'sign-auto':
|
|
|
- opt.signDisplay = 'auto';
|
|
|
- break;
|
|
|
- case 'sign-always':
|
|
|
- opt.signDisplay = 'always';
|
|
|
- break;
|
|
|
- case 'sign-except-zero':
|
|
|
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
- // @ts-ignore https://github.com/microsoft/TypeScript/issues/46712
|
|
|
- opt.signDisplay = 'exceptZero';
|
|
|
- break;
|
|
|
- case 'sign-never':
|
|
|
- opt.signDisplay = 'never';
|
|
|
- break;
|
|
|
- case 'sign-accounting':
|
|
|
- opt.currencySign = 'accounting';
|
|
|
- break;
|
|
|
- case 'sign-accounting-always':
|
|
|
- opt.currencySign = 'accounting';
|
|
|
- opt.signDisplay = 'always';
|
|
|
- break;
|
|
|
- case 'sign-accounting-except-zero':
|
|
|
- opt.currencySign = 'accounting';
|
|
|
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
- // @ts-ignore https://github.com/microsoft/TypeScript/issues/46712
|
|
|
- opt.signDisplay = 'exceptZero';
|
|
|
- break;
|
|
|
- }
|
|
|
- if (decimal === 'decimal-always') fail(decimal);
|
|
|
- if (roundingMode) fail(roundingMode);
|
|
|
- return opt;
|
|
|
- }
|
|
|
-
|
|
|
- function parseAffixToken(src, pos, onError) {
|
|
|
- const char = src[pos];
|
|
|
- switch (char) {
|
|
|
- case '%':
|
|
|
- return {
|
|
|
- char: '%',
|
|
|
- style: 'percent',
|
|
|
- width: 1
|
|
|
- };
|
|
|
- case '‰':
|
|
|
- return {
|
|
|
- char: '%',
|
|
|
- style: 'permille',
|
|
|
- width: 1
|
|
|
- };
|
|
|
- case '¤':
|
|
|
- {
|
|
|
- let width = 1;
|
|
|
- while (src[++pos] === '¤') ++width;
|
|
|
- switch (width) {
|
|
|
- case 1:
|
|
|
- return {
|
|
|
- char,
|
|
|
- currency: 'default',
|
|
|
- width
|
|
|
- };
|
|
|
- case 2:
|
|
|
- return {
|
|
|
- char,
|
|
|
- currency: 'iso-code',
|
|
|
- width
|
|
|
- };
|
|
|
- case 3:
|
|
|
- return {
|
|
|
- char,
|
|
|
- currency: 'full-name',
|
|
|
- width
|
|
|
- };
|
|
|
- case 5:
|
|
|
- return {
|
|
|
- char,
|
|
|
- currency: 'narrow',
|
|
|
- width
|
|
|
- };
|
|
|
- default:
|
|
|
- {
|
|
|
- const msg = `Invalid number (${width}) of ¤ chars in pattern`;
|
|
|
- onError(new PatternError('¤', msg));
|
|
|
- return null;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- case '*':
|
|
|
- {
|
|
|
- const pad = src[pos + 1];
|
|
|
- if (pad) return {
|
|
|
- char,
|
|
|
- pad,
|
|
|
- width: 2
|
|
|
- };
|
|
|
- break;
|
|
|
- }
|
|
|
- case '+':
|
|
|
- case '-':
|
|
|
- return {
|
|
|
- char,
|
|
|
- width: 1
|
|
|
- };
|
|
|
- case "'":
|
|
|
- {
|
|
|
- let str = src[++pos];
|
|
|
- let width = 2;
|
|
|
- if (str === "'") return {
|
|
|
- char,
|
|
|
- str,
|
|
|
- width
|
|
|
- };
|
|
|
- while (true) {
|
|
|
- const next = src[++pos];
|
|
|
- ++width;
|
|
|
- if (next === undefined) {
|
|
|
- const msg = `Unterminated quoted literal in pattern: ${str}`;
|
|
|
- onError(new PatternError("'", msg));
|
|
|
- return {
|
|
|
- char,
|
|
|
- str,
|
|
|
- width
|
|
|
- };
|
|
|
- } else if (next === "'") {
|
|
|
- if (src[++pos] !== "'") return {
|
|
|
- char,
|
|
|
- str,
|
|
|
- width
|
|
|
- };else ++width;
|
|
|
- }
|
|
|
- str += next;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- const isDigit = char => char >= '0' && char <= '9';
|
|
|
- function parseNumberToken(src, pos) {
|
|
|
- const char = src[pos];
|
|
|
- if (isDigit(char)) {
|
|
|
- let digits = char;
|
|
|
- while (true) {
|
|
|
- const next = src[++pos];
|
|
|
- if (isDigit(next)) digits += next;else return {
|
|
|
- char: '0',
|
|
|
- digits,
|
|
|
- width: digits.length
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
- switch (char) {
|
|
|
- case '#':
|
|
|
- {
|
|
|
- let width = 1;
|
|
|
- while (src[++pos] === '#') ++width;
|
|
|
- return {
|
|
|
- char,
|
|
|
- width
|
|
|
- };
|
|
|
- }
|
|
|
- case '@':
|
|
|
- {
|
|
|
- let min = 1;
|
|
|
- while (src[++pos] === '@') ++min;
|
|
|
- let width = min;
|
|
|
- pos -= 1;
|
|
|
- while (src[++pos] === '#') ++width;
|
|
|
- return {
|
|
|
- char,
|
|
|
- min,
|
|
|
- width
|
|
|
- };
|
|
|
- }
|
|
|
- case 'E':
|
|
|
- {
|
|
|
- const plus = src[pos + 1] === '+';
|
|
|
- if (plus) ++pos;
|
|
|
- let expDigits = 0;
|
|
|
- while (src[++pos] === '0') ++expDigits;
|
|
|
- const width = (plus ? 2 : 1) + expDigits;
|
|
|
- if (expDigits) return {
|
|
|
- char,
|
|
|
- expDigits,
|
|
|
- plus,
|
|
|
- width
|
|
|
- };else break;
|
|
|
- }
|
|
|
- case '.':
|
|
|
- case ',':
|
|
|
- return {
|
|
|
- char,
|
|
|
- width: 1
|
|
|
- };
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- function parseSubpattern(src, pos, onError) {
|
|
|
- let State;
|
|
|
- (function (State) {
|
|
|
- State[State["Prefix"] = 0] = "Prefix";
|
|
|
- State[State["Number"] = 1] = "Number";
|
|
|
- State[State["Suffix"] = 2] = "Suffix";
|
|
|
- })(State || (State = {}));
|
|
|
- const prefix = [];
|
|
|
- const number = [];
|
|
|
- const suffix = [];
|
|
|
- let state = State.Prefix;
|
|
|
- let str = '';
|
|
|
- while (pos < src.length) {
|
|
|
- const char = src[pos];
|
|
|
- if (char === ';') {
|
|
|
- pos += 1;
|
|
|
- break;
|
|
|
- }
|
|
|
- switch (state) {
|
|
|
- case State.Prefix:
|
|
|
- {
|
|
|
- const token = parseAffixToken(src, pos, onError);
|
|
|
- if (token) {
|
|
|
- if (str) {
|
|
|
- prefix.push({
|
|
|
- char: "'",
|
|
|
- str,
|
|
|
- width: str.length
|
|
|
- });
|
|
|
- str = '';
|
|
|
- }
|
|
|
- prefix.push(token);
|
|
|
- pos += token.width;
|
|
|
- } else {
|
|
|
- const token = parseNumberToken(src, pos);
|
|
|
- if (token) {
|
|
|
- if (str) {
|
|
|
- prefix.push({
|
|
|
- char: "'",
|
|
|
- str,
|
|
|
- width: str.length
|
|
|
- });
|
|
|
- str = '';
|
|
|
- }
|
|
|
- state = State.Number;
|
|
|
- number.push(token);
|
|
|
- pos += token.width;
|
|
|
- } else {
|
|
|
- str += char;
|
|
|
- pos += 1;
|
|
|
- }
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case State.Number:
|
|
|
- {
|
|
|
- const token = parseNumberToken(src, pos);
|
|
|
- if (token) {
|
|
|
- number.push(token);
|
|
|
- pos += token.width;
|
|
|
- } else {
|
|
|
- state = State.Suffix;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case State.Suffix:
|
|
|
- {
|
|
|
- const token = parseAffixToken(src, pos, onError);
|
|
|
- if (token) {
|
|
|
- if (str) {
|
|
|
- suffix.push({
|
|
|
- char: "'",
|
|
|
- str,
|
|
|
- width: str.length
|
|
|
- });
|
|
|
- str = '';
|
|
|
- }
|
|
|
- suffix.push(token);
|
|
|
- pos += token.width;
|
|
|
- } else {
|
|
|
- str += char;
|
|
|
- pos += 1;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (str) suffix.push({
|
|
|
- char: "'",
|
|
|
- str,
|
|
|
- width: str.length
|
|
|
- });
|
|
|
- return {
|
|
|
- pattern: {
|
|
|
- prefix,
|
|
|
- number,
|
|
|
- suffix
|
|
|
- },
|
|
|
- pos
|
|
|
- };
|
|
|
- }
|
|
|
- function parseTokens(src, onError) {
|
|
|
- const {
|
|
|
- pattern,
|
|
|
- pos
|
|
|
- } = parseSubpattern(src, 0, onError);
|
|
|
- if (pos < src.length) {
|
|
|
- const {
|
|
|
- pattern: negative
|
|
|
- } = parseSubpattern(src, pos, onError);
|
|
|
- return {
|
|
|
- tokens: pattern,
|
|
|
- negative
|
|
|
- };
|
|
|
- }
|
|
|
- return {
|
|
|
- tokens: pattern
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- function parseNumberAsSkeleton(tokens, onError) {
|
|
|
- const res = {};
|
|
|
- let hasGroups = false;
|
|
|
- let hasExponent = false;
|
|
|
- let intOptional = 0;
|
|
|
- let intDigits = '';
|
|
|
- let decimalPos = -1;
|
|
|
- let fracDigits = '';
|
|
|
- let fracOptional = 0;
|
|
|
- for (let pos = 0; pos < tokens.length; ++pos) {
|
|
|
- const token = tokens[pos];
|
|
|
- switch (token.char) {
|
|
|
- case '#':
|
|
|
- {
|
|
|
- if (decimalPos === -1) {
|
|
|
- if (intDigits) {
|
|
|
- const msg = 'Pattern has # after integer digits';
|
|
|
- onError(new PatternError('#', msg));
|
|
|
- }
|
|
|
- intOptional += token.width;
|
|
|
- } else {
|
|
|
- fracOptional += token.width;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case '0':
|
|
|
- {
|
|
|
- if (decimalPos === -1) {
|
|
|
- intDigits += token.digits;
|
|
|
- } else {
|
|
|
- if (fracOptional) {
|
|
|
- const msg = 'Pattern has digits after # in fraction';
|
|
|
- onError(new PatternError('0', msg));
|
|
|
- }
|
|
|
- fracDigits += token.digits;
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- case '@':
|
|
|
- {
|
|
|
- if (res.precision) onError(new MaskedValueError('precision', res.precision));
|
|
|
- res.precision = {
|
|
|
- style: 'precision-fraction',
|
|
|
- minSignificant: token.min,
|
|
|
- maxSignificant: token.width
|
|
|
- };
|
|
|
- break;
|
|
|
- }
|
|
|
- case ',':
|
|
|
- hasGroups = true;
|
|
|
- break;
|
|
|
- case '.':
|
|
|
- if (decimalPos === 1) {
|
|
|
- const msg = 'Pattern has more than one decimal separator';
|
|
|
- onError(new PatternError('.', msg));
|
|
|
- }
|
|
|
- decimalPos = pos;
|
|
|
- break;
|
|
|
- case 'E':
|
|
|
- {
|
|
|
- if (hasExponent) onError(new MaskedValueError('exponent', res.notation));
|
|
|
- if (hasGroups) {
|
|
|
- const msg = 'Exponential patterns may not contain grouping separators';
|
|
|
- onError(new PatternError('E', msg));
|
|
|
- }
|
|
|
- res.notation = {
|
|
|
- style: 'scientific'
|
|
|
- };
|
|
|
- if (token.expDigits > 1) res.notation.expDigits = token.expDigits;
|
|
|
- if (token.plus) res.notation.expSign = 'sign-always';
|
|
|
- hasExponent = true;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- // imprecise mapping due to paradigm differences
|
|
|
- if (hasGroups) res.group = 'group-auto';else if (intOptional + intDigits.length > 3) res.group = 'group-off';
|
|
|
- const increment = Number(`${intDigits || '0'}.${fracDigits}`);
|
|
|
- if (increment) res.precision = {
|
|
|
- style: 'precision-increment',
|
|
|
- increment
|
|
|
- };
|
|
|
- if (!hasExponent) {
|
|
|
- if (intDigits.length > 1) res.integerWidth = {
|
|
|
- min: intDigits.length
|
|
|
- };
|
|
|
- if (!res.precision && (fracDigits.length || fracOptional)) {
|
|
|
- res.precision = {
|
|
|
- style: 'precision-fraction',
|
|
|
- minFraction: fracDigits.length,
|
|
|
- maxFraction: fracDigits.length + fracOptional
|
|
|
- };
|
|
|
- }
|
|
|
- } else {
|
|
|
- if (!res.precision || increment) {
|
|
|
- res.integerWidth = intOptional ? {
|
|
|
- min: 1,
|
|
|
- max: intOptional + intDigits.length
|
|
|
- } : {
|
|
|
- min: Math.max(1, intDigits.length)
|
|
|
- };
|
|
|
- }
|
|
|
- if (res.precision) {
|
|
|
- if (!increment) res.integerWidth = {
|
|
|
- min: 1,
|
|
|
- max: 1
|
|
|
- };
|
|
|
- } else {
|
|
|
- const dc = intDigits.length + fracDigits.length;
|
|
|
- if (decimalPos === -1) {
|
|
|
- if (dc > 0) res.precision = {
|
|
|
- style: 'precision-fraction',
|
|
|
- maxSignificant: dc
|
|
|
- };
|
|
|
- } else {
|
|
|
- res.precision = {
|
|
|
- style: 'precision-fraction',
|
|
|
- maxSignificant: Math.max(1, dc) + fracOptional
|
|
|
- };
|
|
|
- if (dc > 1) res.precision.minSignificant = dc;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- function handleAffix(affixTokens, res, currency, onError, isPrefix) {
|
|
|
- let inFmt = false;
|
|
|
- let str = '';
|
|
|
- for (const token of affixTokens) {
|
|
|
- switch (token.char) {
|
|
|
- case '%':
|
|
|
- res.unit = {
|
|
|
- style: token.style
|
|
|
- };
|
|
|
- if (isPrefix) inFmt = true;else str = '';
|
|
|
- break;
|
|
|
- case '¤':
|
|
|
- if (!currency) {
|
|
|
- const msg = `The ¤ pattern requires a currency`;
|
|
|
- onError(new PatternError('¤', msg));
|
|
|
- break;
|
|
|
- }
|
|
|
- res.unit = {
|
|
|
- style: 'currency',
|
|
|
- currency
|
|
|
- };
|
|
|
- switch (token.currency) {
|
|
|
- case 'iso-code':
|
|
|
- res.unitWidth = 'unit-width-iso-code';
|
|
|
- break;
|
|
|
- case 'full-name':
|
|
|
- res.unitWidth = 'unit-width-full-name';
|
|
|
- break;
|
|
|
- case 'narrow':
|
|
|
- res.unitWidth = 'unit-width-narrow';
|
|
|
- break;
|
|
|
- }
|
|
|
- if (isPrefix) inFmt = true;else str = '';
|
|
|
- break;
|
|
|
- case '*':
|
|
|
- // TODO
|
|
|
- break;
|
|
|
- case '+':
|
|
|
- if (!inFmt) str += '+';
|
|
|
- break;
|
|
|
- case "'":
|
|
|
- if (!inFmt) str += token.str;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return str;
|
|
|
- }
|
|
|
- function getNegativeAffix(affixTokens, isPrefix) {
|
|
|
- let inFmt = false;
|
|
|
- let str = '';
|
|
|
- for (const token of affixTokens) {
|
|
|
- switch (token.char) {
|
|
|
- case '%':
|
|
|
- case '¤':
|
|
|
- if (isPrefix) inFmt = true;else str = '';
|
|
|
- break;
|
|
|
- case '-':
|
|
|
- if (!inFmt) str += '-';
|
|
|
- break;
|
|
|
- case "'":
|
|
|
- if (!inFmt) str += token.str;
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- return str;
|
|
|
- }
|
|
|
- /**
|
|
|
- * Parse an {@link
|
|
|
- * http://unicode.org/reports/tr35/tr35-numbers.html#Number_Format_Patterns |
|
|
|
- * ICU NumberFormatter pattern} string into a {@link Skeleton} structure.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param src - The pattern string
|
|
|
- * @param currency - If the pattern includes ¤ tokens, their skeleton
|
|
|
- * representation requires a three-letter currency code.
|
|
|
- * @param onError - Called when the parser encounters a syntax error. The
|
|
|
- * function will still return a {@link Skeleton}, but it will be incomplete
|
|
|
- * and/or inaccurate. If not defined, the error will be thrown instead.
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * Unlike the skeleton parser, the pattern parser is not able to return partial
|
|
|
- * results on error, and will instead throw. Output padding is not supported.
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { parseNumberPattern } from '@messageformat/number-skeleton'
|
|
|
- *
|
|
|
- * parseNumberPattern('#,##0.00 ¤', 'EUR', console.error)
|
|
|
- * // {
|
|
|
- * // group: 'group-auto',
|
|
|
- * // precision: {
|
|
|
- * // style: 'precision-fraction',
|
|
|
- * // minFraction: 2,
|
|
|
- * // maxFraction: 2
|
|
|
- * // },
|
|
|
- * // unit: { style: 'currency', currency: 'EUR' }
|
|
|
- * // }
|
|
|
- * ```
|
|
|
- */
|
|
|
- function parseNumberPattern(src, currency) {
|
|
|
- let onError = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : error => {
|
|
|
- throw error;
|
|
|
- };
|
|
|
- const {
|
|
|
- tokens,
|
|
|
- negative
|
|
|
- } = parseTokens(src, onError);
|
|
|
- const res = parseNumberAsSkeleton(tokens.number, onError);
|
|
|
- const prefix = handleAffix(tokens.prefix, res, currency, onError, true);
|
|
|
- const suffix = handleAffix(tokens.suffix, res, currency, onError, false);
|
|
|
- if (negative) {
|
|
|
- const negPrefix = getNegativeAffix(negative.prefix, true);
|
|
|
- const negSuffix = getNegativeAffix(negative.suffix, false);
|
|
|
- res.affix = {
|
|
|
- pos: [prefix, suffix],
|
|
|
- neg: [negPrefix, negSuffix]
|
|
|
- };
|
|
|
- res.sign = 'sign-never';
|
|
|
- } else if (prefix || suffix) {
|
|
|
- res.affix = {
|
|
|
- pos: [prefix, suffix]
|
|
|
- };
|
|
|
- }
|
|
|
- return res;
|
|
|
- }
|
|
|
-
|
|
|
- /** @internal */
|
|
|
- function isNumberingSystem(ns) {
|
|
|
- const systems = ['arab', 'arabext', 'bali', 'beng', 'deva', 'fullwide', 'gujr', 'guru', 'hanidec', 'khmr', 'knda', 'laoo', 'latn', 'limb', 'mlym', 'mong', 'mymr', 'orya', 'tamldec', 'telu', 'thai', 'tibt'];
|
|
|
- return systems.indexOf(ns) !== -1;
|
|
|
- }
|
|
|
-
|
|
|
- // FIXME: subtype is not checked
|
|
|
- /** @internal */
|
|
|
- function isUnit(unit) {
|
|
|
- const types = ['acceleration', 'angle', 'area', 'concentr', 'consumption', 'digital', 'duration', 'electric', 'energy', 'force', 'frequency', 'graphics', 'length', 'light', 'mass', 'power', 'pressure', 'speed', 'temperature', 'torque', 'volume'];
|
|
|
- const [type] = unit.split('-', 1);
|
|
|
- return types.indexOf(type) !== -1;
|
|
|
- }
|
|
|
-
|
|
|
- const maxOptions = {
|
|
|
- 'compact-short': 0,
|
|
|
- 'compact-long': 0,
|
|
|
- 'notation-simple': 0,
|
|
|
- scientific: 2,
|
|
|
- engineering: 2,
|
|
|
- percent: 0,
|
|
|
- permille: 0,
|
|
|
- 'base-unit': 0,
|
|
|
- currency: 1,
|
|
|
- 'measure-unit': 1,
|
|
|
- 'per-measure-unit': 1,
|
|
|
- 'unit-width-narrow': 0,
|
|
|
- 'unit-width-short': 0,
|
|
|
- 'unit-width-full-name': 0,
|
|
|
- 'unit-width-iso-code': 0,
|
|
|
- 'unit-width-hidden': 0,
|
|
|
- 'precision-integer': 0,
|
|
|
- 'precision-unlimited': 0,
|
|
|
- 'precision-currency-standard': 1,
|
|
|
- 'precision-currency-cash': 0,
|
|
|
- 'precision-increment': 1,
|
|
|
- 'rounding-mode-ceiling': 0,
|
|
|
- 'rounding-mode-floor': 0,
|
|
|
- 'rounding-mode-down': 0,
|
|
|
- 'rounding-mode-up': 0,
|
|
|
- 'rounding-mode-half-even': 0,
|
|
|
- 'rounding-mode-half-down': 0,
|
|
|
- 'rounding-mode-half-up': 0,
|
|
|
- 'rounding-mode-unnecessary': 0,
|
|
|
- 'integer-width': 1,
|
|
|
- scale: 1,
|
|
|
- 'group-off': 0,
|
|
|
- 'group-min2': 0,
|
|
|
- 'group-auto': 0,
|
|
|
- 'group-on-aligned': 0,
|
|
|
- 'group-thousands': 0,
|
|
|
- latin: 0,
|
|
|
- 'numbering-system': 1,
|
|
|
- 'sign-auto': 0,
|
|
|
- 'sign-always': 0,
|
|
|
- 'sign-never': 0,
|
|
|
- 'sign-accounting': 0,
|
|
|
- 'sign-accounting-always': 0,
|
|
|
- 'sign-except-zero': 0,
|
|
|
- 'sign-accounting-except-zero': 0,
|
|
|
- 'decimal-auto': 0,
|
|
|
- 'decimal-always': 0
|
|
|
- };
|
|
|
- const minOptions = {
|
|
|
- currency: 1,
|
|
|
- 'integer-width': 1,
|
|
|
- 'measure-unit': 1,
|
|
|
- 'numbering-system': 1,
|
|
|
- 'per-measure-unit': 1,
|
|
|
- 'precision-increment': 1,
|
|
|
- scale: 1
|
|
|
- };
|
|
|
- function hasMaxOption(stem) {
|
|
|
- return stem in maxOptions;
|
|
|
- }
|
|
|
- function hasMinOption(stem) {
|
|
|
- return stem in minOptions;
|
|
|
- }
|
|
|
- /** @internal */
|
|
|
- function validOptions(stem, options, onError) {
|
|
|
- if (hasMaxOption(stem)) {
|
|
|
- const maxOpt = maxOptions[stem];
|
|
|
- if (options.length > maxOpt) {
|
|
|
- if (maxOpt === 0) {
|
|
|
- for (const opt of options) onError(new BadOptionError(stem, opt));
|
|
|
- } else {
|
|
|
- onError(new TooManyOptionsError(stem, options, maxOpt));
|
|
|
- }
|
|
|
- return false;
|
|
|
- } else if (hasMinOption(stem) && options.length < minOptions[stem]) {
|
|
|
- onError(new MissingOptionError(stem));
|
|
|
- return false;
|
|
|
- }
|
|
|
- }
|
|
|
- return true;
|
|
|
- }
|
|
|
-
|
|
|
- function parseBlueprintDigits(src, style) {
|
|
|
- const re = style === 'fraction' ? /^\.(0*)(\+|#*)$/ : /^(@+)(\+|#*)$/;
|
|
|
- const match = src && src.match(re);
|
|
|
- if (match) {
|
|
|
- const min = match[1].length;
|
|
|
- switch (match[2].charAt(0)) {
|
|
|
- case '':
|
|
|
- return {
|
|
|
- min,
|
|
|
- max: min
|
|
|
- };
|
|
|
- case '+':
|
|
|
- return {
|
|
|
- min,
|
|
|
- max: null
|
|
|
- };
|
|
|
- case '#':
|
|
|
- {
|
|
|
- return {
|
|
|
- min,
|
|
|
- max: min + match[2].length
|
|
|
- };
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
- function parsePrecisionBlueprint(stem, options, onError) {
|
|
|
- const fd = parseBlueprintDigits(stem, 'fraction');
|
|
|
- if (fd) {
|
|
|
- if (options.length > 1) onError(new TooManyOptionsError(stem, options, 1));
|
|
|
- const res = {
|
|
|
- style: 'precision-fraction',
|
|
|
- source: stem,
|
|
|
- minFraction: fd.min
|
|
|
- };
|
|
|
- if (fd.max != null) res.maxFraction = fd.max;
|
|
|
- const option = options[0];
|
|
|
- const sd = parseBlueprintDigits(option, 'significant');
|
|
|
- if (sd) {
|
|
|
- res.source = `${stem}/${option}`;
|
|
|
- res.minSignificant = sd.min;
|
|
|
- if (sd.max != null) res.maxSignificant = sd.max;
|
|
|
- } else if (option) onError(new BadOptionError(stem, option));
|
|
|
- return res;
|
|
|
- }
|
|
|
- const sd = parseBlueprintDigits(stem, 'significant');
|
|
|
- if (sd) {
|
|
|
- for (const opt of options) onError(new BadOptionError(stem, opt));
|
|
|
- const res = {
|
|
|
- style: 'precision-fraction',
|
|
|
- source: stem,
|
|
|
- minSignificant: sd.min
|
|
|
- };
|
|
|
- if (sd.max != null) res.maxSignificant = sd.max;
|
|
|
- return res;
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
-
|
|
|
- /** @internal */
|
|
|
- class TokenParser {
|
|
|
- constructor(onError) {
|
|
|
- this.skeleton = {};
|
|
|
- this.onError = onError;
|
|
|
- }
|
|
|
- badOption(stem, opt) {
|
|
|
- this.onError(new BadOptionError(stem, opt));
|
|
|
- }
|
|
|
- assertEmpty(key) {
|
|
|
- const prev = this.skeleton[key];
|
|
|
- if (prev) this.onError(new MaskedValueError(key, prev));
|
|
|
- }
|
|
|
- parseToken(stem, options) {
|
|
|
- if (!validOptions(stem, options, this.onError)) return;
|
|
|
- const option = options[0];
|
|
|
- const res = this.skeleton;
|
|
|
- switch (stem) {
|
|
|
- // notation
|
|
|
- case 'compact-short':
|
|
|
- case 'compact-long':
|
|
|
- case 'notation-simple':
|
|
|
- this.assertEmpty('notation');
|
|
|
- res.notation = {
|
|
|
- style: stem
|
|
|
- };
|
|
|
- break;
|
|
|
- case 'scientific':
|
|
|
- case 'engineering':
|
|
|
- {
|
|
|
- let expDigits = null;
|
|
|
- let expSign = undefined;
|
|
|
- for (const opt of options) {
|
|
|
- switch (opt) {
|
|
|
- case 'sign-auto':
|
|
|
- case 'sign-always':
|
|
|
- case 'sign-never':
|
|
|
- case 'sign-accounting':
|
|
|
- case 'sign-accounting-always':
|
|
|
- case 'sign-except-zero':
|
|
|
- case 'sign-accounting-except-zero':
|
|
|
- expSign = opt;
|
|
|
- break;
|
|
|
- default:
|
|
|
- if (/^\+e+$/.test(opt)) expDigits = opt.length - 1;else {
|
|
|
- this.badOption(stem, opt);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- this.assertEmpty('notation');
|
|
|
- const source = options.join('/');
|
|
|
- res.notation = expDigits && expSign ? {
|
|
|
- style: stem,
|
|
|
- source,
|
|
|
- expDigits,
|
|
|
- expSign
|
|
|
- } : expDigits ? {
|
|
|
- style: stem,
|
|
|
- source,
|
|
|
- expDigits
|
|
|
- } : expSign ? {
|
|
|
- style: stem,
|
|
|
- source,
|
|
|
- expSign
|
|
|
- } : {
|
|
|
- style: stem,
|
|
|
- source
|
|
|
- };
|
|
|
- break;
|
|
|
- }
|
|
|
- // unit
|
|
|
- case 'percent':
|
|
|
- case 'permille':
|
|
|
- case 'base-unit':
|
|
|
- this.assertEmpty('unit');
|
|
|
- res.unit = {
|
|
|
- style: stem
|
|
|
- };
|
|
|
- break;
|
|
|
- case 'currency':
|
|
|
- if (/^[A-Z]{3}$/.test(option)) {
|
|
|
- this.assertEmpty('unit');
|
|
|
- res.unit = {
|
|
|
- style: stem,
|
|
|
- currency: option
|
|
|
- };
|
|
|
- } else this.badOption(stem, option);
|
|
|
- break;
|
|
|
- case 'measure-unit':
|
|
|
- {
|
|
|
- if (isUnit(option)) {
|
|
|
- this.assertEmpty('unit');
|
|
|
- res.unit = {
|
|
|
- style: stem,
|
|
|
- unit: option
|
|
|
- };
|
|
|
- } else this.badOption(stem, option);
|
|
|
- break;
|
|
|
- }
|
|
|
- // unitPer
|
|
|
- case 'per-measure-unit':
|
|
|
- {
|
|
|
- if (isUnit(option)) {
|
|
|
- this.assertEmpty('unitPer');
|
|
|
- res.unitPer = option;
|
|
|
- } else this.badOption(stem, option);
|
|
|
- break;
|
|
|
- }
|
|
|
- // unitWidth
|
|
|
- case 'unit-width-narrow':
|
|
|
- case 'unit-width-short':
|
|
|
- case 'unit-width-full-name':
|
|
|
- case 'unit-width-iso-code':
|
|
|
- case 'unit-width-hidden':
|
|
|
- this.assertEmpty('unitWidth');
|
|
|
- res.unitWidth = stem;
|
|
|
- break;
|
|
|
- // precision
|
|
|
- case 'precision-integer':
|
|
|
- case 'precision-unlimited':
|
|
|
- case 'precision-currency-cash':
|
|
|
- this.assertEmpty('precision');
|
|
|
- res.precision = {
|
|
|
- style: stem
|
|
|
- };
|
|
|
- break;
|
|
|
- case 'precision-currency-standard':
|
|
|
- this.assertEmpty('precision');
|
|
|
- if (option === 'w') {
|
|
|
- res.precision = {
|
|
|
- style: stem,
|
|
|
- trailingZero: 'stripIfInteger'
|
|
|
- };
|
|
|
- } else {
|
|
|
- res.precision = {
|
|
|
- style: stem
|
|
|
- };
|
|
|
- }
|
|
|
- break;
|
|
|
- case 'precision-increment':
|
|
|
- {
|
|
|
- const increment = Number(option);
|
|
|
- if (increment > 0) {
|
|
|
- this.assertEmpty('precision');
|
|
|
- res.precision = {
|
|
|
- style: stem,
|
|
|
- increment
|
|
|
- };
|
|
|
- } else this.badOption(stem, option);
|
|
|
- break;
|
|
|
- }
|
|
|
- // roundingMode
|
|
|
- case 'rounding-mode-ceiling':
|
|
|
- case 'rounding-mode-floor':
|
|
|
- case 'rounding-mode-down':
|
|
|
- case 'rounding-mode-up':
|
|
|
- case 'rounding-mode-half-even':
|
|
|
- case 'rounding-mode-half-odd':
|
|
|
- case 'rounding-mode-half-ceiling':
|
|
|
- case 'rounding-mode-half-floor':
|
|
|
- case 'rounding-mode-half-down':
|
|
|
- case 'rounding-mode-half-up':
|
|
|
- case 'rounding-mode-unnecessary':
|
|
|
- this.assertEmpty('roundingMode');
|
|
|
- res.roundingMode = stem;
|
|
|
- break;
|
|
|
- // integerWidth
|
|
|
- case 'integer-width':
|
|
|
- {
|
|
|
- if (/^\+0*$/.test(option)) {
|
|
|
- this.assertEmpty('integerWidth');
|
|
|
- res.integerWidth = {
|
|
|
- source: option,
|
|
|
- min: option.length - 1
|
|
|
- };
|
|
|
- } else {
|
|
|
- const m = option.match(/^#*(0*)$/);
|
|
|
- if (m) {
|
|
|
- this.assertEmpty('integerWidth');
|
|
|
- res.integerWidth = {
|
|
|
- source: option,
|
|
|
- min: m[1].length,
|
|
|
- max: m[0].length
|
|
|
- };
|
|
|
- } else this.badOption(stem, option);
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- // scale
|
|
|
- case 'scale':
|
|
|
- {
|
|
|
- const scale = Number(option);
|
|
|
- if (scale > 0) {
|
|
|
- this.assertEmpty('scale');
|
|
|
- res.scale = scale;
|
|
|
- } else this.badOption(stem, option);
|
|
|
- break;
|
|
|
- }
|
|
|
- // group
|
|
|
- case 'group-off':
|
|
|
- case 'group-min2':
|
|
|
- case 'group-auto':
|
|
|
- case 'group-on-aligned':
|
|
|
- case 'group-thousands':
|
|
|
- this.assertEmpty('group');
|
|
|
- res.group = stem;
|
|
|
- break;
|
|
|
- // numberingSystem
|
|
|
- case 'latin':
|
|
|
- this.assertEmpty('numberingSystem');
|
|
|
- res.numberingSystem = 'latn';
|
|
|
- break;
|
|
|
- case 'numbering-system':
|
|
|
- {
|
|
|
- if (isNumberingSystem(option)) {
|
|
|
- this.assertEmpty('numberingSystem');
|
|
|
- res.numberingSystem = option;
|
|
|
- } else this.badOption(stem, option);
|
|
|
- break;
|
|
|
- }
|
|
|
- // sign
|
|
|
- case 'sign-auto':
|
|
|
- case 'sign-always':
|
|
|
- case 'sign-never':
|
|
|
- case 'sign-accounting':
|
|
|
- case 'sign-accounting-always':
|
|
|
- case 'sign-except-zero':
|
|
|
- case 'sign-accounting-except-zero':
|
|
|
- this.assertEmpty('sign');
|
|
|
- res.sign = stem;
|
|
|
- break;
|
|
|
- // decimal
|
|
|
- case 'decimal-auto':
|
|
|
- case 'decimal-always':
|
|
|
- this.assertEmpty('decimal');
|
|
|
- res.decimal = stem;
|
|
|
- break;
|
|
|
- // precision blueprint
|
|
|
- default:
|
|
|
- {
|
|
|
- const precision = parsePrecisionBlueprint(stem, options, this.onError);
|
|
|
- if (precision) {
|
|
|
- this.assertEmpty('precision');
|
|
|
- res.precision = precision;
|
|
|
- } else {
|
|
|
- this.onError(new BadStemError(stem));
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Parse an {@link
|
|
|
- * https://github.com/unicode-org/icu/blob/master/docs/userguide/format_parse/numbers/skeletons.md
|
|
|
- * | ICU NumberFormatter skeleton} string into a {@link Skeleton} structure.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param src - The skeleton string
|
|
|
- * @param onError - Called when the parser encounters a syntax error. The
|
|
|
- * function will still return a {@link Skeleton}, but it may not contain
|
|
|
- * information for all tokens. If not defined, the error will be thrown
|
|
|
- * instead.
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { parseNumberSkeleton } from '@messageformat/number-skeleton'
|
|
|
- *
|
|
|
- * parseNumberSkeleton('compact-short currency/GBP', console.error)
|
|
|
- * // {
|
|
|
- * // notation: { style: 'compact-short' },
|
|
|
- * // unit: { style: 'currency', currency: 'GBP' }
|
|
|
- * // }
|
|
|
- * ```
|
|
|
- */
|
|
|
- function parseNumberSkeleton(src) {
|
|
|
- let onError = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : error => {
|
|
|
- throw error;
|
|
|
- };
|
|
|
- const tokens = [];
|
|
|
- for (const part of src.split(' ')) {
|
|
|
- if (part) {
|
|
|
- const options = part.split('/');
|
|
|
- const stem = options.shift() || '';
|
|
|
- tokens.push({
|
|
|
- stem,
|
|
|
- options
|
|
|
- });
|
|
|
- }
|
|
|
- }
|
|
|
- const parser = new TokenParser(onError);
|
|
|
- for (const {
|
|
|
- stem,
|
|
|
- options
|
|
|
- } of tokens) {
|
|
|
- parser.parseToken(stem, options);
|
|
|
- }
|
|
|
- return parser.skeleton;
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Returns a number formatter function for the given locales and number skeleton
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * Uses `Intl.NumberFormat` (ES2020) internally.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param locales - One or more valid BCP 47 language tags, e.g. `fr` or `en-CA`
|
|
|
- * @param skeleton - An ICU NumberFormatter pattern or `::`-prefixed skeleton
|
|
|
- * string, or a parsed `Skeleton` structure
|
|
|
- * @param currency - If `skeleton` is a pattern string that includes ¤ tokens,
|
|
|
- * their skeleton representation requires a three-letter currency code.
|
|
|
- * @param onError - If defined, will be called separately for each encountered
|
|
|
- * parsing error and unsupported feature.
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { getNumberFormatter } from '@messageformat/number-skeleton'
|
|
|
- *
|
|
|
- * let src = ':: currency/CAD unit-width-narrow'
|
|
|
- * let fmt = getNumberFormatter('en-CA', src, console.error)
|
|
|
- * fmt(42) // '$42.00'
|
|
|
- *
|
|
|
- * src = '::percent scale/100'
|
|
|
- * fmt = getNumberFormatter('en', src, console.error)
|
|
|
- * fmt(0.3) // '30%'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function getNumberFormatter(locales, skeleton, currency, onError) {
|
|
|
- if (typeof skeleton === 'string') {
|
|
|
- skeleton = skeleton.indexOf('::') === 0 ? parseNumberSkeleton(skeleton.slice(2), onError) : parseNumberPattern(skeleton, currency, onError);
|
|
|
- }
|
|
|
- const lc = getNumberFormatLocales(locales, skeleton);
|
|
|
- const opt = getNumberFormatOptions(skeleton, onError);
|
|
|
- const mod = getNumberFormatModifier(skeleton);
|
|
|
- const nf = new Intl.NumberFormat(lc, opt);
|
|
|
- if (skeleton.affix) {
|
|
|
- const [p0, p1] = skeleton.affix.pos;
|
|
|
- const [n0, n1] = skeleton.affix.neg || ['', ''];
|
|
|
- return value => {
|
|
|
- const n = nf.format(mod(value));
|
|
|
- return value < 0 ? `${n0}${n}${n1}` : `${p0}${n}${p1}`;
|
|
|
- };
|
|
|
- }
|
|
|
- return value => nf.format(mod(value));
|
|
|
- }
|
|
|
- /**
|
|
|
- * Returns a string of JavaScript source that evaluates to a number formatter
|
|
|
- * function with the same `(value: number) => string` signature as the function
|
|
|
- * returned by {@link getNumberFormatter}.
|
|
|
- *
|
|
|
- * @remarks
|
|
|
- * The returned function will memoize an `Intl.NumberFormat` instance.
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @param locales - One or more valid BCP 47 language tags, e.g. `fr` or `en-CA`
|
|
|
- * @param skeleton - An ICU NumberFormatter pattern or `::`-prefixed skeleton
|
|
|
- * string, or a parsed `Skeleton` structure
|
|
|
- * @param currency - If `skeleton` is a pattern string that includes ¤ tokens,
|
|
|
- * their skeleton representation requires a three-letter currency code.
|
|
|
- * @param onError - If defined, will be called separately for each encountered
|
|
|
- * parsing error and unsupported feature.
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * import { getNumberFormatterSource } from '@messageformat/number-skeleton'
|
|
|
- *
|
|
|
- * getNumberFormatterSource('en', '::percent', console.error)
|
|
|
- * // '(function() {\n' +
|
|
|
- * // ' var opt = {"style":"percent"};\n' +
|
|
|
- * // ' var nf = new Intl.NumberFormat(["en"], opt);\n' +
|
|
|
- * // ' var mod = function(n) { return n * 0.01; };\n' +
|
|
|
- * // ' return function(value) { return nf.format(mod(value)); }\n' +
|
|
|
- * // '})()'
|
|
|
- *
|
|
|
- * const src = getNumberFormatterSource('en-CA', ':: currency/CAD unit-width-narrow', console.error)
|
|
|
- * // '(function() {\n' +
|
|
|
- * // ' var opt = {"style":"currency","currency":"CAD","currencyDisplay":"narrowSymbol","unitDisplay":"narrow"};\n' +
|
|
|
- * // ' var nf = new Intl.NumberFormat(["en-CA"], opt);\n'
|
|
|
- * // ' return function(value) { return nf.format(value); }\n' +
|
|
|
- * // '})()'
|
|
|
- * const fmt = new Function(`return ${src}`)()
|
|
|
- * fmt(42) // '$42.00'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function getNumberFormatterSource(locales, skeleton, currency, onError) {
|
|
|
- if (typeof skeleton === 'string') {
|
|
|
- skeleton = skeleton.indexOf('::') === 0 ? parseNumberSkeleton(skeleton.slice(2), onError) : parseNumberPattern(skeleton, currency, onError);
|
|
|
- }
|
|
|
- const lc = getNumberFormatLocales(locales, skeleton);
|
|
|
- const opt = getNumberFormatOptions(skeleton, onError);
|
|
|
- const modSrc = getNumberFormatModifierSource(skeleton);
|
|
|
- const lines = [`(function() {`, `var opt = ${JSON.stringify(opt)};`, `var nf = new Intl.NumberFormat(${JSON.stringify(lc)}, opt);`];
|
|
|
- let res = 'nf.format(value)';
|
|
|
- if (modSrc) {
|
|
|
- lines.push(`var mod = ${modSrc};`);
|
|
|
- res = 'nf.format(mod(value))';
|
|
|
- }
|
|
|
- if (skeleton.affix) {
|
|
|
- const [p0, p1] = skeleton.affix.pos.map(s => JSON.stringify(s));
|
|
|
- if (skeleton.affix.neg) {
|
|
|
- const [n0, n1] = skeleton.affix.neg.map(s => JSON.stringify(s));
|
|
|
- res = `value < 0 ? ${n0} + ${res} + ${n1} : ${p0} + ${res} + ${p1}`;
|
|
|
- } else {
|
|
|
- res = `${p0} + ${res} + ${p1}`;
|
|
|
- }
|
|
|
- }
|
|
|
- lines.push(`return function(value) { return ${res}; }`);
|
|
|
- return lines.join('\n ') + '\n})()';
|
|
|
- }
|
|
|
-
|
|
|
- var commonjsGlobal = typeof globalThis !== 'undefined' ? globalThis : typeof window !== 'undefined' ? window : typeof global !== 'undefined' ? global : typeof self !== 'undefined' ? self : {};
|
|
|
-
|
|
|
- var parser = {};
|
|
|
-
|
|
|
- var lexer = {};
|
|
|
-
|
|
|
- var mooExports = {};
|
|
|
- var moo = {
|
|
|
- get exports(){ return mooExports; },
|
|
|
- set exports(v){ mooExports = v; },
|
|
|
- };
|
|
|
-
|
|
|
- (function (module) {
|
|
|
- (function (root, factory) {
|
|
|
- if (module.exports) {
|
|
|
- module.exports = factory();
|
|
|
- } else {
|
|
|
- root.moo = factory();
|
|
|
- }
|
|
|
- })(commonjsGlobal, function () {
|
|
|
-
|
|
|
- var hasOwnProperty = Object.prototype.hasOwnProperty;
|
|
|
- var toString = Object.prototype.toString;
|
|
|
- var hasSticky = typeof new RegExp().sticky === 'boolean';
|
|
|
-
|
|
|
- /***************************************************************************/
|
|
|
-
|
|
|
- function isRegExp(o) {
|
|
|
- return o && toString.call(o) === '[object RegExp]';
|
|
|
- }
|
|
|
- function isObject(o) {
|
|
|
- return o && typeof o === 'object' && !isRegExp(o) && !Array.isArray(o);
|
|
|
- }
|
|
|
- function reEscape(s) {
|
|
|
- return s.replace(/[-\/\\^$*+?.()|[\]{}]/g, '\\$&');
|
|
|
- }
|
|
|
- function reGroups(s) {
|
|
|
- var re = new RegExp('|' + s);
|
|
|
- return re.exec('').length - 1;
|
|
|
- }
|
|
|
- function reCapture(s) {
|
|
|
- return '(' + s + ')';
|
|
|
- }
|
|
|
- function reUnion(regexps) {
|
|
|
- if (!regexps.length) return '(?!)';
|
|
|
- var source = regexps.map(function (s) {
|
|
|
- return "(?:" + s + ")";
|
|
|
- }).join('|');
|
|
|
- return "(?:" + source + ")";
|
|
|
- }
|
|
|
- function regexpOrLiteral(obj) {
|
|
|
- if (typeof obj === 'string') {
|
|
|
- return '(?:' + reEscape(obj) + ')';
|
|
|
- } else if (isRegExp(obj)) {
|
|
|
- // TODO: consider /u support
|
|
|
- if (obj.ignoreCase) throw new Error('RegExp /i flag not allowed');
|
|
|
- if (obj.global) throw new Error('RegExp /g flag is implied');
|
|
|
- if (obj.sticky) throw new Error('RegExp /y flag is implied');
|
|
|
- if (obj.multiline) throw new Error('RegExp /m flag is implied');
|
|
|
- return obj.source;
|
|
|
- } else {
|
|
|
- throw new Error('Not a pattern: ' + obj);
|
|
|
- }
|
|
|
- }
|
|
|
- function pad(s, length) {
|
|
|
- if (s.length > length) {
|
|
|
- return s;
|
|
|
- }
|
|
|
- return Array(length - s.length + 1).join(" ") + s;
|
|
|
- }
|
|
|
- function lastNLines(string, numLines) {
|
|
|
- var position = string.length;
|
|
|
- var lineBreaks = 0;
|
|
|
- while (true) {
|
|
|
- var idx = string.lastIndexOf("\n", position - 1);
|
|
|
- if (idx === -1) {
|
|
|
- break;
|
|
|
- } else {
|
|
|
- lineBreaks++;
|
|
|
- }
|
|
|
- position = idx;
|
|
|
- if (lineBreaks === numLines) {
|
|
|
- break;
|
|
|
- }
|
|
|
- if (position === 0) {
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- var startPosition = lineBreaks < numLines ? 0 : position + 1;
|
|
|
- return string.substring(startPosition).split("\n");
|
|
|
- }
|
|
|
- function objectToRules(object) {
|
|
|
- var keys = Object.getOwnPropertyNames(object);
|
|
|
- var result = [];
|
|
|
- for (var i = 0; i < keys.length; i++) {
|
|
|
- var key = keys[i];
|
|
|
- var thing = object[key];
|
|
|
- var rules = [].concat(thing);
|
|
|
- if (key === 'include') {
|
|
|
- for (var j = 0; j < rules.length; j++) {
|
|
|
- result.push({
|
|
|
- include: rules[j]
|
|
|
- });
|
|
|
- }
|
|
|
- continue;
|
|
|
- }
|
|
|
- var match = [];
|
|
|
- rules.forEach(function (rule) {
|
|
|
- if (isObject(rule)) {
|
|
|
- if (match.length) result.push(ruleOptions(key, match));
|
|
|
- result.push(ruleOptions(key, rule));
|
|
|
- match = [];
|
|
|
- } else {
|
|
|
- match.push(rule);
|
|
|
- }
|
|
|
- });
|
|
|
- if (match.length) result.push(ruleOptions(key, match));
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
- function arrayToRules(array) {
|
|
|
- var result = [];
|
|
|
- for (var i = 0; i < array.length; i++) {
|
|
|
- var obj = array[i];
|
|
|
- if (obj.include) {
|
|
|
- var include = [].concat(obj.include);
|
|
|
- for (var j = 0; j < include.length; j++) {
|
|
|
- result.push({
|
|
|
- include: include[j]
|
|
|
- });
|
|
|
- }
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (!obj.type) {
|
|
|
- throw new Error('Rule has no type: ' + JSON.stringify(obj));
|
|
|
- }
|
|
|
- result.push(ruleOptions(obj.type, obj));
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
- function ruleOptions(type, obj) {
|
|
|
- if (!isObject(obj)) {
|
|
|
- obj = {
|
|
|
- match: obj
|
|
|
- };
|
|
|
- }
|
|
|
- if (obj.include) {
|
|
|
- throw new Error('Matching rules cannot also include states');
|
|
|
- }
|
|
|
-
|
|
|
- // nb. error and fallback imply lineBreaks
|
|
|
- var options = {
|
|
|
- defaultType: type,
|
|
|
- lineBreaks: !!obj.error || !!obj.fallback,
|
|
|
- pop: false,
|
|
|
- next: null,
|
|
|
- push: null,
|
|
|
- error: false,
|
|
|
- fallback: false,
|
|
|
- value: null,
|
|
|
- type: null,
|
|
|
- shouldThrow: false
|
|
|
- };
|
|
|
-
|
|
|
- // Avoid Object.assign(), so we support IE9+
|
|
|
- for (var key in obj) {
|
|
|
- if (hasOwnProperty.call(obj, key)) {
|
|
|
- options[key] = obj[key];
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // type transform cannot be a string
|
|
|
- if (typeof options.type === 'string' && type !== options.type) {
|
|
|
- throw new Error("Type transform cannot be a string (type '" + options.type + "' for token '" + type + "')");
|
|
|
- }
|
|
|
-
|
|
|
- // convert to array
|
|
|
- var match = options.match;
|
|
|
- options.match = Array.isArray(match) ? match : match ? [match] : [];
|
|
|
- options.match.sort(function (a, b) {
|
|
|
- return isRegExp(a) && isRegExp(b) ? 0 : isRegExp(b) ? -1 : isRegExp(a) ? +1 : b.length - a.length;
|
|
|
- });
|
|
|
- return options;
|
|
|
- }
|
|
|
- function toRules(spec) {
|
|
|
- return Array.isArray(spec) ? arrayToRules(spec) : objectToRules(spec);
|
|
|
- }
|
|
|
- var defaultErrorRule = ruleOptions('error', {
|
|
|
- lineBreaks: true,
|
|
|
- shouldThrow: true
|
|
|
- });
|
|
|
- function compileRules(rules, hasStates) {
|
|
|
- var errorRule = null;
|
|
|
- var fast = Object.create(null);
|
|
|
- var fastAllowed = true;
|
|
|
- var unicodeFlag = null;
|
|
|
- var groups = [];
|
|
|
- var parts = [];
|
|
|
-
|
|
|
- // If there is a fallback rule, then disable fast matching
|
|
|
- for (var i = 0; i < rules.length; i++) {
|
|
|
- if (rules[i].fallback) {
|
|
|
- fastAllowed = false;
|
|
|
- }
|
|
|
- }
|
|
|
- for (var i = 0; i < rules.length; i++) {
|
|
|
- var options = rules[i];
|
|
|
- if (options.include) {
|
|
|
- // all valid inclusions are removed by states() preprocessor
|
|
|
- throw new Error('Inheritance is not allowed in stateless lexers');
|
|
|
- }
|
|
|
- if (options.error || options.fallback) {
|
|
|
- // errorRule can only be set once
|
|
|
- if (errorRule) {
|
|
|
- if (!options.fallback === !errorRule.fallback) {
|
|
|
- throw new Error("Multiple " + (options.fallback ? "fallback" : "error") + " rules not allowed (for token '" + options.defaultType + "')");
|
|
|
- } else {
|
|
|
- throw new Error("fallback and error are mutually exclusive (for token '" + options.defaultType + "')");
|
|
|
- }
|
|
|
- }
|
|
|
- errorRule = options;
|
|
|
- }
|
|
|
- var match = options.match.slice();
|
|
|
- if (fastAllowed) {
|
|
|
- while (match.length && typeof match[0] === 'string' && match[0].length === 1) {
|
|
|
- var word = match.shift();
|
|
|
- fast[word.charCodeAt(0)] = options;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Warn about inappropriate state-switching options
|
|
|
- if (options.pop || options.push || options.next) {
|
|
|
- if (!hasStates) {
|
|
|
- throw new Error("State-switching options are not allowed in stateless lexers (for token '" + options.defaultType + "')");
|
|
|
- }
|
|
|
- if (options.fallback) {
|
|
|
- throw new Error("State-switching options are not allowed on fallback tokens (for token '" + options.defaultType + "')");
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // Only rules with a .match are included in the RegExp
|
|
|
- if (match.length === 0) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- fastAllowed = false;
|
|
|
- groups.push(options);
|
|
|
-
|
|
|
- // Check unicode flag is used everywhere or nowhere
|
|
|
- for (var j = 0; j < match.length; j++) {
|
|
|
- var obj = match[j];
|
|
|
- if (!isRegExp(obj)) {
|
|
|
- continue;
|
|
|
- }
|
|
|
- if (unicodeFlag === null) {
|
|
|
- unicodeFlag = obj.unicode;
|
|
|
- } else if (unicodeFlag !== obj.unicode && options.fallback === false) {
|
|
|
- throw new Error('If one rule is /u then all must be');
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- // convert to RegExp
|
|
|
- var pat = reUnion(match.map(regexpOrLiteral));
|
|
|
-
|
|
|
- // validate
|
|
|
- var regexp = new RegExp(pat);
|
|
|
- if (regexp.test("")) {
|
|
|
- throw new Error("RegExp matches empty string: " + regexp);
|
|
|
- }
|
|
|
- var groupCount = reGroups(pat);
|
|
|
- if (groupCount > 0) {
|
|
|
- throw new Error("RegExp has capture groups: " + regexp + "\nUse (?: … ) instead");
|
|
|
- }
|
|
|
-
|
|
|
- // try and detect rules matching newlines
|
|
|
- if (!options.lineBreaks && regexp.test('\n')) {
|
|
|
- throw new Error('Rule should declare lineBreaks: ' + regexp);
|
|
|
- }
|
|
|
-
|
|
|
- // store regex
|
|
|
- parts.push(reCapture(pat));
|
|
|
- }
|
|
|
-
|
|
|
- // If there's no fallback rule, use the sticky flag so we only look for
|
|
|
- // matches at the current index.
|
|
|
- //
|
|
|
- // If we don't support the sticky flag, then fake it using an irrefutable
|
|
|
- // match (i.e. an empty pattern).
|
|
|
- var fallbackRule = errorRule && errorRule.fallback;
|
|
|
- var flags = hasSticky && !fallbackRule ? 'ym' : 'gm';
|
|
|
- var suffix = hasSticky || fallbackRule ? '' : '|';
|
|
|
- if (unicodeFlag === true) flags += "u";
|
|
|
- var combined = new RegExp(reUnion(parts) + suffix, flags);
|
|
|
- return {
|
|
|
- regexp: combined,
|
|
|
- groups: groups,
|
|
|
- fast: fast,
|
|
|
- error: errorRule || defaultErrorRule
|
|
|
- };
|
|
|
- }
|
|
|
- function compile(rules) {
|
|
|
- var result = compileRules(toRules(rules));
|
|
|
- return new Lexer({
|
|
|
- start: result
|
|
|
- }, 'start');
|
|
|
- }
|
|
|
- function checkStateGroup(g, name, map) {
|
|
|
- var state = g && (g.push || g.next);
|
|
|
- if (state && !map[state]) {
|
|
|
- throw new Error("Missing state '" + state + "' (in token '" + g.defaultType + "' of state '" + name + "')");
|
|
|
- }
|
|
|
- if (g && g.pop && +g.pop !== 1) {
|
|
|
- throw new Error("pop must be 1 (in token '" + g.defaultType + "' of state '" + name + "')");
|
|
|
- }
|
|
|
- }
|
|
|
- function compileStates(states, start) {
|
|
|
- var all = states.$all ? toRules(states.$all) : [];
|
|
|
- delete states.$all;
|
|
|
- var keys = Object.getOwnPropertyNames(states);
|
|
|
- if (!start) start = keys[0];
|
|
|
- var ruleMap = Object.create(null);
|
|
|
- for (var i = 0; i < keys.length; i++) {
|
|
|
- var key = keys[i];
|
|
|
- ruleMap[key] = toRules(states[key]).concat(all);
|
|
|
- }
|
|
|
- for (var i = 0; i < keys.length; i++) {
|
|
|
- var key = keys[i];
|
|
|
- var rules = ruleMap[key];
|
|
|
- var included = Object.create(null);
|
|
|
- for (var j = 0; j < rules.length; j++) {
|
|
|
- var rule = rules[j];
|
|
|
- if (!rule.include) continue;
|
|
|
- var splice = [j, 1];
|
|
|
- if (rule.include !== key && !included[rule.include]) {
|
|
|
- included[rule.include] = true;
|
|
|
- var newRules = ruleMap[rule.include];
|
|
|
- if (!newRules) {
|
|
|
- throw new Error("Cannot include nonexistent state '" + rule.include + "' (in state '" + key + "')");
|
|
|
- }
|
|
|
- for (var k = 0; k < newRules.length; k++) {
|
|
|
- var newRule = newRules[k];
|
|
|
- if (rules.indexOf(newRule) !== -1) continue;
|
|
|
- splice.push(newRule);
|
|
|
- }
|
|
|
- }
|
|
|
- rules.splice.apply(rules, splice);
|
|
|
- j--;
|
|
|
- }
|
|
|
- }
|
|
|
- var map = Object.create(null);
|
|
|
- for (var i = 0; i < keys.length; i++) {
|
|
|
- var key = keys[i];
|
|
|
- map[key] = compileRules(ruleMap[key], true);
|
|
|
- }
|
|
|
- for (var i = 0; i < keys.length; i++) {
|
|
|
- var name = keys[i];
|
|
|
- var state = map[name];
|
|
|
- var groups = state.groups;
|
|
|
- for (var j = 0; j < groups.length; j++) {
|
|
|
- checkStateGroup(groups[j], name, map);
|
|
|
- }
|
|
|
- var fastKeys = Object.getOwnPropertyNames(state.fast);
|
|
|
- for (var j = 0; j < fastKeys.length; j++) {
|
|
|
- checkStateGroup(state.fast[fastKeys[j]], name, map);
|
|
|
- }
|
|
|
- }
|
|
|
- return new Lexer(map, start);
|
|
|
- }
|
|
|
- function keywordTransform(map) {
|
|
|
- // Use a JavaScript Map to map keywords to their corresponding token type
|
|
|
- // unless Map is unsupported, then fall back to using an Object:
|
|
|
- var isMap = typeof Map !== 'undefined';
|
|
|
- var reverseMap = isMap ? new Map() : Object.create(null);
|
|
|
- var types = Object.getOwnPropertyNames(map);
|
|
|
- for (var i = 0; i < types.length; i++) {
|
|
|
- var tokenType = types[i];
|
|
|
- var item = map[tokenType];
|
|
|
- var keywordList = Array.isArray(item) ? item : [item];
|
|
|
- keywordList.forEach(function (keyword) {
|
|
|
- if (typeof keyword !== 'string') {
|
|
|
- throw new Error("keyword must be string (in keyword '" + tokenType + "')");
|
|
|
- }
|
|
|
- if (isMap) {
|
|
|
- reverseMap.set(keyword, tokenType);
|
|
|
- } else {
|
|
|
- reverseMap[keyword] = tokenType;
|
|
|
- }
|
|
|
- });
|
|
|
- }
|
|
|
- return function (k) {
|
|
|
- return isMap ? reverseMap.get(k) : reverseMap[k];
|
|
|
- };
|
|
|
- }
|
|
|
-
|
|
|
- /***************************************************************************/
|
|
|
-
|
|
|
- var Lexer = function (states, state) {
|
|
|
- this.startState = state;
|
|
|
- this.states = states;
|
|
|
- this.buffer = '';
|
|
|
- this.stack = [];
|
|
|
- this.reset();
|
|
|
- };
|
|
|
- Lexer.prototype.reset = function (data, info) {
|
|
|
- this.buffer = data || '';
|
|
|
- this.index = 0;
|
|
|
- this.line = info ? info.line : 1;
|
|
|
- this.col = info ? info.col : 1;
|
|
|
- this.queuedToken = info ? info.queuedToken : null;
|
|
|
- this.queuedText = info ? info.queuedText : "";
|
|
|
- this.queuedThrow = info ? info.queuedThrow : null;
|
|
|
- this.setState(info ? info.state : this.startState);
|
|
|
- this.stack = info && info.stack ? info.stack.slice() : [];
|
|
|
- return this;
|
|
|
- };
|
|
|
- Lexer.prototype.save = function () {
|
|
|
- return {
|
|
|
- line: this.line,
|
|
|
- col: this.col,
|
|
|
- state: this.state,
|
|
|
- stack: this.stack.slice(),
|
|
|
- queuedToken: this.queuedToken,
|
|
|
- queuedText: this.queuedText,
|
|
|
- queuedThrow: this.queuedThrow
|
|
|
- };
|
|
|
- };
|
|
|
- Lexer.prototype.setState = function (state) {
|
|
|
- if (!state || this.state === state) return;
|
|
|
- this.state = state;
|
|
|
- var info = this.states[state];
|
|
|
- this.groups = info.groups;
|
|
|
- this.error = info.error;
|
|
|
- this.re = info.regexp;
|
|
|
- this.fast = info.fast;
|
|
|
- };
|
|
|
- Lexer.prototype.popState = function () {
|
|
|
- this.setState(this.stack.pop());
|
|
|
- };
|
|
|
- Lexer.prototype.pushState = function (state) {
|
|
|
- this.stack.push(this.state);
|
|
|
- this.setState(state);
|
|
|
- };
|
|
|
- var eat = hasSticky ? function (re, buffer) {
|
|
|
- // assume re is /y
|
|
|
- return re.exec(buffer);
|
|
|
- } : function (re, buffer) {
|
|
|
- // assume re is /g
|
|
|
- var match = re.exec(buffer);
|
|
|
- // will always match, since we used the |(?:) trick
|
|
|
- if (match[0].length === 0) {
|
|
|
- return null;
|
|
|
- }
|
|
|
- return match;
|
|
|
- };
|
|
|
- Lexer.prototype._getGroup = function (match) {
|
|
|
- var groupCount = this.groups.length;
|
|
|
- for (var i = 0; i < groupCount; i++) {
|
|
|
- if (match[i + 1] !== undefined) {
|
|
|
- return this.groups[i];
|
|
|
- }
|
|
|
- }
|
|
|
- throw new Error('Cannot find token type for matched text');
|
|
|
- };
|
|
|
- function tokenToString() {
|
|
|
- return this.value;
|
|
|
- }
|
|
|
- Lexer.prototype.next = function () {
|
|
|
- var index = this.index;
|
|
|
-
|
|
|
- // If a fallback token matched, we don't need to re-run the RegExp
|
|
|
- if (this.queuedGroup) {
|
|
|
- var token = this._token(this.queuedGroup, this.queuedText, index);
|
|
|
- this.queuedGroup = null;
|
|
|
- this.queuedText = "";
|
|
|
- return token;
|
|
|
- }
|
|
|
- var buffer = this.buffer;
|
|
|
- if (index === buffer.length) {
|
|
|
- return; // EOF
|
|
|
- }
|
|
|
-
|
|
|
- // Fast matching for single characters
|
|
|
- var group = this.fast[buffer.charCodeAt(index)];
|
|
|
- if (group) {
|
|
|
- return this._token(group, buffer.charAt(index), index);
|
|
|
- }
|
|
|
-
|
|
|
- // Execute RegExp
|
|
|
- var re = this.re;
|
|
|
- re.lastIndex = index;
|
|
|
- var match = eat(re, buffer);
|
|
|
-
|
|
|
- // Error tokens match the remaining buffer
|
|
|
- var error = this.error;
|
|
|
- if (match == null) {
|
|
|
- return this._token(error, buffer.slice(index, buffer.length), index);
|
|
|
- }
|
|
|
- var group = this._getGroup(match);
|
|
|
- var text = match[0];
|
|
|
- if (error.fallback && match.index !== index) {
|
|
|
- this.queuedGroup = group;
|
|
|
- this.queuedText = text;
|
|
|
-
|
|
|
- // Fallback tokens contain the unmatched portion of the buffer
|
|
|
- return this._token(error, buffer.slice(index, match.index), index);
|
|
|
- }
|
|
|
- return this._token(group, text, index);
|
|
|
- };
|
|
|
- Lexer.prototype._token = function (group, text, offset) {
|
|
|
- // count line breaks
|
|
|
- var lineBreaks = 0;
|
|
|
- if (group.lineBreaks) {
|
|
|
- var matchNL = /\n/g;
|
|
|
- var nl = 1;
|
|
|
- if (text === '\n') {
|
|
|
- lineBreaks = 1;
|
|
|
- } else {
|
|
|
- while (matchNL.exec(text)) {
|
|
|
- lineBreaks++;
|
|
|
- nl = matchNL.lastIndex;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- var token = {
|
|
|
- type: typeof group.type === 'function' && group.type(text) || group.defaultType,
|
|
|
- value: typeof group.value === 'function' ? group.value(text) : text,
|
|
|
- text: text,
|
|
|
- toString: tokenToString,
|
|
|
- offset: offset,
|
|
|
- lineBreaks: lineBreaks,
|
|
|
- line: this.line,
|
|
|
- col: this.col
|
|
|
- };
|
|
|
- // nb. adding more props to token object will make V8 sad!
|
|
|
-
|
|
|
- var size = text.length;
|
|
|
- this.index += size;
|
|
|
- this.line += lineBreaks;
|
|
|
- if (lineBreaks !== 0) {
|
|
|
- this.col = size - nl + 1;
|
|
|
- } else {
|
|
|
- this.col += size;
|
|
|
- }
|
|
|
-
|
|
|
- // throw, if no rule with {error: true}
|
|
|
- if (group.shouldThrow) {
|
|
|
- var err = new Error(this.formatError(token, "invalid syntax"));
|
|
|
- throw err;
|
|
|
- }
|
|
|
- if (group.pop) this.popState();else if (group.push) this.pushState(group.push);else if (group.next) this.setState(group.next);
|
|
|
- return token;
|
|
|
- };
|
|
|
- if (typeof Symbol !== 'undefined' && Symbol.iterator) {
|
|
|
- var LexerIterator = function (lexer) {
|
|
|
- this.lexer = lexer;
|
|
|
- };
|
|
|
- LexerIterator.prototype.next = function () {
|
|
|
- var token = this.lexer.next();
|
|
|
- return {
|
|
|
- value: token,
|
|
|
- done: !token
|
|
|
- };
|
|
|
- };
|
|
|
- LexerIterator.prototype[Symbol.iterator] = function () {
|
|
|
- return this;
|
|
|
- };
|
|
|
- Lexer.prototype[Symbol.iterator] = function () {
|
|
|
- return new LexerIterator(this);
|
|
|
- };
|
|
|
- }
|
|
|
- Lexer.prototype.formatError = function (token, message) {
|
|
|
- if (token == null) {
|
|
|
- // An undefined token indicates EOF
|
|
|
- var text = this.buffer.slice(this.index);
|
|
|
- var token = {
|
|
|
- text: text,
|
|
|
- offset: this.index,
|
|
|
- lineBreaks: text.indexOf('\n') === -1 ? 0 : 1,
|
|
|
- line: this.line,
|
|
|
- col: this.col
|
|
|
- };
|
|
|
- }
|
|
|
- var numLinesAround = 2;
|
|
|
- var firstDisplayedLine = Math.max(token.line - numLinesAround, 1);
|
|
|
- var lastDisplayedLine = token.line + numLinesAround;
|
|
|
- var lastLineDigits = String(lastDisplayedLine).length;
|
|
|
- var displayedLines = lastNLines(this.buffer, this.line - token.line + numLinesAround + 1).slice(0, 5);
|
|
|
- var errorLines = [];
|
|
|
- errorLines.push(message + " at line " + token.line + " col " + token.col + ":");
|
|
|
- errorLines.push("");
|
|
|
- for (var i = 0; i < displayedLines.length; i++) {
|
|
|
- var line = displayedLines[i];
|
|
|
- var lineNo = firstDisplayedLine + i;
|
|
|
- errorLines.push(pad(String(lineNo), lastLineDigits) + " " + line);
|
|
|
- if (lineNo === token.line) {
|
|
|
- errorLines.push(pad("", lastLineDigits + token.col + 1) + "^");
|
|
|
- }
|
|
|
- }
|
|
|
- return errorLines.join("\n");
|
|
|
- };
|
|
|
- Lexer.prototype.clone = function () {
|
|
|
- return new Lexer(this.states, this.state);
|
|
|
- };
|
|
|
- Lexer.prototype.has = function (tokenType) {
|
|
|
- return true;
|
|
|
- };
|
|
|
- return {
|
|
|
- compile: compile,
|
|
|
- states: compileStates,
|
|
|
- error: Object.freeze({
|
|
|
- error: true
|
|
|
- }),
|
|
|
- fallback: Object.freeze({
|
|
|
- fallback: true
|
|
|
- }),
|
|
|
- keywords: keywordTransform
|
|
|
- };
|
|
|
- });
|
|
|
- })(moo);
|
|
|
-
|
|
|
- (function (exports) {
|
|
|
-
|
|
|
- var __importDefault = commonjsGlobal && commonjsGlobal.__importDefault || function (mod) {
|
|
|
- return mod && mod.__esModule ? mod : {
|
|
|
- "default": mod
|
|
|
- };
|
|
|
- };
|
|
|
- Object.defineProperty(exports, "__esModule", {
|
|
|
- value: true
|
|
|
- });
|
|
|
- exports.lexer = exports.states = void 0;
|
|
|
- const moo_1 = __importDefault(mooExports);
|
|
|
- exports.states = {
|
|
|
- body: {
|
|
|
- doubleapos: {
|
|
|
- match: "''",
|
|
|
- value: () => "'"
|
|
|
- },
|
|
|
- quoted: {
|
|
|
- lineBreaks: true,
|
|
|
- match: /'[{}#](?:[^]*?[^'])?'(?!')/u,
|
|
|
- value: src => src.slice(1, -1).replace(/''/g, "'")
|
|
|
- },
|
|
|
- argument: {
|
|
|
- lineBreaks: true,
|
|
|
- match: /\{\s*[^\p{Pat_Syn}\p{Pat_WS}]+\s*/u,
|
|
|
- push: 'arg',
|
|
|
- value: src => src.substring(1).trim()
|
|
|
- },
|
|
|
- octothorpe: '#',
|
|
|
- end: {
|
|
|
- match: '}',
|
|
|
- pop: 1
|
|
|
- },
|
|
|
- content: {
|
|
|
- lineBreaks: true,
|
|
|
- match: /[^][^{}#']*/u
|
|
|
- }
|
|
|
- },
|
|
|
- arg: {
|
|
|
- select: {
|
|
|
- lineBreaks: true,
|
|
|
- match: /,\s*(?:plural|select|selectordinal)\s*,\s*/u,
|
|
|
- next: 'select',
|
|
|
- value: src => src.split(',')[1].trim()
|
|
|
- },
|
|
|
- 'func-args': {
|
|
|
- lineBreaks: true,
|
|
|
- match: /,\s*[^\p{Pat_Syn}\p{Pat_WS}]+\s*,/u,
|
|
|
- next: 'body',
|
|
|
- value: src => src.split(',')[1].trim()
|
|
|
- },
|
|
|
- 'func-simple': {
|
|
|
- lineBreaks: true,
|
|
|
- match: /,\s*[^\p{Pat_Syn}\p{Pat_WS}]+\s*/u,
|
|
|
- value: src => src.substring(1).trim()
|
|
|
- },
|
|
|
- end: {
|
|
|
- match: '}',
|
|
|
- pop: 1
|
|
|
- }
|
|
|
- },
|
|
|
- select: {
|
|
|
- offset: {
|
|
|
- lineBreaks: true,
|
|
|
- match: /\s*offset\s*:\s*\d+\s*/u,
|
|
|
- value: src => src.split(':')[1].trim()
|
|
|
- },
|
|
|
- case: {
|
|
|
- lineBreaks: true,
|
|
|
- match: /\s*(?:=\d+|[^\p{Pat_Syn}\p{Pat_WS}]+)\s*\{/u,
|
|
|
- push: 'body',
|
|
|
- value: src => src.substring(0, src.indexOf('{')).trim()
|
|
|
- },
|
|
|
- end: {
|
|
|
- match: /\s*\}/u,
|
|
|
- pop: 1
|
|
|
- }
|
|
|
- }
|
|
|
- };
|
|
|
- exports.lexer = moo_1.default.states(exports.states);
|
|
|
- })(lexer);
|
|
|
-
|
|
|
- /**
|
|
|
- * An AST parser for ICU MessageFormat strings
|
|
|
- *
|
|
|
- * @packageDocumentation
|
|
|
- * @example
|
|
|
- * ```
|
|
|
- * import { parse } from '@messageformat/parser
|
|
|
- *
|
|
|
- * parse('So {wow}.')
|
|
|
- * [ { type: 'content', value: 'So ' },
|
|
|
- * { type: 'argument', arg: 'wow' },
|
|
|
- * { type: 'content', value: '.' } ]
|
|
|
- *
|
|
|
- *
|
|
|
- * parse('Such { thing }. { count, selectordinal, one {First} two {Second}' +
|
|
|
- * ' few {Third} other {#th} } word.')
|
|
|
- * [ { type: 'content', value: 'Such ' },
|
|
|
- * { type: 'argument', arg: 'thing' },
|
|
|
- * { type: 'content', value: '. ' },
|
|
|
- * { type: 'selectordinal',
|
|
|
- * arg: 'count',
|
|
|
- * cases: [
|
|
|
- * { key: 'one', tokens: [ { type: 'content', value: 'First' } ] },
|
|
|
- * { key: 'two', tokens: [ { type: 'content', value: 'Second' } ] },
|
|
|
- * { key: 'few', tokens: [ { type: 'content', value: 'Third' } ] },
|
|
|
- * { key: 'other',
|
|
|
- * tokens: [ { type: 'octothorpe' }, { type: 'content', value: 'th' } ] }
|
|
|
- * ] },
|
|
|
- * { type: 'content', value: ' word.' } ]
|
|
|
- *
|
|
|
- *
|
|
|
- * parse('Many{type,select,plural{ numbers}selectordinal{ counting}' +
|
|
|
- * 'select{ choices}other{ some {type}}}.')
|
|
|
- * [ { type: 'content', value: 'Many' },
|
|
|
- * { type: 'select',
|
|
|
- * arg: 'type',
|
|
|
- * cases: [
|
|
|
- * { key: 'plural', tokens: [ { type: 'content', value: 'numbers' } ] },
|
|
|
- * { key: 'selectordinal', tokens: [ { type: 'content', value: 'counting' } ] },
|
|
|
- * { key: 'select', tokens: [ { type: 'content', value: 'choices' } ] },
|
|
|
- * { key: 'other',
|
|
|
- * tokens: [ { type: 'content', value: 'some ' }, { type: 'argument', arg: 'type' } ] }
|
|
|
- * ] },
|
|
|
- * { type: 'content', value: '.' } ]
|
|
|
- *
|
|
|
- *
|
|
|
- * parse('{Such compliance')
|
|
|
- * // ParseError: invalid syntax at line 1 col 7:
|
|
|
- * //
|
|
|
- * // {Such compliance
|
|
|
- * // ^
|
|
|
- *
|
|
|
- *
|
|
|
- * const msg = '{words, plural, zero{No words} one{One word} other{# words}}'
|
|
|
- * parse(msg)
|
|
|
- * [ { type: 'plural',
|
|
|
- * arg: 'words',
|
|
|
- * cases: [
|
|
|
- * { key: 'zero', tokens: [ { type: 'content', value: 'No words' } ] },
|
|
|
- * { key: 'one', tokens: [ { type: 'content', value: 'One word' } ] },
|
|
|
- * { key: 'other',
|
|
|
- * tokens: [ { type: 'octothorpe' }, { type: 'content', value: ' words' } ] }
|
|
|
- * ] } ]
|
|
|
- *
|
|
|
- *
|
|
|
- * parse(msg, { cardinal: [ 'one', 'other' ], ordinal: [ 'one', 'two', 'few', 'other' ] })
|
|
|
- * // ParseError: The plural case zero is not valid in this locale at line 1 col 17:
|
|
|
- * //
|
|
|
- * // {words, plural, zero{
|
|
|
- * // ^
|
|
|
- * ```
|
|
|
- */
|
|
|
- Object.defineProperty(parser, "__esModule", {
|
|
|
- value: true
|
|
|
- });
|
|
|
- var parse_1 = parser.parse = parser.ParseError = void 0;
|
|
|
- const lexer_js_1 = lexer;
|
|
|
- const getContext = lt => ({
|
|
|
- offset: lt.offset,
|
|
|
- line: lt.line,
|
|
|
- col: lt.col,
|
|
|
- text: lt.text,
|
|
|
- lineBreaks: lt.lineBreaks
|
|
|
- });
|
|
|
- const isSelectType = type => type === 'plural' || type === 'select' || type === 'selectordinal';
|
|
|
- function strictArgStyleParam(lt, param) {
|
|
|
- let value = '';
|
|
|
- let text = '';
|
|
|
- for (const p of param) {
|
|
|
- const pText = p.ctx.text;
|
|
|
- text += pText;
|
|
|
- switch (p.type) {
|
|
|
- case 'content':
|
|
|
- value += p.value;
|
|
|
- break;
|
|
|
- case 'argument':
|
|
|
- case 'function':
|
|
|
- case 'octothorpe':
|
|
|
- value += pText;
|
|
|
- break;
|
|
|
- default:
|
|
|
- throw new ParseError(lt, `Unsupported part in strict mode function arg style: ${pText}`);
|
|
|
- }
|
|
|
- }
|
|
|
- const c = {
|
|
|
- type: 'content',
|
|
|
- value: value.trim(),
|
|
|
- ctx: Object.assign({}, param[0].ctx, {
|
|
|
- text
|
|
|
- })
|
|
|
- };
|
|
|
- return [c];
|
|
|
- }
|
|
|
- const strictArgTypes = ['number', 'date', 'time', 'spellout', 'ordinal', 'duration'];
|
|
|
- const defaultPluralKeys = ['zero', 'one', 'two', 'few', 'many', 'other'];
|
|
|
- /**
|
|
|
- * Thrown by {@link parse} on error
|
|
|
- *
|
|
|
- * @public
|
|
|
- */
|
|
|
- class ParseError extends Error {
|
|
|
- /** @internal */
|
|
|
- constructor(lt, msg) {
|
|
|
- super(lexer_js_1.lexer.formatError(lt, msg));
|
|
|
- }
|
|
|
- }
|
|
|
- parser.ParseError = ParseError;
|
|
|
- class Parser {
|
|
|
- constructor(src, opt) {
|
|
|
- var _a, _b, _c, _d;
|
|
|
- this.lexer = lexer_js_1.lexer.reset(src);
|
|
|
- this.cardinalKeys = (_a = opt === null || opt === void 0 ? void 0 : opt.cardinal) !== null && _a !== void 0 ? _a : defaultPluralKeys;
|
|
|
- this.ordinalKeys = (_b = opt === null || opt === void 0 ? void 0 : opt.ordinal) !== null && _b !== void 0 ? _b : defaultPluralKeys;
|
|
|
- this.strict = (_c = opt === null || opt === void 0 ? void 0 : opt.strict) !== null && _c !== void 0 ? _c : false;
|
|
|
- this.strictPluralKeys = (_d = opt === null || opt === void 0 ? void 0 : opt.strictPluralKeys) !== null && _d !== void 0 ? _d : true;
|
|
|
- }
|
|
|
- parse() {
|
|
|
- return this.parseBody(false, true);
|
|
|
- }
|
|
|
- checkSelectKey(lt, type, key) {
|
|
|
- if (key[0] === '=') {
|
|
|
- if (type === 'select') throw new ParseError(lt, `The case ${key} is not valid with select`);
|
|
|
- } else if (type !== 'select') {
|
|
|
- const keys = type === 'plural' ? this.cardinalKeys : this.ordinalKeys;
|
|
|
- if (this.strictPluralKeys && keys.length > 0 && !keys.includes(key)) {
|
|
|
- const msg = `The ${type} case ${key} is not valid in this locale`;
|
|
|
- throw new ParseError(lt, msg);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- parseSelect(_ref, inPlural, ctx, type) {
|
|
|
- let {
|
|
|
- value: arg
|
|
|
- } = _ref;
|
|
|
- const sel = {
|
|
|
- type,
|
|
|
- arg,
|
|
|
- cases: [],
|
|
|
- ctx
|
|
|
- };
|
|
|
- if (type === 'plural' || type === 'selectordinal') inPlural = true;else if (this.strict) inPlural = false;
|
|
|
- for (const lt of this.lexer) {
|
|
|
- switch (lt.type) {
|
|
|
- case 'offset':
|
|
|
- if (type === 'select') throw new ParseError(lt, 'Unexpected plural offset for select');
|
|
|
- if (sel.cases.length > 0) throw new ParseError(lt, 'Plural offset must be set before cases');
|
|
|
- sel.pluralOffset = Number(lt.value);
|
|
|
- ctx.text += lt.text;
|
|
|
- ctx.lineBreaks += lt.lineBreaks;
|
|
|
- break;
|
|
|
- case 'case':
|
|
|
- {
|
|
|
- this.checkSelectKey(lt, type, lt.value);
|
|
|
- sel.cases.push({
|
|
|
- key: lt.value,
|
|
|
- tokens: this.parseBody(inPlural),
|
|
|
- ctx: getContext(lt)
|
|
|
- });
|
|
|
- break;
|
|
|
- }
|
|
|
- case 'end':
|
|
|
- return sel;
|
|
|
- /* istanbul ignore next: never happens */
|
|
|
- default:
|
|
|
- throw new ParseError(lt, `Unexpected lexer token: ${lt.type}`);
|
|
|
- }
|
|
|
- }
|
|
|
- throw new ParseError(null, 'Unexpected message end');
|
|
|
- }
|
|
|
- parseArgToken(lt, inPlural) {
|
|
|
- const ctx = getContext(lt);
|
|
|
- const argType = this.lexer.next();
|
|
|
- if (!argType) throw new ParseError(null, 'Unexpected message end');
|
|
|
- ctx.text += argType.text;
|
|
|
- ctx.lineBreaks += argType.lineBreaks;
|
|
|
- if (this.strict && (argType.type === 'func-simple' || argType.type === 'func-args') && !strictArgTypes.includes(argType.value)) {
|
|
|
- const msg = `Invalid strict mode function arg type: ${argType.value}`;
|
|
|
- throw new ParseError(lt, msg);
|
|
|
- }
|
|
|
- switch (argType.type) {
|
|
|
- case 'end':
|
|
|
- return {
|
|
|
- type: 'argument',
|
|
|
- arg: lt.value,
|
|
|
- ctx
|
|
|
- };
|
|
|
- case 'func-simple':
|
|
|
- {
|
|
|
- const end = this.lexer.next();
|
|
|
- if (!end) throw new ParseError(null, 'Unexpected message end');
|
|
|
- /* istanbul ignore if: never happens */
|
|
|
- if (end.type !== 'end') throw new ParseError(end, `Unexpected lexer token: ${end.type}`);
|
|
|
- ctx.text += end.text;
|
|
|
- if (isSelectType(argType.value.toLowerCase())) throw new ParseError(argType, `Invalid type identifier: ${argType.value}`);
|
|
|
- return {
|
|
|
- type: 'function',
|
|
|
- arg: lt.value,
|
|
|
- key: argType.value,
|
|
|
- ctx
|
|
|
- };
|
|
|
- }
|
|
|
- case 'func-args':
|
|
|
- {
|
|
|
- if (isSelectType(argType.value.toLowerCase())) {
|
|
|
- const msg = `Invalid type identifier: ${argType.value}`;
|
|
|
- throw new ParseError(argType, msg);
|
|
|
- }
|
|
|
- let param = this.parseBody(this.strict ? false : inPlural);
|
|
|
- if (this.strict && param.length > 0) param = strictArgStyleParam(lt, param);
|
|
|
- return {
|
|
|
- type: 'function',
|
|
|
- arg: lt.value,
|
|
|
- key: argType.value,
|
|
|
- param,
|
|
|
- ctx
|
|
|
- };
|
|
|
- }
|
|
|
- case 'select':
|
|
|
- /* istanbul ignore else: never happens */
|
|
|
- if (isSelectType(argType.value)) return this.parseSelect(lt, inPlural, ctx, argType.value);else throw new ParseError(argType, `Unexpected select type ${argType.value}`);
|
|
|
- /* istanbul ignore next: never happens */
|
|
|
- default:
|
|
|
- throw new ParseError(argType, `Unexpected lexer token: ${argType.type}`);
|
|
|
- }
|
|
|
- }
|
|
|
- parseBody(inPlural, atRoot) {
|
|
|
- const tokens = [];
|
|
|
- let content = null;
|
|
|
- for (const lt of this.lexer) {
|
|
|
- if (lt.type === 'argument') {
|
|
|
- if (content) content = null;
|
|
|
- tokens.push(this.parseArgToken(lt, inPlural));
|
|
|
- } else if (lt.type === 'octothorpe' && inPlural) {
|
|
|
- if (content) content = null;
|
|
|
- tokens.push({
|
|
|
- type: 'octothorpe',
|
|
|
- ctx: getContext(lt)
|
|
|
- });
|
|
|
- } else if (lt.type === 'end' && !atRoot) {
|
|
|
- return tokens;
|
|
|
- } else {
|
|
|
- let value = lt.value;
|
|
|
- if (!inPlural && lt.type === 'quoted' && value[0] === '#') {
|
|
|
- if (value.includes('{')) {
|
|
|
- const errMsg = `Unsupported escape pattern: ${value}`;
|
|
|
- throw new ParseError(lt, errMsg);
|
|
|
- }
|
|
|
- value = lt.text;
|
|
|
- }
|
|
|
- if (content) {
|
|
|
- content.value += value;
|
|
|
- content.ctx.text += lt.text;
|
|
|
- content.ctx.lineBreaks += lt.lineBreaks;
|
|
|
- } else {
|
|
|
- content = {
|
|
|
- type: 'content',
|
|
|
- value,
|
|
|
- ctx: getContext(lt)
|
|
|
- };
|
|
|
- tokens.push(content);
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- if (atRoot) return tokens;
|
|
|
- throw new ParseError(null, 'Unexpected message end');
|
|
|
- }
|
|
|
- }
|
|
|
- /**
|
|
|
- * Parse an input string into an array of tokens
|
|
|
- *
|
|
|
- * @public
|
|
|
- * @remarks
|
|
|
- * The parser only supports the default `DOUBLE_OPTIONAL`
|
|
|
- * {@link http://www.icu-project.org/apiref/icu4c/messagepattern_8h.html#af6e0757e0eb81c980b01ee5d68a9978b | apostrophe mode}.
|
|
|
- */
|
|
|
- function parse(src) {
|
|
|
- let options = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {};
|
|
|
- const parser = new Parser(src, options);
|
|
|
- return parser.parse();
|
|
|
- }
|
|
|
- parse_1 = parser.parse = parse;
|
|
|
-
|
|
|
- /**
|
|
|
- * A set of utility functions that are called by the compiled Javascript
|
|
|
- * functions, these are included locally in the output of {@link MessageFormat.compile compile()}.
|
|
|
- */
|
|
|
- /** @private */
|
|
|
- function _nf$1(lc) {
|
|
|
- // eslint-disable-next-line @typescript-eslint/ban-ts-comment
|
|
|
- // @ts-ignore
|
|
|
- return _nf$1[lc] || (_nf$1[lc] = new Intl.NumberFormat(lc));
|
|
|
- }
|
|
|
- /**
|
|
|
- * Utility function for `#` in plural rules
|
|
|
- *
|
|
|
- * @param lc The current locale
|
|
|
- * @param value The value to operate on
|
|
|
- * @param offset An offset, set by the surrounding context
|
|
|
- * @returns The result of applying the offset to the input value
|
|
|
- */
|
|
|
- function number(lc, value, offset) {
|
|
|
- return _nf$1(lc).format(value - offset);
|
|
|
- }
|
|
|
- /**
|
|
|
- * Strict utility function for `#` in plural rules
|
|
|
- *
|
|
|
- * Will throw an Error if `value` or `offset` are non-numeric.
|
|
|
- *
|
|
|
- * @param lc The current locale
|
|
|
- * @param value The value to operate on
|
|
|
- * @param offset An offset, set by the surrounding context
|
|
|
- * @param name The name of the argument, used for error reporting
|
|
|
- * @returns The result of applying the offset to the input value
|
|
|
- */
|
|
|
- function strictNumber(lc, value, offset, name) {
|
|
|
- var n = value - offset;
|
|
|
- if (isNaN(n)) throw new Error('`' + name + '` or its offset is not a number');
|
|
|
- return _nf$1(lc).format(n);
|
|
|
- }
|
|
|
- /**
|
|
|
- * Utility function for `{N, plural|selectordinal, ...}`
|
|
|
- *
|
|
|
- * @param value The key to use to find a pluralization rule
|
|
|
- * @param offset An offset to apply to `value`
|
|
|
- * @param lcfunc A locale function from `pluralFuncs`
|
|
|
- * @param data The object from which results are looked up
|
|
|
- * @param isOrdinal If true, use ordinal rather than cardinal rules
|
|
|
- * @returns The result of the pluralization
|
|
|
- */
|
|
|
- function plural(value, offset, lcfunc, data, isOrdinal) {
|
|
|
- if ({}.hasOwnProperty.call(data, value)) return data[value];
|
|
|
- if (offset) value -= offset;
|
|
|
- var key = lcfunc(value, isOrdinal);
|
|
|
- return key in data ? data[key] : data.other;
|
|
|
- }
|
|
|
- /**
|
|
|
- * Utility function for `{N, select, ...}`
|
|
|
- *
|
|
|
- * @param value The key to use to find a selection
|
|
|
- * @param data The object from which results are looked up
|
|
|
- * @returns The result of the select statement
|
|
|
- */
|
|
|
- function select(value, data) {
|
|
|
- return {}.hasOwnProperty.call(data, value) ? data[value] : data.other;
|
|
|
- }
|
|
|
- /**
|
|
|
- * Checks that all required arguments are set to defined values
|
|
|
- *
|
|
|
- * Throws on failure; otherwise returns undefined
|
|
|
- *
|
|
|
- * @param keys The required keys
|
|
|
- * @param data The data object being checked
|
|
|
- */
|
|
|
- function reqArgs(keys, data) {
|
|
|
- for (var i = 0; i < keys.length; ++i) if (!data || data[keys[i]] === undefined) throw new Error("Message requires argument '".concat(keys[i], "'"));
|
|
|
- }
|
|
|
-
|
|
|
- var Runtime = /*#__PURE__*/Object.freeze({
|
|
|
- __proto__: null,
|
|
|
- _nf: _nf$1,
|
|
|
- number: number,
|
|
|
- plural: plural,
|
|
|
- reqArgs: reqArgs,
|
|
|
- select: select,
|
|
|
- strictNumber: strictNumber
|
|
|
- });
|
|
|
-
|
|
|
- /**
|
|
|
- * Represent a date as a short/default/long/full string
|
|
|
- *
|
|
|
- * @param value Either a Unix epoch time in milliseconds, or a string value
|
|
|
- * representing a date. Parsed with `new Date(value)`
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * var mf = new MessageFormat(['en', 'fi']);
|
|
|
- *
|
|
|
- * mf.compile('Today is {T, date}')({ T: Date.now() })
|
|
|
- * // 'Today is Feb 21, 2016'
|
|
|
- *
|
|
|
- * mf.compile('Tänään on {T, date}', 'fi')({ T: Date.now() })
|
|
|
- * // 'Tänään on 21. helmikuuta 2016'
|
|
|
- *
|
|
|
- * mf.compile('Unix time started on {T, date, full}')({ T: 0 })
|
|
|
- * // 'Unix time started on Thursday, January 1, 1970'
|
|
|
- *
|
|
|
- * var cf = mf.compile('{sys} became operational on {d0, date, short}');
|
|
|
- * cf({ sys: 'HAL 9000', d0: '12 January 1999' })
|
|
|
- * // 'HAL 9000 became operational on 1/12/1999'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function date(value, lc, size) {
|
|
|
- var o = {
|
|
|
- day: 'numeric',
|
|
|
- month: 'short',
|
|
|
- year: 'numeric'
|
|
|
- };
|
|
|
- /* eslint-disable no-fallthrough */
|
|
|
- switch (size) {
|
|
|
- case 'full':
|
|
|
- o.weekday = 'long';
|
|
|
- case 'long':
|
|
|
- o.month = 'long';
|
|
|
- break;
|
|
|
- case 'short':
|
|
|
- o.month = 'numeric';
|
|
|
- }
|
|
|
- return new Date(value).toLocaleDateString(lc, o);
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Represent a duration in seconds as a string
|
|
|
- *
|
|
|
- * @param value A finite number, or its string representation
|
|
|
- * @return Includes one or two `:` separators, and matches the pattern
|
|
|
- * `hhhh:mm:ss`, possibly with a leading `-` for negative values and a
|
|
|
- * trailing `.sss` part for non-integer input
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * var mf = new MessageFormat();
|
|
|
- *
|
|
|
- * mf.compile('It has been {D, duration}')({ D: 123 })
|
|
|
- * // 'It has been 2:03'
|
|
|
- *
|
|
|
- * mf.compile('Countdown: {D, duration}')({ D: -151200.42 })
|
|
|
- * // 'Countdown: -42:00:00.420'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function duration(value) {
|
|
|
- if (typeof value !== 'number') value = Number(value);
|
|
|
- if (!isFinite(value)) return String(value);
|
|
|
- var sign = '';
|
|
|
- if (value < 0) {
|
|
|
- sign = '-';
|
|
|
- value = Math.abs(value);
|
|
|
- } else {
|
|
|
- value = Number(value);
|
|
|
- }
|
|
|
- var sec = value % 60;
|
|
|
- var parts = [Math.round(sec) === sec ? sec : sec.toFixed(3)];
|
|
|
- if (value < 60) {
|
|
|
- parts.unshift(0); // at least one : is required
|
|
|
- } else {
|
|
|
- value = Math.round((value - Number(parts[0])) / 60);
|
|
|
- parts.unshift(value % 60); // minutes
|
|
|
- if (value >= 60) {
|
|
|
- value = Math.round((value - Number(parts[0])) / 60);
|
|
|
- parts.unshift(value); // hours
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- var first = parts.shift();
|
|
|
- return sign + first + ':' + parts.map(function (n) {
|
|
|
- return Number(n) < 10 ? '0' + String(n) : String(n);
|
|
|
- }).join(':');
|
|
|
- }
|
|
|
-
|
|
|
- /**
|
|
|
- * Represent a number as an integer, percent or currency value
|
|
|
- *
|
|
|
- * Available in MessageFormat strings as `{VAR, number, integer|percent|currency}`.
|
|
|
- * Internally, calls Intl.NumberFormat with appropriate parameters. `currency` will
|
|
|
- * default to USD; to change, set `MessageFormat#currency` to the appropriate
|
|
|
- * three-letter currency code, or use the `currency:EUR` form of the argument.
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * var mf = new MessageFormat('en', { currency: 'EUR'});
|
|
|
- *
|
|
|
- * mf.compile('{N} is almost {N, number, integer}')({ N: 3.14 })
|
|
|
- * // '3.14 is almost 3'
|
|
|
- *
|
|
|
- * mf.compile('{P, number, percent} complete')({ P: 0.99 })
|
|
|
- * // '99% complete'
|
|
|
- *
|
|
|
- * mf.compile('The total is {V, number, currency}.')({ V: 5.5 })
|
|
|
- * // 'The total is €5.50.'
|
|
|
- *
|
|
|
- * mf.compile('The total is {V, number, currency:GBP}.')({ V: 5.5 })
|
|
|
- * // 'The total is £5.50.'
|
|
|
- * ```
|
|
|
- */
|
|
|
- var _nf = {};
|
|
|
- function nf(lc, opt) {
|
|
|
- var key = String(lc) + JSON.stringify(opt);
|
|
|
- if (!_nf[key]) _nf[key] = new Intl.NumberFormat(lc, opt);
|
|
|
- return _nf[key];
|
|
|
- }
|
|
|
- function numberFmt(value, lc, arg, defaultCurrency) {
|
|
|
- var _a = arg && arg.split(':') || [],
|
|
|
- type = _a[0],
|
|
|
- currency = _a[1];
|
|
|
- var opt = {
|
|
|
- integer: {
|
|
|
- maximumFractionDigits: 0
|
|
|
- },
|
|
|
- percent: {
|
|
|
- style: 'percent'
|
|
|
- },
|
|
|
- currency: {
|
|
|
- style: 'currency',
|
|
|
- currency: currency && currency.trim() || defaultCurrency,
|
|
|
- minimumFractionDigits: 2,
|
|
|
- maximumFractionDigits: 2
|
|
|
- }
|
|
|
- };
|
|
|
- return nf(lc, opt[type] || {}).format(value);
|
|
|
- }
|
|
|
- var numberCurrency = function (value, lc, arg) {
|
|
|
- return nf(lc, {
|
|
|
- style: 'currency',
|
|
|
- currency: arg,
|
|
|
- minimumFractionDigits: 2,
|
|
|
- maximumFractionDigits: 2
|
|
|
- }).format(value);
|
|
|
- };
|
|
|
- var numberInteger = function (value, lc) {
|
|
|
- return nf(lc, {
|
|
|
- maximumFractionDigits: 0
|
|
|
- }).format(value);
|
|
|
- };
|
|
|
- var numberPercent = function (value, lc) {
|
|
|
- return nf(lc, {
|
|
|
- style: 'percent'
|
|
|
- }).format(value);
|
|
|
- };
|
|
|
-
|
|
|
- /**
|
|
|
- * Represent a time as a short/default/long string
|
|
|
- *
|
|
|
- * @param value Either a Unix epoch time in milliseconds, or a string value
|
|
|
- * representing a date. Parsed with `new Date(value)`
|
|
|
- *
|
|
|
- * @example
|
|
|
- * ```js
|
|
|
- * var mf = new MessageFormat(['en', 'fi']);
|
|
|
- *
|
|
|
- * mf.compile('The time is now {T, time}')({ T: Date.now() })
|
|
|
- * // 'The time is now 11:26:35 PM'
|
|
|
- *
|
|
|
- * mf.compile('Kello on nyt {T, time}', 'fi')({ T: Date.now() })
|
|
|
- * // 'Kello on nyt 23.26.35'
|
|
|
- *
|
|
|
- * var cf = mf.compile('The Eagle landed at {T, time, full} on {T, date, full}');
|
|
|
- * cf({ T: '1969-07-20 20:17:40 UTC' })
|
|
|
- * // 'The Eagle landed at 10:17:40 PM GMT+2 on Sunday, July 20, 1969'
|
|
|
- * ```
|
|
|
- */
|
|
|
- function time(value, lc, size) {
|
|
|
- var o = {
|
|
|
- second: 'numeric',
|
|
|
- minute: 'numeric',
|
|
|
- hour: 'numeric'
|
|
|
- };
|
|
|
- /* eslint-disable no-fallthrough */
|
|
|
- switch (size) {
|
|
|
- case 'full':
|
|
|
- case 'long':
|
|
|
- o.timeZoneName = 'short';
|
|
|
- break;
|
|
|
- case 'short':
|
|
|
- delete o.second;
|
|
|
- }
|
|
|
- return new Date(value).toLocaleTimeString(lc, o);
|
|
|
- }
|
|
|
-
|
|
|
- var Formatters = /*#__PURE__*/Object.freeze({
|
|
|
- __proto__: null,
|
|
|
- date: date,
|
|
|
- duration: duration,
|
|
|
- numberCurrency: numberCurrency,
|
|
|
- numberFmt: numberFmt,
|
|
|
- numberInteger: numberInteger,
|
|
|
- numberPercent: numberPercent,
|
|
|
- time: time
|
|
|
- });
|
|
|
-
|
|
|
- const ES3 = {
|
|
|
- break: true,
|
|
|
- continue: true,
|
|
|
- delete: true,
|
|
|
- else: true,
|
|
|
- for: true,
|
|
|
- function: true,
|
|
|
- if: true,
|
|
|
- in: true,
|
|
|
- new: true,
|
|
|
- return: true,
|
|
|
- this: true,
|
|
|
- typeof: true,
|
|
|
- var: true,
|
|
|
- void: true,
|
|
|
- while: true,
|
|
|
- with: true,
|
|
|
- case: true,
|
|
|
- catch: true,
|
|
|
- default: true,
|
|
|
- do: true,
|
|
|
- finally: true,
|
|
|
- instanceof: true,
|
|
|
- switch: true,
|
|
|
- throw: true,
|
|
|
- try: true
|
|
|
- };
|
|
|
- const ESnext = {
|
|
|
- // in addition to reservedES3
|
|
|
- await: true,
|
|
|
- debugger: true,
|
|
|
- class: true,
|
|
|
- enum: true,
|
|
|
- extends: true,
|
|
|
- super: true,
|
|
|
- const: true,
|
|
|
- export: true,
|
|
|
- import: true,
|
|
|
- null: true,
|
|
|
- true: true,
|
|
|
- false: true,
|
|
|
- implements: true,
|
|
|
- let: true,
|
|
|
- private: true,
|
|
|
- public: true,
|
|
|
- yield: true,
|
|
|
- interface: true,
|
|
|
- package: true,
|
|
|
- protected: true,
|
|
|
- static: true
|
|
|
- };
|
|
|
- var reserved = {
|
|
|
- ES3,
|
|
|
- ESnext
|
|
|
- };
|
|
|
- var reserved$1 = reserved;
|
|
|
-
|
|
|
- // from https://werxltd.com/wp/2010/05/13/javascript-implementation-of-javas-string-hashcode-method/
|
|
|
- function hashCode(str) {
|
|
|
- let hash = 0;
|
|
|
- for (let i = 0; i < str.length; ++i) {
|
|
|
- const char = str.charCodeAt(i);
|
|
|
- hash = (hash << 5) - hash + char;
|
|
|
- hash |= 0; // Convert to 32bit integer
|
|
|
- }
|
|
|
-
|
|
|
- return hash;
|
|
|
- }
|
|
|
- function identifier(key, unique) {
|
|
|
- if (unique) key += ' ' + hashCode(key).toString(36);
|
|
|
- const id = key.trim().replace(/\W+/g, '_');
|
|
|
- return reserved$1.ES3[id] || reserved$1.ESnext[id] || /^\d/.test(id) ? '_' + id : id;
|
|
|
- }
|
|
|
- function property(obj, key) {
|
|
|
- if (/^[A-Z_$][0-9A-Z_$]*$/i.test(key) && !reserved$1.ES3[key]) {
|
|
|
- return obj ? obj + '.' + key : key;
|
|
|
- } else {
|
|
|
- const jkey = JSON.stringify(key);
|
|
|
- return obj ? obj + '[' + jkey + ']' : jkey;
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- var rtlLanguages = [
|
|
|
- 'ar',
|
|
|
- 'ckb',
|
|
|
- 'fa',
|
|
|
- 'he',
|
|
|
- 'ks($|[^bfh])',
|
|
|
- 'lrc',
|
|
|
- 'mzn',
|
|
|
- 'pa-Arab',
|
|
|
- 'ps',
|
|
|
- 'ug',
|
|
|
- 'ur',
|
|
|
- 'uz-Arab',
|
|
|
- 'yi'
|
|
|
- ];
|
|
|
- var rtlRegExp = new RegExp('^' + rtlLanguages.join('|^'));
|
|
|
- function biDiMarkText(text, locale) {
|
|
|
- var isLocaleRTL = rtlRegExp.test(locale);
|
|
|
- var mark = JSON.stringify(isLocaleRTL ? '\u200F' : '\u200E');
|
|
|
- return "".concat(mark, " + ").concat(text, " + ").concat(mark);
|
|
|
- }
|
|
|
-
|
|
|
- var RUNTIME_MODULE = '@messageformat/runtime';
|
|
|
- var CARDINAL_MODULE = '@messageformat/runtime/lib/cardinals';
|
|
|
- var PLURAL_MODULE = '@messageformat/runtime/lib/plurals';
|
|
|
- var FORMATTER_MODULE = '@messageformat/runtime/lib/formatters';
|
|
|
- var Compiler = (function () {
|
|
|
- function Compiler(options) {
|
|
|
- this.arguments = [];
|
|
|
- this.runtime = {};
|
|
|
- this.options = options;
|
|
|
- }
|
|
|
- Compiler.prototype.compile = function (src, plural, plurals) {
|
|
|
- var e_1, _a;
|
|
|
- var _this = this;
|
|
|
- var _b = this.options, localeCodeFromKey = _b.localeCodeFromKey, requireAllArguments = _b.requireAllArguments, strict = _b.strict, strictPluralKeys = _b.strictPluralKeys;
|
|
|
- if (typeof src === 'object') {
|
|
|
- var result = {};
|
|
|
- try {
|
|
|
- for (var _c = __values(Object.keys(src)), _d = _c.next(); !_d.done; _d = _c.next()) {
|
|
|
- var key = _d.value;
|
|
|
- var lc = localeCodeFromKey ? localeCodeFromKey(key) : key;
|
|
|
- var pl = (plurals && lc && plurals[lc]) || plural;
|
|
|
- result[key] = this.compile(src[key], pl, plurals);
|
|
|
- }
|
|
|
- }
|
|
|
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
|
- finally {
|
|
|
- try {
|
|
|
- if (_d && !_d.done && (_a = _c.return)) _a.call(_c);
|
|
|
- }
|
|
|
- finally { if (e_1) throw e_1.error; }
|
|
|
- }
|
|
|
- return result;
|
|
|
- }
|
|
|
- this.plural = plural;
|
|
|
- var parserOptions = {
|
|
|
- cardinal: plural.cardinals,
|
|
|
- ordinal: plural.ordinals,
|
|
|
- strict: strict,
|
|
|
- strictPluralKeys: strictPluralKeys
|
|
|
- };
|
|
|
- this.arguments = [];
|
|
|
- var r = parse_1(src, parserOptions).map(function (token) { return _this.token(token, null); });
|
|
|
- var hasArgs = this.arguments.length > 0;
|
|
|
- var res = this.concatenate(r, true);
|
|
|
- if (requireAllArguments && hasArgs) {
|
|
|
- this.setRuntimeFn('reqArgs');
|
|
|
- var reqArgs = JSON.stringify(this.arguments);
|
|
|
- return "(d) => { reqArgs(".concat(reqArgs, ", d); return ").concat(res, "; }");
|
|
|
- }
|
|
|
- return "(".concat(hasArgs ? 'd' : '', ") => ").concat(res);
|
|
|
- };
|
|
|
- Compiler.prototype.cases = function (token, pluralToken) {
|
|
|
- var _this = this;
|
|
|
- var needOther = true;
|
|
|
- var r = token.cases.map(function (_a) {
|
|
|
- var key = _a.key, tokens = _a.tokens;
|
|
|
- if (key === 'other')
|
|
|
- needOther = false;
|
|
|
- var s = tokens.map(function (tok) { return _this.token(tok, pluralToken); });
|
|
|
- return "".concat(property(null, key.replace(/^=/, '')), ": ").concat(_this.concatenate(s, false));
|
|
|
- });
|
|
|
- if (needOther) {
|
|
|
- var type = token.type;
|
|
|
- var _a = this.plural, cardinals = _a.cardinals, ordinals = _a.ordinals;
|
|
|
- if (type === 'select' ||
|
|
|
- (type === 'plural' && cardinals.includes('other')) ||
|
|
|
- (type === 'selectordinal' && ordinals.includes('other')))
|
|
|
- throw new Error("No 'other' form found in ".concat(JSON.stringify(token)));
|
|
|
- }
|
|
|
- return "{ ".concat(r.join(', '), " }");
|
|
|
- };
|
|
|
- Compiler.prototype.concatenate = function (tokens, root) {
|
|
|
- var asValues = this.options.returnType === 'values';
|
|
|
- return asValues && (root || tokens.length > 1)
|
|
|
- ? '[' + tokens.join(', ') + ']'
|
|
|
- : tokens.join(' + ') || '""';
|
|
|
- };
|
|
|
- Compiler.prototype.token = function (token, pluralToken) {
|
|
|
- if (token.type === 'content')
|
|
|
- return JSON.stringify(token.value);
|
|
|
- var _a = this.plural, id = _a.id, lc = _a.lc;
|
|
|
- var args, fn;
|
|
|
- if ('arg' in token) {
|
|
|
- this.arguments.push(token.arg);
|
|
|
- args = [property('d', token.arg)];
|
|
|
- }
|
|
|
- else
|
|
|
- args = [];
|
|
|
- switch (token.type) {
|
|
|
- case 'argument':
|
|
|
- return this.options.biDiSupport
|
|
|
- ? biDiMarkText(String(args[0]), lc)
|
|
|
- : String(args[0]);
|
|
|
- case 'select':
|
|
|
- fn = 'select';
|
|
|
- if (pluralToken && this.options.strict)
|
|
|
- pluralToken = null;
|
|
|
- args.push(this.cases(token, pluralToken));
|
|
|
- this.setRuntimeFn('select');
|
|
|
- break;
|
|
|
- case 'selectordinal':
|
|
|
- fn = 'plural';
|
|
|
- args.push(token.pluralOffset || 0, id, this.cases(token, token), 1);
|
|
|
- this.setLocale(id, true);
|
|
|
- this.setRuntimeFn('plural');
|
|
|
- break;
|
|
|
- case 'plural':
|
|
|
- fn = 'plural';
|
|
|
- args.push(token.pluralOffset || 0, id, this.cases(token, token));
|
|
|
- this.setLocale(id, false);
|
|
|
- this.setRuntimeFn('plural');
|
|
|
- break;
|
|
|
- case 'function':
|
|
|
- if (!this.options.customFormatters[token.key]) {
|
|
|
- if (token.key === 'date') {
|
|
|
- fn = this.setDateFormatter(token, args, pluralToken);
|
|
|
- break;
|
|
|
- }
|
|
|
- else if (token.key === 'number') {
|
|
|
- fn = this.setNumberFormatter(token, args, pluralToken);
|
|
|
- break;
|
|
|
- }
|
|
|
- }
|
|
|
- args.push(JSON.stringify(this.plural.locale));
|
|
|
- if (token.param) {
|
|
|
- if (pluralToken && this.options.strict)
|
|
|
- pluralToken = null;
|
|
|
- var arg = this.getFormatterArg(token, pluralToken);
|
|
|
- if (arg)
|
|
|
- args.push(arg);
|
|
|
- }
|
|
|
- fn = token.key;
|
|
|
- this.setFormatter(fn);
|
|
|
- break;
|
|
|
- case 'octothorpe':
|
|
|
- if (!pluralToken)
|
|
|
- return '"#"';
|
|
|
- args = [
|
|
|
- JSON.stringify(this.plural.locale),
|
|
|
- property('d', pluralToken.arg),
|
|
|
- pluralToken.pluralOffset || 0
|
|
|
- ];
|
|
|
- if (this.options.strict) {
|
|
|
- fn = 'strictNumber';
|
|
|
- args.push(JSON.stringify(pluralToken.arg));
|
|
|
- this.setRuntimeFn('strictNumber');
|
|
|
- }
|
|
|
- else {
|
|
|
- fn = 'number';
|
|
|
- this.setRuntimeFn('number');
|
|
|
- }
|
|
|
- break;
|
|
|
- }
|
|
|
- if (!fn)
|
|
|
- throw new Error('Parser error for token ' + JSON.stringify(token));
|
|
|
- return "".concat(fn, "(").concat(args.join(', '), ")");
|
|
|
- };
|
|
|
- Compiler.prototype.runtimeIncludes = function (key, type) {
|
|
|
- if (identifier(key) !== key)
|
|
|
- throw new SyntaxError("Reserved word used as ".concat(type, " identifier: ").concat(key));
|
|
|
- var prev = this.runtime[key];
|
|
|
- if (!prev || prev.type === type)
|
|
|
- return prev;
|
|
|
- throw new TypeError("Cannot override ".concat(prev.type, " runtime function as ").concat(type, ": ").concat(key));
|
|
|
- };
|
|
|
- Compiler.prototype.setLocale = function (key, ord) {
|
|
|
- var prev = this.runtimeIncludes(key, 'locale');
|
|
|
- var _a = this.plural, getCardinal = _a.getCardinal, getPlural = _a.getPlural, isDefault = _a.isDefault;
|
|
|
- var pf, module, toString;
|
|
|
- if (!ord && isDefault && getCardinal) {
|
|
|
- if (prev)
|
|
|
- return;
|
|
|
- pf = function (n) { return getCardinal(n); };
|
|
|
- module = CARDINAL_MODULE;
|
|
|
- toString = function () { return String(getCardinal); };
|
|
|
- }
|
|
|
- else {
|
|
|
- if (prev && (!isDefault || prev.module === PLURAL_MODULE))
|
|
|
- return;
|
|
|
- pf = function (n, ord) { return getPlural(n, ord); };
|
|
|
- module = isDefault ? PLURAL_MODULE : getPlural.module || null;
|
|
|
- toString = function () { return String(getPlural); };
|
|
|
- }
|
|
|
- this.runtime[key] = Object.assign(pf, {
|
|
|
- id: key,
|
|
|
- module: module,
|
|
|
- toString: toString,
|
|
|
- type: 'locale'
|
|
|
- });
|
|
|
- };
|
|
|
- Compiler.prototype.setRuntimeFn = function (key) {
|
|
|
- if (this.runtimeIncludes(key, 'runtime'))
|
|
|
- return;
|
|
|
- this.runtime[key] = Object.assign(Runtime[key], {
|
|
|
- id: key,
|
|
|
- module: RUNTIME_MODULE,
|
|
|
- type: 'runtime'
|
|
|
- });
|
|
|
- };
|
|
|
- Compiler.prototype.getFormatterArg = function (_a, pluralToken) {
|
|
|
- var e_2, _b, e_3, _c;
|
|
|
- var _this = this;
|
|
|
- var key = _a.key, param = _a.param;
|
|
|
- var fmt = this.options.customFormatters[key] ||
|
|
|
- (isFormatterKey(key) && Formatters[key]);
|
|
|
- if (!fmt || !param)
|
|
|
- return null;
|
|
|
- var argShape = ('arg' in fmt && fmt.arg) || 'string';
|
|
|
- if (argShape === 'options') {
|
|
|
- var value = '';
|
|
|
- try {
|
|
|
- for (var param_1 = __values(param), param_1_1 = param_1.next(); !param_1_1.done; param_1_1 = param_1.next()) {
|
|
|
- var tok = param_1_1.value;
|
|
|
- if (tok.type === 'content')
|
|
|
- value += tok.value;
|
|
|
- else
|
|
|
- throw new SyntaxError("Expected literal options for ".concat(key, " formatter"));
|
|
|
- }
|
|
|
- }
|
|
|
- catch (e_2_1) { e_2 = { error: e_2_1 }; }
|
|
|
- finally {
|
|
|
- try {
|
|
|
- if (param_1_1 && !param_1_1.done && (_b = param_1.return)) _b.call(param_1);
|
|
|
- }
|
|
|
- finally { if (e_2) throw e_2.error; }
|
|
|
- }
|
|
|
- var options = {};
|
|
|
- try {
|
|
|
- for (var _d = __values(value.split(',')), _e = _d.next(); !_e.done; _e = _d.next()) {
|
|
|
- var pair = _e.value;
|
|
|
- var keyEnd = pair.indexOf(':');
|
|
|
- if (keyEnd === -1)
|
|
|
- options[pair.trim()] = null;
|
|
|
- else {
|
|
|
- var k = pair.substring(0, keyEnd).trim();
|
|
|
- var v = pair.substring(keyEnd + 1).trim();
|
|
|
- if (v === 'true')
|
|
|
- options[k] = true;
|
|
|
- else if (v === 'false')
|
|
|
- options[k] = false;
|
|
|
- else if (v === 'null')
|
|
|
- options[k] = null;
|
|
|
- else {
|
|
|
- var n = Number(v);
|
|
|
- options[k] = Number.isFinite(n) ? n : v;
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- }
|
|
|
- catch (e_3_1) { e_3 = { error: e_3_1 }; }
|
|
|
- finally {
|
|
|
- try {
|
|
|
- if (_e && !_e.done && (_c = _d.return)) _c.call(_d);
|
|
|
- }
|
|
|
- finally { if (e_3) throw e_3.error; }
|
|
|
- }
|
|
|
- return JSON.stringify(options);
|
|
|
- }
|
|
|
- else {
|
|
|
- var parts = param.map(function (tok) { return _this.token(tok, pluralToken); });
|
|
|
- if (argShape === 'raw')
|
|
|
- return "[".concat(parts.join(', '), "]");
|
|
|
- var s = parts.join(' + ');
|
|
|
- return s ? "(".concat(s, ").trim()") : '""';
|
|
|
- }
|
|
|
- };
|
|
|
- Compiler.prototype.setFormatter = function (key) {
|
|
|
- if (this.runtimeIncludes(key, 'formatter'))
|
|
|
- return;
|
|
|
- var cf = this.options.customFormatters[key];
|
|
|
- if (cf) {
|
|
|
- if (typeof cf === 'function')
|
|
|
- cf = { formatter: cf };
|
|
|
- this.runtime[key] = Object.assign(cf.formatter, { type: 'formatter' }, 'module' in cf && cf.module && cf.id
|
|
|
- ? { id: identifier(cf.id), module: cf.module }
|
|
|
- : { id: null, module: null });
|
|
|
- }
|
|
|
- else if (isFormatterKey(key)) {
|
|
|
- this.runtime[key] = Object.assign(Formatters[key], { type: 'formatter' }, { id: key, module: FORMATTER_MODULE });
|
|
|
- }
|
|
|
- else {
|
|
|
- throw new Error("Formatting function not found: ".concat(key));
|
|
|
- }
|
|
|
- };
|
|
|
- Compiler.prototype.setDateFormatter = function (_a, args, plural) {
|
|
|
- var _this = this;
|
|
|
- var param = _a.param;
|
|
|
- var locale = this.plural.locale;
|
|
|
- var argStyle = param && param.length === 1 && param[0];
|
|
|
- if (argStyle &&
|
|
|
- argStyle.type === 'content' &&
|
|
|
- /^\s*::/.test(argStyle.value)) {
|
|
|
- var argSkeletonText_1 = argStyle.value.trim().substr(2);
|
|
|
- var key = identifier("date_".concat(locale, "_").concat(argSkeletonText_1), true);
|
|
|
- if (!this.runtimeIncludes(key, 'formatter')) {
|
|
|
- var fmt = getDateFormatter(locale, argSkeletonText_1);
|
|
|
- this.runtime[key] = Object.assign(fmt, {
|
|
|
- id: key,
|
|
|
- module: null,
|
|
|
- toString: function () { return getDateFormatterSource(locale, argSkeletonText_1); },
|
|
|
- type: 'formatter'
|
|
|
- });
|
|
|
- }
|
|
|
- return key;
|
|
|
- }
|
|
|
- args.push(JSON.stringify(locale));
|
|
|
- if (param && param.length > 0) {
|
|
|
- if (plural && this.options.strict)
|
|
|
- plural = null;
|
|
|
- var s = param.map(function (tok) { return _this.token(tok, plural); });
|
|
|
- args.push('(' + (s.join(' + ') || '""') + ').trim()');
|
|
|
- }
|
|
|
- this.setFormatter('date');
|
|
|
- return 'date';
|
|
|
- };
|
|
|
- Compiler.prototype.setNumberFormatter = function (_a, args, plural) {
|
|
|
- var _this = this;
|
|
|
- var param = _a.param;
|
|
|
- var locale = this.plural.locale;
|
|
|
- if (!param || param.length === 0) {
|
|
|
- args.unshift(JSON.stringify(locale));
|
|
|
- args.push('0');
|
|
|
- this.setRuntimeFn('number');
|
|
|
- return 'number';
|
|
|
- }
|
|
|
- args.push(JSON.stringify(locale));
|
|
|
- if (param.length === 1 && param[0].type === 'content') {
|
|
|
- var fmtArg_1 = param[0].value.trim();
|
|
|
- switch (fmtArg_1) {
|
|
|
- case 'currency':
|
|
|
- args.push(JSON.stringify(this.options.currency));
|
|
|
- this.setFormatter('numberCurrency');
|
|
|
- return 'numberCurrency';
|
|
|
- case 'integer':
|
|
|
- this.setFormatter('numberInteger');
|
|
|
- return 'numberInteger';
|
|
|
- case 'percent':
|
|
|
- this.setFormatter('numberPercent');
|
|
|
- return 'numberPercent';
|
|
|
- }
|
|
|
- var cm = fmtArg_1.match(/^currency:([A-Z]+)$/);
|
|
|
- if (cm) {
|
|
|
- args.push(JSON.stringify(cm[1]));
|
|
|
- this.setFormatter('numberCurrency');
|
|
|
- return 'numberCurrency';
|
|
|
- }
|
|
|
- var key = identifier("number_".concat(locale, "_").concat(fmtArg_1), true);
|
|
|
- if (!this.runtimeIncludes(key, 'formatter')) {
|
|
|
- var currency_1 = this.options.currency;
|
|
|
- var fmt = getNumberFormatter(locale, fmtArg_1, currency_1);
|
|
|
- this.runtime[key] = Object.assign(fmt, {
|
|
|
- id: null,
|
|
|
- module: null,
|
|
|
- toString: function () { return getNumberFormatterSource(locale, fmtArg_1, currency_1); },
|
|
|
- type: 'formatter'
|
|
|
- });
|
|
|
- }
|
|
|
- return key;
|
|
|
- }
|
|
|
- if (plural && this.options.strict)
|
|
|
- plural = null;
|
|
|
- var s = param.map(function (tok) { return _this.token(tok, plural); });
|
|
|
- args.push('(' + (s.join(' + ') || '""') + ').trim()');
|
|
|
- args.push(JSON.stringify(this.options.currency));
|
|
|
- this.setFormatter('numberFmt');
|
|
|
- return 'numberFmt';
|
|
|
- };
|
|
|
- return Compiler;
|
|
|
- }());
|
|
|
- function isFormatterKey(key) {
|
|
|
- return key in Formatters;
|
|
|
- }
|
|
|
-
|
|
|
- const a$2 = n => n == 1 ? 'one' : 'other';
|
|
|
- const b$2 = n => n == 0 || n == 1 ? 'one' : 'other';
|
|
|
- const c$2 = n => n >= 0 && n <= 1 ? 'one' : 'other';
|
|
|
- const d$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1];
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const e$1 = n => 'other';
|
|
|
- const f$2 = n => n == 1 ? 'one' : n == 2 ? 'two' : 'other';
|
|
|
- const af$2 = a$2;
|
|
|
- const ak$2 = b$2;
|
|
|
- const am$2 = c$2;
|
|
|
- const an$2 = a$2;
|
|
|
- const ar$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n100 >= 3 && n100 <= 10 ? 'few' : n100 >= 11 && n100 <= 99 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ars$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n100 >= 3 && n100 <= 10 ? 'few' : n100 >= 11 && n100 <= 99 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const as$2 = c$2;
|
|
|
- const asa$2 = a$2;
|
|
|
- const ast$2 = d$2;
|
|
|
- const az$2 = a$2;
|
|
|
- const bal$2 = a$2;
|
|
|
- const be$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n10 == 1 && n100 != 11 ? 'one' : n10 >= 2 && n10 <= 4 && (n100 < 12 || n100 > 14) ? 'few' : t0 && n10 == 0 || n10 >= 5 && n10 <= 9 || n100 >= 11 && n100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const bem$2 = a$2;
|
|
|
- const bez$2 = a$2;
|
|
|
- const bg$2 = a$2;
|
|
|
- const bho$2 = b$2;
|
|
|
- const bm$2 = e$1;
|
|
|
- const bn$2 = c$2;
|
|
|
- const bo$2 = e$1;
|
|
|
- const br$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- n1000000 = t0 && s[0].slice(-6);
|
|
|
- return n10 == 1 && n100 != 11 && n100 != 71 && n100 != 91 ? 'one' : n10 == 2 && n100 != 12 && n100 != 72 && n100 != 92 ? 'two' : (n10 == 3 || n10 == 4 || n10 == 9) && (n100 < 10 || n100 > 19) && (n100 < 70 || n100 > 79) && (n100 < 90 || n100 > 99) ? 'few' : n != 0 && t0 && n1000000 == 0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const brx$2 = a$2;
|
|
|
- const bs$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const ca$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ce$2 = a$2;
|
|
|
- const ceb$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- f10 = f.slice(-1);
|
|
|
- return v0 && (i == 1 || i == 2 || i == 3) || v0 && i10 != 4 && i10 != 6 && i10 != 9 || !v0 && f10 != 4 && f10 != 6 && f10 != 9 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const cgg$2 = a$2;
|
|
|
- const chr$2 = a$2;
|
|
|
- const ckb$2 = a$2;
|
|
|
- const cs$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1];
|
|
|
- return n == 1 && v0 ? 'one' : i >= 2 && i <= 4 && v0 ? 'few' : !v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const cy$2 = n => n == 0 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n == 3 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- const da$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- return n == 1 || !t0 && (i == 0 || i == 1) ? 'one' : 'other';
|
|
|
- };
|
|
|
- const de$2 = d$2;
|
|
|
- const doi$2 = c$2;
|
|
|
- const dsb$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i100 = i.slice(-2),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i100 == 1 || f100 == 1 ? 'one' : v0 && i100 == 2 || f100 == 2 ? 'two' : v0 && (i100 == 3 || i100 == 4) || f100 == 3 || f100 == 4 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const dv$2 = a$2;
|
|
|
- const dz$2 = e$1;
|
|
|
- const ee$2 = a$2;
|
|
|
- const el$2 = a$2;
|
|
|
- const en$2 = d$2;
|
|
|
- const eo$2 = a$2;
|
|
|
- const es$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return n == 1 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const et$2 = d$2;
|
|
|
- const eu$2 = a$2;
|
|
|
- const fa$2 = c$2;
|
|
|
- const ff$2 = n => n >= 0 && n < 2 ? 'one' : 'other';
|
|
|
- const fi$2 = d$2;
|
|
|
- const fil$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- f10 = f.slice(-1);
|
|
|
- return v0 && (i == 1 || i == 2 || i == 3) || v0 && i10 != 4 && i10 != 6 && i10 != 9 || !v0 && f10 != 4 && f10 != 6 && f10 != 9 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const fo$2 = a$2;
|
|
|
- const fr$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return n >= 0 && n < 2 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const fur$2 = a$2;
|
|
|
- const fy$2 = d$2;
|
|
|
- const ga$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- return n == 1 ? 'one' : n == 2 ? 'two' : t0 && n >= 3 && n <= 6 ? 'few' : t0 && n >= 7 && n <= 10 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const gd$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- return n == 1 || n == 11 ? 'one' : n == 2 || n == 12 ? 'two' : t0 && n >= 3 && n <= 10 || t0 && n >= 13 && n <= 19 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const gl$2 = d$2;
|
|
|
- const gsw$2 = a$2;
|
|
|
- const gu$2 = c$2;
|
|
|
- const guw$2 = b$2;
|
|
|
- const gv$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- return v0 && i10 == 1 ? 'one' : v0 && i10 == 2 ? 'two' : v0 && (i100 == 0 || i100 == 20 || i100 == 40 || i100 == 60 || i100 == 80) ? 'few' : !v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ha$2 = a$2;
|
|
|
- const haw$2 = a$2;
|
|
|
- const he$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1];
|
|
|
- return i == 1 && v0 || i == 0 && !v0 ? 'one' : i == 2 && v0 ? 'two' : 'other';
|
|
|
- };
|
|
|
- const hi$2 = c$2;
|
|
|
- const hnj$2 = e$1;
|
|
|
- const hr$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const hsb$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i100 = i.slice(-2),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i100 == 1 || f100 == 1 ? 'one' : v0 && i100 == 2 || f100 == 2 ? 'two' : v0 && (i100 == 3 || i100 == 4) || f100 == 3 || f100 == 4 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const hu$2 = a$2;
|
|
|
- const hy$2 = n => n >= 0 && n < 2 ? 'one' : 'other';
|
|
|
- const ia$2 = d$2;
|
|
|
- const id$2 = e$1;
|
|
|
- const ig$2 = e$1;
|
|
|
- const ii$2 = e$1;
|
|
|
- const io$2 = d$2;
|
|
|
- const is$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- t = (s[1] || '').replace(/0+$/, ''),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- return t0 && i10 == 1 && i100 != 11 || t % 10 == 1 && t % 100 != 11 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const it$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const iu$2 = f$2;
|
|
|
- const ja$2 = e$1;
|
|
|
- const jbo$2 = e$1;
|
|
|
- const jgo$2 = a$2;
|
|
|
- const jmc$2 = a$2;
|
|
|
- const jv$2 = e$1;
|
|
|
- const jw$2 = e$1;
|
|
|
- const ka$2 = a$2;
|
|
|
- const kab$2 = n => n >= 0 && n < 2 ? 'one' : 'other';
|
|
|
- const kaj$2 = a$2;
|
|
|
- const kcg$2 = a$2;
|
|
|
- const kde$2 = e$1;
|
|
|
- const kea$2 = e$1;
|
|
|
- const kk$2 = a$2;
|
|
|
- const kkj$2 = a$2;
|
|
|
- const kl$2 = a$2;
|
|
|
- const km$2 = e$1;
|
|
|
- const kn$2 = c$2;
|
|
|
- const ko$2 = e$1;
|
|
|
- const ks$2 = a$2;
|
|
|
- const ksb$2 = a$2;
|
|
|
- const ksh$2 = n => n == 0 ? 'zero' : n == 1 ? 'one' : 'other';
|
|
|
- const ku$2 = a$2;
|
|
|
- const kw$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- n1000 = t0 && s[0].slice(-3),
|
|
|
- n100000 = t0 && s[0].slice(-5),
|
|
|
- n1000000 = t0 && s[0].slice(-6);
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n100 == 2 || n100 == 22 || n100 == 42 || n100 == 62 || n100 == 82 || t0 && n1000 == 0 && (n100000 >= 1000 && n100000 <= 20000 || n100000 == 40000 || n100000 == 60000 || n100000 == 80000) || n != 0 && n1000000 == 100000 ? 'two' : n100 == 3 || n100 == 23 || n100 == 43 || n100 == 63 || n100 == 83 ? 'few' : n != 1 && (n100 == 1 || n100 == 21 || n100 == 41 || n100 == 61 || n100 == 81) ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ky$2 = a$2;
|
|
|
- const lag$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0];
|
|
|
- return n == 0 ? 'zero' : (i == 0 || i == 1) && n != 0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const lb$2 = a$2;
|
|
|
- const lg$2 = a$2;
|
|
|
- const lij$2 = d$2;
|
|
|
- const lkt$2 = e$1;
|
|
|
- const ln$2 = b$2;
|
|
|
- const lo$2 = e$1;
|
|
|
- const lt$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- f = s[1] || '',
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n10 == 1 && (n100 < 11 || n100 > 19) ? 'one' : n10 >= 2 && n10 <= 9 && (n100 < 11 || n100 > 19) ? 'few' : f != 0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const lv$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- f = s[1] || '',
|
|
|
- v = f.length,
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- f100 = f.slice(-2),
|
|
|
- f10 = f.slice(-1);
|
|
|
- return t0 && n10 == 0 || n100 >= 11 && n100 <= 19 || v == 2 && f100 >= 11 && f100 <= 19 ? 'zero' : n10 == 1 && n100 != 11 || v == 2 && f10 == 1 && f100 != 11 || v != 2 && f10 == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const mas$2 = a$2;
|
|
|
- const mg$2 = b$2;
|
|
|
- const mgo$2 = a$2;
|
|
|
- const mk$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ml$2 = a$2;
|
|
|
- const mn$2 = a$2;
|
|
|
- const mo$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n == 1 && v0 ? 'one' : !v0 || n == 0 || n != 1 && n100 >= 1 && n100 <= 19 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const mr$2 = a$2;
|
|
|
- const ms$2 = e$1;
|
|
|
- const mt$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n == 1 ? 'one' : n == 2 ? 'two' : n == 0 || n100 >= 3 && n100 <= 10 ? 'few' : n100 >= 11 && n100 <= 19 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const my$2 = e$1;
|
|
|
- const nah$2 = a$2;
|
|
|
- const naq$2 = f$2;
|
|
|
- const nb$2 = a$2;
|
|
|
- const nd$2 = a$2;
|
|
|
- const ne$2 = a$2;
|
|
|
- const nl$2 = d$2;
|
|
|
- const nn$2 = a$2;
|
|
|
- const nnh$2 = a$2;
|
|
|
- const no$2 = a$2;
|
|
|
- const nqo$2 = e$1;
|
|
|
- const nr$2 = a$2;
|
|
|
- const nso$2 = b$2;
|
|
|
- const ny$2 = a$2;
|
|
|
- const nyn$2 = a$2;
|
|
|
- const om$2 = a$2;
|
|
|
- const or$2 = a$2;
|
|
|
- const os$2 = a$2;
|
|
|
- const osa$2 = e$1;
|
|
|
- const pa$2 = b$2;
|
|
|
- const pap$2 = a$2;
|
|
|
- const pcm$2 = c$2;
|
|
|
- const pl$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- return n == 1 && v0 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) ? 'few' : v0 && i != 1 && (i10 == 0 || i10 == 1) || v0 && i10 >= 5 && i10 <= 9 || v0 && i100 >= 12 && i100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const prg$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- f = s[1] || '',
|
|
|
- v = f.length,
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- f100 = f.slice(-2),
|
|
|
- f10 = f.slice(-1);
|
|
|
- return t0 && n10 == 0 || n100 >= 11 && n100 <= 19 || v == 2 && f100 >= 11 && f100 <= 19 ? 'zero' : n10 == 1 && n100 != 11 || v == 2 && f10 == 1 && f100 != 11 || v != 2 && f10 == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ps$2 = a$2;
|
|
|
- const pt$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return i == 0 || i == 1 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const pt_PT$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const rm$2 = a$2;
|
|
|
- const ro$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- return n == 1 && v0 ? 'one' : !v0 || n == 0 || n != 1 && n100 >= 1 && n100 <= 19 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const rof$2 = a$2;
|
|
|
- const ru$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) ? 'few' : v0 && i10 == 0 || v0 && i10 >= 5 && i10 <= 9 || v0 && i100 >= 11 && i100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const rwk$2 = a$2;
|
|
|
- const sah$2 = e$1;
|
|
|
- const saq$2 = a$2;
|
|
|
- const sat$2 = f$2;
|
|
|
- const sc$2 = d$2;
|
|
|
- const scn$2 = d$2;
|
|
|
- const sd$2 = a$2;
|
|
|
- const sdh$2 = a$2;
|
|
|
- const se$2 = f$2;
|
|
|
- const seh$2 = a$2;
|
|
|
- const ses$2 = e$1;
|
|
|
- const sg$2 = e$1;
|
|
|
- const sh$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const shi$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- return n >= 0 && n <= 1 ? 'one' : t0 && n >= 2 && n <= 10 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const si$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '';
|
|
|
- return n == 0 || n == 1 || i == 0 && f == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const sk$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1];
|
|
|
- return n == 1 && v0 ? 'one' : i >= 2 && i <= 4 && v0 ? 'few' : !v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const sl$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i100 = i.slice(-2);
|
|
|
- return v0 && i100 == 1 ? 'one' : v0 && i100 == 2 ? 'two' : v0 && (i100 == 3 || i100 == 4) || !v0 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const sma$2 = f$2;
|
|
|
- const smi$2 = f$2;
|
|
|
- const smj$2 = f$2;
|
|
|
- const smn$2 = f$2;
|
|
|
- const sms$2 = f$2;
|
|
|
- const sn$2 = a$2;
|
|
|
- const so$2 = a$2;
|
|
|
- const sq$2 = a$2;
|
|
|
- const sr$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const ss$2 = a$2;
|
|
|
- const ssy$2 = a$2;
|
|
|
- const st$2 = a$2;
|
|
|
- const su$2 = e$1;
|
|
|
- const sv$2 = d$2;
|
|
|
- const sw$2 = d$2;
|
|
|
- const syr$2 = a$2;
|
|
|
- const ta$2 = a$2;
|
|
|
- const te$2 = a$2;
|
|
|
- const teo$2 = a$2;
|
|
|
- const th$2 = e$1;
|
|
|
- const ti$2 = b$2;
|
|
|
- const tig$2 = a$2;
|
|
|
- const tk$2 = a$2;
|
|
|
- const tl$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- f10 = f.slice(-1);
|
|
|
- return v0 && (i == 1 || i == 2 || i == 3) || v0 && i10 != 4 && i10 != 6 && i10 != 9 || !v0 && f10 != 4 && f10 != 6 && f10 != 9 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const tn$2 = a$2;
|
|
|
- const to$2 = e$1;
|
|
|
- const tpi$2 = e$1;
|
|
|
- const tr$2 = a$2;
|
|
|
- const ts$2 = a$2;
|
|
|
- const tzm$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- return n == 0 || n == 1 || t0 && n >= 11 && n <= 99 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ug$2 = a$2;
|
|
|
- const uk$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- return v0 && i10 == 1 && i100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) ? 'few' : v0 && i10 == 0 || v0 && i10 >= 5 && i10 <= 9 || v0 && i100 >= 11 && i100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const und$2 = e$1;
|
|
|
- const ur$2 = d$2;
|
|
|
- const uz$2 = a$2;
|
|
|
- const ve$2 = a$2;
|
|
|
- const vec$2 = n => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const vi$2 = e$1;
|
|
|
- const vo$2 = a$2;
|
|
|
- const vun$2 = a$2;
|
|
|
- const wa$2 = b$2;
|
|
|
- const wae$2 = a$2;
|
|
|
- const wo$2 = e$1;
|
|
|
- const xh$2 = a$2;
|
|
|
- const xog$2 = a$2;
|
|
|
- const yi$2 = d$2;
|
|
|
- const yo$2 = e$1;
|
|
|
- const yue$2 = e$1;
|
|
|
- const zh$2 = e$1;
|
|
|
- const zu$2 = c$2;
|
|
|
-
|
|
|
- var Cardinals = /*#__PURE__*/Object.freeze({
|
|
|
- __proto__: null,
|
|
|
- af: af$2,
|
|
|
- ak: ak$2,
|
|
|
- am: am$2,
|
|
|
- an: an$2,
|
|
|
- ar: ar$2,
|
|
|
- ars: ars$2,
|
|
|
- as: as$2,
|
|
|
- asa: asa$2,
|
|
|
- ast: ast$2,
|
|
|
- az: az$2,
|
|
|
- bal: bal$2,
|
|
|
- be: be$2,
|
|
|
- bem: bem$2,
|
|
|
- bez: bez$2,
|
|
|
- bg: bg$2,
|
|
|
- bho: bho$2,
|
|
|
- bm: bm$2,
|
|
|
- bn: bn$2,
|
|
|
- bo: bo$2,
|
|
|
- br: br$2,
|
|
|
- brx: brx$2,
|
|
|
- bs: bs$2,
|
|
|
- ca: ca$2,
|
|
|
- ce: ce$2,
|
|
|
- ceb: ceb$2,
|
|
|
- cgg: cgg$2,
|
|
|
- chr: chr$2,
|
|
|
- ckb: ckb$2,
|
|
|
- cs: cs$2,
|
|
|
- cy: cy$2,
|
|
|
- da: da$2,
|
|
|
- de: de$2,
|
|
|
- doi: doi$2,
|
|
|
- dsb: dsb$2,
|
|
|
- dv: dv$2,
|
|
|
- dz: dz$2,
|
|
|
- ee: ee$2,
|
|
|
- el: el$2,
|
|
|
- en: en$2,
|
|
|
- eo: eo$2,
|
|
|
- es: es$2,
|
|
|
- et: et$2,
|
|
|
- eu: eu$2,
|
|
|
- fa: fa$2,
|
|
|
- ff: ff$2,
|
|
|
- fi: fi$2,
|
|
|
- fil: fil$2,
|
|
|
- fo: fo$2,
|
|
|
- fr: fr$2,
|
|
|
- fur: fur$2,
|
|
|
- fy: fy$2,
|
|
|
- ga: ga$2,
|
|
|
- gd: gd$2,
|
|
|
- gl: gl$2,
|
|
|
- gsw: gsw$2,
|
|
|
- gu: gu$2,
|
|
|
- guw: guw$2,
|
|
|
- gv: gv$2,
|
|
|
- ha: ha$2,
|
|
|
- haw: haw$2,
|
|
|
- he: he$2,
|
|
|
- hi: hi$2,
|
|
|
- hnj: hnj$2,
|
|
|
- hr: hr$2,
|
|
|
- hsb: hsb$2,
|
|
|
- hu: hu$2,
|
|
|
- hy: hy$2,
|
|
|
- ia: ia$2,
|
|
|
- id: id$2,
|
|
|
- ig: ig$2,
|
|
|
- ii: ii$2,
|
|
|
- io: io$2,
|
|
|
- is: is$2,
|
|
|
- it: it$2,
|
|
|
- iu: iu$2,
|
|
|
- ja: ja$2,
|
|
|
- jbo: jbo$2,
|
|
|
- jgo: jgo$2,
|
|
|
- jmc: jmc$2,
|
|
|
- jv: jv$2,
|
|
|
- jw: jw$2,
|
|
|
- ka: ka$2,
|
|
|
- kab: kab$2,
|
|
|
- kaj: kaj$2,
|
|
|
- kcg: kcg$2,
|
|
|
- kde: kde$2,
|
|
|
- kea: kea$2,
|
|
|
- kk: kk$2,
|
|
|
- kkj: kkj$2,
|
|
|
- kl: kl$2,
|
|
|
- km: km$2,
|
|
|
- kn: kn$2,
|
|
|
- ko: ko$2,
|
|
|
- ks: ks$2,
|
|
|
- ksb: ksb$2,
|
|
|
- ksh: ksh$2,
|
|
|
- ku: ku$2,
|
|
|
- kw: kw$2,
|
|
|
- ky: ky$2,
|
|
|
- lag: lag$2,
|
|
|
- lb: lb$2,
|
|
|
- lg: lg$2,
|
|
|
- lij: lij$2,
|
|
|
- lkt: lkt$2,
|
|
|
- ln: ln$2,
|
|
|
- lo: lo$2,
|
|
|
- lt: lt$2,
|
|
|
- lv: lv$2,
|
|
|
- mas: mas$2,
|
|
|
- mg: mg$2,
|
|
|
- mgo: mgo$2,
|
|
|
- mk: mk$2,
|
|
|
- ml: ml$2,
|
|
|
- mn: mn$2,
|
|
|
- mo: mo$2,
|
|
|
- mr: mr$2,
|
|
|
- ms: ms$2,
|
|
|
- mt: mt$2,
|
|
|
- my: my$2,
|
|
|
- nah: nah$2,
|
|
|
- naq: naq$2,
|
|
|
- nb: nb$2,
|
|
|
- nd: nd$2,
|
|
|
- ne: ne$2,
|
|
|
- nl: nl$2,
|
|
|
- nn: nn$2,
|
|
|
- nnh: nnh$2,
|
|
|
- no: no$2,
|
|
|
- nqo: nqo$2,
|
|
|
- nr: nr$2,
|
|
|
- nso: nso$2,
|
|
|
- ny: ny$2,
|
|
|
- nyn: nyn$2,
|
|
|
- om: om$2,
|
|
|
- or: or$2,
|
|
|
- os: os$2,
|
|
|
- osa: osa$2,
|
|
|
- pa: pa$2,
|
|
|
- pap: pap$2,
|
|
|
- pcm: pcm$2,
|
|
|
- pl: pl$2,
|
|
|
- prg: prg$2,
|
|
|
- ps: ps$2,
|
|
|
- pt: pt$2,
|
|
|
- pt_PT: pt_PT$2,
|
|
|
- rm: rm$2,
|
|
|
- ro: ro$2,
|
|
|
- rof: rof$2,
|
|
|
- ru: ru$2,
|
|
|
- rwk: rwk$2,
|
|
|
- sah: sah$2,
|
|
|
- saq: saq$2,
|
|
|
- sat: sat$2,
|
|
|
- sc: sc$2,
|
|
|
- scn: scn$2,
|
|
|
- sd: sd$2,
|
|
|
- sdh: sdh$2,
|
|
|
- se: se$2,
|
|
|
- seh: seh$2,
|
|
|
- ses: ses$2,
|
|
|
- sg: sg$2,
|
|
|
- sh: sh$2,
|
|
|
- shi: shi$2,
|
|
|
- si: si$2,
|
|
|
- sk: sk$2,
|
|
|
- sl: sl$2,
|
|
|
- sma: sma$2,
|
|
|
- smi: smi$2,
|
|
|
- smj: smj$2,
|
|
|
- smn: smn$2,
|
|
|
- sms: sms$2,
|
|
|
- sn: sn$2,
|
|
|
- so: so$2,
|
|
|
- sq: sq$2,
|
|
|
- sr: sr$2,
|
|
|
- ss: ss$2,
|
|
|
- ssy: ssy$2,
|
|
|
- st: st$2,
|
|
|
- su: su$2,
|
|
|
- sv: sv$2,
|
|
|
- sw: sw$2,
|
|
|
- syr: syr$2,
|
|
|
- ta: ta$2,
|
|
|
- te: te$2,
|
|
|
- teo: teo$2,
|
|
|
- th: th$2,
|
|
|
- ti: ti$2,
|
|
|
- tig: tig$2,
|
|
|
- tk: tk$2,
|
|
|
- tl: tl$2,
|
|
|
- tn: tn$2,
|
|
|
- to: to$2,
|
|
|
- tpi: tpi$2,
|
|
|
- tr: tr$2,
|
|
|
- ts: ts$2,
|
|
|
- tzm: tzm$2,
|
|
|
- ug: ug$2,
|
|
|
- uk: uk$2,
|
|
|
- und: und$2,
|
|
|
- ur: ur$2,
|
|
|
- uz: uz$2,
|
|
|
- ve: ve$2,
|
|
|
- vec: vec$2,
|
|
|
- vi: vi$2,
|
|
|
- vo: vo$2,
|
|
|
- vun: vun$2,
|
|
|
- wa: wa$2,
|
|
|
- wae: wae$2,
|
|
|
- wo: wo$2,
|
|
|
- xh: xh$2,
|
|
|
- xog: xog$2,
|
|
|
- yi: yi$2,
|
|
|
- yo: yo$2,
|
|
|
- yue: yue$2,
|
|
|
- zh: zh$2,
|
|
|
- zu: zu$2
|
|
|
- });
|
|
|
-
|
|
|
- const z = "zero",
|
|
|
- o = "one",
|
|
|
- t = "two",
|
|
|
- f$1 = "few",
|
|
|
- m = "many",
|
|
|
- x = "other";
|
|
|
- const a$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const b$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const c$1 = {
|
|
|
- cardinal: [x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const d$1 = {
|
|
|
- cardinal: [o, t, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const af$1 = a$1;
|
|
|
- const ak$1 = a$1;
|
|
|
- const am$1 = a$1;
|
|
|
- const an$1 = a$1;
|
|
|
- const ar$1 = {
|
|
|
- cardinal: [z, o, t, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const ars$1 = {
|
|
|
- cardinal: [z, o, t, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const as$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, m, x]
|
|
|
- };
|
|
|
- const asa$1 = a$1;
|
|
|
- const ast$1 = a$1;
|
|
|
- const az$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, f$1, m, x]
|
|
|
- };
|
|
|
- const bal$1 = b$1;
|
|
|
- const be$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [f$1, x]
|
|
|
- };
|
|
|
- const bem$1 = a$1;
|
|
|
- const bez$1 = a$1;
|
|
|
- const bg$1 = a$1;
|
|
|
- const bho$1 = a$1;
|
|
|
- const bm$1 = c$1;
|
|
|
- const bn$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, m, x]
|
|
|
- };
|
|
|
- const bo$1 = c$1;
|
|
|
- const br$1 = {
|
|
|
- cardinal: [o, t, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const brx$1 = a$1;
|
|
|
- const bs$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const ca$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [o, t, f$1, x]
|
|
|
- };
|
|
|
- const ce$1 = a$1;
|
|
|
- const ceb$1 = a$1;
|
|
|
- const cgg$1 = a$1;
|
|
|
- const chr$1 = a$1;
|
|
|
- const ckb$1 = a$1;
|
|
|
- const cs$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const cy$1 = {
|
|
|
- cardinal: [z, o, t, f$1, m, x],
|
|
|
- ordinal: [z, o, t, f$1, m, x]
|
|
|
- };
|
|
|
- const da$1 = a$1;
|
|
|
- const de$1 = a$1;
|
|
|
- const doi$1 = a$1;
|
|
|
- const dsb$1 = {
|
|
|
- cardinal: [o, t, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const dv$1 = a$1;
|
|
|
- const dz$1 = c$1;
|
|
|
- const ee$1 = a$1;
|
|
|
- const el$1 = a$1;
|
|
|
- const en$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, x]
|
|
|
- };
|
|
|
- const eo$1 = a$1;
|
|
|
- const es$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const et$1 = a$1;
|
|
|
- const eu$1 = a$1;
|
|
|
- const fa$1 = a$1;
|
|
|
- const ff$1 = a$1;
|
|
|
- const fi$1 = a$1;
|
|
|
- const fil$1 = b$1;
|
|
|
- const fo$1 = a$1;
|
|
|
- const fr$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const fur$1 = a$1;
|
|
|
- const fy$1 = a$1;
|
|
|
- const ga$1 = {
|
|
|
- cardinal: [o, t, f$1, m, x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const gd$1 = {
|
|
|
- cardinal: [o, t, f$1, x],
|
|
|
- ordinal: [o, t, f$1, x]
|
|
|
- };
|
|
|
- const gl$1 = a$1;
|
|
|
- const gsw$1 = a$1;
|
|
|
- const gu$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, m, x]
|
|
|
- };
|
|
|
- const guw$1 = a$1;
|
|
|
- const gv$1 = {
|
|
|
- cardinal: [o, t, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const ha$1 = a$1;
|
|
|
- const haw$1 = a$1;
|
|
|
- const he$1 = d$1;
|
|
|
- const hi$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, m, x]
|
|
|
- };
|
|
|
- const hnj$1 = c$1;
|
|
|
- const hr$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const hsb$1 = {
|
|
|
- cardinal: [o, t, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const hu$1 = b$1;
|
|
|
- const hy$1 = b$1;
|
|
|
- const ia$1 = a$1;
|
|
|
- const id$1 = c$1;
|
|
|
- const ig$1 = c$1;
|
|
|
- const ii$1 = c$1;
|
|
|
- const io$1 = a$1;
|
|
|
- const is$1 = a$1;
|
|
|
- const it$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [m, x]
|
|
|
- };
|
|
|
- const iu$1 = d$1;
|
|
|
- const ja$1 = c$1;
|
|
|
- const jbo$1 = c$1;
|
|
|
- const jgo$1 = a$1;
|
|
|
- const jmc$1 = a$1;
|
|
|
- const jv$1 = c$1;
|
|
|
- const jw$1 = c$1;
|
|
|
- const ka$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, m, x]
|
|
|
- };
|
|
|
- const kab$1 = a$1;
|
|
|
- const kaj$1 = a$1;
|
|
|
- const kcg$1 = a$1;
|
|
|
- const kde$1 = c$1;
|
|
|
- const kea$1 = c$1;
|
|
|
- const kk$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [m, x]
|
|
|
- };
|
|
|
- const kkj$1 = a$1;
|
|
|
- const kl$1 = a$1;
|
|
|
- const km$1 = c$1;
|
|
|
- const kn$1 = a$1;
|
|
|
- const ko$1 = c$1;
|
|
|
- const ks$1 = a$1;
|
|
|
- const ksb$1 = a$1;
|
|
|
- const ksh$1 = {
|
|
|
- cardinal: [z, o, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const ku$1 = a$1;
|
|
|
- const kw$1 = {
|
|
|
- cardinal: [z, o, t, f$1, m, x],
|
|
|
- ordinal: [o, m, x]
|
|
|
- };
|
|
|
- const ky$1 = a$1;
|
|
|
- const lag$1 = {
|
|
|
- cardinal: [z, o, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const lb$1 = a$1;
|
|
|
- const lg$1 = a$1;
|
|
|
- const lij$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [m, x]
|
|
|
- };
|
|
|
- const lkt$1 = c$1;
|
|
|
- const ln$1 = a$1;
|
|
|
- const lo$1 = {
|
|
|
- cardinal: [x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const lt$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const lv$1 = {
|
|
|
- cardinal: [z, o, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const mas$1 = a$1;
|
|
|
- const mg$1 = a$1;
|
|
|
- const mgo$1 = a$1;
|
|
|
- const mk$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, m, x]
|
|
|
- };
|
|
|
- const ml$1 = a$1;
|
|
|
- const mn$1 = a$1;
|
|
|
- const mo$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const mr$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, x]
|
|
|
- };
|
|
|
- const ms$1 = {
|
|
|
- cardinal: [x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const mt$1 = {
|
|
|
- cardinal: [o, t, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const my$1 = c$1;
|
|
|
- const nah$1 = a$1;
|
|
|
- const naq$1 = d$1;
|
|
|
- const nb$1 = a$1;
|
|
|
- const nd$1 = a$1;
|
|
|
- const ne$1 = b$1;
|
|
|
- const nl$1 = a$1;
|
|
|
- const nn$1 = a$1;
|
|
|
- const nnh$1 = a$1;
|
|
|
- const no$1 = a$1;
|
|
|
- const nqo$1 = c$1;
|
|
|
- const nr$1 = a$1;
|
|
|
- const nso$1 = a$1;
|
|
|
- const ny$1 = a$1;
|
|
|
- const nyn$1 = a$1;
|
|
|
- const om$1 = a$1;
|
|
|
- const or$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, t, f$1, m, x]
|
|
|
- };
|
|
|
- const os$1 = a$1;
|
|
|
- const osa$1 = c$1;
|
|
|
- const pa$1 = a$1;
|
|
|
- const pap$1 = a$1;
|
|
|
- const pcm$1 = a$1;
|
|
|
- const pl$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const prg$1 = {
|
|
|
- cardinal: [z, o, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const ps$1 = a$1;
|
|
|
- const pt$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const pt_PT$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const rm$1 = a$1;
|
|
|
- const ro$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const rof$1 = a$1;
|
|
|
- const ru$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const rwk$1 = a$1;
|
|
|
- const sah$1 = c$1;
|
|
|
- const saq$1 = a$1;
|
|
|
- const sat$1 = d$1;
|
|
|
- const sc$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [m, x]
|
|
|
- };
|
|
|
- const scn$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [m, x]
|
|
|
- };
|
|
|
- const sd$1 = a$1;
|
|
|
- const sdh$1 = a$1;
|
|
|
- const se$1 = d$1;
|
|
|
- const seh$1 = a$1;
|
|
|
- const ses$1 = c$1;
|
|
|
- const sg$1 = c$1;
|
|
|
- const sh$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const shi$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const si$1 = a$1;
|
|
|
- const sk$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const sl$1 = {
|
|
|
- cardinal: [o, t, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const sma$1 = d$1;
|
|
|
- const smi$1 = d$1;
|
|
|
- const smj$1 = d$1;
|
|
|
- const smn$1 = d$1;
|
|
|
- const sms$1 = d$1;
|
|
|
- const sn$1 = a$1;
|
|
|
- const so$1 = a$1;
|
|
|
- const sq$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [o, m, x]
|
|
|
- };
|
|
|
- const sr$1 = {
|
|
|
- cardinal: [o, f$1, x],
|
|
|
- ordinal: [x]
|
|
|
- };
|
|
|
- const ss$1 = a$1;
|
|
|
- const ssy$1 = a$1;
|
|
|
- const st$1 = a$1;
|
|
|
- const su$1 = c$1;
|
|
|
- const sv$1 = b$1;
|
|
|
- const sw$1 = a$1;
|
|
|
- const syr$1 = a$1;
|
|
|
- const ta$1 = a$1;
|
|
|
- const te$1 = a$1;
|
|
|
- const teo$1 = a$1;
|
|
|
- const th$1 = c$1;
|
|
|
- const ti$1 = a$1;
|
|
|
- const tig$1 = a$1;
|
|
|
- const tk$1 = {
|
|
|
- cardinal: [o, x],
|
|
|
- ordinal: [f$1, x]
|
|
|
- };
|
|
|
- const tl$1 = b$1;
|
|
|
- const tn$1 = a$1;
|
|
|
- const to$1 = c$1;
|
|
|
- const tpi$1 = c$1;
|
|
|
- const tr$1 = a$1;
|
|
|
- const ts$1 = a$1;
|
|
|
- const tzm$1 = a$1;
|
|
|
- const ug$1 = a$1;
|
|
|
- const uk$1 = {
|
|
|
- cardinal: [o, f$1, m, x],
|
|
|
- ordinal: [f$1, x]
|
|
|
- };
|
|
|
- const und$1 = c$1;
|
|
|
- const ur$1 = a$1;
|
|
|
- const uz$1 = a$1;
|
|
|
- const ve$1 = a$1;
|
|
|
- const vec$1 = {
|
|
|
- cardinal: [o, m, x],
|
|
|
- ordinal: [m, x]
|
|
|
- };
|
|
|
- const vi$1 = {
|
|
|
- cardinal: [x],
|
|
|
- ordinal: [o, x]
|
|
|
- };
|
|
|
- const vo$1 = a$1;
|
|
|
- const vun$1 = a$1;
|
|
|
- const wa$1 = a$1;
|
|
|
- const wae$1 = a$1;
|
|
|
- const wo$1 = c$1;
|
|
|
- const xh$1 = a$1;
|
|
|
- const xog$1 = a$1;
|
|
|
- const yi$1 = a$1;
|
|
|
- const yo$1 = c$1;
|
|
|
- const yue$1 = c$1;
|
|
|
- const zh$1 = c$1;
|
|
|
- const zu$1 = a$1;
|
|
|
-
|
|
|
- var PluralCategories = /*#__PURE__*/Object.freeze({
|
|
|
- __proto__: null,
|
|
|
- af: af$1,
|
|
|
- ak: ak$1,
|
|
|
- am: am$1,
|
|
|
- an: an$1,
|
|
|
- ar: ar$1,
|
|
|
- ars: ars$1,
|
|
|
- as: as$1,
|
|
|
- asa: asa$1,
|
|
|
- ast: ast$1,
|
|
|
- az: az$1,
|
|
|
- bal: bal$1,
|
|
|
- be: be$1,
|
|
|
- bem: bem$1,
|
|
|
- bez: bez$1,
|
|
|
- bg: bg$1,
|
|
|
- bho: bho$1,
|
|
|
- bm: bm$1,
|
|
|
- bn: bn$1,
|
|
|
- bo: bo$1,
|
|
|
- br: br$1,
|
|
|
- brx: brx$1,
|
|
|
- bs: bs$1,
|
|
|
- ca: ca$1,
|
|
|
- ce: ce$1,
|
|
|
- ceb: ceb$1,
|
|
|
- cgg: cgg$1,
|
|
|
- chr: chr$1,
|
|
|
- ckb: ckb$1,
|
|
|
- cs: cs$1,
|
|
|
- cy: cy$1,
|
|
|
- da: da$1,
|
|
|
- de: de$1,
|
|
|
- doi: doi$1,
|
|
|
- dsb: dsb$1,
|
|
|
- dv: dv$1,
|
|
|
- dz: dz$1,
|
|
|
- ee: ee$1,
|
|
|
- el: el$1,
|
|
|
- en: en$1,
|
|
|
- eo: eo$1,
|
|
|
- es: es$1,
|
|
|
- et: et$1,
|
|
|
- eu: eu$1,
|
|
|
- fa: fa$1,
|
|
|
- ff: ff$1,
|
|
|
- fi: fi$1,
|
|
|
- fil: fil$1,
|
|
|
- fo: fo$1,
|
|
|
- fr: fr$1,
|
|
|
- fur: fur$1,
|
|
|
- fy: fy$1,
|
|
|
- ga: ga$1,
|
|
|
- gd: gd$1,
|
|
|
- gl: gl$1,
|
|
|
- gsw: gsw$1,
|
|
|
- gu: gu$1,
|
|
|
- guw: guw$1,
|
|
|
- gv: gv$1,
|
|
|
- ha: ha$1,
|
|
|
- haw: haw$1,
|
|
|
- he: he$1,
|
|
|
- hi: hi$1,
|
|
|
- hnj: hnj$1,
|
|
|
- hr: hr$1,
|
|
|
- hsb: hsb$1,
|
|
|
- hu: hu$1,
|
|
|
- hy: hy$1,
|
|
|
- ia: ia$1,
|
|
|
- id: id$1,
|
|
|
- ig: ig$1,
|
|
|
- ii: ii$1,
|
|
|
- io: io$1,
|
|
|
- is: is$1,
|
|
|
- it: it$1,
|
|
|
- iu: iu$1,
|
|
|
- ja: ja$1,
|
|
|
- jbo: jbo$1,
|
|
|
- jgo: jgo$1,
|
|
|
- jmc: jmc$1,
|
|
|
- jv: jv$1,
|
|
|
- jw: jw$1,
|
|
|
- ka: ka$1,
|
|
|
- kab: kab$1,
|
|
|
- kaj: kaj$1,
|
|
|
- kcg: kcg$1,
|
|
|
- kde: kde$1,
|
|
|
- kea: kea$1,
|
|
|
- kk: kk$1,
|
|
|
- kkj: kkj$1,
|
|
|
- kl: kl$1,
|
|
|
- km: km$1,
|
|
|
- kn: kn$1,
|
|
|
- ko: ko$1,
|
|
|
- ks: ks$1,
|
|
|
- ksb: ksb$1,
|
|
|
- ksh: ksh$1,
|
|
|
- ku: ku$1,
|
|
|
- kw: kw$1,
|
|
|
- ky: ky$1,
|
|
|
- lag: lag$1,
|
|
|
- lb: lb$1,
|
|
|
- lg: lg$1,
|
|
|
- lij: lij$1,
|
|
|
- lkt: lkt$1,
|
|
|
- ln: ln$1,
|
|
|
- lo: lo$1,
|
|
|
- lt: lt$1,
|
|
|
- lv: lv$1,
|
|
|
- mas: mas$1,
|
|
|
- mg: mg$1,
|
|
|
- mgo: mgo$1,
|
|
|
- mk: mk$1,
|
|
|
- ml: ml$1,
|
|
|
- mn: mn$1,
|
|
|
- mo: mo$1,
|
|
|
- mr: mr$1,
|
|
|
- ms: ms$1,
|
|
|
- mt: mt$1,
|
|
|
- my: my$1,
|
|
|
- nah: nah$1,
|
|
|
- naq: naq$1,
|
|
|
- nb: nb$1,
|
|
|
- nd: nd$1,
|
|
|
- ne: ne$1,
|
|
|
- nl: nl$1,
|
|
|
- nn: nn$1,
|
|
|
- nnh: nnh$1,
|
|
|
- no: no$1,
|
|
|
- nqo: nqo$1,
|
|
|
- nr: nr$1,
|
|
|
- nso: nso$1,
|
|
|
- ny: ny$1,
|
|
|
- nyn: nyn$1,
|
|
|
- om: om$1,
|
|
|
- or: or$1,
|
|
|
- os: os$1,
|
|
|
- osa: osa$1,
|
|
|
- pa: pa$1,
|
|
|
- pap: pap$1,
|
|
|
- pcm: pcm$1,
|
|
|
- pl: pl$1,
|
|
|
- prg: prg$1,
|
|
|
- ps: ps$1,
|
|
|
- pt: pt$1,
|
|
|
- pt_PT: pt_PT$1,
|
|
|
- rm: rm$1,
|
|
|
- ro: ro$1,
|
|
|
- rof: rof$1,
|
|
|
- ru: ru$1,
|
|
|
- rwk: rwk$1,
|
|
|
- sah: sah$1,
|
|
|
- saq: saq$1,
|
|
|
- sat: sat$1,
|
|
|
- sc: sc$1,
|
|
|
- scn: scn$1,
|
|
|
- sd: sd$1,
|
|
|
- sdh: sdh$1,
|
|
|
- se: se$1,
|
|
|
- seh: seh$1,
|
|
|
- ses: ses$1,
|
|
|
- sg: sg$1,
|
|
|
- sh: sh$1,
|
|
|
- shi: shi$1,
|
|
|
- si: si$1,
|
|
|
- sk: sk$1,
|
|
|
- sl: sl$1,
|
|
|
- sma: sma$1,
|
|
|
- smi: smi$1,
|
|
|
- smj: smj$1,
|
|
|
- smn: smn$1,
|
|
|
- sms: sms$1,
|
|
|
- sn: sn$1,
|
|
|
- so: so$1,
|
|
|
- sq: sq$1,
|
|
|
- sr: sr$1,
|
|
|
- ss: ss$1,
|
|
|
- ssy: ssy$1,
|
|
|
- st: st$1,
|
|
|
- su: su$1,
|
|
|
- sv: sv$1,
|
|
|
- sw: sw$1,
|
|
|
- syr: syr$1,
|
|
|
- ta: ta$1,
|
|
|
- te: te$1,
|
|
|
- teo: teo$1,
|
|
|
- th: th$1,
|
|
|
- ti: ti$1,
|
|
|
- tig: tig$1,
|
|
|
- tk: tk$1,
|
|
|
- tl: tl$1,
|
|
|
- tn: tn$1,
|
|
|
- to: to$1,
|
|
|
- tpi: tpi$1,
|
|
|
- tr: tr$1,
|
|
|
- ts: ts$1,
|
|
|
- tzm: tzm$1,
|
|
|
- ug: ug$1,
|
|
|
- uk: uk$1,
|
|
|
- und: und$1,
|
|
|
- ur: ur$1,
|
|
|
- uz: uz$1,
|
|
|
- ve: ve$1,
|
|
|
- vec: vec$1,
|
|
|
- vi: vi$1,
|
|
|
- vo: vo$1,
|
|
|
- vun: vun$1,
|
|
|
- wa: wa$1,
|
|
|
- wae: wae$1,
|
|
|
- wo: wo$1,
|
|
|
- xh: xh$1,
|
|
|
- xog: xog$1,
|
|
|
- yi: yi$1,
|
|
|
- yo: yo$1,
|
|
|
- yue: yue$1,
|
|
|
- zh: zh$1,
|
|
|
- zu: zu$1
|
|
|
- });
|
|
|
-
|
|
|
- const a = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const b = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 || n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const c = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n >= 0 && n <= 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const d = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1];
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const e = (n, ord) => 'other';
|
|
|
- const f = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 ? 'one' : n == 2 ? 'two' : 'other';
|
|
|
- };
|
|
|
- const af = a;
|
|
|
- const ak = b;
|
|
|
- const am = c;
|
|
|
- const an = a;
|
|
|
- const ar = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n100 >= 3 && n100 <= 10 ? 'few' : n100 >= 11 && n100 <= 99 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ars = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n100 >= 3 && n100 <= 10 ? 'few' : n100 >= 11 && n100 <= 99 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const as = (n, ord) => {
|
|
|
- if (ord) return n == 1 || n == 5 || n == 7 || n == 8 || n == 9 || n == 10 ? 'one' : n == 2 || n == 3 ? 'two' : n == 4 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- return n >= 0 && n <= 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const asa = a;
|
|
|
- const ast = d;
|
|
|
- const az = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- i1000 = i.slice(-3);
|
|
|
- if (ord) return i10 == 1 || i10 == 2 || i10 == 5 || i10 == 7 || i10 == 8 || i100 == 20 || i100 == 50 || i100 == 70 || i100 == 80 ? 'one' : i10 == 3 || i10 == 4 || i1000 == 100 || i1000 == 200 || i1000 == 300 || i1000 == 400 || i1000 == 500 || i1000 == 600 || i1000 == 700 || i1000 == 800 || i1000 == 900 ? 'few' : i == 0 || i10 == 6 || i100 == 40 || i100 == 60 || i100 == 90 ? 'many' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const bal = (n, ord) => n == 1 ? 'one' : 'other';
|
|
|
- const be = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return (n10 == 2 || n10 == 3) && n100 != 12 && n100 != 13 ? 'few' : 'other';
|
|
|
- return n10 == 1 && n100 != 11 ? 'one' : n10 >= 2 && n10 <= 4 && (n100 < 12 || n100 > 14) ? 'few' : t0 && n10 == 0 || n10 >= 5 && n10 <= 9 || n100 >= 11 && n100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const bem = a;
|
|
|
- const bez = a;
|
|
|
- const bg = a;
|
|
|
- const bho = b;
|
|
|
- const bm = e;
|
|
|
- const bn = (n, ord) => {
|
|
|
- if (ord) return n == 1 || n == 5 || n == 7 || n == 8 || n == 9 || n == 10 ? 'one' : n == 2 || n == 3 ? 'two' : n == 4 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- return n >= 0 && n <= 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const bo = e;
|
|
|
- const br = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- n1000000 = t0 && s[0].slice(-6);
|
|
|
- if (ord) return 'other';
|
|
|
- return n10 == 1 && n100 != 11 && n100 != 71 && n100 != 91 ? 'one' : n10 == 2 && n100 != 12 && n100 != 72 && n100 != 92 ? 'two' : (n10 == 3 || n10 == 4 || n10 == 9) && (n100 < 10 || n100 > 19) && (n100 < 70 || n100 > 79) && (n100 < 90 || n100 > 99) ? 'few' : n != 0 && t0 && n1000000 == 0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const brx = a;
|
|
|
- const bs = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const ca = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return n == 1 || n == 3 ? 'one' : n == 2 ? 'two' : n == 4 ? 'few' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ce = a;
|
|
|
- const ceb = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- f10 = f.slice(-1);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && (i == 1 || i == 2 || i == 3) || v0 && i10 != 4 && i10 != 6 && i10 != 9 || !v0 && f10 != 4 && f10 != 6 && f10 != 9 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const cgg = a;
|
|
|
- const chr = a;
|
|
|
- const ckb = a;
|
|
|
- const cs = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1];
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 && v0 ? 'one' : i >= 2 && i <= 4 && v0 ? 'few' : !v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const cy = (n, ord) => {
|
|
|
- if (ord) return n == 0 || n == 7 || n == 8 || n == 9 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n == 3 || n == 4 ? 'few' : n == 5 || n == 6 ? 'many' : 'other';
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n == 2 ? 'two' : n == 3 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const da = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 || !t0 && (i == 0 || i == 1) ? 'one' : 'other';
|
|
|
- };
|
|
|
- const de = d;
|
|
|
- const doi = c;
|
|
|
- const dsb = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i100 = i.slice(-2),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i100 == 1 || f100 == 1 ? 'one' : v0 && i100 == 2 || f100 == 2 ? 'two' : v0 && (i100 == 3 || i100 == 4) || f100 == 3 || f100 == 4 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const dv = a;
|
|
|
- const dz = e;
|
|
|
- const ee = a;
|
|
|
- const el = a;
|
|
|
- const en = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return n10 == 1 && n100 != 11 ? 'one' : n10 == 2 && n100 != 12 ? 'two' : n10 == 3 && n100 != 13 ? 'few' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const eo = a;
|
|
|
- const es = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const et = d;
|
|
|
- const eu = a;
|
|
|
- const fa = c;
|
|
|
- const ff = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n >= 0 && n < 2 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const fi = d;
|
|
|
- const fil = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- f10 = f.slice(-1);
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return v0 && (i == 1 || i == 2 || i == 3) || v0 && i10 != 4 && i10 != 6 && i10 != 9 || !v0 && f10 != 4 && f10 != 6 && f10 != 9 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const fo = a;
|
|
|
- const fr = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return n >= 0 && n < 2 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const fur = a;
|
|
|
- const fy = d;
|
|
|
- const ga = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return n == 1 ? 'one' : n == 2 ? 'two' : t0 && n >= 3 && n <= 6 ? 'few' : t0 && n >= 7 && n <= 10 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const gd = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return n == 1 || n == 11 ? 'one' : n == 2 || n == 12 ? 'two' : n == 3 || n == 13 ? 'few' : 'other';
|
|
|
- return n == 1 || n == 11 ? 'one' : n == 2 || n == 12 ? 'two' : t0 && n >= 3 && n <= 10 || t0 && n >= 13 && n <= 19 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const gl = d;
|
|
|
- const gsw = a;
|
|
|
- const gu = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : n == 2 || n == 3 ? 'two' : n == 4 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- return n >= 0 && n <= 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const guw = b;
|
|
|
- const gv = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i10 == 1 ? 'one' : v0 && i10 == 2 ? 'two' : v0 && (i100 == 0 || i100 == 20 || i100 == 40 || i100 == 60 || i100 == 80) ? 'few' : !v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ha = a;
|
|
|
- const haw = a;
|
|
|
- const he = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1];
|
|
|
- if (ord) return 'other';
|
|
|
- return i == 1 && v0 || i == 0 && !v0 ? 'one' : i == 2 && v0 ? 'two' : 'other';
|
|
|
- };
|
|
|
- const hi = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : n == 2 || n == 3 ? 'two' : n == 4 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- return n >= 0 && n <= 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const hnj = e;
|
|
|
- const hr = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const hsb = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i100 = i.slice(-2),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i100 == 1 || f100 == 1 ? 'one' : v0 && i100 == 2 || f100 == 2 ? 'two' : v0 && (i100 == 3 || i100 == 4) || f100 == 3 || f100 == 4 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const hu = (n, ord) => {
|
|
|
- if (ord) return n == 1 || n == 5 ? 'one' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const hy = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return n >= 0 && n < 2 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ia = d;
|
|
|
- const id = e;
|
|
|
- const ig = e;
|
|
|
- const ii = e;
|
|
|
- const io = d;
|
|
|
- const is = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- t = (s[1] || '').replace(/0+$/, ''),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return t0 && i10 == 1 && i100 != 11 || t % 10 == 1 && t % 100 != 11 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const it = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return n == 11 || n == 8 || n == 80 || n == 800 ? 'many' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const iu = f;
|
|
|
- const ja = e;
|
|
|
- const jbo = e;
|
|
|
- const jgo = a;
|
|
|
- const jmc = a;
|
|
|
- const jv = e;
|
|
|
- const jw = e;
|
|
|
- const ka = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return i == 1 ? 'one' : i == 0 || i100 >= 2 && i100 <= 20 || i100 == 40 || i100 == 60 || i100 == 80 ? 'many' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const kab = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n >= 0 && n < 2 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const kaj = a;
|
|
|
- const kcg = a;
|
|
|
- const kde = e;
|
|
|
- const kea = e;
|
|
|
- const kk = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1);
|
|
|
- if (ord) return n10 == 6 || n10 == 9 || t0 && n10 == 0 && n != 0 ? 'many' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const kkj = a;
|
|
|
- const kl = a;
|
|
|
- const km = e;
|
|
|
- const kn = c;
|
|
|
- const ko = e;
|
|
|
- const ks = a;
|
|
|
- const ksb = a;
|
|
|
- const ksh = (n, ord) => {
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ku = a;
|
|
|
- const kw = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- n1000 = t0 && s[0].slice(-3),
|
|
|
- n100000 = t0 && s[0].slice(-5),
|
|
|
- n1000000 = t0 && s[0].slice(-6);
|
|
|
- if (ord) return t0 && n >= 1 && n <= 4 || n100 >= 1 && n100 <= 4 || n100 >= 21 && n100 <= 24 || n100 >= 41 && n100 <= 44 || n100 >= 61 && n100 <= 64 || n100 >= 81 && n100 <= 84 ? 'one' : n == 5 || n100 == 5 ? 'many' : 'other';
|
|
|
- return n == 0 ? 'zero' : n == 1 ? 'one' : n100 == 2 || n100 == 22 || n100 == 42 || n100 == 62 || n100 == 82 || t0 && n1000 == 0 && (n100000 >= 1000 && n100000 <= 20000 || n100000 == 40000 || n100000 == 60000 || n100000 == 80000) || n != 0 && n1000000 == 100000 ? 'two' : n100 == 3 || n100 == 23 || n100 == 43 || n100 == 63 || n100 == 83 ? 'few' : n != 1 && (n100 == 1 || n100 == 21 || n100 == 41 || n100 == 61 || n100 == 81) ? 'many' : 'other';
|
|
|
- };
|
|
|
- const ky = a;
|
|
|
- const lag = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0];
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 ? 'zero' : (i == 0 || i == 1) && n != 0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const lb = a;
|
|
|
- const lg = a;
|
|
|
- const lij = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return n == 11 || n == 8 || t0 && n >= 80 && n <= 89 || t0 && n >= 800 && n <= 899 ? 'many' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const lkt = e;
|
|
|
- const ln = b;
|
|
|
- const lo = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return 'other';
|
|
|
- };
|
|
|
- const lt = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- f = s[1] || '',
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return n10 == 1 && (n100 < 11 || n100 > 19) ? 'one' : n10 >= 2 && n10 <= 9 && (n100 < 11 || n100 > 19) ? 'few' : f != 0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const lv = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- f = s[1] || '',
|
|
|
- v = f.length,
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- f100 = f.slice(-2),
|
|
|
- f10 = f.slice(-1);
|
|
|
- if (ord) return 'other';
|
|
|
- return t0 && n10 == 0 || n100 >= 11 && n100 <= 19 || v == 2 && f100 >= 11 && f100 <= 19 ? 'zero' : n10 == 1 && n100 != 11 || v == 2 && f10 == 1 && f100 != 11 || v != 2 && f10 == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const mas = a;
|
|
|
- const mg = b;
|
|
|
- const mgo = a;
|
|
|
- const mk = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return i10 == 1 && i100 != 11 ? 'one' : i10 == 2 && i100 != 12 ? 'two' : (i10 == 7 || i10 == 8) && i100 != 17 && i100 != 18 ? 'many' : 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ml = a;
|
|
|
- const mn = a;
|
|
|
- const mo = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : !v0 || n == 0 || n != 1 && n100 >= 1 && n100 <= 19 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const mr = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : n == 2 || n == 3 ? 'two' : n == 4 ? 'few' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ms = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return 'other';
|
|
|
- };
|
|
|
- const mt = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 ? 'one' : n == 2 ? 'two' : n == 0 || n100 >= 3 && n100 <= 10 ? 'few' : n100 >= 11 && n100 <= 19 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const my = e;
|
|
|
- const nah = a;
|
|
|
- const naq = f;
|
|
|
- const nb = a;
|
|
|
- const nd = a;
|
|
|
- const ne = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return t0 && n >= 1 && n <= 4 ? 'one' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const nl = d;
|
|
|
- const nn = a;
|
|
|
- const nnh = a;
|
|
|
- const no = a;
|
|
|
- const nqo = e;
|
|
|
- const nr = a;
|
|
|
- const nso = b;
|
|
|
- const ny = a;
|
|
|
- const nyn = a;
|
|
|
- const om = a;
|
|
|
- const or = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return n == 1 || n == 5 || t0 && n >= 7 && n <= 9 ? 'one' : n == 2 || n == 3 ? 'two' : n == 4 ? 'few' : n == 6 ? 'many' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const os = a;
|
|
|
- const osa = e;
|
|
|
- const pa = b;
|
|
|
- const pap = a;
|
|
|
- const pcm = c;
|
|
|
- const pl = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 && v0 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) ? 'few' : v0 && i != 1 && (i10 == 0 || i10 == 1) || v0 && i10 >= 5 && i10 <= 9 || v0 && i100 >= 12 && i100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const prg = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- f = s[1] || '',
|
|
|
- v = f.length,
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- f100 = f.slice(-2),
|
|
|
- f10 = f.slice(-1);
|
|
|
- if (ord) return 'other';
|
|
|
- return t0 && n10 == 0 || n100 >= 11 && n100 <= 19 || v == 2 && f100 >= 11 && f100 <= 19 ? 'zero' : n10 == 1 && n100 != 11 || v == 2 && f10 == 1 && f100 != 11 || v != 2 && f10 == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ps = a;
|
|
|
- const pt = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return 'other';
|
|
|
- return i == 0 || i == 1 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const pt_PT = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const rm = a;
|
|
|
- const ro = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : !v0 || n == 0 || n != 1 && n100 >= 1 && n100 <= 19 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const rof = a;
|
|
|
- const ru = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) ? 'few' : v0 && i10 == 0 || v0 && i10 >= 5 && i10 <= 9 || v0 && i100 >= 11 && i100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const rwk = a;
|
|
|
- const sah = e;
|
|
|
- const saq = a;
|
|
|
- const sat = f;
|
|
|
- const sc = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1];
|
|
|
- if (ord) return n == 11 || n == 8 || n == 80 || n == 800 ? 'many' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const scn = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1];
|
|
|
- if (ord) return n == 11 || n == 8 || n == 80 || n == 800 ? 'many' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const sd = a;
|
|
|
- const sdh = a;
|
|
|
- const se = f;
|
|
|
- const seh = a;
|
|
|
- const ses = e;
|
|
|
- const sg = e;
|
|
|
- const sh = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const shi = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return 'other';
|
|
|
- return n >= 0 && n <= 1 ? 'one' : t0 && n >= 2 && n <= 10 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const si = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '';
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 || n == 1 || i == 0 && f == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const sk = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1];
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 1 && v0 ? 'one' : i >= 2 && i <= 4 && v0 ? 'few' : !v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const sl = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i100 == 1 ? 'one' : v0 && i100 == 2 ? 'two' : v0 && (i100 == 3 || i100 == 4) || !v0 ? 'few' : 'other';
|
|
|
- };
|
|
|
- const sma = f;
|
|
|
- const smi = f;
|
|
|
- const smj = f;
|
|
|
- const smn = f;
|
|
|
- const sms = f;
|
|
|
- const sn = a;
|
|
|
- const so = a;
|
|
|
- const sq = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return n == 1 ? 'one' : n10 == 4 && n100 != 14 ? 'many' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const sr = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2),
|
|
|
- f10 = f.slice(-1),
|
|
|
- f100 = f.slice(-2);
|
|
|
- if (ord) return 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 || f10 == 1 && f100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) || f10 >= 2 && f10 <= 4 && (f100 < 12 || f100 > 14) ? 'few' : 'other';
|
|
|
- };
|
|
|
- const ss = a;
|
|
|
- const ssy = a;
|
|
|
- const st = a;
|
|
|
- const su = e;
|
|
|
- const sv = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2);
|
|
|
- if (ord) return (n10 == 1 || n10 == 2) && n100 != 11 && n100 != 12 ? 'one' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const sw = d;
|
|
|
- const syr = a;
|
|
|
- const ta = a;
|
|
|
- const te = a;
|
|
|
- const teo = a;
|
|
|
- const th = e;
|
|
|
- const ti = b;
|
|
|
- const tig = a;
|
|
|
- const tk = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1);
|
|
|
- if (ord) return n10 == 6 || n10 == 9 || n == 10 ? 'few' : 'other';
|
|
|
- return n == 1 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const tl = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- f = s[1] || '',
|
|
|
- v0 = !s[1],
|
|
|
- i10 = i.slice(-1),
|
|
|
- f10 = f.slice(-1);
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return v0 && (i == 1 || i == 2 || i == 3) || v0 && i10 != 4 && i10 != 6 && i10 != 9 || !v0 && f10 != 4 && f10 != 6 && f10 != 9 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const tn = a;
|
|
|
- const to = e;
|
|
|
- const tpi = e;
|
|
|
- const tr = a;
|
|
|
- const ts = a;
|
|
|
- const tzm = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- t0 = Number(s[0]) == n;
|
|
|
- if (ord) return 'other';
|
|
|
- return n == 0 || n == 1 || t0 && n >= 11 && n <= 99 ? 'one' : 'other';
|
|
|
- };
|
|
|
- const ug = a;
|
|
|
- const uk = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- t0 = Number(s[0]) == n,
|
|
|
- n10 = t0 && s[0].slice(-1),
|
|
|
- n100 = t0 && s[0].slice(-2),
|
|
|
- i10 = i.slice(-1),
|
|
|
- i100 = i.slice(-2);
|
|
|
- if (ord) return n10 == 3 && n100 != 13 ? 'few' : 'other';
|
|
|
- return v0 && i10 == 1 && i100 != 11 ? 'one' : v0 && i10 >= 2 && i10 <= 4 && (i100 < 12 || i100 > 14) ? 'few' : v0 && i10 == 0 || v0 && i10 >= 5 && i10 <= 9 || v0 && i100 >= 11 && i100 <= 14 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const und = e;
|
|
|
- const ur = d;
|
|
|
- const uz = a;
|
|
|
- const ve = a;
|
|
|
- const vec = (n, ord) => {
|
|
|
- const s = String(n).split('.'),
|
|
|
- i = s[0],
|
|
|
- v0 = !s[1],
|
|
|
- i1000000 = i.slice(-6);
|
|
|
- if (ord) return n == 11 || n == 8 || n == 80 || n == 800 ? 'many' : 'other';
|
|
|
- return n == 1 && v0 ? 'one' : i != 0 && i1000000 == 0 && v0 ? 'many' : 'other';
|
|
|
- };
|
|
|
- const vi = (n, ord) => {
|
|
|
- if (ord) return n == 1 ? 'one' : 'other';
|
|
|
- return 'other';
|
|
|
- };
|
|
|
- const vo = a;
|
|
|
- const vun = a;
|
|
|
- const wa = b;
|
|
|
- const wae = a;
|
|
|
- const wo = e;
|
|
|
- const xh = a;
|
|
|
- const xog = a;
|
|
|
- const yi = d;
|
|
|
- const yo = e;
|
|
|
- const yue = e;
|
|
|
- const zh = e;
|
|
|
- const zu = c;
|
|
|
-
|
|
|
- var Plurals = /*#__PURE__*/Object.freeze({
|
|
|
- __proto__: null,
|
|
|
- af: af,
|
|
|
- ak: ak,
|
|
|
- am: am,
|
|
|
- an: an,
|
|
|
- ar: ar,
|
|
|
- ars: ars,
|
|
|
- as: as,
|
|
|
- asa: asa,
|
|
|
- ast: ast,
|
|
|
- az: az,
|
|
|
- bal: bal,
|
|
|
- be: be,
|
|
|
- bem: bem,
|
|
|
- bez: bez,
|
|
|
- bg: bg,
|
|
|
- bho: bho,
|
|
|
- bm: bm,
|
|
|
- bn: bn,
|
|
|
- bo: bo,
|
|
|
- br: br,
|
|
|
- brx: brx,
|
|
|
- bs: bs,
|
|
|
- ca: ca,
|
|
|
- ce: ce,
|
|
|
- ceb: ceb,
|
|
|
- cgg: cgg,
|
|
|
- chr: chr,
|
|
|
- ckb: ckb,
|
|
|
- cs: cs,
|
|
|
- cy: cy,
|
|
|
- da: da,
|
|
|
- de: de,
|
|
|
- doi: doi,
|
|
|
- dsb: dsb,
|
|
|
- dv: dv,
|
|
|
- dz: dz,
|
|
|
- ee: ee,
|
|
|
- el: el,
|
|
|
- en: en,
|
|
|
- eo: eo,
|
|
|
- es: es,
|
|
|
- et: et,
|
|
|
- eu: eu,
|
|
|
- fa: fa,
|
|
|
- ff: ff,
|
|
|
- fi: fi,
|
|
|
- fil: fil,
|
|
|
- fo: fo,
|
|
|
- fr: fr,
|
|
|
- fur: fur,
|
|
|
- fy: fy,
|
|
|
- ga: ga,
|
|
|
- gd: gd,
|
|
|
- gl: gl,
|
|
|
- gsw: gsw,
|
|
|
- gu: gu,
|
|
|
- guw: guw,
|
|
|
- gv: gv,
|
|
|
- ha: ha,
|
|
|
- haw: haw,
|
|
|
- he: he,
|
|
|
- hi: hi,
|
|
|
- hnj: hnj,
|
|
|
- hr: hr,
|
|
|
- hsb: hsb,
|
|
|
- hu: hu,
|
|
|
- hy: hy,
|
|
|
- ia: ia,
|
|
|
- id: id,
|
|
|
- ig: ig,
|
|
|
- ii: ii,
|
|
|
- io: io,
|
|
|
- is: is,
|
|
|
- it: it,
|
|
|
- iu: iu,
|
|
|
- ja: ja,
|
|
|
- jbo: jbo,
|
|
|
- jgo: jgo,
|
|
|
- jmc: jmc,
|
|
|
- jv: jv,
|
|
|
- jw: jw,
|
|
|
- ka: ka,
|
|
|
- kab: kab,
|
|
|
- kaj: kaj,
|
|
|
- kcg: kcg,
|
|
|
- kde: kde,
|
|
|
- kea: kea,
|
|
|
- kk: kk,
|
|
|
- kkj: kkj,
|
|
|
- kl: kl,
|
|
|
- km: km,
|
|
|
- kn: kn,
|
|
|
- ko: ko,
|
|
|
- ks: ks,
|
|
|
- ksb: ksb,
|
|
|
- ksh: ksh,
|
|
|
- ku: ku,
|
|
|
- kw: kw,
|
|
|
- ky: ky,
|
|
|
- lag: lag,
|
|
|
- lb: lb,
|
|
|
- lg: lg,
|
|
|
- lij: lij,
|
|
|
- lkt: lkt,
|
|
|
- ln: ln,
|
|
|
- lo: lo,
|
|
|
- lt: lt,
|
|
|
- lv: lv,
|
|
|
- mas: mas,
|
|
|
- mg: mg,
|
|
|
- mgo: mgo,
|
|
|
- mk: mk,
|
|
|
- ml: ml,
|
|
|
- mn: mn,
|
|
|
- mo: mo,
|
|
|
- mr: mr,
|
|
|
- ms: ms,
|
|
|
- mt: mt,
|
|
|
- my: my,
|
|
|
- nah: nah,
|
|
|
- naq: naq,
|
|
|
- nb: nb,
|
|
|
- nd: nd,
|
|
|
- ne: ne,
|
|
|
- nl: nl,
|
|
|
- nn: nn,
|
|
|
- nnh: nnh,
|
|
|
- no: no,
|
|
|
- nqo: nqo,
|
|
|
- nr: nr,
|
|
|
- nso: nso,
|
|
|
- ny: ny,
|
|
|
- nyn: nyn,
|
|
|
- om: om,
|
|
|
- or: or,
|
|
|
- os: os,
|
|
|
- osa: osa,
|
|
|
- pa: pa,
|
|
|
- pap: pap,
|
|
|
- pcm: pcm,
|
|
|
- pl: pl,
|
|
|
- prg: prg,
|
|
|
- ps: ps,
|
|
|
- pt: pt,
|
|
|
- pt_PT: pt_PT,
|
|
|
- rm: rm,
|
|
|
- ro: ro,
|
|
|
- rof: rof,
|
|
|
- ru: ru,
|
|
|
- rwk: rwk,
|
|
|
- sah: sah,
|
|
|
- saq: saq,
|
|
|
- sat: sat,
|
|
|
- sc: sc,
|
|
|
- scn: scn,
|
|
|
- sd: sd,
|
|
|
- sdh: sdh,
|
|
|
- se: se,
|
|
|
- seh: seh,
|
|
|
- ses: ses,
|
|
|
- sg: sg,
|
|
|
- sh: sh,
|
|
|
- shi: shi,
|
|
|
- si: si,
|
|
|
- sk: sk,
|
|
|
- sl: sl,
|
|
|
- sma: sma,
|
|
|
- smi: smi,
|
|
|
- smj: smj,
|
|
|
- smn: smn,
|
|
|
- sms: sms,
|
|
|
- sn: sn,
|
|
|
- so: so,
|
|
|
- sq: sq,
|
|
|
- sr: sr,
|
|
|
- ss: ss,
|
|
|
- ssy: ssy,
|
|
|
- st: st,
|
|
|
- su: su,
|
|
|
- sv: sv,
|
|
|
- sw: sw,
|
|
|
- syr: syr,
|
|
|
- ta: ta,
|
|
|
- te: te,
|
|
|
- teo: teo,
|
|
|
- th: th,
|
|
|
- ti: ti,
|
|
|
- tig: tig,
|
|
|
- tk: tk,
|
|
|
- tl: tl,
|
|
|
- tn: tn,
|
|
|
- to: to,
|
|
|
- tpi: tpi,
|
|
|
- tr: tr,
|
|
|
- ts: ts,
|
|
|
- tzm: tzm,
|
|
|
- ug: ug,
|
|
|
- uk: uk,
|
|
|
- und: und,
|
|
|
- ur: ur,
|
|
|
- uz: uz,
|
|
|
- ve: ve,
|
|
|
- vec: vec,
|
|
|
- vi: vi,
|
|
|
- vo: vo,
|
|
|
- vun: vun,
|
|
|
- wa: wa,
|
|
|
- wae: wae,
|
|
|
- wo: wo,
|
|
|
- xh: xh,
|
|
|
- xog: xog,
|
|
|
- yi: yi,
|
|
|
- yo: yo,
|
|
|
- yue: yue,
|
|
|
- zh: zh,
|
|
|
- zu: zu
|
|
|
- });
|
|
|
-
|
|
|
- function normalize(locale) {
|
|
|
- if (typeof locale !== 'string' || locale.length < 2)
|
|
|
- throw new RangeError("Invalid language tag: ".concat(locale));
|
|
|
- if (locale.startsWith('pt-PT'))
|
|
|
- return 'pt-PT';
|
|
|
- var m = locale.match(/.+?(?=[-_])/);
|
|
|
- return m ? m[0] : locale;
|
|
|
- }
|
|
|
- function getPlural(locale) {
|
|
|
- if (typeof locale === 'function') {
|
|
|
- var lc_1 = normalize(locale.name);
|
|
|
- return {
|
|
|
- isDefault: false,
|
|
|
- id: identifier(lc_1),
|
|
|
- lc: lc_1,
|
|
|
- locale: locale.name,
|
|
|
- getPlural: locale,
|
|
|
- cardinals: locale.cardinals || [],
|
|
|
- ordinals: locale.ordinals || []
|
|
|
- };
|
|
|
- }
|
|
|
- var lc = normalize(locale);
|
|
|
- var id = identifier(lc);
|
|
|
- if (isPluralId(id)) {
|
|
|
- return {
|
|
|
- isDefault: true,
|
|
|
- id: id,
|
|
|
- lc: lc,
|
|
|
- locale: locale,
|
|
|
- getCardinal: Cardinals[id],
|
|
|
- getPlural: Plurals[id],
|
|
|
- cardinals: PluralCategories[id].cardinal,
|
|
|
- ordinals: PluralCategories[id].ordinal
|
|
|
- };
|
|
|
- }
|
|
|
- return null;
|
|
|
- }
|
|
|
- function getAllPlurals(firstLocale) {
|
|
|
- var keys = Object.keys(Plurals).filter(function (key) { return key !== firstLocale; });
|
|
|
- keys.unshift(firstLocale);
|
|
|
- return keys.map(getPlural);
|
|
|
- }
|
|
|
- function hasPlural(locale) {
|
|
|
- var lc = normalize(locale);
|
|
|
- return identifier(lc) in Plurals;
|
|
|
- }
|
|
|
- function isPluralId(id) {
|
|
|
- return id in Plurals;
|
|
|
- }
|
|
|
-
|
|
|
- var MessageFormat = (function () {
|
|
|
- function MessageFormat(locale, options) {
|
|
|
- this.plurals = [];
|
|
|
- this.options = Object.assign({
|
|
|
- biDiSupport: false,
|
|
|
- currency: 'USD',
|
|
|
- customFormatters: {},
|
|
|
- localeCodeFromKey: null,
|
|
|
- requireAllArguments: false,
|
|
|
- returnType: 'string',
|
|
|
- strict: (options && options.strictNumberSign) || false,
|
|
|
- strictPluralKeys: true
|
|
|
- }, options);
|
|
|
- if (locale === '*') {
|
|
|
- this.plurals = getAllPlurals(MessageFormat.defaultLocale);
|
|
|
- }
|
|
|
- else if (Array.isArray(locale)) {
|
|
|
- this.plurals = locale.map(getPlural).filter(Boolean);
|
|
|
- }
|
|
|
- else if (locale) {
|
|
|
- var pl = getPlural(locale);
|
|
|
- if (pl)
|
|
|
- this.plurals = [pl];
|
|
|
- }
|
|
|
- if (this.plurals.length === 0) {
|
|
|
- var pl = getPlural(MessageFormat.defaultLocale);
|
|
|
- this.plurals = [pl];
|
|
|
- }
|
|
|
- }
|
|
|
- MessageFormat.escape = function (str, octothorpe) {
|
|
|
- var esc = octothorpe ? /[#{}]/g : /[{}]/g;
|
|
|
- return String(str).replace(esc, "'$&'");
|
|
|
- };
|
|
|
- MessageFormat.supportedLocalesOf = function (locales) {
|
|
|
- var la = Array.isArray(locales) ? locales : [locales];
|
|
|
- return la.filter(hasPlural);
|
|
|
- };
|
|
|
- MessageFormat.prototype.resolvedOptions = function () {
|
|
|
- return __assign(__assign({}, this.options), { locale: this.plurals[0].locale, plurals: this.plurals });
|
|
|
- };
|
|
|
- MessageFormat.prototype.compile = function (message) {
|
|
|
- var e_1, _a;
|
|
|
- var compiler = new Compiler(this.options);
|
|
|
- var fnBody = 'return ' + compiler.compile(message, this.plurals[0]);
|
|
|
- var nfArgs = [];
|
|
|
- var fnArgs = [];
|
|
|
- try {
|
|
|
- for (var _b = __values(Object.entries(compiler.runtime)), _c = _b.next(); !_c.done; _c = _b.next()) {
|
|
|
- var _d = __read(_c.value, 2), key = _d[0], fmt = _d[1];
|
|
|
- nfArgs.push(key);
|
|
|
- fnArgs.push(fmt);
|
|
|
- }
|
|
|
- }
|
|
|
- catch (e_1_1) { e_1 = { error: e_1_1 }; }
|
|
|
- finally {
|
|
|
- try {
|
|
|
- if (_c && !_c.done && (_a = _b.return)) _a.call(_b);
|
|
|
- }
|
|
|
- finally { if (e_1) throw e_1.error; }
|
|
|
- }
|
|
|
- var fn = new (Function.bind.apply(Function, __spreadArray(__spreadArray([void 0], __read(nfArgs), false), [fnBody], false)))();
|
|
|
- return fn.apply(void 0, __spreadArray([], __read(fnArgs), false));
|
|
|
- };
|
|
|
- MessageFormat.defaultLocale = 'en';
|
|
|
- return MessageFormat;
|
|
|
- }());
|
|
|
-
|
|
|
- return MessageFormat;
|
|
|
-
|
|
|
-}));
|