UNPKG

starchild-widget

Version:

Starchild Widget

1,484 lines (1,483 loc) 523 kB
var __defProp = Object.defineProperty; var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value); import * as React from "react"; import React__default from "react"; import * as ReactDOM from "react-dom"; import { jsxs, jsx, Fragment } from "react/jsx-runtime"; function getDefaultExportFromCjs(x) { return x && x.__esModule && Object.prototype.hasOwnProperty.call(x, "default") ? x["default"] : x; } var parser = {}; var lexer = {}; var moo$1 = { exports: {} }; var moo = moo$1.exports; var hasRequiredMoo; function requireMoo() { if (hasRequiredMoo) return moo$1.exports; hasRequiredMoo = 1; (function(module) { (function(root2, factory) { if (module.exports) { module.exports = factory(); } else { root2.moo = factory(); } })(moo, function() { var hasOwnProperty2 = Object.prototype.hasOwnProperty; var toString2 = Object.prototype.toString; var hasSticky = typeof new RegExp().sticky === "boolean"; function isRegExp(o) { return o && toString2.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 re2 = new RegExp("|" + s); return re2.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)) { 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(string2, numLines) { var position2 = string2.length; var lineBreaks = 0; while (true) { var idx = string2.lastIndexOf("\n", position2 - 1); if (idx === -1) { break; } else { lineBreaks++; } position2 = idx; if (lineBreaks === numLines) { break; } if (position2 === 0) { break; } } var startPosition = lineBreaks < numLines ? 0 : position2 + 1; return string2.substring(startPosition).split("\n"); } function objectToRules(object) { var keys2 = Object.getOwnPropertyNames(object); var result = []; for (var i = 0; i < keys2.length; i++) { var key = keys2[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"); } 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 }; for (var key in obj) { if (hasOwnProperty2.call(obj, key)) { options[key] = obj[key]; } } if (typeof options.type === "string" && type !== options.type) { throw new Error("Type transform cannot be a string (type '" + options.type + "' for token '" + type + "')"); } 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 = /* @__PURE__ */ Object.create(null); var fastAllowed = true; var unicodeFlag = null; var groups = []; var parts = []; 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) { throw new Error("Inheritance is not allowed in stateless lexers"); } if (options.error || options.fallback) { 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; } } 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 + "')"); } } if (match.length === 0) { continue; } fastAllowed = false; groups.push(options); 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"); } } var pat = reUnion(match.map(regexpOrLiteral)); 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"); } if (!options.lineBreaks && regexp.test("\n")) { throw new Error("Rule should declare lineBreaks: " + regexp); } parts.push(reCapture(pat)); } 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, fast, error: errorRule || defaultErrorRule }; } function compile(rules) { var result = compileRules(toRules(rules)); return new Lexer({ start: result }, "start"); } function checkStateGroup(g, name2, map2) { var state = g && (g.push || g.next); if (state && !map2[state]) { throw new Error("Missing state '" + state + "' (in token '" + g.defaultType + "' of state '" + name2 + "')"); } if (g && g.pop && +g.pop !== 1) { throw new Error("pop must be 1 (in token '" + g.defaultType + "' of state '" + name2 + "')"); } } function compileStates(states, start2) { var all2 = states.$all ? toRules(states.$all) : []; delete states.$all; var keys2 = Object.getOwnPropertyNames(states); if (!start2) start2 = keys2[0]; var ruleMap = /* @__PURE__ */ Object.create(null); for (var i = 0; i < keys2.length; i++) { var key = keys2[i]; ruleMap[key] = toRules(states[key]).concat(all2); } for (var i = 0; i < keys2.length; i++) { var key = keys2[i]; var rules = ruleMap[key]; var included = /* @__PURE__ */ Object.create(null); for (var j = 0; j < rules.length; j++) { var rule = rules[j]; if (!rule.include) continue; var splice2 = [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; splice2.push(newRule); } } rules.splice.apply(rules, splice2); j--; } } var map2 = /* @__PURE__ */ Object.create(null); for (var i = 0; i < keys2.length; i++) { var key = keys2[i]; map2[key] = compileRules(ruleMap[key], true); } for (var i = 0; i < keys2.length; i++) { var name2 = keys2[i]; var state = map2[name2]; var groups = state.groups; for (var j = 0; j < groups.length; j++) { checkStateGroup(groups[j], name2, map2); } var fastKeys = Object.getOwnPropertyNames(state.fast); for (var j = 0; j < fastKeys.length; j++) { checkStateGroup(state.fast[fastKeys[j]], name2, map2); } } return new Lexer(map2, start2); } function keywordTransform(map2) { var isMap = typeof Map !== "undefined"; var reverseMap = isMap ? /* @__PURE__ */ new Map() : /* @__PURE__ */ Object.create(null); var types2 = Object.getOwnPropertyNames(map2); for (var i = 0; i < types2.length; i++) { var tokenType = types2[i]; var item = map2[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(re2, buffer) { return re2.exec(buffer); } : function(re2, buffer) { var match = re2.exec(buffer); 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] !== void 0) { return this.groups[i]; } } throw new Error("Cannot find token type for matched text"); }; function tokenToString() { return this.value; } Lexer.prototype.next = function() { var index2 = this.index; if (this.queuedGroup) { var token = this._token(this.queuedGroup, this.queuedText, index2); this.queuedGroup = null; this.queuedText = ""; return token; } var buffer = this.buffer; if (index2 === buffer.length) { return; } var group = this.fast[buffer.charCodeAt(index2)]; if (group) { return this._token(group, buffer.charAt(index2), index2); } var re2 = this.re; re2.lastIndex = index2; var match = eat(re2, buffer); var error = this.error; if (match == null) { return this._token(error, buffer.slice(index2, buffer.length), index2); } var group = this._getGroup(match); var text2 = match[0]; if (error.fallback && match.index !== index2) { this.queuedGroup = group; this.queuedText = text2; return this._token(error, buffer.slice(index2, match.index), index2); } return this._token(group, text2, index2); }; Lexer.prototype._token = function(group, text2, offset2) { var lineBreaks = 0; if (group.lineBreaks) { var matchNL = /\n/g; var nl = 1; if (text2 === "\n") { lineBreaks = 1; } else { while (matchNL.exec(text2)) { lineBreaks++; nl = matchNL.lastIndex; } } } var token = { type: typeof group.type === "function" && group.type(text2) || group.defaultType, value: typeof group.value === "function" ? group.value(text2) : text2, text: text2, toString: tokenToString, offset: offset2, lineBreaks, line: this.line, col: this.col }; var size = text2.length; this.index += size; this.line += lineBreaks; if (lineBreaks !== 0) { this.col = size - nl + 1; } else { this.col += size; } if (group.shouldThrow) { var err2 = new Error(this.formatError(token, "invalid syntax")); throw err2; } 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(lexer2) { this.lexer = lexer2; }; 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) { var text2 = this.buffer.slice(this.index); var token = { text: text2, offset: this.index, lineBreaks: text2.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, states: compileStates, error: Object.freeze({ error: true }), fallback: Object.freeze({ fallback: true }), keywords: keywordTransform }; }); })(moo$1); return moo$1.exports; } var hasRequiredLexer; function requireLexer() { if (hasRequiredLexer) return lexer; hasRequiredLexer = 1; (function(exports) { var __importDefault = lexer && lexer.__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(/* @__PURE__ */ requireMoo()); 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); return lexer; } var hasRequiredParser; function requireParser() { if (hasRequiredParser) return parser; hasRequiredParser = 1; Object.defineProperty(parser, "__esModule", { value: true }); parser.ParseError = void 0; parser.parse = parse2; const lexer_js_1 = /* @__PURE__ */ requireLexer(); 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 text2 = ""; for (const p of param) { const pText = p.ctx.text; text2 += 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: text2 }) }; return [c]; } const strictArgTypes = [ "number", "date", "time", "spellout", "ordinal", "duration" ]; const defaultPluralKeys = ["zero", "one", "two", "few", "many", "other"]; 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 _a2, _b, _c, _d2; this.lexer = lexer_js_1.lexer.reset(src); this.cardinalKeys = (_a2 = opt === null || opt === void 0 ? void 0 : opt.cardinal) !== null && _a2 !== void 0 ? _a2 : 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 = (_d2 = opt === null || opt === void 0 ? void 0 : opt.strictPluralKeys) !== null && _d2 !== void 0 ? _d2 : 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 keys2 = type === "plural" ? this.cardinalKeys : this.ordinalKeys; if (this.strictPluralKeys && keys2.length > 0 && !keys2.includes(key)) { const msg = `The ${type} case ${key} is not valid in this locale`; throw new ParseError(lt, msg); } } } parseSelect({ value: arg }, inPlural, ctx, type) { 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 end2 = this.lexer.next(); if (!end2) throw new ParseError(null, "Unexpected message end"); if (end2.type !== "end") { throw new ParseError(end2, `Unexpected lexer token: ${end2.type}`); } ctx.text += end2.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": 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 content2 = null; for (const lt of this.lexer) { if (lt.type === "argument") { if (content2) content2 = null; tokens.push(this.parseArgToken(lt, inPlural)); } else if (lt.type === "octothorpe" && inPlural) { if (content2) content2 = 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 (content2) { content2.value += value; content2.ctx.text += lt.text; content2.ctx.lineBreaks += lt.lineBreaks; } else { content2 = { type: "content", value, ctx: getContext(lt) }; tokens.push(content2); } } } if (atRoot) return tokens; throw new ParseError(null, "Unexpected message end"); } } function parse2(src, options = {}) { const parser2 = new Parser(src, options); return parser2.parse(); } return parser; } var parserExports = /* @__PURE__ */ requireParser(); 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 void 0; } } function dayStyle(token, onError) { const { char, desc, width } = token; if (char === "d") { return numeric(width); } else { onError(`${desc} is not supported`); return void 0; } } function weekdayStyle(token, onError) { const { char, desc, width } = token; if ((char === "c" || char === "e") && width < 3) { const msg = `Numeric value is not supported for ${desc}; falling back to weekday:short`; onError(msg, DateFormatError.WARNING); } 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) { 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 void 0; case "X": onError(`${desc} is not supported`); return void 0; } 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 void 0; 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 void 0; } function getDateFormatOptions(tokens, timeZone, onError = (error) => { throw error; }) { const options = { timeZone }; const fields2 = []; 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 (fields2.indexOf(field) === -1) fields2.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 === void 0) { 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; } } 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; } } function processTokens(tokens, mapText) { if (!tokens.filter((token) => token.type !== "content").length) { return tokens.map((token) => mapText(token.value)); } return tokens.map((token) => { var _a2; if (token.type === "content") { return mapText(token.value); } else if (token.type === "octothorpe") { return "#"; } else if (token.type === "argument") { return [token.arg]; } else if (token.type === "function") { const _param = (_a2 = token == null ? void 0 : token.param) == null ? void 0 : _a2[0]; if (token.key === "date" && _param) { const opts = compileDateExpression(_param.value.trim(), (e) => { throw new Error(`Unable to compile date expression: ${e.message}`); }); return [token.arg, token.key, opts]; } if (_param) { return [token.arg, token.key, _param.value.trim()]; } else { return [token.arg, token.key]; } } const offset2 = token.pluralOffset; const formatProps = {}; token.cases.forEach(({ key, tokens: tokens2 }) => { const prop = key[0] === "=" ? key.slice(1) : key; formatProps[prop] = processTokens(tokens2, mapText); }); return [ token.arg, token.type, { offset: offset2, ...formatProps } ]; }); } function compileDateExpression(format, onError) { if (/^::/.test(format)) { const tokens = parseDateTokens(format.substring(2)); return getDateFormatOptions(tokens, void 0, onError); } return format; } function compileMessageOrThrow(message, mapText = (v) => v) { return processTokens(parserExports.parse(message), mapText); } function compileMessage(message, mapText = (v) => v) { try { return compileMessageOrThrow(message, mapText); } catch (e) { console.error(`${e.message} Message: ${message}`); return [message]; } } const isString = (s) => typeof s === "string"; const isFunction = (f) => typeof f === "function"; const cache = /* @__PURE__ */ new Map(); const defaultLocale = "en"; function normalizeLocales(locales) { const out = Array.isArray(locales) ? locales : [locales]; return [...out, defaultLocale]; } function date(locales, value, format) { const _locales = normalizeLocales(locales); if (!format) { format = "default"; } let o; if (typeof format === "string") { o = { day: "numeric", month: "short", year: "numeric" }; switch (format) { case "full": o.weekday = "long"; case "long": o.month = "long"; break; case "short": o.month = "numeric"; break; } } else { o = format; } const formatter = getMemoized( () => cacheKey("date", _locales, format), () => new Intl.DateTimeFormat(_locales, o) ); return formatter.format(isString(value) ? new Date(value) : value); } function time(locales, value, format) { let o; if (!format) { format = "default"; } if (typeof format === "string") { o = { second: "numeric", minute: "numeric", hour: "numeric" }; switch (format) { case "full": case "long": o.timeZoneName = "short"; break; case "short": delete o.second; } } else { o = format; } return date(locales, value, o); } function number$1(locales, value, format) { const _locales = normalizeLocales(locales); const formatter = getMemoized( () => cacheKey("number", _locales, format), () => new Intl.NumberFormat(_locales, format) ); return formatter.format(value); } function plural(locales, ordinal, value, { offset: offset2 = 0, ...rules }) { const _locales = normalizeLocales(locales); const plurals = ordinal ? getMemoized( () => cacheKey("plural-ordinal", _locales), () => new Intl.PluralRules(_locales, { type: "ordinal" }) ) : getMemoized( () => cacheKey("plural-cardinal", _locales), () => new Intl.PluralRules(_locales, { type: "cardinal" }) ); return rules[value] ?? rules[plurals.select(value - offset2)] ?? rules.other; } function getMemoized(getKey, construct) { const key = getKey(); let formatter = cache.get(key); if (!formatter) { formatter = construct(); cache.set(key, formatter); } return formatter; } function cacheKey(type, locales, options) { const localeKey = locales.join("-"); return `${type}-${localeKey}-${JSON.stringify(options)}`; } const ESCAPE_SEQUENCE_REGEX = /\\u[a-fA-F0-9]{4}|\\x[a-fA-F0-9]{2}/; const decodeEscapeSequences = (str) => { return str.replace( // Same pattern but with capturing groups for extracting values during replacement /\\u([a-fA-F0-9]{4})|\\x([a-fA-F0-9]{2})/g, (_, unicode, hex) => { if (unicode) { const codePoint = parseInt(unicode, 16); return String.fromCharCode(codePoint); } else { const codePoint = parseInt(hex, 16); return String.fromCharCode(codePoint); } } ); }; const OCTOTHORPE_PH = "%__lingui_octothorpe__%"; const getDefaultFormats = (locale, passedLocales, formats = {}) => { const locales = passedLocales || locale; const style = (format) => { if (typeof format === "object") return format; return formats[format]; }; const replaceOctothorpe = (value, message) => { const numberFormat = Object.keys(formats).length ? style("number") : void 0; const valueStr = number$1(locales, value, numberFormat); return message.replace(new RegExp(OCTOTHORPE_PH, "g"), valueStr); }; return { plural: (value, cases) => { const { offset: offset2 = 0 } = cases; const message = plural(locales, false, value, cases); return replaceOctothorpe(value - offset2, message); }, selectordinal: (value, cases) => { const { offset: offset2 = 0 } = cases; const message = plural(locales, true, value, cases); return replaceOctothorpe(value - offset2, message); }, select: selectFormatter, number: (value, format) => number$1( locales, value, style(format) || { style: format } ), date: (value, format) => date(locales, value, style(format) || format), time: (value, format) => time(locales, value, style(format) || format) }; }; const selectFormatter = (value, rules) => rules[value] ?? rules.other; function interpolate(translation, locale, locales) { return (values = {}, formats) => { const formatters = getDefaultFormats(locale, locales, formats); const formatMessage = (tokens, replaceOctothorpe = false) => { if (!Array.isArray(tokens)) return tokens; return tokens.reduce((message, token) => { if (token === "#" && replaceOctothorpe) { return message + OCTOTHORPE_PH; } if (isString(token)) { return message + token; } const [name2, type, format] = token; let interpolatedFormat = {}; if (type === "plural" || type === "selectordinal" || type === "select") { Object.entries(format).forEach( ([key, value2]) => { interpolatedFormat[key] = formatMessage( value2, type === "plural" || type === "selectordinal" ); } ); } else { interpolatedFormat = format; } let value; if (type) { const formatter = formatters[type]; value = formatter(values[name2], interpolatedFormat); } else { value = values[name2]; } if (value == null) { return message; } return message + value; }, ""); }; const result = formatMessage(translation); if (isString(result) && ESCAPE_SEQUENCE_REGEX.test(result)) { return decodeEscapeSequences(result); } if (isString(result)) return result; return result ? String(result) : ""; }; } var __defProp$1 = Object.defineProperty; var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField$1 = (obj, key, value) => { __defNormalProp$1(obj, key + "", value); return value; }; class EventEmitter { constructor() { __publicField$1(this, "_events", {}); } on(event, listener) { var _a2; (_a2 = this._events)[event] ?? (_a2[event] = []); this._events[event].push(listener); return () => this.removeListener(event, listener); } removeListener(event, listener) { const maybeListeners = this._getListeners(event); if (!maybeListeners) return; const index2 = maybeListeners.indexOf(listener); if (~index2) maybeListeners.splice(index2, 1); } emit(event, ...args) { const maybeListeners = this._getListeners(event); if (!maybeListeners) return; maybeListeners.map((listener) => listener.apply(this, args)); } _getListeners(event) { const maybeListeners = this._events[event]; return Array.isArray(maybeListeners) ? maybeListeners : false; } } var __defProp2 = Object.defineProperty; var __defNormalProp2 = (obj, key, value) => key in obj ? __defProp2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value; var __publicField2 = (obj, key, value) => { __defNormalProp2(obj, typeof key !== "symbol" ? key + "" : key, value); return value; }; class I18n extends EventEmitter { constructor(params) { super(); __publicField2(this, "_locale", ""); __publicField2(this, "_locales"); __publicField2(this, "_localeData", {}); __publicField2(this, "_messages", {}); __publicField2(this, "_missing"); __publicField2(this, "_messageCompiler"); __publicField2(this, "t", this._.bind(this)); if (process.env.NODE_ENV !== "production") { this.setMessagesCompiler(compileMessage); } if (params.missing != null) this._missing = params.missing; if (params.messages != null) this.load(params.messages); if (params.localeData != null) this.loadLocaleData(params.localeData); if (typeof params.locale === "string" || params.locales) { this.activate(params.locale ?? defaultLocale, params.locales); } } get locale() { return this._locale; } get locales() { return this._locales; } get messages() { return this._messages[this._locale] ?? {}; } /** * @deprecated this has no effect. Please remove this from the code. Deprecated in v4 */ get localeData() { return this._localeData[this._locale] ?? {}; } _loadLocaleData(locale, localeData) { const maybeLocaleData = this._localeData[locale]; if (!maybeLocaleData) { this._localeData[locale] = localeData; } else { Object.assign(maybeLocaleData, localeData); } } /** * Registers a `MessageCompiler` to enable the use of uncompiled catalogs at runtime. * * In production builds, the `MessageCompiler` is typically excluded to reduce bundle size. * By default, message catalogs should be precompiled during the build process. However, * if you need to compile catalogs at runtime, you can use this method to set a message compiler. * * Example usage: * * ```ts * import { compileMessage } from "@lingui/message-utils/compileMessage"; * * i18n.setMessagesCompiler(compileMessage); * ``` */ setMessagesCompiler(compiler2) { this._messageCompiler = compiler2; return this; } /** * @deprecated Plurals automatically used from Intl.PluralRules you can safely remove this call. Deprecated in v4 */ loadLocaleData(localeOrAllData, localeData) { if (typeof localeOrAllData === "string") { this._loadLocaleData(localeOrAllData, localeData); } else { Object.keys(localeOrAllData).forEach( (locale) => this._loadLocaleData(locale, localeOrAllData[locale]) ); } this.emit("change"); } _load(locale, messages) { const maybeMessages = this._messages[locale]; if (!maybeMessages) { this._messages[locale] = messages; } else { Object.assign(maybeMessages, messages); } } load(localeOrMessages, messages) { if (typeof