@cute-dw/core
Version:
This TypeScript library is the main part of a more powerfull package designed for the fast WEB software development. The cornerstone of the library is the **DataStore** class, which might be useful when you need a full control of the data, but do not need
182 lines • 26.9 kB
JavaScript
import { Strings } from "../../Strings";
import { Locale } from "../Locale";
import { NumberSpellerDictionary } from "./NumberSpellerDictionary";
/**
* This utility class consists exclusively of the static methods that operate on numeric values with localization taking into account
* @since 0.4.0
* @license MIT, (c) 2022 ALEXANDER STRELKOV, alv.strelkov@gmail.com
*/
export class NumberSpeller {
/**
*
* @param amount
* @param thousandGroup
* @param words
* @param options
* @returns
*/
static _digitGroup(amount, thousandGroup, words, options) {
let res = "";
let nBase = 1000000000000000.00, v = 0, srcAmount = amount;
for (let nGrp = 1; nGrp <= 5; nGrp++) {
v = Math.trunc(amount / nBase);
if (v > 0) {
amount -= Math.trunc(v * nBase);
res += this._digitGroup(v, nGrp, words, options);
if (amount > 0) {
res += words.texts.delim1000 || "";
}
res += " ";
}
nBase = Math.trunc(nBase / 1000);
}
// hundreds
v = Math.trunc(amount / 100);
if (v > 0) {
amount -= Math.trunc(v * 100);
if (words.hundreds.length == 1) {
res += (words.ones[v] + " " + words.hundreds[0] + " ");
}
else {
res += (words.hundreds[v - 1] + " ");
}
}
// tens
let fractions = "";
v = Math.trunc(amount / 10);
if (v > 0) {
amount -= Math.trunc(v * 10);
if (v == 1 && amount > 0) {
// 11-19
fractions += (words.teens[amount - 1] + " ");
amount = 0;
}
else {
fractions += words.tens[v - 1];
if (v > 1 && amount > 0 && words.texts.tenSplitter) {
fractions += words.texts.tenSplitter;
}
else {
fractions += " ";
}
}
}
// units
let item;
let more = "";
let pointWord = "";
let useExacts = true;
let currOptions = undefined;
if (thousandGroup !== undefined) {
item = words.groups[thousandGroup].find(obj => obj.values === undefined || obj.values.indexOf(amount) >= 0);
}
else if (options.currency) {
currOptions = words.currency[options.currency];
if (currOptions) {
useExacts = currOptions.useExacts ?? true;
if (options.isFraction) {
item = currOptions.parts?.fraction.find(obj => obj.values === undefined || obj.values.indexOf(amount) >= 0);
pointWord = Strings.trimAll(currOptions.point) || "";
pointWord = (pointWord != "" ? pointWord + " " : "");
}
else {
item = currOptions.parts?.integer.find(obj => obj.values === undefined || obj.values.indexOf(amount) >= 0);
}
}
}
if (item) {
more = item.word;
}
if (amount > 0) {
let word = words.ones[amount];
if (useExacts && words.exactWordsMapping && (options.isFraction || thousandGroup == 5)) {
word = words.exactWordsMapping[amount] ?? word;
}
fractions += word;
}
else if (srcAmount == 0) {
fractions += words.ones[0];
}
return (res + pointWord + (options.isFraction && options.fractionAsNumber ? Strings.right("0" + String(srcAmount), 2) : fractions)).trimEnd() + " " + more;
}
/**
* Converts an integer value in words
* @param value A number to convert
* @param options An object containing certain properties and their values
* @returns String
* @static
*/
static spellInteger(value, options) {
const oLocale = options?.locale instanceof Locale ? options.locale : new Locale(options?.locale);
const words = NumberSpellerDictionary.get(oLocale.baseName);
if (!words) {
return String(value);
}
if (!Number.isFinite(value)) {
return String(value);
}
let signWord = "";
if (value < 0) {
value = Math.abs(value);
signWord = words.texts?.minus ?? "-";
}
return signWord + this._digitGroup(Math.trunc(value), undefined, words, {}).trimEnd();
}
/**
* Converts amount of money in words
* @param value Sum to convert
* @param options Configuration object
* @returns String
* @throws Error if the _locale_ value is invalid in `options`
* @static
*/
static spellCurrency(value, options) {
const oLocale = options?.locale instanceof Locale ? options.locale : new Locale(options?.locale);
const words = NumberSpellerDictionary.get(oLocale.baseName);
if (!words) {
throw new TypeError(`Unknown locale: ${oLocale.baseName}`);
}
let currency = options?.currency ?? "";
if (currency.trim() == "" && Object.keys(words.currency).length > 0) {
currency = Object.keys(words.currency)[0];
}
if (!words.currency[currency]) {
throw new TypeError(`Unknown currency '${currency}' in locale '${oLocale.baseName}'`);
}
if (!Number.isFinite(value)) {
throw new RangeError(`Invalid value: ${value}`);
}
let signWord = "";
if (value < 0) {
value = Math.abs(value);
signWord = (words.texts?.minus ?? "-") + " ";
}
const intPart = Math.trunc(value);
const decPart = Math.round((value - intPart) * 100);
let sVal = signWord + this._digitGroup(intPart, undefined, words, { currency, isFraction: false });
if (sVal != "") {
sVal += " ";
}
return sVal + (decPart == 0 && words.currency[currency].only
? words.currency[currency].only
: this._digitGroup(decPart, undefined, words, { currency, isFraction: true, fractionAsNumber: options?.fractionAsNumber ?? true }));
}
/**
* Gets the result of the specified _unit_ formatting
* @param value A value in units
* @param unit Required value in unit formatting. Possible values are [core unit identifiers](https://tc39.es/proposal-unified-intl-numberformat/section6/locales-currencies-tz_proposed_out.html#sec-issanctionedsimpleunitidentifier) that was selected for use in ECMAScript. Pairs of simple units can be concatenated with "-per-" to make a compound unit.
* @param options Configuration object
* @returns String
* @throws Error if the _locale_ value is invalid in `options`
* @static
*/
static spellUnit(value, unit, options) {
const oLocale = options?.locale instanceof Locale ? options.locale : new Locale(options?.locale);
let output = (new Intl.NumberFormat(oLocale.baseName, { style: "unit", unit, unitDisplay: options?.unitDisplay ?? "long" })).format(value);
if (!(options?.valueAsNumber ?? false) && Number.isInteger(value)) {
output = NumberSpeller.spellInteger(value, { locale: options?.locale }) + " " + Strings.getLastToken(output, " ")[0];
}
return output;
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiTnVtYmVyU3BlbGxlci5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2N1dGUtY29yZS9zcmMvbGliL3V0aWwvaTE4bi90ZXh0L051bWJlclNwZWxsZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsTUFBTSxFQUFFLE1BQU0sV0FBVyxDQUFDO0FBQ25DLE9BQU8sRUFBdUMsdUJBQXVCLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN6Rzs7OztHQUlHO0FBQ0gsTUFBTSxPQUFPLGFBQWE7SUFDeEI7Ozs7Ozs7T0FPRztJQUNLLE1BQU0sQ0FBQyxXQUFXLENBQUMsTUFBYyxFQUFFLGFBQWlDLEVBQUUsS0FBbUMsRUFBRSxPQUFnRjtRQUNqTSxJQUFJLEdBQUcsR0FBRyxFQUFFLENBQUM7UUFDYixJQUFJLEtBQUssR0FBRyxtQkFBbUIsRUFBRSxDQUFDLEdBQUcsQ0FBQyxFQUFFLFNBQVMsR0FBRyxNQUFNLENBQUM7UUFFM0QsS0FBSyxJQUFJLElBQUksR0FBRyxDQUFDLEVBQUUsSUFBSSxJQUFJLENBQUMsRUFBRSxJQUFJLEVBQUUsRUFBRTtZQUNwQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxNQUFNLEdBQUcsS0FBSyxDQUFDLENBQUM7WUFDL0IsSUFBSSxDQUFDLEdBQUcsQ0FBQyxFQUFFO2dCQUNULE1BQU0sSUFBSSxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxLQUFLLENBQUMsQ0FBQztnQkFDaEMsR0FBRyxJQUFJLElBQUksQ0FBQyxXQUFXLENBQUMsQ0FBQyxFQUFFLElBQUksRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDLENBQUM7Z0JBQ2pELElBQUksTUFBTSxHQUFHLENBQUMsRUFBRTtvQkFDZCxHQUFHLElBQUksS0FBSyxDQUFDLEtBQUssQ0FBQyxTQUFTLElBQUks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RUFBRSxNQUFNLFlBQVksTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxJQUFJLE1BQU0sQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFDakcsSUFBSSxNQUFNLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsT0FBTyxDQUFDLFFBQVEsRUFBRSxFQUFDLEtBQUssRUFBRSxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxPQUFPLEVBQUUsV0FBVyxJQUFJLE1BQU0sRUFBQyxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDekksSUFBSyxDQUFDLENBQUMsT0FBTyxFQUFFLGFBQWEsSUFBRSxLQUFLLENBQUMsSUFBSSxNQUFNLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxFQUFHO1lBQ2pFLE1BQU0sR0FBRyxhQUFhLENBQUMsWUFBWSxDQUFDLEtBQUssRUFBRSxFQUFDLE1BQU0sRUFBRSxPQUFPLEVBQUUsTUFBTSxFQUFDLENBQUMsR0FBRyxHQUFHLEdBQUUsT0FBTyxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7U0FDbkg7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0NBRUYiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBTdHJpbmdzIH0gZnJvbSBcIi4uLy4uL1N0cmluZ3NcIjtcbmltcG9ydCB7IExvY2FsZSB9IGZyb20gXCIuLi9Mb2NhbGVcIjtcbmltcG9ydCB7IEN1cnJlbmN5T3B0aW9ucywgRGlnaXRhbFdvcmRzQ29uZmlnLCBOdW1iZXJTcGVsbGVyRGljdGlvbmFyeSB9IGZyb20gXCIuL051bWJlclNwZWxsZXJEaWN0aW9uYXJ5XCI7XG4vKipcbiAqIFRoaXMgdXRpbGl0eSBjbGFzcyBjb25zaXN0cyBleGNsdXNpdmVseSBvZiB0aGUgc3RhdGljIG1ldGhvZHMgdGhhdCBvcGVyYXRlIG9uIG51bWVyaWMgdmFsdWVzIHdpdGggbG9jYWxpemF0aW9uIHRha2luZyBpbnRvIGFjY291bnRcbiAqIEBzaW5jZSAwLjQuMFxuICogQGxpY2Vuc2UgTUlULCAoYykgMjAyMiBBTEVYQU5ERVIgU1RSRUxLT1YsIGFsdi5zdHJlbGtvdkBnbWFpbC5jb21cbiAqL1xuZXhwb3J0IGNsYXNzIE51bWJlclNwZWxsZXIge1xuICAvKipcbiAgICpcbiAgICogQHBhcmFtIGFtb3VudFxuICAgKiBAcGFyYW0gdGhvdXNhbmRHcm91cFxuICAgKiBAcGFyYW0gd29yZHNcbiAgICogQHBhcmFtIG9wdGlvbnNcbiAgICogQHJldHVybnNcbiAgICovXG4gIHByaXZhdGUgc3RhdGljIF9kaWdpdEdyb3VwKGFtb3VudDogbnVtYmVyLCB0aG91c2FuZEdyb3VwOiBudW1iZXIgfCB1bmRlZmluZWQsIHdvcmRzOiBSZWFkb25seTxEaWdpdGFsV29yZHNDb25maWc+LCBvcHRpb25zOiB7IGN1cnJlbmN5Pzogc3RyaW5nLCBpc0ZyYWN0aW9uPzogYm9vbGVhbiwgZnJhY3Rpb25Bc051bWJlcj86IGJvb2xlYW4gfSk6IHN0cmluZyB7XG4gICAgbGV0IHJlcyA9IFwiXCI7XG4gICAgbGV0IG5CYXNlID0gMTAwMDAwMDAwMDAwMDAwMC4wMCwgdiA9IDAsIHNyY0Ftb3VudCA9IGFtb3VudDtcblxuICAgIGZvciAobGV0IG5HcnAgPSAxOyBuR3JwIDw9IDU7IG5HcnArKykge1xuICAgICAgdiA9IE1hdGgudHJ1bmMoYW1vdW50IC8gbkJhc2UpO1xuICAgICAgaWYgKHYgPiAwKSB7XG4gICAgICAgIGFtb3VudCAtPSBNYXRoLnRydW5jKHYgKiBuQmFzZSk7XG4gICAgICAgIHJlcyArPSB0aGlzLl9kaWdpdEdyb3VwKHYsIG5HcnAsIHdvcmRzLCBvcHRpb25zKTtcbiAgICAgICAgaWYgKGFtb3VudCA+IDApIHtcbiAgICAgICAgICByZXMgKz0gd29yZHMudGV4dHMuZGVsaW0xMDAwIHx8IFwiXCI7XG4gICAgICAgIH1cbiAgICAgICAgcmVzICs9IFwiIFwiO1xuICAgICAgfVxuICAgICAgbkJhc2UgPSBNYXRoLnRydW5jKG5CYXNlIC8gMTAwMCk7XG4gICAgfVxuICAgIC8vIGh1bmRyZWRzXG4gICAgdiA9IE1hdGgudHJ1bmMoYW1vdW50IC8gMTAwKTtcbiAgICBpZiAodiA+IDApIHtcbiAgICAgIGFtb3VudCAtPSBNYXRoLnRydW5jKHYgKiAxMDApO1xuICAgICAgaWYgKHdvcmRzLmh1bmRyZWRzLmxlbmd0aCA9PSAxKSB7XG4gICAgICAgIHJlcyArPSAod29yZHMub25lc1t2XSArIFwiIFwiICsgd29yZHMuaHVuZHJlZHNbMF0gKyBcIiBcIik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXMgKz0gKHdvcmRzLmh1bmRyZWRzW3YgLSAxXSArIFwiIFwiKTtcbiAgICAgIH1cbiAgICB9XG4gICAgLy8gdGVuc1xuICAgIGxldCBmcmFjdGlvbnMgPSBcIlwiO1xuICAgIHYgPSBNYXRoLnRydW5jKGFtb3VudCAvIDEwKTtcbiAgICBpZiAodiA+IDApIHtcbiAgICAgIGFtb3VudCAtPSBNYXRoLnRydW5jKHYgKiAxMCk7XG4gICAgICBpZiAodiA9PSAxICYmIGFtb3VudCA+IDApIHtcbiAgICAgICAgLy8gMTEtMTlcbiAgICAgICAgZnJhY3Rpb25zICs9ICh3b3Jkcy50ZWVuc1thbW91bnQgLSAxXSArIFwiIFwiKTtcbiAgICAgICAgYW1vdW50ID0gMDtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZyYWN0aW9ucyArPSB3b3Jkcy50ZW5zW3YgLSAxXTtcbiAgICAgICAgaWYgKHYgPiAxICYmIGFtb3VudCA+IDAgJiYgd29yZHMudGV4dHMudGVuU3BsaXR0ZXIpIHtcbiAgICAgICAgICBmcmFjdGlvbnMgKz0gd29yZHMudGV4dHMudGVuU3BsaXR0ZXI7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZnJhY3Rpb25zICs9IFwiIFwiO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICAgIC8vIHVuaXRzXG4gICAgbGV0IGl0ZW07XG4gICAgbGV0IG1vcmUgPSBcIlwiO1xuICAgIGxldCBwb2ludFdvcmQgPSBcIlwiO1xuICAgIGxldCB1c2VFeGFjdHMgPSB0cnVlO1xuICAgIGxldCBjdXJyT3B0aW9uczogQ3VycmVuY3lPcHRpb25zIHwgdW5kZWZpbmVkID0gdW5kZWZpbmVkO1xuICAgIGlmICh0aG91c2FuZEdyb3VwICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIGl0ZW0gPSB3b3Jkcy5ncm91cHNbdGhvdXNhbmRHcm91cF0uZmluZChvYmogPT4gb2JqLnZhbHVlcyA9PT0gdW5kZWZpbmVkIHx8IG9iai52YWx1ZXMuaW5kZXhPZihhbW91bnQpID49IDApO1xuICAgIH0gZWxzZSBpZiAob3B0aW9ucy5jdXJyZW5jeSkge1xuICAgICAgY3Vyck9wdGlvbnMgPSB3b3Jkcy5jdXJyZW5jeVtvcHRpb25zLmN1cnJlbmN5XTtcbiAgICAgIGlmIChjdXJyT3B0aW9ucykge1xuICAgICAgICB1c2VFeGFjdHMgPSBjdXJyT3B0aW9ucy51c2VFeGFjdHMgPz8gdHJ1ZTtcbiAgICAgICAgaWYgKG9wdGlvbnMuaXNGcmFjdGlvbikge1xuICAgICAgICAgIGl0ZW0gPSBjdXJyT3B0aW9ucy5wYXJ0cz8uZnJhY3Rpb24uZmluZChvYmogPT4gb2JqLnZhbHVlcyA9PT0gdW5kZWZpbmVkIHx8IG9iai52YWx1ZXMuaW5kZXhPZihhbW91bnQpID49IDApO1xuICAgICAgICAgIHBvaW50V29yZCA9IFN0cmluZ3MudHJpbUFsbChjdXJyT3B0aW9ucy5wb2ludCkgfHwgXCJcIjtcbiAgICAgICAgICBwb2ludFdvcmQgPSAocG9pbnRXb3JkICE9IFwiXCIgPyBwb2ludFdvcmQgKyBcIiBcIiA6IFwiXCIpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGl0ZW0gPSBjdXJyT3B0aW9ucy5wYXJ0cz8uaW50ZWdlci5maW5kKG9iaiA9PiBvYmoudmFsdWVzID09PSB1bmRlZmluZWQgfHwgb2JqLnZhbHVlcy5pbmRleE9mKGFtb3VudCkgPj0gMCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgaWYgKGl0ZW0pIHtcbiAgICAgIG1vcmUgPSBpdGVtLndvcmQ7XG4gICAgfVxuXG4gICAgaWYgKGFtb3VudCA+IDApIHtcbiAgICAgIGxldCB3b3JkID0gd29yZHMub25lc1thbW91bnRdO1xuICAgICAgaWYgKHVzZUV4YWN0cyAmJiB3b3Jkcy5leGFjdFdvcmRzTWFwcGluZyAmJiAob3B0aW9ucy5pc0ZyYWN0aW9uIHx8IHRob3VzYW5kR3JvdXAgPT0gNSkpIHtcbiAgICAgICAgd29yZCA9IHdvcmRzLmV4YWN0V29yZHNNYXBwaW5nW2Ftb3VudF0gPz8gd29yZDtcbiAgICAgIH1cbiAgICAgIGZyYWN0aW9ucyArPSB3b3JkO1xuICAgIH0gZWxzZSBpZiAoc3JjQW1vdW50ID09IDApIHtcbiAgICAgIGZyYWN0aW9ucyArPSB3b3Jkcy5vbmVzWzBdO1xuICAgIH1cblxuICAgIHJldHVybiAocmVzICsgcG9pbnRXb3JkICsgKG9wdGlvbnMuaXNGcmFjdGlvbiAmJiBvcHRpb25zLmZyYWN0aW9uQXNOdW1iZXIgPyBTdHJpbmdzLnJpZ2h0KFwiMFwiICsgU3RyaW5nKHNyY0Ftb3VudCksIDIpIDogZnJhY3Rpb25zKSkudHJpbUVuZCgpICsgXCIgXCIgKyBtb3JlO1xuICB9XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbiBpbnRlZ2VyIHZhbHVlIGluIHdvcmRzXG4gICAqIEBwYXJhbSB2YWx1ZSBBIG51bWJlciB0byBjb252ZXJ0XG4gICAqIEBwYXJhbSBvcHRpb25zIEFuIG9iamVjdCBjb250YWluaW5nIGNlcnRhaW4gcHJvcGVydGllcyBhbmQgdGhlaXIgdmFsdWVzXG4gICAqIEByZXR1cm5zIFN0cmluZ1xuICAgKiBAc3RhdGljXG4gICAqL1xuICBzdGF0aWMgc3BlbGxJbnRlZ2VyKHZhbHVlOiBudW1iZXIsIG9wdGlvbnM/OiB7IGxvY2FsZT86IHN0cmluZyB8IExvY2FsZSB9KTogc3RyaW5nIHtcbiAgICBjb25zdCBvTG9jYWxlID0gb3B0aW9ucz8ubG9jYWxlIGluc3RhbmNlb2YgTG9jYWxlID8gb3B0aW9ucy5sb2NhbGUgOiBuZXcgTG9jYWxlKG9wdGlvbnM/LmxvY2FsZSk7XG5cbiAgICBjb25zdCB3b3JkcyA9IE51bWJlclNwZWxsZXJEaWN0aW9uYXJ5LmdldChvTG9jYWxlLmJhc2VOYW1lISk7XG4gICAgaWYgKCF3b3Jkcykge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICAgIGlmICghTnVtYmVyLmlzRmluaXRlKHZhbHVlKSkge1xuICAgICAgcmV0dXJuIFN0cmluZyh2YWx1ZSk7XG4gICAgfVxuICAgIGxldCBzaWduV29yZCA9IFwiXCI7XG4gICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSk7XG4gICAgICBzaWduV29yZCA9IHdvcmRzLnRleHRzPy5taW51cyA/PyBcIi1cIjtcbiAgICB9XG5cbiAgICByZXR1cm4gc2lnbldvcmQgKyB0aGlzLl9kaWdpdEdyb3VwKE1hdGgudHJ1bmModmFsdWUpLCB1bmRlZmluZWQsIHdvcmRzLCB7fSkudHJpbUVuZCgpO1xuICB9XG4gIC8qKlxuICAgKiBDb252ZXJ0cyBhbW91bnQgb2YgbW9uZXkgaW4gd29yZHNcbiAgICogQHBhcmFtIHZhbHVlICBTdW0gdG8gY29udmVydFxuICAgKiBAcGFyYW0gb3B0aW9ucyBDb25maWd1cmF0aW9uIG9iamVjdFxuICAgKiBAcmV0dXJucyBTdHJpbmdcbiAgICogQHRocm93cyBFcnJvciBpZiB0aGUgX2xvY2FsZV8gdmFsdWUgaXMgaW52YWxpZCBpbiBgb3B0aW9uc2BcbiAgICogQHN0YXRpY1xuICAgKi9cbiAgc3RhdGljIHNwZWxsQ3VycmVuY3kodmFsdWU6IG51bWJlciwgb3B0aW9ucz86IHsgY3VycmVuY3k/OiBzdHJpbmcsIGxvY2FsZT86IHN0cmluZyB8IExvY2FsZSwgZnJhY3Rpb25Bc051bWJlcj86IGJvb2xlYW4gfSk6IHN0cmluZyB7XG4gICAgY29uc3Qgb0xvY2FsZSA9IG9wdGlvbnM/LmxvY2FsZSBpbnN0YW5jZW9mIExvY2FsZSA/IG9wdGlvbnMubG9jYWxlIDogbmV3IExvY2FsZShvcHRpb25zPy5sb2NhbGUpO1xuICAgIGNvbnN0IHdvcmRzID0gTnVtYmVyU3BlbGxlckRpY3Rpb25hcnkuZ2V0KG9Mb2NhbGUuYmFzZU5hbWUhKTtcblxuICAgIGlmICghd29yZHMpIHtcbiAgICAgIHRocm93IG5ldyBUeXBlRXJyb3IoYFVua25vd24gbG9jYWxlOiAke29Mb2NhbGUuYmFzZU5hbWV9YCk7XG4gICAgfVxuXG4gICAgbGV0IGN1cnJlbmN5ID0gb3B0aW9ucz8uY3VycmVuY3kgPz8gXCJcIjtcbiAgICBpZiAoY3VycmVuY3kudHJpbSgpID09IFwiXCIgJiYgT2JqZWN0LmtleXMod29yZHMuY3VycmVuY3kpLmxlbmd0aCA+IDApIHtcbiAgICAgIGN1cnJlbmN5ID0gT2JqZWN0LmtleXMod29yZHMuY3VycmVuY3kpWzBdO1xuICAgIH1cblxuICAgIGlmICghd29yZHMuY3VycmVuY3lbY3VycmVuY3ldKSB7XG4gICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKGBVbmtub3duIGN1cnJlbmN5ICcke2N1cnJlbmN5fScgaW4gbG9jYWxlICcke29Mb2NhbGUuYmFzZU5hbWV9J2ApO1xuICAgIH1cbiAgICBpZiAoIU51bWJlci5pc0Zpbml0ZSh2YWx1ZSkpIHtcbiAgICAgIHRocm93IG5ldyBSYW5nZUVycm9yKGBJbnZhbGlkIHZhbHVlOiAke3ZhbHVlfWApO1xuICAgIH1cblxuICAgIGxldCBzaWduV29yZCA9IFwiXCI7XG4gICAgaWYgKHZhbHVlIDwgMCkge1xuICAgICAgdmFsdWUgPSBNYXRoLmFicyh2YWx1ZSk7XG4gICAgICBzaWduV29yZCA9ICh3b3Jkcy50ZXh0cz8ubWludXMgPz8gXCItXCIpICsgXCIgXCI7XG4gICAgfVxuXG4gICAgY29uc3QgaW50UGFydCA9IE1hdGgudHJ1bmModmFsdWUpO1xuICAgIGNvbnN0IGRlY1BhcnQgPSBNYXRoLnJvdW5kKCh2YWx1ZSAtIGludFBhcnQpICogMTAwKTtcblxuICAgIGxldCBzVmFsID0gc2lnbldvcmQgKyB0aGlzLl9kaWdpdEdyb3VwKGludFBhcnQsIHVuZGVmaW5lZCwgd29yZHMsIHsgY3VycmVuY3ksIGlzRnJhY3Rpb246IGZhbHNlIH0pO1xuICAgIGlmIChzVmFsICE9IFwiXCIpIHtcbiAgICAgIHNWYWwgKz0gXCIgXCI7XG4gICAgfVxuICAgIHJldHVybiBzVmFsICsgKGRlY1BhcnQgPT0gMCAmJiB3b3Jkcy5jdXJyZW5jeVtjdXJyZW5jeV0ub25seVxuICAgICAgICAgICAgICAgICAgICAgID8gd29yZHMuY3VycmVuY3lbY3VycmVuY3ldLm9ubHlcbiAgICAgICAgICAgICAgICAgICAgICA6IHRoaXMuX2RpZ2l0R3JvdXAoZGVjUGFydCwgdW5kZWZpbmVkLCB3b3JkcyxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHsgY3VycmVuY3ksIGlzRnJhY3Rpb246IHRydWUsIGZyYWN0aW9uQXNOdW1iZXI6IG9wdGlvbnM/LmZyYWN0aW9uQXNOdW1iZXIgPz8gdHJ1ZSB9XG4gICAgICAgICAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICAgICApO1xuICB9XG4gIC8qKlxuICAgKiBHZXRzIHRoZSByZXN1bHQgb2YgdGhlIHNwZWNpZmllZCBfdW5pdF8gZm9ybWF0dGluZ1xuICAgKiBAcGFyYW0gdmFsdWUgQSB2YWx1ZSBpbiB1bml0c1xuICAgKiBAcGFyYW0gdW5pdCBSZXF1aXJlZCB2YWx1ZSBpbiB1bml0IGZvcm1hdHRpbmcuIFBvc3NpYmxlIHZhbHVlcyBhcmUgW2NvcmUgdW5pdCBpZGVudGlmaWVyc10oaHR0cHM6Ly90YzM5LmVzL3Byb3Bvc2FsLXVuaWZpZWQtaW50bC1udW1iZXJmb3JtYXQvc2VjdGlvbjYvbG9jYWxlcy1jdXJyZW5jaWVzLXR6X3Byb3Bvc2VkX291dC5odG1sI3NlYy1pc3NhbmN0aW9uZWRzaW1wbGV1bml0aWRlbnRpZmllcikgdGhhdCB3YXMgc2VsZWN0ZWQgZm9yIHVzZSBpbiBFQ01BU2NyaXB0LiBQYWlycyBvZiBzaW1wbGUgdW5pdHMgY2FuIGJlIGNvbmNhdGVuYXRlZCB3aXRoIFwiLXBlci1cIiB0byBtYWtlIGEgY29tcG91bmQgdW5pdC5cbiAgICogQHBhcmFtIG9wdGlvbnMgQ29uZmlndXJhdGlvbiBvYmplY3RcbiAgICogQHJldHVybnMgU3RyaW5nXG4gICAqIEB0aHJvd3MgRXJyb3IgaWYgdGhlIF9sb2NhbGVfIHZhbHVlIGlzIGludmFsaWQgaW4gYG9wdGlvbnNgXG4gICAqIEBzdGF0aWNcbiAgICovXG4gIHN0YXRpYyBzcGVsbFVuaXQodmFsdWU6IG51bWJlciwgdW5pdDogc3RyaW5nLCBvcHRpb25zPzogeyBsb2NhbGU/OiBzdHJpbmcgfCBMb2NhbGUsIHVuaXREaXNwbGF5PzogXCJsb25nXCJ8XCJzaG9ydFwifFwibmFycm93XCIsIHZhbHVlQXNOdW1iZXI/OiBib29sZWFufSk6IHN0cmluZyB7XG4gICAgY29uc3Qgb0xvY2FsZSA9IG9wdGlvbnM/LmxvY2FsZSBpbnN0YW5jZW9mIExvY2FsZSA/IG9wdGlvbnMubG9jYWxlIDogbmV3IExvY2FsZShvcHRpb25zPy5sb2NhbGUpO1xuICAgIGxldCBvdXRwdXQgPSAobmV3IEludGwuTnVtYmVyRm9ybWF0KG9Mb2NhbGUuYmFzZU5hbWUsIHtzdHlsZTogXCJ1bml0XCIsIHVuaXQsIHVuaXREaXNwbGF5OiBvcHRpb25zPy51bml0RGlzcGxheSA/PyBcImxvbmdcIn0pKS5mb3JtYXQodmFsdWUpO1xuICAgIGlmICggIShvcHRpb25zPy52YWx1ZUFzTnVtYmVyPz9mYWxzZSkgJiYgTnVtYmVyLmlzSW50ZWdlcih2YWx1ZSkgKSB7XG4gICAgICBvdXRwdXQgPSBOdW1iZXJTcGVsbGVyLnNwZWxsSW50ZWdlcih2YWx1ZSwge2xvY2FsZTogb3B0aW9ucz8ubG9jYWxlfSkgKyBcIiBcIisgU3RyaW5ncy5nZXRMYXN0VG9rZW4ob3V0cHV0LCBcIiBcIilbMF07XG4gICAgfVxuICAgIHJldHVybiBvdXRwdXQ7XG4gIH1cblxufVxuIl19