@nova-ui/bits
Version:
SolarWinds Nova Framework
219 lines • 30.5 kB
JavaScript
// © 2022 SolarWinds Worldwide, LLC. All rights reserved.
//
// Permission is hereby granted, free of charge, to any person obtaining a copy
// of this software and associated documentation files (the "Software"), to
// deal in the Software without restriction, including without limitation the
// rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
// sell copies of the Software, and to permit persons to whom the Software is
// furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in
// all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
// THE SOFTWARE.
import { Injectable } from "@angular/core";
import { LoggerService } from "./log-service";
import { UnitBase, unitConversionConstants, } from "../constants/unit-conversion.constants";
import * as i0 from "@angular/core";
import * as i1 from "./log-service";
/**
* <example-url>./../examples/index.html#/common/unit-conversion-service</example-url>
*
* Service for converting a raw value to a larger unit approximation of the value--for example, 1024 B to 1 MB, 12345 Hz to 12.35 kHz, etc.
*/
export class UnitConversionService {
constructor(logger) {
this.logger = logger;
}
/**
* Converts a raw value to a larger unit approximation of the value. For example, 1024 B to 1 KB, 12345 Hz to 12.35 kHz, etc.
*
* @param value The value to convert
* @param base The base to use for the exponential expression when calculating the conversion result
*
* @returns {{ [Key in keyof Pick<IUnitConversionResult, "value" | "order">]: number }} The value and order of conversion
*/
convertLinear(value, base) {
let resultValue;
let resultOrder;
if (value === 0) {
return {
value: 0,
order: 0,
};
}
resultOrder = Math.floor(Math.log(Math.abs(value)) / Math.log(base));
resultValue = value / Math.pow(base, Math.floor(resultOrder));
if (Math.abs(value) > 0 && Math.abs(value) < 1) {
return {
value: value,
order: 0,
};
}
// fix the precision edge case
const valueCeiled = Math.ceil(resultValue);
if (valueCeiled % base === 0) {
resultValue = valueCeiled / base;
resultOrder += 1;
}
return {
value: resultValue,
order: resultOrder,
};
}
/**
* Converts a raw value to a larger unit approximation of the value. For example, 1100ms to 1.1s, 66000ms to 1.1m, etc.
*
* @param value The value to convert
* @param factors Array of factors to use for calculating smallest possible not zero result
*
* @returns {{ [Key in keyof Pick<IUnitConversionResult, "value" | "order">]: number }} The value and order of conversion
*/
convertNonLinear(value, factors) {
const sortedFactors = factors.sort((a, b) => a > b ? -1 : a < b ? 1 : 0);
const highestFactorIndex = sortedFactors.findIndex((factor) => value / factor >= 1);
const highestFactor = factors[highestFactorIndex];
if (Math.abs(value) > 0 && Math.abs(value) < 1) {
return {
value: value,
order: 0,
};
}
return {
value: value / highestFactor,
order: highestFactorIndex === -1 ? 0 : factors.length - highestFactorIndex - 1,
};
}
/**
* Converts a raw value to a larger unit approximation of the value. For example, 1024 B to 1 KB, 12345 Hz to 12.35 kHz, 66000ms to 1.1m, etc.
*
* @param value The value to convert
* @param base The base or array of factors to use for calculating the conversion result
* @param scale The number of significant digits to the right of the decimal to include in the resulting converted value
*
* @returns {IUnitConversionResult} The conversion result
*/
convert(value, base = UnitBase.Standard, scale = 1) {
const result = Array.isArray(base) ?
this.convertNonLinear(value, base) :
this.convertLinear(value, base);
let strValue;
if (value !== 0) {
strValue = parseFloat(result.value.toFixed(scale)).toString();
}
else {
result.order = 0;
strValue = value.toString();
}
return {
value: strValue,
order: result.order,
scientificNotation: value?.toExponential(scale),
scale,
};
}
/**
* Gets the display string of a conversion result
*
* @param conversion The result of an invocation of this service's convert method
* @param unit The unit used in the conversion
* @param plusSign Whether to prepend the display string with a '+'
* @param nanDisplay The string to display in case the conversion result is NaN or Infinity
*
* @returns {string} The display string of the conversion result
*/
getFullDisplay(conversion, unit, plusSign = false, nanDisplay = "---") {
const isValidNumber = this.isValidNumber(conversion.value);
const spacing = unit !== "generic" && isValidNumber ? " " : "";
let unitDisplay = isValidNumber
? this.getUnitDisplay(conversion, unit)
: "";
// The generic unit is not currently i18n friendly
const localizeValue = unit !== "generic";
let displayValue;
if (!unitDisplay && isValidNumber && conversion.order) {
unitDisplay = this.getUnitDisplayBaseValue(unit);
displayValue = this.getScientificDisplay(conversion, plusSign, nanDisplay);
}
else {
displayValue = this.getValueDisplay(conversion, plusSign, nanDisplay, localizeValue);
}
return `${displayValue}${spacing}${unitDisplay}`;
}
/**
* Gets the converted value display string
*
* @param conversion The result of an invocation of this service's convert method
* @param plusSign Whether to prepend the display string with a '+'
* @param nanDisplay The string to display in case the conversion result is NaN or Infinity
* @param localize Whether to localize the value for display. Note: It's not recommended to localize values for
* the "generic" unit, e.g. "1.1K" for 1100, as the "generic" unit is currently not i18n friendly
*
* @returns {string} The converted value display string
*/
getValueDisplay(conversion, plusSign = false, nanDisplay = "---", localize = true) {
if (!this.isValidNumber(conversion.value)) {
return nanDisplay;
}
const outputValue = localize
? parseFloat(conversion.value).toLocaleString(undefined, {
maximumFractionDigits: conversion.scale,
})
: conversion.value;
const prefix = plusSign && parseInt(conversion.value, 10) > 0 ? "+" : "";
return `${prefix}${outputValue}`;
}
/**
* Gets the converted unit display string
*
* @param conversion The result of an invocation of this service's convert method
* @param unit The basic unit used in the conversion
*
* @returns {string} The converted unit display string
*/
getUnitDisplay(conversion, unit) {
return unitConversionConstants[unit][conversion.order];
}
/**
* Gets the base value of the converted unit
*
* @param unit The basic unit used in the conversion
*
* @returns {string} The abbreviation for the smallest unit of the provided UnitOption
*/
getUnitDisplayBaseValue(unit) {
return unitConversionConstants[unit][0];
}
/**
* Gets the converted value display string in scientific notation
*
* @param conversion The result of an invocation of this service's convert method
* @param plusSign Whether to prepend the display string with a '+'
* @param nanDisplay The string to display in case the conversion result is NaN or Infinity
*
* @returns {string} The converted value display string in scientific notation
*/
getScientificDisplay(conversion, plusSign = false, nanDisplay = "---") {
if (!this.isValidNumber(conversion.value)) {
return nanDisplay;
}
const prefix = plusSign && parseInt(conversion.value, 10) > 0 ? "+" : "";
return `${prefix}${conversion.scientificNotation}`;
}
isValidNumber(value) {
return !isNaN(parseFloat(value)) && isFinite(parseInt(value, 10));
}
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UnitConversionService, deps: [{ token: i1.LoggerService }], target: i0.ɵɵFactoryTarget.Injectable }); }
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UnitConversionService, providedIn: "root" }); }
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: UnitConversionService, decorators: [{
type: Injectable,
args: [{ providedIn: "root" }]
}], ctorParameters: () => [{ type: i1.LoggerService }] });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidW5pdC1jb252ZXJzaW9uLnNlcnZpY2UuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvc2VydmljZXMvdW5pdC1jb252ZXJzaW9uLnNlcnZpY2UudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEseURBQXlEO0FBQ3pELEVBQUU7QUFDRiwrRUFBK0U7QUFDL0UsNEVBQTRFO0FBQzVFLDhFQUE4RTtBQUM5RSwrRUFBK0U7QUFDL0UsOEVBQThFO0FBQzlFLDREQUE0RDtBQUM1RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLHVEQUF1RDtBQUN2RCxFQUFFO0FBQ0YsNkVBQTZFO0FBQzdFLDRFQUE0RTtBQUM1RSwrRUFBK0U7QUFDL0UsMEVBQTBFO0FBQzFFLGlGQUFpRjtBQUNqRiw2RUFBNkU7QUFDN0UsaUJBQWlCO0FBRWpCLE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFFM0MsT0FBTyxFQUFFLGFBQWEsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUU5QyxPQUFPLEVBQ0gsUUFBUSxFQUNSLHVCQUF1QixHQUUxQixNQUFNLHdDQUF3QyxDQUFDOzs7QUFFaEQ7Ozs7R0FJRztBQUVILE1BQU0sT0FBTyxxQkFBcUI7SUFDOUIsWUFBb0IsTUFBcUI7UUFBckIsV0FBTSxHQUFOLE1BQU0sQ0FBZTtJQUFHLENBQUM7SUFFN0M7Ozs7Ozs7T0FPRztJQUNLLGFBQWEsQ0FDakIsS0FBYSxFQUNiLElBQVk7UUFFWixJQUFJLFdBQW1CLENBQUM7UUFDeEIsSUFBSSxXQUFtQixDQUFDO1FBRXhCLElBQUksS0FBSyxLQUFLLENBQUMsRUFBRTtZQUNiLE9BQU87Z0JBQ0gsS0FBSyxFQUFFLENBQUM7Z0JBQ1IsS0FBSyxFQUFFLENBQUM7YUFDWCxDQUFDO1NBQ0w7UUFFRCxXQUFXLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FDcEIsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FDN0MsQ0FBQztRQUNGLFdBQVcsR0FBRyxLQUFLLEdBQUcsSUFBSSxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsQ0FBQyxDQUFDO1FBRTlELElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksSUFBSSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEVBQUU7WUFDNUMsT0FBTztnQkFDSCxLQUFLLEVBQUUsS0FBSztnQkFDWixLQUFLLEVBQUUsQ0FBQzthQUNYLENBQUM7U0FDTDtRQUVELDhCQUE4QjtRQUM5QixNQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQzNDLElBQUksV0FBVyxHQUFHLElBQUksS0FBSyxDQUFDLEVBQUU7WUFDMUIsV0FBVyxHQUFHLFdBQVcsR0FBRyxJQUFJLENBQUM7WUFDakMsV0FBVyxJQUFJLENBQUMsQ0FBQztTQUNwQjtRQUVELE9BQU87WUFDSCxLQUFLLEVBQUUsV0FBVztZQUNsQixLQUFLLEVBQUUsV0FBVztTQUNyQixDQUFDO0lBQ04sQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSyxnQkFBZ0IsQ0FDcEIsS0FBYSxFQUNiLE9BQWlCO1FBRWpCLE1BQU0sYUFBYSxHQUFHLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUN6RSxNQUFNLGtCQUFrQixHQUFHLGFBQWEsQ0FBQyxTQUFTLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLEtBQUssR0FBRyxNQUFNLElBQUksQ0FBQyxDQUFDLENBQUM7UUFDcEYsTUFBTSxhQUFhLEdBQUcsT0FBTyxDQUFDLGtCQUFrQixDQUFDLENBQUM7UUFFbEQsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUM1QyxPQUFPO2dCQUNILEtBQUssRUFBRSxLQUFLO2dCQUNaLEtBQUssRUFBRSxDQUFDO2FBQ1gsQ0FBQztTQUNMO1FBRUQsT0FBTztZQUNILEtBQUssRUFBRSxLQUFLLEdBQUcsYUFBYTtZQUM1QixLQUFLLEVBQUUsa0JBQWtCLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxrQkFBa0IsR0FBRyxDQUFDO1NBQ2pGLENBQUM7SUFDTixDQUFDO0lBRUQ7Ozs7Ozs7O09BUUc7SUFDSCxPQUFPLENBQ0gsS0FBYSxFQUNiLE9BQTBCLFFBQVEsQ0FBQyxRQUFRLEVBQzNDLFFBQWdCLENBQUM7UUFFakIsTUFBTSxNQUFNLEdBQUcsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2hDLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUNwQyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssRUFBRSxJQUFJLENBQUMsQ0FBQztRQUVwQyxJQUFJLFFBQWdCLENBQUM7UUFFckIsSUFBSSxLQUFLLEtBQUssQ0FBQyxFQUFFO1lBQ2IsUUFBUSxHQUFHLFVBQVUsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQ2pFO2FBQU07WUFDSCxNQUFNLENBQUMsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNqQixRQUFRLEdBQUcsS0FBSyxDQUFDLFFBQVEsRUFBRSxDQUFDO1NBQy9CO1FBRUQsT0FBTztZQUNILEtBQUssRUFBRSxRQUFRO1lBQ2YsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO1lBQ25CLGtCQUFrQixFQUFFLEtBQUssRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDO1lBQy9DLEtBQUs7U0FDUixDQUFDO0lBQ04sQ0FBQztJQUVEOzs7Ozs7Ozs7T0FTRztJQUNJLGNBQWMsQ0FDakIsVUFBaUMsRUFDakMsSUFBZ0IsRUFDaEIsUUFBUSxHQUFHLEtBQUssRUFDaEIsVUFBVSxHQUFHLEtBQUs7UUFFbEIsTUFBTSxhQUFhLEdBQUcsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUM7UUFDM0QsTUFBTSxPQUFPLEdBQUcsSUFBSSxLQUFLLFNBQVMsSUFBSSxhQUFhLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQy9ELElBQUksV0FBVyxHQUFHLGFBQWE7WUFDM0IsQ0FBQyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQztZQUN2QyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBRVQsa0RBQWtEO1FBQ2xELE1BQU0sYUFBYSxHQUFHLElBQUksS0FBSyxTQUFTLENBQUM7UUFFekMsSUFBSSxZQUFvQixDQUFDO1FBRXpCLElBQUksQ0FBQyxXQUFXLElBQUksYUFBYSxJQUFJLFVBQVUsQ0FBQyxLQUFLLEVBQUU7WUFDbkQsV0FBVyxHQUFHLElBQUksQ0FBQyx1QkFBdUIsQ0FBQyxJQUFJLENBQUMsQ0FBQztZQUNqRCxZQUFZLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUNwQyxVQUFVLEVBQ1YsUUFBUSxFQUNSLFVBQVUsQ0FDYixDQUFDO1NBQ0w7YUFBTTtZQUNILFlBQVksR0FBRyxJQUFJLENBQUMsZUFBZSxDQUMvQixVQUFVLEVBQ1YsUUFBUSxFQUNSLFVBQVUsRUFDVixhQUFhLENBQ2hCLENBQUM7U0FDTDtRQUNELE9BQU8sR0FBRyxZQUFZLEdBQUcsT0FBTyxHQUFHLFdBQVcsRUFBRSxDQUFDO0lBQ3JELENBQUM7SUFFRDs7Ozs7Ozs7OztPQVVHO0lBQ0ksZUFBZSxDQUNsQixVQUFpQyxFQUNqQyxRQUFRLEdBQUcsS0FBSyxFQUNoQixVQUFVLEdBQUcsS0FBSyxFQUNsQixRQUFRLEdBQUcsSUFBSTtRQUVmLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUN2QyxPQUFPLFVBQVUsQ0FBQztTQUNyQjtRQUVELE1BQU0sV0FBVyxHQUFHLFFBQVE7WUFDeEIsQ0FBQyxDQUFDLFVBQVUsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLENBQUMsY0FBYyxDQUFDLFNBQVMsRUFBRTtnQkFDbkQscUJBQXFCLEVBQUUsVUFBVSxDQUFDLEtBQUs7YUFDMUMsQ0FBQztZQUNKLENBQUMsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDO1FBQ3ZCLE1BQU0sTUFBTSxHQUNSLFFBQVEsSUFBSSxRQUFRLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO1FBQzlELE9BQU8sR0FBRyxNQUFNLEdBQUcsV0FBVyxFQUFFLENBQUM7SUFDckMsQ0FBQztJQUVEOzs7Ozs7O09BT0c7SUFDSSxjQUFjLENBQ2pCLFVBQWlDLEVBQ2pDLElBQWdCO1FBRWhCLE9BQU8sdUJBQXVCLENBQUMsSUFBSSxDQUFDLENBQUMsVUFBVSxDQUFDLEtBQUssQ0FBQyxDQUFDO0lBQzNELENBQUM7SUFFRDs7Ozs7O09BTUc7SUFDSSx1QkFBdUIsQ0FBQyxJQUFnQjtRQUMzQyxPQUFPLHVCQUF1QixDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO0lBQzVDLENBQUM7SUFFRDs7Ozs7Ozs7T0FRRztJQUNJLG9CQUFvQixDQUN2QixVQUFpQyxFQUNqQyxRQUFRLEdBQUcsS0FBSyxFQUNoQixVQUFVLEdBQUcsS0FBSztRQUVsQixJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLEVBQUU7WUFDdkMsT0FBTyxVQUFVLENBQUM7U0FDckI7UUFDRCxNQUFNLE1BQU0sR0FDUixRQUFRLElBQUksUUFBUSxDQUFDLFVBQVUsQ0FBQyxLQUFLLEVBQUUsRUFBRSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQztRQUU5RCxPQUFPLEdBQUcsTUFBTSxHQUFHLFVBQVUsQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO0lBQ3ZELENBQUM7SUFFTyxhQUFhLENBQUMsS0FBVTtRQUM1QixPQUFPLENBQUMsS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsQ0FBQyxJQUFJLFFBQVEsQ0FBQyxRQUFRLENBQUMsS0FBSyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUM7SUFDdEUsQ0FBQzsrR0FqUFEscUJBQXFCO21IQUFyQixxQkFBcUIsY0FEUixNQUFNOzs0RkFDbkIscUJBQXFCO2tCQURqQyxVQUFVO21CQUFDLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSIsInNvdXJjZXNDb250ZW50IjpbIi8vIMKpIDIwMjIgU29sYXJXaW5kcyBXb3JsZHdpZGUsIExMQy4gQWxsIHJpZ2h0cyByZXNlcnZlZC5cbi8vXG4vLyBQZXJtaXNzaW9uIGlzIGhlcmVieSBncmFudGVkLCBmcmVlIG9mIGNoYXJnZSwgdG8gYW55IHBlcnNvbiBvYnRhaW5pbmcgYSBjb3B5XG4vLyAgb2YgdGhpcyBzb2Z0d2FyZSBhbmQgYXNzb2NpYXRlZCBkb2N1bWVudGF0aW9uIGZpbGVzICh0aGUgXCJTb2Z0d2FyZVwiKSwgdG9cbi8vICBkZWFsIGluIHRoZSBTb2Z0d2FyZSB3aXRob3V0IHJlc3RyaWN0aW9uLCBpbmNsdWRpbmcgd2l0aG91dCBsaW1pdGF0aW9uIHRoZVxuLy8gIHJpZ2h0cyB0byB1c2UsIGNvcHksIG1vZGlmeSwgbWVyZ2UsIHB1Ymxpc2gsIGRpc3RyaWJ1dGUsIHN1YmxpY2Vuc2UsIGFuZC9vclxuLy8gIHNlbGwgY29waWVzIG9mIHRoZSBTb2Z0d2FyZSwgYW5kIHRvIHBlcm1pdCBwZXJzb25zIHRvIHdob20gdGhlIFNvZnR3YXJlIGlzXG4vLyAgZnVybmlzaGVkIHRvIGRvIHNvLCBzdWJqZWN0IHRvIHRoZSBmb2xsb3dpbmcgY29uZGl0aW9uczpcbi8vXG4vLyBUaGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSBhbmQgdGhpcyBwZXJtaXNzaW9uIG5vdGljZSBzaGFsbCBiZSBpbmNsdWRlZCBpblxuLy8gIGFsbCBjb3BpZXMgb3Igc3Vic3RhbnRpYWwgcG9ydGlvbnMgb2YgdGhlIFNvZnR3YXJlLlxuLy9cbi8vIFRIRSBTT0ZUV0FSRSBJUyBQUk9WSURFRCBcIkFTIElTXCIsIFdJVEhPVVQgV0FSUkFOVFkgT0YgQU5ZIEtJTkQsIEVYUFJFU1MgT1Jcbi8vICBJTVBMSUVELCBJTkNMVURJTkcgQlVUIE5PVCBMSU1JVEVEIFRPIFRIRSBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSxcbi8vICBGSVRORVNTIEZPUiBBIFBBUlRJQ1VMQVIgUFVSUE9TRSBBTkQgTk9OSU5GUklOR0VNRU5ULiBJTiBOTyBFVkVOVCBTSEFMTCBUSEVcbi8vICBBVVRIT1JTIE9SIENPUFlSSUdIVCBIT0xERVJTIEJFIExJQUJMRSBGT1IgQU5ZIENMQUlNLCBEQU1BR0VTIE9SIE9USEVSXG4vLyAgTElBQklMSVRZLCBXSEVUSEVSIElOIEFOIEFDVElPTiBPRiBDT05UUkFDVCwgVE9SVCBPUiBPVEhFUldJU0UsIEFSSVNJTkcgRlJPTSxcbi8vICBPVVQgT0YgT1IgSU4gQ09OTkVDVElPTiBXSVRIIFRIRSBTT0ZUV0FSRSBPUiBUSEUgVVNFIE9SIE9USEVSIERFQUxJTkdTIElOXG4vLyAgVEhFIFNPRlRXQVJFLlxuXG5pbXBvcnQgeyBJbmplY3RhYmxlIH0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcblxuaW1wb3J0IHsgTG9nZ2VyU2VydmljZSB9IGZyb20gXCIuL2xvZy1zZXJ2aWNlXCI7XG5pbXBvcnQgeyBJVW5pdENvbnZlcnNpb25SZXN1bHQgfSBmcm9tIFwiLi9wdWJsaWMtYXBpXCI7XG5pbXBvcnQge1xuICAgIFVuaXRCYXNlLFxuICAgIHVuaXRDb252ZXJzaW9uQ29uc3RhbnRzLFxuICAgIFVuaXRPcHRpb24sXG59IGZyb20gXCIuLi9jb25zdGFudHMvdW5pdC1jb252ZXJzaW9uLmNvbnN0YW50c1wiO1xuXG4vKipcbiAqIDxleGFtcGxlLXVybD4uLy4uL2V4YW1wbGVzL2luZGV4Lmh0bWwjL2NvbW1vbi91bml0LWNvbnZlcnNpb24tc2VydmljZTwvZXhhbXBsZS11cmw+XG4gKlxuICogU2VydmljZSBmb3IgY29udmVydGluZyBhIHJhdyB2YWx1ZSB0byBhIGxhcmdlciB1bml0IGFwcHJveGltYXRpb24gb2YgdGhlIHZhbHVlLS1mb3IgZXhhbXBsZSwgMTAyNCBCIHRvIDEgTUIsIDEyMzQ1IEh6IHRvIDEyLjM1IGtIeiwgZXRjLlxuICovXG5ASW5qZWN0YWJsZSh7IHByb3ZpZGVkSW46IFwicm9vdFwiIH0pXG5leHBvcnQgY2xhc3MgVW5pdENvbnZlcnNpb25TZXJ2aWNlIHtcbiAgICBjb25zdHJ1Y3Rvcihwcml2YXRlIGxvZ2dlcjogTG9nZ2VyU2VydmljZSkge31cblxuICAgIC8qKlxuICAgICAqIENvbnZlcnRzIGEgcmF3IHZhbHVlIHRvIGEgbGFyZ2VyIHVuaXQgYXBwcm94aW1hdGlvbiBvZiB0aGUgdmFsdWUuIEZvciBleGFtcGxlLCAxMDI0IEIgdG8gMSBLQiwgMTIzNDUgSHogdG8gMTIuMzUga0h6LCBldGMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnRcbiAgICAgKiBAcGFyYW0gYmFzZSBUaGUgYmFzZSB0byB1c2UgZm9yIHRoZSBleHBvbmVudGlhbCBleHByZXNzaW9uIHdoZW4gY2FsY3VsYXRpbmcgdGhlIGNvbnZlcnNpb24gcmVzdWx0XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7eyBbS2V5IGluIGtleW9mIFBpY2s8SVVuaXRDb252ZXJzaW9uUmVzdWx0LCBcInZhbHVlXCIgfCBcIm9yZGVyXCI+XTogbnVtYmVyIH19IFRoZSB2YWx1ZSBhbmQgb3JkZXIgb2YgY29udmVyc2lvblxuICAgICAqL1xuICAgIHByaXZhdGUgY29udmVydExpbmVhcihcbiAgICAgICAgdmFsdWU6IG51bWJlcixcbiAgICAgICAgYmFzZTogbnVtYmVyXG4gICAgKTogeyBbS2V5IGluIGtleW9mIFBpY2s8SVVuaXRDb252ZXJzaW9uUmVzdWx0LCBcInZhbHVlXCIgfCBcIm9yZGVyXCI+XTogbnVtYmVyIH0ge1xuICAgICAgICBsZXQgcmVzdWx0VmFsdWU6IG51bWJlcjtcbiAgICAgICAgbGV0IHJlc3VsdE9yZGVyOiBudW1iZXI7XG5cbiAgICAgICAgaWYgKHZhbHVlID09PSAwKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHZhbHVlOiAwLFxuICAgICAgICAgICAgICAgIG9yZGVyOiAwLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJlc3VsdE9yZGVyID0gTWF0aC5mbG9vcihcbiAgICAgICAgICAgIE1hdGgubG9nKE1hdGguYWJzKHZhbHVlKSkgLyBNYXRoLmxvZyhiYXNlKVxuICAgICAgICApO1xuICAgICAgICByZXN1bHRWYWx1ZSA9IHZhbHVlIC8gTWF0aC5wb3coYmFzZSwgTWF0aC5mbG9vcihyZXN1bHRPcmRlcikpO1xuXG4gICAgICAgIGlmIChNYXRoLmFicyh2YWx1ZSkgPiAwICYmIE1hdGguYWJzKHZhbHVlKSA8IDEpIHtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgICAgICAgICAgIG9yZGVyOiAwLFxuICAgICAgICAgICAgfTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIGZpeCB0aGUgcHJlY2lzaW9uIGVkZ2UgY2FzZVxuICAgICAgICBjb25zdCB2YWx1ZUNlaWxlZCA9IE1hdGguY2VpbChyZXN1bHRWYWx1ZSk7XG4gICAgICAgIGlmICh2YWx1ZUNlaWxlZCAlIGJhc2UgPT09IDApIHtcbiAgICAgICAgICAgIHJlc3VsdFZhbHVlID0gdmFsdWVDZWlsZWQgLyBiYXNlO1xuICAgICAgICAgICAgcmVzdWx0T3JkZXIgKz0gMTtcbiAgICAgICAgfVxuXG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICB2YWx1ZTogcmVzdWx0VmFsdWUsXG4gICAgICAgICAgICBvcmRlcjogcmVzdWx0T3JkZXIsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogQ29udmVydHMgYSByYXcgdmFsdWUgdG8gYSBsYXJnZXIgdW5pdCBhcHByb3hpbWF0aW9uIG9mIHRoZSB2YWx1ZS4gRm9yIGV4YW1wbGUsIDExMDBtcyB0byAxLjFzLCA2NjAwMG1zIHRvIDEuMW0sIGV0Yy5cbiAgICAgKlxuICAgICAqIEBwYXJhbSB2YWx1ZSBUaGUgdmFsdWUgdG8gY29udmVydFxuICAgICAqIEBwYXJhbSBmYWN0b3JzIEFycmF5IG9mIGZhY3RvcnMgdG8gdXNlIGZvciBjYWxjdWxhdGluZyBzbWFsbGVzdCBwb3NzaWJsZSBub3QgemVybyByZXN1bHRcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHt7IFtLZXkgaW4ga2V5b2YgUGljazxJVW5pdENvbnZlcnNpb25SZXN1bHQsIFwidmFsdWVcIiB8IFwib3JkZXJcIj5dOiBudW1iZXIgfX0gVGhlIHZhbHVlIGFuZCBvcmRlciBvZiBjb252ZXJzaW9uXG4gICAgICovXG4gICAgcHJpdmF0ZSBjb252ZXJ0Tm9uTGluZWFyKFxuICAgICAgICB2YWx1ZTogbnVtYmVyLFxuICAgICAgICBmYWN0b3JzOiBudW1iZXJbXVxuICAgICk6IHsgW0tleSBpbiBrZXlvZiBQaWNrPElVbml0Q29udmVyc2lvblJlc3VsdCwgXCJ2YWx1ZVwiIHwgXCJvcmRlclwiPl06IG51bWJlciB9IHtcbiAgICAgICAgY29uc3Qgc29ydGVkRmFjdG9ycyA9IGZhY3RvcnMuc29ydCgoYSwgYikgPT4gYSA+IGIgPyAtMSA6IGEgPCBiID8gMSA6IDApO1xuICAgICAgICBjb25zdCBoaWdoZXN0RmFjdG9ySW5kZXggPSBzb3J0ZWRGYWN0b3JzLmZpbmRJbmRleCgoZmFjdG9yKSA9PiB2YWx1ZSAvIGZhY3RvciA+PSAxKTtcbiAgICAgICAgY29uc3QgaGlnaGVzdEZhY3RvciA9IGZhY3RvcnNbaGlnaGVzdEZhY3RvckluZGV4XTtcblxuICAgICAgICBpZiAoTWF0aC5hYnModmFsdWUpID4gMCAmJiBNYXRoLmFicyh2YWx1ZSkgPCAxKSB7XG4gICAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgICAgIHZhbHVlOiB2YWx1ZSxcbiAgICAgICAgICAgICAgICBvcmRlcjogMCxcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsdWU6IHZhbHVlIC8gaGlnaGVzdEZhY3RvcixcbiAgICAgICAgICAgIG9yZGVyOiBoaWdoZXN0RmFjdG9ySW5kZXggPT09IC0xID8gMCA6IGZhY3RvcnMubGVuZ3RoIC0gaGlnaGVzdEZhY3RvckluZGV4IC0gMSxcbiAgICAgICAgfTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDb252ZXJ0cyBhIHJhdyB2YWx1ZSB0byBhIGxhcmdlciB1bml0IGFwcHJveGltYXRpb24gb2YgdGhlIHZhbHVlLiBGb3IgZXhhbXBsZSwgMTAyNCBCIHRvIDEgS0IsIDEyMzQ1IEh6IHRvIDEyLjM1IGtIeiwgNjYwMDBtcyB0byAxLjFtLCBldGMuXG4gICAgICpcbiAgICAgKiBAcGFyYW0gdmFsdWUgVGhlIHZhbHVlIHRvIGNvbnZlcnRcbiAgICAgKiBAcGFyYW0gYmFzZSBUaGUgYmFzZSBvciBhcnJheSBvZiBmYWN0b3JzIHRvIHVzZSBmb3IgY2FsY3VsYXRpbmcgdGhlIGNvbnZlcnNpb24gcmVzdWx0XG4gICAgICogQHBhcmFtIHNjYWxlIFRoZSBudW1iZXIgb2Ygc2lnbmlmaWNhbnQgZGlnaXRzIHRvIHRoZSByaWdodCBvZiB0aGUgZGVjaW1hbCB0byBpbmNsdWRlIGluIHRoZSByZXN1bHRpbmcgY29udmVydGVkIHZhbHVlXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7SVVuaXRDb252ZXJzaW9uUmVzdWx0fSBUaGUgY29udmVyc2lvbiByZXN1bHRcbiAgICAgKi9cbiAgICBjb252ZXJ0KFxuICAgICAgICB2YWx1ZTogbnVtYmVyLFxuICAgICAgICBiYXNlOiBudW1iZXIgfCBudW1iZXJbXSA9IFVuaXRCYXNlLlN0YW5kYXJkLFxuICAgICAgICBzY2FsZTogbnVtYmVyID0gMVxuICAgICk6IElVbml0Q29udmVyc2lvblJlc3VsdCB7XG4gICAgICAgIGNvbnN0IHJlc3VsdCA9IEFycmF5LmlzQXJyYXkoYmFzZSkgP1xuICAgICAgICAgICAgdGhpcy5jb252ZXJ0Tm9uTGluZWFyKHZhbHVlLCBiYXNlKSA6XG4gICAgICAgICAgICB0aGlzLmNvbnZlcnRMaW5lYXIodmFsdWUsIGJhc2UpO1xuXG4gICAgICAgIGxldCBzdHJWYWx1ZTogc3RyaW5nO1xuXG4gICAgICAgIGlmICh2YWx1ZSAhPT0gMCkge1xuICAgICAgICAgICAgc3RyVmFsdWUgPSBwYXJzZUZsb2F0KHJlc3VsdC52YWx1ZS50b0ZpeGVkKHNjYWxlKSkudG9TdHJpbmcoKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIHJlc3VsdC5vcmRlciA9IDA7XG4gICAgICAgICAgICBzdHJWYWx1ZSA9IHZhbHVlLnRvU3RyaW5nKCk7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdmFsdWU6IHN0clZhbHVlLFxuICAgICAgICAgICAgb3JkZXI6IHJlc3VsdC5vcmRlcixcbiAgICAgICAgICAgIHNjaWVudGlmaWNOb3RhdGlvbjogdmFsdWU/LnRvRXhwb25lbnRpYWwoc2NhbGUpLFxuICAgICAgICAgICAgc2NhbGUsXG4gICAgICAgIH07XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogR2V0cyB0aGUgZGlzcGxheSBzdHJpbmcgb2YgYSBjb252ZXJzaW9uIHJlc3VsdFxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbnZlcnNpb24gVGhlIHJlc3VsdCBvZiBhbiBpbnZvY2F0aW9uIG9mIHRoaXMgc2VydmljZSdzIGNvbnZlcnQgbWV0aG9kXG4gICAgICogQHBhcmFtIHVuaXQgVGhlIHVuaXQgdXNlZCBpbiB0aGUgY29udmVyc2lvblxuICAgICAqIEBwYXJhbSBwbHVzU2lnbiBXaGV0aGVyIHRvIHByZXBlbmQgdGhlIGRpc3BsYXkgc3RyaW5nIHdpdGggYSAnKydcbiAgICAgKiBAcGFyYW0gbmFuRGlzcGxheSBUaGUgc3RyaW5nIHRvIGRpc3BsYXkgaW4gY2FzZSB0aGUgY29udmVyc2lvbiByZXN1bHQgaXMgTmFOIG9yIEluZmluaXR5XG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgZGlzcGxheSBzdHJpbmcgb2YgdGhlIGNvbnZlcnNpb24gcmVzdWx0XG4gICAgICovXG4gICAgcHVibGljIGdldEZ1bGxEaXNwbGF5KFxuICAgICAgICBjb252ZXJzaW9uOiBJVW5pdENvbnZlcnNpb25SZXN1bHQsXG4gICAgICAgIHVuaXQ6IFVuaXRPcHRpb24sXG4gICAgICAgIHBsdXNTaWduID0gZmFsc2UsXG4gICAgICAgIG5hbkRpc3BsYXkgPSBcIi0tLVwiXG4gICAgKTogc3RyaW5nIHtcbiAgICAgICAgY29uc3QgaXNWYWxpZE51bWJlciA9IHRoaXMuaXNWYWxpZE51bWJlcihjb252ZXJzaW9uLnZhbHVlKTtcbiAgICAgICAgY29uc3Qgc3BhY2luZyA9IHVuaXQgIT09IFwiZ2VuZXJpY1wiICYmIGlzVmFsaWROdW1iZXIgPyBcIiBcIiA6IFwiXCI7XG4gICAgICAgIGxldCB1bml0RGlzcGxheSA9IGlzVmFsaWROdW1iZXJcbiAgICAgICAgICAgID8gdGhpcy5nZXRVbml0RGlzcGxheShjb252ZXJzaW9uLCB1bml0KVxuICAgICAgICAgICAgOiBcIlwiO1xuXG4gICAgICAgIC8vIFRoZSBnZW5lcmljIHVuaXQgaXMgbm90IGN1cnJlbnRseSBpMThuIGZyaWVuZGx5XG4gICAgICAgIGNvbnN0IGxvY2FsaXplVmFsdWUgPSB1bml0ICE9PSBcImdlbmVyaWNcIjtcblxuICAgICAgICBsZXQgZGlzcGxheVZhbHVlOiBzdHJpbmc7XG5cbiAgICAgICAgaWYgKCF1bml0RGlzcGxheSAmJiBpc1ZhbGlkTnVtYmVyICYmIGNvbnZlcnNpb24ub3JkZXIpIHtcbiAgICAgICAgICAgIHVuaXREaXNwbGF5ID0gdGhpcy5nZXRVbml0RGlzcGxheUJhc2VWYWx1ZSh1bml0KTtcbiAgICAgICAgICAgIGRpc3BsYXlWYWx1ZSA9IHRoaXMuZ2V0U2NpZW50aWZpY0Rpc3BsYXkoXG4gICAgICAgICAgICAgICAgY29udmVyc2lvbixcbiAgICAgICAgICAgICAgICBwbHVzU2lnbixcbiAgICAgICAgICAgICAgICBuYW5EaXNwbGF5XG4gICAgICAgICAgICApO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgZGlzcGxheVZhbHVlID0gdGhpcy5nZXRWYWx1ZURpc3BsYXkoXG4gICAgICAgICAgICAgICAgY29udmVyc2lvbixcbiAgICAgICAgICAgICAgICBwbHVzU2lnbixcbiAgICAgICAgICAgICAgICBuYW5EaXNwbGF5LFxuICAgICAgICAgICAgICAgIGxvY2FsaXplVmFsdWVcbiAgICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgICAgcmV0dXJuIGAke2Rpc3BsYXlWYWx1ZX0ke3NwYWNpbmd9JHt1bml0RGlzcGxheX1gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGNvbnZlcnRlZCB2YWx1ZSBkaXNwbGF5IHN0cmluZ1xuICAgICAqXG4gICAgICogQHBhcmFtIGNvbnZlcnNpb24gVGhlIHJlc3VsdCBvZiBhbiBpbnZvY2F0aW9uIG9mIHRoaXMgc2VydmljZSdzIGNvbnZlcnQgbWV0aG9kXG4gICAgICogQHBhcmFtIHBsdXNTaWduIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgZGlzcGxheSBzdHJpbmcgd2l0aCBhICcrJ1xuICAgICAqIEBwYXJhbSBuYW5EaXNwbGF5IFRoZSBzdHJpbmcgdG8gZGlzcGxheSBpbiBjYXNlIHRoZSBjb252ZXJzaW9uIHJlc3VsdCBpcyBOYU4gb3IgSW5maW5pdHlcbiAgICAgKiBAcGFyYW0gbG9jYWxpemUgV2hldGhlciB0byBsb2NhbGl6ZSB0aGUgdmFsdWUgZm9yIGRpc3BsYXkuIE5vdGU6IEl0J3Mgbm90IHJlY29tbWVuZGVkIHRvIGxvY2FsaXplIHZhbHVlcyBmb3JcbiAgICAgKiAgICAgICAgICAgICAgICAgdGhlIFwiZ2VuZXJpY1wiIHVuaXQsIGUuZy4gXCIxLjFLXCIgZm9yIDExMDAsIGFzIHRoZSBcImdlbmVyaWNcIiB1bml0IGlzIGN1cnJlbnRseSBub3QgaTE4biBmcmllbmRseVxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGNvbnZlcnRlZCB2YWx1ZSBkaXNwbGF5IHN0cmluZ1xuICAgICAqL1xuICAgIHB1YmxpYyBnZXRWYWx1ZURpc3BsYXkoXG4gICAgICAgIGNvbnZlcnNpb246IElVbml0Q29udmVyc2lvblJlc3VsdCxcbiAgICAgICAgcGx1c1NpZ24gPSBmYWxzZSxcbiAgICAgICAgbmFuRGlzcGxheSA9IFwiLS0tXCIsXG4gICAgICAgIGxvY2FsaXplID0gdHJ1ZVxuICAgICk6IHN0cmluZyB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkTnVtYmVyKGNvbnZlcnNpb24udmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmFuRGlzcGxheTtcbiAgICAgICAgfVxuXG4gICAgICAgIGNvbnN0IG91dHB1dFZhbHVlID0gbG9jYWxpemVcbiAgICAgICAgICAgID8gcGFyc2VGbG9hdChjb252ZXJzaW9uLnZhbHVlKS50b0xvY2FsZVN0cmluZyh1bmRlZmluZWQsIHtcbiAgICAgICAgICAgICAgICAgIG1heGltdW1GcmFjdGlvbkRpZ2l0czogY29udmVyc2lvbi5zY2FsZSxcbiAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgIDogY29udmVyc2lvbi52YWx1ZTtcbiAgICAgICAgY29uc3QgcHJlZml4ID1cbiAgICAgICAgICAgIHBsdXNTaWduICYmIHBhcnNlSW50KGNvbnZlcnNpb24udmFsdWUsIDEwKSA+IDAgPyBcIitcIiA6IFwiXCI7XG4gICAgICAgIHJldHVybiBgJHtwcmVmaXh9JHtvdXRwdXRWYWx1ZX1gO1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIEdldHMgdGhlIGNvbnZlcnRlZCB1bml0IGRpc3BsYXkgc3RyaW5nXG4gICAgICpcbiAgICAgKiBAcGFyYW0gY29udmVyc2lvbiBUaGUgcmVzdWx0IG9mIGFuIGludm9jYXRpb24gb2YgdGhpcyBzZXJ2aWNlJ3MgY29udmVydCBtZXRob2RcbiAgICAgKiBAcGFyYW0gdW5pdCBUaGUgYmFzaWMgdW5pdCB1c2VkIGluIHRoZSBjb252ZXJzaW9uXG4gICAgICpcbiAgICAgKiBAcmV0dXJucyB7c3RyaW5nfSBUaGUgY29udmVydGVkIHVuaXQgZGlzcGxheSBzdHJpbmdcbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0VW5pdERpc3BsYXkoXG4gICAgICAgIGNvbnZlcnNpb246IElVbml0Q29udmVyc2lvblJlc3VsdCxcbiAgICAgICAgdW5pdDogVW5pdE9wdGlvblxuICAgICk6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB1bml0Q29udmVyc2lvbkNvbnN0YW50c1t1bml0XVtjb252ZXJzaW9uLm9yZGVyXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBiYXNlIHZhbHVlIG9mIHRoZSBjb252ZXJ0ZWQgdW5pdFxuICAgICAqXG4gICAgICogQHBhcmFtIHVuaXQgVGhlIGJhc2ljIHVuaXQgdXNlZCBpbiB0aGUgY29udmVyc2lvblxuICAgICAqXG4gICAgICogQHJldHVybnMge3N0cmluZ30gVGhlIGFiYnJldmlhdGlvbiBmb3IgdGhlIHNtYWxsZXN0IHVuaXQgb2YgdGhlIHByb3ZpZGVkIFVuaXRPcHRpb25cbiAgICAgKi9cbiAgICBwdWJsaWMgZ2V0VW5pdERpc3BsYXlCYXNlVmFsdWUodW5pdDogVW5pdE9wdGlvbik6IHN0cmluZyB7XG4gICAgICAgIHJldHVybiB1bml0Q29udmVyc2lvbkNvbnN0YW50c1t1bml0XVswXTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBHZXRzIHRoZSBjb252ZXJ0ZWQgdmFsdWUgZGlzcGxheSBzdHJpbmcgaW4gc2NpZW50aWZpYyBub3RhdGlvblxuICAgICAqXG4gICAgICogQHBhcmFtIGNvbnZlcnNpb24gVGhlIHJlc3VsdCBvZiBhbiBpbnZvY2F0aW9uIG9mIHRoaXMgc2VydmljZSdzIGNvbnZlcnQgbWV0aG9kXG4gICAgICogQHBhcmFtIHBsdXNTaWduIFdoZXRoZXIgdG8gcHJlcGVuZCB0aGUgZGlzcGxheSBzdHJpbmcgd2l0aCBhICcrJ1xuICAgICAqIEBwYXJhbSBuYW5EaXNwbGF5IFRoZSBzdHJpbmcgdG8gZGlzcGxheSBpbiBjYXNlIHRoZSBjb252ZXJzaW9uIHJlc3VsdCBpcyBOYU4gb3IgSW5maW5pdHlcbiAgICAgKlxuICAgICAqIEByZXR1cm5zIHtzdHJpbmd9IFRoZSBjb252ZXJ0ZWQgdmFsdWUgZGlzcGxheSBzdHJpbmcgaW4gc2NpZW50aWZpYyBub3RhdGlvblxuICAgICAqL1xuICAgIHB1YmxpYyBnZXRTY2llbnRpZmljRGlzcGxheShcbiAgICAgICAgY29udmVyc2lvbjogSVVuaXRDb252ZXJzaW9uUmVzdWx0LFxuICAgICAgICBwbHVzU2lnbiA9IGZhbHNlLFxuICAgICAgICBuYW5EaXNwbGF5ID0gXCItLS1cIlxuICAgICk6IHN0cmluZyB7XG4gICAgICAgIGlmICghdGhpcy5pc1ZhbGlkTnVtYmVyKGNvbnZlcnNpb24udmFsdWUpKSB7XG4gICAgICAgICAgICByZXR1cm4gbmFuRGlzcGxheTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwcmVmaXggPVxuICAgICAgICAgICAgcGx1c1NpZ24gJiYgcGFyc2VJbnQoY29udmVyc2lvbi52YWx1ZSwgMTApID4gMCA/IFwiK1wiIDogXCJcIjtcblxuICAgICAgICByZXR1cm4gYCR7cHJlZml4fSR7Y29udmVyc2lvbi5zY2llbnRpZmljTm90YXRpb259YDtcbiAgICB9XG5cbiAgICBwcml2YXRlIGlzVmFsaWROdW1iZXIodmFsdWU6IGFueSk6IGJvb2xlYW4ge1xuICAgICAgICByZXR1cm4gIWlzTmFOKHBhcnNlRmxvYXQodmFsdWUpKSAmJiBpc0Zpbml0ZShwYXJzZUludCh2YWx1ZSwgMTApKTtcbiAgICB9XG59XG4iXX0=