UNPKG

@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

239 lines 39.3 kB
/** * This class is based on the following excellent work: *********************************************************************************************** * Javascript-number-formatter * Lightweight & Fast JavaScript Number Formatter * * @preserve IntegraXor Web SCADA - JavaScript Number Formatter (http://www.integraxor.com/) * @author KPL * @maintainer Rob Garrison * @copyright 2019 ecava * @license MIT * @link http://mottie.github.com/javascript-number-formatter/ * @version 2.0.9 ***********************************************************************************************/ import { Arrays } from "../../Arrays"; import { Numbers } from "../../Numbers"; import { Strings } from "../../Strings"; import { Locale } from "../Locale"; import { NumberFormat } from "./NumberFormat"; const maskRegex = /[0-9\-+#]/; const notMaskRegex = /[^\d\-+#]/g; const DEFAULT_PATTERN = "[Default]"; const MAX_DECIMAL_PATTERNS = 4; /** * Decimal number formatter is a concrete subclass of `NumberFormat` that formats decimal numbers. * It has a variety of features designed to make it possible to parse and format numbers in any locale. It also supports different kinds of * numbers, including integers (123), fixed-point numbers (123.4), scientific notation (1.23E4), percentages (12%), and * currency amounts ($123). * * A number display format can have up to four _sections_. Only the first is required. The three other sections determine how the data displays if its value is negative, zero, or _null_. The sections are separated by semi-colons: * `positive-format;negative-format;zero-format;null-format`. For example: #,##0.00;(#,##0.00);-;empty * * You can use special characters: * - \# - A number * - 0 - A required number; a number will display for every 0 in the mask * * Percent signs, decimal points, parentheses, and spaces display as entered in the mask. * * In general, a number display format should include at least one 0. If users enter 0 in a field with the mask ###, the field will appear to be blank if you do not provide a zero-format section. If the mask is ###.##, only the period displays. If you want two decimal places to display even if both are 0, use the mask ##0.00. * * You can use a few _keywords_ also. Enclose display format keywords in square brackets ([]). For example, you can use the keyword [General] or [Default] when you want to determine the localized format for a decimal number. Four other available keywords are * _Decimal_, _Currency_, _Unit_ and _Percent_. All keywords are case insensitive. * @since 0.5.0 * @license MIT, (c) 2022 ALEXANDER STRELKOV, alv.strelkov@gmail.com */ export class DecimalFormat extends NumberFormat { constructor(pattern = DEFAULT_PATTERN, options) { super(); this._maskObjects = Array(MAX_DECIMAL_PATTERNS).fill({}); const locales = options?.locales instanceof Locale ? options.locales.fullName : options?.locales; this._options = { ...options }; this._pattern = (Strings.trimAll(pattern) || DEFAULT_PATTERN); this._subpatterns = Arrays.padEnd(this._pattern.split(";"), MAX_DECIMAL_PATTERNS, ""); this._subpatterns.map((val, idx, arr) => arr[idx] = val.trim()); try { const checkMask = Strings.replaceAll(this._pattern, " ", "").toLowerCase(); switch (checkMask) { case NumberFormat.DEFAULT: case NumberFormat.DECIMAL: case "[general]": this._formatter = new Intl.NumberFormat(locales, options); this._subpatterns.length = 0; break; case NumberFormat.CURRENCY: this._formatter = new Intl.NumberFormat(locales, { style: "currency", currency: options?.currency }); this._subpatterns.length = 0; break; case NumberFormat.UNIT: this._formatter = new Intl.NumberFormat(locales, { style: "unit", unit: options?.unit }); this._subpatterns.length = 0; break; case NumberFormat.PERCENT: this._formatter = new Intl.NumberFormat(locales, { style: "percent" }); this._subpatterns.length = 0; break; default: // do masks' parsing ourself this._maskObjects.map((val, idx, arr) => { arr[idx] = this._parseDisplayMask(this._subpatterns[idx]); }); } } catch (e) { // May be one of these conditions occurs: // 1) 'style' is "currency", but 'currency' property value is not valid or empty // 2) 'style' is "unit", but 'unit' property value is not valid or empty // So, we apply default decimal formatter for now, but will append '[?]' text to the end of 'format()'s method output this._error = e; this._options.currency = this._options.unit = undefined; this._formatter = new Intl.NumberFormat(locales, this._options); this._subpatterns.length = 0; } } _getIndex(mask) { return mask.search(maskRegex); } _parseDisplayMask(mask = "#.##") { const maskObj = { integer: "", fraction: "", mask: "", prefix: "", suffix: "" }; const len = mask.length; if (len == 0) { return maskObj; } const start = this._getIndex(mask); if (start < 0) { maskObj.prefix = mask; maskObj.mask = ""; return maskObj; } maskObj.prefix = start > 0 ? mask.substring(0, start) : ""; // Reverse string: not an ideal method if there are surrogate pairs const end = this._getIndex(mask.split("").reverse().join("")); const offset = len - end; const substr = mask.substring(offset, offset + 1); // Add 1 to offset if mask has a trailing decimal/comma const indx = offset + (".,".indexOf(substr) >= 0 ? 1 : 0); maskObj.suffix = end > 0 ? mask.substring(indx, len) : ""; maskObj.mask = mask.substring(start, indx); maskObj.maskHasNegativeSign = maskObj.mask.charAt(0) === "-"; maskObj.maskHasPositiveSign = maskObj.mask.charAt(0) === "+"; // Search for group separator & decimal; anything not digit, // not +/- sign, and not # let result = maskObj.mask.match(notMaskRegex); // Treat the right most symbol as decimal maskObj.decimal = (result && result[result.length - 1]) || "."; // Treat the left most symbol as group separator maskObj.separator = (result && result[1] && result[0]) || ","; // Split the decimal for the format string if any let splittedDec = maskObj.mask.split(maskObj.decimal); maskObj.integer = splittedDec[0] || ""; maskObj.fraction = splittedDec[1] || ""; return maskObj; } _processValue(value, maskObj, options) { const valObj = { value, integer: "", fraction: "", sign: "" }; let isNegative = (value < 0); if (isNegative) { // Process only abs(), and turn on flag. valObj.value = -value; valObj.sign = "-"; } let multiplier = 1.0; if (maskObj.suffix.trim() == "%" || maskObj.prefix.trim() == "%") { multiplier = 100.0; } valObj.value = Numbers.round(+valObj.value * multiplier, maskObj.fraction.length); // Convert number to string to trim off *all* trailing decimal zero(es) //valObj.value = Number(valObj.value).toString(); valObj.value = String(valObj.value); // Fill back any trailing zero according to format // look for last zero in format const posTrailZero = maskObj.fraction.lastIndexOf("0") || -1; let [valInteger = "0", valFraction = ""] = valObj.value.split("."); if (!valFraction || (valFraction && valFraction.length <= posTrailZero)) { valFraction = posTrailZero < 0 ? "" : (Number("0." + valFraction).toFixed(posTrailZero + 1)).replace("0.", ""); } valObj.integer = valInteger; valObj.fraction = valFraction; this._addSeparators(valObj, maskObj); // Remove negative sign if result is zero if (valObj.result === "0" || valObj.result === "") { // Remove negative sign if result is zero isNegative = false; valObj.sign = ""; } if (!isNegative && maskObj.maskHasPositiveSign) { valObj.sign = "+"; } else if (isNegative && maskObj.maskHasPositiveSign) { valObj.sign = "-"; } else if (isNegative) { valObj.sign = options.enforceMaskSign && !maskObj.maskHasNegativeSign ? "" : "-"; } return valObj; } _addSeparators(valObj, maskObj) { valObj.result = ""; // Look for separator const szSep = maskObj.integer.split(maskObj.separator || ""); // Join back without separator for counting the pos of any leading 0 const maskInteger = szSep.join(""); const posLeadZero = maskInteger.indexOf("0"); if (posLeadZero > -1) { valObj.integer = valObj.integer.padStart(maskInteger.length - posLeadZero, "0"); } else if (Number(valObj.integer) === 0) { valObj.integer = ""; } // Process the first group separator from decimal (.) only, the rest ignore. // get the length of the last slice of split result. const posSeparator = (szSep[1] && szSep[szSep.length - 1].length); if (posSeparator) { const len = valObj.integer?.length || 0; const offset = len % posSeparator; for (let indx = 0; indx < len; indx++) { valObj.result += valObj.integer.charAt(indx); // -posSeparator so that won't trail separator on full length if (!((indx - offset + 1) % posSeparator) && indx < len - posSeparator) { valObj.result += maskObj.separator; } } } else { valObj.result = valObj.integer; } valObj.result += (maskObj.fraction && valObj.fraction) ? maskObj.decimal + valObj.fraction : ""; } /** * @override */ format(value) { if (value == null || isNaN(Number(value))) { // Null or invalid inputs return (this._subpatterns[3] || ""); } if (this._formatter) { // Intl formatter was defined return this._formatter.format(value) + (this._error ? " [?]" : ""); } let enforceMaskSign = false; let maskObj = this._maskObjects[0]; if (value == 0 && this._subpatterns[2] != "") { maskObj = this._maskObjects[2]; } else if (value < 0 && this._subpatterns[1] != "") { maskObj = this._maskObjects[1]; enforceMaskSign = true; } //const maskObj = this._parseDisplayMask(pattern); const valObj = this._processValue(value, maskObj, { ...this._options, enforceMaskSign }); return `${maskObj.prefix}${valObj.sign}${valObj.result}${maskObj.suffix}`; } ; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiRGVjaW1hbEZvcm1hdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2N1dGUtY29yZS9zcmMvbGliL3V0aWwvaTE4bi90ZXh0L0RlY2ltYWxGb3JtYXQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUE7Ozs7Ozs7Ozs7Ozs7aUdBYWlHO0FBRWpHLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxjQUFjLENBQUM7QUFDdEMsT0FBTyxFQUFFLE9BQU8sRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUN4QyxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ3hDLE9BQU8sRUFBRSxNQUFNLEVBQUUsTUFBTSxXQUFXLENBQUM7QUFDbkMsT0FBTyxFQUFFLFlBQVksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBd0I5QyxNQUFNLFNBQVMsR0FBRyxXQUFXLENBQUM7QUFDOUIsTUFBTSxZQUFZLEdBQUcsWUFBWSxDQUFDO0FBRWxDLE1BQU0sZUFBZSxHQUFTLFdBQVcsQ0FBQztBQUMxQyxNQUFNLG9CQUFvQixHQUFJLENBQUMsQ0FBQztBQUVoQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBcUJHO0FBQ0gsTUFBTSxPQUFPLGFBQWMsU0FBUSxZQUFZO0lBUzdDLFlBQVksVUFBa0IsZUFBZSxFQUFFLE9BQThCO1FBQzNFLEtBQUssRUFBRSxDQUFDO1FBSkYsaUJBQVksR0FBaUIsS0FBSyxDQUFDLG9CQUFvQixDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBTXhFLE1BQU0sT0FBTyxHQUFHLE9BQU8sRUFBRSxPQUFPLFlBQVksTUFBTSxDQUFDLENBQUMsQ0FBQyxPQUFPLENBQUMsT0FBTyxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQztRQUVqRyxJQUFJLENBQUMsUUFBUSxHQUFHLEVBQUUsR0FBRyxPQUFPLEVBQUUsQ0FBQztRQUMvQixJQUFJLENB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TUFBTSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxDQUFDO1NBQ3BFO1FBRUQsSUFBSSxlQUFlLEdBQUcsS0FBSyxDQUFDO1FBQzVCLElBQUksT0FBTyxHQUFHLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLENBQUM7UUFDbkMsSUFBSSxLQUFLLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQzVDLE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1NBQ2hDO2FBQU0sSUFBSSxLQUFLLEdBQUcsQ0FBQyxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksRUFBRSxFQUFFO1lBQ2xELE9BQU8sR0FBRyxJQUFJLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLGVBQWUsR0FBRyxJQUFJLENBQUM7U0FDeEI7UUFFRCxrREFBa0Q7UUFDbEQsTUFBTSxNQUFNLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsT0FBTyxFQUFFLEVBQUUsR0FBRyxJQUFJLENBQUMsUUFBUSxFQUFFLGVBQWUsRUFBRSxDQUFDLENBQUM7UUFDekYsT0FBTyxHQUFHLE9BQU8sQ0FBQyxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksR0FBRyxNQUFNLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQztJQUM1RSxDQUFDO0lBQUEsQ0FBQztDQUVIIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiAgICAgICAgICAgICAgICAgICAgVGhpcyBjbGFzcyBpcyBiYXNlZCBvbiB0aGUgZm9sbG93aW5nIGV4Y2VsbGVudCB3b3JrOlxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqXG4gKiBKYXZhc2NyaXB0LW51bWJlci1mb3JtYXR0ZXJcbiAqIExpZ2h0d2VpZ2h0ICYgRmFzdCBKYXZhU2NyaXB0IE51bWJlciBGb3JtYXR0ZXJcbiAqXG4gKiBAcHJlc2VydmUgSW50ZWdyYVhvciBXZWIgU0NBREEgLSBKYXZhU2NyaXB0IE51bWJlciBGb3JtYXR0ZXIgKGh0dHA6Ly93d3cuaW50ZWdyYXhvci5jb20vKVxuICogQGF1dGhvciBLUExcbiAqIEBtYWludGFpbmVyIFJvYiBHYXJyaXNvblxuICogQGNvcHlyaWdodCAyMDE5IGVjYXZhXG4gKiBAbGljZW5zZSBNSVRcbiAqIEBsaW5rIGh0dHA6Ly9tb3R0aWUuZ2l0aHViLmNvbS9qYXZhc2NyaXB0LW51bWJlci1mb3JtYXR0ZXIvXG4gKiBAdmVyc2lvbiAyLjAuOVxuICoqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqKioqL1xuXG5pbXBvcnQgeyBBcnJheXMgfSBmcm9tIFwiLi4vLi4vQXJyYXlzXCI7XG5pbXBvcnQgeyBOdW1iZXJzIH0gZnJvbSBcIi4uLy4uL051bWJlcnNcIjtcbmltcG9ydCB7IFN0cmluZ3MgfSBmcm9tIFwiLi4vLi4vU3RyaW5nc1wiO1xuaW1wb3J0IHsgTG9jYWxlIH0gZnJvbSBcIi4uL0xvY2FsZVwiO1xuaW1wb3J0IHsgTnVtYmVyRm9ybWF0IH0gZnJvbSBcIi4vTnVtYmVyRm9ybWF0XCI7XG5cbnR5cGUgTWFza09iamVjdCA9IHtcbiAgaW50ZWdlcjogc3RyaW5nLFxuICBmcmFjdGlvbjogc3RyaW5nLFxuICBkZWNpbWFsPzogc3RyaW5nLFxuICBzZXBhcmF0b3I/OiBzdHJpbmcsXG4gIHByZWZpeDogc3RyaW5nLFxuICBzdWZmaXg6IHN0cmluZyxcbiAgbWFzazogc3RyaW5nLFxuICBtYXNrSGFzTmVnYXRpdmVTaWduPzogYm9vbGVhbixcbiAgbWFza0hhc1Bvc2l0aXZlU2lnbj86IGJvb2xlYW5cbn07XG5cbnR5cGUgVmFsdWVPYmplY3QgPSB7XG4gIHZhbHVlOiBudW1iZXIgfCBzdHJpbmcsXG4gIGludGVnZXI6IHN0cmluZyxcbiAgZnJhY3Rpb246IHN0cmluZyxcbiAgc2lnbjogc3RyaW5nLFxuICByZXN1bHQ/OiBzdHJpbmdcbn07XG5cbmV4cG9ydCB0eXBlIERlY2ltYWxGb3JtYXRPcHRpb25zID0gT21pdDxJbnRsLk51bWJlckZvcm1hdE9wdGlvbnMsIFwic3R5bGVcIj4gJiB7IGxvY2FsZXM/OiBzdHJpbmcgfCBzdHJpbmdbXSB8IExvY2FsZSB9O1xuXG5jb25zdCBtYXNrUmVnZXggPSAvWzAtOVxcLSsjXS87XG5jb25zdCBub3RNYXNrUmVnZXggPSAvW15cXGRcXC0rI10vZztcblxuY29uc3QgREVGQVVMVF9QQVRURVJOICAgICAgID0gXCJbRGVmYXVsdF1cIjtcbmNvbnN0IE1BWF9ERUNJTUFMX1BBVFRFUk5TICA9IDQ7XG5cbi8qKlxuICogRGVjaW1hbCBudW1iZXIgZm9ybWF0dGVyIGlzIGEgY29uY3JldGUgc3ViY2xhc3Mgb2YgYE51bWJlckZvcm1hdGAgdGhhdCBmb3JtYXRzIGRlY2ltYWwgbnVtYmVycy5cbiAqIEl0IGhhcyBhIHZhcmlldHkgb2YgZmVhdHVyZXMgZGVzaWduZWQgdG8gbWFrZSBpdCBwb3NzaWJsZSB0byBwYXJzZSBhbmQgZm9ybWF0IG51bWJlcnMgaW4gYW55IGxvY2FsZS4gSXQgYWxzbyBzdXBwb3J0cyBkaWZmZXJlbnQga2luZHMgb2ZcbiAqIG51bWJlcnMsIGluY2x1ZGluZyBpbnRlZ2VycyAoMTIzKSwgZml4ZWQtcG9pbnQgbnVtYmVycyAoMTIzLjQpLCBzY2llbnRpZmljIG5vdGF0aW9uICgxLjIzRTQpLCBwZXJjZW50YWdlcyAoMTIlKSwgYW5kXG4gKiBjdXJyZW5jeSBhbW91bnRzICgkMTIzKS5cbiAqXG4gKiBBIG51bWJlciBkaXNwbGF5IGZvcm1hdCBjYW4gaGF2ZSB1cCB0byBmb3VyIF9zZWN0aW9uc18uIE9ubHkgdGhlIGZpcnN0IGlzIHJlcXVpcmVkLiBUaGUgdGhyZWUgb3RoZXIgc2VjdGlvbnMgZGV0ZXJtaW5lIGhvdyB0aGUgZGF0YSBkaXNwbGF5cyBpZiBpdHMgdmFsdWUgaXMgbmVnYXRpdmUsIHplcm8sIG9yIF9udWxsXy4gVGhlIHNlY3Rpb25zIGFyZSBzZXBhcmF0ZWQgYnkgc2VtaS1jb2xvbnM6XG4gKiBgcG9zaXRpdmUtZm9ybWF0O25lZ2F0aXZlLWZvcm1hdDt6ZXJvLWZvcm1hdDtudWxsLWZvcm1hdGAuIEZvciBleGFtcGxlOiAgIywjIzAuMDA7KCMsIyMwLjAwKTstO2VtcHR5XG4gKlxuICogWW91IGNhbiB1c2Ugc3BlY2lhbCBjaGFyYWN0ZXJzOlxuICogLSBcXCMgLSBBIG51bWJlclxuICogLSAwIC0gQSByZXF1aXJlZCBudW1iZXI7IGEgbnVtYmVyIHdpbGwgZGlzcGxheSBmb3IgZXZlcnkgMCBpbiB0aGUgbWFza1xuICpcbiAqIFBlcmNlbnQgc2lnbnMsIGRlY2ltYWwgcG9pbnRzLCBwYXJlbnRoZXNlcywgYW5kIHNwYWNlcyBkaXNwbGF5IGFzIGVudGVyZWQgaW4gdGhlIG1hc2suXG4gKlxuICogSW4gZ2VuZXJhbCwgYSBudW1iZXIgZGlzcGxheSBmb3JtYXQgc2hvdWxkIGluY2x1ZGUgYXQgbGVhc3Qgb25lIDAuIElmIHVzZXJzIGVudGVyIDAgaW4gYSBmaWVsZCB3aXRoIHRoZSBtYXNrICMjIywgdGhlIGZpZWxkIHdpbGwgYXBwZWFyIHRvIGJlIGJsYW5rIGlmIHlvdSBkbyBub3QgcHJvdmlkZSBhIHplcm8tZm9ybWF0IHNlY3Rpb24uIElmIHRoZSBtYXNrIGlzICMjIy4jIywgb25seSB0aGUgcGVyaW9kIGRpc3BsYXlzLiBJZiB5b3Ugd2FudCB0d28gZGVjaW1hbCBwbGFjZXMgdG8gZGlzcGxheSBldmVuIGlmIGJvdGggYXJlIDAsIHVzZSB0aGUgbWFzayAjIzAuMDAuXG4gKlxuICogWW91IGNhbiB1c2UgYSBmZXcgX2tleXdvcmRzXyBhbHNvLiBFbmNsb3NlIGRpc3BsYXkgZm9ybWF0IGtleXdvcmRzIGluIHNxdWFyZSBicmFja2V0cyAoW10pLiBGb3IgZXhhbXBsZSwgeW91IGNhbiB1c2UgdGhlIGtleXdvcmQgW0dlbmVyYWxdIG9yIFtEZWZhdWx0XSB3aGVuIHlvdSB3YW50IHRvIGRldGVybWluZSB0aGUgbG9jYWxpemVkIGZvcm1hdCBmb3IgYSBkZWNpbWFsIG51bWJlci4gRm91ciBvdGhlciBhdmFpbGFibGUga2V5d29yZHMgYXJlXG4gKiBfRGVjaW1hbF8sIF9DdXJyZW5jeV8sIF9Vbml0XyBhbmQgX1BlcmNlbnRfLiBBbGwga2V5d29yZHMgYXJlIGNhc2UgaW5zZW5zaXRpdmUuXG4gKiBAc2luY2UgMC41LjBcbiAqIEBsaWNlbnNlIE1JVCwgKGMpIDIwMjIgQUxFWEFOREVSIFNUUkVMS09WLCBhbHYuc3RyZWxrb3ZAZ21haWwuY29tXG4gKi9cbmV4cG9ydCBjbGFzcyBEZWNpbWFsRm9ybWF0IGV4dGVuZHMgTnVtYmVyRm9ybWF0IHtcblxuICBwcml2YXRlIF9mb3JtYXR0ZXI6IEludGwuTnVtYmVyRm9ybWF0IHwgdW5kZWZpbmVkO1xuICBwcml2YXRlIF9lcnJvcjogRXJyb3IgfCB1bmRlZmluZWQ7XG4gIHByaXZhdGUgX3BhdHRlcm46IHN0cmluZztcbiAgcHJpdmF0ZSBfc3VicGF0dGVybnM6IHN0cmluZ1tdO1xuICBwcml2YXRlIF9tYXNrT2JqZWN0czogTWFza09iamVjdFtdID0gQXJyYXkoTUFYX0RFQ0lNQUxfUEFUVEVSTlMpLmZpbGwoe30pO1xuICBwcml2YXRlIF9vcHRpb25zOiBEZWNpbWFsRm9ybWF0T3B0aW9ucztcblxuICBjb25zdHJ1Y3RvcihwYXR0ZXJuOiBzdHJpbmcgPSBERUZBVUxUX1BBVFRFUk4sIG9wdGlvbnM/OiBEZWNpbWFsRm9ybWF0T3B0aW9ucykge1xuICAgIHN1cGVyKCk7XG5cbiAgICBjb25zdCBsb2NhbGVzID0gb3B0aW9ucz8ubG9jYWxlcyBpbnN0YW5jZW9mIExvY2FsZSA/IG9wdGlvbnMubG9jYWxlcy5mdWxsTmFtZSA6IG9wdGlvbnM/LmxvY2FsZXM7XG5cbiAgICB0aGlzLl9vcHRpb25zID0geyAuLi5vcHRpb25zIH07XG4gICAgdGhpcy5fcGF0dGVybiA9IChTdHJpbmdzLnRyaW1BbGwocGF0dGVybikgfHwgREVGQVVMVF9QQVRURVJOKTtcbiAgICB0aGlzLl9zdWJwYXR0ZXJucyA9IEFycmF5cy5wYWRFbmQodGhpcy5fcGF0dGVybi5zcGxpdChcIjtcIiksIE1BWF9ERUNJTUFMX1BBVFRFUk5TLCBcIlwiKTtcbiAgICB0aGlzLl9zdWJwYXR0ZXJucy5tYXAoKHZhbCwgaWR4LCBhcnIpID0+IGFycltpZHhdID0gdmFsLnRyaW0oKSk7XG5cbiAgICB0cnkge1xuICAgICAgY29uc3QgY2hlY2tNYXNrID0gU3RyaW5ncy5yZXBsYWNlQWxsKHRoaXMuX3BhdHRlcm4sIFwiIFwiLCBcIlwiKSEudG9Mb3dlckNhc2UoKVxuICAgICAgc3dpdGNoIChjaGVja01hc2spIHtcbiAgICAgICAgY2FzZSBOdW1iZXJGb3JtYXQuREVGQVVMVDpcbiAgICAgICAgY2FzZSBOdW1iZXJGb3JtYXQuREVDSU1BTDpcbiAgICAgICAgY2FzZSBcIltnZW5lcmFsXVwiOlxuICAgICAgICAgIHRoaXMuX2Zvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGVzLCBvcHRpb25zKTtcbiAgICAgICAgICB0aGlzLl9zdWJwYXR0ZXJucy5sZW5ndGggPSAwO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIE51bWJlckZvcm1hdC5DVVJSRU5DWTpcbiAgICAgICAgICB0aGlzLl9mb3JtYXR0ZXIgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jYWxlcywgeyBzdHlsZTogXCJjdXJyZW5jeVwiLCBjdXJyZW5jeTogb3B0aW9ucz8uY3VycmVuY3kgfSk7XG4gICAgICAgICAgdGhpcy5fc3VicGF0dGVybnMubGVuZ3RoID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBOdW1iZXJGb3JtYXQuVU5JVDpcbiAgICAgICAgICB0aGlzLl9mb3JtYXR0ZXIgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jYWxlcywgeyBzdHlsZTogXCJ1bml0XCIsIHVuaXQ6IG9wdGlvbnM/LnVuaXQgfSk7XG4gICAgICAgICAgdGhpcy5fc3VicGF0dGVybnMubGVuZ3RoID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgY2FzZSBOdW1iZXJGb3JtYXQuUEVSQ0VOVDpcbiAgICAgICAgICB0aGlzLl9mb3JtYXR0ZXIgPSBuZXcgSW50bC5OdW1iZXJGb3JtYXQobG9jYWxlcywgeyBzdHlsZTogXCJwZXJjZW50XCIgfSk7XG4gICAgICAgICAgdGhpcy5fc3VicGF0dGVybnMubGVuZ3RoID0gMDtcbiAgICAgICAgICBicmVhaztcbiAgICAgICAgZGVmYXVsdDpcbiAgICAgICAgICAvLyBkbyBtYXNrcycgcGFyc2luZyBvdXJzZWxmXG4gICAgICAgICAgdGhpcy5fbWFza09iamVjdHMubWFwKCh2YWwsIGlkeCwgYXJyKSA9PiB7IGFycltpZHhdID0gdGhpcy5fcGFyc2VEaXNwbGF5TWFzayh0aGlzLl9zdWJwYXR0ZXJuc1tpZHhdKSB9KTtcbiAgICAgIH1cbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBNYXkgYmUgb25lIG9mIHRoZXNlIGNvbmRpdGlvbnMgb2NjdXJzOlxuICAgICAgLy8gMSkgJ3N0eWxlJyBpcyBcImN1cnJlbmN5XCIsIGJ1dCAnY3VycmVuY3knIHByb3BlcnR5IHZhbHVlIGlzIG5vdCB2YWxpZCBvciBlbXB0eVxuICAgICAgLy8gMikgJ3N0eWxlJyBpcyBcInVuaXRcIiwgYnV0ICd1bml0JyBwcm9wZXJ0eSB2YWx1ZSBpcyBub3QgdmFsaWQgb3IgZW1wdHlcbiAgICAgIC8vIFNvLCB3ZSBhcHBseSBkZWZhdWx0IGRlY2ltYWwgZm9ybWF0dGVyIGZvciBub3csIGJ1dCB3aWxsIGFwcGVuZCAnWz9dJyB0ZXh0IHRvIHRoZSBlbmQgb2YgJ2Zvcm1hdCgpJ3MgbWV0aG9kIG91dHB1dFxuICAgICAgdGhpcy5fZXJyb3IgPSBlIGFzIEVycm9yO1xuICAgICAgdGhpcy5fb3B0aW9ucy5jdXJyZW5jeSA9IHRoaXMuX29wdGlvbnMudW5pdCA9IHVuZGVmaW5lZDtcbiAgICAgIHRoaXMuX2Zvcm1hdHRlciA9IG5ldyBJbnRsLk51bWJlckZvcm1hdChsb2NhbGVzLCB0aGlzLl9vcHRpb25zKTtcbiAgICAgIHRoaXMuX3N1YnBhdHRlcm5zLmxlbmd0aCA9IDA7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfZ2V0SW5kZXgobWFzazogc3RyaW5nKTogbnVtYmVyIHtcbiAgICByZXR1cm4gbWFzay5zZWFyY2gobWFza1JlZ2V4KTtcbiAgfVxuXG4gIHByaXZhdGUgX3BhcnNlRGlzcGxheU1hc2sobWFzazogc3RyaW5nID0gXCIjLiMjXCIpOiBNYXNrT2JqZWN0IHtcbiAgICBjb25zdCBtYXNrT2JqOiBNYXNrT2JqZWN0ID0geyBpbnRlZ2VyOiBcIlwiLCBmcmFjdGlvbjogXCJcIiwgbWFzazogXCJcIiwgcHJlZml4OiBcIlwiLCBzdWZmaXg6IFwiXCIgfTtcbiAgICBjb25zdCBsZW4gPSBtYXNrLmxlbmd0aDtcblxuICAgIGlmIChsZW4gPT0gMCkge1xuICAgICAgcmV0dXJuIG1hc2tPYmo7XG4gICAgfVxuXG4gICAgY29uc3Qgc3RhcnQgPSB0aGlzLl9nZXRJbmRleChtYXNrKTtcbiAgICBpZiAoc3RhcnQgPCAwKSB7XG4gICAgICBtYXNrT2JqLnByZWZpeCA9IG1hc2s7XG4gICAgICBtYXNrT2JqLm1hc2sgPSBcIlwiO1xuICAgICAgcmV0dXJuIG1hc2tPYmo7XG4gICAgfVxuICAgIG1hc2tPYmoucHJlZml4ID0gc3RhcnQgPiAwID8gbWFzay5zdWJzdHJpbmcoMCwgc3RhcnQpIDogXCJcIjtcblxuICAgIC8vIFJldmVyc2Ugc3RyaW5nOiBub3QgYW4gaWRlYWwgbWV0aG9kIGlmIHRoZXJlIGFyZSBzdXJyb2dhdGUgcGFpcnNcbiAgICBjb25zdCBlbmQgPSB0aGlzLl9nZXRJbmRleChtYXNrLnNwbGl0KFwiXCIpLnJldmVyc2UoKS5qb2luKFwiXCIpKTtcbiAgICBjb25zdCBvZmZzZXQgPSBsZW4gLSBlbmQ7XG4gICAgY29uc3Qgc3Vic3RyID0gbWFzay5zdWJzdHJpbmcob2Zmc2V0LCBvZmZzZXQgKyAxKTtcbiAgICAvLyBBZGQgMSB0byBvZmZzZXQgaWYgbWFzayBoYXMgYSB0cmFpbGluZyBkZWNpbWFsL2NvbW1hXG4gICAgY29uc3QgaW5keCA9IG9mZnNldCArIChcIi4sXCIuaW5kZXhPZihzdWJzdHIpID49IDAgPyAxIDogMCk7XG4gICAgbWFza09iai5zdWZmaXggPSBlbmQgPiAwID8gbWFzay5zdWJzdHJpbmcoaW5keCwgbGVuKSA6IFwiXCI7XG5cbiAgICBtYXNrT2JqLm1hc2sgPSBtYXNrLnN1YnN0cmluZyhzdGFydCwgaW5keCk7XG4gICAgbWFza09iai5tYXNrSGFzTmVnYXRpdmVTaWduID0gbWFza09iai5tYXNrLmNoYXJBdCgwKSA9PT0gXCItXCI7XG4gICAgbWFza09iai5tYXNrSGFzUG9zaXRpdmVTaWduID0gbWFza09iai5tYXNrLmNoYXJBdCgwKSA9PT0gXCIrXCI7XG5cbiAgICAvLyBTZWFyY2ggZm9yIGdyb3VwIHNlcGFyYXRvciAmIGRlY2ltYWw7IGFueXRoaW5nIG5vdCBkaWdpdCxcbiAgICAvLyBub3QgKy8tIHNpZ24sIGFuZCBub3QgI1xuICAgIGxldCByZXN1bHQgPSBtYXNrT2JqLm1hc2subWF0Y2gobm90TWFza1JlZ2V4KTtcbiAgICAvLyBUcmVhdCB0aGUgcmlnaHQgbW9zdCBzeW1ib2wgYXMgZGVjaW1hbFxuICAgIG1hc2tPYmouZGVjaW1hbCA9IChyZXN1bHQgJiYgcmVzdWx0W3Jlc3VsdC5sZW5ndGggLSAxXSkgfHwgXCIuXCI7XG4gICAgLy8gVHJlYXQgdGhlIGxlZnQgbW9zdCBzeW1ib2wgYXMgZ3JvdXAgc2VwYXJhdG9yXG4gICAgbWFza09iai5zZXBhcmF0b3IgPSAocmVzdWx0ICYmIHJlc3VsdFsxXSAmJiByZXN1bHRbMF0pIHx8IFwiLFwiO1xuXG4gICAgLy8gU3BsaXQgdGhlIGRlY2ltYWwgZm9yIHRoZSBmb3JtYXQgc3RyaW5nIGlmIGFueVxuICAgIGxldCBzcGxpdHRlZERlYyA9IG1hc2tPYmoubWFzay5zcGxpdChtYXNrT2JqLmRlY2ltYWwpO1xuICAgIG1hc2tPYmouaW50ZWdlciA9IHNwbGl0dGVkRGVjWzBdIHx8IFwiXCI7XG4gICAgbWFza09iai5mcmFjdGlvbiA9IHNwbGl0dGVkRGVjWzFdIHx8IFwiXCI7XG4gICAgcmV0dXJuIG1hc2tPYmo7XG4gIH1cblxuICBwcml2YXRlIF9wcm9jZXNzVmFsdWUodmFsdWU6IG51bWJlciwgbWFza09iajogTWFza09iamVjdCwgb3B0aW9uczogSW50bC5OdW1iZXJGb3JtYXRPcHRpb25zICYgeyBlbmZvcmNlTWFza1NpZ24/OiBib29sZWFuIH0pIHtcbiAgICBjb25zdCB2YWxPYmo6IFZhbHVlT2JqZWN0ID0geyB2YWx1ZSwgaW50ZWdlcjogXCJcIiwgZnJhY3Rpb246IFwiXCIsIHNpZ246IFwiXCIgfTtcbiAgICBsZXQgaXNOZWdhdGl2ZSA9ICh2YWx1ZSA8IDApO1xuICAgIGlmIChpc05lZ2F0aXZlKSB7XG4gICAgICAvLyBQcm9jZXNzIG9ubHkgYWJzKCksIGFuZCB0dXJuIG9uIGZsYWcuXG4gICAgICB2YWxPYmoudmFsdWUgPSAtdmFsdWU7XG4gICAgICB2YWxPYmouc2lnbiA9IFwiLVwiO1xuICAgIH1cblxuICAgIGxldCBtdWx0aXBsaWVyID0gMS4wO1xuICAgIGlmIChtYXNrT2JqLnN1ZmZpeC50cmltKCkgPT0gXCIlXCIgfHwgbWFza09iai5wcmVmaXgudHJpbSgpID09IFwiJVwiKSB7XG4gICAgICBtdWx0aXBsaWVyID0gMTAwLjA7XG4gICAgfVxuICAgIHZhbE9iai52YWx1ZSA9IE51bWJlcnMucm91bmQoK3ZhbE9iai52YWx1ZSAqIG11bHRpcGxpZXIsIG1hc2tPYmouZnJhY3Rpb24ubGVuZ3RoKTtcbiAgICAvLyBDb252ZXJ0IG51bWJlciB0byBzdHJpbmcgdG8gdHJpbSBvZmYgKmFsbCogdHJhaWxpbmcgZGVjaW1hbCB6ZXJvKGVzKVxuICAgIC8vdmFsT2JqLnZhbHVlID0gTnVtYmVyKHZhbE9iai52YWx1ZSkudG9TdHJpbmcoKTtcbiAgICB2YWxPYmoudmFsdWUgPSBTdHJpbmcodmFsT2JqLnZhbHVlKTtcblxuICAgIC8vIEZpbGwgYmFjayBhbnkgdHJhaWxpbmcgemVybyBhY2NvcmRpbmcgdG8gZm9ybWF0XG4gICAgLy8gbG9vayBmb3IgbGFzdCB6ZXJvIGluIGZvcm1hdFxuICAgIGNvbnN0IHBvc1RyYWlsWmVybyA9IG1hc2tPYmouZnJhY3Rpb24ubGFzdEluZGV4T2YoXCIwXCIpIHx8IC0xO1xuICAgIGxldCBbdmFsSW50ZWdlciA9IFwiMFwiLCB2YWxGcmFjdGlvbiA9IFwiXCJdID0gdmFsT2JqLnZhbHVlLnNwbGl0KFwiLlwiKTtcbiAgICBpZiAoIXZhbEZyYWN0aW9uIHx8ICh2YWxGcmFjdGlvbiAmJiB2YWxGcmFjdGlvbi5sZW5ndGggPD0gcG9zVHJhaWxaZXJvKSkge1xuICAgICAgdmFsRnJhY3Rpb24gPSBwb3NUcmFpbFplcm8gPCAwXG4gICAgICAgID8gXCJcIlxuICAgICAgICA6IChOdW1iZXIoXCIwLlwiICsgdmFsRnJhY3Rpb24pLnRvRml4ZWQocG9zVHJhaWxaZXJvICsgMSkpLnJlcGxhY2UoXCIwLlwiLCBcIlwiKTtcbiAgICB9XG5cbiAgICB2YWxPYmouaW50ZWdlciA9IHZhbEludGVnZXI7XG4gICAgdmFsT2JqLmZyYWN0aW9uID0gdmFsRnJhY3Rpb247XG4gICAgdGhpcy5fYWRkU2VwYXJhdG9ycyh2YWxPYmosIG1hc2tPYmopO1xuXG4gICAgLy8gUmVtb3ZlIG5lZ2F0aXZlIHNpZ24gaWYgcmVzdWx0IGlzIHplcm9cbiAgICBpZiAodmFsT2JqLnJlc3VsdCA9PT0gXCIwXCIgfHwgdmFsT2JqLnJlc3VsdCA9PT0gXCJcIikge1xuICAgICAgLy8gUmVtb3ZlIG5lZ2F0aXZlIHNpZ24gaWYgcmVzdWx0IGlzIHplcm9cbiAgICAgIGlzTmVnYXRpdmUgPSBmYWxzZTtcbiAgICAgIHZhbE9iai5zaWduID0gXCJcIjtcbiAgICB9XG5cbiAgICBpZiAoIWlzTmVnYXRpdmUgJiYgbWFza09iai5tYXNrSGFzUG9zaXRpdmVTaWduKSB7XG4gICAgICB2YWxPYmouc2lnbiA9IFwiK1wiO1xuICAgIH0gZWxzZSBpZiAoaXNOZWdhdGl2ZSAmJiBtYXNrT2JqLm1hc2tIYXNQb3NpdGl2ZVNpZ24pIHtcbiAgICAgIHZhbE9iai5zaWduID0gXCItXCI7XG4gICAgfSBlbHNlIGlmIChpc05lZ2F0aXZlKSB7XG4gICAgICB2YWxPYmouc2lnbiA9IG9wdGlvbnMuZW5mb3JjZU1hc2tTaWduICYmICFtYXNrT2JqLm1hc2tIYXNOZWdhdGl2ZVNpZ25cbiAgICAgICAgPyBcIlwiXG4gICAgICAgIDogXCItXCI7XG4gICAgfVxuXG4gICAgcmV0dXJuIHZhbE9iajtcbiAgfVxuXG4gIHByaXZhdGUgX2FkZFNlcGFyYXRvcnModmFsT2JqOiBWYWx1ZU9iamVjdCwgbWFza09iajogTWFza09iamVjdCk6IHZvaWQge1xuICAgIHZhbE9iai5yZXN1bHQgPSBcIlwiO1xuICAgIC8vIExvb2sgZm9yIHNlcGFyYXRvclxuICAgIGNvbnN0IHN6U2VwID0gbWFza09iai5pbnRlZ2VyLnNwbGl0KG1hc2tPYmouc2VwYXJhdG9yIHx8IFwiXCIpO1xuICAgIC8vIEpvaW4gYmFjayB3aXRob3V0IHNlcGFyYXRvciBmb3IgY291bnRpbmcgdGhlIHBvcyBvZiBhbnkgbGVhZGluZyAwXG4gICAgY29uc3QgbWFza0ludGVnZXIgPSBzelNlcC5qb2luKFwiXCIpO1xuXG4gICAgY29uc3QgcG9zTGVhZFplcm8gPSBtYXNrSW50ZWdlci5pbmRleE9mKFwiMFwiKTtcbiAgICBpZiAocG9zTGVhZFplcm8gPiAtMSkge1xuICAgICAgdmFsT2JqLmludGVnZXIgPSB2YWxPYmouaW50ZWdlci5wYWRTdGFydChtYXNrSW50ZWdlci5sZW5ndGggLSBwb3NMZWFkWmVybywgXCIwXCIpO1xuICAgIH0gZWxzZSBpZiAoTnVtYmVyKHZhbE9iai5pbnRlZ2VyKSA9PT0gMCkge1xuICAgICAgdmFsT2JqLmludGVnZXIgPSBcIlwiO1xuICAgIH1cblxuICAgIC8vIFByb2Nlc3MgdGhlIGZpcnN0IGdyb3VwIHNlcGFyYXRvciBmcm9tIGRlY2ltYWwgKC4pIG9ubHksIHRoZSByZXN0IGlnbm9yZS5cbiAgICAvLyBnZXQgdGhlIGxlbmd0aCBvZiB0aGUgbGFzdCBzbGljZSBvZiBzcGxpdCByZXN1bHQuXG4gICAgY29uc3QgcG9zU2VwYXJhdG9yID0gKHN6U2VwWzFdICYmIHN6U2VwW3N6U2VwLmxlbmd0aCAtIDFdLmxlbmd0aCk7XG4gICAgaWYgKHBvc1NlcGFyYXRvcikge1xuICAgICAgY29uc3QgbGVuID0gdmFsT2JqLmludGVnZXI/Lmxlbmd0aCB8fCAwO1xuICAgICAgY29uc3Qgb2Zmc2V0ID0gbGVuICUgcG9zU2VwYXJhdG9yO1xuICAgICAgZm9yIChsZXQgaW5keCA9IDA7IGluZHggPCBsZW47IGluZHgrKykge1xuICAgICAgICB2YWxPYmoucmVzdWx0ICs9IHZhbE9iai5pbnRlZ2VyLmNoYXJBdChpbmR4KTtcbiAgICAgICAgLy8gLXBvc1NlcGFyYXRvciBzbyB0aGF0IHdvbid0IHRyYWlsIHNlcGFyYXRvciBvbiBmdWxsIGxlbmd0aFxuICAgICAgICBpZiAoISgoaW5keCAtIG9mZnNldCArIDEpICUgcG9zU2VwYXJhdG9yKSAmJiBpbmR4IDwgbGVuIC0gcG9zU2VwYXJhdG9yKSB7XG4gICAgICAgICAgdmFsT2JqLnJlc3VsdCArPSBtYXNrT2JqLnNlcGFyYXRvcjtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2YWxPYmoucmVzdWx0ID0gdmFsT2JqLmludGVnZXI7XG4gICAgfVxuXG4gICAgdmFsT2JqLnJlc3VsdCArPSAobWFza09iai5mcmFjdGlvbiAmJiB2YWxPYmouZnJhY3Rpb24pXG4gICAgICA/IG1hc2tPYmouZGVjaW1hbCArIHZhbE9iai5mcmFjdGlvblxuICAgICAgOiBcIlwiO1xuXG4gIH1cbiAgLyoqXG4gICAqIEBvdmVycmlkZVxuICAgKi9cbiAgb3ZlcnJpZGUgZm9ybWF0KHZhbHVlOiBudW1iZXIgfCBudWxsKTogc3RyaW5nIHtcblxuICAgIGlmICh2YWx1ZSA9PSBudWxsIHx8IGlzTmFOKE51bWJlcih2YWx1ZSkpKSB7XG4gICAgICAvLyBOdWxsIG9yIGludmFsaWQgaW5wdXRzXG4gICAgICByZXR1cm4gKHRoaXMuX3N1YnBhdHRlcm5zWzNdIHx8IFwiXCIpO1xuICAgIH1cblxuICAgIGlmICh0aGlzLl9mb3JtYXR0ZXIpIHtcbiAgICAgIC8vIEludGwgZm9ybWF0dGVyIHdhcyBkZWZpbmVkXG4gICAgICByZXR1cm4gdGhpcy5fZm9ybWF0dGVyLmZvcm1hdCh2YWx1ZSkgKyAodGhpcy5fZXJyb3IgPyBcIiBbP11cIiA6IFwiXCIpO1xuICAgIH1cblxuICAgIGxldCBlbmZvcmNlTWFza1NpZ24gPSBmYWxzZTtcbiAgICBsZXQgbWFza09iaiA9IHRoaXMuX21hc2tPYmplY3RzWzBdO1xuICAgIGlmICh2YWx1ZSA9PSAwICYmIHRoaXMuX3N1YnBhdHRlcm5zWzJdICE9IFwiXCIpIHtcbiAgICAgIG1hc2tPYmogPSB0aGlzLl9tYXNrT2JqZWN0c1syXTtcbiAgICB9IGVsc2UgaWYgKHZhbHVlIDwgMCAmJiB0aGlzLl9zdWJwYXR0ZXJuc1sxXSAhPSBcIlwiKSB7XG4gICAgICBtYXNrT2JqID0gdGhpcy5fbWFza09iamVjdHNbMV07XG4gICAgICBlbmZvcmNlTWFza1NpZ24gPSB0cnVlO1xuICAgIH1cblxuICAgIC8vY29uc3QgbWFza09iaiA9IHRoaXMuX3BhcnNlRGlzcGxheU1hc2socGF0dGVybik7XG4gICAgY29uc3QgdmFsT2JqID0gdGhpcy5fcHJvY2Vzc1ZhbHVlKHZhbHVlLCBtYXNrT2JqLCB7IC4uLnRoaXMuX29wdGlvbnMsIGVuZm9yY2VNYXNrU2lnbiB9KTtcbiAgICByZXR1cm4gYCR7bWFza09iai5wcmVmaXh9JHt2YWxPYmouc2lnbn0ke3ZhbE9iai5yZXN1bHR9JHttYXNrT2JqLnN1ZmZpeH1gO1xuICB9O1xuXG59XG4iXX0=