@qogni/dygraphs
Version:
dygraphs is a fast, flexible open source JavaScript charting library.
395 lines (368 loc) • 42.8 kB
JavaScript
/**
* @license
* Copyright 2011 Dan Vanderkam (danvdk@gmail.com)
* MIT-licenced: https://opensource.org/licenses/MIT
*/
/**
* @fileoverview DygraphOptions is responsible for parsing and returning
* information about options.
*/
// TODO: remove this jshint directive & fix the warnings.
/*jshint sub:true */
"use strict";
Object.defineProperty(exports, "__esModule", {
value: true
});
exports["default"] = void 0;
var utils = _interopRequireWildcard(require("./dygraph-utils"));
var _dygraphDefaultAttrs = _interopRequireDefault(require("./dygraph-default-attrs"));
var _dygraphOptionsReference = _interopRequireDefault(require("./dygraph-options-reference"));
function _interopRequireDefault(e) { return e && e.__esModule ? e : { "default": e }; }
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function _getRequireWildcardCache(e) { return e ? t : r; })(e); }
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { "default": e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && {}.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n["default"] = e, t && t.set(e, n), n; }
/*
* Interesting member variables: (REMOVING THIS LIST AS I CLOSURIZE)
* global_ - global attributes (common among all graphs, AIUI)
* user - attributes set by the user
* series_ - { seriesName -> { idx, yAxis, options }}
*/
/**
* This parses attributes into an object that can be easily queried.
*
* It doesn't necessarily mean that all options are available, specifically
* if labels are not yet available, since those drive details of the per-series
* and per-axis options.
*
* @param {Dygraph} dygraph The chart to which these options belong.
* @constructor
*/
var DygraphOptions = function DygraphOptions(dygraph) {
/**
* The dygraph.
* @type {!Dygraph}
*/
this.dygraph_ = dygraph;
/**
* Array of axis index to { series : [ series names ] , options : { axis-specific options. } }
* @type {Array.<{series : Array.<string>, options : Object}>} @private
*/
this.yAxes_ = [];
/**
* Contains x-axis specific options, which are stored in the options key.
* This matches the yAxes_ object structure (by being a dictionary with an
* options element) allowing for shared code.
* @type {options: Object} @private
*/
this.xAxis_ = {};
this.series_ = {};
// Once these two objects are initialized, you can call get();
this.global_ = this.dygraph_.attrs_;
this.user_ = this.dygraph_.user_attrs_ || {};
/**
* A list of series in columnar order.
* @type {Array.<string>}
*/
this.labels_ = [];
this.highlightSeries_ = this.get("highlightSeriesOpts") || {};
this.reparseSeries();
};
/**
* Not optimal, but does the trick when you're only using two axes.
* If we move to more axes, this can just become a function.
*
* @type {Object.<number>}
* @private
*/
DygraphOptions.AXIS_STRING_MAPPINGS_ = {
'y': 0,
'Y': 0,
'y1': 0,
'Y1': 0,
'y2': 1,
'Y2': 1
};
/**
* @param {string|number} axis
* @private
*/
DygraphOptions.axisToIndex_ = function (axis) {
if (typeof axis == "string") {
if (DygraphOptions.AXIS_STRING_MAPPINGS_.hasOwnProperty(axis)) {
return DygraphOptions.AXIS_STRING_MAPPINGS_[axis];
}
throw "Unknown axis : " + axis;
}
if (typeof axis == "number") {
if (axis === 0 || axis === 1) {
return axis;
}
throw "Dygraphs only supports two y-axes, indexed from 0-1.";
}
if (axis) {
throw "Unknown axis : " + axis;
}
// No axis specification means axis 0.
return 0;
};
/**
* Reparses options that are all related to series. This typically occurs when
* options are either updated, or source data has been made available.
*
* TODO(konigsberg): The method name is kind of weak; fix.
*/
DygraphOptions.prototype.reparseSeries = function () {
var labels = this.get("labels");
if (!labels) {
return; // -- can't do more for now, will parse after getting the labels.
}
this.labels_ = labels.slice(1);
this.yAxes_ = [{
series: [],
options: {}
}]; // Always one axis at least.
this.xAxis_ = {
options: {}
};
this.series_ = {};
// Series are specified in the series element:
//
// {
// labels: [ "X", "foo", "bar" ],
// pointSize: 3,
// series : {
// foo : {}, // options for foo
// bar : {} // options for bar
// }
// }
//
// So, if series is found, it's expected to contain per-series data,
// otherwise set a default.
var seriesDict = this.user_.series || {};
for (var idx = 0; idx < this.labels_.length; idx++) {
var seriesName = this.labels_[idx];
var optionsForSeries = seriesDict[seriesName] || {};
var yAxis = DygraphOptions.axisToIndex_(optionsForSeries["axis"]);
this.series_[seriesName] = {
idx: idx,
yAxis: yAxis,
options: optionsForSeries
};
if (!this.yAxes_[yAxis]) {
this.yAxes_[yAxis] = {
series: [seriesName],
options: {}
};
} else {
this.yAxes_[yAxis].series.push(seriesName);
}
}
var axis_opts = this.user_["axes"] || {};
utils.update(this.yAxes_[0].options, axis_opts["y"] || {});
if (this.yAxes_.length > 1) {
utils.update(this.yAxes_[1].options, axis_opts["y2"] || {});
}
utils.update(this.xAxis_.options, axis_opts["x"] || {});
if (typeof process !== 'undefined' && process.env.NODE_ENV != 'production') {
// For "production" code, this gets removed by uglifyjs.
this.validateOptions_();
}
};
/**
* Get a global value.
*
* @param {string} name the name of the option.
*/
DygraphOptions.prototype.get = function (name) {
var result = this.getGlobalUser_(name);
if (result !== null) {
return result;
}
return this.getGlobalDefault_(name);
};
DygraphOptions.prototype.getGlobalUser_ = function (name) {
if (this.user_.hasOwnProperty(name)) {
return this.user_[name];
}
return null;
};
DygraphOptions.prototype.getGlobalDefault_ = function (name) {
if (this.global_.hasOwnProperty(name)) {
return this.global_[name];
}
if (_dygraphDefaultAttrs["default"].hasOwnProperty(name)) {
return _dygraphDefaultAttrs["default"][name];
}
return null;
};
/**
* Get a value for a specific axis. If there is no specific value for the axis,
* the global value is returned.
*
* @param {string} name the name of the option.
* @param {string|number} axis the axis to search. Can be the string representation
* ("y", "y2") or the axis number (0, 1).
*/
DygraphOptions.prototype.getForAxis = function (name, axis) {
var axisIdx;
var axisString;
// Since axis can be a number or a string, straighten everything out here.
if (typeof axis == 'number') {
axisIdx = axis;
axisString = axisIdx === 0 ? "y" : "y2";
} else {
if (axis == "y1") {
axis = "y";
} // Standardize on 'y'. Is this bad? I think so.
if (axis == "y") {
axisIdx = 0;
} else if (axis == "y2") {
axisIdx = 1;
} else if (axis == "x") {
axisIdx = -1; // simply a placeholder for below.
} else {
throw "Unknown axis " + axis;
}
axisString = axis;
}
var userAxis = axisIdx == -1 ? this.xAxis_ : this.yAxes_[axisIdx];
// Search the user-specified axis option first.
if (userAxis) {
// This condition could be removed if we always set up this.yAxes_ for y2.
var axisOptions = userAxis.options;
if (axisOptions.hasOwnProperty(name)) {
return axisOptions[name];
}
}
// User-specified global options second.
// But, hack, ignore globally-specified 'logscale' for 'x' axis declaration.
if (!(axis === 'x' && name === 'logscale')) {
var result = this.getGlobalUser_(name);
if (result !== null) {
return result;
}
}
// Default axis options third.
var defaultAxisOptions = _dygraphDefaultAttrs["default"].axes[axisString];
if (defaultAxisOptions.hasOwnProperty(name)) {
return defaultAxisOptions[name];
}
// Default global options last.
return this.getGlobalDefault_(name);
};
/**
* Get a value for a specific series. If there is no specific value for the series,
* the value for the axis is returned (and afterwards, the global value.)
*
* @param {string} name the name of the option.
* @param {string} series the series to search.
*/
DygraphOptions.prototype.getForSeries = function (name, series) {
// Honors indexes as series.
if (series === this.dygraph_.getHighlightSeries()) {
if (this.highlightSeries_.hasOwnProperty(name)) {
return this.highlightSeries_[name];
}
}
if (!this.series_.hasOwnProperty(series)) {
throw "Unknown series: " + series;
}
var seriesObj = this.series_[series];
var seriesOptions = seriesObj["options"];
if (seriesOptions.hasOwnProperty(name)) {
return seriesOptions[name];
}
return this.getForAxis(name, seriesObj["yAxis"]);
};
/**
* Returns the number of y-axes on the chart.
* @return {number} the number of axes.
*/
DygraphOptions.prototype.numAxes = function () {
return this.yAxes_.length;
};
/**
* Return the y-axis for a given series, specified by name.
*/
DygraphOptions.prototype.axisForSeries = function (series) {
return this.series_[series].yAxis;
};
/**
* Returns the options for the specified axis.
*/
// TODO(konigsberg): this is y-axis specific. Support the x axis.
DygraphOptions.prototype.axisOptions = function (yAxis) {
return this.yAxes_[yAxis].options;
};
/**
* Return the series associated with an axis.
*/
DygraphOptions.prototype.seriesForAxis = function (yAxis) {
return this.yAxes_[yAxis].series;
};
/**
* Return the list of all series, in their columnar order.
*/
DygraphOptions.prototype.seriesNames = function () {
return this.labels_;
};
if (typeof process !== 'undefined' && process.env.NODE_ENV != 'production') {
// For "production" code, this gets removed by uglifyjs.
/**
* Validate all options.
* This requires OPTIONS_REFERENCE, which is only available in debug builds.
* @private
*/
DygraphOptions.prototype.validateOptions_ = function () {
if (typeof _dygraphOptionsReference["default"] === 'undefined') {
throw 'Called validateOptions_ in prod build.';
}
var that = this;
var validateOption = function validateOption(optionName) {
if (!_dygraphOptionsReference["default"][optionName]) {
that.warnInvalidOption_(optionName);
}
};
var optionsDicts = [this.xAxis_.options, this.yAxes_[0].options, this.yAxes_[1] && this.yAxes_[1].options, this.global_, this.user_, this.highlightSeries_];
var names = this.seriesNames();
for (var i = 0; i < names.length; i++) {
var name = names[i];
if (this.series_.hasOwnProperty(name)) {
optionsDicts.push(this.series_[name].options);
}
}
for (var i = 0; i < optionsDicts.length; i++) {
var dict = optionsDicts[i];
if (!dict) continue;
for (var optionName in dict) {
if (dict.hasOwnProperty(optionName)) {
validateOption(optionName);
}
}
}
};
var WARNINGS = {}; // Only show any particular warning once.
/**
* Logs a warning about invalid options.
* TODO: make this throw for testing
* @private
*/
DygraphOptions.prototype.warnInvalidOption_ = function (optionName) {
if (!WARNINGS[optionName]) {
WARNINGS[optionName] = true;
var isSeries = this.labels_.indexOf(optionName) >= 0;
if (isSeries) {
console.warn('Use new-style per-series options (saw ' + optionName + ' as top-level options key). See http://blog.dygraphs.com/2012/12/the-new-and-better-way-to-specify.html (The New and Better Way to Specify Series and Axis Options).');
} else {
console.warn('Unknown option ' + optionName + ' (see https://dygraphs.com/options.html for the full list of options)');
}
throw "invalid option " + optionName;
}
};
// Reset list of previously-shown warnings. Used for testing.
DygraphOptions.resetWarnings_ = function () {
WARNINGS = {};
};
}
var _default = exports["default"] = DygraphOptions;
module.exports = exports.default;
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJuYW1lcyI6WyJPYmplY3QiLCJkZWZpbmVQcm9wZXJ0eSIsImV4cG9ydHMiLCJ2YWx1ZSIsInV0aWxzIiwiX2ludGVyb3BSZXF1aXJlV2lsZGNhcmQiLCJyZXF1aXJlIiwiX2R5Z3JhcGhEZWZhdWx0QXR0cnMiLCJfaW50ZXJvcFJlcXVpcmVEZWZhdWx0IiwiX2R5Z3JhcGhPcHRpb25zUmVmZXJlbmNlIiwiZSIsIl9fZXNNb2R1bGUiLCJfZ2V0UmVxdWlyZVdpbGRjYXJkQ2FjaGUiLCJXZWFrTWFwIiwiciIsInQiLCJoYXMiLCJnZXQiLCJuIiwiX19wcm90b19fIiwiYSIsImdldE93blByb3BlcnR5RGVzY3JpcHRvciIsInUiLCJoYXNPd25Qcm9wZXJ0eSIsImNhbGwiLCJpIiwic2V0IiwiRHlncmFwaE9wdGlvbnMiLCJkeWdyYXBoIiwiZHlncmFwaF8iLCJ5QXhlc18iLCJ4QXhpc18iLCJzZXJpZXNfIiwiZ2xvYmFsXyIsImF0dHJzXyIsInVzZXJfIiwidXNlcl9hdHRyc18iLCJsYWJlbHNfIiwiaGlnaGxpZ2h0U2VyaWVzXyIsInJlcGFyc2VTZXJpZXMiLCJBWElTX1NUUklOR19NQVBQSU5HU18iLCJheGlzVG9JbmRleF8iLCJheGlzIiwicHJvdG90eXBlIiwibGFiZWxzIiwic2xpY2UiLCJzZXJpZXMiLCJvcHRpb25zIiwic2VyaWVzRGljdCIsImlkeCIsImxlbmd0aCIsInNlcmllc05hbWUiLCJvcHRpb25zRm9yU2VyaWVzIiwieUF4aXMiLCJwdXNoIiwiYXhpc19vcHRzIiwidXBkYXRlIiwicHJvY2VzcyIsImVudiIsIk5PREVfRU5WIiwidmFsaWRhdGVPcHRpb25zXyIsIm5hbWUiLCJyZXN1bHQiLCJnZXRHbG9iYWxVc2VyXyIsImdldEdsb2JhbERlZmF1bHRfIiwiREVGQVVMVF9BVFRSUyIsImdldEZvckF4aXMiLCJheGlzSWR4IiwiYXhpc1N0cmluZyIsInVzZXJBeGlzIiwiYXhpc09wdGlvbnMiLCJkZWZhdWx0QXhpc09wdGlvbnMiLCJheGVzIiwiZ2V0Rm9yU2VyaWVzIiwiZ2V0SGlnaGxpZ2h0U2VyaWVzIiwic2VyaWVzT2JqIiwic2VyaWVzT3B0aW9ucyIsIm51bUF4ZXMiLCJheGlzRm9yU2VyaWVzIiwic2VyaWVzRm9yQXhpcyIsInNlcmllc05hbWVzIiwiT1BUSU9OU19SRUZFUkVOQ0UiLCJ0aGF0IiwidmFsaWRhdGVPcHRpb24iLCJvcHRpb25OYW1lIiwid2FybkludmFsaWRPcHRpb25fIiwib3B0aW9uc0RpY3RzIiwibmFtZXMiLCJkaWN0IiwiV0FSTklOR1MiLCJpc1NlcmllcyIsImluZGV4T2YiLCJjb25zb2xlIiwid2FybiIsInJlc2V0V2FybmluZ3NfIiwiX2RlZmF1bHQiLCJtb2R1bGUiLCJkZWZhdWx0Il0sInNvdXJjZXMiOlsiLi4vc3JjL2R5Z3JhcGgtb3B0aW9ucy5qcyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgMjAxMSBEYW4gVmFuZGVya2FtIChkYW52ZGtAZ21haWwuY29tKVxuICogTUlULWxpY2VuY2VkOiBodHRwczovL29wZW5zb3VyY2Uub3JnL2xpY2Vuc2VzL01JVFxuICovXG5cbi8qKlxuICogQGZpbGVvdmVydmlldyBEeWdyYXBoT3B0aW9ucyBpcyByZXNwb25zaWJsZSBmb3IgcGFyc2luZyBhbmQgcmV0dXJuaW5nXG4gKiBpbmZvcm1hdGlvbiBhYm91dCBvcHRpb25zLlxuICovXG5cbi8vIFRPRE86IHJlbW92ZSB0aGlzIGpzaGludCBkaXJlY3RpdmUgJiBmaXggdGhlIHdhcm5pbmdzLlxuLypqc2hpbnQgc3ViOnRydWUgKi9cblwidXNlIHN0cmljdFwiO1xuXG5pbXBvcnQgKiBhcyB1dGlscyBmcm9tICcuL2R5Z3JhcGgtdXRpbHMnO1xuaW1wb3J0IERFRkFVTFRfQVRUUlMgZnJvbSAnLi9keWdyYXBoLWRlZmF1bHQtYXR0cnMnO1xuaW1wb3J0IE9QVElPTlNfUkVGRVJFTkNFIGZyb20gJy4vZHlncmFwaC1vcHRpb25zLXJlZmVyZW5jZSc7XG5cbi8qXG4gKiBJbnRlcmVzdGluZyBtZW1iZXIgdmFyaWFibGVzOiAoUkVNT1ZJTkcgVEhJUyBMSVNUIEFTIEkgQ0xPU1VSSVpFKVxuICogZ2xvYmFsXyAtIGdsb2JhbCBhdHRyaWJ1dGVzIChjb21tb24gYW1vbmcgYWxsIGdyYXBocywgQUlVSSlcbiAqIHVzZXIgLSBhdHRyaWJ1dGVzIHNldCBieSB0aGUgdXNlclxuICogc2VyaWVzXyAtIHsgc2VyaWVzTmFtZSAtPiB7IGlkeCwgeUF4aXMsIG9wdGlvbnMgfX1cbiAqL1xuXG4vKipcbiAqIFRoaXMgcGFyc2VzIGF0dHJpYnV0ZXMgaW50byBhbiBvYmplY3QgdGhhdCBjYW4gYmUgZWFzaWx5IHF1ZXJpZWQuXG4gKlxuICogSXQgZG9lc24ndCBuZWNlc3NhcmlseSBtZWFuIHRoYXQgYWxsIG9wdGlvbnMgYXJlIGF2YWlsYWJsZSwgc3BlY2lmaWNhbGx5XG4gKiBpZiBsYWJlbHMgYXJlIG5vdCB5ZXQgYXZhaWxhYmxlLCBzaW5jZSB0aG9zZSBkcml2ZSBkZXRhaWxzIG9mIHRoZSBwZXItc2VyaWVzXG4gKiBhbmQgcGVyLWF4aXMgb3B0aW9ucy5cbiAqXG4gKiBAcGFyYW0ge0R5Z3JhcGh9IGR5Z3JhcGggVGhlIGNoYXJ0IHRvIHdoaWNoIHRoZXNlIG9wdGlvbnMgYmVsb25nLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbnZhciBEeWdyYXBoT3B0aW9ucyA9IGZ1bmN0aW9uKGR5Z3JhcGgpIHtcbiAgLyoqXG4gICAqIFRoZSBkeWdyYXBoLlxuICAgKiBAdHlwZSB7IUR5Z3JhcGh9XG4gICAqL1xuICB0aGlzLmR5Z3JhcGhfID0gZHlncmFwaDtcblxuICAvKipcbiAgICogQXJyYXkgb2YgYXhpcyBpbmRleCB0byB7IHNlcmllcyA6IFsgc2VyaWVzIG5hbWVzIF0gLCBvcHRpb25zIDogeyBheGlzLXNwZWNpZmljIG9wdGlvbnMuIH0gfVxuICAgKiBAdHlwZSB7QXJyYXkuPHtzZXJpZXMgOiBBcnJheS48c3RyaW5nPiwgb3B0aW9ucyA6IE9iamVjdH0+fSBAcHJpdmF0ZVxuICAgKi9cbiAgdGhpcy55QXhlc18gPSBbXTtcblxuICAvKipcbiAgICogQ29udGFpbnMgeC1heGlzIHNwZWNpZmljIG9wdGlvbnMsIHdoaWNoIGFyZSBzdG9yZWQgaW4gdGhlIG9wdGlvbnMga2V5LlxuICAgKiBUaGlzIG1hdGNoZXMgdGhlIHlBeGVzXyBvYmplY3Qgc3RydWN0dXJlIChieSBiZWluZyBhIGRpY3Rpb25hcnkgd2l0aCBhblxuICAgKiBvcHRpb25zIGVsZW1lbnQpIGFsbG93aW5nIGZvciBzaGFyZWQgY29kZS5cbiAgICogQHR5cGUge29wdGlvbnM6IE9iamVjdH0gQHByaXZhdGVcbiAgICovXG4gIHRoaXMueEF4aXNfID0ge307XG4gIHRoaXMuc2VyaWVzXyA9IHt9O1xuXG4gIC8vIE9uY2UgdGhlc2UgdHdvIG9iamVjdHMgYXJlIGluaXRpYWxpemVkLCB5b3UgY2FuIGNhbGwgZ2V0KCk7XG4gIHRoaXMuZ2xvYmFsXyA9IHRoaXMuZHlncmFwaF8uYXR0cnNfO1xuICB0aGlzLnVzZXJfID0gdGhpcy5keWdyYXBoXy51c2VyX2F0dHJzXyB8fCB7fTtcblxuICAvKipcbiAgICogQSBsaXN0IG9mIHNlcmllcyBpbiBjb2x1bW5hciBvcmRlci5cbiAgICogQHR5cGUge0FycmF5LjxzdHJpbmc+fVxuICAgKi9cbiAgdGhpcy5sYWJlbHNfID0gW107XG5cbiAgdGhpcy5oaWdobGlnaHRTZXJpZXNfID0gdGhpcy5nZXQoXCJoaWdobGlnaHRTZXJpZXNPcHRzXCIpIHx8IHt9O1xuICB0aGlzLnJlcGFyc2VTZXJpZXMoKTtcbn07XG5cbi8qKlxuICogTm90IG9wdGltYWwsIGJ1dCBkb2VzIHRoZSB0cmljayB3aGVuIHlvdSdyZSBvbmx5IHVzaW5nIHR3byBheGVzLlxuICogSWYgd2UgbW92ZSB0byBtb3JlIGF4ZXMsIHRoaXMgY2FuIGp1c3QgYmVjb21lIGEgZnVuY3Rpb24uXG4gKlxuICogQHR5cGUge09iamVjdC48bnVtYmVyPn1cbiAqIEBwcml2YXRlXG4gKi9cbkR5Z3JhcGhPcHRpb25zLkFYSVNfU1RSSU5HX01BUFBJTkdTXyA9IHtcbiAgJ3knIDogMCxcbiAgJ1knIDogMCxcbiAgJ3kxJyA6IDAsXG4gICdZMScgOiAwLFxuICAneTInIDogMSxcbiAgJ1kyJyA6IDFcbn07XG5cbi8qKlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBheGlzXG4gKiBAcHJpdmF0ZVxuICovXG5EeWdyYXBoT3B0aW9ucy5heGlzVG9JbmRleF8gPSBmdW5jdGlvbihheGlzKSB7XG4gIGlmICh0eXBlb2YoYXhpcykgPT0gXCJzdHJpbmdcIikge1xuICAgIGlmIChEeWdyYXBoT3B0aW9ucy5BWElTX1NUUklOR19NQVBQSU5HU18uaGFzT3duUHJvcGVydHkoYXhpcykpIHtcbiAgICAgIHJldHVybiBEeWdyYXBoT3B0aW9ucy5BWElTX1NUUklOR19NQVBQSU5HU19bYXhpc107XG4gICAgfVxuICAgIHRocm93IFwiVW5rbm93biBheGlzIDogXCIgKyBheGlzO1xuICB9XG4gIGlmICh0eXBlb2YoYXhpcykgPT0gXCJudW1iZXJcIikge1xuICAgIGlmIChheGlzID09PSAwIHx8IGF4aXMgPT09IDEpIHtcbiAgICAgIHJldHVybiBheGlzO1xuICAgIH1cbiAgICB0aHJvdyBcIkR5Z3JhcGhzIG9ubHkgc3VwcG9ydHMgdHdvIHktYXhlcywgaW5kZXhlZCBmcm9tIDAtMS5cIjtcbiAgfVxuICBpZiAoYXhpcykge1xuICAgIHRocm93IFwiVW5rbm93biBheGlzIDogXCIgKyBheGlzO1xuICB9XG4gIC8vIE5vIGF4aXMgc3BlY2lmaWNhdGlvbiBtZWFucyBheGlzIDAuXG4gIHJldHVybiAwO1xufTtcblxuLyoqXG4gKiBSZXBhcnNlcyBvcHRpb25zIHRoYXQgYXJlIGFsbCByZWxhdGVkIHRvIHNlcmllcy4gVGhpcyB0eXBpY2FsbHkgb2NjdXJzIHdoZW5cbiAqIG9wdGlvbnMgYXJlIGVpdGhlciB1cGRhdGVkLCBvciBzb3VyY2UgZGF0YSBoYXMgYmVlbiBtYWRlIGF2YWlsYWJsZS5cbiAqXG4gKiBUT0RPKGtvbmlnc2JlcmcpOiBUaGUgbWV0aG9kIG5hbWUgaXMga2luZCBvZiB3ZWFrOyBmaXguXG4gKi9cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5yZXBhcnNlU2VyaWVzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBsYWJlbHMgPSB0aGlzLmdldChcImxhYmVsc1wiKTtcbiAgaWYgKCFsYWJlbHMpIHtcbiAgICByZXR1cm47IC8vIC0tIGNhbid0IGRvIG1vcmUgZm9yIG5vdywgd2lsbCBwYXJzZSBhZnRlciBnZXR0aW5nIHRoZSBsYWJlbHMuXG4gIH1cblxuICB0aGlzLmxhYmVsc18gPSBsYWJlbHMuc2xpY2UoMSk7XG5cbiAgdGhpcy55QXhlc18gPSBbIHsgc2VyaWVzIDogW10sIG9wdGlvbnMgOiB7fX0gXTsgLy8gQWx3YXlzIG9uZSBheGlzIGF0IGxlYXN0LlxuICB0aGlzLnhBeGlzXyA9IHsgb3B0aW9ucyA6IHt9IH07XG4gIHRoaXMuc2VyaWVzXyA9IHt9O1xuXG4gIC8vIFNlcmllcyBhcmUgc3BlY2lmaWVkIGluIHRoZSBzZXJpZXMgZWxlbWVudDpcbiAgLy9cbiAgLy8ge1xuICAvLyAgIGxhYmVsczogWyBcIlhcIiwgXCJmb29cIiwgXCJiYXJcIiBdLFxuICAvLyAgIHBvaW50U2l6ZTogMyxcbiAgLy8gICBzZXJpZXMgOiB7XG4gIC8vICAgICBmb28gOiB7fSwgLy8gb3B0aW9ucyBmb3IgZm9vXG4gIC8vICAgICBiYXIgOiB7fSAvLyBvcHRpb25zIGZvciBiYXJcbiAgLy8gICB9XG4gIC8vIH1cbiAgLy9cbiAgLy8gU28sIGlmIHNlcmllcyBpcyBmb3VuZCwgaXQncyBleHBlY3RlZCB0byBjb250YWluIHBlci1zZXJpZXMgZGF0YSxcbiAgLy8gb3RoZXJ3aXNlIHNldCBhIGRlZmF1bHQuXG4gIHZhciBzZXJpZXNEaWN0ID0gdGhpcy51c2VyXy5zZXJpZXMgfHwge307XG4gIGZvciAodmFyIGlkeCA9IDA7IGlkeCA8IHRoaXMubGFiZWxzXy5sZW5ndGg7IGlkeCsrKSB7XG4gICAgdmFyIHNlcmllc05hbWUgPSB0aGlzLmxhYmVsc19baWR4XTtcbiAgICB2YXIgb3B0aW9uc0ZvclNlcmllcyA9IHNlcmllc0RpY3Rbc2VyaWVzTmFtZV0gfHwge307XG4gICAgdmFyIHlBeGlzID0gRHlncmFwaE9wdGlvbnMuYXhpc1RvSW5kZXhfKG9wdGlvbnNGb3JTZXJpZXNbXCJheGlzXCJdKTtcblxuICAgIHRoaXMuc2VyaWVzX1tzZXJpZXNOYW1lXSA9IHtcbiAgICAgIGlkeDogaWR4LFxuICAgICAgeUF4aXM6IHlBeGlzLFxuICAgICAgb3B0aW9ucyA6IG9wdGlvbnNGb3JTZXJpZXMgfTtcblxuICAgIGlmICghdGhpcy55QXhlc19beUF4aXNdKSB7XG4gICAgICB0aGlzLnlBeGVzX1t5QXhpc10gPSAgeyBzZXJpZXMgOiBbIHNlcmllc05hbWUgXSwgb3B0aW9ucyA6IHt9IH07XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMueUF4ZXNfW3lBeGlzXS5zZXJpZXMucHVzaChzZXJpZXNOYW1lKTtcbiAgICB9XG4gIH1cblxuICB2YXIgYXhpc19vcHRzID0gdGhpcy51c2VyX1tcImF4ZXNcIl0gfHwge307XG4gIHV0aWxzLnVwZGF0ZSh0aGlzLnlBeGVzX1swXS5vcHRpb25zLCBheGlzX29wdHNbXCJ5XCJdIHx8IHt9KTtcbiAgaWYgKHRoaXMueUF4ZXNfLmxlbmd0aCA+IDEpIHtcbiAgICB1dGlscy51cGRhdGUodGhpcy55QXhlc19bMV0ub3B0aW9ucywgYXhpc19vcHRzW1wieTJcIl0gfHwge30pO1xuICB9XG4gIHV0aWxzLnVwZGF0ZSh0aGlzLnhBeGlzXy5vcHRpb25zLCBheGlzX29wdHNbXCJ4XCJdIHx8IHt9KTtcblxuICBpZiAodHlwZW9mIHByb2Nlc3MgIT09ICd1bmRlZmluZWQnICYmIHByb2Nlc3MuZW52Lk5PREVfRU5WICE9ICdwcm9kdWN0aW9uJykge1xuICAvLyBGb3IgXCJwcm9kdWN0aW9uXCIgY29kZSwgdGhpcyBnZXRzIHJlbW92ZWQgYnkgdWdsaWZ5anMuXG4gICAgdGhpcy52YWxpZGF0ZU9wdGlvbnNfKCk7XG4gIH1cbn07XG5cbi8qKlxuICogR2V0IGEgZ2xvYmFsIHZhbHVlLlxuICpcbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIHRoZSBuYW1lIG9mIHRoZSBvcHRpb24uXG4gKi9cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5nZXQgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHZhciByZXN1bHQgPSB0aGlzLmdldEdsb2JhbFVzZXJfKG5hbWUpO1xuICBpZiAocmVzdWx0ICE9PSBudWxsKSB7XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuICByZXR1cm4gdGhpcy5nZXRHbG9iYWxEZWZhdWx0XyhuYW1lKTtcbn07XG5cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5nZXRHbG9iYWxVc2VyXyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgaWYgKHRoaXMudXNlcl8uaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICByZXR1cm4gdGhpcy51c2VyX1tuYW1lXTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5nZXRHbG9iYWxEZWZhdWx0XyA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgaWYgKHRoaXMuZ2xvYmFsXy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgIHJldHVybiB0aGlzLmdsb2JhbF9bbmFtZV07XG4gIH1cbiAgaWYgKERFRkFVTFRfQVRUUlMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICByZXR1cm4gREVGQVVMVF9BVFRSU1tuYW1lXTtcbiAgfVxuICByZXR1cm4gbnVsbDtcbn07XG5cbi8qKlxuICogR2V0IGEgdmFsdWUgZm9yIGEgc3BlY2lmaWMgYXhpcy4gSWYgdGhlcmUgaXMgbm8gc3BlY2lmaWMgdmFsdWUgZm9yIHRoZSBheGlzLFxuICogdGhlIGdsb2JhbCB2YWx1ZSBpcyByZXR1cm5lZC5cbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgb3B0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd8bnVtYmVyfSBheGlzIHRoZSBheGlzIHRvIHNlYXJjaC4gQ2FuIGJlIHRoZSBzdHJpbmcgcmVwcmVzZW50YXRpb25cbiAqIChcInlcIiwgXCJ5MlwiKSBvciB0aGUgYXhpcyBudW1iZXIgKDAsIDEpLlxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUuZ2V0Rm9yQXhpcyA9IGZ1bmN0aW9uKG5hbWUsIGF4aXMpIHtcbiAgdmFyIGF4aXNJZHg7XG4gIHZhciBheGlzU3RyaW5nO1xuXG4gIC8vIFNpbmNlIGF4aXMgY2FuIGJlIGEgbnVtYmVyIG9yIGEgc3RyaW5nLCBzdHJhaWdodGVuIGV2ZXJ5dGhpbmcgb3V0IGhlcmUuXG4gIGlmICh0eXBlb2YoYXhpcykgPT0gJ251bWJlcicpIHtcbiAgICBheGlzSWR4ID0gYXhpcztcbiAgICBheGlzU3RyaW5nID0gYXhpc0lkeCA9PT0gMCA/IFwieVwiIDogXCJ5MlwiO1xuICB9IGVsc2Uge1xuICAgIGlmIChheGlzID09IFwieTFcIikgeyBheGlzID0gXCJ5XCI7IH0gLy8gU3RhbmRhcmRpemUgb24gJ3knLiBJcyB0aGlzIGJhZD8gSSB0aGluayBzby5cbiAgICBpZiAoYXhpcyA9PSBcInlcIikge1xuICAgICAgYXhpc0lkeCA9IDA7XG4gICAgfSBlbHNlIGlmIChheGlzID09IFwieTJcIikge1xuICAgICAgYXhpc0lkeCA9IDE7XG4gICAgfSBlbHNlIGlmIChheGlzID09IFwieFwiKSB7XG4gICAgICBheGlzSWR4ID0gLTE7IC8vIHNpbXBseSBhIHBsYWNlaG9sZGVyIGZvciBiZWxvdy5cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3cgXCJVbmtub3duIGF4aXMgXCIgKyBheGlzO1xuICAgIH1cbiAgICBheGlzU3RyaW5nID0gYXhpcztcbiAgfVxuXG4gIHZhciB1c2VyQXhpcyA9IChheGlzSWR4ID09IC0xKSA/IHRoaXMueEF4aXNfIDogdGhpcy55QXhlc19bYXhpc0lkeF07XG5cbiAgLy8gU2VhcmNoIHRoZSB1c2VyLXNwZWNpZmllZCBheGlzIG9wdGlvbiBmaXJzdC5cbiAgaWYgKHVzZXJBeGlzKSB7IC8vIFRoaXMgY29uZGl0aW9uIGNvdWxkIGJlIHJlbW92ZWQgaWYgd2UgYWx3YXlzIHNldCB1cCB0aGlzLnlBeGVzXyBmb3IgeTIuXG4gICAgdmFyIGF4aXNPcHRpb25zID0gdXNlckF4aXMub3B0aW9ucztcbiAgICBpZiAoYXhpc09wdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgIHJldHVybiBheGlzT3B0aW9uc1tuYW1lXTtcbiAgICB9XG4gIH1cblxuICAvLyBVc2VyLXNwZWNpZmllZCBnbG9iYWwgb3B0aW9ucyBzZWNvbmQuXG4gIC8vIEJ1dCwgaGFjaywgaWdub3JlIGdsb2JhbGx5LXNwZWNpZmllZCAnbG9nc2NhbGUnIGZvciAneCcgYXhpcyBkZWNsYXJhdGlvbi5cbiAgaWYgKCEoYXhpcyA9PT0gJ3gnICYmIG5hbWUgPT09ICdsb2dzY2FsZScpKSB7XG4gICAgdmFyIHJlc3VsdCA9IHRoaXMuZ2V0R2xvYmFsVXNlcl8obmFtZSk7XG4gICAgaWYgKHJlc3VsdCAhPT0gbnVsbCkge1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH1cbiAgLy8gRGVmYXVsdCBheGlzIG9wdGlvbnMgdGhpcmQuXG4gIHZhciBkZWZhdWx0QXhpc09wdGlvbnMgPSBERUZBVUxUX0FUVFJTLmF4ZXNbYXhpc1N0cmluZ107XG4gIGlmIChkZWZhdWx0QXhpc09wdGlvbnMuaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICByZXR1cm4gZGVmYXVsdEF4aXNPcHRpb25zW25hbWVdO1xuICB9XG5cbiAgLy8gRGVmYXVsdCBnbG9iYWwgb3B0aW9ucyBsYXN0LlxuICByZXR1cm4gdGhpcy5nZXRHbG9iYWxEZWZhdWx0XyhuYW1lKTtcbn07XG5cbi8qKlxuICogR2V0IGEgdmFsdWUgZm9yIGEgc3BlY2lmaWMgc2VyaWVzLiBJZiB0aGVyZSBpcyBubyBzcGVjaWZpYyB2YWx1ZSBmb3IgdGhlIHNlcmllcyxcbiAqIHRoZSB2YWx1ZSBmb3IgdGhlIGF4aXMgaXMgcmV0dXJuZWQgKGFuZCBhZnRlcndhcmRzLCB0aGUgZ2xvYmFsIHZhbHVlLilcbiAqXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSB0aGUgbmFtZSBvZiB0aGUgb3B0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IHNlcmllcyB0aGUgc2VyaWVzIHRvIHNlYXJjaC5cbiAqL1xuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLmdldEZvclNlcmllcyA9IGZ1bmN0aW9uKG5hbWUsIHNlcmllcykge1xuICAvLyBIb25vcnMgaW5kZXhlcyBhcyBzZXJpZXMuXG4gIGlmIChzZXJpZXMgPT09IHRoaXMuZHlncmFwaF8uZ2V0SGlnaGxpZ2h0U2VyaWVzKCkpIHtcbiAgICBpZiAodGhpcy5oaWdobGlnaHRTZXJpZXNfLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgICByZXR1cm4gdGhpcy5oaWdobGlnaHRTZXJpZXNfW25hbWVdO1xuICAgIH1cbiAgfVxuXG4gIGlmICghdGhpcy5zZXJpZXNfLmhhc093blByb3BlcnR5KHNlcmllcykpIHtcbiAgICB0aHJvdyBcIlVua25vd24gc2VyaWVzOiBcIiArIHNlcmllcztcbiAgfVxuXG4gIHZhciBzZXJpZXNPYmogPSB0aGlzLnNlcmllc19bc2VyaWVzXTtcbiAgdmFyIHNlcmllc09wdGlvbnMgPSBzZXJpZXNPYmpbXCJvcHRpb25zXCJdO1xuICBpZiAoc2VyaWVzT3B0aW9ucy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgIHJldHVybiBzZXJpZXNPcHRpb25zW25hbWVdO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZ2V0Rm9yQXhpcyhuYW1lLCBzZXJpZXNPYmpbXCJ5QXhpc1wiXSk7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIG51bWJlciBvZiB5LWF4ZXMgb24gdGhlIGNoYXJ0LlxuICogQHJldHVybiB7bnVtYmVyfSB0aGUgbnVtYmVyIG9mIGF4ZXMuXG4gKi9cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5udW1BeGVzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLnlBeGVzXy5sZW5ndGg7XG59O1xuXG4vKipcbiAqIFJldHVybiB0aGUgeS1heGlzIGZvciBhIGdpdmVuIHNlcmllcywgc3BlY2lmaWVkIGJ5IG5hbWUuXG4gKi9cbkR5Z3JhcGhPcHRpb25zLnByb3RvdHlwZS5heGlzRm9yU2VyaWVzID0gZnVuY3Rpb24oc2VyaWVzKSB7XG4gIHJldHVybiB0aGlzLnNlcmllc19bc2VyaWVzXS55QXhpcztcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgb3B0aW9ucyBmb3IgdGhlIHNwZWNpZmllZCBheGlzLlxuICovXG4vLyBUT0RPKGtvbmlnc2JlcmcpOiB0aGlzIGlzIHktYXhpcyBzcGVjaWZpYy4gU3VwcG9ydCB0aGUgeCBheGlzLlxuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLmF4aXNPcHRpb25zID0gZnVuY3Rpb24oeUF4aXMpIHtcbiAgcmV0dXJuIHRoaXMueUF4ZXNfW3lBeGlzXS5vcHRpb25zO1xufTtcblxuLyoqXG4gKiBSZXR1cm4gdGhlIHNlcmllcyBhc3NvY2lhdGVkIHdpdGggYW4gYXhpcy5cbiAqL1xuRHlncmFwaE9wdGlvbnMucHJvdG90eXBlLnNlcmllc0ZvckF4aXMgPSBmdW5jdGlvbih5QXhpcykge1xuICByZXR1cm4gdGhpcy55QXhlc19beUF4aXNdLnNlcmllcztcbn07XG5cbi8qKlxuICogUmV0dXJuIHRoZSBsaXN0IG9mIGFsbCBzZXJpZXMsIGluIHRoZWlyIGNvbHVtbmFyIG9yZGVyLlxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUuc2VyaWVzTmFtZXMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMubGFiZWxzXztcbn07XG5cbmlmICh0eXBlb2YgcHJvY2VzcyAhPT0gJ3VuZGVmaW5lZCcgJiYgcHJvY2Vzcy5lbnYuTk9ERV9FTlYgIT0gJ3Byb2R1Y3Rpb24nKSB7XG4vLyBGb3IgXCJwcm9kdWN0aW9uXCIgY29kZSwgdGhpcyBnZXRzIHJlbW92ZWQgYnkgdWdsaWZ5anMuXG5cbi8qKlxuICogVmFsaWRhdGUgYWxsIG9wdGlvbnMuXG4gKiBUaGlzIHJlcXVpcmVzIE9QVElPTlNfUkVGRVJFTkNFLCB3aGljaCBpcyBvbmx5IGF2YWlsYWJsZSBpbiBkZWJ1ZyBidWlsZHMuXG4gKiBAcHJpdmF0ZVxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUudmFsaWRhdGVPcHRpb25zXyA9IGZ1bmN0aW9uKCkge1xuICBpZiAodHlwZW9mIE9QVElPTlNfUkVGRVJFTkNFID09PSAndW5kZWZpbmVkJykge1xuICAgIHRocm93ICdDYWxsZWQgdmFsaWRhdGVPcHRpb25zXyBpbiBwcm9kIGJ1aWxkLic7XG4gIH1cblxuICB2YXIgdGhhdCA9IHRoaXM7XG4gIHZhciB2YWxpZGF0ZU9wdGlvbiA9IGZ1bmN0aW9uKG9wdGlvbk5hbWUpIHtcbiAgICBpZiAoIU9QVElPTlNfUkVGRVJFTkNFW29wdGlvbk5hbWVdKSB7XG4gICAgICB0aGF0Lndhcm5JbnZhbGlkT3B0aW9uXyhvcHRpb25OYW1lKTtcbiAgICB9XG4gIH07XG5cbiAgdmFyIG9wdGlvbnNEaWN0cyA9IFt0aGlzLnhBeGlzXy5vcHRpb25zLFxuICAgICAgICAgICAgICAgICAgICAgIHRoaXMueUF4ZXNfWzBdLm9wdGlvbnMsXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy55QXhlc19bMV0gJiYgdGhpcy55QXhlc19bMV0ub3B0aW9ucyxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmdsb2JhbF8sXG4gICAgICAgICAgICAgICAgICAgICAgdGhpcy51c2VyXyxcbiAgICAgICAgICAgICAgICAgICAgICB0aGlzLmhpZ2hsaWdodFNlcmllc19dO1xuICB2YXIgbmFtZXMgPSB0aGlzLnNlcmllc05hbWVzKCk7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbmFtZXMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgbmFtZSA9IG5hbWVzW2ldO1xuICAgIGlmICh0aGlzLnNlcmllc18uaGFzT3duUHJvcGVydHkobmFtZSkpIHtcbiAgICAgIG9wdGlvbnNEaWN0cy5wdXNoKHRoaXMuc2VyaWVzX1tuYW1lXS5vcHRpb25zKTtcbiAgICB9XG4gIH1cbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBvcHRpb25zRGljdHMubGVuZ3RoOyBpKyspIHtcbiAgICB2YXIgZGljdCA9IG9wdGlvbnNEaWN0c1tpXTtcbiAgICBpZiAoIWRpY3QpIGNvbnRpbnVlO1xuICAgIGZvciAodmFyIG9wdGlvbk5hbWUgaW4gZGljdCkge1xuICAgICAgaWYgKGRpY3QuaGFzT3duUHJvcGVydHkob3B0aW9uTmFtZSkpIHtcbiAgICAgICAgdmFsaWRhdGVPcHRpb24ob3B0aW9uTmFtZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG52YXIgV0FSTklOR1MgPSB7fTsgIC8vIE9ubHkgc2hvdyBhbnkgcGFydGljdWxhciB3YXJuaW5nIG9uY2UuXG5cbi8qKlxuICogTG9ncyBhIHdhcm5pbmcgYWJvdXQgaW52YWxpZCBvcHRpb25zLlxuICogVE9ETzogbWFrZSB0aGlzIHRocm93IGZvciB0ZXN0aW5nXG4gKiBAcHJpdmF0ZVxuICovXG5EeWdyYXBoT3B0aW9ucy5wcm90b3R5cGUud2FybkludmFsaWRPcHRpb25fID0gZnVuY3Rpb24ob3B0aW9uTmFtZSkge1xuICBpZiAoIVdBUk5JTkdTW29wdGlvbk5hbWVdKSB7XG4gICAgV0FSTklOR1Nbb3B0aW9uTmFtZV0gPSB0cnVlO1xuICAgIHZhciBpc1NlcmllcyA9ICh0aGlzLmxhYmVsc18uaW5kZXhPZihvcHRpb25OYW1lKSA+PSAwKTtcbiAgICBpZiAoaXNTZXJpZXMpIHtcbiAgICAgIGNvbnNvbGUud2FybignVXNlIG5ldy1zdHlsZSBwZXItc2VyaWVzIG9wdGlvbnMgKHNhdyAnICsgb3B0aW9uTmFtZSArICcgYXMgdG9wLWxldmVsIG9wdGlvbnMga2V5KS4gU2VlIGh0dHA6Ly9ibG9nLmR5Z3JhcGhzLmNvbS8yMDEyLzEyL3RoZS1uZXctYW5kLWJldHRlci13YXktdG8tc3BlY2lmeS5odG1sIChUaGUgTmV3IGFuZCBCZXR0ZXIgV2F5IHRvIFNwZWNpZnkgU2VyaWVzIGFuZCBBeGlzIE9wdGlvbnMpLicpO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb25zb2xlLndhcm4oJ1Vua25vd24gb3B0aW9uICcgKyBvcHRpb25OYW1lICsgJyAoc2VlIGh0dHBzOi8vZHlncmFwaHMuY29tL29wdGlvbnMuaHRtbCBmb3IgdGhlIGZ1bGwgbGlzdCBvZiBvcHRpb25zKScpO1xuICAgIH1cbiAgICB0aHJvdyBcImludmFsaWQgb3B0aW9uIFwiICsgb3B0aW9uTmFtZTtcbiAgfVxufTtcblxuLy8gUmVzZXQgbGlzdCBvZiBwcmV2aW91c2x5LXNob3duIHdhcm5pbmdzLiBVc2VkIGZvciB0ZXN0aW5nLlxuRHlncmFwaE9wdGlvbnMucmVzZXRXYXJuaW5nc18gPSBmdW5jdGlvbigpIHtcbiAgV0FSTklOR1MgPSB7fTtcbn07XG5cbn1cblxuZXhwb3J0IGRlZmF1bHQgRHlncmFwaE9wdGlvbnM7XG4iXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBO0FBQ0E7O0FBRUE7QUFDQTtBQUNBLFlBQVk7O0FBQUNBLE1BQUEsQ0FBQUMsY0FBQSxDQUFBQyxPQUFBO0VBQUFDLEtBQUE7QUFBQTtBQUFBRCxPQUFBO0FBRWIsSUFBQUUsS0FBQSxHQUFBQyx1QkFBQSxDQUFBQyxPQUFBO0FBQ0EsSUFBQUMsb0JBQUEsR0FBQUMsc0JBQUEsQ0FBQUYsT0FBQTtBQUNBLElBQUFHLHdCQUFBLEdBQUFELHNCQUFBLENBQUFGLE9BQUE7QUFBNEQsU0FBQUUsdUJBQUFFLENBQUEsV0FBQUEsQ0FBQSxJQUFBQSxDQUFBLENBQUFDLFVBQUEsR0FBQUQsQ0FBQSxnQkFBQUEsQ0FBQTtBQUFBLFNBQUFFLHlCQUFBRixDQUFBLDZCQUFBRyxPQUFBLG1CQUFBQyxDQUFBLE9BQUFELE9BQUEsSUFBQUUsQ0FBQSxPQUFBRixPQUFBLFlBQUFELHdCQUFBLFlBQUFBLHlCQUFBRixDQUFBLFdBQUFBLENBQUEsR0FBQUssQ0FBQSxHQUFBRCxDQUFBLEtBQUFKLENBQUE7QUFBQSxTQUFBTCx3QkFBQUss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O1FBQ3JDeUIsWUFBWSxDQUFDaEMsSUFBSSxDQUFDLElBQUksQ0FBQ3RCLE9BQU8sQ0FBQzZCLElBQUksQ0FBQyxDQUFDZCxPQUFPLENBQUM7TUFDL0M7SUFDRjtJQUNBLEtBQUssSUFBSXRCLENBQUMsR0FBRyxDQUFDLEVBQUVBLENBQUMsR0FBRzZELFlBQVksQ0FBQ3BDLE1BQU0sRUFBRXpCLENBQUMsRUFBRSxFQUFFO01BQzVDLElBQUkrRCxJQUFJLEdBQUdGLFlBQVksQ0FBQzdELENBQUMsQ0FBQztNQUMxQixJQUFJLENBQUMrRCxJQUFJLEVBQUU7TUFDWCxLQUFLLElBQUlKLFVBQVUsSUFBSUksSUFBSSxFQUFFO1FBQzNCLElBQUlBLElBQUksQ0FBQ2pFLGNBQWMsQ0FBQzZELFVBQVUsQ0FBQyxFQUFFO1VBQ25DRCxjQUFjLENBQUNDLFVBQVUsQ0FBQztRQUM1QjtNQUNGO0lBQ0Y7RUFDRixDQUFDO0VBRUQsSUFBSUssUUFBUSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUU7O0VBRXBCO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7RUFDQTlELGNBQWMsQ0FBQ2dCLFNBQVMsQ0FBQzBDLGtCQUFrQixHQUFHLFVBQVNELFVBQVUsRUFBRTtJQUNqRSxJQUFJLENBQUNLLFFBQVEsQ0FBQ0wsVUFBVSxDQUFDLEVBQUU7TUFDekJLLFFBQVEsQ0FBQ0wsVUFBVSxDQUFDLEdBQUcsSUFBSTtNQUMzQixJQUFJTSxRQUFRLEdBQUksSUFBSSxDQUFDckQsT0FBTyxDQUFDc0QsT0FBTyxDQUFDUCxVQUFVLENBQUMsSUFBSSxDQUFFO01BQ3RELElBQUlNLFFBQVEsRUFBRTtRQUNaRSxPQUFPLENBQUNDLElBQUksQ0FBQyx3Q0FBd0MsR0FBR1QsVUFBVSxHQUFHLHNLQUFzSyxDQUFDO01BQzlPLENBQUMsTUFBTTtRQUNMUSxPQUFPLENBQUNDLElBQUksQ0FBQyxpQkFBaUIsR0FBR1QsVUFBVSxHQUFHLHVFQUF1RSxDQUFDO01BQ3hIO01BQ0EsTUFBTSxpQkFBaUIsR0FBR0EsVUFBVTtJQUN0QztFQUNGLENBQUM7O0VBRUQ7RUFDQXpELGNBQWMsQ0FBQ21FLGNBQWMsR0FBRyxZQUFXO0lBQ3pDTCxRQUFRLEdBQUcsQ0FBQyxDQUFDO0VBQ2YsQ0FBQztBQUVEO0FBQUMsSUFBQU0sUUFBQSxHQUFBN0YsT0FBQSxjQUVjeUIsY0FBYztBQUFBcUUsTUFBQSxDQUFBOUYsT0FBQSxHQUFBQSxPQUFBLENBQUErRixPQUFBIiwiaWdub3JlTGlzdCI6W119