diff --git a/build/embed.d.ts b/build/embed.d.ts new file mode 100644 index 00000000..4a87888c --- /dev/null +++ b/build/embed.d.ts @@ -0,0 +1,45 @@ +import * as vegaImport from 'vega-lib'; +import * as VegaLite from 'vega-lite'; +import { Config as VgConfig, Loader, Spec as VgSpec, View } from 'vega-lib'; +import { Config as VlConfig } from 'vega-lite/build/src/config'; +import { TopLevelExtendedSpec as VlSpec } from 'vega-lite/build/src/spec'; +export declare const vega: typeof vegaImport; +export declare const vl: typeof VegaLite; +export declare type Mode = 'vega' | 'vega-lite'; +export interface EmbedOptions { + actions?: boolean | { + export?: boolean; + source?: boolean; + editor?: boolean; + }; + mode?: Mode; + logLevel?: number; + loader?: Loader; + renderer?: 'canvas' | 'svg'; + onBeforeParse?: (spec: VisualizationSpec) => VisualizationSpec; + width?: number; + height?: number; + padding?: number | { + left?: number; + right?: number; + top?: number; + bottom?: number; + }; + config?: string | VlConfig | VgConfig; + sourceHeader?: string; + sourceFooter?: string; + editorUrl?: string; +} +export declare type VisualizationSpec = VlSpec | VgSpec; +/** + * Embed a Vega visualization component in a web page. This function returns a promise. + * + * @param el DOM element in which to place component (DOM node or CSS selector). + * @param spec String : A URL string from which to load the Vega specification. + * Object : The Vega/Vega-Lite specification as a parsed JSON object. + * @param opt A JavaScript object containing options for embedding. + */ +export default function embed(el: HTMLBaseElement | string, spec: string | VisualizationSpec, opt: EmbedOptions): Promise<{} | { + view: View; + spec: VisualizationSpec; +}>; diff --git a/build/embed.js b/build/embed.js new file mode 100644 index 00000000..8bff52e7 --- /dev/null +++ b/build/embed.js @@ -0,0 +1,161 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var versionCompare = require("compare-versions"); +var d3 = require("d3-selection"); +var vegaImport = require("vega-lib"); +var VegaLite = require("vega-lite"); +var vega_schema_url_parser_1 = require("vega-schema-url-parser"); +var post_1 = require("./post"); +exports.vega = vegaImport; +exports.vl = VegaLite; +var NAMES = { + 'vega': 'Vega', + 'vega-lite': 'Vega-Lite', +}; +var VERSION = { + 'vega': exports.vega.version, + 'vega-lite': exports.vl ? exports.vl.version : 'not available', +}; +var PREPROCESSOR = { + 'vega': function (vgjson, _) { return vgjson; }, + 'vega-lite': function (vljson, config) { return exports.vl.compile(vljson, config).spec; }, +}; +/** + * Embed a Vega visualization component in a web page. This function returns a promise. + * + * @param el DOM element in which to place component (DOM node or CSS selector). + * @param spec String : A URL string from which to load the Vega specification. + * Object : The Vega/Vega-Lite specification as a parsed JSON object. + * @param opt A JavaScript object containing options for embedding. + */ +function embed(el, spec, opt) { + try { + opt = opt || {}; + var actions = opt.actions !== undefined ? opt.actions : true; + var loader = opt.loader || exports.vega.loader(); + var renderer = opt.renderer || 'canvas'; + var logLevel = opt.logLevel || exports.vega.Warn; + // Load the visualization specification. + if (exports.vega.isString(spec)) { + return loader.load(spec).then(function (data) { return embed(el, JSON.parse(data), opt); }).catch(Promise.reject); + } + // Load Vega theme/configuration. + var config = opt.config; + if (exports.vega.isString(config)) { + return loader.load(config).then(function (data) { + opt.config = JSON.parse(data); + return embed(el, spec, opt); + }).catch(Promise.reject); + } + // Decide mode + var parsed = void 0; + var mode_1; + if (spec.$schema) { + parsed = vega_schema_url_parser_1.default(spec.$schema); + if (opt.mode && opt.mode !== parsed.library) { + console.warn("The given visualization spec is written in " + NAMES[parsed.library] + ", but mode argument sets " + NAMES[opt.mode] + "."); + } + mode_1 = parsed.library; + if (versionCompare(parsed.version, VERSION[mode_1]) > 0) { + console.warn("The input spec uses " + mode_1 + " " + parsed.version + ", but the current version of " + NAMES[mode_1] + " is " + VERSION[mode_1] + "."); + } + } + else { + mode_1 = opt.mode || 'vega'; + } + var vgSpec = PREPROCESSOR[mode_1](spec, config); + if (mode_1 === 'vega-lite') { + if (vgSpec.$schema) { + parsed = vega_schema_url_parser_1.default(vgSpec.$schema); + if (versionCompare(parsed.version, VERSION.vega) > 0) { + console.warn("The compiled spec uses Vega " + parsed.version + ", but current version is " + VERSION.vega + "."); + } + } + } + // ensure container div has class 'vega-embed' + var div = d3.select(el) // d3.select supports elements and strings + .classed('vega-embed', true) + .html(''); // clear container + if (opt.onBeforeParse) { + // Allow Vega spec to be modified before being used + vgSpec = opt.onBeforeParse(vgSpec); + } + var runtime = exports.vega.parse(vgSpec, opt.config); // may throw an Error if parsing fails + var view_1 = new exports.vega.View(runtime, { loader: loader, logLevel: logLevel, renderer: renderer }) + .initialize(el); + // Vega-Lite does not need hover so we can improve perf by not activating it + if (mode_1 !== 'vega-lite') { + view_1.hover(); + } + if (opt) { + if (opt.width) { + view_1.width(opt.width); + } + if (opt.height) { + view_1.height(opt.height); + } + if (opt.padding) { + view_1.padding(opt.padding); + } + } + view_1.run(); + if (actions !== false) { + // add child div to house action links + var ctrl = div.append('div') + .attr('class', 'vega-actions'); + // add 'Export' action + if (actions === true || actions.export !== false) { + var ext_1 = renderer === 'canvas' ? 'png' : 'svg'; + ctrl.append('a') + .text("Export as " + ext_1.toUpperCase()) + .attr('href', '#') + .attr('target', '_blank') + .attr('download', "visualization." + ext_1) + .on('mousedown', function () { + var _this = this; + view_1.toImageURL(ext_1).then(function (url) { + _this.href = url; + }).catch(function (error) { throw error; }); + d3.event.preventDefault(); + }); + } + // add 'View Source' action + if (actions === true || actions.source !== false) { + ctrl.append('a') + .text('View Source') + .attr('href', '#') + .on('click', function () { + viewSource(JSON.stringify(spec, null, 2), opt.sourceHeader || '', opt.sourceFooter || ''); + d3.event.preventDefault(); + }); + } + // add 'Open in Vega Editor' action + if (actions === true || actions.editor !== false) { + var editorUrl_1 = opt.editorUrl || 'https://vega.github.io/editor/'; + ctrl.append('a') + .text('Open in Vega Editor') + .attr('href', '#') + .on('click', function () { + post_1.post(window, editorUrl_1, { + mode: mode_1, + spec: JSON.stringify(spec, null, 2), + }); + d3.event.preventDefault(); + }); + } + } + return Promise.resolve({ view: view_1, spec: spec }); + } + catch (err) { + return Promise.reject(err); + } +} +exports.default = embed; +function viewSource(source, sourceHeader, sourceFooter) { + var header = "" + sourceHeader + "
";
+    var footer = "
" + sourceFooter + ""; + var win = window.open(''); + win.document.write(header + source + footer); + win.document.title = 'Vega JSON Source'; +} +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZW1iZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvZW1iZWQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7QUFBQSxpREFBbUQ7QUFDbkQsaUNBQW1DO0FBQ25DLHFDQUF1QztBQUN2QyxvQ0FBc0M7QUFDdEMsaUVBQWtEO0FBS2xELCtCQUE4QjtBQUVqQixRQUFBLElBQUksR0FBRyxVQUFVLENBQUM7QUFDbEIsUUFBQSxFQUFFLEdBQUcsUUFBUSxDQUFDO0FBb0IzQixJQUFNLEtBQUssR0FBRztJQUNaLE1BQU0sRUFBTyxNQUFNO0lBQ25CLFdBQVcsRUFBRSxXQUFXO0NBQ3pCLENBQUM7QUFFRixJQUFNLE9BQU8sR0FBRztJQUNkLE1BQU0sRUFBTyxZQUFJLENBQUMsT0FBTztJQUN6QixXQUFXLEVBQUUsVUFBRSxDQUFDLENBQUMsQ0FBQyxVQUFFLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxlQUFlO0NBQy9DLENBQUM7QUFFRixJQUFNLFlBQVksR0FBRztJQUNuQixNQUFNLEVBQU8sVUFBQyxNQUFNLEVBQUUsQ0FBQyxJQUFLLE9BQUEsTUFBTSxFQUFOLENBQU07SUFDbEMsV0FBVyxFQUFFLFVBQUMsTUFBTSxFQUFFLE1BQU0sSUFBSyxPQUFBLFVBQUUsQ0FBQyxPQUFPLENBQUMsTUFBTSxFQUFFLE1BQU0sQ0FBQyxDQUFDLElBQUksRUFBL0IsQ0FBK0I7Q0FDakUsQ0FBQztBQUlGOzs7Ozs7O0dBT0c7QUFDSCxlQUE4QixFQUE0QixFQUFFLElBQWdDLEVBQUUsR0FBaUI7SUFDN0csSUFBSSxDQUFDO1FBQ0gsR0FBRyxHQUFHLEdBQUcsSUFBSSxFQUFFLENBQUM7UUFDaEIsSUFBTSxPQUFPLEdBQUksR0FBRyxDQUFDLE9BQU8sS0FBSyxTQUFTLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztRQUVoRSxJQUFNLE1BQU0sR0FBVyxHQUFHLENBQUMsTUFBTSxJQUFJLFlBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNuRCxJQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQztRQUMxQyxJQUFNLFFBQVEsR0FBRyxHQUFHLENBQUMsUUFBUSxJQUFJLFlBQUksQ0FBQyxJQUFJLENBQUM7UUFFM0Msd0NBQXdDO1FBQ3hDLEVBQUUsQ0FBQyxDQUFDLFlBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ3hCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLElBQUksQ0FDM0IsVUFBQSxJQUFJLElBQUksT0FBQSxLQUFLLENBQUMsRUFBRSxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLEVBQUUsR0FBRyxDQUFDLEVBQWhDLENBQWdDLENBQ3pDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMxQixDQUFDO1FBRUQsaUNBQWlDO1FBQ2pDLElBQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUM7UUFDMUIsRUFBRSxDQUFDLENBQUMsWUFBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDMUIsTUFBTSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsSUFBSTtnQkFDbEMsR0FBRyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUM5QixNQUFNLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDOUIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsQ0FBQztRQUMzQixDQUFDO1FBRUQsY0FBYztRQUNkLElBQUksTUFBTSxTQUFvQyxDQUFDO1FBQy9DLElBQUksTUFBVSxDQUFDO1FBRWYsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7WUFDakIsTUFBTSxHQUFHLGdDQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQ3BDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLElBQUksR0FBRyxDQUFDLElBQUksS0FBSyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDNUMsT0FBTyxDQUFDLElBQUksQ0FBQyxnREFBOEMsS0FBSyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsaUNBQTRCLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLE1BQUcsQ0FBQyxDQUFDO1lBQ2xJLENBQUM7WUFFRCxNQUFJLEdBQUcsTUFBTSxDQUFDLE9BQWUsQ0FBQztZQUU5QixFQUFFLENBQUMsQ0FBQyxjQUFjLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsTUFBSSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUN0RCxPQUFPLENBQUMsSUFBSSxDQUFDLHlCQUF1QixNQUFJLFNBQUksTUFBTSxDQUFDLE9BQU8scUNBQWdDLEtBQUssQ0FBQyxNQUFJLENBQUMsWUFBTyxPQUFPLENBQUMsTUFBSSxDQUFDLE1BQUcsQ0FBQyxDQUFDO1lBQ2hJLENBQUM7UUFDSCxDQUFDO1FBQUMsSUFBSSxDQUFDLENBQUM7WUFDTixNQUFJLEdBQUcsR0FBRyxDQUFDLElBQUksSUFBSSxNQUFNLENBQUM7UUFDNUIsQ0FBQztRQUVELElBQUksTUFBTSxHQUFXLFlBQVksQ0FBQyxNQUFJLENBQUMsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7UUFFdEQsRUFBRSxDQUFDLENBQUMsTUFBSSxLQUFLLFdBQVcsQ0FBQyxDQUFDLENBQUM7WUFDekIsRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ25CLE1BQU0sR0FBRyxnQ0FBWSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFdEMsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3JELE9BQU8sQ0FBQyxJQUFJLENBQUMsaUNBQStCLE1BQU0sQ0FBQyxPQUFPLGlDQUE0QixPQUFPLENBQUMsSUFBSSxNQUFHLENBQUMsQ0FBQztnQkFDekcsQ0FBQztZQUNILENBQUM7UUFDSCxDQUFDO1FBRUQsOENBQThDO1FBQzlDLElBQU0sR0FBRyxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsRUFBUyxDQUFDLENBQUUsMENBQTBDO2FBQ3pFLE9BQU8sQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDO2FBQzNCLElBQUksQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLGtCQUFrQjtRQUUvQixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztZQUN0QixtREFBbUQ7WUFDbkQsTUFBTSxHQUFHLEdBQUcsQ0FBQyxhQUFhLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDckMsQ0FBQztRQUVELElBQU0sT0FBTyxHQUFHLFlBQUksQ0FBQyxLQUFLLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFFLHNDQUFzQztRQUV2RixJQUFNLE1BQUksR0FBRyxJQUFJLFlBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLEVBQUMsTUFBTSxRQUFBLEVBQUUsUUFBUSxVQUFBLEVBQUUsUUFBUSxVQUFBLEVBQUMsQ0FBQzthQUM5RCxVQUFVLENBQUMsRUFBRSxDQUFDLENBQUM7UUFFbEIsNEVBQTRFO1FBQzVFLEVBQUUsQ0FBQyxDQUFDLE1BQUksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLE1BQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztRQUNmLENBQUM7UUFFRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1lBQ1IsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2QsTUFBSSxDQUFDLEtBQUssQ0FBQyxHQUFHLENBQUMsS0FBSyxDQUFDLENBQUM7WUFDeEIsQ0FBQztZQUNELEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO2dCQUNmLE1BQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxDQUFDO1lBQzFCLENBQUM7WUFDRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztnQkFDaEIsTUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUM7WUFDNUIsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFJLENBQUMsR0FBRyxFQUFFLENBQUM7UUFFWCxFQUFFLENBQUMsQ0FBQyxPQUFPLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztZQUN0QixzQ0FBc0M7WUFDdEMsSUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7aUJBQzNCLElBQUksQ0FBQyxPQUFPLEVBQUUsY0FBYyxDQUFDLENBQUM7WUFFakMsc0JBQXNCO1lBQ3RCLEVBQUUsQ0FBQyxDQUFDLE9BQU8sS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNqRCxJQUFNLEtBQUcsR0FBRyxRQUFRLEtBQUssUUFBUSxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQztnQkFDbEQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7cUJBQ2IsSUFBSSxDQUFDLGVBQWEsS0FBRyxDQUFDLFdBQVcsRUFBSSxDQUFDO3FCQUN0QyxJQUFJLENBQUMsTUFBTSxFQUFFLEdBQUcsQ0FBQztxQkFDakIsSUFBSSxDQUFDLFFBQVEsRUFBRSxRQUFRLENBQUM7cUJBQ3hCLElBQUksQ0FBQyxVQUFVLEVBQUUsbUJBQWlCLEtBQUssQ0FBQztxQkFDeEMsRUFBRSxDQUFDLFdBQVcsRUFBRTtvQkFBQSxpQkFLaEI7b0JBSkMsTUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFHLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBQSxHQUFHO3dCQUMzQixLQUFJLENBQUMsSUFBSSxHQUFJLEdBQUcsQ0FBQztvQkFDbkIsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQUEsS0FBSyxJQUFNLE1BQU0sS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7b0JBQ3BDLEVBQUUsQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQzVCLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztZQUVELDJCQUEyQjtZQUMzQixFQUFFLENBQUMsQ0FBQyxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDakQsSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUM7cUJBQ2IsSUFBSSxDQUFDLGFBQWEsQ0FBQztxQkFDbkIsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUM7cUJBQ2pCLEVBQUUsQ0FBQyxPQUFPLEVBQUU7b0JBQ1gsVUFBVSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxHQUFHLENBQUMsWUFBWSxJQUFJLEVBQUUsRUFBRSxHQUFHLENBQUMsWUFBWSxJQUFJLEVBQUUsQ0FBQyxDQUFDO29CQUMxRixFQUFFLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM1QixDQUFDLENBQUMsQ0FBQztZQUNQLENBQUM7WUFFRCxtQ0FBbUM7WUFDbkMsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2pELElBQU0sV0FBUyxHQUFHLEdBQUcsQ0FBQyxTQUFTLElBQUksZ0NBQWdDLENBQUM7Z0JBQ3BFLElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO3FCQUNiLElBQUksQ0FBQyxxQkFBcUIsQ0FBQztxQkFDM0IsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUM7cUJBQ2pCLEVBQUUsQ0FBQyxPQUFPLEVBQUU7b0JBQ1gsV0FBSSxDQUFDLE1BQU0sRUFBRSxXQUFTLEVBQUU7d0JBQ3RCLElBQUksUUFBQTt3QkFDSixJQUFJLEVBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsSUFBSSxFQUFFLENBQUMsQ0FBQztxQkFDcEMsQ0FBQyxDQUFDO29CQUNILEVBQUUsQ0FBQyxLQUFLLENBQUMsY0FBYyxFQUFFLENBQUM7Z0JBQzVCLENBQUMsQ0FBQyxDQUFDO1lBQ1AsQ0FBQztRQUNILENBQUM7UUFFRCxNQUFNLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBQyxFQUFDLElBQUksUUFBQSxFQUFFLElBQUksTUFBQSxFQUFDLENBQUMsQ0FBQztJQUN2QyxDQUFDO0lBQUMsS0FBSyxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztRQUNiLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxDQUFDO0lBQzdCLENBQUM7QUFDSCxDQUFDO0FBOUlELHdCQThJQztBQUVELG9CQUFvQixNQUFjLEVBQUUsWUFBb0IsRUFBRSxZQUFvQjtJQUM1RSxJQUFNLE1BQU0sR0FBRyxpQkFBZSxZQUFZLDRDQUF1QyxDQUFDO0lBQ2xGLElBQU0sTUFBTSxHQUFHLGtCQUFnQixZQUFZLG1CQUFnQixDQUFDO0lBQzVELElBQU0sR0FBRyxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLENBQUM7SUFDNUIsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLENBQUMsTUFBTSxHQUFHLE1BQU0sR0FBRyxNQUFNLENBQUMsQ0FBQztJQUM3QyxHQUFHLENBQUMsUUFBUSxDQUFDLEtBQUssR0FBRyxrQkFBa0IsQ0FBQztBQUMxQyxDQUFDIn0= \ No newline at end of file diff --git a/build/index.d.ts b/build/index.d.ts new file mode 100644 index 00000000..03286194 --- /dev/null +++ b/build/index.d.ts @@ -0,0 +1,7 @@ +import embed from './embed'; +declare const embedModule: typeof embed & { + default?: typeof embed; + vega?; + vl?; +}; +export = embedModule; diff --git a/build/index.js b/build/index.js new file mode 100644 index 00000000..6783682e --- /dev/null +++ b/build/index.js @@ -0,0 +1,11 @@ +"use strict"; +var vega = require("vega-lib"); +var vl = require("vega-lite"); +var embed_1 = require("./embed"); +var embedModule = embed_1.default; +embedModule.default = embed_1.default; +// expose Vega and Vega-Lite libs +embedModule.vega = vega; +embedModule.vl = vl; +module.exports = embedModule; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQUFBLCtCQUFpQztBQUNqQyw4QkFBZ0M7QUFFaEMsaUNBQTRCO0FBRTVCLElBQU0sV0FBVyxHQUF3RCxlQUFLLENBQUM7QUFFL0UsV0FBVyxDQUFDLE9BQU8sR0FBRyxlQUFLLENBQUM7QUFFNUIsaUNBQWlDO0FBQ2pDLFdBQVcsQ0FBQyxJQUFJLEdBQUcsSUFBSSxDQUFDO0FBQ3hCLFdBQVcsQ0FBQyxFQUFFLEdBQUcsRUFBRSxDQUFDO0FBRXBCLGlCQUFTLFdBQVcsQ0FBQyJ9 \ No newline at end of file diff --git a/build/post.d.ts b/build/post.d.ts new file mode 100644 index 00000000..7431e9a1 --- /dev/null +++ b/build/post.d.ts @@ -0,0 +1,4 @@ +/** + * Open editor url in a new window, and pass a message. + */ +export declare function post(window: Window, url: string, data: any): void; diff --git a/build/post.js b/build/post.js new file mode 100644 index 00000000..f867d955 --- /dev/null +++ b/build/post.js @@ -0,0 +1,31 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Open editor url in a new window, and pass a message. + */ +function post(window, url, data) { + var editor = window.open(url); + var wait = 10000; + var step = 250; + var count = ~~(wait / step); + function listen(evt) { + if (evt.source === editor) { + count = 0; + window.removeEventListener('message', listen, false); + } + } + window.addEventListener('message', listen, false); + // send message + // periodically resend until ack received or timeout + function send() { + if (count <= 0) { + return; + } + editor.postMessage(data, '*'); + setTimeout(send, step); + count -= 1; + } + setTimeout(send, step); +} +exports.post = post; +//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicG9zdC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3NyYy9wb3N0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7O0FBQUE7O0dBRUc7QUFDSCxjQUFxQixNQUFjLEVBQUUsR0FBVyxFQUFFLElBQVM7SUFDekQsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUM7SUFDbkIsSUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztJQUU1QixnQkFBZ0IsR0FBRztRQUNqQixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDMUIsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNWLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3ZELENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFbEQsZUFBZTtJQUNmLG9EQUFvRDtJQUNwRDtRQUNFLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2YsTUFBTSxDQUFDO1FBQ1QsQ0FBQztRQUNELE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkIsS0FBSyxJQUFJLENBQUMsQ0FBQztJQUNiLENBQUM7SUFDRCxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUF6QkQsb0JBeUJDIn0= \ No newline at end of file diff --git a/build/vega-embed.js b/build/vega-embed.js new file mode 100644 index 00000000..02d705d7 --- /dev/null +++ b/build/vega-embed.js @@ -0,0 +1,37884 @@ +(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.vegaEmbed = f()}})(function(){var define,module,exports;return (function(){function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o n2) return 1; + if (n2 > n1) return -1; + } + + if ([s1[2], s2[2]].every(patch.test.bind(patch))) { + var p1 = patch.exec(s1[2])[1].split('.').map(tryParse); + var p2 = patch.exec(s2[2])[1].split('.').map(tryParse); + + for (i = 0; i < Math.max(p1.length, p2.length); i++) { + if (p1[i] === undefined || typeof p2[i] === 'string' && typeof p1[i] === 'number') return -1; + if (p2[i] === undefined || typeof p1[i] === 'string' && typeof p2[i] === 'number') return 1; + + if (p1[i] > p2[i]) return 1; + if (p2[i] > p1[i]) return -1; + } + } else if ([s1[2], s2[2]].some(patch.test.bind(patch))) { + return patch.test(s1[2]) ? -1 : 1; + } + + return 0; + }; + +})); + +},{}],3:[function(require,module,exports){ +// https://d3js.org/d3-selection/ Version 1.3.0. Copyright 2018 Mike Bostock. +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.d3 = global.d3 || {}))); +}(this, (function (exports) { 'use strict'; + +var xhtml = "http://www.w3.org/1999/xhtml"; + +var namespaces = { + svg: "http://www.w3.org/2000/svg", + xhtml: xhtml, + xlink: "http://www.w3.org/1999/xlink", + xml: "http://www.w3.org/XML/1998/namespace", + xmlns: "http://www.w3.org/2000/xmlns/" +}; + +function namespace(name) { + var prefix = name += "", i = prefix.indexOf(":"); + if (i >= 0 && (prefix = name.slice(0, i)) !== "xmlns") name = name.slice(i + 1); + return namespaces.hasOwnProperty(prefix) ? {space: namespaces[prefix], local: name} : name; +} + +function creatorInherit(name) { + return function() { + var document = this.ownerDocument, + uri = this.namespaceURI; + return uri === xhtml && document.documentElement.namespaceURI === xhtml + ? document.createElement(name) + : document.createElementNS(uri, name); + }; +} + +function creatorFixed(fullname) { + return function() { + return this.ownerDocument.createElementNS(fullname.space, fullname.local); + }; +} + +function creator(name) { + var fullname = namespace(name); + return (fullname.local + ? creatorFixed + : creatorInherit)(fullname); +} + +function none() {} + +function selector(selector) { + return selector == null ? none : function() { + return this.querySelector(selector); + }; +} + +function selection_select(select) { + if (typeof select !== "function") select = selector(select); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = new Array(n), node, subnode, i = 0; i < n; ++i) { + if ((node = group[i]) && (subnode = select.call(node, node.__data__, i, group))) { + if ("__data__" in node) subnode.__data__ = node.__data__; + subgroup[i] = subnode; + } + } + } + + return new Selection(subgroups, this._parents); +} + +function empty() { + return []; +} + +function selectorAll(selector) { + return selector == null ? empty : function() { + return this.querySelectorAll(selector); + }; +} + +function selection_selectAll(select) { + if (typeof select !== "function") select = selectorAll(select); + + for (var groups = this._groups, m = groups.length, subgroups = [], parents = [], j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, node, i = 0; i < n; ++i) { + if (node = group[i]) { + subgroups.push(select.call(node, node.__data__, i, group)); + parents.push(node); + } + } + } + + return new Selection(subgroups, parents); +} + +var matcher = function(selector) { + return function() { + return this.matches(selector); + }; +}; + +if (typeof document !== "undefined") { + var element = document.documentElement; + if (!element.matches) { + var vendorMatches = element.webkitMatchesSelector + || element.msMatchesSelector + || element.mozMatchesSelector + || element.oMatchesSelector; + matcher = function(selector) { + return function() { + return vendorMatches.call(this, selector); + }; + }; + } +} + +var matcher$1 = matcher; + +function selection_filter(match) { + if (typeof match !== "function") match = matcher$1(match); + + for (var groups = this._groups, m = groups.length, subgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, subgroup = subgroups[j] = [], node, i = 0; i < n; ++i) { + if ((node = group[i]) && match.call(node, node.__data__, i, group)) { + subgroup.push(node); + } + } + } + + return new Selection(subgroups, this._parents); +} + +function sparse(update) { + return new Array(update.length); +} + +function selection_enter() { + return new Selection(this._enter || this._groups.map(sparse), this._parents); +} + +function EnterNode(parent, datum) { + this.ownerDocument = parent.ownerDocument; + this.namespaceURI = parent.namespaceURI; + this._next = null; + this._parent = parent; + this.__data__ = datum; +} + +EnterNode.prototype = { + constructor: EnterNode, + appendChild: function(child) { return this._parent.insertBefore(child, this._next); }, + insertBefore: function(child, next) { return this._parent.insertBefore(child, next); }, + querySelector: function(selector) { return this._parent.querySelector(selector); }, + querySelectorAll: function(selector) { return this._parent.querySelectorAll(selector); } +}; + +function constant(x) { + return function() { + return x; + }; +} + +var keyPrefix = "$"; // Protect against keys like “__proto__”. + +function bindIndex(parent, group, enter, update, exit, data) { + var i = 0, + node, + groupLength = group.length, + dataLength = data.length; + + // Put any non-null nodes that fit into update. + // Put any null nodes into enter. + // Put any remaining data into enter. + for (; i < dataLength; ++i) { + if (node = group[i]) { + node.__data__ = data[i]; + update[i] = node; + } else { + enter[i] = new EnterNode(parent, data[i]); + } + } + + // Put any non-null nodes that don’t fit into exit. + for (; i < groupLength; ++i) { + if (node = group[i]) { + exit[i] = node; + } + } +} + +function bindKey(parent, group, enter, update, exit, data, key) { + var i, + node, + nodeByKeyValue = {}, + groupLength = group.length, + dataLength = data.length, + keyValues = new Array(groupLength), + keyValue; + + // Compute the key for each node. + // If multiple nodes have the same key, the duplicates are added to exit. + for (i = 0; i < groupLength; ++i) { + if (node = group[i]) { + keyValues[i] = keyValue = keyPrefix + key.call(node, node.__data__, i, group); + if (keyValue in nodeByKeyValue) { + exit[i] = node; + } else { + nodeByKeyValue[keyValue] = node; + } + } + } + + // Compute the key for each datum. + // If there a node associated with this key, join and add it to update. + // If there is not (or the key is a duplicate), add it to enter. + for (i = 0; i < dataLength; ++i) { + keyValue = keyPrefix + key.call(parent, data[i], i, data); + if (node = nodeByKeyValue[keyValue]) { + update[i] = node; + node.__data__ = data[i]; + nodeByKeyValue[keyValue] = null; + } else { + enter[i] = new EnterNode(parent, data[i]); + } + } + + // Add any remaining nodes that were not bound to data to exit. + for (i = 0; i < groupLength; ++i) { + if ((node = group[i]) && (nodeByKeyValue[keyValues[i]] === node)) { + exit[i] = node; + } + } +} + +function selection_data(value, key) { + if (!value) { + data = new Array(this.size()), j = -1; + this.each(function(d) { data[++j] = d; }); + return data; + } + + var bind = key ? bindKey : bindIndex, + parents = this._parents, + groups = this._groups; + + if (typeof value !== "function") value = constant(value); + + for (var m = groups.length, update = new Array(m), enter = new Array(m), exit = new Array(m), j = 0; j < m; ++j) { + var parent = parents[j], + group = groups[j], + groupLength = group.length, + data = value.call(parent, parent && parent.__data__, j, parents), + dataLength = data.length, + enterGroup = enter[j] = new Array(dataLength), + updateGroup = update[j] = new Array(dataLength), + exitGroup = exit[j] = new Array(groupLength); + + bind(parent, group, enterGroup, updateGroup, exitGroup, data, key); + + // Now connect the enter nodes to their following update node, such that + // appendChild can insert the materialized enter node before this node, + // rather than at the end of the parent node. + for (var i0 = 0, i1 = 0, previous, next; i0 < dataLength; ++i0) { + if (previous = enterGroup[i0]) { + if (i0 >= i1) i1 = i0 + 1; + while (!(next = updateGroup[i1]) && ++i1 < dataLength); + previous._next = next || null; + } + } + } + + update = new Selection(update, parents); + update._enter = enter; + update._exit = exit; + return update; +} + +function selection_exit() { + return new Selection(this._exit || this._groups.map(sparse), this._parents); +} + +function selection_merge(selection$$1) { + + for (var groups0 = this._groups, groups1 = selection$$1._groups, m0 = groups0.length, m1 = groups1.length, m = Math.min(m0, m1), merges = new Array(m0), j = 0; j < m; ++j) { + for (var group0 = groups0[j], group1 = groups1[j], n = group0.length, merge = merges[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group0[i] || group1[i]) { + merge[i] = node; + } + } + } + + for (; j < m0; ++j) { + merges[j] = groups0[j]; + } + + return new Selection(merges, this._parents); +} + +function selection_order() { + + for (var groups = this._groups, j = -1, m = groups.length; ++j < m;) { + for (var group = groups[j], i = group.length - 1, next = group[i], node; --i >= 0;) { + if (node = group[i]) { + if (next && next !== node.nextSibling) next.parentNode.insertBefore(node, next); + next = node; + } + } + } + + return this; +} + +function selection_sort(compare) { + if (!compare) compare = ascending; + + function compareNode(a, b) { + return a && b ? compare(a.__data__, b.__data__) : !a - !b; + } + + for (var groups = this._groups, m = groups.length, sortgroups = new Array(m), j = 0; j < m; ++j) { + for (var group = groups[j], n = group.length, sortgroup = sortgroups[j] = new Array(n), node, i = 0; i < n; ++i) { + if (node = group[i]) { + sortgroup[i] = node; + } + } + sortgroup.sort(compareNode); + } + + return new Selection(sortgroups, this._parents).order(); +} + +function ascending(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +} + +function selection_call() { + var callback = arguments[0]; + arguments[0] = this; + callback.apply(null, arguments); + return this; +} + +function selection_nodes() { + var nodes = new Array(this.size()), i = -1; + this.each(function() { nodes[++i] = this; }); + return nodes; +} + +function selection_node() { + + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length; i < n; ++i) { + var node = group[i]; + if (node) return node; + } + } + + return null; +} + +function selection_size() { + var size = 0; + this.each(function() { ++size; }); + return size; +} + +function selection_empty() { + return !this.node(); +} + +function selection_each(callback) { + + for (var groups = this._groups, j = 0, m = groups.length; j < m; ++j) { + for (var group = groups[j], i = 0, n = group.length, node; i < n; ++i) { + if (node = group[i]) callback.call(node, node.__data__, i, group); + } + } + + return this; +} + +function attrRemove(name) { + return function() { + this.removeAttribute(name); + }; +} + +function attrRemoveNS(fullname) { + return function() { + this.removeAttributeNS(fullname.space, fullname.local); + }; +} + +function attrConstant(name, value) { + return function() { + this.setAttribute(name, value); + }; +} + +function attrConstantNS(fullname, value) { + return function() { + this.setAttributeNS(fullname.space, fullname.local, value); + }; +} + +function attrFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttribute(name); + else this.setAttribute(name, v); + }; +} + +function attrFunctionNS(fullname, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.removeAttributeNS(fullname.space, fullname.local); + else this.setAttributeNS(fullname.space, fullname.local, v); + }; +} + +function selection_attr(name, value) { + var fullname = namespace(name); + + if (arguments.length < 2) { + var node = this.node(); + return fullname.local + ? node.getAttributeNS(fullname.space, fullname.local) + : node.getAttribute(fullname); + } + + return this.each((value == null + ? (fullname.local ? attrRemoveNS : attrRemove) : (typeof value === "function" + ? (fullname.local ? attrFunctionNS : attrFunction) + : (fullname.local ? attrConstantNS : attrConstant)))(fullname, value)); +} + +function defaultView(node) { + return (node.ownerDocument && node.ownerDocument.defaultView) // node is a Node + || (node.document && node) // node is a Window + || node.defaultView; // node is a Document +} + +function styleRemove(name) { + return function() { + this.style.removeProperty(name); + }; +} + +function styleConstant(name, value, priority) { + return function() { + this.style.setProperty(name, value, priority); + }; +} + +function styleFunction(name, value, priority) { + return function() { + var v = value.apply(this, arguments); + if (v == null) this.style.removeProperty(name); + else this.style.setProperty(name, v, priority); + }; +} + +function selection_style(name, value, priority) { + return arguments.length > 1 + ? this.each((value == null + ? styleRemove : typeof value === "function" + ? styleFunction + : styleConstant)(name, value, priority == null ? "" : priority)) + : styleValue(this.node(), name); +} + +function styleValue(node, name) { + return node.style.getPropertyValue(name) + || defaultView(node).getComputedStyle(node, null).getPropertyValue(name); +} + +function propertyRemove(name) { + return function() { + delete this[name]; + }; +} + +function propertyConstant(name, value) { + return function() { + this[name] = value; + }; +} + +function propertyFunction(name, value) { + return function() { + var v = value.apply(this, arguments); + if (v == null) delete this[name]; + else this[name] = v; + }; +} + +function selection_property(name, value) { + return arguments.length > 1 + ? this.each((value == null + ? propertyRemove : typeof value === "function" + ? propertyFunction + : propertyConstant)(name, value)) + : this.node()[name]; +} + +function classArray(string) { + return string.trim().split(/^|\s+/); +} + +function classList(node) { + return node.classList || new ClassList(node); +} + +function ClassList(node) { + this._node = node; + this._names = classArray(node.getAttribute("class") || ""); +} + +ClassList.prototype = { + add: function(name) { + var i = this._names.indexOf(name); + if (i < 0) { + this._names.push(name); + this._node.setAttribute("class", this._names.join(" ")); + } + }, + remove: function(name) { + var i = this._names.indexOf(name); + if (i >= 0) { + this._names.splice(i, 1); + this._node.setAttribute("class", this._names.join(" ")); + } + }, + contains: function(name) { + return this._names.indexOf(name) >= 0; + } +}; + +function classedAdd(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.add(names[i]); +} + +function classedRemove(node, names) { + var list = classList(node), i = -1, n = names.length; + while (++i < n) list.remove(names[i]); +} + +function classedTrue(names) { + return function() { + classedAdd(this, names); + }; +} + +function classedFalse(names) { + return function() { + classedRemove(this, names); + }; +} + +function classedFunction(names, value) { + return function() { + (value.apply(this, arguments) ? classedAdd : classedRemove)(this, names); + }; +} + +function selection_classed(name, value) { + var names = classArray(name + ""); + + if (arguments.length < 2) { + var list = classList(this.node()), i = -1, n = names.length; + while (++i < n) if (!list.contains(names[i])) return false; + return true; + } + + return this.each((typeof value === "function" + ? classedFunction : value + ? classedTrue + : classedFalse)(names, value)); +} + +function textRemove() { + this.textContent = ""; +} + +function textConstant(value) { + return function() { + this.textContent = value; + }; +} + +function textFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.textContent = v == null ? "" : v; + }; +} + +function selection_text(value) { + return arguments.length + ? this.each(value == null + ? textRemove : (typeof value === "function" + ? textFunction + : textConstant)(value)) + : this.node().textContent; +} + +function htmlRemove() { + this.innerHTML = ""; +} + +function htmlConstant(value) { + return function() { + this.innerHTML = value; + }; +} + +function htmlFunction(value) { + return function() { + var v = value.apply(this, arguments); + this.innerHTML = v == null ? "" : v; + }; +} + +function selection_html(value) { + return arguments.length + ? this.each(value == null + ? htmlRemove : (typeof value === "function" + ? htmlFunction + : htmlConstant)(value)) + : this.node().innerHTML; +} + +function raise() { + if (this.nextSibling) this.parentNode.appendChild(this); +} + +function selection_raise() { + return this.each(raise); +} + +function lower() { + if (this.previousSibling) this.parentNode.insertBefore(this, this.parentNode.firstChild); +} + +function selection_lower() { + return this.each(lower); +} + +function selection_append(name) { + var create = typeof name === "function" ? name : creator(name); + return this.select(function() { + return this.appendChild(create.apply(this, arguments)); + }); +} + +function constantNull() { + return null; +} + +function selection_insert(name, before) { + var create = typeof name === "function" ? name : creator(name), + select = before == null ? constantNull : typeof before === "function" ? before : selector(before); + return this.select(function() { + return this.insertBefore(create.apply(this, arguments), select.apply(this, arguments) || null); + }); +} + +function remove() { + var parent = this.parentNode; + if (parent) parent.removeChild(this); +} + +function selection_remove() { + return this.each(remove); +} + +function selection_cloneShallow() { + return this.parentNode.insertBefore(this.cloneNode(false), this.nextSibling); +} + +function selection_cloneDeep() { + return this.parentNode.insertBefore(this.cloneNode(true), this.nextSibling); +} + +function selection_clone(deep) { + return this.select(deep ? selection_cloneDeep : selection_cloneShallow); +} + +function selection_datum(value) { + return arguments.length + ? this.property("__data__", value) + : this.node().__data__; +} + +var filterEvents = {}; + +exports.event = null; + +if (typeof document !== "undefined") { + var element$1 = document.documentElement; + if (!("onmouseenter" in element$1)) { + filterEvents = {mouseenter: "mouseover", mouseleave: "mouseout"}; + } +} + +function filterContextListener(listener, index, group) { + listener = contextListener(listener, index, group); + return function(event) { + var related = event.relatedTarget; + if (!related || (related !== this && !(related.compareDocumentPosition(this) & 8))) { + listener.call(this, event); + } + }; +} + +function contextListener(listener, index, group) { + return function(event1) { + var event0 = exports.event; // Events can be reentrant (e.g., focus). + exports.event = event1; + try { + listener.call(this, this.__data__, index, group); + } finally { + exports.event = event0; + } + }; +} + +function parseTypenames(typenames) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + return {type: t, name: name}; + }); +} + +function onRemove(typename) { + return function() { + var on = this.__on; + if (!on) return; + for (var j = 0, i = -1, m = on.length, o; j < m; ++j) { + if (o = on[j], (!typename.type || o.type === typename.type) && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.capture); + } else { + on[++i] = o; + } + } + if (++i) on.length = i; + else delete this.__on; + }; +} + +function onAdd(typename, value, capture) { + var wrap = filterEvents.hasOwnProperty(typename.type) ? filterContextListener : contextListener; + return function(d, i, group) { + var on = this.__on, o, listener = wrap(value, i, group); + if (on) for (var j = 0, m = on.length; j < m; ++j) { + if ((o = on[j]).type === typename.type && o.name === typename.name) { + this.removeEventListener(o.type, o.listener, o.capture); + this.addEventListener(o.type, o.listener = listener, o.capture = capture); + o.value = value; + return; + } + } + this.addEventListener(typename.type, listener, capture); + o = {type: typename.type, name: typename.name, value: value, listener: listener, capture: capture}; + if (!on) this.__on = [o]; + else on.push(o); + }; +} + +function selection_on(typename, value, capture) { + var typenames = parseTypenames(typename + ""), i, n = typenames.length, t; + + if (arguments.length < 2) { + var on = this.node().__on; + if (on) for (var j = 0, m = on.length, o; j < m; ++j) { + for (i = 0, o = on[j]; i < n; ++i) { + if ((t = typenames[i]).type === o.type && t.name === o.name) { + return o.value; + } + } + } + return; + } + + on = value ? onAdd : onRemove; + if (capture == null) capture = false; + for (i = 0; i < n; ++i) this.each(on(typenames[i], value, capture)); + return this; +} + +function customEvent(event1, listener, that, args) { + var event0 = exports.event; + event1.sourceEvent = exports.event; + exports.event = event1; + try { + return listener.apply(that, args); + } finally { + exports.event = event0; + } +} + +function dispatchEvent(node, type, params) { + var window = defaultView(node), + event = window.CustomEvent; + + if (typeof event === "function") { + event = new event(type, params); + } else { + event = window.document.createEvent("Event"); + if (params) event.initEvent(type, params.bubbles, params.cancelable), event.detail = params.detail; + else event.initEvent(type, false, false); + } + + node.dispatchEvent(event); +} + +function dispatchConstant(type, params) { + return function() { + return dispatchEvent(this, type, params); + }; +} + +function dispatchFunction(type, params) { + return function() { + return dispatchEvent(this, type, params.apply(this, arguments)); + }; +} + +function selection_dispatch(type, params) { + return this.each((typeof params === "function" + ? dispatchFunction + : dispatchConstant)(type, params)); +} + +var root = [null]; + +function Selection(groups, parents) { + this._groups = groups; + this._parents = parents; +} + +function selection() { + return new Selection([[document.documentElement]], root); +} + +Selection.prototype = selection.prototype = { + constructor: Selection, + select: selection_select, + selectAll: selection_selectAll, + filter: selection_filter, + data: selection_data, + enter: selection_enter, + exit: selection_exit, + merge: selection_merge, + order: selection_order, + sort: selection_sort, + call: selection_call, + nodes: selection_nodes, + node: selection_node, + size: selection_size, + empty: selection_empty, + each: selection_each, + attr: selection_attr, + style: selection_style, + property: selection_property, + classed: selection_classed, + text: selection_text, + html: selection_html, + raise: selection_raise, + lower: selection_lower, + append: selection_append, + insert: selection_insert, + remove: selection_remove, + clone: selection_clone, + datum: selection_datum, + on: selection_on, + dispatch: selection_dispatch +}; + +function select(selector) { + return typeof selector === "string" + ? new Selection([[document.querySelector(selector)]], [document.documentElement]) + : new Selection([[selector]], root); +} + +function create(name) { + return select(creator(name).call(document.documentElement)); +} + +var nextId = 0; + +function local() { + return new Local; +} + +function Local() { + this._ = "@" + (++nextId).toString(36); +} + +Local.prototype = local.prototype = { + constructor: Local, + get: function(node) { + var id = this._; + while (!(id in node)) if (!(node = node.parentNode)) return; + return node[id]; + }, + set: function(node, value) { + return node[this._] = value; + }, + remove: function(node) { + return this._ in node && delete node[this._]; + }, + toString: function() { + return this._; + } +}; + +function sourceEvent() { + var current = exports.event, source; + while (source = current.sourceEvent) current = source; + return current; +} + +function point(node, event) { + var svg = node.ownerSVGElement || node; + + if (svg.createSVGPoint) { + var point = svg.createSVGPoint(); + point.x = event.clientX, point.y = event.clientY; + point = point.matrixTransform(node.getScreenCTM().inverse()); + return [point.x, point.y]; + } + + var rect = node.getBoundingClientRect(); + return [event.clientX - rect.left - node.clientLeft, event.clientY - rect.top - node.clientTop]; +} + +function mouse(node) { + var event = sourceEvent(); + if (event.changedTouches) event = event.changedTouches[0]; + return point(node, event); +} + +function selectAll(selector) { + return typeof selector === "string" + ? new Selection([document.querySelectorAll(selector)], [document.documentElement]) + : new Selection([selector == null ? [] : selector], root); +} + +function touch(node, touches, identifier) { + if (arguments.length < 3) identifier = touches, touches = sourceEvent().changedTouches; + + for (var i = 0, n = touches ? touches.length : 0, touch; i < n; ++i) { + if ((touch = touches[i]).identifier === identifier) { + return point(node, touch); + } + } + + return null; +} + +function touches(node, touches) { + if (touches == null) touches = sourceEvent().touches; + + for (var i = 0, n = touches ? touches.length : 0, points = new Array(n); i < n; ++i) { + points[i] = point(node, touches[i]); + } + + return points; +} + +exports.create = create; +exports.creator = creator; +exports.local = local; +exports.matcher = matcher$1; +exports.mouse = mouse; +exports.namespace = namespace; +exports.namespaces = namespaces; +exports.clientPoint = point; +exports.select = select; +exports.selectAll = selectAll; +exports.selection = selection; +exports.selector = selector; +exports.selectorAll = selectorAll; +exports.style = styleValue; +exports.touch = touch; +exports.touches = touches; +exports.window = defaultView; +exports.customEvent = customEvent; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); + +},{}],4:[function(require,module,exports){ +(function (Buffer){ +(function (global, factory) { + typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.vega = global.vega || {}))); +}(this, (function (exports) { 'use strict'; + +var accessor = function(fn, fields, name) { + fn.fields = fields || []; + fn.fname = name; + return fn; +}; + +function accessorName(fn) { + return fn == null ? null : fn.fname; +} + +function accessorFields(fn) { + return fn == null ? null : fn.fields; +} + +var error$1 = function(message) { + throw Error(message); +}; + +var splitAccessPath = function(p) { + var path = [], + q = null, + b = 0, + n = p.length, + s = '', + i, j, c; + + p = p + ''; + + function push() { + path.push(s + p.substring(i, j)); + s = ''; + i = j + 1; + } + + for (i=j=0; j i) { + push(); + } else { + i = j + 1; + } + } else if (c === '[') { + if (j > i) push(); + b = i = j + 1; + } else if (c === ']') { + if (!b) error$1('Access path missing open bracket: ' + p); + if (b > 0) push(); + b = 0; + i = j + 1; + } + } + + if (b) error$1('Access path missing closing bracket: ' + p); + if (q) error$1('Access path missing closing quote: ' + p); + + if (j > i) { + j++; + push(); + } + + return path; +}; + +var isArray = Array.isArray; + +var isObject = function(_) { + return _ === Object(_); +}; + +var isString = function(_) { + return typeof _ === 'string'; +}; + +function $(x) { + return isArray(x) ? '[' + x.map($) + ']' + : isObject(x) || isString(x) ? + // Output valid JSON and JS source strings. + // See http://timelessrepo.com/json-isnt-a-javascript-subset + JSON.stringify(x).replace('\u2028','\\u2028').replace('\u2029', '\\u2029') + : x; +} + +var field = function(field, name) { + var path = splitAccessPath(field), + code = 'return _[' + path.map($).join('][') + '];'; + + return accessor( + Function('_', code), + [(field = path.length===1 ? path[0] : field)], + name || field + ); +}; + +var empty = []; + +var id = field('id'); + +var identity = accessor(function(_) { return _; }, empty, 'identity'); + +var zero = accessor(function() { return 0; }, empty, 'zero'); + +var one = accessor(function() { return 1; }, empty, 'one'); + +var truthy = accessor(function() { return true; }, empty, 'true'); + +var falsy = accessor(function() { return false; }, empty, 'false'); + +function log(method, level, input) { + var args = [level].concat([].slice.call(input)); + console[method].apply(console, args); // eslint-disable-line no-console +} + +var None = 0; +var Error$1 = 1; +var Warn = 2; +var Info = 3; +var Debug = 4; + +var logger = function(_) { + var level = _ || None; + return { + level: function(_) { + if (arguments.length) { + level = +_; + return this; + } else { + return level; + } + }, + error: function() { + if (level >= Error$1) log('error', 'ERROR', arguments); + return this; + }, + warn: function() { + if (level >= Warn) log('warn', 'WARN', arguments); + return this; + }, + info: function() { + if (level >= Info) log('log', 'INFO', arguments); + return this; + }, + debug: function() { + if (level >= Debug) log('log', 'DEBUG', arguments); + return this; + } + } +}; + +var peek = function(array) { + return array[array.length - 1]; +}; + +var toNumber = function(_) { + return _ == null || _ === '' ? null : +_; +}; + +function exp(sign) { + return function(x) { return sign * Math.exp(x); }; +} + +function log$1(sign) { + return function(x) { return Math.log(sign * x); }; +} + +function pow(exponent) { + return function(x) { + return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); + }; +} + +function pan(domain, delta, lift, ground) { + var d0 = lift(domain[0]), + d1 = lift(peek(domain)), + dd = (d1 - d0) * delta; + + return [ + ground(d0 - dd), + ground(d1 - dd) + ]; +} + +function panLinear(domain, delta) { + return pan(domain, delta, toNumber, identity); +} + +function panLog(domain, delta) { + var sign = Math.sign(domain[0]); + return pan(domain, delta, log$1(sign), exp(sign)); +} + +function panPow(domain, delta, exponent) { + return pan(domain, delta, pow(exponent), pow(1/exponent)); +} + +function zoom(domain, anchor, scale, lift, ground) { + var d0 = lift(domain[0]), + d1 = lift(peek(domain)), + da = anchor != null ? lift(anchor) : (d0 + d1) / 2; + + return [ + ground(da + (d0 - da) * scale), + ground(da + (d1 - da) * scale) + ]; +} + +function zoomLinear(domain, anchor, scale) { + return zoom(domain, anchor, scale, toNumber, identity); +} + +function zoomLog(domain, anchor, scale) { + var sign = Math.sign(domain[0]); + return zoom(domain, anchor, scale, log$1(sign), exp(sign)); +} + +function zoomPow(domain, anchor, scale, exponent) { + return zoom(domain, anchor, scale, pow(exponent), pow(1/exponent)); +} + +var array = function(_) { + return _ != null ? (isArray(_) ? _ : [_]) : []; +}; + +var isFunction = function(_) { + return typeof _ === 'function'; +}; + +var compare = function(fields, orders) { + var idx = [], + cmp = (fields = array(fields)).map(function(f, i) { + if (f == null) { + return null; + } else { + idx.push(i); + return isFunction(f) ? f + : splitAccessPath(f).map($).join(']['); + } + }), + n = idx.length - 1, + ord = array(orders), + code = 'var u,v;return ', + i, j, f, u, v, d, t, lt, gt; + + if (n < 0) return null; + + for (j=0; j<=n; ++j) { + i = idx[j]; + f = cmp[i]; + + if (isFunction(f)) { + d = 'f' + i; + u = '(u=this.' + d + '(a))'; + v = '(v=this.' + d + '(b))'; + (t = t || {})[d] = f; + } else { + u = '(u=a['+f+'])'; + v = '(v=b['+f+'])'; + } + + d = '((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))'; + + if (ord[i] !== 'descending') { + gt = 1; + lt = -1; + } else { + gt = -1; + lt = 1; + } + + code += '(' + u+'<'+v+'||u==null)&&v!=null?' + lt + + ':(u>v||v==null)&&u!=null?' + gt + + ':'+d+'!==u&&v===v?' + lt + + ':v!==v&&u===u?' + gt + + (i < n ? ':' : ':0'); + } + + f = Function('a', 'b', code + ';'); + if (t) f = f.bind(t); + + fields = fields.reduce(function(map, field) { + if (isFunction(field)) { + (accessorFields(field) || []).forEach(function(_) { map[_] = 1; }); + } else if (field != null) { + map[field + ''] = 1; + } + return map; + }, {}); + + return accessor(f, Object.keys(fields)); +}; + +var constant = function(_) { + return isFunction(_) ? _ : function() { return _; }; +}; + +var debounce = function(delay, handler) { + var tid, evt; + + function callback() { + handler(evt); + tid = evt = null; + } + + return function(e) { + evt = e; + if (tid) clearTimeout(tid); + tid = setTimeout(callback, delay); + }; +}; + +var extend = function(_) { + for (var x, k, i=1, len=arguments.length; i= b) { + a = c = b; + break; + } + } + u = v = i; + while (++i < n) { + b = array[i]; + if (b != null) { + if (a > b) { + a = b; + u = i; + } + if (c < b) { + c = b; + v = i; + } + } + } + } else { + while (++i < n) { + b = f(array[i], i, array); + if (b != null && b >= b) { + a = c = b; + break; + } + } + u = v = i; + while (++i < n) { + b = f(array[i], i, array); + if (b != null) { + if (a > b) { + a = b; + u = i; + } + if (c < b) { + c = b; + v = i; + } + } + } + } + + return [u, v]; +}; + +var NULL = {}; + +var fastmap = function(input) { + var obj = {}, + map, + test; + + function has(key) { + return obj.hasOwnProperty(key) && obj[key] !== NULL; + } + + map = { + size: 0, + empty: 0, + object: obj, + has: has, + get: function(key) { + return has(key) ? obj[key] : undefined; + }, + set: function(key, value) { + if (!has(key)) { + ++map.size; + if (obj[key] === NULL) --map.empty; + } + obj[key] = value; + return this; + }, + delete: function(key) { + if (has(key)) { + --map.size; + ++map.empty; + obj[key] = NULL; + } + return this; + }, + clear: function() { + map.size = map.empty = 0; + map.object = obj = {}; + }, + test: function(_) { + if (arguments.length) { + test = _; + return map; + } else { + return test; + } + }, + clean: function() { + var next = {}, + size = 0, + key, value; + for (key in obj) { + value = obj[key]; + if (value !== NULL && (!test || !test(value))) { + next[key] = value; + ++size; + } + } + map.size = size; + map.empty = 0; + map.object = (obj = next); + } + }; + + if (input) Object.keys(input).forEach(function(key) { + map.set(key, input[key]); + }); + + return map; +}; + +var inherits = function(child, parent) { + var proto = (child.prototype = Object.create(parent.prototype)); + proto.constructor = child; + return proto; +}; + +var isBoolean = function(_) { + return typeof _ === 'boolean'; +}; + +var isDate = function(_) { + return Object.prototype.toString.call(_) === '[object Date]'; +}; + +var isNumber = function(_) { + return typeof _ === 'number'; +}; + +var isRegExp = function(_) { + return Object.prototype.toString.call(_) === '[object RegExp]'; +}; + +var key = function(fields, flat) { + if (fields) { + fields = flat + ? array(fields).map(function(f) { return f.replace(/\\(.)/g, '$1'); }) + : array(fields); + } + + var fn = !(fields && fields.length) + ? function() { return ''; } + : Function('_', 'return \'\'+' + + fields.map(function(f) { + return '_[' + (flat + ? $(f) + : splitAccessPath(f).map($).join('][') + ) + ']'; + }).join('+\'|\'+') + ';'); + + return accessor(fn, fields, 'key'); +}; + +var merge = function(compare, array0, array1, output) { + var n0 = array0.length, + n1 = array1.length; + + if (!n1) return array0; + if (!n0) return array1; + + var merged = output || new array0.constructor(n0 + n1), + i0 = 0, i1 = 0, i = 0; + + for (; i0 0 + ? array1[i1++] + : array0[i0++]; + } + + for (; i0= 0) s += str; + return s; +}; + +var pad = function(str, length, padchar, align) { + var c = padchar || ' ', + s = str + '', + n = length - s.length; + + return n <= 0 ? s + : align === 'left' ? repeat(c, n) + s + : align === 'center' ? repeat(c, ~~(n/2)) + s + repeat(c, Math.ceil(n/2)) + : s + repeat(c, n); +}; + +var toBoolean = function(_) { + return _ == null || _ === '' ? null : !_ || _ === 'false' || _ === '0' ? false : !!_; +}; + +function defaultParser(_) { + return isNumber(_) ? _ : isDate(_) ? _ : Date.parse(_); +} + +var toDate = function(_, parser) { + parser = parser || defaultParser; + return _ == null || _ === '' ? null : parser(_); +}; + +var toString = function(_) { + return _ == null || _ === '' ? null : _ + ''; +}; + +var toSet = function(_) { + for (var s={}, i=0, n=_.length; i= 0) { + list.splice(idx, 1); + } + } + return list; + }; + + return list; +} + +var TUPLE_ID_KEY = Symbol('vega_id'); +var TUPLE_ID = 1; + +/** + * Resets the internal tuple id counter to one. + */ + + +/** + * Checks if an input value is a registered tuple. + * @param {*} t - The value to check. + * @return {boolean} True if the input is a tuple, false otherwise. + */ +function isTuple(t) { + return !!(t && tupleid(t)); +} + +/** + * Returns the id of a tuple. + * @param {object} t - The input tuple. + * @return {*} the tuple id. + */ +function tupleid(t) { + return t[TUPLE_ID_KEY]; +} + +/** + * Sets the id of a tuple. + * @param {object} t - The input tuple. + * @param {*} id - The id value to set. + * @return {object} the input tuple. + */ +function setid(t, id) { + t[TUPLE_ID_KEY] = id; + return t; +} + +/** + * Ingest an object or value as a data tuple. + * If the input value is an object, an id field will be added to it. For + * efficiency, the input object is modified directly. A copy is not made. + * If the input value is a literal, it will be wrapped in a new object + * instance, with the value accessible as the 'data' property. + * @param datum - The value to ingest. + * @return {object} The ingested data tuple. + */ +function ingest(datum) { + var t = (datum === Object(datum)) ? datum : {data: datum}; + return tupleid(t) ? t : setid(t, TUPLE_ID++); +} + +/** + * Given a source tuple, return a derived copy. + * @param {object} t - The source tuple. + * @return {object} The derived tuple. + */ +function derive(t) { + return rederive(t, ingest({})); +} + +/** + * Rederive a derived tuple by copying values from the source tuple. + * @param {object} t - The source tuple. + * @param {object} d - The derived tuple. + * @return {object} The derived tuple. + */ +function rederive(t, d) { + for (var k in t) d[k] = t[k]; + return d; +} + +/** + * Replace an existing tuple with a new tuple. + * @param {object} t - The existing data tuple. + * @param {object} d - The new tuple that replaces the old. + * @return {object} The new tuple. + */ +function replace(t, d) { + return setid(d, tupleid(t)); +} + +function isChangeSet(v) { + return v && v.constructor === changeset; +} + +function changeset() { + var add = [], // insert tuples + rem = [], // remove tuples + mod = [], // modify tuples + remp = [], // remove by predicate + modp = [], // modify by predicate + reflow = false; + + return { + constructor: changeset, + insert: function(t) { + var d = array(t), i = 0, n = d.length; + for (; i= 0) { + if (v[index] !== value || force) { + v[index] = value; + mod[index + ':' + name] = -1; + mod[name] = -1; + } + } else if (v !== value || force) { + o[name] = value; + mod[name] = isArray(value) ? 1 + value.length : -1; + } + + return o; +}; + +/** + * Tests if one or more parameters has been modified. If invoked with no + * arguments, returns true if any parameter value has changed. If the first + * argument is array, returns trues if any parameter name in the array has + * changed. Otherwise, tests if the given name and optional array index has + * changed. + * @param {string} name - The parameter name to test. + * @param {number} [index=undefined] - The parameter array index to test. + * @return {boolean} - Returns true if a queried parameter was modified. + */ +prototype$2.modified = function(name, index) { + var mod = this[CACHE], k; + if (!arguments.length) { + for (k in mod) { if (mod[k]) return true; } + return false; + } else if (isArray(name)) { + for (k=0; k= 0) + ? (index + 1 < mod[name] || !!mod[index + ':' + name]) + : !!mod[name]; +}; + +/** + * Clears the modification records. After calling this method, + * all parameters are considered unmodified. + */ +prototype$2.clear = function() { + this[CACHE] = {}; + return this; +}; + +var OP_ID = 0; +var PULSE = 'pulse'; +var NO_PARAMS = new Parameters(); + +// Boolean Flags +var SKIP = 1; +var MODIFIED = 2; + +/** + * An Operator is a processing node in a dataflow graph. + * Each operator stores a value and an optional value update function. + * Operators can accept a hash of named parameters. Parameter values can + * either be direct (JavaScript literals, arrays, objects) or indirect + * (other operators whose values will be pulled dynamically). Operators + * included as parameters will have this operator added as a dependency. + * @constructor + * @param {*} [init] - The initial value for this operator. + * @param {function(object, Pulse)} [update] - An update function. Upon + * evaluation of this operator, the update function will be invoked and the + * return value will be used as the new value of this operator. + * @param {object} [params] - The parameters for this operator. + * @param {boolean} [react=true] - Flag indicating if this operator should + * listen for changes to upstream operators included as parameters. + * @see parameters + */ +function Operator(init, update, params, react) { + this.id = ++OP_ID; + this.value = init; + this.stamp = -1; + this.rank = -1; + this.qrank = -1; + this.flags = 0; + + if (update) { + this._update = update; + } + if (params) this.parameters(params, react); +} + +var prototype$1 = Operator.prototype; + +/** + * Returns a list of target operators dependent on this operator. + * If this list does not exist, it is created and then returned. + * @return {UniqueList} + */ +prototype$1.targets = function() { + return this._targets || (this._targets = UniqueList(id)); +}; + +/** + * Sets the value of this operator. + * @param {*} value - the value to set. + * @return {Number} Returns 1 if the operator value has changed + * according to strict equality, returns 0 otherwise. + */ +prototype$1.set = function(value) { + if (this.value !== value) { + this.value = value; + return 1; + } else { + return 0; + } +}; + +function flag(bit) { + return function(state) { + var f = this.flags; + if (arguments.length === 0) return !!(f & bit); + this.flags = state ? (f | bit) : (f & ~bit); + return this; + }; +} + +/** + * Indicates that operator evaluation should be skipped on the next pulse. + * This operator will still propagate incoming pulses, but its update function + * will not be invoked. The skip flag is reset after every pulse, so calling + * this method will affect processing of the next pulse only. + */ +prototype$1.skip = flag(SKIP); + +/** + * Indicates that this operator's value has been modified on its most recent + * pulse. Normally modification is checked via strict equality; however, in + * some cases it is more efficient to update the internal state of an object. + * In those cases, the modified flag can be used to trigger propagation. Once + * set, the modification flag persists across pulses until unset. The flag can + * be used with the last timestamp to test if a modification is recent. + */ +prototype$1.modified = flag(MODIFIED); + +/** + * Sets the parameters for this operator. The parameter values are analyzed for + * operator instances. If found, this operator will be added as a dependency + * of the parameterizing operator. Operator values are dynamically marshalled + * from each operator parameter prior to evaluation. If a parameter value is + * an array, the array will also be searched for Operator instances. However, + * the search does not recurse into sub-arrays or object properties. + * @param {object} params - A hash of operator parameters. + * @param {boolean} [react=true] - A flag indicating if this operator should + * automatically update (react) when parameter values change. In other words, + * this flag determines if the operator registers itself as a listener on + * any upstream operators included in the parameters. + * @return {Operator[]} - An array of upstream dependencies. + */ +prototype$1.parameters = function(params, react) { + react = react !== false; + var self = this, + argval = (self._argval = self._argval || new Parameters()), + argops = (self._argops = self._argops || []), + deps = [], + name, value, n, i; + + function add(name, index, value) { + if (value instanceof Operator) { + if (value !== self) { + if (react) value.targets().add(self); + deps.push(value); + } + argops.push({op:value, name:name, index:index}); + } else { + argval.set(name, index, value); + } + } + + for (name in params) { + value = params[name]; + + if (name === PULSE) { + array(value).forEach(function(op) { + if (!(op instanceof Operator)) { + error$1('Pulse parameters must be operator instances.'); + } else if (op !== self) { + op.targets().add(self); + deps.push(op); + } + }); + self.source = value; + } else if (isArray(value)) { + argval.set(name, -1, Array(n = value.length)); + for (i=0; i} - The source operators that should propagate + * to the target operator. + */ +var connect = function(target, sources) { + var targetRank = target.rank, i, n; + + for (i=0, n=sources.length; i pause) { + t = now; + return 1; + } else { + return 0; + } + }); +}; + +prototype$3.debounce = function(delay) { + var s = stream(); + + this.targets().add(stream(null, null, + debounce(delay, function(e) { + var df = e.dataflow; + s.receive(e); + if (df && df.run) df.run(); + }) + )); + + return s; +}; + +prototype$3.between = function(a, b) { + var active = false; + a.targets().add(stream(null, null, function() { active = true; })); + b.targets().add(stream(null, null, function() { active = false; })); + return this.filter(function() { return active; }); +}; + +/** + * Create a new event stream from an event source. + * @param {object} source - The event source to monitor. The input must + * support the addEventListener method. + * @param {string} type - The event type. + * @param {function(object): boolean} [filter] - Event filter function. + * @param {function(object): *} [apply] - Event application function. + * If provided, this function will be invoked and the result will be + * used as the downstream event value. + * @return {EventStream} + */ +var events = function(source, type, filter, apply) { + var df = this, + s = stream(filter, apply), + send = function(e) { + e.dataflow = df; + try { + s.receive(e); + } catch (error) { + df.error(error); + } finally { + df.run(); + } + }, + sources; + + if (typeof source === 'string' && typeof document !== 'undefined') { + sources = document.querySelectorAll(source); + } else { + sources = array(source); + } + + for (var i=0, n=sources.length; i= keys.length) { + if (sortValues != null) array.sort(sortValues); + return rollup != null ? rollup(array) : array; + } + + var i = -1, + n = array.length, + key = keys[depth++], + keyValue, + value, + valuesByKey = map(), + values, + result = createResult(); + + while (++i < n) { + if (values = valuesByKey.get(keyValue = key(value = array[i]) + "")) { + values.push(value); + } else { + valuesByKey.set(keyValue, [value]); + } + } + + valuesByKey.each(function(values, key) { + setResult(result, key, apply(values, depth, createResult, setResult)); + }); + + return result; + } + + function entries(map$$1, depth) { + if (++depth > keys.length) return map$$1; + var array, sortKey = sortKeys[depth - 1]; + if (rollup != null && depth >= keys.length) array = map$$1.entries(); + else array = [], map$$1.each(function(v, k) { array.push({key: k, values: entries(v, depth)}); }); + return sortKey != null ? array.sort(function(a, b) { return sortKey(a.key, b.key); }) : array; + } + + return nest = { + object: function(array) { return apply(array, 0, createObject, setObject); }, + map: function(array) { return apply(array, 0, createMap, setMap); }, + entries: function(array) { return entries(apply(array, 0, createMap, setMap), 0); }, + key: function(d) { keys.push(d); return nest; }, + sortKeys: function(order) { sortKeys[keys.length - 1] = order; return nest; }, + sortValues: function(order) { sortValues = order; return nest; }, + rollup: function(f) { rollup = f; return nest; } + }; +}; + +function createObject() { + return {}; +} + +function setObject(object, key, value) { + object[key] = value; +} + +function createMap() { + return map(); +} + +function setMap(map$$1, key, value) { + map$$1.set(key, value); +} + +function Set() {} + +var proto = map.prototype; + +Set.prototype = set.prototype = { + constructor: Set, + has: proto.has, + add: function(value) { + value += ""; + this[prefix + value] = value; + return this; + }, + remove: proto.remove, + clear: proto.clear, + values: proto.keys, + size: proto.size, + empty: proto.empty, + each: proto.each +}; + +function set(object, f) { + var set = new Set; + + // Copy constructor. + if (object instanceof Set) object.each(function(value) { set.add(value); }); + + // Otherwise, assume it’s an array. + else if (object) { + var i = -1, n = object.length; + if (f == null) while (++i < n) set.add(object[i]); + else while (++i < n) set.add(f(object[i], i, object)); + } + + return set; +} + +var noop = {value: function() {}}; + +function dispatch() { + for (var i = 0, n = arguments.length, _ = {}, t; i < n; ++i) { + if (!(t = arguments[i] + "") || (t in _)) throw new Error("illegal type: " + t); + _[t] = []; + } + return new Dispatch(_); +} + +function Dispatch(_) { + this._ = _; +} + +function parseTypenames(typenames, types) { + return typenames.trim().split(/^|\s+/).map(function(t) { + var name = "", i = t.indexOf("."); + if (i >= 0) name = t.slice(i + 1), t = t.slice(0, i); + if (t && !types.hasOwnProperty(t)) throw new Error("unknown type: " + t); + return {type: t, name: name}; + }); +} + +Dispatch.prototype = dispatch.prototype = { + constructor: Dispatch, + on: function(typename, callback) { + var _ = this._, + T = parseTypenames(typename + "", _), + t, + i = -1, + n = T.length; + + // If no callback was specified, return the callback of the given type and name. + if (arguments.length < 2) { + while (++i < n) if ((t = (typename = T[i]).type) && (t = get(_[t], typename.name))) return t; + return; + } + + // If a type was specified, set the callback for the given type and name. + // Otherwise, if a null callback was specified, remove callbacks of the given name. + if (callback != null && typeof callback !== "function") throw new Error("invalid callback: " + callback); + while (++i < n) { + if (t = (typename = T[i]).type) _[t] = set$2(_[t], typename.name, callback); + else if (callback == null) for (t in _) _[t] = set$2(_[t], typename.name, null); + } + + return this; + }, + copy: function() { + var copy = {}, _ = this._; + for (var t in _) copy[t] = _[t].slice(); + return new Dispatch(copy); + }, + call: function(type, that) { + if ((n = arguments.length - 2) > 0) for (var args = new Array(n), i = 0, n, t; i < n; ++i) args[i] = arguments[i + 2]; + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); + }, + apply: function(type, that, args) { + if (!this._.hasOwnProperty(type)) throw new Error("unknown type: " + type); + for (var t = this._[type], i = 0, n = t.length; i < n; ++i) t[i].value.apply(that, args); + } +}; + +function get(type, name) { + for (var i = 0, n = type.length, c; i < n; ++i) { + if ((c = type[i]).name === name) { + return c.value; + } + } +} + +function set$2(type, name, callback) { + for (var i = 0, n = type.length; i < n; ++i) { + if (type[i].name === name) { + type[i] = noop, type = type.slice(0, i).concat(type.slice(i + 1)); + break; + } + } + if (callback != null) type.push({name: name, value: callback}); + return type; +} + +var request$1 = function(url, callback) { + var request, + event = dispatch("beforesend", "progress", "load", "error"), + mimeType, + headers = map(), + xhr = new XMLHttpRequest, + user = null, + password = null, + response, + responseType, + timeout = 0; + + // If IE does not support CORS, use XDomainRequest. + if (typeof XDomainRequest !== "undefined" + && !("withCredentials" in xhr) + && /^(http(s)?:)?\/\//.test(url)) xhr = new XDomainRequest; + + "onload" in xhr + ? xhr.onload = xhr.onerror = xhr.ontimeout = respond + : xhr.onreadystatechange = function(o) { xhr.readyState > 3 && respond(o); }; + + function respond(o) { + var status = xhr.status, result; + if (!status && hasResponse(xhr) + || status >= 200 && status < 300 + || status === 304) { + if (response) { + try { + result = response.call(request, xhr); + } catch (e) { + event.call("error", request, e); + return; + } + } else { + result = xhr; + } + event.call("load", request, result); + } else { + event.call("error", request, o); + } + } + + xhr.onprogress = function(e) { + event.call("progress", request, e); + }; + + request = { + header: function(name, value) { + name = (name + "").toLowerCase(); + if (arguments.length < 2) return headers.get(name); + if (value == null) headers.remove(name); + else headers.set(name, value + ""); + return request; + }, + + // If mimeType is non-null and no Accept header is set, a default is used. + mimeType: function(value) { + if (!arguments.length) return mimeType; + mimeType = value == null ? null : value + ""; + return request; + }, + + // Specifies what type the response value should take; + // for instance, arraybuffer, blob, document, or text. + responseType: function(value) { + if (!arguments.length) return responseType; + responseType = value; + return request; + }, + + timeout: function(value) { + if (!arguments.length) return timeout; + timeout = +value; + return request; + }, + + user: function(value) { + return arguments.length < 1 ? user : (user = value == null ? null : value + "", request); + }, + + password: function(value) { + return arguments.length < 1 ? password : (password = value == null ? null : value + "", request); + }, + + // Specify how to convert the response content to a specific type; + // changes the callback value on "load" events. + response: function(value) { + response = value; + return request; + }, + + // Alias for send("GET", …). + get: function(data, callback) { + return request.send("GET", data, callback); + }, + + // Alias for send("POST", …). + post: function(data, callback) { + return request.send("POST", data, callback); + }, + + // If callback is non-null, it will be used for error and load events. + send: function(method, data, callback) { + xhr.open(method, url, true, user, password); + if (mimeType != null && !headers.has("accept")) headers.set("accept", mimeType + ",*/*"); + if (xhr.setRequestHeader) headers.each(function(value, name) { xhr.setRequestHeader(name, value); }); + if (mimeType != null && xhr.overrideMimeType) xhr.overrideMimeType(mimeType); + if (responseType != null) xhr.responseType = responseType; + if (timeout > 0) xhr.timeout = timeout; + if (callback == null && typeof data === "function") callback = data, data = null; + if (callback != null && callback.length === 1) callback = fixCallback(callback); + if (callback != null) request.on("error", callback).on("load", function(xhr) { callback(null, xhr); }); + event.call("beforesend", request, xhr); + xhr.send(data == null ? null : data); + return request; + }, + + abort: function() { + xhr.abort(); + return request; + }, + + on: function() { + var value = event.on.apply(event, arguments); + return value === event ? request : value; + } + }; + + if (callback != null) { + if (typeof callback !== "function") throw new Error("invalid callback: " + callback); + return request.get(callback); + } + + return request; +}; + +function fixCallback(callback) { + return function(error, xhr) { + callback(error == null ? xhr : null); + }; +} + +function hasResponse(xhr) { + var type = xhr.responseType; + return type && type !== "text" + ? xhr.response // null on error + : xhr.responseText; // "" on error +} + +var EOL = {}; +var EOF = {}; +var QUOTE = 34; +var NEWLINE = 10; +var RETURN = 13; + +function objectConverter(columns) { + return new Function("d", "return {" + columns.map(function(name, i) { + return JSON.stringify(name) + ": d[" + i + "]"; + }).join(",") + "}"); +} + +function customConverter(columns, f) { + var object = objectConverter(columns); + return function(row, i) { + return f(object(row), i, columns); + }; +} + +// Compute unique columns in order of discovery. +function inferColumns(rows) { + var columnSet = Object.create(null), + columns = []; + + rows.forEach(function(row) { + for (var column in row) { + if (!(column in columnSet)) { + columns.push(columnSet[column] = column); + } + } + }); + + return columns; +} + +var dsvFormat = function(delimiter) { + var reFormat = new RegExp("[\"" + delimiter + "\n\r]"), + DELIMITER = delimiter.charCodeAt(0); + + function parse(text, f) { + var convert, columns, rows = parseRows(text, function(row, i) { + if (convert) return convert(row, i - 1); + columns = row, convert = f ? customConverter(row, f) : objectConverter(row); + }); + rows.columns = columns || []; + return rows; + } + + function parseRows(text, f) { + var rows = [], // output rows + N = text.length, + I = 0, // current character index + n = 0, // current line number + t, // current token + eof = N <= 0, // current token followed by EOF? + eol = false; // current token followed by EOL? + + // Strip the trailing newline. + if (text.charCodeAt(N - 1) === NEWLINE) --N; + if (text.charCodeAt(N - 1) === RETURN) --N; + + function token() { + if (eof) return EOF; + if (eol) return eol = false, EOL; + + // Unescape quotes. + var i, j = I, c; + if (text.charCodeAt(j) === QUOTE) { + while (I++ < N && text.charCodeAt(I) !== QUOTE || text.charCodeAt(++I) === QUOTE); + if ((i = I) >= N) eof = true; + else if ((c = text.charCodeAt(I++)) === NEWLINE) eol = true; + else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } + return text.slice(j + 1, i - 1).replace(/""/g, "\""); + } + + // Find next delimiter or newline. + while (I < N) { + if ((c = text.charCodeAt(i = I++)) === NEWLINE) eol = true; + else if (c === RETURN) { eol = true; if (text.charCodeAt(I) === NEWLINE) ++I; } + else if (c !== DELIMITER) continue; + return text.slice(j, i); + } + + // Return last token before EOF. + return eof = true, text.slice(j, N); + } + + while ((t = token()) !== EOF) { + var row = []; + while (t !== EOL && t !== EOF) row.push(t), t = token(); + if (f && (row = f(row, n++)) == null) continue; + rows.push(row); + } + + return rows; + } + + function format(rows, columns) { + if (columns == null) columns = inferColumns(rows); + return [columns.map(formatValue).join(delimiter)].concat(rows.map(function(row) { + return columns.map(function(column) { + return formatValue(row[column]); + }).join(delimiter); + })).join("\n"); + } + + function formatRows(rows) { + return rows.map(formatRow).join("\n"); + } + + function formatRow(row) { + return row.map(formatValue).join(delimiter); + } + + function formatValue(text) { + return text == null ? "" + : reFormat.test(text += "") ? "\"" + text.replace(/"/g, "\"\"") + "\"" + : text; + } + + return { + parse: parse, + parseRows: parseRows, + format: format, + formatRows: formatRows + }; +}; + +var csv$1 = dsvFormat(","); + +var tsv = dsvFormat("\t"); + +// Matches absolute URLs with optional protocol +// https://... file://... //... +var protocol_re = /^([A-Za-z]+:)?\/\//; + +// Special treatment in node.js for the file: protocol +var fileProtocol = 'file://'; + +// Request options to check for d3-request +var requestOptions = [ + 'mimeType', + 'responseType', + 'user', + 'password' +]; + +/** + * Creates a new loader instance that provides methods for requesting files + * from either the network or disk, and for sanitizing request URIs. + * @param {object} [options] - Optional default loading options to use. + * @return {object} - A new loader instance. + */ +var loader = function(options) { + return { + options: options || {}, + sanitize: sanitize, + load: load, + file: file, + http: http + }; +}; + +function marshall(loader, options) { + return extend({}, loader.options, options); +} + +/** + * Load an external resource, typically either from the web or from the local + * filesystem. This function uses {@link sanitize} to first sanitize the uri, + * then calls either {@link http} (for web requests) or {@link file} (for + * filesystem loading). + * @param {string} uri - The resource indicator (e.g., URL or filename). + * @param {object} [options] - Optional loading options. These options will + * override any existing default options. + * @return {Promise} - A promise that resolves to the loaded content. + */ +function load(uri, options) { + var loader = this; + return loader.sanitize(uri, options) + .then(function(opt) { + var url = opt.href; + return opt.localFile + ? loader.file(url) + : loader.http(url, options); + }); +} + +/** + * URI sanitizer function. + * @param {string} uri - The uri (url or filename) to sanity check. + * @param {object} options - An options hash. + * @return {Promise} - A promise that resolves to an object containing + * sanitized uri data, or rejects it the input uri is deemed invalid. + * The properties of the resolved object are assumed to be + * valid attributes for an HTML 'a' tag. The sanitized uri *must* be + * provided by the 'href' property of the returned object. + */ +function sanitize(uri, options) { + options = marshall(this, options); + return new Promise(function(accept, reject) { + var result = {href: null}, + isFile, hasProtocol, loadFile, base; + + if (uri == null || typeof uri !== 'string') { + reject('Sanitize failure, invalid URI: ' + $(uri)); + return; + } + + hasProtocol = protocol_re.test(uri); + + // if relative url (no protocol/host), prepend baseURL + if ((base = options.baseURL) && !hasProtocol) { + // Ensure that there is a slash between the baseURL (e.g. hostname) and url + if (!startsWith(uri, '/') && base[base.length-1] !== '/') { + uri = '/' + uri; + } + uri = base + uri; + } + + // should we load from file system? + loadFile = (isFile = startsWith(uri, fileProtocol)) + || options.mode === 'file' + || options.mode !== 'http' && !hasProtocol && fs(); + + if (isFile) { + // strip file protocol + uri = uri.slice(fileProtocol.length); + } else if (startsWith(uri, '//')) { + if (options.defaultProtocol === 'file') { + // if is file, strip protocol and set loadFile flag + uri = uri.slice(2); + loadFile = true; + } else { + // if relative protocol (starts with '//'), prepend default protocol + uri = (options.defaultProtocol || 'http') + ':' + uri; + } + } + + // set non-enumerable mode flag to indicate local file load + Object.defineProperty(result, 'localFile', {value: !!loadFile}); + + // set uri + result.href = uri; + + // set default result target, if specified + if (options.target) { + result.target = options.target + ''; + } + + // return + accept(result); + }); +} + +/** + * HTTP request loader. + * @param {string} url - The url to request. + * @param {object} options - An options hash. + * @return {Promise} - A promise that resolves to the file contents. + */ +function http(url, options) { + options = marshall(this, options); + return new Promise(function(accept, reject) { + var req = request$1(url), + name; + + for (name in options.headers) { + req.header(name, options.headers[name]); + } + + requestOptions.forEach(function(name) { + if (options[name]) req[name](options[name]); + }); + + req.on('error', function(error) { + reject(error || 'Error loading URL: ' + url); + }) + .on('load', function(result) { + var text$$1 = result && result.responseText; + (!result || result.status === 0) + ? reject(text$$1 || 'Error') + : accept(text$$1); + }) + .get(); + }); +} + +/** + * File system loader. + * @param {string} filename - The file system path to load. + * @return {Promise} - A promise that resolves to the file contents. + */ +function file(filename) { + return new Promise(function(accept, reject) { + var f = fs(); + f ? f.readFile(filename, function(error, data) { + if (error) reject(error); + else accept(data); + }) + : reject('No file system access for ' + filename); + }); +} + +function fs() { + var fs = typeof require === 'function' && require('fs'); + return fs && isFunction(fs.readFile) ? fs : null; +} + +function startsWith(string, query) { + return string == null ? false : string.lastIndexOf(query, 0) === 0; +} + +var typeParsers = { + boolean: toBoolean, + integer: toNumber, + number: toNumber, + date: toDate, + string: toString, + unknown: identity +}; + +var typeTests = [ + isBoolean$1, + isInteger, + isNumber$1, + isDate$1 +]; + +var typeList = [ + 'boolean', + 'integer', + 'number', + 'date' +]; + +function inferType(values, field$$1) { + if (!values || !values.length) return 'unknown'; + + var tests = typeTests.slice(), + value, i, n, j; + + for (i=0, n=values.length; i 1) arcs = extractArcs(topology, object$$1, filter); + else for (i = 0, arcs = new Array(n = topology.arcs.length); i < n; ++i) arcs[i] = i; + return {type: "MultiLineString", arcs: stitch(topology, arcs)}; +} + +function extractArcs(topology, object$$1, filter) { + var arcs = [], + geomsByArc = [], + geom; + + function extract0(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } + + function extract1(arcs) { + arcs.forEach(extract0); + } + + function extract2(arcs) { + arcs.forEach(extract1); + } + + function extract3(arcs) { + arcs.forEach(extract2); + } + + function geometry(o) { + switch (geom = o, o.type) { + case "GeometryCollection": o.geometries.forEach(geometry); break; + case "LineString": extract1(o.arcs); break; + case "MultiLineString": case "Polygon": extract2(o.arcs); break; + case "MultiPolygon": extract3(o.arcs); break; + } + } + + geometry(object$$1); + + geomsByArc.forEach(filter == null + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + + return arcs; +} + +var bisect = function(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; +}; + +var topojson = function(data, format) { + var method, object, property; + data = json$1(data, format); + + method = (format && (property = format.feature)) ? feature + : (format && (property = format.mesh)) ? mesh + : error$1('Missing TopoJSON feature or mesh parameter.'); + + object = (object = data.objects[property]) + ? method(data, object) + : error$1('Invalid TopoJSON object: ' + property); + + return object && object.features || [object]; +}; + +var formats = { + dsv: dsv$1, + csv: delimitedFormat(','), + tsv: delimitedFormat('\t'), + json: json$1, + topojson: topojson +}; + +var formats$1 = function(name, format) { + if (arguments.length > 1) { + formats[name] = format; + return this; + } else { + return formats.hasOwnProperty(name) ? formats[name] : null; + } +}; + +var t0 = new Date; +var t1 = new Date; + +function newInterval(floori, offseti, count, field) { + + function interval(date) { + return floori(date = new Date(+date)), date; + } + + interval.floor = interval; + + interval.ceil = function(date) { + return floori(date = new Date(date - 1)), offseti(date, 1), floori(date), date; + }; + + interval.round = function(date) { + var d0 = interval(date), + d1 = interval.ceil(date); + return date - d0 < d1 - date ? d0 : d1; + }; + + interval.offset = function(date, step) { + return offseti(date = new Date(+date), step == null ? 1 : Math.floor(step)), date; + }; + + interval.range = function(start, stop, step) { + var range = [], previous; + start = interval.ceil(start); + step = step == null ? 1 : Math.floor(step); + if (!(start < stop) || !(step > 0)) return range; // also handles Invalid Date + do range.push(previous = new Date(+start)), offseti(start, step), floori(start); + while (previous < start && start < stop); + return range; + }; + + interval.filter = function(test) { + return newInterval(function(date) { + if (date >= date) while (floori(date), !test(date)) date.setTime(date - 1); + }, function(date, step) { + if (date >= date) { + if (step < 0) while (++step <= 0) { + while (offseti(date, -1), !test(date)) {} // eslint-disable-line no-empty + } else while (--step >= 0) { + while (offseti(date, +1), !test(date)) {} // eslint-disable-line no-empty + } + } + }); + }; + + if (count) { + interval.count = function(start, end) { + t0.setTime(+start), t1.setTime(+end); + floori(t0), floori(t1); + return Math.floor(count(t0, t1)); + }; + + interval.every = function(step) { + step = Math.floor(step); + return !isFinite(step) || !(step > 0) ? null + : !(step > 1) ? interval + : interval.filter(field + ? function(d) { return field(d) % step === 0; } + : function(d) { return interval.count(0, d) % step === 0; }); + }; + } + + return interval; +} + +var millisecond = newInterval(function() { + // noop +}, function(date, step) { + date.setTime(+date + step); +}, function(start, end) { + return end - start; +}); + +// An optimized implementation for this simple case. +millisecond.every = function(k) { + k = Math.floor(k); + if (!isFinite(k) || !(k > 0)) return null; + if (!(k > 1)) return millisecond; + return newInterval(function(date) { + date.setTime(Math.floor(date / k) * k); + }, function(date, step) { + date.setTime(+date + step * k); + }, function(start, end) { + return (end - start) / k; + }); +}; + +var durationSecond = 1e3; +var durationMinute = 6e4; +var durationHour = 36e5; +var durationDay = 864e5; +var durationWeek = 6048e5; + +var second = newInterval(function(date) { + date.setTime(Math.floor(date / durationSecond) * durationSecond); +}, function(date, step) { + date.setTime(+date + step * durationSecond); +}, function(start, end) { + return (end - start) / durationSecond; +}, function(date) { + return date.getUTCSeconds(); +}); + +var minute = newInterval(function(date) { + date.setTime(Math.floor(date / durationMinute) * durationMinute); +}, function(date, step) { + date.setTime(+date + step * durationMinute); +}, function(start, end) { + return (end - start) / durationMinute; +}, function(date) { + return date.getMinutes(); +}); + +var hour = newInterval(function(date) { + var offset = date.getTimezoneOffset() * durationMinute % durationHour; + if (offset < 0) offset += durationHour; + date.setTime(Math.floor((+date - offset) / durationHour) * durationHour + offset); +}, function(date, step) { + date.setTime(+date + step * durationHour); +}, function(start, end) { + return (end - start) / durationHour; +}, function(date) { + return date.getHours(); +}); + +var day = newInterval(function(date) { + date.setHours(0, 0, 0, 0); +}, function(date, step) { + date.setDate(date.getDate() + step); +}, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationDay; +}, function(date) { + return date.getDate() - 1; +}); + +function weekday(i) { + return newInterval(function(date) { + date.setDate(date.getDate() - (date.getDay() + 7 - i) % 7); + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setDate(date.getDate() + step * 7); + }, function(start, end) { + return (end - start - (end.getTimezoneOffset() - start.getTimezoneOffset()) * durationMinute) / durationWeek; + }); +} + +var sunday = weekday(0); +var monday = weekday(1); +var tuesday = weekday(2); +var wednesday = weekday(3); +var thursday = weekday(4); +var friday = weekday(5); +var saturday = weekday(6); + +var month = newInterval(function(date) { + date.setDate(1); + date.setHours(0, 0, 0, 0); +}, function(date, step) { + date.setMonth(date.getMonth() + step); +}, function(start, end) { + return end.getMonth() - start.getMonth() + (end.getFullYear() - start.getFullYear()) * 12; +}, function(date) { + return date.getMonth(); +}); + +var year = newInterval(function(date) { + date.setMonth(0, 1); + date.setHours(0, 0, 0, 0); +}, function(date, step) { + date.setFullYear(date.getFullYear() + step); +}, function(start, end) { + return end.getFullYear() - start.getFullYear(); +}, function(date) { + return date.getFullYear(); +}); + +// An optimized implementation for this simple case. +year.every = function(k) { + return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { + date.setFullYear(Math.floor(date.getFullYear() / k) * k); + date.setMonth(0, 1); + date.setHours(0, 0, 0, 0); + }, function(date, step) { + date.setFullYear(date.getFullYear() + step * k); + }); +}; + +var utcMinute = newInterval(function(date) { + date.setUTCSeconds(0, 0); +}, function(date, step) { + date.setTime(+date + step * durationMinute); +}, function(start, end) { + return (end - start) / durationMinute; +}, function(date) { + return date.getUTCMinutes(); +}); + +var utcHour = newInterval(function(date) { + date.setUTCMinutes(0, 0, 0); +}, function(date, step) { + date.setTime(+date + step * durationHour); +}, function(start, end) { + return (end - start) / durationHour; +}, function(date) { + return date.getUTCHours(); +}); + +var utcDay = newInterval(function(date) { + date.setUTCHours(0, 0, 0, 0); +}, function(date, step) { + date.setUTCDate(date.getUTCDate() + step); +}, function(start, end) { + return (end - start) / durationDay; +}, function(date) { + return date.getUTCDate() - 1; +}); + +function utcWeekday(i) { + return newInterval(function(date) { + date.setUTCDate(date.getUTCDate() - (date.getUTCDay() + 7 - i) % 7); + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCDate(date.getUTCDate() + step * 7); + }, function(start, end) { + return (end - start) / durationWeek; + }); +} + +var utcSunday = utcWeekday(0); +var utcMonday = utcWeekday(1); +var utcTuesday = utcWeekday(2); +var utcWednesday = utcWeekday(3); +var utcThursday = utcWeekday(4); +var utcFriday = utcWeekday(5); +var utcSaturday = utcWeekday(6); + +var utcMonth = newInterval(function(date) { + date.setUTCDate(1); + date.setUTCHours(0, 0, 0, 0); +}, function(date, step) { + date.setUTCMonth(date.getUTCMonth() + step); +}, function(start, end) { + return end.getUTCMonth() - start.getUTCMonth() + (end.getUTCFullYear() - start.getUTCFullYear()) * 12; +}, function(date) { + return date.getUTCMonth(); +}); + +var utcYear = newInterval(function(date) { + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); +}, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step); +}, function(start, end) { + return end.getUTCFullYear() - start.getUTCFullYear(); +}, function(date) { + return date.getUTCFullYear(); +}); + +// An optimized implementation for this simple case. +utcYear.every = function(k) { + return !isFinite(k = Math.floor(k)) || !(k > 0) ? null : newInterval(function(date) { + date.setUTCFullYear(Math.floor(date.getUTCFullYear() / k) * k); + date.setUTCMonth(0, 1); + date.setUTCHours(0, 0, 0, 0); + }, function(date, step) { + date.setUTCFullYear(date.getUTCFullYear() + step * k); + }); +}; + +function localDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(-1, d.m, d.d, d.H, d.M, d.S, d.L); + date.setFullYear(d.y); + return date; + } + return new Date(d.y, d.m, d.d, d.H, d.M, d.S, d.L); +} + +function utcDate(d) { + if (0 <= d.y && d.y < 100) { + var date = new Date(Date.UTC(-1, d.m, d.d, d.H, d.M, d.S, d.L)); + date.setUTCFullYear(d.y); + return date; + } + return new Date(Date.UTC(d.y, d.m, d.d, d.H, d.M, d.S, d.L)); +} + +function newYear(y) { + return {y: y, m: 0, d: 1, H: 0, M: 0, S: 0, L: 0}; +} + +function formatLocale(locale) { + var locale_dateTime = locale.dateTime, + locale_date = locale.date, + locale_time = locale.time, + locale_periods = locale.periods, + locale_weekdays = locale.days, + locale_shortWeekdays = locale.shortDays, + locale_months = locale.months, + locale_shortMonths = locale.shortMonths; + + var periodRe = formatRe(locale_periods), + periodLookup = formatLookup(locale_periods), + weekdayRe = formatRe(locale_weekdays), + weekdayLookup = formatLookup(locale_weekdays), + shortWeekdayRe = formatRe(locale_shortWeekdays), + shortWeekdayLookup = formatLookup(locale_shortWeekdays), + monthRe = formatRe(locale_months), + monthLookup = formatLookup(locale_months), + shortMonthRe = formatRe(locale_shortMonths), + shortMonthLookup = formatLookup(locale_shortMonths); + + var formats = { + "a": formatShortWeekday, + "A": formatWeekday, + "b": formatShortMonth, + "B": formatMonth, + "c": null, + "d": formatDayOfMonth, + "e": formatDayOfMonth, + "f": formatMicroseconds, + "H": formatHour24, + "I": formatHour12, + "j": formatDayOfYear, + "L": formatMilliseconds, + "m": formatMonthNumber, + "M": formatMinutes, + "p": formatPeriod, + "Q": formatUnixTimestamp, + "s": formatUnixTimestampSeconds, + "S": formatSeconds, + "u": formatWeekdayNumberMonday, + "U": formatWeekNumberSunday, + "V": formatWeekNumberISO, + "w": formatWeekdayNumberSunday, + "W": formatWeekNumberMonday, + "x": null, + "X": null, + "y": formatYear, + "Y": formatFullYear, + "Z": formatZone, + "%": formatLiteralPercent + }; + + var utcFormats = { + "a": formatUTCShortWeekday, + "A": formatUTCWeekday, + "b": formatUTCShortMonth, + "B": formatUTCMonth, + "c": null, + "d": formatUTCDayOfMonth, + "e": formatUTCDayOfMonth, + "f": formatUTCMicroseconds, + "H": formatUTCHour24, + "I": formatUTCHour12, + "j": formatUTCDayOfYear, + "L": formatUTCMilliseconds, + "m": formatUTCMonthNumber, + "M": formatUTCMinutes, + "p": formatUTCPeriod, + "Q": formatUnixTimestamp, + "s": formatUnixTimestampSeconds, + "S": formatUTCSeconds, + "u": formatUTCWeekdayNumberMonday, + "U": formatUTCWeekNumberSunday, + "V": formatUTCWeekNumberISO, + "w": formatUTCWeekdayNumberSunday, + "W": formatUTCWeekNumberMonday, + "x": null, + "X": null, + "y": formatUTCYear, + "Y": formatUTCFullYear, + "Z": formatUTCZone, + "%": formatLiteralPercent + }; + + var parses = { + "a": parseShortWeekday, + "A": parseWeekday, + "b": parseShortMonth, + "B": parseMonth, + "c": parseLocaleDateTime, + "d": parseDayOfMonth, + "e": parseDayOfMonth, + "f": parseMicroseconds, + "H": parseHour24, + "I": parseHour24, + "j": parseDayOfYear, + "L": parseMilliseconds, + "m": parseMonthNumber, + "M": parseMinutes, + "p": parsePeriod, + "Q": parseUnixTimestamp, + "s": parseUnixTimestampSeconds, + "S": parseSeconds, + "u": parseWeekdayNumberMonday, + "U": parseWeekNumberSunday, + "V": parseWeekNumberISO, + "w": parseWeekdayNumberSunday, + "W": parseWeekNumberMonday, + "x": parseLocaleDate, + "X": parseLocaleTime, + "y": parseYear, + "Y": parseFullYear, + "Z": parseZone, + "%": parseLiteralPercent + }; + + // These recursive directive definitions must be deferred. + formats.x = newFormat(locale_date, formats); + formats.X = newFormat(locale_time, formats); + formats.c = newFormat(locale_dateTime, formats); + utcFormats.x = newFormat(locale_date, utcFormats); + utcFormats.X = newFormat(locale_time, utcFormats); + utcFormats.c = newFormat(locale_dateTime, utcFormats); + + function newFormat(specifier, formats) { + return function(date) { + var string = [], + i = -1, + j = 0, + n = specifier.length, + c, + pad, + format; + + if (!(date instanceof Date)) date = new Date(+date); + + while (++i < n) { + if (specifier.charCodeAt(i) === 37) { + string.push(specifier.slice(j, i)); + if ((pad = pads[c = specifier.charAt(++i)]) != null) c = specifier.charAt(++i); + else pad = c === "e" ? " " : "0"; + if (format = formats[c]) c = format(date, pad); + string.push(c); + j = i + 1; + } + } + + string.push(specifier.slice(j, i)); + return string.join(""); + }; + } + + function newParse(specifier, newDate) { + return function(string) { + var d = newYear(1900), + i = parseSpecifier(d, specifier, string += "", 0), + week, day$$1; + if (i != string.length) return null; + + // If a UNIX timestamp is specified, return it. + if ("Q" in d) return new Date(d.Q); + + // The am-pm flag is 0 for AM, and 1 for PM. + if ("p" in d) d.H = d.H % 12 + d.p * 12; + + // Convert day-of-week and week-of-year to day-of-year. + if ("V" in d) { + if (d.V < 1 || d.V > 53) return null; + if (!("w" in d)) d.w = 1; + if ("Z" in d) { + week = utcDate(newYear(d.y)), day$$1 = week.getUTCDay(); + week = day$$1 > 4 || day$$1 === 0 ? utcMonday.ceil(week) : utcMonday(week); + week = utcDay.offset(week, (d.V - 1) * 7); + d.y = week.getUTCFullYear(); + d.m = week.getUTCMonth(); + d.d = week.getUTCDate() + (d.w + 6) % 7; + } else { + week = newDate(newYear(d.y)), day$$1 = week.getDay(); + week = day$$1 > 4 || day$$1 === 0 ? monday.ceil(week) : monday(week); + week = day.offset(week, (d.V - 1) * 7); + d.y = week.getFullYear(); + d.m = week.getMonth(); + d.d = week.getDate() + (d.w + 6) % 7; + } + } else if ("W" in d || "U" in d) { + if (!("w" in d)) d.w = "u" in d ? d.u % 7 : "W" in d ? 1 : 0; + day$$1 = "Z" in d ? utcDate(newYear(d.y)).getUTCDay() : newDate(newYear(d.y)).getDay(); + d.m = 0; + d.d = "W" in d ? (d.w + 6) % 7 + d.W * 7 - (day$$1 + 5) % 7 : d.w + d.U * 7 - (day$$1 + 6) % 7; + } + + // If a time zone is specified, all fields are interpreted as UTC and then + // offset according to the specified time zone. + if ("Z" in d) { + d.H += d.Z / 100 | 0; + d.M += d.Z % 100; + return utcDate(d); + } + + // Otherwise, all fields are in local time. + return newDate(d); + }; + } + + function parseSpecifier(d, specifier, string, j) { + var i = 0, + n = specifier.length, + m = string.length, + c, + parse; + + while (i < n) { + if (j >= m) return -1; + c = specifier.charCodeAt(i++); + if (c === 37) { + c = specifier.charAt(i++); + parse = parses[c in pads ? specifier.charAt(i++) : c]; + if (!parse || ((j = parse(d, string, j)) < 0)) return -1; + } else if (c != string.charCodeAt(j++)) { + return -1; + } + } + + return j; + } + + function parsePeriod(d, string, i) { + var n = periodRe.exec(string.slice(i)); + return n ? (d.p = periodLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseShortWeekday(d, string, i) { + var n = shortWeekdayRe.exec(string.slice(i)); + return n ? (d.w = shortWeekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseWeekday(d, string, i) { + var n = weekdayRe.exec(string.slice(i)); + return n ? (d.w = weekdayLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseShortMonth(d, string, i) { + var n = shortMonthRe.exec(string.slice(i)); + return n ? (d.m = shortMonthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseMonth(d, string, i) { + var n = monthRe.exec(string.slice(i)); + return n ? (d.m = monthLookup[n[0].toLowerCase()], i + n[0].length) : -1; + } + + function parseLocaleDateTime(d, string, i) { + return parseSpecifier(d, locale_dateTime, string, i); + } + + function parseLocaleDate(d, string, i) { + return parseSpecifier(d, locale_date, string, i); + } + + function parseLocaleTime(d, string, i) { + return parseSpecifier(d, locale_time, string, i); + } + + function formatShortWeekday(d) { + return locale_shortWeekdays[d.getDay()]; + } + + function formatWeekday(d) { + return locale_weekdays[d.getDay()]; + } + + function formatShortMonth(d) { + return locale_shortMonths[d.getMonth()]; + } + + function formatMonth(d) { + return locale_months[d.getMonth()]; + } + + function formatPeriod(d) { + return locale_periods[+(d.getHours() >= 12)]; + } + + function formatUTCShortWeekday(d) { + return locale_shortWeekdays[d.getUTCDay()]; + } + + function formatUTCWeekday(d) { + return locale_weekdays[d.getUTCDay()]; + } + + function formatUTCShortMonth(d) { + return locale_shortMonths[d.getUTCMonth()]; + } + + function formatUTCMonth(d) { + return locale_months[d.getUTCMonth()]; + } + + function formatUTCPeriod(d) { + return locale_periods[+(d.getUTCHours() >= 12)]; + } + + return { + format: function(specifier) { + var f = newFormat(specifier += "", formats); + f.toString = function() { return specifier; }; + return f; + }, + parse: function(specifier) { + var p = newParse(specifier += "", localDate); + p.toString = function() { return specifier; }; + return p; + }, + utcFormat: function(specifier) { + var f = newFormat(specifier += "", utcFormats); + f.toString = function() { return specifier; }; + return f; + }, + utcParse: function(specifier) { + var p = newParse(specifier, utcDate); + p.toString = function() { return specifier; }; + return p; + } + }; +} + +var pads = {"-": "", "_": " ", "0": "0"}; +var numberRe = /^\s*\d+/; +var percentRe = /^%/; +var requoteRe = /[\\^$*+?|[\]().{}]/g; + +function pad$1(value, fill, width) { + var sign = value < 0 ? "-" : "", + string = (sign ? -value : value) + "", + length = string.length; + return sign + (length < width ? new Array(width - length + 1).join(fill) + string : string); +} + +function requote(s) { + return s.replace(requoteRe, "\\$&"); +} + +function formatRe(names) { + return new RegExp("^(?:" + names.map(requote).join("|") + ")", "i"); +} + +function formatLookup(names) { + var map = {}, i = -1, n = names.length; + while (++i < n) map[names[i].toLowerCase()] = i; + return map; +} + +function parseWeekdayNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.w = +n[0], i + n[0].length) : -1; +} + +function parseWeekdayNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 1)); + return n ? (d.u = +n[0], i + n[0].length) : -1; +} + +function parseWeekNumberSunday(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.U = +n[0], i + n[0].length) : -1; +} + +function parseWeekNumberISO(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.V = +n[0], i + n[0].length) : -1; +} + +function parseWeekNumberMonday(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.W = +n[0], i + n[0].length) : -1; +} + +function parseFullYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 4)); + return n ? (d.y = +n[0], i + n[0].length) : -1; +} + +function parseYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.y = +n[0] + (+n[0] > 68 ? 1900 : 2000), i + n[0].length) : -1; +} + +function parseZone(d, string, i) { + var n = /^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(string.slice(i, i + 6)); + return n ? (d.Z = n[1] ? 0 : -(n[2] + (n[3] || "00")), i + n[0].length) : -1; +} + +function parseMonthNumber(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.m = n[0] - 1, i + n[0].length) : -1; +} + +function parseDayOfMonth(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.d = +n[0], i + n[0].length) : -1; +} + +function parseDayOfYear(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.m = 0, d.d = +n[0], i + n[0].length) : -1; +} + +function parseHour24(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.H = +n[0], i + n[0].length) : -1; +} + +function parseMinutes(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.M = +n[0], i + n[0].length) : -1; +} + +function parseSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 2)); + return n ? (d.S = +n[0], i + n[0].length) : -1; +} + +function parseMilliseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 3)); + return n ? (d.L = +n[0], i + n[0].length) : -1; +} + +function parseMicroseconds(d, string, i) { + var n = numberRe.exec(string.slice(i, i + 6)); + return n ? (d.L = Math.floor(n[0] / 1000), i + n[0].length) : -1; +} + +function parseLiteralPercent(d, string, i) { + var n = percentRe.exec(string.slice(i, i + 1)); + return n ? i + n[0].length : -1; +} + +function parseUnixTimestamp(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.Q = +n[0], i + n[0].length) : -1; +} + +function parseUnixTimestampSeconds(d, string, i) { + var n = numberRe.exec(string.slice(i)); + return n ? (d.Q = (+n[0]) * 1000, i + n[0].length) : -1; +} + +function formatDayOfMonth(d, p) { + return pad$1(d.getDate(), p, 2); +} + +function formatHour24(d, p) { + return pad$1(d.getHours(), p, 2); +} + +function formatHour12(d, p) { + return pad$1(d.getHours() % 12 || 12, p, 2); +} + +function formatDayOfYear(d, p) { + return pad$1(1 + day.count(year(d), d), p, 3); +} + +function formatMilliseconds(d, p) { + return pad$1(d.getMilliseconds(), p, 3); +} + +function formatMicroseconds(d, p) { + return formatMilliseconds(d, p) + "000"; +} + +function formatMonthNumber(d, p) { + return pad$1(d.getMonth() + 1, p, 2); +} + +function formatMinutes(d, p) { + return pad$1(d.getMinutes(), p, 2); +} + +function formatSeconds(d, p) { + return pad$1(d.getSeconds(), p, 2); +} + +function formatWeekdayNumberMonday(d) { + var day$$1 = d.getDay(); + return day$$1 === 0 ? 7 : day$$1; +} + +function formatWeekNumberSunday(d, p) { + return pad$1(sunday.count(year(d), d), p, 2); +} + +function formatWeekNumberISO(d, p) { + var day$$1 = d.getDay(); + d = (day$$1 >= 4 || day$$1 === 0) ? thursday(d) : thursday.ceil(d); + return pad$1(thursday.count(year(d), d) + (year(d).getDay() === 4), p, 2); +} + +function formatWeekdayNumberSunday(d) { + return d.getDay(); +} + +function formatWeekNumberMonday(d, p) { + return pad$1(monday.count(year(d), d), p, 2); +} + +function formatYear(d, p) { + return pad$1(d.getFullYear() % 100, p, 2); +} + +function formatFullYear(d, p) { + return pad$1(d.getFullYear() % 10000, p, 4); +} + +function formatZone(d) { + var z = d.getTimezoneOffset(); + return (z > 0 ? "-" : (z *= -1, "+")) + + pad$1(z / 60 | 0, "0", 2) + + pad$1(z % 60, "0", 2); +} + +function formatUTCDayOfMonth(d, p) { + return pad$1(d.getUTCDate(), p, 2); +} + +function formatUTCHour24(d, p) { + return pad$1(d.getUTCHours(), p, 2); +} + +function formatUTCHour12(d, p) { + return pad$1(d.getUTCHours() % 12 || 12, p, 2); +} + +function formatUTCDayOfYear(d, p) { + return pad$1(1 + utcDay.count(utcYear(d), d), p, 3); +} + +function formatUTCMilliseconds(d, p) { + return pad$1(d.getUTCMilliseconds(), p, 3); +} + +function formatUTCMicroseconds(d, p) { + return formatUTCMilliseconds(d, p) + "000"; +} + +function formatUTCMonthNumber(d, p) { + return pad$1(d.getUTCMonth() + 1, p, 2); +} + +function formatUTCMinutes(d, p) { + return pad$1(d.getUTCMinutes(), p, 2); +} + +function formatUTCSeconds(d, p) { + return pad$1(d.getUTCSeconds(), p, 2); +} + +function formatUTCWeekdayNumberMonday(d) { + var dow = d.getUTCDay(); + return dow === 0 ? 7 : dow; +} + +function formatUTCWeekNumberSunday(d, p) { + return pad$1(utcSunday.count(utcYear(d), d), p, 2); +} + +function formatUTCWeekNumberISO(d, p) { + var day$$1 = d.getUTCDay(); + d = (day$$1 >= 4 || day$$1 === 0) ? utcThursday(d) : utcThursday.ceil(d); + return pad$1(utcThursday.count(utcYear(d), d) + (utcYear(d).getUTCDay() === 4), p, 2); +} + +function formatUTCWeekdayNumberSunday(d) { + return d.getUTCDay(); +} + +function formatUTCWeekNumberMonday(d, p) { + return pad$1(utcMonday.count(utcYear(d), d), p, 2); +} + +function formatUTCYear(d, p) { + return pad$1(d.getUTCFullYear() % 100, p, 2); +} + +function formatUTCFullYear(d, p) { + return pad$1(d.getUTCFullYear() % 10000, p, 4); +} + +function formatUTCZone() { + return "+0000"; +} + +function formatLiteralPercent() { + return "%"; +} + +function formatUnixTimestamp(d) { + return +d; +} + +function formatUnixTimestampSeconds(d) { + return Math.floor(+d / 1000); +} + +var locale$1; +var timeFormat; +var timeParse; +var utcFormat; +var utcParse; + +defaultLocale({ + dateTime: "%x, %X", + date: "%-m/%-d/%Y", + time: "%-I:%M:%S %p", + periods: ["AM", "PM"], + days: ["Sunday", "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"], + shortDays: ["Sun", "Mon", "Tue", "Wed", "Thu", "Fri", "Sat"], + months: ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"], + shortMonths: ["Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"] +}); + +function defaultLocale(definition) { + locale$1 = formatLocale(definition); + timeFormat = locale$1.format; + timeParse = locale$1.parse; + utcFormat = locale$1.utcFormat; + utcParse = locale$1.utcParse; + return locale$1; +} + +var isoSpecifier = "%Y-%m-%dT%H:%M:%S.%LZ"; + +function formatIsoNative(date) { + return date.toISOString(); +} + +var formatIso = Date.prototype.toISOString + ? formatIsoNative + : utcFormat(isoSpecifier); + +function parseIsoNative(string) { + var date = new Date(string); + return isNaN(date) ? null : date; +} + +var parseIso = +new Date("2000-01-01T00:00:00.000Z") + ? parseIsoNative + : utcParse(isoSpecifier); + +var read = function(data, schema, dateParse) { + schema = schema || {}; + + var reader = formats$1(schema.type || 'json'); + if (!reader) error$1('Unknown data format type: ' + schema.type); + + data = reader(data, schema); + if (schema.parse) parse(data, schema.parse, dateParse); + + if (data.hasOwnProperty('columns')) delete data.columns; + return data; +}; + +function parse(data, types, dateParse) { + if (!data.length) return; // early exit for empty data + + dateParse = dateParse || timeParse; + + var fields = data.columns || Object.keys(data[0]), + parsers, datum, field$$1, i, j, n, m; + + if (types === 'auto') types = inferTypes(data, fields); + + fields = Object.keys(types); + parsers = fields.map(function(field$$1) { + var type = types[field$$1], + parts, pattern; + + if (type && (type.indexOf('date:') === 0 || type.indexOf('utc:') === 0)) { + parts = type.split(/:(.+)?/, 2); // split on first : + pattern = parts[1]; + + if ((pattern[0] === '\'' && pattern[pattern.length-1] === '\'') || + (pattern[0] === '"' && pattern[pattern.length-1] === '"')) { + pattern = pattern.slice(1, -1); + } + + return parts[0] === 'utc' ? utcParse(pattern) : dateParse(pattern); + } + + if (!typeParsers[type]) { + throw Error('Illegal format pattern: ' + field$$1 + ':' + type); + } + + return typeParsers[type]; + }); + + for (i=0, n=data.length, m=fields.length; i= 0;) { + queue.push(cur = list[i]); + if (cur === op) error$1('Cycle detected in dataflow graph.'); + } + } + } +} + +/** + * Sentinel value indicating pulse propagation should stop. + */ +var StopPropagation = {}; + +// Pulse visit type flags +var ADD = (1 << 0); +var REM = (1 << 1); +var MOD = (1 << 2); +var ADD_REM = ADD | REM; +var ADD_MOD = ADD | MOD; +var ALL = ADD | REM | MOD; +var REFLOW = (1 << 3); +var SOURCE = (1 << 4); +var NO_SOURCE = (1 << 5); +var NO_FIELDS = (1 << 6); + +/** + * A Pulse enables inter-operator communication during a run of the + * dataflow graph. In addition to the current timestamp, a pulse may also + * contain a change-set of added, removed or modified data tuples, as well as + * a pointer to a full backing data source. Tuple change sets may not + * be fully materialized; for example, to prevent needless array creation + * a change set may include larger arrays and corresponding filter functions. + * The pulse provides a {@link visit} method to enable proper and efficient + * iteration over requested data tuples. + * + * In addition, each pulse can track modification flags for data tuple fields. + * Responsible transform operators should call the {@link modifies} method to + * indicate changes to data fields. The {@link modified} method enables + * querying of this modification state. + * + * @constructor + * @param {Dataflow} dataflow - The backing dataflow instance. + * @param {number} stamp - The current propagation timestamp. + * @param {string} [encode] - An optional encoding set name, which is then + * accessible as Pulse.encode. Operators can respond to (or ignore) this + * setting as appropriate. This parameter can be used in conjunction with + * the Encode transform in the vega-encode module. + */ +function Pulse(dataflow, stamp, encode) { + this.dataflow = dataflow; + this.stamp = stamp == null ? -1 : stamp; + this.add = []; + this.rem = []; + this.mod = []; + this.fields = null; + this.encode = encode || null; +} + +var prototype$4 = Pulse.prototype; + +/** + * Sentinel value indicating pulse propagation should stop. + */ +prototype$4.StopPropagation = StopPropagation; + +/** + * Boolean flag indicating ADD (added) tuples. + */ +prototype$4.ADD = ADD; + +/** + * Boolean flag indicating REM (removed) tuples. + */ +prototype$4.REM = REM; + +/** + * Boolean flag indicating MOD (modified) tuples. + */ +prototype$4.MOD = MOD; + +/** + * Boolean flag indicating ADD (added) and REM (removed) tuples. + */ +prototype$4.ADD_REM = ADD_REM; + +/** + * Boolean flag indicating ADD (added) and MOD (modified) tuples. + */ +prototype$4.ADD_MOD = ADD_MOD; + +/** + * Boolean flag indicating ADD, REM and MOD tuples. + */ +prototype$4.ALL = ALL; + +/** + * Boolean flag indicating all tuples in a data source + * except for the ADD, REM and MOD tuples. + */ +prototype$4.REFLOW = REFLOW; + +/** + * Boolean flag indicating a 'pass-through' to a + * backing data source, ignoring ADD, REM and MOD tuples. + */ +prototype$4.SOURCE = SOURCE; + +/** + * Boolean flag indicating that source data should be + * suppressed when creating a forked pulse. + */ +prototype$4.NO_SOURCE = NO_SOURCE; + +/** + * Boolean flag indicating that field modifications should be + * suppressed when creating a forked pulse. + */ +prototype$4.NO_FIELDS = NO_FIELDS; + +/** + * Creates a new pulse based on the values of this pulse. + * The dataflow, time stamp and field modification values are copied over. + * By default, new empty ADD, REM and MOD arrays are created. + * @param {number} flags - Integer of boolean flags indicating which (if any) + * tuple arrays should be copied to the new pulse. The supported flag values + * are ADD, REM and MOD. Array references are copied directly: new array + * instances are not created. + * @return {Pulse} - The forked pulse instance. + * @see init + */ +prototype$4.fork = function(flags) { + return new Pulse(this.dataflow).init(this, flags); +}; + +/** + * Returns a pulse that adds all tuples from a backing source. This is + * useful for cases where operators are added to a dataflow after an + * upstream data pipeline has already been processed, ensuring that + * new operators can observe all tuples within a stream. + * @return {Pulse} - A pulse instance with all source tuples included + * in the add array. If the current pulse already has all source + * tuples in its add array, it is returned directly. If the current + * pulse does not have a backing source, it is returned directly. + */ +prototype$4.addAll = function() { + var p = this; + if (!this.source || this.source.length === this.add.length) { + return p; + } else { + p = new Pulse(this.dataflow).init(this); + p.add = p.source; + return p; + } +}; + +/** + * Initialize this pulse based on the values of another pulse. This method + * is used internally by {@link fork} to initialize a new forked tuple. + * The dataflow, time stamp and field modification values are copied over. + * By default, new empty ADD, REM and MOD arrays are created. + * @param {Pulse} src - The source pulse to copy from. + * @param {number} flags - Integer of boolean flags indicating which (if any) + * tuple arrays should be copied to the new pulse. The supported flag values + * are ADD, REM and MOD. Array references are copied directly: new array + * instances are not created. By default, source data arrays are copied + * to the new pulse. Use the NO_SOURCE flag to enforce a null source. + * @return {Pulse} - Returns this Pulse instance. + */ +prototype$4.init = function(src, flags) { + var p = this; + p.stamp = src.stamp; + p.encode = src.encode; + + if (src.fields && !(flags & NO_FIELDS)) { + p.fields = src.fields; + } + + if (flags & ADD) { + p.addF = src.addF; + p.add = src.add; + } else { + p.addF = null; + p.add = []; + } + + if (flags & REM) { + p.remF = src.remF; + p.rem = src.rem; + } else { + p.remF = null; + p.rem = []; + } + + if (flags & MOD) { + p.modF = src.modF; + p.mod = src.mod; + } else { + p.modF = null; + p.mod = []; + } + + if (flags & NO_SOURCE) { + p.srcF = null; + p.source = null; + } else { + p.srcF = src.srcF; + p.source = src.source; + } + + return p; +}; + +/** + * Schedules a function to run after pulse propagation completes. + * @param {function} func - The function to run. + */ +prototype$4.runAfter = function(func) { + this.dataflow.runAfter(func); +}; + +/** + * Indicates if tuples have been added, removed or modified. + * @param {number} [flags] - The tuple types (ADD, REM or MOD) to query. + * Defaults to ALL, returning true if any tuple type has changed. + * @return {boolean} - Returns true if one or more queried tuple types have + * changed, false otherwise. + */ +prototype$4.changed = function(flags) { + var f = flags || ALL; + return ((f & ADD) && this.add.length) + || ((f & REM) && this.rem.length) + || ((f & MOD) && this.mod.length); +}; + +/** + * Forces a "reflow" of tuple values, such that all tuples in the backing + * source are added to the MOD set, unless already present in the ADD set. + * @param {boolean} [fork=false] - If true, returns a forked copy of this + * pulse, and invokes reflow on that derived pulse. + * @return {Pulse} - The reflowed pulse instance. + */ +prototype$4.reflow = function(fork) { + if (fork) return this.fork(ALL).reflow(); + + var len = this.add.length, + src = this.source && this.source.length; + if (src && src !== len) { + this.mod = this.source; + if (len) this.filter(MOD, filter(this, ADD)); + } + return this; +}; + +/** + * Marks one or more data field names as modified to assist dependency + * tracking and incremental processing by transform operators. + * @param {string|Array} _ - The field(s) to mark as modified. + * @return {Pulse} - This pulse instance. + */ +prototype$4.modifies = function(_) { + var fields = array(_), + hash = this.fields || (this.fields = {}); + fields.forEach(function(f) { hash[f] = true; }); + return this; +}; + +/** + * Checks if one or more data fields have been modified during this pulse + * propagation timestamp. + * @param {string|Array} _ - The field(s) to check for modified. + * @return {boolean} - Returns true if any of the provided fields has been + * marked as modified, false otherwise. + */ +prototype$4.modified = function(_) { + var fields = this.fields; + return !(this.mod.length && fields) ? false + : !arguments.length ? !!fields + : isArray(_) ? _.some(function(f) { return fields[f]; }) + : fields[_]; +}; + +/** + * Adds a filter function to one more tuple sets. Filters are applied to + * backing tuple arrays, to determine the actual set of tuples considered + * added, removed or modified. They can be used to delay materialization of + * a tuple set in order to avoid expensive array copies. In addition, the + * filter functions can serve as value transformers: unlike standard predicate + * function (which return boolean values), Pulse filters should return the + * actual tuple value to process. If a tuple set is already filtered, the + * new filter function will be appended into a conjuntive ('and') query. + * @param {number} flags - Flags indicating the tuple set(s) to filter. + * @param {function(*):object} filter - Filter function that will be applied + * to the tuple set array, and should return a data tuple if the value + * should be included in the tuple set, and falsy (or null) otherwise. + * @return {Pulse} - Returns this pulse instance. + */ +prototype$4.filter = function(flags, filter) { + var p = this; + if (flags & ADD) p.addF = addFilter(p.addF, filter); + if (flags & REM) p.remF = addFilter(p.remF, filter); + if (flags & MOD) p.modF = addFilter(p.modF, filter); + if (flags & SOURCE) p.srcF = addFilter(p.srcF, filter); + return p; +}; + +function addFilter(a, b) { + return a ? function(t,i) { return a(t,i) && b(t,i); } : b; +} + +/** + * Materialize one or more tuple sets in this pulse. If the tuple set(s) have + * a registered filter function, it will be applied and the tuple set(s) will + * be replaced with materialized tuple arrays. + * @param {number} flags - Flags indicating the tuple set(s) to materialize. + * @return {Pulse} - Returns this pulse instance. + */ +prototype$4.materialize = function(flags) { + flags = flags || ALL; + var p = this; + if ((flags & ADD) && p.addF) { + p.add = materialize(p.add, p.addF); + p.addF = null; + } + if ((flags & REM) && p.remF) { + p.rem = materialize(p.rem, p.remF); + p.remF = null; + } + if ((flags & MOD) && p.modF) { + p.mod = materialize(p.mod, p.modF); + p.modF = null; + } + if ((flags & SOURCE) && p.srcF) { + p.source = p.source.filter(p.srcF); + p.srcF = null; + } + return p; +}; + +function materialize(data, filter) { + var out = []; + visitArray(data, filter, function(_) { out.push(_); }); + return out; +} + +function filter(pulse, flags) { + var map = {}; + pulse.visit(flags, function(t) { map[tupleid(t)] = 1; }); + return function(t) { return map[tupleid(t)] ? null : t; }; +} + +/** + * Visit one or more tuple sets in this pulse. + * @param {number} flags - Flags indicating the tuple set(s) to visit. + * Legal values are ADD, REM, MOD and SOURCE (if a backing data source + * has been set). + * @param {function(object):*} - Visitor function invoked per-tuple. + * @return {Pulse} - Returns this pulse instance. + */ +prototype$4.visit = function(flags, visitor) { + var p = this, v = visitor, src, sum; + + if (flags & SOURCE) { + visitArray(p.source, p.srcF, v); + return p; + } + + if (flags & ADD) visitArray(p.add, p.addF, v); + if (flags & REM) visitArray(p.rem, p.remF, v); + if (flags & MOD) visitArray(p.mod, p.modF, v); + + if ((flags & REFLOW) && (src = p.source)) { + sum = p.add.length + p.mod.length; + if (sum === src.length) { + // do nothing + } else if (sum) { + visitArray(src, filter(p, ADD_MOD), v); + } else { + // if no add/rem/mod tuples, visit source + visitArray(src, p.srcF, v); + } + } + + return p; +}; + +/** + * Represents a set of multiple pulses. Used as input for operators + * that accept multiple pulses at a time. Contained pulses are + * accessible via the public "pulses" array property. This pulse doe + * not carry added, removed or modified tuples directly. However, + * the visit method can be used to traverse all such tuples contained + * in sub-pulses with a timestamp matching this parent multi-pulse. + * @constructor + * @param {Dataflow} dataflow - The backing dataflow instance. + * @param {number} stamp - The timestamp. + * @param {Array} pulses - The sub-pulses for this multi-pulse. + */ +function MultiPulse(dataflow, stamp, pulses, encode) { + var p = this, + c = 0, + pulse, hash, i, n, f; + + this.dataflow = dataflow; + this.stamp = stamp; + this.fields = null; + this.encode = encode || null; + this.pulses = pulses; + + for (i=0, n=pulses.length; i= Info) { + dt = Date.now(); + df.debug('-- START PROPAGATION (' + df._clock + ') -----'); + } + + // initialize queue, reset touched operators + df._touched.forEach(function(op) { df._enqueue(op, true); }); + df._touched = UniqueList(id); + + try { + while (df._heap.size() > 0) { + op = df._heap.pop(); + + // re-queue if rank changes + if (op.rank !== op.qrank) { df._enqueue(op, true); continue; } + + // otherwise, evaluate the operator + next = op.run(df._getPulse(op, encode)); + + if (level >= Debug) { + df.debug(op.id, next === StopPropagation ? 'STOP' : next, op); + } + + // propagate the pulse + if (next !== StopPropagation) { + df._pulse = next; + if (op._targets) op._targets.forEach(function(op) { df._enqueue(op); }); + } + + // increment visit counter + ++count; + } + } catch (err) { + error = err; + } + + // reset pulse map + df._pulses = {}; + df._pulse = null; + + if (level >= Info) { + dt = Date.now() - dt; + df.info('> Pulse ' + df._clock + ': ' + count + ' operators; ' + dt + 'ms'); + } + + if (error) { + df._postrun = []; + df.error(error); + } + + if (df._onrun) { + try { df._onrun(df, count, error); } catch (err) { df.error(err); } + } + + // invoke callbacks queued via runAfter + if (df._postrun.length) { + var postrun = df._postrun; + df._postrun = []; + postrun + .sort(function(a, b) { return b.priority - a.priority; }) + .forEach(function(_) { invokeCallback(df, _.callback); }); + } + + return count; +} + +function invokeCallback(df, callback) { + try { callback(df); } catch (err) { df.error(err); } +} + +/** + * Runs the dataflow and returns a Promise that resolves when the + * propagation cycle completes. The standard run method may exit early + * if there are pending data loading operations. In contrast, this + * method returns a Promise to allow callers to receive notification + * when dataflow evaluation completes. + * @return {Promise} - A promise that resolves to this dataflow. + */ +function runAsync() { + return this._pending || Promise.resolve(this.run()); +} + +/** + * Schedules a callback function to be invoked after the current pulse + * propagation completes. If no propagation is currently occurring, + * the function is invoked immediately. + * @param {function(Dataflow)} callback - The callback function to run. + * The callback will be invoked with this Dataflow instance as its + * sole argument. + * @param {boolean} enqueue - A boolean flag indicating that the + * callback should be queued up to run after the next propagation + * cycle, suppressing immediate invocation when propagation is not + * currently occurring. + */ +function runAfter(callback, enqueue, priority) { + if (this._pulse || enqueue) { + // pulse propagation is currently running, queue to run after + this._postrun.push({ + priority: priority || 0, + callback: callback + }); + } else { + // pulse propagation already complete, invoke immediately + invokeCallback(this, callback); + } +} + +/** + * Enqueue an operator into the priority queue for evaluation. The operator + * will be enqueued if it has no registered pulse for the current cycle, or if + * the force argument is true. Upon enqueue, this method also sets the + * operator's qrank to the current rank value. + * @param {Operator} op - The operator to enqueue. + * @param {boolean} [force] - A flag indicating if the operator should be + * forceably added to the queue, even if it has already been previously + * enqueued during the current pulse propagation. This is useful when the + * dataflow graph is dynamically modified and the operator rank changes. + */ +function enqueue(op, force) { + var p = !this._pulses[op.id]; + if (p) this._pulses[op.id] = this._pulse; + if (p || force) { + op.qrank = op.rank; + this._heap.push(op); + } +} + +/** + * Provide a correct pulse for evaluating an operator. If the operator has an + * explicit source operator, we will try to pull the pulse(s) from it. + * If there is an array of source operators, we build a multi-pulse. + * Otherwise, we return a current pulse with correct source data. + * If the pulse is the pulse map has an explicit target set, we use that. + * Else if the pulse on the upstream source operator is current, we use that. + * Else we use the pulse from the pulse map, but copy the source tuple array. + * @param {Operator} op - The operator for which to get an input pulse. + * @param {string} [encode] - An (optional) encoding set name with which to + * annotate the returned pulse. See {@link run} for more information. + */ +function getPulse(op, encode) { + var s = op.source, + stamp = this._clock, + p; + + if (s && isArray(s)) { + p = s.map(function(_) { return _.pulse; }); + return new MultiPulse(this, stamp, p, encode); + } + + p = this._pulses[op.id]; + if (s) { + s = s.pulse; + if (!s || s === StopPropagation) { + p.source = []; + } else if (s.stamp === stamp && p.target !== op) { + p = s; + } else { + p.source = s.source; + } + } + + return p; +} + +var NO_OPT = {skip: false, force: false}; + +/** + * Touches an operator, scheduling it to be evaluated. If invoked outside of + * a pulse propagation, the operator will be evaluated the next time this + * dataflow is run. If invoked in the midst of pulse propagation, the operator + * will be queued for evaluation if and only if the operator has not yet been + * evaluated on the current propagation timestamp. + * @param {Operator} op - The operator to touch. + * @param {object} [options] - Additional options hash. + * @param {boolean} [options.skip] - If true, the operator will + * be skipped: it will not be evaluated, but its dependents will be. + * @return {Dataflow} + */ +function touch(op, options) { + var opt = options || NO_OPT; + if (this._pulse) { + // if in midst of propagation, add to priority queue + this._enqueue(op); + } else { + // otherwise, queue for next propagation + this._touched.add(op); + } + if (opt.skip) op.skip(true); + return this; +} + +/** + * Updates the value of the given operator. + * @param {Operator} op - The operator to update. + * @param {*} value - The value to set. + * @param {object} [options] - Additional options hash. + * @param {boolean} [options.force] - If true, the operator will + * be re-evaluated even if its value has not changed. + * @param {boolean} [options.skip] - If true, the operator will + * be skipped: it will not be evaluated, but its dependents will be. + * @return {Dataflow} + */ +function update(op, value, options) { + var opt = options || NO_OPT; + if (op.set(value) || opt.force) { + this.touch(op, opt); + } + return this; +} + +/** + * Pulses an operator with a changeset of tuples. If invoked outside of + * a pulse propagation, the pulse will be applied the next time this + * dataflow is run. If invoked in the midst of pulse propagation, the pulse + * will be added to the set of active pulses and will be applied if and + * only if the target operator has not yet been evaluated on the current + * propagation timestamp. + * @param {Operator} op - The operator to pulse. + * @param {ChangeSet} value - The tuple changeset to apply. + * @param {object} [options] - Additional options hash. + * @param {boolean} [options.skip] - If true, the operator will + * be skipped: it will not be evaluated, but its dependents will be. + * @return {Dataflow} + */ +function pulse(op, changeset, options) { + this.touch(op, options || NO_OPT); + + var p = new Pulse(this, this._clock + (this._pulse ? 0 : 1)), + t = op.pulse && op.pulse.source || []; + p.target = op; + this._pulses[op.id] = changeset.pulse(p, t); + + return this; +} + +function Heap(comparator) { + this.cmp = comparator; + this.nodes = []; +} + +var prototype$6 = Heap.prototype; + +prototype$6.size = function() { + return this.nodes.length; +}; + +prototype$6.clear = function() { + this.nodes = []; + return this; +}; + +prototype$6.peek = function() { + return this.nodes[0]; +}; + +prototype$6.push = function(x) { + var array = this.nodes; + array.push(x); + return siftdown(array, 0, array.length-1, this.cmp); +}; + +prototype$6.pop = function() { + var array = this.nodes, + last = array.pop(), + item; + + if (array.length) { + item = array[0]; + array[0] = last; + siftup(array, 0, this.cmp); + } else { + item = last; + } + return item; +}; + +prototype$6.replace = function(item) { + var array = this.nodes, + retval = array[0]; + array[0] = item; + siftup(array, 0, this.cmp); + return retval; +}; + +prototype$6.pushpop = function(item) { + var array = this.nodes, ref = array[0]; + if (array.length && this.cmp(ref, item) < 0) { + array[0] = item; + item = ref; + siftup(array, 0, this.cmp); + } + return item; +}; + +function siftdown(array, start, idx, cmp) { + var item, parent, pidx; + + item = array[idx]; + while (idx > start) { + pidx = (idx - 1) >> 1; + parent = array[pidx]; + if (cmp(item, parent) < 0) { + array[idx] = parent; + idx = pidx; + continue; + } + break; + } + return (array[idx] = item); +} + +function siftup(array, idx, cmp) { + var start = idx, + end = array.length, + item = array[idx], + cidx = 2 * idx + 1, ridx; + + while (cidx < end) { + ridx = cidx + 1; + if (ridx < end && cmp(array[cidx], array[ridx]) >= 0) { + cidx = ridx; + } + array[idx] = array[cidx]; + idx = cidx; + cidx = 2 * idx + 1; + } + array[idx] = item; + return siftdown(array, start, idx, cmp); +} + +/** + * A dataflow graph for reactive processing of data streams. + * @constructor + */ +function Dataflow() { + this._log = logger(); + this.logLevel(Error$1); + + this._clock = 0; + this._rank = 0; + try { + this._loader = loader(); + } catch (e) { + // do nothing if loader module is unavailable + } + + this._touched = UniqueList(id); + this._pulses = {}; + this._pulse = null; + + this._heap = new Heap(function(a, b) { return a.qrank - b.qrank; }); + this._postrun = []; +} + +var prototype = Dataflow.prototype; + +/** + * The current timestamp of this dataflow. This value reflects the + * timestamp of the previous dataflow run. The dataflow is initialized + * with a stamp value of 0. The initial run of the dataflow will have + * a timestap of 1, and so on. This value will match the + * {@link Pulse.stamp} property. + * @return {number} - The current timestamp value. + */ +prototype.stamp = function() { + return this._clock; +}; + +/** + * Gets or sets the loader instance to use for data file loading. A + * loader object must provide a "load" method for loading files and a + * "sanitize" method for checking URL/filename validity. Both methods + * should accept a URI and options hash as arguments, and return a Promise + * that resolves to the loaded file contents (load) or a hash containing + * sanitized URI data with the sanitized url assigned to the "href" property + * (sanitize). + * @param {object} _ - The loader instance to use. + * @return {object|Dataflow} - If no arguments are provided, returns + * the current loader instance. Otherwise returns this Dataflow instance. + */ +prototype.loader = function(_) { + if (arguments.length) { + this._loader = _; + return this; + } else { + return this._loader; + } +}; + +/** + * Empty entry threshold for garbage cleaning. Map data structures will + * perform cleaning once the number of empty entries exceeds this value. + */ +prototype.cleanThreshold = 1e4; + +// OPERATOR REGISTRATION +prototype.add = add; +prototype.connect = connect; +prototype.rank = rank; +prototype.rerank = rerank; + +// OPERATOR UPDATES +prototype.pulse = pulse; +prototype.touch = touch; +prototype.update = update; +prototype.changeset = changeset; + +// DATA LOADING +prototype.ingest = ingest$1; +prototype.request = request; + +// EVENT HANDLING +prototype.events = events; +prototype.on = on; + +// PULSE PROPAGATION +prototype.run = run; +prototype.runAsync = runAsync; +prototype.runAfter = runAfter; +prototype._enqueue = enqueue; +prototype._getPulse = getPulse; + +// LOGGING AND ERROR HANDLING + +function logMethod(method) { + return function() { + return this._log[method].apply(this, arguments); + }; +} + +/** + * Logs an error message. By default, logged messages are written to console + * output. The message will only be logged if the current log level is high + * enough to permit error messages. + */ +prototype.error = logMethod('error'); + +/** + * Logs a warning message. By default, logged messages are written to console + * output. The message will only be logged if the current log level is high + * enough to permit warning messages. + */ +prototype.warn = logMethod('warn'); + +/** + * Logs a information message. By default, logged messages are written to + * console output. The message will only be logged if the current log level is + * high enough to permit information messages. + */ +prototype.info = logMethod('info'); + +/** + * Logs a debug message. By default, logged messages are written to console + * output. The message will only be logged if the current log level is high + * enough to permit debug messages. + */ +prototype.debug = logMethod('debug'); + +/** + * Get or set the current log level. If an argument is provided, it + * will be used as the new log level. + * @param {number} [level] - Should be one of None, Warn, Info + * @return {number} - The current log level. + */ +prototype.logLevel = logMethod('level'); + +/** + * Abstract class for operators that process data tuples. + * Subclasses must provide a {@link transform} method for operator processing. + * @constructor + * @param {*} [init] - The initial value for this operator. + * @param {object} [params] - The parameters for this operator. + * @param {Operator} [source] - The operator from which to receive pulses. + */ +function Transform(init, params) { + Operator.call(this, init, null, params); +} + +var prototype$7 = inherits(Transform, Operator); + +/** + * Overrides {@link Operator.evaluate} for transform operators. + * Internally, this method calls {@link evaluate} to perform processing. + * If {@link evaluate} returns a falsy value, the input pulse is returned. + * This method should NOT be overridden, instead overrride {@link evaluate}. + * @param {Pulse} pulse - the current dataflow pulse. + * @return the output pulse for this operator (or StopPropagation) + */ +prototype$7.run = function(pulse) { + if (pulse.stamp <= this.stamp) return pulse.StopPropagation; + + var rv; + if (this.skip()) { + this.skip(false); + } else { + rv = this.evaluate(pulse); + } + rv = rv || pulse; + + if (rv !== pulse.StopPropagation) this.pulse = rv; + this.stamp = pulse.stamp; + + return rv; +}; + +/** + * Overrides {@link Operator.evaluate} for transform operators. + * Marshalls parameter values and then invokes {@link transform}. + * @param {Pulse} pulse - the current dataflow pulse. + * @return {Pulse} The output pulse (or StopPropagation). A falsy return + value (including undefined) will let the input pulse pass through. + */ +prototype$7.evaluate = function(pulse) { + var params = this.marshall(pulse.stamp), + out = this.transform(params, pulse); + params.clear(); + return out; +}; + +/** + * Process incoming pulses. + * Subclasses should override this method to implement transforms. + * @param {Parameters} _ - The operator parameter values. + * @param {Pulse} pulse - The current dataflow pulse. + * @return {Pulse} The output pulse (or StopPropagation). A falsy return + * value (including undefined) will let the input pulse pass through. + */ +prototype$7.transform = function() {}; + +var transforms = {}; + +function definition(type) { + var t = transform$1(type); + return t && t.Definition || null; +} + +function transform$1(type) { + type = type && type.toLowerCase(); + return transforms.hasOwnProperty(type) ? transforms[type] : null; +} + +// Utilities + +function multikey(f) { + return function(x) { + var n = f.length, + i = 1, + k = String(f[0](x)); + + for (; i 1 ? this.dev / (this.valid-1) : 0', + req: ['mean'], idx: 1 + }), + 'variancep': measure({ + name: 'variancep', + set: 'this.valid > 1 ? this.dev / this.valid : 0', + req: ['variance'], idx: 2 + }), + 'stdev': measure({ + name: 'stdev', + set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0', + req: ['variance'], idx: 2 + }), + 'stdevp': measure({ + name: 'stdevp', + set: 'this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0', + req: ['variance'], idx: 2 + }), + 'stderr': measure({ + name: 'stderr', + set: 'this.valid > 1 ? Math.sqrt(this.dev / (this.valid * (this.valid-1))) : 0', + req: ['variance'], idx: 2 + }), + 'distinct': measure({ + name: 'distinct', + set: 'cell.data.distinct(this.get)', + req: ['values'], idx: 3 + }), + 'ci0': measure({ + name: 'ci0', + set: 'cell.data.ci0(this.get)', + req: ['values'], idx: 3 + }), + 'ci1': measure({ + name: 'ci1', + set: 'cell.data.ci1(this.get)', + req: ['values'], idx: 3 + }), + 'median': measure({ + name: 'median', + set: 'cell.data.q2(this.get)', + req: ['values'], idx: 3 + }), + 'q1': measure({ + name: 'q1', + set: 'cell.data.q1(this.get)', + req: ['values'], idx: 3 + }), + 'q3': measure({ + name: 'q3', + set: 'cell.data.q3(this.get)', + req: ['values'], idx: 3 + }), + 'argmin': measure({ + name: 'argmin', + init: 'this.argmin = null;', + add: 'if (v < this.min) this.argmin = t;', + rem: 'if (v <= this.min) this.argmin = null;', + set: 'this.argmin || cell.data.argmin(this.get)', + req: ['min'], str: ['values'], idx: 3 + }), + 'argmax': measure({ + name: 'argmax', + init: 'this.argmax = null;', + add: 'if (v > this.max) this.argmax = t;', + rem: 'if (v >= this.max) this.argmax = null;', + set: 'this.argmax || cell.data.argmax(this.get)', + req: ['max'], str: ['values'], idx: 3 + }), + 'min': measure({ + name: 'min', + init: 'this.min = null;', + add: 'if (v < this.min || this.min === null) this.min = v;', + rem: 'if (v <= this.min) this.min = NaN;', + set: 'this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)', + str: ['values'], idx: 4 + }), + 'max': measure({ + name: 'max', + init: 'this.max = null;', + add: 'if (v > this.max || this.max === null) this.max = v;', + rem: 'if (v >= this.max) this.max = NaN;', + set: 'this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)', + str: ['values'], idx: 4 + }) +}; + +var ValidAggregateOps = Object.keys(AggregateOps); + +function createMeasure(op, name) { + return AggregateOps[op](name); +} + +function measure(base) { + return function(out) { + var m = extend({init:'', add:'', rem:'', idx:0}, base); + m.out = out || base.name; + return m; + }; +} + +function compareIndex(a, b) { + return a.idx - b.idx; +} + +function resolve(agg, stream) { + function collect(m, a) { + function helper(r) { if (!m[r]) collect(m, m[r] = AggregateOps[r]()); } + if (a.req) a.req.forEach(helper); + if (stream && a.str) a.str.forEach(helper); + return m; + } + var map = agg.reduce( + collect, + agg.reduce(function(m, a) { + m[a.name] = a; + return m; + }, {}) + ); + var values = [], key$$1; + for (key$$1 in map) values.push(map[key$$1]); + return values.sort(compareIndex); +} + +function compileMeasures(agg, field$$1) { + var get = field$$1 || identity, + all = resolve(agg, true), // assume streaming removes may occur + init = 'var cell = this.cell; this.valid = 0; this.missing = 0;', + ctr = 'this.cell = cell; this.init();', + add = 'if(v==null){++this.missing; return;} if(v!==v) return; ++this.valid;', + rem = 'if(v==null){--this.missing; return;} if(v!==v) return; --this.valid;', + set = 'var cell = this.cell;'; + + all.forEach(function(a) { + init += a.init; + add += a.add; + rem += a.rem; + }); + agg.slice().sort(compareIndex).forEach(function(a) { + set += 't[\'' + a.out + '\']=' + a.set + ';'; + }); + set += 'return t;'; + + ctr = Function('cell', ctr); + ctr.prototype.init = Function(init); + ctr.prototype.add = Function('v', 't', add); + ctr.prototype.rem = Function('v', 't', rem); + ctr.prototype.set = Function('t', set); + ctr.prototype.get = get; + ctr.fields = agg.map(function(_) { return _.out; }); + return ctr; +} + +var bin = function(_) { + // determine range + var maxb = _.maxbins || 20, + base = _.base || 10, + logb = Math.log(base), + div = _.divide || [5, 2], + min = _.extent[0], + max = _.extent[1], + span = max - min, + step, level, minstep, precision, v, i, n, eps; + + if (_.step) { + // if step size is explicitly given, use that + step = _.step; + } else if (_.steps) { + // if provided, limit choice to acceptable step sizes + v = span / maxb; + for (i=0, n=_.steps.length; i < n && _.steps[i] < v; ++i); + step = _.steps[Math.max(0, i-1)]; + } else { + // else use span to determine step size + level = Math.ceil(Math.log(maxb) / logb); + minstep = _.minstep || 0; + step = Math.max( + minstep, + Math.pow(base, Math.round(Math.log(span) / logb) - level) + ); + + // increase step size if too many bins + while (Math.ceil(span/step) > maxb) { step *= base; } + + // decrease step size if allowed + for (i=0, n=div.length; i= minstep && span / v <= maxb) step = v; + } + } + + // update precision, min and max + v = Math.log(step); + precision = v >= 0 ? 0 : ~~(-v / logb) + 1; + eps = Math.pow(base, -precision - 1); + if (_.nice || _.nice === undefined) { + v = Math.floor(min / step + eps) * step; + min = min < v ? v - step : v; + max = Math.ceil(max / step) * step; + } + + return { + start: min, + stop: max, + step: step + }; +}; + +var numbers = function(array, f) { + var numbers = [], + n = array.length, + i = -1, a; + + if (f == null) { + while (++i < n) if (!isNaN(a = number(array[i]))) numbers.push(a); + } else { + while (++i < n) if (!isNaN(a = number(f(array[i], i, array)))) numbers.push(a); + } + return numbers; +}; + +function number(x) { + return x === null ? NaN : +x; +} + +exports.random = Math.random; + +function setRandom(r) { + exports.random = r; +} + +var ascending = function(a, b) { + return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN; +}; + +var bisector = function(compare) { + if (compare.length === 1) compare = ascendingComparator(compare); + return { + left: function(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) < 0) lo = mid + 1; + else hi = mid; + } + return lo; + }, + right: function(a, x, lo, hi) { + if (lo == null) lo = 0; + if (hi == null) hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (compare(a[mid], x) > 0) hi = mid; + else lo = mid + 1; + } + return lo; + } + }; +}; + +function ascendingComparator(f) { + return function(d, x) { + return ascending(f(d), x); + }; +} + +var ascendingBisect = bisector(ascending); +var bisectRight = ascendingBisect.right; +var bisectLeft = ascendingBisect.left; + +function pair(a, b) { + return [a, b]; +} + +var number$1 = function(x) { + return x === null ? NaN : +x; +}; + +var variance = function(values, valueof) { + var n = values.length, + m = 0, + i = -1, + mean = 0, + value, + delta, + sum = 0; + + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number$1(values[i]))) { + delta = value - mean; + mean += delta / ++m; + sum += delta * (value - mean); + } + } + } + + else { + while (++i < n) { + if (!isNaN(value = number$1(valueof(values[i], i, values)))) { + delta = value - mean; + mean += delta / ++m; + sum += delta * (value - mean); + } + } + } + + if (m > 1) return sum / (m - 1); +}; + +var extent = function(values, valueof) { + var n = values.length, + i = -1, + value, + min, + max; + + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + min = max = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null) { + if (min > value) min = value; + if (max < value) max = value; + } + } + } + } + } + + else { + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + min = max = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null) { + if (min > value) min = value; + if (max < value) max = value; + } + } + } + } + } + + return [min, max]; +}; + +var identity$2 = function(x) { + return x; +}; + +var sequence = function(start, stop, step) { + start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step; + + var i = -1, + n = Math.max(0, Math.ceil((stop - start) / step)) | 0, + range = new Array(n); + + while (++i < n) { + range[i] = start + i * step; + } + + return range; +}; + +var e10 = Math.sqrt(50); +var e5 = Math.sqrt(10); +var e2$1 = Math.sqrt(2); + +var ticks = function(start, stop, count) { + var reverse, + i = -1, + n, + ticks, + step; + + stop = +stop, start = +start, count = +count; + if (start === stop && count > 0) return [start]; + if (reverse = stop < start) n = start, start = stop, stop = n; + if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return []; + + if (step > 0) { + start = Math.ceil(start / step); + stop = Math.floor(stop / step); + ticks = new Array(n = Math.ceil(stop - start + 1)); + while (++i < n) ticks[i] = (start + i) * step; + } else { + start = Math.floor(start * step); + stop = Math.ceil(stop * step); + ticks = new Array(n = Math.ceil(start - stop + 1)); + while (++i < n) ticks[i] = (start - i) / step; + } + + if (reverse) ticks.reverse(); + + return ticks; +}; + +function tickIncrement(start, stop, count) { + var step = (stop - start) / Math.max(0, count), + power = Math.floor(Math.log(step) / Math.LN10), + error = step / Math.pow(10, power); + return power >= 0 + ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2$1 ? 2 : 1) * Math.pow(10, power) + : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2$1 ? 2 : 1); +} + +function tickStep(start, stop, count) { + var step0 = Math.abs(stop - start) / Math.max(0, count), + step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)), + error = step0 / step1; + if (error >= e10) step1 *= 10; + else if (error >= e5) step1 *= 5; + else if (error >= e2$1) step1 *= 2; + return stop < start ? -step1 : step1; +} + +var thresholdSturges = function(values) { + return Math.ceil(Math.log(values.length) / Math.LN2) + 1; +}; + +var threshold = function(values, p, valueof) { + if (valueof == null) valueof = number$1; + if (!(n = values.length)) return; + if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values); + if (p >= 1) return +valueof(values[n - 1], n - 1, values); + var n, + i = (n - 1) * p, + i0 = Math.floor(i), + value0 = +valueof(values[i0], i0, values), + value1 = +valueof(values[i0 + 1], i0 + 1, values); + return value0 + (value1 - value0) * (i - i0); +}; + +var max = function(values, valueof) { + var n = values.length, + i = -1, + value, + max; + + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + max = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null && value > max) { + max = value; + } + } + } + } + } + + else { + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + max = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null && value > max) { + max = value; + } + } + } + } + } + + return max; +}; + +var mean = function(values, valueof) { + var n = values.length, + m = n, + i = -1, + value, + sum = 0; + + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number$1(values[i]))) sum += value; + else --m; + } + } + + else { + while (++i < n) { + if (!isNaN(value = number$1(valueof(values[i], i, values)))) sum += value; + else --m; + } + } + + if (m) return sum / m; +}; + +var median = function(values, valueof) { + var n = values.length, + i = -1, + value, + numbers = []; + + if (valueof == null) { + while (++i < n) { + if (!isNaN(value = number$1(values[i]))) { + numbers.push(value); + } + } + } + + else { + while (++i < n) { + if (!isNaN(value = number$1(valueof(values[i], i, values)))) { + numbers.push(value); + } + } + } + + return threshold(numbers.sort(ascending), 0.5); +}; + +var merge$2 = function(arrays) { + var n = arrays.length, + m, + i = -1, + j = 0, + merged, + array; + + while (++i < n) j += arrays[i].length; + merged = new Array(j); + + while (--n >= 0) { + array = arrays[n]; + m = array.length; + while (--m >= 0) { + merged[--j] = array[m]; + } + } + + return merged; +}; + +var min = function(values, valueof) { + var n = values.length, + i = -1, + value, + min; + + if (valueof == null) { + while (++i < n) { // Find the first comparable value. + if ((value = values[i]) != null && value >= value) { + min = value; + while (++i < n) { // Compare the remaining values. + if ((value = values[i]) != null && min > value) { + min = value; + } + } + } + } + } + + else { + while (++i < n) { // Find the first comparable value. + if ((value = valueof(values[i], i, values)) != null && value >= value) { + min = value; + while (++i < n) { // Compare the remaining values. + if ((value = valueof(values[i], i, values)) != null && min > value) { + min = value; + } + } + } + } + } + + return min; +}; + +var permute = function(array, indexes) { + var i = indexes.length, permutes = new Array(i); + while (i--) permutes[i] = array[indexes[i]]; + return permutes; +}; + +var sum = function(values, valueof) { + var n = values.length, + i = -1, + value, + sum = 0; + + if (valueof == null) { + while (++i < n) { + if (value = +values[i]) sum += value; // Note: zero and null are equivalent. + } + } + + else { + while (++i < n) { + if (value = +valueof(values[i], i, values)) sum += value; + } + } + + return sum; +}; + +function length(d) { + return d.length; +} + +var bootstrapCI = function(array, samples, alpha, f) { + var values = numbers(array, f), + n = values.length, + m = samples, + a, i, j, mu; + + for (j=0, mu=Array(m); j= a && x < b) ? 1 / d : 0; + }; + + dist.cdf = function(x) { + var v = Math.floor(x); + return v < a ? 0 : v >= b ? 1 : (v - a + 1) / d; + }; + + dist.icdf = function(p) { + return (p >= 0 && p <= 1) ? a - 1 + Math.floor(p * d) : NaN; + }; + + return dist.min(min).max(max); +}; + +var randomNormal = function(mean, stdev) { + var mu, + sigma, + next = NaN, + dist = {}; + + dist.mean = function(_) { + if (arguments.length) { + mu = _ || 0; + next = NaN; + return dist; + } else { + return mu; + } + }; + + dist.stdev = function(_) { + if (arguments.length) { + sigma = _ == null ? 1 : _; + next = NaN; + return dist; + } else { + return sigma; + } + }; + + dist.sample = function() { + var x = 0, y = 0, rds, c; + if (next === next) { + x = next; + next = NaN; + return x; + } + do { + x = exports.random() * 2 - 1; + y = exports.random() * 2 - 1; + rds = x * x + y * y; + } while (rds === 0 || rds > 1); + c = Math.sqrt(-2 * Math.log(rds) / rds); // Box-Muller transform + next = mu + y * c * sigma; + return mu + x * c * sigma; + }; + + dist.pdf = function(x) { + var exp = Math.exp(Math.pow(x-mu, 2) / (-2 * Math.pow(sigma, 2))); + return (1 / (sigma * Math.sqrt(2*Math.PI))) * exp; + }; + + // Approximation from West (2009) + // Better Approximations to Cumulative Normal Functions + dist.cdf = function(x) { + var cd, + z = (x - mu) / sigma, + Z = Math.abs(z); + if (Z > 37) { + cd = 0; + } else { + var sum, exp = Math.exp(-Z*Z/2); + if (Z < 7.07106781186547) { + sum = 3.52624965998911e-02 * Z + 0.700383064443688; + sum = sum * Z + 6.37396220353165; + sum = sum * Z + 33.912866078383; + sum = sum * Z + 112.079291497871; + sum = sum * Z + 221.213596169931; + sum = sum * Z + 220.206867912376; + cd = exp * sum; + sum = 8.83883476483184e-02 * Z + 1.75566716318264; + sum = sum * Z + 16.064177579207; + sum = sum * Z + 86.7807322029461; + sum = sum * Z + 296.564248779674; + sum = sum * Z + 637.333633378831; + sum = sum * Z + 793.826512519948; + sum = sum * Z + 440.413735824752; + cd = cd / sum; + } else { + sum = Z + 0.65; + sum = Z + 4 / sum; + sum = Z + 3 / sum; + sum = Z + 2 / sum; + sum = Z + 1 / sum; + cd = exp / sum / 2.506628274631; + } + } + return z > 0 ? 1 - cd : cd; + }; + + // Approximation of Probit function using inverse error function. + dist.icdf = function(p) { + if (p <= 0 || p >= 1) return NaN; + var x = 2*p - 1, + v = (8 * (Math.PI - 3)) / (3 * Math.PI * (4-Math.PI)), + a = (2 / (Math.PI*v)) + (Math.log(1 - Math.pow(x,2)) / 2), + b = Math.log(1 - (x*x)) / v, + s = (x > 0 ? 1 : -1) * Math.sqrt(Math.sqrt((a*a) - b) - a); + return mu + sigma * Math.SQRT2 * s; + }; + + return dist.mean(mean).stdev(stdev); +}; + +// TODO: support for additional kernels? +var randomKDE = function(support, bandwidth) { + var kernel = randomNormal(), + dist = {}, + n = 0; + + dist.data = function(_) { + if (arguments.length) { + support = _; + n = _ ? _.length : 0; + return dist.bandwidth(bandwidth); + } else { + return support; + } + }; + + dist.bandwidth = function(_) { + if (!arguments.length) return bandwidth; + bandwidth = _; + if (!bandwidth && support) bandwidth = estimateBandwidth(support); + return dist; + }; + + dist.sample = function() { + return support[~~(exports.random() * n)] + bandwidth * kernel.sample(); + }; + + dist.pdf = function(x) { + for (var y=0, i=0; i= a && x <= b) ? 1 / d : 0; + }; + + dist.cdf = function(x) { + return x < a ? 0 : x > b ? 1 : (x - a) / d; + }; + + dist.icdf = function(p) { + return (p >= 0 && p <= 1) ? a + p * d : NaN; + }; + + return dist.min(min).max(max); +}; + +function TupleStore(key$$1) { + this._key = key$$1 ? field(key$$1) : tupleid; + this.reset(); +} + +var prototype$9 = TupleStore.prototype; + +prototype$9.reset = function() { + this._add = []; + this._rem = []; + this._ext = null; + this._get = null; + this._q = null; +}; + +prototype$9.add = function(v) { + this._add.push(v); +}; + +prototype$9.rem = function(v) { + this._rem.push(v); +}; + +prototype$9.values = function() { + this._get = null; + if (this._rem.length === 0) return this._add; + + var a = this._add, + r = this._rem, + k = this._key, + n = a.length, + m = r.length, + x = Array(n - m), + map = {}, i, j, v; + + // use unique key field to clear removed values + for (i=0; i= 0) { + s = get(v[n]) + ''; + if (!map.hasOwnProperty(s)) { + map[s] = 1; + ++count; + } + } + + return count; +}; + +prototype$9.extent = function(get) { + if (this._get !== get || !this._ext) { + var v = this.values(), + i = extentIndex(v, get); + this._ext = [v[i[0]], v[i[1]]]; + this._get = get; + } + return this._ext; +}; + +prototype$9.argmin = function(get) { + return this.extent(get)[0] || {}; +}; + +prototype$9.argmax = function(get) { + return this.extent(get)[1] || {}; +}; + +prototype$9.min = function(get) { + var m = this.extent(get)[0]; + return m != null ? get(m) : +Infinity; +}; + +prototype$9.max = function(get) { + var m = this.extent(get)[1]; + return m != null ? get(m) : -Infinity; +}; + +prototype$9.quartile = function(get) { + if (this._get !== get || !this._q) { + this._q = quartiles(this.values(), get); + this._get = get; + } + return this._q; +}; + +prototype$9.q1 = function(get) { + return this.quartile(get)[0]; +}; + +prototype$9.q2 = function(get) { + return this.quartile(get)[1]; +}; + +prototype$9.q3 = function(get) { + return this.quartile(get)[2]; +}; + +prototype$9.ci = function(get) { + if (this._get !== get || !this._ci) { + this._ci = bootstrapCI(this.values(), 1000, 0.05, get); + this._get = get; + } + return this._ci; +}; + +prototype$9.ci0 = function(get) { + return this.ci(get)[0]; +}; + +prototype$9.ci1 = function(get) { + return this.ci(get)[1]; +}; + +/** + * Group-by aggregation operator. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} [params.groupby] - An array of accessors to groupby. + * @param {Array} [params.fields] - An array of accessors to aggregate. + * @param {Array} [params.ops] - An array of strings indicating aggregation operations. + * @param {Array} [params.as] - An array of output field names for aggregated values. + * @param {boolean} [params.cross=false] - A flag indicating that the full + * cross-product of groupby values should be generated, including empty cells. + * If true, the drop parameter is ignored and empty cells are retained. + * @param {boolean} [params.drop=true] - A flag indicating if empty cells should be removed. + */ +function Aggregate(params) { + Transform.call(this, null, params); + + this._adds = []; // array of added output tuples + this._mods = []; // array of modified output tuples + this._alen = 0; // number of active added tuples + this._mlen = 0; // number of active modified tuples + this._drop = true; // should empty aggregation cells be removed + this._cross = false; // produce full cross-product of group-by values + + this._dims = []; // group-by dimension accessors + this._dnames = []; // group-by dimension names + + this._measures = []; // collection of aggregation monoids + this._countOnly = false; // flag indicating only count aggregation + this._counts = null; // collection of count fields + this._prev = null; // previous aggregation cells + + this._inputs = null; // array of dependent input tuple field names + this._outputs = null; // array of output tuple field names +} + +Aggregate.Definition = { + "type": "Aggregate", + "metadata": {"generates": true, "changes": true}, + "params": [ + { "name": "groupby", "type": "field", "array": true }, + { "name": "ops", "type": "enum", "array": true, "values": ValidAggregateOps }, + { "name": "fields", "type": "field", "null": true, "array": true }, + { "name": "as", "type": "string", "null": true, "array": true }, + { "name": "drop", "type": "boolean", "default": true }, + { "name": "cross", "type": "boolean", "default": false }, + { "name": "key", "type": "field" } + ] +}; + +var prototype$8 = inherits(Aggregate, Transform); + +prototype$8.transform = function(_, pulse) { + var aggr = this, + out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS), + mod; + + this.stamp = out.stamp; + + if (this.value && ((mod = _.modified()) || pulse.modified(this._inputs))) { + this._prev = this.value; + this.value = mod ? this.init(_) : {}; + pulse.visit(pulse.SOURCE, function(t) { aggr.add(t); }); + } else { + this.value = this.value || this.init(_); + pulse.visit(pulse.REM, function(t) { aggr.rem(t); }); + pulse.visit(pulse.ADD, function(t) { aggr.add(t); }); + } + + // Indicate output fields and return aggregate tuples. + out.modifies(this._outputs); + + // Should empty cells be dropped? + aggr._drop = _.drop !== false; + + // If domain cross-product requested, generate empty cells as needed + // and ensure that empty cells are not dropped + if (_.cross && aggr._dims.length > 1) { + aggr._drop = false; + this.cross(); + } + + return aggr.changes(out); +}; + +prototype$8.cross = function() { + var aggr = this, + curr = aggr.value, + dims = aggr._dnames, + vals = dims.map(function() { return {}; }), + n = dims.length; + + // collect all group-by domain values + function collect(cells) { + var key$$1, i, t, v; + for (key$$1 in cells) { + t = cells[key$$1].tuple; + for (i=0; i} params.fields - The fields to compare. + * @param {Array} [params.orders] - The sort orders. + * Each entry should be one of "ascending" (default) or "descending". + */ +function Compare(params) { + Operator.call(this, null, update$1, params); +} + +inherits(Compare, Operator); + +function update$1(_) { + return (this.value && !_.modified()) + ? this.value + : compare(_.fields, _.orders); +} + +/** + * Count regexp-defined pattern occurrences in a text field. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.field - An accessor for the text field. + * @param {string} [params.pattern] - RegExp string defining the text pattern. + * @param {string} [params.case] - One of 'lower', 'upper' or null (mixed) case. + * @param {string} [params.stopwords] - RegExp string of words to ignore. + */ +function CountPattern(params) { + Transform.call(this, null, params); +} + +CountPattern.Definition = { + "type": "CountPattern", + "metadata": {"generates": true, "changes": true}, + "params": [ + { "name": "field", "type": "field", "required": true }, + { "name": "case", "type": "enum", "values": ["upper", "lower", "mixed"], "default": "mixed" }, + { "name": "pattern", "type": "string", "default": "[\\w\"]+" }, + { "name": "stopwords", "type": "string", "default": "" }, + { "name": "as", "type": "string", "array": true, "length": 2, "default": ["text", "count"] } + ] +}; + +function tokenize(text, tcase, match) { + switch (tcase) { + case 'upper': text = text.toUpperCase(); break; + case 'lower': text = text.toLowerCase(); break; + } + return text.match(match); +} + +var prototype$12 = inherits(CountPattern, Transform); + +prototype$12.transform = function(_, pulse) { + function process(update) { + return function(tuple) { + var tokens = tokenize(get(tuple), _.case, match) || [], t; + for (var i=0, n=tokens.length; i} [params.as] - The names of the output fields. + */ +function Cross(params) { + Transform.call(this, null, params); +} + +Cross.Definition = { + "type": "Cross", + "metadata": {"generates": true}, + "params": [ + { "name": "filter", "type": "expr" }, + { "name": "as", "type": "string", "array": true, "length": 2, "default": ["a", "b"] } + ] +}; + +var prototype$13 = inherits(Cross, Transform); + +prototype$13.transform = function(_, pulse) { + var out = pulse.fork(pulse.NO_SOURCE), + data = this.value, + as = _.as || ['a', 'b'], + a = as[0], b = as[1], + reset = !data + || pulse.changed(pulse.ADD_REM) + || _.modified('as') + || _.modified('filter'); + + if (reset) { + if (data) out.rem = data; + data = pulse.materialize(pulse.SOURCE).source; + out.add = this.value = cross$1(data, a, b, _.filter || truthy); + } else { + out.mod = data; + } + + out.source = this.value; + return out.modifies(as); +}; + +function cross$1(input, a, b, filter) { + var data = [], + t = {}, + n = input.length, + i = 0, + j, left; + + for (; i} - A method for requesting + * source data. Used for distributions (such as KDE) that + * require sample data points. This method will only be + * invoked if the 'from' parameter for a target data source + * is not provided. Typically this method returns backing + * source data for a Pulse object. + * @return {object} - The output distribution object. + */ +function parse$1(def, data) { + var func = def[FUNCTION]; + if (!Distributions.hasOwnProperty(func)) { + error$1('Unknown distribution function: ' + func); + } + + var d = Distributions[func](); + + for (var name in def) { + // if data field, extract values + if (name === FIELD) { + d.data((def.from || data()).map(def[name])); + } + + // if distribution mixture, recurse to parse each definition + else if (name === DISTRIBUTIONS) { + d[name](def[name].map(function(_) { return parse$1(_, data); })); + } + + // otherwise, simply set the parameter + else if (typeof d[name] === FUNCTION) { + d[name](def[name]); + } + } + + return d; +} + +/** + * Grid sample points for a probability density. Given a distribution and + * a sampling extent, will generate points suitable for plotting either + * PDF (probability density function) or CDF (cumulative distribution + * function) curves. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {object} params.distribution - The probability distribution. This + * is an object parameter dependent on the distribution type. + * @param {string} [params.method='pdf'] - The distribution method to sample. + * One of 'pdf' or 'cdf'. + * @param {Array} [params.extent] - The [min, max] extent over which + * to sample the distribution. This argument is required in most cases, but + * can be omitted if the distribution (e.g., 'kde') supports a 'data' method + * that returns numerical sample points from which the extent can be deduced. + * @param {number} [params.steps=100] - The number of sampling steps. + */ +function Density(params) { + Transform.call(this, null, params); +} + +var distributions = [ + { + "key": {"function": "normal"}, + "params": [ + { "name": "mean", "type": "number", "default": 0 }, + { "name": "stdev", "type": "number", "default": 1 } + ] + }, + { + "key": {"function": "uniform"}, + "params": [ + { "name": "min", "type": "number", "default": 0 }, + { "name": "max", "type": "number", "default": 1 } + ] + }, + { + "key": {"function": "kde"}, + "params": [ + { "name": "field", "type": "field", "required": true }, + { "name": "from", "type": "data" }, + { "name": "bandwidth", "type": "number", "default": 0 } + ] + } +]; + +var mixture = { + "key": {"function": "mixture"}, + "params": [ + { "name": "distributions", "type": "param", "array": true, + "params": distributions }, + { "name": "weights", "type": "number", "array": true } + ] +}; + +Density.Definition = { + "type": "Density", + "metadata": {"generates": true}, + "params": [ + { "name": "extent", "type": "number", "array": true, "length": 2 }, + { "name": "steps", "type": "number", "default": 100 }, + { "name": "method", "type": "string", "default": "pdf", + "values": ["pdf", "cdf"] }, + { "name": "distribution", "type": "param", + "params": distributions.concat(mixture) }, + { "name": "as", "type": "string", "array": true, + "default": ["value", "density"] } + ] +}; + +var prototype$14 = inherits(Density, Transform); + +prototype$14.transform = function(_, pulse) { + var out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS); + + if (!this.value || pulse.changed() || _.modified()) { + var dist = parse$1(_.distribution, source(pulse)), + method = _.method || 'pdf'; + + if (method !== 'pdf' && method !== 'cdf') { + error$1('Invalid density method: ' + method); + } + if (!_.extent && !dist.data) { + error$1('Missing density extent parameter.'); + } + method = dist[method]; + + var as = _.as || ['value', 'density'], + domain = _.extent || extent(dist.data()), + step = (domain[1] - domain[0]) / (_.steps || 100), + values = sequence(domain[0], domain[1] + step/2, step) + .map(function(v) { + var tuple = {}; + tuple[as[0]] = v; + tuple[as[1]] = method(v); + return ingest(tuple); + }); + + if (this.value) out.rem = this.value; + this.value = out.add = out.source = values; + } + + return out; +}; + +function source(pulse) { + return function() { return pulse.materialize(pulse.SOURCE).source; }; +} + +/** + * Computes extents (min/max) for a data field. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.field - The field over which to compute extends. + */ +function Extent(params) { + Transform.call(this, [+Infinity, -Infinity], params); +} + +Extent.Definition = { + "type": "Extent", + "metadata": {}, + "params": [ + { "name": "field", "type": "field", "required": true } + ] +}; + +var prototype$15 = inherits(Extent, Transform); + +prototype$15.transform = function(_, pulse) { + var extent = this.value, + field$$1 = _.field, + min = extent[0], + max = extent[1], + flag = pulse.ADD, + mod; + + mod = pulse.changed() + || pulse.modified(field$$1.fields) + || _.modified('field'); + + if (mod) { + flag = pulse.SOURCE; + min = +Infinity; + max = -Infinity; + } + + pulse.visit(flag, function(t) { + var v = field$$1(t); + if (v != null) { + // coerce to number + v = +v; + // NaNs will fail all comparisons! + if (v < min) min = v; + if (v > max) max = v; + } + }); + + this.value = [min, max]; +}; + +/** + * Provides a bridge between a parent transform and a target subflow that + * consumes only a subset of the tuples that pass through the parent. + * @constructor + * @param {Pulse} pulse - A pulse to use as the value of this operator. + * @param {Transform} parent - The parent transform (typically a Facet instance). + * @param {Transform} target - A transform that receives the subflow of tuples. + */ +function Subflow(pulse, parent) { + Operator.call(this, pulse); + this.parent = parent; +} + +var prototype$17 = inherits(Subflow, Operator); + +prototype$17.connect = function(target) { + this.targets().add(target); + return (target.source = this); +}; + +/** + * Add an 'add' tuple to the subflow pulse. + * @param {Tuple} t - The tuple being added. + */ +prototype$17.add = function(t) { + this.value.add.push(t); +}; + +/** + * Add a 'rem' tuple to the subflow pulse. + * @param {Tuple} t - The tuple being removed. + */ +prototype$17.rem = function(t) { + this.value.rem.push(t); +}; + +/** + * Add a 'mod' tuple to the subflow pulse. + * @param {Tuple} t - The tuple being modified. + */ +prototype$17.mod = function(t) { + this.value.mod.push(t); +}; + +/** + * Re-initialize this operator's pulse value. + * @param {Pulse} pulse - The pulse to copy from. + * @see Pulse.init + */ +prototype$17.init = function(pulse) { + this.value.init(pulse, pulse.NO_SOURCE); +}; + +/** + * Evaluate this operator. This method overrides the + * default behavior to simply return the contained pulse value. + * @return {Pulse} + */ +prototype$17.evaluate = function() { + // assert: this.value.stamp === pulse.stamp + return this.value; +}; + +/** + * Facets a dataflow into a set of subflows based on a key. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(Dataflow, string): Operator} params.subflow - A function + * that generates a subflow of operators and returns its root operator. + * @param {function(object): *} params.key - The key field to facet by. + */ +function Facet(params) { + Transform.call(this, {}, params); + this._keys = fastmap(); // cache previously calculated key values + + // keep track of active subflows, use as targets array for listeners + // this allows us to limit propagation to only updated subflows + var a = this._targets = []; + a.active = 0; + a.forEach = function(f) { + for (var i=0, n=a.active; i df.cleanThreshold) df.runAfter(cache.clean); + return pulse; +}; + +/** + * Generates one or more field accessor functions. + * If the 'name' parameter is an array, an array of field accessors + * will be created and the 'as' parameter will be ignored. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {string} params.name - The field name(s) to access. + * @param {string} params.as - The accessor function name. + */ +function Field(params) { + Operator.call(this, null, update$2, params); +} + +inherits(Field, Operator); + +function update$2(_) { + return (this.value && !_.modified()) ? this.value + : isArray(_.name) ? array(_.name).map(function(f) { return field(f); }) + : field(_.name, _.as); +} + +/** + * Filters data tuples according to a predicate function. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.expr - The predicate expression function + * that determines a tuple's filter status. Truthy values pass the filter. + */ +function Filter(params) { + Transform.call(this, fastmap(), params); +} + +Filter.Definition = { + "type": "Filter", + "metadata": {"changes": true}, + "params": [ + { "name": "expr", "type": "expr", "required": true } + ] +}; + +var prototype$18 = inherits(Filter, Transform); + +prototype$18.transform = function(_, pulse) { + var df = pulse.dataflow, + cache = this.value, // cache ids of filtered tuples + output = pulse.fork(), + add = output.add, + rem = output.rem, + mod = output.mod, + test = _.expr, + isMod = true; + + pulse.visit(pulse.REM, function(t) { + var id$$1 = tupleid(t); + if (!cache.has(id$$1)) rem.push(t); + else cache.delete(id$$1); + }); + + pulse.visit(pulse.ADD, function(t) { + if (test(t, _)) add.push(t); + else cache.set(tupleid(t), 1); + }); + + function revisit(t) { + var id$$1 = tupleid(t), + b = test(t, _), + s = cache.get(id$$1); + if (b && s) { + cache.delete(id$$1); + add.push(t); + } else if (!b && !s) { + cache.set(id$$1, 1); + rem.push(t); + } else if (isMod && b && !s) { + mod.push(t); + } + } + + pulse.visit(pulse.MOD, revisit); + + if (_.modified()) { + isMod = false; + pulse.visit(pulse.REFLOW, revisit); + } + + if (cache.empty > df.cleanThreshold) df.runAfter(cache.clean); + return output; +}; + +// use either provided alias or accessor field name +function fieldNames(fields, as) { + if (!fields) return null; + return fields.map(function(f, i) { + return as[i] || accessorName(f); + }); +} + +/** + * Flattens array-typed field values into new data objects. + * If multiple fields are specified, they are treated as parallel arrays, + * with output values included for each matching index (or null if missing). + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} params.fields - An array of field + * accessors for the tuple fields that should be flattened. + * @param {Array} [params.as] - Output field names for flattened + * array fields. Any unspecified fields will use the field name provided + * by the fields accessors. + */ +function Flatten(params) { + Transform.call(this, [], params); +} + +Flatten.Definition = { + "type": "Flatten", + "metadata": {"generates": true, "source": true}, + "params": [ + { "name": "fields", "type": "field", "array": true, "required": true }, + { "name": "as", "type": "string", "array": true } + ] +}; + +var prototype$19 = inherits(Flatten, Transform); + +prototype$19.transform = function(_, pulse) { + var out = pulse.fork(pulse.NO_SOURCE), + fields = _.fields, + as = fieldNames(fields, _.as || []), + m = as.length; + + // remove any previous results + out.rem = this.value; + + // generate flattened tuples + pulse.visit(pulse.SOURCE, function(t) { + var arrays = fields.map(function(f) { return f(t); }), + maxlen = arrays.reduce(function(l, a) { return Math.max(l, a.length); }, 0), + i = 0, j, d, v; + + for (; i} [params.as] - Output field names for folded key + * and value fields, defaults to ['key', 'value']. + */ +function Fold(params) { + Transform.call(this, [], params); +} + +Fold.Definition = { + "type": "Fold", + "metadata": {"generates": true, "source": true}, + "params": [ + { "name": "fields", "type": "field", "array": true, "required": true }, + { "name": "as", "type": "string", "array": true, "length": 2, "default": ["key", "value"] } + ] +}; + +var prototype$20 = inherits(Fold, Transform); + +prototype$20.transform = function(_, pulse) { + var out = pulse.fork(pulse.NO_SOURCE), + fields = _.fields, + fnames = fields.map(accessorName), + as = _.as || ['key', 'value'], + k = as[0], + v = as[1], + n = fields.length; + + out.rem = this.value; + + pulse.visit(pulse.SOURCE, function(t) { + for (var i=0, d; i 0) { + // need more tuples, generate and add + for (add=[]; --num >= 0;) { + add.push(t = ingest(gen(_))); + data.push(t); + } + out.add = out.add.length + ? out.materialize(out.ADD).add.concat(add) + : add; + } else { + // need fewer tuples, remove + rem = data.slice(0, -num); + out.rem = out.rem.length + ? out.materialize(out.REM).rem.concat(rem) + : rem; + data = data.slice(-num); + } + + out.source = this.value = data; + return out; +}; + +var Methods = { + value: 'value', + median: median, + mean: mean, + min: min, + max: max +}; + +var Empty = []; + +/** + * Impute missing values. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.field - The value field to impute. + * @param {Array} [params.groupby] - An array of + * accessors to determine series within which to perform imputation. + * @param {function(object): *} params.key - An accessor for a key value. + * Each key value should be unique within a group. New tuples will be + * imputed for any key values that are not found within a group. + * @param {Array<*>} [params.keyvals] - Optional array of required key + * values. New tuples will be imputed for any key values that are not + * found within a group. In addition, these values will be automatically + * augmented with the key values observed in the input data. + * @param {string} [method='value'] - The imputation method to use. One of + * 'value', 'mean', 'median', 'max', 'min'. + * @param {*} [value=0] - The constant value to use for imputation + * when using method 'value'. + */ +function Impute(params) { + Transform.call(this, [], params); +} + +Impute.Definition = { + "type": "Impute", + "metadata": {"generates": true, "changes": true}, + "params": [ + { "name": "field", "type": "field", "required": true }, + { "name": "key", "type": "field", "required": true }, + { "name": "keyvals", "array": true }, + { "name": "groupby", "type": "field", "array": true }, + { "name": "method", "type": "enum", "default": "value", + "values": ["value", "mean", "median", "max", "min"] }, + { "name": "value", "default": 0 } + ] +}; + +var prototype$23 = inherits(Impute, Transform); + +function getValue(_) { + var m = _.method || Methods.value, v; + + if (Methods[m] == null) { + error$1('Unrecognized imputation method: ' + m); + } else if (m === Methods.value) { + v = _.value !== undefined ? _.value : 0; + return function() { return v; }; + } else { + return Methods[m]; + } +} + +function getField(_) { + var f = _.field; + return function(t) { return t ? f(t) : NaN; }; +} + +prototype$23.transform = function(_, pulse) { + var out = pulse.fork(pulse.ALL), + impute = getValue(_), + field$$1 = getField(_), + fName = accessorName(_.field), + kName = accessorName(_.key), + gNames = (_.groupby || []).map(accessorName), + groups = partition(pulse.source, _.groupby, _.key, _.keyvals), + curr = [], + prev = this.value, + m = groups.domain.length, + group, value, gVals, kVal, g, i, j, l, n, t; + + for (g=0, l=groups.length; g} params.fields - The field name(s) for the key function. + * @param {boolean} params.flat - A boolean flag indicating if the field names + * should be treated as flat property names, side-stepping nested field + * lookups normally indicated by dot or bracket notation. + */ +function Key(params) { + Operator.call(this, null, update$3, params); +} + +inherits(Key, Operator); + +function update$3(_) { + return (this.value && !_.modified()) ? this.value : key(_.fields, _.flat); +} + +/** + * Extend tuples by joining them with values from a lookup table. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Map} params.index - The lookup table map. + * @param {Array} params.as - Output field names for each lookup value. + * @param {*} [params.default] - A default value to use if lookup fails. + */ +function Lookup(params) { + Transform.call(this, {}, params); +} + +Lookup.Definition = { + "type": "Lookup", + "metadata": {"modifies": true}, + "params": [ + { "name": "index", "type": "index", "params": [ + {"name": "from", "type": "data", "required": true }, + {"name": "key", "type": "field", "required": true } + ] }, + { "name": "values", "type": "field", "array": true }, + { "name": "fields", "type": "field", "array": true, "required": true }, + { "name": "as", "type": "string", "array": true }, + { "name": "default", "default": null } + ] +}; + +var prototype$25 = inherits(Lookup, Transform); + +prototype$25.transform = function(_, pulse) { + var out = pulse, + as = _.as, + keys = _.fields, + index = _.index, + values = _.values, + defaultValue = _.default==null ? null : _.default, + reset = _.modified(), + flag = reset ? pulse.SOURCE : pulse.ADD, + n = keys.length, + set, m, mods; + + if (values) { + m = values.length; + + if (n > 1 && !as) { + error$1('Multi-field lookup requires explicit "as" parameter.'); + } + if (as && as.length !== n * m) { + error$1('The "as" parameter has too few output field names.'); + } + as = as || values.map(accessorName); + + set = function(t) { + for (var i=0, k=0, j, v; i>} params.extents - The input extents. + */ +function MultiExtent(params) { + Operator.call(this, null, update$4, params); +} + +inherits(MultiExtent, Operator); + +function update$4(_) { + if (this.value && !_.modified()) { + return this.value; + } + + var min = +Infinity, + max = -Infinity, + ext = _.extents, + i, n, e; + + for (i=0, n=ext.length; i max) max = e[1]; + } + return [min, max]; +} + +/** + * Merge a collection of value arrays. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array>} params.values - The input value arrrays. + */ +function MultiValues(params) { + Operator.call(this, null, update$5, params); +} + +inherits(MultiValues, Operator); + +function update$5(_) { + return (this.value && !_.modified()) + ? this.value + : _.values.reduce(function(data, _) { return data.concat(_); }, []); +} + +/** + * Operator whose value is simply its parameter hash. This operator is + * useful for enabling reactive updates to values of nested objects. + * @constructor + * @param {object} params - The parameters for this operator. + */ +function Params(params) { + Transform.call(this, null, params); +} + +inherits(Params, Transform); + +Params.prototype.transform = function(_, pulse) { + this.modified(_.modified()); + this.value = _; + return pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS); // do not pass tuples +}; + +/** + * Aggregate and pivot selected field values to become new fields. + * This operator is useful to construction cross-tabulations. + * @constructor + * @param {Array} [params.groupby] - An array of accessors + * to groupby. These fields act just like groupby fields of an Aggregate transform. + * @param {function(object): *} params.field - The field to pivot on. The unique + * values of this field become new field names in the output stream. + * @param {function(object): *} params.value - The field to populate pivoted fields. + * The aggregate values of this field become the values of the new pivoted fields. + * @param {string} [params.op] - The aggregation operation for the value field, + * applied per cell in the output stream. The default is "sum". + * @param {number} [params.limit] - An optional parameter indicating the maximum + * number of pivoted fields to generate. The pivoted field names are sorted in + * ascending order prior to enforcing the limit. + */ +function Pivot(params) { + Aggregate.call(this, params); +} + +Pivot.Definition = { + "type": "Pivot", + "metadata": {"generates": true, "changes": true}, + "params": [ + { "name": "groupby", "type": "field", "array": true }, + { "name": "field", "type": "field", "required": true }, + { "name": "value", "type": "field", "required": true }, + { "name": "op", "type": "enum", "values": ValidAggregateOps, "default": "sum" }, + { "name": "limit", "type": "number", "default": 0 }, + { "name": "key", "type": "field" } + ] +}; + +var prototype$26 = inherits(Pivot, Aggregate); + +prototype$26._transform = prototype$26.transform; + +prototype$26.transform = function(_, pulse) { + return this._transform(aggregateParams(_, pulse), pulse); +}; + +// Shoehorn a pivot transform into an aggregate transform! +// First collect all unique pivot field values. +// Then generate aggregate fields for each output pivot field. +function aggregateParams(_, pulse) { + var key$$1 = _.field, + value = _.value, + op = (_.op === 'count' ? '__count__' : _.op) || 'sum', + fields = accessorFields(key$$1).concat(accessorFields(value)), + keys = pivotKeys(key$$1, _.limit || 0, pulse); + + return { + key: _.key, + groupby: _.groupby, + ops: keys.map(function() { return op; }), + fields: keys.map(function(k) { return get$1(k, key$$1, value, fields); }), + as: keys.map(function(k) { return k + ''; }), + modified: _.modified.bind(_) + }; +} + +// Generate aggregate field accessor. +// Output NaN for non-existent values; aggregator will ignore! +function get$1(k, key$$1, value, fields) { + return accessor( + function(d) { return key$$1(d) === k ? value(d) : NaN; }, + fields, + k + '' + ); +} + +// Collect (and optionally limit) all unique pivot values. +function pivotKeys(key$$1, limit, pulse) { + var map = {}, + list = []; + + pulse.visit(pulse.SOURCE, function(t) { + var k = key$$1(t); + if (!map[k]) { + map[k] = 1; + list.push(k); + } + }); + + // TODO? Move this comparator to vega-util? + list.sort(function(u, v) { + return (uv||v==null) && u!=null ? 1 + : ((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))!==u && v===v ? -1 + : v!==v && u===u ? 1 : 0; + }); + + return limit ? list.slice(0, limit) : list; +} + +/** + * Partitions pre-faceted data into tuple subflows. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(Dataflow, string): Operator} params.subflow - A function + * that generates a subflow of operators and returns its root operator. + * @param {function(object): Array} params.field - The field + * accessor for an array of subflow tuple objects. + */ +function PreFacet(params) { + Facet.call(this, params); +} + +var prototype$27 = inherits(PreFacet, Facet); + +prototype$27.transform = function(_, pulse) { + var self = this, + flow = _.subflow, + field$$1 = _.field; + + if (_.modified('field') || field$$1 && pulse.modified(accessorFields(field$$1))) { + error$1('PreFacet does not support field modification.'); + } + + this._targets.active = 0; // reset list of active subflows + + pulse.visit(pulse.MOD, function(t) { + var sf = self.subflow(tupleid(t), flow, pulse, t); + field$$1 ? field$$1(t).forEach(function(_) { sf.mod(_); }) : sf.mod(t); + }); + + pulse.visit(pulse.ADD, function(t) { + var sf = self.subflow(tupleid(t), flow, pulse, t); + field$$1 ? field$$1(t).forEach(function(_) { sf.add(ingest(_)); }) : sf.add(t); + }); + + pulse.visit(pulse.REM, function(t) { + var sf = self.subflow(tupleid(t), flow, pulse, t); + field$$1 ? field$$1(t).forEach(function(_) { sf.rem(_); }) : sf.rem(t); + }); + + return pulse; +}; + +/** + * Performs a relational projection, copying selected fields from source + * tuples to a new set of derived tuples. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} [params.as] - Output field names for each projected + * field. Any unspecified fields will use the field name provided by + * the field accessor. + */ +function Project(params) { + Transform.call(this, null, params); +} + +Project.Definition = { + "type": "Project", + "metadata": {"generates": true, "changes": true, "modifies": true}, + "params": [ + { "name": "fields", "type": "field", "array": true }, + { "name": "as", "type": "string", "null": true, "array": true }, + ] +}; + +var prototype$28 = inherits(Project, Transform); + +prototype$28.transform = function(_, pulse) { + var fields = _.fields, + as = fieldNames(_.fields, _.as || []), + derive$$1 = fields + ? function(s, t) { return project(s, t, fields, as); } + : rederive, + out, lut; + + if (this.value) { + lut = this.value; + } else { + pulse = pulse.addAll(); + lut = this.value = {}; + } + + out = pulse.fork(pulse.NO_SOURCE); + + pulse.visit(pulse.REM, function(t) { + var id$$1 = tupleid(t); + out.rem.push(lut[id$$1]); + lut[id$$1] = null; + }); + + pulse.visit(pulse.ADD, function(t) { + var dt = derive$$1(t, ingest({})); + lut[tupleid(t)] = dt; + out.add.push(dt); + }); + + pulse.visit(pulse.MOD, function(t) { + out.mod.push(derive$$1(t, lut[tupleid(t)])); + }); + + return out; +}; + +function project(s, t, fields, as) { + for (var i=0, n=fields.length; i= cap) { + p = res[idx]; + if (map[tupleid(p)]) out.rem.push(p); // eviction + res[idx] = t; + } + } + ++cnt; + } + + if (pulse.rem.length) { + // find all tuples that should be removed, add to output + pulse.visit(pulse.REM, function(t) { + var id$$1 = tupleid(t); + if (map[id$$1]) { + map[id$$1] = -1; + out.rem.push(t); + } + --cnt; + }); + + // filter removed tuples out of the sample reservoir + res = res.filter(function(t) { return map[tupleid(t)] !== -1; }); + } + + if ((pulse.rem.length || mod) && res.length < num && pulse.source) { + // replenish sample if backing data source is available + cap = cnt = res.length; + pulse.visit(pulse.SOURCE, function(t) { + // update, but skip previously sampled tuples + if (!map[tupleid(t)]) update(t); + }); + cap = -1; + } + + if (mod && res.length > num) { + for (var i=0, n=res.length-num; i df.cleanThreshold) df.runAfter(index.clean); + return pulse.fork(); +}; + +/** + * Extracts an array of values. Assumes the source data has already been + * reduced as needed (e.g., by an upstream Aggregate transform). + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.field - The domain field to extract. + * @param {function(*,*): number} [params.sort] - An optional + * comparator function for sorting the values. The comparator will be + * applied to backing tuples prior to value extraction. + */ +function Values(params) { + Transform.call(this, null, params); +} + +var prototype$35 = inherits(Values, Transform); + +prototype$35.transform = function(_, pulse) { + var run = !this.value + || _.modified('field') + || _.modified('sort') + || pulse.changed() + || (_.sort && pulse.modified(_.sort.fields)); + + if (run) { + this.value = (_.sort + ? pulse.source.slice().sort(_.sort) + : pulse.source).map(_.field); + } +}; + +function WindowOp(op, field$$1, param, as) { + var fn = WindowOps[op](field$$1, param); + return { + init: fn.init || zero, + update: function(w, t) { t[as] = fn.next(w); } + }; +} + +var WindowOps = { + row_number: function() { + return { + next: function(w) { return w.index + 1; } + }; + }, + rank: function() { + var rank; + return { + init: function() { rank = 1; }, + next: function(w) { + var i = w.index, + data = w.data; + return (i && w.compare(data[i - 1], data[i])) ? (rank = i + 1) : rank; + } + }; + }, + dense_rank: function() { + var drank; + return { + init: function() { drank = 1; }, + next: function(w) { + var i = w.index, + d = w.data; + return (i && w.compare(d[i - 1], d[i])) ? ++drank : drank; + } + }; + }, + percent_rank: function() { + var rank = WindowOps.rank(), + next = rank.next; + return { + init: rank.init, + next: function(w) { + return (next(w) - 1) / (w.data.length - 1); + } + }; + }, + cume_dist: function() { + var cume; + return { + init: function() { cume = 0; }, + next: function(w) { + var i = w.index, + d = w.data, + c = w.compare; + if (cume < i) { + while (i + 1 < d.length && !c(d[i], d[i + 1])) ++i; + cume = i; + } + return (1 + cume) / d.length; + } + }; + }, + ntile: function(field$$1, num) { + num = +num; + if (!(num > 0)) error$1('ntile num must be greater than zero.'); + var cume = WindowOps.cume_dist(), + next = cume.next; + return { + init: cume.init, + next: function(w) { return Math.ceil(num * next(w)); } + }; + }, + + lag: function(field$$1, offset) { + offset = +offset || 1; + return { + next: function(w) { + var i = w.index - offset; + return i >= 0 ? field$$1(w.data[i]) : null; + } + }; + }, + lead: function(field$$1, offset) { + offset = +offset || 1; + return { + next: function(w) { + var i = w.index + offset, + d = w.data; + return i < d.length ? field$$1(d[i]) : null; + } + }; + }, + + first_value: function(field$$1) { + return { + next: function(w) { return field$$1(w.data[w.i0]); } + }; + }, + last_value: function(field$$1) { + return { + next: function(w) { return field$$1(w.data[w.i1 - 1]); } + } + }, + nth_value: function(field$$1, nth) { + nth = +nth; + if (!(nth > 0)) error$1('nth_value nth must be greater than zero.'); + return { + next: function(w) { + var i = w.i0 + (nth - 1); + return i < w.i1 ? field$$1(w.data[i]) : null; + } + } + } +}; + +var ValidWindowOps = Object.keys(WindowOps); + +function WindowState(_) { + var self = this, + ops = array(_.ops), + fields = array(_.fields), + params = array(_.params), + as = array(_.as), + outputs = self.outputs = [], + windows = self.windows = [], + inputs = {}, + map = {}, + countOnly = true, + counts = [], + measures = []; + + function visitInputs(f) { + array(accessorFields(f)).forEach(function(_) { inputs[_] = 1; }); + } + visitInputs(_.sort); + + ops.forEach(function(op, i) { + var field$$1 = fields[i], + mname = accessorName(field$$1), + name = measureName(op, mname, as[i]); + + visitInputs(field$$1); + outputs.push(name); + + // Window operation + if (WindowOps.hasOwnProperty(op)) { + windows.push(WindowOp(op, fields[i], params[i], name)); + } + + // Aggregate operation + else { + if (field$$1 == null && op !== 'count') { + error$1('Null aggregate field specified.'); + } + if (op === 'count') { + counts.push(name); + return; + } + + countOnly = false; + var m = map[mname]; + if (!m) { + m = (map[mname] = []); + m.field = field$$1; + measures.push(m); + } + m.push(createMeasure(op, name)); + } + }); + + if (counts.length || measures.length) { + self.cell = cell(measures, counts, countOnly); + } + + self.inputs = Object.keys(inputs); +} + +var prototype$37 = WindowState.prototype; + +prototype$37.init = function() { + this.windows.forEach(function(_) { _.init(); }); + if (this.cell) this.cell.init(); +}; + +prototype$37.update = function(w, t) { + var self = this, + cell = self.cell, + wind = self.windows, + data = w.data, + m = wind && wind.length, + j; + + if (cell) { + for (j=w.p0; j} [params.groupby] - An array of accessors by which to partition tuples into separate windows. + * @param {Array} params.ops - An array of strings indicating window operations to perform. + * @param {Array} [params.fields] - An array of accessors + * for data fields to use as inputs to window operations. + * @param {Array<*>} [params.params] - An array of parameter values for window operations. + * @param {Array} [params.as] - An array of output field names for window operations. + * @param {Array} [params.frame] - Window frame definition as two-element array. + * @param {boolean} [params.ignorePeers=false] - If true, base window frame boundaries on row + * number alone, ignoring peers with identical sort values. If false (default), + * the window boundaries will be adjusted to include peer values. + */ +function Window(params) { + Transform.call(this, {}, params); + this._mlen = 0; + this._mods = []; +} + +Window.Definition = { + "type": "Window", + "metadata": {"modifies": true}, + "params": [ + { "name": "sort", "type": "compare" }, + { "name": "groupby", "type": "field", "array": true }, + { "name": "ops", "type": "enum", "array": true, "values": ValidWindowOps.concat(ValidAggregateOps) }, + { "name": "params", "type": "number", "null": true, "array": true }, + { "name": "fields", "type": "field", "null": true, "array": true }, + { "name": "as", "type": "string", "null": true, "array": true }, + { "name": "frame", "type": "number", "null": true, "array": true, "length": 2, "default": [null, 0] }, + { "name": "ignorePeers", "type": "boolean", "default": false } + ] +}; + +var prototype$36 = inherits(Window, Transform); + +prototype$36.transform = function(_, pulse) { + var self = this, + state = self.state, + mod = _.modified(), + i, n; + + this.stamp = pulse.stamp; + + // initialize window state + if (!state || mod) { + state = self.state = new WindowState(_); + } + + // retrieve group for a tuple + var key$$1 = groupkey(_.groupby); + function group(t) { return self.group(key$$1(t)); } + + // partition input tuples + if (mod || pulse.modified(state.inputs)) { + self.value = {}; + pulse.visit(pulse.SOURCE, function(t) { group(t).add(t); }); + } else { + pulse.visit(pulse.REM, function(t) { group(t).remove(t); }); + pulse.visit(pulse.ADD, function(t) { group(t).add(t); }); + } + + // perform window calculations for each modified partition + for (i=0, n=self._mlen; i 0 && !c(d[r0], d[r0-1])) w.i0 = bisect.left(d, d[r0]); + if (r1 < n && !c(d[r1], d[r1+1])) w.i1 = bisect.right(d, d[r1]); +} + + + +var tx = Object.freeze({ + aggregate: Aggregate, + bin: Bin, + collect: Collect, + compare: Compare, + countpattern: CountPattern, + cross: Cross, + density: Density, + extent: Extent, + facet: Facet, + field: Field, + filter: Filter, + flatten: Flatten, + fold: Fold, + formula: Formula, + generate: Generate, + impute: Impute, + joinaggregate: JoinAggregate, + key: Key, + lookup: Lookup, + multiextent: MultiExtent, + multivalues: MultiValues, + params: Params, + pivot: Pivot, + prefacet: PreFacet, + project: Project, + proxy: Proxy, + relay: Relay, + sample: Sample, + sequence: Sequence, + sieve: Sieve, + subflow: Subflow, + tupleindex: TupleIndex, + values: Values, + window: Window +}); + +function Bounds(b) { + this.clear(); + if (b) this.union(b); +} + +var prototype$39 = Bounds.prototype; + +prototype$39.clone = function() { + return new Bounds(this); +}; + +prototype$39.clear = function() { + this.x1 = +Number.MAX_VALUE; + this.y1 = +Number.MAX_VALUE; + this.x2 = -Number.MAX_VALUE; + this.y2 = -Number.MAX_VALUE; + return this; +}; + +prototype$39.empty = function() { + return ( + this.x1 === +Number.MAX_VALUE && + this.y1 === +Number.MAX_VALUE && + this.x2 === -Number.MAX_VALUE && + this.y2 === -Number.MAX_VALUE + ); +}; + +prototype$39.set = function(x1, y1, x2, y2) { + if (x2 < x1) { + this.x2 = x1; + this.x1 = x2; + } else { + this.x1 = x1; + this.x2 = x2; + } + if (y2 < y1) { + this.y2 = y1; + this.y1 = y2; + } else { + this.y1 = y1; + this.y2 = y2; + } + return this; +}; + +prototype$39.add = function(x, y) { + if (x < this.x1) this.x1 = x; + if (y < this.y1) this.y1 = y; + if (x > this.x2) this.x2 = x; + if (y > this.y2) this.y2 = y; + return this; +}; + +prototype$39.expand = function(d) { + this.x1 -= d; + this.y1 -= d; + this.x2 += d; + this.y2 += d; + return this; +}; + +prototype$39.round = function() { + this.x1 = Math.floor(this.x1); + this.y1 = Math.floor(this.y1); + this.x2 = Math.ceil(this.x2); + this.y2 = Math.ceil(this.y2); + return this; +}; + +prototype$39.translate = function(dx, dy) { + this.x1 += dx; + this.x2 += dx; + this.y1 += dy; + this.y2 += dy; + return this; +}; + +prototype$39.rotate = function(angle, x, y) { + var cos = Math.cos(angle), + sin = Math.sin(angle), + cx = x - x*cos + y*sin, + cy = y - x*sin - y*cos, + x1 = this.x1, x2 = this.x2, + y1 = this.y1, y2 = this.y2; + + return this.clear() + .add(cos*x1 - sin*y1 + cx, sin*x1 + cos*y1 + cy) + .add(cos*x1 - sin*y2 + cx, sin*x1 + cos*y2 + cy) + .add(cos*x2 - sin*y1 + cx, sin*x2 + cos*y1 + cy) + .add(cos*x2 - sin*y2 + cx, sin*x2 + cos*y2 + cy); +}; + +prototype$39.union = function(b) { + if (b.x1 < this.x1) this.x1 = b.x1; + if (b.y1 < this.y1) this.y1 = b.y1; + if (b.x2 > this.x2) this.x2 = b.x2; + if (b.y2 > this.y2) this.y2 = b.y2; + return this; +}; + +prototype$39.intersect = function(b) { + if (b.x1 > this.x1) this.x1 = b.x1; + if (b.y1 > this.y1) this.y1 = b.y1; + if (b.x2 < this.x2) this.x2 = b.x2; + if (b.y2 < this.y2) this.y2 = b.y2; + return this; +}; + +prototype$39.encloses = function(b) { + return b && ( + this.x1 <= b.x1 && + this.x2 >= b.x2 && + this.y1 <= b.y1 && + this.y2 >= b.y2 + ); +}; + +prototype$39.alignsWith = function(b) { + return b && ( + this.x1 == b.x1 || + this.x2 == b.x2 || + this.y1 == b.y1 || + this.y2 == b.y2 + ); +}; + +prototype$39.intersects = function(b) { + return b && !( + this.x2 < b.x1 || + this.x1 > b.x2 || + this.y2 < b.y1 || + this.y1 > b.y2 + ); +}; + +prototype$39.contains = function(x, y) { + return !( + x < this.x1 || + x > this.x2 || + y < this.y1 || + y > this.y2 + ); +}; + +prototype$39.width = function() { + return this.x2 - this.x1; +}; + +prototype$39.height = function() { + return this.y2 - this.y1; +}; + +var gradient_id = 0; + +var Gradient = function(p0, p1) { + var stops = [], gradient; + return gradient = { + id: 'gradient_' + (gradient_id++), + x1: p0 ? p0[0] : 0, + y1: p0 ? p0[1] : 0, + x2: p1 ? p1[0] : 1, + y2: p1 ? p1[1] : 0, + stops: stops, + stop: function(offset, color) { + stops.push({offset: offset, color: color}); + return gradient; + } + }; +}; + +function Item(mark) { + this.mark = mark; + this.bounds = (this.bounds || new Bounds()); +} + +function GroupItem(mark) { + Item.call(this, mark); + this.items = (this.items || []); +} + +inherits(GroupItem, Item); + +function domCanvas(w, h) { + if (typeof document !== 'undefined' && document.createElement) { + var c = document.createElement('canvas'); + if (c && c.getContext) { + c.width = w; + c.height = h; + return c; + } + } + return null; +} + +function domImage() { + return typeof Image !== 'undefined' ? Image : null; +} + +var NodeCanvas; + +try { + // try to load canvas module + NodeCanvas = require('canvas'); + if (!NodeCanvas) throw 1; +} catch (e) { + try { + // if canvas fails, try to load canvas-prebuilt + NodeCanvas = require('canvas-prebuilt'); + } catch (e2) { + // if all options fail, set to null + NodeCanvas = null; + } +} + +function nodeCanvas(w, h) { + if (NodeCanvas) { + try { + return new NodeCanvas(w, h); + } catch (e) { + // do nothing, return null on error + } + } + return null; +} + +function nodeImage() { + return NodeCanvas && NodeCanvas.Image || null; +} + +function canvas(w, h) { + return domCanvas(w, h) || nodeCanvas(w, h) || null; +} + +function image() { + return domImage() || nodeImage() || null; +} + +function ResourceLoader(customLoader) { + this._pending = 0; + this._loader = customLoader || loader(); +} + +var prototype$40 = ResourceLoader.prototype; + +prototype$40.pending = function() { + return this._pending; +}; + +function increment(loader$$1) { + loader$$1._pending += 1; +} + +function decrement(loader$$1) { + loader$$1._pending -= 1; +} + +prototype$40.sanitizeURL = function(uri) { + var loader$$1 = this; + increment(loader$$1); + + return loader$$1._loader.sanitize(uri, {context:'href'}) + .then(function(opt) { + decrement(loader$$1); + return opt; + }) + .catch(function() { + decrement(loader$$1); + return null; + }); +}; + +prototype$40.loadImage = function(uri) { + var loader$$1 = this, + Image = image(); + increment(loader$$1); + + return loader$$1._loader + .sanitize(uri, {context: 'image'}) + .then(function(opt) { + var url = opt.href; + if (!url || !Image) throw {url: url}; + + var img = new Image(); + + img.onload = function() { + decrement(loader$$1); + img.loaded = true; + }; + + img.onerror = function() { + decrement(loader$$1); + img.loaded = false; + }; + + img.src = url; + return img; + }) + .catch(function(e) { + decrement(loader$$1); + return {loaded: false, width: 0, height: 0, src: e && e.url || ''}; + }); +}; + +prototype$40.ready = function() { + var loader$$1 = this; + return new Promise(function(accept) { + function poll(value) { + if (!loader$$1.pending()) accept(value); + else setTimeout(function() { poll(true); }, 10); + } + poll(false); + }); +}; + +var pi = Math.PI; +var tau = 2 * pi; +var epsilon = 1e-6; +var tauEpsilon = tau - epsilon; + +function Path() { + this._x0 = this._y0 = // start of current subpath + this._x1 = this._y1 = null; // end of current subpath + this._ = ""; +} + +function path() { + return new Path; +} + +Path.prototype = path.prototype = { + constructor: Path, + moveTo: function(x, y) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y); + }, + closePath: function() { + if (this._x1 !== null) { + this._x1 = this._x0, this._y1 = this._y0; + this._ += "Z"; + } + }, + lineTo: function(x, y) { + this._ += "L" + (this._x1 = +x) + "," + (this._y1 = +y); + }, + quadraticCurveTo: function(x1, y1, x, y) { + this._ += "Q" + (+x1) + "," + (+y1) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { + this._ += "C" + (+x1) + "," + (+y1) + "," + (+x2) + "," + (+y2) + "," + (this._x1 = +x) + "," + (this._y1 = +y); + }, + arcTo: function(x1, y1, x2, y2, r) { + x1 = +x1, y1 = +y1, x2 = +x2, y2 = +y2, r = +r; + var x0 = this._x1, + y0 = this._y1, + x21 = x2 - x1, + y21 = y2 - y1, + x01 = x0 - x1, + y01 = y0 - y1, + l01_2 = x01 * x01 + y01 * y01; + + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); + + // Is this path empty? Move to (x1,y1). + if (this._x1 === null) { + this._ += "M" + (this._x1 = x1) + "," + (this._y1 = y1); + } + + // Or, is (x1,y1) coincident with (x0,y0)? Do nothing. + else if (!(l01_2 > epsilon)) {} + + // Or, are (x0,y0), (x1,y1) and (x2,y2) collinear? + // Equivalently, is (x1,y1) coincident with (x2,y2)? + // Or, is the radius zero? Line to (x1,y1). + else if (!(Math.abs(y01 * x21 - y21 * x01) > epsilon) || !r) { + this._ += "L" + (this._x1 = x1) + "," + (this._y1 = y1); + } + + // Otherwise, draw an arc! + else { + var x20 = x2 - x0, + y20 = y2 - y0, + l21_2 = x21 * x21 + y21 * y21, + l20_2 = x20 * x20 + y20 * y20, + l21 = Math.sqrt(l21_2), + l01 = Math.sqrt(l01_2), + l = r * Math.tan((pi - Math.acos((l21_2 + l01_2 - l20_2) / (2 * l21 * l01))) / 2), + t01 = l / l01, + t21 = l / l21; + + // If the start tangent is not coincident with (x0,y0), line to. + if (Math.abs(t01 - 1) > epsilon) { + this._ += "L" + (x1 + t01 * x01) + "," + (y1 + t01 * y01); + } + + this._ += "A" + r + "," + r + ",0,0," + (+(y01 * x20 > x01 * y20)) + "," + (this._x1 = x1 + t21 * x21) + "," + (this._y1 = y1 + t21 * y21); + } + }, + arc: function(x, y, r, a0, a1, ccw) { + x = +x, y = +y, r = +r; + var dx = r * Math.cos(a0), + dy = r * Math.sin(a0), + x0 = x + dx, + y0 = y + dy, + cw = 1 ^ ccw, + da = ccw ? a0 - a1 : a1 - a0; + + // Is the radius negative? Error. + if (r < 0) throw new Error("negative radius: " + r); + + // Is this path empty? Move to (x0,y0). + if (this._x1 === null) { + this._ += "M" + x0 + "," + y0; + } + + // Or, is (x0,y0) not coincident with the previous point? Line to (x0,y0). + else if (Math.abs(this._x1 - x0) > epsilon || Math.abs(this._y1 - y0) > epsilon) { + this._ += "L" + x0 + "," + y0; + } + + // Is this arc empty? We’re done. + if (!r) return; + + // Does the angle go the wrong way? Flip the direction. + if (da < 0) da = da % tau + tau; + + // Is this a complete circle? Draw two arcs to complete the circle. + if (da > tauEpsilon) { + this._ += "A" + r + "," + r + ",0,1," + cw + "," + (x - dx) + "," + (y - dy) + "A" + r + "," + r + ",0,1," + cw + "," + (this._x1 = x0) + "," + (this._y1 = y0); + } + + // Is this arc non-empty? Draw an arc! + else if (da > epsilon) { + this._ += "A" + r + "," + r + ",0," + (+(da >= pi)) + "," + cw + "," + (this._x1 = x + r * Math.cos(a1)) + "," + (this._y1 = y + r * Math.sin(a1)); + } + }, + rect: function(x, y, w, h) { + this._ += "M" + (this._x0 = this._x1 = +x) + "," + (this._y0 = this._y1 = +y) + "h" + (+w) + "v" + (+h) + "h" + (-w) + "Z"; + }, + toString: function() { + return this._; + } +}; + +var constant$2 = function(x) { + return function constant() { + return x; + }; +}; + +var abs = Math.abs; +var atan2 = Math.atan2; +var cos = Math.cos; +var max$1 = Math.max; +var min$1 = Math.min; +var sin = Math.sin; +var sqrt = Math.sqrt; + +var epsilon$1 = 1e-12; +var pi$1 = Math.PI; +var halfPi = pi$1 / 2; +var tau$1 = 2 * pi$1; + +function acos(x) { + return x > 1 ? 0 : x < -1 ? pi$1 : Math.acos(x); +} + +function asin(x) { + return x >= 1 ? halfPi : x <= -1 ? -halfPi : Math.asin(x); +} + +function arcInnerRadius(d) { + return d.innerRadius; +} + +function arcOuterRadius(d) { + return d.outerRadius; +} + +function arcStartAngle(d) { + return d.startAngle; +} + +function arcEndAngle(d) { + return d.endAngle; +} + +function arcPadAngle(d) { + return d && d.padAngle; // Note: optional! +} + +function intersect(x0, y0, x1, y1, x2, y2, x3, y3) { + var x10 = x1 - x0, y10 = y1 - y0, + x32 = x3 - x2, y32 = y3 - y2, + t = (x32 * (y0 - y2) - y32 * (x0 - x2)) / (y32 * x10 - x32 * y10); + return [x0 + t * x10, y0 + t * y10]; +} + +// Compute perpendicular offset line of length rc. +// http://mathworld.wolfram.com/Circle-LineIntersection.html +function cornerTangents(x0, y0, x1, y1, r1, rc, cw) { + var x01 = x0 - x1, + y01 = y0 - y1, + lo = (cw ? rc : -rc) / sqrt(x01 * x01 + y01 * y01), + ox = lo * y01, + oy = -lo * x01, + x11 = x0 + ox, + y11 = y0 + oy, + x10 = x1 + ox, + y10 = y1 + oy, + x00 = (x11 + x10) / 2, + y00 = (y11 + y10) / 2, + dx = x10 - x11, + dy = y10 - y11, + d2 = dx * dx + dy * dy, + r = r1 - rc, + D = x11 * y10 - x10 * y11, + d = (dy < 0 ? -1 : 1) * sqrt(max$1(0, r * r * d2 - D * D)), + cx0 = (D * dy - dx * d) / d2, + cy0 = (-D * dx - dy * d) / d2, + cx1 = (D * dy + dx * d) / d2, + cy1 = (-D * dx + dy * d) / d2, + dx0 = cx0 - x00, + dy0 = cy0 - y00, + dx1 = cx1 - x00, + dy1 = cy1 - y00; + + // Pick the closer of the two intersection points. + // TODO Is there a faster way to determine which intersection to use? + if (dx0 * dx0 + dy0 * dy0 > dx1 * dx1 + dy1 * dy1) cx0 = cx1, cy0 = cy1; + + return { + cx: cx0, + cy: cy0, + x01: -ox, + y01: -oy, + x11: cx0 * (r1 / r - 1), + y11: cy0 * (r1 / r - 1) + }; +} + +var d3_arc = function() { + var innerRadius = arcInnerRadius, + outerRadius = arcOuterRadius, + cornerRadius = constant$2(0), + padRadius = null, + startAngle = arcStartAngle, + endAngle = arcEndAngle, + padAngle = arcPadAngle, + context = null; + + function arc() { + var buffer, + r, + r0 = +innerRadius.apply(this, arguments), + r1 = +outerRadius.apply(this, arguments), + a0 = startAngle.apply(this, arguments) - halfPi, + a1 = endAngle.apply(this, arguments) - halfPi, + da = abs(a1 - a0), + cw = a1 > a0; + + if (!context) context = buffer = path(); + + // Ensure that the outer radius is always larger than the inner radius. + if (r1 < r0) r = r1, r1 = r0, r0 = r; + + // Is it a point? + if (!(r1 > epsilon$1)) context.moveTo(0, 0); + + // Or is it a circle or annulus? + else if (da > tau$1 - epsilon$1) { + context.moveTo(r1 * cos(a0), r1 * sin(a0)); + context.arc(0, 0, r1, a0, a1, !cw); + if (r0 > epsilon$1) { + context.moveTo(r0 * cos(a1), r0 * sin(a1)); + context.arc(0, 0, r0, a1, a0, cw); + } + } + + // Or is it a circular or annular sector? + else { + var a01 = a0, + a11 = a1, + a00 = a0, + a10 = a1, + da0 = da, + da1 = da, + ap = padAngle.apply(this, arguments) / 2, + rp = (ap > epsilon$1) && (padRadius ? +padRadius.apply(this, arguments) : sqrt(r0 * r0 + r1 * r1)), + rc = min$1(abs(r1 - r0) / 2, +cornerRadius.apply(this, arguments)), + rc0 = rc, + rc1 = rc, + t0, + t1; + + // Apply padding? Note that since r1 ≥ r0, da1 ≥ da0. + if (rp > epsilon$1) { + var p0 = asin(rp / r0 * sin(ap)), + p1 = asin(rp / r1 * sin(ap)); + if ((da0 -= p0 * 2) > epsilon$1) p0 *= (cw ? 1 : -1), a00 += p0, a10 -= p0; + else da0 = 0, a00 = a10 = (a0 + a1) / 2; + if ((da1 -= p1 * 2) > epsilon$1) p1 *= (cw ? 1 : -1), a01 += p1, a11 -= p1; + else da1 = 0, a01 = a11 = (a0 + a1) / 2; + } + + var x01 = r1 * cos(a01), + y01 = r1 * sin(a01), + x10 = r0 * cos(a10), + y10 = r0 * sin(a10); + + // Apply rounded corners? + if (rc > epsilon$1) { + var x11 = r1 * cos(a11), + y11 = r1 * sin(a11), + x00 = r0 * cos(a00), + y00 = r0 * sin(a00); + + // Restrict the corner radius according to the sector angle. + if (da < pi$1) { + var oc = da0 > epsilon$1 ? intersect(x01, y01, x00, y00, x11, y11, x10, y10) : [x10, y10], + ax = x01 - oc[0], + ay = y01 - oc[1], + bx = x11 - oc[0], + by = y11 - oc[1], + kc = 1 / sin(acos((ax * bx + ay * by) / (sqrt(ax * ax + ay * ay) * sqrt(bx * bx + by * by))) / 2), + lc = sqrt(oc[0] * oc[0] + oc[1] * oc[1]); + rc0 = min$1(rc, (r0 - lc) / (kc - 1)); + rc1 = min$1(rc, (r1 - lc) / (kc + 1)); + } + } + + // Is the sector collapsed to a line? + if (!(da1 > epsilon$1)) context.moveTo(x01, y01); + + // Does the sector’s outer ring have rounded corners? + else if (rc1 > epsilon$1) { + t0 = cornerTangents(x00, y00, x01, y01, r1, rc1, cw); + t1 = cornerTangents(x11, y11, x10, y10, r1, rc1, cw); + + context.moveTo(t0.cx + t0.x01, t0.cy + t0.y01); + + // Have the corners merged? + if (rc1 < rc) context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); + + // Otherwise, draw the two corners and the ring. + else { + context.arc(t0.cx, t0.cy, rc1, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); + context.arc(0, 0, r1, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), !cw); + context.arc(t1.cx, t1.cy, rc1, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); + } + } + + // Or is the outer ring just a circular arc? + else context.moveTo(x01, y01), context.arc(0, 0, r1, a01, a11, !cw); + + // Is there no inner ring, and it’s a circular sector? + // Or perhaps it’s an annular sector collapsed due to padding? + if (!(r0 > epsilon$1) || !(da0 > epsilon$1)) context.lineTo(x10, y10); + + // Does the sector’s inner ring (or point) have rounded corners? + else if (rc0 > epsilon$1) { + t0 = cornerTangents(x10, y10, x11, y11, r0, -rc0, cw); + t1 = cornerTangents(x01, y01, x00, y00, r0, -rc0, cw); + + context.lineTo(t0.cx + t0.x01, t0.cy + t0.y01); + + // Have the corners merged? + if (rc0 < rc) context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t1.y01, t1.x01), !cw); + + // Otherwise, draw the two corners and the ring. + else { + context.arc(t0.cx, t0.cy, rc0, atan2(t0.y01, t0.x01), atan2(t0.y11, t0.x11), !cw); + context.arc(0, 0, r0, atan2(t0.cy + t0.y11, t0.cx + t0.x11), atan2(t1.cy + t1.y11, t1.cx + t1.x11), cw); + context.arc(t1.cx, t1.cy, rc0, atan2(t1.y11, t1.x11), atan2(t1.y01, t1.x01), !cw); + } + } + + // Or is the inner ring just a circular arc? + else context.arc(0, 0, r0, a10, a00, cw); + } + + context.closePath(); + + if (buffer) return context = null, buffer + "" || null; + } + + arc.centroid = function() { + var r = (+innerRadius.apply(this, arguments) + +outerRadius.apply(this, arguments)) / 2, + a = (+startAngle.apply(this, arguments) + +endAngle.apply(this, arguments)) / 2 - pi$1 / 2; + return [cos(a) * r, sin(a) * r]; + }; + + arc.innerRadius = function(_) { + return arguments.length ? (innerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : innerRadius; + }; + + arc.outerRadius = function(_) { + return arguments.length ? (outerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : outerRadius; + }; + + arc.cornerRadius = function(_) { + return arguments.length ? (cornerRadius = typeof _ === "function" ? _ : constant$2(+_), arc) : cornerRadius; + }; + + arc.padRadius = function(_) { + return arguments.length ? (padRadius = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), arc) : padRadius; + }; + + arc.startAngle = function(_) { + return arguments.length ? (startAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : startAngle; + }; + + arc.endAngle = function(_) { + return arguments.length ? (endAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : endAngle; + }; + + arc.padAngle = function(_) { + return arguments.length ? (padAngle = typeof _ === "function" ? _ : constant$2(+_), arc) : padAngle; + }; + + arc.context = function(_) { + return arguments.length ? ((context = _ == null ? null : _), arc) : context; + }; + + return arc; +}; + +function Linear(context) { + this._context = context; +} + +Linear.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; // proceed + default: this._context.lineTo(x, y); break; + } + } +}; + +var curveLinear = function(context) { + return new Linear(context); +}; + +function x$1(p) { + return p[0]; +} + +function y$1(p) { + return p[1]; +} + +var line$1 = function() { + var x = x$1, + y = y$1, + defined = constant$2(true), + context = null, + curve = curveLinear, + output = null; + + function line(data) { + var i, + n = data.length, + d, + defined0 = false, + buffer; + + if (context == null) output = curve(buffer = path()); + + for (i = 0; i <= n; ++i) { + if (!(i < n && defined(d = data[i], i, data)) === defined0) { + if (defined0 = !defined0) output.lineStart(); + else output.lineEnd(); + } + if (defined0) output.point(+x(d, i, data), +y(d, i, data)); + } + + if (buffer) return output = null, buffer + "" || null; + } + + line.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : constant$2(+_), line) : x; + }; + + line.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : constant$2(+_), line) : y; + }; + + line.defined = function(_) { + return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), line) : defined; + }; + + line.curve = function(_) { + return arguments.length ? (curve = _, context != null && (output = curve(context)), line) : curve; + }; + + line.context = function(_) { + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), line) : context; + }; + + return line; +}; + +var area$1 = function() { + var x0 = x$1, + x1 = null, + y0 = constant$2(0), + y1 = y$1, + defined = constant$2(true), + context = null, + curve = curveLinear, + output = null; + + function area(data) { + var i, + j, + k, + n = data.length, + d, + defined0 = false, + buffer, + x0z = new Array(n), + y0z = new Array(n); + + if (context == null) output = curve(buffer = path()); + + for (i = 0; i <= n; ++i) { + if (!(i < n && defined(d = data[i], i, data)) === defined0) { + if (defined0 = !defined0) { + j = i; + output.areaStart(); + output.lineStart(); + } else { + output.lineEnd(); + output.lineStart(); + for (k = i - 1; k >= j; --k) { + output.point(x0z[k], y0z[k]); + } + output.lineEnd(); + output.areaEnd(); + } + } + if (defined0) { + x0z[i] = +x0(d, i, data), y0z[i] = +y0(d, i, data); + output.point(x1 ? +x1(d, i, data) : x0z[i], y1 ? +y1(d, i, data) : y0z[i]); + } + } + + if (buffer) return output = null, buffer + "" || null; + } + + function arealine() { + return line$1().defined(defined).curve(curve).context(context); + } + + area.x = function(_) { + return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), x1 = null, area) : x0; + }; + + area.x0 = function(_) { + return arguments.length ? (x0 = typeof _ === "function" ? _ : constant$2(+_), area) : x0; + }; + + area.x1 = function(_) { + return arguments.length ? (x1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : x1; + }; + + area.y = function(_) { + return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), y1 = null, area) : y0; + }; + + area.y0 = function(_) { + return arguments.length ? (y0 = typeof _ === "function" ? _ : constant$2(+_), area) : y0; + }; + + area.y1 = function(_) { + return arguments.length ? (y1 = _ == null ? null : typeof _ === "function" ? _ : constant$2(+_), area) : y1; + }; + + area.lineX0 = + area.lineY0 = function() { + return arealine().x(x0).y(y0); + }; + + area.lineY1 = function() { + return arealine().x(x0).y(y1); + }; + + area.lineX1 = function() { + return arealine().x(x1).y(y0); + }; + + area.defined = function(_) { + return arguments.length ? (defined = typeof _ === "function" ? _ : constant$2(!!_), area) : defined; + }; + + area.curve = function(_) { + return arguments.length ? (curve = _, context != null && (output = curve(context)), area) : curve; + }; + + area.context = function(_) { + return arguments.length ? (_ == null ? context = output = null : output = curve(context = _), area) : context; + }; + + return area; +}; + +var circle = { + draw: function(context, size) { + var r = Math.sqrt(size / pi$1); + context.moveTo(r, 0); + context.arc(0, 0, r, 0, tau$1); + } +}; + +var d3_symbol = function() { + var type = constant$2(circle), + size = constant$2(64), + context = null; + + function symbol() { + var buffer; + if (!context) context = buffer = path(); + type.apply(this, arguments).draw(context, +size.apply(this, arguments)); + if (buffer) return context = null, buffer + "" || null; + } + + symbol.type = function(_) { + return arguments.length ? (type = typeof _ === "function" ? _ : constant$2(_), symbol) : type; + }; + + symbol.size = function(_) { + return arguments.length ? (size = typeof _ === "function" ? _ : constant$2(+_), symbol) : size; + }; + + symbol.context = function(_) { + return arguments.length ? (context = _ == null ? null : _, symbol) : context; + }; + + return symbol; +}; + +var noop$1 = function() {}; + +function point(that, x, y) { + that._context.bezierCurveTo( + (2 * that._x0 + that._x1) / 3, + (2 * that._y0 + that._y1) / 3, + (that._x0 + 2 * that._x1) / 3, + (that._y0 + 2 * that._y1) / 3, + (that._x0 + 4 * that._x1 + x) / 6, + (that._y0 + 4 * that._y1 + y) / 6 + ); +} + +function Basis(context) { + this._context = context; +} + +Basis.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 3: point(this, this._x1, this._y1); // proceed + case 2: this._context.lineTo(this._x1, this._y1); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._context.lineTo((5 * this._x0 + this._x1) / 6, (5 * this._y0 + this._y1) / 6); // proceed + default: point(this, x, y); break; + } + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; + } +}; + +var curveBasis = function(context) { + return new Basis(context); +}; + +function BasisClosed(context) { + this._context = context; +} + +BasisClosed.prototype = { + areaStart: noop$1, + areaEnd: noop$1, + lineStart: function() { + this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = + this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 1: { + this._context.moveTo(this._x2, this._y2); + this._context.closePath(); + break; + } + case 2: { + this._context.moveTo((this._x2 + 2 * this._x3) / 3, (this._y2 + 2 * this._y3) / 3); + this._context.lineTo((this._x3 + 2 * this._x2) / 3, (this._y3 + 2 * this._y2) / 3); + this._context.closePath(); + break; + } + case 3: { + this.point(this._x2, this._y2); + this.point(this._x3, this._y3); + this.point(this._x4, this._y4); + break; + } + } + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._x2 = x, this._y2 = y; break; + case 1: this._point = 2; this._x3 = x, this._y3 = y; break; + case 2: this._point = 3; this._x4 = x, this._y4 = y; this._context.moveTo((this._x0 + 4 * this._x1 + x) / 6, (this._y0 + 4 * this._y1 + y) / 6); break; + default: point(this, x, y); break; + } + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; + } +}; + +var curveBasisClosed = function(context) { + return new BasisClosed(context); +}; + +function BasisOpen(context) { + this._context = context; +} + +BasisOpen.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = NaN; + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; break; + case 1: this._point = 2; break; + case 2: this._point = 3; var x0 = (this._x0 + 4 * this._x1 + x) / 6, y0 = (this._y0 + 4 * this._y1 + y) / 6; this._line ? this._context.lineTo(x0, y0) : this._context.moveTo(x0, y0); break; + case 3: this._point = 4; // proceed + default: point(this, x, y); break; + } + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; + } +}; + +var curveBasisOpen = function(context) { + return new BasisOpen(context); +}; + +function Bundle(context, beta) { + this._basis = new Basis(context); + this._beta = beta; +} + +Bundle.prototype = { + lineStart: function() { + this._x = []; + this._y = []; + this._basis.lineStart(); + }, + lineEnd: function() { + var x = this._x, + y = this._y, + j = x.length - 1; + + if (j > 0) { + var x0 = x[0], + y0 = y[0], + dx = x[j] - x0, + dy = y[j] - y0, + i = -1, + t; + + while (++i <= j) { + t = i / j; + this._basis.point( + this._beta * x[i] + (1 - this._beta) * (x0 + t * dx), + this._beta * y[i] + (1 - this._beta) * (y0 + t * dy) + ); + } + } + + this._x = this._y = null; + this._basis.lineEnd(); + }, + point: function(x, y) { + this._x.push(+x); + this._y.push(+y); + } +}; + +var curveBundle = (function custom(beta) { + + function bundle(context) { + return beta === 1 ? new Basis(context) : new Bundle(context, beta); + } + + bundle.beta = function(beta) { + return custom(+beta); + }; + + return bundle; +})(0.85); + +function point$1(that, x, y) { + that._context.bezierCurveTo( + that._x1 + that._k * (that._x2 - that._x0), + that._y1 + that._k * (that._y2 - that._y0), + that._x2 + that._k * (that._x1 - x), + that._y2 + that._k * (that._y1 - y), + that._x2, + that._y2 + ); +} + +function Cardinal(context, tension) { + this._context = context; + this._k = (1 - tension) / 6; +} + +Cardinal.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 2: this._context.lineTo(this._x2, this._y2); break; + case 3: point$1(this, this._x1, this._y1); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; this._x1 = x, this._y1 = y; break; + case 2: this._point = 3; // proceed + default: point$1(this, x, y); break; + } + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; + +var curveCardinal = (function custom(tension) { + + function cardinal(context) { + return new Cardinal(context, tension); + } + + cardinal.tension = function(tension) { + return custom(+tension); + }; + + return cardinal; +})(0); + +function CardinalClosed(context, tension) { + this._context = context; + this._k = (1 - tension) / 6; +} + +CardinalClosed.prototype = { + areaStart: noop$1, + areaEnd: noop$1, + lineStart: function() { + this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = + this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 1: { + this._context.moveTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 2: { + this._context.lineTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 3: { + this.point(this._x3, this._y3); + this.point(this._x4, this._y4); + this.point(this._x5, this._y5); + break; + } + } + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._x3 = x, this._y3 = y; break; + case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; + case 2: this._point = 3; this._x5 = x, this._y5 = y; break; + default: point$1(this, x, y); break; + } + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; + +var curveCardinalClosed = (function custom(tension) { + + function cardinal(context) { + return new CardinalClosed(context, tension); + } + + cardinal.tension = function(tension) { + return custom(+tension); + }; + + return cardinal; +})(0); + +function CardinalOpen(context, tension) { + this._context = context; + this._k = (1 - tension) / 6; +} + +CardinalOpen.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; + case 3: this._point = 4; // proceed + default: point$1(this, x, y); break; + } + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; + +var curveCardinalOpen = (function custom(tension) { + + function cardinal(context) { + return new CardinalOpen(context, tension); + } + + cardinal.tension = function(tension) { + return custom(+tension); + }; + + return cardinal; +})(0); + +function point$2(that, x, y) { + var x1 = that._x1, + y1 = that._y1, + x2 = that._x2, + y2 = that._y2; + + if (that._l01_a > epsilon$1) { + var a = 2 * that._l01_2a + 3 * that._l01_a * that._l12_a + that._l12_2a, + n = 3 * that._l01_a * (that._l01_a + that._l12_a); + x1 = (x1 * a - that._x0 * that._l12_2a + that._x2 * that._l01_2a) / n; + y1 = (y1 * a - that._y0 * that._l12_2a + that._y2 * that._l01_2a) / n; + } + + if (that._l23_a > epsilon$1) { + var b = 2 * that._l23_2a + 3 * that._l23_a * that._l12_a + that._l12_2a, + m = 3 * that._l23_a * (that._l23_a + that._l12_a); + x2 = (x2 * b + that._x1 * that._l23_2a - x * that._l12_2a) / m; + y2 = (y2 * b + that._y1 * that._l23_2a - y * that._l12_2a) / m; + } + + that._context.bezierCurveTo(x1, y1, x2, y2, that._x2, that._y2); +} + +function CatmullRom(context, alpha) { + this._context = context; + this._alpha = alpha; +} + +CatmullRom.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._l01_a = this._l12_a = this._l23_a = + this._l01_2a = this._l12_2a = this._l23_2a = + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 2: this._context.lineTo(this._x2, this._y2); break; + case 3: this.point(this._x2, this._y2); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + + if (this._point) { + var x23 = this._x2 - x, + y23 = this._y2 - y; + this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); + } + + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; // proceed + default: point$2(this, x, y); break; + } + + this._l01_a = this._l12_a, this._l12_a = this._l23_a; + this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; + +var curveCatmullRom = (function custom(alpha) { + + function catmullRom(context) { + return alpha ? new CatmullRom(context, alpha) : new Cardinal(context, 0); + } + + catmullRom.alpha = function(alpha) { + return custom(+alpha); + }; + + return catmullRom; +})(0.5); + +function CatmullRomClosed(context, alpha) { + this._context = context; + this._alpha = alpha; +} + +CatmullRomClosed.prototype = { + areaStart: noop$1, + areaEnd: noop$1, + lineStart: function() { + this._x0 = this._x1 = this._x2 = this._x3 = this._x4 = this._x5 = + this._y0 = this._y1 = this._y2 = this._y3 = this._y4 = this._y5 = NaN; + this._l01_a = this._l12_a = this._l23_a = + this._l01_2a = this._l12_2a = this._l23_2a = + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 1: { + this._context.moveTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 2: { + this._context.lineTo(this._x3, this._y3); + this._context.closePath(); + break; + } + case 3: { + this.point(this._x3, this._y3); + this.point(this._x4, this._y4); + this.point(this._x5, this._y5); + break; + } + } + }, + point: function(x, y) { + x = +x, y = +y; + + if (this._point) { + var x23 = this._x2 - x, + y23 = this._y2 - y; + this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); + } + + switch (this._point) { + case 0: this._point = 1; this._x3 = x, this._y3 = y; break; + case 1: this._point = 2; this._context.moveTo(this._x4 = x, this._y4 = y); break; + case 2: this._point = 3; this._x5 = x, this._y5 = y; break; + default: point$2(this, x, y); break; + } + + this._l01_a = this._l12_a, this._l12_a = this._l23_a; + this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; + +var curveCatmullRomClosed = (function custom(alpha) { + + function catmullRom(context) { + return alpha ? new CatmullRomClosed(context, alpha) : new CardinalClosed(context, 0); + } + + catmullRom.alpha = function(alpha) { + return custom(+alpha); + }; + + return catmullRom; +})(0.5); + +function CatmullRomOpen(context, alpha) { + this._context = context; + this._alpha = alpha; +} + +CatmullRomOpen.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = this._x2 = + this._y0 = this._y1 = this._y2 = NaN; + this._l01_a = this._l12_a = this._l23_a = + this._l01_2a = this._l12_2a = this._l23_2a = + this._point = 0; + }, + lineEnd: function() { + if (this._line || (this._line !== 0 && this._point === 3)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + + if (this._point) { + var x23 = this._x2 - x, + y23 = this._y2 - y; + this._l23_a = Math.sqrt(this._l23_2a = Math.pow(x23 * x23 + y23 * y23, this._alpha)); + } + + switch (this._point) { + case 0: this._point = 1; break; + case 1: this._point = 2; break; + case 2: this._point = 3; this._line ? this._context.lineTo(this._x2, this._y2) : this._context.moveTo(this._x2, this._y2); break; + case 3: this._point = 4; // proceed + default: point$2(this, x, y); break; + } + + this._l01_a = this._l12_a, this._l12_a = this._l23_a; + this._l01_2a = this._l12_2a, this._l12_2a = this._l23_2a; + this._x0 = this._x1, this._x1 = this._x2, this._x2 = x; + this._y0 = this._y1, this._y1 = this._y2, this._y2 = y; + } +}; + +var curveCatmullRomOpen = (function custom(alpha) { + + function catmullRom(context) { + return alpha ? new CatmullRomOpen(context, alpha) : new CardinalOpen(context, 0); + } + + catmullRom.alpha = function(alpha) { + return custom(+alpha); + }; + + return catmullRom; +})(0.5); + +function LinearClosed(context) { + this._context = context; +} + +LinearClosed.prototype = { + areaStart: noop$1, + areaEnd: noop$1, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._point) this._context.closePath(); + }, + point: function(x, y) { + x = +x, y = +y; + if (this._point) this._context.lineTo(x, y); + else this._point = 1, this._context.moveTo(x, y); + } +}; + +var curveLinearClosed = function(context) { + return new LinearClosed(context); +}; + +function sign(x) { + return x < 0 ? -1 : 1; +} + +// Calculate the slopes of the tangents (Hermite-type interpolation) based on +// the following paper: Steffen, M. 1990. A Simple Method for Monotonic +// Interpolation in One Dimension. Astronomy and Astrophysics, Vol. 239, NO. +// NOV(II), P. 443, 1990. +function slope3(that, x2, y2) { + var h0 = that._x1 - that._x0, + h1 = x2 - that._x1, + s0 = (that._y1 - that._y0) / (h0 || h1 < 0 && -0), + s1 = (y2 - that._y1) / (h1 || h0 < 0 && -0), + p = (s0 * h1 + s1 * h0) / (h0 + h1); + return (sign(s0) + sign(s1)) * Math.min(Math.abs(s0), Math.abs(s1), 0.5 * Math.abs(p)) || 0; +} + +// Calculate a one-sided slope. +function slope2(that, t) { + var h = that._x1 - that._x0; + return h ? (3 * (that._y1 - that._y0) / h - t) / 2 : t; +} + +// According to https://en.wikipedia.org/wiki/Cubic_Hermite_spline#Representations +// "you can express cubic Hermite interpolation in terms of cubic Bézier curves +// with respect to the four values p0, p0 + m0 / 3, p1 - m1 / 3, p1". +function point$3(that, t0, t1) { + var x0 = that._x0, + y0 = that._y0, + x1 = that._x1, + y1 = that._y1, + dx = (x1 - x0) / 3; + that._context.bezierCurveTo(x0 + dx, y0 + dx * t0, x1 - dx, y1 - dx * t1, x1, y1); +} + +function MonotoneX(context) { + this._context = context; +} + +MonotoneX.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x0 = this._x1 = + this._y0 = this._y1 = + this._t0 = NaN; + this._point = 0; + }, + lineEnd: function() { + switch (this._point) { + case 2: this._context.lineTo(this._x1, this._y1); break; + case 3: point$3(this, this._t0, slope2(this, this._t0)); break; + } + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + this._line = 1 - this._line; + }, + point: function(x, y) { + var t1 = NaN; + + x = +x, y = +y; + if (x === this._x1 && y === this._y1) return; // Ignore coincident points. + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; break; + case 2: this._point = 3; point$3(this, slope2(this, t1 = slope3(this, x, y)), t1); break; + default: point$3(this, this._t0, t1 = slope3(this, x, y)); break; + } + + this._x0 = this._x1, this._x1 = x; + this._y0 = this._y1, this._y1 = y; + this._t0 = t1; + } +}; + +function MonotoneY(context) { + this._context = new ReflectContext(context); +} + +(MonotoneY.prototype = Object.create(MonotoneX.prototype)).point = function(x, y) { + MonotoneX.prototype.point.call(this, y, x); +}; + +function ReflectContext(context) { + this._context = context; +} + +ReflectContext.prototype = { + moveTo: function(x, y) { this._context.moveTo(y, x); }, + closePath: function() { this._context.closePath(); }, + lineTo: function(x, y) { this._context.lineTo(y, x); }, + bezierCurveTo: function(x1, y1, x2, y2, x, y) { this._context.bezierCurveTo(y1, x1, y2, x2, y, x); } +}; + +function monotoneX(context) { + return new MonotoneX(context); +} + +function monotoneY(context) { + return new MonotoneY(context); +} + +function Natural(context) { + this._context = context; +} + +Natural.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x = []; + this._y = []; + }, + lineEnd: function() { + var x = this._x, + y = this._y, + n = x.length; + + if (n) { + this._line ? this._context.lineTo(x[0], y[0]) : this._context.moveTo(x[0], y[0]); + if (n === 2) { + this._context.lineTo(x[1], y[1]); + } else { + var px = controlPoints(x), + py = controlPoints(y); + for (var i0 = 0, i1 = 1; i1 < n; ++i0, ++i1) { + this._context.bezierCurveTo(px[0][i0], py[0][i0], px[1][i0], py[1][i0], x[i1], y[i1]); + } + } + } + + if (this._line || (this._line !== 0 && n === 1)) this._context.closePath(); + this._line = 1 - this._line; + this._x = this._y = null; + }, + point: function(x, y) { + this._x.push(+x); + this._y.push(+y); + } +}; + +// See https://www.particleincell.com/2012/bezier-splines/ for derivation. +function controlPoints(x) { + var i, + n = x.length - 1, + m, + a = new Array(n), + b = new Array(n), + r = new Array(n); + a[0] = 0, b[0] = 2, r[0] = x[0] + 2 * x[1]; + for (i = 1; i < n - 1; ++i) a[i] = 1, b[i] = 4, r[i] = 4 * x[i] + 2 * x[i + 1]; + a[n - 1] = 2, b[n - 1] = 7, r[n - 1] = 8 * x[n - 1] + x[n]; + for (i = 1; i < n; ++i) m = a[i] / b[i - 1], b[i] -= m, r[i] -= m * r[i - 1]; + a[n - 1] = r[n - 1] / b[n - 1]; + for (i = n - 2; i >= 0; --i) a[i] = (r[i] - a[i + 1]) / b[i]; + b[n - 1] = (x[n] + a[n - 1]) / 2; + for (i = 0; i < n - 1; ++i) b[i] = 2 * x[i + 1] - a[i + 1]; + return [a, b]; +} + +var curveNatural = function(context) { + return new Natural(context); +}; + +function Step(context, t) { + this._context = context; + this._t = t; +} + +Step.prototype = { + areaStart: function() { + this._line = 0; + }, + areaEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._x = this._y = NaN; + this._point = 0; + }, + lineEnd: function() { + if (0 < this._t && this._t < 1 && this._point === 2) this._context.lineTo(this._x, this._y); + if (this._line || (this._line !== 0 && this._point === 1)) this._context.closePath(); + if (this._line >= 0) this._t = 1 - this._t, this._line = 1 - this._line; + }, + point: function(x, y) { + x = +x, y = +y; + switch (this._point) { + case 0: this._point = 1; this._line ? this._context.lineTo(x, y) : this._context.moveTo(x, y); break; + case 1: this._point = 2; // proceed + default: { + if (this._t <= 0) { + this._context.lineTo(this._x, y); + this._context.lineTo(x, y); + } else { + var x1 = this._x * (1 - this._t) + x * this._t; + this._context.lineTo(x1, this._y); + this._context.lineTo(x1, y); + } + break; + } + } + this._x = x, this._y = y; + } +}; + +var curveStep = function(context) { + return new Step(context, 0.5); +}; + +function stepBefore(context) { + return new Step(context, 0); +} + +function stepAfter(context) { + return new Step(context, 1); +} + +var lookup = { + 'basis': { + curve: curveBasis + }, + 'basis-closed': { + curve: curveBasisClosed + }, + 'basis-open': { + curve: curveBasisOpen + }, + 'bundle': { + curve: curveBundle, + tension: 'beta', + value: 0.85 + }, + 'cardinal': { + curve: curveCardinal, + tension: 'tension', + value: 0 + }, + 'cardinal-open': { + curve: curveCardinalOpen, + tension: 'tension', + value: 0 + }, + 'cardinal-closed': { + curve: curveCardinalClosed, + tension: 'tension', + value: 0 + }, + 'catmull-rom': { + curve: curveCatmullRom, + tension: 'alpha', + value: 0.5 + }, + 'catmull-rom-closed': { + curve: curveCatmullRomClosed, + tension: 'alpha', + value: 0.5 + }, + 'catmull-rom-open': { + curve: curveCatmullRomOpen, + tension: 'alpha', + value: 0.5 + }, + 'linear': { + curve: curveLinear + }, + 'linear-closed': { + curve: curveLinearClosed + }, + 'monotone': { + horizontal: monotoneY, + vertical: monotoneX + }, + 'natural': { + curve: curveNatural + }, + 'step': { + curve: curveStep + }, + 'step-after': { + curve: stepAfter + }, + 'step-before': { + curve: stepBefore + } +}; + +function curves(type, orientation, tension) { + var entry = lookup.hasOwnProperty(type) && lookup[type], + curve = null; + + if (entry) { + curve = entry.curve || entry[orientation || 'vertical']; + if (entry.tension && tension != null) { + curve = curve[entry.tension](tension); + } + } + + return curve; +} + +// Path parsing and rendering code adapted from fabric.js -- Thanks! +var cmdlen = { m:2, l:2, h:1, v:1, c:6, s:4, q:4, t:2, a:7 }; +var regexp = [/([MLHVCSQTAZmlhvcsqtaz])/g, /###/, /(\d)([-+])/g, /\s|,|###/]; + +var pathParse = function(pathstr) { + var result = [], + path, + curr, + chunks, + parsed, param, + cmd, len, i, j, n, m; + + // First, break path into command sequence + path = pathstr + .slice() + .replace(regexp[0], '###$1') + .split(regexp[1]) + .slice(1); + + // Next, parse each command in turn + for (i=0, n=path.length; i len) { + for (j=1, m=parsed.length; j 1) { + pl = Math.sqrt(pl); + rx *= pl; + ry *= pl; + } + + var a00 = cos_th / rx; + var a01 = sin_th / rx; + var a10 = (-sin_th) / ry; + var a11 = (cos_th) / ry; + var x0 = a00 * ox + a01 * oy; + var y0 = a10 * ox + a11 * oy; + var x1 = a00 * x + a01 * y; + var y1 = a10 * x + a11 * y; + + var d = (x1-x0) * (x1-x0) + (y1-y0) * (y1-y0); + var sfactor_sq = 1 / d - 0.25; + if (sfactor_sq < 0) sfactor_sq = 0; + var sfactor = Math.sqrt(sfactor_sq); + if (sweep == large) sfactor = -sfactor; + var xc = 0.5 * (x0 + x1) - sfactor * (y1-y0); + var yc = 0.5 * (y0 + y1) + sfactor * (x1-x0); + + var th0 = Math.atan2(y0-yc, x0-xc); + var th1 = Math.atan2(y1-yc, x1-xc); + + var th_arc = th1-th0; + if (th_arc < 0 && sweep === 1){ + th_arc += 2 * Math.PI; + } else if (th_arc > 0 && sweep === 0) { + th_arc -= 2 * Math.PI; + } + + var segs = Math.ceil(Math.abs(th_arc / (Math.PI * 0.5 + 0.001))); + var result = []; + for (var i=0; i circleThreshold) { + add$1(cx - r, cy - r); + add$1(cx + r, cy + r); + return; + } + + var xmin = Infinity, xmax = -Infinity, + ymin = Infinity, ymax = -Infinity, + s, i, x, y; + + function update(a) { + x = r * Math.cos(a); + y = r * Math.sin(a); + if (x < xmin) xmin = x; + if (x > xmax) xmax = x; + if (y < ymin) ymin = y; + if (y > ymax) ymax = y; + } + + // Sample end points and interior points aligned with 90 degrees + update(sa); + update(ea); + + if (ea !== sa) { + sa = sa % tau$3; if (sa < 0) sa += tau$3; + ea = ea % tau$3; if (ea < 0) ea += tau$3; + + if (ea < sa) { + ccw = !ccw; // flip direction + s = sa; sa = ea; ea = s; // swap end-points + } + + if (ccw) { + ea -= tau$3; + s = sa - (sa % halfPi$1); + for (i=0; i<4 && s>ea; ++i, s-=halfPi$1) update(s); + } else { + s = sa - (sa % halfPi$1) + halfPi$1; + for (i=0; i<4 && s 0) { + context.globalAlpha = opacity; + context.fillStyle = color(context, item, item.fill); + return true; + } else { + return false; + } +}; + +var Empty$1 = []; + +var stroke = function(context, item, opacity) { + var lw = (lw = item.strokeWidth) != null ? lw : 1; + + if (lw <= 0) return false; + + opacity *= (item.strokeOpacity==null ? 1 : item.strokeOpacity); + if (opacity > 0) { + context.globalAlpha = opacity; + context.strokeStyle = color(context, item, item.stroke); + + context.lineWidth = lw; + context.lineCap = item.strokeCap || 'butt'; + context.lineJoin = item.strokeJoin || 'miter'; + context.miterLimit = item.strokeMiterLimit || 10; + + if (context.setLineDash) { + context.setLineDash(item.strokeDash || Empty$1); + context.lineDashOffset = item.strokeDashOffset || 0; + } + return true; + } else { + return false; + } +}; + +function compare$1(a, b) { + return a.zindex - b.zindex || a.index - b.index; +} + +function zorder(scene) { + if (!scene.zdirty) return scene.zitems; + + var items = scene.items, + output = [], item, i, n; + + for (i=0, n=items.length; i= 0;) { + if (hit = visitor(items[i])) return hit; + } + + if (items === zitems) { + for (items=scene.items, i=items.length; --i >= 0;) { + if (!items[i].zindex) { + if (hit = visitor(items[i])) return hit; + } + } + } + + return null; +} + +function drawAll(path) { + return function(context, scene, bounds) { + visit(scene, function(item) { + if (!bounds || bounds.intersects(item.bounds)) { + drawPath(path, context, item, item); + } + }); + }; +} + +function drawOne(path) { + return function(context, scene, bounds) { + if (scene.items.length && (!bounds || bounds.intersects(scene.bounds))) { + drawPath(path, context, scene.items[0], scene.items); + } + }; +} + +function drawPath(path, context, item, items) { + var opacity = item.opacity == null ? 1 : item.opacity; + if (opacity === 0) return; + + if (path(context, items)) return; + + if (item.fill && fill(context, item, opacity)) { + context.fill(); + } + + if (item.stroke && stroke(context, item, opacity)) { + context.stroke(); + } +} + +var trueFunc = function() { return true; }; + +function pick(test) { + if (!test) test = trueFunc; + + return function(context, scene, x, y, gx, gy) { + if (context.pixelRatio > 1) { + x *= context.pixelRatio; + y *= context.pixelRatio; + } + + return pickVisit(scene, function(item) { + var b = item.bounds; + // first hit test against bounding box + if ((b && !b.contains(gx, gy)) || !b) return; + // if in bounding box, perform more careful test + if (test(context, item, x, y, gx, gy)) return item; + }); + }; +} + +function hitPath(path, filled) { + return function(context, o, x, y) { + var item = Array.isArray(o) ? o[0] : o, + fill = (filled == null) ? item.fill : filled, + stroke = item.stroke && context.isPointInStroke, lw, lc; + + if (stroke) { + lw = item.strokeWidth; + lc = item.strokeCap; + context.lineWidth = lw != null ? lw : 1; + context.lineCap = lc != null ? lc : 'butt'; + } + + return path(context, o) ? false : + (fill && context.isPointInPath(x, y)) || + (stroke && context.isPointInStroke(x, y)); + }; +} + +function pickPath(path) { + return pick(hitPath(path)); +} + +var translate = function(x, y) { + return 'translate(' + x + ',' + y + ')'; +}; + +var translateItem = function(item) { + return translate(item.x || 0, item.y || 0); +}; + +var markItemPath = function(type, shape) { + + function attr(emit, item) { + emit('transform', translateItem(item)); + emit('d', shape(null, item)); + } + + function bound(bounds, item) { + shape(context(bounds), item); + return boundStroke(bounds, item) + .translate(item.x || 0, item.y || 0); + } + + function draw(context$$1, item) { + var x = item.x || 0, + y = item.y || 0; + context$$1.translate(x, y); + context$$1.beginPath(); + shape(context$$1, item); + context$$1.translate(-x, -y); + } + + return { + type: type, + tag: 'path', + nested: false, + attr: attr, + bound: bound, + draw: drawAll(draw), + pick: pickPath(draw) + }; + +}; + +var arc = markItemPath('arc', arc$1); + +var markMultiItemPath = function(type, shape) { + + function attr(emit, item) { + var items = item.mark.items; + if (items.length) emit('d', shape(null, items)); + } + + function bound(bounds, mark) { + var items = mark.items; + if (items.length === 0) { + return bounds; + } else { + shape(context(bounds), items); + return boundStroke(bounds, items[0]); + } + } + + function draw(context$$1, items) { + context$$1.beginPath(); + shape(context$$1, items); + } + + var hit = hitPath(draw); + + function pick$$1(context$$1, scene, x, y, gx, gy) { + var items = scene.items, + b = scene.bounds; + + if (!items || !items.length || b && !b.contains(gx, gy)) { + return null; + } + + if (context$$1.pixelRatio > 1) { + x *= context$$1.pixelRatio; + y *= context$$1.pixelRatio; + } + return hit(context$$1, items, x, y) ? items[0] : null; + } + + return { + type: type, + tag: 'path', + nested: true, + attr: attr, + bound: bound, + draw: drawOne(draw), + pick: pick$$1 + }; + +}; + +var area$2 = markMultiItemPath('area', area); + +var clip_id = 1; + +function resetSVGClipId() { + clip_id = 1; +} + +var clip = function(renderer, item, size) { + var clip = item.clip, + defs = renderer._defs, + id$$1 = item.clip_id || (item.clip_id = 'clip' + clip_id++), + c = defs.clipping[id$$1] || (defs.clipping[id$$1] = {id: id$$1}); + + if (isFunction(clip)) { + c.path = clip(null); + } else { + c.width = size.width || 0; + c.height = size.height || 0; + } + + return 'url(#' + id$$1 + ')'; +}; + +var StrokeOffset = 0.5; + +function attr(emit, item) { + emit('transform', translateItem(item)); +} + +function background(emit, item) { + var offset = item.stroke ? StrokeOffset : 0; + emit('class', 'background'); + emit('d', rectangle(null, item, offset, offset)); +} + +function foreground(emit, item, renderer) { + var url = item.clip ? clip(renderer, item, item) : null; + emit('clip-path', url); +} + +function bound(bounds, group) { + if (!group.clip && group.items) { + var items = group.items; + for (var j=0, m=items.length; j 0) { + context.beginPath(); + offset = group.stroke ? StrokeOffset : 0; + rectangle(context, group, offset, offset); + if (group.fill && fill(context, group, opacity)) { + context.fill(); + } + if (group.stroke && stroke(context, group, opacity)) { + context.stroke(); + } + } + } + + // set clip and bounds + if (group.clip) { + context.beginPath(); + context.rect(0, 0, w, h); + context.clip(); + } + if (bounds) bounds.translate(-gx, -gy); + + // draw group contents + visit(group, function(item) { + renderer.draw(context, item, bounds); + }); + + // restore graphics context + if (bounds) bounds.translate(gx, gy); + context.restore(); + }); +} + +function pick$1(context, scene, x, y, gx, gy) { + if (scene.bounds && !scene.bounds.contains(gx, gy) || !scene.items) { + return null; + } + + var handler = this; + + return pickVisit(scene, function(group) { + var hit, dx, dy, b; + + // first hit test against bounding box + // if a group is clipped, that should be handled by the bounds check. + b = group.bounds; + if (b && !b.contains(gx, gy)) return; + + // passed bounds check, so test sub-groups + dx = (group.x || 0); + dy = (group.y || 0); + + context.save(); + context.translate(dx, dy); + + dx = gx - dx; + dy = gy - dy; + + hit = pickVisit(group, function(mark) { + return pickMark(mark, dx, dy) + ? handler.pick(mark, x, y, dx, dy) + : null; + }); + + context.restore(); + if (hit) return hit; + + hit = scene.interactive !== false + && (group.fill || group.stroke) + && dx >= 0 + && dx <= group.width + && dy >= 0 + && dy <= group.height; + + return hit ? group : null; + }); +} + +function pickMark(mark, x, y) { + return (mark.interactive !== false || mark.marktype === 'group') + && mark.bounds && mark.bounds.contains(x, y); +} + +var group = { + type: 'group', + tag: 'g', + nested: false, + attr: attr, + bound: bound, + draw: draw, + pick: pick$1, + background: background, + foreground: foreground +}; + +function getImage(item, renderer) { + var image = item.image; + if (!image || image.url !== item.url) { + image = {loaded: false, width: 0, height: 0}; + renderer.loadImage(item.url).then(function(image) { + item.image = image; + item.image.url = item.url; + }); + } + return image; +} + +function imageXOffset(align, w) { + return align === 'center' ? w / 2 : align === 'right' ? w : 0; +} + +function imageYOffset(baseline, h) { + return baseline === 'middle' ? h / 2 : baseline === 'bottom' ? h : 0; +} + +function attr$1(emit, item, renderer) { + var image = getImage(item, renderer), + x = item.x || 0, + y = item.y || 0, + w = (item.width != null ? item.width : image.width) || 0, + h = (item.height != null ? item.height : image.height) || 0, + a = item.aspect === false ? 'none' : 'xMidYMid'; + + x -= imageXOffset(item.align, w); + y -= imageYOffset(item.baseline, h); + + emit('href', image.src || '', 'http://www.w3.org/1999/xlink', 'xlink:href'); + emit('transform', translate(x, y)); + emit('width', w); + emit('height', h); + emit('preserveAspectRatio', a); +} + +function bound$1(bounds, item) { + var image = item.image, + x = item.x || 0, + y = item.y || 0, + w = (item.width != null ? item.width : (image && image.width)) || 0, + h = (item.height != null ? item.height : (image && image.height)) || 0; + + x -= imageXOffset(item.align, w); + y -= imageYOffset(item.baseline, h); + + return bounds.set(x, y, x + w, y + h); +} + +function draw$1(context, scene, bounds) { + var renderer = this; + + visit(scene, function(item) { + if (bounds && !bounds.intersects(item.bounds)) return; // bounds check + + var image = getImage(item, renderer), + x = item.x || 0, + y = item.y || 0, + w = (item.width != null ? item.width : image.width) || 0, + h = (item.height != null ? item.height : image.height) || 0, + opacity, ar0, ar1, t; + + x -= imageXOffset(item.align, w); + y -= imageYOffset(item.baseline, h); + + if (item.aspect !== false) { + ar0 = image.width / image.height; + ar1 = item.width / item.height; + if (ar0 === ar0 && ar1 === ar1 && ar0 !== ar1) { + if (ar1 < ar0) { + t = w / ar0; + y += (h - t) / 2; + h = t; + } else { + t = h * ar0; + x += (w - t) / 2; + w = t; + } + } + } + + if (image.loaded) { + context.globalAlpha = (opacity = item.opacity) != null ? opacity : 1; + context.drawImage(image, x, y, w, h); + } + }); +} + +var image$1 = { + type: 'image', + tag: 'image', + nested: false, + attr: attr$1, + bound: bound$1, + draw: draw$1, + pick: pick(), + get: getImage, + xOffset: imageXOffset, + yOffset: imageYOffset +}; + +var line$2 = markMultiItemPath('line', line); + +function attr$2(emit, item) { + emit('transform', translateItem(item)); + emit('d', item.path); +} + +function path$2(context$$1, item) { + var path = item.path; + if (path == null) return true; + + var cache = item.pathCache; + if (!cache || cache.path !== path) { + (item.pathCache = cache = pathParse(path)).path = path; + } + pathRender(context$$1, cache, item.x, item.y); +} + +function bound$2(bounds, item) { + return path$2(context(bounds), item) + ? bounds.set(0, 0, 0, 0) + : boundStroke(bounds, item); +} + +var path$3 = { + type: 'path', + tag: 'path', + nested: false, + attr: attr$2, + bound: bound$2, + draw: drawAll(path$2), + pick: pickPath(path$2) +}; + +function attr$3(emit, item) { + emit('d', rectangle(null, item)); +} + +function bound$3(bounds, item) { + var x, y; + return boundStroke(bounds.set( + x = item.x || 0, + y = item.y || 0, + (x + item.width) || 0, + (y + item.height) || 0 + ), item); +} + +function draw$2(context, item) { + context.beginPath(); + rectangle(context, item); +} + +var rect = { + type: 'rect', + tag: 'path', + nested: false, + attr: attr$3, + bound: bound$3, + draw: drawAll(draw$2), + pick: pickPath(draw$2) +}; + +function attr$4(emit, item) { + emit('transform', translateItem(item)); + emit('x2', item.x2 != null ? item.x2 - (item.x||0) : 0); + emit('y2', item.y2 != null ? item.y2 - (item.y||0) : 0); +} + +function bound$4(bounds, item) { + var x1, y1; + return boundStroke(bounds.set( + x1 = item.x || 0, + y1 = item.y || 0, + item.x2 != null ? item.x2 : x1, + item.y2 != null ? item.y2 : y1 + ), item); +} + +function path$4(context, item, opacity) { + var x1, y1, x2, y2; + + if (item.stroke && stroke(context, item, opacity)) { + x1 = item.x || 0; + y1 = item.y || 0; + x2 = item.x2 != null ? item.x2 : x1; + y2 = item.y2 != null ? item.y2 : y1; + context.beginPath(); + context.moveTo(x1, y1); + context.lineTo(x2, y2); + return true; + } + return false; +} + +function draw$3(context, scene, bounds) { + visit(scene, function(item) { + if (bounds && !bounds.intersects(item.bounds)) return; // bounds check + var opacity = item.opacity == null ? 1 : item.opacity; + if (opacity && path$4(context, item, opacity)) { + context.stroke(); + } + }); +} + +function hit(context, item, x, y) { + if (!context.isPointInStroke) return false; + return path$4(context, item, 1) && context.isPointInStroke(x, y); +} + +var rule = { + type: 'rule', + tag: 'line', + nested: false, + attr: attr$4, + bound: bound$4, + draw: draw$3, + pick: pick(hit) +}; + +var shape$1 = markItemPath('shape', shape); + +var symbol$1 = markItemPath('symbol', symbol); + +var context$1; +var fontHeight; + +var textMetrics = { + height: height, + measureWidth: measureWidth, + estimateWidth: estimateWidth, + width: estimateWidth, + canvas: useCanvas +}; + +useCanvas(true); + +// make dumb, simple estimate if no canvas is available +function estimateWidth(item) { + fontHeight = height(item); + return estimate(textValue(item)); +} + +function estimate(text) { + return ~~(0.8 * text.length * fontHeight); +} + +// measure text width if canvas is available +function measureWidth(item) { + context$1.font = font(item); + return measure$1(textValue(item)); +} + +function measure$1(text) { + return context$1.measureText(text).width; +} + +function height(item) { + return item.fontSize != null ? item.fontSize : 11; +} + +function useCanvas(use) { + context$1 = use && (context$1 = canvas(1,1)) ? context$1.getContext('2d') : null; + textMetrics.width = context$1 ? measureWidth : estimateWidth; +} + +function textValue(item) { + var s = item.text; + if (s == null) { + return ''; + } else { + return item.limit > 0 ? truncate$1(item) : s + ''; + } +} + +function truncate$1(item) { + var limit = +item.limit, + text = item.text + '', + width; + + if (context$1) { + context$1.font = font(item); + width = measure$1; + } else { + fontHeight = height(item); + width = estimate; + } + + if (width(text) < limit) return text; + + var ellipsis = item.ellipsis || '\u2026', + rtl = item.dir === 'rtl', + lo = 0, + hi = text.length, mid; + + limit -= width(ellipsis); + + if (rtl) { + while (lo < hi) { + mid = (lo + hi >>> 1); + if (width(text.slice(mid)) > limit) lo = mid + 1; + else hi = mid; + } + return ellipsis + text.slice(lo); + } else { + while (lo < hi) { + mid = 1 + (lo + hi >>> 1); + if (width(text.slice(0, mid)) < limit) lo = mid; + else hi = mid - 1; + } + return text.slice(0, lo) + ellipsis; + } +} + + +function font(item, quote) { + var font = item.font; + if (quote && font) { + font = String(font).replace(/"/g, '\''); + } + return '' + + (item.fontStyle ? item.fontStyle + ' ' : '') + + (item.fontVariant ? item.fontVariant + ' ' : '') + + (item.fontWeight ? item.fontWeight + ' ' : '') + + height(item) + 'px ' + + (font || 'sans-serif'); +} + +function offset(item) { + // perform our own font baseline calculation + // why? not all browsers support SVG 1.1 'alignment-baseline' :( + var baseline = item.baseline, + h = height(item); + return Math.round( + baseline === 'top' ? 0.79*h : + baseline === 'middle' ? 0.30*h : + baseline === 'bottom' ? -0.21*h : 0 + ); +} + +var textAlign = { + 'left': 'start', + 'center': 'middle', + 'right': 'end' +}; + +var tempBounds = new Bounds(); + +function attr$5(emit, item) { + var dx = item.dx || 0, + dy = (item.dy || 0) + offset(item), + x = item.x || 0, + y = item.y || 0, + a = item.angle || 0, + r = item.radius || 0, t; + + if (r) { + t = (item.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + emit('text-anchor', textAlign[item.align] || 'start'); + + if (a) { + t = translate(x, y) + ' rotate('+a+')'; + if (dx || dy) t += ' ' + translate(dx, dy); + } else { + t = translate(x + dx, y + dy); + } + emit('transform', t); +} + +function bound$5(bounds, item, noRotate) { + var h = textMetrics.height(item), + a = item.align, + r = item.radius || 0, + x = item.x || 0, + y = item.y || 0, + dx = item.dx || 0, + dy = (item.dy || 0) + offset(item) - Math.round(0.8*h), // use 4/5 offset + w, t; + + if (r) { + t = (item.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + // horizontal alignment + w = textMetrics.width(item); + if (a === 'center') { + dx -= (w / 2); + } else if (a === 'right') { + dx -= w; + } else { + // left by default, do nothing + } + + bounds.set(dx+=x, dy+=y, dx+w, dy+h); + if (item.angle && !noRotate) { + bounds.rotate(item.angle*Math.PI/180, x, y); + } + return bounds.expand(noRotate || !w ? 0 : 1); +} + +function draw$4(context, scene, bounds) { + visit(scene, function(item) { + var opacity, x, y, r, t, str; + if (bounds && !bounds.intersects(item.bounds)) return; // bounds check + if (!(str = textValue(item))) return; // get text string + + opacity = item.opacity == null ? 1 : item.opacity; + if (opacity === 0) return; + + context.font = font(item); + context.textAlign = item.align || 'left'; + + x = item.x || 0; + y = item.y || 0; + if ((r = item.radius)) { + t = (item.theta || 0) - Math.PI/2; + x += r * Math.cos(t); + y += r * Math.sin(t); + } + + if (item.angle) { + context.save(); + context.translate(x, y); + context.rotate(item.angle * Math.PI/180); + x = y = 0; // reset x, y + } + x += (item.dx || 0); + y += (item.dy || 0) + offset(item); + + if (item.fill && fill(context, item, opacity)) { + context.fillText(str, x, y); + } + if (item.stroke && stroke(context, item, opacity)) { + context.strokeText(str, x, y); + } + if (item.angle) context.restore(); + }); +} + +function hit$1(context, item, x, y, gx, gy) { + if (item.fontSize <= 0) return false; + if (!item.angle) return true; // bounds sufficient if no rotation + + // project point into space of unrotated bounds + var b = bound$5(tempBounds, item, true), + a = -item.angle * Math.PI / 180, + cos = Math.cos(a), + sin = Math.sin(a), + ix = item.x, + iy = item.y, + px = cos*gx - sin*gy + (ix - ix*cos + iy*sin), + py = sin*gx + cos*gy + (iy - ix*sin - iy*cos); + + return b.contains(px, py); +} + +var text$1 = { + type: 'text', + tag: 'text', + nested: false, + attr: attr$5, + bound: bound$5, + draw: draw$4, + pick: pick(hit$1) +}; + +var trail$1 = markMultiItemPath('trail', trail); + +var marks = { + arc: arc, + area: area$2, + group: group, + image: image$1, + line: line$2, + path: path$3, + rect: rect, + rule: rule, + shape: shape$1, + symbol: symbol$1, + text: text$1, + trail: trail$1 +}; + +var boundItem$1 = function(item, func, opt) { + var type = marks[item.mark.marktype], + bound = func || type.bound; + if (type.nested) item = item.mark; + + return bound(item.bounds || (item.bounds = new Bounds()), item, opt); +}; + +var DUMMY = {mark: null}; + +var boundMark = function(mark, bounds, opt) { + var type = marks[mark.marktype], + bound = type.bound, + items = mark.items, + hasItems = items && items.length, + i, n, item, b; + + if (type.nested) { + if (hasItems) { + item = items[0]; + } else { + // no items, fake it + DUMMY.mark = mark; + item = DUMMY; + } + b = boundItem$1(item, bound, opt); + bounds = bounds && bounds.union(b) || b; + return bounds; + } + + bounds = bounds + || mark.bounds && mark.bounds.clear() + || new Bounds(); + + if (hasItems) { + for (i=0, n=items.length; i index) el.removeChild(nodes[--curr]); + return el; +} + +// generate css class name for mark +function cssClass(mark) { + return 'mark-' + mark.marktype + + (mark.role ? ' role-' + mark.role : '') + + (mark.name ? ' ' + mark.name : ''); +} + +function Handler(customLoader) { + this._active = null; + this._handlers = {}; + this._loader = customLoader || loader(); +} + +var prototype$42 = Handler.prototype; + +prototype$42.initialize = function(el, origin, obj) { + this._el = el; + this._obj = obj || null; + return this.origin(origin); +}; + +prototype$42.element = function() { + return this._el; +}; + +prototype$42.origin = function(origin) { + this._origin = origin || [0, 0]; + return this; +}; + +prototype$42.scene = function(scene) { + if (!arguments.length) return this._scene; + this._scene = scene; + return this; +}; + +// add an event handler +// subclasses should override +prototype$42.on = function(/*type, handler*/) {}; + +// remove an event handler +// subclasses should override +prototype$42.off = function(/*type, handler*/) {}; + +// utility method for finding array index of registered handler +// returns -1 if handler is not registered +prototype$42._handlerIndex = function(h, type, handler) { + for (var i = h ? h.length : 0; --i>=0;) { + if (h[i].type === type && !handler || h[i].handler === handler) { + return i; + } + } + return -1; +}; + +// return an array with all registered event handlers +prototype$42.handlers = function() { + var h = this._handlers, a = [], k; + for (k in h) { a.push.apply(a, h[k]); } + return a; +}; + +prototype$42.eventName = function(name) { + var i = name.indexOf('.'); + return i < 0 ? name : name.slice(0,i); +}; + +prototype$42.handleHref = function(event, item, href) { + this._loader + .sanitize(href, {context:'href'}) + .then(function(opt) { + var e = new MouseEvent(event.type, event), + a = domCreate(null, 'a'); + for (var name in opt) a.setAttribute(name, opt[name]); + a.dispatchEvent(e); + }) + .catch(function() { /* do nothing */ }); +}; + +prototype$42.handleTooltip = function(event, item, tooltipText) { + this._el.setAttribute('title', tooltipText || ''); +}; + +/** + * Create a new Renderer instance. + * @param {object} [loader] - Optional loader instance for + * image and href URL sanitization. If not specified, a + * standard loader instance will be generated. + * @constructor + */ +function Renderer(loader) { + this._el = null; + this._bgcolor = null; + this._loader = new ResourceLoader(loader); +} + +var prototype$43 = Renderer.prototype; + +/** + * Initialize a new Renderer instance. + * @param {DOMElement} el - The containing DOM element for the display. + * @param {number} width - The coordinate width of the display, in pixels. + * @param {number} height - The coordinate height of the display, in pixels. + * @param {Array} origin - The origin of the display, in pixels. + * The coordinate system will be translated to this point. + * @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply + * the width and height to determine the final pixel size. + * @return {Renderer} - This renderer instance; + */ +prototype$43.initialize = function(el, width, height, origin, scaleFactor) { + this._el = el; + return this.resize(width, height, origin, scaleFactor); +}; + +/** + * Returns the parent container element for a visualization. + * @return {DOMElement} - The containing DOM element. + */ +prototype$43.element = function() { + return this._el; +}; + +/** + * Returns the scene element (e.g., canvas or SVG) of the visualization + * Subclasses must override if the first child is not the scene element. + * @return {DOMElement} - The scene (e.g., canvas or SVG) element. + */ +prototype$43.scene = function() { + return this._el && this._el.firstChild; +}; + +/** + * Get / set the background color. + */ +prototype$43.background = function(bgcolor) { + if (arguments.length === 0) return this._bgcolor; + this._bgcolor = bgcolor; + return this; +}; + +/** + * Resize the display. + * @param {number} width - The new coordinate width of the display, in pixels. + * @param {number} height - The new coordinate height of the display, in pixels. + * @param {Array} origin - The new origin of the display, in pixels. + * The coordinate system will be translated to this point. + * @param {number} [scaleFactor=1] - Optional scaleFactor by which to multiply + * the width and height to determine the final pixel size. + * @return {Renderer} - This renderer instance; + */ +prototype$43.resize = function(width, height, origin, scaleFactor) { + this._width = width; + this._height = height; + this._origin = origin || [0, 0]; + this._scale = scaleFactor || 1; + return this; +}; + +/** + * Report a dirty item whose bounds should be redrawn. + * This base class method does nothing. Subclasses that perform + * incremental should implement this method. + * @param {Item} item - The dirty item whose bounds should be redrawn. + */ +prototype$43.dirty = function(/*item*/) { +}; + +/** + * Render an input scenegraph, potentially with a set of dirty items. + * This method will perform an immediate rendering with available resources. + * The renderer may also need to perform image loading to perform a complete + * render. This process can lead to asynchronous re-rendering of the scene + * after this method returns. To receive notification when rendering is + * complete, use the renderAsync method instead. + * @param {object} scene - The root mark of a scenegraph to render. + * @return {Renderer} - This renderer instance. + */ +prototype$43.render = function(scene) { + var r = this; + + // bind arguments into a render call, and cache it + // this function may be subsequently called for async redraw + r._call = function() { r._render(scene); }; + + // invoke the renderer + r._call(); + + // clear the cached call for garbage collection + // async redraws will stash their own copy + r._call = null; + + return r; +}; + +/** + * Internal rendering method. Renderer subclasses should override this + * method to actually perform rendering. + * @param {object} scene - The root mark of a scenegraph to render. + */ +prototype$43._render = function(/*scene*/) { + // subclasses to override +}; + +/** + * Asynchronous rendering method. Similar to render, but returns a Promise + * that resolves when all rendering is completed. Sometimes a renderer must + * perform image loading to get a complete rendering. The returned + * Promise will not resolve until this process completes. + * @param {object} scene - The root mark of a scenegraph to render. + * @return {Promise} - A Promise that resolves when rendering is complete. + */ +prototype$43.renderAsync = function(scene) { + var r = this.render(scene); + return this._ready + ? this._ready.then(function() { return r; }) + : Promise.resolve(r); +}; + +/** + * Internal method for asynchronous resource loading. + * Proxies method calls to the ImageLoader, and tracks loading + * progress to invoke a re-render once complete. + * @param {string} method - The method name to invoke on the ImageLoader. + * @param {string} uri - The URI for the requested resource. + * @return {Promise} - A Promise that resolves to the requested resource. + */ +prototype$43._load = function(method, uri) { + var r = this, + p = r._loader[method](uri); + + if (!r._ready) { + // re-render the scene when loading completes + var call = r._call; + r._ready = r._loader.ready() + .then(function(redraw) { + if (redraw) call(); + r._ready = null; + }); + } + + return p; +}; + +/** + * Sanitize a URL to include as a hyperlink in the rendered scene. + * This method proxies a call to ImageLoader.sanitizeURL, but also tracks + * image loading progress and invokes a re-render once complete. + * @param {string} uri - The URI string to sanitize. + * @return {Promise} - A Promise that resolves to the sanitized URL. + */ +prototype$43.sanitizeURL = function(uri) { + return this._load('sanitizeURL', uri); +}; + +/** + * Requests an image to include in the rendered scene. + * This method proxies a call to ImageLoader.loadImage, but also tracks + * image loading progress and invokes a re-render once complete. + * @param {string} uri - The URI string of the image. + * @return {Promise} - A Promise that resolves to the loaded Image. + */ +prototype$43.loadImage = function(uri) { + return this._load('loadImage', uri); +}; + +var point$4 = function(event, el) { + var rect = el.getBoundingClientRect(); + return [ + event.clientX - rect.left - (el.clientLeft || 0), + event.clientY - rect.top - (el.clientTop || 0) + ]; +}; + +function CanvasHandler(loader) { + Handler.call(this, loader); + this._down = null; + this._touch = null; + this._first = true; +} + +var prototype$44 = inherits(CanvasHandler, Handler); + +prototype$44.initialize = function(el, origin, obj) { + // add event listeners + var canvas = this._canvas = el && domFind(el, 'canvas'); + if (canvas) { + var that = this; + this.events.forEach(function(type) { + canvas.addEventListener(type, function(evt) { + if (prototype$44[type]) { + prototype$44[type].call(that, evt); + } else { + that.fire(type, evt); + } + }); + }); + } + + return Handler.prototype.initialize.call(this, el, origin, obj); +}; + +prototype$44.canvas = function() { + return this._canvas; +}; + +// retrieve the current canvas context +prototype$44.context = function() { + return this._canvas.getContext('2d'); +}; + +// supported events +prototype$44.events = [ + 'keydown', + 'keypress', + 'keyup', + 'dragenter', + 'dragleave', + 'dragover', + 'mousedown', + 'mouseup', + 'mousemove', + 'mouseout', + 'mouseover', + 'click', + 'dblclick', + 'wheel', + 'mousewheel', + 'touchstart', + 'touchmove', + 'touchend' +]; + +// to keep old versions of firefox happy +prototype$44.DOMMouseScroll = function(evt) { + this.fire('mousewheel', evt); +}; + +function move(moveEvent, overEvent, outEvent) { + return function(evt) { + var a = this._active, + p = this.pickEvent(evt); + + if (p === a) { + // active item and picked item are the same + this.fire(moveEvent, evt); // fire move + } else { + // active item and picked item are different + if (!a || !a.exit) { + // fire out for prior active item + // suppress if active item was removed from scene + this.fire(outEvent, evt); + } + this._active = p; // set new active item + this.fire(overEvent, evt); // fire over for new active item + this.fire(moveEvent, evt); // fire move for new active item + } + }; +} + +function inactive(type) { + return function(evt) { + this.fire(type, evt); + this._active = null; + }; +} + +prototype$44.mousemove = move('mousemove', 'mouseover', 'mouseout'); +prototype$44.dragover = move('dragover', 'dragenter', 'dragleave'); + +prototype$44.mouseout = inactive('mouseout'); +prototype$44.dragleave = inactive('dragleave'); + +prototype$44.mousedown = function(evt) { + this._down = this._active; + this.fire('mousedown', evt); +}; + +prototype$44.click = function(evt) { + if (this._down === this._active) { + this.fire('click', evt); + this._down = null; + } +}; + +prototype$44.touchstart = function(evt) { + this._touch = this.pickEvent(evt.changedTouches[0]); + + if (this._first) { + this._active = this._touch; + this._first = false; + } + + this.fire('touchstart', evt, true); +}; + +prototype$44.touchmove = function(evt) { + this.fire('touchmove', evt, true); +}; + +prototype$44.touchend = function(evt) { + this.fire('touchend', evt, true); + this._touch = null; +}; + +// fire an event +prototype$44.fire = function(type, evt, touch) { + var a = touch ? this._touch : this._active, + h = this._handlers[type], i, len; + + // if hyperlinked, handle link first + if (type === 'click' && a && a.href) { + this.handleHref(evt, a, a.href); + } else if ((type === 'mouseover' || type === 'mouseout') && a && a.tooltip) { + this.handleTooltip(evt, a, type === 'mouseover' ? a.tooltip : null); + } + + // invoke all registered handlers + if (h) { + evt.vegaType = type; + for (i=0, len=h.length; i= 0) { + h.splice(i, 1); + } + + return this; +}; + +prototype$44.pickEvent = function(evt) { + var p = point$4(evt, this._canvas), + o = this._origin; + return this.pick(this._scene, p[0], p[1], p[0] - o[0], p[1] - o[1]); +}; + +// find the scenegraph item at the current mouse position +// x, y -- the absolute x, y mouse coordinates on the canvas element +// gx, gy -- the relative coordinates within the current group +prototype$44.pick = function(scene, x, y, gx, gy) { + var g = this.context(), + mark = marks[scene.marktype]; + return mark.pick.call(this, g, scene, x, y, gx, gy); +}; + +var clip$1 = function(context, scene) { + var clip = scene.clip; + + context.save(); + context.beginPath(); + + if (isFunction(clip)) { + clip(context); + } else { + var group = scene.group; + context.rect(0, 0, group.width || 0, group.height || 0); + } + + context.clip(); +}; + +var devicePixelRatio = typeof window !== 'undefined' + ? window.devicePixelRatio || 1 : 1; + +var resize = function(canvas, width, height, origin, scaleFactor) { + var inDOM = typeof HTMLElement !== 'undefined' + && canvas instanceof HTMLElement + && canvas.parentNode != null; + + var context = canvas.getContext('2d'), + ratio = inDOM ? devicePixelRatio : scaleFactor; + + canvas.width = width * ratio; + canvas.height = height * ratio; + + if (inDOM && ratio !== 1) { + canvas.style.width = width + 'px'; + canvas.style.height = height + 'px'; + } + + context.pixelRatio = ratio; + context.setTransform( + ratio, 0, 0, ratio, + ratio * origin[0], + ratio * origin[1] + ); + + return canvas; +}; + +function CanvasRenderer(loader) { + Renderer.call(this, loader); + this._redraw = false; + this._dirty = new Bounds(); +} + +var prototype$45 = inherits(CanvasRenderer, Renderer); +var base = Renderer.prototype; +var tempBounds$1 = new Bounds(); + +prototype$45.initialize = function(el, width, height, origin, scaleFactor) { + this._canvas = canvas(1, 1); // instantiate a small canvas + if (el) { + domClear(el, 0).appendChild(this._canvas); + this._canvas.setAttribute('class', 'marks'); + } + // this method will invoke resize to size the canvas appropriately + return base.initialize.call(this, el, width, height, origin, scaleFactor); +}; + +prototype$45.resize = function(width, height, origin, scaleFactor) { + base.resize.call(this, width, height, origin, scaleFactor); + resize(this._canvas, this._width, this._height, this._origin, this._scale); + this._redraw = true; + return this; +}; + +prototype$45.canvas = function() { + return this._canvas; +}; + +prototype$45.context = function() { + return this._canvas ? this._canvas.getContext('2d') : null; +}; + +prototype$45.dirty = function(item) { + var b = translate$1(item.bounds, item.mark.group); + this._dirty.union(b); +}; + +function clipToBounds(g, b, origin) { + // expand bounds by 1 pixel, then round to pixel boundaries + b.expand(1).round(); + + // to avoid artifacts translate if origin has fractional pixels + b.translate(-(origin[0] % 1), -(origin[1] % 1)); + + // set clipping path + g.beginPath(); + g.rect(b.x1, b.y1, b.width(), b.height()); + g.clip(); + + return b; +} + +function translate$1(bounds, group) { + if (group == null) return bounds; + var b = tempBounds$1.clear().union(bounds); + for (; group != null; group = group.mark.group) { + b.translate(group.x || 0, group.y || 0); + } + return b; +} + +prototype$45._render = function(scene) { + var g = this.context(), + o = this._origin, + w = this._width, + h = this._height, + b = this._dirty; + + // setup + g.save(); + if (this._redraw || b.empty()) { + this._redraw = false; + b = null; + } else { + b = clipToBounds(g, b, o); + } + + this.clear(-o[0], -o[1], w, h); + + // render + this.draw(g, scene, b); + + // takedown + g.restore(); + + this._dirty.clear(); + return this; +}; + +prototype$45.draw = function(ctx, scene, bounds) { + var mark = marks[scene.marktype]; + if (scene.clip) clip$1(ctx, scene); + mark.draw.call(this, ctx, scene, bounds); + if (scene.clip) ctx.restore(); +}; + +prototype$45.clear = function(x, y, w, h) { + var g = this.context(); + g.clearRect(x, y, w, h); + if (this._bgcolor != null) { + g.fillStyle = this._bgcolor; + g.fillRect(x, y, w, h); + } +}; + +function SVGHandler(loader) { + Handler.call(this, loader); + var h = this; + h._hrefHandler = listener(h, function(evt, item) { + if (item && item.href) h.handleHref(evt, item, item.href); + }); + h._tooltipHandler = listener(h, function(evt, item) { + if (item && item.tooltip) { + h.handleTooltip(evt, item, evt.type === 'mouseover' ? item.tooltip : null); + } + }); +} + +var prototype$46 = inherits(SVGHandler, Handler); + +prototype$46.initialize = function(el, origin, obj) { + var svg = this._svg; + if (svg) { + svg.removeEventListener('click', this._hrefHandler); + svg.removeEventListener('mouseover', this._tooltipHandler); + svg.removeEventListener('mouseout', this._tooltipHandler); + } + this._svg = svg = el && domFind(el, 'svg'); + if (svg) { + svg.addEventListener('click', this._hrefHandler); + svg.addEventListener('mouseover', this._tooltipHandler); + svg.addEventListener('mouseout', this._tooltipHandler); + } + return Handler.prototype.initialize.call(this, el, origin, obj); +}; + +prototype$46.svg = function() { + return this._svg; +}; + +// wrap an event listener for the SVG DOM +function listener(context, handler) { + return function(evt) { + var target = evt.target, + item = target.__data__; + evt.vegaType = evt.type; + item = Array.isArray(item) ? item[0] : item; + handler.call(context._obj, evt, item); + }; +} + +// add an event handler +prototype$46.on = function(type, handler) { + var name = this.eventName(type), + h = this._handlers, + i = this._handlerIndex(h[name], type, handler); + + if (i < 0) { + var x = { + type: type, + handler: handler, + listener: listener(this, handler) + }; + + (h[name] || (h[name] = [])).push(x); + if (this._svg) { + this._svg.addEventListener(name, x.listener); + } + } + + return this; +}; + +// remove an event handler +prototype$46.off = function(type, handler) { + var name = this.eventName(type), + h = this._handlers[name], + i = this._handlerIndex(h, type, handler); + + if (i >= 0) { + if (this._svg) { + this._svg.removeEventListener(name, h[i].listener); + } + h.splice(i, 1); + } + + return this; +}; + +// generate string for an opening xml tag +// tag: the name of the xml tag +// attr: hash of attribute name-value pairs to include +// raw: additional raw string to include in tag markup +function openTag(tag, attr, raw) { + var s = '<' + tag, key, val; + if (attr) { + for (key in attr) { + val = attr[key]; + if (val != null) { + s += ' ' + key + '="' + val + '"'; + } + } + } + if (raw) s += ' ' + raw; + return s + '>'; +} + +// generate string for closing xml tag +// tag: the name of the xml tag +function closeTag(tag) { + return ''; +} + +var metadata = { + 'version': '1.1', + 'xmlns': 'http://www.w3.org/2000/svg', + 'xmlns:xlink': 'http://www.w3.org/1999/xlink' +}; + +var styles = { + 'fill': 'fill', + 'fillOpacity': 'fill-opacity', + 'stroke': 'stroke', + 'strokeOpacity': 'stroke-opacity', + 'strokeWidth': 'stroke-width', + 'strokeCap': 'stroke-linecap', + 'strokeJoin': 'stroke-linejoin', + 'strokeDash': 'stroke-dasharray', + 'strokeDashOffset': 'stroke-dashoffset', + 'strokeMiterLimit': 'stroke-miterlimit', + 'opacity': 'opacity' +}; + +var styleProperties = Object.keys(styles); + +var ns = metadata.xmlns; + +function SVGRenderer(loader) { + Renderer.call(this, loader); + this._dirtyID = 1; + this._dirty = []; + this._svg = null; + this._root = null; + this._defs = null; +} + +var prototype$47 = inherits(SVGRenderer, Renderer); +var base$1 = Renderer.prototype; + +prototype$47.initialize = function(el, width, height, padding) { + if (el) { + this._svg = domChild(el, 0, 'svg', ns); + this._svg.setAttribute('class', 'marks'); + domClear(el, 1); + // set the svg root group + this._root = domChild(this._svg, 0, 'g', ns); + domClear(this._svg, 1); + } + + // create the svg definitions cache + this._defs = { + gradient: {}, + clipping: {} + }; + + // set background color if defined + this.background(this._bgcolor); + + return base$1.initialize.call(this, el, width, height, padding); +}; + +prototype$47.background = function(bgcolor) { + if (arguments.length && this._svg) { + this._svg.style.setProperty('background-color', bgcolor); + } + return base$1.background.apply(this, arguments); +}; + +prototype$47.resize = function(width, height, origin, scaleFactor) { + base$1.resize.call(this, width, height, origin, scaleFactor); + + if (this._svg) { + this._svg.setAttribute('width', this._width * this._scale); + this._svg.setAttribute('height', this._height * this._scale); + this._svg.setAttribute('viewBox', '0 0 ' + this._width + ' ' + this._height); + this._root.setAttribute('transform', 'translate(' + this._origin + ')'); + } + + this._dirty = []; + + return this; +}; + +prototype$47.svg = function() { + if (!this._svg) return null; + + var attr = { + class: 'marks', + width: this._width * this._scale, + height: this._height * this._scale, + viewBox: '0 0 ' + this._width + ' ' + this._height + }; + for (var key$$1 in metadata) { + attr[key$$1] = metadata[key$$1]; + } + + var bg = !this._bgcolor ? '' + : (openTag('rect', { + width: this._width, + height: this._height, + style: 'fill: ' + this._bgcolor + ';' + }) + closeTag('rect')); + + return openTag('svg', attr) + bg + this._svg.innerHTML + closeTag('svg'); +}; + + +// -- Render entry point -- + +prototype$47._render = function(scene) { + // perform spot updates and re-render markup + if (this._dirtyCheck()) { + if (this._dirtyAll) this._resetDefs(); + this.draw(this._root, scene); + domClear(this._root, 1); + } + + this.updateDefs(); + + this._dirty = []; + ++this._dirtyID; + + return this; +}; + +// -- Manage SVG definitions ('defs') block -- + +prototype$47.updateDefs = function() { + var svg = this._svg, + defs = this._defs, + el = defs.el, + index = 0, id$$1; + + for (id$$1 in defs.gradient) { + if (!el) defs.el = (el = domChild(svg, 0, 'defs', ns)); + updateGradient(el, defs.gradient[id$$1], index++); + } + + for (id$$1 in defs.clipping) { + if (!el) defs.el = (el = domChild(svg, 0, 'defs', ns)); + updateClipping(el, defs.clipping[id$$1], index++); + } + + // clean-up + if (el) { + if (index === 0) { + svg.removeChild(el); + defs.el = null; + } else { + domClear(el, index); + } + } +}; + +function updateGradient(el, grad, index) { + var i, n, stop; + + el = domChild(el, index, 'linearGradient', ns); + el.setAttribute('id', grad.id); + el.setAttribute('x1', grad.x1); + el.setAttribute('x2', grad.x2); + el.setAttribute('y1', grad.y1); + el.setAttribute('y2', grad.y2); + + for (i=0, n=grad.stops.length; i 0) ? openTag('defs') + defs + closeTag('defs') : ''; +}; + +var object$1; + +function emit$1(name, value, ns, prefixed) { + object$1[prefixed || name] = value; +} + +prototype$48.attributes = function(attr, item) { + object$1 = {}; + attr(emit$1, item, this); + return object$1; +}; + +prototype$48.href = function(item) { + var that = this, + href = item.href, + attr; + + if (href) { + if (attr = that._hrefs && that._hrefs[href]) { + return attr; + } else { + that.sanitizeURL(href).then(function(attr) { + // rewrite to use xlink namespace + // note that this will be deprecated in SVG 2.0 + attr['xlink:href'] = attr.href; + attr.href = null; + (that._hrefs || (that._hrefs = {}))[href] = attr; + }); + } + } + return null; +}; + +prototype$48.mark = function(scene) { + var renderer = this, + mdef = marks[scene.marktype], + tag = mdef.tag, + defs = this._defs, + str = '', + style; + + if (tag !== 'g' && scene.interactive === false) { + style = 'style="pointer-events: none;"'; + } + + // render opening group tag + str += openTag('g', { + 'class': cssClass(scene), + 'clip-path': scene.clip ? clip(renderer, scene, scene.group) : null + }, style); + + // render contained elements + function process(item) { + var href = renderer.href(item); + if (href) str += openTag('a', href); + + style = (tag !== 'g') ? applyStyles(item, scene, tag, defs) : null; + str += openTag(tag, renderer.attributes(mdef.attr, item), style); + + if (tag === 'text') { + str += escape_text(textValue(item)); + } else if (tag === 'g') { + str += openTag('path', renderer.attributes(mdef.background, item), + applyStyles(item, scene, 'bgrect', defs)) + closeTag('path'); + + str += openTag('g', renderer.attributes(mdef.foreground, item)) + + renderer.markGroup(item) + + closeTag('g'); + } + + str += closeTag(tag); + if (href) str += closeTag('a'); + } + + if (mdef.nested) { + if (scene.items && scene.items.length) process(scene.items[0]); + } else { + visit(scene, process); + } + + // render closing group tag + return str + closeTag('g'); +}; + +prototype$48.markGroup = function(scene) { + var renderer = this, + str = ''; + + visit(scene, function(item) { + str += renderer.mark(item); + }); + + return str; +}; + +function applyStyles(o, mark, tag, defs) { + if (o == null) return ''; + var i, n, prop, name, value, s = ''; + + if (tag === 'bgrect' && mark.interactive === false) { + s += 'pointer-events: none; '; + } + + if (tag === 'text') { + s += 'font: ' + font(o) + '; '; + } + + for (i=0, n=styleProperties.length; i/g, '>'); +} + +var Canvas = 'canvas'; +var PNG = 'png'; +var SVG = 'svg'; +var None$1 = 'none'; + +var RenderType = { + Canvas: Canvas, + PNG: PNG, + SVG: SVG, + None: None$1 +}; + +var modules = {}; + +modules[Canvas] = modules[PNG] = { + renderer: CanvasRenderer, + headless: CanvasRenderer, + handler: CanvasHandler +}; + +modules[SVG] = { + renderer: SVGRenderer, + headless: SVGStringRenderer, + handler: SVGHandler +}; + +modules[None$1] = {}; + +function renderModule(name, _) { + name = String(name || '').toLowerCase(); + if (arguments.length > 1) { + modules[name] = _; + return this; + } else { + return modules[name]; + } +} + +var clipBounds = new Bounds(); + +var boundClip = function(mark) { + var clip = mark.clip; + + if (isFunction(clip)) { + clip(context(clipBounds.clear())); + } else if (clip) { + clipBounds.set(0, 0, mark.group.width, mark.group.height); + } else return; + + mark.bounds.intersect(clipBounds); +}; + +var TOLERANCE = 1e-9; + +function sceneEqual(a, b, key$$1) { + return (a === b) ? true + : (key$$1 === 'path') ? pathEqual(a, b) + : (a instanceof Date && b instanceof Date) ? +a === +b + : (isNumber(a) && isNumber(b)) ? Math.abs(a - b) <= TOLERANCE + : (!a || !b || !isObject(a) && !isObject(b)) ? a == b + : (a == null || b == null) ? false + : objectEqual(a, b); +} + +function pathEqual(a, b) { + return sceneEqual(pathParse(a), pathParse(b)); +} + +function objectEqual(a, b) { + var ka = Object.keys(a), + kb = Object.keys(b), + key$$1, i; + + if (ka.length !== kb.length) return false; + + ka.sort(); + kb.sort(); + + for (i = ka.length - 1; i >= 0; i--) { + if (ka[i] != kb[i]) return false; + } + + for (i = ka.length - 1; i >= 0; i--) { + key$$1 = ka[i]; + if (!sceneEqual(a[key$$1], b[key$$1], key$$1)) return false; + } + + return typeof a === typeof b; +} + +/** + * Calculate bounding boxes for scenegraph items. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {object} params.mark - The scenegraph mark instance to bound. + */ +function Bound(params) { + Transform.call(this, null, params); +} + +var prototype$38 = inherits(Bound, Transform); + +prototype$38.transform = function(_, pulse) { + var view = pulse.dataflow, + mark = _.mark, + type = mark.marktype, + entry = marks[type], + bound = entry.bound, + markBounds = mark.bounds, rebound; + + if (entry.nested) { + // multi-item marks have a single bounds instance + if (mark.items.length) view.dirty(mark.items[0]); + markBounds = boundItem(mark, bound); + mark.items.forEach(function(item) { + item.bounds.clear().union(markBounds); + }); + } + + else if (type === 'group' || _.modified()) { + // operator parameters modified -> re-bound all items + // updates group bounds in response to modified group content + pulse.visit(pulse.MOD, function(item) { view.dirty(item); }); + markBounds.clear(); + mark.items.forEach(function(item) { + markBounds.union(boundItem(item, bound)); + }); + } + + else { + // incrementally update bounds, re-bound mark as needed + rebound = pulse.changed(pulse.REM); + + pulse.visit(pulse.ADD, function(item) { + markBounds.union(boundItem(item, bound)); + }); + + pulse.visit(pulse.MOD, function(item) { + rebound = rebound || markBounds.alignsWith(item.bounds); + view.dirty(item); + markBounds.union(boundItem(item, bound)); + }); + + if (rebound) { + markBounds.clear(); + mark.items.forEach(function(item) { markBounds.union(item.bounds); }); + } + } + + // ensure mark bounds do not exceed any clipping region + boundClip(mark); + + return pulse.modifies('bounds'); +}; + +function boundItem(item, bound, opt) { + return bound(item.bounds.clear(), item, opt); +} + +var COUNTER_NAME = ':vega_identifier:'; + +/** + * Adds a unique identifier to all added tuples. + * This transform creates a new signal that serves as an id counter. + * As a result, the id counter is shared across all instances of this + * transform, generating unique ids across multiple data streams. In + * addition, this signal value can be included in a snapshot of the + * dataflow state, enabling correct resumption of id allocation. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {string} params.as - The field name for the generated identifier. + */ +function Identifier(params) { + Transform.call(this, 0, params); +} + +Identifier.Definition = { + "type": "Identifier", + "metadata": {"modifies": true}, + "params": [ + { "name": "as", "type": "string", "required": true } + ] +}; + +var prototype$49 = inherits(Identifier, Transform); + +prototype$49.transform = function(_, pulse) { + var counter = getCounter(pulse.dataflow), + id$$1 = counter.value, + as = _.as; + + pulse.visit(pulse.ADD, function(t) { + if (!t[as]) t[as] = ++id$$1; + }); + + counter.set(this.value = id$$1); + return pulse; +}; + +function getCounter(view) { + var counter = view._signals[COUNTER_NAME]; + if (!counter) { + view._signals[COUNTER_NAME] = (counter = view.add(0)); + } + return counter; +} + +/** + * Bind scenegraph items to a scenegraph mark instance. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {object} params.markdef - The mark definition for creating the mark. + * This is an object of legal scenegraph mark properties which *must* include + * the 'marktype' property. + */ +function Mark(params) { + Transform.call(this, null, params); +} + +var prototype$50 = inherits(Mark, Transform); + +prototype$50.transform = function(_, pulse) { + var mark = this.value; + + // acquire mark on first invocation, bind context and group + if (!mark) { + mark = pulse.dataflow.scenegraph().mark(_.markdef, lookup$1(_), _.index); + mark.group.context = _.context; + if (!_.context.group) _.context.group = mark.group; + mark.source = this; + mark.clip = _.clip; + mark.interactive = _.interactive; + this.value = mark; + } + + // initialize entering items + var Init = mark.marktype === 'group' ? GroupItem : Item; + pulse.visit(pulse.ADD, function(item) { Init.call(item, mark); }); + + // update clipping and/or interactive status + if (_.modified('clip') || _.modified('interactive')) { + mark.clip = _.clip; + mark.interactive = !!_.interactive; + mark.zdirty = true; // force re-eval + pulse.reflow(); + } + + // bind items array to scenegraph mark + mark.items = pulse.source; + return pulse; +}; + +function lookup$1(_) { + var g = _.groups, p = _.parent; + return g && g.size === 1 ? g.get(Object.keys(g.object)[0]) + : g && p ? g.lookup(p) + : null; +} + +var Top = 'top'; +var Left = 'left'; +var Right = 'right'; +var Bottom = 'bottom'; + +/** + * Analyze items for overlap, changing opacity to hide items with + * overlapping bounding boxes. This transform will preserve at least + * two items (e.g., first and last) even if overlap persists. + * @param {object} params - The parameters for this operator. + * @param {function(*,*): number} [params.sort] - A comparator + * function for sorting items. + * @param {object} [params.method] - The overlap removal method to apply. + * One of 'parity' (default, hide every other item until there is no + * more overlap) or 'greedy' (sequentially scan and hide and items that + * overlap with the last visible item). + * @param {object} [params.boundScale] - A scale whose range should be used + * to bound the items. Items exceeding the bounds of the scale range + * will be treated as overlapping. If null or undefined, no bounds check + * will be applied. + * @param {object} [params.boundOrient] - The orientation of the scale + * (top, bottom, left, or right) used to bound items. This parameter is + * ignored if boundScale is null or undefined. + * @param {object} [params.boundTolerance] - The tolerance in pixels for + * bound inclusion testing (default 1). This specifies by how many pixels + * an item's bounds may exceed the scale range bounds and not be culled. + * @constructor + */ +function Overlap(params) { + Transform.call(this, null, params); +} + +var prototype$51 = inherits(Overlap, Transform); + +var methods = { + parity: function(items) { + return items.filter(function(item, i) { + return i % 2 ? (item.opacity = 0) : 1; + }); + }, + greedy: function(items) { + var a; + return items.filter(function(b, i) { + if (!i || !intersect$1(a.bounds, b.bounds)) { + a = b; + return 1; + } else { + return b.opacity = 0; + } + }); + } +}; + +// compute bounding box intersection +// allow 1 pixel of overlap tolerance +function intersect$1(a, b) { + return !( + a.x2 - 1 < b.x1 || + a.x1 + 1 > b.x2 || + a.y2 - 1 < b.y1 || + a.y1 + 1 > b.y2 + ); +} + +function hasOverlap(items) { + for (var i=1, n=items.length, a=items[0].bounds, b; i 1 && b.height() > 1; +} + +function boundTest(scale, orient, tolerance) { + var range = scale.range(), + b = new Bounds(); + + if (orient === Top || orient === Bottom) { + b.set(range[0], -Infinity, range[1], +Infinity); + } else { + b.set(-Infinity, range[0], +Infinity, range[1]); + } + b.expand(tolerance || 1); + + return function(item) { + return b.encloses(item.bounds); + }; +} + +prototype$51.transform = function(_, pulse) { + var reduce = methods[_.method] || methods.parity, + source = pulse.materialize(pulse.SOURCE).source; + + if (!source) return; + + if (_.sort) { + source = source.slice().sort(_.sort); + } + + if (_.method === 'greedy') { + source = source.filter(hasBounds); + } + + // reset all items to be fully opaque + source.forEach(function(item) { item.opacity = 1; }); + + var items = source; + + if (items.length >= 3 && hasOverlap(items)) { + pulse = pulse.reflow(_.modified()).modifies('opacity'); + do { + items = reduce(items); + } while (items.length >= 3 && hasOverlap(items)); + + if (items.length < 3 && !peek(source).opacity) { + if (items.length > 1) peek(items).opacity = 0; + peek(source).opacity = 1; + } + } + + if (_.boundScale) { + var test = boundTest(_.boundScale, _.boundOrient, _.boundTolerance); + source.forEach(function(item) { + if (!test(item)) item.opacity = 0; + }); + } + + return pulse; +}; + +/** + * Queue modified scenegraph items for rendering. + * @constructor + */ +function Render(params) { + Transform.call(this, null, params); +} + +var prototype$52 = inherits(Render, Transform); + +prototype$52.transform = function(_, pulse) { + var view = pulse.dataflow; + + pulse.visit(pulse.ALL, function(item) { view.dirty(item); }); + + // set z-index dirty flag as needed + if (pulse.fields && pulse.fields['zindex']) { + var item = pulse.source && pulse.source[0]; + if (item) item.mark.zdirty = true; + } +}; + +var AxisRole$1 = 'axis'; +var LegendRole$1 = 'legend'; +var RowHeader$1 = 'row-header'; +var RowFooter$1 = 'row-footer'; +var RowTitle = 'row-title'; +var ColHeader$1 = 'column-header'; +var ColFooter$1 = 'column-footer'; +var ColTitle = 'column-title'; + +function extractGroups(group) { + var groups = group.items, + n = groups.length, + i = 0, mark, items; + + var views = { + marks: [], + rowheaders: [], + rowfooters: [], + colheaders: [], + colfooters: [], + rowtitle: null, + coltitle: null + }; + + // layout axes, gather legends, collect bounds + for (; i limit) { + view.warn('Grid headers exceed limit: ' + limit); + headers = headers.slice(0, limit); + } + + // apply offset + init += offset; + + // clear mark bounds for all headers + for (j=0, m=headers.length; j= 0 && (g = groups[k]) == null; k-=back); + + // assign coordinates and update bounds + if (isX) { + x = band == null ? g.x : Math.round(g.bounds.x1 + band * g.bounds.width()); + y = init; + } else { + x = init; + y = band == null ? g.y : Math.round(g.bounds.y1 + band * g.bounds.height()); + } + b.union(h.bounds.translate(x - (h.x || 0), y - (h.y || 0))); + h.x = x; + h.y = y; + view.dirty(h); + + // update current edge of layout bounds + edge = agg(edge, b[bf]); + } + + return edge; +} + +function layoutTitle$1(view, g, offset, isX, bounds, band) { + if (!g) return; + view.dirty(g); + + // compute title coordinates + var x = offset, y = offset; + isX + ? (x = Math.round(bounds.x1 + band * bounds.width())) + : (y = Math.round(bounds.y1 + band * bounds.height())); + + // assign coordinates and update bounds + g.bounds.translate(x - (g.x || 0), y - (g.y || 0)); + g.mark.bounds.clear().union(g.bounds); + g.x = x; + g.y = y; + + // queue title for redraw + view.dirty(g); +} + +var Fit = 'fit'; +var FitX = 'fit-x'; +var FitY = 'fit-y'; +var Pad = 'pad'; +var None$2 = 'none'; +var Padding = 'padding'; + +var AxisRole = 'axis'; +var TitleRole = 'title'; +var FrameRole = 'frame'; +var LegendRole = 'legend'; +var ScopeRole = 'scope'; +var RowHeader = 'row-header'; +var RowFooter = 'row-footer'; +var ColHeader = 'column-header'; +var ColFooter = 'column-footer'; + +var AxisOffset = 0.5; +var tempBounds$2 = new Bounds(); + +/** + * Layout view elements such as axes and legends. + * Also performs size adjustments. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {object} params.mark - Scenegraph mark of groups to layout. + */ +function ViewLayout(params) { + Transform.call(this, null, params); +} + +var prototype$53 = inherits(ViewLayout, Transform); + +prototype$53.transform = function(_, pulse) { + // TODO incremental update, output? + var view = pulse.dataflow; + _.mark.items.forEach(function(group) { + if (_.layout) gridLayout(view, group, _.layout); + layoutGroup(view, group, _); + }); + return pulse; +}; + +function layoutGroup(view, group, _) { + var items = group.items, + width = Math.max(0, group.width || 0), + height = Math.max(0, group.height || 0), + viewBounds = new Bounds().set(0, 0, width, height), + axisBounds = viewBounds.clone(), + xBounds = viewBounds.clone(), + yBounds = viewBounds.clone(), + legends = [], title, + mark, flow, b, i, n; + + // layout axes, gather legends, collect bounds + for (i=0, n=items.length; i -1) bounds.union(item.items[i].bounds); + if ((i=indices[1]) > -1) bounds.union(item.items[i].bounds); + + // position axis group and title + switch (orient) { + case Top: + x = position || 0; + y = -offset; + s = Math.max(minExtent, Math.min(maxExtent, -bounds.y1)); + if (title) { + if (title.auto) { + s += titlePadding; + title.y = -s; + s += title.bounds.height(); + bounds.add(title.bounds.x1, 0) + .add(title.bounds.x2, 0); + } else { + bounds.union(title.bounds); + } + } + bounds.add(0, -s).add(range, 0); + break; + case Left: + x = -offset; + y = position || 0; + s = Math.max(minExtent, Math.min(maxExtent, -bounds.x1)); + if (title) { + if (title.auto) { + s += titlePadding; + title.x = -s; + s += title.bounds.width(); + bounds.add(0, title.bounds.y1) + .add(0, title.bounds.y2); + } else { + bounds.union(title.bounds); + } + } + bounds.add(-s, 0).add(0, range); + break; + case Right: + x = width + offset; + y = position || 0; + s = Math.max(minExtent, Math.min(maxExtent, bounds.x2)); + if (title) { + if (title.auto) { + s += titlePadding; + title.x = s; + s += title.bounds.width(); + bounds.add(0, title.bounds.y1) + .add(0, title.bounds.y2); + } else { + bounds.union(title.bounds); + } + } + bounds.add(0, 0).add(s, range); + break; + case Bottom: + x = position || 0; + y = height + offset; + s = Math.max(minExtent, Math.min(maxExtent, bounds.y2)); + if (title) if (title.auto) { + s += titlePadding; + title.y = s; + s += title.bounds.height(); + bounds.add(title.bounds.x1, 0) + .add(title.bounds.x2, 0); + } else { + bounds.union(title.bounds); + } + bounds.add(0, 0).add(range, s); + break; + default: + x = item.x; + y = item.y; + } + + // update bounds + boundStroke(bounds.translate(x, y), item); + + if (set$3(item, 'x', x + AxisOffset) | set$3(item, 'y', y + AxisOffset)) { + item.bounds = tempBounds$2; + view.dirty(item); + item.bounds = bounds; + view.dirty(item); + } + + return item.mark.bounds.clear().union(bounds); +} + +function layoutTitle(view, title, axisBounds) { + var item = title.items[0], + datum = item.datum, + orient = datum.orient, + offset = item.offset, + bounds = item.bounds, + x = 0, y = 0; + + tempBounds$2.clear().union(bounds); + + // position axis group and title + switch (orient) { + case Top: + x = item.x; + y = axisBounds.y1 - offset; + break; + case Left: + x = axisBounds.x1 - offset; + y = item.y; + break; + case Right: + x = axisBounds.x2 + offset; + y = item.y; + break; + case Bottom: + x = item.x; + y = axisBounds.y2 + offset; + break; + default: + x = item.x; + y = item.y; + } + + bounds.translate(x - item.x, y - item.y); + if (set$3(item, 'x', x) | set$3(item, 'y', y)) { + item.bounds = tempBounds$2; + view.dirty(item); + item.bounds = bounds; + view.dirty(item); + } + + // update bounds + return title.bounds.clear().union(bounds); +} + +function layoutLegend(view, legend, flow, xBounds, yBounds, width, height) { + var item = legend.items[0], + datum = item.datum, + orient = datum.orient, + offset = item.offset, + bounds = item.bounds, + x = 0, + y = 0, + w, h, axisBounds; + + if (orient === Top || orient === Bottom) { + axisBounds = yBounds, + x = flow[orient]; + } else if (orient === Left || orient === Right) { + axisBounds = xBounds; + y = flow[orient]; + } + + tempBounds$2.clear().union(bounds); + bounds.clear(); + + // aggregate bounds to determine size + // shave off 1 pixel because it looks better... + item.items.forEach(function(_) { bounds.union(_.bounds); }); + w = Math.round(bounds.width()) + 2 * item.padding - 1; + h = Math.round(bounds.height()) + 2 * item.padding - 1; + + switch (orient) { + case Left: + x -= w + offset - Math.floor(axisBounds.x1); + flow.left += h + flow.margin; + break; + case Right: + x += offset + Math.ceil(axisBounds.x2); + flow.right += h + flow.margin; + break; + case Top: + y -= h + offset - Math.floor(axisBounds.y1); + flow.top += w + flow.margin; + break; + case Bottom: + y += offset + Math.ceil(axisBounds.y2); + flow.bottom += w + flow.margin; + break; + case 'top-left': + x += offset; + y += offset; + break; + case 'top-right': + x += width - w - offset; + y += offset; + break; + case 'bottom-left': + x += offset; + y += height - h - offset; + break; + case 'bottom-right': + x += width - w - offset; + y += height - h - offset; + break; + default: + x = item.x; + y = item.y; + } + + // update bounds + boundStroke(bounds.set(x, y, x + w, y + h), item); + + // update legend layout + if (set$3(item, 'x', x) | set$3(item, 'width', w) | + set$3(item, 'y', y) | set$3(item, 'height', h)) { + item.bounds = tempBounds$2; + view.dirty(item); + item.bounds = bounds; + view.dirty(item); + } + + return item.mark.bounds.clear().union(bounds); +} + +function layoutSize(view, group, viewBounds, _) { + var auto = _.autosize || {}, + type = auto.type, + viewWidth = view._width, + viewHeight = view._height, + padding = view.padding(); + + if (view._autosize < 1 || !type) return; + + var width = Math.max(0, group.width || 0), + left = Math.max(0, Math.ceil(-viewBounds.x1)), + right = Math.max(0, Math.ceil(viewBounds.x2 - width)), + height = Math.max(0, group.height || 0), + top = Math.max(0, Math.ceil(-viewBounds.y1)), + bottom = Math.max(0, Math.ceil(viewBounds.y2 - height)); + + if (auto.contains === Padding) { + viewWidth -= padding.left + padding.right; + viewHeight -= padding.top + padding.bottom; + } + + if (type === None$2) { + left = 0; + top = 0; + width = viewWidth; + height = viewHeight; + } + + else if (type === Fit) { + width = Math.max(0, viewWidth - left - right); + height = Math.max(0, viewHeight - top - bottom); + } + + else if (type === FitX) { + width = Math.max(0, viewWidth - left - right); + viewHeight = height + top + bottom; + } + + else if (type === FitY) { + viewWidth = width + left + right; + height = Math.max(0, viewHeight - top - bottom); + } + + else if (type === Pad) { + viewWidth = width + left + right; + viewHeight = height + top + bottom; + } + + view._resizeView( + viewWidth, viewHeight, + width, height, + [left, top], + auto.resize + ); +} + + + +var vtx = Object.freeze({ + bound: Bound, + identifier: Identifier, + mark: Mark, + overlap: Overlap, + render: Render, + viewlayout: ViewLayout +}); + +var Log = 'log'; +var Pow = 'pow'; +var Utc = 'utc'; +var Sqrt = 'sqrt'; +var Band = 'band'; +var Time = 'time'; +var Point = 'point'; +var Linear$1 = 'linear'; +var Ordinal = 'ordinal'; +var Quantile = 'quantile'; +var Quantize = 'quantize'; +var Threshold = 'threshold'; +var BinLinear = 'bin-linear'; +var BinOrdinal = 'bin-ordinal'; +var Sequential = 'sequential'; + +var invertRange = function(scale) { + return function(_) { + var lo = _[0], + hi = _[1], + t; + + if (hi < lo) { + t = lo; + lo = hi; + hi = t; + } + + return [ + scale.invert(lo), + scale.invert(hi) + ]; + } +}; + +var invertRangeExtent = function(scale) { + return function(_) { + var range = scale.range(), + lo = _[0], + hi = _[1], + min = -1, max, t, i, n; + + if (hi < lo) { + t = lo; + lo = hi; + hi = t; + } + + for (i=0, n=range.length; i= lo && range[i] <= hi) { + if (min < 0) min = i; + max = i; + } + } + + if (min < 0) return undefined; + + lo = scale.invertExtent(range[min]); + hi = scale.invertExtent(range[max]); + + return [ + lo[0] === undefined ? lo[1] : lo[0], + hi[1] === undefined ? hi[0] : hi[1] + ]; + } +}; + +var bandSpace = function(count, paddingInner, paddingOuter) { + var space = count - paddingInner + paddingOuter * 2; + return count ? (space > 0 ? space : 1) : 0; +}; + +var array$2 = Array.prototype; + +var map$3 = array$2.map; +var slice$2 = array$2.slice; + +var implicit = {name: "implicit"}; + +function ordinal(range) { + var index = map(), + domain = [], + unknown = implicit; + + range = range == null ? [] : slice$2.call(range); + + function scale(d) { + var key = d + "", i = index.get(key); + if (!i) { + if (unknown !== implicit) return unknown; + index.set(key, i = domain.push(d)); + } + return range[(i - 1) % range.length]; + } + + scale.domain = function(_) { + if (!arguments.length) return domain.slice(); + domain = [], index = map(); + var i = -1, n = _.length, d, key; + while (++i < n) if (!index.has(key = (d = _[i]) + "")) index.set(key, domain.push(d)); + return scale; + }; + + scale.range = function(_) { + return arguments.length ? (range = slice$2.call(_), scale) : range.slice(); + }; + + scale.unknown = function(_) { + return arguments.length ? (unknown = _, scale) : unknown; + }; + + scale.copy = function() { + return ordinal() + .domain(domain) + .range(range) + .unknown(unknown); + }; + + return scale; +} + +var define = function(constructor, factory, prototype) { + constructor.prototype = factory.prototype = prototype; + prototype.constructor = constructor; +}; + +function extend$1(parent, definition) { + var prototype = Object.create(parent.prototype); + for (var key in definition) prototype[key] = definition[key]; + return prototype; +} + +function Color() {} + +var darker = 0.7; +var brighter = 1 / darker; + +var reI = "\\s*([+-]?\\d+)\\s*"; +var reN = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)\\s*"; +var reP = "\\s*([+-]?\\d*\\.?\\d+(?:[eE][+-]?\\d+)?)%\\s*"; +var reHex3 = /^#([0-9a-f]{3})$/; +var reHex6 = /^#([0-9a-f]{6})$/; +var reRgbInteger = new RegExp("^rgb\\(" + [reI, reI, reI] + "\\)$"); +var reRgbPercent = new RegExp("^rgb\\(" + [reP, reP, reP] + "\\)$"); +var reRgbaInteger = new RegExp("^rgba\\(" + [reI, reI, reI, reN] + "\\)$"); +var reRgbaPercent = new RegExp("^rgba\\(" + [reP, reP, reP, reN] + "\\)$"); +var reHslPercent = new RegExp("^hsl\\(" + [reN, reP, reP] + "\\)$"); +var reHslaPercent = new RegExp("^hsla\\(" + [reN, reP, reP, reN] + "\\)$"); + +var named = { + aliceblue: 0xf0f8ff, + antiquewhite: 0xfaebd7, + aqua: 0x00ffff, + aquamarine: 0x7fffd4, + azure: 0xf0ffff, + beige: 0xf5f5dc, + bisque: 0xffe4c4, + black: 0x000000, + blanchedalmond: 0xffebcd, + blue: 0x0000ff, + blueviolet: 0x8a2be2, + brown: 0xa52a2a, + burlywood: 0xdeb887, + cadetblue: 0x5f9ea0, + chartreuse: 0x7fff00, + chocolate: 0xd2691e, + coral: 0xff7f50, + cornflowerblue: 0x6495ed, + cornsilk: 0xfff8dc, + crimson: 0xdc143c, + cyan: 0x00ffff, + darkblue: 0x00008b, + darkcyan: 0x008b8b, + darkgoldenrod: 0xb8860b, + darkgray: 0xa9a9a9, + darkgreen: 0x006400, + darkgrey: 0xa9a9a9, + darkkhaki: 0xbdb76b, + darkmagenta: 0x8b008b, + darkolivegreen: 0x556b2f, + darkorange: 0xff8c00, + darkorchid: 0x9932cc, + darkred: 0x8b0000, + darksalmon: 0xe9967a, + darkseagreen: 0x8fbc8f, + darkslateblue: 0x483d8b, + darkslategray: 0x2f4f4f, + darkslategrey: 0x2f4f4f, + darkturquoise: 0x00ced1, + darkviolet: 0x9400d3, + deeppink: 0xff1493, + deepskyblue: 0x00bfff, + dimgray: 0x696969, + dimgrey: 0x696969, + dodgerblue: 0x1e90ff, + firebrick: 0xb22222, + floralwhite: 0xfffaf0, + forestgreen: 0x228b22, + fuchsia: 0xff00ff, + gainsboro: 0xdcdcdc, + ghostwhite: 0xf8f8ff, + gold: 0xffd700, + goldenrod: 0xdaa520, + gray: 0x808080, + green: 0x008000, + greenyellow: 0xadff2f, + grey: 0x808080, + honeydew: 0xf0fff0, + hotpink: 0xff69b4, + indianred: 0xcd5c5c, + indigo: 0x4b0082, + ivory: 0xfffff0, + khaki: 0xf0e68c, + lavender: 0xe6e6fa, + lavenderblush: 0xfff0f5, + lawngreen: 0x7cfc00, + lemonchiffon: 0xfffacd, + lightblue: 0xadd8e6, + lightcoral: 0xf08080, + lightcyan: 0xe0ffff, + lightgoldenrodyellow: 0xfafad2, + lightgray: 0xd3d3d3, + lightgreen: 0x90ee90, + lightgrey: 0xd3d3d3, + lightpink: 0xffb6c1, + lightsalmon: 0xffa07a, + lightseagreen: 0x20b2aa, + lightskyblue: 0x87cefa, + lightslategray: 0x778899, + lightslategrey: 0x778899, + lightsteelblue: 0xb0c4de, + lightyellow: 0xffffe0, + lime: 0x00ff00, + limegreen: 0x32cd32, + linen: 0xfaf0e6, + magenta: 0xff00ff, + maroon: 0x800000, + mediumaquamarine: 0x66cdaa, + mediumblue: 0x0000cd, + mediumorchid: 0xba55d3, + mediumpurple: 0x9370db, + mediumseagreen: 0x3cb371, + mediumslateblue: 0x7b68ee, + mediumspringgreen: 0x00fa9a, + mediumturquoise: 0x48d1cc, + mediumvioletred: 0xc71585, + midnightblue: 0x191970, + mintcream: 0xf5fffa, + mistyrose: 0xffe4e1, + moccasin: 0xffe4b5, + navajowhite: 0xffdead, + navy: 0x000080, + oldlace: 0xfdf5e6, + olive: 0x808000, + olivedrab: 0x6b8e23, + orange: 0xffa500, + orangered: 0xff4500, + orchid: 0xda70d6, + palegoldenrod: 0xeee8aa, + palegreen: 0x98fb98, + paleturquoise: 0xafeeee, + palevioletred: 0xdb7093, + papayawhip: 0xffefd5, + peachpuff: 0xffdab9, + peru: 0xcd853f, + pink: 0xffc0cb, + plum: 0xdda0dd, + powderblue: 0xb0e0e6, + purple: 0x800080, + rebeccapurple: 0x663399, + red: 0xff0000, + rosybrown: 0xbc8f8f, + royalblue: 0x4169e1, + saddlebrown: 0x8b4513, + salmon: 0xfa8072, + sandybrown: 0xf4a460, + seagreen: 0x2e8b57, + seashell: 0xfff5ee, + sienna: 0xa0522d, + silver: 0xc0c0c0, + skyblue: 0x87ceeb, + slateblue: 0x6a5acd, + slategray: 0x708090, + slategrey: 0x708090, + snow: 0xfffafa, + springgreen: 0x00ff7f, + steelblue: 0x4682b4, + tan: 0xd2b48c, + teal: 0x008080, + thistle: 0xd8bfd8, + tomato: 0xff6347, + turquoise: 0x40e0d0, + violet: 0xee82ee, + wheat: 0xf5deb3, + white: 0xffffff, + whitesmoke: 0xf5f5f5, + yellow: 0xffff00, + yellowgreen: 0x9acd32 +}; + +define(Color, color$1, { + displayable: function() { + return this.rgb().displayable(); + }, + toString: function() { + return this.rgb() + ""; + } +}); + +function color$1(format) { + var m; + format = (format + "").trim().toLowerCase(); + return (m = reHex3.exec(format)) ? (m = parseInt(m[1], 16), new Rgb((m >> 8 & 0xf) | (m >> 4 & 0x0f0), (m >> 4 & 0xf) | (m & 0xf0), ((m & 0xf) << 4) | (m & 0xf), 1)) // #f00 + : (m = reHex6.exec(format)) ? rgbn(parseInt(m[1], 16)) // #ff0000 + : (m = reRgbInteger.exec(format)) ? new Rgb(m[1], m[2], m[3], 1) // rgb(255, 0, 0) + : (m = reRgbPercent.exec(format)) ? new Rgb(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, 1) // rgb(100%, 0%, 0%) + : (m = reRgbaInteger.exec(format)) ? rgba(m[1], m[2], m[3], m[4]) // rgba(255, 0, 0, 1) + : (m = reRgbaPercent.exec(format)) ? rgba(m[1] * 255 / 100, m[2] * 255 / 100, m[3] * 255 / 100, m[4]) // rgb(100%, 0%, 0%, 1) + : (m = reHslPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, 1) // hsl(120, 50%, 50%) + : (m = reHslaPercent.exec(format)) ? hsla(m[1], m[2] / 100, m[3] / 100, m[4]) // hsla(120, 50%, 50%, 1) + : named.hasOwnProperty(format) ? rgbn(named[format]) + : format === "transparent" ? new Rgb(NaN, NaN, NaN, 0) + : null; +} + +function rgbn(n) { + return new Rgb(n >> 16 & 0xff, n >> 8 & 0xff, n & 0xff, 1); +} + +function rgba(r, g, b, a) { + if (a <= 0) r = g = b = NaN; + return new Rgb(r, g, b, a); +} + +function rgbConvert(o) { + if (!(o instanceof Color)) o = color$1(o); + if (!o) return new Rgb; + o = o.rgb(); + return new Rgb(o.r, o.g, o.b, o.opacity); +} + +function rgb(r, g, b, opacity) { + return arguments.length === 1 ? rgbConvert(r) : new Rgb(r, g, b, opacity == null ? 1 : opacity); +} + +function Rgb(r, g, b, opacity) { + this.r = +r; + this.g = +g; + this.b = +b; + this.opacity = +opacity; +} + +define(Rgb, rgb, extend$1(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Rgb(this.r * k, this.g * k, this.b * k, this.opacity); + }, + rgb: function() { + return this; + }, + displayable: function() { + return (0 <= this.r && this.r <= 255) + && (0 <= this.g && this.g <= 255) + && (0 <= this.b && this.b <= 255) + && (0 <= this.opacity && this.opacity <= 1); + }, + toString: function() { + var a = this.opacity; a = isNaN(a) ? 1 : Math.max(0, Math.min(1, a)); + return (a === 1 ? "rgb(" : "rgba(") + + Math.max(0, Math.min(255, Math.round(this.r) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.g) || 0)) + ", " + + Math.max(0, Math.min(255, Math.round(this.b) || 0)) + + (a === 1 ? ")" : ", " + a + ")"); + } +})); + +function hsla(h, s, l, a) { + if (a <= 0) h = s = l = NaN; + else if (l <= 0 || l >= 1) h = s = NaN; + else if (s <= 0) h = NaN; + return new Hsl(h, s, l, a); +} + +function hslConvert(o) { + if (o instanceof Hsl) return new Hsl(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Color)) o = color$1(o); + if (!o) return new Hsl; + if (o instanceof Hsl) return o; + o = o.rgb(); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + min = Math.min(r, g, b), + max = Math.max(r, g, b), + h = NaN, + s = max - min, + l = (max + min) / 2; + if (s) { + if (r === max) h = (g - b) / s + (g < b) * 6; + else if (g === max) h = (b - r) / s + 2; + else h = (r - g) / s + 4; + s /= l < 0.5 ? max + min : 2 - max - min; + h *= 60; + } else { + s = l > 0 && l < 1 ? 0 : h; + } + return new Hsl(h, s, l, o.opacity); +} + +function hsl(h, s, l, opacity) { + return arguments.length === 1 ? hslConvert(h) : new Hsl(h, s, l, opacity == null ? 1 : opacity); +} + +function Hsl(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; +} + +define(Hsl, hsl, extend$1(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Hsl(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = this.h % 360 + (this.h < 0) * 360, + s = isNaN(h) || isNaN(this.s) ? 0 : this.s, + l = this.l, + m2 = l + (l < 0.5 ? l : 1 - l) * s, + m1 = 2 * l - m2; + return new Rgb( + hsl2rgb(h >= 240 ? h - 240 : h + 120, m1, m2), + hsl2rgb(h, m1, m2), + hsl2rgb(h < 120 ? h + 240 : h - 120, m1, m2), + this.opacity + ); + }, + displayable: function() { + return (0 <= this.s && this.s <= 1 || isNaN(this.s)) + && (0 <= this.l && this.l <= 1) + && (0 <= this.opacity && this.opacity <= 1); + } +})); + +/* From FvD 13.37, CSS Color Module Level 3 */ +function hsl2rgb(h, m1, m2) { + return (h < 60 ? m1 + (m2 - m1) * h / 60 + : h < 180 ? m2 + : h < 240 ? m1 + (m2 - m1) * (240 - h) / 60 + : m1) * 255; +} + +var deg2rad = Math.PI / 180; +var rad2deg = 180 / Math.PI; + +var Kn = 18; +var Xn = 0.950470; +var Yn = 1; +var Zn = 1.088830; +var t0$1 = 4 / 29; +var t1$1 = 6 / 29; +var t2 = 3 * t1$1 * t1$1; +var t3 = t1$1 * t1$1 * t1$1; + +function labConvert(o) { + if (o instanceof Lab) return new Lab(o.l, o.a, o.b, o.opacity); + if (o instanceof Hcl) { + var h = o.h * deg2rad; + return new Lab(o.l, Math.cos(h) * o.c, Math.sin(h) * o.c, o.opacity); + } + if (!(o instanceof Rgb)) o = rgbConvert(o); + var b = rgb2xyz(o.r), + a = rgb2xyz(o.g), + l = rgb2xyz(o.b), + x = xyz2lab((0.4124564 * b + 0.3575761 * a + 0.1804375 * l) / Xn), + y = xyz2lab((0.2126729 * b + 0.7151522 * a + 0.0721750 * l) / Yn), + z = xyz2lab((0.0193339 * b + 0.1191920 * a + 0.9503041 * l) / Zn); + return new Lab(116 * y - 16, 500 * (x - y), 200 * (y - z), o.opacity); +} + +function lab(l, a, b, opacity) { + return arguments.length === 1 ? labConvert(l) : new Lab(l, a, b, opacity == null ? 1 : opacity); +} + +function Lab(l, a, b, opacity) { + this.l = +l; + this.a = +a; + this.b = +b; + this.opacity = +opacity; +} + +define(Lab, lab, extend$1(Color, { + brighter: function(k) { + return new Lab(this.l + Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); + }, + darker: function(k) { + return new Lab(this.l - Kn * (k == null ? 1 : k), this.a, this.b, this.opacity); + }, + rgb: function() { + var y = (this.l + 16) / 116, + x = isNaN(this.a) ? y : y + this.a / 500, + z = isNaN(this.b) ? y : y - this.b / 200; + y = Yn * lab2xyz(y); + x = Xn * lab2xyz(x); + z = Zn * lab2xyz(z); + return new Rgb( + xyz2rgb( 3.2404542 * x - 1.5371385 * y - 0.4985314 * z), // D65 -> sRGB + xyz2rgb(-0.9692660 * x + 1.8760108 * y + 0.0415560 * z), + xyz2rgb( 0.0556434 * x - 0.2040259 * y + 1.0572252 * z), + this.opacity + ); + } +})); + +function xyz2lab(t) { + return t > t3 ? Math.pow(t, 1 / 3) : t / t2 + t0$1; +} + +function lab2xyz(t) { + return t > t1$1 ? t * t * t : t2 * (t - t0$1); +} + +function xyz2rgb(x) { + return 255 * (x <= 0.0031308 ? 12.92 * x : 1.055 * Math.pow(x, 1 / 2.4) - 0.055); +} + +function rgb2xyz(x) { + return (x /= 255) <= 0.04045 ? x / 12.92 : Math.pow((x + 0.055) / 1.055, 2.4); +} + +function hclConvert(o) { + if (o instanceof Hcl) return new Hcl(o.h, o.c, o.l, o.opacity); + if (!(o instanceof Lab)) o = labConvert(o); + var h = Math.atan2(o.b, o.a) * rad2deg; + return new Hcl(h < 0 ? h + 360 : h, Math.sqrt(o.a * o.a + o.b * o.b), o.l, o.opacity); +} + +function hcl(h, c, l, opacity) { + return arguments.length === 1 ? hclConvert(h) : new Hcl(h, c, l, opacity == null ? 1 : opacity); +} + +function Hcl(h, c, l, opacity) { + this.h = +h; + this.c = +c; + this.l = +l; + this.opacity = +opacity; +} + +define(Hcl, hcl, extend$1(Color, { + brighter: function(k) { + return new Hcl(this.h, this.c, this.l + Kn * (k == null ? 1 : k), this.opacity); + }, + darker: function(k) { + return new Hcl(this.h, this.c, this.l - Kn * (k == null ? 1 : k), this.opacity); + }, + rgb: function() { + return labConvert(this).rgb(); + } +})); + +var A = -0.14861; +var B = +1.78277; +var C = -0.29227; +var D = -0.90649; +var E = +1.97294; +var ED = E * D; +var EB = E * B; +var BC_DA = B * C - D * A; + +function cubehelixConvert(o) { + if (o instanceof Cubehelix) return new Cubehelix(o.h, o.s, o.l, o.opacity); + if (!(o instanceof Rgb)) o = rgbConvert(o); + var r = o.r / 255, + g = o.g / 255, + b = o.b / 255, + l = (BC_DA * b + ED * r - EB * g) / (BC_DA + ED - EB), + bl = b - l, + k = (E * (g - l) - C * bl) / D, + s = Math.sqrt(k * k + bl * bl) / (E * l * (1 - l)), // NaN if l=0 or l=1 + h = s ? Math.atan2(k, bl) * rad2deg - 120 : NaN; + return new Cubehelix(h < 0 ? h + 360 : h, s, l, o.opacity); +} + +function cubehelix(h, s, l, opacity) { + return arguments.length === 1 ? cubehelixConvert(h) : new Cubehelix(h, s, l, opacity == null ? 1 : opacity); +} + +function Cubehelix(h, s, l, opacity) { + this.h = +h; + this.s = +s; + this.l = +l; + this.opacity = +opacity; +} + +define(Cubehelix, cubehelix, extend$1(Color, { + brighter: function(k) { + k = k == null ? brighter : Math.pow(brighter, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); + }, + darker: function(k) { + k = k == null ? darker : Math.pow(darker, k); + return new Cubehelix(this.h, this.s, this.l * k, this.opacity); + }, + rgb: function() { + var h = isNaN(this.h) ? 0 : (this.h + 120) * deg2rad, + l = +this.l, + a = isNaN(this.s) ? 0 : this.s * l * (1 - l), + cosh = Math.cos(h), + sinh = Math.sin(h); + return new Rgb( + 255 * (l + a * (A * cosh + B * sinh)), + 255 * (l + a * (C * cosh + D * sinh)), + 255 * (l + a * (E * cosh)), + this.opacity + ); + } +})); + +function basis(t1, v0, v1, v2, v3) { + var t2 = t1 * t1, t3 = t2 * t1; + return ((1 - 3 * t1 + 3 * t2 - t3) * v0 + + (4 - 6 * t2 + 3 * t3) * v1 + + (1 + 3 * t1 + 3 * t2 - 3 * t3) * v2 + + t3 * v3) / 6; +} + +var basis$1 = function(values) { + var n = values.length - 1; + return function(t) { + var i = t <= 0 ? (t = 0) : t >= 1 ? (t = 1, n - 1) : Math.floor(t * n), + v1 = values[i], + v2 = values[i + 1], + v0 = i > 0 ? values[i - 1] : 2 * v1 - v2, + v3 = i < n - 1 ? values[i + 2] : 2 * v2 - v1; + return basis((t - i / n) * n, v0, v1, v2, v3); + }; +}; + +var basisClosed = function(values) { + var n = values.length; + return function(t) { + var i = Math.floor(((t %= 1) < 0 ? ++t : t) * n), + v0 = values[(i + n - 1) % n], + v1 = values[i % n], + v2 = values[(i + 1) % n], + v3 = values[(i + 2) % n]; + return basis((t - i / n) * n, v0, v1, v2, v3); + }; +}; + +var constant$4 = function(x) { + return function() { + return x; + }; +}; + +function linear$1(a, d) { + return function(t) { + return a + t * d; + }; +} + +function exponential(a, b, y) { + return a = Math.pow(a, y), b = Math.pow(b, y) - a, y = 1 / y, function(t) { + return Math.pow(a + t * b, y); + }; +} + +function hue(a, b) { + var d = b - a; + return d ? linear$1(a, d > 180 || d < -180 ? d - 360 * Math.round(d / 360) : d) : constant$4(isNaN(a) ? b : a); +} + +function gamma(y) { + return (y = +y) === 1 ? nogamma : function(a, b) { + return b - a ? exponential(a, b, y) : constant$4(isNaN(a) ? b : a); + }; +} + +function nogamma(a, b) { + var d = b - a; + return d ? linear$1(a, d) : constant$4(isNaN(a) ? b : a); +} + +var rgb$1 = (function rgbGamma(y) { + var color$$1 = gamma(y); + + function rgb$$1(start, end) { + var r = color$$1((start = rgb(start)).r, (end = rgb(end)).r), + g = color$$1(start.g, end.g), + b = color$$1(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.r = r(t); + start.g = g(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; + } + + rgb$$1.gamma = rgbGamma; + + return rgb$$1; +})(1); + +function rgbSpline(spline) { + return function(colors) { + var n = colors.length, + r = new Array(n), + g = new Array(n), + b = new Array(n), + i, color$$1; + for (i = 0; i < n; ++i) { + color$$1 = rgb(colors[i]); + r[i] = color$$1.r || 0; + g[i] = color$$1.g || 0; + b[i] = color$$1.b || 0; + } + r = spline(r); + g = spline(g); + b = spline(b); + color$$1.opacity = 1; + return function(t) { + color$$1.r = r(t); + color$$1.g = g(t); + color$$1.b = b(t); + return color$$1 + ""; + }; + }; +} + +var rgbBasis = rgbSpline(basis$1); +var rgbBasisClosed = rgbSpline(basisClosed); + +var array$3 = function(a, b) { + var nb = b ? b.length : 0, + na = a ? Math.min(nb, a.length) : 0, + x = new Array(na), + c = new Array(nb), + i; + + for (i = 0; i < na; ++i) x[i] = interpolate(a[i], b[i]); + for (; i < nb; ++i) c[i] = b[i]; + + return function(t) { + for (i = 0; i < na; ++i) c[i] = x[i](t); + return c; + }; +}; + +var date = function(a, b) { + var d = new Date; + return a = +a, b -= a, function(t) { + return d.setTime(a + b * t), d; + }; +}; + +var reinterpolate = function(a, b) { + return a = +a, b -= a, function(t) { + return a + b * t; + }; +}; + +var object$2 = function(a, b) { + var i = {}, + c = {}, + k; + + if (a === null || typeof a !== "object") a = {}; + if (b === null || typeof b !== "object") b = {}; + + for (k in b) { + if (k in a) { + i[k] = interpolate(a[k], b[k]); + } else { + c[k] = b[k]; + } + } + + return function(t) { + for (k in i) c[k] = i[k](t); + return c; + }; +}; + +var reA = /[-+]?(?:\d+\.?\d*|\.?\d+)(?:[eE][-+]?\d+)?/g; +var reB = new RegExp(reA.source, "g"); + +function zero$1(b) { + return function() { + return b; + }; +} + +function one$1(b) { + return function(t) { + return b(t) + ""; + }; +} + +var string = function(a, b) { + var bi = reA.lastIndex = reB.lastIndex = 0, // scan index for next number in b + am, // current match in a + bm, // current match in b + bs, // string preceding current number in b, if any + i = -1, // index in s + s = [], // string constants and placeholders + q = []; // number interpolators + + // Coerce inputs to strings. + a = a + "", b = b + ""; + + // Interpolate pairs of numbers in a & b. + while ((am = reA.exec(a)) + && (bm = reB.exec(b))) { + if ((bs = bm.index) > bi) { // a string precedes the next number in b + bs = b.slice(bi, bs); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; + } + if ((am = am[0]) === (bm = bm[0])) { // numbers in a & b match + if (s[i]) s[i] += bm; // coalesce with previous string + else s[++i] = bm; + } else { // interpolate non-matching numbers + s[++i] = null; + q.push({i: i, x: reinterpolate(am, bm)}); + } + bi = reB.lastIndex; + } + + // Add remains of b. + if (bi < b.length) { + bs = b.slice(bi); + if (s[i]) s[i] += bs; // coalesce with previous string + else s[++i] = bs; + } + + // Special optimization for only a single match. + // Otherwise, interpolate each of the numbers and rejoin the string. + return s.length < 2 ? (q[0] + ? one$1(q[0].x) + : zero$1(b)) + : (b = q.length, function(t) { + for (var i = 0, o; i < b; ++i) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }); +}; + +var interpolate = function(a, b) { + var t = typeof b, c; + return b == null || t === "boolean" ? constant$4(b) + : (t === "number" ? reinterpolate + : t === "string" ? ((c = color$1(b)) ? (b = c, rgb$1) : string) + : b instanceof color$1 ? rgb$1 + : b instanceof Date ? date + : Array.isArray(b) ? array$3 + : typeof b.valueOf !== "function" && typeof b.toString !== "function" || isNaN(b) ? object$2 + : reinterpolate)(a, b); +}; + +var interpolateRound = function(a, b) { + return a = +a, b -= a, function(t) { + return Math.round(a + b * t); + }; +}; + +var degrees = 180 / Math.PI; + +var identity$5 = { + translateX: 0, + translateY: 0, + rotate: 0, + skewX: 0, + scaleX: 1, + scaleY: 1 +}; + +var decompose = function(a, b, c, d, e, f) { + var scaleX, scaleY, skewX; + if (scaleX = Math.sqrt(a * a + b * b)) a /= scaleX, b /= scaleX; + if (skewX = a * c + b * d) c -= a * skewX, d -= b * skewX; + if (scaleY = Math.sqrt(c * c + d * d)) c /= scaleY, d /= scaleY, skewX /= scaleY; + if (a * d < b * c) a = -a, b = -b, skewX = -skewX, scaleX = -scaleX; + return { + translateX: e, + translateY: f, + rotate: Math.atan2(b, a) * degrees, + skewX: Math.atan(skewX) * degrees, + scaleX: scaleX, + scaleY: scaleY + }; +}; + +var cssNode; +var cssRoot; +var cssView; +var svgNode; + +function parseCss(value) { + if (value === "none") return identity$5; + if (!cssNode) cssNode = document.createElement("DIV"), cssRoot = document.documentElement, cssView = document.defaultView; + cssNode.style.transform = value; + value = cssView.getComputedStyle(cssRoot.appendChild(cssNode), null).getPropertyValue("transform"); + cssRoot.removeChild(cssNode); + value = value.slice(7, -1).split(","); + return decompose(+value[0], +value[1], +value[2], +value[3], +value[4], +value[5]); +} + +function parseSvg(value) { + if (value == null) return identity$5; + if (!svgNode) svgNode = document.createElementNS("http://www.w3.org/2000/svg", "g"); + svgNode.setAttribute("transform", value); + if (!(value = svgNode.transform.baseVal.consolidate())) return identity$5; + value = value.matrix; + return decompose(value.a, value.b, value.c, value.d, value.e, value.f); +} + +function interpolateTransform(parse, pxComma, pxParen, degParen) { + + function pop(s) { + return s.length ? s.pop() + " " : ""; + } + + function translate(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push("translate(", null, pxComma, null, pxParen); + q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)}); + } else if (xb || yb) { + s.push("translate(" + xb + pxComma + yb + pxParen); + } + } + + function rotate(a, b, s, q) { + if (a !== b) { + if (a - b > 180) b += 360; else if (b - a > 180) a += 360; // shortest path + q.push({i: s.push(pop(s) + "rotate(", null, degParen) - 2, x: reinterpolate(a, b)}); + } else if (b) { + s.push(pop(s) + "rotate(" + b + degParen); + } + } + + function skewX(a, b, s, q) { + if (a !== b) { + q.push({i: s.push(pop(s) + "skewX(", null, degParen) - 2, x: reinterpolate(a, b)}); + } else if (b) { + s.push(pop(s) + "skewX(" + b + degParen); + } + } + + function scale(xa, ya, xb, yb, s, q) { + if (xa !== xb || ya !== yb) { + var i = s.push(pop(s) + "scale(", null, ",", null, ")"); + q.push({i: i - 4, x: reinterpolate(xa, xb)}, {i: i - 2, x: reinterpolate(ya, yb)}); + } else if (xb !== 1 || yb !== 1) { + s.push(pop(s) + "scale(" + xb + "," + yb + ")"); + } + } + + return function(a, b) { + var s = [], // string constants and placeholders + q = []; // number interpolators + a = parse(a), b = parse(b); + translate(a.translateX, a.translateY, b.translateX, b.translateY, s, q); + rotate(a.rotate, b.rotate, s, q); + skewX(a.skewX, b.skewX, s, q); + scale(a.scaleX, a.scaleY, b.scaleX, b.scaleY, s, q); + a = b = null; // gc + return function(t) { + var i = -1, n = q.length, o; + while (++i < n) s[(o = q[i]).i] = o.x(t); + return s.join(""); + }; + }; +} + +var interpolateTransformCss = interpolateTransform(parseCss, "px, ", "px)", "deg)"); +var interpolateTransformSvg = interpolateTransform(parseSvg, ", ", ")", ")"); + +var rho = Math.SQRT2; +var rho2 = 2; +var rho4 = 4; +var epsilon2 = 1e-12; + +function cosh(x) { + return ((x = Math.exp(x)) + 1 / x) / 2; +} + +function sinh(x) { + return ((x = Math.exp(x)) - 1 / x) / 2; +} + +function tanh(x) { + return ((x = Math.exp(2 * x)) - 1) / (x + 1); +} + +// p0 = [ux0, uy0, w0] +// p1 = [ux1, uy1, w1] +var zoom$1 = function(p0, p1) { + var ux0 = p0[0], uy0 = p0[1], w0 = p0[2], + ux1 = p1[0], uy1 = p1[1], w1 = p1[2], + dx = ux1 - ux0, + dy = uy1 - uy0, + d2 = dx * dx + dy * dy, + i, + S; + + // Special case for u0 ≅ u1. + if (d2 < epsilon2) { + S = Math.log(w1 / w0) / rho; + i = function(t) { + return [ + ux0 + t * dx, + uy0 + t * dy, + w0 * Math.exp(rho * t * S) + ]; + }; + } + + // General case. + else { + var d1 = Math.sqrt(d2), + b0 = (w1 * w1 - w0 * w0 + rho4 * d2) / (2 * w0 * rho2 * d1), + b1 = (w1 * w1 - w0 * w0 - rho4 * d2) / (2 * w1 * rho2 * d1), + r0 = Math.log(Math.sqrt(b0 * b0 + 1) - b0), + r1 = Math.log(Math.sqrt(b1 * b1 + 1) - b1); + S = (r1 - r0) / rho; + i = function(t) { + var s = t * S, + coshr0 = cosh(r0), + u = w0 / (rho2 * d1) * (coshr0 * tanh(rho * s + r0) - sinh(r0)); + return [ + ux0 + u * dx, + uy0 + u * dy, + w0 * coshr0 / cosh(rho * s + r0) + ]; + }; + } + + i.duration = S * 1000; + + return i; +}; + +function hsl$1(hue$$1) { + return function(start, end) { + var h = hue$$1((start = hsl(start)).h, (end = hsl(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(t); + start.opacity = opacity(t); + return start + ""; + }; + } +} + +var hsl$2 = hsl$1(hue); +var hslLong = hsl$1(nogamma); + +function lab$1(start, end) { + var l = nogamma((start = lab(start)).l, (end = lab(end)).l), + a = nogamma(start.a, end.a), + b = nogamma(start.b, end.b), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.l = l(t); + start.a = a(t); + start.b = b(t); + start.opacity = opacity(t); + return start + ""; + }; +} + +function hcl$1(hue$$1) { + return function(start, end) { + var h = hue$$1((start = hcl(start)).h, (end = hcl(end)).h), + c = nogamma(start.c, end.c), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.c = c(t); + start.l = l(t); + start.opacity = opacity(t); + return start + ""; + }; + } +} + +var hcl$2 = hcl$1(hue); +var hclLong = hcl$1(nogamma); + +function cubehelix$1(hue$$1) { + return (function cubehelixGamma(y) { + y = +y; + + function cubehelix$$1(start, end) { + var h = hue$$1((start = cubehelix(start)).h, (end = cubehelix(end)).h), + s = nogamma(start.s, end.s), + l = nogamma(start.l, end.l), + opacity = nogamma(start.opacity, end.opacity); + return function(t) { + start.h = h(t); + start.s = s(t); + start.l = l(Math.pow(t, y)); + start.opacity = opacity(t); + return start + ""; + }; + } + + cubehelix$$1.gamma = cubehelixGamma; + + return cubehelix$$1; + })(1); +} + +var cubehelix$2 = cubehelix$1(hue); +var cubehelixLong = cubehelix$1(nogamma); + +var quantize$1 = function(interpolator, n) { + var samples = new Array(n); + for (var i = 0; i < n; ++i) samples[i] = interpolator(i / (n - 1)); + return samples; +}; + + + +var $$1 = Object.freeze({ + interpolate: interpolate, + interpolateArray: array$3, + interpolateBasis: basis$1, + interpolateBasisClosed: basisClosed, + interpolateDate: date, + interpolateNumber: reinterpolate, + interpolateObject: object$2, + interpolateRound: interpolateRound, + interpolateString: string, + interpolateTransformCss: interpolateTransformCss, + interpolateTransformSvg: interpolateTransformSvg, + interpolateZoom: zoom$1, + interpolateRgb: rgb$1, + interpolateRgbBasis: rgbBasis, + interpolateRgbBasisClosed: rgbBasisClosed, + interpolateHsl: hsl$2, + interpolateHslLong: hslLong, + interpolateLab: lab$1, + interpolateHcl: hcl$2, + interpolateHclLong: hclLong, + interpolateCubehelix: cubehelix$2, + interpolateCubehelixLong: cubehelixLong, + quantize: quantize$1 +}); + +var constant$5 = function(x) { + return function() { + return x; + }; +}; + +var number$2 = function(x) { + return +x; +}; + +var unit = [0, 1]; + +function deinterpolateLinear(a, b) { + return (b -= (a = +a)) + ? function(x) { return (x - a) / b; } + : constant$5(b); +} + +function deinterpolateClamp(deinterpolate) { + return function(a, b) { + var d = deinterpolate(a = +a, b = +b); + return function(x) { return x <= a ? 0 : x >= b ? 1 : d(x); }; + }; +} + +function reinterpolateClamp(reinterpolate$$1) { + return function(a, b) { + var r = reinterpolate$$1(a = +a, b = +b); + return function(t) { return t <= 0 ? a : t >= 1 ? b : r(t); }; + }; +} + +function bimap(domain, range, deinterpolate, reinterpolate$$1) { + var d0 = domain[0], d1 = domain[1], r0 = range[0], r1 = range[1]; + if (d1 < d0) d0 = deinterpolate(d1, d0), r0 = reinterpolate$$1(r1, r0); + else d0 = deinterpolate(d0, d1), r0 = reinterpolate$$1(r0, r1); + return function(x) { return r0(d0(x)); }; +} + +function polymap(domain, range, deinterpolate, reinterpolate$$1) { + var j = Math.min(domain.length, range.length) - 1, + d = new Array(j), + r = new Array(j), + i = -1; + + // Reverse descending domains. + if (domain[j] < domain[0]) { + domain = domain.slice().reverse(); + range = range.slice().reverse(); + } + + while (++i < j) { + d[i] = deinterpolate(domain[i], domain[i + 1]); + r[i] = reinterpolate$$1(range[i], range[i + 1]); + } + + return function(x) { + var i = bisectRight(domain, x, 1, j) - 1; + return r[i](d[i](x)); + }; +} + +function copy(source, target) { + return target + .domain(source.domain()) + .range(source.range()) + .interpolate(source.interpolate()) + .clamp(source.clamp()); +} + +// deinterpolate(a, b)(x) takes a domain value x in [a,b] and returns the corresponding parameter t in [0,1]. +// reinterpolate(a, b)(t) takes a parameter t in [0,1] and returns the corresponding domain value x in [a,b]. +function continuous(deinterpolate, reinterpolate$$1) { + var domain = unit, + range = unit, + interpolate$$1 = interpolate, + clamp = false, + piecewise, + output, + input; + + function rescale() { + piecewise = Math.min(domain.length, range.length) > 2 ? polymap : bimap; + output = input = null; + return scale; + } + + function scale(x) { + return (output || (output = piecewise(domain, range, clamp ? deinterpolateClamp(deinterpolate) : deinterpolate, interpolate$$1)))(+x); + } + + scale.invert = function(y) { + return (input || (input = piecewise(range, domain, deinterpolateLinear, clamp ? reinterpolateClamp(reinterpolate$$1) : reinterpolate$$1)))(+y); + }; + + scale.domain = function(_) { + return arguments.length ? (domain = map$3.call(_, number$2), rescale()) : domain.slice(); + }; + + scale.range = function(_) { + return arguments.length ? (range = slice$2.call(_), rescale()) : range.slice(); + }; + + scale.rangeRound = function(_) { + return range = slice$2.call(_), interpolate$$1 = interpolateRound, rescale(); + }; + + scale.clamp = function(_) { + return arguments.length ? (clamp = !!_, rescale()) : clamp; + }; + + scale.interpolate = function(_) { + return arguments.length ? (interpolate$$1 = _, rescale()) : interpolate$$1; + }; + + return rescale(); +} + +// Computes the decimal coefficient and exponent of the specified number x with +// significant digits p, where x is positive and p is in [1, 21] or undefined. +// For example, formatDecimal(1.23) returns ["123", 0]. +var formatDecimal = function(x, p) { + if ((i = (x = p ? x.toExponential(p - 1) : x.toExponential()).indexOf("e")) < 0) return null; // NaN, ±Infinity + var i, coefficient = x.slice(0, i); + + // The string returned by toExponential either has the form \d\.\d+e[-+]\d+ + // (e.g., 1.2e+3) or the form \de[-+]\d+ (e.g., 1e+3). + return [ + coefficient.length > 1 ? coefficient[0] + coefficient.slice(2) : coefficient, + +x.slice(i + 1) + ]; +}; + +var exponent = function(x) { + return x = formatDecimal(Math.abs(x)), x ? x[1] : NaN; +}; + +var formatGroup = function(grouping, thousands) { + return function(value, width) { + var i = value.length, + t = [], + j = 0, + g = grouping[0], + length = 0; + + while (i > 0 && g > 0) { + if (length + g + 1 > width) g = Math.max(1, width - length); + t.push(value.substring(i -= g, i + g)); + if ((length += g + 1) > width) break; + g = grouping[j = (j + 1) % grouping.length]; + } + + return t.reverse().join(thousands); + }; +}; + +var formatNumerals = function(numerals) { + return function(value) { + return value.replace(/[0-9]/g, function(i) { + return numerals[+i]; + }); + }; +}; + +var formatDefault = function(x, p) { + x = x.toPrecision(p); + + out: for (var n = x.length, i = 1, i0 = -1, i1; i < n; ++i) { + switch (x[i]) { + case ".": i0 = i1 = i; break; + case "0": if (i0 === 0) i0 = i; i1 = i; break; + case "e": break out; + default: if (i0 > 0) i0 = 0; break; + } + } + + return i0 > 0 ? x.slice(0, i0) + x.slice(i1 + 1) : x; +}; + +var prefixExponent; + +var formatPrefixAuto = function(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1], + i = exponent - (prefixExponent = Math.max(-8, Math.min(8, Math.floor(exponent / 3))) * 3) + 1, + n = coefficient.length; + return i === n ? coefficient + : i > n ? coefficient + new Array(i - n + 1).join("0") + : i > 0 ? coefficient.slice(0, i) + "." + coefficient.slice(i) + : "0." + new Array(1 - i).join("0") + formatDecimal(x, Math.max(0, p + i - 1))[0]; // less than 1y! +}; + +var formatRounded = function(x, p) { + var d = formatDecimal(x, p); + if (!d) return x + ""; + var coefficient = d[0], + exponent = d[1]; + return exponent < 0 ? "0." + new Array(-exponent).join("0") + coefficient + : coefficient.length > exponent + 1 ? coefficient.slice(0, exponent + 1) + "." + coefficient.slice(exponent + 1) + : coefficient + new Array(exponent - coefficient.length + 2).join("0"); +}; + +var formatTypes = { + "": formatDefault, + "%": function(x, p) { return (x * 100).toFixed(p); }, + "b": function(x) { return Math.round(x).toString(2); }, + "c": function(x) { return x + ""; }, + "d": function(x) { return Math.round(x).toString(10); }, + "e": function(x, p) { return x.toExponential(p); }, + "f": function(x, p) { return x.toFixed(p); }, + "g": function(x, p) { return x.toPrecision(p); }, + "o": function(x) { return Math.round(x).toString(8); }, + "p": function(x, p) { return formatRounded(x * 100, p); }, + "r": formatRounded, + "s": formatPrefixAuto, + "X": function(x) { return Math.round(x).toString(16).toUpperCase(); }, + "x": function(x) { return Math.round(x).toString(16); } +}; + +// [[fill]align][sign][symbol][0][width][,][.precision][type] +var re = /^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i; + +function formatSpecifier(specifier) { + return new FormatSpecifier(specifier); +} + +formatSpecifier.prototype = FormatSpecifier.prototype; // instanceof + +function FormatSpecifier(specifier) { + if (!(match = re.exec(specifier))) throw new Error("invalid format: " + specifier); + + var match, + fill = match[1] || " ", + align = match[2] || ">", + sign = match[3] || "-", + symbol = match[4] || "", + zero = !!match[5], + width = match[6] && +match[6], + comma = !!match[7], + precision = match[8] && +match[8].slice(1), + type = match[9] || ""; + + // The "n" type is an alias for ",g". + if (type === "n") comma = true, type = "g"; + + // Map invalid types to the default format. + else if (!formatTypes[type]) type = ""; + + // If zero fill is specified, padding goes after sign and before digits. + if (zero || (fill === "0" && align === "=")) zero = true, fill = "0", align = "="; + + this.fill = fill; + this.align = align; + this.sign = sign; + this.symbol = symbol; + this.zero = zero; + this.width = width; + this.comma = comma; + this.precision = precision; + this.type = type; +} + +FormatSpecifier.prototype.toString = function() { + return this.fill + + this.align + + this.sign + + this.symbol + + (this.zero ? "0" : "") + + (this.width == null ? "" : Math.max(1, this.width | 0)) + + (this.comma ? "," : "") + + (this.precision == null ? "" : "." + Math.max(0, this.precision | 0)) + + this.type; +}; + +var identity$6 = function(x) { + return x; +}; + +var prefixes = ["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"]; + +var formatLocale$1 = function(locale) { + var group = locale.grouping && locale.thousands ? formatGroup(locale.grouping, locale.thousands) : identity$6, + currency = locale.currency, + decimal = locale.decimal, + numerals = locale.numerals ? formatNumerals(locale.numerals) : identity$6, + percent = locale.percent || "%"; + + function newFormat(specifier) { + specifier = formatSpecifier(specifier); + + var fill = specifier.fill, + align = specifier.align, + sign = specifier.sign, + symbol = specifier.symbol, + zero = specifier.zero, + width = specifier.width, + comma = specifier.comma, + precision = specifier.precision, + type = specifier.type; + + // Compute the prefix and suffix. + // For SI-prefix, the suffix is lazily computed. + var prefix = symbol === "$" ? currency[0] : symbol === "#" && /[boxX]/.test(type) ? "0" + type.toLowerCase() : "", + suffix = symbol === "$" ? currency[1] : /[%p]/.test(type) ? percent : ""; + + // What format function should we use? + // Is this an integer type? + // Can this type generate exponential notation? + var formatType = formatTypes[type], + maybeSuffix = !type || /[defgprs%]/.test(type); + + // Set the default precision if not specified, + // or clamp the specified precision to the supported range. + // For significant precision, it must be in [1, 21]. + // For fixed precision, it must be in [0, 20]. + precision = precision == null ? (type ? 6 : 12) + : /[gprs]/.test(type) ? Math.max(1, Math.min(21, precision)) + : Math.max(0, Math.min(20, precision)); + + function format(value) { + var valuePrefix = prefix, + valueSuffix = suffix, + i, n, c; + + if (type === "c") { + valueSuffix = formatType(value) + valueSuffix; + value = ""; + } else { + value = +value; + + // Perform the initial formatting. + var valueNegative = value < 0; + value = formatType(Math.abs(value), precision); + + // If a negative value rounds to zero during formatting, treat as positive. + if (valueNegative && +value === 0) valueNegative = false; + + // Compute the prefix and suffix. + valuePrefix = (valueNegative ? (sign === "(" ? sign : "-") : sign === "-" || sign === "(" ? "" : sign) + valuePrefix; + valueSuffix = (type === "s" ? prefixes[8 + prefixExponent / 3] : "") + valueSuffix + (valueNegative && sign === "(" ? ")" : ""); + + // Break the formatted value into the integer “value” part that can be + // grouped, and fractional or exponential “suffix” part that is not. + if (maybeSuffix) { + i = -1, n = value.length; + while (++i < n) { + if (c = value.charCodeAt(i), 48 > c || c > 57) { + valueSuffix = (c === 46 ? decimal + value.slice(i + 1) : value.slice(i)) + valueSuffix; + value = value.slice(0, i); + break; + } + } + } + } + + // If the fill character is not "0", grouping is applied before padding. + if (comma && !zero) value = group(value, Infinity); + + // Compute the padding. + var length = valuePrefix.length + value.length + valueSuffix.length, + padding = length < width ? new Array(width - length + 1).join(fill) : ""; + + // If the fill character is "0", grouping is applied after padding. + if (comma && zero) value = group(padding + value, padding.length ? width - valueSuffix.length : Infinity), padding = ""; + + // Reconstruct the final output based on the desired alignment. + switch (align) { + case "<": value = valuePrefix + value + valueSuffix + padding; break; + case "=": value = valuePrefix + padding + value + valueSuffix; break; + case "^": value = padding.slice(0, length = padding.length >> 1) + valuePrefix + value + valueSuffix + padding.slice(length); break; + default: value = padding + valuePrefix + value + valueSuffix; break; + } + + return numerals(value); + } + + format.toString = function() { + return specifier + ""; + }; + + return format; + } + + function formatPrefix(specifier, value) { + var f = newFormat((specifier = formatSpecifier(specifier), specifier.type = "f", specifier)), + e = Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3, + k = Math.pow(10, -e), + prefix = prefixes[8 + e / 3]; + return function(value) { + return f(k * value) + prefix; + }; + } + + return { + format: newFormat, + formatPrefix: formatPrefix + }; +}; + +var locale$2; +var format; +var formatPrefix; + +defaultLocale$1({ + decimal: ".", + thousands: ",", + grouping: [3], + currency: ["$", ""] +}); + +function defaultLocale$1(definition) { + locale$2 = formatLocale$1(definition); + format = locale$2.format; + formatPrefix = locale$2.formatPrefix; + return locale$2; +} + +var precisionFixed = function(step) { + return Math.max(0, -exponent(Math.abs(step))); +}; + +var precisionPrefix = function(step, value) { + return Math.max(0, Math.max(-8, Math.min(8, Math.floor(exponent(value) / 3))) * 3 - exponent(Math.abs(step))); +}; + +var precisionRound = function(step, max) { + step = Math.abs(step), max = Math.abs(max) - step; + return Math.max(0, exponent(max) - exponent(step)) + 1; +}; + +var tickFormat$1 = function(domain, count, specifier) { + var start = domain[0], + stop = domain[domain.length - 1], + step = tickStep(start, stop, count == null ? 10 : count), + precision; + specifier = formatSpecifier(specifier == null ? ",f" : specifier); + switch (specifier.type) { + case "s": { + var value = Math.max(Math.abs(start), Math.abs(stop)); + if (specifier.precision == null && !isNaN(precision = precisionPrefix(step, value))) specifier.precision = precision; + return formatPrefix(specifier, value); + } + case "": + case "e": + case "g": + case "p": + case "r": { + if (specifier.precision == null && !isNaN(precision = precisionRound(step, Math.max(Math.abs(start), Math.abs(stop))))) specifier.precision = precision - (specifier.type === "e"); + break; + } + case "f": + case "%": { + if (specifier.precision == null && !isNaN(precision = precisionFixed(step))) specifier.precision = precision - (specifier.type === "%") * 2; + break; + } + } + return format(specifier); +}; + +function linearish(scale) { + var domain = scale.domain; + + scale.ticks = function(count) { + var d = domain(); + return ticks(d[0], d[d.length - 1], count == null ? 10 : count); + }; + + scale.tickFormat = function(count, specifier) { + return tickFormat$1(domain(), count, specifier); + }; + + scale.nice = function(count) { + if (count == null) count = 10; + + var d = domain(), + i0 = 0, + i1 = d.length - 1, + start = d[i0], + stop = d[i1], + step; + + if (stop < start) { + step = start, start = stop, stop = step; + step = i0, i0 = i1, i1 = step; + } + + step = tickIncrement(start, stop, count); + + if (step > 0) { + start = Math.floor(start / step) * step; + stop = Math.ceil(stop / step) * step; + step = tickIncrement(start, stop, count); + } else if (step < 0) { + start = Math.ceil(start * step) / step; + stop = Math.floor(stop * step) / step; + step = tickIncrement(start, stop, count); + } + + if (step > 0) { + d[i0] = Math.floor(start / step) * step; + d[i1] = Math.ceil(stop / step) * step; + domain(d); + } else if (step < 0) { + d[i0] = Math.ceil(start * step) / step; + d[i1] = Math.floor(stop * step) / step; + domain(d); + } + + return scale; + }; + + return scale; +} + +function linear() { + var scale = continuous(deinterpolateLinear, reinterpolate); + + scale.copy = function() { + return copy(scale, linear()); + }; + + return linearish(scale); +} + +function identity$4() { + var domain = [0, 1]; + + function scale(x) { + return +x; + } + + scale.invert = scale; + + scale.domain = scale.range = function(_) { + return arguments.length ? (domain = map$3.call(_, number$2), scale) : domain.slice(); + }; + + scale.copy = function() { + return identity$4().domain(domain); + }; + + return linearish(scale); +} + +var nice = function(domain, interval) { + domain = domain.slice(); + + var i0 = 0, + i1 = domain.length - 1, + x0 = domain[i0], + x1 = domain[i1], + t; + + if (x1 < x0) { + t = i0, i0 = i1, i1 = t; + t = x0, x0 = x1, x1 = t; + } + + domain[i0] = interval.floor(x0); + domain[i1] = interval.ceil(x1); + return domain; +}; + +function deinterpolate(a, b) { + return (b = Math.log(b / a)) + ? function(x) { return Math.log(x / a) / b; } + : constant$5(b); +} + +function reinterpolate$1(a, b) { + return a < 0 + ? function(t) { return -Math.pow(-b, t) * Math.pow(-a, 1 - t); } + : function(t) { return Math.pow(b, t) * Math.pow(a, 1 - t); }; +} + +function pow10(x) { + return isFinite(x) ? +("1e" + x) : x < 0 ? 0 : x; +} + +function powp(base) { + return base === 10 ? pow10 + : base === Math.E ? Math.exp + : function(x) { return Math.pow(base, x); }; +} + +function logp(base) { + return base === Math.E ? Math.log + : base === 10 && Math.log10 + || base === 2 && Math.log2 + || (base = Math.log(base), function(x) { return Math.log(x) / base; }); +} + +function reflect(f) { + return function(x) { + return -f(-x); + }; +} + +function log$2() { + var scale = continuous(deinterpolate, reinterpolate$1).domain([1, 10]), + domain = scale.domain, + base = 10, + logs = logp(10), + pows = powp(10); + + function rescale() { + logs = logp(base), pows = powp(base); + if (domain()[0] < 0) logs = reflect(logs), pows = reflect(pows); + return scale; + } + + scale.base = function(_) { + return arguments.length ? (base = +_, rescale()) : base; + }; + + scale.domain = function(_) { + return arguments.length ? (domain(_), rescale()) : domain(); + }; + + scale.ticks = function(count) { + var d = domain(), + u = d[0], + v = d[d.length - 1], + r; + + if (r = v < u) i = u, u = v, v = i; + + var i = logs(u), + j = logs(v), + p, + k, + t, + n = count == null ? 10 : +count, + z = []; + + if (!(base % 1) && j - i < n) { + i = Math.round(i) - 1, j = Math.round(j) + 1; + if (u > 0) for (; i < j; ++i) { + for (k = 1, p = pows(i); k < base; ++k) { + t = p * k; + if (t < u) continue; + if (t > v) break; + z.push(t); + } + } else for (; i < j; ++i) { + for (k = base - 1, p = pows(i); k >= 1; --k) { + t = p * k; + if (t < u) continue; + if (t > v) break; + z.push(t); + } + } + } else { + z = ticks(i, j, Math.min(j - i, n)).map(pows); + } + + return r ? z.reverse() : z; + }; + + scale.tickFormat = function(count, specifier) { + if (specifier == null) specifier = base === 10 ? ".0e" : ","; + if (typeof specifier !== "function") specifier = format(specifier); + if (count === Infinity) return specifier; + if (count == null) count = 10; + var k = Math.max(1, base * count / scale.ticks().length); // TODO fast estimate? + return function(d) { + var i = d / pows(Math.round(logs(d))); + if (i * base < base - 0.5) i *= base; + return i <= k ? specifier(d) : ""; + }; + }; + + scale.nice = function() { + return domain(nice(domain(), { + floor: function(x) { return pows(Math.floor(logs(x))); }, + ceil: function(x) { return pows(Math.ceil(logs(x))); } + })); + }; + + scale.copy = function() { + return copy(scale, log$2().base(base)); + }; + + return scale; +} + +function raise(x, exponent) { + return x < 0 ? -Math.pow(-x, exponent) : Math.pow(x, exponent); +} + +function pow$1() { + var exponent = 1, + scale = continuous(deinterpolate, reinterpolate), + domain = scale.domain; + + function deinterpolate(a, b) { + return (b = raise(b, exponent) - (a = raise(a, exponent))) + ? function(x) { return (raise(x, exponent) - a) / b; } + : constant$5(b); + } + + function reinterpolate(a, b) { + b = raise(b, exponent) - (a = raise(a, exponent)); + return function(t) { return raise(a + b * t, 1 / exponent); }; + } + + scale.exponent = function(_) { + return arguments.length ? (exponent = +_, domain(domain())) : exponent; + }; + + scale.copy = function() { + return copy(scale, pow$1().exponent(exponent)); + }; + + return linearish(scale); +} + +function sqrt$1() { + return pow$1().exponent(0.5); +} + +function quantile() { + var domain = [], + range = [], + thresholds = []; + + function rescale() { + var i = 0, n = Math.max(1, range.length); + thresholds = new Array(n - 1); + while (++i < n) thresholds[i - 1] = threshold(domain, i / n); + return scale; + } + + function scale(x) { + if (!isNaN(x = +x)) return range[bisectRight(thresholds, x)]; + } + + scale.invertExtent = function(y) { + var i = range.indexOf(y); + return i < 0 ? [NaN, NaN] : [ + i > 0 ? thresholds[i - 1] : domain[0], + i < thresholds.length ? thresholds[i] : domain[domain.length - 1] + ]; + }; + + scale.domain = function(_) { + if (!arguments.length) return domain.slice(); + domain = []; + for (var i = 0, n = _.length, d; i < n; ++i) if (d = _[i], d != null && !isNaN(d = +d)) domain.push(d); + domain.sort(ascending); + return rescale(); + }; + + scale.range = function(_) { + return arguments.length ? (range = slice$2.call(_), rescale()) : range.slice(); + }; + + scale.quantiles = function() { + return thresholds.slice(); + }; + + scale.copy = function() { + return quantile() + .domain(domain) + .range(range); + }; + + return scale; +} + +function quantize$2() { + var x0 = 0, + x1 = 1, + n = 1, + domain = [0.5], + range = [0, 1]; + + function scale(x) { + if (x <= x) return range[bisectRight(domain, x, 0, n)]; + } + + function rescale() { + var i = -1; + domain = new Array(n); + while (++i < n) domain[i] = ((i + 1) * x1 - (i - n) * x0) / (n + 1); + return scale; + } + + scale.domain = function(_) { + return arguments.length ? (x0 = +_[0], x1 = +_[1], rescale()) : [x0, x1]; + }; + + scale.range = function(_) { + return arguments.length ? (n = (range = slice$2.call(_)).length - 1, rescale()) : range.slice(); + }; + + scale.invertExtent = function(y) { + var i = range.indexOf(y); + return i < 0 ? [NaN, NaN] + : i < 1 ? [x0, domain[0]] + : i >= n ? [domain[n - 1], x1] + : [domain[i - 1], domain[i]]; + }; + + scale.copy = function() { + return quantize$2() + .domain([x0, x1]) + .range(range); + }; + + return linearish(scale); +} + +function threshold$1() { + var domain = [0.5], + range = [0, 1], + n = 1; + + function scale(x) { + if (x <= x) return range[bisectRight(domain, x, 0, n)]; + } + + scale.domain = function(_) { + return arguments.length ? (domain = slice$2.call(_), n = Math.min(domain.length, range.length - 1), scale) : domain.slice(); + }; + + scale.range = function(_) { + return arguments.length ? (range = slice$2.call(_), n = Math.min(domain.length, range.length - 1), scale) : range.slice(); + }; + + scale.invertExtent = function(y) { + var i = range.indexOf(y); + return [domain[i - 1], domain[i]]; + }; + + scale.copy = function() { + return threshold$1() + .domain(domain) + .range(range); + }; + + return scale; +} + +var durationSecond$1 = 1000; +var durationMinute$1 = durationSecond$1 * 60; +var durationHour$1 = durationMinute$1 * 60; +var durationDay$1 = durationHour$1 * 24; +var durationWeek$1 = durationDay$1 * 7; +var durationMonth = durationDay$1 * 30; +var durationYear = durationDay$1 * 365; + +function date$1(t) { + return new Date(t); +} + +function number$3(t) { + return t instanceof Date ? +t : +new Date(+t); +} + +function calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format) { + var scale = continuous(deinterpolateLinear, reinterpolate), + invert = scale.invert, + domain = scale.domain; + + var formatMillisecond = format(".%L"), + formatSecond = format(":%S"), + formatMinute = format("%I:%M"), + formatHour = format("%I %p"), + formatDay = format("%a %d"), + formatWeek = format("%b %d"), + formatMonth = format("%B"), + formatYear = format("%Y"); + + var tickIntervals = [ + [second$$1, 1, durationSecond$1], + [second$$1, 5, 5 * durationSecond$1], + [second$$1, 15, 15 * durationSecond$1], + [second$$1, 30, 30 * durationSecond$1], + [minute$$1, 1, durationMinute$1], + [minute$$1, 5, 5 * durationMinute$1], + [minute$$1, 15, 15 * durationMinute$1], + [minute$$1, 30, 30 * durationMinute$1], + [ hour$$1, 1, durationHour$1 ], + [ hour$$1, 3, 3 * durationHour$1 ], + [ hour$$1, 6, 6 * durationHour$1 ], + [ hour$$1, 12, 12 * durationHour$1 ], + [ day$$1, 1, durationDay$1 ], + [ day$$1, 2, 2 * durationDay$1 ], + [ week, 1, durationWeek$1 ], + [ month$$1, 1, durationMonth ], + [ month$$1, 3, 3 * durationMonth ], + [ year$$1, 1, durationYear ] + ]; + + function tickFormat(date$$1) { + return (second$$1(date$$1) < date$$1 ? formatMillisecond + : minute$$1(date$$1) < date$$1 ? formatSecond + : hour$$1(date$$1) < date$$1 ? formatMinute + : day$$1(date$$1) < date$$1 ? formatHour + : month$$1(date$$1) < date$$1 ? (week(date$$1) < date$$1 ? formatDay : formatWeek) + : year$$1(date$$1) < date$$1 ? formatMonth + : formatYear)(date$$1); + } + + function tickInterval(interval, start, stop, step) { + if (interval == null) interval = 10; + + // If a desired tick count is specified, pick a reasonable tick interval + // based on the extent of the domain and a rough estimate of tick size. + // Otherwise, assume interval is already a time interval and use it. + if (typeof interval === "number") { + var target = Math.abs(stop - start) / interval, + i = bisector(function(i) { return i[2]; }).right(tickIntervals, target); + if (i === tickIntervals.length) { + step = tickStep(start / durationYear, stop / durationYear, interval); + interval = year$$1; + } else if (i) { + i = tickIntervals[target / tickIntervals[i - 1][2] < tickIntervals[i][2] / target ? i - 1 : i]; + step = i[1]; + interval = i[0]; + } else { + step = Math.max(tickStep(start, stop, interval), 1); + interval = millisecond$$1; + } + } + + return step == null ? interval : interval.every(step); + } + + scale.invert = function(y) { + return new Date(invert(y)); + }; + + scale.domain = function(_) { + return arguments.length ? domain(map$3.call(_, number$3)) : domain().map(date$1); + }; + + scale.ticks = function(interval, step) { + var d = domain(), + t0 = d[0], + t1 = d[d.length - 1], + r = t1 < t0, + t; + if (r) t = t0, t0 = t1, t1 = t; + t = tickInterval(interval, t0, t1, step); + t = t ? t.range(t0, t1 + 1) : []; // inclusive stop + return r ? t.reverse() : t; + }; + + scale.tickFormat = function(count, specifier) { + return specifier == null ? tickFormat : format(specifier); + }; + + scale.nice = function(interval, step) { + var d = domain(); + return (interval = tickInterval(interval, d[0], d[d.length - 1], step)) + ? domain(nice(d, interval)) + : scale; + }; + + scale.copy = function() { + return copy(scale, calendar(year$$1, month$$1, week, day$$1, hour$$1, minute$$1, second$$1, millisecond$$1, format)); + }; + + return scale; +} + +var time = function() { + return calendar(year, month, sunday, day, hour, minute, second, millisecond, timeFormat).domain([new Date(2000, 0, 1), new Date(2000, 0, 2)]); +}; + +var utcTime = function() { + return calendar(utcYear, utcMonth, utcSunday, utcDay, utcHour, utcMinute, second, millisecond, utcFormat).domain([Date.UTC(2000, 0, 1), Date.UTC(2000, 0, 2)]); +}; + +function band$$1() { + var scale = ordinal().unknown(undefined), + domain = scale.domain, + ordinalRange = scale.range, + range = [0, 1], + step, + bandwidth, + round = false, + paddingInner = 0, + paddingOuter = 0, + align = 0.5; + + delete scale.unknown; + + function rescale() { + var n = domain().length, + reverse = range[1] < range[0], + start = range[reverse - 0], + stop = range[1 - reverse], + space = bandSpace(n, paddingInner, paddingOuter); + + step = (stop - start) / (space || 1); + if (round) { + step = Math.floor(step); + } + start += (stop - start - step * (n - paddingInner)) * align; + bandwidth = step * (1 - paddingInner); + if (round) { + start = Math.round(start); + bandwidth = Math.round(bandwidth); + } + var values = sequence(n).map(function(i) { return start + step * i; }); + return ordinalRange(reverse ? values.reverse() : values); + } + + scale.domain = function(_) { + if (arguments.length) { + domain(_); + return rescale(); + } else { + return domain(); + } + }; + + scale.range = function(_) { + if (arguments.length) { + range = [+_[0], +_[1]]; + return rescale(); + } else { + return range.slice(); + } + }; + + scale.rangeRound = function(_) { + range = [+_[0], +_[1]]; + round = true; + return rescale(); + }; + + scale.bandwidth = function() { + return bandwidth; + }; + + scale.step = function() { + return step; + }; + + scale.round = function(_) { + if (arguments.length) { + round = !!_; + return rescale(); + } else { + return round; + } + }; + + scale.padding = function(_) { + if (arguments.length) { + paddingOuter = Math.max(0, Math.min(1, _)); + paddingInner = paddingOuter; + return rescale(); + } else { + return paddingInner; + } + }; + + scale.paddingInner = function(_) { + if (arguments.length) { + paddingInner = Math.max(0, Math.min(1, _)); + return rescale(); + } else { + return paddingInner; + } + }; + + scale.paddingOuter = function(_) { + if (arguments.length) { + paddingOuter = Math.max(0, Math.min(1, _)); + return rescale(); + } else { + return paddingOuter; + } + }; + + scale.align = function(_) { + if (arguments.length) { + align = Math.max(0, Math.min(1, _)); + return rescale(); + } else { + return align; + } + }; + + scale.invertRange = function(_) { + // bail if range has null or undefined values + if (_[0] == null || _[1] == null) return; + + var lo = +_[0], + hi = +_[1], + reverse = range[1] < range[0], + values = reverse ? ordinalRange().reverse() : ordinalRange(), + n = values.length - 1, a, b, t; + + // bail if either range endpoint is invalid + if (lo !== lo || hi !== hi) return; + + // order range inputs, bail if outside of scale range + if (hi < lo) { + t = lo; + lo = hi; + hi = t; + } + if (hi < values[0] || lo > range[1-reverse]) return; + + // binary search to index into scale range + a = Math.max(0, bisectRight(values, lo) - 1); + b = lo===hi ? a : bisectRight(values, hi) - 1; + + // increment index a if lo is within padding gap + if (lo - values[a] > bandwidth + 1e-10) ++a; + + if (reverse) { + // map + swap + t = a; + a = n - b; + b = n - t; + } + return (a > b) ? undefined : domain().slice(a, b+1); + }; + + scale.invert = function(_) { + var value = scale.invertRange([_, _]); + return value ? value[0] : value; + }; + + scale.copy = function() { + return band$$1() + .domain(domain()) + .range(range) + .round(round) + .paddingInner(paddingInner) + .paddingOuter(paddingOuter) + .align(align); + }; + + return rescale(); +} + +function pointish(scale) { + var copy = scale.copy; + + scale.padding = scale.paddingOuter; + delete scale.paddingInner; + + scale.copy = function() { + return pointish(copy()); + }; + + return scale; +} + +function point$5() { + return pointish(band$$1().paddingInner(1)); +} + +var map$4 = Array.prototype.map; +var slice$3 = Array.prototype.slice; + +function numbers$1(_) { + return map$4.call(_, function(x) { return +x; }); +} + +function binLinear() { + var linear$$1 = linear(), + domain = []; + + function scale(x) { + return linear$$1(x); + } + + function setDomain(_) { + domain = numbers$1(_); + linear$$1.domain([domain[0], peek(domain)]); + } + + scale.domain = function(_) { + return arguments.length ? (setDomain(_), scale) : domain.slice(); + }; + + scale.range = function(_) { + return arguments.length ? (linear$$1.range(_), scale) : linear$$1.range(); + }; + + scale.rangeRound = function(_) { + return arguments.length ? (linear$$1.rangeRound(_), scale) : linear$$1.rangeRound(); + }; + + scale.interpolate = function(_) { + return arguments.length ? (linear$$1.interpolate(_), scale) : linear$$1.interpolate(); + }; + + scale.invert = function(_) { + return linear$$1.invert(_); + }; + + scale.ticks = function(count) { + var n = domain.length, + stride = ~~(n / (count || n)); + + return stride < 2 + ? scale.domain() + : domain.filter(function(x, i) { return !(i % stride); }); + }; + + scale.tickFormat = function() { + return linear$$1.tickFormat.apply(linear$$1, arguments); + }; + + scale.copy = function() { + return binLinear().domain(scale.domain()).range(scale.range()); + }; + + return scale; +} + +function binOrdinal() { + var domain = [], + range = []; + + function scale(x) { + return x == null || x !== x + ? undefined + : range[(bisectRight(domain, x) - 1) % range.length]; + } + + scale.domain = function(_) { + if (arguments.length) { + domain = numbers$1(_); + return scale; + } else { + return domain.slice(); + } + }; + + scale.range = function(_) { + if (arguments.length) { + range = slice$3.call(_); + return scale; + } else { + return range.slice(); + } + }; + + scale.copy = function() { + return binOrdinal().domain(scale.domain()).range(scale.range()); + }; + + return scale; +} + +function sequential$1(interpolator) { + var linear$$1 = linear(), + x0 = 0, + dx = 1, + clamp = false; + + function update() { + var domain = linear$$1.domain(); + x0 = domain[0]; + dx = peek(domain) - x0; + } + + function scale(x) { + var t = (x - x0) / dx; + return interpolator(clamp ? Math.max(0, Math.min(1, t)) : t); + } + + scale.clamp = function(_) { + if (arguments.length) { + clamp = !!_; + return scale; + } else { + return clamp; + } + }; + + scale.domain = function(_) { + return arguments.length ? (linear$$1.domain(_), update(), scale) : linear$$1.domain(); + }; + + scale.interpolator = function(_) { + if (arguments.length) { + interpolator = _; + return scale; + } else { + return interpolator; + } + }; + + scale.copy = function() { + return sequential$1().domain(linear$$1.domain()).clamp(clamp).interpolator(interpolator); + }; + + scale.ticks = function(count) { + return linear$$1.ticks(count); + }; + + scale.tickFormat = function(count, specifier) { + return linear$$1.tickFormat(count, specifier); + }; + + scale.nice = function(count) { + return linear$$1.nice(count), update(), scale; + }; + + return scale; +} + +/** + * Augment scales with their type and needed inverse methods. + */ +function create(type, constructor) { + return function scale() { + var s = constructor(); + + if (!s.invertRange) { + s.invertRange = s.invert ? invertRange(s) + : s.invertExtent ? invertRangeExtent(s) + : undefined; + } + + s.type = type; + return s; + }; +} + +function scale$1(type, scale) { + if (arguments.length > 1) { + scales[type] = create(type, scale); + return this; + } else { + return scales.hasOwnProperty(type) ? scales[type] : undefined; + } +} + +var scales = { + // base scale types + identity: identity$4, + linear: linear, + log: log$2, + ordinal: ordinal, + pow: pow$1, + sqrt: sqrt$1, + quantile: quantile, + quantize: quantize$2, + threshold: threshold$1, + time: time, + utc: utcTime, + + // extended scale types + band: band$$1, + point: point$5, + sequential: sequential$1, + 'bin-linear': binLinear, + 'bin-ordinal': binOrdinal +}; + +for (var key$1 in scales) { + scale$1(key$1, scales[key$1]); +} + +function colors(specifier) { + var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; + while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); + return colors; +} + +var category20 = colors( + '1f77b4aec7e8ff7f0effbb782ca02c98df8ad62728ff98969467bdc5b0d58c564bc49c94e377c2f7b6d27f7f7fc7c7c7bcbd22dbdb8d17becf9edae5' +); + +var category20b = colors( + '393b795254a36b6ecf9c9ede6379398ca252b5cf6bcedb9c8c6d31bd9e39e7ba52e7cb94843c39ad494ad6616be7969c7b4173a55194ce6dbdde9ed6' +); + +var category20c = colors( + '3182bd6baed69ecae1c6dbefe6550dfd8d3cfdae6bfdd0a231a35474c476a1d99bc7e9c0756bb19e9ac8bcbddcdadaeb636363969696bdbdbdd9d9d9' +); + +var tableau10 = colors( + '4c78a8f58518e4575672b7b254a24beeca3bb279a2ff9da69d755dbab0ac' +); + +var tableau20 = colors( + '4c78a89ecae9f58518ffbf7954a24b88d27ab79a20f2cf5b43989483bcb6e45756ff9d9879706ebab0acd67195fcbfd2b279a2d6a5c99e765fd8b5a5' +); + +var blueOrange = new Array(3).concat( + "67a9cff7f7f7f1a340", + "0571b092c5defdb863e66101", + "0571b092c5def7f7f7fdb863e66101", + "2166ac67a9cfd1e5f0fee0b6f1a340b35806", + "2166ac67a9cfd1e5f0f7f7f7fee0b6f1a340b35806", + "2166ac4393c392c5ded1e5f0fee0b6fdb863e08214b35806", + "2166ac4393c392c5ded1e5f0f7f7f7fee0b6fdb863e08214b35806", + "0530612166ac4393c392c5ded1e5f0fee0b6fdb863e08214b358067f3b08", + "0530612166ac4393c392c5ded1e5f0f7f7f7fee0b6fdb863e08214b358067f3b08" +).map(colors); + +var colors$1 = function(specifier) { + var n = specifier.length / 6 | 0, colors = new Array(n), i = 0; + while (i < n) colors[i] = "#" + specifier.slice(i * 6, ++i * 6); + return colors; +}; + +var category10 = colors$1("1f77b4ff7f0e2ca02cd627289467bd8c564be377c27f7f7fbcbd2217becf"); + +var Accent = colors$1("7fc97fbeaed4fdc086ffff99386cb0f0027fbf5b17666666"); + +var Dark2 = colors$1("1b9e77d95f027570b3e7298a66a61ee6ab02a6761d666666"); + +var Paired = colors$1("a6cee31f78b4b2df8a33a02cfb9a99e31a1cfdbf6fff7f00cab2d66a3d9affff99b15928"); + +var Pastel1 = colors$1("fbb4aeb3cde3ccebc5decbe4fed9a6ffffcce5d8bdfddaecf2f2f2"); + +var Pastel2 = colors$1("b3e2cdfdcdaccbd5e8f4cae4e6f5c9fff2aef1e2cccccccc"); + +var Set1 = colors$1("e41a1c377eb84daf4a984ea3ff7f00ffff33a65628f781bf999999"); + +var Set2 = colors$1("66c2a5fc8d628da0cbe78ac3a6d854ffd92fe5c494b3b3b3"); + +var Set3 = colors$1("8dd3c7ffffb3bebadafb807280b1d3fdb462b3de69fccde5d9d9d9bc80bdccebc5ffed6f"); + +var ramp = function(scheme) { + return rgbBasis(scheme[scheme.length - 1]); +}; + +var scheme = new Array(3).concat( + "d8b365f5f5f55ab4ac", + "a6611adfc27d80cdc1018571", + "a6611adfc27df5f5f580cdc1018571", + "8c510ad8b365f6e8c3c7eae55ab4ac01665e", + "8c510ad8b365f6e8c3f5f5f5c7eae55ab4ac01665e", + "8c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e", + "8c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e", + "5430058c510abf812ddfc27df6e8c3c7eae580cdc135978f01665e003c30", + "5430058c510abf812ddfc27df6e8c3f5f5f5c7eae580cdc135978f01665e003c30" +).map(colors$1); + +var BrBG = ramp(scheme); + +var scheme$1 = new Array(3).concat( + "af8dc3f7f7f77fbf7b", + "7b3294c2a5cfa6dba0008837", + "7b3294c2a5cff7f7f7a6dba0008837", + "762a83af8dc3e7d4e8d9f0d37fbf7b1b7837", + "762a83af8dc3e7d4e8f7f7f7d9f0d37fbf7b1b7837", + "762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b7837", + "762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b7837", + "40004b762a839970abc2a5cfe7d4e8d9f0d3a6dba05aae611b783700441b", + "40004b762a839970abc2a5cfe7d4e8f7f7f7d9f0d3a6dba05aae611b783700441b" +).map(colors$1); + +var PRGn = ramp(scheme$1); + +var scheme$2 = new Array(3).concat( + "e9a3c9f7f7f7a1d76a", + "d01c8bf1b6dab8e1864dac26", + "d01c8bf1b6daf7f7f7b8e1864dac26", + "c51b7de9a3c9fde0efe6f5d0a1d76a4d9221", + "c51b7de9a3c9fde0eff7f7f7e6f5d0a1d76a4d9221", + "c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221", + "c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221", + "8e0152c51b7dde77aef1b6dafde0efe6f5d0b8e1867fbc414d9221276419", + "8e0152c51b7dde77aef1b6dafde0eff7f7f7e6f5d0b8e1867fbc414d9221276419" +).map(colors$1); + +var PiYG = ramp(scheme$2); + +var scheme$3 = new Array(3).concat( + "998ec3f7f7f7f1a340", + "5e3c99b2abd2fdb863e66101", + "5e3c99b2abd2f7f7f7fdb863e66101", + "542788998ec3d8daebfee0b6f1a340b35806", + "542788998ec3d8daebf7f7f7fee0b6f1a340b35806", + "5427888073acb2abd2d8daebfee0b6fdb863e08214b35806", + "5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b35806", + "2d004b5427888073acb2abd2d8daebfee0b6fdb863e08214b358067f3b08", + "2d004b5427888073acb2abd2d8daebf7f7f7fee0b6fdb863e08214b358067f3b08" +).map(colors$1); + +var PuOr = ramp(scheme$3); + +var scheme$4 = new Array(3).concat( + "ef8a62f7f7f767a9cf", + "ca0020f4a58292c5de0571b0", + "ca0020f4a582f7f7f792c5de0571b0", + "b2182bef8a62fddbc7d1e5f067a9cf2166ac", + "b2182bef8a62fddbc7f7f7f7d1e5f067a9cf2166ac", + "b2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac", + "b2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac", + "67001fb2182bd6604df4a582fddbc7d1e5f092c5de4393c32166ac053061", + "67001fb2182bd6604df4a582fddbc7f7f7f7d1e5f092c5de4393c32166ac053061" +).map(colors$1); + +var RdBu = ramp(scheme$4); + +var scheme$5 = new Array(3).concat( + "ef8a62ffffff999999", + "ca0020f4a582bababa404040", + "ca0020f4a582ffffffbababa404040", + "b2182bef8a62fddbc7e0e0e09999994d4d4d", + "b2182bef8a62fddbc7ffffffe0e0e09999994d4d4d", + "b2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d", + "b2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d", + "67001fb2182bd6604df4a582fddbc7e0e0e0bababa8787874d4d4d1a1a1a", + "67001fb2182bd6604df4a582fddbc7ffffffe0e0e0bababa8787874d4d4d1a1a1a" +).map(colors$1); + +var RdGy = ramp(scheme$5); + +var scheme$6 = new Array(3).concat( + "fc8d59ffffbf91bfdb", + "d7191cfdae61abd9e92c7bb6", + "d7191cfdae61ffffbfabd9e92c7bb6", + "d73027fc8d59fee090e0f3f891bfdb4575b4", + "d73027fc8d59fee090ffffbfe0f3f891bfdb4575b4", + "d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4", + "d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4", + "a50026d73027f46d43fdae61fee090e0f3f8abd9e974add14575b4313695", + "a50026d73027f46d43fdae61fee090ffffbfe0f3f8abd9e974add14575b4313695" +).map(colors$1); + +var RdYlBu = ramp(scheme$6); + +var scheme$7 = new Array(3).concat( + "fc8d59ffffbf91cf60", + "d7191cfdae61a6d96a1a9641", + "d7191cfdae61ffffbfa6d96a1a9641", + "d73027fc8d59fee08bd9ef8b91cf601a9850", + "d73027fc8d59fee08bffffbfd9ef8b91cf601a9850", + "d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850", + "d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850", + "a50026d73027f46d43fdae61fee08bd9ef8ba6d96a66bd631a9850006837", + "a50026d73027f46d43fdae61fee08bffffbfd9ef8ba6d96a66bd631a9850006837" +).map(colors$1); + +var RdYlGn = ramp(scheme$7); + +var scheme$8 = new Array(3).concat( + "fc8d59ffffbf99d594", + "d7191cfdae61abdda42b83ba", + "d7191cfdae61ffffbfabdda42b83ba", + "d53e4ffc8d59fee08be6f59899d5943288bd", + "d53e4ffc8d59fee08bffffbfe6f59899d5943288bd", + "d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd", + "d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd", + "9e0142d53e4ff46d43fdae61fee08be6f598abdda466c2a53288bd5e4fa2", + "9e0142d53e4ff46d43fdae61fee08bffffbfe6f598abdda466c2a53288bd5e4fa2" +).map(colors$1); + +var Spectral = ramp(scheme$8); + +var scheme$9 = new Array(3).concat( + "e5f5f999d8c92ca25f", + "edf8fbb2e2e266c2a4238b45", + "edf8fbb2e2e266c2a42ca25f006d2c", + "edf8fbccece699d8c966c2a42ca25f006d2c", + "edf8fbccece699d8c966c2a441ae76238b45005824", + "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45005824", + "f7fcfde5f5f9ccece699d8c966c2a441ae76238b45006d2c00441b" +).map(colors$1); + +var BuGn = ramp(scheme$9); + +var scheme$10 = new Array(3).concat( + "e0ecf49ebcda8856a7", + "edf8fbb3cde38c96c688419d", + "edf8fbb3cde38c96c68856a7810f7c", + "edf8fbbfd3e69ebcda8c96c68856a7810f7c", + "edf8fbbfd3e69ebcda8c96c68c6bb188419d6e016b", + "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d6e016b", + "f7fcfde0ecf4bfd3e69ebcda8c96c68c6bb188419d810f7c4d004b" +).map(colors$1); + +var BuPu = ramp(scheme$10); + +var scheme$11 = new Array(3).concat( + "e0f3dba8ddb543a2ca", + "f0f9e8bae4bc7bccc42b8cbe", + "f0f9e8bae4bc7bccc443a2ca0868ac", + "f0f9e8ccebc5a8ddb57bccc443a2ca0868ac", + "f0f9e8ccebc5a8ddb57bccc44eb3d32b8cbe08589e", + "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe08589e", + "f7fcf0e0f3dbccebc5a8ddb57bccc44eb3d32b8cbe0868ac084081" +).map(colors$1); + +var GnBu = ramp(scheme$11); + +var scheme$12 = new Array(3).concat( + "fee8c8fdbb84e34a33", + "fef0d9fdcc8afc8d59d7301f", + "fef0d9fdcc8afc8d59e34a33b30000", + "fef0d9fdd49efdbb84fc8d59e34a33b30000", + "fef0d9fdd49efdbb84fc8d59ef6548d7301f990000", + "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301f990000", + "fff7ecfee8c8fdd49efdbb84fc8d59ef6548d7301fb300007f0000" +).map(colors$1); + +var OrRd = ramp(scheme$12); + +var scheme$13 = new Array(3).concat( + "ece2f0a6bddb1c9099", + "f6eff7bdc9e167a9cf02818a", + "f6eff7bdc9e167a9cf1c9099016c59", + "f6eff7d0d1e6a6bddb67a9cf1c9099016c59", + "f6eff7d0d1e6a6bddb67a9cf3690c002818a016450", + "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016450", + "fff7fbece2f0d0d1e6a6bddb67a9cf3690c002818a016c59014636" +).map(colors$1); + +var PuBuGn = ramp(scheme$13); + +var scheme$14 = new Array(3).concat( + "ece7f2a6bddb2b8cbe", + "f1eef6bdc9e174a9cf0570b0", + "f1eef6bdc9e174a9cf2b8cbe045a8d", + "f1eef6d0d1e6a6bddb74a9cf2b8cbe045a8d", + "f1eef6d0d1e6a6bddb74a9cf3690c00570b0034e7b", + "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0034e7b", + "fff7fbece7f2d0d1e6a6bddb74a9cf3690c00570b0045a8d023858" +).map(colors$1); + +var PuBu = ramp(scheme$14); + +var scheme$15 = new Array(3).concat( + "e7e1efc994c7dd1c77", + "f1eef6d7b5d8df65b0ce1256", + "f1eef6d7b5d8df65b0dd1c77980043", + "f1eef6d4b9dac994c7df65b0dd1c77980043", + "f1eef6d4b9dac994c7df65b0e7298ace125691003f", + "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125691003f", + "f7f4f9e7e1efd4b9dac994c7df65b0e7298ace125698004367001f" +).map(colors$1); + +var PuRd = ramp(scheme$15); + +var scheme$16 = new Array(3).concat( + "fde0ddfa9fb5c51b8a", + "feebe2fbb4b9f768a1ae017e", + "feebe2fbb4b9f768a1c51b8a7a0177", + "feebe2fcc5c0fa9fb5f768a1c51b8a7a0177", + "feebe2fcc5c0fa9fb5f768a1dd3497ae017e7a0177", + "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a0177", + "fff7f3fde0ddfcc5c0fa9fb5f768a1dd3497ae017e7a017749006a" +).map(colors$1); + +var RdPu = ramp(scheme$16); + +var scheme$17 = new Array(3).concat( + "edf8b17fcdbb2c7fb8", + "ffffcca1dab441b6c4225ea8", + "ffffcca1dab441b6c42c7fb8253494", + "ffffccc7e9b47fcdbb41b6c42c7fb8253494", + "ffffccc7e9b47fcdbb41b6c41d91c0225ea80c2c84", + "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea80c2c84", + "ffffd9edf8b1c7e9b47fcdbb41b6c41d91c0225ea8253494081d58" +).map(colors$1); + +var YlGnBu = ramp(scheme$17); + +var scheme$18 = new Array(3).concat( + "f7fcb9addd8e31a354", + "ffffccc2e69978c679238443", + "ffffccc2e69978c67931a354006837", + "ffffccd9f0a3addd8e78c67931a354006837", + "ffffccd9f0a3addd8e78c67941ab5d238443005a32", + "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443005a32", + "ffffe5f7fcb9d9f0a3addd8e78c67941ab5d238443006837004529" +).map(colors$1); + +var YlGn = ramp(scheme$18); + +var scheme$19 = new Array(3).concat( + "fff7bcfec44fd95f0e", + "ffffd4fed98efe9929cc4c02", + "ffffd4fed98efe9929d95f0e993404", + "ffffd4fee391fec44ffe9929d95f0e993404", + "ffffd4fee391fec44ffe9929ec7014cc4c028c2d04", + "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c028c2d04", + "ffffe5fff7bcfee391fec44ffe9929ec7014cc4c02993404662506" +).map(colors$1); + +var YlOrBr = ramp(scheme$19); + +var scheme$20 = new Array(3).concat( + "ffeda0feb24cf03b20", + "ffffb2fecc5cfd8d3ce31a1c", + "ffffb2fecc5cfd8d3cf03b20bd0026", + "ffffb2fed976feb24cfd8d3cf03b20bd0026", + "ffffb2fed976feb24cfd8d3cfc4e2ae31a1cb10026", + "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cb10026", + "ffffccffeda0fed976feb24cfd8d3cfc4e2ae31a1cbd0026800026" +).map(colors$1); + +var YlOrRd = ramp(scheme$20); + +var scheme$21 = new Array(3).concat( + "deebf79ecae13182bd", + "eff3ffbdd7e76baed62171b5", + "eff3ffbdd7e76baed63182bd08519c", + "eff3ffc6dbef9ecae16baed63182bd08519c", + "eff3ffc6dbef9ecae16baed64292c62171b5084594", + "f7fbffdeebf7c6dbef9ecae16baed64292c62171b5084594", + "f7fbffdeebf7c6dbef9ecae16baed64292c62171b508519c08306b" +).map(colors$1); + +var Blues = ramp(scheme$21); + +var scheme$22 = new Array(3).concat( + "e5f5e0a1d99b31a354", + "edf8e9bae4b374c476238b45", + "edf8e9bae4b374c47631a354006d2c", + "edf8e9c7e9c0a1d99b74c47631a354006d2c", + "edf8e9c7e9c0a1d99b74c47641ab5d238b45005a32", + "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45005a32", + "f7fcf5e5f5e0c7e9c0a1d99b74c47641ab5d238b45006d2c00441b" +).map(colors$1); + +var Greens = ramp(scheme$22); + +var scheme$23 = new Array(3).concat( + "f0f0f0bdbdbd636363", + "f7f7f7cccccc969696525252", + "f7f7f7cccccc969696636363252525", + "f7f7f7d9d9d9bdbdbd969696636363252525", + "f7f7f7d9d9d9bdbdbd969696737373525252252525", + "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525", + "fffffff0f0f0d9d9d9bdbdbd969696737373525252252525000000" +).map(colors$1); + +var Greys = ramp(scheme$23); + +var scheme$24 = new Array(3).concat( + "efedf5bcbddc756bb1", + "f2f0f7cbc9e29e9ac86a51a3", + "f2f0f7cbc9e29e9ac8756bb154278f", + "f2f0f7dadaebbcbddc9e9ac8756bb154278f", + "f2f0f7dadaebbcbddc9e9ac8807dba6a51a34a1486", + "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a34a1486", + "fcfbfdefedf5dadaebbcbddc9e9ac8807dba6a51a354278f3f007d" +).map(colors$1); + +var Purples = ramp(scheme$24); + +var scheme$25 = new Array(3).concat( + "fee0d2fc9272de2d26", + "fee5d9fcae91fb6a4acb181d", + "fee5d9fcae91fb6a4ade2d26a50f15", + "fee5d9fcbba1fc9272fb6a4ade2d26a50f15", + "fee5d9fcbba1fc9272fb6a4aef3b2ccb181d99000d", + "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181d99000d", + "fff5f0fee0d2fcbba1fc9272fb6a4aef3b2ccb181da50f1567000d" +).map(colors$1); + +var Reds = ramp(scheme$25); + +var scheme$26 = new Array(3).concat( + "fee6cefdae6be6550d", + "feeddefdbe85fd8d3cd94701", + "feeddefdbe85fd8d3ce6550da63603", + "feeddefdd0a2fdae6bfd8d3ce6550da63603", + "feeddefdd0a2fdae6bfd8d3cf16913d948018c2d04", + "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d948018c2d04", + "fff5ebfee6cefdd0a2fdae6bfd8d3cf16913d94801a636037f2704" +).map(colors$1); + +var Oranges = ramp(scheme$26); + +var cubehelix$3 = cubehelixLong(cubehelix(300, 0.5, 0.0), cubehelix(-240, 0.5, 1.0)); + +var warm = cubehelixLong(cubehelix(-100, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); + +var cool = cubehelixLong(cubehelix(260, 0.75, 0.35), cubehelix(80, 1.50, 0.8)); + +var rainbow = cubehelix(); + +var rainbow$1 = function(t) { + if (t < 0 || t > 1) t -= Math.floor(t); + var ts = Math.abs(t - 0.5); + rainbow.h = 360 * t - 100; + rainbow.s = 1.5 - 1.5 * ts; + rainbow.l = 0.8 - 0.9 * ts; + return rainbow + ""; +}; + +function ramp$1(range) { + var n = range.length; + return function(t) { + return range[Math.max(0, Math.min(n - 1, Math.floor(t * n)))]; + }; +} + +var viridis = ramp$1(colors$1("44015444025645045745055946075a46085c460a5d460b5e470d60470e6147106347116447136548146748166848176948186a481a6c481b6d481c6e481d6f481f70482071482173482374482475482576482677482878482979472a7a472c7a472d7b472e7c472f7d46307e46327e46337f463480453581453781453882443983443a83443b84433d84433e85423f854240864241864142874144874045884046883f47883f48893e49893e4a893e4c8a3d4d8a3d4e8a3c4f8a3c508b3b518b3b528b3a538b3a548c39558c39568c38588c38598c375a8c375b8d365c8d365d8d355e8d355f8d34608d34618d33628d33638d32648e32658e31668e31678e31688e30698e306a8e2f6b8e2f6c8e2e6d8e2e6e8e2e6f8e2d708e2d718e2c718e2c728e2c738e2b748e2b758e2a768e2a778e2a788e29798e297a8e297b8e287c8e287d8e277e8e277f8e27808e26818e26828e26828e25838e25848e25858e24868e24878e23888e23898e238a8d228b8d228c8d228d8d218e8d218f8d21908d21918c20928c20928c20938c1f948c1f958b1f968b1f978b1f988b1f998a1f9a8a1e9b8a1e9c891e9d891f9e891f9f881fa0881fa1881fa1871fa28720a38620a48621a58521a68522a78522a88423a98324aa8325ab8225ac8226ad8127ad8128ae8029af7f2ab07f2cb17e2db27d2eb37c2fb47c31b57b32b67a34b67935b77937b87838b9773aba763bbb753dbc743fbc7340bd7242be7144bf7046c06f48c16e4ac16d4cc26c4ec36b50c46a52c56954c56856c66758c7655ac8645cc8635ec96260ca6063cb5f65cb5e67cc5c69cd5b6ccd5a6ece5870cf5773d05675d05477d1537ad1517cd2507fd34e81d34d84d44b86d54989d5488bd6468ed64590d74393d74195d84098d83e9bd93c9dd93ba0da39a2da37a5db36a8db34aadc32addc30b0dd2fb2dd2db5de2bb8de29bade28bddf26c0df25c2df23c5e021c8e020cae11fcde11dd0e11cd2e21bd5e21ad8e219dae319dde318dfe318e2e418e5e419e7e419eae51aece51befe51cf1e51df4e61ef6e620f8e621fbe723fde725")); + +var magma = ramp$1(colors$1("00000401000501010601010802010902020b02020d03030f03031204041405041606051806051a07061c08071e0907200a08220b09240c09260d0a290e0b2b100b2d110c2f120d31130d34140e36150e38160f3b180f3d19103f1a10421c10441d11471e114920114b21114e22115024125325125527125829115a2a115c2c115f2d11612f116331116533106734106936106b38106c390f6e3b0f703d0f713f0f72400f74420f75440f764510774710784910784a10794c117a4e117b4f127b51127c52137c54137d56147d57157e59157e5a167e5c167f5d177f5f187f601880621980641a80651a80671b80681c816a1c816b1d816d1d816e1e81701f81721f817320817521817621817822817922827b23827c23827e24828025828125818326818426818627818827818928818b29818c29818e2a81902a81912b81932b80942c80962c80982d80992d809b2e7f9c2e7f9e2f7fa02f7fa1307ea3307ea5317ea6317da8327daa337dab337cad347cae347bb0357bb2357bb3367ab5367ab73779b83779ba3878bc3978bd3977bf3a77c03a76c23b75c43c75c53c74c73d73c83e73ca3e72cc3f71cd4071cf4070d0416fd2426fd3436ed5446dd6456cd8456cd9466bdb476adc4869de4968df4a68e04c67e24d66e34e65e44f64e55064e75263e85362e95462ea5661eb5760ec5860ed5a5fee5b5eef5d5ef05f5ef1605df2625df2645cf3655cf4675cf4695cf56b5cf66c5cf66e5cf7705cf7725cf8745cf8765cf9785df9795df97b5dfa7d5efa7f5efa815ffb835ffb8560fb8761fc8961fc8a62fc8c63fc8e64fc9065fd9266fd9467fd9668fd9869fd9a6afd9b6bfe9d6cfe9f6dfea16efea36ffea571fea772fea973feaa74feac76feae77feb078feb27afeb47bfeb67cfeb77efeb97ffebb81febd82febf84fec185fec287fec488fec68afec88cfeca8dfecc8ffecd90fecf92fed194fed395fed597fed799fed89afdda9cfddc9efddea0fde0a1fde2a3fde3a5fde5a7fde7a9fde9aafdebacfcecaefceeb0fcf0b2fcf2b4fcf4b6fcf6b8fcf7b9fcf9bbfcfbbdfcfdbf")); + +var inferno = ramp$1(colors$1("00000401000501010601010802010a02020c02020e03021004031204031405041706041907051b08051d09061f0a07220b07240c08260d08290e092b10092d110a30120a32140b34150b37160b39180c3c190c3e1b0c411c0c431e0c451f0c48210c4a230c4c240c4f260c51280b53290b552b0b572d0b592f0a5b310a5c320a5e340a5f3609613809623909633b09643d09653e0966400a67420a68440a68450a69470b6a490b6a4a0c6b4c0c6b4d0d6c4f0d6c510e6c520e6d540f6d550f6d57106e59106e5a116e5c126e5d126e5f136e61136e62146e64156e65156e67166e69166e6a176e6c186e6d186e6f196e71196e721a6e741a6e751b6e771c6d781c6d7a1d6d7c1d6d7d1e6d7f1e6c801f6c82206c84206b85216b87216b88226a8a226a8c23698d23698f24699025689225689326679526679727669827669a28659b29649d29649f2a63a02a63a22b62a32c61a52c60a62d60a82e5fa92e5eab2f5ead305dae305cb0315bb1325ab3325ab43359b63458b73557b93556ba3655bc3754bd3853bf3952c03a51c13a50c33b4fc43c4ec63d4dc73e4cc83f4bca404acb4149cc4248ce4347cf4446d04545d24644d34743d44842d54a41d74b3fd84c3ed94d3dda4e3cdb503bdd513ade5238df5337e05536e15635e25734e35933e45a31e55c30e65d2fe75e2ee8602de9612bea632aeb6429eb6628ec6726ed6925ee6a24ef6c23ef6e21f06f20f1711ff1731df2741cf3761bf37819f47918f57b17f57d15f67e14f68013f78212f78410f8850ff8870ef8890cf98b0bf98c0af98e09fa9008fa9207fa9407fb9606fb9706fb9906fb9b06fb9d07fc9f07fca108fca309fca50afca60cfca80dfcaa0ffcac11fcae12fcb014fcb216fcb418fbb61afbb81dfbba1ffbbc21fbbe23fac026fac228fac42afac62df9c72ff9c932f9cb35f8cd37f8cf3af7d13df7d340f6d543f6d746f5d949f5db4cf4dd4ff4df53f4e156f3e35af3e55df2e661f2e865f2ea69f1ec6df1ed71f1ef75f1f179f2f27df2f482f3f586f3f68af4f88ef5f992f6fa96f8fb9af9fc9dfafda1fcffa4")); + +var plasma = ramp$1(colors$1("0d088710078813078916078a19068c1b068d1d068e20068f2206902406912605912805922a05932c05942e05952f059631059733059735049837049938049a3a049a3c049b3e049c3f049c41049d43039e44039e46039f48039f4903a04b03a14c02a14e02a25002a25102a35302a35502a45601a45801a45901a55b01a55c01a65e01a66001a66100a76300a76400a76600a76700a86900a86a00a86c00a86e00a86f00a87100a87201a87401a87501a87701a87801a87a02a87b02a87d03a87e03a88004a88104a78305a78405a78606a68707a68808a68a09a58b0aa58d0ba58e0ca48f0da4910ea3920fa39410a29511a19613a19814a099159f9a169f9c179e9d189d9e199da01a9ca11b9ba21d9aa31e9aa51f99a62098a72197a82296aa2395ab2494ac2694ad2793ae2892b02991b12a90b22b8fb32c8eb42e8db52f8cb6308bb7318ab83289ba3388bb3488bc3587bd3786be3885bf3984c03a83c13b82c23c81c33d80c43e7fc5407ec6417dc7427cc8437bc9447aca457acb4679cc4778cc4977cd4a76ce4b75cf4c74d04d73d14e72d24f71d35171d45270d5536fd5546ed6556dd7566cd8576bd9586ada5a6ada5b69db5c68dc5d67dd5e66de5f65de6164df6263e06363e16462e26561e26660e3685fe4695ee56a5de56b5de66c5ce76e5be76f5ae87059e97158e97257ea7457eb7556eb7655ec7754ed7953ed7a52ee7b51ef7c51ef7e50f07f4ff0804ef1814df1834cf2844bf3854bf3874af48849f48948f58b47f58c46f68d45f68f44f79044f79143f79342f89441f89540f9973ff9983ef99a3efa9b3dfa9c3cfa9e3bfb9f3afba139fba238fca338fca537fca636fca835fca934fdab33fdac33fdae32fdaf31fdb130fdb22ffdb42ffdb52efeb72dfeb82cfeba2cfebb2bfebd2afebe2afec029fdc229fdc328fdc527fdc627fdc827fdca26fdcb26fccd25fcce25fcd025fcd225fbd324fbd524fbd724fad824fada24f9dc24f9dd25f8df25f8e125f7e225f7e425f6e626f6e826f5e926f5eb27f4ed27f3ee27f3f027f2f227f1f426f1f525f0f724f0f921")); + + + +var _ = Object.freeze({ + schemeCategory10: category10, + schemeAccent: Accent, + schemeDark2: Dark2, + schemePaired: Paired, + schemePastel1: Pastel1, + schemePastel2: Pastel2, + schemeSet1: Set1, + schemeSet2: Set2, + schemeSet3: Set3, + interpolateBrBG: BrBG, + schemeBrBG: scheme, + interpolatePRGn: PRGn, + schemePRGn: scheme$1, + interpolatePiYG: PiYG, + schemePiYG: scheme$2, + interpolatePuOr: PuOr, + schemePuOr: scheme$3, + interpolateRdBu: RdBu, + schemeRdBu: scheme$4, + interpolateRdGy: RdGy, + schemeRdGy: scheme$5, + interpolateRdYlBu: RdYlBu, + schemeRdYlBu: scheme$6, + interpolateRdYlGn: RdYlGn, + schemeRdYlGn: scheme$7, + interpolateSpectral: Spectral, + schemeSpectral: scheme$8, + interpolateBuGn: BuGn, + schemeBuGn: scheme$9, + interpolateBuPu: BuPu, + schemeBuPu: scheme$10, + interpolateGnBu: GnBu, + schemeGnBu: scheme$11, + interpolateOrRd: OrRd, + schemeOrRd: scheme$12, + interpolatePuBuGn: PuBuGn, + schemePuBuGn: scheme$13, + interpolatePuBu: PuBu, + schemePuBu: scheme$14, + interpolatePuRd: PuRd, + schemePuRd: scheme$15, + interpolateRdPu: RdPu, + schemeRdPu: scheme$16, + interpolateYlGnBu: YlGnBu, + schemeYlGnBu: scheme$17, + interpolateYlGn: YlGn, + schemeYlGn: scheme$18, + interpolateYlOrBr: YlOrBr, + schemeYlOrBr: scheme$19, + interpolateYlOrRd: YlOrRd, + schemeYlOrRd: scheme$20, + interpolateBlues: Blues, + schemeBlues: scheme$21, + interpolateGreens: Greens, + schemeGreens: scheme$22, + interpolateGreys: Greys, + schemeGreys: scheme$23, + interpolatePurples: Purples, + schemePurples: scheme$24, + interpolateReds: Reds, + schemeReds: scheme$25, + interpolateOranges: Oranges, + schemeOranges: scheme$26, + interpolateCubehelixDefault: cubehelix$3, + interpolateRainbow: rainbow$1, + interpolateWarm: warm, + interpolateCool: cool, + interpolateViridis: viridis, + interpolateMagma: magma, + interpolateInferno: inferno, + interpolatePlasma: plasma +}); + +var discrete = { + blueorange: blueOrange +}; + +var schemes = { + // d3 categorical palettes + category10: category10, + accent: Accent, + dark2: Dark2, + paired: Paired, + pastel1: Pastel1, + pastel2: Pastel2, + set1: Set1, + set2: Set2, + set3: Set3, + + // additional categorical palettes + category20: category20, + category20b: category20b, + category20c: category20c, + tableau10: tableau10, + tableau20: tableau20, + + // sequential multi-hue interpolators + viridis: viridis, + magma: magma, + inferno: inferno, + plasma: plasma, + + // extended interpolators + blueorange: rgbBasis(peek(blueOrange)) +}; + +function add$2(name, suffix) { + schemes[name] = _['interpolate' + suffix]; + discrete[name] = _['scheme' + suffix]; +} + +// sequential single-hue +add$2('blues', 'Blues'); +add$2('greens', 'Greens'); +add$2('greys', 'Greys'); +add$2('purples', 'Purples'); +add$2('reds', 'Reds'); +add$2('oranges', 'Oranges'); + +// diverging +add$2('brownbluegreen', 'BrBG'); +add$2('purplegreen', 'PRGn'); +add$2('pinkyellowgreen', 'PiYG'); +add$2('purpleorange', 'PuOr'); +add$2('redblue', 'RdBu'); +add$2('redgrey', 'RdGy'); +add$2('redyellowblue', 'RdYlBu'); +add$2('redyellowgreen', 'RdYlGn'); +add$2('spectral', 'Spectral'); + +// sequential multi-hue +add$2('bluegreen', 'BuGn'); +add$2('bluepurple', 'BuPu'); +add$2('greenblue', 'GnBu'); +add$2('orangered', 'OrRd'); +add$2('purplebluegreen', 'PuBuGn'); +add$2('purpleblue', 'PuBu'); +add$2('purplered', 'PuRd'); +add$2('redpurple', 'RdPu'); +add$2('yellowgreenblue', 'YlGnBu'); +add$2('yellowgreen', 'YlGn'); +add$2('yelloworangebrown', 'YlOrBr'); +add$2('yelloworangered', 'YlOrRd'); + +var getScheme = function(name, scheme$$1) { + if (arguments.length > 1) { + schemes[name] = scheme$$1; + return this; + } + + var part = name.split('-'); + name = part[0]; + part = +part[1] + 1; + + return part && discrete.hasOwnProperty(name) ? discrete[name][part-1] + : !part && schemes.hasOwnProperty(name) ? schemes[name] + : undefined; +}; + +function interpolateRange(interpolator, range) { + var start = range[0], + span = peek(range) - start; + return function(i) { return interpolator(start + i * span); }; +} + +function scaleFraction(scale, min, max) { + var delta = max - min; + return !delta ? constant(0) + : scale.type === 'linear' || scale.type === 'sequential' + ? function(_) { return (_ - min) / delta; } + : scale.copy().domain([min, max]).range([0, 1]).interpolate(lerp); +} + +function lerp(a, b) { + var span = b - a; + return function(i) { return a + i * span; } +} + +function interpolate$1(type, gamma) { + var interp = $$1[method(type)]; + return (gamma != null && interp && interp.gamma) + ? interp.gamma(gamma) + : interp; +} + +function method(type) { + return 'interpolate' + type.toLowerCase() + .split('-') + .map(function(s) { return s[0].toUpperCase() + s.slice(1); }) + .join(''); +} + +var time$1 = { + millisecond: millisecond, + second: second, + minute: minute, + hour: hour, + day: day, + week: sunday, + month: month, + year: year +}; + +var utc = { + millisecond: millisecond, + second: second, + minute: utcMinute, + hour: utcHour, + day: utcDay, + week: utcSunday, + month: utcMonth, + year: utcYear +}; + +function timeInterval(name) { + return time$1.hasOwnProperty(name) && time$1[name]; +} + +function utcInterval(name) { + return utc.hasOwnProperty(name) && utc[name]; +} + +/** + * Determine the tick count or interval function. + * @param {Scale} scale - The scale for which to generate tick values. + * @param {*} count - The desired tick count or interval specifier. + * @return {*} - The tick count or interval function. + */ +function tickCount(scale$$1, count) { + var step; + + if (isObject(count)) { + step = count.step; + count = count.interval; + } + + if (isString(count)) { + count = scale$$1.type === 'time' ? timeInterval(count) + : scale$$1.type === 'utc' ? utcInterval(count) + : error$1('Only time and utc scales accept interval strings.'); + if (step) count = count.every(step); + } + + return count; +} + +/** + * Filter a set of candidate tick values, ensuring that only tick values + * that lie within the scale range are included. + * @param {Scale} scale - The scale for which to generate tick values. + * @param {Array<*>} ticks - The candidate tick values. + * @param {*} count - The tick count or interval function. + * @return {Array<*>} - The filtered tick values. + */ +function validTicks(scale$$1, ticks, count) { + var range = scale$$1.range(), + lo = range[0], + hi = peek(range); + if (lo > hi) { + range = hi; + hi = lo; + lo = range; + } + + ticks = ticks.filter(function(v) { + v = scale$$1(v); + return !(v < lo || v > hi) + }); + + if (count > 0 && ticks.length > 1) { + var endpoints = [ticks[0], peek(ticks)]; + while (ticks.length > count && ticks.length >= 3) { + ticks = ticks.filter(function(_, i) { return !(i % 2); }); + } + if (ticks.length < 3) { + ticks = endpoints; + } + } + + return ticks; +} + +/** + * Generate tick values for the given scale and approximate tick count or + * interval value. If the scale has a 'ticks' method, it will be used to + * generate the ticks, with the count argument passed as a parameter. If the + * scale lacks a 'ticks' method, the full scale domain will be returned. + * @param {Scale} scale - The scale for which to generate tick values. + * @param {*} [count] - The approximate number of desired ticks. + * @return {Array<*>} - The generated tick values. + */ +function tickValues(scale$$1, count) { + return scale$$1.ticks ? scale$$1.ticks(count) : scale$$1.domain(); +} + +/** + * Generate a label format function for a scale. If the scale has a + * 'tickFormat' method, it will be used to generate the formatter, with the + * count and specifier arguments passed as parameters. If the scale lacks a + * 'tickFormat' method, the returned formatter performs simple string coercion. + * If the input scale is a logarithmic scale and the format specifier does not + * indicate a desired decimal precision, a special variable precision formatter + * that automatically trims trailing zeroes will be generated. + * @param {Scale} scale - The scale for which to generate the label formatter. + * @param {*} [count] - The approximate number of desired ticks. + * @param {string} [specifier] - The format specifier. Must be a legal d3 4.0 + * specifier string (see https://github.com/d3/d3-format#formatSpecifier). + * @return {function(*):string} - The generated label formatter. + */ +function tickFormat(scale$$1, count, specifier) { + var format$$1 = scale$$1.tickFormat + ? scale$$1.tickFormat(count, specifier) + : String; + + return (scale$$1.type === Log) + ? filter$1(format$$1, variablePrecision(specifier)) + : format$$1; +} + +function filter$1(sourceFormat, targetFormat) { + return function(_) { + return sourceFormat(_) ? targetFormat(_) : ''; + }; +} + +function variablePrecision(specifier) { + var s = formatSpecifier(specifier || ','); + + if (s.precision == null) { + s.precision = 12; + switch (s.type) { + case '%': s.precision -= 2; break; + case 'e': s.precision -= 1; break; + } + return trimZeroes( + format(s), // number format + format('.1f')(1)[1] // decimal point character + ); + } else { + return format(s); + } +} + +function trimZeroes(format$$1, decimalChar) { + return function(x) { + var str = format$$1(x), + dec = str.indexOf(decimalChar), + idx, end; + + if (dec < 0) return str; + + idx = rightmostDigit(str, dec); + end = idx < str.length ? str.slice(idx) : ''; + while (--idx > dec) if (str[idx] !== '0') { ++idx; break; } + + return str.slice(0, idx) + end; + }; +} + +function rightmostDigit(str, dec) { + var i = str.lastIndexOf('e'), c; + if (i > 0) return i; + for (i=str.length; --i > dec;) { + c = str.charCodeAt(i); + if (c >= 48 && c <= 57) return i + 1; // is digit + } +} + +/** + * Generates axis ticks for visualizing a spatial scale. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Scale} params.scale - The scale to generate ticks for. + * @param {*} [params.count=10] - The approximate number of ticks, or + * desired tick interval, to use. + * @param {Array<*>} [params.values] - The exact tick values to use. + * These must be legal domain values for the provided scale. + * If provided, the count argument is ignored. + * @param {function(*):string} [params.formatSpecifier] - A format specifier + * to use in conjunction with scale.tickFormat. Legal values are + * any valid d3 4.0 format specifier. + * @param {function(*):string} [params.format] - The format function to use. + * If provided, the formatSpecifier argument is ignored. + */ +function AxisTicks(params) { + Transform.call(this, null, params); +} + +var prototype$54 = inherits(AxisTicks, Transform); + +prototype$54.transform = function(_, pulse) { + if (this.value && !_.modified()) { + return pulse.StopPropagation; + } + + var out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS), + ticks = this.value, + scale = _.scale, + count = _.count == null ? (_.values ? _.values.length : 10) : tickCount(scale, _.count), + format = _.format || tickFormat(scale, count, _.formatSpecifier), + values = _.values ? validTicks(scale, _.values, count) : tickValues(scale, count); + + if (ticks) out.rem = ticks; + + ticks = values.map(function(value, i) { + return ingest({ + index: i / (values.length - 1), + value: value, + label: format(value) + }); + }); + + if (_.extra) { + // add an extra tick pegged to the initial domain value + // this is used to generate axes with 'binned' domains + ticks.push(ingest({ + index: -1, + extra: {value: ticks[0].value}, + label: '' + })); + } + + out.source = ticks; + out.add = ticks; + this.value = ticks; + + return out; +}; + +/** + * Joins a set of data elements against a set of visual items. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): object} [params.item] - An item generator function. + * @param {function(object): *} [params.key] - The key field associating data and visual items. + */ +function DataJoin(params) { + Transform.call(this, null, params); +} + +var prototype$55 = inherits(DataJoin, Transform); + +function defaultItemCreate() { + return ingest({}); +} + +function isExit(t) { + return t.exit; +} + +prototype$55.transform = function(_, pulse) { + var df = pulse.dataflow, + out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS), + item = _.item || defaultItemCreate, + key$$1 = _.key || tupleid, + map = this.value; + + // prevent transient (e.g., hover) requests from + // cascading across marks derived from marks + if (isArray(out.encode)) { + out.encode = null; + } + + if (map && (_.modified('key') || pulse.modified(key$$1))) { + error$1('DataJoin does not support modified key function or fields.'); + } + + if (!map) { + pulse = pulse.addAll(); + this.value = map = fastmap().test(isExit); + map.lookup = function(t) { return map.get(key$$1(t)); }; + } + + pulse.visit(pulse.ADD, function(t) { + var k = key$$1(t), + x = map.get(k); + + if (x) { + if (x.exit) { + map.empty--; + out.add.push(x); + } else { + out.mod.push(x); + } + } else { + map.set(k, (x = item(t))); + out.add.push(x); + } + + x.datum = t; + x.exit = false; + }); + + pulse.visit(pulse.MOD, function(t) { + var k = key$$1(t), + x = map.get(k); + + if (x) { + x.datum = t; + out.mod.push(x); + } + }); + + pulse.visit(pulse.REM, function(t) { + var k = key$$1(t), + x = map.get(k); + + if (t === x.datum && !x.exit) { + out.rem.push(x); + x.exit = true; + ++map.empty; + } + }); + + if (pulse.changed(pulse.ADD_MOD)) out.modifies('datum'); + + if (_.clean && map.empty > df.cleanThreshold) df.runAfter(map.clean); + + return out; +}; + +/** + * Invokes encoding functions for visual items. + * @constructor + * @param {object} params - The parameters to the encoding functions. This + * parameter object will be passed through to all invoked encoding functions. + * @param {object} param.encoders - The encoding functions + * @param {function(object, object): boolean} [param.encoders.update] - Update encoding set + * @param {function(object, object): boolean} [param.encoders.enter] - Enter encoding set + * @param {function(object, object): boolean} [param.encoders.exit] - Exit encoding set + */ +function Encode(params) { + Transform.call(this, null, params); +} + +var prototype$56 = inherits(Encode, Transform); + +prototype$56.transform = function(_, pulse) { + var out = pulse.fork(pulse.ADD_REM), + encoders = _.encoders, + encode = pulse.encode; + + // if an array, the encode directive includes additional sets + // that must be defined in order for the primary set to be invoked + // e.g., only run the update set if the hover set is defined + if (isArray(encode)) { + if (out.changed() || encode.every(function(e) { return encoders[e]; })) { + encode = encode[0]; + } else { + return pulse.StopPropagation; + } + } + + // marshall encoder functions + var reenter = encode === 'enter', + update = encoders.update || falsy, + enter = encoders.enter || falsy, + exit = encoders.exit || falsy, + set = (encode && !reenter ? encoders[encode] : update) || falsy; + + if (pulse.changed(pulse.ADD)) { + pulse.visit(pulse.ADD, function(t) { + enter(t, _); + update(t, _); + if (set !== falsy && set !== update) set(t, _); + }); + out.modifies(enter.output); + out.modifies(update.output); + if (set !== falsy && set !== update) out.modifies(set.output); + } + + if (pulse.changed(pulse.REM) && exit !== falsy) { + pulse.visit(pulse.REM, function(t) { exit(t, _); }); + out.modifies(exit.output); + } + + if (reenter || set !== falsy) { + var flag = pulse.MOD | (_.modified() ? pulse.REFLOW : 0); + if (reenter) { + pulse.visit(flag, function(t) { + var mod = enter(t, _); + if (set(t, _) || mod) out.mod.push(t); + }); + if (out.mod.length) out.modifies(enter.output); + } else { + pulse.visit(flag, function(t) { + if (set(t, _)) out.mod.push(t); + }); + } + if (out.mod.length) out.modifies(set.output); + } + + return out.changed() ? out : pulse.StopPropagation; +}; + +var discrete$1 = {}; +discrete$1[Quantile] = quantile$1; +discrete$1[Quantize] = quantize$3; +discrete$1[Threshold] = threshold$2; +discrete$1[BinLinear] = bin$1; +discrete$1[BinOrdinal] = bin$1; + +function labelValues(scale, count, gradient) { + if (gradient) return scale.domain(); + var values = discrete$1[scale.type]; + return values ? values(scale) : tickValues(scale, count); +} + +function quantize$3(scale) { + var domain = scale.domain(), + x0 = domain[0], + x1 = peek(domain), + n = scale.range().length, + values = new Array(n), + i = 0; + + values[0] = -Infinity; + while (++i < n) values[i] = (i * x1 - (i - n) * x0) / n; + values.max = +Infinity; + + return values; +} + +function quantile$1(scale) { + var values = [-Infinity].concat(scale.quantiles()); + values.max = +Infinity; + + return values; +} + +function threshold$2(scale) { + var values = [-Infinity].concat(scale.domain()); + values.max = +Infinity; + + return values; +} + +function bin$1(scale) { + var values = scale.domain(); + values.max = values.pop(); + + return values; +} + +function labelFormat(scale, format) { + return discrete$1[scale.type] ? formatRange(format) : formatPoint(format); +} + +function formatRange(format) { + return function(value, index, array$$1) { + var limit = array$$1[index + 1] || array$$1.max || +Infinity, + lo = formatValue(value, format), + hi = formatValue(limit, format); + return lo && hi ? lo + '\u2013' + hi : hi ? '< ' + hi : '\u2265 ' + lo; + }; +} + +function formatValue(value, format) { + return isFinite(value) ? format(value) : null; +} + +function formatPoint(format) { + return function(value) { + return format(value); + }; +} + +/** + * Generates legend entries for visualizing a scale. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Scale} params.scale - The scale to generate items for. + * @param {*} [params.count=10] - The approximate number of items, or + * desired tick interval, to use. + * @param {Array<*>} [params.values] - The exact tick values to use. + * These must be legal domain values for the provided scale. + * If provided, the count argument is ignored. + * @param {function(*):string} [params.formatSpecifier] - A format specifier + * to use in conjunction with scale.tickFormat. Legal values are + * any valid d3 4.0 format specifier. + * @param {function(*):string} [params.format] - The format function to use. + * If provided, the formatSpecifier argument is ignored. + */ +function LegendEntries(params) { + Transform.call(this, [], params); +} + +var prototype$57 = inherits(LegendEntries, Transform); + +prototype$57.transform = function(_, pulse) { + if (this.value != null && !_.modified()) { + return pulse.StopPropagation; + } + + var out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS), + total = 0, + items = this.value, + grad = _.type === 'gradient', + scale = _.scale, + count = _.count == null ? 5 : tickCount(scale, _.count), + format = _.format || tickFormat(scale, count, _.formatSpecifier), + values = _.values || labelValues(scale, count, grad); + + format = labelFormat(scale, format); + if (items) out.rem = items; + + if (grad) { + var domain = _.values ? scale.domain() : values, + fraction = scaleFraction(scale, domain[0], peek(domain)); + } else { + var size = _.size, + offset; + if (isFunction(size)) { + // if first value maps to size zero, remove from list (vega#717) + if (!_.values && scale(values[0]) === 0) { + values = values.slice(1); + } + // compute size offset for legend entries + offset = values.reduce(function(max, value) { + return Math.max(max, size(value, _)); + }, 0); + } else { + size = constant(offset = size || 8); + } + } + + items = values.map(function(value, index) { + var t = ingest({ + index: index, + label: format(value, index, values), + value: value + }); + + if (grad) { + t.perc = fraction(value); + } else { + t.offset = offset; + t.size = size(value, _); + t.total = Math.round(total); + total += t.size; + } + return t; + }); + + out.source = items; + out.add = items; + this.value = items; + + return out; +}; + +var Paths = fastmap({ + 'line': line$3, + 'line-radial': lineR, + 'arc': arc$2, + 'arc-radial': arcR, + 'curve': curve, + 'curve-radial': curveR, + 'orthogonal-horizontal': orthoX, + 'orthogonal-vertical': orthoY, + 'orthogonal-radial': orthoR, + 'diagonal-horizontal': diagonalX, + 'diagonal-vertical': diagonalY, + 'diagonal-radial': diagonalR +}); + +function sourceX(t) { return t.source.x; } +function sourceY(t) { return t.source.y; } +function targetX(t) { return t.target.x; } +function targetY(t) { return t.target.y; } + + /** + * Layout paths linking source and target elements. + * @constructor + * @param {object} params - The parameters for this operator. + */ +function LinkPath(params) { + Transform.call(this, {}, params); +} + +LinkPath.Definition = { + "type": "LinkPath", + "metadata": {"modifies": true}, + "params": [ + { "name": "sourceX", "type": "field", "default": "source.x" }, + { "name": "sourceY", "type": "field", "default": "source.y" }, + { "name": "targetX", "type": "field", "default": "target.x" }, + { "name": "targetY", "type": "field", "default": "target.y" }, + { "name": "orient", "type": "enum", "default": "vertical", + "values": ["horizontal", "vertical", "radial"] }, + { "name": "shape", "type": "enum", "default": "line", + "values": ["line", "arc", "curve", "diagonal", "orthogonal"] }, + { "name": "as", "type": "string", "default": "path" } + ] +}; + +var prototype$58 = inherits(LinkPath, Transform); + +prototype$58.transform = function(_, pulse) { + var sx = _.sourceX || sourceX, + sy = _.sourceY || sourceY, + tx = _.targetX || targetX, + ty = _.targetY || targetY, + as = _.as || 'path', + orient = _.orient || 'vertical', + shape = _.shape || 'line', + path = Paths.get(shape + '-' + orient) || Paths.get(shape); + + if (!path) { + error$1('LinkPath unsupported type: ' + _.shape + + (_.orient ? '-' + _.orient : '')); + } + + pulse.visit(pulse.SOURCE, function(t) { + t[as] = path(sx(t), sy(t), tx(t), ty(t)); + }); + + return pulse.reflow(_.modified()).modifies(as); +}; + +// -- Link Path Generation Methods ----- + +function line$3(sx, sy, tx, ty) { + return 'M' + sx + ',' + sy + + 'L' + tx + ',' + ty; +} + +function lineR(sa, sr, ta, tr) { + return line$3( + sr * Math.cos(sa), sr * Math.sin(sa), + tr * Math.cos(ta), tr * Math.sin(ta) + ); +} + +function arc$2(sx, sy, tx, ty) { + var dx = tx - sx, + dy = ty - sy, + rr = Math.sqrt(dx * dx + dy * dy) / 2, + ra = 180 * Math.atan2(dy, dx) / Math.PI; + return 'M' + sx + ',' + sy + + 'A' + rr + ',' + rr + + ' ' + ra + ' 0 1' + + ' ' + tx + ',' + ty; +} + +function arcR(sa, sr, ta, tr) { + return arc$2( + sr * Math.cos(sa), sr * Math.sin(sa), + tr * Math.cos(ta), tr * Math.sin(ta) + ); +} + +function curve(sx, sy, tx, ty) { + var dx = tx - sx, + dy = ty - sy, + ix = 0.2 * (dx + dy), + iy = 0.2 * (dy - dx); + return 'M' + sx + ',' + sy + + 'C' + (sx+ix) + ',' + (sy+iy) + + ' ' + (tx+iy) + ',' + (ty-ix) + + ' ' + tx + ',' + ty; +} + +function curveR(sa, sr, ta, tr) { + return curve( + sr * Math.cos(sa), sr * Math.sin(sa), + tr * Math.cos(ta), tr * Math.sin(ta) + ); +} + +function orthoX(sx, sy, tx, ty) { + return 'M' + sx + ',' + sy + + 'V' + ty + 'H' + tx; +} + +function orthoY(sx, sy, tx, ty) { + return 'M' + sx + ',' + sy + + 'H' + tx + 'V' + ty; +} + +function orthoR(sa, sr, ta, tr) { + var sc = Math.cos(sa), + ss = Math.sin(sa), + tc = Math.cos(ta), + ts = Math.sin(ta), + sf = Math.abs(ta - sa) > Math.PI ? ta <= sa : ta > sa; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'A' + sr + ',' + sr + ' 0 0,' + (sf?1:0) + + ' ' + (sr*tc) + ',' + (sr*ts) + + 'L' + (tr*tc) + ',' + (tr*ts); +} + +function diagonalX(sx, sy, tx, ty) { + var m = (sx + tx) / 2; + return 'M' + sx + ',' + sy + + 'C' + m + ',' + sy + + ' ' + m + ',' + ty + + ' ' + tx + ',' + ty; +} + +function diagonalY(sx, sy, tx, ty) { + var m = (sy + ty) / 2; + return 'M' + sx + ',' + sy + + 'C' + sx + ',' + m + + ' ' + tx + ',' + m + + ' ' + tx + ',' + ty; +} + +function diagonalR(sa, sr, ta, tr) { + var sc = Math.cos(sa), + ss = Math.sin(sa), + tc = Math.cos(ta), + ts = Math.sin(ta), + mr = (sr + tr) / 2; + return 'M' + (sr*sc) + ',' + (sr*ss) + + 'C' + (mr*sc) + ',' + (mr*ss) + + ' ' + (mr*tc) + ',' + (mr*ts) + + ' ' + (tr*tc) + ',' + (tr*ts); +} + +/** + * Pie and donut chart layout. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.field - The value field to size pie segments. + * @param {number} [params.startAngle=0] - The start angle (in radians) of the layout. + * @param {number} [params.endAngle=2π] - The end angle (in radians) of the layout. + * @param {boolean} [params.sort] - Boolean flag for sorting sectors by value. + */ +function Pie(params) { + Transform.call(this, null, params); +} + +Pie.Definition = { + "type": "Pie", + "metadata": {"modifies": true}, + "params": [ + { "name": "field", "type": "field" }, + { "name": "startAngle", "type": "number", "default": 0 }, + { "name": "endAngle", "type": "number", "default": 6.283185307179586 }, + { "name": "sort", "type": "boolean", "default": false }, + { "name": "as", "type": "string", "array": true, "length": 2, "default": ["startAngle", "endAngle"] } + ] +}; + +var prototype$59 = inherits(Pie, Transform); + +prototype$59.transform = function(_, pulse) { + var as = _.as || ['startAngle', 'endAngle'], + startAngle = as[0], + endAngle = as[1], + field$$1 = _.field || one, + start = _.startAngle || 0, + stop = _.endAngle != null ? _.endAngle : 2 * Math.PI, + data = pulse.source, + values = data.map(field$$1), + n = values.length, + a = start, + k = (stop - start) / sum(values), + index = sequence(n), + i, t, v; + + if (_.sort) { + index.sort(function(a, b) { + return values[a] - values[b]; + }); + } + + for (i=0; i -1) return raw; + + var domain = _.domain, + type = scale.type, + zero$$1 = _.zero || (_.zero === undefined && INCLUDE_ZERO[type]), + n, mid; + + if (!domain) return 0; + + // adjust continuous domain for minimum pixel padding + if (INCLUDE_PAD[type] && _.padding && domain[0] !== peek(domain)) { + domain = padDomain(type, domain, _.range, _.padding, _.exponent); + } + + // adjust domain based on zero, min, max settings + if (zero$$1 || _.domainMin != null || _.domainMax != null || _.domainMid != null) { + n = ((domain = domain.slice()).length - 1) || 1; + if (zero$$1) { + if (domain[0] > 0) domain[0] = 0; + if (domain[n] < 0) domain[n] = 0; + } + if (_.domainMin != null) domain[0] = _.domainMin; + if (_.domainMax != null) domain[n] = _.domainMax; + + if (_.domainMid != null) { + mid = _.domainMid; + if (mid < domain[0] || mid > domain[n]) { + df.warn('Scale domainMid exceeds domain min or max.', mid); + } + domain.splice(n, 0, mid); + } + } + + // set the scale domain + scale.domain(domain); + + // if ordinal scale domain is defined, prevent implicit + // domain construction as side-effect of scale lookup + if (type === Ordinal) { + scale.unknown(undefined); + } + + // perform 'nice' adjustment as requested + if (_.nice && scale.nice) { + scale.nice((_.nice !== true && tickCount(scale, _.nice)) || null); + } + + // return the cardinality of the domain + return domain.length; +} + +function rawDomain(scale, raw) { + if (raw) { + scale.domain(raw); + return raw.length; + } else { + return -1; + } +} + +function padDomain(type, domain, range, pad$$1, exponent) { + var span = Math.abs(peek(range) - range[0]), + frac = span / (span - 2 * pad$$1), + d = type === Log ? zoomLog(domain, null, frac) + : type === Sqrt ? zoomPow(domain, null, frac, 0.5) + : type === Pow ? zoomPow(domain, null, frac, exponent) + : zoomLinear(domain, null, frac); + + domain = domain.slice(); + domain[0] = d[0]; + domain[domain.length-1] = d[1]; + return domain; +} + +function configureRange(scale, _, count) { + var round = _.round || false, + range = _.range; + + // if range step specified, calculate full range extent + if (_.rangeStep != null) { + range = configureRangeStep(scale.type, _, count); + } + + // else if a range scheme is defined, use that + else if (_.scheme) { + range = configureScheme(scale.type, _, count); + if (isFunction(range)) return scale.interpolator(range); + } + + // given a range array for a sequential scale, convert to interpolator + else if (range && scale.type === Sequential) { + return scale.interpolator(rgbBasis(flip(range, _.reverse))); + } + + // configure rounding / interpolation + if (range && _.interpolate && scale.interpolate) { + scale.interpolate(interpolate$1(_.interpolate, _.interpolateGamma)); + } else if (isFunction(scale.round)) { + scale.round(round); + } else if (isFunction(scale.rangeRound)) { + scale.interpolate(round ? interpolateRound : interpolate); + } + + if (range) scale.range(flip(range, _.reverse)); +} + +function configureRangeStep(type, _, count) { + if (type !== Band && type !== Point) { + error$1('Only band and point scales support rangeStep.'); + } + + // calculate full range based on requested step size and padding + var outer = (_.paddingOuter != null ? _.paddingOuter : _.padding) || 0, + inner = type === Point ? 1 + : ((_.paddingInner != null ? _.paddingInner : _.padding) || 0); + return [0, _.rangeStep * bandSpace(count, inner, outer)]; +} + +function configureScheme(type, _, count) { + var name = _.scheme.toLowerCase(), + scheme = getScheme(name), + extent = _.schemeExtent, + discrete; + + if (!scheme) { + error$1('Unrecognized scheme name: ' + _.scheme); + } + + // determine size for potential discrete range + count = (type === Threshold) ? count + 1 + : (type === BinOrdinal) ? count - 1 + : (type === Quantile || type === Quantize) ? (+_.schemeCount || DEFAULT_COUNT) + : count; + + // adjust and/or quantize scheme as appropriate + return type === Sequential ? adjustScheme(scheme, extent, _.reverse) + : !extent && (discrete = getScheme(name + '-' + count)) ? discrete + : isFunction(scheme) ? quantize$4(adjustScheme(scheme, extent), count) + : type === Ordinal ? scheme : scheme.slice(0, count); +} + +function adjustScheme(scheme, extent, reverse) { + return (isFunction(scheme) && (extent || reverse)) + ? interpolateRange(scheme, flip(extent || [0, 1], reverse)) + : scheme; +} + +function flip(array$$1, reverse) { + return reverse ? array$$1.slice().reverse() : array$$1; +} + +function quantize$4(interpolator, count) { + var samples = new Array(count), + n = (count - 1) || 1; + for (var i = 0; i < count; ++i) samples[i] = interpolator(i / n); + return samples; +} + +/** + * Sorts scenegraph items in the pulse source array. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(*,*): number} [params.sort] - A comparator + * function for sorting tuples. + */ +function SortItems(params) { + Transform.call(this, null, params); +} + +var prototype$61 = inherits(SortItems, Transform); + +prototype$61.transform = function(_, pulse) { + var mod = _.modified('sort') + || pulse.changed(pulse.ADD) + || pulse.modified(_.sort.fields) + || pulse.modified('datum'); + + if (mod) pulse.source.sort(_.sort); + + this.modified(mod); + return pulse; +}; + +var Center = 'center'; +var Normalize = 'normalize'; + +/** + * Stack layout for visualization elements. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(object): *} params.field - The value field to stack. + * @param {Array} [params.groupby] - An array of accessors to groupby. + * @param {function(object,object): number} [params.sort] - A comparator for stack sorting. + * @param {string} [offset='zero'] - One of 'zero', 'center', 'normalize'. + */ +function Stack(params) { + Transform.call(this, null, params); +} + +Stack.Definition = { + "type": "Stack", + "metadata": {"modifies": true}, + "params": [ + { "name": "field", "type": "field" }, + { "name": "groupby", "type": "field", "array": true }, + { "name": "sort", "type": "compare" }, + { "name": "offset", "type": "enum", "default": "zero", "values": ["zero", "center", "normalize"] }, + { "name": "as", "type": "string", "array": true, "length": 2, "default": ["y0", "y1"] } + ] +}; + +var prototype$62 = inherits(Stack, Transform); + +prototype$62.transform = function(_, pulse) { + var as = _.as || ['y0', 'y1'], + y0 = as[0], + y1 = as[1], + field$$1 = _.field || one, + stack = _.offset === Center ? stackCenter + : _.offset === Normalize ? stackNormalize + : stackZero, + groups, i, n, max; + + // partition, sum, and sort the stack groups + groups = partition$1(pulse.source, _.groupby, _.sort, field$$1); + + // compute stack layouts per group + for (i=0, n=groups.length, max=groups.max; i max) max = s; + if (sort) g.sort(sort); + } + groups.max = max; + + return groups; +} + + + +var encode = Object.freeze({ + axisticks: AxisTicks, + datajoin: DataJoin, + encode: Encode, + legendentries: LegendEntries, + linkpath: LinkPath, + pie: Pie, + scale: Scale, + sortitems: SortItems, + stack: Stack, + validTicks: validTicks +}); + +var array$4 = Array.prototype; + +var slice$4 = array$4.slice; + +var ascending$2 = function(a, b) { + return a - b; +}; + +var area$3 = function(ring) { + var i = 0, n = ring.length, area = ring[n - 1][1] * ring[0][0] - ring[n - 1][0] * ring[0][1]; + while (++i < n) area += ring[i - 1][1] * ring[i][0] - ring[i - 1][0] * ring[i][1]; + return area; +}; + +var constant$6 = function(x) { + return function() { + return x; + }; +}; + +var contains = function(ring, hole) { + var i = -1, n = hole.length, c; + while (++i < n) if (c = ringContains(ring, hole[i])) return c; + return 0; +}; + +function ringContains(ring, point) { + var x = point[0], y = point[1], contains = -1; + for (var i = 0, n = ring.length, j = n - 1; i < n; j = i++) { + var pi = ring[i], xi = pi[0], yi = pi[1], pj = ring[j], xj = pj[0], yj = pj[1]; + if (segmentContains(pi, pj, point)) return 0; + if (((yi > y) !== (yj > y)) && ((x < (xj - xi) * (y - yi) / (yj - yi) + xi))) contains = -contains; + } + return contains; +} + +function segmentContains(a, b, c) { + var i; return collinear(a, b, c) && within(a[i = +(a[0] === b[0])], c[i], b[i]); +} + +function collinear(a, b, c) { + return (b[0] - a[0]) * (c[1] - a[1]) === (c[0] - a[0]) * (b[1] - a[1]); +} + +function within(p, q, r) { + return p <= q && q <= r || r <= q && q <= p; +} + +var noop$3 = function() {}; + +var cases = [ + [], + [[[1.0, 1.5], [0.5, 1.0]]], + [[[1.5, 1.0], [1.0, 1.5]]], + [[[1.5, 1.0], [0.5, 1.0]]], + [[[1.0, 0.5], [1.5, 1.0]]], + [[[1.0, 1.5], [0.5, 1.0]], [[1.0, 0.5], [1.5, 1.0]]], + [[[1.0, 0.5], [1.0, 1.5]]], + [[[1.0, 0.5], [0.5, 1.0]]], + [[[0.5, 1.0], [1.0, 0.5]]], + [[[1.0, 1.5], [1.0, 0.5]]], + [[[0.5, 1.0], [1.0, 0.5]], [[1.5, 1.0], [1.0, 1.5]]], + [[[1.5, 1.0], [1.0, 0.5]]], + [[[0.5, 1.0], [1.5, 1.0]]], + [[[1.0, 1.5], [1.5, 1.0]]], + [[[0.5, 1.0], [1.0, 1.5]]], + [] +]; + +var contours = function() { + var dx = 1, + dy = 1, + threshold$$1 = thresholdSturges, + smooth = smoothLinear; + + function contours(values) { + var tz = threshold$$1(values); + + // Convert number of thresholds into uniform thresholds. + if (!Array.isArray(tz)) { + var domain = extent(values), start = domain[0], stop = domain[1]; + tz = tickStep(start, stop, tz); + tz = sequence(Math.floor(start / tz) * tz, Math.floor(stop / tz) * tz, tz); + } else { + tz = tz.slice().sort(ascending$2); + } + + return tz.map(function(value) { + return contour(values, value); + }); + } + + // Accumulate, smooth contour rings, assign holes to exterior rings. + // Based on https://github.com/mbostock/shapefile/blob/v0.6.2/shp/polygon.js + function contour(values, value) { + var polygons = [], + holes = []; + + isorings(values, value, function(ring) { + smooth(ring, values, value); + if (area$3(ring) > 0) polygons.push([ring]); + else holes.push(ring); + }); + + holes.forEach(function(hole) { + for (var i = 0, n = polygons.length, polygon; i < n; ++i) { + if (contains((polygon = polygons[i])[0], hole) !== -1) { + polygon.push(hole); + return; + } + } + }); + + return { + type: "MultiPolygon", + value: value, + coordinates: polygons + }; + } + + // Marching squares with isolines stitched into rings. + // Based on https://github.com/topojson/topojson-client/blob/v3.0.0/src/stitch.js + function isorings(values, value, callback) { + var fragmentByStart = new Array, + fragmentByEnd = new Array, + x, y, t0, t1, t2, t3; + + // Special case for the first row (y = -1, t2 = t3 = 0). + x = y = -1; + t1 = values[0] >= value; + cases[t1 << 1].forEach(stitch); + while (++x < dx - 1) { + t0 = t1, t1 = values[x + 1] >= value; + cases[t0 | t1 << 1].forEach(stitch); + } + cases[t1 << 0].forEach(stitch); + + // General case for the intermediate rows. + while (++y < dy - 1) { + x = -1; + t1 = values[y * dx + dx] >= value; + t2 = values[y * dx] >= value; + cases[t1 << 1 | t2 << 2].forEach(stitch); + while (++x < dx - 1) { + t0 = t1, t1 = values[y * dx + dx + x + 1] >= value; + t3 = t2, t2 = values[y * dx + x + 1] >= value; + cases[t0 | t1 << 1 | t2 << 2 | t3 << 3].forEach(stitch); + } + cases[t1 | t2 << 3].forEach(stitch); + } + + // Special case for the last row (y = dy - 1, t0 = t1 = 0). + x = -1; + t2 = values[y * dx] >= value; + cases[t2 << 2].forEach(stitch); + while (++x < dx - 1) { + t3 = t2, t2 = values[y * dx + x + 1] >= value; + cases[t2 << 2 | t3 << 3].forEach(stitch); + } + cases[t2 << 3].forEach(stitch); + + function stitch(line) { + var start = [line[0][0] + x, line[0][1] + y], + end = [line[1][0] + x, line[1][1] + y], + startIndex = index(start), + endIndex = index(end), + f, g; + if (f = fragmentByEnd[startIndex]) { + if (g = fragmentByStart[endIndex]) { + delete fragmentByEnd[f.end]; + delete fragmentByStart[g.start]; + if (f === g) { + f.ring.push(end); + callback(f.ring); + } else { + fragmentByStart[f.start] = fragmentByEnd[g.end] = {start: f.start, end: g.end, ring: f.ring.concat(g.ring)}; + } + } else { + delete fragmentByEnd[f.end]; + f.ring.push(end); + fragmentByEnd[f.end = endIndex] = f; + } + } else if (f = fragmentByStart[endIndex]) { + if (g = fragmentByEnd[startIndex]) { + delete fragmentByStart[f.start]; + delete fragmentByEnd[g.end]; + if (f === g) { + f.ring.push(end); + callback(f.ring); + } else { + fragmentByStart[g.start] = fragmentByEnd[f.end] = {start: g.start, end: f.end, ring: g.ring.concat(f.ring)}; + } + } else { + delete fragmentByStart[f.start]; + f.ring.unshift(start); + fragmentByStart[f.start = startIndex] = f; + } + } else { + fragmentByStart[startIndex] = fragmentByEnd[endIndex] = {start: startIndex, end: endIndex, ring: [start, end]}; + } + } + } + + function index(point) { + return point[0] * 2 + point[1] * (dx + 1) * 4; + } + + function smoothLinear(ring, values, value) { + ring.forEach(function(point) { + var x = point[0], + y = point[1], + xt = x | 0, + yt = y | 0, + v0, + v1 = values[yt * dx + xt]; + if (x > 0 && x < dx && xt === x) { + v0 = values[yt * dx + xt - 1]; + point[0] = x + (value - v0) / (v1 - v0) - 0.5; + } + if (y > 0 && y < dy && yt === y) { + v0 = values[(yt - 1) * dx + xt]; + point[1] = y + (value - v0) / (v1 - v0) - 0.5; + } + }); + } + + contours.contour = contour; + + contours.size = function(_) { + if (!arguments.length) return [dx, dy]; + var _0 = Math.ceil(_[0]), _1 = Math.ceil(_[1]); + if (!(_0 > 0) || !(_1 > 0)) throw new Error("invalid size"); + return dx = _0, dy = _1, contours; + }; + + contours.thresholds = function(_) { + return arguments.length ? (threshold$$1 = typeof _ === "function" ? _ : Array.isArray(_) ? constant$6(slice$4.call(_)) : constant$6(_), contours) : threshold$$1; + }; + + contours.smooth = function(_) { + return arguments.length ? (smooth = _ ? smoothLinear : noop$3, contours) : smooth === smoothLinear; + }; + + return contours; +}; + +// TODO Optimize edge cases. +// TODO Optimize index calculation. +// TODO Optimize arguments. +function blurX(source, target, r) { + var n = source.width, + m = source.height, + w = (r << 1) + 1; + for (var j = 0; j < m; ++j) { + for (var i = 0, sr = 0; i < n + r; ++i) { + if (i < n) { + sr += source.data[i + j * n]; + } + if (i >= r) { + if (i >= w) { + sr -= source.data[i - w + j * n]; + } + target.data[i - r + j * n] = sr / Math.min(i + 1, n - 1 + w - i, w); + } + } + } +} + +// TODO Optimize edge cases. +// TODO Optimize index calculation. +// TODO Optimize arguments. +function blurY(source, target, r) { + var n = source.width, + m = source.height, + w = (r << 1) + 1; + for (var i = 0; i < n; ++i) { + for (var j = 0, sr = 0; j < m + r; ++j) { + if (j < m) { + sr += source.data[i + j * n]; + } + if (j >= r) { + if (j >= w) { + sr -= source.data[i + (j - w) * n]; + } + target.data[i + (j - r) * n] = sr / Math.min(j + 1, m - 1 + w - j, w); + } + } + } +} + +function defaultX(d) { + return d[0]; +} + +function defaultY(d) { + return d[1]; +} + +var contourDensity = function() { + var x = defaultX, + y = defaultY, + dx = 960, + dy = 500, + r = 20, // blur radius + k = 2, // log2(grid cell size) + o = r * 3, // grid offset, to pad for blur + n = (dx + o * 2) >> k, // grid width + m = (dy + o * 2) >> k, // grid height + threshold$$1 = constant$6(20); + + function density(data) { + var values0 = new Float32Array(n * m), + values1 = new Float32Array(n * m); + + data.forEach(function(d, i, data) { + var xi = (x(d, i, data) + o) >> k, + yi = (y(d, i, data) + o) >> k; + if (xi >= 0 && xi < n && yi >= 0 && yi < m) { + ++values0[xi + yi * n]; + } + }); + + // TODO Optimize. + blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); + blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); + blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); + blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); + blurX({width: n, height: m, data: values0}, {width: n, height: m, data: values1}, r >> k); + blurY({width: n, height: m, data: values1}, {width: n, height: m, data: values0}, r >> k); + + var tz = threshold$$1(values0); + + // Convert number of thresholds into uniform thresholds. + if (!Array.isArray(tz)) { + var stop = max(values0); + tz = tickStep(0, stop, tz); + tz = sequence(0, Math.floor(stop / tz) * tz, tz); + tz.shift(); + } + + return contours() + .thresholds(tz) + .size([n, m]) + (values0) + .map(transform); + } + + function transform(geometry) { + geometry.value *= Math.pow(2, -2 * k); // Density in points per square pixel. + geometry.coordinates.forEach(transformPolygon); + return geometry; + } + + function transformPolygon(coordinates) { + coordinates.forEach(transformRing); + } + + function transformRing(coordinates) { + coordinates.forEach(transformPoint); + } + + // TODO Optimize. + function transformPoint(coordinates) { + coordinates[0] = coordinates[0] * Math.pow(2, k) - o; + coordinates[1] = coordinates[1] * Math.pow(2, k) - o; + } + + function resize() { + o = r * 3; + n = (dx + o * 2) >> k; + m = (dy + o * 2) >> k; + return density; + } + + density.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : constant$6(+_), density) : x; + }; + + density.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : constant$6(+_), density) : y; + }; + + density.size = function(_) { + if (!arguments.length) return [dx, dy]; + var _0 = Math.ceil(_[0]), _1 = Math.ceil(_[1]); + if (!(_0 >= 0) && !(_0 >= 0)) throw new Error("invalid size"); + return dx = _0, dy = _1, resize(); + }; + + density.cellSize = function(_) { + if (!arguments.length) return 1 << k; + if (!((_ = +_) >= 1)) throw new Error("invalid cell size"); + return k = Math.floor(Math.log(_) / Math.LN2), resize(); + }; + + density.thresholds = function(_) { + return arguments.length ? (threshold$$1 = typeof _ === "function" ? _ : Array.isArray(_) ? constant$6(slice$4.call(_)) : constant$6(_), density) : threshold$$1; + }; + + density.bandwidth = function(_) { + if (!arguments.length) return Math.sqrt(r * (r + 1)); + if (!((_ = +_) >= 0)) throw new Error("invalid bandwidth"); + return r = Math.round((Math.sqrt(4 * _ * _ + 1) - 1) / 2), resize(); + }; + + return density; +}; + +var CONTOUR_PARAMS = ['values', 'size']; +var DENSITY_PARAMS = ['x', 'y', 'size', 'cellSize', 'bandwidth']; + +/** + * Generate contours based on kernel-density estimation of point data. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} params.size - The dimensions [width, height] over which to compute contours. + * If the values parameter is provided, this must be the dimensions of the input data. + * If density estimation is performed, this is the output view dimensions in pixels. + * @param {Array} [params.values] - An array of numeric values representing an + * width x height grid of values over which to compute contours. If unspecified, this + * transform will instead attempt to compute contours for the kernel density estimate + * using values drawn from data tuples in the input pulse. + * @param {function(object): number} [params.x] - The pixel x-coordinate accessor for density estimation. + * @param {function(object): number} [params.y] - The pixel y-coordinate accessor for density estimation. + * @param {number} [params.cellSize] - Contour density calculation cell size. + * @param {number} [params.bandwidth] - Kernel density estimation bandwidth. + * @param {Array} [params.thresholds] - Contour threshold array. If + * this parameter is set, the count and nice parameters will be ignored. + * @param {number} [params.count] - The desired number of contours. + * @param {boolean} [params.nice] - Boolean flag indicating if the contour + * threshold values should be automatically aligned to "nice" + * human-friendly values. Setting this flag may cause the number of + * thresholds to deviate from the specified count. + */ +function Contour(params) { + Transform.call(this, null, params); +} + +Contour.Definition = { + "type": "Contour", + "metadata": {"generates": true}, + "params": [ + { "name": "size", "type": "number", "array": true, "length": 2, "required": true }, + { "name": "values", "type": "number", "array": true }, + { "name": "x", "type": "field" }, + { "name": "y", "type": "field" }, + { "name": "cellSize", "type": "number" }, + { "name": "bandwidth", "type": "number" }, + { "name": "count", "type": "number" }, + { "name": "nice", "type": "number", "default": false }, + { "name": "thresholds", "type": "number", "array": true } + ] +}; + +var prototype$63 = inherits(Contour, Transform); + +prototype$63.transform = function(_, pulse) { + if (this.value && !pulse.changed() && !_.modified()) + return pulse.StopPropagation; + + var out = pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS), + count = _.count || 10, + contour, params, values; + + if (_.values) { + contour = contours(); + params = CONTOUR_PARAMS; + values = _.values; + } else { + contour = contourDensity(); + params = DENSITY_PARAMS; + values = pulse.materialize(pulse.SOURCE).source; + } + + // set threshold parameter + contour.thresholds(_.thresholds || (_.nice ? count : quantize$5(count))); + + // set all other parameters + params.forEach(function(param) { + if (_[param] != null) contour[param](_[param]); + }); + + if (this.value) out.rem = this.value; + values = values && values.length ? contour(values).map(ingest) : []; + this.value = out.source = out.add = values; + + return out; +}; + +function quantize$5(k) { + return function(values) { + var ex = extent(values), x0 = ex[0], dx = ex[1] - x0, + t = [], i = 1; + for (; i<=k; ++i) t.push(x0 + dx * i / (k + 1)); + return t; + }; +} + +var Feature = 'Feature'; +var FeatureCollection = 'FeatureCollection'; +var MultiPoint = 'MultiPoint'; + +/** + * Consolidate an array of [longitude, latitude] points or GeoJSON features + * into a combined GeoJSON object. This transform is particularly useful for + * combining geo data for a Projection's fit argument. The resulting GeoJSON + * data is available as this transform's value. Input pulses are unchanged. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} [params.fields] - A two-element array + * of field accessors for the longitude and latitude values. + * @param {function(object): *} params.geojson - A field accessor for + * retrieving GeoJSON feature data. + */ +function GeoJSON(params) { + Transform.call(this, null, params); +} + +GeoJSON.Definition = { + "type": "GeoJSON", + "metadata": {}, + "params": [ + { "name": "fields", "type": "field", "array": true, "length": 2 }, + { "name": "geojson", "type": "field" }, + ] +}; + +var prototype$64 = inherits(GeoJSON, Transform); + +prototype$64.transform = function(_, pulse) { + var features = this._features, + points = this._points, + fields = _.fields, + lon = fields && fields[0], + lat = fields && fields[1], + geojson = _.geojson, + flag = pulse.ADD, + mod; + + mod = _.modified() + || pulse.changed(pulse.REM) + || pulse.modified(accessorFields(geojson)) + || (lon && (pulse.modified(accessorFields(lon)))) + || (lat && (pulse.modified(accessorFields(lat)))); + + if (!this.value || mod) { + flag = pulse.SOURCE; + this._features = (features = []); + this._points = (points = []); + } + + if (geojson) { + pulse.visit(flag, function(t) { + features.push(geojson(t)); + }); + } + + if (lon && lat) { + pulse.visit(flag, function(t) { + var x = lon(t), + y = lat(t); + if (x != null && y != null && (x = +x) === x && (y = +y) === y) { + points.push([x, y]); + } + }); + features = features.concat({ + type: Feature, + geometry: { + type: MultiPoint, + coordinates: points + } + }); + } + + this.value = { + type: FeatureCollection, + features: features + }; +}; + +// Adds floating point numbers with twice the normal precision. +// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and +// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3) +// 305–363 (1997). +// Code adapted from GeographicLib by Charles F. F. Karney, +// http://geographiclib.sourceforge.net/ + +var adder = function() { + return new Adder; +}; + +function Adder() { + this.reset(); +} + +Adder.prototype = { + constructor: Adder, + reset: function() { + this.s = // rounded value + this.t = 0; // exact error + }, + add: function(y) { + add$3(temp$1, y, this.t); + add$3(this, temp$1.s, this.s); + if (this.s) this.t += temp$1.t; + else this.s = temp$1.t; + }, + valueOf: function() { + return this.s; + } +}; + +var temp$1 = new Adder; + +function add$3(adder, a, b) { + var x = adder.s = a + b, + bv = x - a, + av = x - bv; + adder.t = (a - av) + (b - bv); +} + +var epsilon$2 = 1e-6; +var epsilon2$1 = 1e-12; +var pi$3 = Math.PI; +var halfPi$2 = pi$3 / 2; +var quarterPi = pi$3 / 4; +var tau$4 = pi$3 * 2; + +var degrees$1 = 180 / pi$3; +var radians = pi$3 / 180; + +var abs$1 = Math.abs; +var atan = Math.atan; +var atan2$1 = Math.atan2; +var cos$1 = Math.cos; +var ceil = Math.ceil; +var exp$1 = Math.exp; + +var log$3 = Math.log; +var pow$2 = Math.pow; +var sin$1 = Math.sin; +var sign$1 = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; }; +var sqrt$2 = Math.sqrt; +var tan = Math.tan; + +function acos$1(x) { + return x > 1 ? 0 : x < -1 ? pi$3 : Math.acos(x); +} + +function asin$1(x) { + return x > 1 ? halfPi$2 : x < -1 ? -halfPi$2 : Math.asin(x); +} + +function noop$4() {} + +function streamGeometry(geometry, stream) { + if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) { + streamGeometryType[geometry.type](geometry, stream); + } +} + +var streamObjectType = { + Feature: function(object, stream) { + streamGeometry(object.geometry, stream); + }, + FeatureCollection: function(object, stream) { + var features = object.features, i = -1, n = features.length; + while (++i < n) streamGeometry(features[i].geometry, stream); + } +}; + +var streamGeometryType = { + Sphere: function(object, stream) { + stream.sphere(); + }, + Point: function(object, stream) { + object = object.coordinates; + stream.point(object[0], object[1], object[2]); + }, + MultiPoint: function(object, stream) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]); + }, + LineString: function(object, stream) { + streamLine(object.coordinates, stream, 0); + }, + MultiLineString: function(object, stream) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) streamLine(coordinates[i], stream, 0); + }, + Polygon: function(object, stream) { + streamPolygon(object.coordinates, stream); + }, + MultiPolygon: function(object, stream) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) streamPolygon(coordinates[i], stream); + }, + GeometryCollection: function(object, stream) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) streamGeometry(geometries[i], stream); + } +}; + +function streamLine(coordinates, stream, closed) { + var i = -1, n = coordinates.length - closed, coordinate; + stream.lineStart(); + while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]); + stream.lineEnd(); +} + +function streamPolygon(coordinates, stream) { + var i = -1, n = coordinates.length; + stream.polygonStart(); + while (++i < n) streamLine(coordinates[i], stream, 1); + stream.polygonEnd(); +} + +var geoStream = function(object, stream) { + if (object && streamObjectType.hasOwnProperty(object.type)) { + streamObjectType[object.type](object, stream); + } else { + streamGeometry(object, stream); + } +}; + +var areaRingSum = adder(); + +var areaSum = adder(); +var lambda00; +var phi00; +var lambda0; +var cosPhi0; +var sinPhi0; + +var areaStream = { + point: noop$4, + lineStart: noop$4, + lineEnd: noop$4, + polygonStart: function() { + areaRingSum.reset(); + areaStream.lineStart = areaRingStart; + areaStream.lineEnd = areaRingEnd; + }, + polygonEnd: function() { + var areaRing = +areaRingSum; + areaSum.add(areaRing < 0 ? tau$4 + areaRing : areaRing); + this.lineStart = this.lineEnd = this.point = noop$4; + }, + sphere: function() { + areaSum.add(tau$4); + } +}; + +function areaRingStart() { + areaStream.point = areaPointFirst; +} + +function areaRingEnd() { + areaPoint(lambda00, phi00); +} + +function areaPointFirst(lambda, phi) { + areaStream.point = areaPoint; + lambda00 = lambda, phi00 = phi; + lambda *= radians, phi *= radians; + lambda0 = lambda, cosPhi0 = cos$1(phi = phi / 2 + quarterPi), sinPhi0 = sin$1(phi); +} + +function areaPoint(lambda, phi) { + lambda *= radians, phi *= radians; + phi = phi / 2 + quarterPi; // half the angular distance from south pole + + // Spherical excess E for a spherical triangle with vertices: south pole, + // previous point, current point. Uses a formula derived from Cagnoli’s + // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2). + var dLambda = lambda - lambda0, + sdLambda = dLambda >= 0 ? 1 : -1, + adLambda = sdLambda * dLambda, + cosPhi = cos$1(phi), + sinPhi = sin$1(phi), + k = sinPhi0 * sinPhi, + u = cosPhi0 * cosPhi + k * cos$1(adLambda), + v = k * sdLambda * sin$1(adLambda); + areaRingSum.add(atan2$1(v, u)); + + // Advance the previous points. + lambda0 = lambda, cosPhi0 = cosPhi, sinPhi0 = sinPhi; +} + +var area$4 = function(object) { + areaSum.reset(); + geoStream(object, areaStream); + return areaSum * 2; +}; + +function spherical(cartesian) { + return [atan2$1(cartesian[1], cartesian[0]), asin$1(cartesian[2])]; +} + +function cartesian(spherical) { + var lambda = spherical[0], phi = spherical[1], cosPhi = cos$1(phi); + return [cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)]; +} + +function cartesianDot(a, b) { + return a[0] * b[0] + a[1] * b[1] + a[2] * b[2]; +} + +function cartesianCross(a, b) { + return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]]; +} + +// TODO return a +function cartesianAddInPlace(a, b) { + a[0] += b[0], a[1] += b[1], a[2] += b[2]; +} + +function cartesianScale(vector, k) { + return [vector[0] * k, vector[1] * k, vector[2] * k]; +} + +// TODO return d +function cartesianNormalizeInPlace(d) { + var l = sqrt$2(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]); + d[0] /= l, d[1] /= l, d[2] /= l; +} + +var lambda0$1; +var phi0; +var lambda1; +var phi1; +var lambda2; +var lambda00$1; +var phi00$1; +var p0; +var deltaSum = adder(); +var ranges; +var range; + +var boundsStream = { + point: boundsPoint, + lineStart: boundsLineStart, + lineEnd: boundsLineEnd, + polygonStart: function() { + boundsStream.point = boundsRingPoint; + boundsStream.lineStart = boundsRingStart; + boundsStream.lineEnd = boundsRingEnd; + deltaSum.reset(); + areaStream.polygonStart(); + }, + polygonEnd: function() { + areaStream.polygonEnd(); + boundsStream.point = boundsPoint; + boundsStream.lineStart = boundsLineStart; + boundsStream.lineEnd = boundsLineEnd; + if (areaRingSum < 0) lambda0$1 = -(lambda1 = 180), phi0 = -(phi1 = 90); + else if (deltaSum > epsilon$2) phi1 = 90; + else if (deltaSum < -epsilon$2) phi0 = -90; + range[0] = lambda0$1, range[1] = lambda1; + } +}; + +function boundsPoint(lambda, phi) { + ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]); + if (phi < phi0) phi0 = phi; + if (phi > phi1) phi1 = phi; +} + +function linePoint(lambda, phi) { + var p = cartesian([lambda * radians, phi * radians]); + if (p0) { + var normal = cartesianCross(p0, p), + equatorial = [normal[1], -normal[0], 0], + inflection = cartesianCross(equatorial, normal); + cartesianNormalizeInPlace(inflection); + inflection = spherical(inflection); + var delta = lambda - lambda2, + sign = delta > 0 ? 1 : -1, + lambdai = inflection[0] * degrees$1 * sign, + phii, + antimeridian = abs$1(delta) > 180; + if (antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) { + phii = inflection[1] * degrees$1; + if (phii > phi1) phi1 = phii; + } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * lambda2 < lambdai && lambdai < sign * lambda)) { + phii = -inflection[1] * degrees$1; + if (phii < phi0) phi0 = phii; + } else { + if (phi < phi0) phi0 = phi; + if (phi > phi1) phi1 = phi; + } + if (antimeridian) { + if (lambda < lambda2) { + if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; + } else { + if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; + } + } else { + if (lambda1 >= lambda0$1) { + if (lambda < lambda0$1) lambda0$1 = lambda; + if (lambda > lambda1) lambda1 = lambda; + } else { + if (lambda > lambda2) { + if (angle(lambda0$1, lambda) > angle(lambda0$1, lambda1)) lambda1 = lambda; + } else { + if (angle(lambda, lambda1) > angle(lambda0$1, lambda1)) lambda0$1 = lambda; + } + } + } + } else { + ranges.push(range = [lambda0$1 = lambda, lambda1 = lambda]); + } + if (phi < phi0) phi0 = phi; + if (phi > phi1) phi1 = phi; + p0 = p, lambda2 = lambda; +} + +function boundsLineStart() { + boundsStream.point = linePoint; +} + +function boundsLineEnd() { + range[0] = lambda0$1, range[1] = lambda1; + boundsStream.point = boundsPoint; + p0 = null; +} + +function boundsRingPoint(lambda, phi) { + if (p0) { + var delta = lambda - lambda2; + deltaSum.add(abs$1(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta); + } else { + lambda00$1 = lambda, phi00$1 = phi; + } + areaStream.point(lambda, phi); + linePoint(lambda, phi); +} + +function boundsRingStart() { + areaStream.lineStart(); +} + +function boundsRingEnd() { + boundsRingPoint(lambda00$1, phi00$1); + areaStream.lineEnd(); + if (abs$1(deltaSum) > epsilon$2) lambda0$1 = -(lambda1 = 180); + range[0] = lambda0$1, range[1] = lambda1; + p0 = null; +} + +// Finds the left-right distance between two longitudes. +// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want +// the distance between ±180° to be 360°. +function angle(lambda0, lambda1) { + return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1; +} + +function rangeCompare(a, b) { + return a[0] - b[0]; +} + +function rangeContains(range, x) { + return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x; +} + +var bounds$1 = function(feature) { + var i, n, a, b, merged, deltaMax, delta; + + phi1 = lambda1 = -(lambda0$1 = phi0 = Infinity); + ranges = []; + geoStream(feature, boundsStream); + + // First, sort ranges by their minimum longitudes. + if (n = ranges.length) { + ranges.sort(rangeCompare); + + // Then, merge any ranges that overlap. + for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) { + b = ranges[i]; + if (rangeContains(a, b[0]) || rangeContains(a, b[1])) { + if (angle(a[0], b[1]) > angle(a[0], a[1])) a[1] = b[1]; + if (angle(b[0], a[1]) > angle(a[0], a[1])) a[0] = b[0]; + } else { + merged.push(a = b); + } + } + + // Finally, find the largest gap between the merged ranges. + // The final bounding box will be the inverse of this gap. + for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) { + b = merged[i]; + if ((delta = angle(a[1], b[0])) > deltaMax) deltaMax = delta, lambda0$1 = b[0], lambda1 = a[1]; + } + } + + ranges = range = null; + + return lambda0$1 === Infinity || phi0 === Infinity + ? [[NaN, NaN], [NaN, NaN]] + : [[lambda0$1, phi0], [lambda1, phi1]]; +}; + +var W0; +var W1; +var X0; +var Y0; +var Z0; +var X1; +var Y1; +var Z1; +var X2; +var Y2; +var Z2; +var lambda00$2; +var phi00$2; +var x0; +var y0; +var z0; // previous point + +var centroidStream = { + sphere: noop$4, + point: centroidPoint, + lineStart: centroidLineStart, + lineEnd: centroidLineEnd, + polygonStart: function() { + centroidStream.lineStart = centroidRingStart; + centroidStream.lineEnd = centroidRingEnd; + }, + polygonEnd: function() { + centroidStream.lineStart = centroidLineStart; + centroidStream.lineEnd = centroidLineEnd; + } +}; + +// Arithmetic mean of Cartesian vectors. +function centroidPoint(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi); + centroidPointCartesian(cosPhi * cos$1(lambda), cosPhi * sin$1(lambda), sin$1(phi)); +} + +function centroidPointCartesian(x, y, z) { + ++W0; + X0 += (x - X0) / W0; + Y0 += (y - Y0) / W0; + Z0 += (z - Z0) / W0; +} + +function centroidLineStart() { + centroidStream.point = centroidLinePointFirst; +} + +function centroidLinePointFirst(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi); + x0 = cosPhi * cos$1(lambda); + y0 = cosPhi * sin$1(lambda); + z0 = sin$1(phi); + centroidStream.point = centroidLinePoint; + centroidPointCartesian(x0, y0, z0); +} + +function centroidLinePoint(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi), + x = cosPhi * cos$1(lambda), + y = cosPhi * sin$1(lambda), + z = sin$1(phi), + w = atan2$1(sqrt$2((w = y0 * z - z0 * y) * w + (w = z0 * x - x0 * z) * w + (w = x0 * y - y0 * x) * w), x0 * x + y0 * y + z0 * z); + W1 += w; + X1 += w * (x0 + (x0 = x)); + Y1 += w * (y0 + (y0 = y)); + Z1 += w * (z0 + (z0 = z)); + centroidPointCartesian(x0, y0, z0); +} + +function centroidLineEnd() { + centroidStream.point = centroidPoint; +} + +// See J. E. Brock, The Inertia Tensor for a Spherical Triangle, +// J. Applied Mechanics 42, 239 (1975). +function centroidRingStart() { + centroidStream.point = centroidRingPointFirst; +} + +function centroidRingEnd() { + centroidRingPoint(lambda00$2, phi00$2); + centroidStream.point = centroidPoint; +} + +function centroidRingPointFirst(lambda, phi) { + lambda00$2 = lambda, phi00$2 = phi; + lambda *= radians, phi *= radians; + centroidStream.point = centroidRingPoint; + var cosPhi = cos$1(phi); + x0 = cosPhi * cos$1(lambda); + y0 = cosPhi * sin$1(lambda); + z0 = sin$1(phi); + centroidPointCartesian(x0, y0, z0); +} + +function centroidRingPoint(lambda, phi) { + lambda *= radians, phi *= radians; + var cosPhi = cos$1(phi), + x = cosPhi * cos$1(lambda), + y = cosPhi * sin$1(lambda), + z = sin$1(phi), + cx = y0 * z - z0 * y, + cy = z0 * x - x0 * z, + cz = x0 * y - y0 * x, + m = sqrt$2(cx * cx + cy * cy + cz * cz), + w = asin$1(m), // line weight = angle + v = m && -w / m; // area weight multiplier + X2 += v * cx; + Y2 += v * cy; + Z2 += v * cz; + W1 += w; + X1 += w * (x0 + (x0 = x)); + Y1 += w * (y0 + (y0 = y)); + Z1 += w * (z0 + (z0 = z)); + centroidPointCartesian(x0, y0, z0); +} + +var centroid = function(object) { + W0 = W1 = + X0 = Y0 = Z0 = + X1 = Y1 = Z1 = + X2 = Y2 = Z2 = 0; + geoStream(object, centroidStream); + + var x = X2, + y = Y2, + z = Z2, + m = x * x + y * y + z * z; + + // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid. + if (m < epsilon2$1) { + x = X1, y = Y1, z = Z1; + // If the feature has zero length, fall back to arithmetic mean of point vectors. + if (W1 < epsilon$2) x = X0, y = Y0, z = Z0; + m = x * x + y * y + z * z; + // If the feature still has an undefined ccentroid, then return. + if (m < epsilon2$1) return [NaN, NaN]; + } + + return [atan2$1(y, x) * degrees$1, asin$1(z / sqrt$2(m)) * degrees$1]; +}; + +var compose = function(a, b) { + + function compose(x, y) { + return x = a(x, y), b(x[0], x[1]); + } + + if (a.invert && b.invert) compose.invert = function(x, y) { + return x = b.invert(x, y), x && a.invert(x[0], x[1]); + }; + + return compose; +}; + +function rotationIdentity(lambda, phi) { + return [lambda > pi$3 ? lambda - tau$4 : lambda < -pi$3 ? lambda + tau$4 : lambda, phi]; +} + +rotationIdentity.invert = rotationIdentity; + +function rotateRadians(deltaLambda, deltaPhi, deltaGamma) { + return (deltaLambda %= tau$4) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma)) + : rotationLambda(deltaLambda)) + : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma) + : rotationIdentity); +} + +function forwardRotationLambda(deltaLambda) { + return function(lambda, phi) { + return lambda += deltaLambda, [lambda > pi$3 ? lambda - tau$4 : lambda < -pi$3 ? lambda + tau$4 : lambda, phi]; + }; +} + +function rotationLambda(deltaLambda) { + var rotation = forwardRotationLambda(deltaLambda); + rotation.invert = forwardRotationLambda(-deltaLambda); + return rotation; +} + +function rotationPhiGamma(deltaPhi, deltaGamma) { + var cosDeltaPhi = cos$1(deltaPhi), + sinDeltaPhi = sin$1(deltaPhi), + cosDeltaGamma = cos$1(deltaGamma), + sinDeltaGamma = sin$1(deltaGamma); + + function rotation(lambda, phi) { + var cosPhi = cos$1(phi), + x = cos$1(lambda) * cosPhi, + y = sin$1(lambda) * cosPhi, + z = sin$1(phi), + k = z * cosDeltaPhi + x * sinDeltaPhi; + return [ + atan2$1(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi), + asin$1(k * cosDeltaGamma + y * sinDeltaGamma) + ]; + } + + rotation.invert = function(lambda, phi) { + var cosPhi = cos$1(phi), + x = cos$1(lambda) * cosPhi, + y = sin$1(lambda) * cosPhi, + z = sin$1(phi), + k = z * cosDeltaGamma - y * sinDeltaGamma; + return [ + atan2$1(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi), + asin$1(k * cosDeltaPhi - x * sinDeltaPhi) + ]; + }; + + return rotation; +} + +var rotation = function(rotate) { + rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0); + + function forward(coordinates) { + coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians); + return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; + } + + forward.invert = function(coordinates) { + coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians); + return coordinates[0] *= degrees$1, coordinates[1] *= degrees$1, coordinates; + }; + + return forward; +}; + +// Generates a circle centered at [0°, 0°], with a given radius and precision. +function circleStream(stream, radius, delta, direction, t0, t1) { + if (!delta) return; + var cosRadius = cos$1(radius), + sinRadius = sin$1(radius), + step = direction * delta; + if (t0 == null) { + t0 = radius + direction * tau$4; + t1 = radius - step / 2; + } else { + t0 = circleRadius(cosRadius, t0); + t1 = circleRadius(cosRadius, t1); + if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau$4; + } + for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) { + point = spherical([cosRadius, -sinRadius * cos$1(t), -sinRadius * sin$1(t)]); + stream.point(point[0], point[1]); + } +} + +// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0]. +function circleRadius(cosRadius, point) { + point = cartesian(point), point[0] -= cosRadius; + cartesianNormalizeInPlace(point); + var radius = acos$1(-point[1]); + return ((-point[2] < 0 ? -radius : radius) + tau$4 - epsilon$2) % tau$4; +} + +var clipBuffer = function() { + var lines = [], + line; + return { + point: function(x, y) { + line.push([x, y]); + }, + lineStart: function() { + lines.push(line = []); + }, + lineEnd: noop$4, + rejoin: function() { + if (lines.length > 1) lines.push(lines.pop().concat(lines.shift())); + }, + result: function() { + var result = lines; + lines = []; + line = null; + return result; + } + }; +}; + +var pointEqual = function(a, b) { + return abs$1(a[0] - b[0]) < epsilon$2 && abs$1(a[1] - b[1]) < epsilon$2; +}; + +function Intersection(point, points, other, entry) { + this.x = point; + this.z = points; + this.o = other; // another intersection + this.e = entry; // is an entry? + this.v = false; // visited + this.n = this.p = null; // next & previous +} + +// A generalized polygon clipping algorithm: given a polygon that has been cut +// into its visible line segments, and rejoins the segments by interpolating +// along the clip edge. +var clipRejoin = function(segments, compareIntersection, startInside, interpolate, stream) { + var subject = [], + clip = [], + i, + n; + + segments.forEach(function(segment) { + if ((n = segment.length - 1) <= 0) return; + var n, p0 = segment[0], p1 = segment[n], x; + + // If the first and last points of a segment are coincident, then treat as a + // closed ring. TODO if all rings are closed, then the winding order of the + // exterior ring should be checked. + if (pointEqual(p0, p1)) { + stream.lineStart(); + for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]); + stream.lineEnd(); + return; + } + + subject.push(x = new Intersection(p0, segment, null, true)); + clip.push(x.o = new Intersection(p0, null, x, false)); + subject.push(x = new Intersection(p1, segment, null, false)); + clip.push(x.o = new Intersection(p1, null, x, true)); + }); + + if (!subject.length) return; + + clip.sort(compareIntersection); + link$1(subject); + link$1(clip); + + for (i = 0, n = clip.length; i < n; ++i) { + clip[i].e = startInside = !startInside; + } + + var start = subject[0], + points, + point; + + while (1) { + // Find first unvisited intersection. + var current = start, + isSubject = true; + while (current.v) if ((current = current.n) === start) return; + points = current.z; + stream.lineStart(); + do { + current.v = current.o.v = true; + if (current.e) { + if (isSubject) { + for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]); + } else { + interpolate(current.x, current.n.x, 1, stream); + } + current = current.n; + } else { + if (isSubject) { + points = current.p.z; + for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]); + } else { + interpolate(current.x, current.p.x, -1, stream); + } + current = current.p; + } + current = current.o; + points = current.z; + isSubject = !isSubject; + } while (!current.v); + stream.lineEnd(); + } +}; + +function link$1(array) { + if (!(n = array.length)) return; + var n, + i = 0, + a = array[0], + b; + while (++i < n) { + a.n = b = array[i]; + b.p = a; + a = b; + } + a.n = b = array[0]; + b.p = a; +} + +var sum$2 = adder(); + +var polygonContains = function(polygon, point) { + var lambda = point[0], + phi = point[1], + normal = [sin$1(lambda), -cos$1(lambda), 0], + angle = 0, + winding = 0; + + sum$2.reset(); + + for (var i = 0, n = polygon.length; i < n; ++i) { + if (!(m = (ring = polygon[i]).length)) continue; + var ring, + m, + point0 = ring[m - 1], + lambda0 = point0[0], + phi0 = point0[1] / 2 + quarterPi, + sinPhi0 = sin$1(phi0), + cosPhi0 = cos$1(phi0); + + for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) { + var point1 = ring[j], + lambda1 = point1[0], + phi1 = point1[1] / 2 + quarterPi, + sinPhi1 = sin$1(phi1), + cosPhi1 = cos$1(phi1), + delta = lambda1 - lambda0, + sign = delta >= 0 ? 1 : -1, + absDelta = sign * delta, + antimeridian = absDelta > pi$3, + k = sinPhi0 * sinPhi1; + + sum$2.add(atan2$1(k * sign * sin$1(absDelta), cosPhi0 * cosPhi1 + k * cos$1(absDelta))); + angle += antimeridian ? delta + sign * tau$4 : delta; + + // Are the longitudes either side of the point’s meridian (lambda), + // and are the latitudes smaller than the parallel (phi)? + if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) { + var arc = cartesianCross(cartesian(point0), cartesian(point1)); + cartesianNormalizeInPlace(arc); + var intersection = cartesianCross(normal, arc); + cartesianNormalizeInPlace(intersection); + var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin$1(intersection[2]); + if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) { + winding += antimeridian ^ delta >= 0 ? 1 : -1; + } + } + } + } + + // First, determine whether the South pole is inside or outside: + // + // It is inside if: + // * the polygon winds around it in a clockwise direction. + // * the polygon does not (cumulatively) wind around it, but has a negative + // (counter-clockwise) area. + // + // Second, count the (signed) number of times a segment crosses a lambda + // from the point to the South pole. If it is zero, then the point is the + // same side as the South pole. + + return (angle < -epsilon$2 || angle < epsilon$2 && sum$2 < -epsilon$2) ^ (winding & 1); +}; + +var clip$2 = function(pointVisible, clipLine, interpolate, start) { + return function(sink) { + var line = clipLine(sink), + ringBuffer = clipBuffer(), + ringSink = clipLine(ringBuffer), + polygonStarted = false, + polygon, + segments, + ring; + + var clip = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { + clip.point = pointRing; + clip.lineStart = ringStart; + clip.lineEnd = ringEnd; + segments = []; + polygon = []; + }, + polygonEnd: function() { + clip.point = point; + clip.lineStart = lineStart; + clip.lineEnd = lineEnd; + segments = merge$2(segments); + var startInside = polygonContains(polygon, start); + if (segments.length) { + if (!polygonStarted) sink.polygonStart(), polygonStarted = true; + clipRejoin(segments, compareIntersection, startInside, interpolate, sink); + } else if (startInside) { + if (!polygonStarted) sink.polygonStart(), polygonStarted = true; + sink.lineStart(); + interpolate(null, null, 1, sink); + sink.lineEnd(); + } + if (polygonStarted) sink.polygonEnd(), polygonStarted = false; + segments = polygon = null; + }, + sphere: function() { + sink.polygonStart(); + sink.lineStart(); + interpolate(null, null, 1, sink); + sink.lineEnd(); + sink.polygonEnd(); + } + }; + + function point(lambda, phi) { + if (pointVisible(lambda, phi)) sink.point(lambda, phi); + } + + function pointLine(lambda, phi) { + line.point(lambda, phi); + } + + function lineStart() { + clip.point = pointLine; + line.lineStart(); + } + + function lineEnd() { + clip.point = point; + line.lineEnd(); + } + + function pointRing(lambda, phi) { + ring.push([lambda, phi]); + ringSink.point(lambda, phi); + } + + function ringStart() { + ringSink.lineStart(); + ring = []; + } + + function ringEnd() { + pointRing(ring[0][0], ring[0][1]); + ringSink.lineEnd(); + + var clean = ringSink.clean(), + ringSegments = ringBuffer.result(), + i, n = ringSegments.length, m, + segment, + point; + + ring.pop(); + polygon.push(ring); + ring = null; + + if (!n) return; + + // No intersections. + if (clean & 1) { + segment = ringSegments[0]; + if ((m = segment.length - 1) > 0) { + if (!polygonStarted) sink.polygonStart(), polygonStarted = true; + sink.lineStart(); + for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]); + sink.lineEnd(); + } + return; + } + + // Rejoin connected segments. + // TODO reuse ringBuffer.rejoin()? + if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift())); + + segments.push(ringSegments.filter(validSegment)); + } + + return clip; + }; +}; + +function validSegment(segment) { + return segment.length > 1; +} + +// Intersections are sorted along the clip edge. For both antimeridian cutting +// and circle clipping, the same comparison is used. +function compareIntersection(a, b) { + return ((a = a.x)[0] < 0 ? a[1] - halfPi$2 - epsilon$2 : halfPi$2 - a[1]) + - ((b = b.x)[0] < 0 ? b[1] - halfPi$2 - epsilon$2 : halfPi$2 - b[1]); +} + +var clipAntimeridian = clip$2( + function() { return true; }, + clipAntimeridianLine, + clipAntimeridianInterpolate, + [-pi$3, -halfPi$2] +); + +// Takes a line and cuts into visible segments. Return values: 0 - there were +// intersections or the line was empty; 1 - no intersections; 2 - there were +// intersections, and the first and last segments should be rejoined. +function clipAntimeridianLine(stream) { + var lambda0 = NaN, + phi0 = NaN, + sign0 = NaN, + clean; // no intersections + + return { + lineStart: function() { + stream.lineStart(); + clean = 1; + }, + point: function(lambda1, phi1) { + var sign1 = lambda1 > 0 ? pi$3 : -pi$3, + delta = abs$1(lambda1 - lambda0); + if (abs$1(delta - pi$3) < epsilon$2) { // line crosses a pole + stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi$2 : -halfPi$2); + stream.point(sign0, phi0); + stream.lineEnd(); + stream.lineStart(); + stream.point(sign1, phi0); + stream.point(lambda1, phi0); + clean = 0; + } else if (sign0 !== sign1 && delta >= pi$3) { // line crosses antimeridian + if (abs$1(lambda0 - sign0) < epsilon$2) lambda0 -= sign0 * epsilon$2; // handle degeneracies + if (abs$1(lambda1 - sign1) < epsilon$2) lambda1 -= sign1 * epsilon$2; + phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1); + stream.point(sign0, phi0); + stream.lineEnd(); + stream.lineStart(); + stream.point(sign1, phi0); + clean = 0; + } + stream.point(lambda0 = lambda1, phi0 = phi1); + sign0 = sign1; + }, + lineEnd: function() { + stream.lineEnd(); + lambda0 = phi0 = NaN; + }, + clean: function() { + return 2 - clean; // if intersections, rejoin first and last segments + } + }; +} + +function clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) { + var cosPhi0, + cosPhi1, + sinLambda0Lambda1 = sin$1(lambda0 - lambda1); + return abs$1(sinLambda0Lambda1) > epsilon$2 + ? atan((sin$1(phi0) * (cosPhi1 = cos$1(phi1)) * sin$1(lambda1) + - sin$1(phi1) * (cosPhi0 = cos$1(phi0)) * sin$1(lambda0)) + / (cosPhi0 * cosPhi1 * sinLambda0Lambda1)) + : (phi0 + phi1) / 2; +} + +function clipAntimeridianInterpolate(from, to, direction, stream) { + var phi; + if (from == null) { + phi = direction * halfPi$2; + stream.point(-pi$3, phi); + stream.point(0, phi); + stream.point(pi$3, phi); + stream.point(pi$3, 0); + stream.point(pi$3, -phi); + stream.point(0, -phi); + stream.point(-pi$3, -phi); + stream.point(-pi$3, 0); + stream.point(-pi$3, phi); + } else if (abs$1(from[0] - to[0]) > epsilon$2) { + var lambda = from[0] < to[0] ? pi$3 : -pi$3; + phi = direction * lambda / 2; + stream.point(-lambda, phi); + stream.point(0, phi); + stream.point(lambda, phi); + } else { + stream.point(to[0], to[1]); + } +} + +var clipCircle = function(radius) { + var cr = cos$1(radius), + delta = 6 * radians, + smallRadius = cr > 0, + notHemisphere = abs$1(cr) > epsilon$2; // TODO optimise for this common case + + function interpolate(from, to, direction, stream) { + circleStream(stream, radius, delta, direction, from, to); + } + + function visible(lambda, phi) { + return cos$1(lambda) * cos$1(phi) > cr; + } + + // Takes a line and cuts into visible segments. Return values used for polygon + // clipping: 0 - there were intersections or the line was empty; 1 - no + // intersections 2 - there were intersections, and the first and last segments + // should be rejoined. + function clipLine(stream) { + var point0, // previous point + c0, // code for previous point + v0, // visibility of previous point + v00, // visibility of first point + clean; // no intersections + return { + lineStart: function() { + v00 = v0 = false; + clean = 1; + }, + point: function(lambda, phi) { + var point1 = [lambda, phi], + point2, + v = visible(lambda, phi), + c = smallRadius + ? v ? 0 : code(lambda, phi) + : v ? code(lambda + (lambda < 0 ? pi$3 : -pi$3), phi) : 0; + if (!point0 && (v00 = v0 = v)) stream.lineStart(); + // Handle degeneracies. + // TODO ignore if not clipping polygons. + if (v !== v0) { + point2 = intersect(point0, point1); + if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) { + point1[0] += epsilon$2; + point1[1] += epsilon$2; + v = visible(point1[0], point1[1]); + } + } + if (v !== v0) { + clean = 0; + if (v) { + // outside going in + stream.lineStart(); + point2 = intersect(point1, point0); + stream.point(point2[0], point2[1]); + } else { + // inside going out + point2 = intersect(point0, point1); + stream.point(point2[0], point2[1]); + stream.lineEnd(); + } + point0 = point2; + } else if (notHemisphere && point0 && smallRadius ^ v) { + var t; + // If the codes for two points are different, or are both zero, + // and there this segment intersects with the small circle. + if (!(c & c0) && (t = intersect(point1, point0, true))) { + clean = 0; + if (smallRadius) { + stream.lineStart(); + stream.point(t[0][0], t[0][1]); + stream.point(t[1][0], t[1][1]); + stream.lineEnd(); + } else { + stream.point(t[1][0], t[1][1]); + stream.lineEnd(); + stream.lineStart(); + stream.point(t[0][0], t[0][1]); + } + } + } + if (v && (!point0 || !pointEqual(point0, point1))) { + stream.point(point1[0], point1[1]); + } + point0 = point1, v0 = v, c0 = c; + }, + lineEnd: function() { + if (v0) stream.lineEnd(); + point0 = null; + }, + // Rejoin first and last segments if there were intersections and the first + // and last points were visible. + clean: function() { + return clean | ((v00 && v0) << 1); + } + }; + } + + // Intersects the great circle between a and b with the clip circle. + function intersect(a, b, two) { + var pa = cartesian(a), + pb = cartesian(b); + + // We have two planes, n1.p = d1 and n2.p = d2. + // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2). + var n1 = [1, 0, 0], // normal + n2 = cartesianCross(pa, pb), + n2n2 = cartesianDot(n2, n2), + n1n2 = n2[0], // cartesianDot(n1, n2), + determinant = n2n2 - n1n2 * n1n2; + + // Two polar points. + if (!determinant) return !two && a; + + var c1 = cr * n2n2 / determinant, + c2 = -cr * n1n2 / determinant, + n1xn2 = cartesianCross(n1, n2), + A = cartesianScale(n1, c1), + B = cartesianScale(n2, c2); + cartesianAddInPlace(A, B); + + // Solve |p(t)|^2 = 1. + var u = n1xn2, + w = cartesianDot(A, u), + uu = cartesianDot(u, u), + t2 = w * w - uu * (cartesianDot(A, A) - 1); + + if (t2 < 0) return; + + var t = sqrt$2(t2), + q = cartesianScale(u, (-w - t) / uu); + cartesianAddInPlace(q, A); + q = spherical(q); + + if (!two) return q; + + // Two intersection points. + var lambda0 = a[0], + lambda1 = b[0], + phi0 = a[1], + phi1 = b[1], + z; + + if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z; + + var delta = lambda1 - lambda0, + polar = abs$1(delta - pi$3) < epsilon$2, + meridian = polar || delta < epsilon$2; + + if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z; + + // Check that the first point is between a and b. + if (meridian + ? polar + ? phi0 + phi1 > 0 ^ q[1] < (abs$1(q[0] - lambda0) < epsilon$2 ? phi0 : phi1) + : phi0 <= q[1] && q[1] <= phi1 + : delta > pi$3 ^ (lambda0 <= q[0] && q[0] <= lambda1)) { + var q1 = cartesianScale(u, (-w + t) / uu); + cartesianAddInPlace(q1, A); + return [q, spherical(q1)]; + } + } + + // Generates a 4-bit vector representing the location of a point relative to + // the small circle's bounding box. + function code(lambda, phi) { + var r = smallRadius ? radius : pi$3 - radius, + code = 0; + if (lambda < -r) code |= 1; // left + else if (lambda > r) code |= 2; // right + if (phi < -r) code |= 4; // below + else if (phi > r) code |= 8; // above + return code; + } + + return clip$2(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi$3, radius - pi$3]); +}; + +var clipLine = function(a, b, x0, y0, x1, y1) { + var ax = a[0], + ay = a[1], + bx = b[0], + by = b[1], + t0 = 0, + t1 = 1, + dx = bx - ax, + dy = by - ay, + r; + + r = x0 - ax; + if (!dx && r > 0) return; + r /= dx; + if (dx < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dx > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + + r = x1 - ax; + if (!dx && r < 0) return; + r /= dx; + if (dx < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dx > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + + r = y0 - ay; + if (!dy && r > 0) return; + r /= dy; + if (dy < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dy > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + + r = y1 - ay; + if (!dy && r < 0) return; + r /= dy; + if (dy < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dy > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + + if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy; + if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy; + return true; +}; + +var clipMax = 1e9; +var clipMin = -clipMax; + +// TODO Use d3-polygon’s polygonContains here for the ring check? +// TODO Eliminate duplicate buffering in clipBuffer and polygon.push? + +function clipRectangle(x0, y0, x1, y1) { + + function visible(x, y) { + return x0 <= x && x <= x1 && y0 <= y && y <= y1; + } + + function interpolate(from, to, direction, stream) { + var a = 0, a1 = 0; + if (from == null + || (a = corner(from, direction)) !== (a1 = corner(to, direction)) + || comparePoint(from, to) < 0 ^ direction > 0) { + do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0); + while ((a = (a + direction + 4) % 4) !== a1); + } else { + stream.point(to[0], to[1]); + } + } + + function corner(p, direction) { + return abs$1(p[0] - x0) < epsilon$2 ? direction > 0 ? 0 : 3 + : abs$1(p[0] - x1) < epsilon$2 ? direction > 0 ? 2 : 1 + : abs$1(p[1] - y0) < epsilon$2 ? direction > 0 ? 1 : 0 + : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon + } + + function compareIntersection(a, b) { + return comparePoint(a.x, b.x); + } + + function comparePoint(a, b) { + var ca = corner(a, 1), + cb = corner(b, 1); + return ca !== cb ? ca - cb + : ca === 0 ? b[1] - a[1] + : ca === 1 ? a[0] - b[0] + : ca === 2 ? a[1] - b[1] + : b[0] - a[0]; + } + + return function(stream) { + var activeStream = stream, + bufferStream = clipBuffer(), + segments, + polygon, + ring, + x__, y__, v__, // first point + x_, y_, v_, // previous point + first, + clean; + + var clipStream = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: polygonStart, + polygonEnd: polygonEnd + }; + + function point(x, y) { + if (visible(x, y)) activeStream.point(x, y); + } + + function polygonInside() { + var winding = 0; + + for (var i = 0, n = polygon.length; i < n; ++i) { + for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) { + a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1]; + if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; } + else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; } + } + } + + return winding; + } + + // Buffer geometry within a polygon and then clip it en masse. + function polygonStart() { + activeStream = bufferStream, segments = [], polygon = [], clean = true; + } + + function polygonEnd() { + var startInside = polygonInside(), + cleanInside = clean && startInside, + visible = (segments = merge$2(segments)).length; + if (cleanInside || visible) { + stream.polygonStart(); + if (cleanInside) { + stream.lineStart(); + interpolate(null, null, 1, stream); + stream.lineEnd(); + } + if (visible) { + clipRejoin(segments, compareIntersection, startInside, interpolate, stream); + } + stream.polygonEnd(); + } + activeStream = stream, segments = polygon = ring = null; + } + + function lineStart() { + clipStream.point = linePoint; + if (polygon) polygon.push(ring = []); + first = true; + v_ = false; + x_ = y_ = NaN; + } + + // TODO rather than special-case polygons, simply handle them separately. + // Ideally, coincident intersection points should be jittered to avoid + // clipping issues. + function lineEnd() { + if (segments) { + linePoint(x__, y__); + if (v__ && v_) bufferStream.rejoin(); + segments.push(bufferStream.result()); + } + clipStream.point = point; + if (v_) activeStream.lineEnd(); + } + + function linePoint(x, y) { + var v = visible(x, y); + if (polygon) ring.push([x, y]); + if (first) { + x__ = x, y__ = y, v__ = v; + first = false; + if (v) { + activeStream.lineStart(); + activeStream.point(x, y); + } + } else { + if (v && v_) activeStream.point(x, y); + else { + var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))], + b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))]; + if (clipLine(a, b, x0, y0, x1, y1)) { + if (!v_) { + activeStream.lineStart(); + activeStream.point(a[0], a[1]); + } + activeStream.point(b[0], b[1]); + if (!v) activeStream.lineEnd(); + clean = false; + } else if (v) { + activeStream.lineStart(); + activeStream.point(x, y); + clean = false; + } + } + } + x_ = x, y_ = y, v_ = v; + } + + return clipStream; + }; +} + +var lengthSum = adder(); +var lambda0$2; +var sinPhi0$1; +var cosPhi0$1; + +var lengthStream = { + sphere: noop$4, + point: noop$4, + lineStart: lengthLineStart, + lineEnd: noop$4, + polygonStart: noop$4, + polygonEnd: noop$4 +}; + +function lengthLineStart() { + lengthStream.point = lengthPointFirst; + lengthStream.lineEnd = lengthLineEnd; +} + +function lengthLineEnd() { + lengthStream.point = lengthStream.lineEnd = noop$4; +} + +function lengthPointFirst(lambda, phi) { + lambda *= radians, phi *= radians; + lambda0$2 = lambda, sinPhi0$1 = sin$1(phi), cosPhi0$1 = cos$1(phi); + lengthStream.point = lengthPoint; +} + +function lengthPoint(lambda, phi) { + lambda *= radians, phi *= radians; + var sinPhi = sin$1(phi), + cosPhi = cos$1(phi), + delta = abs$1(lambda - lambda0$2), + cosDelta = cos$1(delta), + sinDelta = sin$1(delta), + x = cosPhi * sinDelta, + y = cosPhi0$1 * sinPhi - sinPhi0$1 * cosPhi * cosDelta, + z = sinPhi0$1 * sinPhi + cosPhi0$1 * cosPhi * cosDelta; + lengthSum.add(atan2$1(sqrt$2(x * x + y * y), z)); + lambda0$2 = lambda, sinPhi0$1 = sinPhi, cosPhi0$1 = cosPhi; +} + +var length$1 = function(object) { + lengthSum.reset(); + geoStream(object, lengthStream); + return +lengthSum; +}; + +var coordinates = [null, null]; +var object$3 = {type: "LineString", coordinates: coordinates}; + +var distance = function(a, b) { + coordinates[0] = a; + coordinates[1] = b; + return length$1(object$3); +}; + +var containsGeometryType = { + Sphere: function() { + return true; + }, + Point: function(object, point) { + return containsPoint(object.coordinates, point); + }, + MultiPoint: function(object, point) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) if (containsPoint(coordinates[i], point)) return true; + return false; + }, + LineString: function(object, point) { + return containsLine(object.coordinates, point); + }, + MultiLineString: function(object, point) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) if (containsLine(coordinates[i], point)) return true; + return false; + }, + Polygon: function(object, point) { + return containsPolygon(object.coordinates, point); + }, + MultiPolygon: function(object, point) { + var coordinates = object.coordinates, i = -1, n = coordinates.length; + while (++i < n) if (containsPolygon(coordinates[i], point)) return true; + return false; + }, + GeometryCollection: function(object, point) { + var geometries = object.geometries, i = -1, n = geometries.length; + while (++i < n) if (containsGeometry(geometries[i], point)) return true; + return false; + } +}; + +function containsGeometry(geometry, point) { + return geometry && containsGeometryType.hasOwnProperty(geometry.type) + ? containsGeometryType[geometry.type](geometry, point) + : false; +} + +function containsPoint(coordinates, point) { + return distance(coordinates, point) === 0; +} + +function containsLine(coordinates, point) { + var ab = distance(coordinates[0], coordinates[1]), + ao = distance(coordinates[0], point), + ob = distance(point, coordinates[1]); + return ao + ob <= ab + epsilon$2; +} + +function containsPolygon(coordinates, point) { + return !!polygonContains(coordinates.map(ringRadians), pointRadians(point)); +} + +function ringRadians(ring) { + return ring = ring.map(pointRadians), ring.pop(), ring; +} + +function pointRadians(point) { + return [point[0] * radians, point[1] * radians]; +} + +function graticuleX(y0, y1, dy) { + var y = sequence(y0, y1 - epsilon$2, dy).concat(y1); + return function(x) { return y.map(function(y) { return [x, y]; }); }; +} + +function graticuleY(x0, x1, dx) { + var x = sequence(x0, x1 - epsilon$2, dx).concat(x1); + return function(y) { return x.map(function(x) { return [x, y]; }); }; +} + +function graticule() { + var x1, x0, X1, X0, + y1, y0, Y1, Y0, + dx = 10, dy = dx, DX = 90, DY = 360, + x, y, X, Y, + precision = 2.5; + + function graticule() { + return {type: "MultiLineString", coordinates: lines()}; + } + + function lines() { + return sequence(ceil(X0 / DX) * DX, X1, DX).map(X) + .concat(sequence(ceil(Y0 / DY) * DY, Y1, DY).map(Y)) + .concat(sequence(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs$1(x % DX) > epsilon$2; }).map(x)) + .concat(sequence(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs$1(y % DY) > epsilon$2; }).map(y)); + } + + graticule.lines = function() { + return lines().map(function(coordinates) { return {type: "LineString", coordinates: coordinates}; }); + }; + + graticule.outline = function() { + return { + type: "Polygon", + coordinates: [ + X(X0).concat( + Y(Y1).slice(1), + X(X1).reverse().slice(1), + Y(Y0).reverse().slice(1)) + ] + }; + }; + + graticule.extent = function(_) { + if (!arguments.length) return graticule.extentMinor(); + return graticule.extentMajor(_).extentMinor(_); + }; + + graticule.extentMajor = function(_) { + if (!arguments.length) return [[X0, Y0], [X1, Y1]]; + X0 = +_[0][0], X1 = +_[1][0]; + Y0 = +_[0][1], Y1 = +_[1][1]; + if (X0 > X1) _ = X0, X0 = X1, X1 = _; + if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _; + return graticule.precision(precision); + }; + + graticule.extentMinor = function(_) { + if (!arguments.length) return [[x0, y0], [x1, y1]]; + x0 = +_[0][0], x1 = +_[1][0]; + y0 = +_[0][1], y1 = +_[1][1]; + if (x0 > x1) _ = x0, x0 = x1, x1 = _; + if (y0 > y1) _ = y0, y0 = y1, y1 = _; + return graticule.precision(precision); + }; + + graticule.step = function(_) { + if (!arguments.length) return graticule.stepMinor(); + return graticule.stepMajor(_).stepMinor(_); + }; + + graticule.stepMajor = function(_) { + if (!arguments.length) return [DX, DY]; + DX = +_[0], DY = +_[1]; + return graticule; + }; + + graticule.stepMinor = function(_) { + if (!arguments.length) return [dx, dy]; + dx = +_[0], dy = +_[1]; + return graticule; + }; + + graticule.precision = function(_) { + if (!arguments.length) return precision; + precision = +_; + x = graticuleX(y0, y1, 90); + y = graticuleY(x0, x1, precision); + X = graticuleX(Y0, Y1, 90); + Y = graticuleY(X0, X1, precision); + return graticule; + }; + + return graticule + .extentMajor([[-180, -90 + epsilon$2], [180, 90 - epsilon$2]]) + .extentMinor([[-180, -80 - epsilon$2], [180, 80 + epsilon$2]]); +} + +var identity$7 = function(x) { + return x; +}; + +var areaSum$1 = adder(); +var areaRingSum$1 = adder(); +var x00; +var y00; +var x0$1; +var y0$1; + +var areaStream$1 = { + point: noop$4, + lineStart: noop$4, + lineEnd: noop$4, + polygonStart: function() { + areaStream$1.lineStart = areaRingStart$1; + areaStream$1.lineEnd = areaRingEnd$1; + }, + polygonEnd: function() { + areaStream$1.lineStart = areaStream$1.lineEnd = areaStream$1.point = noop$4; + areaSum$1.add(abs$1(areaRingSum$1)); + areaRingSum$1.reset(); + }, + result: function() { + var area = areaSum$1 / 2; + areaSum$1.reset(); + return area; + } +}; + +function areaRingStart$1() { + areaStream$1.point = areaPointFirst$1; +} + +function areaPointFirst$1(x, y) { + areaStream$1.point = areaPoint$1; + x00 = x0$1 = x, y00 = y0$1 = y; +} + +function areaPoint$1(x, y) { + areaRingSum$1.add(y0$1 * x - x0$1 * y); + x0$1 = x, y0$1 = y; +} + +function areaRingEnd$1() { + areaPoint$1(x00, y00); +} + +var x0$2 = Infinity; +var y0$2 = x0$2; +var x1 = -x0$2; +var y1 = x1; + +var boundsStream$1 = { + point: boundsPoint$1, + lineStart: noop$4, + lineEnd: noop$4, + polygonStart: noop$4, + polygonEnd: noop$4, + result: function() { + var bounds = [[x0$2, y0$2], [x1, y1]]; + x1 = y1 = -(y0$2 = x0$2 = Infinity); + return bounds; + } +}; + +function boundsPoint$1(x, y) { + if (x < x0$2) x0$2 = x; + if (x > x1) x1 = x; + if (y < y0$2) y0$2 = y; + if (y > y1) y1 = y; +} + +// TODO Enforce positive area for exterior, negative area for interior? + +var X0$1 = 0; +var Y0$1 = 0; +var Z0$1 = 0; +var X1$1 = 0; +var Y1$1 = 0; +var Z1$1 = 0; +var X2$1 = 0; +var Y2$1 = 0; +var Z2$1 = 0; +var x00$1; +var y00$1; +var x0$3; +var y0$3; + +var centroidStream$1 = { + point: centroidPoint$1, + lineStart: centroidLineStart$1, + lineEnd: centroidLineEnd$1, + polygonStart: function() { + centroidStream$1.lineStart = centroidRingStart$1; + centroidStream$1.lineEnd = centroidRingEnd$1; + }, + polygonEnd: function() { + centroidStream$1.point = centroidPoint$1; + centroidStream$1.lineStart = centroidLineStart$1; + centroidStream$1.lineEnd = centroidLineEnd$1; + }, + result: function() { + var centroid = Z2$1 ? [X2$1 / Z2$1, Y2$1 / Z2$1] + : Z1$1 ? [X1$1 / Z1$1, Y1$1 / Z1$1] + : Z0$1 ? [X0$1 / Z0$1, Y0$1 / Z0$1] + : [NaN, NaN]; + X0$1 = Y0$1 = Z0$1 = + X1$1 = Y1$1 = Z1$1 = + X2$1 = Y2$1 = Z2$1 = 0; + return centroid; + } +}; + +function centroidPoint$1(x, y) { + X0$1 += x; + Y0$1 += y; + ++Z0$1; +} + +function centroidLineStart$1() { + centroidStream$1.point = centroidPointFirstLine; +} + +function centroidPointFirstLine(x, y) { + centroidStream$1.point = centroidPointLine; + centroidPoint$1(x0$3 = x, y0$3 = y); +} + +function centroidPointLine(x, y) { + var dx = x - x0$3, dy = y - y0$3, z = sqrt$2(dx * dx + dy * dy); + X1$1 += z * (x0$3 + x) / 2; + Y1$1 += z * (y0$3 + y) / 2; + Z1$1 += z; + centroidPoint$1(x0$3 = x, y0$3 = y); +} + +function centroidLineEnd$1() { + centroidStream$1.point = centroidPoint$1; +} + +function centroidRingStart$1() { + centroidStream$1.point = centroidPointFirstRing; +} + +function centroidRingEnd$1() { + centroidPointRing(x00$1, y00$1); +} + +function centroidPointFirstRing(x, y) { + centroidStream$1.point = centroidPointRing; + centroidPoint$1(x00$1 = x0$3 = x, y00$1 = y0$3 = y); +} + +function centroidPointRing(x, y) { + var dx = x - x0$3, + dy = y - y0$3, + z = sqrt$2(dx * dx + dy * dy); + + X1$1 += z * (x0$3 + x) / 2; + Y1$1 += z * (y0$3 + y) / 2; + Z1$1 += z; + + z = y0$3 * x - x0$3 * y; + X2$1 += z * (x0$3 + x); + Y2$1 += z * (y0$3 + y); + Z2$1 += z * 3; + centroidPoint$1(x0$3 = x, y0$3 = y); +} + +function PathContext(context) { + this._context = context; +} + +PathContext.prototype = { + _radius: 4.5, + pointRadius: function(_) { + return this._radius = _, this; + }, + polygonStart: function() { + this._line = 0; + }, + polygonEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line === 0) this._context.closePath(); + this._point = NaN; + }, + point: function(x, y) { + switch (this._point) { + case 0: { + this._context.moveTo(x, y); + this._point = 1; + break; + } + case 1: { + this._context.lineTo(x, y); + break; + } + default: { + this._context.moveTo(x + this._radius, y); + this._context.arc(x, y, this._radius, 0, tau$4); + break; + } + } + }, + result: noop$4 +}; + +var lengthSum$1 = adder(); +var lengthRing; +var x00$2; +var y00$2; +var x0$4; +var y0$4; + +var lengthStream$1 = { + point: noop$4, + lineStart: function() { + lengthStream$1.point = lengthPointFirst$1; + }, + lineEnd: function() { + if (lengthRing) lengthPoint$1(x00$2, y00$2); + lengthStream$1.point = noop$4; + }, + polygonStart: function() { + lengthRing = true; + }, + polygonEnd: function() { + lengthRing = null; + }, + result: function() { + var length = +lengthSum$1; + lengthSum$1.reset(); + return length; + } +}; + +function lengthPointFirst$1(x, y) { + lengthStream$1.point = lengthPoint$1; + x00$2 = x0$4 = x, y00$2 = y0$4 = y; +} + +function lengthPoint$1(x, y) { + x0$4 -= x, y0$4 -= y; + lengthSum$1.add(sqrt$2(x0$4 * x0$4 + y0$4 * y0$4)); + x0$4 = x, y0$4 = y; +} + +function PathString() { + this._string = []; +} + +PathString.prototype = { + _radius: 4.5, + _circle: circle$2(4.5), + pointRadius: function(_) { + if ((_ = +_) !== this._radius) this._radius = _, this._circle = null; + return this; + }, + polygonStart: function() { + this._line = 0; + }, + polygonEnd: function() { + this._line = NaN; + }, + lineStart: function() { + this._point = 0; + }, + lineEnd: function() { + if (this._line === 0) this._string.push("Z"); + this._point = NaN; + }, + point: function(x, y) { + switch (this._point) { + case 0: { + this._string.push("M", x, ",", y); + this._point = 1; + break; + } + case 1: { + this._string.push("L", x, ",", y); + break; + } + default: { + if (this._circle == null) this._circle = circle$2(this._radius); + this._string.push("M", x, ",", y, this._circle); + break; + } + } + }, + result: function() { + if (this._string.length) { + var result = this._string.join(""); + this._string = []; + return result; + } else { + return null; + } + } +}; + +function circle$2(radius) { + return "m0," + radius + + "a" + radius + "," + radius + " 0 1,1 0," + -2 * radius + + "a" + radius + "," + radius + " 0 1,1 0," + 2 * radius + + "z"; +} + +var geoPath = function(projection, context) { + var pointRadius = 4.5, + projectionStream, + contextStream; + + function path(object) { + if (object) { + if (typeof pointRadius === "function") contextStream.pointRadius(+pointRadius.apply(this, arguments)); + geoStream(object, projectionStream(contextStream)); + } + return contextStream.result(); + } + + path.area = function(object) { + geoStream(object, projectionStream(areaStream$1)); + return areaStream$1.result(); + }; + + path.measure = function(object) { + geoStream(object, projectionStream(lengthStream$1)); + return lengthStream$1.result(); + }; + + path.bounds = function(object) { + geoStream(object, projectionStream(boundsStream$1)); + return boundsStream$1.result(); + }; + + path.centroid = function(object) { + geoStream(object, projectionStream(centroidStream$1)); + return centroidStream$1.result(); + }; + + path.projection = function(_) { + return arguments.length ? (projectionStream = _ == null ? (projection = null, identity$7) : (projection = _).stream, path) : projection; + }; + + path.context = function(_) { + if (!arguments.length) return context; + contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _); + if (typeof pointRadius !== "function") contextStream.pointRadius(pointRadius); + return path; + }; + + path.pointRadius = function(_) { + if (!arguments.length) return pointRadius; + pointRadius = typeof _ === "function" ? _ : (contextStream.pointRadius(+_), +_); + return path; + }; + + return path.projection(projection).context(context); +}; + +function transformer(methods) { + return function(stream) { + var s = new TransformStream; + for (var key in methods) s[key] = methods[key]; + s.stream = stream; + return s; + }; +} + +function TransformStream() {} + +TransformStream.prototype = { + constructor: TransformStream, + point: function(x, y) { this.stream.point(x, y); }, + sphere: function() { this.stream.sphere(); }, + lineStart: function() { this.stream.lineStart(); }, + lineEnd: function() { this.stream.lineEnd(); }, + polygonStart: function() { this.stream.polygonStart(); }, + polygonEnd: function() { this.stream.polygonEnd(); } +}; + +function fit(projection, fitBounds, object) { + var clip = projection.clipExtent && projection.clipExtent(); + projection.scale(150).translate([0, 0]); + if (clip != null) projection.clipExtent(null); + geoStream(object, projection.stream(boundsStream$1)); + fitBounds(boundsStream$1.result()); + if (clip != null) projection.clipExtent(clip); + return projection; +} + +function fitExtent(projection, extent, object) { + return fit(projection, function(b) { + var w = extent[1][0] - extent[0][0], + h = extent[1][1] - extent[0][1], + k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])), + x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2, + y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2; + projection.scale(150 * k).translate([x, y]); + }, object); +} + +function fitSize(projection, size, object) { + return fitExtent(projection, [[0, 0], size], object); +} + +function fitWidth(projection, width, object) { + return fit(projection, function(b) { + var w = +width, + k = w / (b[1][0] - b[0][0]), + x = (w - k * (b[1][0] + b[0][0])) / 2, + y = -k * b[0][1]; + projection.scale(150 * k).translate([x, y]); + }, object); +} + +function fitHeight(projection, height, object) { + return fit(projection, function(b) { + var h = +height, + k = h / (b[1][1] - b[0][1]), + x = -k * b[0][0], + y = (h - k * (b[1][1] + b[0][1])) / 2; + projection.scale(150 * k).translate([x, y]); + }, object); +} + +var maxDepth = 16; +var cosMinDistance = cos$1(30 * radians); // cos(minimum angular distance) + +var resample = function(project, delta2) { + return +delta2 ? resample$1(project, delta2) : resampleNone(project); +}; + +function resampleNone(project) { + return transformer({ + point: function(x, y) { + x = project(x, y); + this.stream.point(x[0], x[1]); + } + }); +} + +function resample$1(project, delta2) { + + function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) { + var dx = x1 - x0, + dy = y1 - y0, + d2 = dx * dx + dy * dy; + if (d2 > 4 * delta2 && depth--) { + var a = a0 + a1, + b = b0 + b1, + c = c0 + c1, + m = sqrt$2(a * a + b * b + c * c), + phi2 = asin$1(c /= m), + lambda2 = abs$1(abs$1(c) - 1) < epsilon$2 || abs$1(lambda0 - lambda1) < epsilon$2 ? (lambda0 + lambda1) / 2 : atan2$1(b, a), + p = project(lambda2, phi2), + x2 = p[0], + y2 = p[1], + dx2 = x2 - x0, + dy2 = y2 - y0, + dz = dy * dx2 - dx * dy2; + if (dz * dz / d2 > delta2 // perpendicular projected distance + || abs$1((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end + || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance + resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream); + stream.point(x2, y2); + resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream); + } + } + } + return function(stream) { + var lambda00, x00, y00, a00, b00, c00, // first point + lambda0, x0, y0, a0, b0, c0; // previous point + + var resampleStream = { + point: point, + lineStart: lineStart, + lineEnd: lineEnd, + polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; }, + polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; } + }; + + function point(x, y) { + x = project(x, y); + stream.point(x[0], x[1]); + } + + function lineStart() { + x0 = NaN; + resampleStream.point = linePoint; + stream.lineStart(); + } + + function linePoint(lambda, phi) { + var c = cartesian([lambda, phi]), p = project(lambda, phi); + resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream); + stream.point(x0, y0); + } + + function lineEnd() { + resampleStream.point = point; + stream.lineEnd(); + } + + function ringStart() { + lineStart(); + resampleStream.point = ringPoint; + resampleStream.lineEnd = ringEnd; + } + + function ringPoint(lambda, phi) { + linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0; + resampleStream.point = linePoint; + } + + function ringEnd() { + resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream); + resampleStream.lineEnd = lineEnd; + lineEnd(); + } + + return resampleStream; + }; +} + +var transformRadians = transformer({ + point: function(x, y) { + this.stream.point(x * radians, y * radians); + } +}); + +function transformRotate(rotate) { + return transformer({ + point: function(x, y) { + var r = rotate(x, y); + return this.stream.point(r[0], r[1]); + } + }); +} + +function projection$1(project) { + return projectionMutator(function() { return project; })(); +} + +function projectionMutator(projectAt) { + var project, + k = 150, // scale + x = 480, y = 250, // translate + dx, dy, lambda = 0, phi = 0, // center + deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate + theta = null, preclip = clipAntimeridian, // clip angle + x0 = null, y0, x1, y1, postclip = identity$7, // clip extent + delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision + cache, + cacheStream; + + function projection(point) { + point = projectRotate(point[0] * radians, point[1] * radians); + return [point[0] * k + dx, dy - point[1] * k]; + } + + function invert(point) { + point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k); + return point && [point[0] * degrees$1, point[1] * degrees$1]; + } + + function projectTransform(x, y) { + return x = project(x, y), [x[0] * k + dx, dy - x[1] * k]; + } + + projection.stream = function(stream) { + return cache && cacheStream === stream ? cache : cache = transformRadians(transformRotate(rotate)(preclip(projectResample(postclip(cacheStream = stream))))); + }; + + projection.preclip = function(_) { + return arguments.length ? (preclip = _, theta = undefined, reset()) : preclip; + }; + + projection.postclip = function(_) { + return arguments.length ? (postclip = _, x0 = y0 = x1 = y1 = null, reset()) : postclip; + }; + + projection.clipAngle = function(_) { + return arguments.length ? (preclip = +_ ? clipCircle(theta = _ * radians) : (theta = null, clipAntimeridian), reset()) : theta * degrees$1; + }; + + projection.clipExtent = function(_) { + return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, identity$7) : clipRectangle(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]]; + }; + + projection.scale = function(_) { + return arguments.length ? (k = +_, recenter()) : k; + }; + + projection.translate = function(_) { + return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y]; + }; + + projection.center = function(_) { + return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees$1, phi * degrees$1]; + }; + + projection.rotate = function(_) { + return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees$1, deltaPhi * degrees$1, deltaGamma * degrees$1]; + }; + + projection.precision = function(_) { + return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt$2(delta2); + }; + + projection.fitExtent = function(extent, object) { + return fitExtent(projection, extent, object); + }; + + projection.fitSize = function(size, object) { + return fitSize(projection, size, object); + }; + + projection.fitWidth = function(width, object) { + return fitWidth(projection, width, object); + }; + + projection.fitHeight = function(height, object) { + return fitHeight(projection, height, object); + }; + + function recenter() { + projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project); + var center = project(lambda, phi); + dx = x - center[0] * k; + dy = y + center[1] * k; + return reset(); + } + + function reset() { + cache = cacheStream = null; + return projection; + } + + return function() { + project = projectAt.apply(this, arguments); + projection.invert = project.invert && invert; + return recenter(); + }; +} + +function conicProjection(projectAt) { + var phi0 = 0, + phi1 = pi$3 / 3, + m = projectionMutator(projectAt), + p = m(phi0, phi1); + + p.parallels = function(_) { + return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees$1, phi1 * degrees$1]; + }; + + return p; +} + +function cylindricalEqualAreaRaw(phi0) { + var cosPhi0 = cos$1(phi0); + + function forward(lambda, phi) { + return [lambda * cosPhi0, sin$1(phi) / cosPhi0]; + } + + forward.invert = function(x, y) { + return [x / cosPhi0, asin$1(y * cosPhi0)]; + }; + + return forward; +} + +function conicEqualAreaRaw(y0, y1) { + var sy0 = sin$1(y0), n = (sy0 + sin$1(y1)) / 2; + + // Are the parallels symmetrical around the Equator? + if (abs$1(n) < epsilon$2) return cylindricalEqualAreaRaw(y0); + + var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt$2(c) / n; + + function project(x, y) { + var r = sqrt$2(c - 2 * n * sin$1(y)) / n; + return [r * sin$1(x *= n), r0 - r * cos$1(x)]; + } + + project.invert = function(x, y) { + var r0y = r0 - y; + return [atan2$1(x, abs$1(r0y)) / n * sign$1(r0y), asin$1((c - (x * x + r0y * r0y) * n * n) / (2 * n))]; + }; + + return project; +} + +var conicEqualArea = function() { + return conicProjection(conicEqualAreaRaw) + .scale(155.424) + .center([0, 33.6442]); +}; + +var albers = function() { + return conicEqualArea() + .parallels([29.5, 45.5]) + .scale(1070) + .translate([480, 250]) + .rotate([96, 0]) + .center([-0.6, 38.7]); +}; + +// The projections must have mutually exclusive clip regions on the sphere, +// as this will avoid emitting interleaving lines and polygons. +function multiplex(streams) { + var n = streams.length; + return { + point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); }, + sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); }, + lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); }, + lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); }, + polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); }, + polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); } + }; +} + +// A composite projection for the United States, configured by default for +// 960×500. The projection also works quite well at 960×600 if you change the +// scale to 1285 and adjust the translate accordingly. The set of standard +// parallels for each region comes from USGS, which is published here: +// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers +var geoAlbersUsa = function() { + var cache, + cacheStream, + lower48 = albers(), lower48Point, + alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338 + hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007 + point, pointStream = {point: function(x, y) { point = [x, y]; }}; + + function albersUsa(coordinates) { + var x = coordinates[0], y = coordinates[1]; + return point = null, + (lower48Point.point(x, y), point) + || (alaskaPoint.point(x, y), point) + || (hawaiiPoint.point(x, y), point); + } + + albersUsa.invert = function(coordinates) { + var k = lower48.scale(), + t = lower48.translate(), + x = (coordinates[0] - t[0]) / k, + y = (coordinates[1] - t[1]) / k; + return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska + : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii + : lower48).invert(coordinates); + }; + + albersUsa.stream = function(stream) { + return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]); + }; + + albersUsa.precision = function(_) { + if (!arguments.length) return lower48.precision(); + lower48.precision(_), alaska.precision(_), hawaii.precision(_); + return reset(); + }; + + albersUsa.scale = function(_) { + if (!arguments.length) return lower48.scale(); + lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_); + return albersUsa.translate(lower48.translate()); + }; + + albersUsa.translate = function(_) { + if (!arguments.length) return lower48.translate(); + var k = lower48.scale(), x = +_[0], y = +_[1]; + + lower48Point = lower48 + .translate(_) + .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]]) + .stream(pointStream); + + alaskaPoint = alaska + .translate([x - 0.307 * k, y + 0.201 * k]) + .clipExtent([[x - 0.425 * k + epsilon$2, y + 0.120 * k + epsilon$2], [x - 0.214 * k - epsilon$2, y + 0.234 * k - epsilon$2]]) + .stream(pointStream); + + hawaiiPoint = hawaii + .translate([x - 0.205 * k, y + 0.212 * k]) + .clipExtent([[x - 0.214 * k + epsilon$2, y + 0.166 * k + epsilon$2], [x - 0.115 * k - epsilon$2, y + 0.234 * k - epsilon$2]]) + .stream(pointStream); + + return reset(); + }; + + albersUsa.fitExtent = function(extent, object) { + return fitExtent(albersUsa, extent, object); + }; + + albersUsa.fitSize = function(size, object) { + return fitSize(albersUsa, size, object); + }; + + albersUsa.fitWidth = function(width, object) { + return fitWidth(albersUsa, width, object); + }; + + albersUsa.fitHeight = function(height, object) { + return fitHeight(albersUsa, height, object); + }; + + function reset() { + cache = cacheStream = null; + return albersUsa; + } + + return albersUsa.scale(1070); +}; + +function azimuthalRaw(scale) { + return function(x, y) { + var cx = cos$1(x), + cy = cos$1(y), + k = scale(cx * cy); + return [ + k * cy * sin$1(x), + k * sin$1(y) + ]; + } +} + +function azimuthalInvert(angle) { + return function(x, y) { + var z = sqrt$2(x * x + y * y), + c = angle(z), + sc = sin$1(c), + cc = cos$1(c); + return [ + atan2$1(x * sc, z * cc), + asin$1(z && y * sc / z) + ]; + } +} + +var azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) { + return sqrt$2(2 / (1 + cxcy)); +}); + +azimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) { + return 2 * asin$1(z / 2); +}); + +var geoAzimuthalEqualArea = function() { + return projection$1(azimuthalEqualAreaRaw) + .scale(124.75) + .clipAngle(180 - 1e-3); +}; + +var azimuthalEquidistantRaw = azimuthalRaw(function(c) { + return (c = acos$1(c)) && c / sin$1(c); +}); + +azimuthalEquidistantRaw.invert = azimuthalInvert(function(z) { + return z; +}); + +var geoAzimuthalEquidistant = function() { + return projection$1(azimuthalEquidistantRaw) + .scale(79.4188) + .clipAngle(180 - 1e-3); +}; + +function mercatorRaw(lambda, phi) { + return [lambda, log$3(tan((halfPi$2 + phi) / 2))]; +} + +mercatorRaw.invert = function(x, y) { + return [x, 2 * atan(exp$1(y)) - halfPi$2]; +}; + +var geoMercator = function() { + return mercatorProjection(mercatorRaw) + .scale(961 / tau$4); +}; + +function mercatorProjection(project) { + var m = projection$1(project), + center = m.center, + scale = m.scale, + translate = m.translate, + clipExtent = m.clipExtent, + x0 = null, y0, x1, y1; // clip extent + + m.scale = function(_) { + return arguments.length ? (scale(_), reclip()) : scale(); + }; + + m.translate = function(_) { + return arguments.length ? (translate(_), reclip()) : translate(); + }; + + m.center = function(_) { + return arguments.length ? (center(_), reclip()) : center(); + }; + + m.clipExtent = function(_) { + return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]]; + }; + + function reclip() { + var k = pi$3 * scale(), + t = m(rotation(m.rotate()).invert([0, 0])); + return clipExtent(x0 == null + ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw + ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]] + : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]); + } + + return reclip(); +} + +function tany(y) { + return tan((halfPi$2 + y) / 2); +} + +function conicConformalRaw(y0, y1) { + var cy0 = cos$1(y0), + n = y0 === y1 ? sin$1(y0) : log$3(cy0 / cos$1(y1)) / log$3(tany(y1) / tany(y0)), + f = cy0 * pow$2(tany(y0), n) / n; + + if (!n) return mercatorRaw; + + function project(x, y) { + if (f > 0) { if (y < -halfPi$2 + epsilon$2) y = -halfPi$2 + epsilon$2; } + else { if (y > halfPi$2 - epsilon$2) y = halfPi$2 - epsilon$2; } + var r = f / pow$2(tany(y), n); + return [r * sin$1(n * x), f - r * cos$1(n * x)]; + } + + project.invert = function(x, y) { + var fy = f - y, r = sign$1(n) * sqrt$2(x * x + fy * fy); + return [atan2$1(x, abs$1(fy)) / n * sign$1(fy), 2 * atan(pow$2(f / r, 1 / n)) - halfPi$2]; + }; + + return project; +} + +var geoConicConformal = function() { + return conicProjection(conicConformalRaw) + .scale(109.5) + .parallels([30, 30]); +}; + +function equirectangularRaw(lambda, phi) { + return [lambda, phi]; +} + +equirectangularRaw.invert = equirectangularRaw; + +var geoEquirectangular = function() { + return projection$1(equirectangularRaw) + .scale(152.63); +}; + +function conicEquidistantRaw(y0, y1) { + var cy0 = cos$1(y0), + n = y0 === y1 ? sin$1(y0) : (cy0 - cos$1(y1)) / (y1 - y0), + g = cy0 / n + y0; + + if (abs$1(n) < epsilon$2) return equirectangularRaw; + + function project(x, y) { + var gy = g - y, nx = n * x; + return [gy * sin$1(nx), g - gy * cos$1(nx)]; + } + + project.invert = function(x, y) { + var gy = g - y; + return [atan2$1(x, abs$1(gy)) / n * sign$1(gy), g - sign$1(n) * sqrt$2(x * x + gy * gy)]; + }; + + return project; +} + +var geoConicEquidistant = function() { + return conicProjection(conicEquidistantRaw) + .scale(131.154) + .center([0, 13.9389]); +}; + +function gnomonicRaw(x, y) { + var cy = cos$1(y), k = cos$1(x) * cy; + return [cy * sin$1(x) / k, sin$1(y) / k]; +} + +gnomonicRaw.invert = azimuthalInvert(atan); + +var geoGnomonic = function() { + return projection$1(gnomonicRaw) + .scale(144.049) + .clipAngle(60); +}; + +function orthographicRaw(x, y) { + return [cos$1(y) * sin$1(x), sin$1(y)]; +} + +orthographicRaw.invert = azimuthalInvert(asin$1); + +var geoOrthographic = function() { + return projection$1(orthographicRaw) + .scale(249.5) + .clipAngle(90 + epsilon$2); +}; + +function stereographicRaw(x, y) { + var cy = cos$1(y), k = 1 + cos$1(x) * cy; + return [cy * sin$1(x) / k, sin$1(y) / k]; +} + +stereographicRaw.invert = azimuthalInvert(function(z) { + return 2 * atan(z); +}); + +var geoStereographic = function() { + return projection$1(stereographicRaw) + .scale(250) + .clipAngle(142); +}; + +function transverseMercatorRaw(lambda, phi) { + return [log$3(tan((halfPi$2 + phi) / 2)), -lambda]; +} + +transverseMercatorRaw.invert = function(x, y) { + return [-y, 2 * atan(exp$1(x)) - halfPi$2]; +}; + +var geoTransverseMercator = function() { + var m = mercatorProjection(transverseMercatorRaw), + center = m.center, + rotate = m.rotate; + + m.center = function(_) { + return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]); + }; + + m.rotate = function(_) { + return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]); + }; + + return rotate([0, 0, 90]) + .scale(159.155); +}; + +var defaultPath = geoPath(); + +var projectionProperties = [ + // standard properties in d3-geo + 'clipAngle', + 'clipExtent', + 'scale', + 'translate', + 'center', + 'rotate', + 'parallels', + 'precision', + + // extended properties in d3-geo-projections + 'coefficient', + 'distance', + 'fraction', + 'lobes', + 'parallel', + 'radius', + 'ratio', + 'spacing', + 'tilt' +]; + +/** + * Augment projections with their type and a copy method. + */ +function create$1(type, constructor) { + return function projection$$1() { + var p = constructor(); + + p.type = type; + + p.path = geoPath().projection(p); + + p.copy = p.copy || function() { + var c = projection$$1(); + projectionProperties.forEach(function(prop) { + if (p.hasOwnProperty(prop)) c[prop](p[prop]()); + }); + c.path.pointRadius(p.path.pointRadius()); + return c; + }; + + return p; + }; +} + +function projection$$1(type, proj) { + if (!type || typeof type !== 'string') { + throw new Error('Projection type must be a name string.'); + } + type = type.toLowerCase(); + if (arguments.length > 1) { + projections[type] = create$1(type, proj); + return this; + } else { + return projections.hasOwnProperty(type) ? projections[type] : null; + } +} + +function getProjectionPath(proj) { + return (proj && proj.path) || defaultPath; +} + +var projections = { + // base d3-geo projection types + albers: albers, + albersusa: geoAlbersUsa, + azimuthalequalarea: geoAzimuthalEqualArea, + azimuthalequidistant: geoAzimuthalEquidistant, + conicconformal: geoConicConformal, + conicequalarea: conicEqualArea, + conicequidistant: geoConicEquidistant, + equirectangular: geoEquirectangular, + gnomonic: geoGnomonic, + mercator: geoMercator, + orthographic: geoOrthographic, + stereographic: geoStereographic, + transversemercator: geoTransverseMercator +}; + +for (var key$2 in projections) { + projection$$1(key$2, projections[key$2]); +} + +/** + * Map GeoJSON data to an SVG path string. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(number, number): *} params.projection - The cartographic + * projection to apply. + * @param {function(object): *} [params.field] - The field with GeoJSON data, + * or null if the tuple itself is a GeoJSON feature. + * @param {string} [params.as='path'] - The output field in which to store + * the generated path data (default 'path'). + */ +function GeoPath(params) { + Transform.call(this, null, params); +} + +GeoPath.Definition = { + "type": "GeoPath", + "metadata": {"modifies": true}, + "params": [ + { "name": "projection", "type": "projection" }, + { "name": "field", "type": "field" }, + { "name": "pointRadius", "type": "number", "expr": true }, + { "name": "as", "type": "string", "default": "path" } + ] +}; + +var prototype$65 = inherits(GeoPath, Transform); + +prototype$65.transform = function(_, pulse) { + var out = pulse.fork(pulse.ALL), + path = this.value, + field$$1 = _.field || identity, + as = _.as || 'path', + flag = out.SOURCE; + + function set(t) { t[as] = path(field$$1(t)); } + + if (!path || _.modified()) { + // parameters updated, reset and reflow + this.value = path = getProjectionPath(_.projection); + out.materialize().reflow(); + } else { + flag = field$$1 === identity || pulse.modified(field$$1.fields) + ? out.ADD_MOD + : out.ADD; + } + + var prev = initPath(path, _.pointRadius); + out.visit(flag, set); + path.pointRadius(prev); + + return out.modifies(as); +}; + +function initPath(path, pointRadius) { + var prev = path.pointRadius(); + path.context(null); + if (pointRadius != null) { + path.pointRadius(pointRadius); + } + return prev; +} + +/** + * Geo-code a longitude/latitude point to an x/y coordinate. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(number, number): *} params.projection - The cartographic + * projection to apply. + * @param {Array} params.fields - A two-element array of + * field accessors for the longitude and latitude values. + * @param {Array} [params.as] - A two-element array of field names + * under which to store the result. Defaults to ['x','y']. + */ +function GeoPoint(params) { + Transform.call(this, null, params); +} + +GeoPoint.Definition = { + "type": "GeoPoint", + "metadata": {"modifies": true}, + "params": [ + { "name": "projection", "type": "projection", "required": true }, + { "name": "fields", "type": "field", "array": true, "required": true, "length": 2 }, + { "name": "as", "type": "string", "array": true, "length": 2, "default": ["x", "y"] } + ] +}; + +var prototype$66 = inherits(GeoPoint, Transform); + +prototype$66.transform = function(_, pulse) { + var proj = _.projection, + lon = _.fields[0], + lat = _.fields[1], + as = _.as || ['x', 'y'], + x = as[0], + y = as[1], + mod; + + function set(t) { + var xy = proj([lon(t), lat(t)]); + if (xy) { + t[x] = xy[0]; + t[y] = xy[1]; + } else { + t[x] = undefined; + t[y] = undefined; + } + } + + if (_.modified()) { + // parameters updated, reflow + pulse = pulse.materialize().reflow(true).visit(pulse.SOURCE, set); + } else { + mod = pulse.modified(lon.fields) || pulse.modified(lat.fields); + pulse.visit(mod ? pulse.ADD_MOD : pulse.ADD, set); + } + + return pulse.modifies(as); +}; + +/** + * Annotate items with a geopath shape generator. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {function(number, number): *} params.projection - The cartographic + * projection to apply. + * @param {function(object): *} [params.field] - The field with GeoJSON data, + * or null if the tuple itself is a GeoJSON feature. + * @param {string} [params.as='shape'] - The output field in which to store + * the generated path data (default 'shape'). + */ +function GeoShape(params) { + Transform.call(this, null, params); +} + +GeoShape.Definition = { + "type": "GeoShape", + "metadata": {"modifies": true}, + "params": [ + { "name": "projection", "type": "projection" }, + { "name": "field", "type": "field", "default": "datum" }, + { "name": "pointRadius", "type": "number", "expr": true }, + { "name": "as", "type": "string", "default": "shape" } + ] +}; + +var prototype$67 = inherits(GeoShape, Transform); + +prototype$67.transform = function(_, pulse) { + var out = pulse.fork(pulse.ALL), + shape = this.value, + datum = _.field || field('datum'), + as = _.as || 'shape', + flag = out.ADD_MOD; + + if (!shape || _.modified()) { + // parameters updated, reset and reflow + this.value = shape = shapeGenerator( + getProjectionPath(_.projection), + datum, + _.pointRadius + ); + out.materialize().reflow(); + flag = out.SOURCE; + } + + out.visit(flag, function(t) { t[as] = shape; }); + + return out.modifies(as); +}; + +function shapeGenerator(path, field$$1, pointRadius) { + var shape = pointRadius == null + ? function(_) { return path(field$$1(_)); } + : function(_) { + var prev = path.pointRadius(), + value = path.pointRadius(pointRadius)(field$$1(_)); + path.pointRadius(prev); + return value; + }; + shape.context = function(_) { + path.context(_); + return shape; + }; + + return shape; +} + +/** + * GeoJSON feature generator for creating graticules. + * @constructor + */ +function Graticule(params) { + Transform.call(this, [], params); + this.generator = graticule(); +} + +Graticule.Definition = { + "type": "Graticule", + "metadata": {"source": true, "generates": true, "changes": true}, + "params": [ + { "name": "extent", "type": "array", "array": true, "length": 2, + "content": {"type": "number", "array": true, "length": 2} }, + { "name": "extentMajor", "type": "array", "array": true, "length": 2, + "content": {"type": "number", "array": true, "length": 2} }, + { "name": "extentMinor", "type": "array", "array": true, "length": 2, + "content": {"type": "number", "array": true, "length": 2} }, + { "name": "step", "type": "number", "array": true, "length": 2 }, + { "name": "stepMajor", "type": "number", "array": true, "length": 2, "default": [90, 360] }, + { "name": "stepMinor", "type": "number", "array": true, "length": 2, "default": [10, 10] }, + { "name": "precision", "type": "number", "default": 2.5 } + ] +}; + +var prototype$68 = inherits(Graticule, Transform); + +prototype$68.transform = function(_, pulse) { + var out = pulse.fork(), + src = this.value, + gen = this.generator, t; + + if (!src.length || _.modified()) { + for (var prop in _) { + if (isFunction(gen[prop])) { + gen[prop](_[prop]); + } + } + } + + t = gen(); + if (src.length) { + out.mod.push(replace(src[0], t)); + } else { + out.add.push(ingest(t)); + } + src[0] = t; + out.source = src; + + return out; +}; + +/** + * Maintains a cartographic projection. + * @constructor + * @param {object} params - The parameters for this operator. + */ +function Projection(params) { + Transform.call(this, null, params); + this.modified(true); // always treat as modified +} + +var prototype$69 = inherits(Projection, Transform); + +prototype$69.transform = function(_, pulse) { + var proj = this.value; + + if (!proj || _.modified('type')) { + this.value = (proj = create$2(_.type)); + projectionProperties.forEach(function(prop) { + if (_[prop] != null) set$4(proj, prop, _[prop]); + }); + } else { + projectionProperties.forEach(function(prop) { + if (_.modified(prop)) set$4(proj, prop, _[prop]); + }); + } + + if (_.pointRadius != null) proj.path.pointRadius(_.pointRadius); + if (_.fit) fit$1(proj, _); + + return pulse.fork(pulse.NO_SOURCE | pulse.NO_FIELDS); +}; + +function fit$1(proj, _) { + var data = collectGeoJSON(_.fit); + _.extent ? proj.fitExtent(_.extent, data) + : _.size ? proj.fitSize(_.size, data) : 0; +} + +function create$2(type) { + var constructor = projection$$1((type || 'mercator').toLowerCase()); + if (!constructor) error$1('Unrecognized projection type: ' + type); + return constructor(); +} + +function set$4(proj, key$$1, value) { + if (isFunction(proj[key$$1])) proj[key$$1](value); +} + +function collectGeoJSON(features) { + features = array(features); + return features.length === 1 + ? features[0] + : { + type: FeatureCollection, + features: features.reduce(function(list, f) { + (f && f.type === FeatureCollection) ? list.push.apply(list, f.features) + : isArray(f) ? list.push.apply(list, f) + : list.push(f); + return list; + }, []) + }; +} + + + +var geo = Object.freeze({ + contour: Contour, + geojson: GeoJSON, + geopath: GeoPath, + geopoint: GeoPoint, + geoshape: GeoShape, + graticule: Graticule, + projection: Projection +}); + +var forceCenter = function(x, y) { + var nodes; + + if (x == null) x = 0; + if (y == null) y = 0; + + function force() { + var i, + n = nodes.length, + node, + sx = 0, + sy = 0; + + for (i = 0; i < n; ++i) { + node = nodes[i], sx += node.x, sy += node.y; + } + + for (sx = sx / n - x, sy = sy / n - y, i = 0; i < n; ++i) { + node = nodes[i], node.x -= sx, node.y -= sy; + } + } + + force.initialize = function(_) { + nodes = _; + }; + + force.x = function(_) { + return arguments.length ? (x = +_, force) : x; + }; + + force.y = function(_) { + return arguments.length ? (y = +_, force) : y; + }; + + return force; +}; + +var constant$8 = function(x) { + return function() { + return x; + }; +}; + +var jiggle = function() { + return (Math.random() - 0.5) * 1e-6; +}; + +var tree_add = function(d) { + var x = +this._x.call(null, d), + y = +this._y.call(null, d); + return add$4(this.cover(x, y), x, y, d); +}; + +function add$4(tree, x, y, d) { + if (isNaN(x) || isNaN(y)) return tree; // ignore invalid points + + var parent, + node = tree._root, + leaf = {data: d}, + x0 = tree._x0, + y0 = tree._y0, + x1 = tree._x1, + y1 = tree._y1, + xm, + ym, + xp, + yp, + right, + bottom, + i, + j; + + // If the tree is empty, initialize the root as a leaf. + if (!node) return tree._root = leaf, tree; + + // Find the existing leaf for the new point, or add it. + while (node.length) { + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + if (parent = node, !(node = node[i = bottom << 1 | right])) return parent[i] = leaf, tree; + } + + // Is the new point is exactly coincident with the existing point? + xp = +tree._x.call(null, node.data); + yp = +tree._y.call(null, node.data); + if (x === xp && y === yp) return leaf.next = node, parent ? parent[i] = leaf : tree._root = leaf, tree; + + // Otherwise, split the leaf node until the old and new point are separated. + do { + parent = parent ? parent[i] = new Array(4) : tree._root = new Array(4); + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + } while ((i = bottom << 1 | right) === (j = (yp >= ym) << 1 | (xp >= xm))); + return parent[j] = node, parent[i] = leaf, tree; +} + +function addAll$1(data) { + var d, i, n = data.length, + x, + y, + xz = new Array(n), + yz = new Array(n), + x0 = Infinity, + y0 = Infinity, + x1 = -Infinity, + y1 = -Infinity; + + // Compute the points and their extent. + for (i = 0; i < n; ++i) { + if (isNaN(x = +this._x.call(null, d = data[i])) || isNaN(y = +this._y.call(null, d))) continue; + xz[i] = x; + yz[i] = y; + if (x < x0) x0 = x; + if (x > x1) x1 = x; + if (y < y0) y0 = y; + if (y > y1) y1 = y; + } + + // If there were no (valid) points, inherit the existing extent. + if (x1 < x0) x0 = this._x0, x1 = this._x1; + if (y1 < y0) y0 = this._y0, y1 = this._y1; + + // Expand the tree to cover the new points. + this.cover(x0, y0).cover(x1, y1); + + // Add the new points. + for (i = 0; i < n; ++i) { + add$4(this, xz[i], yz[i], data[i]); + } + + return this; +} + +var tree_cover = function(x, y) { + if (isNaN(x = +x) || isNaN(y = +y)) return this; // ignore invalid points + + var x0 = this._x0, + y0 = this._y0, + x1 = this._x1, + y1 = this._y1; + + // If the quadtree has no extent, initialize them. + // Integer extent are necessary so that if we later double the extent, + // the existing quadrant boundaries don’t change due to floating point error! + if (isNaN(x0)) { + x1 = (x0 = Math.floor(x)) + 1; + y1 = (y0 = Math.floor(y)) + 1; + } + + // Otherwise, double repeatedly to cover. + else if (x0 > x || x > x1 || y0 > y || y > y1) { + var z = x1 - x0, + node = this._root, + parent, + i; + + switch (i = (y < (y0 + y1) / 2) << 1 | (x < (x0 + x1) / 2)) { + case 0: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x1 = x0 + z, y1 = y0 + z, x > x1 || y > y1); + break; + } + case 1: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x0 = x1 - z, y1 = y0 + z, x0 > x || y > y1); + break; + } + case 2: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x1 = x0 + z, y0 = y1 - z, x > x1 || y0 > y); + break; + } + case 3: { + do parent = new Array(4), parent[i] = node, node = parent; + while (z *= 2, x0 = x1 - z, y0 = y1 - z, x0 > x || y0 > y); + break; + } + } + + if (this._root && this._root.length) this._root = node; + } + + // If the quadtree covers the point already, just return. + else return this; + + this._x0 = x0; + this._y0 = y0; + this._x1 = x1; + this._y1 = y1; + return this; +}; + +var tree_data = function() { + var data = []; + this.visit(function(node) { + if (!node.length) do data.push(node.data); while (node = node.next) + }); + return data; +}; + +var tree_extent = function(_) { + return arguments.length + ? this.cover(+_[0][0], +_[0][1]).cover(+_[1][0], +_[1][1]) + : isNaN(this._x0) ? undefined : [[this._x0, this._y0], [this._x1, this._y1]]; +}; + +var Quad = function(node, x0, y0, x1, y1) { + this.node = node; + this.x0 = x0; + this.y0 = y0; + this.x1 = x1; + this.y1 = y1; +}; + +var tree_find = function(x, y, radius) { + var data, + x0 = this._x0, + y0 = this._y0, + x1, + y1, + x2, + y2, + x3 = this._x1, + y3 = this._y1, + quads = [], + node = this._root, + q, + i; + + if (node) quads.push(new Quad(node, x0, y0, x3, y3)); + if (radius == null) radius = Infinity; + else { + x0 = x - radius, y0 = y - radius; + x3 = x + radius, y3 = y + radius; + radius *= radius; + } + + while (q = quads.pop()) { + + // Stop searching if this quadrant can’t contain a closer node. + if (!(node = q.node) + || (x1 = q.x0) > x3 + || (y1 = q.y0) > y3 + || (x2 = q.x1) < x0 + || (y2 = q.y1) < y0) continue; + + // Bisect the current quadrant. + if (node.length) { + var xm = (x1 + x2) / 2, + ym = (y1 + y2) / 2; + + quads.push( + new Quad(node[3], xm, ym, x2, y2), + new Quad(node[2], x1, ym, xm, y2), + new Quad(node[1], xm, y1, x2, ym), + new Quad(node[0], x1, y1, xm, ym) + ); + + // Visit the closest quadrant first. + if (i = (y >= ym) << 1 | (x >= xm)) { + q = quads[quads.length - 1]; + quads[quads.length - 1] = quads[quads.length - 1 - i]; + quads[quads.length - 1 - i] = q; + } + } + + // Visit this point. (Visiting coincident points isn’t necessary!) + else { + var dx = x - +this._x.call(null, node.data), + dy = y - +this._y.call(null, node.data), + d2 = dx * dx + dy * dy; + if (d2 < radius) { + var d = Math.sqrt(radius = d2); + x0 = x - d, y0 = y - d; + x3 = x + d, y3 = y + d; + data = node.data; + } + } + } + + return data; +}; + +var tree_remove = function(d) { + if (isNaN(x = +this._x.call(null, d)) || isNaN(y = +this._y.call(null, d))) return this; // ignore invalid points + + var parent, + node = this._root, + retainer, + previous, + next, + x0 = this._x0, + y0 = this._y0, + x1 = this._x1, + y1 = this._y1, + x, + y, + xm, + ym, + right, + bottom, + i, + j; + + // If the tree is empty, initialize the root as a leaf. + if (!node) return this; + + // Find the leaf node for the point. + // While descending, also retain the deepest parent with a non-removed sibling. + if (node.length) while (true) { + if (right = x >= (xm = (x0 + x1) / 2)) x0 = xm; else x1 = xm; + if (bottom = y >= (ym = (y0 + y1) / 2)) y0 = ym; else y1 = ym; + if (!(parent = node, node = node[i = bottom << 1 | right])) return this; + if (!node.length) break; + if (parent[(i + 1) & 3] || parent[(i + 2) & 3] || parent[(i + 3) & 3]) retainer = parent, j = i; + } + + // Find the point to remove. + while (node.data !== d) if (!(previous = node, node = node.next)) return this; + if (next = node.next) delete node.next; + + // If there are multiple coincident points, remove just the point. + if (previous) return (next ? previous.next = next : delete previous.next), this; + + // If this is the root point, remove it. + if (!parent) return this._root = next, this; + + // Remove this leaf. + next ? parent[i] = next : delete parent[i]; + + // If the parent now contains exactly one leaf, collapse superfluous parents. + if ((node = parent[0] || parent[1] || parent[2] || parent[3]) + && node === (parent[3] || parent[2] || parent[1] || parent[0]) + && !node.length) { + if (retainer) retainer[j] = node; + else this._root = node; + } + + return this; +}; + +function removeAll(data) { + for (var i = 0, n = data.length; i < n; ++i) this.remove(data[i]); + return this; +} + +var tree_root = function() { + return this._root; +}; + +var tree_size = function() { + var size = 0; + this.visit(function(node) { + if (!node.length) do ++size; while (node = node.next) + }); + return size; +}; + +var tree_visit = function(callback) { + var quads = [], q, node = this._root, child, x0, y0, x1, y1; + if (node) quads.push(new Quad(node, this._x0, this._y0, this._x1, this._y1)); + while (q = quads.pop()) { + if (!callback(node = q.node, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1) && node.length) { + var xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; + if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); + if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); + if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); + } + } + return this; +}; + +var tree_visitAfter = function(callback) { + var quads = [], next = [], q; + if (this._root) quads.push(new Quad(this._root, this._x0, this._y0, this._x1, this._y1)); + while (q = quads.pop()) { + var node = q.node; + if (node.length) { + var child, x0 = q.x0, y0 = q.y0, x1 = q.x1, y1 = q.y1, xm = (x0 + x1) / 2, ym = (y0 + y1) / 2; + if (child = node[0]) quads.push(new Quad(child, x0, y0, xm, ym)); + if (child = node[1]) quads.push(new Quad(child, xm, y0, x1, ym)); + if (child = node[2]) quads.push(new Quad(child, x0, ym, xm, y1)); + if (child = node[3]) quads.push(new Quad(child, xm, ym, x1, y1)); + } + next.push(q); + } + while (q = next.pop()) { + callback(q.node, q.x0, q.y0, q.x1, q.y1); + } + return this; +}; + +function defaultX$1(d) { + return d[0]; +} + +var tree_x = function(_) { + return arguments.length ? (this._x = _, this) : this._x; +}; + +function defaultY$1(d) { + return d[1]; +} + +var tree_y = function(_) { + return arguments.length ? (this._y = _, this) : this._y; +}; + +function quadtree(nodes, x, y) { + var tree = new Quadtree(x == null ? defaultX$1 : x, y == null ? defaultY$1 : y, NaN, NaN, NaN, NaN); + return nodes == null ? tree : tree.addAll(nodes); +} + +function Quadtree(x, y, x0, y0, x1, y1) { + this._x = x; + this._y = y; + this._x0 = x0; + this._y0 = y0; + this._x1 = x1; + this._y1 = y1; + this._root = undefined; +} + +function leaf_copy(leaf) { + var copy = {data: leaf.data}, next = copy; + while (leaf = leaf.next) next = next.next = {data: leaf.data}; + return copy; +} + +var treeProto = quadtree.prototype = Quadtree.prototype; + +treeProto.copy = function() { + var copy = new Quadtree(this._x, this._y, this._x0, this._y0, this._x1, this._y1), + node = this._root, + nodes, + child; + + if (!node) return copy; + + if (!node.length) return copy._root = leaf_copy(node), copy; + + nodes = [{source: node, target: copy._root = new Array(4)}]; + while (node = nodes.pop()) { + for (var i = 0; i < 4; ++i) { + if (child = node.source[i]) { + if (child.length) nodes.push({source: child, target: node.target[i] = new Array(4)}); + else node.target[i] = leaf_copy(child); + } + } + } + + return copy; +}; + +treeProto.add = tree_add; +treeProto.addAll = addAll$1; +treeProto.cover = tree_cover; +treeProto.data = tree_data; +treeProto.extent = tree_extent; +treeProto.find = tree_find; +treeProto.remove = tree_remove; +treeProto.removeAll = removeAll; +treeProto.root = tree_root; +treeProto.size = tree_size; +treeProto.visit = tree_visit; +treeProto.visitAfter = tree_visitAfter; +treeProto.x = tree_x; +treeProto.y = tree_y; + +function x$2(d) { + return d.x + d.vx; +} + +function y$2(d) { + return d.y + d.vy; +} + +var forceCollide = function(radius) { + var nodes, + radii, + strength = 1, + iterations = 1; + + if (typeof radius !== "function") radius = constant$8(radius == null ? 1 : +radius); + + function force() { + var i, n = nodes.length, + tree, + node, + xi, + yi, + ri, + ri2; + + for (var k = 0; k < iterations; ++k) { + tree = quadtree(nodes, x$2, y$2).visitAfter(prepare); + for (i = 0; i < n; ++i) { + node = nodes[i]; + ri = radii[node.index], ri2 = ri * ri; + xi = node.x + node.vx; + yi = node.y + node.vy; + tree.visit(apply); + } + } + + function apply(quad, x0, y0, x1, y1) { + var data = quad.data, rj = quad.r, r = ri + rj; + if (data) { + if (data.index > node.index) { + var x = xi - data.x - data.vx, + y = yi - data.y - data.vy, + l = x * x + y * y; + if (l < r * r) { + if (x === 0) x = jiggle(), l += x * x; + if (y === 0) y = jiggle(), l += y * y; + l = (r - (l = Math.sqrt(l))) / l * strength; + node.vx += (x *= l) * (r = (rj *= rj) / (ri2 + rj)); + node.vy += (y *= l) * r; + data.vx -= x * (r = 1 - r); + data.vy -= y * r; + } + } + return; + } + return x0 > xi + r || x1 < xi - r || y0 > yi + r || y1 < yi - r; + } + } + + function prepare(quad) { + if (quad.data) return quad.r = radii[quad.data.index]; + for (var i = quad.r = 0; i < 4; ++i) { + if (quad[i] && quad[i].r > quad.r) { + quad.r = quad[i].r; + } + } + } + + function initialize() { + if (!nodes) return; + var i, n = nodes.length, node; + radii = new Array(n); + for (i = 0; i < n; ++i) node = nodes[i], radii[node.index] = +radius(node, i, nodes); + } + + force.initialize = function(_) { + nodes = _; + initialize(); + }; + + force.iterations = function(_) { + return arguments.length ? (iterations = +_, force) : iterations; + }; + + force.strength = function(_) { + return arguments.length ? (strength = +_, force) : strength; + }; + + force.radius = function(_) { + return arguments.length ? (radius = typeof _ === "function" ? _ : constant$8(+_), initialize(), force) : radius; + }; + + return force; +}; + +function index(d) { + return d.index; +} + +function find(nodeById, nodeId) { + var node = nodeById.get(nodeId); + if (!node) throw new Error("missing: " + nodeId); + return node; +} + +var forceLink = function(links) { + var id = index, + strength = defaultStrength, + strengths, + distance = constant$8(30), + distances, + nodes, + count, + bias, + iterations = 1; + + if (links == null) links = []; + + function defaultStrength(link) { + return 1 / Math.min(count[link.source.index], count[link.target.index]); + } + + function force(alpha) { + for (var k = 0, n = links.length; k < iterations; ++k) { + for (var i = 0, link, source, target, x, y, l, b; i < n; ++i) { + link = links[i], source = link.source, target = link.target; + x = target.x + target.vx - source.x - source.vx || jiggle(); + y = target.y + target.vy - source.y - source.vy || jiggle(); + l = Math.sqrt(x * x + y * y); + l = (l - distances[i]) / l * alpha * strengths[i]; + x *= l, y *= l; + target.vx -= x * (b = bias[i]); + target.vy -= y * b; + source.vx += x * (b = 1 - b); + source.vy += y * b; + } + } + } + + function initialize() { + if (!nodes) return; + + var i, + n = nodes.length, + m = links.length, + nodeById = map(nodes, id), + link; + + for (i = 0, count = new Array(n); i < m; ++i) { + link = links[i], link.index = i; + if (typeof link.source !== "object") link.source = find(nodeById, link.source); + if (typeof link.target !== "object") link.target = find(nodeById, link.target); + count[link.source.index] = (count[link.source.index] || 0) + 1; + count[link.target.index] = (count[link.target.index] || 0) + 1; + } + + for (i = 0, bias = new Array(m); i < m; ++i) { + link = links[i], bias[i] = count[link.source.index] / (count[link.source.index] + count[link.target.index]); + } + + strengths = new Array(m), initializeStrength(); + distances = new Array(m), initializeDistance(); + } + + function initializeStrength() { + if (!nodes) return; + + for (var i = 0, n = links.length; i < n; ++i) { + strengths[i] = +strength(links[i], i, links); + } + } + + function initializeDistance() { + if (!nodes) return; + + for (var i = 0, n = links.length; i < n; ++i) { + distances[i] = +distance(links[i], i, links); + } + } + + force.initialize = function(_) { + nodes = _; + initialize(); + }; + + force.links = function(_) { + return arguments.length ? (links = _, initialize(), force) : links; + }; + + force.id = function(_) { + return arguments.length ? (id = _, force) : id; + }; + + force.iterations = function(_) { + return arguments.length ? (iterations = +_, force) : iterations; + }; + + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$8(+_), initializeStrength(), force) : strength; + }; + + force.distance = function(_) { + return arguments.length ? (distance = typeof _ === "function" ? _ : constant$8(+_), initializeDistance(), force) : distance; + }; + + return force; +}; + +var frame = 0; +var timeout = 0; +var interval = 0; +var pokeDelay = 1000; +var taskHead; +var taskTail; +var clockLast = 0; +var clockNow = 0; +var clockSkew = 0; +var clock = typeof performance === "object" && performance.now ? performance : Date; +var setFrame = typeof window === "object" && window.requestAnimationFrame ? window.requestAnimationFrame.bind(window) : function(f) { setTimeout(f, 17); }; + +function now() { + return clockNow || (setFrame(clearNow), clockNow = clock.now() + clockSkew); +} + +function clearNow() { + clockNow = 0; +} + +function Timer() { + this._call = + this._time = + this._next = null; +} + +Timer.prototype = timer.prototype = { + constructor: Timer, + restart: function(callback, delay, time) { + if (typeof callback !== "function") throw new TypeError("callback is not a function"); + time = (time == null ? now() : +time) + (delay == null ? 0 : +delay); + if (!this._next && taskTail !== this) { + if (taskTail) taskTail._next = this; + else taskHead = this; + taskTail = this; + } + this._call = callback; + this._time = time; + sleep(); + }, + stop: function() { + if (this._call) { + this._call = null; + this._time = Infinity; + sleep(); + } + } +}; + +function timer(callback, delay, time) { + var t = new Timer; + t.restart(callback, delay, time); + return t; +} + +function timerFlush() { + now(); // Get the current time, if not already set. + ++frame; // Pretend we’ve set an alarm, if we haven’t already. + var t = taskHead, e; + while (t) { + if ((e = clockNow - t._time) >= 0) t._call.call(null, e); + t = t._next; + } + --frame; +} + +function wake() { + clockNow = (clockLast = clock.now()) + clockSkew; + frame = timeout = 0; + try { + timerFlush(); + } finally { + frame = 0; + nap(); + clockNow = 0; + } +} + +function poke() { + var now = clock.now(), delay = now - clockLast; + if (delay > pokeDelay) clockSkew -= delay, clockLast = now; +} + +function nap() { + var t0, t1 = taskHead, t2, time = Infinity; + while (t1) { + if (t1._call) { + if (time > t1._time) time = t1._time; + t0 = t1, t1 = t1._next; + } else { + t2 = t1._next, t1._next = null; + t1 = t0 ? t0._next = t2 : taskHead = t2; + } + } + taskTail = t0; + sleep(time); +} + +function sleep(time) { + if (frame) return; // Soonest alarm already set, or will be. + if (timeout) timeout = clearTimeout(timeout); + var delay = time - clockNow; // Strictly less than if we recomputed clockNow. + if (delay > 24) { + if (time < Infinity) timeout = setTimeout(wake, time - clock.now() - clockSkew); + if (interval) interval = clearInterval(interval); + } else { + if (!interval) clockLast = clock.now(), interval = setInterval(poke, pokeDelay); + frame = 1, setFrame(wake); + } +} + +function x$3(d) { + return d.x; +} + +function y$3(d) { + return d.y; +} + +var initialRadius = 10; +var initialAngle = Math.PI * (3 - Math.sqrt(5)); + +var forceSimulation = function(nodes) { + var simulation, + alpha = 1, + alphaMin = 0.001, + alphaDecay = 1 - Math.pow(alphaMin, 1 / 300), + alphaTarget = 0, + velocityDecay = 0.6, + forces = map(), + stepper = timer(step), + event = dispatch("tick", "end"); + + if (nodes == null) nodes = []; + + function step() { + tick(); + event.call("tick", simulation); + if (alpha < alphaMin) { + stepper.stop(); + event.call("end", simulation); + } + } + + function tick() { + var i, n = nodes.length, node; + + alpha += (alphaTarget - alpha) * alphaDecay; + + forces.each(function(force) { + force(alpha); + }); + + for (i = 0; i < n; ++i) { + node = nodes[i]; + if (node.fx == null) node.x += node.vx *= velocityDecay; + else node.x = node.fx, node.vx = 0; + if (node.fy == null) node.y += node.vy *= velocityDecay; + else node.y = node.fy, node.vy = 0; + } + } + + function initializeNodes() { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.index = i; + if (isNaN(node.x) || isNaN(node.y)) { + var radius = initialRadius * Math.sqrt(i), angle = i * initialAngle; + node.x = radius * Math.cos(angle); + node.y = radius * Math.sin(angle); + } + if (isNaN(node.vx) || isNaN(node.vy)) { + node.vx = node.vy = 0; + } + } + } + + function initializeForce(force) { + if (force.initialize) force.initialize(nodes); + return force; + } + + initializeNodes(); + + return simulation = { + tick: tick, + + restart: function() { + return stepper.restart(step), simulation; + }, + + stop: function() { + return stepper.stop(), simulation; + }, + + nodes: function(_) { + return arguments.length ? (nodes = _, initializeNodes(), forces.each(initializeForce), simulation) : nodes; + }, + + alpha: function(_) { + return arguments.length ? (alpha = +_, simulation) : alpha; + }, + + alphaMin: function(_) { + return arguments.length ? (alphaMin = +_, simulation) : alphaMin; + }, + + alphaDecay: function(_) { + return arguments.length ? (alphaDecay = +_, simulation) : +alphaDecay; + }, + + alphaTarget: function(_) { + return arguments.length ? (alphaTarget = +_, simulation) : alphaTarget; + }, + + velocityDecay: function(_) { + return arguments.length ? (velocityDecay = 1 - _, simulation) : 1 - velocityDecay; + }, + + force: function(name, _) { + return arguments.length > 1 ? ((_ == null ? forces.remove(name) : forces.set(name, initializeForce(_))), simulation) : forces.get(name); + }, + + find: function(x, y, radius) { + var i = 0, + n = nodes.length, + dx, + dy, + d2, + node, + closest; + + if (radius == null) radius = Infinity; + else radius *= radius; + + for (i = 0; i < n; ++i) { + node = nodes[i]; + dx = x - node.x; + dy = y - node.y; + d2 = dx * dx + dy * dy; + if (d2 < radius) closest = node, radius = d2; + } + + return closest; + }, + + on: function(name, _) { + return arguments.length > 1 ? (event.on(name, _), simulation) : event.on(name); + } + }; +}; + +var forceManyBody = function() { + var nodes, + node, + alpha, + strength = constant$8(-30), + strengths, + distanceMin2 = 1, + distanceMax2 = Infinity, + theta2 = 0.81; + + function force(_) { + var i, n = nodes.length, tree = quadtree(nodes, x$3, y$3).visitAfter(accumulate); + for (alpha = _, i = 0; i < n; ++i) node = nodes[i], tree.visit(apply); + } + + function initialize() { + if (!nodes) return; + var i, n = nodes.length, node; + strengths = new Array(n); + for (i = 0; i < n; ++i) node = nodes[i], strengths[node.index] = +strength(node, i, nodes); + } + + function accumulate(quad) { + var strength = 0, q, c, weight = 0, x, y, i; + + // For internal nodes, accumulate forces from child quadrants. + if (quad.length) { + for (x = y = i = 0; i < 4; ++i) { + if ((q = quad[i]) && (c = Math.abs(q.value))) { + strength += q.value, weight += c, x += c * q.x, y += c * q.y; + } + } + quad.x = x / weight; + quad.y = y / weight; + } + + // For leaf nodes, accumulate forces from coincident quadrants. + else { + q = quad; + q.x = q.data.x; + q.y = q.data.y; + do strength += strengths[q.data.index]; + while (q = q.next); + } + + quad.value = strength; + } + + function apply(quad, x1, _, x2) { + if (!quad.value) return true; + + var x = quad.x - node.x, + y = quad.y - node.y, + w = x2 - x1, + l = x * x + y * y; + + // Apply the Barnes-Hut approximation if possible. + // Limit forces for very close nodes; randomize direction if coincident. + if (w * w / theta2 < l) { + if (l < distanceMax2) { + if (x === 0) x = jiggle(), l += x * x; + if (y === 0) y = jiggle(), l += y * y; + if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + node.vx += x * quad.value * alpha / l; + node.vy += y * quad.value * alpha / l; + } + return true; + } + + // Otherwise, process points directly. + else if (quad.length || l >= distanceMax2) return; + + // Limit forces for very close nodes; randomize direction if coincident. + if (quad.data !== node || quad.next) { + if (x === 0) x = jiggle(), l += x * x; + if (y === 0) y = jiggle(), l += y * y; + if (l < distanceMin2) l = Math.sqrt(distanceMin2 * l); + } + + do if (quad.data !== node) { + w = strengths[quad.data.index] * alpha / l; + node.vx += x * w; + node.vy += y * w; + } while (quad = quad.next); + } + + force.initialize = function(_) { + nodes = _; + initialize(); + }; + + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$8(+_), initialize(), force) : strength; + }; + + force.distanceMin = function(_) { + return arguments.length ? (distanceMin2 = _ * _, force) : Math.sqrt(distanceMin2); + }; + + force.distanceMax = function(_) { + return arguments.length ? (distanceMax2 = _ * _, force) : Math.sqrt(distanceMax2); + }; + + force.theta = function(_) { + return arguments.length ? (theta2 = _ * _, force) : Math.sqrt(theta2); + }; + + return force; +}; + +var forceX = function(x) { + var strength = constant$8(0.1), + nodes, + strengths, + xz; + + if (typeof x !== "function") x = constant$8(x == null ? 0 : +x); + + function force(alpha) { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.vx += (xz[i] - node.x) * strengths[i] * alpha; + } + } + + function initialize() { + if (!nodes) return; + var i, n = nodes.length; + strengths = new Array(n); + xz = new Array(n); + for (i = 0; i < n; ++i) { + strengths[i] = isNaN(xz[i] = +x(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); + } + } + + force.initialize = function(_) { + nodes = _; + initialize(); + }; + + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$8(+_), initialize(), force) : strength; + }; + + force.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : constant$8(+_), initialize(), force) : x; + }; + + return force; +}; + +var forceY = function(y) { + var strength = constant$8(0.1), + nodes, + strengths, + yz; + + if (typeof y !== "function") y = constant$8(y == null ? 0 : +y); + + function force(alpha) { + for (var i = 0, n = nodes.length, node; i < n; ++i) { + node = nodes[i], node.vy += (yz[i] - node.y) * strengths[i] * alpha; + } + } + + function initialize() { + if (!nodes) return; + var i, n = nodes.length; + strengths = new Array(n); + yz = new Array(n); + for (i = 0; i < n; ++i) { + strengths[i] = isNaN(yz[i] = +y(nodes[i], i, nodes)) ? 0 : +strength(nodes[i], i, nodes); + } + } + + force.initialize = function(_) { + nodes = _; + initialize(); + }; + + force.strength = function(_) { + return arguments.length ? (strength = typeof _ === "function" ? _ : constant$8(+_), initialize(), force) : strength; + }; + + force.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : constant$8(+_), initialize(), force) : y; + }; + + return force; +}; + +var ForceMap = { + center: forceCenter, + collide: forceCollide, + nbody: forceManyBody, + link: forceLink, + x: forceX, + y: forceY +}; + +var Forces = 'forces'; +var ForceParams = [ + 'alpha', 'alphaMin', 'alphaTarget', + 'velocityDecay', 'forces' + ]; +var ForceConfig = ['static', 'iterations']; +var ForceOutput = ['x', 'y', 'vx', 'vy']; + +/** + * Force simulation layout. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} params.forces - The forces to apply. + */ +function Force(params) { + Transform.call(this, null, params); +} + +Force.Definition = { + "type": "Force", + "metadata": {"modifies": true}, + "params": [ + { "name": "static", "type": "boolean", "default": false }, + { "name": "restart", "type": "boolean", "default": false }, + { "name": "iterations", "type": "number", "default": 300 }, + { "name": "alpha", "type": "number", "default": 1 }, + { "name": "alphaMin", "type": "number", "default": 0.001 }, + { "name": "alphaTarget", "type": "number", "default": 0 }, + { "name": "velocityDecay", "type": "number", "default": 0.4 }, + { "name": "forces", "type": "param", "array": true, + "params": [ + { + "key": {"force": "center"}, + "params": [ + { "name": "x", "type": "number", "default": 0 }, + { "name": "y", "type": "number", "default": 0 } + ] + }, + { + "key": {"force": "collide"}, + "params": [ + { "name": "radius", "type": "number", "expr": true }, + { "name": "strength", "type": "number", "default": 0.7 }, + { "name": "iterations", "type": "number", "default": 1 } + ] + }, + { + "key": {"force": "nbody"}, + "params": [ + { "name": "strength", "type": "number", "default": -30 }, + { "name": "theta", "type": "number", "default": 0.9 }, + { "name": "distanceMin", "type": "number", "default": 1 }, + { "name": "distanceMax", "type": "number" } + ] + }, + { + "key": {"force": "link"}, + "params": [ + { "name": "links", "type": "data" }, + { "name": "id", "type": "field" }, + { "name": "distance", "type": "number", "default": 30, "expr": true }, + { "name": "strength", "type": "number", "expr": true }, + { "name": "iterations", "type": "number", "default": 1 } + ] + }, + { + "key": {"force": "x"}, + "params": [ + { "name": "strength", "type": "number", "default": 0.1 }, + { "name": "x", "type": "field" } + ] + }, + { + "key": {"force": "y"}, + "params": [ + { "name": "strength", "type": "number", "default": 0.1 }, + { "name": "y", "type": "field" } + ] + } + ] }, + { + "name": "as", "type": "string", "array": true, "modify": false, + "default": ForceOutput + } + ] +}; + +var prototype$70 = inherits(Force, Transform); + +prototype$70.transform = function(_, pulse) { + var sim = this.value, + change = pulse.changed(pulse.ADD_REM), + params = _.modified(ForceParams), + iters = _.iterations || 300; + + // configure simulation + if (!sim) { + this.value = sim = simulation(pulse.source, _); + sim.on('tick', rerun(pulse.dataflow, this)); + if (!_.static) { + change = true; + sim.tick(); // ensure we run on init + } + pulse.modifies('index'); + } else { + if (change) { + pulse.modifies('index'); + sim.nodes(pulse.source); + } + if (params || pulse.changed(pulse.MOD)) { + setup(sim, _, 0, pulse); + } + } + + // run simulation + if (params || change || _.modified(ForceConfig) + || (pulse.changed() && _.restart)) + { + sim.alpha(Math.max(sim.alpha(), _.alpha || 1)) + .alphaDecay(1 - Math.pow(sim.alphaMin(), 1 / iters)); + + if (_.static) { + for (sim.stop(); --iters >= 0;) sim.tick(); + } else { + if (sim.stopped()) sim.restart(); + if (!change) return pulse.StopPropagation; // defer to sim ticks + } + } + + return this.finish(_, pulse); +}; + +prototype$70.finish = function(_, pulse) { + var dataflow = pulse.dataflow; + + // inspect dependencies, touch link source data + for (var args=this._argops, j=0, m=args.length, arg; j= 0) sum += children[i].value; + node.value = sum; +} + +var node_count = function() { + return this.eachAfter(count); +}; + +var node_each = function(callback) { + var node = this, current, next = [node], children, i, n; + do { + current = next.reverse(), next = []; + while (node = current.pop()) { + callback(node), children = node.children; + if (children) for (i = 0, n = children.length; i < n; ++i) { + next.push(children[i]); + } + } + } while (next.length); + return this; +}; + +var node_eachBefore = function(callback) { + var node = this, nodes = [node], children, i; + while (node = nodes.pop()) { + callback(node), children = node.children; + if (children) for (i = children.length - 1; i >= 0; --i) { + nodes.push(children[i]); + } + } + return this; +}; + +var node_eachAfter = function(callback) { + var node = this, nodes = [node], next = [], children, i, n; + while (node = nodes.pop()) { + next.push(node), children = node.children; + if (children) for (i = 0, n = children.length; i < n; ++i) { + nodes.push(children[i]); + } + } + while (node = next.pop()) { + callback(node); + } + return this; +}; + +var node_sum = function(value) { + return this.eachAfter(function(node) { + var sum = +value(node.data) || 0, + children = node.children, + i = children && children.length; + while (--i >= 0) sum += children[i].value; + node.value = sum; + }); +}; + +var node_sort = function(compare) { + return this.eachBefore(function(node) { + if (node.children) { + node.children.sort(compare); + } + }); +}; + +var node_path = function(end) { + var start = this, + ancestor = leastCommonAncestor(start, end), + nodes = [start]; + while (start !== ancestor) { + start = start.parent; + nodes.push(start); + } + var k = nodes.length; + while (end !== ancestor) { + nodes.splice(k, 0, end); + end = end.parent; + } + return nodes; +}; + +function leastCommonAncestor(a, b) { + if (a === b) return a; + var aNodes = a.ancestors(), + bNodes = b.ancestors(), + c = null; + a = aNodes.pop(); + b = bNodes.pop(); + while (a === b) { + c = a; + a = aNodes.pop(); + b = bNodes.pop(); + } + return c; +} + +var node_ancestors = function() { + var node = this, nodes = [node]; + while (node = node.parent) { + nodes.push(node); + } + return nodes; +}; + +var node_descendants = function() { + var nodes = []; + this.each(function(node) { + nodes.push(node); + }); + return nodes; +}; + +var node_leaves = function() { + var leaves = []; + this.eachBefore(function(node) { + if (!node.children) { + leaves.push(node); + } + }); + return leaves; +}; + +var node_links = function() { + var root = this, links = []; + root.each(function(node) { + if (node !== root) { // Don’t include the root’s parent, if any. + links.push({source: node.parent, target: node}); + } + }); + return links; +}; + +function hierarchy(data, children) { + var root = new Node(data), + valued = +data.value && (root.value = data.value), + node, + nodes = [root], + child, + childs, + i, + n; + + if (children == null) children = defaultChildren; + + while (node = nodes.pop()) { + if (valued) node.value = +node.data.value; + if ((childs = children(node.data)) && (n = childs.length)) { + node.children = new Array(n); + for (i = n - 1; i >= 0; --i) { + nodes.push(child = node.children[i] = new Node(childs[i])); + child.parent = node; + child.depth = node.depth + 1; + } + } + } + + return root.eachBefore(computeHeight); +} + +function node_copy() { + return hierarchy(this).eachBefore(copyData); +} + +function defaultChildren(d) { + return d.children; +} + +function copyData(node) { + node.data = node.data.data; +} + +function computeHeight(node) { + var height = 0; + do node.height = height; + while ((node = node.parent) && (node.height < ++height)); +} + +function Node(data) { + this.data = data; + this.depth = + this.height = 0; + this.parent = null; +} + +Node.prototype = hierarchy.prototype = { + constructor: Node, + count: node_count, + each: node_each, + eachAfter: node_eachAfter, + eachBefore: node_eachBefore, + sum: node_sum, + sort: node_sort, + path: node_path, + ancestors: node_ancestors, + descendants: node_descendants, + leaves: node_leaves, + links: node_links, + copy: node_copy +}; + +var slice$5 = Array.prototype.slice; + +function shuffle$1(array) { + var m = array.length, + t, + i; + + while (m) { + i = Math.random() * m-- | 0; + t = array[m]; + array[m] = array[i]; + array[i] = t; + } + + return array; +} + +var enclose = function(circles) { + var i = 0, n = (circles = shuffle$1(slice$5.call(circles))).length, B = [], p, e; + + while (i < n) { + p = circles[i]; + if (e && enclosesWeak(e, p)) ++i; + else e = encloseBasis(B = extendBasis(B, p)), i = 0; + } + + return e; +}; + +function extendBasis(B, p) { + var i, j; + + if (enclosesWeakAll(p, B)) return [p]; + + // If we get here then B must have at least one element. + for (i = 0; i < B.length; ++i) { + if (enclosesNot(p, B[i]) + && enclosesWeakAll(encloseBasis2(B[i], p), B)) { + return [B[i], p]; + } + } + + // If we get here then B must have at least two elements. + for (i = 0; i < B.length - 1; ++i) { + for (j = i + 1; j < B.length; ++j) { + if (enclosesNot(encloseBasis2(B[i], B[j]), p) + && enclosesNot(encloseBasis2(B[i], p), B[j]) + && enclosesNot(encloseBasis2(B[j], p), B[i]) + && enclosesWeakAll(encloseBasis3(B[i], B[j], p), B)) { + return [B[i], B[j], p]; + } + } + } + + // If we get here then something is very wrong. + throw new Error; +} + +function enclosesNot(a, b) { + var dr = a.r - b.r, dx = b.x - a.x, dy = b.y - a.y; + return dr < 0 || dr * dr < dx * dx + dy * dy; +} + +function enclosesWeak(a, b) { + var dr = a.r - b.r + 1e-6, dx = b.x - a.x, dy = b.y - a.y; + return dr > 0 && dr * dr > dx * dx + dy * dy; +} + +function enclosesWeakAll(a, B) { + for (var i = 0; i < B.length; ++i) { + if (!enclosesWeak(a, B[i])) { + return false; + } + } + return true; +} + +function encloseBasis(B) { + switch (B.length) { + case 1: return encloseBasis1(B[0]); + case 2: return encloseBasis2(B[0], B[1]); + case 3: return encloseBasis3(B[0], B[1], B[2]); + } +} + +function encloseBasis1(a) { + return { + x: a.x, + y: a.y, + r: a.r + }; +} + +function encloseBasis2(a, b) { + var x1 = a.x, y1 = a.y, r1 = a.r, + x2 = b.x, y2 = b.y, r2 = b.r, + x21 = x2 - x1, y21 = y2 - y1, r21 = r2 - r1, + l = Math.sqrt(x21 * x21 + y21 * y21); + return { + x: (x1 + x2 + x21 / l * r21) / 2, + y: (y1 + y2 + y21 / l * r21) / 2, + r: (l + r1 + r2) / 2 + }; +} + +function encloseBasis3(a, b, c) { + var x1 = a.x, y1 = a.y, r1 = a.r, + x2 = b.x, y2 = b.y, r2 = b.r, + x3 = c.x, y3 = c.y, r3 = c.r, + a2 = x1 - x2, + a3 = x1 - x3, + b2 = y1 - y2, + b3 = y1 - y3, + c2 = r2 - r1, + c3 = r3 - r1, + d1 = x1 * x1 + y1 * y1 - r1 * r1, + d2 = d1 - x2 * x2 - y2 * y2 + r2 * r2, + d3 = d1 - x3 * x3 - y3 * y3 + r3 * r3, + ab = a3 * b2 - a2 * b3, + xa = (b2 * d3 - b3 * d2) / (ab * 2) - x1, + xb = (b3 * c2 - b2 * c3) / ab, + ya = (a3 * d2 - a2 * d3) / (ab * 2) - y1, + yb = (a2 * c3 - a3 * c2) / ab, + A = xb * xb + yb * yb - 1, + B = 2 * (r1 + xa * xb + ya * yb), + C = xa * xa + ya * ya - r1 * r1, + r = -(A ? (B + Math.sqrt(B * B - 4 * A * C)) / (2 * A) : C / B); + return { + x: x1 + xa + xb * r, + y: y1 + ya + yb * r, + r: r + }; +} + +function place(a, b, c) { + var ax = a.x, + ay = a.y, + da = b.r + c.r, + db = a.r + c.r, + dx = b.x - ax, + dy = b.y - ay, + dc = dx * dx + dy * dy; + if (dc) { + var x = 0.5 + ((db *= db) - (da *= da)) / (2 * dc), + y = Math.sqrt(Math.max(0, 2 * da * (db + dc) - (db -= dc) * db - da * da)) / (2 * dc); + c.x = ax + x * dx + y * dy; + c.y = ay + x * dy - y * dx; + } else { + c.x = ax + db; + c.y = ay; + } +} + +function intersects(a, b) { + var dx = b.x - a.x, + dy = b.y - a.y, + dr = a.r + b.r; + return dr * dr - 1e-6 > dx * dx + dy * dy; +} + +function score(node) { + var a = node._, + b = node.next._, + ab = a.r + b.r, + dx = (a.x * b.r + b.x * a.r) / ab, + dy = (a.y * b.r + b.y * a.r) / ab; + return dx * dx + dy * dy; +} + +function Node$1(circle) { + this._ = circle; + this.next = null; + this.previous = null; +} + +function packEnclose(circles) { + if (!(n = circles.length)) return 0; + + var a, b, c, n, aa, ca, i, j, k, sj, sk; + + // Place the first circle. + a = circles[0], a.x = 0, a.y = 0; + if (!(n > 1)) return a.r; + + // Place the second circle. + b = circles[1], a.x = -b.r, b.x = a.r, b.y = 0; + if (!(n > 2)) return a.r + b.r; + + // Place the third circle. + place(b, a, c = circles[2]); + + // Initialize the front-chain using the first three circles a, b and c. + a = new Node$1(a), b = new Node$1(b), c = new Node$1(c); + a.next = c.previous = b; + b.next = a.previous = c; + c.next = b.previous = a; + + // Attempt to place each remaining circle… + pack: for (i = 3; i < n; ++i) { + place(a._, b._, c = circles[i]), c = new Node$1(c); + + // Find the closest intersecting circle on the front-chain, if any. + // “Closeness” is determined by linear distance along the front-chain. + // “Ahead” or “behind” is likewise determined by linear distance. + j = b.next, k = a.previous, sj = b._.r, sk = a._.r; + do { + if (sj <= sk) { + if (intersects(j._, c._)) { + b = j, a.next = b, b.previous = a, --i; + continue pack; + } + sj += j._.r, j = j.next; + } else { + if (intersects(k._, c._)) { + a = k, a.next = b, b.previous = a, --i; + continue pack; + } + sk += k._.r, k = k.previous; + } + } while (j !== k.next); + + // Success! Insert the new circle c between a and b. + c.previous = a, c.next = b, a.next = b.previous = b = c; + + // Compute the new closest circle pair to the centroid. + aa = score(a); + while ((c = c.next) !== b) { + if ((ca = score(c)) < aa) { + a = c, aa = ca; + } + } + b = a.next; + } + + // Compute the enclosing circle of the front chain. + a = [b._], c = b; while ((c = c.next) !== b) a.push(c._); c = enclose(a); + + // Translate the circles to put the enclosing circle around the origin. + for (i = 0; i < n; ++i) a = circles[i], a.x -= c.x, a.y -= c.y; + + return c.r; +} + +function optional(f) { + return f == null ? null : required(f); +} + +function required(f) { + if (typeof f !== "function") throw new Error; + return f; +} + +function constantZero() { + return 0; +} + +var constant$9 = function(x) { + return function() { + return x; + }; +}; + +function defaultRadius(d) { + return Math.sqrt(d.value); +} + +var pack$1 = function() { + var radius = null, + dx = 1, + dy = 1, + padding = constantZero; + + function pack(root) { + root.x = dx / 2, root.y = dy / 2; + if (radius) { + root.eachBefore(radiusLeaf(radius)) + .eachAfter(packChildren(padding, 0.5)) + .eachBefore(translateChild(1)); + } else { + root.eachBefore(radiusLeaf(defaultRadius)) + .eachAfter(packChildren(constantZero, 1)) + .eachAfter(packChildren(padding, root.r / Math.min(dx, dy))) + .eachBefore(translateChild(Math.min(dx, dy) / (2 * root.r))); + } + return root; + } + + pack.radius = function(x) { + return arguments.length ? (radius = optional(x), pack) : radius; + }; + + pack.size = function(x) { + return arguments.length ? (dx = +x[0], dy = +x[1], pack) : [dx, dy]; + }; + + pack.padding = function(x) { + return arguments.length ? (padding = typeof x === "function" ? x : constant$9(+x), pack) : padding; + }; + + return pack; +}; + +function radiusLeaf(radius) { + return function(node) { + if (!node.children) { + node.r = Math.max(0, +radius(node) || 0); + } + }; +} + +function packChildren(padding, k) { + return function(node) { + if (children = node.children) { + var children, + i, + n = children.length, + r = padding(node) * k || 0, + e; + + if (r) for (i = 0; i < n; ++i) children[i].r += r; + e = packEnclose(children); + if (r) for (i = 0; i < n; ++i) children[i].r -= r; + node.r = e + r; + } + }; +} + +function translateChild(k) { + return function(node) { + var parent = node.parent; + node.r *= k; + if (parent) { + node.x = parent.x + k * node.x; + node.y = parent.y + k * node.y; + } + }; +} + +var roundNode = function(node) { + node.x0 = Math.round(node.x0); + node.y0 = Math.round(node.y0); + node.x1 = Math.round(node.x1); + node.y1 = Math.round(node.y1); +}; + +var treemapDice = function(parent, x0, y0, x1, y1) { + var nodes = parent.children, + node, + i = -1, + n = nodes.length, + k = parent.value && (x1 - x0) / parent.value; + + while (++i < n) { + node = nodes[i], node.y0 = y0, node.y1 = y1; + node.x0 = x0, node.x1 = x0 += node.value * k; + } +}; + +var partition$2 = function() { + var dx = 1, + dy = 1, + padding = 0, + round = false; + + function partition(root) { + var n = root.height + 1; + root.x0 = + root.y0 = padding; + root.x1 = dx; + root.y1 = dy / n; + root.eachBefore(positionNode(dy, n)); + if (round) root.eachBefore(roundNode); + return root; + } + + function positionNode(dy, n) { + return function(node) { + if (node.children) { + treemapDice(node, node.x0, dy * (node.depth + 1) / n, node.x1, dy * (node.depth + 2) / n); + } + var x0 = node.x0, + y0 = node.y0, + x1 = node.x1 - padding, + y1 = node.y1 - padding; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + node.x0 = x0; + node.y0 = y0; + node.x1 = x1; + node.y1 = y1; + }; + } + + partition.round = function(x) { + return arguments.length ? (round = !!x, partition) : round; + }; + + partition.size = function(x) { + return arguments.length ? (dx = +x[0], dy = +x[1], partition) : [dx, dy]; + }; + + partition.padding = function(x) { + return arguments.length ? (padding = +x, partition) : padding; + }; + + return partition; +}; + +var keyPrefix = "$"; +var preroot = {depth: -1}; +var ambiguous = {}; + +function defaultId(d) { + return d.id; +} + +function defaultParentId(d) { + return d.parentId; +} + +var stratify = function() { + var id = defaultId, + parentId = defaultParentId; + + function stratify(data) { + var d, + i, + n = data.length, + root, + parent, + node, + nodes = new Array(n), + nodeId, + nodeKey, + nodeByKey = {}; + + for (i = 0; i < n; ++i) { + d = data[i], node = nodes[i] = new Node(d); + if ((nodeId = id(d, i, data)) != null && (nodeId += "")) { + nodeKey = keyPrefix + (node.id = nodeId); + nodeByKey[nodeKey] = nodeKey in nodeByKey ? ambiguous : node; + } + } + + for (i = 0; i < n; ++i) { + node = nodes[i], nodeId = parentId(data[i], i, data); + if (nodeId == null || !(nodeId += "")) { + if (root) throw new Error("multiple roots"); + root = node; + } else { + parent = nodeByKey[keyPrefix + nodeId]; + if (!parent) throw new Error("missing: " + nodeId); + if (parent === ambiguous) throw new Error("ambiguous: " + nodeId); + if (parent.children) parent.children.push(node); + else parent.children = [node]; + node.parent = parent; + } + } + + if (!root) throw new Error("no root"); + root.parent = preroot; + root.eachBefore(function(node) { node.depth = node.parent.depth + 1; --n; }).eachBefore(computeHeight); + root.parent = null; + if (n > 0) throw new Error("cycle"); + + return root; + } + + stratify.id = function(x) { + return arguments.length ? (id = required(x), stratify) : id; + }; + + stratify.parentId = function(x) { + return arguments.length ? (parentId = required(x), stratify) : parentId; + }; + + return stratify; +}; + +function defaultSeparation$1(a, b) { + return a.parent === b.parent ? 1 : 2; +} + +// function radialSeparation(a, b) { +// return (a.parent === b.parent ? 1 : 2) / a.depth; +// } + +// This function is used to traverse the left contour of a subtree (or +// subforest). It returns the successor of v on this contour. This successor is +// either given by the leftmost child of v or by the thread of v. The function +// returns null if and only if v is on the highest level of its subtree. +function nextLeft(v) { + var children = v.children; + return children ? children[0] : v.t; +} + +// This function works analogously to nextLeft. +function nextRight(v) { + var children = v.children; + return children ? children[children.length - 1] : v.t; +} + +// Shifts the current subtree rooted at w+. This is done by increasing +// prelim(w+) and mod(w+) by shift. +function moveSubtree(wm, wp, shift) { + var change = shift / (wp.i - wm.i); + wp.c -= change; + wp.s += shift; + wm.c += change; + wp.z += shift; + wp.m += shift; +} + +// All other shifts, applied to the smaller subtrees between w- and w+, are +// performed by this function. To prepare the shifts, we have to adjust +// change(w+), shift(w+), and change(w-). +function executeShifts(v) { + var shift = 0, + change = 0, + children = v.children, + i = children.length, + w; + while (--i >= 0) { + w = children[i]; + w.z += shift; + w.m += shift; + shift += w.s + (change += w.c); + } +} + +// If vi-’s ancestor is a sibling of v, returns vi-’s ancestor. Otherwise, +// returns the specified (default) ancestor. +function nextAncestor(vim, v, ancestor) { + return vim.a.parent === v.parent ? vim.a : ancestor; +} + +function TreeNode(node, i) { + this._ = node; + this.parent = null; + this.children = null; + this.A = null; // default ancestor + this.a = this; // ancestor + this.z = 0; // prelim + this.m = 0; // mod + this.c = 0; // change + this.s = 0; // shift + this.t = null; // thread + this.i = i; // number +} + +TreeNode.prototype = Object.create(Node.prototype); + +function treeRoot(root) { + var tree = new TreeNode(root, 0), + node, + nodes = [tree], + child, + children, + i, + n; + + while (node = nodes.pop()) { + if (children = node._.children) { + node.children = new Array(n = children.length); + for (i = n - 1; i >= 0; --i) { + nodes.push(child = node.children[i] = new TreeNode(children[i], i)); + child.parent = node; + } + } + } + + (tree.parent = new TreeNode(null, 0)).children = [tree]; + return tree; +} + +// Node-link tree diagram using the Reingold-Tilford "tidy" algorithm +var tree$1 = function() { + var separation = defaultSeparation$1, + dx = 1, + dy = 1, + nodeSize = null; + + function tree(root) { + var t = treeRoot(root); + + // Compute the layout using Buchheim et al.’s algorithm. + t.eachAfter(firstWalk), t.parent.m = -t.z; + t.eachBefore(secondWalk); + + // If a fixed node size is specified, scale x and y. + if (nodeSize) root.eachBefore(sizeNode); + + // If a fixed tree size is specified, scale x and y based on the extent. + // Compute the left-most, right-most, and depth-most nodes for extents. + else { + var left = root, + right = root, + bottom = root; + root.eachBefore(function(node) { + if (node.x < left.x) left = node; + if (node.x > right.x) right = node; + if (node.depth > bottom.depth) bottom = node; + }); + var s = left === right ? 1 : separation(left, right) / 2, + tx = s - left.x, + kx = dx / (right.x + s + tx), + ky = dy / (bottom.depth || 1); + root.eachBefore(function(node) { + node.x = (node.x + tx) * kx; + node.y = node.depth * ky; + }); + } + + return root; + } + + // Computes a preliminary x-coordinate for v. Before that, FIRST WALK is + // applied recursively to the children of v, as well as the function + // APPORTION. After spacing out the children by calling EXECUTE SHIFTS, the + // node v is placed to the midpoint of its outermost children. + function firstWalk(v) { + var children = v.children, + siblings = v.parent.children, + w = v.i ? siblings[v.i - 1] : null; + if (children) { + executeShifts(v); + var midpoint = (children[0].z + children[children.length - 1].z) / 2; + if (w) { + v.z = w.z + separation(v._, w._); + v.m = v.z - midpoint; + } else { + v.z = midpoint; + } + } else if (w) { + v.z = w.z + separation(v._, w._); + } + v.parent.A = apportion(v, w, v.parent.A || siblings[0]); + } + + // Computes all real x-coordinates by summing up the modifiers recursively. + function secondWalk(v) { + v._.x = v.z + v.parent.m; + v.m += v.parent.m; + } + + // The core of the algorithm. Here, a new subtree is combined with the + // previous subtrees. Threads are used to traverse the inside and outside + // contours of the left and right subtree up to the highest common level. The + // vertices used for the traversals are vi+, vi-, vo-, and vo+, where the + // superscript o means outside and i means inside, the subscript - means left + // subtree and + means right subtree. For summing up the modifiers along the + // contour, we use respective variables si+, si-, so-, and so+. Whenever two + // nodes of the inside contours conflict, we compute the left one of the + // greatest uncommon ancestors using the function ANCESTOR and call MOVE + // SUBTREE to shift the subtree and prepare the shifts of smaller subtrees. + // Finally, we add a new thread (if necessary). + function apportion(v, w, ancestor) { + if (w) { + var vip = v, + vop = v, + vim = w, + vom = vip.parent.children[0], + sip = vip.m, + sop = vop.m, + sim = vim.m, + som = vom.m, + shift; + while (vim = nextRight(vim), vip = nextLeft(vip), vim && vip) { + vom = nextLeft(vom); + vop = nextRight(vop); + vop.a = v; + shift = vim.z + sim - vip.z - sip + separation(vim._, vip._); + if (shift > 0) { + moveSubtree(nextAncestor(vim, v, ancestor), v, shift); + sip += shift; + sop += shift; + } + sim += vim.m; + sip += vip.m; + som += vom.m; + sop += vop.m; + } + if (vim && !nextRight(vop)) { + vop.t = vim; + vop.m += sim - sop; + } + if (vip && !nextLeft(vom)) { + vom.t = vip; + vom.m += sip - som; + ancestor = v; + } + } + return ancestor; + } + + function sizeNode(node) { + node.x *= dx; + node.y = node.depth * dy; + } + + tree.separation = function(x) { + return arguments.length ? (separation = x, tree) : separation; + }; + + tree.size = function(x) { + return arguments.length ? (nodeSize = false, dx = +x[0], dy = +x[1], tree) : (nodeSize ? null : [dx, dy]); + }; + + tree.nodeSize = function(x) { + return arguments.length ? (nodeSize = true, dx = +x[0], dy = +x[1], tree) : (nodeSize ? [dx, dy] : null); + }; + + return tree; +}; + +var treemapSlice = function(parent, x0, y0, x1, y1) { + var nodes = parent.children, + node, + i = -1, + n = nodes.length, + k = parent.value && (y1 - y0) / parent.value; + + while (++i < n) { + node = nodes[i], node.x0 = x0, node.x1 = x1; + node.y0 = y0, node.y1 = y0 += node.value * k; + } +}; + +var phi = (1 + Math.sqrt(5)) / 2; + +function squarifyRatio(ratio, parent, x0, y0, x1, y1) { + var rows = [], + nodes = parent.children, + row, + nodeValue, + i0 = 0, + i1 = 0, + n = nodes.length, + dx, dy, + value = parent.value, + sumValue, + minValue, + maxValue, + newRatio, + minRatio, + alpha, + beta; + + while (i0 < n) { + dx = x1 - x0, dy = y1 - y0; + + // Find the next non-empty node. + do sumValue = nodes[i1++].value; while (!sumValue && i1 < n); + minValue = maxValue = sumValue; + alpha = Math.max(dy / dx, dx / dy) / (value * ratio); + beta = sumValue * sumValue * alpha; + minRatio = Math.max(maxValue / beta, beta / minValue); + + // Keep adding nodes while the aspect ratio maintains or improves. + for (; i1 < n; ++i1) { + sumValue += nodeValue = nodes[i1].value; + if (nodeValue < minValue) minValue = nodeValue; + if (nodeValue > maxValue) maxValue = nodeValue; + beta = sumValue * sumValue * alpha; + newRatio = Math.max(maxValue / beta, beta / minValue); + if (newRatio > minRatio) { sumValue -= nodeValue; break; } + minRatio = newRatio; + } + + // Position and record the row orientation. + rows.push(row = {value: sumValue, dice: dx < dy, children: nodes.slice(i0, i1)}); + if (row.dice) treemapDice(row, x0, y0, x1, value ? y0 += dy * sumValue / value : y1); + else treemapSlice(row, x0, y0, value ? x0 += dx * sumValue / value : x1, y1); + value -= sumValue, i0 = i1; + } + + return rows; +} + +var treemapSquarify = (function custom(ratio) { + + function squarify(parent, x0, y0, x1, y1) { + squarifyRatio(ratio, parent, x0, y0, x1, y1); + } + + squarify.ratio = function(x) { + return custom((x = +x) > 1 ? x : 1); + }; + + return squarify; +})(phi); + +var treemap = function() { + var tile = treemapSquarify, + round = false, + dx = 1, + dy = 1, + paddingStack = [0], + paddingInner = constantZero, + paddingTop = constantZero, + paddingRight = constantZero, + paddingBottom = constantZero, + paddingLeft = constantZero; + + function treemap(root) { + root.x0 = + root.y0 = 0; + root.x1 = dx; + root.y1 = dy; + root.eachBefore(positionNode); + paddingStack = [0]; + if (round) root.eachBefore(roundNode); + return root; + } + + function positionNode(node) { + var p = paddingStack[node.depth], + x0 = node.x0 + p, + y0 = node.y0 + p, + x1 = node.x1 - p, + y1 = node.y1 - p; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + node.x0 = x0; + node.y0 = y0; + node.x1 = x1; + node.y1 = y1; + if (node.children) { + p = paddingStack[node.depth + 1] = paddingInner(node) / 2; + x0 += paddingLeft(node) - p; + y0 += paddingTop(node) - p; + x1 -= paddingRight(node) - p; + y1 -= paddingBottom(node) - p; + if (x1 < x0) x0 = x1 = (x0 + x1) / 2; + if (y1 < y0) y0 = y1 = (y0 + y1) / 2; + tile(node, x0, y0, x1, y1); + } + } + + treemap.round = function(x) { + return arguments.length ? (round = !!x, treemap) : round; + }; + + treemap.size = function(x) { + return arguments.length ? (dx = +x[0], dy = +x[1], treemap) : [dx, dy]; + }; + + treemap.tile = function(x) { + return arguments.length ? (tile = required(x), treemap) : tile; + }; + + treemap.padding = function(x) { + return arguments.length ? treemap.paddingInner(x).paddingOuter(x) : treemap.paddingInner(); + }; + + treemap.paddingInner = function(x) { + return arguments.length ? (paddingInner = typeof x === "function" ? x : constant$9(+x), treemap) : paddingInner; + }; + + treemap.paddingOuter = function(x) { + return arguments.length ? treemap.paddingTop(x).paddingRight(x).paddingBottom(x).paddingLeft(x) : treemap.paddingTop(); + }; + + treemap.paddingTop = function(x) { + return arguments.length ? (paddingTop = typeof x === "function" ? x : constant$9(+x), treemap) : paddingTop; + }; + + treemap.paddingRight = function(x) { + return arguments.length ? (paddingRight = typeof x === "function" ? x : constant$9(+x), treemap) : paddingRight; + }; + + treemap.paddingBottom = function(x) { + return arguments.length ? (paddingBottom = typeof x === "function" ? x : constant$9(+x), treemap) : paddingBottom; + }; + + treemap.paddingLeft = function(x) { + return arguments.length ? (paddingLeft = typeof x === "function" ? x : constant$9(+x), treemap) : paddingLeft; + }; + + return treemap; +}; + +var treemapBinary = function(parent, x0, y0, x1, y1) { + var nodes = parent.children, + i, n = nodes.length, + sum, sums = new Array(n + 1); + + for (sums[0] = sum = i = 0; i < n; ++i) { + sums[i + 1] = sum += nodes[i].value; + } + + partition(0, n, parent.value, x0, y0, x1, y1); + + function partition(i, j, value, x0, y0, x1, y1) { + if (i >= j - 1) { + var node = nodes[i]; + node.x0 = x0, node.y0 = y0; + node.x1 = x1, node.y1 = y1; + return; + } + + var valueOffset = sums[i], + valueTarget = (value / 2) + valueOffset, + k = i + 1, + hi = j - 1; + + while (k < hi) { + var mid = k + hi >>> 1; + if (sums[mid] < valueTarget) k = mid + 1; + else hi = mid; + } + + if ((valueTarget - sums[k - 1]) < (sums[k] - valueTarget) && i + 1 < k) --k; + + var valueLeft = sums[k] - valueOffset, + valueRight = value - valueLeft; + + if ((x1 - x0) > (y1 - y0)) { + var xk = (x0 * valueRight + x1 * valueLeft) / value; + partition(i, k, valueLeft, x0, y0, xk, y1); + partition(k, j, valueRight, xk, y0, x1, y1); + } else { + var yk = (y0 * valueRight + y1 * valueLeft) / value; + partition(i, k, valueLeft, x0, y0, x1, yk); + partition(k, j, valueRight, x0, yk, x1, y1); + } + } +}; + +var treemapSliceDice = function(parent, x0, y0, x1, y1) { + (parent.depth & 1 ? treemapSlice : treemapDice)(parent, x0, y0, x1, y1); +}; + +var treemapResquarify = (function custom(ratio) { + + function resquarify(parent, x0, y0, x1, y1) { + if ((rows = parent._squarify) && (rows.ratio === ratio)) { + var rows, + row, + nodes, + i, + j = -1, + n, + m = rows.length, + value = parent.value; + + while (++j < m) { + row = rows[j], nodes = row.children; + for (i = row.value = 0, n = nodes.length; i < n; ++i) row.value += nodes[i].value; + if (row.dice) treemapDice(row, x0, y0, x1, y0 += (y1 - y0) * row.value / value); + else treemapSlice(row, x0, y0, x0 += (x1 - x0) * row.value / value, y1); + value -= row.value; + } + } else { + parent._squarify = rows = squarifyRatio(ratio, parent, x0, y0, x1, y1); + rows.ratio = ratio; + } + } + + resquarify.ratio = function(x) { + return custom((x = +x) > 1 ? x : 1); + }; + + return resquarify; +})(phi); + +/** + * Nest tuples into a tree structure, grouped by key values. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} params.keys - The key fields to nest by, in order. + * @param {function(object): *} [params.key] - Unique key field for each tuple. + * If not provided, the tuple id field is used. + * @param {boolean} [params.generate=false] - A boolean flag indicating if + * non-leaf nodes generated by this transform should be included in the + * output. The default (false) includes only the input data (leaf nodes) + * in the data stream. + */ +function Nest(params) { + Transform.call(this, null, params); +} + +Nest.Definition = { + "type": "Nest", + "metadata": {"treesource": true, "generates": true}, + "params": [ + { "name": "keys", "type": "field", "array": true }, + { "name": "key", "type": "field" }, + { "name": "generate", "type": "boolean" } + ] +}; + +var prototype$71 = inherits(Nest, Transform); + +function children(n) { + return n.values; +} + +prototype$71.transform = function(_, pulse) { + if (!pulse.source) { + error$1('Nest transform requires an upstream data source.'); + } + + var key$$1 = _.key || tupleid, + gen = _.generate, + mod = _.modified(), + out = gen || mod ? pulse.fork(pulse.ALL) : pulse, + root, tree, map$$1; + + if (!this.value || mod || pulse.changed()) { + // collect nodes to remove + if (gen && this.value) { + out.materialize(out.REM); + this.value.each(function(node) { + if (node.children) out.rem.push(node); + }); + } + + // generate new tree structure + root = array(_.keys) + .reduce(function(n, k) { n.key(k); return n; }, nest()) + .entries(out.materialize(out.SOURCE).source); + this.value = tree = hierarchy({values: root}, children); + + // collect nodes to add + if (gen) { + out.materialize(out.ADD); + out.source = out.source.slice(); + tree.each(function(node) { + if (node.children) { + node = ingest(node.data); + out.add.push(node); + out.source.push(node); + } + }); + } + + // build lookup table + map$$1 = tree.lookup = {}; + tree.each(function(node) { + if (tupleid(node.data) != null) { + map$$1[key$$1(node.data)] = node; + } + }); + } + + out.source.root = this.value; + return out; +}; + +/** + * Abstract class for tree layout. + * @constructor + * @param {object} params - The parameters for this operator. + */ +function HierarchyLayout(params) { + Transform.call(this, null, params); +} + +var prototype$73 = inherits(HierarchyLayout, Transform); + +prototype$73.transform = function(_, pulse) { + if (!pulse.source || !pulse.source.root) { + error$1(this.constructor.name + + ' transform requires a backing tree data source.'); + } + + var layout = this.layout(_.method), + fields = this.fields, + root = pulse.source.root, + as = _.as || fields; + + if (_.field) root.sum(_.field); + if (_.sort) root.sort(_.sort); + + setParams(layout, this.params, _); + try { + this.value = layout(root); + } catch (err) { + error$1(err); + } + root.each(function(node) { setFields(node, fields, as); }); + + return pulse.reflow(_.modified()).modifies(as).modifies('leaf'); +}; + +function setParams(layout, params, _) { + for (var p, i=0, n=params.length; i 0) return; + r /= dx; + if (dx < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dx > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + + r = x1 - ax; + if (!dx && r < 0) return; + r /= dx; + if (dx < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dx > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + + r = y0 - ay; + if (!dy && r > 0) return; + r /= dy; + if (dy < 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } else if (dy > 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } + + r = y1 - ay; + if (!dy && r < 0) return; + r /= dy; + if (dy < 0) { + if (r > t1) return; + if (r > t0) t0 = r; + } else if (dy > 0) { + if (r < t0) return; + if (r < t1) t1 = r; + } + + if (!(t0 > 0) && !(t1 < 1)) return true; // TODO Better check? + + if (t0 > 0) edge[0] = [ax + t0 * dx, ay + t0 * dy]; + if (t1 < 1) edge[1] = [ax + t1 * dx, ay + t1 * dy]; + return true; +} + +function connectEdge(edge, x0, y0, x1, y1) { + var v1 = edge[1]; + if (v1) return true; + + var v0 = edge[0], + left = edge.left, + right = edge.right, + lx = left[0], + ly = left[1], + rx = right[0], + ry = right[1], + fx = (lx + rx) / 2, + fy = (ly + ry) / 2, + fm, + fb; + + if (ry === ly) { + if (fx < x0 || fx >= x1) return; + if (lx > rx) { + if (!v0) v0 = [fx, y0]; + else if (v0[1] >= y1) return; + v1 = [fx, y1]; + } else { + if (!v0) v0 = [fx, y1]; + else if (v0[1] < y0) return; + v1 = [fx, y0]; + } + } else { + fm = (lx - rx) / (ry - ly); + fb = fy - fm * fx; + if (fm < -1 || fm > 1) { + if (lx > rx) { + if (!v0) v0 = [(y0 - fb) / fm, y0]; + else if (v0[1] >= y1) return; + v1 = [(y1 - fb) / fm, y1]; + } else { + if (!v0) v0 = [(y1 - fb) / fm, y1]; + else if (v0[1] < y0) return; + v1 = [(y0 - fb) / fm, y0]; + } + } else { + if (ly < ry) { + if (!v0) v0 = [x0, fm * x0 + fb]; + else if (v0[0] >= x1) return; + v1 = [x1, fm * x1 + fb]; + } else { + if (!v0) v0 = [x1, fm * x1 + fb]; + else if (v0[0] < x0) return; + v1 = [x0, fm * x0 + fb]; + } + } + } + + edge[0] = v0; + edge[1] = v1; + return true; +} + +function clipEdges(x0, y0, x1, y1) { + var i = edges.length, + edge; + + while (i--) { + if (!connectEdge(edge = edges[i], x0, y0, x1, y1) + || !clipEdge(edge, x0, y0, x1, y1) + || !(Math.abs(edge[0][0] - edge[1][0]) > epsilon$3 + || Math.abs(edge[0][1] - edge[1][1]) > epsilon$3)) { + delete edges[i]; + } + } +} + +function createCell(site) { + return cells[site.index] = { + site: site, + halfedges: [] + }; +} + +function cellHalfedgeAngle(cell, edge) { + var site = cell.site, + va = edge.left, + vb = edge.right; + if (site === vb) vb = va, va = site; + if (vb) return Math.atan2(vb[1] - va[1], vb[0] - va[0]); + if (site === va) va = edge[1], vb = edge[0]; + else va = edge[0], vb = edge[1]; + return Math.atan2(va[0] - vb[0], vb[1] - va[1]); +} + +function cellHalfedgeStart(cell, edge) { + return edge[+(edge.left !== cell.site)]; +} + +function cellHalfedgeEnd(cell, edge) { + return edge[+(edge.left === cell.site)]; +} + +function sortCellHalfedges() { + for (var i = 0, n = cells.length, cell, halfedges, j, m; i < n; ++i) { + if ((cell = cells[i]) && (m = (halfedges = cell.halfedges).length)) { + var index = new Array(m), + array = new Array(m); + for (j = 0; j < m; ++j) index[j] = j, array[j] = cellHalfedgeAngle(cell, edges[halfedges[j]]); + index.sort(function(i, j) { return array[j] - array[i]; }); + for (j = 0; j < m; ++j) array[j] = halfedges[index[j]]; + for (j = 0; j < m; ++j) halfedges[j] = array[j]; + } + } +} + +function clipCells(x0, y0, x1, y1) { + var nCells = cells.length, + iCell, + cell, + site, + iHalfedge, + halfedges, + nHalfedges, + start, + startX, + startY, + end, + endX, + endY, + cover = true; + + for (iCell = 0; iCell < nCells; ++iCell) { + if (cell = cells[iCell]) { + site = cell.site; + halfedges = cell.halfedges; + iHalfedge = halfedges.length; + + // Remove any dangling clipped edges. + while (iHalfedge--) { + if (!edges[halfedges[iHalfedge]]) { + halfedges.splice(iHalfedge, 1); + } + } + + // Insert any border edges as necessary. + iHalfedge = 0, nHalfedges = halfedges.length; + while (iHalfedge < nHalfedges) { + end = cellHalfedgeEnd(cell, edges[halfedges[iHalfedge]]), endX = end[0], endY = end[1]; + start = cellHalfedgeStart(cell, edges[halfedges[++iHalfedge % nHalfedges]]), startX = start[0], startY = start[1]; + if (Math.abs(endX - startX) > epsilon$3 || Math.abs(endY - startY) > epsilon$3) { + halfedges.splice(iHalfedge, 0, edges.push(createBorderEdge(site, end, + Math.abs(endX - x0) < epsilon$3 && y1 - endY > epsilon$3 ? [x0, Math.abs(startX - x0) < epsilon$3 ? startY : y1] + : Math.abs(endY - y1) < epsilon$3 && x1 - endX > epsilon$3 ? [Math.abs(startY - y1) < epsilon$3 ? startX : x1, y1] + : Math.abs(endX - x1) < epsilon$3 && endY - y0 > epsilon$3 ? [x1, Math.abs(startX - x1) < epsilon$3 ? startY : y0] + : Math.abs(endY - y0) < epsilon$3 && endX - x0 > epsilon$3 ? [Math.abs(startY - y0) < epsilon$3 ? startX : x0, y0] + : null)) - 1); + ++nHalfedges; + } + } + + if (nHalfedges) cover = false; + } + } + + // If there weren’t any edges, have the closest site cover the extent. + // It doesn’t matter which corner of the extent we measure! + if (cover) { + var dx, dy, d2, dc = Infinity; + + for (iCell = 0, cover = null; iCell < nCells; ++iCell) { + if (cell = cells[iCell]) { + site = cell.site; + dx = site[0] - x0; + dy = site[1] - y0; + d2 = dx * dx + dy * dy; + if (d2 < dc) dc = d2, cover = cell; + } + } + + if (cover) { + var v00 = [x0, y0], v01 = [x0, y1], v11 = [x1, y1], v10 = [x1, y0]; + cover.halfedges.push( + edges.push(createBorderEdge(site = cover.site, v00, v01)) - 1, + edges.push(createBorderEdge(site, v01, v11)) - 1, + edges.push(createBorderEdge(site, v11, v10)) - 1, + edges.push(createBorderEdge(site, v10, v00)) - 1 + ); + } + } + + // Lastly delete any cells with no edges; these were entirely clipped. + for (iCell = 0; iCell < nCells; ++iCell) { + if (cell = cells[iCell]) { + if (!cell.halfedges.length) { + delete cells[iCell]; + } + } + } +} + +var circlePool = []; + +var firstCircle; + +function Circle() { + RedBlackNode(this); + this.x = + this.y = + this.arc = + this.site = + this.cy = null; +} + +function attachCircle(arc) { + var lArc = arc.P, + rArc = arc.N; + + if (!lArc || !rArc) return; + + var lSite = lArc.site, + cSite = arc.site, + rSite = rArc.site; + + if (lSite === rSite) return; + + var bx = cSite[0], + by = cSite[1], + ax = lSite[0] - bx, + ay = lSite[1] - by, + cx = rSite[0] - bx, + cy = rSite[1] - by; + + var d = 2 * (ax * cy - ay * cx); + if (d >= -epsilon2$2) return; + + var ha = ax * ax + ay * ay, + hc = cx * cx + cy * cy, + x = (cy * ha - ay * hc) / d, + y = (ax * hc - cx * ha) / d; + + var circle = circlePool.pop() || new Circle; + circle.arc = arc; + circle.site = cSite; + circle.x = x + bx; + circle.y = (circle.cy = y + by) + Math.sqrt(x * x + y * y); // y bottom + + arc.circle = circle; + + var before = null, + node = circles._; + + while (node) { + if (circle.y < node.y || (circle.y === node.y && circle.x <= node.x)) { + if (node.L) node = node.L; + else { before = node.P; break; } + } else { + if (node.R) node = node.R; + else { before = node; break; } + } + } + + circles.insert(before, circle); + if (!before) firstCircle = circle; +} + +function detachCircle(arc) { + var circle = arc.circle; + if (circle) { + if (!circle.P) firstCircle = circle.N; + circles.remove(circle); + circlePool.push(circle); + RedBlackNode(circle); + arc.circle = null; + } +} + +var beachPool = []; + +function Beach() { + RedBlackNode(this); + this.edge = + this.site = + this.circle = null; +} + +function createBeach(site) { + var beach = beachPool.pop() || new Beach; + beach.site = site; + return beach; +} + +function detachBeach(beach) { + detachCircle(beach); + beaches.remove(beach); + beachPool.push(beach); + RedBlackNode(beach); +} + +function removeBeach(beach) { + var circle = beach.circle, + x = circle.x, + y = circle.cy, + vertex = [x, y], + previous = beach.P, + next = beach.N, + disappearing = [beach]; + + detachBeach(beach); + + var lArc = previous; + while (lArc.circle + && Math.abs(x - lArc.circle.x) < epsilon$3 + && Math.abs(y - lArc.circle.cy) < epsilon$3) { + previous = lArc.P; + disappearing.unshift(lArc); + detachBeach(lArc); + lArc = previous; + } + + disappearing.unshift(lArc); + detachCircle(lArc); + + var rArc = next; + while (rArc.circle + && Math.abs(x - rArc.circle.x) < epsilon$3 + && Math.abs(y - rArc.circle.cy) < epsilon$3) { + next = rArc.N; + disappearing.push(rArc); + detachBeach(rArc); + rArc = next; + } + + disappearing.push(rArc); + detachCircle(rArc); + + var nArcs = disappearing.length, + iArc; + for (iArc = 1; iArc < nArcs; ++iArc) { + rArc = disappearing[iArc]; + lArc = disappearing[iArc - 1]; + setEdgeEnd(rArc.edge, lArc.site, rArc.site, vertex); + } + + lArc = disappearing[0]; + rArc = disappearing[nArcs - 1]; + rArc.edge = createEdge(lArc.site, rArc.site, null, vertex); + + attachCircle(lArc); + attachCircle(rArc); +} + +function addBeach(site) { + var x = site[0], + directrix = site[1], + lArc, + rArc, + dxl, + dxr, + node = beaches._; + + while (node) { + dxl = leftBreakPoint(node, directrix) - x; + if (dxl > epsilon$3) node = node.L; else { + dxr = x - rightBreakPoint(node, directrix); + if (dxr > epsilon$3) { + if (!node.R) { + lArc = node; + break; + } + node = node.R; + } else { + if (dxl > -epsilon$3) { + lArc = node.P; + rArc = node; + } else if (dxr > -epsilon$3) { + lArc = node; + rArc = node.N; + } else { + lArc = rArc = node; + } + break; + } + } + } + + createCell(site); + var newArc = createBeach(site); + beaches.insert(lArc, newArc); + + if (!lArc && !rArc) return; + + if (lArc === rArc) { + detachCircle(lArc); + rArc = createBeach(lArc.site); + beaches.insert(newArc, rArc); + newArc.edge = rArc.edge = createEdge(lArc.site, newArc.site); + attachCircle(lArc); + attachCircle(rArc); + return; + } + + if (!rArc) { // && lArc + newArc.edge = createEdge(lArc.site, newArc.site); + return; + } + + // else lArc !== rArc + detachCircle(lArc); + detachCircle(rArc); + + var lSite = lArc.site, + ax = lSite[0], + ay = lSite[1], + bx = site[0] - ax, + by = site[1] - ay, + rSite = rArc.site, + cx = rSite[0] - ax, + cy = rSite[1] - ay, + d = 2 * (bx * cy - by * cx), + hb = bx * bx + by * by, + hc = cx * cx + cy * cy, + vertex = [(cy * hb - by * hc) / d + ax, (bx * hc - cx * hb) / d + ay]; + + setEdgeEnd(rArc.edge, lSite, rSite, vertex); + newArc.edge = createEdge(lSite, site, null, vertex); + rArc.edge = createEdge(site, rSite, null, vertex); + attachCircle(lArc); + attachCircle(rArc); +} + +function leftBreakPoint(arc, directrix) { + var site = arc.site, + rfocx = site[0], + rfocy = site[1], + pby2 = rfocy - directrix; + + if (!pby2) return rfocx; + + var lArc = arc.P; + if (!lArc) return -Infinity; + + site = lArc.site; + var lfocx = site[0], + lfocy = site[1], + plby2 = lfocy - directrix; + + if (!plby2) return lfocx; + + var hl = lfocx - rfocx, + aby2 = 1 / pby2 - 1 / plby2, + b = hl / plby2; + + if (aby2) return (-b + Math.sqrt(b * b - 2 * aby2 * (hl * hl / (-2 * plby2) - lfocy + plby2 / 2 + rfocy - pby2 / 2))) / aby2 + rfocx; + + return (rfocx + lfocx) / 2; +} + +function rightBreakPoint(arc, directrix) { + var rArc = arc.N; + if (rArc) return leftBreakPoint(rArc, directrix); + var site = arc.site; + return site[1] === directrix ? site[0] : Infinity; +} + +var epsilon$3 = 1e-6; +var epsilon2$2 = 1e-12; +var beaches; +var cells; +var circles; +var edges; + +function triangleArea(a, b, c) { + return (a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]); +} + +function lexicographic(a, b) { + return b[1] - a[1] + || b[0] - a[0]; +} + +function Diagram(sites, extent) { + var site = sites.sort(lexicographic).pop(), + x, + y, + circle; + + edges = []; + cells = new Array(sites.length); + beaches = new RedBlackTree; + circles = new RedBlackTree; + + while (true) { + circle = firstCircle; + if (site && (!circle || site[1] < circle.y || (site[1] === circle.y && site[0] < circle.x))) { + if (site[0] !== x || site[1] !== y) { + addBeach(site); + x = site[0], y = site[1]; + } + site = sites.pop(); + } else if (circle) { + removeBeach(circle.arc); + } else { + break; + } + } + + sortCellHalfedges(); + + if (extent) { + var x0 = +extent[0][0], + y0 = +extent[0][1], + x1 = +extent[1][0], + y1 = +extent[1][1]; + clipEdges(x0, y0, x1, y1); + clipCells(x0, y0, x1, y1); + } + + this.edges = edges; + this.cells = cells; + + beaches = + circles = + edges = + cells = null; +} + +Diagram.prototype = { + constructor: Diagram, + + polygons: function() { + var edges = this.edges; + + return this.cells.map(function(cell) { + var polygon = cell.halfedges.map(function(i) { return cellHalfedgeStart(cell, edges[i]); }); + polygon.data = cell.site.data; + return polygon; + }); + }, + + triangles: function() { + var triangles = [], + edges = this.edges; + + this.cells.forEach(function(cell, i) { + if (!(m = (halfedges = cell.halfedges).length)) return; + var site = cell.site, + halfedges, + j = -1, + m, + s0, + e1 = edges[halfedges[m - 1]], + s1 = e1.left === site ? e1.right : e1.left; + + while (++j < m) { + s0 = s1; + e1 = edges[halfedges[j]]; + s1 = e1.left === site ? e1.right : e1.left; + if (s0 && s1 && i < s0.index && i < s1.index && triangleArea(site, s0, s1) < 0) { + triangles.push([site.data, s0.data, s1.data]); + } + } + }); + + return triangles; + }, + + links: function() { + return this.edges.filter(function(edge) { + return edge.right; + }).map(function(edge) { + return { + source: edge.left.data, + target: edge.right.data + }; + }); + }, + + find: function(x, y, radius) { + var that = this, i0, i1 = that._found || 0, n = that.cells.length, cell; + + // Use the previously-found cell, or start with an arbitrary one. + while (!(cell = that.cells[i1])) if (++i1 >= n) return null; + var dx = x - cell.site[0], dy = y - cell.site[1], d2 = dx * dx + dy * dy; + + // Traverse the half-edges to find a closer cell, if any. + do { + cell = that.cells[i0 = i1], i1 = null; + cell.halfedges.forEach(function(e) { + var edge = that.edges[e], v = edge.left; + if ((v === cell.site || !v) && !(v = edge.right)) return; + var vx = x - v[0], vy = y - v[1], v2 = vx * vx + vy * vy; + if (v2 < d2) d2 = v2, i1 = v.index; + }); + } while (i1 !== null); + + that._found = i0; + + return radius == null || d2 <= radius * radius ? cell.site : null; + } +}; + +var voronoi$1 = function() { + var x = x$4, + y = y$4, + extent = null; + + function voronoi(data) { + return new Diagram(data.map(function(d, i) { + var s = [Math.round(x(d, i, data) / epsilon$3) * epsilon$3, Math.round(y(d, i, data) / epsilon$3) * epsilon$3]; + s.index = i; + s.data = d; + return s; + }), extent); + } + + voronoi.polygons = function(data) { + return voronoi(data).polygons(); + }; + + voronoi.links = function(data) { + return voronoi(data).links(); + }; + + voronoi.triangles = function(data) { + return voronoi(data).triangles(); + }; + + voronoi.x = function(_) { + return arguments.length ? (x = typeof _ === "function" ? _ : constant$10(+_), voronoi) : x; + }; + + voronoi.y = function(_) { + return arguments.length ? (y = typeof _ === "function" ? _ : constant$10(+_), voronoi) : y; + }; + + voronoi.extent = function(_) { + return arguments.length ? (extent = _ == null ? null : [[+_[0][0], +_[0][1]], [+_[1][0], +_[1][1]]], voronoi) : extent && [[extent[0][0], extent[0][1]], [extent[1][0], extent[1][1]]]; + }; + + voronoi.size = function(_) { + return arguments.length ? (extent = _ == null ? null : [[0, 0], [+_[0], +_[1]]], voronoi) : extent && [extent[1][0] - extent[0][0], extent[1][1] - extent[0][1]]; + }; + + return voronoi; +}; + +function Voronoi(params) { + Transform.call(this, null, params); +} + +Voronoi.Definition = { + "type": "Voronoi", + "metadata": {"modifies": true}, + "params": [ + { "name": "x", "type": "field", "required": true }, + { "name": "y", "type": "field", "required": true }, + { "name": "size", "type": "number", "array": true, "length": 2 }, + { "name": "extent", "type": "array", "array": true, "length": 2, + "default": [[-1e5, -1e5], [1e5, 1e5]], + "content": {"type": "number", "array": true, "length": 2} }, + { "name": "as", "type": "string", "default": "path" } + ] +}; + +var prototype$79 = inherits(Voronoi, Transform); + +var defaultExtent = [[-1e5, -1e5], [1e5, 1e5]]; + +prototype$79.transform = function(_, pulse) { + var as = _.as || 'path', + data = pulse.source, + diagram, polygons, i, n; + + // configure and construct voronoi diagram + diagram = voronoi$1().x(_.x).y(_.y); + if (_.size) diagram.size(_.size); + else diagram.extent(_.extent || defaultExtent); + + this.value = (diagram = diagram(data)); + + // map polygons to paths + polygons = diagram.polygons(); + for (i=0, n=data.length; i> 5; +var ch = 1 << 11; + +var cloud = function() { + var size = [256, 256], + text, + font, + fontSize, + fontStyle, + fontWeight, + rotate, + padding, + spiral = archimedeanSpiral, + words = [], + random = Math.random, + cloud = {}; + + cloud.layout = function() { + var contextAndRatio = getContext(canvas()), + board = zeroArray((size[0] >> 5) * size[1]), + bounds = null, + n = words.length, + i = -1, + tags = [], + data = words.map(function(d) { + return { + text: text(d), + font: font(d), + style: fontStyle(d), + weight: fontWeight(d), + rotate: rotate(d), + size: ~~fontSize(d), + padding: padding(d), + xoff: 0, + yoff: 0, + x1: 0, + y1: 0, + x0: 0, + y0: 0, + hasText: false, + sprite: null, + datum: d + }; + }).sort(function(a, b) { return b.size - a.size; }); + + while (++i < n) { + var d = data[i]; + d.x = (size[0] * (random() + .5)) >> 1; + d.y = (size[1] * (random() + .5)) >> 1; + cloudSprite(contextAndRatio, d, data, i); + if (d.hasText && place(board, d, bounds)) { + tags.push(d); + if (bounds) cloudBounds(bounds, d); + else bounds = [{x: d.x + d.x0, y: d.y + d.y0}, {x: d.x + d.x1, y: d.y + d.y1}]; + // Temporary hack + d.x -= size[0] >> 1; + d.y -= size[1] >> 1; + } + } + + return tags; + }; + + function getContext(canvas$$1) { + canvas$$1.width = canvas$$1.height = 1; + var ratio = Math.sqrt(canvas$$1.getContext("2d").getImageData(0, 0, 1, 1).data.length >> 2); + canvas$$1.width = (cw << 5) / ratio; + canvas$$1.height = ch / ratio; + + var context = canvas$$1.getContext("2d"); + context.fillStyle = context.strokeStyle = "red"; + context.textAlign = "center"; + + return {context: context, ratio: ratio}; + } + + function place(board, tag, bounds) { + var startX = tag.x, + startY = tag.y, + maxDelta = Math.sqrt(size[0] * size[0] + size[1] * size[1]), + s = spiral(size), + dt = random() < .5 ? 1 : -1, + t = -dt, + dxdy, + dx, + dy; + + while (dxdy = s(t += dt)) { + dx = ~~dxdy[0]; + dy = ~~dxdy[1]; + + if (Math.min(Math.abs(dx), Math.abs(dy)) >= maxDelta) break; + + tag.x = startX + dx; + tag.y = startY + dy; + + if (tag.x + tag.x0 < 0 || tag.y + tag.y0 < 0 || + tag.x + tag.x1 > size[0] || tag.y + tag.y1 > size[1]) continue; + // TODO only check for collisions within current bounds. + if (!bounds || !cloudCollide(tag, board, size[0])) { + if (!bounds || collideRects(tag, bounds)) { + var sprite = tag.sprite, + w = tag.width >> 5, + sw = size[0] >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + board[x + i] |= (last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0); + } + x += sw; + } + tag.sprite = null; + return true; + } + } + } + return false; + } + + cloud.words = function(_) { + if (arguments.length) { + words = _; + return cloud; + } else { + return words; + } + }; + + cloud.size = function(_) { + if (arguments.length) { + size = [+_[0], +_[1]]; + return cloud; + } else { + return size; + } + }; + + cloud.font = function(_) { + if (arguments.length) { + font = functor(_); + return cloud; + } else { + return font; + } + }; + + cloud.fontStyle = function(_) { + if (arguments.length) { + fontStyle = functor(_); + return cloud; + } else { + return fontStyle; + } + }; + + cloud.fontWeight = function(_) { + if (arguments.length) { + fontWeight = functor(_); + return cloud; + } else { + return fontWeight; + } + }; + + cloud.rotate = function(_) { + if (arguments.length) { + rotate = functor(_); + return cloud; + } else { + return rotate; + } + }; + + cloud.text = function(_) { + if (arguments.length) { + text = functor(_); + return cloud; + } else { + return text; + } + }; + + cloud.spiral = function(_) { + if (arguments.length) { + spiral = spirals[_] || _; + return cloud; + } else { + return spiral; + } + }; + + cloud.fontSize = function(_) { + if (arguments.length) { + fontSize = functor(_); + return cloud; + } else { + return fontSize; + } + }; + + cloud.padding = function(_) { + if (arguments.length) { + padding = functor(_); + return cloud; + } else { + return padding; + } + }; + + cloud.random = function(_) { + if (arguments.length) { + random = _; + return cloud; + } else { + return random; + } + }; + + return cloud; +}; + +// Fetches a monochrome sprite bitmap for the specified text. +// Load in batches for speed. +function cloudSprite(contextAndRatio, d, data, di) { + if (d.sprite) return; + var c = contextAndRatio.context, + ratio = contextAndRatio.ratio; + + c.clearRect(0, 0, (cw << 5) / ratio, ch / ratio); + var x = 0, + y = 0, + maxh = 0, + n = data.length, + w, w32, h, i, j; + --di; + while (++di < n) { + d = data[di]; + c.save(); + c.font = d.style + " " + d.weight + " " + ~~((d.size + 1) / ratio) + "px " + d.font; + w = c.measureText(d.text + "m").width * ratio; + h = d.size << 1; + if (d.rotate) { + var sr = Math.sin(d.rotate * cloudRadians), + cr = Math.cos(d.rotate * cloudRadians), + wcr = w * cr, + wsr = w * sr, + hcr = h * cr, + hsr = h * sr; + w = (Math.max(Math.abs(wcr + hsr), Math.abs(wcr - hsr)) + 0x1f) >> 5 << 5; + h = ~~Math.max(Math.abs(wsr + hcr), Math.abs(wsr - hcr)); + } else { + w = (w + 0x1f) >> 5 << 5; + } + if (h > maxh) maxh = h; + if (x + w >= (cw << 5)) { + x = 0; + y += maxh; + maxh = 0; + } + if (y + h >= ch) break; + c.translate((x + (w >> 1)) / ratio, (y + (h >> 1)) / ratio); + if (d.rotate) c.rotate(d.rotate * cloudRadians); + c.fillText(d.text, 0, 0); + if (d.padding) { + c.lineWidth = 2 * d.padding; + c.strokeText(d.text, 0, 0); + } + c.restore(); + d.width = w; + d.height = h; + d.xoff = x; + d.yoff = y; + d.x1 = w >> 1; + d.y1 = h >> 1; + d.x0 = -d.x1; + d.y0 = -d.y1; + d.hasText = true; + x += w; + } + var pixels = c.getImageData(0, 0, (cw << 5) / ratio, ch / ratio).data, + sprite = []; + while (--di >= 0) { + d = data[di]; + if (!d.hasText) continue; + w = d.width; + w32 = w >> 5; + h = d.y1 - d.y0; + // Zero the buffer + for (i = 0; i < h * w32; i++) sprite[i] = 0; + x = d.xoff; + if (x == null) return; + y = d.yoff; + var seen = 0, + seenRow = -1; + for (j = 0; j < h; j++) { + for (i = 0; i < w; i++) { + var k = w32 * j + (i >> 5), + m = pixels[((y + j) * (cw << 5) + (x + i)) << 2] ? 1 << (31 - (i % 32)) : 0; + sprite[k] |= m; + seen |= m; + } + if (seen) seenRow = j; + else { + d.y0++; + h--; + j--; + y++; + } + } + d.y1 = d.y0 + seenRow; + d.sprite = sprite.slice(0, (d.y1 - d.y0) * w32); + } +} + +// Use mask-based collision detection. +function cloudCollide(tag, board, sw) { + sw >>= 5; + var sprite = tag.sprite, + w = tag.width >> 5, + lx = tag.x - (w << 4), + sx = lx & 0x7f, + msx = 32 - sx, + h = tag.y1 - tag.y0, + x = (tag.y + tag.y0) * sw + (lx >> 5), + last; + for (var j = 0; j < h; j++) { + last = 0; + for (var i = 0; i <= w; i++) { + if (((last << msx) | (i < w ? (last = sprite[j * w + i]) >>> sx : 0)) + & board[x + i]) return true; + } + x += sw; + } + return false; +} + +function cloudBounds(bounds, d) { + var b0 = bounds[0], + b1 = bounds[1]; + if (d.x + d.x0 < b0.x) b0.x = d.x + d.x0; + if (d.y + d.y0 < b0.y) b0.y = d.y + d.y0; + if (d.x + d.x1 > b1.x) b1.x = d.x + d.x1; + if (d.y + d.y1 > b1.y) b1.y = d.y + d.y1; +} + +function collideRects(a, b) { + return a.x + a.x1 > b[0].x && a.x + a.x0 < b[1].x && a.y + a.y1 > b[0].y && a.y + a.y0 < b[1].y; +} + +function archimedeanSpiral(size) { + var e = size[0] / size[1]; + return function(t) { + return [e * (t *= .1) * Math.cos(t), t * Math.sin(t)]; + }; +} + +function rectangularSpiral(size) { + var dy = 4, + dx = dy * size[0] / size[1], + x = 0, + y = 0; + return function(t) { + var sign = t < 0 ? -1 : 1; + // See triangular numbers: T_n = n * (n + 1) / 2. + switch ((Math.sqrt(1 + 4 * sign * t) - sign) & 3) { + case 0: x += dx; break; + case 1: y += dy; break; + case 2: x -= dx; break; + default: y -= dy; break; + } + return [x, y]; + }; +} + +// TODO reuse arrays? +function zeroArray(n) { + var a = [], + i = -1; + while (++i < n) a[i] = 0; + return a; +} + +function functor(d) { + return typeof d === "function" ? d : function() { return d; }; +} + +var spirals = { + archimedean: archimedeanSpiral, + rectangular: rectangularSpiral +}; + +var Output$4 = ['x', 'y', 'font', 'fontSize', 'fontStyle', 'fontWeight', 'angle']; + +var Params$1 = ['text', 'font', 'rotate', 'fontSize', 'fontStyle', 'fontWeight']; + +function Wordcloud(params) { + Transform.call(this, cloud(), params); +} + +Wordcloud.Definition = { + "type": "Wordcloud", + "metadata": {"modifies": true}, + "params": [ + { "name": "size", "type": "number", "array": true, "length": 2 }, + { "name": "font", "type": "string", "expr": true, "default": "sans-serif" }, + { "name": "fontStyle", "type": "string", "expr": true, "default": "normal" }, + { "name": "fontWeight", "type": "string", "expr": true, "default": "normal" }, + { "name": "fontSize", "type": "number", "expr": true, "default": 14 }, + { "name": "fontSizeRange", "type": "number", "array": "nullable", "default": [10, 50] }, + { "name": "rotate", "type": "number", "expr": true, "default": 0 }, + { "name": "text", "type": "field" }, + { "name": "spiral", "type": "string", "values": ["archimedean", "rectangular"] }, + { "name": "padding", "type": "number", "expr": true }, + { "name": "as", "type": "string", "array": true, "length": 7, "default": Output$4 } + ] +}; + +var prototype$80 = inherits(Wordcloud, Transform); + +prototype$80.transform = function(_, pulse) { + function modp(param) { + var p = _[param]; + return isFunction(p) && pulse.modified(p.fields); + } + + var mod = _.modified(); + if (!(mod || pulse.changed(pulse.ADD_REM) || Params$1.some(modp))) return; + + var data = pulse.materialize(pulse.SOURCE).source, + layout = this.value, + as = _.as || Output$4, + fontSize = _.fontSize || 14, + range; + + isFunction(fontSize) + ? (range = _.fontSizeRange) + : (fontSize = constant(fontSize)); + + // create font size scaling function as needed + if (range) { + var fsize = fontSize, + sizeScale = scale$1('sqrt')() + .domain(extent$2(fsize, data)) + .range(range); + fontSize = function(x) { return sizeScale(fsize(x)); }; + } + + data.forEach(function(t) { + t[as[0]] = NaN; + t[as[1]] = NaN; + t[as[3]] = 0; + }); + + // configure layout + var words = layout + .words(data) + .text(_.text) + .size(_.size || [500, 500]) + .padding(_.padding || 1) + .spiral(_.spiral || 'archimedean') + .rotate(_.rotate || 0) + .font(_.font || 'sans-serif') + .fontStyle(_.fontStyle || 'normal') + .fontWeight(_.fontWeight || 'normal') + .fontSize(fontSize) + .random(exports.random) + .layout(); + + var size = layout.size(), + dx = size[0] >> 1, + dy = size[1] >> 1, + i = 0, + n = words.length, + w, t; + + for (; i max) max = v; + } + + return [min, max]; +} + + + +var wordcloud = Object.freeze({ + wordcloud: Wordcloud +}); + +function array8(n) { return new Uint8Array(n); } + +function array16(n) { return new Uint16Array(n); } + +function array32(n) { return new Uint32Array(n); } + +/** + * Maintains CrossFilter state. + */ +function Bitmaps() { + + var width = 8, + data = [], + seen = array32(0), + curr = array$5(0, width), + prev = array$5(0, width); + + return { + + data: function() { return data; }, + + seen: function() { + return (seen = lengthen(seen, data.length)); + }, + + add: function(array) { + for (var i=0, j=data.length, n=array.length, t; i boolean (true => remove) + var n = data.length, + copy = Array(n - num), + reindex = data, // reuse old data array for index map + t, i, j; + + // seek forward to first removal + for (i=0; !map[i] && i k || m > width) { + width = Math.max(m, width); + curr = array$5(n, width, curr); + prev = array$5(n, width); + } + } + }; +} + +function lengthen(array, length, copy) { + if (array.length >= length) return array; + copy = copy || new array.constructor(length); + copy.set(array); + return copy; +} + +function array$5(n, m, array) { + var copy = (m < 0x101 ? array8 : m < 0x10001 ? array16 : array32)(n); + if (array) copy.set(array); + return copy; +} + +var Dimension = function(index, i, query) { + var bit = (1 << i); + + return { + one: bit, + zero: ~bit, + range: query.slice(), + bisect: index.bisect, + index: index.index, + size: index.size, + + onAdd: function(added, curr) { + var dim = this, + range = dim.bisect(dim.range, added.value), + idx = added.index, + lo = range[0], + hi = range[1], + n1 = idx.length, i; + + for (i=0; i 0) for (i=0; i remove + var n = size, + idx, i, j; + + // seek forward to first removal + for (i=0; !map[index[i]] && i y ? 1 : 0; + }); + return permute(values, index); +} + +function merge$3(base, value0, index0, n0, value1, index1, n1, value, index) { + var i0 = 0, i1 = 0, i; + + for (i=0; i0 < n0 && i1 < n1; ++i) { + if (value0[i0] < value1[i1]) { + value[i] = value0[i0]; + index[i] = index0[i0++]; + } else { + value[i] = value1[i1]; + index[i] = index1[i1++] + base; + } + } + + for (; i0 < n0; ++i0, ++i) { + value[i] = value0[i0]; + index[i] = index0[i0]; + } + + for (; i1 < n1; ++i1, ++i) { + value[i] = value1[i1]; + index[i] = index1[i1] + base; + } +} + +/** + * An indexed multi-dimensional filter. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {Array} params.fields - An array of dimension accessors to filter. + * @param {Array} params.query - An array of per-dimension range queries. + */ +function CrossFilter(params) { + Transform.call(this, Bitmaps(), params); + this._indices = null; + this._dims = null; +} + +CrossFilter.Definition = { + "type": "CrossFilter", + "metadata": {}, + "params": [ + { "name": "fields", "type": "field", "array": true, "required": true }, + { "name": "query", "type": "array", "array": true, "required": true, + "content": {"type": "number", "array": true, "length": 2} } + ] +}; + +var prototype$81 = inherits(CrossFilter, Transform); + +prototype$81.transform = function(_, pulse) { + if (!this._dims) { + return this.init(_, pulse); + } else { + var init = _.modified('fields') + || _.fields.some(function(f) { return pulse.modified(f.fields); }); + + return init + ? this.reinit(_, pulse) + : this.eval(_, pulse); + } +}; + +prototype$81.init = function(_, pulse) { + var fields = _.fields, + query = _.query, + indices = this._indices = {}, + dims = this._dims = [], + m = query.length, + i = 0, key$$1, index; + + // instantiate indices and dimensions + for (; i lo0) { + for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) { + k = index[i]; + if (seen[k] !== stamp) { + prev[k] = curr[k]; + seen[k] = stamp; + out.push(k); + } + curr[k] ^= one$$1; + } + } + + // Fast incremental update based on previous hi index. + if (hi1 > hi0) { + for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) { + k = index[i]; + if (seen[k] !== stamp) { + prev[k] = curr[k]; + seen[k] = stamp; + out.push(k); + } + curr[k] ^= one$$1; + } + } else if (hi1 < hi0) { + for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) { + k = index[i]; + if (seen[k] !== stamp) { + prev[k] = curr[k]; + seen[k] = stamp; + out.push(k); + } + curr[k] ^= one$$1; + } + } + + dim.range = query.slice(); +}; + +prototype$81.incrementOne = function(dim, query, add, rem) { + var bits = this.value, + curr = bits.curr(), + index = dim.index(), + old = dim.bisect(dim.range), + range = dim.bisect(query), + lo1 = range[0], + hi1 = range[1], + lo0 = old[0], + hi0 = old[1], + one$$1 = dim.one, + i, j, k; + + // Fast incremental update based on previous lo index. + if (lo1 < lo0) { + for (i = lo1, j = Math.min(lo0, hi1); i < j; ++i) { + k = index[i]; + curr[k] ^= one$$1; + add.push(k); + } + } else if (lo1 > lo0) { + for (i = lo0, j = Math.min(lo1, hi0); i < j; ++i) { + k = index[i]; + curr[k] ^= one$$1; + rem.push(k); + } + } + + // Fast incremental update based on previous hi index. + if (hi1 > hi0) { + for (i = Math.max(lo1, hi0), j = hi1; i < j; ++i) { + k = index[i]; + curr[k] ^= one$$1; + add.push(k); + } + } else if (hi1 < hi0) { + for (i = Math.max(lo0, hi1), j = hi0; i < j; ++i) { + k = index[i]; + curr[k] ^= one$$1; + rem.push(k); + } + } + + dim.range = query.slice(); +}; + +/** + * Selectively filters tuples by resolving against a filter bitmap. + * Useful for processing the output of a cross-filter transform. + * @constructor + * @param {object} params - The parameters for this operator. + * @param {object} params.ignore - A bit mask indicating which filters to ignore. + * @param {object} params.filter - The per-tuple filter bitmaps. Typically this + * parameter value is a reference to a {@link CrossFilter} transform. + */ +function ResolveFilter(params) { + Transform.call(this, null, params); +} + +ResolveFilter.Definition = { + "type": "ResolveFilter", + "metadata": {}, + "params": [ + { "name": "ignore", "type": "number", "required": true, + "description": "A bit mask indicating which filters to ignore." }, + { "name": "filter", "type": "object", "required": true, + "description": "Per-tuple filter bitmaps from a CrossFilter transform." } + ] +}; + +var prototype$82 = inherits(ResolveFilter, Transform); + +prototype$82.transform = function(_, pulse) { + var ignore = ~(_.ignore || 0), // bit mask where zeros -> dims to ignore + bitmap = _.filter, + mask = bitmap.mask; + + // exit early if no relevant filter changes + if ((mask & ignore) === 0) return pulse.StopPropagation; + + var output = pulse.fork(pulse.ALL), + data = bitmap.data(), + curr = bitmap.curr(), + prev = bitmap.prev(), + pass = function(k) { + return !(curr[k] & ignore) ? data[k] : null; + }; + + // propagate all mod tuples that pass the filter + output.filter(output.MOD, pass); + + // determine add & rem tuples via filter functions + // for efficiency, we do *not* populate new arrays, + // instead we add filter functions applied downstream + + if (!(mask & (mask-1))) { // only one filter changed + output.filter(output.ADD, pass); + output.filter(output.REM, function(k) { + return (curr[k] & ignore) === mask ? data[k] : null; + }); + + } else { // multiple filters changed + output.filter(output.ADD, function(k) { + var c = curr[k] & ignore, + f = !c && (c ^ (prev[k] & ignore)); + return f ? data[k] : null; + }); + output.filter(output.REM, function(k) { + var c = curr[k] & ignore, + f = c && !(c ^ (c ^ (prev[k] & ignore))); + return f ? data[k] : null; + }); + } + + // add filter to source data in case of reflow... + return output.filter(output.SOURCE, function(t) { return pass(t._index); }); +}; + + + +var xf = Object.freeze({ + crossfilter: CrossFilter, + resolvefilter: ResolveFilter +}); + +var version = "3.2.0"; + +var Default = 'default'; + +var cursor = function(view) { + var cursor = view._signals.cursor; + + // add cursor signal to dataflow, if needed + if (!cursor) { + view._signals.cursor = (cursor = view.add({user: Default, item: null})); + } + + // evaluate cursor on each mousemove event + view.on(view.events('view', 'mousemove'), cursor, + function(_, event) { + var value = cursor.value, + user = value ? (isString(value) ? value : value.user) : Default, + item = event.item && event.item.cursor || null; + + return (value && user === value.user && item == value.item) ? value + : {user: user, item: item}; + } + ); + + // when cursor signal updates, set visible cursor + view.add(null, function(_) { + var user = _.cursor, + item = this.value; + + if (!isString(user)) { + item = user.item; + user = user.user; + } + + setCursor(user && user !== Default ? user : (item || user)); + + return item; + }, {cursor: cursor}); +}; + +function setCursor(cursor) { + // set cursor on document body + // this ensures cursor applies even if dragging out of view + if (typeof document !== 'undefined' && document.body) { + document.body.style.cursor = cursor; + } +} + +function dataref(view, name) { + var data = view._runtime.data; + if (!data.hasOwnProperty(name)) { + error$1('Unrecognized data set: ' + name); + } + return data[name]; +} + +function data(name) { + return dataref(this, name).values.value; +} + +function change(name, changes) { + if (!isChangeSet(changes)) { + error$1('Second argument to changes must be a changeset.'); + } + var dataset = dataref(this, name); + dataset.modified = true; + return this.pulse(dataset.input, changes); +} + +function insert(name, _) { + return change.call(this, name, changeset().insert(_)); +} + +function remove(name, _) { + return change.call(this, name, changeset().remove(_)); +} + +function width(view) { + var padding = view.padding(); + return Math.max(0, view._viewWidth + padding.left + padding.right); +} + +function height$1(view) { + var padding = view.padding(); + return Math.max(0, view._viewHeight + padding.top + padding.bottom); +} + +function offset$1(view) { + var padding = view.padding(), + origin = view._origin; + return [ + padding.left + origin[0], + padding.top + origin[1] + ]; +} + +function resizeRenderer(view) { + var origin = offset$1(view), + w = width(view), + h = height$1(view); + + view._renderer.background(view._background); + view._renderer.resize(w, h, origin); + view._handler.origin(origin); + + view._resizeListeners.forEach(function(handler) { + handler(w, h); + }); +} + +/** + * Extend an event with additional view-specific methods. + * Adds a new property ('vega') to an event that provides a number + * of methods for querying information about the current interaction. + * The vega object provides the following methods: + * view - Returns the backing View instance. + * item - Returns the currently active scenegraph item (if any). + * group - Returns the currently active scenegraph group (if any). + * This method accepts a single string-typed argument indicating the name + * of the desired parent group. The scenegraph will be traversed from + * the item up towards the root to search for a matching group. If no + * argument is provided the enclosing group for the active item is + * returned, unless the item it itself a group, in which case it is + * returned directly. + * xy - Returns a two-element array containing the x and y coordinates for + * mouse or touch events. For touch events, this is based on the first + * elements in the changedTouches array. This method accepts a single + * argument: either an item instance or mark name that should serve as + * the reference coordinate system. If no argument is provided the + * top-level view coordinate system is assumed. + * x - Returns the current x-coordinate, accepts the same arguments as xy. + * y - Returns the current y-coordinate, accepts the same arguments as xy. + * @param {Event} event - The input event to extend. + * @param {Item} item - The currently active scenegraph item (if any). + * @return {Event} - The extended input event. + */ +var eventExtend = function(view, event, item) { + var el = view._renderer.scene(), + p, e, translate; + + if (el) { + translate = offset$1(view); + e = event.changedTouches ? event.changedTouches[0] : event; + p = point$4(e, el); + p[0] -= translate[0]; + p[1] -= translate[1]; + } + + event.dataflow = view; + event.vega = extension(view, item, p); + event.item = item; + return event; +}; + +function extension(view, item, point) { + var itemGroup = item + ? item.mark.marktype === 'group' ? item : item.mark.group + : null; + + function group(name) { + var g = itemGroup, i; + if (name) for (i = item; i; i = i.mark.group) { + if (i.mark.name === name) { g = i; break; } + } + return g && g.mark && g.mark.interactive ? g : {}; + } + + function xy(item) { + if (!item) return point; + if (isString(item)) item = group(item); + + var p = point.slice(); + while (item) { + p[0] -= item.x || 0; + p[1] -= item.y || 0; + item = item.mark && item.mark.group; + } + return p; + } + + return { + view: constant(view), + item: constant(item || {}), + group: group, + xy: xy, + x: function(item) { return xy(item)[0]; }, + y: function(item) { return xy(item)[1]; } + }; +} + +var VIEW = 'view'; +var WINDOW = 'window'; + +/** + * Initialize event handling configuration. + * @param {object} config - The configuration settings. + * @return {object} + */ +function initializeEventConfig(config) { + config = extend({}, config); + + var def = config.defaults; + if (def) { + if (isArray(def.prevent)) { + def.prevent = toSet(def.prevent); + } + if (isArray(def.allow)) { + def.allow = toSet(def.allow); + } + } + + return config; +} + +function prevent(view, type) { + var def = view._eventConfig.defaults, + prevent = def && def.prevent, + allow = def && def.allow; + + return prevent === false || allow === true ? false + : prevent === true || allow === false ? true + : prevent ? prevent[type] + : allow ? !allow[type] + : view.preventDefault(); +} + +/** + * Create a new event stream from an event source. + * @param {object} source - The event source to monitor. + * @param {string} type - The event type. + * @param {function(object): boolean} [filter] - Event filter function. + * @return {EventStream} + */ +function events$1(source, type, filter) { + var view = this, + s = new EventStream(filter), + send = function(e, item) { + if (source === VIEW && prevent(view, type)) { + e.preventDefault(); + } + try { + s.receive(eventExtend(view, e, item)); + } catch (error) { + view.error(error); + } finally { + view.run(); + } + }, + sources; + + if (source === VIEW) { + view.addEventListener(type, send); + return s; + } + + if (source === WINDOW) { + if (typeof window !== 'undefined') sources = [window]; + } else if (typeof document !== 'undefined') { + sources = document.querySelectorAll(source); + } + + if (!sources) { + view.warn('Can not resolve event source: ' + source); + return s; + } + + for (var i=0, n=sources.length; i= 0) { + e = listeners[n]; + m = e.sources.length; + while (--m >= 0) { + e.sources[m].removeEventListener(e.type, e.handler); + } + } +}; + +var element$1 = function(tag, attr, text) { + var el = document.createElement(tag); + for (var key in attr) el.setAttribute(key, attr[key]); + if (text != null) el.textContent = text; + return el; +}; + +var BindClass = 'vega-bind'; +var NameClass = 'vega-bind-name'; +var RadioClass = 'vega-bind-radio'; +var OptionClass = 'vega-option-'; + +/** + * Bind a signal to an external HTML input element. The resulting two-way + * binding will propagate input changes to signals, and propagate signal + * changes to the input element state. If this view instance has no parent + * element, we assume the view is headless and no bindings are created. + * @param {Element|string} el - The parent DOM element to which the input + * element should be appended as a child. If string-valued, this argument + * will be treated as a CSS selector. If null or undefined, the parent + * element of this view will be used as the element. + * @param {object} param - The binding parameters which specify the signal + * to bind to, the input element type, and type-specific configuration. + * @return {View} - This view instance. + */ +var bind$1 = function(view, el, binding) { + if (!el) return; + + var param = binding.param, + bind = binding.state; + + if (!bind) { + bind = binding.state = { + elements: null, + active: false, + set: null, + update: function(value) { + bind.source = true; + view.signal(param.signal, value).run(); + } + }; + if (param.debounce) { + bind.update = debounce(param.debounce, bind.update); + } + } + + generate(bind, el, param, view.signal(param.signal)); + + if (!bind.active) { + view.on(view._signals[param.signal], null, function() { + bind.source + ? (bind.source = false) + : bind.set(view.signal(param.signal)); + }); + bind.active = true; + } + + return bind; +}; + +/** + * Generate an HTML input form element and bind it to a signal. + */ +function generate(bind, el, param, value) { + var div = element$1('div', {'class': BindClass}); + + div.appendChild(element$1('span', + {'class': NameClass}, + (param.name || param.signal) + )); + + el.appendChild(div); + + var input = form; + switch (param.input) { + case 'checkbox': input = checkbox; break; + case 'select': input = select; break; + case 'radio': input = radio; break; + case 'range': input = range$1; break; + } + + input(bind, div, param, value); +} + +/** + * Generates an arbitrary input form element. + * The input type is controlled via user-provided parameters. + */ +function form(bind, el, param, value) { + var node = element$1('input'); + + for (var key$$1 in param) { + if (key$$1 !== 'signal' && key$$1 !== 'element') { + node.setAttribute(key$$1 === 'input' ? 'type' : key$$1, param[key$$1]); + } + } + node.setAttribute('name', param.signal); + node.value = value; + + el.appendChild(node); + + node.addEventListener('input', function() { + bind.update(node.value); + }); + + bind.elements = [node]; + bind.set = function(value) { node.value = value; }; +} + +/** + * Generates a checkbox input element. + */ +function checkbox(bind, el, param, value) { + var attr = {type: 'checkbox', name: param.signal}; + if (value) attr.checked = true; + var node = element$1('input', attr); + + el.appendChild(node); + + node.addEventListener('change', function() { + bind.update(node.checked); + }); + + bind.elements = [node]; + bind.set = function(value) { node.checked = !!value || null; }; +} + +/** + * Generates a selection list input element. + */ +function select(bind, el, param, value) { + var node = element$1('select', {name: param.signal}); + + param.options.forEach(function(option) { + var attr = {value: option}; + if (valuesEqual(option, value)) attr.selected = true; + node.appendChild(element$1('option', attr, option+'')); + }); + + el.appendChild(node); + + node.addEventListener('change', function() { + bind.update(param.options[node.selectedIndex]); + }); + + bind.elements = [node]; + bind.set = function(value) { + for (var i=0, n=param.options.length; i + Copyright (C) 2013 Thaddee Tyl + Copyright (C) 2013 Mathias Bynens + Copyright (C) 2012 Ariya Hidayat + Copyright (C) 2012 Mathias Bynens + Copyright (C) 2012 Joost-Wim Boekesteijn + Copyright (C) 2012 Kris Kowal + Copyright (C) 2012 Yusuke Suzuki + Copyright (C) 2012 Arpad Borsos + Copyright (C) 2011 Ariya Hidayat + + Redistribution and use in source and binary forms, with or without + modification, are permitted provided that the following conditions are met: + + * Redistributions of source code must retain the above copyright + notice, this list of conditions and the following disclaimer. + * Redistributions in binary form must reproduce the above copyright + notice, this list of conditions and the following disclaimer in the + documentation and/or other materials provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" + AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES + (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND + ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF + THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. +*/ +var source$1; +var index$1; +var length$2; +var lookahead; + +var TokenBooleanLiteral = 1; +var TokenEOF = 2; +var TokenIdentifier = 3; +var TokenKeyword = 4; +var TokenNullLiteral = 5; +var TokenNumericLiteral = 6; +var TokenPunctuator = 7; +var TokenStringLiteral = 8; + +var SyntaxArrayExpression = 'ArrayExpression'; +var SyntaxBinaryExpression = 'BinaryExpression'; +var SyntaxCallExpression = 'CallExpression'; +var SyntaxConditionalExpression = 'ConditionalExpression'; +var SyntaxIdentifier = 'Identifier'; +var SyntaxLiteral = 'Literal'; +var SyntaxLogicalExpression = 'LogicalExpression'; +var SyntaxMemberExpression = 'MemberExpression'; +var SyntaxObjectExpression = 'ObjectExpression'; +var SyntaxProperty = 'Property'; +var SyntaxUnaryExpression = 'UnaryExpression'; + +// Error messages should be identical to V8. +var MessageUnexpectedToken = 'Unexpected token %0'; +var MessageUnexpectedNumber = 'Unexpected number'; +var MessageUnexpectedString = 'Unexpected string'; +var MessageUnexpectedIdentifier = 'Unexpected identifier'; +var MessageUnexpectedReserved = 'Unexpected reserved word'; +var MessageUnexpectedEOS = 'Unexpected end of input'; +var MessageInvalidRegExp = 'Invalid regular expression'; +var MessageUnterminatedRegExp = 'Invalid regular expression: missing /'; +var MessageStrictOctalLiteral = 'Octal literals are not allowed in strict mode.'; +var MessageStrictDuplicateProperty = 'Duplicate data property in object literal not allowed in strict mode'; + +var ILLEGAL = 'ILLEGAL'; +var DISABLED = 'Disabled.'; + +// See also tools/generate-unicode-regex.py. +var RegexNonAsciiIdentifierStart = new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0370-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u05D0-\u05EA\u05F0-\u05F2\u0620-\u064A\u066E\u066F\u0671-\u06D3\u06D5\u06E5\u06E6\u06EE\u06EF\u06FA-\u06FC\u06FF\u0710\u0712-\u072F\u074D-\u07A5\u07B1\u07CA-\u07EA\u07F4\u07F5\u07FA\u0800-\u0815\u081A\u0824\u0828\u0840-\u0858\u08A0-\u08B2\u0904-\u0939\u093D\u0950\u0958-\u0961\u0971-\u0980\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BD\u09CE\u09DC\u09DD\u09DF-\u09E1\u09F0\u09F1\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A59-\u0A5C\u0A5E\u0A72-\u0A74\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABD\u0AD0\u0AE0\u0AE1\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3D\u0B5C\u0B5D\u0B5F-\u0B61\u0B71\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BD0\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D\u0C58\u0C59\u0C60\u0C61\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBD\u0CDE\u0CE0\u0CE1\u0CF1\u0CF2\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D\u0D4E\u0D60\u0D61\u0D7A-\u0D7F\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0E01-\u0E30\u0E32\u0E33\u0E40-\u0E46\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB0\u0EB2\u0EB3\u0EBD\u0EC0-\u0EC4\u0EC6\u0EDC-\u0EDF\u0F00\u0F40-\u0F47\u0F49-\u0F6C\u0F88-\u0F8C\u1000-\u102A\u103F\u1050-\u1055\u105A-\u105D\u1061\u1065\u1066\u106E-\u1070\u1075-\u1081\u108E\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1711\u1720-\u1731\u1740-\u1751\u1760-\u176C\u176E-\u1770\u1780-\u17B3\u17D7\u17DC\u1820-\u1877\u1880-\u18A8\u18AA\u18B0-\u18F5\u1900-\u191E\u1950-\u196D\u1970-\u1974\u1980-\u19AB\u19C1-\u19C7\u1A00-\u1A16\u1A20-\u1A54\u1AA7\u1B05-\u1B33\u1B45-\u1B4B\u1B83-\u1BA0\u1BAE\u1BAF\u1BBA-\u1BE5\u1C00-\u1C23\u1C4D-\u1C4F\u1C5A-\u1C7D\u1CE9-\u1CEC\u1CEE-\u1CF1\u1CF5\u1CF6\u1D00-\u1DBF\u1E00-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u2071\u207F\u2090-\u209C\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CEE\u2CF2\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D80-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2E2F\u3005-\u3007\u3021-\u3029\u3031-\u3035\u3038-\u303C\u3041-\u3096\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA61F\uA62A\uA62B\uA640-\uA66E\uA67F-\uA69D\uA6A0-\uA6EF\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA801\uA803-\uA805\uA807-\uA80A\uA80C-\uA822\uA840-\uA873\uA882-\uA8B3\uA8F2-\uA8F7\uA8FB\uA90A-\uA925\uA930-\uA946\uA960-\uA97C\uA984-\uA9B2\uA9CF\uA9E0-\uA9E4\uA9E6-\uA9EF\uA9FA-\uA9FE\uAA00-\uAA28\uAA40-\uAA42\uAA44-\uAA4B\uAA60-\uAA76\uAA7A\uAA7E-\uAAAF\uAAB1\uAAB5\uAAB6\uAAB9-\uAABD\uAAC0\uAAC2\uAADB-\uAADD\uAAE0-\uAAEA\uAAF2-\uAAF4\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABE2\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D\uFB1F-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE70-\uFE74\uFE76-\uFEFC\uFF21-\uFF3A\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'); +var RegexNonAsciiIdentifierPart = new RegExp('[\xAA\xB5\xBA\xC0-\xD6\xD8-\xF6\xF8-\u02C1\u02C6-\u02D1\u02E0-\u02E4\u02EC\u02EE\u0300-\u0374\u0376\u0377\u037A-\u037D\u037F\u0386\u0388-\u038A\u038C\u038E-\u03A1\u03A3-\u03F5\u03F7-\u0481\u0483-\u0487\u048A-\u052F\u0531-\u0556\u0559\u0561-\u0587\u0591-\u05BD\u05BF\u05C1\u05C2\u05C4\u05C5\u05C7\u05D0-\u05EA\u05F0-\u05F2\u0610-\u061A\u0620-\u0669\u066E-\u06D3\u06D5-\u06DC\u06DF-\u06E8\u06EA-\u06FC\u06FF\u0710-\u074A\u074D-\u07B1\u07C0-\u07F5\u07FA\u0800-\u082D\u0840-\u085B\u08A0-\u08B2\u08E4-\u0963\u0966-\u096F\u0971-\u0983\u0985-\u098C\u098F\u0990\u0993-\u09A8\u09AA-\u09B0\u09B2\u09B6-\u09B9\u09BC-\u09C4\u09C7\u09C8\u09CB-\u09CE\u09D7\u09DC\u09DD\u09DF-\u09E3\u09E6-\u09F1\u0A01-\u0A03\u0A05-\u0A0A\u0A0F\u0A10\u0A13-\u0A28\u0A2A-\u0A30\u0A32\u0A33\u0A35\u0A36\u0A38\u0A39\u0A3C\u0A3E-\u0A42\u0A47\u0A48\u0A4B-\u0A4D\u0A51\u0A59-\u0A5C\u0A5E\u0A66-\u0A75\u0A81-\u0A83\u0A85-\u0A8D\u0A8F-\u0A91\u0A93-\u0AA8\u0AAA-\u0AB0\u0AB2\u0AB3\u0AB5-\u0AB9\u0ABC-\u0AC5\u0AC7-\u0AC9\u0ACB-\u0ACD\u0AD0\u0AE0-\u0AE3\u0AE6-\u0AEF\u0B01-\u0B03\u0B05-\u0B0C\u0B0F\u0B10\u0B13-\u0B28\u0B2A-\u0B30\u0B32\u0B33\u0B35-\u0B39\u0B3C-\u0B44\u0B47\u0B48\u0B4B-\u0B4D\u0B56\u0B57\u0B5C\u0B5D\u0B5F-\u0B63\u0B66-\u0B6F\u0B71\u0B82\u0B83\u0B85-\u0B8A\u0B8E-\u0B90\u0B92-\u0B95\u0B99\u0B9A\u0B9C\u0B9E\u0B9F\u0BA3\u0BA4\u0BA8-\u0BAA\u0BAE-\u0BB9\u0BBE-\u0BC2\u0BC6-\u0BC8\u0BCA-\u0BCD\u0BD0\u0BD7\u0BE6-\u0BEF\u0C00-\u0C03\u0C05-\u0C0C\u0C0E-\u0C10\u0C12-\u0C28\u0C2A-\u0C39\u0C3D-\u0C44\u0C46-\u0C48\u0C4A-\u0C4D\u0C55\u0C56\u0C58\u0C59\u0C60-\u0C63\u0C66-\u0C6F\u0C81-\u0C83\u0C85-\u0C8C\u0C8E-\u0C90\u0C92-\u0CA8\u0CAA-\u0CB3\u0CB5-\u0CB9\u0CBC-\u0CC4\u0CC6-\u0CC8\u0CCA-\u0CCD\u0CD5\u0CD6\u0CDE\u0CE0-\u0CE3\u0CE6-\u0CEF\u0CF1\u0CF2\u0D01-\u0D03\u0D05-\u0D0C\u0D0E-\u0D10\u0D12-\u0D3A\u0D3D-\u0D44\u0D46-\u0D48\u0D4A-\u0D4E\u0D57\u0D60-\u0D63\u0D66-\u0D6F\u0D7A-\u0D7F\u0D82\u0D83\u0D85-\u0D96\u0D9A-\u0DB1\u0DB3-\u0DBB\u0DBD\u0DC0-\u0DC6\u0DCA\u0DCF-\u0DD4\u0DD6\u0DD8-\u0DDF\u0DE6-\u0DEF\u0DF2\u0DF3\u0E01-\u0E3A\u0E40-\u0E4E\u0E50-\u0E59\u0E81\u0E82\u0E84\u0E87\u0E88\u0E8A\u0E8D\u0E94-\u0E97\u0E99-\u0E9F\u0EA1-\u0EA3\u0EA5\u0EA7\u0EAA\u0EAB\u0EAD-\u0EB9\u0EBB-\u0EBD\u0EC0-\u0EC4\u0EC6\u0EC8-\u0ECD\u0ED0-\u0ED9\u0EDC-\u0EDF\u0F00\u0F18\u0F19\u0F20-\u0F29\u0F35\u0F37\u0F39\u0F3E-\u0F47\u0F49-\u0F6C\u0F71-\u0F84\u0F86-\u0F97\u0F99-\u0FBC\u0FC6\u1000-\u1049\u1050-\u109D\u10A0-\u10C5\u10C7\u10CD\u10D0-\u10FA\u10FC-\u1248\u124A-\u124D\u1250-\u1256\u1258\u125A-\u125D\u1260-\u1288\u128A-\u128D\u1290-\u12B0\u12B2-\u12B5\u12B8-\u12BE\u12C0\u12C2-\u12C5\u12C8-\u12D6\u12D8-\u1310\u1312-\u1315\u1318-\u135A\u135D-\u135F\u1380-\u138F\u13A0-\u13F4\u1401-\u166C\u166F-\u167F\u1681-\u169A\u16A0-\u16EA\u16EE-\u16F8\u1700-\u170C\u170E-\u1714\u1720-\u1734\u1740-\u1753\u1760-\u176C\u176E-\u1770\u1772\u1773\u1780-\u17D3\u17D7\u17DC\u17DD\u17E0-\u17E9\u180B-\u180D\u1810-\u1819\u1820-\u1877\u1880-\u18AA\u18B0-\u18F5\u1900-\u191E\u1920-\u192B\u1930-\u193B\u1946-\u196D\u1970-\u1974\u1980-\u19AB\u19B0-\u19C9\u19D0-\u19D9\u1A00-\u1A1B\u1A20-\u1A5E\u1A60-\u1A7C\u1A7F-\u1A89\u1A90-\u1A99\u1AA7\u1AB0-\u1ABD\u1B00-\u1B4B\u1B50-\u1B59\u1B6B-\u1B73\u1B80-\u1BF3\u1C00-\u1C37\u1C40-\u1C49\u1C4D-\u1C7D\u1CD0-\u1CD2\u1CD4-\u1CF6\u1CF8\u1CF9\u1D00-\u1DF5\u1DFC-\u1F15\u1F18-\u1F1D\u1F20-\u1F45\u1F48-\u1F4D\u1F50-\u1F57\u1F59\u1F5B\u1F5D\u1F5F-\u1F7D\u1F80-\u1FB4\u1FB6-\u1FBC\u1FBE\u1FC2-\u1FC4\u1FC6-\u1FCC\u1FD0-\u1FD3\u1FD6-\u1FDB\u1FE0-\u1FEC\u1FF2-\u1FF4\u1FF6-\u1FFC\u200C\u200D\u203F\u2040\u2054\u2071\u207F\u2090-\u209C\u20D0-\u20DC\u20E1\u20E5-\u20F0\u2102\u2107\u210A-\u2113\u2115\u2119-\u211D\u2124\u2126\u2128\u212A-\u212D\u212F-\u2139\u213C-\u213F\u2145-\u2149\u214E\u2160-\u2188\u2C00-\u2C2E\u2C30-\u2C5E\u2C60-\u2CE4\u2CEB-\u2CF3\u2D00-\u2D25\u2D27\u2D2D\u2D30-\u2D67\u2D6F\u2D7F-\u2D96\u2DA0-\u2DA6\u2DA8-\u2DAE\u2DB0-\u2DB6\u2DB8-\u2DBE\u2DC0-\u2DC6\u2DC8-\u2DCE\u2DD0-\u2DD6\u2DD8-\u2DDE\u2DE0-\u2DFF\u2E2F\u3005-\u3007\u3021-\u302F\u3031-\u3035\u3038-\u303C\u3041-\u3096\u3099\u309A\u309D-\u309F\u30A1-\u30FA\u30FC-\u30FF\u3105-\u312D\u3131-\u318E\u31A0-\u31BA\u31F0-\u31FF\u3400-\u4DB5\u4E00-\u9FCC\uA000-\uA48C\uA4D0-\uA4FD\uA500-\uA60C\uA610-\uA62B\uA640-\uA66F\uA674-\uA67D\uA67F-\uA69D\uA69F-\uA6F1\uA717-\uA71F\uA722-\uA788\uA78B-\uA78E\uA790-\uA7AD\uA7B0\uA7B1\uA7F7-\uA827\uA840-\uA873\uA880-\uA8C4\uA8D0-\uA8D9\uA8E0-\uA8F7\uA8FB\uA900-\uA92D\uA930-\uA953\uA960-\uA97C\uA980-\uA9C0\uA9CF-\uA9D9\uA9E0-\uA9FE\uAA00-\uAA36\uAA40-\uAA4D\uAA50-\uAA59\uAA60-\uAA76\uAA7A-\uAAC2\uAADB-\uAADD\uAAE0-\uAAEF\uAAF2-\uAAF6\uAB01-\uAB06\uAB09-\uAB0E\uAB11-\uAB16\uAB20-\uAB26\uAB28-\uAB2E\uAB30-\uAB5A\uAB5C-\uAB5F\uAB64\uAB65\uABC0-\uABEA\uABEC\uABED\uABF0-\uABF9\uAC00-\uD7A3\uD7B0-\uD7C6\uD7CB-\uD7FB\uF900-\uFA6D\uFA70-\uFAD9\uFB00-\uFB06\uFB13-\uFB17\uFB1D-\uFB28\uFB2A-\uFB36\uFB38-\uFB3C\uFB3E\uFB40\uFB41\uFB43\uFB44\uFB46-\uFBB1\uFBD3-\uFD3D\uFD50-\uFD8F\uFD92-\uFDC7\uFDF0-\uFDFB\uFE00-\uFE0F\uFE20-\uFE2D\uFE33\uFE34\uFE4D-\uFE4F\uFE70-\uFE74\uFE76-\uFEFC\uFF10-\uFF19\uFF21-\uFF3A\uFF3F\uFF41-\uFF5A\uFF66-\uFFBE\uFFC2-\uFFC7\uFFCA-\uFFCF\uFFD2-\uFFD7\uFFDA-\uFFDC]'); + +// Ensure the condition is true, otherwise throw an error. +// This is only to have a better contract semantic, i.e. another safety net +// to catch a logic error. The condition shall be fulfilled in normal case. +// Do NOT use this to enforce a certain condition on any user input. + +function assert(condition, message) { + /* istanbul ignore next */ + if (!condition) { + throw new Error('ASSERT: ' + message); + } +} + +function isDecimalDigit(ch) { + return (ch >= 0x30 && ch <= 0x39); // 0..9 +} + +function isHexDigit(ch) { + return '0123456789abcdefABCDEF'.indexOf(ch) >= 0; +} + +function isOctalDigit(ch) { + return '01234567'.indexOf(ch) >= 0; +} + +// 7.2 White Space + +function isWhiteSpace(ch) { + return (ch === 0x20) || (ch === 0x09) || (ch === 0x0B) || (ch === 0x0C) || (ch === 0xA0) || + (ch >= 0x1680 && [0x1680, 0x180E, 0x2000, 0x2001, 0x2002, 0x2003, 0x2004, 0x2005, 0x2006, 0x2007, 0x2008, 0x2009, 0x200A, 0x202F, 0x205F, 0x3000, 0xFEFF].indexOf(ch) >= 0); +} + +// 7.3 Line Terminators + +function isLineTerminator(ch) { + return (ch === 0x0A) || (ch === 0x0D) || (ch === 0x2028) || (ch === 0x2029); +} + +// 7.6 Identifier Names and Identifiers + +function isIdentifierStart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && RegexNonAsciiIdentifierStart.test(String.fromCharCode(ch))); +} + +function isIdentifierPart(ch) { + return (ch === 0x24) || (ch === 0x5F) || // $ (dollar) and _ (underscore) + (ch >= 0x41 && ch <= 0x5A) || // A..Z + (ch >= 0x61 && ch <= 0x7A) || // a..z + (ch >= 0x30 && ch <= 0x39) || // 0..9 + (ch === 0x5C) || // \ (backslash) + ((ch >= 0x80) && RegexNonAsciiIdentifierPart.test(String.fromCharCode(ch))); +} + +// 7.6.1.1 Keywords + +var keywords$1 = { + 'if':1, 'in':1, 'do':1, + 'var':1, 'for':1, 'new':1, 'try':1, 'let':1, + 'this':1, 'else':1, 'case':1, 'void':1, 'with':1, 'enum':1, + 'while':1, 'break':1, 'catch':1, 'throw':1, 'const':1, 'yield':1, 'class':1, 'super':1, + 'return':1, 'typeof':1, 'delete':1, 'switch':1, 'export':1, 'import':1, 'public':1, 'static':1, + 'default':1, 'finally':1, 'extends':1, 'package':1, 'private':1, + 'function':1, 'continue':1, 'debugger':1, + 'interface':1, 'protected':1, + 'instanceof':1, 'implements':1 +}; + +function skipComment() { + var ch; + + while (index$1 < length$2) { + ch = source$1.charCodeAt(index$1); + + if (isWhiteSpace(ch) || isLineTerminator(ch)) { + ++index$1; + } else { + break; + } + } +} + +function scanHexEscape(prefix) { + var i, len, ch, code = 0; + + len = (prefix === 'u') ? 4 : 2; + for (i = 0; i < len; ++i) { + if (index$1 < length$2 && isHexDigit(source$1[index$1])) { + ch = source$1[index$1++]; + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } else { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + } + return String.fromCharCode(code); +} + +function scanUnicodeCodePointEscape() { + var ch, code, cu1, cu2; + + ch = source$1[index$1]; + code = 0; + + // At least, one hex digit is required. + if (ch === '}') { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + while (index$1 < length$2) { + ch = source$1[index$1++]; + if (!isHexDigit(ch)) { + break; + } + code = code * 16 + '0123456789abcdef'.indexOf(ch.toLowerCase()); + } + + if (code > 0x10FFFF || ch !== '}') { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + // UTF-16 Encoding + if (code <= 0xFFFF) { + return String.fromCharCode(code); + } + cu1 = ((code - 0x10000) >> 10) + 0xD800; + cu2 = ((code - 0x10000) & 1023) + 0xDC00; + return String.fromCharCode(cu1, cu2); +} + +function getEscapedIdentifier() { + var ch, id; + + ch = source$1.charCodeAt(index$1++); + id = String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + if (source$1.charCodeAt(index$1) !== 0x75) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + ++index$1; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierStart(ch.charCodeAt(0))) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + id = ch; + } + + while (index$1 < length$2) { + ch = source$1.charCodeAt(index$1); + if (!isIdentifierPart(ch)) { + break; + } + ++index$1; + id += String.fromCharCode(ch); + + // '\u' (U+005C, U+0075) denotes an escaped character. + if (ch === 0x5C) { + id = id.substr(0, id.length - 1); + if (source$1.charCodeAt(index$1) !== 0x75) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + ++index$1; + ch = scanHexEscape('u'); + if (!ch || ch === '\\' || !isIdentifierPart(ch.charCodeAt(0))) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + id += ch; + } + } + + return id; +} + +function getIdentifier() { + var start, ch; + + start = index$1++; + while (index$1 < length$2) { + ch = source$1.charCodeAt(index$1); + if (ch === 0x5C) { + // Blackslash (U+005C) marks Unicode escape sequence. + index$1 = start; + return getEscapedIdentifier(); + } + if (isIdentifierPart(ch)) { + ++index$1; + } else { + break; + } + } + + return source$1.slice(start, index$1); +} + +function scanIdentifier() { + var start, id, type; + + start = index$1; + + // Backslash (U+005C) starts an escaped character. + id = (source$1.charCodeAt(index$1) === 0x5C) ? getEscapedIdentifier() : getIdentifier(); + + // There is no keyword or literal with only one character. + // Thus, it must be an identifier. + if (id.length === 1) { + type = TokenIdentifier; + } else if (keywords$1.hasOwnProperty(id)) { + type = TokenKeyword; + } else if (id === 'null') { + type = TokenNullLiteral; + } else if (id === 'true' || id === 'false') { + type = TokenBooleanLiteral; + } else { + type = TokenIdentifier; + } + + return { + type: type, + value: id, + start: start, + end: index$1 + }; +} + +// 7.7 Punctuators + +function scanPunctuator() { + var start = index$1, + code = source$1.charCodeAt(index$1), + code2, + ch1 = source$1[index$1], + ch2, + ch3, + ch4; + + switch (code) { + + // Check for most common single-character punctuators. + case 0x2E: // . dot + case 0x28: // ( open bracket + case 0x29: // ) close bracket + case 0x3B: // ; semicolon + case 0x2C: // , comma + case 0x7B: // { open curly brace + case 0x7D: // } close curly brace + case 0x5B: // [ + case 0x5D: // ] + case 0x3A: // : + case 0x3F: // ? + case 0x7E: // ~ + ++index$1; + return { + type: TokenPunctuator, + value: String.fromCharCode(code), + start: start, + end: index$1 + }; + + default: + code2 = source$1.charCodeAt(index$1 + 1); + + // '=' (U+003D) marks an assignment or comparison operator. + if (code2 === 0x3D) { + switch (code) { + case 0x2B: // + + case 0x2D: // - + case 0x2F: // / + case 0x3C: // < + case 0x3E: // > + case 0x5E: // ^ + case 0x7C: // | + case 0x25: // % + case 0x26: // & + case 0x2A: // * + index$1 += 2; + return { + type: TokenPunctuator, + value: String.fromCharCode(code) + String.fromCharCode(code2), + start: start, + end: index$1 + }; + + case 0x21: // ! + case 0x3D: // = + index$1 += 2; + + // !== and === + if (source$1.charCodeAt(index$1) === 0x3D) { + ++index$1; + } + return { + type: TokenPunctuator, + value: source$1.slice(start, index$1), + start: start, + end: index$1 + }; + } + } + } + + // 4-character punctuator: >>>= + + ch4 = source$1.substr(index$1, 4); + + if (ch4 === '>>>=') { + index$1 += 4; + return { + type: TokenPunctuator, + value: ch4, + start: start, + end: index$1 + }; + } + + // 3-character punctuators: === !== >>> <<= >>= + + ch3 = ch4.substr(0, 3); + + if (ch3 === '>>>' || ch3 === '<<=' || ch3 === '>>=') { + index$1 += 3; + return { + type: TokenPunctuator, + value: ch3, + start: start, + end: index$1 + }; + } + + // Other 2-character punctuators: ++ -- << >> && || + ch2 = ch3.substr(0, 2); + + if ((ch1 === ch2[1] && ('+-<>&|'.indexOf(ch1) >= 0)) || ch2 === '=>') { + index$1 += 2; + return { + type: TokenPunctuator, + value: ch2, + start: start, + end: index$1 + }; + } + + // 1-character punctuators: < > = ! + - * % & | ^ / + + if ('<>=!+-*%&|^/'.indexOf(ch1) >= 0) { + ++index$1; + return { + type: TokenPunctuator, + value: ch1, + start: start, + end: index$1 + }; + } + + throwError({}, MessageUnexpectedToken, ILLEGAL); +} + +// 7.8.3 Numeric Literals + +function scanHexLiteral(start) { + var number = ''; + + while (index$1 < length$2) { + if (!isHexDigit(source$1[index$1])) { + break; + } + number += source$1[index$1++]; + } + + if (number.length === 0) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + if (isIdentifierStart(source$1.charCodeAt(index$1))) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + return { + type: TokenNumericLiteral, + value: parseInt('0x' + number, 16), + start: start, + end: index$1 + }; +} + +function scanOctalLiteral(start) { + var number = '0' + source$1[index$1++]; + while (index$1 < length$2) { + if (!isOctalDigit(source$1[index$1])) { + break; + } + number += source$1[index$1++]; + } + + if (isIdentifierStart(source$1.charCodeAt(index$1)) || isDecimalDigit(source$1.charCodeAt(index$1))) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + return { + type: TokenNumericLiteral, + value: parseInt(number, 8), + octal: true, + start: start, + end: index$1 + }; +} + +function scanNumericLiteral() { + var number, start, ch; + + ch = source$1[index$1]; + assert(isDecimalDigit(ch.charCodeAt(0)) || (ch === '.'), + 'Numeric literal must start with a decimal digit or a decimal point'); + + start = index$1; + number = ''; + if (ch !== '.') { + number = source$1[index$1++]; + ch = source$1[index$1]; + + // Hex number starts with '0x'. + // Octal number starts with '0'. + if (number === '0') { + if (ch === 'x' || ch === 'X') { + ++index$1; + return scanHexLiteral(start); + } + if (isOctalDigit(ch)) { + return scanOctalLiteral(start); + } + + // decimal number starts with '0' such as '09' is illegal. + if (ch && isDecimalDigit(ch.charCodeAt(0))) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + } + + while (isDecimalDigit(source$1.charCodeAt(index$1))) { + number += source$1[index$1++]; + } + ch = source$1[index$1]; + } + + if (ch === '.') { + number += source$1[index$1++]; + while (isDecimalDigit(source$1.charCodeAt(index$1))) { + number += source$1[index$1++]; + } + ch = source$1[index$1]; + } + + if (ch === 'e' || ch === 'E') { + number += source$1[index$1++]; + + ch = source$1[index$1]; + if (ch === '+' || ch === '-') { + number += source$1[index$1++]; + } + if (isDecimalDigit(source$1.charCodeAt(index$1))) { + while (isDecimalDigit(source$1.charCodeAt(index$1))) { + number += source$1[index$1++]; + } + } else { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + } + + if (isIdentifierStart(source$1.charCodeAt(index$1))) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + return { + type: TokenNumericLiteral, + value: parseFloat(number), + start: start, + end: index$1 + }; +} + +// 7.8.4 String Literals + +function scanStringLiteral() { + var str = '', + quote, start, ch, code, octal = false; + + quote = source$1[index$1]; + assert((quote === '\'' || quote === '"'), + 'String literal must starts with a quote'); + + start = index$1; + ++index$1; + + while (index$1 < length$2) { + ch = source$1[index$1++]; + + if (ch === quote) { + quote = ''; + break; + } else if (ch === '\\') { + ch = source$1[index$1++]; + if (!ch || !isLineTerminator(ch.charCodeAt(0))) { + switch (ch) { + case 'u': + case 'x': + if (source$1[index$1] === '{') { + ++index$1; + str += scanUnicodeCodePointEscape(); + } else { + str += scanHexEscape(ch); + } + break; + case 'n': + str += '\n'; + break; + case 'r': + str += '\r'; + break; + case 't': + str += '\t'; + break; + case 'b': + str += '\b'; + break; + case 'f': + str += '\f'; + break; + case 'v': + str += '\x0B'; + break; + + default: + if (isOctalDigit(ch)) { + code = '01234567'.indexOf(ch); + + // \0 is not octal escape sequence + if (code !== 0) { + octal = true; + } + + if (index$1 < length$2 && isOctalDigit(source$1[index$1])) { + octal = true; + code = code * 8 + '01234567'.indexOf(source$1[index$1++]); + + // 3 digits are only allowed when string starts + // with 0, 1, 2, 3 + if ('0123'.indexOf(ch) >= 0 && + index$1 < length$2 && + isOctalDigit(source$1[index$1])) { + code = code * 8 + '01234567'.indexOf(source$1[index$1++]); + } + } + str += String.fromCharCode(code); + } else { + str += ch; + } + break; + } + } else { + if (ch === '\r' && source$1[index$1] === '\n') { + ++index$1; + } + } + } else if (isLineTerminator(ch.charCodeAt(0))) { + break; + } else { + str += ch; + } + } + + if (quote !== '') { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } + + return { + type: TokenStringLiteral, + value: str, + octal: octal, + start: start, + end: index$1 + }; +} + +function testRegExp(pattern, flags) { + var tmp = pattern; + + if (flags.indexOf('u') >= 0) { + // Replace each astral symbol and every Unicode code point + // escape sequence with a single ASCII symbol to avoid throwing on + // regular expressions that are only valid in combination with the + // `/u` flag. + // Note: replacing with the ASCII symbol `x` might cause false + // negatives in unlikely scenarios. For example, `[\u{61}-b]` is a + // perfectly valid pattern that is equivalent to `[a-b]`, but it + // would be replaced by `[x-b]` which throws an error. + tmp = tmp + .replace(/\\u\{([0-9a-fA-F]+)\}/g, function($0, $1) { + if (parseInt($1, 16) <= 0x10FFFF) { + return 'x'; + } + throwError({}, MessageInvalidRegExp); + }) + .replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g, 'x'); + } + + // First, detect invalid regular expressions. + try { + new RegExp(tmp); + } catch (e) { + throwError({}, MessageInvalidRegExp); + } + + // Return a regular expression object for this pattern-flag pair, or + // `null` in case the current environment doesn't support the flags it + // uses. + try { + return new RegExp(pattern, flags); + } catch (exception) { + return null; + } +} + +function scanRegExpBody() { + var ch, str, classMarker, terminated, body; + + ch = source$1[index$1]; + assert(ch === '/', 'Regular expression literal must start with a slash'); + str = source$1[index$1++]; + + classMarker = false; + terminated = false; + while (index$1 < length$2) { + ch = source$1[index$1++]; + str += ch; + if (ch === '\\') { + ch = source$1[index$1++]; + // ECMA-262 7.8.5 + if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, MessageUnterminatedRegExp); + } + str += ch; + } else if (isLineTerminator(ch.charCodeAt(0))) { + throwError({}, MessageUnterminatedRegExp); + } else if (classMarker) { + if (ch === ']') { + classMarker = false; + } + } else { + if (ch === '/') { + terminated = true; + break; + } else if (ch === '[') { + classMarker = true; + } + } + } + + if (!terminated) { + throwError({}, MessageUnterminatedRegExp); + } + + // Exclude leading and trailing slash. + body = str.substr(1, str.length - 2); + return { + value: body, + literal: str + }; +} + +function scanRegExpFlags() { + var ch, str, flags; + + str = ''; + flags = ''; + while (index$1 < length$2) { + ch = source$1[index$1]; + if (!isIdentifierPart(ch.charCodeAt(0))) { + break; + } + + ++index$1; + if (ch === '\\' && index$1 < length$2) { + throwError({}, MessageUnexpectedToken, ILLEGAL); + } else { + flags += ch; + str += ch; + } + } + + if (flags.search(/[^gimuy]/g) >= 0) { + throwError({}, MessageInvalidRegExp, flags); + } + + return { + value: flags, + literal: str + }; +} + +function scanRegExp() { + var start, body, flags, value; + + lookahead = null; + skipComment(); + start = index$1; + + body = scanRegExpBody(); + flags = scanRegExpFlags(); + value = testRegExp(body.value, flags.value); + + return { + literal: body.literal + flags.literal, + value: value, + regex: { + pattern: body.value, + flags: flags.value + }, + start: start, + end: index$1 + }; +} + +function isIdentifierName(token) { + return token.type === TokenIdentifier || + token.type === TokenKeyword || + token.type === TokenBooleanLiteral || + token.type === TokenNullLiteral; +} + +function advance() { + var ch; + + skipComment(); + + if (index$1 >= length$2) { + return { + type: TokenEOF, + start: index$1, + end: index$1 + }; + } + + ch = source$1.charCodeAt(index$1); + + if (isIdentifierStart(ch)) { + return scanIdentifier(); + } + + // Very common: ( and ) and ; + if (ch === 0x28 || ch === 0x29 || ch === 0x3B) { + return scanPunctuator(); + } + + // String literal starts with single quote (U+0027) or double quote (U+0022). + if (ch === 0x27 || ch === 0x22) { + return scanStringLiteral(); + } + + + // Dot (.) U+002E can also start a floating-point number, hence the need + // to check the next character. + if (ch === 0x2E) { + if (isDecimalDigit(source$1.charCodeAt(index$1 + 1))) { + return scanNumericLiteral(); + } + return scanPunctuator(); + } + + if (isDecimalDigit(ch)) { + return scanNumericLiteral(); + } + + return scanPunctuator(); +} + +function lex() { + var token; + + token = lookahead; + index$1 = token.end; + + lookahead = advance(); + + index$1 = token.end; + + return token; +} + +function peek$1() { + var pos; + + pos = index$1; + + lookahead = advance(); + index$1 = pos; +} + +function finishArrayExpression(elements) { + var node = new ASTNode(SyntaxArrayExpression); + node.elements = elements; + return node; +} + +function finishBinaryExpression(operator, left, right) { + var node = new ASTNode((operator === '||' || operator === '&&') ? SyntaxLogicalExpression : SyntaxBinaryExpression); + node.operator = operator; + node.left = left; + node.right = right; + return node; +} + +function finishCallExpression(callee, args) { + var node = new ASTNode(SyntaxCallExpression); + node.callee = callee; + node.arguments = args; + return node; +} + +function finishConditionalExpression(test, consequent, alternate) { + var node = new ASTNode(SyntaxConditionalExpression); + node.test = test; + node.consequent = consequent; + node.alternate = alternate; + return node; +} + +function finishIdentifier(name) { + var node = new ASTNode(SyntaxIdentifier); + node.name = name; + return node; +} + +function finishLiteral(token) { + var node = new ASTNode(SyntaxLiteral); + node.value = token.value; + node.raw = source$1.slice(token.start, token.end); + if (token.regex) { + if (node.raw === '//') { + node.raw = '/(?:)/'; + } + node.regex = token.regex; + } + return node; +} + +function finishMemberExpression(accessor, object, property) { + var node = new ASTNode(SyntaxMemberExpression); + node.computed = accessor === '['; + node.object = object; + node.property = property; + if (!node.computed) property.member = true; + return node; +} + +function finishObjectExpression(properties) { + var node = new ASTNode(SyntaxObjectExpression); + node.properties = properties; + return node; +} + +function finishProperty(kind, key, value) { + var node = new ASTNode(SyntaxProperty); + node.key = key; + node.value = value; + node.kind = kind; + return node; +} + +function finishUnaryExpression(operator, argument) { + var node = new ASTNode(SyntaxUnaryExpression); + node.operator = operator; + node.argument = argument; + node.prefix = true; + return node; +} + +// Throw an exception + +function throwError(token, messageFormat) { + var error, + args = Array.prototype.slice.call(arguments, 2), + msg = messageFormat.replace( + /%(\d)/g, + function(whole, index) { + assert(index < args.length, 'Message reference must be in range'); + return args[index]; + } + ); + + + error = new Error(msg); + error.index = index$1; + error.description = msg; + throw error; +} + +// Throw an exception because of the token. + +function throwUnexpected(token) { + if (token.type === TokenEOF) { + throwError(token, MessageUnexpectedEOS); + } + + if (token.type === TokenNumericLiteral) { + throwError(token, MessageUnexpectedNumber); + } + + if (token.type === TokenStringLiteral) { + throwError(token, MessageUnexpectedString); + } + + if (token.type === TokenIdentifier) { + throwError(token, MessageUnexpectedIdentifier); + } + + if (token.type === TokenKeyword) { + throwError(token, MessageUnexpectedReserved); + } + + // BooleanLiteral, NullLiteral, or Punctuator. + throwError(token, MessageUnexpectedToken, token.value); +} + +// Expect the next token to match the specified punctuator. +// If not, an exception will be thrown. + +function expect(value) { + var token = lex(); + if (token.type !== TokenPunctuator || token.value !== value) { + throwUnexpected(token); + } +} + +// Return true if the next token matches the specified punctuator. + +function match(value) { + return lookahead.type === TokenPunctuator && lookahead.value === value; +} + +// Return true if the next token matches the specified keyword + +function matchKeyword(keyword) { + return lookahead.type === TokenKeyword && lookahead.value === keyword; +} + +// 11.1.4 Array Initialiser + +function parseArrayInitialiser() { + var elements = []; + + index$1 = lookahead.start; + expect('['); + + while (!match(']')) { + if (match(',')) { + lex(); + elements.push(null); + } else { + elements.push(parseConditionalExpression()); + + if (!match(']')) { + expect(','); + } + } + } + + lex(); + + return finishArrayExpression(elements); +} + +// 11.1.5 Object Initialiser + +function parseObjectPropertyKey() { + var token; + + index$1 = lookahead.start; + token = lex(); + + // Note: This function is called only from parseObjectProperty(), where + // EOF and Punctuator tokens are already filtered out. + + if (token.type === TokenStringLiteral || token.type === TokenNumericLiteral) { + if (token.octal) { + throwError(token, MessageStrictOctalLiteral); + } + return finishLiteral(token); + } + + return finishIdentifier(token.value); +} + +function parseObjectProperty() { + var token, key, id, value; + + index$1 = lookahead.start; + token = lookahead; + + if (token.type === TokenIdentifier) { + id = parseObjectPropertyKey(); + expect(':'); + value = parseConditionalExpression(); + return finishProperty('init', id, value); + } + if (token.type === TokenEOF || token.type === TokenPunctuator) { + throwUnexpected(token); + } else { + key = parseObjectPropertyKey(); + expect(':'); + value = parseConditionalExpression(); + return finishProperty('init', key, value); + } +} + +function parseObjectInitialiser() { + var properties = [], + property, name, key, map = {}, + toString = String; + + index$1 = lookahead.start; + expect('{'); + + while (!match('}')) { + property = parseObjectProperty(); + + if (property.key.type === SyntaxIdentifier) { + name = property.key.name; + } else { + name = toString(property.key.value); + } + + key = '$' + name; + if (Object.prototype.hasOwnProperty.call(map, key)) { + throwError({}, MessageStrictDuplicateProperty); + } else { + map[key] = true; + } + + properties.push(property); + + if (!match('}')) { + expect(','); + } + } + + expect('}'); + + return finishObjectExpression(properties); +} + +// 11.1.6 The Grouping Operator + +function parseGroupExpression() { + var expr; + + expect('('); + + expr = parseExpression$1(); + + expect(')'); + + return expr; +} + + +// 11.1 Primary Expressions + +var legalKeywords = { + "if": 1, + "this": 1 +}; + +function parsePrimaryExpression() { + var type, token, expr; + + if (match('(')) { + return parseGroupExpression(); + } + + if (match('[')) { + return parseArrayInitialiser(); + } + + if (match('{')) { + return parseObjectInitialiser(); + } + + type = lookahead.type; + index$1 = lookahead.start; + + + if (type === TokenIdentifier || legalKeywords[lookahead.value]) { + expr = finishIdentifier(lex().value); + } else if (type === TokenStringLiteral || type === TokenNumericLiteral) { + if (lookahead.octal) { + throwError(lookahead, MessageStrictOctalLiteral); + } + expr = finishLiteral(lex()); + } else if (type === TokenKeyword) { + throw new Error(DISABLED); + } else if (type === TokenBooleanLiteral) { + token = lex(); + token.value = (token.value === 'true'); + expr = finishLiteral(token); + } else if (type === TokenNullLiteral) { + token = lex(); + token.value = null; + expr = finishLiteral(token); + } else if (match('/') || match('/=')) { + expr = finishLiteral(scanRegExp()); + peek$1(); + } else { + throwUnexpected(lex()); + } + + return expr; +} + +// 11.2 Left-Hand-Side Expressions + +function parseArguments() { + var args = []; + + expect('('); + + if (!match(')')) { + while (index$1 < length$2) { + args.push(parseConditionalExpression()); + if (match(')')) { + break; + } + expect(','); + } + } + + expect(')'); + + return args; +} + +function parseNonComputedProperty() { + var token; + index$1 = lookahead.start; + token = lex(); + + if (!isIdentifierName(token)) { + throwUnexpected(token); + } + + return finishIdentifier(token.value); +} + +function parseNonComputedMember() { + expect('.'); + + return parseNonComputedProperty(); +} + +function parseComputedMember() { + var expr; + + expect('['); + + expr = parseExpression$1(); + + expect(']'); + + return expr; +} + +function parseLeftHandSideExpressionAllowCall() { + var expr, args, property; + + expr = parsePrimaryExpression(); + + for (;;) { + if (match('.')) { + property = parseNonComputedMember(); + expr = finishMemberExpression('.', expr, property); + } else if (match('(')) { + args = parseArguments(); + expr = finishCallExpression(expr, args); + } else if (match('[')) { + property = parseComputedMember(); + expr = finishMemberExpression('[', expr, property); + } else { + break; + } + } + + return expr; +} + +// 11.3 Postfix Expressions + +function parsePostfixExpression() { + var expr = parseLeftHandSideExpressionAllowCall(); + + if (lookahead.type === TokenPunctuator) { + if ((match('++') || match('--'))) { + throw new Error(DISABLED); + } + } + + return expr; +} + +// 11.4 Unary Operators + +function parseUnaryExpression() { + var token, expr; + + if (lookahead.type !== TokenPunctuator && lookahead.type !== TokenKeyword) { + expr = parsePostfixExpression(); + } else if (match('++') || match('--')) { + throw new Error(DISABLED); + } else if (match('+') || match('-') || match('~') || match('!')) { + token = lex(); + expr = parseUnaryExpression(); + expr = finishUnaryExpression(token.value, expr); + } else if (matchKeyword('delete') || matchKeyword('void') || matchKeyword('typeof')) { + throw new Error(DISABLED); + } else { + expr = parsePostfixExpression(); + } + + return expr; +} + +function binaryPrecedence(token) { + var prec = 0; + + if (token.type !== TokenPunctuator && token.type !== TokenKeyword) { + return 0; + } + + switch (token.value) { + case '||': + prec = 1; + break; + + case '&&': + prec = 2; + break; + + case '|': + prec = 3; + break; + + case '^': + prec = 4; + break; + + case '&': + prec = 5; + break; + + case '==': + case '!=': + case '===': + case '!==': + prec = 6; + break; + + case '<': + case '>': + case '<=': + case '>=': + case 'instanceof': + case 'in': + prec = 7; + break; + + case '<<': + case '>>': + case '>>>': + prec = 8; + break; + + case '+': + case '-': + prec = 9; + break; + + case '*': + case '/': + case '%': + prec = 11; + break; + + default: + break; + } + + return prec; +} + +// 11.5 Multiplicative Operators +// 11.6 Additive Operators +// 11.7 Bitwise Shift Operators +// 11.8 Relational Operators +// 11.9 Equality Operators +// 11.10 Binary Bitwise Operators +// 11.11 Binary Logical Operators + +function parseBinaryExpression() { + var marker, markers, expr, token, prec, stack, right, operator, left, i; + + marker = lookahead; + left = parseUnaryExpression(); + + token = lookahead; + prec = binaryPrecedence(token); + if (prec === 0) { + return left; + } + token.prec = prec; + lex(); + + markers = [marker, lookahead]; + right = parseUnaryExpression(); + + stack = [left, token, right]; + + while ((prec = binaryPrecedence(lookahead)) > 0) { + + // Reduce: make a binary expression from the three topmost entries. + while ((stack.length > 2) && (prec <= stack[stack.length - 2].prec)) { + right = stack.pop(); + operator = stack.pop().value; + left = stack.pop(); + markers.pop(); + expr = finishBinaryExpression(operator, left, right); + stack.push(expr); + } + + // Shift. + token = lex(); + token.prec = prec; + stack.push(token); + markers.push(lookahead); + expr = parseUnaryExpression(); + stack.push(expr); + } + + // Final reduce to clean-up the stack. + i = stack.length - 1; + expr = stack[i]; + markers.pop(); + while (i > 1) { + markers.pop(); + expr = finishBinaryExpression(stack[i - 1].value, stack[i - 2], expr); + i -= 2; + } + + return expr; +} + +// 11.12 Conditional Operator + +function parseConditionalExpression() { + var expr, consequent, alternate; + + expr = parseBinaryExpression(); + + if (match('?')) { + lex(); + consequent = parseConditionalExpression(); + expect(':'); + alternate = parseConditionalExpression(); + + expr = finishConditionalExpression(expr, consequent, alternate); + } + + return expr; +} + +// 11.14 Comma Operator + +function parseExpression$1() { + var expr = parseConditionalExpression(); + + if (match(',')) { + throw new Error(DISABLED); // no sequence expressions + } + + return expr; +} + +var parse$3 = function(code) { + source$1 = code; + index$1 = 0; + length$2 = source$1.length; + lookahead = null; + + peek$1(); + + var expr = parseExpression$1(); + + if (lookahead.type !== TokenEOF) { + throw new Error("Unexpect token after expression."); + } + return expr; +}; + +var Constants = { + NaN: 'NaN', + E: 'Math.E', + LN2: 'Math.LN2', + LN10: 'Math.LN10', + LOG2E: 'Math.LOG2E', + LOG10E: 'Math.LOG10E', + PI: 'Math.PI', + SQRT1_2: 'Math.SQRT1_2', + SQRT2: 'Math.SQRT2', + MIN_VALUE: 'Number.MIN_VALUE', + MAX_VALUE: 'Number.MAX_VALUE' +}; + +var Functions = function(codegen) { + + function fncall(name, args, cast, type) { + var obj = codegen(args[0]); + if (cast) { + obj = cast + '(' + obj + ')'; + if (cast.lastIndexOf('new ', 0) === 0) obj = '(' + obj + ')'; + } + return obj + '.' + name + (type < 0 ? '' : type === 0 ? + '()' : + '(' + args.slice(1).map(codegen).join(',') + ')'); + } + + function fn(name, cast, type) { + return function(args) { + return fncall(name, args, cast, type); + }; + } + + var DATE = 'new Date', + STRING = 'String', + REGEXP = 'RegExp'; + + return { + // MATH functions + isNaN: 'isNaN', + isFinite: 'isFinite', + abs: 'Math.abs', + acos: 'Math.acos', + asin: 'Math.asin', + atan: 'Math.atan', + atan2: 'Math.atan2', + ceil: 'Math.ceil', + cos: 'Math.cos', + exp: 'Math.exp', + floor: 'Math.floor', + log: 'Math.log', + max: 'Math.max', + min: 'Math.min', + pow: 'Math.pow', + random: 'Math.random', + round: 'Math.round', + sin: 'Math.sin', + sqrt: 'Math.sqrt', + tan: 'Math.tan', + + clamp: function(args) { + if (args.length < 3) error$1('Missing arguments to clamp function.'); + if (args.length > 3) error$1('Too many arguments to clamp function.'); + var a = args.map(codegen); + return 'Math.max('+a[1]+', Math.min('+a[2]+','+a[0]+'))'; + }, + + // DATE functions + now: 'Date.now', + utc: 'Date.UTC', + datetime: DATE, + date: fn('getDate', DATE, 0), + day: fn('getDay', DATE, 0), + year: fn('getFullYear', DATE, 0), + month: fn('getMonth', DATE, 0), + hours: fn('getHours', DATE, 0), + minutes: fn('getMinutes', DATE, 0), + seconds: fn('getSeconds', DATE, 0), + milliseconds: fn('getMilliseconds', DATE, 0), + time: fn('getTime', DATE, 0), + timezoneoffset: fn('getTimezoneOffset', DATE, 0), + utcdate: fn('getUTCDate', DATE, 0), + utcday: fn('getUTCDay', DATE, 0), + utcyear: fn('getUTCFullYear', DATE, 0), + utcmonth: fn('getUTCMonth', DATE, 0), + utchours: fn('getUTCHours', DATE, 0), + utcminutes: fn('getUTCMinutes', DATE, 0), + utcseconds: fn('getUTCSeconds', DATE, 0), + utcmilliseconds: fn('getUTCMilliseconds', DATE, 0), + + // shared sequence functions + length: fn('length', null, -1), + indexof: fn('indexOf', null), + lastindexof: fn('lastIndexOf', null), + slice: fn('slice', null), + + // STRING functions + parseFloat: 'parseFloat', + parseInt: 'parseInt', + upper: fn('toUpperCase', STRING, 0), + lower: fn('toLowerCase', STRING, 0), + substring: fn('substring', STRING), + replace: fn('replace', STRING), + + // REGEXP functions + regexp: REGEXP, + test: fn('test', REGEXP), + + // Control Flow functions + if: function(args) { + if (args.length < 3) error$1('Missing arguments to if function.'); + if (args.length > 3) error$1('Too many arguments to if function.'); + var a = args.map(codegen); + return '('+a[0]+'?'+a[1]+':'+a[2]+')'; + } + }; +}; + +var codegen = function(opt) { + opt = opt || {}; + + var whitelist = opt.whitelist ? toSet(opt.whitelist) : {}, + blacklist = opt.blacklist ? toSet(opt.blacklist) : {}, + constants = opt.constants || Constants, + functions = (opt.functions || Functions)(visit), + globalvar = opt.globalvar, + fieldvar = opt.fieldvar, + globals = {}, + fields = {}, + memberDepth = 0; + + var outputGlobal = isFunction(globalvar) + ? globalvar + : function (id$$1) { return globalvar + '["' + id$$1 + '"]'; }; + + function visit(ast) { + if (isString(ast)) return ast; + var generator = Generators[ast.type]; + if (generator == null) error$1('Unsupported type: ' + ast.type); + return generator(ast); + } + + var Generators = { + Literal: function(n) { + return n.raw; + }, + + Identifier: function(n) { + var id$$1 = n.name; + if (memberDepth > 0) { + return id$$1; + } else if (blacklist.hasOwnProperty(id$$1)) { + return error$1('Illegal identifier: ' + id$$1); + } else if (constants.hasOwnProperty(id$$1)) { + return constants[id$$1]; + } else if (whitelist.hasOwnProperty(id$$1)) { + return id$$1; + } else { + globals[id$$1] = 1; + return outputGlobal(id$$1); + } + }, + + MemberExpression: function(n) { + var d = !n.computed; + var o = visit(n.object); + if (d) memberDepth += 1; + var p = visit(n.property); + if (o === fieldvar) { fields[p] = 1; } // HACKish... + if (d) memberDepth -= 1; + return o + (d ? '.'+p : '['+p+']'); + }, + + CallExpression: function(n) { + if (n.callee.type !== 'Identifier') { + error$1('Illegal callee type: ' + n.callee.type); + } + var callee = n.callee.name; + var args = n.arguments; + var fn = functions.hasOwnProperty(callee) && functions[callee]; + if (!fn) error$1('Unrecognized function: ' + callee); + return isFunction(fn) + ? fn(args) + : fn + '(' + args.map(visit).join(',') + ')'; + }, + + ArrayExpression: function(n) { + return '[' + n.elements.map(visit).join(',') + ']'; + }, + + BinaryExpression: function(n) { + return '(' + visit(n.left) + n.operator + visit(n.right) + ')'; + }, + + UnaryExpression: function(n) { + return '(' + n.operator + visit(n.argument) + ')'; + }, + + ConditionalExpression: function(n) { + return '(' + visit(n.test) + + '?' + visit(n.consequent) + + ':' + visit(n.alternate) + + ')'; + }, + + LogicalExpression: function(n) { + return '(' + visit(n.left) + n.operator + visit(n.right) + ')'; + }, + + ObjectExpression: function(n) { + return '{' + n.properties.map(visit).join(',') + '}'; + }, + + Property: function(n) { + memberDepth += 1; + var k = visit(n.key); + memberDepth -= 1; + return k + ':' + visit(n.value); + } + }; + + function codegen(ast) { + var result = { + code: visit(ast), + globals: Object.keys(globals), + fields: Object.keys(fields) + }; + globals = {}; + fields = {}; + return result; + } + + codegen.functions = functions; + codegen.constants = constants; + + return codegen; +}; + +var formatCache = {}; + +function formatter(type, method, specifier) { + var k = type + ':' + specifier, + e = formatCache[k]; + if (!e || e[0] !== method) { + formatCache[k] = (e = [method, method(specifier)]); + } + return e[1]; +} + +function format$1(_, specifier) { + return formatter('format', format, specifier)(_); +} + +function timeFormat$1(_, specifier) { + return formatter('timeFormat', timeFormat, specifier)(_); +} + +function utcFormat$1(_, specifier) { + return formatter('utcFormat', utcFormat, specifier)(_); +} + +function timeParse$1(_, specifier) { + return formatter('timeParse', timeParse, specifier)(_); +} + +function utcParse$1(_, specifier) { + return formatter('utcParse', utcParse, specifier)(_); +} + +var dateObj = new Date(2000, 0, 1); + +function time$2(month, day, specifier) { + dateObj.setMonth(month); + dateObj.setDate(day); + return timeFormat$1(dateObj, specifier); +} + +function monthFormat(month) { + return time$2(month, 1, '%B'); +} + +function monthAbbrevFormat(month) { + return time$2(month, 1, '%b'); +} + +function dayFormat(day) { + return time$2(0, 2 + day, '%A'); +} + +function dayAbbrevFormat(day) { + return time$2(0, 2 + day, '%a'); +} + +function quarter(date) { + return 1 + ~~(new Date(date).getMonth() / 3); +} + +function utcquarter(date) { + return 1 + ~~(new Date(date).getUTCMonth() / 3); +} + +function log$4(df, method, args) { + try { + df[method].apply(df, ['EXPRESSION'].concat([].slice.call(args))); + } catch (err) { + df.warn(err); + } + return args[args.length-1]; +} + +function warn() { + return log$4(this.context.dataflow, 'warn', arguments); +} + +function info() { + return log$4(this.context.dataflow, 'info', arguments); +} + +function debug() { + return log$4(this.context.dataflow, 'debug', arguments); +} + +var inScope = function(item) { + var group = this.context.group, + value = false; + + if (group) while (item) { + if (item === group) { value = true; break; } + item = item.mark.group; + } + return value; +}; + +/** + * Span-preserving range clamp. If the span of the input range is less + * than (max - min) and an endpoint exceeds either the min or max value, + * the range is translated such that the span is preserved and one + * endpoint touches the boundary of the min/max range. + * If the span exceeds (max - min), the range [min, max] is returned. + */ +var clampRange = function(range, min, max) { + var lo = range[0], + hi = range[1], + span; + + if (hi < lo) { + span = hi; + hi = lo; + lo = span; + } + span = hi - lo; + + return span >= (max - min) + ? [min, max] + : [ + Math.min(Math.max(lo, min), max - span), + Math.min(Math.max(hi, span), max) + ]; +}; + +function pinchDistance(event) { + var t = event.touches, + dx = t[0].clientX - t[1].clientX, + dy = t[0].clientY - t[1].clientY; + return Math.sqrt(dx * dx + dy * dy); +} + +function pinchAngle(event) { + var t = event.touches; + return Math.atan2( + t[0].clientY - t[1].clientY, + t[0].clientX - t[1].clientX + ); +} + +var _window = (typeof window !== 'undefined' && window) || null; + +function screen() { + return _window ? _window.screen : {}; +} + +function windowSize() { + return _window + ? [_window.innerWidth, _window.innerHeight] + : [undefined, undefined]; +} + +function containerSize() { + var view = this.context.dataflow, + el = view.container && view.container(); + return el + ? [el.clientWidth, el.clientHeight] + : [undefined, undefined]; +} + +var flush = function(range, value, threshold, left, right, center) { + var l = Math.abs(value - range[0]), + r = Math.abs(peek(range) - value); + return l < r && l <= threshold ? left + : r <= threshold ? right + : center; +}; + +var span = function(array) { + return (array[array.length-1] - array[0]) || 0; +}; + +var Literal = 'Literal'; +var Identifier$1 = 'Identifier'; + +var indexPrefix = '@'; +var scalePrefix = '%'; +var dataPrefix = ':'; + +function getScale(name, ctx) { + var s; + return isFunction(name) ? name + : isString(name) ? (s = ctx.scales[name]) && s.value + : undefined; +} + +function addScaleDependency(scope, params, name) { + var scaleName = scalePrefix + name; + if (!params.hasOwnProperty(scaleName)) { + try { + params[scaleName] = scope.scaleRef(name); + } catch (err) { + // TODO: error handling? warning? + } + } +} + +function scaleVisitor(name, args, scope, params) { + if (args[0].type === Literal) { + // add scale dependency + addScaleDependency(scope, params, args[0].value); + } + else if (args[0].type === Identifier$1) { + // indirect scale lookup; add all scales as parameters + for (name in scope.scales) { + addScaleDependency(scope, params, name); + } + } +} + +function range$2(name, group) { + var s = getScale(name, (group || this).context); + return s && s.range ? s.range() : []; +} + +function domain(name, group) { + var s = getScale(name, (group || this).context); + return s ? s.domain() : []; +} + +function bandwidth(name, group) { + var s = getScale(name, (group || this).context); + return s && s.bandwidth ? s.bandwidth() : 0; +} + +function bandspace(count, paddingInner, paddingOuter) { + return bandSpace(count || 0, paddingInner || 0, paddingOuter || 0); +} + +function copy$1(name, group) { + var s = getScale(name, (group || this).context); + return s ? s.copy() : undefined; +} + +function scale$2(name, value, group) { + var s = getScale(name, (group || this).context); + return s ? s(value) : undefined; +} + +function invert(name, range, group) { + var s = getScale(name, (group || this).context); + return !s ? undefined + : isArray(range) ? (s.invertRange || s.invert)(range) + : (s.invert || s.invertExtent)(range); +} + +var scaleGradient = function(scale, p0, p1, count, group) { + scale = getScale(scale, (group || this).context); + + var gradient = Gradient(p0, p1), + stops = scale.domain(), + min = stops[0], + max = stops[stops.length-1], + fraction = scaleFraction(scale, min, max); + + if (scale.ticks) { + stops = scale.ticks(+count || 15); + if (min !== stops[0]) stops.unshift(min); + if (max !== stops[stops.length-1]) stops.push(max); + } + + for (var i=0, n=stops.length; i r1) { + t = r0; + r0 = r1; + r1 = t; + } + left = left === undefined || left; + right = right === undefined || right; + + return (left ? r0 <= value : r0 < value) && + (right ? value <= r1 : value < r1); +}; + +var encode$1 = function(item, name, retval) { + if (item) { + var df = this.context.dataflow, + target = item.mark.source; + df.pulse(target, df.changeset().encode(item, name)); + } + return retval !== undefined ? retval : item; +}; + +function equal(a, b) { + return a === b || a !== a && b !== b ? true + : isArray(a) && isArray(b) && a.length === b.length ? equalArray(a, b) + : false; +} + +function equalArray(a, b) { + for (var i=0, n=a.length; i, fields: array, values: array<*>, bins: object} +function vlPoint(name, datum, op) { + return vlSelection.call(this, name, datum, op, testPoint); +} + +// Assumes interval selection typles are of the form: +// {unit: string, intervals: array<{encoding: string, field:string, extent:array}>} +function vlInterval(name, datum, op) { + return vlSelection.call(this, name, datum, op, testInterval); +} + +function vlMultiVisitor(name, args, scope, params) { + if (args[0].type !== Literal) error$1('First argument to indata must be a string literal.'); + + var data = args[0].value, + // vlMulti, vlMultiDomain have different # of params, but op is always last. + op = args.length >= 2 && args[args.length-1].value, + field$$1 = 'unit', + indexName = indexPrefix + field$$1; + + if (op === INTERSECT && !params.hasOwnProperty(indexName)) { + params[indexName] = scope.getData(data).indataRef(scope, field$$1); + } + + dataVisitor(name, args, scope, params); +} + +/** + * Materializes a point selection as a scale domain. + * @param {string} name - The name of the dataset representing the selection. + * @param {string} [encoding] - A particular encoding channel to materialize. + * @param {string} [field] - A particular field to materialize. + * @param {string} [op='intersect'] - The set operation for combining selections. + * One of 'intersect' (default) or 'union'. + * @returns {array} An array of values to serve as a scale domain. + */ +function vlPointDomain(name, encoding, field$$1, op) { + var data = this.context.data[name], + entries = data ? data.values.value : [], + unitIdx = data ? data[UNIT_INDEX] && data[UNIT_INDEX].value : undefined, + entry = entries[0], + i = 0, n, index, values, continuous, units; + + if (!entry) return undefined; + + for (n = encoding ? entry.encodings.length : entry.fields.length; i 2; + break; + } + } + + values = entries.reduce(function(acc, entry) { + var extent = entry.intervals[index].extent, + value = discrete + ? extent.map(function (d) { return {unit: entry.unit, value: d}; }) + : {unit: entry.unit, value: extent}; + + if (discrete) { + acc.push.apply(acc, value); + } else { + acc.push(value); + } + return acc; + }, []); + + + return discrete ? discreteDomain(values, op) : continuousDomain(values, op); +} + +function discreteDomain(entries, op) { + var units = {}, count = 0, + values = {}, domain = [], + i = 0, n = entries.length, + entry, unit, v, key$$1; + + for (; i hi) { + hi = extent[0]; + lo = extent[1]; + } + domain = domain ? merge$$1(domain, lo, hi) : [lo, hi]; + } + + return domain && domain.length && (+domain[0] !== +domain[1]) + ? domain + : undefined; +} + +function unionInterval(domain, lo, hi) { + if (domain[0] > lo) domain[0] = lo; + if (domain[1] < hi) domain[1] = hi; + return domain; +} + +function intersectInterval(domain, lo, hi) { + if (hi < domain[0] || domain[1] < lo) { + return []; + } else { + if (domain[0] < lo) domain[0] = lo; + if (domain[1] > hi) domain[1] = hi; + } + return domain; +} + +// Expression function context object +var functionContext = { + random: function() { return exports.random(); }, // override default + isArray: isArray, + isBoolean: isBoolean, + isDate: isDate, + isNumber: isNumber, + isObject: isObject, + isRegExp: isRegExp, + isString: isString, + isTuple: isTuple, + toBoolean: toBoolean, + toDate: toDate, + toNumber: toNumber, + toString: toString, + pad: pad, + peek: peek, + truncate: truncate, + rgb: rgb, + lab: lab, + hcl: hcl, + hsl: hsl, + sequence: sequence, + format: format$1, + utcFormat: utcFormat$1, + utcParse: utcParse$1, + timeFormat: timeFormat$1, + timeParse: timeParse$1, + monthFormat: monthFormat, + monthAbbrevFormat: monthAbbrevFormat, + dayFormat: dayFormat, + dayAbbrevFormat: dayAbbrevFormat, + quarter: quarter, + utcquarter: utcquarter, + warn: warn, + info: info, + debug: debug, + inScope: inScope, + clampRange: clampRange, + pinchDistance: pinchDistance, + pinchAngle: pinchAngle, + screen: screen, + containerSize: containerSize, + windowSize: windowSize, + span: span, + flush: flush, + bandspace: bandspace, + inrange: inrange, + setdata: setdata, + pathShape: pathShape, + panLinear: panLinear, + panLog: panLog, + panPow: panPow, + zoomLinear: zoomLinear, + zoomLog: zoomLog, + zoomPow: zoomPow, + encode: encode$1, + modify: modify +}; + +var eventFunctions = ['view', 'item', 'group', 'xy', 'x', 'y']; +var eventPrefix = 'event.vega.'; +var thisPrefix = 'this.'; +var astVisitors = {}; // AST visitors for dependency analysis + +function expressionFunction(name, fn, visitor) { + if (arguments.length === 1) { + return functionContext[name]; + } + + // register with the functionContext + functionContext[name] = fn; + + // if there is an astVisitor register that, too + if (visitor) astVisitors[name] = visitor; + + // if the code generator has already been initialized, + // we need to also register the function with it + if (codeGenerator) codeGenerator.functions[name] = thisPrefix + name; + return this; +} + +// register expression functions with ast visitors +expressionFunction('bandwidth', bandwidth, scaleVisitor); +expressionFunction('copy', copy$1, scaleVisitor); +expressionFunction('domain', domain, scaleVisitor); +expressionFunction('range', range$2, scaleVisitor); +expressionFunction('invert', invert, scaleVisitor); +expressionFunction('scale', scale$2, scaleVisitor); +expressionFunction('gradient', scaleGradient, scaleVisitor); +expressionFunction('geoArea', geoArea, scaleVisitor); +expressionFunction('geoBounds', geoBounds, scaleVisitor); +expressionFunction('geoCentroid', geoCentroid, scaleVisitor); +expressionFunction('geoShape', geoShape, scaleVisitor); +expressionFunction('indata', indata, indataVisitor); +expressionFunction('data', data$1, dataVisitor); +expressionFunction('vlSingle', vlPoint, dataVisitor); +expressionFunction('vlSingleDomain', vlPointDomain, dataVisitor); +expressionFunction('vlMulti', vlPoint, vlMultiVisitor); +expressionFunction('vlMultiDomain', vlPointDomain, vlMultiVisitor); +expressionFunction('vlInterval', vlInterval, dataVisitor); +expressionFunction('vlIntervalDomain', vlIntervalDomain, dataVisitor); +expressionFunction('treePath', treePath, dataVisitor); +expressionFunction('treeAncestors', treeAncestors, dataVisitor); + +// Build expression function registry +function buildFunctions(codegen$$1) { + var fn = Functions(codegen$$1); + eventFunctions.forEach(function(name) { fn[name] = eventPrefix + name; }); + for (var name in functionContext) { fn[name] = thisPrefix + name; } + return fn; +} + +// Export code generator and parameters +var codegenParams = { + blacklist: ['_'], + whitelist: ['datum', 'event', 'item'], + fieldvar: 'datum', + globalvar: function(id$$1) { return '_[' + $('$' + id$$1) + ']'; }, + functions: buildFunctions, + constants: Constants, + visitors: astVisitors +}; + +var codeGenerator = codegen(codegenParams); + +var signalPrefix = '$'; + +var parseExpression = function(expr, scope, preamble) { + var params = {}, ast, gen; + + // parse the expression to an abstract syntax tree (ast) + try { + ast = parse$3(expr); + } catch (err) { + error$1('Expression parse error: ' + $(expr)); + } + + // analyze ast function calls for dependencies + ast.visit(function visitor(node) { + if (node.type !== 'CallExpression') return; + var name = node.callee.name, + visit = codegenParams.visitors[name]; + if (visit) visit(name, node.arguments, scope, params); + }); + + // perform code generation + gen = codeGenerator(ast); + + // collect signal dependencies + gen.globals.forEach(function(name) { + var signalName = signalPrefix + name; + if (!params.hasOwnProperty(signalName) && scope.getSignal(name)) { + params[signalName] = scope.signalRef(name); + } + }); + + // return generated expression code and dependencies + return { + $expr: preamble ? preamble + 'return(' + gen.code + ');' : gen.code, + $fields: gen.fields, + $params: params + }; +}; + +var VIEW$1 = 'view'; +var SCOPE = 'scope'; + +var parseStream = function(stream, scope) { + return stream.signal ? scope.getSignal(stream.signal).id + : stream.scale ? scope.getScale(stream.scale).id + : parseStream$1(stream, scope); +}; + +function eventSource(source) { + return source === SCOPE ? VIEW$1 : (source || VIEW$1); +} + +function parseStream$1(stream, scope) { + var method = stream.merge ? mergeStream + : stream.stream ? nestedStream + : stream.type ? eventStream + : error$1('Invalid stream specification: ' + $(stream)); + + return method(stream, scope); +} + +function mergeStream(stream, scope) { + var list = stream.merge.map(function(s) { + return parseStream$1(s, scope); + }); + + var entry = streamParameters({merge: list}, stream, scope); + return scope.addStream(entry).id; +} + +function nestedStream(stream, scope) { + var id$$1 = parseStream$1(stream.stream, scope), + entry = streamParameters({stream: id$$1}, stream, scope); + return scope.addStream(entry).id; +} + +function eventStream(stream, scope) { + var id$$1 = scope.event(eventSource(stream.source), stream.type), + entry = streamParameters({stream: id$$1}, stream, scope); + return Object.keys(entry).length === 1 ? id$$1 + : scope.addStream(entry).id; +} + +function streamParameters(entry, stream, scope) { + var param = stream.between; + + if (param) { + if (param.length !== 2) { + error$1('Stream "between" parameter must have 2 entries: ' + $(stream)); + } + entry.between = [ + parseStream$1(param[0], scope), + parseStream$1(param[1], scope) + ]; + } + + param = stream.filter ? array(stream.filter) : []; + if (stream.marktype || stream.markname || stream.markrole) { + // add filter for mark type, name and/or role + param.push(filterMark(stream.marktype, stream.markname, stream.markrole)); + } + if (stream.source === SCOPE) { + // add filter to limit events from sub-scope only + param.push('inScope(event.item)'); + } + if (param.length) { + entry.filter = parseExpression('(' + param.join(')&&(') + ')').$expr; + } + + if ((param = stream.throttle) != null) { + entry.throttle = +param; + } + + if ((param = stream.debounce) != null) { + entry.debounce = +param; + } + + if (stream.consume) { + entry.consume = true; + } + + return entry; +} + +function filterMark(type, name, role) { + var item = 'event.item'; + return item + + (type && type !== '*' ? '&&' + item + '.mark.marktype===\'' + type + '\'' : '') + + (role ? '&&' + item + '.mark.role===\'' + role + '\'' : '') + + (name ? '&&' + item + '.mark.name===\'' + name + '\'' : ''); +} + +/** + * Parse an event selector string. + * Returns an array of event stream definitions. + */ +var selector = function(selector, source, marks) { + DEFAULT_SOURCE = source || VIEW$2; + MARKS = marks || DEFAULT_MARKS; + return parseMerge(selector.trim()).map(parseSelector); +}; + +var VIEW$2 = 'view'; +var LBRACK = '['; +var RBRACK = ']'; +var LBRACE = '{'; +var RBRACE = '}'; +var COLON = ':'; +var COMMA = ','; +var NAME = '@'; +var GT = '>'; +var ILLEGAL$1 = /[[\]{}]/; +var DEFAULT_SOURCE; +var MARKS; +var DEFAULT_MARKS = { + '*': 1, + arc: 1, + area: 1, + group: 1, + image: 1, + line: 1, + path: 1, + rect: 1, + rule: 1, + shape: 1, + symbol: 1, + text: 1, + trail: 1 + }; + +function isMarkType(type) { + return MARKS.hasOwnProperty(type); +} + +function find$1(s, i, endChar, pushChar, popChar) { + var count = 0, + n = s.length, + c; + for (; i= 0) --count; + else if (pushChar && pushChar.indexOf(c) >= 0) ++count; + } + return i; +} + +function parseMerge(s) { + var output = [], + start = 0, + n = s.length, + i = 0; + + while (i < n) { + i = find$1(s, i, COMMA, LBRACK + LBRACE, RBRACK + RBRACE); + output.push(s.substring(start, i).trim()); + start = ++i; + } + + if (output.length === 0) { + throw 'Empty event selector: ' + s; + } + return output; +} + +function parseSelector(s) { + return s[0] === '[' + ? parseBetween(s) + : parseStream$2(s); +} + +function parseBetween(s) { + var n = s.length, + i = 1, + b, stream; + + i = find$1(s, i, RBRACK, LBRACK, RBRACK); + if (i === n) { + throw 'Empty between selector: ' + s; + } + + b = parseMerge(s.substring(1, i)); + if (b.length !== 2) { + throw 'Between selector must have two elements: ' + s; + } + + s = s.slice(i + 1).trim(); + if (s[0] !== GT) { + throw 'Expected \'>\' after between selector: ' + s; + } + + b = b.map(parseSelector); + + stream = parseSelector(s.slice(1).trim()); + if (stream.between) { + return { + between: b, + stream: stream + }; + } else { + stream.between = b; + } + + return stream; +} + +function parseStream$2(s) { + var stream = {source: DEFAULT_SOURCE}, + source = [], + throttle = [0, 0], + markname = 0, + start = 0, + n = s.length, + i = 0, j, + filter; + + // extract throttle from end + if (s[n-1] === RBRACE) { + i = s.lastIndexOf(LBRACE); + if (i >= 0) { + try { + throttle = parseThrottle(s.substring(i+1, n-1)); + } catch (e) { + throw 'Invalid throttle specification: ' + s; + } + s = s.slice(0, i).trim(); + n = s.length; + } else throw 'Unmatched right brace: ' + s; + i = 0; + } + + if (!n) throw s; + + // set name flag based on first char + if (s[0] === NAME) markname = ++i; + + // extract first part of multi-part stream selector + j = find$1(s, i, COLON); + if (j < n) { + source.push(s.substring(start, j).trim()); + start = i = ++j; + } + + // extract remaining part of stream selector + i = find$1(s, i, LBRACK); + if (i === n) { + source.push(s.substring(start, n).trim()); + } else { + source.push(s.substring(start, i).trim()); + filter = []; + start = ++i; + if (start === n) throw 'Unmatched left bracket: ' + s; + } + + // extract filters + while (i < n) { + i = find$1(s, i, RBRACK); + if (i === n) throw 'Unmatched left bracket: ' + s; + filter.push(s.substring(start, i).trim()); + if (i < n-1 && s[++i] !== LBRACK) throw 'Expected left bracket: ' + s; + start = ++i; + } + + // marshall event stream specification + if (!(n = source.length) || ILLEGAL$1.test(source[n-1])) { + throw 'Invalid event selector: ' + s; + } + + if (n > 1) { + stream.type = source[1]; + if (markname) { + stream.markname = source[0].slice(1); + } else if (isMarkType(source[0])) { + stream.marktype = source[0]; + } else { + stream.source = source[0]; + } + } else { + stream.type = source[0]; + } + if (stream.type.slice(-1) === '!') { + stream.consume = true; + stream.type = stream.type.slice(0, -1); + } + if (filter != null) stream.filter = filter; + if (throttle[0]) stream.throttle = throttle[0]; + if (throttle[1]) stream.debounce = throttle[1]; + + return stream; +} + +function parseThrottle(s) { + var a = s.split(COMMA); + if (!s.length || a.length > 2) throw s; + return a.map(function(_) { + var x = +_; + if (x !== x) throw s; + return x; + }); +} + +var preamble = 'var datum=event.item&&event.item.datum;'; + +var parseUpdate = function(spec, scope, target) { + var events = spec.events, + update = spec.update, + encode = spec.encode, + sources = [], + value = '', entry; + + if (!events) { + error$1('Signal update missing events specification.'); + } + + // interpret as an event selector string + if (isString(events)) { + events = selector(events); + } + + // separate event streams from signal updates + events = array(events).filter(function(stream) { + if (stream.signal || stream.scale) { + sources.push(stream); + return 0; + } else { + return 1; + } + }); + + // merge event streams, include as source + if (events.length) { + sources.push(events.length > 1 ? {merge: events} : events[0]); + } + + if (encode != null) { + if (update) error$1('Signal encode and update are mutually exclusive.'); + update = 'encode(item(),' + $(encode) + ')'; + } + + // resolve update value + value = isString(update) ? parseExpression(update, scope, preamble) + : update.expr != null ? parseExpression(update.expr, scope, preamble) + : update.value != null ? update.value + : update.signal != null ? { + $expr: '_.value', + $params: {value: scope.signalRef(update.signal)} + } + : error$1('Invalid signal update specification.'); + + entry = { + target: target, + update: value + }; + + if (spec.force) { + entry.options = {force: true}; + } + + sources.forEach(function(source) { + source = {source: parseStream(source, scope)}; + scope.addUpdate(extend(source, entry)); + }); +}; + +var parseSignalUpdates = function(signal, scope) { + var op = scope.getSignal(signal.name); + + if (signal.update) { + var expr = parseExpression(signal.update, scope); + op.update = expr.$expr; + op.params = expr.$params; + } + + if (signal.on) { + signal.on.forEach(function(_) { + parseUpdate(_, scope, op.id); + }); + } +}; + +function Entry(type, value, params, parent) { + this.id = -1; + this.type = type; + this.value = value; + this.params = params; + if (parent) this.parent = parent; +} + +function entry(type, value, params, parent) { + return new Entry(type, value, params, parent); +} + +function operator(value, params) { + return entry('operator', value, params); +} + +// ----- + +function ref(op) { + var ref = {$ref: op.id}; + // if operator not yet registered, cache ref to resolve later + if (op.id < 0) (op.refs = op.refs || []).push(ref); + return ref; +} + +var tupleidRef = { + $tupleid: 1, + toString: function() { return ':_tupleid_:'; } +}; + +function fieldRef$1(field$$1, name) { + return name ? {$field: field$$1, $name: name} : {$field: field$$1}; +} + +var keyFieldRef = fieldRef$1('key'); + +function compareRef(fields, orders) { + return {$compare: fields, $order: orders}; +} + +function keyRef(fields, flat) { + var ref = {$key: fields}; + if (flat) ref.$flat = true; + return ref; +} + +// ----- + +var Ascending = 'ascending'; + +var Descending = 'descending'; + +function sortKey(sort) { + return !isObject(sort) ? '' + : (sort.order === Descending ? '-' : '+') + + aggrField(sort.op, sort.field); +} + +function aggrField(op, field$$1) { + return (op && op.signal ? '$' + op.signal : op || '') + + (op && field$$1 ? '_' : '') + + (field$$1 && field$$1.signal ? '$' + field$$1.signal : field$$1 || ''); +} + +// ----- + +function isSignal(_) { + return _ && _.signal; +} + +function value(specValue, defaultValue) { + return specValue != null ? specValue : defaultValue; +} + +function transform$3(name) { + return function(params, value$$1, parent) { + return entry(name, value$$1, params || undefined, parent); + }; +} + +var Aggregate$1 = transform$3('aggregate'); +var AxisTicks$1 = transform$3('axisticks'); +var Bound$1 = transform$3('bound'); +var Collect$1 = transform$3('collect'); +var Compare$1 = transform$3('compare'); +var DataJoin$1 = transform$3('datajoin'); +var Encode$1 = transform$3('encode'); + +var Facet$1 = transform$3('facet'); +var Field$1 = transform$3('field'); +var Key$1 = transform$3('key'); +var LegendEntries$1 = transform$3('legendentries'); +var Mark$1 = transform$3('mark'); +var MultiExtent$1 = transform$3('multiextent'); +var MultiValues$1 = transform$3('multivalues'); +var Overlap$1 = transform$3('overlap'); +var Params$2 = transform$3('params'); +var PreFacet$1 = transform$3('prefacet'); +var Projection$1 = transform$3('projection'); +var Proxy$1 = transform$3('proxy'); +var Relay$1 = transform$3('relay'); +var Render$1 = transform$3('render'); +var Scale$1 = transform$3('scale'); +var Sieve$1 = transform$3('sieve'); +var SortItems$1 = transform$3('sortitems'); +var ViewLayout$1 = transform$3('viewlayout'); +var Values$1 = transform$3('values'); + +var FIELD_REF_ID = 0; + +var types = [ + 'identity', + 'ordinal', 'band', 'point', + 'bin-linear', 'bin-ordinal', + 'linear', 'pow', 'sqrt', 'log', 'sequential', + 'time', 'utc', + 'quantize', 'quantile', 'threshold' +]; + +var allTypes = toSet(types); +var ordinalTypes = toSet(types.slice(1, 6)); + +function isOrdinal(type) { + return ordinalTypes.hasOwnProperty(type); +} + +function isQuantile(type) { + return type === 'quantile'; +} + +function initScale(spec, scope) { + var type = spec.type || 'linear'; + + if (!allTypes.hasOwnProperty(type)) { + error$1('Unrecognized scale type: ' + $(type)); + } + + scope.addScale(spec.name, { + type: type, + domain: undefined + }); +} + +function parseScale(spec, scope) { + var params = scope.getScale(spec.name).params, + key$$1; + + params.domain = parseScaleDomain(spec.domain, spec, scope); + + if (spec.range != null) { + params.range = parseScaleRange(spec, scope, params); + } + + if (spec.interpolate != null) { + parseScaleInterpolate(spec.interpolate, params); + } + + if (spec.nice != null) { + parseScaleNice(spec.nice, params); + } + + for (key$$1 in spec) { + if (params.hasOwnProperty(key$$1) || key$$1 === 'name') continue; + params[key$$1] = parseLiteral(spec[key$$1], scope); + } +} + +function parseLiteral(v, scope) { + return !isObject(v) ? v + : v.signal ? scope.signalRef(v.signal) + : error$1('Unsupported object: ' + $(v)); +} + +function parseArray(v, scope) { + return v.signal + ? scope.signalRef(v.signal) + : v.map(function(v) { return parseLiteral(v, scope); }); +} + +function dataLookupError(name) { + error$1('Can not find data set: ' + $(name)); +} + +// -- SCALE DOMAIN ---- + +function parseScaleDomain(domain, spec, scope) { + if (!domain) { + if (spec.domainMin != null || spec.domainMax != null) { + error$1('No scale domain defined for domainMin/domainMax to override.'); + } + return; // default domain + } + + return domain.signal ? scope.signalRef(domain.signal) + : (isArray(domain) ? explicitDomain + : domain.fields ? multipleDomain + : singularDomain)(domain, spec, scope); +} + +function explicitDomain(domain, spec, scope) { + return domain.map(function(v) { + return parseLiteral(v, scope); + }); +} + +function singularDomain(domain, spec, scope) { + var data = scope.getData(domain.data); + if (!data) dataLookupError(domain.data); + + return isOrdinal(spec.type) + ? data.valuesRef(scope, domain.field, parseSort(domain.sort, false)) + : isQuantile(spec.type) ? data.domainRef(scope, domain.field) + : data.extentRef(scope, domain.field); +} + +function multipleDomain(domain, spec, scope) { + var data = domain.data, + fields = domain.fields.reduce(function(dom, d) { + d = isString(d) ? {data: data, field: d} + : (isArray(d) || d.signal) ? fieldRef(d, scope) + : d; + dom.push(d); + return dom; + }, []); + + return (isOrdinal(spec.type) ? ordinalMultipleDomain + : isQuantile(spec.type) ? quantileMultipleDomain + : numericMultipleDomain)(domain, scope, fields); +} + +function fieldRef(data, scope) { + var name = '_:vega:_' + (FIELD_REF_ID++), + coll = Collect$1({}); + + if (isArray(data)) { + coll.value = {$ingest: data}; + } else if (data.signal) { + var code = 'setdata(' + $(name) + ',' + data.signal + ')'; + coll.params.input = scope.signalRef(code); + } + scope.addDataPipeline(name, [coll, Sieve$1({})]); + return {data: name, field: 'data'}; +} + +function ordinalMultipleDomain(domain, scope, fields) { + var counts, a, c, v; + + // get value counts for each domain field + counts = fields.map(function(f) { + var data = scope.getData(f.data); + if (!data) dataLookupError(f.data); + return data.countsRef(scope, f.field); + }); + + // sum counts from all fields + a = scope.add(Aggregate$1({ + groupby: keyFieldRef, + ops:['sum'], fields: [scope.fieldRef('count')], as:['count'], + pulse: counts + })); + + // collect aggregate output + c = scope.add(Collect$1({pulse: ref(a)})); + + // extract values for combined domain + v = scope.add(Values$1({ + field: keyFieldRef, + sort: scope.sortRef(parseSort(domain.sort, true)), + pulse: ref(c) + })); + + return ref(v); +} + +function parseSort(sort, multidomain) { + if (sort) { + if (!sort.field && !sort.op) { + if (isObject(sort)) sort.field = 'key'; + else sort = {field: 'key'}; + } else if (!sort.field && sort.op !== 'count') { + error$1('No field provided for sort aggregate op: ' + sort.op); + } else if (multidomain && sort.field) { + error$1('Multiple domain scales can not sort by field.'); + } else if (multidomain && sort.op && sort.op !== 'count') { + error$1('Multiple domain scales support op count only.'); + } + } + return sort; +} + +function quantileMultipleDomain(domain, scope, fields) { + // get value arrays for each domain field + var values = fields.map(function(f) { + var data = scope.getData(f.data); + if (!data) dataLookupError(f.data); + return data.domainRef(scope, f.field); + }); + + // combine value arrays + return ref(scope.add(MultiValues$1({values: values}))); +} + +function numericMultipleDomain(domain, scope, fields) { + // get extents for each domain field + var extents = fields.map(function(f) { + var data = scope.getData(f.data); + if (!data) dataLookupError(f.data); + return data.extentRef(scope, f.field); + }); + + // combine extents + return ref(scope.add(MultiExtent$1({extents: extents}))); +} + +// -- SCALE NICE ----- + +function parseScaleNice(nice, params) { + params.nice = isObject(nice) + ? { + interval: parseLiteral(nice.interval), + step: parseLiteral(nice.step) + } + : parseLiteral(nice); +} + +// -- SCALE INTERPOLATION ----- + +function parseScaleInterpolate(interpolate, params) { + params.interpolate = parseLiteral(interpolate.type || interpolate); + if (interpolate.gamma != null) { + params.interpolateGamma = parseLiteral(interpolate.gamma); + } +} + +// -- SCALE RANGE ----- + +function parseScaleRange(spec, scope, params) { + var range = spec.range, + config = scope.config.range; + + if (range.signal) { + return scope.signalRef(range.signal); + } else if (isString(range)) { + if (config && config.hasOwnProperty(range)) { + spec = extend({}, spec, {range: config[range]}); + return parseScaleRange(spec, scope, params); + } else if (range === 'width') { + range = [0, {signal: 'width'}]; + } else if (range === 'height') { + range = isOrdinal(spec.type) + ? [0, {signal: 'height'}] + : [{signal: 'height'}, 0]; + } else { + error$1('Unrecognized scale range value: ' + $(range)); + } + } else if (range.scheme) { + params.scheme = parseLiteral(range.scheme, scope); + if (range.extent) params.schemeExtent = parseArray(range.extent, scope); + if (range.count) params.schemeCount = parseLiteral(range.count, scope); + return; + } else if (range.step) { + params.rangeStep = parseLiteral(range.step, scope); + return; + } else if (isOrdinal(spec.type) && !isArray(range)) { + return parseScaleDomain(range, spec, scope); + } else if (!isArray(range)) { + error$1('Unsupported range type: ' + $(range)); + } + + return range.map(function(v) { + return parseLiteral(v, scope); + }); +} + +var parseProjection = function(proj, scope) { + var params = {}; + + for (var name in proj) { + if (name === 'name') continue; + params[name] = parseParameter(proj[name], scope); + } + + scope.addProjection(proj.name, params); +}; + +function parseParameter(_, scope) { + return isArray(_) ? _.map(function(_) { return parseParameter(_, scope); }) + : !isObject(_) ? _ + : _.signal ? scope.signalRef(_.signal) + : error$1('Unsupported parameter object: ' + $(_)); +} + +var Top$1 = 'top'; +var Left$1 = 'left'; +var Right$1 = 'right'; +var Bottom$1 = 'bottom'; + +var Index = 'index'; +var Label = 'label'; +var Offset = 'offset'; +var Perc = 'perc'; +var Size = 'size'; +var Total = 'total'; +var Value = 'value'; + +var GuideLabelStyle = 'guide-label'; +var GuideTitleStyle = 'guide-title'; +var GroupTitleStyle = 'group-title'; + +var LegendScales = [ + 'shape', + 'size', + 'fill', + 'stroke', + 'strokeDash', + 'opacity' +]; + +var Skip = { + name: 1, + interactive: 1 +}; + +var Skip$1 = toSet(['rule']); +var Swap = toSet(['group', 'image', 'rect']); + +var adjustSpatial = function(encode, marktype) { + var code = ''; + + if (Skip$1[marktype]) return code; + + if (encode.x2) { + if (encode.x) { + if (Swap[marktype]) { + code += 'if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;'; + } + code += 'o.width=o.x2-o.x;'; + } else { + code += 'o.x=o.x2-(o.width||0);'; + } + } + + if (encode.xc) { + code += 'o.x=o.xc-(o.width||0)/2;'; + } + + if (encode.y2) { + if (encode.y) { + if (Swap[marktype]) { + code += 'if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;'; + } + code += 'o.height=o.y2-o.y;'; + } else { + code += 'o.y=o.y2-(o.height||0);'; + } + } + + if (encode.yc) { + code += 'o.y=o.yc-(o.height||0)/2;'; + } + + return code; +}; + +var color$2 = function(enc, scope, params, fields) { + function color(type, x, y, z) { + var a = entry$1(null, x, scope, params, fields), + b = entry$1(null, y, scope, params, fields), + c = entry$1(null, z, scope, params, fields); + return 'this.' + type + '(' + [a, b, c].join(',') + ').toString()'; + } + + return (enc.c) ? color('hcl', enc.h, enc.c, enc.l) + : (enc.h || enc.s) ? color('hsl', enc.h, enc.s, enc.l) + : (enc.l || enc.a) ? color('lab', enc.l, enc.a, enc.b) + : (enc.r || enc.g || enc.b) ? color('rgb', enc.r, enc.g, enc.b) + : null; +}; + +var expression = function(code, scope, params, fields) { + var expr = parseExpression(code, scope); + expr.$fields.forEach(function(name) { fields[name] = 1; }); + extend(params, expr.$params); + return expr.$expr; +}; + +var field$1 = function(ref, scope, params, fields) { + return resolve$1(isObject(ref) ? ref : {datum: ref}, scope, params, fields); +}; + +function resolve$1(ref, scope, params, fields) { + var object, level, field$$1; + + if (ref.signal) { + object = 'datum'; + field$$1 = expression(ref.signal, scope, params, fields); + } else if (ref.group || ref.parent) { + level = Math.max(1, ref.level || 1); + object = 'item'; + + while (level-- > 0) { + object += '.mark.group'; + } + + if (ref.parent) { + field$$1 = ref.parent; + object += '.datum'; + } else { + field$$1 = ref.group; + } + } else if (ref.datum) { + object = 'datum'; + field$$1 = ref.datum; + } else { + error$1('Invalid field reference: ' + $(ref)); + } + + if (!ref.signal) { + if (isString(field$$1)) { + fields[field$$1] = 1; // TODO review field tracking? + field$$1 = splitAccessPath(field$$1).map($).join(']['); + } else { + field$$1 = resolve$1(field$$1, scope, params, fields); + } + } + + return object + '[' + field$$1 + ']'; +} + +var scale$3 = function(enc, value, scope, params, fields) { + var scale = getScale$1(enc.scale, scope, params, fields), + interp, func, flag; + + if (enc.range != null) { + // pull value from scale range + interp = +enc.range; + func = scale + '.range()'; + value = (interp === 0) ? (func + '[0]') + : '($=' + func + ',' + ((interp === 1) ? '$[$.length-1]' + : '$[0]+' + interp + '*($[$.length-1]-$[0])') + ')'; + } else { + // run value through scale and/or pull scale bandwidth + if (value !== undefined) value = scale + '(' + value + ')'; + + if (enc.band && (flag = hasBandwidth(enc.scale, scope))) { + func = scale + '.bandwidth'; + interp = +enc.band; + interp = func + '()' + (interp===1 ? '' : '*' + interp); + + // if we don't know the scale type, check for bandwidth + if (flag < 0) interp = '(' + func + '?' + interp + ':0)'; + + value = (value ? value + '+' : '') + interp; + + if (enc.extra) { + // include logic to handle extraneous elements + value = '(datum.extra?' + scale + '(datum.extra.value):' + value + ')'; + } + } + + if (value == null) value = '0'; + } + + return value; +}; + +function hasBandwidth(name, scope) { + if (!isString(name)) return -1; + var type = scope.scaleType(name); + return type === 'band' || type === 'point' ? 1 : 0; +} + +function getScale$1(name, scope, params, fields) { + var scaleName; + + if (isString(name)) { + // direct scale lookup; add scale as parameter + scaleName = scalePrefix + name; + if (!params.hasOwnProperty(scaleName)) { + params[scaleName] = scope.scaleRef(name); + } + scaleName = $(scaleName); + } else { + // indirect scale lookup; add all scales as parameters + for (scaleName in scope.scales) { + params[scalePrefix + scaleName] = scope.scaleRef(scaleName); + } + scaleName = $(scalePrefix) + '+' + + (name.signal + ? '(' + expression(name.signal, scope, params, fields) + ')' + : field$1(name, scope, params, fields)); + } + + return '_[' + scaleName + ']'; +} + +var gradient$1 = function(enc, scope, params, fields) { + return 'this.gradient(' + + getScale$1(enc.gradient, scope, params, fields) + + ',' + $(enc.start) + + ',' + $(enc.stop) + + ',' + $(enc.count) + + ')'; +}; + +var property = function(property, scope, params, fields) { + return isObject(property) + ? '(' + entry$1(null, property, scope, params, fields) + ')' + : property; +}; + +var entry$1 = function(channel, enc, scope, params, fields) { + if (enc.gradient != null) { + return gradient$1(enc, scope, params, fields); + } + + var value = enc.signal ? expression(enc.signal, scope, params, fields) + : enc.color ? color$2(enc.color, scope, params, fields) + : enc.field != null ? field$1(enc.field, scope, params, fields) + : enc.value !== undefined ? $(enc.value) + : undefined; + + if (enc.scale != null) { + value = scale$3(enc, value, scope, params, fields); + } + + if (value === undefined) { + value = null; + } + + if (enc.exponent != null) { + value = 'Math.pow(' + value + ',' + + property(enc.exponent, scope, params, fields) + ')'; + } + + if (enc.mult != null) { + value += '*' + property(enc.mult, scope, params, fields); + } + + if (enc.offset != null) { + value += '+' + property(enc.offset, scope, params, fields); + } + + if (enc.round) { + value = 'Math.round(' + value + ')'; + } + + return value; +}; + +var set$5 = function(obj, key$$1, value) { + return obj + '[' + $(key$$1) + ']=' + value + ';'; +}; + +var rule$1 = function(channel, rules, scope, params, fields) { + var code = ''; + + rules.forEach(function(rule) { + var value = entry$1(channel, rule, scope, params, fields); + code += rule.test + ? expression(rule.test, scope, params, fields) + '?' + value + ':' + : value; + }); + + return set$5('o', channel, code); +}; + +function parseEncode(encode, marktype, params, scope) { + var fields = {}, + code = 'var o=item,datum=o.datum,$;', + channel, enc, value; + + for (channel in encode) { + enc = encode[channel]; + if (isArray(enc)) { // rule + code += rule$1(channel, enc, scope, params, fields); + } else { + value = entry$1(channel, enc, scope, params, fields); + code += set$5('o', channel, value); + } + } + + code += adjustSpatial(encode, marktype); + code += 'return 1;'; + + return { + $expr: code, + $fields: Object.keys(fields), + $output: Object.keys(encode) + }; +} + +var MarkRole = 'mark'; +var FrameRole$1 = 'frame'; +var ScopeRole$1 = 'scope'; + +var AxisRole$2 = 'axis'; +var AxisDomainRole = 'axis-domain'; +var AxisGridRole = 'axis-grid'; +var AxisLabelRole = 'axis-label'; +var AxisTickRole = 'axis-tick'; +var AxisTitleRole = 'axis-title'; + +var LegendRole$2 = 'legend'; +var LegendEntryRole = 'legend-entry'; +var LegendGradientRole = 'legend-gradient'; +var LegendLabelRole = 'legend-label'; +var LegendSymbolRole = 'legend-symbol'; +var LegendTitleRole = 'legend-title'; + +var TitleRole$1 = 'title'; + +function encoder(_) { + return isObject(_) ? _ : {value: _}; +} + +function addEncode(object, name, value) { + if (value != null) { + object[name] = isObject(value) && !isArray(value) ? value : {value: value}; + return 1; + } else { + return 0; + } +} + +function extendEncode(encode, extra, skip) { + for (var name in extra) { + if (skip && skip.hasOwnProperty(name)) continue; + encode[name] = extend(encode[name] || {}, extra[name]); + } + return encode; +} + +function encoders(encode, type, role, style, scope, params) { + var enc, key$$1; + params = params || {}; + params.encoders = {$encode: (enc = {})}; + + encode = applyDefaults(encode, type, role, style, scope.config); + + for (key$$1 in encode) { + enc[key$$1] = parseEncode(encode[key$$1], type, params, scope); + } + + return params; +} + +function applyDefaults(encode, type, role, style, config) { + var enter = {}, key$$1, skip, props; + + // ignore legend and axis + if (role == 'legend' || String(role).indexOf('axis') === 0) { + role = null; + } + + // resolve mark config + props = role === FrameRole$1 ? config.group + : (role === MarkRole) ? extend({}, config.mark, config[type]) + : null; + + for (key$$1 in props) { + // do not apply defaults if relevant fields are defined + skip = has(key$$1, encode) + || (key$$1 === 'fill' || key$$1 === 'stroke') + && (has('fill', encode) || has('stroke', encode)); + + if (!skip) enter[key$$1] = {value: props[key$$1]}; + } + + // resolve styles, apply with increasing precedence + array(style).forEach(function(name) { + var props = config.style && config.style[name]; + for (var key$$1 in props) { + if (!has(key$$1, encode)) { + enter[key$$1] = {value: props[key$$1]}; + } + } + }); + + encode = extend({}, encode); // defensive copy + encode.enter = extend(enter, encode.enter); + + return encode; +} + +function has(key$$1, encode) { + return encode && ( + (encode.enter && encode.enter[key$$1]) || + (encode.update && encode.update[key$$1]) + ); +} + +var guideMark = function(type, role, style, key, dataRef, encode, extras) { + return { + type: type, + name: extras ? extras.name : undefined, + role: role, + style: (extras && extras.style) || style, + key: key, + from: dataRef, + interactive: !!(extras && extras.interactive), + encode: extendEncode(encode, extras, Skip) + }; +}; + +var GroupMark = 'group'; +var RectMark = 'rect'; +var RuleMark = 'rule'; +var SymbolMark = 'symbol'; +var TextMark = 'text'; + +var legendGradient = function(spec, scale, config, userEncode) { + var zero = {value: 0}, + encode = {}, enter, update; + + encode.enter = enter = { + opacity: zero, + x: zero, + y: zero + }; + addEncode(enter, 'width', config.gradientWidth); + addEncode(enter, 'height', config.gradientHeight); + addEncode(enter, 'stroke', config.gradientStrokeColor); + addEncode(enter, 'strokeWidth', config.gradientStrokeWidth); + + encode.exit = { + opacity: zero + }; + + encode.update = update = { + x: zero, + y: zero, + fill: {gradient: scale}, + opacity: {value: 1} + }; + addEncode(update, 'width', config.gradientWidth); + addEncode(update, 'height', config.gradientHeight); + + return guideMark(RectMark, LegendGradientRole, null, undefined, undefined, encode, userEncode); +}; + +var alignExpr = 'datum.' + Perc + '<=0?"left"' + + ':datum.' + Perc + '>=1?"right":"center"'; + +var legendGradientLabels = function(spec, config, userEncode, dataRef) { + var zero = {value: 0}, + encode = {}, enter, update; + + encode.enter = enter = { + opacity: zero + }; + addEncode(enter, 'fill', config.labelColor); + addEncode(enter, 'font', config.labelFont); + addEncode(enter, 'fontSize', config.labelFontSize); + addEncode(enter, 'fontWeight', config.labelFontWeight); + addEncode(enter, 'baseline', config.gradientLabelBaseline); + addEncode(enter, 'limit', config.gradientLabelLimit); + + encode.exit = { + opacity: zero + }; + + encode.update = update = { + opacity: {value: 1}, + text: {field: Label} + }; + + enter.x = update.x = { + field: Perc, + mult: config.gradientWidth + }; + + enter.y = update.y = { + value: config.gradientHeight, + offset: config.gradientLabelOffset + }; + + enter.align = update.align = {signal: alignExpr}; + + return guideMark(TextMark, LegendLabelRole, GuideLabelStyle, Perc, dataRef, encode, userEncode); +}; + +var legendLabels = function(spec, config, userEncode, dataRef) { + var zero = {value: 0}, + encode = {}, enter, update; + + encode.enter = enter = { + opacity: zero + }; + addEncode(enter, 'align', config.labelAlign); + addEncode(enter, 'baseline', config.labelBaseline); + addEncode(enter, 'fill', config.labelColor); + addEncode(enter, 'font', config.labelFont); + addEncode(enter, 'fontSize', config.labelFontSize); + addEncode(enter, 'fontWeight', config.labelFontWeight); + addEncode(enter, 'limit', config.labelLimit); + + encode.exit = { + opacity: zero + }; + + encode.update = update = { + opacity: {value: 1}, + text: {field: Label} + }; + + enter.x = update.x = { + field: Offset, + offset: config.labelOffset + }; + + enter.y = update.y = { + field: Size, + mult: 0.5, + offset: { + field: Total, + offset: { + field: {group: 'entryPadding'}, + mult: {field: Index} + } + } + }; + + return guideMark(TextMark, LegendLabelRole, GuideLabelStyle, Value, dataRef, encode, userEncode); +}; + +var legendSymbols = function(spec, config, userEncode, dataRef) { + var zero = {value: 0}, + encode = {}, enter, update; + + encode.enter = enter = { + opacity: zero + }; + addEncode(enter, 'shape', config.symbolType); + addEncode(enter, 'size', config.symbolSize); + addEncode(enter, 'strokeWidth', config.symbolStrokeWidth); + if (!spec.fill) { + addEncode(enter, 'fill', config.symbolFillColor); + addEncode(enter, 'stroke', config.symbolStrokeColor); + } + + encode.exit = { + opacity: zero + }; + + encode.update = update = { + opacity: {value: 1} + }; + + enter.x = update.x = { + field: Offset, + mult: 0.5 + }; + + enter.y = update.y = { + field: Size, + mult: 0.5, + offset: { + field: Total, + offset: { + field: {group: 'entryPadding'}, + mult: {field: Index} + } + } + }; + + LegendScales.forEach(function(scale) { + if (spec[scale]) { + update[scale] = enter[scale] = {scale: spec[scale], field: Value}; + } + }); + + return guideMark(SymbolMark, LegendSymbolRole, null, Value, dataRef, encode, userEncode); +}; + +var legendTitle = function(spec, config, userEncode, dataRef) { + var zero = {value: 0}, + title = spec.title, + encode = {}, enter; + + encode.enter = enter = { + x: {field: {group: 'padding'}}, + y: {field: {group: 'padding'}}, + opacity: zero + }; + addEncode(enter, 'align', config.titleAlign); + addEncode(enter, 'baseline', config.titleBaseline); + addEncode(enter, 'fill', config.titleColor); + addEncode(enter, 'font', config.titleFont); + addEncode(enter, 'fontSize', config.titleFontSize); + addEncode(enter, 'fontWeight', config.titleFontWeight); + addEncode(enter, 'limit', config.titleLimit); + + encode.exit = { + opacity: zero + }; + + encode.update = { + opacity: {value: 1}, + text: title && title.signal ? {signal: title.signal} : {value: title + ''} + }; + + return guideMark(TextMark, LegendTitleRole, GuideTitleStyle, null, dataRef, encode, userEncode); +}; + +var guideGroup = function(role, style, name, dataRef, interactive, encode, marks) { + return { + type: GroupMark, + name: name, + role: role, + style: style, + from: dataRef, + interactive: interactive || false, + encode: encode, + marks: marks + }; +}; + +var clip$3 = function(clip, scope) { + var expr; + + if (isObject(clip)) { + if (clip.signal) { + expr = clip.signal; + } else if (clip.path) { + expr = 'pathShape(' + param(clip.path) + ')'; + } else if (clip.sphere) { + expr = 'geoShape(' + param(clip.sphere) + ', {type: "Sphere"})'; + } + } + + return expr + ? scope.signalRef(expr) + : !!clip; +}; + +function param(value) { + return isObject(value) && value.signal + ? value.signal + : $(value); +} + +var role = function(spec) { + var role = spec.role || ''; + return (!role.indexOf('axis') || !role.indexOf('legend')) + ? role + : spec.type === GroupMark ? ScopeRole$1 : (role || MarkRole); +}; + +var definition$1 = function(spec) { + return { + marktype: spec.type, + name: spec.name || undefined, + role: spec.role || role(spec), + zindex: +spec.zindex || undefined + }; +}; + +var interactive = function(spec, scope) { + return spec && spec.signal ? scope.signalRef(spec.signal) + : spec === false ? false + : true; +}; + +/** + * Parse a data transform specification. + */ +var parseTransform = function(spec, scope) { + var def = definition(spec.type); + if (!def) error$1('Unrecognized transform type: ' + $(spec.type)); + + var t = entry(def.type.toLowerCase(), null, parseParameters(def, spec, scope)); + if (spec.signal) scope.addSignal(spec.signal, scope.proxy(t)); + t.metadata = def.metadata || {}; + + return t; +}; + +/** + * Parse all parameters of a data transform. + */ +function parseParameters(def, spec, scope) { + var params = {}, pdef, i, n; + for (i=0, n=def.params.length; i 0 ? ',' : '') + + (isObject(value$$1) + ? (value$$1.signal || propertyLambda(value$$1)) + : $(value$$1)); + } + return code + ']'; +} + +function objectLambda(obj) { + var code = '{', + i = 0, + key$$1, value$$1; + + for (key$$1 in obj) { + value$$1 = obj[key$$1]; + code += (++i > 1 ? ',' : '') + + $(key$$1) + ':' + + (isObject(value$$1) + ? (value$$1.signal || propertyLambda(value$$1)) + : $(value$$1)); + } + return code + '}'; +} + +prototype$85.addBinding = function(name, bind) { + if (!this.bindings) { + error$1('Nested signals do not support binding: ' + $(name)); + } + this.bindings.push(extend({signal: name}, bind)); +}; + +// ---- + +prototype$85.addScaleProj = function(name, transform) { + if (this.scales.hasOwnProperty(name)) { + error$1('Duplicate scale or projection name: ' + $(name)); + } + this.scales[name] = this.add(transform); +}; + +prototype$85.addScale = function(name, params) { + this.addScaleProj(name, Scale$1(params)); +}; + +prototype$85.addProjection = function(name, params) { + this.addScaleProj(name, Projection$1(params)); +}; + +prototype$85.getScale = function(name) { + if (!this.scales[name]) { + error$1('Unrecognized scale name: ' + $(name)); + } + return this.scales[name]; +}; + +prototype$85.projectionRef = +prototype$85.scaleRef = function(name) { + return ref(this.getScale(name)); +}; + +prototype$85.projectionType = +prototype$85.scaleType = function(name) { + return this.getScale(name).params.type; +}; + +// ---- + +prototype$85.addData = function(name, dataScope) { + if (this.data.hasOwnProperty(name)) { + error$1('Duplicate data set name: ' + $(name)); + } + return (this.data[name] = dataScope); +}; + +prototype$85.getData = function(name) { + if (!this.data[name]) { + error$1('Undefined data set name: ' + $(name)); + } + return this.data[name]; +}; + +prototype$85.addDataPipeline = function(name, entries) { + if (this.data.hasOwnProperty(name)) { + error$1('Duplicate data set name: ' + $(name)); + } + return this.addData(name, DataScope.fromEntries(this, entries)); +}; + +var defaults = function(configs) { + var output = defaults$1(); + (configs || []).forEach(function(config) { + var key$$1, value, style; + if (config) { + for (key$$1 in config) { + if (key$$1 === 'style') { + style = output.style || (output.style = {}); + for (key$$1 in config.style) { + style[key$$1] = extend(style[key$$1] || {}, config.style[key$$1]); + } + } else { + value = config[key$$1]; + output[key$$1] = isObject(value) && !isArray(value) + ? extend(isObject(output[key$$1]) ? output[key$$1] : {}, value) + : value; + } + } + } + }); + return output; +}; + +var defaultFont = 'sans-serif'; +var defaultSymbolSize = 30; +var defaultStrokeWidth = 2; +var defaultColor = '#4c78a8'; +var black = "#000"; +var gray = '#888'; +var lightGray = '#ddd'; + +/** + * Standard configuration defaults for Vega specification parsing. + * Users can provide their own (sub-)set of these default values + * by passing in a config object to the top-level parse method. + */ +function defaults$1() { + return { + // default padding around visualization + padding: 0, + + // default for automatic sizing; options: "none", "pad", "fit" + // or provide an object (e.g., {"type": "pad", "resize": true}) + autosize: 'pad', + + // default view background color + // covers the entire view component + background: null, + + // default event handling configuration + // preventDefault for view-sourced event types except 'wheel' + events: { + defaults: {allow: ['wheel']} + }, + + // defaults for top-level group marks + // accepts mark properties (fill, stroke, etc) + // covers the data rectangle within group width/height + group: null, + + // defaults for basic mark types + // each subset accepts mark properties (fill, stroke, etc) + mark: null, + arc: { fill: defaultColor }, + area: { fill: defaultColor }, + image: null, + line: { + stroke: defaultColor, + strokeWidth: defaultStrokeWidth + }, + path: { stroke: defaultColor }, + rect: { fill: defaultColor }, + rule: { stroke: black }, + shape: { stroke: defaultColor }, + symbol: { + fill: defaultColor, + size: 64 + }, + text: { + fill: black, + font: defaultFont, + fontSize: 11 + }, + + // style definitions + style: { + // axis & legend labels + "guide-label": { + fill: black, + font: defaultFont, + fontSize: 10 + }, + // axis & legend titles + "guide-title": { + fill: black, + font: defaultFont, + fontSize: 11, + fontWeight: 'bold' + }, + // headers, including chart title + "group-title": { + fill: black, + font: defaultFont, + fontSize: 13, + fontWeight: 'bold' + }, + // defaults for styled point marks in Vega-Lite + point: { + size: defaultSymbolSize, + strokeWidth: defaultStrokeWidth, + shape: 'circle' + }, + circle: { + size: defaultSymbolSize, + strokeWidth: defaultStrokeWidth + }, + square: { + size: defaultSymbolSize, + strokeWidth: defaultStrokeWidth, + shape: 'square' + }, + // defaults for styled group marks in Vega-Lite + cell: { + fill: 'transparent', + stroke: lightGray + } + }, + + // defaults for axes + axis: { + minExtent: 0, + maxExtent: 200, + bandPosition: 0.5, + domain: true, + domainWidth: 1, + domainColor: gray, + grid: false, + gridWidth: 1, + gridColor: lightGray, + gridOpacity: 1, + labels: true, + labelAngle: 0, + labelLimit: 180, + labelPadding: 2, + ticks: true, + tickColor: gray, + tickOffset: 0, + tickRound: true, + tickSize: 5, + tickWidth: 1, + titleAlign: 'center', + titlePadding: 4 + }, + + // correction for centering bias + axisBand: { + tickOffset: -1 + }, + + // defaults for legends + legend: { + orient: 'right', + offset: 18, + padding: 0, + entryPadding: 5, + titlePadding: 5, + gradientWidth: 100, + gradientHeight: 20, + gradientStrokeColor: lightGray, + gradientStrokeWidth: 0, + gradientLabelBaseline: 'top', + gradientLabelOffset: 2, + labelAlign: 'left', + labelBaseline: 'middle', + labelOffset: 8, + labelLimit: 160, + symbolType: 'circle', + symbolSize: 100, + symbolFillColor: 'transparent', + symbolStrokeColor: gray, + symbolStrokeWidth: 1.5, + titleAlign: 'left', + titleBaseline: 'top', + titleLimit: 180 + }, + + // defaults for group title + title: { + orient: 'top', + anchor: 'middle', + offset: 4 + }, + + // defaults for scale ranges + range: { + category: { + scheme: 'tableau10' + }, + ordinal: { + scheme: 'blues', + extent: [0.2, 1] + }, + heatmap: { + scheme: 'viridis' + }, + ramp: { + scheme: 'blues', + extent: [0.2, 1] + }, + diverging: { + scheme: 'blueorange' + }, + symbol: [ + 'circle', + 'square', + 'triangle-up', + 'cross', + 'diamond', + 'triangle-right', + 'triangle-down', + 'triangle-left' + ] + } + }; +} + +var parse$2 = function(spec, config) { + if (!isObject(spec)) error$1('Input Vega specification must be an object.'); + return parseView(spec, new Scope(defaults([config, spec.config]))) + .toRuntime(); +}; + +/** + * Parse an expression given the argument signature and body code. + */ +function expression$1(args, code, ctx) { + // wrap code in return statement if expression does not terminate + if (code[code.length-1] !== ';') { + code = 'return(' + code + ');'; + } + var fn = Function.apply(null, args.concat(code)); + return ctx && ctx.functions ? fn.bind(ctx.functions) : fn; +} + +/** + * Parse an expression used to update an operator value. + */ +function operatorExpression(code, ctx) { + return expression$1(['_'], code, ctx); +} + +/** + * Parse an expression provided as an operator parameter value. + */ +function parameterExpression(code, ctx) { + return expression$1(['datum', '_'], code, ctx); +} + +/** + * Parse an expression applied to an event stream. + */ +function eventExpression(code, ctx) { + return expression$1(['event'], code, ctx); +} + +/** + * Parse an expression used to handle an event-driven operator update. + */ +function handlerExpression(code, ctx) { + return expression$1(['_', 'event'], code, ctx); +} + +/** + * Parse an expression that performs visual encoding. + */ +function encodeExpression(code, ctx) { + return expression$1(['item', '_'], code, ctx); +} + +/** + * Parse a set of operator parameters. + */ +function parseParameters$1(spec, ctx, params) { + params = params || {}; + var key$$1, value; + + for (key$$1 in spec) { + value = spec[key$$1]; + + if (value && value.$expr && value.$params) { + // if expression, parse its parameters + parseParameters$1(value.$params, ctx, params); + } + + params[key$$1] = isArray(value) + ? value.map(function(v) { return parseParameter$2(v, ctx); }) + : parseParameter$2(value, ctx); + } + return params; +} + +/** + * Parse a single parameter. + */ +function parseParameter$2(spec, ctx) { + if (!spec || !isObject(spec)) return spec; + + for (var i=0, n=PARSERS.length, p; i= 0) { + l.splice(i, 1); + } + return this; +}; + +function findHandler(signal, handler) { + var t = signal._targets || [], + h = t.filter(function(op) { + var u = op._update; + return u && u.handler === handler; + }); + return h.length ? h[0] : null; +} + +prototype$83.addSignalListener = function(name, handler) { + var s = lookupSignal(this, name), + h = findHandler(s, handler); + + if (!h) { + h = function() { handler(name, s.value); }; + h.handler = handler; + this.on(s, null, h); + } + return this; +}; + +prototype$83.removeSignalListener = function(name, handler) { + var s = lookupSignal(this, name), + h = findHandler(s, handler); + + if (h) s._targets.remove(h); + return this; +}; + +prototype$83.preventDefault = function(_) { + if (arguments.length) { + this._preventDefault = _; + return this; + } else { + return this._preventDefault; + } +}; + +prototype$83.tooltipHandler = function(_) { + var h = this._handler; + if (!arguments.length) { + return h.handleTooltip; + } else { + h.handleTooltip = _ || Handler.prototype.handleTooltip; + return this; + } +}; + +prototype$83.events = events$1; +prototype$83.finalize = finalize; +prototype$83.hover = hover; + +// -- DATA ---- +prototype$83.data = data; +prototype$83.change = change; +prototype$83.insert = insert; +prototype$83.remove = remove; + +// -- INITIALIZATION ---- +prototype$83.initialize = initialize$1; + +// -- HEADLESS RENDERING ---- +prototype$83.toImageURL = renderToImageURL; +prototype$83.toCanvas = renderToCanvas; +prototype$83.toSVG = renderToSVG; + +// -- SAVE / RESTORE STATE ---- +prototype$83.getState = getState$1; +prototype$83.setState = setState$1; + +// -- Transforms ----- + +extend(transforms, tx, vtx, encode, geo, force, tree, voronoi, wordcloud, xf); + +exports.version = version; +exports.Dataflow = Dataflow; +exports.EventStream = EventStream; +exports.Parameters = Parameters; +exports.Pulse = Pulse; +exports.MultiPulse = MultiPulse; +exports.Operator = Operator; +exports.Transform = Transform; +exports.changeset = changeset; +exports.ingest = ingest; +exports.isTuple = isTuple; +exports.definition = definition; +exports.transform = transform$1; +exports.transforms = transforms; +exports.tupleid = tupleid; +exports.scale = scale$1; +exports.scheme = getScheme; +exports.interpolate = interpolate$1; +exports.interpolateRange = interpolateRange; +exports.timeInterval = timeInterval; +exports.utcInterval = utcInterval; +exports.projection = projection$$1; +exports.View = View; +exports.parse = parse$2; +exports.expressionFunction = expressionFunction; +exports.formatLocale = defaultLocale$1; +exports.timeFormatLocale = defaultLocale; +exports.runtime = parseDataflow; +exports.runtimeContext = context$2; +exports.bin = bin; +exports.bootstrapCI = bootstrapCI; +exports.quartiles = quartiles; +exports.setRandom = setRandom; +exports.randomInteger = integer; +exports.randomKDE = randomKDE; +exports.randomMixture = randomMixture; +exports.randomNormal = randomNormal; +exports.randomUniform = randomUniform; +exports.accessor = accessor; +exports.accessorName = accessorName; +exports.accessorFields = accessorFields; +exports.id = id; +exports.identity = identity; +exports.zero = zero; +exports.one = one; +exports.truthy = truthy; +exports.falsy = falsy; +exports.logger = logger; +exports.None = None; +exports.Error = Error$1; +exports.Warn = Warn; +exports.Info = Info; +exports.Debug = Debug; +exports.panLinear = panLinear; +exports.panLog = panLog; +exports.panPow = panPow; +exports.zoomLinear = zoomLinear; +exports.zoomLog = zoomLog; +exports.zoomPow = zoomPow; +exports.array = array; +exports.compare = compare; +exports.constant = constant; +exports.debounce = debounce; +exports.error = error$1; +exports.extend = extend; +exports.extentIndex = extentIndex; +exports.fastmap = fastmap; +exports.field = field; +exports.inherits = inherits; +exports.isArray = isArray; +exports.isBoolean = isBoolean; +exports.isDate = isDate; +exports.isFunction = isFunction; +exports.isNumber = isNumber; +exports.isObject = isObject; +exports.isRegExp = isRegExp; +exports.isString = isString; +exports.key = key; +exports.merge = merge; +exports.pad = pad; +exports.peek = peek; +exports.repeat = repeat; +exports.splitAccessPath = splitAccessPath; +exports.stringValue = $; +exports.toBoolean = toBoolean; +exports.toDate = toDate; +exports.toNumber = toNumber; +exports.toString = toString; +exports.toSet = toSet; +exports.truncate = truncate; +exports.visitArray = visitArray; +exports.loader = loader; +exports.read = read; +exports.inferType = inferType; +exports.inferTypes = inferTypes; +exports.typeParsers = typeParsers; +exports.formats = formats$1; +exports.Bounds = Bounds; +exports.Gradient = Gradient; +exports.GroupItem = GroupItem; +exports.ResourceLoader = ResourceLoader; +exports.Item = Item; +exports.Scenegraph = Scenegraph; +exports.Handler = Handler; +exports.Renderer = Renderer; +exports.CanvasHandler = CanvasHandler; +exports.CanvasRenderer = CanvasRenderer; +exports.SVGHandler = SVGHandler; +exports.SVGRenderer = SVGRenderer; +exports.SVGStringRenderer = SVGStringRenderer; +exports.RenderType = RenderType; +exports.renderModule = renderModule; +exports.Marks = marks; +exports.boundClip = boundClip; +exports.boundContext = context; +exports.boundStroke = boundStroke; +exports.boundItem = boundItem$1; +exports.boundMark = boundMark; +exports.pathCurves = curves; +exports.pathSymbols = symbols$1; +exports.pathRectangle = vg_rect; +exports.pathTrail = vg_trail; +exports.pathParse = pathParse; +exports.pathRender = pathRender; +exports.point = point$4; +exports.domCreate = domCreate; +exports.domFind = domFind; +exports.domChild = domChild; +exports.domClear = domClear; +exports.openTag = openTag; +exports.closeTag = closeTag; +exports.font = font; +exports.textMetrics = textMetrics; +exports.resetSVGClipId = resetSVGClipId; +exports.sceneEqual = sceneEqual; +exports.pathEqual = pathEqual; +exports.sceneToJSON = sceneToJSON; +exports.sceneFromJSON = sceneFromJSON; +exports.sceneZOrder = zorder; +exports.sceneVisit = visit; +exports.scenePickVisit = pickVisit; + +Object.defineProperty(exports, '__esModule', { value: true }); + +}))); + +}).call(this,require("buffer").Buffer) + +},{"buffer":1,"canvas":1,"canvas-prebuilt":1,"fs":1}],5:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Parse a vega schema url into library and version. + */ +function default_1(url) { + var regex = /\/schema\/([\w-]+)\/([\w\.\-]+)\.json$/g; + var _a = regex.exec(url).slice(1, 3), library = _a[0], version = _a[1]; + return { library: library, version: version }; +} +exports.default = default_1; + +},{}],6:[function(require,module,exports){ +(function (global){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +var versionCompare = require("compare-versions"); +var d3 = require("d3-selection"); +var vegaImport = require("vega-lib"); +var VegaLite = (typeof window !== "undefined" ? window['vl'] : typeof global !== "undefined" ? global['vl'] : null); +var vega_schema_url_parser_1 = require("vega-schema-url-parser"); +var post_1 = require("./post"); +exports.vega = vegaImport; +exports.vl = VegaLite; +var NAMES = { + 'vega': 'Vega', + 'vega-lite': 'Vega-Lite', +}; +var VERSION = { + 'vega': exports.vega.version, + 'vega-lite': exports.vl ? exports.vl.version : 'not available', +}; +var PREPROCESSOR = { + 'vega': function (vgjson, _) { return vgjson; }, + 'vega-lite': function (vljson, config) { return exports.vl.compile(vljson, config).spec; }, +}; +/** + * Embed a Vega visualization component in a web page. This function returns a promise. + * + * @param el DOM element in which to place component (DOM node or CSS selector). + * @param spec String : A URL string from which to load the Vega specification. + * Object : The Vega/Vega-Lite specification as a parsed JSON object. + * @param opt A JavaScript object containing options for embedding. + */ +function embed(el, spec, opt) { + try { + opt = opt || {}; + var actions = opt.actions !== undefined ? opt.actions : true; + var loader = opt.loader || exports.vega.loader(); + var renderer = opt.renderer || 'canvas'; + var logLevel = opt.logLevel || exports.vega.Warn; + // Load the visualization specification. + if (exports.vega.isString(spec)) { + return loader.load(spec).then(function (data) { return embed(el, JSON.parse(data), opt); }).catch(Promise.reject); + } + // Load Vega theme/configuration. + var config = opt.config; + if (exports.vega.isString(config)) { + return loader.load(config).then(function (data) { + opt.config = JSON.parse(data); + return embed(el, spec, opt); + }).catch(Promise.reject); + } + // Decide mode + var parsed = void 0; + var mode_1; + if (spec.$schema) { + parsed = vega_schema_url_parser_1.default(spec.$schema); + if (opt.mode && opt.mode !== parsed.library) { + console.warn("The given visualization spec is written in " + NAMES[parsed.library] + ", but mode argument sets " + NAMES[opt.mode] + "."); + } + mode_1 = parsed.library; + if (versionCompare(parsed.version, VERSION[mode_1]) > 0) { + console.warn("The input spec uses " + mode_1 + " " + parsed.version + ", but the current version of " + NAMES[mode_1] + " is " + VERSION[mode_1] + "."); + } + } + else { + mode_1 = opt.mode || 'vega'; + } + var vgSpec = PREPROCESSOR[mode_1](spec, config); + if (mode_1 === 'vega-lite') { + if (vgSpec.$schema) { + parsed = vega_schema_url_parser_1.default(vgSpec.$schema); + if (versionCompare(parsed.version, VERSION.vega) > 0) { + console.warn("The compiled spec uses Vega " + parsed.version + ", but current version is " + VERSION.vega + "."); + } + } + } + // ensure container div has class 'vega-embed' + var div = d3.select(el) // d3.select supports elements and strings + .classed('vega-embed', true) + .html(''); // clear container + if (opt.onBeforeParse) { + // Allow Vega spec to be modified before being used + vgSpec = opt.onBeforeParse(vgSpec); + } + var runtime = exports.vega.parse(vgSpec, opt.config); // may throw an Error if parsing fails + var view_1 = new exports.vega.View(runtime, { loader: loader, logLevel: logLevel, renderer: renderer }) + .initialize(el); + // Vega-Lite does not need hover so we can improve perf by not activating it + if (mode_1 !== 'vega-lite') { + view_1.hover(); + } + if (opt) { + if (opt.width) { + view_1.width(opt.width); + } + if (opt.height) { + view_1.height(opt.height); + } + if (opt.padding) { + view_1.padding(opt.padding); + } + } + view_1.run(); + if (actions !== false) { + // add child div to house action links + var ctrl = div.append('div') + .attr('class', 'vega-actions'); + // add 'Export' action + if (actions === true || actions.export !== false) { + var ext_1 = renderer === 'canvas' ? 'png' : 'svg'; + ctrl.append('a') + .text("Export as " + ext_1.toUpperCase()) + .attr('href', '#') + .attr('target', '_blank') + .attr('download', "visualization." + ext_1) + .on('mousedown', function () { + var _this = this; + view_1.toImageURL(ext_1).then(function (url) { + _this.href = url; + }).catch(function (error) { throw error; }); + d3.event.preventDefault(); + }); + } + // add 'View Source' action + if (actions === true || actions.source !== false) { + ctrl.append('a') + .text('View Source') + .attr('href', '#') + .on('click', function () { + viewSource(JSON.stringify(spec, null, 2), opt.sourceHeader || '', opt.sourceFooter || ''); + d3.event.preventDefault(); + }); + } + // add 'Open in Vega Editor' action + if (actions === true || actions.editor !== false) { + var editorUrl_1 = opt.editorUrl || 'https://vega.github.io/editor/'; + ctrl.append('a') + .text('Open in Vega Editor') + .attr('href', '#') + .on('click', function () { + post_1.post(window, editorUrl_1, { + mode: mode_1, + spec: JSON.stringify(spec, null, 2), + }); + d3.event.preventDefault(); + }); + } + } + return Promise.resolve({ view: view_1, spec: spec }); + } + catch (err) { + return Promise.reject(err); + } +} +exports.default = embed; +function viewSource(source, sourceHeader, sourceFooter) { + var header = "" + sourceHeader + "
";
+    var footer = "
" + sourceFooter + ""; + var win = window.open(''); + win.document.write(header + source + footer); + win.document.title = 'Vega JSON Source'; +} + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./post":8,"compare-versions":2,"d3-selection":3,"vega-lib":4,"vega-schema-url-parser":5}],7:[function(require,module,exports){ +(function (global){ +"use strict"; +var vega = require("vega-lib"); +var vl = (typeof window !== "undefined" ? window['vl'] : typeof global !== "undefined" ? global['vl'] : null); +var embed_1 = require("./embed"); +var embedModule = embed_1.default; +embedModule.default = embed_1.default; +// expose Vega and Vega-Lite libs +embedModule.vega = vega; +embedModule.vl = vl; +module.exports = embedModule; + +}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {}) + +},{"./embed":6,"vega-lib":4}],8:[function(require,module,exports){ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +/** + * Open editor url in a new window, and pass a message. + */ +function post(window, url, data) { + var editor = window.open(url); + var wait = 10000; + var step = 250; + var count = ~~(wait / step); + function listen(evt) { + if (evt.source === editor) { + count = 0; + window.removeEventListener('message', listen, false); + } + } + window.addEventListener('message', listen, false); + // send message + // periodically resend until ack received or timeout + function send() { + if (count <= 0) { + return; + } + editor.postMessage(data, '*'); + setTimeout(send, step); + count -= 1; + } + setTimeout(send, step); +} +exports.post = post; + +},{}]},{},[7])(7) +}); +//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIm5vZGVfbW9kdWxlcy9icm93c2VyLXBhY2svX3ByZWx1ZGUuanMiLCJub2RlX21vZHVsZXMvYnJvd3Nlci1yZXNvbHZlL2VtcHR5LmpzIiwibm9kZV9tb2R1bGVzL2NvbXBhcmUtdmVyc2lvbnMvaW5kZXguanMiLCJub2RlX21vZHVsZXMvZDMtc2VsZWN0aW9uL2Rpc3QvZDMtc2VsZWN0aW9uLmpzIiwibm9kZV9tb2R1bGVzL3ZlZ2EtbGliL2J1aWxkL3ZlZ2EuanMiLCJub2RlX21vZHVsZXMvdmVnYS1zY2hlbWEtdXJsLXBhcnNlci9pbmRleC5qcyIsInNyYy9lbWJlZC50cyIsInNyYy9pbmRleC50cyIsInNyYy9wb3N0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FDQUE7O0FDQUE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBOztBQ3BFQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7OztBQ24rQkE7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7QUN0dW5DQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7Ozs7O0FDWEEsaURBQW1EO0FBQ25ELGlDQUFtQztBQUNuQyxxQ0FBdUM7QUFDdkMsb0NBQXNDO0FBQ3RDLGlFQUFrRDtBQUtsRCwrQkFBOEI7QUFFakIsUUFBQSxJQUFJLEdBQUcsVUFBVSxDQUFDO0FBQ2xCLFFBQUEsRUFBRSxHQUFHLFFBQVEsQ0FBQztBQW9CM0IsSUFBTSxLQUFLLEdBQUc7SUFDWixNQUFNLEVBQU8sTUFBTTtJQUNuQixXQUFXLEVBQUUsV0FBVztDQUN6QixDQUFDO0FBRUYsSUFBTSxPQUFPLEdBQUc7SUFDZCxNQUFNLEVBQU8sWUFBSSxDQUFDLE9BQU87SUFDekIsV0FBVyxFQUFFLFVBQUUsQ0FBQyxDQUFDLENBQUMsVUFBRSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUMsZUFBZTtDQUMvQyxDQUFDO0FBRUYsSUFBTSxZQUFZLEdBQUc7SUFDbkIsTUFBTSxFQUFPLFVBQUMsTUFBTSxFQUFFLENBQUMsSUFBSyxPQUFBLE1BQU0sRUFBTixDQUFNO0lBQ2xDLFdBQVcsRUFBRSxVQUFDLE1BQU0sRUFBRSxNQUFNLElBQUssT0FBQSxVQUFFLENBQUMsT0FBTyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQyxJQUFJLEVBQS9CLENBQStCO0NBQ2pFLENBQUM7QUFJRjs7Ozs7OztHQU9HO0FBQ0gsZUFBOEIsRUFBNEIsRUFBRSxJQUFnQyxFQUFFLEdBQWlCO0lBQzdHLElBQUksQ0FBQztRQUNILEdBQUcsR0FBRyxHQUFHLElBQUksRUFBRSxDQUFDO1FBQ2hCLElBQU0sT0FBTyxHQUFJLEdBQUcsQ0FBQyxPQUFPLEtBQUssU0FBUyxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUM7UUFFaEUsSUFBTSxNQUFNLEdBQVcsR0FBRyxDQUFDLE1BQU0sSUFBSSxZQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDbkQsSUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFFBQVEsSUFBSSxRQUFRLENBQUM7UUFDMUMsSUFBTSxRQUFRLEdBQUcsR0FBRyxDQUFDLFFBQVEsSUFBSSxZQUFJLENBQUMsSUFBSSxDQUFDO1FBRTNDLHdDQUF3QztRQUN4QyxFQUFFLENBQUMsQ0FBQyxZQUFJLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixNQUFNLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQzNCLFVBQUEsSUFBSSxJQUFJLE9BQUEsS0FBSyxDQUFDLEVBQUUsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxFQUFFLEdBQUcsQ0FBQyxFQUFoQyxDQUFnQyxDQUN6QyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDMUIsQ0FBQztRQUVELGlDQUFpQztRQUNqQyxJQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDO1FBQzFCLEVBQUUsQ0FBQyxDQUFDLFlBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQzFCLE1BQU0sQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFBLElBQUk7Z0JBQ2xDLEdBQUcsQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxJQUFJLENBQUMsQ0FBQztnQkFDOUIsTUFBTSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1lBQzlCLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7UUFDM0IsQ0FBQztRQUVELGNBQWM7UUFDZCxJQUFJLE1BQU0sU0FBb0MsQ0FBQztRQUMvQyxJQUFJLE1BQVUsQ0FBQztRQUVmLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLE1BQU0sR0FBRyxnQ0FBWSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUNwQyxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxJQUFJLEtBQUssTUFBTSxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQzVDLE9BQU8sQ0FBQyxJQUFJLENBQUMsZ0RBQThDLEtBQUssQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLGlDQUE0QixLQUFLLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxNQUFHLENBQUMsQ0FBQztZQUNsSSxDQUFDO1lBRUQsTUFBSSxHQUFHLE1BQU0sQ0FBQyxPQUFlLENBQUM7WUFFOUIsRUFBRSxDQUFDLENBQUMsY0FBYyxDQUFDLE1BQU0sQ0FBQyxPQUFPLEVBQUUsT0FBTyxDQUFDLE1BQUksQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQztnQkFDdEQsT0FBTyxDQUFDLElBQUksQ0FBQyx5QkFBdUIsTUFBSSxTQUFJLE1BQU0sQ0FBQyxPQUFPLHFDQUFnQyxLQUFLLENBQUMsTUFBSSxDQUFDLFlBQU8sT0FBTyxDQUFDLE1BQUksQ0FBQyxNQUFHLENBQUMsQ0FBQztZQUNoSSxDQUFDO1FBQ0gsQ0FBQztRQUFDLElBQUksQ0FBQyxDQUFDO1lBQ04sTUFBSSxHQUFHLEdBQUcsQ0FBQyxJQUFJLElBQUksTUFBTSxDQUFDO1FBQzVCLENBQUM7UUFFRCxJQUFJLE1BQU0sR0FBVyxZQUFZLENBQUMsTUFBSSxDQUFDLENBQUMsSUFBSSxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBRXRELEVBQUUsQ0FBQyxDQUFDLE1BQUksS0FBSyxXQUFXLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLEVBQUUsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsQ0FBQyxDQUFDO2dCQUNuQixNQUFNLEdBQUcsZ0NBQVksQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDLENBQUM7Z0JBRXRDLEVBQUUsQ0FBQyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsT0FBTyxFQUFFLE9BQU8sQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNyRCxPQUFPLENBQUMsSUFBSSxDQUFDLGlDQUErQixNQUFNLENBQUMsT0FBTyxpQ0FBNEIsT0FBTyxDQUFDLElBQUksTUFBRyxDQUFDLENBQUM7Z0JBQ3pHLENBQUM7WUFDSCxDQUFDO1FBQ0gsQ0FBQztRQUVELDhDQUE4QztRQUM5QyxJQUFNLEdBQUcsR0FBRyxFQUFFLENBQUMsTUFBTSxDQUFDLEVBQVMsQ0FBQyxDQUFFLDBDQUEwQzthQUN6RSxPQUFPLENBQUMsWUFBWSxFQUFFLElBQUksQ0FBQzthQUMzQixJQUFJLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxrQkFBa0I7UUFFL0IsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQUM7WUFDdEIsbURBQW1EO1lBQ25ELE1BQU0sR0FBRyxHQUFHLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBQ3JDLENBQUM7UUFFRCxJQUFNLE9BQU8sR0FBRyxZQUFJLENBQUMsS0FBSyxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBRSxzQ0FBc0M7UUFFdkYsSUFBTSxNQUFJLEdBQUcsSUFBSSxZQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxFQUFDLE1BQU0sUUFBQSxFQUFFLFFBQVEsVUFBQSxFQUFFLFFBQVEsVUFBQSxFQUFDLENBQUM7YUFDOUQsVUFBVSxDQUFDLEVBQUUsQ0FBQyxDQUFDO1FBRWxCLDRFQUE0RTtRQUM1RSxFQUFFLENBQUMsQ0FBQyxNQUFJLEtBQUssV0FBVyxDQUFDLENBQUMsQ0FBQztZQUN6QixNQUFJLENBQUMsS0FBSyxFQUFFLENBQUM7UUFDZixDQUFDO1FBRUQsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQztZQUNSLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNkLE1BQUksQ0FBQyxLQUFLLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ3hCLENBQUM7WUFDRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQztnQkFDZixNQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNLENBQUMsQ0FBQztZQUMxQixDQUFDO1lBQ0QsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7Z0JBQ2hCLE1BQUksQ0FBQyxPQUFPLENBQUMsR0FBRyxDQUFDLE9BQU8sQ0FBQyxDQUFDO1lBQzVCLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO1FBRVgsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7WUFDdEIsc0NBQXNDO1lBQ3RDLElBQU0sSUFBSSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDO2lCQUMzQixJQUFJLENBQUMsT0FBTyxFQUFFLGNBQWMsQ0FBQyxDQUFDO1lBRWpDLHNCQUFzQjtZQUN0QixFQUFFLENBQUMsQ0FBQyxPQUFPLEtBQUssSUFBSSxJQUFJLE9BQU8sQ0FBQyxNQUFNLEtBQUssS0FBSyxDQUFDLENBQUMsQ0FBQztnQkFDakQsSUFBTSxLQUFHLEdBQUcsUUFBUSxLQUFLLFFBQVEsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUM7Z0JBQ2xELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO3FCQUNiLElBQUksQ0FBQyxlQUFhLEtBQUcsQ0FBQyxXQUFXLEVBQUksQ0FBQztxQkFDdEMsSUFBSSxDQUFDLE1BQU0sRUFBRSxHQUFHLENBQUM7cUJBQ2pCLElBQUksQ0FBQyxRQUFRLEVBQUUsUUFBUSxDQUFDO3FCQUN4QixJQUFJLENBQUMsVUFBVSxFQUFFLG1CQUFpQixLQUFLLENBQUM7cUJBQ3hDLEVBQUUsQ0FBQyxXQUFXLEVBQUU7b0JBQUEsaUJBS2hCO29CQUpDLE1BQUksQ0FBQyxVQUFVLENBQUMsS0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQUEsR0FBRzt3QkFDM0IsS0FBSSxDQUFDLElBQUksR0FBSSxHQUFHLENBQUM7b0JBQ25CLENBQUMsQ0FBQyxDQUFDLEtBQUssQ0FBQyxVQUFBLEtBQUssSUFBTSxNQUFNLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO29CQUNwQyxFQUFFLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM1QixDQUFDLENBQUMsQ0FBQztZQUNQLENBQUM7WUFFRCwyQkFBMkI7WUFDM0IsRUFBRSxDQUFDLENBQUMsT0FBTyxLQUFLLElBQUksSUFBSSxPQUFPLENBQUMsTUFBTSxLQUFLLEtBQUssQ0FBQyxDQUFDLENBQUM7Z0JBQ2pELElBQUksQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDO3FCQUNiLElBQUksQ0FBQyxhQUFhLENBQUM7cUJBQ25CLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDO3FCQUNqQixFQUFFLENBQUMsT0FBTyxFQUFFO29CQUNYLFVBQVUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksRUFBRSxJQUFJLEVBQUUsQ0FBQyxDQUFDLEVBQUUsR0FBRyxDQUFDLFlBQVksSUFBSSxFQUFFLEVBQUUsR0FBRyxDQUFDLFlBQVksSUFBSSxFQUFFLENBQUMsQ0FBQztvQkFDMUYsRUFBRSxDQUFDLEtBQUssQ0FBQyxjQUFjLEVBQUUsQ0FBQztnQkFDNUIsQ0FBQyxDQUFDLENBQUM7WUFDUCxDQUFDO1lBRUQsbUNBQW1DO1lBQ25DLEVBQUUsQ0FBQyxDQUFDLE9BQU8sS0FBSyxJQUFJLElBQUksT0FBTyxDQUFDLE1BQU0sS0FBSyxLQUFLLENBQUMsQ0FBQyxDQUFDO2dCQUNqRCxJQUFNLFdBQVMsR0FBRyxHQUFHLENBQUMsU0FBUyxJQUFJLGdDQUFnQyxDQUFDO2dCQUNwRSxJQUFJLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQztxQkFDYixJQUFJLENBQUMscUJBQXFCLENBQUM7cUJBQzNCLElBQUksQ0FBQyxNQUFNLEVBQUUsR0FBRyxDQUFDO3FCQUNqQixFQUFFLENBQUMsT0FBTyxFQUFFO29CQUNYLFdBQUksQ0FBQyxNQUFNLEVBQUUsV0FBUyxFQUFFO3dCQUN0QixJQUFJLFFBQUE7d0JBQ0osSUFBSSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7cUJBQ3BDLENBQUMsQ0FBQztvQkFDSCxFQUFFLENBQUMsS0FBSyxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM1QixDQUFDLENBQUMsQ0FBQztZQUNQLENBQUM7UUFDSCxDQUFDO1FBRUQsTUFBTSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsRUFBQyxJQUFJLFFBQUEsRUFBRSxJQUFJLE1BQUEsRUFBQyxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7UUFDYixNQUFNLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUM3QixDQUFDO0FBQ0gsQ0FBQztBQTlJRCx3QkE4SUM7QUFFRCxvQkFBb0IsTUFBYyxFQUFFLFlBQW9CLEVBQUUsWUFBb0I7SUFDNUUsSUFBTSxNQUFNLEdBQUcsaUJBQWUsWUFBWSw0Q0FBdUMsQ0FBQztJQUNsRixJQUFNLE1BQU0sR0FBRyxrQkFBZ0IsWUFBWSxtQkFBZ0IsQ0FBQztJQUM1RCxJQUFNLEdBQUcsR0FBRyxNQUFNLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO0lBQzVCLEdBQUcsQ0FBQyxRQUFRLENBQUMsS0FBSyxDQUFDLE1BQU0sR0FBRyxNQUFNLEdBQUcsTUFBTSxDQUFDLENBQUM7SUFDN0MsR0FBRyxDQUFDLFFBQVEsQ0FBQyxLQUFLLEdBQUcsa0JBQWtCLENBQUM7QUFDMUMsQ0FBQzs7Ozs7OztBQy9NRCwrQkFBaUM7QUFDakMsOEJBQWdDO0FBRWhDLGlDQUE0QjtBQUU1QixJQUFNLFdBQVcsR0FBd0QsZUFBSyxDQUFDO0FBRS9FLFdBQVcsQ0FBQyxPQUFPLEdBQUcsZUFBSyxDQUFDO0FBRTVCLGlDQUFpQztBQUNqQyxXQUFXLENBQUMsSUFBSSxHQUFHLElBQUksQ0FBQztBQUN4QixXQUFXLENBQUMsRUFBRSxHQUFHLEVBQUUsQ0FBQztBQUVwQixpQkFBUyxXQUFXLENBQUM7Ozs7Ozs7QUNickI7O0dBRUc7QUFDSCxjQUFxQixNQUFjLEVBQUUsR0FBVyxFQUFFLElBQVM7SUFDekQsSUFBTSxNQUFNLEdBQUcsTUFBTSxDQUFDLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztJQUNoQyxJQUFNLElBQUksR0FBRyxLQUFLLENBQUM7SUFDbkIsSUFBTSxJQUFJLEdBQUcsR0FBRyxDQUFDO0lBQ2pCLElBQUksS0FBSyxHQUFHLENBQUMsQ0FBQyxDQUFDLElBQUksR0FBRyxJQUFJLENBQUMsQ0FBQztJQUU1QixnQkFBZ0IsR0FBRztRQUNqQixFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxLQUFLLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDMUIsS0FBSyxHQUFHLENBQUMsQ0FBQztZQUNWLE1BQU0sQ0FBQyxtQkFBbUIsQ0FBQyxTQUFTLEVBQUUsTUFBTSxFQUFFLEtBQUssQ0FBQyxDQUFDO1FBQ3ZELENBQUM7SUFDSCxDQUFDO0lBQ0QsTUFBTSxDQUFDLGdCQUFnQixDQUFDLFNBQVMsRUFBRSxNQUFNLEVBQUUsS0FBSyxDQUFDLENBQUM7SUFFbEQsZUFBZTtJQUNmLG9EQUFvRDtJQUNwRDtRQUNFLEVBQUUsQ0FBQyxDQUFDLEtBQUssSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQ2YsTUFBTSxDQUFDO1FBQ1QsQ0FBQztRQUNELE1BQU0sQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLEdBQUcsQ0FBQyxDQUFDO1FBQzlCLFVBQVUsQ0FBQyxJQUFJLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDdkIsS0FBSyxJQUFJLENBQUMsQ0FBQztJQUNiLENBQUM7SUFDRCxVQUFVLENBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO0FBQ3pCLENBQUM7QUF6QkQsb0JBeUJDIiwiZmlsZSI6ImdlbmVyYXRlZC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzQ29udGVudCI6WyIoZnVuY3Rpb24oKXtmdW5jdGlvbiBlKHQsbixyKXtmdW5jdGlvbiBzKG8sdSl7aWYoIW5bb10pe2lmKCF0W29dKXt2YXIgYT10eXBlb2YgcmVxdWlyZT09XCJmdW5jdGlvblwiJiZyZXF1aXJlO2lmKCF1JiZhKXJldHVybiBhKG8sITApO2lmKGkpcmV0dXJuIGkobywhMCk7dmFyIGY9bmV3IEVycm9yKFwiQ2Fubm90IGZpbmQgbW9kdWxlICdcIitvK1wiJ1wiKTt0aHJvdyBmLmNvZGU9XCJNT0RVTEVfTk9UX0ZPVU5EXCIsZn12YXIgbD1uW29dPXtleHBvcnRzOnt9fTt0W29dWzBdLmNhbGwobC5leHBvcnRzLGZ1bmN0aW9uKGUpe3ZhciBuPXRbb11bMV1bZV07cmV0dXJuIHMobj9uOmUpfSxsLGwuZXhwb3J0cyxlLHQsbixyKX1yZXR1cm4gbltvXS5leHBvcnRzfXZhciBpPXR5cGVvZiByZXF1aXJlPT1cImZ1bmN0aW9uXCImJnJlcXVpcmU7Zm9yKHZhciBvPTA7bzxyLmxlbmd0aDtvKyspcyhyW29dKTtyZXR1cm4gc31yZXR1cm4gZX0pKCkiLCIiLCIvKiBnbG9iYWwgZGVmaW5lICovXG4oZnVuY3Rpb24gKHJvb3QsIGZhY3RvcnkpIHtcbiAgICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICAgIGlmICh0eXBlb2YgZGVmaW5lID09PSAnZnVuY3Rpb24nICYmIGRlZmluZS5hbWQpIHtcbiAgICAgICAgZGVmaW5lKFtdLCBmYWN0b3J5KTtcbiAgICB9IGVsc2UgaWYgKHR5cGVvZiBleHBvcnRzID09PSAnb2JqZWN0Jykge1xuICAgICAgICBtb2R1bGUuZXhwb3J0cyA9IGZhY3RvcnkoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgICByb290LmNvbXBhcmVWZXJzaW9ucyA9IGZhY3RvcnkoKTtcbiAgICB9XG59KHRoaXMsIGZ1bmN0aW9uICgpIHtcblxuICAgIHZhciBzZW12ZXIgPSAvXnY/KD86XFxkKykoXFwuKD86W3gqXXxcXGQrKShcXC4oPzpbeCpdfFxcZCspKD86LVtcXGRhLXpcXC1dKyg/OlxcLltcXGRhLXpcXC1dKykqKT8oPzpcXCtbXFxkYS16XFwtXSsoPzpcXC5bXFxkYS16XFwtXSspKik/KT8pPyQvaTtcbiAgICB2YXIgcGF0Y2ggPSAvLShbMC05QS1aYS16LS5dKykvO1xuXG4gICAgZnVuY3Rpb24gc3BsaXQodikge1xuICAgICAgICB2YXIgdGVtcCA9IHYucmVwbGFjZSgvXnYvLCAnJykuc3BsaXQoJy4nKTtcbiAgICAgICAgdmFyIGFyciA9IHRlbXAuc3BsaWNlKDAsIDIpO1xuICAgICAgICBhcnIucHVzaCh0ZW1wLmpvaW4oJy4nKSk7XG4gICAgICAgIHJldHVybiBhcnI7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdHJ5UGFyc2Uodikge1xuICAgICAgICByZXR1cm4gaXNOYU4oTnVtYmVyKHYpKSA/IHYgOiBOdW1iZXIodik7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gdmFsaWRhdGUodmVyc2lvbikge1xuICAgICAgICBpZiAodHlwZW9mIHZlcnNpb24gIT09ICdzdHJpbmcnKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgVHlwZUVycm9yKCdJbnZhbGlkIGFyZ3VtZW50IGV4cGVjdGVkIHN0cmluZycpO1xuICAgICAgICB9XG4gICAgICAgIGlmICghc2VtdmVyLnRlc3QodmVyc2lvbikpIHtcbiAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignSW52YWxpZCBhcmd1bWVudCBub3QgdmFsaWQgc2VtdmVyJyk7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gZnVuY3Rpb24gY29tcGFyZVZlcnNpb25zKHYxLCB2Mikge1xuICAgICAgICBbdjEsIHYyXS5mb3JFYWNoKHZhbGlkYXRlKTtcblxuICAgICAgICB2YXIgczEgPSBzcGxpdCh2MSk7XG4gICAgICAgIHZhciBzMiA9IHNwbGl0KHYyKTtcblxuICAgICAgICBmb3IgKHZhciBpID0gMDsgaSA8IDM7IGkrKykge1xuICAgICAgICAgICAgdmFyIG4xID0gcGFyc2VJbnQoczFbaV0gfHwgMCwgMTApO1xuICAgICAgICAgICAgdmFyIG4yID0gcGFyc2VJbnQoczJbaV0gfHwgMCwgMTApO1xuXG4gICAgICAgICAgICBpZiAobjEgPiBuMikgcmV0dXJuIDE7XG4gICAgICAgICAgICBpZiAobjIgPiBuMSkgcmV0dXJuIC0xO1xuICAgICAgICB9XG5cbiAgICAgICAgaWYgKFtzMVsyXSwgczJbMl1dLmV2ZXJ5KHBhdGNoLnRlc3QuYmluZChwYXRjaCkpKSB7XG4gICAgICAgICAgICB2YXIgcDEgPSBwYXRjaC5leGVjKHMxWzJdKVsxXS5zcGxpdCgnLicpLm1hcCh0cnlQYXJzZSk7XG4gICAgICAgICAgICB2YXIgcDIgPSBwYXRjaC5leGVjKHMyWzJdKVsxXS5zcGxpdCgnLicpLm1hcCh0cnlQYXJzZSk7XG5cbiAgICAgICAgICAgIGZvciAoaSA9IDA7IGkgPCBNYXRoLm1heChwMS5sZW5ndGgsIHAyLmxlbmd0aCk7IGkrKykge1xuICAgICAgICAgICAgICAgIGlmIChwMVtpXSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiBwMltpXSA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIHAxW2ldID09PSAnbnVtYmVyJykgcmV0dXJuIC0xO1xuICAgICAgICAgICAgICAgIGlmIChwMltpXSA9PT0gdW5kZWZpbmVkIHx8IHR5cGVvZiBwMVtpXSA9PT0gJ3N0cmluZycgJiYgdHlwZW9mIHAyW2ldID09PSAnbnVtYmVyJykgcmV0dXJuIDE7XG5cbiAgICAgICAgICAgICAgICBpZiAocDFbaV0gPiBwMltpXSkgcmV0dXJuIDE7XG4gICAgICAgICAgICAgICAgaWYgKHAyW2ldID4gcDFbaV0pIHJldHVybiAtMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgfSBlbHNlIGlmIChbczFbMl0sIHMyWzJdXS5zb21lKHBhdGNoLnRlc3QuYmluZChwYXRjaCkpKSB7XG4gICAgICAgICAgICByZXR1cm4gcGF0Y2gudGVzdChzMVsyXSkgPyAtMSA6IDE7XG4gICAgICAgIH1cblxuICAgICAgICByZXR1cm4gMDtcbiAgICB9O1xuXG59KSk7XG4iLCIvLyBodHRwczovL2QzanMub3JnL2QzLXNlbGVjdGlvbi8gVmVyc2lvbiAxLjMuMC4gQ29weXJpZ2h0IDIwMTggTWlrZSBCb3N0b2NrLlxuKGZ1bmN0aW9uIChnbG9iYWwsIGZhY3RvcnkpIHtcblx0dHlwZW9mIGV4cG9ydHMgPT09ICdvYmplY3QnICYmIHR5cGVvZiBtb2R1bGUgIT09ICd1bmRlZmluZWQnID8gZmFjdG9yeShleHBvcnRzKSA6XG5cdHR5cGVvZiBkZWZpbmUgPT09ICdmdW5jdGlvbicgJiYgZGVmaW5lLmFtZCA/IGRlZmluZShbJ2V4cG9ydHMnXSwgZmFjdG9yeSkgOlxuXHQoZmFjdG9yeSgoZ2xvYmFsLmQzID0gZ2xvYmFsLmQzIHx8IHt9KSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG52YXIgeGh0bWwgPSBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGh0bWxcIjtcblxudmFyIG5hbWVzcGFjZXMgPSB7XG4gIHN2ZzogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLFxuICB4aHRtbDogeGh0bWwsXG4gIHhsaW5rOiBcImh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmtcIixcbiAgeG1sOiBcImh0dHA6Ly93d3cudzMub3JnL1hNTC8xOTk4L25hbWVzcGFjZVwiLFxuICB4bWxuczogXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3htbG5zL1wiXG59O1xuXG5mdW5jdGlvbiBuYW1lc3BhY2UobmFtZSkge1xuICB2YXIgcHJlZml4ID0gbmFtZSArPSBcIlwiLCBpID0gcHJlZml4LmluZGV4T2YoXCI6XCIpO1xuICBpZiAoaSA+PSAwICYmIChwcmVmaXggPSBuYW1lLnNsaWNlKDAsIGkpKSAhPT0gXCJ4bWxuc1wiKSBuYW1lID0gbmFtZS5zbGljZShpICsgMSk7XG4gIHJldHVybiBuYW1lc3BhY2VzLmhhc093blByb3BlcnR5KHByZWZpeCkgPyB7c3BhY2U6IG5hbWVzcGFjZXNbcHJlZml4XSwgbG9jYWw6IG5hbWV9IDogbmFtZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRvckluaGVyaXQobmFtZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRvY3VtZW50ID0gdGhpcy5vd25lckRvY3VtZW50LFxuICAgICAgICB1cmkgPSB0aGlzLm5hbWVzcGFjZVVSSTtcbiAgICByZXR1cm4gdXJpID09PSB4aHRtbCAmJiBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQubmFtZXNwYWNlVVJJID09PSB4aHRtbFxuICAgICAgICA/IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQobmFtZSlcbiAgICAgICAgOiBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlModXJpLCBuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY3JlYXRvckZpeGVkKGZ1bGxuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5vd25lckRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjcmVhdG9yKG5hbWUpIHtcbiAgdmFyIGZ1bGxuYW1lID0gbmFtZXNwYWNlKG5hbWUpO1xuICByZXR1cm4gKGZ1bGxuYW1lLmxvY2FsXG4gICAgICA/IGNyZWF0b3JGaXhlZFxuICAgICAgOiBjcmVhdG9ySW5oZXJpdCkoZnVsbG5hbWUpO1xufVxuXG5mdW5jdGlvbiBub25lKCkge31cblxuZnVuY3Rpb24gc2VsZWN0b3Ioc2VsZWN0b3IpIHtcbiAgcmV0dXJuIHNlbGVjdG9yID09IG51bGwgPyBub25lIDogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMucXVlcnlTZWxlY3RvcihzZWxlY3Rvcik7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9zZWxlY3Qoc2VsZWN0KSB7XG4gIGlmICh0eXBlb2Ygc2VsZWN0ICE9PSBcImZ1bmN0aW9uXCIpIHNlbGVjdCA9IHNlbGVjdG9yKHNlbGVjdCk7XG5cbiAgZm9yICh2YXIgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzLCBtID0gZ3JvdXBzLmxlbmd0aCwgc3ViZ3JvdXBzID0gbmV3IEFycmF5KG0pLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBzdWJncm91cCA9IHN1Ymdyb3Vwc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgc3Vibm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiAoc3Vibm9kZSA9IHNlbGVjdC5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSkpIHtcbiAgICAgICAgaWYgKFwiX19kYXRhX19cIiBpbiBub2RlKSBzdWJub2RlLl9fZGF0YV9fID0gbm9kZS5fX2RhdGFfXztcbiAgICAgICAgc3ViZ3JvdXBbaV0gPSBzdWJub2RlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59XG5cbmZ1bmN0aW9uIGVtcHR5KCkge1xuICByZXR1cm4gW107XG59XG5cbmZ1bmN0aW9uIHNlbGVjdG9yQWxsKHNlbGVjdG9yKSB7XG4gIHJldHVybiBzZWxlY3RvciA9PSBudWxsID8gZW1wdHkgOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX3NlbGVjdEFsbChzZWxlY3QpIHtcbiAgaWYgKHR5cGVvZiBzZWxlY3QgIT09IFwiZnVuY3Rpb25cIikgc2VsZWN0ID0gc2VsZWN0b3JBbGwoc2VsZWN0KTtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIG0gPSBncm91cHMubGVuZ3RoLCBzdWJncm91cHMgPSBbXSwgcGFyZW50cyA9IFtdLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlLCBpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBzdWJncm91cHMucHVzaChzZWxlY3QuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCkpO1xuICAgICAgICBwYXJlbnRzLnB1c2gobm9kZSk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG5ldyBTZWxlY3Rpb24oc3ViZ3JvdXBzLCBwYXJlbnRzKTtcbn1cblxudmFyIG1hdGNoZXIgPSBmdW5jdGlvbihzZWxlY3Rvcikge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMubWF0Y2hlcyhzZWxlY3Rvcik7XG4gIH07XG59O1xuXG5pZiAodHlwZW9mIGRvY3VtZW50ICE9PSBcInVuZGVmaW5lZFwiKSB7XG4gIHZhciBlbGVtZW50ID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICBpZiAoIWVsZW1lbnQubWF0Y2hlcykge1xuICAgIHZhciB2ZW5kb3JNYXRjaGVzID0gZWxlbWVudC53ZWJraXRNYXRjaGVzU2VsZWN0b3JcbiAgICAgICAgfHwgZWxlbWVudC5tc01hdGNoZXNTZWxlY3RvclxuICAgICAgICB8fCBlbGVtZW50Lm1vek1hdGNoZXNTZWxlY3RvclxuICAgICAgICB8fCBlbGVtZW50Lm9NYXRjaGVzU2VsZWN0b3I7XG4gICAgbWF0Y2hlciA9IGZ1bmN0aW9uKHNlbGVjdG9yKSB7XG4gICAgICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiB2ZW5kb3JNYXRjaGVzLmNhbGwodGhpcywgc2VsZWN0b3IpO1xuICAgICAgfTtcbiAgICB9O1xuICB9XG59XG5cbnZhciBtYXRjaGVyJDEgPSBtYXRjaGVyO1xuXG5mdW5jdGlvbiBzZWxlY3Rpb25fZmlsdGVyKG1hdGNoKSB7XG4gIGlmICh0eXBlb2YgbWF0Y2ggIT09IFwiZnVuY3Rpb25cIikgbWF0Y2ggPSBtYXRjaGVyJDEobWF0Y2gpO1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHN1Ymdyb3VwcyA9IG5ldyBBcnJheShtKSwgaiA9IDA7IGogPCBtOyArK2opIHtcbiAgICBmb3IgKHZhciBncm91cCA9IGdyb3Vwc1tqXSwgbiA9IGdyb3VwLmxlbmd0aCwgc3ViZ3JvdXAgPSBzdWJncm91cHNbal0gPSBbXSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmICgobm9kZSA9IGdyb3VwW2ldKSAmJiBtYXRjaC5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKSkge1xuICAgICAgICBzdWJncm91cC5wdXNoKG5vZGUpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHN1Ymdyb3VwcywgdGhpcy5fcGFyZW50cyk7XG59XG5cbmZ1bmN0aW9uIHNwYXJzZSh1cGRhdGUpIHtcbiAgcmV0dXJuIG5ldyBBcnJheSh1cGRhdGUubGVuZ3RoKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2VudGVyKCkge1xuICByZXR1cm4gbmV3IFNlbGVjdGlvbih0aGlzLl9lbnRlciB8fCB0aGlzLl9ncm91cHMubWFwKHNwYXJzZSksIHRoaXMuX3BhcmVudHMpO1xufVxuXG5mdW5jdGlvbiBFbnRlck5vZGUocGFyZW50LCBkYXR1bSkge1xuICB0aGlzLm93bmVyRG9jdW1lbnQgPSBwYXJlbnQub3duZXJEb2N1bWVudDtcbiAgdGhpcy5uYW1lc3BhY2VVUkkgPSBwYXJlbnQubmFtZXNwYWNlVVJJO1xuICB0aGlzLl9uZXh0ID0gbnVsbDtcbiAgdGhpcy5fcGFyZW50ID0gcGFyZW50O1xuICB0aGlzLl9fZGF0YV9fID0gZGF0dW07XG59XG5cbkVudGVyTm9kZS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBFbnRlck5vZGUsXG4gIGFwcGVuZENoaWxkOiBmdW5jdGlvbihjaGlsZCkgeyByZXR1cm4gdGhpcy5fcGFyZW50Lmluc2VydEJlZm9yZShjaGlsZCwgdGhpcy5fbmV4dCk7IH0sXG4gIGluc2VydEJlZm9yZTogZnVuY3Rpb24oY2hpbGQsIG5leHQpIHsgcmV0dXJuIHRoaXMuX3BhcmVudC5pbnNlcnRCZWZvcmUoY2hpbGQsIG5leHQpOyB9LFxuICBxdWVyeVNlbGVjdG9yOiBmdW5jdGlvbihzZWxlY3RvcikgeyByZXR1cm4gdGhpcy5fcGFyZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpOyB9LFxuICBxdWVyeVNlbGVjdG9yQWxsOiBmdW5jdGlvbihzZWxlY3RvcikgeyByZXR1cm4gdGhpcy5fcGFyZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc2VsZWN0b3IpOyB9XG59O1xuXG5mdW5jdGlvbiBjb25zdGFudCh4KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn1cblxudmFyIGtleVByZWZpeCA9IFwiJFwiOyAvLyBQcm90ZWN0IGFnYWluc3Qga2V5cyBsaWtlIOKAnF9fcHJvdG9fX+KAnS5cblxuZnVuY3Rpb24gYmluZEluZGV4KHBhcmVudCwgZ3JvdXAsIGVudGVyLCB1cGRhdGUsIGV4aXQsIGRhdGEpIHtcbiAgdmFyIGkgPSAwLFxuICAgICAgbm9kZSxcbiAgICAgIGdyb3VwTGVuZ3RoID0gZ3JvdXAubGVuZ3RoLFxuICAgICAgZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoO1xuXG4gIC8vIFB1dCBhbnkgbm9uLW51bGwgbm9kZXMgdGhhdCBmaXQgaW50byB1cGRhdGUuXG4gIC8vIFB1dCBhbnkgbnVsbCBub2RlcyBpbnRvIGVudGVyLlxuICAvLyBQdXQgYW55IHJlbWFpbmluZyBkYXRhIGludG8gZW50ZXIuXG4gIGZvciAoOyBpIDwgZGF0YUxlbmd0aDsgKytpKSB7XG4gICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgbm9kZS5fX2RhdGFfXyA9IGRhdGFbaV07XG4gICAgICB1cGRhdGVbaV0gPSBub2RlO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRlcltpXSA9IG5ldyBFbnRlck5vZGUocGFyZW50LCBkYXRhW2ldKTtcbiAgICB9XG4gIH1cblxuICAvLyBQdXQgYW55IG5vbi1udWxsIG5vZGVzIHRoYXQgZG9u4oCZdCBmaXQgaW50byBleGl0LlxuICBmb3IgKDsgaSA8IGdyb3VwTGVuZ3RoOyArK2kpIHtcbiAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICBleGl0W2ldID0gbm9kZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gYmluZEtleShwYXJlbnQsIGdyb3VwLCBlbnRlciwgdXBkYXRlLCBleGl0LCBkYXRhLCBrZXkpIHtcbiAgdmFyIGksXG4gICAgICBub2RlLFxuICAgICAgbm9kZUJ5S2V5VmFsdWUgPSB7fSxcbiAgICAgIGdyb3VwTGVuZ3RoID0gZ3JvdXAubGVuZ3RoLFxuICAgICAgZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoLFxuICAgICAga2V5VmFsdWVzID0gbmV3IEFycmF5KGdyb3VwTGVuZ3RoKSxcbiAgICAgIGtleVZhbHVlO1xuXG4gIC8vIENvbXB1dGUgdGhlIGtleSBmb3IgZWFjaCBub2RlLlxuICAvLyBJZiBtdWx0aXBsZSBub2RlcyBoYXZlIHRoZSBzYW1lIGtleSwgdGhlIGR1cGxpY2F0ZXMgYXJlIGFkZGVkIHRvIGV4aXQuXG4gIGZvciAoaSA9IDA7IGkgPCBncm91cExlbmd0aDsgKytpKSB7XG4gICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAga2V5VmFsdWVzW2ldID0ga2V5VmFsdWUgPSBrZXlQcmVmaXggKyBrZXkuY2FsbChub2RlLCBub2RlLl9fZGF0YV9fLCBpLCBncm91cCk7XG4gICAgICBpZiAoa2V5VmFsdWUgaW4gbm9kZUJ5S2V5VmFsdWUpIHtcbiAgICAgICAgZXhpdFtpXSA9IG5vZGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlQnlLZXlWYWx1ZVtrZXlWYWx1ZV0gPSBub2RlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIENvbXB1dGUgdGhlIGtleSBmb3IgZWFjaCBkYXR1bS5cbiAgLy8gSWYgdGhlcmUgYSBub2RlIGFzc29jaWF0ZWQgd2l0aCB0aGlzIGtleSwgam9pbiBhbmQgYWRkIGl0IHRvIHVwZGF0ZS5cbiAgLy8gSWYgdGhlcmUgaXMgbm90IChvciB0aGUga2V5IGlzIGEgZHVwbGljYXRlKSwgYWRkIGl0IHRvIGVudGVyLlxuICBmb3IgKGkgPSAwOyBpIDwgZGF0YUxlbmd0aDsgKytpKSB7XG4gICAga2V5VmFsdWUgPSBrZXlQcmVmaXggKyBrZXkuY2FsbChwYXJlbnQsIGRhdGFbaV0sIGksIGRhdGEpO1xuICAgIGlmIChub2RlID0gbm9kZUJ5S2V5VmFsdWVba2V5VmFsdWVdKSB7XG4gICAgICB1cGRhdGVbaV0gPSBub2RlO1xuICAgICAgbm9kZS5fX2RhdGFfXyA9IGRhdGFbaV07XG4gICAgICBub2RlQnlLZXlWYWx1ZVtrZXlWYWx1ZV0gPSBudWxsO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRlcltpXSA9IG5ldyBFbnRlck5vZGUocGFyZW50LCBkYXRhW2ldKTtcbiAgICB9XG4gIH1cblxuICAvLyBBZGQgYW55IHJlbWFpbmluZyBub2RlcyB0aGF0IHdlcmUgbm90IGJvdW5kIHRvIGRhdGEgdG8gZXhpdC5cbiAgZm9yIChpID0gMDsgaSA8IGdyb3VwTGVuZ3RoOyArK2kpIHtcbiAgICBpZiAoKG5vZGUgPSBncm91cFtpXSkgJiYgKG5vZGVCeUtleVZhbHVlW2tleVZhbHVlc1tpXV0gPT09IG5vZGUpKSB7XG4gICAgICBleGl0W2ldID0gbm9kZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2RhdGEodmFsdWUsIGtleSkge1xuICBpZiAoIXZhbHVlKSB7XG4gICAgZGF0YSA9IG5ldyBBcnJheSh0aGlzLnNpemUoKSksIGogPSAtMTtcbiAgICB0aGlzLmVhY2goZnVuY3Rpb24oZCkgeyBkYXRhWysral0gPSBkOyB9KTtcbiAgICByZXR1cm4gZGF0YTtcbiAgfVxuXG4gIHZhciBiaW5kID0ga2V5ID8gYmluZEtleSA6IGJpbmRJbmRleCxcbiAgICAgIHBhcmVudHMgPSB0aGlzLl9wYXJlbnRzLFxuICAgICAgZ3JvdXBzID0gdGhpcy5fZ3JvdXBzO1xuXG4gIGlmICh0eXBlb2YgdmFsdWUgIT09IFwiZnVuY3Rpb25cIikgdmFsdWUgPSBjb25zdGFudCh2YWx1ZSk7XG5cbiAgZm9yICh2YXIgbSA9IGdyb3Vwcy5sZW5ndGgsIHVwZGF0ZSA9IG5ldyBBcnJheShtKSwgZW50ZXIgPSBuZXcgQXJyYXkobSksIGV4aXQgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgdmFyIHBhcmVudCA9IHBhcmVudHNbal0sXG4gICAgICAgIGdyb3VwID0gZ3JvdXBzW2pdLFxuICAgICAgICBncm91cExlbmd0aCA9IGdyb3VwLmxlbmd0aCxcbiAgICAgICAgZGF0YSA9IHZhbHVlLmNhbGwocGFyZW50LCBwYXJlbnQgJiYgcGFyZW50Ll9fZGF0YV9fLCBqLCBwYXJlbnRzKSxcbiAgICAgICAgZGF0YUxlbmd0aCA9IGRhdGEubGVuZ3RoLFxuICAgICAgICBlbnRlckdyb3VwID0gZW50ZXJbal0gPSBuZXcgQXJyYXkoZGF0YUxlbmd0aCksXG4gICAgICAgIHVwZGF0ZUdyb3VwID0gdXBkYXRlW2pdID0gbmV3IEFycmF5KGRhdGFMZW5ndGgpLFxuICAgICAgICBleGl0R3JvdXAgPSBleGl0W2pdID0gbmV3IEFycmF5KGdyb3VwTGVuZ3RoKTtcblxuICAgIGJpbmQocGFyZW50LCBncm91cCwgZW50ZXJHcm91cCwgdXBkYXRlR3JvdXAsIGV4aXRHcm91cCwgZGF0YSwga2V5KTtcblxuICAgIC8vIE5vdyBjb25uZWN0IHRoZSBlbnRlciBub2RlcyB0byB0aGVpciBmb2xsb3dpbmcgdXBkYXRlIG5vZGUsIHN1Y2ggdGhhdFxuICAgIC8vIGFwcGVuZENoaWxkIGNhbiBpbnNlcnQgdGhlIG1hdGVyaWFsaXplZCBlbnRlciBub2RlIGJlZm9yZSB0aGlzIG5vZGUsXG4gICAgLy8gcmF0aGVyIHRoYW4gYXQgdGhlIGVuZCBvZiB0aGUgcGFyZW50IG5vZGUuXG4gICAgZm9yICh2YXIgaTAgPSAwLCBpMSA9IDAsIHByZXZpb3VzLCBuZXh0OyBpMCA8IGRhdGFMZW5ndGg7ICsraTApIHtcbiAgICAgIGlmIChwcmV2aW91cyA9IGVudGVyR3JvdXBbaTBdKSB7XG4gICAgICAgIGlmIChpMCA+PSBpMSkgaTEgPSBpMCArIDE7XG4gICAgICAgIHdoaWxlICghKG5leHQgPSB1cGRhdGVHcm91cFtpMV0pICYmICsraTEgPCBkYXRhTGVuZ3RoKTtcbiAgICAgICAgcHJldmlvdXMuX25leHQgPSBuZXh0IHx8IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgdXBkYXRlID0gbmV3IFNlbGVjdGlvbih1cGRhdGUsIHBhcmVudHMpO1xuICB1cGRhdGUuX2VudGVyID0gZW50ZXI7XG4gIHVwZGF0ZS5fZXhpdCA9IGV4aXQ7XG4gIHJldHVybiB1cGRhdGU7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9leGl0KCkge1xuICByZXR1cm4gbmV3IFNlbGVjdGlvbih0aGlzLl9leGl0IHx8IHRoaXMuX2dyb3Vwcy5tYXAoc3BhcnNlKSwgdGhpcy5fcGFyZW50cyk7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9tZXJnZShzZWxlY3Rpb24kJDEpIHtcblxuICBmb3IgKHZhciBncm91cHMwID0gdGhpcy5fZ3JvdXBzLCBncm91cHMxID0gc2VsZWN0aW9uJCQxLl9ncm91cHMsIG0wID0gZ3JvdXBzMC5sZW5ndGgsIG0xID0gZ3JvdXBzMS5sZW5ndGgsIG0gPSBNYXRoLm1pbihtMCwgbTEpLCBtZXJnZXMgPSBuZXcgQXJyYXkobTApLCBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwMCA9IGdyb3VwczBbal0sIGdyb3VwMSA9IGdyb3VwczFbal0sIG4gPSBncm91cDAubGVuZ3RoLCBtZXJnZSA9IG1lcmdlc1tqXSA9IG5ldyBBcnJheShuKSwgbm9kZSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIGlmIChub2RlID0gZ3JvdXAwW2ldIHx8IGdyb3VwMVtpXSkge1xuICAgICAgICBtZXJnZVtpXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZm9yICg7IGogPCBtMDsgKytqKSB7XG4gICAgbWVyZ2VzW2pdID0gZ3JvdXBzMFtqXTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKG1lcmdlcywgdGhpcy5fcGFyZW50cyk7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9vcmRlcigpIHtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIGogPSAtMSwgbSA9IGdyb3Vwcy5sZW5ndGg7ICsraiA8IG07KSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSBncm91cC5sZW5ndGggLSAxLCBuZXh0ID0gZ3JvdXBbaV0sIG5vZGU7IC0taSA+PSAwOykge1xuICAgICAgaWYgKG5vZGUgPSBncm91cFtpXSkge1xuICAgICAgICBpZiAobmV4dCAmJiBuZXh0ICE9PSBub2RlLm5leHRTaWJsaW5nKSBuZXh0LnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKG5vZGUsIG5leHQpO1xuICAgICAgICBuZXh0ID0gbm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX3NvcnQoY29tcGFyZSkge1xuICBpZiAoIWNvbXBhcmUpIGNvbXBhcmUgPSBhc2NlbmRpbmc7XG5cbiAgZnVuY3Rpb24gY29tcGFyZU5vZGUoYSwgYikge1xuICAgIHJldHVybiBhICYmIGIgPyBjb21wYXJlKGEuX19kYXRhX18sIGIuX19kYXRhX18pIDogIWEgLSAhYjtcbiAgfVxuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgbSA9IGdyb3Vwcy5sZW5ndGgsIHNvcnRncm91cHMgPSBuZXcgQXJyYXkobSksIGogPSAwOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIG4gPSBncm91cC5sZW5ndGgsIHNvcnRncm91cCA9IHNvcnRncm91cHNbal0gPSBuZXcgQXJyYXkobiksIG5vZGUsIGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSB7XG4gICAgICAgIHNvcnRncm91cFtpXSA9IG5vZGU7XG4gICAgICB9XG4gICAgfVxuICAgIHNvcnRncm91cC5zb3J0KGNvbXBhcmVOb2RlKTtcbiAgfVxuXG4gIHJldHVybiBuZXcgU2VsZWN0aW9uKHNvcnRncm91cHMsIHRoaXMuX3BhcmVudHMpLm9yZGVyKCk7XG59XG5cbmZ1bmN0aW9uIGFzY2VuZGluZyhhLCBiKSB7XG4gIHJldHVybiBhIDwgYiA/IC0xIDogYSA+IGIgPyAxIDogYSA+PSBiID8gMCA6IE5hTjtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2NhbGwoKSB7XG4gIHZhciBjYWxsYmFjayA9IGFyZ3VtZW50c1swXTtcbiAgYXJndW1lbnRzWzBdID0gdGhpcztcbiAgY2FsbGJhY2suYXBwbHkobnVsbCwgYXJndW1lbnRzKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9ub2RlcygpIHtcbiAgdmFyIG5vZGVzID0gbmV3IEFycmF5KHRoaXMuc2l6ZSgpKSwgaSA9IC0xO1xuICB0aGlzLmVhY2goZnVuY3Rpb24oKSB7IG5vZGVzWysraV0gPSB0aGlzOyB9KTtcbiAgcmV0dXJuIG5vZGVzO1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fbm9kZSgpIHtcblxuICBmb3IgKHZhciBncm91cHMgPSB0aGlzLl9ncm91cHMsIGogPSAwLCBtID0gZ3JvdXBzLmxlbmd0aDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGdyb3VwID0gZ3JvdXBzW2pdLCBpID0gMCwgbiA9IGdyb3VwLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgdmFyIG5vZGUgPSBncm91cFtpXTtcbiAgICAgIGlmIChub2RlKSByZXR1cm4gbm9kZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX3NpemUoKSB7XG4gIHZhciBzaXplID0gMDtcbiAgdGhpcy5lYWNoKGZ1bmN0aW9uKCkgeyArK3NpemU7IH0pO1xuICByZXR1cm4gc2l6ZTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2VtcHR5KCkge1xuICByZXR1cm4gIXRoaXMubm9kZSgpO1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fZWFjaChjYWxsYmFjaykge1xuXG4gIGZvciAodmFyIGdyb3VwcyA9IHRoaXMuX2dyb3VwcywgaiA9IDAsIG0gPSBncm91cHMubGVuZ3RoOyBqIDwgbTsgKytqKSB7XG4gICAgZm9yICh2YXIgZ3JvdXAgPSBncm91cHNbal0sIGkgPSAwLCBuID0gZ3JvdXAubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBpZiAobm9kZSA9IGdyb3VwW2ldKSBjYWxsYmFjay5jYWxsKG5vZGUsIG5vZGUuX19kYXRhX18sIGksIGdyb3VwKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxuZnVuY3Rpb24gYXR0clJlbW92ZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnJlbW92ZUF0dHJpYnV0ZShuYW1lKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gYXR0clJlbW92ZU5TKGZ1bGxuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnJlbW92ZUF0dHJpYnV0ZU5TKGZ1bGxuYW1lLnNwYWNlLCBmdWxsbmFtZS5sb2NhbCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJDb25zdGFudChuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5zZXRBdHRyaWJ1dGUobmFtZSwgdmFsdWUpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBhdHRyQ29uc3RhbnROUyhmdWxsbmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuc2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsLCB2YWx1ZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJGdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIHRoaXMucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIGVsc2UgdGhpcy5zZXRBdHRyaWJ1dGUobmFtZSwgdik7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGF0dHJGdW5jdGlvbk5TKGZ1bGxuYW1lLCB2YWx1ZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgdmFyIHYgPSB2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICAgIGlmICh2ID09IG51bGwpIHRoaXMucmVtb3ZlQXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsKTtcbiAgICBlbHNlIHRoaXMuc2V0QXR0cmlidXRlTlMoZnVsbG5hbWUuc3BhY2UsIGZ1bGxuYW1lLmxvY2FsLCB2KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2F0dHIobmFtZSwgdmFsdWUpIHtcbiAgdmFyIGZ1bGxuYW1lID0gbmFtZXNwYWNlKG5hbWUpO1xuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgIHZhciBub2RlID0gdGhpcy5ub2RlKCk7XG4gICAgcmV0dXJuIGZ1bGxuYW1lLmxvY2FsXG4gICAgICAgID8gbm9kZS5nZXRBdHRyaWJ1dGVOUyhmdWxsbmFtZS5zcGFjZSwgZnVsbG5hbWUubG9jYWwpXG4gICAgICAgIDogbm9kZS5nZXRBdHRyaWJ1dGUoZnVsbG5hbWUpO1xuICB9XG5cbiAgcmV0dXJuIHRoaXMuZWFjaCgodmFsdWUgPT0gbnVsbFxuICAgICAgPyAoZnVsbG5hbWUubG9jYWwgPyBhdHRyUmVtb3ZlTlMgOiBhdHRyUmVtb3ZlKSA6ICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgPyAoZnVsbG5hbWUubG9jYWwgPyBhdHRyRnVuY3Rpb25OUyA6IGF0dHJGdW5jdGlvbilcbiAgICAgIDogKGZ1bGxuYW1lLmxvY2FsID8gYXR0ckNvbnN0YW50TlMgOiBhdHRyQ29uc3RhbnQpKSkoZnVsbG5hbWUsIHZhbHVlKSk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRWaWV3KG5vZGUpIHtcbiAgcmV0dXJuIChub2RlLm93bmVyRG9jdW1lbnQgJiYgbm9kZS5vd25lckRvY3VtZW50LmRlZmF1bHRWaWV3KSAvLyBub2RlIGlzIGEgTm9kZVxuICAgICAgfHwgKG5vZGUuZG9jdW1lbnQgJiYgbm9kZSkgLy8gbm9kZSBpcyBhIFdpbmRvd1xuICAgICAgfHwgbm9kZS5kZWZhdWx0VmlldzsgLy8gbm9kZSBpcyBhIERvY3VtZW50XG59XG5cbmZ1bmN0aW9uIHN0eWxlUmVtb3ZlKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuc3R5bGUucmVtb3ZlUHJvcGVydHkobmFtZSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0eWxlQ29uc3RhbnQobmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlLCBwcmlvcml0eSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHN0eWxlRnVuY3Rpb24obmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgaWYgKHYgPT0gbnVsbCkgdGhpcy5zdHlsZS5yZW1vdmVQcm9wZXJ0eShuYW1lKTtcbiAgICBlbHNlIHRoaXMuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgdiwgcHJpb3JpdHkpO1xuICB9O1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fc3R5bGUobmFtZSwgdmFsdWUsIHByaW9yaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMVxuICAgICAgPyB0aGlzLmVhY2goKHZhbHVlID09IG51bGxcbiAgICAgICAgICAgID8gc3R5bGVSZW1vdmUgOiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgICAgPyBzdHlsZUZ1bmN0aW9uXG4gICAgICAgICAgICA6IHN0eWxlQ29uc3RhbnQpKG5hbWUsIHZhbHVlLCBwcmlvcml0eSA9PSBudWxsID8gXCJcIiA6IHByaW9yaXR5KSlcbiAgICAgIDogc3R5bGVWYWx1ZSh0aGlzLm5vZGUoKSwgbmFtZSk7XG59XG5cbmZ1bmN0aW9uIHN0eWxlVmFsdWUobm9kZSwgbmFtZSkge1xuICByZXR1cm4gbm9kZS5zdHlsZS5nZXRQcm9wZXJ0eVZhbHVlKG5hbWUpXG4gICAgICB8fCBkZWZhdWx0Vmlldyhub2RlKS5nZXRDb21wdXRlZFN0eWxlKG5vZGUsIG51bGwpLmdldFByb3BlcnR5VmFsdWUobmFtZSk7XG59XG5cbmZ1bmN0aW9uIHByb3BlcnR5UmVtb3ZlKG5hbWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIGRlbGV0ZSB0aGlzW25hbWVdO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9wZXJ0eUNvbnN0YW50KG5hbWUsIHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzW25hbWVdID0gdmFsdWU7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHByb3BlcnR5RnVuY3Rpb24obmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBpZiAodiA9PSBudWxsKSBkZWxldGUgdGhpc1tuYW1lXTtcbiAgICBlbHNlIHRoaXNbbmFtZV0gPSB2O1xuICB9O1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fcHJvcGVydHkobmFtZSwgdmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPiAxXG4gICAgICA/IHRoaXMuZWFjaCgodmFsdWUgPT0gbnVsbFxuICAgICAgICAgID8gcHJvcGVydHlSZW1vdmUgOiB0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gcHJvcGVydHlGdW5jdGlvblxuICAgICAgICAgIDogcHJvcGVydHlDb25zdGFudCkobmFtZSwgdmFsdWUpKVxuICAgICAgOiB0aGlzLm5vZGUoKVtuYW1lXTtcbn1cblxuZnVuY3Rpb24gY2xhc3NBcnJheShzdHJpbmcpIHtcbiAgcmV0dXJuIHN0cmluZy50cmltKCkuc3BsaXQoL158XFxzKy8pO1xufVxuXG5mdW5jdGlvbiBjbGFzc0xpc3Qobm9kZSkge1xuICByZXR1cm4gbm9kZS5jbGFzc0xpc3QgfHwgbmV3IENsYXNzTGlzdChub2RlKTtcbn1cblxuZnVuY3Rpb24gQ2xhc3NMaXN0KG5vZGUpIHtcbiAgdGhpcy5fbm9kZSA9IG5vZGU7XG4gIHRoaXMuX25hbWVzID0gY2xhc3NBcnJheShub2RlLmdldEF0dHJpYnV0ZShcImNsYXNzXCIpIHx8IFwiXCIpO1xufVxuXG5DbGFzc0xpc3QucHJvdG90eXBlID0ge1xuICBhZGQ6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgaSA9IHRoaXMuX25hbWVzLmluZGV4T2YobmFtZSk7XG4gICAgaWYgKGkgPCAwKSB7XG4gICAgICB0aGlzLl9uYW1lcy5wdXNoKG5hbWUpO1xuICAgICAgdGhpcy5fbm9kZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCB0aGlzLl9uYW1lcy5qb2luKFwiIFwiKSk7XG4gICAgfVxuICB9LFxuICByZW1vdmU6IGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgaSA9IHRoaXMuX25hbWVzLmluZGV4T2YobmFtZSk7XG4gICAgaWYgKGkgPj0gMCkge1xuICAgICAgdGhpcy5fbmFtZXMuc3BsaWNlKGksIDEpO1xuICAgICAgdGhpcy5fbm9kZS5zZXRBdHRyaWJ1dGUoXCJjbGFzc1wiLCB0aGlzLl9uYW1lcy5qb2luKFwiIFwiKSk7XG4gICAgfVxuICB9LFxuICBjb250YWluczogZnVuY3Rpb24obmFtZSkge1xuICAgIHJldHVybiB0aGlzLl9uYW1lcy5pbmRleE9mKG5hbWUpID49IDA7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNsYXNzZWRBZGQobm9kZSwgbmFtZXMpIHtcbiAgdmFyIGxpc3QgPSBjbGFzc0xpc3Qobm9kZSksIGkgPSAtMSwgbiA9IG5hbWVzLmxlbmd0aDtcbiAgd2hpbGUgKCsraSA8IG4pIGxpc3QuYWRkKG5hbWVzW2ldKTtcbn1cblxuZnVuY3Rpb24gY2xhc3NlZFJlbW92ZShub2RlLCBuYW1lcykge1xuICB2YXIgbGlzdCA9IGNsYXNzTGlzdChub2RlKSwgaSA9IC0xLCBuID0gbmFtZXMubGVuZ3RoO1xuICB3aGlsZSAoKytpIDwgbikgbGlzdC5yZW1vdmUobmFtZXNbaV0pO1xufVxuXG5mdW5jdGlvbiBjbGFzc2VkVHJ1ZShuYW1lcykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgY2xhc3NlZEFkZCh0aGlzLCBuYW1lcyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRGYWxzZShuYW1lcykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgY2xhc3NlZFJlbW92ZSh0aGlzLCBuYW1lcyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsYXNzZWRGdW5jdGlvbihuYW1lcywgdmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgICh2YWx1ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpID8gY2xhc3NlZEFkZCA6IGNsYXNzZWRSZW1vdmUpKHRoaXMsIG5hbWVzKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2NsYXNzZWQobmFtZSwgdmFsdWUpIHtcbiAgdmFyIG5hbWVzID0gY2xhc3NBcnJheShuYW1lICsgXCJcIik7XG5cbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPCAyKSB7XG4gICAgdmFyIGxpc3QgPSBjbGFzc0xpc3QodGhpcy5ub2RlKCkpLCBpID0gLTEsIG4gPSBuYW1lcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghbGlzdC5jb250YWlucyhuYW1lc1tpXSkpIHJldHVybiBmYWxzZTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmVhY2goKHR5cGVvZiB2YWx1ZSA9PT0gXCJmdW5jdGlvblwiXG4gICAgICA/IGNsYXNzZWRGdW5jdGlvbiA6IHZhbHVlXG4gICAgICA/IGNsYXNzZWRUcnVlXG4gICAgICA6IGNsYXNzZWRGYWxzZSkobmFtZXMsIHZhbHVlKSk7XG59XG5cbmZ1bmN0aW9uIHRleHRSZW1vdmUoKSB7XG4gIHRoaXMudGV4dENvbnRlbnQgPSBcIlwiO1xufVxuXG5mdW5jdGlvbiB0ZXh0Q29uc3RhbnQodmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHRoaXMudGV4dENvbnRlbnQgPSB2YWx1ZTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gdGV4dEZ1bmN0aW9uKHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgdiA9IHZhbHVlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG4gICAgdGhpcy50ZXh0Q29udGVudCA9IHYgPT0gbnVsbCA/IFwiXCIgOiB2O1xuICB9O1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fdGV4dCh2YWx1ZSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmVhY2godmFsdWUgPT0gbnVsbFxuICAgICAgICAgID8gdGV4dFJlbW92ZSA6ICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gdGV4dEZ1bmN0aW9uXG4gICAgICAgICAgOiB0ZXh0Q29uc3RhbnQpKHZhbHVlKSlcbiAgICAgIDogdGhpcy5ub2RlKCkudGV4dENvbnRlbnQ7XG59XG5cbmZ1bmN0aW9uIGh0bWxSZW1vdmUoKSB7XG4gIHRoaXMuaW5uZXJIVE1MID0gXCJcIjtcbn1cblxuZnVuY3Rpb24gaHRtbENvbnN0YW50KHZhbHVlKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLmlubmVySFRNTCA9IHZhbHVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiBodG1sRnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHZhciB2ID0gdmFsdWUuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICB0aGlzLmlubmVySFRNTCA9IHYgPT0gbnVsbCA/IFwiXCIgOiB2O1xuICB9O1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25faHRtbCh2YWx1ZSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmVhY2godmFsdWUgPT0gbnVsbFxuICAgICAgICAgID8gaHRtbFJlbW92ZSA6ICh0eXBlb2YgdmFsdWUgPT09IFwiZnVuY3Rpb25cIlxuICAgICAgICAgID8gaHRtbEZ1bmN0aW9uXG4gICAgICAgICAgOiBodG1sQ29uc3RhbnQpKHZhbHVlKSlcbiAgICAgIDogdGhpcy5ub2RlKCkuaW5uZXJIVE1MO1xufVxuXG5mdW5jdGlvbiByYWlzZSgpIHtcbiAgaWYgKHRoaXMubmV4dFNpYmxpbmcpIHRoaXMucGFyZW50Tm9kZS5hcHBlbmRDaGlsZCh0aGlzKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX3JhaXNlKCkge1xuICByZXR1cm4gdGhpcy5lYWNoKHJhaXNlKTtcbn1cblxuZnVuY3Rpb24gbG93ZXIoKSB7XG4gIGlmICh0aGlzLnByZXZpb3VzU2libGluZykgdGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLCB0aGlzLnBhcmVudE5vZGUuZmlyc3RDaGlsZCk7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9sb3dlcigpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChsb3dlcik7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9hcHBlbmQobmFtZSkge1xuICB2YXIgY3JlYXRlID0gdHlwZW9mIG5hbWUgPT09IFwiZnVuY3Rpb25cIiA/IG5hbWUgOiBjcmVhdG9yKG5hbWUpO1xuICByZXR1cm4gdGhpcy5zZWxlY3QoZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuYXBwZW5kQ2hpbGQoY3JlYXRlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gY29uc3RhbnROdWxsKCkge1xuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2luc2VydChuYW1lLCBiZWZvcmUpIHtcbiAgdmFyIGNyZWF0ZSA9IHR5cGVvZiBuYW1lID09PSBcImZ1bmN0aW9uXCIgPyBuYW1lIDogY3JlYXRvcihuYW1lKSxcbiAgICAgIHNlbGVjdCA9IGJlZm9yZSA9PSBudWxsID8gY29uc3RhbnROdWxsIDogdHlwZW9mIGJlZm9yZSA9PT0gXCJmdW5jdGlvblwiID8gYmVmb3JlIDogc2VsZWN0b3IoYmVmb3JlKTtcbiAgcmV0dXJuIHRoaXMuc2VsZWN0KGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLmluc2VydEJlZm9yZShjcmVhdGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSwgc2VsZWN0LmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgfHwgbnVsbCk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiByZW1vdmUoKSB7XG4gIHZhciBwYXJlbnQgPSB0aGlzLnBhcmVudE5vZGU7XG4gIGlmIChwYXJlbnQpIHBhcmVudC5yZW1vdmVDaGlsZCh0aGlzKTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX3JlbW92ZSgpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaChyZW1vdmUpO1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fY2xvbmVTaGFsbG93KCkge1xuICByZXR1cm4gdGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmNsb25lTm9kZShmYWxzZSksIHRoaXMubmV4dFNpYmxpbmcpO1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fY2xvbmVEZWVwKCkge1xuICByZXR1cm4gdGhpcy5wYXJlbnROb2RlLmluc2VydEJlZm9yZSh0aGlzLmNsb25lTm9kZSh0cnVlKSwgdGhpcy5uZXh0U2libGluZyk7XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9jbG9uZShkZWVwKSB7XG4gIHJldHVybiB0aGlzLnNlbGVjdChkZWVwID8gc2VsZWN0aW9uX2Nsb25lRGVlcCA6IHNlbGVjdGlvbl9jbG9uZVNoYWxsb3cpO1xufVxuXG5mdW5jdGlvbiBzZWxlY3Rpb25fZGF0dW0odmFsdWUpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGhcbiAgICAgID8gdGhpcy5wcm9wZXJ0eShcIl9fZGF0YV9fXCIsIHZhbHVlKVxuICAgICAgOiB0aGlzLm5vZGUoKS5fX2RhdGFfXztcbn1cblxudmFyIGZpbHRlckV2ZW50cyA9IHt9O1xuXG5leHBvcnRzLmV2ZW50ID0gbnVsbDtcblxuaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gXCJ1bmRlZmluZWRcIikge1xuICB2YXIgZWxlbWVudCQxID0gZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50O1xuICBpZiAoIShcIm9ubW91c2VlbnRlclwiIGluIGVsZW1lbnQkMSkpIHtcbiAgICBmaWx0ZXJFdmVudHMgPSB7bW91c2VlbnRlcjogXCJtb3VzZW92ZXJcIiwgbW91c2VsZWF2ZTogXCJtb3VzZW91dFwifTtcbiAgfVxufVxuXG5mdW5jdGlvbiBmaWx0ZXJDb250ZXh0TGlzdGVuZXIobGlzdGVuZXIsIGluZGV4LCBncm91cCkge1xuICBsaXN0ZW5lciA9IGNvbnRleHRMaXN0ZW5lcihsaXN0ZW5lciwgaW5kZXgsIGdyb3VwKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50KSB7XG4gICAgdmFyIHJlbGF0ZWQgPSBldmVudC5yZWxhdGVkVGFyZ2V0O1xuICAgIGlmICghcmVsYXRlZCB8fCAocmVsYXRlZCAhPT0gdGhpcyAmJiAhKHJlbGF0ZWQuY29tcGFyZURvY3VtZW50UG9zaXRpb24odGhpcykgJiA4KSkpIHtcbiAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgZXZlbnQpO1xuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gY29udGV4dExpc3RlbmVyKGxpc3RlbmVyLCBpbmRleCwgZ3JvdXApIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGV2ZW50MSkge1xuICAgIHZhciBldmVudDAgPSBleHBvcnRzLmV2ZW50OyAvLyBFdmVudHMgY2FuIGJlIHJlZW50cmFudCAoZS5nLiwgZm9jdXMpLlxuICAgIGV4cG9ydHMuZXZlbnQgPSBldmVudDE7XG4gICAgdHJ5IHtcbiAgICAgIGxpc3RlbmVyLmNhbGwodGhpcywgdGhpcy5fX2RhdGFfXywgaW5kZXgsIGdyb3VwKTtcbiAgICB9IGZpbmFsbHkge1xuICAgICAgZXhwb3J0cy5ldmVudCA9IGV2ZW50MDtcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lcykge1xuICByZXR1cm4gdHlwZW5hbWVzLnRyaW0oKS5zcGxpdCgvXnxcXHMrLykubWFwKGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgbmFtZSA9IFwiXCIsIGkgPSB0LmluZGV4T2YoXCIuXCIpO1xuICAgIGlmIChpID49IDApIG5hbWUgPSB0LnNsaWNlKGkgKyAxKSwgdCA9IHQuc2xpY2UoMCwgaSk7XG4gICAgcmV0dXJuIHt0eXBlOiB0LCBuYW1lOiBuYW1lfTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIG9uUmVtb3ZlKHR5cGVuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICB2YXIgb24gPSB0aGlzLl9fb247XG4gICAgaWYgKCFvbikgcmV0dXJuO1xuICAgIGZvciAodmFyIGogPSAwLCBpID0gLTEsIG0gPSBvbi5sZW5ndGgsIG87IGogPCBtOyArK2opIHtcbiAgICAgIGlmIChvID0gb25bal0sICghdHlwZW5hbWUudHlwZSB8fCBvLnR5cGUgPT09IHR5cGVuYW1lLnR5cGUpICYmIG8ubmFtZSA9PT0gdHlwZW5hbWUubmFtZSkge1xuICAgICAgICB0aGlzLnJlbW92ZUV2ZW50TGlzdGVuZXIoby50eXBlLCBvLmxpc3RlbmVyLCBvLmNhcHR1cmUpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb25bKytpXSA9IG87XG4gICAgICB9XG4gICAgfVxuICAgIGlmICgrK2kpIG9uLmxlbmd0aCA9IGk7XG4gICAgZWxzZSBkZWxldGUgdGhpcy5fX29uO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvbkFkZCh0eXBlbmFtZSwgdmFsdWUsIGNhcHR1cmUpIHtcbiAgdmFyIHdyYXAgPSBmaWx0ZXJFdmVudHMuaGFzT3duUHJvcGVydHkodHlwZW5hbWUudHlwZSkgPyBmaWx0ZXJDb250ZXh0TGlzdGVuZXIgOiBjb250ZXh0TGlzdGVuZXI7XG4gIHJldHVybiBmdW5jdGlvbihkLCBpLCBncm91cCkge1xuICAgIHZhciBvbiA9IHRoaXMuX19vbiwgbywgbGlzdGVuZXIgPSB3cmFwKHZhbHVlLCBpLCBncm91cCk7XG4gICAgaWYgKG9uKSBmb3IgKHZhciBqID0gMCwgbSA9IG9uLmxlbmd0aDsgaiA8IG07ICsraikge1xuICAgICAgaWYgKChvID0gb25bal0pLnR5cGUgPT09IHR5cGVuYW1lLnR5cGUgJiYgby5uYW1lID09PSB0eXBlbmFtZS5uYW1lKSB7XG4gICAgICAgIHRoaXMucmVtb3ZlRXZlbnRMaXN0ZW5lcihvLnR5cGUsIG8ubGlzdGVuZXIsIG8uY2FwdHVyZSk7XG4gICAgICAgIHRoaXMuYWRkRXZlbnRMaXN0ZW5lcihvLnR5cGUsIG8ubGlzdGVuZXIgPSBsaXN0ZW5lciwgby5jYXB0dXJlID0gY2FwdHVyZSk7XG4gICAgICAgIG8udmFsdWUgPSB2YWx1ZTtcbiAgICAgICAgcmV0dXJuO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLmFkZEV2ZW50TGlzdGVuZXIodHlwZW5hbWUudHlwZSwgbGlzdGVuZXIsIGNhcHR1cmUpO1xuICAgIG8gPSB7dHlwZTogdHlwZW5hbWUudHlwZSwgbmFtZTogdHlwZW5hbWUubmFtZSwgdmFsdWU6IHZhbHVlLCBsaXN0ZW5lcjogbGlzdGVuZXIsIGNhcHR1cmU6IGNhcHR1cmV9O1xuICAgIGlmICghb24pIHRoaXMuX19vbiA9IFtvXTtcbiAgICBlbHNlIG9uLnB1c2gobyk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHNlbGVjdGlvbl9vbih0eXBlbmFtZSwgdmFsdWUsIGNhcHR1cmUpIHtcbiAgdmFyIHR5cGVuYW1lcyA9IHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lICsgXCJcIiksIGksIG4gPSB0eXBlbmFtZXMubGVuZ3RoLCB0O1xuXG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikge1xuICAgIHZhciBvbiA9IHRoaXMubm9kZSgpLl9fb247XG4gICAgaWYgKG9uKSBmb3IgKHZhciBqID0gMCwgbSA9IG9uLmxlbmd0aCwgbzsgaiA8IG07ICsraikge1xuICAgICAgZm9yIChpID0gMCwgbyA9IG9uW2pdOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIGlmICgodCA9IHR5cGVuYW1lc1tpXSkudHlwZSA9PT0gby50eXBlICYmIHQubmFtZSA9PT0gby5uYW1lKSB7XG4gICAgICAgICAgcmV0dXJuIG8udmFsdWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgb24gPSB2YWx1ZSA/IG9uQWRkIDogb25SZW1vdmU7XG4gIGlmIChjYXB0dXJlID09IG51bGwpIGNhcHR1cmUgPSBmYWxzZTtcbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgdGhpcy5lYWNoKG9uKHR5cGVuYW1lc1tpXSwgdmFsdWUsIGNhcHR1cmUpKTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIGN1c3RvbUV2ZW50KGV2ZW50MSwgbGlzdGVuZXIsIHRoYXQsIGFyZ3MpIHtcbiAgdmFyIGV2ZW50MCA9IGV4cG9ydHMuZXZlbnQ7XG4gIGV2ZW50MS5zb3VyY2VFdmVudCA9IGV4cG9ydHMuZXZlbnQ7XG4gIGV4cG9ydHMuZXZlbnQgPSBldmVudDE7XG4gIHRyeSB7XG4gICAgcmV0dXJuIGxpc3RlbmVyLmFwcGx5KHRoYXQsIGFyZ3MpO1xuICB9IGZpbmFsbHkge1xuICAgIGV4cG9ydHMuZXZlbnQgPSBldmVudDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hFdmVudChub2RlLCB0eXBlLCBwYXJhbXMpIHtcbiAgdmFyIHdpbmRvdyA9IGRlZmF1bHRWaWV3KG5vZGUpLFxuICAgICAgZXZlbnQgPSB3aW5kb3cuQ3VzdG9tRXZlbnQ7XG5cbiAgaWYgKHR5cGVvZiBldmVudCA9PT0gXCJmdW5jdGlvblwiKSB7XG4gICAgZXZlbnQgPSBuZXcgZXZlbnQodHlwZSwgcGFyYW1zKTtcbiAgfSBlbHNlIHtcbiAgICBldmVudCA9IHdpbmRvdy5kb2N1bWVudC5jcmVhdGVFdmVudChcIkV2ZW50XCIpO1xuICAgIGlmIChwYXJhbXMpIGV2ZW50LmluaXRFdmVudCh0eXBlLCBwYXJhbXMuYnViYmxlcywgcGFyYW1zLmNhbmNlbGFibGUpLCBldmVudC5kZXRhaWwgPSBwYXJhbXMuZGV0YWlsO1xuICAgIGVsc2UgZXZlbnQuaW5pdEV2ZW50KHR5cGUsIGZhbHNlLCBmYWxzZSk7XG4gIH1cblxuICBub2RlLmRpc3BhdGNoRXZlbnQoZXZlbnQpO1xufVxuXG5mdW5jdGlvbiBkaXNwYXRjaENvbnN0YW50KHR5cGUsIHBhcmFtcykge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGRpc3BhdGNoRXZlbnQodGhpcywgdHlwZSwgcGFyYW1zKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZGlzcGF0Y2hGdW5jdGlvbih0eXBlLCBwYXJhbXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkaXNwYXRjaEV2ZW50KHRoaXMsIHR5cGUsIHBhcmFtcy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uX2Rpc3BhdGNoKHR5cGUsIHBhcmFtcykge1xuICByZXR1cm4gdGhpcy5lYWNoKCh0eXBlb2YgcGFyYW1zID09PSBcImZ1bmN0aW9uXCJcbiAgICAgID8gZGlzcGF0Y2hGdW5jdGlvblxuICAgICAgOiBkaXNwYXRjaENvbnN0YW50KSh0eXBlLCBwYXJhbXMpKTtcbn1cblxudmFyIHJvb3QgPSBbbnVsbF07XG5cbmZ1bmN0aW9uIFNlbGVjdGlvbihncm91cHMsIHBhcmVudHMpIHtcbiAgdGhpcy5fZ3JvdXBzID0gZ3JvdXBzO1xuICB0aGlzLl9wYXJlbnRzID0gcGFyZW50cztcbn1cblxuZnVuY3Rpb24gc2VsZWN0aW9uKCkge1xuICByZXR1cm4gbmV3IFNlbGVjdGlvbihbW2RvY3VtZW50LmRvY3VtZW50RWxlbWVudF1dLCByb290KTtcbn1cblxuU2VsZWN0aW9uLnByb3RvdHlwZSA9IHNlbGVjdGlvbi5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBTZWxlY3Rpb24sXG4gIHNlbGVjdDogc2VsZWN0aW9uX3NlbGVjdCxcbiAgc2VsZWN0QWxsOiBzZWxlY3Rpb25fc2VsZWN0QWxsLFxuICBmaWx0ZXI6IHNlbGVjdGlvbl9maWx0ZXIsXG4gIGRhdGE6IHNlbGVjdGlvbl9kYXRhLFxuICBlbnRlcjogc2VsZWN0aW9uX2VudGVyLFxuICBleGl0OiBzZWxlY3Rpb25fZXhpdCxcbiAgbWVyZ2U6IHNlbGVjdGlvbl9tZXJnZSxcbiAgb3JkZXI6IHNlbGVjdGlvbl9vcmRlcixcbiAgc29ydDogc2VsZWN0aW9uX3NvcnQsXG4gIGNhbGw6IHNlbGVjdGlvbl9jYWxsLFxuICBub2Rlczogc2VsZWN0aW9uX25vZGVzLFxuICBub2RlOiBzZWxlY3Rpb25fbm9kZSxcbiAgc2l6ZTogc2VsZWN0aW9uX3NpemUsXG4gIGVtcHR5OiBzZWxlY3Rpb25fZW1wdHksXG4gIGVhY2g6IHNlbGVjdGlvbl9lYWNoLFxuICBhdHRyOiBzZWxlY3Rpb25fYXR0cixcbiAgc3R5bGU6IHNlbGVjdGlvbl9zdHlsZSxcbiAgcHJvcGVydHk6IHNlbGVjdGlvbl9wcm9wZXJ0eSxcbiAgY2xhc3NlZDogc2VsZWN0aW9uX2NsYXNzZWQsXG4gIHRleHQ6IHNlbGVjdGlvbl90ZXh0LFxuICBodG1sOiBzZWxlY3Rpb25faHRtbCxcbiAgcmFpc2U6IHNlbGVjdGlvbl9yYWlzZSxcbiAgbG93ZXI6IHNlbGVjdGlvbl9sb3dlcixcbiAgYXBwZW5kOiBzZWxlY3Rpb25fYXBwZW5kLFxuICBpbnNlcnQ6IHNlbGVjdGlvbl9pbnNlcnQsXG4gIHJlbW92ZTogc2VsZWN0aW9uX3JlbW92ZSxcbiAgY2xvbmU6IHNlbGVjdGlvbl9jbG9uZSxcbiAgZGF0dW06IHNlbGVjdGlvbl9kYXR1bSxcbiAgb246IHNlbGVjdGlvbl9vbixcbiAgZGlzcGF0Y2g6IHNlbGVjdGlvbl9kaXNwYXRjaFxufTtcblxuZnVuY3Rpb24gc2VsZWN0KHNlbGVjdG9yKSB7XG4gIHJldHVybiB0eXBlb2Ygc2VsZWN0b3IgPT09IFwic3RyaW5nXCJcbiAgICAgID8gbmV3IFNlbGVjdGlvbihbW2RvY3VtZW50LnF1ZXJ5U2VsZWN0b3Ioc2VsZWN0b3IpXV0sIFtkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdKVxuICAgICAgOiBuZXcgU2VsZWN0aW9uKFtbc2VsZWN0b3JdXSwgcm9vdCk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZShuYW1lKSB7XG4gIHJldHVybiBzZWxlY3QoY3JlYXRvcihuYW1lKS5jYWxsKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCkpO1xufVxuXG52YXIgbmV4dElkID0gMDtcblxuZnVuY3Rpb24gbG9jYWwoKSB7XG4gIHJldHVybiBuZXcgTG9jYWw7XG59XG5cbmZ1bmN0aW9uIExvY2FsKCkge1xuICB0aGlzLl8gPSBcIkBcIiArICgrK25leHRJZCkudG9TdHJpbmcoMzYpO1xufVxuXG5Mb2NhbC5wcm90b3R5cGUgPSBsb2NhbC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBMb2NhbCxcbiAgZ2V0OiBmdW5jdGlvbihub2RlKSB7XG4gICAgdmFyIGlkID0gdGhpcy5fO1xuICAgIHdoaWxlICghKGlkIGluIG5vZGUpKSBpZiAoIShub2RlID0gbm9kZS5wYXJlbnROb2RlKSkgcmV0dXJuO1xuICAgIHJldHVybiBub2RlW2lkXTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihub2RlLCB2YWx1ZSkge1xuICAgIHJldHVybiBub2RlW3RoaXMuX10gPSB2YWx1ZTtcbiAgfSxcbiAgcmVtb3ZlOiBmdW5jdGlvbihub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMuXyBpbiBub2RlICYmIGRlbGV0ZSBub2RlW3RoaXMuX107XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5fO1xuICB9XG59O1xuXG5mdW5jdGlvbiBzb3VyY2VFdmVudCgpIHtcbiAgdmFyIGN1cnJlbnQgPSBleHBvcnRzLmV2ZW50LCBzb3VyY2U7XG4gIHdoaWxlIChzb3VyY2UgPSBjdXJyZW50LnNvdXJjZUV2ZW50KSBjdXJyZW50ID0gc291cmNlO1xuICByZXR1cm4gY3VycmVudDtcbn1cblxuZnVuY3Rpb24gcG9pbnQobm9kZSwgZXZlbnQpIHtcbiAgdmFyIHN2ZyA9IG5vZGUub3duZXJTVkdFbGVtZW50IHx8IG5vZGU7XG5cbiAgaWYgKHN2Zy5jcmVhdGVTVkdQb2ludCkge1xuICAgIHZhciBwb2ludCA9IHN2Zy5jcmVhdGVTVkdQb2ludCgpO1xuICAgIHBvaW50LnggPSBldmVudC5jbGllbnRYLCBwb2ludC55ID0gZXZlbnQuY2xpZW50WTtcbiAgICBwb2ludCA9IHBvaW50Lm1hdHJpeFRyYW5zZm9ybShub2RlLmdldFNjcmVlbkNUTSgpLmludmVyc2UoKSk7XG4gICAgcmV0dXJuIFtwb2ludC54LCBwb2ludC55XTtcbiAgfVxuXG4gIHZhciByZWN0ID0gbm9kZS5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgcmV0dXJuIFtldmVudC5jbGllbnRYIC0gcmVjdC5sZWZ0IC0gbm9kZS5jbGllbnRMZWZ0LCBldmVudC5jbGllbnRZIC0gcmVjdC50b3AgLSBub2RlLmNsaWVudFRvcF07XG59XG5cbmZ1bmN0aW9uIG1vdXNlKG5vZGUpIHtcbiAgdmFyIGV2ZW50ID0gc291cmNlRXZlbnQoKTtcbiAgaWYgKGV2ZW50LmNoYW5nZWRUb3VjaGVzKSBldmVudCA9IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdO1xuICByZXR1cm4gcG9pbnQobm9kZSwgZXZlbnQpO1xufVxuXG5mdW5jdGlvbiBzZWxlY3RBbGwoc2VsZWN0b3IpIHtcbiAgcmV0dXJuIHR5cGVvZiBzZWxlY3RvciA9PT0gXCJzdHJpbmdcIlxuICAgICAgPyBuZXcgU2VsZWN0aW9uKFtkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKHNlbGVjdG9yKV0sIFtkb2N1bWVudC5kb2N1bWVudEVsZW1lbnRdKVxuICAgICAgOiBuZXcgU2VsZWN0aW9uKFtzZWxlY3RvciA9PSBudWxsID8gW10gOiBzZWxlY3Rvcl0sIHJvb3QpO1xufVxuXG5mdW5jdGlvbiB0b3VjaChub2RlLCB0b3VjaGVzLCBpZGVudGlmaWVyKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMykgaWRlbnRpZmllciA9IHRvdWNoZXMsIHRvdWNoZXMgPSBzb3VyY2VFdmVudCgpLmNoYW5nZWRUb3VjaGVzO1xuXG4gIGZvciAodmFyIGkgPSAwLCBuID0gdG91Y2hlcyA/IHRvdWNoZXMubGVuZ3RoIDogMCwgdG91Y2g7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoKHRvdWNoID0gdG91Y2hlc1tpXSkuaWRlbnRpZmllciA9PT0gaWRlbnRpZmllcikge1xuICAgICAgcmV0dXJuIHBvaW50KG5vZGUsIHRvdWNoKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gdG91Y2hlcyhub2RlLCB0b3VjaGVzKSB7XG4gIGlmICh0b3VjaGVzID09IG51bGwpIHRvdWNoZXMgPSBzb3VyY2VFdmVudCgpLnRvdWNoZXM7XG5cbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0b3VjaGVzID8gdG91Y2hlcy5sZW5ndGggOiAwLCBwb2ludHMgPSBuZXcgQXJyYXkobik7IGkgPCBuOyArK2kpIHtcbiAgICBwb2ludHNbaV0gPSBwb2ludChub2RlLCB0b3VjaGVzW2ldKTtcbiAgfVxuXG4gIHJldHVybiBwb2ludHM7XG59XG5cbmV4cG9ydHMuY3JlYXRlID0gY3JlYXRlO1xuZXhwb3J0cy5jcmVhdG9yID0gY3JlYXRvcjtcbmV4cG9ydHMubG9jYWwgPSBsb2NhbDtcbmV4cG9ydHMubWF0Y2hlciA9IG1hdGNoZXIkMTtcbmV4cG9ydHMubW91c2UgPSBtb3VzZTtcbmV4cG9ydHMubmFtZXNwYWNlID0gbmFtZXNwYWNlO1xuZXhwb3J0cy5uYW1lc3BhY2VzID0gbmFtZXNwYWNlcztcbmV4cG9ydHMuY2xpZW50UG9pbnQgPSBwb2ludDtcbmV4cG9ydHMuc2VsZWN0ID0gc2VsZWN0O1xuZXhwb3J0cy5zZWxlY3RBbGwgPSBzZWxlY3RBbGw7XG5leHBvcnRzLnNlbGVjdGlvbiA9IHNlbGVjdGlvbjtcbmV4cG9ydHMuc2VsZWN0b3IgPSBzZWxlY3RvcjtcbmV4cG9ydHMuc2VsZWN0b3JBbGwgPSBzZWxlY3RvckFsbDtcbmV4cG9ydHMuc3R5bGUgPSBzdHlsZVZhbHVlO1xuZXhwb3J0cy50b3VjaCA9IHRvdWNoO1xuZXhwb3J0cy50b3VjaGVzID0gdG91Y2hlcztcbmV4cG9ydHMud2luZG93ID0gZGVmYXVsdFZpZXc7XG5leHBvcnRzLmN1c3RvbUV2ZW50ID0gY3VzdG9tRXZlbnQ7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbn0pKSk7XG4iLCIoZnVuY3Rpb24gKGdsb2JhbCwgZmFjdG9yeSkge1xuXHR0eXBlb2YgZXhwb3J0cyA9PT0gJ29iamVjdCcgJiYgdHlwZW9mIG1vZHVsZSAhPT0gJ3VuZGVmaW5lZCcgPyBmYWN0b3J5KGV4cG9ydHMpIDpcblx0dHlwZW9mIGRlZmluZSA9PT0gJ2Z1bmN0aW9uJyAmJiBkZWZpbmUuYW1kID8gZGVmaW5lKFsnZXhwb3J0cyddLCBmYWN0b3J5KSA6XG5cdChmYWN0b3J5KChnbG9iYWwudmVnYSA9IGdsb2JhbC52ZWdhIHx8IHt9KSkpO1xufSh0aGlzLCAoZnVuY3Rpb24gKGV4cG9ydHMpIHsgJ3VzZSBzdHJpY3QnO1xuXG52YXIgYWNjZXNzb3IgPSBmdW5jdGlvbihmbiwgZmllbGRzLCBuYW1lKSB7XG4gIGZuLmZpZWxkcyA9IGZpZWxkcyB8fCBbXTtcbiAgZm4uZm5hbWUgPSBuYW1lO1xuICByZXR1cm4gZm47XG59O1xuXG5mdW5jdGlvbiBhY2Nlc3Nvck5hbWUoZm4pIHtcbiAgcmV0dXJuIGZuID09IG51bGwgPyBudWxsIDogZm4uZm5hbWU7XG59XG5cbmZ1bmN0aW9uIGFjY2Vzc29yRmllbGRzKGZuKSB7XG4gIHJldHVybiBmbiA9PSBudWxsID8gbnVsbCA6IGZuLmZpZWxkcztcbn1cblxudmFyIGVycm9yJDEgPSBmdW5jdGlvbihtZXNzYWdlKSB7XG4gIHRocm93IEVycm9yKG1lc3NhZ2UpO1xufTtcblxudmFyIHNwbGl0QWNjZXNzUGF0aCA9IGZ1bmN0aW9uKHApIHtcbiAgdmFyIHBhdGggPSBbXSxcbiAgICAgIHEgPSBudWxsLFxuICAgICAgYiA9IDAsXG4gICAgICBuID0gcC5sZW5ndGgsXG4gICAgICBzID0gJycsXG4gICAgICBpLCBqLCBjO1xuXG4gIHAgPSBwICsgJyc7XG5cbiAgZnVuY3Rpb24gcHVzaCgpIHtcbiAgICBwYXRoLnB1c2gocyArIHAuc3Vic3RyaW5nKGksIGopKTtcbiAgICBzID0gJyc7XG4gICAgaSA9IGogKyAxO1xuICB9XG5cbiAgZm9yIChpPWo9MDsgajxuOyArK2opIHtcbiAgICBjID0gcFtqXTtcbiAgICBpZiAoYyA9PT0gJ1xcXFwnKSB7XG4gICAgICBzICs9IHAuc3Vic3RyaW5nKGksIGopO1xuICAgICAgaSA9ICsrajtcbiAgICB9IGVsc2UgaWYgKGMgPT09IHEpIHtcbiAgICAgIHB1c2goKTtcbiAgICAgIHEgPSBudWxsO1xuICAgICAgYiA9IC0xO1xuICAgIH0gZWxzZSBpZiAocSkge1xuICAgICAgY29udGludWU7XG4gICAgfSBlbHNlIGlmIChpID09PSBiICYmIGMgPT09ICdcIicpIHtcbiAgICAgIGkgPSBqICsgMTtcbiAgICAgIHEgPSBjO1xuICAgIH0gZWxzZSBpZiAoaSA9PT0gYiAmJiBjID09PSBcIidcIikge1xuICAgICAgaSA9IGogKyAxO1xuICAgICAgcSA9IGM7XG4gICAgfSBlbHNlIGlmIChjID09PSAnLicgJiYgIWIpIHtcbiAgICAgIGlmIChqID4gaSkge1xuICAgICAgICBwdXNoKCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpID0gaiArIDE7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChjID09PSAnWycpIHtcbiAgICAgIGlmIChqID4gaSkgcHVzaCgpO1xuICAgICAgYiA9IGkgPSBqICsgMTtcbiAgICB9IGVsc2UgaWYgKGMgPT09ICddJykge1xuICAgICAgaWYgKCFiKSBlcnJvciQxKCdBY2Nlc3MgcGF0aCBtaXNzaW5nIG9wZW4gYnJhY2tldDogJyArIHApO1xuICAgICAgaWYgKGIgPiAwKSBwdXNoKCk7XG4gICAgICBiID0gMDtcbiAgICAgIGkgPSBqICsgMTtcbiAgICB9XG4gIH1cblxuICBpZiAoYikgZXJyb3IkMSgnQWNjZXNzIHBhdGggbWlzc2luZyBjbG9zaW5nIGJyYWNrZXQ6ICcgKyBwKTtcbiAgaWYgKHEpIGVycm9yJDEoJ0FjY2VzcyBwYXRoIG1pc3NpbmcgY2xvc2luZyBxdW90ZTogJyArIHApO1xuXG4gIGlmIChqID4gaSkge1xuICAgIGorKztcbiAgICBwdXNoKCk7XG4gIH1cblxuICByZXR1cm4gcGF0aDtcbn07XG5cbnZhciBpc0FycmF5ID0gQXJyYXkuaXNBcnJheTtcblxudmFyIGlzT2JqZWN0ID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gXyA9PT0gT2JqZWN0KF8pO1xufTtcblxudmFyIGlzU3RyaW5nID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gdHlwZW9mIF8gPT09ICdzdHJpbmcnO1xufTtcblxuZnVuY3Rpb24gJCh4KSB7XG4gIHJldHVybiBpc0FycmF5KHgpID8gJ1snICsgeC5tYXAoJCkgKyAnXSdcbiAgICA6IGlzT2JqZWN0KHgpIHx8IGlzU3RyaW5nKHgpID9cbiAgICAgIC8vIE91dHB1dCB2YWxpZCBKU09OIGFuZCBKUyBzb3VyY2Ugc3RyaW5ncy5cbiAgICAgIC8vIFNlZSBodHRwOi8vdGltZWxlc3NyZXBvLmNvbS9qc29uLWlzbnQtYS1qYXZhc2NyaXB0LXN1YnNldFxuICAgICAgSlNPTi5zdHJpbmdpZnkoeCkucmVwbGFjZSgnXFx1MjAyOCcsJ1xcXFx1MjAyOCcpLnJlcGxhY2UoJ1xcdTIwMjknLCAnXFxcXHUyMDI5JylcbiAgICA6IHg7XG59XG5cbnZhciBmaWVsZCA9IGZ1bmN0aW9uKGZpZWxkLCBuYW1lKSB7XG4gIHZhciBwYXRoID0gc3BsaXRBY2Nlc3NQYXRoKGZpZWxkKSxcbiAgICAgIGNvZGUgPSAncmV0dXJuIF9bJyArIHBhdGgubWFwKCQpLmpvaW4oJ11bJykgKyAnXTsnO1xuXG4gIHJldHVybiBhY2Nlc3NvcihcbiAgICBGdW5jdGlvbignXycsIGNvZGUpLFxuICAgIFsoZmllbGQgPSBwYXRoLmxlbmd0aD09PTEgPyBwYXRoWzBdIDogZmllbGQpXSxcbiAgICBuYW1lIHx8IGZpZWxkXG4gICk7XG59O1xuXG52YXIgZW1wdHkgPSBbXTtcblxudmFyIGlkID0gZmllbGQoJ2lkJyk7XG5cbnZhciBpZGVudGl0eSA9IGFjY2Vzc29yKGZ1bmN0aW9uKF8pIHsgcmV0dXJuIF87IH0sIGVtcHR5LCAnaWRlbnRpdHknKTtcblxudmFyIHplcm8gPSBhY2Nlc3NvcihmdW5jdGlvbigpIHsgcmV0dXJuIDA7IH0sIGVtcHR5LCAnemVybycpO1xuXG52YXIgb25lID0gYWNjZXNzb3IoZnVuY3Rpb24oKSB7IHJldHVybiAxOyB9LCBlbXB0eSwgJ29uZScpO1xuXG52YXIgdHJ1dGh5ID0gYWNjZXNzb3IoZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9LCBlbXB0eSwgJ3RydWUnKTtcblxudmFyIGZhbHN5ID0gYWNjZXNzb3IoZnVuY3Rpb24oKSB7IHJldHVybiBmYWxzZTsgfSwgZW1wdHksICdmYWxzZScpO1xuXG5mdW5jdGlvbiBsb2cobWV0aG9kLCBsZXZlbCwgaW5wdXQpIHtcbiAgdmFyIGFyZ3MgPSBbbGV2ZWxdLmNvbmNhdChbXS5zbGljZS5jYWxsKGlucHV0KSk7XG4gIGNvbnNvbGVbbWV0aG9kXS5hcHBseShjb25zb2xlLCBhcmdzKTsgLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1jb25zb2xlXG59XG5cbnZhciBOb25lICA9IDA7XG52YXIgRXJyb3IkMSA9IDE7XG52YXIgV2FybiAgPSAyO1xudmFyIEluZm8gID0gMztcbnZhciBEZWJ1ZyA9IDQ7XG5cbnZhciBsb2dnZXIgPSBmdW5jdGlvbihfKSB7XG4gIHZhciBsZXZlbCA9IF8gfHwgTm9uZTtcbiAgcmV0dXJuIHtcbiAgICBsZXZlbDogZnVuY3Rpb24oXykge1xuICAgICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgICAgbGV2ZWwgPSArXztcbiAgICAgICAgcmV0dXJuIHRoaXM7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXR1cm4gbGV2ZWw7XG4gICAgICB9XG4gICAgfSxcbiAgICBlcnJvcjogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAobGV2ZWwgPj0gRXJyb3IkMSkgbG9nKCdlcnJvcicsICdFUlJPUicsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIHdhcm46IGZ1bmN0aW9uKCkge1xuICAgICAgaWYgKGxldmVsID49IFdhcm4pIGxvZygnd2FybicsICdXQVJOJywgYXJndW1lbnRzKTtcbiAgICAgIHJldHVybiB0aGlzO1xuICAgIH0sXG4gICAgaW5mbzogZnVuY3Rpb24oKSB7XG4gICAgICBpZiAobGV2ZWwgPj0gSW5mbykgbG9nKCdsb2cnLCAnSU5GTycsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGRlYnVnOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChsZXZlbCA+PSBEZWJ1ZykgbG9nKCdsb2cnLCAnREVCVUcnLCBhcmd1bWVudHMpO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfVxuICB9XG59O1xuXG52YXIgcGVlayA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gIHJldHVybiBhcnJheVthcnJheS5sZW5ndGggLSAxXTtcbn07XG5cbnZhciB0b051bWJlciA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIF8gPT0gbnVsbCB8fCBfID09PSAnJyA/IG51bGwgOiArXztcbn07XG5cbmZ1bmN0aW9uIGV4cChzaWduKSB7XG4gIHJldHVybiBmdW5jdGlvbih4KSB7IHJldHVybiBzaWduICogTWF0aC5leHAoeCk7IH07XG59XG5cbmZ1bmN0aW9uIGxvZyQxKHNpZ24pIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgubG9nKHNpZ24gKiB4KTsgfTtcbn1cblxuZnVuY3Rpb24gcG93KGV4cG9uZW50KSB7XG4gIHJldHVybiBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIHggPCAwID8gLU1hdGgucG93KC14LCBleHBvbmVudCkgOiBNYXRoLnBvdyh4LCBleHBvbmVudCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBhbihkb21haW4sIGRlbHRhLCBsaWZ0LCBncm91bmQpIHtcbiAgdmFyIGQwID0gbGlmdChkb21haW5bMF0pLFxuICAgICAgZDEgPSBsaWZ0KHBlZWsoZG9tYWluKSksXG4gICAgICBkZCA9IChkMSAtIGQwKSAqIGRlbHRhO1xuXG4gIHJldHVybiBbXG4gICAgZ3JvdW5kKGQwIC0gZGQpLFxuICAgIGdyb3VuZChkMSAtIGRkKVxuICBdO1xufVxuXG5mdW5jdGlvbiBwYW5MaW5lYXIoZG9tYWluLCBkZWx0YSkge1xuICByZXR1cm4gcGFuKGRvbWFpbiwgZGVsdGEsIHRvTnVtYmVyLCBpZGVudGl0eSk7XG59XG5cbmZ1bmN0aW9uIHBhbkxvZyhkb21haW4sIGRlbHRhKSB7XG4gIHZhciBzaWduID0gTWF0aC5zaWduKGRvbWFpblswXSk7XG4gIHJldHVybiBwYW4oZG9tYWluLCBkZWx0YSwgbG9nJDEoc2lnbiksIGV4cChzaWduKSk7XG59XG5cbmZ1bmN0aW9uIHBhblBvdyhkb21haW4sIGRlbHRhLCBleHBvbmVudCkge1xuICByZXR1cm4gcGFuKGRvbWFpbiwgZGVsdGEsIHBvdyhleHBvbmVudCksIHBvdygxL2V4cG9uZW50KSk7XG59XG5cbmZ1bmN0aW9uIHpvb20oZG9tYWluLCBhbmNob3IsIHNjYWxlLCBsaWZ0LCBncm91bmQpIHtcbiAgdmFyIGQwID0gbGlmdChkb21haW5bMF0pLFxuICAgICAgZDEgPSBsaWZ0KHBlZWsoZG9tYWluKSksXG4gICAgICBkYSA9IGFuY2hvciAhPSBudWxsID8gbGlmdChhbmNob3IpIDogKGQwICsgZDEpIC8gMjtcblxuICByZXR1cm4gW1xuICAgIGdyb3VuZChkYSArIChkMCAtIGRhKSAqIHNjYWxlKSxcbiAgICBncm91bmQoZGEgKyAoZDEgLSBkYSkgKiBzY2FsZSlcbiAgXTtcbn1cblxuZnVuY3Rpb24gem9vbUxpbmVhcihkb21haW4sIGFuY2hvciwgc2NhbGUpIHtcbiAgcmV0dXJuIHpvb20oZG9tYWluLCBhbmNob3IsIHNjYWxlLCB0b051bWJlciwgaWRlbnRpdHkpO1xufVxuXG5mdW5jdGlvbiB6b29tTG9nKGRvbWFpbiwgYW5jaG9yLCBzY2FsZSkge1xuICB2YXIgc2lnbiA9IE1hdGguc2lnbihkb21haW5bMF0pO1xuICByZXR1cm4gem9vbShkb21haW4sIGFuY2hvciwgc2NhbGUsIGxvZyQxKHNpZ24pLCBleHAoc2lnbikpO1xufVxuXG5mdW5jdGlvbiB6b29tUG93KGRvbWFpbiwgYW5jaG9yLCBzY2FsZSwgZXhwb25lbnQpIHtcbiAgcmV0dXJuIHpvb20oZG9tYWluLCBhbmNob3IsIHNjYWxlLCBwb3coZXhwb25lbnQpLCBwb3coMS9leHBvbmVudCkpO1xufVxuXG52YXIgYXJyYXkgPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBfICE9IG51bGwgPyAoaXNBcnJheShfKSA/IF8gOiBbX10pIDogW107XG59O1xuXG52YXIgaXNGdW5jdGlvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIHR5cGVvZiBfID09PSAnZnVuY3Rpb24nO1xufTtcblxudmFyIGNvbXBhcmUgPSBmdW5jdGlvbihmaWVsZHMsIG9yZGVycykge1xuICB2YXIgaWR4ID0gW10sXG4gICAgICBjbXAgPSAoZmllbGRzID0gYXJyYXkoZmllbGRzKSkubWFwKGZ1bmN0aW9uKGYsIGkpIHtcbiAgICAgICAgaWYgKGYgPT0gbnVsbCkge1xuICAgICAgICAgIHJldHVybiBudWxsO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlkeC5wdXNoKGkpO1xuICAgICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGYpID8gZlxuICAgICAgICAgICAgOiBzcGxpdEFjY2Vzc1BhdGgoZikubWFwKCQpLmpvaW4oJ11bJyk7XG4gICAgICAgIH1cbiAgICAgIH0pLFxuICAgICAgbiA9IGlkeC5sZW5ndGggLSAxLFxuICAgICAgb3JkID0gYXJyYXkob3JkZXJzKSxcbiAgICAgIGNvZGUgPSAndmFyIHUsdjtyZXR1cm4gJyxcbiAgICAgIGksIGosIGYsIHUsIHYsIGQsIHQsIGx0LCBndDtcblxuICBpZiAobiA8IDApIHJldHVybiBudWxsO1xuXG4gIGZvciAoaj0wOyBqPD1uOyArK2opIHtcbiAgICBpID0gaWR4W2pdO1xuICAgIGYgPSBjbXBbaV07XG5cbiAgICBpZiAoaXNGdW5jdGlvbihmKSkge1xuICAgICAgZCA9ICdmJyArIGk7XG4gICAgICB1ID0gJyh1PXRoaXMuJyArIGQgKyAnKGEpKSc7XG4gICAgICB2ID0gJyh2PXRoaXMuJyArIGQgKyAnKGIpKSc7XG4gICAgICAodCA9IHQgfHwge30pW2RdID0gZjtcbiAgICB9IGVsc2Uge1xuICAgICAgdSA9ICcodT1hWycrZisnXSknO1xuICAgICAgdiA9ICcodj1iWycrZisnXSknO1xuICAgIH1cblxuICAgIGQgPSAnKCh2PXYgaW5zdGFuY2VvZiBEYXRlPyt2OnYpLCh1PXUgaW5zdGFuY2VvZiBEYXRlPyt1OnUpKSc7XG5cbiAgICBpZiAob3JkW2ldICE9PSAnZGVzY2VuZGluZycpIHtcbiAgICAgIGd0ID0gMTtcbiAgICAgIGx0ID0gLTE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGd0ID0gLTE7XG4gICAgICBsdCA9IDE7XG4gICAgfVxuXG4gICAgY29kZSArPSAnKCcgKyB1Kyc8Jyt2Kyd8fHU9PW51bGwpJiZ2IT1udWxsPycgKyBsdFxuICAgICAgKyAnOih1PnZ8fHY9PW51bGwpJiZ1IT1udWxsPycgKyBndFxuICAgICAgKyAnOicrZCsnIT09dSYmdj09PXY/JyArIGx0XG4gICAgICArICc6diE9PXYmJnU9PT11PycgKyBndFxuICAgICAgKyAoaSA8IG4gPyAnOicgOiAnOjAnKTtcbiAgfVxuXG4gIGYgPSBGdW5jdGlvbignYScsICdiJywgY29kZSArICc7Jyk7XG4gIGlmICh0KSBmID0gZi5iaW5kKHQpO1xuXG4gIGZpZWxkcyA9IGZpZWxkcy5yZWR1Y2UoZnVuY3Rpb24obWFwLCBmaWVsZCkge1xuICAgIGlmIChpc0Z1bmN0aW9uKGZpZWxkKSkge1xuICAgICAgKGFjY2Vzc29yRmllbGRzKGZpZWxkKSB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihfKSB7IG1hcFtfXSA9IDE7IH0pO1xuICAgIH0gZWxzZSBpZiAoZmllbGQgIT0gbnVsbCkge1xuICAgICAgbWFwW2ZpZWxkICsgJyddID0gMTtcbiAgICB9XG4gICAgcmV0dXJuIG1hcDtcbiAgfSwge30pO1xuXG4gIHJldHVybiBhY2Nlc3NvcihmLCBPYmplY3Qua2V5cyhmaWVsZHMpKTtcbn07XG5cbnZhciBjb25zdGFudCA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIGlzRnVuY3Rpb24oXykgPyBfIDogZnVuY3Rpb24oKSB7IHJldHVybiBfOyB9O1xufTtcblxudmFyIGRlYm91bmNlID0gZnVuY3Rpb24oZGVsYXksIGhhbmRsZXIpIHtcbiAgdmFyIHRpZCwgZXZ0O1xuXG4gIGZ1bmN0aW9uIGNhbGxiYWNrKCkge1xuICAgIGhhbmRsZXIoZXZ0KTtcbiAgICB0aWQgPSBldnQgPSBudWxsO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGUpIHtcbiAgICBldnQgPSBlO1xuICAgIGlmICh0aWQpIGNsZWFyVGltZW91dCh0aWQpO1xuICAgIHRpZCA9IHNldFRpbWVvdXQoY2FsbGJhY2ssIGRlbGF5KTtcbiAgfTtcbn07XG5cbnZhciBleHRlbmQgPSBmdW5jdGlvbihfKSB7XG4gIGZvciAodmFyIHgsIGssIGk9MSwgbGVuPWFyZ3VtZW50cy5sZW5ndGg7IGk8bGVuOyArK2kpIHtcbiAgICB4ID0gYXJndW1lbnRzW2ldO1xuICAgIGZvciAoayBpbiB4KSB7IF9ba10gPSB4W2tdOyB9XG4gIH1cbiAgcmV0dXJuIF87XG59O1xuXG52YXIgZXh0ZW50SW5kZXggPSBmdW5jdGlvbihhcnJheSwgZikge1xuICB2YXIgaSA9IC0xLFxuICAgICAgbiA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGEsIGIsIGMsIHUsIHY7XG5cbiAgaWYgKGYgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBiID0gYXJyYXlbaV07XG4gICAgICBpZiAoYiAhPSBudWxsICYmIGIgPj0gYikge1xuICAgICAgICBhID0gYyA9IGI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICB1ID0gdiA9IGk7XG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIGIgPSBhcnJheVtpXTtcbiAgICAgIGlmIChiICE9IG51bGwpIHtcbiAgICAgICAgaWYgKGEgPiBiKSB7XG4gICAgICAgICAgYSA9IGI7XG4gICAgICAgICAgdSA9IGk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKGMgPCBiKSB7XG4gICAgICAgICAgYyA9IGI7XG4gICAgICAgICAgdiA9IGk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSk7XG4gICAgICBpZiAoYiAhPSBudWxsICYmIGIgPj0gYikge1xuICAgICAgICBhID0gYyA9IGI7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICB1ID0gdiA9IGk7XG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIGIgPSBmKGFycmF5W2ldLCBpLCBhcnJheSk7XG4gICAgICBpZiAoYiAhPSBudWxsKSB7XG4gICAgICAgIGlmIChhID4gYikge1xuICAgICAgICAgIGEgPSBiO1xuICAgICAgICAgIHUgPSBpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChjIDwgYikge1xuICAgICAgICAgIGMgPSBiO1xuICAgICAgICAgIHYgPSBpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIFt1LCB2XTtcbn07XG5cbnZhciBOVUxMID0ge307XG5cbnZhciBmYXN0bWFwID0gZnVuY3Rpb24oaW5wdXQpIHtcbiAgdmFyIG9iaiA9IHt9LFxuICAgICAgbWFwLFxuICAgICAgdGVzdDtcblxuICBmdW5jdGlvbiBoYXMoa2V5KSB7XG4gICAgcmV0dXJuIG9iai5oYXNPd25Qcm9wZXJ0eShrZXkpICYmIG9ialtrZXldICE9PSBOVUxMO1xuICB9XG5cbiAgbWFwID0ge1xuICAgIHNpemU6IDAsXG4gICAgZW1wdHk6IDAsXG4gICAgb2JqZWN0OiBvYmosXG4gICAgaGFzOiBoYXMsXG4gICAgZ2V0OiBmdW5jdGlvbihrZXkpIHtcbiAgICAgIHJldHVybiBoYXMoa2V5KSA/IG9ialtrZXldIDogdW5kZWZpbmVkO1xuICAgIH0sXG4gICAgc2V0OiBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgICBpZiAoIWhhcyhrZXkpKSB7XG4gICAgICAgICsrbWFwLnNpemU7XG4gICAgICAgIGlmIChvYmpba2V5XSA9PT0gTlVMTCkgLS1tYXAuZW1wdHk7XG4gICAgICB9XG4gICAgICBvYmpba2V5XSA9IHZhbHVlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBkZWxldGU6IGZ1bmN0aW9uKGtleSkge1xuICAgICAgaWYgKGhhcyhrZXkpKSB7XG4gICAgICAgIC0tbWFwLnNpemU7XG4gICAgICAgICsrbWFwLmVtcHR5O1xuICAgICAgICBvYmpba2V5XSA9IE5VTEw7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGNsZWFyOiBmdW5jdGlvbigpIHtcbiAgICAgIG1hcC5zaXplID0gbWFwLmVtcHR5ID0gMDtcbiAgICAgIG1hcC5vYmplY3QgPSBvYmogPSB7fTtcbiAgICB9LFxuICAgIHRlc3Q6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICAgIHRlc3QgPSBfO1xuICAgICAgICByZXR1cm4gbWFwO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIHRlc3Q7XG4gICAgICB9XG4gICAgfSxcbiAgICBjbGVhbjogZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgbmV4dCA9IHt9LFxuICAgICAgICAgIHNpemUgPSAwLFxuICAgICAgICAgIGtleSwgdmFsdWU7XG4gICAgICBmb3IgKGtleSBpbiBvYmopIHtcbiAgICAgICAgdmFsdWUgPSBvYmpba2V5XTtcbiAgICAgICAgaWYgKHZhbHVlICE9PSBOVUxMICYmICghdGVzdCB8fCAhdGVzdCh2YWx1ZSkpKSB7XG4gICAgICAgICAgbmV4dFtrZXldID0gdmFsdWU7XG4gICAgICAgICAgKytzaXplO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBtYXAuc2l6ZSA9IHNpemU7XG4gICAgICBtYXAuZW1wdHkgPSAwO1xuICAgICAgbWFwLm9iamVjdCA9IChvYmogPSBuZXh0KTtcbiAgICB9XG4gIH07XG5cbiAgaWYgKGlucHV0KSBPYmplY3Qua2V5cyhpbnB1dCkuZm9yRWFjaChmdW5jdGlvbihrZXkpIHtcbiAgICBtYXAuc2V0KGtleSwgaW5wdXRba2V5XSk7XG4gIH0pO1xuXG4gIHJldHVybiBtYXA7XG59O1xuXG52YXIgaW5oZXJpdHMgPSBmdW5jdGlvbihjaGlsZCwgcGFyZW50KSB7XG4gIHZhciBwcm90byA9IChjaGlsZC5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHBhcmVudC5wcm90b3R5cGUpKTtcbiAgcHJvdG8uY29uc3RydWN0b3IgPSBjaGlsZDtcbiAgcmV0dXJuIHByb3RvO1xufTtcblxudmFyIGlzQm9vbGVhbiA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIHR5cGVvZiBfID09PSAnYm9vbGVhbic7XG59O1xuXG52YXIgaXNEYXRlID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gT2JqZWN0LnByb3RvdHlwZS50b1N0cmluZy5jYWxsKF8pID09PSAnW29iamVjdCBEYXRlXSc7XG59O1xuXG52YXIgaXNOdW1iZXIgPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiB0eXBlb2YgXyA9PT0gJ251bWJlcic7XG59O1xuXG52YXIgaXNSZWdFeHAgPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBPYmplY3QucHJvdG90eXBlLnRvU3RyaW5nLmNhbGwoXykgPT09ICdbb2JqZWN0IFJlZ0V4cF0nO1xufTtcblxudmFyIGtleSA9IGZ1bmN0aW9uKGZpZWxkcywgZmxhdCkge1xuICBpZiAoZmllbGRzKSB7XG4gICAgZmllbGRzID0gZmxhdFxuICAgICAgPyBhcnJheShmaWVsZHMpLm1hcChmdW5jdGlvbihmKSB7IHJldHVybiBmLnJlcGxhY2UoL1xcXFwoLikvZywgJyQxJyk7IH0pXG4gICAgICA6IGFycmF5KGZpZWxkcyk7XG4gIH1cblxuICB2YXIgZm4gPSAhKGZpZWxkcyAmJiBmaWVsZHMubGVuZ3RoKVxuICAgID8gZnVuY3Rpb24oKSB7IHJldHVybiAnJzsgfVxuICAgIDogRnVuY3Rpb24oJ18nLCAncmV0dXJuIFxcJ1xcJysnICtcbiAgICAgICAgZmllbGRzLm1hcChmdW5jdGlvbihmKSB7XG4gICAgICAgICAgcmV0dXJuICdfWycgKyAoZmxhdFxuICAgICAgICAgICAgICA/ICQoZilcbiAgICAgICAgICAgICAgOiBzcGxpdEFjY2Vzc1BhdGgoZikubWFwKCQpLmpvaW4oJ11bJylcbiAgICAgICAgICAgICkgKyAnXSc7XG4gICAgICAgIH0pLmpvaW4oJytcXCd8XFwnKycpICsgJzsnKTtcblxuICByZXR1cm4gYWNjZXNzb3IoZm4sIGZpZWxkcywgJ2tleScpO1xufTtcblxudmFyIG1lcmdlID0gZnVuY3Rpb24oY29tcGFyZSwgYXJyYXkwLCBhcnJheTEsIG91dHB1dCkge1xuICB2YXIgbjAgPSBhcnJheTAubGVuZ3RoLFxuICAgICAgbjEgPSBhcnJheTEubGVuZ3RoO1xuXG4gIGlmICghbjEpIHJldHVybiBhcnJheTA7XG4gIGlmICghbjApIHJldHVybiBhcnJheTE7XG5cbiAgdmFyIG1lcmdlZCA9IG91dHB1dCB8fCBuZXcgYXJyYXkwLmNvbnN0cnVjdG9yKG4wICsgbjEpLFxuICAgICAgaTAgPSAwLCBpMSA9IDAsIGkgPSAwO1xuXG4gIGZvciAoOyBpMDxuMCAmJiBpMTxuMTsgKytpKSB7XG4gICAgbWVyZ2VkW2ldID0gY29tcGFyZShhcnJheTBbaTBdLCBhcnJheTFbaTFdKSA+IDBcbiAgICAgICA/IGFycmF5MVtpMSsrXVxuICAgICAgIDogYXJyYXkwW2kwKytdO1xuICB9XG5cbiAgZm9yICg7IGkwPG4wOyArK2kwLCArK2kpIHtcbiAgICBtZXJnZWRbaV0gPSBhcnJheTBbaTBdO1xuICB9XG5cbiAgZm9yICg7IGkxPG4xOyArK2kxLCArK2kpIHtcbiAgICBtZXJnZWRbaV0gPSBhcnJheTFbaTFdO1xuICB9XG5cbiAgcmV0dXJuIG1lcmdlZDtcbn07XG5cbnZhciByZXBlYXQgPSBmdW5jdGlvbihzdHIsIHJlcHMpIHtcbiAgdmFyIHMgPSAnJztcbiAgd2hpbGUgKC0tcmVwcyA+PSAwKSBzICs9IHN0cjtcbiAgcmV0dXJuIHM7XG59O1xuXG52YXIgcGFkID0gZnVuY3Rpb24oc3RyLCBsZW5ndGgsIHBhZGNoYXIsIGFsaWduKSB7XG4gIHZhciBjID0gcGFkY2hhciB8fCAnICcsXG4gICAgICBzID0gc3RyICsgJycsXG4gICAgICBuID0gbGVuZ3RoIC0gcy5sZW5ndGg7XG5cbiAgcmV0dXJuIG4gPD0gMCA/IHNcbiAgICA6IGFsaWduID09PSAnbGVmdCcgPyByZXBlYXQoYywgbikgKyBzXG4gICAgOiBhbGlnbiA9PT0gJ2NlbnRlcicgPyByZXBlYXQoYywgfn4obi8yKSkgKyBzICsgcmVwZWF0KGMsIE1hdGguY2VpbChuLzIpKVxuICAgIDogcyArIHJlcGVhdChjLCBuKTtcbn07XG5cbnZhciB0b0Jvb2xlYW4gPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBfID09IG51bGwgfHwgXyA9PT0gJycgPyBudWxsIDogIV8gfHwgXyA9PT0gJ2ZhbHNlJyB8fCBfID09PSAnMCcgPyBmYWxzZSA6ICEhXztcbn07XG5cbmZ1bmN0aW9uIGRlZmF1bHRQYXJzZXIoXykge1xuICByZXR1cm4gaXNOdW1iZXIoXykgPyBfIDogaXNEYXRlKF8pID8gXyA6IERhdGUucGFyc2UoXyk7XG59XG5cbnZhciB0b0RhdGUgPSBmdW5jdGlvbihfLCBwYXJzZXIpIHtcbiAgcGFyc2VyID0gcGFyc2VyIHx8IGRlZmF1bHRQYXJzZXI7XG4gIHJldHVybiBfID09IG51bGwgfHwgXyA9PT0gJycgPyBudWxsIDogcGFyc2VyKF8pO1xufTtcblxudmFyIHRvU3RyaW5nID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gXyA9PSBudWxsIHx8IF8gPT09ICcnID8gbnVsbCA6IF8gKyAnJztcbn07XG5cbnZhciB0b1NldCA9IGZ1bmN0aW9uKF8pIHtcbiAgZm9yICh2YXIgcz17fSwgaT0wLCBuPV8ubGVuZ3RoOyBpPG47ICsraSkgc1tfW2ldXSA9IHRydWU7XG4gIHJldHVybiBzO1xufTtcblxudmFyIHRydW5jYXRlID0gZnVuY3Rpb24oc3RyLCBsZW5ndGgsIGFsaWduLCBlbGxpcHNpcykge1xuICB2YXIgZSA9IGVsbGlwc2lzICE9IG51bGwgPyBlbGxpcHNpcyA6ICdcXHUyMDI2JyxcbiAgICAgIHMgPSBzdHIgKyAnJyxcbiAgICAgIG4gPSBzLmxlbmd0aCxcbiAgICAgIGwgPSBNYXRoLm1heCgwLCBsZW5ndGggLSBlLmxlbmd0aCk7XG5cbiAgcmV0dXJuIG4gPD0gbGVuZ3RoID8gc1xuICAgIDogYWxpZ24gPT09ICdsZWZ0JyA/IGUgKyBzLnNsaWNlKG4gLSBsKVxuICAgIDogYWxpZ24gPT09ICdjZW50ZXInID8gcy5zbGljZSgwLCBNYXRoLmNlaWwobC8yKSkgKyBlICsgcy5zbGljZShuIC0gfn4obC8yKSlcbiAgICA6IHMuc2xpY2UoMCwgbCkgKyBlO1xufTtcblxudmFyIHZpc2l0QXJyYXkgPSBmdW5jdGlvbihhcnJheSwgZmlsdGVyLCB2aXNpdG9yKSB7XG4gIGlmIChhcnJheSkge1xuICAgIHZhciBpID0gMCwgbiA9IGFycmF5Lmxlbmd0aCwgdDtcbiAgICBpZiAoZmlsdGVyKSB7XG4gICAgICBmb3IgKDsgaTxuOyArK2kpIHtcbiAgICAgICAgaWYgKHQgPSBmaWx0ZXIoYXJyYXlbaV0pKSB2aXNpdG9yKHQsIGksIGFycmF5KTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgYXJyYXkuZm9yRWFjaCh2aXNpdG9yKTtcbiAgICB9XG4gIH1cbn07XG5cbmZ1bmN0aW9uIFVuaXF1ZUxpc3QoaWRGdW5jKSB7XG4gIHZhciAkJCQxID0gaWRGdW5jIHx8IGlkZW50aXR5LFxuICAgICAgbGlzdCA9IFtdLFxuICAgICAgaWRzID0ge307XG5cbiAgbGlzdC5hZGQgPSBmdW5jdGlvbihfKSB7XG4gICAgdmFyIGlkJCQxID0gJCQkMShfKTtcbiAgICBpZiAoIWlkc1tpZCQkMV0pIHtcbiAgICAgIGlkc1tpZCQkMV0gPSAxO1xuICAgICAgbGlzdC5wdXNoKF8pO1xuICAgIH1cbiAgICByZXR1cm4gbGlzdDtcbiAgfTtcblxuICBsaXN0LnJlbW92ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICB2YXIgaWQkJDEgPSAkJCQxKF8pLCBpZHg7XG4gICAgaWYgKGlkc1tpZCQkMV0pIHtcbiAgICAgIGlkc1tpZCQkMV0gPSAwO1xuICAgICAgaWYgKChpZHggPSBsaXN0LmluZGV4T2YoXykpID49IDApIHtcbiAgICAgICAgbGlzdC5zcGxpY2UoaWR4LCAxKTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGxpc3Q7XG4gIH07XG5cbiAgcmV0dXJuIGxpc3Q7XG59XG5cbnZhciBUVVBMRV9JRF9LRVkgPSBTeW1ib2woJ3ZlZ2FfaWQnKTtcbnZhciBUVVBMRV9JRCA9IDE7XG5cbi8qKlxuICogUmVzZXRzIHRoZSBpbnRlcm5hbCB0dXBsZSBpZCBjb3VudGVyIHRvIG9uZS5cbiAqL1xuXG5cbi8qKlxuICogQ2hlY2tzIGlmIGFuIGlucHV0IHZhbHVlIGlzIGEgcmVnaXN0ZXJlZCB0dXBsZS5cbiAqIEBwYXJhbSB7Kn0gdCAtIFRoZSB2YWx1ZSB0byBjaGVjay5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IFRydWUgaWYgdGhlIGlucHV0IGlzIGEgdHVwbGUsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xuZnVuY3Rpb24gaXNUdXBsZSh0KSB7XG4gIHJldHVybiAhISh0ICYmIHR1cGxlaWQodCkpO1xufVxuXG4vKipcbiAqIFJldHVybnMgdGhlIGlkIG9mIGEgdHVwbGUuXG4gKiBAcGFyYW0ge29iamVjdH0gdCAtIFRoZSBpbnB1dCB0dXBsZS5cbiAqIEByZXR1cm4geyp9IHRoZSB0dXBsZSBpZC5cbiAqL1xuZnVuY3Rpb24gdHVwbGVpZCh0KSB7XG4gIHJldHVybiB0W1RVUExFX0lEX0tFWV07XG59XG5cbi8qKlxuICogU2V0cyB0aGUgaWQgb2YgYSB0dXBsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSB0IC0gVGhlIGlucHV0IHR1cGxlLlxuICogQHBhcmFtIHsqfSBpZCAtIFRoZSBpZCB2YWx1ZSB0byBzZXQuXG4gKiBAcmV0dXJuIHtvYmplY3R9IHRoZSBpbnB1dCB0dXBsZS5cbiAqL1xuZnVuY3Rpb24gc2V0aWQodCwgaWQpIHtcbiAgdFtUVVBMRV9JRF9LRVldID0gaWQ7XG4gIHJldHVybiB0O1xufVxuXG4vKipcbiAqIEluZ2VzdCBhbiBvYmplY3Qgb3IgdmFsdWUgYXMgYSBkYXRhIHR1cGxlLlxuICogSWYgdGhlIGlucHV0IHZhbHVlIGlzIGFuIG9iamVjdCwgYW4gaWQgZmllbGQgd2lsbCBiZSBhZGRlZCB0byBpdC4gRm9yXG4gKiBlZmZpY2llbmN5LCB0aGUgaW5wdXQgb2JqZWN0IGlzIG1vZGlmaWVkIGRpcmVjdGx5LiBBIGNvcHkgaXMgbm90IG1hZGUuXG4gKiBJZiB0aGUgaW5wdXQgdmFsdWUgaXMgYSBsaXRlcmFsLCBpdCB3aWxsIGJlIHdyYXBwZWQgaW4gYSBuZXcgb2JqZWN0XG4gKiBpbnN0YW5jZSwgd2l0aCB0aGUgdmFsdWUgYWNjZXNzaWJsZSBhcyB0aGUgJ2RhdGEnIHByb3BlcnR5LlxuICogQHBhcmFtIGRhdHVtIC0gVGhlIHZhbHVlIHRvIGluZ2VzdC5cbiAqIEByZXR1cm4ge29iamVjdH0gVGhlIGluZ2VzdGVkIGRhdGEgdHVwbGUuXG4gKi9cbmZ1bmN0aW9uIGluZ2VzdChkYXR1bSkge1xuICB2YXIgdCA9IChkYXR1bSA9PT0gT2JqZWN0KGRhdHVtKSkgPyBkYXR1bSA6IHtkYXRhOiBkYXR1bX07XG4gIHJldHVybiB0dXBsZWlkKHQpID8gdCA6IHNldGlkKHQsIFRVUExFX0lEKyspO1xufVxuXG4vKipcbiAqIEdpdmVuIGEgc291cmNlIHR1cGxlLCByZXR1cm4gYSBkZXJpdmVkIGNvcHkuXG4gKiBAcGFyYW0ge29iamVjdH0gdCAtIFRoZSBzb3VyY2UgdHVwbGUuXG4gKiBAcmV0dXJuIHtvYmplY3R9IFRoZSBkZXJpdmVkIHR1cGxlLlxuICovXG5mdW5jdGlvbiBkZXJpdmUodCkge1xuICByZXR1cm4gcmVkZXJpdmUodCwgaW5nZXN0KHt9KSk7XG59XG5cbi8qKlxuICogUmVkZXJpdmUgYSBkZXJpdmVkIHR1cGxlIGJ5IGNvcHlpbmcgdmFsdWVzIGZyb20gdGhlIHNvdXJjZSB0dXBsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSB0IC0gVGhlIHNvdXJjZSB0dXBsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBkIC0gVGhlIGRlcml2ZWQgdHVwbGUuXG4gKiBAcmV0dXJuIHtvYmplY3R9IFRoZSBkZXJpdmVkIHR1cGxlLlxuICovXG5mdW5jdGlvbiByZWRlcml2ZSh0LCBkKSB7XG4gIGZvciAodmFyIGsgaW4gdCkgZFtrXSA9IHRba107XG4gIHJldHVybiBkO1xufVxuXG4vKipcbiAqIFJlcGxhY2UgYW4gZXhpc3RpbmcgdHVwbGUgd2l0aCBhIG5ldyB0dXBsZS5cbiAqIEBwYXJhbSB7b2JqZWN0fSB0IC0gVGhlIGV4aXN0aW5nIGRhdGEgdHVwbGUuXG4gKiBAcGFyYW0ge29iamVjdH0gZCAtIFRoZSBuZXcgdHVwbGUgdGhhdCByZXBsYWNlcyB0aGUgb2xkLlxuICogQHJldHVybiB7b2JqZWN0fSBUaGUgbmV3IHR1cGxlLlxuICovXG5mdW5jdGlvbiByZXBsYWNlKHQsIGQpIHtcbiAgcmV0dXJuIHNldGlkKGQsIHR1cGxlaWQodCkpO1xufVxuXG5mdW5jdGlvbiBpc0NoYW5nZVNldCh2KSB7XG4gIHJldHVybiB2ICYmIHYuY29uc3RydWN0b3IgPT09IGNoYW5nZXNldDtcbn1cblxuZnVuY3Rpb24gY2hhbmdlc2V0KCkge1xuICB2YXIgYWRkID0gW10sICAvLyBpbnNlcnQgdHVwbGVzXG4gICAgICByZW0gPSBbXSwgIC8vIHJlbW92ZSB0dXBsZXNcbiAgICAgIG1vZCA9IFtdLCAgLy8gbW9kaWZ5IHR1cGxlc1xuICAgICAgcmVtcCA9IFtdLCAvLyByZW1vdmUgYnkgcHJlZGljYXRlXG4gICAgICBtb2RwID0gW10sIC8vIG1vZGlmeSBieSBwcmVkaWNhdGVcbiAgICAgIHJlZmxvdyA9IGZhbHNlO1xuXG4gIHJldHVybiB7XG4gICAgY29uc3RydWN0b3I6IGNoYW5nZXNldCxcbiAgICBpbnNlcnQ6IGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBkID0gYXJyYXkodCksIGkgPSAwLCBuID0gZC5sZW5ndGg7XG4gICAgICBmb3IgKDsgaTxuOyArK2kpIGFkZC5wdXNoKGRbaV0pO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBhID0gaXNGdW5jdGlvbih0KSA/IHJlbXAgOiByZW0sXG4gICAgICAgICAgZCA9IGFycmF5KHQpLCBpID0gMCwgbiA9IGQubGVuZ3RoO1xuICAgICAgZm9yICg7IGk8bjsgKytpKSBhLnB1c2goZFtpXSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIG1vZGlmeTogZnVuY3Rpb24odCwgZmllbGQkJDEsIHZhbHVlKSB7XG4gICAgICB2YXIgbSA9IHtmaWVsZDogZmllbGQkJDEsIHZhbHVlOiBjb25zdGFudCh2YWx1ZSl9O1xuICAgICAgaWYgKGlzRnVuY3Rpb24odCkpIHtcbiAgICAgICAgbS5maWx0ZXIgPSB0O1xuICAgICAgICBtb2RwLnB1c2gobSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtLnR1cGxlID0gdDtcbiAgICAgICAgbW9kLnB1c2gobSk7XG4gICAgICB9XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIGVuY29kZTogZnVuY3Rpb24odCwgc2V0KSB7XG4gICAgICBpZiAoaXNGdW5jdGlvbih0KSkgbW9kcC5wdXNoKHtmaWx0ZXI6IHQsIGZpZWxkOiBzZXR9KTtcbiAgICAgIGVsc2UgbW9kLnB1c2goe3R1cGxlOiB0LCBmaWVsZDogc2V0fSk7XG4gICAgICByZXR1cm4gdGhpcztcbiAgICB9LFxuICAgIHJlZmxvdzogZnVuY3Rpb24oKSB7XG4gICAgICByZWZsb3cgPSB0cnVlO1xuICAgICAgcmV0dXJuIHRoaXM7XG4gICAgfSxcbiAgICBwdWxzZTogZnVuY3Rpb24ocHVsc2UsIHR1cGxlcykge1xuICAgICAgdmFyIG91dCwgaSwgbiwgbSwgZiwgdCwgaWQkJDE7XG5cbiAgICAgIC8vIGFkZFxuICAgICAgZm9yIChpPTAsIG49YWRkLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgICAgcHVsc2UuYWRkLnB1c2goaW5nZXN0KGFkZFtpXSkpO1xuICAgICAgfVxuXG4gICAgICAvLyByZW1vdmVcbiAgICAgIGZvciAob3V0PXt9LCBpPTAsIG49cmVtLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgICAgdCA9IHJlbVtpXTtcbiAgICAgICAgb3V0W3R1cGxlaWQodCldID0gdDtcbiAgICAgIH1cbiAgICAgIGZvciAoaT0wLCBuPXJlbXAubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgICBmID0gcmVtcFtpXTtcbiAgICAgICAgdHVwbGVzLmZvckVhY2goZnVuY3Rpb24odCkge1xuICAgICAgICAgIGlmIChmKHQpKSBvdXRbdHVwbGVpZCh0KV0gPSB0O1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICAgIGZvciAoaWQkJDEgaW4gb3V0KSBwdWxzZS5yZW0ucHVzaChvdXRbaWQkJDFdKTtcblxuICAgICAgLy8gbW9kaWZ5XG4gICAgICBmdW5jdGlvbiBtb2RpZnkodCwgZiwgdikge1xuICAgICAgICBpZiAodikgdFtmXSA9IHYodCk7IGVsc2UgcHVsc2UuZW5jb2RlID0gZjtcbiAgICAgICAgaWYgKCFyZWZsb3cpIG91dFt0dXBsZWlkKHQpXSA9IHQ7XG4gICAgICB9XG4gICAgICBmb3IgKG91dD17fSwgaT0wLCBuPW1vZC5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgICAgIG0gPSBtb2RbaV07XG4gICAgICAgIG1vZGlmeShtLnR1cGxlLCBtLmZpZWxkLCBtLnZhbHVlKTtcbiAgICAgICAgcHVsc2UubW9kaWZpZXMobS5maWVsZCk7XG4gICAgICB9XG4gICAgICBmb3IgKGk9MCwgbj1tb2RwLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgICAgbSA9IG1vZHBbaV07XG4gICAgICAgIGYgPSBtLmZpbHRlcjtcbiAgICAgICAgdHVwbGVzLmZvckVhY2goZnVuY3Rpb24odCkge1xuICAgICAgICAgIGlmIChmKHQpKSBtb2RpZnkodCwgbS5maWVsZCwgbS52YWx1ZSk7XG4gICAgICAgIH0pO1xuICAgICAgICBwdWxzZS5tb2RpZmllcyhtLmZpZWxkKTtcbiAgICAgIH1cblxuICAgICAgLy8gcmVmbG93P1xuICAgICAgaWYgKHJlZmxvdykge1xuICAgICAgICBwdWxzZS5tb2QgPSByZW0ubGVuZ3RoIHx8IHJlbXAubGVuZ3RoXG4gICAgICAgICAgPyB0dXBsZXMuZmlsdGVyKGZ1bmN0aW9uKHQpIHsgcmV0dXJuIG91dC5oYXNPd25Qcm9wZXJ0eSh0dXBsZWlkKHQpKTsgfSlcbiAgICAgICAgICA6IHR1cGxlcy5zbGljZSgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZm9yIChpZCQkMSBpbiBvdXQpIHB1bHNlLm1vZC5wdXNoKG91dFtpZCQkMV0pO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gcHVsc2U7XG4gICAgfVxuICB9O1xufVxuXG52YXIgQ0FDSEUgPSAnXzptb2Q6Xyc7XG5cbi8qKlxuICogSGFzaCB0aGF0IHRyYWNrcyBtb2RpZmljYXRpb25zIHRvIGFzc2lnbmVkIHZhbHVlcy5cbiAqIENhbGxlcnMgKm11c3QqIHVzZSB0aGUgc2V0IG1ldGhvZCB0byB1cGRhdGUgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBQYXJhbWV0ZXJzKCkge1xuICBPYmplY3QuZGVmaW5lUHJvcGVydHkodGhpcywgQ0FDSEUsIHt3cml0YWJsZTp0cnVlLCB2YWx1ZToge319KTtcbn1cblxudmFyIHByb3RvdHlwZSQyID0gUGFyYW1ldGVycy5wcm90b3R5cGU7XG5cbi8qKlxuICogU2V0IGEgcGFyYW1ldGVyIHZhbHVlLiBJZiB0aGUgcGFyYW1ldGVyIHZhbHVlIGNoYW5nZXMsIHRoZSBwYXJhbWV0ZXJcbiAqIHdpbGwgYmUgcmVjb3JkZWQgYXMgbW9kaWZpZWQuXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBwYXJhbWV0ZXIgbmFtZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBpbmRleCAtIFRoZSBpbmRleCBpbnRvIGFuIGFycmF5LXZhbHVlIHBhcmFtZXRlci4gSWdub3JlZCBpZlxuICogICB0aGUgYXJndW1lbnQgaXMgdW5kZWZpbmVkLCBudWxsIG9yIGxlc3MgdGhhbiB6ZXJvLlxuICogQHBhcmFtIHsqfSB2YWx1ZSAtIFRoZSBwYXJhbWV0ZXIgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHtib29sZWFufSBbZm9yY2U9ZmFsc2VdIC0gSWYgdHJ1ZSwgcmVjb3JkcyB0aGUgcGFyYW1ldGVyIGFzIG1vZGlmaWVkXG4gKiAgIGV2ZW4gaWYgdGhlIHZhbHVlIGlzIHVuY2hhbmdlZC5cbiAqIEByZXR1cm4ge1BhcmFtZXRlcnN9IC0gVGhpcyBwYXJhbWV0ZXIgb2JqZWN0LlxuICovXG5wcm90b3R5cGUkMi5zZXQgPSBmdW5jdGlvbihuYW1lLCBpbmRleCwgdmFsdWUsIGZvcmNlKSB7XG4gIHZhciBvID0gdGhpcyxcbiAgICAgIHYgPSBvW25hbWVdLFxuICAgICAgbW9kID0gb1tDQUNIRV07XG5cbiAgaWYgKGluZGV4ICE9IG51bGwgJiYgaW5kZXggPj0gMCkge1xuICAgIGlmICh2W2luZGV4XSAhPT0gdmFsdWUgfHwgZm9yY2UpIHtcbiAgICAgIHZbaW5kZXhdID0gdmFsdWU7XG4gICAgICBtb2RbaW5kZXggKyAnOicgKyBuYW1lXSA9IC0xO1xuICAgICAgbW9kW25hbWVdID0gLTE7XG4gICAgfVxuICB9IGVsc2UgaWYgKHYgIT09IHZhbHVlIHx8IGZvcmNlKSB7XG4gICAgb1tuYW1lXSA9IHZhbHVlO1xuICAgIG1vZFtuYW1lXSA9IGlzQXJyYXkodmFsdWUpID8gMSArIHZhbHVlLmxlbmd0aCA6IC0xO1xuICB9XG5cbiAgcmV0dXJuIG87XG59O1xuXG4vKipcbiAqIFRlc3RzIGlmIG9uZSBvciBtb3JlIHBhcmFtZXRlcnMgaGFzIGJlZW4gbW9kaWZpZWQuIElmIGludm9rZWQgd2l0aCBub1xuICogYXJndW1lbnRzLCByZXR1cm5zIHRydWUgaWYgYW55IHBhcmFtZXRlciB2YWx1ZSBoYXMgY2hhbmdlZC4gSWYgdGhlIGZpcnN0XG4gKiBhcmd1bWVudCBpcyBhcnJheSwgcmV0dXJucyB0cnVlcyBpZiBhbnkgcGFyYW1ldGVyIG5hbWUgaW4gdGhlIGFycmF5IGhhc1xuICogY2hhbmdlZC4gT3RoZXJ3aXNlLCB0ZXN0cyBpZiB0aGUgZ2l2ZW4gbmFtZSBhbmQgb3B0aW9uYWwgYXJyYXkgaW5kZXggaGFzXG4gKiBjaGFuZ2VkLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgcGFyYW1ldGVyIG5hbWUgdG8gdGVzdC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbaW5kZXg9dW5kZWZpbmVkXSAtIFRoZSBwYXJhbWV0ZXIgYXJyYXkgaW5kZXggdG8gdGVzdC5cbiAqIEByZXR1cm4ge2Jvb2xlYW59IC0gUmV0dXJucyB0cnVlIGlmIGEgcXVlcmllZCBwYXJhbWV0ZXIgd2FzIG1vZGlmaWVkLlxuICovXG5wcm90b3R5cGUkMi5tb2RpZmllZCA9IGZ1bmN0aW9uKG5hbWUsIGluZGV4KSB7XG4gIHZhciBtb2QgPSB0aGlzW0NBQ0hFXSwgaztcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgZm9yIChrIGluIG1vZCkgeyBpZiAobW9kW2tdKSByZXR1cm4gdHJ1ZTsgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfSBlbHNlIGlmIChpc0FycmF5KG5hbWUpKSB7XG4gICAgZm9yIChrPTA7IGs8bmFtZS5sZW5ndGg7ICsraykge1xuICAgICAgaWYgKG1vZFtuYW1lW2tdXSkgcmV0dXJuIHRydWU7XG4gICAgfVxuICAgIHJldHVybiBmYWxzZTtcbiAgfVxuICByZXR1cm4gKGluZGV4ICE9IG51bGwgJiYgaW5kZXggPj0gMClcbiAgICA/IChpbmRleCArIDEgPCBtb2RbbmFtZV0gfHwgISFtb2RbaW5kZXggKyAnOicgKyBuYW1lXSlcbiAgICA6ICEhbW9kW25hbWVdO1xufTtcblxuLyoqXG4gKiBDbGVhcnMgdGhlIG1vZGlmaWNhdGlvbiByZWNvcmRzLiBBZnRlciBjYWxsaW5nIHRoaXMgbWV0aG9kLFxuICogYWxsIHBhcmFtZXRlcnMgYXJlIGNvbnNpZGVyZWQgdW5tb2RpZmllZC5cbiAqL1xucHJvdG90eXBlJDIuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgdGhpc1tDQUNIRV0gPSB7fTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgT1BfSUQgPSAwO1xudmFyIFBVTFNFID0gJ3B1bHNlJztcbnZhciBOT19QQVJBTVMgPSBuZXcgUGFyYW1ldGVycygpO1xuXG4vLyBCb29sZWFuIEZsYWdzXG52YXIgU0tJUCAgICAgPSAxO1xudmFyIE1PRElGSUVEID0gMjtcblxuLyoqXG4gKiBBbiBPcGVyYXRvciBpcyBhIHByb2Nlc3Npbmcgbm9kZSBpbiBhIGRhdGFmbG93IGdyYXBoLlxuICogRWFjaCBvcGVyYXRvciBzdG9yZXMgYSB2YWx1ZSBhbmQgYW4gb3B0aW9uYWwgdmFsdWUgdXBkYXRlIGZ1bmN0aW9uLlxuICogT3BlcmF0b3JzIGNhbiBhY2NlcHQgYSBoYXNoIG9mIG5hbWVkIHBhcmFtZXRlcnMuIFBhcmFtZXRlciB2YWx1ZXMgY2FuXG4gKiBlaXRoZXIgYmUgZGlyZWN0IChKYXZhU2NyaXB0IGxpdGVyYWxzLCBhcnJheXMsIG9iamVjdHMpIG9yIGluZGlyZWN0XG4gKiAob3RoZXIgb3BlcmF0b3JzIHdob3NlIHZhbHVlcyB3aWxsIGJlIHB1bGxlZCBkeW5hbWljYWxseSkuIE9wZXJhdG9yc1xuICogaW5jbHVkZWQgYXMgcGFyYW1ldGVycyB3aWxsIGhhdmUgdGhpcyBvcGVyYXRvciBhZGRlZCBhcyBhIGRlcGVuZGVuY3kuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7Kn0gW2luaXRdIC0gVGhlIGluaXRpYWwgdmFsdWUgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCwgUHVsc2UpfSBbdXBkYXRlXSAtIEFuIHVwZGF0ZSBmdW5jdGlvbi4gVXBvblxuICogICBldmFsdWF0aW9uIG9mIHRoaXMgb3BlcmF0b3IsIHRoZSB1cGRhdGUgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIGFuZCB0aGVcbiAqICAgcmV0dXJuIHZhbHVlIHdpbGwgYmUgdXNlZCBhcyB0aGUgbmV3IHZhbHVlIG9mIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge29iamVjdH0gW3BhcmFtc10gLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlYWN0PXRydWVdIC0gRmxhZyBpbmRpY2F0aW5nIGlmIHRoaXMgb3BlcmF0b3Igc2hvdWxkXG4gKiAgIGxpc3RlbiBmb3IgY2hhbmdlcyB0byB1cHN0cmVhbSBvcGVyYXRvcnMgaW5jbHVkZWQgYXMgcGFyYW1ldGVycy5cbiAqIEBzZWUgcGFyYW1ldGVyc1xuICovXG5mdW5jdGlvbiBPcGVyYXRvcihpbml0LCB1cGRhdGUsIHBhcmFtcywgcmVhY3QpIHtcbiAgdGhpcy5pZCA9ICsrT1BfSUQ7XG4gIHRoaXMudmFsdWUgPSBpbml0O1xuICB0aGlzLnN0YW1wID0gLTE7XG4gIHRoaXMucmFuayA9IC0xO1xuICB0aGlzLnFyYW5rID0gLTE7XG4gIHRoaXMuZmxhZ3MgPSAwO1xuXG4gIGlmICh1cGRhdGUpIHtcbiAgICB0aGlzLl91cGRhdGUgPSB1cGRhdGU7XG4gIH1cbiAgaWYgKHBhcmFtcykgdGhpcy5wYXJhbWV0ZXJzKHBhcmFtcywgcmVhY3QpO1xufVxuXG52YXIgcHJvdG90eXBlJDEgPSBPcGVyYXRvci5wcm90b3R5cGU7XG5cbi8qKlxuICogUmV0dXJucyBhIGxpc3Qgb2YgdGFyZ2V0IG9wZXJhdG9ycyBkZXBlbmRlbnQgb24gdGhpcyBvcGVyYXRvci5cbiAqIElmIHRoaXMgbGlzdCBkb2VzIG5vdCBleGlzdCwgaXQgaXMgY3JlYXRlZCBhbmQgdGhlbiByZXR1cm5lZC5cbiAqIEByZXR1cm4ge1VuaXF1ZUxpc3R9XG4gKi9cbnByb3RvdHlwZSQxLnRhcmdldHMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3RhcmdldHMgfHwgKHRoaXMuX3RhcmdldHMgPSBVbmlxdWVMaXN0KGlkKSk7XG59O1xuXG4vKipcbiAqIFNldHMgdGhlIHZhbHVlIG9mIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0geyp9IHZhbHVlIC0gdGhlIHZhbHVlIHRvIHNldC5cbiAqIEByZXR1cm4ge051bWJlcn0gUmV0dXJucyAxIGlmIHRoZSBvcGVyYXRvciB2YWx1ZSBoYXMgY2hhbmdlZFxuICogICBhY2NvcmRpbmcgdG8gc3RyaWN0IGVxdWFsaXR5LCByZXR1cm5zIDAgb3RoZXJ3aXNlLlxuICovXG5wcm90b3R5cGUkMS5zZXQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICBpZiAodGhpcy52YWx1ZSAhPT0gdmFsdWUpIHtcbiAgICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGZsYWcoYml0KSB7XG4gIHJldHVybiBmdW5jdGlvbihzdGF0ZSkge1xuICAgIHZhciBmID0gdGhpcy5mbGFncztcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA9PT0gMCkgcmV0dXJuICEhKGYgJiBiaXQpO1xuICAgIHRoaXMuZmxhZ3MgPSBzdGF0ZSA/IChmIHwgYml0KSA6IChmICYgfmJpdCk7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH07XG59XG5cbi8qKlxuICogSW5kaWNhdGVzIHRoYXQgb3BlcmF0b3IgZXZhbHVhdGlvbiBzaG91bGQgYmUgc2tpcHBlZCBvbiB0aGUgbmV4dCBwdWxzZS5cbiAqIFRoaXMgb3BlcmF0b3Igd2lsbCBzdGlsbCBwcm9wYWdhdGUgaW5jb21pbmcgcHVsc2VzLCBidXQgaXRzIHVwZGF0ZSBmdW5jdGlvblxuICogd2lsbCBub3QgYmUgaW52b2tlZC4gVGhlIHNraXAgZmxhZyBpcyByZXNldCBhZnRlciBldmVyeSBwdWxzZSwgc28gY2FsbGluZ1xuICogdGhpcyBtZXRob2Qgd2lsbCBhZmZlY3QgcHJvY2Vzc2luZyBvZiB0aGUgbmV4dCBwdWxzZSBvbmx5LlxuICovXG5wcm90b3R5cGUkMS5za2lwID0gZmxhZyhTS0lQKTtcblxuLyoqXG4gKiBJbmRpY2F0ZXMgdGhhdCB0aGlzIG9wZXJhdG9yJ3MgdmFsdWUgaGFzIGJlZW4gbW9kaWZpZWQgb24gaXRzIG1vc3QgcmVjZW50XG4gKiBwdWxzZS4gTm9ybWFsbHkgbW9kaWZpY2F0aW9uIGlzIGNoZWNrZWQgdmlhIHN0cmljdCBlcXVhbGl0eTsgaG93ZXZlciwgaW5cbiAqIHNvbWUgY2FzZXMgaXQgaXMgbW9yZSBlZmZpY2llbnQgdG8gdXBkYXRlIHRoZSBpbnRlcm5hbCBzdGF0ZSBvZiBhbiBvYmplY3QuXG4gKiBJbiB0aG9zZSBjYXNlcywgdGhlIG1vZGlmaWVkIGZsYWcgY2FuIGJlIHVzZWQgdG8gdHJpZ2dlciBwcm9wYWdhdGlvbi4gT25jZVxuICogc2V0LCB0aGUgbW9kaWZpY2F0aW9uIGZsYWcgcGVyc2lzdHMgYWNyb3NzIHB1bHNlcyB1bnRpbCB1bnNldC4gVGhlIGZsYWcgY2FuXG4gKiBiZSB1c2VkIHdpdGggdGhlIGxhc3QgdGltZXN0YW1wIHRvIHRlc3QgaWYgYSBtb2RpZmljYXRpb24gaXMgcmVjZW50LlxuICovXG5wcm90b3R5cGUkMS5tb2RpZmllZCA9IGZsYWcoTU9ESUZJRUQpO1xuXG4vKipcbiAqIFNldHMgdGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuIFRoZSBwYXJhbWV0ZXIgdmFsdWVzIGFyZSBhbmFseXplZCBmb3JcbiAqIG9wZXJhdG9yIGluc3RhbmNlcy4gSWYgZm91bmQsIHRoaXMgb3BlcmF0b3Igd2lsbCBiZSBhZGRlZCBhcyBhIGRlcGVuZGVuY3lcbiAqIG9mIHRoZSBwYXJhbWV0ZXJpemluZyBvcGVyYXRvci4gT3BlcmF0b3IgdmFsdWVzIGFyZSBkeW5hbWljYWxseSBtYXJzaGFsbGVkXG4gKiBmcm9tIGVhY2ggb3BlcmF0b3IgcGFyYW1ldGVyIHByaW9yIHRvIGV2YWx1YXRpb24uIElmIGEgcGFyYW1ldGVyIHZhbHVlIGlzXG4gKiBhbiBhcnJheSwgdGhlIGFycmF5IHdpbGwgYWxzbyBiZSBzZWFyY2hlZCBmb3IgT3BlcmF0b3IgaW5zdGFuY2VzLiBIb3dldmVyLFxuICogdGhlIHNlYXJjaCBkb2VzIG5vdCByZWN1cnNlIGludG8gc3ViLWFycmF5cyBvciBvYmplY3QgcHJvcGVydGllcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBBIGhhc2ggb2Ygb3BlcmF0b3IgcGFyYW1ldGVycy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3JlYWN0PXRydWVdIC0gQSBmbGFnIGluZGljYXRpbmcgaWYgdGhpcyBvcGVyYXRvciBzaG91bGRcbiAqICAgYXV0b21hdGljYWxseSB1cGRhdGUgKHJlYWN0KSB3aGVuIHBhcmFtZXRlciB2YWx1ZXMgY2hhbmdlLiBJbiBvdGhlciB3b3JkcyxcbiAqICAgdGhpcyBmbGFnIGRldGVybWluZXMgaWYgdGhlIG9wZXJhdG9yIHJlZ2lzdGVycyBpdHNlbGYgYXMgYSBsaXN0ZW5lciBvblxuICogICBhbnkgdXBzdHJlYW0gb3BlcmF0b3JzIGluY2x1ZGVkIGluIHRoZSBwYXJhbWV0ZXJzLlxuICogQHJldHVybiB7T3BlcmF0b3JbXX0gLSBBbiBhcnJheSBvZiB1cHN0cmVhbSBkZXBlbmRlbmNpZXMuXG4gKi9cbnByb3RvdHlwZSQxLnBhcmFtZXRlcnMgPSBmdW5jdGlvbihwYXJhbXMsIHJlYWN0KSB7XG4gIHJlYWN0ID0gcmVhY3QgIT09IGZhbHNlO1xuICB2YXIgc2VsZiA9IHRoaXMsXG4gICAgICBhcmd2YWwgPSAoc2VsZi5fYXJndmFsID0gc2VsZi5fYXJndmFsIHx8IG5ldyBQYXJhbWV0ZXJzKCkpLFxuICAgICAgYXJnb3BzID0gKHNlbGYuX2FyZ29wcyA9IHNlbGYuX2FyZ29wcyB8fCBbXSksXG4gICAgICBkZXBzID0gW10sXG4gICAgICBuYW1lLCB2YWx1ZSwgbiwgaTtcblxuICBmdW5jdGlvbiBhZGQobmFtZSwgaW5kZXgsIHZhbHVlKSB7XG4gICAgaWYgKHZhbHVlIGluc3RhbmNlb2YgT3BlcmF0b3IpIHtcbiAgICAgIGlmICh2YWx1ZSAhPT0gc2VsZikge1xuICAgICAgICBpZiAocmVhY3QpIHZhbHVlLnRhcmdldHMoKS5hZGQoc2VsZik7XG4gICAgICAgIGRlcHMucHVzaCh2YWx1ZSk7XG4gICAgICB9XG4gICAgICBhcmdvcHMucHVzaCh7b3A6dmFsdWUsIG5hbWU6bmFtZSwgaW5kZXg6aW5kZXh9KTtcbiAgICB9IGVsc2Uge1xuICAgICAgYXJndmFsLnNldChuYW1lLCBpbmRleCwgdmFsdWUpO1xuICAgIH1cbiAgfVxuXG4gIGZvciAobmFtZSBpbiBwYXJhbXMpIHtcbiAgICB2YWx1ZSA9IHBhcmFtc1tuYW1lXTtcblxuICAgIGlmIChuYW1lID09PSBQVUxTRSkge1xuICAgICAgYXJyYXkodmFsdWUpLmZvckVhY2goZnVuY3Rpb24ob3ApIHtcbiAgICAgICAgaWYgKCEob3AgaW5zdGFuY2VvZiBPcGVyYXRvcikpIHtcbiAgICAgICAgICBlcnJvciQxKCdQdWxzZSBwYXJhbWV0ZXJzIG11c3QgYmUgb3BlcmF0b3IgaW5zdGFuY2VzLicpO1xuICAgICAgICB9IGVsc2UgaWYgKG9wICE9PSBzZWxmKSB7XG4gICAgICAgICAgb3AudGFyZ2V0cygpLmFkZChzZWxmKTtcbiAgICAgICAgICBkZXBzLnB1c2gob3ApO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICAgIHNlbGYuc291cmNlID0gdmFsdWU7XG4gICAgfSBlbHNlIGlmIChpc0FycmF5KHZhbHVlKSkge1xuICAgICAgYXJndmFsLnNldChuYW1lLCAtMSwgQXJyYXkobiA9IHZhbHVlLmxlbmd0aCkpO1xuICAgICAgZm9yIChpPTA7IGk8bjsgKytpKSBhZGQobmFtZSwgaSwgdmFsdWVbaV0pO1xuICAgIH0gZWxzZSB7XG4gICAgICBhZGQobmFtZSwgLTEsIHZhbHVlKTtcbiAgICB9XG4gIH1cblxuICB0aGlzLm1hcnNoYWxsKCkuY2xlYXIoKTsgLy8gaW5pdGlhbGl6ZSB2YWx1ZXNcbiAgcmV0dXJuIGRlcHM7XG59O1xuXG4vKipcbiAqIEludGVybmFsIG1ldGhvZCBmb3IgbWFyc2hhbGxpbmcgcGFyYW1ldGVyIHZhbHVlcy5cbiAqIFZpc2l0cyBlYWNoIG9wZXJhdG9yIGRlcGVuZGVuY3kgdG8gcHVsbCB0aGUgbGF0ZXN0IHZhbHVlLlxuICogQHJldHVybiB7UGFyYW1ldGVyc30gQSBQYXJhbWV0ZXJzIG9iamVjdCB0byBwYXNzIHRvIHRoZSB1cGRhdGUgZnVuY3Rpb24uXG4gKi9cbnByb3RvdHlwZSQxLm1hcnNoYWxsID0gZnVuY3Rpb24oc3RhbXApIHtcbiAgdmFyIGFyZ3ZhbCA9IHRoaXMuX2FyZ3ZhbCB8fCBOT19QQVJBTVMsXG4gICAgICBhcmdvcHMgPSB0aGlzLl9hcmdvcHMsIGl0ZW0sIGksIG4sIG9wLCBtb2Q7XG5cbiAgaWYgKGFyZ29wcyAmJiAobiA9IGFyZ29wcy5sZW5ndGgpKSB7XG4gICAgZm9yIChpPTA7IGk8bjsgKytpKSB7XG4gICAgICBpdGVtID0gYXJnb3BzW2ldO1xuICAgICAgb3AgPSBpdGVtLm9wO1xuICAgICAgbW9kID0gb3AubW9kaWZpZWQoKSAmJiBvcC5zdGFtcCA9PT0gc3RhbXA7XG4gICAgICBhcmd2YWwuc2V0KGl0ZW0ubmFtZSwgaXRlbS5pbmRleCwgb3AudmFsdWUsIG1vZCk7XG4gICAgfVxuICB9XG4gIHJldHVybiBhcmd2YWw7XG59O1xuXG4vKipcbiAqIERlbGVnYXRlIG1ldGhvZCB0byBwZXJmb3JtIG9wZXJhdG9yIHByb2Nlc3NpbmcuXG4gKiBTdWJjbGFzc2VzIGNhbiBvdmVycmlkZSB0aGlzIG1ldGhvZCB0byBwZXJmb3JtIGN1c3RvbSBwcm9jZXNzaW5nLlxuICogQnkgZGVmYXVsdCwgaXQgbWFyc2hhbGxzIHBhcmFtZXRlcnMgYW5kIGNhbGxzIHRoZSB1cGRhdGUgZnVuY3Rpb25cbiAqIGlmIHRoYXQgZnVuY3Rpb24gaXMgZGVmaW5lZC4gSWYgdGhlIHVwZGF0ZSBmdW5jdGlvbiBkb2VzIG5vdFxuICogY2hhbmdlIHRoZSBvcGVyYXRvciB2YWx1ZSB0aGVuIFN0b3BQcm9wYWdhdGlvbiBpcyByZXR1cm5lZC5cbiAqIElmIG5vIHVwZGF0ZSBmdW5jdGlvbiBpcyBkZWZpbmVkLCB0aGlzIG1ldGhvZCBkb2VzIG5vdGhpbmcuXG4gKiBAcGFyYW0ge1B1bHNlfSBwdWxzZSAtIHRoZSBjdXJyZW50IGRhdGFmbG93IHB1bHNlLlxuICogQHJldHVybiBUaGUgb3V0cHV0IHB1bHNlIG9yIFN0b3BQcm9wYWdhdGlvbi4gQSBmYWxzeSByZXR1cm4gdmFsdWVcbiAqICAgKGluY2x1ZGluZyB1bmRlZmluZWQpIHdpbGwgbGV0IHRoZSBpbnB1dCBwdWxzZSBwYXNzIHRocm91Z2guXG4gKi9cbnByb3RvdHlwZSQxLmV2YWx1YXRlID0gZnVuY3Rpb24ocHVsc2UpIHtcbiAgaWYgKHRoaXMuX3VwZGF0ZSkge1xuICAgIHZhciBwYXJhbXMgPSB0aGlzLm1hcnNoYWxsKHB1bHNlLnN0YW1wKSxcbiAgICAgICAgdiA9IHRoaXMuX3VwZGF0ZShwYXJhbXMsIHB1bHNlKTtcblxuICAgIHBhcmFtcy5jbGVhcigpO1xuICAgIGlmICh2ICE9PSB0aGlzLnZhbHVlKSB7XG4gICAgICB0aGlzLnZhbHVlID0gdjtcbiAgICB9IGVsc2UgaWYgKCF0aGlzLm1vZGlmaWVkKCkpIHtcbiAgICAgIHJldHVybiBwdWxzZS5TdG9wUHJvcGFnYXRpb247XG4gICAgfVxuICB9XG59O1xuXG4vKipcbiAqIFJ1biB0aGlzIG9wZXJhdG9yIGZvciB0aGUgY3VycmVudCBwdWxzZS4gSWYgdGhpcyBvcGVyYXRvciBoYXMgYWxyZWFkeVxuICogYmVlbiBydW4gYXQgKG9yIGFmdGVyKSB0aGUgcHVsc2UgdGltZXN0YW1wLCByZXR1cm5zIFN0b3BQcm9wYWdhdGlvbi5cbiAqIEludGVybmFsbHksIHRoaXMgbWV0aG9kIGNhbGxzIHtAbGluayBldmFsdWF0ZX0gdG8gcGVyZm9ybSBwcm9jZXNzaW5nLlxuICogSWYge0BsaW5rIGV2YWx1YXRlfSByZXR1cm5zIGEgZmFsc3kgdmFsdWUsIHRoZSBpbnB1dCBwdWxzZSBpcyByZXR1cm5lZC5cbiAqIFRoaXMgbWV0aG9kIHNob3VsZCBOT1QgYmUgb3ZlcnJpZGRlbiwgaW5zdGVhZCBvdmVycnJpZGUge0BsaW5rIGV2YWx1YXRlfS5cbiAqIEBwYXJhbSB7UHVsc2V9IHB1bHNlIC0gdGhlIGN1cnJlbnQgZGF0YWZsb3cgcHVsc2UuXG4gKiBAcmV0dXJuIHRoZSBvdXRwdXQgcHVsc2UgZm9yIHRoaXMgb3BlcmF0b3IgKG9yIFN0b3BQcm9wYWdhdGlvbilcbiAqL1xucHJvdG90eXBlJDEucnVuID0gZnVuY3Rpb24ocHVsc2UpIHtcbiAgaWYgKHB1bHNlLnN0YW1wIDw9IHRoaXMuc3RhbXApIHJldHVybiBwdWxzZS5TdG9wUHJvcGFnYXRpb247XG4gIHZhciBydjtcbiAgaWYgKHRoaXMuc2tpcCgpKSB7XG4gICAgdGhpcy5za2lwKGZhbHNlKTtcbiAgICBydiA9IDA7XG4gIH0gZWxzZSB7XG4gICAgcnYgPSB0aGlzLmV2YWx1YXRlKHB1bHNlKTtcbiAgfVxuICB0aGlzLnN0YW1wID0gcHVsc2Uuc3RhbXA7XG4gIHRoaXMucHVsc2UgPSBydjtcbiAgcmV0dXJuIHJ2IHx8IHB1bHNlO1xufTtcblxuLyoqXG4gKiBBZGQgYW4gb3BlcmF0b3IgdG8gdGhlIGRhdGFmbG93IGdyYXBoLiBUaGlzIGZ1bmN0aW9uIGFjY2VwdHMgYVxuICogdmFyaWV0eSBvZiBpbnB1dCBhcmd1bWVudCB0eXBlcy4gVGhlIGJhc2ljIHNpZ25hdHVyZSBzdXBwb3J0cyBhblxuICogaW5pdGlhbCB2YWx1ZSwgdXBkYXRlIGZ1bmN0aW9uIGFuZCBwYXJhbWV0ZXJzLiBJZiB0aGUgZmlyc3QgcGFyYW1ldGVyXG4gKiBpcyBhbiBPcGVyYXRvciBpbnN0YW5jZSwgaXQgd2lsbCBiZSBhZGRlZCBkaXJlY3RseS4gSWYgaXQgaXMgYVxuICogY29uc3RydWN0b3IgZm9yIGFuIE9wZXJhdG9yIHN1YmNsYXNzLCBhIG5ldyBpbnN0YW5jZSB3aWxsIGJlIGluc3RhbnRpYXRlZC5cbiAqIE90aGVyd2lzZSwgaWYgdGhlIGZpcnN0IHBhcmFtZXRlciBpcyBhIGZ1bmN0aW9uIGluc3RhbmNlLCBpdCB3aWxsIGJlIHVzZWRcbiAqIGFzIHRoZSB1cGRhdGUgZnVuY3Rpb24gYW5kIGEgbnVsbCBpbml0aWFsIHZhbHVlIGlzIGFzc3VtZWQuXG4gKiBAcGFyYW0geyp9IGluaXQgLSBPbmUgb2Y6IHRoZSBvcGVyYXRvciB0byBhZGQsIHRoZSBpbml0aWFsIHZhbHVlIG9mXG4gKiAgIHRoZSBvcGVyYXRvciwgYW4gb3BlcmF0b3IgY2xhc3MgdG8gaW5zdGFudGlhdGUsIG9yIGFuIHVwZGF0ZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb259IFt1cGRhdGVdIC0gVGhlIG9wZXJhdG9yIHVwZGF0ZSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbcGFyYW1zXSAtIFRoZSBvcGVyYXRvciBwYXJhbWV0ZXJzLlxuICogQHBhcmFtIHtib29sZWFufSBbcmVhY3Q9dHJ1ZV0gLSBGbGFnIGluZGljYXRpbmcgaWYgdGhpcyBvcGVyYXRvciBzaG91bGRcbiAqICAgbGlzdGVuIGZvciBjaGFuZ2VzIHRvIHVwc3RyZWFtIG9wZXJhdG9ycyBpbmNsdWRlZCBhcyBwYXJhbWV0ZXJzLlxuICogQHJldHVybiB7T3BlcmF0b3J9IC0gVGhlIGFkZGVkIG9wZXJhdG9yLlxuICovXG52YXIgYWRkID0gZnVuY3Rpb24oaW5pdCwgdXBkYXRlLCBwYXJhbXMsIHJlYWN0KSB7XG4gIHZhciBzaGlmdCA9IDEsXG4gICAgb3A7XG5cbiAgaWYgKGluaXQgaW5zdGFuY2VvZiBPcGVyYXRvcikge1xuICAgIG9wID0gaW5pdDtcbiAgfSBlbHNlIGlmIChpbml0ICYmIGluaXQucHJvdG90eXBlIGluc3RhbmNlb2YgT3BlcmF0b3IpIHtcbiAgICBvcCA9IG5ldyBpbml0KCk7XG4gIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihpbml0KSkge1xuICAgIG9wID0gbmV3IE9wZXJhdG9yKG51bGwsIGluaXQpO1xuICB9IGVsc2Uge1xuICAgIHNoaWZ0ID0gMDtcbiAgICBvcCA9IG5ldyBPcGVyYXRvcihpbml0LCB1cGRhdGUpO1xuICB9XG5cbiAgdGhpcy5yYW5rKG9wKTtcbiAgaWYgKHNoaWZ0KSB7XG4gICAgcmVhY3QgPSBwYXJhbXM7XG4gICAgcGFyYW1zID0gdXBkYXRlO1xuICB9XG4gIGlmIChwYXJhbXMpIHRoaXMuY29ubmVjdChvcCwgb3AucGFyYW1ldGVycyhwYXJhbXMsIHJlYWN0KSk7XG4gIHRoaXMudG91Y2gob3ApO1xuXG4gIHJldHVybiBvcDtcbn07XG5cbi8qKlxuICogQ29ubmVjdCBhIHRhcmdldCBvcGVyYXRvciBhcyBhIGRlcGVuZGVudCBvZiBzb3VyY2Ugb3BlcmF0b3JzLlxuICogSWYgbmVjZXNzYXJ5LCB0aGlzIG1ldGhvZCB3aWxsIHJlcmFuayB0aGUgdGFyZ2V0IG9wZXJhdG9yIGFuZCBpdHNcbiAqIGRlcGVuZGVudHMgdG8gZW5zdXJlIHByb3BhZ2F0aW9uIHByb2NlZWRzIGluIGEgdG9wb2xvZ2ljYWxseSBzb3J0ZWQgb3JkZXIuXG4gKiBAcGFyYW0ge09wZXJhdG9yfSB0YXJnZXQgLSBUaGUgdGFyZ2V0IG9wZXJhdG9yLlxuICogQHBhcmFtIHtBcnJheTxPcGVyYXRvcj59IC0gVGhlIHNvdXJjZSBvcGVyYXRvcnMgdGhhdCBzaG91bGQgcHJvcGFnYXRlXG4gKiAgIHRvIHRoZSB0YXJnZXQgb3BlcmF0b3IuXG4gKi9cbnZhciBjb25uZWN0ID0gZnVuY3Rpb24odGFyZ2V0LCBzb3VyY2VzKSB7XG4gIHZhciB0YXJnZXRSYW5rID0gdGFyZ2V0LnJhbmssIGksIG47XG5cbiAgZm9yIChpPTAsIG49c291cmNlcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgaWYgKHRhcmdldFJhbmsgPCBzb3VyY2VzW2ldLnJhbmspIHtcbiAgICAgIHRoaXMucmVyYW5rKHRhcmdldCk7XG4gICAgICByZXR1cm47XG4gICAgfVxuICB9XG59O1xuXG52YXIgU1RSRUFNX0lEID0gMDtcblxuLyoqXG4gKiBNb2RlbHMgYW4gZXZlbnQgc3RyZWFtLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKE9iamVjdCwgbnVtYmVyKTogYm9vbGVhbn0gW2ZpbHRlcl0gLSBGaWx0ZXIgcHJlZGljYXRlLlxuICogICBFdmVudHMgcGFzcyB0aHJvdWdoIHdoZW4gdHJ1dGh5LCBldmVudHMgYXJlIHN1cHByZXNzZWQgd2hlbiBmYWxzeS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oT2JqZWN0KTogKn0gW2FwcGx5XSAtIEFwcGxpZWQgdG8gaW5wdXQgZXZlbnRzIHRvIHByb2R1Y2VcbiAqICAgbmV3IGV2ZW50IHZhbHVlcy5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oT2JqZWN0KX0gW3JlY2VpdmVdIC0gRXZlbnQgY2FsbGJhY2sgZnVuY3Rpb24gdG8gaW52b2tlXG4gKiAgIHVwb24gcmVjZWlwdCBvZiBhIG5ldyBldmVudC4gVXNlIHRvIG92ZXJyaWRlIHN0YW5kYXJkIGV2ZW50IHByb2Nlc3NpbmcuXG4gKi9cbmZ1bmN0aW9uIEV2ZW50U3RyZWFtKGZpbHRlciwgYXBwbHksIHJlY2VpdmUpIHtcbiAgdGhpcy5pZCA9ICsrU1RSRUFNX0lEO1xuICB0aGlzLnZhbHVlID0gbnVsbDtcbiAgaWYgKHJlY2VpdmUpIHRoaXMucmVjZWl2ZSA9IHJlY2VpdmU7XG4gIGlmIChmaWx0ZXIpIHRoaXMuX2ZpbHRlciA9IGZpbHRlcjtcbiAgaWYgKGFwcGx5KSB0aGlzLl9hcHBseSA9IGFwcGx5O1xufVxuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgZXZlbnQgc3RyZWFtIGluc3RhbmNlIHdpdGggdGhlIHByb3ZpZGVkXG4gKiAob3B0aW9uYWwpIGZpbHRlciwgYXBwbHkgYW5kIHJlY2VpdmUgZnVuY3Rpb25zLlxuICogQHBhcmFtIHtmdW5jdGlvbihPYmplY3QsIG51bWJlcik6IGJvb2xlYW59IFtmaWx0ZXJdIC0gRmlsdGVyIHByZWRpY2F0ZS5cbiAqICAgRXZlbnRzIHBhc3MgdGhyb3VnaCB3aGVuIHRydXRoeSwgZXZlbnRzIGFyZSBzdXBwcmVzc2VkIHdoZW4gZmFsc3kuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKE9iamVjdCk6ICp9IFthcHBseV0gLSBBcHBsaWVkIHRvIGlucHV0IGV2ZW50cyB0byBwcm9kdWNlXG4gKiAgIG5ldyBldmVudCB2YWx1ZXMuXG4gKiBAc2VlIEV2ZW50U3RyZWFtXG4gKi9cbmZ1bmN0aW9uIHN0cmVhbShmaWx0ZXIsIGFwcGx5LCByZWNlaXZlKSB7XG4gIHJldHVybiBuZXcgRXZlbnRTdHJlYW0oZmlsdGVyLCBhcHBseSwgcmVjZWl2ZSk7XG59XG5cbnZhciBwcm90b3R5cGUkMyA9IEV2ZW50U3RyZWFtLnByb3RvdHlwZTtcblxucHJvdG90eXBlJDMuX2ZpbHRlciA9IHRydXRoeTtcblxucHJvdG90eXBlJDMuX2FwcGx5ID0gaWRlbnRpdHk7XG5cbnByb3RvdHlwZSQzLnRhcmdldHMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX3RhcmdldHMgfHwgKHRoaXMuX3RhcmdldHMgPSBVbmlxdWVMaXN0KGlkKSk7XG59O1xuXG5wcm90b3R5cGUkMy5jb25zdW1lID0gZnVuY3Rpb24oXykge1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiAhIXRoaXMuX2NvbnN1bWU7XG4gIHRoaXMuX2NvbnN1bWUgPSAhIV87XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDMucmVjZWl2ZSA9IGZ1bmN0aW9uKGV2dCkge1xuICBpZiAodGhpcy5fZmlsdGVyKGV2dCkpIHtcbiAgICB2YXIgdmFsID0gKHRoaXMudmFsdWUgPSB0aGlzLl9hcHBseShldnQpKSxcbiAgICAgICAgdHJnID0gdGhpcy5fdGFyZ2V0cyxcbiAgICAgICAgbiA9IHRyZyA/IHRyZy5sZW5ndGggOiAwLFxuICAgICAgICBpID0gMDtcblxuICAgIGZvciAoOyBpPG47ICsraSkgdHJnW2ldLnJlY2VpdmUodmFsKTtcblxuICAgIGlmICh0aGlzLl9jb25zdW1lKSB7XG4gICAgICBldnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgIGV2dC5zdG9wUHJvcGFnYXRpb24oKTtcbiAgICB9XG4gIH1cbn07XG5cbnByb3RvdHlwZSQzLmZpbHRlciA9IGZ1bmN0aW9uKGZpbHRlcikge1xuICB2YXIgcyA9IHN0cmVhbShmaWx0ZXIpO1xuICB0aGlzLnRhcmdldHMoKS5hZGQocyk7XG4gIHJldHVybiBzO1xufTtcblxucHJvdG90eXBlJDMuYXBwbHkgPSBmdW5jdGlvbihhcHBseSkge1xuICB2YXIgcyA9IHN0cmVhbShudWxsLCBhcHBseSk7XG4gIHRoaXMudGFyZ2V0cygpLmFkZChzKTtcbiAgcmV0dXJuIHM7XG59O1xuXG5wcm90b3R5cGUkMy5tZXJnZSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcyA9IHN0cmVhbSgpO1xuXG4gIHRoaXMudGFyZ2V0cygpLmFkZChzKTtcbiAgZm9yICh2YXIgaT0wLCBuPWFyZ3VtZW50cy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgYXJndW1lbnRzW2ldLnRhcmdldHMoKS5hZGQocyk7XG4gIH1cblxuICByZXR1cm4gcztcbn07XG5cbnByb3RvdHlwZSQzLnRocm90dGxlID0gZnVuY3Rpb24ocGF1c2UpIHtcbiAgdmFyIHQgPSAtMTtcbiAgcmV0dXJuIHRoaXMuZmlsdGVyKGZ1bmN0aW9uKCkge1xuICAgIHZhciBub3cgPSBEYXRlLm5vdygpO1xuICAgIGlmICgobm93IC0gdCkgPiBwYXVzZSkge1xuICAgICAgdCA9IG5vdztcbiAgICAgIHJldHVybiAxO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gMDtcbiAgICB9XG4gIH0pO1xufTtcblxucHJvdG90eXBlJDMuZGVib3VuY2UgPSBmdW5jdGlvbihkZWxheSkge1xuICB2YXIgcyA9IHN0cmVhbSgpO1xuXG4gIHRoaXMudGFyZ2V0cygpLmFkZChzdHJlYW0obnVsbCwgbnVsbCxcbiAgICBkZWJvdW5jZShkZWxheSwgZnVuY3Rpb24oZSkge1xuICAgICAgdmFyIGRmID0gZS5kYXRhZmxvdztcbiAgICAgIHMucmVjZWl2ZShlKTtcbiAgICAgIGlmIChkZiAmJiBkZi5ydW4pIGRmLnJ1bigpO1xuICAgIH0pXG4gICkpO1xuXG4gIHJldHVybiBzO1xufTtcblxucHJvdG90eXBlJDMuYmV0d2VlbiA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGFjdGl2ZSA9IGZhbHNlO1xuICBhLnRhcmdldHMoKS5hZGQoc3RyZWFtKG51bGwsIG51bGwsIGZ1bmN0aW9uKCkgeyBhY3RpdmUgPSB0cnVlOyB9KSk7XG4gIGIudGFyZ2V0cygpLmFkZChzdHJlYW0obnVsbCwgbnVsbCwgZnVuY3Rpb24oKSB7IGFjdGl2ZSA9IGZhbHNlOyB9KSk7XG4gIHJldHVybiB0aGlzLmZpbHRlcihmdW5jdGlvbigpIHsgcmV0dXJuIGFjdGl2ZTsgfSk7XG59O1xuXG4vKipcbiAqIENyZWF0ZSBhIG5ldyBldmVudCBzdHJlYW0gZnJvbSBhbiBldmVudCBzb3VyY2UuXG4gKiBAcGFyYW0ge29iamVjdH0gc291cmNlIC0gVGhlIGV2ZW50IHNvdXJjZSB0byBtb25pdG9yLiBUaGUgaW5wdXQgbXVzdFxuICogIHN1cHBvcnQgdGhlIGFkZEV2ZW50TGlzdGVuZXIgbWV0aG9kLlxuICogQHBhcmFtIHtzdHJpbmd9IHR5cGUgLSBUaGUgZXZlbnQgdHlwZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogYm9vbGVhbn0gW2ZpbHRlcl0gLSBFdmVudCBmaWx0ZXIgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IFthcHBseV0gLSBFdmVudCBhcHBsaWNhdGlvbiBmdW5jdGlvbi5cbiAqICAgSWYgcHJvdmlkZWQsIHRoaXMgZnVuY3Rpb24gd2lsbCBiZSBpbnZva2VkIGFuZCB0aGUgcmVzdWx0IHdpbGwgYmVcbiAqICAgdXNlZCBhcyB0aGUgZG93bnN0cmVhbSBldmVudCB2YWx1ZS5cbiAqIEByZXR1cm4ge0V2ZW50U3RyZWFtfVxuICovXG52YXIgZXZlbnRzID0gZnVuY3Rpb24oc291cmNlLCB0eXBlLCBmaWx0ZXIsIGFwcGx5KSB7XG4gIHZhciBkZiA9IHRoaXMsXG4gICAgICBzID0gc3RyZWFtKGZpbHRlciwgYXBwbHkpLFxuICAgICAgc2VuZCA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgICAgZS5kYXRhZmxvdyA9IGRmO1xuICAgICAgICB0cnkge1xuICAgICAgICAgIHMucmVjZWl2ZShlKTtcbiAgICAgICAgfSBjYXRjaCAoZXJyb3IpIHtcbiAgICAgICAgICBkZi5lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgZGYucnVuKCk7XG4gICAgICAgIH1cbiAgICAgIH0sXG4gICAgICBzb3VyY2VzO1xuXG4gIGlmICh0eXBlb2Ygc291cmNlID09PSAnc3RyaW5nJyAmJiB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnKSB7XG4gICAgc291cmNlcyA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoc291cmNlKTtcbiAgfSBlbHNlIHtcbiAgICBzb3VyY2VzID0gYXJyYXkoc291cmNlKTtcbiAgfVxuXG4gIGZvciAodmFyIGk9MCwgbj1zb3VyY2VzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBzb3VyY2VzW2ldLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgc2VuZCk7XG4gIH1cblxuICByZXR1cm4gcztcbn07XG5cbnZhciBwcmVmaXggPSBcIiRcIjtcblxuZnVuY3Rpb24gTWFwKCkge31cblxuTWFwLnByb3RvdHlwZSA9IG1hcC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBNYXAsXG4gIGhhczogZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIChwcmVmaXggKyBrZXkpIGluIHRoaXM7XG4gIH0sXG4gIGdldDogZnVuY3Rpb24oa2V5KSB7XG4gICAgcmV0dXJuIHRoaXNbcHJlZml4ICsga2V5XTtcbiAgfSxcbiAgc2V0OiBmdW5jdGlvbihrZXksIHZhbHVlKSB7XG4gICAgdGhpc1twcmVmaXggKyBrZXldID0gdmFsdWU7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0sXG4gIHJlbW92ZTogZnVuY3Rpb24oa2V5KSB7XG4gICAgdmFyIHByb3BlcnR5ID0gcHJlZml4ICsga2V5O1xuICAgIHJldHVybiBwcm9wZXJ0eSBpbiB0aGlzICYmIGRlbGV0ZSB0aGlzW3Byb3BlcnR5XTtcbiAgfSxcbiAgY2xlYXI6IGZ1bmN0aW9uKCkge1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSBkZWxldGUgdGhpc1twcm9wZXJ0eV07XG4gIH0sXG4gIGtleXM6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBrZXlzID0gW107XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIGtleXMucHVzaChwcm9wZXJ0eS5zbGljZSgxKSk7XG4gICAgcmV0dXJuIGtleXM7XG4gIH0sXG4gIHZhbHVlczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHZhbHVlcyA9IFtdO1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSB2YWx1ZXMucHVzaCh0aGlzW3Byb3BlcnR5XSk7XG4gICAgcmV0dXJuIHZhbHVlcztcbiAgfSxcbiAgZW50cmllczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGVudHJpZXMgPSBbXTtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJvcGVydHlbMF0gPT09IHByZWZpeCkgZW50cmllcy5wdXNoKHtrZXk6IHByb3BlcnR5LnNsaWNlKDEpLCB2YWx1ZTogdGhpc1twcm9wZXJ0eV19KTtcbiAgICByZXR1cm4gZW50cmllcztcbiAgfSxcbiAgc2l6ZTogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHNpemUgPSAwO1xuICAgIGZvciAodmFyIHByb3BlcnR5IGluIHRoaXMpIGlmIChwcm9wZXJ0eVswXSA9PT0gcHJlZml4KSArK3NpemU7XG4gICAgcmV0dXJuIHNpemU7XG4gIH0sXG4gIGVtcHR5OiBmdW5jdGlvbigpIHtcbiAgICBmb3IgKHZhciBwcm9wZXJ0eSBpbiB0aGlzKSBpZiAocHJvcGVydHlbMF0gPT09IHByZWZpeCkgcmV0dXJuIGZhbHNlO1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuICBlYWNoOiBmdW5jdGlvbihmKSB7XG4gICAgZm9yICh2YXIgcHJvcGVydHkgaW4gdGhpcykgaWYgKHByb3BlcnR5WzBdID09PSBwcmVmaXgpIGYodGhpc1twcm9wZXJ0eV0sIHByb3BlcnR5LnNsaWNlKDEpLCB0aGlzKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gbWFwKG9iamVjdCwgZikge1xuICB2YXIgbWFwID0gbmV3IE1hcDtcblxuICAvLyBDb3B5IGNvbnN0cnVjdG9yLlxuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgTWFwKSBvYmplY3QuZWFjaChmdW5jdGlvbih2YWx1ZSwga2V5KSB7IG1hcC5zZXQoa2V5LCB2YWx1ZSk7IH0pO1xuXG4gIC8vIEluZGV4IGFycmF5IGJ5IG51bWVyaWMgaW5kZXggb3Igc3BlY2lmaWVkIGtleSBmdW5jdGlvbi5cbiAgZWxzZSBpZiAoQXJyYXkuaXNBcnJheShvYmplY3QpKSB7XG4gICAgdmFyIGkgPSAtMSxcbiAgICAgICAgbiA9IG9iamVjdC5sZW5ndGgsXG4gICAgICAgIG87XG5cbiAgICBpZiAoZiA9PSBudWxsKSB3aGlsZSAoKytpIDwgbikgbWFwLnNldChpLCBvYmplY3RbaV0pO1xuICAgIGVsc2Ugd2hpbGUgKCsraSA8IG4pIG1hcC5zZXQoZihvID0gb2JqZWN0W2ldLCBpLCBvYmplY3QpLCBvKTtcbiAgfVxuXG4gIC8vIENvbnZlcnQgb2JqZWN0IHRvIG1hcC5cbiAgZWxzZSBpZiAob2JqZWN0KSBmb3IgKHZhciBrZXkgaW4gb2JqZWN0KSBtYXAuc2V0KGtleSwgb2JqZWN0W2tleV0pO1xuXG4gIHJldHVybiBtYXA7XG59XG5cbnZhciBuZXN0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBrZXlzID0gW10sXG4gICAgICBzb3J0S2V5cyA9IFtdLFxuICAgICAgc29ydFZhbHVlcyxcbiAgICAgIHJvbGx1cCxcbiAgICAgIG5lc3Q7XG5cbiAgZnVuY3Rpb24gYXBwbHkoYXJyYXksIGRlcHRoLCBjcmVhdGVSZXN1bHQsIHNldFJlc3VsdCkge1xuICAgIGlmIChkZXB0aCA+PSBrZXlzLmxlbmd0aCkge1xuICAgICAgaWYgKHNvcnRWYWx1ZXMgIT0gbnVsbCkgYXJyYXkuc29ydChzb3J0VmFsdWVzKTtcbiAgICAgIHJldHVybiByb2xsdXAgIT0gbnVsbCA/IHJvbGx1cChhcnJheSkgOiBhcnJheTtcbiAgICB9XG5cbiAgICB2YXIgaSA9IC0xLFxuICAgICAgICBuID0gYXJyYXkubGVuZ3RoLFxuICAgICAgICBrZXkgPSBrZXlzW2RlcHRoKytdLFxuICAgICAgICBrZXlWYWx1ZSxcbiAgICAgICAgdmFsdWUsXG4gICAgICAgIHZhbHVlc0J5S2V5ID0gbWFwKCksXG4gICAgICAgIHZhbHVlcyxcbiAgICAgICAgcmVzdWx0ID0gY3JlYXRlUmVzdWx0KCk7XG5cbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKHZhbHVlcyA9IHZhbHVlc0J5S2V5LmdldChrZXlWYWx1ZSA9IGtleSh2YWx1ZSA9IGFycmF5W2ldKSArIFwiXCIpKSB7XG4gICAgICAgIHZhbHVlcy5wdXNoKHZhbHVlKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZhbHVlc0J5S2V5LnNldChrZXlWYWx1ZSwgW3ZhbHVlXSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmFsdWVzQnlLZXkuZWFjaChmdW5jdGlvbih2YWx1ZXMsIGtleSkge1xuICAgICAgc2V0UmVzdWx0KHJlc3VsdCwga2V5LCBhcHBseSh2YWx1ZXMsIGRlcHRoLCBjcmVhdGVSZXN1bHQsIHNldFJlc3VsdCkpO1xuICAgIH0pO1xuXG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIGVudHJpZXMobWFwJCQxLCBkZXB0aCkge1xuICAgIGlmICgrK2RlcHRoID4ga2V5cy5sZW5ndGgpIHJldHVybiBtYXAkJDE7XG4gICAgdmFyIGFycmF5LCBzb3J0S2V5ID0gc29ydEtleXNbZGVwdGggLSAxXTtcbiAgICBpZiAocm9sbHVwICE9IG51bGwgJiYgZGVwdGggPj0ga2V5cy5sZW5ndGgpIGFycmF5ID0gbWFwJCQxLmVudHJpZXMoKTtcbiAgICBlbHNlIGFycmF5ID0gW10sIG1hcCQkMS5lYWNoKGZ1bmN0aW9uKHYsIGspIHsgYXJyYXkucHVzaCh7a2V5OiBrLCB2YWx1ZXM6IGVudHJpZXModiwgZGVwdGgpfSk7IH0pO1xuICAgIHJldHVybiBzb3J0S2V5ICE9IG51bGwgPyBhcnJheS5zb3J0KGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIHNvcnRLZXkoYS5rZXksIGIua2V5KTsgfSkgOiBhcnJheTtcbiAgfVxuXG4gIHJldHVybiBuZXN0ID0ge1xuICAgIG9iamVjdDogZnVuY3Rpb24oYXJyYXkpIHsgcmV0dXJuIGFwcGx5KGFycmF5LCAwLCBjcmVhdGVPYmplY3QsIHNldE9iamVjdCk7IH0sXG4gICAgbWFwOiBmdW5jdGlvbihhcnJheSkgeyByZXR1cm4gYXBwbHkoYXJyYXksIDAsIGNyZWF0ZU1hcCwgc2V0TWFwKTsgfSxcbiAgICBlbnRyaWVzOiBmdW5jdGlvbihhcnJheSkgeyByZXR1cm4gZW50cmllcyhhcHBseShhcnJheSwgMCwgY3JlYXRlTWFwLCBzZXRNYXApLCAwKTsgfSxcbiAgICBrZXk6IGZ1bmN0aW9uKGQpIHsga2V5cy5wdXNoKGQpOyByZXR1cm4gbmVzdDsgfSxcbiAgICBzb3J0S2V5czogZnVuY3Rpb24ob3JkZXIpIHsgc29ydEtleXNba2V5cy5sZW5ndGggLSAxXSA9IG9yZGVyOyByZXR1cm4gbmVzdDsgfSxcbiAgICBzb3J0VmFsdWVzOiBmdW5jdGlvbihvcmRlcikgeyBzb3J0VmFsdWVzID0gb3JkZXI7IHJldHVybiBuZXN0OyB9LFxuICAgIHJvbGx1cDogZnVuY3Rpb24oZikgeyByb2xsdXAgPSBmOyByZXR1cm4gbmVzdDsgfVxuICB9O1xufTtcblxuZnVuY3Rpb24gY3JlYXRlT2JqZWN0KCkge1xuICByZXR1cm4ge307XG59XG5cbmZ1bmN0aW9uIHNldE9iamVjdChvYmplY3QsIGtleSwgdmFsdWUpIHtcbiAgb2JqZWN0W2tleV0gPSB2YWx1ZTtcbn1cblxuZnVuY3Rpb24gY3JlYXRlTWFwKCkge1xuICByZXR1cm4gbWFwKCk7XG59XG5cbmZ1bmN0aW9uIHNldE1hcChtYXAkJDEsIGtleSwgdmFsdWUpIHtcbiAgbWFwJCQxLnNldChrZXksIHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gU2V0KCkge31cblxudmFyIHByb3RvID0gbWFwLnByb3RvdHlwZTtcblxuU2V0LnByb3RvdHlwZSA9IHNldC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBTZXQsXG4gIGhhczogcHJvdG8uaGFzLFxuICBhZGQ6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFsdWUgKz0gXCJcIjtcbiAgICB0aGlzW3ByZWZpeCArIHZhbHVlXSA9IHZhbHVlO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICByZW1vdmU6IHByb3RvLnJlbW92ZSxcbiAgY2xlYXI6IHByb3RvLmNsZWFyLFxuICB2YWx1ZXM6IHByb3RvLmtleXMsXG4gIHNpemU6IHByb3RvLnNpemUsXG4gIGVtcHR5OiBwcm90by5lbXB0eSxcbiAgZWFjaDogcHJvdG8uZWFjaFxufTtcblxuZnVuY3Rpb24gc2V0KG9iamVjdCwgZikge1xuICB2YXIgc2V0ID0gbmV3IFNldDtcblxuICAvLyBDb3B5IGNvbnN0cnVjdG9yLlxuICBpZiAob2JqZWN0IGluc3RhbmNlb2YgU2V0KSBvYmplY3QuZWFjaChmdW5jdGlvbih2YWx1ZSkgeyBzZXQuYWRkKHZhbHVlKTsgfSk7XG5cbiAgLy8gT3RoZXJ3aXNlLCBhc3N1bWUgaXTigJlzIGFuIGFycmF5LlxuICBlbHNlIGlmIChvYmplY3QpIHtcbiAgICB2YXIgaSA9IC0xLCBuID0gb2JqZWN0Lmxlbmd0aDtcbiAgICBpZiAoZiA9PSBudWxsKSB3aGlsZSAoKytpIDwgbikgc2V0LmFkZChvYmplY3RbaV0pO1xuICAgIGVsc2Ugd2hpbGUgKCsraSA8IG4pIHNldC5hZGQoZihvYmplY3RbaV0sIGksIG9iamVjdCkpO1xuICB9XG5cbiAgcmV0dXJuIHNldDtcbn1cblxudmFyIG5vb3AgPSB7dmFsdWU6IGZ1bmN0aW9uKCkge319O1xuXG5mdW5jdGlvbiBkaXNwYXRjaCgpIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSBhcmd1bWVudHMubGVuZ3RoLCBfID0ge30sIHQ7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoISh0ID0gYXJndW1lbnRzW2ldICsgXCJcIikgfHwgKHQgaW4gXykpIHRocm93IG5ldyBFcnJvcihcImlsbGVnYWwgdHlwZTogXCIgKyB0KTtcbiAgICBfW3RdID0gW107XG4gIH1cbiAgcmV0dXJuIG5ldyBEaXNwYXRjaChfKTtcbn1cblxuZnVuY3Rpb24gRGlzcGF0Y2goXykge1xuICB0aGlzLl8gPSBfO1xufVxuXG5mdW5jdGlvbiBwYXJzZVR5cGVuYW1lcyh0eXBlbmFtZXMsIHR5cGVzKSB7XG4gIHJldHVybiB0eXBlbmFtZXMudHJpbSgpLnNwbGl0KC9efFxccysvKS5tYXAoZnVuY3Rpb24odCkge1xuICAgIHZhciBuYW1lID0gXCJcIiwgaSA9IHQuaW5kZXhPZihcIi5cIik7XG4gICAgaWYgKGkgPj0gMCkgbmFtZSA9IHQuc2xpY2UoaSArIDEpLCB0ID0gdC5zbGljZSgwLCBpKTtcbiAgICBpZiAodCAmJiAhdHlwZXMuaGFzT3duUHJvcGVydHkodCkpIHRocm93IG5ldyBFcnJvcihcInVua25vd24gdHlwZTogXCIgKyB0KTtcbiAgICByZXR1cm4ge3R5cGU6IHQsIG5hbWU6IG5hbWV9O1xuICB9KTtcbn1cblxuRGlzcGF0Y2gucHJvdG90eXBlID0gZGlzcGF0Y2gucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogRGlzcGF0Y2gsXG4gIG9uOiBmdW5jdGlvbih0eXBlbmFtZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgXyA9IHRoaXMuXyxcbiAgICAgICAgVCA9IHBhcnNlVHlwZW5hbWVzKHR5cGVuYW1lICsgXCJcIiwgXyksXG4gICAgICAgIHQsXG4gICAgICAgIGkgPSAtMSxcbiAgICAgICAgbiA9IFQubGVuZ3RoO1xuXG4gICAgLy8gSWYgbm8gY2FsbGJhY2sgd2FzIHNwZWNpZmllZCwgcmV0dXJuIHRoZSBjYWxsYmFjayBvZiB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCA8IDIpIHtcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSAmJiAodCA9IGdldChfW3RdLCB0eXBlbmFtZS5uYW1lKSkpIHJldHVybiB0O1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIElmIGEgdHlwZSB3YXMgc3BlY2lmaWVkLCBzZXQgdGhlIGNhbGxiYWNrIGZvciB0aGUgZ2l2ZW4gdHlwZSBhbmQgbmFtZS5cbiAgICAvLyBPdGhlcndpc2UsIGlmIGEgbnVsbCBjYWxsYmFjayB3YXMgc3BlY2lmaWVkLCByZW1vdmUgY2FsbGJhY2tzIG9mIHRoZSBnaXZlbiBuYW1lLlxuICAgIGlmIChjYWxsYmFjayAhPSBudWxsICYmIHR5cGVvZiBjYWxsYmFjayAhPT0gXCJmdW5jdGlvblwiKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGNhbGxiYWNrOiBcIiArIGNhbGxiYWNrKTtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKHQgPSAodHlwZW5hbWUgPSBUW2ldKS50eXBlKSBfW3RdID0gc2V0JDIoX1t0XSwgdHlwZW5hbWUubmFtZSwgY2FsbGJhY2spO1xuICAgICAgZWxzZSBpZiAoY2FsbGJhY2sgPT0gbnVsbCkgZm9yICh0IGluIF8pIF9bdF0gPSBzZXQkMihfW3RdLCB0eXBlbmFtZS5uYW1lLCBudWxsKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgY29weTogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNvcHkgPSB7fSwgXyA9IHRoaXMuXztcbiAgICBmb3IgKHZhciB0IGluIF8pIGNvcHlbdF0gPSBfW3RdLnNsaWNlKCk7XG4gICAgcmV0dXJuIG5ldyBEaXNwYXRjaChjb3B5KTtcbiAgfSxcbiAgY2FsbDogZnVuY3Rpb24odHlwZSwgdGhhdCkge1xuICAgIGlmICgobiA9IGFyZ3VtZW50cy5sZW5ndGggLSAyKSA+IDApIGZvciAodmFyIGFyZ3MgPSBuZXcgQXJyYXkobiksIGkgPSAwLCBuLCB0OyBpIDwgbjsgKytpKSBhcmdzW2ldID0gYXJndW1lbnRzW2kgKyAyXTtcbiAgICBpZiAoIXRoaXMuXy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biB0eXBlOiBcIiArIHR5cGUpO1xuICAgIGZvciAodCA9IHRoaXMuX1t0eXBlXSwgaSA9IDAsIG4gPSB0Lmxlbmd0aDsgaSA8IG47ICsraSkgdFtpXS52YWx1ZS5hcHBseSh0aGF0LCBhcmdzKTtcbiAgfSxcbiAgYXBwbHk6IGZ1bmN0aW9uKHR5cGUsIHRoYXQsIGFyZ3MpIHtcbiAgICBpZiAoIXRoaXMuXy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSkgdGhyb3cgbmV3IEVycm9yKFwidW5rbm93biB0eXBlOiBcIiArIHR5cGUpO1xuICAgIGZvciAodmFyIHQgPSB0aGlzLl9bdHlwZV0sIGkgPSAwLCBuID0gdC5sZW5ndGg7IGkgPCBuOyArK2kpIHRbaV0udmFsdWUuYXBwbHkodGhhdCwgYXJncyk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGdldCh0eXBlLCBuYW1lKSB7XG4gIGZvciAodmFyIGkgPSAwLCBuID0gdHlwZS5sZW5ndGgsIGM7IGkgPCBuOyArK2kpIHtcbiAgICBpZiAoKGMgPSB0eXBlW2ldKS5uYW1lID09PSBuYW1lKSB7XG4gICAgICByZXR1cm4gYy52YWx1ZTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0JDIodHlwZSwgbmFtZSwgY2FsbGJhY2spIHtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSB0eXBlLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgIGlmICh0eXBlW2ldLm5hbWUgPT09IG5hbWUpIHtcbiAgICAgIHR5cGVbaV0gPSBub29wLCB0eXBlID0gdHlwZS5zbGljZSgwLCBpKS5jb25jYXQodHlwZS5zbGljZShpICsgMSkpO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG4gIGlmIChjYWxsYmFjayAhPSBudWxsKSB0eXBlLnB1c2goe25hbWU6IG5hbWUsIHZhbHVlOiBjYWxsYmFja30pO1xuICByZXR1cm4gdHlwZTtcbn1cblxudmFyIHJlcXVlc3QkMSA9IGZ1bmN0aW9uKHVybCwgY2FsbGJhY2spIHtcbiAgdmFyIHJlcXVlc3QsXG4gICAgICBldmVudCA9IGRpc3BhdGNoKFwiYmVmb3Jlc2VuZFwiLCBcInByb2dyZXNzXCIsIFwibG9hZFwiLCBcImVycm9yXCIpLFxuICAgICAgbWltZVR5cGUsXG4gICAgICBoZWFkZXJzID0gbWFwKCksXG4gICAgICB4aHIgPSBuZXcgWE1MSHR0cFJlcXVlc3QsXG4gICAgICB1c2VyID0gbnVsbCxcbiAgICAgIHBhc3N3b3JkID0gbnVsbCxcbiAgICAgIHJlc3BvbnNlLFxuICAgICAgcmVzcG9uc2VUeXBlLFxuICAgICAgdGltZW91dCA9IDA7XG5cbiAgLy8gSWYgSUUgZG9lcyBub3Qgc3VwcG9ydCBDT1JTLCB1c2UgWERvbWFpblJlcXVlc3QuXG4gIGlmICh0eXBlb2YgWERvbWFpblJlcXVlc3QgIT09IFwidW5kZWZpbmVkXCJcbiAgICAgICYmICEoXCJ3aXRoQ3JlZGVudGlhbHNcIiBpbiB4aHIpXG4gICAgICAmJiAvXihodHRwKHMpPzopP1xcL1xcLy8udGVzdCh1cmwpKSB4aHIgPSBuZXcgWERvbWFpblJlcXVlc3Q7XG5cbiAgXCJvbmxvYWRcIiBpbiB4aHJcbiAgICAgID8geGhyLm9ubG9hZCA9IHhoci5vbmVycm9yID0geGhyLm9udGltZW91dCA9IHJlc3BvbmRcbiAgICAgIDogeGhyLm9ucmVhZHlzdGF0ZWNoYW5nZSA9IGZ1bmN0aW9uKG8pIHsgeGhyLnJlYWR5U3RhdGUgPiAzICYmIHJlc3BvbmQobyk7IH07XG5cbiAgZnVuY3Rpb24gcmVzcG9uZChvKSB7XG4gICAgdmFyIHN0YXR1cyA9IHhoci5zdGF0dXMsIHJlc3VsdDtcbiAgICBpZiAoIXN0YXR1cyAmJiBoYXNSZXNwb25zZSh4aHIpXG4gICAgICAgIHx8IHN0YXR1cyA+PSAyMDAgJiYgc3RhdHVzIDwgMzAwXG4gICAgICAgIHx8IHN0YXR1cyA9PT0gMzA0KSB7XG4gICAgICBpZiAocmVzcG9uc2UpIHtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICByZXN1bHQgPSByZXNwb25zZS5jYWxsKHJlcXVlc3QsIHhocik7XG4gICAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgICBldmVudC5jYWxsKFwiZXJyb3JcIiwgcmVxdWVzdCwgZSk7XG4gICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICByZXN1bHQgPSB4aHI7XG4gICAgICB9XG4gICAgICBldmVudC5jYWxsKFwibG9hZFwiLCByZXF1ZXN0LCByZXN1bHQpO1xuICAgIH0gZWxzZSB7XG4gICAgICBldmVudC5jYWxsKFwiZXJyb3JcIiwgcmVxdWVzdCwgbyk7XG4gICAgfVxuICB9XG5cbiAgeGhyLm9ucHJvZ3Jlc3MgPSBmdW5jdGlvbihlKSB7XG4gICAgZXZlbnQuY2FsbChcInByb2dyZXNzXCIsIHJlcXVlc3QsIGUpO1xuICB9O1xuXG4gIHJlcXVlc3QgPSB7XG4gICAgaGVhZGVyOiBmdW5jdGlvbihuYW1lLCB2YWx1ZSkge1xuICAgICAgbmFtZSA9IChuYW1lICsgXCJcIikudG9Mb3dlckNhc2UoKTtcbiAgICAgIGlmIChhcmd1bWVudHMubGVuZ3RoIDwgMikgcmV0dXJuIGhlYWRlcnMuZ2V0KG5hbWUpO1xuICAgICAgaWYgKHZhbHVlID09IG51bGwpIGhlYWRlcnMucmVtb3ZlKG5hbWUpO1xuICAgICAgZWxzZSBoZWFkZXJzLnNldChuYW1lLCB2YWx1ZSArIFwiXCIpO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcblxuICAgIC8vIElmIG1pbWVUeXBlIGlzIG5vbi1udWxsIGFuZCBubyBBY2NlcHQgaGVhZGVyIGlzIHNldCwgYSBkZWZhdWx0IGlzIHVzZWQuXG4gICAgbWltZVR5cGU6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBtaW1lVHlwZTtcbiAgICAgIG1pbWVUeXBlID0gdmFsdWUgPT0gbnVsbCA/IG51bGwgOiB2YWx1ZSArIFwiXCI7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgLy8gU3BlY2lmaWVzIHdoYXQgdHlwZSB0aGUgcmVzcG9uc2UgdmFsdWUgc2hvdWxkIHRha2U7XG4gICAgLy8gZm9yIGluc3RhbmNlLCBhcnJheWJ1ZmZlciwgYmxvYiwgZG9jdW1lbnQsIG9yIHRleHQuXG4gICAgcmVzcG9uc2VUeXBlOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcmVzcG9uc2VUeXBlO1xuICAgICAgcmVzcG9uc2VUeXBlID0gdmFsdWU7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgdGltZW91dDogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRpbWVvdXQ7XG4gICAgICB0aW1lb3V0ID0gK3ZhbHVlO1xuICAgICAgcmV0dXJuIHJlcXVlc3Q7XG4gICAgfSxcblxuICAgIHVzZXI6IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA8IDEgPyB1c2VyIDogKHVzZXIgPSB2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlICsgXCJcIiwgcmVxdWVzdCk7XG4gICAgfSxcblxuICAgIHBhc3N3b3JkOiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPCAxID8gcGFzc3dvcmQgOiAocGFzc3dvcmQgPSB2YWx1ZSA9PSBudWxsID8gbnVsbCA6IHZhbHVlICsgXCJcIiwgcmVxdWVzdCk7XG4gICAgfSxcblxuICAgIC8vIFNwZWNpZnkgaG93IHRvIGNvbnZlcnQgdGhlIHJlc3BvbnNlIGNvbnRlbnQgdG8gYSBzcGVjaWZpYyB0eXBlO1xuICAgIC8vIGNoYW5nZXMgdGhlIGNhbGxiYWNrIHZhbHVlIG9uIFwibG9hZFwiIGV2ZW50cy5cbiAgICByZXNwb25zZTogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgIHJlc3BvbnNlID0gdmFsdWU7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgLy8gQWxpYXMgZm9yIHNlbmQoXCJHRVRcIiwg4oCmKS5cbiAgICBnZXQ6IGZ1bmN0aW9uKGRhdGEsIGNhbGxiYWNrKSB7XG4gICAgICByZXR1cm4gcmVxdWVzdC5zZW5kKFwiR0VUXCIsIGRhdGEsIGNhbGxiYWNrKTtcbiAgICB9LFxuXG4gICAgLy8gQWxpYXMgZm9yIHNlbmQoXCJQT1NUXCIsIOKApikuXG4gICAgcG9zdDogZnVuY3Rpb24oZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgIHJldHVybiByZXF1ZXN0LnNlbmQoXCJQT1NUXCIsIGRhdGEsIGNhbGxiYWNrKTtcbiAgICB9LFxuXG4gICAgLy8gSWYgY2FsbGJhY2sgaXMgbm9uLW51bGwsIGl0IHdpbGwgYmUgdXNlZCBmb3IgZXJyb3IgYW5kIGxvYWQgZXZlbnRzLlxuICAgIHNlbmQ6IGZ1bmN0aW9uKG1ldGhvZCwgZGF0YSwgY2FsbGJhY2spIHtcbiAgICAgIHhoci5vcGVuKG1ldGhvZCwgdXJsLCB0cnVlLCB1c2VyLCBwYXNzd29yZCk7XG4gICAgICBpZiAobWltZVR5cGUgIT0gbnVsbCAmJiAhaGVhZGVycy5oYXMoXCJhY2NlcHRcIikpIGhlYWRlcnMuc2V0KFwiYWNjZXB0XCIsIG1pbWVUeXBlICsgXCIsKi8qXCIpO1xuICAgICAgaWYgKHhoci5zZXRSZXF1ZXN0SGVhZGVyKSBoZWFkZXJzLmVhY2goZnVuY3Rpb24odmFsdWUsIG5hbWUpIHsgeGhyLnNldFJlcXVlc3RIZWFkZXIobmFtZSwgdmFsdWUpOyB9KTtcbiAgICAgIGlmIChtaW1lVHlwZSAhPSBudWxsICYmIHhoci5vdmVycmlkZU1pbWVUeXBlKSB4aHIub3ZlcnJpZGVNaW1lVHlwZShtaW1lVHlwZSk7XG4gICAgICBpZiAocmVzcG9uc2VUeXBlICE9IG51bGwpIHhoci5yZXNwb25zZVR5cGUgPSByZXNwb25zZVR5cGU7XG4gICAgICBpZiAodGltZW91dCA+IDApIHhoci50aW1lb3V0ID0gdGltZW91dDtcbiAgICAgIGlmIChjYWxsYmFjayA9PSBudWxsICYmIHR5cGVvZiBkYXRhID09PSBcImZ1bmN0aW9uXCIpIGNhbGxiYWNrID0gZGF0YSwgZGF0YSA9IG51bGw7XG4gICAgICBpZiAoY2FsbGJhY2sgIT0gbnVsbCAmJiBjYWxsYmFjay5sZW5ndGggPT09IDEpIGNhbGxiYWNrID0gZml4Q2FsbGJhY2soY2FsbGJhY2spO1xuICAgICAgaWYgKGNhbGxiYWNrICE9IG51bGwpIHJlcXVlc3Qub24oXCJlcnJvclwiLCBjYWxsYmFjaykub24oXCJsb2FkXCIsIGZ1bmN0aW9uKHhocikgeyBjYWxsYmFjayhudWxsLCB4aHIpOyB9KTtcbiAgICAgIGV2ZW50LmNhbGwoXCJiZWZvcmVzZW5kXCIsIHJlcXVlc3QsIHhocik7XG4gICAgICB4aHIuc2VuZChkYXRhID09IG51bGwgPyBudWxsIDogZGF0YSk7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgYWJvcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgeGhyLmFib3J0KCk7XG4gICAgICByZXR1cm4gcmVxdWVzdDtcbiAgICB9LFxuXG4gICAgb246IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHZhbHVlID0gZXZlbnQub24uYXBwbHkoZXZlbnQsIGFyZ3VtZW50cyk7XG4gICAgICByZXR1cm4gdmFsdWUgPT09IGV2ZW50ID8gcmVxdWVzdCA6IHZhbHVlO1xuICAgIH1cbiAgfTtcblxuICBpZiAoY2FsbGJhY2sgIT0gbnVsbCkge1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBjYWxsYmFjazogXCIgKyBjYWxsYmFjayk7XG4gICAgcmV0dXJuIHJlcXVlc3QuZ2V0KGNhbGxiYWNrKTtcbiAgfVxuXG4gIHJldHVybiByZXF1ZXN0O1xufTtcblxuZnVuY3Rpb24gZml4Q2FsbGJhY2soY2FsbGJhY2spIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGVycm9yLCB4aHIpIHtcbiAgICBjYWxsYmFjayhlcnJvciA9PSBudWxsID8geGhyIDogbnVsbCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGhhc1Jlc3BvbnNlKHhocikge1xuICB2YXIgdHlwZSA9IHhoci5yZXNwb25zZVR5cGU7XG4gIHJldHVybiB0eXBlICYmIHR5cGUgIT09IFwidGV4dFwiXG4gICAgICA/IHhoci5yZXNwb25zZSAvLyBudWxsIG9uIGVycm9yXG4gICAgICA6IHhoci5yZXNwb25zZVRleHQ7IC8vIFwiXCIgb24gZXJyb3Jcbn1cblxudmFyIEVPTCA9IHt9O1xudmFyIEVPRiA9IHt9O1xudmFyIFFVT1RFID0gMzQ7XG52YXIgTkVXTElORSA9IDEwO1xudmFyIFJFVFVSTiA9IDEzO1xuXG5mdW5jdGlvbiBvYmplY3RDb252ZXJ0ZXIoY29sdW1ucykge1xuICByZXR1cm4gbmV3IEZ1bmN0aW9uKFwiZFwiLCBcInJldHVybiB7XCIgKyBjb2x1bW5zLm1hcChmdW5jdGlvbihuYW1lLCBpKSB7XG4gICAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KG5hbWUpICsgXCI6IGRbXCIgKyBpICsgXCJdXCI7XG4gIH0pLmpvaW4oXCIsXCIpICsgXCJ9XCIpO1xufVxuXG5mdW5jdGlvbiBjdXN0b21Db252ZXJ0ZXIoY29sdW1ucywgZikge1xuICB2YXIgb2JqZWN0ID0gb2JqZWN0Q29udmVydGVyKGNvbHVtbnMpO1xuICByZXR1cm4gZnVuY3Rpb24ocm93LCBpKSB7XG4gICAgcmV0dXJuIGYob2JqZWN0KHJvdyksIGksIGNvbHVtbnMpO1xuICB9O1xufVxuXG4vLyBDb21wdXRlIHVuaXF1ZSBjb2x1bW5zIGluIG9yZGVyIG9mIGRpc2NvdmVyeS5cbmZ1bmN0aW9uIGluZmVyQ29sdW1ucyhyb3dzKSB7XG4gIHZhciBjb2x1bW5TZXQgPSBPYmplY3QuY3JlYXRlKG51bGwpLFxuICAgICAgY29sdW1ucyA9IFtdO1xuXG4gIHJvd3MuZm9yRWFjaChmdW5jdGlvbihyb3cpIHtcbiAgICBmb3IgKHZhciBjb2x1bW4gaW4gcm93KSB7XG4gICAgICBpZiAoIShjb2x1bW4gaW4gY29sdW1uU2V0KSkge1xuICAgICAgICBjb2x1bW5zLnB1c2goY29sdW1uU2V0W2NvbHVtbl0gPSBjb2x1bW4pO1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGNvbHVtbnM7XG59XG5cbnZhciBkc3ZGb3JtYXQgPSBmdW5jdGlvbihkZWxpbWl0ZXIpIHtcbiAgdmFyIHJlRm9ybWF0ID0gbmV3IFJlZ0V4cChcIltcXFwiXCIgKyBkZWxpbWl0ZXIgKyBcIlxcblxccl1cIiksXG4gICAgICBERUxJTUlURVIgPSBkZWxpbWl0ZXIuY2hhckNvZGVBdCgwKTtcblxuICBmdW5jdGlvbiBwYXJzZSh0ZXh0LCBmKSB7XG4gICAgdmFyIGNvbnZlcnQsIGNvbHVtbnMsIHJvd3MgPSBwYXJzZVJvd3ModGV4dCwgZnVuY3Rpb24ocm93LCBpKSB7XG4gICAgICBpZiAoY29udmVydCkgcmV0dXJuIGNvbnZlcnQocm93LCBpIC0gMSk7XG4gICAgICBjb2x1bW5zID0gcm93LCBjb252ZXJ0ID0gZiA/IGN1c3RvbUNvbnZlcnRlcihyb3csIGYpIDogb2JqZWN0Q29udmVydGVyKHJvdyk7XG4gICAgfSk7XG4gICAgcm93cy5jb2x1bW5zID0gY29sdW1ucyB8fCBbXTtcbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlUm93cyh0ZXh0LCBmKSB7XG4gICAgdmFyIHJvd3MgPSBbXSwgLy8gb3V0cHV0IHJvd3NcbiAgICAgICAgTiA9IHRleHQubGVuZ3RoLFxuICAgICAgICBJID0gMCwgLy8gY3VycmVudCBjaGFyYWN0ZXIgaW5kZXhcbiAgICAgICAgbiA9IDAsIC8vIGN1cnJlbnQgbGluZSBudW1iZXJcbiAgICAgICAgdCwgLy8gY3VycmVudCB0b2tlblxuICAgICAgICBlb2YgPSBOIDw9IDAsIC8vIGN1cnJlbnQgdG9rZW4gZm9sbG93ZWQgYnkgRU9GP1xuICAgICAgICBlb2wgPSBmYWxzZTsgLy8gY3VycmVudCB0b2tlbiBmb2xsb3dlZCBieSBFT0w/XG5cbiAgICAvLyBTdHJpcCB0aGUgdHJhaWxpbmcgbmV3bGluZS5cbiAgICBpZiAodGV4dC5jaGFyQ29kZUF0KE4gLSAxKSA9PT0gTkVXTElORSkgLS1OO1xuICAgIGlmICh0ZXh0LmNoYXJDb2RlQXQoTiAtIDEpID09PSBSRVRVUk4pIC0tTjtcblxuICAgIGZ1bmN0aW9uIHRva2VuKCkge1xuICAgICAgaWYgKGVvZikgcmV0dXJuIEVPRjtcbiAgICAgIGlmIChlb2wpIHJldHVybiBlb2wgPSBmYWxzZSwgRU9MO1xuXG4gICAgICAvLyBVbmVzY2FwZSBxdW90ZXMuXG4gICAgICB2YXIgaSwgaiA9IEksIGM7XG4gICAgICBpZiAodGV4dC5jaGFyQ29kZUF0KGopID09PSBRVU9URSkge1xuICAgICAgICB3aGlsZSAoSSsrIDwgTiAmJiB0ZXh0LmNoYXJDb2RlQXQoSSkgIT09IFFVT1RFIHx8IHRleHQuY2hhckNvZGVBdCgrK0kpID09PSBRVU9URSk7XG4gICAgICAgIGlmICgoaSA9IEkpID49IE4pIGVvZiA9IHRydWU7XG4gICAgICAgIGVsc2UgaWYgKChjID0gdGV4dC5jaGFyQ29kZUF0KEkrKykpID09PSBORVdMSU5FKSBlb2wgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmIChjID09PSBSRVRVUk4pIHsgZW9sID0gdHJ1ZTsgaWYgKHRleHQuY2hhckNvZGVBdChJKSA9PT0gTkVXTElORSkgKytJOyB9XG4gICAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGogKyAxLCBpIC0gMSkucmVwbGFjZSgvXCJcIi9nLCBcIlxcXCJcIik7XG4gICAgICB9XG5cbiAgICAgIC8vIEZpbmQgbmV4dCBkZWxpbWl0ZXIgb3IgbmV3bGluZS5cbiAgICAgIHdoaWxlIChJIDwgTikge1xuICAgICAgICBpZiAoKGMgPSB0ZXh0LmNoYXJDb2RlQXQoaSA9IEkrKykpID09PSBORVdMSU5FKSBlb2wgPSB0cnVlO1xuICAgICAgICBlbHNlIGlmIChjID09PSBSRVRVUk4pIHsgZW9sID0gdHJ1ZTsgaWYgKHRleHQuY2hhckNvZGVBdChJKSA9PT0gTkVXTElORSkgKytJOyB9XG4gICAgICAgIGVsc2UgaWYgKGMgIT09IERFTElNSVRFUikgY29udGludWU7XG4gICAgICAgIHJldHVybiB0ZXh0LnNsaWNlKGosIGkpO1xuICAgICAgfVxuXG4gICAgICAvLyBSZXR1cm4gbGFzdCB0b2tlbiBiZWZvcmUgRU9GLlxuICAgICAgcmV0dXJuIGVvZiA9IHRydWUsIHRleHQuc2xpY2UoaiwgTik7XG4gICAgfVxuXG4gICAgd2hpbGUgKCh0ID0gdG9rZW4oKSkgIT09IEVPRikge1xuICAgICAgdmFyIHJvdyA9IFtdO1xuICAgICAgd2hpbGUgKHQgIT09IEVPTCAmJiB0ICE9PSBFT0YpIHJvdy5wdXNoKHQpLCB0ID0gdG9rZW4oKTtcbiAgICAgIGlmIChmICYmIChyb3cgPSBmKHJvdywgbisrKSkgPT0gbnVsbCkgY29udGludWU7XG4gICAgICByb3dzLnB1c2gocm93KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm93cztcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdChyb3dzLCBjb2x1bW5zKSB7XG4gICAgaWYgKGNvbHVtbnMgPT0gbnVsbCkgY29sdW1ucyA9IGluZmVyQ29sdW1ucyhyb3dzKTtcbiAgICByZXR1cm4gW2NvbHVtbnMubWFwKGZvcm1hdFZhbHVlKS5qb2luKGRlbGltaXRlcildLmNvbmNhdChyb3dzLm1hcChmdW5jdGlvbihyb3cpIHtcbiAgICAgIHJldHVybiBjb2x1bW5zLm1hcChmdW5jdGlvbihjb2x1bW4pIHtcbiAgICAgICAgcmV0dXJuIGZvcm1hdFZhbHVlKHJvd1tjb2x1bW5dKTtcbiAgICAgIH0pLmpvaW4oZGVsaW1pdGVyKTtcbiAgICB9KSkuam9pbihcIlxcblwiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFJvd3Mocm93cykge1xuICAgIHJldHVybiByb3dzLm1hcChmb3JtYXRSb3cpLmpvaW4oXCJcXG5cIik7XG4gIH1cblxuICBmdW5jdGlvbiBmb3JtYXRSb3cocm93KSB7XG4gICAgcmV0dXJuIHJvdy5tYXAoZm9ybWF0VmFsdWUpLmpvaW4oZGVsaW1pdGVyKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFZhbHVlKHRleHQpIHtcbiAgICByZXR1cm4gdGV4dCA9PSBudWxsID8gXCJcIlxuICAgICAgICA6IHJlRm9ybWF0LnRlc3QodGV4dCArPSBcIlwiKSA/IFwiXFxcIlwiICsgdGV4dC5yZXBsYWNlKC9cIi9nLCBcIlxcXCJcXFwiXCIpICsgXCJcXFwiXCJcbiAgICAgICAgOiB0ZXh0O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBwYXJzZTogcGFyc2UsXG4gICAgcGFyc2VSb3dzOiBwYXJzZVJvd3MsXG4gICAgZm9ybWF0OiBmb3JtYXQsXG4gICAgZm9ybWF0Um93czogZm9ybWF0Um93c1xuICB9O1xufTtcblxudmFyIGNzdiQxID0gZHN2Rm9ybWF0KFwiLFwiKTtcblxudmFyIHRzdiA9IGRzdkZvcm1hdChcIlxcdFwiKTtcblxuLy8gTWF0Y2hlcyBhYnNvbHV0ZSBVUkxzIHdpdGggb3B0aW9uYWwgcHJvdG9jb2xcbi8vICAgaHR0cHM6Ly8uLi4gICAgZmlsZTovLy4uLiAgICAvLy4uLlxudmFyIHByb3RvY29sX3JlID0gL14oW0EtWmEtel0rOik/XFwvXFwvLztcblxuLy8gU3BlY2lhbCB0cmVhdG1lbnQgaW4gbm9kZS5qcyBmb3IgdGhlIGZpbGU6IHByb3RvY29sXG52YXIgZmlsZVByb3RvY29sID0gJ2ZpbGU6Ly8nO1xuXG4vLyBSZXF1ZXN0IG9wdGlvbnMgdG8gY2hlY2sgZm9yIGQzLXJlcXVlc3RcbnZhciByZXF1ZXN0T3B0aW9ucyA9IFtcbiAgJ21pbWVUeXBlJyxcbiAgJ3Jlc3BvbnNlVHlwZScsXG4gICd1c2VyJyxcbiAgJ3Bhc3N3b3JkJ1xuXTtcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IGxvYWRlciBpbnN0YW5jZSB0aGF0IHByb3ZpZGVzIG1ldGhvZHMgZm9yIHJlcXVlc3RpbmcgZmlsZXNcbiAqIGZyb20gZWl0aGVyIHRoZSBuZXR3b3JrIG9yIGRpc2ssIGFuZCBmb3Igc2FuaXRpemluZyByZXF1ZXN0IFVSSXMuXG4gKiBAcGFyYW0ge29iamVjdH0gW29wdGlvbnNdIC0gT3B0aW9uYWwgZGVmYXVsdCBsb2FkaW5nIG9wdGlvbnMgdG8gdXNlLlxuICogQHJldHVybiB7b2JqZWN0fSAtIEEgbmV3IGxvYWRlciBpbnN0YW5jZS5cbiAqL1xudmFyIGxvYWRlciA9IGZ1bmN0aW9uKG9wdGlvbnMpIHtcbiAgcmV0dXJuIHtcbiAgICBvcHRpb25zOiBvcHRpb25zIHx8IHt9LFxuICAgIHNhbml0aXplOiBzYW5pdGl6ZSxcbiAgICBsb2FkOiBsb2FkLFxuICAgIGZpbGU6IGZpbGUsXG4gICAgaHR0cDogaHR0cFxuICB9O1xufTtcblxuZnVuY3Rpb24gbWFyc2hhbGwobG9hZGVyLCBvcHRpb25zKSB7XG4gIHJldHVybiBleHRlbmQoe30sIGxvYWRlci5vcHRpb25zLCBvcHRpb25zKTtcbn1cblxuLyoqXG4gKiBMb2FkIGFuIGV4dGVybmFsIHJlc291cmNlLCB0eXBpY2FsbHkgZWl0aGVyIGZyb20gdGhlIHdlYiBvciBmcm9tIHRoZSBsb2NhbFxuICogZmlsZXN5c3RlbS4gVGhpcyBmdW5jdGlvbiB1c2VzIHtAbGluayBzYW5pdGl6ZX0gdG8gZmlyc3Qgc2FuaXRpemUgdGhlIHVyaSxcbiAqIHRoZW4gY2FsbHMgZWl0aGVyIHtAbGluayBodHRwfSAoZm9yIHdlYiByZXF1ZXN0cykgb3Ige0BsaW5rIGZpbGV9IChmb3JcbiAqIGZpbGVzeXN0ZW0gbG9hZGluZykuXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJpIC0gVGhlIHJlc291cmNlIGluZGljYXRvciAoZS5nLiwgVVJMIG9yIGZpbGVuYW1lKS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBPcHRpb25hbCBsb2FkaW5nIG9wdGlvbnMuIFRoZXNlIG9wdGlvbnMgd2lsbFxuICogICBvdmVycmlkZSBhbnkgZXhpc3RpbmcgZGVmYXVsdCBvcHRpb25zLlxuICogQHJldHVybiB7UHJvbWlzZX0gLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byB0aGUgbG9hZGVkIGNvbnRlbnQuXG4gKi9cbmZ1bmN0aW9uIGxvYWQodXJpLCBvcHRpb25zKSB7XG4gIHZhciBsb2FkZXIgPSB0aGlzO1xuICByZXR1cm4gbG9hZGVyLnNhbml0aXplKHVyaSwgb3B0aW9ucylcbiAgICAudGhlbihmdW5jdGlvbihvcHQpIHtcbiAgICAgIHZhciB1cmwgPSBvcHQuaHJlZjtcbiAgICAgIHJldHVybiBvcHQubG9jYWxGaWxlXG4gICAgICAgID8gbG9hZGVyLmZpbGUodXJsKVxuICAgICAgICA6IGxvYWRlci5odHRwKHVybCwgb3B0aW9ucyk7XG4gICAgfSk7XG59XG5cbi8qKlxuICogVVJJIHNhbml0aXplciBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSB1cmkgLSBUaGUgdXJpICh1cmwgb3IgZmlsZW5hbWUpIHRvIHNhbml0eSBjaGVjay5cbiAqIEBwYXJhbSB7b2JqZWN0fSBvcHRpb25zIC0gQW4gb3B0aW9ucyBoYXNoLlxuICogQHJldHVybiB7UHJvbWlzZX0gLSBBIHByb21pc2UgdGhhdCByZXNvbHZlcyB0byBhbiBvYmplY3QgY29udGFpbmluZ1xuICogIHNhbml0aXplZCB1cmkgZGF0YSwgb3IgcmVqZWN0cyBpdCB0aGUgaW5wdXQgdXJpIGlzIGRlZW1lZCBpbnZhbGlkLlxuICogIFRoZSBwcm9wZXJ0aWVzIG9mIHRoZSByZXNvbHZlZCBvYmplY3QgYXJlIGFzc3VtZWQgdG8gYmVcbiAqICB2YWxpZCBhdHRyaWJ1dGVzIGZvciBhbiBIVE1MICdhJyB0YWcuIFRoZSBzYW5pdGl6ZWQgdXJpICptdXN0KiBiZVxuICogIHByb3ZpZGVkIGJ5IHRoZSAnaHJlZicgcHJvcGVydHkgb2YgdGhlIHJldHVybmVkIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gc2FuaXRpemUodXJpLCBvcHRpb25zKSB7XG4gIG9wdGlvbnMgPSBtYXJzaGFsbCh0aGlzLCBvcHRpb25zKTtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGFjY2VwdCwgcmVqZWN0KSB7XG4gICAgdmFyIHJlc3VsdCA9IHtocmVmOiBudWxsfSxcbiAgICAgICAgaXNGaWxlLCBoYXNQcm90b2NvbCwgbG9hZEZpbGUsIGJhc2U7XG5cbiAgICBpZiAodXJpID09IG51bGwgfHwgdHlwZW9mIHVyaSAhPT0gJ3N0cmluZycpIHtcbiAgICAgIHJlamVjdCgnU2FuaXRpemUgZmFpbHVyZSwgaW52YWxpZCBVUkk6ICcgKyAkKHVyaSkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIGhhc1Byb3RvY29sID0gcHJvdG9jb2xfcmUudGVzdCh1cmkpO1xuXG4gICAgLy8gaWYgcmVsYXRpdmUgdXJsIChubyBwcm90b2NvbC9ob3N0KSwgcHJlcGVuZCBiYXNlVVJMXG4gICAgaWYgKChiYXNlID0gb3B0aW9ucy5iYXNlVVJMKSAmJiAhaGFzUHJvdG9jb2wpIHtcbiAgICAgIC8vIEVuc3VyZSB0aGF0IHRoZXJlIGlzIGEgc2xhc2ggYmV0d2VlbiB0aGUgYmFzZVVSTCAoZS5nLiBob3N0bmFtZSkgYW5kIHVybFxuICAgICAgaWYgKCFzdGFydHNXaXRoKHVyaSwgJy8nKSAmJiBiYXNlW2Jhc2UubGVuZ3RoLTFdICE9PSAnLycpIHtcbiAgICAgICAgdXJpID0gJy8nICsgdXJpO1xuICAgICAgfVxuICAgICAgdXJpID0gYmFzZSArIHVyaTtcbiAgICB9XG5cbiAgICAvLyBzaG91bGQgd2UgbG9hZCBmcm9tIGZpbGUgc3lzdGVtP1xuICAgIGxvYWRGaWxlID0gKGlzRmlsZSA9IHN0YXJ0c1dpdGgodXJpLCBmaWxlUHJvdG9jb2wpKVxuICAgICAgfHwgb3B0aW9ucy5tb2RlID09PSAnZmlsZSdcbiAgICAgIHx8IG9wdGlvbnMubW9kZSAhPT0gJ2h0dHAnICYmICFoYXNQcm90b2NvbCAmJiBmcygpO1xuXG4gICAgaWYgKGlzRmlsZSkge1xuICAgICAgLy8gc3RyaXAgZmlsZSBwcm90b2NvbFxuICAgICAgdXJpID0gdXJpLnNsaWNlKGZpbGVQcm90b2NvbC5sZW5ndGgpO1xuICAgIH0gZWxzZSBpZiAoc3RhcnRzV2l0aCh1cmksICcvLycpKSB7XG4gICAgICBpZiAob3B0aW9ucy5kZWZhdWx0UHJvdG9jb2wgPT09ICdmaWxlJykge1xuICAgICAgICAvLyBpZiBpcyBmaWxlLCBzdHJpcCBwcm90b2NvbCBhbmQgc2V0IGxvYWRGaWxlIGZsYWdcbiAgICAgICAgdXJpID0gdXJpLnNsaWNlKDIpO1xuICAgICAgICBsb2FkRmlsZSA9IHRydWU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICAvLyBpZiByZWxhdGl2ZSBwcm90b2NvbCAoc3RhcnRzIHdpdGggJy8vJyksIHByZXBlbmQgZGVmYXVsdCBwcm90b2NvbFxuICAgICAgICB1cmkgPSAob3B0aW9ucy5kZWZhdWx0UHJvdG9jb2wgfHwgJ2h0dHAnKSArICc6JyArIHVyaTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzZXQgbm9uLWVudW1lcmFibGUgbW9kZSBmbGFnIHRvIGluZGljYXRlIGxvY2FsIGZpbGUgbG9hZFxuICAgIE9iamVjdC5kZWZpbmVQcm9wZXJ0eShyZXN1bHQsICdsb2NhbEZpbGUnLCB7dmFsdWU6ICEhbG9hZEZpbGV9KTtcblxuICAgIC8vIHNldCB1cmlcbiAgICByZXN1bHQuaHJlZiA9IHVyaTtcblxuICAgIC8vIHNldCBkZWZhdWx0IHJlc3VsdCB0YXJnZXQsIGlmIHNwZWNpZmllZFxuICAgIGlmIChvcHRpb25zLnRhcmdldCkge1xuICAgICAgcmVzdWx0LnRhcmdldCA9IG9wdGlvbnMudGFyZ2V0ICsgJyc7XG4gICAgfVxuXG4gICAgLy8gcmV0dXJuXG4gICAgYWNjZXB0KHJlc3VsdCk7XG4gIH0pO1xufVxuXG4vKipcbiAqIEhUVFAgcmVxdWVzdCBsb2FkZXIuXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJsIC0gVGhlIHVybCB0byByZXF1ZXN0LlxuICogQHBhcmFtIHtvYmplY3R9IG9wdGlvbnMgLSBBbiBvcHRpb25zIGhhc2guXG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBmaWxlIGNvbnRlbnRzLlxuICovXG5mdW5jdGlvbiBodHRwKHVybCwgb3B0aW9ucykge1xuICBvcHRpb25zID0gbWFyc2hhbGwodGhpcywgb3B0aW9ucyk7XG4gIHJldHVybiBuZXcgUHJvbWlzZShmdW5jdGlvbihhY2NlcHQsIHJlamVjdCkge1xuICAgIHZhciByZXEgPSByZXF1ZXN0JDEodXJsKSxcbiAgICAgICAgbmFtZTtcblxuICAgIGZvciAobmFtZSBpbiBvcHRpb25zLmhlYWRlcnMpIHtcbiAgICAgIHJlcS5oZWFkZXIobmFtZSwgb3B0aW9ucy5oZWFkZXJzW25hbWVdKTtcbiAgICB9XG5cbiAgICByZXF1ZXN0T3B0aW9ucy5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICAgIGlmIChvcHRpb25zW25hbWVdKSByZXFbbmFtZV0ob3B0aW9uc1tuYW1lXSk7XG4gICAgfSk7XG5cbiAgICByZXEub24oJ2Vycm9yJywgZnVuY3Rpb24oZXJyb3IpIHtcbiAgICAgICAgcmVqZWN0KGVycm9yIHx8ICdFcnJvciBsb2FkaW5nIFVSTDogJyArIHVybCk7XG4gICAgICB9KVxuICAgICAgLm9uKCdsb2FkJywgZnVuY3Rpb24ocmVzdWx0KSB7XG4gICAgICAgIHZhciB0ZXh0JCQxID0gcmVzdWx0ICYmIHJlc3VsdC5yZXNwb25zZVRleHQ7XG4gICAgICAgICghcmVzdWx0IHx8IHJlc3VsdC5zdGF0dXMgPT09IDApXG4gICAgICAgICAgPyByZWplY3QodGV4dCQkMSB8fCAnRXJyb3InKVxuICAgICAgICAgIDogYWNjZXB0KHRleHQkJDEpO1xuICAgICAgfSlcbiAgICAgIC5nZXQoKTtcbiAgfSk7XG59XG5cbi8qKlxuICogRmlsZSBzeXN0ZW0gbG9hZGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IGZpbGVuYW1lIC0gVGhlIGZpbGUgc3lzdGVtIHBhdGggdG8gbG9hZC5cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGZpbGUgY29udGVudHMuXG4gKi9cbmZ1bmN0aW9uIGZpbGUoZmlsZW5hbWUpIHtcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGFjY2VwdCwgcmVqZWN0KSB7XG4gICAgdmFyIGYgPSBmcygpO1xuICAgIGYgPyBmLnJlYWRGaWxlKGZpbGVuYW1lLCBmdW5jdGlvbihlcnJvciwgZGF0YSkge1xuICAgICAgICAgIGlmIChlcnJvcikgcmVqZWN0KGVycm9yKTtcbiAgICAgICAgICBlbHNlIGFjY2VwdChkYXRhKTtcbiAgICAgICAgfSlcbiAgICAgIDogcmVqZWN0KCdObyBmaWxlIHN5c3RlbSBhY2Nlc3MgZm9yICcgKyBmaWxlbmFtZSk7XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBmcygpIHtcbiAgdmFyIGZzID0gdHlwZW9mIHJlcXVpcmUgPT09ICdmdW5jdGlvbicgJiYgcmVxdWlyZSgnZnMnKTtcbiAgcmV0dXJuIGZzICYmIGlzRnVuY3Rpb24oZnMucmVhZEZpbGUpID8gZnMgOiBudWxsO1xufVxuXG5mdW5jdGlvbiBzdGFydHNXaXRoKHN0cmluZywgcXVlcnkpIHtcbiAgcmV0dXJuIHN0cmluZyA9PSBudWxsID8gZmFsc2UgOiBzdHJpbmcubGFzdEluZGV4T2YocXVlcnksIDApID09PSAwO1xufVxuXG52YXIgdHlwZVBhcnNlcnMgPSB7XG4gIGJvb2xlYW46IHRvQm9vbGVhbixcbiAgaW50ZWdlcjogdG9OdW1iZXIsXG4gIG51bWJlcjogIHRvTnVtYmVyLFxuICBkYXRlOiAgICB0b0RhdGUsXG4gIHN0cmluZzogIHRvU3RyaW5nLFxuICB1bmtub3duOiBpZGVudGl0eVxufTtcblxudmFyIHR5cGVUZXN0cyA9IFtcbiAgaXNCb29sZWFuJDEsXG4gIGlzSW50ZWdlcixcbiAgaXNOdW1iZXIkMSxcbiAgaXNEYXRlJDFcbl07XG5cbnZhciB0eXBlTGlzdCA9IFtcbiAgJ2Jvb2xlYW4nLFxuICAnaW50ZWdlcicsXG4gICdudW1iZXInLFxuICAnZGF0ZSdcbl07XG5cbmZ1bmN0aW9uIGluZmVyVHlwZSh2YWx1ZXMsIGZpZWxkJCQxKSB7XG4gIGlmICghdmFsdWVzIHx8ICF2YWx1ZXMubGVuZ3RoKSByZXR1cm4gJ3Vua25vd24nO1xuXG4gIHZhciB0ZXN0cyA9IHR5cGVUZXN0cy5zbGljZSgpLFxuICAgICAgdmFsdWUsIGksIG4sIGo7XG5cbiAgZm9yIChpPTAsIG49dmFsdWVzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICB2YWx1ZSA9IGZpZWxkJCQxID8gdmFsdWVzW2ldW2ZpZWxkJCQxXSA6IHZhbHVlc1tpXTtcbiAgICBmb3IgKGo9MDsgajx0ZXN0cy5sZW5ndGg7ICsraikge1xuICAgICAgaWYgKGlzVmFsaWQodmFsdWUpICYmICF0ZXN0c1tqXSh2YWx1ZSkpIHtcbiAgICAgICAgdGVzdHMuc3BsaWNlKGosIDEpOyAtLWo7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICh0ZXN0cy5sZW5ndGggPT09IDApIHJldHVybiAnc3RyaW5nJztcbiAgfVxuICByZXR1cm4gdHlwZUxpc3RbdHlwZVRlc3RzLmluZGV4T2YodGVzdHNbMF0pXTtcbn1cblxuZnVuY3Rpb24gaW5mZXJUeXBlcyhkYXRhLCBmaWVsZHMpIHtcbiAgcmV0dXJuIGZpZWxkcy5yZWR1Y2UoZnVuY3Rpb24odHlwZXMsIGZpZWxkJCQxKSB7XG4gICAgdHlwZXNbZmllbGQkJDFdID0gaW5mZXJUeXBlKGRhdGEsIGZpZWxkJCQxKTtcbiAgICByZXR1cm4gdHlwZXM7XG4gIH0sIHt9KTtcbn1cblxuLy8gLS0gVHlwZSBDaGVja3MgLS0tLVxuXG5mdW5jdGlvbiBpc1ZhbGlkKF8pIHtcbiAgcmV0dXJuIF8gIT0gbnVsbCAmJiBfID09PSBfO1xufVxuXG5mdW5jdGlvbiBpc0Jvb2xlYW4kMShfKSB7XG4gIHJldHVybiBfID09PSAndHJ1ZScgfHwgXyA9PT0gJ2ZhbHNlJyB8fCBfID09PSB0cnVlIHx8IF8gPT09IGZhbHNlO1xufVxuXG5mdW5jdGlvbiBpc0RhdGUkMShfKSB7XG4gIHJldHVybiAhaXNOYU4oRGF0ZS5wYXJzZShfKSk7XG59XG5cbmZ1bmN0aW9uIGlzTnVtYmVyJDEoXykge1xuICByZXR1cm4gIWlzTmFOKCtfKSAmJiAhKF8gaW5zdGFuY2VvZiBEYXRlKTtcbn1cblxuZnVuY3Rpb24gaXNJbnRlZ2VyKF8pIHtcbiAgcmV0dXJuIGlzTnVtYmVyJDEoXykgJiYgKF89K18pID09PSB+fl87XG59XG5cbmZ1bmN0aW9uIGRlbGltaXRlZEZvcm1hdChkZWxpbWl0ZXIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGRhdGEsIGZvcm1hdCkge1xuICAgIHZhciBkZWxpbSA9IHtkZWxpbWl0ZXI6IGRlbGltaXRlcn07XG4gICAgcmV0dXJuIGRzdiQxKGRhdGEsIGZvcm1hdCA/IGV4dGVuZChmb3JtYXQsIGRlbGltKSA6IGRlbGltKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZHN2JDEoZGF0YSwgZm9ybWF0KSB7XG4gIGlmIChmb3JtYXQuaGVhZGVyKSB7XG4gICAgZGF0YSA9IGZvcm1hdC5oZWFkZXJcbiAgICAgIC5tYXAoJClcbiAgICAgIC5qb2luKGZvcm1hdC5kZWxpbWl0ZXIpICsgJ1xcbicgKyBkYXRhO1xuICB9XG4gIHJldHVybiBkc3ZGb3JtYXQoZm9ybWF0LmRlbGltaXRlcikucGFyc2UoZGF0YSsnJyk7XG59XG5cbmZ1bmN0aW9uIGlzQnVmZmVyKF8pIHtcbiAgcmV0dXJuICh0eXBlb2YgQnVmZmVyID09PSAnZnVuY3Rpb24nICYmIGlzRnVuY3Rpb24oQnVmZmVyLmlzQnVmZmVyKSlcbiAgICA/IEJ1ZmZlci5pc0J1ZmZlcihfKSA6IGZhbHNlO1xufVxuXG52YXIganNvbiQxID0gZnVuY3Rpb24oZGF0YSwgZm9ybWF0KSB7XG4gIHZhciBwcm9wID0gKGZvcm1hdCAmJiBmb3JtYXQucHJvcGVydHkpID8gZmllbGQoZm9ybWF0LnByb3BlcnR5KSA6IGlkZW50aXR5O1xuICByZXR1cm4gaXNPYmplY3QoZGF0YSkgJiYgIWlzQnVmZmVyKGRhdGEpXG4gICAgPyBwYXJzZUpTT04ocHJvcChkYXRhKSlcbiAgICA6IHByb3AoSlNPTi5wYXJzZShkYXRhKSk7XG59O1xuXG5mdW5jdGlvbiBwYXJzZUpTT04oZGF0YSwgZm9ybWF0KSB7XG4gIHJldHVybiAoZm9ybWF0ICYmIGZvcm1hdC5jb3B5KVxuICAgID8gSlNPTi5wYXJzZShKU09OLnN0cmluZ2lmeShkYXRhKSlcbiAgICA6IGRhdGE7XG59XG5cbnZhciBpZGVudGl0eSQxID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geDtcbn07XG5cbnZhciB0cmFuc2Zvcm0gPSBmdW5jdGlvbih0cmFuc2Zvcm0pIHtcbiAgaWYgKHRyYW5zZm9ybSA9PSBudWxsKSByZXR1cm4gaWRlbnRpdHkkMTtcbiAgdmFyIHgwLFxuICAgICAgeTAsXG4gICAgICBreCA9IHRyYW5zZm9ybS5zY2FsZVswXSxcbiAgICAgIGt5ID0gdHJhbnNmb3JtLnNjYWxlWzFdLFxuICAgICAgZHggPSB0cmFuc2Zvcm0udHJhbnNsYXRlWzBdLFxuICAgICAgZHkgPSB0cmFuc2Zvcm0udHJhbnNsYXRlWzFdO1xuICByZXR1cm4gZnVuY3Rpb24oaW5wdXQsIGkpIHtcbiAgICBpZiAoIWkpIHgwID0geTAgPSAwO1xuICAgIHZhciBqID0gMiwgbiA9IGlucHV0Lmxlbmd0aCwgb3V0cHV0ID0gbmV3IEFycmF5KG4pO1xuICAgIG91dHB1dFswXSA9ICh4MCArPSBpbnB1dFswXSkgKiBreCArIGR4O1xuICAgIG91dHB1dFsxXSA9ICh5MCArPSBpbnB1dFsxXSkgKiBreSArIGR5O1xuICAgIHdoaWxlIChqIDwgbikgb3V0cHV0W2pdID0gaW5wdXRbal0sICsrajtcbiAgICByZXR1cm4gb3V0cHV0O1xuICB9O1xufTtcblxudmFyIHJldmVyc2UgPSBmdW5jdGlvbihhcnJheSwgbikge1xuICB2YXIgdCwgaiA9IGFycmF5Lmxlbmd0aCwgaSA9IGogLSBuO1xuICB3aGlsZSAoaSA8IC0taikgdCA9IGFycmF5W2ldLCBhcnJheVtpKytdID0gYXJyYXlbal0sIGFycmF5W2pdID0gdDtcbn07XG5cbnZhciBmZWF0dXJlID0gZnVuY3Rpb24odG9wb2xvZ3ksIG8pIHtcbiAgcmV0dXJuIG8udHlwZSA9PT0gXCJHZW9tZXRyeUNvbGxlY3Rpb25cIlxuICAgICAgPyB7dHlwZTogXCJGZWF0dXJlQ29sbGVjdGlvblwiLCBmZWF0dXJlczogby5nZW9tZXRyaWVzLm1hcChmdW5jdGlvbihvKSB7IHJldHVybiBmZWF0dXJlJDEodG9wb2xvZ3ksIG8pOyB9KX1cbiAgICAgIDogZmVhdHVyZSQxKHRvcG9sb2d5LCBvKTtcbn07XG5cbmZ1bmN0aW9uIGZlYXR1cmUkMSh0b3BvbG9neSwgbykge1xuICB2YXIgaWQgPSBvLmlkLFxuICAgICAgYmJveCA9IG8uYmJveCxcbiAgICAgIHByb3BlcnRpZXMgPSBvLnByb3BlcnRpZXMgPT0gbnVsbCA/IHt9IDogby5wcm9wZXJ0aWVzLFxuICAgICAgZ2VvbWV0cnkgPSBvYmplY3QodG9wb2xvZ3ksIG8pO1xuICByZXR1cm4gaWQgPT0gbnVsbCAmJiBiYm94ID09IG51bGwgPyB7dHlwZTogXCJGZWF0dXJlXCIsIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsIGdlb21ldHJ5OiBnZW9tZXRyeX1cbiAgICAgIDogYmJveCA9PSBudWxsID8ge3R5cGU6IFwiRmVhdHVyZVwiLCBpZDogaWQsIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsIGdlb21ldHJ5OiBnZW9tZXRyeX1cbiAgICAgIDoge3R5cGU6IFwiRmVhdHVyZVwiLCBpZDogaWQsIGJib3g6IGJib3gsIHByb3BlcnRpZXM6IHByb3BlcnRpZXMsIGdlb21ldHJ5OiBnZW9tZXRyeX07XG59XG5cbmZ1bmN0aW9uIG9iamVjdCh0b3BvbG9neSwgbykge1xuICB2YXIgdHJhbnNmb3JtUG9pbnQgPSB0cmFuc2Zvcm0odG9wb2xvZ3kudHJhbnNmb3JtKSxcbiAgICAgIGFyY3MgPSB0b3BvbG9neS5hcmNzO1xuXG4gIGZ1bmN0aW9uIGFyYyhpLCBwb2ludHMpIHtcbiAgICBpZiAocG9pbnRzLmxlbmd0aCkgcG9pbnRzLnBvcCgpO1xuICAgIGZvciAodmFyIGEgPSBhcmNzW2kgPCAwID8gfmkgOiBpXSwgayA9IDAsIG4gPSBhLmxlbmd0aDsgayA8IG47ICsraykge1xuICAgICAgcG9pbnRzLnB1c2godHJhbnNmb3JtUG9pbnQoYVtrXSwgaykpO1xuICAgIH1cbiAgICBpZiAoaSA8IDApIHJldmVyc2UocG9pbnRzLCBuKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBvaW50KHApIHtcbiAgICByZXR1cm4gdHJhbnNmb3JtUG9pbnQocCk7XG4gIH1cblxuICBmdW5jdGlvbiBsaW5lKGFyY3MpIHtcbiAgICB2YXIgcG9pbnRzID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBhcmNzLmxlbmd0aDsgaSA8IG47ICsraSkgYXJjKGFyY3NbaV0sIHBvaW50cyk7XG4gICAgaWYgKHBvaW50cy5sZW5ndGggPCAyKSBwb2ludHMucHVzaChwb2ludHNbMF0pOyAvLyBUaGlzIHNob3VsZCBuZXZlciBoYXBwZW4gcGVyIHRoZSBzcGVjaWZpY2F0aW9uLlxuICAgIHJldHVybiBwb2ludHM7XG4gIH1cblxuICBmdW5jdGlvbiByaW5nKGFyY3MpIHtcbiAgICB2YXIgcG9pbnRzID0gbGluZShhcmNzKTtcbiAgICB3aGlsZSAocG9pbnRzLmxlbmd0aCA8IDQpIHBvaW50cy5wdXNoKHBvaW50c1swXSk7IC8vIFRoaXMgbWF5IGhhcHBlbiBpZiBhbiBhcmMgaGFzIG9ubHkgdHdvIHBvaW50cy5cbiAgICByZXR1cm4gcG9pbnRzO1xuICB9XG5cbiAgZnVuY3Rpb24gcG9seWdvbihhcmNzKSB7XG4gICAgcmV0dXJuIGFyY3MubWFwKHJpbmcpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2VvbWV0cnkobykge1xuICAgIHZhciB0eXBlID0gby50eXBlLCBjb29yZGluYXRlcztcbiAgICBzd2l0Y2ggKHR5cGUpIHtcbiAgICAgIGNhc2UgXCJHZW9tZXRyeUNvbGxlY3Rpb25cIjogcmV0dXJuIHt0eXBlOiB0eXBlLCBnZW9tZXRyaWVzOiBvLmdlb21ldHJpZXMubWFwKGdlb21ldHJ5KX07XG4gICAgICBjYXNlIFwiUG9pbnRcIjogY29vcmRpbmF0ZXMgPSBwb2ludChvLmNvb3JkaW5hdGVzKTsgYnJlYWs7XG4gICAgICBjYXNlIFwiTXVsdGlQb2ludFwiOiBjb29yZGluYXRlcyA9IG8uY29vcmRpbmF0ZXMubWFwKHBvaW50KTsgYnJlYWs7XG4gICAgICBjYXNlIFwiTGluZVN0cmluZ1wiOiBjb29yZGluYXRlcyA9IGxpbmUoby5hcmNzKTsgYnJlYWs7XG4gICAgICBjYXNlIFwiTXVsdGlMaW5lU3RyaW5nXCI6IGNvb3JkaW5hdGVzID0gby5hcmNzLm1hcChsaW5lKTsgYnJlYWs7XG4gICAgICBjYXNlIFwiUG9seWdvblwiOiBjb29yZGluYXRlcyA9IHBvbHlnb24oby5hcmNzKTsgYnJlYWs7XG4gICAgICBjYXNlIFwiTXVsdGlQb2x5Z29uXCI6IGNvb3JkaW5hdGVzID0gby5hcmNzLm1hcChwb2x5Z29uKTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiByZXR1cm4gbnVsbDtcbiAgICB9XG4gICAgcmV0dXJuIHt0eXBlOiB0eXBlLCBjb29yZGluYXRlczogY29vcmRpbmF0ZXN9O1xuICB9XG5cbiAgcmV0dXJuIGdlb21ldHJ5KG8pO1xufVxuXG52YXIgc3RpdGNoID0gZnVuY3Rpb24odG9wb2xvZ3ksIGFyY3MpIHtcbiAgdmFyIHN0aXRjaGVkQXJjcyA9IHt9LFxuICAgICAgZnJhZ21lbnRCeVN0YXJ0ID0ge30sXG4gICAgICBmcmFnbWVudEJ5RW5kID0ge30sXG4gICAgICBmcmFnbWVudHMgPSBbXSxcbiAgICAgIGVtcHR5SW5kZXggPSAtMTtcblxuICAvLyBTdGl0Y2ggZW1wdHkgYXJjcyBmaXJzdCwgc2luY2UgdGhleSBtYXkgYmUgc3Vic3VtZWQgYnkgb3RoZXIgYXJjcy5cbiAgYXJjcy5mb3JFYWNoKGZ1bmN0aW9uKGksIGopIHtcbiAgICB2YXIgYXJjID0gdG9wb2xvZ3kuYXJjc1tpIDwgMCA/IH5pIDogaV0sIHQ7XG4gICAgaWYgKGFyYy5sZW5ndGggPCAzICYmICFhcmNbMV1bMF0gJiYgIWFyY1sxXVsxXSkge1xuICAgICAgdCA9IGFyY3NbKytlbXB0eUluZGV4XSwgYXJjc1tlbXB0eUluZGV4XSA9IGksIGFyY3Nbal0gPSB0O1xuICAgIH1cbiAgfSk7XG5cbiAgYXJjcy5mb3JFYWNoKGZ1bmN0aW9uKGkpIHtcbiAgICB2YXIgZSA9IGVuZHMoaSksXG4gICAgICAgIHN0YXJ0ID0gZVswXSxcbiAgICAgICAgZW5kID0gZVsxXSxcbiAgICAgICAgZiwgZztcblxuICAgIGlmIChmID0gZnJhZ21lbnRCeUVuZFtzdGFydF0pIHtcbiAgICAgIGRlbGV0ZSBmcmFnbWVudEJ5RW5kW2YuZW5kXTtcbiAgICAgIGYucHVzaChpKTtcbiAgICAgIGYuZW5kID0gZW5kO1xuICAgICAgaWYgKGcgPSBmcmFnbWVudEJ5U3RhcnRbZW5kXSkge1xuICAgICAgICBkZWxldGUgZnJhZ21lbnRCeVN0YXJ0W2cuc3RhcnRdO1xuICAgICAgICB2YXIgZmcgPSBnID09PSBmID8gZiA6IGYuY29uY2F0KGcpO1xuICAgICAgICBmcmFnbWVudEJ5U3RhcnRbZmcuc3RhcnQgPSBmLnN0YXJ0XSA9IGZyYWdtZW50QnlFbmRbZmcuZW5kID0gZy5lbmRdID0gZmc7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBmcmFnbWVudEJ5U3RhcnRbZi5zdGFydF0gPSBmcmFnbWVudEJ5RW5kW2YuZW5kXSA9IGY7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChmID0gZnJhZ21lbnRCeVN0YXJ0W2VuZF0pIHtcbiAgICAgIGRlbGV0ZSBmcmFnbWVudEJ5U3RhcnRbZi5zdGFydF07XG4gICAgICBmLnVuc2hpZnQoaSk7XG4gICAgICBmLnN0YXJ0ID0gc3RhcnQ7XG4gICAgICBpZiAoZyA9IGZyYWdtZW50QnlFbmRbc3RhcnRdKSB7XG4gICAgICAgIGRlbGV0ZSBmcmFnbWVudEJ5RW5kW2cuZW5kXTtcbiAgICAgICAgdmFyIGdmID0gZyA9PT0gZiA/IGYgOiBnLmNvbmNhdChmKTtcbiAgICAgICAgZnJhZ21lbnRCeVN0YXJ0W2dmLnN0YXJ0ID0gZy5zdGFydF0gPSBmcmFnbWVudEJ5RW5kW2dmLmVuZCA9IGYuZW5kXSA9IGdmO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZnJhZ21lbnRCeVN0YXJ0W2Yuc3RhcnRdID0gZnJhZ21lbnRCeUVuZFtmLmVuZF0gPSBmO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBmID0gW2ldO1xuICAgICAgZnJhZ21lbnRCeVN0YXJ0W2Yuc3RhcnQgPSBzdGFydF0gPSBmcmFnbWVudEJ5RW5kW2YuZW5kID0gZW5kXSA9IGY7XG4gICAgfVxuICB9KTtcblxuICBmdW5jdGlvbiBlbmRzKGkpIHtcbiAgICB2YXIgYXJjID0gdG9wb2xvZ3kuYXJjc1tpIDwgMCA/IH5pIDogaV0sIHAwID0gYXJjWzBdLCBwMTtcbiAgICBpZiAodG9wb2xvZ3kudHJhbnNmb3JtKSBwMSA9IFswLCAwXSwgYXJjLmZvckVhY2goZnVuY3Rpb24oZHApIHsgcDFbMF0gKz0gZHBbMF0sIHAxWzFdICs9IGRwWzFdOyB9KTtcbiAgICBlbHNlIHAxID0gYXJjW2FyYy5sZW5ndGggLSAxXTtcbiAgICByZXR1cm4gaSA8IDAgPyBbcDEsIHAwXSA6IFtwMCwgcDFdO1xuICB9XG5cbiAgZnVuY3Rpb24gZmx1c2goZnJhZ21lbnRCeUVuZCwgZnJhZ21lbnRCeVN0YXJ0KSB7XG4gICAgZm9yICh2YXIgayBpbiBmcmFnbWVudEJ5RW5kKSB7XG4gICAgICB2YXIgZiA9IGZyYWdtZW50QnlFbmRba107XG4gICAgICBkZWxldGUgZnJhZ21lbnRCeVN0YXJ0W2Yuc3RhcnRdO1xuICAgICAgZGVsZXRlIGYuc3RhcnQ7XG4gICAgICBkZWxldGUgZi5lbmQ7XG4gICAgICBmLmZvckVhY2goZnVuY3Rpb24oaSkgeyBzdGl0Y2hlZEFyY3NbaSA8IDAgPyB+aSA6IGldID0gMTsgfSk7XG4gICAgICBmcmFnbWVudHMucHVzaChmKTtcbiAgICB9XG4gIH1cblxuICBmbHVzaChmcmFnbWVudEJ5RW5kLCBmcmFnbWVudEJ5U3RhcnQpO1xuICBmbHVzaChmcmFnbWVudEJ5U3RhcnQsIGZyYWdtZW50QnlFbmQpO1xuICBhcmNzLmZvckVhY2goZnVuY3Rpb24oaSkgeyBpZiAoIXN0aXRjaGVkQXJjc1tpIDwgMCA/IH5pIDogaV0pIGZyYWdtZW50cy5wdXNoKFtpXSk7IH0pO1xuXG4gIHJldHVybiBmcmFnbWVudHM7XG59O1xuXG52YXIgbWVzaCA9IGZ1bmN0aW9uKHRvcG9sb2d5KSB7XG4gIHJldHVybiBvYmplY3QodG9wb2xvZ3ksIG1lc2hBcmNzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpO1xufTtcblxuZnVuY3Rpb24gbWVzaEFyY3ModG9wb2xvZ3ksIG9iamVjdCQkMSwgZmlsdGVyKSB7XG4gIHZhciBhcmNzLCBpLCBuO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIGFyY3MgPSBleHRyYWN0QXJjcyh0b3BvbG9neSwgb2JqZWN0JCQxLCBmaWx0ZXIpO1xuICBlbHNlIGZvciAoaSA9IDAsIGFyY3MgPSBuZXcgQXJyYXkobiA9IHRvcG9sb2d5LmFyY3MubGVuZ3RoKTsgaSA8IG47ICsraSkgYXJjc1tpXSA9IGk7XG4gIHJldHVybiB7dHlwZTogXCJNdWx0aUxpbmVTdHJpbmdcIiwgYXJjczogc3RpdGNoKHRvcG9sb2d5LCBhcmNzKX07XG59XG5cbmZ1bmN0aW9uIGV4dHJhY3RBcmNzKHRvcG9sb2d5LCBvYmplY3QkJDEsIGZpbHRlcikge1xuICB2YXIgYXJjcyA9IFtdLFxuICAgICAgZ2VvbXNCeUFyYyA9IFtdLFxuICAgICAgZ2VvbTtcblxuICBmdW5jdGlvbiBleHRyYWN0MChpKSB7XG4gICAgdmFyIGogPSBpIDwgMCA/IH5pIDogaTtcbiAgICAoZ2VvbXNCeUFyY1tqXSB8fCAoZ2VvbXNCeUFyY1tqXSA9IFtdKSkucHVzaCh7aTogaSwgZzogZ2VvbX0pO1xuICB9XG5cbiAgZnVuY3Rpb24gZXh0cmFjdDEoYXJjcykge1xuICAgIGFyY3MuZm9yRWFjaChleHRyYWN0MCk7XG4gIH1cblxuICBmdW5jdGlvbiBleHRyYWN0MihhcmNzKSB7XG4gICAgYXJjcy5mb3JFYWNoKGV4dHJhY3QxKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGV4dHJhY3QzKGFyY3MpIHtcbiAgICBhcmNzLmZvckVhY2goZXh0cmFjdDIpO1xuICB9XG5cbiAgZnVuY3Rpb24gZ2VvbWV0cnkobykge1xuICAgIHN3aXRjaCAoZ2VvbSA9IG8sIG8udHlwZSkge1xuICAgICAgY2FzZSBcIkdlb21ldHJ5Q29sbGVjdGlvblwiOiBvLmdlb21ldHJpZXMuZm9yRWFjaChnZW9tZXRyeSk7IGJyZWFrO1xuICAgICAgY2FzZSBcIkxpbmVTdHJpbmdcIjogZXh0cmFjdDEoby5hcmNzKTsgYnJlYWs7XG4gICAgICBjYXNlIFwiTXVsdGlMaW5lU3RyaW5nXCI6IGNhc2UgXCJQb2x5Z29uXCI6IGV4dHJhY3QyKG8uYXJjcyk7IGJyZWFrO1xuICAgICAgY2FzZSBcIk11bHRpUG9seWdvblwiOiBleHRyYWN0MyhvLmFyY3MpOyBicmVhaztcbiAgICB9XG4gIH1cblxuICBnZW9tZXRyeShvYmplY3QkJDEpO1xuXG4gIGdlb21zQnlBcmMuZm9yRWFjaChmaWx0ZXIgPT0gbnVsbFxuICAgICAgPyBmdW5jdGlvbihnZW9tcykgeyBhcmNzLnB1c2goZ2VvbXNbMF0uaSk7IH1cbiAgICAgIDogZnVuY3Rpb24oZ2VvbXMpIHsgaWYgKGZpbHRlcihnZW9tc1swXS5nLCBnZW9tc1tnZW9tcy5sZW5ndGggLSAxXS5nKSkgYXJjcy5wdXNoKGdlb21zWzBdLmkpOyB9KTtcblxuICByZXR1cm4gYXJjcztcbn1cblxudmFyIGJpc2VjdCA9IGZ1bmN0aW9uKGEsIHgpIHtcbiAgdmFyIGxvID0gMCwgaGkgPSBhLmxlbmd0aDtcbiAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICB2YXIgbWlkID0gbG8gKyBoaSA+Pj4gMTtcbiAgICBpZiAoYVttaWRdIDwgeCkgbG8gPSBtaWQgKyAxO1xuICAgIGVsc2UgaGkgPSBtaWQ7XG4gIH1cbiAgcmV0dXJuIGxvO1xufTtcblxudmFyIHRvcG9qc29uID0gZnVuY3Rpb24oZGF0YSwgZm9ybWF0KSB7XG4gIHZhciBtZXRob2QsIG9iamVjdCwgcHJvcGVydHk7XG4gIGRhdGEgPSBqc29uJDEoZGF0YSwgZm9ybWF0KTtcblxuICBtZXRob2QgPSAoZm9ybWF0ICYmIChwcm9wZXJ0eSA9IGZvcm1hdC5mZWF0dXJlKSkgPyBmZWF0dXJlXG4gICAgOiAoZm9ybWF0ICYmIChwcm9wZXJ0eSA9IGZvcm1hdC5tZXNoKSkgPyBtZXNoXG4gICAgOiBlcnJvciQxKCdNaXNzaW5nIFRvcG9KU09OIGZlYXR1cmUgb3IgbWVzaCBwYXJhbWV0ZXIuJyk7XG5cbiAgb2JqZWN0ID0gKG9iamVjdCA9IGRhdGEub2JqZWN0c1twcm9wZXJ0eV0pXG4gICAgPyBtZXRob2QoZGF0YSwgb2JqZWN0KVxuICAgIDogZXJyb3IkMSgnSW52YWxpZCBUb3BvSlNPTiBvYmplY3Q6ICcgKyBwcm9wZXJ0eSk7XG5cbiAgcmV0dXJuIG9iamVjdCAmJiBvYmplY3QuZmVhdHVyZXMgfHwgW29iamVjdF07XG59O1xuXG52YXIgZm9ybWF0cyA9IHtcbiAgZHN2OiBkc3YkMSxcbiAgY3N2OiBkZWxpbWl0ZWRGb3JtYXQoJywnKSxcbiAgdHN2OiBkZWxpbWl0ZWRGb3JtYXQoJ1xcdCcpLFxuICBqc29uOiBqc29uJDEsXG4gIHRvcG9qc29uOiB0b3BvanNvblxufTtcblxudmFyIGZvcm1hdHMkMSA9IGZ1bmN0aW9uKG5hbWUsIGZvcm1hdCkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICBmb3JtYXRzW25hbWVdID0gZm9ybWF0O1xuICAgIHJldHVybiB0aGlzO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmb3JtYXRzLmhhc093blByb3BlcnR5KG5hbWUpID8gZm9ybWF0c1tuYW1lXSA6IG51bGw7XG4gIH1cbn07XG5cbnZhciB0MCA9IG5ldyBEYXRlO1xudmFyIHQxID0gbmV3IERhdGU7XG5cbmZ1bmN0aW9uIG5ld0ludGVydmFsKGZsb29yaSwgb2Zmc2V0aSwgY291bnQsIGZpZWxkKSB7XG5cbiAgZnVuY3Rpb24gaW50ZXJ2YWwoZGF0ZSkge1xuICAgIHJldHVybiBmbG9vcmkoZGF0ZSA9IG5ldyBEYXRlKCtkYXRlKSksIGRhdGU7XG4gIH1cblxuICBpbnRlcnZhbC5mbG9vciA9IGludGVydmFsO1xuXG4gIGludGVydmFsLmNlaWwgPSBmdW5jdGlvbihkYXRlKSB7XG4gICAgcmV0dXJuIGZsb29yaShkYXRlID0gbmV3IERhdGUoZGF0ZSAtIDEpKSwgb2Zmc2V0aShkYXRlLCAxKSwgZmxvb3JpKGRhdGUpLCBkYXRlO1xuICB9O1xuXG4gIGludGVydmFsLnJvdW5kID0gZnVuY3Rpb24oZGF0ZSkge1xuICAgIHZhciBkMCA9IGludGVydmFsKGRhdGUpLFxuICAgICAgICBkMSA9IGludGVydmFsLmNlaWwoZGF0ZSk7XG4gICAgcmV0dXJuIGRhdGUgLSBkMCA8IGQxIC0gZGF0ZSA/IGQwIDogZDE7XG4gIH07XG5cbiAgaW50ZXJ2YWwub2Zmc2V0ID0gZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIHJldHVybiBvZmZzZXRpKGRhdGUgPSBuZXcgRGF0ZSgrZGF0ZSksIHN0ZXAgPT0gbnVsbCA/IDEgOiBNYXRoLmZsb29yKHN0ZXApKSwgZGF0ZTtcbiAgfTtcblxuICBpbnRlcnZhbC5yYW5nZSA9IGZ1bmN0aW9uKHN0YXJ0LCBzdG9wLCBzdGVwKSB7XG4gICAgdmFyIHJhbmdlID0gW10sIHByZXZpb3VzO1xuICAgIHN0YXJ0ID0gaW50ZXJ2YWwuY2VpbChzdGFydCk7XG4gICAgc3RlcCA9IHN0ZXAgPT0gbnVsbCA/IDEgOiBNYXRoLmZsb29yKHN0ZXApO1xuICAgIGlmICghKHN0YXJ0IDwgc3RvcCkgfHwgIShzdGVwID4gMCkpIHJldHVybiByYW5nZTsgLy8gYWxzbyBoYW5kbGVzIEludmFsaWQgRGF0ZVxuICAgIGRvIHJhbmdlLnB1c2gocHJldmlvdXMgPSBuZXcgRGF0ZSgrc3RhcnQpKSwgb2Zmc2V0aShzdGFydCwgc3RlcCksIGZsb29yaShzdGFydCk7XG4gICAgd2hpbGUgKHByZXZpb3VzIDwgc3RhcnQgJiYgc3RhcnQgPCBzdG9wKTtcbiAgICByZXR1cm4gcmFuZ2U7XG4gIH07XG5cbiAgaW50ZXJ2YWwuZmlsdGVyID0gZnVuY3Rpb24odGVzdCkge1xuICAgIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgICBpZiAoZGF0ZSA+PSBkYXRlKSB3aGlsZSAoZmxvb3JpKGRhdGUpLCAhdGVzdChkYXRlKSkgZGF0ZS5zZXRUaW1lKGRhdGUgLSAxKTtcbiAgICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgICBpZiAoZGF0ZSA+PSBkYXRlKSB7XG4gICAgICAgIGlmIChzdGVwIDwgMCkgd2hpbGUgKCsrc3RlcCA8PSAwKSB7XG4gICAgICAgICAgd2hpbGUgKG9mZnNldGkoZGF0ZSwgLTEpLCAhdGVzdChkYXRlKSkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eVxuICAgICAgICB9IGVsc2Ugd2hpbGUgKC0tc3RlcCA+PSAwKSB7XG4gICAgICAgICAgd2hpbGUgKG9mZnNldGkoZGF0ZSwgKzEpLCAhdGVzdChkYXRlKSkge30gLy8gZXNsaW50LWRpc2FibGUtbGluZSBuby1lbXB0eVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG5cbiAgaWYgKGNvdW50KSB7XG4gICAgaW50ZXJ2YWwuY291bnQgPSBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgICB0MC5zZXRUaW1lKCtzdGFydCksIHQxLnNldFRpbWUoK2VuZCk7XG4gICAgICBmbG9vcmkodDApLCBmbG9vcmkodDEpO1xuICAgICAgcmV0dXJuIE1hdGguZmxvb3IoY291bnQodDAsIHQxKSk7XG4gICAgfTtcblxuICAgIGludGVydmFsLmV2ZXJ5ID0gZnVuY3Rpb24oc3RlcCkge1xuICAgICAgc3RlcCA9IE1hdGguZmxvb3Ioc3RlcCk7XG4gICAgICByZXR1cm4gIWlzRmluaXRlKHN0ZXApIHx8ICEoc3RlcCA+IDApID8gbnVsbFxuICAgICAgICAgIDogIShzdGVwID4gMSkgPyBpbnRlcnZhbFxuICAgICAgICAgIDogaW50ZXJ2YWwuZmlsdGVyKGZpZWxkXG4gICAgICAgICAgICAgID8gZnVuY3Rpb24oZCkgeyByZXR1cm4gZmllbGQoZCkgJSBzdGVwID09PSAwOyB9XG4gICAgICAgICAgICAgIDogZnVuY3Rpb24oZCkgeyByZXR1cm4gaW50ZXJ2YWwuY291bnQoMCwgZCkgJSBzdGVwID09PSAwOyB9KTtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIGludGVydmFsO1xufVxuXG52YXIgbWlsbGlzZWNvbmQgPSBuZXdJbnRlcnZhbChmdW5jdGlvbigpIHtcbiAgLy8gbm9vcFxufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIGVuZCAtIHN0YXJ0O1xufSk7XG5cbi8vIEFuIG9wdGltaXplZCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBzaW1wbGUgY2FzZS5cbm1pbGxpc2Vjb25kLmV2ZXJ5ID0gZnVuY3Rpb24oaykge1xuICBrID0gTWF0aC5mbG9vcihrKTtcbiAgaWYgKCFpc0Zpbml0ZShrKSB8fCAhKGsgPiAwKSkgcmV0dXJuIG51bGw7XG4gIGlmICghKGsgPiAxKSkgcmV0dXJuIG1pbGxpc2Vjb25kO1xuICByZXR1cm4gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VGltZShNYXRoLmZsb29yKGRhdGUgLyBrKSAqIGspO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIGspO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBrO1xuICB9KTtcbn07XG5cbnZhciBkdXJhdGlvblNlY29uZCA9IDFlMztcbnZhciBkdXJhdGlvbk1pbnV0ZSA9IDZlNDtcbnZhciBkdXJhdGlvbkhvdXIgPSAzNmU1O1xudmFyIGR1cmF0aW9uRGF5ID0gODY0ZTU7XG52YXIgZHVyYXRpb25XZWVrID0gNjA0OGU1O1xuXG52YXIgc2Vjb25kID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldFRpbWUoTWF0aC5mbG9vcihkYXRlIC8gZHVyYXRpb25TZWNvbmQpICogZHVyYXRpb25TZWNvbmQpO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25TZWNvbmQpO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGR1cmF0aW9uU2Vjb25kO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRVVENTZWNvbmRzKCk7XG59KTtcblxudmFyIG1pbnV0ZSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRUaW1lKE1hdGguZmxvb3IoZGF0ZSAvIGR1cmF0aW9uTWludXRlKSAqIGR1cmF0aW9uTWludXRlKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRUaW1lKCtkYXRlICsgc3RlcCAqIGR1cmF0aW9uTWludXRlKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvbk1pbnV0ZTtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0TWludXRlcygpO1xufSk7XG5cbnZhciBob3VyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICB2YXIgb2Zmc2V0ID0gZGF0ZS5nZXRUaW1lem9uZU9mZnNldCgpICogZHVyYXRpb25NaW51dGUgJSBkdXJhdGlvbkhvdXI7XG4gIGlmIChvZmZzZXQgPCAwKSBvZmZzZXQgKz0gZHVyYXRpb25Ib3VyO1xuICBkYXRlLnNldFRpbWUoTWF0aC5mbG9vcigoK2RhdGUgLSBvZmZzZXQpIC8gZHVyYXRpb25Ib3VyKSAqIGR1cmF0aW9uSG91ciArIG9mZnNldCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiBkdXJhdGlvbkhvdXIpO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gKGVuZCAtIHN0YXJ0KSAvIGR1cmF0aW9uSG91cjtcbn0sIGZ1bmN0aW9uKGRhdGUpIHtcbiAgcmV0dXJuIGRhdGUuZ2V0SG91cnMoKTtcbn0pO1xuXG52YXIgZGF5ID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCAtIChlbmQuZ2V0VGltZXpvbmVPZmZzZXQoKSAtIHN0YXJ0LmdldFRpbWV6b25lT2Zmc2V0KCkpICogZHVyYXRpb25NaW51dGUpIC8gZHVyYXRpb25EYXk7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldERhdGUoKSAtIDE7XG59KTtcblxuZnVuY3Rpb24gd2Vla2RheShpKSB7XG4gIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpIC0gKGRhdGUuZ2V0RGF5KCkgKyA3IC0gaSkgJSA3KTtcbiAgICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpICsgc3RlcCAqIDcpO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChlbmQgLSBzdGFydCAtIChlbmQuZ2V0VGltZXpvbmVPZmZzZXQoKSAtIHN0YXJ0LmdldFRpbWV6b25lT2Zmc2V0KCkpICogZHVyYXRpb25NaW51dGUpIC8gZHVyYXRpb25XZWVrO1xuICB9KTtcbn1cblxudmFyIHN1bmRheSA9IHdlZWtkYXkoMCk7XG52YXIgbW9uZGF5ID0gd2Vla2RheSgxKTtcbnZhciB0dWVzZGF5ID0gd2Vla2RheSgyKTtcbnZhciB3ZWRuZXNkYXkgPSB3ZWVrZGF5KDMpO1xudmFyIHRodXJzZGF5ID0gd2Vla2RheSg0KTtcbnZhciBmcmlkYXkgPSB3ZWVrZGF5KDUpO1xudmFyIHNhdHVyZGF5ID0gd2Vla2RheSg2KTtcblxudmFyIG1vbnRoID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldERhdGUoMSk7XG4gIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0TW9udGgoZGF0ZS5nZXRNb250aCgpICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiBlbmQuZ2V0TW9udGgoKSAtIHN0YXJ0LmdldE1vbnRoKCkgKyAoZW5kLmdldEZ1bGxZZWFyKCkgLSBzdGFydC5nZXRGdWxsWWVhcigpKSAqIDEyO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRNb250aCgpO1xufSk7XG5cbnZhciB5ZWFyID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldE1vbnRoKDAsIDEpO1xuICBkYXRlLnNldEhvdXJzKDAsIDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldEZ1bGxZZWFyKGRhdGUuZ2V0RnVsbFllYXIoKSArIHN0ZXApO1xufSwgZnVuY3Rpb24oc3RhcnQsIGVuZCkge1xuICByZXR1cm4gZW5kLmdldEZ1bGxZZWFyKCkgLSBzdGFydC5nZXRGdWxsWWVhcigpO1xufSwgZnVuY3Rpb24oZGF0ZSkge1xuICByZXR1cm4gZGF0ZS5nZXRGdWxsWWVhcigpO1xufSk7XG5cbi8vIEFuIG9wdGltaXplZCBpbXBsZW1lbnRhdGlvbiBmb3IgdGhpcyBzaW1wbGUgY2FzZS5cbnllYXIuZXZlcnkgPSBmdW5jdGlvbihrKSB7XG4gIHJldHVybiAhaXNGaW5pdGUoayA9IE1hdGguZmxvb3IoaykpIHx8ICEoayA+IDApID8gbnVsbCA6IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgICBkYXRlLnNldEZ1bGxZZWFyKE1hdGguZmxvb3IoZGF0ZS5nZXRGdWxsWWVhcigpIC8gaykgKiBrKTtcbiAgICBkYXRlLnNldE1vbnRoKDAsIDEpO1xuICAgIGRhdGUuc2V0SG91cnMoMCwgMCwgMCwgMCk7XG4gIH0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgICBkYXRlLnNldEZ1bGxZZWFyKGRhdGUuZ2V0RnVsbFllYXIoKSArIHN0ZXAgKiBrKTtcbiAgfSk7XG59O1xuXG52YXIgdXRjTWludXRlID0gbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICBkYXRlLnNldFVUQ1NlY29uZHMoMCwgMCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VGltZSgrZGF0ZSArIHN0ZXAgKiBkdXJhdGlvbk1pbnV0ZSk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25NaW51dGU7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ01pbnV0ZXMoKTtcbn0pO1xuXG52YXIgdXRjSG91ciA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENNaW51dGVzKDAsIDAsIDApO1xufSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICBkYXRlLnNldFRpbWUoK2RhdGUgKyBzdGVwICogZHVyYXRpb25Ib3VyKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvbkhvdXI7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ0hvdXJzKCk7XG59KTtcblxudmFyIHV0Y0RheSA9IG5ld0ludGVydmFsKGZ1bmN0aW9uKGRhdGUpIHtcbiAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiAoZW5kIC0gc3RhcnQpIC8gZHVyYXRpb25EYXk7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ0RhdGUoKSAtIDE7XG59KTtcblxuZnVuY3Rpb24gdXRjV2Vla2RheShpKSB7XG4gIHJldHVybiBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gICAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpIC0gKGRhdGUuZ2V0VVRDRGF5KCkgKyA3IC0gaSkgJSA3KTtcbiAgICBkYXRlLnNldFVUQ0hvdXJzKDAsIDAsIDAsIDApO1xuICB9LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gICAgZGF0ZS5zZXRVVENEYXRlKGRhdGUuZ2V0VVRDRGF0ZSgpICsgc3RlcCAqIDcpO1xuICB9LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gICAgcmV0dXJuIChlbmQgLSBzdGFydCkgLyBkdXJhdGlvbldlZWs7XG4gIH0pO1xufVxuXG52YXIgdXRjU3VuZGF5ID0gdXRjV2Vla2RheSgwKTtcbnZhciB1dGNNb25kYXkgPSB1dGNXZWVrZGF5KDEpO1xudmFyIHV0Y1R1ZXNkYXkgPSB1dGNXZWVrZGF5KDIpO1xudmFyIHV0Y1dlZG5lc2RheSA9IHV0Y1dlZWtkYXkoMyk7XG52YXIgdXRjVGh1cnNkYXkgPSB1dGNXZWVrZGF5KDQpO1xudmFyIHV0Y0ZyaWRheSA9IHV0Y1dlZWtkYXkoNSk7XG52YXIgdXRjU2F0dXJkYXkgPSB1dGNXZWVrZGF5KDYpO1xuXG52YXIgdXRjTW9udGggPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0VVRDRGF0ZSgxKTtcbiAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbn0sIGZ1bmN0aW9uKGRhdGUsIHN0ZXApIHtcbiAgZGF0ZS5zZXRVVENNb250aChkYXRlLmdldFVUQ01vbnRoKCkgKyBzdGVwKTtcbn0sIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgcmV0dXJuIGVuZC5nZXRVVENNb250aCgpIC0gc3RhcnQuZ2V0VVRDTW9udGgoKSArIChlbmQuZ2V0VVRDRnVsbFllYXIoKSAtIHN0YXJ0LmdldFVUQ0Z1bGxZZWFyKCkpICogMTI7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ01vbnRoKCk7XG59KTtcblxudmFyIHV0Y1llYXIgPSBuZXdJbnRlcnZhbChmdW5jdGlvbihkYXRlKSB7XG4gIGRhdGUuc2V0VVRDTW9udGgoMCwgMSk7XG4gIGRhdGUuc2V0VVRDSG91cnMoMCwgMCwgMCwgMCk7XG59LCBmdW5jdGlvbihkYXRlLCBzdGVwKSB7XG4gIGRhdGUuc2V0VVRDRnVsbFllYXIoZGF0ZS5nZXRVVENGdWxsWWVhcigpICsgc3RlcCk7XG59LCBmdW5jdGlvbihzdGFydCwgZW5kKSB7XG4gIHJldHVybiBlbmQuZ2V0VVRDRnVsbFllYXIoKSAtIHN0YXJ0LmdldFVUQ0Z1bGxZZWFyKCk7XG59LCBmdW5jdGlvbihkYXRlKSB7XG4gIHJldHVybiBkYXRlLmdldFVUQ0Z1bGxZZWFyKCk7XG59KTtcblxuLy8gQW4gb3B0aW1pemVkIGltcGxlbWVudGF0aW9uIGZvciB0aGlzIHNpbXBsZSBjYXNlLlxudXRjWWVhci5ldmVyeSA9IGZ1bmN0aW9uKGspIHtcbiAgcmV0dXJuICFpc0Zpbml0ZShrID0gTWF0aC5mbG9vcihrKSkgfHwgIShrID4gMCkgPyBudWxsIDogbmV3SW50ZXJ2YWwoZnVuY3Rpb24oZGF0ZSkge1xuICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoTWF0aC5mbG9vcihkYXRlLmdldFVUQ0Z1bGxZZWFyKCkgLyBrKSAqIGspO1xuICAgIGRhdGUuc2V0VVRDTW9udGgoMCwgMSk7XG4gICAgZGF0ZS5zZXRVVENIb3VycygwLCAwLCAwLCAwKTtcbiAgfSwgZnVuY3Rpb24oZGF0ZSwgc3RlcCkge1xuICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoZGF0ZS5nZXRVVENGdWxsWWVhcigpICsgc3RlcCAqIGspO1xuICB9KTtcbn07XG5cbmZ1bmN0aW9uIGxvY2FsRGF0ZShkKSB7XG4gIGlmICgwIDw9IGQueSAmJiBkLnkgPCAxMDApIHtcbiAgICB2YXIgZGF0ZSA9IG5ldyBEYXRlKC0xLCBkLm0sIGQuZCwgZC5ILCBkLk0sIGQuUywgZC5MKTtcbiAgICBkYXRlLnNldEZ1bGxZZWFyKGQueSk7XG4gICAgcmV0dXJuIGRhdGU7XG4gIH1cbiAgcmV0dXJuIG5ldyBEYXRlKGQueSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCk7XG59XG5cbmZ1bmN0aW9uIHV0Y0RhdGUoZCkge1xuICBpZiAoMCA8PSBkLnkgJiYgZC55IDwgMTAwKSB7XG4gICAgdmFyIGRhdGUgPSBuZXcgRGF0ZShEYXRlLlVUQygtMSwgZC5tLCBkLmQsIGQuSCwgZC5NLCBkLlMsIGQuTCkpO1xuICAgIGRhdGUuc2V0VVRDRnVsbFllYXIoZC55KTtcbiAgICByZXR1cm4gZGF0ZTtcbiAgfVxuICByZXR1cm4gbmV3IERhdGUoRGF0ZS5VVEMoZC55LCBkLm0sIGQuZCwgZC5ILCBkLk0sIGQuUywgZC5MKSk7XG59XG5cbmZ1bmN0aW9uIG5ld1llYXIoeSkge1xuICByZXR1cm4ge3k6IHksIG06IDAsIGQ6IDEsIEg6IDAsIE06IDAsIFM6IDAsIEw6IDB9O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRMb2NhbGUobG9jYWxlKSB7XG4gIHZhciBsb2NhbGVfZGF0ZVRpbWUgPSBsb2NhbGUuZGF0ZVRpbWUsXG4gICAgICBsb2NhbGVfZGF0ZSA9IGxvY2FsZS5kYXRlLFxuICAgICAgbG9jYWxlX3RpbWUgPSBsb2NhbGUudGltZSxcbiAgICAgIGxvY2FsZV9wZXJpb2RzID0gbG9jYWxlLnBlcmlvZHMsXG4gICAgICBsb2NhbGVfd2Vla2RheXMgPSBsb2NhbGUuZGF5cyxcbiAgICAgIGxvY2FsZV9zaG9ydFdlZWtkYXlzID0gbG9jYWxlLnNob3J0RGF5cyxcbiAgICAgIGxvY2FsZV9tb250aHMgPSBsb2NhbGUubW9udGhzLFxuICAgICAgbG9jYWxlX3Nob3J0TW9udGhzID0gbG9jYWxlLnNob3J0TW9udGhzO1xuXG4gIHZhciBwZXJpb2RSZSA9IGZvcm1hdFJlKGxvY2FsZV9wZXJpb2RzKSxcbiAgICAgIHBlcmlvZExvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfcGVyaW9kcyksXG4gICAgICB3ZWVrZGF5UmUgPSBmb3JtYXRSZShsb2NhbGVfd2Vla2RheXMpLFxuICAgICAgd2Vla2RheUxvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfd2Vla2RheXMpLFxuICAgICAgc2hvcnRXZWVrZGF5UmUgPSBmb3JtYXRSZShsb2NhbGVfc2hvcnRXZWVrZGF5cyksXG4gICAgICBzaG9ydFdlZWtkYXlMb29rdXAgPSBmb3JtYXRMb29rdXAobG9jYWxlX3Nob3J0V2Vla2RheXMpLFxuICAgICAgbW9udGhSZSA9IGZvcm1hdFJlKGxvY2FsZV9tb250aHMpLFxuICAgICAgbW9udGhMb29rdXAgPSBmb3JtYXRMb29rdXAobG9jYWxlX21vbnRocyksXG4gICAgICBzaG9ydE1vbnRoUmUgPSBmb3JtYXRSZShsb2NhbGVfc2hvcnRNb250aHMpLFxuICAgICAgc2hvcnRNb250aExvb2t1cCA9IGZvcm1hdExvb2t1cChsb2NhbGVfc2hvcnRNb250aHMpO1xuXG4gIHZhciBmb3JtYXRzID0ge1xuICAgIFwiYVwiOiBmb3JtYXRTaG9ydFdlZWtkYXksXG4gICAgXCJBXCI6IGZvcm1hdFdlZWtkYXksXG4gICAgXCJiXCI6IGZvcm1hdFNob3J0TW9udGgsXG4gICAgXCJCXCI6IGZvcm1hdE1vbnRoLFxuICAgIFwiY1wiOiBudWxsLFxuICAgIFwiZFwiOiBmb3JtYXREYXlPZk1vbnRoLFxuICAgIFwiZVwiOiBmb3JtYXREYXlPZk1vbnRoLFxuICAgIFwiZlwiOiBmb3JtYXRNaWNyb3NlY29uZHMsXG4gICAgXCJIXCI6IGZvcm1hdEhvdXIyNCxcbiAgICBcIklcIjogZm9ybWF0SG91cjEyLFxuICAgIFwialwiOiBmb3JtYXREYXlPZlllYXIsXG4gICAgXCJMXCI6IGZvcm1hdE1pbGxpc2Vjb25kcyxcbiAgICBcIm1cIjogZm9ybWF0TW9udGhOdW1iZXIsXG4gICAgXCJNXCI6IGZvcm1hdE1pbnV0ZXMsXG4gICAgXCJwXCI6IGZvcm1hdFBlcmlvZCxcbiAgICBcIlFcIjogZm9ybWF0VW5peFRpbWVzdGFtcCxcbiAgICBcInNcIjogZm9ybWF0VW5peFRpbWVzdGFtcFNlY29uZHMsXG4gICAgXCJTXCI6IGZvcm1hdFNlY29uZHMsXG4gICAgXCJ1XCI6IGZvcm1hdFdlZWtkYXlOdW1iZXJNb25kYXksXG4gICAgXCJVXCI6IGZvcm1hdFdlZWtOdW1iZXJTdW5kYXksXG4gICAgXCJWXCI6IGZvcm1hdFdlZWtOdW1iZXJJU08sXG4gICAgXCJ3XCI6IGZvcm1hdFdlZWtkYXlOdW1iZXJTdW5kYXksXG4gICAgXCJXXCI6IGZvcm1hdFdlZWtOdW1iZXJNb25kYXksXG4gICAgXCJ4XCI6IG51bGwsXG4gICAgXCJYXCI6IG51bGwsXG4gICAgXCJ5XCI6IGZvcm1hdFllYXIsXG4gICAgXCJZXCI6IGZvcm1hdEZ1bGxZZWFyLFxuICAgIFwiWlwiOiBmb3JtYXRab25lLFxuICAgIFwiJVwiOiBmb3JtYXRMaXRlcmFsUGVyY2VudFxuICB9O1xuXG4gIHZhciB1dGNGb3JtYXRzID0ge1xuICAgIFwiYVwiOiBmb3JtYXRVVENTaG9ydFdlZWtkYXksXG4gICAgXCJBXCI6IGZvcm1hdFVUQ1dlZWtkYXksXG4gICAgXCJiXCI6IGZvcm1hdFVUQ1Nob3J0TW9udGgsXG4gICAgXCJCXCI6IGZvcm1hdFVUQ01vbnRoLFxuICAgIFwiY1wiOiBudWxsLFxuICAgIFwiZFwiOiBmb3JtYXRVVENEYXlPZk1vbnRoLFxuICAgIFwiZVwiOiBmb3JtYXRVVENEYXlPZk1vbnRoLFxuICAgIFwiZlwiOiBmb3JtYXRVVENNaWNyb3NlY29uZHMsXG4gICAgXCJIXCI6IGZvcm1hdFVUQ0hvdXIyNCxcbiAgICBcIklcIjogZm9ybWF0VVRDSG91cjEyLFxuICAgIFwialwiOiBmb3JtYXRVVENEYXlPZlllYXIsXG4gICAgXCJMXCI6IGZvcm1hdFVUQ01pbGxpc2Vjb25kcyxcbiAgICBcIm1cIjogZm9ybWF0VVRDTW9udGhOdW1iZXIsXG4gICAgXCJNXCI6IGZvcm1hdFVUQ01pbnV0ZXMsXG4gICAgXCJwXCI6IGZvcm1hdFVUQ1BlcmlvZCxcbiAgICBcIlFcIjogZm9ybWF0VW5peFRpbWVzdGFtcCxcbiAgICBcInNcIjogZm9ybWF0VW5peFRpbWVzdGFtcFNlY29uZHMsXG4gICAgXCJTXCI6IGZvcm1hdFVUQ1NlY29uZHMsXG4gICAgXCJ1XCI6IGZvcm1hdFVUQ1dlZWtkYXlOdW1iZXJNb25kYXksXG4gICAgXCJVXCI6IGZvcm1hdFVUQ1dlZWtOdW1iZXJTdW5kYXksXG4gICAgXCJWXCI6IGZvcm1hdFVUQ1dlZWtOdW1iZXJJU08sXG4gICAgXCJ3XCI6IGZvcm1hdFVUQ1dlZWtkYXlOdW1iZXJTdW5kYXksXG4gICAgXCJXXCI6IGZvcm1hdFVUQ1dlZWtOdW1iZXJNb25kYXksXG4gICAgXCJ4XCI6IG51bGwsXG4gICAgXCJYXCI6IG51bGwsXG4gICAgXCJ5XCI6IGZvcm1hdFVUQ1llYXIsXG4gICAgXCJZXCI6IGZvcm1hdFVUQ0Z1bGxZZWFyLFxuICAgIFwiWlwiOiBmb3JtYXRVVENab25lLFxuICAgIFwiJVwiOiBmb3JtYXRMaXRlcmFsUGVyY2VudFxuICB9O1xuXG4gIHZhciBwYXJzZXMgPSB7XG4gICAgXCJhXCI6IHBhcnNlU2hvcnRXZWVrZGF5LFxuICAgIFwiQVwiOiBwYXJzZVdlZWtkYXksXG4gICAgXCJiXCI6IHBhcnNlU2hvcnRNb250aCxcbiAgICBcIkJcIjogcGFyc2VNb250aCxcbiAgICBcImNcIjogcGFyc2VMb2NhbGVEYXRlVGltZSxcbiAgICBcImRcIjogcGFyc2VEYXlPZk1vbnRoLFxuICAgIFwiZVwiOiBwYXJzZURheU9mTW9udGgsXG4gICAgXCJmXCI6IHBhcnNlTWljcm9zZWNvbmRzLFxuICAgIFwiSFwiOiBwYXJzZUhvdXIyNCxcbiAgICBcIklcIjogcGFyc2VIb3VyMjQsXG4gICAgXCJqXCI6IHBhcnNlRGF5T2ZZZWFyLFxuICAgIFwiTFwiOiBwYXJzZU1pbGxpc2Vjb25kcyxcbiAgICBcIm1cIjogcGFyc2VNb250aE51bWJlcixcbiAgICBcIk1cIjogcGFyc2VNaW51dGVzLFxuICAgIFwicFwiOiBwYXJzZVBlcmlvZCxcbiAgICBcIlFcIjogcGFyc2VVbml4VGltZXN0YW1wLFxuICAgIFwic1wiOiBwYXJzZVVuaXhUaW1lc3RhbXBTZWNvbmRzLFxuICAgIFwiU1wiOiBwYXJzZVNlY29uZHMsXG4gICAgXCJ1XCI6IHBhcnNlV2Vla2RheU51bWJlck1vbmRheSxcbiAgICBcIlVcIjogcGFyc2VXZWVrTnVtYmVyU3VuZGF5LFxuICAgIFwiVlwiOiBwYXJzZVdlZWtOdW1iZXJJU08sXG4gICAgXCJ3XCI6IHBhcnNlV2Vla2RheU51bWJlclN1bmRheSxcbiAgICBcIldcIjogcGFyc2VXZWVrTnVtYmVyTW9uZGF5LFxuICAgIFwieFwiOiBwYXJzZUxvY2FsZURhdGUsXG4gICAgXCJYXCI6IHBhcnNlTG9jYWxlVGltZSxcbiAgICBcInlcIjogcGFyc2VZZWFyLFxuICAgIFwiWVwiOiBwYXJzZUZ1bGxZZWFyLFxuICAgIFwiWlwiOiBwYXJzZVpvbmUsXG4gICAgXCIlXCI6IHBhcnNlTGl0ZXJhbFBlcmNlbnRcbiAgfTtcblxuICAvLyBUaGVzZSByZWN1cnNpdmUgZGlyZWN0aXZlIGRlZmluaXRpb25zIG11c3QgYmUgZGVmZXJyZWQuXG4gIGZvcm1hdHMueCA9IG5ld0Zvcm1hdChsb2NhbGVfZGF0ZSwgZm9ybWF0cyk7XG4gIGZvcm1hdHMuWCA9IG5ld0Zvcm1hdChsb2NhbGVfdGltZSwgZm9ybWF0cyk7XG4gIGZvcm1hdHMuYyA9IG5ld0Zvcm1hdChsb2NhbGVfZGF0ZVRpbWUsIGZvcm1hdHMpO1xuICB1dGNGb3JtYXRzLnggPSBuZXdGb3JtYXQobG9jYWxlX2RhdGUsIHV0Y0Zvcm1hdHMpO1xuICB1dGNGb3JtYXRzLlggPSBuZXdGb3JtYXQobG9jYWxlX3RpbWUsIHV0Y0Zvcm1hdHMpO1xuICB1dGNGb3JtYXRzLmMgPSBuZXdGb3JtYXQobG9jYWxlX2RhdGVUaW1lLCB1dGNGb3JtYXRzKTtcblxuICBmdW5jdGlvbiBuZXdGb3JtYXQoc3BlY2lmaWVyLCBmb3JtYXRzKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKGRhdGUpIHtcbiAgICAgIHZhciBzdHJpbmcgPSBbXSxcbiAgICAgICAgICBpID0gLTEsXG4gICAgICAgICAgaiA9IDAsXG4gICAgICAgICAgbiA9IHNwZWNpZmllci5sZW5ndGgsXG4gICAgICAgICAgYyxcbiAgICAgICAgICBwYWQsXG4gICAgICAgICAgZm9ybWF0O1xuXG4gICAgICBpZiAoIShkYXRlIGluc3RhbmNlb2YgRGF0ZSkpIGRhdGUgPSBuZXcgRGF0ZSgrZGF0ZSk7XG5cbiAgICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICAgIGlmIChzcGVjaWZpZXIuY2hhckNvZGVBdChpKSA9PT0gMzcpIHtcbiAgICAgICAgICBzdHJpbmcucHVzaChzcGVjaWZpZXIuc2xpY2UoaiwgaSkpO1xuICAgICAgICAgIGlmICgocGFkID0gcGFkc1tjID0gc3BlY2lmaWVyLmNoYXJBdCgrK2kpXSkgIT0gbnVsbCkgYyA9IHNwZWNpZmllci5jaGFyQXQoKytpKTtcbiAgICAgICAgICBlbHNlIHBhZCA9IGMgPT09IFwiZVwiID8gXCIgXCIgOiBcIjBcIjtcbiAgICAgICAgICBpZiAoZm9ybWF0ID0gZm9ybWF0c1tjXSkgYyA9IGZvcm1hdChkYXRlLCBwYWQpO1xuICAgICAgICAgIHN0cmluZy5wdXNoKGMpO1xuICAgICAgICAgIGogPSBpICsgMTtcbiAgICAgICAgfVxuICAgICAgfVxuXG4gICAgICBzdHJpbmcucHVzaChzcGVjaWZpZXIuc2xpY2UoaiwgaSkpO1xuICAgICAgcmV0dXJuIHN0cmluZy5qb2luKFwiXCIpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBuZXdQYXJzZShzcGVjaWZpZXIsIG5ld0RhdGUpIHtcbiAgICByZXR1cm4gZnVuY3Rpb24oc3RyaW5nKSB7XG4gICAgICB2YXIgZCA9IG5ld1llYXIoMTkwMCksXG4gICAgICAgICAgaSA9IHBhcnNlU3BlY2lmaWVyKGQsIHNwZWNpZmllciwgc3RyaW5nICs9IFwiXCIsIDApLFxuICAgICAgICAgIHdlZWssIGRheSQkMTtcbiAgICAgIGlmIChpICE9IHN0cmluZy5sZW5ndGgpIHJldHVybiBudWxsO1xuXG4gICAgICAvLyBJZiBhIFVOSVggdGltZXN0YW1wIGlzIHNwZWNpZmllZCwgcmV0dXJuIGl0LlxuICAgICAgaWYgKFwiUVwiIGluIGQpIHJldHVybiBuZXcgRGF0ZShkLlEpO1xuXG4gICAgICAvLyBUaGUgYW0tcG0gZmxhZyBpcyAwIGZvciBBTSwgYW5kIDEgZm9yIFBNLlxuICAgICAgaWYgKFwicFwiIGluIGQpIGQuSCA9IGQuSCAlIDEyICsgZC5wICogMTI7XG5cbiAgICAgIC8vIENvbnZlcnQgZGF5LW9mLXdlZWsgYW5kIHdlZWstb2YteWVhciB0byBkYXktb2YteWVhci5cbiAgICAgIGlmIChcIlZcIiBpbiBkKSB7XG4gICAgICAgIGlmIChkLlYgPCAxIHx8IGQuViA+IDUzKSByZXR1cm4gbnVsbDtcbiAgICAgICAgaWYgKCEoXCJ3XCIgaW4gZCkpIGQudyA9IDE7XG4gICAgICAgIGlmIChcIlpcIiBpbiBkKSB7XG4gICAgICAgICAgd2VlayA9IHV0Y0RhdGUobmV3WWVhcihkLnkpKSwgZGF5JCQxID0gd2Vlay5nZXRVVENEYXkoKTtcbiAgICAgICAgICB3ZWVrID0gZGF5JCQxID4gNCB8fCBkYXkkJDEgPT09IDAgPyB1dGNNb25kYXkuY2VpbCh3ZWVrKSA6IHV0Y01vbmRheSh3ZWVrKTtcbiAgICAgICAgICB3ZWVrID0gdXRjRGF5Lm9mZnNldCh3ZWVrLCAoZC5WIC0gMSkgKiA3KTtcbiAgICAgICAgICBkLnkgPSB3ZWVrLmdldFVUQ0Z1bGxZZWFyKCk7XG4gICAgICAgICAgZC5tID0gd2Vlay5nZXRVVENNb250aCgpO1xuICAgICAgICAgIGQuZCA9IHdlZWsuZ2V0VVRDRGF0ZSgpICsgKGQudyArIDYpICUgNztcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB3ZWVrID0gbmV3RGF0ZShuZXdZZWFyKGQueSkpLCBkYXkkJDEgPSB3ZWVrLmdldERheSgpO1xuICAgICAgICAgIHdlZWsgPSBkYXkkJDEgPiA0IHx8IGRheSQkMSA9PT0gMCA/IG1vbmRheS5jZWlsKHdlZWspIDogbW9uZGF5KHdlZWspO1xuICAgICAgICAgIHdlZWsgPSBkYXkub2Zmc2V0KHdlZWssIChkLlYgLSAxKSAqIDcpO1xuICAgICAgICAgIGQueSA9IHdlZWsuZ2V0RnVsbFllYXIoKTtcbiAgICAgICAgICBkLm0gPSB3ZWVrLmdldE1vbnRoKCk7XG4gICAgICAgICAgZC5kID0gd2Vlay5nZXREYXRlKCkgKyAoZC53ICsgNikgJSA3O1xuICAgICAgICB9XG4gICAgICB9IGVsc2UgaWYgKFwiV1wiIGluIGQgfHwgXCJVXCIgaW4gZCkge1xuICAgICAgICBpZiAoIShcIndcIiBpbiBkKSkgZC53ID0gXCJ1XCIgaW4gZCA/IGQudSAlIDcgOiBcIldcIiBpbiBkID8gMSA6IDA7XG4gICAgICAgIGRheSQkMSA9IFwiWlwiIGluIGQgPyB1dGNEYXRlKG5ld1llYXIoZC55KSkuZ2V0VVRDRGF5KCkgOiBuZXdEYXRlKG5ld1llYXIoZC55KSkuZ2V0RGF5KCk7XG4gICAgICAgIGQubSA9IDA7XG4gICAgICAgIGQuZCA9IFwiV1wiIGluIGQgPyAoZC53ICsgNikgJSA3ICsgZC5XICogNyAtIChkYXkkJDEgKyA1KSAlIDcgOiBkLncgKyBkLlUgKiA3IC0gKGRheSQkMSArIDYpICUgNztcbiAgICAgIH1cblxuICAgICAgLy8gSWYgYSB0aW1lIHpvbmUgaXMgc3BlY2lmaWVkLCBhbGwgZmllbGRzIGFyZSBpbnRlcnByZXRlZCBhcyBVVEMgYW5kIHRoZW5cbiAgICAgIC8vIG9mZnNldCBhY2NvcmRpbmcgdG8gdGhlIHNwZWNpZmllZCB0aW1lIHpvbmUuXG4gICAgICBpZiAoXCJaXCIgaW4gZCkge1xuICAgICAgICBkLkggKz0gZC5aIC8gMTAwIHwgMDtcbiAgICAgICAgZC5NICs9IGQuWiAlIDEwMDtcbiAgICAgICAgcmV0dXJuIHV0Y0RhdGUoZCk7XG4gICAgICB9XG5cbiAgICAgIC8vIE90aGVyd2lzZSwgYWxsIGZpZWxkcyBhcmUgaW4gbG9jYWwgdGltZS5cbiAgICAgIHJldHVybiBuZXdEYXRlKGQpO1xuICAgIH07XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVNwZWNpZmllcihkLCBzcGVjaWZpZXIsIHN0cmluZywgaikge1xuICAgIHZhciBpID0gMCxcbiAgICAgICAgbiA9IHNwZWNpZmllci5sZW5ndGgsXG4gICAgICAgIG0gPSBzdHJpbmcubGVuZ3RoLFxuICAgICAgICBjLFxuICAgICAgICBwYXJzZTtcblxuICAgIHdoaWxlIChpIDwgbikge1xuICAgICAgaWYgKGogPj0gbSkgcmV0dXJuIC0xO1xuICAgICAgYyA9IHNwZWNpZmllci5jaGFyQ29kZUF0KGkrKyk7XG4gICAgICBpZiAoYyA9PT0gMzcpIHtcbiAgICAgICAgYyA9IHNwZWNpZmllci5jaGFyQXQoaSsrKTtcbiAgICAgICAgcGFyc2UgPSBwYXJzZXNbYyBpbiBwYWRzID8gc3BlY2lmaWVyLmNoYXJBdChpKyspIDogY107XG4gICAgICAgIGlmICghcGFyc2UgfHwgKChqID0gcGFyc2UoZCwgc3RyaW5nLCBqKSkgPCAwKSkgcmV0dXJuIC0xO1xuICAgICAgfSBlbHNlIGlmIChjICE9IHN0cmluZy5jaGFyQ29kZUF0KGorKykpIHtcbiAgICAgICAgcmV0dXJuIC0xO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBqO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VQZXJpb2QoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBwZXJpb2RSZS5leGVjKHN0cmluZy5zbGljZShpKSk7XG4gICAgcmV0dXJuIG4gPyAoZC5wID0gcGVyaW9kTG9va3VwW25bMF0udG9Mb3dlckNhc2UoKV0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlU2hvcnRXZWVrZGF5KGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gc2hvcnRXZWVrZGF5UmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICAgIHJldHVybiBuID8gKGQudyA9IHNob3J0V2Vla2RheUxvb2t1cFtuWzBdLnRvTG93ZXJDYXNlKCldLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZVdlZWtkYXkoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSB3ZWVrZGF5UmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICAgIHJldHVybiBuID8gKGQudyA9IHdlZWtkYXlMb29rdXBbblswXS50b0xvd2VyQ2FzZSgpXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VTaG9ydE1vbnRoKGQsIHN0cmluZywgaSkge1xuICAgIHZhciBuID0gc2hvcnRNb250aFJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICByZXR1cm4gbiA/IChkLm0gPSBzaG9ydE1vbnRoTG9va3VwW25bMF0udG9Mb3dlckNhc2UoKV0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBhcnNlTW9udGgoZCwgc3RyaW5nLCBpKSB7XG4gICAgdmFyIG4gPSBtb250aFJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgICByZXR1cm4gbiA/IChkLm0gPSBtb250aExvb2t1cFtuWzBdLnRvTG93ZXJDYXNlKCldLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUxvY2FsZURhdGVUaW1lKGQsIHN0cmluZywgaSkge1xuICAgIHJldHVybiBwYXJzZVNwZWNpZmllcihkLCBsb2NhbGVfZGF0ZVRpbWUsIHN0cmluZywgaSk7XG4gIH1cblxuICBmdW5jdGlvbiBwYXJzZUxvY2FsZURhdGUoZCwgc3RyaW5nLCBpKSB7XG4gICAgcmV0dXJuIHBhcnNlU3BlY2lmaWVyKGQsIGxvY2FsZV9kYXRlLCBzdHJpbmcsIGkpO1xuICB9XG5cbiAgZnVuY3Rpb24gcGFyc2VMb2NhbGVUaW1lKGQsIHN0cmluZywgaSkge1xuICAgIHJldHVybiBwYXJzZVNwZWNpZmllcihkLCBsb2NhbGVfdGltZSwgc3RyaW5nLCBpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFNob3J0V2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9zaG9ydFdlZWtkYXlzW2QuZ2V0RGF5KCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0V2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV93ZWVrZGF5c1tkLmdldERheSgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFNob3J0TW9udGgoZCkge1xuICAgIHJldHVybiBsb2NhbGVfc2hvcnRNb250aHNbZC5nZXRNb250aCgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdE1vbnRoKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX21vbnRoc1tkLmdldE1vbnRoKCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0UGVyaW9kKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX3BlcmlvZHNbKyhkLmdldEhvdXJzKCkgPj0gMTIpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1Nob3J0V2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV9zaG9ydFdlZWtkYXlzW2QuZ2V0VVRDRGF5KCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0VVRDV2Vla2RheShkKSB7XG4gICAgcmV0dXJuIGxvY2FsZV93ZWVrZGF5c1tkLmdldFVUQ0RheSgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ1Nob3J0TW9udGgoZCkge1xuICAgIHJldHVybiBsb2NhbGVfc2hvcnRNb250aHNbZC5nZXRVVENNb250aCgpXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcm1hdFVUQ01vbnRoKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX21vbnRoc1tkLmdldFVUQ01vbnRoKCldO1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0VVRDUGVyaW9kKGQpIHtcbiAgICByZXR1cm4gbG9jYWxlX3BlcmlvZHNbKyhkLmdldFVUQ0hvdXJzKCkgPj0gMTIpXTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgZm9ybWF0OiBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICAgIHZhciBmID0gbmV3Rm9ybWF0KHNwZWNpZmllciArPSBcIlwiLCBmb3JtYXRzKTtcbiAgICAgIGYudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBmO1xuICAgIH0sXG4gICAgcGFyc2U6IGZ1bmN0aW9uKHNwZWNpZmllcikge1xuICAgICAgdmFyIHAgPSBuZXdQYXJzZShzcGVjaWZpZXIgKz0gXCJcIiwgbG9jYWxEYXRlKTtcbiAgICAgIHAudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBwO1xuICAgIH0sXG4gICAgdXRjRm9ybWF0OiBmdW5jdGlvbihzcGVjaWZpZXIpIHtcbiAgICAgIHZhciBmID0gbmV3Rm9ybWF0KHNwZWNpZmllciArPSBcIlwiLCB1dGNGb3JtYXRzKTtcbiAgICAgIGYudG9TdHJpbmcgPSBmdW5jdGlvbigpIHsgcmV0dXJuIHNwZWNpZmllcjsgfTtcbiAgICAgIHJldHVybiBmO1xuICAgIH0sXG4gICAgdXRjUGFyc2U6IGZ1bmN0aW9uKHNwZWNpZmllcikge1xuICAgICAgdmFyIHAgPSBuZXdQYXJzZShzcGVjaWZpZXIsIHV0Y0RhdGUpO1xuICAgICAgcC50b1N0cmluZyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gc3BlY2lmaWVyOyB9O1xuICAgICAgcmV0dXJuIHA7XG4gICAgfVxuICB9O1xufVxuXG52YXIgcGFkcyA9IHtcIi1cIjogXCJcIiwgXCJfXCI6IFwiIFwiLCBcIjBcIjogXCIwXCJ9O1xudmFyIG51bWJlclJlID0gL15cXHMqXFxkKy87XG52YXIgcGVyY2VudFJlID0gL14lLztcbnZhciByZXF1b3RlUmUgPSAvW1xcXFxeJCorP3xbXFxdKCkue31dL2c7XG5cbmZ1bmN0aW9uIHBhZCQxKHZhbHVlLCBmaWxsLCB3aWR0aCkge1xuICB2YXIgc2lnbiA9IHZhbHVlIDwgMCA/IFwiLVwiIDogXCJcIixcbiAgICAgIHN0cmluZyA9IChzaWduID8gLXZhbHVlIDogdmFsdWUpICsgXCJcIixcbiAgICAgIGxlbmd0aCA9IHN0cmluZy5sZW5ndGg7XG4gIHJldHVybiBzaWduICsgKGxlbmd0aCA8IHdpZHRoID8gbmV3IEFycmF5KHdpZHRoIC0gbGVuZ3RoICsgMSkuam9pbihmaWxsKSArIHN0cmluZyA6IHN0cmluZyk7XG59XG5cbmZ1bmN0aW9uIHJlcXVvdGUocykge1xuICByZXR1cm4gcy5yZXBsYWNlKHJlcXVvdGVSZSwgXCJcXFxcJCZcIik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFJlKG5hbWVzKSB7XG4gIHJldHVybiBuZXcgUmVnRXhwKFwiXig/OlwiICsgbmFtZXMubWFwKHJlcXVvdGUpLmpvaW4oXCJ8XCIpICsgXCIpXCIsIFwiaVwiKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TG9va3VwKG5hbWVzKSB7XG4gIHZhciBtYXAgPSB7fSwgaSA9IC0xLCBuID0gbmFtZXMubGVuZ3RoO1xuICB3aGlsZSAoKytpIDwgbikgbWFwW25hbWVzW2ldLnRvTG93ZXJDYXNlKCldID0gaTtcbiAgcmV0dXJuIG1hcDtcbn1cblxuZnVuY3Rpb24gcGFyc2VXZWVrZGF5TnVtYmVyU3VuZGF5KGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAxKSk7XG4gIHJldHVybiBuID8gKGQudyA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlV2Vla2RheU51bWJlck1vbmRheShkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMSkpO1xuICByZXR1cm4gbiA/IChkLnUgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVdlZWtOdW1iZXJTdW5kYXkoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC5VID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VXZWVrTnVtYmVySVNPKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gIHJldHVybiBuID8gKGQuViA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlV2Vla051bWJlck1vbmRheShkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLlcgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZUZ1bGxZZWFyKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyA0KSk7XG4gIHJldHVybiBuID8gKGQueSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlWWVhcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLnkgPSArblswXSArICgrblswXSA+IDY4ID8gMTkwMCA6IDIwMDApLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlWm9uZShkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSAvXihaKXwoWystXVxcZFxcZCkoPzo6PyhcXGRcXGQpKT8vLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyA2KSk7XG4gIHJldHVybiBuID8gKGQuWiA9IG5bMV0gPyAwIDogLShuWzJdICsgKG5bM10gfHwgXCIwMFwiKSksIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNb250aE51bWJlcihkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLm0gPSBuWzBdIC0gMSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZURheU9mTW9udGgoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC5kID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VEYXlPZlllYXIoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDMpKTtcbiAgcmV0dXJuIG4gPyAoZC5tID0gMCwgZC5kID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VIb3VyMjQoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSwgaSArIDIpKTtcbiAgcmV0dXJuIG4gPyAoZC5IID0gK25bMF0sIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNaW51dGVzKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGksIGkgKyAyKSk7XG4gIHJldHVybiBuID8gKGQuTSA9ICtuWzBdLCBpICsgblswXS5sZW5ndGgpIDogLTE7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU2Vjb25kcyhkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMikpO1xuICByZXR1cm4gbiA/IChkLlMgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZU1pbGxpc2Vjb25kcyhkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMykpO1xuICByZXR1cm4gbiA/IChkLkwgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZU1pY3Jvc2Vjb25kcyhkLCBzdHJpbmcsIGkpIHtcbiAgdmFyIG4gPSBudW1iZXJSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgNikpO1xuICByZXR1cm4gbiA/IChkLkwgPSBNYXRoLmZsb29yKG5bMF0gLyAxMDAwKSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZUxpdGVyYWxQZXJjZW50KGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IHBlcmNlbnRSZS5leGVjKHN0cmluZy5zbGljZShpLCBpICsgMSkpO1xuICByZXR1cm4gbiA/IGkgKyBuWzBdLmxlbmd0aCA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVVuaXhUaW1lc3RhbXAoZCwgc3RyaW5nLCBpKSB7XG4gIHZhciBuID0gbnVtYmVyUmUuZXhlYyhzdHJpbmcuc2xpY2UoaSkpO1xuICByZXR1cm4gbiA/IChkLlEgPSArblswXSwgaSArIG5bMF0ubGVuZ3RoKSA6IC0xO1xufVxuXG5mdW5jdGlvbiBwYXJzZVVuaXhUaW1lc3RhbXBTZWNvbmRzKGQsIHN0cmluZywgaSkge1xuICB2YXIgbiA9IG51bWJlclJlLmV4ZWMoc3RyaW5nLnNsaWNlKGkpKTtcbiAgcmV0dXJuIG4gPyAoZC5RID0gKCtuWzBdKSAqIDEwMDAsIGkgKyBuWzBdLmxlbmd0aCkgOiAtMTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0RGF5T2ZNb250aChkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldERhdGUoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEhvdXIyNChkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldEhvdXJzKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRIb3VyMTIoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoZC5nZXRIb3VycygpICUgMTIgfHwgMTIsIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXREYXlPZlllYXIoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoMSArIGRheS5jb3VudCh5ZWFyKGQpLCBkKSwgcCwgMyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdE1pbGxpc2Vjb25kcyhkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldE1pbGxpc2Vjb25kcygpLCBwLCAzKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0TWljcm9zZWNvbmRzKGQsIHApIHtcbiAgcmV0dXJuIGZvcm1hdE1pbGxpc2Vjb25kcyhkLCBwKSArIFwiMDAwXCI7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdE1vbnRoTnVtYmVyKGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKGQuZ2V0TW9udGgoKSArIDEsIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRNaW51dGVzKGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKGQuZ2V0TWludXRlcygpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0U2Vjb25kcyhkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldFNlY29uZHMoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFdlZWtkYXlOdW1iZXJNb25kYXkoZCkge1xuICB2YXIgZGF5JCQxID0gZC5nZXREYXkoKTtcbiAgcmV0dXJuIGRheSQkMSA9PT0gMCA/IDcgOiBkYXkkJDE7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFdlZWtOdW1iZXJTdW5kYXkoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoc3VuZGF5LmNvdW50KHllYXIoZCksIGQpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0V2Vla051bWJlcklTTyhkLCBwKSB7XG4gIHZhciBkYXkkJDEgPSBkLmdldERheSgpO1xuICBkID0gKGRheSQkMSA+PSA0IHx8IGRheSQkMSA9PT0gMCkgPyB0aHVyc2RheShkKSA6IHRodXJzZGF5LmNlaWwoZCk7XG4gIHJldHVybiBwYWQkMSh0aHVyc2RheS5jb3VudCh5ZWFyKGQpLCBkKSArICh5ZWFyKGQpLmdldERheSgpID09PSA0KSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFdlZWtkYXlOdW1iZXJTdW5kYXkoZCkge1xuICByZXR1cm4gZC5nZXREYXkoKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0V2Vla051bWJlck1vbmRheShkLCBwKSB7XG4gIHJldHVybiBwYWQkMShtb25kYXkuY291bnQoeWVhcihkKSwgZCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRZZWFyKGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKGQuZ2V0RnVsbFllYXIoKSAlIDEwMCwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdEZ1bGxZZWFyKGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKGQuZ2V0RnVsbFllYXIoKSAlIDEwMDAwLCBwLCA0KTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0Wm9uZShkKSB7XG4gIHZhciB6ID0gZC5nZXRUaW1lem9uZU9mZnNldCgpO1xuICByZXR1cm4gKHogPiAwID8gXCItXCIgOiAoeiAqPSAtMSwgXCIrXCIpKVxuICAgICAgKyBwYWQkMSh6IC8gNjAgfCAwLCBcIjBcIiwgMilcbiAgICAgICsgcGFkJDEoeiAlIDYwLCBcIjBcIiwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ0RheU9mTW9udGgoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoZC5nZXRVVENEYXRlKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENIb3VyMjQoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoZC5nZXRVVENIb3VycygpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDSG91cjEyKGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKGQuZ2V0VVRDSG91cnMoKSAlIDEyIHx8IDEyLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDRGF5T2ZZZWFyKGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKDEgKyB1dGNEYXkuY291bnQodXRjWWVhcihkKSwgZCksIHAsIDMpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENNaWxsaXNlY29uZHMoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoZC5nZXRVVENNaWxsaXNlY29uZHMoKSwgcCwgMyk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ01pY3Jvc2Vjb25kcyhkLCBwKSB7XG4gIHJldHVybiBmb3JtYXRVVENNaWxsaXNlY29uZHMoZCwgcCkgKyBcIjAwMFwiO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENNb250aE51bWJlcihkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldFVUQ01vbnRoKCkgKyAxLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDTWludXRlcyhkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldFVUQ01pbnV0ZXMoKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1NlY29uZHMoZCwgcCkge1xuICByZXR1cm4gcGFkJDEoZC5nZXRVVENTZWNvbmRzKCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENXZWVrZGF5TnVtYmVyTW9uZGF5KGQpIHtcbiAgdmFyIGRvdyA9IGQuZ2V0VVRDRGF5KCk7XG4gIHJldHVybiBkb3cgPT09IDAgPyA3IDogZG93O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENXZWVrTnVtYmVyU3VuZGF5KGQsIHApIHtcbiAgcmV0dXJuIHBhZCQxKHV0Y1N1bmRheS5jb3VudCh1dGNZZWFyKGQpLCBkKSwgcCwgMik7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtOdW1iZXJJU08oZCwgcCkge1xuICB2YXIgZGF5JCQxID0gZC5nZXRVVENEYXkoKTtcbiAgZCA9IChkYXkkJDEgPj0gNCB8fCBkYXkkJDEgPT09IDApID8gdXRjVGh1cnNkYXkoZCkgOiB1dGNUaHVyc2RheS5jZWlsKGQpO1xuICByZXR1cm4gcGFkJDEodXRjVGh1cnNkYXkuY291bnQodXRjWWVhcihkKSwgZCkgKyAodXRjWWVhcihkKS5nZXRVVENEYXkoKSA9PT0gNCksIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENXZWVrZGF5TnVtYmVyU3VuZGF5KGQpIHtcbiAgcmV0dXJuIGQuZ2V0VVRDRGF5KCk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1dlZWtOdW1iZXJNb25kYXkoZCwgcCkge1xuICByZXR1cm4gcGFkJDEodXRjTW9uZGF5LmNvdW50KHV0Y1llYXIoZCksIGQpLCBwLCAyKTtcbn1cblxuZnVuY3Rpb24gZm9ybWF0VVRDWWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldFVUQ0Z1bGxZZWFyKCkgJSAxMDAsIHAsIDIpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRVVENGdWxsWWVhcihkLCBwKSB7XG4gIHJldHVybiBwYWQkMShkLmdldFVUQ0Z1bGxZZWFyKCkgJSAxMDAwMCwgcCwgNCk7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVUQ1pvbmUoKSB7XG4gIHJldHVybiBcIiswMDAwXCI7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdExpdGVyYWxQZXJjZW50KCkge1xuICByZXR1cm4gXCIlXCI7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVuaXhUaW1lc3RhbXAoZCkge1xuICByZXR1cm4gK2Q7XG59XG5cbmZ1bmN0aW9uIGZvcm1hdFVuaXhUaW1lc3RhbXBTZWNvbmRzKGQpIHtcbiAgcmV0dXJuIE1hdGguZmxvb3IoK2QgLyAxMDAwKTtcbn1cblxudmFyIGxvY2FsZSQxO1xudmFyIHRpbWVGb3JtYXQ7XG52YXIgdGltZVBhcnNlO1xudmFyIHV0Y0Zvcm1hdDtcbnZhciB1dGNQYXJzZTtcblxuZGVmYXVsdExvY2FsZSh7XG4gIGRhdGVUaW1lOiBcIiV4LCAlWFwiLFxuICBkYXRlOiBcIiUtbS8lLWQvJVlcIixcbiAgdGltZTogXCIlLUk6JU06JVMgJXBcIixcbiAgcGVyaW9kczogW1wiQU1cIiwgXCJQTVwiXSxcbiAgZGF5czogW1wiU3VuZGF5XCIsIFwiTW9uZGF5XCIsIFwiVHVlc2RheVwiLCBcIldlZG5lc2RheVwiLCBcIlRodXJzZGF5XCIsIFwiRnJpZGF5XCIsIFwiU2F0dXJkYXlcIl0sXG4gIHNob3J0RGF5czogW1wiU3VuXCIsIFwiTW9uXCIsIFwiVHVlXCIsIFwiV2VkXCIsIFwiVGh1XCIsIFwiRnJpXCIsIFwiU2F0XCJdLFxuICBtb250aHM6IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsIFwiSnVseVwiLCBcIkF1Z3VzdFwiLCBcIlNlcHRlbWJlclwiLCBcIk9jdG9iZXJcIiwgXCJOb3ZlbWJlclwiLCBcIkRlY2VtYmVyXCJdLFxuICBzaG9ydE1vbnRoczogW1wiSmFuXCIsIFwiRmViXCIsIFwiTWFyXCIsIFwiQXByXCIsIFwiTWF5XCIsIFwiSnVuXCIsIFwiSnVsXCIsIFwiQXVnXCIsIFwiU2VwXCIsIFwiT2N0XCIsIFwiTm92XCIsIFwiRGVjXCJdXG59KTtcblxuZnVuY3Rpb24gZGVmYXVsdExvY2FsZShkZWZpbml0aW9uKSB7XG4gIGxvY2FsZSQxID0gZm9ybWF0TG9jYWxlKGRlZmluaXRpb24pO1xuICB0aW1lRm9ybWF0ID0gbG9jYWxlJDEuZm9ybWF0O1xuICB0aW1lUGFyc2UgPSBsb2NhbGUkMS5wYXJzZTtcbiAgdXRjRm9ybWF0ID0gbG9jYWxlJDEudXRjRm9ybWF0O1xuICB1dGNQYXJzZSA9IGxvY2FsZSQxLnV0Y1BhcnNlO1xuICByZXR1cm4gbG9jYWxlJDE7XG59XG5cbnZhciBpc29TcGVjaWZpZXIgPSBcIiVZLSVtLSVkVCVIOiVNOiVTLiVMWlwiO1xuXG5mdW5jdGlvbiBmb3JtYXRJc29OYXRpdmUoZGF0ZSkge1xuICByZXR1cm4gZGF0ZS50b0lTT1N0cmluZygpO1xufVxuXG52YXIgZm9ybWF0SXNvID0gRGF0ZS5wcm90b3R5cGUudG9JU09TdHJpbmdcbiAgICA/IGZvcm1hdElzb05hdGl2ZVxuICAgIDogdXRjRm9ybWF0KGlzb1NwZWNpZmllcik7XG5cbmZ1bmN0aW9uIHBhcnNlSXNvTmF0aXZlKHN0cmluZykge1xuICB2YXIgZGF0ZSA9IG5ldyBEYXRlKHN0cmluZyk7XG4gIHJldHVybiBpc05hTihkYXRlKSA/IG51bGwgOiBkYXRlO1xufVxuXG52YXIgcGFyc2VJc28gPSArbmV3IERhdGUoXCIyMDAwLTAxLTAxVDAwOjAwOjAwLjAwMFpcIilcbiAgICA/IHBhcnNlSXNvTmF0aXZlXG4gICAgOiB1dGNQYXJzZShpc29TcGVjaWZpZXIpO1xuXG52YXIgcmVhZCA9IGZ1bmN0aW9uKGRhdGEsIHNjaGVtYSwgZGF0ZVBhcnNlKSB7XG4gIHNjaGVtYSA9IHNjaGVtYSB8fCB7fTtcblxuICB2YXIgcmVhZGVyID0gZm9ybWF0cyQxKHNjaGVtYS50eXBlIHx8ICdqc29uJyk7XG4gIGlmICghcmVhZGVyKSBlcnJvciQxKCdVbmtub3duIGRhdGEgZm9ybWF0IHR5cGU6ICcgKyBzY2hlbWEudHlwZSk7XG5cbiAgZGF0YSA9IHJlYWRlcihkYXRhLCBzY2hlbWEpO1xuICBpZiAoc2NoZW1hLnBhcnNlKSBwYXJzZShkYXRhLCBzY2hlbWEucGFyc2UsIGRhdGVQYXJzZSk7XG5cbiAgaWYgKGRhdGEuaGFzT3duUHJvcGVydHkoJ2NvbHVtbnMnKSkgZGVsZXRlIGRhdGEuY29sdW1ucztcbiAgcmV0dXJuIGRhdGE7XG59O1xuXG5mdW5jdGlvbiBwYXJzZShkYXRhLCB0eXBlcywgZGF0ZVBhcnNlKSB7XG4gIGlmICghZGF0YS5sZW5ndGgpIHJldHVybjsgLy8gZWFybHkgZXhpdCBmb3IgZW1wdHkgZGF0YVxuXG4gIGRhdGVQYXJzZSA9IGRhdGVQYXJzZSB8fCB0aW1lUGFyc2U7XG5cbiAgdmFyIGZpZWxkcyA9IGRhdGEuY29sdW1ucyB8fCBPYmplY3Qua2V5cyhkYXRhWzBdKSxcbiAgICAgIHBhcnNlcnMsIGRhdHVtLCBmaWVsZCQkMSwgaSwgaiwgbiwgbTtcblxuICBpZiAodHlwZXMgPT09ICdhdXRvJykgdHlwZXMgPSBpbmZlclR5cGVzKGRhdGEsIGZpZWxkcyk7XG5cbiAgZmllbGRzID0gT2JqZWN0LmtleXModHlwZXMpO1xuICBwYXJzZXJzID0gZmllbGRzLm1hcChmdW5jdGlvbihmaWVsZCQkMSkge1xuICAgIHZhciB0eXBlID0gdHlwZXNbZmllbGQkJDFdLFxuICAgICAgICBwYXJ0cywgcGF0dGVybjtcblxuICAgIGlmICh0eXBlICYmICh0eXBlLmluZGV4T2YoJ2RhdGU6JykgPT09IDAgfHwgdHlwZS5pbmRleE9mKCd1dGM6JykgPT09IDApKSB7XG4gICAgICBwYXJ0cyA9IHR5cGUuc3BsaXQoLzooLispPy8sIDIpOyAgLy8gc3BsaXQgb24gZmlyc3QgOlxuICAgICAgcGF0dGVybiA9IHBhcnRzWzFdO1xuXG4gICAgICBpZiAoKHBhdHRlcm5bMF0gPT09ICdcXCcnICYmIHBhdHRlcm5bcGF0dGVybi5sZW5ndGgtMV0gPT09ICdcXCcnKSB8fFxuICAgICAgICAgIChwYXR0ZXJuWzBdID09PSAnXCInICAmJiBwYXR0ZXJuW3BhdHRlcm4ubGVuZ3RoLTFdID09PSAnXCInKSkge1xuICAgICAgICBwYXR0ZXJuID0gcGF0dGVybi5zbGljZSgxLCAtMSk7XG4gICAgICB9XG5cbiAgICAgIHJldHVybiBwYXJ0c1swXSA9PT0gJ3V0YycgPyB1dGNQYXJzZShwYXR0ZXJuKSA6IGRhdGVQYXJzZShwYXR0ZXJuKTtcbiAgICB9XG5cbiAgICBpZiAoIXR5cGVQYXJzZXJzW3R5cGVdKSB7XG4gICAgICB0aHJvdyBFcnJvcignSWxsZWdhbCBmb3JtYXQgcGF0dGVybjogJyArIGZpZWxkJCQxICsgJzonICsgdHlwZSk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHR5cGVQYXJzZXJzW3R5cGVdO1xuICB9KTtcblxuICBmb3IgKGk9MCwgbj1kYXRhLmxlbmd0aCwgbT1maWVsZHMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGRhdHVtID0gZGF0YVtpXTtcbiAgICBmb3IgKGo9MDsgajxtOyArK2opIHtcbiAgICAgIGZpZWxkJCQxID0gZmllbGRzW2pdO1xuICAgICAgZGF0dW1bZmllbGQkJDFdID0gcGFyc2Vyc1tqXShkYXR1bVtmaWVsZCQkMV0pO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBpbmdlc3QkMSh0YXJnZXQsIGRhdGEsIGZvcm1hdCkge1xuICByZXR1cm4gdGhpcy5wdWxzZSh0YXJnZXQsIHRoaXMuY2hhbmdlc2V0KCkuaW5zZXJ0KHJlYWQoZGF0YSwgZm9ybWF0KSkpO1xufVxuXG5mdW5jdGlvbiBsb2FkUGVuZGluZyhkZikge1xuICB2YXIgYWNjZXB0LCByZWplY3QsXG4gICAgICBwZW5kaW5nID0gbmV3IFByb21pc2UoZnVuY3Rpb24oYSwgcikge1xuICAgICAgICBhY2NlcHQgPSBhO1xuICAgICAgICByZWplY3QgPSByO1xuICAgICAgfSk7XG5cbiAgcGVuZGluZy5yZXF1ZXN0cyA9IDA7XG5cbiAgcGVuZGluZy5kb25lID0gZnVuY3Rpb24oKSB7XG4gICAgaWYgKC0tcGVuZGluZy5yZXF1ZXN0cyA9PT0gMCkge1xuICAgICAgZGYucnVuQWZ0ZXIoZnVuY3Rpb24oKSB7XG4gICAgICAgIGRmLl9wZW5kaW5nID0gbnVsbDtcbiAgICAgICAgdHJ5IHtcbiAgICAgICAgICBkZi5ydW4oKTtcbiAgICAgICAgICBhY2NlcHQoZGYpO1xuICAgICAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgICAgICByZWplY3QoZXJyKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiAoZGYuX3BlbmRpbmcgPSBwZW5kaW5nKTtcbn1cblxuZnVuY3Rpb24gcmVxdWVzdCh0YXJnZXQsIHVybCwgZm9ybWF0KSB7XG4gIHZhciBkZiA9IHRoaXMsXG4gICAgICBwZW5kaW5nID0gZGYuX3BlbmRpbmcgfHwgbG9hZFBlbmRpbmcoZGYpO1xuXG4gIHBlbmRpbmcucmVxdWVzdHMgKz0gMTtcblxuICBkZi5sb2FkZXIoKVxuICAgIC5sb2FkKHVybCwge2NvbnRleHQ6J2RhdGFmbG93J30pXG4gICAgLnRoZW4oXG4gICAgICBmdW5jdGlvbihkYXRhKSB7IGRmLmluZ2VzdCh0YXJnZXQsIGRhdGEsIGZvcm1hdCk7IH0sXG4gICAgICBmdW5jdGlvbihlcnJvcikgeyBkZi5lcnJvcignTG9hZGluZyBmYWlsZWQnLCB1cmwsIGVycm9yKTsgfSlcbiAgICAuY2F0Y2goXG4gICAgICBmdW5jdGlvbihlcnJvcikgeyBkZi5lcnJvcignRGF0YSBpbmdlc3Rpb24gZmFpbGVkJywgdXJsLCBlcnJvcik7IH0pXG4gICAgLnRoZW4ocGVuZGluZy5kb25lLCBwZW5kaW5nLmRvbmUpO1xufVxuXG52YXIgU0tJUCQxID0ge3NraXA6IHRydWV9O1xuXG4vKipcbiAqIFBlcmZvcm0gb3BlcmF0b3IgdXBkYXRlcyBpbiByZXNwb25zZSB0byBldmVudHMuIEFwcGxpZXMgYW5cbiAqIHVwZGF0ZSBmdW5jdGlvbiB0byBjb21wdXRlIGEgbmV3IG9wZXJhdG9yIHZhbHVlLiBJZiB0aGUgdXBkYXRlIGZ1bmN0aW9uXG4gKiByZXR1cm5zIGEge0BsaW5rIENoYW5nZVNldH0sIHRoZSBvcGVyYXRvciB3aWxsIGJlIHB1bHNlZCB3aXRoIHRob3NlIHR1cGxlXG4gKiBjaGFuZ2VzLiBPdGhlcndpc2UsIHRoZSBvcGVyYXRvciB2YWx1ZSB3aWxsIGJlIHVwZGF0ZWQgdG8gdGhlIHJldHVybiB2YWx1ZS5cbiAqIEBwYXJhbSB7RXZlbnRTdHJlYW18T3BlcmF0b3J9IHNvdXJjZSAtIFRoZSBldmVudCBzb3VyY2UgdG8gcmVhY3QgdG8uXG4gKiAgIFRoaXMgYXJndW1lbnQgY2FuIGJlIGVpdGhlciBhbiBFdmVudFN0cmVhbSBvciBhbiBPcGVyYXRvci5cbiAqIEBwYXJhbSB7T3BlcmF0b3J8ZnVuY3Rpb24ob2JqZWN0KTpPcGVyYXRvcn0gdGFyZ2V0IC0gVGhlIG9wZXJhdG9yIHRvIHVwZGF0ZS5cbiAqICAgVGhpcyBhcmd1bWVudCBjYW4gZWl0aGVyIGJlIGFuIE9wZXJhdG9yIGluc3RhbmNlIG9yIChpZiB0aGUgc291cmNlXG4gKiAgIGFyZ3VtZW50IGlzIGFuIEV2ZW50U3RyZWFtKSwgYSBmdW5jdGlvbiB0aGF0IGFjY2VwdHMgYW4gZXZlbnQgb2JqZWN0IGFzXG4gKiAgIGlucHV0IGFuZCByZXR1cm5zIGFuIE9wZXJhdG9yIHRvIHRhcmdldC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oUGFyYW1ldGVycyxFdmVudCk6ICp9IFt1cGRhdGVdIC0gT3B0aW9uYWwgdXBkYXRlIGZ1bmN0aW9uXG4gKiAgIHRvIGNvbXB1dGUgdGhlIG5ldyBvcGVyYXRvciB2YWx1ZSwgb3IgYSBsaXRlcmFsIHZhbHVlIHRvIHNldC4gVXBkYXRlXG4gKiAgIGZ1bmN0aW9ucyBleHBlY3QgdG8gcmVjZWl2ZSBhIHBhcmFtZXRlciBvYmplY3QgYW5kIGV2ZW50IGFzIGFyZ3VtZW50cy5cbiAqICAgVGhpcyBmdW5jdGlvbiBjYW4gZWl0aGVyIHJldHVybiBhIG5ldyBvcGVyYXRvciB2YWx1ZSBvciAoaWYgdGhlIHNvdXJjZVxuICogICBhcmd1bWVudCBpcyBhbiBFdmVudFN0cmVhbSkgYSB7QGxpbmsgQ2hhbmdlU2V0fSBpbnN0YW5jZSB0byBwdWxzZVxuICogICB0aGUgdGFyZ2V0IG9wZXJhdG9yIHdpdGggdHVwbGUgY2hhbmdlcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbcGFyYW1zXSAtIFRoZSB1cGRhdGUgZnVuY3Rpb24gcGFyYW1ldGVycy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBBZGRpdGlvbmFsIG9wdGlvbnMgaGFzaC4gSWYgbm90IG92ZXJyaWRkZW4sXG4gKiAgIHVwZGF0ZWQgb3BlcmF0b3JzIHdpbGwgYmUgc2tpcHBlZCBieSBkZWZhdWx0LlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5za2lwXSAtIElmIHRydWUsIHRoZSBvcGVyYXRvciB3aWxsXG4gKiAgYmUgc2tpcHBlZDogaXQgd2lsbCBub3QgYmUgZXZhbHVhdGVkLCBidXQgaXRzIGRlcGVuZGVudHMgd2lsbCBiZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuZm9yY2VdIC0gSWYgdHJ1ZSwgdGhlIG9wZXJhdG9yIHdpbGxcbiAqICAgYmUgcmUtZXZhbHVhdGVkIGV2ZW4gaWYgaXRzIHZhbHVlIGhhcyBub3QgY2hhbmdlZC5cbiAqIEByZXR1cm4ge0RhdGFmbG93fVxuICovXG52YXIgb24gPSBmdW5jdGlvbihzb3VyY2UsIHRhcmdldCwgdXBkYXRlLCBwYXJhbXMsIG9wdGlvbnMpIHtcbiAgdmFyIGZuID0gc291cmNlIGluc3RhbmNlb2YgT3BlcmF0b3IgPyBvbk9wZXJhdG9yIDogb25TdHJlYW07XG4gIGZuKHRoaXMsIHNvdXJjZSwgdGFyZ2V0LCB1cGRhdGUsIHBhcmFtcywgb3B0aW9ucyk7XG4gIHJldHVybiB0aGlzO1xufTtcblxuZnVuY3Rpb24gb25TdHJlYW0oZGYsIHN0cmVhbSwgdGFyZ2V0LCB1cGRhdGUsIHBhcmFtcywgb3B0aW9ucykge1xuICB2YXIgb3B0ID0gZXh0ZW5kKHt9LCBvcHRpb25zLCBTS0lQJDEpLCBmdW5jLCBvcDtcblxuICBpZiAoIWlzRnVuY3Rpb24odGFyZ2V0KSkgdGFyZ2V0ID0gY29uc3RhbnQodGFyZ2V0KTtcblxuICBpZiAodXBkYXRlID09PSB1bmRlZmluZWQpIHtcbiAgICBmdW5jID0gZnVuY3Rpb24oZSkge1xuICAgICAgZGYudG91Y2godGFyZ2V0KGUpKTtcbiAgICB9O1xuICB9IGVsc2UgaWYgKGlzRnVuY3Rpb24odXBkYXRlKSkge1xuICAgIG9wID0gbmV3IE9wZXJhdG9yKG51bGwsIHVwZGF0ZSwgcGFyYW1zLCBmYWxzZSk7XG4gICAgZnVuYyA9IGZ1bmN0aW9uKGUpIHtcbiAgICAgIHZhciB2LCB0ID0gdGFyZ2V0KGUpO1xuICAgICAgb3AuZXZhbHVhdGUoZSk7XG4gICAgICBpc0NoYW5nZVNldCh2ID0gb3AudmFsdWUpID8gZGYucHVsc2UodCwgdiwgb3B0aW9ucykgOiBkZi51cGRhdGUodCwgdiwgb3B0KTtcbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGZ1bmMgPSBmdW5jdGlvbihlKSB7XG4gICAgICBkZi51cGRhdGUodGFyZ2V0KGUpLCB1cGRhdGUsIG9wdCk7XG4gICAgfTtcbiAgfVxuXG4gIHN0cmVhbS5hcHBseShmdW5jKTtcbn1cblxuZnVuY3Rpb24gb25PcGVyYXRvcihkZiwgc291cmNlLCB0YXJnZXQsIHVwZGF0ZSwgcGFyYW1zLCBvcHRpb25zKSB7XG4gIHZhciBmdW5jLCBvcDtcblxuICBpZiAodXBkYXRlID09PSB1bmRlZmluZWQpIHtcbiAgICBvcCA9IHRhcmdldDtcbiAgfSBlbHNlIHtcbiAgICBmdW5jID0gaXNGdW5jdGlvbih1cGRhdGUpID8gdXBkYXRlIDogY29uc3RhbnQodXBkYXRlKTtcbiAgICB1cGRhdGUgPSAhdGFyZ2V0ID8gZnVuYyA6IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gICAgICB2YXIgdmFsdWUgPSBmdW5jKF8sIHB1bHNlKTtcbiAgICAgIHJldHVybiB0YXJnZXQuc2tpcCgpXG4gICAgICAgID8gdmFsdWVcbiAgICAgICAgOiAodGFyZ2V0LnNraXAodHJ1ZSkudmFsdWUgPSB2YWx1ZSk7XG4gICAgfTtcblxuICAgIG9wID0gbmV3IE9wZXJhdG9yKG51bGwsIHVwZGF0ZSwgcGFyYW1zLCBmYWxzZSk7XG4gICAgb3AubW9kaWZpZWQob3B0aW9ucyAmJiBvcHRpb25zLmZvcmNlKTtcbiAgICBvcC5yYW5rID0gMDtcblxuICAgIGlmICh0YXJnZXQpIHtcbiAgICAgIG9wLnNraXAodHJ1ZSk7IC8vIHNraXAgZmlyc3QgaW52b2NhdGlvblxuICAgICAgb3AudmFsdWUgPSB0YXJnZXQudmFsdWU7XG4gICAgICBvcC50YXJnZXRzKCkuYWRkKHRhcmdldCk7XG4gICAgfVxuICB9XG5cbiAgc291cmNlLnRhcmdldHMoKS5hZGQob3ApO1xufVxuXG4vKipcbiAqIEFzc2lnbnMgYSByYW5rIHRvIGFuIG9wZXJhdG9yLiBSYW5rcyBhcmUgYXNzaWduZWQgaW4gaW5jcmVhc2luZyBvcmRlclxuICogYnkgaW5jcmVtZW50aW5nIGFuIGludGVybmFsIHJhbmsgY291bnRlci5cbiAqIEBwYXJhbSB7T3BlcmF0b3J9IG9wIC0gVGhlIG9wZXJhdG9yIHRvIGFzc2lnbiBhIHJhbmsuXG4gKi9cbmZ1bmN0aW9uIHJhbmsob3ApIHtcbiAgb3AucmFuayA9ICsrdGhpcy5fcmFuaztcbn1cblxuLyoqXG4gKiBSZS1yYW5rcyBhbiBvcGVyYXRvciBhbmQgYWxsIGRvd25zdHJlYW0gdGFyZ2V0IGRlcGVuZGVuY2llcy4gVGhpc1xuICogaXMgbmVjZXNzYXJ5IHdoZW4gdXBzdHJlYW0gZGVwZW5jaWVzIG9mIGhpZ2hlciByYW5rIGFyZSBhZGRlZCB0b1xuICogYSB0YXJnZXQgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge09wZXJhdG9yfSBvcCAtIFRoZSBvcGVyYXRvciB0byByZS1yYW5rLlxuICovXG5mdW5jdGlvbiByZXJhbmsob3ApIHtcbiAgdmFyIHF1ZXVlID0gW29wXSxcbiAgICAgIGN1ciwgbGlzdCwgaTtcblxuICB3aGlsZSAocXVldWUubGVuZ3RoKSB7XG4gICAgdGhpcy5yYW5rKGN1ciA9IHF1ZXVlLnBvcCgpKTtcbiAgICBpZiAobGlzdCA9IGN1ci5fdGFyZ2V0cykge1xuICAgICAgZm9yIChpPWxpc3QubGVuZ3RoOyAtLWkgPj0gMDspIHtcbiAgICAgICAgcXVldWUucHVzaChjdXIgPSBsaXN0W2ldKTtcbiAgICAgICAgaWYgKGN1ciA9PT0gb3ApIGVycm9yJDEoJ0N5Y2xlIGRldGVjdGVkIGluIGRhdGFmbG93IGdyYXBoLicpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG4vKipcbiAqIFNlbnRpbmVsIHZhbHVlIGluZGljYXRpbmcgcHVsc2UgcHJvcGFnYXRpb24gc2hvdWxkIHN0b3AuXG4gKi9cbnZhciBTdG9wUHJvcGFnYXRpb24gPSB7fTtcblxuLy8gUHVsc2UgdmlzaXQgdHlwZSBmbGFnc1xudmFyIEFERCAgICAgICA9ICgxIDw8IDApO1xudmFyIFJFTSAgICAgICA9ICgxIDw8IDEpO1xudmFyIE1PRCAgICAgICA9ICgxIDw8IDIpO1xudmFyIEFERF9SRU0gICA9IEFERCB8IFJFTTtcbnZhciBBRERfTU9EICAgPSBBREQgfCBNT0Q7XG52YXIgQUxMICAgICAgID0gQUREIHwgUkVNIHwgTU9EO1xudmFyIFJFRkxPVyAgICA9ICgxIDw8IDMpO1xudmFyIFNPVVJDRSAgICA9ICgxIDw8IDQpO1xudmFyIE5PX1NPVVJDRSA9ICgxIDw8IDUpO1xudmFyIE5PX0ZJRUxEUyA9ICgxIDw8IDYpO1xuXG4vKipcbiAqIEEgUHVsc2UgZW5hYmxlcyBpbnRlci1vcGVyYXRvciBjb21tdW5pY2F0aW9uIGR1cmluZyBhIHJ1biBvZiB0aGVcbiAqIGRhdGFmbG93IGdyYXBoLiBJbiBhZGRpdGlvbiB0byB0aGUgY3VycmVudCB0aW1lc3RhbXAsIGEgcHVsc2UgbWF5IGFsc29cbiAqIGNvbnRhaW4gYSBjaGFuZ2Utc2V0IG9mIGFkZGVkLCByZW1vdmVkIG9yIG1vZGlmaWVkIGRhdGEgdHVwbGVzLCBhcyB3ZWxsIGFzXG4gKiBhIHBvaW50ZXIgdG8gYSBmdWxsIGJhY2tpbmcgZGF0YSBzb3VyY2UuIFR1cGxlIGNoYW5nZSBzZXRzIG1heSBub3RcbiAqIGJlIGZ1bGx5IG1hdGVyaWFsaXplZDsgZm9yIGV4YW1wbGUsIHRvIHByZXZlbnQgbmVlZGxlc3MgYXJyYXkgY3JlYXRpb25cbiAqIGEgY2hhbmdlIHNldCBtYXkgaW5jbHVkZSBsYXJnZXIgYXJyYXlzIGFuZCBjb3JyZXNwb25kaW5nIGZpbHRlciBmdW5jdGlvbnMuXG4gKiBUaGUgcHVsc2UgcHJvdmlkZXMgYSB7QGxpbmsgdmlzaXR9IG1ldGhvZCB0byBlbmFibGUgcHJvcGVyIGFuZCBlZmZpY2llbnRcbiAqIGl0ZXJhdGlvbiBvdmVyIHJlcXVlc3RlZCBkYXRhIHR1cGxlcy5cbiAqXG4gKiBJbiBhZGRpdGlvbiwgZWFjaCBwdWxzZSBjYW4gdHJhY2sgbW9kaWZpY2F0aW9uIGZsYWdzIGZvciBkYXRhIHR1cGxlIGZpZWxkcy5cbiAqIFJlc3BvbnNpYmxlIHRyYW5zZm9ybSBvcGVyYXRvcnMgc2hvdWxkIGNhbGwgdGhlIHtAbGluayBtb2RpZmllc30gbWV0aG9kIHRvXG4gKiBpbmRpY2F0ZSBjaGFuZ2VzIHRvIGRhdGEgZmllbGRzLiBUaGUge0BsaW5rIG1vZGlmaWVkfSBtZXRob2QgZW5hYmxlc1xuICogcXVlcnlpbmcgb2YgdGhpcyBtb2RpZmljYXRpb24gc3RhdGUuXG4gKlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge0RhdGFmbG93fSBkYXRhZmxvdyAtIFRoZSBiYWNraW5nIGRhdGFmbG93IGluc3RhbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IHN0YW1wIC0gVGhlIGN1cnJlbnQgcHJvcGFnYXRpb24gdGltZXN0YW1wLlxuICogQHBhcmFtIHtzdHJpbmd9IFtlbmNvZGVdIC0gQW4gb3B0aW9uYWwgZW5jb2Rpbmcgc2V0IG5hbWUsIHdoaWNoIGlzIHRoZW5cbiAqICAgYWNjZXNzaWJsZSBhcyBQdWxzZS5lbmNvZGUuIE9wZXJhdG9ycyBjYW4gcmVzcG9uZCB0byAob3IgaWdub3JlKSB0aGlzXG4gKiAgIHNldHRpbmcgYXMgYXBwcm9wcmlhdGUuIFRoaXMgcGFyYW1ldGVyIGNhbiBiZSB1c2VkIGluIGNvbmp1bmN0aW9uIHdpdGhcbiAqICAgdGhlIEVuY29kZSB0cmFuc2Zvcm0gaW4gdGhlIHZlZ2EtZW5jb2RlIG1vZHVsZS5cbiAqL1xuZnVuY3Rpb24gUHVsc2UoZGF0YWZsb3csIHN0YW1wLCBlbmNvZGUpIHtcbiAgdGhpcy5kYXRhZmxvdyA9IGRhdGFmbG93O1xuICB0aGlzLnN0YW1wID0gc3RhbXAgPT0gbnVsbCA/IC0xIDogc3RhbXA7XG4gIHRoaXMuYWRkID0gW107XG4gIHRoaXMucmVtID0gW107XG4gIHRoaXMubW9kID0gW107XG4gIHRoaXMuZmllbGRzID0gbnVsbDtcbiAgdGhpcy5lbmNvZGUgPSBlbmNvZGUgfHwgbnVsbDtcbn1cblxudmFyIHByb3RvdHlwZSQ0ID0gUHVsc2UucHJvdG90eXBlO1xuXG4vKipcbiAqIFNlbnRpbmVsIHZhbHVlIGluZGljYXRpbmcgcHVsc2UgcHJvcGFnYXRpb24gc2hvdWxkIHN0b3AuXG4gKi9cbnByb3RvdHlwZSQ0LlN0b3BQcm9wYWdhdGlvbiA9IFN0b3BQcm9wYWdhdGlvbjtcblxuLyoqXG4gKiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyBBREQgKGFkZGVkKSB0dXBsZXMuXG4gKi9cbnByb3RvdHlwZSQ0LkFERCA9IEFERDtcblxuLyoqXG4gKiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyBSRU0gKHJlbW92ZWQpIHR1cGxlcy5cbiAqL1xucHJvdG90eXBlJDQuUkVNID0gUkVNO1xuXG4vKipcbiAqIEJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIE1PRCAobW9kaWZpZWQpIHR1cGxlcy5cbiAqL1xucHJvdG90eXBlJDQuTU9EID0gTU9EO1xuXG4vKipcbiAqIEJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIEFERCAoYWRkZWQpIGFuZCBSRU0gKHJlbW92ZWQpIHR1cGxlcy5cbiAqL1xucHJvdG90eXBlJDQuQUREX1JFTSA9IEFERF9SRU07XG5cbi8qKlxuICogQm9vbGVhbiBmbGFnIGluZGljYXRpbmcgQUREIChhZGRlZCkgYW5kIE1PRCAobW9kaWZpZWQpIHR1cGxlcy5cbiAqL1xucHJvdG90eXBlJDQuQUREX01PRCA9IEFERF9NT0Q7XG5cbi8qKlxuICogQm9vbGVhbiBmbGFnIGluZGljYXRpbmcgQURELCBSRU0gYW5kIE1PRCB0dXBsZXMuXG4gKi9cbnByb3RvdHlwZSQ0LkFMTCA9IEFMTDtcblxuLyoqXG4gKiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyBhbGwgdHVwbGVzIGluIGEgZGF0YSBzb3VyY2VcbiAqIGV4Y2VwdCBmb3IgdGhlIEFERCwgUkVNIGFuZCBNT0QgdHVwbGVzLlxuICovXG5wcm90b3R5cGUkNC5SRUZMT1cgPSBSRUZMT1c7XG5cbi8qKlxuICogQm9vbGVhbiBmbGFnIGluZGljYXRpbmcgYSAncGFzcy10aHJvdWdoJyB0byBhXG4gKiBiYWNraW5nIGRhdGEgc291cmNlLCBpZ25vcmluZyBBREQsIFJFTSBhbmQgTU9EIHR1cGxlcy5cbiAqL1xucHJvdG90eXBlJDQuU09VUkNFID0gU09VUkNFO1xuXG4vKipcbiAqIEJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIHRoYXQgc291cmNlIGRhdGEgc2hvdWxkIGJlXG4gKiBzdXBwcmVzc2VkIHdoZW4gY3JlYXRpbmcgYSBmb3JrZWQgcHVsc2UuXG4gKi9cbnByb3RvdHlwZSQ0Lk5PX1NPVVJDRSA9IE5PX1NPVVJDRTtcblxuLyoqXG4gKiBCb29sZWFuIGZsYWcgaW5kaWNhdGluZyB0aGF0IGZpZWxkIG1vZGlmaWNhdGlvbnMgc2hvdWxkIGJlXG4gKiBzdXBwcmVzc2VkIHdoZW4gY3JlYXRpbmcgYSBmb3JrZWQgcHVsc2UuXG4gKi9cbnByb3RvdHlwZSQ0Lk5PX0ZJRUxEUyA9IE5PX0ZJRUxEUztcblxuLyoqXG4gKiBDcmVhdGVzIGEgbmV3IHB1bHNlIGJhc2VkIG9uIHRoZSB2YWx1ZXMgb2YgdGhpcyBwdWxzZS5cbiAqIFRoZSBkYXRhZmxvdywgdGltZSBzdGFtcCBhbmQgZmllbGQgbW9kaWZpY2F0aW9uIHZhbHVlcyBhcmUgY29waWVkIG92ZXIuXG4gKiBCeSBkZWZhdWx0LCBuZXcgZW1wdHkgQURELCBSRU0gYW5kIE1PRCBhcnJheXMgYXJlIGNyZWF0ZWQuXG4gKiBAcGFyYW0ge251bWJlcn0gZmxhZ3MgLSBJbnRlZ2VyIG9mIGJvb2xlYW4gZmxhZ3MgaW5kaWNhdGluZyB3aGljaCAoaWYgYW55KVxuICogICB0dXBsZSBhcnJheXMgc2hvdWxkIGJlIGNvcGllZCB0byB0aGUgbmV3IHB1bHNlLiBUaGUgc3VwcG9ydGVkIGZsYWcgdmFsdWVzXG4gKiAgIGFyZSBBREQsIFJFTSBhbmQgTU9ELiBBcnJheSByZWZlcmVuY2VzIGFyZSBjb3BpZWQgZGlyZWN0bHk6IG5ldyBhcnJheVxuICogICBpbnN0YW5jZXMgYXJlIG5vdCBjcmVhdGVkLlxuICogQHJldHVybiB7UHVsc2V9IC0gVGhlIGZvcmtlZCBwdWxzZSBpbnN0YW5jZS5cbiAqIEBzZWUgaW5pdFxuICovXG5wcm90b3R5cGUkNC5mb3JrID0gZnVuY3Rpb24oZmxhZ3MpIHtcbiAgcmV0dXJuIG5ldyBQdWxzZSh0aGlzLmRhdGFmbG93KS5pbml0KHRoaXMsIGZsYWdzKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyBhIHB1bHNlIHRoYXQgYWRkcyBhbGwgdHVwbGVzIGZyb20gYSBiYWNraW5nIHNvdXJjZS4gVGhpcyBpc1xuICogdXNlZnVsIGZvciBjYXNlcyB3aGVyZSBvcGVyYXRvcnMgYXJlIGFkZGVkIHRvIGEgZGF0YWZsb3cgYWZ0ZXIgYW5cbiAqIHVwc3RyZWFtIGRhdGEgcGlwZWxpbmUgaGFzIGFscmVhZHkgYmVlbiBwcm9jZXNzZWQsIGVuc3VyaW5nIHRoYXRcbiAqIG5ldyBvcGVyYXRvcnMgY2FuIG9ic2VydmUgYWxsIHR1cGxlcyB3aXRoaW4gYSBzdHJlYW0uXG4gKiBAcmV0dXJuIHtQdWxzZX0gLSBBIHB1bHNlIGluc3RhbmNlIHdpdGggYWxsIHNvdXJjZSB0dXBsZXMgaW5jbHVkZWRcbiAqICAgaW4gdGhlIGFkZCBhcnJheS4gSWYgdGhlIGN1cnJlbnQgcHVsc2UgYWxyZWFkeSBoYXMgYWxsIHNvdXJjZVxuICogICB0dXBsZXMgaW4gaXRzIGFkZCBhcnJheSwgaXQgaXMgcmV0dXJuZWQgZGlyZWN0bHkuIElmIHRoZSBjdXJyZW50XG4gKiAgIHB1bHNlIGRvZXMgbm90IGhhdmUgYSBiYWNraW5nIHNvdXJjZSwgaXQgaXMgcmV0dXJuZWQgZGlyZWN0bHkuXG4gKi9cbnByb3RvdHlwZSQ0LmFkZEFsbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcCA9IHRoaXM7XG4gIGlmICghdGhpcy5zb3VyY2UgfHwgdGhpcy5zb3VyY2UubGVuZ3RoID09PSB0aGlzLmFkZC5sZW5ndGgpIHtcbiAgICByZXR1cm4gcDtcbiAgfSBlbHNlIHtcbiAgICBwID0gbmV3IFB1bHNlKHRoaXMuZGF0YWZsb3cpLmluaXQodGhpcyk7XG4gICAgcC5hZGQgPSBwLnNvdXJjZTtcbiAgICByZXR1cm4gcDtcbiAgfVxufTtcblxuLyoqXG4gKiBJbml0aWFsaXplIHRoaXMgcHVsc2UgYmFzZWQgb24gdGhlIHZhbHVlcyBvZiBhbm90aGVyIHB1bHNlLiBUaGlzIG1ldGhvZFxuICogaXMgdXNlZCBpbnRlcm5hbGx5IGJ5IHtAbGluayBmb3JrfSB0byBpbml0aWFsaXplIGEgbmV3IGZvcmtlZCB0dXBsZS5cbiAqIFRoZSBkYXRhZmxvdywgdGltZSBzdGFtcCBhbmQgZmllbGQgbW9kaWZpY2F0aW9uIHZhbHVlcyBhcmUgY29waWVkIG92ZXIuXG4gKiBCeSBkZWZhdWx0LCBuZXcgZW1wdHkgQURELCBSRU0gYW5kIE1PRCBhcnJheXMgYXJlIGNyZWF0ZWQuXG4gKiBAcGFyYW0ge1B1bHNlfSBzcmMgLSBUaGUgc291cmNlIHB1bHNlIHRvIGNvcHkgZnJvbS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmbGFncyAtIEludGVnZXIgb2YgYm9vbGVhbiBmbGFncyBpbmRpY2F0aW5nIHdoaWNoIChpZiBhbnkpXG4gKiAgIHR1cGxlIGFycmF5cyBzaG91bGQgYmUgY29waWVkIHRvIHRoZSBuZXcgcHVsc2UuIFRoZSBzdXBwb3J0ZWQgZmxhZyB2YWx1ZXNcbiAqICAgYXJlIEFERCwgUkVNIGFuZCBNT0QuIEFycmF5IHJlZmVyZW5jZXMgYXJlIGNvcGllZCBkaXJlY3RseTogbmV3IGFycmF5XG4gKiAgIGluc3RhbmNlcyBhcmUgbm90IGNyZWF0ZWQuIEJ5IGRlZmF1bHQsIHNvdXJjZSBkYXRhIGFycmF5cyBhcmUgY29waWVkXG4gKiAgIHRvIHRoZSBuZXcgcHVsc2UuIFVzZSB0aGUgTk9fU09VUkNFIGZsYWcgdG8gZW5mb3JjZSBhIG51bGwgc291cmNlLlxuICogQHJldHVybiB7UHVsc2V9IC0gUmV0dXJucyB0aGlzIFB1bHNlIGluc3RhbmNlLlxuICovXG5wcm90b3R5cGUkNC5pbml0ID0gZnVuY3Rpb24oc3JjLCBmbGFncykge1xuICB2YXIgcCA9IHRoaXM7XG4gIHAuc3RhbXAgPSBzcmMuc3RhbXA7XG4gIHAuZW5jb2RlID0gc3JjLmVuY29kZTtcblxuICBpZiAoc3JjLmZpZWxkcyAmJiAhKGZsYWdzICYgTk9fRklFTERTKSkge1xuICAgIHAuZmllbGRzID0gc3JjLmZpZWxkcztcbiAgfVxuXG4gIGlmIChmbGFncyAmIEFERCkge1xuICAgIHAuYWRkRiA9IHNyYy5hZGRGO1xuICAgIHAuYWRkID0gc3JjLmFkZDtcbiAgfSBlbHNlIHtcbiAgICBwLmFkZEYgPSBudWxsO1xuICAgIHAuYWRkID0gW107XG4gIH1cblxuICBpZiAoZmxhZ3MgJiBSRU0pIHtcbiAgICBwLnJlbUYgPSBzcmMucmVtRjtcbiAgICBwLnJlbSA9IHNyYy5yZW07XG4gIH0gZWxzZSB7XG4gICAgcC5yZW1GID0gbnVsbDtcbiAgICBwLnJlbSA9IFtdO1xuICB9XG5cbiAgaWYgKGZsYWdzICYgTU9EKSB7XG4gICAgcC5tb2RGID0gc3JjLm1vZEY7XG4gICAgcC5tb2QgPSBzcmMubW9kO1xuICB9IGVsc2Uge1xuICAgIHAubW9kRiA9IG51bGw7XG4gICAgcC5tb2QgPSBbXTtcbiAgfVxuXG4gIGlmIChmbGFncyAmIE5PX1NPVVJDRSkge1xuICAgIHAuc3JjRiA9IG51bGw7XG4gICAgcC5zb3VyY2UgPSBudWxsO1xuICB9IGVsc2Uge1xuICAgIHAuc3JjRiA9IHNyYy5zcmNGO1xuICAgIHAuc291cmNlID0gc3JjLnNvdXJjZTtcbiAgfVxuXG4gIHJldHVybiBwO1xufTtcblxuLyoqXG4gKiBTY2hlZHVsZXMgYSBmdW5jdGlvbiB0byBydW4gYWZ0ZXIgcHVsc2UgcHJvcGFnYXRpb24gY29tcGxldGVzLlxuICogQHBhcmFtIHtmdW5jdGlvbn0gZnVuYyAtIFRoZSBmdW5jdGlvbiB0byBydW4uXG4gKi9cbnByb3RvdHlwZSQ0LnJ1bkFmdGVyID0gZnVuY3Rpb24oZnVuYykge1xuICB0aGlzLmRhdGFmbG93LnJ1bkFmdGVyKGZ1bmMpO1xufTtcblxuLyoqXG4gKiBJbmRpY2F0ZXMgaWYgdHVwbGVzIGhhdmUgYmVlbiBhZGRlZCwgcmVtb3ZlZCBvciBtb2RpZmllZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbZmxhZ3NdIC0gVGhlIHR1cGxlIHR5cGVzIChBREQsIFJFTSBvciBNT0QpIHRvIHF1ZXJ5LlxuICogICBEZWZhdWx0cyB0byBBTEwsIHJldHVybmluZyB0cnVlIGlmIGFueSB0dXBsZSB0eXBlIGhhcyBjaGFuZ2VkLlxuICogQHJldHVybiB7Ym9vbGVhbn0gLSBSZXR1cm5zIHRydWUgaWYgb25lIG9yIG1vcmUgcXVlcmllZCB0dXBsZSB0eXBlcyBoYXZlXG4gKiAgIGNoYW5nZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xucHJvdG90eXBlJDQuY2hhbmdlZCA9IGZ1bmN0aW9uKGZsYWdzKSB7XG4gIHZhciBmID0gZmxhZ3MgfHwgQUxMO1xuICByZXR1cm4gKChmICYgQUREKSAmJiB0aGlzLmFkZC5sZW5ndGgpXG4gICAgICB8fCAoKGYgJiBSRU0pICYmIHRoaXMucmVtLmxlbmd0aClcbiAgICAgIHx8ICgoZiAmIE1PRCkgJiYgdGhpcy5tb2QubGVuZ3RoKTtcbn07XG5cbi8qKlxuICogRm9yY2VzIGEgXCJyZWZsb3dcIiBvZiB0dXBsZSB2YWx1ZXMsIHN1Y2ggdGhhdCBhbGwgdHVwbGVzIGluIHRoZSBiYWNraW5nXG4gKiBzb3VyY2UgYXJlIGFkZGVkIHRvIHRoZSBNT0Qgc2V0LCB1bmxlc3MgYWxyZWFkeSBwcmVzZW50IGluIHRoZSBBREQgc2V0LlxuICogQHBhcmFtIHtib29sZWFufSBbZm9yaz1mYWxzZV0gLSBJZiB0cnVlLCByZXR1cm5zIGEgZm9ya2VkIGNvcHkgb2YgdGhpc1xuICogICBwdWxzZSwgYW5kIGludm9rZXMgcmVmbG93IG9uIHRoYXQgZGVyaXZlZCBwdWxzZS5cbiAqIEByZXR1cm4ge1B1bHNlfSAtIFRoZSByZWZsb3dlZCBwdWxzZSBpbnN0YW5jZS5cbiAqL1xucHJvdG90eXBlJDQucmVmbG93ID0gZnVuY3Rpb24oZm9yaykge1xuICBpZiAoZm9yaykgcmV0dXJuIHRoaXMuZm9yayhBTEwpLnJlZmxvdygpO1xuXG4gIHZhciBsZW4gPSB0aGlzLmFkZC5sZW5ndGgsXG4gICAgICBzcmMgPSB0aGlzLnNvdXJjZSAmJiB0aGlzLnNvdXJjZS5sZW5ndGg7XG4gIGlmIChzcmMgJiYgc3JjICE9PSBsZW4pIHtcbiAgICB0aGlzLm1vZCA9IHRoaXMuc291cmNlO1xuICAgIGlmIChsZW4pIHRoaXMuZmlsdGVyKE1PRCwgZmlsdGVyKHRoaXMsIEFERCkpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBNYXJrcyBvbmUgb3IgbW9yZSBkYXRhIGZpZWxkIG5hbWVzIGFzIG1vZGlmaWVkIHRvIGFzc2lzdCBkZXBlbmRlbmN5XG4gKiB0cmFja2luZyBhbmQgaW5jcmVtZW50YWwgcHJvY2Vzc2luZyBieSB0cmFuc2Zvcm0gb3BlcmF0b3JzLlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gXyAtIFRoZSBmaWVsZChzKSB0byBtYXJrIGFzIG1vZGlmaWVkLlxuICogQHJldHVybiB7UHVsc2V9IC0gVGhpcyBwdWxzZSBpbnN0YW5jZS5cbiAqL1xucHJvdG90eXBlJDQubW9kaWZpZXMgPSBmdW5jdGlvbihfKSB7XG4gIHZhciBmaWVsZHMgPSBhcnJheShfKSxcbiAgICAgIGhhc2ggPSB0aGlzLmZpZWxkcyB8fCAodGhpcy5maWVsZHMgPSB7fSk7XG4gIGZpZWxkcy5mb3JFYWNoKGZ1bmN0aW9uKGYpIHsgaGFzaFtmXSA9IHRydWU7IH0pO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8qKlxuICogQ2hlY2tzIGlmIG9uZSBvciBtb3JlIGRhdGEgZmllbGRzIGhhdmUgYmVlbiBtb2RpZmllZCBkdXJpbmcgdGhpcyBwdWxzZVxuICogcHJvcGFnYXRpb24gdGltZXN0YW1wLlxuICogQHBhcmFtIHtzdHJpbmd8QXJyYXk8c3RyaW5nPn0gXyAtIFRoZSBmaWVsZChzKSB0byBjaGVjayBmb3IgbW9kaWZpZWQuXG4gKiBAcmV0dXJuIHtib29sZWFufSAtIFJldHVybnMgdHJ1ZSBpZiBhbnkgb2YgdGhlIHByb3ZpZGVkIGZpZWxkcyBoYXMgYmVlblxuICogICBtYXJrZWQgYXMgbW9kaWZpZWQsIGZhbHNlIG90aGVyd2lzZS5cbiAqL1xucHJvdG90eXBlJDQubW9kaWZpZWQgPSBmdW5jdGlvbihfKSB7XG4gIHZhciBmaWVsZHMgPSB0aGlzLmZpZWxkcztcbiAgcmV0dXJuICEodGhpcy5tb2QubGVuZ3RoICYmIGZpZWxkcykgPyBmYWxzZVxuICAgIDogIWFyZ3VtZW50cy5sZW5ndGggPyAhIWZpZWxkc1xuICAgIDogaXNBcnJheShfKSA/IF8uc29tZShmdW5jdGlvbihmKSB7IHJldHVybiBmaWVsZHNbZl07IH0pXG4gICAgOiBmaWVsZHNbX107XG59O1xuXG4vKipcbiAqIEFkZHMgYSBmaWx0ZXIgZnVuY3Rpb24gdG8gb25lIG1vcmUgdHVwbGUgc2V0cy4gRmlsdGVycyBhcmUgYXBwbGllZCB0b1xuICogYmFja2luZyB0dXBsZSBhcnJheXMsIHRvIGRldGVybWluZSB0aGUgYWN0dWFsIHNldCBvZiB0dXBsZXMgY29uc2lkZXJlZFxuICogYWRkZWQsIHJlbW92ZWQgb3IgbW9kaWZpZWQuIFRoZXkgY2FuIGJlIHVzZWQgdG8gZGVsYXkgbWF0ZXJpYWxpemF0aW9uIG9mXG4gKiBhIHR1cGxlIHNldCBpbiBvcmRlciB0byBhdm9pZCBleHBlbnNpdmUgYXJyYXkgY29waWVzLiBJbiBhZGRpdGlvbiwgdGhlXG4gKiBmaWx0ZXIgZnVuY3Rpb25zIGNhbiBzZXJ2ZSBhcyB2YWx1ZSB0cmFuc2Zvcm1lcnM6IHVubGlrZSBzdGFuZGFyZCBwcmVkaWNhdGVcbiAqIGZ1bmN0aW9uICh3aGljaCByZXR1cm4gYm9vbGVhbiB2YWx1ZXMpLCBQdWxzZSBmaWx0ZXJzIHNob3VsZCByZXR1cm4gdGhlXG4gKiBhY3R1YWwgdHVwbGUgdmFsdWUgdG8gcHJvY2Vzcy4gSWYgYSB0dXBsZSBzZXQgaXMgYWxyZWFkeSBmaWx0ZXJlZCwgdGhlXG4gKiBuZXcgZmlsdGVyIGZ1bmN0aW9uIHdpbGwgYmUgYXBwZW5kZWQgaW50byBhIGNvbmp1bnRpdmUgKCdhbmQnKSBxdWVyeS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmbGFncyAtIEZsYWdzIGluZGljYXRpbmcgdGhlIHR1cGxlIHNldChzKSB0byBmaWx0ZXIuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCopOm9iamVjdH0gZmlsdGVyIC0gRmlsdGVyIGZ1bmN0aW9uIHRoYXQgd2lsbCBiZSBhcHBsaWVkXG4gKiAgIHRvIHRoZSB0dXBsZSBzZXQgYXJyYXksIGFuZCBzaG91bGQgcmV0dXJuIGEgZGF0YSB0dXBsZSBpZiB0aGUgdmFsdWVcbiAqICAgc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZSB0dXBsZSBzZXQsIGFuZCBmYWxzeSAob3IgbnVsbCkgb3RoZXJ3aXNlLlxuICogQHJldHVybiB7UHVsc2V9IC0gUmV0dXJucyB0aGlzIHB1bHNlIGluc3RhbmNlLlxuICovXG5wcm90b3R5cGUkNC5maWx0ZXIgPSBmdW5jdGlvbihmbGFncywgZmlsdGVyKSB7XG4gIHZhciBwID0gdGhpcztcbiAgaWYgKGZsYWdzICYgQUREKSBwLmFkZEYgPSBhZGRGaWx0ZXIocC5hZGRGLCBmaWx0ZXIpO1xuICBpZiAoZmxhZ3MgJiBSRU0pIHAucmVtRiA9IGFkZEZpbHRlcihwLnJlbUYsIGZpbHRlcik7XG4gIGlmIChmbGFncyAmIE1PRCkgcC5tb2RGID0gYWRkRmlsdGVyKHAubW9kRiwgZmlsdGVyKTtcbiAgaWYgKGZsYWdzICYgU09VUkNFKSBwLnNyY0YgPSBhZGRGaWx0ZXIocC5zcmNGLCBmaWx0ZXIpO1xuICByZXR1cm4gcDtcbn07XG5cbmZ1bmN0aW9uIGFkZEZpbHRlcihhLCBiKSB7XG4gIHJldHVybiBhID8gZnVuY3Rpb24odCxpKSB7IHJldHVybiBhKHQsaSkgJiYgYih0LGkpOyB9IDogYjtcbn1cblxuLyoqXG4gKiBNYXRlcmlhbGl6ZSBvbmUgb3IgbW9yZSB0dXBsZSBzZXRzIGluIHRoaXMgcHVsc2UuIElmIHRoZSB0dXBsZSBzZXQocykgaGF2ZVxuICogYSByZWdpc3RlcmVkIGZpbHRlciBmdW5jdGlvbiwgaXQgd2lsbCBiZSBhcHBsaWVkIGFuZCB0aGUgdHVwbGUgc2V0KHMpIHdpbGxcbiAqIGJlIHJlcGxhY2VkIHdpdGggbWF0ZXJpYWxpemVkIHR1cGxlIGFycmF5cy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmbGFncyAtIEZsYWdzIGluZGljYXRpbmcgdGhlIHR1cGxlIHNldChzKSB0byBtYXRlcmlhbGl6ZS5cbiAqIEByZXR1cm4ge1B1bHNlfSAtIFJldHVybnMgdGhpcyBwdWxzZSBpbnN0YW5jZS5cbiAqL1xucHJvdG90eXBlJDQubWF0ZXJpYWxpemUgPSBmdW5jdGlvbihmbGFncykge1xuICBmbGFncyA9IGZsYWdzIHx8IEFMTDtcbiAgdmFyIHAgPSB0aGlzO1xuICBpZiAoKGZsYWdzICYgQUREKSAmJiBwLmFkZEYpIHtcbiAgICBwLmFkZCA9IG1hdGVyaWFsaXplKHAuYWRkLCBwLmFkZEYpO1xuICAgIHAuYWRkRiA9IG51bGw7XG4gIH1cbiAgaWYgKChmbGFncyAmIFJFTSkgJiYgcC5yZW1GKSB7XG4gICAgcC5yZW0gPSBtYXRlcmlhbGl6ZShwLnJlbSwgcC5yZW1GKTtcbiAgICBwLnJlbUYgPSBudWxsO1xuICB9XG4gIGlmICgoZmxhZ3MgJiBNT0QpICYmIHAubW9kRikge1xuICAgIHAubW9kID0gbWF0ZXJpYWxpemUocC5tb2QsIHAubW9kRik7XG4gICAgcC5tb2RGID0gbnVsbDtcbiAgfVxuICBpZiAoKGZsYWdzICYgU09VUkNFKSAmJiBwLnNyY0YpIHtcbiAgICBwLnNvdXJjZSA9IHAuc291cmNlLmZpbHRlcihwLnNyY0YpO1xuICAgIHAuc3JjRiA9IG51bGw7XG4gIH1cbiAgcmV0dXJuIHA7XG59O1xuXG5mdW5jdGlvbiBtYXRlcmlhbGl6ZShkYXRhLCBmaWx0ZXIpIHtcbiAgdmFyIG91dCA9IFtdO1xuICB2aXNpdEFycmF5KGRhdGEsIGZpbHRlciwgZnVuY3Rpb24oXykgeyBvdXQucHVzaChfKTsgfSk7XG4gIHJldHVybiBvdXQ7XG59XG5cbmZ1bmN0aW9uIGZpbHRlcihwdWxzZSwgZmxhZ3MpIHtcbiAgdmFyIG1hcCA9IHt9O1xuICBwdWxzZS52aXNpdChmbGFncywgZnVuY3Rpb24odCkgeyBtYXBbdHVwbGVpZCh0KV0gPSAxOyB9KTtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHsgcmV0dXJuIG1hcFt0dXBsZWlkKHQpXSA/IG51bGwgOiB0OyB9O1xufVxuXG4vKipcbiAqIFZpc2l0IG9uZSBvciBtb3JlIHR1cGxlIHNldHMgaW4gdGhpcyBwdWxzZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBmbGFncyAtIEZsYWdzIGluZGljYXRpbmcgdGhlIHR1cGxlIHNldChzKSB0byB2aXNpdC5cbiAqICAgTGVnYWwgdmFsdWVzIGFyZSBBREQsIFJFTSwgTU9EIGFuZCBTT1VSQ0UgKGlmIGEgYmFja2luZyBkYXRhIHNvdXJjZVxuICogICBoYXMgYmVlbiBzZXQpLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOip9IC0gVmlzaXRvciBmdW5jdGlvbiBpbnZva2VkIHBlci10dXBsZS5cbiAqIEByZXR1cm4ge1B1bHNlfSAtIFJldHVybnMgdGhpcyBwdWxzZSBpbnN0YW5jZS5cbiAqL1xucHJvdG90eXBlJDQudmlzaXQgPSBmdW5jdGlvbihmbGFncywgdmlzaXRvcikge1xuICB2YXIgcCA9IHRoaXMsIHYgPSB2aXNpdG9yLCBzcmMsIHN1bTtcblxuICBpZiAoZmxhZ3MgJiBTT1VSQ0UpIHtcbiAgICB2aXNpdEFycmF5KHAuc291cmNlLCBwLnNyY0YsIHYpO1xuICAgIHJldHVybiBwO1xuICB9XG5cbiAgaWYgKGZsYWdzICYgQUREKSB2aXNpdEFycmF5KHAuYWRkLCBwLmFkZEYsIHYpO1xuICBpZiAoZmxhZ3MgJiBSRU0pIHZpc2l0QXJyYXkocC5yZW0sIHAucmVtRiwgdik7XG4gIGlmIChmbGFncyAmIE1PRCkgdmlzaXRBcnJheShwLm1vZCwgcC5tb2RGLCB2KTtcblxuICBpZiAoKGZsYWdzICYgUkVGTE9XKSAmJiAoc3JjID0gcC5zb3VyY2UpKSB7XG4gICAgc3VtID0gcC5hZGQubGVuZ3RoICsgcC5tb2QubGVuZ3RoO1xuICAgIGlmIChzdW0gPT09IHNyYy5sZW5ndGgpIHtcbiAgICAgIC8vIGRvIG5vdGhpbmdcbiAgICB9IGVsc2UgaWYgKHN1bSkge1xuICAgICAgdmlzaXRBcnJheShzcmMsIGZpbHRlcihwLCBBRERfTU9EKSwgdik7XG4gICAgfSBlbHNlIHtcbiAgICAgIC8vIGlmIG5vIGFkZC9yZW0vbW9kIHR1cGxlcywgdmlzaXQgc291cmNlXG4gICAgICB2aXNpdEFycmF5KHNyYywgcC5zcmNGLCB2KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gcDtcbn07XG5cbi8qKlxuICogUmVwcmVzZW50cyBhIHNldCBvZiBtdWx0aXBsZSBwdWxzZXMuIFVzZWQgYXMgaW5wdXQgZm9yIG9wZXJhdG9yc1xuICogdGhhdCBhY2NlcHQgbXVsdGlwbGUgcHVsc2VzIGF0IGEgdGltZS4gQ29udGFpbmVkIHB1bHNlcyBhcmVcbiAqIGFjY2Vzc2libGUgdmlhIHRoZSBwdWJsaWMgXCJwdWxzZXNcIiBhcnJheSBwcm9wZXJ0eS4gVGhpcyBwdWxzZSBkb2VcbiAqIG5vdCBjYXJyeSBhZGRlZCwgcmVtb3ZlZCBvciBtb2RpZmllZCB0dXBsZXMgZGlyZWN0bHkuIEhvd2V2ZXIsXG4gKiB0aGUgdmlzaXQgbWV0aG9kIGNhbiBiZSB1c2VkIHRvIHRyYXZlcnNlIGFsbCBzdWNoIHR1cGxlcyBjb250YWluZWRcbiAqIGluIHN1Yi1wdWxzZXMgd2l0aCBhIHRpbWVzdGFtcCBtYXRjaGluZyB0aGlzIHBhcmVudCBtdWx0aS1wdWxzZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtEYXRhZmxvd30gZGF0YWZsb3cgLSBUaGUgYmFja2luZyBkYXRhZmxvdyBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBzdGFtcCAtIFRoZSB0aW1lc3RhbXAuXG4gKiBAcGFyYW0ge0FycmF5PFB1bHNlPn0gcHVsc2VzIC0gVGhlIHN1Yi1wdWxzZXMgZm9yIHRoaXMgbXVsdGktcHVsc2UuXG4gKi9cbmZ1bmN0aW9uIE11bHRpUHVsc2UoZGF0YWZsb3csIHN0YW1wLCBwdWxzZXMsIGVuY29kZSkge1xuICB2YXIgcCA9IHRoaXMsXG4gICAgICBjID0gMCxcbiAgICAgIHB1bHNlLCBoYXNoLCBpLCBuLCBmO1xuXG4gIHRoaXMuZGF0YWZsb3cgPSBkYXRhZmxvdztcbiAgdGhpcy5zdGFtcCA9IHN0YW1wO1xuICB0aGlzLmZpZWxkcyA9IG51bGw7XG4gIHRoaXMuZW5jb2RlID0gZW5jb2RlIHx8IG51bGw7XG4gIHRoaXMucHVsc2VzID0gcHVsc2VzO1xuXG4gIGZvciAoaT0wLCBuPXB1bHNlcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgcHVsc2UgPSBwdWxzZXNbaV07XG4gICAgaWYgKHB1bHNlLnN0YW1wICE9PSBzdGFtcCkgY29udGludWU7XG5cbiAgICBpZiAocHVsc2UuZmllbGRzKSB7XG4gICAgICBoYXNoID0gcC5maWVsZHMgfHwgKHAuZmllbGRzID0ge30pO1xuICAgICAgZm9yIChmIGluIHB1bHNlLmZpZWxkcykgeyBoYXNoW2ZdID0gMTsgfVxuICAgIH1cblxuICAgIGlmIChwdWxzZS5jaGFuZ2VkKHAuQUREKSkgYyB8PSBwLkFERDtcbiAgICBpZiAocHVsc2UuY2hhbmdlZChwLlJFTSkpIGMgfD0gcC5SRU07XG4gICAgaWYgKHB1bHNlLmNoYW5nZWQocC5NT0QpKSBjIHw9IHAuTU9EO1xuICB9XG5cbiAgdGhpcy5jaGFuZ2VzID0gYztcbn1cblxudmFyIHByb3RvdHlwZSQ1ID0gaW5oZXJpdHMoTXVsdGlQdWxzZSwgUHVsc2UpO1xuXG4vKipcbiAqIENyZWF0ZXMgYSBuZXcgcHVsc2UgYmFzZWQgb24gdGhlIHZhbHVlcyBvZiB0aGlzIHB1bHNlLlxuICogVGhlIGRhdGFmbG93LCB0aW1lIHN0YW1wIGFuZCBmaWVsZCBtb2RpZmljYXRpb24gdmFsdWVzIGFyZSBjb3BpZWQgb3Zlci5cbiAqIEByZXR1cm4ge1B1bHNlfVxuICovXG5wcm90b3R5cGUkNS5mb3JrID0gZnVuY3Rpb24oZmxhZ3MpIHtcbiAgdmFyIHAgPSBuZXcgUHVsc2UodGhpcy5kYXRhZmxvdykuaW5pdCh0aGlzLCBmbGFncyAmIHRoaXMuTk9fRklFTERTKTtcbiAgaWYgKGZsYWdzICE9PSB1bmRlZmluZWQpIHtcbiAgICBpZiAoZmxhZ3MgJiBwLkFERCkge1xuICAgICAgdGhpcy52aXNpdChwLkFERCwgZnVuY3Rpb24odCkgeyByZXR1cm4gcC5hZGQucHVzaCh0KTsgfSk7XG4gICAgfVxuICAgIGlmIChmbGFncyAmIHAuUkVNKSB7XG4gICAgICB0aGlzLnZpc2l0KHAuUkVNLCBmdW5jdGlvbih0KSB7IHJldHVybiBwLnJlbS5wdXNoKHQpOyB9KTtcbiAgICB9XG4gICAgaWYgKGZsYWdzICYgcC5NT0QpIHtcbiAgICAgIHRoaXMudmlzaXQocC5NT0QsIGZ1bmN0aW9uKHQpIHsgcmV0dXJuIHAubW9kLnB1c2godCk7IH0pO1xuICAgIH1cbiAgfVxuICByZXR1cm4gcDtcbn07XG5cbnByb3RvdHlwZSQ1LmNoYW5nZWQgPSBmdW5jdGlvbihmbGFncykge1xuICByZXR1cm4gdGhpcy5jaGFuZ2VzICYgZmxhZ3M7XG59O1xuXG5wcm90b3R5cGUkNS5tb2RpZmllZCA9IGZ1bmN0aW9uKF8pIHtcbiAgdmFyIHAgPSB0aGlzLCBmaWVsZHMgPSBwLmZpZWxkcztcbiAgcmV0dXJuICEoZmllbGRzICYmIChwLmNoYW5nZXMgJiBwLk1PRCkpID8gMFxuICAgIDogaXNBcnJheShfKSA/IF8uc29tZShmdW5jdGlvbihmKSB7IHJldHVybiBmaWVsZHNbZl07IH0pXG4gICAgOiBmaWVsZHNbX107XG59O1xuXG5wcm90b3R5cGUkNS5maWx0ZXIgPSBmdW5jdGlvbigpIHtcbiAgZXJyb3IkMSgnTXVsdGlQdWxzZSBkb2VzIG5vdCBzdXBwb3J0IGZpbHRlcmluZy4nKTtcbn07XG5cbnByb3RvdHlwZSQ1Lm1hdGVyaWFsaXplID0gZnVuY3Rpb24oKSB7XG4gIGVycm9yJDEoJ011bHRpUHVsc2UgZG9lcyBub3Qgc3VwcG9ydCBtYXRlcmlhbGl6YXRpb24uJyk7XG59O1xuXG5wcm90b3R5cGUkNS52aXNpdCA9IGZ1bmN0aW9uKGZsYWdzLCB2aXNpdG9yKSB7XG4gIHZhciBwID0gdGhpcyxcbiAgICAgIHB1bHNlcyA9IHAucHVsc2VzLFxuICAgICAgbiA9IHB1bHNlcy5sZW5ndGgsXG4gICAgICBpID0gMDtcblxuICBpZiAoZmxhZ3MgJiBwLlNPVVJDRSkge1xuICAgIGZvciAoOyBpPG47ICsraSkge1xuICAgICAgcHVsc2VzW2ldLnZpc2l0KGZsYWdzLCB2aXNpdG9yKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgICBpZiAocHVsc2VzW2ldLnN0YW1wID09PSBwLnN0YW1wKSB7XG4gICAgICAgIHB1bHNlc1tpXS52aXNpdChmbGFncywgdmlzaXRvcik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHA7XG59O1xuXG4vKipcbiAqIFJ1bnMgdGhlIGRhdGFmbG93LiBUaGlzIG1ldGhvZCB3aWxsIGluY3JlbWVudCB0aGUgY3VycmVudCB0aW1lc3RhbXBcbiAqIGFuZCBwcm9jZXNzIGFsbCB1cGRhdGVkLCBwdWxzZWQgYW5kIHRvdWNoZWQgb3BlcmF0b3JzLiBXaGVuIHJ1biBmb3JcbiAqIHRoZSBmaXJzdCB0aW1lLCBhbGwgcmVnaXN0ZXJlZCBvcGVyYXRvcnMgd2lsbCBiZSBwcm9jZXNzZWQuIElmIHRoZXJlXG4gKiBhcmUgcGVuZGluZyBkYXRhIGxvYWRpbmcgb3BlcmF0aW9ucywgdGhpcyBtZXRob2Qgd2lsbCByZXR1cm4gaW1tZWRpYXRlbHlcbiAqIHdpdGhvdXQgZXZhbHVhdGluZyB0aGUgZGF0YWZsb3cuIEluc3RlYWQsIHRoZSBkYXRhZmxvdyB3aWxsIGJlXG4gKiBhc3luY2hyb25vdXNseSBpbnZva2VkIHdoZW4gZGF0YSBsb2FkaW5nIGNvbXBsZXRlcy4gVG8gdHJhY2sgd2hlbiBkYXRhZmxvd1xuICogZXZhbHVhdGlvbiBjb21wbGV0ZXMsIHVzZSB0aGUge0BsaW5rIHJ1bkFzeW5jfSBtZXRob2QgaW5zdGVhZC5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZW5jb2RlXSAtIFRoZSBuYW1lIG9mIGFuIGVuY29kaW5nIHNldCB0byBpbnZva2UgZHVyaW5nXG4gKiAgIHByb3BhZ2F0aW9uLiBUaGlzIHZhbHVlIGlzIGFkZGVkIHRvIGdlbmVyYXRlZCBQdWxzZSBpbnN0YW5jZXM7XG4gKiAgIG9wZXJhdG9ycyBjYW4gdGhlbiByZXNwb25kIHRvIChvciBpZ25vcmUpIHRoaXMgc2V0dGluZyBhcyBhcHByb3ByaWF0ZS5cbiAqICAgVGhpcyBwYXJhbWV0ZXIgY2FuIGJlIHVzZWQgaW4gY29uanVuY3Rpb24gd2l0aCB0aGUgRW5jb2RlIHRyYW5zZm9ybSBpblxuICogICB0aGUgdmVnYS1lbmNvZGUgbW9kdWxlLlxuICovXG5mdW5jdGlvbiBydW4oZW5jb2RlKSB7XG4gIHZhciBkZiA9IHRoaXMsXG4gICAgICBjb3VudCA9IDAsXG4gICAgICBsZXZlbCA9IGRmLmxvZ0xldmVsKCksXG4gICAgICBvcCwgbmV4dCwgZHQsIGVycm9yO1xuXG4gIGlmIChkZi5fcGVuZGluZykge1xuICAgIGRmLmluZm8oJ0F3YWl0aW5nIHJlcXVlc3RzLCBkZWxheWluZyBkYXRhZmxvdyBydW4uJyk7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBpZiAoZGYuX3B1bHNlKSB7XG4gICAgZGYuZXJyb3IoJ0RhdGFmbG93IGludm9rZWQgcmVjdXJzaXZlbHkuIFVzZSB0aGUgcnVuQWZ0ZXIgbWV0aG9kIHRvIHF1ZXVlIGludm9jYXRpb24uJyk7XG4gICAgcmV0dXJuIDA7XG4gIH1cblxuICBpZiAoIWRmLl90b3VjaGVkLmxlbmd0aCkge1xuICAgIGRmLmluZm8oJ0RhdGFmbG93IGludm9rZWQsIGJ1dCBub3RoaW5nIHRvIGRvLicpO1xuICAgIHJldHVybiAwO1xuICB9XG5cbiAgZGYuX3B1bHNlID0gbmV3IFB1bHNlKGRmLCArK2RmLl9jbG9jaywgZW5jb2RlKTtcblxuICBpZiAobGV2ZWwgPj0gSW5mbykge1xuICAgIGR0ID0gRGF0ZS5ub3coKTtcbiAgICBkZi5kZWJ1ZygnLS0gU1RBUlQgUFJPUEFHQVRJT04gKCcgKyBkZi5fY2xvY2sgKyAnKSAtLS0tLScpO1xuICB9XG5cbiAgLy8gaW5pdGlhbGl6ZSBxdWV1ZSwgcmVzZXQgdG91Y2hlZCBvcGVyYXRvcnNcbiAgZGYuX3RvdWNoZWQuZm9yRWFjaChmdW5jdGlvbihvcCkgeyBkZi5fZW5xdWV1ZShvcCwgdHJ1ZSk7IH0pO1xuICBkZi5fdG91Y2hlZCA9IFVuaXF1ZUxpc3QoaWQpO1xuXG4gIHRyeSB7XG4gICAgd2hpbGUgKGRmLl9oZWFwLnNpemUoKSA+IDApIHtcbiAgICAgIG9wID0gZGYuX2hlYXAucG9wKCk7XG5cbiAgICAgIC8vIHJlLXF1ZXVlIGlmIHJhbmsgY2hhbmdlc1xuICAgICAgaWYgKG9wLnJhbmsgIT09IG9wLnFyYW5rKSB7IGRmLl9lbnF1ZXVlKG9wLCB0cnVlKTsgY29udGludWU7IH1cblxuICAgICAgLy8gb3RoZXJ3aXNlLCBldmFsdWF0ZSB0aGUgb3BlcmF0b3JcbiAgICAgIG5leHQgPSBvcC5ydW4oZGYuX2dldFB1bHNlKG9wLCBlbmNvZGUpKTtcblxuICAgICAgaWYgKGxldmVsID49IERlYnVnKSB7XG4gICAgICAgIGRmLmRlYnVnKG9wLmlkLCBuZXh0ID09PSBTdG9wUHJvcGFnYXRpb24gPyAnU1RPUCcgOiBuZXh0LCBvcCk7XG4gICAgICB9XG5cbiAgICAgIC8vIHByb3BhZ2F0ZSB0aGUgcHVsc2VcbiAgICAgIGlmIChuZXh0ICE9PSBTdG9wUHJvcGFnYXRpb24pIHtcbiAgICAgICAgZGYuX3B1bHNlID0gbmV4dDtcbiAgICAgICAgaWYgKG9wLl90YXJnZXRzKSBvcC5fdGFyZ2V0cy5mb3JFYWNoKGZ1bmN0aW9uKG9wKSB7IGRmLl9lbnF1ZXVlKG9wKTsgfSk7XG4gICAgICB9XG5cbiAgICAgIC8vIGluY3JlbWVudCB2aXNpdCBjb3VudGVyXG4gICAgICArK2NvdW50O1xuICAgIH1cbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IgPSBlcnI7XG4gIH1cblxuICAvLyByZXNldCBwdWxzZSBtYXBcbiAgZGYuX3B1bHNlcyA9IHt9O1xuICBkZi5fcHVsc2UgPSBudWxsO1xuXG4gIGlmIChsZXZlbCA+PSBJbmZvKSB7XG4gICAgZHQgPSBEYXRlLm5vdygpIC0gZHQ7XG4gICAgZGYuaW5mbygnPiBQdWxzZSAnICsgZGYuX2Nsb2NrICsgJzogJyArIGNvdW50ICsgJyBvcGVyYXRvcnM7ICcgKyBkdCArICdtcycpO1xuICB9XG5cbiAgaWYgKGVycm9yKSB7XG4gICAgZGYuX3Bvc3RydW4gPSBbXTtcbiAgICBkZi5lcnJvcihlcnJvcik7XG4gIH1cblxuICBpZiAoZGYuX29ucnVuKSB7XG4gICAgdHJ5IHsgZGYuX29ucnVuKGRmLCBjb3VudCwgZXJyb3IpOyB9IGNhdGNoIChlcnIpIHsgZGYuZXJyb3IoZXJyKTsgfVxuICB9XG5cbiAgLy8gaW52b2tlIGNhbGxiYWNrcyBxdWV1ZWQgdmlhIHJ1bkFmdGVyXG4gIGlmIChkZi5fcG9zdHJ1bi5sZW5ndGgpIHtcbiAgICB2YXIgcG9zdHJ1biA9IGRmLl9wb3N0cnVuO1xuICAgIGRmLl9wb3N0cnVuID0gW107XG4gICAgcG9zdHJ1blxuICAgICAgLnNvcnQoZnVuY3Rpb24oYSwgYikgeyByZXR1cm4gYi5wcmlvcml0eSAtIGEucHJpb3JpdHk7IH0pXG4gICAgICAuZm9yRWFjaChmdW5jdGlvbihfKSB7IGludm9rZUNhbGxiYWNrKGRmLCBfLmNhbGxiYWNrKTsgfSk7XG4gIH1cblxuICByZXR1cm4gY291bnQ7XG59XG5cbmZ1bmN0aW9uIGludm9rZUNhbGxiYWNrKGRmLCBjYWxsYmFjaykge1xuICB0cnkgeyBjYWxsYmFjayhkZik7IH0gY2F0Y2ggKGVycikgeyBkZi5lcnJvcihlcnIpOyB9XG59XG5cbi8qKlxuICogUnVucyB0aGUgZGF0YWZsb3cgYW5kIHJldHVybnMgYSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiB0aGVcbiAqIHByb3BhZ2F0aW9uIGN5Y2xlIGNvbXBsZXRlcy4gVGhlIHN0YW5kYXJkIHJ1biBtZXRob2QgbWF5IGV4aXQgZWFybHlcbiAqIGlmIHRoZXJlIGFyZSBwZW5kaW5nIGRhdGEgbG9hZGluZyBvcGVyYXRpb25zLiBJbiBjb250cmFzdCwgdGhpc1xuICogbWV0aG9kIHJldHVybnMgYSBQcm9taXNlIHRvIGFsbG93IGNhbGxlcnMgdG8gcmVjZWl2ZSBub3RpZmljYXRpb25cbiAqIHdoZW4gZGF0YWZsb3cgZXZhbHVhdGlvbiBjb21wbGV0ZXMuXG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoaXMgZGF0YWZsb3cuXG4gKi9cbmZ1bmN0aW9uIHJ1bkFzeW5jKCkge1xuICByZXR1cm4gdGhpcy5fcGVuZGluZyB8fCBQcm9taXNlLnJlc29sdmUodGhpcy5ydW4oKSk7XG59XG5cbi8qKlxuICogU2NoZWR1bGVzIGEgY2FsbGJhY2sgZnVuY3Rpb24gdG8gYmUgaW52b2tlZCBhZnRlciB0aGUgY3VycmVudCBwdWxzZVxuICogcHJvcGFnYXRpb24gY29tcGxldGVzLiBJZiBubyBwcm9wYWdhdGlvbiBpcyBjdXJyZW50bHkgb2NjdXJyaW5nLFxuICogdGhlIGZ1bmN0aW9uIGlzIGludm9rZWQgaW1tZWRpYXRlbHkuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKERhdGFmbG93KX0gY2FsbGJhY2sgLSBUaGUgY2FsbGJhY2sgZnVuY3Rpb24gdG8gcnVuLlxuICogICBUaGUgY2FsbGJhY2sgd2lsbCBiZSBpbnZva2VkIHdpdGggdGhpcyBEYXRhZmxvdyBpbnN0YW5jZSBhcyBpdHNcbiAqICAgc29sZSBhcmd1bWVudC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gZW5xdWV1ZSAtIEEgYm9vbGVhbiBmbGFnIGluZGljYXRpbmcgdGhhdCB0aGVcbiAqICAgY2FsbGJhY2sgc2hvdWxkIGJlIHF1ZXVlZCB1cCB0byBydW4gYWZ0ZXIgdGhlIG5leHQgcHJvcGFnYXRpb25cbiAqICAgY3ljbGUsIHN1cHByZXNzaW5nIGltbWVkaWF0ZSBpbnZvY2F0aW9uIHdoZW4gcHJvcGFnYXRpb24gaXMgbm90XG4gKiAgIGN1cnJlbnRseSBvY2N1cnJpbmcuXG4gKi9cbmZ1bmN0aW9uIHJ1bkFmdGVyKGNhbGxiYWNrLCBlbnF1ZXVlLCBwcmlvcml0eSkge1xuICBpZiAodGhpcy5fcHVsc2UgfHwgZW5xdWV1ZSkge1xuICAgIC8vIHB1bHNlIHByb3BhZ2F0aW9uIGlzIGN1cnJlbnRseSBydW5uaW5nLCBxdWV1ZSB0byBydW4gYWZ0ZXJcbiAgICB0aGlzLl9wb3N0cnVuLnB1c2goe1xuICAgICAgcHJpb3JpdHk6IHByaW9yaXR5IHx8IDAsXG4gICAgICBjYWxsYmFjazogY2FsbGJhY2tcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBwdWxzZSBwcm9wYWdhdGlvbiBhbHJlYWR5IGNvbXBsZXRlLCBpbnZva2UgaW1tZWRpYXRlbHlcbiAgICBpbnZva2VDYWxsYmFjayh0aGlzLCBjYWxsYmFjayk7XG4gIH1cbn1cblxuLyoqXG4gKiBFbnF1ZXVlIGFuIG9wZXJhdG9yIGludG8gdGhlIHByaW9yaXR5IHF1ZXVlIGZvciBldmFsdWF0aW9uLiBUaGUgb3BlcmF0b3JcbiAqIHdpbGwgYmUgZW5xdWV1ZWQgaWYgaXQgaGFzIG5vIHJlZ2lzdGVyZWQgcHVsc2UgZm9yIHRoZSBjdXJyZW50IGN5Y2xlLCBvciBpZlxuICogdGhlIGZvcmNlIGFyZ3VtZW50IGlzIHRydWUuIFVwb24gZW5xdWV1ZSwgdGhpcyBtZXRob2QgYWxzbyBzZXRzIHRoZVxuICogb3BlcmF0b3IncyBxcmFuayB0byB0aGUgY3VycmVudCByYW5rIHZhbHVlLlxuICogQHBhcmFtIHtPcGVyYXRvcn0gb3AgLSBUaGUgb3BlcmF0b3IgdG8gZW5xdWV1ZS5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW2ZvcmNlXSAtIEEgZmxhZyBpbmRpY2F0aW5nIGlmIHRoZSBvcGVyYXRvciBzaG91bGQgYmVcbiAqICAgZm9yY2VhYmx5IGFkZGVkIHRvIHRoZSBxdWV1ZSwgZXZlbiBpZiBpdCBoYXMgYWxyZWFkeSBiZWVuIHByZXZpb3VzbHlcbiAqICAgZW5xdWV1ZWQgZHVyaW5nIHRoZSBjdXJyZW50IHB1bHNlIHByb3BhZ2F0aW9uLiBUaGlzIGlzIHVzZWZ1bCB3aGVuIHRoZVxuICogICBkYXRhZmxvdyBncmFwaCBpcyBkeW5hbWljYWxseSBtb2RpZmllZCBhbmQgdGhlIG9wZXJhdG9yIHJhbmsgY2hhbmdlcy5cbiAqL1xuZnVuY3Rpb24gZW5xdWV1ZShvcCwgZm9yY2UpIHtcbiAgdmFyIHAgPSAhdGhpcy5fcHVsc2VzW29wLmlkXTtcbiAgaWYgKHApIHRoaXMuX3B1bHNlc1tvcC5pZF0gPSB0aGlzLl9wdWxzZTtcbiAgaWYgKHAgfHwgZm9yY2UpIHtcbiAgICBvcC5xcmFuayA9IG9wLnJhbms7XG4gICAgdGhpcy5faGVhcC5wdXNoKG9wKTtcbiAgfVxufVxuXG4vKipcbiAqIFByb3ZpZGUgYSBjb3JyZWN0IHB1bHNlIGZvciBldmFsdWF0aW5nIGFuIG9wZXJhdG9yLiBJZiB0aGUgb3BlcmF0b3IgaGFzIGFuXG4gKiBleHBsaWNpdCBzb3VyY2Ugb3BlcmF0b3IsIHdlIHdpbGwgdHJ5IHRvIHB1bGwgdGhlIHB1bHNlKHMpIGZyb20gaXQuXG4gKiBJZiB0aGVyZSBpcyBhbiBhcnJheSBvZiBzb3VyY2Ugb3BlcmF0b3JzLCB3ZSBidWlsZCBhIG11bHRpLXB1bHNlLlxuICogT3RoZXJ3aXNlLCB3ZSByZXR1cm4gYSBjdXJyZW50IHB1bHNlIHdpdGggY29ycmVjdCBzb3VyY2UgZGF0YS5cbiAqIElmIHRoZSBwdWxzZSBpcyB0aGUgcHVsc2UgbWFwIGhhcyBhbiBleHBsaWNpdCB0YXJnZXQgc2V0LCB3ZSB1c2UgdGhhdC5cbiAqIEVsc2UgaWYgdGhlIHB1bHNlIG9uIHRoZSB1cHN0cmVhbSBzb3VyY2Ugb3BlcmF0b3IgaXMgY3VycmVudCwgd2UgdXNlIHRoYXQuXG4gKiBFbHNlIHdlIHVzZSB0aGUgcHVsc2UgZnJvbSB0aGUgcHVsc2UgbWFwLCBidXQgY29weSB0aGUgc291cmNlIHR1cGxlIGFycmF5LlxuICogQHBhcmFtIHtPcGVyYXRvcn0gb3AgLSBUaGUgb3BlcmF0b3IgZm9yIHdoaWNoIHRvIGdldCBhbiBpbnB1dCBwdWxzZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZW5jb2RlXSAtIEFuIChvcHRpb25hbCkgZW5jb2Rpbmcgc2V0IG5hbWUgd2l0aCB3aGljaCB0b1xuICogICBhbm5vdGF0ZSB0aGUgcmV0dXJuZWQgcHVsc2UuIFNlZSB7QGxpbmsgcnVufSBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xuZnVuY3Rpb24gZ2V0UHVsc2Uob3AsIGVuY29kZSkge1xuICB2YXIgcyA9IG9wLnNvdXJjZSxcbiAgICAgIHN0YW1wID0gdGhpcy5fY2xvY2ssXG4gICAgICBwO1xuXG4gIGlmIChzICYmIGlzQXJyYXkocykpIHtcbiAgICBwID0gcy5tYXAoZnVuY3Rpb24oXykgeyByZXR1cm4gXy5wdWxzZTsgfSk7XG4gICAgcmV0dXJuIG5ldyBNdWx0aVB1bHNlKHRoaXMsIHN0YW1wLCBwLCBlbmNvZGUpO1xuICB9XG5cbiAgcCA9IHRoaXMuX3B1bHNlc1tvcC5pZF07XG4gIGlmIChzKSB7XG4gICAgcyA9IHMucHVsc2U7XG4gICAgaWYgKCFzIHx8IHMgPT09IFN0b3BQcm9wYWdhdGlvbikge1xuICAgICAgcC5zb3VyY2UgPSBbXTtcbiAgICB9IGVsc2UgaWYgKHMuc3RhbXAgPT09IHN0YW1wICYmIHAudGFyZ2V0ICE9PSBvcCkge1xuICAgICAgcCA9IHM7XG4gICAgfSBlbHNlIHtcbiAgICAgIHAuc291cmNlID0gcy5zb3VyY2U7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHA7XG59XG5cbnZhciBOT19PUFQgPSB7c2tpcDogZmFsc2UsIGZvcmNlOiBmYWxzZX07XG5cbi8qKlxuICogVG91Y2hlcyBhbiBvcGVyYXRvciwgc2NoZWR1bGluZyBpdCB0byBiZSBldmFsdWF0ZWQuIElmIGludm9rZWQgb3V0c2lkZSBvZlxuICogYSBwdWxzZSBwcm9wYWdhdGlvbiwgdGhlIG9wZXJhdG9yIHdpbGwgYmUgZXZhbHVhdGVkIHRoZSBuZXh0IHRpbWUgdGhpc1xuICogZGF0YWZsb3cgaXMgcnVuLiBJZiBpbnZva2VkIGluIHRoZSBtaWRzdCBvZiBwdWxzZSBwcm9wYWdhdGlvbiwgdGhlIG9wZXJhdG9yXG4gKiB3aWxsIGJlIHF1ZXVlZCBmb3IgZXZhbHVhdGlvbiBpZiBhbmQgb25seSBpZiB0aGUgb3BlcmF0b3IgaGFzIG5vdCB5ZXQgYmVlblxuICogZXZhbHVhdGVkIG9uIHRoZSBjdXJyZW50IHByb3BhZ2F0aW9uIHRpbWVzdGFtcC5cbiAqIEBwYXJhbSB7T3BlcmF0b3J9IG9wIC0gVGhlIG9wZXJhdG9yIHRvIHRvdWNoLlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXSAtIEFkZGl0aW9uYWwgb3B0aW9ucyBoYXNoLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5za2lwXSAtIElmIHRydWUsIHRoZSBvcGVyYXRvciB3aWxsXG4gKiAgIGJlIHNraXBwZWQ6IGl0IHdpbGwgbm90IGJlIGV2YWx1YXRlZCwgYnV0IGl0cyBkZXBlbmRlbnRzIHdpbGwgYmUuXG4gKiBAcmV0dXJuIHtEYXRhZmxvd31cbiAqL1xuZnVuY3Rpb24gdG91Y2gob3AsIG9wdGlvbnMpIHtcbiAgdmFyIG9wdCA9IG9wdGlvbnMgfHwgTk9fT1BUO1xuICBpZiAodGhpcy5fcHVsc2UpIHtcbiAgICAvLyBpZiBpbiBtaWRzdCBvZiBwcm9wYWdhdGlvbiwgYWRkIHRvIHByaW9yaXR5IHF1ZXVlXG4gICAgdGhpcy5fZW5xdWV1ZShvcCk7XG4gIH0gZWxzZSB7XG4gICAgLy8gb3RoZXJ3aXNlLCBxdWV1ZSBmb3IgbmV4dCBwcm9wYWdhdGlvblxuICAgIHRoaXMuX3RvdWNoZWQuYWRkKG9wKTtcbiAgfVxuICBpZiAob3B0LnNraXApIG9wLnNraXAodHJ1ZSk7XG4gIHJldHVybiB0aGlzO1xufVxuXG4vKipcbiAqIFVwZGF0ZXMgdGhlIHZhbHVlIG9mIHRoZSBnaXZlbiBvcGVyYXRvci5cbiAqIEBwYXJhbSB7T3BlcmF0b3J9IG9wIC0gVGhlIG9wZXJhdG9yIHRvIHVwZGF0ZS5cbiAqIEBwYXJhbSB7Kn0gdmFsdWUgLSBUaGUgdmFsdWUgdG8gc2V0LlxuICogQHBhcmFtIHtvYmplY3R9IFtvcHRpb25zXSAtIEFkZGl0aW9uYWwgb3B0aW9ucyBoYXNoLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5mb3JjZV0gLSBJZiB0cnVlLCB0aGUgb3BlcmF0b3Igd2lsbFxuICogICBiZSByZS1ldmFsdWF0ZWQgZXZlbiBpZiBpdHMgdmFsdWUgaGFzIG5vdCBjaGFuZ2VkLlxuICogQHBhcmFtIHtib29sZWFufSBbb3B0aW9ucy5za2lwXSAtIElmIHRydWUsIHRoZSBvcGVyYXRvciB3aWxsXG4gKiAgIGJlIHNraXBwZWQ6IGl0IHdpbGwgbm90IGJlIGV2YWx1YXRlZCwgYnV0IGl0cyBkZXBlbmRlbnRzIHdpbGwgYmUuXG4gKiBAcmV0dXJuIHtEYXRhZmxvd31cbiAqL1xuZnVuY3Rpb24gdXBkYXRlKG9wLCB2YWx1ZSwgb3B0aW9ucykge1xuICB2YXIgb3B0ID0gb3B0aW9ucyB8fCBOT19PUFQ7XG4gIGlmIChvcC5zZXQodmFsdWUpIHx8IG9wdC5mb3JjZSkge1xuICAgIHRoaXMudG91Y2gob3AsIG9wdCk7XG4gIH1cbiAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogUHVsc2VzIGFuIG9wZXJhdG9yIHdpdGggYSBjaGFuZ2VzZXQgb2YgdHVwbGVzLiBJZiBpbnZva2VkIG91dHNpZGUgb2ZcbiAqIGEgcHVsc2UgcHJvcGFnYXRpb24sIHRoZSBwdWxzZSB3aWxsIGJlIGFwcGxpZWQgdGhlIG5leHQgdGltZSB0aGlzXG4gKiBkYXRhZmxvdyBpcyBydW4uIElmIGludm9rZWQgaW4gdGhlIG1pZHN0IG9mIHB1bHNlIHByb3BhZ2F0aW9uLCB0aGUgcHVsc2VcbiAqIHdpbGwgYmUgYWRkZWQgdG8gdGhlIHNldCBvZiBhY3RpdmUgcHVsc2VzIGFuZCB3aWxsIGJlIGFwcGxpZWQgaWYgYW5kXG4gKiBvbmx5IGlmIHRoZSB0YXJnZXQgb3BlcmF0b3IgaGFzIG5vdCB5ZXQgYmVlbiBldmFsdWF0ZWQgb24gdGhlIGN1cnJlbnRcbiAqIHByb3BhZ2F0aW9uIHRpbWVzdGFtcC5cbiAqIEBwYXJhbSB7T3BlcmF0b3J9IG9wIC0gVGhlIG9wZXJhdG9yIHRvIHB1bHNlLlxuICogQHBhcmFtIHtDaGFuZ2VTZXR9IHZhbHVlIC0gVGhlIHR1cGxlIGNoYW5nZXNldCB0byBhcHBseS5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBBZGRpdGlvbmFsIG9wdGlvbnMgaGFzaC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW29wdGlvbnMuc2tpcF0gLSBJZiB0cnVlLCB0aGUgb3BlcmF0b3Igd2lsbFxuICogICBiZSBza2lwcGVkOiBpdCB3aWxsIG5vdCBiZSBldmFsdWF0ZWQsIGJ1dCBpdHMgZGVwZW5kZW50cyB3aWxsIGJlLlxuICogQHJldHVybiB7RGF0YWZsb3d9XG4gKi9cbmZ1bmN0aW9uIHB1bHNlKG9wLCBjaGFuZ2VzZXQsIG9wdGlvbnMpIHtcbiAgdGhpcy50b3VjaChvcCwgb3B0aW9ucyB8fCBOT19PUFQpO1xuXG4gIHZhciBwID0gbmV3IFB1bHNlKHRoaXMsIHRoaXMuX2Nsb2NrICsgKHRoaXMuX3B1bHNlID8gMCA6IDEpKSxcbiAgICAgIHQgPSBvcC5wdWxzZSAmJiBvcC5wdWxzZS5zb3VyY2UgfHwgW107XG4gIHAudGFyZ2V0ID0gb3A7XG4gIHRoaXMuX3B1bHNlc1tvcC5pZF0gPSBjaGFuZ2VzZXQucHVsc2UocCwgdCk7XG5cbiAgcmV0dXJuIHRoaXM7XG59XG5cbmZ1bmN0aW9uIEhlYXAoY29tcGFyYXRvcikge1xuICB0aGlzLmNtcCA9IGNvbXBhcmF0b3I7XG4gIHRoaXMubm9kZXMgPSBbXTtcbn1cblxudmFyIHByb3RvdHlwZSQ2ID0gSGVhcC5wcm90b3R5cGU7XG5cbnByb3RvdHlwZSQ2LnNpemUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMubm9kZXMubGVuZ3RoO1xufTtcblxucHJvdG90eXBlJDYuY2xlYXIgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5ub2RlcyA9IFtdO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ2LnBlZWsgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMubm9kZXNbMF07XG59O1xuXG5wcm90b3R5cGUkNi5wdXNoID0gZnVuY3Rpb24oeCkge1xuICB2YXIgYXJyYXkgPSB0aGlzLm5vZGVzO1xuICBhcnJheS5wdXNoKHgpO1xuICByZXR1cm4gc2lmdGRvd24oYXJyYXksIDAsIGFycmF5Lmxlbmd0aC0xLCB0aGlzLmNtcCk7XG59O1xuXG5wcm90b3R5cGUkNi5wb3AgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFycmF5ID0gdGhpcy5ub2RlcyxcbiAgICAgIGxhc3QgPSBhcnJheS5wb3AoKSxcbiAgICAgIGl0ZW07XG5cbiAgaWYgKGFycmF5Lmxlbmd0aCkge1xuICAgIGl0ZW0gPSBhcnJheVswXTtcbiAgICBhcnJheVswXSA9IGxhc3Q7XG4gICAgc2lmdHVwKGFycmF5LCAwLCB0aGlzLmNtcCk7XG4gIH0gZWxzZSB7XG4gICAgaXRlbSA9IGxhc3Q7XG4gIH1cbiAgcmV0dXJuIGl0ZW07XG59O1xuXG5wcm90b3R5cGUkNi5yZXBsYWNlID0gZnVuY3Rpb24oaXRlbSkge1xuICB2YXIgYXJyYXkgPSB0aGlzLm5vZGVzLFxuICAgICAgcmV0dmFsID0gYXJyYXlbMF07XG4gIGFycmF5WzBdID0gaXRlbTtcbiAgc2lmdHVwKGFycmF5LCAwLCB0aGlzLmNtcCk7XG4gIHJldHVybiByZXR2YWw7XG59O1xuXG5wcm90b3R5cGUkNi5wdXNocG9wID0gZnVuY3Rpb24oaXRlbSkge1xuICB2YXIgYXJyYXkgPSB0aGlzLm5vZGVzLCByZWYgPSBhcnJheVswXTtcbiAgaWYgKGFycmF5Lmxlbmd0aCAmJiB0aGlzLmNtcChyZWYsIGl0ZW0pIDwgMCkge1xuICAgIGFycmF5WzBdID0gaXRlbTtcbiAgICBpdGVtID0gcmVmO1xuICAgIHNpZnR1cChhcnJheSwgMCwgdGhpcy5jbXApO1xuICB9XG4gIHJldHVybiBpdGVtO1xufTtcblxuZnVuY3Rpb24gc2lmdGRvd24oYXJyYXksIHN0YXJ0LCBpZHgsIGNtcCkge1xuICB2YXIgaXRlbSwgcGFyZW50LCBwaWR4O1xuXG4gIGl0ZW0gPSBhcnJheVtpZHhdO1xuICB3aGlsZSAoaWR4ID4gc3RhcnQpIHtcbiAgICBwaWR4ID0gKGlkeCAtIDEpID4+IDE7XG4gICAgcGFyZW50ID0gYXJyYXlbcGlkeF07XG4gICAgaWYgKGNtcChpdGVtLCBwYXJlbnQpIDwgMCkge1xuICAgICAgYXJyYXlbaWR4XSA9IHBhcmVudDtcbiAgICAgIGlkeCA9IHBpZHg7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG4gICAgYnJlYWs7XG4gIH1cbiAgcmV0dXJuIChhcnJheVtpZHhdID0gaXRlbSk7XG59XG5cbmZ1bmN0aW9uIHNpZnR1cChhcnJheSwgaWR4LCBjbXApIHtcbiAgdmFyIHN0YXJ0ID0gaWR4LFxuICAgICAgZW5kID0gYXJyYXkubGVuZ3RoLFxuICAgICAgaXRlbSA9IGFycmF5W2lkeF0sXG4gICAgICBjaWR4ID0gMiAqIGlkeCArIDEsIHJpZHg7XG5cbiAgd2hpbGUgKGNpZHggPCBlbmQpIHtcbiAgICByaWR4ID0gY2lkeCArIDE7XG4gICAgaWYgKHJpZHggPCBlbmQgJiYgY21wKGFycmF5W2NpZHhdLCBhcnJheVtyaWR4XSkgPj0gMCkge1xuICAgICAgY2lkeCA9IHJpZHg7XG4gICAgfVxuICAgIGFycmF5W2lkeF0gPSBhcnJheVtjaWR4XTtcbiAgICBpZHggPSBjaWR4O1xuICAgIGNpZHggPSAyICogaWR4ICsgMTtcbiAgfVxuICBhcnJheVtpZHhdID0gaXRlbTtcbiAgcmV0dXJuIHNpZnRkb3duKGFycmF5LCBzdGFydCwgaWR4LCBjbXApO1xufVxuXG4vKipcbiAqIEEgZGF0YWZsb3cgZ3JhcGggZm9yIHJlYWN0aXZlIHByb2Nlc3Npbmcgb2YgZGF0YSBzdHJlYW1zLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIERhdGFmbG93KCkge1xuICB0aGlzLl9sb2cgPSBsb2dnZXIoKTtcbiAgdGhpcy5sb2dMZXZlbChFcnJvciQxKTtcblxuICB0aGlzLl9jbG9jayA9IDA7XG4gIHRoaXMuX3JhbmsgPSAwO1xuICB0cnkge1xuICAgIHRoaXMuX2xvYWRlciA9IGxvYWRlcigpO1xuICB9IGNhdGNoIChlKSB7XG4gICAgLy8gZG8gbm90aGluZyBpZiBsb2FkZXIgbW9kdWxlIGlzIHVuYXZhaWxhYmxlXG4gIH1cblxuICB0aGlzLl90b3VjaGVkID0gVW5pcXVlTGlzdChpZCk7XG4gIHRoaXMuX3B1bHNlcyA9IHt9O1xuICB0aGlzLl9wdWxzZSA9IG51bGw7XG5cbiAgdGhpcy5faGVhcCA9IG5ldyBIZWFwKGZ1bmN0aW9uKGEsIGIpIHsgcmV0dXJuIGEucXJhbmsgLSBiLnFyYW5rOyB9KTtcbiAgdGhpcy5fcG9zdHJ1biA9IFtdO1xufVxuXG52YXIgcHJvdG90eXBlID0gRGF0YWZsb3cucHJvdG90eXBlO1xuXG4vKipcbiAqIFRoZSBjdXJyZW50IHRpbWVzdGFtcCBvZiB0aGlzIGRhdGFmbG93LiBUaGlzIHZhbHVlIHJlZmxlY3RzIHRoZVxuICogdGltZXN0YW1wIG9mIHRoZSBwcmV2aW91cyBkYXRhZmxvdyBydW4uIFRoZSBkYXRhZmxvdyBpcyBpbml0aWFsaXplZFxuICogd2l0aCBhIHN0YW1wIHZhbHVlIG9mIDAuIFRoZSBpbml0aWFsIHJ1biBvZiB0aGUgZGF0YWZsb3cgd2lsbCBoYXZlXG4gKiBhIHRpbWVzdGFwIG9mIDEsIGFuZCBzbyBvbi4gVGhpcyB2YWx1ZSB3aWxsIG1hdGNoIHRoZVxuICoge0BsaW5rIFB1bHNlLnN0YW1wfSBwcm9wZXJ0eS5cbiAqIEByZXR1cm4ge251bWJlcn0gLSBUaGUgY3VycmVudCB0aW1lc3RhbXAgdmFsdWUuXG4gKi9cbnByb3RvdHlwZS5zdGFtcCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fY2xvY2s7XG59O1xuXG4vKipcbiAqIEdldHMgb3Igc2V0cyB0aGUgbG9hZGVyIGluc3RhbmNlIHRvIHVzZSBmb3IgZGF0YSBmaWxlIGxvYWRpbmcuIEFcbiAqIGxvYWRlciBvYmplY3QgbXVzdCBwcm92aWRlIGEgXCJsb2FkXCIgbWV0aG9kIGZvciBsb2FkaW5nIGZpbGVzIGFuZCBhXG4gKiBcInNhbml0aXplXCIgbWV0aG9kIGZvciBjaGVja2luZyBVUkwvZmlsZW5hbWUgdmFsaWRpdHkuIEJvdGggbWV0aG9kc1xuICogc2hvdWxkIGFjY2VwdCBhIFVSSSBhbmQgb3B0aW9ucyBoYXNoIGFzIGFyZ3VtZW50cywgYW5kIHJldHVybiBhIFByb21pc2VcbiAqIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxvYWRlZCBmaWxlIGNvbnRlbnRzIChsb2FkKSBvciBhIGhhc2ggY29udGFpbmluZ1xuICogc2FuaXRpemVkIFVSSSBkYXRhIHdpdGggdGhlIHNhbml0aXplZCB1cmwgYXNzaWduZWQgdG8gdGhlIFwiaHJlZlwiIHByb3BlcnR5XG4gKiAoc2FuaXRpemUpLlxuICogQHBhcmFtIHtvYmplY3R9IF8gLSBUaGUgbG9hZGVyIGluc3RhbmNlIHRvIHVzZS5cbiAqIEByZXR1cm4ge29iamVjdHxEYXRhZmxvd30gLSBJZiBubyBhcmd1bWVudHMgYXJlIHByb3ZpZGVkLCByZXR1cm5zXG4gKiAgIHRoZSBjdXJyZW50IGxvYWRlciBpbnN0YW5jZS4gT3RoZXJ3aXNlIHJldHVybnMgdGhpcyBEYXRhZmxvdyBpbnN0YW5jZS5cbiAqL1xucHJvdG90eXBlLmxvYWRlciA9IGZ1bmN0aW9uKF8pIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICB0aGlzLl9sb2FkZXIgPSBfO1xuICAgIHJldHVybiB0aGlzO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzLl9sb2FkZXI7XG4gIH1cbn07XG5cbi8qKlxuICogRW1wdHkgZW50cnkgdGhyZXNob2xkIGZvciBnYXJiYWdlIGNsZWFuaW5nLiBNYXAgZGF0YSBzdHJ1Y3R1cmVzIHdpbGxcbiAqIHBlcmZvcm0gY2xlYW5pbmcgb25jZSB0aGUgbnVtYmVyIG9mIGVtcHR5IGVudHJpZXMgZXhjZWVkcyB0aGlzIHZhbHVlLlxuICovXG5wcm90b3R5cGUuY2xlYW5UaHJlc2hvbGQgPSAxZTQ7XG5cbi8vIE9QRVJBVE9SIFJFR0lTVFJBVElPTlxucHJvdG90eXBlLmFkZCA9IGFkZDtcbnByb3RvdHlwZS5jb25uZWN0ID0gY29ubmVjdDtcbnByb3RvdHlwZS5yYW5rID0gcmFuaztcbnByb3RvdHlwZS5yZXJhbmsgPSByZXJhbms7XG5cbi8vIE9QRVJBVE9SIFVQREFURVNcbnByb3RvdHlwZS5wdWxzZSA9IHB1bHNlO1xucHJvdG90eXBlLnRvdWNoID0gdG91Y2g7XG5wcm90b3R5cGUudXBkYXRlID0gdXBkYXRlO1xucHJvdG90eXBlLmNoYW5nZXNldCA9IGNoYW5nZXNldDtcblxuLy8gREFUQSBMT0FESU5HXG5wcm90b3R5cGUuaW5nZXN0ID0gaW5nZXN0JDE7XG5wcm90b3R5cGUucmVxdWVzdCA9IHJlcXVlc3Q7XG5cbi8vIEVWRU5UIEhBTkRMSU5HXG5wcm90b3R5cGUuZXZlbnRzID0gZXZlbnRzO1xucHJvdG90eXBlLm9uID0gb247XG5cbi8vIFBVTFNFIFBST1BBR0FUSU9OXG5wcm90b3R5cGUucnVuID0gcnVuO1xucHJvdG90eXBlLnJ1bkFzeW5jID0gcnVuQXN5bmM7XG5wcm90b3R5cGUucnVuQWZ0ZXIgPSBydW5BZnRlcjtcbnByb3RvdHlwZS5fZW5xdWV1ZSA9IGVucXVldWU7XG5wcm90b3R5cGUuX2dldFB1bHNlID0gZ2V0UHVsc2U7XG5cbi8vIExPR0dJTkcgQU5EIEVSUk9SIEhBTkRMSU5HXG5cbmZ1bmN0aW9uIGxvZ01ldGhvZChtZXRob2QpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLl9sb2dbbWV0aG9kXS5hcHBseSh0aGlzLCBhcmd1bWVudHMpO1xuICB9O1xufVxuXG4vKipcbiAqIExvZ3MgYW4gZXJyb3IgbWVzc2FnZS4gQnkgZGVmYXVsdCwgbG9nZ2VkIG1lc3NhZ2VzIGFyZSB3cml0dGVuIHRvIGNvbnNvbGVcbiAqIG91dHB1dC4gVGhlIG1lc3NhZ2Ugd2lsbCBvbmx5IGJlIGxvZ2dlZCBpZiB0aGUgY3VycmVudCBsb2cgbGV2ZWwgaXMgaGlnaFxuICogZW5vdWdoIHRvIHBlcm1pdCBlcnJvciBtZXNzYWdlcy5cbiAqL1xucHJvdG90eXBlLmVycm9yID0gbG9nTWV0aG9kKCdlcnJvcicpO1xuXG4vKipcbiAqIExvZ3MgYSB3YXJuaW5nIG1lc3NhZ2UuIEJ5IGRlZmF1bHQsIGxvZ2dlZCBtZXNzYWdlcyBhcmUgd3JpdHRlbiB0byBjb25zb2xlXG4gKiBvdXRwdXQuIFRoZSBtZXNzYWdlIHdpbGwgb25seSBiZSBsb2dnZWQgaWYgdGhlIGN1cnJlbnQgbG9nIGxldmVsIGlzIGhpZ2hcbiAqIGVub3VnaCB0byBwZXJtaXQgd2FybmluZyBtZXNzYWdlcy5cbiAqL1xucHJvdG90eXBlLndhcm4gPSBsb2dNZXRob2QoJ3dhcm4nKTtcblxuLyoqXG4gKiBMb2dzIGEgaW5mb3JtYXRpb24gbWVzc2FnZS4gQnkgZGVmYXVsdCwgbG9nZ2VkIG1lc3NhZ2VzIGFyZSB3cml0dGVuIHRvXG4gKiBjb25zb2xlIG91dHB1dC4gVGhlIG1lc3NhZ2Ugd2lsbCBvbmx5IGJlIGxvZ2dlZCBpZiB0aGUgY3VycmVudCBsb2cgbGV2ZWwgaXNcbiAqIGhpZ2ggZW5vdWdoIHRvIHBlcm1pdCBpbmZvcm1hdGlvbiBtZXNzYWdlcy5cbiAqL1xucHJvdG90eXBlLmluZm8gPSBsb2dNZXRob2QoJ2luZm8nKTtcblxuLyoqXG4gKiBMb2dzIGEgZGVidWcgbWVzc2FnZS4gQnkgZGVmYXVsdCwgbG9nZ2VkIG1lc3NhZ2VzIGFyZSB3cml0dGVuIHRvIGNvbnNvbGVcbiAqIG91dHB1dC4gVGhlIG1lc3NhZ2Ugd2lsbCBvbmx5IGJlIGxvZ2dlZCBpZiB0aGUgY3VycmVudCBsb2cgbGV2ZWwgaXMgaGlnaFxuICogZW5vdWdoIHRvIHBlcm1pdCBkZWJ1ZyBtZXNzYWdlcy5cbiAqL1xucHJvdG90eXBlLmRlYnVnID0gbG9nTWV0aG9kKCdkZWJ1ZycpO1xuXG4vKipcbiAqIEdldCBvciBzZXQgdGhlIGN1cnJlbnQgbG9nIGxldmVsLiBJZiBhbiBhcmd1bWVudCBpcyBwcm92aWRlZCwgaXRcbiAqIHdpbGwgYmUgdXNlZCBhcyB0aGUgbmV3IGxvZyBsZXZlbC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbbGV2ZWxdIC0gU2hvdWxkIGJlIG9uZSBvZiBOb25lLCBXYXJuLCBJbmZvXG4gKiBAcmV0dXJuIHtudW1iZXJ9IC0gVGhlIGN1cnJlbnQgbG9nIGxldmVsLlxuICovXG5wcm90b3R5cGUubG9nTGV2ZWwgPSBsb2dNZXRob2QoJ2xldmVsJyk7XG5cbi8qKlxuICogQWJzdHJhY3QgY2xhc3MgZm9yIG9wZXJhdG9ycyB0aGF0IHByb2Nlc3MgZGF0YSB0dXBsZXMuXG4gKiBTdWJjbGFzc2VzIG11c3QgcHJvdmlkZSBhIHtAbGluayB0cmFuc2Zvcm19IG1ldGhvZCBmb3Igb3BlcmF0b3IgcHJvY2Vzc2luZy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHsqfSBbaW5pdF0gLSBUaGUgaW5pdGlhbCB2YWx1ZSBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbcGFyYW1zXSAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtPcGVyYXRvcn0gW3NvdXJjZV0gLSBUaGUgb3BlcmF0b3IgZnJvbSB3aGljaCB0byByZWNlaXZlIHB1bHNlcy5cbiAqL1xuZnVuY3Rpb24gVHJhbnNmb3JtKGluaXQsIHBhcmFtcykge1xuICBPcGVyYXRvci5jYWxsKHRoaXMsIGluaXQsIG51bGwsIHBhcmFtcyk7XG59XG5cbnZhciBwcm90b3R5cGUkNyA9IGluaGVyaXRzKFRyYW5zZm9ybSwgT3BlcmF0b3IpO1xuXG4vKipcbiAqIE92ZXJyaWRlcyB7QGxpbmsgT3BlcmF0b3IuZXZhbHVhdGV9IGZvciB0cmFuc2Zvcm0gb3BlcmF0b3JzLlxuICogSW50ZXJuYWxseSwgdGhpcyBtZXRob2QgY2FsbHMge0BsaW5rIGV2YWx1YXRlfSB0byBwZXJmb3JtIHByb2Nlc3NpbmcuXG4gKiBJZiB7QGxpbmsgZXZhbHVhdGV9IHJldHVybnMgYSBmYWxzeSB2YWx1ZSwgdGhlIGlucHV0IHB1bHNlIGlzIHJldHVybmVkLlxuICogVGhpcyBtZXRob2Qgc2hvdWxkIE5PVCBiZSBvdmVycmlkZGVuLCBpbnN0ZWFkIG92ZXJycmlkZSB7QGxpbmsgZXZhbHVhdGV9LlxuICogQHBhcmFtIHtQdWxzZX0gcHVsc2UgLSB0aGUgY3VycmVudCBkYXRhZmxvdyBwdWxzZS5cbiAqIEByZXR1cm4gdGhlIG91dHB1dCBwdWxzZSBmb3IgdGhpcyBvcGVyYXRvciAob3IgU3RvcFByb3BhZ2F0aW9uKVxuICovXG5wcm90b3R5cGUkNy5ydW4gPSBmdW5jdGlvbihwdWxzZSkge1xuICBpZiAocHVsc2Uuc3RhbXAgPD0gdGhpcy5zdGFtcCkgcmV0dXJuIHB1bHNlLlN0b3BQcm9wYWdhdGlvbjtcblxuICB2YXIgcnY7XG4gIGlmICh0aGlzLnNraXAoKSkge1xuICAgIHRoaXMuc2tpcChmYWxzZSk7XG4gIH0gZWxzZSB7XG4gICAgcnYgPSB0aGlzLmV2YWx1YXRlKHB1bHNlKTtcbiAgfVxuICBydiA9IHJ2IHx8IHB1bHNlO1xuXG4gIGlmIChydiAhPT0gcHVsc2UuU3RvcFByb3BhZ2F0aW9uKSB0aGlzLnB1bHNlID0gcnY7XG4gIHRoaXMuc3RhbXAgPSBwdWxzZS5zdGFtcDtcblxuICByZXR1cm4gcnY7XG59O1xuXG4vKipcbiAqIE92ZXJyaWRlcyB7QGxpbmsgT3BlcmF0b3IuZXZhbHVhdGV9IGZvciB0cmFuc2Zvcm0gb3BlcmF0b3JzLlxuICogTWFyc2hhbGxzIHBhcmFtZXRlciB2YWx1ZXMgYW5kIHRoZW4gaW52b2tlcyB7QGxpbmsgdHJhbnNmb3JtfS5cbiAqIEBwYXJhbSB7UHVsc2V9IHB1bHNlIC0gdGhlIGN1cnJlbnQgZGF0YWZsb3cgcHVsc2UuXG4gKiBAcmV0dXJuIHtQdWxzZX0gVGhlIG91dHB1dCBwdWxzZSAob3IgU3RvcFByb3BhZ2F0aW9uKS4gQSBmYWxzeSByZXR1cm5cbiAgICAgdmFsdWUgKGluY2x1ZGluZyB1bmRlZmluZWQpIHdpbGwgbGV0IHRoZSBpbnB1dCBwdWxzZSBwYXNzIHRocm91Z2guXG4gKi9cbnByb3RvdHlwZSQ3LmV2YWx1YXRlID0gZnVuY3Rpb24ocHVsc2UpIHtcbiAgdmFyIHBhcmFtcyA9IHRoaXMubWFyc2hhbGwocHVsc2Uuc3RhbXApLFxuICAgICAgb3V0ID0gdGhpcy50cmFuc2Zvcm0ocGFyYW1zLCBwdWxzZSk7XG4gIHBhcmFtcy5jbGVhcigpO1xuICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBQcm9jZXNzIGluY29taW5nIHB1bHNlcy5cbiAqIFN1YmNsYXNzZXMgc2hvdWxkIG92ZXJyaWRlIHRoaXMgbWV0aG9kIHRvIGltcGxlbWVudCB0cmFuc2Zvcm1zLlxuICogQHBhcmFtIHtQYXJhbWV0ZXJzfSBfIC0gVGhlIG9wZXJhdG9yIHBhcmFtZXRlciB2YWx1ZXMuXG4gKiBAcGFyYW0ge1B1bHNlfSBwdWxzZSAtIFRoZSBjdXJyZW50IGRhdGFmbG93IHB1bHNlLlxuICogQHJldHVybiB7UHVsc2V9IFRoZSBvdXRwdXQgcHVsc2UgKG9yIFN0b3BQcm9wYWdhdGlvbikuIEEgZmFsc3kgcmV0dXJuXG4gKiAgIHZhbHVlIChpbmNsdWRpbmcgdW5kZWZpbmVkKSB3aWxsIGxldCB0aGUgaW5wdXQgcHVsc2UgcGFzcyB0aHJvdWdoLlxuICovXG5wcm90b3R5cGUkNy50cmFuc2Zvcm0gPSBmdW5jdGlvbigpIHt9O1xuXG52YXIgdHJhbnNmb3JtcyA9IHt9O1xuXG5mdW5jdGlvbiBkZWZpbml0aW9uKHR5cGUpIHtcbiAgdmFyIHQgPSB0cmFuc2Zvcm0kMSh0eXBlKTtcbiAgcmV0dXJuIHQgJiYgdC5EZWZpbml0aW9uIHx8IG51bGw7XG59XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybSQxKHR5cGUpIHtcbiAgdHlwZSA9IHR5cGUgJiYgdHlwZS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gdHJhbnNmb3Jtcy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSA/IHRyYW5zZm9ybXNbdHlwZV0gOiBudWxsO1xufVxuXG4vLyBVdGlsaXRpZXNcblxuZnVuY3Rpb24gbXVsdGlrZXkoZikge1xuICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgIHZhciBuID0gZi5sZW5ndGgsXG4gICAgICAgIGkgPSAxLFxuICAgICAgICBrID0gU3RyaW5nKGZbMF0oeCkpO1xuXG4gICAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgICBrICs9ICd8JyArIGZbaV0oeCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIGs7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGdyb3Vwa2V5KGZpZWxkcykge1xuICByZXR1cm4gIWZpZWxkcyB8fCAhZmllbGRzLmxlbmd0aCA/IGZ1bmN0aW9uKCkgeyByZXR1cm4gJyc7IH1cbiAgICA6IGZpZWxkcy5sZW5ndGggPT09IDEgPyBmaWVsZHNbMF1cbiAgICA6IG11bHRpa2V5KGZpZWxkcyk7XG59XG5cbmZ1bmN0aW9uIG1lYXN1cmVOYW1lKG9wLCBmaWVsZCQkMSwgYXMpIHtcbiAgcmV0dXJuIGFzIHx8IChvcCArICghZmllbGQkJDEgPyAnJyA6ICdfJyArIGZpZWxkJCQxKSk7XG59XG5cbnZhciBBZ2dyZWdhdGVPcHMgPSB7XG4gICd2YWx1ZXMnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAndmFsdWVzJyxcbiAgICBpbml0OiAnY2VsbC5zdG9yZSA9IHRydWU7JyxcbiAgICBzZXQ6ICAnY2VsbC5kYXRhLnZhbHVlcygpJywgaWR4OiAtMVxuICB9KSxcbiAgJ2NvdW50JzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ2NvdW50JyxcbiAgICBzZXQ6ICAnY2VsbC5udW0nXG4gIH0pLFxuICAnX19jb3VudF9fJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ2NvdW50JyxcbiAgICBzZXQ6ICAndGhpcy5taXNzaW5nICsgdGhpcy52YWxpZCdcbiAgfSksXG4gICdtaXNzaW5nJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ21pc3NpbmcnLFxuICAgIHNldDogICd0aGlzLm1pc3NpbmcnXG4gIH0pLFxuICAndmFsaWQnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAndmFsaWQnLFxuICAgIHNldDogICd0aGlzLnZhbGlkJ1xuICB9KSxcbiAgJ3N1bSc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdzdW0nLFxuICAgIGluaXQ6ICd0aGlzLnN1bSA9IDA7JyxcbiAgICBhZGQ6ICAndGhpcy5zdW0gKz0gdjsnLFxuICAgIHJlbTogICd0aGlzLnN1bSAtPSB2OycsXG4gICAgc2V0OiAgJ3RoaXMuc3VtJ1xuICB9KSxcbiAgJ21lYW4nOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnbWVhbicsXG4gICAgaW5pdDogJ3RoaXMubWVhbiA9IDA7JyxcbiAgICBhZGQ6ICAndmFyIGQgPSB2IC0gdGhpcy5tZWFuOyB0aGlzLm1lYW4gKz0gZCAvIHRoaXMudmFsaWQ7JyxcbiAgICByZW06ICAndmFyIGQgPSB2IC0gdGhpcy5tZWFuOyB0aGlzLm1lYW4gLT0gdGhpcy52YWxpZCA/IGQgLyB0aGlzLnZhbGlkIDogdGhpcy5tZWFuOycsXG4gICAgc2V0OiAgJ3RoaXMubWVhbidcbiAgfSksXG4gICdhdmVyYWdlJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ2F2ZXJhZ2UnLFxuICAgIHNldDogICd0aGlzLm1lYW4nLFxuICAgIHJlcTogIFsnbWVhbiddLCBpZHg6IDFcbiAgfSksXG4gICd2YXJpYW5jZSc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICd2YXJpYW5jZScsXG4gICAgaW5pdDogJ3RoaXMuZGV2ID0gMDsnLFxuICAgIGFkZDogICd0aGlzLmRldiArPSBkICogKHYgLSB0aGlzLm1lYW4pOycsXG4gICAgcmVtOiAgJ3RoaXMuZGV2IC09IGQgKiAodiAtIHRoaXMubWVhbik7JyxcbiAgICBzZXQ6ICAndGhpcy52YWxpZCA+IDEgPyB0aGlzLmRldiAvICh0aGlzLnZhbGlkLTEpIDogMCcsXG4gICAgcmVxOiAgWydtZWFuJ10sIGlkeDogMVxuICB9KSxcbiAgJ3ZhcmlhbmNlcCc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICd2YXJpYW5jZXAnLFxuICAgIHNldDogICd0aGlzLnZhbGlkID4gMSA/IHRoaXMuZGV2IC8gdGhpcy52YWxpZCA6IDAnLFxuICAgIHJlcTogIFsndmFyaWFuY2UnXSwgaWR4OiAyXG4gIH0pLFxuICAnc3RkZXYnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnc3RkZXYnLFxuICAgIHNldDogICd0aGlzLnZhbGlkID4gMSA/IE1hdGguc3FydCh0aGlzLmRldiAvICh0aGlzLnZhbGlkLTEpKSA6IDAnLFxuICAgIHJlcTogIFsndmFyaWFuY2UnXSwgaWR4OiAyXG4gIH0pLFxuICAnc3RkZXZwJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ3N0ZGV2cCcsXG4gICAgc2V0OiAgJ3RoaXMudmFsaWQgPiAxID8gTWF0aC5zcXJ0KHRoaXMuZGV2IC8gdGhpcy52YWxpZCkgOiAwJyxcbiAgICByZXE6ICBbJ3ZhcmlhbmNlJ10sIGlkeDogMlxuICB9KSxcbiAgJ3N0ZGVycic6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdzdGRlcnInLFxuICAgIHNldDogICd0aGlzLnZhbGlkID4gMSA/IE1hdGguc3FydCh0aGlzLmRldiAvICh0aGlzLnZhbGlkICogKHRoaXMudmFsaWQtMSkpKSA6IDAnLFxuICAgIHJlcTogIFsndmFyaWFuY2UnXSwgaWR4OiAyXG4gIH0pLFxuICAnZGlzdGluY3QnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnZGlzdGluY3QnLFxuICAgIHNldDogICdjZWxsLmRhdGEuZGlzdGluY3QodGhpcy5nZXQpJyxcbiAgICByZXE6ICBbJ3ZhbHVlcyddLCBpZHg6IDNcbiAgfSksXG4gICdjaTAnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnY2kwJyxcbiAgICBzZXQ6ICAnY2VsbC5kYXRhLmNpMCh0aGlzLmdldCknLFxuICAgIHJlcTogIFsndmFsdWVzJ10sIGlkeDogM1xuICB9KSxcbiAgJ2NpMSc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdjaTEnLFxuICAgIHNldDogICdjZWxsLmRhdGEuY2kxKHRoaXMuZ2V0KScsXG4gICAgcmVxOiAgWyd2YWx1ZXMnXSwgaWR4OiAzXG4gIH0pLFxuICAnbWVkaWFuJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ21lZGlhbicsXG4gICAgc2V0OiAgJ2NlbGwuZGF0YS5xMih0aGlzLmdldCknLFxuICAgIHJlcTogIFsndmFsdWVzJ10sIGlkeDogM1xuICB9KSxcbiAgJ3ExJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ3ExJyxcbiAgICBzZXQ6ICAnY2VsbC5kYXRhLnExKHRoaXMuZ2V0KScsXG4gICAgcmVxOiAgWyd2YWx1ZXMnXSwgaWR4OiAzXG4gIH0pLFxuICAncTMnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAncTMnLFxuICAgIHNldDogICdjZWxsLmRhdGEucTModGhpcy5nZXQpJyxcbiAgICByZXE6ICBbJ3ZhbHVlcyddLCBpZHg6IDNcbiAgfSksXG4gICdhcmdtaW4nOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnYXJnbWluJyxcbiAgICBpbml0OiAndGhpcy5hcmdtaW4gPSBudWxsOycsXG4gICAgYWRkOiAgJ2lmICh2IDwgdGhpcy5taW4pIHRoaXMuYXJnbWluID0gdDsnLFxuICAgIHJlbTogICdpZiAodiA8PSB0aGlzLm1pbikgdGhpcy5hcmdtaW4gPSBudWxsOycsXG4gICAgc2V0OiAgJ3RoaXMuYXJnbWluIHx8IGNlbGwuZGF0YS5hcmdtaW4odGhpcy5nZXQpJyxcbiAgICByZXE6ICBbJ21pbiddLCBzdHI6IFsndmFsdWVzJ10sIGlkeDogM1xuICB9KSxcbiAgJ2FyZ21heCc6IG1lYXN1cmUoe1xuICAgIG5hbWU6ICdhcmdtYXgnLFxuICAgIGluaXQ6ICd0aGlzLmFyZ21heCA9IG51bGw7JyxcbiAgICBhZGQ6ICAnaWYgKHYgPiB0aGlzLm1heCkgdGhpcy5hcmdtYXggPSB0OycsXG4gICAgcmVtOiAgJ2lmICh2ID49IHRoaXMubWF4KSB0aGlzLmFyZ21heCA9IG51bGw7JyxcbiAgICBzZXQ6ICAndGhpcy5hcmdtYXggfHwgY2VsbC5kYXRhLmFyZ21heCh0aGlzLmdldCknLFxuICAgIHJlcTogIFsnbWF4J10sIHN0cjogWyd2YWx1ZXMnXSwgaWR4OiAzXG4gIH0pLFxuICAnbWluJzogbWVhc3VyZSh7XG4gICAgbmFtZTogJ21pbicsXG4gICAgaW5pdDogJ3RoaXMubWluID0gbnVsbDsnLFxuICAgIGFkZDogICdpZiAodiA8IHRoaXMubWluIHx8IHRoaXMubWluID09PSBudWxsKSB0aGlzLm1pbiA9IHY7JyxcbiAgICByZW06ICAnaWYgKHYgPD0gdGhpcy5taW4pIHRoaXMubWluID0gTmFOOycsXG4gICAgc2V0OiAgJ3RoaXMubWluID0gKGlzTmFOKHRoaXMubWluKSA/IGNlbGwuZGF0YS5taW4odGhpcy5nZXQpIDogdGhpcy5taW4pJyxcbiAgICBzdHI6ICBbJ3ZhbHVlcyddLCBpZHg6IDRcbiAgfSksXG4gICdtYXgnOiBtZWFzdXJlKHtcbiAgICBuYW1lOiAnbWF4JyxcbiAgICBpbml0OiAndGhpcy5tYXggPSBudWxsOycsXG4gICAgYWRkOiAgJ2lmICh2ID4gdGhpcy5tYXggfHwgdGhpcy5tYXggPT09IG51bGwpIHRoaXMubWF4ID0gdjsnLFxuICAgIHJlbTogICdpZiAodiA+PSB0aGlzLm1heCkgdGhpcy5tYXggPSBOYU47JyxcbiAgICBzZXQ6ICAndGhpcy5tYXggPSAoaXNOYU4odGhpcy5tYXgpID8gY2VsbC5kYXRhLm1heCh0aGlzLmdldCkgOiB0aGlzLm1heCknLFxuICAgIHN0cjogIFsndmFsdWVzJ10sIGlkeDogNFxuICB9KVxufTtcblxudmFyIFZhbGlkQWdncmVnYXRlT3BzID0gT2JqZWN0LmtleXMoQWdncmVnYXRlT3BzKTtcblxuZnVuY3Rpb24gY3JlYXRlTWVhc3VyZShvcCwgbmFtZSkge1xuICByZXR1cm4gQWdncmVnYXRlT3BzW29wXShuYW1lKTtcbn1cblxuZnVuY3Rpb24gbWVhc3VyZShiYXNlKSB7XG4gIHJldHVybiBmdW5jdGlvbihvdXQpIHtcbiAgICB2YXIgbSA9IGV4dGVuZCh7aW5pdDonJywgYWRkOicnLCByZW06JycsIGlkeDowfSwgYmFzZSk7XG4gICAgbS5vdXQgPSBvdXQgfHwgYmFzZS5uYW1lO1xuICAgIHJldHVybiBtO1xuICB9O1xufVxuXG5mdW5jdGlvbiBjb21wYXJlSW5kZXgoYSwgYikge1xuICByZXR1cm4gYS5pZHggLSBiLmlkeDtcbn1cblxuZnVuY3Rpb24gcmVzb2x2ZShhZ2csIHN0cmVhbSkge1xuICBmdW5jdGlvbiBjb2xsZWN0KG0sIGEpIHtcbiAgICBmdW5jdGlvbiBoZWxwZXIocikgeyBpZiAoIW1bcl0pIGNvbGxlY3QobSwgbVtyXSA9IEFnZ3JlZ2F0ZU9wc1tyXSgpKTsgfVxuICAgIGlmIChhLnJlcSkgYS5yZXEuZm9yRWFjaChoZWxwZXIpO1xuICAgIGlmIChzdHJlYW0gJiYgYS5zdHIpIGEuc3RyLmZvckVhY2goaGVscGVyKTtcbiAgICByZXR1cm4gbTtcbiAgfVxuICB2YXIgbWFwID0gYWdnLnJlZHVjZShcbiAgICBjb2xsZWN0LFxuICAgIGFnZy5yZWR1Y2UoZnVuY3Rpb24obSwgYSkge1xuICAgICAgbVthLm5hbWVdID0gYTtcbiAgICAgIHJldHVybiBtO1xuICAgIH0sIHt9KVxuICApO1xuICB2YXIgdmFsdWVzID0gW10sIGtleSQkMTtcbiAgZm9yIChrZXkkJDEgaW4gbWFwKSB2YWx1ZXMucHVzaChtYXBba2V5JCQxXSk7XG4gIHJldHVybiB2YWx1ZXMuc29ydChjb21wYXJlSW5kZXgpO1xufVxuXG5mdW5jdGlvbiBjb21waWxlTWVhc3VyZXMoYWdnLCBmaWVsZCQkMSkge1xuICB2YXIgZ2V0ID0gZmllbGQkJDEgfHwgaWRlbnRpdHksXG4gICAgICBhbGwgPSByZXNvbHZlKGFnZywgdHJ1ZSksIC8vIGFzc3VtZSBzdHJlYW1pbmcgcmVtb3ZlcyBtYXkgb2NjdXJcbiAgICAgIGluaXQgPSAndmFyIGNlbGwgPSB0aGlzLmNlbGw7IHRoaXMudmFsaWQgPSAwOyB0aGlzLm1pc3NpbmcgPSAwOycsXG4gICAgICBjdHIgPSAndGhpcy5jZWxsID0gY2VsbDsgdGhpcy5pbml0KCk7JyxcbiAgICAgIGFkZCA9ICdpZih2PT1udWxsKXsrK3RoaXMubWlzc2luZzsgcmV0dXJuO30gaWYodiE9PXYpIHJldHVybjsgKyt0aGlzLnZhbGlkOycsXG4gICAgICByZW0gPSAnaWYodj09bnVsbCl7LS10aGlzLm1pc3Npbmc7IHJldHVybjt9IGlmKHYhPT12KSByZXR1cm47IC0tdGhpcy52YWxpZDsnLFxuICAgICAgc2V0ID0gJ3ZhciBjZWxsID0gdGhpcy5jZWxsOyc7XG5cbiAgYWxsLmZvckVhY2goZnVuY3Rpb24oYSkge1xuICAgIGluaXQgKz0gYS5pbml0O1xuICAgIGFkZCArPSBhLmFkZDtcbiAgICByZW0gKz0gYS5yZW07XG4gIH0pO1xuICBhZ2cuc2xpY2UoKS5zb3J0KGNvbXBhcmVJbmRleCkuZm9yRWFjaChmdW5jdGlvbihhKSB7XG4gICAgc2V0ICs9ICd0W1xcJycgKyBhLm91dCArICdcXCddPScgKyBhLnNldCArICc7JztcbiAgfSk7XG4gIHNldCArPSAncmV0dXJuIHQ7JztcblxuICBjdHIgPSBGdW5jdGlvbignY2VsbCcsIGN0cik7XG4gIGN0ci5wcm90b3R5cGUuaW5pdCA9IEZ1bmN0aW9uKGluaXQpO1xuICBjdHIucHJvdG90eXBlLmFkZCA9IEZ1bmN0aW9uKCd2JywgJ3QnLCBhZGQpO1xuICBjdHIucHJvdG90eXBlLnJlbSA9IEZ1bmN0aW9uKCd2JywgJ3QnLCByZW0pO1xuICBjdHIucHJvdG90eXBlLnNldCA9IEZ1bmN0aW9uKCd0Jywgc2V0KTtcbiAgY3RyLnByb3RvdHlwZS5nZXQgPSBnZXQ7XG4gIGN0ci5maWVsZHMgPSBhZ2cubWFwKGZ1bmN0aW9uKF8pIHsgcmV0dXJuIF8ub3V0OyB9KTtcbiAgcmV0dXJuIGN0cjtcbn1cblxudmFyIGJpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgLy8gZGV0ZXJtaW5lIHJhbmdlXG4gIHZhciBtYXhiID0gXy5tYXhiaW5zIHx8IDIwLFxuICAgICAgYmFzZSA9IF8uYmFzZSB8fCAxMCxcbiAgICAgIGxvZ2IgPSBNYXRoLmxvZyhiYXNlKSxcbiAgICAgIGRpdiAgPSBfLmRpdmlkZSB8fCBbNSwgMl0sXG4gICAgICBtaW4gID0gXy5leHRlbnRbMF0sXG4gICAgICBtYXggID0gXy5leHRlbnRbMV0sXG4gICAgICBzcGFuID0gbWF4IC0gbWluLFxuICAgICAgc3RlcCwgbGV2ZWwsIG1pbnN0ZXAsIHByZWNpc2lvbiwgdiwgaSwgbiwgZXBzO1xuXG4gIGlmIChfLnN0ZXApIHtcbiAgICAvLyBpZiBzdGVwIHNpemUgaXMgZXhwbGljaXRseSBnaXZlbiwgdXNlIHRoYXRcbiAgICBzdGVwID0gXy5zdGVwO1xuICB9IGVsc2UgaWYgKF8uc3RlcHMpIHtcbiAgICAvLyBpZiBwcm92aWRlZCwgbGltaXQgY2hvaWNlIHRvIGFjY2VwdGFibGUgc3RlcCBzaXplc1xuICAgIHYgPSBzcGFuIC8gbWF4YjtcbiAgICBmb3IgKGk9MCwgbj1fLnN0ZXBzLmxlbmd0aDsgaSA8IG4gJiYgXy5zdGVwc1tpXSA8IHY7ICsraSk7XG4gICAgc3RlcCA9IF8uc3RlcHNbTWF0aC5tYXgoMCwgaS0xKV07XG4gIH0gZWxzZSB7XG4gICAgLy8gZWxzZSB1c2Ugc3BhbiB0byBkZXRlcm1pbmUgc3RlcCBzaXplXG4gICAgbGV2ZWwgPSBNYXRoLmNlaWwoTWF0aC5sb2cobWF4YikgLyBsb2diKTtcbiAgICBtaW5zdGVwID0gXy5taW5zdGVwIHx8IDA7XG4gICAgc3RlcCA9IE1hdGgubWF4KFxuICAgICAgbWluc3RlcCxcbiAgICAgIE1hdGgucG93KGJhc2UsIE1hdGgucm91bmQoTWF0aC5sb2coc3BhbikgLyBsb2diKSAtIGxldmVsKVxuICAgICk7XG5cbiAgICAvLyBpbmNyZWFzZSBzdGVwIHNpemUgaWYgdG9vIG1hbnkgYmluc1xuICAgIHdoaWxlIChNYXRoLmNlaWwoc3Bhbi9zdGVwKSA+IG1heGIpIHsgc3RlcCAqPSBiYXNlOyB9XG5cbiAgICAvLyBkZWNyZWFzZSBzdGVwIHNpemUgaWYgYWxsb3dlZFxuICAgIGZvciAoaT0wLCBuPWRpdi5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgICB2ID0gc3RlcCAvIGRpdltpXTtcbiAgICAgIGlmICh2ID49IG1pbnN0ZXAgJiYgc3BhbiAvIHYgPD0gbWF4Yikgc3RlcCA9IHY7XG4gICAgfVxuICB9XG5cbiAgLy8gdXBkYXRlIHByZWNpc2lvbiwgbWluIGFuZCBtYXhcbiAgdiA9IE1hdGgubG9nKHN0ZXApO1xuICBwcmVjaXNpb24gPSB2ID49IDAgPyAwIDogfn4oLXYgLyBsb2diKSArIDE7XG4gIGVwcyA9IE1hdGgucG93KGJhc2UsIC1wcmVjaXNpb24gLSAxKTtcbiAgaWYgKF8ubmljZSB8fCBfLm5pY2UgPT09IHVuZGVmaW5lZCkge1xuICAgIHYgPSBNYXRoLmZsb29yKG1pbiAvIHN0ZXAgKyBlcHMpICogc3RlcDtcbiAgICBtaW4gPSBtaW4gPCB2ID8gdiAtIHN0ZXAgOiB2O1xuICAgIG1heCA9IE1hdGguY2VpbChtYXggLyBzdGVwKSAqIHN0ZXA7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHN0YXJ0OiBtaW4sXG4gICAgc3RvcDogIG1heCxcbiAgICBzdGVwOiAgc3RlcFxuICB9O1xufTtcblxudmFyIG51bWJlcnMgPSBmdW5jdGlvbihhcnJheSwgZikge1xuICB2YXIgbnVtYmVycyA9IFtdLFxuICAgICAgbiA9IGFycmF5Lmxlbmd0aCxcbiAgICAgIGkgPSAtMSwgYTtcblxuICBpZiAoZiA9PSBudWxsKSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghaXNOYU4oYSA9IG51bWJlcihhcnJheVtpXSkpKSBudW1iZXJzLnB1c2goYSk7XG4gIH0gZWxzZSB7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghaXNOYU4oYSA9IG51bWJlcihmKGFycmF5W2ldLCBpLCBhcnJheSkpKSkgbnVtYmVycy5wdXNoKGEpO1xuICB9XG4gIHJldHVybiBudW1iZXJzO1xufTtcblxuZnVuY3Rpb24gbnVtYmVyKHgpIHtcbiAgcmV0dXJuIHggPT09IG51bGwgPyBOYU4gOiAreDtcbn1cblxuZXhwb3J0cy5yYW5kb20gPSBNYXRoLnJhbmRvbTtcblxuZnVuY3Rpb24gc2V0UmFuZG9tKHIpIHtcbiAgZXhwb3J0cy5yYW5kb20gPSByO1xufVxuXG52YXIgYXNjZW5kaW5nID0gZnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYSA8IGIgPyAtMSA6IGEgPiBiID8gMSA6IGEgPj0gYiA/IDAgOiBOYU47XG59O1xuXG52YXIgYmlzZWN0b3IgPSBmdW5jdGlvbihjb21wYXJlKSB7XG4gIGlmIChjb21wYXJlLmxlbmd0aCA9PT0gMSkgY29tcGFyZSA9IGFzY2VuZGluZ0NvbXBhcmF0b3IoY29tcGFyZSk7XG4gIHJldHVybiB7XG4gICAgbGVmdDogZnVuY3Rpb24oYSwgeCwgbG8sIGhpKSB7XG4gICAgICBpZiAobG8gPT0gbnVsbCkgbG8gPSAwO1xuICAgICAgaWYgKGhpID09IG51bGwpIGhpID0gYS5sZW5ndGg7XG4gICAgICB3aGlsZSAobG8gPCBoaSkge1xuICAgICAgICB2YXIgbWlkID0gbG8gKyBoaSA+Pj4gMTtcbiAgICAgICAgaWYgKGNvbXBhcmUoYVttaWRdLCB4KSA8IDApIGxvID0gbWlkICsgMTtcbiAgICAgICAgZWxzZSBoaSA9IG1pZDtcbiAgICAgIH1cbiAgICAgIHJldHVybiBsbztcbiAgICB9LFxuICAgIHJpZ2h0OiBmdW5jdGlvbihhLCB4LCBsbywgaGkpIHtcbiAgICAgIGlmIChsbyA9PSBudWxsKSBsbyA9IDA7XG4gICAgICBpZiAoaGkgPT0gbnVsbCkgaGkgPSBhLmxlbmd0aDtcbiAgICAgIHdoaWxlIChsbyA8IGhpKSB7XG4gICAgICAgIHZhciBtaWQgPSBsbyArIGhpID4+PiAxO1xuICAgICAgICBpZiAoY29tcGFyZShhW21pZF0sIHgpID4gMCkgaGkgPSBtaWQ7XG4gICAgICAgIGVsc2UgbG8gPSBtaWQgKyAxO1xuICAgICAgfVxuICAgICAgcmV0dXJuIGxvO1xuICAgIH1cbiAgfTtcbn07XG5cbmZ1bmN0aW9uIGFzY2VuZGluZ0NvbXBhcmF0b3IoZikge1xuICByZXR1cm4gZnVuY3Rpb24oZCwgeCkge1xuICAgIHJldHVybiBhc2NlbmRpbmcoZihkKSwgeCk7XG4gIH07XG59XG5cbnZhciBhc2NlbmRpbmdCaXNlY3QgPSBiaXNlY3Rvcihhc2NlbmRpbmcpO1xudmFyIGJpc2VjdFJpZ2h0ID0gYXNjZW5kaW5nQmlzZWN0LnJpZ2h0O1xudmFyIGJpc2VjdExlZnQgPSBhc2NlbmRpbmdCaXNlY3QubGVmdDtcblxuZnVuY3Rpb24gcGFpcihhLCBiKSB7XG4gIHJldHVybiBbYSwgYl07XG59XG5cbnZhciBudW1iZXIkMSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIHggPT09IG51bGwgPyBOYU4gOiAreDtcbn07XG5cbnZhciB2YXJpYW5jZSA9IGZ1bmN0aW9uKHZhbHVlcywgdmFsdWVvZikge1xuICB2YXIgbiA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICBtID0gMCxcbiAgICAgIGkgPSAtMSxcbiAgICAgIG1lYW4gPSAwLFxuICAgICAgdmFsdWUsXG4gICAgICBkZWx0YSxcbiAgICAgIHN1bSA9IDA7XG5cbiAgaWYgKHZhbHVlb2YgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAoIWlzTmFOKHZhbHVlID0gbnVtYmVyJDEodmFsdWVzW2ldKSkpIHtcbiAgICAgICAgZGVsdGEgPSB2YWx1ZSAtIG1lYW47XG4gICAgICAgIG1lYW4gKz0gZGVsdGEgLyArK207XG4gICAgICAgIHN1bSArPSBkZWx0YSAqICh2YWx1ZSAtIG1lYW4pO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAoIWlzTmFOKHZhbHVlID0gbnVtYmVyJDEodmFsdWVvZih2YWx1ZXNbaV0sIGksIHZhbHVlcykpKSkge1xuICAgICAgICBkZWx0YSA9IHZhbHVlIC0gbWVhbjtcbiAgICAgICAgbWVhbiArPSBkZWx0YSAvICsrbTtcbiAgICAgICAgc3VtICs9IGRlbHRhICogKHZhbHVlIC0gbWVhbik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKG0gPiAxKSByZXR1cm4gc3VtIC8gKG0gLSAxKTtcbn07XG5cbnZhciBleHRlbnQgPSBmdW5jdGlvbih2YWx1ZXMsIHZhbHVlb2YpIHtcbiAgdmFyIG4gPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgaSA9IC0xLFxuICAgICAgdmFsdWUsXG4gICAgICBtaW4sXG4gICAgICBtYXg7XG5cbiAgaWYgKHZhbHVlb2YgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7IC8vIEZpbmQgdGhlIGZpcnN0IGNvbXBhcmFibGUgdmFsdWUuXG4gICAgICBpZiAoKHZhbHVlID0gdmFsdWVzW2ldKSAhPSBudWxsICYmIHZhbHVlID49IHZhbHVlKSB7XG4gICAgICAgIG1pbiA9IG1heCA9IHZhbHVlO1xuICAgICAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBDb21wYXJlIHRoZSByZW1haW5pbmcgdmFsdWVzLlxuICAgICAgICAgIGlmICgodmFsdWUgPSB2YWx1ZXNbaV0pICE9IG51bGwpIHtcbiAgICAgICAgICAgIGlmIChtaW4gPiB2YWx1ZSkgbWluID0gdmFsdWU7XG4gICAgICAgICAgICBpZiAobWF4IDwgdmFsdWUpIG1heCA9IHZhbHVlO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7IC8vIEZpbmQgdGhlIGZpcnN0IGNvbXBhcmFibGUgdmFsdWUuXG4gICAgICBpZiAoKHZhbHVlID0gdmFsdWVvZih2YWx1ZXNbaV0sIGksIHZhbHVlcykpICE9IG51bGwgJiYgdmFsdWUgPj0gdmFsdWUpIHtcbiAgICAgICAgbWluID0gbWF4ID0gdmFsdWU7XG4gICAgICAgIHdoaWxlICgrK2kgPCBuKSB7IC8vIENvbXBhcmUgdGhlIHJlbWFpbmluZyB2YWx1ZXMuXG4gICAgICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSAhPSBudWxsKSB7XG4gICAgICAgICAgICBpZiAobWluID4gdmFsdWUpIG1pbiA9IHZhbHVlO1xuICAgICAgICAgICAgaWYgKG1heCA8IHZhbHVlKSBtYXggPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gW21pbiwgbWF4XTtcbn07XG5cbnZhciBpZGVudGl0eSQyID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4geDtcbn07XG5cbnZhciBzZXF1ZW5jZSA9IGZ1bmN0aW9uKHN0YXJ0LCBzdG9wLCBzdGVwKSB7XG4gIHN0YXJ0ID0gK3N0YXJ0LCBzdG9wID0gK3N0b3AsIHN0ZXAgPSAobiA9IGFyZ3VtZW50cy5sZW5ndGgpIDwgMiA/IChzdG9wID0gc3RhcnQsIHN0YXJ0ID0gMCwgMSkgOiBuIDwgMyA/IDEgOiArc3RlcDtcblxuICB2YXIgaSA9IC0xLFxuICAgICAgbiA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCgoc3RvcCAtIHN0YXJ0KSAvIHN0ZXApKSB8IDAsXG4gICAgICByYW5nZSA9IG5ldyBBcnJheShuKTtcblxuICB3aGlsZSAoKytpIDwgbikge1xuICAgIHJhbmdlW2ldID0gc3RhcnQgKyBpICogc3RlcDtcbiAgfVxuXG4gIHJldHVybiByYW5nZTtcbn07XG5cbnZhciBlMTAgPSBNYXRoLnNxcnQoNTApO1xudmFyIGU1ID0gTWF0aC5zcXJ0KDEwKTtcbnZhciBlMiQxID0gTWF0aC5zcXJ0KDIpO1xuXG52YXIgdGlja3MgPSBmdW5jdGlvbihzdGFydCwgc3RvcCwgY291bnQpIHtcbiAgdmFyIHJldmVyc2UsXG4gICAgICBpID0gLTEsXG4gICAgICBuLFxuICAgICAgdGlja3MsXG4gICAgICBzdGVwO1xuXG4gIHN0b3AgPSArc3RvcCwgc3RhcnQgPSArc3RhcnQsIGNvdW50ID0gK2NvdW50O1xuICBpZiAoc3RhcnQgPT09IHN0b3AgJiYgY291bnQgPiAwKSByZXR1cm4gW3N0YXJ0XTtcbiAgaWYgKHJldmVyc2UgPSBzdG9wIDwgc3RhcnQpIG4gPSBzdGFydCwgc3RhcnQgPSBzdG9wLCBzdG9wID0gbjtcbiAgaWYgKChzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpKSA9PT0gMCB8fCAhaXNGaW5pdGUoc3RlcCkpIHJldHVybiBbXTtcblxuICBpZiAoc3RlcCA+IDApIHtcbiAgICBzdGFydCA9IE1hdGguY2VpbChzdGFydCAvIHN0ZXApO1xuICAgIHN0b3AgPSBNYXRoLmZsb29yKHN0b3AgLyBzdGVwKTtcbiAgICB0aWNrcyA9IG5ldyBBcnJheShuID0gTWF0aC5jZWlsKHN0b3AgLSBzdGFydCArIDEpKTtcbiAgICB3aGlsZSAoKytpIDwgbikgdGlja3NbaV0gPSAoc3RhcnQgKyBpKSAqIHN0ZXA7XG4gIH0gZWxzZSB7XG4gICAgc3RhcnQgPSBNYXRoLmZsb29yKHN0YXJ0ICogc3RlcCk7XG4gICAgc3RvcCA9IE1hdGguY2VpbChzdG9wICogc3RlcCk7XG4gICAgdGlja3MgPSBuZXcgQXJyYXkobiA9IE1hdGguY2VpbChzdGFydCAtIHN0b3AgKyAxKSk7XG4gICAgd2hpbGUgKCsraSA8IG4pIHRpY2tzW2ldID0gKHN0YXJ0IC0gaSkgLyBzdGVwO1xuICB9XG5cbiAgaWYgKHJldmVyc2UpIHRpY2tzLnJldmVyc2UoKTtcblxuICByZXR1cm4gdGlja3M7XG59O1xuXG5mdW5jdGlvbiB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCkge1xuICB2YXIgc3RlcCA9IChzdG9wIC0gc3RhcnQpIC8gTWF0aC5tYXgoMCwgY291bnQpLFxuICAgICAgcG93ZXIgPSBNYXRoLmZsb29yKE1hdGgubG9nKHN0ZXApIC8gTWF0aC5MTjEwKSxcbiAgICAgIGVycm9yID0gc3RlcCAvIE1hdGgucG93KDEwLCBwb3dlcik7XG4gIHJldHVybiBwb3dlciA+PSAwXG4gICAgICA/IChlcnJvciA+PSBlMTAgPyAxMCA6IGVycm9yID49IGU1ID8gNSA6IGVycm9yID49IGUyJDEgPyAyIDogMSkgKiBNYXRoLnBvdygxMCwgcG93ZXIpXG4gICAgICA6IC1NYXRoLnBvdygxMCwgLXBvd2VyKSAvIChlcnJvciA+PSBlMTAgPyAxMCA6IGVycm9yID49IGU1ID8gNSA6IGVycm9yID49IGUyJDEgPyAyIDogMSk7XG59XG5cbmZ1bmN0aW9uIHRpY2tTdGVwKHN0YXJ0LCBzdG9wLCBjb3VudCkge1xuICB2YXIgc3RlcDAgPSBNYXRoLmFicyhzdG9wIC0gc3RhcnQpIC8gTWF0aC5tYXgoMCwgY291bnQpLFxuICAgICAgc3RlcDEgPSBNYXRoLnBvdygxMCwgTWF0aC5mbG9vcihNYXRoLmxvZyhzdGVwMCkgLyBNYXRoLkxOMTApKSxcbiAgICAgIGVycm9yID0gc3RlcDAgLyBzdGVwMTtcbiAgaWYgKGVycm9yID49IGUxMCkgc3RlcDEgKj0gMTA7XG4gIGVsc2UgaWYgKGVycm9yID49IGU1KSBzdGVwMSAqPSA1O1xuICBlbHNlIGlmIChlcnJvciA+PSBlMiQxKSBzdGVwMSAqPSAyO1xuICByZXR1cm4gc3RvcCA8IHN0YXJ0ID8gLXN0ZXAxIDogc3RlcDE7XG59XG5cbnZhciB0aHJlc2hvbGRTdHVyZ2VzID0gZnVuY3Rpb24odmFsdWVzKSB7XG4gIHJldHVybiBNYXRoLmNlaWwoTWF0aC5sb2codmFsdWVzLmxlbmd0aCkgLyBNYXRoLkxOMikgKyAxO1xufTtcblxudmFyIHRocmVzaG9sZCA9IGZ1bmN0aW9uKHZhbHVlcywgcCwgdmFsdWVvZikge1xuICBpZiAodmFsdWVvZiA9PSBudWxsKSB2YWx1ZW9mID0gbnVtYmVyJDE7XG4gIGlmICghKG4gPSB2YWx1ZXMubGVuZ3RoKSkgcmV0dXJuO1xuICBpZiAoKHAgPSArcCkgPD0gMCB8fCBuIDwgMikgcmV0dXJuICt2YWx1ZW9mKHZhbHVlc1swXSwgMCwgdmFsdWVzKTtcbiAgaWYgKHAgPj0gMSkgcmV0dXJuICt2YWx1ZW9mKHZhbHVlc1tuIC0gMV0sIG4gLSAxLCB2YWx1ZXMpO1xuICB2YXIgbixcbiAgICAgIGkgPSAobiAtIDEpICogcCxcbiAgICAgIGkwID0gTWF0aC5mbG9vcihpKSxcbiAgICAgIHZhbHVlMCA9ICt2YWx1ZW9mKHZhbHVlc1tpMF0sIGkwLCB2YWx1ZXMpLFxuICAgICAgdmFsdWUxID0gK3ZhbHVlb2YodmFsdWVzW2kwICsgMV0sIGkwICsgMSwgdmFsdWVzKTtcbiAgcmV0dXJuIHZhbHVlMCArICh2YWx1ZTEgLSB2YWx1ZTApICogKGkgLSBpMCk7XG59O1xuXG52YXIgbWF4ID0gZnVuY3Rpb24odmFsdWVzLCB2YWx1ZW9mKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgIGkgPSAtMSxcbiAgICAgIHZhbHVlLFxuICAgICAgbWF4O1xuXG4gIGlmICh2YWx1ZW9mID09IG51bGwpIHtcbiAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBGaW5kIHRoZSBmaXJzdCBjb21wYXJhYmxlIHZhbHVlLlxuICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlc1tpXSkgIT0gbnVsbCAmJiB2YWx1ZSA+PSB2YWx1ZSkge1xuICAgICAgICBtYXggPSB2YWx1ZTtcbiAgICAgICAgd2hpbGUgKCsraSA8IG4pIHsgLy8gQ29tcGFyZSB0aGUgcmVtYWluaW5nIHZhbHVlcy5cbiAgICAgICAgICBpZiAoKHZhbHVlID0gdmFsdWVzW2ldKSAhPSBudWxsICYmIHZhbHVlID4gbWF4KSB7XG4gICAgICAgICAgICBtYXggPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBGaW5kIHRoZSBmaXJzdCBjb21wYXJhYmxlIHZhbHVlLlxuICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSAhPSBudWxsICYmIHZhbHVlID49IHZhbHVlKSB7XG4gICAgICAgIG1heCA9IHZhbHVlO1xuICAgICAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBDb21wYXJlIHRoZSByZW1haW5pbmcgdmFsdWVzLlxuICAgICAgICAgIGlmICgodmFsdWUgPSB2YWx1ZW9mKHZhbHVlc1tpXSwgaSwgdmFsdWVzKSkgIT0gbnVsbCAmJiB2YWx1ZSA+IG1heCkge1xuICAgICAgICAgICAgbWF4ID0gdmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1heDtcbn07XG5cbnZhciBtZWFuID0gZnVuY3Rpb24odmFsdWVzLCB2YWx1ZW9mKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgIG0gPSBuLFxuICAgICAgaSA9IC0xLFxuICAgICAgdmFsdWUsXG4gICAgICBzdW0gPSAwO1xuXG4gIGlmICh2YWx1ZW9mID09IG51bGwpIHtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKCFpc05hTih2YWx1ZSA9IG51bWJlciQxKHZhbHVlc1tpXSkpKSBzdW0gKz0gdmFsdWU7XG4gICAgICBlbHNlIC0tbTtcbiAgICB9XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKCFpc05hTih2YWx1ZSA9IG51bWJlciQxKHZhbHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSkpIHN1bSArPSB2YWx1ZTtcbiAgICAgIGVsc2UgLS1tO1xuICAgIH1cbiAgfVxuXG4gIGlmIChtKSByZXR1cm4gc3VtIC8gbTtcbn07XG5cbnZhciBtZWRpYW4gPSBmdW5jdGlvbih2YWx1ZXMsIHZhbHVlb2YpIHtcbiAgdmFyIG4gPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgaSA9IC0xLFxuICAgICAgdmFsdWUsXG4gICAgICBudW1iZXJzID0gW107XG5cbiAgaWYgKHZhbHVlb2YgPT0gbnVsbCkge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAoIWlzTmFOKHZhbHVlID0gbnVtYmVyJDEodmFsdWVzW2ldKSkpIHtcbiAgICAgICAgbnVtYmVycy5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKCFpc05hTih2YWx1ZSA9IG51bWJlciQxKHZhbHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSkpIHtcbiAgICAgICAgbnVtYmVycy5wdXNoKHZhbHVlKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhyZXNob2xkKG51bWJlcnMuc29ydChhc2NlbmRpbmcpLCAwLjUpO1xufTtcblxudmFyIG1lcmdlJDIgPSBmdW5jdGlvbihhcnJheXMpIHtcbiAgdmFyIG4gPSBhcnJheXMubGVuZ3RoLFxuICAgICAgbSxcbiAgICAgIGkgPSAtMSxcbiAgICAgIGogPSAwLFxuICAgICAgbWVyZ2VkLFxuICAgICAgYXJyYXk7XG5cbiAgd2hpbGUgKCsraSA8IG4pIGogKz0gYXJyYXlzW2ldLmxlbmd0aDtcbiAgbWVyZ2VkID0gbmV3IEFycmF5KGopO1xuXG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIGFycmF5ID0gYXJyYXlzW25dO1xuICAgIG0gPSBhcnJheS5sZW5ndGg7XG4gICAgd2hpbGUgKC0tbSA+PSAwKSB7XG4gICAgICBtZXJnZWRbLS1qXSA9IGFycmF5W21dO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtZXJnZWQ7XG59O1xuXG52YXIgbWluID0gZnVuY3Rpb24odmFsdWVzLCB2YWx1ZW9mKSB7XG4gIHZhciBuID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgIGkgPSAtMSxcbiAgICAgIHZhbHVlLFxuICAgICAgbWluO1xuXG4gIGlmICh2YWx1ZW9mID09IG51bGwpIHtcbiAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBGaW5kIHRoZSBmaXJzdCBjb21wYXJhYmxlIHZhbHVlLlxuICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlc1tpXSkgIT0gbnVsbCAmJiB2YWx1ZSA+PSB2YWx1ZSkge1xuICAgICAgICBtaW4gPSB2YWx1ZTtcbiAgICAgICAgd2hpbGUgKCsraSA8IG4pIHsgLy8gQ29tcGFyZSB0aGUgcmVtYWluaW5nIHZhbHVlcy5cbiAgICAgICAgICBpZiAoKHZhbHVlID0gdmFsdWVzW2ldKSAhPSBudWxsICYmIG1pbiA+IHZhbHVlKSB7XG4gICAgICAgICAgICBtaW4gPSB2YWx1ZTtcbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBlbHNlIHtcbiAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBGaW5kIHRoZSBmaXJzdCBjb21wYXJhYmxlIHZhbHVlLlxuICAgICAgaWYgKCh2YWx1ZSA9IHZhbHVlb2YodmFsdWVzW2ldLCBpLCB2YWx1ZXMpKSAhPSBudWxsICYmIHZhbHVlID49IHZhbHVlKSB7XG4gICAgICAgIG1pbiA9IHZhbHVlO1xuICAgICAgICB3aGlsZSAoKytpIDwgbikgeyAvLyBDb21wYXJlIHRoZSByZW1haW5pbmcgdmFsdWVzLlxuICAgICAgICAgIGlmICgodmFsdWUgPSB2YWx1ZW9mKHZhbHVlc1tpXSwgaSwgdmFsdWVzKSkgIT0gbnVsbCAmJiBtaW4gPiB2YWx1ZSkge1xuICAgICAgICAgICAgbWluID0gdmFsdWU7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1pbjtcbn07XG5cbnZhciBwZXJtdXRlID0gZnVuY3Rpb24oYXJyYXksIGluZGV4ZXMpIHtcbiAgdmFyIGkgPSBpbmRleGVzLmxlbmd0aCwgcGVybXV0ZXMgPSBuZXcgQXJyYXkoaSk7XG4gIHdoaWxlIChpLS0pIHBlcm11dGVzW2ldID0gYXJyYXlbaW5kZXhlc1tpXV07XG4gIHJldHVybiBwZXJtdXRlcztcbn07XG5cbnZhciBzdW0gPSBmdW5jdGlvbih2YWx1ZXMsIHZhbHVlb2YpIHtcbiAgdmFyIG4gPSB2YWx1ZXMubGVuZ3RoLFxuICAgICAgaSA9IC0xLFxuICAgICAgdmFsdWUsXG4gICAgICBzdW0gPSAwO1xuXG4gIGlmICh2YWx1ZW9mID09IG51bGwpIHtcbiAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgaWYgKHZhbHVlID0gK3ZhbHVlc1tpXSkgc3VtICs9IHZhbHVlOyAvLyBOb3RlOiB6ZXJvIGFuZCBudWxsIGFyZSBlcXVpdmFsZW50LlxuICAgIH1cbiAgfVxuXG4gIGVsc2Uge1xuICAgIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgICBpZiAodmFsdWUgPSArdmFsdWVvZih2YWx1ZXNbaV0sIGksIHZhbHVlcykpIHN1bSArPSB2YWx1ZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gc3VtO1xufTtcblxuZnVuY3Rpb24gbGVuZ3RoKGQpIHtcbiAgcmV0dXJuIGQubGVuZ3RoO1xufVxuXG52YXIgYm9vdHN0cmFwQ0kgPSBmdW5jdGlvbihhcnJheSwgc2FtcGxlcywgYWxwaGEsIGYpIHtcbiAgdmFyIHZhbHVlcyA9IG51bWJlcnMoYXJyYXksIGYpLFxuICAgICAgbiA9IHZhbHVlcy5sZW5ndGgsXG4gICAgICBtID0gc2FtcGxlcyxcbiAgICAgIGEsIGksIGosIG11O1xuXG4gIGZvciAoaj0wLCBtdT1BcnJheShtKTsgajxtOyArK2opIHtcbiAgICBmb3IgKGE9MCwgaT0wOyBpPG47ICsraSkge1xuICAgICAgYSArPSB2YWx1ZXNbfn4oZXhwb3J0cy5yYW5kb20oKSAqIG4pXTtcbiAgICB9XG4gICAgbXVbal0gPSBhIC8gbjtcbiAgfVxuXG4gIHJldHVybiBbXG4gICAgdGhyZXNob2xkKG11LnNvcnQoYXNjZW5kaW5nKSwgYWxwaGEvMiksXG4gICAgdGhyZXNob2xkKG11LCAxLShhbHBoYS8yKSlcbiAgXTtcbn07XG5cbnZhciBxdWFydGlsZXMgPSBmdW5jdGlvbihhcnJheSwgZikge1xuICB2YXIgdmFsdWVzID0gbnVtYmVycyhhcnJheSwgZik7XG5cbiAgcmV0dXJuIFtcbiAgICB0aHJlc2hvbGQodmFsdWVzLnNvcnQoYXNjZW5kaW5nKSwgMC4yNSksXG4gICAgdGhyZXNob2xkKHZhbHVlcywgMC41MCksXG4gICAgdGhyZXNob2xkKHZhbHVlcywgMC43NSlcbiAgXTtcbn07XG5cbnZhciBpbnRlZ2VyID0gZnVuY3Rpb24obWluLCBtYXgpIHtcbiAgaWYgKG1heCA9PSBudWxsKSB7XG4gICAgbWF4ID0gbWluO1xuICAgIG1pbiA9IDA7XG4gIH1cblxuICB2YXIgZGlzdCA9IHt9LFxuICAgICAgYSwgYiwgZDtcblxuICBkaXN0Lm1pbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgYSA9IF8gfHwgMDtcbiAgICAgIGQgPSBiIC0gYTtcbiAgICAgIHJldHVybiBkaXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYTtcbiAgICB9XG4gIH07XG5cbiAgZGlzdC5tYXggPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGIgPSBfIHx8IDA7XG4gICAgICBkID0gYiAtIGE7XG4gICAgICByZXR1cm4gZGlzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGI7XG4gICAgfVxuICB9O1xuXG4gIGRpc3Quc2FtcGxlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGEgKyBNYXRoLmZsb29yKGQgKiBleHBvcnRzLnJhbmRvbSgpKTtcbiAgfTtcblxuICBkaXN0LnBkZiA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gKHggPT09IE1hdGguZmxvb3IoeCkgJiYgeCA+PSBhICYmIHggPCBiKSA/IDEgLyBkIDogMDtcbiAgfTtcblxuICBkaXN0LmNkZiA9IGZ1bmN0aW9uKHgpIHtcbiAgICB2YXIgdiA9IE1hdGguZmxvb3IoeCk7XG4gICAgcmV0dXJuIHYgPCBhID8gMCA6IHYgPj0gYiA/IDEgOiAodiAtIGEgKyAxKSAvIGQ7XG4gIH07XG5cbiAgZGlzdC5pY2RmID0gZnVuY3Rpb24ocCkge1xuICAgIHJldHVybiAocCA+PSAwICYmIHAgPD0gMSkgPyBhIC0gMSArIE1hdGguZmxvb3IocCAqIGQpIDogTmFOO1xuICB9O1xuXG4gIHJldHVybiBkaXN0Lm1pbihtaW4pLm1heChtYXgpO1xufTtcblxudmFyIHJhbmRvbU5vcm1hbCA9IGZ1bmN0aW9uKG1lYW4sIHN0ZGV2KSB7XG4gIHZhciBtdSxcbiAgICAgIHNpZ21hLFxuICAgICAgbmV4dCA9IE5hTixcbiAgICAgIGRpc3QgPSB7fTtcblxuICBkaXN0Lm1lYW4gPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIG11ID0gXyB8fCAwO1xuICAgICAgbmV4dCA9IE5hTjtcbiAgICAgIHJldHVybiBkaXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gbXU7XG4gICAgfVxuICB9O1xuXG4gIGRpc3Quc3RkZXYgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHNpZ21hID0gXyA9PSBudWxsID8gMSA6IF87XG4gICAgICBuZXh0ID0gTmFOO1xuICAgICAgcmV0dXJuIGRpc3Q7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzaWdtYTtcbiAgICB9XG4gIH07XG5cbiAgZGlzdC5zYW1wbGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgeCA9IDAsIHkgPSAwLCByZHMsIGM7XG4gICAgaWYgKG5leHQgPT09IG5leHQpIHtcbiAgICAgIHggPSBuZXh0O1xuICAgICAgbmV4dCA9IE5hTjtcbiAgICAgIHJldHVybiB4O1xuICAgIH1cbiAgICBkbyB7XG4gICAgICB4ID0gZXhwb3J0cy5yYW5kb20oKSAqIDIgLSAxO1xuICAgICAgeSA9IGV4cG9ydHMucmFuZG9tKCkgKiAyIC0gMTtcbiAgICAgIHJkcyA9IHggKiB4ICsgeSAqIHk7XG4gICAgfSB3aGlsZSAocmRzID09PSAwIHx8IHJkcyA+IDEpO1xuICAgIGMgPSBNYXRoLnNxcnQoLTIgKiBNYXRoLmxvZyhyZHMpIC8gcmRzKTsgLy8gQm94LU11bGxlciB0cmFuc2Zvcm1cbiAgICBuZXh0ID0gbXUgKyB5ICogYyAqIHNpZ21hO1xuICAgIHJldHVybiBtdSArIHggKiBjICogc2lnbWE7XG4gIH07XG5cbiAgZGlzdC5wZGYgPSBmdW5jdGlvbih4KSB7XG4gICAgdmFyIGV4cCA9IE1hdGguZXhwKE1hdGgucG93KHgtbXUsIDIpIC8gKC0yICogTWF0aC5wb3coc2lnbWEsIDIpKSk7XG4gICAgcmV0dXJuICgxIC8gKHNpZ21hICogTWF0aC5zcXJ0KDIqTWF0aC5QSSkpKSAqIGV4cDtcbiAgfTtcblxuICAvLyBBcHByb3hpbWF0aW9uIGZyb20gV2VzdCAoMjAwOSlcbiAgLy8gQmV0dGVyIEFwcHJveGltYXRpb25zIHRvIEN1bXVsYXRpdmUgTm9ybWFsIEZ1bmN0aW9uc1xuICBkaXN0LmNkZiA9IGZ1bmN0aW9uKHgpIHtcbiAgICB2YXIgY2QsXG4gICAgICAgIHogPSAoeCAtIG11KSAvIHNpZ21hLFxuICAgICAgICBaID0gTWF0aC5hYnMoeik7XG4gICAgaWYgKFogPiAzNykge1xuICAgICAgY2QgPSAwO1xuICAgIH0gZWxzZSB7XG4gICAgICB2YXIgc3VtLCBleHAgPSBNYXRoLmV4cCgtWipaLzIpO1xuICAgICAgaWYgKFogPCA3LjA3MTA2NzgxMTg2NTQ3KSB7XG4gICAgICAgIHN1bSA9IDMuNTI2MjQ5NjU5OTg5MTFlLTAyICogWiArIDAuNzAwMzgzMDY0NDQzNjg4O1xuICAgICAgICBzdW0gPSBzdW0gKiBaICsgNi4zNzM5NjIyMDM1MzE2NTtcbiAgICAgICAgc3VtID0gc3VtICogWiArIDMzLjkxMjg2NjA3ODM4MztcbiAgICAgICAgc3VtID0gc3VtICogWiArIDExMi4wNzkyOTE0OTc4NzE7XG4gICAgICAgIHN1bSA9IHN1bSAqIFogKyAyMjEuMjEzNTk2MTY5OTMxO1xuICAgICAgICBzdW0gPSBzdW0gKiBaICsgMjIwLjIwNjg2NzkxMjM3NjtcbiAgICAgICAgY2QgPSBleHAgKiBzdW07XG4gICAgICAgIHN1bSA9IDguODM4ODM0NzY0ODMxODRlLTAyICogWiArIDEuNzU1NjY3MTYzMTgyNjQ7XG4gICAgICAgIHN1bSA9IHN1bSAqIFogKyAxNi4wNjQxNzc1NzkyMDc7XG4gICAgICAgIHN1bSA9IHN1bSAqIFogKyA4Ni43ODA3MzIyMDI5NDYxO1xuICAgICAgICBzdW0gPSBzdW0gKiBaICsgMjk2LjU2NDI0ODc3OTY3NDtcbiAgICAgICAgc3VtID0gc3VtICogWiArIDYzNy4zMzM2MzMzNzg4MzE7XG4gICAgICAgIHN1bSA9IHN1bSAqIFogKyA3OTMuODI2NTEyNTE5OTQ4O1xuICAgICAgICBzdW0gPSBzdW0gKiBaICsgNDQwLjQxMzczNTgyNDc1MjtcbiAgICAgICAgY2QgPSBjZCAvIHN1bTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHN1bSA9IFogKyAwLjY1O1xuICAgICAgICBzdW0gPSBaICsgNCAvIHN1bTtcbiAgICAgICAgc3VtID0gWiArIDMgLyBzdW07XG4gICAgICAgIHN1bSA9IFogKyAyIC8gc3VtO1xuICAgICAgICBzdW0gPSBaICsgMSAvIHN1bTtcbiAgICAgICAgY2QgPSBleHAgLyBzdW0gLyAyLjUwNjYyODI3NDYzMTtcbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIHogPiAwID8gMSAtIGNkIDogY2Q7XG4gIH07XG5cbiAgLy8gQXBwcm94aW1hdGlvbiBvZiBQcm9iaXQgZnVuY3Rpb24gdXNpbmcgaW52ZXJzZSBlcnJvciBmdW5jdGlvbi5cbiAgZGlzdC5pY2RmID0gZnVuY3Rpb24ocCkge1xuICAgIGlmIChwIDw9IDAgfHwgcCA+PSAxKSByZXR1cm4gTmFOO1xuICAgIHZhciB4ID0gMipwIC0gMSxcbiAgICAgICAgdiA9ICg4ICogKE1hdGguUEkgLSAzKSkgLyAoMyAqIE1hdGguUEkgKiAoNC1NYXRoLlBJKSksXG4gICAgICAgIGEgPSAoMiAvIChNYXRoLlBJKnYpKSArIChNYXRoLmxvZygxIC0gTWF0aC5wb3coeCwyKSkgLyAyKSxcbiAgICAgICAgYiA9IE1hdGgubG9nKDEgLSAoeCp4KSkgLyB2LFxuICAgICAgICBzID0gKHggPiAwID8gMSA6IC0xKSAqIE1hdGguc3FydChNYXRoLnNxcnQoKGEqYSkgLSBiKSAtIGEpO1xuICAgIHJldHVybiBtdSArIHNpZ21hICogTWF0aC5TUVJUMiAqIHM7XG4gIH07XG5cbiAgcmV0dXJuIGRpc3QubWVhbihtZWFuKS5zdGRldihzdGRldik7XG59O1xuXG4vLyBUT0RPOiBzdXBwb3J0IGZvciBhZGRpdGlvbmFsIGtlcm5lbHM/XG52YXIgcmFuZG9tS0RFID0gZnVuY3Rpb24oc3VwcG9ydCwgYmFuZHdpZHRoKSB7XG4gIHZhciBrZXJuZWwgPSByYW5kb21Ob3JtYWwoKSxcbiAgICAgIGRpc3QgPSB7fSxcbiAgICAgIG4gPSAwO1xuXG4gIGRpc3QuZGF0YSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgc3VwcG9ydCA9IF87XG4gICAgICBuID0gXyA/IF8ubGVuZ3RoIDogMDtcbiAgICAgIHJldHVybiBkaXN0LmJhbmR3aWR0aChiYW5kd2lkdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gc3VwcG9ydDtcbiAgICB9XG4gIH07XG5cbiAgZGlzdC5iYW5kd2lkdGggPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gYmFuZHdpZHRoO1xuICAgIGJhbmR3aWR0aCA9IF87XG4gICAgaWYgKCFiYW5kd2lkdGggJiYgc3VwcG9ydCkgYmFuZHdpZHRoID0gZXN0aW1hdGVCYW5kd2lkdGgoc3VwcG9ydCk7XG4gICAgcmV0dXJuIGRpc3Q7XG4gIH07XG5cbiAgZGlzdC5zYW1wbGUgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gc3VwcG9ydFt+fihleHBvcnRzLnJhbmRvbSgpICogbildICsgYmFuZHdpZHRoICoga2VybmVsLnNhbXBsZSgpO1xuICB9O1xuXG4gIGRpc3QucGRmID0gZnVuY3Rpb24oeCkge1xuICAgIGZvciAodmFyIHk9MCwgaT0wOyBpPG47ICsraSkge1xuICAgICAgeSArPSBrZXJuZWwucGRmKCh4IC0gc3VwcG9ydFtpXSkgLyBiYW5kd2lkdGgpO1xuICAgIH1cbiAgICByZXR1cm4geSAvIGJhbmR3aWR0aCAvIG47XG4gIH07XG5cbiAgZGlzdC5jZGYgPSBmdW5jdGlvbih4KSB7XG4gICAgZm9yICh2YXIgeT0wLCBpPTA7IGk8bjsgKytpKSB7XG4gICAgICB5ICs9IGtlcm5lbC5jZGYoKHggLSBzdXBwb3J0W2ldKSAvIGJhbmR3aWR0aCk7XG4gICAgfVxuICAgIHJldHVybiB5IC8gbjtcbiAgfTtcblxuICBkaXN0LmljZGYgPSBmdW5jdGlvbigpIHtcbiAgICB0aHJvdyBFcnJvcignS0RFIGljZGYgbm90IHN1cHBvcnRlZC4nKTtcbiAgfTtcblxuICByZXR1cm4gZGlzdC5kYXRhKHN1cHBvcnQpO1xufTtcblxuLy8gU2NvdHQsIEQuIFcuICgxOTkyKSBNdWx0aXZhcmlhdGUgRGVuc2l0eSBFc3RpbWF0aW9uOlxuLy8gVGhlb3J5LCBQcmFjdGljZSwgYW5kIFZpc3VhbGl6YXRpb24uIFdpbGV5LlxuZnVuY3Rpb24gZXN0aW1hdGVCYW5kd2lkdGgoYXJyYXkpIHtcbiAgdmFyIG4gPSBhcnJheS5sZW5ndGgsXG4gICAgICBxID0gcXVhcnRpbGVzKGFycmF5KSxcbiAgICAgIGggPSAocVsyXSAtIHFbMF0pIC8gMS4zNDtcbiAgcmV0dXJuIDEuMDYgKiBNYXRoLm1pbihNYXRoLnNxcnQodmFyaWFuY2UoYXJyYXkpKSwgaCkgKiBNYXRoLnBvdyhuLCAtMC4yKTtcbn1cblxudmFyIHJhbmRvbU1peHR1cmUgPSBmdW5jdGlvbihkaXN0cywgd2VpZ2h0cykge1xuICB2YXIgZGlzdCA9IHt9LCBtID0gMCwgdztcblxuICBmdW5jdGlvbiBub3JtYWxpemUoeCkge1xuICAgIHZhciB3ID0gW10sIHN1bSA9IDAsIGk7XG4gICAgZm9yIChpPTA7IGk8bTsgKytpKSB7IHN1bSArPSAod1tpXSA9ICh4W2ldPT1udWxsID8gMSA6ICt4W2ldKSk7IH1cbiAgICBmb3IgKGk9MDsgaTxtOyArK2kpIHsgd1tpXSAvPSBzdW07IH1cbiAgICByZXR1cm4gdztcbiAgfVxuXG4gIGRpc3Qud2VpZ2h0cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgdyA9IG5vcm1hbGl6ZSh3ZWlnaHRzID0gKF8gfHwgW10pKTtcbiAgICAgIHJldHVybiBkaXN0O1xuICAgIH1cbiAgICByZXR1cm4gd2VpZ2h0cztcbiAgfTtcblxuICBkaXN0LmRpc3RyaWJ1dGlvbnMgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGlmIChfKSB7XG4gICAgICAgIG0gPSBfLmxlbmd0aDtcbiAgICAgICAgZGlzdHMgPSBfO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgbSA9IDA7XG4gICAgICAgIGRpc3RzID0gW107XG4gICAgICB9XG4gICAgICByZXR1cm4gZGlzdC53ZWlnaHRzKHdlaWdodHMpO1xuICAgIH1cbiAgICByZXR1cm4gZGlzdHM7XG4gIH07XG5cbiAgZGlzdC5zYW1wbGUgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgciA9IGV4cG9ydHMucmFuZG9tKCksXG4gICAgICAgIGQgPSBkaXN0c1ttLTFdLFxuICAgICAgICB2ID0gd1swXSxcbiAgICAgICAgaSA9IDA7XG5cbiAgICAvLyBmaXJzdCBzZWxlY3QgZGlzdHJpYnV0aW9uXG4gICAgZm9yICg7IGk8bS0xOyB2ICs9IHdbKytpXSkge1xuICAgICAgaWYgKHIgPCB2KSB7IGQgPSBkaXN0c1tpXTsgYnJlYWs7IH1cbiAgICB9XG4gICAgLy8gdGhlbiBzYW1wbGUgZnJvbSBpdFxuICAgIHJldHVybiBkLnNhbXBsZSgpO1xuICB9O1xuXG4gIGRpc3QucGRmID0gZnVuY3Rpb24oeCkge1xuICAgIGZvciAodmFyIHA9MCwgaT0wOyBpPG07ICsraSkge1xuICAgICAgcCArPSB3W2ldICogZGlzdHNbaV0ucGRmKHgpO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfTtcblxuICBkaXN0LmNkZiA9IGZ1bmN0aW9uKHgpIHtcbiAgICBmb3IgKHZhciBwPTAsIGk9MDsgaTxtOyArK2kpIHtcbiAgICAgIHAgKz0gd1tpXSAqIGRpc3RzW2ldLmNkZih4KTtcbiAgICB9XG4gICAgcmV0dXJuIHA7XG4gIH07XG5cbiAgZGlzdC5pY2RmID0gZnVuY3Rpb24oKSB7XG4gICAgdGhyb3cgRXJyb3IoJ01peHR1cmUgaWNkZiBub3Qgc3VwcG9ydGVkLicpO1xuICB9O1xuXG4gIHJldHVybiBkaXN0LmRpc3RyaWJ1dGlvbnMoZGlzdHMpLndlaWdodHMod2VpZ2h0cyk7XG59O1xuXG52YXIgcmFuZG9tVW5pZm9ybSA9IGZ1bmN0aW9uKG1pbiwgbWF4KSB7XG4gIGlmIChtYXggPT0gbnVsbCkge1xuICAgIG1heCA9IChtaW4gPT0gbnVsbCA/IDEgOiBtaW4pO1xuICAgIG1pbiA9IDA7XG4gIH1cblxuICB2YXIgZGlzdCA9IHt9LFxuICAgICAgYSwgYiwgZDtcblxuICBkaXN0Lm1pbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgYSA9IF8gfHwgMDtcbiAgICAgIGQgPSBiIC0gYTtcbiAgICAgIHJldHVybiBkaXN0O1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYTtcbiAgICB9XG4gIH07XG5cbiAgZGlzdC5tYXggPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGIgPSBfIHx8IDA7XG4gICAgICBkID0gYiAtIGE7XG4gICAgICByZXR1cm4gZGlzdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGI7XG4gICAgfVxuICB9O1xuXG4gIGRpc3Quc2FtcGxlID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGEgKyBkICogZXhwb3J0cy5yYW5kb20oKTtcbiAgfTtcblxuICBkaXN0LnBkZiA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gKHggPj0gYSAmJiB4IDw9IGIpID8gMSAvIGQgOiAwO1xuICB9O1xuXG4gIGRpc3QuY2RmID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiB4IDwgYSA/IDAgOiB4ID4gYiA/IDEgOiAoeCAtIGEpIC8gZDtcbiAgfTtcblxuICBkaXN0LmljZGYgPSBmdW5jdGlvbihwKSB7XG4gICAgcmV0dXJuIChwID49IDAgJiYgcCA8PSAxKSA/IGEgKyBwICogZCA6IE5hTjtcbiAgfTtcblxuICByZXR1cm4gZGlzdC5taW4obWluKS5tYXgobWF4KTtcbn07XG5cbmZ1bmN0aW9uIFR1cGxlU3RvcmUoa2V5JCQxKSB7XG4gIHRoaXMuX2tleSA9IGtleSQkMSA/IGZpZWxkKGtleSQkMSkgOiB0dXBsZWlkO1xuICB0aGlzLnJlc2V0KCk7XG59XG5cbnZhciBwcm90b3R5cGUkOSA9IFR1cGxlU3RvcmUucHJvdG90eXBlO1xuXG5wcm90b3R5cGUkOS5yZXNldCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9hZGQgPSBbXTtcbiAgdGhpcy5fcmVtID0gW107XG4gIHRoaXMuX2V4dCA9IG51bGw7XG4gIHRoaXMuX2dldCA9IG51bGw7XG4gIHRoaXMuX3EgPSBudWxsO1xufTtcblxucHJvdG90eXBlJDkuYWRkID0gZnVuY3Rpb24odikge1xuICB0aGlzLl9hZGQucHVzaCh2KTtcbn07XG5cbnByb3RvdHlwZSQ5LnJlbSA9IGZ1bmN0aW9uKHYpIHtcbiAgdGhpcy5fcmVtLnB1c2godik7XG59O1xuXG5wcm90b3R5cGUkOS52YWx1ZXMgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fZ2V0ID0gbnVsbDtcbiAgaWYgKHRoaXMuX3JlbS5sZW5ndGggPT09IDApIHJldHVybiB0aGlzLl9hZGQ7XG5cbiAgdmFyIGEgPSB0aGlzLl9hZGQsXG4gICAgICByID0gdGhpcy5fcmVtLFxuICAgICAgayA9IHRoaXMuX2tleSxcbiAgICAgIG4gPSBhLmxlbmd0aCxcbiAgICAgIG0gPSByLmxlbmd0aCxcbiAgICAgIHggPSBBcnJheShuIC0gbSksXG4gICAgICBtYXAgPSB7fSwgaSwgaiwgdjtcblxuICAvLyB1c2UgdW5pcXVlIGtleSBmaWVsZCB0byBjbGVhciByZW1vdmVkIHZhbHVlc1xuICBmb3IgKGk9MDsgaTxtOyArK2kpIHtcbiAgICBtYXBbayhyW2ldKV0gPSAxO1xuICB9XG4gIGZvciAoaT0wLCBqPTA7IGk8bjsgKytpKSB7XG4gICAgaWYgKG1hcFtrKHYgPSBhW2ldKV0pIHtcbiAgICAgIG1hcFtrKHYpXSA9IDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHhbaisrXSA9IHY7XG4gICAgfVxuICB9XG5cbiAgdGhpcy5fcmVtID0gW107XG4gIHJldHVybiAodGhpcy5fYWRkID0geCk7XG59O1xuXG4vLyBtZW1vaXppbmcgc3RhdGlzdGljcyBtZXRob2RzXG5cbnByb3RvdHlwZSQ5LmRpc3RpbmN0ID0gZnVuY3Rpb24oZ2V0KSB7XG4gIHZhciB2ID0gdGhpcy52YWx1ZXMoKSxcbiAgICAgIG4gPSB2Lmxlbmd0aCxcbiAgICAgIG1hcCA9IHt9LFxuICAgICAgY291bnQgPSAwLCBzO1xuXG4gIHdoaWxlICgtLW4gPj0gMCkge1xuICAgIHMgPSBnZXQodltuXSkgKyAnJztcbiAgICBpZiAoIW1hcC5oYXNPd25Qcm9wZXJ0eShzKSkge1xuICAgICAgbWFwW3NdID0gMTtcbiAgICAgICsrY291bnQ7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGNvdW50O1xufTtcblxucHJvdG90eXBlJDkuZXh0ZW50ID0gZnVuY3Rpb24oZ2V0KSB7XG4gIGlmICh0aGlzLl9nZXQgIT09IGdldCB8fCAhdGhpcy5fZXh0KSB7XG4gICAgdmFyIHYgPSB0aGlzLnZhbHVlcygpLFxuICAgICAgICBpID0gZXh0ZW50SW5kZXgodiwgZ2V0KTtcbiAgICB0aGlzLl9leHQgPSBbdltpWzBdXSwgdltpWzFdXV07XG4gICAgdGhpcy5fZ2V0ID0gZ2V0O1xuICB9XG4gIHJldHVybiB0aGlzLl9leHQ7XG59O1xuXG5wcm90b3R5cGUkOS5hcmdtaW4gPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMuZXh0ZW50KGdldClbMF0gfHwge307XG59O1xuXG5wcm90b3R5cGUkOS5hcmdtYXggPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMuZXh0ZW50KGdldClbMV0gfHwge307XG59O1xuXG5wcm90b3R5cGUkOS5taW4gPSBmdW5jdGlvbihnZXQpIHtcbiAgdmFyIG0gPSB0aGlzLmV4dGVudChnZXQpWzBdO1xuICByZXR1cm4gbSAhPSBudWxsID8gZ2V0KG0pIDogK0luZmluaXR5O1xufTtcblxucHJvdG90eXBlJDkubWF4ID0gZnVuY3Rpb24oZ2V0KSB7XG4gIHZhciBtID0gdGhpcy5leHRlbnQoZ2V0KVsxXTtcbiAgcmV0dXJuIG0gIT0gbnVsbCA/IGdldChtKSA6IC1JbmZpbml0eTtcbn07XG5cbnByb3RvdHlwZSQ5LnF1YXJ0aWxlID0gZnVuY3Rpb24oZ2V0KSB7XG4gIGlmICh0aGlzLl9nZXQgIT09IGdldCB8fCAhdGhpcy5fcSkge1xuICAgIHRoaXMuX3EgPSBxdWFydGlsZXModGhpcy52YWx1ZXMoKSwgZ2V0KTtcbiAgICB0aGlzLl9nZXQgPSBnZXQ7XG4gIH1cbiAgcmV0dXJuIHRoaXMuX3E7XG59O1xuXG5wcm90b3R5cGUkOS5xMSA9IGZ1bmN0aW9uKGdldCkge1xuICByZXR1cm4gdGhpcy5xdWFydGlsZShnZXQpWzBdO1xufTtcblxucHJvdG90eXBlJDkucTIgPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMucXVhcnRpbGUoZ2V0KVsxXTtcbn07XG5cbnByb3RvdHlwZSQ5LnEzID0gZnVuY3Rpb24oZ2V0KSB7XG4gIHJldHVybiB0aGlzLnF1YXJ0aWxlKGdldClbMl07XG59O1xuXG5wcm90b3R5cGUkOS5jaSA9IGZ1bmN0aW9uKGdldCkge1xuICBpZiAodGhpcy5fZ2V0ICE9PSBnZXQgfHwgIXRoaXMuX2NpKSB7XG4gICAgdGhpcy5fY2kgPSBib290c3RyYXBDSSh0aGlzLnZhbHVlcygpLCAxMDAwLCAwLjA1LCBnZXQpO1xuICAgIHRoaXMuX2dldCA9IGdldDtcbiAgfVxuICByZXR1cm4gdGhpcy5fY2k7XG59O1xuXG5wcm90b3R5cGUkOS5jaTAgPSBmdW5jdGlvbihnZXQpIHtcbiAgcmV0dXJuIHRoaXMuY2koZ2V0KVswXTtcbn07XG5cbnByb3RvdHlwZSQ5LmNpMSA9IGZ1bmN0aW9uKGdldCkge1xuICByZXR1cm4gdGhpcy5jaShnZXQpWzFdO1xufTtcblxuLyoqXG4gKiBHcm91cC1ieSBhZ2dyZWdhdGlvbiBvcGVyYXRvci5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqPn0gW3BhcmFtcy5ncm91cGJ5XSAtIEFuIGFycmF5IG9mIGFjY2Vzc29ycyB0byBncm91cGJ5LlxuICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqPn0gW3BhcmFtcy5maWVsZHNdIC0gQW4gYXJyYXkgb2YgYWNjZXNzb3JzIHRvIGFnZ3JlZ2F0ZS5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3BhcmFtcy5vcHNdIC0gQW4gYXJyYXkgb2Ygc3RyaW5ncyBpbmRpY2F0aW5nIGFnZ3JlZ2F0aW9uIG9wZXJhdGlvbnMuXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtwYXJhbXMuYXNdIC0gQW4gYXJyYXkgb2Ygb3V0cHV0IGZpZWxkIG5hbWVzIGZvciBhZ2dyZWdhdGVkIHZhbHVlcy5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3BhcmFtcy5jcm9zcz1mYWxzZV0gLSBBIGZsYWcgaW5kaWNhdGluZyB0aGF0IHRoZSBmdWxsXG4gKiAgIGNyb3NzLXByb2R1Y3Qgb2YgZ3JvdXBieSB2YWx1ZXMgc2hvdWxkIGJlIGdlbmVyYXRlZCwgaW5jbHVkaW5nIGVtcHR5IGNlbGxzLlxuICogICBJZiB0cnVlLCB0aGUgZHJvcCBwYXJhbWV0ZXIgaXMgaWdub3JlZCBhbmQgZW1wdHkgY2VsbHMgYXJlIHJldGFpbmVkLlxuICogQHBhcmFtIHtib29sZWFufSBbcGFyYW1zLmRyb3A9dHJ1ZV0gLSBBIGZsYWcgaW5kaWNhdGluZyBpZiBlbXB0eSBjZWxscyBzaG91bGQgYmUgcmVtb3ZlZC5cbiAqL1xuZnVuY3Rpb24gQWdncmVnYXRlKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xuXG4gIHRoaXMuX2FkZHMgPSBbXTsgLy8gYXJyYXkgb2YgYWRkZWQgb3V0cHV0IHR1cGxlc1xuICB0aGlzLl9tb2RzID0gW107IC8vIGFycmF5IG9mIG1vZGlmaWVkIG91dHB1dCB0dXBsZXNcbiAgdGhpcy5fYWxlbiA9IDA7ICAvLyBudW1iZXIgb2YgYWN0aXZlIGFkZGVkIHR1cGxlc1xuICB0aGlzLl9tbGVuID0gMDsgIC8vIG51bWJlciBvZiBhY3RpdmUgbW9kaWZpZWQgdHVwbGVzXG4gIHRoaXMuX2Ryb3AgPSB0cnVlOyAgIC8vIHNob3VsZCBlbXB0eSBhZ2dyZWdhdGlvbiBjZWxscyBiZSByZW1vdmVkXG4gIHRoaXMuX2Nyb3NzID0gZmFsc2U7IC8vIHByb2R1Y2UgZnVsbCBjcm9zcy1wcm9kdWN0IG9mIGdyb3VwLWJ5IHZhbHVlc1xuXG4gIHRoaXMuX2RpbXMgPSBbXTsgICAvLyBncm91cC1ieSBkaW1lbnNpb24gYWNjZXNzb3JzXG4gIHRoaXMuX2RuYW1lcyA9IFtdOyAvLyBncm91cC1ieSBkaW1lbnNpb24gbmFtZXNcblxuICB0aGlzLl9tZWFzdXJlcyA9IFtdOyAvLyBjb2xsZWN0aW9uIG9mIGFnZ3JlZ2F0aW9uIG1vbm9pZHNcbiAgdGhpcy5fY291bnRPbmx5ID0gZmFsc2U7IC8vIGZsYWcgaW5kaWNhdGluZyBvbmx5IGNvdW50IGFnZ3JlZ2F0aW9uXG4gIHRoaXMuX2NvdW50cyA9IG51bGw7IC8vIGNvbGxlY3Rpb24gb2YgY291bnQgZmllbGRzXG4gIHRoaXMuX3ByZXYgPSBudWxsOyAgIC8vIHByZXZpb3VzIGFnZ3JlZ2F0aW9uIGNlbGxzXG5cbiAgdGhpcy5faW5wdXRzID0gbnVsbDsgIC8vIGFycmF5IG9mIGRlcGVuZGVudCBpbnB1dCB0dXBsZSBmaWVsZCBuYW1lc1xuICB0aGlzLl9vdXRwdXRzID0gbnVsbDsgLy8gYXJyYXkgb2Ygb3V0cHV0IHR1cGxlIGZpZWxkIG5hbWVzXG59XG5cbkFnZ3JlZ2F0ZS5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJBZ2dyZWdhdGVcIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJnZW5lcmF0ZXNcIjogdHJ1ZSwgXCJjaGFuZ2VzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJncm91cGJ5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwib3BzXCIsIFwidHlwZVwiOiBcImVudW1cIiwgXCJhcnJheVwiOiB0cnVlLCBcInZhbHVlc1wiOiBWYWxpZEFnZ3JlZ2F0ZU9wcyB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRzXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwibnVsbFwiOiB0cnVlLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcIm51bGxcIjogdHJ1ZSwgXCJhcnJheVwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJkcm9wXCIsIFwidHlwZVwiOiBcImJvb2xlYW5cIiwgXCJkZWZhdWx0XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcImNyb3NzXCIsIFwidHlwZVwiOiBcImJvb2xlYW5cIiwgXCJkZWZhdWx0XCI6IGZhbHNlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJrZXlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkOCA9IGluaGVyaXRzKEFnZ3JlZ2F0ZSwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDgudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGFnZ3IgPSB0aGlzLFxuICAgICAgb3V0ID0gcHVsc2UuZm9yayhwdWxzZS5OT19TT1VSQ0UgfCBwdWxzZS5OT19GSUVMRFMpLFxuICAgICAgbW9kO1xuXG4gIHRoaXMuc3RhbXAgPSBvdXQuc3RhbXA7XG5cbiAgaWYgKHRoaXMudmFsdWUgJiYgKChtb2QgPSBfLm1vZGlmaWVkKCkpIHx8IHB1bHNlLm1vZGlmaWVkKHRoaXMuX2lucHV0cykpKSB7XG4gICAgdGhpcy5fcHJldiA9IHRoaXMudmFsdWU7XG4gICAgdGhpcy52YWx1ZSA9IG1vZCA/IHRoaXMuaW5pdChfKSA6IHt9O1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlNPVVJDRSwgZnVuY3Rpb24odCkgeyBhZ2dyLmFkZCh0KTsgfSk7XG4gIH0gZWxzZSB7XG4gICAgdGhpcy52YWx1ZSA9IHRoaXMudmFsdWUgfHwgdGhpcy5pbml0KF8pO1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlJFTSwgZnVuY3Rpb24odCkgeyBhZ2dyLnJlbSh0KTsgfSk7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbih0KSB7IGFnZ3IuYWRkKHQpOyB9KTtcbiAgfVxuXG4gIC8vIEluZGljYXRlIG91dHB1dCBmaWVsZHMgYW5kIHJldHVybiBhZ2dyZWdhdGUgdHVwbGVzLlxuICBvdXQubW9kaWZpZXModGhpcy5fb3V0cHV0cyk7XG5cbiAgLy8gU2hvdWxkIGVtcHR5IGNlbGxzIGJlIGRyb3BwZWQ/XG4gIGFnZ3IuX2Ryb3AgPSBfLmRyb3AgIT09IGZhbHNlO1xuXG4gIC8vIElmIGRvbWFpbiBjcm9zcy1wcm9kdWN0IHJlcXVlc3RlZCwgZ2VuZXJhdGUgZW1wdHkgY2VsbHMgYXMgbmVlZGVkXG4gIC8vIGFuZCBlbnN1cmUgdGhhdCBlbXB0eSBjZWxscyBhcmUgbm90IGRyb3BwZWRcbiAgaWYgKF8uY3Jvc3MgJiYgYWdnci5fZGltcy5sZW5ndGggPiAxKSB7XG4gICAgYWdnci5fZHJvcCA9IGZhbHNlO1xuICAgIHRoaXMuY3Jvc3MoKTtcbiAgfVxuXG4gIHJldHVybiBhZ2dyLmNoYW5nZXMob3V0KTtcbn07XG5cbnByb3RvdHlwZSQ4LmNyb3NzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBhZ2dyID0gdGhpcyxcbiAgICAgIGN1cnIgPSBhZ2dyLnZhbHVlLFxuICAgICAgZGltcyA9IGFnZ3IuX2RuYW1lcyxcbiAgICAgIHZhbHMgPSBkaW1zLm1hcChmdW5jdGlvbigpIHsgcmV0dXJuIHt9OyB9KSxcbiAgICAgIG4gPSBkaW1zLmxlbmd0aDtcblxuICAvLyBjb2xsZWN0IGFsbCBncm91cC1ieSBkb21haW4gdmFsdWVzXG4gIGZ1bmN0aW9uIGNvbGxlY3QoY2VsbHMpIHtcbiAgICB2YXIga2V5JCQxLCBpLCB0LCB2O1xuICAgIGZvciAoa2V5JCQxIGluIGNlbGxzKSB7XG4gICAgICB0ID0gY2VsbHNba2V5JCQxXS50dXBsZTtcbiAgICAgIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgICAgICB2YWxzW2ldWyh2ID0gdFtkaW1zW2ldXSldID0gdjtcbiAgICAgIH1cbiAgICB9XG4gIH1cbiAgY29sbGVjdChhZ2dyLl9wcmV2KTtcbiAgY29sbGVjdChjdXJyKTtcblxuICAvLyBpdGVyYXRlIG92ZXIga2V5IGNyb3NzLXByb2R1Y3QsIGNyZWF0ZSBjZWxscyBhcyBuZWVkZWRcbiAgZnVuY3Rpb24gZ2VuZXJhdGUoYmFzZSwgdHVwbGUsIGluZGV4KSB7XG4gICAgdmFyIG5hbWUgPSBkaW1zW2luZGV4XSxcbiAgICAgICAgdiA9IHZhbHNbaW5kZXgrK10sXG4gICAgICAgIGssIGtleSQkMTtcblxuICAgIGZvciAoayBpbiB2KSB7XG4gICAgICB0dXBsZVtuYW1lXSA9IHZba107XG4gICAgICBrZXkkJDEgPSBiYXNlID8gYmFzZSArICd8JyArIGsgOiBrO1xuICAgICAgaWYgKGluZGV4IDwgbikgZ2VuZXJhdGUoa2V5JCQxLCB0dXBsZSwgaW5kZXgpO1xuICAgICAgZWxzZSBpZiAoIWN1cnJba2V5JCQxXSkgYWdnci5jZWxsKGtleSQkMSwgdHVwbGUpO1xuICAgIH1cbiAgfVxuICBnZW5lcmF0ZSgnJywge30sIDApO1xufTtcblxucHJvdG90eXBlJDguaW5pdCA9IGZ1bmN0aW9uKF8pIHtcbiAgLy8gaW5pdGlhbGl6ZSBpbnB1dCBhbmQgb3V0cHV0IGZpZWxkc1xuICB2YXIgaW5wdXRzID0gKHRoaXMuX2lucHV0cyA9IFtdKSxcbiAgICAgIG91dHB1dHMgPSAodGhpcy5fb3V0cHV0cyA9IFtdKSxcbiAgICAgIGlucHV0TWFwID0ge307XG5cbiAgZnVuY3Rpb24gaW5wdXRWaXNpdChnZXQpIHtcbiAgICB2YXIgZmllbGRzID0gYXJyYXkoYWNjZXNzb3JGaWVsZHMoZ2V0KSksXG4gICAgICAgIGkgPSAwLCBuID0gZmllbGRzLmxlbmd0aCwgZjtcbiAgICBmb3IgKDsgaTxuOyArK2kpIHtcbiAgICAgIGlmICghaW5wdXRNYXBbZj1maWVsZHNbaV1dKSB7XG4gICAgICAgIGlucHV0TWFwW2ZdID0gMTtcbiAgICAgICAgaW5wdXRzLnB1c2goZik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gaW5pdGlhbGl6ZSBncm91cC1ieSBkaW1lbnNpb25zXG4gIHRoaXMuX2RpbXMgPSBhcnJheShfLmdyb3VwYnkpO1xuICB0aGlzLl9kbmFtZXMgPSB0aGlzLl9kaW1zLm1hcChmdW5jdGlvbihkKSB7XG4gICAgdmFyIGRuYW1lID0gYWNjZXNzb3JOYW1lKGQpO1xuICAgIGlucHV0VmlzaXQoZCk7XG4gICAgb3V0cHV0cy5wdXNoKGRuYW1lKTtcbiAgICByZXR1cm4gZG5hbWU7XG4gIH0pO1xuICB0aGlzLmNlbGxrZXkgPSBfLmtleSA/IF8ua2V5IDogZ3JvdXBrZXkodGhpcy5fZGltcyk7XG5cbiAgLy8gaW5pdGlhbGl6ZSBhZ2dyZWdhdGUgbWVhc3VyZXNcbiAgdGhpcy5fY291bnRPbmx5ID0gdHJ1ZTtcbiAgdGhpcy5fY291bnRzID0gW107XG4gIHRoaXMuX21lYXN1cmVzID0gW107XG5cbiAgdmFyIGZpZWxkcyA9IF8uZmllbGRzIHx8IFtudWxsXSxcbiAgICAgIG9wcyA9IF8ub3BzIHx8IFsnY291bnQnXSxcbiAgICAgIGFzID0gXy5hcyB8fCBbXSxcbiAgICAgIG4gPSBmaWVsZHMubGVuZ3RoLFxuICAgICAgbWFwID0ge30sXG4gICAgICBmaWVsZCQkMSwgb3AsIG0sIG1uYW1lLCBvdXRuYW1lLCBpO1xuXG4gIGlmIChuICE9PSBvcHMubGVuZ3RoKSB7XG4gICAgZXJyb3IkMSgnVW5tYXRjaGVkIG51bWJlciBvZiBmaWVsZHMgYW5kIGFnZ3JlZ2F0ZSBvcHMuJyk7XG4gIH1cblxuICBmb3IgKGk9MDsgaTxuOyArK2kpIHtcbiAgICBmaWVsZCQkMSA9IGZpZWxkc1tpXTtcbiAgICBvcCA9IG9wc1tpXTtcblxuICAgIGlmIChmaWVsZCQkMSA9PSBudWxsICYmIG9wICE9PSAnY291bnQnKSB7XG4gICAgICBlcnJvciQxKCdOdWxsIGFnZ3JlZ2F0ZSBmaWVsZCBzcGVjaWZpZWQuJyk7XG4gICAgfVxuICAgIG1uYW1lID0gYWNjZXNzb3JOYW1lKGZpZWxkJCQxKTtcbiAgICBvdXRuYW1lID0gbWVhc3VyZU5hbWUob3AsIG1uYW1lLCBhc1tpXSk7XG4gICAgb3V0cHV0cy5wdXNoKG91dG5hbWUpO1xuXG4gICAgaWYgKG9wID09PSAnY291bnQnKSB7XG4gICAgICB0aGlzLl9jb3VudHMucHVzaChvdXRuYW1lKTtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cblxuICAgIG0gPSBtYXBbbW5hbWVdO1xuICAgIGlmICghbSkge1xuICAgICAgaW5wdXRWaXNpdChmaWVsZCQkMSk7XG4gICAgICBtID0gKG1hcFttbmFtZV0gPSBbXSk7XG4gICAgICBtLmZpZWxkID0gZmllbGQkJDE7XG4gICAgICB0aGlzLl9tZWFzdXJlcy5wdXNoKG0pO1xuICAgIH1cblxuICAgIGlmIChvcCAhPT0gJ2NvdW50JykgdGhpcy5fY291bnRPbmx5ID0gZmFsc2U7XG4gICAgbS5wdXNoKGNyZWF0ZU1lYXN1cmUob3AsIG91dG5hbWUpKTtcbiAgfVxuXG4gIHRoaXMuX21lYXN1cmVzID0gdGhpcy5fbWVhc3VyZXMubWFwKGZ1bmN0aW9uKG0pIHtcbiAgICByZXR1cm4gY29tcGlsZU1lYXN1cmVzKG0sIG0uZmllbGQpO1xuICB9KTtcblxuICByZXR1cm4ge307IC8vIGFnZ3JlZ2F0aW9uIGNlbGxzICh0aGlzLnZhbHVlKVxufTtcblxuLy8gLS0gQ2VsbCBNYW5hZ2VtZW50IC0tLS0tXG5cbnByb3RvdHlwZSQ4LmNlbGxrZXkgPSBncm91cGtleSgpO1xuXG5wcm90b3R5cGUkOC5jZWxsID0gZnVuY3Rpb24oa2V5JCQxLCB0KSB7XG4gIHZhciBjZWxsID0gdGhpcy52YWx1ZVtrZXkkJDFdO1xuICBpZiAoIWNlbGwpIHtcbiAgICBjZWxsID0gdGhpcy52YWx1ZVtrZXkkJDFdID0gdGhpcy5uZXdjZWxsKGtleSQkMSwgdCk7XG4gICAgdGhpcy5fYWRkc1t0aGlzLl9hbGVuKytdID0gY2VsbDtcbiAgfSBlbHNlIGlmIChjZWxsLm51bSA9PT0gMCAmJiB0aGlzLl9kcm9wICYmIGNlbGwuc3RhbXAgPCB0aGlzLnN0YW1wKSB7XG4gICAgY2VsbC5zdGFtcCA9IHRoaXMuc3RhbXA7XG4gICAgdGhpcy5fYWRkc1t0aGlzLl9hbGVuKytdID0gY2VsbDtcbiAgfSBlbHNlIGlmIChjZWxsLnN0YW1wIDwgdGhpcy5zdGFtcCkge1xuICAgIGNlbGwuc3RhbXAgPSB0aGlzLnN0YW1wO1xuICAgIHRoaXMuX21vZHNbdGhpcy5fbWxlbisrXSA9IGNlbGw7XG4gIH1cbiAgcmV0dXJuIGNlbGw7XG59O1xuXG5wcm90b3R5cGUkOC5uZXdjZWxsID0gZnVuY3Rpb24oa2V5JCQxLCB0KSB7XG4gIHZhciBjZWxsID0ge1xuICAgIGtleTogICBrZXkkJDEsXG4gICAgbnVtOiAgIDAsXG4gICAgYWdnOiAgIG51bGwsXG4gICAgdHVwbGU6IHRoaXMubmV3dHVwbGUodCwgdGhpcy5fcHJldiAmJiB0aGlzLl9wcmV2W2tleSQkMV0pLFxuICAgIHN0YW1wOiB0aGlzLnN0YW1wLFxuICAgIHN0b3JlOiBmYWxzZVxuICB9O1xuXG4gIGlmICghdGhpcy5fY291bnRPbmx5KSB7XG4gICAgdmFyIG1lYXN1cmVzID0gdGhpcy5fbWVhc3VyZXMsXG4gICAgICAgIG4gPSBtZWFzdXJlcy5sZW5ndGgsIGk7XG5cbiAgICBjZWxsLmFnZyA9IEFycmF5KG4pO1xuICAgIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgICAgY2VsbC5hZ2dbaV0gPSBuZXcgbWVhc3VyZXNbaV0oY2VsbCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGNlbGwuc3RvcmUpIHtcbiAgICBjZWxsLmRhdGEgPSBuZXcgVHVwbGVTdG9yZSgpO1xuICB9XG5cbiAgcmV0dXJuIGNlbGw7XG59O1xuXG5wcm90b3R5cGUkOC5uZXd0dXBsZSA9IGZ1bmN0aW9uKHQsIHApIHtcbiAgdmFyIG5hbWVzID0gdGhpcy5fZG5hbWVzLFxuICAgICAgZGltcyA9IHRoaXMuX2RpbXMsXG4gICAgICB4ID0ge30sIGksIG47XG5cbiAgZm9yIChpPTAsIG49ZGltcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgeFtuYW1lc1tpXV0gPSBkaW1zW2ldKHQpO1xuICB9XG5cbiAgcmV0dXJuIHAgPyByZXBsYWNlKHAudHVwbGUsIHgpIDogaW5nZXN0KHgpO1xufTtcblxuLy8gLS0gUHJvY2VzcyBUdXBsZXMgLS0tLS1cblxucHJvdG90eXBlJDguYWRkID0gZnVuY3Rpb24odCkge1xuICB2YXIga2V5JCQxID0gdGhpcy5jZWxsa2V5KHQpLFxuICAgICAgY2VsbCA9IHRoaXMuY2VsbChrZXkkJDEsIHQpLFxuICAgICAgYWdnLCBpLCBuO1xuXG4gIGNlbGwubnVtICs9IDE7XG4gIGlmICh0aGlzLl9jb3VudE9ubHkpIHJldHVybjtcblxuICBpZiAoY2VsbC5zdG9yZSkgY2VsbC5kYXRhLmFkZCh0KTtcblxuICBhZ2cgPSBjZWxsLmFnZztcbiAgZm9yIChpPTAsIG49YWdnLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBhZ2dbaV0uYWRkKGFnZ1tpXS5nZXQodCksIHQpO1xuICB9XG59O1xuXG5wcm90b3R5cGUkOC5yZW0gPSBmdW5jdGlvbih0KSB7XG4gIHZhciBrZXkkJDEgPSB0aGlzLmNlbGxrZXkodCksXG4gICAgICBjZWxsID0gdGhpcy5jZWxsKGtleSQkMSwgdCksXG4gICAgICBhZ2csIGksIG47XG5cbiAgY2VsbC5udW0gLT0gMTtcbiAgaWYgKHRoaXMuX2NvdW50T25seSkgcmV0dXJuO1xuXG4gIGlmIChjZWxsLnN0b3JlKSBjZWxsLmRhdGEucmVtKHQpO1xuXG4gIGFnZyA9IGNlbGwuYWdnO1xuICBmb3IgKGk9MCwgbj1hZ2cubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGFnZ1tpXS5yZW0oYWdnW2ldLmdldCh0KSwgdCk7XG4gIH1cbn07XG5cbnByb3RvdHlwZSQ4LmNlbGx0dXBsZSA9IGZ1bmN0aW9uKGNlbGwpIHtcbiAgdmFyIHR1cGxlID0gY2VsbC50dXBsZSxcbiAgICAgIGNvdW50cyA9IHRoaXMuX2NvdW50cyxcbiAgICAgIGFnZywgaSwgbjtcblxuICAvLyBjb25zb2xpZGF0ZSBzdG9yZWQgdmFsdWVzXG4gIGlmIChjZWxsLnN0b3JlKSB7XG4gICAgY2VsbC5kYXRhLnZhbHVlcygpO1xuICB9XG5cbiAgLy8gdXBkYXRlIHR1cGxlIHByb3BlcnRpZXNcbiAgZm9yIChpPTAsIG49Y291bnRzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICB0dXBsZVtjb3VudHNbaV1dID0gY2VsbC5udW07XG4gIH1cbiAgaWYgKCF0aGlzLl9jb3VudE9ubHkpIHtcbiAgICBhZ2cgPSBjZWxsLmFnZztcbiAgICBmb3IgKGk9MCwgbj1hZ2cubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgYWdnW2ldLnNldCh0dXBsZSk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHR1cGxlO1xufTtcblxucHJvdG90eXBlJDguY2hhbmdlcyA9IGZ1bmN0aW9uKG91dCkge1xuICB2YXIgYWRkcyA9IHRoaXMuX2FkZHMsXG4gICAgICBtb2RzID0gdGhpcy5fbW9kcyxcbiAgICAgIHByZXYgPSB0aGlzLl9wcmV2LFxuICAgICAgZHJvcCA9IHRoaXMuX2Ryb3AsXG4gICAgICBhZGQgPSBvdXQuYWRkLFxuICAgICAgcmVtID0gb3V0LnJlbSxcbiAgICAgIG1vZCA9IG91dC5tb2QsXG4gICAgICBjZWxsLCBrZXkkJDEsIGksIG47XG5cbiAgaWYgKHByZXYpIGZvciAoa2V5JCQxIGluIHByZXYpIHtcbiAgICBjZWxsID0gcHJldltrZXkkJDFdO1xuICAgIGlmICghZHJvcCB8fCBjZWxsLm51bSkgcmVtLnB1c2goY2VsbC50dXBsZSk7XG4gIH1cblxuICBmb3IgKGk9MCwgbj10aGlzLl9hbGVuOyBpPG47ICsraSkge1xuICAgIGFkZC5wdXNoKHRoaXMuY2VsbHR1cGxlKGFkZHNbaV0pKTtcbiAgICBhZGRzW2ldID0gbnVsbDsgLy8gZm9yIGdhcmJhZ2UgY29sbGVjdGlvblxuICB9XG5cbiAgZm9yIChpPTAsIG49dGhpcy5fbWxlbjsgaTxuOyArK2kpIHtcbiAgICBjZWxsID0gbW9kc1tpXTtcbiAgICAoY2VsbC5udW0gPT09IDAgJiYgZHJvcCA/IHJlbSA6IG1vZCkucHVzaCh0aGlzLmNlbGx0dXBsZShjZWxsKSk7XG4gICAgbW9kc1tpXSA9IG51bGw7IC8vIGZvciBnYXJiYWdlIGNvbGxlY3Rpb25cbiAgfVxuXG4gIHRoaXMuX2FsZW4gPSB0aGlzLl9tbGVuID0gMDsgLy8gcmVzZXQgbGlzdCBvZiBhY3RpdmUgY2VsbHNcbiAgdGhpcy5fcHJldiA9IG51bGw7XG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIGJpbm5pbmcgZnVuY3Rpb24gZm9yIGRpc2NyZXRpemluZyBkYXRhLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuIFRoZVxuICogICBwcm92aWRlZCB2YWx1ZXMgc2hvdWxkIGJlIHZhbGlkIG9wdGlvbnMgZm9yIHRoZSB7QGxpbmsgYmlufSBmdW5jdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogKn0gcGFyYW1zLmZpZWxkIC0gVGhlIGRhdGEgZmllbGQgdG8gYmluLlxuICovXG5mdW5jdGlvbiBCaW4ocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbkJpbi5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJCaW5cIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJtb2RpZmllc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJhbmNob3JcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcIm1heGJpbnNcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAyMCB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYmFzZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDEwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJkaXZpZGVcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJkZWZhdWx0XCI6IFs1LCAyXSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZXh0ZW50XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwic3RlcFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwic3RlcHNcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwibWluc3RlcFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICB7IFwibmFtZVwiOiBcIm5pY2VcIiwgXCJ0eXBlXCI6IFwiYm9vbGVhblwiLCBcImRlZmF1bHRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwibmFtZVwiLCBcInR5cGVcIjogXCJzdHJpbmdcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiwgXCJkZWZhdWx0XCI6IFtcImJpbjBcIiwgXCJiaW4xXCJdIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQxMCA9IGluaGVyaXRzKEJpbiwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDEwLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBiaW5zID0gdGhpcy5fYmlucyhfKSxcbiAgICAgIHN0YXJ0ID0gYmlucy5zdGFydCxcbiAgICAgIHN0ZXAgPSBiaW5zLnN0ZXAsXG4gICAgICBhcyA9IF8uYXMgfHwgWydiaW4wJywgJ2JpbjEnXSxcbiAgICAgIGIwID0gYXNbMF0sXG4gICAgICBiMSA9IGFzWzFdLFxuICAgICAgZmxhZztcblxuICBpZiAoXy5tb2RpZmllZCgpKSB7XG4gICAgcHVsc2UgPSBwdWxzZS5yZWZsb3codHJ1ZSk7XG4gICAgZmxhZyA9IHB1bHNlLlNPVVJDRTtcbiAgfSBlbHNlIHtcbiAgICBmbGFnID0gcHVsc2UubW9kaWZpZWQoYWNjZXNzb3JGaWVsZHMoXy5maWVsZCkpID8gcHVsc2UuQUREX01PRCA6IHB1bHNlLkFERDtcbiAgfVxuXG4gIHB1bHNlLnZpc2l0KGZsYWcsIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgdiA9IGJpbnModCk7XG4gICAgLy8gbWluaW11bSBiaW4gdmFsdWUgKGluY2x1c2l2ZSlcbiAgICB0W2IwXSA9IHY7XG4gICAgLy8gbWF4aW11bSBiaW4gdmFsdWUgKGV4Y2x1c2l2ZSlcbiAgICAvLyB1c2UgY29udm9sdXRlZCBtYXRoIGZvciBiZXR0ZXIgZmxvYXRpbmcgcG9pbnQgYWdyZWVtZW50XG4gICAgLy8gc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS92ZWdhL3ZlZ2EvaXNzdWVzLzgzMFxuICAgIHRbYjFdID0gdiA9PSBudWxsID8gbnVsbCA6IHN0YXJ0ICsgc3RlcCAqICgxICsgKHYgLSBzdGFydCkgLyBzdGVwKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHB1bHNlLm1vZGlmaWVzKGFzKTtcbn07XG5cbnByb3RvdHlwZSQxMC5fYmlucyA9IGZ1bmN0aW9uKF8pIHtcbiAgaWYgKHRoaXMudmFsdWUgJiYgIV8ubW9kaWZpZWQoKSkge1xuICAgIHJldHVybiB0aGlzLnZhbHVlO1xuICB9XG5cbiAgdmFyIGZpZWxkJCQxID0gXy5maWVsZCxcbiAgICAgIGJpbnMgID0gYmluKF8pLFxuICAgICAgc3RhcnQgPSBiaW5zLnN0YXJ0LFxuICAgICAgc3RvcCAgPSBiaW5zLnN0b3AsXG4gICAgICBzdGVwICA9IGJpbnMuc3RlcCxcbiAgICAgIGEsIGQ7XG5cbiAgaWYgKChhID0gXy5hbmNob3IpICE9IG51bGwpIHtcbiAgICBkID0gYSAtIChzdGFydCArIHN0ZXAgKiBNYXRoLmZsb29yKChhIC0gc3RhcnQpIC8gc3RlcCkpO1xuICAgIHN0YXJ0ICs9IGQ7XG4gICAgc3RvcCArPSBkO1xuICB9XG5cbiAgdmFyIGYgPSBmdW5jdGlvbih0KSB7XG4gICAgdmFyIHYgPSBmaWVsZCQkMSh0KTtcbiAgICBpZiAodiA9PSBudWxsKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9IGVsc2Uge1xuICAgICAgdiA9IE1hdGgubWF4KHN0YXJ0LCBNYXRoLm1pbigrdiwgc3RvcCAtIHN0ZXApKTtcbiAgICAgIHJldHVybiBzdGFydCArIHN0ZXAgKiBNYXRoLmZsb29yKCh2IC0gc3RhcnQpIC8gc3RlcCk7XG4gICAgfVxuICB9O1xuXG4gIGYuc3RhcnQgPSBzdGFydDtcbiAgZi5zdG9wID0gc3RvcDtcbiAgZi5zdGVwID0gc3RlcDtcblxuICByZXR1cm4gdGhpcy52YWx1ZSA9IGFjY2Vzc29yKFxuICAgIGYsXG4gICAgYWNjZXNzb3JGaWVsZHMoZmllbGQkJDEpLFxuICAgIF8ubmFtZSB8fCAnYmluXycgKyBhY2Nlc3Nvck5hbWUoZmllbGQkJDEpXG4gICk7XG59O1xuXG52YXIgU29ydGVkTGlzdCA9IGZ1bmN0aW9uKGlkRnVuYywgc291cmNlLCBpbnB1dCkge1xuICB2YXIgJCQkMSA9IGlkRnVuYyxcbiAgICAgIGRhdGEgPSBzb3VyY2UgfHwgW10sXG4gICAgICBhZGQgPSBpbnB1dCB8fCBbXSxcbiAgICAgIHJlbSA9IHt9LFxuICAgICAgY250ID0gMDtcblxuICByZXR1cm4ge1xuICAgIGFkZDogZnVuY3Rpb24odCkgeyBhZGQucHVzaCh0KTsgfSxcbiAgICByZW1vdmU6IGZ1bmN0aW9uKHQpIHsgcmVtWyQkJDEodCldID0gKytjbnQ7IH0sXG4gICAgc2l6ZTogZnVuY3Rpb24oKSB7IHJldHVybiBkYXRhLmxlbmd0aDsgfSxcbiAgICBkYXRhOiBmdW5jdGlvbihjb21wYXJlJCQxLCByZXNvcnQpIHtcbiAgICAgIGlmIChjbnQpIHtcbiAgICAgICAgZGF0YSA9IGRhdGEuZmlsdGVyKGZ1bmN0aW9uKHQpIHsgcmV0dXJuICFyZW1bJCQkMSh0KV07IH0pO1xuICAgICAgICByZW0gPSB7fTtcbiAgICAgICAgY250ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChyZXNvcnQgJiYgY29tcGFyZSQkMSkge1xuICAgICAgICBkYXRhLnNvcnQoY29tcGFyZSQkMSk7XG4gICAgICB9XG4gICAgICBpZiAoYWRkLmxlbmd0aCkge1xuICAgICAgICBkYXRhID0gY29tcGFyZSQkMVxuICAgICAgICAgID8gbWVyZ2UoY29tcGFyZSQkMSwgZGF0YSwgYWRkLnNvcnQoY29tcGFyZSQkMSkpXG4gICAgICAgICAgOiBkYXRhLmNvbmNhdChhZGQpO1xuICAgICAgICBhZGQgPSBbXTtcbiAgICAgIH1cbiAgICAgIHJldHVybiBkYXRhO1xuICAgIH1cbiAgfVxufTtcblxuLyoqXG4gKiBDb2xsZWN0cyBhbGwgZGF0YSB0dXBsZXMgdGhhdCBwYXNzIHRocm91Z2ggdGhpcyBvcGVyYXRvci5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbigqLCopOiBudW1iZXJ9IFtwYXJhbXMuc29ydF0gLSBBbiBvcHRpb25hbFxuICogICBjb21wYXJhdG9yIGZ1bmN0aW9uIGZvciBhZGRpdGlvbmFsbHkgc29ydGluZyB0aGUgY29sbGVjdGVkIHR1cGxlcy5cbiAqL1xuZnVuY3Rpb24gQ29sbGVjdChwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgW10sIHBhcmFtcyk7XG59XG5cbkNvbGxlY3QuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiQ29sbGVjdFwiLFxuICBcIm1ldGFkYXRhXCI6IHtcInNvdXJjZVwiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwic29ydFwiLCBcInR5cGVcIjogXCJjb21wYXJlXCIgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDExID0gaW5oZXJpdHMoQ29sbGVjdCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDExLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBvdXQgPSBwdWxzZS5mb3JrKHB1bHNlLkFMTCksXG4gICAgICBsaXN0ID0gU29ydGVkTGlzdCh0dXBsZWlkLCB0aGlzLnZhbHVlLCBvdXQubWF0ZXJpYWxpemUob3V0LkFERCkuYWRkKSxcbiAgICAgIHNvcnQgPSBfLnNvcnQsXG4gICAgICBtb2QgPSBwdWxzZS5jaGFuZ2VkKCkgfHwgKHNvcnQgJiZcbiAgICAgICAgICAgIChfLm1vZGlmaWVkKCdzb3J0JykgfHwgcHVsc2UubW9kaWZpZWQoc29ydC5maWVsZHMpKSk7XG5cbiAgb3V0LnZpc2l0KG91dC5SRU0sIGxpc3QucmVtb3ZlKTtcblxuICB0aGlzLm1vZGlmaWVkKG1vZCk7XG4gIHRoaXMudmFsdWUgPSBvdXQuc291cmNlID0gbGlzdC5kYXRhKHNvcnQsIG1vZCk7XG5cbiAgLy8gcHJvcGFnYXRlIHRyZWUgcm9vdCBpZiBkZWZpbmVkXG4gIGlmIChwdWxzZS5zb3VyY2UgJiYgcHVsc2Uuc291cmNlLnJvb3QpIHtcbiAgICB0aGlzLnZhbHVlLnJvb3QgPSBwdWxzZS5zb3VyY2Uucm9vdDtcbiAgfVxuXG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIGNvbXBhcmF0b3IgZnVuY3Rpb24uXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gcGFyYW1zLmZpZWxkcyAtIFRoZSBmaWVsZHMgdG8gY29tcGFyZS5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3BhcmFtcy5vcmRlcnNdIC0gVGhlIHNvcnQgb3JkZXJzLlxuICogICBFYWNoIGVudHJ5IHNob3VsZCBiZSBvbmUgb2YgXCJhc2NlbmRpbmdcIiAoZGVmYXVsdCkgb3IgXCJkZXNjZW5kaW5nXCIuXG4gKi9cbmZ1bmN0aW9uIENvbXBhcmUocGFyYW1zKSB7XG4gIE9wZXJhdG9yLmNhbGwodGhpcywgbnVsbCwgdXBkYXRlJDEsIHBhcmFtcyk7XG59XG5cbmluaGVyaXRzKENvbXBhcmUsIE9wZXJhdG9yKTtcblxuZnVuY3Rpb24gdXBkYXRlJDEoXykge1xuICByZXR1cm4gKHRoaXMudmFsdWUgJiYgIV8ubW9kaWZpZWQoKSlcbiAgICA/IHRoaXMudmFsdWVcbiAgICA6IGNvbXBhcmUoXy5maWVsZHMsIF8ub3JkZXJzKTtcbn1cblxuLyoqXG4gKiBDb3VudCByZWdleHAtZGVmaW5lZCBwYXR0ZXJuIG9jY3VycmVuY2VzIGluIGEgdGV4dCBmaWVsZC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGQgLSBBbiBhY2Nlc3NvciBmb3IgdGhlIHRleHQgZmllbGQuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5wYXR0ZXJuXSAtIFJlZ0V4cCBzdHJpbmcgZGVmaW5pbmcgdGhlIHRleHQgcGF0dGVybi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbcGFyYW1zLmNhc2VdIC0gT25lIG9mICdsb3dlcicsICd1cHBlcicgb3IgbnVsbCAobWl4ZWQpIGNhc2UuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5zdG9wd29yZHNdIC0gUmVnRXhwIHN0cmluZyBvZiB3b3JkcyB0byBpZ25vcmUuXG4gKi9cbmZ1bmN0aW9uIENvdW50UGF0dGVybihwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxuQ291bnRQYXR0ZXJuLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIkNvdW50UGF0dGVyblwiLFxuICBcIm1ldGFkYXRhXCI6IHtcImdlbmVyYXRlc1wiOiB0cnVlLCBcImNoYW5nZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiY2FzZVwiLCBcInR5cGVcIjogXCJlbnVtXCIsIFwidmFsdWVzXCI6IFtcInVwcGVyXCIsIFwibG93ZXJcIiwgXCJtaXhlZFwiXSwgXCJkZWZhdWx0XCI6IFwibWl4ZWRcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwicGF0dGVyblwiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJkZWZhdWx0XCI6IFwiW1xcXFx3XFxcIl0rXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcInN0b3B3b3Jkc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJkZWZhdWx0XCI6IFwiXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsIFwiZGVmYXVsdFwiOiBbXCJ0ZXh0XCIsIFwiY291bnRcIl0gfVxuICBdXG59O1xuXG5mdW5jdGlvbiB0b2tlbml6ZSh0ZXh0LCB0Y2FzZSwgbWF0Y2gpIHtcbiAgc3dpdGNoICh0Y2FzZSkge1xuICAgIGNhc2UgJ3VwcGVyJzogdGV4dCA9IHRleHQudG9VcHBlckNhc2UoKTsgYnJlYWs7XG4gICAgY2FzZSAnbG93ZXInOiB0ZXh0ID0gdGV4dC50b0xvd2VyQ2FzZSgpOyBicmVhaztcbiAgfVxuICByZXR1cm4gdGV4dC5tYXRjaChtYXRjaCk7XG59XG5cbnZhciBwcm90b3R5cGUkMTIgPSBpbmhlcml0cyhDb3VudFBhdHRlcm4sIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQxMi50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICBmdW5jdGlvbiBwcm9jZXNzKHVwZGF0ZSkge1xuICAgIHJldHVybiBmdW5jdGlvbih0dXBsZSkge1xuICAgICAgdmFyIHRva2VucyA9IHRva2VuaXplKGdldCh0dXBsZSksIF8uY2FzZSwgbWF0Y2gpIHx8IFtdLCB0O1xuICAgICAgZm9yICh2YXIgaT0wLCBuPXRva2Vucy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgICAgIGlmICghc3RvcC50ZXN0KHQgPSB0b2tlbnNbaV0pKSB1cGRhdGUodCk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIHZhciBpbml0ID0gdGhpcy5fcGFyYW1ldGVyQ2hlY2soXywgcHVsc2UpLFxuICAgICAgY291bnRzID0gdGhpcy5fY291bnRzLFxuICAgICAgbWF0Y2ggPSB0aGlzLl9tYXRjaCxcbiAgICAgIHN0b3AgPSB0aGlzLl9zdG9wLFxuICAgICAgZ2V0ID0gXy5maWVsZCxcbiAgICAgIGFzID0gXy5hcyB8fCBbJ3RleHQnLCAnY291bnQnXSxcbiAgICAgIGFkZCA9IHByb2Nlc3MoZnVuY3Rpb24odCkgeyBjb3VudHNbdF0gPSAxICsgKGNvdW50c1t0XSB8fCAwKTsgfSksXG4gICAgICByZW0gPSBwcm9jZXNzKGZ1bmN0aW9uKHQpIHsgY291bnRzW3RdIC09IDE7IH0pO1xuXG4gIGlmIChpbml0KSB7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuU09VUkNFLCBhZGQpO1xuICB9IGVsc2Uge1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLkFERCwgYWRkKTtcbiAgICBwdWxzZS52aXNpdChwdWxzZS5SRU0sIHJlbSk7XG4gIH1cblxuICByZXR1cm4gdGhpcy5fZmluaXNoKHB1bHNlLCBhcyk7IC8vIGdlbmVyYXRlIG91dHB1dCB0dXBsZXNcbn07XG5cbnByb3RvdHlwZSQxMi5fcGFyYW1ldGVyQ2hlY2sgPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgaW5pdCA9IGZhbHNlO1xuXG4gIGlmIChfLm1vZGlmaWVkKCdzdG9wd29yZHMnKSB8fCAhdGhpcy5fc3RvcCkge1xuICAgIHRoaXMuX3N0b3AgPSBuZXcgUmVnRXhwKCdeJyArIChfLnN0b3B3b3JkcyB8fCAnJykgKyAnJCcsICdpJyk7XG4gICAgaW5pdCA9IHRydWU7XG4gIH1cblxuICBpZiAoXy5tb2RpZmllZCgncGF0dGVybicpIHx8ICF0aGlzLl9tYXRjaCkge1xuICAgIHRoaXMuX21hdGNoID0gbmV3IFJlZ0V4cCgoXy5wYXR0ZXJuIHx8ICdbXFxcXHdcXCddKycpLCAnZycpO1xuICAgIGluaXQgPSB0cnVlO1xuICB9XG5cbiAgaWYgKF8ubW9kaWZpZWQoJ2ZpZWxkJykgfHwgcHVsc2UubW9kaWZpZWQoXy5maWVsZC5maWVsZHMpKSB7XG4gICAgaW5pdCA9IHRydWU7XG4gIH1cblxuICBpZiAoaW5pdCkgdGhpcy5fY291bnRzID0ge307XG4gIHJldHVybiBpbml0O1xufTtcblxucHJvdG90eXBlJDEyLl9maW5pc2ggPSBmdW5jdGlvbihwdWxzZSwgYXMpIHtcbiAgdmFyIGNvdW50cyA9IHRoaXMuX2NvdW50cyxcbiAgICAgIHR1cGxlcyA9IHRoaXMuX3R1cGxlcyB8fCAodGhpcy5fdHVwbGVzID0ge30pLFxuICAgICAgdGV4dCA9IGFzWzBdLFxuICAgICAgY291bnQgPSBhc1sxXSxcbiAgICAgIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKSxcbiAgICAgIHcsIHQsIGM7XG5cbiAgZm9yICh3IGluIGNvdW50cykge1xuICAgIHQgPSB0dXBsZXNbd107XG4gICAgYyA9IGNvdW50c1t3XSB8fCAwO1xuICAgIGlmICghdCAmJiBjKSB7XG4gICAgICB0dXBsZXNbd10gPSAodCA9IGluZ2VzdCh7fSkpO1xuICAgICAgdFt0ZXh0XSA9IHc7XG4gICAgICB0W2NvdW50XSA9IGM7XG4gICAgICBvdXQuYWRkLnB1c2godCk7XG4gICAgfSBlbHNlIGlmIChjID09PSAwKSB7XG4gICAgICBpZiAodCkgb3V0LnJlbS5wdXNoKHQpO1xuICAgICAgY291bnRzW3ddID0gbnVsbDtcbiAgICAgIHR1cGxlc1t3XSA9IG51bGw7XG4gICAgfSBlbHNlIGlmICh0W2NvdW50XSAhPT0gYykge1xuICAgICAgdFtjb3VudF0gPSBjO1xuICAgICAgb3V0Lm1vZC5wdXNoKHQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBvdXQubW9kaWZpZXMoYXMpO1xufTtcblxuLyoqXG4gKiBQZXJmb3JtIGEgY3Jvc3MtcHJvZHVjdCBvZiBhIHR1cGxlIHN0cmVhbSB3aXRoIGl0c2VsZi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOmJvb2xlYW59IFtwYXJhbXMuZmlsdGVyXSAtIEFuIG9wdGlvbmFsIGZpbHRlclxuICogICBmdW5jdGlvbiBmb3Igc2VsZWN0aXZlbHkgaW5jbHVkaW5nIHR1cGxlcyBpbiB0aGUgY3Jvc3MgcHJvZHVjdC5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3BhcmFtcy5hc10gLSBUaGUgbmFtZXMgb2YgdGhlIG91dHB1dCBmaWVsZHMuXG4gKi9cbmZ1bmN0aW9uIENyb3NzKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5Dcm9zcy5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJDcm9zc1wiLFxuICBcIm1ldGFkYXRhXCI6IHtcImdlbmVyYXRlc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZmlsdGVyXCIsIFwidHlwZVwiOiBcImV4cHJcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiwgXCJkZWZhdWx0XCI6IFtcImFcIiwgXCJiXCJdIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQxMyA9IGluaGVyaXRzKENyb3NzLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMTMudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFKSxcbiAgICAgIGRhdGEgPSB0aGlzLnZhbHVlLFxuICAgICAgYXMgPSBfLmFzIHx8IFsnYScsICdiJ10sXG4gICAgICBhID0gYXNbMF0sIGIgPSBhc1sxXSxcbiAgICAgIHJlc2V0ID0gIWRhdGFcbiAgICAgICAgICB8fCBwdWxzZS5jaGFuZ2VkKHB1bHNlLkFERF9SRU0pXG4gICAgICAgICAgfHwgXy5tb2RpZmllZCgnYXMnKVxuICAgICAgICAgIHx8IF8ubW9kaWZpZWQoJ2ZpbHRlcicpO1xuXG4gIGlmIChyZXNldCkge1xuICAgIGlmIChkYXRhKSBvdXQucmVtID0gZGF0YTtcbiAgICBkYXRhID0gcHVsc2UubWF0ZXJpYWxpemUocHVsc2UuU09VUkNFKS5zb3VyY2U7XG4gICAgb3V0LmFkZCA9IHRoaXMudmFsdWUgPSBjcm9zcyQxKGRhdGEsIGEsIGIsIF8uZmlsdGVyIHx8IHRydXRoeSk7XG4gIH0gZWxzZSB7XG4gICAgb3V0Lm1vZCA9IGRhdGE7XG4gIH1cblxuICBvdXQuc291cmNlID0gdGhpcy52YWx1ZTtcbiAgcmV0dXJuIG91dC5tb2RpZmllcyhhcyk7XG59O1xuXG5mdW5jdGlvbiBjcm9zcyQxKGlucHV0LCBhLCBiLCBmaWx0ZXIpIHtcbiAgdmFyIGRhdGEgPSBbXSxcbiAgICAgIHQgPSB7fSxcbiAgICAgIG4gPSBpbnB1dC5sZW5ndGgsXG4gICAgICBpID0gMCxcbiAgICAgIGosIGxlZnQ7XG5cbiAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgdFthXSA9IGxlZnQgPSBpbnB1dFtpXTtcbiAgICBmb3IgKGo9MDsgajxuOyArK2opIHtcbiAgICAgIHRbYl0gPSBpbnB1dFtqXTtcbiAgICAgIGlmIChmaWx0ZXIodCkpIHtcbiAgICAgICAgZGF0YS5wdXNoKGluZ2VzdCh0KSk7XG4gICAgICAgIHQgPSB7fTtcbiAgICAgICAgdFthXSA9IGxlZnQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGRhdGE7XG59XG5cbnZhciBEaXN0cmlidXRpb25zID0ge1xuICBrZGU6ICAgICByYW5kb21LREUsXG4gIG1peHR1cmU6IHJhbmRvbU1peHR1cmUsXG4gIG5vcm1hbDogIHJhbmRvbU5vcm1hbCxcbiAgdW5pZm9ybTogcmFuZG9tVW5pZm9ybVxufTtcblxudmFyIERJU1RSSUJVVElPTlMgPSAnZGlzdHJpYnV0aW9ucyc7XG52YXIgRlVOQ1RJT04gPSAnZnVuY3Rpb24nO1xudmFyIEZJRUxEID0gJ2ZpZWxkJztcblxuLyoqXG4gKiBQYXJzZSBhIHBhcmFtZXRlciBvYmplY3QgZm9yIGEgcHJvYmFiaWxpdHkgZGlzdHJpYnV0aW9uLlxuICogQHBhcmFtIHtvYmplY3R9IGRlZiAtIFRoZSBkaXN0cmlidXRpb24gcGFyYW1ldGVyIG9iamVjdC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKTpBcnJheTxvYmplY3Q+fSAtIEEgbWV0aG9kIGZvciByZXF1ZXN0aW5nXG4gKiAgIHNvdXJjZSBkYXRhLiBVc2VkIGZvciBkaXN0cmlidXRpb25zIChzdWNoIGFzIEtERSkgdGhhdFxuICogICByZXF1aXJlIHNhbXBsZSBkYXRhIHBvaW50cy4gVGhpcyBtZXRob2Qgd2lsbCBvbmx5IGJlXG4gKiAgIGludm9rZWQgaWYgdGhlICdmcm9tJyBwYXJhbWV0ZXIgZm9yIGEgdGFyZ2V0IGRhdGEgc291cmNlXG4gKiAgIGlzIG5vdCBwcm92aWRlZC4gVHlwaWNhbGx5IHRoaXMgbWV0aG9kIHJldHVybnMgYmFja2luZ1xuICogICBzb3VyY2UgZGF0YSBmb3IgYSBQdWxzZSBvYmplY3QuXG4gKiBAcmV0dXJuIHtvYmplY3R9IC0gVGhlIG91dHB1dCBkaXN0cmlidXRpb24gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBwYXJzZSQxKGRlZiwgZGF0YSkge1xuICB2YXIgZnVuYyA9IGRlZltGVU5DVElPTl07XG4gIGlmICghRGlzdHJpYnV0aW9ucy5oYXNPd25Qcm9wZXJ0eShmdW5jKSkge1xuICAgIGVycm9yJDEoJ1Vua25vd24gZGlzdHJpYnV0aW9uIGZ1bmN0aW9uOiAnICsgZnVuYyk7XG4gIH1cblxuICB2YXIgZCA9IERpc3RyaWJ1dGlvbnNbZnVuY10oKTtcblxuICBmb3IgKHZhciBuYW1lIGluIGRlZikge1xuICAgIC8vIGlmIGRhdGEgZmllbGQsIGV4dHJhY3QgdmFsdWVzXG4gICAgaWYgKG5hbWUgPT09IEZJRUxEKSB7XG4gICAgICBkLmRhdGEoKGRlZi5mcm9tIHx8IGRhdGEoKSkubWFwKGRlZltuYW1lXSkpO1xuICAgIH1cblxuICAgIC8vIGlmIGRpc3RyaWJ1dGlvbiBtaXh0dXJlLCByZWN1cnNlIHRvIHBhcnNlIGVhY2ggZGVmaW5pdGlvblxuICAgIGVsc2UgaWYgKG5hbWUgPT09IERJU1RSSUJVVElPTlMpIHtcbiAgICAgIGRbbmFtZV0oZGVmW25hbWVdLm1hcChmdW5jdGlvbihfKSB7IHJldHVybiBwYXJzZSQxKF8sIGRhdGEpOyB9KSk7XG4gICAgfVxuXG4gICAgLy8gb3RoZXJ3aXNlLCBzaW1wbHkgc2V0IHRoZSBwYXJhbWV0ZXJcbiAgICBlbHNlIGlmICh0eXBlb2YgZFtuYW1lXSA9PT0gRlVOQ1RJT04pIHtcbiAgICAgIGRbbmFtZV0oZGVmW25hbWVdKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZDtcbn1cblxuLyoqXG4gKiBHcmlkIHNhbXBsZSBwb2ludHMgZm9yIGEgcHJvYmFiaWxpdHkgZGVuc2l0eS4gR2l2ZW4gYSBkaXN0cmlidXRpb24gYW5kXG4gKiBhIHNhbXBsaW5nIGV4dGVudCwgd2lsbCBnZW5lcmF0ZSBwb2ludHMgc3VpdGFibGUgZm9yIHBsb3R0aW5nIGVpdGhlclxuICogUERGIChwcm9iYWJpbGl0eSBkZW5zaXR5IGZ1bmN0aW9uKSBvciBDREYgKGN1bXVsYXRpdmUgZGlzdHJpYnV0aW9uXG4gKiBmdW5jdGlvbikgY3VydmVzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zLmRpc3RyaWJ1dGlvbiAtIFRoZSBwcm9iYWJpbGl0eSBkaXN0cmlidXRpb24uIFRoaXNcbiAqICAgaXMgYW4gb2JqZWN0IHBhcmFtZXRlciBkZXBlbmRlbnQgb24gdGhlIGRpc3RyaWJ1dGlvbiB0eXBlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMubWV0aG9kPSdwZGYnXSAtIFRoZSBkaXN0cmlidXRpb24gbWV0aG9kIHRvIHNhbXBsZS5cbiAqICAgT25lIG9mICdwZGYnIG9yICdjZGYnLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBbcGFyYW1zLmV4dGVudF0gLSBUaGUgW21pbiwgbWF4XSBleHRlbnQgb3ZlciB3aGljaFxuICogICB0byBzYW1wbGUgdGhlIGRpc3RyaWJ1dGlvbi4gVGhpcyBhcmd1bWVudCBpcyByZXF1aXJlZCBpbiBtb3N0IGNhc2VzLCBidXRcbiAqICAgY2FuIGJlIG9taXR0ZWQgaWYgdGhlIGRpc3RyaWJ1dGlvbiAoZS5nLiwgJ2tkZScpIHN1cHBvcnRzIGEgJ2RhdGEnIG1ldGhvZFxuICogICB0aGF0IHJldHVybnMgbnVtZXJpY2FsIHNhbXBsZSBwb2ludHMgZnJvbSB3aGljaCB0aGUgZXh0ZW50IGNhbiBiZSBkZWR1Y2VkLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJhbXMuc3RlcHM9MTAwXSAtIFRoZSBudW1iZXIgb2Ygc2FtcGxpbmcgc3RlcHMuXG4gKi9cbmZ1bmN0aW9uIERlbnNpdHkocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbnZhciBkaXN0cmlidXRpb25zID0gW1xuICB7XG4gICAgXCJrZXlcIjoge1wiZnVuY3Rpb25cIjogXCJub3JtYWxcIn0sXG4gICAgXCJwYXJhbXNcIjogW1xuICAgICAgeyBcIm5hbWVcIjogXCJtZWFuXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9LFxuICAgICAgeyBcIm5hbWVcIjogXCJzdGRldlwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDEgfVxuICAgIF1cbiAgfSxcbiAge1xuICAgIFwia2V5XCI6IHtcImZ1bmN0aW9uXCI6IFwidW5pZm9ybVwifSxcbiAgICBcInBhcmFtc1wiOiBbXG4gICAgICB7IFwibmFtZVwiOiBcIm1pblwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICAgIHsgXCJuYW1lXCI6IFwibWF4XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMSB9XG4gICAgXVxuICB9LFxuICB7XG4gICAgXCJrZXlcIjoge1wiZnVuY3Rpb25cIjogXCJrZGVcIn0sXG4gICAgXCJwYXJhbXNcIjogW1xuICAgICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcInJlcXVpcmVkXCI6IHRydWUgfSxcbiAgICAgIHsgXCJuYW1lXCI6IFwiZnJvbVwiLCBcInR5cGVcIjogXCJkYXRhXCIgfSxcbiAgICAgIHsgXCJuYW1lXCI6IFwiYmFuZHdpZHRoXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9XG4gICAgXVxuICB9XG5dO1xuXG52YXIgbWl4dHVyZSA9IHtcbiAgXCJrZXlcIjoge1wiZnVuY3Rpb25cIjogXCJtaXh0dXJlXCJ9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJkaXN0cmlidXRpb25zXCIsIFwidHlwZVwiOiBcInBhcmFtXCIsIFwiYXJyYXlcIjogdHJ1ZSxcbiAgICAgIFwicGFyYW1zXCI6IGRpc3RyaWJ1dGlvbnMgfSxcbiAgICB7IFwibmFtZVwiOiBcIndlaWdodHNcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSB9XG4gIF1cbn07XG5cbkRlbnNpdHkuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiRGVuc2l0eVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcImdlbmVyYXRlc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZXh0ZW50XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIgfSxcbiAgICB7IFwibmFtZVwiOiBcInN0ZXBzXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMTAwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJtZXRob2RcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiZGVmYXVsdFwiOiBcInBkZlwiLFxuICAgICAgXCJ2YWx1ZXNcIjogW1wicGRmXCIsIFwiY2RmXCJdIH0sXG4gICAgeyBcIm5hbWVcIjogXCJkaXN0cmlidXRpb25cIiwgXCJ0eXBlXCI6IFwicGFyYW1cIixcbiAgICAgIFwicGFyYW1zXCI6IGRpc3RyaWJ1dGlvbnMuY29uY2F0KG1peHR1cmUpIH0sXG4gICAgeyBcIm5hbWVcIjogXCJhc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJhcnJheVwiOiB0cnVlLFxuICAgICAgXCJkZWZhdWx0XCI6IFtcInZhbHVlXCIsIFwiZGVuc2l0eVwiXSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMTQgPSBpbmhlcml0cyhEZW5zaXR5LCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMTQudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKTtcblxuICBpZiAoIXRoaXMudmFsdWUgfHwgcHVsc2UuY2hhbmdlZCgpIHx8IF8ubW9kaWZpZWQoKSkge1xuICAgIHZhciBkaXN0ID0gcGFyc2UkMShfLmRpc3RyaWJ1dGlvbiwgc291cmNlKHB1bHNlKSksXG4gICAgICAgIG1ldGhvZCA9IF8ubWV0aG9kIHx8ICdwZGYnO1xuXG4gICAgaWYgKG1ldGhvZCAhPT0gJ3BkZicgJiYgbWV0aG9kICE9PSAnY2RmJykge1xuICAgICAgZXJyb3IkMSgnSW52YWxpZCBkZW5zaXR5IG1ldGhvZDogJyArIG1ldGhvZCk7XG4gICAgfVxuICAgIGlmICghXy5leHRlbnQgJiYgIWRpc3QuZGF0YSkge1xuICAgICAgZXJyb3IkMSgnTWlzc2luZyBkZW5zaXR5IGV4dGVudCBwYXJhbWV0ZXIuJyk7XG4gICAgfVxuICAgIG1ldGhvZCA9IGRpc3RbbWV0aG9kXTtcblxuICAgIHZhciBhcyA9IF8uYXMgfHwgWyd2YWx1ZScsICdkZW5zaXR5J10sXG4gICAgICAgIGRvbWFpbiA9IF8uZXh0ZW50IHx8IGV4dGVudChkaXN0LmRhdGEoKSksXG4gICAgICAgIHN0ZXAgPSAoZG9tYWluWzFdIC0gZG9tYWluWzBdKSAvIChfLnN0ZXBzIHx8IDEwMCksXG4gICAgICAgIHZhbHVlcyA9IHNlcXVlbmNlKGRvbWFpblswXSwgZG9tYWluWzFdICsgc3RlcC8yLCBzdGVwKVxuICAgICAgICAgIC5tYXAoZnVuY3Rpb24odikge1xuICAgICAgICAgICAgdmFyIHR1cGxlID0ge307XG4gICAgICAgICAgICB0dXBsZVthc1swXV0gPSB2O1xuICAgICAgICAgICAgdHVwbGVbYXNbMV1dID0gbWV0aG9kKHYpO1xuICAgICAgICAgICAgcmV0dXJuIGluZ2VzdCh0dXBsZSk7XG4gICAgICAgICAgfSk7XG5cbiAgICBpZiAodGhpcy52YWx1ZSkgb3V0LnJlbSA9IHRoaXMudmFsdWU7XG4gICAgdGhpcy52YWx1ZSA9IG91dC5hZGQgPSBvdXQuc291cmNlID0gdmFsdWVzO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbmZ1bmN0aW9uIHNvdXJjZShwdWxzZSkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7IHJldHVybiBwdWxzZS5tYXRlcmlhbGl6ZShwdWxzZS5TT1VSQ0UpLnNvdXJjZTsgfTtcbn1cblxuLyoqXG4gKiBDb21wdXRlcyBleHRlbnRzIChtaW4vbWF4KSBmb3IgYSBkYXRhIGZpZWxkLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy5maWVsZCAtIFRoZSBmaWVsZCBvdmVyIHdoaWNoIHRvIGNvbXB1dGUgZXh0ZW5kcy5cbiAqL1xuZnVuY3Rpb24gRXh0ZW50KHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBbK0luZmluaXR5LCAtSW5maW5pdHldLCBwYXJhbXMpO1xufVxuXG5FeHRlbnQuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiRXh0ZW50XCIsXG4gIFwibWV0YWRhdGFcIjoge30sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMTUgPSBpbmhlcml0cyhFeHRlbnQsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQxNS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgZXh0ZW50ID0gdGhpcy52YWx1ZSxcbiAgICAgIGZpZWxkJCQxID0gXy5maWVsZCxcbiAgICAgIG1pbiA9IGV4dGVudFswXSxcbiAgICAgIG1heCA9IGV4dGVudFsxXSxcbiAgICAgIGZsYWcgPSBwdWxzZS5BREQsXG4gICAgICBtb2Q7XG5cbiAgbW9kID0gcHVsc2UuY2hhbmdlZCgpXG4gICAgIHx8IHB1bHNlLm1vZGlmaWVkKGZpZWxkJCQxLmZpZWxkcylcbiAgICAgfHwgXy5tb2RpZmllZCgnZmllbGQnKTtcblxuICBpZiAobW9kKSB7XG4gICAgZmxhZyA9IHB1bHNlLlNPVVJDRTtcbiAgICBtaW4gPSArSW5maW5pdHk7XG4gICAgbWF4ID0gLUluZmluaXR5O1xuICB9XG5cbiAgcHVsc2UudmlzaXQoZmxhZywgZnVuY3Rpb24odCkge1xuICAgIHZhciB2ID0gZmllbGQkJDEodCk7XG4gICAgaWYgKHYgIT0gbnVsbCkge1xuICAgICAgLy8gY29lcmNlIHRvIG51bWJlclxuICAgICAgdiA9ICt2O1xuICAgICAgLy8gTmFOcyB3aWxsIGZhaWwgYWxsIGNvbXBhcmlzb25zIVxuICAgICAgaWYgKHYgPCBtaW4pIG1pbiA9IHY7XG4gICAgICBpZiAodiA+IG1heCkgbWF4ID0gdjtcbiAgICB9XG4gIH0pO1xuXG4gIHRoaXMudmFsdWUgPSBbbWluLCBtYXhdO1xufTtcblxuLyoqXG4gKiBQcm92aWRlcyBhIGJyaWRnZSBiZXR3ZWVuIGEgcGFyZW50IHRyYW5zZm9ybSBhbmQgYSB0YXJnZXQgc3ViZmxvdyB0aGF0XG4gKiBjb25zdW1lcyBvbmx5IGEgc3Vic2V0IG9mIHRoZSB0dXBsZXMgdGhhdCBwYXNzIHRocm91Z2ggdGhlIHBhcmVudC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtQdWxzZX0gcHVsc2UgLSBBIHB1bHNlIHRvIHVzZSBhcyB0aGUgdmFsdWUgb2YgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7VHJhbnNmb3JtfSBwYXJlbnQgLSBUaGUgcGFyZW50IHRyYW5zZm9ybSAodHlwaWNhbGx5IGEgRmFjZXQgaW5zdGFuY2UpLlxuICogQHBhcmFtIHtUcmFuc2Zvcm19IHRhcmdldCAtIEEgdHJhbnNmb3JtIHRoYXQgcmVjZWl2ZXMgdGhlIHN1YmZsb3cgb2YgdHVwbGVzLlxuICovXG5mdW5jdGlvbiBTdWJmbG93KHB1bHNlLCBwYXJlbnQpIHtcbiAgT3BlcmF0b3IuY2FsbCh0aGlzLCBwdWxzZSk7XG4gIHRoaXMucGFyZW50ID0gcGFyZW50O1xufVxuXG52YXIgcHJvdG90eXBlJDE3ID0gaW5oZXJpdHMoU3ViZmxvdywgT3BlcmF0b3IpO1xuXG5wcm90b3R5cGUkMTcuY29ubmVjdCA9IGZ1bmN0aW9uKHRhcmdldCkge1xuICB0aGlzLnRhcmdldHMoKS5hZGQodGFyZ2V0KTtcbiAgcmV0dXJuICh0YXJnZXQuc291cmNlID0gdGhpcyk7XG59O1xuXG4vKipcbiAqIEFkZCBhbiAnYWRkJyB0dXBsZSB0byB0aGUgc3ViZmxvdyBwdWxzZS5cbiAqIEBwYXJhbSB7VHVwbGV9IHQgLSBUaGUgdHVwbGUgYmVpbmcgYWRkZWQuXG4gKi9cbnByb3RvdHlwZSQxNy5hZGQgPSBmdW5jdGlvbih0KSB7XG4gIHRoaXMudmFsdWUuYWRkLnB1c2godCk7XG59O1xuXG4vKipcbiAqIEFkZCBhICdyZW0nIHR1cGxlIHRvIHRoZSBzdWJmbG93IHB1bHNlLlxuICogQHBhcmFtIHtUdXBsZX0gdCAtIFRoZSB0dXBsZSBiZWluZyByZW1vdmVkLlxuICovXG5wcm90b3R5cGUkMTcucmVtID0gZnVuY3Rpb24odCkge1xuICB0aGlzLnZhbHVlLnJlbS5wdXNoKHQpO1xufTtcblxuLyoqXG4gKiBBZGQgYSAnbW9kJyB0dXBsZSB0byB0aGUgc3ViZmxvdyBwdWxzZS5cbiAqIEBwYXJhbSB7VHVwbGV9IHQgLSBUaGUgdHVwbGUgYmVpbmcgbW9kaWZpZWQuXG4gKi9cbnByb3RvdHlwZSQxNy5tb2QgPSBmdW5jdGlvbih0KSB7XG4gIHRoaXMudmFsdWUubW9kLnB1c2godCk7XG59O1xuXG4vKipcbiAqIFJlLWluaXRpYWxpemUgdGhpcyBvcGVyYXRvcidzIHB1bHNlIHZhbHVlLlxuICogQHBhcmFtIHtQdWxzZX0gcHVsc2UgLSBUaGUgcHVsc2UgdG8gY29weSBmcm9tLlxuICogQHNlZSBQdWxzZS5pbml0XG4gKi9cbnByb3RvdHlwZSQxNy5pbml0ID0gZnVuY3Rpb24ocHVsc2UpIHtcbiAgdGhpcy52YWx1ZS5pbml0KHB1bHNlLCBwdWxzZS5OT19TT1VSQ0UpO1xufTtcblxuLyoqXG4gKiBFdmFsdWF0ZSB0aGlzIG9wZXJhdG9yLiBUaGlzIG1ldGhvZCBvdmVycmlkZXMgdGhlXG4gKiBkZWZhdWx0IGJlaGF2aW9yIHRvIHNpbXBseSByZXR1cm4gdGhlIGNvbnRhaW5lZCBwdWxzZSB2YWx1ZS5cbiAqIEByZXR1cm4ge1B1bHNlfVxuICovXG5wcm90b3R5cGUkMTcuZXZhbHVhdGUgPSBmdW5jdGlvbigpIHtcbiAgLy8gYXNzZXJ0OiB0aGlzLnZhbHVlLnN0YW1wID09PSBwdWxzZS5zdGFtcFxuICByZXR1cm4gdGhpcy52YWx1ZTtcbn07XG5cbi8qKlxuICogRmFjZXRzIGEgZGF0YWZsb3cgaW50byBhIHNldCBvZiBzdWJmbG93cyBiYXNlZCBvbiBhIGtleS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihEYXRhZmxvdywgc3RyaW5nKTogT3BlcmF0b3J9IHBhcmFtcy5zdWJmbG93IC0gQSBmdW5jdGlvblxuICogICB0aGF0IGdlbmVyYXRlcyBhIHN1YmZsb3cgb2Ygb3BlcmF0b3JzIGFuZCByZXR1cm5zIGl0cyByb290IG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMua2V5IC0gVGhlIGtleSBmaWVsZCB0byBmYWNldCBieS5cbiAqL1xuZnVuY3Rpb24gRmFjZXQocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIHt9LCBwYXJhbXMpO1xuICB0aGlzLl9rZXlzID0gZmFzdG1hcCgpOyAvLyBjYWNoZSBwcmV2aW91c2x5IGNhbGN1bGF0ZWQga2V5IHZhbHVlc1xuXG4gIC8vIGtlZXAgdHJhY2sgb2YgYWN0aXZlIHN1YmZsb3dzLCB1c2UgYXMgdGFyZ2V0cyBhcnJheSBmb3IgbGlzdGVuZXJzXG4gIC8vIHRoaXMgYWxsb3dzIHVzIHRvIGxpbWl0IHByb3BhZ2F0aW9uIHRvIG9ubHkgdXBkYXRlZCBzdWJmbG93c1xuICB2YXIgYSA9IHRoaXMuX3RhcmdldHMgPSBbXTtcbiAgYS5hY3RpdmUgPSAwO1xuICBhLmZvckVhY2ggPSBmdW5jdGlvbihmKSB7XG4gICAgZm9yICh2YXIgaT0wLCBuPWEuYWN0aXZlOyBpPG47ICsraSkgZihhW2ldLCBpLCBhKTtcbiAgfTtcbn1cblxudmFyIHByb3RvdHlwZSQxNiA9IGluaGVyaXRzKEZhY2V0LCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMTYuYWN0aXZhdGUgPSBmdW5jdGlvbihmbG93KSB7XG4gIHRoaXMuX3RhcmdldHNbdGhpcy5fdGFyZ2V0cy5hY3RpdmUrK10gPSBmbG93O1xufTtcblxucHJvdG90eXBlJDE2LnN1YmZsb3cgPSBmdW5jdGlvbihrZXkkJDEsIGZsb3csIHB1bHNlLCBwYXJlbnQpIHtcbiAgdmFyIGZsb3dzID0gdGhpcy52YWx1ZSxcbiAgICAgIHNmID0gZmxvd3MuaGFzT3duUHJvcGVydHkoa2V5JCQxKSAmJiBmbG93c1trZXkkJDFdLFxuICAgICAgZGYsIHA7XG5cbiAgaWYgKCFzZikge1xuICAgIHAgPSBwYXJlbnQgfHwgKHAgPSB0aGlzLl9ncm91cFtrZXkkJDFdKSAmJiBwLnR1cGxlO1xuICAgIGRmID0gcHVsc2UuZGF0YWZsb3c7XG4gICAgc2YgPSBkZi5hZGQobmV3IFN1YmZsb3cocHVsc2UuZm9yayhwdWxzZS5OT19TT1VSQ0UpLCB0aGlzKSlcbiAgICAgIC5jb25uZWN0KGZsb3coZGYsIGtleSQkMSwgcCkpO1xuICAgIGZsb3dzW2tleSQkMV0gPSBzZjtcbiAgICB0aGlzLmFjdGl2YXRlKHNmKTtcbiAgfSBlbHNlIGlmIChzZi52YWx1ZS5zdGFtcCA8IHB1bHNlLnN0YW1wKSB7XG4gICAgc2YuaW5pdChwdWxzZSk7XG4gICAgdGhpcy5hY3RpdmF0ZShzZik7XG4gIH1cblxuICByZXR1cm4gc2Y7XG59O1xuXG5wcm90b3R5cGUkMTYudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGRmID0gcHVsc2UuZGF0YWZsb3csXG4gICAgICBzZWxmID0gdGhpcyxcbiAgICAgIGtleSQkMSA9IF8ua2V5LFxuICAgICAgZmxvdyA9IF8uc3ViZmxvdyxcbiAgICAgIGNhY2hlID0gdGhpcy5fa2V5cyxcbiAgICAgIHJla2V5ID0gXy5tb2RpZmllZCgna2V5Jyk7XG5cbiAgZnVuY3Rpb24gc3ViZmxvdyhrZXkkJDEpIHtcbiAgICByZXR1cm4gc2VsZi5zdWJmbG93KGtleSQkMSwgZmxvdywgcHVsc2UpO1xuICB9XG5cbiAgdGhpcy5fZ3JvdXAgPSBfLmdyb3VwIHx8IHt9O1xuICB0aGlzLl90YXJnZXRzLmFjdGl2ZSA9IDA7IC8vIHJlc2V0IGxpc3Qgb2YgYWN0aXZlIHN1YmZsb3dzXG5cbiAgcHVsc2UudmlzaXQocHVsc2UuUkVNLCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGlkJCQxID0gdHVwbGVpZCh0KSxcbiAgICAgICAgayA9IGNhY2hlLmdldChpZCQkMSk7XG4gICAgaWYgKGsgIT09IHVuZGVmaW5lZCkge1xuICAgICAgY2FjaGUuZGVsZXRlKGlkJCQxKTtcbiAgICAgIHN1YmZsb3coaykucmVtKHQpO1xuICAgIH1cbiAgfSk7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGsgPSBrZXkkJDEodCk7XG4gICAgY2FjaGUuc2V0KHR1cGxlaWQodCksIGspO1xuICAgIHN1YmZsb3coaykuYWRkKHQpO1xuICB9KTtcblxuICBpZiAocmVrZXkgfHwgcHVsc2UubW9kaWZpZWQoa2V5JCQxLmZpZWxkcykpIHtcbiAgICBwdWxzZS52aXNpdChwdWxzZS5NT0QsIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBpZCQkMSA9IHR1cGxlaWQodCksXG4gICAgICAgICAgazAgPSBjYWNoZS5nZXQoaWQkJDEpLFxuICAgICAgICAgIGsxID0ga2V5JCQxKHQpO1xuICAgICAgaWYgKGswID09PSBrMSkge1xuICAgICAgICBzdWJmbG93KGsxKS5tb2QodCk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjYWNoZS5zZXQoaWQkJDEsIGsxKTtcbiAgICAgICAgc3ViZmxvdyhrMCkucmVtKHQpO1xuICAgICAgICBzdWJmbG93KGsxKS5hZGQodCk7XG4gICAgICB9XG4gICAgfSk7XG4gIH0gZWxzZSBpZiAocHVsc2UuY2hhbmdlZChwdWxzZS5NT0QpKSB7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuTU9ELCBmdW5jdGlvbih0KSB7XG4gICAgICBzdWJmbG93KGNhY2hlLmdldCh0dXBsZWlkKHQpKSkubW9kKHQpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKHJla2V5KSB7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuUkVGTE9XLCBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgaWQkJDEgPSB0dXBsZWlkKHQpLFxuICAgICAgICAgIGswID0gY2FjaGUuZ2V0KGlkJCQxKSxcbiAgICAgICAgICBrMSA9IGtleSQkMSh0KTtcbiAgICAgIGlmIChrMCAhPT0gazEpIHtcbiAgICAgICAgY2FjaGUuc2V0KGlkJCQxLCBrMSk7XG4gICAgICAgIHN1YmZsb3coazApLnJlbSh0KTtcbiAgICAgICAgc3ViZmxvdyhrMSkuYWRkKHQpO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKGNhY2hlLmVtcHR5ID4gZGYuY2xlYW5UaHJlc2hvbGQpIGRmLnJ1bkFmdGVyKGNhY2hlLmNsZWFuKTtcbiAgcmV0dXJuIHB1bHNlO1xufTtcblxuLyoqXG4gKiBHZW5lcmF0ZXMgb25lIG9yIG1vcmUgZmllbGQgYWNjZXNzb3IgZnVuY3Rpb25zLlxuICogSWYgdGhlICduYW1lJyBwYXJhbWV0ZXIgaXMgYW4gYXJyYXksIGFuIGFycmF5IG9mIGZpZWxkIGFjY2Vzc29yc1xuICogd2lsbCBiZSBjcmVhdGVkIGFuZCB0aGUgJ2FzJyBwYXJhbWV0ZXIgd2lsbCBiZSBpZ25vcmVkLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLm5hbWUgLSBUaGUgZmllbGQgbmFtZShzKSB0byBhY2Nlc3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLmFzIC0gVGhlIGFjY2Vzc29yIGZ1bmN0aW9uIG5hbWUuXG4gKi9cbmZ1bmN0aW9uIEZpZWxkKHBhcmFtcykge1xuICBPcGVyYXRvci5jYWxsKHRoaXMsIG51bGwsIHVwZGF0ZSQyLCBwYXJhbXMpO1xufVxuXG5pbmhlcml0cyhGaWVsZCwgT3BlcmF0b3IpO1xuXG5mdW5jdGlvbiB1cGRhdGUkMihfKSB7XG4gIHJldHVybiAodGhpcy52YWx1ZSAmJiAhXy5tb2RpZmllZCgpKSA/IHRoaXMudmFsdWVcbiAgICA6IGlzQXJyYXkoXy5uYW1lKSA/IGFycmF5KF8ubmFtZSkubWFwKGZ1bmN0aW9uKGYpIHsgcmV0dXJuIGZpZWxkKGYpOyB9KVxuICAgIDogZmllbGQoXy5uYW1lLCBfLmFzKTtcbn1cblxuLyoqXG4gKiBGaWx0ZXJzIGRhdGEgdHVwbGVzIGFjY29yZGluZyB0byBhIHByZWRpY2F0ZSBmdW5jdGlvbi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZXhwciAtIFRoZSBwcmVkaWNhdGUgZXhwcmVzc2lvbiBmdW5jdGlvblxuICogICB0aGF0IGRldGVybWluZXMgYSB0dXBsZSdzIGZpbHRlciBzdGF0dXMuIFRydXRoeSB2YWx1ZXMgcGFzcyB0aGUgZmlsdGVyLlxuICovXG5mdW5jdGlvbiBGaWx0ZXIocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIGZhc3RtYXAoKSwgcGFyYW1zKTtcbn1cblxuRmlsdGVyLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIkZpbHRlclwiLFxuICBcIm1ldGFkYXRhXCI6IHtcImNoYW5nZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImV4cHJcIiwgXCJ0eXBlXCI6IFwiZXhwclwiLCBcInJlcXVpcmVkXCI6IHRydWUgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDE4ID0gaW5oZXJpdHMoRmlsdGVyLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMTgudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGRmID0gcHVsc2UuZGF0YWZsb3csXG4gICAgICBjYWNoZSA9IHRoaXMudmFsdWUsIC8vIGNhY2hlIGlkcyBvZiBmaWx0ZXJlZCB0dXBsZXNcbiAgICAgIG91dHB1dCA9IHB1bHNlLmZvcmsoKSxcbiAgICAgIGFkZCA9IG91dHB1dC5hZGQsXG4gICAgICByZW0gPSBvdXRwdXQucmVtLFxuICAgICAgbW9kID0gb3V0cHV0Lm1vZCxcbiAgICAgIHRlc3QgPSBfLmV4cHIsXG4gICAgICBpc01vZCA9IHRydWU7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuUkVNLCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGlkJCQxID0gdHVwbGVpZCh0KTtcbiAgICBpZiAoIWNhY2hlLmhhcyhpZCQkMSkpIHJlbS5wdXNoKHQpO1xuICAgIGVsc2UgY2FjaGUuZGVsZXRlKGlkJCQxKTtcbiAgfSk7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbih0KSB7XG4gICAgaWYgKHRlc3QodCwgXykpIGFkZC5wdXNoKHQpO1xuICAgIGVsc2UgY2FjaGUuc2V0KHR1cGxlaWQodCksIDEpO1xuICB9KTtcblxuICBmdW5jdGlvbiByZXZpc2l0KHQpIHtcbiAgICB2YXIgaWQkJDEgPSB0dXBsZWlkKHQpLFxuICAgICAgICBiID0gdGVzdCh0LCBfKSxcbiAgICAgICAgcyA9IGNhY2hlLmdldChpZCQkMSk7XG4gICAgaWYgKGIgJiYgcykge1xuICAgICAgY2FjaGUuZGVsZXRlKGlkJCQxKTtcbiAgICAgIGFkZC5wdXNoKHQpO1xuICAgIH0gZWxzZSBpZiAoIWIgJiYgIXMpIHtcbiAgICAgIGNhY2hlLnNldChpZCQkMSwgMSk7XG4gICAgICByZW0ucHVzaCh0KTtcbiAgICB9IGVsc2UgaWYgKGlzTW9kICYmIGIgJiYgIXMpIHtcbiAgICAgIG1vZC5wdXNoKHQpO1xuICAgIH1cbiAgfVxuXG4gIHB1bHNlLnZpc2l0KHB1bHNlLk1PRCwgcmV2aXNpdCk7XG5cbiAgaWYgKF8ubW9kaWZpZWQoKSkge1xuICAgIGlzTW9kID0gZmFsc2U7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuUkVGTE9XLCByZXZpc2l0KTtcbiAgfVxuXG4gIGlmIChjYWNoZS5lbXB0eSA+IGRmLmNsZWFuVGhyZXNob2xkKSBkZi5ydW5BZnRlcihjYWNoZS5jbGVhbik7XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG4vLyB1c2UgZWl0aGVyIHByb3ZpZGVkIGFsaWFzIG9yIGFjY2Vzc29yIGZpZWxkIG5hbWVcbmZ1bmN0aW9uIGZpZWxkTmFtZXMoZmllbGRzLCBhcykge1xuICBpZiAoIWZpZWxkcykgcmV0dXJuIG51bGw7XG4gIHJldHVybiBmaWVsZHMubWFwKGZ1bmN0aW9uKGYsIGkpIHtcbiAgICByZXR1cm4gYXNbaV0gfHwgYWNjZXNzb3JOYW1lKGYpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBGbGF0dGVucyBhcnJheS10eXBlZCBmaWVsZCB2YWx1ZXMgaW50byBuZXcgZGF0YSBvYmplY3RzLlxuICogSWYgbXVsdGlwbGUgZmllbGRzIGFyZSBzcGVjaWZpZWQsIHRoZXkgYXJlIHRyZWF0ZWQgYXMgcGFyYWxsZWwgYXJyYXlzLFxuICogd2l0aCBvdXRwdXQgdmFsdWVzIGluY2x1ZGVkIGZvciBlYWNoIG1hdGNoaW5nIGluZGV4IChvciBudWxsIGlmIG1pc3NpbmcpLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge0FycmF5PGZ1bmN0aW9uKG9iamVjdCk6ICo+fSBwYXJhbXMuZmllbGRzIC0gQW4gYXJyYXkgb2YgZmllbGRcbiAqICAgYWNjZXNzb3JzIGZvciB0aGUgdHVwbGUgZmllbGRzIHRoYXQgc2hvdWxkIGJlIGZsYXR0ZW5lZC5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3BhcmFtcy5hc10gLSBPdXRwdXQgZmllbGQgbmFtZXMgZm9yIGZsYXR0ZW5lZFxuICogICBhcnJheSBmaWVsZHMuIEFueSB1bnNwZWNpZmllZCBmaWVsZHMgd2lsbCB1c2UgdGhlIGZpZWxkIG5hbWUgcHJvdmlkZWRcbiAqICAgYnkgdGhlIGZpZWxkcyBhY2Nlc3NvcnMuXG4gKi9cbmZ1bmN0aW9uIEZsYXR0ZW4ocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIFtdLCBwYXJhbXMpO1xufVxuXG5GbGF0dGVuLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIkZsYXR0ZW5cIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJnZW5lcmF0ZXNcIjogdHJ1ZSwgXCJzb3VyY2VcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkc1wiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcImFycmF5XCI6IHRydWUsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMTkgPSBpbmhlcml0cyhGbGF0dGVuLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMTkudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFKSxcbiAgICAgIGZpZWxkcyA9IF8uZmllbGRzLFxuICAgICAgYXMgPSBmaWVsZE5hbWVzKGZpZWxkcywgXy5hcyB8fCBbXSksXG4gICAgICBtID0gYXMubGVuZ3RoO1xuXG4gIC8vIHJlbW92ZSBhbnkgcHJldmlvdXMgcmVzdWx0c1xuICBvdXQucmVtID0gdGhpcy52YWx1ZTtcblxuICAvLyBnZW5lcmF0ZSBmbGF0dGVuZWQgdHVwbGVzXG4gIHB1bHNlLnZpc2l0KHB1bHNlLlNPVVJDRSwgZnVuY3Rpb24odCkge1xuICAgIHZhciBhcnJheXMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uKGYpIHsgcmV0dXJuIGYodCk7IH0pLFxuICAgICAgICBtYXhsZW4gPSBhcnJheXMucmVkdWNlKGZ1bmN0aW9uKGwsIGEpIHsgcmV0dXJuIE1hdGgubWF4KGwsIGEubGVuZ3RoKTsgfSwgMCksXG4gICAgICAgIGkgPSAwLCBqLCBkLCB2O1xuXG4gICAgZm9yICg7IGk8bWF4bGVuOyArK2kpIHtcbiAgICAgIGQgPSBkZXJpdmUodCk7XG4gICAgICBmb3IgKGo9MDsgajxtOyArK2opIHtcbiAgICAgICAgZFthc1tqXV0gPSAodiA9IGFycmF5c1tqXVtpXSkgPT0gbnVsbCA/IG51bGwgOiB2O1xuICAgICAgfVxuICAgICAgb3V0LmFkZC5wdXNoKGQpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy52YWx1ZSA9IG91dC5zb3VyY2UgPSBvdXQuYWRkO1xuICByZXR1cm4gb3V0Lm1vZGlmaWVzKGFzKTtcbn07XG5cbi8qKlxuICogRm9sZHMgb25lIG1vcmUgdHVwbGUgZmllbGRzIGludG8gbXVsdGlwbGUgdHVwbGVzIGluIHdoaWNoIHRoZSBmaWVsZFxuICogbmFtZSBhbmQgdmFsdWVzIGFyZSBhdmFpbGFibGUgdW5kZXIgbmV3ICdrZXknIGFuZCAndmFsdWUnIGZpZWxkcy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGRzIC0gQW4gYXJyYXkgb2YgZmllbGQgYWNjZXNzb3JzXG4gKiAgIGZvciB0aGUgdHVwbGUgZmllbGRzIHRoYXQgc2hvdWxkIGJlIGZvbGRlZC5cbiAqIEBwYXJhbSB7QXJyYXk8c3RyaW5nPn0gW3BhcmFtcy5hc10gLSBPdXRwdXQgZmllbGQgbmFtZXMgZm9yIGZvbGRlZCBrZXlcbiAqICAgYW5kIHZhbHVlIGZpZWxkcywgZGVmYXVsdHMgdG8gWydrZXknLCAndmFsdWUnXS5cbiAqL1xuZnVuY3Rpb24gRm9sZChwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgW10sIHBhcmFtcyk7XG59XG5cbkZvbGQuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiRm9sZFwiLFxuICBcIm1ldGFkYXRhXCI6IHtcImdlbmVyYXRlc1wiOiB0cnVlLCBcInNvdXJjZVwiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRzXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJhc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiAyLCBcImRlZmF1bHRcIjogW1wia2V5XCIsIFwidmFsdWVcIl0gfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDIwID0gaW5oZXJpdHMoRm9sZCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDIwLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBvdXQgPSBwdWxzZS5mb3JrKHB1bHNlLk5PX1NPVVJDRSksXG4gICAgICBmaWVsZHMgPSBfLmZpZWxkcyxcbiAgICAgIGZuYW1lcyA9IGZpZWxkcy5tYXAoYWNjZXNzb3JOYW1lKSxcbiAgICAgIGFzID0gXy5hcyB8fCBbJ2tleScsICd2YWx1ZSddLFxuICAgICAgayA9IGFzWzBdLFxuICAgICAgdiA9IGFzWzFdLFxuICAgICAgbiA9IGZpZWxkcy5sZW5ndGg7XG5cbiAgb3V0LnJlbSA9IHRoaXMudmFsdWU7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuU09VUkNFLCBmdW5jdGlvbih0KSB7XG4gICAgZm9yICh2YXIgaT0wLCBkOyBpPG47ICsraSkge1xuICAgICAgZCA9IGRlcml2ZSh0KTtcbiAgICAgIGRba10gPSBmbmFtZXNbaV07XG4gICAgICBkW3ZdID0gZmllbGRzW2ldKHQpO1xuICAgICAgb3V0LmFkZC5wdXNoKGQpO1xuICAgIH1cbiAgfSk7XG5cbiAgdGhpcy52YWx1ZSA9IG91dC5zb3VyY2UgPSBvdXQuYWRkO1xuICByZXR1cm4gb3V0Lm1vZGlmaWVzKGFzKTtcbn07XG5cbi8qKlxuICogSW52b2tlcyBhIGZ1bmN0aW9uIGZvciBlYWNoIGRhdGEgdHVwbGUgYW5kIHNhdmVzIHRoZSByZXN1bHRzIGFzIGEgbmV3IGZpZWxkLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy5leHByIC0gVGhlIGZvcm11bGEgZnVuY3Rpb24gdG8gaW52b2tlIGZvciBlYWNoIHR1cGxlLlxuICogQHBhcmFtIHtzdHJpbmd9IHBhcmFtcy5hcyAtIFRoZSBmaWVsZCBuYW1lIHVuZGVyIHdoaWNoIHRvIHNhdmUgdGhlIHJlc3VsdC5cbiAqIEBwYXJhbSB7Ym9vbGVhbn0gW3BhcmFtcy5pbml0b25seT1mYWxzZV0gLSBJZiB0cnVlLCB0aGUgZm9ybXVsYSBpcyBhcHBsaWVkIHRvXG4gKiAgIGFkZGVkIHR1cGxlcyBvbmx5LCBhbmQgZG9lcyBub3QgdXBkYXRlIGluIHJlc3BvbnNlIHRvIG1vZGlmaWNhdGlvbnMuXG4gKi9cbmZ1bmN0aW9uIEZvcm11bGEocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbkZvcm11bGEuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiRm9ybXVsYVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJleHByXCIsIFwidHlwZVwiOiBcImV4cHJcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJhc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJpbml0b25seVwiLCBcInR5cGVcIjogXCJib29sZWFuXCIgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDIxID0gaW5oZXJpdHMoRm9ybXVsYSwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDIxLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBmdW5jID0gXy5leHByLFxuICAgICAgYXMgPSBfLmFzLFxuICAgICAgbW9kID0gXy5tb2RpZmllZCgpLFxuICAgICAgZmxhZyA9IF8uaW5pdG9ubHkgPyBwdWxzZS5BRERcbiAgICAgICAgOiBtb2QgPyBwdWxzZS5TT1VSQ0VcbiAgICAgICAgOiBwdWxzZS5tb2RpZmllZChmdW5jLmZpZWxkcykgPyBwdWxzZS5BRERfTU9EXG4gICAgICAgIDogcHVsc2UuQUREO1xuXG4gIGZ1bmN0aW9uIHNldCh0KSB7XG4gICAgdFthc10gPSBmdW5jKHQsIF8pO1xuICB9XG5cbiAgaWYgKG1vZCkge1xuICAgIC8vIHBhcmFtZXRlcnMgdXBkYXRlZCwgbmVlZCB0byByZWZsb3dcbiAgICBwdWxzZSA9IHB1bHNlLm1hdGVyaWFsaXplKCkucmVmbG93KHRydWUpO1xuICB9XG5cbiAgaWYgKCFfLmluaXRvbmx5KSB7XG4gICAgcHVsc2UubW9kaWZpZXMoYXMpO1xuICB9XG5cbiAgcmV0dXJuIHB1bHNlLnZpc2l0KGZsYWcsIHNldCk7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBkYXRhIHR1cGxlcyB1c2luZyBhIHByb3ZpZGVkIGdlbmVyYXRvciBmdW5jdGlvbi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihQYXJhbWV0ZXJzKTogb2JqZWN0fSBwYXJhbXMuZ2VuZXJhdG9yIC0gQSB0dXBsZSBnZW5lcmF0b3JcbiAqICAgZnVuY3Rpb24uIFRoaXMgZnVuY3Rpb24gaXMgZ2l2ZW4gdGhlIG9wZXJhdG9yIHBhcmFtZXRlcnMgYXMgaW5wdXQuXG4gKiAgIENoYW5nZXMgdG8gYW55IGFkZGl0aW9uYWwgcGFyYW1ldGVycyB3aWxsIG5vdCB0cmlnZ2VyIHJlLWNhbGN1bGF0aW9uXG4gKiAgIG9mIHByZXZpb3VzbHkgZ2VuZXJhdGVkIHR1cGxlcy4gT25seSBmdXR1cmUgdHVwbGVzIGFyZSBhZmZlY3RlZC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBwYXJhbXMuc2l6ZSAtIFRoZSBudW1iZXIgb2YgdHVwbGVzIHRvIHByb2R1Y2UuXG4gKi9cbmZ1bmN0aW9uIEdlbmVyYXRlKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBbXSwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQyMiA9IGluaGVyaXRzKEdlbmVyYXRlLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMjIudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGRhdGEgPSB0aGlzLnZhbHVlLFxuICAgICAgb3V0ID0gcHVsc2UuZm9yayhwdWxzZS5BTEwpLFxuICAgICAgbnVtID0gXy5zaXplIC0gZGF0YS5sZW5ndGgsXG4gICAgICBnZW4gPSBfLmdlbmVyYXRvcixcbiAgICAgIGFkZCwgcmVtLCB0O1xuXG4gIGlmIChudW0gPiAwKSB7XG4gICAgLy8gbmVlZCBtb3JlIHR1cGxlcywgZ2VuZXJhdGUgYW5kIGFkZFxuICAgIGZvciAoYWRkPVtdOyAtLW51bSA+PSAwOykge1xuICAgICAgYWRkLnB1c2godCA9IGluZ2VzdChnZW4oXykpKTtcbiAgICAgIGRhdGEucHVzaCh0KTtcbiAgICB9XG4gICAgb3V0LmFkZCA9IG91dC5hZGQubGVuZ3RoXG4gICAgICA/IG91dC5tYXRlcmlhbGl6ZShvdXQuQUREKS5hZGQuY29uY2F0KGFkZClcbiAgICAgIDogYWRkO1xuICB9IGVsc2Uge1xuICAgIC8vIG5lZWQgZmV3ZXIgdHVwbGVzLCByZW1vdmVcbiAgICByZW0gPSBkYXRhLnNsaWNlKDAsIC1udW0pO1xuICAgIG91dC5yZW0gPSBvdXQucmVtLmxlbmd0aFxuICAgICAgPyBvdXQubWF0ZXJpYWxpemUob3V0LlJFTSkucmVtLmNvbmNhdChyZW0pXG4gICAgICA6IHJlbTtcbiAgICBkYXRhID0gZGF0YS5zbGljZSgtbnVtKTtcbiAgfVxuXG4gIG91dC5zb3VyY2UgPSB0aGlzLnZhbHVlID0gZGF0YTtcbiAgcmV0dXJuIG91dDtcbn07XG5cbnZhciBNZXRob2RzID0ge1xuICB2YWx1ZTogJ3ZhbHVlJyxcbiAgbWVkaWFuOiBtZWRpYW4sXG4gIG1lYW46IG1lYW4sXG4gIG1pbjogbWluLFxuICBtYXg6IG1heFxufTtcblxudmFyIEVtcHR5ID0gW107XG5cbi8qKlxuICogSW1wdXRlIG1pc3NpbmcgdmFsdWVzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy5maWVsZCAtIFRoZSB2YWx1ZSBmaWVsZCB0byBpbXB1dGUuXG4gKiBAcGFyYW0ge0FycmF5PGZ1bmN0aW9uKG9iamVjdCk6ICo+fSBbcGFyYW1zLmdyb3VwYnldIC0gQW4gYXJyYXkgb2ZcbiAqICAgYWNjZXNzb3JzIHRvIGRldGVybWluZSBzZXJpZXMgd2l0aGluIHdoaWNoIHRvIHBlcmZvcm0gaW1wdXRhdGlvbi5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogKn0gcGFyYW1zLmtleSAtIEFuIGFjY2Vzc29yIGZvciBhIGtleSB2YWx1ZS5cbiAqICAgRWFjaCBrZXkgdmFsdWUgc2hvdWxkIGJlIHVuaXF1ZSB3aXRoaW4gYSBncm91cC4gTmV3IHR1cGxlcyB3aWxsIGJlXG4gKiAgIGltcHV0ZWQgZm9yIGFueSBrZXkgdmFsdWVzIHRoYXQgYXJlIG5vdCBmb3VuZCB3aXRoaW4gYSBncm91cC5cbiAqIEBwYXJhbSB7QXJyYXk8Kj59IFtwYXJhbXMua2V5dmFsc10gLSBPcHRpb25hbCBhcnJheSBvZiByZXF1aXJlZCBrZXlcbiAqICAgdmFsdWVzLiBOZXcgdHVwbGVzIHdpbGwgYmUgaW1wdXRlZCBmb3IgYW55IGtleSB2YWx1ZXMgdGhhdCBhcmUgbm90XG4gKiAgIGZvdW5kIHdpdGhpbiBhIGdyb3VwLiBJbiBhZGRpdGlvbiwgdGhlc2UgdmFsdWVzIHdpbGwgYmUgYXV0b21hdGljYWxseVxuICogICBhdWdtZW50ZWQgd2l0aCB0aGUga2V5IHZhbHVlcyBvYnNlcnZlZCBpbiB0aGUgaW5wdXQgZGF0YS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbbWV0aG9kPSd2YWx1ZSddIC0gVGhlIGltcHV0YXRpb24gbWV0aG9kIHRvIHVzZS4gT25lIG9mXG4gKiAgICd2YWx1ZScsICdtZWFuJywgJ21lZGlhbicsICdtYXgnLCAnbWluJy5cbiAqIEBwYXJhbSB7Kn0gW3ZhbHVlPTBdIC0gVGhlIGNvbnN0YW50IHZhbHVlIHRvIHVzZSBmb3IgaW1wdXRhdGlvblxuICogICB3aGVuIHVzaW5nIG1ldGhvZCAndmFsdWUnLlxuICovXG5mdW5jdGlvbiBJbXB1dGUocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIFtdLCBwYXJhbXMpO1xufVxuXG5JbXB1dGUuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiSW1wdXRlXCIsXG4gIFwibWV0YWRhdGFcIjoge1wiZ2VuZXJhdGVzXCI6IHRydWUsIFwiY2hhbmdlc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJrZXlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJrZXl2YWxzXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZ3JvdXBieVwiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcIm1ldGhvZFwiLCBcInR5cGVcIjogXCJlbnVtXCIsIFwiZGVmYXVsdFwiOiBcInZhbHVlXCIsXG4gICAgICBcInZhbHVlc1wiOiBbXCJ2YWx1ZVwiLCBcIm1lYW5cIiwgXCJtZWRpYW5cIiwgXCJtYXhcIiwgXCJtaW5cIl0gfSxcbiAgICB7IFwibmFtZVwiOiBcInZhbHVlXCIsIFwiZGVmYXVsdFwiOiAwIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQyMyA9IGluaGVyaXRzKEltcHV0ZSwgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gZ2V0VmFsdWUoXykge1xuICB2YXIgbSA9IF8ubWV0aG9kIHx8IE1ldGhvZHMudmFsdWUsIHY7XG5cbiAgaWYgKE1ldGhvZHNbbV0gPT0gbnVsbCkge1xuICAgIGVycm9yJDEoJ1VucmVjb2duaXplZCBpbXB1dGF0aW9uIG1ldGhvZDogJyArIG0pO1xuICB9IGVsc2UgaWYgKG0gPT09IE1ldGhvZHMudmFsdWUpIHtcbiAgICB2ID0gXy52YWx1ZSAhPT0gdW5kZWZpbmVkID8gXy52YWx1ZSA6IDA7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKCkgeyByZXR1cm4gdjsgfTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gTWV0aG9kc1ttXTtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRGaWVsZChfKSB7XG4gIHZhciBmID0gXy5maWVsZDtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHsgcmV0dXJuIHQgPyBmKHQpIDogTmFOOyB9O1xufVxuXG5wcm90b3R5cGUkMjMudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuQUxMKSxcbiAgICAgIGltcHV0ZSA9IGdldFZhbHVlKF8pLFxuICAgICAgZmllbGQkJDEgPSBnZXRGaWVsZChfKSxcbiAgICAgIGZOYW1lID0gYWNjZXNzb3JOYW1lKF8uZmllbGQpLFxuICAgICAga05hbWUgPSBhY2Nlc3Nvck5hbWUoXy5rZXkpLFxuICAgICAgZ05hbWVzID0gKF8uZ3JvdXBieSB8fCBbXSkubWFwKGFjY2Vzc29yTmFtZSksXG4gICAgICBncm91cHMgPSBwYXJ0aXRpb24ocHVsc2Uuc291cmNlLCBfLmdyb3VwYnksIF8ua2V5LCBfLmtleXZhbHMpLFxuICAgICAgY3VyciA9IFtdLFxuICAgICAgcHJldiA9IHRoaXMudmFsdWUsXG4gICAgICBtID0gZ3JvdXBzLmRvbWFpbi5sZW5ndGgsXG4gICAgICBncm91cCwgdmFsdWUsIGdWYWxzLCBrVmFsLCBnLCBpLCBqLCBsLCBuLCB0O1xuXG4gIGZvciAoZz0wLCBsPWdyb3Vwcy5sZW5ndGg7IGc8bDsgKytnKSB7XG4gICAgZ3JvdXAgPSBncm91cHNbZ107XG4gICAgZ1ZhbHMgPSBncm91cC52YWx1ZXM7XG4gICAgdmFsdWUgPSBOYU47XG5cbiAgICAvLyBhZGQgdHVwbGVzIGZvciBtaXNzaW5nIHZhbHVlc1xuICAgIGZvciAoaj0wOyBqPG07ICsraikge1xuICAgICAgaWYgKGdyb3VwW2pdICE9IG51bGwpIGNvbnRpbnVlO1xuICAgICAga1ZhbCA9IGdyb3Vwcy5kb21haW5bal07XG5cbiAgICAgIHQgPSB7X2ltcHV0ZTogdHJ1ZX07XG4gICAgICBmb3IgKGk9MCwgbj1nVmFscy5sZW5ndGg7IGk8bjsgKytpKSB0W2dOYW1lc1tpXV0gPSBnVmFsc1tpXTtcbiAgICAgIHRba05hbWVdID0ga1ZhbDtcbiAgICAgIHRbZk5hbWVdID0gaXNOYU4odmFsdWUpID8gKHZhbHVlID0gaW1wdXRlKGdyb3VwLCBmaWVsZCQkMSkpIDogdmFsdWU7XG5cbiAgICAgIGN1cnIucHVzaChpbmdlc3QodCkpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHVwZGF0ZSBwdWxzZSB3aXRoIGltcHV0ZWQgdHVwbGVzXG4gIGlmIChjdXJyLmxlbmd0aCkgb3V0LmFkZCA9IG91dC5tYXRlcmlhbGl6ZShvdXQuQUREKS5hZGQuY29uY2F0KGN1cnIpO1xuICBpZiAocHJldi5sZW5ndGgpIG91dC5yZW0gPSBvdXQubWF0ZXJpYWxpemUob3V0LlJFTSkucmVtLmNvbmNhdChwcmV2KTtcbiAgdGhpcy52YWx1ZSA9IGN1cnI7XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbmZ1bmN0aW9uIHBhcnRpdGlvbihkYXRhLCBncm91cGJ5LCBrZXkkJDEsIGtleXZhbHMpIHtcbiAgdmFyIGdldCA9IGZ1bmN0aW9uKGYpIHsgcmV0dXJuIGYodCk7IH0sXG4gICAgICBncm91cHMgPSBbXSxcbiAgICAgIGRvbWFpbiA9IGtleXZhbHMgPyBrZXl2YWxzLnNsaWNlKCkgOiBbXSxcbiAgICAgIGtNYXAgPSB7fSxcbiAgICAgIGdNYXAgPSB7fSwgZ1ZhbHMsIGdLZXksXG4gICAgICBncm91cCwgaSwgaiwgaywgbiwgdDtcblxuICBkb21haW4uZm9yRWFjaChmdW5jdGlvbihrLCBpKSB7IGtNYXBba10gPSBpICsgMTsgfSk7XG5cbiAgZm9yIChpPTAsIG49ZGF0YS5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdCA9IGRhdGFbaV07XG4gICAgayA9IGtleSQkMSh0KTtcbiAgICBqID0ga01hcFtrXSB8fCAoa01hcFtrXSA9IGRvbWFpbi5wdXNoKGspKTtcblxuICAgIGdLZXkgPSAoZ1ZhbHMgPSBncm91cGJ5ID8gZ3JvdXBieS5tYXAoZ2V0KSA6IEVtcHR5KSArICcnO1xuICAgIGlmICghKGdyb3VwID0gZ01hcFtnS2V5XSkpIHtcbiAgICAgIGdyb3VwID0gKGdNYXBbZ0tleV0gPSBbXSk7XG4gICAgICBncm91cHMucHVzaChncm91cCk7XG4gICAgICBncm91cC52YWx1ZXMgPSBnVmFscztcbiAgICB9XG4gICAgZ3JvdXBbai0xXSA9IHQ7XG4gIH1cblxuICBncm91cHMuZG9tYWluID0gZG9tYWluO1xuICByZXR1cm4gZ3JvdXBzO1xufVxuXG4vKipcbiAqIEV4dGVuZCBpbnB1dCB0dXBsZXMgd2l0aCBhZ2dyZWdhdGUgdmFsdWVzLlxuICogQ2FsY3VhdGVzIGFnZ3JlZ2F0ZSB2YWx1ZXMgYW5kIGpvaW5zIHRoZW0gd2l0aCB0aGUgaW5wdXQgc3RyZWFtLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIEpvaW5BZ2dyZWdhdGUocGFyYW1zKSB7XG4gIEFnZ3JlZ2F0ZS5jYWxsKHRoaXMsIHBhcmFtcyk7XG59XG5cbkpvaW5BZ2dyZWdhdGUuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiSm9pbkFnZ3JlZ2F0ZVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJncm91cGJ5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRzXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwibnVsbFwiOiB0cnVlLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcIm9wc1wiLCBcInR5cGVcIjogXCJlbnVtXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJ2YWx1ZXNcIjogVmFsaWRBZ2dyZWdhdGVPcHMgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcIm51bGxcIjogdHJ1ZSwgXCJhcnJheVwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJrZXlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMjQgPSBpbmhlcml0cyhKb2luQWdncmVnYXRlLCBBZ2dyZWdhdGUpO1xuXG5wcm90b3R5cGUkMjQudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGFnZ3IgPSB0aGlzLFxuICAgICAgbW9kID0gXy5tb2RpZmllZCgpLFxuICAgICAgY2VsbHM7XG5cbiAgLy8gcHJvY2VzcyBhbGwgaW5wdXQgdHVwbGVzIHRvIGNhbGN1bGF0ZSBhZ2dyZWdhdGVzXG4gIGlmIChhZ2dyLnZhbHVlICYmIChtb2QgfHwgcHVsc2UubW9kaWZpZWQoYWdnci5faW5wdXRzKSkpIHtcbiAgICBjZWxscyA9IGFnZ3IudmFsdWUgPSBtb2QgPyBhZ2dyLmluaXQoXykgOiB7fTtcbiAgICBwdWxzZS52aXNpdChwdWxzZS5TT1VSQ0UsIGZ1bmN0aW9uKHQpIHsgYWdnci5hZGQodCk7IH0pO1xuICB9IGVsc2Uge1xuICAgIGNlbGxzID0gYWdnci52YWx1ZSA9IGFnZ3IudmFsdWUgfHwgdGhpcy5pbml0KF8pO1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlJFTSwgZnVuY3Rpb24odCkgeyBhZ2dyLnJlbSh0KTsgfSk7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbih0KSB7IGFnZ3IuYWRkKHQpOyB9KTtcbiAgfVxuXG4gIC8vIHVwZGF0ZSBhZ2dyZWdhdGlvbiBjZWxsc1xuICBhZ2dyLmNoYW5nZXMoKTtcblxuICAvLyB3cml0ZSBhZ2dyZWdhdGUgdmFsdWVzIHRvIGlucHV0IHR1cGxlc1xuICBwdWxzZS52aXNpdChwdWxzZS5TT1VSQ0UsIGZ1bmN0aW9uKHQpIHtcbiAgICBleHRlbmQodCwgY2VsbHNbYWdnci5jZWxsa2V5KHQpXS50dXBsZSk7XG4gIH0pO1xuXG4gIHJldHVybiBwdWxzZS5yZWZsb3cobW9kKS5tb2RpZmllcyh0aGlzLl9vdXRwdXRzKTtcbn07XG5cbnByb3RvdHlwZSQyNC5jaGFuZ2VzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBhZGRzID0gdGhpcy5fYWRkcyxcbiAgICAgIG1vZHMgPSB0aGlzLl9tb2RzLFxuICAgICAgaSwgbjtcblxuICBmb3IgKGk9MCwgbj10aGlzLl9hbGVuOyBpPG47ICsraSkge1xuICAgIHRoaXMuY2VsbHR1cGxlKGFkZHNbaV0pO1xuICAgIGFkZHNbaV0gPSBudWxsOyAvLyBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uXG4gIH1cblxuICBmb3IgKGk9MCwgbj10aGlzLl9tbGVuOyBpPG47ICsraSkge1xuICAgIHRoaXMuY2VsbHR1cGxlKG1vZHNbaV0pO1xuICAgIG1vZHNbaV0gPSBudWxsOyAvLyBmb3IgZ2FyYmFnZSBjb2xsZWN0aW9uXG4gIH1cblxuICB0aGlzLl9hbGVuID0gdGhpcy5fbWxlbiA9IDA7IC8vIHJlc2V0IGxpc3Qgb2YgYWN0aXZlIGNlbGxzXG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBhIGtleSBmdW5jdGlvbi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBwYXJhbXMuZmllbGRzIC0gVGhlIGZpZWxkIG5hbWUocykgZm9yIHRoZSBrZXkgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge2Jvb2xlYW59IHBhcmFtcy5mbGF0IC0gQSBib29sZWFuIGZsYWcgaW5kaWNhdGluZyBpZiB0aGUgZmllbGQgbmFtZXNcbiAqICBzaG91bGQgYmUgdHJlYXRlZCBhcyBmbGF0IHByb3BlcnR5IG5hbWVzLCBzaWRlLXN0ZXBwaW5nIG5lc3RlZCBmaWVsZFxuICogIGxvb2t1cHMgbm9ybWFsbHkgaW5kaWNhdGVkIGJ5IGRvdCBvciBicmFja2V0IG5vdGF0aW9uLlxuICovXG5mdW5jdGlvbiBLZXkocGFyYW1zKSB7XG4gIE9wZXJhdG9yLmNhbGwodGhpcywgbnVsbCwgdXBkYXRlJDMsIHBhcmFtcyk7XG59XG5cbmluaGVyaXRzKEtleSwgT3BlcmF0b3IpO1xuXG5mdW5jdGlvbiB1cGRhdGUkMyhfKSB7XG4gIHJldHVybiAodGhpcy52YWx1ZSAmJiAhXy5tb2RpZmllZCgpKSA/IHRoaXMudmFsdWUgOiBrZXkoXy5maWVsZHMsIF8uZmxhdCk7XG59XG5cbi8qKlxuICogRXh0ZW5kIHR1cGxlcyBieSBqb2luaW5nIHRoZW0gd2l0aCB2YWx1ZXMgZnJvbSBhIGxvb2t1cCB0YWJsZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtNYXB9IHBhcmFtcy5pbmRleCAtIFRoZSBsb29rdXAgdGFibGUgbWFwLlxuICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGRzIC0gVGhlIGZpZWxkcyB0byBsb29rdXAuXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IHBhcmFtcy5hcyAtIE91dHB1dCBmaWVsZCBuYW1lcyBmb3IgZWFjaCBsb29rdXAgdmFsdWUuXG4gKiBAcGFyYW0geyp9IFtwYXJhbXMuZGVmYXVsdF0gLSBBIGRlZmF1bHQgdmFsdWUgdG8gdXNlIGlmIGxvb2t1cCBmYWlscy5cbiAqL1xuZnVuY3Rpb24gTG9va3VwKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCB7fSwgcGFyYW1zKTtcbn1cblxuTG9va3VwLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIkxvb2t1cFwiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJpbmRleFwiLCBcInR5cGVcIjogXCJpbmRleFwiLCBcInBhcmFtc1wiOiBbXG4gICAgICAgIHtcIm5hbWVcIjogXCJmcm9tXCIsIFwidHlwZVwiOiBcImRhdGFcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgICAgIHtcIm5hbWVcIjogXCJrZXlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH1cbiAgICAgIF0gfSxcbiAgICB7IFwibmFtZVwiOiBcInZhbHVlc1wiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkc1wiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcImFycmF5XCI6IHRydWUsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZGVmYXVsdFwiLCBcImRlZmF1bHRcIjogbnVsbCB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMjUgPSBpbmhlcml0cyhMb29rdXAsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQyNS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgb3V0ID0gcHVsc2UsXG4gICAgICBhcyA9IF8uYXMsXG4gICAgICBrZXlzID0gXy5maWVsZHMsXG4gICAgICBpbmRleCA9IF8uaW5kZXgsXG4gICAgICB2YWx1ZXMgPSBfLnZhbHVlcyxcbiAgICAgIGRlZmF1bHRWYWx1ZSA9IF8uZGVmYXVsdD09bnVsbCA/IG51bGwgOiBfLmRlZmF1bHQsXG4gICAgICByZXNldCA9IF8ubW9kaWZpZWQoKSxcbiAgICAgIGZsYWcgPSByZXNldCA/IHB1bHNlLlNPVVJDRSA6IHB1bHNlLkFERCxcbiAgICAgIG4gPSBrZXlzLmxlbmd0aCxcbiAgICAgIHNldCwgbSwgbW9kcztcblxuICBpZiAodmFsdWVzKSB7XG4gICAgbSA9IHZhbHVlcy5sZW5ndGg7XG5cbiAgICBpZiAobiA+IDEgJiYgIWFzKSB7XG4gICAgICBlcnJvciQxKCdNdWx0aS1maWVsZCBsb29rdXAgcmVxdWlyZXMgZXhwbGljaXQgXCJhc1wiIHBhcmFtZXRlci4nKTtcbiAgICB9XG4gICAgaWYgKGFzICYmIGFzLmxlbmd0aCAhPT0gbiAqIG0pIHtcbiAgICAgIGVycm9yJDEoJ1RoZSBcImFzXCIgcGFyYW1ldGVyIGhhcyB0b28gZmV3IG91dHB1dCBmaWVsZCBuYW1lcy4nKTtcbiAgICB9XG4gICAgYXMgPSBhcyB8fCB2YWx1ZXMubWFwKGFjY2Vzc29yTmFtZSk7XG5cbiAgICBzZXQgPSBmdW5jdGlvbih0KSB7XG4gICAgICBmb3IgKHZhciBpPTAsIGs9MCwgaiwgdjsgaTxuOyArK2kpIHtcbiAgICAgICAgdiA9IGluZGV4LmdldChrZXlzW2ldKHQpKTtcbiAgICAgICAgaWYgKHYgPT0gbnVsbCkgZm9yIChqPTA7IGo8bTsgKytqLCArK2spIHRbYXNba11dID0gZGVmYXVsdFZhbHVlO1xuICAgICAgICBlbHNlIGZvciAoaj0wOyBqPG07ICsraiwgKytrKSB0W2FzW2tdXSA9IHZhbHVlc1tqXSh2KTtcbiAgICAgIH1cbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIGlmICghYXMpIHtcbiAgICAgIGVycm9yJDEoJ01pc3Npbmcgb3V0cHV0IGZpZWxkIG5hbWVzLicpO1xuICAgIH1cblxuICAgIHNldCA9IGZ1bmN0aW9uKHQpIHtcbiAgICAgIGZvciAodmFyIGk9MCwgdjsgaTxuOyArK2kpIHtcbiAgICAgICAgdiA9IGluZGV4LmdldChrZXlzW2ldKHQpKTtcbiAgICAgICAgdFthc1tpXV0gPSB2PT1udWxsID8gZGVmYXVsdFZhbHVlIDogdjtcbiAgICAgIH1cbiAgICB9O1xuICB9XG5cbiAgaWYgKHJlc2V0KSB7XG4gICAgb3V0ID0gcHVsc2UucmVmbG93KHRydWUpO1xuICB9IGVsc2Uge1xuICAgIG1vZHMgPSBrZXlzLnNvbWUoZnVuY3Rpb24oaykgeyByZXR1cm4gcHVsc2UubW9kaWZpZWQoay5maWVsZHMpOyB9KTtcbiAgICBmbGFnIHw9IChtb2RzID8gcHVsc2UuTU9EIDogMCk7XG4gIH1cbiAgcHVsc2UudmlzaXQoZmxhZywgc2V0KTtcblxuICByZXR1cm4gb3V0Lm1vZGlmaWVzKGFzKTtcbn07XG5cbi8qKlxuICogQ29tcHV0ZXMgZ2xvYmFsIG1pbi9tYXggZXh0ZW50cyBvdmVyIGEgY29sbGVjdGlvbiBvZiBleHRlbnRzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge0FycmF5PEFycmF5PG51bWJlcj4+fSBwYXJhbXMuZXh0ZW50cyAtIFRoZSBpbnB1dCBleHRlbnRzLlxuICovXG5mdW5jdGlvbiBNdWx0aUV4dGVudChwYXJhbXMpIHtcbiAgT3BlcmF0b3IuY2FsbCh0aGlzLCBudWxsLCB1cGRhdGUkNCwgcGFyYW1zKTtcbn1cblxuaW5oZXJpdHMoTXVsdGlFeHRlbnQsIE9wZXJhdG9yKTtcblxuZnVuY3Rpb24gdXBkYXRlJDQoXykge1xuICBpZiAodGhpcy52YWx1ZSAmJiAhXy5tb2RpZmllZCgpKSB7XG4gICAgcmV0dXJuIHRoaXMudmFsdWU7XG4gIH1cblxuICB2YXIgbWluID0gK0luZmluaXR5LFxuICAgICAgbWF4ID0gLUluZmluaXR5LFxuICAgICAgZXh0ID0gXy5leHRlbnRzLFxuICAgICAgaSwgbiwgZTtcblxuICBmb3IgKGk9MCwgbj1leHQubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGUgPSBleHRbaV07XG4gICAgaWYgKGVbMF0gPCBtaW4pIG1pbiA9IGVbMF07XG4gICAgaWYgKGVbMV0gPiBtYXgpIG1heCA9IGVbMV07XG4gIH1cbiAgcmV0dXJuIFttaW4sIG1heF07XG59XG5cbi8qKlxuICogTWVyZ2UgYSBjb2xsZWN0aW9uIG9mIHZhbHVlIGFycmF5cy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtBcnJheTxBcnJheTwqPj59IHBhcmFtcy52YWx1ZXMgLSBUaGUgaW5wdXQgdmFsdWUgYXJycmF5cy5cbiAqL1xuZnVuY3Rpb24gTXVsdGlWYWx1ZXMocGFyYW1zKSB7XG4gIE9wZXJhdG9yLmNhbGwodGhpcywgbnVsbCwgdXBkYXRlJDUsIHBhcmFtcyk7XG59XG5cbmluaGVyaXRzKE11bHRpVmFsdWVzLCBPcGVyYXRvcik7XG5cbmZ1bmN0aW9uIHVwZGF0ZSQ1KF8pIHtcbiAgcmV0dXJuICh0aGlzLnZhbHVlICYmICFfLm1vZGlmaWVkKCkpXG4gICAgPyB0aGlzLnZhbHVlXG4gICAgOiBfLnZhbHVlcy5yZWR1Y2UoZnVuY3Rpb24oZGF0YSwgXykgeyByZXR1cm4gZGF0YS5jb25jYXQoXyk7IH0sIFtdKTtcbn1cblxuLyoqXG4gKiBPcGVyYXRvciB3aG9zZSB2YWx1ZSBpcyBzaW1wbHkgaXRzIHBhcmFtZXRlciBoYXNoLiBUaGlzIG9wZXJhdG9yIGlzXG4gKiB1c2VmdWwgZm9yIGVuYWJsaW5nIHJlYWN0aXZlIHVwZGF0ZXMgdG8gdmFsdWVzIG9mIG5lc3RlZCBvYmplY3RzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIFBhcmFtcyhwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxuaW5oZXJpdHMoUGFyYW1zLCBUcmFuc2Zvcm0pO1xuXG5QYXJhbXMucHJvdG90eXBlLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHRoaXMubW9kaWZpZWQoXy5tb2RpZmllZCgpKTtcbiAgdGhpcy52YWx1ZSA9IF87XG4gIHJldHVybiBwdWxzZS5mb3JrKHB1bHNlLk5PX1NPVVJDRSB8IHB1bHNlLk5PX0ZJRUxEUyk7IC8vIGRvIG5vdCBwYXNzIHR1cGxlc1xufTtcblxuLyoqXG4gKiBBZ2dyZWdhdGUgYW5kIHBpdm90IHNlbGVjdGVkIGZpZWxkIHZhbHVlcyB0byBiZWNvbWUgbmV3IGZpZWxkcy5cbiAqIFRoaXMgb3BlcmF0b3IgaXMgdXNlZnVsIHRvIGNvbnN0cnVjdGlvbiBjcm9zcy10YWJ1bGF0aW9ucy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqPn0gW3BhcmFtcy5ncm91cGJ5XSAtIEFuIGFycmF5IG9mIGFjY2Vzc29yc1xuICogIHRvIGdyb3VwYnkuIFRoZXNlIGZpZWxkcyBhY3QganVzdCBsaWtlIGdyb3VwYnkgZmllbGRzIG9mIGFuIEFnZ3JlZ2F0ZSB0cmFuc2Zvcm0uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy5maWVsZCAtIFRoZSBmaWVsZCB0byBwaXZvdCBvbi4gVGhlIHVuaXF1ZVxuICogIHZhbHVlcyBvZiB0aGlzIGZpZWxkIGJlY29tZSBuZXcgZmllbGQgbmFtZXMgaW4gdGhlIG91dHB1dCBzdHJlYW0uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy52YWx1ZSAtIFRoZSBmaWVsZCB0byBwb3B1bGF0ZSBwaXZvdGVkIGZpZWxkcy5cbiAqICBUaGUgYWdncmVnYXRlIHZhbHVlcyBvZiB0aGlzIGZpZWxkIGJlY29tZSB0aGUgdmFsdWVzIG9mIHRoZSBuZXcgcGl2b3RlZCBmaWVsZHMuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3BhcmFtcy5vcF0gLSBUaGUgYWdncmVnYXRpb24gb3BlcmF0aW9uIGZvciB0aGUgdmFsdWUgZmllbGQsXG4gKiAgYXBwbGllZCBwZXIgY2VsbCBpbiB0aGUgb3V0cHV0IHN0cmVhbS4gVGhlIGRlZmF1bHQgaXMgXCJzdW1cIi5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbcGFyYW1zLmxpbWl0XSAtIEFuIG9wdGlvbmFsIHBhcmFtZXRlciBpbmRpY2F0aW5nIHRoZSBtYXhpbXVtXG4gKiAgbnVtYmVyIG9mIHBpdm90ZWQgZmllbGRzIHRvIGdlbmVyYXRlLiBUaGUgcGl2b3RlZCBmaWVsZCBuYW1lcyBhcmUgc29ydGVkIGluXG4gKiAgYXNjZW5kaW5nIG9yZGVyIHByaW9yIHRvIGVuZm9yY2luZyB0aGUgbGltaXQuXG4gKi9cbmZ1bmN0aW9uIFBpdm90KHBhcmFtcykge1xuICBBZ2dyZWdhdGUuY2FsbCh0aGlzLCBwYXJhbXMpO1xufVxuXG5QaXZvdC5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJQaXZvdFwiLFxuICBcIm1ldGFkYXRhXCI6IHtcImdlbmVyYXRlc1wiOiB0cnVlLCBcImNoYW5nZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImdyb3VwYnlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJhcnJheVwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcInJlcXVpcmVkXCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcInZhbHVlXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwib3BcIiwgXCJ0eXBlXCI6IFwiZW51bVwiLCBcInZhbHVlc1wiOiBWYWxpZEFnZ3JlZ2F0ZU9wcywgXCJkZWZhdWx0XCI6IFwic3VtXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcImxpbWl0XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9LFxuICAgIHsgXCJuYW1lXCI6IFwia2V5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDI2ID0gaW5oZXJpdHMoUGl2b3QsIEFnZ3JlZ2F0ZSk7XG5cbnByb3RvdHlwZSQyNi5fdHJhbnNmb3JtID0gcHJvdG90eXBlJDI2LnRyYW5zZm9ybTtcblxucHJvdG90eXBlJDI2LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHJldHVybiB0aGlzLl90cmFuc2Zvcm0oYWdncmVnYXRlUGFyYW1zKF8sIHB1bHNlKSwgcHVsc2UpO1xufTtcblxuLy8gU2hvZWhvcm4gYSBwaXZvdCB0cmFuc2Zvcm0gaW50byBhbiBhZ2dyZWdhdGUgdHJhbnNmb3JtIVxuLy8gRmlyc3QgY29sbGVjdCBhbGwgdW5pcXVlIHBpdm90IGZpZWxkIHZhbHVlcy5cbi8vIFRoZW4gZ2VuZXJhdGUgYWdncmVnYXRlIGZpZWxkcyBmb3IgZWFjaCBvdXRwdXQgcGl2b3QgZmllbGQuXG5mdW5jdGlvbiBhZ2dyZWdhdGVQYXJhbXMoXywgcHVsc2UpIHtcbiAgdmFyIGtleSQkMSAgICA9IF8uZmllbGQsXG4gIHZhbHVlICA9IF8udmFsdWUsXG4gICAgICBvcCAgICAgPSAoXy5vcCA9PT0gJ2NvdW50JyA/ICdfX2NvdW50X18nIDogXy5vcCkgfHwgJ3N1bScsXG4gICAgICBmaWVsZHMgPSBhY2Nlc3NvckZpZWxkcyhrZXkkJDEpLmNvbmNhdChhY2Nlc3NvckZpZWxkcyh2YWx1ZSkpLFxuICAgICAga2V5cyAgID0gcGl2b3RLZXlzKGtleSQkMSwgXy5saW1pdCB8fCAwLCBwdWxzZSk7XG5cbiAgcmV0dXJuIHtcbiAgICBrZXk6ICAgICAgXy5rZXksXG4gICAgZ3JvdXBieTogIF8uZ3JvdXBieSxcbiAgICBvcHM6ICAgICAga2V5cy5tYXAoZnVuY3Rpb24oKSB7IHJldHVybiBvcDsgfSksXG4gICAgZmllbGRzOiAgIGtleXMubWFwKGZ1bmN0aW9uKGspIHsgcmV0dXJuIGdldCQxKGssIGtleSQkMSwgdmFsdWUsIGZpZWxkcyk7IH0pLFxuICAgIGFzOiAgICAgICBrZXlzLm1hcChmdW5jdGlvbihrKSB7IHJldHVybiBrICsgJyc7IH0pLFxuICAgIG1vZGlmaWVkOiBfLm1vZGlmaWVkLmJpbmQoXylcbiAgfTtcbn1cblxuLy8gR2VuZXJhdGUgYWdncmVnYXRlIGZpZWxkIGFjY2Vzc29yLlxuLy8gT3V0cHV0IE5hTiBmb3Igbm9uLWV4aXN0ZW50IHZhbHVlczsgYWdncmVnYXRvciB3aWxsIGlnbm9yZSFcbmZ1bmN0aW9uIGdldCQxKGssIGtleSQkMSwgdmFsdWUsIGZpZWxkcykge1xuICByZXR1cm4gYWNjZXNzb3IoXG4gICAgZnVuY3Rpb24oZCkgeyByZXR1cm4ga2V5JCQxKGQpID09PSBrID8gdmFsdWUoZCkgOiBOYU47IH0sXG4gICAgZmllbGRzLFxuICAgIGsgKyAnJ1xuICApO1xufVxuXG4vLyBDb2xsZWN0IChhbmQgb3B0aW9uYWxseSBsaW1pdCkgYWxsIHVuaXF1ZSBwaXZvdCB2YWx1ZXMuXG5mdW5jdGlvbiBwaXZvdEtleXMoa2V5JCQxLCBsaW1pdCwgcHVsc2UpIHtcbiAgdmFyIG1hcCA9IHt9LFxuICAgICAgbGlzdCA9IFtdO1xuXG4gIHB1bHNlLnZpc2l0KHB1bHNlLlNPVVJDRSwgZnVuY3Rpb24odCkge1xuICAgIHZhciBrID0ga2V5JCQxKHQpO1xuICAgIGlmICghbWFwW2tdKSB7XG4gICAgICBtYXBba10gPSAxO1xuICAgICAgbGlzdC5wdXNoKGspO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gVE9ETz8gTW92ZSB0aGlzIGNvbXBhcmF0b3IgdG8gdmVnYS11dGlsP1xuICBsaXN0LnNvcnQoZnVuY3Rpb24odSwgdikge1xuICAgIHJldHVybiAodTx2fHx1PT1udWxsKSAmJiB2IT1udWxsID8gLTFcbiAgICAgIDogKHU+dnx8dj09bnVsbCkgJiYgdSE9bnVsbCA/IDFcbiAgICAgIDogKCh2PXYgaW5zdGFuY2VvZiBEYXRlPyt2OnYpLCh1PXUgaW5zdGFuY2VvZiBEYXRlPyt1OnUpKSE9PXUgJiYgdj09PXYgPyAtMVxuICAgICAgOiB2IT09diAmJiB1PT09dSA/IDEgOiAwO1xuICB9KTtcblxuICByZXR1cm4gbGltaXQgPyBsaXN0LnNsaWNlKDAsIGxpbWl0KSA6IGxpc3Q7XG59XG5cbi8qKlxuICogUGFydGl0aW9ucyBwcmUtZmFjZXRlZCBkYXRhIGludG8gdHVwbGUgc3ViZmxvd3MuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oRGF0YWZsb3csIHN0cmluZyk6IE9wZXJhdG9yfSBwYXJhbXMuc3ViZmxvdyAtIEEgZnVuY3Rpb25cbiAqICAgdGhhdCBnZW5lcmF0ZXMgYSBzdWJmbG93IG9mIG9wZXJhdG9ycyBhbmQgcmV0dXJucyBpdHMgcm9vdCBvcGVyYXRvci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogQXJyYXk8b2JqZWN0Pn0gcGFyYW1zLmZpZWxkIC0gVGhlIGZpZWxkXG4gKiAgIGFjY2Vzc29yIGZvciBhbiBhcnJheSBvZiBzdWJmbG93IHR1cGxlIG9iamVjdHMuXG4gKi9cbmZ1bmN0aW9uIFByZUZhY2V0KHBhcmFtcykge1xuICBGYWNldC5jYWxsKHRoaXMsIHBhcmFtcyk7XG59XG5cbnZhciBwcm90b3R5cGUkMjcgPSBpbmhlcml0cyhQcmVGYWNldCwgRmFjZXQpO1xuXG5wcm90b3R5cGUkMjcudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIHNlbGYgPSB0aGlzLFxuICAgICAgZmxvdyA9IF8uc3ViZmxvdyxcbiAgICAgIGZpZWxkJCQxID0gXy5maWVsZDtcblxuICBpZiAoXy5tb2RpZmllZCgnZmllbGQnKSB8fCBmaWVsZCQkMSAmJiBwdWxzZS5tb2RpZmllZChhY2Nlc3NvckZpZWxkcyhmaWVsZCQkMSkpKSB7XG4gICAgZXJyb3IkMSgnUHJlRmFjZXQgZG9lcyBub3Qgc3VwcG9ydCBmaWVsZCBtb2RpZmljYXRpb24uJyk7XG4gIH1cblxuICB0aGlzLl90YXJnZXRzLmFjdGl2ZSA9IDA7IC8vIHJlc2V0IGxpc3Qgb2YgYWN0aXZlIHN1YmZsb3dzXG5cbiAgcHVsc2UudmlzaXQocHVsc2UuTU9ELCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIHNmID0gc2VsZi5zdWJmbG93KHR1cGxlaWQodCksIGZsb3csIHB1bHNlLCB0KTtcbiAgICBmaWVsZCQkMSA/IGZpZWxkJCQxKHQpLmZvckVhY2goZnVuY3Rpb24oXykgeyBzZi5tb2QoXyk7IH0pIDogc2YubW9kKHQpO1xuICB9KTtcblxuICBwdWxzZS52aXNpdChwdWxzZS5BREQsIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgc2YgPSBzZWxmLnN1YmZsb3codHVwbGVpZCh0KSwgZmxvdywgcHVsc2UsIHQpO1xuICAgIGZpZWxkJCQxID8gZmllbGQkJDEodCkuZm9yRWFjaChmdW5jdGlvbihfKSB7IHNmLmFkZChpbmdlc3QoXykpOyB9KSA6IHNmLmFkZCh0KTtcbiAgfSk7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuUkVNLCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIHNmID0gc2VsZi5zdWJmbG93KHR1cGxlaWQodCksIGZsb3csIHB1bHNlLCB0KTtcbiAgICBmaWVsZCQkMSA/IGZpZWxkJCQxKHQpLmZvckVhY2goZnVuY3Rpb24oXykgeyBzZi5yZW0oXyk7IH0pIDogc2YucmVtKHQpO1xuICB9KTtcblxuICByZXR1cm4gcHVsc2U7XG59O1xuXG4vKipcbiAqIFBlcmZvcm1zIGEgcmVsYXRpb25hbCBwcm9qZWN0aW9uLCBjb3B5aW5nIHNlbGVjdGVkIGZpZWxkcyBmcm9tIHNvdXJjZVxuICogdHVwbGVzIHRvIGEgbmV3IHNldCBvZiBkZXJpdmVkIHR1cGxlcy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGRzIC0gVGhlIGZpZWxkcyB0byBwcm9qZWN0LFxuICogICBhcyBhbiBhcnJheSBvZiBmaWVsZCBhY2Nlc3NvcnMuIElmIHVuc3BlY2lmaWVkLCBhbGwgZmllbGRzIHdpbGwgYmVcbiAqICAgY29waWVkIHdpdGggbmFtZXMgdW5jaGFuZ2VkLlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBbcGFyYW1zLmFzXSAtIE91dHB1dCBmaWVsZCBuYW1lcyBmb3IgZWFjaCBwcm9qZWN0ZWRcbiAqICAgZmllbGQuIEFueSB1bnNwZWNpZmllZCBmaWVsZHMgd2lsbCB1c2UgdGhlIGZpZWxkIG5hbWUgcHJvdmlkZWQgYnlcbiAqICAgdGhlIGZpZWxkIGFjY2Vzc29yLlxuICovXG5mdW5jdGlvbiBQcm9qZWN0KHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5Qcm9qZWN0LkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIlByb2plY3RcIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJnZW5lcmF0ZXNcIjogdHJ1ZSwgXCJjaGFuZ2VzXCI6IHRydWUsIFwibW9kaWZpZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkc1wiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcIm51bGxcIjogdHJ1ZSwgXCJhcnJheVwiOiB0cnVlIH0sXG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMjggPSBpbmhlcml0cyhQcm9qZWN0LCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMjgudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGZpZWxkcyA9IF8uZmllbGRzLFxuICAgICAgYXMgPSBmaWVsZE5hbWVzKF8uZmllbGRzLCBfLmFzIHx8IFtdKSxcbiAgICAgIGRlcml2ZSQkMSA9IGZpZWxkc1xuICAgICAgICA/IGZ1bmN0aW9uKHMsIHQpIHsgcmV0dXJuIHByb2plY3QocywgdCwgZmllbGRzLCBhcyk7IH1cbiAgICAgICAgOiByZWRlcml2ZSxcbiAgICAgIG91dCwgbHV0O1xuXG4gIGlmICh0aGlzLnZhbHVlKSB7XG4gICAgbHV0ID0gdGhpcy52YWx1ZTtcbiAgfSBlbHNlIHtcbiAgICBwdWxzZSA9IHB1bHNlLmFkZEFsbCgpO1xuICAgIGx1dCA9IHRoaXMudmFsdWUgPSB7fTtcbiAgfVxuXG4gIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFKTtcblxuICBwdWxzZS52aXNpdChwdWxzZS5SRU0sIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgaWQkJDEgPSB0dXBsZWlkKHQpO1xuICAgIG91dC5yZW0ucHVzaChsdXRbaWQkJDFdKTtcbiAgICBsdXRbaWQkJDFdID0gbnVsbDtcbiAgfSk7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGR0ID0gZGVyaXZlJCQxKHQsIGluZ2VzdCh7fSkpO1xuICAgIGx1dFt0dXBsZWlkKHQpXSA9IGR0O1xuICAgIG91dC5hZGQucHVzaChkdCk7XG4gIH0pO1xuXG4gIHB1bHNlLnZpc2l0KHB1bHNlLk1PRCwgZnVuY3Rpb24odCkge1xuICAgIG91dC5tb2QucHVzaChkZXJpdmUkJDEodCwgbHV0W3R1cGxlaWQodCldKSk7XG4gIH0pO1xuXG4gIHJldHVybiBvdXQ7XG59O1xuXG5mdW5jdGlvbiBwcm9qZWN0KHMsIHQsIGZpZWxkcywgYXMpIHtcbiAgZm9yICh2YXIgaT0wLCBuPWZpZWxkcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdFthc1tpXV0gPSBmaWVsZHNbaV0ocyk7XG4gIH1cbiAgcmV0dXJuIHQ7XG59XG5cbi8qKlxuICogUHJveHkgdGhlIHZhbHVlIG9mIGFub3RoZXIgb3BlcmF0b3IgYXMgYSBwdXJlIHNpZ25hbCB2YWx1ZS5cbiAqIEVuc3VyZXMgbm8gdHVwbGVzIGFyZSBwcm9wYWdhdGVkLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0geyp9IHBhcmFtcy52YWx1ZSAtIFRoZSB2YWx1ZSB0byBwcm94eSwgYmVjb21lcyB0aGUgdmFsdWUgb2YgdGhpcyBvcGVyYXRvci5cbiAqL1xuZnVuY3Rpb24gUHJveHkocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbnZhciBwcm90b3R5cGUkMjkgPSBpbmhlcml0cyhQcm94eSwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDI5LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHRoaXMudmFsdWUgPSBfLnZhbHVlO1xuICByZXR1cm4gXy5tb2RpZmllZCgndmFsdWUnKVxuICAgID8gcHVsc2UuZm9yayhwdWxzZS5OT19TT1VSQ0UgfCBwdWxzZS5OT19GSUVMRFMpXG4gICAgOiBwdWxzZS5TdG9wUHJvcGFnYXRpb247XG59O1xuXG4vKipcbiAqIFJlbGF5cyBhIGRhdGEgc3RyZWFtIGJldHdlZW4gZGF0YSBwcm9jZXNzaW5nIHBpcGVsaW5lcy5cbiAqIElmIHRoZSBkZXJpdmUgcGFyYW1ldGVyIGlzIHNldCwgdGhpcyB0cmFuc2Zvcm0gd2lsbCBjcmVhdGUgZGVyaXZlZFxuICogY29waWVzIG9mIG9ic2VydmVkIHR1cGxlcy4gVGhpcyBwcm92aWRlcyBkZXJpdmVkIGRhdGEgc3RyZWFtcyBpbiB3aGljaFxuICogbW9kaWZpY2F0aW9ucyB0byB0aGUgdHVwbGVzIGRvIG5vdCBwb2xsdXRlIGFuIHVwc3RyZWFtIGRhdGEgc291cmNlLlxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJhbXMuZGVyaXZlPWZhbHNlXSAtIEJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIGlmXG4gKiAgIHRoZSB0cmFuc2Zvcm0gc2hvdWxkIG1ha2UgZGVyaXZlZCBjb3BpZXMgb2YgaW5jb21pbmcgdHVwbGVzLlxuICogQGNvbnN0cnVjdG9yXG4gKi9cbmZ1bmN0aW9uIFJlbGF5KHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG52YXIgcHJvdG90eXBlJDMwID0gaW5oZXJpdHMoUmVsYXksIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQzMC50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgb3V0LCBsdXQ7XG5cbiAgaWYgKHRoaXMudmFsdWUpIHtcbiAgICBsdXQgPSB0aGlzLnZhbHVlO1xuICB9IGVsc2Uge1xuICAgIG91dCA9IHB1bHNlID0gcHVsc2UuYWRkQWxsKCk7XG4gICAgbHV0ID0gdGhpcy52YWx1ZSA9IHt9O1xuICB9XG5cbiAgaWYgKF8uZGVyaXZlKSB7XG4gICAgb3V0ID0gcHVsc2UuZm9yayhwdWxzZS5OT19TT1VSQ0UpO1xuXG4gICAgcHVsc2UudmlzaXQocHVsc2UuUkVNLCBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgaWQkJDEgPSB0dXBsZWlkKHQpO1xuICAgICAgb3V0LnJlbS5wdXNoKGx1dFtpZCQkMV0pO1xuICAgICAgbHV0W2lkJCQxXSA9IG51bGw7XG4gICAgfSk7XG5cbiAgICBwdWxzZS52aXNpdChwdWxzZS5BREQsIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBkdCA9IGRlcml2ZSh0KTtcbiAgICAgIGx1dFt0dXBsZWlkKHQpXSA9IGR0O1xuICAgICAgb3V0LmFkZC5wdXNoKGR0KTtcbiAgICB9KTtcblxuICAgIHB1bHNlLnZpc2l0KHB1bHNlLk1PRCwgZnVuY3Rpb24odCkge1xuICAgICAgb3V0Lm1vZC5wdXNoKHJlZGVyaXZlKHQsIGx1dFt0dXBsZWlkKHQpXSkpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogU2FtcGxlcyB0dXBsZXMgcGFzc2luZyB0aHJvdWdoIHRoaXMgb3BlcmF0b3IuXG4gKiBVc2VzIHJlc2Vydm9pciBzYW1wbGluZyB0byBtYWludGFpbiBhIHJlcHJlc2VudGF0aXZlIHNhbXBsZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJhbXMuc2l6ZT0xMDAwXSAtIFRoZSBtYXhpbXVtIG51bWJlciBvZiBzYW1wbGVzLlxuICovXG5mdW5jdGlvbiBTYW1wbGUocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIFtdLCBwYXJhbXMpO1xuICB0aGlzLmNvdW50ID0gMDtcbn1cblxuU2FtcGxlLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIlNhbXBsZVwiLFxuICBcIm1ldGFkYXRhXCI6IHt9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJzaXplXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMTAwMCB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkMzEgPSBpbmhlcml0cyhTYW1wbGUsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQzMS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgb3V0ID0gcHVsc2UuZm9yayhwdWxzZS5OT19TT1VSQ0UpLFxuICAgICAgbW9kID0gXy5tb2RpZmllZCgnc2l6ZScpLFxuICAgICAgbnVtID0gXy5zaXplLFxuICAgICAgcmVzID0gdGhpcy52YWx1ZSxcbiAgICAgIGNudCA9IHRoaXMuY291bnQsXG4gICAgICBjYXAgPSAwLFxuICAgICAgbWFwID0gcmVzLnJlZHVjZShmdW5jdGlvbihtLCB0KSB7XG4gICAgICAgIG1bdHVwbGVpZCh0KV0gPSAxO1xuICAgICAgICByZXR1cm4gbTtcbiAgICAgIH0sIHt9KTtcblxuICAvLyBzYW1wbGUgcmVzZXJ2b2lyIHVwZGF0ZSBmdW5jdGlvblxuICBmdW5jdGlvbiB1cGRhdGUodCkge1xuICAgIHZhciBwLCBpZHg7XG5cbiAgICBpZiAocmVzLmxlbmd0aCA8IG51bSkge1xuICAgICAgcmVzLnB1c2godCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGlkeCA9IH5+KChjbnQgKyAxKSAqIGV4cG9ydHMucmFuZG9tKCkpO1xuICAgICAgaWYgKGlkeCA8IHJlcy5sZW5ndGggJiYgaWR4ID49IGNhcCkge1xuICAgICAgICBwID0gcmVzW2lkeF07XG4gICAgICAgIGlmIChtYXBbdHVwbGVpZChwKV0pIG91dC5yZW0ucHVzaChwKTsgLy8gZXZpY3Rpb25cbiAgICAgICAgcmVzW2lkeF0gPSB0O1xuICAgICAgfVxuICAgIH1cbiAgICArK2NudDtcbiAgfVxuXG4gIGlmIChwdWxzZS5yZW0ubGVuZ3RoKSB7XG4gICAgLy8gZmluZCBhbGwgdHVwbGVzIHRoYXQgc2hvdWxkIGJlIHJlbW92ZWQsIGFkZCB0byBvdXRwdXRcbiAgICBwdWxzZS52aXNpdChwdWxzZS5SRU0sIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBpZCQkMSA9IHR1cGxlaWQodCk7XG4gICAgICBpZiAobWFwW2lkJCQxXSkge1xuICAgICAgICBtYXBbaWQkJDFdID0gLTE7XG4gICAgICAgIG91dC5yZW0ucHVzaCh0KTtcbiAgICAgIH1cbiAgICAgIC0tY250O1xuICAgIH0pO1xuXG4gICAgLy8gZmlsdGVyIHJlbW92ZWQgdHVwbGVzIG91dCBvZiB0aGUgc2FtcGxlIHJlc2Vydm9pclxuICAgIHJlcyA9IHJlcy5maWx0ZXIoZnVuY3Rpb24odCkgeyByZXR1cm4gbWFwW3R1cGxlaWQodCldICE9PSAtMTsgfSk7XG4gIH1cblxuICBpZiAoKHB1bHNlLnJlbS5sZW5ndGggfHwgbW9kKSAmJiByZXMubGVuZ3RoIDwgbnVtICYmIHB1bHNlLnNvdXJjZSkge1xuICAgIC8vIHJlcGxlbmlzaCBzYW1wbGUgaWYgYmFja2luZyBkYXRhIHNvdXJjZSBpcyBhdmFpbGFibGVcbiAgICBjYXAgPSBjbnQgPSByZXMubGVuZ3RoO1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlNPVVJDRSwgZnVuY3Rpb24odCkge1xuICAgICAgLy8gdXBkYXRlLCBidXQgc2tpcCBwcmV2aW91c2x5IHNhbXBsZWQgdHVwbGVzXG4gICAgICBpZiAoIW1hcFt0dXBsZWlkKHQpXSkgdXBkYXRlKHQpO1xuICAgIH0pO1xuICAgIGNhcCA9IC0xO1xuICB9XG5cbiAgaWYgKG1vZCAmJiByZXMubGVuZ3RoID4gbnVtKSB7XG4gICAgZm9yICh2YXIgaT0wLCBuPXJlcy5sZW5ndGgtbnVtOyBpPG47ICsraSkge1xuICAgICAgbWFwW3R1cGxlaWQocmVzW2ldKV0gPSAtMTtcbiAgICAgIG91dC5yZW0ucHVzaChyZXNbaV0pO1xuICAgIH1cbiAgICByZXMgPSByZXMuc2xpY2Uobik7XG4gIH1cblxuICBpZiAocHVsc2UubW9kLmxlbmd0aCkge1xuICAgIC8vIHByb3BhZ2F0ZSBtb2RpZmllZCB0dXBsZXMgaW4gdGhlIHNhbXBsZSByZXNlcnZvaXJcbiAgICBwdWxzZS52aXNpdChwdWxzZS5NT0QsIGZ1bmN0aW9uKHQpIHtcbiAgICAgIGlmIChtYXBbdHVwbGVpZCh0KV0pIG91dC5tb2QucHVzaCh0KTtcbiAgICB9KTtcbiAgfVxuXG4gIGlmIChwdWxzZS5hZGQubGVuZ3RoKSB7XG4gICAgLy8gdXBkYXRlIHNhbXBsZSByZXNlcnZvaXJcbiAgICBwdWxzZS52aXNpdChwdWxzZS5BREQsIHVwZGF0ZSk7XG4gIH1cblxuICBpZiAocHVsc2UuYWRkLmxlbmd0aCB8fCBjYXAgPCAwKSB7XG4gICAgLy8gb3V0cHV0IG5ld2x5IGFkZGVkIHR1cGxlc1xuICAgIG91dC5hZGQgPSByZXMuZmlsdGVyKGZ1bmN0aW9uKHQpIHsgcmV0dXJuICFtYXBbdHVwbGVpZCh0KV07IH0pO1xuICB9XG5cbiAgdGhpcy5jb3VudCA9IGNudDtcbiAgdGhpcy52YWx1ZSA9IG91dC5zb3VyY2UgPSByZXM7XG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlcyBkYXRhIHR1cGxlcyBmb3IgYSBzcGVjaWZpZWQgc2VxdWVuY2UgcmFuZ2Ugb2YgbnVtYmVycy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5zdGFydCAtIFRoZSBmaXJzdCBudW1iZXIgaW4gdGhlIHNlcXVlbmNlLlxuICogQHBhcmFtIHtudW1iZXJ9IHBhcmFtcy5zdG9wIC0gVGhlIGxhc3QgbnVtYmVyIChleGNsdXNpdmUpIGluIHRoZSBzZXF1ZW5jZS5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbcGFyYW1zLnN0ZXA9MV0gLSBUaGUgc3RlcCBzaXplIGJldHdlZW4gbnVtYmVycyBpbiB0aGUgc2VxdWVuY2UuXG4gKi9cbmZ1bmN0aW9uIFNlcXVlbmNlKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5TZXF1ZW5jZS5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJTZXF1ZW5jZVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcImdlbmVyYXRlc1wiOiB0cnVlLCBcImNoYW5nZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcInN0YXJ0XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcInJlcXVpcmVkXCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcInN0b3BcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwic3RlcFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDEgfVxuICBdLFxuICBcIm91dHB1dFwiOiBbXCJ2YWx1ZVwiXVxufTtcblxudmFyIHByb3RvdHlwZSQzMiA9IGluaGVyaXRzKFNlcXVlbmNlLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkMzIudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgaWYgKHRoaXMudmFsdWUgJiYgIV8ubW9kaWZpZWQoKSkgcmV0dXJuO1xuXG4gIHZhciBvdXQgPSBwdWxzZS5tYXRlcmlhbGl6ZSgpLmZvcmsocHVsc2UuTU9EKTtcblxuICBvdXQucmVtID0gdGhpcy52YWx1ZSA/IHB1bHNlLnJlbS5jb25jYXQodGhpcy52YWx1ZSkgOiBwdWxzZS5yZW07XG4gIHRoaXMudmFsdWUgPSBzZXF1ZW5jZShfLnN0YXJ0LCBfLnN0b3AsIF8uc3RlcCB8fCAxKS5tYXAoaW5nZXN0KTtcbiAgb3V0LmFkZCA9IHB1bHNlLmFkZC5jb25jYXQodGhpcy52YWx1ZSk7XG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIFByb3BhZ2F0ZXMgYSBuZXcgcHVsc2Ugd2l0aG91dCBhbnkgdHVwbGVzIHNvIGxvbmcgYXMgdGhlIGlucHV0XG4gKiBwdWxzZSBjb250YWlucyBzb21lIGFkZGVkLCByZW1vdmVkIG9yIG1vZGlmaWVkIHR1cGxlcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBTaWV2ZShwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbiAgdGhpcy5tb2RpZmllZCh0cnVlKTsgLy8gYWx3YXlzIHRyZWF0IGFzIG1vZGlmaWVkXG59XG5cbnZhciBwcm90b3R5cGUkMzMgPSBpbmhlcml0cyhTaWV2ZSwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDMzLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHRoaXMudmFsdWUgPSBwdWxzZS5zb3VyY2U7XG4gIHJldHVybiBwdWxzZS5jaGFuZ2VkKClcbiAgICA/IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKVxuICAgIDogcHVsc2UuU3RvcFByb3BhZ2F0aW9uO1xufTtcblxuLyoqXG4gKiBBbiBpbmRleCB0aGF0IG1hcHMgZnJvbSB1bmlxdWUsIHN0cmluZy1jb2VyY2VkLCBmaWVsZCB2YWx1ZXMgdG8gdHVwbGVzLlxuICogQXNzdW1lcyB0aGF0IHRoZSBmaWVsZCBzZXJ2ZXMgYXMgYSB1bmlxdWUga2V5IHdpdGggbm8gZHVwbGljYXRlIHZhbHVlcy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGQgLSBUaGUgZmllbGQgYWNjZXNzb3IgdG8gaW5kZXguXG4gKi9cbmZ1bmN0aW9uIFR1cGxlSW5kZXgocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIGZhc3RtYXAoKSwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQzNCA9IGluaGVyaXRzKFR1cGxlSW5kZXgsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQzNC50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgZGYgPSBwdWxzZS5kYXRhZmxvdyxcbiAgICAgIGZpZWxkJCQxID0gXy5maWVsZCxcbiAgICAgIGluZGV4ID0gdGhpcy52YWx1ZSxcbiAgICAgIG1vZCA9IHRydWU7XG5cbiAgZnVuY3Rpb24gc2V0KHQpIHsgaW5kZXguc2V0KGZpZWxkJCQxKHQpLCB0KTsgfVxuXG4gIGlmIChfLm1vZGlmaWVkKCdmaWVsZCcpIHx8IHB1bHNlLm1vZGlmaWVkKGZpZWxkJCQxLmZpZWxkcykpIHtcbiAgICBpbmRleC5jbGVhcigpO1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlNPVVJDRSwgc2V0KTtcbiAgfSBlbHNlIGlmIChwdWxzZS5jaGFuZ2VkKCkpIHtcbiAgICBwdWxzZS52aXNpdChwdWxzZS5SRU0sIGZ1bmN0aW9uKHQpIHsgaW5kZXguZGVsZXRlKGZpZWxkJCQxKHQpKTsgfSk7XG4gICAgcHVsc2UudmlzaXQocHVsc2UuQURELCBzZXQpO1xuICB9IGVsc2Uge1xuICAgIG1vZCA9IGZhbHNlO1xuICB9XG5cbiAgdGhpcy5tb2RpZmllZChtb2QpO1xuICBpZiAoaW5kZXguZW1wdHkgPiBkZi5jbGVhblRocmVzaG9sZCkgZGYucnVuQWZ0ZXIoaW5kZXguY2xlYW4pO1xuICByZXR1cm4gcHVsc2UuZm9yaygpO1xufTtcblxuLyoqXG4gKiBFeHRyYWN0cyBhbiBhcnJheSBvZiB2YWx1ZXMuIEFzc3VtZXMgdGhlIHNvdXJjZSBkYXRhIGhhcyBhbHJlYWR5IGJlZW5cbiAqIHJlZHVjZWQgYXMgbmVlZGVkIChlLmcuLCBieSBhbiB1cHN0cmVhbSBBZ2dyZWdhdGUgdHJhbnNmb3JtKS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGQgLSBUaGUgZG9tYWluIGZpZWxkIHRvIGV4dHJhY3QuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosKik6IG51bWJlcn0gW3BhcmFtcy5zb3J0XSAtIEFuIG9wdGlvbmFsXG4gKiAgIGNvbXBhcmF0b3IgZnVuY3Rpb24gZm9yIHNvcnRpbmcgdGhlIHZhbHVlcy4gVGhlIGNvbXBhcmF0b3Igd2lsbCBiZVxuICogICBhcHBsaWVkIHRvIGJhY2tpbmcgdHVwbGVzIHByaW9yIHRvIHZhbHVlIGV4dHJhY3Rpb24uXG4gKi9cbmZ1bmN0aW9uIFZhbHVlcyhwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQzNSA9IGluaGVyaXRzKFZhbHVlcywgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDM1LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBydW4gPSAhdGhpcy52YWx1ZVxuICAgIHx8IF8ubW9kaWZpZWQoJ2ZpZWxkJylcbiAgICB8fCBfLm1vZGlmaWVkKCdzb3J0JylcbiAgICB8fCBwdWxzZS5jaGFuZ2VkKClcbiAgICB8fCAoXy5zb3J0ICYmIHB1bHNlLm1vZGlmaWVkKF8uc29ydC5maWVsZHMpKTtcblxuICBpZiAocnVuKSB7XG4gICAgdGhpcy52YWx1ZSA9IChfLnNvcnRcbiAgICAgID8gcHVsc2Uuc291cmNlLnNsaWNlKCkuc29ydChfLnNvcnQpXG4gICAgICA6IHB1bHNlLnNvdXJjZSkubWFwKF8uZmllbGQpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBXaW5kb3dPcChvcCwgZmllbGQkJDEsIHBhcmFtLCBhcykge1xuICB2YXIgZm4gPSBXaW5kb3dPcHNbb3BdKGZpZWxkJCQxLCBwYXJhbSk7XG4gIHJldHVybiB7XG4gICAgaW5pdDogICBmbi5pbml0IHx8IHplcm8sXG4gICAgdXBkYXRlOiBmdW5jdGlvbih3LCB0KSB7IHRbYXNdID0gZm4ubmV4dCh3KTsgfVxuICB9O1xufVxuXG52YXIgV2luZG93T3BzID0ge1xuICByb3dfbnVtYmVyOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4ge1xuICAgICAgbmV4dDogZnVuY3Rpb24odykgeyByZXR1cm4gdy5pbmRleCArIDE7IH1cbiAgICB9O1xuICB9LFxuICByYW5rOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmFuaztcbiAgICByZXR1cm4ge1xuICAgICAgaW5pdDogZnVuY3Rpb24oKSB7IHJhbmsgPSAxOyB9LFxuICAgICAgbmV4dDogZnVuY3Rpb24odykge1xuICAgICAgICB2YXIgaSA9IHcuaW5kZXgsXG4gICAgICAgICAgICBkYXRhID0gdy5kYXRhO1xuICAgICAgICByZXR1cm4gKGkgJiYgdy5jb21wYXJlKGRhdGFbaSAtIDFdLCBkYXRhW2ldKSkgPyAocmFuayA9IGkgKyAxKSA6IHJhbms7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbiAgZGVuc2VfcmFuazogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGRyYW5rO1xuICAgIHJldHVybiB7XG4gICAgICBpbml0OiBmdW5jdGlvbigpIHsgZHJhbmsgPSAxOyB9LFxuICAgICAgbmV4dDogZnVuY3Rpb24odykge1xuICAgICAgICB2YXIgaSA9IHcuaW5kZXgsXG4gICAgICAgICAgICBkID0gdy5kYXRhO1xuICAgICAgICByZXR1cm4gKGkgJiYgdy5jb21wYXJlKGRbaSAtIDFdLCBkW2ldKSkgPyArK2RyYW5rIDogZHJhbms7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbiAgcGVyY2VudF9yYW5rOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgcmFuayA9IFdpbmRvd09wcy5yYW5rKCksXG4gICAgICAgIG5leHQgPSByYW5rLm5leHQ7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluaXQ6IHJhbmsuaW5pdCxcbiAgICAgIG5leHQ6IGZ1bmN0aW9uKHcpIHtcbiAgICAgICAgcmV0dXJuIChuZXh0KHcpIC0gMSkgLyAody5kYXRhLmxlbmd0aCAtIDEpO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG4gIGN1bWVfZGlzdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGN1bWU7XG4gICAgcmV0dXJuIHtcbiAgICAgIGluaXQ6IGZ1bmN0aW9uKCkgeyBjdW1lID0gMDsgfSxcbiAgICAgIG5leHQ6IGZ1bmN0aW9uKHcpIHtcbiAgICAgICAgdmFyIGkgPSB3LmluZGV4LFxuICAgICAgICAgICAgZCA9IHcuZGF0YSxcbiAgICAgICAgICAgIGMgPSB3LmNvbXBhcmU7XG4gICAgICAgIGlmIChjdW1lIDwgaSkge1xuICAgICAgICAgIHdoaWxlIChpICsgMSA8IGQubGVuZ3RoICYmICFjKGRbaV0sIGRbaSArIDFdKSkgKytpO1xuICAgICAgICAgIGN1bWUgPSBpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybiAoMSArIGN1bWUpIC8gZC5sZW5ndGg7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbiAgbnRpbGU6IGZ1bmN0aW9uKGZpZWxkJCQxLCBudW0pIHtcbiAgICBudW0gPSArbnVtO1xuICAgIGlmICghKG51bSA+IDApKSBlcnJvciQxKCdudGlsZSBudW0gbXVzdCBiZSBncmVhdGVyIHRoYW4gemVyby4nKTtcbiAgICB2YXIgY3VtZSA9IFdpbmRvd09wcy5jdW1lX2Rpc3QoKSxcbiAgICAgICAgbmV4dCA9IGN1bWUubmV4dDtcbiAgICByZXR1cm4ge1xuICAgICAgaW5pdDogY3VtZS5pbml0LFxuICAgICAgbmV4dDogZnVuY3Rpb24odykgeyByZXR1cm4gTWF0aC5jZWlsKG51bSAqIG5leHQodykpOyB9XG4gICAgfTtcbiAgfSxcblxuICBsYWc6IGZ1bmN0aW9uKGZpZWxkJCQxLCBvZmZzZXQpIHtcbiAgICBvZmZzZXQgPSArb2Zmc2V0IHx8IDE7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5leHQ6IGZ1bmN0aW9uKHcpIHtcbiAgICAgICAgdmFyIGkgPSB3LmluZGV4IC0gb2Zmc2V0O1xuICAgICAgICByZXR1cm4gaSA+PSAwID8gZmllbGQkJDEody5kYXRhW2ldKSA6IG51bGw7XG4gICAgICB9XG4gICAgfTtcbiAgfSxcbiAgbGVhZDogZnVuY3Rpb24oZmllbGQkJDEsIG9mZnNldCkge1xuICAgIG9mZnNldCA9ICtvZmZzZXQgfHwgMTtcbiAgICByZXR1cm4ge1xuICAgICAgbmV4dDogZnVuY3Rpb24odykge1xuICAgICAgICB2YXIgaSA9IHcuaW5kZXggKyBvZmZzZXQsXG4gICAgICAgICAgICBkID0gdy5kYXRhO1xuICAgICAgICByZXR1cm4gaSA8IGQubGVuZ3RoID8gZmllbGQkJDEoZFtpXSkgOiBudWxsO1xuICAgICAgfVxuICAgIH07XG4gIH0sXG5cbiAgZmlyc3RfdmFsdWU6IGZ1bmN0aW9uKGZpZWxkJCQxKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIG5leHQ6IGZ1bmN0aW9uKHcpIHsgcmV0dXJuIGZpZWxkJCQxKHcuZGF0YVt3LmkwXSk7IH1cbiAgICB9O1xuICB9LFxuICBsYXN0X3ZhbHVlOiBmdW5jdGlvbihmaWVsZCQkMSkge1xuICAgIHJldHVybiB7XG4gICAgICBuZXh0OiBmdW5jdGlvbih3KSB7IHJldHVybiBmaWVsZCQkMSh3LmRhdGFbdy5pMSAtIDFdKTsgfVxuICAgIH1cbiAgfSxcbiAgbnRoX3ZhbHVlOiBmdW5jdGlvbihmaWVsZCQkMSwgbnRoKSB7XG4gICAgbnRoID0gK250aDtcbiAgICBpZiAoIShudGggPiAwKSkgZXJyb3IkMSgnbnRoX3ZhbHVlIG50aCBtdXN0IGJlIGdyZWF0ZXIgdGhhbiB6ZXJvLicpO1xuICAgIHJldHVybiB7XG4gICAgICBuZXh0OiBmdW5jdGlvbih3KSB7XG4gICAgICAgIHZhciBpID0gdy5pMCArIChudGggLSAxKTtcbiAgICAgICAgcmV0dXJuIGkgPCB3LmkxID8gZmllbGQkJDEody5kYXRhW2ldKSA6IG51bGw7XG4gICAgICB9XG4gICAgfVxuICB9XG59O1xuXG52YXIgVmFsaWRXaW5kb3dPcHMgPSBPYmplY3Qua2V5cyhXaW5kb3dPcHMpO1xuXG5mdW5jdGlvbiBXaW5kb3dTdGF0ZShfKSB7XG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIG9wcyA9IGFycmF5KF8ub3BzKSxcbiAgICAgIGZpZWxkcyA9IGFycmF5KF8uZmllbGRzKSxcbiAgICAgIHBhcmFtcyA9IGFycmF5KF8ucGFyYW1zKSxcbiAgICAgIGFzID0gYXJyYXkoXy5hcyksXG4gICAgICBvdXRwdXRzID0gc2VsZi5vdXRwdXRzID0gW10sXG4gICAgICB3aW5kb3dzID0gc2VsZi53aW5kb3dzID0gW10sXG4gICAgICBpbnB1dHMgPSB7fSxcbiAgICAgIG1hcCA9IHt9LFxuICAgICAgY291bnRPbmx5ID0gdHJ1ZSxcbiAgICAgIGNvdW50cyA9IFtdLFxuICAgICAgbWVhc3VyZXMgPSBbXTtcblxuICBmdW5jdGlvbiB2aXNpdElucHV0cyhmKSB7XG4gICAgYXJyYXkoYWNjZXNzb3JGaWVsZHMoZikpLmZvckVhY2goZnVuY3Rpb24oXykgeyBpbnB1dHNbX10gPSAxOyB9KTtcbiAgfVxuICB2aXNpdElucHV0cyhfLnNvcnQpO1xuXG4gIG9wcy5mb3JFYWNoKGZ1bmN0aW9uKG9wLCBpKSB7XG4gICAgdmFyIGZpZWxkJCQxID0gZmllbGRzW2ldLFxuICAgICAgICBtbmFtZSA9IGFjY2Vzc29yTmFtZShmaWVsZCQkMSksXG4gICAgICAgIG5hbWUgPSBtZWFzdXJlTmFtZShvcCwgbW5hbWUsIGFzW2ldKTtcblxuICAgIHZpc2l0SW5wdXRzKGZpZWxkJCQxKTtcbiAgICBvdXRwdXRzLnB1c2gobmFtZSk7XG5cbiAgICAvLyBXaW5kb3cgb3BlcmF0aW9uXG4gICAgaWYgKFdpbmRvd09wcy5oYXNPd25Qcm9wZXJ0eShvcCkpIHtcbiAgICAgIHdpbmRvd3MucHVzaChXaW5kb3dPcChvcCwgZmllbGRzW2ldLCBwYXJhbXNbaV0sIG5hbWUpKTtcbiAgICB9XG5cbiAgICAvLyBBZ2dyZWdhdGUgb3BlcmF0aW9uXG4gICAgZWxzZSB7XG4gICAgICBpZiAoZmllbGQkJDEgPT0gbnVsbCAmJiBvcCAhPT0gJ2NvdW50Jykge1xuICAgICAgICBlcnJvciQxKCdOdWxsIGFnZ3JlZ2F0ZSBmaWVsZCBzcGVjaWZpZWQuJyk7XG4gICAgICB9XG4gICAgICBpZiAob3AgPT09ICdjb3VudCcpIHtcbiAgICAgICAgY291bnRzLnB1c2gobmFtZSk7XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgY291bnRPbmx5ID0gZmFsc2U7XG4gICAgICB2YXIgbSA9IG1hcFttbmFtZV07XG4gICAgICBpZiAoIW0pIHtcbiAgICAgICAgbSA9IChtYXBbbW5hbWVdID0gW10pO1xuICAgICAgICBtLmZpZWxkID0gZmllbGQkJDE7XG4gICAgICAgIG1lYXN1cmVzLnB1c2gobSk7XG4gICAgICB9XG4gICAgICBtLnB1c2goY3JlYXRlTWVhc3VyZShvcCwgbmFtZSkpO1xuICAgIH1cbiAgfSk7XG5cbiAgaWYgKGNvdW50cy5sZW5ndGggfHwgbWVhc3VyZXMubGVuZ3RoKSB7XG4gICAgc2VsZi5jZWxsID0gY2VsbChtZWFzdXJlcywgY291bnRzLCBjb3VudE9ubHkpO1xuICB9XG5cbiAgc2VsZi5pbnB1dHMgPSBPYmplY3Qua2V5cyhpbnB1dHMpO1xufVxuXG52YXIgcHJvdG90eXBlJDM3ID0gV2luZG93U3RhdGUucHJvdG90eXBlO1xuXG5wcm90b3R5cGUkMzcuaW5pdCA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLndpbmRvd3MuZm9yRWFjaChmdW5jdGlvbihfKSB7IF8uaW5pdCgpOyB9KTtcbiAgaWYgKHRoaXMuY2VsbCkgdGhpcy5jZWxsLmluaXQoKTtcbn07XG5cbnByb3RvdHlwZSQzNy51cGRhdGUgPSBmdW5jdGlvbih3LCB0KSB7XG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIGNlbGwgPSBzZWxmLmNlbGwsXG4gICAgICB3aW5kID0gc2VsZi53aW5kb3dzLFxuICAgICAgZGF0YSA9IHcuZGF0YSxcbiAgICAgIG0gPSB3aW5kICYmIHdpbmQubGVuZ3RoLFxuICAgICAgajtcblxuICBpZiAoY2VsbCkge1xuICAgIGZvciAoaj13LnAwOyBqPHcuaTA7ICsraikgY2VsbC5yZW0oZGF0YVtqXSk7XG4gICAgZm9yIChqPXcucDE7IGo8dy5pMTsgKytqKSBjZWxsLmFkZChkYXRhW2pdKTtcbiAgICBjZWxsLnNldCh0KTtcbiAgfVxuICBmb3IgKGo9MDsgajxtOyArK2opIHdpbmRbal0udXBkYXRlKHcsIHQpO1xufTtcblxuZnVuY3Rpb24gY2VsbChtZWFzdXJlcywgY291bnRzLCBjb3VudE9ubHkpIHtcbiAgbWVhc3VyZXMgPSBtZWFzdXJlcy5tYXAoZnVuY3Rpb24obSkge1xuICAgIHJldHVybiBjb21waWxlTWVhc3VyZXMobSwgbS5maWVsZCk7XG4gIH0pO1xuXG4gIHZhciBjZWxsID0ge1xuICAgIG51bTogICAwLFxuICAgIGFnZzogICBudWxsLFxuICAgIHN0b3JlOiBmYWxzZSxcbiAgICBjb3VudDogY291bnRzXG4gIH07XG5cbiAgaWYgKCFjb3VudE9ubHkpIHtcbiAgICB2YXIgbiA9IG1lYXN1cmVzLmxlbmd0aCxcbiAgICAgICAgYSA9IGNlbGwuYWdnID0gQXJyYXkobiksXG4gICAgICAgIGkgPSAwO1xuICAgIGZvciAoOyBpPG47ICsraSkgYVtpXSA9IG5ldyBtZWFzdXJlc1tpXShjZWxsKTtcbiAgfVxuXG4gIGlmIChjZWxsLnN0b3JlKSB7XG4gICAgdmFyIHN0b3JlID0gY2VsbC5kYXRhID0gbmV3IFR1cGxlU3RvcmUoKTtcbiAgfVxuXG4gIGNlbGwuYWRkID0gZnVuY3Rpb24odCkge1xuICAgIGNlbGwubnVtICs9IDE7XG4gICAgaWYgKGNvdW50T25seSkgcmV0dXJuO1xuICAgIGlmIChzdG9yZSkgc3RvcmUuYWRkKHQpO1xuICAgIGZvciAodmFyIGk9MDsgaTxuOyArK2kpIHtcbiAgICAgIGFbaV0uYWRkKGFbaV0uZ2V0KHQpLCB0KTtcbiAgICB9XG4gIH07XG5cbiAgY2VsbC5yZW0gPSBmdW5jdGlvbih0KSB7XG4gICAgY2VsbC5udW0gLT0gMTtcbiAgICBpZiAoY291bnRPbmx5KSByZXR1cm47XG4gICAgaWYgKHN0b3JlKSBzdG9yZS5yZW0odCk7XG4gICAgZm9yICh2YXIgaT0wOyBpPG47ICsraSkge1xuICAgICAgYVtpXS5yZW0oYVtpXS5nZXQodCksIHQpO1xuICAgIH1cbiAgfTtcblxuICBjZWxsLnNldCA9IGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgaSwgbjtcblxuICAgIC8vIGNvbnNvbGlkYXRlIHN0b3JlZCB2YWx1ZXNcbiAgICBpZiAoc3RvcmUpIHN0b3JlLnZhbHVlcygpO1xuXG4gICAgLy8gdXBkYXRlIHR1cGxlIHByb3BlcnRpZXNcbiAgICBmb3IgKGk9MCwgbj1jb3VudHMubGVuZ3RoOyBpPG47ICsraSkgdFtjb3VudHNbaV1dID0gY2VsbC5udW07XG4gICAgaWYgKCFjb3VudE9ubHkpIGZvciAoaT0wLCBuPWEubGVuZ3RoOyBpPG47ICsraSkgYVtpXS5zZXQodCk7XG4gIH07XG5cbiAgY2VsbC5pbml0ID0gZnVuY3Rpb24oKSB7XG4gICAgY2VsbC5udW0gPSAwO1xuICAgIGlmIChzdG9yZSkgc3RvcmUucmVzZXQoKTtcbiAgICBmb3IgKHZhciBpPTA7IGk8bjsgKytpKSBhW2ldLmluaXQoKTtcbiAgfTtcblxuICByZXR1cm4gY2VsbDtcbn1cblxuLyoqXG4gKiBQZXJmb3JtIHdpbmRvdyBjYWxjdWxhdGlvbnMgYW5kIHdyaXRlIHJlc3VsdHMgdG8gdGhlIGlucHV0IHN0cmVhbS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbigqLCopOiBudW1iZXJ9IFtwYXJhbXMuc29ydF0gLSBBIGNvbXBhcmF0b3IgZnVuY3Rpb24gZm9yIHNvcnRpbmcgdHVwbGVzIHdpdGhpbiBhIHdpbmRvdy5cbiAqIEBwYXJhbSB7QXJyYXk8ZnVuY3Rpb24ob2JqZWN0KTogKj59IFtwYXJhbXMuZ3JvdXBieV0gLSBBbiBhcnJheSBvZiBhY2Nlc3NvcnMgYnkgd2hpY2ggdG8gcGFydGl0aW9uIHR1cGxlcyBpbnRvIHNlcGFyYXRlIHdpbmRvd3MuXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IHBhcmFtcy5vcHMgLSBBbiBhcnJheSBvZiBzdHJpbmdzIGluZGljYXRpbmcgd2luZG93IG9wZXJhdGlvbnMgdG8gcGVyZm9ybS5cbiAqIEBwYXJhbSB7QXJyYXk8ZnVuY3Rpb24ob2JqZWN0KTogKj59IFtwYXJhbXMuZmllbGRzXSAtIEFuIGFycmF5IG9mIGFjY2Vzc29yc1xuICogICBmb3IgZGF0YSBmaWVsZHMgdG8gdXNlIGFzIGlucHV0cyB0byB3aW5kb3cgb3BlcmF0aW9ucy5cbiAqIEBwYXJhbSB7QXJyYXk8Kj59IFtwYXJhbXMucGFyYW1zXSAtIEFuIGFycmF5IG9mIHBhcmFtZXRlciB2YWx1ZXMgZm9yIHdpbmRvdyBvcGVyYXRpb25zLlxuICogQHBhcmFtIHtBcnJheTxzdHJpbmc+fSBbcGFyYW1zLmFzXSAtIEFuIGFycmF5IG9mIG91dHB1dCBmaWVsZCBuYW1lcyBmb3Igd2luZG93IG9wZXJhdGlvbnMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IFtwYXJhbXMuZnJhbWVdIC0gV2luZG93IGZyYW1lIGRlZmluaXRpb24gYXMgdHdvLWVsZW1lbnQgYXJyYXkuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtwYXJhbXMuaWdub3JlUGVlcnM9ZmFsc2VdIC0gSWYgdHJ1ZSwgYmFzZSB3aW5kb3cgZnJhbWUgYm91bmRhcmllcyBvbiByb3dcbiAqICAgbnVtYmVyIGFsb25lLCBpZ25vcmluZyBwZWVycyB3aXRoIGlkZW50aWNhbCBzb3J0IHZhbHVlcy4gSWYgZmFsc2UgKGRlZmF1bHQpLFxuICogICB0aGUgd2luZG93IGJvdW5kYXJpZXMgd2lsbCBiZSBhZGp1c3RlZCB0byBpbmNsdWRlIHBlZXIgdmFsdWVzLlxuICovXG5mdW5jdGlvbiBXaW5kb3cocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIHt9LCBwYXJhbXMpO1xuICB0aGlzLl9tbGVuID0gMDtcbiAgdGhpcy5fbW9kcyA9IFtdO1xufVxuXG5XaW5kb3cuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiV2luZG93XCIsXG4gIFwibWV0YWRhdGFcIjoge1wibW9kaWZpZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcInNvcnRcIiwgXCJ0eXBlXCI6IFwiY29tcGFyZVwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJncm91cGJ5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwib3BzXCIsIFwidHlwZVwiOiBcImVudW1cIiwgXCJhcnJheVwiOiB0cnVlLCBcInZhbHVlc1wiOiBWYWxpZFdpbmRvd09wcy5jb25jYXQoVmFsaWRBZ2dyZWdhdGVPcHMpIH0sXG4gICAgeyBcIm5hbWVcIjogXCJwYXJhbXNcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwibnVsbFwiOiB0cnVlLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkc1wiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcIm51bGxcIjogdHJ1ZSwgXCJhcnJheVwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJhc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJudWxsXCI6IHRydWUsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZnJhbWVcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwibnVsbFwiOiB0cnVlLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsIFwiZGVmYXVsdFwiOiBbbnVsbCwgMF0gfSxcbiAgICB7IFwibmFtZVwiOiBcImlnbm9yZVBlZXJzXCIsIFwidHlwZVwiOiBcImJvb2xlYW5cIiwgXCJkZWZhdWx0XCI6IGZhbHNlIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQzNiA9IGluaGVyaXRzKFdpbmRvdywgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDM2LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIHN0YXRlID0gc2VsZi5zdGF0ZSxcbiAgICAgIG1vZCA9IF8ubW9kaWZpZWQoKSxcbiAgICAgIGksIG47XG5cbiAgdGhpcy5zdGFtcCA9IHB1bHNlLnN0YW1wO1xuXG4gIC8vIGluaXRpYWxpemUgd2luZG93IHN0YXRlXG4gIGlmICghc3RhdGUgfHwgbW9kKSB7XG4gICAgc3RhdGUgPSBzZWxmLnN0YXRlID0gbmV3IFdpbmRvd1N0YXRlKF8pO1xuICB9XG5cbiAgLy8gcmV0cmlldmUgZ3JvdXAgZm9yIGEgdHVwbGVcbiAgdmFyIGtleSQkMSA9IGdyb3Vwa2V5KF8uZ3JvdXBieSk7XG4gIGZ1bmN0aW9uIGdyb3VwKHQpIHsgcmV0dXJuIHNlbGYuZ3JvdXAoa2V5JCQxKHQpKTsgfVxuXG4gIC8vIHBhcnRpdGlvbiBpbnB1dCB0dXBsZXNcbiAgaWYgKG1vZCB8fCBwdWxzZS5tb2RpZmllZChzdGF0ZS5pbnB1dHMpKSB7XG4gICAgc2VsZi52YWx1ZSA9IHt9O1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlNPVVJDRSwgZnVuY3Rpb24odCkgeyBncm91cCh0KS5hZGQodCk7IH0pO1xuICB9IGVsc2Uge1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLlJFTSwgZnVuY3Rpb24odCkgeyBncm91cCh0KS5yZW1vdmUodCk7IH0pO1xuICAgIHB1bHNlLnZpc2l0KHB1bHNlLkFERCwgZnVuY3Rpb24odCkgeyBncm91cCh0KS5hZGQodCk7IH0pO1xuICB9XG5cbiAgLy8gcGVyZm9ybSB3aW5kb3cgY2FsY3VsYXRpb25zIGZvciBlYWNoIG1vZGlmaWVkIHBhcnRpdGlvblxuICBmb3IgKGk9MCwgbj1zZWxmLl9tbGVuOyBpPG47ICsraSkge1xuICAgIHByb2Nlc3NQYXJ0aXRpb24oc2VsZi5fbW9kc1tpXSwgc3RhdGUsIF8pO1xuICB9XG4gIHNlbGYuX21sZW4gPSAwO1xuICBzZWxmLl9tb2RzID0gW107XG5cbiAgLy8gVE9ETyBkb24ndCByZWZsb3cgZXZlcnl0aGluZz9cbiAgcmV0dXJuIHB1bHNlLnJlZmxvdyhtb2QpLm1vZGlmaWVzKHN0YXRlLm91dHB1dHMpO1xufTtcblxucHJvdG90eXBlJDM2Lmdyb3VwID0gZnVuY3Rpb24oa2V5JCQxKSB7XG4gIHZhciBzZWxmID0gdGhpcyxcbiAgICAgIGdyb3VwID0gc2VsZi52YWx1ZVtrZXkkJDFdO1xuXG4gIGlmICghZ3JvdXApIHtcbiAgICBncm91cCA9IHNlbGYudmFsdWVba2V5JCQxXSA9IFNvcnRlZExpc3QodHVwbGVpZCk7XG4gICAgZ3JvdXAuc3RhbXAgPSAtMTtcbiAgfVxuXG4gIGlmIChncm91cC5zdGFtcCA8IHNlbGYuc3RhbXApIHtcbiAgICBncm91cC5zdGFtcCA9IHNlbGYuc3RhbXA7XG4gICAgc2VsZi5fbW9kc1tzZWxmLl9tbGVuKytdID0gZ3JvdXA7XG4gIH1cblxuICByZXR1cm4gZ3JvdXA7XG59O1xuXG5mdW5jdGlvbiBwcm9jZXNzUGFydGl0aW9uKGxpc3QsIHN0YXRlLCBfKSB7XG4gIHZhciBzb3J0ID0gXy5zb3J0LFxuICAgICAgcmFuZ2UgPSBzb3J0ICYmICFfLmlnbm9yZVBlZXJzLFxuICAgICAgZnJhbWUgPSBfLmZyYW1lIHx8IFtudWxsLCAwXSxcbiAgICAgIGRhdGEgPSBsaXN0LmRhdGEoc29ydCksXG4gICAgICBuID0gZGF0YS5sZW5ndGgsXG4gICAgICBpID0gMCxcbiAgICAgIGIgPSByYW5nZSA/IGJpc2VjdG9yKHNvcnQpIDogbnVsbCxcbiAgICAgIHcgPSB7XG4gICAgICAgIGkwOiAwLCBpMTogMCwgcDA6IDAsIHAxOiAwLCBpbmRleDogMCxcbiAgICAgICAgZGF0YTogZGF0YSwgY29tcGFyZTogc29ydCB8fCBjb25zdGFudCgtMSlcbiAgICAgIH07XG5cbiAgZm9yIChzdGF0ZS5pbml0KCk7IGk8bjsgKytpKSB7XG4gICAgc2V0V2luZG93KHcsIGZyYW1lLCBpLCBuKTtcbiAgICBpZiAocmFuZ2UpIGFkanVzdFJhbmdlKHcsIGIpO1xuICAgIHN0YXRlLnVwZGF0ZSh3LCBkYXRhW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzZXRXaW5kb3codywgZiwgaSwgbikge1xuICB3LnAwID0gdy5pMDtcbiAgdy5wMSA9IHcuaTE7XG4gIHcuaTAgPSBmWzBdID09IG51bGwgPyAwIDogTWF0aC5tYXgoMCwgaSAtIE1hdGguYWJzKGZbMF0pKTtcbiAgdy5pMSA9IGZbMV0gPT0gbnVsbCA/IG4gOiBNYXRoLm1pbihuLCBpICsgTWF0aC5hYnMoZlsxXSkgKyAxKTtcbiAgdy5pbmRleCA9IGk7XG59XG5cbi8vIGlmIGZyYW1lIHR5cGUgaXMgJ3JhbmdlJywgYWRqdXN0IHdpbmRvdyBmb3IgcGVlciB2YWx1ZXNcbmZ1bmN0aW9uIGFkanVzdFJhbmdlKHcsIGJpc2VjdCkge1xuICB2YXIgcjAgPSB3LmkwLFxuICAgICAgcjEgPSB3LmkxIC0gMSxcbiAgICAgIGMgPSB3LmNvbXBhcmUsXG4gICAgICBkID0gdy5kYXRhLFxuICAgICAgbiA9IGQubGVuZ3RoIC0gMTtcblxuICBpZiAocjAgPiAwICYmICFjKGRbcjBdLCBkW3IwLTFdKSkgdy5pMCA9IGJpc2VjdC5sZWZ0KGQsIGRbcjBdKTtcbiAgaWYgKHIxIDwgbiAmJiAhYyhkW3IxXSwgZFtyMSsxXSkpIHcuaTEgPSBiaXNlY3QucmlnaHQoZCwgZFtyMV0pO1xufVxuXG5cblxudmFyIHR4ID0gT2JqZWN0LmZyZWV6ZSh7XG5cdGFnZ3JlZ2F0ZTogQWdncmVnYXRlLFxuXHRiaW46IEJpbixcblx0Y29sbGVjdDogQ29sbGVjdCxcblx0Y29tcGFyZTogQ29tcGFyZSxcblx0Y291bnRwYXR0ZXJuOiBDb3VudFBhdHRlcm4sXG5cdGNyb3NzOiBDcm9zcyxcblx0ZGVuc2l0eTogRGVuc2l0eSxcblx0ZXh0ZW50OiBFeHRlbnQsXG5cdGZhY2V0OiBGYWNldCxcblx0ZmllbGQ6IEZpZWxkLFxuXHRmaWx0ZXI6IEZpbHRlcixcblx0ZmxhdHRlbjogRmxhdHRlbixcblx0Zm9sZDogRm9sZCxcblx0Zm9ybXVsYTogRm9ybXVsYSxcblx0Z2VuZXJhdGU6IEdlbmVyYXRlLFxuXHRpbXB1dGU6IEltcHV0ZSxcblx0am9pbmFnZ3JlZ2F0ZTogSm9pbkFnZ3JlZ2F0ZSxcblx0a2V5OiBLZXksXG5cdGxvb2t1cDogTG9va3VwLFxuXHRtdWx0aWV4dGVudDogTXVsdGlFeHRlbnQsXG5cdG11bHRpdmFsdWVzOiBNdWx0aVZhbHVlcyxcblx0cGFyYW1zOiBQYXJhbXMsXG5cdHBpdm90OiBQaXZvdCxcblx0cHJlZmFjZXQ6IFByZUZhY2V0LFxuXHRwcm9qZWN0OiBQcm9qZWN0LFxuXHRwcm94eTogUHJveHksXG5cdHJlbGF5OiBSZWxheSxcblx0c2FtcGxlOiBTYW1wbGUsXG5cdHNlcXVlbmNlOiBTZXF1ZW5jZSxcblx0c2lldmU6IFNpZXZlLFxuXHRzdWJmbG93OiBTdWJmbG93LFxuXHR0dXBsZWluZGV4OiBUdXBsZUluZGV4LFxuXHR2YWx1ZXM6IFZhbHVlcyxcblx0d2luZG93OiBXaW5kb3dcbn0pO1xuXG5mdW5jdGlvbiBCb3VuZHMoYikge1xuICB0aGlzLmNsZWFyKCk7XG4gIGlmIChiKSB0aGlzLnVuaW9uKGIpO1xufVxuXG52YXIgcHJvdG90eXBlJDM5ID0gQm91bmRzLnByb3RvdHlwZTtcblxucHJvdG90eXBlJDM5LmNsb25lID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgQm91bmRzKHRoaXMpO1xufTtcblxucHJvdG90eXBlJDM5LmNsZWFyID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMueDEgPSArTnVtYmVyLk1BWF9WQUxVRTtcbiAgdGhpcy55MSA9ICtOdW1iZXIuTUFYX1ZBTFVFO1xuICB0aGlzLngyID0gLU51bWJlci5NQVhfVkFMVUU7XG4gIHRoaXMueTIgPSAtTnVtYmVyLk1BWF9WQUxVRTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5wcm90b3R5cGUkMzkuZW1wdHkgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIChcbiAgICB0aGlzLngxID09PSArTnVtYmVyLk1BWF9WQUxVRSAmJlxuICAgIHRoaXMueTEgPT09ICtOdW1iZXIuTUFYX1ZBTFVFICYmXG4gICAgdGhpcy54MiA9PT0gLU51bWJlci5NQVhfVkFMVUUgJiZcbiAgICB0aGlzLnkyID09PSAtTnVtYmVyLk1BWF9WQUxVRVxuICApO1xufTtcblxucHJvdG90eXBlJDM5LnNldCA9IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyKSB7XG4gIGlmICh4MiA8IHgxKSB7XG4gICAgdGhpcy54MiA9IHgxO1xuICAgIHRoaXMueDEgPSB4MjtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLngxID0geDE7XG4gICAgdGhpcy54MiA9IHgyO1xuICB9XG4gIGlmICh5MiA8IHkxKSB7XG4gICAgdGhpcy55MiA9IHkxO1xuICAgIHRoaXMueTEgPSB5MjtcbiAgfSBlbHNlIHtcbiAgICB0aGlzLnkxID0geTE7XG4gICAgdGhpcy55MiA9IHkyO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDM5LmFkZCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgaWYgKHggPCB0aGlzLngxKSB0aGlzLngxID0geDtcbiAgaWYgKHkgPCB0aGlzLnkxKSB0aGlzLnkxID0geTtcbiAgaWYgKHggPiB0aGlzLngyKSB0aGlzLngyID0geDtcbiAgaWYgKHkgPiB0aGlzLnkyKSB0aGlzLnkyID0geTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5wcm90b3R5cGUkMzkuZXhwYW5kID0gZnVuY3Rpb24oZCkge1xuICB0aGlzLngxIC09IGQ7XG4gIHRoaXMueTEgLT0gZDtcbiAgdGhpcy54MiArPSBkO1xuICB0aGlzLnkyICs9IGQ7XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDM5LnJvdW5kID0gZnVuY3Rpb24oKSB7XG4gIHRoaXMueDEgPSBNYXRoLmZsb29yKHRoaXMueDEpO1xuICB0aGlzLnkxID0gTWF0aC5mbG9vcih0aGlzLnkxKTtcbiAgdGhpcy54MiA9IE1hdGguY2VpbCh0aGlzLngyKTtcbiAgdGhpcy55MiA9IE1hdGguY2VpbCh0aGlzLnkyKTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5wcm90b3R5cGUkMzkudHJhbnNsYXRlID0gZnVuY3Rpb24oZHgsIGR5KSB7XG4gIHRoaXMueDEgKz0gZHg7XG4gIHRoaXMueDIgKz0gZHg7XG4gIHRoaXMueTEgKz0gZHk7XG4gIHRoaXMueTIgKz0gZHk7XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDM5LnJvdGF0ZSA9IGZ1bmN0aW9uKGFuZ2xlLCB4LCB5KSB7XG4gIHZhciBjb3MgPSBNYXRoLmNvcyhhbmdsZSksXG4gICAgICBzaW4gPSBNYXRoLnNpbihhbmdsZSksXG4gICAgICBjeCA9IHggLSB4KmNvcyArIHkqc2luLFxuICAgICAgY3kgPSB5IC0geCpzaW4gLSB5KmNvcyxcbiAgICAgIHgxID0gdGhpcy54MSwgeDIgPSB0aGlzLngyLFxuICAgICAgeTEgPSB0aGlzLnkxLCB5MiA9IHRoaXMueTI7XG5cbiAgcmV0dXJuIHRoaXMuY2xlYXIoKVxuICAgIC5hZGQoY29zKngxIC0gc2luKnkxICsgY3gsICBzaW4qeDEgKyBjb3MqeTEgKyBjeSlcbiAgICAuYWRkKGNvcyp4MSAtIHNpbip5MiArIGN4LCAgc2luKngxICsgY29zKnkyICsgY3kpXG4gICAgLmFkZChjb3MqeDIgLSBzaW4qeTEgKyBjeCwgIHNpbip4MiArIGNvcyp5MSArIGN5KVxuICAgIC5hZGQoY29zKngyIC0gc2luKnkyICsgY3gsICBzaW4qeDIgKyBjb3MqeTIgKyBjeSk7XG59O1xuXG5wcm90b3R5cGUkMzkudW5pb24gPSBmdW5jdGlvbihiKSB7XG4gIGlmIChiLngxIDwgdGhpcy54MSkgdGhpcy54MSA9IGIueDE7XG4gIGlmIChiLnkxIDwgdGhpcy55MSkgdGhpcy55MSA9IGIueTE7XG4gIGlmIChiLngyID4gdGhpcy54MikgdGhpcy54MiA9IGIueDI7XG4gIGlmIChiLnkyID4gdGhpcy55MikgdGhpcy55MiA9IGIueTI7XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDM5LmludGVyc2VjdCA9IGZ1bmN0aW9uKGIpIHtcbiAgaWYgKGIueDEgPiB0aGlzLngxKSB0aGlzLngxID0gYi54MTtcbiAgaWYgKGIueTEgPiB0aGlzLnkxKSB0aGlzLnkxID0gYi55MTtcbiAgaWYgKGIueDIgPCB0aGlzLngyKSB0aGlzLngyID0gYi54MjtcbiAgaWYgKGIueTIgPCB0aGlzLnkyKSB0aGlzLnkyID0gYi55MjtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG5wcm90b3R5cGUkMzkuZW5jbG9zZXMgPSBmdW5jdGlvbihiKSB7XG4gIHJldHVybiBiICYmIChcbiAgICB0aGlzLngxIDw9IGIueDEgJiZcbiAgICB0aGlzLngyID49IGIueDIgJiZcbiAgICB0aGlzLnkxIDw9IGIueTEgJiZcbiAgICB0aGlzLnkyID49IGIueTJcbiAgKTtcbn07XG5cbnByb3RvdHlwZSQzOS5hbGlnbnNXaXRoID0gZnVuY3Rpb24oYikge1xuICByZXR1cm4gYiAmJiAoXG4gICAgdGhpcy54MSA9PSBiLngxIHx8XG4gICAgdGhpcy54MiA9PSBiLngyIHx8XG4gICAgdGhpcy55MSA9PSBiLnkxIHx8XG4gICAgdGhpcy55MiA9PSBiLnkyXG4gICk7XG59O1xuXG5wcm90b3R5cGUkMzkuaW50ZXJzZWN0cyA9IGZ1bmN0aW9uKGIpIHtcbiAgcmV0dXJuIGIgJiYgIShcbiAgICB0aGlzLngyIDwgYi54MSB8fFxuICAgIHRoaXMueDEgPiBiLngyIHx8XG4gICAgdGhpcy55MiA8IGIueTEgfHxcbiAgICB0aGlzLnkxID4gYi55MlxuICApO1xufTtcblxucHJvdG90eXBlJDM5LmNvbnRhaW5zID0gZnVuY3Rpb24oeCwgeSkge1xuICByZXR1cm4gIShcbiAgICB4IDwgdGhpcy54MSB8fFxuICAgIHggPiB0aGlzLngyIHx8XG4gICAgeSA8IHRoaXMueTEgfHxcbiAgICB5ID4gdGhpcy55MlxuICApO1xufTtcblxucHJvdG90eXBlJDM5LndpZHRoID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLngyIC0gdGhpcy54MTtcbn07XG5cbnByb3RvdHlwZSQzOS5oZWlnaHQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMueTIgLSB0aGlzLnkxO1xufTtcblxudmFyIGdyYWRpZW50X2lkID0gMDtcblxudmFyIEdyYWRpZW50ID0gZnVuY3Rpb24ocDAsIHAxKSB7XG4gIHZhciBzdG9wcyA9IFtdLCBncmFkaWVudDtcbiAgcmV0dXJuIGdyYWRpZW50ID0ge1xuICAgIGlkOiAnZ3JhZGllbnRfJyArIChncmFkaWVudF9pZCsrKSxcbiAgICB4MTogcDAgPyBwMFswXSA6IDAsXG4gICAgeTE6IHAwID8gcDBbMV0gOiAwLFxuICAgIHgyOiBwMSA/IHAxWzBdIDogMSxcbiAgICB5MjogcDEgPyBwMVsxXSA6IDAsXG4gICAgc3RvcHM6IHN0b3BzLFxuICAgIHN0b3A6IGZ1bmN0aW9uKG9mZnNldCwgY29sb3IpIHtcbiAgICAgIHN0b3BzLnB1c2goe29mZnNldDogb2Zmc2V0LCBjb2xvcjogY29sb3J9KTtcbiAgICAgIHJldHVybiBncmFkaWVudDtcbiAgICB9XG4gIH07XG59O1xuXG5mdW5jdGlvbiBJdGVtKG1hcmspIHtcbiAgdGhpcy5tYXJrID0gbWFyaztcbiAgdGhpcy5ib3VuZHMgPSAodGhpcy5ib3VuZHMgfHwgbmV3IEJvdW5kcygpKTtcbn1cblxuZnVuY3Rpb24gR3JvdXBJdGVtKG1hcmspIHtcbiAgSXRlbS5jYWxsKHRoaXMsIG1hcmspO1xuICB0aGlzLml0ZW1zID0gKHRoaXMuaXRlbXMgfHwgW10pO1xufVxuXG5pbmhlcml0cyhHcm91cEl0ZW0sIEl0ZW0pO1xuXG5mdW5jdGlvbiBkb21DYW52YXModywgaCkge1xuICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KSB7XG4gICAgdmFyIGMgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50KCdjYW52YXMnKTtcbiAgICBpZiAoYyAmJiBjLmdldENvbnRleHQpIHtcbiAgICAgIGMud2lkdGggPSB3O1xuICAgICAgYy5oZWlnaHQgPSBoO1xuICAgICAgcmV0dXJuIGM7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufVxuXG5mdW5jdGlvbiBkb21JbWFnZSgpIHtcbiAgcmV0dXJuIHR5cGVvZiBJbWFnZSAhPT0gJ3VuZGVmaW5lZCcgPyBJbWFnZSA6IG51bGw7XG59XG5cbnZhciBOb2RlQ2FudmFzO1xuXG50cnkge1xuICAvLyB0cnkgdG8gbG9hZCBjYW52YXMgbW9kdWxlXG4gIE5vZGVDYW52YXMgPSByZXF1aXJlKCdjYW52YXMnKTtcbiAgaWYgKCFOb2RlQ2FudmFzKSB0aHJvdyAxO1xufSBjYXRjaCAoZSkge1xuICB0cnkge1xuICAgIC8vIGlmIGNhbnZhcyBmYWlscywgdHJ5IHRvIGxvYWQgY2FudmFzLXByZWJ1aWx0XG4gICAgTm9kZUNhbnZhcyA9IHJlcXVpcmUoJ2NhbnZhcy1wcmVidWlsdCcpO1xuICB9IGNhdGNoIChlMikge1xuICAgIC8vIGlmIGFsbCBvcHRpb25zIGZhaWwsIHNldCB0byBudWxsXG4gICAgTm9kZUNhbnZhcyA9IG51bGw7XG4gIH1cbn1cblxuZnVuY3Rpb24gbm9kZUNhbnZhcyh3LCBoKSB7XG4gIGlmIChOb2RlQ2FudmFzKSB7XG4gICAgdHJ5IHtcbiAgICAgIHJldHVybiBuZXcgTm9kZUNhbnZhcyh3LCBoKTtcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICAvLyBkbyBub3RoaW5nLCByZXR1cm4gbnVsbCBvbiBlcnJvclxuICAgIH1cbiAgfVxuICByZXR1cm4gbnVsbDtcbn1cblxuZnVuY3Rpb24gbm9kZUltYWdlKCkge1xuICByZXR1cm4gTm9kZUNhbnZhcyAmJiBOb2RlQ2FudmFzLkltYWdlIHx8IG51bGw7XG59XG5cbmZ1bmN0aW9uIGNhbnZhcyh3LCBoKSB7XG4gIHJldHVybiBkb21DYW52YXModywgaCkgfHwgbm9kZUNhbnZhcyh3LCBoKSB8fCBudWxsO1xufVxuXG5mdW5jdGlvbiBpbWFnZSgpIHtcbiAgcmV0dXJuIGRvbUltYWdlKCkgfHwgbm9kZUltYWdlKCkgfHwgbnVsbDtcbn1cblxuZnVuY3Rpb24gUmVzb3VyY2VMb2FkZXIoY3VzdG9tTG9hZGVyKSB7XG4gIHRoaXMuX3BlbmRpbmcgPSAwO1xuICB0aGlzLl9sb2FkZXIgPSBjdXN0b21Mb2FkZXIgfHwgbG9hZGVyKCk7XG59XG5cbnZhciBwcm90b3R5cGUkNDAgPSBSZXNvdXJjZUxvYWRlci5wcm90b3R5cGU7XG5cbnByb3RvdHlwZSQ0MC5wZW5kaW5nID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9wZW5kaW5nO1xufTtcblxuZnVuY3Rpb24gaW5jcmVtZW50KGxvYWRlciQkMSkge1xuICBsb2FkZXIkJDEuX3BlbmRpbmcgKz0gMTtcbn1cblxuZnVuY3Rpb24gZGVjcmVtZW50KGxvYWRlciQkMSkge1xuICBsb2FkZXIkJDEuX3BlbmRpbmcgLT0gMTtcbn1cblxucHJvdG90eXBlJDQwLnNhbml0aXplVVJMID0gZnVuY3Rpb24odXJpKSB7XG4gIHZhciBsb2FkZXIkJDEgPSB0aGlzO1xuICBpbmNyZW1lbnQobG9hZGVyJCQxKTtcblxuICByZXR1cm4gbG9hZGVyJCQxLl9sb2FkZXIuc2FuaXRpemUodXJpLCB7Y29udGV4dDonaHJlZid9KVxuICAgIC50aGVuKGZ1bmN0aW9uKG9wdCkge1xuICAgICAgZGVjcmVtZW50KGxvYWRlciQkMSk7XG4gICAgICByZXR1cm4gb3B0O1xuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uKCkge1xuICAgICAgZGVjcmVtZW50KGxvYWRlciQkMSk7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9KTtcbn07XG5cbnByb3RvdHlwZSQ0MC5sb2FkSW1hZ2UgPSBmdW5jdGlvbih1cmkpIHtcbiAgdmFyIGxvYWRlciQkMSA9IHRoaXMsXG4gICAgICBJbWFnZSA9IGltYWdlKCk7XG4gIGluY3JlbWVudChsb2FkZXIkJDEpO1xuXG4gIHJldHVybiBsb2FkZXIkJDEuX2xvYWRlclxuICAgIC5zYW5pdGl6ZSh1cmksIHtjb250ZXh0OiAnaW1hZ2UnfSlcbiAgICAudGhlbihmdW5jdGlvbihvcHQpIHtcbiAgICAgIHZhciB1cmwgPSBvcHQuaHJlZjtcbiAgICAgIGlmICghdXJsIHx8ICFJbWFnZSkgdGhyb3cge3VybDogdXJsfTtcblxuICAgICAgdmFyIGltZyA9IG5ldyBJbWFnZSgpO1xuXG4gICAgICBpbWcub25sb2FkID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGRlY3JlbWVudChsb2FkZXIkJDEpO1xuICAgICAgICBpbWcubG9hZGVkID0gdHJ1ZTtcbiAgICAgIH07XG5cbiAgICAgIGltZy5vbmVycm9yID0gZnVuY3Rpb24oKSB7XG4gICAgICAgIGRlY3JlbWVudChsb2FkZXIkJDEpO1xuICAgICAgICBpbWcubG9hZGVkID0gZmFsc2U7XG4gICAgICB9O1xuXG4gICAgICBpbWcuc3JjID0gdXJsO1xuICAgICAgcmV0dXJuIGltZztcbiAgICB9KVxuICAgIC5jYXRjaChmdW5jdGlvbihlKSB7XG4gICAgICBkZWNyZW1lbnQobG9hZGVyJCQxKTtcbiAgICAgIHJldHVybiB7bG9hZGVkOiBmYWxzZSwgd2lkdGg6IDAsIGhlaWdodDogMCwgc3JjOiBlICYmIGUudXJsIHx8ICcnfTtcbiAgICB9KTtcbn07XG5cbnByb3RvdHlwZSQ0MC5yZWFkeSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbG9hZGVyJCQxID0gdGhpcztcbiAgcmV0dXJuIG5ldyBQcm9taXNlKGZ1bmN0aW9uKGFjY2VwdCkge1xuICAgIGZ1bmN0aW9uIHBvbGwodmFsdWUpIHtcbiAgICAgIGlmICghbG9hZGVyJCQxLnBlbmRpbmcoKSkgYWNjZXB0KHZhbHVlKTtcbiAgICAgIGVsc2Ugc2V0VGltZW91dChmdW5jdGlvbigpIHsgcG9sbCh0cnVlKTsgfSwgMTApO1xuICAgIH1cbiAgICBwb2xsKGZhbHNlKTtcbiAgfSk7XG59O1xuXG52YXIgcGkgPSBNYXRoLlBJO1xudmFyIHRhdSA9IDIgKiBwaTtcbnZhciBlcHNpbG9uID0gMWUtNjtcbnZhciB0YXVFcHNpbG9uID0gdGF1IC0gZXBzaWxvbjtcblxuZnVuY3Rpb24gUGF0aCgpIHtcbiAgdGhpcy5feDAgPSB0aGlzLl95MCA9IC8vIHN0YXJ0IG9mIGN1cnJlbnQgc3VicGF0aFxuICB0aGlzLl94MSA9IHRoaXMuX3kxID0gbnVsbDsgLy8gZW5kIG9mIGN1cnJlbnQgc3VicGF0aFxuICB0aGlzLl8gPSBcIlwiO1xufVxuXG5mdW5jdGlvbiBwYXRoKCkge1xuICByZXR1cm4gbmV3IFBhdGg7XG59XG5cblBhdGgucHJvdG90eXBlID0gcGF0aC5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBQYXRoLFxuICBtb3ZlVG86IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB0aGlzLl8gKz0gXCJNXCIgKyAodGhpcy5feDAgPSB0aGlzLl94MSA9ICt4KSArIFwiLFwiICsgKHRoaXMuX3kwID0gdGhpcy5feTEgPSAreSk7XG4gIH0sXG4gIGNsb3NlUGF0aDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX3gxICE9PSBudWxsKSB7XG4gICAgICB0aGlzLl94MSA9IHRoaXMuX3gwLCB0aGlzLl95MSA9IHRoaXMuX3kwO1xuICAgICAgdGhpcy5fICs9IFwiWlwiO1xuICAgIH1cbiAgfSxcbiAgbGluZVRvOiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdGhpcy5fICs9IFwiTFwiICsgKHRoaXMuX3gxID0gK3gpICsgXCIsXCIgKyAodGhpcy5feTEgPSAreSk7XG4gIH0sXG4gIHF1YWRyYXRpY0N1cnZlVG86IGZ1bmN0aW9uKHgxLCB5MSwgeCwgeSkge1xuICAgIHRoaXMuXyArPSBcIlFcIiArICgreDEpICsgXCIsXCIgKyAoK3kxKSArIFwiLFwiICsgKHRoaXMuX3gxID0gK3gpICsgXCIsXCIgKyAodGhpcy5feTEgPSAreSk7XG4gIH0sXG4gIGJlemllckN1cnZlVG86IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyLCB4LCB5KSB7XG4gICAgdGhpcy5fICs9IFwiQ1wiICsgKCt4MSkgKyBcIixcIiArICgreTEpICsgXCIsXCIgKyAoK3gyKSArIFwiLFwiICsgKCt5MikgKyBcIixcIiArICh0aGlzLl94MSA9ICt4KSArIFwiLFwiICsgKHRoaXMuX3kxID0gK3kpO1xuICB9LFxuICBhcmNUbzogZnVuY3Rpb24oeDEsIHkxLCB4MiwgeTIsIHIpIHtcbiAgICB4MSA9ICt4MSwgeTEgPSAreTEsIHgyID0gK3gyLCB5MiA9ICt5MiwgciA9ICtyO1xuICAgIHZhciB4MCA9IHRoaXMuX3gxLFxuICAgICAgICB5MCA9IHRoaXMuX3kxLFxuICAgICAgICB4MjEgPSB4MiAtIHgxLFxuICAgICAgICB5MjEgPSB5MiAtIHkxLFxuICAgICAgICB4MDEgPSB4MCAtIHgxLFxuICAgICAgICB5MDEgPSB5MCAtIHkxLFxuICAgICAgICBsMDFfMiA9IHgwMSAqIHgwMSArIHkwMSAqIHkwMTtcblxuICAgIC8vIElzIHRoZSByYWRpdXMgbmVnYXRpdmU/IEVycm9yLlxuICAgIGlmIChyIDwgMCkgdGhyb3cgbmV3IEVycm9yKFwibmVnYXRpdmUgcmFkaXVzOiBcIiArIHIpO1xuXG4gICAgLy8gSXMgdGhpcyBwYXRoIGVtcHR5PyBNb3ZlIHRvICh4MSx5MSkuXG4gICAgaWYgKHRoaXMuX3gxID09PSBudWxsKSB7XG4gICAgICB0aGlzLl8gKz0gXCJNXCIgKyAodGhpcy5feDEgPSB4MSkgKyBcIixcIiArICh0aGlzLl95MSA9IHkxKTtcbiAgICB9XG5cbiAgICAvLyBPciwgaXMgKHgxLHkxKSBjb2luY2lkZW50IHdpdGggKHgwLHkwKT8gRG8gbm90aGluZy5cbiAgICBlbHNlIGlmICghKGwwMV8yID4gZXBzaWxvbikpIHt9XG5cbiAgICAvLyBPciwgYXJlICh4MCx5MCksICh4MSx5MSkgYW5kICh4Mix5MikgY29sbGluZWFyP1xuICAgIC8vIEVxdWl2YWxlbnRseSwgaXMgKHgxLHkxKSBjb2luY2lkZW50IHdpdGggKHgyLHkyKT9cbiAgICAvLyBPciwgaXMgdGhlIHJhZGl1cyB6ZXJvPyBMaW5lIHRvICh4MSx5MSkuXG4gICAgZWxzZSBpZiAoIShNYXRoLmFicyh5MDEgKiB4MjEgLSB5MjEgKiB4MDEpID4gZXBzaWxvbikgfHwgIXIpIHtcbiAgICAgIHRoaXMuXyArPSBcIkxcIiArICh0aGlzLl94MSA9IHgxKSArIFwiLFwiICsgKHRoaXMuX3kxID0geTEpO1xuICAgIH1cblxuICAgIC8vIE90aGVyd2lzZSwgZHJhdyBhbiBhcmMhXG4gICAgZWxzZSB7XG4gICAgICB2YXIgeDIwID0geDIgLSB4MCxcbiAgICAgICAgICB5MjAgPSB5MiAtIHkwLFxuICAgICAgICAgIGwyMV8yID0geDIxICogeDIxICsgeTIxICogeTIxLFxuICAgICAgICAgIGwyMF8yID0geDIwICogeDIwICsgeTIwICogeTIwLFxuICAgICAgICAgIGwyMSA9IE1hdGguc3FydChsMjFfMiksXG4gICAgICAgICAgbDAxID0gTWF0aC5zcXJ0KGwwMV8yKSxcbiAgICAgICAgICBsID0gciAqIE1hdGgudGFuKChwaSAtIE1hdGguYWNvcygobDIxXzIgKyBsMDFfMiAtIGwyMF8yKSAvICgyICogbDIxICogbDAxKSkpIC8gMiksXG4gICAgICAgICAgdDAxID0gbCAvIGwwMSxcbiAgICAgICAgICB0MjEgPSBsIC8gbDIxO1xuXG4gICAgICAvLyBJZiB0aGUgc3RhcnQgdGFuZ2VudCBpcyBub3QgY29pbmNpZGVudCB3aXRoICh4MCx5MCksIGxpbmUgdG8uXG4gICAgICBpZiAoTWF0aC5hYnModDAxIC0gMSkgPiBlcHNpbG9uKSB7XG4gICAgICAgIHRoaXMuXyArPSBcIkxcIiArICh4MSArIHQwMSAqIHgwMSkgKyBcIixcIiArICh5MSArIHQwMSAqIHkwMSk7XG4gICAgICB9XG5cbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLDAsXCIgKyAoKyh5MDEgKiB4MjAgPiB4MDEgKiB5MjApKSArIFwiLFwiICsgKHRoaXMuX3gxID0geDEgKyB0MjEgKiB4MjEpICsgXCIsXCIgKyAodGhpcy5feTEgPSB5MSArIHQyMSAqIHkyMSk7XG4gICAgfVxuICB9LFxuICBhcmM6IGZ1bmN0aW9uKHgsIHksIHIsIGEwLCBhMSwgY2N3KSB7XG4gICAgeCA9ICt4LCB5ID0gK3ksIHIgPSArcjtcbiAgICB2YXIgZHggPSByICogTWF0aC5jb3MoYTApLFxuICAgICAgICBkeSA9IHIgKiBNYXRoLnNpbihhMCksXG4gICAgICAgIHgwID0geCArIGR4LFxuICAgICAgICB5MCA9IHkgKyBkeSxcbiAgICAgICAgY3cgPSAxIF4gY2N3LFxuICAgICAgICBkYSA9IGNjdyA/IGEwIC0gYTEgOiBhMSAtIGEwO1xuXG4gICAgLy8gSXMgdGhlIHJhZGl1cyBuZWdhdGl2ZT8gRXJyb3IuXG4gICAgaWYgKHIgPCAwKSB0aHJvdyBuZXcgRXJyb3IoXCJuZWdhdGl2ZSByYWRpdXM6IFwiICsgcik7XG5cbiAgICAvLyBJcyB0aGlzIHBhdGggZW1wdHk/IE1vdmUgdG8gKHgwLHkwKS5cbiAgICBpZiAodGhpcy5feDEgPT09IG51bGwpIHtcbiAgICAgIHRoaXMuXyArPSBcIk1cIiArIHgwICsgXCIsXCIgKyB5MDtcbiAgICB9XG5cbiAgICAvLyBPciwgaXMgKHgwLHkwKSBub3QgY29pbmNpZGVudCB3aXRoIHRoZSBwcmV2aW91cyBwb2ludD8gTGluZSB0byAoeDAseTApLlxuICAgIGVsc2UgaWYgKE1hdGguYWJzKHRoaXMuX3gxIC0geDApID4gZXBzaWxvbiB8fCBNYXRoLmFicyh0aGlzLl95MSAtIHkwKSA+IGVwc2lsb24pIHtcbiAgICAgIHRoaXMuXyArPSBcIkxcIiArIHgwICsgXCIsXCIgKyB5MDtcbiAgICB9XG5cbiAgICAvLyBJcyB0aGlzIGFyYyBlbXB0eT8gV2XigJlyZSBkb25lLlxuICAgIGlmICghcikgcmV0dXJuO1xuXG4gICAgLy8gRG9lcyB0aGUgYW5nbGUgZ28gdGhlIHdyb25nIHdheT8gRmxpcCB0aGUgZGlyZWN0aW9uLlxuICAgIGlmIChkYSA8IDApIGRhID0gZGEgJSB0YXUgKyB0YXU7XG5cbiAgICAvLyBJcyB0aGlzIGEgY29tcGxldGUgY2lyY2xlPyBEcmF3IHR3byBhcmNzIHRvIGNvbXBsZXRlIHRoZSBjaXJjbGUuXG4gICAgaWYgKGRhID4gdGF1RXBzaWxvbikge1xuICAgICAgdGhpcy5fICs9IFwiQVwiICsgciArIFwiLFwiICsgciArIFwiLDAsMSxcIiArIGN3ICsgXCIsXCIgKyAoeCAtIGR4KSArIFwiLFwiICsgKHkgLSBkeSkgKyBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLDEsXCIgKyBjdyArIFwiLFwiICsgKHRoaXMuX3gxID0geDApICsgXCIsXCIgKyAodGhpcy5feTEgPSB5MCk7XG4gICAgfVxuXG4gICAgLy8gSXMgdGhpcyBhcmMgbm9uLWVtcHR5PyBEcmF3IGFuIGFyYyFcbiAgICBlbHNlIGlmIChkYSA+IGVwc2lsb24pIHtcbiAgICAgIHRoaXMuXyArPSBcIkFcIiArIHIgKyBcIixcIiArIHIgKyBcIiwwLFwiICsgKCsoZGEgPj0gcGkpKSArIFwiLFwiICsgY3cgKyBcIixcIiArICh0aGlzLl94MSA9IHggKyByICogTWF0aC5jb3MoYTEpKSArIFwiLFwiICsgKHRoaXMuX3kxID0geSArIHIgKiBNYXRoLnNpbihhMSkpO1xuICAgIH1cbiAgfSxcbiAgcmVjdDogZnVuY3Rpb24oeCwgeSwgdywgaCkge1xuICAgIHRoaXMuXyArPSBcIk1cIiArICh0aGlzLl94MCA9IHRoaXMuX3gxID0gK3gpICsgXCIsXCIgKyAodGhpcy5feTAgPSB0aGlzLl95MSA9ICt5KSArIFwiaFwiICsgKCt3KSArIFwidlwiICsgKCtoKSArIFwiaFwiICsgKC13KSArIFwiWlwiO1xuICB9LFxuICB0b1N0cmluZzogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRoaXMuXztcbiAgfVxufTtcblxudmFyIGNvbnN0YW50JDIgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbiBjb25zdGFudCgpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbnZhciBhYnMgPSBNYXRoLmFicztcbnZhciBhdGFuMiA9IE1hdGguYXRhbjI7XG52YXIgY29zID0gTWF0aC5jb3M7XG52YXIgbWF4JDEgPSBNYXRoLm1heDtcbnZhciBtaW4kMSA9IE1hdGgubWluO1xudmFyIHNpbiA9IE1hdGguc2luO1xudmFyIHNxcnQgPSBNYXRoLnNxcnQ7XG5cbnZhciBlcHNpbG9uJDEgPSAxZS0xMjtcbnZhciBwaSQxID0gTWF0aC5QSTtcbnZhciBoYWxmUGkgPSBwaSQxIC8gMjtcbnZhciB0YXUkMSA9IDIgKiBwaSQxO1xuXG5mdW5jdGlvbiBhY29zKHgpIHtcbiAgcmV0dXJuIHggPiAxID8gMCA6IHggPCAtMSA/IHBpJDEgOiBNYXRoLmFjb3MoeCk7XG59XG5cbmZ1bmN0aW9uIGFzaW4oeCkge1xuICByZXR1cm4geCA+PSAxID8gaGFsZlBpIDogeCA8PSAtMSA/IC1oYWxmUGkgOiBNYXRoLmFzaW4oeCk7XG59XG5cbmZ1bmN0aW9uIGFyY0lubmVyUmFkaXVzKGQpIHtcbiAgcmV0dXJuIGQuaW5uZXJSYWRpdXM7XG59XG5cbmZ1bmN0aW9uIGFyY091dGVyUmFkaXVzKGQpIHtcbiAgcmV0dXJuIGQub3V0ZXJSYWRpdXM7XG59XG5cbmZ1bmN0aW9uIGFyY1N0YXJ0QW5nbGUoZCkge1xuICByZXR1cm4gZC5zdGFydEFuZ2xlO1xufVxuXG5mdW5jdGlvbiBhcmNFbmRBbmdsZShkKSB7XG4gIHJldHVybiBkLmVuZEFuZ2xlO1xufVxuXG5mdW5jdGlvbiBhcmNQYWRBbmdsZShkKSB7XG4gIHJldHVybiBkICYmIGQucGFkQW5nbGU7IC8vIE5vdGU6IG9wdGlvbmFsIVxufVxuXG5mdW5jdGlvbiBpbnRlcnNlY3QoeDAsIHkwLCB4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gIHZhciB4MTAgPSB4MSAtIHgwLCB5MTAgPSB5MSAtIHkwLFxuICAgICAgeDMyID0geDMgLSB4MiwgeTMyID0geTMgLSB5MixcbiAgICAgIHQgPSAoeDMyICogKHkwIC0geTIpIC0geTMyICogKHgwIC0geDIpKSAvICh5MzIgKiB4MTAgLSB4MzIgKiB5MTApO1xuICByZXR1cm4gW3gwICsgdCAqIHgxMCwgeTAgKyB0ICogeTEwXTtcbn1cblxuLy8gQ29tcHV0ZSBwZXJwZW5kaWN1bGFyIG9mZnNldCBsaW5lIG9mIGxlbmd0aCByYy5cbi8vIGh0dHA6Ly9tYXRod29ybGQud29sZnJhbS5jb20vQ2lyY2xlLUxpbmVJbnRlcnNlY3Rpb24uaHRtbFxuZnVuY3Rpb24gY29ybmVyVGFuZ2VudHMoeDAsIHkwLCB4MSwgeTEsIHIxLCByYywgY3cpIHtcbiAgdmFyIHgwMSA9IHgwIC0geDEsXG4gICAgICB5MDEgPSB5MCAtIHkxLFxuICAgICAgbG8gPSAoY3cgPyByYyA6IC1yYykgLyBzcXJ0KHgwMSAqIHgwMSArIHkwMSAqIHkwMSksXG4gICAgICBveCA9IGxvICogeTAxLFxuICAgICAgb3kgPSAtbG8gKiB4MDEsXG4gICAgICB4MTEgPSB4MCArIG94LFxuICAgICAgeTExID0geTAgKyBveSxcbiAgICAgIHgxMCA9IHgxICsgb3gsXG4gICAgICB5MTAgPSB5MSArIG95LFxuICAgICAgeDAwID0gKHgxMSArIHgxMCkgLyAyLFxuICAgICAgeTAwID0gKHkxMSArIHkxMCkgLyAyLFxuICAgICAgZHggPSB4MTAgLSB4MTEsXG4gICAgICBkeSA9IHkxMCAtIHkxMSxcbiAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHksXG4gICAgICByID0gcjEgLSByYyxcbiAgICAgIEQgPSB4MTEgKiB5MTAgLSB4MTAgKiB5MTEsXG4gICAgICBkID0gKGR5IDwgMCA/IC0xIDogMSkgKiBzcXJ0KG1heCQxKDAsIHIgKiByICogZDIgLSBEICogRCkpLFxuICAgICAgY3gwID0gKEQgKiBkeSAtIGR4ICogZCkgLyBkMixcbiAgICAgIGN5MCA9ICgtRCAqIGR4IC0gZHkgKiBkKSAvIGQyLFxuICAgICAgY3gxID0gKEQgKiBkeSArIGR4ICogZCkgLyBkMixcbiAgICAgIGN5MSA9ICgtRCAqIGR4ICsgZHkgKiBkKSAvIGQyLFxuICAgICAgZHgwID0gY3gwIC0geDAwLFxuICAgICAgZHkwID0gY3kwIC0geTAwLFxuICAgICAgZHgxID0gY3gxIC0geDAwLFxuICAgICAgZHkxID0gY3kxIC0geTAwO1xuXG4gIC8vIFBpY2sgdGhlIGNsb3NlciBvZiB0aGUgdHdvIGludGVyc2VjdGlvbiBwb2ludHMuXG4gIC8vIFRPRE8gSXMgdGhlcmUgYSBmYXN0ZXIgd2F5IHRvIGRldGVybWluZSB3aGljaCBpbnRlcnNlY3Rpb24gdG8gdXNlP1xuICBpZiAoZHgwICogZHgwICsgZHkwICogZHkwID4gZHgxICogZHgxICsgZHkxICogZHkxKSBjeDAgPSBjeDEsIGN5MCA9IGN5MTtcblxuICByZXR1cm4ge1xuICAgIGN4OiBjeDAsXG4gICAgY3k6IGN5MCxcbiAgICB4MDE6IC1veCxcbiAgICB5MDE6IC1veSxcbiAgICB4MTE6IGN4MCAqIChyMSAvIHIgLSAxKSxcbiAgICB5MTE6IGN5MCAqIChyMSAvIHIgLSAxKVxuICB9O1xufVxuXG52YXIgZDNfYXJjID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpbm5lclJhZGl1cyA9IGFyY0lubmVyUmFkaXVzLFxuICAgICAgb3V0ZXJSYWRpdXMgPSBhcmNPdXRlclJhZGl1cyxcbiAgICAgIGNvcm5lclJhZGl1cyA9IGNvbnN0YW50JDIoMCksXG4gICAgICBwYWRSYWRpdXMgPSBudWxsLFxuICAgICAgc3RhcnRBbmdsZSA9IGFyY1N0YXJ0QW5nbGUsXG4gICAgICBlbmRBbmdsZSA9IGFyY0VuZEFuZ2xlLFxuICAgICAgcGFkQW5nbGUgPSBhcmNQYWRBbmdsZSxcbiAgICAgIGNvbnRleHQgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGFyYygpIHtcbiAgICB2YXIgYnVmZmVyLFxuICAgICAgICByLFxuICAgICAgICByMCA9ICtpbm5lclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICByMSA9ICtvdXRlclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpLFxuICAgICAgICBhMCA9IHN0YXJ0QW5nbGUuYXBwbHkodGhpcywgYXJndW1lbnRzKSAtIGhhbGZQaSxcbiAgICAgICAgYTEgPSBlbmRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpIC0gaGFsZlBpLFxuICAgICAgICBkYSA9IGFicyhhMSAtIGEwKSxcbiAgICAgICAgY3cgPSBhMSA+IGEwO1xuXG4gICAgaWYgKCFjb250ZXh0KSBjb250ZXh0ID0gYnVmZmVyID0gcGF0aCgpO1xuXG4gICAgLy8gRW5zdXJlIHRoYXQgdGhlIG91dGVyIHJhZGl1cyBpcyBhbHdheXMgbGFyZ2VyIHRoYW4gdGhlIGlubmVyIHJhZGl1cy5cbiAgICBpZiAocjEgPCByMCkgciA9IHIxLCByMSA9IHIwLCByMCA9IHI7XG5cbiAgICAvLyBJcyBpdCBhIHBvaW50P1xuICAgIGlmICghKHIxID4gZXBzaWxvbiQxKSkgY29udGV4dC5tb3ZlVG8oMCwgMCk7XG5cbiAgICAvLyBPciBpcyBpdCBhIGNpcmNsZSBvciBhbm51bHVzP1xuICAgIGVsc2UgaWYgKGRhID4gdGF1JDEgLSBlcHNpbG9uJDEpIHtcbiAgICAgIGNvbnRleHQubW92ZVRvKHIxICogY29zKGEwKSwgcjEgKiBzaW4oYTApKTtcbiAgICAgIGNvbnRleHQuYXJjKDAsIDAsIHIxLCBhMCwgYTEsICFjdyk7XG4gICAgICBpZiAocjAgPiBlcHNpbG9uJDEpIHtcbiAgICAgICAgY29udGV4dC5tb3ZlVG8ocjAgKiBjb3MoYTEpLCByMCAqIHNpbihhMSkpO1xuICAgICAgICBjb250ZXh0LmFyYygwLCAwLCByMCwgYTEsIGEwLCBjdyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gT3IgaXMgaXQgYSBjaXJjdWxhciBvciBhbm51bGFyIHNlY3Rvcj9cbiAgICBlbHNlIHtcbiAgICAgIHZhciBhMDEgPSBhMCxcbiAgICAgICAgICBhMTEgPSBhMSxcbiAgICAgICAgICBhMDAgPSBhMCxcbiAgICAgICAgICBhMTAgPSBhMSxcbiAgICAgICAgICBkYTAgPSBkYSxcbiAgICAgICAgICBkYTEgPSBkYSxcbiAgICAgICAgICBhcCA9IHBhZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykgLyAyLFxuICAgICAgICAgIHJwID0gKGFwID4gZXBzaWxvbiQxKSAmJiAocGFkUmFkaXVzID8gK3BhZFJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpIDogc3FydChyMCAqIHIwICsgcjEgKiByMSkpLFxuICAgICAgICAgIHJjID0gbWluJDEoYWJzKHIxIC0gcjApIC8gMiwgK2Nvcm5lclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpKSxcbiAgICAgICAgICByYzAgPSByYyxcbiAgICAgICAgICByYzEgPSByYyxcbiAgICAgICAgICB0MCxcbiAgICAgICAgICB0MTtcblxuICAgICAgLy8gQXBwbHkgcGFkZGluZz8gTm90ZSB0aGF0IHNpbmNlIHIxIOKJpSByMCwgZGExIOKJpSBkYTAuXG4gICAgICBpZiAocnAgPiBlcHNpbG9uJDEpIHtcbiAgICAgICAgdmFyIHAwID0gYXNpbihycCAvIHIwICogc2luKGFwKSksXG4gICAgICAgICAgICBwMSA9IGFzaW4ocnAgLyByMSAqIHNpbihhcCkpO1xuICAgICAgICBpZiAoKGRhMCAtPSBwMCAqIDIpID4gZXBzaWxvbiQxKSBwMCAqPSAoY3cgPyAxIDogLTEpLCBhMDAgKz0gcDAsIGExMCAtPSBwMDtcbiAgICAgICAgZWxzZSBkYTAgPSAwLCBhMDAgPSBhMTAgPSAoYTAgKyBhMSkgLyAyO1xuICAgICAgICBpZiAoKGRhMSAtPSBwMSAqIDIpID4gZXBzaWxvbiQxKSBwMSAqPSAoY3cgPyAxIDogLTEpLCBhMDEgKz0gcDEsIGExMSAtPSBwMTtcbiAgICAgICAgZWxzZSBkYTEgPSAwLCBhMDEgPSBhMTEgPSAoYTAgKyBhMSkgLyAyO1xuICAgICAgfVxuXG4gICAgICB2YXIgeDAxID0gcjEgKiBjb3MoYTAxKSxcbiAgICAgICAgICB5MDEgPSByMSAqIHNpbihhMDEpLFxuICAgICAgICAgIHgxMCA9IHIwICogY29zKGExMCksXG4gICAgICAgICAgeTEwID0gcjAgKiBzaW4oYTEwKTtcblxuICAgICAgLy8gQXBwbHkgcm91bmRlZCBjb3JuZXJzP1xuICAgICAgaWYgKHJjID4gZXBzaWxvbiQxKSB7XG4gICAgICAgIHZhciB4MTEgPSByMSAqIGNvcyhhMTEpLFxuICAgICAgICAgICAgeTExID0gcjEgKiBzaW4oYTExKSxcbiAgICAgICAgICAgIHgwMCA9IHIwICogY29zKGEwMCksXG4gICAgICAgICAgICB5MDAgPSByMCAqIHNpbihhMDApO1xuXG4gICAgICAgIC8vIFJlc3RyaWN0IHRoZSBjb3JuZXIgcmFkaXVzIGFjY29yZGluZyB0byB0aGUgc2VjdG9yIGFuZ2xlLlxuICAgICAgICBpZiAoZGEgPCBwaSQxKSB7XG4gICAgICAgICAgdmFyIG9jID0gZGEwID4gZXBzaWxvbiQxID8gaW50ZXJzZWN0KHgwMSwgeTAxLCB4MDAsIHkwMCwgeDExLCB5MTEsIHgxMCwgeTEwKSA6IFt4MTAsIHkxMF0sXG4gICAgICAgICAgICAgIGF4ID0geDAxIC0gb2NbMF0sXG4gICAgICAgICAgICAgIGF5ID0geTAxIC0gb2NbMV0sXG4gICAgICAgICAgICAgIGJ4ID0geDExIC0gb2NbMF0sXG4gICAgICAgICAgICAgIGJ5ID0geTExIC0gb2NbMV0sXG4gICAgICAgICAgICAgIGtjID0gMSAvIHNpbihhY29zKChheCAqIGJ4ICsgYXkgKiBieSkgLyAoc3FydChheCAqIGF4ICsgYXkgKiBheSkgKiBzcXJ0KGJ4ICogYnggKyBieSAqIGJ5KSkpIC8gMiksXG4gICAgICAgICAgICAgIGxjID0gc3FydChvY1swXSAqIG9jWzBdICsgb2NbMV0gKiBvY1sxXSk7XG4gICAgICAgICAgcmMwID0gbWluJDEocmMsIChyMCAtIGxjKSAvIChrYyAtIDEpKTtcbiAgICAgICAgICByYzEgPSBtaW4kMShyYywgKHIxIC0gbGMpIC8gKGtjICsgMSkpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIElzIHRoZSBzZWN0b3IgY29sbGFwc2VkIHRvIGEgbGluZT9cbiAgICAgIGlmICghKGRhMSA+IGVwc2lsb24kMSkpIGNvbnRleHQubW92ZVRvKHgwMSwgeTAxKTtcblxuICAgICAgLy8gRG9lcyB0aGUgc2VjdG9y4oCZcyBvdXRlciByaW5nIGhhdmUgcm91bmRlZCBjb3JuZXJzP1xuICAgICAgZWxzZSBpZiAocmMxID4gZXBzaWxvbiQxKSB7XG4gICAgICAgIHQwID0gY29ybmVyVGFuZ2VudHMoeDAwLCB5MDAsIHgwMSwgeTAxLCByMSwgcmMxLCBjdyk7XG4gICAgICAgIHQxID0gY29ybmVyVGFuZ2VudHMoeDExLCB5MTEsIHgxMCwgeTEwLCByMSwgcmMxLCBjdyk7XG5cbiAgICAgICAgY29udGV4dC5tb3ZlVG8odDAuY3ggKyB0MC54MDEsIHQwLmN5ICsgdDAueTAxKTtcblxuICAgICAgICAvLyBIYXZlIHRoZSBjb3JuZXJzIG1lcmdlZD9cbiAgICAgICAgaWYgKHJjMSA8IHJjKSBjb250ZXh0LmFyYyh0MC5jeCwgdDAuY3ksIHJjMSwgYXRhbjIodDAueTAxLCB0MC54MDEpLCBhdGFuMih0MS55MDEsIHQxLngwMSksICFjdyk7XG5cbiAgICAgICAgLy8gT3RoZXJ3aXNlLCBkcmF3IHRoZSB0d28gY29ybmVycyBhbmQgdGhlIHJpbmcuXG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMxLCBhdGFuMih0MC55MDEsIHQwLngwMSksIGF0YW4yKHQwLnkxMSwgdDAueDExKSwgIWN3KTtcbiAgICAgICAgICBjb250ZXh0LmFyYygwLCAwLCByMSwgYXRhbjIodDAuY3kgKyB0MC55MTEsIHQwLmN4ICsgdDAueDExKSwgYXRhbjIodDEuY3kgKyB0MS55MTEsIHQxLmN4ICsgdDEueDExKSwgIWN3KTtcbiAgICAgICAgICBjb250ZXh0LmFyYyh0MS5jeCwgdDEuY3ksIHJjMSwgYXRhbjIodDEueTExLCB0MS54MTEpLCBhdGFuMih0MS55MDEsIHQxLngwMSksICFjdyk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gT3IgaXMgdGhlIG91dGVyIHJpbmcganVzdCBhIGNpcmN1bGFyIGFyYz9cbiAgICAgIGVsc2UgY29udGV4dC5tb3ZlVG8oeDAxLCB5MDEpLCBjb250ZXh0LmFyYygwLCAwLCByMSwgYTAxLCBhMTEsICFjdyk7XG5cbiAgICAgIC8vIElzIHRoZXJlIG5vIGlubmVyIHJpbmcsIGFuZCBpdOKAmXMgYSBjaXJjdWxhciBzZWN0b3I/XG4gICAgICAvLyBPciBwZXJoYXBzIGl04oCZcyBhbiBhbm51bGFyIHNlY3RvciBjb2xsYXBzZWQgZHVlIHRvIHBhZGRpbmc/XG4gICAgICBpZiAoIShyMCA+IGVwc2lsb24kMSkgfHwgIShkYTAgPiBlcHNpbG9uJDEpKSBjb250ZXh0LmxpbmVUbyh4MTAsIHkxMCk7XG5cbiAgICAgIC8vIERvZXMgdGhlIHNlY3RvcuKAmXMgaW5uZXIgcmluZyAob3IgcG9pbnQpIGhhdmUgcm91bmRlZCBjb3JuZXJzP1xuICAgICAgZWxzZSBpZiAocmMwID4gZXBzaWxvbiQxKSB7XG4gICAgICAgIHQwID0gY29ybmVyVGFuZ2VudHMoeDEwLCB5MTAsIHgxMSwgeTExLCByMCwgLXJjMCwgY3cpO1xuICAgICAgICB0MSA9IGNvcm5lclRhbmdlbnRzKHgwMSwgeTAxLCB4MDAsIHkwMCwgcjAsIC1yYzAsIGN3KTtcblxuICAgICAgICBjb250ZXh0LmxpbmVUbyh0MC5jeCArIHQwLngwMSwgdDAuY3kgKyB0MC55MDEpO1xuXG4gICAgICAgIC8vIEhhdmUgdGhlIGNvcm5lcnMgbWVyZ2VkP1xuICAgICAgICBpZiAocmMwIDwgcmMpIGNvbnRleHQuYXJjKHQwLmN4LCB0MC5jeSwgcmMwLCBhdGFuMih0MC55MDEsIHQwLngwMSksIGF0YW4yKHQxLnkwMSwgdDEueDAxKSwgIWN3KTtcblxuICAgICAgICAvLyBPdGhlcndpc2UsIGRyYXcgdGhlIHR3byBjb3JuZXJzIGFuZCB0aGUgcmluZy5cbiAgICAgICAgZWxzZSB7XG4gICAgICAgICAgY29udGV4dC5hcmModDAuY3gsIHQwLmN5LCByYzAsIGF0YW4yKHQwLnkwMSwgdDAueDAxKSwgYXRhbjIodDAueTExLCB0MC54MTEpLCAhY3cpO1xuICAgICAgICAgIGNvbnRleHQuYXJjKDAsIDAsIHIwLCBhdGFuMih0MC5jeSArIHQwLnkxMSwgdDAuY3ggKyB0MC54MTEpLCBhdGFuMih0MS5jeSArIHQxLnkxMSwgdDEuY3ggKyB0MS54MTEpLCBjdyk7XG4gICAgICAgICAgY29udGV4dC5hcmModDEuY3gsIHQxLmN5LCByYzAsIGF0YW4yKHQxLnkxMSwgdDEueDExKSwgYXRhbjIodDEueTAxLCB0MS54MDEpLCAhY3cpO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIC8vIE9yIGlzIHRoZSBpbm5lciByaW5nIGp1c3QgYSBjaXJjdWxhciBhcmM/XG4gICAgICBlbHNlIGNvbnRleHQuYXJjKDAsIDAsIHIwLCBhMTAsIGEwMCwgY3cpO1xuICAgIH1cblxuICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG5cbiAgICBpZiAoYnVmZmVyKSByZXR1cm4gY29udGV4dCA9IG51bGwsIGJ1ZmZlciArIFwiXCIgfHwgbnVsbDtcbiAgfVxuXG4gIGFyYy5jZW50cm9pZCA9IGZ1bmN0aW9uKCkge1xuICAgIHZhciByID0gKCtpbm5lclJhZGl1cy5hcHBseSh0aGlzLCBhcmd1bWVudHMpICsgK291dGVyUmFkaXVzLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIC8gMixcbiAgICAgICAgYSA9ICgrc3RhcnRBbmdsZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpICsgK2VuZEFuZ2xlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykpIC8gMiAtIHBpJDEgLyAyO1xuICAgIHJldHVybiBbY29zKGEpICogciwgc2luKGEpICogcl07XG4gIH07XG5cbiAgYXJjLmlubmVyUmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGlubmVyUmFkaXVzID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IGlubmVyUmFkaXVzO1xuICB9O1xuXG4gIGFyYy5vdXRlclJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChvdXRlclJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIGFyYykgOiBvdXRlclJhZGl1cztcbiAgfTtcblxuICBhcmMuY29ybmVyUmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGNvcm5lclJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIGFyYykgOiBjb3JuZXJSYWRpdXM7XG4gIH07XG5cbiAgYXJjLnBhZFJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRSYWRpdXMgPSBfID09IG51bGwgPyBudWxsIDogdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IHBhZFJhZGl1cztcbiAgfTtcblxuICBhcmMuc3RhcnRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdGFydEFuZ2xlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IHN0YXJ0QW5nbGU7XG4gIH07XG5cbiAgYXJjLmVuZEFuZ2xlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGVuZEFuZ2xlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJjKSA6IGVuZEFuZ2xlO1xuICB9O1xuXG4gIGFyYy5wYWRBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRBbmdsZSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIGFyYykgOiBwYWRBbmdsZTtcbiAgfTtcblxuICBhcmMuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICgoY29udGV4dCA9IF8gPT0gbnVsbCA/IG51bGwgOiBfKSwgYXJjKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIGFyYztcbn07XG5cbmZ1bmN0aW9uIExpbmVhcihjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5MaW5lYXIucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpOyBicmVhaztcbiAgICB9XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUxpbmVhciA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBMaW5lYXIoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiB4JDEocCkge1xuICByZXR1cm4gcFswXTtcbn1cblxuZnVuY3Rpb24geSQxKHApIHtcbiAgcmV0dXJuIHBbMV07XG59XG5cbnZhciBsaW5lJDEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHggPSB4JDEsXG4gICAgICB5ID0geSQxLFxuICAgICAgZGVmaW5lZCA9IGNvbnN0YW50JDIodHJ1ZSksXG4gICAgICBjb250ZXh0ID0gbnVsbCxcbiAgICAgIGN1cnZlID0gY3VydmVMaW5lYXIsXG4gICAgICBvdXRwdXQgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIGxpbmUoZGF0YSkge1xuICAgIHZhciBpLFxuICAgICAgICBuID0gZGF0YS5sZW5ndGgsXG4gICAgICAgIGQsXG4gICAgICAgIGRlZmluZWQwID0gZmFsc2UsXG4gICAgICAgIGJ1ZmZlcjtcblxuICAgIGlmIChjb250ZXh0ID09IG51bGwpIG91dHB1dCA9IGN1cnZlKGJ1ZmZlciA9IHBhdGgoKSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDw9IG47ICsraSkge1xuICAgICAgaWYgKCEoaSA8IG4gJiYgZGVmaW5lZChkID0gZGF0YVtpXSwgaSwgZGF0YSkpID09PSBkZWZpbmVkMCkge1xuICAgICAgICBpZiAoZGVmaW5lZDAgPSAhZGVmaW5lZDApIG91dHB1dC5saW5lU3RhcnQoKTtcbiAgICAgICAgZWxzZSBvdXRwdXQubGluZUVuZCgpO1xuICAgICAgfVxuICAgICAgaWYgKGRlZmluZWQwKSBvdXRwdXQucG9pbnQoK3goZCwgaSwgZGF0YSksICt5KGQsIGksIGRhdGEpKTtcbiAgICB9XG5cbiAgICBpZiAoYnVmZmVyKSByZXR1cm4gb3V0cHV0ID0gbnVsbCwgYnVmZmVyICsgXCJcIiB8fCBudWxsO1xuICB9XG5cbiAgbGluZS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBsaW5lKSA6IHg7XG4gIH07XG5cbiAgbGluZS55ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBsaW5lKSA6IHk7XG4gIH07XG5cbiAgbGluZS5kZWZpbmVkID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRlZmluZWQgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoISFfKSwgbGluZSkgOiBkZWZpbmVkO1xuICB9O1xuXG4gIGxpbmUuY3VydmUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY3VydmUgPSBfLCBjb250ZXh0ICE9IG51bGwgJiYgKG91dHB1dCA9IGN1cnZlKGNvbnRleHQpKSwgbGluZSkgOiBjdXJ2ZTtcbiAgfTtcblxuICBsaW5lLmNvbnRleHQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoXyA9PSBudWxsID8gY29udGV4dCA9IG91dHB1dCA9IG51bGwgOiBvdXRwdXQgPSBjdXJ2ZShjb250ZXh0ID0gXyksIGxpbmUpIDogY29udGV4dDtcbiAgfTtcblxuICByZXR1cm4gbGluZTtcbn07XG5cbnZhciBhcmVhJDEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHgwID0geCQxLFxuICAgICAgeDEgPSBudWxsLFxuICAgICAgeTAgPSBjb25zdGFudCQyKDApLFxuICAgICAgeTEgPSB5JDEsXG4gICAgICBkZWZpbmVkID0gY29uc3RhbnQkMih0cnVlKSxcbiAgICAgIGNvbnRleHQgPSBudWxsLFxuICAgICAgY3VydmUgPSBjdXJ2ZUxpbmVhcixcbiAgICAgIG91dHB1dCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gYXJlYShkYXRhKSB7XG4gICAgdmFyIGksXG4gICAgICAgIGosXG4gICAgICAgIGssXG4gICAgICAgIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgZCxcbiAgICAgICAgZGVmaW5lZDAgPSBmYWxzZSxcbiAgICAgICAgYnVmZmVyLFxuICAgICAgICB4MHogPSBuZXcgQXJyYXkobiksXG4gICAgICAgIHkweiA9IG5ldyBBcnJheShuKTtcblxuICAgIGlmIChjb250ZXh0ID09IG51bGwpIG91dHB1dCA9IGN1cnZlKGJ1ZmZlciA9IHBhdGgoKSk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDw9IG47ICsraSkge1xuICAgICAgaWYgKCEoaSA8IG4gJiYgZGVmaW5lZChkID0gZGF0YVtpXSwgaSwgZGF0YSkpID09PSBkZWZpbmVkMCkge1xuICAgICAgICBpZiAoZGVmaW5lZDAgPSAhZGVmaW5lZDApIHtcbiAgICAgICAgICBqID0gaTtcbiAgICAgICAgICBvdXRwdXQuYXJlYVN0YXJ0KCk7XG4gICAgICAgICAgb3V0cHV0LmxpbmVTdGFydCgpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG91dHB1dC5saW5lRW5kKCk7XG4gICAgICAgICAgb3V0cHV0LmxpbmVTdGFydCgpO1xuICAgICAgICAgIGZvciAoayA9IGkgLSAxOyBrID49IGo7IC0taykge1xuICAgICAgICAgICAgb3V0cHV0LnBvaW50KHgweltrXSwgeTB6W2tdKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgb3V0cHV0LmxpbmVFbmQoKTtcbiAgICAgICAgICBvdXRwdXQuYXJlYUVuZCgpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBpZiAoZGVmaW5lZDApIHtcbiAgICAgICAgeDB6W2ldID0gK3gwKGQsIGksIGRhdGEpLCB5MHpbaV0gPSAreTAoZCwgaSwgZGF0YSk7XG4gICAgICAgIG91dHB1dC5wb2ludCh4MSA/ICt4MShkLCBpLCBkYXRhKSA6IHgweltpXSwgeTEgPyAreTEoZCwgaSwgZGF0YSkgOiB5MHpbaV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChidWZmZXIpIHJldHVybiBvdXRwdXQgPSBudWxsLCBidWZmZXIgKyBcIlwiIHx8IG51bGw7XG4gIH1cblxuICBmdW5jdGlvbiBhcmVhbGluZSgpIHtcbiAgICByZXR1cm4gbGluZSQxKCkuZGVmaW5lZChkZWZpbmVkKS5jdXJ2ZShjdXJ2ZSkuY29udGV4dChjb250ZXh0KTtcbiAgfVxuXG4gIGFyZWEueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4MCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIHgxID0gbnVsbCwgYXJlYSkgOiB4MDtcbiAgfTtcblxuICBhcmVhLngwID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJlYSkgOiB4MDtcbiAgfTtcblxuICBhcmVhLngxID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgxID0gXyA9PSBudWxsID8gbnVsbCA6IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMigrXyksIGFyZWEpIDogeDE7XG4gIH07XG5cbiAgYXJlYS55ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkwID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgeTEgPSBudWxsLCBhcmVhKSA6IHkwO1xuICB9O1xuXG4gIGFyZWEueTAgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeTAgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBhcmVhKSA6IHkwO1xuICB9O1xuXG4gIGFyZWEueTEgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeTEgPSBfID09IG51bGwgPyBudWxsIDogdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCtfKSwgYXJlYSkgOiB5MTtcbiAgfTtcblxuICBhcmVhLmxpbmVYMCA9XG4gIGFyZWEubGluZVkwID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGFyZWFsaW5lKCkueCh4MCkueSh5MCk7XG4gIH07XG5cbiAgYXJlYS5saW5lWTEgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYXJlYWxpbmUoKS54KHgwKS55KHkxKTtcbiAgfTtcblxuICBhcmVhLmxpbmVYMSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBhcmVhbGluZSgpLngoeDEpLnkoeTApO1xuICB9O1xuXG4gIGFyZWEuZGVmaW5lZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkZWZpbmVkID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQyKCEhXyksIGFyZWEpIDogZGVmaW5lZDtcbiAgfTtcblxuICBhcmVhLmN1cnZlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGN1cnZlID0gXywgY29udGV4dCAhPSBudWxsICYmIChvdXRwdXQgPSBjdXJ2ZShjb250ZXh0KSksIGFyZWEpIDogY3VydmU7XG4gIH07XG5cbiAgYXJlYS5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKF8gPT0gbnVsbCA/IGNvbnRleHQgPSBvdXRwdXQgPSBudWxsIDogb3V0cHV0ID0gY3VydmUoY29udGV4dCA9IF8pLCBhcmVhKSA6IGNvbnRleHQ7XG4gIH07XG5cbiAgcmV0dXJuIGFyZWE7XG59O1xuXG52YXIgY2lyY2xlID0ge1xuICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgdmFyIHIgPSBNYXRoLnNxcnQoc2l6ZSAvIHBpJDEpO1xuICAgIGNvbnRleHQubW92ZVRvKHIsIDApO1xuICAgIGNvbnRleHQuYXJjKDAsIDAsIHIsIDAsIHRhdSQxKTtcbiAgfVxufTtcblxudmFyIGQzX3N5bWJvbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdHlwZSA9IGNvbnN0YW50JDIoY2lyY2xlKSxcbiAgICAgIHNpemUgPSBjb25zdGFudCQyKDY0KSxcbiAgICAgIGNvbnRleHQgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIHN5bWJvbCgpIHtcbiAgICB2YXIgYnVmZmVyO1xuICAgIGlmICghY29udGV4dCkgY29udGV4dCA9IGJ1ZmZlciA9IHBhdGgoKTtcbiAgICB0eXBlLmFwcGx5KHRoaXMsIGFyZ3VtZW50cykuZHJhdyhjb250ZXh0LCArc2l6ZS5hcHBseSh0aGlzLCBhcmd1bWVudHMpKTtcbiAgICBpZiAoYnVmZmVyKSByZXR1cm4gY29udGV4dCA9IG51bGwsIGJ1ZmZlciArIFwiXCIgfHwgbnVsbDtcbiAgfVxuXG4gIHN5bWJvbC50eXBlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHR5cGUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoXyksIHN5bWJvbCkgOiB0eXBlO1xuICB9O1xuXG4gIHN5bWJvbC5zaXplID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNpemUgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDIoK18pLCBzeW1ib2wpIDogc2l6ZTtcbiAgfTtcblxuICBzeW1ib2wuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjb250ZXh0ID0gXyA9PSBudWxsID8gbnVsbCA6IF8sIHN5bWJvbCkgOiBjb250ZXh0O1xuICB9O1xuXG4gIHJldHVybiBzeW1ib2w7XG59O1xuXG52YXIgbm9vcCQxID0gZnVuY3Rpb24oKSB7fTtcblxuZnVuY3Rpb24gcG9pbnQodGhhdCwgeCwgeSkge1xuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oXG4gICAgKDIgKiB0aGF0Ll94MCArIHRoYXQuX3gxKSAvIDMsXG4gICAgKDIgKiB0aGF0Ll95MCArIHRoYXQuX3kxKSAvIDMsXG4gICAgKHRoYXQuX3gwICsgMiAqIHRoYXQuX3gxKSAvIDMsXG4gICAgKHRoYXQuX3kwICsgMiAqIHRoYXQuX3kxKSAvIDMsXG4gICAgKHRoYXQuX3gwICsgNCAqIHRoYXQuX3gxICsgeCkgLyA2LFxuICAgICh0aGF0Ll95MCArIDQgKiB0aGF0Ll95MSArIHkpIC8gNlxuICApO1xufVxuXG5mdW5jdGlvbiBCYXNpcyhjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5CYXNpcy5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMzogcG9pbnQodGhpcywgdGhpcy5feDEsIHRoaXMuX3kxKTsgLy8gcHJvY2VlZFxuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MSwgdGhpcy5feTEpOyBicmVhaztcbiAgICB9XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIHRoaXMuX2xpbmUgPSAxIC0gdGhpcy5fbGluZTtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB4ID0gK3gsIHkgPSAreTtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHgsIHkpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX2NvbnRleHQubGluZVRvKCg1ICogdGhpcy5feDAgKyB0aGlzLl94MSkgLyA2LCAoNSAqIHRoaXMuX3kwICsgdGhpcy5feTEpIC8gNik7IC8vIHByb2NlZWRcbiAgICAgIGRlZmF1bHQ6IHBvaW50KHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSwgdGhpcy5feDEgPSB4O1xuICAgIHRoaXMuX3kwID0gdGhpcy5feTEsIHRoaXMuX3kxID0geTtcbiAgfVxufTtcblxudmFyIGN1cnZlQmFzaXMgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgQmFzaXMoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBCYXNpc0Nsb3NlZChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5CYXNpc0Nsb3NlZC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogbm9vcCQxLFxuICBhcmVhRW5kOiBub29wJDEsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9IHRoaXMuX3gyID0gdGhpcy5feDMgPSB0aGlzLl94NCA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gdGhpcy5feTMgPSB0aGlzLl95NCA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MiwgdGhpcy5feTIpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbygodGhpcy5feDIgKyAyICogdGhpcy5feDMpIC8gMywgKHRoaXMuX3kyICsgMiAqIHRoaXMuX3kzKSAvIDMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbygodGhpcy5feDMgKyAyICogdGhpcy5feDIpIC8gMywgKHRoaXMuX3kzICsgMiAqIHRoaXMuX3kyKSAvIDMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3gyLCB0aGlzLl95Mik7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDMsIHRoaXMuX3kzKTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NCwgdGhpcy5feTQpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gyID0geCwgdGhpcy5feTIgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl94MyA9IHgsIHRoaXMuX3kzID0geTsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5feDQgPSB4LCB0aGlzLl95NCA9IHk7IHRoaXMuX2NvbnRleHQubW92ZVRvKCh0aGlzLl94MCArIDQgKiB0aGlzLl94MSArIHgpIC8gNiwgKHRoaXMuX3kwICsgNCAqIHRoaXMuX3kxICsgeSkgLyA2KTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBwb2ludCh0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUJhc2lzQ2xvc2VkID0gZnVuY3Rpb24oY29udGV4dCkge1xuICByZXR1cm4gbmV3IEJhc2lzQ2xvc2VkKGNvbnRleHQpO1xufTtcblxuZnVuY3Rpb24gQmFzaXNPcGVuKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbkJhc2lzT3Blbi5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIGFyZWFFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5feDAgPSB0aGlzLl94MSA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAzKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHZhciB4MCA9ICh0aGlzLl94MCArIDQgKiB0aGlzLl94MSArIHgpIC8gNiwgeTAgPSAodGhpcy5feTAgKyA0ICogdGhpcy5feTEgKyB5KSAvIDY7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4MCwgeTApIDogdGhpcy5fY29udGV4dC5tb3ZlVG8oeDAsIHkwKTsgYnJlYWs7XG4gICAgICBjYXNlIDM6IHRoaXMuX3BvaW50ID0gNDsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDogcG9pbnQodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxLCB0aGlzLl94MSA9IHg7XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSwgdGhpcy5feTEgPSB5O1xuICB9XG59O1xuXG52YXIgY3VydmVCYXNpc09wZW4gPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgQmFzaXNPcGVuKGNvbnRleHQpO1xufTtcblxuZnVuY3Rpb24gQnVuZGxlKGNvbnRleHQsIGJldGEpIHtcbiAgdGhpcy5fYmFzaXMgPSBuZXcgQmFzaXMoY29udGV4dCk7XG4gIHRoaXMuX2JldGEgPSBiZXRhO1xufVxuXG5CdW5kbGUucHJvdG90eXBlID0ge1xuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3ggPSBbXTtcbiAgICB0aGlzLl95ID0gW107XG4gICAgdGhpcy5fYmFzaXMubGluZVN0YXJ0KCk7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB4ID0gdGhpcy5feCxcbiAgICAgICAgeSA9IHRoaXMuX3ksXG4gICAgICAgIGogPSB4Lmxlbmd0aCAtIDE7XG5cbiAgICBpZiAoaiA+IDApIHtcbiAgICAgIHZhciB4MCA9IHhbMF0sXG4gICAgICAgICAgeTAgPSB5WzBdLFxuICAgICAgICAgIGR4ID0geFtqXSAtIHgwLFxuICAgICAgICAgIGR5ID0geVtqXSAtIHkwLFxuICAgICAgICAgIGkgPSAtMSxcbiAgICAgICAgICB0O1xuXG4gICAgICB3aGlsZSAoKytpIDw9IGopIHtcbiAgICAgICAgdCA9IGkgLyBqO1xuICAgICAgICB0aGlzLl9iYXNpcy5wb2ludChcbiAgICAgICAgICB0aGlzLl9iZXRhICogeFtpXSArICgxIC0gdGhpcy5fYmV0YSkgKiAoeDAgKyB0ICogZHgpLFxuICAgICAgICAgIHRoaXMuX2JldGEgKiB5W2ldICsgKDEgLSB0aGlzLl9iZXRhKSAqICh5MCArIHQgKiBkeSlcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICB0aGlzLl94ID0gdGhpcy5feSA9IG51bGw7XG4gICAgdGhpcy5fYmFzaXMubGluZUVuZCgpO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHRoaXMuX3gucHVzaCgreCk7XG4gICAgdGhpcy5feS5wdXNoKCt5KTtcbiAgfVxufTtcblxudmFyIGN1cnZlQnVuZGxlID0gKGZ1bmN0aW9uIGN1c3RvbShiZXRhKSB7XG5cbiAgZnVuY3Rpb24gYnVuZGxlKGNvbnRleHQpIHtcbiAgICByZXR1cm4gYmV0YSA9PT0gMSA/IG5ldyBCYXNpcyhjb250ZXh0KSA6IG5ldyBCdW5kbGUoY29udGV4dCwgYmV0YSk7XG4gIH1cblxuICBidW5kbGUuYmV0YSA9IGZ1bmN0aW9uKGJldGEpIHtcbiAgICByZXR1cm4gY3VzdG9tKCtiZXRhKTtcbiAgfTtcblxuICByZXR1cm4gYnVuZGxlO1xufSkoMC44NSk7XG5cbmZ1bmN0aW9uIHBvaW50JDEodGhhdCwgeCwgeSkge1xuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oXG4gICAgdGhhdC5feDEgKyB0aGF0Ll9rICogKHRoYXQuX3gyIC0gdGhhdC5feDApLFxuICAgIHRoYXQuX3kxICsgdGhhdC5fayAqICh0aGF0Ll95MiAtIHRoYXQuX3kwKSxcbiAgICB0aGF0Ll94MiArIHRoYXQuX2sgKiAodGhhdC5feDEgLSB4KSxcbiAgICB0aGF0Ll95MiArIHRoYXQuX2sgKiAodGhhdC5feTEgLSB5KSxcbiAgICB0aGF0Ll94MixcbiAgICB0aGF0Ll95MlxuICApO1xufVxuXG5mdW5jdGlvbiBDYXJkaW5hbChjb250ZXh0LCB0ZW5zaW9uKSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLl9rID0gKDEgLSB0ZW5zaW9uKSAvIDY7XG59XG5cbkNhcmRpbmFsLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMjogdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDIsIHRoaXMuX3kyKTsgYnJlYWs7XG4gICAgICBjYXNlIDM6IHBvaW50JDEodGhpcywgdGhpcy5feDEsIHRoaXMuX3kxKTsgYnJlYWs7XG4gICAgfVxuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl94MSA9IHgsIHRoaXMuX3kxID0geTsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDogcG9pbnQkMSh0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUNhcmRpbmFsID0gKGZ1bmN0aW9uIGN1c3RvbSh0ZW5zaW9uKSB7XG5cbiAgZnVuY3Rpb24gY2FyZGluYWwoY29udGV4dCkge1xuICAgIHJldHVybiBuZXcgQ2FyZGluYWwoY29udGV4dCwgdGVuc2lvbik7XG4gIH1cblxuICBjYXJkaW5hbC50ZW5zaW9uID0gZnVuY3Rpb24odGVuc2lvbikge1xuICAgIHJldHVybiBjdXN0b20oK3RlbnNpb24pO1xuICB9O1xuXG4gIHJldHVybiBjYXJkaW5hbDtcbn0pKDApO1xuXG5mdW5jdGlvbiBDYXJkaW5hbENsb3NlZChjb250ZXh0LCB0ZW5zaW9uKSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xuICB0aGlzLl9rID0gKDEgLSB0ZW5zaW9uKSAvIDY7XG59XG5cbkNhcmRpbmFsQ2xvc2VkLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBub29wJDEsXG4gIGFyZWFFbmQ6IG5vb3AkMSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPSB0aGlzLl94MyA9IHRoaXMuX3g0ID0gdGhpcy5feDUgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IHRoaXMuX3kzID0gdGhpcy5feTQgPSB0aGlzLl95NSA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MywgdGhpcy5feTMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MywgdGhpcy5feTMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDQsIHRoaXMuX3k0KTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NSwgdGhpcy5feTUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX3gzID0geCwgdGhpcy5feTMgPSB5OyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94NCA9IHgsIHRoaXMuX3k0ID0geSk7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX3g1ID0geCwgdGhpcy5feTUgPSB5OyBicmVhaztcbiAgICAgIGRlZmF1bHQ6IHBvaW50JDEodGhpcywgeCwgeSk7IGJyZWFrO1xuICAgIH1cbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxLCB0aGlzLl94MSA9IHRoaXMuX3gyLCB0aGlzLl94MiA9IHg7XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSwgdGhpcy5feTEgPSB0aGlzLl95MiwgdGhpcy5feTIgPSB5O1xuICB9XG59O1xuXG52YXIgY3VydmVDYXJkaW5hbENsb3NlZCA9IChmdW5jdGlvbiBjdXN0b20odGVuc2lvbikge1xuXG4gIGZ1bmN0aW9uIGNhcmRpbmFsKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IENhcmRpbmFsQ2xvc2VkKGNvbnRleHQsIHRlbnNpb24pO1xuICB9XG5cbiAgY2FyZGluYWwudGVuc2lvbiA9IGZ1bmN0aW9uKHRlbnNpb24pIHtcbiAgICByZXR1cm4gY3VzdG9tKCt0ZW5zaW9uKTtcbiAgfTtcblxuICByZXR1cm4gY2FyZGluYWw7XG59KSgwKTtcblxuZnVuY3Rpb24gQ2FyZGluYWxPcGVuKGNvbnRleHQsIHRlbnNpb24pIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2sgPSAoMSAtIHRlbnNpb24pIC8gNjtcbn1cblxuQ2FyZGluYWxPcGVuLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAzKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IGJyZWFrO1xuICAgICAgY2FzZSAxOiB0aGlzLl9wb2ludCA9IDI7IGJyZWFrO1xuICAgICAgY2FzZSAyOiB0aGlzLl9wb2ludCA9IDM7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MiwgdGhpcy5feTIpIDogdGhpcy5fY29udGV4dC5tb3ZlVG8odGhpcy5feDIsIHRoaXMuX3kyKTsgYnJlYWs7XG4gICAgICBjYXNlIDM6IHRoaXMuX3BvaW50ID0gNDsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDogcG9pbnQkMSh0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUNhcmRpbmFsT3BlbiA9IChmdW5jdGlvbiBjdXN0b20odGVuc2lvbikge1xuXG4gIGZ1bmN0aW9uIGNhcmRpbmFsKGNvbnRleHQpIHtcbiAgICByZXR1cm4gbmV3IENhcmRpbmFsT3Blbihjb250ZXh0LCB0ZW5zaW9uKTtcbiAgfVxuXG4gIGNhcmRpbmFsLnRlbnNpb24gPSBmdW5jdGlvbih0ZW5zaW9uKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrdGVuc2lvbik7XG4gIH07XG5cbiAgcmV0dXJuIGNhcmRpbmFsO1xufSkoMCk7XG5cbmZ1bmN0aW9uIHBvaW50JDIodGhhdCwgeCwgeSkge1xuICB2YXIgeDEgPSB0aGF0Ll94MSxcbiAgICAgIHkxID0gdGhhdC5feTEsXG4gICAgICB4MiA9IHRoYXQuX3gyLFxuICAgICAgeTIgPSB0aGF0Ll95MjtcblxuICBpZiAodGhhdC5fbDAxX2EgPiBlcHNpbG9uJDEpIHtcbiAgICB2YXIgYSA9IDIgKiB0aGF0Ll9sMDFfMmEgKyAzICogdGhhdC5fbDAxX2EgKiB0aGF0Ll9sMTJfYSArIHRoYXQuX2wxMl8yYSxcbiAgICAgICAgbiA9IDMgKiB0aGF0Ll9sMDFfYSAqICh0aGF0Ll9sMDFfYSArIHRoYXQuX2wxMl9hKTtcbiAgICB4MSA9ICh4MSAqIGEgLSB0aGF0Ll94MCAqIHRoYXQuX2wxMl8yYSArIHRoYXQuX3gyICogdGhhdC5fbDAxXzJhKSAvIG47XG4gICAgeTEgPSAoeTEgKiBhIC0gdGhhdC5feTAgKiB0aGF0Ll9sMTJfMmEgKyB0aGF0Ll95MiAqIHRoYXQuX2wwMV8yYSkgLyBuO1xuICB9XG5cbiAgaWYgKHRoYXQuX2wyM19hID4gZXBzaWxvbiQxKSB7XG4gICAgdmFyIGIgPSAyICogdGhhdC5fbDIzXzJhICsgMyAqIHRoYXQuX2wyM19hICogdGhhdC5fbDEyX2EgKyB0aGF0Ll9sMTJfMmEsXG4gICAgICAgIG0gPSAzICogdGhhdC5fbDIzX2EgKiAodGhhdC5fbDIzX2EgKyB0aGF0Ll9sMTJfYSk7XG4gICAgeDIgPSAoeDIgKiBiICsgdGhhdC5feDEgKiB0aGF0Ll9sMjNfMmEgLSB4ICogdGhhdC5fbDEyXzJhKSAvIG07XG4gICAgeTIgPSAoeTIgKiBiICsgdGhhdC5feTEgKiB0aGF0Ll9sMjNfMmEgLSB5ICogdGhhdC5fbDEyXzJhKSAvIG07XG4gIH1cblxuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oeDEsIHkxLCB4MiwgeTIsIHRoYXQuX3gyLCB0aGF0Ll95Mik7XG59XG5cbmZ1bmN0aW9uIENhdG11bGxSb20oY29udGV4dCwgYWxwaGEpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2FscGhhID0gYWxwaGE7XG59XG5cbkNhdG11bGxSb20ucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPSB0aGlzLl94MiA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gTmFOO1xuICAgIHRoaXMuX2wwMV9hID0gdGhpcy5fbDEyX2EgPSB0aGlzLl9sMjNfYSA9XG4gICAgdGhpcy5fbDAxXzJhID0gdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhID1cbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMjogdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feDIsIHRoaXMuX3kyKTsgYnJlYWs7XG4gICAgICBjYXNlIDM6IHRoaXMucG9pbnQodGhpcy5feDIsIHRoaXMuX3kyKTsgYnJlYWs7XG4gICAgfVxuICAgIGlmICh0aGlzLl9saW5lIHx8ICh0aGlzLl9saW5lICE9PSAwICYmIHRoaXMuX3BvaW50ID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG5cbiAgICBpZiAodGhpcy5fcG9pbnQpIHtcbiAgICAgIHZhciB4MjMgPSB0aGlzLl94MiAtIHgsXG4gICAgICAgICAgeTIzID0gdGhpcy5feTIgLSB5O1xuICAgICAgdGhpcy5fbDIzX2EgPSBNYXRoLnNxcnQodGhpcy5fbDIzXzJhID0gTWF0aC5wb3coeDIzICogeDIzICsgeTIzICogeTIzLCB0aGlzLl9hbHBoYSkpO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4LCB5KTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDogcG9pbnQkMih0aGlzLCB4LCB5KTsgYnJlYWs7XG4gICAgfVxuXG4gICAgdGhpcy5fbDAxX2EgPSB0aGlzLl9sMTJfYSwgdGhpcy5fbDEyX2EgPSB0aGlzLl9sMjNfYTtcbiAgICB0aGlzLl9sMDFfMmEgPSB0aGlzLl9sMTJfMmEsIHRoaXMuX2wxMl8yYSA9IHRoaXMuX2wyM18yYTtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxLCB0aGlzLl94MSA9IHRoaXMuX3gyLCB0aGlzLl94MiA9IHg7XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSwgdGhpcy5feTEgPSB0aGlzLl95MiwgdGhpcy5feTIgPSB5O1xuICB9XG59O1xuXG52YXIgY3VydmVDYXRtdWxsUm9tID0gKGZ1bmN0aW9uIGN1c3RvbShhbHBoYSkge1xuXG4gIGZ1bmN0aW9uIGNhdG11bGxSb20oY29udGV4dCkge1xuICAgIHJldHVybiBhbHBoYSA/IG5ldyBDYXRtdWxsUm9tKGNvbnRleHQsIGFscGhhKSA6IG5ldyBDYXJkaW5hbChjb250ZXh0LCAwKTtcbiAgfVxuXG4gIGNhdG11bGxSb20uYWxwaGEgPSBmdW5jdGlvbihhbHBoYSkge1xuICAgIHJldHVybiBjdXN0b20oK2FscGhhKTtcbiAgfTtcblxuICByZXR1cm4gY2F0bXVsbFJvbTtcbn0pKDAuNSk7XG5cbmZ1bmN0aW9uIENhdG11bGxSb21DbG9zZWQoY29udGV4dCwgYWxwaGEpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2FscGhhID0gYWxwaGE7XG59XG5cbkNhdG11bGxSb21DbG9zZWQucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IG5vb3AkMSxcbiAgYXJlYUVuZDogbm9vcCQxLFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPSB0aGlzLl94MiA9IHRoaXMuX3gzID0gdGhpcy5feDQgPSB0aGlzLl94NSA9XG4gICAgdGhpcy5feTAgPSB0aGlzLl95MSA9IHRoaXMuX3kyID0gdGhpcy5feTMgPSB0aGlzLl95NCA9IHRoaXMuX3k1ID0gTmFOO1xuICAgIHRoaXMuX2wwMV9hID0gdGhpcy5fbDEyX2EgPSB0aGlzLl9sMjNfYSA9XG4gICAgdGhpcy5fbDAxXzJhID0gdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhID1cbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMToge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MywgdGhpcy5feTMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MywgdGhpcy5feTMpO1xuICAgICAgICB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMzoge1xuICAgICAgICB0aGlzLnBvaW50KHRoaXMuX3gzLCB0aGlzLl95Myk7XG4gICAgICAgIHRoaXMucG9pbnQodGhpcy5feDQsIHRoaXMuX3k0KTtcbiAgICAgICAgdGhpcy5wb2ludCh0aGlzLl94NSwgdGhpcy5feTUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG5cbiAgICBpZiAodGhpcy5fcG9pbnQpIHtcbiAgICAgIHZhciB4MjMgPSB0aGlzLl94MiAtIHgsXG4gICAgICAgICAgeTIzID0gdGhpcy5feTIgLSB5O1xuICAgICAgdGhpcy5fbDIzX2EgPSBNYXRoLnNxcnQodGhpcy5fbDIzXzJhID0gTWF0aC5wb3coeDIzICogeDIzICsgeTIzICogeTIzLCB0aGlzLl9hbHBoYSkpO1xuICAgIH1cblxuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyB0aGlzLl94MyA9IHgsIHRoaXMuX3kzID0geTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgdGhpcy5fY29udGV4dC5tb3ZlVG8odGhpcy5feDQgPSB4LCB0aGlzLl95NCA9IHkpOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyB0aGlzLl94NSA9IHgsIHRoaXMuX3k1ID0geTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hLCB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hO1xuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSwgdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhO1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUNhdG11bGxSb21DbG9zZWQgPSAoZnVuY3Rpb24gY3VzdG9tKGFscGhhKSB7XG5cbiAgZnVuY3Rpb24gY2F0bXVsbFJvbShjb250ZXh0KSB7XG4gICAgcmV0dXJuIGFscGhhID8gbmV3IENhdG11bGxSb21DbG9zZWQoY29udGV4dCwgYWxwaGEpIDogbmV3IENhcmRpbmFsQ2xvc2VkKGNvbnRleHQsIDApO1xuICB9XG5cbiAgY2F0bXVsbFJvbS5hbHBoYSA9IGZ1bmN0aW9uKGFscGhhKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrYWxwaGEpO1xuICB9O1xuXG4gIHJldHVybiBjYXRtdWxsUm9tO1xufSkoMC41KTtcblxuZnVuY3Rpb24gQ2F0bXVsbFJvbU9wZW4oY29udGV4dCwgYWxwaGEpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX2FscGhhID0gYWxwaGE7XG59XG5cbkNhdG11bGxSb21PcGVuLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94MCA9IHRoaXMuX3gxID0gdGhpcy5feDIgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPSB0aGlzLl95MiA9IE5hTjtcbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hID0gdGhpcy5fbDIzX2EgPVxuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSA9IHRoaXMuX2wyM18yYSA9XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMykpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHggPSAreCwgeSA9ICt5O1xuXG4gICAgaWYgKHRoaXMuX3BvaW50KSB7XG4gICAgICB2YXIgeDIzID0gdGhpcy5feDIgLSB4LFxuICAgICAgICAgIHkyMyA9IHRoaXMuX3kyIC0geTtcbiAgICAgIHRoaXMuX2wyM19hID0gTWF0aC5zcXJ0KHRoaXMuX2wyM18yYSA9IE1hdGgucG93KHgyMyAqIHgyMyArIHkyMyAqIHkyMywgdGhpcy5fYWxwaGEpKTtcbiAgICB9XG5cbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHRoaXMuX3BvaW50ID0gMTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgYnJlYWs7XG4gICAgICBjYXNlIDI6IHRoaXMuX3BvaW50ID0gMzsgdGhpcy5fbGluZSA/IHRoaXMuX2NvbnRleHQubGluZVRvKHRoaXMuX3gyLCB0aGlzLl95MikgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh0aGlzLl94MiwgdGhpcy5feTIpOyBicmVhaztcbiAgICAgIGNhc2UgMzogdGhpcy5fcG9pbnQgPSA0OyAvLyBwcm9jZWVkXG4gICAgICBkZWZhdWx0OiBwb2ludCQyKHRoaXMsIHgsIHkpOyBicmVhaztcbiAgICB9XG5cbiAgICB0aGlzLl9sMDFfYSA9IHRoaXMuX2wxMl9hLCB0aGlzLl9sMTJfYSA9IHRoaXMuX2wyM19hO1xuICAgIHRoaXMuX2wwMV8yYSA9IHRoaXMuX2wxMl8yYSwgdGhpcy5fbDEyXzJhID0gdGhpcy5fbDIzXzJhO1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0gdGhpcy5feDIsIHRoaXMuX3gyID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHRoaXMuX3kyLCB0aGlzLl95MiA9IHk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUNhdG11bGxSb21PcGVuID0gKGZ1bmN0aW9uIGN1c3RvbShhbHBoYSkge1xuXG4gIGZ1bmN0aW9uIGNhdG11bGxSb20oY29udGV4dCkge1xuICAgIHJldHVybiBhbHBoYSA/IG5ldyBDYXRtdWxsUm9tT3Blbihjb250ZXh0LCBhbHBoYSkgOiBuZXcgQ2FyZGluYWxPcGVuKGNvbnRleHQsIDApO1xuICB9XG5cbiAgY2F0bXVsbFJvbS5hbHBoYSA9IGZ1bmN0aW9uKGFscGhhKSB7XG4gICAgcmV0dXJuIGN1c3RvbSgrYWxwaGEpO1xuICB9O1xuXG4gIHJldHVybiBjYXRtdWxsUm9tO1xufSkoMC41KTtcblxuZnVuY3Rpb24gTGluZWFyQ2xvc2VkKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbkxpbmVhckNsb3NlZC5wcm90b3R5cGUgPSB7XG4gIGFyZWFTdGFydDogbm9vcCQxLFxuICBhcmVhRW5kOiBub29wJDEsXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fcG9pbnQpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgeCA9ICt4LCB5ID0gK3k7XG4gICAgaWYgKHRoaXMuX3BvaW50KSB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KTtcbiAgICBlbHNlIHRoaXMuX3BvaW50ID0gMSwgdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZUxpbmVhckNsb3NlZCA9IGZ1bmN0aW9uKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBMaW5lYXJDbG9zZWQoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBzaWduKHgpIHtcbiAgcmV0dXJuIHggPCAwID8gLTEgOiAxO1xufVxuXG4vLyBDYWxjdWxhdGUgdGhlIHNsb3BlcyBvZiB0aGUgdGFuZ2VudHMgKEhlcm1pdGUtdHlwZSBpbnRlcnBvbGF0aW9uKSBiYXNlZCBvblxuLy8gdGhlIGZvbGxvd2luZyBwYXBlcjogU3RlZmZlbiwgTS4gMTk5MC4gQSBTaW1wbGUgTWV0aG9kIGZvciBNb25vdG9uaWNcbi8vIEludGVycG9sYXRpb24gaW4gT25lIERpbWVuc2lvbi4gQXN0cm9ub215IGFuZCBBc3Ryb3BoeXNpY3MsIFZvbC4gMjM5LCBOTy5cbi8vIE5PVihJSSksIFAuIDQ0MywgMTk5MC5cbmZ1bmN0aW9uIHNsb3BlMyh0aGF0LCB4MiwgeTIpIHtcbiAgdmFyIGgwID0gdGhhdC5feDEgLSB0aGF0Ll94MCxcbiAgICAgIGgxID0geDIgLSB0aGF0Ll94MSxcbiAgICAgIHMwID0gKHRoYXQuX3kxIC0gdGhhdC5feTApIC8gKGgwIHx8IGgxIDwgMCAmJiAtMCksXG4gICAgICBzMSA9ICh5MiAtIHRoYXQuX3kxKSAvIChoMSB8fCBoMCA8IDAgJiYgLTApLFxuICAgICAgcCA9IChzMCAqIGgxICsgczEgKiBoMCkgLyAoaDAgKyBoMSk7XG4gIHJldHVybiAoc2lnbihzMCkgKyBzaWduKHMxKSkgKiBNYXRoLm1pbihNYXRoLmFicyhzMCksIE1hdGguYWJzKHMxKSwgMC41ICogTWF0aC5hYnMocCkpIHx8IDA7XG59XG5cbi8vIENhbGN1bGF0ZSBhIG9uZS1zaWRlZCBzbG9wZS5cbmZ1bmN0aW9uIHNsb3BlMih0aGF0LCB0KSB7XG4gIHZhciBoID0gdGhhdC5feDEgLSB0aGF0Ll94MDtcbiAgcmV0dXJuIGggPyAoMyAqICh0aGF0Ll95MSAtIHRoYXQuX3kwKSAvIGggLSB0KSAvIDIgOiB0O1xufVxuXG4vLyBBY2NvcmRpbmcgdG8gaHR0cHM6Ly9lbi53aWtpcGVkaWEub3JnL3dpa2kvQ3ViaWNfSGVybWl0ZV9zcGxpbmUjUmVwcmVzZW50YXRpb25zXG4vLyBcInlvdSBjYW4gZXhwcmVzcyBjdWJpYyBIZXJtaXRlIGludGVycG9sYXRpb24gaW4gdGVybXMgb2YgY3ViaWMgQsOpemllciBjdXJ2ZXNcbi8vIHdpdGggcmVzcGVjdCB0byB0aGUgZm91ciB2YWx1ZXMgcDAsIHAwICsgbTAgLyAzLCBwMSAtIG0xIC8gMywgcDFcIi5cbmZ1bmN0aW9uIHBvaW50JDModGhhdCwgdDAsIHQxKSB7XG4gIHZhciB4MCA9IHRoYXQuX3gwLFxuICAgICAgeTAgPSB0aGF0Ll95MCxcbiAgICAgIHgxID0gdGhhdC5feDEsXG4gICAgICB5MSA9IHRoYXQuX3kxLFxuICAgICAgZHggPSAoeDEgLSB4MCkgLyAzO1xuICB0aGF0Ll9jb250ZXh0LmJlemllckN1cnZlVG8oeDAgKyBkeCwgeTAgKyBkeCAqIHQwLCB4MSAtIGR4LCB5MSAtIGR4ICogdDEsIHgxLCB5MSk7XG59XG5cbmZ1bmN0aW9uIE1vbm90b25lWChjb250ZXh0KSB7XG4gIHRoaXMuX2NvbnRleHQgPSBjb250ZXh0O1xufVxuXG5Nb25vdG9uZVgucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3gwID0gdGhpcy5feDEgPVxuICAgIHRoaXMuX3kwID0gdGhpcy5feTEgPVxuICAgIHRoaXMuX3QwID0gTmFOO1xuICAgIHRoaXMuX3BvaW50ID0gMDtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAyOiB0aGlzLl9jb250ZXh0LmxpbmVUbyh0aGlzLl94MSwgdGhpcy5feTEpOyBicmVhaztcbiAgICAgIGNhc2UgMzogcG9pbnQkMyh0aGlzLCB0aGlzLl90MCwgc2xvcGUyKHRoaXMsIHRoaXMuX3QwKSk7IGJyZWFrO1xuICAgIH1cbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiB0aGlzLl9wb2ludCA9PT0gMSkpIHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHZhciB0MSA9IE5hTjtcblxuICAgIHggPSAreCwgeSA9ICt5O1xuICAgIGlmICh4ID09PSB0aGlzLl94MSAmJiB5ID09PSB0aGlzLl95MSkgcmV0dXJuOyAvLyBJZ25vcmUgY29pbmNpZGVudCBwb2ludHMuXG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB0aGlzLl9wb2ludCA9IDE7IHRoaXMuX2xpbmUgPyB0aGlzLl9jb250ZXh0LmxpbmVUbyh4LCB5KSA6IHRoaXMuX2NvbnRleHQubW92ZVRvKHgsIHkpOyBicmVhaztcbiAgICAgIGNhc2UgMTogdGhpcy5fcG9pbnQgPSAyOyBicmVhaztcbiAgICAgIGNhc2UgMjogdGhpcy5fcG9pbnQgPSAzOyBwb2ludCQzKHRoaXMsIHNsb3BlMih0aGlzLCB0MSA9IHNsb3BlMyh0aGlzLCB4LCB5KSksIHQxKTsgYnJlYWs7XG4gICAgICBkZWZhdWx0OiBwb2ludCQzKHRoaXMsIHRoaXMuX3QwLCB0MSA9IHNsb3BlMyh0aGlzLCB4LCB5KSk7IGJyZWFrO1xuICAgIH1cblxuICAgIHRoaXMuX3gwID0gdGhpcy5feDEsIHRoaXMuX3gxID0geDtcbiAgICB0aGlzLl95MCA9IHRoaXMuX3kxLCB0aGlzLl95MSA9IHk7XG4gICAgdGhpcy5fdDAgPSB0MTtcbiAgfVxufTtcblxuZnVuY3Rpb24gTW9ub3RvbmVZKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IG5ldyBSZWZsZWN0Q29udGV4dChjb250ZXh0KTtcbn1cblxuKE1vbm90b25lWS5wcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKE1vbm90b25lWC5wcm90b3R5cGUpKS5wb2ludCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgTW9ub3RvbmVYLnByb3RvdHlwZS5wb2ludC5jYWxsKHRoaXMsIHksIHgpO1xufTtcblxuZnVuY3Rpb24gUmVmbGVjdENvbnRleHQoY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuUmVmbGVjdENvbnRleHQucHJvdG90eXBlID0ge1xuICBtb3ZlVG86IGZ1bmN0aW9uKHgsIHkpIHsgdGhpcy5fY29udGV4dC5tb3ZlVG8oeSwgeCk7IH0sXG4gIGNsb3NlUGF0aDogZnVuY3Rpb24oKSB7IHRoaXMuX2NvbnRleHQuY2xvc2VQYXRoKCk7IH0sXG4gIGxpbmVUbzogZnVuY3Rpb24oeCwgeSkgeyB0aGlzLl9jb250ZXh0LmxpbmVUbyh5LCB4KTsgfSxcbiAgYmV6aWVyQ3VydmVUbzogZnVuY3Rpb24oeDEsIHkxLCB4MiwgeTIsIHgsIHkpIHsgdGhpcy5fY29udGV4dC5iZXppZXJDdXJ2ZVRvKHkxLCB4MSwgeTIsIHgyLCB5LCB4KTsgfVxufTtcblxuZnVuY3Rpb24gbW9ub3RvbmVYKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBNb25vdG9uZVgoY29udGV4dCk7XG59XG5cbmZ1bmN0aW9uIG1vbm90b25lWShjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgTW9ub3RvbmVZKGNvbnRleHQpO1xufVxuXG5mdW5jdGlvbiBOYXR1cmFsKGNvbnRleHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG59XG5cbk5hdHVyYWwucHJvdG90eXBlID0ge1xuICBhcmVhU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSAwO1xuICB9LFxuICBhcmVhRW5kOiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gTmFOO1xuICB9LFxuICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX3ggPSBbXTtcbiAgICB0aGlzLl95ID0gW107XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciB4ID0gdGhpcy5feCxcbiAgICAgICAgeSA9IHRoaXMuX3ksXG4gICAgICAgIG4gPSB4Lmxlbmd0aDtcblxuICAgIGlmIChuKSB7XG4gICAgICB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeFswXSwgeVswXSkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4WzBdLCB5WzBdKTtcbiAgICAgIGlmIChuID09PSAyKSB7XG4gICAgICAgIHRoaXMuX2NvbnRleHQubGluZVRvKHhbMV0sIHlbMV0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFyIHB4ID0gY29udHJvbFBvaW50cyh4KSxcbiAgICAgICAgICAgIHB5ID0gY29udHJvbFBvaW50cyh5KTtcbiAgICAgICAgZm9yICh2YXIgaTAgPSAwLCBpMSA9IDE7IGkxIDwgbjsgKytpMCwgKytpMSkge1xuICAgICAgICAgIHRoaXMuX2NvbnRleHQuYmV6aWVyQ3VydmVUbyhweFswXVtpMF0sIHB5WzBdW2kwXSwgcHhbMV1baTBdLCBweVsxXVtpMF0sIHhbaTFdLCB5W2kxXSk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fbGluZSB8fCAodGhpcy5fbGluZSAhPT0gMCAmJiBuID09PSAxKSkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9saW5lID0gMSAtIHRoaXMuX2xpbmU7XG4gICAgdGhpcy5feCA9IHRoaXMuX3kgPSBudWxsO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHRoaXMuX3gucHVzaCgreCk7XG4gICAgdGhpcy5feS5wdXNoKCt5KTtcbiAgfVxufTtcblxuLy8gU2VlIGh0dHBzOi8vd3d3LnBhcnRpY2xlaW5jZWxsLmNvbS8yMDEyL2Jlemllci1zcGxpbmVzLyBmb3IgZGVyaXZhdGlvbi5cbmZ1bmN0aW9uIGNvbnRyb2xQb2ludHMoeCkge1xuICB2YXIgaSxcbiAgICAgIG4gPSB4Lmxlbmd0aCAtIDEsXG4gICAgICBtLFxuICAgICAgYSA9IG5ldyBBcnJheShuKSxcbiAgICAgIGIgPSBuZXcgQXJyYXkobiksXG4gICAgICByID0gbmV3IEFycmF5KG4pO1xuICBhWzBdID0gMCwgYlswXSA9IDIsIHJbMF0gPSB4WzBdICsgMiAqIHhbMV07XG4gIGZvciAoaSA9IDE7IGkgPCBuIC0gMTsgKytpKSBhW2ldID0gMSwgYltpXSA9IDQsIHJbaV0gPSA0ICogeFtpXSArIDIgKiB4W2kgKyAxXTtcbiAgYVtuIC0gMV0gPSAyLCBiW24gLSAxXSA9IDcsIHJbbiAtIDFdID0gOCAqIHhbbiAtIDFdICsgeFtuXTtcbiAgZm9yIChpID0gMTsgaSA8IG47ICsraSkgbSA9IGFbaV0gLyBiW2kgLSAxXSwgYltpXSAtPSBtLCByW2ldIC09IG0gKiByW2kgLSAxXTtcbiAgYVtuIC0gMV0gPSByW24gLSAxXSAvIGJbbiAtIDFdO1xuICBmb3IgKGkgPSBuIC0gMjsgaSA+PSAwOyAtLWkpIGFbaV0gPSAocltpXSAtIGFbaSArIDFdKSAvIGJbaV07XG4gIGJbbiAtIDFdID0gKHhbbl0gKyBhW24gLSAxXSkgLyAyO1xuICBmb3IgKGkgPSAwOyBpIDwgbiAtIDE7ICsraSkgYltpXSA9IDIgKiB4W2kgKyAxXSAtIGFbaSArIDFdO1xuICByZXR1cm4gW2EsIGJdO1xufVxuXG52YXIgY3VydmVOYXR1cmFsID0gZnVuY3Rpb24oY29udGV4dCkge1xuICByZXR1cm4gbmV3IE5hdHVyYWwoY29udGV4dCk7XG59O1xuXG5mdW5jdGlvbiBTdGVwKGNvbnRleHQsIHQpIHtcbiAgdGhpcy5fY29udGV4dCA9IGNvbnRleHQ7XG4gIHRoaXMuX3QgPSB0O1xufVxuXG5TdGVwLnByb3RvdHlwZSA9IHtcbiAgYXJlYVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgYXJlYUVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl94ID0gdGhpcy5feSA9IE5hTjtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICgwIDwgdGhpcy5fdCAmJiB0aGlzLl90IDwgMSAmJiB0aGlzLl9wb2ludCA9PT0gMikgdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feCwgdGhpcy5feSk7XG4gICAgaWYgKHRoaXMuX2xpbmUgfHwgKHRoaXMuX2xpbmUgIT09IDAgJiYgdGhpcy5fcG9pbnQgPT09IDEpKSB0aGlzLl9jb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIGlmICh0aGlzLl9saW5lID49IDApIHRoaXMuX3QgPSAxIC0gdGhpcy5fdCwgdGhpcy5fbGluZSA9IDEgLSB0aGlzLl9saW5lO1xuICB9LFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHggPSAreCwgeSA9ICt5O1xuICAgIHN3aXRjaCAodGhpcy5fcG9pbnQpIHtcbiAgICAgIGNhc2UgMDogdGhpcy5fcG9pbnQgPSAxOyB0aGlzLl9saW5lID8gdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSkgOiB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4LCB5KTsgYnJlYWs7XG4gICAgICBjYXNlIDE6IHRoaXMuX3BvaW50ID0gMjsgLy8gcHJvY2VlZFxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICBpZiAodGhpcy5fdCA8PSAwKSB7XG4gICAgICAgICAgdGhpcy5fY29udGV4dC5saW5lVG8odGhpcy5feCwgeSk7XG4gICAgICAgICAgdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFyIHgxID0gdGhpcy5feCAqICgxIC0gdGhpcy5fdCkgKyB4ICogdGhpcy5fdDtcbiAgICAgICAgICB0aGlzLl9jb250ZXh0LmxpbmVUbyh4MSwgdGhpcy5feSk7XG4gICAgICAgICAgdGhpcy5fY29udGV4dC5saW5lVG8oeDEsIHkpO1xuICAgICAgICB9XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgICB0aGlzLl94ID0geCwgdGhpcy5feSA9IHk7XG4gIH1cbn07XG5cbnZhciBjdXJ2ZVN0ZXAgPSBmdW5jdGlvbihjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgU3RlcChjb250ZXh0LCAwLjUpO1xufTtcblxuZnVuY3Rpb24gc3RlcEJlZm9yZShjb250ZXh0KSB7XG4gIHJldHVybiBuZXcgU3RlcChjb250ZXh0LCAwKTtcbn1cblxuZnVuY3Rpb24gc3RlcEFmdGVyKGNvbnRleHQpIHtcbiAgcmV0dXJuIG5ldyBTdGVwKGNvbnRleHQsIDEpO1xufVxuXG52YXIgbG9va3VwID0ge1xuICAnYmFzaXMnOiB7XG4gICAgY3VydmU6IGN1cnZlQmFzaXNcbiAgfSxcbiAgJ2Jhc2lzLWNsb3NlZCc6IHtcbiAgICBjdXJ2ZTogY3VydmVCYXNpc0Nsb3NlZFxuICB9LFxuICAnYmFzaXMtb3Blbic6IHtcbiAgICBjdXJ2ZTogY3VydmVCYXNpc09wZW5cbiAgfSxcbiAgJ2J1bmRsZSc6IHtcbiAgICBjdXJ2ZTogY3VydmVCdW5kbGUsXG4gICAgdGVuc2lvbjogJ2JldGEnLFxuICAgIHZhbHVlOiAwLjg1XG4gIH0sXG4gICdjYXJkaW5hbCc6IHtcbiAgICBjdXJ2ZTogY3VydmVDYXJkaW5hbCxcbiAgICB0ZW5zaW9uOiAndGVuc2lvbicsXG4gICAgdmFsdWU6IDBcbiAgfSxcbiAgJ2NhcmRpbmFsLW9wZW4nOiB7XG4gICAgY3VydmU6IGN1cnZlQ2FyZGluYWxPcGVuLFxuICAgIHRlbnNpb246ICd0ZW5zaW9uJyxcbiAgICB2YWx1ZTogMFxuICB9LFxuICAnY2FyZGluYWwtY2xvc2VkJzoge1xuICAgIGN1cnZlOiBjdXJ2ZUNhcmRpbmFsQ2xvc2VkLFxuICAgIHRlbnNpb246ICd0ZW5zaW9uJyxcbiAgICB2YWx1ZTogMFxuICB9LFxuICAnY2F0bXVsbC1yb20nOiB7XG4gICAgY3VydmU6IGN1cnZlQ2F0bXVsbFJvbSxcbiAgICB0ZW5zaW9uOiAnYWxwaGEnLFxuICAgIHZhbHVlOiAwLjVcbiAgfSxcbiAgJ2NhdG11bGwtcm9tLWNsb3NlZCc6IHtcbiAgICBjdXJ2ZTogY3VydmVDYXRtdWxsUm9tQ2xvc2VkLFxuICAgIHRlbnNpb246ICdhbHBoYScsXG4gICAgdmFsdWU6IDAuNVxuICB9LFxuICAnY2F0bXVsbC1yb20tb3Blbic6IHtcbiAgICBjdXJ2ZTogY3VydmVDYXRtdWxsUm9tT3BlbixcbiAgICB0ZW5zaW9uOiAnYWxwaGEnLFxuICAgIHZhbHVlOiAwLjVcbiAgfSxcbiAgJ2xpbmVhcic6IHtcbiAgICBjdXJ2ZTogY3VydmVMaW5lYXJcbiAgfSxcbiAgJ2xpbmVhci1jbG9zZWQnOiB7XG4gICAgY3VydmU6IGN1cnZlTGluZWFyQ2xvc2VkXG4gIH0sXG4gICdtb25vdG9uZSc6IHtcbiAgICBob3Jpem9udGFsOiBtb25vdG9uZVksXG4gICAgdmVydGljYWw6ICAgbW9ub3RvbmVYXG4gIH0sXG4gICduYXR1cmFsJzoge1xuICAgIGN1cnZlOiBjdXJ2ZU5hdHVyYWxcbiAgfSxcbiAgJ3N0ZXAnOiB7XG4gICAgY3VydmU6IGN1cnZlU3RlcFxuICB9LFxuICAnc3RlcC1hZnRlcic6IHtcbiAgICBjdXJ2ZTogc3RlcEFmdGVyXG4gIH0sXG4gICdzdGVwLWJlZm9yZSc6IHtcbiAgICBjdXJ2ZTogc3RlcEJlZm9yZVxuICB9XG59O1xuXG5mdW5jdGlvbiBjdXJ2ZXModHlwZSwgb3JpZW50YXRpb24sIHRlbnNpb24pIHtcbiAgdmFyIGVudHJ5ID0gbG9va3VwLmhhc093blByb3BlcnR5KHR5cGUpICYmIGxvb2t1cFt0eXBlXSxcbiAgICAgIGN1cnZlID0gbnVsbDtcblxuICBpZiAoZW50cnkpIHtcbiAgICBjdXJ2ZSA9IGVudHJ5LmN1cnZlIHx8IGVudHJ5W29yaWVudGF0aW9uIHx8ICd2ZXJ0aWNhbCddO1xuICAgIGlmIChlbnRyeS50ZW5zaW9uICYmIHRlbnNpb24gIT0gbnVsbCkge1xuICAgICAgY3VydmUgPSBjdXJ2ZVtlbnRyeS50ZW5zaW9uXSh0ZW5zaW9uKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY3VydmU7XG59XG5cbi8vIFBhdGggcGFyc2luZyBhbmQgcmVuZGVyaW5nIGNvZGUgYWRhcHRlZCBmcm9tIGZhYnJpYy5qcyAtLSBUaGFua3MhXG52YXIgY21kbGVuID0geyBtOjIsIGw6MiwgaDoxLCB2OjEsIGM6Niwgczo0LCBxOjQsIHQ6MiwgYTo3IH07XG52YXIgcmVnZXhwID0gWy8oW01MSFZDU1FUQVptbGh2Y3NxdGF6XSkvZywgLyMjIy8sIC8oXFxkKShbLStdKS9nLCAvXFxzfCx8IyMjL107XG5cbnZhciBwYXRoUGFyc2UgPSBmdW5jdGlvbihwYXRoc3RyKSB7XG4gIHZhciByZXN1bHQgPSBbXSxcbiAgICAgIHBhdGgsXG4gICAgICBjdXJyLFxuICAgICAgY2h1bmtzLFxuICAgICAgcGFyc2VkLCBwYXJhbSxcbiAgICAgIGNtZCwgbGVuLCBpLCBqLCBuLCBtO1xuXG4gIC8vIEZpcnN0LCBicmVhayBwYXRoIGludG8gY29tbWFuZCBzZXF1ZW5jZVxuICBwYXRoID0gcGF0aHN0clxuICAgIC5zbGljZSgpXG4gICAgLnJlcGxhY2UocmVnZXhwWzBdLCAnIyMjJDEnKVxuICAgIC5zcGxpdChyZWdleHBbMV0pXG4gICAgLnNsaWNlKDEpO1xuXG4gIC8vIE5leHQsIHBhcnNlIGVhY2ggY29tbWFuZCBpbiB0dXJuXG4gIGZvciAoaT0wLCBuPXBhdGgubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGN1cnIgPSBwYXRoW2ldO1xuICAgIGNodW5rcyA9IGN1cnJcbiAgICAgIC5zbGljZSgxKVxuICAgICAgLnRyaW0oKVxuICAgICAgLnJlcGxhY2UocmVnZXhwWzJdLCckMSMjIyQyJylcbiAgICAgIC5zcGxpdChyZWdleHBbM10pO1xuICAgIGNtZCA9IGN1cnIuY2hhckF0KDApO1xuXG4gICAgcGFyc2VkID0gW2NtZF07XG4gICAgZm9yIChqPTAsIG09Y2h1bmtzLmxlbmd0aDsgajxtOyArK2opIHtcbiAgICAgIGlmICgocGFyYW0gPSArY2h1bmtzW2pdKSA9PT0gcGFyYW0pIHsgLy8gbm90IE5hTlxuICAgICAgICBwYXJzZWQucHVzaChwYXJhbSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgbGVuID0gY21kbGVuW2NtZC50b0xvd2VyQ2FzZSgpXTtcbiAgICBpZiAocGFyc2VkLmxlbmd0aC0xID4gbGVuKSB7XG4gICAgICBmb3IgKGo9MSwgbT1wYXJzZWQubGVuZ3RoOyBqPG07IGorPWxlbikge1xuICAgICAgICByZXN1bHQucHVzaChbY21kXS5jb25jYXQocGFyc2VkLnNsaWNlKGosIGorbGVuKSkpO1xuICAgICAgfVxuICAgIH1cbiAgICBlbHNlIHtcbiAgICAgIHJlc3VsdC5wdXNoKHBhcnNlZCk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHJlc3VsdDtcbn07XG5cbnZhciBzZWdtZW50Q2FjaGUgPSB7fTtcbnZhciBiZXppZXJDYWNoZSA9IHt9O1xuXG52YXIgam9pbiA9IFtdLmpvaW47XG5cbi8vIENvcGllZCBmcm9tIElua3NjYXBlIHN2Z3RvcGRmLCB0aGFua3MhXG5mdW5jdGlvbiBzZWdtZW50cyh4LCB5LCByeCwgcnksIGxhcmdlLCBzd2VlcCwgcm90YXRlWCwgb3gsIG95KSB7XG4gIHZhciBrZXkgPSBqb2luLmNhbGwoYXJndW1lbnRzKTtcbiAgaWYgKHNlZ21lbnRDYWNoZVtrZXldKSB7XG4gICAgcmV0dXJuIHNlZ21lbnRDYWNoZVtrZXldO1xuICB9XG5cbiAgdmFyIHRoID0gcm90YXRlWCAqIChNYXRoLlBJLzE4MCk7XG4gIHZhciBzaW5fdGggPSBNYXRoLnNpbih0aCk7XG4gIHZhciBjb3NfdGggPSBNYXRoLmNvcyh0aCk7XG4gIHJ4ID0gTWF0aC5hYnMocngpO1xuICByeSA9IE1hdGguYWJzKHJ5KTtcbiAgdmFyIHB4ID0gY29zX3RoICogKG94IC0geCkgKiAwLjUgKyBzaW5fdGggKiAob3kgLSB5KSAqIDAuNTtcbiAgdmFyIHB5ID0gY29zX3RoICogKG95IC0geSkgKiAwLjUgLSBzaW5fdGggKiAob3ggLSB4KSAqIDAuNTtcbiAgdmFyIHBsID0gKHB4KnB4KSAvIChyeCpyeCkgKyAocHkqcHkpIC8gKHJ5KnJ5KTtcbiAgaWYgKHBsID4gMSkge1xuICAgIHBsID0gTWF0aC5zcXJ0KHBsKTtcbiAgICByeCAqPSBwbDtcbiAgICByeSAqPSBwbDtcbiAgfVxuXG4gIHZhciBhMDAgPSBjb3NfdGggLyByeDtcbiAgdmFyIGEwMSA9IHNpbl90aCAvIHJ4O1xuICB2YXIgYTEwID0gKC1zaW5fdGgpIC8gcnk7XG4gIHZhciBhMTEgPSAoY29zX3RoKSAvIHJ5O1xuICB2YXIgeDAgPSBhMDAgKiBveCArIGEwMSAqIG95O1xuICB2YXIgeTAgPSBhMTAgKiBveCArIGExMSAqIG95O1xuICB2YXIgeDEgPSBhMDAgKiB4ICsgYTAxICogeTtcbiAgdmFyIHkxID0gYTEwICogeCArIGExMSAqIHk7XG5cbiAgdmFyIGQgPSAoeDEteDApICogKHgxLXgwKSArICh5MS15MCkgKiAoeTEteTApO1xuICB2YXIgc2ZhY3Rvcl9zcSA9IDEgLyBkIC0gMC4yNTtcbiAgaWYgKHNmYWN0b3Jfc3EgPCAwKSBzZmFjdG9yX3NxID0gMDtcbiAgdmFyIHNmYWN0b3IgPSBNYXRoLnNxcnQoc2ZhY3Rvcl9zcSk7XG4gIGlmIChzd2VlcCA9PSBsYXJnZSkgc2ZhY3RvciA9IC1zZmFjdG9yO1xuICB2YXIgeGMgPSAwLjUgKiAoeDAgKyB4MSkgLSBzZmFjdG9yICogKHkxLXkwKTtcbiAgdmFyIHljID0gMC41ICogKHkwICsgeTEpICsgc2ZhY3RvciAqICh4MS14MCk7XG5cbiAgdmFyIHRoMCA9IE1hdGguYXRhbjIoeTAteWMsIHgwLXhjKTtcbiAgdmFyIHRoMSA9IE1hdGguYXRhbjIoeTEteWMsIHgxLXhjKTtcblxuICB2YXIgdGhfYXJjID0gdGgxLXRoMDtcbiAgaWYgKHRoX2FyYyA8IDAgJiYgc3dlZXAgPT09IDEpe1xuICAgIHRoX2FyYyArPSAyICogTWF0aC5QSTtcbiAgfSBlbHNlIGlmICh0aF9hcmMgPiAwICYmIHN3ZWVwID09PSAwKSB7XG4gICAgdGhfYXJjIC09IDIgKiBNYXRoLlBJO1xuICB9XG5cbiAgdmFyIHNlZ3MgPSBNYXRoLmNlaWwoTWF0aC5hYnModGhfYXJjIC8gKE1hdGguUEkgKiAwLjUgKyAwLjAwMSkpKTtcbiAgdmFyIHJlc3VsdCA9IFtdO1xuICBmb3IgKHZhciBpPTA7IGk8c2VnczsgKytpKSB7XG4gICAgdmFyIHRoMiA9IHRoMCArIGkgKiB0aF9hcmMgLyBzZWdzO1xuICAgIHZhciB0aDMgPSB0aDAgKyAoaSsxKSAqIHRoX2FyYyAvIHNlZ3M7XG4gICAgcmVzdWx0W2ldID0gW3hjLCB5YywgdGgyLCB0aDMsIHJ4LCByeSwgc2luX3RoLCBjb3NfdGhdO1xuICB9XG5cbiAgcmV0dXJuIChzZWdtZW50Q2FjaGVba2V5XSA9IHJlc3VsdCk7XG59XG5cbmZ1bmN0aW9uIGJlemllcihwYXJhbXMpIHtcbiAgdmFyIGtleSA9IGpvaW4uY2FsbChwYXJhbXMpO1xuICBpZiAoYmV6aWVyQ2FjaGVba2V5XSkge1xuICAgIHJldHVybiBiZXppZXJDYWNoZVtrZXldO1xuICB9XG5cbiAgdmFyIGN4ID0gcGFyYW1zWzBdLFxuICAgICAgY3kgPSBwYXJhbXNbMV0sXG4gICAgICB0aDAgPSBwYXJhbXNbMl0sXG4gICAgICB0aDEgPSBwYXJhbXNbM10sXG4gICAgICByeCA9IHBhcmFtc1s0XSxcbiAgICAgIHJ5ID0gcGFyYW1zWzVdLFxuICAgICAgc2luX3RoID0gcGFyYW1zWzZdLFxuICAgICAgY29zX3RoID0gcGFyYW1zWzddO1xuXG4gIHZhciBhMDAgPSBjb3NfdGggKiByeDtcbiAgdmFyIGEwMSA9IC1zaW5fdGggKiByeTtcbiAgdmFyIGExMCA9IHNpbl90aCAqIHJ4O1xuICB2YXIgYTExID0gY29zX3RoICogcnk7XG5cbiAgdmFyIGNvc190aDAgPSBNYXRoLmNvcyh0aDApO1xuICB2YXIgc2luX3RoMCA9IE1hdGguc2luKHRoMCk7XG4gIHZhciBjb3NfdGgxID0gTWF0aC5jb3ModGgxKTtcbiAgdmFyIHNpbl90aDEgPSBNYXRoLnNpbih0aDEpO1xuXG4gIHZhciB0aF9oYWxmID0gMC41ICogKHRoMSAtIHRoMCk7XG4gIHZhciBzaW5fdGhfaDIgPSBNYXRoLnNpbih0aF9oYWxmICogMC41KTtcbiAgdmFyIHQgPSAoOC8zKSAqIHNpbl90aF9oMiAqIHNpbl90aF9oMiAvIE1hdGguc2luKHRoX2hhbGYpO1xuICB2YXIgeDEgPSBjeCArIGNvc190aDAgLSB0ICogc2luX3RoMDtcbiAgdmFyIHkxID0gY3kgKyBzaW5fdGgwICsgdCAqIGNvc190aDA7XG4gIHZhciB4MyA9IGN4ICsgY29zX3RoMTtcbiAgdmFyIHkzID0gY3kgKyBzaW5fdGgxO1xuICB2YXIgeDIgPSB4MyArIHQgKiBzaW5fdGgxO1xuICB2YXIgeTIgPSB5MyAtIHQgKiBjb3NfdGgxO1xuXG4gIHJldHVybiAoYmV6aWVyQ2FjaGVba2V5XSA9IFtcbiAgICBhMDAgKiB4MSArIGEwMSAqIHkxLCAgYTEwICogeDEgKyBhMTEgKiB5MSxcbiAgICBhMDAgKiB4MiArIGEwMSAqIHkyLCAgYTEwICogeDIgKyBhMTEgKiB5MixcbiAgICBhMDAgKiB4MyArIGEwMSAqIHkzLCAgYTEwICogeDMgKyBhMTEgKiB5M1xuICBdKTtcbn1cblxudmFyIHRlbXAgPSBbJ2wnLCAwLCAwLCAwLCAwLCAwLCAwLCAwXTtcblxuZnVuY3Rpb24gc2NhbGUoY3VycmVudCwgcykge1xuICB2YXIgYyA9ICh0ZW1wWzBdID0gY3VycmVudFswXSk7XG4gIGlmIChjID09PSAnYScgfHwgYyA9PT0gJ0EnKSB7XG4gICAgdGVtcFsxXSA9IHMgKiBjdXJyZW50WzFdO1xuICAgIHRlbXBbMl0gPSBzICogY3VycmVudFsyXTtcbiAgICB0ZW1wWzZdID0gcyAqIGN1cnJlbnRbNl07XG4gICAgdGVtcFs3XSA9IHMgKiBjdXJyZW50WzddO1xuICB9IGVsc2Uge1xuICAgIGZvciAodmFyIGk9MSwgbj1jdXJyZW50Lmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIHRlbXBbaV0gPSBzICogY3VycmVudFtpXTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHRlbXA7XG59XG5cbnZhciBwYXRoUmVuZGVyID0gZnVuY3Rpb24oY29udGV4dCwgcGF0aCwgbCwgdCwgcykge1xuICB2YXIgY3VycmVudCwgLy8gY3VycmVudCBpbnN0cnVjdGlvblxuICAgICAgcHJldmlvdXMgPSBudWxsLFxuICAgICAgeCA9IDAsIC8vIGN1cnJlbnQgeFxuICAgICAgeSA9IDAsIC8vIGN1cnJlbnQgeVxuICAgICAgY29udHJvbFggPSAwLCAvLyBjdXJyZW50IGNvbnRyb2wgcG9pbnQgeFxuICAgICAgY29udHJvbFkgPSAwLCAvLyBjdXJyZW50IGNvbnRyb2wgcG9pbnQgeVxuICAgICAgdGVtcFgsXG4gICAgICB0ZW1wWSxcbiAgICAgIHRlbXBDb250cm9sWCxcbiAgICAgIHRlbXBDb250cm9sWTtcblxuICBpZiAobCA9PSBudWxsKSBsID0gMDtcbiAgaWYgKHQgPT0gbnVsbCkgdCA9IDA7XG4gIGlmIChzID09IG51bGwpIHMgPSAxO1xuXG4gIGlmIChjb250ZXh0LmJlZ2luUGF0aCkgY29udGV4dC5iZWdpblBhdGgoKTtcblxuICBmb3IgKHZhciBpPTAsIGxlbj1wYXRoLmxlbmd0aDsgaTxsZW47ICsraSkge1xuICAgIGN1cnJlbnQgPSBwYXRoW2ldO1xuICAgIGlmIChzICE9PSAxKSBjdXJyZW50ID0gc2NhbGUoY3VycmVudCwgcyk7XG5cbiAgICBzd2l0Y2ggKGN1cnJlbnRbMF0pIHsgLy8gZmlyc3QgbGV0dGVyXG5cbiAgICAgIGNhc2UgJ2wnOiAvLyBsaW5ldG8sIHJlbGF0aXZlXG4gICAgICAgIHggKz0gY3VycmVudFsxXTtcbiAgICAgICAgeSArPSBjdXJyZW50WzJdO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyh4ICsgbCwgeSArIHQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnTCc6IC8vIGxpbmV0bywgYWJzb2x1dGVcbiAgICAgICAgeCA9IGN1cnJlbnRbMV07XG4gICAgICAgIHkgPSBjdXJyZW50WzJdO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyh4ICsgbCwgeSArIHQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnaCc6IC8vIGhvcml6b250YWwgbGluZXRvLCByZWxhdGl2ZVxuICAgICAgICB4ICs9IGN1cnJlbnRbMV07XG4gICAgICAgIGNvbnRleHQubGluZVRvKHggKyBsLCB5ICsgdCk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdIJzogLy8gaG9yaXpvbnRhbCBsaW5ldG8sIGFic29sdXRlXG4gICAgICAgIHggPSBjdXJyZW50WzFdO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyh4ICsgbCwgeSArIHQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAndic6IC8vIHZlcnRpY2FsIGxpbmV0bywgcmVsYXRpdmVcbiAgICAgICAgeSArPSBjdXJyZW50WzFdO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyh4ICsgbCwgeSArIHQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnVic6IC8vIHZlcmljYWwgbGluZXRvLCBhYnNvbHV0ZVxuICAgICAgICB5ID0gY3VycmVudFsxXTtcbiAgICAgICAgY29udGV4dC5saW5lVG8oeCArIGwsIHkgKyB0KTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ20nOiAvLyBtb3ZlVG8sIHJlbGF0aXZlXG4gICAgICAgIHggKz0gY3VycmVudFsxXTtcbiAgICAgICAgeSArPSBjdXJyZW50WzJdO1xuICAgICAgICBjb250ZXh0Lm1vdmVUbyh4ICsgbCwgeSArIHQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnTSc6IC8vIG1vdmVUbywgYWJzb2x1dGVcbiAgICAgICAgeCA9IGN1cnJlbnRbMV07XG4gICAgICAgIHkgPSBjdXJyZW50WzJdO1xuICAgICAgICBjb250ZXh0Lm1vdmVUbyh4ICsgbCwgeSArIHQpO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAnYyc6IC8vIGJlemllckN1cnZlVG8sIHJlbGF0aXZlXG4gICAgICAgIHRlbXBYID0geCArIGN1cnJlbnRbNV07XG4gICAgICAgIHRlbXBZID0geSArIGN1cnJlbnRbNl07XG4gICAgICAgIGNvbnRyb2xYID0geCArIGN1cnJlbnRbM107XG4gICAgICAgIGNvbnRyb2xZID0geSArIGN1cnJlbnRbNF07XG4gICAgICAgIGNvbnRleHQuYmV6aWVyQ3VydmVUbyhcbiAgICAgICAgICB4ICsgY3VycmVudFsxXSArIGwsIC8vIHgxXG4gICAgICAgICAgeSArIGN1cnJlbnRbMl0gKyB0LCAvLyB5MVxuICAgICAgICAgIGNvbnRyb2xYICsgbCwgLy8geDJcbiAgICAgICAgICBjb250cm9sWSArIHQsIC8vIHkyXG4gICAgICAgICAgdGVtcFggKyBsLFxuICAgICAgICAgIHRlbXBZICsgdFxuICAgICAgICApO1xuICAgICAgICB4ID0gdGVtcFg7XG4gICAgICAgIHkgPSB0ZW1wWTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ0MnOiAvLyBiZXppZXJDdXJ2ZVRvLCBhYnNvbHV0ZVxuICAgICAgICB4ID0gY3VycmVudFs1XTtcbiAgICAgICAgeSA9IGN1cnJlbnRbNl07XG4gICAgICAgIGNvbnRyb2xYID0gY3VycmVudFszXTtcbiAgICAgICAgY29udHJvbFkgPSBjdXJyZW50WzRdO1xuICAgICAgICBjb250ZXh0LmJlemllckN1cnZlVG8oXG4gICAgICAgICAgY3VycmVudFsxXSArIGwsXG4gICAgICAgICAgY3VycmVudFsyXSArIHQsXG4gICAgICAgICAgY29udHJvbFggKyBsLFxuICAgICAgICAgIGNvbnRyb2xZICsgdCxcbiAgICAgICAgICB4ICsgbCxcbiAgICAgICAgICB5ICsgdFxuICAgICAgICApO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAncyc6IC8vIHNob3J0aGFuZCBjdWJpYyBiZXppZXJDdXJ2ZVRvLCByZWxhdGl2ZVxuICAgICAgICAvLyB0cmFuc2Zvcm0gdG8gYWJzb2x1dGUgeCx5XG4gICAgICAgIHRlbXBYID0geCArIGN1cnJlbnRbM107XG4gICAgICAgIHRlbXBZID0geSArIGN1cnJlbnRbNF07XG4gICAgICAgIC8vIGNhbGN1bGF0ZSByZWZsZWN0aW9uIG9mIHByZXZpb3VzIGNvbnRyb2wgcG9pbnRzXG4gICAgICAgIGNvbnRyb2xYID0gMiAqIHggLSBjb250cm9sWDtcbiAgICAgICAgY29udHJvbFkgPSAyICogeSAtIGNvbnRyb2xZO1xuICAgICAgICBjb250ZXh0LmJlemllckN1cnZlVG8oXG4gICAgICAgICAgY29udHJvbFggKyBsLFxuICAgICAgICAgIGNvbnRyb2xZICsgdCxcbiAgICAgICAgICB4ICsgY3VycmVudFsxXSArIGwsXG4gICAgICAgICAgeSArIGN1cnJlbnRbMl0gKyB0LFxuICAgICAgICAgIHRlbXBYICsgbCxcbiAgICAgICAgICB0ZW1wWSArIHRcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBzZXQgY29udHJvbCBwb2ludCB0byAybmQgb25lIG9mIHRoaXMgY29tbWFuZFxuICAgICAgICAvLyB0aGUgZmlyc3QgY29udHJvbCBwb2ludCBpcyBhc3N1bWVkIHRvIGJlIHRoZSByZWZsZWN0aW9uIG9mXG4gICAgICAgIC8vIHRoZSBzZWNvbmQgY29udHJvbCBwb2ludCBvbiB0aGUgcHJldmlvdXMgY29tbWFuZCByZWxhdGl2ZVxuICAgICAgICAvLyB0byB0aGUgY3VycmVudCBwb2ludC5cbiAgICAgICAgY29udHJvbFggPSB4ICsgY3VycmVudFsxXTtcbiAgICAgICAgY29udHJvbFkgPSB5ICsgY3VycmVudFsyXTtcblxuICAgICAgICB4ID0gdGVtcFg7XG4gICAgICAgIHkgPSB0ZW1wWTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ1MnOiAvLyBzaG9ydGhhbmQgY3ViaWMgYmV6aWVyQ3VydmVUbywgYWJzb2x1dGVcbiAgICAgICAgdGVtcFggPSBjdXJyZW50WzNdO1xuICAgICAgICB0ZW1wWSA9IGN1cnJlbnRbNF07XG4gICAgICAgIC8vIGNhbGN1bGF0ZSByZWZsZWN0aW9uIG9mIHByZXZpb3VzIGNvbnRyb2wgcG9pbnRzXG4gICAgICAgIGNvbnRyb2xYID0gMip4IC0gY29udHJvbFg7XG4gICAgICAgIGNvbnRyb2xZID0gMip5IC0gY29udHJvbFk7XG4gICAgICAgIGNvbnRleHQuYmV6aWVyQ3VydmVUbyhcbiAgICAgICAgICBjb250cm9sWCArIGwsXG4gICAgICAgICAgY29udHJvbFkgKyB0LFxuICAgICAgICAgIGN1cnJlbnRbMV0gKyBsLFxuICAgICAgICAgIGN1cnJlbnRbMl0gKyB0LFxuICAgICAgICAgIHRlbXBYICsgbCxcbiAgICAgICAgICB0ZW1wWSArIHRcbiAgICAgICAgKTtcbiAgICAgICAgeCA9IHRlbXBYO1xuICAgICAgICB5ID0gdGVtcFk7XG4gICAgICAgIC8vIHNldCBjb250cm9sIHBvaW50IHRvIDJuZCBvbmUgb2YgdGhpcyBjb21tYW5kXG4gICAgICAgIC8vIHRoZSBmaXJzdCBjb250cm9sIHBvaW50IGlzIGFzc3VtZWQgdG8gYmUgdGhlIHJlZmxlY3Rpb24gb2ZcbiAgICAgICAgLy8gdGhlIHNlY29uZCBjb250cm9sIHBvaW50IG9uIHRoZSBwcmV2aW91cyBjb21tYW5kIHJlbGF0aXZlXG4gICAgICAgIC8vIHRvIHRoZSBjdXJyZW50IHBvaW50LlxuICAgICAgICBjb250cm9sWCA9IGN1cnJlbnRbMV07XG4gICAgICAgIGNvbnRyb2xZID0gY3VycmVudFsyXTtcblxuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAncSc6IC8vIHF1YWRyYXRpY0N1cnZlVG8sIHJlbGF0aXZlXG4gICAgICAgIC8vIHRyYW5zZm9ybSB0byBhYnNvbHV0ZSB4LHlcbiAgICAgICAgdGVtcFggPSB4ICsgY3VycmVudFszXTtcbiAgICAgICAgdGVtcFkgPSB5ICsgY3VycmVudFs0XTtcblxuICAgICAgICBjb250cm9sWCA9IHggKyBjdXJyZW50WzFdO1xuICAgICAgICBjb250cm9sWSA9IHkgKyBjdXJyZW50WzJdO1xuXG4gICAgICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbyhcbiAgICAgICAgICBjb250cm9sWCArIGwsXG4gICAgICAgICAgY29udHJvbFkgKyB0LFxuICAgICAgICAgIHRlbXBYICsgbCxcbiAgICAgICAgICB0ZW1wWSArIHRcbiAgICAgICAgKTtcbiAgICAgICAgeCA9IHRlbXBYO1xuICAgICAgICB5ID0gdGVtcFk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdRJzogLy8gcXVhZHJhdGljQ3VydmVUbywgYWJzb2x1dGVcbiAgICAgICAgdGVtcFggPSBjdXJyZW50WzNdO1xuICAgICAgICB0ZW1wWSA9IGN1cnJlbnRbNF07XG5cbiAgICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKFxuICAgICAgICAgIGN1cnJlbnRbMV0gKyBsLFxuICAgICAgICAgIGN1cnJlbnRbMl0gKyB0LFxuICAgICAgICAgIHRlbXBYICsgbCxcbiAgICAgICAgICB0ZW1wWSArIHRcbiAgICAgICAgKTtcbiAgICAgICAgeCA9IHRlbXBYO1xuICAgICAgICB5ID0gdGVtcFk7XG4gICAgICAgIGNvbnRyb2xYID0gY3VycmVudFsxXTtcbiAgICAgICAgY29udHJvbFkgPSBjdXJyZW50WzJdO1xuICAgICAgICBicmVhaztcblxuICAgICAgY2FzZSAndCc6IC8vIHNob3J0aGFuZCBxdWFkcmF0aWNDdXJ2ZVRvLCByZWxhdGl2ZVxuXG4gICAgICAgIC8vIHRyYW5zZm9ybSB0byBhYnNvbHV0ZSB4LHlcbiAgICAgICAgdGVtcFggPSB4ICsgY3VycmVudFsxXTtcbiAgICAgICAgdGVtcFkgPSB5ICsgY3VycmVudFsyXTtcblxuICAgICAgICBpZiAocHJldmlvdXNbMF0ubWF0Y2goL1tRcVR0XS8pID09PSBudWxsKSB7XG4gICAgICAgICAgLy8gSWYgdGhlcmUgaXMgbm8gcHJldmlvdXMgY29tbWFuZCBvciBpZiB0aGUgcHJldmlvdXMgY29tbWFuZCB3YXMgbm90IGEgUSwgcSwgVCBvciB0LFxuICAgICAgICAgIC8vIGFzc3VtZSB0aGUgY29udHJvbCBwb2ludCBpcyBjb2luY2lkZW50IHdpdGggdGhlIGN1cnJlbnQgcG9pbnRcbiAgICAgICAgICBjb250cm9sWCA9IHg7XG4gICAgICAgICAgY29udHJvbFkgPSB5O1xuICAgICAgICB9XG4gICAgICAgIGVsc2UgaWYgKHByZXZpb3VzWzBdID09PSAndCcpIHtcbiAgICAgICAgICAvLyBjYWxjdWxhdGUgcmVmbGVjdGlvbiBvZiBwcmV2aW91cyBjb250cm9sIHBvaW50cyBmb3IgdFxuICAgICAgICAgIGNvbnRyb2xYID0gMiAqIHggLSB0ZW1wQ29udHJvbFg7XG4gICAgICAgICAgY29udHJvbFkgPSAyICogeSAtIHRlbXBDb250cm9sWTtcbiAgICAgICAgfVxuICAgICAgICBlbHNlIGlmIChwcmV2aW91c1swXSA9PT0gJ3EnKSB7XG4gICAgICAgICAgLy8gY2FsY3VsYXRlIHJlZmxlY3Rpb24gb2YgcHJldmlvdXMgY29udHJvbCBwb2ludHMgZm9yIHFcbiAgICAgICAgICBjb250cm9sWCA9IDIgKiB4IC0gY29udHJvbFg7XG4gICAgICAgICAgY29udHJvbFkgPSAyICogeSAtIGNvbnRyb2xZO1xuICAgICAgICB9XG5cbiAgICAgICAgdGVtcENvbnRyb2xYID0gY29udHJvbFg7XG4gICAgICAgIHRlbXBDb250cm9sWSA9IGNvbnRyb2xZO1xuXG4gICAgICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbyhcbiAgICAgICAgICBjb250cm9sWCArIGwsXG4gICAgICAgICAgY29udHJvbFkgKyB0LFxuICAgICAgICAgIHRlbXBYICsgbCxcbiAgICAgICAgICB0ZW1wWSArIHRcbiAgICAgICAgKTtcbiAgICAgICAgeCA9IHRlbXBYO1xuICAgICAgICB5ID0gdGVtcFk7XG4gICAgICAgIGNvbnRyb2xYID0geCArIGN1cnJlbnRbMV07XG4gICAgICAgIGNvbnRyb2xZID0geSArIGN1cnJlbnRbMl07XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdUJzpcbiAgICAgICAgdGVtcFggPSBjdXJyZW50WzFdO1xuICAgICAgICB0ZW1wWSA9IGN1cnJlbnRbMl07XG5cbiAgICAgICAgLy8gY2FsY3VsYXRlIHJlZmxlY3Rpb24gb2YgcHJldmlvdXMgY29udHJvbCBwb2ludHNcbiAgICAgICAgY29udHJvbFggPSAyICogeCAtIGNvbnRyb2xYO1xuICAgICAgICBjb250cm9sWSA9IDIgKiB5IC0gY29udHJvbFk7XG4gICAgICAgIGNvbnRleHQucXVhZHJhdGljQ3VydmVUbyhcbiAgICAgICAgICBjb250cm9sWCArIGwsXG4gICAgICAgICAgY29udHJvbFkgKyB0LFxuICAgICAgICAgIHRlbXBYICsgbCxcbiAgICAgICAgICB0ZW1wWSArIHRcbiAgICAgICAgKTtcbiAgICAgICAgeCA9IHRlbXBYO1xuICAgICAgICB5ID0gdGVtcFk7XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdhJzpcbiAgICAgICAgZHJhd0FyYyhjb250ZXh0LCB4ICsgbCwgeSArIHQsIFtcbiAgICAgICAgICBjdXJyZW50WzFdLFxuICAgICAgICAgIGN1cnJlbnRbMl0sXG4gICAgICAgICAgY3VycmVudFszXSxcbiAgICAgICAgICBjdXJyZW50WzRdLFxuICAgICAgICAgIGN1cnJlbnRbNV0sXG4gICAgICAgICAgY3VycmVudFs2XSArIHggKyBsLFxuICAgICAgICAgIGN1cnJlbnRbN10gKyB5ICsgdFxuICAgICAgICBdKTtcbiAgICAgICAgeCArPSBjdXJyZW50WzZdO1xuICAgICAgICB5ICs9IGN1cnJlbnRbN107XG4gICAgICAgIGJyZWFrO1xuXG4gICAgICBjYXNlICdBJzpcbiAgICAgICAgZHJhd0FyYyhjb250ZXh0LCB4ICsgbCwgeSArIHQsIFtcbiAgICAgICAgICBjdXJyZW50WzFdLFxuICAgICAgICAgIGN1cnJlbnRbMl0sXG4gICAgICAgICAgY3VycmVudFszXSxcbiAgICAgICAgICBjdXJyZW50WzRdLFxuICAgICAgICAgIGN1cnJlbnRbNV0sXG4gICAgICAgICAgY3VycmVudFs2XSArIGwsXG4gICAgICAgICAgY3VycmVudFs3XSArIHRcbiAgICAgICAgXSk7XG4gICAgICAgIHggPSBjdXJyZW50WzZdO1xuICAgICAgICB5ID0gY3VycmVudFs3XTtcbiAgICAgICAgYnJlYWs7XG5cbiAgICAgIGNhc2UgJ3onOlxuICAgICAgY2FzZSAnWic6XG4gICAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBwcmV2aW91cyA9IGN1cnJlbnQ7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGRyYXdBcmMoY29udGV4dCwgeCwgeSwgY29vcmRzKSB7XG4gIHZhciBzZWcgPSBzZWdtZW50cyhcbiAgICBjb29yZHNbNV0sIC8vIGVuZCB4XG4gICAgY29vcmRzWzZdLCAvLyBlbmQgeVxuICAgIGNvb3Jkc1swXSwgLy8gcmFkaXVzIHhcbiAgICBjb29yZHNbMV0sIC8vIHJhZGl1cyB5XG4gICAgY29vcmRzWzNdLCAvLyBsYXJnZSBmbGFnXG4gICAgY29vcmRzWzRdLCAvLyBzd2VlcCBmbGFnXG4gICAgY29vcmRzWzJdLCAvLyByb3RhdGlvblxuICAgIHgsIHlcbiAgKTtcbiAgZm9yICh2YXIgaT0wOyBpPHNlZy5sZW5ndGg7ICsraSkge1xuICAgIHZhciBiZXogPSBiZXppZXIoc2VnW2ldKTtcbiAgICBjb250ZXh0LmJlemllckN1cnZlVG8oYmV6WzBdLCBiZXpbMV0sIGJlelsyXSwgYmV6WzNdLCBiZXpbNF0sIGJlels1XSk7XG4gIH1cbn1cblxudmFyIHRhdSQyID0gMiAqIE1hdGguUEk7XG52YXIgaGFsZlNxcnQzID0gTWF0aC5zcXJ0KDMpIC8gMjtcblxudmFyIGJ1aWx0aW5zID0ge1xuICAnY2lyY2xlJzoge1xuICAgIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUpIC8gMjtcbiAgICAgIGNvbnRleHQubW92ZVRvKHIsIDApO1xuICAgICAgY29udGV4dC5hcmMoMCwgMCwgciwgMCwgdGF1JDIpO1xuICAgIH1cbiAgfSxcbiAgJ2Nyb3NzJzoge1xuICAgIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUpIC8gMixcbiAgICAgICAgICBzID0gciAvIDIuNTtcbiAgICAgIGNvbnRleHQubW92ZVRvKC1yLCAtcyk7XG4gICAgICBjb250ZXh0LmxpbmVUbygtciwgcyk7XG4gICAgICBjb250ZXh0LmxpbmVUbygtcywgcyk7XG4gICAgICBjb250ZXh0LmxpbmVUbygtcywgcik7XG4gICAgICBjb250ZXh0LmxpbmVUbyhzLCByKTtcbiAgICAgIGNvbnRleHQubGluZVRvKHMsIHMpO1xuICAgICAgY29udGV4dC5saW5lVG8ociwgcyk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhyLCAtcyk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhzLCAtcyk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhzLCAtcik7XG4gICAgICBjb250ZXh0LmxpbmVUbygtcywgLXIpO1xuICAgICAgY29udGV4dC5saW5lVG8oLXMsIC1zKTtcbiAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfVxuICB9LFxuICAnZGlhbW9uZCc6IHtcbiAgICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgICB2YXIgciA9IE1hdGguc3FydChzaXplKSAvIDI7XG4gICAgICBjb250ZXh0Lm1vdmVUbygtciwgMCk7XG4gICAgICBjb250ZXh0LmxpbmVUbygwLCAtcik7XG4gICAgICBjb250ZXh0LmxpbmVUbyhyLCAwKTtcbiAgICAgIGNvbnRleHQubGluZVRvKDAsIHIpO1xuICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB9XG4gIH0sXG4gICdzcXVhcmUnOiB7XG4gICAgZHJhdzogZnVuY3Rpb24oY29udGV4dCwgc2l6ZSkge1xuICAgICAgdmFyIHcgPSBNYXRoLnNxcnQoc2l6ZSksXG4gICAgICAgICAgeCA9IC13IC8gMjtcbiAgICAgIGNvbnRleHQucmVjdCh4LCB4LCB3LCB3KTtcbiAgICB9XG4gIH0sXG4gICd0cmlhbmdsZS11cCc6IHtcbiAgICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgICB2YXIgciA9IE1hdGguc3FydChzaXplKSAvIDIsXG4gICAgICAgICAgaCA9IGhhbGZTcXJ0MyAqIHI7XG4gICAgICBjb250ZXh0Lm1vdmVUbygwLCAtaCk7XG4gICAgICBjb250ZXh0LmxpbmVUbygtciwgaCk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhyLCBoKTtcbiAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfVxuICB9LFxuICAndHJpYW5nbGUtZG93bic6IHtcbiAgICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgICB2YXIgciA9IE1hdGguc3FydChzaXplKSAvIDIsXG4gICAgICAgICAgaCA9IGhhbGZTcXJ0MyAqIHI7XG4gICAgICBjb250ZXh0Lm1vdmVUbygwLCBoKTtcbiAgICAgIGNvbnRleHQubGluZVRvKC1yLCAtaCk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhyLCAtaCk7XG4gICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIH1cbiAgfSxcbiAgJ3RyaWFuZ2xlLXJpZ2h0Jzoge1xuICAgIGRyYXc6IGZ1bmN0aW9uKGNvbnRleHQsIHNpemUpIHtcbiAgICAgIHZhciByID0gTWF0aC5zcXJ0KHNpemUpIC8gMixcbiAgICAgICAgICBoID0gaGFsZlNxcnQzICogcjtcbiAgICAgIGNvbnRleHQubW92ZVRvKGgsIDApO1xuICAgICAgY29udGV4dC5saW5lVG8oLWgsIC1yKTtcbiAgICAgIGNvbnRleHQubGluZVRvKC1oLCByKTtcbiAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfVxuICB9LFxuICAndHJpYW5nbGUtbGVmdCc6IHtcbiAgICBkcmF3OiBmdW5jdGlvbihjb250ZXh0LCBzaXplKSB7XG4gICAgICB2YXIgciA9IE1hdGguc3FydChzaXplKSAvIDIsXG4gICAgICAgICAgaCA9IGhhbGZTcXJ0MyAqIHI7XG4gICAgICBjb250ZXh0Lm1vdmVUbygtaCwgMCk7XG4gICAgICBjb250ZXh0LmxpbmVUbyhoLCAtcik7XG4gICAgICBjb250ZXh0LmxpbmVUbyhoLCByKTtcbiAgICAgIGNvbnRleHQuY2xvc2VQYXRoKCk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBzeW1ib2xzJDEoXykge1xuICByZXR1cm4gYnVpbHRpbnMuaGFzT3duUHJvcGVydHkoXykgPyBidWlsdGluc1tfXSA6IGN1c3RvbVN5bWJvbChfKTtcbn1cblxudmFyIGN1c3RvbSA9IHt9O1xuXG5mdW5jdGlvbiBjdXN0b21TeW1ib2wocGF0aCkge1xuICBpZiAoIWN1c3RvbS5oYXNPd25Qcm9wZXJ0eShwYXRoKSkge1xuICAgIHZhciBwYXJzZWQgPSBwYXRoUGFyc2UocGF0aCk7XG4gICAgY3VzdG9tW3BhdGhdID0ge1xuICAgICAgZHJhdzogZnVuY3Rpb24oY29udGV4dCwgc2l6ZSkge1xuICAgICAgICBwYXRoUmVuZGVyKGNvbnRleHQsIHBhcnNlZCwgMCwgMCwgTWF0aC5zcXJ0KHNpemUpIC8gMik7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuICByZXR1cm4gY3VzdG9tW3BhdGhdO1xufVxuXG5mdW5jdGlvbiByZWN0YW5nbGVYKGQpIHtcbiAgcmV0dXJuIGQueDtcbn1cblxuZnVuY3Rpb24gcmVjdGFuZ2xlWShkKSB7XG4gIHJldHVybiBkLnk7XG59XG5cbmZ1bmN0aW9uIHJlY3RhbmdsZVdpZHRoKGQpIHtcbiAgcmV0dXJuIGQud2lkdGg7XG59XG5cbmZ1bmN0aW9uIHJlY3RhbmdsZUhlaWdodChkKSB7XG4gIHJldHVybiBkLmhlaWdodDtcbn1cblxuZnVuY3Rpb24gY29uc3RhbnQkMyhfKSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHsgcmV0dXJuIF87IH07XG59XG5cbnZhciB2Z19yZWN0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciB4ID0gcmVjdGFuZ2xlWCxcbiAgICAgIHkgPSByZWN0YW5nbGVZLFxuICAgICAgd2lkdGggPSByZWN0YW5nbGVXaWR0aCxcbiAgICAgIGhlaWdodCA9IHJlY3RhbmdsZUhlaWdodCxcbiAgICAgIGNvcm5lclJhZGl1cyA9IGNvbnN0YW50JDMoMCksXG4gICAgICBjb250ZXh0ID0gbnVsbDtcblxuICBmdW5jdGlvbiByZWN0YW5nbGUoXywgeDAsIHkwKSB7XG4gICAgdmFyIGJ1ZmZlcixcbiAgICAgICAgeDEgPSB4MCAhPSBudWxsID8geDAgOiAreC5jYWxsKHRoaXMsIF8pLFxuICAgICAgICB5MSA9IHkwICE9IG51bGwgPyB5MCA6ICt5LmNhbGwodGhpcywgXyksXG4gICAgICAgIHcgID0gK3dpZHRoLmNhbGwodGhpcywgXyksXG4gICAgICAgIGggID0gK2hlaWdodC5jYWxsKHRoaXMsIF8pLFxuICAgICAgICBjciA9ICtjb3JuZXJSYWRpdXMuY2FsbCh0aGlzLCBfKTtcblxuICAgIGlmICghY29udGV4dCkgY29udGV4dCA9IGJ1ZmZlciA9IHBhdGgoKTtcblxuICAgIGlmIChjciA8PSAwKSB7XG4gICAgICBjb250ZXh0LnJlY3QoeDEsIHkxLCB3LCBoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFyIHgyID0geDEgKyB3LFxuICAgICAgICAgIHkyID0geTEgKyBoO1xuICAgICAgY29udGV4dC5tb3ZlVG8oeDEgKyBjciwgeTEpO1xuICAgICAgY29udGV4dC5saW5lVG8oeDIgLSBjciwgeTEpO1xuICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKHgyLCB5MSwgeDIsIHkxICsgY3IpO1xuICAgICAgY29udGV4dC5saW5lVG8oeDIsIHkyIC0gY3IpO1xuICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKHgyLCB5MiwgeDIgLSBjciwgeTIpO1xuICAgICAgY29udGV4dC5saW5lVG8oeDEgKyBjciwgeTIpO1xuICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKHgxLCB5MiwgeDEsIHkyIC0gY3IpO1xuICAgICAgY29udGV4dC5saW5lVG8oeDEsIHkxICsgY3IpO1xuICAgICAgY29udGV4dC5xdWFkcmF0aWNDdXJ2ZVRvKHgxLCB5MSwgeDEgKyBjciwgeTEpO1xuICAgICAgY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB9XG5cbiAgICBpZiAoYnVmZmVyKSB7XG4gICAgICBjb250ZXh0ID0gbnVsbDtcbiAgICAgIHJldHVybiBidWZmZXIgKyAnJyB8fCBudWxsO1xuICAgIH1cbiAgfVxuXG4gIHJlY3RhbmdsZS54ID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB4ID0gdHlwZW9mIF8gPT09ICdmdW5jdGlvbicgPyBfIDogY29uc3RhbnQkMygrXyk7XG4gICAgICByZXR1cm4gcmVjdGFuZ2xlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4geDtcbiAgICB9XG4gIH07XG5cbiAgcmVjdGFuZ2xlLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHkgPSB0eXBlb2YgXyA9PT0gJ2Z1bmN0aW9uJyA/IF8gOiBjb25zdGFudCQzKCtfKTtcbiAgICAgIHJldHVybiByZWN0YW5nbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiB5O1xuICAgIH1cbiAgfTtcblxuICByZWN0YW5nbGUud2lkdGggPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHdpZHRoID0gdHlwZW9mIF8gPT09ICdmdW5jdGlvbicgPyBfIDogY29uc3RhbnQkMygrXyk7XG4gICAgICByZXR1cm4gcmVjdGFuZ2xlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gd2lkdGg7XG4gICAgfVxuICB9O1xuXG4gIHJlY3RhbmdsZS5oZWlnaHQgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGhlaWdodCA9IHR5cGVvZiBfID09PSAnZnVuY3Rpb24nID8gXyA6IGNvbnN0YW50JDMoK18pO1xuICAgICAgcmV0dXJuIHJlY3RhbmdsZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGhlaWdodDtcbiAgICB9XG4gIH07XG5cbiAgcmVjdGFuZ2xlLmNvcm5lclJhZGl1cyA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29ybmVyUmFkaXVzID0gdHlwZW9mIF8gPT09ICdmdW5jdGlvbicgPyBfIDogY29uc3RhbnQkMygrXyk7XG4gICAgICByZXR1cm4gcmVjdGFuZ2xlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gY29ybmVyUmFkaXVzO1xuICAgIH1cbiAgfTtcblxuICByZWN0YW5nbGUuY29udGV4dCA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY29udGV4dCA9IF8gPT0gbnVsbCA/IG51bGwgOiBfO1xuICAgICAgcmV0dXJuIHJlY3RhbmdsZTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiByZWN0YW5nbGU7XG59O1xuXG52YXIgcGkkMiA9IE1hdGguUEk7XG5cbnZhciB2Z190cmFpbCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgeCxcbiAgICAgIHksXG4gICAgICBzaXplLFxuICAgICAgZGVmaW5lZCxcbiAgICAgIGNvbnRleHQgPSBudWxsLFxuICAgICAgcmVhZHksIHgxLCB5MSwgcjE7XG5cbiAgZnVuY3Rpb24gcG9pbnQoeDIsIHkyLCB3Mikge1xuICAgIHZhciByMiA9IHcyIC8gMjtcblxuICAgIGlmIChyZWFkeSkge1xuICAgICAgdmFyIHV4ID0geTEgLSB5MixcbiAgICAgICAgICB1eSA9IHgyIC0geDE7XG5cbiAgICAgIGlmICh1eCB8fCB1eSkge1xuICAgICAgICAvLyBnZXQgbm9ybWFsIHZlY3RvclxuICAgICAgICB2YXIgdWQgPSBNYXRoLnNxcnQodXggKiB1eCArIHV5ICogdXkpLFxuICAgICAgICAgICAgcnggPSAodXggLz0gdWQpICogcjEsXG4gICAgICAgICAgICByeSA9ICh1eSAvPSB1ZCkgKiByMSxcbiAgICAgICAgICAgIHQgPSBNYXRoLmF0YW4yKHV5LCB1eCk7XG5cbiAgICAgICAgLy8gZHJhdyBzZWdtZW50XG4gICAgICAgIGNvbnRleHQubW92ZVRvKHgxIC0gcngsIHkxIC0gcnkpO1xuICAgICAgICBjb250ZXh0LmxpbmVUbyh4MiAtIHV4ICogcjIsIHkyIC0gdXkgKiByMik7XG4gICAgICAgIGNvbnRleHQuYXJjKHgyLCB5MiwgcjIsIHQgLSBwaSQyLCB0KTtcbiAgICAgICAgY29udGV4dC5saW5lVG8oeDEgKyByeCwgeTEgKyByeSk7XG4gICAgICAgIGNvbnRleHQuYXJjKHgxLCB5MSwgcjEsIHQsIHQgKyBwaSQyKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGNvbnRleHQuYXJjKHgyLCB5MiwgcjIsIDAsIDIqcGkkMik7XG4gICAgICB9XG4gICAgICBjb250ZXh0LmNsb3NlUGF0aCgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZWFkeSA9IDE7XG4gICAgfVxuICAgIHgxID0geDI7XG4gICAgeTEgPSB5MjtcbiAgICByMSA9IHIyO1xuICB9XG5cbiAgZnVuY3Rpb24gdHJhaWwoZGF0YSkge1xuICAgIHZhciBpLFxuICAgICAgICBuID0gZGF0YS5sZW5ndGgsXG4gICAgICAgIGQsXG4gICAgICAgIGRlZmluZWQwID0gZmFsc2UsXG4gICAgICAgIGJ1ZmZlcjtcblxuICAgIGlmIChjb250ZXh0ID09IG51bGwpIGNvbnRleHQgPSBidWZmZXIgPSBwYXRoKCk7XG5cbiAgICBmb3IgKGkgPSAwOyBpIDw9IG47ICsraSkge1xuICAgICAgaWYgKCEoaSA8IG4gJiYgZGVmaW5lZChkID0gZGF0YVtpXSwgaSwgZGF0YSkpID09PSBkZWZpbmVkMCkge1xuICAgICAgICBpZiAoZGVmaW5lZDAgPSAhZGVmaW5lZDApIHJlYWR5ID0gMDtcbiAgICAgIH1cbiAgICAgIGlmIChkZWZpbmVkMCkgcG9pbnQoK3goZCwgaSwgZGF0YSksICt5KGQsIGksIGRhdGEpLCArc2l6ZShkLCBpLCBkYXRhKSk7XG4gICAgfVxuXG4gICAgaWYgKGJ1ZmZlcikge1xuICAgICAgY29udGV4dCA9IG51bGw7XG4gICAgICByZXR1cm4gYnVmZmVyICsgJycgfHwgbnVsbDtcbiAgICB9XG4gIH1cblxuICB0cmFpbC54ID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICB4ID0gXztcbiAgICAgIHJldHVybiB0cmFpbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHg7XG4gICAgfVxuICB9O1xuXG4gIHRyYWlsLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHkgPSBfO1xuICAgICAgcmV0dXJuIHRyYWlsO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4geTtcbiAgICB9XG4gIH07XG5cbiAgdHJhaWwuc2l6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgc2l6ZSA9IF87XG4gICAgICByZXR1cm4gdHJhaWw7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzaXplO1xuICAgIH1cbiAgfTtcblxuICB0cmFpbC5kZWZpbmVkID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBkZWZpbmVkID0gXztcbiAgICAgIHJldHVybiB0cmFpbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGRlZmluZWQ7XG4gICAgfVxuICB9O1xuXG4gIHRyYWlsLmNvbnRleHQgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIGlmIChfID09IG51bGwpIHtcbiAgICAgICAgY29udGV4dCA9IG51bGw7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBjb250ZXh0ID0gXztcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmFpbDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGNvbnRleHQ7XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiB0cmFpbDtcbn07XG5cbmZ1bmN0aW9uIHgoaXRlbSkgICAgeyByZXR1cm4gaXRlbS54IHx8IDA7IH1cbmZ1bmN0aW9uIHkoaXRlbSkgICAgeyByZXR1cm4gaXRlbS55IHx8IDA7IH1cbmZ1bmN0aW9uIHcoaXRlbSkgICAgeyByZXR1cm4gaXRlbS53aWR0aCB8fCAwOyB9XG5mdW5jdGlvbiB0cyhpdGVtKSAgIHsgcmV0dXJuIGl0ZW0uc2l6ZSB8fCAxOyB9XG5mdW5jdGlvbiBoKGl0ZW0pICAgIHsgcmV0dXJuIGl0ZW0uaGVpZ2h0IHx8IDA7IH1cbmZ1bmN0aW9uIHh3KGl0ZW0pICAgeyByZXR1cm4gKGl0ZW0ueCB8fCAwKSArIChpdGVtLndpZHRoIHx8IDApOyB9XG5mdW5jdGlvbiB5aChpdGVtKSAgIHsgcmV0dXJuIChpdGVtLnkgfHwgMCkgKyAoaXRlbS5oZWlnaHQgfHwgMCk7IH1cbmZ1bmN0aW9uIHNhKGl0ZW0pICAgeyByZXR1cm4gaXRlbS5zdGFydEFuZ2xlIHx8IDA7IH1cbmZ1bmN0aW9uIGVhKGl0ZW0pICAgeyByZXR1cm4gaXRlbS5lbmRBbmdsZSB8fCAwOyB9XG5mdW5jdGlvbiBwYShpdGVtKSAgIHsgcmV0dXJuIGl0ZW0ucGFkQW5nbGUgfHwgMDsgfVxuZnVuY3Rpb24gaXIoaXRlbSkgICB7IHJldHVybiBpdGVtLmlubmVyUmFkaXVzIHx8IDA7IH1cbmZ1bmN0aW9uIG9yKGl0ZW0pICAgeyByZXR1cm4gaXRlbS5vdXRlclJhZGl1cyB8fCAwOyB9XG5mdW5jdGlvbiBjcihpdGVtKSAgIHsgcmV0dXJuIGl0ZW0uY29ybmVyUmFkaXVzIHx8IDA7IH1cbmZ1bmN0aW9uIGRlZihpdGVtKSAgeyByZXR1cm4gIShpdGVtLmRlZmluZWQgPT09IGZhbHNlKTsgfVxuZnVuY3Rpb24gc2l6ZShpdGVtKSB7IHJldHVybiBpdGVtLnNpemUgPT0gbnVsbCA/IDY0IDogaXRlbS5zaXplOyB9XG5mdW5jdGlvbiB0eXBlJDEoaXRlbSkgeyByZXR1cm4gc3ltYm9scyQxKGl0ZW0uc2hhcGUgfHwgJ2NpcmNsZScpOyB9XG5cbnZhciBhcmNTaGFwZSAgICA9IGQzX2FyYygpLnN0YXJ0QW5nbGUoc2EpLmVuZEFuZ2xlKGVhKS5wYWRBbmdsZShwYSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLmlubmVyUmFkaXVzKGlyKS5vdXRlclJhZGl1cyhvcikuY29ybmVyUmFkaXVzKGNyKTtcbnZhciBhcmVhdlNoYXBlICA9IGFyZWEkMSgpLngoeCkueTEoeSkueTAoeWgpLmRlZmluZWQoZGVmKTtcbnZhciBhcmVhaFNoYXBlICA9IGFyZWEkMSgpLnkoeSkueDEoeCkueDAoeHcpLmRlZmluZWQoZGVmKTtcbnZhciBsaW5lU2hhcGUgICA9IGxpbmUkMSgpLngoeCkueSh5KS5kZWZpbmVkKGRlZik7XG52YXIgcmVjdFNoYXBlICAgPSB2Z19yZWN0KCkueCh4KS55KHkpLndpZHRoKHcpLmhlaWdodChoKS5jb3JuZXJSYWRpdXMoY3IpO1xudmFyIHN5bWJvbFNoYXBlID0gZDNfc3ltYm9sKCkudHlwZSh0eXBlJDEpLnNpemUoc2l6ZSk7XG52YXIgdHJhaWxTaGFwZSAgPSB2Z190cmFpbCgpLngoeCkueSh5KS5kZWZpbmVkKGRlZikuc2l6ZSh0cyk7XG5cbmZ1bmN0aW9uIGFyYyQxKGNvbnRleHQsIGl0ZW0pIHtcbiAgcmV0dXJuIGFyY1NoYXBlLmNvbnRleHQoY29udGV4dCkoaXRlbSk7XG59XG5cbmZ1bmN0aW9uIGFyZWEoY29udGV4dCwgaXRlbXMpIHtcbiAgdmFyIGl0ZW0gPSBpdGVtc1swXSxcbiAgICAgIGludGVycCA9IGl0ZW0uaW50ZXJwb2xhdGUgfHwgJ2xpbmVhcic7XG4gIHJldHVybiAoaXRlbS5vcmllbnQgPT09ICdob3Jpem9udGFsJyA/IGFyZWFoU2hhcGUgOiBhcmVhdlNoYXBlKVxuICAgIC5jdXJ2ZShjdXJ2ZXMoaW50ZXJwLCBpdGVtLm9yaWVudCwgaXRlbS50ZW5zaW9uKSlcbiAgICAuY29udGV4dChjb250ZXh0KShpdGVtcyk7XG59XG5cbmZ1bmN0aW9uIGxpbmUoY29udGV4dCwgaXRlbXMpIHtcbiAgdmFyIGl0ZW0gPSBpdGVtc1swXSxcbiAgICAgIGludGVycCA9IGl0ZW0uaW50ZXJwb2xhdGUgfHwgJ2xpbmVhcic7XG4gIHJldHVybiBsaW5lU2hhcGUuY3VydmUoY3VydmVzKGludGVycCwgaXRlbS5vcmllbnQsIGl0ZW0udGVuc2lvbikpXG4gICAgLmNvbnRleHQoY29udGV4dCkoaXRlbXMpO1xufVxuXG5mdW5jdGlvbiByZWN0YW5nbGUoY29udGV4dCwgaXRlbSwgeCwgeSkge1xuICByZXR1cm4gcmVjdFNoYXBlLmNvbnRleHQoY29udGV4dCkoaXRlbSwgeCwgeSk7XG59XG5cbmZ1bmN0aW9uIHNoYXBlKGNvbnRleHQsIGl0ZW0pIHtcbiAgcmV0dXJuIChpdGVtLm1hcmsuc2hhcGUgfHwgaXRlbS5zaGFwZSlcbiAgICAuY29udGV4dChjb250ZXh0KShpdGVtKTtcbn1cblxuZnVuY3Rpb24gc3ltYm9sKGNvbnRleHQsIGl0ZW0pIHtcbiAgcmV0dXJuIHN5bWJvbFNoYXBlLmNvbnRleHQoY29udGV4dCkoaXRlbSk7XG59XG5cbmZ1bmN0aW9uIHRyYWlsKGNvbnRleHQsIGl0ZW1zKSB7XG4gIHJldHVybiB0cmFpbFNoYXBlLmNvbnRleHQoY29udGV4dCkoaXRlbXMpO1xufVxuXG52YXIgYm91bmRTdHJva2UgPSBmdW5jdGlvbihib3VuZHMsIGl0ZW0pIHtcbiAgaWYgKGl0ZW0uc3Ryb2tlICYmIGl0ZW0ub3BhY2l0eSAhPT0gMCAmJiBpdGVtLnN0cm9rZU9wYWNpdHkgIT09IDApIHtcbiAgICBib3VuZHMuZXhwYW5kKGl0ZW0uc3Ryb2tlV2lkdGggIT0gbnVsbCA/ICtpdGVtLnN0cm9rZVdpZHRoIDogMSk7XG4gIH1cbiAgcmV0dXJuIGJvdW5kcztcbn07XG5cbnZhciBib3VuZHM7XG52YXIgdGF1JDMgPSBNYXRoLlBJICogMjtcbnZhciBoYWxmUGkkMSA9IHRhdSQzIC8gNDtcbnZhciBjaXJjbGVUaHJlc2hvbGQgPSB0YXUkMyAtIDFlLTg7XG5cbmZ1bmN0aW9uIGNvbnRleHQoXykge1xuICBib3VuZHMgPSBfO1xuICByZXR1cm4gY29udGV4dDtcbn1cblxuZnVuY3Rpb24gbm9vcCQyKCkge31cblxuZnVuY3Rpb24gYWRkJDEoeCwgeSkgeyBib3VuZHMuYWRkKHgsIHkpOyB9XG5cbmNvbnRleHQuYmVnaW5QYXRoID0gbm9vcCQyO1xuXG5jb250ZXh0LmNsb3NlUGF0aCA9IG5vb3AkMjtcblxuY29udGV4dC5tb3ZlVG8gPSBhZGQkMTtcblxuY29udGV4dC5saW5lVG8gPSBhZGQkMTtcblxuY29udGV4dC5yZWN0ID0gZnVuY3Rpb24oeCwgeSwgdywgaCkge1xuICBhZGQkMSh4LCB5KTtcbiAgYWRkJDEoeCArIHcsIHkgKyBoKTtcbn07XG5cbmNvbnRleHQucXVhZHJhdGljQ3VydmVUbyA9IGZ1bmN0aW9uKHgxLCB5MSwgeDIsIHkyKSB7XG4gIGFkZCQxKHgxLCB5MSk7XG4gIGFkZCQxKHgyLCB5Mik7XG59O1xuXG5jb250ZXh0LmJlemllckN1cnZlVG8gPSBmdW5jdGlvbih4MSwgeTEsIHgyLCB5MiwgeDMsIHkzKSB7XG4gIGFkZCQxKHgxLCB5MSk7XG4gIGFkZCQxKHgyLCB5Mik7XG4gIGFkZCQxKHgzLCB5Myk7XG59O1xuXG5jb250ZXh0LmFyYyA9IGZ1bmN0aW9uKGN4LCBjeSwgciwgc2EsIGVhLCBjY3cpIHtcbiAgaWYgKE1hdGguYWJzKGVhIC0gc2EpID4gY2lyY2xlVGhyZXNob2xkKSB7XG4gICAgYWRkJDEoY3ggLSByLCBjeSAtIHIpO1xuICAgIGFkZCQxKGN4ICsgciwgY3kgKyByKTtcbiAgICByZXR1cm47XG4gIH1cblxuICB2YXIgeG1pbiA9IEluZmluaXR5LCB4bWF4ID0gLUluZmluaXR5LFxuICAgICAgeW1pbiA9IEluZmluaXR5LCB5bWF4ID0gLUluZmluaXR5LFxuICAgICAgcywgaSwgeCwgeTtcblxuICBmdW5jdGlvbiB1cGRhdGUoYSkge1xuICAgIHggPSByICogTWF0aC5jb3MoYSk7XG4gICAgeSA9IHIgKiBNYXRoLnNpbihhKTtcbiAgICBpZiAoeCA8IHhtaW4pIHhtaW4gPSB4O1xuICAgIGlmICh4ID4geG1heCkgeG1heCA9IHg7XG4gICAgaWYgKHkgPCB5bWluKSB5bWluID0geTtcbiAgICBpZiAoeSA+IHltYXgpIHltYXggPSB5O1xuICB9XG5cbiAgLy8gU2FtcGxlIGVuZCBwb2ludHMgYW5kIGludGVyaW9yIHBvaW50cyBhbGlnbmVkIHdpdGggOTAgZGVncmVlc1xuICB1cGRhdGUoc2EpO1xuICB1cGRhdGUoZWEpO1xuXG4gIGlmIChlYSAhPT0gc2EpIHtcbiAgICBzYSA9IHNhICUgdGF1JDM7IGlmIChzYSA8IDApIHNhICs9IHRhdSQzO1xuICAgIGVhID0gZWEgJSB0YXUkMzsgaWYgKGVhIDwgMCkgZWEgKz0gdGF1JDM7XG5cbiAgICBpZiAoZWEgPCBzYSkge1xuICAgICAgY2N3ID0gIWNjdzsgLy8gZmxpcCBkaXJlY3Rpb25cbiAgICAgIHMgPSBzYTsgc2EgPSBlYTsgZWEgPSBzOyAvLyBzd2FwIGVuZC1wb2ludHNcbiAgICB9XG5cbiAgICBpZiAoY2N3KSB7XG4gICAgICBlYSAtPSB0YXUkMztcbiAgICAgIHMgPSBzYSAtIChzYSAlIGhhbGZQaSQxKTtcbiAgICAgIGZvciAoaT0wOyBpPDQgJiYgcz5lYTsgKytpLCBzLT1oYWxmUGkkMSkgdXBkYXRlKHMpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzID0gc2EgLSAoc2EgJSBoYWxmUGkkMSkgKyBoYWxmUGkkMTtcbiAgICAgIGZvciAoaT0wOyBpPDQgJiYgczxlYTsgKytpLCBzPXMraGFsZlBpJDEpIHVwZGF0ZShzKTtcbiAgICB9XG4gIH1cblxuICBhZGQkMShjeCArIHhtaW4sIGN5ICsgeW1pbik7XG4gIGFkZCQxKGN4ICsgeG1heCwgY3kgKyB5bWF4KTtcbn07XG5cbnZhciBncmFkaWVudCA9IGZ1bmN0aW9uKGNvbnRleHQsIGdyYWRpZW50LCBib3VuZHMpIHtcbiAgdmFyIHcgPSBib3VuZHMud2lkdGgoKSxcbiAgICAgIGggPSBib3VuZHMuaGVpZ2h0KCksXG4gICAgICB4MSA9IGJvdW5kcy54MSArIGdyYWRpZW50LngxICogdyxcbiAgICAgIHkxID0gYm91bmRzLnkxICsgZ3JhZGllbnQueTEgKiBoLFxuICAgICAgeDIgPSBib3VuZHMueDEgKyBncmFkaWVudC54MiAqIHcsXG4gICAgICB5MiA9IGJvdW5kcy55MSArIGdyYWRpZW50LnkyICogaCxcbiAgICAgIHN0b3AgPSBncmFkaWVudC5zdG9wcyxcbiAgICAgIGkgPSAwLFxuICAgICAgbiA9IHN0b3AubGVuZ3RoLFxuICAgICAgbGluZWFyR3JhZGllbnQgPSBjb250ZXh0LmNyZWF0ZUxpbmVhckdyYWRpZW50KHgxLCB5MSwgeDIsIHkyKTtcblxuICBmb3IgKDsgaTxuOyArK2kpIHtcbiAgICBsaW5lYXJHcmFkaWVudC5hZGRDb2xvclN0b3Aoc3RvcFtpXS5vZmZzZXQsIHN0b3BbaV0uY29sb3IpO1xuICB9XG5cbiAgcmV0dXJuIGxpbmVhckdyYWRpZW50O1xufTtcblxudmFyIGNvbG9yID0gZnVuY3Rpb24oY29udGV4dCwgaXRlbSwgdmFsdWUpIHtcbiAgcmV0dXJuICh2YWx1ZS5pZCkgP1xuICAgIGdyYWRpZW50KGNvbnRleHQsIHZhbHVlLCBpdGVtLmJvdW5kcykgOlxuICAgIHZhbHVlO1xufTtcblxudmFyIGZpbGwgPSBmdW5jdGlvbihjb250ZXh0LCBpdGVtLCBvcGFjaXR5KSB7XG4gIG9wYWNpdHkgKj0gKGl0ZW0uZmlsbE9wYWNpdHk9PW51bGwgPyAxIDogaXRlbS5maWxsT3BhY2l0eSk7XG4gIGlmIChvcGFjaXR5ID4gMCkge1xuICAgIGNvbnRleHQuZ2xvYmFsQWxwaGEgPSBvcGFjaXR5O1xuICAgIGNvbnRleHQuZmlsbFN0eWxlID0gY29sb3IoY29udGV4dCwgaXRlbSwgaXRlbS5maWxsKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZmFsc2U7XG4gIH1cbn07XG5cbnZhciBFbXB0eSQxID0gW107XG5cbnZhciBzdHJva2UgPSBmdW5jdGlvbihjb250ZXh0LCBpdGVtLCBvcGFjaXR5KSB7XG4gIHZhciBsdyA9IChsdyA9IGl0ZW0uc3Ryb2tlV2lkdGgpICE9IG51bGwgPyBsdyA6IDE7XG5cbiAgaWYgKGx3IDw9IDApIHJldHVybiBmYWxzZTtcblxuICBvcGFjaXR5ICo9IChpdGVtLnN0cm9rZU9wYWNpdHk9PW51bGwgPyAxIDogaXRlbS5zdHJva2VPcGFjaXR5KTtcbiAgaWYgKG9wYWNpdHkgPiAwKSB7XG4gICAgY29udGV4dC5nbG9iYWxBbHBoYSA9IG9wYWNpdHk7XG4gICAgY29udGV4dC5zdHJva2VTdHlsZSA9IGNvbG9yKGNvbnRleHQsIGl0ZW0sIGl0ZW0uc3Ryb2tlKTtcblxuICAgIGNvbnRleHQubGluZVdpZHRoID0gbHc7XG4gICAgY29udGV4dC5saW5lQ2FwID0gaXRlbS5zdHJva2VDYXAgfHwgJ2J1dHQnO1xuICAgIGNvbnRleHQubGluZUpvaW4gPSBpdGVtLnN0cm9rZUpvaW4gfHwgJ21pdGVyJztcbiAgICBjb250ZXh0Lm1pdGVyTGltaXQgPSBpdGVtLnN0cm9rZU1pdGVyTGltaXQgfHwgMTA7XG5cbiAgICBpZiAoY29udGV4dC5zZXRMaW5lRGFzaCkge1xuICAgICAgY29udGV4dC5zZXRMaW5lRGFzaChpdGVtLnN0cm9rZURhc2ggfHwgRW1wdHkkMSk7XG4gICAgICBjb250ZXh0LmxpbmVEYXNoT2Zmc2V0ID0gaXRlbS5zdHJva2VEYXNoT2Zmc2V0IHx8IDA7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBmYWxzZTtcbiAgfVxufTtcblxuZnVuY3Rpb24gY29tcGFyZSQxKGEsIGIpIHtcbiAgcmV0dXJuIGEuemluZGV4IC0gYi56aW5kZXggfHwgYS5pbmRleCAtIGIuaW5kZXg7XG59XG5cbmZ1bmN0aW9uIHpvcmRlcihzY2VuZSkge1xuICBpZiAoIXNjZW5lLnpkaXJ0eSkgcmV0dXJuIHNjZW5lLnppdGVtcztcblxuICB2YXIgaXRlbXMgPSBzY2VuZS5pdGVtcyxcbiAgICAgIG91dHB1dCA9IFtdLCBpdGVtLCBpLCBuO1xuXG4gIGZvciAoaT0wLCBuPWl0ZW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBpdGVtID0gaXRlbXNbaV07XG4gICAgaXRlbS5pbmRleCA9IGk7XG4gICAgaWYgKGl0ZW0uemluZGV4KSBvdXRwdXQucHVzaChpdGVtKTtcbiAgfVxuXG4gIHNjZW5lLnpkaXJ0eSA9IGZhbHNlO1xuICByZXR1cm4gc2NlbmUueml0ZW1zID0gb3V0cHV0LnNvcnQoY29tcGFyZSQxKTtcbn1cblxuZnVuY3Rpb24gdmlzaXQoc2NlbmUsIHZpc2l0b3IpIHtcbiAgdmFyIGl0ZW1zID0gc2NlbmUuaXRlbXMsIGksIG47XG4gIGlmICghaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkgcmV0dXJuO1xuXG4gIHZhciB6aXRlbXMgPSB6b3JkZXIoc2NlbmUpO1xuXG4gIGlmICh6aXRlbXMgJiYgeml0ZW1zLmxlbmd0aCkge1xuICAgIGZvciAoaT0wLCBuPWl0ZW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIGlmICghaXRlbXNbaV0uemluZGV4KSB2aXNpdG9yKGl0ZW1zW2ldKTtcbiAgICB9XG4gICAgaXRlbXMgPSB6aXRlbXM7XG4gIH1cblxuICBmb3IgKGk9MCwgbj1pdGVtcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdmlzaXRvcihpdGVtc1tpXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGlja1Zpc2l0KHNjZW5lLCB2aXNpdG9yKSB7XG4gIHZhciBpdGVtcyA9IHNjZW5lLml0ZW1zLCBoaXQsIGk7XG4gIGlmICghaXRlbXMgfHwgIWl0ZW1zLmxlbmd0aCkgcmV0dXJuIG51bGw7XG5cbiAgdmFyIHppdGVtcyA9IHpvcmRlcihzY2VuZSk7XG4gIGlmICh6aXRlbXMgJiYgeml0ZW1zLmxlbmd0aCkgaXRlbXMgPSB6aXRlbXM7XG5cbiAgZm9yIChpPWl0ZW1zLmxlbmd0aDsgLS1pID49IDA7KSB7XG4gICAgaWYgKGhpdCA9IHZpc2l0b3IoaXRlbXNbaV0pKSByZXR1cm4gaGl0O1xuICB9XG5cbiAgaWYgKGl0ZW1zID09PSB6aXRlbXMpIHtcbiAgICBmb3IgKGl0ZW1zPXNjZW5lLml0ZW1zLCBpPWl0ZW1zLmxlbmd0aDsgLS1pID49IDA7KSB7XG4gICAgICBpZiAoIWl0ZW1zW2ldLnppbmRleCkge1xuICAgICAgICBpZiAoaGl0ID0gdmlzaXRvcihpdGVtc1tpXSkpIHJldHVybiBoaXQ7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG51bGw7XG59XG5cbmZ1bmN0aW9uIGRyYXdBbGwocGF0aCkge1xuICByZXR1cm4gZnVuY3Rpb24oY29udGV4dCwgc2NlbmUsIGJvdW5kcykge1xuICAgIHZpc2l0KHNjZW5lLCBmdW5jdGlvbihpdGVtKSB7XG4gICAgICBpZiAoIWJvdW5kcyB8fCBib3VuZHMuaW50ZXJzZWN0cyhpdGVtLmJvdW5kcykpIHtcbiAgICAgICAgZHJhd1BhdGgocGF0aCwgY29udGV4dCwgaXRlbSwgaXRlbSk7XG4gICAgICB9XG4gICAgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGRyYXdPbmUocGF0aCkge1xuICByZXR1cm4gZnVuY3Rpb24oY29udGV4dCwgc2NlbmUsIGJvdW5kcykge1xuICAgIGlmIChzY2VuZS5pdGVtcy5sZW5ndGggJiYgKCFib3VuZHMgfHwgYm91bmRzLmludGVyc2VjdHMoc2NlbmUuYm91bmRzKSkpIHtcbiAgICAgIGRyYXdQYXRoKHBhdGgsIGNvbnRleHQsIHNjZW5lLml0ZW1zWzBdLCBzY2VuZS5pdGVtcyk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBkcmF3UGF0aChwYXRoLCBjb250ZXh0LCBpdGVtLCBpdGVtcykge1xuICB2YXIgb3BhY2l0eSA9IGl0ZW0ub3BhY2l0eSA9PSBudWxsID8gMSA6IGl0ZW0ub3BhY2l0eTtcbiAgaWYgKG9wYWNpdHkgPT09IDApIHJldHVybjtcblxuICBpZiAocGF0aChjb250ZXh0LCBpdGVtcykpIHJldHVybjtcblxuICBpZiAoaXRlbS5maWxsICYmIGZpbGwoY29udGV4dCwgaXRlbSwgb3BhY2l0eSkpIHtcbiAgICBjb250ZXh0LmZpbGwoKTtcbiAgfVxuXG4gIGlmIChpdGVtLnN0cm9rZSAmJiBzdHJva2UoY29udGV4dCwgaXRlbSwgb3BhY2l0eSkpIHtcbiAgICBjb250ZXh0LnN0cm9rZSgpO1xuICB9XG59XG5cbnZhciB0cnVlRnVuYyA9IGZ1bmN0aW9uKCkgeyByZXR1cm4gdHJ1ZTsgfTtcblxuZnVuY3Rpb24gcGljayh0ZXN0KSB7XG4gIGlmICghdGVzdCkgdGVzdCA9IHRydWVGdW5jO1xuXG4gIHJldHVybiBmdW5jdGlvbihjb250ZXh0LCBzY2VuZSwgeCwgeSwgZ3gsIGd5KSB7XG4gICAgaWYgKGNvbnRleHQucGl4ZWxSYXRpbyA+IDEpIHtcbiAgICAgIHggKj0gY29udGV4dC5waXhlbFJhdGlvO1xuICAgICAgeSAqPSBjb250ZXh0LnBpeGVsUmF0aW87XG4gICAgfVxuXG4gICAgcmV0dXJuIHBpY2tWaXNpdChzY2VuZSwgZnVuY3Rpb24oaXRlbSkge1xuICAgICAgdmFyIGIgPSBpdGVtLmJvdW5kcztcbiAgICAgIC8vIGZpcnN0IGhpdCB0ZXN0IGFnYWluc3QgYm91bmRpbmcgYm94XG4gICAgICBpZiAoKGIgJiYgIWIuY29udGFpbnMoZ3gsIGd5KSkgfHwgIWIpIHJldHVybjtcbiAgICAgIC8vIGlmIGluIGJvdW5kaW5nIGJveCwgcGVyZm9ybSBtb3JlIGNhcmVmdWwgdGVzdFxuICAgICAgaWYgKHRlc3QoY29udGV4dCwgaXRlbSwgeCwgeSwgZ3gsIGd5KSkgcmV0dXJuIGl0ZW07XG4gICAgfSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGhpdFBhdGgocGF0aCwgZmlsbGVkKSB7XG4gIHJldHVybiBmdW5jdGlvbihjb250ZXh0LCBvLCB4LCB5KSB7XG4gICAgdmFyIGl0ZW0gPSBBcnJheS5pc0FycmF5KG8pID8gb1swXSA6IG8sXG4gICAgICAgIGZpbGwgPSAoZmlsbGVkID09IG51bGwpID8gaXRlbS5maWxsIDogZmlsbGVkLFxuICAgICAgICBzdHJva2UgPSBpdGVtLnN0cm9rZSAmJiBjb250ZXh0LmlzUG9pbnRJblN0cm9rZSwgbHcsIGxjO1xuXG4gICAgaWYgKHN0cm9rZSkge1xuICAgICAgbHcgPSBpdGVtLnN0cm9rZVdpZHRoO1xuICAgICAgbGMgPSBpdGVtLnN0cm9rZUNhcDtcbiAgICAgIGNvbnRleHQubGluZVdpZHRoID0gbHcgIT0gbnVsbCA/IGx3IDogMTtcbiAgICAgIGNvbnRleHQubGluZUNhcCAgID0gbGMgIT0gbnVsbCA/IGxjIDogJ2J1dHQnO1xuICAgIH1cblxuICAgIHJldHVybiBwYXRoKGNvbnRleHQsIG8pID8gZmFsc2UgOlxuICAgICAgKGZpbGwgJiYgY29udGV4dC5pc1BvaW50SW5QYXRoKHgsIHkpKSB8fFxuICAgICAgKHN0cm9rZSAmJiBjb250ZXh0LmlzUG9pbnRJblN0cm9rZSh4LCB5KSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIHBpY2tQYXRoKHBhdGgpIHtcbiAgcmV0dXJuIHBpY2soaGl0UGF0aChwYXRoKSk7XG59XG5cbnZhciB0cmFuc2xhdGUgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHJldHVybiAndHJhbnNsYXRlKCcgKyB4ICsgJywnICsgeSArICcpJztcbn07XG5cbnZhciB0cmFuc2xhdGVJdGVtID0gZnVuY3Rpb24oaXRlbSkge1xuICByZXR1cm4gdHJhbnNsYXRlKGl0ZW0ueCB8fCAwLCBpdGVtLnkgfHwgMCk7XG59O1xuXG52YXIgbWFya0l0ZW1QYXRoID0gZnVuY3Rpb24odHlwZSwgc2hhcGUpIHtcblxuICBmdW5jdGlvbiBhdHRyKGVtaXQsIGl0ZW0pIHtcbiAgICBlbWl0KCd0cmFuc2Zvcm0nLCB0cmFuc2xhdGVJdGVtKGl0ZW0pKTtcbiAgICBlbWl0KCdkJywgc2hhcGUobnVsbCwgaXRlbSkpO1xuICB9XG5cbiAgZnVuY3Rpb24gYm91bmQoYm91bmRzLCBpdGVtKSB7XG4gICAgc2hhcGUoY29udGV4dChib3VuZHMpLCBpdGVtKTtcbiAgICByZXR1cm4gYm91bmRTdHJva2UoYm91bmRzLCBpdGVtKVxuICAgICAgLnRyYW5zbGF0ZShpdGVtLnggfHwgMCwgaXRlbS55IHx8IDApO1xuICB9XG5cbiAgZnVuY3Rpb24gZHJhdyhjb250ZXh0JCQxLCBpdGVtKSB7XG4gICAgdmFyIHggPSBpdGVtLnggfHwgMCxcbiAgICAgICAgeSA9IGl0ZW0ueSB8fCAwO1xuICAgIGNvbnRleHQkJDEudHJhbnNsYXRlKHgsIHkpO1xuICAgIGNvbnRleHQkJDEuYmVnaW5QYXRoKCk7XG4gICAgc2hhcGUoY29udGV4dCQkMSwgaXRlbSk7XG4gICAgY29udGV4dCQkMS50cmFuc2xhdGUoLXgsIC15KTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogICB0eXBlLFxuICAgIHRhZzogICAgJ3BhdGgnLFxuICAgIG5lc3RlZDogZmFsc2UsXG4gICAgYXR0cjogICBhdHRyLFxuICAgIGJvdW5kOiAgYm91bmQsXG4gICAgZHJhdzogICBkcmF3QWxsKGRyYXcpLFxuICAgIHBpY2s6ICAgcGlja1BhdGgoZHJhdylcbiAgfTtcblxufTtcblxudmFyIGFyYyA9IG1hcmtJdGVtUGF0aCgnYXJjJywgYXJjJDEpO1xuXG52YXIgbWFya011bHRpSXRlbVBhdGggPSBmdW5jdGlvbih0eXBlLCBzaGFwZSkge1xuXG4gIGZ1bmN0aW9uIGF0dHIoZW1pdCwgaXRlbSkge1xuICAgIHZhciBpdGVtcyA9IGl0ZW0ubWFyay5pdGVtcztcbiAgICBpZiAoaXRlbXMubGVuZ3RoKSBlbWl0KCdkJywgc2hhcGUobnVsbCwgaXRlbXMpKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGJvdW5kKGJvdW5kcywgbWFyaykge1xuICAgIHZhciBpdGVtcyA9IG1hcmsuaXRlbXM7XG4gICAgaWYgKGl0ZW1zLmxlbmd0aCA9PT0gMCkge1xuICAgICAgcmV0dXJuIGJvdW5kcztcbiAgICB9IGVsc2Uge1xuICAgICAgc2hhcGUoY29udGV4dChib3VuZHMpLCBpdGVtcyk7XG4gICAgICByZXR1cm4gYm91bmRTdHJva2UoYm91bmRzLCBpdGVtc1swXSk7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gZHJhdyhjb250ZXh0JCQxLCBpdGVtcykge1xuICAgIGNvbnRleHQkJDEuYmVnaW5QYXRoKCk7XG4gICAgc2hhcGUoY29udGV4dCQkMSwgaXRlbXMpO1xuICB9XG5cbiAgdmFyIGhpdCA9IGhpdFBhdGgoZHJhdyk7XG5cbiAgZnVuY3Rpb24gcGljayQkMShjb250ZXh0JCQxLCBzY2VuZSwgeCwgeSwgZ3gsIGd5KSB7XG4gICAgdmFyIGl0ZW1zID0gc2NlbmUuaXRlbXMsXG4gICAgICAgIGIgPSBzY2VuZS5ib3VuZHM7XG5cbiAgICBpZiAoIWl0ZW1zIHx8ICFpdGVtcy5sZW5ndGggfHwgYiAmJiAhYi5jb250YWlucyhneCwgZ3kpKSB7XG4gICAgICByZXR1cm4gbnVsbDtcbiAgICB9XG5cbiAgICBpZiAoY29udGV4dCQkMS5waXhlbFJhdGlvID4gMSkge1xuICAgICAgeCAqPSBjb250ZXh0JCQxLnBpeGVsUmF0aW87XG4gICAgICB5ICo9IGNvbnRleHQkJDEucGl4ZWxSYXRpbztcbiAgICB9XG4gICAgcmV0dXJuIGhpdChjb250ZXh0JCQxLCBpdGVtcywgeCwgeSkgPyBpdGVtc1swXSA6IG51bGw7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHR5cGU6ICAgdHlwZSxcbiAgICB0YWc6ICAgICdwYXRoJyxcbiAgICBuZXN0ZWQ6IHRydWUsXG4gICAgYXR0cjogICBhdHRyLFxuICAgIGJvdW5kOiAgYm91bmQsXG4gICAgZHJhdzogICBkcmF3T25lKGRyYXcpLFxuICAgIHBpY2s6ICAgcGljayQkMVxuICB9O1xuXG59O1xuXG52YXIgYXJlYSQyID0gbWFya011bHRpSXRlbVBhdGgoJ2FyZWEnLCBhcmVhKTtcblxudmFyIGNsaXBfaWQgPSAxO1xuXG5mdW5jdGlvbiByZXNldFNWR0NsaXBJZCgpIHtcbiAgY2xpcF9pZCA9IDE7XG59XG5cbnZhciBjbGlwID0gZnVuY3Rpb24ocmVuZGVyZXIsIGl0ZW0sIHNpemUpIHtcbiAgdmFyIGNsaXAgPSBpdGVtLmNsaXAsXG4gICAgICBkZWZzID0gcmVuZGVyZXIuX2RlZnMsXG4gICAgICBpZCQkMSA9IGl0ZW0uY2xpcF9pZCB8fCAoaXRlbS5jbGlwX2lkID0gJ2NsaXAnICsgY2xpcF9pZCsrKSxcbiAgICAgIGMgPSBkZWZzLmNsaXBwaW5nW2lkJCQxXSB8fCAoZGVmcy5jbGlwcGluZ1tpZCQkMV0gPSB7aWQ6IGlkJCQxfSk7XG5cbiAgaWYgKGlzRnVuY3Rpb24oY2xpcCkpIHtcbiAgICBjLnBhdGggPSBjbGlwKG51bGwpO1xuICB9IGVsc2Uge1xuICAgIGMud2lkdGggPSBzaXplLndpZHRoIHx8IDA7XG4gICAgYy5oZWlnaHQgPSBzaXplLmhlaWdodCB8fCAwO1xuICB9XG5cbiAgcmV0dXJuICd1cmwoIycgKyBpZCQkMSArICcpJztcbn07XG5cbnZhciBTdHJva2VPZmZzZXQgPSAwLjU7XG5cbmZ1bmN0aW9uIGF0dHIoZW1pdCwgaXRlbSkge1xuICBlbWl0KCd0cmFuc2Zvcm0nLCB0cmFuc2xhdGVJdGVtKGl0ZW0pKTtcbn1cblxuZnVuY3Rpb24gYmFja2dyb3VuZChlbWl0LCBpdGVtKSB7XG4gIHZhciBvZmZzZXQgPSBpdGVtLnN0cm9rZSA/IFN0cm9rZU9mZnNldCA6IDA7XG4gIGVtaXQoJ2NsYXNzJywgJ2JhY2tncm91bmQnKTtcbiAgZW1pdCgnZCcsIHJlY3RhbmdsZShudWxsLCBpdGVtLCBvZmZzZXQsIG9mZnNldCkpO1xufVxuXG5mdW5jdGlvbiBmb3JlZ3JvdW5kKGVtaXQsIGl0ZW0sIHJlbmRlcmVyKSB7XG4gIHZhciB1cmwgPSBpdGVtLmNsaXAgPyBjbGlwKHJlbmRlcmVyLCBpdGVtLCBpdGVtKSA6IG51bGw7XG4gIGVtaXQoJ2NsaXAtcGF0aCcsIHVybCk7XG59XG5cbmZ1bmN0aW9uIGJvdW5kKGJvdW5kcywgZ3JvdXApIHtcbiAgaWYgKCFncm91cC5jbGlwICYmIGdyb3VwLml0ZW1zKSB7XG4gICAgdmFyIGl0ZW1zID0gZ3JvdXAuaXRlbXM7XG4gICAgZm9yICh2YXIgaj0wLCBtPWl0ZW1zLmxlbmd0aDsgajxtOyArK2opIHtcbiAgICAgIGJvdW5kcy51bmlvbihpdGVtc1tqXS5ib3VuZHMpO1xuICAgIH1cbiAgfVxuXG4gIGlmIChncm91cC5jbGlwIHx8IGdyb3VwLndpZHRoIHx8IGdyb3VwLmhlaWdodCkge1xuICAgIGJvdW5kU3Ryb2tlKFxuICAgICAgYm91bmRzLmFkZCgwLCAwKS5hZGQoZ3JvdXAud2lkdGggfHwgMCwgZ3JvdXAuaGVpZ2h0IHx8IDApLFxuICAgICAgZ3JvdXBcbiAgICApO1xuICB9XG5cbiAgcmV0dXJuIGJvdW5kcy50cmFuc2xhdGUoZ3JvdXAueCB8fCAwLCBncm91cC55IHx8IDApO1xufVxuXG5mdW5jdGlvbiBkcmF3KGNvbnRleHQsIHNjZW5lLCBib3VuZHMpIHtcbiAgdmFyIHJlbmRlcmVyID0gdGhpcztcblxuICB2aXNpdChzY2VuZSwgZnVuY3Rpb24oZ3JvdXApIHtcbiAgICB2YXIgZ3ggPSBncm91cC54IHx8IDAsXG4gICAgICAgIGd5ID0gZ3JvdXAueSB8fCAwLFxuICAgICAgICB3ID0gZ3JvdXAud2lkdGggfHwgMCxcbiAgICAgICAgaCA9IGdyb3VwLmhlaWdodCB8fCAwLFxuICAgICAgICBvZmZzZXQsIG9wYWNpdHk7XG5cbiAgICAvLyBzZXR1cCBncmFwaGljcyBjb250ZXh0XG4gICAgY29udGV4dC5zYXZlKCk7XG4gICAgY29udGV4dC50cmFuc2xhdGUoZ3gsIGd5KTtcblxuICAgIC8vIGRyYXcgZ3JvdXAgYmFja2dyb3VuZFxuICAgIGlmIChncm91cC5zdHJva2UgfHwgZ3JvdXAuZmlsbCkge1xuICAgICAgb3BhY2l0eSA9IGdyb3VwLm9wYWNpdHkgPT0gbnVsbCA/IDEgOiBncm91cC5vcGFjaXR5O1xuICAgICAgaWYgKG9wYWNpdHkgPiAwKSB7XG4gICAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICAgIG9mZnNldCA9IGdyb3VwLnN0cm9rZSA/IFN0cm9rZU9mZnNldCA6IDA7XG4gICAgICAgIHJlY3RhbmdsZShjb250ZXh0LCBncm91cCwgb2Zmc2V0LCBvZmZzZXQpO1xuICAgICAgICBpZiAoZ3JvdXAuZmlsbCAmJiBmaWxsKGNvbnRleHQsIGdyb3VwLCBvcGFjaXR5KSkge1xuICAgICAgICAgIGNvbnRleHQuZmlsbCgpO1xuICAgICAgICB9XG4gICAgICAgIGlmIChncm91cC5zdHJva2UgJiYgc3Ryb2tlKGNvbnRleHQsIGdyb3VwLCBvcGFjaXR5KSkge1xuICAgICAgICAgIGNvbnRleHQuc3Ryb2tlKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBzZXQgY2xpcCBhbmQgYm91bmRzXG4gICAgaWYgKGdyb3VwLmNsaXApIHtcbiAgICAgIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gICAgICBjb250ZXh0LnJlY3QoMCwgMCwgdywgaCk7XG4gICAgICBjb250ZXh0LmNsaXAoKTtcbiAgICB9XG4gICAgaWYgKGJvdW5kcykgYm91bmRzLnRyYW5zbGF0ZSgtZ3gsIC1neSk7XG5cbiAgICAvLyBkcmF3IGdyb3VwIGNvbnRlbnRzXG4gICAgdmlzaXQoZ3JvdXAsIGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICAgIHJlbmRlcmVyLmRyYXcoY29udGV4dCwgaXRlbSwgYm91bmRzKTtcbiAgICB9KTtcblxuICAgIC8vIHJlc3RvcmUgZ3JhcGhpY3MgY29udGV4dFxuICAgIGlmIChib3VuZHMpIGJvdW5kcy50cmFuc2xhdGUoZ3gsIGd5KTtcbiAgICBjb250ZXh0LnJlc3RvcmUoKTtcbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHBpY2skMShjb250ZXh0LCBzY2VuZSwgeCwgeSwgZ3gsIGd5KSB7XG4gIGlmIChzY2VuZS5ib3VuZHMgJiYgIXNjZW5lLmJvdW5kcy5jb250YWlucyhneCwgZ3kpIHx8ICFzY2VuZS5pdGVtcykge1xuICAgIHJldHVybiBudWxsO1xuICB9XG5cbiAgdmFyIGhhbmRsZXIgPSB0aGlzO1xuXG4gIHJldHVybiBwaWNrVmlzaXQoc2NlbmUsIGZ1bmN0aW9uKGdyb3VwKSB7XG4gICAgdmFyIGhpdCwgZHgsIGR5LCBiO1xuXG4gICAgLy8gZmlyc3QgaGl0IHRlc3QgYWdhaW5zdCBib3VuZGluZyBib3hcbiAgICAvLyBpZiBhIGdyb3VwIGlzIGNsaXBwZWQsIHRoYXQgc2hvdWxkIGJlIGhhbmRsZWQgYnkgdGhlIGJvdW5kcyBjaGVjay5cbiAgICBiID0gZ3JvdXAuYm91bmRzO1xuICAgIGlmIChiICYmICFiLmNvbnRhaW5zKGd4LCBneSkpIHJldHVybjtcblxuICAgIC8vIHBhc3NlZCBib3VuZHMgY2hlY2ssIHNvIHRlc3Qgc3ViLWdyb3Vwc1xuICAgIGR4ID0gKGdyb3VwLnggfHwgMCk7XG4gICAgZHkgPSAoZ3JvdXAueSB8fCAwKTtcblxuICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgIGNvbnRleHQudHJhbnNsYXRlKGR4LCBkeSk7XG5cbiAgICBkeCA9IGd4IC0gZHg7XG4gICAgZHkgPSBneSAtIGR5O1xuXG4gICAgaGl0ID0gcGlja1Zpc2l0KGdyb3VwLCBmdW5jdGlvbihtYXJrKSB7XG4gICAgICByZXR1cm4gcGlja01hcmsobWFyaywgZHgsIGR5KVxuICAgICAgICA/IGhhbmRsZXIucGljayhtYXJrLCB4LCB5LCBkeCwgZHkpXG4gICAgICAgIDogbnVsbDtcbiAgICB9KTtcblxuICAgIGNvbnRleHQucmVzdG9yZSgpO1xuICAgIGlmIChoaXQpIHJldHVybiBoaXQ7XG5cbiAgICBoaXQgPSBzY2VuZS5pbnRlcmFjdGl2ZSAhPT0gZmFsc2VcbiAgICAgICYmIChncm91cC5maWxsIHx8IGdyb3VwLnN0cm9rZSlcbiAgICAgICYmIGR4ID49IDBcbiAgICAgICYmIGR4IDw9IGdyb3VwLndpZHRoXG4gICAgICAmJiBkeSA+PSAwXG4gICAgICAmJiBkeSA8PSBncm91cC5oZWlnaHQ7XG5cbiAgICByZXR1cm4gaGl0ID8gZ3JvdXAgOiBudWxsO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gcGlja01hcmsobWFyaywgeCwgeSkge1xuICByZXR1cm4gKG1hcmsuaW50ZXJhY3RpdmUgIT09IGZhbHNlIHx8IG1hcmsubWFya3R5cGUgPT09ICdncm91cCcpXG4gICAgJiYgbWFyay5ib3VuZHMgJiYgbWFyay5ib3VuZHMuY29udGFpbnMoeCwgeSk7XG59XG5cbnZhciBncm91cCA9IHtcbiAgdHlwZTogICAgICAgJ2dyb3VwJyxcbiAgdGFnOiAgICAgICAgJ2cnLFxuICBuZXN0ZWQ6ICAgICBmYWxzZSxcbiAgYXR0cjogICAgICAgYXR0cixcbiAgYm91bmQ6ICAgICAgYm91bmQsXG4gIGRyYXc6ICAgICAgIGRyYXcsXG4gIHBpY2s6ICAgICAgIHBpY2skMSxcbiAgYmFja2dyb3VuZDogYmFja2dyb3VuZCxcbiAgZm9yZWdyb3VuZDogZm9yZWdyb3VuZFxufTtcblxuZnVuY3Rpb24gZ2V0SW1hZ2UoaXRlbSwgcmVuZGVyZXIpIHtcbiAgdmFyIGltYWdlID0gaXRlbS5pbWFnZTtcbiAgaWYgKCFpbWFnZSB8fCBpbWFnZS51cmwgIT09IGl0ZW0udXJsKSB7XG4gICAgaW1hZ2UgPSB7bG9hZGVkOiBmYWxzZSwgd2lkdGg6IDAsIGhlaWdodDogMH07XG4gICAgcmVuZGVyZXIubG9hZEltYWdlKGl0ZW0udXJsKS50aGVuKGZ1bmN0aW9uKGltYWdlKSB7XG4gICAgICBpdGVtLmltYWdlID0gaW1hZ2U7XG4gICAgICBpdGVtLmltYWdlLnVybCA9IGl0ZW0udXJsO1xuICAgIH0pO1xuICB9XG4gIHJldHVybiBpbWFnZTtcbn1cblxuZnVuY3Rpb24gaW1hZ2VYT2Zmc2V0KGFsaWduLCB3KSB7XG4gIHJldHVybiBhbGlnbiA9PT0gJ2NlbnRlcicgPyB3IC8gMiA6IGFsaWduID09PSAncmlnaHQnID8gdyA6IDA7XG59XG5cbmZ1bmN0aW9uIGltYWdlWU9mZnNldChiYXNlbGluZSwgaCkge1xuICByZXR1cm4gYmFzZWxpbmUgPT09ICdtaWRkbGUnID8gaCAvIDIgOiBiYXNlbGluZSA9PT0gJ2JvdHRvbScgPyBoIDogMDtcbn1cblxuZnVuY3Rpb24gYXR0ciQxKGVtaXQsIGl0ZW0sIHJlbmRlcmVyKSB7XG4gIHZhciBpbWFnZSA9IGdldEltYWdlKGl0ZW0sIHJlbmRlcmVyKSxcbiAgICAgIHggPSBpdGVtLnggfHwgMCxcbiAgICAgIHkgPSBpdGVtLnkgfHwgMCxcbiAgICAgIHcgPSAoaXRlbS53aWR0aCAhPSBudWxsID8gaXRlbS53aWR0aCA6IGltYWdlLndpZHRoKSB8fCAwLFxuICAgICAgaCA9IChpdGVtLmhlaWdodCAhPSBudWxsID8gaXRlbS5oZWlnaHQgOiBpbWFnZS5oZWlnaHQpIHx8IDAsXG4gICAgICBhID0gaXRlbS5hc3BlY3QgPT09IGZhbHNlID8gJ25vbmUnIDogJ3hNaWRZTWlkJztcblxuICB4IC09IGltYWdlWE9mZnNldChpdGVtLmFsaWduLCB3KTtcbiAgeSAtPSBpbWFnZVlPZmZzZXQoaXRlbS5iYXNlbGluZSwgaCk7XG5cbiAgZW1pdCgnaHJlZicsIGltYWdlLnNyYyB8fCAnJywgJ2h0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsnLCAneGxpbms6aHJlZicpO1xuICBlbWl0KCd0cmFuc2Zvcm0nLCB0cmFuc2xhdGUoeCwgeSkpO1xuICBlbWl0KCd3aWR0aCcsIHcpO1xuICBlbWl0KCdoZWlnaHQnLCBoKTtcbiAgZW1pdCgncHJlc2VydmVBc3BlY3RSYXRpbycsIGEpO1xufVxuXG5mdW5jdGlvbiBib3VuZCQxKGJvdW5kcywgaXRlbSkge1xuICB2YXIgaW1hZ2UgPSBpdGVtLmltYWdlLFxuICAgICAgeCA9IGl0ZW0ueCB8fCAwLFxuICAgICAgeSA9IGl0ZW0ueSB8fCAwLFxuICAgICAgdyA9IChpdGVtLndpZHRoICE9IG51bGwgPyBpdGVtLndpZHRoIDogKGltYWdlICYmIGltYWdlLndpZHRoKSkgfHwgMCxcbiAgICAgIGggPSAoaXRlbS5oZWlnaHQgIT0gbnVsbCA/IGl0ZW0uaGVpZ2h0IDogKGltYWdlICYmIGltYWdlLmhlaWdodCkpIHx8IDA7XG5cbiAgeCAtPSBpbWFnZVhPZmZzZXQoaXRlbS5hbGlnbiwgdyk7XG4gIHkgLT0gaW1hZ2VZT2Zmc2V0KGl0ZW0uYmFzZWxpbmUsIGgpO1xuXG4gIHJldHVybiBib3VuZHMuc2V0KHgsIHksIHggKyB3LCB5ICsgaCk7XG59XG5cbmZ1bmN0aW9uIGRyYXckMShjb250ZXh0LCBzY2VuZSwgYm91bmRzKSB7XG4gIHZhciByZW5kZXJlciA9IHRoaXM7XG5cbiAgdmlzaXQoc2NlbmUsIGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICBpZiAoYm91bmRzICYmICFib3VuZHMuaW50ZXJzZWN0cyhpdGVtLmJvdW5kcykpIHJldHVybjsgLy8gYm91bmRzIGNoZWNrXG5cbiAgICB2YXIgaW1hZ2UgPSBnZXRJbWFnZShpdGVtLCByZW5kZXJlciksXG4gICAgICAgIHggPSBpdGVtLnggfHwgMCxcbiAgICAgICAgeSA9IGl0ZW0ueSB8fCAwLFxuICAgICAgICB3ID0gKGl0ZW0ud2lkdGggIT0gbnVsbCA/IGl0ZW0ud2lkdGggOiBpbWFnZS53aWR0aCkgfHwgMCxcbiAgICAgICAgaCA9IChpdGVtLmhlaWdodCAhPSBudWxsID8gaXRlbS5oZWlnaHQgOiBpbWFnZS5oZWlnaHQpIHx8IDAsXG4gICAgICAgIG9wYWNpdHksIGFyMCwgYXIxLCB0O1xuXG4gICAgeCAtPSBpbWFnZVhPZmZzZXQoaXRlbS5hbGlnbiwgdyk7XG4gICAgeSAtPSBpbWFnZVlPZmZzZXQoaXRlbS5iYXNlbGluZSwgaCk7XG5cbiAgICBpZiAoaXRlbS5hc3BlY3QgIT09IGZhbHNlKSB7XG4gICAgICBhcjAgPSBpbWFnZS53aWR0aCAvIGltYWdlLmhlaWdodDtcbiAgICAgIGFyMSA9IGl0ZW0ud2lkdGggLyBpdGVtLmhlaWdodDtcbiAgICAgIGlmIChhcjAgPT09IGFyMCAmJiBhcjEgPT09IGFyMSAmJiBhcjAgIT09IGFyMSkge1xuICAgICAgICBpZiAoYXIxIDwgYXIwKSB7XG4gICAgICAgICAgdCA9IHcgLyBhcjA7XG4gICAgICAgICAgeSArPSAoaCAtIHQpIC8gMjtcbiAgICAgICAgICBoID0gdDtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICB0ID0gaCAqIGFyMDtcbiAgICAgICAgICB4ICs9ICh3IC0gdCkgLyAyO1xuICAgICAgICAgIHcgPSB0O1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKGltYWdlLmxvYWRlZCkge1xuICAgICAgY29udGV4dC5nbG9iYWxBbHBoYSA9IChvcGFjaXR5ID0gaXRlbS5vcGFjaXR5KSAhPSBudWxsID8gb3BhY2l0eSA6IDE7XG4gICAgICBjb250ZXh0LmRyYXdJbWFnZShpbWFnZSwgeCwgeSwgdywgaCk7XG4gICAgfVxuICB9KTtcbn1cblxudmFyIGltYWdlJDEgPSB7XG4gIHR5cGU6ICAgICAnaW1hZ2UnLFxuICB0YWc6ICAgICAgJ2ltYWdlJyxcbiAgbmVzdGVkOiAgIGZhbHNlLFxuICBhdHRyOiAgICAgYXR0ciQxLFxuICBib3VuZDogICAgYm91bmQkMSxcbiAgZHJhdzogICAgIGRyYXckMSxcbiAgcGljazogICAgIHBpY2soKSxcbiAgZ2V0OiAgICAgIGdldEltYWdlLFxuICB4T2Zmc2V0OiAgaW1hZ2VYT2Zmc2V0LFxuICB5T2Zmc2V0OiAgaW1hZ2VZT2Zmc2V0XG59O1xuXG52YXIgbGluZSQyID0gbWFya011bHRpSXRlbVBhdGgoJ2xpbmUnLCBsaW5lKTtcblxuZnVuY3Rpb24gYXR0ciQyKGVtaXQsIGl0ZW0pIHtcbiAgZW1pdCgndHJhbnNmb3JtJywgdHJhbnNsYXRlSXRlbShpdGVtKSk7XG4gIGVtaXQoJ2QnLCBpdGVtLnBhdGgpO1xufVxuXG5mdW5jdGlvbiBwYXRoJDIoY29udGV4dCQkMSwgaXRlbSkge1xuICB2YXIgcGF0aCA9IGl0ZW0ucGF0aDtcbiAgaWYgKHBhdGggPT0gbnVsbCkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIGNhY2hlID0gaXRlbS5wYXRoQ2FjaGU7XG4gIGlmICghY2FjaGUgfHwgY2FjaGUucGF0aCAhPT0gcGF0aCkge1xuICAgIChpdGVtLnBhdGhDYWNoZSA9IGNhY2hlID0gcGF0aFBhcnNlKHBhdGgpKS5wYXRoID0gcGF0aDtcbiAgfVxuICBwYXRoUmVuZGVyKGNvbnRleHQkJDEsIGNhY2hlLCBpdGVtLngsIGl0ZW0ueSk7XG59XG5cbmZ1bmN0aW9uIGJvdW5kJDIoYm91bmRzLCBpdGVtKSB7XG4gIHJldHVybiBwYXRoJDIoY29udGV4dChib3VuZHMpLCBpdGVtKVxuICAgID8gYm91bmRzLnNldCgwLCAwLCAwLCAwKVxuICAgIDogYm91bmRTdHJva2UoYm91bmRzLCBpdGVtKTtcbn1cblxudmFyIHBhdGgkMyA9IHtcbiAgdHlwZTogICAncGF0aCcsXG4gIHRhZzogICAgJ3BhdGgnLFxuICBuZXN0ZWQ6IGZhbHNlLFxuICBhdHRyOiAgIGF0dHIkMixcbiAgYm91bmQ6ICBib3VuZCQyLFxuICBkcmF3OiAgIGRyYXdBbGwocGF0aCQyKSxcbiAgcGljazogICBwaWNrUGF0aChwYXRoJDIpXG59O1xuXG5mdW5jdGlvbiBhdHRyJDMoZW1pdCwgaXRlbSkge1xuICBlbWl0KCdkJywgcmVjdGFuZ2xlKG51bGwsIGl0ZW0pKTtcbn1cblxuZnVuY3Rpb24gYm91bmQkMyhib3VuZHMsIGl0ZW0pIHtcbiAgdmFyIHgsIHk7XG4gIHJldHVybiBib3VuZFN0cm9rZShib3VuZHMuc2V0KFxuICAgIHggPSBpdGVtLnggfHwgMCxcbiAgICB5ID0gaXRlbS55IHx8IDAsXG4gICAgKHggKyBpdGVtLndpZHRoKSB8fCAwLFxuICAgICh5ICsgaXRlbS5oZWlnaHQpIHx8IDBcbiAgKSwgaXRlbSk7XG59XG5cbmZ1bmN0aW9uIGRyYXckMihjb250ZXh0LCBpdGVtKSB7XG4gIGNvbnRleHQuYmVnaW5QYXRoKCk7XG4gIHJlY3RhbmdsZShjb250ZXh0LCBpdGVtKTtcbn1cblxudmFyIHJlY3QgPSB7XG4gIHR5cGU6ICAgJ3JlY3QnLFxuICB0YWc6ICAgICdwYXRoJyxcbiAgbmVzdGVkOiBmYWxzZSxcbiAgYXR0cjogICBhdHRyJDMsXG4gIGJvdW5kOiAgYm91bmQkMyxcbiAgZHJhdzogICBkcmF3QWxsKGRyYXckMiksXG4gIHBpY2s6ICAgcGlja1BhdGgoZHJhdyQyKVxufTtcblxuZnVuY3Rpb24gYXR0ciQ0KGVtaXQsIGl0ZW0pIHtcbiAgZW1pdCgndHJhbnNmb3JtJywgdHJhbnNsYXRlSXRlbShpdGVtKSk7XG4gIGVtaXQoJ3gyJywgaXRlbS54MiAhPSBudWxsID8gaXRlbS54MiAtIChpdGVtLnh8fDApIDogMCk7XG4gIGVtaXQoJ3kyJywgaXRlbS55MiAhPSBudWxsID8gaXRlbS55MiAtIChpdGVtLnl8fDApIDogMCk7XG59XG5cbmZ1bmN0aW9uIGJvdW5kJDQoYm91bmRzLCBpdGVtKSB7XG4gIHZhciB4MSwgeTE7XG4gIHJldHVybiBib3VuZFN0cm9rZShib3VuZHMuc2V0KFxuICAgIHgxID0gaXRlbS54IHx8IDAsXG4gICAgeTEgPSBpdGVtLnkgfHwgMCxcbiAgICBpdGVtLngyICE9IG51bGwgPyBpdGVtLngyIDogeDEsXG4gICAgaXRlbS55MiAhPSBudWxsID8gaXRlbS55MiA6IHkxXG4gICksIGl0ZW0pO1xufVxuXG5mdW5jdGlvbiBwYXRoJDQoY29udGV4dCwgaXRlbSwgb3BhY2l0eSkge1xuICB2YXIgeDEsIHkxLCB4MiwgeTI7XG5cbiAgaWYgKGl0ZW0uc3Ryb2tlICYmIHN0cm9rZShjb250ZXh0LCBpdGVtLCBvcGFjaXR5KSkge1xuICAgIHgxID0gaXRlbS54IHx8IDA7XG4gICAgeTEgPSBpdGVtLnkgfHwgMDtcbiAgICB4MiA9IGl0ZW0ueDIgIT0gbnVsbCA/IGl0ZW0ueDIgOiB4MTtcbiAgICB5MiA9IGl0ZW0ueTIgIT0gbnVsbCA/IGl0ZW0ueTIgOiB5MTtcbiAgICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuICAgIGNvbnRleHQubW92ZVRvKHgxLCB5MSk7XG4gICAgY29udGV4dC5saW5lVG8oeDIsIHkyKTtcbiAgICByZXR1cm4gdHJ1ZTtcbiAgfVxuICByZXR1cm4gZmFsc2U7XG59XG5cbmZ1bmN0aW9uIGRyYXckMyhjb250ZXh0LCBzY2VuZSwgYm91bmRzKSB7XG4gIHZpc2l0KHNjZW5lLCBmdW5jdGlvbihpdGVtKSB7XG4gICAgaWYgKGJvdW5kcyAmJiAhYm91bmRzLmludGVyc2VjdHMoaXRlbS5ib3VuZHMpKSByZXR1cm47IC8vIGJvdW5kcyBjaGVja1xuICAgIHZhciBvcGFjaXR5ID0gaXRlbS5vcGFjaXR5ID09IG51bGwgPyAxIDogaXRlbS5vcGFjaXR5O1xuICAgIGlmIChvcGFjaXR5ICYmIHBhdGgkNChjb250ZXh0LCBpdGVtLCBvcGFjaXR5KSkge1xuICAgICAgY29udGV4dC5zdHJva2UoKTtcbiAgICB9XG4gIH0pO1xufVxuXG5mdW5jdGlvbiBoaXQoY29udGV4dCwgaXRlbSwgeCwgeSkge1xuICBpZiAoIWNvbnRleHQuaXNQb2ludEluU3Ryb2tlKSByZXR1cm4gZmFsc2U7XG4gIHJldHVybiBwYXRoJDQoY29udGV4dCwgaXRlbSwgMSkgJiYgY29udGV4dC5pc1BvaW50SW5TdHJva2UoeCwgeSk7XG59XG5cbnZhciBydWxlID0ge1xuICB0eXBlOiAgICdydWxlJyxcbiAgdGFnOiAgICAnbGluZScsXG4gIG5lc3RlZDogZmFsc2UsXG4gIGF0dHI6ICAgYXR0ciQ0LFxuICBib3VuZDogIGJvdW5kJDQsXG4gIGRyYXc6ICAgZHJhdyQzLFxuICBwaWNrOiAgIHBpY2soaGl0KVxufTtcblxudmFyIHNoYXBlJDEgPSBtYXJrSXRlbVBhdGgoJ3NoYXBlJywgc2hhcGUpO1xuXG52YXIgc3ltYm9sJDEgPSBtYXJrSXRlbVBhdGgoJ3N5bWJvbCcsIHN5bWJvbCk7XG5cbnZhciBjb250ZXh0JDE7XG52YXIgZm9udEhlaWdodDtcblxudmFyIHRleHRNZXRyaWNzID0ge1xuICBoZWlnaHQ6IGhlaWdodCxcbiAgbWVhc3VyZVdpZHRoOiBtZWFzdXJlV2lkdGgsXG4gIGVzdGltYXRlV2lkdGg6IGVzdGltYXRlV2lkdGgsXG4gIHdpZHRoOiBlc3RpbWF0ZVdpZHRoLFxuICBjYW52YXM6IHVzZUNhbnZhc1xufTtcblxudXNlQ2FudmFzKHRydWUpO1xuXG4vLyBtYWtlIGR1bWIsIHNpbXBsZSBlc3RpbWF0ZSBpZiBubyBjYW52YXMgaXMgYXZhaWxhYmxlXG5mdW5jdGlvbiBlc3RpbWF0ZVdpZHRoKGl0ZW0pIHtcbiAgZm9udEhlaWdodCA9IGhlaWdodChpdGVtKTtcbiAgcmV0dXJuIGVzdGltYXRlKHRleHRWYWx1ZShpdGVtKSk7XG59XG5cbmZ1bmN0aW9uIGVzdGltYXRlKHRleHQpIHtcbiAgcmV0dXJuIH5+KDAuOCAqIHRleHQubGVuZ3RoICogZm9udEhlaWdodCk7XG59XG5cbi8vIG1lYXN1cmUgdGV4dCB3aWR0aCBpZiBjYW52YXMgaXMgYXZhaWxhYmxlXG5mdW5jdGlvbiBtZWFzdXJlV2lkdGgoaXRlbSkge1xuICBjb250ZXh0JDEuZm9udCA9IGZvbnQoaXRlbSk7XG4gIHJldHVybiBtZWFzdXJlJDEodGV4dFZhbHVlKGl0ZW0pKTtcbn1cblxuZnVuY3Rpb24gbWVhc3VyZSQxKHRleHQpIHtcbiAgcmV0dXJuIGNvbnRleHQkMS5tZWFzdXJlVGV4dCh0ZXh0KS53aWR0aDtcbn1cblxuZnVuY3Rpb24gaGVpZ2h0KGl0ZW0pIHtcbiAgcmV0dXJuIGl0ZW0uZm9udFNpemUgIT0gbnVsbCA/IGl0ZW0uZm9udFNpemUgOiAxMTtcbn1cblxuZnVuY3Rpb24gdXNlQ2FudmFzKHVzZSkge1xuICBjb250ZXh0JDEgPSB1c2UgJiYgKGNvbnRleHQkMSA9IGNhbnZhcygxLDEpKSA/IGNvbnRleHQkMS5nZXRDb250ZXh0KCcyZCcpIDogbnVsbDtcbiAgdGV4dE1ldHJpY3Mud2lkdGggPSBjb250ZXh0JDEgPyBtZWFzdXJlV2lkdGggOiBlc3RpbWF0ZVdpZHRoO1xufVxuXG5mdW5jdGlvbiB0ZXh0VmFsdWUoaXRlbSkge1xuICB2YXIgcyA9IGl0ZW0udGV4dDtcbiAgaWYgKHMgPT0gbnVsbCkge1xuICAgIHJldHVybiAnJztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gaXRlbS5saW1pdCA+IDAgPyB0cnVuY2F0ZSQxKGl0ZW0pIDogcyArICcnO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRydW5jYXRlJDEoaXRlbSkge1xuICB2YXIgbGltaXQgPSAraXRlbS5saW1pdCxcbiAgICAgIHRleHQgPSBpdGVtLnRleHQgKyAnJyxcbiAgICAgIHdpZHRoO1xuXG4gIGlmIChjb250ZXh0JDEpIHtcbiAgICBjb250ZXh0JDEuZm9udCA9IGZvbnQoaXRlbSk7XG4gICAgd2lkdGggPSBtZWFzdXJlJDE7XG4gIH0gZWxzZSB7XG4gICAgZm9udEhlaWdodCA9IGhlaWdodChpdGVtKTtcbiAgICB3aWR0aCA9IGVzdGltYXRlO1xuICB9XG5cbiAgaWYgKHdpZHRoKHRleHQpIDwgbGltaXQpIHJldHVybiB0ZXh0O1xuXG4gIHZhciBlbGxpcHNpcyA9IGl0ZW0uZWxsaXBzaXMgfHwgJ1xcdTIwMjYnLFxuICAgICAgcnRsID0gaXRlbS5kaXIgPT09ICdydGwnLFxuICAgICAgbG8gPSAwLFxuICAgICAgaGkgPSB0ZXh0Lmxlbmd0aCwgbWlkO1xuXG4gIGxpbWl0IC09IHdpZHRoKGVsbGlwc2lzKTtcblxuICBpZiAocnRsKSB7XG4gICAgd2hpbGUgKGxvIDwgaGkpIHtcbiAgICAgIG1pZCA9IChsbyArIGhpID4+PiAxKTtcbiAgICAgIGlmICh3aWR0aCh0ZXh0LnNsaWNlKG1pZCkpID4gbGltaXQpIGxvID0gbWlkICsgMTtcbiAgICAgIGVsc2UgaGkgPSBtaWQ7XG4gICAgfVxuICAgIHJldHVybiBlbGxpcHNpcyArIHRleHQuc2xpY2UobG8pO1xuICB9IGVsc2Uge1xuICAgIHdoaWxlIChsbyA8IGhpKSB7XG4gICAgICBtaWQgPSAxICsgKGxvICsgaGkgPj4+IDEpO1xuICAgICAgaWYgKHdpZHRoKHRleHQuc2xpY2UoMCwgbWlkKSkgPCBsaW1pdCkgbG8gPSBtaWQ7XG4gICAgICBlbHNlIGhpID0gbWlkIC0gMTtcbiAgICB9XG4gICAgcmV0dXJuIHRleHQuc2xpY2UoMCwgbG8pICsgZWxsaXBzaXM7XG4gIH1cbn1cblxuXG5mdW5jdGlvbiBmb250KGl0ZW0sIHF1b3RlKSB7XG4gIHZhciBmb250ID0gaXRlbS5mb250O1xuICBpZiAocXVvdGUgJiYgZm9udCkge1xuICAgIGZvbnQgPSBTdHJpbmcoZm9udCkucmVwbGFjZSgvXCIvZywgJ1xcJycpO1xuICB9XG4gIHJldHVybiAnJyArXG4gICAgKGl0ZW0uZm9udFN0eWxlID8gaXRlbS5mb250U3R5bGUgKyAnICcgOiAnJykgK1xuICAgIChpdGVtLmZvbnRWYXJpYW50ID8gaXRlbS5mb250VmFyaWFudCArICcgJyA6ICcnKSArXG4gICAgKGl0ZW0uZm9udFdlaWdodCA/IGl0ZW0uZm9udFdlaWdodCArICcgJyA6ICcnKSArXG4gICAgaGVpZ2h0KGl0ZW0pICsgJ3B4ICcgK1xuICAgIChmb250IHx8ICdzYW5zLXNlcmlmJyk7XG59XG5cbmZ1bmN0aW9uIG9mZnNldChpdGVtKSB7XG4gIC8vIHBlcmZvcm0gb3VyIG93biBmb250IGJhc2VsaW5lIGNhbGN1bGF0aW9uXG4gIC8vIHdoeT8gbm90IGFsbCBicm93c2VycyBzdXBwb3J0IFNWRyAxLjEgJ2FsaWdubWVudC1iYXNlbGluZScgOihcbiAgdmFyIGJhc2VsaW5lID0gaXRlbS5iYXNlbGluZSxcbiAgICAgIGggPSBoZWlnaHQoaXRlbSk7XG4gIHJldHVybiBNYXRoLnJvdW5kKFxuICAgIGJhc2VsaW5lID09PSAndG9wJyAgICA/ICAwLjc5KmggOlxuICAgIGJhc2VsaW5lID09PSAnbWlkZGxlJyA/ICAwLjMwKmggOlxuICAgIGJhc2VsaW5lID09PSAnYm90dG9tJyA/IC0wLjIxKmggOiAwXG4gICk7XG59XG5cbnZhciB0ZXh0QWxpZ24gPSB7XG4gICdsZWZ0JzogICAnc3RhcnQnLFxuICAnY2VudGVyJzogJ21pZGRsZScsXG4gICdyaWdodCc6ICAnZW5kJ1xufTtcblxudmFyIHRlbXBCb3VuZHMgPSBuZXcgQm91bmRzKCk7XG5cbmZ1bmN0aW9uIGF0dHIkNShlbWl0LCBpdGVtKSB7XG4gIHZhciBkeCA9IGl0ZW0uZHggfHwgMCxcbiAgICAgIGR5ID0gKGl0ZW0uZHkgfHwgMCkgKyBvZmZzZXQoaXRlbSksXG4gICAgICB4ID0gaXRlbS54IHx8IDAsXG4gICAgICB5ID0gaXRlbS55IHx8IDAsXG4gICAgICBhID0gaXRlbS5hbmdsZSB8fCAwLFxuICAgICAgciA9IGl0ZW0ucmFkaXVzIHx8IDAsIHQ7XG5cbiAgaWYgKHIpIHtcbiAgICB0ID0gKGl0ZW0udGhldGEgfHwgMCkgLSBNYXRoLlBJLzI7XG4gICAgeCArPSByICogTWF0aC5jb3ModCk7XG4gICAgeSArPSByICogTWF0aC5zaW4odCk7XG4gIH1cblxuICBlbWl0KCd0ZXh0LWFuY2hvcicsIHRleHRBbGlnbltpdGVtLmFsaWduXSB8fCAnc3RhcnQnKTtcblxuICBpZiAoYSkge1xuICAgIHQgPSB0cmFuc2xhdGUoeCwgeSkgKyAnIHJvdGF0ZSgnK2ErJyknO1xuICAgIGlmIChkeCB8fCBkeSkgdCArPSAnICcgKyB0cmFuc2xhdGUoZHgsIGR5KTtcbiAgfSBlbHNlIHtcbiAgICB0ID0gdHJhbnNsYXRlKHggKyBkeCwgeSArIGR5KTtcbiAgfVxuICBlbWl0KCd0cmFuc2Zvcm0nLCB0KTtcbn1cblxuZnVuY3Rpb24gYm91bmQkNShib3VuZHMsIGl0ZW0sIG5vUm90YXRlKSB7XG4gIHZhciBoID0gdGV4dE1ldHJpY3MuaGVpZ2h0KGl0ZW0pLFxuICAgICAgYSA9IGl0ZW0uYWxpZ24sXG4gICAgICByID0gaXRlbS5yYWRpdXMgfHwgMCxcbiAgICAgIHggPSBpdGVtLnggfHwgMCxcbiAgICAgIHkgPSBpdGVtLnkgfHwgMCxcbiAgICAgIGR4ID0gaXRlbS5keCB8fCAwLFxuICAgICAgZHkgPSAoaXRlbS5keSB8fCAwKSArIG9mZnNldChpdGVtKSAtIE1hdGgucm91bmQoMC44KmgpLCAvLyB1c2UgNC81IG9mZnNldFxuICAgICAgdywgdDtcblxuICBpZiAocikge1xuICAgIHQgPSAoaXRlbS50aGV0YSB8fCAwKSAtIE1hdGguUEkvMjtcbiAgICB4ICs9IHIgKiBNYXRoLmNvcyh0KTtcbiAgICB5ICs9IHIgKiBNYXRoLnNpbih0KTtcbiAgfVxuXG4gIC8vIGhvcml6b250YWwgYWxpZ25tZW50XG4gIHcgPSB0ZXh0TWV0cmljcy53aWR0aChpdGVtKTtcbiAgaWYgKGEgPT09ICdjZW50ZXInKSB7XG4gICAgZHggLT0gKHcgLyAyKTtcbiAgfSBlbHNlIGlmIChhID09PSAncmlnaHQnKSB7XG4gICAgZHggLT0gdztcbiAgfSBlbHNlIHtcbiAgICAvLyBsZWZ0IGJ5IGRlZmF1bHQsIGRvIG5vdGhpbmdcbiAgfVxuXG4gIGJvdW5kcy5zZXQoZHgrPXgsIGR5Kz15LCBkeCt3LCBkeStoKTtcbiAgaWYgKGl0ZW0uYW5nbGUgJiYgIW5vUm90YXRlKSB7XG4gICAgYm91bmRzLnJvdGF0ZShpdGVtLmFuZ2xlKk1hdGguUEkvMTgwLCB4LCB5KTtcbiAgfVxuICByZXR1cm4gYm91bmRzLmV4cGFuZChub1JvdGF0ZSB8fCAhdyA/IDAgOiAxKTtcbn1cblxuZnVuY3Rpb24gZHJhdyQ0KGNvbnRleHQsIHNjZW5lLCBib3VuZHMpIHtcbiAgdmlzaXQoc2NlbmUsIGZ1bmN0aW9uKGl0ZW0pIHtcbiAgICB2YXIgb3BhY2l0eSwgeCwgeSwgciwgdCwgc3RyO1xuICAgIGlmIChib3VuZHMgJiYgIWJvdW5kcy5pbnRlcnNlY3RzKGl0ZW0uYm91bmRzKSkgcmV0dXJuOyAvLyBib3VuZHMgY2hlY2tcbiAgICBpZiAoIShzdHIgPSB0ZXh0VmFsdWUoaXRlbSkpKSByZXR1cm47IC8vIGdldCB0ZXh0IHN0cmluZ1xuXG4gICAgb3BhY2l0eSA9IGl0ZW0ub3BhY2l0eSA9PSBudWxsID8gMSA6IGl0ZW0ub3BhY2l0eTtcbiAgICBpZiAob3BhY2l0eSA9PT0gMCkgcmV0dXJuO1xuXG4gICAgY29udGV4dC5mb250ID0gZm9udChpdGVtKTtcbiAgICBjb250ZXh0LnRleHRBbGlnbiA9IGl0ZW0uYWxpZ24gfHwgJ2xlZnQnO1xuXG4gICAgeCA9IGl0ZW0ueCB8fCAwO1xuICAgIHkgPSBpdGVtLnkgfHwgMDtcbiAgICBpZiAoKHIgPSBpdGVtLnJhZGl1cykpIHtcbiAgICAgIHQgPSAoaXRlbS50aGV0YSB8fCAwKSAtIE1hdGguUEkvMjtcbiAgICAgIHggKz0gciAqIE1hdGguY29zKHQpO1xuICAgICAgeSArPSByICogTWF0aC5zaW4odCk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0uYW5nbGUpIHtcbiAgICAgIGNvbnRleHQuc2F2ZSgpO1xuICAgICAgY29udGV4dC50cmFuc2xhdGUoeCwgeSk7XG4gICAgICBjb250ZXh0LnJvdGF0ZShpdGVtLmFuZ2xlICogTWF0aC5QSS8xODApO1xuICAgICAgeCA9IHkgPSAwOyAvLyByZXNldCB4LCB5XG4gICAgfVxuICAgIHggKz0gKGl0ZW0uZHggfHwgMCk7XG4gICAgeSArPSAoaXRlbS5keSB8fCAwKSArIG9mZnNldChpdGVtKTtcblxuICAgIGlmIChpdGVtLmZpbGwgJiYgZmlsbChjb250ZXh0LCBpdGVtLCBvcGFjaXR5KSkge1xuICAgICAgY29udGV4dC5maWxsVGV4dChzdHIsIHgsIHkpO1xuICAgIH1cbiAgICBpZiAoaXRlbS5zdHJva2UgJiYgc3Ryb2tlKGNvbnRleHQsIGl0ZW0sIG9wYWNpdHkpKSB7XG4gICAgICBjb250ZXh0LnN0cm9rZVRleHQoc3RyLCB4LCB5KTtcbiAgICB9XG4gICAgaWYgKGl0ZW0uYW5nbGUpIGNvbnRleHQucmVzdG9yZSgpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gaGl0JDEoY29udGV4dCwgaXRlbSwgeCwgeSwgZ3gsIGd5KSB7XG4gIGlmIChpdGVtLmZvbnRTaXplIDw9IDApIHJldHVybiBmYWxzZTtcbiAgaWYgKCFpdGVtLmFuZ2xlKSByZXR1cm4gdHJ1ZTsgLy8gYm91bmRzIHN1ZmZpY2llbnQgaWYgbm8gcm90YXRpb25cblxuICAvLyBwcm9qZWN0IHBvaW50IGludG8gc3BhY2Ugb2YgdW5yb3RhdGVkIGJvdW5kc1xuICB2YXIgYiA9IGJvdW5kJDUodGVtcEJvdW5kcywgaXRlbSwgdHJ1ZSksXG4gICAgICBhID0gLWl0ZW0uYW5nbGUgKiBNYXRoLlBJIC8gMTgwLFxuICAgICAgY29zID0gTWF0aC5jb3MoYSksXG4gICAgICBzaW4gPSBNYXRoLnNpbihhKSxcbiAgICAgIGl4ID0gaXRlbS54LFxuICAgICAgaXkgPSBpdGVtLnksXG4gICAgICBweCA9IGNvcypneCAtIHNpbipneSArIChpeCAtIGl4KmNvcyArIGl5KnNpbiksXG4gICAgICBweSA9IHNpbipneCArIGNvcypneSArIChpeSAtIGl4KnNpbiAtIGl5KmNvcyk7XG5cbiAgcmV0dXJuIGIuY29udGFpbnMocHgsIHB5KTtcbn1cblxudmFyIHRleHQkMSA9IHtcbiAgdHlwZTogICAndGV4dCcsXG4gIHRhZzogICAgJ3RleHQnLFxuICBuZXN0ZWQ6IGZhbHNlLFxuICBhdHRyOiAgIGF0dHIkNSxcbiAgYm91bmQ6ICBib3VuZCQ1LFxuICBkcmF3OiAgIGRyYXckNCxcbiAgcGljazogICBwaWNrKGhpdCQxKVxufTtcblxudmFyIHRyYWlsJDEgPSBtYXJrTXVsdGlJdGVtUGF0aCgndHJhaWwnLCB0cmFpbCk7XG5cbnZhciBtYXJrcyA9IHtcbiAgYXJjOiAgICAgYXJjLFxuICBhcmVhOiAgICBhcmVhJDIsXG4gIGdyb3VwOiAgIGdyb3VwLFxuICBpbWFnZTogICBpbWFnZSQxLFxuICBsaW5lOiAgICBsaW5lJDIsXG4gIHBhdGg6ICAgIHBhdGgkMyxcbiAgcmVjdDogICAgcmVjdCxcbiAgcnVsZTogICAgcnVsZSxcbiAgc2hhcGU6ICAgc2hhcGUkMSxcbiAgc3ltYm9sOiAgc3ltYm9sJDEsXG4gIHRleHQ6ICAgIHRleHQkMSxcbiAgdHJhaWw6ICAgdHJhaWwkMVxufTtcblxudmFyIGJvdW5kSXRlbSQxID0gZnVuY3Rpb24oaXRlbSwgZnVuYywgb3B0KSB7XG4gIHZhciB0eXBlID0gbWFya3NbaXRlbS5tYXJrLm1hcmt0eXBlXSxcbiAgICAgIGJvdW5kID0gZnVuYyB8fCB0eXBlLmJvdW5kO1xuICBpZiAodHlwZS5uZXN0ZWQpIGl0ZW0gPSBpdGVtLm1hcms7XG5cbiAgcmV0dXJuIGJvdW5kKGl0ZW0uYm91bmRzIHx8IChpdGVtLmJvdW5kcyA9IG5ldyBCb3VuZHMoKSksIGl0ZW0sIG9wdCk7XG59O1xuXG52YXIgRFVNTVkgPSB7bWFyazogbnVsbH07XG5cbnZhciBib3VuZE1hcmsgPSBmdW5jdGlvbihtYXJrLCBib3VuZHMsIG9wdCkge1xuICB2YXIgdHlwZSAgPSBtYXJrc1ttYXJrLm1hcmt0eXBlXSxcbiAgICAgIGJvdW5kID0gdHlwZS5ib3VuZCxcbiAgICAgIGl0ZW1zID0gbWFyay5pdGVtcyxcbiAgICAgIGhhc0l0ZW1zID0gaXRlbXMgJiYgaXRlbXMubGVuZ3RoLFxuICAgICAgaSwgbiwgaXRlbSwgYjtcblxuICBpZiAodHlwZS5uZXN0ZWQpIHtcbiAgICBpZiAoaGFzSXRlbXMpIHtcbiAgICAgIGl0ZW0gPSBpdGVtc1swXTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gbm8gaXRlbXMsIGZha2UgaXRcbiAgICAgIERVTU1ZLm1hcmsgPSBtYXJrO1xuICAgICAgaXRlbSA9IERVTU1ZO1xuICAgIH1cbiAgICBiID0gYm91bmRJdGVtJDEoaXRlbSwgYm91bmQsIG9wdCk7XG4gICAgYm91bmRzID0gYm91bmRzICYmIGJvdW5kcy51bmlvbihiKSB8fCBiO1xuICAgIHJldHVybiBib3VuZHM7XG4gIH1cblxuICBib3VuZHMgPSBib3VuZHNcbiAgICB8fCBtYXJrLmJvdW5kcyAmJiBtYXJrLmJvdW5kcy5jbGVhcigpXG4gICAgfHwgbmV3IEJvdW5kcygpO1xuXG4gIGlmIChoYXNJdGVtcykge1xuICAgIGZvciAoaT0wLCBuPWl0ZW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIGJvdW5kcy51bmlvbihib3VuZEl0ZW0kMShpdGVtc1tpXSwgYm91bmQsIG9wdCkpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBtYXJrLmJvdW5kcyA9IGJvdW5kcztcbn07XG5cbnZhciBrZXlzJDEgPSBbXG4gICdtYXJrdHlwZScsICduYW1lJywgJ3JvbGUnLCAnaW50ZXJhY3RpdmUnLCAnY2xpcCcsICdpdGVtcycsICd6aW5kZXgnLFxuICAneCcsICd5JywgJ3dpZHRoJywgJ2hlaWdodCcsICdhbGlnbicsICdiYXNlbGluZScsICAgICAgICAgICAgIC8vIGxheW91dFxuICAnZmlsbCcsICdmaWxsT3BhY2l0eScsICdvcGFjaXR5JywgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGZpbGxcbiAgJ3N0cm9rZScsICdzdHJva2VPcGFjaXR5JywgJ3N0cm9rZVdpZHRoJywgJ3N0cm9rZUNhcCcsICAgICAgICAvLyBzdHJva2VcbiAgJ3N0cm9rZURhc2gnLCAnc3Ryb2tlRGFzaE9mZnNldCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBzdHJva2UgZGFzaFxuICAnc3RhcnRBbmdsZScsICdlbmRBbmdsZScsICdpbm5lclJhZGl1cycsICdvdXRlclJhZGl1cycsICAgICAgIC8vIGFyY1xuICAnY29ybmVyUmFkaXVzJywgJ3BhZEFuZ2xlJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIGFyYywgcmVjdFxuICAnaW50ZXJwb2xhdGUnLCAndGVuc2lvbicsICdvcmllbnQnLCAnZGVmaW5lZCcsICAgICAgICAgICAgICAgIC8vIGFyZWEsIGxpbmVcbiAgJ3VybCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBpbWFnZVxuICAncGF0aCcsICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHBhdGhcbiAgJ3gyJywgJ3kyJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAvLyBydWxlXG4gICdzaXplJywgJ3NoYXBlJywgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gc3ltYm9sXG4gICd0ZXh0JywgJ2FuZ2xlJywgJ3RoZXRhJywgJ3JhZGl1cycsICdkeCcsICdkeScsICAgICAgICAgICAgICAgLy8gdGV4dFxuICAnZm9udCcsICdmb250U2l6ZScsICdmb250V2VpZ2h0JywgJ2ZvbnRTdHlsZScsICdmb250VmFyaWFudCcgIC8vIGZvbnRcbl07XG5cbmZ1bmN0aW9uIHNjZW5lVG9KU09OKHNjZW5lLCBpbmRlbnQpIHtcbiAgcmV0dXJuIEpTT04uc3RyaW5naWZ5KHNjZW5lLCBrZXlzJDEsIGluZGVudCk7XG59XG5cbmZ1bmN0aW9uIHNjZW5lRnJvbUpTT04oanNvbikge1xuICB2YXIgc2NlbmUgPSAodHlwZW9mIGpzb24gPT09ICdzdHJpbmcnID8gSlNPTi5wYXJzZShqc29uKSA6IGpzb24pO1xuICByZXR1cm4gaW5pdGlhbGl6ZShzY2VuZSk7XG59XG5cbmZ1bmN0aW9uIGluaXRpYWxpemUoc2NlbmUpIHtcbiAgdmFyIHR5cGUgPSBzY2VuZS5tYXJrdHlwZSxcbiAgICAgIGl0ZW1zID0gc2NlbmUuaXRlbXMsXG4gICAgICBwYXJlbnQsIGksIG47XG5cbiAgaWYgKGl0ZW1zKSB7XG4gICAgZm9yIChpPTAsIG49aXRlbXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgcGFyZW50ID0gdHlwZSA/ICdtYXJrJyA6ICdncm91cCc7XG4gICAgICBpdGVtc1tpXVtwYXJlbnRdID0gc2NlbmU7XG4gICAgICBpZiAoaXRlbXNbaV0uemluZGV4KSBpdGVtc1tpXVtwYXJlbnRdLnpkaXJ0eSA9IHRydWU7XG4gICAgICBpZiAoJ2dyb3VwJyA9PT0gKHR5cGUgfHwgcGFyZW50KSkgaW5pdGlhbGl6ZShpdGVtc1tpXSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKHR5cGUpIGJvdW5kTWFyayhzY2VuZSk7XG4gIHJldHVybiBzY2VuZTtcbn1cblxuZnVuY3Rpb24gU2NlbmVncmFwaChzY2VuZSkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMucm9vdCA9IHNjZW5lRnJvbUpTT04oc2NlbmUpO1xuICB9IGVsc2Uge1xuICAgIHRoaXMucm9vdCA9IGNyZWF0ZU1hcmsoe1xuICAgICAgbWFya3R5cGU6ICdncm91cCcsXG4gICAgICBuYW1lOiAncm9vdCcsXG4gICAgICByb2xlOiAnZnJhbWUnXG4gICAgfSk7XG4gICAgdGhpcy5yb290Lml0ZW1zID0gW25ldyBHcm91cEl0ZW0odGhpcy5yb290KV07XG4gIH1cbn1cblxudmFyIHByb3RvdHlwZSQ0MSA9IFNjZW5lZ3JhcGgucHJvdG90eXBlO1xuXG5wcm90b3R5cGUkNDEudG9KU09OID0gZnVuY3Rpb24oaW5kZW50KSB7XG4gIHJldHVybiBzY2VuZVRvSlNPTih0aGlzLnJvb3QsIGluZGVudCB8fCAwKTtcbn07XG5cbnByb3RvdHlwZSQ0MS5tYXJrID0gZnVuY3Rpb24obWFya2RlZiwgZ3JvdXAsIGluZGV4KSB7XG4gIGdyb3VwID0gZ3JvdXAgfHwgdGhpcy5yb290Lml0ZW1zWzBdO1xuICB2YXIgbWFyayA9IGNyZWF0ZU1hcmsobWFya2RlZiwgZ3JvdXApO1xuICBncm91cC5pdGVtc1tpbmRleF0gPSBtYXJrO1xuICBpZiAobWFyay56aW5kZXgpIG1hcmsuZ3JvdXAuemRpcnR5ID0gdHJ1ZTtcbiAgcmV0dXJuIG1hcms7XG59O1xuXG5mdW5jdGlvbiBjcmVhdGVNYXJrKGRlZiwgZ3JvdXApIHtcbiAgcmV0dXJuIHtcbiAgICBib3VuZHM6ICAgICAgbmV3IEJvdW5kcygpLFxuICAgIGNsaXA6ICAgICAgICAhIWRlZi5jbGlwLFxuICAgIGdyb3VwOiAgICAgICBncm91cCxcbiAgICBpbnRlcmFjdGl2ZTogZGVmLmludGVyYWN0aXZlID09PSBmYWxzZSA/IGZhbHNlIDogdHJ1ZSxcbiAgICBpdGVtczogICAgICAgW10sXG4gICAgbWFya3R5cGU6ICAgIGRlZi5tYXJrdHlwZSxcbiAgICBuYW1lOiAgICAgICAgZGVmLm5hbWUgfHwgdW5kZWZpbmVkLFxuICAgIHJvbGU6ICAgICAgICBkZWYucm9sZSB8fCB1bmRlZmluZWQsXG4gICAgemluZGV4OiAgICAgIGRlZi56aW5kZXggfHwgMFxuICB9O1xufVxuXG4vLyBjcmVhdGUgYSBuZXcgRE9NIGVsZW1lbnRcbmZ1bmN0aW9uIGRvbUNyZWF0ZShkb2MsIHRhZywgbnMpIHtcbiAgaWYgKCFkb2MgJiYgdHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJyAmJiBkb2N1bWVudC5jcmVhdGVFbGVtZW50KSB7XG4gICAgZG9jID0gZG9jdW1lbnQ7XG4gIH1cbiAgcmV0dXJuIGRvY1xuICAgID8gKG5zID8gZG9jLmNyZWF0ZUVsZW1lbnROUyhucywgdGFnKSA6IGRvYy5jcmVhdGVFbGVtZW50KHRhZykpXG4gICAgOiBudWxsO1xufVxuXG4vLyBmaW5kIGZpcnN0IGNoaWxkIGVsZW1lbnQgd2l0aCBtYXRjaGluZyB0YWdcbmZ1bmN0aW9uIGRvbUZpbmQoZWwsIHRhZykge1xuICB0YWcgPSB0YWcudG9Mb3dlckNhc2UoKTtcbiAgdmFyIG5vZGVzID0gZWwuY2hpbGROb2RlcywgaSA9IDAsIG4gPSBub2Rlcy5sZW5ndGg7XG4gIGZvciAoOyBpPG47ICsraSkgaWYgKG5vZGVzW2ldLnRhZ05hbWUudG9Mb3dlckNhc2UoKSA9PT0gdGFnKSB7XG4gICAgcmV0dXJuIG5vZGVzW2ldO1xuICB9XG59XG5cbi8vIHJldHJpZXZlIGNoaWxkIGVsZW1lbnQgYXQgZ2l2ZW4gaW5kZXhcbi8vIGNyZWF0ZSAmIGluc2VydCBpZiBkb2Vzbid0IGV4aXN0IG9yIGlmIHRhZ3MgZG8gbm90IG1hdGNoXG5mdW5jdGlvbiBkb21DaGlsZChlbCwgaW5kZXgsIHRhZywgbnMpIHtcbiAgdmFyIGEgPSBlbC5jaGlsZE5vZGVzW2luZGV4XSwgYjtcbiAgaWYgKCFhIHx8IGEudGFnTmFtZS50b0xvd2VyQ2FzZSgpICE9PSB0YWcudG9Mb3dlckNhc2UoKSkge1xuICAgIGIgPSBhIHx8IG51bGw7XG4gICAgYSA9IGRvbUNyZWF0ZShlbC5vd25lckRvY3VtZW50LCB0YWcsIG5zKTtcbiAgICBlbC5pbnNlcnRCZWZvcmUoYSwgYik7XG4gIH1cbiAgcmV0dXJuIGE7XG59XG5cbi8vIHJlbW92ZSBhbGwgY2hpbGQgZWxlbWVudHMgYXQgb3IgYWJvdmUgdGhlIGdpdmVuIGluZGV4XG5mdW5jdGlvbiBkb21DbGVhcihlbCwgaW5kZXgpIHtcbiAgdmFyIG5vZGVzID0gZWwuY2hpbGROb2RlcyxcbiAgICAgIGN1cnIgPSBub2Rlcy5sZW5ndGg7XG4gIHdoaWxlIChjdXJyID4gaW5kZXgpIGVsLnJlbW92ZUNoaWxkKG5vZGVzWy0tY3Vycl0pO1xuICByZXR1cm4gZWw7XG59XG5cbi8vIGdlbmVyYXRlIGNzcyBjbGFzcyBuYW1lIGZvciBtYXJrXG5mdW5jdGlvbiBjc3NDbGFzcyhtYXJrKSB7XG4gIHJldHVybiAnbWFyay0nICsgbWFyay5tYXJrdHlwZVxuICAgICsgKG1hcmsucm9sZSA/ICcgcm9sZS0nICsgbWFyay5yb2xlIDogJycpXG4gICAgKyAobWFyay5uYW1lID8gJyAnICsgbWFyay5uYW1lIDogJycpO1xufVxuXG5mdW5jdGlvbiBIYW5kbGVyKGN1c3RvbUxvYWRlcikge1xuICB0aGlzLl9hY3RpdmUgPSBudWxsO1xuICB0aGlzLl9oYW5kbGVycyA9IHt9O1xuICB0aGlzLl9sb2FkZXIgPSBjdXN0b21Mb2FkZXIgfHwgbG9hZGVyKCk7XG59XG5cbnZhciBwcm90b3R5cGUkNDIgPSBIYW5kbGVyLnByb3RvdHlwZTtcblxucHJvdG90eXBlJDQyLmluaXRpYWxpemUgPSBmdW5jdGlvbihlbCwgb3JpZ2luLCBvYmopIHtcbiAgdGhpcy5fZWwgPSBlbDtcbiAgdGhpcy5fb2JqID0gb2JqIHx8IG51bGw7XG4gIHJldHVybiB0aGlzLm9yaWdpbihvcmlnaW4pO1xufTtcblxucHJvdG90eXBlJDQyLmVsZW1lbnQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX2VsO1xufTtcblxucHJvdG90eXBlJDQyLm9yaWdpbiA9IGZ1bmN0aW9uKG9yaWdpbikge1xuICB0aGlzLl9vcmlnaW4gPSBvcmlnaW4gfHwgWzAsIDBdO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ0Mi5zY2VuZSA9IGZ1bmN0aW9uKHNjZW5lKSB7XG4gIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIHRoaXMuX3NjZW5lO1xuICB0aGlzLl9zY2VuZSA9IHNjZW5lO1xuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIGFkZCBhbiBldmVudCBoYW5kbGVyXG4vLyBzdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZVxucHJvdG90eXBlJDQyLm9uID0gZnVuY3Rpb24oLyp0eXBlLCBoYW5kbGVyKi8pIHt9O1xuXG4vLyByZW1vdmUgYW4gZXZlbnQgaGFuZGxlclxuLy8gc3ViY2xhc3NlcyBzaG91bGQgb3ZlcnJpZGVcbnByb3RvdHlwZSQ0Mi5vZmYgPSBmdW5jdGlvbigvKnR5cGUsIGhhbmRsZXIqLykge307XG5cbi8vIHV0aWxpdHkgbWV0aG9kIGZvciBmaW5kaW5nIGFycmF5IGluZGV4IG9mIHJlZ2lzdGVyZWQgaGFuZGxlclxuLy8gcmV0dXJucyAtMSBpZiBoYW5kbGVyIGlzIG5vdCByZWdpc3RlcmVkXG5wcm90b3R5cGUkNDIuX2hhbmRsZXJJbmRleCA9IGZ1bmN0aW9uKGgsIHR5cGUsIGhhbmRsZXIpIHtcbiAgZm9yICh2YXIgaSA9IGggPyBoLmxlbmd0aCA6IDA7IC0taT49MDspIHtcbiAgICBpZiAoaFtpXS50eXBlID09PSB0eXBlICYmICFoYW5kbGVyIHx8IGhbaV0uaGFuZGxlciA9PT0gaGFuZGxlcikge1xuICAgICAgcmV0dXJuIGk7XG4gICAgfVxuICB9XG4gIHJldHVybiAtMTtcbn07XG5cbi8vIHJldHVybiBhbiBhcnJheSB3aXRoIGFsbCByZWdpc3RlcmVkIGV2ZW50IGhhbmRsZXJzXG5wcm90b3R5cGUkNDIuaGFuZGxlcnMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGggPSB0aGlzLl9oYW5kbGVycywgYSA9IFtdLCBrO1xuICBmb3IgKGsgaW4gaCkgeyBhLnB1c2guYXBwbHkoYSwgaFtrXSk7IH1cbiAgcmV0dXJuIGE7XG59O1xuXG5wcm90b3R5cGUkNDIuZXZlbnROYW1lID0gZnVuY3Rpb24obmFtZSkge1xuICB2YXIgaSA9IG5hbWUuaW5kZXhPZignLicpO1xuICByZXR1cm4gaSA8IDAgPyBuYW1lIDogbmFtZS5zbGljZSgwLGkpO1xufTtcblxucHJvdG90eXBlJDQyLmhhbmRsZUhyZWYgPSBmdW5jdGlvbihldmVudCwgaXRlbSwgaHJlZikge1xuICB0aGlzLl9sb2FkZXJcbiAgICAuc2FuaXRpemUoaHJlZiwge2NvbnRleHQ6J2hyZWYnfSlcbiAgICAudGhlbihmdW5jdGlvbihvcHQpIHtcbiAgICAgIHZhciBlID0gbmV3IE1vdXNlRXZlbnQoZXZlbnQudHlwZSwgZXZlbnQpLFxuICAgICAgICAgIGEgPSBkb21DcmVhdGUobnVsbCwgJ2EnKTtcbiAgICAgIGZvciAodmFyIG5hbWUgaW4gb3B0KSBhLnNldEF0dHJpYnV0ZShuYW1lLCBvcHRbbmFtZV0pO1xuICAgICAgYS5kaXNwYXRjaEV2ZW50KGUpO1xuICAgIH0pXG4gICAgLmNhdGNoKGZ1bmN0aW9uKCkgeyAvKiBkbyBub3RoaW5nICovIH0pO1xufTtcblxucHJvdG90eXBlJDQyLmhhbmRsZVRvb2x0aXAgPSBmdW5jdGlvbihldmVudCwgaXRlbSwgdG9vbHRpcFRleHQpIHtcbiAgdGhpcy5fZWwuc2V0QXR0cmlidXRlKCd0aXRsZScsIHRvb2x0aXBUZXh0IHx8ICcnKTtcbn07XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IFJlbmRlcmVyIGluc3RhbmNlLlxuICogQHBhcmFtIHtvYmplY3R9IFtsb2FkZXJdIC0gT3B0aW9uYWwgbG9hZGVyIGluc3RhbmNlIGZvclxuICogICBpbWFnZSBhbmQgaHJlZiBVUkwgc2FuaXRpemF0aW9uLiBJZiBub3Qgc3BlY2lmaWVkLCBhXG4gKiAgIHN0YW5kYXJkIGxvYWRlciBpbnN0YW5jZSB3aWxsIGJlIGdlbmVyYXRlZC5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBSZW5kZXJlcihsb2FkZXIpIHtcbiAgdGhpcy5fZWwgPSBudWxsO1xuICB0aGlzLl9iZ2NvbG9yID0gbnVsbDtcbiAgdGhpcy5fbG9hZGVyID0gbmV3IFJlc291cmNlTG9hZGVyKGxvYWRlcik7XG59XG5cbnZhciBwcm90b3R5cGUkNDMgPSBSZW5kZXJlci5wcm90b3R5cGU7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBhIG5ldyBSZW5kZXJlciBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7RE9NRWxlbWVudH0gZWwgLSBUaGUgY29udGFpbmluZyBET00gZWxlbWVudCBmb3IgdGhlIGRpc3BsYXkuXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBUaGUgY29vcmRpbmF0ZSB3aWR0aCBvZiB0aGUgZGlzcGxheSwgaW4gcGl4ZWxzLlxuICogQHBhcmFtIHtudW1iZXJ9IGhlaWdodCAtIFRoZSBjb29yZGluYXRlIGhlaWdodCBvZiB0aGUgZGlzcGxheSwgaW4gcGl4ZWxzLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBvcmlnaW4gLSBUaGUgb3JpZ2luIG9mIHRoZSBkaXNwbGF5LCBpbiBwaXhlbHMuXG4gKiAgIFRoZSBjb29yZGluYXRlIHN5c3RlbSB3aWxsIGJlIHRyYW5zbGF0ZWQgdG8gdGhpcyBwb2ludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2NhbGVGYWN0b3I9MV0gLSBPcHRpb25hbCBzY2FsZUZhY3RvciBieSB3aGljaCB0byBtdWx0aXBseVxuICogICB0aGUgd2lkdGggYW5kIGhlaWdodCB0byBkZXRlcm1pbmUgdGhlIGZpbmFsIHBpeGVsIHNpemUuXG4gKiBAcmV0dXJuIHtSZW5kZXJlcn0gLSBUaGlzIHJlbmRlcmVyIGluc3RhbmNlO1xuICovXG5wcm90b3R5cGUkNDMuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0LCBvcmlnaW4sIHNjYWxlRmFjdG9yKSB7XG4gIHRoaXMuX2VsID0gZWw7XG4gIHJldHVybiB0aGlzLnJlc2l6ZSh3aWR0aCwgaGVpZ2h0LCBvcmlnaW4sIHNjYWxlRmFjdG9yKTtcbn07XG5cbi8qKlxuICogUmV0dXJucyB0aGUgcGFyZW50IGNvbnRhaW5lciBlbGVtZW50IGZvciBhIHZpc3VhbGl6YXRpb24uXG4gKiBAcmV0dXJuIHtET01FbGVtZW50fSAtIFRoZSBjb250YWluaW5nIERPTSBlbGVtZW50LlxuICovXG5wcm90b3R5cGUkNDMuZWxlbWVudCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fZWw7XG59O1xuXG4vKipcbiAqIFJldHVybnMgdGhlIHNjZW5lIGVsZW1lbnQgKGUuZy4sIGNhbnZhcyBvciBTVkcpIG9mIHRoZSB2aXN1YWxpemF0aW9uXG4gKiBTdWJjbGFzc2VzIG11c3Qgb3ZlcnJpZGUgaWYgdGhlIGZpcnN0IGNoaWxkIGlzIG5vdCB0aGUgc2NlbmUgZWxlbWVudC5cbiAqIEByZXR1cm4ge0RPTUVsZW1lbnR9IC0gVGhlIHNjZW5lIChlLmcuLCBjYW52YXMgb3IgU1ZHKSBlbGVtZW50LlxuICovXG5wcm90b3R5cGUkNDMuc2NlbmUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX2VsICYmIHRoaXMuX2VsLmZpcnN0Q2hpbGQ7XG59O1xuXG4vKipcbiAqIEdldCAvIHNldCB0aGUgYmFja2dyb3VuZCBjb2xvci5cbiAqL1xucHJvdG90eXBlJDQzLmJhY2tncm91bmQgPSBmdW5jdGlvbihiZ2NvbG9yKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAwKSByZXR1cm4gdGhpcy5fYmdjb2xvcjtcbiAgdGhpcy5fYmdjb2xvciA9IGJnY29sb3I7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLyoqXG4gKiBSZXNpemUgdGhlIGRpc3BsYXkuXG4gKiBAcGFyYW0ge251bWJlcn0gd2lkdGggLSBUaGUgbmV3IGNvb3JkaW5hdGUgd2lkdGggb2YgdGhlIGRpc3BsYXksIGluIHBpeGVscy5cbiAqIEBwYXJhbSB7bnVtYmVyfSBoZWlnaHQgLSBUaGUgbmV3IGNvb3JkaW5hdGUgaGVpZ2h0IG9mIHRoZSBkaXNwbGF5LCBpbiBwaXhlbHMuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IG9yaWdpbiAtIFRoZSBuZXcgb3JpZ2luIG9mIHRoZSBkaXNwbGF5LCBpbiBwaXhlbHMuXG4gKiAgIFRoZSBjb29yZGluYXRlIHN5c3RlbSB3aWxsIGJlIHRyYW5zbGF0ZWQgdG8gdGhpcyBwb2ludC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbc2NhbGVGYWN0b3I9MV0gLSBPcHRpb25hbCBzY2FsZUZhY3RvciBieSB3aGljaCB0byBtdWx0aXBseVxuICogICB0aGUgd2lkdGggYW5kIGhlaWdodCB0byBkZXRlcm1pbmUgdGhlIGZpbmFsIHBpeGVsIHNpemUuXG4gKiBAcmV0dXJuIHtSZW5kZXJlcn0gLSBUaGlzIHJlbmRlcmVyIGluc3RhbmNlO1xuICovXG5wcm90b3R5cGUkNDMucmVzaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCwgb3JpZ2luLCBzY2FsZUZhY3Rvcikge1xuICB0aGlzLl93aWR0aCA9IHdpZHRoO1xuICB0aGlzLl9oZWlnaHQgPSBoZWlnaHQ7XG4gIHRoaXMuX29yaWdpbiA9IG9yaWdpbiB8fCBbMCwgMF07XG4gIHRoaXMuX3NjYWxlID0gc2NhbGVGYWN0b3IgfHwgMTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlcG9ydCBhIGRpcnR5IGl0ZW0gd2hvc2UgYm91bmRzIHNob3VsZCBiZSByZWRyYXduLlxuICogVGhpcyBiYXNlIGNsYXNzIG1ldGhvZCBkb2VzIG5vdGhpbmcuIFN1YmNsYXNzZXMgdGhhdCBwZXJmb3JtXG4gKiBpbmNyZW1lbnRhbCBzaG91bGQgaW1wbGVtZW50IHRoaXMgbWV0aG9kLlxuICogQHBhcmFtIHtJdGVtfSBpdGVtIC0gVGhlIGRpcnR5IGl0ZW0gd2hvc2UgYm91bmRzIHNob3VsZCBiZSByZWRyYXduLlxuICovXG5wcm90b3R5cGUkNDMuZGlydHkgPSBmdW5jdGlvbigvKml0ZW0qLykge1xufTtcblxuLyoqXG4gKiBSZW5kZXIgYW4gaW5wdXQgc2NlbmVncmFwaCwgcG90ZW50aWFsbHkgd2l0aCBhIHNldCBvZiBkaXJ0eSBpdGVtcy5cbiAqIFRoaXMgbWV0aG9kIHdpbGwgcGVyZm9ybSBhbiBpbW1lZGlhdGUgcmVuZGVyaW5nIHdpdGggYXZhaWxhYmxlIHJlc291cmNlcy5cbiAqIFRoZSByZW5kZXJlciBtYXkgYWxzbyBuZWVkIHRvIHBlcmZvcm0gaW1hZ2UgbG9hZGluZyB0byBwZXJmb3JtIGEgY29tcGxldGVcbiAqIHJlbmRlci4gVGhpcyBwcm9jZXNzIGNhbiBsZWFkIHRvIGFzeW5jaHJvbm91cyByZS1yZW5kZXJpbmcgb2YgdGhlIHNjZW5lXG4gKiBhZnRlciB0aGlzIG1ldGhvZCByZXR1cm5zLiBUbyByZWNlaXZlIG5vdGlmaWNhdGlvbiB3aGVuIHJlbmRlcmluZyBpc1xuICogY29tcGxldGUsIHVzZSB0aGUgcmVuZGVyQXN5bmMgbWV0aG9kIGluc3RlYWQuXG4gKiBAcGFyYW0ge29iamVjdH0gc2NlbmUgLSBUaGUgcm9vdCBtYXJrIG9mIGEgc2NlbmVncmFwaCB0byByZW5kZXIuXG4gKiBAcmV0dXJuIHtSZW5kZXJlcn0gLSBUaGlzIHJlbmRlcmVyIGluc3RhbmNlLlxuICovXG5wcm90b3R5cGUkNDMucmVuZGVyID0gZnVuY3Rpb24oc2NlbmUpIHtcbiAgdmFyIHIgPSB0aGlzO1xuXG4gIC8vIGJpbmQgYXJndW1lbnRzIGludG8gYSByZW5kZXIgY2FsbCwgYW5kIGNhY2hlIGl0XG4gIC8vIHRoaXMgZnVuY3Rpb24gbWF5IGJlIHN1YnNlcXVlbnRseSBjYWxsZWQgZm9yIGFzeW5jIHJlZHJhd1xuICByLl9jYWxsID0gZnVuY3Rpb24oKSB7IHIuX3JlbmRlcihzY2VuZSk7IH07XG5cbiAgLy8gaW52b2tlIHRoZSByZW5kZXJlclxuICByLl9jYWxsKCk7XG5cbiAgLy8gY2xlYXIgdGhlIGNhY2hlZCBjYWxsIGZvciBnYXJiYWdlIGNvbGxlY3Rpb25cbiAgLy8gYXN5bmMgcmVkcmF3cyB3aWxsIHN0YXNoIHRoZWlyIG93biBjb3B5XG4gIHIuX2NhbGwgPSBudWxsO1xuXG4gIHJldHVybiByO1xufTtcblxuLyoqXG4gKiBJbnRlcm5hbCByZW5kZXJpbmcgbWV0aG9kLiBSZW5kZXJlciBzdWJjbGFzc2VzIHNob3VsZCBvdmVycmlkZSB0aGlzXG4gKiBtZXRob2QgdG8gYWN0dWFsbHkgcGVyZm9ybSByZW5kZXJpbmcuXG4gKiBAcGFyYW0ge29iamVjdH0gc2NlbmUgLSBUaGUgcm9vdCBtYXJrIG9mIGEgc2NlbmVncmFwaCB0byByZW5kZXIuXG4gKi9cbnByb3RvdHlwZSQ0My5fcmVuZGVyID0gZnVuY3Rpb24oLypzY2VuZSovKSB7XG4gIC8vIHN1YmNsYXNzZXMgdG8gb3ZlcnJpZGVcbn07XG5cbi8qKlxuICogQXN5bmNocm9ub3VzIHJlbmRlcmluZyBtZXRob2QuIFNpbWlsYXIgdG8gcmVuZGVyLCBidXQgcmV0dXJucyBhIFByb21pc2VcbiAqIHRoYXQgcmVzb2x2ZXMgd2hlbiBhbGwgcmVuZGVyaW5nIGlzIGNvbXBsZXRlZC4gU29tZXRpbWVzIGEgcmVuZGVyZXIgbXVzdFxuICogcGVyZm9ybSBpbWFnZSBsb2FkaW5nIHRvIGdldCBhIGNvbXBsZXRlIHJlbmRlcmluZy4gVGhlIHJldHVybmVkXG4gKiBQcm9taXNlIHdpbGwgbm90IHJlc29sdmUgdW50aWwgdGhpcyBwcm9jZXNzIGNvbXBsZXRlcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBzY2VuZSAtIFRoZSByb290IG1hcmsgb2YgYSBzY2VuZWdyYXBoIHRvIHJlbmRlci5cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgd2hlbiByZW5kZXJpbmcgaXMgY29tcGxldGUuXG4gKi9cbnByb3RvdHlwZSQ0My5yZW5kZXJBc3luYyA9IGZ1bmN0aW9uKHNjZW5lKSB7XG4gIHZhciByID0gdGhpcy5yZW5kZXIoc2NlbmUpO1xuICByZXR1cm4gdGhpcy5fcmVhZHlcbiAgICA/IHRoaXMuX3JlYWR5LnRoZW4oZnVuY3Rpb24oKSB7IHJldHVybiByOyB9KVxuICAgIDogUHJvbWlzZS5yZXNvbHZlKHIpO1xufTtcblxuLyoqXG4gKiBJbnRlcm5hbCBtZXRob2QgZm9yIGFzeW5jaHJvbm91cyByZXNvdXJjZSBsb2FkaW5nLlxuICogUHJveGllcyBtZXRob2QgY2FsbHMgdG8gdGhlIEltYWdlTG9hZGVyLCBhbmQgdHJhY2tzIGxvYWRpbmdcbiAqIHByb2dyZXNzIHRvIGludm9rZSBhIHJlLXJlbmRlciBvbmNlIGNvbXBsZXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IG1ldGhvZCAtIFRoZSBtZXRob2QgbmFtZSB0byBpbnZva2Ugb24gdGhlIEltYWdlTG9hZGVyLlxuICogQHBhcmFtIHtzdHJpbmd9IHVyaSAtIFRoZSBVUkkgZm9yIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UuXG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSByZXF1ZXN0ZWQgcmVzb3VyY2UuXG4gKi9cbnByb3RvdHlwZSQ0My5fbG9hZCA9IGZ1bmN0aW9uKG1ldGhvZCwgdXJpKSB7XG4gIHZhciByID0gdGhpcyxcbiAgICAgIHAgPSByLl9sb2FkZXJbbWV0aG9kXSh1cmkpO1xuXG4gIGlmICghci5fcmVhZHkpIHtcbiAgICAvLyByZS1yZW5kZXIgdGhlIHNjZW5lIHdoZW4gbG9hZGluZyBjb21wbGV0ZXNcbiAgICB2YXIgY2FsbCA9IHIuX2NhbGw7XG4gICAgci5fcmVhZHkgPSByLl9sb2FkZXIucmVhZHkoKVxuICAgICAgLnRoZW4oZnVuY3Rpb24ocmVkcmF3KSB7XG4gICAgICAgIGlmIChyZWRyYXcpIGNhbGwoKTtcbiAgICAgICAgci5fcmVhZHkgPSBudWxsO1xuICAgICAgfSk7XG4gIH1cblxuICByZXR1cm4gcDtcbn07XG5cbi8qKlxuICogU2FuaXRpemUgYSBVUkwgdG8gaW5jbHVkZSBhcyBhIGh5cGVybGluayBpbiB0aGUgcmVuZGVyZWQgc2NlbmUuXG4gKiBUaGlzIG1ldGhvZCBwcm94aWVzIGEgY2FsbCB0byBJbWFnZUxvYWRlci5zYW5pdGl6ZVVSTCwgYnV0IGFsc28gdHJhY2tzXG4gKiBpbWFnZSBsb2FkaW5nIHByb2dyZXNzIGFuZCBpbnZva2VzIGEgcmUtcmVuZGVyIG9uY2UgY29tcGxldGUuXG4gKiBAcGFyYW0ge3N0cmluZ30gdXJpIC0gVGhlIFVSSSBzdHJpbmcgdG8gc2FuaXRpemUuXG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgUHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIHRoZSBzYW5pdGl6ZWQgVVJMLlxuICovXG5wcm90b3R5cGUkNDMuc2FuaXRpemVVUkwgPSBmdW5jdGlvbih1cmkpIHtcbiAgcmV0dXJuIHRoaXMuX2xvYWQoJ3Nhbml0aXplVVJMJywgdXJpKTtcbn07XG5cbi8qKlxuICogUmVxdWVzdHMgYW4gaW1hZ2UgdG8gaW5jbHVkZSBpbiB0aGUgcmVuZGVyZWQgc2NlbmUuXG4gKiBUaGlzIG1ldGhvZCBwcm94aWVzIGEgY2FsbCB0byBJbWFnZUxvYWRlci5sb2FkSW1hZ2UsIGJ1dCBhbHNvIHRyYWNrc1xuICogaW1hZ2UgbG9hZGluZyBwcm9ncmVzcyBhbmQgaW52b2tlcyBhIHJlLXJlbmRlciBvbmNlIGNvbXBsZXRlLlxuICogQHBhcmFtIHtzdHJpbmd9IHVyaSAtIFRoZSBVUkkgc3RyaW5nIG9mIHRoZSBpbWFnZS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gdGhlIGxvYWRlZCBJbWFnZS5cbiAqL1xucHJvdG90eXBlJDQzLmxvYWRJbWFnZSA9IGZ1bmN0aW9uKHVyaSkge1xuICByZXR1cm4gdGhpcy5fbG9hZCgnbG9hZEltYWdlJywgdXJpKTtcbn07XG5cbnZhciBwb2ludCQ0ID0gZnVuY3Rpb24oZXZlbnQsIGVsKSB7XG4gIHZhciByZWN0ID0gZWwuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gIHJldHVybiBbXG4gICAgZXZlbnQuY2xpZW50WCAtIHJlY3QubGVmdCAtIChlbC5jbGllbnRMZWZ0IHx8IDApLFxuICAgIGV2ZW50LmNsaWVudFkgLSByZWN0LnRvcCAtIChlbC5jbGllbnRUb3AgfHwgMClcbiAgXTtcbn07XG5cbmZ1bmN0aW9uIENhbnZhc0hhbmRsZXIobG9hZGVyKSB7XG4gIEhhbmRsZXIuY2FsbCh0aGlzLCBsb2FkZXIpO1xuICB0aGlzLl9kb3duID0gbnVsbDtcbiAgdGhpcy5fdG91Y2ggPSBudWxsO1xuICB0aGlzLl9maXJzdCA9IHRydWU7XG59XG5cbnZhciBwcm90b3R5cGUkNDQgPSBpbmhlcml0cyhDYW52YXNIYW5kbGVyLCBIYW5kbGVyKTtcblxucHJvdG90eXBlJDQ0LmluaXRpYWxpemUgPSBmdW5jdGlvbihlbCwgb3JpZ2luLCBvYmopIHtcbiAgLy8gYWRkIGV2ZW50IGxpc3RlbmVyc1xuICB2YXIgY2FudmFzID0gdGhpcy5fY2FudmFzID0gZWwgJiYgZG9tRmluZChlbCwgJ2NhbnZhcycpO1xuICBpZiAoY2FudmFzKSB7XG4gICAgdmFyIHRoYXQgPSB0aGlzO1xuICAgIHRoaXMuZXZlbnRzLmZvckVhY2goZnVuY3Rpb24odHlwZSkge1xuICAgICAgY2FudmFzLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgZnVuY3Rpb24oZXZ0KSB7XG4gICAgICAgIGlmIChwcm90b3R5cGUkNDRbdHlwZV0pIHtcbiAgICAgICAgICBwcm90b3R5cGUkNDRbdHlwZV0uY2FsbCh0aGF0LCBldnQpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIHRoYXQuZmlyZSh0eXBlLCBldnQpO1xuICAgICAgICB9XG4gICAgICB9KTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBIYW5kbGVyLnByb3RvdHlwZS5pbml0aWFsaXplLmNhbGwodGhpcywgZWwsIG9yaWdpbiwgb2JqKTtcbn07XG5cbnByb3RvdHlwZSQ0NC5jYW52YXMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX2NhbnZhcztcbn07XG5cbi8vIHJldHJpZXZlIHRoZSBjdXJyZW50IGNhbnZhcyBjb250ZXh0XG5wcm90b3R5cGUkNDQuY29udGV4dCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fY2FudmFzLmdldENvbnRleHQoJzJkJyk7XG59O1xuXG4vLyBzdXBwb3J0ZWQgZXZlbnRzXG5wcm90b3R5cGUkNDQuZXZlbnRzID0gW1xuICAna2V5ZG93bicsXG4gICdrZXlwcmVzcycsXG4gICdrZXl1cCcsXG4gICdkcmFnZW50ZXInLFxuICAnZHJhZ2xlYXZlJyxcbiAgJ2RyYWdvdmVyJyxcbiAgJ21vdXNlZG93bicsXG4gICdtb3VzZXVwJyxcbiAgJ21vdXNlbW92ZScsXG4gICdtb3VzZW91dCcsXG4gICdtb3VzZW92ZXInLFxuICAnY2xpY2snLFxuICAnZGJsY2xpY2snLFxuICAnd2hlZWwnLFxuICAnbW91c2V3aGVlbCcsXG4gICd0b3VjaHN0YXJ0JyxcbiAgJ3RvdWNobW92ZScsXG4gICd0b3VjaGVuZCdcbl07XG5cbi8vIHRvIGtlZXAgb2xkIHZlcnNpb25zIG9mIGZpcmVmb3ggaGFwcHlcbnByb3RvdHlwZSQ0NC5ET01Nb3VzZVNjcm9sbCA9IGZ1bmN0aW9uKGV2dCkge1xuICB0aGlzLmZpcmUoJ21vdXNld2hlZWwnLCBldnQpO1xufTtcblxuZnVuY3Rpb24gbW92ZShtb3ZlRXZlbnQsIG92ZXJFdmVudCwgb3V0RXZlbnQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGV2dCkge1xuICAgIHZhciBhID0gdGhpcy5fYWN0aXZlLFxuICAgICAgICBwID0gdGhpcy5waWNrRXZlbnQoZXZ0KTtcblxuICAgIGlmIChwID09PSBhKSB7XG4gICAgICAvLyBhY3RpdmUgaXRlbSBhbmQgcGlja2VkIGl0ZW0gYXJlIHRoZSBzYW1lXG4gICAgICB0aGlzLmZpcmUobW92ZUV2ZW50LCBldnQpOyAvLyBmaXJlIG1vdmVcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gYWN0aXZlIGl0ZW0gYW5kIHBpY2tlZCBpdGVtIGFyZSBkaWZmZXJlbnRcbiAgICAgIGlmICghYSB8fCAhYS5leGl0KSB7XG4gICAgICAgIC8vIGZpcmUgb3V0IGZvciBwcmlvciBhY3RpdmUgaXRlbVxuICAgICAgICAvLyBzdXBwcmVzcyBpZiBhY3RpdmUgaXRlbSB3YXMgcmVtb3ZlZCBmcm9tIHNjZW5lXG4gICAgICAgIHRoaXMuZmlyZShvdXRFdmVudCwgZXZ0KTtcbiAgICAgIH1cbiAgICAgIHRoaXMuX2FjdGl2ZSA9IHA7ICAgICAgICAgIC8vIHNldCBuZXcgYWN0aXZlIGl0ZW1cbiAgICAgIHRoaXMuZmlyZShvdmVyRXZlbnQsIGV2dCk7IC8vIGZpcmUgb3ZlciBmb3IgbmV3IGFjdGl2ZSBpdGVtXG4gICAgICB0aGlzLmZpcmUobW92ZUV2ZW50LCBldnQpOyAvLyBmaXJlIG1vdmUgZm9yIG5ldyBhY3RpdmUgaXRlbVxuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gaW5hY3RpdmUodHlwZSkge1xuICByZXR1cm4gZnVuY3Rpb24oZXZ0KSB7XG4gICAgdGhpcy5maXJlKHR5cGUsIGV2dCk7XG4gICAgdGhpcy5fYWN0aXZlID0gbnVsbDtcbiAgfTtcbn1cblxucHJvdG90eXBlJDQ0Lm1vdXNlbW92ZSA9IG1vdmUoJ21vdXNlbW92ZScsICdtb3VzZW92ZXInLCAnbW91c2VvdXQnKTtcbnByb3RvdHlwZSQ0NC5kcmFnb3ZlciAgPSBtb3ZlKCdkcmFnb3ZlcicsICdkcmFnZW50ZXInLCAnZHJhZ2xlYXZlJyk7XG5cbnByb3RvdHlwZSQ0NC5tb3VzZW91dCAgPSBpbmFjdGl2ZSgnbW91c2VvdXQnKTtcbnByb3RvdHlwZSQ0NC5kcmFnbGVhdmUgPSBpbmFjdGl2ZSgnZHJhZ2xlYXZlJyk7XG5cbnByb3RvdHlwZSQ0NC5tb3VzZWRvd24gPSBmdW5jdGlvbihldnQpIHtcbiAgdGhpcy5fZG93biA9IHRoaXMuX2FjdGl2ZTtcbiAgdGhpcy5maXJlKCdtb3VzZWRvd24nLCBldnQpO1xufTtcblxucHJvdG90eXBlJDQ0LmNsaWNrID0gZnVuY3Rpb24oZXZ0KSB7XG4gIGlmICh0aGlzLl9kb3duID09PSB0aGlzLl9hY3RpdmUpIHtcbiAgICB0aGlzLmZpcmUoJ2NsaWNrJywgZXZ0KTtcbiAgICB0aGlzLl9kb3duID0gbnVsbDtcbiAgfVxufTtcblxucHJvdG90eXBlJDQ0LnRvdWNoc3RhcnQgPSBmdW5jdGlvbihldnQpIHtcbiAgdGhpcy5fdG91Y2ggPSB0aGlzLnBpY2tFdmVudChldnQuY2hhbmdlZFRvdWNoZXNbMF0pO1xuXG4gIGlmICh0aGlzLl9maXJzdCkge1xuICAgIHRoaXMuX2FjdGl2ZSA9IHRoaXMuX3RvdWNoO1xuICAgIHRoaXMuX2ZpcnN0ID0gZmFsc2U7XG4gIH1cblxuICB0aGlzLmZpcmUoJ3RvdWNoc3RhcnQnLCBldnQsIHRydWUpO1xufTtcblxucHJvdG90eXBlJDQ0LnRvdWNobW92ZSA9IGZ1bmN0aW9uKGV2dCkge1xuICB0aGlzLmZpcmUoJ3RvdWNobW92ZScsIGV2dCwgdHJ1ZSk7XG59O1xuXG5wcm90b3R5cGUkNDQudG91Y2hlbmQgPSBmdW5jdGlvbihldnQpIHtcbiAgdGhpcy5maXJlKCd0b3VjaGVuZCcsIGV2dCwgdHJ1ZSk7XG4gIHRoaXMuX3RvdWNoID0gbnVsbDtcbn07XG5cbi8vIGZpcmUgYW4gZXZlbnRcbnByb3RvdHlwZSQ0NC5maXJlID0gZnVuY3Rpb24odHlwZSwgZXZ0LCB0b3VjaCkge1xuICB2YXIgYSA9IHRvdWNoID8gdGhpcy5fdG91Y2ggOiB0aGlzLl9hY3RpdmUsXG4gICAgICBoID0gdGhpcy5faGFuZGxlcnNbdHlwZV0sIGksIGxlbjtcblxuICAvLyBpZiBoeXBlcmxpbmtlZCwgaGFuZGxlIGxpbmsgZmlyc3RcbiAgaWYgKHR5cGUgPT09ICdjbGljaycgJiYgYSAmJiBhLmhyZWYpIHtcbiAgICB0aGlzLmhhbmRsZUhyZWYoZXZ0LCBhLCBhLmhyZWYpO1xuICB9IGVsc2UgaWYgKCh0eXBlID09PSAnbW91c2VvdmVyJyB8fCB0eXBlID09PSAnbW91c2VvdXQnKSAmJiBhICYmIGEudG9vbHRpcCkge1xuICAgIHRoaXMuaGFuZGxlVG9vbHRpcChldnQsIGEsIHR5cGUgPT09ICdtb3VzZW92ZXInID8gYS50b29sdGlwIDogbnVsbCk7XG4gIH1cblxuICAvLyBpbnZva2UgYWxsIHJlZ2lzdGVyZWQgaGFuZGxlcnNcbiAgaWYgKGgpIHtcbiAgICBldnQudmVnYVR5cGUgPSB0eXBlO1xuICAgIGZvciAoaT0wLCBsZW49aC5sZW5ndGg7IGk8bGVuOyArK2kpIHtcbiAgICAgIGhbaV0uaGFuZGxlci5jYWxsKHRoaXMuX29iaiwgZXZ0LCBhKTtcbiAgICB9XG4gIH1cbn07XG5cbi8vIGFkZCBhbiBldmVudCBoYW5kbGVyXG5wcm90b3R5cGUkNDQub24gPSBmdW5jdGlvbih0eXBlLCBoYW5kbGVyKSB7XG4gIHZhciBuYW1lID0gdGhpcy5ldmVudE5hbWUodHlwZSksXG4gICAgICBoID0gdGhpcy5faGFuZGxlcnMsXG4gICAgICBpID0gdGhpcy5faGFuZGxlckluZGV4KGhbbmFtZV0sIHR5cGUsIGhhbmRsZXIpO1xuXG4gIGlmIChpIDwgMCkge1xuICAgIChoW25hbWVdIHx8IChoW25hbWVdID0gW10pKS5wdXNoKHtcbiAgICAgIHR5cGU6ICAgIHR5cGUsXG4gICAgICBoYW5kbGVyOiBoYW5kbGVyXG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIHJlbW92ZSBhbiBldmVudCBoYW5kbGVyXG5wcm90b3R5cGUkNDQub2ZmID0gZnVuY3Rpb24odHlwZSwgaGFuZGxlcikge1xuICB2YXIgbmFtZSA9IHRoaXMuZXZlbnROYW1lKHR5cGUpLFxuICAgICAgaCA9IHRoaXMuX2hhbmRsZXJzW25hbWVdLFxuICAgICAgaSA9IHRoaXMuX2hhbmRsZXJJbmRleChoLCB0eXBlLCBoYW5kbGVyKTtcblxuICBpZiAoaSA+PSAwKSB7XG4gICAgaC5zcGxpY2UoaSwgMSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ0NC5waWNrRXZlbnQgPSBmdW5jdGlvbihldnQpIHtcbiAgdmFyIHAgPSBwb2ludCQ0KGV2dCwgdGhpcy5fY2FudmFzKSxcbiAgICAgIG8gPSB0aGlzLl9vcmlnaW47XG4gIHJldHVybiB0aGlzLnBpY2sodGhpcy5fc2NlbmUsIHBbMF0sIHBbMV0sIHBbMF0gLSBvWzBdLCBwWzFdIC0gb1sxXSk7XG59O1xuXG4vLyBmaW5kIHRoZSBzY2VuZWdyYXBoIGl0ZW0gYXQgdGhlIGN1cnJlbnQgbW91c2UgcG9zaXRpb25cbi8vIHgsIHkgLS0gdGhlIGFic29sdXRlIHgsIHkgbW91c2UgY29vcmRpbmF0ZXMgb24gdGhlIGNhbnZhcyBlbGVtZW50XG4vLyBneCwgZ3kgLS0gdGhlIHJlbGF0aXZlIGNvb3JkaW5hdGVzIHdpdGhpbiB0aGUgY3VycmVudCBncm91cFxucHJvdG90eXBlJDQ0LnBpY2sgPSBmdW5jdGlvbihzY2VuZSwgeCwgeSwgZ3gsIGd5KSB7XG4gIHZhciBnID0gdGhpcy5jb250ZXh0KCksXG4gICAgICBtYXJrID0gbWFya3Nbc2NlbmUubWFya3R5cGVdO1xuICByZXR1cm4gbWFyay5waWNrLmNhbGwodGhpcywgZywgc2NlbmUsIHgsIHksIGd4LCBneSk7XG59O1xuXG52YXIgY2xpcCQxID0gZnVuY3Rpb24oY29udGV4dCwgc2NlbmUpIHtcbiAgdmFyIGNsaXAgPSBzY2VuZS5jbGlwO1xuXG4gIGNvbnRleHQuc2F2ZSgpO1xuICBjb250ZXh0LmJlZ2luUGF0aCgpO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGNsaXApKSB7XG4gICAgY2xpcChjb250ZXh0KTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgZ3JvdXAgPSBzY2VuZS5ncm91cDtcbiAgICBjb250ZXh0LnJlY3QoMCwgMCwgZ3JvdXAud2lkdGggfHwgMCwgZ3JvdXAuaGVpZ2h0IHx8IDApO1xuICB9XG5cbiAgY29udGV4dC5jbGlwKCk7XG59O1xuXG52YXIgZGV2aWNlUGl4ZWxSYXRpbyA9IHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnXG4gID8gd2luZG93LmRldmljZVBpeGVsUmF0aW8gfHwgMSA6IDE7XG5cbnZhciByZXNpemUgPSBmdW5jdGlvbihjYW52YXMsIHdpZHRoLCBoZWlnaHQsIG9yaWdpbiwgc2NhbGVGYWN0b3IpIHtcbiAgdmFyIGluRE9NID0gdHlwZW9mIEhUTUxFbGVtZW50ICE9PSAndW5kZWZpbmVkJ1xuICAgICYmIGNhbnZhcyBpbnN0YW5jZW9mIEhUTUxFbGVtZW50XG4gICAgJiYgY2FudmFzLnBhcmVudE5vZGUgIT0gbnVsbDtcblxuICB2YXIgY29udGV4dCA9IGNhbnZhcy5nZXRDb250ZXh0KCcyZCcpLFxuICAgICAgcmF0aW8gPSBpbkRPTSA/IGRldmljZVBpeGVsUmF0aW8gOiBzY2FsZUZhY3RvcjtcblxuICBjYW52YXMud2lkdGggPSB3aWR0aCAqIHJhdGlvO1xuICBjYW52YXMuaGVpZ2h0ID0gaGVpZ2h0ICogcmF0aW87XG5cbiAgaWYgKGluRE9NICYmIHJhdGlvICE9PSAxKSB7XG4gICAgY2FudmFzLnN0eWxlLndpZHRoID0gd2lkdGggKyAncHgnO1xuICAgIGNhbnZhcy5zdHlsZS5oZWlnaHQgPSBoZWlnaHQgKyAncHgnO1xuICB9XG5cbiAgY29udGV4dC5waXhlbFJhdGlvID0gcmF0aW87XG4gIGNvbnRleHQuc2V0VHJhbnNmb3JtKFxuICAgIHJhdGlvLCAwLCAwLCByYXRpbyxcbiAgICByYXRpbyAqIG9yaWdpblswXSxcbiAgICByYXRpbyAqIG9yaWdpblsxXVxuICApO1xuXG4gIHJldHVybiBjYW52YXM7XG59O1xuXG5mdW5jdGlvbiBDYW52YXNSZW5kZXJlcihsb2FkZXIpIHtcbiAgUmVuZGVyZXIuY2FsbCh0aGlzLCBsb2FkZXIpO1xuICB0aGlzLl9yZWRyYXcgPSBmYWxzZTtcbiAgdGhpcy5fZGlydHkgPSBuZXcgQm91bmRzKCk7XG59XG5cbnZhciBwcm90b3R5cGUkNDUgPSBpbmhlcml0cyhDYW52YXNSZW5kZXJlciwgUmVuZGVyZXIpO1xudmFyIGJhc2UgPSBSZW5kZXJlci5wcm90b3R5cGU7XG52YXIgdGVtcEJvdW5kcyQxID0gbmV3IEJvdW5kcygpO1xuXG5wcm90b3R5cGUkNDUuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGVsLCB3aWR0aCwgaGVpZ2h0LCBvcmlnaW4sIHNjYWxlRmFjdG9yKSB7XG4gIHRoaXMuX2NhbnZhcyA9IGNhbnZhcygxLCAxKTsgLy8gaW5zdGFudGlhdGUgYSBzbWFsbCBjYW52YXNcbiAgaWYgKGVsKSB7XG4gICAgZG9tQ2xlYXIoZWwsIDApLmFwcGVuZENoaWxkKHRoaXMuX2NhbnZhcyk7XG4gICAgdGhpcy5fY2FudmFzLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnbWFya3MnKTtcbiAgfVxuICAvLyB0aGlzIG1ldGhvZCB3aWxsIGludm9rZSByZXNpemUgdG8gc2l6ZSB0aGUgY2FudmFzIGFwcHJvcHJpYXRlbHlcbiAgcmV0dXJuIGJhc2UuaW5pdGlhbGl6ZS5jYWxsKHRoaXMsIGVsLCB3aWR0aCwgaGVpZ2h0LCBvcmlnaW4sIHNjYWxlRmFjdG9yKTtcbn07XG5cbnByb3RvdHlwZSQ0NS5yZXNpemUgPSBmdW5jdGlvbih3aWR0aCwgaGVpZ2h0LCBvcmlnaW4sIHNjYWxlRmFjdG9yKSB7XG4gIGJhc2UucmVzaXplLmNhbGwodGhpcywgd2lkdGgsIGhlaWdodCwgb3JpZ2luLCBzY2FsZUZhY3Rvcik7XG4gIHJlc2l6ZSh0aGlzLl9jYW52YXMsIHRoaXMuX3dpZHRoLCB0aGlzLl9oZWlnaHQsIHRoaXMuX29yaWdpbiwgdGhpcy5fc2NhbGUpO1xuICB0aGlzLl9yZWRyYXcgPSB0cnVlO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ0NS5jYW52YXMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuX2NhbnZhcztcbn07XG5cbnByb3RvdHlwZSQ0NS5jb250ZXh0ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9jYW52YXMgPyB0aGlzLl9jYW52YXMuZ2V0Q29udGV4dCgnMmQnKSA6IG51bGw7XG59O1xuXG5wcm90b3R5cGUkNDUuZGlydHkgPSBmdW5jdGlvbihpdGVtKSB7XG4gIHZhciBiID0gdHJhbnNsYXRlJDEoaXRlbS5ib3VuZHMsIGl0ZW0ubWFyay5ncm91cCk7XG4gIHRoaXMuX2RpcnR5LnVuaW9uKGIpO1xufTtcblxuZnVuY3Rpb24gY2xpcFRvQm91bmRzKGcsIGIsIG9yaWdpbikge1xuICAvLyBleHBhbmQgYm91bmRzIGJ5IDEgcGl4ZWwsIHRoZW4gcm91bmQgdG8gcGl4ZWwgYm91bmRhcmllc1xuICBiLmV4cGFuZCgxKS5yb3VuZCgpO1xuXG4gIC8vIHRvIGF2b2lkIGFydGlmYWN0cyB0cmFuc2xhdGUgaWYgb3JpZ2luIGhhcyBmcmFjdGlvbmFsIHBpeGVsc1xuICBiLnRyYW5zbGF0ZSgtKG9yaWdpblswXSAlIDEpLCAtKG9yaWdpblsxXSAlIDEpKTtcblxuICAvLyBzZXQgY2xpcHBpbmcgcGF0aFxuICBnLmJlZ2luUGF0aCgpO1xuICBnLnJlY3QoYi54MSwgYi55MSwgYi53aWR0aCgpLCBiLmhlaWdodCgpKTtcbiAgZy5jbGlwKCk7XG5cbiAgcmV0dXJuIGI7XG59XG5cbmZ1bmN0aW9uIHRyYW5zbGF0ZSQxKGJvdW5kcywgZ3JvdXApIHtcbiAgaWYgKGdyb3VwID09IG51bGwpIHJldHVybiBib3VuZHM7XG4gIHZhciBiID0gdGVtcEJvdW5kcyQxLmNsZWFyKCkudW5pb24oYm91bmRzKTtcbiAgZm9yICg7IGdyb3VwICE9IG51bGw7IGdyb3VwID0gZ3JvdXAubWFyay5ncm91cCkge1xuICAgIGIudHJhbnNsYXRlKGdyb3VwLnggfHwgMCwgZ3JvdXAueSB8fCAwKTtcbiAgfVxuICByZXR1cm4gYjtcbn1cblxucHJvdG90eXBlJDQ1Ll9yZW5kZXIgPSBmdW5jdGlvbihzY2VuZSkge1xuICB2YXIgZyA9IHRoaXMuY29udGV4dCgpLFxuICAgICAgbyA9IHRoaXMuX29yaWdpbixcbiAgICAgIHcgPSB0aGlzLl93aWR0aCxcbiAgICAgIGggPSB0aGlzLl9oZWlnaHQsXG4gICAgICBiID0gdGhpcy5fZGlydHk7XG5cbiAgLy8gc2V0dXBcbiAgZy5zYXZlKCk7XG4gIGlmICh0aGlzLl9yZWRyYXcgfHwgYi5lbXB0eSgpKSB7XG4gICAgdGhpcy5fcmVkcmF3ID0gZmFsc2U7XG4gICAgYiA9IG51bGw7XG4gIH0gZWxzZSB7XG4gICAgYiA9IGNsaXBUb0JvdW5kcyhnLCBiLCBvKTtcbiAgfVxuXG4gIHRoaXMuY2xlYXIoLW9bMF0sIC1vWzFdLCB3LCBoKTtcblxuICAvLyByZW5kZXJcbiAgdGhpcy5kcmF3KGcsIHNjZW5lLCBiKTtcblxuICAvLyB0YWtlZG93blxuICBnLnJlc3RvcmUoKTtcblxuICB0aGlzLl9kaXJ0eS5jbGVhcigpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ0NS5kcmF3ID0gZnVuY3Rpb24oY3R4LCBzY2VuZSwgYm91bmRzKSB7XG4gIHZhciBtYXJrID0gbWFya3Nbc2NlbmUubWFya3R5cGVdO1xuICBpZiAoc2NlbmUuY2xpcCkgY2xpcCQxKGN0eCwgc2NlbmUpO1xuICBtYXJrLmRyYXcuY2FsbCh0aGlzLCBjdHgsIHNjZW5lLCBib3VuZHMpO1xuICBpZiAoc2NlbmUuY2xpcCkgY3R4LnJlc3RvcmUoKTtcbn07XG5cbnByb3RvdHlwZSQ0NS5jbGVhciA9IGZ1bmN0aW9uKHgsIHksIHcsIGgpIHtcbiAgdmFyIGcgPSB0aGlzLmNvbnRleHQoKTtcbiAgZy5jbGVhclJlY3QoeCwgeSwgdywgaCk7XG4gIGlmICh0aGlzLl9iZ2NvbG9yICE9IG51bGwpIHtcbiAgICBnLmZpbGxTdHlsZSA9IHRoaXMuX2JnY29sb3I7XG4gICAgZy5maWxsUmVjdCh4LCB5LCB3LCBoKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gU1ZHSGFuZGxlcihsb2FkZXIpIHtcbiAgSGFuZGxlci5jYWxsKHRoaXMsIGxvYWRlcik7XG4gIHZhciBoID0gdGhpcztcbiAgaC5faHJlZkhhbmRsZXIgPSBsaXN0ZW5lcihoLCBmdW5jdGlvbihldnQsIGl0ZW0pIHtcbiAgICBpZiAoaXRlbSAmJiBpdGVtLmhyZWYpIGguaGFuZGxlSHJlZihldnQsIGl0ZW0sIGl0ZW0uaHJlZik7XG4gIH0pO1xuICBoLl90b29sdGlwSGFuZGxlciA9IGxpc3RlbmVyKGgsIGZ1bmN0aW9uKGV2dCwgaXRlbSkge1xuICAgIGlmIChpdGVtICYmIGl0ZW0udG9vbHRpcCkge1xuICAgICAgaC5oYW5kbGVUb29sdGlwKGV2dCwgaXRlbSwgZXZ0LnR5cGUgPT09ICdtb3VzZW92ZXInID8gaXRlbS50b29sdGlwIDogbnVsbCk7XG4gICAgfVxuICB9KTtcbn1cblxudmFyIHByb3RvdHlwZSQ0NiA9IGluaGVyaXRzKFNWR0hhbmRsZXIsIEhhbmRsZXIpO1xuXG5wcm90b3R5cGUkNDYuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKGVsLCBvcmlnaW4sIG9iaikge1xuICB2YXIgc3ZnID0gdGhpcy5fc3ZnO1xuICBpZiAoc3ZnKSB7XG4gICAgc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5faHJlZkhhbmRsZXIpO1xuICAgIHN2Zy5yZW1vdmVFdmVudExpc3RlbmVyKCdtb3VzZW92ZXInLCB0aGlzLl90b29sdGlwSGFuZGxlcik7XG4gICAgc3ZnLnJlbW92ZUV2ZW50TGlzdGVuZXIoJ21vdXNlb3V0JywgdGhpcy5fdG9vbHRpcEhhbmRsZXIpO1xuICB9XG4gIHRoaXMuX3N2ZyA9IHN2ZyA9IGVsICYmIGRvbUZpbmQoZWwsICdzdmcnKTtcbiAgaWYgKHN2Zykge1xuICAgIHN2Zy5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX2hyZWZIYW5kbGVyKTtcbiAgICBzdmcuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VvdmVyJywgdGhpcy5fdG9vbHRpcEhhbmRsZXIpO1xuICAgIHN2Zy5hZGRFdmVudExpc3RlbmVyKCdtb3VzZW91dCcsIHRoaXMuX3Rvb2x0aXBIYW5kbGVyKTtcbiAgfVxuICByZXR1cm4gSGFuZGxlci5wcm90b3R5cGUuaW5pdGlhbGl6ZS5jYWxsKHRoaXMsIGVsLCBvcmlnaW4sIG9iaik7XG59O1xuXG5wcm90b3R5cGUkNDYuc3ZnID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9zdmc7XG59O1xuXG4vLyB3cmFwIGFuIGV2ZW50IGxpc3RlbmVyIGZvciB0aGUgU1ZHIERPTVxuZnVuY3Rpb24gbGlzdGVuZXIoY29udGV4dCwgaGFuZGxlcikge1xuICByZXR1cm4gZnVuY3Rpb24oZXZ0KSB7XG4gICAgdmFyIHRhcmdldCA9IGV2dC50YXJnZXQsXG4gICAgICAgIGl0ZW0gPSB0YXJnZXQuX19kYXRhX187XG4gICAgZXZ0LnZlZ2FUeXBlID0gZXZ0LnR5cGU7XG4gICAgaXRlbSA9IEFycmF5LmlzQXJyYXkoaXRlbSkgPyBpdGVtWzBdIDogaXRlbTtcbiAgICBoYW5kbGVyLmNhbGwoY29udGV4dC5fb2JqLCBldnQsIGl0ZW0pO1xuICB9O1xufVxuXG4vLyBhZGQgYW4gZXZlbnQgaGFuZGxlclxucHJvdG90eXBlJDQ2Lm9uID0gZnVuY3Rpb24odHlwZSwgaGFuZGxlcikge1xuICB2YXIgbmFtZSA9IHRoaXMuZXZlbnROYW1lKHR5cGUpLFxuICAgICAgaCA9IHRoaXMuX2hhbmRsZXJzLFxuICAgICAgaSA9IHRoaXMuX2hhbmRsZXJJbmRleChoW25hbWVdLCB0eXBlLCBoYW5kbGVyKTtcblxuICBpZiAoaSA8IDApIHtcbiAgICB2YXIgeCA9IHtcbiAgICAgIHR5cGU6ICAgICB0eXBlLFxuICAgICAgaGFuZGxlcjogIGhhbmRsZXIsXG4gICAgICBsaXN0ZW5lcjogbGlzdGVuZXIodGhpcywgaGFuZGxlcilcbiAgICB9O1xuXG4gICAgKGhbbmFtZV0gfHwgKGhbbmFtZV0gPSBbXSkpLnB1c2goeCk7XG4gICAgaWYgKHRoaXMuX3N2Zykge1xuICAgICAgdGhpcy5fc3ZnLmFkZEV2ZW50TGlzdGVuZXIobmFtZSwgeC5saXN0ZW5lcik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vLyByZW1vdmUgYW4gZXZlbnQgaGFuZGxlclxucHJvdG90eXBlJDQ2Lm9mZiA9IGZ1bmN0aW9uKHR5cGUsIGhhbmRsZXIpIHtcbiAgdmFyIG5hbWUgPSB0aGlzLmV2ZW50TmFtZSh0eXBlKSxcbiAgICAgIGggPSB0aGlzLl9oYW5kbGVyc1tuYW1lXSxcbiAgICAgIGkgPSB0aGlzLl9oYW5kbGVySW5kZXgoaCwgdHlwZSwgaGFuZGxlcik7XG5cbiAgaWYgKGkgPj0gMCkge1xuICAgIGlmICh0aGlzLl9zdmcpIHtcbiAgICAgIHRoaXMuX3N2Zy5yZW1vdmVFdmVudExpc3RlbmVyKG5hbWUsIGhbaV0ubGlzdGVuZXIpO1xuICAgIH1cbiAgICBoLnNwbGljZShpLCAxKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gZ2VuZXJhdGUgc3RyaW5nIGZvciBhbiBvcGVuaW5nIHhtbCB0YWdcbi8vIHRhZzogdGhlIG5hbWUgb2YgdGhlIHhtbCB0YWdcbi8vIGF0dHI6IGhhc2ggb2YgYXR0cmlidXRlIG5hbWUtdmFsdWUgcGFpcnMgdG8gaW5jbHVkZVxuLy8gcmF3OiBhZGRpdGlvbmFsIHJhdyBzdHJpbmcgdG8gaW5jbHVkZSBpbiB0YWcgbWFya3VwXG5mdW5jdGlvbiBvcGVuVGFnKHRhZywgYXR0ciwgcmF3KSB7XG4gIHZhciBzID0gJzwnICsgdGFnLCBrZXksIHZhbDtcbiAgaWYgKGF0dHIpIHtcbiAgICBmb3IgKGtleSBpbiBhdHRyKSB7XG4gICAgICB2YWwgPSBhdHRyW2tleV07XG4gICAgICBpZiAodmFsICE9IG51bGwpIHtcbiAgICAgICAgcyArPSAnICcgKyBrZXkgKyAnPVwiJyArIHZhbCArICdcIic7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIGlmIChyYXcpIHMgKz0gJyAnICsgcmF3O1xuICByZXR1cm4gcyArICc+Jztcbn1cblxuLy8gZ2VuZXJhdGUgc3RyaW5nIGZvciBjbG9zaW5nIHhtbCB0YWdcbi8vIHRhZzogdGhlIG5hbWUgb2YgdGhlIHhtbCB0YWdcbmZ1bmN0aW9uIGNsb3NlVGFnKHRhZykge1xuICByZXR1cm4gJzwvJyArIHRhZyArICc+Jztcbn1cblxudmFyIG1ldGFkYXRhID0ge1xuICAndmVyc2lvbic6ICcxLjEnLFxuICAneG1sbnMnOiAnaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmcnLFxuICAneG1sbnM6eGxpbmsnOiAnaHR0cDovL3d3dy53My5vcmcvMTk5OS94bGluaydcbn07XG5cbnZhciBzdHlsZXMgPSB7XG4gICdmaWxsJzogICAgICAgICAgICAgJ2ZpbGwnLFxuICAnZmlsbE9wYWNpdHknOiAgICAgICdmaWxsLW9wYWNpdHknLFxuICAnc3Ryb2tlJzogICAgICAgICAgICdzdHJva2UnLFxuICAnc3Ryb2tlT3BhY2l0eSc6ICAgICdzdHJva2Utb3BhY2l0eScsXG4gICdzdHJva2VXaWR0aCc6ICAgICAgJ3N0cm9rZS13aWR0aCcsXG4gICdzdHJva2VDYXAnOiAgICAgICAgJ3N0cm9rZS1saW5lY2FwJyxcbiAgJ3N0cm9rZUpvaW4nOiAgICAgICAnc3Ryb2tlLWxpbmVqb2luJyxcbiAgJ3N0cm9rZURhc2gnOiAgICAgICAnc3Ryb2tlLWRhc2hhcnJheScsXG4gICdzdHJva2VEYXNoT2Zmc2V0JzogJ3N0cm9rZS1kYXNob2Zmc2V0JyxcbiAgJ3N0cm9rZU1pdGVyTGltaXQnOiAnc3Ryb2tlLW1pdGVybGltaXQnLFxuICAnb3BhY2l0eSc6ICAgICAgICAgICdvcGFjaXR5J1xufTtcblxudmFyIHN0eWxlUHJvcGVydGllcyA9IE9iamVjdC5rZXlzKHN0eWxlcyk7XG5cbnZhciBucyA9IG1ldGFkYXRhLnhtbG5zO1xuXG5mdW5jdGlvbiBTVkdSZW5kZXJlcihsb2FkZXIpIHtcbiAgUmVuZGVyZXIuY2FsbCh0aGlzLCBsb2FkZXIpO1xuICB0aGlzLl9kaXJ0eUlEID0gMTtcbiAgdGhpcy5fZGlydHkgPSBbXTtcbiAgdGhpcy5fc3ZnID0gbnVsbDtcbiAgdGhpcy5fcm9vdCA9IG51bGw7XG4gIHRoaXMuX2RlZnMgPSBudWxsO1xufVxuXG52YXIgcHJvdG90eXBlJDQ3ID0gaW5oZXJpdHMoU1ZHUmVuZGVyZXIsIFJlbmRlcmVyKTtcbnZhciBiYXNlJDEgPSBSZW5kZXJlci5wcm90b3R5cGU7XG5cbnByb3RvdHlwZSQ0Ny5pbml0aWFsaXplID0gZnVuY3Rpb24oZWwsIHdpZHRoLCBoZWlnaHQsIHBhZGRpbmcpIHtcbiAgaWYgKGVsKSB7XG4gICAgdGhpcy5fc3ZnID0gZG9tQ2hpbGQoZWwsIDAsICdzdmcnLCBucyk7XG4gICAgdGhpcy5fc3ZnLnNldEF0dHJpYnV0ZSgnY2xhc3MnLCAnbWFya3MnKTtcbiAgICBkb21DbGVhcihlbCwgMSk7XG4gICAgLy8gc2V0IHRoZSBzdmcgcm9vdCBncm91cFxuICAgIHRoaXMuX3Jvb3QgPSBkb21DaGlsZCh0aGlzLl9zdmcsIDAsICdnJywgbnMpO1xuICAgIGRvbUNsZWFyKHRoaXMuX3N2ZywgMSk7XG4gIH1cblxuICAvLyBjcmVhdGUgdGhlIHN2ZyBkZWZpbml0aW9ucyBjYWNoZVxuICB0aGlzLl9kZWZzID0ge1xuICAgIGdyYWRpZW50OiB7fSxcbiAgICBjbGlwcGluZzoge31cbiAgfTtcblxuICAvLyBzZXQgYmFja2dyb3VuZCBjb2xvciBpZiBkZWZpbmVkXG4gIHRoaXMuYmFja2dyb3VuZCh0aGlzLl9iZ2NvbG9yKTtcblxuICByZXR1cm4gYmFzZSQxLmluaXRpYWxpemUuY2FsbCh0aGlzLCBlbCwgd2lkdGgsIGhlaWdodCwgcGFkZGluZyk7XG59O1xuXG5wcm90b3R5cGUkNDcuYmFja2dyb3VuZCA9IGZ1bmN0aW9uKGJnY29sb3IpIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggJiYgdGhpcy5fc3ZnKSB7XG4gICAgdGhpcy5fc3ZnLnN0eWxlLnNldFByb3BlcnR5KCdiYWNrZ3JvdW5kLWNvbG9yJywgYmdjb2xvcik7XG4gIH1cbiAgcmV0dXJuIGJhc2UkMS5iYWNrZ3JvdW5kLmFwcGx5KHRoaXMsIGFyZ3VtZW50cyk7XG59O1xuXG5wcm90b3R5cGUkNDcucmVzaXplID0gZnVuY3Rpb24od2lkdGgsIGhlaWdodCwgb3JpZ2luLCBzY2FsZUZhY3Rvcikge1xuICBiYXNlJDEucmVzaXplLmNhbGwodGhpcywgd2lkdGgsIGhlaWdodCwgb3JpZ2luLCBzY2FsZUZhY3Rvcik7XG5cbiAgaWYgKHRoaXMuX3N2Zykge1xuICAgIHRoaXMuX3N2Zy5zZXRBdHRyaWJ1dGUoJ3dpZHRoJywgdGhpcy5fd2lkdGggKiB0aGlzLl9zY2FsZSk7XG4gICAgdGhpcy5fc3ZnLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgdGhpcy5faGVpZ2h0ICogdGhpcy5fc2NhbGUpO1xuICAgIHRoaXMuX3N2Zy5zZXRBdHRyaWJ1dGUoJ3ZpZXdCb3gnLCAnMCAwICcgKyB0aGlzLl93aWR0aCArICcgJyArIHRoaXMuX2hlaWdodCk7XG4gICAgdGhpcy5fcm9vdC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsICd0cmFuc2xhdGUoJyArIHRoaXMuX29yaWdpbiArICcpJyk7XG4gIH1cblxuICB0aGlzLl9kaXJ0eSA9IFtdO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDQ3LnN2ZyA9IGZ1bmN0aW9uKCkge1xuICBpZiAoIXRoaXMuX3N2ZykgcmV0dXJuIG51bGw7XG5cbiAgdmFyIGF0dHIgPSB7XG4gICAgY2xhc3M6ICAgJ21hcmtzJyxcbiAgICB3aWR0aDogICB0aGlzLl93aWR0aCAqIHRoaXMuX3NjYWxlLFxuICAgIGhlaWdodDogIHRoaXMuX2hlaWdodCAqIHRoaXMuX3NjYWxlLFxuICAgIHZpZXdCb3g6ICcwIDAgJyArIHRoaXMuX3dpZHRoICsgJyAnICsgdGhpcy5faGVpZ2h0XG4gIH07XG4gIGZvciAodmFyIGtleSQkMSBpbiBtZXRhZGF0YSkge1xuICAgIGF0dHJba2V5JCQxXSA9IG1ldGFkYXRhW2tleSQkMV07XG4gIH1cblxuICB2YXIgYmcgPSAhdGhpcy5fYmdjb2xvciA/ICcnXG4gICAgOiAob3BlblRhZygncmVjdCcsIHtcbiAgICAgICAgd2lkdGg6ICB0aGlzLl93aWR0aCxcbiAgICAgICAgaGVpZ2h0OiB0aGlzLl9oZWlnaHQsXG4gICAgICAgIHN0eWxlOiAgJ2ZpbGw6ICcgKyB0aGlzLl9iZ2NvbG9yICsgJzsnXG4gICAgICB9KSArIGNsb3NlVGFnKCdyZWN0JykpO1xuXG4gIHJldHVybiBvcGVuVGFnKCdzdmcnLCBhdHRyKSArIGJnICsgdGhpcy5fc3ZnLmlubmVySFRNTCArIGNsb3NlVGFnKCdzdmcnKTtcbn07XG5cblxuLy8gLS0gUmVuZGVyIGVudHJ5IHBvaW50IC0tXG5cbnByb3RvdHlwZSQ0Ny5fcmVuZGVyID0gZnVuY3Rpb24oc2NlbmUpIHtcbiAgLy8gcGVyZm9ybSBzcG90IHVwZGF0ZXMgYW5kIHJlLXJlbmRlciBtYXJrdXBcbiAgaWYgKHRoaXMuX2RpcnR5Q2hlY2soKSkge1xuICAgIGlmICh0aGlzLl9kaXJ0eUFsbCkgdGhpcy5fcmVzZXREZWZzKCk7XG4gICAgdGhpcy5kcmF3KHRoaXMuX3Jvb3QsIHNjZW5lKTtcbiAgICBkb21DbGVhcih0aGlzLl9yb290LCAxKTtcbiAgfVxuXG4gIHRoaXMudXBkYXRlRGVmcygpO1xuXG4gIHRoaXMuX2RpcnR5ID0gW107XG4gICsrdGhpcy5fZGlydHlJRDtcblxuICByZXR1cm4gdGhpcztcbn07XG5cbi8vIC0tIE1hbmFnZSBTVkcgZGVmaW5pdGlvbnMgKCdkZWZzJykgYmxvY2sgLS1cblxucHJvdG90eXBlJDQ3LnVwZGF0ZURlZnMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHN2ZyA9IHRoaXMuX3N2ZyxcbiAgICAgIGRlZnMgPSB0aGlzLl9kZWZzLFxuICAgICAgZWwgPSBkZWZzLmVsLFxuICAgICAgaW5kZXggPSAwLCBpZCQkMTtcblxuICBmb3IgKGlkJCQxIGluIGRlZnMuZ3JhZGllbnQpIHtcbiAgICBpZiAoIWVsKSBkZWZzLmVsID0gKGVsID0gZG9tQ2hpbGQoc3ZnLCAwLCAnZGVmcycsIG5zKSk7XG4gICAgdXBkYXRlR3JhZGllbnQoZWwsIGRlZnMuZ3JhZGllbnRbaWQkJDFdLCBpbmRleCsrKTtcbiAgfVxuXG4gIGZvciAoaWQkJDEgaW4gZGVmcy5jbGlwcGluZykge1xuICAgIGlmICghZWwpIGRlZnMuZWwgPSAoZWwgPSBkb21DaGlsZChzdmcsIDAsICdkZWZzJywgbnMpKTtcbiAgICB1cGRhdGVDbGlwcGluZyhlbCwgZGVmcy5jbGlwcGluZ1tpZCQkMV0sIGluZGV4KyspO1xuICB9XG5cbiAgLy8gY2xlYW4tdXBcbiAgaWYgKGVsKSB7XG4gICAgaWYgKGluZGV4ID09PSAwKSB7XG4gICAgICBzdmcucmVtb3ZlQ2hpbGQoZWwpO1xuICAgICAgZGVmcy5lbCA9IG51bGw7XG4gICAgfSBlbHNlIHtcbiAgICAgIGRvbUNsZWFyKGVsLCBpbmRleCk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiB1cGRhdGVHcmFkaWVudChlbCwgZ3JhZCwgaW5kZXgpIHtcbiAgdmFyIGksIG4sIHN0b3A7XG5cbiAgZWwgPSBkb21DaGlsZChlbCwgaW5kZXgsICdsaW5lYXJHcmFkaWVudCcsIG5zKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdpZCcsIGdyYWQuaWQpO1xuICBlbC5zZXRBdHRyaWJ1dGUoJ3gxJywgZ3JhZC54MSk7XG4gIGVsLnNldEF0dHJpYnV0ZSgneDInLCBncmFkLngyKTtcbiAgZWwuc2V0QXR0cmlidXRlKCd5MScsIGdyYWQueTEpO1xuICBlbC5zZXRBdHRyaWJ1dGUoJ3kyJywgZ3JhZC55Mik7XG5cbiAgZm9yIChpPTAsIG49Z3JhZC5zdG9wcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgc3RvcCA9IGRvbUNoaWxkKGVsLCBpLCAnc3RvcCcsIG5zKTtcbiAgICBzdG9wLnNldEF0dHJpYnV0ZSgnb2Zmc2V0JywgZ3JhZC5zdG9wc1tpXS5vZmZzZXQpO1xuICAgIHN0b3Auc2V0QXR0cmlidXRlKCdzdG9wLWNvbG9yJywgZ3JhZC5zdG9wc1tpXS5jb2xvcik7XG4gIH1cbiAgZG9tQ2xlYXIoZWwsIGkpO1xufVxuXG5mdW5jdGlvbiB1cGRhdGVDbGlwcGluZyhlbCwgY2xpcCQkMSwgaW5kZXgpIHtcbiAgdmFyIG1hc2s7XG5cbiAgZWwgPSBkb21DaGlsZChlbCwgaW5kZXgsICdjbGlwUGF0aCcsIG5zKTtcbiAgZWwuc2V0QXR0cmlidXRlKCdpZCcsIGNsaXAkJDEuaWQpO1xuXG4gIGlmIChjbGlwJCQxLnBhdGgpIHtcbiAgICBtYXNrID0gZG9tQ2hpbGQoZWwsIDAsICdwYXRoJywgbnMpO1xuICAgIG1hc2suc2V0QXR0cmlidXRlKCdkJywgY2xpcCQkMS5wYXRoKTtcbiAgfSBlbHNlIHtcbiAgICBtYXNrID0gZG9tQ2hpbGQoZWwsIDAsICdyZWN0JywgbnMpO1xuICAgIG1hc2suc2V0QXR0cmlidXRlKCd4JywgMCk7XG4gICAgbWFzay5zZXRBdHRyaWJ1dGUoJ3knLCAwKTtcbiAgICBtYXNrLnNldEF0dHJpYnV0ZSgnd2lkdGgnLCBjbGlwJCQxLndpZHRoKTtcbiAgICBtYXNrLnNldEF0dHJpYnV0ZSgnaGVpZ2h0JywgY2xpcCQkMS5oZWlnaHQpO1xuICB9XG59XG5cbnByb3RvdHlwZSQ0Ny5fcmVzZXREZWZzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkZWYgPSB0aGlzLl9kZWZzO1xuICBkZWYuZ3JhZGllbnQgPSB7fTtcbiAgZGVmLmNsaXBwaW5nID0ge307XG59O1xuXG5cbi8vIC0tIE1hbmFnZSByZW5kZXJpbmcgb2YgaXRlbXMgbWFya2VkIGFzIGRpcnR5IC0tXG5cbnByb3RvdHlwZSQ0Ny5kaXJ0eSA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgaWYgKGl0ZW0uZGlydHkgIT09IHRoaXMuX2RpcnR5SUQpIHtcbiAgICBpdGVtLmRpcnR5ID0gdGhpcy5fZGlydHlJRDtcbiAgICB0aGlzLl9kaXJ0eS5wdXNoKGl0ZW0pO1xuICB9XG59O1xuXG5wcm90b3R5cGUkNDcuaXNEaXJ0eSA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgcmV0dXJuIHRoaXMuX2RpcnR5QWxsXG4gICAgfHwgIWl0ZW0uX3N2Z1xuICAgIHx8IGl0ZW0uZGlydHkgPT09IHRoaXMuX2RpcnR5SUQ7XG59O1xuXG5wcm90b3R5cGUkNDcuX2RpcnR5Q2hlY2sgPSBmdW5jdGlvbigpIHtcbiAgdGhpcy5fZGlydHlBbGwgPSB0cnVlO1xuICB2YXIgaXRlbXMgPSB0aGlzLl9kaXJ0eTtcbiAgaWYgKCFpdGVtcy5sZW5ndGgpIHJldHVybiB0cnVlO1xuXG4gIHZhciBpZCQkMSA9ICsrdGhpcy5fZGlydHlJRCxcbiAgICAgIGl0ZW0sIG1hcmssIHR5cGUsIG1kZWYsIGksIG4sIG87XG5cbiAgZm9yIChpPTAsIG49aXRlbXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGl0ZW0gPSBpdGVtc1tpXTtcbiAgICBtYXJrID0gaXRlbS5tYXJrO1xuXG4gICAgaWYgKG1hcmsubWFya3R5cGUgIT09IHR5cGUpIHtcbiAgICAgIC8vIG1lbW9pemUgbWFyayBpbnN0YW5jZSBsb29rdXBcbiAgICAgIHR5cGUgPSBtYXJrLm1hcmt0eXBlO1xuICAgICAgbWRlZiA9IG1hcmtzW3R5cGVdO1xuICAgIH1cblxuICAgIGlmIChtYXJrLnpkaXJ0eSAmJiBtYXJrLmRpcnR5ICE9PSBpZCQkMSkge1xuICAgICAgdGhpcy5fZGlydHlBbGwgPSBmYWxzZTtcbiAgICAgIG1hcmsuZGlydHkgPSBpZCQkMTtcbiAgICAgIGRpcnR5UGFyZW50cyhtYXJrLmdyb3VwLCBpZCQkMSk7XG4gICAgfVxuXG4gICAgaWYgKGl0ZW0uZXhpdCkgeyAvLyBFWElUXG4gICAgICBpZiAobWRlZi5uZXN0ZWQgJiYgbWFyay5pdGVtcy5sZW5ndGgpIHtcbiAgICAgICAgLy8gaWYgbmVzdGVkIG1hcmsgd2l0aCByZW1haW5pbmcgcG9pbnRzLCB1cGRhdGUgaW5zdGVhZFxuICAgICAgICBvID0gbWFyay5pdGVtc1swXTtcbiAgICAgICAgaWYgKG8uX3N2ZykgdGhpcy5fdXBkYXRlKG1kZWYsIG8uX3N2Zywgbyk7XG4gICAgICB9IGVsc2UgaWYgKGl0ZW0uX3N2Zykge1xuICAgICAgICAvLyBvdGhlcndpc2UgcmVtb3ZlIGZyb20gRE9NXG4gICAgICAgIG8gPSBpdGVtLl9zdmcucGFyZW50Tm9kZTtcbiAgICAgICAgaWYgKG8pIG8ucmVtb3ZlQ2hpbGQoaXRlbS5fc3ZnKTtcbiAgICAgIH1cbiAgICAgIGl0ZW0uX3N2ZyA9IG51bGw7XG4gICAgICBjb250aW51ZTtcbiAgICB9XG5cbiAgICBpdGVtID0gKG1kZWYubmVzdGVkID8gbWFyay5pdGVtc1swXSA6IGl0ZW0pO1xuICAgIGlmIChpdGVtLl91cGRhdGUgPT09IGlkJCQxKSBjb250aW51ZTsgLy8gYWxyZWFkeSB2aXNpdGVkXG5cbiAgICBpZiAoIWl0ZW0uX3N2ZyB8fCAhaXRlbS5fc3ZnLm93bmVyU1ZHRWxlbWVudCkge1xuICAgICAgLy8gRU5URVJcbiAgICAgIHRoaXMuX2RpcnR5QWxsID0gZmFsc2U7XG4gICAgICBkaXJ0eVBhcmVudHMoaXRlbSwgaWQkJDEpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBJTi1QTEFDRSBVUERBVEVcbiAgICAgIHRoaXMuX3VwZGF0ZShtZGVmLCBpdGVtLl9zdmcsIGl0ZW0pO1xuICAgIH1cbiAgICBpdGVtLl91cGRhdGUgPSBpZCQkMTtcbiAgfVxuICByZXR1cm4gIXRoaXMuX2RpcnR5QWxsO1xufTtcblxuZnVuY3Rpb24gZGlydHlQYXJlbnRzKGl0ZW0sIGlkJCQxKSB7XG4gIGZvciAoOyBpdGVtICYmIGl0ZW0uZGlydHkgIT09IGlkJCQxOyBpdGVtPWl0ZW0ubWFyay5ncm91cCkge1xuICAgIGl0ZW0uZGlydHkgPSBpZCQkMTtcbiAgICBpZiAoaXRlbS5tYXJrICYmIGl0ZW0ubWFyay5kaXJ0eSAhPT0gaWQkJDEpIHtcbiAgICAgIGl0ZW0ubWFyay5kaXJ0eSA9IGlkJCQxO1xuICAgIH0gZWxzZSByZXR1cm47XG4gIH1cbn1cblxuXG4vLyAtLSBDb25zdHJ1Y3QgJiBtYWludGFpbiBzY2VuZWdyYXBoIHRvIFNWRyBtYXBwaW5nIC0tLVxuXG4vLyBEcmF3IGEgbWFyayBjb250YWluZXIuXG5wcm90b3R5cGUkNDcuZHJhdyA9IGZ1bmN0aW9uKGVsLCBzY2VuZSwgcHJldikge1xuICBpZiAoIXRoaXMuaXNEaXJ0eShzY2VuZSkpIHJldHVybiBzY2VuZS5fc3ZnO1xuXG4gIHZhciByZW5kZXJlciA9IHRoaXMsXG4gICAgICBtZGVmID0gbWFya3Nbc2NlbmUubWFya3R5cGVdLFxuICAgICAgZXZlbnRzID0gc2NlbmUuaW50ZXJhY3RpdmUgPT09IGZhbHNlID8gJ25vbmUnIDogbnVsbCxcbiAgICAgIGlzR3JvdXAgPSBtZGVmLnRhZyA9PT0gJ2cnLFxuICAgICAgc2libGluZyA9IG51bGwsXG4gICAgICBpID0gMCxcbiAgICAgIHBhcmVudDtcblxuICBwYXJlbnQgPSBiaW5kKHNjZW5lLCBlbCwgcHJldiwgJ2cnKTtcbiAgcGFyZW50LnNldEF0dHJpYnV0ZSgnY2xhc3MnLCBjc3NDbGFzcyhzY2VuZSkpO1xuICBpZiAoIWlzR3JvdXApIHtcbiAgICBwYXJlbnQuc3R5bGUuc2V0UHJvcGVydHkoJ3BvaW50ZXItZXZlbnRzJywgZXZlbnRzKTtcbiAgfVxuICBpZiAoc2NlbmUuY2xpcCkge1xuICAgIHBhcmVudC5zZXRBdHRyaWJ1dGUoJ2NsaXAtcGF0aCcsIGNsaXAocmVuZGVyZXIsIHNjZW5lLCBzY2VuZS5ncm91cCkpO1xuICB9IGVsc2Uge1xuICAgIHBhcmVudC5yZW1vdmVBdHRyaWJ1dGUoJ2NsaXAtcGF0aCcpO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJvY2VzcyhpdGVtKSB7XG4gICAgdmFyIGRpcnR5ID0gcmVuZGVyZXIuaXNEaXJ0eShpdGVtKSxcbiAgICAgICAgbm9kZSA9IGJpbmQoaXRlbSwgcGFyZW50LCBzaWJsaW5nLCBtZGVmLnRhZyk7XG5cbiAgICBpZiAoZGlydHkpIHtcbiAgICAgIHJlbmRlcmVyLl91cGRhdGUobWRlZiwgbm9kZSwgaXRlbSk7XG4gICAgICBpZiAoaXNHcm91cCkgcmVjdXJzZShyZW5kZXJlciwgbm9kZSwgaXRlbSk7XG4gICAgfVxuXG4gICAgc2libGluZyA9IG5vZGU7XG4gICAgKytpO1xuICB9XG5cbiAgaWYgKG1kZWYubmVzdGVkKSB7XG4gICAgaWYgKHNjZW5lLml0ZW1zLmxlbmd0aCkgcHJvY2VzcyhzY2VuZS5pdGVtc1swXSk7XG4gIH0gZWxzZSB7XG4gICAgdmlzaXQoc2NlbmUsIHByb2Nlc3MpO1xuICB9XG5cbiAgZG9tQ2xlYXIocGFyZW50LCBpKTtcbiAgcmV0dXJuIHBhcmVudDtcbn07XG5cbi8vIFJlY3Vyc2l2ZWx5IHByb2Nlc3MgZ3JvdXAgY29udGVudHMuXG5mdW5jdGlvbiByZWN1cnNlKHJlbmRlcmVyLCBlbCwgZ3JvdXApIHtcbiAgZWwgPSBlbC5sYXN0Q2hpbGQ7XG4gIHZhciBwcmV2LCBpZHggPSAwO1xuXG4gIHZpc2l0KGdyb3VwLCBmdW5jdGlvbihpdGVtKSB7XG4gICAgcHJldiA9IHJlbmRlcmVyLmRyYXcoZWwsIGl0ZW0sIHByZXYpO1xuICAgICsraWR4O1xuICB9KTtcblxuICAvLyByZW1vdmUgYW55IGV4dHJhbmVvdXMgRE9NIGVsZW1lbnRzXG4gIGRvbUNsZWFyKGVsLCAxICsgaWR4KTtcbn1cblxuLy8gQmluZCBhIHNjZW5lZ3JhcGggaXRlbSB0byBhbiBTVkcgRE9NIGVsZW1lbnQuXG4vLyBDcmVhdGUgbmV3IFNWRyBlbGVtZW50cyBhcyBuZWVkZWQuXG5mdW5jdGlvbiBiaW5kKGl0ZW0sIGVsLCBzaWJsaW5nLCB0YWcpIHtcbiAgdmFyIG5vZGUgPSBpdGVtLl9zdmcsIGRvYztcblxuICAvLyBjcmVhdGUgYSBuZXcgZG9tIG5vZGUgaWYgbmVlZGVkXG4gIGlmICghbm9kZSkge1xuICAgIGRvYyA9IGVsLm93bmVyRG9jdW1lbnQ7XG4gICAgbm9kZSA9IGRvbUNyZWF0ZShkb2MsIHRhZywgbnMpO1xuICAgIGl0ZW0uX3N2ZyA9IG5vZGU7XG5cbiAgICBpZiAoaXRlbS5tYXJrKSB7XG4gICAgICBub2RlLl9fZGF0YV9fID0gaXRlbTtcbiAgICAgIG5vZGUuX192YWx1ZXNfXyA9IHtmaWxsOiAnZGVmYXVsdCd9O1xuXG4gICAgICAvLyBpZiBncm91cCwgY3JlYXRlIGJhY2tncm91bmQgYW5kIGZvcmVncm91bmQgZWxlbWVudHNcbiAgICAgIGlmICh0YWcgPT09ICdnJykge1xuICAgICAgICB2YXIgYmcgPSBkb21DcmVhdGUoZG9jLCAncGF0aCcsIG5zKTtcbiAgICAgICAgYmcuc2V0QXR0cmlidXRlKCdjbGFzcycsICdiYWNrZ3JvdW5kJyk7XG4gICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoYmcpO1xuICAgICAgICBiZy5fX2RhdGFfXyA9IGl0ZW07XG5cbiAgICAgICAgdmFyIGZnID0gZG9tQ3JlYXRlKGRvYywgJ2cnLCBucyk7XG4gICAgICAgIG5vZGUuYXBwZW5kQ2hpbGQoZmcpO1xuICAgICAgICBmZy5fX2RhdGFfXyA9IGl0ZW07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgaWYgKGRvYyB8fCBub2RlLnByZXZpb3VzU2libGluZyAhPT0gc2libGluZyB8fCAhc2libGluZykge1xuICAgIGVsLmluc2VydEJlZm9yZShub2RlLCBzaWJsaW5nID8gc2libGluZy5uZXh0U2libGluZyA6IGVsLmZpcnN0Q2hpbGQpO1xuICB9XG5cbiAgcmV0dXJuIG5vZGU7XG59XG5cblxuLy8gLS0gU2V0IGF0dHJpYnV0ZXMgJiBzdHlsZXMgb24gU1ZHIGVsZW1lbnRzIC0tLVxuXG52YXIgZWxlbWVudCA9IG51bGw7XG52YXIgdmFsdWVzJDEgPSBudWxsOyAgLy8gdGVtcCB2YXIgZm9yIGN1cnJlbnQgdmFsdWVzIGhhc2hcblxuLy8gRXh0cmEgY29uZmlndXJhdGlvbiBmb3IgY2VydGFpbiBtYXJrIHR5cGVzXG52YXIgbWFya19leHRyYXMgPSB7XG4gIGdyb3VwOiBmdW5jdGlvbihtZGVmLCBlbCwgaXRlbSkge1xuICAgIHZhbHVlcyQxID0gZWwuX192YWx1ZXNfXzsgLy8gdXNlIHBhcmVudCdzIHZhbHVlcyBoYXNoXG5cbiAgICBlbGVtZW50ID0gZWwuY2hpbGROb2Rlc1sxXTtcbiAgICBtZGVmLmZvcmVncm91bmQoZW1pdCwgaXRlbSwgdGhpcyk7XG5cbiAgICBlbGVtZW50ID0gZWwuY2hpbGROb2Rlc1swXTtcbiAgICBtZGVmLmJhY2tncm91bmQoZW1pdCwgaXRlbSwgdGhpcyk7XG5cbiAgICB2YXIgdmFsdWUgPSBpdGVtLm1hcmsuaW50ZXJhY3RpdmUgPT09IGZhbHNlID8gJ25vbmUnIDogbnVsbDtcbiAgICBpZiAodmFsdWUgIT09IHZhbHVlcyQxLmV2ZW50cykge1xuICAgICAgZWxlbWVudC5zdHlsZS5zZXRQcm9wZXJ0eSgncG9pbnRlci1ldmVudHMnLCB2YWx1ZSk7XG4gICAgICB2YWx1ZXMkMS5ldmVudHMgPSB2YWx1ZTtcbiAgICB9XG4gIH0sXG4gIHRleHQ6IGZ1bmN0aW9uKG1kZWYsIGVsLCBpdGVtKSB7XG4gICAgdmFyIHN0ciA9IHRleHRWYWx1ZShpdGVtKTtcbiAgICBpZiAoc3RyICE9PSB2YWx1ZXMkMS50ZXh0KSB7XG4gICAgICBlbC50ZXh0Q29udGVudCA9IHN0cjtcbiAgICAgIHZhbHVlcyQxLnRleHQgPSBzdHI7XG4gICAgfVxuICAgIHN0ciA9IGZvbnQoaXRlbSk7XG4gICAgaWYgKHN0ciAhPT0gdmFsdWVzJDEuZm9udCkge1xuICAgICAgZWwuc3R5bGUuc2V0UHJvcGVydHkoJ2ZvbnQnLCBzdHIpO1xuICAgICAgdmFsdWVzJDEuZm9udCA9IHN0cjtcbiAgICB9XG4gIH1cbn07XG5cbnByb3RvdHlwZSQ0Ny5fdXBkYXRlID0gZnVuY3Rpb24obWRlZiwgZWwsIGl0ZW0pIHtcbiAgLy8gc2V0IGRvbSBlbGVtZW50IGFuZCB2YWx1ZXMgY2FjaGVcbiAgLy8gcHJvdmlkZXMgYWNjZXNzIHRvIGVtaXQgbWV0aG9kXG4gIGVsZW1lbnQgPSBlbDtcbiAgdmFsdWVzJDEgPSBlbC5fX3ZhbHVlc19fO1xuXG4gIC8vIGFwcGx5IHN2ZyBhdHRyaWJ1dGVzXG4gIG1kZWYuYXR0cihlbWl0LCBpdGVtLCB0aGlzKTtcblxuICAvLyBzb21lIG1hcmtzIG5lZWQgc3BlY2lhbCB0cmVhdG1lbnRcbiAgdmFyIGV4dHJhID0gbWFya19leHRyYXNbbWRlZi50eXBlXTtcbiAgaWYgKGV4dHJhKSBleHRyYS5jYWxsKHRoaXMsIG1kZWYsIGVsLCBpdGVtKTtcblxuICAvLyBhcHBseSBzdmcgY3NzIHN0eWxlc1xuICAvLyBub3RlOiBlbGVtZW50IG1heSBiZSBtb2RpZmllZCBieSAnZXh0cmEnIG1ldGhvZFxuICB0aGlzLnN0eWxlKGVsZW1lbnQsIGl0ZW0pO1xufTtcblxuZnVuY3Rpb24gZW1pdChuYW1lLCB2YWx1ZSwgbnMpIHtcbiAgLy8gZWFybHkgZXhpdCBpZiB2YWx1ZSBpcyB1bmNoYW5nZWRcbiAgaWYgKHZhbHVlID09PSB2YWx1ZXMkMVtuYW1lXSkgcmV0dXJuO1xuXG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgLy8gaWYgdmFsdWUgaXMgcHJvdmlkZWQsIHVwZGF0ZSBET00gYXR0cmlidXRlXG4gICAgaWYgKG5zKSB7XG4gICAgICBlbGVtZW50LnNldEF0dHJpYnV0ZU5TKG5zLCBuYW1lLCB2YWx1ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKG5hbWUsIHZhbHVlKTtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgLy8gZWxzZSByZW1vdmUgRE9NIGF0dHJpYnV0ZVxuICAgIGlmIChucykge1xuICAgICAgZWxlbWVudC5yZW1vdmVBdHRyaWJ1dGVOUyhucywgbmFtZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGVsZW1lbnQucmVtb3ZlQXR0cmlidXRlKG5hbWUpO1xuICAgIH1cbiAgfVxuXG4gIC8vIG5vdGUgY3VycmVudCB2YWx1ZSBmb3IgZnV0dXJlIGNvbXBhcmlzb25cbiAgdmFsdWVzJDFbbmFtZV0gPSB2YWx1ZTtcbn1cblxucHJvdG90eXBlJDQ3LnN0eWxlID0gZnVuY3Rpb24oZWwsIG8pIHtcbiAgaWYgKG8gPT0gbnVsbCkgcmV0dXJuO1xuICB2YXIgaSwgbiwgcHJvcCwgbmFtZSwgdmFsdWU7XG5cbiAgZm9yIChpPTAsIG49c3R5bGVQcm9wZXJ0aWVzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBwcm9wID0gc3R5bGVQcm9wZXJ0aWVzW2ldO1xuICAgIHZhbHVlID0gb1twcm9wXTtcbiAgICBpZiAodmFsdWUgPT09IHZhbHVlcyQxW3Byb3BdKSBjb250aW51ZTtcblxuICAgIG5hbWUgPSBzdHlsZXNbcHJvcF07XG4gICAgaWYgKHZhbHVlID09IG51bGwpIHtcbiAgICAgIGlmIChuYW1lID09PSAnZmlsbCcpIHtcbiAgICAgICAgZWwuc3R5bGUuc2V0UHJvcGVydHkobmFtZSwgJ25vbmUnKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGVsLnN0eWxlLnJlbW92ZVByb3BlcnR5KG5hbWUpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodmFsdWUuaWQpIHtcbiAgICAgICAgLy8gZW5zdXJlIGRlZmluaXRpb24gaXMgaW5jbHVkZWRcbiAgICAgICAgdGhpcy5fZGVmcy5ncmFkaWVudFt2YWx1ZS5pZF0gPSB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAndXJsKCcgKyBocmVmKCkgKyAnIycgKyB2YWx1ZS5pZCArICcpJztcbiAgICAgIH1cbiAgICAgIGVsLnN0eWxlLnNldFByb3BlcnR5KG5hbWUsIHZhbHVlKycnKTtcbiAgICB9XG5cbiAgICB2YWx1ZXMkMVtwcm9wXSA9IHZhbHVlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBocmVmKCkge1xuICB2YXIgbG9jO1xuICByZXR1cm4gdHlwZW9mIHdpbmRvdyA9PT0gJ3VuZGVmaW5lZCcgPyAnJ1xuICAgIDogKGxvYyA9IHdpbmRvdy5sb2NhdGlvbikuaGFzaCA/IGxvYy5ocmVmLnNsaWNlKDAsIC1sb2MuaGFzaC5sZW5ndGgpXG4gICAgOiBsb2MuaHJlZjtcbn1cblxuZnVuY3Rpb24gU1ZHU3RyaW5nUmVuZGVyZXIobG9hZGVyKSB7XG4gIFJlbmRlcmVyLmNhbGwodGhpcywgbG9hZGVyKTtcblxuICB0aGlzLl90ZXh0ID0ge1xuICAgIGhlYWQ6ICcnLFxuICAgIGJnOiAgICcnLFxuICAgIHJvb3Q6ICcnLFxuICAgIGZvb3Q6ICcnLFxuICAgIGRlZnM6ICcnLFxuICAgIGJvZHk6ICcnXG4gIH07XG5cbiAgdGhpcy5fZGVmcyA9IHtcbiAgICBncmFkaWVudDoge30sXG4gICAgY2xpcHBpbmc6IHt9XG4gIH07XG59XG5cbnZhciBwcm90b3R5cGUkNDggPSBpbmhlcml0cyhTVkdTdHJpbmdSZW5kZXJlciwgUmVuZGVyZXIpO1xudmFyIGJhc2UkMiA9IFJlbmRlcmVyLnByb3RvdHlwZTtcblxucHJvdG90eXBlJDQ4LnJlc2l6ZSA9IGZ1bmN0aW9uKHdpZHRoLCBoZWlnaHQsIG9yaWdpbiwgc2NhbGVGYWN0b3IpIHtcbiAgYmFzZSQyLnJlc2l6ZS5jYWxsKHRoaXMsIHdpZHRoLCBoZWlnaHQsIG9yaWdpbiwgc2NhbGVGYWN0b3IpO1xuICB2YXIgbyA9IHRoaXMuX29yaWdpbixcbiAgICAgIHQgPSB0aGlzLl90ZXh0O1xuXG4gIHZhciBhdHRyID0ge1xuICAgIGNsYXNzOiAgICdtYXJrcycsXG4gICAgd2lkdGg6ICAgdGhpcy5fd2lkdGggKiB0aGlzLl9zY2FsZSxcbiAgICBoZWlnaHQ6ICB0aGlzLl9oZWlnaHQgKiB0aGlzLl9zY2FsZSxcbiAgICB2aWV3Qm94OiAnMCAwICcgKyB0aGlzLl93aWR0aCArICcgJyArIHRoaXMuX2hlaWdodFxuICB9O1xuICBmb3IgKHZhciBrZXkkJDEgaW4gbWV0YWRhdGEpIHtcbiAgICBhdHRyW2tleSQkMV0gPSBtZXRhZGF0YVtrZXkkJDFdO1xuICB9XG5cbiAgdC5oZWFkID0gb3BlblRhZygnc3ZnJywgYXR0cik7XG5cbiAgdmFyIGJnID0gdGhpcy5fYmdjb2xvcjtcbiAgaWYgKGJnID09PSAndHJhbnNwYXJlbnQnIHx8IGJnID09PSAnbm9uZScpIGJnID0gbnVsbDtcblxuICBpZiAoYmcpIHtcbiAgICB0LmJnID0gb3BlblRhZygncmVjdCcsIHtcbiAgICAgIHdpZHRoOiAgdGhpcy5fd2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuX2hlaWdodCxcbiAgICAgIHN0eWxlOiAgJ2ZpbGw6ICcgKyBiZyArICc7J1xuICAgIH0pICsgY2xvc2VUYWcoJ3JlY3QnKTtcbiAgfSBlbHNlIHtcbiAgICB0LmJnID0gJyc7XG4gIH1cblxuICB0LnJvb3QgPSBvcGVuVGFnKCdnJywge1xuICAgIHRyYW5zZm9ybTogJ3RyYW5zbGF0ZSgnICsgbyArICcpJ1xuICB9KTtcblxuICB0LmZvb3QgPSBjbG9zZVRhZygnZycpICsgY2xvc2VUYWcoJ3N2ZycpO1xuXG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDQ4LmJhY2tncm91bmQgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHJ2ID0gYmFzZSQyLmJhY2tncm91bmQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggJiYgdGhpcy5fdGV4dC5oZWFkKSB7XG4gICAgdGhpcy5yZXNpemUodGhpcy5fd2lkdGgsIHRoaXMuX2hlaWdodCwgdGhpcy5fb3JpZ2luLCB0aGlzLl9zY2FsZSk7XG4gIH1cbiAgcmV0dXJuIHJ2O1xufTtcblxucHJvdG90eXBlJDQ4LnN2ZyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgdCA9IHRoaXMuX3RleHQ7XG4gIHJldHVybiB0LmhlYWQgKyB0LmJnICsgdC5kZWZzICsgdC5yb290ICsgdC5ib2R5ICsgdC5mb290O1xufTtcblxucHJvdG90eXBlJDQ4Ll9yZW5kZXIgPSBmdW5jdGlvbihzY2VuZSkge1xuICB0aGlzLl90ZXh0LmJvZHkgPSB0aGlzLm1hcmsoc2NlbmUpO1xuICB0aGlzLl90ZXh0LmRlZnMgPSB0aGlzLmJ1aWxkRGVmcygpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ0OC5idWlsZERlZnMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGFsbCA9IHRoaXMuX2RlZnMsXG4gICAgICBkZWZzID0gJycsXG4gICAgICBpLCBpZCQkMSwgZGVmLCBzdG9wcztcblxuICBmb3IgKGlkJCQxIGluIGFsbC5ncmFkaWVudCkge1xuICAgIGRlZiA9IGFsbC5ncmFkaWVudFtpZCQkMV07XG4gICAgc3RvcHMgPSBkZWYuc3RvcHM7XG5cbiAgICBkZWZzICs9IG9wZW5UYWcoJ2xpbmVhckdyYWRpZW50Jywge1xuICAgICAgaWQ6IGlkJCQxLFxuICAgICAgeDE6IGRlZi54MSxcbiAgICAgIHgyOiBkZWYueDIsXG4gICAgICB5MTogZGVmLnkxLFxuICAgICAgeTI6IGRlZi55MlxuICAgIH0pO1xuXG4gICAgZm9yIChpPTA7IGk8c3RvcHMubGVuZ3RoOyArK2kpIHtcbiAgICAgIGRlZnMgKz0gb3BlblRhZygnc3RvcCcsIHtcbiAgICAgICAgb2Zmc2V0OiBzdG9wc1tpXS5vZmZzZXQsXG4gICAgICAgICdzdG9wLWNvbG9yJzogc3RvcHNbaV0uY29sb3JcbiAgICAgIH0pICsgY2xvc2VUYWcoJ3N0b3AnKTtcbiAgICB9XG5cbiAgICBkZWZzICs9IGNsb3NlVGFnKCdsaW5lYXJHcmFkaWVudCcpO1xuICB9XG5cbiAgZm9yIChpZCQkMSBpbiBhbGwuY2xpcHBpbmcpIHtcbiAgICBkZWYgPSBhbGwuY2xpcHBpbmdbaWQkJDFdO1xuXG4gICAgZGVmcyArPSBvcGVuVGFnKCdjbGlwUGF0aCcsIHtpZDogaWQkJDF9KTtcblxuICAgIGlmIChkZWYucGF0aCkge1xuICAgICAgZGVmcyArPSBvcGVuVGFnKCdwYXRoJywge1xuICAgICAgICBkOiBkZWYucGF0aFxuICAgICAgfSkgKyBjbG9zZVRhZygncGF0aCcpO1xuICAgIH0gZWxzZSB7XG4gICAgICBkZWZzICs9IG9wZW5UYWcoJ3JlY3QnLCB7XG4gICAgICAgIHg6IDAsXG4gICAgICAgIHk6IDAsXG4gICAgICAgIHdpZHRoOiBkZWYud2lkdGgsXG4gICAgICAgIGhlaWdodDogZGVmLmhlaWdodFxuICAgICAgfSkgKyBjbG9zZVRhZygncmVjdCcpO1xuICAgIH1cblxuICAgIGRlZnMgKz0gY2xvc2VUYWcoJ2NsaXBQYXRoJyk7XG4gIH1cblxuICByZXR1cm4gKGRlZnMubGVuZ3RoID4gMCkgPyBvcGVuVGFnKCdkZWZzJykgKyBkZWZzICsgY2xvc2VUYWcoJ2RlZnMnKSA6ICcnO1xufTtcblxudmFyIG9iamVjdCQxO1xuXG5mdW5jdGlvbiBlbWl0JDEobmFtZSwgdmFsdWUsIG5zLCBwcmVmaXhlZCkge1xuICBvYmplY3QkMVtwcmVmaXhlZCB8fCBuYW1lXSA9IHZhbHVlO1xufVxuXG5wcm90b3R5cGUkNDguYXR0cmlidXRlcyA9IGZ1bmN0aW9uKGF0dHIsIGl0ZW0pIHtcbiAgb2JqZWN0JDEgPSB7fTtcbiAgYXR0cihlbWl0JDEsIGl0ZW0sIHRoaXMpO1xuICByZXR1cm4gb2JqZWN0JDE7XG59O1xuXG5wcm90b3R5cGUkNDguaHJlZiA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgdmFyIHRoYXQgPSB0aGlzLFxuICAgICAgaHJlZiA9IGl0ZW0uaHJlZixcbiAgICAgIGF0dHI7XG5cbiAgaWYgKGhyZWYpIHtcbiAgICBpZiAoYXR0ciA9IHRoYXQuX2hyZWZzICYmIHRoYXQuX2hyZWZzW2hyZWZdKSB7XG4gICAgICByZXR1cm4gYXR0cjtcbiAgICB9IGVsc2Uge1xuICAgICAgdGhhdC5zYW5pdGl6ZVVSTChocmVmKS50aGVuKGZ1bmN0aW9uKGF0dHIpIHtcbiAgICAgICAgLy8gcmV3cml0ZSB0byB1c2UgeGxpbmsgbmFtZXNwYWNlXG4gICAgICAgIC8vIG5vdGUgdGhhdCB0aGlzIHdpbGwgYmUgZGVwcmVjYXRlZCBpbiBTVkcgMi4wXG4gICAgICAgIGF0dHJbJ3hsaW5rOmhyZWYnXSA9IGF0dHIuaHJlZjtcbiAgICAgICAgYXR0ci5ocmVmID0gbnVsbDtcbiAgICAgICAgKHRoYXQuX2hyZWZzIHx8ICh0aGF0Ll9ocmVmcyA9IHt9KSlbaHJlZl0gPSBhdHRyO1xuICAgICAgfSk7XG4gICAgfVxuICB9XG4gIHJldHVybiBudWxsO1xufTtcblxucHJvdG90eXBlJDQ4Lm1hcmsgPSBmdW5jdGlvbihzY2VuZSkge1xuICB2YXIgcmVuZGVyZXIgPSB0aGlzLFxuICAgICAgbWRlZiA9IG1hcmtzW3NjZW5lLm1hcmt0eXBlXSxcbiAgICAgIHRhZyAgPSBtZGVmLnRhZyxcbiAgICAgIGRlZnMgPSB0aGlzLl9kZWZzLFxuICAgICAgc3RyID0gJycsXG4gICAgICBzdHlsZTtcblxuICBpZiAodGFnICE9PSAnZycgJiYgc2NlbmUuaW50ZXJhY3RpdmUgPT09IGZhbHNlKSB7XG4gICAgc3R5bGUgPSAnc3R5bGU9XCJwb2ludGVyLWV2ZW50czogbm9uZTtcIic7XG4gIH1cblxuICAvLyByZW5kZXIgb3BlbmluZyBncm91cCB0YWdcbiAgc3RyICs9IG9wZW5UYWcoJ2cnLCB7XG4gICAgJ2NsYXNzJzogY3NzQ2xhc3Moc2NlbmUpLFxuICAgICdjbGlwLXBhdGgnOiBzY2VuZS5jbGlwID8gY2xpcChyZW5kZXJlciwgc2NlbmUsIHNjZW5lLmdyb3VwKSA6IG51bGxcbiAgfSwgc3R5bGUpO1xuXG4gIC8vIHJlbmRlciBjb250YWluZWQgZWxlbWVudHNcbiAgZnVuY3Rpb24gcHJvY2VzcyhpdGVtKSB7XG4gICAgdmFyIGhyZWYgPSByZW5kZXJlci5ocmVmKGl0ZW0pO1xuICAgIGlmIChocmVmKSBzdHIgKz0gb3BlblRhZygnYScsIGhyZWYpO1xuXG4gICAgc3R5bGUgPSAodGFnICE9PSAnZycpID8gYXBwbHlTdHlsZXMoaXRlbSwgc2NlbmUsIHRhZywgZGVmcykgOiBudWxsO1xuICAgIHN0ciArPSBvcGVuVGFnKHRhZywgcmVuZGVyZXIuYXR0cmlidXRlcyhtZGVmLmF0dHIsIGl0ZW0pLCBzdHlsZSk7XG5cbiAgICBpZiAodGFnID09PSAndGV4dCcpIHtcbiAgICAgIHN0ciArPSBlc2NhcGVfdGV4dCh0ZXh0VmFsdWUoaXRlbSkpO1xuICAgIH0gZWxzZSBpZiAodGFnID09PSAnZycpIHtcbiAgICAgIHN0ciArPSBvcGVuVGFnKCdwYXRoJywgcmVuZGVyZXIuYXR0cmlidXRlcyhtZGVmLmJhY2tncm91bmQsIGl0ZW0pLFxuICAgICAgICBhcHBseVN0eWxlcyhpdGVtLCBzY2VuZSwgJ2JncmVjdCcsIGRlZnMpKSArIGNsb3NlVGFnKCdwYXRoJyk7XG5cbiAgICAgIHN0ciArPSBvcGVuVGFnKCdnJywgcmVuZGVyZXIuYXR0cmlidXRlcyhtZGVmLmZvcmVncm91bmQsIGl0ZW0pKVxuICAgICAgICArIHJlbmRlcmVyLm1hcmtHcm91cChpdGVtKVxuICAgICAgICArIGNsb3NlVGFnKCdnJyk7XG4gICAgfVxuXG4gICAgc3RyICs9IGNsb3NlVGFnKHRhZyk7XG4gICAgaWYgKGhyZWYpIHN0ciArPSBjbG9zZVRhZygnYScpO1xuICB9XG5cbiAgaWYgKG1kZWYubmVzdGVkKSB7XG4gICAgaWYgKHNjZW5lLml0ZW1zICYmIHNjZW5lLml0ZW1zLmxlbmd0aCkgcHJvY2VzcyhzY2VuZS5pdGVtc1swXSk7XG4gIH0gZWxzZSB7XG4gICAgdmlzaXQoc2NlbmUsIHByb2Nlc3MpO1xuICB9XG5cbiAgLy8gcmVuZGVyIGNsb3NpbmcgZ3JvdXAgdGFnXG4gIHJldHVybiBzdHIgKyBjbG9zZVRhZygnZycpO1xufTtcblxucHJvdG90eXBlJDQ4Lm1hcmtHcm91cCA9IGZ1bmN0aW9uKHNjZW5lKSB7XG4gIHZhciByZW5kZXJlciA9IHRoaXMsXG4gICAgICBzdHIgPSAnJztcblxuICB2aXNpdChzY2VuZSwgZnVuY3Rpb24oaXRlbSkge1xuICAgIHN0ciArPSByZW5kZXJlci5tYXJrKGl0ZW0pO1xuICB9KTtcblxuICByZXR1cm4gc3RyO1xufTtcblxuZnVuY3Rpb24gYXBwbHlTdHlsZXMobywgbWFyaywgdGFnLCBkZWZzKSB7XG4gIGlmIChvID09IG51bGwpIHJldHVybiAnJztcbiAgdmFyIGksIG4sIHByb3AsIG5hbWUsIHZhbHVlLCBzID0gJyc7XG5cbiAgaWYgKHRhZyA9PT0gJ2JncmVjdCcgJiYgbWFyay5pbnRlcmFjdGl2ZSA9PT0gZmFsc2UpIHtcbiAgICBzICs9ICdwb2ludGVyLWV2ZW50czogbm9uZTsgJztcbiAgfVxuXG4gIGlmICh0YWcgPT09ICd0ZXh0Jykge1xuICAgIHMgKz0gJ2ZvbnQ6ICcgKyBmb250KG8pICsgJzsgJztcbiAgfVxuXG4gIGZvciAoaT0wLCBuPXN0eWxlUHJvcGVydGllcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgcHJvcCA9IHN0eWxlUHJvcGVydGllc1tpXTtcbiAgICBuYW1lID0gc3R5bGVzW3Byb3BdO1xuICAgIHZhbHVlID0gb1twcm9wXTtcblxuICAgIGlmICh2YWx1ZSA9PSBudWxsKSB7XG4gICAgICBpZiAobmFtZSA9PT0gJ2ZpbGwnKSB7XG4gICAgICAgIHMgKz0gJ2ZpbGw6IG5vbmU7ICc7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh2YWx1ZSA9PT0gJ3RyYW5zcGFyZW50JyAmJiAobmFtZSA9PT0gJ2ZpbGwnIHx8IG5hbWUgPT09ICdzdHJva2UnKSkge1xuICAgICAgLy8gdHJhbnNwYXJlbnQgaXMgbm90IGEgbGVnYWwgU1ZHIHZhbHVlLCBzbyBtYXAgdG8gbm9uZSBpbnN0ZWFkXG4gICAgICBzICs9IG5hbWUgKyAnOiBub25lOyAnO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAodmFsdWUuaWQpIHtcbiAgICAgICAgLy8gZW5zdXJlIGRlZmluaXRpb24gaXMgaW5jbHVkZWRcbiAgICAgICAgZGVmcy5ncmFkaWVudFt2YWx1ZS5pZF0gPSB2YWx1ZTtcbiAgICAgICAgdmFsdWUgPSAndXJsKCMnICsgdmFsdWUuaWQgKyAnKSc7XG4gICAgICB9XG4gICAgICBzICs9IG5hbWUgKyAnOiAnICsgdmFsdWUgKyAnOyAnO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzID8gJ3N0eWxlPVwiJyArIHMudHJpbSgpICsgJ1wiJyA6IG51bGw7XG59XG5cbmZ1bmN0aW9uIGVzY2FwZV90ZXh0KHMpIHtcbiAgcmV0dXJuIHMucmVwbGFjZSgvJi9nLCAnJmFtcDsnKVxuICAgICAgICAgIC5yZXBsYWNlKC88L2csICcmbHQ7JylcbiAgICAgICAgICAucmVwbGFjZSgvPi9nLCAnJmd0OycpO1xufVxuXG52YXIgQ2FudmFzID0gJ2NhbnZhcyc7XG52YXIgUE5HID0gJ3BuZyc7XG52YXIgU1ZHID0gJ3N2Zyc7XG52YXIgTm9uZSQxID0gJ25vbmUnO1xuXG52YXIgUmVuZGVyVHlwZSA9IHtcbiAgQ2FudmFzOiBDYW52YXMsXG4gIFBORzogICAgUE5HLFxuICBTVkc6ICAgIFNWRyxcbiAgTm9uZTogICBOb25lJDFcbn07XG5cbnZhciBtb2R1bGVzID0ge307XG5cbm1vZHVsZXNbQ2FudmFzXSA9IG1vZHVsZXNbUE5HXSA9IHtcbiAgcmVuZGVyZXI6IENhbnZhc1JlbmRlcmVyLFxuICBoZWFkbGVzczogQ2FudmFzUmVuZGVyZXIsXG4gIGhhbmRsZXI6ICBDYW52YXNIYW5kbGVyXG59O1xuXG5tb2R1bGVzW1NWR10gPSB7XG4gIHJlbmRlcmVyOiBTVkdSZW5kZXJlcixcbiAgaGVhZGxlc3M6IFNWR1N0cmluZ1JlbmRlcmVyLFxuICBoYW5kbGVyOiAgU1ZHSGFuZGxlclxufTtcblxubW9kdWxlc1tOb25lJDFdID0ge307XG5cbmZ1bmN0aW9uIHJlbmRlck1vZHVsZShuYW1lLCBfKSB7XG4gIG5hbWUgPSBTdHJpbmcobmFtZSB8fCAnJykudG9Mb3dlckNhc2UoKTtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGggPiAxKSB7XG4gICAgbW9kdWxlc1tuYW1lXSA9IF87XG4gICAgcmV0dXJuIHRoaXM7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIG1vZHVsZXNbbmFtZV07XG4gIH1cbn1cblxudmFyIGNsaXBCb3VuZHMgPSBuZXcgQm91bmRzKCk7XG5cbnZhciBib3VuZENsaXAgPSBmdW5jdGlvbihtYXJrKSB7XG4gIHZhciBjbGlwID0gbWFyay5jbGlwO1xuXG4gIGlmIChpc0Z1bmN0aW9uKGNsaXApKSB7XG4gICAgY2xpcChjb250ZXh0KGNsaXBCb3VuZHMuY2xlYXIoKSkpO1xuICB9IGVsc2UgaWYgKGNsaXApIHtcbiAgICBjbGlwQm91bmRzLnNldCgwLCAwLCBtYXJrLmdyb3VwLndpZHRoLCBtYXJrLmdyb3VwLmhlaWdodCk7XG4gIH0gZWxzZSByZXR1cm47XG5cbiAgbWFyay5ib3VuZHMuaW50ZXJzZWN0KGNsaXBCb3VuZHMpO1xufTtcblxudmFyIFRPTEVSQU5DRSA9IDFlLTk7XG5cbmZ1bmN0aW9uIHNjZW5lRXF1YWwoYSwgYiwga2V5JCQxKSB7XG4gIHJldHVybiAoYSA9PT0gYikgPyB0cnVlXG4gICAgOiAoa2V5JCQxID09PSAncGF0aCcpID8gcGF0aEVxdWFsKGEsIGIpXG4gICAgOiAoYSBpbnN0YW5jZW9mIERhdGUgJiYgYiBpbnN0YW5jZW9mIERhdGUpID8gK2EgPT09ICtiXG4gICAgOiAoaXNOdW1iZXIoYSkgJiYgaXNOdW1iZXIoYikpID8gTWF0aC5hYnMoYSAtIGIpIDw9IFRPTEVSQU5DRVxuICAgIDogKCFhIHx8ICFiIHx8ICFpc09iamVjdChhKSAmJiAhaXNPYmplY3QoYikpID8gYSA9PSBiXG4gICAgOiAoYSA9PSBudWxsIHx8IGIgPT0gbnVsbCkgPyBmYWxzZVxuICAgIDogb2JqZWN0RXF1YWwoYSwgYik7XG59XG5cbmZ1bmN0aW9uIHBhdGhFcXVhbChhLCBiKSB7XG4gIHJldHVybiBzY2VuZUVxdWFsKHBhdGhQYXJzZShhKSwgcGF0aFBhcnNlKGIpKTtcbn1cblxuZnVuY3Rpb24gb2JqZWN0RXF1YWwoYSwgYikge1xuICB2YXIga2EgPSBPYmplY3Qua2V5cyhhKSxcbiAgICAgIGtiID0gT2JqZWN0LmtleXMoYiksXG4gICAgICBrZXkkJDEsIGk7XG5cbiAgaWYgKGthLmxlbmd0aCAhPT0ga2IubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cbiAga2Euc29ydCgpO1xuICBrYi5zb3J0KCk7XG5cbiAgZm9yIChpID0ga2EubGVuZ3RoIC0gMTsgaSA+PSAwOyBpLS0pIHtcbiAgICBpZiAoa2FbaV0gIT0ga2JbaV0pIHJldHVybiBmYWxzZTtcbiAgfVxuXG4gIGZvciAoaSA9IGthLmxlbmd0aCAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAga2V5JCQxID0ga2FbaV07XG4gICAgaWYgKCFzY2VuZUVxdWFsKGFba2V5JCQxXSwgYltrZXkkJDFdLCBrZXkkJDEpKSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHlwZW9mIGEgPT09IHR5cGVvZiBiO1xufVxuXG4vKipcbiAqIENhbGN1bGF0ZSBib3VuZGluZyBib3hlcyBmb3Igc2NlbmVncmFwaCBpdGVtcy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcy5tYXJrIC0gVGhlIHNjZW5lZ3JhcGggbWFyayBpbnN0YW5jZSB0byBib3VuZC5cbiAqL1xuZnVuY3Rpb24gQm91bmQocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbnZhciBwcm90b3R5cGUkMzggPSBpbmhlcml0cyhCb3VuZCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDM4LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciB2aWV3ID0gcHVsc2UuZGF0YWZsb3csXG4gICAgICBtYXJrID0gXy5tYXJrLFxuICAgICAgdHlwZSA9IG1hcmsubWFya3R5cGUsXG4gICAgICBlbnRyeSA9IG1hcmtzW3R5cGVdLFxuICAgICAgYm91bmQgPSBlbnRyeS5ib3VuZCxcbiAgICAgIG1hcmtCb3VuZHMgPSBtYXJrLmJvdW5kcywgcmVib3VuZDtcblxuICBpZiAoZW50cnkubmVzdGVkKSB7XG4gICAgLy8gbXVsdGktaXRlbSBtYXJrcyBoYXZlIGEgc2luZ2xlIGJvdW5kcyBpbnN0YW5jZVxuICAgIGlmIChtYXJrLml0ZW1zLmxlbmd0aCkgdmlldy5kaXJ0eShtYXJrLml0ZW1zWzBdKTtcbiAgICBtYXJrQm91bmRzID0gYm91bmRJdGVtKG1hcmssIGJvdW5kKTtcbiAgICBtYXJrLml0ZW1zLmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xuICAgICAgaXRlbS5ib3VuZHMuY2xlYXIoKS51bmlvbihtYXJrQm91bmRzKTtcbiAgICB9KTtcbiAgfVxuXG4gIGVsc2UgaWYgKHR5cGUgPT09ICdncm91cCcgfHwgXy5tb2RpZmllZCgpKSB7XG4gICAgLy8gb3BlcmF0b3IgcGFyYW1ldGVycyBtb2RpZmllZCAtPiByZS1ib3VuZCBhbGwgaXRlbXNcbiAgICAvLyB1cGRhdGVzIGdyb3VwIGJvdW5kcyBpbiByZXNwb25zZSB0byBtb2RpZmllZCBncm91cCBjb250ZW50XG4gICAgcHVsc2UudmlzaXQocHVsc2UuTU9ELCBmdW5jdGlvbihpdGVtKSB7IHZpZXcuZGlydHkoaXRlbSk7IH0pO1xuICAgIG1hcmtCb3VuZHMuY2xlYXIoKTtcbiAgICBtYXJrLml0ZW1zLmZvckVhY2goZnVuY3Rpb24oaXRlbSkge1xuICAgICAgbWFya0JvdW5kcy51bmlvbihib3VuZEl0ZW0oaXRlbSwgYm91bmQpKTtcbiAgICB9KTtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIC8vIGluY3JlbWVudGFsbHkgdXBkYXRlIGJvdW5kcywgcmUtYm91bmQgbWFyayBhcyBuZWVkZWRcbiAgICByZWJvdW5kID0gcHVsc2UuY2hhbmdlZChwdWxzZS5SRU0pO1xuXG4gICAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbihpdGVtKSB7XG4gICAgICBtYXJrQm91bmRzLnVuaW9uKGJvdW5kSXRlbShpdGVtLCBib3VuZCkpO1xuICAgIH0pO1xuXG4gICAgcHVsc2UudmlzaXQocHVsc2UuTU9ELCBmdW5jdGlvbihpdGVtKSB7XG4gICAgICByZWJvdW5kID0gcmVib3VuZCB8fCBtYXJrQm91bmRzLmFsaWduc1dpdGgoaXRlbS5ib3VuZHMpO1xuICAgICAgdmlldy5kaXJ0eShpdGVtKTtcbiAgICAgIG1hcmtCb3VuZHMudW5pb24oYm91bmRJdGVtKGl0ZW0sIGJvdW5kKSk7XG4gICAgfSk7XG5cbiAgICBpZiAocmVib3VuZCkge1xuICAgICAgbWFya0JvdW5kcy5jbGVhcigpO1xuICAgICAgbWFyay5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKGl0ZW0pIHsgbWFya0JvdW5kcy51bmlvbihpdGVtLmJvdW5kcyk7IH0pO1xuICAgIH1cbiAgfVxuXG4gIC8vIGVuc3VyZSBtYXJrIGJvdW5kcyBkbyBub3QgZXhjZWVkIGFueSBjbGlwcGluZyByZWdpb25cbiAgYm91bmRDbGlwKG1hcmspO1xuXG4gIHJldHVybiBwdWxzZS5tb2RpZmllcygnYm91bmRzJyk7XG59O1xuXG5mdW5jdGlvbiBib3VuZEl0ZW0oaXRlbSwgYm91bmQsIG9wdCkge1xuICByZXR1cm4gYm91bmQoaXRlbS5ib3VuZHMuY2xlYXIoKSwgaXRlbSwgb3B0KTtcbn1cblxudmFyIENPVU5URVJfTkFNRSA9ICc6dmVnYV9pZGVudGlmaWVyOic7XG5cbi8qKlxuICogQWRkcyBhIHVuaXF1ZSBpZGVudGlmaWVyIHRvIGFsbCBhZGRlZCB0dXBsZXMuXG4gKiBUaGlzIHRyYW5zZm9ybSBjcmVhdGVzIGEgbmV3IHNpZ25hbCB0aGF0IHNlcnZlcyBhcyBhbiBpZCBjb3VudGVyLlxuICogQXMgYSByZXN1bHQsIHRoZSBpZCBjb3VudGVyIGlzIHNoYXJlZCBhY3Jvc3MgYWxsIGluc3RhbmNlcyBvZiB0aGlzXG4gKiB0cmFuc2Zvcm0sIGdlbmVyYXRpbmcgdW5pcXVlIGlkcyBhY3Jvc3MgbXVsdGlwbGUgZGF0YSBzdHJlYW1zLiBJblxuICogYWRkaXRpb24sIHRoaXMgc2lnbmFsIHZhbHVlIGNhbiBiZSBpbmNsdWRlZCBpbiBhIHNuYXBzaG90IG9mIHRoZVxuICogZGF0YWZsb3cgc3RhdGUsIGVuYWJsaW5nIGNvcnJlY3QgcmVzdW1wdGlvbiBvZiBpZCBhbGxvY2F0aW9uLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge3N0cmluZ30gcGFyYW1zLmFzIC0gVGhlIGZpZWxkIG5hbWUgZm9yIHRoZSBnZW5lcmF0ZWQgaWRlbnRpZmllci5cbiAqL1xuZnVuY3Rpb24gSWRlbnRpZmllcihwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgMCwgcGFyYW1zKTtcbn1cblxuSWRlbnRpZmllci5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJJZGVudGlmaWVyXCIsXG4gIFwibWV0YWRhdGFcIjoge1wibW9kaWZpZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcInJlcXVpcmVkXCI6IHRydWUgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDQ5ID0gaW5oZXJpdHMoSWRlbnRpZmllciwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDQ5LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBjb3VudGVyID0gZ2V0Q291bnRlcihwdWxzZS5kYXRhZmxvdyksXG4gICAgICBpZCQkMSA9IGNvdW50ZXIudmFsdWUsXG4gICAgICBhcyA9IF8uYXM7XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuQURELCBmdW5jdGlvbih0KSB7XG4gICAgaWYgKCF0W2FzXSkgdFthc10gPSArK2lkJCQxO1xuICB9KTtcblxuICBjb3VudGVyLnNldCh0aGlzLnZhbHVlID0gaWQkJDEpO1xuICByZXR1cm4gcHVsc2U7XG59O1xuXG5mdW5jdGlvbiBnZXRDb3VudGVyKHZpZXcpIHtcbiAgdmFyIGNvdW50ZXIgPSB2aWV3Ll9zaWduYWxzW0NPVU5URVJfTkFNRV07XG4gIGlmICghY291bnRlcikge1xuICAgIHZpZXcuX3NpZ25hbHNbQ09VTlRFUl9OQU1FXSA9IChjb3VudGVyID0gdmlldy5hZGQoMCkpO1xuICB9XG4gIHJldHVybiBjb3VudGVyO1xufVxuXG4vKipcbiAqIEJpbmQgc2NlbmVncmFwaCBpdGVtcyB0byBhIHNjZW5lZ3JhcGggbWFyayBpbnN0YW5jZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcy5tYXJrZGVmIC0gVGhlIG1hcmsgZGVmaW5pdGlvbiBmb3IgY3JlYXRpbmcgdGhlIG1hcmsuXG4gKiAgIFRoaXMgaXMgYW4gb2JqZWN0IG9mIGxlZ2FsIHNjZW5lZ3JhcGggbWFyayBwcm9wZXJ0aWVzIHdoaWNoICptdXN0KiBpbmNsdWRlXG4gKiAgIHRoZSAnbWFya3R5cGUnIHByb3BlcnR5LlxuICovXG5mdW5jdGlvbiBNYXJrKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG52YXIgcHJvdG90eXBlJDUwID0gaW5oZXJpdHMoTWFyaywgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDUwLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBtYXJrID0gdGhpcy52YWx1ZTtcblxuICAvLyBhY3F1aXJlIG1hcmsgb24gZmlyc3QgaW52b2NhdGlvbiwgYmluZCBjb250ZXh0IGFuZCBncm91cFxuICBpZiAoIW1hcmspIHtcbiAgICBtYXJrID0gcHVsc2UuZGF0YWZsb3cuc2NlbmVncmFwaCgpLm1hcmsoXy5tYXJrZGVmLCBsb29rdXAkMShfKSwgXy5pbmRleCk7XG4gICAgbWFyay5ncm91cC5jb250ZXh0ID0gXy5jb250ZXh0O1xuICAgIGlmICghXy5jb250ZXh0Lmdyb3VwKSBfLmNvbnRleHQuZ3JvdXAgPSBtYXJrLmdyb3VwO1xuICAgIG1hcmsuc291cmNlID0gdGhpcztcbiAgICBtYXJrLmNsaXAgPSBfLmNsaXA7XG4gICAgbWFyay5pbnRlcmFjdGl2ZSA9IF8uaW50ZXJhY3RpdmU7XG4gICAgdGhpcy52YWx1ZSA9IG1hcms7XG4gIH1cblxuICAvLyBpbml0aWFsaXplIGVudGVyaW5nIGl0ZW1zXG4gIHZhciBJbml0ID0gbWFyay5tYXJrdHlwZSA9PT0gJ2dyb3VwJyA/IEdyb3VwSXRlbSA6IEl0ZW07XG4gIHB1bHNlLnZpc2l0KHB1bHNlLkFERCwgZnVuY3Rpb24oaXRlbSkgeyBJbml0LmNhbGwoaXRlbSwgbWFyayk7IH0pO1xuXG4gIC8vIHVwZGF0ZSBjbGlwcGluZyBhbmQvb3IgaW50ZXJhY3RpdmUgc3RhdHVzXG4gIGlmIChfLm1vZGlmaWVkKCdjbGlwJykgfHwgXy5tb2RpZmllZCgnaW50ZXJhY3RpdmUnKSkge1xuICAgIG1hcmsuY2xpcCA9IF8uY2xpcDtcbiAgICBtYXJrLmludGVyYWN0aXZlID0gISFfLmludGVyYWN0aXZlO1xuICAgIG1hcmsuemRpcnR5ID0gdHJ1ZTsgLy8gZm9yY2UgcmUtZXZhbFxuICAgIHB1bHNlLnJlZmxvdygpO1xuICB9XG5cbiAgLy8gYmluZCBpdGVtcyBhcnJheSB0byBzY2VuZWdyYXBoIG1hcmtcbiAgbWFyay5pdGVtcyA9IHB1bHNlLnNvdXJjZTtcbiAgcmV0dXJuIHB1bHNlO1xufTtcblxuZnVuY3Rpb24gbG9va3VwJDEoXykge1xuICB2YXIgZyA9IF8uZ3JvdXBzLCBwID0gXy5wYXJlbnQ7XG4gIHJldHVybiBnICYmIGcuc2l6ZSA9PT0gMSA/IGcuZ2V0KE9iamVjdC5rZXlzKGcub2JqZWN0KVswXSlcbiAgICA6IGcgJiYgcCA/IGcubG9va3VwKHApXG4gICAgOiBudWxsO1xufVxuXG52YXIgVG9wID0gJ3RvcCc7XG52YXIgTGVmdCA9ICdsZWZ0JztcbnZhciBSaWdodCA9ICdyaWdodCc7XG52YXIgQm90dG9tID0gJ2JvdHRvbSc7XG5cbi8qKlxuICogQW5hbHl6ZSBpdGVtcyBmb3Igb3ZlcmxhcCwgY2hhbmdpbmcgb3BhY2l0eSB0byBoaWRlIGl0ZW1zIHdpdGhcbiAqIG92ZXJsYXBwaW5nIGJvdW5kaW5nIGJveGVzLiBUaGlzIHRyYW5zZm9ybSB3aWxsIHByZXNlcnZlIGF0IGxlYXN0XG4gKiB0d28gaXRlbXMgKGUuZy4sIGZpcnN0IGFuZCBsYXN0KSBldmVuIGlmIG92ZXJsYXAgcGVyc2lzdHMuXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosKik6IG51bWJlcn0gW3BhcmFtcy5zb3J0XSAtIEEgY29tcGFyYXRvclxuICogICBmdW5jdGlvbiBmb3Igc29ydGluZyBpdGVtcy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbcGFyYW1zLm1ldGhvZF0gLSBUaGUgb3ZlcmxhcCByZW1vdmFsIG1ldGhvZCB0byBhcHBseS5cbiAqICAgT25lIG9mICdwYXJpdHknIChkZWZhdWx0LCBoaWRlIGV2ZXJ5IG90aGVyIGl0ZW0gdW50aWwgdGhlcmUgaXMgbm9cbiAqICAgbW9yZSBvdmVybGFwKSBvciAnZ3JlZWR5JyAoc2VxdWVudGlhbGx5IHNjYW4gYW5kIGhpZGUgYW5kIGl0ZW1zIHRoYXRcbiAqICAgb3ZlcmxhcCB3aXRoIHRoZSBsYXN0IHZpc2libGUgaXRlbSkuXG4gKiBAcGFyYW0ge29iamVjdH0gW3BhcmFtcy5ib3VuZFNjYWxlXSAtIEEgc2NhbGUgd2hvc2UgcmFuZ2Ugc2hvdWxkIGJlIHVzZWRcbiAqICAgdG8gYm91bmQgdGhlIGl0ZW1zLiBJdGVtcyBleGNlZWRpbmcgdGhlIGJvdW5kcyBvZiB0aGUgc2NhbGUgcmFuZ2VcbiAqICAgd2lsbCBiZSB0cmVhdGVkIGFzIG92ZXJsYXBwaW5nLiBJZiBudWxsIG9yIHVuZGVmaW5lZCwgbm8gYm91bmRzIGNoZWNrXG4gKiAgIHdpbGwgYmUgYXBwbGllZC5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbcGFyYW1zLmJvdW5kT3JpZW50XSAtIFRoZSBvcmllbnRhdGlvbiBvZiB0aGUgc2NhbGVcbiAqICAgKHRvcCwgYm90dG9tLCBsZWZ0LCBvciByaWdodCkgdXNlZCB0byBib3VuZCBpdGVtcy4gVGhpcyBwYXJhbWV0ZXIgaXNcbiAqICAgaWdub3JlZCBpZiBib3VuZFNjYWxlIGlzIG51bGwgb3IgdW5kZWZpbmVkLlxuICogQHBhcmFtIHtvYmplY3R9IFtwYXJhbXMuYm91bmRUb2xlcmFuY2VdIC0gVGhlIHRvbGVyYW5jZSBpbiBwaXhlbHMgZm9yXG4gKiAgIGJvdW5kIGluY2x1c2lvbiB0ZXN0aW5nIChkZWZhdWx0IDEpLiBUaGlzIHNwZWNpZmllcyBieSBob3cgbWFueSBwaXhlbHNcbiAqICAgYW4gaXRlbSdzIGJvdW5kcyBtYXkgZXhjZWVkIHRoZSBzY2FsZSByYW5nZSBib3VuZHMgYW5kIG5vdCBiZSBjdWxsZWQuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gT3ZlcmxhcChwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ1MSA9IGluaGVyaXRzKE92ZXJsYXAsIFRyYW5zZm9ybSk7XG5cbnZhciBtZXRob2RzID0ge1xuICBwYXJpdHk6IGZ1bmN0aW9uKGl0ZW1zKSB7XG4gICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihmdW5jdGlvbihpdGVtLCBpKSB7XG4gICAgICByZXR1cm4gaSAlIDIgPyAoaXRlbS5vcGFjaXR5ID0gMCkgOiAxO1xuICAgIH0pO1xuICB9LFxuICBncmVlZHk6IGZ1bmN0aW9uKGl0ZW1zKSB7XG4gICAgdmFyIGE7XG4gICAgcmV0dXJuIGl0ZW1zLmZpbHRlcihmdW5jdGlvbihiLCBpKSB7XG4gICAgICBpZiAoIWkgfHwgIWludGVyc2VjdCQxKGEuYm91bmRzLCBiLmJvdW5kcykpIHtcbiAgICAgICAgYSA9IGI7XG4gICAgICAgIHJldHVybiAxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmV0dXJuIGIub3BhY2l0eSA9IDA7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cbn07XG5cbi8vIGNvbXB1dGUgYm91bmRpbmcgYm94IGludGVyc2VjdGlvblxuLy8gYWxsb3cgMSBwaXhlbCBvZiBvdmVybGFwIHRvbGVyYW5jZVxuZnVuY3Rpb24gaW50ZXJzZWN0JDEoYSwgYikge1xuICByZXR1cm4gIShcbiAgICBhLngyIC0gMSA8IGIueDEgfHxcbiAgICBhLngxICsgMSA+IGIueDIgfHxcbiAgICBhLnkyIC0gMSA8IGIueTEgfHxcbiAgICBhLnkxICsgMSA+IGIueTJcbiAgKTtcbn1cblxuZnVuY3Rpb24gaGFzT3ZlcmxhcChpdGVtcykge1xuICBmb3IgKHZhciBpPTEsIG49aXRlbXMubGVuZ3RoLCBhPWl0ZW1zWzBdLmJvdW5kcywgYjsgaTxuOyBhPWIsICsraSkge1xuICAgIGlmIChpbnRlcnNlY3QkMShhLCBiID0gaXRlbXNbaV0uYm91bmRzKSkgcmV0dXJuIHRydWU7XG4gIH1cbn1cblxuZnVuY3Rpb24gaGFzQm91bmRzKGl0ZW0pIHtcbiAgdmFyIGIgPSBpdGVtLmJvdW5kcztcbiAgcmV0dXJuIGIud2lkdGgoKSA+IDEgJiYgYi5oZWlnaHQoKSA+IDE7XG59XG5cbmZ1bmN0aW9uIGJvdW5kVGVzdChzY2FsZSwgb3JpZW50LCB0b2xlcmFuY2UpIHtcbiAgdmFyIHJhbmdlID0gc2NhbGUucmFuZ2UoKSxcbiAgICAgIGIgPSBuZXcgQm91bmRzKCk7XG5cbiAgaWYgKG9yaWVudCA9PT0gVG9wIHx8IG9yaWVudCA9PT0gQm90dG9tKSB7XG4gICAgYi5zZXQocmFuZ2VbMF0sIC1JbmZpbml0eSwgcmFuZ2VbMV0sICtJbmZpbml0eSk7XG4gIH0gZWxzZSB7XG4gICAgYi5zZXQoLUluZmluaXR5LCByYW5nZVswXSwgK0luZmluaXR5LCByYW5nZVsxXSk7XG4gIH1cbiAgYi5leHBhbmQodG9sZXJhbmNlIHx8IDEpO1xuXG4gIHJldHVybiBmdW5jdGlvbihpdGVtKSB7XG4gICAgcmV0dXJuIGIuZW5jbG9zZXMoaXRlbS5ib3VuZHMpO1xuICB9O1xufVxuXG5wcm90b3R5cGUkNTEudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIHJlZHVjZSA9IG1ldGhvZHNbXy5tZXRob2RdIHx8IG1ldGhvZHMucGFyaXR5LFxuICAgICAgc291cmNlID0gcHVsc2UubWF0ZXJpYWxpemUocHVsc2UuU09VUkNFKS5zb3VyY2U7XG5cbiAgaWYgKCFzb3VyY2UpIHJldHVybjtcblxuICBpZiAoXy5zb3J0KSB7XG4gICAgc291cmNlID0gc291cmNlLnNsaWNlKCkuc29ydChfLnNvcnQpO1xuICB9XG5cbiAgaWYgKF8ubWV0aG9kID09PSAnZ3JlZWR5Jykge1xuICAgIHNvdXJjZSA9IHNvdXJjZS5maWx0ZXIoaGFzQm91bmRzKTtcbiAgfVxuXG4gIC8vIHJlc2V0IGFsbCBpdGVtcyB0byBiZSBmdWxseSBvcGFxdWVcbiAgc291cmNlLmZvckVhY2goZnVuY3Rpb24oaXRlbSkgeyBpdGVtLm9wYWNpdHkgPSAxOyB9KTtcblxuICB2YXIgaXRlbXMgPSBzb3VyY2U7XG5cbiAgaWYgKGl0ZW1zLmxlbmd0aCA+PSAzICYmIGhhc092ZXJsYXAoaXRlbXMpKSB7XG4gICAgcHVsc2UgPSBwdWxzZS5yZWZsb3coXy5tb2RpZmllZCgpKS5tb2RpZmllcygnb3BhY2l0eScpO1xuICAgIGRvIHtcbiAgICAgIGl0ZW1zID0gcmVkdWNlKGl0ZW1zKTtcbiAgICB9IHdoaWxlIChpdGVtcy5sZW5ndGggPj0gMyAmJiBoYXNPdmVybGFwKGl0ZW1zKSk7XG5cbiAgICBpZiAoaXRlbXMubGVuZ3RoIDwgMyAmJiAhcGVlayhzb3VyY2UpLm9wYWNpdHkpIHtcbiAgICAgIGlmIChpdGVtcy5sZW5ndGggPiAxKSBwZWVrKGl0ZW1zKS5vcGFjaXR5ID0gMDtcbiAgICAgIHBlZWsoc291cmNlKS5vcGFjaXR5ID0gMTtcbiAgICB9XG4gIH1cblxuICBpZiAoXy5ib3VuZFNjYWxlKSB7XG4gICAgdmFyIHRlc3QgPSBib3VuZFRlc3QoXy5ib3VuZFNjYWxlLCBfLmJvdW5kT3JpZW50LCBfLmJvdW5kVG9sZXJhbmNlKTtcbiAgICBzb3VyY2UuZm9yRWFjaChmdW5jdGlvbihpdGVtKSB7XG4gICAgICBpZiAoIXRlc3QoaXRlbSkpIGl0ZW0ub3BhY2l0eSA9IDA7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gcHVsc2U7XG59O1xuXG4vKipcbiAqIFF1ZXVlIG1vZGlmaWVkIHNjZW5lZ3JhcGggaXRlbXMgZm9yIHJlbmRlcmluZy5cbiAqIEBjb25zdHJ1Y3RvclxuICovXG5mdW5jdGlvbiBSZW5kZXIocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbnZhciBwcm90b3R5cGUkNTIgPSBpbmhlcml0cyhSZW5kZXIsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ1Mi50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgdmlldyA9IHB1bHNlLmRhdGFmbG93O1xuXG4gIHB1bHNlLnZpc2l0KHB1bHNlLkFMTCwgZnVuY3Rpb24oaXRlbSkgeyB2aWV3LmRpcnR5KGl0ZW0pOyB9KTtcblxuICAvLyBzZXQgei1pbmRleCBkaXJ0eSBmbGFnIGFzIG5lZWRlZFxuICBpZiAocHVsc2UuZmllbGRzICYmIHB1bHNlLmZpZWxkc1snemluZGV4J10pIHtcbiAgICB2YXIgaXRlbSA9IHB1bHNlLnNvdXJjZSAmJiBwdWxzZS5zb3VyY2VbMF07XG4gICAgaWYgKGl0ZW0pIGl0ZW0ubWFyay56ZGlydHkgPSB0cnVlO1xuICB9XG59O1xuXG52YXIgQXhpc1JvbGUkMSA9ICdheGlzJztcbnZhciBMZWdlbmRSb2xlJDEgPSAnbGVnZW5kJztcbnZhciBSb3dIZWFkZXIkMSA9ICdyb3ctaGVhZGVyJztcbnZhciBSb3dGb290ZXIkMSA9ICdyb3ctZm9vdGVyJztcbnZhciBSb3dUaXRsZSAgPSAncm93LXRpdGxlJztcbnZhciBDb2xIZWFkZXIkMSA9ICdjb2x1bW4taGVhZGVyJztcbnZhciBDb2xGb290ZXIkMSA9ICdjb2x1bW4tZm9vdGVyJztcbnZhciBDb2xUaXRsZSAgPSAnY29sdW1uLXRpdGxlJztcblxuZnVuY3Rpb24gZXh0cmFjdEdyb3Vwcyhncm91cCkge1xuICB2YXIgZ3JvdXBzID0gZ3JvdXAuaXRlbXMsXG4gICAgICBuID0gZ3JvdXBzLmxlbmd0aCxcbiAgICAgIGkgPSAwLCBtYXJrLCBpdGVtcztcblxuICB2YXIgdmlld3MgPSB7XG4gICAgbWFya3M6ICAgICAgW10sXG4gICAgcm93aGVhZGVyczogW10sXG4gICAgcm93Zm9vdGVyczogW10sXG4gICAgY29saGVhZGVyczogW10sXG4gICAgY29sZm9vdGVyczogW10sXG4gICAgcm93dGl0bGU6IG51bGwsXG4gICAgY29sdGl0bGU6IG51bGxcbiAgfTtcblxuICAvLyBsYXlvdXQgYXhlcywgZ2F0aGVyIGxlZ2VuZHMsIGNvbGxlY3QgYm91bmRzXG4gIGZvciAoOyBpPG47ICsraSkge1xuICAgIG1hcmsgPSBncm91cHNbaV07XG4gICAgaXRlbXMgPSBtYXJrLml0ZW1zO1xuICAgIGlmIChtYXJrLm1hcmt0eXBlID09PSAnZ3JvdXAnKSB7XG4gICAgICBzd2l0Y2ggKG1hcmsucm9sZSkge1xuICAgICAgICBjYXNlIEF4aXNSb2xlJDE6XG4gICAgICAgIGNhc2UgTGVnZW5kUm9sZSQxOlxuICAgICAgICAgIGJyZWFrO1xuICAgICAgICBjYXNlIFJvd0hlYWRlciQxOiBhZGRBbGwoaXRlbXMsIHZpZXdzLnJvd2hlYWRlcnMpOyBicmVhaztcbiAgICAgICAgY2FzZSBSb3dGb290ZXIkMTogYWRkQWxsKGl0ZW1zLCB2aWV3cy5yb3dmb290ZXJzKTsgYnJlYWs7XG4gICAgICAgIGNhc2UgQ29sSGVhZGVyJDE6IGFkZEFsbChpdGVtcywgdmlld3MuY29saGVhZGVycyk7IGJyZWFrO1xuICAgICAgICBjYXNlIENvbEZvb3RlciQxOiBhZGRBbGwoaXRlbXMsIHZpZXdzLmNvbGZvb3RlcnMpOyBicmVhaztcbiAgICAgICAgY2FzZSBSb3dUaXRsZTogIHZpZXdzLnJvd3RpdGxlID0gaXRlbXNbMF07IGJyZWFrO1xuICAgICAgICBjYXNlIENvbFRpdGxlOiAgdmlld3MuY29sdGl0bGUgPSBpdGVtc1swXTsgYnJlYWs7XG4gICAgICAgIGRlZmF1bHQ6ICAgICAgICBhZGRBbGwoaXRlbXMsIHZpZXdzLm1hcmtzKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gdmlld3M7XG59XG5cbmZ1bmN0aW9uIGFkZEFsbChpdGVtcywgYXJyYXkkJDEpIHtcbiAgZm9yICh2YXIgaT0wLCBuPWl0ZW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBhcnJheSQkMS5wdXNoKGl0ZW1zW2ldKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBiYm94Rmx1c2goaXRlbSkge1xuICByZXR1cm4ge3gxOiAwLCB5MTogMCwgeDI6IGl0ZW0ud2lkdGggfHwgMCwgeTI6IGl0ZW0uaGVpZ2h0IHx8IDB9O1xufVxuXG5mdW5jdGlvbiBiYm94RnVsbChpdGVtKSB7XG4gIHZhciBiID0gaXRlbS5ib3VuZHMuY2xvbmUoKTtcbiAgcmV0dXJuIGIuZW1wdHkoKVxuICAgID8gYi5zZXQoMCwgMCwgMCwgMClcbiAgICA6IGIudHJhbnNsYXRlKC0oaXRlbS54fHwwKSwgLShpdGVtLnl8fDApKTtcbn1cblxuZnVuY3Rpb24gYm91bmRGbHVzaChpdGVtLCBmaWVsZCQkMSkge1xuICByZXR1cm4gZmllbGQkJDEgPT09ICd4MScgPyAoaXRlbS54IHx8IDApXG4gICAgOiBmaWVsZCQkMSA9PT0gJ3kxJyA/IChpdGVtLnkgfHwgMClcbiAgICA6IGZpZWxkJCQxID09PSAneDInID8gKGl0ZW0ueCB8fCAwKSArIChpdGVtLndpZHRoIHx8IDApXG4gICAgOiBmaWVsZCQkMSA9PT0gJ3kyJyA/IChpdGVtLnkgfHwgMCkgKyAoaXRlbS5oZWlnaHQgfHwgMClcbiAgICA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gYm91bmRGdWxsKGl0ZW0sIGZpZWxkJCQxKSB7XG4gIHJldHVybiBpdGVtLmJvdW5kc1tmaWVsZCQkMV07XG59XG5cbmZ1bmN0aW9uIGdldCQyKG9wdCwga2V5JCQxLCBkKSB7XG4gIHZhciB2ID0gaXNPYmplY3Qob3B0KSA/IG9wdFtrZXkkJDFdIDogb3B0O1xuICByZXR1cm4gdiAhPSBudWxsID8gdiA6IChkICE9PSB1bmRlZmluZWQgPyBkIDogMCk7XG59XG5cbmZ1bmN0aW9uIG9mZnNldFZhbHVlKHYpIHtcbiAgcmV0dXJuIHYgPCAwID8gTWF0aC5jZWlsKC12KSA6IDA7XG59XG5cbmZ1bmN0aW9uIGdyaWRMYXlvdXQodmlldywgZ3JvdXAsIG9wdCkge1xuICB2YXIgdmlld3MgPSBleHRyYWN0R3JvdXBzKGdyb3VwLCBvcHQpLFxuICAgICAgZ3JvdXBzID0gdmlld3MubWFya3MsXG4gICAgICBmbHVzaCA9IG9wdC5ib3VuZHMgPT09ICdmbHVzaCcsXG4gICAgICBiYm94ID0gZmx1c2ggPyBiYm94Rmx1c2ggOiBiYm94RnVsbCxcbiAgICAgIGJvdW5kcyA9IG5ldyBCb3VuZHMoMCwgMCwgMCwgMCksXG4gICAgICBhbGlnbkNvbCA9IGdldCQyKG9wdC5hbGlnbiwgJ2NvbHVtbicpLFxuICAgICAgYWxpZ25Sb3cgPSBnZXQkMihvcHQuYWxpZ24sICdyb3cnKSxcbiAgICAgIHBhZENvbCA9IGdldCQyKG9wdC5wYWRkaW5nLCAnY29sdW1uJyksXG4gICAgICBwYWRSb3cgPSBnZXQkMihvcHQucGFkZGluZywgJ3JvdycpLFxuICAgICAgb2ZmID0gb3B0Lm9mZnNldCxcbiAgICAgIG5jb2xzID0gZ3JvdXAuY29sdW1ucyB8fCBvcHQuY29sdW1ucyB8fCBncm91cHMubGVuZ3RoLFxuICAgICAgbnJvd3MgPSBuY29scyA8IDAgPyAxIDogTWF0aC5jZWlsKGdyb3Vwcy5sZW5ndGggLyBuY29scyksXG4gICAgICBjZWxscyA9IG5yb3dzICogbmNvbHMsXG4gICAgICB4T2Zmc2V0ID0gW10sIHhFeHRlbnQgPSBbXSwgeEluaXQgPSAwLFxuICAgICAgeU9mZnNldCA9IFtdLCB5RXh0ZW50ID0gW10sIHlJbml0ID0gMCxcbiAgICAgIG4gPSBncm91cHMubGVuZ3RoLFxuICAgICAgbSwgaSwgYywgciwgYiwgZywgcHgsIHB5LCB4LCB5LCBiYW5kLCBleHRlbnQsIG9mZnNldDtcblxuICBmb3IgKGk9MDsgaTxuY29sczsgKytpKSB7XG4gICAgeEV4dGVudFtpXSA9IDA7XG4gIH1cbiAgZm9yIChpPTA7IGk8bnJvd3M7ICsraSkge1xuICAgIHlFeHRlbnRbaV0gPSAwO1xuICB9XG5cbiAgLy8gZGV0ZXJtaW5lIG9mZnNldHMgZm9yIGVhY2ggZ3JvdXBcbiAgZm9yIChpPTA7IGk8bjsgKytpKSB7XG4gICAgYiA9IGJib3goZ3JvdXBzW2ldKTtcbiAgICBjID0gaSAlIG5jb2xzO1xuICAgIHIgPSB+fihpIC8gbmNvbHMpO1xuICAgIHB4ID0gYyA/IE1hdGguY2VpbChiYm94KGdyb3Vwc1tpLTFdKS54Mik6IDA7XG4gICAgcHkgPSByID8gTWF0aC5jZWlsKGJib3goZ3JvdXBzW2ktbmNvbHNdKS55Mik6IDA7XG4gICAgeEV4dGVudFtjXSA9IE1hdGgubWF4KHhFeHRlbnRbY10sIHB4KTtcbiAgICB5RXh0ZW50W3JdID0gTWF0aC5tYXgoeUV4dGVudFtyXSwgcHkpO1xuICAgIHhPZmZzZXQucHVzaChwYWRDb2wgKyBvZmZzZXRWYWx1ZShiLngxKSk7XG4gICAgeU9mZnNldC5wdXNoKHBhZFJvdyArIG9mZnNldFZhbHVlKGIueTEpKTtcbiAgICB2aWV3LmRpcnR5KGdyb3Vwc1tpXSk7XG4gIH1cblxuICAvLyBzZXQgaW5pdGlhbCBhbGlnbm1lbnQgb2Zmc2V0c1xuICBmb3IgKGk9MDsgaTxuOyArK2kpIHtcbiAgICBpZiAoaSAlIG5jb2xzID09PSAwKSB4T2Zmc2V0W2ldID0geEluaXQ7XG4gICAgaWYgKGkgPCBuY29scykgeU9mZnNldFtpXSA9IHlJbml0O1xuICB9XG5cbiAgLy8gZW5mb3JjZSBjb2x1bW4gYWxpZ25tZW50IGNvbnN0cmFpbnRzXG4gIGlmIChhbGlnbkNvbCA9PT0gJ2VhY2gnKSB7XG4gICAgZm9yIChjPTE7IGM8bmNvbHM7ICsrYykge1xuICAgICAgZm9yIChvZmZzZXQ9MCwgaT1jOyBpPG47IGkgKz0gbmNvbHMpIHtcbiAgICAgICAgaWYgKG9mZnNldCA8IHhPZmZzZXRbaV0pIG9mZnNldCA9IHhPZmZzZXRbaV07XG4gICAgICB9XG4gICAgICBmb3IgKGk9YzsgaTxuOyBpICs9IG5jb2xzKSB7XG4gICAgICAgIHhPZmZzZXRbaV0gPSBvZmZzZXQgKyB4RXh0ZW50W2NdO1xuICAgICAgfVxuICAgIH1cbiAgfSBlbHNlIGlmIChhbGlnbkNvbCA9PT0gJ2FsbCcpIHtcbiAgICBmb3IgKGV4dGVudD0wLCBjPTE7IGM8bmNvbHM7ICsrYykge1xuICAgICAgaWYgKGV4dGVudCA8IHhFeHRlbnRbY10pIGV4dGVudCA9IHhFeHRlbnRbY107XG4gICAgfVxuICAgIGZvciAob2Zmc2V0PTAsIGk9MDsgaTxuOyArK2kpIHtcbiAgICAgIGlmIChpICUgbmNvbHMgJiYgb2Zmc2V0IDwgeE9mZnNldFtpXSkgb2Zmc2V0ID0geE9mZnNldFtpXTtcbiAgICB9XG4gICAgZm9yIChpPTA7IGk8bjsgKytpKSB7XG4gICAgICBpZiAoaSAlIG5jb2xzKSB4T2Zmc2V0W2ldID0gb2Zmc2V0ICsgZXh0ZW50O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKGM9MTsgYzxuY29sczsgKytjKSB7XG4gICAgICBmb3IgKGk9YzsgaTxuOyBpICs9IG5jb2xzKSB7XG4gICAgICAgIHhPZmZzZXRbaV0gKz0geEV4dGVudFtjXTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyBlbmZvcmNlIHJvdyBhbGlnbm1lbnQgY29uc3RyYWludHNcbiAgaWYgKGFsaWduUm93ID09PSAnZWFjaCcpIHtcbiAgICBmb3IgKHI9MTsgcjxucm93czsgKytyKSB7XG4gICAgICBmb3IgKG9mZnNldD0wLCBpPXIqbmNvbHMsIG09aStuY29sczsgaTxtOyArK2kpIHtcbiAgICAgICAgaWYgKG9mZnNldCA8IHlPZmZzZXRbaV0pIG9mZnNldCA9IHlPZmZzZXRbaV07XG4gICAgICB9XG4gICAgICBmb3IgKGk9cipuY29sczsgaTxtOyArK2kpIHtcbiAgICAgICAgeU9mZnNldFtpXSA9IG9mZnNldCArIHlFeHRlbnRbcl07XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2UgaWYgKGFsaWduUm93ID09PSAnYWxsJykge1xuICAgIGZvciAoZXh0ZW50PTAsIHI9MTsgcjxucm93czsgKytyKSB7XG4gICAgICBpZiAoZXh0ZW50IDwgeUV4dGVudFtyXSkgZXh0ZW50ID0geUV4dGVudFtyXTtcbiAgICB9XG4gICAgZm9yIChvZmZzZXQ9MCwgaT1uY29sczsgaTxuOyArK2kpIHtcbiAgICAgIGlmIChvZmZzZXQgPCB5T2Zmc2V0W2ldKSBvZmZzZXQgPSB5T2Zmc2V0W2ldO1xuICAgIH1cbiAgICBmb3IgKGk9bmNvbHM7IGk8bjsgKytpKSB7XG4gICAgICB5T2Zmc2V0W2ldID0gb2Zmc2V0ICsgZXh0ZW50O1xuICAgIH1cbiAgfSBlbHNlIHtcbiAgICBmb3IgKHI9MTsgcjxucm93czsgKytyKSB7XG4gICAgICBmb3IgKGk9cipuY29scywgbT1pK25jb2xzOyBpPG07ICsraSkge1xuICAgICAgICB5T2Zmc2V0W2ldICs9IHlFeHRlbnRbcl07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gcGVyZm9ybSBob3Jpem9udGFsIGdyaWQgbGF5b3V0XG4gIGZvciAoeD0wLCBpPTA7IGk8bjsgKytpKSB7XG4gICAgZyA9IGdyb3Vwc1tpXTtcbiAgICBweCA9IGcueCB8fCAwO1xuICAgIGcueCA9ICh4ID0geE9mZnNldFtpXSArIChpICUgbmNvbHMgPyB4IDogMCkpO1xuICAgIGcuYm91bmRzLnRyYW5zbGF0ZSh4IC0gcHgsIDApO1xuICB9XG5cbiAgLy8gcGVyZm9ybSB2ZXJ0aWNhbCBncmlkIGxheW91dFxuICBmb3IgKGM9MDsgYzxuY29sczsgKytjKSB7XG4gICAgZm9yICh5PTAsIGk9YzsgaTxuOyBpICs9IG5jb2xzKSB7XG4gICAgICBnID0gZ3JvdXBzW2ldO1xuICAgICAgcHkgPSBnLnkgfHwgMDtcbiAgICAgIGcueSA9ICh5ICs9IHlPZmZzZXRbaV0pO1xuICAgICAgZy5ib3VuZHMudHJhbnNsYXRlKDAsIHkgLSBweSk7XG4gICAgfVxuICB9XG5cbiAgLy8gdXBkYXRlIG1hcmsgYm91bmRzLCBtYXJrIGRpcnR5XG4gIGZvciAoaT0wOyBpPG47ICsraSkgZ3JvdXBzW2ldLm1hcmsuYm91bmRzLmNsZWFyKCk7XG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIGcgPSBncm91cHNbaV07XG4gICAgdmlldy5kaXJ0eShnKTtcbiAgICBib3VuZHMudW5pb24oZy5tYXJrLmJvdW5kcy51bmlvbihnLmJvdW5kcykpO1xuICB9XG5cbiAgLy8gLS0gbGF5b3V0IGdyaWQgaGVhZGVycyBhbmQgZm9vdGVycyAtLVxuXG4gIC8vIGFnZ3JlZ2F0aW9uIGZ1bmN0aW9ucyBmb3IgZ3JpZCBtYXJnaW4gZGV0ZXJtaW5hdGlvblxuICBmdW5jdGlvbiBtaW4oYSwgYikgeyByZXR1cm4gTWF0aC5mbG9vcihNYXRoLm1pbihhLCBiKSk7IH1cbiAgZnVuY3Rpb24gbWF4KGEsIGIpIHsgcmV0dXJuIE1hdGguY2VpbChNYXRoLm1heChhLCBiKSk7IH1cblxuICAvLyBib3VuZGluZyBib3ggY2FsY3VsYXRpb24gbWV0aG9kc1xuICBiYm94ID0gZmx1c2ggPyBib3VuZEZsdXNoIDogYm91bmRGdWxsO1xuXG4gIC8vIHBlcmZvcm0gcm93IGhlYWRlciBsYXlvdXRcbiAgYmFuZCA9IGdldCQyKG9wdC5oZWFkZXJCYW5kLCAncm93JywgbnVsbCk7XG4gIHggPSBsYXlvdXRIZWFkZXJzKHZpZXcsIHZpZXdzLnJvd2hlYWRlcnMsIGdyb3VwcywgbmNvbHMsIG5yb3dzLCAtZ2V0JDIob2ZmLCAncm93SGVhZGVyJyksICAgIG1pbiwgMCwgYmJveCwgJ3gxJywgMCwgbmNvbHMsIDEsIGJhbmQpO1xuXG4gIC8vIHBlcmZvcm0gY29sdW1uIGhlYWRlciBsYXlvdXRcbiAgYmFuZCA9IGdldCQyKG9wdC5oZWFkZXJCYW5kLCAnY29sdW1uJywgbnVsbCk7XG4gIHkgPSBsYXlvdXRIZWFkZXJzKHZpZXcsIHZpZXdzLmNvbGhlYWRlcnMsIGdyb3VwcywgbmNvbHMsIG5jb2xzLCAtZ2V0JDIob2ZmLCAnY29sdW1uSGVhZGVyJyksIG1pbiwgMSwgYmJveCwgJ3kxJywgMCwgMSwgbmNvbHMsIGJhbmQpO1xuXG4gIC8vIHBlcmZvcm0gcm93IGZvb3RlciBsYXlvdXRcbiAgYmFuZCA9IGdldCQyKG9wdC5mb290ZXJCYW5kLCAncm93JywgbnVsbCk7XG4gIGxheW91dEhlYWRlcnMoICAgIHZpZXcsIHZpZXdzLnJvd2Zvb3RlcnMsIGdyb3VwcywgbmNvbHMsIG5yb3dzLCAgZ2V0JDIob2ZmLCAncm93Rm9vdGVyJyksICAgIG1heCwgMCwgYmJveCwgJ3gyJywgbmNvbHMtMSwgbmNvbHMsIDEsIGJhbmQpO1xuXG4gIC8vIHBlcmZvcm0gY29sdW1uIGZvb3RlciBsYXlvdXRcbiAgYmFuZCA9IGdldCQyKG9wdC5mb290ZXJCYW5kLCAnY29sdW1uJywgbnVsbCk7XG4gIGxheW91dEhlYWRlcnMoICAgIHZpZXcsIHZpZXdzLmNvbGZvb3RlcnMsIGdyb3VwcywgbmNvbHMsIG5jb2xzLCAgZ2V0JDIob2ZmLCAnY29sdW1uRm9vdGVyJyksIG1heCwgMSwgYmJveCwgJ3kyJywgY2VsbHMtbmNvbHMsIDEsIG5jb2xzLCBiYW5kKTtcblxuICAvLyBwZXJmb3JtIHJvdyB0aXRsZSBsYXlvdXRcbiAgaWYgKHZpZXdzLnJvd3RpdGxlKSB7XG4gICAgb2Zmc2V0ID0geCAtIGdldCQyKG9mZiwgJ3Jvd1RpdGxlJyk7XG4gICAgYmFuZCA9IGdldCQyKG9wdC50aXRsZUJhbmQsICdyb3cnLCAwLjUpO1xuICAgIGxheW91dFRpdGxlJDEodmlldywgdmlld3Mucm93dGl0bGUsIG9mZnNldCwgMCwgYm91bmRzLCBiYW5kKTtcbiAgfVxuXG4gIC8vIHBlcmZvcm0gY29sdW1uIHRpdGxlIGxheW91dFxuICBpZiAodmlld3MuY29sdGl0bGUpIHtcbiAgICBvZmZzZXQgPSB5IC0gZ2V0JDIob2ZmLCAnY29sdW1uVGl0bGUnKTtcbiAgICBiYW5kID0gZ2V0JDIob3B0LnRpdGxlQmFuZCwgJ2NvbHVtbicsIDAuNSk7XG4gICAgbGF5b3V0VGl0bGUkMSh2aWV3LCB2aWV3cy5jb2x0aXRsZSwgb2Zmc2V0LCAxLCBib3VuZHMsIGJhbmQpO1xuICB9XG59XG5cbmZ1bmN0aW9uIGxheW91dEhlYWRlcnModmlldywgaGVhZGVycywgZ3JvdXBzLCBuY29scywgbGltaXQsIG9mZnNldCwgYWdnLCBpc1gsIGJvdW5kLCBiZiwgc3RhcnQsIHN0cmlkZSwgYmFjaywgYmFuZCkge1xuICB2YXIgbiA9IGdyb3Vwcy5sZW5ndGgsXG4gICAgICBpbml0ID0gMCxcbiAgICAgIGVkZ2UgPSAwLFxuICAgICAgaSwgaiwgaywgbSwgYiwgaCwgZywgeCwgeTtcblxuICAvLyBpZiBubyBncm91cHMsIGVhcmx5IGV4aXQgYW5kIHJldHVybiAwXG4gIGlmICghbikgcmV0dXJuIGluaXQ7XG5cbiAgLy8gY29tcHV0ZSBtYXJnaW5cbiAgZm9yIChpPXN0YXJ0OyBpPG47IGkrPXN0cmlkZSkge1xuICAgIGlmIChncm91cHNbaV0pIGluaXQgPSBhZ2coaW5pdCwgYm91bmQoZ3JvdXBzW2ldLCBiZikpO1xuICB9XG5cbiAgLy8gaWYgbm8gaGVhZGVycywgcmV0dXJuIG1hcmdpbiBjYWxjdWxhdGlvblxuICBpZiAoIWhlYWRlcnMubGVuZ3RoKSByZXR1cm4gaW5pdDtcblxuICAvLyBjaGVjayBpZiBudW1iZXIgb2YgaGVhZGVycyBleGNlZWRzIG51bWJlciBvZiByb3dzIG9yIGNvbHVtbnNcbiAgaWYgKGhlYWRlcnMubGVuZ3RoID4gbGltaXQpIHtcbiAgICB2aWV3Lndhcm4oJ0dyaWQgaGVhZGVycyBleGNlZWQgbGltaXQ6ICcgKyBsaW1pdCk7XG4gICAgaGVhZGVycyA9IGhlYWRlcnMuc2xpY2UoMCwgbGltaXQpO1xuICB9XG5cbiAgLy8gYXBwbHkgb2Zmc2V0XG4gIGluaXQgKz0gb2Zmc2V0O1xuXG4gIC8vIGNsZWFyIG1hcmsgYm91bmRzIGZvciBhbGwgaGVhZGVyc1xuICBmb3IgKGo9MCwgbT1oZWFkZXJzLmxlbmd0aDsgajxtOyArK2opIHtcbiAgICB2aWV3LmRpcnR5KGhlYWRlcnNbal0pO1xuICAgIGhlYWRlcnNbal0ubWFyay5ib3VuZHMuY2xlYXIoKTtcbiAgfVxuXG4gIC8vIGxheW91dCBlYWNoIGhlYWRlclxuICBmb3IgKGk9c3RhcnQsIGo9MCwgbT1oZWFkZXJzLmxlbmd0aDsgajxtOyArK2osIGkrPXN0cmlkZSkge1xuICAgIGggPSBoZWFkZXJzW2pdO1xuICAgIGIgPSBoLm1hcmsuYm91bmRzO1xuXG4gICAgLy8gc2VhcmNoIGZvciBuZWFyZXN0IGdyb3VwIHRvIGFsaWduIHRvXG4gICAgLy8gbmVjZXNzYXJ5IGlmIHRhYmxlIGhhcyBlbXB0eSBjZWxsc1xuICAgIGZvciAoaz1pOyBrID49IDAgJiYgKGcgPSBncm91cHNba10pID09IG51bGw7IGstPWJhY2spO1xuXG4gICAgLy8gYXNzaWduIGNvb3JkaW5hdGVzIGFuZCB1cGRhdGUgYm91bmRzXG4gICAgaWYgKGlzWCkge1xuICAgICAgeCA9IGJhbmQgPT0gbnVsbCA/IGcueCA6IE1hdGgucm91bmQoZy5ib3VuZHMueDEgKyBiYW5kICogZy5ib3VuZHMud2lkdGgoKSk7XG4gICAgICB5ID0gaW5pdDtcbiAgICB9IGVsc2Uge1xuICAgICAgeCA9IGluaXQ7XG4gICAgICB5ID0gYmFuZCA9PSBudWxsID8gZy55IDogTWF0aC5yb3VuZChnLmJvdW5kcy55MSArIGJhbmQgKiBnLmJvdW5kcy5oZWlnaHQoKSk7XG4gICAgfVxuICAgIGIudW5pb24oaC5ib3VuZHMudHJhbnNsYXRlKHggLSAoaC54IHx8IDApLCB5IC0gKGgueSB8fCAwKSkpO1xuICAgIGgueCA9IHg7XG4gICAgaC55ID0geTtcbiAgICB2aWV3LmRpcnR5KGgpO1xuXG4gICAgLy8gdXBkYXRlIGN1cnJlbnQgZWRnZSBvZiBsYXlvdXQgYm91bmRzXG4gICAgZWRnZSA9IGFnZyhlZGdlLCBiW2JmXSk7XG4gIH1cblxuICByZXR1cm4gZWRnZTtcbn1cblxuZnVuY3Rpb24gbGF5b3V0VGl0bGUkMSh2aWV3LCBnLCBvZmZzZXQsIGlzWCwgYm91bmRzLCBiYW5kKSB7XG4gIGlmICghZykgcmV0dXJuO1xuICB2aWV3LmRpcnR5KGcpO1xuXG4gIC8vIGNvbXB1dGUgdGl0bGUgY29vcmRpbmF0ZXNcbiAgdmFyIHggPSBvZmZzZXQsIHkgPSBvZmZzZXQ7XG4gIGlzWFxuICAgID8gKHggPSBNYXRoLnJvdW5kKGJvdW5kcy54MSArIGJhbmQgKiBib3VuZHMud2lkdGgoKSkpXG4gICAgOiAoeSA9IE1hdGgucm91bmQoYm91bmRzLnkxICsgYmFuZCAqIGJvdW5kcy5oZWlnaHQoKSkpO1xuXG4gIC8vIGFzc2lnbiBjb29yZGluYXRlcyBhbmQgdXBkYXRlIGJvdW5kc1xuICBnLmJvdW5kcy50cmFuc2xhdGUoeCAtIChnLnggfHwgMCksIHkgLSAoZy55IHx8IDApKTtcbiAgZy5tYXJrLmJvdW5kcy5jbGVhcigpLnVuaW9uKGcuYm91bmRzKTtcbiAgZy54ID0geDtcbiAgZy55ID0geTtcblxuICAvLyBxdWV1ZSB0aXRsZSBmb3IgcmVkcmF3XG4gIHZpZXcuZGlydHkoZyk7XG59XG5cbnZhciBGaXQgPSAnZml0JztcbnZhciBGaXRYID0gJ2ZpdC14JztcbnZhciBGaXRZID0gJ2ZpdC15JztcbnZhciBQYWQgPSAncGFkJztcbnZhciBOb25lJDIgPSAnbm9uZSc7XG52YXIgUGFkZGluZyA9ICdwYWRkaW5nJztcblxudmFyIEF4aXNSb2xlID0gJ2F4aXMnO1xudmFyIFRpdGxlUm9sZSA9ICd0aXRsZSc7XG52YXIgRnJhbWVSb2xlID0gJ2ZyYW1lJztcbnZhciBMZWdlbmRSb2xlID0gJ2xlZ2VuZCc7XG52YXIgU2NvcGVSb2xlID0gJ3Njb3BlJztcbnZhciBSb3dIZWFkZXIgPSAncm93LWhlYWRlcic7XG52YXIgUm93Rm9vdGVyID0gJ3Jvdy1mb290ZXInO1xudmFyIENvbEhlYWRlciA9ICdjb2x1bW4taGVhZGVyJztcbnZhciBDb2xGb290ZXIgPSAnY29sdW1uLWZvb3Rlcic7XG5cbnZhciBBeGlzT2Zmc2V0ID0gMC41O1xudmFyIHRlbXBCb3VuZHMkMiA9IG5ldyBCb3VuZHMoKTtcblxuLyoqXG4gKiBMYXlvdXQgdmlldyBlbGVtZW50cyBzdWNoIGFzIGF4ZXMgYW5kIGxlZ2VuZHMuXG4gKiBBbHNvIHBlcmZvcm1zIHNpemUgYWRqdXN0bWVudHMuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMubWFyayAtIFNjZW5lZ3JhcGggbWFyayBvZiBncm91cHMgdG8gbGF5b3V0LlxuICovXG5mdW5jdGlvbiBWaWV3TGF5b3V0KHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG52YXIgcHJvdG90eXBlJDUzID0gaW5oZXJpdHMoVmlld0xheW91dCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDUzLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIC8vIFRPRE8gaW5jcmVtZW50YWwgdXBkYXRlLCBvdXRwdXQ/XG4gIHZhciB2aWV3ID0gcHVsc2UuZGF0YWZsb3c7XG4gIF8ubWFyay5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKGdyb3VwKSB7XG4gICAgaWYgKF8ubGF5b3V0KSBncmlkTGF5b3V0KHZpZXcsIGdyb3VwLCBfLmxheW91dCk7XG4gICAgbGF5b3V0R3JvdXAodmlldywgZ3JvdXAsIF8pO1xuICB9KTtcbiAgcmV0dXJuIHB1bHNlO1xufTtcblxuZnVuY3Rpb24gbGF5b3V0R3JvdXAodmlldywgZ3JvdXAsIF8pIHtcbiAgdmFyIGl0ZW1zID0gZ3JvdXAuaXRlbXMsXG4gICAgICB3aWR0aCA9IE1hdGgubWF4KDAsIGdyb3VwLndpZHRoIHx8IDApLFxuICAgICAgaGVpZ2h0ID0gTWF0aC5tYXgoMCwgZ3JvdXAuaGVpZ2h0IHx8IDApLFxuICAgICAgdmlld0JvdW5kcyA9IG5ldyBCb3VuZHMoKS5zZXQoMCwgMCwgd2lkdGgsIGhlaWdodCksXG4gICAgICBheGlzQm91bmRzID0gdmlld0JvdW5kcy5jbG9uZSgpLFxuICAgICAgeEJvdW5kcyA9IHZpZXdCb3VuZHMuY2xvbmUoKSxcbiAgICAgIHlCb3VuZHMgPSB2aWV3Qm91bmRzLmNsb25lKCksXG4gICAgICBsZWdlbmRzID0gW10sIHRpdGxlLFxuICAgICAgbWFyaywgZmxvdywgYiwgaSwgbjtcblxuICAvLyBsYXlvdXQgYXhlcywgZ2F0aGVyIGxlZ2VuZHMsIGNvbGxlY3QgYm91bmRzXG4gIGZvciAoaT0wLCBuPWl0ZW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBtYXJrID0gaXRlbXNbaV07XG4gICAgc3dpdGNoIChtYXJrLnJvbGUpIHtcbiAgICAgIGNhc2UgQXhpc1JvbGU6XG4gICAgICAgIGF4aXNCb3VuZHMudW5pb24oYiA9IGxheW91dEF4aXModmlldywgbWFyaywgd2lkdGgsIGhlaWdodCkpO1xuICAgICAgICAoaXNZQXhpcyhtYXJrKSA/IHhCb3VuZHMgOiB5Qm91bmRzKS51bmlvbihiKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlIFRpdGxlUm9sZTpcbiAgICAgICAgdGl0bGUgPSBtYXJrOyBicmVhaztcbiAgICAgIGNhc2UgTGVnZW5kUm9sZTpcbiAgICAgICAgbGVnZW5kcy5wdXNoKG1hcmspOyBicmVhaztcbiAgICAgIGNhc2UgRnJhbWVSb2xlOlxuICAgICAgY2FzZSBTY29wZVJvbGU6XG4gICAgICBjYXNlIFJvd0hlYWRlcjpcbiAgICAgIGNhc2UgUm93Rm9vdGVyOlxuICAgICAgY2FzZSBDb2xIZWFkZXI6XG4gICAgICBjYXNlIENvbEZvb3RlcjpcbiAgICAgICAgeEJvdW5kcy51bmlvbihtYXJrLmJvdW5kcyk7XG4gICAgICAgIHlCb3VuZHMudW5pb24obWFyay5ib3VuZHMpO1xuICAgICAgICBicmVhaztcbiAgICAgIGRlZmF1bHQ6XG4gICAgICAgIHZpZXdCb3VuZHMudW5pb24obWFyay5ib3VuZHMpO1xuICAgIH1cbiAgfVxuXG4gIC8vIGxheW91dCB0aXRsZSwgYWRqdXN0IGJvdW5kc1xuICBpZiAodGl0bGUpIHtcbiAgICBheGlzQm91bmRzLnVuaW9uKGIgPSBsYXlvdXRUaXRsZSh2aWV3LCB0aXRsZSwgYXhpc0JvdW5kcykpO1xuICAgIChpc1lBeGlzKHRpdGxlKSA/IHhCb3VuZHMgOiB5Qm91bmRzKS51bmlvbihiKTtcbiAgfVxuXG4gIC8vIGxheW91dCBsZWdlbmRzLCBhZGp1c3Qgdmlld0JvdW5kc1xuICBpZiAobGVnZW5kcy5sZW5ndGgpIHtcbiAgICBmbG93ID0ge2xlZnQ6IDAsIHJpZ2h0OiAwLCB0b3A6IDAsIGJvdHRvbTogMCwgbWFyZ2luOiBfLmxlZ2VuZE1hcmdpbiB8fCA4fTtcblxuICAgIGZvciAoaT0wLCBuPWxlZ2VuZHMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgYiA9IGxheW91dExlZ2VuZCh2aWV3LCBsZWdlbmRzW2ldLCBmbG93LCB4Qm91bmRzLCB5Qm91bmRzLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAgIGlmIChfLmF1dG9zaXplICYmIF8uYXV0b3NpemUudHlwZSA9PT0gRml0KSB7XG4gICAgICAgIC8vIGZvciBhdXRvc2l6ZSBmaXQsIGluY29ycG9yYXRlIHRoZSBvcnRob2dvbmFsIGRpbWVuc2lvbiBvbmx5XG4gICAgICAgIC8vIGxlZ2VuZHMgdGhhdCBvdmVycnVuIHRoZSBjaGFydCBhcmVhIHdpbGwgdGhlbiBiZSBjbGlwcGVkXG4gICAgICAgIC8vIG90aGVyd2lzZSB0aGUgY2hhcnQgYXJlYSBnZXRzIHJlZHVjZWQgdG8gbm90aGluZyFcbiAgICAgICAgdmFyIG9yaWVudCA9IGxlZ2VuZHNbaV0uaXRlbXNbMF0uZGF0dW0ub3JpZW50O1xuICAgICAgICBpZiAob3JpZW50ID09PSBMZWZ0IHx8IG9yaWVudCA9PT0gUmlnaHQpIHtcbiAgICAgICAgICB2aWV3Qm91bmRzLmFkZChiLngxLCAwKS5hZGQoYi54MiwgMCk7XG4gICAgICAgIH0gZWxzZSBpZiAob3JpZW50ID09PSBUb3AgfHwgb3JpZW50ID09PSBCb3R0b20pIHtcbiAgICAgICAgICB2aWV3Qm91bmRzLmFkZCgwLCBiLnkxKS5hZGQoMCwgYi55Mik7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHZpZXdCb3VuZHMudW5pb24oYik7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gcGVyZm9ybSBzaXplIGFkanVzdG1lbnRcbiAgdmlld0JvdW5kcy51bmlvbih4Qm91bmRzKS51bmlvbih5Qm91bmRzKS51bmlvbihheGlzQm91bmRzKTtcbiAgbGF5b3V0U2l6ZSh2aWV3LCBncm91cCwgdmlld0JvdW5kcywgXyk7XG59XG5cbmZ1bmN0aW9uIHNldCQzKGl0ZW0sIHByb3BlcnR5LCB2YWx1ZSkge1xuICBpZiAoaXRlbVtwcm9wZXJ0eV0gPT09IHZhbHVlKSB7XG4gICAgcmV0dXJuIDA7XG4gIH0gZWxzZSB7XG4gICAgaXRlbVtwcm9wZXJ0eV0gPSB2YWx1ZTtcbiAgICByZXR1cm4gMTtcbiAgfVxufVxuXG5mdW5jdGlvbiBpc1lBeGlzKG1hcmspIHtcbiAgdmFyIG9yaWVudCA9IG1hcmsuaXRlbXNbMF0uZGF0dW0ub3JpZW50O1xuICByZXR1cm4gb3JpZW50ID09PSBMZWZ0IHx8IG9yaWVudCA9PT0gUmlnaHQ7XG59XG5cbmZ1bmN0aW9uIGF4aXNJbmRpY2VzKGRhdHVtKSB7XG4gIHZhciBpbmRleCA9ICtkYXR1bS5ncmlkO1xuICByZXR1cm4gW1xuICAgIGRhdHVtLnRpY2tzICA/IGluZGV4KysgOiAtMSwgLy8gdGlja3MgaW5kZXhcbiAgICBkYXR1bS5sYWJlbHMgPyBpbmRleCsrIDogLTEsIC8vIGxhYmVscyBpbmRleFxuICAgIGluZGV4ICsgKCtkYXR1bS5kb21haW4pICAgICAgLy8gdGl0bGUgaW5kZXhcbiAgXTtcbn1cblxuZnVuY3Rpb24gbGF5b3V0QXhpcyh2aWV3LCBheGlzLCB3aWR0aCwgaGVpZ2h0KSB7XG4gIHZhciBpdGVtID0gYXhpcy5pdGVtc1swXSxcbiAgICAgIGRhdHVtID0gaXRlbS5kYXR1bSxcbiAgICAgIG9yaWVudCA9IGRhdHVtLm9yaWVudCxcbiAgICAgIGluZGljZXMgPSBheGlzSW5kaWNlcyhkYXR1bSksXG4gICAgICByYW5nZSA9IGl0ZW0ucmFuZ2UsXG4gICAgICBvZmZzZXQgPSBpdGVtLm9mZnNldCxcbiAgICAgIHBvc2l0aW9uID0gaXRlbS5wb3NpdGlvbixcbiAgICAgIG1pbkV4dGVudCA9IGl0ZW0ubWluRXh0ZW50LFxuICAgICAgbWF4RXh0ZW50ID0gaXRlbS5tYXhFeHRlbnQsXG4gICAgICB0aXRsZSA9IGRhdHVtLnRpdGxlICYmIGl0ZW0uaXRlbXNbaW5kaWNlc1syXV0uaXRlbXNbMF0sXG4gICAgICB0aXRsZVBhZGRpbmcgPSBpdGVtLnRpdGxlUGFkZGluZyxcbiAgICAgIGJvdW5kcyA9IGl0ZW0uYm91bmRzLFxuICAgICAgeCA9IDAsIHkgPSAwLCBpLCBzO1xuXG4gIHRlbXBCb3VuZHMkMi5jbGVhcigpLnVuaW9uKGJvdW5kcyk7XG4gIGJvdW5kcy5jbGVhcigpO1xuICBpZiAoKGk9aW5kaWNlc1swXSkgPiAtMSkgYm91bmRzLnVuaW9uKGl0ZW0uaXRlbXNbaV0uYm91bmRzKTtcbiAgaWYgKChpPWluZGljZXNbMV0pID4gLTEpIGJvdW5kcy51bmlvbihpdGVtLml0ZW1zW2ldLmJvdW5kcyk7XG5cbiAgLy8gcG9zaXRpb24gYXhpcyBncm91cCBhbmQgdGl0bGVcbiAgc3dpdGNoIChvcmllbnQpIHtcbiAgICBjYXNlIFRvcDpcbiAgICAgIHggPSBwb3NpdGlvbiB8fCAwO1xuICAgICAgeSA9IC1vZmZzZXQ7XG4gICAgICBzID0gTWF0aC5tYXgobWluRXh0ZW50LCBNYXRoLm1pbihtYXhFeHRlbnQsIC1ib3VuZHMueTEpKTtcbiAgICAgIGlmICh0aXRsZSkge1xuICAgICAgICBpZiAodGl0bGUuYXV0bykge1xuICAgICAgICAgIHMgKz0gdGl0bGVQYWRkaW5nO1xuICAgICAgICAgIHRpdGxlLnkgPSAtcztcbiAgICAgICAgICBzICs9IHRpdGxlLmJvdW5kcy5oZWlnaHQoKTtcbiAgICAgICAgICBib3VuZHMuYWRkKHRpdGxlLmJvdW5kcy54MSwgMClcbiAgICAgICAgICAgICAgICAuYWRkKHRpdGxlLmJvdW5kcy54MiwgMCk7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYm91bmRzLnVuaW9uKHRpdGxlLmJvdW5kcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvdW5kcy5hZGQoMCwgLXMpLmFkZChyYW5nZSwgMCk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIExlZnQ6XG4gICAgICB4ID0gLW9mZnNldDtcbiAgICAgIHkgPSBwb3NpdGlvbiB8fCAwO1xuICAgICAgcyA9IE1hdGgubWF4KG1pbkV4dGVudCwgTWF0aC5taW4obWF4RXh0ZW50LCAtYm91bmRzLngxKSk7XG4gICAgICBpZiAodGl0bGUpIHtcbiAgICAgICAgaWYgKHRpdGxlLmF1dG8pIHtcbiAgICAgICAgICBzICs9IHRpdGxlUGFkZGluZztcbiAgICAgICAgICB0aXRsZS54ID0gLXM7XG4gICAgICAgICAgcyArPSB0aXRsZS5ib3VuZHMud2lkdGgoKTtcbiAgICAgICAgICBib3VuZHMuYWRkKDAsIHRpdGxlLmJvdW5kcy55MSlcbiAgICAgICAgICAgICAgICAuYWRkKDAsIHRpdGxlLmJvdW5kcy55Mik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYm91bmRzLnVuaW9uKHRpdGxlLmJvdW5kcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvdW5kcy5hZGQoLXMsIDApLmFkZCgwLCByYW5nZSk7XG4gICAgICBicmVhaztcbiAgICBjYXNlIFJpZ2h0OlxuICAgICAgeCA9IHdpZHRoICsgb2Zmc2V0O1xuICAgICAgeSA9IHBvc2l0aW9uIHx8IDA7XG4gICAgICBzID0gTWF0aC5tYXgobWluRXh0ZW50LCBNYXRoLm1pbihtYXhFeHRlbnQsIGJvdW5kcy54MikpO1xuICAgICAgaWYgKHRpdGxlKSB7XG4gICAgICAgIGlmICh0aXRsZS5hdXRvKSB7XG4gICAgICAgICAgcyArPSB0aXRsZVBhZGRpbmc7XG4gICAgICAgICAgdGl0bGUueCA9IHM7XG4gICAgICAgICAgcyArPSB0aXRsZS5ib3VuZHMud2lkdGgoKTtcbiAgICAgICAgICBib3VuZHMuYWRkKDAsIHRpdGxlLmJvdW5kcy55MSlcbiAgICAgICAgICAgICAgICAuYWRkKDAsIHRpdGxlLmJvdW5kcy55Mik7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgYm91bmRzLnVuaW9uKHRpdGxlLmJvdW5kcyk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGJvdW5kcy5hZGQoMCwgMCkuYWRkKHMsIHJhbmdlKTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgQm90dG9tOlxuICAgICAgeCA9IHBvc2l0aW9uIHx8IDA7XG4gICAgICB5ID0gaGVpZ2h0ICsgb2Zmc2V0O1xuICAgICAgcyA9IE1hdGgubWF4KG1pbkV4dGVudCwgTWF0aC5taW4obWF4RXh0ZW50LCBib3VuZHMueTIpKTtcbiAgICAgIGlmICh0aXRsZSkgaWYgKHRpdGxlLmF1dG8pIHtcbiAgICAgICAgcyArPSB0aXRsZVBhZGRpbmc7XG4gICAgICAgIHRpdGxlLnkgPSBzO1xuICAgICAgICBzICs9IHRpdGxlLmJvdW5kcy5oZWlnaHQoKTtcbiAgICAgICAgYm91bmRzLmFkZCh0aXRsZS5ib3VuZHMueDEsIDApXG4gICAgICAgICAgICAgIC5hZGQodGl0bGUuYm91bmRzLngyLCAwKTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGJvdW5kcy51bmlvbih0aXRsZS5ib3VuZHMpO1xuICAgICAgfVxuICAgICAgYm91bmRzLmFkZCgwLCAwKS5hZGQocmFuZ2UsIHMpO1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHggPSBpdGVtLng7XG4gICAgICB5ID0gaXRlbS55O1xuICB9XG5cbiAgLy8gdXBkYXRlIGJvdW5kc1xuICBib3VuZFN0cm9rZShib3VuZHMudHJhbnNsYXRlKHgsIHkpLCBpdGVtKTtcblxuICBpZiAoc2V0JDMoaXRlbSwgJ3gnLCB4ICsgQXhpc09mZnNldCkgfCBzZXQkMyhpdGVtLCAneScsIHkgKyBBeGlzT2Zmc2V0KSkge1xuICAgIGl0ZW0uYm91bmRzID0gdGVtcEJvdW5kcyQyO1xuICAgIHZpZXcuZGlydHkoaXRlbSk7XG4gICAgaXRlbS5ib3VuZHMgPSBib3VuZHM7XG4gICAgdmlldy5kaXJ0eShpdGVtKTtcbiAgfVxuXG4gIHJldHVybiBpdGVtLm1hcmsuYm91bmRzLmNsZWFyKCkudW5pb24oYm91bmRzKTtcbn1cblxuZnVuY3Rpb24gbGF5b3V0VGl0bGUodmlldywgdGl0bGUsIGF4aXNCb3VuZHMpIHtcbiAgdmFyIGl0ZW0gPSB0aXRsZS5pdGVtc1swXSxcbiAgICAgIGRhdHVtID0gaXRlbS5kYXR1bSxcbiAgICAgIG9yaWVudCA9IGRhdHVtLm9yaWVudCxcbiAgICAgIG9mZnNldCA9IGl0ZW0ub2Zmc2V0LFxuICAgICAgYm91bmRzID0gaXRlbS5ib3VuZHMsXG4gICAgICB4ID0gMCwgeSA9IDA7XG5cbiAgdGVtcEJvdW5kcyQyLmNsZWFyKCkudW5pb24oYm91bmRzKTtcblxuICAvLyBwb3NpdGlvbiBheGlzIGdyb3VwIGFuZCB0aXRsZVxuICBzd2l0Y2ggKG9yaWVudCkge1xuICAgIGNhc2UgVG9wOlxuICAgICAgeCA9IGl0ZW0ueDtcbiAgICAgIHkgPSBheGlzQm91bmRzLnkxIC0gb2Zmc2V0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBMZWZ0OlxuICAgICAgeCA9IGF4aXNCb3VuZHMueDEgLSBvZmZzZXQ7XG4gICAgICB5ID0gaXRlbS55O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBSaWdodDpcbiAgICAgIHggPSBheGlzQm91bmRzLngyICsgb2Zmc2V0O1xuICAgICAgeSA9IGl0ZW0ueTtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgQm90dG9tOlxuICAgICAgeCA9IGl0ZW0ueDtcbiAgICAgIHkgPSBheGlzQm91bmRzLnkyICsgb2Zmc2V0O1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHggPSBpdGVtLng7XG4gICAgICB5ID0gaXRlbS55O1xuICB9XG5cbiAgYm91bmRzLnRyYW5zbGF0ZSh4IC0gaXRlbS54LCB5IC0gaXRlbS55KTtcbiAgaWYgKHNldCQzKGl0ZW0sICd4JywgeCkgfCBzZXQkMyhpdGVtLCAneScsIHkpKSB7XG4gICAgaXRlbS5ib3VuZHMgPSB0ZW1wQm91bmRzJDI7XG4gICAgdmlldy5kaXJ0eShpdGVtKTtcbiAgICBpdGVtLmJvdW5kcyA9IGJvdW5kcztcbiAgICB2aWV3LmRpcnR5KGl0ZW0pO1xuICB9XG5cbiAgLy8gdXBkYXRlIGJvdW5kc1xuICByZXR1cm4gdGl0bGUuYm91bmRzLmNsZWFyKCkudW5pb24oYm91bmRzKTtcbn1cblxuZnVuY3Rpb24gbGF5b3V0TGVnZW5kKHZpZXcsIGxlZ2VuZCwgZmxvdywgeEJvdW5kcywgeUJvdW5kcywgd2lkdGgsIGhlaWdodCkge1xuICB2YXIgaXRlbSA9IGxlZ2VuZC5pdGVtc1swXSxcbiAgICAgIGRhdHVtID0gaXRlbS5kYXR1bSxcbiAgICAgIG9yaWVudCA9IGRhdHVtLm9yaWVudCxcbiAgICAgIG9mZnNldCA9IGl0ZW0ub2Zmc2V0LFxuICAgICAgYm91bmRzID0gaXRlbS5ib3VuZHMsXG4gICAgICB4ID0gMCxcbiAgICAgIHkgPSAwLFxuICAgICAgdywgaCwgYXhpc0JvdW5kcztcblxuICBpZiAob3JpZW50ID09PSBUb3AgfHwgb3JpZW50ID09PSBCb3R0b20pIHtcbiAgICBheGlzQm91bmRzID0geUJvdW5kcyxcbiAgICB4ID0gZmxvd1tvcmllbnRdO1xuICB9IGVsc2UgaWYgKG9yaWVudCA9PT0gTGVmdCB8fCBvcmllbnQgPT09IFJpZ2h0KSB7XG4gICAgYXhpc0JvdW5kcyA9IHhCb3VuZHM7XG4gICAgeSA9IGZsb3dbb3JpZW50XTtcbiAgfVxuXG4gIHRlbXBCb3VuZHMkMi5jbGVhcigpLnVuaW9uKGJvdW5kcyk7XG4gIGJvdW5kcy5jbGVhcigpO1xuXG4gIC8vIGFnZ3JlZ2F0ZSBib3VuZHMgdG8gZGV0ZXJtaW5lIHNpemVcbiAgLy8gc2hhdmUgb2ZmIDEgcGl4ZWwgYmVjYXVzZSBpdCBsb29rcyBiZXR0ZXIuLi5cbiAgaXRlbS5pdGVtcy5mb3JFYWNoKGZ1bmN0aW9uKF8pIHsgYm91bmRzLnVuaW9uKF8uYm91bmRzKTsgfSk7XG4gIHcgPSBNYXRoLnJvdW5kKGJvdW5kcy53aWR0aCgpKSArIDIgKiBpdGVtLnBhZGRpbmcgLSAxO1xuICBoID0gTWF0aC5yb3VuZChib3VuZHMuaGVpZ2h0KCkpICsgMiAqIGl0ZW0ucGFkZGluZyAtIDE7XG5cbiAgc3dpdGNoIChvcmllbnQpIHtcbiAgICBjYXNlIExlZnQ6XG4gICAgICB4IC09IHcgKyBvZmZzZXQgLSBNYXRoLmZsb29yKGF4aXNCb3VuZHMueDEpO1xuICAgICAgZmxvdy5sZWZ0ICs9IGggKyBmbG93Lm1hcmdpbjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgUmlnaHQ6XG4gICAgICB4ICs9IG9mZnNldCArIE1hdGguY2VpbChheGlzQm91bmRzLngyKTtcbiAgICAgIGZsb3cucmlnaHQgKz0gaCArIGZsb3cubWFyZ2luO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBUb3A6XG4gICAgICB5IC09IGggKyBvZmZzZXQgLSBNYXRoLmZsb29yKGF4aXNCb3VuZHMueTEpO1xuICAgICAgZmxvdy50b3AgKz0gdyArIGZsb3cubWFyZ2luO1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSBCb3R0b206XG4gICAgICB5ICs9IG9mZnNldCArIE1hdGguY2VpbChheGlzQm91bmRzLnkyKTtcbiAgICAgIGZsb3cuYm90dG9tICs9IHcgKyBmbG93Lm1hcmdpbjtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ3RvcC1sZWZ0JzpcbiAgICAgIHggKz0gb2Zmc2V0O1xuICAgICAgeSArPSBvZmZzZXQ7XG4gICAgICBicmVhaztcbiAgICBjYXNlICd0b3AtcmlnaHQnOlxuICAgICAgeCArPSB3aWR0aCAtIHcgLSBvZmZzZXQ7XG4gICAgICB5ICs9IG9mZnNldDtcbiAgICAgIGJyZWFrO1xuICAgIGNhc2UgJ2JvdHRvbS1sZWZ0JzpcbiAgICAgIHggKz0gb2Zmc2V0O1xuICAgICAgeSArPSBoZWlnaHQgLSBoIC0gb2Zmc2V0O1xuICAgICAgYnJlYWs7XG4gICAgY2FzZSAnYm90dG9tLXJpZ2h0JzpcbiAgICAgIHggKz0gd2lkdGggLSB3IC0gb2Zmc2V0O1xuICAgICAgeSArPSBoZWlnaHQgLSBoIC0gb2Zmc2V0O1xuICAgICAgYnJlYWs7XG4gICAgZGVmYXVsdDpcbiAgICAgIHggPSBpdGVtLng7XG4gICAgICB5ID0gaXRlbS55O1xuICB9XG5cbiAgLy8gdXBkYXRlIGJvdW5kc1xuICBib3VuZFN0cm9rZShib3VuZHMuc2V0KHgsIHksIHggKyB3LCB5ICsgaCksIGl0ZW0pO1xuXG4gIC8vIHVwZGF0ZSBsZWdlbmQgbGF5b3V0XG4gIGlmIChzZXQkMyhpdGVtLCAneCcsIHgpIHwgc2V0JDMoaXRlbSwgJ3dpZHRoJywgdykgfFxuICAgICAgc2V0JDMoaXRlbSwgJ3knLCB5KSB8IHNldCQzKGl0ZW0sICdoZWlnaHQnLCBoKSkge1xuICAgIGl0ZW0uYm91bmRzID0gdGVtcEJvdW5kcyQyO1xuICAgIHZpZXcuZGlydHkoaXRlbSk7XG4gICAgaXRlbS5ib3VuZHMgPSBib3VuZHM7XG4gICAgdmlldy5kaXJ0eShpdGVtKTtcbiAgfVxuXG4gIHJldHVybiBpdGVtLm1hcmsuYm91bmRzLmNsZWFyKCkudW5pb24oYm91bmRzKTtcbn1cblxuZnVuY3Rpb24gbGF5b3V0U2l6ZSh2aWV3LCBncm91cCwgdmlld0JvdW5kcywgXykge1xuICB2YXIgYXV0byA9IF8uYXV0b3NpemUgfHwge30sXG4gICAgICB0eXBlID0gYXV0by50eXBlLFxuICAgICAgdmlld1dpZHRoID0gdmlldy5fd2lkdGgsXG4gICAgICB2aWV3SGVpZ2h0ID0gdmlldy5faGVpZ2h0LFxuICAgICAgcGFkZGluZyA9IHZpZXcucGFkZGluZygpO1xuXG4gIGlmICh2aWV3Ll9hdXRvc2l6ZSA8IDEgfHwgIXR5cGUpIHJldHVybjtcblxuICB2YXIgd2lkdGggID0gTWF0aC5tYXgoMCwgZ3JvdXAud2lkdGggfHwgMCksXG4gICAgICBsZWZ0ICAgPSBNYXRoLm1heCgwLCBNYXRoLmNlaWwoLXZpZXdCb3VuZHMueDEpKSxcbiAgICAgIHJpZ2h0ICA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCh2aWV3Qm91bmRzLngyIC0gd2lkdGgpKSxcbiAgICAgIGhlaWdodCA9IE1hdGgubWF4KDAsIGdyb3VwLmhlaWdodCB8fCAwKSxcbiAgICAgIHRvcCAgICA9IE1hdGgubWF4KDAsIE1hdGguY2VpbCgtdmlld0JvdW5kcy55MSkpLFxuICAgICAgYm90dG9tID0gTWF0aC5tYXgoMCwgTWF0aC5jZWlsKHZpZXdCb3VuZHMueTIgLSBoZWlnaHQpKTtcblxuICBpZiAoYXV0by5jb250YWlucyA9PT0gUGFkZGluZykge1xuICAgIHZpZXdXaWR0aCAtPSBwYWRkaW5nLmxlZnQgKyBwYWRkaW5nLnJpZ2h0O1xuICAgIHZpZXdIZWlnaHQgLT0gcGFkZGluZy50b3AgKyBwYWRkaW5nLmJvdHRvbTtcbiAgfVxuXG4gIGlmICh0eXBlID09PSBOb25lJDIpIHtcbiAgICBsZWZ0ID0gMDtcbiAgICB0b3AgPSAwO1xuICAgIHdpZHRoID0gdmlld1dpZHRoO1xuICAgIGhlaWdodCA9IHZpZXdIZWlnaHQ7XG4gIH1cblxuICBlbHNlIGlmICh0eXBlID09PSBGaXQpIHtcbiAgICB3aWR0aCA9IE1hdGgubWF4KDAsIHZpZXdXaWR0aCAtIGxlZnQgLSByaWdodCk7XG4gICAgaGVpZ2h0ID0gTWF0aC5tYXgoMCwgdmlld0hlaWdodCAtIHRvcCAtIGJvdHRvbSk7XG4gIH1cblxuICBlbHNlIGlmICh0eXBlID09PSBGaXRYKSB7XG4gICAgd2lkdGggPSBNYXRoLm1heCgwLCB2aWV3V2lkdGggLSBsZWZ0IC0gcmlnaHQpO1xuICAgIHZpZXdIZWlnaHQgPSBoZWlnaHQgKyB0b3AgKyBib3R0b207XG4gIH1cblxuICBlbHNlIGlmICh0eXBlID09PSBGaXRZKSB7XG4gICAgdmlld1dpZHRoID0gd2lkdGggKyBsZWZ0ICsgcmlnaHQ7XG4gICAgaGVpZ2h0ID0gTWF0aC5tYXgoMCwgdmlld0hlaWdodCAtIHRvcCAtIGJvdHRvbSk7XG4gIH1cblxuICBlbHNlIGlmICh0eXBlID09PSBQYWQpIHtcbiAgICB2aWV3V2lkdGggPSB3aWR0aCArIGxlZnQgKyByaWdodDtcbiAgICB2aWV3SGVpZ2h0ID0gaGVpZ2h0ICsgdG9wICsgYm90dG9tO1xuICB9XG5cbiAgdmlldy5fcmVzaXplVmlldyhcbiAgICB2aWV3V2lkdGgsIHZpZXdIZWlnaHQsXG4gICAgd2lkdGgsIGhlaWdodCxcbiAgICBbbGVmdCwgdG9wXSxcbiAgICBhdXRvLnJlc2l6ZVxuICApO1xufVxuXG5cblxudmFyIHZ0eCA9IE9iamVjdC5mcmVlemUoe1xuXHRib3VuZDogQm91bmQsXG5cdGlkZW50aWZpZXI6IElkZW50aWZpZXIsXG5cdG1hcms6IE1hcmssXG5cdG92ZXJsYXA6IE92ZXJsYXAsXG5cdHJlbmRlcjogUmVuZGVyLFxuXHR2aWV3bGF5b3V0OiBWaWV3TGF5b3V0XG59KTtcblxudmFyIExvZyA9ICdsb2cnO1xudmFyIFBvdyA9ICdwb3cnO1xudmFyIFV0YyA9ICd1dGMnO1xudmFyIFNxcnQgPSAnc3FydCc7XG52YXIgQmFuZCA9ICdiYW5kJztcbnZhciBUaW1lID0gJ3RpbWUnO1xudmFyIFBvaW50ID0gJ3BvaW50JztcbnZhciBMaW5lYXIkMSA9ICdsaW5lYXInO1xudmFyIE9yZGluYWwgPSAnb3JkaW5hbCc7XG52YXIgUXVhbnRpbGUgPSAncXVhbnRpbGUnO1xudmFyIFF1YW50aXplID0gJ3F1YW50aXplJztcbnZhciBUaHJlc2hvbGQgPSAndGhyZXNob2xkJztcbnZhciBCaW5MaW5lYXIgPSAnYmluLWxpbmVhcic7XG52YXIgQmluT3JkaW5hbCA9ICdiaW4tb3JkaW5hbCc7XG52YXIgU2VxdWVudGlhbCA9ICdzZXF1ZW50aWFsJztcblxudmFyIGludmVydFJhbmdlID0gZnVuY3Rpb24oc2NhbGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKF8pIHtcbiAgICB2YXIgbG8gPSBfWzBdLFxuICAgICAgICBoaSA9IF9bMV0sXG4gICAgICAgIHQ7XG5cbiAgICBpZiAoaGkgPCBsbykge1xuICAgICAgdCA9IGxvO1xuICAgICAgbG8gPSBoaTtcbiAgICAgIGhpID0gdDtcbiAgICB9XG5cbiAgICByZXR1cm4gW1xuICAgICAgc2NhbGUuaW52ZXJ0KGxvKSxcbiAgICAgIHNjYWxlLmludmVydChoaSlcbiAgICBdO1xuICB9XG59O1xuXG52YXIgaW52ZXJ0UmFuZ2VFeHRlbnQgPSBmdW5jdGlvbihzY2FsZSkge1xuICByZXR1cm4gZnVuY3Rpb24oXykge1xuICAgIHZhciByYW5nZSA9IHNjYWxlLnJhbmdlKCksXG4gICAgICAgIGxvID0gX1swXSxcbiAgICAgICAgaGkgPSBfWzFdLFxuICAgICAgICBtaW4gPSAtMSwgbWF4LCB0LCBpLCBuO1xuXG4gICAgaWYgKGhpIDwgbG8pIHtcbiAgICAgIHQgPSBsbztcbiAgICAgIGxvID0gaGk7XG4gICAgICBoaSA9IHQ7XG4gICAgfVxuXG4gICAgZm9yIChpPTAsIG49cmFuZ2UubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgaWYgKHJhbmdlW2ldID49IGxvICYmIHJhbmdlW2ldIDw9IGhpKSB7XG4gICAgICAgIGlmIChtaW4gPCAwKSBtaW4gPSBpO1xuICAgICAgICBtYXggPSBpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChtaW4gPCAwKSByZXR1cm4gdW5kZWZpbmVkO1xuXG4gICAgbG8gPSBzY2FsZS5pbnZlcnRFeHRlbnQocmFuZ2VbbWluXSk7XG4gICAgaGkgPSBzY2FsZS5pbnZlcnRFeHRlbnQocmFuZ2VbbWF4XSk7XG5cbiAgICByZXR1cm4gW1xuICAgICAgbG9bMF0gPT09IHVuZGVmaW5lZCA/IGxvWzFdIDogbG9bMF0sXG4gICAgICBoaVsxXSA9PT0gdW5kZWZpbmVkID8gaGlbMF0gOiBoaVsxXVxuICAgIF07XG4gIH1cbn07XG5cbnZhciBiYW5kU3BhY2UgPSBmdW5jdGlvbihjb3VudCwgcGFkZGluZ0lubmVyLCBwYWRkaW5nT3V0ZXIpIHtcbiAgdmFyIHNwYWNlID0gY291bnQgLSBwYWRkaW5nSW5uZXIgKyBwYWRkaW5nT3V0ZXIgKiAyO1xuICByZXR1cm4gY291bnQgPyAoc3BhY2UgPiAwID8gc3BhY2UgOiAxKSA6IDA7XG59O1xuXG52YXIgYXJyYXkkMiA9IEFycmF5LnByb3RvdHlwZTtcblxudmFyIG1hcCQzID0gYXJyYXkkMi5tYXA7XG52YXIgc2xpY2UkMiA9IGFycmF5JDIuc2xpY2U7XG5cbnZhciBpbXBsaWNpdCA9IHtuYW1lOiBcImltcGxpY2l0XCJ9O1xuXG5mdW5jdGlvbiBvcmRpbmFsKHJhbmdlKSB7XG4gIHZhciBpbmRleCA9IG1hcCgpLFxuICAgICAgZG9tYWluID0gW10sXG4gICAgICB1bmtub3duID0gaW1wbGljaXQ7XG5cbiAgcmFuZ2UgPSByYW5nZSA9PSBudWxsID8gW10gOiBzbGljZSQyLmNhbGwocmFuZ2UpO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKGQpIHtcbiAgICB2YXIga2V5ID0gZCArIFwiXCIsIGkgPSBpbmRleC5nZXQoa2V5KTtcbiAgICBpZiAoIWkpIHtcbiAgICAgIGlmICh1bmtub3duICE9PSBpbXBsaWNpdCkgcmV0dXJuIHVua25vd247XG4gICAgICBpbmRleC5zZXQoa2V5LCBpID0gZG9tYWluLnB1c2goZCkpO1xuICAgIH1cbiAgICByZXR1cm4gcmFuZ2VbKGkgLSAxKSAlIHJhbmdlLmxlbmd0aF07XG4gIH1cblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluLnNsaWNlKCk7XG4gICAgZG9tYWluID0gW10sIGluZGV4ID0gbWFwKCk7XG4gICAgdmFyIGkgPSAtMSwgbiA9IF8ubGVuZ3RoLCBkLCBrZXk7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmICghaW5kZXguaGFzKGtleSA9IChkID0gX1tpXSkgKyBcIlwiKSkgaW5kZXguc2V0KGtleSwgZG9tYWluLnB1c2goZCkpO1xuICAgIHJldHVybiBzY2FsZTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSA9IHNsaWNlJDIuY2FsbChfKSwgc2NhbGUpIDogcmFuZ2Uuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS51bmtub3duID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHVua25vd24gPSBfLCBzY2FsZSkgOiB1bmtub3duO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gb3JkaW5hbCgpXG4gICAgICAgIC5kb21haW4oZG9tYWluKVxuICAgICAgICAucmFuZ2UocmFuZ2UpXG4gICAgICAgIC51bmtub3duKHVua25vd24pO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxudmFyIGRlZmluZSA9IGZ1bmN0aW9uKGNvbnN0cnVjdG9yLCBmYWN0b3J5LCBwcm90b3R5cGUpIHtcbiAgY29uc3RydWN0b3IucHJvdG90eXBlID0gZmFjdG9yeS5wcm90b3R5cGUgPSBwcm90b3R5cGU7XG4gIHByb3RvdHlwZS5jb25zdHJ1Y3RvciA9IGNvbnN0cnVjdG9yO1xufTtcblxuZnVuY3Rpb24gZXh0ZW5kJDEocGFyZW50LCBkZWZpbml0aW9uKSB7XG4gIHZhciBwcm90b3R5cGUgPSBPYmplY3QuY3JlYXRlKHBhcmVudC5wcm90b3R5cGUpO1xuICBmb3IgKHZhciBrZXkgaW4gZGVmaW5pdGlvbikgcHJvdG90eXBlW2tleV0gPSBkZWZpbml0aW9uW2tleV07XG4gIHJldHVybiBwcm90b3R5cGU7XG59XG5cbmZ1bmN0aW9uIENvbG9yKCkge31cblxudmFyIGRhcmtlciA9IDAuNztcbnZhciBicmlnaHRlciA9IDEgLyBkYXJrZXI7XG5cbnZhciByZUkgPSBcIlxcXFxzKihbKy1dP1xcXFxkKylcXFxccypcIjtcbnZhciByZU4gPSBcIlxcXFxzKihbKy1dP1xcXFxkKlxcXFwuP1xcXFxkKyg/OltlRV1bKy1dP1xcXFxkKyk/KVxcXFxzKlwiO1xudmFyIHJlUCA9IFwiXFxcXHMqKFsrLV0/XFxcXGQqXFxcXC4/XFxcXGQrKD86W2VFXVsrLV0/XFxcXGQrKT8pJVxcXFxzKlwiO1xudmFyIHJlSGV4MyA9IC9eIyhbMC05YS1mXXszfSkkLztcbnZhciByZUhleDYgPSAvXiMoWzAtOWEtZl17Nn0pJC87XG52YXIgcmVSZ2JJbnRlZ2VyID0gbmV3IFJlZ0V4cChcIl5yZ2JcXFxcKFwiICsgW3JlSSwgcmVJLCByZUldICsgXCJcXFxcKSRcIik7XG52YXIgcmVSZ2JQZXJjZW50ID0gbmV3IFJlZ0V4cChcIl5yZ2JcXFxcKFwiICsgW3JlUCwgcmVQLCByZVBdICsgXCJcXFxcKSRcIik7XG52YXIgcmVSZ2JhSW50ZWdlciA9IG5ldyBSZWdFeHAoXCJecmdiYVxcXFwoXCIgKyBbcmVJLCByZUksIHJlSSwgcmVOXSArIFwiXFxcXCkkXCIpO1xudmFyIHJlUmdiYVBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXnJnYmFcXFxcKFwiICsgW3JlUCwgcmVQLCByZVAsIHJlTl0gKyBcIlxcXFwpJFwiKTtcbnZhciByZUhzbFBlcmNlbnQgPSBuZXcgUmVnRXhwKFwiXmhzbFxcXFwoXCIgKyBbcmVOLCByZVAsIHJlUF0gKyBcIlxcXFwpJFwiKTtcbnZhciByZUhzbGFQZXJjZW50ID0gbmV3IFJlZ0V4cChcIl5oc2xhXFxcXChcIiArIFtyZU4sIHJlUCwgcmVQLCByZU5dICsgXCJcXFxcKSRcIik7XG5cbnZhciBuYW1lZCA9IHtcbiAgYWxpY2VibHVlOiAweGYwZjhmZixcbiAgYW50aXF1ZXdoaXRlOiAweGZhZWJkNyxcbiAgYXF1YTogMHgwMGZmZmYsXG4gIGFxdWFtYXJpbmU6IDB4N2ZmZmQ0LFxuICBhenVyZTogMHhmMGZmZmYsXG4gIGJlaWdlOiAweGY1ZjVkYyxcbiAgYmlzcXVlOiAweGZmZTRjNCxcbiAgYmxhY2s6IDB4MDAwMDAwLFxuICBibGFuY2hlZGFsbW9uZDogMHhmZmViY2QsXG4gIGJsdWU6IDB4MDAwMGZmLFxuICBibHVldmlvbGV0OiAweDhhMmJlMixcbiAgYnJvd246IDB4YTUyYTJhLFxuICBidXJseXdvb2Q6IDB4ZGViODg3LFxuICBjYWRldGJsdWU6IDB4NWY5ZWEwLFxuICBjaGFydHJldXNlOiAweDdmZmYwMCxcbiAgY2hvY29sYXRlOiAweGQyNjkxZSxcbiAgY29yYWw6IDB4ZmY3ZjUwLFxuICBjb3JuZmxvd2VyYmx1ZTogMHg2NDk1ZWQsXG4gIGNvcm5zaWxrOiAweGZmZjhkYyxcbiAgY3JpbXNvbjogMHhkYzE0M2MsXG4gIGN5YW46IDB4MDBmZmZmLFxuICBkYXJrYmx1ZTogMHgwMDAwOGIsXG4gIGRhcmtjeWFuOiAweDAwOGI4YixcbiAgZGFya2dvbGRlbnJvZDogMHhiODg2MGIsXG4gIGRhcmtncmF5OiAweGE5YTlhOSxcbiAgZGFya2dyZWVuOiAweDAwNjQwMCxcbiAgZGFya2dyZXk6IDB4YTlhOWE5LFxuICBkYXJra2hha2k6IDB4YmRiNzZiLFxuICBkYXJrbWFnZW50YTogMHg4YjAwOGIsXG4gIGRhcmtvbGl2ZWdyZWVuOiAweDU1NmIyZixcbiAgZGFya29yYW5nZTogMHhmZjhjMDAsXG4gIGRhcmtvcmNoaWQ6IDB4OTkzMmNjLFxuICBkYXJrcmVkOiAweDhiMDAwMCxcbiAgZGFya3NhbG1vbjogMHhlOTk2N2EsXG4gIGRhcmtzZWFncmVlbjogMHg4ZmJjOGYsXG4gIGRhcmtzbGF0ZWJsdWU6IDB4NDgzZDhiLFxuICBkYXJrc2xhdGVncmF5OiAweDJmNGY0ZixcbiAgZGFya3NsYXRlZ3JleTogMHgyZjRmNGYsXG4gIGRhcmt0dXJxdW9pc2U6IDB4MDBjZWQxLFxuICBkYXJrdmlvbGV0OiAweDk0MDBkMyxcbiAgZGVlcHBpbms6IDB4ZmYxNDkzLFxuICBkZWVwc2t5Ymx1ZTogMHgwMGJmZmYsXG4gIGRpbWdyYXk6IDB4Njk2OTY5LFxuICBkaW1ncmV5OiAweDY5Njk2OSxcbiAgZG9kZ2VyYmx1ZTogMHgxZTkwZmYsXG4gIGZpcmVicmljazogMHhiMjIyMjIsXG4gIGZsb3JhbHdoaXRlOiAweGZmZmFmMCxcbiAgZm9yZXN0Z3JlZW46IDB4MjI4YjIyLFxuICBmdWNoc2lhOiAweGZmMDBmZixcbiAgZ2FpbnNib3JvOiAweGRjZGNkYyxcbiAgZ2hvc3R3aGl0ZTogMHhmOGY4ZmYsXG4gIGdvbGQ6IDB4ZmZkNzAwLFxuICBnb2xkZW5yb2Q6IDB4ZGFhNTIwLFxuICBncmF5OiAweDgwODA4MCxcbiAgZ3JlZW46IDB4MDA4MDAwLFxuICBncmVlbnllbGxvdzogMHhhZGZmMmYsXG4gIGdyZXk6IDB4ODA4MDgwLFxuICBob25leWRldzogMHhmMGZmZjAsXG4gIGhvdHBpbms6IDB4ZmY2OWI0LFxuICBpbmRpYW5yZWQ6IDB4Y2Q1YzVjLFxuICBpbmRpZ286IDB4NGIwMDgyLFxuICBpdm9yeTogMHhmZmZmZjAsXG4gIGtoYWtpOiAweGYwZTY4YyxcbiAgbGF2ZW5kZXI6IDB4ZTZlNmZhLFxuICBsYXZlbmRlcmJsdXNoOiAweGZmZjBmNSxcbiAgbGF3bmdyZWVuOiAweDdjZmMwMCxcbiAgbGVtb25jaGlmZm9uOiAweGZmZmFjZCxcbiAgbGlnaHRibHVlOiAweGFkZDhlNixcbiAgbGlnaHRjb3JhbDogMHhmMDgwODAsXG4gIGxpZ2h0Y3lhbjogMHhlMGZmZmYsXG4gIGxpZ2h0Z29sZGVucm9keWVsbG93OiAweGZhZmFkMixcbiAgbGlnaHRncmF5OiAweGQzZDNkMyxcbiAgbGlnaHRncmVlbjogMHg5MGVlOTAsXG4gIGxpZ2h0Z3JleTogMHhkM2QzZDMsXG4gIGxpZ2h0cGluazogMHhmZmI2YzEsXG4gIGxpZ2h0c2FsbW9uOiAweGZmYTA3YSxcbiAgbGlnaHRzZWFncmVlbjogMHgyMGIyYWEsXG4gIGxpZ2h0c2t5Ymx1ZTogMHg4N2NlZmEsXG4gIGxpZ2h0c2xhdGVncmF5OiAweDc3ODg5OSxcbiAgbGlnaHRzbGF0ZWdyZXk6IDB4Nzc4ODk5LFxuICBsaWdodHN0ZWVsYmx1ZTogMHhiMGM0ZGUsXG4gIGxpZ2h0eWVsbG93OiAweGZmZmZlMCxcbiAgbGltZTogMHgwMGZmMDAsXG4gIGxpbWVncmVlbjogMHgzMmNkMzIsXG4gIGxpbmVuOiAweGZhZjBlNixcbiAgbWFnZW50YTogMHhmZjAwZmYsXG4gIG1hcm9vbjogMHg4MDAwMDAsXG4gIG1lZGl1bWFxdWFtYXJpbmU6IDB4NjZjZGFhLFxuICBtZWRpdW1ibHVlOiAweDAwMDBjZCxcbiAgbWVkaXVtb3JjaGlkOiAweGJhNTVkMyxcbiAgbWVkaXVtcHVycGxlOiAweDkzNzBkYixcbiAgbWVkaXVtc2VhZ3JlZW46IDB4M2NiMzcxLFxuICBtZWRpdW1zbGF0ZWJsdWU6IDB4N2I2OGVlLFxuICBtZWRpdW1zcHJpbmdncmVlbjogMHgwMGZhOWEsXG4gIG1lZGl1bXR1cnF1b2lzZTogMHg0OGQxY2MsXG4gIG1lZGl1bXZpb2xldHJlZDogMHhjNzE1ODUsXG4gIG1pZG5pZ2h0Ymx1ZTogMHgxOTE5NzAsXG4gIG1pbnRjcmVhbTogMHhmNWZmZmEsXG4gIG1pc3R5cm9zZTogMHhmZmU0ZTEsXG4gIG1vY2Nhc2luOiAweGZmZTRiNSxcbiAgbmF2YWpvd2hpdGU6IDB4ZmZkZWFkLFxuICBuYXZ5OiAweDAwMDA4MCxcbiAgb2xkbGFjZTogMHhmZGY1ZTYsXG4gIG9saXZlOiAweDgwODAwMCxcbiAgb2xpdmVkcmFiOiAweDZiOGUyMyxcbiAgb3JhbmdlOiAweGZmYTUwMCxcbiAgb3JhbmdlcmVkOiAweGZmNDUwMCxcbiAgb3JjaGlkOiAweGRhNzBkNixcbiAgcGFsZWdvbGRlbnJvZDogMHhlZWU4YWEsXG4gIHBhbGVncmVlbjogMHg5OGZiOTgsXG4gIHBhbGV0dXJxdW9pc2U6IDB4YWZlZWVlLFxuICBwYWxldmlvbGV0cmVkOiAweGRiNzA5MyxcbiAgcGFwYXlhd2hpcDogMHhmZmVmZDUsXG4gIHBlYWNocHVmZjogMHhmZmRhYjksXG4gIHBlcnU6IDB4Y2Q4NTNmLFxuICBwaW5rOiAweGZmYzBjYixcbiAgcGx1bTogMHhkZGEwZGQsXG4gIHBvd2RlcmJsdWU6IDB4YjBlMGU2LFxuICBwdXJwbGU6IDB4ODAwMDgwLFxuICByZWJlY2NhcHVycGxlOiAweDY2MzM5OSxcbiAgcmVkOiAweGZmMDAwMCxcbiAgcm9zeWJyb3duOiAweGJjOGY4ZixcbiAgcm95YWxibHVlOiAweDQxNjllMSxcbiAgc2FkZGxlYnJvd246IDB4OGI0NTEzLFxuICBzYWxtb246IDB4ZmE4MDcyLFxuICBzYW5keWJyb3duOiAweGY0YTQ2MCxcbiAgc2VhZ3JlZW46IDB4MmU4YjU3LFxuICBzZWFzaGVsbDogMHhmZmY1ZWUsXG4gIHNpZW5uYTogMHhhMDUyMmQsXG4gIHNpbHZlcjogMHhjMGMwYzAsXG4gIHNreWJsdWU6IDB4ODdjZWViLFxuICBzbGF0ZWJsdWU6IDB4NmE1YWNkLFxuICBzbGF0ZWdyYXk6IDB4NzA4MDkwLFxuICBzbGF0ZWdyZXk6IDB4NzA4MDkwLFxuICBzbm93OiAweGZmZmFmYSxcbiAgc3ByaW5nZ3JlZW46IDB4MDBmZjdmLFxuICBzdGVlbGJsdWU6IDB4NDY4MmI0LFxuICB0YW46IDB4ZDJiNDhjLFxuICB0ZWFsOiAweDAwODA4MCxcbiAgdGhpc3RsZTogMHhkOGJmZDgsXG4gIHRvbWF0bzogMHhmZjYzNDcsXG4gIHR1cnF1b2lzZTogMHg0MGUwZDAsXG4gIHZpb2xldDogMHhlZTgyZWUsXG4gIHdoZWF0OiAweGY1ZGViMyxcbiAgd2hpdGU6IDB4ZmZmZmZmLFxuICB3aGl0ZXNtb2tlOiAweGY1ZjVmNSxcbiAgeWVsbG93OiAweGZmZmYwMCxcbiAgeWVsbG93Z3JlZW46IDB4OWFjZDMyXG59O1xuXG5kZWZpbmUoQ29sb3IsIGNvbG9yJDEsIHtcbiAgZGlzcGxheWFibGU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnJnYigpLmRpc3BsYXlhYmxlKCk7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5yZ2IoKSArIFwiXCI7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiBjb2xvciQxKGZvcm1hdCkge1xuICB2YXIgbTtcbiAgZm9ybWF0ID0gKGZvcm1hdCArIFwiXCIpLnRyaW0oKS50b0xvd2VyQ2FzZSgpO1xuICByZXR1cm4gKG0gPSByZUhleDMuZXhlYyhmb3JtYXQpKSA/IChtID0gcGFyc2VJbnQobVsxXSwgMTYpLCBuZXcgUmdiKChtID4+IDggJiAweGYpIHwgKG0gPj4gNCAmIDB4MGYwKSwgKG0gPj4gNCAmIDB4ZikgfCAobSAmIDB4ZjApLCAoKG0gJiAweGYpIDw8IDQpIHwgKG0gJiAweGYpLCAxKSkgLy8gI2YwMFxuICAgICAgOiAobSA9IHJlSGV4Ni5leGVjKGZvcm1hdCkpID8gcmdibihwYXJzZUludChtWzFdLCAxNikpIC8vICNmZjAwMDBcbiAgICAgIDogKG0gPSByZVJnYkludGVnZXIuZXhlYyhmb3JtYXQpKSA/IG5ldyBSZ2IobVsxXSwgbVsyXSwgbVszXSwgMSkgLy8gcmdiKDI1NSwgMCwgMClcbiAgICAgIDogKG0gPSByZVJnYlBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IG5ldyBSZ2IobVsxXSAqIDI1NSAvIDEwMCwgbVsyXSAqIDI1NSAvIDEwMCwgbVszXSAqIDI1NSAvIDEwMCwgMSkgLy8gcmdiKDEwMCUsIDAlLCAwJSlcbiAgICAgIDogKG0gPSByZVJnYmFJbnRlZ2VyLmV4ZWMoZm9ybWF0KSkgPyByZ2JhKG1bMV0sIG1bMl0sIG1bM10sIG1bNF0pIC8vIHJnYmEoMjU1LCAwLCAwLCAxKVxuICAgICAgOiAobSA9IHJlUmdiYVBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IHJnYmEobVsxXSAqIDI1NSAvIDEwMCwgbVsyXSAqIDI1NSAvIDEwMCwgbVszXSAqIDI1NSAvIDEwMCwgbVs0XSkgLy8gcmdiKDEwMCUsIDAlLCAwJSwgMSlcbiAgICAgIDogKG0gPSByZUhzbFBlcmNlbnQuZXhlYyhmb3JtYXQpKSA/IGhzbGEobVsxXSwgbVsyXSAvIDEwMCwgbVszXSAvIDEwMCwgMSkgLy8gaHNsKDEyMCwgNTAlLCA1MCUpXG4gICAgICA6IChtID0gcmVIc2xhUGVyY2VudC5leGVjKGZvcm1hdCkpID8gaHNsYShtWzFdLCBtWzJdIC8gMTAwLCBtWzNdIC8gMTAwLCBtWzRdKSAvLyBoc2xhKDEyMCwgNTAlLCA1MCUsIDEpXG4gICAgICA6IG5hbWVkLmhhc093blByb3BlcnR5KGZvcm1hdCkgPyByZ2JuKG5hbWVkW2Zvcm1hdF0pXG4gICAgICA6IGZvcm1hdCA9PT0gXCJ0cmFuc3BhcmVudFwiID8gbmV3IFJnYihOYU4sIE5hTiwgTmFOLCAwKVxuICAgICAgOiBudWxsO1xufVxuXG5mdW5jdGlvbiByZ2JuKG4pIHtcbiAgcmV0dXJuIG5ldyBSZ2IobiA+PiAxNiAmIDB4ZmYsIG4gPj4gOCAmIDB4ZmYsIG4gJiAweGZmLCAxKTtcbn1cblxuZnVuY3Rpb24gcmdiYShyLCBnLCBiLCBhKSB7XG4gIGlmIChhIDw9IDApIHIgPSBnID0gYiA9IE5hTjtcbiAgcmV0dXJuIG5ldyBSZ2IociwgZywgYiwgYSk7XG59XG5cbmZ1bmN0aW9uIHJnYkNvbnZlcnQobykge1xuICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0gY29sb3IkMShvKTtcbiAgaWYgKCFvKSByZXR1cm4gbmV3IFJnYjtcbiAgbyA9IG8ucmdiKCk7XG4gIHJldHVybiBuZXcgUmdiKG8uciwgby5nLCBvLmIsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIHJnYihyLCBnLCBiLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gcmdiQ29udmVydChyKSA6IG5ldyBSZ2IociwgZywgYiwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBSZ2IociwgZywgYiwgb3BhY2l0eSkge1xuICB0aGlzLnIgPSArcjtcbiAgdGhpcy5nID0gK2c7XG4gIHRoaXMuYiA9ICtiO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKFJnYiwgcmdiLCBleHRlbmQkMShDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBicmlnaHRlciA6IE1hdGgucG93KGJyaWdodGVyLCBrKTtcbiAgICByZXR1cm4gbmV3IFJnYih0aGlzLnIgKiBrLCB0aGlzLmcgKiBrLCB0aGlzLmIgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gZGFya2VyIDogTWF0aC5wb3coZGFya2VyLCBrKTtcbiAgICByZXR1cm4gbmV3IFJnYih0aGlzLnIgKiBrLCB0aGlzLmcgKiBrLCB0aGlzLmIgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBkaXNwbGF5YWJsZTogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuICgwIDw9IHRoaXMuciAmJiB0aGlzLnIgPD0gMjU1KVxuICAgICAgICAmJiAoMCA8PSB0aGlzLmcgJiYgdGhpcy5nIDw9IDI1NSlcbiAgICAgICAgJiYgKDAgPD0gdGhpcy5iICYmIHRoaXMuYiA8PSAyNTUpXG4gICAgICAgICYmICgwIDw9IHRoaXMub3BhY2l0eSAmJiB0aGlzLm9wYWNpdHkgPD0gMSk7XG4gIH0sXG4gIHRvU3RyaW5nOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgYSA9IHRoaXMub3BhY2l0eTsgYSA9IGlzTmFOKGEpID8gMSA6IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIGEpKTtcbiAgICByZXR1cm4gKGEgPT09IDEgPyBcInJnYihcIiA6IFwicmdiYShcIilcbiAgICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5yKSB8fCAwKSkgKyBcIiwgXCJcbiAgICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5nKSB8fCAwKSkgKyBcIiwgXCJcbiAgICAgICAgKyBNYXRoLm1heCgwLCBNYXRoLm1pbigyNTUsIE1hdGgucm91bmQodGhpcy5iKSB8fCAwKSlcbiAgICAgICAgKyAoYSA9PT0gMSA/IFwiKVwiIDogXCIsIFwiICsgYSArIFwiKVwiKTtcbiAgfVxufSkpO1xuXG5mdW5jdGlvbiBoc2xhKGgsIHMsIGwsIGEpIHtcbiAgaWYgKGEgPD0gMCkgaCA9IHMgPSBsID0gTmFOO1xuICBlbHNlIGlmIChsIDw9IDAgfHwgbCA+PSAxKSBoID0gcyA9IE5hTjtcbiAgZWxzZSBpZiAocyA8PSAwKSBoID0gTmFOO1xuICByZXR1cm4gbmV3IEhzbChoLCBzLCBsLCBhKTtcbn1cblxuZnVuY3Rpb24gaHNsQ29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgSHNsKSByZXR1cm4gbmV3IEhzbChvLmgsIG8ucywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgQ29sb3IpKSBvID0gY29sb3IkMShvKTtcbiAgaWYgKCFvKSByZXR1cm4gbmV3IEhzbDtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIc2wpIHJldHVybiBvO1xuICBvID0gby5yZ2IoKTtcbiAgdmFyIHIgPSBvLnIgLyAyNTUsXG4gICAgICBnID0gby5nIC8gMjU1LFxuICAgICAgYiA9IG8uYiAvIDI1NSxcbiAgICAgIG1pbiA9IE1hdGgubWluKHIsIGcsIGIpLFxuICAgICAgbWF4ID0gTWF0aC5tYXgociwgZywgYiksXG4gICAgICBoID0gTmFOLFxuICAgICAgcyA9IG1heCAtIG1pbixcbiAgICAgIGwgPSAobWF4ICsgbWluKSAvIDI7XG4gIGlmIChzKSB7XG4gICAgaWYgKHIgPT09IG1heCkgaCA9IChnIC0gYikgLyBzICsgKGcgPCBiKSAqIDY7XG4gICAgZWxzZSBpZiAoZyA9PT0gbWF4KSBoID0gKGIgLSByKSAvIHMgKyAyO1xuICAgIGVsc2UgaCA9IChyIC0gZykgLyBzICsgNDtcbiAgICBzIC89IGwgPCAwLjUgPyBtYXggKyBtaW4gOiAyIC0gbWF4IC0gbWluO1xuICAgIGggKj0gNjA7XG4gIH0gZWxzZSB7XG4gICAgcyA9IGwgPiAwICYmIGwgPCAxID8gMCA6IGg7XG4gIH1cbiAgcmV0dXJuIG5ldyBIc2woaCwgcywgbCwgby5vcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gaHNsKGgsIHMsIGwsIG9wYWNpdHkpIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPT09IDEgPyBoc2xDb252ZXJ0KGgpIDogbmV3IEhzbChoLCBzLCBsLCBvcGFjaXR5ID09IG51bGwgPyAxIDogb3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIEhzbChoLCBzLCBsLCBvcGFjaXR5KSB7XG4gIHRoaXMuaCA9ICtoO1xuICB0aGlzLnMgPSArcztcbiAgdGhpcy5sID0gK2w7XG4gIHRoaXMub3BhY2l0eSA9ICtvcGFjaXR5O1xufVxuXG5kZWZpbmUoSHNsLCBoc2wsIGV4dGVuZCQxKENvbG9yLCB7XG4gIGJyaWdodGVyOiBmdW5jdGlvbihrKSB7XG4gICAgayA9IGsgPT0gbnVsbCA/IGJyaWdodGVyIDogTWF0aC5wb3coYnJpZ2h0ZXIsIGspO1xuICAgIHJldHVybiBuZXcgSHNsKHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICBkYXJrZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gZGFya2VyIDogTWF0aC5wb3coZGFya2VyLCBrKTtcbiAgICByZXR1cm4gbmV3IEhzbCh0aGlzLmgsIHRoaXMucywgdGhpcy5sICogaywgdGhpcy5vcGFjaXR5KTtcbiAgfSxcbiAgcmdiOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgaCA9IHRoaXMuaCAlIDM2MCArICh0aGlzLmggPCAwKSAqIDM2MCxcbiAgICAgICAgcyA9IGlzTmFOKGgpIHx8IGlzTmFOKHRoaXMucykgPyAwIDogdGhpcy5zLFxuICAgICAgICBsID0gdGhpcy5sLFxuICAgICAgICBtMiA9IGwgKyAobCA8IDAuNSA/IGwgOiAxIC0gbCkgKiBzLFxuICAgICAgICBtMSA9IDIgKiBsIC0gbTI7XG4gICAgcmV0dXJuIG5ldyBSZ2IoXG4gICAgICBoc2wycmdiKGggPj0gMjQwID8gaCAtIDI0MCA6IGggKyAxMjAsIG0xLCBtMiksXG4gICAgICBoc2wycmdiKGgsIG0xLCBtMiksXG4gICAgICBoc2wycmdiKGggPCAxMjAgPyBoICsgMjQwIDogaCAtIDEyMCwgbTEsIG0yKSxcbiAgICAgIHRoaXMub3BhY2l0eVxuICAgICk7XG4gIH0sXG4gIGRpc3BsYXlhYmxlOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gKDAgPD0gdGhpcy5zICYmIHRoaXMucyA8PSAxIHx8IGlzTmFOKHRoaXMucykpXG4gICAgICAgICYmICgwIDw9IHRoaXMubCAmJiB0aGlzLmwgPD0gMSlcbiAgICAgICAgJiYgKDAgPD0gdGhpcy5vcGFjaXR5ICYmIHRoaXMub3BhY2l0eSA8PSAxKTtcbiAgfVxufSkpO1xuXG4vKiBGcm9tIEZ2RCAxMy4zNywgQ1NTIENvbG9yIE1vZHVsZSBMZXZlbCAzICovXG5mdW5jdGlvbiBoc2wycmdiKGgsIG0xLCBtMikge1xuICByZXR1cm4gKGggPCA2MCA/IG0xICsgKG0yIC0gbTEpICogaCAvIDYwXG4gICAgICA6IGggPCAxODAgPyBtMlxuICAgICAgOiBoIDwgMjQwID8gbTEgKyAobTIgLSBtMSkgKiAoMjQwIC0gaCkgLyA2MFxuICAgICAgOiBtMSkgKiAyNTU7XG59XG5cbnZhciBkZWcycmFkID0gTWF0aC5QSSAvIDE4MDtcbnZhciByYWQyZGVnID0gMTgwIC8gTWF0aC5QSTtcblxudmFyIEtuID0gMTg7XG52YXIgWG4gPSAwLjk1MDQ3MDtcbnZhciBZbiA9IDE7XG52YXIgWm4gPSAxLjA4ODgzMDtcbnZhciB0MCQxID0gNCAvIDI5O1xudmFyIHQxJDEgPSA2IC8gMjk7XG52YXIgdDIgPSAzICogdDEkMSAqIHQxJDE7XG52YXIgdDMgPSB0MSQxICogdDEkMSAqIHQxJDE7XG5cbmZ1bmN0aW9uIGxhYkNvbnZlcnQobykge1xuICBpZiAobyBpbnN0YW5jZW9mIExhYikgcmV0dXJuIG5ldyBMYWIoby5sLCBvLmEsIG8uYiwgby5vcGFjaXR5KTtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIY2wpIHtcbiAgICB2YXIgaCA9IG8uaCAqIGRlZzJyYWQ7XG4gICAgcmV0dXJuIG5ldyBMYWIoby5sLCBNYXRoLmNvcyhoKSAqIG8uYywgTWF0aC5zaW4oaCkgKiBvLmMsIG8ub3BhY2l0eSk7XG4gIH1cbiAgaWYgKCEobyBpbnN0YW5jZW9mIFJnYikpIG8gPSByZ2JDb252ZXJ0KG8pO1xuICB2YXIgYiA9IHJnYjJ4eXooby5yKSxcbiAgICAgIGEgPSByZ2IyeHl6KG8uZyksXG4gICAgICBsID0gcmdiMnh5eihvLmIpLFxuICAgICAgeCA9IHh5ejJsYWIoKDAuNDEyNDU2NCAqIGIgKyAwLjM1NzU3NjEgKiBhICsgMC4xODA0Mzc1ICogbCkgLyBYbiksXG4gICAgICB5ID0geHl6MmxhYigoMC4yMTI2NzI5ICogYiArIDAuNzE1MTUyMiAqIGEgKyAwLjA3MjE3NTAgKiBsKSAvIFluKSxcbiAgICAgIHogPSB4eXoybGFiKCgwLjAxOTMzMzkgKiBiICsgMC4xMTkxOTIwICogYSArIDAuOTUwMzA0MSAqIGwpIC8gWm4pO1xuICByZXR1cm4gbmV3IExhYigxMTYgKiB5IC0gMTYsIDUwMCAqICh4IC0geSksIDIwMCAqICh5IC0geiksIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGxhYihsLCBhLCBiLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gbGFiQ29udmVydChsKSA6IG5ldyBMYWIobCwgYSwgYiwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBMYWIobCwgYSwgYiwgb3BhY2l0eSkge1xuICB0aGlzLmwgPSArbDtcbiAgdGhpcy5hID0gK2E7XG4gIHRoaXMuYiA9ICtiO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKExhYiwgbGFiLCBleHRlbmQkMShDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgTGFiKHRoaXMubCArIEtuICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5hLCB0aGlzLmIsIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgTGFiKHRoaXMubCAtIEtuICogKGsgPT0gbnVsbCA/IDEgOiBrKSwgdGhpcy5hLCB0aGlzLmIsIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHkgPSAodGhpcy5sICsgMTYpIC8gMTE2LFxuICAgICAgICB4ID0gaXNOYU4odGhpcy5hKSA/IHkgOiB5ICsgdGhpcy5hIC8gNTAwLFxuICAgICAgICB6ID0gaXNOYU4odGhpcy5iKSA/IHkgOiB5IC0gdGhpcy5iIC8gMjAwO1xuICAgIHkgPSBZbiAqIGxhYjJ4eXooeSk7XG4gICAgeCA9IFhuICogbGFiMnh5eih4KTtcbiAgICB6ID0gWm4gKiBsYWIyeHl6KHopO1xuICAgIHJldHVybiBuZXcgUmdiKFxuICAgICAgeHl6MnJnYiggMy4yNDA0NTQyICogeCAtIDEuNTM3MTM4NSAqIHkgLSAwLjQ5ODUzMTQgKiB6KSwgLy8gRDY1IC0+IHNSR0JcbiAgICAgIHh5ejJyZ2IoLTAuOTY5MjY2MCAqIHggKyAxLjg3NjAxMDggKiB5ICsgMC4wNDE1NTYwICogeiksXG4gICAgICB4eXoycmdiKCAwLjA1NTY0MzQgKiB4IC0gMC4yMDQwMjU5ICogeSArIDEuMDU3MjI1MiAqIHopLFxuICAgICAgdGhpcy5vcGFjaXR5XG4gICAgKTtcbiAgfVxufSkpO1xuXG5mdW5jdGlvbiB4eXoybGFiKHQpIHtcbiAgcmV0dXJuIHQgPiB0MyA/IE1hdGgucG93KHQsIDEgLyAzKSA6IHQgLyB0MiArIHQwJDE7XG59XG5cbmZ1bmN0aW9uIGxhYjJ4eXoodCkge1xuICByZXR1cm4gdCA+IHQxJDEgPyB0ICogdCAqIHQgOiB0MiAqICh0IC0gdDAkMSk7XG59XG5cbmZ1bmN0aW9uIHh5ejJyZ2IoeCkge1xuICByZXR1cm4gMjU1ICogKHggPD0gMC4wMDMxMzA4ID8gMTIuOTIgKiB4IDogMS4wNTUgKiBNYXRoLnBvdyh4LCAxIC8gMi40KSAtIDAuMDU1KTtcbn1cblxuZnVuY3Rpb24gcmdiMnh5eih4KSB7XG4gIHJldHVybiAoeCAvPSAyNTUpIDw9IDAuMDQwNDUgPyB4IC8gMTIuOTIgOiBNYXRoLnBvdygoeCArIDAuMDU1KSAvIDEuMDU1LCAyLjQpO1xufVxuXG5mdW5jdGlvbiBoY2xDb252ZXJ0KG8pIHtcbiAgaWYgKG8gaW5zdGFuY2VvZiBIY2wpIHJldHVybiBuZXcgSGNsKG8uaCwgby5jLCBvLmwsIG8ub3BhY2l0eSk7XG4gIGlmICghKG8gaW5zdGFuY2VvZiBMYWIpKSBvID0gbGFiQ29udmVydChvKTtcbiAgdmFyIGggPSBNYXRoLmF0YW4yKG8uYiwgby5hKSAqIHJhZDJkZWc7XG4gIHJldHVybiBuZXcgSGNsKGggPCAwID8gaCArIDM2MCA6IGgsIE1hdGguc3FydChvLmEgKiBvLmEgKyBvLmIgKiBvLmIpLCBvLmwsIG8ub3BhY2l0eSk7XG59XG5cbmZ1bmN0aW9uIGhjbChoLCBjLCBsLCBvcGFjaXR5KSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID09PSAxID8gaGNsQ29udmVydChoKSA6IG5ldyBIY2woaCwgYywgbCwgb3BhY2l0eSA9PSBudWxsID8gMSA6IG9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBIY2woaCwgYywgbCwgb3BhY2l0eSkge1xuICB0aGlzLmggPSAraDtcbiAgdGhpcy5jID0gK2M7XG4gIHRoaXMubCA9ICtsO1xuICB0aGlzLm9wYWNpdHkgPSArb3BhY2l0eTtcbn1cblxuZGVmaW5lKEhjbCwgaGNsLCBleHRlbmQkMShDb2xvciwge1xuICBicmlnaHRlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgSGNsKHRoaXMuaCwgdGhpcy5jLCB0aGlzLmwgKyBLbiAqIChrID09IG51bGwgPyAxIDogayksIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIHJldHVybiBuZXcgSGNsKHRoaXMuaCwgdGhpcy5jLCB0aGlzLmwgLSBLbiAqIChrID09IG51bGwgPyAxIDogayksIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIHJnYjogZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGxhYkNvbnZlcnQodGhpcykucmdiKCk7XG4gIH1cbn0pKTtcblxudmFyIEEgPSAtMC4xNDg2MTtcbnZhciBCID0gKzEuNzgyNzc7XG52YXIgQyA9IC0wLjI5MjI3O1xudmFyIEQgPSAtMC45MDY0OTtcbnZhciBFID0gKzEuOTcyOTQ7XG52YXIgRUQgPSBFICogRDtcbnZhciBFQiA9IEUgKiBCO1xudmFyIEJDX0RBID0gQiAqIEMgLSBEICogQTtcblxuZnVuY3Rpb24gY3ViZWhlbGl4Q29udmVydChvKSB7XG4gIGlmIChvIGluc3RhbmNlb2YgQ3ViZWhlbGl4KSByZXR1cm4gbmV3IEN1YmVoZWxpeChvLmgsIG8ucywgby5sLCBvLm9wYWNpdHkpO1xuICBpZiAoIShvIGluc3RhbmNlb2YgUmdiKSkgbyA9IHJnYkNvbnZlcnQobyk7XG4gIHZhciByID0gby5yIC8gMjU1LFxuICAgICAgZyA9IG8uZyAvIDI1NSxcbiAgICAgIGIgPSBvLmIgLyAyNTUsXG4gICAgICBsID0gKEJDX0RBICogYiArIEVEICogciAtIEVCICogZykgLyAoQkNfREEgKyBFRCAtIEVCKSxcbiAgICAgIGJsID0gYiAtIGwsXG4gICAgICBrID0gKEUgKiAoZyAtIGwpIC0gQyAqIGJsKSAvIEQsXG4gICAgICBzID0gTWF0aC5zcXJ0KGsgKiBrICsgYmwgKiBibCkgLyAoRSAqIGwgKiAoMSAtIGwpKSwgLy8gTmFOIGlmIGw9MCBvciBsPTFcbiAgICAgIGggPSBzID8gTWF0aC5hdGFuMihrLCBibCkgKiByYWQyZGVnIC0gMTIwIDogTmFOO1xuICByZXR1cm4gbmV3IEN1YmVoZWxpeChoIDwgMCA/IGggKyAzNjAgOiBoLCBzLCBsLCBvLm9wYWNpdHkpO1xufVxuXG5mdW5jdGlvbiBjdWJlaGVsaXgoaCwgcywgbCwgb3BhY2l0eSkge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMSA/IGN1YmVoZWxpeENvbnZlcnQoaCkgOiBuZXcgQ3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkgPT0gbnVsbCA/IDEgOiBvcGFjaXR5KTtcbn1cblxuZnVuY3Rpb24gQ3ViZWhlbGl4KGgsIHMsIGwsIG9wYWNpdHkpIHtcbiAgdGhpcy5oID0gK2g7XG4gIHRoaXMucyA9ICtzO1xuICB0aGlzLmwgPSArbDtcbiAgdGhpcy5vcGFjaXR5ID0gK29wYWNpdHk7XG59XG5cbmRlZmluZShDdWJlaGVsaXgsIGN1YmVoZWxpeCwgZXh0ZW5kJDEoQ29sb3IsIHtcbiAgYnJpZ2h0ZXI6IGZ1bmN0aW9uKGspIHtcbiAgICBrID0gayA9PSBudWxsID8gYnJpZ2h0ZXIgOiBNYXRoLnBvdyhicmlnaHRlciwgayk7XG4gICAgcmV0dXJuIG5ldyBDdWJlaGVsaXgodGhpcy5oLCB0aGlzLnMsIHRoaXMubCAqIGssIHRoaXMub3BhY2l0eSk7XG4gIH0sXG4gIGRhcmtlcjogZnVuY3Rpb24oaykge1xuICAgIGsgPSBrID09IG51bGwgPyBkYXJrZXIgOiBNYXRoLnBvdyhkYXJrZXIsIGspO1xuICAgIHJldHVybiBuZXcgQ3ViZWhlbGl4KHRoaXMuaCwgdGhpcy5zLCB0aGlzLmwgKiBrLCB0aGlzLm9wYWNpdHkpO1xuICB9LFxuICByZ2I6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBoID0gaXNOYU4odGhpcy5oKSA/IDAgOiAodGhpcy5oICsgMTIwKSAqIGRlZzJyYWQsXG4gICAgICAgIGwgPSArdGhpcy5sLFxuICAgICAgICBhID0gaXNOYU4odGhpcy5zKSA/IDAgOiB0aGlzLnMgKiBsICogKDEgLSBsKSxcbiAgICAgICAgY29zaCA9IE1hdGguY29zKGgpLFxuICAgICAgICBzaW5oID0gTWF0aC5zaW4oaCk7XG4gICAgcmV0dXJuIG5ldyBSZ2IoXG4gICAgICAyNTUgKiAobCArIGEgKiAoQSAqIGNvc2ggKyBCICogc2luaCkpLFxuICAgICAgMjU1ICogKGwgKyBhICogKEMgKiBjb3NoICsgRCAqIHNpbmgpKSxcbiAgICAgIDI1NSAqIChsICsgYSAqIChFICogY29zaCkpLFxuICAgICAgdGhpcy5vcGFjaXR5XG4gICAgKTtcbiAgfVxufSkpO1xuXG5mdW5jdGlvbiBiYXNpcyh0MSwgdjAsIHYxLCB2MiwgdjMpIHtcbiAgdmFyIHQyID0gdDEgKiB0MSwgdDMgPSB0MiAqIHQxO1xuICByZXR1cm4gKCgxIC0gMyAqIHQxICsgMyAqIHQyIC0gdDMpICogdjBcbiAgICAgICsgKDQgLSA2ICogdDIgKyAzICogdDMpICogdjFcbiAgICAgICsgKDEgKyAzICogdDEgKyAzICogdDIgLSAzICogdDMpICogdjJcbiAgICAgICsgdDMgKiB2MykgLyA2O1xufVxuXG52YXIgYmFzaXMkMSA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICB2YXIgbiA9IHZhbHVlcy5sZW5ndGggLSAxO1xuICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgIHZhciBpID0gdCA8PSAwID8gKHQgPSAwKSA6IHQgPj0gMSA/ICh0ID0gMSwgbiAtIDEpIDogTWF0aC5mbG9vcih0ICogbiksXG4gICAgICAgIHYxID0gdmFsdWVzW2ldLFxuICAgICAgICB2MiA9IHZhbHVlc1tpICsgMV0sXG4gICAgICAgIHYwID0gaSA+IDAgPyB2YWx1ZXNbaSAtIDFdIDogMiAqIHYxIC0gdjIsXG4gICAgICAgIHYzID0gaSA8IG4gLSAxID8gdmFsdWVzW2kgKyAyXSA6IDIgKiB2MiAtIHYxO1xuICAgIHJldHVybiBiYXNpcygodCAtIGkgLyBuKSAqIG4sIHYwLCB2MSwgdjIsIHYzKTtcbiAgfTtcbn07XG5cbnZhciBiYXNpc0Nsb3NlZCA9IGZ1bmN0aW9uKHZhbHVlcykge1xuICB2YXIgbiA9IHZhbHVlcy5sZW5ndGg7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGkgPSBNYXRoLmZsb29yKCgodCAlPSAxKSA8IDAgPyArK3QgOiB0KSAqIG4pLFxuICAgICAgICB2MCA9IHZhbHVlc1soaSArIG4gLSAxKSAlIG5dLFxuICAgICAgICB2MSA9IHZhbHVlc1tpICUgbl0sXG4gICAgICAgIHYyID0gdmFsdWVzWyhpICsgMSkgJSBuXSxcbiAgICAgICAgdjMgPSB2YWx1ZXNbKGkgKyAyKSAlIG5dO1xuICAgIHJldHVybiBiYXNpcygodCAtIGkgLyBuKSAqIG4sIHYwLCB2MSwgdjIsIHYzKTtcbiAgfTtcbn07XG5cbnZhciBjb25zdGFudCQ0ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG5mdW5jdGlvbiBsaW5lYXIkMShhLCBkKSB7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGEgKyB0ICogZDtcbiAgfTtcbn1cblxuZnVuY3Rpb24gZXhwb25lbnRpYWwoYSwgYiwgeSkge1xuICByZXR1cm4gYSA9IE1hdGgucG93KGEsIHkpLCBiID0gTWF0aC5wb3coYiwgeSkgLSBhLCB5ID0gMSAvIHksIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gTWF0aC5wb3coYSArIHQgKiBiLCB5KTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gaHVlKGEsIGIpIHtcbiAgdmFyIGQgPSBiIC0gYTtcbiAgcmV0dXJuIGQgPyBsaW5lYXIkMShhLCBkID4gMTgwIHx8IGQgPCAtMTgwID8gZCAtIDM2MCAqIE1hdGgucm91bmQoZCAvIDM2MCkgOiBkKSA6IGNvbnN0YW50JDQoaXNOYU4oYSkgPyBiIDogYSk7XG59XG5cbmZ1bmN0aW9uIGdhbW1hKHkpIHtcbiAgcmV0dXJuICh5ID0gK3kpID09PSAxID8gbm9nYW1tYSA6IGZ1bmN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gYiAtIGEgPyBleHBvbmVudGlhbChhLCBiLCB5KSA6IGNvbnN0YW50JDQoaXNOYU4oYSkgPyBiIDogYSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIG5vZ2FtbWEoYSwgYikge1xuICB2YXIgZCA9IGIgLSBhO1xuICByZXR1cm4gZCA/IGxpbmVhciQxKGEsIGQpIDogY29uc3RhbnQkNChpc05hTihhKSA/IGIgOiBhKTtcbn1cblxudmFyIHJnYiQxID0gKGZ1bmN0aW9uIHJnYkdhbW1hKHkpIHtcbiAgdmFyIGNvbG9yJCQxID0gZ2FtbWEoeSk7XG5cbiAgZnVuY3Rpb24gcmdiJCQxKHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgciA9IGNvbG9yJCQxKChzdGFydCA9IHJnYihzdGFydCkpLnIsIChlbmQgPSByZ2IoZW5kKSkuciksXG4gICAgICAgIGcgPSBjb2xvciQkMShzdGFydC5nLCBlbmQuZyksXG4gICAgICAgIGIgPSBjb2xvciQkMShzdGFydC5iLCBlbmQuYiksXG4gICAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgICAgc3RhcnQuciA9IHIodCk7XG4gICAgICBzdGFydC5nID0gZyh0KTtcbiAgICAgIHN0YXJ0LmIgPSBiKHQpO1xuICAgICAgc3RhcnQub3BhY2l0eSA9IG9wYWNpdHkodCk7XG4gICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgIH07XG4gIH1cblxuICByZ2IkJDEuZ2FtbWEgPSByZ2JHYW1tYTtcblxuICByZXR1cm4gcmdiJCQxO1xufSkoMSk7XG5cbmZ1bmN0aW9uIHJnYlNwbGluZShzcGxpbmUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbG9ycykge1xuICAgIHZhciBuID0gY29sb3JzLmxlbmd0aCxcbiAgICAgICAgciA9IG5ldyBBcnJheShuKSxcbiAgICAgICAgZyA9IG5ldyBBcnJheShuKSxcbiAgICAgICAgYiA9IG5ldyBBcnJheShuKSxcbiAgICAgICAgaSwgY29sb3IkJDE7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgY29sb3IkJDEgPSByZ2IoY29sb3JzW2ldKTtcbiAgICAgIHJbaV0gPSBjb2xvciQkMS5yIHx8IDA7XG4gICAgICBnW2ldID0gY29sb3IkJDEuZyB8fCAwO1xuICAgICAgYltpXSA9IGNvbG9yJCQxLmIgfHwgMDtcbiAgICB9XG4gICAgciA9IHNwbGluZShyKTtcbiAgICBnID0gc3BsaW5lKGcpO1xuICAgIGIgPSBzcGxpbmUoYik7XG4gICAgY29sb3IkJDEub3BhY2l0eSA9IDE7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIGNvbG9yJCQxLnIgPSByKHQpO1xuICAgICAgY29sb3IkJDEuZyA9IGcodCk7XG4gICAgICBjb2xvciQkMS5iID0gYih0KTtcbiAgICAgIHJldHVybiBjb2xvciQkMSArIFwiXCI7XG4gICAgfTtcbiAgfTtcbn1cblxudmFyIHJnYkJhc2lzID0gcmdiU3BsaW5lKGJhc2lzJDEpO1xudmFyIHJnYkJhc2lzQ2xvc2VkID0gcmdiU3BsaW5lKGJhc2lzQ2xvc2VkKTtcblxudmFyIGFycmF5JDMgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHZhciBuYiA9IGIgPyBiLmxlbmd0aCA6IDAsXG4gICAgICBuYSA9IGEgPyBNYXRoLm1pbihuYiwgYS5sZW5ndGgpIDogMCxcbiAgICAgIHggPSBuZXcgQXJyYXkobmEpLFxuICAgICAgYyA9IG5ldyBBcnJheShuYiksXG4gICAgICBpO1xuXG4gIGZvciAoaSA9IDA7IGkgPCBuYTsgKytpKSB4W2ldID0gaW50ZXJwb2xhdGUoYVtpXSwgYltpXSk7XG4gIGZvciAoOyBpIDwgbmI7ICsraSkgY1tpXSA9IGJbaV07XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbmE7ICsraSkgY1tpXSA9IHhbaV0odCk7XG4gICAgcmV0dXJuIGM7XG4gIH07XG59O1xuXG52YXIgZGF0ZSA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgdmFyIGQgPSBuZXcgRGF0ZTtcbiAgcmV0dXJuIGEgPSArYSwgYiAtPSBhLCBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGQuc2V0VGltZShhICsgYiAqIHQpLCBkO1xuICB9O1xufTtcblxudmFyIHJlaW50ZXJwb2xhdGUgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHJldHVybiBhID0gK2EsIGIgLT0gYSwgZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBhICsgYiAqIHQ7XG4gIH07XG59O1xuXG52YXIgb2JqZWN0JDIgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHZhciBpID0ge30sXG4gICAgICBjID0ge30sXG4gICAgICBrO1xuXG4gIGlmIChhID09PSBudWxsIHx8IHR5cGVvZiBhICE9PSBcIm9iamVjdFwiKSBhID0ge307XG4gIGlmIChiID09PSBudWxsIHx8IHR5cGVvZiBiICE9PSBcIm9iamVjdFwiKSBiID0ge307XG5cbiAgZm9yIChrIGluIGIpIHtcbiAgICBpZiAoayBpbiBhKSB7XG4gICAgICBpW2tdID0gaW50ZXJwb2xhdGUoYVtrXSwgYltrXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNba10gPSBiW2tdO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgZm9yIChrIGluIGkpIGNba10gPSBpW2tdKHQpO1xuICAgIHJldHVybiBjO1xuICB9O1xufTtcblxudmFyIHJlQSA9IC9bLStdPyg/OlxcZCtcXC4/XFxkKnxcXC4/XFxkKykoPzpbZUVdWy0rXT9cXGQrKT8vZztcbnZhciByZUIgPSBuZXcgUmVnRXhwKHJlQS5zb3VyY2UsIFwiZ1wiKTtcblxuZnVuY3Rpb24gemVybyQxKGIpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBiO1xuICB9O1xufVxuXG5mdW5jdGlvbiBvbmUkMShiKSB7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIGIodCkgKyBcIlwiO1xuICB9O1xufVxuXG52YXIgc3RyaW5nID0gZnVuY3Rpb24oYSwgYikge1xuICB2YXIgYmkgPSByZUEubGFzdEluZGV4ID0gcmVCLmxhc3RJbmRleCA9IDAsIC8vIHNjYW4gaW5kZXggZm9yIG5leHQgbnVtYmVyIGluIGJcbiAgICAgIGFtLCAvLyBjdXJyZW50IG1hdGNoIGluIGFcbiAgICAgIGJtLCAvLyBjdXJyZW50IG1hdGNoIGluIGJcbiAgICAgIGJzLCAvLyBzdHJpbmcgcHJlY2VkaW5nIGN1cnJlbnQgbnVtYmVyIGluIGIsIGlmIGFueVxuICAgICAgaSA9IC0xLCAvLyBpbmRleCBpbiBzXG4gICAgICBzID0gW10sIC8vIHN0cmluZyBjb25zdGFudHMgYW5kIHBsYWNlaG9sZGVyc1xuICAgICAgcSA9IFtdOyAvLyBudW1iZXIgaW50ZXJwb2xhdG9yc1xuXG4gIC8vIENvZXJjZSBpbnB1dHMgdG8gc3RyaW5ncy5cbiAgYSA9IGEgKyBcIlwiLCBiID0gYiArIFwiXCI7XG5cbiAgLy8gSW50ZXJwb2xhdGUgcGFpcnMgb2YgbnVtYmVycyBpbiBhICYgYi5cbiAgd2hpbGUgKChhbSA9IHJlQS5leGVjKGEpKVxuICAgICAgJiYgKGJtID0gcmVCLmV4ZWMoYikpKSB7XG4gICAgaWYgKChicyA9IGJtLmluZGV4KSA+IGJpKSB7IC8vIGEgc3RyaW5nIHByZWNlZGVzIHRoZSBuZXh0IG51bWJlciBpbiBiXG4gICAgICBicyA9IGIuc2xpY2UoYmksIGJzKTtcbiAgICAgIGlmIChzW2ldKSBzW2ldICs9IGJzOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgICAgZWxzZSBzWysraV0gPSBicztcbiAgICB9XG4gICAgaWYgKChhbSA9IGFtWzBdKSA9PT0gKGJtID0gYm1bMF0pKSB7IC8vIG51bWJlcnMgaW4gYSAmIGIgbWF0Y2hcbiAgICAgIGlmIChzW2ldKSBzW2ldICs9IGJtOyAvLyBjb2FsZXNjZSB3aXRoIHByZXZpb3VzIHN0cmluZ1xuICAgICAgZWxzZSBzWysraV0gPSBibTtcbiAgICB9IGVsc2UgeyAvLyBpbnRlcnBvbGF0ZSBub24tbWF0Y2hpbmcgbnVtYmVyc1xuICAgICAgc1srK2ldID0gbnVsbDtcbiAgICAgIHEucHVzaCh7aTogaSwgeDogcmVpbnRlcnBvbGF0ZShhbSwgYm0pfSk7XG4gICAgfVxuICAgIGJpID0gcmVCLmxhc3RJbmRleDtcbiAgfVxuXG4gIC8vIEFkZCByZW1haW5zIG9mIGIuXG4gIGlmIChiaSA8IGIubGVuZ3RoKSB7XG4gICAgYnMgPSBiLnNsaWNlKGJpKTtcbiAgICBpZiAoc1tpXSkgc1tpXSArPSBiczsgLy8gY29hbGVzY2Ugd2l0aCBwcmV2aW91cyBzdHJpbmdcbiAgICBlbHNlIHNbKytpXSA9IGJzO1xuICB9XG5cbiAgLy8gU3BlY2lhbCBvcHRpbWl6YXRpb24gZm9yIG9ubHkgYSBzaW5nbGUgbWF0Y2guXG4gIC8vIE90aGVyd2lzZSwgaW50ZXJwb2xhdGUgZWFjaCBvZiB0aGUgbnVtYmVycyBhbmQgcmVqb2luIHRoZSBzdHJpbmcuXG4gIHJldHVybiBzLmxlbmd0aCA8IDIgPyAocVswXVxuICAgICAgPyBvbmUkMShxWzBdLngpXG4gICAgICA6IHplcm8kMShiKSlcbiAgICAgIDogKGIgPSBxLmxlbmd0aCwgZnVuY3Rpb24odCkge1xuICAgICAgICAgIGZvciAodmFyIGkgPSAwLCBvOyBpIDwgYjsgKytpKSBzWyhvID0gcVtpXSkuaV0gPSBvLngodCk7XG4gICAgICAgICAgcmV0dXJuIHMuam9pbihcIlwiKTtcbiAgICAgICAgfSk7XG59O1xuXG52YXIgaW50ZXJwb2xhdGUgPSBmdW5jdGlvbihhLCBiKSB7XG4gIHZhciB0ID0gdHlwZW9mIGIsIGM7XG4gIHJldHVybiBiID09IG51bGwgfHwgdCA9PT0gXCJib29sZWFuXCIgPyBjb25zdGFudCQ0KGIpXG4gICAgICA6ICh0ID09PSBcIm51bWJlclwiID8gcmVpbnRlcnBvbGF0ZVxuICAgICAgOiB0ID09PSBcInN0cmluZ1wiID8gKChjID0gY29sb3IkMShiKSkgPyAoYiA9IGMsIHJnYiQxKSA6IHN0cmluZylcbiAgICAgIDogYiBpbnN0YW5jZW9mIGNvbG9yJDEgPyByZ2IkMVxuICAgICAgOiBiIGluc3RhbmNlb2YgRGF0ZSA/IGRhdGVcbiAgICAgIDogQXJyYXkuaXNBcnJheShiKSA/IGFycmF5JDNcbiAgICAgIDogdHlwZW9mIGIudmFsdWVPZiAhPT0gXCJmdW5jdGlvblwiICYmIHR5cGVvZiBiLnRvU3RyaW5nICE9PSBcImZ1bmN0aW9uXCIgfHwgaXNOYU4oYikgPyBvYmplY3QkMlxuICAgICAgOiByZWludGVycG9sYXRlKShhLCBiKTtcbn07XG5cbnZhciBpbnRlcnBvbGF0ZVJvdW5kID0gZnVuY3Rpb24oYSwgYikge1xuICByZXR1cm4gYSA9ICthLCBiIC09IGEsIGZ1bmN0aW9uKHQpIHtcbiAgICByZXR1cm4gTWF0aC5yb3VuZChhICsgYiAqIHQpO1xuICB9O1xufTtcblxudmFyIGRlZ3JlZXMgPSAxODAgLyBNYXRoLlBJO1xuXG52YXIgaWRlbnRpdHkkNSA9IHtcbiAgdHJhbnNsYXRlWDogMCxcbiAgdHJhbnNsYXRlWTogMCxcbiAgcm90YXRlOiAwLFxuICBza2V3WDogMCxcbiAgc2NhbGVYOiAxLFxuICBzY2FsZVk6IDFcbn07XG5cbnZhciBkZWNvbXBvc2UgPSBmdW5jdGlvbihhLCBiLCBjLCBkLCBlLCBmKSB7XG4gIHZhciBzY2FsZVgsIHNjYWxlWSwgc2tld1g7XG4gIGlmIChzY2FsZVggPSBNYXRoLnNxcnQoYSAqIGEgKyBiICogYikpIGEgLz0gc2NhbGVYLCBiIC89IHNjYWxlWDtcbiAgaWYgKHNrZXdYID0gYSAqIGMgKyBiICogZCkgYyAtPSBhICogc2tld1gsIGQgLT0gYiAqIHNrZXdYO1xuICBpZiAoc2NhbGVZID0gTWF0aC5zcXJ0KGMgKiBjICsgZCAqIGQpKSBjIC89IHNjYWxlWSwgZCAvPSBzY2FsZVksIHNrZXdYIC89IHNjYWxlWTtcbiAgaWYgKGEgKiBkIDwgYiAqIGMpIGEgPSAtYSwgYiA9IC1iLCBza2V3WCA9IC1za2V3WCwgc2NhbGVYID0gLXNjYWxlWDtcbiAgcmV0dXJuIHtcbiAgICB0cmFuc2xhdGVYOiBlLFxuICAgIHRyYW5zbGF0ZVk6IGYsXG4gICAgcm90YXRlOiBNYXRoLmF0YW4yKGIsIGEpICogZGVncmVlcyxcbiAgICBza2V3WDogTWF0aC5hdGFuKHNrZXdYKSAqIGRlZ3JlZXMsXG4gICAgc2NhbGVYOiBzY2FsZVgsXG4gICAgc2NhbGVZOiBzY2FsZVlcbiAgfTtcbn07XG5cbnZhciBjc3NOb2RlO1xudmFyIGNzc1Jvb3Q7XG52YXIgY3NzVmlldztcbnZhciBzdmdOb2RlO1xuXG5mdW5jdGlvbiBwYXJzZUNzcyh2YWx1ZSkge1xuICBpZiAodmFsdWUgPT09IFwibm9uZVwiKSByZXR1cm4gaWRlbnRpdHkkNTtcbiAgaWYgKCFjc3NOb2RlKSBjc3NOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudChcIkRJVlwiKSwgY3NzUm9vdCA9IGRvY3VtZW50LmRvY3VtZW50RWxlbWVudCwgY3NzVmlldyA9IGRvY3VtZW50LmRlZmF1bHRWaWV3O1xuICBjc3NOb2RlLnN0eWxlLnRyYW5zZm9ybSA9IHZhbHVlO1xuICB2YWx1ZSA9IGNzc1ZpZXcuZ2V0Q29tcHV0ZWRTdHlsZShjc3NSb290LmFwcGVuZENoaWxkKGNzc05vZGUpLCBudWxsKS5nZXRQcm9wZXJ0eVZhbHVlKFwidHJhbnNmb3JtXCIpO1xuICBjc3NSb290LnJlbW92ZUNoaWxkKGNzc05vZGUpO1xuICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDcsIC0xKS5zcGxpdChcIixcIik7XG4gIHJldHVybiBkZWNvbXBvc2UoK3ZhbHVlWzBdLCArdmFsdWVbMV0sICt2YWx1ZVsyXSwgK3ZhbHVlWzNdLCArdmFsdWVbNF0sICt2YWx1ZVs1XSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3ZnKHZhbHVlKSB7XG4gIGlmICh2YWx1ZSA9PSBudWxsKSByZXR1cm4gaWRlbnRpdHkkNTtcbiAgaWYgKCFzdmdOb2RlKSBzdmdOb2RlID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgXCJnXCIpO1xuICBzdmdOb2RlLnNldEF0dHJpYnV0ZShcInRyYW5zZm9ybVwiLCB2YWx1ZSk7XG4gIGlmICghKHZhbHVlID0gc3ZnTm9kZS50cmFuc2Zvcm0uYmFzZVZhbC5jb25zb2xpZGF0ZSgpKSkgcmV0dXJuIGlkZW50aXR5JDU7XG4gIHZhbHVlID0gdmFsdWUubWF0cml4O1xuICByZXR1cm4gZGVjb21wb3NlKHZhbHVlLmEsIHZhbHVlLmIsIHZhbHVlLmMsIHZhbHVlLmQsIHZhbHVlLmUsIHZhbHVlLmYpO1xufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZVRyYW5zZm9ybShwYXJzZSwgcHhDb21tYSwgcHhQYXJlbiwgZGVnUGFyZW4pIHtcblxuICBmdW5jdGlvbiBwb3Aocykge1xuICAgIHJldHVybiBzLmxlbmd0aCA/IHMucG9wKCkgKyBcIiBcIiA6IFwiXCI7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2xhdGUoeGEsIHlhLCB4YiwgeWIsIHMsIHEpIHtcbiAgICBpZiAoeGEgIT09IHhiIHx8IHlhICE9PSB5Yikge1xuICAgICAgdmFyIGkgPSBzLnB1c2goXCJ0cmFuc2xhdGUoXCIsIG51bGwsIHB4Q29tbWEsIG51bGwsIHB4UGFyZW4pO1xuICAgICAgcS5wdXNoKHtpOiBpIC0gNCwgeDogcmVpbnRlcnBvbGF0ZSh4YSwgeGIpfSwge2k6IGkgLSAyLCB4OiByZWludGVycG9sYXRlKHlhLCB5Yil9KTtcbiAgICB9IGVsc2UgaWYgKHhiIHx8IHliKSB7XG4gICAgICBzLnB1c2goXCJ0cmFuc2xhdGUoXCIgKyB4YiArIHB4Q29tbWEgKyB5YiArIHB4UGFyZW4pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHJvdGF0ZShhLCBiLCBzLCBxKSB7XG4gICAgaWYgKGEgIT09IGIpIHtcbiAgICAgIGlmIChhIC0gYiA+IDE4MCkgYiArPSAzNjA7IGVsc2UgaWYgKGIgLSBhID4gMTgwKSBhICs9IDM2MDsgLy8gc2hvcnRlc3QgcGF0aFxuICAgICAgcS5wdXNoKHtpOiBzLnB1c2gocG9wKHMpICsgXCJyb3RhdGUoXCIsIG51bGwsIGRlZ1BhcmVuKSAtIDIsIHg6IHJlaW50ZXJwb2xhdGUoYSwgYil9KTtcbiAgICB9IGVsc2UgaWYgKGIpIHtcbiAgICAgIHMucHVzaChwb3AocykgKyBcInJvdGF0ZShcIiArIGIgKyBkZWdQYXJlbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2tld1goYSwgYiwgcywgcSkge1xuICAgIGlmIChhICE9PSBiKSB7XG4gICAgICBxLnB1c2goe2k6IHMucHVzaChwb3AocykgKyBcInNrZXdYKFwiLCBudWxsLCBkZWdQYXJlbikgLSAyLCB4OiByZWludGVycG9sYXRlKGEsIGIpfSk7XG4gICAgfSBlbHNlIGlmIChiKSB7XG4gICAgICBzLnB1c2gocG9wKHMpICsgXCJza2V3WChcIiArIGIgKyBkZWdQYXJlbik7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeGEsIHlhLCB4YiwgeWIsIHMsIHEpIHtcbiAgICBpZiAoeGEgIT09IHhiIHx8IHlhICE9PSB5Yikge1xuICAgICAgdmFyIGkgPSBzLnB1c2gocG9wKHMpICsgXCJzY2FsZShcIiwgbnVsbCwgXCIsXCIsIG51bGwsIFwiKVwiKTtcbiAgICAgIHEucHVzaCh7aTogaSAtIDQsIHg6IHJlaW50ZXJwb2xhdGUoeGEsIHhiKX0sIHtpOiBpIC0gMiwgeDogcmVpbnRlcnBvbGF0ZSh5YSwgeWIpfSk7XG4gICAgfSBlbHNlIGlmICh4YiAhPT0gMSB8fCB5YiAhPT0gMSkge1xuICAgICAgcy5wdXNoKHBvcChzKSArIFwic2NhbGUoXCIgKyB4YiArIFwiLFwiICsgeWIgKyBcIilcIik7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgcyA9IFtdLCAvLyBzdHJpbmcgY29uc3RhbnRzIGFuZCBwbGFjZWhvbGRlcnNcbiAgICAgICAgcSA9IFtdOyAvLyBudW1iZXIgaW50ZXJwb2xhdG9yc1xuICAgIGEgPSBwYXJzZShhKSwgYiA9IHBhcnNlKGIpO1xuICAgIHRyYW5zbGF0ZShhLnRyYW5zbGF0ZVgsIGEudHJhbnNsYXRlWSwgYi50cmFuc2xhdGVYLCBiLnRyYW5zbGF0ZVksIHMsIHEpO1xuICAgIHJvdGF0ZShhLnJvdGF0ZSwgYi5yb3RhdGUsIHMsIHEpO1xuICAgIHNrZXdYKGEuc2tld1gsIGIuc2tld1gsIHMsIHEpO1xuICAgIHNjYWxlKGEuc2NhbGVYLCBhLnNjYWxlWSwgYi5zY2FsZVgsIGIuc2NhbGVZLCBzLCBxKTtcbiAgICBhID0gYiA9IG51bGw7IC8vIGdjXG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBpID0gLTEsIG4gPSBxLmxlbmd0aCwgbztcbiAgICAgIHdoaWxlICgrK2kgPCBuKSBzWyhvID0gcVtpXSkuaV0gPSBvLngodCk7XG4gICAgICByZXR1cm4gcy5qb2luKFwiXCIpO1xuICAgIH07XG4gIH07XG59XG5cbnZhciBpbnRlcnBvbGF0ZVRyYW5zZm9ybUNzcyA9IGludGVycG9sYXRlVHJhbnNmb3JtKHBhcnNlQ3NzLCBcInB4LCBcIiwgXCJweClcIiwgXCJkZWcpXCIpO1xudmFyIGludGVycG9sYXRlVHJhbnNmb3JtU3ZnID0gaW50ZXJwb2xhdGVUcmFuc2Zvcm0ocGFyc2VTdmcsIFwiLCBcIiwgXCIpXCIsIFwiKVwiKTtcblxudmFyIHJobyA9IE1hdGguU1FSVDI7XG52YXIgcmhvMiA9IDI7XG52YXIgcmhvNCA9IDQ7XG52YXIgZXBzaWxvbjIgPSAxZS0xMjtcblxuZnVuY3Rpb24gY29zaCh4KSB7XG4gIHJldHVybiAoKHggPSBNYXRoLmV4cCh4KSkgKyAxIC8geCkgLyAyO1xufVxuXG5mdW5jdGlvbiBzaW5oKHgpIHtcbiAgcmV0dXJuICgoeCA9IE1hdGguZXhwKHgpKSAtIDEgLyB4KSAvIDI7XG59XG5cbmZ1bmN0aW9uIHRhbmgoeCkge1xuICByZXR1cm4gKCh4ID0gTWF0aC5leHAoMiAqIHgpKSAtIDEpIC8gKHggKyAxKTtcbn1cblxuLy8gcDAgPSBbdXgwLCB1eTAsIHcwXVxuLy8gcDEgPSBbdXgxLCB1eTEsIHcxXVxudmFyIHpvb20kMSA9IGZ1bmN0aW9uKHAwLCBwMSkge1xuICB2YXIgdXgwID0gcDBbMF0sIHV5MCA9IHAwWzFdLCB3MCA9IHAwWzJdLFxuICAgICAgdXgxID0gcDFbMF0sIHV5MSA9IHAxWzFdLCB3MSA9IHAxWzJdLFxuICAgICAgZHggPSB1eDEgLSB1eDAsXG4gICAgICBkeSA9IHV5MSAtIHV5MCxcbiAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHksXG4gICAgICBpLFxuICAgICAgUztcblxuICAvLyBTcGVjaWFsIGNhc2UgZm9yIHUwIOKJhSB1MS5cbiAgaWYgKGQyIDwgZXBzaWxvbjIpIHtcbiAgICBTID0gTWF0aC5sb2codzEgLyB3MCkgLyByaG87XG4gICAgaSA9IGZ1bmN0aW9uKHQpIHtcbiAgICAgIHJldHVybiBbXG4gICAgICAgIHV4MCArIHQgKiBkeCxcbiAgICAgICAgdXkwICsgdCAqIGR5LFxuICAgICAgICB3MCAqIE1hdGguZXhwKHJobyAqIHQgKiBTKVxuICAgICAgXTtcbiAgICB9O1xuICB9XG5cbiAgLy8gR2VuZXJhbCBjYXNlLlxuICBlbHNlIHtcbiAgICB2YXIgZDEgPSBNYXRoLnNxcnQoZDIpLFxuICAgICAgICBiMCA9ICh3MSAqIHcxIC0gdzAgKiB3MCArIHJobzQgKiBkMikgLyAoMiAqIHcwICogcmhvMiAqIGQxKSxcbiAgICAgICAgYjEgPSAodzEgKiB3MSAtIHcwICogdzAgLSByaG80ICogZDIpIC8gKDIgKiB3MSAqIHJobzIgKiBkMSksXG4gICAgICAgIHIwID0gTWF0aC5sb2coTWF0aC5zcXJ0KGIwICogYjAgKyAxKSAtIGIwKSxcbiAgICAgICAgcjEgPSBNYXRoLmxvZyhNYXRoLnNxcnQoYjEgKiBiMSArIDEpIC0gYjEpO1xuICAgIFMgPSAocjEgLSByMCkgLyByaG87XG4gICAgaSA9IGZ1bmN0aW9uKHQpIHtcbiAgICAgIHZhciBzID0gdCAqIFMsXG4gICAgICAgICAgY29zaHIwID0gY29zaChyMCksXG4gICAgICAgICAgdSA9IHcwIC8gKHJobzIgKiBkMSkgKiAoY29zaHIwICogdGFuaChyaG8gKiBzICsgcjApIC0gc2luaChyMCkpO1xuICAgICAgcmV0dXJuIFtcbiAgICAgICAgdXgwICsgdSAqIGR4LFxuICAgICAgICB1eTAgKyB1ICogZHksXG4gICAgICAgIHcwICogY29zaHIwIC8gY29zaChyaG8gKiBzICsgcjApXG4gICAgICBdO1xuICAgIH07XG4gIH1cblxuICBpLmR1cmF0aW9uID0gUyAqIDEwMDA7XG5cbiAgcmV0dXJuIGk7XG59O1xuXG5mdW5jdGlvbiBoc2wkMShodWUkJDEpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgaCA9IGh1ZSQkMSgoc3RhcnQgPSBoc2woc3RhcnQpKS5oLCAoZW5kID0gaHNsKGVuZCkpLmgpLFxuICAgICAgICBzID0gbm9nYW1tYShzdGFydC5zLCBlbmQucyksXG4gICAgICAgIGwgPSBub2dhbW1hKHN0YXJ0LmwsIGVuZC5sKSxcbiAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBzdGFydC5oID0gaCh0KTtcbiAgICAgIHN0YXJ0LnMgPSBzKHQpO1xuICAgICAgc3RhcnQubCA9IGwodCk7XG4gICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICAgIHJldHVybiBzdGFydCArIFwiXCI7XG4gICAgfTtcbiAgfVxufVxuXG52YXIgaHNsJDIgPSBoc2wkMShodWUpO1xudmFyIGhzbExvbmcgPSBoc2wkMShub2dhbW1hKTtcblxuZnVuY3Rpb24gbGFiJDEoc3RhcnQsIGVuZCkge1xuICB2YXIgbCA9IG5vZ2FtbWEoKHN0YXJ0ID0gbGFiKHN0YXJ0KSkubCwgKGVuZCA9IGxhYihlbmQpKS5sKSxcbiAgICAgIGEgPSBub2dhbW1hKHN0YXJ0LmEsIGVuZC5hKSxcbiAgICAgIGIgPSBub2dhbW1hKHN0YXJ0LmIsIGVuZC5iKSxcbiAgICAgIG9wYWNpdHkgPSBub2dhbW1hKHN0YXJ0Lm9wYWNpdHksIGVuZC5vcGFjaXR5KTtcbiAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICBzdGFydC5sID0gbCh0KTtcbiAgICBzdGFydC5hID0gYSh0KTtcbiAgICBzdGFydC5iID0gYih0KTtcbiAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICB9O1xufVxuXG5mdW5jdGlvbiBoY2wkMShodWUkJDEpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0YXJ0LCBlbmQpIHtcbiAgICB2YXIgaCA9IGh1ZSQkMSgoc3RhcnQgPSBoY2woc3RhcnQpKS5oLCAoZW5kID0gaGNsKGVuZCkpLmgpLFxuICAgICAgICBjID0gbm9nYW1tYShzdGFydC5jLCBlbmQuYyksXG4gICAgICAgIGwgPSBub2dhbW1hKHN0YXJ0LmwsIGVuZC5sKSxcbiAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpO1xuICAgIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgICBzdGFydC5oID0gaCh0KTtcbiAgICAgIHN0YXJ0LmMgPSBjKHQpO1xuICAgICAgc3RhcnQubCA9IGwodCk7XG4gICAgICBzdGFydC5vcGFjaXR5ID0gb3BhY2l0eSh0KTtcbiAgICAgIHJldHVybiBzdGFydCArIFwiXCI7XG4gICAgfTtcbiAgfVxufVxuXG52YXIgaGNsJDIgPSBoY2wkMShodWUpO1xudmFyIGhjbExvbmcgPSBoY2wkMShub2dhbW1hKTtcblxuZnVuY3Rpb24gY3ViZWhlbGl4JDEoaHVlJCQxKSB7XG4gIHJldHVybiAoZnVuY3Rpb24gY3ViZWhlbGl4R2FtbWEoeSkge1xuICAgIHkgPSAreTtcblxuICAgIGZ1bmN0aW9uIGN1YmVoZWxpeCQkMShzdGFydCwgZW5kKSB7XG4gICAgICB2YXIgaCA9IGh1ZSQkMSgoc3RhcnQgPSBjdWJlaGVsaXgoc3RhcnQpKS5oLCAoZW5kID0gY3ViZWhlbGl4KGVuZCkpLmgpLFxuICAgICAgICAgIHMgPSBub2dhbW1hKHN0YXJ0LnMsIGVuZC5zKSxcbiAgICAgICAgICBsID0gbm9nYW1tYShzdGFydC5sLCBlbmQubCksXG4gICAgICAgICAgb3BhY2l0eSA9IG5vZ2FtbWEoc3RhcnQub3BhY2l0eSwgZW5kLm9wYWNpdHkpO1xuICAgICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgc3RhcnQuaCA9IGgodCk7XG4gICAgICAgIHN0YXJ0LnMgPSBzKHQpO1xuICAgICAgICBzdGFydC5sID0gbChNYXRoLnBvdyh0LCB5KSk7XG4gICAgICAgIHN0YXJ0Lm9wYWNpdHkgPSBvcGFjaXR5KHQpO1xuICAgICAgICByZXR1cm4gc3RhcnQgKyBcIlwiO1xuICAgICAgfTtcbiAgICB9XG5cbiAgICBjdWJlaGVsaXgkJDEuZ2FtbWEgPSBjdWJlaGVsaXhHYW1tYTtcblxuICAgIHJldHVybiBjdWJlaGVsaXgkJDE7XG4gIH0pKDEpO1xufVxuXG52YXIgY3ViZWhlbGl4JDIgPSBjdWJlaGVsaXgkMShodWUpO1xudmFyIGN1YmVoZWxpeExvbmcgPSBjdWJlaGVsaXgkMShub2dhbW1hKTtcblxudmFyIHF1YW50aXplJDEgPSBmdW5jdGlvbihpbnRlcnBvbGF0b3IsIG4pIHtcbiAgdmFyIHNhbXBsZXMgPSBuZXcgQXJyYXkobik7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgbjsgKytpKSBzYW1wbGVzW2ldID0gaW50ZXJwb2xhdG9yKGkgLyAobiAtIDEpKTtcbiAgcmV0dXJuIHNhbXBsZXM7XG59O1xuXG5cblxudmFyICQkMSA9IE9iamVjdC5mcmVlemUoe1xuXHRpbnRlcnBvbGF0ZTogaW50ZXJwb2xhdGUsXG5cdGludGVycG9sYXRlQXJyYXk6IGFycmF5JDMsXG5cdGludGVycG9sYXRlQmFzaXM6IGJhc2lzJDEsXG5cdGludGVycG9sYXRlQmFzaXNDbG9zZWQ6IGJhc2lzQ2xvc2VkLFxuXHRpbnRlcnBvbGF0ZURhdGU6IGRhdGUsXG5cdGludGVycG9sYXRlTnVtYmVyOiByZWludGVycG9sYXRlLFxuXHRpbnRlcnBvbGF0ZU9iamVjdDogb2JqZWN0JDIsXG5cdGludGVycG9sYXRlUm91bmQ6IGludGVycG9sYXRlUm91bmQsXG5cdGludGVycG9sYXRlU3RyaW5nOiBzdHJpbmcsXG5cdGludGVycG9sYXRlVHJhbnNmb3JtQ3NzOiBpbnRlcnBvbGF0ZVRyYW5zZm9ybUNzcyxcblx0aW50ZXJwb2xhdGVUcmFuc2Zvcm1Tdmc6IGludGVycG9sYXRlVHJhbnNmb3JtU3ZnLFxuXHRpbnRlcnBvbGF0ZVpvb206IHpvb20kMSxcblx0aW50ZXJwb2xhdGVSZ2I6IHJnYiQxLFxuXHRpbnRlcnBvbGF0ZVJnYkJhc2lzOiByZ2JCYXNpcyxcblx0aW50ZXJwb2xhdGVSZ2JCYXNpc0Nsb3NlZDogcmdiQmFzaXNDbG9zZWQsXG5cdGludGVycG9sYXRlSHNsOiBoc2wkMixcblx0aW50ZXJwb2xhdGVIc2xMb25nOiBoc2xMb25nLFxuXHRpbnRlcnBvbGF0ZUxhYjogbGFiJDEsXG5cdGludGVycG9sYXRlSGNsOiBoY2wkMixcblx0aW50ZXJwb2xhdGVIY2xMb25nOiBoY2xMb25nLFxuXHRpbnRlcnBvbGF0ZUN1YmVoZWxpeDogY3ViZWhlbGl4JDIsXG5cdGludGVycG9sYXRlQ3ViZWhlbGl4TG9uZzogY3ViZWhlbGl4TG9uZyxcblx0cXVhbnRpemU6IHF1YW50aXplJDFcbn0pO1xuXG52YXIgY29uc3RhbnQkNSA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIG51bWJlciQyID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gK3g7XG59O1xuXG52YXIgdW5pdCA9IFswLCAxXTtcblxuZnVuY3Rpb24gZGVpbnRlcnBvbGF0ZUxpbmVhcihhLCBiKSB7XG4gIHJldHVybiAoYiAtPSAoYSA9ICthKSlcbiAgICAgID8gZnVuY3Rpb24oeCkgeyByZXR1cm4gKHggLSBhKSAvIGI7IH1cbiAgICAgIDogY29uc3RhbnQkNShiKTtcbn1cblxuZnVuY3Rpb24gZGVpbnRlcnBvbGF0ZUNsYW1wKGRlaW50ZXJwb2xhdGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGEsIGIpIHtcbiAgICB2YXIgZCA9IGRlaW50ZXJwb2xhdGUoYSA9ICthLCBiID0gK2IpO1xuICAgIHJldHVybiBmdW5jdGlvbih4KSB7IHJldHVybiB4IDw9IGEgPyAwIDogeCA+PSBiID8gMSA6IGQoeCk7IH07XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJlaW50ZXJwb2xhdGVDbGFtcChyZWludGVycG9sYXRlJCQxKSB7XG4gIHJldHVybiBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIHIgPSByZWludGVycG9sYXRlJCQxKGEgPSArYSwgYiA9ICtiKTtcbiAgICByZXR1cm4gZnVuY3Rpb24odCkgeyByZXR1cm4gdCA8PSAwID8gYSA6IHQgPj0gMSA/IGIgOiByKHQpOyB9O1xuICB9O1xufVxuXG5mdW5jdGlvbiBiaW1hcChkb21haW4sIHJhbmdlLCBkZWludGVycG9sYXRlLCByZWludGVycG9sYXRlJCQxKSB7XG4gIHZhciBkMCA9IGRvbWFpblswXSwgZDEgPSBkb21haW5bMV0sIHIwID0gcmFuZ2VbMF0sIHIxID0gcmFuZ2VbMV07XG4gIGlmIChkMSA8IGQwKSBkMCA9IGRlaW50ZXJwb2xhdGUoZDEsIGQwKSwgcjAgPSByZWludGVycG9sYXRlJCQxKHIxLCByMCk7XG4gIGVsc2UgZDAgPSBkZWludGVycG9sYXRlKGQwLCBkMSksIHIwID0gcmVpbnRlcnBvbGF0ZSQkMShyMCwgcjEpO1xuICByZXR1cm4gZnVuY3Rpb24oeCkgeyByZXR1cm4gcjAoZDAoeCkpOyB9O1xufVxuXG5mdW5jdGlvbiBwb2x5bWFwKGRvbWFpbiwgcmFuZ2UsIGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUkJDEpIHtcbiAgdmFyIGogPSBNYXRoLm1pbihkb21haW4ubGVuZ3RoLCByYW5nZS5sZW5ndGgpIC0gMSxcbiAgICAgIGQgPSBuZXcgQXJyYXkoaiksXG4gICAgICByID0gbmV3IEFycmF5KGopLFxuICAgICAgaSA9IC0xO1xuXG4gIC8vIFJldmVyc2UgZGVzY2VuZGluZyBkb21haW5zLlxuICBpZiAoZG9tYWluW2pdIDwgZG9tYWluWzBdKSB7XG4gICAgZG9tYWluID0gZG9tYWluLnNsaWNlKCkucmV2ZXJzZSgpO1xuICAgIHJhbmdlID0gcmFuZ2Uuc2xpY2UoKS5yZXZlcnNlKCk7XG4gIH1cblxuICB3aGlsZSAoKytpIDwgaikge1xuICAgIGRbaV0gPSBkZWludGVycG9sYXRlKGRvbWFpbltpXSwgZG9tYWluW2kgKyAxXSk7XG4gICAgcltpXSA9IHJlaW50ZXJwb2xhdGUkJDEocmFuZ2VbaV0sIHJhbmdlW2kgKyAxXSk7XG4gIH1cblxuICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgIHZhciBpID0gYmlzZWN0UmlnaHQoZG9tYWluLCB4LCAxLCBqKSAtIDE7XG4gICAgcmV0dXJuIHJbaV0oZFtpXSh4KSk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNvcHkoc291cmNlLCB0YXJnZXQpIHtcbiAgcmV0dXJuIHRhcmdldFxuICAgICAgLmRvbWFpbihzb3VyY2UuZG9tYWluKCkpXG4gICAgICAucmFuZ2Uoc291cmNlLnJhbmdlKCkpXG4gICAgICAuaW50ZXJwb2xhdGUoc291cmNlLmludGVycG9sYXRlKCkpXG4gICAgICAuY2xhbXAoc291cmNlLmNsYW1wKCkpO1xufVxuXG4vLyBkZWludGVycG9sYXRlKGEsIGIpKHgpIHRha2VzIGEgZG9tYWluIHZhbHVlIHggaW4gW2EsYl0gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgcGFyYW1ldGVyIHQgaW4gWzAsMV0uXG4vLyByZWludGVycG9sYXRlKGEsIGIpKHQpIHRha2VzIGEgcGFyYW1ldGVyIHQgaW4gWzAsMV0gYW5kIHJldHVybnMgdGhlIGNvcnJlc3BvbmRpbmcgZG9tYWluIHZhbHVlIHggaW4gW2EsYl0uXG5mdW5jdGlvbiBjb250aW51b3VzKGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUkJDEpIHtcbiAgdmFyIGRvbWFpbiA9IHVuaXQsXG4gICAgICByYW5nZSA9IHVuaXQsXG4gICAgICBpbnRlcnBvbGF0ZSQkMSA9IGludGVycG9sYXRlLFxuICAgICAgY2xhbXAgPSBmYWxzZSxcbiAgICAgIHBpZWNld2lzZSxcbiAgICAgIG91dHB1dCxcbiAgICAgIGlucHV0O1xuXG4gIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgcGllY2V3aXNlID0gTWF0aC5taW4oZG9tYWluLmxlbmd0aCwgcmFuZ2UubGVuZ3RoKSA+IDIgPyBwb2x5bWFwIDogYmltYXA7XG4gICAgb3V0cHV0ID0gaW5wdXQgPSBudWxsO1xuICAgIHJldHVybiBzY2FsZTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICByZXR1cm4gKG91dHB1dCB8fCAob3V0cHV0ID0gcGllY2V3aXNlKGRvbWFpbiwgcmFuZ2UsIGNsYW1wID8gZGVpbnRlcnBvbGF0ZUNsYW1wKGRlaW50ZXJwb2xhdGUpIDogZGVpbnRlcnBvbGF0ZSwgaW50ZXJwb2xhdGUkJDEpKSkoK3gpO1xuICB9XG5cbiAgc2NhbGUuaW52ZXJ0ID0gZnVuY3Rpb24oeSkge1xuICAgIHJldHVybiAoaW5wdXQgfHwgKGlucHV0ID0gcGllY2V3aXNlKHJhbmdlLCBkb21haW4sIGRlaW50ZXJwb2xhdGVMaW5lYXIsIGNsYW1wID8gcmVpbnRlcnBvbGF0ZUNsYW1wKHJlaW50ZXJwb2xhdGUkJDEpIDogcmVpbnRlcnBvbGF0ZSQkMSkpKSgreSk7XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbiA9IG1hcCQzLmNhbGwoXywgbnVtYmVyJDIpLCByZXNjYWxlKCkpIDogZG9tYWluLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFuZ2UgPSBzbGljZSQyLmNhbGwoXyksIHJlc2NhbGUoKSkgOiByYW5nZS5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLnJhbmdlUm91bmQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIHJhbmdlID0gc2xpY2UkMi5jYWxsKF8pLCBpbnRlcnBvbGF0ZSQkMSA9IGludGVycG9sYXRlUm91bmQsIHJlc2NhbGUoKTtcbiAgfTtcblxuICBzY2FsZS5jbGFtcCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChjbGFtcCA9ICEhXywgcmVzY2FsZSgpKSA6IGNsYW1wO1xuICB9O1xuXG4gIHNjYWxlLmludGVycG9sYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGludGVycG9sYXRlJCQxID0gXywgcmVzY2FsZSgpKSA6IGludGVycG9sYXRlJCQxO1xuICB9O1xuXG4gIHJldHVybiByZXNjYWxlKCk7XG59XG5cbi8vIENvbXB1dGVzIHRoZSBkZWNpbWFsIGNvZWZmaWNpZW50IGFuZCBleHBvbmVudCBvZiB0aGUgc3BlY2lmaWVkIG51bWJlciB4IHdpdGhcbi8vIHNpZ25pZmljYW50IGRpZ2l0cyBwLCB3aGVyZSB4IGlzIHBvc2l0aXZlIGFuZCBwIGlzIGluIFsxLCAyMV0gb3IgdW5kZWZpbmVkLlxuLy8gRm9yIGV4YW1wbGUsIGZvcm1hdERlY2ltYWwoMS4yMykgcmV0dXJucyBbXCIxMjNcIiwgMF0uXG52YXIgZm9ybWF0RGVjaW1hbCA9IGZ1bmN0aW9uKHgsIHApIHtcbiAgaWYgKChpID0gKHggPSBwID8geC50b0V4cG9uZW50aWFsKHAgLSAxKSA6IHgudG9FeHBvbmVudGlhbCgpKS5pbmRleE9mKFwiZVwiKSkgPCAwKSByZXR1cm4gbnVsbDsgLy8gTmFOLCDCsUluZmluaXR5XG4gIHZhciBpLCBjb2VmZmljaWVudCA9IHguc2xpY2UoMCwgaSk7XG5cbiAgLy8gVGhlIHN0cmluZyByZXR1cm5lZCBieSB0b0V4cG9uZW50aWFsIGVpdGhlciBoYXMgdGhlIGZvcm0gXFxkXFwuXFxkK2VbLStdXFxkK1xuICAvLyAoZS5nLiwgMS4yZSszKSBvciB0aGUgZm9ybSBcXGRlWy0rXVxcZCsgKGUuZy4sIDFlKzMpLlxuICByZXR1cm4gW1xuICAgIGNvZWZmaWNpZW50Lmxlbmd0aCA+IDEgPyBjb2VmZmljaWVudFswXSArIGNvZWZmaWNpZW50LnNsaWNlKDIpIDogY29lZmZpY2llbnQsXG4gICAgK3guc2xpY2UoaSArIDEpXG4gIF07XG59O1xuXG52YXIgZXhwb25lbnQgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4ID0gZm9ybWF0RGVjaW1hbChNYXRoLmFicyh4KSksIHggPyB4WzFdIDogTmFOO1xufTtcblxudmFyIGZvcm1hdEdyb3VwID0gZnVuY3Rpb24oZ3JvdXBpbmcsIHRob3VzYW5kcykge1xuICByZXR1cm4gZnVuY3Rpb24odmFsdWUsIHdpZHRoKSB7XG4gICAgdmFyIGkgPSB2YWx1ZS5sZW5ndGgsXG4gICAgICAgIHQgPSBbXSxcbiAgICAgICAgaiA9IDAsXG4gICAgICAgIGcgPSBncm91cGluZ1swXSxcbiAgICAgICAgbGVuZ3RoID0gMDtcblxuICAgIHdoaWxlIChpID4gMCAmJiBnID4gMCkge1xuICAgICAgaWYgKGxlbmd0aCArIGcgKyAxID4gd2lkdGgpIGcgPSBNYXRoLm1heCgxLCB3aWR0aCAtIGxlbmd0aCk7XG4gICAgICB0LnB1c2godmFsdWUuc3Vic3RyaW5nKGkgLT0gZywgaSArIGcpKTtcbiAgICAgIGlmICgobGVuZ3RoICs9IGcgKyAxKSA+IHdpZHRoKSBicmVhaztcbiAgICAgIGcgPSBncm91cGluZ1tqID0gKGogKyAxKSAlIGdyb3VwaW5nLmxlbmd0aF07XG4gICAgfVxuXG4gICAgcmV0dXJuIHQucmV2ZXJzZSgpLmpvaW4odGhvdXNhbmRzKTtcbiAgfTtcbn07XG5cbnZhciBmb3JtYXROdW1lcmFscyA9IGZ1bmN0aW9uKG51bWVyYWxzKSB7XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiB2YWx1ZS5yZXBsYWNlKC9bMC05XS9nLCBmdW5jdGlvbihpKSB7XG4gICAgICByZXR1cm4gbnVtZXJhbHNbK2ldO1xuICAgIH0pO1xuICB9O1xufTtcblxudmFyIGZvcm1hdERlZmF1bHQgPSBmdW5jdGlvbih4LCBwKSB7XG4gIHggPSB4LnRvUHJlY2lzaW9uKHApO1xuXG4gIG91dDogZm9yICh2YXIgbiA9IHgubGVuZ3RoLCBpID0gMSwgaTAgPSAtMSwgaTE7IGkgPCBuOyArK2kpIHtcbiAgICBzd2l0Y2ggKHhbaV0pIHtcbiAgICAgIGNhc2UgXCIuXCI6IGkwID0gaTEgPSBpOyBicmVhaztcbiAgICAgIGNhc2UgXCIwXCI6IGlmIChpMCA9PT0gMCkgaTAgPSBpOyBpMSA9IGk7IGJyZWFrO1xuICAgICAgY2FzZSBcImVcIjogYnJlYWsgb3V0O1xuICAgICAgZGVmYXVsdDogaWYgKGkwID4gMCkgaTAgPSAwOyBicmVhaztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gaTAgPiAwID8geC5zbGljZSgwLCBpMCkgKyB4LnNsaWNlKGkxICsgMSkgOiB4O1xufTtcblxudmFyIHByZWZpeEV4cG9uZW50O1xuXG52YXIgZm9ybWF0UHJlZml4QXV0byA9IGZ1bmN0aW9uKHgsIHApIHtcbiAgdmFyIGQgPSBmb3JtYXREZWNpbWFsKHgsIHApO1xuICBpZiAoIWQpIHJldHVybiB4ICsgXCJcIjtcbiAgdmFyIGNvZWZmaWNpZW50ID0gZFswXSxcbiAgICAgIGV4cG9uZW50ID0gZFsxXSxcbiAgICAgIGkgPSBleHBvbmVudCAtIChwcmVmaXhFeHBvbmVudCA9IE1hdGgubWF4KC04LCBNYXRoLm1pbig4LCBNYXRoLmZsb29yKGV4cG9uZW50IC8gMykpKSAqIDMpICsgMSxcbiAgICAgIG4gPSBjb2VmZmljaWVudC5sZW5ndGg7XG4gIHJldHVybiBpID09PSBuID8gY29lZmZpY2llbnRcbiAgICAgIDogaSA+IG4gPyBjb2VmZmljaWVudCArIG5ldyBBcnJheShpIC0gbiArIDEpLmpvaW4oXCIwXCIpXG4gICAgICA6IGkgPiAwID8gY29lZmZpY2llbnQuc2xpY2UoMCwgaSkgKyBcIi5cIiArIGNvZWZmaWNpZW50LnNsaWNlKGkpXG4gICAgICA6IFwiMC5cIiArIG5ldyBBcnJheSgxIC0gaSkuam9pbihcIjBcIikgKyBmb3JtYXREZWNpbWFsKHgsIE1hdGgubWF4KDAsIHAgKyBpIC0gMSkpWzBdOyAvLyBsZXNzIHRoYW4gMXkhXG59O1xuXG52YXIgZm9ybWF0Um91bmRlZCA9IGZ1bmN0aW9uKHgsIHApIHtcbiAgdmFyIGQgPSBmb3JtYXREZWNpbWFsKHgsIHApO1xuICBpZiAoIWQpIHJldHVybiB4ICsgXCJcIjtcbiAgdmFyIGNvZWZmaWNpZW50ID0gZFswXSxcbiAgICAgIGV4cG9uZW50ID0gZFsxXTtcbiAgcmV0dXJuIGV4cG9uZW50IDwgMCA/IFwiMC5cIiArIG5ldyBBcnJheSgtZXhwb25lbnQpLmpvaW4oXCIwXCIpICsgY29lZmZpY2llbnRcbiAgICAgIDogY29lZmZpY2llbnQubGVuZ3RoID4gZXhwb25lbnQgKyAxID8gY29lZmZpY2llbnQuc2xpY2UoMCwgZXhwb25lbnQgKyAxKSArIFwiLlwiICsgY29lZmZpY2llbnQuc2xpY2UoZXhwb25lbnQgKyAxKVxuICAgICAgOiBjb2VmZmljaWVudCArIG5ldyBBcnJheShleHBvbmVudCAtIGNvZWZmaWNpZW50Lmxlbmd0aCArIDIpLmpvaW4oXCIwXCIpO1xufTtcblxudmFyIGZvcm1hdFR5cGVzID0ge1xuICBcIlwiOiBmb3JtYXREZWZhdWx0LFxuICBcIiVcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4gKHggKiAxMDApLnRvRml4ZWQocCk7IH0sXG4gIFwiYlwiOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDIpOyB9LFxuICBcImNcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4geCArIFwiXCI7IH0sXG4gIFwiZFwiOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDEwKTsgfSxcbiAgXCJlXCI6IGZ1bmN0aW9uKHgsIHApIHsgcmV0dXJuIHgudG9FeHBvbmVudGlhbChwKTsgfSxcbiAgXCJmXCI6IGZ1bmN0aW9uKHgsIHApIHsgcmV0dXJuIHgudG9GaXhlZChwKTsgfSxcbiAgXCJnXCI6IGZ1bmN0aW9uKHgsIHApIHsgcmV0dXJuIHgudG9QcmVjaXNpb24ocCk7IH0sXG4gIFwib1wiOiBmdW5jdGlvbih4KSB7IHJldHVybiBNYXRoLnJvdW5kKHgpLnRvU3RyaW5nKDgpOyB9LFxuICBcInBcIjogZnVuY3Rpb24oeCwgcCkgeyByZXR1cm4gZm9ybWF0Um91bmRlZCh4ICogMTAwLCBwKTsgfSxcbiAgXCJyXCI6IGZvcm1hdFJvdW5kZWQsXG4gIFwic1wiOiBmb3JtYXRQcmVmaXhBdXRvLFxuICBcIlhcIjogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5yb3VuZCh4KS50b1N0cmluZygxNikudG9VcHBlckNhc2UoKTsgfSxcbiAgXCJ4XCI6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgucm91bmQoeCkudG9TdHJpbmcoMTYpOyB9XG59O1xuXG4vLyBbW2ZpbGxdYWxpZ25dW3NpZ25dW3N5bWJvbF1bMF1bd2lkdGhdWyxdWy5wcmVjaXNpb25dW3R5cGVdXG52YXIgcmUgPSAvXig/OiguKT8oWzw+PV5dKSk/KFsrXFwtXFwoIF0pPyhbJCNdKT8oMCk/KFxcZCspPygsKT8oXFwuXFxkKyk/KFthLXolXSk/JC9pO1xuXG5mdW5jdGlvbiBmb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyKSB7XG4gIHJldHVybiBuZXcgRm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllcik7XG59XG5cbmZvcm1hdFNwZWNpZmllci5wcm90b3R5cGUgPSBGb3JtYXRTcGVjaWZpZXIucHJvdG90eXBlOyAvLyBpbnN0YW5jZW9mXG5cbmZ1bmN0aW9uIEZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpIHtcbiAgaWYgKCEobWF0Y2ggPSByZS5leGVjKHNwZWNpZmllcikpKSB0aHJvdyBuZXcgRXJyb3IoXCJpbnZhbGlkIGZvcm1hdDogXCIgKyBzcGVjaWZpZXIpO1xuXG4gIHZhciBtYXRjaCxcbiAgICAgIGZpbGwgPSBtYXRjaFsxXSB8fCBcIiBcIixcbiAgICAgIGFsaWduID0gbWF0Y2hbMl0gfHwgXCI+XCIsXG4gICAgICBzaWduID0gbWF0Y2hbM10gfHwgXCItXCIsXG4gICAgICBzeW1ib2wgPSBtYXRjaFs0XSB8fCBcIlwiLFxuICAgICAgemVybyA9ICEhbWF0Y2hbNV0sXG4gICAgICB3aWR0aCA9IG1hdGNoWzZdICYmICttYXRjaFs2XSxcbiAgICAgIGNvbW1hID0gISFtYXRjaFs3XSxcbiAgICAgIHByZWNpc2lvbiA9IG1hdGNoWzhdICYmICttYXRjaFs4XS5zbGljZSgxKSxcbiAgICAgIHR5cGUgPSBtYXRjaFs5XSB8fCBcIlwiO1xuXG4gIC8vIFRoZSBcIm5cIiB0eXBlIGlzIGFuIGFsaWFzIGZvciBcIixnXCIuXG4gIGlmICh0eXBlID09PSBcIm5cIikgY29tbWEgPSB0cnVlLCB0eXBlID0gXCJnXCI7XG5cbiAgLy8gTWFwIGludmFsaWQgdHlwZXMgdG8gdGhlIGRlZmF1bHQgZm9ybWF0LlxuICBlbHNlIGlmICghZm9ybWF0VHlwZXNbdHlwZV0pIHR5cGUgPSBcIlwiO1xuXG4gIC8vIElmIHplcm8gZmlsbCBpcyBzcGVjaWZpZWQsIHBhZGRpbmcgZ29lcyBhZnRlciBzaWduIGFuZCBiZWZvcmUgZGlnaXRzLlxuICBpZiAoemVybyB8fCAoZmlsbCA9PT0gXCIwXCIgJiYgYWxpZ24gPT09IFwiPVwiKSkgemVybyA9IHRydWUsIGZpbGwgPSBcIjBcIiwgYWxpZ24gPSBcIj1cIjtcblxuICB0aGlzLmZpbGwgPSBmaWxsO1xuICB0aGlzLmFsaWduID0gYWxpZ247XG4gIHRoaXMuc2lnbiA9IHNpZ247XG4gIHRoaXMuc3ltYm9sID0gc3ltYm9sO1xuICB0aGlzLnplcm8gPSB6ZXJvO1xuICB0aGlzLndpZHRoID0gd2lkdGg7XG4gIHRoaXMuY29tbWEgPSBjb21tYTtcbiAgdGhpcy5wcmVjaXNpb24gPSBwcmVjaXNpb247XG4gIHRoaXMudHlwZSA9IHR5cGU7XG59XG5cbkZvcm1hdFNwZWNpZmllci5wcm90b3R5cGUudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHRoaXMuZmlsbFxuICAgICAgKyB0aGlzLmFsaWduXG4gICAgICArIHRoaXMuc2lnblxuICAgICAgKyB0aGlzLnN5bWJvbFxuICAgICAgKyAodGhpcy56ZXJvID8gXCIwXCIgOiBcIlwiKVxuICAgICAgKyAodGhpcy53aWR0aCA9PSBudWxsID8gXCJcIiA6IE1hdGgubWF4KDEsIHRoaXMud2lkdGggfCAwKSlcbiAgICAgICsgKHRoaXMuY29tbWEgPyBcIixcIiA6IFwiXCIpXG4gICAgICArICh0aGlzLnByZWNpc2lvbiA9PSBudWxsID8gXCJcIiA6IFwiLlwiICsgTWF0aC5tYXgoMCwgdGhpcy5wcmVjaXNpb24gfCAwKSlcbiAgICAgICsgdGhpcy50eXBlO1xufTtcblxudmFyIGlkZW50aXR5JDYgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4O1xufTtcblxudmFyIHByZWZpeGVzID0gW1wieVwiLFwielwiLFwiYVwiLFwiZlwiLFwicFwiLFwiblwiLFwiwrVcIixcIm1cIixcIlwiLFwia1wiLFwiTVwiLFwiR1wiLFwiVFwiLFwiUFwiLFwiRVwiLFwiWlwiLFwiWVwiXTtcblxudmFyIGZvcm1hdExvY2FsZSQxID0gZnVuY3Rpb24obG9jYWxlKSB7XG4gIHZhciBncm91cCA9IGxvY2FsZS5ncm91cGluZyAmJiBsb2NhbGUudGhvdXNhbmRzID8gZm9ybWF0R3JvdXAobG9jYWxlLmdyb3VwaW5nLCBsb2NhbGUudGhvdXNhbmRzKSA6IGlkZW50aXR5JDYsXG4gICAgICBjdXJyZW5jeSA9IGxvY2FsZS5jdXJyZW5jeSxcbiAgICAgIGRlY2ltYWwgPSBsb2NhbGUuZGVjaW1hbCxcbiAgICAgIG51bWVyYWxzID0gbG9jYWxlLm51bWVyYWxzID8gZm9ybWF0TnVtZXJhbHMobG9jYWxlLm51bWVyYWxzKSA6IGlkZW50aXR5JDYsXG4gICAgICBwZXJjZW50ID0gbG9jYWxlLnBlcmNlbnQgfHwgXCIlXCI7XG5cbiAgZnVuY3Rpb24gbmV3Rm9ybWF0KHNwZWNpZmllcikge1xuICAgIHNwZWNpZmllciA9IGZvcm1hdFNwZWNpZmllcihzcGVjaWZpZXIpO1xuXG4gICAgdmFyIGZpbGwgPSBzcGVjaWZpZXIuZmlsbCxcbiAgICAgICAgYWxpZ24gPSBzcGVjaWZpZXIuYWxpZ24sXG4gICAgICAgIHNpZ24gPSBzcGVjaWZpZXIuc2lnbixcbiAgICAgICAgc3ltYm9sID0gc3BlY2lmaWVyLnN5bWJvbCxcbiAgICAgICAgemVybyA9IHNwZWNpZmllci56ZXJvLFxuICAgICAgICB3aWR0aCA9IHNwZWNpZmllci53aWR0aCxcbiAgICAgICAgY29tbWEgPSBzcGVjaWZpZXIuY29tbWEsXG4gICAgICAgIHByZWNpc2lvbiA9IHNwZWNpZmllci5wcmVjaXNpb24sXG4gICAgICAgIHR5cGUgPSBzcGVjaWZpZXIudHlwZTtcblxuICAgIC8vIENvbXB1dGUgdGhlIHByZWZpeCBhbmQgc3VmZml4LlxuICAgIC8vIEZvciBTSS1wcmVmaXgsIHRoZSBzdWZmaXggaXMgbGF6aWx5IGNvbXB1dGVkLlxuICAgIHZhciBwcmVmaXggPSBzeW1ib2wgPT09IFwiJFwiID8gY3VycmVuY3lbMF0gOiBzeW1ib2wgPT09IFwiI1wiICYmIC9bYm94WF0vLnRlc3QodHlwZSkgPyBcIjBcIiArIHR5cGUudG9Mb3dlckNhc2UoKSA6IFwiXCIsXG4gICAgICAgIHN1ZmZpeCA9IHN5bWJvbCA9PT0gXCIkXCIgPyBjdXJyZW5jeVsxXSA6IC9bJXBdLy50ZXN0KHR5cGUpID8gcGVyY2VudCA6IFwiXCI7XG5cbiAgICAvLyBXaGF0IGZvcm1hdCBmdW5jdGlvbiBzaG91bGQgd2UgdXNlP1xuICAgIC8vIElzIHRoaXMgYW4gaW50ZWdlciB0eXBlP1xuICAgIC8vIENhbiB0aGlzIHR5cGUgZ2VuZXJhdGUgZXhwb25lbnRpYWwgbm90YXRpb24/XG4gICAgdmFyIGZvcm1hdFR5cGUgPSBmb3JtYXRUeXBlc1t0eXBlXSxcbiAgICAgICAgbWF5YmVTdWZmaXggPSAhdHlwZSB8fCAvW2RlZmdwcnMlXS8udGVzdCh0eXBlKTtcblxuICAgIC8vIFNldCB0aGUgZGVmYXVsdCBwcmVjaXNpb24gaWYgbm90IHNwZWNpZmllZCxcbiAgICAvLyBvciBjbGFtcCB0aGUgc3BlY2lmaWVkIHByZWNpc2lvbiB0byB0aGUgc3VwcG9ydGVkIHJhbmdlLlxuICAgIC8vIEZvciBzaWduaWZpY2FudCBwcmVjaXNpb24sIGl0IG11c3QgYmUgaW4gWzEsIDIxXS5cbiAgICAvLyBGb3IgZml4ZWQgcHJlY2lzaW9uLCBpdCBtdXN0IGJlIGluIFswLCAyMF0uXG4gICAgcHJlY2lzaW9uID0gcHJlY2lzaW9uID09IG51bGwgPyAodHlwZSA/IDYgOiAxMilcbiAgICAgICAgOiAvW2dwcnNdLy50ZXN0KHR5cGUpID8gTWF0aC5tYXgoMSwgTWF0aC5taW4oMjEsIHByZWNpc2lvbikpXG4gICAgICAgIDogTWF0aC5tYXgoMCwgTWF0aC5taW4oMjAsIHByZWNpc2lvbikpO1xuXG4gICAgZnVuY3Rpb24gZm9ybWF0KHZhbHVlKSB7XG4gICAgICB2YXIgdmFsdWVQcmVmaXggPSBwcmVmaXgsXG4gICAgICAgICAgdmFsdWVTdWZmaXggPSBzdWZmaXgsXG4gICAgICAgICAgaSwgbiwgYztcblxuICAgICAgaWYgKHR5cGUgPT09IFwiY1wiKSB7XG4gICAgICAgIHZhbHVlU3VmZml4ID0gZm9ybWF0VHlwZSh2YWx1ZSkgKyB2YWx1ZVN1ZmZpeDtcbiAgICAgICAgdmFsdWUgPSBcIlwiO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdmFsdWUgPSArdmFsdWU7XG5cbiAgICAgICAgLy8gUGVyZm9ybSB0aGUgaW5pdGlhbCBmb3JtYXR0aW5nLlxuICAgICAgICB2YXIgdmFsdWVOZWdhdGl2ZSA9IHZhbHVlIDwgMDtcbiAgICAgICAgdmFsdWUgPSBmb3JtYXRUeXBlKE1hdGguYWJzKHZhbHVlKSwgcHJlY2lzaW9uKTtcblxuICAgICAgICAvLyBJZiBhIG5lZ2F0aXZlIHZhbHVlIHJvdW5kcyB0byB6ZXJvIGR1cmluZyBmb3JtYXR0aW5nLCB0cmVhdCBhcyBwb3NpdGl2ZS5cbiAgICAgICAgaWYgKHZhbHVlTmVnYXRpdmUgJiYgK3ZhbHVlID09PSAwKSB2YWx1ZU5lZ2F0aXZlID0gZmFsc2U7XG5cbiAgICAgICAgLy8gQ29tcHV0ZSB0aGUgcHJlZml4IGFuZCBzdWZmaXguXG4gICAgICAgIHZhbHVlUHJlZml4ID0gKHZhbHVlTmVnYXRpdmUgPyAoc2lnbiA9PT0gXCIoXCIgPyBzaWduIDogXCItXCIpIDogc2lnbiA9PT0gXCItXCIgfHwgc2lnbiA9PT0gXCIoXCIgPyBcIlwiIDogc2lnbikgKyB2YWx1ZVByZWZpeDtcbiAgICAgICAgdmFsdWVTdWZmaXggPSAodHlwZSA9PT0gXCJzXCIgPyBwcmVmaXhlc1s4ICsgcHJlZml4RXhwb25lbnQgLyAzXSA6IFwiXCIpICsgdmFsdWVTdWZmaXggKyAodmFsdWVOZWdhdGl2ZSAmJiBzaWduID09PSBcIihcIiA/IFwiKVwiIDogXCJcIik7XG5cbiAgICAgICAgLy8gQnJlYWsgdGhlIGZvcm1hdHRlZCB2YWx1ZSBpbnRvIHRoZSBpbnRlZ2VyIOKAnHZhbHVl4oCdIHBhcnQgdGhhdCBjYW4gYmVcbiAgICAgICAgLy8gZ3JvdXBlZCwgYW5kIGZyYWN0aW9uYWwgb3IgZXhwb25lbnRpYWwg4oCcc3VmZml44oCdIHBhcnQgdGhhdCBpcyBub3QuXG4gICAgICAgIGlmIChtYXliZVN1ZmZpeCkge1xuICAgICAgICAgIGkgPSAtMSwgbiA9IHZhbHVlLmxlbmd0aDtcbiAgICAgICAgICB3aGlsZSAoKytpIDwgbikge1xuICAgICAgICAgICAgaWYgKGMgPSB2YWx1ZS5jaGFyQ29kZUF0KGkpLCA0OCA+IGMgfHwgYyA+IDU3KSB7XG4gICAgICAgICAgICAgIHZhbHVlU3VmZml4ID0gKGMgPT09IDQ2ID8gZGVjaW1hbCArIHZhbHVlLnNsaWNlKGkgKyAxKSA6IHZhbHVlLnNsaWNlKGkpKSArIHZhbHVlU3VmZml4O1xuICAgICAgICAgICAgICB2YWx1ZSA9IHZhbHVlLnNsaWNlKDAsIGkpO1xuICAgICAgICAgICAgICBicmVhaztcbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSWYgdGhlIGZpbGwgY2hhcmFjdGVyIGlzIG5vdCBcIjBcIiwgZ3JvdXBpbmcgaXMgYXBwbGllZCBiZWZvcmUgcGFkZGluZy5cbiAgICAgIGlmIChjb21tYSAmJiAhemVybykgdmFsdWUgPSBncm91cCh2YWx1ZSwgSW5maW5pdHkpO1xuXG4gICAgICAvLyBDb21wdXRlIHRoZSBwYWRkaW5nLlxuICAgICAgdmFyIGxlbmd0aCA9IHZhbHVlUHJlZml4Lmxlbmd0aCArIHZhbHVlLmxlbmd0aCArIHZhbHVlU3VmZml4Lmxlbmd0aCxcbiAgICAgICAgICBwYWRkaW5nID0gbGVuZ3RoIDwgd2lkdGggPyBuZXcgQXJyYXkod2lkdGggLSBsZW5ndGggKyAxKS5qb2luKGZpbGwpIDogXCJcIjtcblxuICAgICAgLy8gSWYgdGhlIGZpbGwgY2hhcmFjdGVyIGlzIFwiMFwiLCBncm91cGluZyBpcyBhcHBsaWVkIGFmdGVyIHBhZGRpbmcuXG4gICAgICBpZiAoY29tbWEgJiYgemVybykgdmFsdWUgPSBncm91cChwYWRkaW5nICsgdmFsdWUsIHBhZGRpbmcubGVuZ3RoID8gd2lkdGggLSB2YWx1ZVN1ZmZpeC5sZW5ndGggOiBJbmZpbml0eSksIHBhZGRpbmcgPSBcIlwiO1xuXG4gICAgICAvLyBSZWNvbnN0cnVjdCB0aGUgZmluYWwgb3V0cHV0IGJhc2VkIG9uIHRoZSBkZXNpcmVkIGFsaWdubWVudC5cbiAgICAgIHN3aXRjaCAoYWxpZ24pIHtcbiAgICAgICAgY2FzZSBcIjxcIjogdmFsdWUgPSB2YWx1ZVByZWZpeCArIHZhbHVlICsgdmFsdWVTdWZmaXggKyBwYWRkaW5nOyBicmVhaztcbiAgICAgICAgY2FzZSBcIj1cIjogdmFsdWUgPSB2YWx1ZVByZWZpeCArIHBhZGRpbmcgKyB2YWx1ZSArIHZhbHVlU3VmZml4OyBicmVhaztcbiAgICAgICAgY2FzZSBcIl5cIjogdmFsdWUgPSBwYWRkaW5nLnNsaWNlKDAsIGxlbmd0aCA9IHBhZGRpbmcubGVuZ3RoID4+IDEpICsgdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4ICsgcGFkZGluZy5zbGljZShsZW5ndGgpOyBicmVhaztcbiAgICAgICAgZGVmYXVsdDogdmFsdWUgPSBwYWRkaW5nICsgdmFsdWVQcmVmaXggKyB2YWx1ZSArIHZhbHVlU3VmZml4OyBicmVhaztcbiAgICAgIH1cblxuICAgICAgcmV0dXJuIG51bWVyYWxzKHZhbHVlKTtcbiAgICB9XG5cbiAgICBmb3JtYXQudG9TdHJpbmcgPSBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzcGVjaWZpZXIgKyBcIlwiO1xuICAgIH07XG5cbiAgICByZXR1cm4gZm9ybWF0O1xuICB9XG5cbiAgZnVuY3Rpb24gZm9ybWF0UHJlZml4KHNwZWNpZmllciwgdmFsdWUpIHtcbiAgICB2YXIgZiA9IG5ld0Zvcm1hdCgoc3BlY2lmaWVyID0gZm9ybWF0U3BlY2lmaWVyKHNwZWNpZmllciksIHNwZWNpZmllci50eXBlID0gXCJmXCIsIHNwZWNpZmllcikpLFxuICAgICAgICBlID0gTWF0aC5tYXgoLTgsIE1hdGgubWluKDgsIE1hdGguZmxvb3IoZXhwb25lbnQodmFsdWUpIC8gMykpKSAqIDMsXG4gICAgICAgIGsgPSBNYXRoLnBvdygxMCwgLWUpLFxuICAgICAgICBwcmVmaXggPSBwcmVmaXhlc1s4ICsgZSAvIDNdO1xuICAgIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgICAgcmV0dXJuIGYoayAqIHZhbHVlKSArIHByZWZpeDtcbiAgICB9O1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBmb3JtYXQ6IG5ld0Zvcm1hdCxcbiAgICBmb3JtYXRQcmVmaXg6IGZvcm1hdFByZWZpeFxuICB9O1xufTtcblxudmFyIGxvY2FsZSQyO1xudmFyIGZvcm1hdDtcbnZhciBmb3JtYXRQcmVmaXg7XG5cbmRlZmF1bHRMb2NhbGUkMSh7XG4gIGRlY2ltYWw6IFwiLlwiLFxuICB0aG91c2FuZHM6IFwiLFwiLFxuICBncm91cGluZzogWzNdLFxuICBjdXJyZW5jeTogW1wiJFwiLCBcIlwiXVxufSk7XG5cbmZ1bmN0aW9uIGRlZmF1bHRMb2NhbGUkMShkZWZpbml0aW9uKSB7XG4gIGxvY2FsZSQyID0gZm9ybWF0TG9jYWxlJDEoZGVmaW5pdGlvbik7XG4gIGZvcm1hdCA9IGxvY2FsZSQyLmZvcm1hdDtcbiAgZm9ybWF0UHJlZml4ID0gbG9jYWxlJDIuZm9ybWF0UHJlZml4O1xuICByZXR1cm4gbG9jYWxlJDI7XG59XG5cbnZhciBwcmVjaXNpb25GaXhlZCA9IGZ1bmN0aW9uKHN0ZXApIHtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIC1leHBvbmVudChNYXRoLmFicyhzdGVwKSkpO1xufTtcblxudmFyIHByZWNpc2lvblByZWZpeCA9IGZ1bmN0aW9uKHN0ZXAsIHZhbHVlKSB7XG4gIHJldHVybiBNYXRoLm1heCgwLCBNYXRoLm1heCgtOCwgTWF0aC5taW4oOCwgTWF0aC5mbG9vcihleHBvbmVudCh2YWx1ZSkgLyAzKSkpICogMyAtIGV4cG9uZW50KE1hdGguYWJzKHN0ZXApKSk7XG59O1xuXG52YXIgcHJlY2lzaW9uUm91bmQgPSBmdW5jdGlvbihzdGVwLCBtYXgpIHtcbiAgc3RlcCA9IE1hdGguYWJzKHN0ZXApLCBtYXggPSBNYXRoLmFicyhtYXgpIC0gc3RlcDtcbiAgcmV0dXJuIE1hdGgubWF4KDAsIGV4cG9uZW50KG1heCkgLSBleHBvbmVudChzdGVwKSkgKyAxO1xufTtcblxudmFyIHRpY2tGb3JtYXQkMSA9IGZ1bmN0aW9uKGRvbWFpbiwgY291bnQsIHNwZWNpZmllcikge1xuICB2YXIgc3RhcnQgPSBkb21haW5bMF0sXG4gICAgICBzdG9wID0gZG9tYWluW2RvbWFpbi5sZW5ndGggLSAxXSxcbiAgICAgIHN0ZXAgPSB0aWNrU3RlcChzdGFydCwgc3RvcCwgY291bnQgPT0gbnVsbCA/IDEwIDogY291bnQpLFxuICAgICAgcHJlY2lzaW9uO1xuICBzcGVjaWZpZXIgPSBmb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyID09IG51bGwgPyBcIixmXCIgOiBzcGVjaWZpZXIpO1xuICBzd2l0Y2ggKHNwZWNpZmllci50eXBlKSB7XG4gICAgY2FzZSBcInNcIjoge1xuICAgICAgdmFyIHZhbHVlID0gTWF0aC5tYXgoTWF0aC5hYnMoc3RhcnQpLCBNYXRoLmFicyhzdG9wKSk7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25QcmVmaXgoc3RlcCwgdmFsdWUpKSkgc3BlY2lmaWVyLnByZWNpc2lvbiA9IHByZWNpc2lvbjtcbiAgICAgIHJldHVybiBmb3JtYXRQcmVmaXgoc3BlY2lmaWVyLCB2YWx1ZSk7XG4gICAgfVxuICAgIGNhc2UgXCJcIjpcbiAgICBjYXNlIFwiZVwiOlxuICAgIGNhc2UgXCJnXCI6XG4gICAgY2FzZSBcInBcIjpcbiAgICBjYXNlIFwiclwiOiB7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25Sb3VuZChzdGVwLCBNYXRoLm1heChNYXRoLmFicyhzdGFydCksIE1hdGguYWJzKHN0b3ApKSkpKSBzcGVjaWZpZXIucHJlY2lzaW9uID0gcHJlY2lzaW9uIC0gKHNwZWNpZmllci50eXBlID09PSBcImVcIik7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgY2FzZSBcImZcIjpcbiAgICBjYXNlIFwiJVwiOiB7XG4gICAgICBpZiAoc3BlY2lmaWVyLnByZWNpc2lvbiA9PSBudWxsICYmICFpc05hTihwcmVjaXNpb24gPSBwcmVjaXNpb25GaXhlZChzdGVwKSkpIHNwZWNpZmllci5wcmVjaXNpb24gPSBwcmVjaXNpb24gLSAoc3BlY2lmaWVyLnR5cGUgPT09IFwiJVwiKSAqIDI7XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cbiAgcmV0dXJuIGZvcm1hdChzcGVjaWZpZXIpO1xufTtcblxuZnVuY3Rpb24gbGluZWFyaXNoKHNjYWxlKSB7XG4gIHZhciBkb21haW4gPSBzY2FsZS5kb21haW47XG5cbiAgc2NhbGUudGlja3MgPSBmdW5jdGlvbihjb3VudCkge1xuICAgIHZhciBkID0gZG9tYWluKCk7XG4gICAgcmV0dXJuIHRpY2tzKGRbMF0sIGRbZC5sZW5ndGggLSAxXSwgY291bnQgPT0gbnVsbCA/IDEwIDogY291bnQpO1xuICB9O1xuXG4gIHNjYWxlLnRpY2tGb3JtYXQgPSBmdW5jdGlvbihjb3VudCwgc3BlY2lmaWVyKSB7XG4gICAgcmV0dXJuIHRpY2tGb3JtYXQkMShkb21haW4oKSwgY291bnQsIHNwZWNpZmllcik7XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgaWYgKGNvdW50ID09IG51bGwpIGNvdW50ID0gMTA7XG5cbiAgICB2YXIgZCA9IGRvbWFpbigpLFxuICAgICAgICBpMCA9IDAsXG4gICAgICAgIGkxID0gZC5sZW5ndGggLSAxLFxuICAgICAgICBzdGFydCA9IGRbaTBdLFxuICAgICAgICBzdG9wID0gZFtpMV0sXG4gICAgICAgIHN0ZXA7XG5cbiAgICBpZiAoc3RvcCA8IHN0YXJ0KSB7XG4gICAgICBzdGVwID0gc3RhcnQsIHN0YXJ0ID0gc3RvcCwgc3RvcCA9IHN0ZXA7XG4gICAgICBzdGVwID0gaTAsIGkwID0gaTEsIGkxID0gc3RlcDtcbiAgICB9XG5cbiAgICBzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpO1xuXG4gICAgaWYgKHN0ZXAgPiAwKSB7XG4gICAgICBzdGFydCA9IE1hdGguZmxvb3Ioc3RhcnQgLyBzdGVwKSAqIHN0ZXA7XG4gICAgICBzdG9wID0gTWF0aC5jZWlsKHN0b3AgLyBzdGVwKSAqIHN0ZXA7XG4gICAgICBzdGVwID0gdGlja0luY3JlbWVudChzdGFydCwgc3RvcCwgY291bnQpO1xuICAgIH0gZWxzZSBpZiAoc3RlcCA8IDApIHtcbiAgICAgIHN0YXJ0ID0gTWF0aC5jZWlsKHN0YXJ0ICogc3RlcCkgLyBzdGVwO1xuICAgICAgc3RvcCA9IE1hdGguZmxvb3Ioc3RvcCAqIHN0ZXApIC8gc3RlcDtcbiAgICAgIHN0ZXAgPSB0aWNrSW5jcmVtZW50KHN0YXJ0LCBzdG9wLCBjb3VudCk7XG4gICAgfVxuXG4gICAgaWYgKHN0ZXAgPiAwKSB7XG4gICAgICBkW2kwXSA9IE1hdGguZmxvb3Ioc3RhcnQgLyBzdGVwKSAqIHN0ZXA7XG4gICAgICBkW2kxXSA9IE1hdGguY2VpbChzdG9wIC8gc3RlcCkgKiBzdGVwO1xuICAgICAgZG9tYWluKGQpO1xuICAgIH0gZWxzZSBpZiAoc3RlcCA8IDApIHtcbiAgICAgIGRbaTBdID0gTWF0aC5jZWlsKHN0YXJ0ICogc3RlcCkgLyBzdGVwO1xuICAgICAgZFtpMV0gPSBNYXRoLmZsb29yKHN0b3AgKiBzdGVwKSAvIHN0ZXA7XG4gICAgICBkb21haW4oZCk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHNjYWxlO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxuZnVuY3Rpb24gbGluZWFyKCkge1xuICB2YXIgc2NhbGUgPSBjb250aW51b3VzKGRlaW50ZXJwb2xhdGVMaW5lYXIsIHJlaW50ZXJwb2xhdGUpO1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gY29weShzY2FsZSwgbGluZWFyKCkpO1xuICB9O1xuXG4gIHJldHVybiBsaW5lYXJpc2goc2NhbGUpO1xufVxuXG5mdW5jdGlvbiBpZGVudGl0eSQ0KCkge1xuICB2YXIgZG9tYWluID0gWzAsIDFdO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICByZXR1cm4gK3g7XG4gIH1cblxuICBzY2FsZS5pbnZlcnQgPSBzY2FsZTtcblxuICBzY2FsZS5kb21haW4gPSBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkb21haW4gPSBtYXAkMy5jYWxsKF8sIG51bWJlciQyKSwgc2NhbGUpIDogZG9tYWluLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBpZGVudGl0eSQ0KCkuZG9tYWluKGRvbWFpbik7XG4gIH07XG5cbiAgcmV0dXJuIGxpbmVhcmlzaChzY2FsZSk7XG59XG5cbnZhciBuaWNlID0gZnVuY3Rpb24oZG9tYWluLCBpbnRlcnZhbCkge1xuICBkb21haW4gPSBkb21haW4uc2xpY2UoKTtcblxuICB2YXIgaTAgPSAwLFxuICAgICAgaTEgPSBkb21haW4ubGVuZ3RoIC0gMSxcbiAgICAgIHgwID0gZG9tYWluW2kwXSxcbiAgICAgIHgxID0gZG9tYWluW2kxXSxcbiAgICAgIHQ7XG5cbiAgaWYgKHgxIDwgeDApIHtcbiAgICB0ID0gaTAsIGkwID0gaTEsIGkxID0gdDtcbiAgICB0ID0geDAsIHgwID0geDEsIHgxID0gdDtcbiAgfVxuXG4gIGRvbWFpbltpMF0gPSBpbnRlcnZhbC5mbG9vcih4MCk7XG4gIGRvbWFpbltpMV0gPSBpbnRlcnZhbC5jZWlsKHgxKTtcbiAgcmV0dXJuIGRvbWFpbjtcbn07XG5cbmZ1bmN0aW9uIGRlaW50ZXJwb2xhdGUoYSwgYikge1xuICByZXR1cm4gKGIgPSBNYXRoLmxvZyhiIC8gYSkpXG4gICAgICA/IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgubG9nKHggLyBhKSAvIGI7IH1cbiAgICAgIDogY29uc3RhbnQkNShiKTtcbn1cblxuZnVuY3Rpb24gcmVpbnRlcnBvbGF0ZSQxKGEsIGIpIHtcbiAgcmV0dXJuIGEgPCAwXG4gICAgICA/IGZ1bmN0aW9uKHQpIHsgcmV0dXJuIC1NYXRoLnBvdygtYiwgdCkgKiBNYXRoLnBvdygtYSwgMSAtIHQpOyB9XG4gICAgICA6IGZ1bmN0aW9uKHQpIHsgcmV0dXJuIE1hdGgucG93KGIsIHQpICogTWF0aC5wb3coYSwgMSAtIHQpOyB9O1xufVxuXG5mdW5jdGlvbiBwb3cxMCh4KSB7XG4gIHJldHVybiBpc0Zpbml0ZSh4KSA/ICsoXCIxZVwiICsgeCkgOiB4IDwgMCA/IDAgOiB4O1xufVxuXG5mdW5jdGlvbiBwb3dwKGJhc2UpIHtcbiAgcmV0dXJuIGJhc2UgPT09IDEwID8gcG93MTBcbiAgICAgIDogYmFzZSA9PT0gTWF0aC5FID8gTWF0aC5leHBcbiAgICAgIDogZnVuY3Rpb24oeCkgeyByZXR1cm4gTWF0aC5wb3coYmFzZSwgeCk7IH07XG59XG5cbmZ1bmN0aW9uIGxvZ3AoYmFzZSkge1xuICByZXR1cm4gYmFzZSA9PT0gTWF0aC5FID8gTWF0aC5sb2dcbiAgICAgIDogYmFzZSA9PT0gMTAgJiYgTWF0aC5sb2cxMFxuICAgICAgfHwgYmFzZSA9PT0gMiAmJiBNYXRoLmxvZzJcbiAgICAgIHx8IChiYXNlID0gTWF0aC5sb2coYmFzZSksIGZ1bmN0aW9uKHgpIHsgcmV0dXJuIE1hdGgubG9nKHgpIC8gYmFzZTsgfSk7XG59XG5cbmZ1bmN0aW9uIHJlZmxlY3QoZikge1xuICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiAtZigteCk7XG4gIH07XG59XG5cbmZ1bmN0aW9uIGxvZyQyKCkge1xuICB2YXIgc2NhbGUgPSBjb250aW51b3VzKGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUkMSkuZG9tYWluKFsxLCAxMF0pLFxuICAgICAgZG9tYWluID0gc2NhbGUuZG9tYWluLFxuICAgICAgYmFzZSA9IDEwLFxuICAgICAgbG9ncyA9IGxvZ3AoMTApLFxuICAgICAgcG93cyA9IHBvd3AoMTApO1xuXG4gIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgbG9ncyA9IGxvZ3AoYmFzZSksIHBvd3MgPSBwb3dwKGJhc2UpO1xuICAgIGlmIChkb21haW4oKVswXSA8IDApIGxvZ3MgPSByZWZsZWN0KGxvZ3MpLCBwb3dzID0gcmVmbGVjdChwb3dzKTtcbiAgICByZXR1cm4gc2NhbGU7XG4gIH1cblxuICBzY2FsZS5iYXNlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGJhc2UgPSArXywgcmVzY2FsZSgpKSA6IGJhc2U7XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbihfKSwgcmVzY2FsZSgpKSA6IGRvbWFpbigpO1xuICB9O1xuXG4gIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24oY291bnQpIHtcbiAgICB2YXIgZCA9IGRvbWFpbigpLFxuICAgICAgICB1ID0gZFswXSxcbiAgICAgICAgdiA9IGRbZC5sZW5ndGggLSAxXSxcbiAgICAgICAgcjtcblxuICAgIGlmIChyID0gdiA8IHUpIGkgPSB1LCB1ID0gdiwgdiA9IGk7XG5cbiAgICB2YXIgaSA9IGxvZ3ModSksXG4gICAgICAgIGogPSBsb2dzKHYpLFxuICAgICAgICBwLFxuICAgICAgICBrLFxuICAgICAgICB0LFxuICAgICAgICBuID0gY291bnQgPT0gbnVsbCA/IDEwIDogK2NvdW50LFxuICAgICAgICB6ID0gW107XG5cbiAgICBpZiAoIShiYXNlICUgMSkgJiYgaiAtIGkgPCBuKSB7XG4gICAgICBpID0gTWF0aC5yb3VuZChpKSAtIDEsIGogPSBNYXRoLnJvdW5kKGopICsgMTtcbiAgICAgIGlmICh1ID4gMCkgZm9yICg7IGkgPCBqOyArK2kpIHtcbiAgICAgICAgZm9yIChrID0gMSwgcCA9IHBvd3MoaSk7IGsgPCBiYXNlOyArK2spIHtcbiAgICAgICAgICB0ID0gcCAqIGs7XG4gICAgICAgICAgaWYgKHQgPCB1KSBjb250aW51ZTtcbiAgICAgICAgICBpZiAodCA+IHYpIGJyZWFrO1xuICAgICAgICAgIHoucHVzaCh0KTtcbiAgICAgICAgfVxuICAgICAgfSBlbHNlIGZvciAoOyBpIDwgajsgKytpKSB7XG4gICAgICAgIGZvciAoayA9IGJhc2UgLSAxLCBwID0gcG93cyhpKTsgayA+PSAxOyAtLWspIHtcbiAgICAgICAgICB0ID0gcCAqIGs7XG4gICAgICAgICAgaWYgKHQgPCB1KSBjb250aW51ZTtcbiAgICAgICAgICBpZiAodCA+IHYpIGJyZWFrO1xuICAgICAgICAgIHoucHVzaCh0KTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB6ID0gdGlja3MoaSwgaiwgTWF0aC5taW4oaiAtIGksIG4pKS5tYXAocG93cyk7XG4gICAgfVxuXG4gICAgcmV0dXJuIHIgPyB6LnJldmVyc2UoKSA6IHo7XG4gIH07XG5cbiAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICBpZiAoc3BlY2lmaWVyID09IG51bGwpIHNwZWNpZmllciA9IGJhc2UgPT09IDEwID8gXCIuMGVcIiA6IFwiLFwiO1xuICAgIGlmICh0eXBlb2Ygc3BlY2lmaWVyICE9PSBcImZ1bmN0aW9uXCIpIHNwZWNpZmllciA9IGZvcm1hdChzcGVjaWZpZXIpO1xuICAgIGlmIChjb3VudCA9PT0gSW5maW5pdHkpIHJldHVybiBzcGVjaWZpZXI7XG4gICAgaWYgKGNvdW50ID09IG51bGwpIGNvdW50ID0gMTA7XG4gICAgdmFyIGsgPSBNYXRoLm1heCgxLCBiYXNlICogY291bnQgLyBzY2FsZS50aWNrcygpLmxlbmd0aCk7IC8vIFRPRE8gZmFzdCBlc3RpbWF0ZT9cbiAgICByZXR1cm4gZnVuY3Rpb24oZCkge1xuICAgICAgdmFyIGkgPSBkIC8gcG93cyhNYXRoLnJvdW5kKGxvZ3MoZCkpKTtcbiAgICAgIGlmIChpICogYmFzZSA8IGJhc2UgLSAwLjUpIGkgKj0gYmFzZTtcbiAgICAgIHJldHVybiBpIDw9IGsgPyBzcGVjaWZpZXIoZCkgOiBcIlwiO1xuICAgIH07XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBkb21haW4obmljZShkb21haW4oKSwge1xuICAgICAgZmxvb3I6IGZ1bmN0aW9uKHgpIHsgcmV0dXJuIHBvd3MoTWF0aC5mbG9vcihsb2dzKHgpKSk7IH0sXG4gICAgICBjZWlsOiBmdW5jdGlvbih4KSB7IHJldHVybiBwb3dzKE1hdGguY2VpbChsb2dzKHgpKSk7IH1cbiAgICB9KSk7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBsb2ckMigpLmJhc2UoYmFzZSkpO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxuZnVuY3Rpb24gcmFpc2UoeCwgZXhwb25lbnQpIHtcbiAgcmV0dXJuIHggPCAwID8gLU1hdGgucG93KC14LCBleHBvbmVudCkgOiBNYXRoLnBvdyh4LCBleHBvbmVudCk7XG59XG5cbmZ1bmN0aW9uIHBvdyQxKCkge1xuICB2YXIgZXhwb25lbnQgPSAxLFxuICAgICAgc2NhbGUgPSBjb250aW51b3VzKGRlaW50ZXJwb2xhdGUsIHJlaW50ZXJwb2xhdGUpLFxuICAgICAgZG9tYWluID0gc2NhbGUuZG9tYWluO1xuXG4gIGZ1bmN0aW9uIGRlaW50ZXJwb2xhdGUoYSwgYikge1xuICAgIHJldHVybiAoYiA9IHJhaXNlKGIsIGV4cG9uZW50KSAtIChhID0gcmFpc2UoYSwgZXhwb25lbnQpKSlcbiAgICAgICAgPyBmdW5jdGlvbih4KSB7IHJldHVybiAocmFpc2UoeCwgZXhwb25lbnQpIC0gYSkgLyBiOyB9XG4gICAgICAgIDogY29uc3RhbnQkNShiKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlaW50ZXJwb2xhdGUoYSwgYikge1xuICAgIGIgPSByYWlzZShiLCBleHBvbmVudCkgLSAoYSA9IHJhaXNlKGEsIGV4cG9uZW50KSk7XG4gICAgcmV0dXJuIGZ1bmN0aW9uKHQpIHsgcmV0dXJuIHJhaXNlKGEgKyBiICogdCwgMSAvIGV4cG9uZW50KTsgfTtcbiAgfVxuXG4gIHNjYWxlLmV4cG9uZW50ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGV4cG9uZW50ID0gK18sIGRvbWFpbihkb21haW4oKSkpIDogZXhwb25lbnQ7XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBjb3B5KHNjYWxlLCBwb3ckMSgpLmV4cG9uZW50KGV4cG9uZW50KSk7XG4gIH07XG5cbiAgcmV0dXJuIGxpbmVhcmlzaChzY2FsZSk7XG59XG5cbmZ1bmN0aW9uIHNxcnQkMSgpIHtcbiAgcmV0dXJuIHBvdyQxKCkuZXhwb25lbnQoMC41KTtcbn1cblxuZnVuY3Rpb24gcXVhbnRpbGUoKSB7XG4gIHZhciBkb21haW4gPSBbXSxcbiAgICAgIHJhbmdlID0gW10sXG4gICAgICB0aHJlc2hvbGRzID0gW107XG5cbiAgZnVuY3Rpb24gcmVzY2FsZSgpIHtcbiAgICB2YXIgaSA9IDAsIG4gPSBNYXRoLm1heCgxLCByYW5nZS5sZW5ndGgpO1xuICAgIHRocmVzaG9sZHMgPSBuZXcgQXJyYXkobiAtIDEpO1xuICAgIHdoaWxlICgrK2kgPCBuKSB0aHJlc2hvbGRzW2kgLSAxXSA9IHRocmVzaG9sZChkb21haW4sIGkgLyBuKTtcbiAgICByZXR1cm4gc2NhbGU7XG4gIH1cblxuICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgaWYgKCFpc05hTih4ID0gK3gpKSByZXR1cm4gcmFuZ2VbYmlzZWN0UmlnaHQodGhyZXNob2xkcywgeCldO1xuICB9XG5cbiAgc2NhbGUuaW52ZXJ0RXh0ZW50ID0gZnVuY3Rpb24oeSkge1xuICAgIHZhciBpID0gcmFuZ2UuaW5kZXhPZih5KTtcbiAgICByZXR1cm4gaSA8IDAgPyBbTmFOLCBOYU5dIDogW1xuICAgICAgaSA+IDAgPyB0aHJlc2hvbGRzW2kgLSAxXSA6IGRvbWFpblswXSxcbiAgICAgIGkgPCB0aHJlc2hvbGRzLmxlbmd0aCA/IHRocmVzaG9sZHNbaV0gOiBkb21haW5bZG9tYWluLmxlbmd0aCAtIDFdXG4gICAgXTtcbiAgfTtcblxuICBzY2FsZS5kb21haW4gPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gZG9tYWluLnNsaWNlKCk7XG4gICAgZG9tYWluID0gW107XG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBfLmxlbmd0aCwgZDsgaSA8IG47ICsraSkgaWYgKGQgPSBfW2ldLCBkICE9IG51bGwgJiYgIWlzTmFOKGQgPSArZCkpIGRvbWFpbi5wdXNoKGQpO1xuICAgIGRvbWFpbi5zb3J0KGFzY2VuZGluZyk7XG4gICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSA9IHNsaWNlJDIuY2FsbChfKSwgcmVzY2FsZSgpKSA6IHJhbmdlLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUucXVhbnRpbGVzID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHRocmVzaG9sZHMuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHF1YW50aWxlKClcbiAgICAgICAgLmRvbWFpbihkb21haW4pXG4gICAgICAgIC5yYW5nZShyYW5nZSk7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiBxdWFudGl6ZSQyKCkge1xuICB2YXIgeDAgPSAwLFxuICAgICAgeDEgPSAxLFxuICAgICAgbiA9IDEsXG4gICAgICBkb21haW4gPSBbMC41XSxcbiAgICAgIHJhbmdlID0gWzAsIDFdO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICBpZiAoeCA8PSB4KSByZXR1cm4gcmFuZ2VbYmlzZWN0UmlnaHQoZG9tYWluLCB4LCAwLCBuKV07XG4gIH1cblxuICBmdW5jdGlvbiByZXNjYWxlKCkge1xuICAgIHZhciBpID0gLTE7XG4gICAgZG9tYWluID0gbmV3IEFycmF5KG4pO1xuICAgIHdoaWxlICgrK2kgPCBuKSBkb21haW5baV0gPSAoKGkgKyAxKSAqIHgxIC0gKGkgLSBuKSAqIHgwKSAvIChuICsgMSk7XG4gICAgcmV0dXJuIHNjYWxlO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHgwID0gK19bMF0sIHgxID0gK19bMV0sIHJlc2NhbGUoKSkgOiBbeDAsIHgxXTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChuID0gKHJhbmdlID0gc2xpY2UkMi5jYWxsKF8pKS5sZW5ndGggLSAxLCByZXNjYWxlKCkpIDogcmFuZ2Uuc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5pbnZlcnRFeHRlbnQgPSBmdW5jdGlvbih5KSB7XG4gICAgdmFyIGkgPSByYW5nZS5pbmRleE9mKHkpO1xuICAgIHJldHVybiBpIDwgMCA/IFtOYU4sIE5hTl1cbiAgICAgICAgOiBpIDwgMSA/IFt4MCwgZG9tYWluWzBdXVxuICAgICAgICA6IGkgPj0gbiA/IFtkb21haW5bbiAtIDFdLCB4MV1cbiAgICAgICAgOiBbZG9tYWluW2kgLSAxXSwgZG9tYWluW2ldXTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHF1YW50aXplJDIoKVxuICAgICAgICAuZG9tYWluKFt4MCwgeDFdKVxuICAgICAgICAucmFuZ2UocmFuZ2UpO1xuICB9O1xuXG4gIHJldHVybiBsaW5lYXJpc2goc2NhbGUpO1xufVxuXG5mdW5jdGlvbiB0aHJlc2hvbGQkMSgpIHtcbiAgdmFyIGRvbWFpbiA9IFswLjVdLFxuICAgICAgcmFuZ2UgPSBbMCwgMV0sXG4gICAgICBuID0gMTtcblxuICBmdW5jdGlvbiBzY2FsZSh4KSB7XG4gICAgaWYgKHggPD0geCkgcmV0dXJuIHJhbmdlW2Jpc2VjdFJpZ2h0KGRvbWFpbiwgeCwgMCwgbildO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRvbWFpbiA9IHNsaWNlJDIuY2FsbChfKSwgbiA9IE1hdGgubWluKGRvbWFpbi5sZW5ndGgsIHJhbmdlLmxlbmd0aCAtIDEpLCBzY2FsZSkgOiBkb21haW4uc2xpY2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChyYW5nZSA9IHNsaWNlJDIuY2FsbChfKSwgbiA9IE1hdGgubWluKGRvbWFpbi5sZW5ndGgsIHJhbmdlLmxlbmd0aCAtIDEpLCBzY2FsZSkgOiByYW5nZS5zbGljZSgpO1xuICB9O1xuXG4gIHNjYWxlLmludmVydEV4dGVudCA9IGZ1bmN0aW9uKHkpIHtcbiAgICB2YXIgaSA9IHJhbmdlLmluZGV4T2YoeSk7XG4gICAgcmV0dXJuIFtkb21haW5baSAtIDFdLCBkb21haW5baV1dO1xuICB9O1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhyZXNob2xkJDEoKVxuICAgICAgICAuZG9tYWluKGRvbWFpbilcbiAgICAgICAgLnJhbmdlKHJhbmdlKTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5cbnZhciBkdXJhdGlvblNlY29uZCQxID0gMTAwMDtcbnZhciBkdXJhdGlvbk1pbnV0ZSQxID0gZHVyYXRpb25TZWNvbmQkMSAqIDYwO1xudmFyIGR1cmF0aW9uSG91ciQxID0gZHVyYXRpb25NaW51dGUkMSAqIDYwO1xudmFyIGR1cmF0aW9uRGF5JDEgPSBkdXJhdGlvbkhvdXIkMSAqIDI0O1xudmFyIGR1cmF0aW9uV2VlayQxID0gZHVyYXRpb25EYXkkMSAqIDc7XG52YXIgZHVyYXRpb25Nb250aCA9IGR1cmF0aW9uRGF5JDEgKiAzMDtcbnZhciBkdXJhdGlvblllYXIgPSBkdXJhdGlvbkRheSQxICogMzY1O1xuXG5mdW5jdGlvbiBkYXRlJDEodCkge1xuICByZXR1cm4gbmV3IERhdGUodCk7XG59XG5cbmZ1bmN0aW9uIG51bWJlciQzKHQpIHtcbiAgcmV0dXJuIHQgaW5zdGFuY2VvZiBEYXRlID8gK3QgOiArbmV3IERhdGUoK3QpO1xufVxuXG5mdW5jdGlvbiBjYWxlbmRhcih5ZWFyJCQxLCBtb250aCQkMSwgd2VlaywgZGF5JCQxLCBob3VyJCQxLCBtaW51dGUkJDEsIHNlY29uZCQkMSwgbWlsbGlzZWNvbmQkJDEsIGZvcm1hdCkge1xuICB2YXIgc2NhbGUgPSBjb250aW51b3VzKGRlaW50ZXJwb2xhdGVMaW5lYXIsIHJlaW50ZXJwb2xhdGUpLFxuICAgICAgaW52ZXJ0ID0gc2NhbGUuaW52ZXJ0LFxuICAgICAgZG9tYWluID0gc2NhbGUuZG9tYWluO1xuXG4gIHZhciBmb3JtYXRNaWxsaXNlY29uZCA9IGZvcm1hdChcIi4lTFwiKSxcbiAgICAgIGZvcm1hdFNlY29uZCA9IGZvcm1hdChcIjolU1wiKSxcbiAgICAgIGZvcm1hdE1pbnV0ZSA9IGZvcm1hdChcIiVJOiVNXCIpLFxuICAgICAgZm9ybWF0SG91ciA9IGZvcm1hdChcIiVJICVwXCIpLFxuICAgICAgZm9ybWF0RGF5ID0gZm9ybWF0KFwiJWEgJWRcIiksXG4gICAgICBmb3JtYXRXZWVrID0gZm9ybWF0KFwiJWIgJWRcIiksXG4gICAgICBmb3JtYXRNb250aCA9IGZvcm1hdChcIiVCXCIpLFxuICAgICAgZm9ybWF0WWVhciA9IGZvcm1hdChcIiVZXCIpO1xuXG4gIHZhciB0aWNrSW50ZXJ2YWxzID0gW1xuICAgIFtzZWNvbmQkJDEsICAxLCAgICAgIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFtzZWNvbmQkJDEsICA1LCAgNSAqIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFtzZWNvbmQkJDEsIDE1LCAxNSAqIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFtzZWNvbmQkJDEsIDMwLCAzMCAqIGR1cmF0aW9uU2Vjb25kJDFdLFxuICAgIFttaW51dGUkJDEsICAxLCAgICAgIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFttaW51dGUkJDEsICA1LCAgNSAqIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFttaW51dGUkJDEsIDE1LCAxNSAqIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFttaW51dGUkJDEsIDMwLCAzMCAqIGR1cmF0aW9uTWludXRlJDFdLFxuICAgIFsgIGhvdXIkJDEsICAxLCAgICAgIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgIGhvdXIkJDEsICAzLCAgMyAqIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgIGhvdXIkJDEsICA2LCAgNiAqIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgIGhvdXIkJDEsIDEyLCAxMiAqIGR1cmF0aW9uSG91ciQxICBdLFxuICAgIFsgICBkYXkkJDEsICAxLCAgICAgIGR1cmF0aW9uRGF5JDEgICBdLFxuICAgIFsgICBkYXkkJDEsICAyLCAgMiAqIGR1cmF0aW9uRGF5JDEgICBdLFxuICAgIFsgIHdlZWssICAxLCAgICAgIGR1cmF0aW9uV2VlayQxICBdLFxuICAgIFsgbW9udGgkJDEsICAxLCAgICAgIGR1cmF0aW9uTW9udGggXSxcbiAgICBbIG1vbnRoJCQxLCAgMywgIDMgKiBkdXJhdGlvbk1vbnRoIF0sXG4gICAgWyAgeWVhciQkMSwgIDEsICAgICAgZHVyYXRpb25ZZWFyICBdXG4gIF07XG5cbiAgZnVuY3Rpb24gdGlja0Zvcm1hdChkYXRlJCQxKSB7XG4gICAgcmV0dXJuIChzZWNvbmQkJDEoZGF0ZSQkMSkgPCBkYXRlJCQxID8gZm9ybWF0TWlsbGlzZWNvbmRcbiAgICAgICAgOiBtaW51dGUkJDEoZGF0ZSQkMSkgPCBkYXRlJCQxID8gZm9ybWF0U2Vjb25kXG4gICAgICAgIDogaG91ciQkMShkYXRlJCQxKSA8IGRhdGUkJDEgPyBmb3JtYXRNaW51dGVcbiAgICAgICAgOiBkYXkkJDEoZGF0ZSQkMSkgPCBkYXRlJCQxID8gZm9ybWF0SG91clxuICAgICAgICA6IG1vbnRoJCQxKGRhdGUkJDEpIDwgZGF0ZSQkMSA/ICh3ZWVrKGRhdGUkJDEpIDwgZGF0ZSQkMSA/IGZvcm1hdERheSA6IGZvcm1hdFdlZWspXG4gICAgICAgIDogeWVhciQkMShkYXRlJCQxKSA8IGRhdGUkJDEgPyBmb3JtYXRNb250aFxuICAgICAgICA6IGZvcm1hdFllYXIpKGRhdGUkJDEpO1xuICB9XG5cbiAgZnVuY3Rpb24gdGlja0ludGVydmFsKGludGVydmFsLCBzdGFydCwgc3RvcCwgc3RlcCkge1xuICAgIGlmIChpbnRlcnZhbCA9PSBudWxsKSBpbnRlcnZhbCA9IDEwO1xuXG4gICAgLy8gSWYgYSBkZXNpcmVkIHRpY2sgY291bnQgaXMgc3BlY2lmaWVkLCBwaWNrIGEgcmVhc29uYWJsZSB0aWNrIGludGVydmFsXG4gICAgLy8gYmFzZWQgb24gdGhlIGV4dGVudCBvZiB0aGUgZG9tYWluIGFuZCBhIHJvdWdoIGVzdGltYXRlIG9mIHRpY2sgc2l6ZS5cbiAgICAvLyBPdGhlcndpc2UsIGFzc3VtZSBpbnRlcnZhbCBpcyBhbHJlYWR5IGEgdGltZSBpbnRlcnZhbCBhbmQgdXNlIGl0LlxuICAgIGlmICh0eXBlb2YgaW50ZXJ2YWwgPT09IFwibnVtYmVyXCIpIHtcbiAgICAgIHZhciB0YXJnZXQgPSBNYXRoLmFicyhzdG9wIC0gc3RhcnQpIC8gaW50ZXJ2YWwsXG4gICAgICAgICAgaSA9IGJpc2VjdG9yKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIGlbMl07IH0pLnJpZ2h0KHRpY2tJbnRlcnZhbHMsIHRhcmdldCk7XG4gICAgICBpZiAoaSA9PT0gdGlja0ludGVydmFscy5sZW5ndGgpIHtcbiAgICAgICAgc3RlcCA9IHRpY2tTdGVwKHN0YXJ0IC8gZHVyYXRpb25ZZWFyLCBzdG9wIC8gZHVyYXRpb25ZZWFyLCBpbnRlcnZhbCk7XG4gICAgICAgIGludGVydmFsID0geWVhciQkMTtcbiAgICAgIH0gZWxzZSBpZiAoaSkge1xuICAgICAgICBpID0gdGlja0ludGVydmFsc1t0YXJnZXQgLyB0aWNrSW50ZXJ2YWxzW2kgLSAxXVsyXSA8IHRpY2tJbnRlcnZhbHNbaV1bMl0gLyB0YXJnZXQgPyBpIC0gMSA6IGldO1xuICAgICAgICBzdGVwID0gaVsxXTtcbiAgICAgICAgaW50ZXJ2YWwgPSBpWzBdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgc3RlcCA9IE1hdGgubWF4KHRpY2tTdGVwKHN0YXJ0LCBzdG9wLCBpbnRlcnZhbCksIDEpO1xuICAgICAgICBpbnRlcnZhbCA9IG1pbGxpc2Vjb25kJCQxO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBzdGVwID09IG51bGwgPyBpbnRlcnZhbCA6IGludGVydmFsLmV2ZXJ5KHN0ZXApO1xuICB9XG5cbiAgc2NhbGUuaW52ZXJ0ID0gZnVuY3Rpb24oeSkge1xuICAgIHJldHVybiBuZXcgRGF0ZShpbnZlcnQoeSkpO1xuICB9O1xuXG4gIHNjYWxlLmRvbWFpbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGRvbWFpbihtYXAkMy5jYWxsKF8sIG51bWJlciQzKSkgOiBkb21haW4oKS5tYXAoZGF0ZSQxKTtcbiAgfTtcblxuICBzY2FsZS50aWNrcyA9IGZ1bmN0aW9uKGludGVydmFsLCBzdGVwKSB7XG4gICAgdmFyIGQgPSBkb21haW4oKSxcbiAgICAgICAgdDAgPSBkWzBdLFxuICAgICAgICB0MSA9IGRbZC5sZW5ndGggLSAxXSxcbiAgICAgICAgciA9IHQxIDwgdDAsXG4gICAgICAgIHQ7XG4gICAgaWYgKHIpIHQgPSB0MCwgdDAgPSB0MSwgdDEgPSB0O1xuICAgIHQgPSB0aWNrSW50ZXJ2YWwoaW50ZXJ2YWwsIHQwLCB0MSwgc3RlcCk7XG4gICAgdCA9IHQgPyB0LnJhbmdlKHQwLCB0MSArIDEpIDogW107IC8vIGluY2x1c2l2ZSBzdG9wXG4gICAgcmV0dXJuIHIgPyB0LnJldmVyc2UoKSA6IHQ7XG4gIH07XG5cbiAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICByZXR1cm4gc3BlY2lmaWVyID09IG51bGwgPyB0aWNrRm9ybWF0IDogZm9ybWF0KHNwZWNpZmllcik7XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKGludGVydmFsLCBzdGVwKSB7XG4gICAgdmFyIGQgPSBkb21haW4oKTtcbiAgICByZXR1cm4gKGludGVydmFsID0gdGlja0ludGVydmFsKGludGVydmFsLCBkWzBdLCBkW2QubGVuZ3RoIC0gMV0sIHN0ZXApKVxuICAgICAgICA/IGRvbWFpbihuaWNlKGQsIGludGVydmFsKSlcbiAgICAgICAgOiBzY2FsZTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGNvcHkoc2NhbGUsIGNhbGVuZGFyKHllYXIkJDEsIG1vbnRoJCQxLCB3ZWVrLCBkYXkkJDEsIGhvdXIkJDEsIG1pbnV0ZSQkMSwgc2Vjb25kJCQxLCBtaWxsaXNlY29uZCQkMSwgZm9ybWF0KSk7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG52YXIgdGltZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY2FsZW5kYXIoeWVhciwgbW9udGgsIHN1bmRheSwgZGF5LCBob3VyLCBtaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmQsIHRpbWVGb3JtYXQpLmRvbWFpbihbbmV3IERhdGUoMjAwMCwgMCwgMSksIG5ldyBEYXRlKDIwMDAsIDAsIDIpXSk7XG59O1xuXG52YXIgdXRjVGltZSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY2FsZW5kYXIodXRjWWVhciwgdXRjTW9udGgsIHV0Y1N1bmRheSwgdXRjRGF5LCB1dGNIb3VyLCB1dGNNaW51dGUsIHNlY29uZCwgbWlsbGlzZWNvbmQsIHV0Y0Zvcm1hdCkuZG9tYWluKFtEYXRlLlVUQygyMDAwLCAwLCAxKSwgRGF0ZS5VVEMoMjAwMCwgMCwgMildKTtcbn07XG5cbmZ1bmN0aW9uIGJhbmQkJDEoKSB7XG4gIHZhciBzY2FsZSA9IG9yZGluYWwoKS51bmtub3duKHVuZGVmaW5lZCksXG4gICAgICBkb21haW4gPSBzY2FsZS5kb21haW4sXG4gICAgICBvcmRpbmFsUmFuZ2UgPSBzY2FsZS5yYW5nZSxcbiAgICAgIHJhbmdlID0gWzAsIDFdLFxuICAgICAgc3RlcCxcbiAgICAgIGJhbmR3aWR0aCxcbiAgICAgIHJvdW5kID0gZmFsc2UsXG4gICAgICBwYWRkaW5nSW5uZXIgPSAwLFxuICAgICAgcGFkZGluZ091dGVyID0gMCxcbiAgICAgIGFsaWduID0gMC41O1xuXG4gIGRlbGV0ZSBzY2FsZS51bmtub3duO1xuXG4gIGZ1bmN0aW9uIHJlc2NhbGUoKSB7XG4gICAgdmFyIG4gPSBkb21haW4oKS5sZW5ndGgsXG4gICAgICAgIHJldmVyc2UgPSByYW5nZVsxXSA8IHJhbmdlWzBdLFxuICAgICAgICBzdGFydCA9IHJhbmdlW3JldmVyc2UgLSAwXSxcbiAgICAgICAgc3RvcCA9IHJhbmdlWzEgLSByZXZlcnNlXSxcbiAgICAgICAgc3BhY2UgPSBiYW5kU3BhY2UobiwgcGFkZGluZ0lubmVyLCBwYWRkaW5nT3V0ZXIpO1xuXG4gICAgc3RlcCA9IChzdG9wIC0gc3RhcnQpIC8gKHNwYWNlIHx8IDEpO1xuICAgIGlmIChyb3VuZCkge1xuICAgICAgc3RlcCA9IE1hdGguZmxvb3Ioc3RlcCk7XG4gICAgfVxuICAgIHN0YXJ0ICs9IChzdG9wIC0gc3RhcnQgLSBzdGVwICogKG4gLSBwYWRkaW5nSW5uZXIpKSAqIGFsaWduO1xuICAgIGJhbmR3aWR0aCA9IHN0ZXAgKiAoMSAtIHBhZGRpbmdJbm5lcik7XG4gICAgaWYgKHJvdW5kKSB7XG4gICAgICBzdGFydCA9IE1hdGgucm91bmQoc3RhcnQpO1xuICAgICAgYmFuZHdpZHRoID0gTWF0aC5yb3VuZChiYW5kd2lkdGgpO1xuICAgIH1cbiAgICB2YXIgdmFsdWVzID0gc2VxdWVuY2UobikubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIHN0YXJ0ICsgc3RlcCAqIGk7IH0pO1xuICAgIHJldHVybiBvcmRpbmFsUmFuZ2UocmV2ZXJzZSA/IHZhbHVlcy5yZXZlcnNlKCkgOiB2YWx1ZXMpO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBkb21haW4oXyk7XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gZG9tYWluKCk7XG4gICAgfVxuICB9O1xuXG4gIHNjYWxlLnJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICByYW5nZSA9IFsrX1swXSwgK19bMV1dO1xuICAgICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHJhbmdlLnNsaWNlKCk7XG4gICAgfVxuICB9O1xuXG4gIHNjYWxlLnJhbmdlUm91bmQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmFuZ2UgPSBbK19bMF0sICtfWzFdXTtcbiAgICByb3VuZCA9IHRydWU7XG4gICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgfTtcblxuICBzY2FsZS5iYW5kd2lkdGggPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gYmFuZHdpZHRoO1xuICB9O1xuXG4gIHNjYWxlLnN0ZXAgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gc3RlcDtcbiAgfTtcblxuICBzY2FsZS5yb3VuZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgcm91bmQgPSAhIV87XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcm91bmQ7XG4gICAgfVxuICB9O1xuXG4gIHNjYWxlLnBhZGRpbmcgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHBhZGRpbmdPdXRlciA9IE1hdGgubWF4KDAsIE1hdGgubWluKDEsIF8pKTtcbiAgICAgIHBhZGRpbmdJbm5lciA9IHBhZGRpbmdPdXRlcjtcbiAgICAgIHJldHVybiByZXNjYWxlKCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYWRkaW5nSW5uZXI7XG4gICAgfVxuICB9O1xuXG4gIHNjYWxlLnBhZGRpbmdJbm5lciA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgcGFkZGluZ0lubmVyID0gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgXykpO1xuICAgICAgcmV0dXJuIHJlc2NhbGUoKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHBhZGRpbmdJbm5lcjtcbiAgICB9XG4gIH07XG5cbiAgc2NhbGUucGFkZGluZ091dGVyID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBwYWRkaW5nT3V0ZXIgPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBfKSk7XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcGFkZGluZ091dGVyO1xuICAgIH1cbiAgfTtcblxuICBzY2FsZS5hbGlnbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgYWxpZ24gPSBNYXRoLm1heCgwLCBNYXRoLm1pbigxLCBfKSk7XG4gICAgICByZXR1cm4gcmVzY2FsZSgpO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gYWxpZ247XG4gICAgfVxuICB9O1xuXG4gIHNjYWxlLmludmVydFJhbmdlID0gZnVuY3Rpb24oXykge1xuICAgIC8vIGJhaWwgaWYgcmFuZ2UgaGFzIG51bGwgb3IgdW5kZWZpbmVkIHZhbHVlc1xuICAgIGlmIChfWzBdID09IG51bGwgfHwgX1sxXSA9PSBudWxsKSByZXR1cm47XG5cbiAgICB2YXIgbG8gPSArX1swXSxcbiAgICAgICAgaGkgPSArX1sxXSxcbiAgICAgICAgcmV2ZXJzZSA9IHJhbmdlWzFdIDwgcmFuZ2VbMF0sXG4gICAgICAgIHZhbHVlcyA9IHJldmVyc2UgPyBvcmRpbmFsUmFuZ2UoKS5yZXZlcnNlKCkgOiBvcmRpbmFsUmFuZ2UoKSxcbiAgICAgICAgbiA9IHZhbHVlcy5sZW5ndGggLSAxLCBhLCBiLCB0O1xuXG4gICAgLy8gYmFpbCBpZiBlaXRoZXIgcmFuZ2UgZW5kcG9pbnQgaXMgaW52YWxpZFxuICAgIGlmIChsbyAhPT0gbG8gfHwgaGkgIT09IGhpKSByZXR1cm47XG5cbiAgICAvLyBvcmRlciByYW5nZSBpbnB1dHMsIGJhaWwgaWYgb3V0c2lkZSBvZiBzY2FsZSByYW5nZVxuICAgIGlmIChoaSA8IGxvKSB7XG4gICAgICB0ID0gbG87XG4gICAgICBsbyA9IGhpO1xuICAgICAgaGkgPSB0O1xuICAgIH1cbiAgICBpZiAoaGkgPCB2YWx1ZXNbMF0gfHwgbG8gPiByYW5nZVsxLXJldmVyc2VdKSByZXR1cm47XG5cbiAgICAvLyBiaW5hcnkgc2VhcmNoIHRvIGluZGV4IGludG8gc2NhbGUgcmFuZ2VcbiAgICBhID0gTWF0aC5tYXgoMCwgYmlzZWN0UmlnaHQodmFsdWVzLCBsbykgLSAxKTtcbiAgICBiID0gbG89PT1oaSA/IGEgOiBiaXNlY3RSaWdodCh2YWx1ZXMsIGhpKSAtIDE7XG5cbiAgICAvLyBpbmNyZW1lbnQgaW5kZXggYSBpZiBsbyBpcyB3aXRoaW4gcGFkZGluZyBnYXBcbiAgICBpZiAobG8gLSB2YWx1ZXNbYV0gPiBiYW5kd2lkdGggKyAxZS0xMCkgKythO1xuXG4gICAgaWYgKHJldmVyc2UpIHtcbiAgICAgIC8vIG1hcCArIHN3YXBcbiAgICAgIHQgPSBhO1xuICAgICAgYSA9IG4gLSBiO1xuICAgICAgYiA9IG4gLSB0O1xuICAgIH1cbiAgICByZXR1cm4gKGEgPiBiKSA/IHVuZGVmaW5lZCA6IGRvbWFpbigpLnNsaWNlKGEsIGIrMSk7XG4gIH07XG5cbiAgc2NhbGUuaW52ZXJ0ID0gZnVuY3Rpb24oXykge1xuICAgIHZhciB2YWx1ZSA9IHNjYWxlLmludmVydFJhbmdlKFtfLCBfXSk7XG4gICAgcmV0dXJuIHZhbHVlID8gdmFsdWVbMF0gOiB2YWx1ZTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGJhbmQkJDEoKVxuICAgICAgICAuZG9tYWluKGRvbWFpbigpKVxuICAgICAgICAucmFuZ2UocmFuZ2UpXG4gICAgICAgIC5yb3VuZChyb3VuZClcbiAgICAgICAgLnBhZGRpbmdJbm5lcihwYWRkaW5nSW5uZXIpXG4gICAgICAgIC5wYWRkaW5nT3V0ZXIocGFkZGluZ091dGVyKVxuICAgICAgICAuYWxpZ24oYWxpZ24pO1xuICB9O1xuXG4gIHJldHVybiByZXNjYWxlKCk7XG59XG5cbmZ1bmN0aW9uIHBvaW50aXNoKHNjYWxlKSB7XG4gIHZhciBjb3B5ID0gc2NhbGUuY29weTtcblxuICBzY2FsZS5wYWRkaW5nID0gc2NhbGUucGFkZGluZ091dGVyO1xuICBkZWxldGUgc2NhbGUucGFkZGluZ0lubmVyO1xuXG4gIHNjYWxlLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gcG9pbnRpc2goY29weSgpKTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5cbmZ1bmN0aW9uIHBvaW50JDUoKSB7XG4gIHJldHVybiBwb2ludGlzaChiYW5kJCQxKCkucGFkZGluZ0lubmVyKDEpKTtcbn1cblxudmFyIG1hcCQ0ID0gQXJyYXkucHJvdG90eXBlLm1hcDtcbnZhciBzbGljZSQzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG5mdW5jdGlvbiBudW1iZXJzJDEoXykge1xuICByZXR1cm4gbWFwJDQuY2FsbChfLCBmdW5jdGlvbih4KSB7IHJldHVybiAreDsgfSk7XG59XG5cbmZ1bmN0aW9uIGJpbkxpbmVhcigpIHtcbiAgdmFyIGxpbmVhciQkMSA9IGxpbmVhcigpLFxuICAgICAgZG9tYWluID0gW107XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHJldHVybiBsaW5lYXIkJDEoeCk7XG4gIH1cblxuICBmdW5jdGlvbiBzZXREb21haW4oXykge1xuICAgIGRvbWFpbiA9IG51bWJlcnMkMShfKTtcbiAgICBsaW5lYXIkJDEuZG9tYWluKFtkb21haW5bMF0sIHBlZWsoZG9tYWluKV0pO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNldERvbWFpbihfKSwgc2NhbGUpIDogZG9tYWluLnNsaWNlKCk7XG4gIH07XG5cbiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAobGluZWFyJCQxLnJhbmdlKF8pLCBzY2FsZSkgOiBsaW5lYXIkJDEucmFuZ2UoKTtcbiAgfTtcblxuICBzY2FsZS5yYW5nZVJvdW5kID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGxpbmVhciQkMS5yYW5nZVJvdW5kKF8pLCBzY2FsZSkgOiBsaW5lYXIkJDEucmFuZ2VSb3VuZCgpO1xuICB9O1xuXG4gIHNjYWxlLmludGVycG9sYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGxpbmVhciQkMS5pbnRlcnBvbGF0ZShfKSwgc2NhbGUpIDogbGluZWFyJCQxLmludGVycG9sYXRlKCk7XG4gIH07XG5cbiAgc2NhbGUuaW52ZXJ0ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBsaW5lYXIkJDEuaW52ZXJ0KF8pO1xuICB9O1xuXG4gIHNjYWxlLnRpY2tzID0gZnVuY3Rpb24oY291bnQpIHtcbiAgICB2YXIgbiA9IGRvbWFpbi5sZW5ndGgsXG4gICAgICAgIHN0cmlkZSA9IH5+KG4gLyAoY291bnQgfHwgbikpO1xuXG4gICAgcmV0dXJuIHN0cmlkZSA8IDJcbiAgICAgID8gc2NhbGUuZG9tYWluKClcbiAgICAgIDogZG9tYWluLmZpbHRlcihmdW5jdGlvbih4LCBpKSB7IHJldHVybiAhKGkgJSBzdHJpZGUpOyB9KTtcbiAgfTtcblxuICBzY2FsZS50aWNrRm9ybWF0ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGxpbmVhciQkMS50aWNrRm9ybWF0LmFwcGx5KGxpbmVhciQkMSwgYXJndW1lbnRzKTtcbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIGJpbkxpbmVhcigpLmRvbWFpbihzY2FsZS5kb21haW4oKSkucmFuZ2Uoc2NhbGUucmFuZ2UoKSk7XG4gIH07XG5cbiAgcmV0dXJuIHNjYWxlO1xufVxuXG5mdW5jdGlvbiBiaW5PcmRpbmFsKCkge1xuICB2YXIgZG9tYWluID0gW10sXG4gICAgICByYW5nZSA9IFtdO1xuXG4gIGZ1bmN0aW9uIHNjYWxlKHgpIHtcbiAgICByZXR1cm4geCA9PSBudWxsIHx8IHggIT09IHhcbiAgICAgID8gdW5kZWZpbmVkXG4gICAgICA6IHJhbmdlWyhiaXNlY3RSaWdodChkb21haW4sIHgpIC0gMSkgJSByYW5nZS5sZW5ndGhdO1xuICB9XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBkb21haW4gPSBudW1iZXJzJDEoXyk7XG4gICAgICByZXR1cm4gc2NhbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBkb21haW4uc2xpY2UoKTtcbiAgICB9XG4gIH07XG5cbiAgc2NhbGUucmFuZ2UgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJhbmdlID0gc2xpY2UkMy5jYWxsKF8pO1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcmFuZ2Uuc2xpY2UoKTtcbiAgICB9XG4gIH07XG5cbiAgc2NhbGUuY29weSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBiaW5PcmRpbmFsKCkuZG9tYWluKHNjYWxlLmRvbWFpbigpKS5yYW5nZShzY2FsZS5yYW5nZSgpKTtcbiAgfTtcblxuICByZXR1cm4gc2NhbGU7XG59XG5cbmZ1bmN0aW9uIHNlcXVlbnRpYWwkMShpbnRlcnBvbGF0b3IpIHtcbiAgdmFyIGxpbmVhciQkMSA9IGxpbmVhcigpLFxuICAgICAgeDAgPSAwLFxuICAgICAgZHggPSAxLFxuICAgICAgY2xhbXAgPSBmYWxzZTtcblxuICBmdW5jdGlvbiB1cGRhdGUoKSB7XG4gICAgdmFyIGRvbWFpbiA9IGxpbmVhciQkMS5kb21haW4oKTtcbiAgICB4MCA9IGRvbWFpblswXTtcbiAgICBkeCA9IHBlZWsoZG9tYWluKSAtIHgwO1xuICB9XG5cbiAgZnVuY3Rpb24gc2NhbGUoeCkge1xuICAgIHZhciB0ID0gKHggLSB4MCkgLyBkeDtcbiAgICByZXR1cm4gaW50ZXJwb2xhdG9yKGNsYW1wID8gTWF0aC5tYXgoMCwgTWF0aC5taW4oMSwgdCkpIDogdCk7XG4gIH1cblxuICBzY2FsZS5jbGFtcCA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgY2xhbXAgPSAhIV87XG4gICAgICByZXR1cm4gc2NhbGU7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBjbGFtcDtcbiAgICB9XG4gIH07XG5cbiAgc2NhbGUuZG9tYWluID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGxpbmVhciQkMS5kb21haW4oXyksIHVwZGF0ZSgpLCBzY2FsZSkgOiBsaW5lYXIkJDEuZG9tYWluKCk7XG4gIH07XG5cbiAgc2NhbGUuaW50ZXJwb2xhdG9yID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBpbnRlcnBvbGF0b3IgPSBfO1xuICAgICAgcmV0dXJuIHNjYWxlO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gaW50ZXJwb2xhdG9yO1xuICAgIH1cbiAgfTtcblxuICBzY2FsZS5jb3B5ID0gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHNlcXVlbnRpYWwkMSgpLmRvbWFpbihsaW5lYXIkJDEuZG9tYWluKCkpLmNsYW1wKGNsYW1wKS5pbnRlcnBvbGF0b3IoaW50ZXJwb2xhdG9yKTtcbiAgfTtcblxuICBzY2FsZS50aWNrcyA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgcmV0dXJuIGxpbmVhciQkMS50aWNrcyhjb3VudCk7XG4gIH07XG5cbiAgc2NhbGUudGlja0Zvcm1hdCA9IGZ1bmN0aW9uKGNvdW50LCBzcGVjaWZpZXIpIHtcbiAgICByZXR1cm4gbGluZWFyJCQxLnRpY2tGb3JtYXQoY291bnQsIHNwZWNpZmllcik7XG4gIH07XG5cbiAgc2NhbGUubmljZSA9IGZ1bmN0aW9uKGNvdW50KSB7XG4gICAgcmV0dXJuIGxpbmVhciQkMS5uaWNlKGNvdW50KSwgdXBkYXRlKCksIHNjYWxlO1xuICB9O1xuXG4gIHJldHVybiBzY2FsZTtcbn1cblxuLyoqXG4gKiBBdWdtZW50IHNjYWxlcyB3aXRoIHRoZWlyIHR5cGUgYW5kIG5lZWRlZCBpbnZlcnNlIG1ldGhvZHMuXG4gKi9cbmZ1bmN0aW9uIGNyZWF0ZSh0eXBlLCBjb25zdHJ1Y3Rvcikge1xuICByZXR1cm4gZnVuY3Rpb24gc2NhbGUoKSB7XG4gICAgdmFyIHMgPSBjb25zdHJ1Y3RvcigpO1xuXG4gICAgaWYgKCFzLmludmVydFJhbmdlKSB7XG4gICAgICBzLmludmVydFJhbmdlID0gcy5pbnZlcnQgPyBpbnZlcnRSYW5nZShzKVxuICAgICAgICA6IHMuaW52ZXJ0RXh0ZW50ID8gaW52ZXJ0UmFuZ2VFeHRlbnQocylcbiAgICAgICAgOiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcy50eXBlID0gdHlwZTtcbiAgICByZXR1cm4gcztcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2NhbGUkMSh0eXBlLCBzY2FsZSkge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICBzY2FsZXNbdHlwZV0gPSBjcmVhdGUodHlwZSwgc2NhbGUpO1xuICAgIHJldHVybiB0aGlzO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBzY2FsZXMuaGFzT3duUHJvcGVydHkodHlwZSkgPyBzY2FsZXNbdHlwZV0gOiB1bmRlZmluZWQ7XG4gIH1cbn1cblxudmFyIHNjYWxlcyA9IHtcbiAgLy8gYmFzZSBzY2FsZSB0eXBlc1xuICBpZGVudGl0eTogICAgICBpZGVudGl0eSQ0LFxuICBsaW5lYXI6ICAgICAgICBsaW5lYXIsXG4gIGxvZzogICAgICAgICAgIGxvZyQyLFxuICBvcmRpbmFsOiAgICAgICBvcmRpbmFsLFxuICBwb3c6ICAgICAgICAgICBwb3ckMSxcbiAgc3FydDogICAgICAgICAgc3FydCQxLFxuICBxdWFudGlsZTogICAgICBxdWFudGlsZSxcbiAgcXVhbnRpemU6ICAgICAgcXVhbnRpemUkMixcbiAgdGhyZXNob2xkOiAgICAgdGhyZXNob2xkJDEsXG4gIHRpbWU6ICAgICAgICAgIHRpbWUsXG4gIHV0YzogICAgICAgICAgIHV0Y1RpbWUsXG5cbiAgLy8gZXh0ZW5kZWQgc2NhbGUgdHlwZXNcbiAgYmFuZDogICAgICAgICAgYmFuZCQkMSxcbiAgcG9pbnQ6ICAgICAgICAgcG9pbnQkNSxcbiAgc2VxdWVudGlhbDogICAgc2VxdWVudGlhbCQxLFxuICAnYmluLWxpbmVhcic6ICBiaW5MaW5lYXIsXG4gICdiaW4tb3JkaW5hbCc6IGJpbk9yZGluYWxcbn07XG5cbmZvciAodmFyIGtleSQxIGluIHNjYWxlcykge1xuICBzY2FsZSQxKGtleSQxLCBzY2FsZXNba2V5JDFdKTtcbn1cblxuZnVuY3Rpb24gY29sb3JzKHNwZWNpZmllcikge1xuICB2YXIgbiA9IHNwZWNpZmllci5sZW5ndGggLyA2IHwgMCwgY29sb3JzID0gbmV3IEFycmF5KG4pLCBpID0gMDtcbiAgd2hpbGUgKGkgPCBuKSBjb2xvcnNbaV0gPSBcIiNcIiArIHNwZWNpZmllci5zbGljZShpICogNiwgKytpICogNik7XG4gIHJldHVybiBjb2xvcnM7XG59XG5cbnZhciBjYXRlZ29yeTIwID0gY29sb3JzKFxuICAnMWY3N2I0YWVjN2U4ZmY3ZjBlZmZiYjc4MmNhMDJjOThkZjhhZDYyNzI4ZmY5ODk2OTQ2N2JkYzViMGQ1OGM1NjRiYzQ5Yzk0ZTM3N2MyZjdiNmQyN2Y3ZjdmYzdjN2M3YmNiZDIyZGJkYjhkMTdiZWNmOWVkYWU1J1xuKTtcblxudmFyIGNhdGVnb3J5MjBiID0gY29sb3JzKFxuICAnMzkzYjc5NTI1NGEzNmI2ZWNmOWM5ZWRlNjM3OTM5OGNhMjUyYjVjZjZiY2VkYjljOGM2ZDMxYmQ5ZTM5ZTdiYTUyZTdjYjk0ODQzYzM5YWQ0OTRhZDY2MTZiZTc5NjljN2I0MTczYTU1MTk0Y2U2ZGJkZGU5ZWQ2J1xuKTtcblxudmFyIGNhdGVnb3J5MjBjID0gY29sb3JzKFxuICAnMzE4MmJkNmJhZWQ2OWVjYWUxYzZkYmVmZTY1NTBkZmQ4ZDNjZmRhZTZiZmRkMGEyMzFhMzU0NzRjNDc2YTFkOTliYzdlOWMwNzU2YmIxOWU5YWM4YmNiZGRjZGFkYWViNjM2MzYzOTY5Njk2YmRiZGJkZDlkOWQ5J1xuKTtcblxudmFyIHRhYmxlYXUxMCA9IGNvbG9ycyhcbiAgJzRjNzhhOGY1ODUxOGU0NTc1NjcyYjdiMjU0YTI0YmVlY2EzYmIyNzlhMmZmOWRhNjlkNzU1ZGJhYjBhYydcbik7XG5cbnZhciB0YWJsZWF1MjAgPSBjb2xvcnMoXG4gICc0Yzc4YTg5ZWNhZTlmNTg1MThmZmJmNzk1NGEyNGI4OGQyN2FiNzlhMjBmMmNmNWI0Mzk4OTQ4M2JjYjZlNDU3NTZmZjlkOTg3OTcwNmViYWIwYWNkNjcxOTVmY2JmZDJiMjc5YTJkNmE1Yzk5ZTc2NWZkOGI1YTUnXG4pO1xuXG52YXIgYmx1ZU9yYW5nZSA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiNjdhOWNmZjdmN2Y3ZjFhMzQwXCIsXG4gIFwiMDU3MWIwOTJjNWRlZmRiODYzZTY2MTAxXCIsXG4gIFwiMDU3MWIwOTJjNWRlZjdmN2Y3ZmRiODYzZTY2MTAxXCIsXG4gIFwiMjE2NmFjNjdhOWNmZDFlNWYwZmVlMGI2ZjFhMzQwYjM1ODA2XCIsXG4gIFwiMjE2NmFjNjdhOWNmZDFlNWYwZjdmN2Y3ZmVlMGI2ZjFhMzQwYjM1ODA2XCIsXG4gIFwiMjE2NmFjNDM5M2MzOTJjNWRlZDFlNWYwZmVlMGI2ZmRiODYzZTA4MjE0YjM1ODA2XCIsXG4gIFwiMjE2NmFjNDM5M2MzOTJjNWRlZDFlNWYwZjdmN2Y3ZmVlMGI2ZmRiODYzZTA4MjE0YjM1ODA2XCIsXG4gIFwiMDUzMDYxMjE2NmFjNDM5M2MzOTJjNWRlZDFlNWYwZmVlMGI2ZmRiODYzZTA4MjE0YjM1ODA2N2YzYjA4XCIsXG4gIFwiMDUzMDYxMjE2NmFjNDM5M2MzOTJjNWRlZDFlNWYwZjdmN2Y3ZmVlMGI2ZmRiODYzZTA4MjE0YjM1ODA2N2YzYjA4XCJcbikubWFwKGNvbG9ycyk7XG5cbnZhciBjb2xvcnMkMSA9IGZ1bmN0aW9uKHNwZWNpZmllcikge1xuICB2YXIgbiA9IHNwZWNpZmllci5sZW5ndGggLyA2IHwgMCwgY29sb3JzID0gbmV3IEFycmF5KG4pLCBpID0gMDtcbiAgd2hpbGUgKGkgPCBuKSBjb2xvcnNbaV0gPSBcIiNcIiArIHNwZWNpZmllci5zbGljZShpICogNiwgKytpICogNik7XG4gIHJldHVybiBjb2xvcnM7XG59O1xuXG52YXIgY2F0ZWdvcnkxMCA9IGNvbG9ycyQxKFwiMWY3N2I0ZmY3ZjBlMmNhMDJjZDYyNzI4OTQ2N2JkOGM1NjRiZTM3N2MyN2Y3ZjdmYmNiZDIyMTdiZWNmXCIpO1xuXG52YXIgQWNjZW50ID0gY29sb3JzJDEoXCI3ZmM5N2ZiZWFlZDRmZGMwODZmZmZmOTkzODZjYjBmMDAyN2ZiZjViMTc2NjY2NjZcIik7XG5cbnZhciBEYXJrMiA9IGNvbG9ycyQxKFwiMWI5ZTc3ZDk1ZjAyNzU3MGIzZTcyOThhNjZhNjFlZTZhYjAyYTY3NjFkNjY2NjY2XCIpO1xuXG52YXIgUGFpcmVkID0gY29sb3JzJDEoXCJhNmNlZTMxZjc4YjRiMmRmOGEzM2EwMmNmYjlhOTllMzFhMWNmZGJmNmZmZjdmMDBjYWIyZDY2YTNkOWFmZmZmOTliMTU5MjhcIik7XG5cbnZhciBQYXN0ZWwxID0gY29sb3JzJDEoXCJmYmI0YWViM2NkZTNjY2ViYzVkZWNiZTRmZWQ5YTZmZmZmY2NlNWQ4YmRmZGRhZWNmMmYyZjJcIik7XG5cbnZhciBQYXN0ZWwyID0gY29sb3JzJDEoXCJiM2UyY2RmZGNkYWNjYmQ1ZThmNGNhZTRlNmY1YzlmZmYyYWVmMWUyY2NjY2NjY2NcIik7XG5cbnZhciBTZXQxID0gY29sb3JzJDEoXCJlNDFhMWMzNzdlYjg0ZGFmNGE5ODRlYTNmZjdmMDBmZmZmMzNhNjU2MjhmNzgxYmY5OTk5OTlcIik7XG5cbnZhciBTZXQyID0gY29sb3JzJDEoXCI2NmMyYTVmYzhkNjI4ZGEwY2JlNzhhYzNhNmQ4NTRmZmQ5MmZlNWM0OTRiM2IzYjNcIik7XG5cbnZhciBTZXQzID0gY29sb3JzJDEoXCI4ZGQzYzdmZmZmYjNiZWJhZGFmYjgwNzI4MGIxZDNmZGI0NjJiM2RlNjlmY2NkZTVkOWQ5ZDliYzgwYmRjY2ViYzVmZmVkNmZcIik7XG5cbnZhciByYW1wID0gZnVuY3Rpb24oc2NoZW1lKSB7XG4gIHJldHVybiByZ2JCYXNpcyhzY2hlbWVbc2NoZW1lLmxlbmd0aCAtIDFdKTtcbn07XG5cbnZhciBzY2hlbWUgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImQ4YjM2NWY1ZjVmNTVhYjRhY1wiLFxuICBcImE2NjExYWRmYzI3ZDgwY2RjMTAxODU3MVwiLFxuICBcImE2NjExYWRmYzI3ZGY1ZjVmNTgwY2RjMTAxODU3MVwiLFxuICBcIjhjNTEwYWQ4YjM2NWY2ZThjM2M3ZWFlNTVhYjRhYzAxNjY1ZVwiLFxuICBcIjhjNTEwYWQ4YjM2NWY2ZThjM2Y1ZjVmNWM3ZWFlNTVhYjRhYzAxNjY1ZVwiLFxuICBcIjhjNTEwYWJmODEyZGRmYzI3ZGY2ZThjM2M3ZWFlNTgwY2RjMTM1OTc4ZjAxNjY1ZVwiLFxuICBcIjhjNTEwYWJmODEyZGRmYzI3ZGY2ZThjM2Y1ZjVmNWM3ZWFlNTgwY2RjMTM1OTc4ZjAxNjY1ZVwiLFxuICBcIjU0MzAwNThjNTEwYWJmODEyZGRmYzI3ZGY2ZThjM2M3ZWFlNTgwY2RjMTM1OTc4ZjAxNjY1ZTAwM2MzMFwiLFxuICBcIjU0MzAwNThjNTEwYWJmODEyZGRmYzI3ZGY2ZThjM2Y1ZjVmNWM3ZWFlNTgwY2RjMTM1OTc4ZjAxNjY1ZTAwM2MzMFwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBCckJHID0gcmFtcChzY2hlbWUpO1xuXG52YXIgc2NoZW1lJDEgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImFmOGRjM2Y3ZjdmNzdmYmY3YlwiLFxuICBcIjdiMzI5NGMyYTVjZmE2ZGJhMDAwODgzN1wiLFxuICBcIjdiMzI5NGMyYTVjZmY3ZjdmN2E2ZGJhMDAwODgzN1wiLFxuICBcIjc2MmE4M2FmOGRjM2U3ZDRlOGQ5ZjBkMzdmYmY3YjFiNzgzN1wiLFxuICBcIjc2MmE4M2FmOGRjM2U3ZDRlOGY3ZjdmN2Q5ZjBkMzdmYmY3YjFiNzgzN1wiLFxuICBcIjc2MmE4Mzk5NzBhYmMyYTVjZmU3ZDRlOGQ5ZjBkM2E2ZGJhMDVhYWU2MTFiNzgzN1wiLFxuICBcIjc2MmE4Mzk5NzBhYmMyYTVjZmU3ZDRlOGY3ZjdmN2Q5ZjBkM2E2ZGJhMDVhYWU2MTFiNzgzN1wiLFxuICBcIjQwMDA0Yjc2MmE4Mzk5NzBhYmMyYTVjZmU3ZDRlOGQ5ZjBkM2E2ZGJhMDVhYWU2MTFiNzgzNzAwNDQxYlwiLFxuICBcIjQwMDA0Yjc2MmE4Mzk5NzBhYmMyYTVjZmU3ZDRlOGY3ZjdmN2Q5ZjBkM2E2ZGJhMDVhYWU2MTFiNzgzNzAwNDQxYlwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBQUkduID0gcmFtcChzY2hlbWUkMSk7XG5cbnZhciBzY2hlbWUkMiA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiZTlhM2M5ZjdmN2Y3YTFkNzZhXCIsXG4gIFwiZDAxYzhiZjFiNmRhYjhlMTg2NGRhYzI2XCIsXG4gIFwiZDAxYzhiZjFiNmRhZjdmN2Y3YjhlMTg2NGRhYzI2XCIsXG4gIFwiYzUxYjdkZTlhM2M5ZmRlMGVmZTZmNWQwYTFkNzZhNGQ5MjIxXCIsXG4gIFwiYzUxYjdkZTlhM2M5ZmRlMGVmZjdmN2Y3ZTZmNWQwYTFkNzZhNGQ5MjIxXCIsXG4gIFwiYzUxYjdkZGU3N2FlZjFiNmRhZmRlMGVmZTZmNWQwYjhlMTg2N2ZiYzQxNGQ5MjIxXCIsXG4gIFwiYzUxYjdkZGU3N2FlZjFiNmRhZmRlMGVmZjdmN2Y3ZTZmNWQwYjhlMTg2N2ZiYzQxNGQ5MjIxXCIsXG4gIFwiOGUwMTUyYzUxYjdkZGU3N2FlZjFiNmRhZmRlMGVmZTZmNWQwYjhlMTg2N2ZiYzQxNGQ5MjIxMjc2NDE5XCIsXG4gIFwiOGUwMTUyYzUxYjdkZGU3N2FlZjFiNmRhZmRlMGVmZjdmN2Y3ZTZmNWQwYjhlMTg2N2ZiYzQxNGQ5MjIxMjc2NDE5XCJcbikubWFwKGNvbG9ycyQxKTtcblxudmFyIFBpWUcgPSByYW1wKHNjaGVtZSQyKTtcblxudmFyIHNjaGVtZSQzID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCI5OThlYzNmN2Y3ZjdmMWEzNDBcIixcbiAgXCI1ZTNjOTliMmFiZDJmZGI4NjNlNjYxMDFcIixcbiAgXCI1ZTNjOTliMmFiZDJmN2Y3ZjdmZGI4NjNlNjYxMDFcIixcbiAgXCI1NDI3ODg5OThlYzNkOGRhZWJmZWUwYjZmMWEzNDBiMzU4MDZcIixcbiAgXCI1NDI3ODg5OThlYzNkOGRhZWJmN2Y3ZjdmZWUwYjZmMWEzNDBiMzU4MDZcIixcbiAgXCI1NDI3ODg4MDczYWNiMmFiZDJkOGRhZWJmZWUwYjZmZGI4NjNlMDgyMTRiMzU4MDZcIixcbiAgXCI1NDI3ODg4MDczYWNiMmFiZDJkOGRhZWJmN2Y3ZjdmZWUwYjZmZGI4NjNlMDgyMTRiMzU4MDZcIixcbiAgXCIyZDAwNGI1NDI3ODg4MDczYWNiMmFiZDJkOGRhZWJmZWUwYjZmZGI4NjNlMDgyMTRiMzU4MDY3ZjNiMDhcIixcbiAgXCIyZDAwNGI1NDI3ODg4MDczYWNiMmFiZDJkOGRhZWJmN2Y3ZjdmZWUwYjZmZGI4NjNlMDgyMTRiMzU4MDY3ZjNiMDhcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgUHVPciA9IHJhbXAoc2NoZW1lJDMpO1xuXG52YXIgc2NoZW1lJDQgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImVmOGE2MmY3ZjdmNzY3YTljZlwiLFxuICBcImNhMDAyMGY0YTU4MjkyYzVkZTA1NzFiMFwiLFxuICBcImNhMDAyMGY0YTU4MmY3ZjdmNzkyYzVkZTA1NzFiMFwiLFxuICBcImIyMTgyYmVmOGE2MmZkZGJjN2QxZTVmMDY3YTljZjIxNjZhY1wiLFxuICBcImIyMTgyYmVmOGE2MmZkZGJjN2Y3ZjdmN2QxZTVmMDY3YTljZjIxNjZhY1wiLFxuICBcImIyMTgyYmQ2NjA0ZGY0YTU4MmZkZGJjN2QxZTVmMDkyYzVkZTQzOTNjMzIxNjZhY1wiLFxuICBcImIyMTgyYmQ2NjA0ZGY0YTU4MmZkZGJjN2Y3ZjdmN2QxZTVmMDkyYzVkZTQzOTNjMzIxNjZhY1wiLFxuICBcIjY3MDAxZmIyMTgyYmQ2NjA0ZGY0YTU4MmZkZGJjN2QxZTVmMDkyYzVkZTQzOTNjMzIxNjZhYzA1MzA2MVwiLFxuICBcIjY3MDAxZmIyMTgyYmQ2NjA0ZGY0YTU4MmZkZGJjN2Y3ZjdmN2QxZTVmMDkyYzVkZTQzOTNjMzIxNjZhYzA1MzA2MVwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBSZEJ1ID0gcmFtcChzY2hlbWUkNCk7XG5cbnZhciBzY2hlbWUkNSA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiZWY4YTYyZmZmZmZmOTk5OTk5XCIsXG4gIFwiY2EwMDIwZjRhNTgyYmFiYWJhNDA0MDQwXCIsXG4gIFwiY2EwMDIwZjRhNTgyZmZmZmZmYmFiYWJhNDA0MDQwXCIsXG4gIFwiYjIxODJiZWY4YTYyZmRkYmM3ZTBlMGUwOTk5OTk5NGQ0ZDRkXCIsXG4gIFwiYjIxODJiZWY4YTYyZmRkYmM3ZmZmZmZmZTBlMGUwOTk5OTk5NGQ0ZDRkXCIsXG4gIFwiYjIxODJiZDY2MDRkZjRhNTgyZmRkYmM3ZTBlMGUwYmFiYWJhODc4Nzg3NGQ0ZDRkXCIsXG4gIFwiYjIxODJiZDY2MDRkZjRhNTgyZmRkYmM3ZmZmZmZmZTBlMGUwYmFiYWJhODc4Nzg3NGQ0ZDRkXCIsXG4gIFwiNjcwMDFmYjIxODJiZDY2MDRkZjRhNTgyZmRkYmM3ZTBlMGUwYmFiYWJhODc4Nzg3NGQ0ZDRkMWExYTFhXCIsXG4gIFwiNjcwMDFmYjIxODJiZDY2MDRkZjRhNTgyZmRkYmM3ZmZmZmZmZTBlMGUwYmFiYWJhODc4Nzg3NGQ0ZDRkMWExYTFhXCJcbikubWFwKGNvbG9ycyQxKTtcblxudmFyIFJkR3kgPSByYW1wKHNjaGVtZSQ1KTtcblxudmFyIHNjaGVtZSQ2ID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJmYzhkNTlmZmZmYmY5MWJmZGJcIixcbiAgXCJkNzE5MWNmZGFlNjFhYmQ5ZTkyYzdiYjZcIixcbiAgXCJkNzE5MWNmZGFlNjFmZmZmYmZhYmQ5ZTkyYzdiYjZcIixcbiAgXCJkNzMwMjdmYzhkNTlmZWUwOTBlMGYzZjg5MWJmZGI0NTc1YjRcIixcbiAgXCJkNzMwMjdmYzhkNTlmZWUwOTBmZmZmYmZlMGYzZjg5MWJmZGI0NTc1YjRcIixcbiAgXCJkNzMwMjdmNDZkNDNmZGFlNjFmZWUwOTBlMGYzZjhhYmQ5ZTk3NGFkZDE0NTc1YjRcIixcbiAgXCJkNzMwMjdmNDZkNDNmZGFlNjFmZWUwOTBmZmZmYmZlMGYzZjhhYmQ5ZTk3NGFkZDE0NTc1YjRcIixcbiAgXCJhNTAwMjZkNzMwMjdmNDZkNDNmZGFlNjFmZWUwOTBlMGYzZjhhYmQ5ZTk3NGFkZDE0NTc1YjQzMTM2OTVcIixcbiAgXCJhNTAwMjZkNzMwMjdmNDZkNDNmZGFlNjFmZWUwOTBmZmZmYmZlMGYzZjhhYmQ5ZTk3NGFkZDE0NTc1YjQzMTM2OTVcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgUmRZbEJ1ID0gcmFtcChzY2hlbWUkNik7XG5cbnZhciBzY2hlbWUkNyA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiZmM4ZDU5ZmZmZmJmOTFjZjYwXCIsXG4gIFwiZDcxOTFjZmRhZTYxYTZkOTZhMWE5NjQxXCIsXG4gIFwiZDcxOTFjZmRhZTYxZmZmZmJmYTZkOTZhMWE5NjQxXCIsXG4gIFwiZDczMDI3ZmM4ZDU5ZmVlMDhiZDllZjhiOTFjZjYwMWE5ODUwXCIsXG4gIFwiZDczMDI3ZmM4ZDU5ZmVlMDhiZmZmZmJmZDllZjhiOTFjZjYwMWE5ODUwXCIsXG4gIFwiZDczMDI3ZjQ2ZDQzZmRhZTYxZmVlMDhiZDllZjhiYTZkOTZhNjZiZDYzMWE5ODUwXCIsXG4gIFwiZDczMDI3ZjQ2ZDQzZmRhZTYxZmVlMDhiZmZmZmJmZDllZjhiYTZkOTZhNjZiZDYzMWE5ODUwXCIsXG4gIFwiYTUwMDI2ZDczMDI3ZjQ2ZDQzZmRhZTYxZmVlMDhiZDllZjhiYTZkOTZhNjZiZDYzMWE5ODUwMDA2ODM3XCIsXG4gIFwiYTUwMDI2ZDczMDI3ZjQ2ZDQzZmRhZTYxZmVlMDhiZmZmZmJmZDllZjhiYTZkOTZhNjZiZDYzMWE5ODUwMDA2ODM3XCJcbikubWFwKGNvbG9ycyQxKTtcblxudmFyIFJkWWxHbiA9IHJhbXAoc2NoZW1lJDcpO1xuXG52YXIgc2NoZW1lJDggPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImZjOGQ1OWZmZmZiZjk5ZDU5NFwiLFxuICBcImQ3MTkxY2ZkYWU2MWFiZGRhNDJiODNiYVwiLFxuICBcImQ3MTkxY2ZkYWU2MWZmZmZiZmFiZGRhNDJiODNiYVwiLFxuICBcImQ1M2U0ZmZjOGQ1OWZlZTA4YmU2ZjU5ODk5ZDU5NDMyODhiZFwiLFxuICBcImQ1M2U0ZmZjOGQ1OWZlZTA4YmZmZmZiZmU2ZjU5ODk5ZDU5NDMyODhiZFwiLFxuICBcImQ1M2U0ZmY0NmQ0M2ZkYWU2MWZlZTA4YmU2ZjU5OGFiZGRhNDY2YzJhNTMyODhiZFwiLFxuICBcImQ1M2U0ZmY0NmQ0M2ZkYWU2MWZlZTA4YmZmZmZiZmU2ZjU5OGFiZGRhNDY2YzJhNTMyODhiZFwiLFxuICBcIjllMDE0MmQ1M2U0ZmY0NmQ0M2ZkYWU2MWZlZTA4YmU2ZjU5OGFiZGRhNDY2YzJhNTMyODhiZDVlNGZhMlwiLFxuICBcIjllMDE0MmQ1M2U0ZmY0NmQ0M2ZkYWU2MWZlZTA4YmZmZmZiZmU2ZjU5OGFiZGRhNDY2YzJhNTMyODhiZDVlNGZhMlwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBTcGVjdHJhbCA9IHJhbXAoc2NoZW1lJDgpO1xuXG52YXIgc2NoZW1lJDkgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImU1ZjVmOTk5ZDhjOTJjYTI1ZlwiLFxuICBcImVkZjhmYmIyZTJlMjY2YzJhNDIzOGI0NVwiLFxuICBcImVkZjhmYmIyZTJlMjY2YzJhNDJjYTI1ZjAwNmQyY1wiLFxuICBcImVkZjhmYmNjZWNlNjk5ZDhjOTY2YzJhNDJjYTI1ZjAwNmQyY1wiLFxuICBcImVkZjhmYmNjZWNlNjk5ZDhjOTY2YzJhNDQxYWU3NjIzOGI0NTAwNTgyNFwiLFxuICBcImY3ZmNmZGU1ZjVmOWNjZWNlNjk5ZDhjOTY2YzJhNDQxYWU3NjIzOGI0NTAwNTgyNFwiLFxuICBcImY3ZmNmZGU1ZjVmOWNjZWNlNjk5ZDhjOTY2YzJhNDQxYWU3NjIzOGI0NTAwNmQyYzAwNDQxYlwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBCdUduID0gcmFtcChzY2hlbWUkOSk7XG5cbnZhciBzY2hlbWUkMTAgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImUwZWNmNDllYmNkYTg4NTZhN1wiLFxuICBcImVkZjhmYmIzY2RlMzhjOTZjNjg4NDE5ZFwiLFxuICBcImVkZjhmYmIzY2RlMzhjOTZjNjg4NTZhNzgxMGY3Y1wiLFxuICBcImVkZjhmYmJmZDNlNjllYmNkYThjOTZjNjg4NTZhNzgxMGY3Y1wiLFxuICBcImVkZjhmYmJmZDNlNjllYmNkYThjOTZjNjhjNmJiMTg4NDE5ZDZlMDE2YlwiLFxuICBcImY3ZmNmZGUwZWNmNGJmZDNlNjllYmNkYThjOTZjNjhjNmJiMTg4NDE5ZDZlMDE2YlwiLFxuICBcImY3ZmNmZGUwZWNmNGJmZDNlNjllYmNkYThjOTZjNjhjNmJiMTg4NDE5ZDgxMGY3YzRkMDA0YlwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBCdVB1ID0gcmFtcChzY2hlbWUkMTApO1xuXG52YXIgc2NoZW1lJDExID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJlMGYzZGJhOGRkYjU0M2EyY2FcIixcbiAgXCJmMGY5ZThiYWU0YmM3YmNjYzQyYjhjYmVcIixcbiAgXCJmMGY5ZThiYWU0YmM3YmNjYzQ0M2EyY2EwODY4YWNcIixcbiAgXCJmMGY5ZThjY2ViYzVhOGRkYjU3YmNjYzQ0M2EyY2EwODY4YWNcIixcbiAgXCJmMGY5ZThjY2ViYzVhOGRkYjU3YmNjYzQ0ZWIzZDMyYjhjYmUwODU4OWVcIixcbiAgXCJmN2ZjZjBlMGYzZGJjY2ViYzVhOGRkYjU3YmNjYzQ0ZWIzZDMyYjhjYmUwODU4OWVcIixcbiAgXCJmN2ZjZjBlMGYzZGJjY2ViYzVhOGRkYjU3YmNjYzQ0ZWIzZDMyYjhjYmUwODY4YWMwODQwODFcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgR25CdSA9IHJhbXAoc2NoZW1lJDExKTtcblxudmFyIHNjaGVtZSQxMiA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiZmVlOGM4ZmRiYjg0ZTM0YTMzXCIsXG4gIFwiZmVmMGQ5ZmRjYzhhZmM4ZDU5ZDczMDFmXCIsXG4gIFwiZmVmMGQ5ZmRjYzhhZmM4ZDU5ZTM0YTMzYjMwMDAwXCIsXG4gIFwiZmVmMGQ5ZmRkNDllZmRiYjg0ZmM4ZDU5ZTM0YTMzYjMwMDAwXCIsXG4gIFwiZmVmMGQ5ZmRkNDllZmRiYjg0ZmM4ZDU5ZWY2NTQ4ZDczMDFmOTkwMDAwXCIsXG4gIFwiZmZmN2VjZmVlOGM4ZmRkNDllZmRiYjg0ZmM4ZDU5ZWY2NTQ4ZDczMDFmOTkwMDAwXCIsXG4gIFwiZmZmN2VjZmVlOGM4ZmRkNDllZmRiYjg0ZmM4ZDU5ZWY2NTQ4ZDczMDFmYjMwMDAwN2YwMDAwXCJcbikubWFwKGNvbG9ycyQxKTtcblxudmFyIE9yUmQgPSByYW1wKHNjaGVtZSQxMik7XG5cbnZhciBzY2hlbWUkMTMgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImVjZTJmMGE2YmRkYjFjOTA5OVwiLFxuICBcImY2ZWZmN2JkYzllMTY3YTljZjAyODE4YVwiLFxuICBcImY2ZWZmN2JkYzllMTY3YTljZjFjOTA5OTAxNmM1OVwiLFxuICBcImY2ZWZmN2QwZDFlNmE2YmRkYjY3YTljZjFjOTA5OTAxNmM1OVwiLFxuICBcImY2ZWZmN2QwZDFlNmE2YmRkYjY3YTljZjM2OTBjMDAyODE4YTAxNjQ1MFwiLFxuICBcImZmZjdmYmVjZTJmMGQwZDFlNmE2YmRkYjY3YTljZjM2OTBjMDAyODE4YTAxNjQ1MFwiLFxuICBcImZmZjdmYmVjZTJmMGQwZDFlNmE2YmRkYjY3YTljZjM2OTBjMDAyODE4YTAxNmM1OTAxNDYzNlwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBQdUJ1R24gPSByYW1wKHNjaGVtZSQxMyk7XG5cbnZhciBzY2hlbWUkMTQgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImVjZTdmMmE2YmRkYjJiOGNiZVwiLFxuICBcImYxZWVmNmJkYzllMTc0YTljZjA1NzBiMFwiLFxuICBcImYxZWVmNmJkYzllMTc0YTljZjJiOGNiZTA0NWE4ZFwiLFxuICBcImYxZWVmNmQwZDFlNmE2YmRkYjc0YTljZjJiOGNiZTA0NWE4ZFwiLFxuICBcImYxZWVmNmQwZDFlNmE2YmRkYjc0YTljZjM2OTBjMDA1NzBiMDAzNGU3YlwiLFxuICBcImZmZjdmYmVjZTdmMmQwZDFlNmE2YmRkYjc0YTljZjM2OTBjMDA1NzBiMDAzNGU3YlwiLFxuICBcImZmZjdmYmVjZTdmMmQwZDFlNmE2YmRkYjc0YTljZjM2OTBjMDA1NzBiMDA0NWE4ZDAyMzg1OFwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBQdUJ1ID0gcmFtcChzY2hlbWUkMTQpO1xuXG52YXIgc2NoZW1lJDE1ID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJlN2UxZWZjOTk0YzdkZDFjNzdcIixcbiAgXCJmMWVlZjZkN2I1ZDhkZjY1YjBjZTEyNTZcIixcbiAgXCJmMWVlZjZkN2I1ZDhkZjY1YjBkZDFjNzc5ODAwNDNcIixcbiAgXCJmMWVlZjZkNGI5ZGFjOTk0YzdkZjY1YjBkZDFjNzc5ODAwNDNcIixcbiAgXCJmMWVlZjZkNGI5ZGFjOTk0YzdkZjY1YjBlNzI5OGFjZTEyNTY5MTAwM2ZcIixcbiAgXCJmN2Y0ZjllN2UxZWZkNGI5ZGFjOTk0YzdkZjY1YjBlNzI5OGFjZTEyNTY5MTAwM2ZcIixcbiAgXCJmN2Y0ZjllN2UxZWZkNGI5ZGFjOTk0YzdkZjY1YjBlNzI5OGFjZTEyNTY5ODAwNDM2NzAwMWZcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgUHVSZCA9IHJhbXAoc2NoZW1lJDE1KTtcblxudmFyIHNjaGVtZSQxNiA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiZmRlMGRkZmE5ZmI1YzUxYjhhXCIsXG4gIFwiZmVlYmUyZmJiNGI5Zjc2OGExYWUwMTdlXCIsXG4gIFwiZmVlYmUyZmJiNGI5Zjc2OGExYzUxYjhhN2EwMTc3XCIsXG4gIFwiZmVlYmUyZmNjNWMwZmE5ZmI1Zjc2OGExYzUxYjhhN2EwMTc3XCIsXG4gIFwiZmVlYmUyZmNjNWMwZmE5ZmI1Zjc2OGExZGQzNDk3YWUwMTdlN2EwMTc3XCIsXG4gIFwiZmZmN2YzZmRlMGRkZmNjNWMwZmE5ZmI1Zjc2OGExZGQzNDk3YWUwMTdlN2EwMTc3XCIsXG4gIFwiZmZmN2YzZmRlMGRkZmNjNWMwZmE5ZmI1Zjc2OGExZGQzNDk3YWUwMTdlN2EwMTc3NDkwMDZhXCJcbikubWFwKGNvbG9ycyQxKTtcblxudmFyIFJkUHUgPSByYW1wKHNjaGVtZSQxNik7XG5cbnZhciBzY2hlbWUkMTcgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImVkZjhiMTdmY2RiYjJjN2ZiOFwiLFxuICBcImZmZmZjY2ExZGFiNDQxYjZjNDIyNWVhOFwiLFxuICBcImZmZmZjY2ExZGFiNDQxYjZjNDJjN2ZiODI1MzQ5NFwiLFxuICBcImZmZmZjY2M3ZTliNDdmY2RiYjQxYjZjNDJjN2ZiODI1MzQ5NFwiLFxuICBcImZmZmZjY2M3ZTliNDdmY2RiYjQxYjZjNDFkOTFjMDIyNWVhODBjMmM4NFwiLFxuICBcImZmZmZkOWVkZjhiMWM3ZTliNDdmY2RiYjQxYjZjNDFkOTFjMDIyNWVhODBjMmM4NFwiLFxuICBcImZmZmZkOWVkZjhiMWM3ZTliNDdmY2RiYjQxYjZjNDFkOTFjMDIyNWVhODI1MzQ5NDA4MWQ1OFwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBZbEduQnUgPSByYW1wKHNjaGVtZSQxNyk7XG5cbnZhciBzY2hlbWUkMTggPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImY3ZmNiOWFkZGQ4ZTMxYTM1NFwiLFxuICBcImZmZmZjY2MyZTY5OTc4YzY3OTIzODQ0M1wiLFxuICBcImZmZmZjY2MyZTY5OTc4YzY3OTMxYTM1NDAwNjgzN1wiLFxuICBcImZmZmZjY2Q5ZjBhM2FkZGQ4ZTc4YzY3OTMxYTM1NDAwNjgzN1wiLFxuICBcImZmZmZjY2Q5ZjBhM2FkZGQ4ZTc4YzY3OTQxYWI1ZDIzODQ0MzAwNWEzMlwiLFxuICBcImZmZmZlNWY3ZmNiOWQ5ZjBhM2FkZGQ4ZTc4YzY3OTQxYWI1ZDIzODQ0MzAwNWEzMlwiLFxuICBcImZmZmZlNWY3ZmNiOWQ5ZjBhM2FkZGQ4ZTc4YzY3OTQxYWI1ZDIzODQ0MzAwNjgzNzAwNDUyOVwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBZbEduID0gcmFtcChzY2hlbWUkMTgpO1xuXG52YXIgc2NoZW1lJDE5ID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJmZmY3YmNmZWM0NGZkOTVmMGVcIixcbiAgXCJmZmZmZDRmZWQ5OGVmZTk5MjljYzRjMDJcIixcbiAgXCJmZmZmZDRmZWQ5OGVmZTk5MjlkOTVmMGU5OTM0MDRcIixcbiAgXCJmZmZmZDRmZWUzOTFmZWM0NGZmZTk5MjlkOTVmMGU5OTM0MDRcIixcbiAgXCJmZmZmZDRmZWUzOTFmZWM0NGZmZTk5MjllYzcwMTRjYzRjMDI4YzJkMDRcIixcbiAgXCJmZmZmZTVmZmY3YmNmZWUzOTFmZWM0NGZmZTk5MjllYzcwMTRjYzRjMDI4YzJkMDRcIixcbiAgXCJmZmZmZTVmZmY3YmNmZWUzOTFmZWM0NGZmZTk5MjllYzcwMTRjYzRjMDI5OTM0MDQ2NjI1MDZcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgWWxPckJyID0gcmFtcChzY2hlbWUkMTkpO1xuXG52YXIgc2NoZW1lJDIwID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJmZmVkYTBmZWIyNGNmMDNiMjBcIixcbiAgXCJmZmZmYjJmZWNjNWNmZDhkM2NlMzFhMWNcIixcbiAgXCJmZmZmYjJmZWNjNWNmZDhkM2NmMDNiMjBiZDAwMjZcIixcbiAgXCJmZmZmYjJmZWQ5NzZmZWIyNGNmZDhkM2NmMDNiMjBiZDAwMjZcIixcbiAgXCJmZmZmYjJmZWQ5NzZmZWIyNGNmZDhkM2NmYzRlMmFlMzFhMWNiMTAwMjZcIixcbiAgXCJmZmZmY2NmZmVkYTBmZWQ5NzZmZWIyNGNmZDhkM2NmYzRlMmFlMzFhMWNiMTAwMjZcIixcbiAgXCJmZmZmY2NmZmVkYTBmZWQ5NzZmZWIyNGNmZDhkM2NmYzRlMmFlMzFhMWNiZDAwMjY4MDAwMjZcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgWWxPclJkID0gcmFtcChzY2hlbWUkMjApO1xuXG52YXIgc2NoZW1lJDIxID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJkZWViZjc5ZWNhZTEzMTgyYmRcIixcbiAgXCJlZmYzZmZiZGQ3ZTc2YmFlZDYyMTcxYjVcIixcbiAgXCJlZmYzZmZiZGQ3ZTc2YmFlZDYzMTgyYmQwODUxOWNcIixcbiAgXCJlZmYzZmZjNmRiZWY5ZWNhZTE2YmFlZDYzMTgyYmQwODUxOWNcIixcbiAgXCJlZmYzZmZjNmRiZWY5ZWNhZTE2YmFlZDY0MjkyYzYyMTcxYjUwODQ1OTRcIixcbiAgXCJmN2ZiZmZkZWViZjdjNmRiZWY5ZWNhZTE2YmFlZDY0MjkyYzYyMTcxYjUwODQ1OTRcIixcbiAgXCJmN2ZiZmZkZWViZjdjNmRiZWY5ZWNhZTE2YmFlZDY0MjkyYzYyMTcxYjUwODUxOWMwODMwNmJcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgQmx1ZXMgPSByYW1wKHNjaGVtZSQyMSk7XG5cbnZhciBzY2hlbWUkMjIgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImU1ZjVlMGExZDk5YjMxYTM1NFwiLFxuICBcImVkZjhlOWJhZTRiMzc0YzQ3NjIzOGI0NVwiLFxuICBcImVkZjhlOWJhZTRiMzc0YzQ3NjMxYTM1NDAwNmQyY1wiLFxuICBcImVkZjhlOWM3ZTljMGExZDk5Yjc0YzQ3NjMxYTM1NDAwNmQyY1wiLFxuICBcImVkZjhlOWM3ZTljMGExZDk5Yjc0YzQ3NjQxYWI1ZDIzOGI0NTAwNWEzMlwiLFxuICBcImY3ZmNmNWU1ZjVlMGM3ZTljMGExZDk5Yjc0YzQ3NjQxYWI1ZDIzOGI0NTAwNWEzMlwiLFxuICBcImY3ZmNmNWU1ZjVlMGM3ZTljMGExZDk5Yjc0YzQ3NjQxYWI1ZDIzOGI0NTAwNmQyYzAwNDQxYlwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBHcmVlbnMgPSByYW1wKHNjaGVtZSQyMik7XG5cbnZhciBzY2hlbWUkMjMgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImYwZjBmMGJkYmRiZDYzNjM2M1wiLFxuICBcImY3ZjdmN2NjY2NjYzk2OTY5NjUyNTI1MlwiLFxuICBcImY3ZjdmN2NjY2NjYzk2OTY5NjYzNjM2MzI1MjUyNVwiLFxuICBcImY3ZjdmN2Q5ZDlkOWJkYmRiZDk2OTY5NjYzNjM2MzI1MjUyNVwiLFxuICBcImY3ZjdmN2Q5ZDlkOWJkYmRiZDk2OTY5NjczNzM3MzUyNTI1MjI1MjUyNVwiLFxuICBcImZmZmZmZmYwZjBmMGQ5ZDlkOWJkYmRiZDk2OTY5NjczNzM3MzUyNTI1MjI1MjUyNVwiLFxuICBcImZmZmZmZmYwZjBmMGQ5ZDlkOWJkYmRiZDk2OTY5NjczNzM3MzUyNTI1MjI1MjUyNTAwMDAwMFwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBHcmV5cyA9IHJhbXAoc2NoZW1lJDIzKTtcblxudmFyIHNjaGVtZSQyNCA9IG5ldyBBcnJheSgzKS5jb25jYXQoXG4gIFwiZWZlZGY1YmNiZGRjNzU2YmIxXCIsXG4gIFwiZjJmMGY3Y2JjOWUyOWU5YWM4NmE1MWEzXCIsXG4gIFwiZjJmMGY3Y2JjOWUyOWU5YWM4NzU2YmIxNTQyNzhmXCIsXG4gIFwiZjJmMGY3ZGFkYWViYmNiZGRjOWU5YWM4NzU2YmIxNTQyNzhmXCIsXG4gIFwiZjJmMGY3ZGFkYWViYmNiZGRjOWU5YWM4ODA3ZGJhNmE1MWEzNGExNDg2XCIsXG4gIFwiZmNmYmZkZWZlZGY1ZGFkYWViYmNiZGRjOWU5YWM4ODA3ZGJhNmE1MWEzNGExNDg2XCIsXG4gIFwiZmNmYmZkZWZlZGY1ZGFkYWViYmNiZGRjOWU5YWM4ODA3ZGJhNmE1MWEzNTQyNzhmM2YwMDdkXCJcbikubWFwKGNvbG9ycyQxKTtcblxudmFyIFB1cnBsZXMgPSByYW1wKHNjaGVtZSQyNCk7XG5cbnZhciBzY2hlbWUkMjUgPSBuZXcgQXJyYXkoMykuY29uY2F0KFxuICBcImZlZTBkMmZjOTI3MmRlMmQyNlwiLFxuICBcImZlZTVkOWZjYWU5MWZiNmE0YWNiMTgxZFwiLFxuICBcImZlZTVkOWZjYWU5MWZiNmE0YWRlMmQyNmE1MGYxNVwiLFxuICBcImZlZTVkOWZjYmJhMWZjOTI3MmZiNmE0YWRlMmQyNmE1MGYxNVwiLFxuICBcImZlZTVkOWZjYmJhMWZjOTI3MmZiNmE0YWVmM2IyY2NiMTgxZDk5MDAwZFwiLFxuICBcImZmZjVmMGZlZTBkMmZjYmJhMWZjOTI3MmZiNmE0YWVmM2IyY2NiMTgxZDk5MDAwZFwiLFxuICBcImZmZjVmMGZlZTBkMmZjYmJhMWZjOTI3MmZiNmE0YWVmM2IyY2NiMTgxZGE1MGYxNTY3MDAwZFwiXG4pLm1hcChjb2xvcnMkMSk7XG5cbnZhciBSZWRzID0gcmFtcChzY2hlbWUkMjUpO1xuXG52YXIgc2NoZW1lJDI2ID0gbmV3IEFycmF5KDMpLmNvbmNhdChcbiAgXCJmZWU2Y2VmZGFlNmJlNjU1MGRcIixcbiAgXCJmZWVkZGVmZGJlODVmZDhkM2NkOTQ3MDFcIixcbiAgXCJmZWVkZGVmZGJlODVmZDhkM2NlNjU1MGRhNjM2MDNcIixcbiAgXCJmZWVkZGVmZGQwYTJmZGFlNmJmZDhkM2NlNjU1MGRhNjM2MDNcIixcbiAgXCJmZWVkZGVmZGQwYTJmZGFlNmJmZDhkM2NmMTY5MTNkOTQ4MDE4YzJkMDRcIixcbiAgXCJmZmY1ZWJmZWU2Y2VmZGQwYTJmZGFlNmJmZDhkM2NmMTY5MTNkOTQ4MDE4YzJkMDRcIixcbiAgXCJmZmY1ZWJmZWU2Y2VmZGQwYTJmZGFlNmJmZDhkM2NmMTY5MTNkOTQ4MDFhNjM2MDM3ZjI3MDRcIlxuKS5tYXAoY29sb3JzJDEpO1xuXG52YXIgT3JhbmdlcyA9IHJhbXAoc2NoZW1lJDI2KTtcblxudmFyIGN1YmVoZWxpeCQzID0gY3ViZWhlbGl4TG9uZyhjdWJlaGVsaXgoMzAwLCAwLjUsIDAuMCksIGN1YmVoZWxpeCgtMjQwLCAwLjUsIDEuMCkpO1xuXG52YXIgd2FybSA9IGN1YmVoZWxpeExvbmcoY3ViZWhlbGl4KC0xMDAsIDAuNzUsIDAuMzUpLCBjdWJlaGVsaXgoODAsIDEuNTAsIDAuOCkpO1xuXG52YXIgY29vbCA9IGN1YmVoZWxpeExvbmcoY3ViZWhlbGl4KDI2MCwgMC43NSwgMC4zNSksIGN1YmVoZWxpeCg4MCwgMS41MCwgMC44KSk7XG5cbnZhciByYWluYm93ID0gY3ViZWhlbGl4KCk7XG5cbnZhciByYWluYm93JDEgPSBmdW5jdGlvbih0KSB7XG4gIGlmICh0IDwgMCB8fCB0ID4gMSkgdCAtPSBNYXRoLmZsb29yKHQpO1xuICB2YXIgdHMgPSBNYXRoLmFicyh0IC0gMC41KTtcbiAgcmFpbmJvdy5oID0gMzYwICogdCAtIDEwMDtcbiAgcmFpbmJvdy5zID0gMS41IC0gMS41ICogdHM7XG4gIHJhaW5ib3cubCA9IDAuOCAtIDAuOSAqIHRzO1xuICByZXR1cm4gcmFpbmJvdyArIFwiXCI7XG59O1xuXG5mdW5jdGlvbiByYW1wJDEocmFuZ2UpIHtcbiAgdmFyIG4gPSByYW5nZS5sZW5ndGg7XG4gIHJldHVybiBmdW5jdGlvbih0KSB7XG4gICAgcmV0dXJuIHJhbmdlW01hdGgubWF4KDAsIE1hdGgubWluKG4gLSAxLCBNYXRoLmZsb29yKHQgKiBuKSkpXTtcbiAgfTtcbn1cblxudmFyIHZpcmlkaXMgPSByYW1wJDEoY29sb3JzJDEoXCI0NDAxNTQ0NDAyNTY0NTA0NTc0NTA1NTk0NjA3NWE0NjA4NWM0NjBhNWQ0NjBiNWU0NzBkNjA0NzBlNjE0NzEwNjM0NzExNjQ0NzEzNjU0ODE0Njc0ODE2Njg0ODE3Njk0ODE4NmE0ODFhNmM0ODFiNmQ0ODFjNmU0ODFkNmY0ODFmNzA0ODIwNzE0ODIxNzM0ODIzNzQ0ODI0NzU0ODI1NzY0ODI2Nzc0ODI4Nzg0ODI5Nzk0NzJhN2E0NzJjN2E0NzJkN2I0NzJlN2M0NzJmN2Q0NjMwN2U0NjMyN2U0NjMzN2Y0NjM0ODA0NTM1ODE0NTM3ODE0NTM4ODI0NDM5ODM0NDNhODM0NDNiODQ0MzNkODQ0MzNlODU0MjNmODU0MjQwODY0MjQxODY0MTQyODc0MTQ0ODc0MDQ1ODg0MDQ2ODgzZjQ3ODgzZjQ4ODkzZTQ5ODkzZTRhODkzZTRjOGEzZDRkOGEzZDRlOGEzYzRmOGEzYzUwOGIzYjUxOGIzYjUyOGIzYTUzOGIzYTU0OGMzOTU1OGMzOTU2OGMzODU4OGMzODU5OGMzNzVhOGMzNzViOGQzNjVjOGQzNjVkOGQzNTVlOGQzNTVmOGQzNDYwOGQzNDYxOGQzMzYyOGQzMzYzOGQzMjY0OGUzMjY1OGUzMTY2OGUzMTY3OGUzMTY4OGUzMDY5OGUzMDZhOGUyZjZiOGUyZjZjOGUyZTZkOGUyZTZlOGUyZTZmOGUyZDcwOGUyZDcxOGUyYzcxOGUyYzcyOGUyYzczOGUyYjc0OGUyYjc1OGUyYTc2OGUyYTc3OGUyYTc4OGUyOTc5OGUyOTdhOGUyOTdiOGUyODdjOGUyODdkOGUyNzdlOGUyNzdmOGUyNzgwOGUyNjgxOGUyNjgyOGUyNjgyOGUyNTgzOGUyNTg0OGUyNTg1OGUyNDg2OGUyNDg3OGUyMzg4OGUyMzg5OGUyMzhhOGQyMjhiOGQyMjhjOGQyMjhkOGQyMThlOGQyMThmOGQyMTkwOGQyMTkxOGMyMDkyOGMyMDkyOGMyMDkzOGMxZjk0OGMxZjk1OGIxZjk2OGIxZjk3OGIxZjk4OGIxZjk5OGExZjlhOGExZTliOGExZTljODkxZTlkODkxZjllODkxZjlmODgxZmEwODgxZmExODgxZmExODcxZmEyODcyMGEzODYyMGE0ODYyMWE1ODUyMWE2ODUyMmE3ODUyMmE4ODQyM2E5ODMyNGFhODMyNWFiODIyNWFjODIyNmFkODEyN2FkODEyOGFlODAyOWFmN2YyYWIwN2YyY2IxN2UyZGIyN2QyZWIzN2MyZmI0N2MzMWI1N2IzMmI2N2EzNGI2NzkzNWI3NzkzN2I4NzgzOGI5NzczYWJhNzYzYmJiNzUzZGJjNzQzZmJjNzM0MGJkNzI0MmJlNzE0NGJmNzA0NmMwNmY0OGMxNmU0YWMxNmQ0Y2MyNmM0ZWMzNmI1MGM0NmE1MmM1Njk1NGM1Njg1NmM2Njc1OGM3NjU1YWM4NjQ1Y2M4NjM1ZWM5NjI2MGNhNjA2M2NiNWY2NWNiNWU2N2NjNWM2OWNkNWI2Y2NkNWE2ZWNlNTg3MGNmNTc3M2QwNTY3NWQwNTQ3N2QxNTM3YWQxNTE3Y2QyNTA3ZmQzNGU4MWQzNGQ4NGQ0NGI4NmQ1NDk4OWQ1NDg4YmQ2NDY4ZWQ2NDU5MGQ3NDM5M2Q3NDE5NWQ4NDA5OGQ4M2U5YmQ5M2M5ZGQ5M2JhMGRhMzlhMmRhMzdhNWRiMzZhOGRiMzRhYWRjMzJhZGRjMzBiMGRkMmZiMmRkMmRiNWRlMmJiOGRlMjliYWRlMjhiZGRmMjZjMGRmMjVjMmRmMjNjNWUwMjFjOGUwMjBjYWUxMWZjZGUxMWRkMGUxMWNkMmUyMWJkNWUyMWFkOGUyMTlkYWUzMTlkZGUzMThkZmUzMThlMmU0MThlNWU0MTllN2U0MTllYWU1MWFlY2U1MWJlZmU1MWNmMWU1MWRmNGU2MWVmNmU2MjBmOGU2MjFmYmU3MjNmZGU3MjVcIikpO1xuXG52YXIgbWFnbWEgPSByYW1wJDEoY29sb3JzJDEoXCIwMDAwMDQwMTAwMDUwMTAxMDYwMTAxMDgwMjAxMDkwMjAyMGIwMjAyMGQwMzAzMGYwMzAzMTIwNDA0MTQwNTA0MTYwNjA1MTgwNjA1MWEwNzA2MWMwODA3MWUwOTA3MjAwYTA4MjIwYjA5MjQwYzA5MjYwZDBhMjkwZTBiMmIxMDBiMmQxMTBjMmYxMjBkMzExMzBkMzQxNDBlMzYxNTBlMzgxNjBmM2IxODBmM2QxOTEwM2YxYTEwNDIxYzEwNDQxZDExNDcxZTExNDkyMDExNGIyMTExNGUyMjExNTAyNDEyNTMyNTEyNTUyNzEyNTgyOTExNWEyYTExNWMyYzExNWYyZDExNjEyZjExNjMzMTExNjUzMzEwNjczNDEwNjkzNjEwNmIzODEwNmMzOTBmNmUzYjBmNzAzZDBmNzEzZjBmNzI0MDBmNzQ0MjBmNzU0NDBmNzY0NTEwNzc0NzEwNzg0OTEwNzg0YTEwNzk0YzExN2E0ZTExN2I0ZjEyN2I1MTEyN2M1MjEzN2M1NDEzN2Q1NjE0N2Q1NzE1N2U1OTE1N2U1YTE2N2U1YzE2N2Y1ZDE3N2Y1ZjE4N2Y2MDE4ODA2MjE5ODA2NDFhODA2NTFhODA2NzFiODA2ODFjODE2YTFjODE2YjFkODE2ZDFkODE2ZTFlODE3MDFmODE3MjFmODE3MzIwODE3NTIxODE3NjIxODE3ODIyODE3OTIyODI3YjIzODI3YzIzODI3ZTI0ODI4MDI1ODI4MTI1ODE4MzI2ODE4NDI2ODE4NjI3ODE4ODI3ODE4OTI4ODE4YjI5ODE4YzI5ODE4ZTJhODE5MDJhODE5MTJiODE5MzJiODA5NDJjODA5NjJjODA5ODJkODA5OTJkODA5YjJlN2Y5YzJlN2Y5ZTJmN2ZhMDJmN2ZhMTMwN2VhMzMwN2VhNTMxN2VhNjMxN2RhODMyN2RhYTMzN2RhYjMzN2NhZDM0N2NhZTM0N2JiMDM1N2JiMjM1N2JiMzM2N2FiNTM2N2FiNzM3NzliODM3NzliYTM4NzhiYzM5NzhiZDM5NzdiZjNhNzdjMDNhNzZjMjNiNzVjNDNjNzVjNTNjNzRjNzNkNzNjODNlNzNjYTNlNzJjYzNmNzFjZDQwNzFjZjQwNzBkMDQxNmZkMjQyNmZkMzQzNmVkNTQ0NmRkNjQ1NmNkODQ1NmNkOTQ2NmJkYjQ3NmFkYzQ4NjlkZTQ5NjhkZjRhNjhlMDRjNjdlMjRkNjZlMzRlNjVlNDRmNjRlNTUwNjRlNzUyNjNlODUzNjJlOTU0NjJlYTU2NjFlYjU3NjBlYzU4NjBlZDVhNWZlZTViNWVlZjVkNWVmMDVmNWVmMTYwNWRmMjYyNWRmMjY0NWNmMzY1NWNmNDY3NWNmNDY5NWNmNTZiNWNmNjZjNWNmNjZlNWNmNzcwNWNmNzcyNWNmODc0NWNmODc2NWNmOTc4NWRmOTc5NWRmOTdiNWRmYTdkNWVmYTdmNWVmYTgxNWZmYjgzNWZmYjg1NjBmYjg3NjFmYzg5NjFmYzhhNjJmYzhjNjNmYzhlNjRmYzkwNjVmZDkyNjZmZDk0NjdmZDk2NjhmZDk4NjlmZDlhNmFmZDliNmJmZTlkNmNmZTlmNmRmZWExNmVmZWEzNmZmZWE1NzFmZWE3NzJmZWE5NzNmZWFhNzRmZWFjNzZmZWFlNzdmZWIwNzhmZWIyN2FmZWI0N2JmZWI2N2NmZWI3N2VmZWI5N2ZmZWJiODFmZWJkODJmZWJmODRmZWMxODVmZWMyODdmZWM0ODhmZWM2OGFmZWM4OGNmZWNhOGRmZWNjOGZmZWNkOTBmZWNmOTJmZWQxOTRmZWQzOTVmZWQ1OTdmZWQ3OTlmZWQ4OWFmZGRhOWNmZGRjOWVmZGRlYTBmZGUwYTFmZGUyYTNmZGUzYTVmZGU1YTdmZGU3YTlmZGU5YWFmZGViYWNmY2VjYWVmY2VlYjBmY2YwYjJmY2YyYjRmY2Y0YjZmY2Y2YjhmY2Y3YjlmY2Y5YmJmY2ZiYmRmY2ZkYmZcIikpO1xuXG52YXIgaW5mZXJubyA9IHJhbXAkMShjb2xvcnMkMShcIjAwMDAwNDAxMDAwNTAxMDEwNjAxMDEwODAyMDEwYTAyMDIwYzAyMDIwZTAzMDIxMDA0MDMxMjA0MDMxNDA1MDQxNzA2MDQxOTA3MDUxYjA4MDUxZDA5MDYxZjBhMDcyMjBiMDcyNDBjMDgyNjBkMDgyOTBlMDkyYjEwMDkyZDExMGEzMDEyMGEzMjE0MGIzNDE1MGIzNzE2MGIzOTE4MGMzYzE5MGMzZTFiMGM0MTFjMGM0MzFlMGM0NTFmMGM0ODIxMGM0YTIzMGM0YzI0MGM0ZjI2MGM1MTI4MGI1MzI5MGI1NTJiMGI1NzJkMGI1OTJmMGE1YjMxMGE1YzMyMGE1ZTM0MGE1ZjM2MDk2MTM4MDk2MjM5MDk2MzNiMDk2NDNkMDk2NTNlMDk2NjQwMGE2NzQyMGE2ODQ0MGE2ODQ1MGE2OTQ3MGI2YTQ5MGI2YTRhMGM2YjRjMGM2YjRkMGQ2YzRmMGQ2YzUxMGU2YzUyMGU2ZDU0MGY2ZDU1MGY2ZDU3MTA2ZTU5MTA2ZTVhMTE2ZTVjMTI2ZTVkMTI2ZTVmMTM2ZTYxMTM2ZTYyMTQ2ZTY0MTU2ZTY1MTU2ZTY3MTY2ZTY5MTY2ZTZhMTc2ZTZjMTg2ZTZkMTg2ZTZmMTk2ZTcxMTk2ZTcyMWE2ZTc0MWE2ZTc1MWI2ZTc3MWM2ZDc4MWM2ZDdhMWQ2ZDdjMWQ2ZDdkMWU2ZDdmMWU2YzgwMWY2YzgyMjA2Yzg0MjA2Yjg1MjE2Yjg3MjE2Yjg4MjI2YThhMjI2YThjMjM2OThkMjM2OThmMjQ2OTkwMjU2ODkyMjU2ODkzMjY2Nzk1MjY2Nzk3Mjc2Njk4Mjc2NjlhMjg2NTliMjk2NDlkMjk2NDlmMmE2M2EwMmE2M2EyMmI2MmEzMmM2MWE1MmM2MGE2MmQ2MGE4MmU1ZmE5MmU1ZWFiMmY1ZWFkMzA1ZGFlMzA1Y2IwMzE1YmIxMzI1YWIzMzI1YWI0MzM1OWI2MzQ1OGI3MzU1N2I5MzU1NmJhMzY1NWJjMzc1NGJkMzg1M2JmMzk1MmMwM2E1MWMxM2E1MGMzM2I0ZmM0M2M0ZWM2M2Q0ZGM3M2U0Y2M4M2Y0YmNhNDA0YWNiNDE0OWNjNDI0OGNlNDM0N2NmNDQ0NmQwNDU0NWQyNDY0NGQzNDc0M2Q0NDg0MmQ1NGE0MWQ3NGIzZmQ4NGMzZWQ5NGQzZGRhNGUzY2RiNTAzYmRkNTEzYWRlNTIzOGRmNTMzN2UwNTUzNmUxNTYzNWUyNTczNGUzNTkzM2U0NWEzMWU1NWMzMGU2NWQyZmU3NWUyZWU4NjAyZGU5NjEyYmVhNjMyYWViNjQyOWViNjYyOGVjNjcyNmVkNjkyNWVlNmEyNGVmNmMyM2VmNmUyMWYwNmYyMGYxNzExZmYxNzMxZGYyNzQxY2YzNzYxYmYzNzgxOWY0NzkxOGY1N2IxN2Y1N2QxNWY2N2UxNGY2ODAxM2Y3ODIxMmY3ODQxMGY4ODUwZmY4ODcwZWY4ODkwY2Y5OGIwYmY5OGMwYWY5OGUwOWZhOTAwOGZhOTIwN2ZhOTQwN2ZiOTYwNmZiOTcwNmZiOTkwNmZiOWIwNmZiOWQwN2ZjOWYwN2ZjYTEwOGZjYTMwOWZjYTUwYWZjYTYwY2ZjYTgwZGZjYWEwZmZjYWMxMWZjYWUxMmZjYjAxNGZjYjIxNmZjYjQxOGZiYjYxYWZiYjgxZGZiYmExZmZiYmMyMWZiYmUyM2ZhYzAyNmZhYzIyOGZhYzQyYWZhYzYyZGY5YzcyZmY5YzkzMmY5Y2IzNWY4Y2QzN2Y4Y2YzYWY3ZDEzZGY3ZDM0MGY2ZDU0M2Y2ZDc0NmY1ZDk0OWY1ZGI0Y2Y0ZGQ0ZmY0ZGY1M2Y0ZTE1NmYzZTM1YWYzZTU1ZGYyZTY2MWYyZTg2NWYyZWE2OWYxZWM2ZGYxZWQ3MWYxZWY3NWYxZjE3OWYyZjI3ZGYyZjQ4MmYzZjU4NmYzZjY4YWY0Zjg4ZWY1Zjk5MmY2ZmE5NmY4ZmI5YWY5ZmM5ZGZhZmRhMWZjZmZhNFwiKSk7XG5cbnZhciBwbGFzbWEgPSByYW1wJDEoY29sb3JzJDEoXCIwZDA4ODcxMDA3ODgxMzA3ODkxNjA3OGExOTA2OGMxYjA2OGQxZDA2OGUyMDA2OGYyMjA2OTAyNDA2OTEyNjA1OTEyODA1OTIyYTA1OTMyYzA1OTQyZTA1OTUyZjA1OTYzMTA1OTczMzA1OTczNTA0OTgzNzA0OTkzODA0OWEzYTA0OWEzYzA0OWIzZTA0OWMzZjA0OWM0MTA0OWQ0MzAzOWU0NDAzOWU0NjAzOWY0ODAzOWY0OTAzYTA0YjAzYTE0YzAyYTE0ZTAyYTI1MDAyYTI1MTAyYTM1MzAyYTM1NTAyYTQ1NjAxYTQ1ODAxYTQ1OTAxYTU1YjAxYTU1YzAxYTY1ZTAxYTY2MDAxYTY2MTAwYTc2MzAwYTc2NDAwYTc2NjAwYTc2NzAwYTg2OTAwYTg2YTAwYTg2YzAwYTg2ZTAwYTg2ZjAwYTg3MTAwYTg3MjAxYTg3NDAxYTg3NTAxYTg3NzAxYTg3ODAxYTg3YTAyYTg3YjAyYTg3ZDAzYTg3ZTAzYTg4MDA0YTg4MTA0YTc4MzA1YTc4NDA1YTc4NjA2YTY4NzA3YTY4ODA4YTY4YTA5YTU4YjBhYTU4ZDBiYTU4ZTBjYTQ4ZjBkYTQ5MTBlYTM5MjBmYTM5NDEwYTI5NTExYTE5NjEzYTE5ODE0YTA5OTE1OWY5YTE2OWY5YzE3OWU5ZDE4OWQ5ZTE5OWRhMDFhOWNhMTFiOWJhMjFkOWFhMzFlOWFhNTFmOTlhNjIwOThhNzIxOTdhODIyOTZhYTIzOTVhYjI0OTRhYzI2OTRhZDI3OTNhZTI4OTJiMDI5OTFiMTJhOTBiMjJiOGZiMzJjOGViNDJlOGRiNTJmOGNiNjMwOGJiNzMxOGFiODMyODliYTMzODhiYjM0ODhiYzM1ODdiZDM3ODZiZTM4ODViZjM5ODRjMDNhODNjMTNiODJjMjNjODFjMzNkODBjNDNlN2ZjNTQwN2VjNjQxN2RjNzQyN2NjODQzN2JjOTQ0N2FjYTQ1N2FjYjQ2NzljYzQ3NzhjYzQ5NzdjZDRhNzZjZTRiNzVjZjRjNzRkMDRkNzNkMTRlNzJkMjRmNzFkMzUxNzFkNDUyNzBkNTUzNmZkNTU0NmVkNjU1NmRkNzU2NmNkODU3NmJkOTU4NmFkYTVhNmFkYTViNjlkYjVjNjhkYzVkNjdkZDVlNjZkZTVmNjVkZTYxNjRkZjYyNjNlMDYzNjNlMTY0NjJlMjY1NjFlMjY2NjBlMzY4NWZlNDY5NWVlNTZhNWRlNTZiNWRlNjZjNWNlNzZlNWJlNzZmNWFlODcwNTllOTcxNThlOTcyNTdlYTc0NTdlYjc1NTZlYjc2NTVlYzc3NTRlZDc5NTNlZDdhNTJlZTdiNTFlZjdjNTFlZjdlNTBmMDdmNGZmMDgwNGVmMTgxNGRmMTgzNGNmMjg0NGJmMzg1NGJmMzg3NGFmNDg4NDlmNDg5NDhmNThiNDdmNThjNDZmNjhkNDVmNjhmNDRmNzkwNDRmNzkxNDNmNzkzNDJmODk0NDFmODk1NDBmOTk3M2ZmOTk4M2VmOTlhM2VmYTliM2RmYTljM2NmYTllM2JmYjlmM2FmYmExMzlmYmEyMzhmY2EzMzhmY2E1MzdmY2E2MzZmY2E4MzVmY2E5MzRmZGFiMzNmZGFjMzNmZGFlMzJmZGFmMzFmZGIxMzBmZGIyMmZmZGI0MmZmZGI1MmVmZWI3MmRmZWI4MmNmZWJhMmNmZWJiMmJmZWJkMmFmZWJlMmFmZWMwMjlmZGMyMjlmZGMzMjhmZGM1MjdmZGM2MjdmZGM4MjdmZGNhMjZmZGNiMjZmY2NkMjVmY2NlMjVmY2QwMjVmY2QyMjVmYmQzMjRmYmQ1MjRmYmQ3MjRmYWQ4MjRmYWRhMjRmOWRjMjRmOWRkMjVmOGRmMjVmOGUxMjVmN2UyMjVmN2U0MjVmNmU2MjZmNmU4MjZmNWU5MjZmNWViMjdmNGVkMjdmM2VlMjdmM2YwMjdmMmYyMjdmMWY0MjZmMWY1MjVmMGY3MjRmMGY5MjFcIikpO1xuXG5cblxudmFyIF8gPSBPYmplY3QuZnJlZXplKHtcblx0c2NoZW1lQ2F0ZWdvcnkxMDogY2F0ZWdvcnkxMCxcblx0c2NoZW1lQWNjZW50OiBBY2NlbnQsXG5cdHNjaGVtZURhcmsyOiBEYXJrMixcblx0c2NoZW1lUGFpcmVkOiBQYWlyZWQsXG5cdHNjaGVtZVBhc3RlbDE6IFBhc3RlbDEsXG5cdHNjaGVtZVBhc3RlbDI6IFBhc3RlbDIsXG5cdHNjaGVtZVNldDE6IFNldDEsXG5cdHNjaGVtZVNldDI6IFNldDIsXG5cdHNjaGVtZVNldDM6IFNldDMsXG5cdGludGVycG9sYXRlQnJCRzogQnJCRyxcblx0c2NoZW1lQnJCRzogc2NoZW1lLFxuXHRpbnRlcnBvbGF0ZVBSR246IFBSR24sXG5cdHNjaGVtZVBSR246IHNjaGVtZSQxLFxuXHRpbnRlcnBvbGF0ZVBpWUc6IFBpWUcsXG5cdHNjaGVtZVBpWUc6IHNjaGVtZSQyLFxuXHRpbnRlcnBvbGF0ZVB1T3I6IFB1T3IsXG5cdHNjaGVtZVB1T3I6IHNjaGVtZSQzLFxuXHRpbnRlcnBvbGF0ZVJkQnU6IFJkQnUsXG5cdHNjaGVtZVJkQnU6IHNjaGVtZSQ0LFxuXHRpbnRlcnBvbGF0ZVJkR3k6IFJkR3ksXG5cdHNjaGVtZVJkR3k6IHNjaGVtZSQ1LFxuXHRpbnRlcnBvbGF0ZVJkWWxCdTogUmRZbEJ1LFxuXHRzY2hlbWVSZFlsQnU6IHNjaGVtZSQ2LFxuXHRpbnRlcnBvbGF0ZVJkWWxHbjogUmRZbEduLFxuXHRzY2hlbWVSZFlsR246IHNjaGVtZSQ3LFxuXHRpbnRlcnBvbGF0ZVNwZWN0cmFsOiBTcGVjdHJhbCxcblx0c2NoZW1lU3BlY3RyYWw6IHNjaGVtZSQ4LFxuXHRpbnRlcnBvbGF0ZUJ1R246IEJ1R24sXG5cdHNjaGVtZUJ1R246IHNjaGVtZSQ5LFxuXHRpbnRlcnBvbGF0ZUJ1UHU6IEJ1UHUsXG5cdHNjaGVtZUJ1UHU6IHNjaGVtZSQxMCxcblx0aW50ZXJwb2xhdGVHbkJ1OiBHbkJ1LFxuXHRzY2hlbWVHbkJ1OiBzY2hlbWUkMTEsXG5cdGludGVycG9sYXRlT3JSZDogT3JSZCxcblx0c2NoZW1lT3JSZDogc2NoZW1lJDEyLFxuXHRpbnRlcnBvbGF0ZVB1QnVHbjogUHVCdUduLFxuXHRzY2hlbWVQdUJ1R246IHNjaGVtZSQxMyxcblx0aW50ZXJwb2xhdGVQdUJ1OiBQdUJ1LFxuXHRzY2hlbWVQdUJ1OiBzY2hlbWUkMTQsXG5cdGludGVycG9sYXRlUHVSZDogUHVSZCxcblx0c2NoZW1lUHVSZDogc2NoZW1lJDE1LFxuXHRpbnRlcnBvbGF0ZVJkUHU6IFJkUHUsXG5cdHNjaGVtZVJkUHU6IHNjaGVtZSQxNixcblx0aW50ZXJwb2xhdGVZbEduQnU6IFlsR25CdSxcblx0c2NoZW1lWWxHbkJ1OiBzY2hlbWUkMTcsXG5cdGludGVycG9sYXRlWWxHbjogWWxHbixcblx0c2NoZW1lWWxHbjogc2NoZW1lJDE4LFxuXHRpbnRlcnBvbGF0ZVlsT3JCcjogWWxPckJyLFxuXHRzY2hlbWVZbE9yQnI6IHNjaGVtZSQxOSxcblx0aW50ZXJwb2xhdGVZbE9yUmQ6IFlsT3JSZCxcblx0c2NoZW1lWWxPclJkOiBzY2hlbWUkMjAsXG5cdGludGVycG9sYXRlQmx1ZXM6IEJsdWVzLFxuXHRzY2hlbWVCbHVlczogc2NoZW1lJDIxLFxuXHRpbnRlcnBvbGF0ZUdyZWVuczogR3JlZW5zLFxuXHRzY2hlbWVHcmVlbnM6IHNjaGVtZSQyMixcblx0aW50ZXJwb2xhdGVHcmV5czogR3JleXMsXG5cdHNjaGVtZUdyZXlzOiBzY2hlbWUkMjMsXG5cdGludGVycG9sYXRlUHVycGxlczogUHVycGxlcyxcblx0c2NoZW1lUHVycGxlczogc2NoZW1lJDI0LFxuXHRpbnRlcnBvbGF0ZVJlZHM6IFJlZHMsXG5cdHNjaGVtZVJlZHM6IHNjaGVtZSQyNSxcblx0aW50ZXJwb2xhdGVPcmFuZ2VzOiBPcmFuZ2VzLFxuXHRzY2hlbWVPcmFuZ2VzOiBzY2hlbWUkMjYsXG5cdGludGVycG9sYXRlQ3ViZWhlbGl4RGVmYXVsdDogY3ViZWhlbGl4JDMsXG5cdGludGVycG9sYXRlUmFpbmJvdzogcmFpbmJvdyQxLFxuXHRpbnRlcnBvbGF0ZVdhcm06IHdhcm0sXG5cdGludGVycG9sYXRlQ29vbDogY29vbCxcblx0aW50ZXJwb2xhdGVWaXJpZGlzOiB2aXJpZGlzLFxuXHRpbnRlcnBvbGF0ZU1hZ21hOiBtYWdtYSxcblx0aW50ZXJwb2xhdGVJbmZlcm5vOiBpbmZlcm5vLFxuXHRpbnRlcnBvbGF0ZVBsYXNtYTogcGxhc21hXG59KTtcblxudmFyIGRpc2NyZXRlID0ge1xuICBibHVlb3JhbmdlOiAgYmx1ZU9yYW5nZVxufTtcblxudmFyIHNjaGVtZXMgPSB7XG4gIC8vIGQzIGNhdGVnb3JpY2FsIHBhbGV0dGVzXG4gIGNhdGVnb3J5MTA6ICBjYXRlZ29yeTEwLFxuICBhY2NlbnQ6ICAgICAgQWNjZW50LFxuICBkYXJrMjogICAgICAgRGFyazIsXG4gIHBhaXJlZDogICAgICBQYWlyZWQsXG4gIHBhc3RlbDE6ICAgICBQYXN0ZWwxLFxuICBwYXN0ZWwyOiAgICAgUGFzdGVsMixcbiAgc2V0MTogICAgICAgIFNldDEsXG4gIHNldDI6ICAgICAgICBTZXQyLFxuICBzZXQzOiAgICAgICAgU2V0MyxcblxuICAvLyBhZGRpdGlvbmFsIGNhdGVnb3JpY2FsIHBhbGV0dGVzXG4gIGNhdGVnb3J5MjA6ICBjYXRlZ29yeTIwLFxuICBjYXRlZ29yeTIwYjogY2F0ZWdvcnkyMGIsXG4gIGNhdGVnb3J5MjBjOiBjYXRlZ29yeTIwYyxcbiAgdGFibGVhdTEwOiAgIHRhYmxlYXUxMCxcbiAgdGFibGVhdTIwOiAgIHRhYmxlYXUyMCxcblxuICAvLyBzZXF1ZW50aWFsIG11bHRpLWh1ZSBpbnRlcnBvbGF0b3JzXG4gIHZpcmlkaXM6ICAgICB2aXJpZGlzLFxuICBtYWdtYTogICAgICAgbWFnbWEsXG4gIGluZmVybm86ICAgICBpbmZlcm5vLFxuICBwbGFzbWE6ICAgICAgcGxhc21hLFxuXG4gIC8vIGV4dGVuZGVkIGludGVycG9sYXRvcnNcbiAgYmx1ZW9yYW5nZTogIHJnYkJhc2lzKHBlZWsoYmx1ZU9yYW5nZSkpXG59O1xuXG5mdW5jdGlvbiBhZGQkMihuYW1lLCBzdWZmaXgpIHtcbiAgc2NoZW1lc1tuYW1lXSA9IF9bJ2ludGVycG9sYXRlJyArIHN1ZmZpeF07XG4gIGRpc2NyZXRlW25hbWVdID0gX1snc2NoZW1lJyArIHN1ZmZpeF07XG59XG5cbi8vIHNlcXVlbnRpYWwgc2luZ2xlLWh1ZVxuYWRkJDIoJ2JsdWVzJywgICAgJ0JsdWVzJyk7XG5hZGQkMignZ3JlZW5zJywgICAnR3JlZW5zJyk7XG5hZGQkMignZ3JleXMnLCAgICAnR3JleXMnKTtcbmFkZCQyKCdwdXJwbGVzJywgICdQdXJwbGVzJyk7XG5hZGQkMigncmVkcycsICAgICAnUmVkcycpO1xuYWRkJDIoJ29yYW5nZXMnLCAgJ09yYW5nZXMnKTtcblxuLy8gZGl2ZXJnaW5nXG5hZGQkMignYnJvd25ibHVlZ3JlZW4nLCAgICAnQnJCRycpO1xuYWRkJDIoJ3B1cnBsZWdyZWVuJywgICAgICAgJ1BSR24nKTtcbmFkZCQyKCdwaW5reWVsbG93Z3JlZW4nLCAgICdQaVlHJyk7XG5hZGQkMigncHVycGxlb3JhbmdlJywgICAgICAnUHVPcicpO1xuYWRkJDIoJ3JlZGJsdWUnLCAgICAgICAgICAgJ1JkQnUnKTtcbmFkZCQyKCdyZWRncmV5JywgICAgICAgICAgICdSZEd5Jyk7XG5hZGQkMigncmVkeWVsbG93Ymx1ZScsICAgICAnUmRZbEJ1Jyk7XG5hZGQkMigncmVkeWVsbG93Z3JlZW4nLCAgICAnUmRZbEduJyk7XG5hZGQkMignc3BlY3RyYWwnLCAgICAgICAgICAnU3BlY3RyYWwnKTtcblxuLy8gc2VxdWVudGlhbCBtdWx0aS1odWVcbmFkZCQyKCdibHVlZ3JlZW4nLCAgICAgICAgICdCdUduJyk7XG5hZGQkMignYmx1ZXB1cnBsZScsICAgICAgICAnQnVQdScpO1xuYWRkJDIoJ2dyZWVuYmx1ZScsICAgICAgICAgJ0duQnUnKTtcbmFkZCQyKCdvcmFuZ2VyZWQnLCAgICAgICAgICdPclJkJyk7XG5hZGQkMigncHVycGxlYmx1ZWdyZWVuJywgICAnUHVCdUduJyk7XG5hZGQkMigncHVycGxlYmx1ZScsICAgICAgICAnUHVCdScpO1xuYWRkJDIoJ3B1cnBsZXJlZCcsICAgICAgICAgJ1B1UmQnKTtcbmFkZCQyKCdyZWRwdXJwbGUnLCAgICAgICAgICdSZFB1Jyk7XG5hZGQkMigneWVsbG93Z3JlZW5ibHVlJywgICAnWWxHbkJ1Jyk7XG5hZGQkMigneWVsbG93Z3JlZW4nLCAgICAgICAnWWxHbicpO1xuYWRkJDIoJ3llbGxvd29yYW5nZWJyb3duJywgJ1lsT3JCcicpO1xuYWRkJDIoJ3llbGxvd29yYW5nZXJlZCcsICAgJ1lsT3JSZCcpO1xuXG52YXIgZ2V0U2NoZW1lID0gZnVuY3Rpb24obmFtZSwgc2NoZW1lJCQxKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID4gMSkge1xuICAgIHNjaGVtZXNbbmFtZV0gPSBzY2hlbWUkJDE7XG4gICAgcmV0dXJuIHRoaXM7XG4gIH1cblxuICB2YXIgcGFydCA9IG5hbWUuc3BsaXQoJy0nKTtcbiAgbmFtZSA9IHBhcnRbMF07XG4gIHBhcnQgPSArcGFydFsxXSArIDE7XG5cbiAgcmV0dXJuIHBhcnQgJiYgZGlzY3JldGUuaGFzT3duUHJvcGVydHkobmFtZSkgPyBkaXNjcmV0ZVtuYW1lXVtwYXJ0LTFdXG4gICAgOiAhcGFydCAmJiBzY2hlbWVzLmhhc093blByb3BlcnR5KG5hbWUpID8gc2NoZW1lc1tuYW1lXVxuICAgIDogdW5kZWZpbmVkO1xufTtcblxuZnVuY3Rpb24gaW50ZXJwb2xhdGVSYW5nZShpbnRlcnBvbGF0b3IsIHJhbmdlKSB7XG4gIHZhciBzdGFydCA9IHJhbmdlWzBdLFxuICAgICAgc3BhbiA9IHBlZWsocmFuZ2UpIC0gc3RhcnQ7XG4gIHJldHVybiBmdW5jdGlvbihpKSB7IHJldHVybiBpbnRlcnBvbGF0b3Ioc3RhcnQgKyBpICogc3Bhbik7IH07XG59XG5cbmZ1bmN0aW9uIHNjYWxlRnJhY3Rpb24oc2NhbGUsIG1pbiwgbWF4KSB7XG4gIHZhciBkZWx0YSA9IG1heCAtIG1pbjtcbiAgcmV0dXJuICFkZWx0YSA/IGNvbnN0YW50KDApXG4gICAgOiBzY2FsZS50eXBlID09PSAnbGluZWFyJyB8fCBzY2FsZS50eXBlID09PSAnc2VxdWVudGlhbCdcbiAgICAgID8gZnVuY3Rpb24oXykgeyByZXR1cm4gKF8gLSBtaW4pIC8gZGVsdGE7IH1cbiAgICAgIDogc2NhbGUuY29weSgpLmRvbWFpbihbbWluLCBtYXhdKS5yYW5nZShbMCwgMV0pLmludGVycG9sYXRlKGxlcnApO1xufVxuXG5mdW5jdGlvbiBsZXJwKGEsIGIpIHtcbiAgdmFyIHNwYW4gPSBiIC0gYTtcbiAgcmV0dXJuIGZ1bmN0aW9uKGkpIHsgcmV0dXJuIGEgKyBpICogc3BhbjsgfVxufVxuXG5mdW5jdGlvbiBpbnRlcnBvbGF0ZSQxKHR5cGUsIGdhbW1hKSB7XG4gIHZhciBpbnRlcnAgPSAkJDFbbWV0aG9kKHR5cGUpXTtcbiAgcmV0dXJuIChnYW1tYSAhPSBudWxsICYmIGludGVycCAmJiBpbnRlcnAuZ2FtbWEpXG4gICAgPyBpbnRlcnAuZ2FtbWEoZ2FtbWEpXG4gICAgOiBpbnRlcnA7XG59XG5cbmZ1bmN0aW9uIG1ldGhvZCh0eXBlKSB7XG4gIHJldHVybiAnaW50ZXJwb2xhdGUnICsgdHlwZS50b0xvd2VyQ2FzZSgpXG4gICAgLnNwbGl0KCctJylcbiAgICAubWFwKGZ1bmN0aW9uKHMpIHsgcmV0dXJuIHNbMF0udG9VcHBlckNhc2UoKSArIHMuc2xpY2UoMSk7IH0pXG4gICAgLmpvaW4oJycpO1xufVxuXG52YXIgdGltZSQxID0ge1xuICBtaWxsaXNlY29uZDogbWlsbGlzZWNvbmQsXG4gIHNlY29uZDogICAgICBzZWNvbmQsXG4gIG1pbnV0ZTogICAgICBtaW51dGUsXG4gIGhvdXI6ICAgICAgICBob3VyLFxuICBkYXk6ICAgICAgICAgZGF5LFxuICB3ZWVrOiAgICAgICAgc3VuZGF5LFxuICBtb250aDogICAgICAgbW9udGgsXG4gIHllYXI6ICAgICAgICB5ZWFyXG59O1xuXG52YXIgdXRjID0ge1xuICBtaWxsaXNlY29uZDogbWlsbGlzZWNvbmQsXG4gIHNlY29uZDogICAgICBzZWNvbmQsXG4gIG1pbnV0ZTogICAgICB1dGNNaW51dGUsXG4gIGhvdXI6ICAgICAgICB1dGNIb3VyLFxuICBkYXk6ICAgICAgICAgdXRjRGF5LFxuICB3ZWVrOiAgICAgICAgdXRjU3VuZGF5LFxuICBtb250aDogICAgICAgdXRjTW9udGgsXG4gIHllYXI6ICAgICAgICB1dGNZZWFyXG59O1xuXG5mdW5jdGlvbiB0aW1lSW50ZXJ2YWwobmFtZSkge1xuICByZXR1cm4gdGltZSQxLmhhc093blByb3BlcnR5KG5hbWUpICYmIHRpbWUkMVtuYW1lXTtcbn1cblxuZnVuY3Rpb24gdXRjSW50ZXJ2YWwobmFtZSkge1xuICByZXR1cm4gdXRjLmhhc093blByb3BlcnR5KG5hbWUpICYmIHV0Y1tuYW1lXTtcbn1cblxuLyoqXG4gKiBEZXRlcm1pbmUgdGhlIHRpY2sgY291bnQgb3IgaW50ZXJ2YWwgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge1NjYWxlfSBzY2FsZSAtIFRoZSBzY2FsZSBmb3Igd2hpY2ggdG8gZ2VuZXJhdGUgdGljayB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IGNvdW50IC0gVGhlIGRlc2lyZWQgdGljayBjb3VudCBvciBpbnRlcnZhbCBzcGVjaWZpZXIuXG4gKiBAcmV0dXJuIHsqfSAtIFRoZSB0aWNrIGNvdW50IG9yIGludGVydmFsIGZ1bmN0aW9uLlxuICovXG5mdW5jdGlvbiB0aWNrQ291bnQoc2NhbGUkJDEsIGNvdW50KSB7XG4gIHZhciBzdGVwO1xuXG4gIGlmIChpc09iamVjdChjb3VudCkpIHtcbiAgICBzdGVwID0gY291bnQuc3RlcDtcbiAgICBjb3VudCA9IGNvdW50LmludGVydmFsO1xuICB9XG5cbiAgaWYgKGlzU3RyaW5nKGNvdW50KSkge1xuICAgIGNvdW50ID0gc2NhbGUkJDEudHlwZSA9PT0gJ3RpbWUnID8gdGltZUludGVydmFsKGNvdW50KVxuICAgICAgOiBzY2FsZSQkMS50eXBlID09PSAndXRjJyA/IHV0Y0ludGVydmFsKGNvdW50KVxuICAgICAgOiBlcnJvciQxKCdPbmx5IHRpbWUgYW5kIHV0YyBzY2FsZXMgYWNjZXB0IGludGVydmFsIHN0cmluZ3MuJyk7XG4gICAgaWYgKHN0ZXApIGNvdW50ID0gY291bnQuZXZlcnkoc3RlcCk7XG4gIH1cblxuICByZXR1cm4gY291bnQ7XG59XG5cbi8qKlxuICogRmlsdGVyIGEgc2V0IG9mIGNhbmRpZGF0ZSB0aWNrIHZhbHVlcywgZW5zdXJpbmcgdGhhdCBvbmx5IHRpY2sgdmFsdWVzXG4gKiB0aGF0IGxpZSB3aXRoaW4gdGhlIHNjYWxlIHJhbmdlIGFyZSBpbmNsdWRlZC5cbiAqIEBwYXJhbSB7U2NhbGV9IHNjYWxlIC0gVGhlIHNjYWxlIGZvciB3aGljaCB0byBnZW5lcmF0ZSB0aWNrIHZhbHVlcy5cbiAqIEBwYXJhbSB7QXJyYXk8Kj59IHRpY2tzIC0gVGhlIGNhbmRpZGF0ZSB0aWNrIHZhbHVlcy5cbiAqIEBwYXJhbSB7Kn0gY291bnQgLSBUaGUgdGljayBjb3VudCBvciBpbnRlcnZhbCBmdW5jdGlvbi5cbiAqIEByZXR1cm4ge0FycmF5PCo+fSAtIFRoZSBmaWx0ZXJlZCB0aWNrIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gdmFsaWRUaWNrcyhzY2FsZSQkMSwgdGlja3MsIGNvdW50KSB7XG4gIHZhciByYW5nZSA9IHNjYWxlJCQxLnJhbmdlKCksXG4gICAgICBsbyA9IHJhbmdlWzBdLFxuICAgICAgaGkgPSBwZWVrKHJhbmdlKTtcbiAgaWYgKGxvID4gaGkpIHtcbiAgICByYW5nZSA9IGhpO1xuICAgIGhpID0gbG87XG4gICAgbG8gPSByYW5nZTtcbiAgfVxuXG4gIHRpY2tzID0gdGlja3MuZmlsdGVyKGZ1bmN0aW9uKHYpIHtcbiAgICB2ID0gc2NhbGUkJDEodik7XG4gICAgcmV0dXJuICEodiA8IGxvIHx8IHYgPiBoaSlcbiAgfSk7XG5cbiAgaWYgKGNvdW50ID4gMCAmJiB0aWNrcy5sZW5ndGggPiAxKSB7XG4gICAgdmFyIGVuZHBvaW50cyA9IFt0aWNrc1swXSwgcGVlayh0aWNrcyldO1xuICAgIHdoaWxlICh0aWNrcy5sZW5ndGggPiBjb3VudCAmJiB0aWNrcy5sZW5ndGggPj0gMykge1xuICAgICAgdGlja3MgPSB0aWNrcy5maWx0ZXIoZnVuY3Rpb24oXywgaSkgeyByZXR1cm4gIShpICUgMik7IH0pO1xuICAgIH1cbiAgICBpZiAodGlja3MubGVuZ3RoIDwgMykge1xuICAgICAgdGlja3MgPSBlbmRwb2ludHM7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIHRpY2tzO1xufVxuXG4vKipcbiAqIEdlbmVyYXRlIHRpY2sgdmFsdWVzIGZvciB0aGUgZ2l2ZW4gc2NhbGUgYW5kIGFwcHJveGltYXRlIHRpY2sgY291bnQgb3JcbiAqIGludGVydmFsIHZhbHVlLiBJZiB0aGUgc2NhbGUgaGFzIGEgJ3RpY2tzJyBtZXRob2QsIGl0IHdpbGwgYmUgdXNlZCB0b1xuICogZ2VuZXJhdGUgdGhlIHRpY2tzLCB3aXRoIHRoZSBjb3VudCBhcmd1bWVudCBwYXNzZWQgYXMgYSBwYXJhbWV0ZXIuIElmIHRoZVxuICogc2NhbGUgbGFja3MgYSAndGlja3MnIG1ldGhvZCwgdGhlIGZ1bGwgc2NhbGUgZG9tYWluIHdpbGwgYmUgcmV0dXJuZWQuXG4gKiBAcGFyYW0ge1NjYWxlfSBzY2FsZSAtIFRoZSBzY2FsZSBmb3Igd2hpY2ggdG8gZ2VuZXJhdGUgdGljayB2YWx1ZXMuXG4gKiBAcGFyYW0geyp9IFtjb3VudF0gLSBUaGUgYXBwcm94aW1hdGUgbnVtYmVyIG9mIGRlc2lyZWQgdGlja3MuXG4gKiBAcmV0dXJuIHtBcnJheTwqPn0gLSBUaGUgZ2VuZXJhdGVkIHRpY2sgdmFsdWVzLlxuICovXG5mdW5jdGlvbiB0aWNrVmFsdWVzKHNjYWxlJCQxLCBjb3VudCkge1xuICByZXR1cm4gc2NhbGUkJDEudGlja3MgPyBzY2FsZSQkMS50aWNrcyhjb3VudCkgOiBzY2FsZSQkMS5kb21haW4oKTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZSBhIGxhYmVsIGZvcm1hdCBmdW5jdGlvbiBmb3IgYSBzY2FsZS4gSWYgdGhlIHNjYWxlIGhhcyBhXG4gKiAndGlja0Zvcm1hdCcgbWV0aG9kLCBpdCB3aWxsIGJlIHVzZWQgdG8gZ2VuZXJhdGUgdGhlIGZvcm1hdHRlciwgd2l0aCB0aGVcbiAqIGNvdW50IGFuZCBzcGVjaWZpZXIgYXJndW1lbnRzIHBhc3NlZCBhcyBwYXJhbWV0ZXJzLiBJZiB0aGUgc2NhbGUgbGFja3MgYVxuICogJ3RpY2tGb3JtYXQnIG1ldGhvZCwgdGhlIHJldHVybmVkIGZvcm1hdHRlciBwZXJmb3JtcyBzaW1wbGUgc3RyaW5nIGNvZXJjaW9uLlxuICogSWYgdGhlIGlucHV0IHNjYWxlIGlzIGEgbG9nYXJpdGhtaWMgc2NhbGUgYW5kIHRoZSBmb3JtYXQgc3BlY2lmaWVyIGRvZXMgbm90XG4gKiBpbmRpY2F0ZSBhIGRlc2lyZWQgZGVjaW1hbCBwcmVjaXNpb24sIGEgc3BlY2lhbCB2YXJpYWJsZSBwcmVjaXNpb24gZm9ybWF0dGVyXG4gKiB0aGF0IGF1dG9tYXRpY2FsbHkgdHJpbXMgdHJhaWxpbmcgemVyb2VzIHdpbGwgYmUgZ2VuZXJhdGVkLlxuICogQHBhcmFtIHtTY2FsZX0gc2NhbGUgLSBUaGUgc2NhbGUgZm9yIHdoaWNoIHRvIGdlbmVyYXRlIHRoZSBsYWJlbCBmb3JtYXR0ZXIuXG4gKiBAcGFyYW0geyp9IFtjb3VudF0gLSBUaGUgYXBwcm94aW1hdGUgbnVtYmVyIG9mIGRlc2lyZWQgdGlja3MuXG4gKiBAcGFyYW0ge3N0cmluZ30gW3NwZWNpZmllcl0gLSBUaGUgZm9ybWF0IHNwZWNpZmllci4gTXVzdCBiZSBhIGxlZ2FsIGQzIDQuMFxuICogICBzcGVjaWZpZXIgc3RyaW5nIChzZWUgaHR0cHM6Ly9naXRodWIuY29tL2QzL2QzLWZvcm1hdCNmb3JtYXRTcGVjaWZpZXIpLlxuICogQHJldHVybiB7ZnVuY3Rpb24oKik6c3RyaW5nfSAtIFRoZSBnZW5lcmF0ZWQgbGFiZWwgZm9ybWF0dGVyLlxuICovXG5mdW5jdGlvbiB0aWNrRm9ybWF0KHNjYWxlJCQxLCBjb3VudCwgc3BlY2lmaWVyKSB7XG4gIHZhciBmb3JtYXQkJDEgPSBzY2FsZSQkMS50aWNrRm9ybWF0XG4gICAgPyBzY2FsZSQkMS50aWNrRm9ybWF0KGNvdW50LCBzcGVjaWZpZXIpXG4gICAgOiBTdHJpbmc7XG5cbiAgcmV0dXJuIChzY2FsZSQkMS50eXBlID09PSBMb2cpXG4gICAgPyBmaWx0ZXIkMShmb3JtYXQkJDEsIHZhcmlhYmxlUHJlY2lzaW9uKHNwZWNpZmllcikpXG4gICAgOiBmb3JtYXQkJDE7XG59XG5cbmZ1bmN0aW9uIGZpbHRlciQxKHNvdXJjZUZvcm1hdCwgdGFyZ2V0Rm9ybWF0KSB7XG4gIHJldHVybiBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIHNvdXJjZUZvcm1hdChfKSA/IHRhcmdldEZvcm1hdChfKSA6ICcnO1xuICB9O1xufVxuXG5mdW5jdGlvbiB2YXJpYWJsZVByZWNpc2lvbihzcGVjaWZpZXIpIHtcbiAgdmFyIHMgPSBmb3JtYXRTcGVjaWZpZXIoc3BlY2lmaWVyIHx8ICcsJyk7XG5cbiAgaWYgKHMucHJlY2lzaW9uID09IG51bGwpIHtcbiAgICBzLnByZWNpc2lvbiA9IDEyO1xuICAgIHN3aXRjaCAocy50eXBlKSB7XG4gICAgICBjYXNlICclJzogcy5wcmVjaXNpb24gLT0gMjsgYnJlYWs7XG4gICAgICBjYXNlICdlJzogcy5wcmVjaXNpb24gLT0gMTsgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiB0cmltWmVyb2VzKFxuICAgICAgZm9ybWF0KHMpLCAgICAgICAgICAvLyBudW1iZXIgZm9ybWF0XG4gICAgICBmb3JtYXQoJy4xZicpKDEpWzFdIC8vIGRlY2ltYWwgcG9pbnQgY2hhcmFjdGVyXG4gICAgKTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gZm9ybWF0KHMpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHRyaW1aZXJvZXMoZm9ybWF0JCQxLCBkZWNpbWFsQ2hhcikge1xuICByZXR1cm4gZnVuY3Rpb24oeCkge1xuICAgIHZhciBzdHIgPSBmb3JtYXQkJDEoeCksXG4gICAgICAgIGRlYyA9IHN0ci5pbmRleE9mKGRlY2ltYWxDaGFyKSxcbiAgICAgICAgaWR4LCBlbmQ7XG5cbiAgICBpZiAoZGVjIDwgMCkgcmV0dXJuIHN0cjtcblxuICAgIGlkeCA9IHJpZ2h0bW9zdERpZ2l0KHN0ciwgZGVjKTtcbiAgICBlbmQgPSBpZHggPCBzdHIubGVuZ3RoID8gc3RyLnNsaWNlKGlkeCkgOiAnJztcbiAgICB3aGlsZSAoLS1pZHggPiBkZWMpIGlmIChzdHJbaWR4XSAhPT0gJzAnKSB7ICsraWR4OyBicmVhazsgfVxuXG4gICAgcmV0dXJuIHN0ci5zbGljZSgwLCBpZHgpICsgZW5kO1xuICB9O1xufVxuXG5mdW5jdGlvbiByaWdodG1vc3REaWdpdChzdHIsIGRlYykge1xuICB2YXIgaSA9IHN0ci5sYXN0SW5kZXhPZignZScpLCBjO1xuICBpZiAoaSA+IDApIHJldHVybiBpO1xuICBmb3IgKGk9c3RyLmxlbmd0aDsgLS1pID4gZGVjOykge1xuICAgIGMgPSBzdHIuY2hhckNvZGVBdChpKTtcbiAgICBpZiAoYyA+PSA0OCAmJiBjIDw9IDU3KSByZXR1cm4gaSArIDE7IC8vIGlzIGRpZ2l0XG4gIH1cbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYXhpcyB0aWNrcyBmb3IgdmlzdWFsaXppbmcgYSBzcGF0aWFsIHNjYWxlLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge1NjYWxlfSBwYXJhbXMuc2NhbGUgLSBUaGUgc2NhbGUgdG8gZ2VuZXJhdGUgdGlja3MgZm9yLlxuICogQHBhcmFtIHsqfSBbcGFyYW1zLmNvdW50PTEwXSAtIFRoZSBhcHByb3hpbWF0ZSBudW1iZXIgb2YgdGlja3MsIG9yXG4gKiAgIGRlc2lyZWQgdGljayBpbnRlcnZhbCwgdG8gdXNlLlxuICogQHBhcmFtIHtBcnJheTwqPn0gW3BhcmFtcy52YWx1ZXNdIC0gVGhlIGV4YWN0IHRpY2sgdmFsdWVzIHRvIHVzZS5cbiAqICAgVGhlc2UgbXVzdCBiZSBsZWdhbCBkb21haW4gdmFsdWVzIGZvciB0aGUgcHJvdmlkZWQgc2NhbGUuXG4gKiAgIElmIHByb3ZpZGVkLCB0aGUgY291bnQgYXJndW1lbnQgaXMgaWdub3JlZC5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oKik6c3RyaW5nfSBbcGFyYW1zLmZvcm1hdFNwZWNpZmllcl0gLSBBIGZvcm1hdCBzcGVjaWZpZXJcbiAqICAgdG8gdXNlIGluIGNvbmp1bmN0aW9uIHdpdGggc2NhbGUudGlja0Zvcm1hdC4gTGVnYWwgdmFsdWVzIGFyZVxuICogICBhbnkgdmFsaWQgZDMgNC4wIGZvcm1hdCBzcGVjaWZpZXIuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCopOnN0cmluZ30gW3BhcmFtcy5mb3JtYXRdIC0gVGhlIGZvcm1hdCBmdW5jdGlvbiB0byB1c2UuXG4gKiAgIElmIHByb3ZpZGVkLCB0aGUgZm9ybWF0U3BlY2lmaWVyIGFyZ3VtZW50IGlzIGlnbm9yZWQuXG4gKi9cbmZ1bmN0aW9uIEF4aXNUaWNrcyhwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ1NCA9IGluaGVyaXRzKEF4aXNUaWNrcywgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDU0LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGlmICh0aGlzLnZhbHVlICYmICFfLm1vZGlmaWVkKCkpIHtcbiAgICByZXR1cm4gcHVsc2UuU3RvcFByb3BhZ2F0aW9uO1xuICB9XG5cbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKSxcbiAgICAgIHRpY2tzID0gdGhpcy52YWx1ZSxcbiAgICAgIHNjYWxlID0gXy5zY2FsZSxcbiAgICAgIGNvdW50ID0gXy5jb3VudCA9PSBudWxsID8gKF8udmFsdWVzID8gXy52YWx1ZXMubGVuZ3RoIDogMTApIDogdGlja0NvdW50KHNjYWxlLCBfLmNvdW50KSxcbiAgICAgIGZvcm1hdCA9IF8uZm9ybWF0IHx8IHRpY2tGb3JtYXQoc2NhbGUsIGNvdW50LCBfLmZvcm1hdFNwZWNpZmllciksXG4gICAgICB2YWx1ZXMgPSBfLnZhbHVlcyA/IHZhbGlkVGlja3Moc2NhbGUsIF8udmFsdWVzLCBjb3VudCkgOiB0aWNrVmFsdWVzKHNjYWxlLCBjb3VudCk7XG5cbiAgaWYgKHRpY2tzKSBvdXQucmVtID0gdGlja3M7XG5cbiAgdGlja3MgPSB2YWx1ZXMubWFwKGZ1bmN0aW9uKHZhbHVlLCBpKSB7XG4gICAgcmV0dXJuIGluZ2VzdCh7XG4gICAgICBpbmRleDogaSAvICh2YWx1ZXMubGVuZ3RoIC0gMSksXG4gICAgICB2YWx1ZTogdmFsdWUsXG4gICAgICBsYWJlbDogZm9ybWF0KHZhbHVlKVxuICAgIH0pO1xuICB9KTtcblxuICBpZiAoXy5leHRyYSkge1xuICAgIC8vIGFkZCBhbiBleHRyYSB0aWNrIHBlZ2dlZCB0byB0aGUgaW5pdGlhbCBkb21haW4gdmFsdWVcbiAgICAvLyB0aGlzIGlzIHVzZWQgdG8gZ2VuZXJhdGUgYXhlcyB3aXRoICdiaW5uZWQnIGRvbWFpbnNcbiAgICB0aWNrcy5wdXNoKGluZ2VzdCh7XG4gICAgICBpbmRleDogLTEsXG4gICAgICBleHRyYToge3ZhbHVlOiB0aWNrc1swXS52YWx1ZX0sXG4gICAgICBsYWJlbDogJydcbiAgICB9KSk7XG4gIH1cblxuICBvdXQuc291cmNlID0gdGlja3M7XG4gIG91dC5hZGQgPSB0aWNrcztcbiAgdGhpcy52YWx1ZSA9IHRpY2tzO1xuXG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEpvaW5zIGEgc2V0IG9mIGRhdGEgZWxlbWVudHMgYWdhaW5zdCBhIHNldCBvZiB2aXN1YWwgaXRlbXMuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogb2JqZWN0fSBbcGFyYW1zLml0ZW1dIC0gQW4gaXRlbSBnZW5lcmF0b3IgZnVuY3Rpb24uXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IFtwYXJhbXMua2V5XSAtIFRoZSBrZXkgZmllbGQgYXNzb2NpYXRpbmcgZGF0YSBhbmQgdmlzdWFsIGl0ZW1zLlxuICovXG5mdW5jdGlvbiBEYXRhSm9pbihwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ1NSA9IGluaGVyaXRzKERhdGFKb2luLCBUcmFuc2Zvcm0pO1xuXG5mdW5jdGlvbiBkZWZhdWx0SXRlbUNyZWF0ZSgpIHtcbiAgcmV0dXJuIGluZ2VzdCh7fSk7XG59XG5cbmZ1bmN0aW9uIGlzRXhpdCh0KSB7XG4gIHJldHVybiB0LmV4aXQ7XG59XG5cbnByb3RvdHlwZSQ1NS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgZGYgPSBwdWxzZS5kYXRhZmxvdyxcbiAgICAgIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKSxcbiAgICAgIGl0ZW0gPSBfLml0ZW0gfHwgZGVmYXVsdEl0ZW1DcmVhdGUsXG4gICAgICBrZXkkJDEgPSBfLmtleSB8fCB0dXBsZWlkLFxuICAgICAgbWFwID0gdGhpcy52YWx1ZTtcblxuICAvLyBwcmV2ZW50IHRyYW5zaWVudCAoZS5nLiwgaG92ZXIpIHJlcXVlc3RzIGZyb21cbiAgLy8gY2FzY2FkaW5nIGFjcm9zcyBtYXJrcyBkZXJpdmVkIGZyb20gbWFya3NcbiAgaWYgKGlzQXJyYXkob3V0LmVuY29kZSkpIHtcbiAgICBvdXQuZW5jb2RlID0gbnVsbDtcbiAgfVxuXG4gIGlmIChtYXAgJiYgKF8ubW9kaWZpZWQoJ2tleScpIHx8IHB1bHNlLm1vZGlmaWVkKGtleSQkMSkpKSB7XG4gICAgZXJyb3IkMSgnRGF0YUpvaW4gZG9lcyBub3Qgc3VwcG9ydCBtb2RpZmllZCBrZXkgZnVuY3Rpb24gb3IgZmllbGRzLicpO1xuICB9XG5cbiAgaWYgKCFtYXApIHtcbiAgICBwdWxzZSA9IHB1bHNlLmFkZEFsbCgpO1xuICAgIHRoaXMudmFsdWUgPSBtYXAgPSBmYXN0bWFwKCkudGVzdChpc0V4aXQpO1xuICAgIG1hcC5sb29rdXAgPSBmdW5jdGlvbih0KSB7IHJldHVybiBtYXAuZ2V0KGtleSQkMSh0KSk7IH07XG4gIH1cblxuICBwdWxzZS52aXNpdChwdWxzZS5BREQsIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgayA9IGtleSQkMSh0KSxcbiAgICAgICAgeCA9IG1hcC5nZXQoayk7XG5cbiAgICBpZiAoeCkge1xuICAgICAgaWYgKHguZXhpdCkge1xuICAgICAgICBtYXAuZW1wdHktLTtcbiAgICAgICAgb3V0LmFkZC5wdXNoKHgpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgb3V0Lm1vZC5wdXNoKHgpO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBtYXAuc2V0KGssICh4ID0gaXRlbSh0KSkpO1xuICAgICAgb3V0LmFkZC5wdXNoKHgpO1xuICAgIH1cblxuICAgIHguZGF0dW0gPSB0O1xuICAgIHguZXhpdCA9IGZhbHNlO1xuICB9KTtcblxuICBwdWxzZS52aXNpdChwdWxzZS5NT0QsIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgayA9IGtleSQkMSh0KSxcbiAgICAgICAgeCA9IG1hcC5nZXQoayk7XG5cbiAgICBpZiAoeCkge1xuICAgICAgeC5kYXR1bSA9IHQ7XG4gICAgICBvdXQubW9kLnB1c2goeCk7XG4gICAgfVxuICB9KTtcblxuICBwdWxzZS52aXNpdChwdWxzZS5SRU0sIGZ1bmN0aW9uKHQpIHtcbiAgICB2YXIgayA9IGtleSQkMSh0KSxcbiAgICAgICAgeCA9IG1hcC5nZXQoayk7XG5cbiAgICBpZiAodCA9PT0geC5kYXR1bSAmJiAheC5leGl0KSB7XG4gICAgICBvdXQucmVtLnB1c2goeCk7XG4gICAgICB4LmV4aXQgPSB0cnVlO1xuICAgICAgKyttYXAuZW1wdHk7XG4gICAgfVxuICB9KTtcblxuICBpZiAocHVsc2UuY2hhbmdlZChwdWxzZS5BRERfTU9EKSkgb3V0Lm1vZGlmaWVzKCdkYXR1bScpO1xuXG4gIGlmIChfLmNsZWFuICYmIG1hcC5lbXB0eSA+IGRmLmNsZWFuVGhyZXNob2xkKSBkZi5ydW5BZnRlcihtYXAuY2xlYW4pO1xuXG4gIHJldHVybiBvdXQ7XG59O1xuXG4vKipcbiAqIEludm9rZXMgZW5jb2RpbmcgZnVuY3Rpb25zIGZvciB2aXN1YWwgaXRlbXMuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyB0byB0aGUgZW5jb2RpbmcgZnVuY3Rpb25zLiBUaGlzXG4gKiAgIHBhcmFtZXRlciBvYmplY3Qgd2lsbCBiZSBwYXNzZWQgdGhyb3VnaCB0byBhbGwgaW52b2tlZCBlbmNvZGluZyBmdW5jdGlvbnMuXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW0uZW5jb2RlcnMgLSBUaGUgZW5jb2RpbmcgZnVuY3Rpb25zXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCwgb2JqZWN0KTogYm9vbGVhbn0gW3BhcmFtLmVuY29kZXJzLnVwZGF0ZV0gLSBVcGRhdGUgZW5jb2Rpbmcgc2V0XG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCwgb2JqZWN0KTogYm9vbGVhbn0gW3BhcmFtLmVuY29kZXJzLmVudGVyXSAtIEVudGVyIGVuY29kaW5nIHNldFxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QsIG9iamVjdCk6IGJvb2xlYW59IFtwYXJhbS5lbmNvZGVycy5leGl0XSAtIEV4aXQgZW5jb2Rpbmcgc2V0XG4gKi9cbmZ1bmN0aW9uIEVuY29kZShwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ1NiA9IGluaGVyaXRzKEVuY29kZSwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDU2LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBvdXQgPSBwdWxzZS5mb3JrKHB1bHNlLkFERF9SRU0pLFxuICAgICAgZW5jb2RlcnMgPSBfLmVuY29kZXJzLFxuICAgICAgZW5jb2RlID0gcHVsc2UuZW5jb2RlO1xuXG4gIC8vIGlmIGFuIGFycmF5LCB0aGUgZW5jb2RlIGRpcmVjdGl2ZSBpbmNsdWRlcyBhZGRpdGlvbmFsIHNldHNcbiAgLy8gdGhhdCBtdXN0IGJlIGRlZmluZWQgaW4gb3JkZXIgZm9yIHRoZSBwcmltYXJ5IHNldCB0byBiZSBpbnZva2VkXG4gIC8vIGUuZy4sIG9ubHkgcnVuIHRoZSB1cGRhdGUgc2V0IGlmIHRoZSBob3ZlciBzZXQgaXMgZGVmaW5lZFxuICBpZiAoaXNBcnJheShlbmNvZGUpKSB7XG4gICAgaWYgKG91dC5jaGFuZ2VkKCkgfHwgZW5jb2RlLmV2ZXJ5KGZ1bmN0aW9uKGUpIHsgcmV0dXJuIGVuY29kZXJzW2VdOyB9KSkge1xuICAgICAgZW5jb2RlID0gZW5jb2RlWzBdO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gcHVsc2UuU3RvcFByb3BhZ2F0aW9uO1xuICAgIH1cbiAgfVxuXG4gIC8vIG1hcnNoYWxsIGVuY29kZXIgZnVuY3Rpb25zXG4gIHZhciByZWVudGVyID0gZW5jb2RlID09PSAnZW50ZXInLFxuICAgICAgdXBkYXRlID0gZW5jb2RlcnMudXBkYXRlIHx8IGZhbHN5LFxuICAgICAgZW50ZXIgPSBlbmNvZGVycy5lbnRlciB8fCBmYWxzeSxcbiAgICAgIGV4aXQgPSBlbmNvZGVycy5leGl0IHx8IGZhbHN5LFxuICAgICAgc2V0ID0gKGVuY29kZSAmJiAhcmVlbnRlciA/IGVuY29kZXJzW2VuY29kZV0gOiB1cGRhdGUpIHx8IGZhbHN5O1xuXG4gIGlmIChwdWxzZS5jaGFuZ2VkKHB1bHNlLkFERCkpIHtcbiAgICBwdWxzZS52aXNpdChwdWxzZS5BREQsIGZ1bmN0aW9uKHQpIHtcbiAgICAgIGVudGVyKHQsIF8pO1xuICAgICAgdXBkYXRlKHQsIF8pO1xuICAgICAgaWYgKHNldCAhPT0gZmFsc3kgJiYgc2V0ICE9PSB1cGRhdGUpIHNldCh0LCBfKTtcbiAgICB9KTtcbiAgICBvdXQubW9kaWZpZXMoZW50ZXIub3V0cHV0KTtcbiAgICBvdXQubW9kaWZpZXModXBkYXRlLm91dHB1dCk7XG4gICAgaWYgKHNldCAhPT0gZmFsc3kgJiYgc2V0ICE9PSB1cGRhdGUpIG91dC5tb2RpZmllcyhzZXQub3V0cHV0KTtcbiAgfVxuXG4gIGlmIChwdWxzZS5jaGFuZ2VkKHB1bHNlLlJFTSkgJiYgZXhpdCAhPT0gZmFsc3kpIHtcbiAgICBwdWxzZS52aXNpdChwdWxzZS5SRU0sIGZ1bmN0aW9uKHQpIHsgZXhpdCh0LCBfKTsgfSk7XG4gICAgb3V0Lm1vZGlmaWVzKGV4aXQub3V0cHV0KTtcbiAgfVxuXG4gIGlmIChyZWVudGVyIHx8IHNldCAhPT0gZmFsc3kpIHtcbiAgICB2YXIgZmxhZyA9IHB1bHNlLk1PRCB8IChfLm1vZGlmaWVkKCkgPyBwdWxzZS5SRUZMT1cgOiAwKTtcbiAgICBpZiAocmVlbnRlcikge1xuICAgICAgcHVsc2UudmlzaXQoZmxhZywgZnVuY3Rpb24odCkge1xuICAgICAgICB2YXIgbW9kID0gZW50ZXIodCwgXyk7XG4gICAgICAgIGlmIChzZXQodCwgXykgfHwgbW9kKSBvdXQubW9kLnB1c2godCk7XG4gICAgICB9KTtcbiAgICAgIGlmIChvdXQubW9kLmxlbmd0aCkgb3V0Lm1vZGlmaWVzKGVudGVyLm91dHB1dCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHB1bHNlLnZpc2l0KGZsYWcsIGZ1bmN0aW9uKHQpIHtcbiAgICAgICAgaWYgKHNldCh0LCBfKSkgb3V0Lm1vZC5wdXNoKHQpO1xuICAgICAgfSk7XG4gICAgfVxuICAgIGlmIChvdXQubW9kLmxlbmd0aCkgb3V0Lm1vZGlmaWVzKHNldC5vdXRwdXQpO1xuICB9XG5cbiAgcmV0dXJuIG91dC5jaGFuZ2VkKCkgPyBvdXQgOiBwdWxzZS5TdG9wUHJvcGFnYXRpb247XG59O1xuXG52YXIgZGlzY3JldGUkMSA9IHt9O1xuZGlzY3JldGUkMVtRdWFudGlsZV0gPSBxdWFudGlsZSQxO1xuZGlzY3JldGUkMVtRdWFudGl6ZV0gPSBxdWFudGl6ZSQzO1xuZGlzY3JldGUkMVtUaHJlc2hvbGRdID0gdGhyZXNob2xkJDI7XG5kaXNjcmV0ZSQxW0JpbkxpbmVhcl0gPSBiaW4kMTtcbmRpc2NyZXRlJDFbQmluT3JkaW5hbF0gPSBiaW4kMTtcblxuZnVuY3Rpb24gbGFiZWxWYWx1ZXMoc2NhbGUsIGNvdW50LCBncmFkaWVudCkge1xuICBpZiAoZ3JhZGllbnQpIHJldHVybiBzY2FsZS5kb21haW4oKTtcbiAgdmFyIHZhbHVlcyA9IGRpc2NyZXRlJDFbc2NhbGUudHlwZV07XG4gIHJldHVybiB2YWx1ZXMgPyB2YWx1ZXMoc2NhbGUpIDogdGlja1ZhbHVlcyhzY2FsZSwgY291bnQpO1xufVxuXG5mdW5jdGlvbiBxdWFudGl6ZSQzKHNjYWxlKSB7XG4gIHZhciBkb21haW4gPSBzY2FsZS5kb21haW4oKSxcbiAgICAgIHgwID0gZG9tYWluWzBdLFxuICAgICAgeDEgPSBwZWVrKGRvbWFpbiksXG4gICAgICBuID0gc2NhbGUucmFuZ2UoKS5sZW5ndGgsXG4gICAgICB2YWx1ZXMgPSBuZXcgQXJyYXkobiksXG4gICAgICBpID0gMDtcblxuICB2YWx1ZXNbMF0gPSAtSW5maW5pdHk7XG4gIHdoaWxlICgrK2kgPCBuKSB2YWx1ZXNbaV0gPSAoaSAqIHgxIC0gKGkgLSBuKSAqIHgwKSAvIG47XG4gIHZhbHVlcy5tYXggPSArSW5maW5pdHk7XG5cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuZnVuY3Rpb24gcXVhbnRpbGUkMShzY2FsZSkge1xuICB2YXIgdmFsdWVzID0gWy1JbmZpbml0eV0uY29uY2F0KHNjYWxlLnF1YW50aWxlcygpKTtcbiAgdmFsdWVzLm1heCA9ICtJbmZpbml0eTtcblxuICByZXR1cm4gdmFsdWVzO1xufVxuXG5mdW5jdGlvbiB0aHJlc2hvbGQkMihzY2FsZSkge1xuICB2YXIgdmFsdWVzID0gWy1JbmZpbml0eV0uY29uY2F0KHNjYWxlLmRvbWFpbigpKTtcbiAgdmFsdWVzLm1heCA9ICtJbmZpbml0eTtcblxuICByZXR1cm4gdmFsdWVzO1xufVxuXG5mdW5jdGlvbiBiaW4kMShzY2FsZSkge1xuICB2YXIgdmFsdWVzID0gc2NhbGUuZG9tYWluKCk7XG4gIHZhbHVlcy5tYXggPSB2YWx1ZXMucG9wKCk7XG5cbiAgcmV0dXJuIHZhbHVlcztcbn1cblxuZnVuY3Rpb24gbGFiZWxGb3JtYXQoc2NhbGUsIGZvcm1hdCkge1xuICByZXR1cm4gZGlzY3JldGUkMVtzY2FsZS50eXBlXSA/IGZvcm1hdFJhbmdlKGZvcm1hdCkgOiBmb3JtYXRQb2ludChmb3JtYXQpO1xufVxuXG5mdW5jdGlvbiBmb3JtYXRSYW5nZShmb3JtYXQpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHZhbHVlLCBpbmRleCwgYXJyYXkkJDEpIHtcbiAgICB2YXIgbGltaXQgPSBhcnJheSQkMVtpbmRleCArIDFdIHx8IGFycmF5JCQxLm1heCB8fCArSW5maW5pdHksXG4gICAgICAgIGxvID0gZm9ybWF0VmFsdWUodmFsdWUsIGZvcm1hdCksXG4gICAgICAgIGhpID0gZm9ybWF0VmFsdWUobGltaXQsIGZvcm1hdCk7XG4gICAgcmV0dXJuIGxvICYmIGhpID8gbG8gKyAnXFx1MjAxMycgKyBoaSA6IGhpID8gJzwgJyArIGhpIDogJ1xcdTIyNjUgJyArIGxvO1xuICB9O1xufVxuXG5mdW5jdGlvbiBmb3JtYXRWYWx1ZSh2YWx1ZSwgZm9ybWF0KSB7XG4gIHJldHVybiBpc0Zpbml0ZSh2YWx1ZSkgPyBmb3JtYXQodmFsdWUpIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gZm9ybWF0UG9pbnQoZm9ybWF0KSB7XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZSkge1xuICAgIHJldHVybiBmb3JtYXQodmFsdWUpO1xuICB9O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBsZWdlbmQgZW50cmllcyBmb3IgdmlzdWFsaXppbmcgYSBzY2FsZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtTY2FsZX0gcGFyYW1zLnNjYWxlIC0gVGhlIHNjYWxlIHRvIGdlbmVyYXRlIGl0ZW1zIGZvci5cbiAqIEBwYXJhbSB7Kn0gW3BhcmFtcy5jb3VudD0xMF0gLSBUaGUgYXBwcm94aW1hdGUgbnVtYmVyIG9mIGl0ZW1zLCBvclxuICogICBkZXNpcmVkIHRpY2sgaW50ZXJ2YWwsIHRvIHVzZS5cbiAqIEBwYXJhbSB7QXJyYXk8Kj59IFtwYXJhbXMudmFsdWVzXSAtIFRoZSBleGFjdCB0aWNrIHZhbHVlcyB0byB1c2UuXG4gKiAgIFRoZXNlIG11c3QgYmUgbGVnYWwgZG9tYWluIHZhbHVlcyBmb3IgdGhlIHByb3ZpZGVkIHNjYWxlLlxuICogICBJZiBwcm92aWRlZCwgdGhlIGNvdW50IGFyZ3VtZW50IGlzIGlnbm9yZWQuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCopOnN0cmluZ30gW3BhcmFtcy5mb3JtYXRTcGVjaWZpZXJdIC0gQSBmb3JtYXQgc3BlY2lmaWVyXG4gKiAgIHRvIHVzZSBpbiBjb25qdW5jdGlvbiB3aXRoIHNjYWxlLnRpY2tGb3JtYXQuIExlZ2FsIHZhbHVlcyBhcmVcbiAqICAgYW55IHZhbGlkIGQzIDQuMCBmb3JtYXQgc3BlY2lmaWVyLlxuICogQHBhcmFtIHtmdW5jdGlvbigqKTpzdHJpbmd9IFtwYXJhbXMuZm9ybWF0XSAtIFRoZSBmb3JtYXQgZnVuY3Rpb24gdG8gdXNlLlxuICogICBJZiBwcm92aWRlZCwgdGhlIGZvcm1hdFNwZWNpZmllciBhcmd1bWVudCBpcyBpZ25vcmVkLlxuICovXG5mdW5jdGlvbiBMZWdlbmRFbnRyaWVzKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBbXSwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ1NyA9IGluaGVyaXRzKExlZ2VuZEVudHJpZXMsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ1Ny50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICBpZiAodGhpcy52YWx1ZSAhPSBudWxsICYmICFfLm1vZGlmaWVkKCkpIHtcbiAgICByZXR1cm4gcHVsc2UuU3RvcFByb3BhZ2F0aW9uO1xuICB9XG5cbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKSxcbiAgICAgIHRvdGFsID0gMCxcbiAgICAgIGl0ZW1zID0gdGhpcy52YWx1ZSxcbiAgICAgIGdyYWQgID0gXy50eXBlID09PSAnZ3JhZGllbnQnLFxuICAgICAgc2NhbGUgPSBfLnNjYWxlLFxuICAgICAgY291bnQgPSBfLmNvdW50ID09IG51bGwgPyA1IDogdGlja0NvdW50KHNjYWxlLCBfLmNvdW50KSxcbiAgICAgIGZvcm1hdCA9IF8uZm9ybWF0IHx8IHRpY2tGb3JtYXQoc2NhbGUsIGNvdW50LCBfLmZvcm1hdFNwZWNpZmllciksXG4gICAgICB2YWx1ZXMgPSBfLnZhbHVlcyB8fCBsYWJlbFZhbHVlcyhzY2FsZSwgY291bnQsIGdyYWQpO1xuXG4gIGZvcm1hdCA9IGxhYmVsRm9ybWF0KHNjYWxlLCBmb3JtYXQpO1xuICBpZiAoaXRlbXMpIG91dC5yZW0gPSBpdGVtcztcblxuICBpZiAoZ3JhZCkge1xuICAgIHZhciBkb21haW4gPSBfLnZhbHVlcyA/IHNjYWxlLmRvbWFpbigpIDogdmFsdWVzLFxuICAgICAgICBmcmFjdGlvbiA9IHNjYWxlRnJhY3Rpb24oc2NhbGUsIGRvbWFpblswXSwgcGVlayhkb21haW4pKTtcbiAgfSBlbHNlIHtcbiAgICB2YXIgc2l6ZSA9IF8uc2l6ZSxcbiAgICAgICAgb2Zmc2V0O1xuICAgIGlmIChpc0Z1bmN0aW9uKHNpemUpKSB7XG4gICAgICAvLyBpZiBmaXJzdCB2YWx1ZSBtYXBzIHRvIHNpemUgemVybywgcmVtb3ZlIGZyb20gbGlzdCAodmVnYSM3MTcpXG4gICAgICBpZiAoIV8udmFsdWVzICYmIHNjYWxlKHZhbHVlc1swXSkgPT09IDApIHtcbiAgICAgICAgdmFsdWVzID0gdmFsdWVzLnNsaWNlKDEpO1xuICAgICAgfVxuICAgICAgLy8gY29tcHV0ZSBzaXplIG9mZnNldCBmb3IgbGVnZW5kIGVudHJpZXNcbiAgICAgIG9mZnNldCA9IHZhbHVlcy5yZWR1Y2UoZnVuY3Rpb24obWF4LCB2YWx1ZSkge1xuICAgICAgICByZXR1cm4gTWF0aC5tYXgobWF4LCBzaXplKHZhbHVlLCBfKSk7XG4gICAgICB9LCAwKTtcbiAgICB9IGVsc2Uge1xuICAgICAgc2l6ZSA9IGNvbnN0YW50KG9mZnNldCA9IHNpemUgfHwgOCk7XG4gICAgfVxuICB9XG5cbiAgaXRlbXMgPSB2YWx1ZXMubWFwKGZ1bmN0aW9uKHZhbHVlLCBpbmRleCkge1xuICAgIHZhciB0ID0gaW5nZXN0KHtcbiAgICAgIGluZGV4OiBpbmRleCxcbiAgICAgIGxhYmVsOiBmb3JtYXQodmFsdWUsIGluZGV4LCB2YWx1ZXMpLFxuICAgICAgdmFsdWU6IHZhbHVlXG4gICAgfSk7XG5cbiAgICBpZiAoZ3JhZCkge1xuICAgICAgdC5wZXJjID0gZnJhY3Rpb24odmFsdWUpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0Lm9mZnNldCA9IG9mZnNldDtcbiAgICAgIHQuc2l6ZSA9IHNpemUodmFsdWUsIF8pO1xuICAgICAgdC50b3RhbCA9IE1hdGgucm91bmQodG90YWwpO1xuICAgICAgdG90YWwgKz0gdC5zaXplO1xuICAgIH1cbiAgICByZXR1cm4gdDtcbiAgfSk7XG5cbiAgb3V0LnNvdXJjZSA9IGl0ZW1zO1xuICBvdXQuYWRkID0gaXRlbXM7XG4gIHRoaXMudmFsdWUgPSBpdGVtcztcblxuICByZXR1cm4gb3V0O1xufTtcblxudmFyIFBhdGhzID0gZmFzdG1hcCh7XG4gICdsaW5lJzogbGluZSQzLFxuICAnbGluZS1yYWRpYWwnOiBsaW5lUixcbiAgJ2FyYyc6IGFyYyQyLFxuICAnYXJjLXJhZGlhbCc6IGFyY1IsXG4gICdjdXJ2ZSc6IGN1cnZlLFxuICAnY3VydmUtcmFkaWFsJzogY3VydmVSLFxuICAnb3J0aG9nb25hbC1ob3Jpem9udGFsJzogb3J0aG9YLFxuICAnb3J0aG9nb25hbC12ZXJ0aWNhbCc6IG9ydGhvWSxcbiAgJ29ydGhvZ29uYWwtcmFkaWFsJzogb3J0aG9SLFxuICAnZGlhZ29uYWwtaG9yaXpvbnRhbCc6IGRpYWdvbmFsWCxcbiAgJ2RpYWdvbmFsLXZlcnRpY2FsJzogZGlhZ29uYWxZLFxuICAnZGlhZ29uYWwtcmFkaWFsJzogZGlhZ29uYWxSXG59KTtcblxuZnVuY3Rpb24gc291cmNlWCh0KSB7IHJldHVybiB0LnNvdXJjZS54OyB9XG5mdW5jdGlvbiBzb3VyY2VZKHQpIHsgcmV0dXJuIHQuc291cmNlLnk7IH1cbmZ1bmN0aW9uIHRhcmdldFgodCkgeyByZXR1cm4gdC50YXJnZXQueDsgfVxuZnVuY3Rpb24gdGFyZ2V0WSh0KSB7IHJldHVybiB0LnRhcmdldC55OyB9XG5cbiAvKipcbiAgKiBMYXlvdXQgcGF0aHMgbGlua2luZyBzb3VyY2UgYW5kIHRhcmdldCBlbGVtZW50cy5cbiAgKiBAY29uc3RydWN0b3JcbiAgKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gICovXG5mdW5jdGlvbiBMaW5rUGF0aChwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywge30sIHBhcmFtcyk7XG59XG5cbkxpbmtQYXRoLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIkxpbmtQYXRoXCIsXG4gIFwibWV0YWRhdGFcIjoge1wibW9kaWZpZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcInNvdXJjZVhcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJkZWZhdWx0XCI6IFwic291cmNlLnhcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwic291cmNlWVwiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcImRlZmF1bHRcIjogXCJzb3VyY2UueVwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJ0YXJnZXRYXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiZGVmYXVsdFwiOiBcInRhcmdldC54XCIgfSxcbiAgICB7IFwibmFtZVwiOiBcInRhcmdldFlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJkZWZhdWx0XCI6IFwidGFyZ2V0LnlcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwib3JpZW50XCIsIFwidHlwZVwiOiBcImVudW1cIiwgXCJkZWZhdWx0XCI6IFwidmVydGljYWxcIixcbiAgICAgIFwidmFsdWVzXCI6IFtcImhvcml6b250YWxcIiwgXCJ2ZXJ0aWNhbFwiLCBcInJhZGlhbFwiXSB9LFxuICAgIHsgXCJuYW1lXCI6IFwic2hhcGVcIiwgXCJ0eXBlXCI6IFwiZW51bVwiLCBcImRlZmF1bHRcIjogXCJsaW5lXCIsXG4gICAgICBcInZhbHVlc1wiOiBbXCJsaW5lXCIsIFwiYXJjXCIsIFwiY3VydmVcIiwgXCJkaWFnb25hbFwiLCBcIm9ydGhvZ29uYWxcIl0gfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcImRlZmF1bHRcIjogXCJwYXRoXCIgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDU4ID0gaW5oZXJpdHMoTGlua1BhdGgsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ1OC50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgc3ggPSBfLnNvdXJjZVggfHwgc291cmNlWCxcbiAgICAgIHN5ID0gXy5zb3VyY2VZIHx8IHNvdXJjZVksXG4gICAgICB0eCA9IF8udGFyZ2V0WCB8fCB0YXJnZXRYLFxuICAgICAgdHkgPSBfLnRhcmdldFkgfHwgdGFyZ2V0WSxcbiAgICAgIGFzID0gXy5hcyB8fCAncGF0aCcsXG4gICAgICBvcmllbnQgPSBfLm9yaWVudCB8fCAndmVydGljYWwnLFxuICAgICAgc2hhcGUgPSBfLnNoYXBlIHx8ICdsaW5lJyxcbiAgICAgIHBhdGggPSBQYXRocy5nZXQoc2hhcGUgKyAnLScgKyBvcmllbnQpIHx8IFBhdGhzLmdldChzaGFwZSk7XG5cbiAgaWYgKCFwYXRoKSB7XG4gICAgZXJyb3IkMSgnTGlua1BhdGggdW5zdXBwb3J0ZWQgdHlwZTogJyArIF8uc2hhcGVcbiAgICAgICsgKF8ub3JpZW50ID8gJy0nICsgXy5vcmllbnQgOiAnJykpO1xuICB9XG5cbiAgcHVsc2UudmlzaXQocHVsc2UuU09VUkNFLCBmdW5jdGlvbih0KSB7XG4gICAgdFthc10gPSBwYXRoKHN4KHQpLCBzeSh0KSwgdHgodCksIHR5KHQpKTtcbiAgfSk7XG5cbiAgcmV0dXJuIHB1bHNlLnJlZmxvdyhfLm1vZGlmaWVkKCkpLm1vZGlmaWVzKGFzKTtcbn07XG5cbi8vIC0tIExpbmsgUGF0aCBHZW5lcmF0aW9uIE1ldGhvZHMgLS0tLS1cblxuZnVuY3Rpb24gbGluZSQzKHN4LCBzeSwgdHgsIHR5KSB7XG4gIHJldHVybiAnTScgKyBzeCArICcsJyArIHN5ICtcbiAgICAgICAgICdMJyArIHR4ICsgJywnICsgdHk7XG59XG5cbmZ1bmN0aW9uIGxpbmVSKHNhLCBzciwgdGEsIHRyKSB7XG4gIHJldHVybiBsaW5lJDMoXG4gICAgc3IgKiBNYXRoLmNvcyhzYSksIHNyICogTWF0aC5zaW4oc2EpLFxuICAgIHRyICogTWF0aC5jb3ModGEpLCB0ciAqIE1hdGguc2luKHRhKVxuICApO1xufVxuXG5mdW5jdGlvbiBhcmMkMihzeCwgc3ksIHR4LCB0eSkge1xuICB2YXIgZHggPSB0eCAtIHN4LFxuICAgICAgZHkgPSB0eSAtIHN5LFxuICAgICAgcnIgPSBNYXRoLnNxcnQoZHggKiBkeCArIGR5ICogZHkpIC8gMixcbiAgICAgIHJhID0gMTgwICogTWF0aC5hdGFuMihkeSwgZHgpIC8gTWF0aC5QSTtcbiAgcmV0dXJuICdNJyArIHN4ICsgJywnICsgc3kgK1xuICAgICAgICAgJ0EnICsgcnIgKyAnLCcgKyByciArXG4gICAgICAgICAnICcgKyByYSArICcgMCAxJyArXG4gICAgICAgICAnICcgKyB0eCArICcsJyArIHR5O1xufVxuXG5mdW5jdGlvbiBhcmNSKHNhLCBzciwgdGEsIHRyKSB7XG4gIHJldHVybiBhcmMkMihcbiAgICBzciAqIE1hdGguY29zKHNhKSwgc3IgKiBNYXRoLnNpbihzYSksXG4gICAgdHIgKiBNYXRoLmNvcyh0YSksIHRyICogTWF0aC5zaW4odGEpXG4gICk7XG59XG5cbmZ1bmN0aW9uIGN1cnZlKHN4LCBzeSwgdHgsIHR5KSB7XG4gIHZhciBkeCA9IHR4IC0gc3gsXG4gICAgICBkeSA9IHR5IC0gc3ksXG4gICAgICBpeCA9IDAuMiAqIChkeCArIGR5KSxcbiAgICAgIGl5ID0gMC4yICogKGR5IC0gZHgpO1xuICByZXR1cm4gJ00nICsgc3ggKyAnLCcgKyBzeSArXG4gICAgICAgICAnQycgKyAoc3graXgpICsgJywnICsgKHN5K2l5KSArXG4gICAgICAgICAnICcgKyAodHgraXkpICsgJywnICsgKHR5LWl4KSArXG4gICAgICAgICAnICcgKyB0eCArICcsJyArIHR5O1xufVxuXG5mdW5jdGlvbiBjdXJ2ZVIoc2EsIHNyLCB0YSwgdHIpIHtcbiAgcmV0dXJuIGN1cnZlKFxuICAgIHNyICogTWF0aC5jb3Moc2EpLCBzciAqIE1hdGguc2luKHNhKSxcbiAgICB0ciAqIE1hdGguY29zKHRhKSwgdHIgKiBNYXRoLnNpbih0YSlcbiAgKTtcbn1cblxuZnVuY3Rpb24gb3J0aG9YKHN4LCBzeSwgdHgsIHR5KSB7XG4gIHJldHVybiAnTScgKyBzeCArICcsJyArIHN5ICtcbiAgICAgICAgICdWJyArIHR5ICsgJ0gnICsgdHg7XG59XG5cbmZ1bmN0aW9uIG9ydGhvWShzeCwgc3ksIHR4LCB0eSkge1xuICByZXR1cm4gJ00nICsgc3ggKyAnLCcgKyBzeSArXG4gICAgICAgICAnSCcgKyB0eCArICdWJyArIHR5O1xufVxuXG5mdW5jdGlvbiBvcnRob1Ioc2EsIHNyLCB0YSwgdHIpIHtcbiAgdmFyIHNjID0gTWF0aC5jb3Moc2EpLFxuICAgICAgc3MgPSBNYXRoLnNpbihzYSksXG4gICAgICB0YyA9IE1hdGguY29zKHRhKSxcbiAgICAgIHRzID0gTWF0aC5zaW4odGEpLFxuICAgICAgc2YgPSBNYXRoLmFicyh0YSAtIHNhKSA+IE1hdGguUEkgPyB0YSA8PSBzYSA6IHRhID4gc2E7XG4gIHJldHVybiAnTScgKyAoc3Iqc2MpICsgJywnICsgKHNyKnNzKSArXG4gICAgICAgICAnQScgKyBzciArICcsJyArIHNyICsgJyAwIDAsJyArIChzZj8xOjApICtcbiAgICAgICAgICcgJyArIChzcip0YykgKyAnLCcgKyAoc3IqdHMpICtcbiAgICAgICAgICdMJyArICh0cip0YykgKyAnLCcgKyAodHIqdHMpO1xufVxuXG5mdW5jdGlvbiBkaWFnb25hbFgoc3gsIHN5LCB0eCwgdHkpIHtcbiAgdmFyIG0gPSAoc3ggKyB0eCkgLyAyO1xuICByZXR1cm4gJ00nICsgc3ggKyAnLCcgKyBzeSArXG4gICAgICAgICAnQycgKyBtICArICcsJyArIHN5ICtcbiAgICAgICAgICcgJyArIG0gICsgJywnICsgdHkgK1xuICAgICAgICAgJyAnICsgdHggKyAnLCcgKyB0eTtcbn1cblxuZnVuY3Rpb24gZGlhZ29uYWxZKHN4LCBzeSwgdHgsIHR5KSB7XG4gIHZhciBtID0gKHN5ICsgdHkpIC8gMjtcbiAgcmV0dXJuICdNJyArIHN4ICsgJywnICsgc3kgK1xuICAgICAgICAgJ0MnICsgc3ggKyAnLCcgKyBtICtcbiAgICAgICAgICcgJyArIHR4ICsgJywnICsgbSArXG4gICAgICAgICAnICcgKyB0eCArICcsJyArIHR5O1xufVxuXG5mdW5jdGlvbiBkaWFnb25hbFIoc2EsIHNyLCB0YSwgdHIpIHtcbiAgdmFyIHNjID0gTWF0aC5jb3Moc2EpLFxuICAgICAgc3MgPSBNYXRoLnNpbihzYSksXG4gICAgICB0YyA9IE1hdGguY29zKHRhKSxcbiAgICAgIHRzID0gTWF0aC5zaW4odGEpLFxuICAgICAgbXIgPSAoc3IgKyB0cikgLyAyO1xuICByZXR1cm4gJ00nICsgKHNyKnNjKSArICcsJyArIChzcipzcykgK1xuICAgICAgICAgJ0MnICsgKG1yKnNjKSArICcsJyArIChtcipzcykgK1xuICAgICAgICAgJyAnICsgKG1yKnRjKSArICcsJyArIChtcip0cykgK1xuICAgICAgICAgJyAnICsgKHRyKnRjKSArICcsJyArICh0cip0cyk7XG59XG5cbi8qKlxuICogUGllIGFuZCBkb251dCBjaGFydCBsYXlvdXQuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogKn0gcGFyYW1zLmZpZWxkIC0gVGhlIHZhbHVlIGZpZWxkIHRvIHNpemUgcGllIHNlZ21lbnRzLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJhbXMuc3RhcnRBbmdsZT0wXSAtIFRoZSBzdGFydCBhbmdsZSAoaW4gcmFkaWFucykgb2YgdGhlIGxheW91dC5cbiAqIEBwYXJhbSB7bnVtYmVyfSBbcGFyYW1zLmVuZEFuZ2xlPTLPgF0gLSBUaGUgZW5kIGFuZ2xlIChpbiByYWRpYW5zKSBvZiB0aGUgbGF5b3V0LlxuICogQHBhcmFtIHtib29sZWFufSBbcGFyYW1zLnNvcnRdIC0gQm9vbGVhbiBmbGFnIGZvciBzb3J0aW5nIHNlY3RvcnMgYnkgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIFBpZShwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxuUGllLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIlBpZVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJzdGFydEFuZ2xlXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZW5kQW5nbGVcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiA2LjI4MzE4NTMwNzE3OTU4NiB9LFxuICAgIHsgXCJuYW1lXCI6IFwic29ydFwiLCBcInR5cGVcIjogXCJib29sZWFuXCIsIFwiZGVmYXVsdFwiOiBmYWxzZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiwgXCJkZWZhdWx0XCI6IFtcInN0YXJ0QW5nbGVcIiwgXCJlbmRBbmdsZVwiXSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkNTkgPSBpbmhlcml0cyhQaWUsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ1OS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgYXMgPSBfLmFzIHx8IFsnc3RhcnRBbmdsZScsICdlbmRBbmdsZSddLFxuICAgICAgc3RhcnRBbmdsZSA9IGFzWzBdLFxuICAgICAgZW5kQW5nbGUgPSBhc1sxXSxcbiAgICAgIGZpZWxkJCQxID0gXy5maWVsZCB8fCBvbmUsXG4gICAgICBzdGFydCA9IF8uc3RhcnRBbmdsZSB8fCAwLFxuICAgICAgc3RvcCA9IF8uZW5kQW5nbGUgIT0gbnVsbCA/IF8uZW5kQW5nbGUgOiAyICogTWF0aC5QSSxcbiAgICAgIGRhdGEgPSBwdWxzZS5zb3VyY2UsXG4gICAgICB2YWx1ZXMgPSBkYXRhLm1hcChmaWVsZCQkMSksXG4gICAgICBuID0gdmFsdWVzLmxlbmd0aCxcbiAgICAgIGEgPSBzdGFydCxcbiAgICAgIGsgPSAoc3RvcCAtIHN0YXJ0KSAvIHN1bSh2YWx1ZXMpLFxuICAgICAgaW5kZXggPSBzZXF1ZW5jZShuKSxcbiAgICAgIGksIHQsIHY7XG5cbiAgaWYgKF8uc29ydCkge1xuICAgIGluZGV4LnNvcnQoZnVuY3Rpb24oYSwgYikge1xuICAgICAgcmV0dXJuIHZhbHVlc1thXSAtIHZhbHVlc1tiXTtcbiAgICB9KTtcbiAgfVxuXG4gIGZvciAoaT0wOyBpPG47ICsraSkge1xuICAgIHYgPSB2YWx1ZXNbaW5kZXhbaV1dO1xuICAgIHQgPSBkYXRhW2luZGV4W2ldXTtcbiAgICB0W3N0YXJ0QW5nbGVdID0gYTtcbiAgICB0W2VuZEFuZ2xlXSA9IChhICs9IHYgKiBrKTtcbiAgfVxuXG4gIHRoaXMudmFsdWUgPSB2YWx1ZXM7XG4gIHJldHVybiBwdWxzZS5yZWZsb3coXy5tb2RpZmllZCgpKS5tb2RpZmllcyhhcyk7XG59O1xuXG52YXIgREVGQVVMVF9DT1VOVCA9IDU7XG5cbnZhciBJTkNMVURFX1pFUk8gPSB0b1NldChbTGluZWFyJDEsIFBvdywgU3FydF0pO1xuXG52YXIgSU5DTFVERV9QQUQgPSB0b1NldChbTGluZWFyJDEsIExvZywgUG93LCBTcXJ0LCBUaW1lLCBVdGNdKTtcblxudmFyIFNLSVAkMiA9IHRvU2V0KFtcbiAgJ3NldCcsICdtb2RpZmllZCcsICdjbGVhcicsICd0eXBlJywgJ3NjaGVtZScsICdzY2hlbWVFeHRlbnQnLCAnc2NoZW1lQ291bnQnLFxuICAnZG9tYWluJywgJ2RvbWFpbk1pbicsICdkb21haW5NaWQnLCAnZG9tYWluTWF4JywgJ2RvbWFpblJhdycsICduaWNlJywgJ3plcm8nLFxuICAncmFuZ2UnLCAncmFuZ2VTdGVwJywgJ3JvdW5kJywgJ3JldmVyc2UnLCAnaW50ZXJwb2xhdGUnLCAnaW50ZXJwb2xhdGVHYW1tYSdcbl0pO1xuXG4vKipcbiAqIE1haW50YWlucyBhIHNjYWxlIGZ1bmN0aW9uIG1hcHBpbmcgZGF0YSB2YWx1ZXMgdG8gdmlzdWFsIGNoYW5uZWxzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIFNjYWxlKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xuICB0aGlzLm1vZGlmaWVkKHRydWUpOyAvLyBhbHdheXMgdHJlYXQgYXMgbW9kaWZpZWRcbn1cblxudmFyIHByb3RvdHlwZSQ2MCA9IGluaGVyaXRzKFNjYWxlLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkNjAudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGRmID0gcHVsc2UuZGF0YWZsb3csXG4gICAgICBzY2FsZSA9IHRoaXMudmFsdWUsXG4gICAgICBwcm9wO1xuXG4gIGlmICghc2NhbGUgfHwgXy5tb2RpZmllZCgndHlwZScpKSB7XG4gICAgdGhpcy52YWx1ZSA9IHNjYWxlID0gc2NhbGUkMSgoXy50eXBlIHx8IExpbmVhciQxKS50b0xvd2VyQ2FzZSgpKSgpO1xuICB9XG5cbiAgZm9yIChwcm9wIGluIF8pIGlmICghU0tJUCQyW3Byb3BdKSB7XG4gICAgLy8gcGFkZGluZyBpcyBhIHNjYWxlIHByb3BlcnR5IGZvciBiYW5kL3BvaW50IGJ1dCBub3Qgb3RoZXJzXG4gICAgaWYgKHByb3AgPT09ICdwYWRkaW5nJyAmJiBJTkNMVURFX1BBRFtzY2FsZS50eXBlXSkgY29udGludWU7XG4gICAgLy8gaW52b2tlIHNjYWxlIHByb3BlcnR5IHNldHRlciwgcmFpc2Ugd2FybmluZyBpZiBub3QgZm91bmRcbiAgICBpc0Z1bmN0aW9uKHNjYWxlW3Byb3BdKVxuICAgICAgPyBzY2FsZVtwcm9wXShfW3Byb3BdKVxuICAgICAgOiBkZi53YXJuKCdVbnN1cHBvcnRlZCBzY2FsZSBwcm9wZXJ0eTogJyArIHByb3ApO1xuICB9XG5cbiAgY29uZmlndXJlUmFuZ2Uoc2NhbGUsIF8sIGNvbmZpZ3VyZURvbWFpbihzY2FsZSwgXywgZGYpKTtcblxuICByZXR1cm4gcHVsc2UuZm9yayhwdWxzZS5OT19TT1VSQ0UgfCBwdWxzZS5OT19GSUVMRFMpO1xufTtcblxuZnVuY3Rpb24gY29uZmlndXJlRG9tYWluKHNjYWxlLCBfLCBkZikge1xuICAvLyBjaGVjayByYXcgZG9tYWluLCBpZiBwcm92aWRlZCB1c2UgdGhhdCBhbmQgZXhpdCBlYXJseVxuICB2YXIgcmF3ID0gcmF3RG9tYWluKHNjYWxlLCBfLmRvbWFpblJhdyk7XG4gIGlmIChyYXcgPiAtMSkgcmV0dXJuIHJhdztcblxuICB2YXIgZG9tYWluID0gXy5kb21haW4sXG4gICAgICB0eXBlID0gc2NhbGUudHlwZSxcbiAgICAgIHplcm8kJDEgPSBfLnplcm8gfHwgKF8uemVybyA9PT0gdW5kZWZpbmVkICYmIElOQ0xVREVfWkVST1t0eXBlXSksXG4gICAgICBuLCBtaWQ7XG5cbiAgaWYgKCFkb21haW4pIHJldHVybiAwO1xuXG4gIC8vIGFkanVzdCBjb250aW51b3VzIGRvbWFpbiBmb3IgbWluaW11bSBwaXhlbCBwYWRkaW5nXG4gIGlmIChJTkNMVURFX1BBRFt0eXBlXSAmJiBfLnBhZGRpbmcgJiYgZG9tYWluWzBdICE9PSBwZWVrKGRvbWFpbikpIHtcbiAgICBkb21haW4gPSBwYWREb21haW4odHlwZSwgZG9tYWluLCBfLnJhbmdlLCBfLnBhZGRpbmcsIF8uZXhwb25lbnQpO1xuICB9XG5cbiAgLy8gYWRqdXN0IGRvbWFpbiBiYXNlZCBvbiB6ZXJvLCBtaW4sIG1heCBzZXR0aW5nc1xuICBpZiAoemVybyQkMSB8fCBfLmRvbWFpbk1pbiAhPSBudWxsIHx8IF8uZG9tYWluTWF4ICE9IG51bGwgfHwgXy5kb21haW5NaWQgIT0gbnVsbCkge1xuICAgIG4gPSAoKGRvbWFpbiA9IGRvbWFpbi5zbGljZSgpKS5sZW5ndGggLSAxKSB8fCAxO1xuICAgIGlmICh6ZXJvJCQxKSB7XG4gICAgICBpZiAoZG9tYWluWzBdID4gMCkgZG9tYWluWzBdID0gMDtcbiAgICAgIGlmIChkb21haW5bbl0gPCAwKSBkb21haW5bbl0gPSAwO1xuICAgIH1cbiAgICBpZiAoXy5kb21haW5NaW4gIT0gbnVsbCkgZG9tYWluWzBdID0gXy5kb21haW5NaW47XG4gICAgaWYgKF8uZG9tYWluTWF4ICE9IG51bGwpIGRvbWFpbltuXSA9IF8uZG9tYWluTWF4O1xuXG4gICAgaWYgKF8uZG9tYWluTWlkICE9IG51bGwpIHtcbiAgICAgIG1pZCA9IF8uZG9tYWluTWlkO1xuICAgICAgaWYgKG1pZCA8IGRvbWFpblswXSB8fCBtaWQgPiBkb21haW5bbl0pIHtcbiAgICAgICAgZGYud2FybignU2NhbGUgZG9tYWluTWlkIGV4Y2VlZHMgZG9tYWluIG1pbiBvciBtYXguJywgbWlkKTtcbiAgICAgIH1cbiAgICAgIGRvbWFpbi5zcGxpY2UobiwgMCwgbWlkKTtcbiAgICB9XG4gIH1cblxuICAvLyBzZXQgdGhlIHNjYWxlIGRvbWFpblxuICBzY2FsZS5kb21haW4oZG9tYWluKTtcblxuICAvLyBpZiBvcmRpbmFsIHNjYWxlIGRvbWFpbiBpcyBkZWZpbmVkLCBwcmV2ZW50IGltcGxpY2l0XG4gIC8vIGRvbWFpbiBjb25zdHJ1Y3Rpb24gYXMgc2lkZS1lZmZlY3Qgb2Ygc2NhbGUgbG9va3VwXG4gIGlmICh0eXBlID09PSBPcmRpbmFsKSB7XG4gICAgc2NhbGUudW5rbm93bih1bmRlZmluZWQpO1xuICB9XG5cbiAgLy8gcGVyZm9ybSAnbmljZScgYWRqdXN0bWVudCBhcyByZXF1ZXN0ZWRcbiAgaWYgKF8ubmljZSAmJiBzY2FsZS5uaWNlKSB7XG4gICAgc2NhbGUubmljZSgoXy5uaWNlICE9PSB0cnVlICYmIHRpY2tDb3VudChzY2FsZSwgXy5uaWNlKSkgfHwgbnVsbCk7XG4gIH1cblxuICAvLyByZXR1cm4gdGhlIGNhcmRpbmFsaXR5IG9mIHRoZSBkb21haW5cbiAgcmV0dXJuIGRvbWFpbi5sZW5ndGg7XG59XG5cbmZ1bmN0aW9uIHJhd0RvbWFpbihzY2FsZSwgcmF3KSB7XG4gIGlmIChyYXcpIHtcbiAgICBzY2FsZS5kb21haW4ocmF3KTtcbiAgICByZXR1cm4gcmF3Lmxlbmd0aDtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gLTE7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFkRG9tYWluKHR5cGUsIGRvbWFpbiwgcmFuZ2UsIHBhZCQkMSwgZXhwb25lbnQpIHtcbiAgdmFyIHNwYW4gPSBNYXRoLmFicyhwZWVrKHJhbmdlKSAtIHJhbmdlWzBdKSxcbiAgICAgIGZyYWMgPSBzcGFuIC8gKHNwYW4gLSAyICogcGFkJCQxKSxcbiAgICAgIGQgPSB0eXBlID09PSBMb2cgID8gem9vbUxvZyhkb21haW4sIG51bGwsIGZyYWMpXG4gICAgICAgIDogdHlwZSA9PT0gU3FydCA/IHpvb21Qb3coZG9tYWluLCBudWxsLCBmcmFjLCAwLjUpXG4gICAgICAgIDogdHlwZSA9PT0gUG93ICA/IHpvb21Qb3coZG9tYWluLCBudWxsLCBmcmFjLCBleHBvbmVudClcbiAgICAgICAgOiB6b29tTGluZWFyKGRvbWFpbiwgbnVsbCwgZnJhYyk7XG5cbiAgZG9tYWluID0gZG9tYWluLnNsaWNlKCk7XG4gIGRvbWFpblswXSA9IGRbMF07XG4gIGRvbWFpbltkb21haW4ubGVuZ3RoLTFdID0gZFsxXTtcbiAgcmV0dXJuIGRvbWFpbjtcbn1cblxuZnVuY3Rpb24gY29uZmlndXJlUmFuZ2Uoc2NhbGUsIF8sIGNvdW50KSB7XG4gIHZhciByb3VuZCA9IF8ucm91bmQgfHwgZmFsc2UsXG4gICAgICByYW5nZSA9IF8ucmFuZ2U7XG5cbiAgLy8gaWYgcmFuZ2Ugc3RlcCBzcGVjaWZpZWQsIGNhbGN1bGF0ZSBmdWxsIHJhbmdlIGV4dGVudFxuICBpZiAoXy5yYW5nZVN0ZXAgIT0gbnVsbCkge1xuICAgIHJhbmdlID0gY29uZmlndXJlUmFuZ2VTdGVwKHNjYWxlLnR5cGUsIF8sIGNvdW50KTtcbiAgfVxuXG4gIC8vIGVsc2UgaWYgYSByYW5nZSBzY2hlbWUgaXMgZGVmaW5lZCwgdXNlIHRoYXRcbiAgZWxzZSBpZiAoXy5zY2hlbWUpIHtcbiAgICByYW5nZSA9IGNvbmZpZ3VyZVNjaGVtZShzY2FsZS50eXBlLCBfLCBjb3VudCk7XG4gICAgaWYgKGlzRnVuY3Rpb24ocmFuZ2UpKSByZXR1cm4gc2NhbGUuaW50ZXJwb2xhdG9yKHJhbmdlKTtcbiAgfVxuXG4gIC8vIGdpdmVuIGEgcmFuZ2UgYXJyYXkgZm9yIGEgc2VxdWVudGlhbCBzY2FsZSwgY29udmVydCB0byBpbnRlcnBvbGF0b3JcbiAgZWxzZSBpZiAocmFuZ2UgJiYgc2NhbGUudHlwZSA9PT0gU2VxdWVudGlhbCkge1xuICAgIHJldHVybiBzY2FsZS5pbnRlcnBvbGF0b3IocmdiQmFzaXMoZmxpcChyYW5nZSwgXy5yZXZlcnNlKSkpO1xuICB9XG5cbiAgLy8gY29uZmlndXJlIHJvdW5kaW5nIC8gaW50ZXJwb2xhdGlvblxuICBpZiAocmFuZ2UgJiYgXy5pbnRlcnBvbGF0ZSAmJiBzY2FsZS5pbnRlcnBvbGF0ZSkge1xuICAgIHNjYWxlLmludGVycG9sYXRlKGludGVycG9sYXRlJDEoXy5pbnRlcnBvbGF0ZSwgXy5pbnRlcnBvbGF0ZUdhbW1hKSk7XG4gIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihzY2FsZS5yb3VuZCkpIHtcbiAgICBzY2FsZS5yb3VuZChyb3VuZCk7XG4gIH0gZWxzZSBpZiAoaXNGdW5jdGlvbihzY2FsZS5yYW5nZVJvdW5kKSkge1xuICAgIHNjYWxlLmludGVycG9sYXRlKHJvdW5kID8gaW50ZXJwb2xhdGVSb3VuZCA6IGludGVycG9sYXRlKTtcbiAgfVxuXG4gIGlmIChyYW5nZSkgc2NhbGUucmFuZ2UoZmxpcChyYW5nZSwgXy5yZXZlcnNlKSk7XG59XG5cbmZ1bmN0aW9uIGNvbmZpZ3VyZVJhbmdlU3RlcCh0eXBlLCBfLCBjb3VudCkge1xuICBpZiAodHlwZSAhPT0gQmFuZCAmJiB0eXBlICE9PSBQb2ludCkge1xuICAgIGVycm9yJDEoJ09ubHkgYmFuZCBhbmQgcG9pbnQgc2NhbGVzIHN1cHBvcnQgcmFuZ2VTdGVwLicpO1xuICB9XG5cbiAgLy8gY2FsY3VsYXRlIGZ1bGwgcmFuZ2UgYmFzZWQgb24gcmVxdWVzdGVkIHN0ZXAgc2l6ZSBhbmQgcGFkZGluZ1xuICB2YXIgb3V0ZXIgPSAoXy5wYWRkaW5nT3V0ZXIgIT0gbnVsbCA/IF8ucGFkZGluZ091dGVyIDogXy5wYWRkaW5nKSB8fCAwLFxuICAgICAgaW5uZXIgPSB0eXBlID09PSBQb2ludCA/IDFcbiAgICAgICAgICAgIDogKChfLnBhZGRpbmdJbm5lciAhPSBudWxsID8gXy5wYWRkaW5nSW5uZXIgOiBfLnBhZGRpbmcpIHx8IDApO1xuICByZXR1cm4gWzAsIF8ucmFuZ2VTdGVwICogYmFuZFNwYWNlKGNvdW50LCBpbm5lciwgb3V0ZXIpXTtcbn1cblxuZnVuY3Rpb24gY29uZmlndXJlU2NoZW1lKHR5cGUsIF8sIGNvdW50KSB7XG4gIHZhciBuYW1lID0gXy5zY2hlbWUudG9Mb3dlckNhc2UoKSxcbiAgICAgIHNjaGVtZSA9IGdldFNjaGVtZShuYW1lKSxcbiAgICAgIGV4dGVudCA9IF8uc2NoZW1lRXh0ZW50LFxuICAgICAgZGlzY3JldGU7XG5cbiAgaWYgKCFzY2hlbWUpIHtcbiAgICBlcnJvciQxKCdVbnJlY29nbml6ZWQgc2NoZW1lIG5hbWU6ICcgKyBfLnNjaGVtZSk7XG4gIH1cblxuICAvLyBkZXRlcm1pbmUgc2l6ZSBmb3IgcG90ZW50aWFsIGRpc2NyZXRlIHJhbmdlXG4gIGNvdW50ID0gKHR5cGUgPT09IFRocmVzaG9sZCkgPyBjb3VudCArIDFcbiAgICA6ICh0eXBlID09PSBCaW5PcmRpbmFsKSA/IGNvdW50IC0gMVxuICAgIDogKHR5cGUgPT09IFF1YW50aWxlIHx8IHR5cGUgPT09IFF1YW50aXplKSA/ICgrXy5zY2hlbWVDb3VudCB8fCBERUZBVUxUX0NPVU5UKVxuICAgIDogY291bnQ7XG5cbiAgLy8gYWRqdXN0IGFuZC9vciBxdWFudGl6ZSBzY2hlbWUgYXMgYXBwcm9wcmlhdGVcbiAgcmV0dXJuIHR5cGUgPT09IFNlcXVlbnRpYWwgPyBhZGp1c3RTY2hlbWUoc2NoZW1lLCBleHRlbnQsIF8ucmV2ZXJzZSlcbiAgICA6ICFleHRlbnQgJiYgKGRpc2NyZXRlID0gZ2V0U2NoZW1lKG5hbWUgKyAnLScgKyBjb3VudCkpID8gZGlzY3JldGVcbiAgICA6IGlzRnVuY3Rpb24oc2NoZW1lKSA/IHF1YW50aXplJDQoYWRqdXN0U2NoZW1lKHNjaGVtZSwgZXh0ZW50KSwgY291bnQpXG4gICAgOiB0eXBlID09PSBPcmRpbmFsID8gc2NoZW1lIDogc2NoZW1lLnNsaWNlKDAsIGNvdW50KTtcbn1cblxuZnVuY3Rpb24gYWRqdXN0U2NoZW1lKHNjaGVtZSwgZXh0ZW50LCByZXZlcnNlKSB7XG4gIHJldHVybiAoaXNGdW5jdGlvbihzY2hlbWUpICYmIChleHRlbnQgfHwgcmV2ZXJzZSkpXG4gICAgPyBpbnRlcnBvbGF0ZVJhbmdlKHNjaGVtZSwgZmxpcChleHRlbnQgfHwgWzAsIDFdLCByZXZlcnNlKSlcbiAgICA6IHNjaGVtZTtcbn1cblxuZnVuY3Rpb24gZmxpcChhcnJheSQkMSwgcmV2ZXJzZSkge1xuICByZXR1cm4gcmV2ZXJzZSA/IGFycmF5JCQxLnNsaWNlKCkucmV2ZXJzZSgpIDogYXJyYXkkJDE7XG59XG5cbmZ1bmN0aW9uIHF1YW50aXplJDQoaW50ZXJwb2xhdG9yLCBjb3VudCkge1xuICB2YXIgc2FtcGxlcyA9IG5ldyBBcnJheShjb3VudCksXG4gICAgICBuID0gKGNvdW50IC0gMSkgfHwgMTtcbiAgZm9yICh2YXIgaSA9IDA7IGkgPCBjb3VudDsgKytpKSBzYW1wbGVzW2ldID0gaW50ZXJwb2xhdG9yKGkgLyBuKTtcbiAgcmV0dXJuIHNhbXBsZXM7XG59XG5cbi8qKlxuICogU29ydHMgc2NlbmVncmFwaCBpdGVtcyBpbiB0aGUgcHVsc2Ugc291cmNlIGFycmF5LlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKCosKik6IG51bWJlcn0gW3BhcmFtcy5zb3J0XSAtIEEgY29tcGFyYXRvclxuICogICBmdW5jdGlvbiBmb3Igc29ydGluZyB0dXBsZXMuXG4gKi9cbmZ1bmN0aW9uIFNvcnRJdGVtcyhwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ2MSA9IGluaGVyaXRzKFNvcnRJdGVtcywgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDYxLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBtb2QgPSBfLm1vZGlmaWVkKCdzb3J0JylcbiAgICAgICAgIHx8IHB1bHNlLmNoYW5nZWQocHVsc2UuQUREKVxuICAgICAgICAgfHwgcHVsc2UubW9kaWZpZWQoXy5zb3J0LmZpZWxkcylcbiAgICAgICAgIHx8IHB1bHNlLm1vZGlmaWVkKCdkYXR1bScpO1xuXG4gIGlmIChtb2QpIHB1bHNlLnNvdXJjZS5zb3J0KF8uc29ydCk7XG5cbiAgdGhpcy5tb2RpZmllZChtb2QpO1xuICByZXR1cm4gcHVsc2U7XG59O1xuXG52YXIgQ2VudGVyID0gJ2NlbnRlcic7XG52YXIgTm9ybWFsaXplID0gJ25vcm1hbGl6ZSc7XG5cbi8qKlxuICogU3RhY2sgbGF5b3V0IGZvciB2aXN1YWxpemF0aW9uIGVsZW1lbnRzLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy5maWVsZCAtIFRoZSB2YWx1ZSBmaWVsZCB0byBzdGFjay5cbiAqIEBwYXJhbSB7QXJyYXk8ZnVuY3Rpb24ob2JqZWN0KTogKj59IFtwYXJhbXMuZ3JvdXBieV0gLSBBbiBhcnJheSBvZiBhY2Nlc3NvcnMgdG8gZ3JvdXBieS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0LG9iamVjdCk6IG51bWJlcn0gW3BhcmFtcy5zb3J0XSAtIEEgY29tcGFyYXRvciBmb3Igc3RhY2sgc29ydGluZy5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbb2Zmc2V0PSd6ZXJvJ10gLSBPbmUgb2YgJ3plcm8nLCAnY2VudGVyJywgJ25vcm1hbGl6ZScuXG4gKi9cbmZ1bmN0aW9uIFN0YWNrKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5TdGFjay5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJTdGFja1wiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJncm91cGJ5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwic29ydFwiLCBcInR5cGVcIjogXCJjb21wYXJlXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcIm9mZnNldFwiLCBcInR5cGVcIjogXCJlbnVtXCIsIFwiZGVmYXVsdFwiOiBcInplcm9cIiwgXCJ2YWx1ZXNcIjogW1wiemVyb1wiLCBcImNlbnRlclwiLCBcIm5vcm1hbGl6ZVwiXSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiwgXCJkZWZhdWx0XCI6IFtcInkwXCIsIFwieTFcIl0gfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDYyID0gaW5oZXJpdHMoU3RhY2ssIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ2Mi50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgYXMgPSBfLmFzIHx8IFsneTAnLCAneTEnXSxcbiAgICAgIHkwID0gYXNbMF0sXG4gICAgICB5MSA9IGFzWzFdLFxuICAgICAgZmllbGQkJDEgPSBfLmZpZWxkIHx8IG9uZSxcbiAgICAgIHN0YWNrID0gXy5vZmZzZXQgPT09IENlbnRlciA/IHN0YWNrQ2VudGVyXG4gICAgICAgICAgICA6IF8ub2Zmc2V0ID09PSBOb3JtYWxpemUgPyBzdGFja05vcm1hbGl6ZVxuICAgICAgICAgICAgOiBzdGFja1plcm8sXG4gICAgICBncm91cHMsIGksIG4sIG1heDtcblxuICAvLyBwYXJ0aXRpb24sIHN1bSwgYW5kIHNvcnQgdGhlIHN0YWNrIGdyb3Vwc1xuICBncm91cHMgPSBwYXJ0aXRpb24kMShwdWxzZS5zb3VyY2UsIF8uZ3JvdXBieSwgXy5zb3J0LCBmaWVsZCQkMSk7XG5cbiAgLy8gY29tcHV0ZSBzdGFjayBsYXlvdXRzIHBlciBncm91cFxuICBmb3IgKGk9MCwgbj1ncm91cHMubGVuZ3RoLCBtYXg9Z3JvdXBzLm1heDsgaTxuOyArK2kpIHtcbiAgICBzdGFjayhncm91cHNbaV0sIG1heCwgZmllbGQkJDEsIHkwLCB5MSk7XG4gIH1cblxuICByZXR1cm4gcHVsc2UucmVmbG93KF8ubW9kaWZpZWQoKSkubW9kaWZpZXMoYXMpO1xufTtcblxuZnVuY3Rpb24gc3RhY2tDZW50ZXIoZ3JvdXAsIG1heCwgZmllbGQkJDEsIHkwLCB5MSkge1xuICB2YXIgbGFzdCA9IChtYXggLSBncm91cC5zdW0pIC8gMixcbiAgICAgIG0gPSBncm91cC5sZW5ndGgsXG4gICAgICBqID0gMCwgdDtcblxuICBmb3IgKDsgajxtOyArK2opIHtcbiAgICB0ID0gZ3JvdXBbal07XG4gICAgdFt5MF0gPSBsYXN0O1xuICAgIHRbeTFdID0gKGxhc3QgKz0gTWF0aC5hYnMoZmllbGQkJDEodCkpKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBzdGFja05vcm1hbGl6ZShncm91cCwgbWF4LCBmaWVsZCQkMSwgeTAsIHkxKSB7XG4gIHZhciBzY2FsZSA9IDEgLyBncm91cC5zdW0sXG4gICAgICBsYXN0ID0gMCxcbiAgICAgIG0gPSBncm91cC5sZW5ndGgsXG4gICAgICBqID0gMCwgdiA9IDAsIHQ7XG5cbiAgZm9yICg7IGo8bTsgKytqKSB7XG4gICAgdCA9IGdyb3VwW2pdO1xuICAgIHRbeTBdID0gbGFzdDtcbiAgICB0W3kxXSA9IGxhc3QgPSBzY2FsZSAqICh2ICs9IE1hdGguYWJzKGZpZWxkJCQxKHQpKSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc3RhY2taZXJvKGdyb3VwLCBtYXgsIGZpZWxkJCQxLCB5MCwgeTEpIHtcbiAgdmFyIGxhc3RQb3MgPSAwLFxuICAgICAgbGFzdE5lZyA9IDAsXG4gICAgICBtID0gZ3JvdXAubGVuZ3RoLFxuICAgICAgaiA9IDAsIHYsIHQ7XG5cbiAgZm9yICg7IGo8bTsgKytqKSB7XG4gICAgdCA9IGdyb3VwW2pdO1xuICAgIHYgPSBmaWVsZCQkMSh0KTtcbiAgICBpZiAodiA8IDApIHtcbiAgICAgIHRbeTBdID0gbGFzdE5lZztcbiAgICAgIHRbeTFdID0gKGxhc3ROZWcgKz0gdik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRbeTBdID0gbGFzdFBvcztcbiAgICAgIHRbeTFdID0gKGxhc3RQb3MgKz0gdik7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHBhcnRpdGlvbiQxKGRhdGEsIGdyb3VwYnksIHNvcnQsIGZpZWxkJCQxKSB7XG4gIHZhciBncm91cHMgPSBbXSxcbiAgICAgIGdldCA9IGZ1bmN0aW9uKGYpIHsgcmV0dXJuIGYodCk7IH0sXG4gICAgICBtYXAsIGksIG4sIG0sIHQsIGssIGcsIHMsIG1heDtcblxuICAvLyBwYXJ0aXRpb24gZGF0YSBwb2ludHMgaW50byBzdGFjayBncm91cHNcbiAgaWYgKGdyb3VwYnkgPT0gbnVsbCkge1xuICAgIGdyb3Vwcy5wdXNoKGRhdGEuc2xpY2UoKSk7XG4gIH0gZWxzZSB7XG4gICAgZm9yIChtYXA9e30sIGk9MCwgbj1kYXRhLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIHQgPSBkYXRhW2ldO1xuICAgICAgayA9IGdyb3VwYnkubWFwKGdldCk7XG4gICAgICBnID0gbWFwW2tdO1xuICAgICAgaWYgKCFnKSB7XG4gICAgICAgIG1hcFtrXSA9IChnID0gW10pO1xuICAgICAgICBncm91cHMucHVzaChnKTtcbiAgICAgIH1cbiAgICAgIGcucHVzaCh0KTtcbiAgICB9XG4gIH1cblxuICAvLyBjb21wdXRlIHN1bXMgb2YgZ3JvdXBzLCBzb3J0IGdyb3VwcyBhcyBuZWVkZWRcbiAgZm9yIChrPTAsIG1heD0wLCBtPWdyb3Vwcy5sZW5ndGg7IGs8bTsgKytrKSB7XG4gICAgZyA9IGdyb3Vwc1trXTtcbiAgICBmb3IgKGk9MCwgcz0wLCBuPWcubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgcyArPSBNYXRoLmFicyhmaWVsZCQkMShnW2ldKSk7XG4gICAgfVxuICAgIGcuc3VtID0gcztcbiAgICBpZiAocyA+IG1heCkgbWF4ID0gcztcbiAgICBpZiAoc29ydCkgZy5zb3J0KHNvcnQpO1xuICB9XG4gIGdyb3Vwcy5tYXggPSBtYXg7XG5cbiAgcmV0dXJuIGdyb3Vwcztcbn1cblxuXG5cbnZhciBlbmNvZGUgPSBPYmplY3QuZnJlZXplKHtcblx0YXhpc3RpY2tzOiBBeGlzVGlja3MsXG5cdGRhdGFqb2luOiBEYXRhSm9pbixcblx0ZW5jb2RlOiBFbmNvZGUsXG5cdGxlZ2VuZGVudHJpZXM6IExlZ2VuZEVudHJpZXMsXG5cdGxpbmtwYXRoOiBMaW5rUGF0aCxcblx0cGllOiBQaWUsXG5cdHNjYWxlOiBTY2FsZSxcblx0c29ydGl0ZW1zOiBTb3J0SXRlbXMsXG5cdHN0YWNrOiBTdGFjayxcblx0dmFsaWRUaWNrczogdmFsaWRUaWNrc1xufSk7XG5cbnZhciBhcnJheSQ0ID0gQXJyYXkucHJvdG90eXBlO1xuXG52YXIgc2xpY2UkNCA9IGFycmF5JDQuc2xpY2U7XG5cbnZhciBhc2NlbmRpbmckMiA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGEgLSBiO1xufTtcblxudmFyIGFyZWEkMyA9IGZ1bmN0aW9uKHJpbmcpIHtcbiAgdmFyIGkgPSAwLCBuID0gcmluZy5sZW5ndGgsIGFyZWEgPSByaW5nW24gLSAxXVsxXSAqIHJpbmdbMF1bMF0gLSByaW5nW24gLSAxXVswXSAqIHJpbmdbMF1bMV07XG4gIHdoaWxlICgrK2kgPCBuKSBhcmVhICs9IHJpbmdbaSAtIDFdWzFdICogcmluZ1tpXVswXSAtIHJpbmdbaSAtIDFdWzBdICogcmluZ1tpXVsxXTtcbiAgcmV0dXJuIGFyZWE7XG59O1xuXG52YXIgY29uc3RhbnQkNiA9IGZ1bmN0aW9uKHgpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB4O1xuICB9O1xufTtcblxudmFyIGNvbnRhaW5zID0gZnVuY3Rpb24ocmluZywgaG9sZSkge1xuICB2YXIgaSA9IC0xLCBuID0gaG9sZS5sZW5ndGgsIGM7XG4gIHdoaWxlICgrK2kgPCBuKSBpZiAoYyA9IHJpbmdDb250YWlucyhyaW5nLCBob2xlW2ldKSkgcmV0dXJuIGM7XG4gIHJldHVybiAwO1xufTtcblxuZnVuY3Rpb24gcmluZ0NvbnRhaW5zKHJpbmcsIHBvaW50KSB7XG4gIHZhciB4ID0gcG9pbnRbMF0sIHkgPSBwb2ludFsxXSwgY29udGFpbnMgPSAtMTtcbiAgZm9yICh2YXIgaSA9IDAsIG4gPSByaW5nLmxlbmd0aCwgaiA9IG4gLSAxOyBpIDwgbjsgaiA9IGkrKykge1xuICAgIHZhciBwaSA9IHJpbmdbaV0sIHhpID0gcGlbMF0sIHlpID0gcGlbMV0sIHBqID0gcmluZ1tqXSwgeGogPSBwalswXSwgeWogPSBwalsxXTtcbiAgICBpZiAoc2VnbWVudENvbnRhaW5zKHBpLCBwaiwgcG9pbnQpKSByZXR1cm4gMDtcbiAgICBpZiAoKCh5aSA+IHkpICE9PSAoeWogPiB5KSkgJiYgKCh4IDwgKHhqIC0geGkpICogKHkgLSB5aSkgLyAoeWogLSB5aSkgKyB4aSkpKSBjb250YWlucyA9IC1jb250YWlucztcbiAgfVxuICByZXR1cm4gY29udGFpbnM7XG59XG5cbmZ1bmN0aW9uIHNlZ21lbnRDb250YWlucyhhLCBiLCBjKSB7XG4gIHZhciBpOyByZXR1cm4gY29sbGluZWFyKGEsIGIsIGMpICYmIHdpdGhpbihhW2kgPSArKGFbMF0gPT09IGJbMF0pXSwgY1tpXSwgYltpXSk7XG59XG5cbmZ1bmN0aW9uIGNvbGxpbmVhcihhLCBiLCBjKSB7XG4gIHJldHVybiAoYlswXSAtIGFbMF0pICogKGNbMV0gLSBhWzFdKSA9PT0gKGNbMF0gLSBhWzBdKSAqIChiWzFdIC0gYVsxXSk7XG59XG5cbmZ1bmN0aW9uIHdpdGhpbihwLCBxLCByKSB7XG4gIHJldHVybiBwIDw9IHEgJiYgcSA8PSByIHx8IHIgPD0gcSAmJiBxIDw9IHA7XG59XG5cbnZhciBub29wJDMgPSBmdW5jdGlvbigpIHt9O1xuXG52YXIgY2FzZXMgPSBbXG4gIFtdLFxuICBbW1sxLjAsIDEuNV0sIFswLjUsIDEuMF1dXSxcbiAgW1tbMS41LCAxLjBdLCBbMS4wLCAxLjVdXV0sXG4gIFtbWzEuNSwgMS4wXSwgWzAuNSwgMS4wXV1dLFxuICBbW1sxLjAsIDAuNV0sIFsxLjUsIDEuMF1dXSxcbiAgW1tbMS4wLCAxLjVdLCBbMC41LCAxLjBdXSwgW1sxLjAsIDAuNV0sIFsxLjUsIDEuMF1dXSxcbiAgW1tbMS4wLCAwLjVdLCBbMS4wLCAxLjVdXV0sXG4gIFtbWzEuMCwgMC41XSwgWzAuNSwgMS4wXV1dLFxuICBbW1swLjUsIDEuMF0sIFsxLjAsIDAuNV1dXSxcbiAgW1tbMS4wLCAxLjVdLCBbMS4wLCAwLjVdXV0sXG4gIFtbWzAuNSwgMS4wXSwgWzEuMCwgMC41XV0sIFtbMS41LCAxLjBdLCBbMS4wLCAxLjVdXV0sXG4gIFtbWzEuNSwgMS4wXSwgWzEuMCwgMC41XV1dLFxuICBbW1swLjUsIDEuMF0sIFsxLjUsIDEuMF1dXSxcbiAgW1tbMS4wLCAxLjVdLCBbMS41LCAxLjBdXV0sXG4gIFtbWzAuNSwgMS4wXSwgWzEuMCwgMS41XV1dLFxuICBbXVxuXTtcblxudmFyIGNvbnRvdXJzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICB0aHJlc2hvbGQkJDEgPSB0aHJlc2hvbGRTdHVyZ2VzLFxuICAgICAgc21vb3RoID0gc21vb3RoTGluZWFyO1xuXG4gIGZ1bmN0aW9uIGNvbnRvdXJzKHZhbHVlcykge1xuICAgIHZhciB0eiA9IHRocmVzaG9sZCQkMSh2YWx1ZXMpO1xuXG4gICAgLy8gQ29udmVydCBudW1iZXIgb2YgdGhyZXNob2xkcyBpbnRvIHVuaWZvcm0gdGhyZXNob2xkcy5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodHopKSB7XG4gICAgICB2YXIgZG9tYWluID0gZXh0ZW50KHZhbHVlcyksIHN0YXJ0ID0gZG9tYWluWzBdLCBzdG9wID0gZG9tYWluWzFdO1xuICAgICAgdHogPSB0aWNrU3RlcChzdGFydCwgc3RvcCwgdHopO1xuICAgICAgdHogPSBzZXF1ZW5jZShNYXRoLmZsb29yKHN0YXJ0IC8gdHopICogdHosIE1hdGguZmxvb3Ioc3RvcCAvIHR6KSAqIHR6LCB0eik7XG4gICAgfSBlbHNlIHtcbiAgICAgIHR6ID0gdHouc2xpY2UoKS5zb3J0KGFzY2VuZGluZyQyKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdHoubWFwKGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgICByZXR1cm4gY29udG91cih2YWx1ZXMsIHZhbHVlKTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIEFjY3VtdWxhdGUsIHNtb290aCBjb250b3VyIHJpbmdzLCBhc3NpZ24gaG9sZXMgdG8gZXh0ZXJpb3IgcmluZ3MuXG4gIC8vIEJhc2VkIG9uIGh0dHBzOi8vZ2l0aHViLmNvbS9tYm9zdG9jay9zaGFwZWZpbGUvYmxvYi92MC42LjIvc2hwL3BvbHlnb24uanNcbiAgZnVuY3Rpb24gY29udG91cih2YWx1ZXMsIHZhbHVlKSB7XG4gICAgdmFyIHBvbHlnb25zID0gW10sXG4gICAgICAgIGhvbGVzID0gW107XG5cbiAgICBpc29yaW5ncyh2YWx1ZXMsIHZhbHVlLCBmdW5jdGlvbihyaW5nKSB7XG4gICAgICBzbW9vdGgocmluZywgdmFsdWVzLCB2YWx1ZSk7XG4gICAgICBpZiAoYXJlYSQzKHJpbmcpID4gMCkgcG9seWdvbnMucHVzaChbcmluZ10pO1xuICAgICAgZWxzZSBob2xlcy5wdXNoKHJpbmcpO1xuICAgIH0pO1xuXG4gICAgaG9sZXMuZm9yRWFjaChmdW5jdGlvbihob2xlKSB7XG4gICAgICBmb3IgKHZhciBpID0gMCwgbiA9IHBvbHlnb25zLmxlbmd0aCwgcG9seWdvbjsgaSA8IG47ICsraSkge1xuICAgICAgICBpZiAoY29udGFpbnMoKHBvbHlnb24gPSBwb2x5Z29uc1tpXSlbMF0sIGhvbGUpICE9PSAtMSkge1xuICAgICAgICAgIHBvbHlnb24ucHVzaChob2xlKTtcbiAgICAgICAgICByZXR1cm47XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9KTtcblxuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBcIk11bHRpUG9seWdvblwiLFxuICAgICAgdmFsdWU6IHZhbHVlLFxuICAgICAgY29vcmRpbmF0ZXM6IHBvbHlnb25zXG4gICAgfTtcbiAgfVxuXG4gIC8vIE1hcmNoaW5nIHNxdWFyZXMgd2l0aCBpc29saW5lcyBzdGl0Y2hlZCBpbnRvIHJpbmdzLlxuICAvLyBCYXNlZCBvbiBodHRwczovL2dpdGh1Yi5jb20vdG9wb2pzb24vdG9wb2pzb24tY2xpZW50L2Jsb2IvdjMuMC4wL3NyYy9zdGl0Y2guanNcbiAgZnVuY3Rpb24gaXNvcmluZ3ModmFsdWVzLCB2YWx1ZSwgY2FsbGJhY2spIHtcbiAgICB2YXIgZnJhZ21lbnRCeVN0YXJ0ID0gbmV3IEFycmF5LFxuICAgICAgICBmcmFnbWVudEJ5RW5kID0gbmV3IEFycmF5LFxuICAgICAgICB4LCB5LCB0MCwgdDEsIHQyLCB0MztcblxuICAgIC8vIFNwZWNpYWwgY2FzZSBmb3IgdGhlIGZpcnN0IHJvdyAoeSA9IC0xLCB0MiA9IHQzID0gMCkuXG4gICAgeCA9IHkgPSAtMTtcbiAgICB0MSA9IHZhbHVlc1swXSA+PSB2YWx1ZTtcbiAgICBjYXNlc1t0MSA8PCAxXS5mb3JFYWNoKHN0aXRjaCk7XG4gICAgd2hpbGUgKCsreCA8IGR4IC0gMSkge1xuICAgICAgdDAgPSB0MSwgdDEgPSB2YWx1ZXNbeCArIDFdID49IHZhbHVlO1xuICAgICAgY2FzZXNbdDAgfCB0MSA8PCAxXS5mb3JFYWNoKHN0aXRjaCk7XG4gICAgfVxuICAgIGNhc2VzW3QxIDw8IDBdLmZvckVhY2goc3RpdGNoKTtcblxuICAgIC8vIEdlbmVyYWwgY2FzZSBmb3IgdGhlIGludGVybWVkaWF0ZSByb3dzLlxuICAgIHdoaWxlICgrK3kgPCBkeSAtIDEpIHtcbiAgICAgIHggPSAtMTtcbiAgICAgIHQxID0gdmFsdWVzW3kgKiBkeCArIGR4XSA+PSB2YWx1ZTtcbiAgICAgIHQyID0gdmFsdWVzW3kgKiBkeF0gPj0gdmFsdWU7XG4gICAgICBjYXNlc1t0MSA8PCAxIHwgdDIgPDwgMl0uZm9yRWFjaChzdGl0Y2gpO1xuICAgICAgd2hpbGUgKCsreCA8IGR4IC0gMSkge1xuICAgICAgICB0MCA9IHQxLCB0MSA9IHZhbHVlc1t5ICogZHggKyBkeCArIHggKyAxXSA+PSB2YWx1ZTtcbiAgICAgICAgdDMgPSB0MiwgdDIgPSB2YWx1ZXNbeSAqIGR4ICsgeCArIDFdID49IHZhbHVlO1xuICAgICAgICBjYXNlc1t0MCB8IHQxIDw8IDEgfCB0MiA8PCAyIHwgdDMgPDwgM10uZm9yRWFjaChzdGl0Y2gpO1xuICAgICAgfVxuICAgICAgY2FzZXNbdDEgfCB0MiA8PCAzXS5mb3JFYWNoKHN0aXRjaCk7XG4gICAgfVxuXG4gICAgLy8gU3BlY2lhbCBjYXNlIGZvciB0aGUgbGFzdCByb3cgKHkgPSBkeSAtIDEsIHQwID0gdDEgPSAwKS5cbiAgICB4ID0gLTE7XG4gICAgdDIgPSB2YWx1ZXNbeSAqIGR4XSA+PSB2YWx1ZTtcbiAgICBjYXNlc1t0MiA8PCAyXS5mb3JFYWNoKHN0aXRjaCk7XG4gICAgd2hpbGUgKCsreCA8IGR4IC0gMSkge1xuICAgICAgdDMgPSB0MiwgdDIgPSB2YWx1ZXNbeSAqIGR4ICsgeCArIDFdID49IHZhbHVlO1xuICAgICAgY2FzZXNbdDIgPDwgMiB8IHQzIDw8IDNdLmZvckVhY2goc3RpdGNoKTtcbiAgICB9XG4gICAgY2FzZXNbdDIgPDwgM10uZm9yRWFjaChzdGl0Y2gpO1xuXG4gICAgZnVuY3Rpb24gc3RpdGNoKGxpbmUpIHtcbiAgICAgIHZhciBzdGFydCA9IFtsaW5lWzBdWzBdICsgeCwgbGluZVswXVsxXSArIHldLFxuICAgICAgICAgIGVuZCA9IFtsaW5lWzFdWzBdICsgeCwgbGluZVsxXVsxXSArIHldLFxuICAgICAgICAgIHN0YXJ0SW5kZXggPSBpbmRleChzdGFydCksXG4gICAgICAgICAgZW5kSW5kZXggPSBpbmRleChlbmQpLFxuICAgICAgICAgIGYsIGc7XG4gICAgICBpZiAoZiA9IGZyYWdtZW50QnlFbmRbc3RhcnRJbmRleF0pIHtcbiAgICAgICAgaWYgKGcgPSBmcmFnbWVudEJ5U3RhcnRbZW5kSW5kZXhdKSB7XG4gICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlFbmRbZi5lbmRdO1xuICAgICAgICAgIGRlbGV0ZSBmcmFnbWVudEJ5U3RhcnRbZy5zdGFydF07XG4gICAgICAgICAgaWYgKGYgPT09IGcpIHtcbiAgICAgICAgICAgIGYucmluZy5wdXNoKGVuZCk7XG4gICAgICAgICAgICBjYWxsYmFjayhmLnJpbmcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcmFnbWVudEJ5U3RhcnRbZi5zdGFydF0gPSBmcmFnbWVudEJ5RW5kW2cuZW5kXSA9IHtzdGFydDogZi5zdGFydCwgZW5kOiBnLmVuZCwgcmluZzogZi5yaW5nLmNvbmNhdChnLnJpbmcpfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlFbmRbZi5lbmRdO1xuICAgICAgICAgIGYucmluZy5wdXNoKGVuZCk7XG4gICAgICAgICAgZnJhZ21lbnRCeUVuZFtmLmVuZCA9IGVuZEluZGV4XSA9IGY7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSBpZiAoZiA9IGZyYWdtZW50QnlTdGFydFtlbmRJbmRleF0pIHtcbiAgICAgICAgaWYgKGcgPSBmcmFnbWVudEJ5RW5kW3N0YXJ0SW5kZXhdKSB7XG4gICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlTdGFydFtmLnN0YXJ0XTtcbiAgICAgICAgICBkZWxldGUgZnJhZ21lbnRCeUVuZFtnLmVuZF07XG4gICAgICAgICAgaWYgKGYgPT09IGcpIHtcbiAgICAgICAgICAgIGYucmluZy5wdXNoKGVuZCk7XG4gICAgICAgICAgICBjYWxsYmFjayhmLnJpbmcpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBmcmFnbWVudEJ5U3RhcnRbZy5zdGFydF0gPSBmcmFnbWVudEJ5RW5kW2YuZW5kXSA9IHtzdGFydDogZy5zdGFydCwgZW5kOiBmLmVuZCwgcmluZzogZy5yaW5nLmNvbmNhdChmLnJpbmcpfTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgZGVsZXRlIGZyYWdtZW50QnlTdGFydFtmLnN0YXJ0XTtcbiAgICAgICAgICBmLnJpbmcudW5zaGlmdChzdGFydCk7XG4gICAgICAgICAgZnJhZ21lbnRCeVN0YXJ0W2Yuc3RhcnQgPSBzdGFydEluZGV4XSA9IGY7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGZyYWdtZW50QnlTdGFydFtzdGFydEluZGV4XSA9IGZyYWdtZW50QnlFbmRbZW5kSW5kZXhdID0ge3N0YXJ0OiBzdGFydEluZGV4LCBlbmQ6IGVuZEluZGV4LCByaW5nOiBbc3RhcnQsIGVuZF19O1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluZGV4KHBvaW50KSB7XG4gICAgcmV0dXJuIHBvaW50WzBdICogMiArIHBvaW50WzFdICogKGR4ICsgMSkgKiA0O1xuICB9XG5cbiAgZnVuY3Rpb24gc21vb3RoTGluZWFyKHJpbmcsIHZhbHVlcywgdmFsdWUpIHtcbiAgICByaW5nLmZvckVhY2goZnVuY3Rpb24ocG9pbnQpIHtcbiAgICAgIHZhciB4ID0gcG9pbnRbMF0sXG4gICAgICAgICAgeSA9IHBvaW50WzFdLFxuICAgICAgICAgIHh0ID0geCB8IDAsXG4gICAgICAgICAgeXQgPSB5IHwgMCxcbiAgICAgICAgICB2MCxcbiAgICAgICAgICB2MSA9IHZhbHVlc1t5dCAqIGR4ICsgeHRdO1xuICAgICAgaWYgKHggPiAwICYmIHggPCBkeCAmJiB4dCA9PT0geCkge1xuICAgICAgICB2MCA9IHZhbHVlc1t5dCAqIGR4ICsgeHQgLSAxXTtcbiAgICAgICAgcG9pbnRbMF0gPSB4ICsgKHZhbHVlIC0gdjApIC8gKHYxIC0gdjApIC0gMC41O1xuICAgICAgfVxuICAgICAgaWYgKHkgPiAwICYmIHkgPCBkeSAmJiB5dCA9PT0geSkge1xuICAgICAgICB2MCA9IHZhbHVlc1soeXQgLSAxKSAqIGR4ICsgeHRdO1xuICAgICAgICBwb2ludFsxXSA9IHkgKyAodmFsdWUgLSB2MCkgLyAodjEgLSB2MCkgLSAwLjU7XG4gICAgICB9XG4gICAgfSk7XG4gIH1cblxuICBjb250b3Vycy5jb250b3VyID0gY29udG91cjtcblxuICBjb250b3Vycy5zaXplID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtkeCwgZHldO1xuICAgIHZhciBfMCA9IE1hdGguY2VpbChfWzBdKSwgXzEgPSBNYXRoLmNlaWwoX1sxXSk7XG4gICAgaWYgKCEoXzAgPiAwKSB8fCAhKF8xID4gMCkpIHRocm93IG5ldyBFcnJvcihcImludmFsaWQgc2l6ZVwiKTtcbiAgICByZXR1cm4gZHggPSBfMCwgZHkgPSBfMSwgY29udG91cnM7XG4gIH07XG5cbiAgY29udG91cnMudGhyZXNob2xkcyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aHJlc2hvbGQkJDEgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IEFycmF5LmlzQXJyYXkoXykgPyBjb25zdGFudCQ2KHNsaWNlJDQuY2FsbChfKSkgOiBjb25zdGFudCQ2KF8pLCBjb250b3VycykgOiB0aHJlc2hvbGQkJDE7XG4gIH07XG5cbiAgY29udG91cnMuc21vb3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNtb290aCA9IF8gPyBzbW9vdGhMaW5lYXIgOiBub29wJDMsIGNvbnRvdXJzKSA6IHNtb290aCA9PT0gc21vb3RoTGluZWFyO1xuICB9O1xuXG4gIHJldHVybiBjb250b3Vycztcbn07XG5cbi8vIFRPRE8gT3B0aW1pemUgZWRnZSBjYXNlcy5cbi8vIFRPRE8gT3B0aW1pemUgaW5kZXggY2FsY3VsYXRpb24uXG4vLyBUT0RPIE9wdGltaXplIGFyZ3VtZW50cy5cbmZ1bmN0aW9uIGJsdXJYKHNvdXJjZSwgdGFyZ2V0LCByKSB7XG4gIHZhciBuID0gc291cmNlLndpZHRoLFxuICAgICAgbSA9IHNvdXJjZS5oZWlnaHQsXG4gICAgICB3ID0gKHIgPDwgMSkgKyAxO1xuICBmb3IgKHZhciBqID0gMDsgaiA8IG07ICsraikge1xuICAgIGZvciAodmFyIGkgPSAwLCBzciA9IDA7IGkgPCBuICsgcjsgKytpKSB7XG4gICAgICBpZiAoaSA8IG4pIHtcbiAgICAgICAgc3IgKz0gc291cmNlLmRhdGFbaSArIGogKiBuXTtcbiAgICAgIH1cbiAgICAgIGlmIChpID49IHIpIHtcbiAgICAgICAgaWYgKGkgPj0gdykge1xuICAgICAgICAgIHNyIC09IHNvdXJjZS5kYXRhW2kgLSB3ICsgaiAqIG5dO1xuICAgICAgICB9XG4gICAgICAgIHRhcmdldC5kYXRhW2kgLSByICsgaiAqIG5dID0gc3IgLyBNYXRoLm1pbihpICsgMSwgbiAtIDEgKyB3IC0gaSwgdyk7XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbi8vIFRPRE8gT3B0aW1pemUgZWRnZSBjYXNlcy5cbi8vIFRPRE8gT3B0aW1pemUgaW5kZXggY2FsY3VsYXRpb24uXG4vLyBUT0RPIE9wdGltaXplIGFyZ3VtZW50cy5cbmZ1bmN0aW9uIGJsdXJZKHNvdXJjZSwgdGFyZ2V0LCByKSB7XG4gIHZhciBuID0gc291cmNlLndpZHRoLFxuICAgICAgbSA9IHNvdXJjZS5oZWlnaHQsXG4gICAgICB3ID0gKHIgPDwgMSkgKyAxO1xuICBmb3IgKHZhciBpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGZvciAodmFyIGogPSAwLCBzciA9IDA7IGogPCBtICsgcjsgKytqKSB7XG4gICAgICBpZiAoaiA8IG0pIHtcbiAgICAgICAgc3IgKz0gc291cmNlLmRhdGFbaSArIGogKiBuXTtcbiAgICAgIH1cbiAgICAgIGlmIChqID49IHIpIHtcbiAgICAgICAgaWYgKGogPj0gdykge1xuICAgICAgICAgIHNyIC09IHNvdXJjZS5kYXRhW2kgKyAoaiAtIHcpICogbl07XG4gICAgICAgIH1cbiAgICAgICAgdGFyZ2V0LmRhdGFbaSArIChqIC0gcikgKiBuXSA9IHNyIC8gTWF0aC5taW4oaiArIDEsIG0gLSAxICsgdyAtIGosIHcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBkZWZhdWx0WChkKSB7XG4gIHJldHVybiBkWzBdO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0WShkKSB7XG4gIHJldHVybiBkWzFdO1xufVxuXG52YXIgY29udG91ckRlbnNpdHkgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHggPSBkZWZhdWx0WCxcbiAgICAgIHkgPSBkZWZhdWx0WSxcbiAgICAgIGR4ID0gOTYwLFxuICAgICAgZHkgPSA1MDAsXG4gICAgICByID0gMjAsIC8vIGJsdXIgcmFkaXVzXG4gICAgICBrID0gMiwgLy8gbG9nMihncmlkIGNlbGwgc2l6ZSlcbiAgICAgIG8gPSByICogMywgLy8gZ3JpZCBvZmZzZXQsIHRvIHBhZCBmb3IgYmx1clxuICAgICAgbiA9IChkeCArIG8gKiAyKSA+PiBrLCAvLyBncmlkIHdpZHRoXG4gICAgICBtID0gKGR5ICsgbyAqIDIpID4+IGssIC8vIGdyaWQgaGVpZ2h0XG4gICAgICB0aHJlc2hvbGQkJDEgPSBjb25zdGFudCQ2KDIwKTtcblxuICBmdW5jdGlvbiBkZW5zaXR5KGRhdGEpIHtcbiAgICB2YXIgdmFsdWVzMCA9IG5ldyBGbG9hdDMyQXJyYXkobiAqIG0pLFxuICAgICAgICB2YWx1ZXMxID0gbmV3IEZsb2F0MzJBcnJheShuICogbSk7XG5cbiAgICBkYXRhLmZvckVhY2goZnVuY3Rpb24oZCwgaSwgZGF0YSkge1xuICAgICAgdmFyIHhpID0gKHgoZCwgaSwgZGF0YSkgKyBvKSA+PiBrLFxuICAgICAgICAgIHlpID0gKHkoZCwgaSwgZGF0YSkgKyBvKSA+PiBrO1xuICAgICAgaWYgKHhpID49IDAgJiYgeGkgPCBuICYmIHlpID49IDAgJiYgeWkgPCBtKSB7XG4gICAgICAgICsrdmFsdWVzMFt4aSArIHlpICogbl07XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICAvLyBUT0RPIE9wdGltaXplLlxuICAgIGJsdXJYKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMwfSwge3dpZHRoOiBuLCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczF9LCByID4+IGspO1xuICAgIGJsdXJZKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMxfSwge3dpZHRoOiBuLCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczB9LCByID4+IGspO1xuICAgIGJsdXJYKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMwfSwge3dpZHRoOiBuLCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczF9LCByID4+IGspO1xuICAgIGJsdXJZKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMxfSwge3dpZHRoOiBuLCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczB9LCByID4+IGspO1xuICAgIGJsdXJYKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMwfSwge3dpZHRoOiBuLCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczF9LCByID4+IGspO1xuICAgIGJsdXJZKHt3aWR0aDogbiwgaGVpZ2h0OiBtLCBkYXRhOiB2YWx1ZXMxfSwge3dpZHRoOiBuLCBoZWlnaHQ6IG0sIGRhdGE6IHZhbHVlczB9LCByID4+IGspO1xuXG4gICAgdmFyIHR6ID0gdGhyZXNob2xkJCQxKHZhbHVlczApO1xuXG4gICAgLy8gQ29udmVydCBudW1iZXIgb2YgdGhyZXNob2xkcyBpbnRvIHVuaWZvcm0gdGhyZXNob2xkcy5cbiAgICBpZiAoIUFycmF5LmlzQXJyYXkodHopKSB7XG4gICAgICB2YXIgc3RvcCA9IG1heCh2YWx1ZXMwKTtcbiAgICAgIHR6ID0gdGlja1N0ZXAoMCwgc3RvcCwgdHopO1xuICAgICAgdHogPSBzZXF1ZW5jZSgwLCBNYXRoLmZsb29yKHN0b3AgLyB0eikgKiB0eiwgdHopO1xuICAgICAgdHouc2hpZnQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gY29udG91cnMoKVxuICAgICAgICAudGhyZXNob2xkcyh0eilcbiAgICAgICAgLnNpemUoW24sIG1dKVxuICAgICAgKHZhbHVlczApXG4gICAgICAgIC5tYXAodHJhbnNmb3JtKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zZm9ybShnZW9tZXRyeSkge1xuICAgIGdlb21ldHJ5LnZhbHVlICo9IE1hdGgucG93KDIsIC0yICogayk7IC8vIERlbnNpdHkgaW4gcG9pbnRzIHBlciBzcXVhcmUgcGl4ZWwuXG4gICAgZ2VvbWV0cnkuY29vcmRpbmF0ZXMuZm9yRWFjaCh0cmFuc2Zvcm1Qb2x5Z29uKTtcbiAgICByZXR1cm4gZ2VvbWV0cnk7XG4gIH1cblxuICBmdW5jdGlvbiB0cmFuc2Zvcm1Qb2x5Z29uKGNvb3JkaW5hdGVzKSB7XG4gICAgY29vcmRpbmF0ZXMuZm9yRWFjaCh0cmFuc2Zvcm1SaW5nKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHRyYW5zZm9ybVJpbmcoY29vcmRpbmF0ZXMpIHtcbiAgICBjb29yZGluYXRlcy5mb3JFYWNoKHRyYW5zZm9ybVBvaW50KTtcbiAgfVxuXG4gIC8vIFRPRE8gT3B0aW1pemUuXG4gIGZ1bmN0aW9uIHRyYW5zZm9ybVBvaW50KGNvb3JkaW5hdGVzKSB7XG4gICAgY29vcmRpbmF0ZXNbMF0gPSBjb29yZGluYXRlc1swXSAqIE1hdGgucG93KDIsIGspIC0gbztcbiAgICBjb29yZGluYXRlc1sxXSA9IGNvb3JkaW5hdGVzWzFdICogTWF0aC5wb3coMiwgaykgLSBvO1xuICB9XG5cbiAgZnVuY3Rpb24gcmVzaXplKCkge1xuICAgIG8gPSByICogMztcbiAgICBuID0gKGR4ICsgbyAqIDIpID4+IGs7XG4gICAgbSA9IChkeSArIG8gKiAyKSA+PiBrO1xuICAgIHJldHVybiBkZW5zaXR5O1xuICB9XG5cbiAgZGVuc2l0eS54ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHggPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDYoK18pLCBkZW5zaXR5KSA6IHg7XG4gIH07XG5cbiAgZGVuc2l0eS55ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHkgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDYoK18pLCBkZW5zaXR5KSA6IHk7XG4gIH07XG5cbiAgZGVuc2l0eS5zaXplID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIFtkeCwgZHldO1xuICAgIHZhciBfMCA9IE1hdGguY2VpbChfWzBdKSwgXzEgPSBNYXRoLmNlaWwoX1sxXSk7XG4gICAgaWYgKCEoXzAgPj0gMCkgJiYgIShfMCA+PSAwKSkgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBzaXplXCIpO1xuICAgIHJldHVybiBkeCA9IF8wLCBkeSA9IF8xLCByZXNpemUoKTtcbiAgfTtcblxuICBkZW5zaXR5LmNlbGxTaXplID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIDEgPDwgaztcbiAgICBpZiAoISgoXyA9ICtfKSA+PSAxKSkgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBjZWxsIHNpemVcIik7XG4gICAgcmV0dXJuIGsgPSBNYXRoLmZsb29yKE1hdGgubG9nKF8pIC8gTWF0aC5MTjIpLCByZXNpemUoKTtcbiAgfTtcblxuICBkZW5zaXR5LnRocmVzaG9sZHMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGhyZXNob2xkJCQxID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBBcnJheS5pc0FycmF5KF8pID8gY29uc3RhbnQkNihzbGljZSQ0LmNhbGwoXykpIDogY29uc3RhbnQkNihfKSwgZGVuc2l0eSkgOiB0aHJlc2hvbGQkJDE7XG4gIH07XG5cbiAgZGVuc2l0eS5iYW5kd2lkdGggPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gTWF0aC5zcXJ0KHIgKiAociArIDEpKTtcbiAgICBpZiAoISgoXyA9ICtfKSA+PSAwKSkgdGhyb3cgbmV3IEVycm9yKFwiaW52YWxpZCBiYW5kd2lkdGhcIik7XG4gICAgcmV0dXJuIHIgPSBNYXRoLnJvdW5kKChNYXRoLnNxcnQoNCAqIF8gKiBfICsgMSkgLSAxKSAvIDIpLCByZXNpemUoKTtcbiAgfTtcblxuICByZXR1cm4gZGVuc2l0eTtcbn07XG5cbnZhciBDT05UT1VSX1BBUkFNUyA9IFsndmFsdWVzJywgJ3NpemUnXTtcbnZhciBERU5TSVRZX1BBUkFNUyA9IFsneCcsICd5JywgJ3NpemUnLCAnY2VsbFNpemUnLCAnYmFuZHdpZHRoJ107XG5cbi8qKlxuICogR2VuZXJhdGUgY29udG91cnMgYmFzZWQgb24ga2VybmVsLWRlbnNpdHkgZXN0aW1hdGlvbiBvZiBwb2ludCBkYXRhLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge0FycmF5PG51bWJlcj59IHBhcmFtcy5zaXplIC0gVGhlIGRpbWVuc2lvbnMgW3dpZHRoLCBoZWlnaHRdIG92ZXIgd2hpY2ggdG8gY29tcHV0ZSBjb250b3Vycy5cbiAqICBJZiB0aGUgdmFsdWVzIHBhcmFtZXRlciBpcyBwcm92aWRlZCwgdGhpcyBtdXN0IGJlIHRoZSBkaW1lbnNpb25zIG9mIHRoZSBpbnB1dCBkYXRhLlxuICogIElmIGRlbnNpdHkgZXN0aW1hdGlvbiBpcyBwZXJmb3JtZWQsIHRoaXMgaXMgdGhlIG91dHB1dCB2aWV3IGRpbWVuc2lvbnMgaW4gcGl4ZWxzLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBbcGFyYW1zLnZhbHVlc10gLSBBbiBhcnJheSBvZiBudW1lcmljIHZhbHVlcyByZXByZXNlbnRpbmcgYW5cbiAqICB3aWR0aCB4IGhlaWdodCBncmlkIG9mIHZhbHVlcyBvdmVyIHdoaWNoIHRvIGNvbXB1dGUgY29udG91cnMuIElmIHVuc3BlY2lmaWVkLCB0aGlzXG4gKiAgdHJhbnNmb3JtIHdpbGwgaW5zdGVhZCBhdHRlbXB0IHRvIGNvbXB1dGUgY29udG91cnMgZm9yIHRoZSBrZXJuZWwgZGVuc2l0eSBlc3RpbWF0ZVxuICogIHVzaW5nIHZhbHVlcyBkcmF3biBmcm9tIGRhdGEgdHVwbGVzIGluIHRoZSBpbnB1dCBwdWxzZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogbnVtYmVyfSBbcGFyYW1zLnhdIC0gVGhlIHBpeGVsIHgtY29vcmRpbmF0ZSBhY2Nlc3NvciBmb3IgZGVuc2l0eSBlc3RpbWF0aW9uLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiBudW1iZXJ9IFtwYXJhbXMueV0gLSBUaGUgcGl4ZWwgeS1jb29yZGluYXRlIGFjY2Vzc29yIGZvciBkZW5zaXR5IGVzdGltYXRpb24uXG4gKiBAcGFyYW0ge251bWJlcn0gW3BhcmFtcy5jZWxsU2l6ZV0gLSBDb250b3VyIGRlbnNpdHkgY2FsY3VsYXRpb24gY2VsbCBzaXplLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJhbXMuYmFuZHdpZHRoXSAtIEtlcm5lbCBkZW5zaXR5IGVzdGltYXRpb24gYmFuZHdpZHRoLlxuICogQHBhcmFtIHtBcnJheTxudW1iZXI+fSBbcGFyYW1zLnRocmVzaG9sZHNdIC0gQ29udG91ciB0aHJlc2hvbGQgYXJyYXkuIElmXG4gKiAgIHRoaXMgcGFyYW1ldGVyIGlzIHNldCwgdGhlIGNvdW50IGFuZCBuaWNlIHBhcmFtZXRlcnMgd2lsbCBiZSBpZ25vcmVkLlxuICogQHBhcmFtIHtudW1iZXJ9IFtwYXJhbXMuY291bnRdIC0gVGhlIGRlc2lyZWQgbnVtYmVyIG9mIGNvbnRvdXJzLlxuICogQHBhcmFtIHtib29sZWFufSBbcGFyYW1zLm5pY2VdIC0gQm9vbGVhbiBmbGFnIGluZGljYXRpbmcgaWYgdGhlIGNvbnRvdXJcbiAqICAgdGhyZXNob2xkIHZhbHVlcyBzaG91bGQgYmUgYXV0b21hdGljYWxseSBhbGlnbmVkIHRvIFwibmljZVwiXG4gKiAgIGh1bWFuLWZyaWVuZGx5IHZhbHVlcy4gU2V0dGluZyB0aGlzIGZsYWcgbWF5IGNhdXNlIHRoZSBudW1iZXIgb2ZcbiAqICAgdGhyZXNob2xkcyB0byBkZXZpYXRlIGZyb20gdGhlIHNwZWNpZmllZCBjb3VudC5cbiAqL1xuZnVuY3Rpb24gQ29udG91cihwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxuQ29udG91ci5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJDb250b3VyXCIsXG4gIFwibWV0YWRhdGFcIjoge1wiZ2VuZXJhdGVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJzaXplXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwidmFsdWVzXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcInhcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwieVwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJjZWxsU2l6ZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYmFuZHdpZHRoXCIsIFwidHlwZVwiOiBcIm51bWJlclwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJjb3VudFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwibmljZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IGZhbHNlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJ0aHJlc2hvbGRzXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDYzID0gaW5oZXJpdHMoQ29udG91ciwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDYzLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGlmICh0aGlzLnZhbHVlICYmICFwdWxzZS5jaGFuZ2VkKCkgJiYgIV8ubW9kaWZpZWQoKSlcbiAgICByZXR1cm4gcHVsc2UuU3RvcFByb3BhZ2F0aW9uO1xuXG4gIHZhciBvdXQgPSBwdWxzZS5mb3JrKHB1bHNlLk5PX1NPVVJDRSB8IHB1bHNlLk5PX0ZJRUxEUyksXG4gICAgICBjb3VudCA9IF8uY291bnQgfHwgMTAsXG4gICAgICBjb250b3VyLCBwYXJhbXMsIHZhbHVlcztcblxuICBpZiAoXy52YWx1ZXMpIHtcbiAgICBjb250b3VyID0gY29udG91cnMoKTtcbiAgICBwYXJhbXMgPSBDT05UT1VSX1BBUkFNUztcbiAgICB2YWx1ZXMgPSBfLnZhbHVlcztcbiAgfSBlbHNlIHtcbiAgICBjb250b3VyID0gY29udG91ckRlbnNpdHkoKTtcbiAgICBwYXJhbXMgPSBERU5TSVRZX1BBUkFNUztcbiAgICB2YWx1ZXMgPSBwdWxzZS5tYXRlcmlhbGl6ZShwdWxzZS5TT1VSQ0UpLnNvdXJjZTtcbiAgfVxuXG4gIC8vIHNldCB0aHJlc2hvbGQgcGFyYW1ldGVyXG4gIGNvbnRvdXIudGhyZXNob2xkcyhfLnRocmVzaG9sZHMgfHwgKF8ubmljZSA/IGNvdW50IDogcXVhbnRpemUkNShjb3VudCkpKTtcblxuICAvLyBzZXQgYWxsIG90aGVyIHBhcmFtZXRlcnNcbiAgcGFyYW1zLmZvckVhY2goZnVuY3Rpb24ocGFyYW0pIHtcbiAgICBpZiAoX1twYXJhbV0gIT0gbnVsbCkgY29udG91cltwYXJhbV0oX1twYXJhbV0pO1xuICB9KTtcblxuICBpZiAodGhpcy52YWx1ZSkgb3V0LnJlbSA9IHRoaXMudmFsdWU7XG4gIHZhbHVlcyA9IHZhbHVlcyAmJiB2YWx1ZXMubGVuZ3RoID8gY29udG91cih2YWx1ZXMpLm1hcChpbmdlc3QpIDogW107XG4gIHRoaXMudmFsdWUgPSBvdXQuc291cmNlID0gb3V0LmFkZCA9IHZhbHVlcztcblxuICByZXR1cm4gb3V0O1xufTtcblxuZnVuY3Rpb24gcXVhbnRpemUkNShrKSB7XG4gIHJldHVybiBmdW5jdGlvbih2YWx1ZXMpIHtcbiAgICB2YXIgZXggPSBleHRlbnQodmFsdWVzKSwgeDAgPSBleFswXSwgZHggPSBleFsxXSAtIHgwLFxuICAgICAgICB0ID0gW10sIGkgPSAxO1xuICAgIGZvciAoOyBpPD1rOyArK2kpIHQucHVzaCh4MCArIGR4ICogaSAvIChrICsgMSkpO1xuICAgIHJldHVybiB0O1xuICB9O1xufVxuXG52YXIgRmVhdHVyZSA9ICdGZWF0dXJlJztcbnZhciBGZWF0dXJlQ29sbGVjdGlvbiA9ICdGZWF0dXJlQ29sbGVjdGlvbic7XG52YXIgTXVsdGlQb2ludCA9ICdNdWx0aVBvaW50JztcblxuLyoqXG4gKiBDb25zb2xpZGF0ZSBhbiBhcnJheSBvZiBbbG9uZ2l0dWRlLCBsYXRpdHVkZV0gcG9pbnRzIG9yIEdlb0pTT04gZmVhdHVyZXNcbiAqIGludG8gYSBjb21iaW5lZCBHZW9KU09OIG9iamVjdC4gVGhpcyB0cmFuc2Zvcm0gaXMgcGFydGljdWxhcmx5IHVzZWZ1bCBmb3JcbiAqIGNvbWJpbmluZyBnZW8gZGF0YSBmb3IgYSBQcm9qZWN0aW9uJ3MgZml0IGFyZ3VtZW50LiBUaGUgcmVzdWx0aW5nIEdlb0pTT05cbiAqIGRhdGEgaXMgYXZhaWxhYmxlIGFzIHRoaXMgdHJhbnNmb3JtJ3MgdmFsdWUuIElucHV0IHB1bHNlcyBhcmUgdW5jaGFuZ2VkLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKiBAcGFyYW0ge0FycmF5PGZ1bmN0aW9uKG9iamVjdCk6ICo+fSBbcGFyYW1zLmZpZWxkc10gLSBBIHR3by1lbGVtZW50IGFycmF5XG4gKiAgIG9mIGZpZWxkIGFjY2Vzc29ycyBmb3IgdGhlIGxvbmdpdHVkZSBhbmQgbGF0aXR1ZGUgdmFsdWVzLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZ2VvanNvbiAtIEEgZmllbGQgYWNjZXNzb3IgZm9yXG4gKiAgIHJldHJpZXZpbmcgR2VvSlNPTiBmZWF0dXJlIGRhdGEuXG4gKi9cbmZ1bmN0aW9uIEdlb0pTT04ocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cbkdlb0pTT04uRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiR2VvSlNPTlwiLFxuICBcIm1ldGFkYXRhXCI6IHt9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZHNcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiAyIH0sXG4gICAgeyBcIm5hbWVcIjogXCJnZW9qc29uXCIsIFwidHlwZVwiOiBcImZpZWxkXCIgfSxcbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQ2NCA9IGluaGVyaXRzKEdlb0pTT04sIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ2NC50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgZmVhdHVyZXMgPSB0aGlzLl9mZWF0dXJlcyxcbiAgICAgIHBvaW50cyA9IHRoaXMuX3BvaW50cyxcbiAgICAgIGZpZWxkcyA9IF8uZmllbGRzLFxuICAgICAgbG9uID0gZmllbGRzICYmIGZpZWxkc1swXSxcbiAgICAgIGxhdCA9IGZpZWxkcyAmJiBmaWVsZHNbMV0sXG4gICAgICBnZW9qc29uID0gXy5nZW9qc29uLFxuICAgICAgZmxhZyA9IHB1bHNlLkFERCxcbiAgICAgIG1vZDtcblxuICBtb2QgPSBfLm1vZGlmaWVkKClcbiAgICB8fCBwdWxzZS5jaGFuZ2VkKHB1bHNlLlJFTSlcbiAgICB8fCBwdWxzZS5tb2RpZmllZChhY2Nlc3NvckZpZWxkcyhnZW9qc29uKSlcbiAgICB8fCAobG9uICYmIChwdWxzZS5tb2RpZmllZChhY2Nlc3NvckZpZWxkcyhsb24pKSkpXG4gICAgfHwgKGxhdCAmJiAocHVsc2UubW9kaWZpZWQoYWNjZXNzb3JGaWVsZHMobGF0KSkpKTtcblxuICBpZiAoIXRoaXMudmFsdWUgfHwgbW9kKSB7XG4gICAgZmxhZyA9IHB1bHNlLlNPVVJDRTtcbiAgICB0aGlzLl9mZWF0dXJlcyA9IChmZWF0dXJlcyA9IFtdKTtcbiAgICB0aGlzLl9wb2ludHMgPSAocG9pbnRzID0gW10pO1xuICB9XG5cbiAgaWYgKGdlb2pzb24pIHtcbiAgICBwdWxzZS52aXNpdChmbGFnLCBmdW5jdGlvbih0KSB7XG4gICAgICBmZWF0dXJlcy5wdXNoKGdlb2pzb24odCkpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGxvbiAmJiBsYXQpIHtcbiAgICBwdWxzZS52aXNpdChmbGFnLCBmdW5jdGlvbih0KSB7XG4gICAgICB2YXIgeCA9IGxvbih0KSxcbiAgICAgICAgICB5ID0gbGF0KHQpO1xuICAgICAgaWYgKHggIT0gbnVsbCAmJiB5ICE9IG51bGwgJiYgKHggPSAreCkgPT09IHggJiYgKHkgPSAreSkgPT09IHkpIHtcbiAgICAgICAgcG9pbnRzLnB1c2goW3gsIHldKTtcbiAgICAgIH1cbiAgICB9KTtcbiAgICBmZWF0dXJlcyA9IGZlYXR1cmVzLmNvbmNhdCh7XG4gICAgICB0eXBlOiBGZWF0dXJlLFxuICAgICAgZ2VvbWV0cnk6IHtcbiAgICAgICAgdHlwZTogTXVsdGlQb2ludCxcbiAgICAgICAgY29vcmRpbmF0ZXM6IHBvaW50c1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgdGhpcy52YWx1ZSA9IHtcbiAgICB0eXBlOiBGZWF0dXJlQ29sbGVjdGlvbixcbiAgICBmZWF0dXJlczogZmVhdHVyZXNcbiAgfTtcbn07XG5cbi8vIEFkZHMgZmxvYXRpbmcgcG9pbnQgbnVtYmVycyB3aXRoIHR3aWNlIHRoZSBub3JtYWwgcHJlY2lzaW9uLlxuLy8gUmVmZXJlbmNlOiBKLiBSLiBTaGV3Y2h1aywgQWRhcHRpdmUgUHJlY2lzaW9uIEZsb2F0aW5nLVBvaW50IEFyaXRobWV0aWMgYW5kXG4vLyBGYXN0IFJvYnVzdCBHZW9tZXRyaWMgUHJlZGljYXRlcywgRGlzY3JldGUgJiBDb21wdXRhdGlvbmFsIEdlb21ldHJ5IDE4KDMpXG4vLyAzMDXigJMzNjMgKDE5OTcpLlxuLy8gQ29kZSBhZGFwdGVkIGZyb20gR2VvZ3JhcGhpY0xpYiBieSBDaGFybGVzIEYuIEYuIEthcm5leSxcbi8vIGh0dHA6Ly9nZW9ncmFwaGljbGliLnNvdXJjZWZvcmdlLm5ldC9cblxudmFyIGFkZGVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBuZXcgQWRkZXI7XG59O1xuXG5mdW5jdGlvbiBBZGRlcigpIHtcbiAgdGhpcy5yZXNldCgpO1xufVxuXG5BZGRlci5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBBZGRlcixcbiAgcmVzZXQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMucyA9IC8vIHJvdW5kZWQgdmFsdWVcbiAgICB0aGlzLnQgPSAwOyAvLyBleGFjdCBlcnJvclxuICB9LFxuICBhZGQ6IGZ1bmN0aW9uKHkpIHtcbiAgICBhZGQkMyh0ZW1wJDEsIHksIHRoaXMudCk7XG4gICAgYWRkJDModGhpcywgdGVtcCQxLnMsIHRoaXMucyk7XG4gICAgaWYgKHRoaXMucykgdGhpcy50ICs9IHRlbXAkMS50O1xuICAgIGVsc2UgdGhpcy5zID0gdGVtcCQxLnQ7XG4gIH0sXG4gIHZhbHVlT2Y6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0aGlzLnM7XG4gIH1cbn07XG5cbnZhciB0ZW1wJDEgPSBuZXcgQWRkZXI7XG5cbmZ1bmN0aW9uIGFkZCQzKGFkZGVyLCBhLCBiKSB7XG4gIHZhciB4ID0gYWRkZXIucyA9IGEgKyBiLFxuICAgICAgYnYgPSB4IC0gYSxcbiAgICAgIGF2ID0geCAtIGJ2O1xuICBhZGRlci50ID0gKGEgLSBhdikgKyAoYiAtIGJ2KTtcbn1cblxudmFyIGVwc2lsb24kMiA9IDFlLTY7XG52YXIgZXBzaWxvbjIkMSA9IDFlLTEyO1xudmFyIHBpJDMgPSBNYXRoLlBJO1xudmFyIGhhbGZQaSQyID0gcGkkMyAvIDI7XG52YXIgcXVhcnRlclBpID0gcGkkMyAvIDQ7XG52YXIgdGF1JDQgPSBwaSQzICogMjtcblxudmFyIGRlZ3JlZXMkMSA9IDE4MCAvIHBpJDM7XG52YXIgcmFkaWFucyA9IHBpJDMgLyAxODA7XG5cbnZhciBhYnMkMSA9IE1hdGguYWJzO1xudmFyIGF0YW4gPSBNYXRoLmF0YW47XG52YXIgYXRhbjIkMSA9IE1hdGguYXRhbjI7XG52YXIgY29zJDEgPSBNYXRoLmNvcztcbnZhciBjZWlsID0gTWF0aC5jZWlsO1xudmFyIGV4cCQxID0gTWF0aC5leHA7XG5cbnZhciBsb2ckMyA9IE1hdGgubG9nO1xudmFyIHBvdyQyID0gTWF0aC5wb3c7XG52YXIgc2luJDEgPSBNYXRoLnNpbjtcbnZhciBzaWduJDEgPSBNYXRoLnNpZ24gfHwgZnVuY3Rpb24oeCkgeyByZXR1cm4geCA+IDAgPyAxIDogeCA8IDAgPyAtMSA6IDA7IH07XG52YXIgc3FydCQyID0gTWF0aC5zcXJ0O1xudmFyIHRhbiA9IE1hdGgudGFuO1xuXG5mdW5jdGlvbiBhY29zJDEoeCkge1xuICByZXR1cm4geCA+IDEgPyAwIDogeCA8IC0xID8gcGkkMyA6IE1hdGguYWNvcyh4KTtcbn1cblxuZnVuY3Rpb24gYXNpbiQxKHgpIHtcbiAgcmV0dXJuIHggPiAxID8gaGFsZlBpJDIgOiB4IDwgLTEgPyAtaGFsZlBpJDIgOiBNYXRoLmFzaW4oeCk7XG59XG5cbmZ1bmN0aW9uIG5vb3AkNCgpIHt9XG5cbmZ1bmN0aW9uIHN0cmVhbUdlb21ldHJ5KGdlb21ldHJ5LCBzdHJlYW0pIHtcbiAgaWYgKGdlb21ldHJ5ICYmIHN0cmVhbUdlb21ldHJ5VHlwZS5oYXNPd25Qcm9wZXJ0eShnZW9tZXRyeS50eXBlKSkge1xuICAgIHN0cmVhbUdlb21ldHJ5VHlwZVtnZW9tZXRyeS50eXBlXShnZW9tZXRyeSwgc3RyZWFtKTtcbiAgfVxufVxuXG52YXIgc3RyZWFtT2JqZWN0VHlwZSA9IHtcbiAgRmVhdHVyZTogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICBzdHJlYW1HZW9tZXRyeShvYmplY3QuZ2VvbWV0cnksIHN0cmVhbSk7XG4gIH0sXG4gIEZlYXR1cmVDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHZhciBmZWF0dXJlcyA9IG9iamVjdC5mZWF0dXJlcywgaSA9IC0xLCBuID0gZmVhdHVyZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBzdHJlYW1HZW9tZXRyeShmZWF0dXJlc1tpXS5nZW9tZXRyeSwgc3RyZWFtKTtcbiAgfVxufTtcblxudmFyIHN0cmVhbUdlb21ldHJ5VHlwZSA9IHtcbiAgU3BoZXJlOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHN0cmVhbS5zcGhlcmUoKTtcbiAgfSxcbiAgUG9pbnQ6IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgb2JqZWN0ID0gb2JqZWN0LmNvb3JkaW5hdGVzO1xuICAgIHN0cmVhbS5wb2ludChvYmplY3RbMF0sIG9iamVjdFsxXSwgb2JqZWN0WzJdKTtcbiAgfSxcbiAgTXVsdGlQb2ludDogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICB2YXIgY29vcmRpbmF0ZXMgPSBvYmplY3QuY29vcmRpbmF0ZXMsIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgb2JqZWN0ID0gY29vcmRpbmF0ZXNbaV0sIHN0cmVhbS5wb2ludChvYmplY3RbMF0sIG9iamVjdFsxXSwgb2JqZWN0WzJdKTtcbiAgfSxcbiAgTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICBzdHJlYW1MaW5lKG9iamVjdC5jb29yZGluYXRlcywgc3RyZWFtLCAwKTtcbiAgfSxcbiAgTXVsdGlMaW5lU3RyaW5nOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBzdHJlYW1MaW5lKGNvb3JkaW5hdGVzW2ldLCBzdHJlYW0sIDApO1xuICB9LFxuICBQb2x5Z29uOiBmdW5jdGlvbihvYmplY3QsIHN0cmVhbSkge1xuICAgIHN0cmVhbVBvbHlnb24ob2JqZWN0LmNvb3JkaW5hdGVzLCBzdHJlYW0pO1xuICB9LFxuICBNdWx0aVBvbHlnb246IGZ1bmN0aW9uKG9iamVjdCwgc3RyZWFtKSB7XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIHN0cmVhbVBvbHlnb24oY29vcmRpbmF0ZXNbaV0sIHN0cmVhbSk7XG4gIH0sXG4gIEdlb21ldHJ5Q29sbGVjdGlvbjogZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgICB2YXIgZ2VvbWV0cmllcyA9IG9iamVjdC5nZW9tZXRyaWVzLCBpID0gLTEsIG4gPSBnZW9tZXRyaWVzLmxlbmd0aDtcbiAgICB3aGlsZSAoKytpIDwgbikgc3RyZWFtR2VvbWV0cnkoZ2VvbWV0cmllc1tpXSwgc3RyZWFtKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gc3RyZWFtTGluZShjb29yZGluYXRlcywgc3RyZWFtLCBjbG9zZWQpIHtcbiAgdmFyIGkgPSAtMSwgbiA9IGNvb3JkaW5hdGVzLmxlbmd0aCAtIGNsb3NlZCwgY29vcmRpbmF0ZTtcbiAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICB3aGlsZSAoKytpIDwgbikgY29vcmRpbmF0ZSA9IGNvb3JkaW5hdGVzW2ldLCBzdHJlYW0ucG9pbnQoY29vcmRpbmF0ZVswXSwgY29vcmRpbmF0ZVsxXSwgY29vcmRpbmF0ZVsyXSk7XG4gIHN0cmVhbS5saW5lRW5kKCk7XG59XG5cbmZ1bmN0aW9uIHN0cmVhbVBvbHlnb24oY29vcmRpbmF0ZXMsIHN0cmVhbSkge1xuICB2YXIgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICBzdHJlYW0ucG9seWdvblN0YXJ0KCk7XG4gIHdoaWxlICgrK2kgPCBuKSBzdHJlYW1MaW5lKGNvb3JkaW5hdGVzW2ldLCBzdHJlYW0sIDEpO1xuICBzdHJlYW0ucG9seWdvbkVuZCgpO1xufVxuXG52YXIgZ2VvU3RyZWFtID0gZnVuY3Rpb24ob2JqZWN0LCBzdHJlYW0pIHtcbiAgaWYgKG9iamVjdCAmJiBzdHJlYW1PYmplY3RUeXBlLmhhc093blByb3BlcnR5KG9iamVjdC50eXBlKSkge1xuICAgIHN0cmVhbU9iamVjdFR5cGVbb2JqZWN0LnR5cGVdKG9iamVjdCwgc3RyZWFtKTtcbiAgfSBlbHNlIHtcbiAgICBzdHJlYW1HZW9tZXRyeShvYmplY3QsIHN0cmVhbSk7XG4gIH1cbn07XG5cbnZhciBhcmVhUmluZ1N1bSA9IGFkZGVyKCk7XG5cbnZhciBhcmVhU3VtID0gYWRkZXIoKTtcbnZhciBsYW1iZGEwMDtcbnZhciBwaGkwMDtcbnZhciBsYW1iZGEwO1xudmFyIGNvc1BoaTA7XG52YXIgc2luUGhpMDtcblxudmFyIGFyZWFTdHJlYW0gPSB7XG4gIHBvaW50OiBub29wJDQsXG4gIGxpbmVTdGFydDogbm9vcCQ0LFxuICBsaW5lRW5kOiBub29wJDQsXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgYXJlYVJpbmdTdW0ucmVzZXQoKTtcbiAgICBhcmVhU3RyZWFtLmxpbmVTdGFydCA9IGFyZWFSaW5nU3RhcnQ7XG4gICAgYXJlYVN0cmVhbS5saW5lRW5kID0gYXJlYVJpbmdFbmQ7XG4gIH0sXG4gIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHZhciBhcmVhUmluZyA9ICthcmVhUmluZ1N1bTtcbiAgICBhcmVhU3VtLmFkZChhcmVhUmluZyA8IDAgPyB0YXUkNCArIGFyZWFSaW5nIDogYXJlYVJpbmcpO1xuICAgIHRoaXMubGluZVN0YXJ0ID0gdGhpcy5saW5lRW5kID0gdGhpcy5wb2ludCA9IG5vb3AkNDtcbiAgfSxcbiAgc3BoZXJlOiBmdW5jdGlvbigpIHtcbiAgICBhcmVhU3VtLmFkZCh0YXUkNCk7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGFyZWFSaW5nU3RhcnQoKSB7XG4gIGFyZWFTdHJlYW0ucG9pbnQgPSBhcmVhUG9pbnRGaXJzdDtcbn1cblxuZnVuY3Rpb24gYXJlYVJpbmdFbmQoKSB7XG4gIGFyZWFQb2ludChsYW1iZGEwMCwgcGhpMDApO1xufVxuXG5mdW5jdGlvbiBhcmVhUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkge1xuICBhcmVhU3RyZWFtLnBvaW50ID0gYXJlYVBvaW50O1xuICBsYW1iZGEwMCA9IGxhbWJkYSwgcGhpMDAgPSBwaGk7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgbGFtYmRhMCA9IGxhbWJkYSwgY29zUGhpMCA9IGNvcyQxKHBoaSA9IHBoaSAvIDIgKyBxdWFydGVyUGkpLCBzaW5QaGkwID0gc2luJDEocGhpKTtcbn1cblxuZnVuY3Rpb24gYXJlYVBvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgcGhpID0gcGhpIC8gMiArIHF1YXJ0ZXJQaTsgLy8gaGFsZiB0aGUgYW5ndWxhciBkaXN0YW5jZSBmcm9tIHNvdXRoIHBvbGVcblxuICAvLyBTcGhlcmljYWwgZXhjZXNzIEUgZm9yIGEgc3BoZXJpY2FsIHRyaWFuZ2xlIHdpdGggdmVydGljZXM6IHNvdXRoIHBvbGUsXG4gIC8vIHByZXZpb3VzIHBvaW50LCBjdXJyZW50IHBvaW50LiAgVXNlcyBhIGZvcm11bGEgZGVyaXZlZCBmcm9tIENhZ25vbGnigJlzXG4gIC8vIHRoZW9yZW0uICBTZWUgVG9kaHVudGVyLCBTcGhlcmljYWwgVHJpZy4gKDE4NzEpLCBTZWMuIDEwMywgRXEuICgyKS5cbiAgdmFyIGRMYW1iZGEgPSBsYW1iZGEgLSBsYW1iZGEwLFxuICAgICAgc2RMYW1iZGEgPSBkTGFtYmRhID49IDAgPyAxIDogLTEsXG4gICAgICBhZExhbWJkYSA9IHNkTGFtYmRhICogZExhbWJkYSxcbiAgICAgIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICBzaW5QaGkgPSBzaW4kMShwaGkpLFxuICAgICAgayA9IHNpblBoaTAgKiBzaW5QaGksXG4gICAgICB1ID0gY29zUGhpMCAqIGNvc1BoaSArIGsgKiBjb3MkMShhZExhbWJkYSksXG4gICAgICB2ID0gayAqIHNkTGFtYmRhICogc2luJDEoYWRMYW1iZGEpO1xuICBhcmVhUmluZ1N1bS5hZGQoYXRhbjIkMSh2LCB1KSk7XG5cbiAgLy8gQWR2YW5jZSB0aGUgcHJldmlvdXMgcG9pbnRzLlxuICBsYW1iZGEwID0gbGFtYmRhLCBjb3NQaGkwID0gY29zUGhpLCBzaW5QaGkwID0gc2luUGhpO1xufVxuXG52YXIgYXJlYSQ0ID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gIGFyZWFTdW0ucmVzZXQoKTtcbiAgZ2VvU3RyZWFtKG9iamVjdCwgYXJlYVN0cmVhbSk7XG4gIHJldHVybiBhcmVhU3VtICogMjtcbn07XG5cbmZ1bmN0aW9uIHNwaGVyaWNhbChjYXJ0ZXNpYW4pIHtcbiAgcmV0dXJuIFthdGFuMiQxKGNhcnRlc2lhblsxXSwgY2FydGVzaWFuWzBdKSwgYXNpbiQxKGNhcnRlc2lhblsyXSldO1xufVxuXG5mdW5jdGlvbiBjYXJ0ZXNpYW4oc3BoZXJpY2FsKSB7XG4gIHZhciBsYW1iZGEgPSBzcGhlcmljYWxbMF0sIHBoaSA9IHNwaGVyaWNhbFsxXSwgY29zUGhpID0gY29zJDEocGhpKTtcbiAgcmV0dXJuIFtjb3NQaGkgKiBjb3MkMShsYW1iZGEpLCBjb3NQaGkgKiBzaW4kMShsYW1iZGEpLCBzaW4kMShwaGkpXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuRG90KGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gKiBiWzBdICsgYVsxXSAqIGJbMV0gKyBhWzJdICogYlsyXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuQ3Jvc3MoYSwgYikge1xuICByZXR1cm4gW2FbMV0gKiBiWzJdIC0gYVsyXSAqIGJbMV0sIGFbMl0gKiBiWzBdIC0gYVswXSAqIGJbMl0sIGFbMF0gKiBiWzFdIC0gYVsxXSAqIGJbMF1dO1xufVxuXG4vLyBUT0RPIHJldHVybiBhXG5mdW5jdGlvbiBjYXJ0ZXNpYW5BZGRJblBsYWNlKGEsIGIpIHtcbiAgYVswXSArPSBiWzBdLCBhWzFdICs9IGJbMV0sIGFbMl0gKz0gYlsyXTtcbn1cblxuZnVuY3Rpb24gY2FydGVzaWFuU2NhbGUodmVjdG9yLCBrKSB7XG4gIHJldHVybiBbdmVjdG9yWzBdICogaywgdmVjdG9yWzFdICogaywgdmVjdG9yWzJdICoga107XG59XG5cbi8vIFRPRE8gcmV0dXJuIGRcbmZ1bmN0aW9uIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoZCkge1xuICB2YXIgbCA9IHNxcnQkMihkWzBdICogZFswXSArIGRbMV0gKiBkWzFdICsgZFsyXSAqIGRbMl0pO1xuICBkWzBdIC89IGwsIGRbMV0gLz0gbCwgZFsyXSAvPSBsO1xufVxuXG52YXIgbGFtYmRhMCQxO1xudmFyIHBoaTA7XG52YXIgbGFtYmRhMTtcbnZhciBwaGkxO1xudmFyIGxhbWJkYTI7XG52YXIgbGFtYmRhMDAkMTtcbnZhciBwaGkwMCQxO1xudmFyIHAwO1xudmFyIGRlbHRhU3VtID0gYWRkZXIoKTtcbnZhciByYW5nZXM7XG52YXIgcmFuZ2U7XG5cbnZhciBib3VuZHNTdHJlYW0gPSB7XG4gIHBvaW50OiBib3VuZHNQb2ludCxcbiAgbGluZVN0YXJ0OiBib3VuZHNMaW5lU3RhcnQsXG4gIGxpbmVFbmQ6IGJvdW5kc0xpbmVFbmQsXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgYm91bmRzU3RyZWFtLnBvaW50ID0gYm91bmRzUmluZ1BvaW50O1xuICAgIGJvdW5kc1N0cmVhbS5saW5lU3RhcnQgPSBib3VuZHNSaW5nU3RhcnQ7XG4gICAgYm91bmRzU3RyZWFtLmxpbmVFbmQgPSBib3VuZHNSaW5nRW5kO1xuICAgIGRlbHRhU3VtLnJlc2V0KCk7XG4gICAgYXJlYVN0cmVhbS5wb2x5Z29uU3RhcnQoKTtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgYXJlYVN0cmVhbS5wb2x5Z29uRW5kKCk7XG4gICAgYm91bmRzU3RyZWFtLnBvaW50ID0gYm91bmRzUG9pbnQ7XG4gICAgYm91bmRzU3RyZWFtLmxpbmVTdGFydCA9IGJvdW5kc0xpbmVTdGFydDtcbiAgICBib3VuZHNTdHJlYW0ubGluZUVuZCA9IGJvdW5kc0xpbmVFbmQ7XG4gICAgaWYgKGFyZWFSaW5nU3VtIDwgMCkgbGFtYmRhMCQxID0gLShsYW1iZGExID0gMTgwKSwgcGhpMCA9IC0ocGhpMSA9IDkwKTtcbiAgICBlbHNlIGlmIChkZWx0YVN1bSA+IGVwc2lsb24kMikgcGhpMSA9IDkwO1xuICAgIGVsc2UgaWYgKGRlbHRhU3VtIDwgLWVwc2lsb24kMikgcGhpMCA9IC05MDtcbiAgICByYW5nZVswXSA9IGxhbWJkYTAkMSwgcmFuZ2VbMV0gPSBsYW1iZGExO1xuICB9XG59O1xuXG5mdW5jdGlvbiBib3VuZHNQb2ludChsYW1iZGEsIHBoaSkge1xuICByYW5nZXMucHVzaChyYW5nZSA9IFtsYW1iZGEwJDEgPSBsYW1iZGEsIGxhbWJkYTEgPSBsYW1iZGFdKTtcbiAgaWYgKHBoaSA8IHBoaTApIHBoaTAgPSBwaGk7XG4gIGlmIChwaGkgPiBwaGkxKSBwaGkxID0gcGhpO1xufVxuXG5mdW5jdGlvbiBsaW5lUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgdmFyIHAgPSBjYXJ0ZXNpYW4oW2xhbWJkYSAqIHJhZGlhbnMsIHBoaSAqIHJhZGlhbnNdKTtcbiAgaWYgKHAwKSB7XG4gICAgdmFyIG5vcm1hbCA9IGNhcnRlc2lhbkNyb3NzKHAwLCBwKSxcbiAgICAgICAgZXF1YXRvcmlhbCA9IFtub3JtYWxbMV0sIC1ub3JtYWxbMF0sIDBdLFxuICAgICAgICBpbmZsZWN0aW9uID0gY2FydGVzaWFuQ3Jvc3MoZXF1YXRvcmlhbCwgbm9ybWFsKTtcbiAgICBjYXJ0ZXNpYW5Ob3JtYWxpemVJblBsYWNlKGluZmxlY3Rpb24pO1xuICAgIGluZmxlY3Rpb24gPSBzcGhlcmljYWwoaW5mbGVjdGlvbik7XG4gICAgdmFyIGRlbHRhID0gbGFtYmRhIC0gbGFtYmRhMixcbiAgICAgICAgc2lnbiA9IGRlbHRhID4gMCA/IDEgOiAtMSxcbiAgICAgICAgbGFtYmRhaSA9IGluZmxlY3Rpb25bMF0gKiBkZWdyZWVzJDEgKiBzaWduLFxuICAgICAgICBwaGlpLFxuICAgICAgICBhbnRpbWVyaWRpYW4gPSBhYnMkMShkZWx0YSkgPiAxODA7XG4gICAgaWYgKGFudGltZXJpZGlhbiBeIChzaWduICogbGFtYmRhMiA8IGxhbWJkYWkgJiYgbGFtYmRhaSA8IHNpZ24gKiBsYW1iZGEpKSB7XG4gICAgICBwaGlpID0gaW5mbGVjdGlvblsxXSAqIGRlZ3JlZXMkMTtcbiAgICAgIGlmIChwaGlpID4gcGhpMSkgcGhpMSA9IHBoaWk7XG4gICAgfSBlbHNlIGlmIChsYW1iZGFpID0gKGxhbWJkYWkgKyAzNjApICUgMzYwIC0gMTgwLCBhbnRpbWVyaWRpYW4gXiAoc2lnbiAqIGxhbWJkYTIgPCBsYW1iZGFpICYmIGxhbWJkYWkgPCBzaWduICogbGFtYmRhKSkge1xuICAgICAgcGhpaSA9IC1pbmZsZWN0aW9uWzFdICogZGVncmVlcyQxO1xuICAgICAgaWYgKHBoaWkgPCBwaGkwKSBwaGkwID0gcGhpaTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKHBoaSA8IHBoaTApIHBoaTAgPSBwaGk7XG4gICAgICBpZiAocGhpID4gcGhpMSkgcGhpMSA9IHBoaTtcbiAgICB9XG4gICAgaWYgKGFudGltZXJpZGlhbikge1xuICAgICAgaWYgKGxhbWJkYSA8IGxhbWJkYTIpIHtcbiAgICAgICAgaWYgKGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhKSA+IGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhMSkpIGxhbWJkYTEgPSBsYW1iZGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoYW5nbGUobGFtYmRhLCBsYW1iZGExKSA+IGFuZ2xlKGxhbWJkYTAkMSwgbGFtYmRhMSkpIGxhbWJkYTAkMSA9IGxhbWJkYTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGxhbWJkYTEgPj0gbGFtYmRhMCQxKSB7XG4gICAgICAgIGlmIChsYW1iZGEgPCBsYW1iZGEwJDEpIGxhbWJkYTAkMSA9IGxhbWJkYTtcbiAgICAgICAgaWYgKGxhbWJkYSA+IGxhbWJkYTEpIGxhbWJkYTEgPSBsYW1iZGE7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAobGFtYmRhID4gbGFtYmRhMikge1xuICAgICAgICAgIGlmIChhbmdsZShsYW1iZGEwJDEsIGxhbWJkYSkgPiBhbmdsZShsYW1iZGEwJDEsIGxhbWJkYTEpKSBsYW1iZGExID0gbGFtYmRhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhbmdsZShsYW1iZGEsIGxhbWJkYTEpID4gYW5nbGUobGFtYmRhMCQxLCBsYW1iZGExKSkgbGFtYmRhMCQxID0gbGFtYmRhO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHJhbmdlcy5wdXNoKHJhbmdlID0gW2xhbWJkYTAkMSA9IGxhbWJkYSwgbGFtYmRhMSA9IGxhbWJkYV0pO1xuICB9XG4gIGlmIChwaGkgPCBwaGkwKSBwaGkwID0gcGhpO1xuICBpZiAocGhpID4gcGhpMSkgcGhpMSA9IHBoaTtcbiAgcDAgPSBwLCBsYW1iZGEyID0gbGFtYmRhO1xufVxuXG5mdW5jdGlvbiBib3VuZHNMaW5lU3RhcnQoKSB7XG4gIGJvdW5kc1N0cmVhbS5wb2ludCA9IGxpbmVQb2ludDtcbn1cblxuZnVuY3Rpb24gYm91bmRzTGluZUVuZCgpIHtcbiAgcmFuZ2VbMF0gPSBsYW1iZGEwJDEsIHJhbmdlWzFdID0gbGFtYmRhMTtcbiAgYm91bmRzU3RyZWFtLnBvaW50ID0gYm91bmRzUG9pbnQ7XG4gIHAwID0gbnVsbDtcbn1cblxuZnVuY3Rpb24gYm91bmRzUmluZ1BvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGlmIChwMCkge1xuICAgIHZhciBkZWx0YSA9IGxhbWJkYSAtIGxhbWJkYTI7XG4gICAgZGVsdGFTdW0uYWRkKGFicyQxKGRlbHRhKSA+IDE4MCA/IGRlbHRhICsgKGRlbHRhID4gMCA/IDM2MCA6IC0zNjApIDogZGVsdGEpO1xuICB9IGVsc2Uge1xuICAgIGxhbWJkYTAwJDEgPSBsYW1iZGEsIHBoaTAwJDEgPSBwaGk7XG4gIH1cbiAgYXJlYVN0cmVhbS5wb2ludChsYW1iZGEsIHBoaSk7XG4gIGxpbmVQb2ludChsYW1iZGEsIHBoaSk7XG59XG5cbmZ1bmN0aW9uIGJvdW5kc1JpbmdTdGFydCgpIHtcbiAgYXJlYVN0cmVhbS5saW5lU3RhcnQoKTtcbn1cblxuZnVuY3Rpb24gYm91bmRzUmluZ0VuZCgpIHtcbiAgYm91bmRzUmluZ1BvaW50KGxhbWJkYTAwJDEsIHBoaTAwJDEpO1xuICBhcmVhU3RyZWFtLmxpbmVFbmQoKTtcbiAgaWYgKGFicyQxKGRlbHRhU3VtKSA+IGVwc2lsb24kMikgbGFtYmRhMCQxID0gLShsYW1iZGExID0gMTgwKTtcbiAgcmFuZ2VbMF0gPSBsYW1iZGEwJDEsIHJhbmdlWzFdID0gbGFtYmRhMTtcbiAgcDAgPSBudWxsO1xufVxuXG4vLyBGaW5kcyB0aGUgbGVmdC1yaWdodCBkaXN0YW5jZSBiZXR3ZWVuIHR3byBsb25naXR1ZGVzLlxuLy8gVGhpcyBpcyBhbG1vc3QgdGhlIHNhbWUgYXMgKGxhbWJkYTEgLSBsYW1iZGEwICsgMzYwwrApICUgMzYwwrAsIGV4Y2VwdCB0aGF0IHdlIHdhbnRcbi8vIHRoZSBkaXN0YW5jZSBiZXR3ZWVuIMKxMTgwwrAgdG8gYmUgMzYwwrAuXG5mdW5jdGlvbiBhbmdsZShsYW1iZGEwLCBsYW1iZGExKSB7XG4gIHJldHVybiAobGFtYmRhMSAtPSBsYW1iZGEwKSA8IDAgPyBsYW1iZGExICsgMzYwIDogbGFtYmRhMTtcbn1cblxuZnVuY3Rpb24gcmFuZ2VDb21wYXJlKGEsIGIpIHtcbiAgcmV0dXJuIGFbMF0gLSBiWzBdO1xufVxuXG5mdW5jdGlvbiByYW5nZUNvbnRhaW5zKHJhbmdlLCB4KSB7XG4gIHJldHVybiByYW5nZVswXSA8PSByYW5nZVsxXSA/IHJhbmdlWzBdIDw9IHggJiYgeCA8PSByYW5nZVsxXSA6IHggPCByYW5nZVswXSB8fCByYW5nZVsxXSA8IHg7XG59XG5cbnZhciBib3VuZHMkMSA9IGZ1bmN0aW9uKGZlYXR1cmUpIHtcbiAgdmFyIGksIG4sIGEsIGIsIG1lcmdlZCwgZGVsdGFNYXgsIGRlbHRhO1xuXG4gIHBoaTEgPSBsYW1iZGExID0gLShsYW1iZGEwJDEgPSBwaGkwID0gSW5maW5pdHkpO1xuICByYW5nZXMgPSBbXTtcbiAgZ2VvU3RyZWFtKGZlYXR1cmUsIGJvdW5kc1N0cmVhbSk7XG5cbiAgLy8gRmlyc3QsIHNvcnQgcmFuZ2VzIGJ5IHRoZWlyIG1pbmltdW0gbG9uZ2l0dWRlcy5cbiAgaWYgKG4gPSByYW5nZXMubGVuZ3RoKSB7XG4gICAgcmFuZ2VzLnNvcnQocmFuZ2VDb21wYXJlKTtcblxuICAgIC8vIFRoZW4sIG1lcmdlIGFueSByYW5nZXMgdGhhdCBvdmVybGFwLlxuICAgIGZvciAoaSA9IDEsIGEgPSByYW5nZXNbMF0sIG1lcmdlZCA9IFthXTsgaSA8IG47ICsraSkge1xuICAgICAgYiA9IHJhbmdlc1tpXTtcbiAgICAgIGlmIChyYW5nZUNvbnRhaW5zKGEsIGJbMF0pIHx8IHJhbmdlQ29udGFpbnMoYSwgYlsxXSkpIHtcbiAgICAgICAgaWYgKGFuZ2xlKGFbMF0sIGJbMV0pID4gYW5nbGUoYVswXSwgYVsxXSkpIGFbMV0gPSBiWzFdO1xuICAgICAgICBpZiAoYW5nbGUoYlswXSwgYVsxXSkgPiBhbmdsZShhWzBdLCBhWzFdKSkgYVswXSA9IGJbMF07XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBtZXJnZWQucHVzaChhID0gYik7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmluYWxseSwgZmluZCB0aGUgbGFyZ2VzdCBnYXAgYmV0d2VlbiB0aGUgbWVyZ2VkIHJhbmdlcy5cbiAgICAvLyBUaGUgZmluYWwgYm91bmRpbmcgYm94IHdpbGwgYmUgdGhlIGludmVyc2Ugb2YgdGhpcyBnYXAuXG4gICAgZm9yIChkZWx0YU1heCA9IC1JbmZpbml0eSwgbiA9IG1lcmdlZC5sZW5ndGggLSAxLCBpID0gMCwgYSA9IG1lcmdlZFtuXTsgaSA8PSBuOyBhID0gYiwgKytpKSB7XG4gICAgICBiID0gbWVyZ2VkW2ldO1xuICAgICAgaWYgKChkZWx0YSA9IGFuZ2xlKGFbMV0sIGJbMF0pKSA+IGRlbHRhTWF4KSBkZWx0YU1heCA9IGRlbHRhLCBsYW1iZGEwJDEgPSBiWzBdLCBsYW1iZGExID0gYVsxXTtcbiAgICB9XG4gIH1cblxuICByYW5nZXMgPSByYW5nZSA9IG51bGw7XG5cbiAgcmV0dXJuIGxhbWJkYTAkMSA9PT0gSW5maW5pdHkgfHwgcGhpMCA9PT0gSW5maW5pdHlcbiAgICAgID8gW1tOYU4sIE5hTl0sIFtOYU4sIE5hTl1dXG4gICAgICA6IFtbbGFtYmRhMCQxLCBwaGkwXSwgW2xhbWJkYTEsIHBoaTFdXTtcbn07XG5cbnZhciBXMDtcbnZhciBXMTtcbnZhciBYMDtcbnZhciBZMDtcbnZhciBaMDtcbnZhciBYMTtcbnZhciBZMTtcbnZhciBaMTtcbnZhciBYMjtcbnZhciBZMjtcbnZhciBaMjtcbnZhciBsYW1iZGEwMCQyO1xudmFyIHBoaTAwJDI7XG52YXIgeDA7XG52YXIgeTA7XG52YXIgejA7IC8vIHByZXZpb3VzIHBvaW50XG5cbnZhciBjZW50cm9pZFN0cmVhbSA9IHtcbiAgc3BoZXJlOiBub29wJDQsXG4gIHBvaW50OiBjZW50cm9pZFBvaW50LFxuICBsaW5lU3RhcnQ6IGNlbnRyb2lkTGluZVN0YXJ0LFxuICBsaW5lRW5kOiBjZW50cm9pZExpbmVFbmQsXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZVN0YXJ0ID0gY2VudHJvaWRSaW5nU3RhcnQ7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZUVuZCA9IGNlbnRyb2lkUmluZ0VuZDtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZVN0YXJ0ID0gY2VudHJvaWRMaW5lU3RhcnQ7XG4gICAgY2VudHJvaWRTdHJlYW0ubGluZUVuZCA9IGNlbnRyb2lkTGluZUVuZDtcbiAgfVxufTtcblxuLy8gQXJpdGhtZXRpYyBtZWFuIG9mIENhcnRlc2lhbiB2ZWN0b3JzLlxuZnVuY3Rpb24gY2VudHJvaWRQb2ludChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpO1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKGNvc1BoaSAqIGNvcyQxKGxhbWJkYSksIGNvc1BoaSAqIHNpbiQxKGxhbWJkYSksIHNpbiQxKHBoaSkpO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgsIHksIHopIHtcbiAgKytXMDtcbiAgWDAgKz0gKHggLSBYMCkgLyBXMDtcbiAgWTAgKz0gKHkgLSBZMCkgLyBXMDtcbiAgWjAgKz0gKHogLSBaMCkgLyBXMDtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRMaW5lU3RhcnQoKSB7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRMaW5lUG9pbnRGaXJzdDtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRMaW5lUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpO1xuICB4MCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSk7XG4gIHkwID0gY29zUGhpICogc2luJDEobGFtYmRhKTtcbiAgejAgPSBzaW4kMShwaGkpO1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkTGluZVBvaW50O1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgwLCB5MCwgejApO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZExpbmVQb2ludChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgeCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSksXG4gICAgICB5ID0gY29zUGhpICogc2luJDEobGFtYmRhKSxcbiAgICAgIHogPSBzaW4kMShwaGkpLFxuICAgICAgdyA9IGF0YW4yJDEoc3FydCQyKCh3ID0geTAgKiB6IC0gejAgKiB5KSAqIHcgKyAodyA9IHowICogeCAtIHgwICogeikgKiB3ICsgKHcgPSB4MCAqIHkgLSB5MCAqIHgpICogdyksIHgwICogeCArIHkwICogeSArIHowICogeik7XG4gIFcxICs9IHc7XG4gIFgxICs9IHcgKiAoeDAgKyAoeDAgPSB4KSk7XG4gIFkxICs9IHcgKiAoeTAgKyAoeTAgPSB5KSk7XG4gIFoxICs9IHcgKiAoejAgKyAoejAgPSB6KSk7XG4gIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeDAsIHkwLCB6MCk7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkTGluZUVuZCgpIHtcbiAgY2VudHJvaWRTdHJlYW0ucG9pbnQgPSBjZW50cm9pZFBvaW50O1xufVxuXG4vLyBTZWUgSi4gRS4gQnJvY2ssIFRoZSBJbmVydGlhIFRlbnNvciBmb3IgYSBTcGhlcmljYWwgVHJpYW5nbGUsXG4vLyBKLiBBcHBsaWVkIE1lY2hhbmljcyA0MiwgMjM5ICgxOTc1KS5cbmZ1bmN0aW9uIGNlbnRyb2lkUmluZ1N0YXJ0KCkge1xuICBjZW50cm9pZFN0cmVhbS5wb2ludCA9IGNlbnRyb2lkUmluZ1BvaW50Rmlyc3Q7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUmluZ0VuZCgpIHtcbiAgY2VudHJvaWRSaW5nUG9pbnQobGFtYmRhMDAkMiwgcGhpMDAkMik7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRQb2ludDtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRSaW5nUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEwMCQyID0gbGFtYmRhLCBwaGkwMCQyID0gcGhpO1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIGNlbnRyb2lkU3RyZWFtLnBvaW50ID0gY2VudHJvaWRSaW5nUG9pbnQ7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpO1xuICB4MCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSk7XG4gIHkwID0gY29zUGhpICogc2luJDEobGFtYmRhKTtcbiAgejAgPSBzaW4kMShwaGkpO1xuICBjZW50cm9pZFBvaW50Q2FydGVzaWFuKHgwLCB5MCwgejApO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdQb2ludChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIHZhciBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgeCA9IGNvc1BoaSAqIGNvcyQxKGxhbWJkYSksXG4gICAgICB5ID0gY29zUGhpICogc2luJDEobGFtYmRhKSxcbiAgICAgIHogPSBzaW4kMShwaGkpLFxuICAgICAgY3ggPSB5MCAqIHogLSB6MCAqIHksXG4gICAgICBjeSA9IHowICogeCAtIHgwICogeixcbiAgICAgIGN6ID0geDAgKiB5IC0geTAgKiB4LFxuICAgICAgbSA9IHNxcnQkMihjeCAqIGN4ICsgY3kgKiBjeSArIGN6ICogY3opLFxuICAgICAgdyA9IGFzaW4kMShtKSwgLy8gbGluZSB3ZWlnaHQgPSBhbmdsZVxuICAgICAgdiA9IG0gJiYgLXcgLyBtOyAvLyBhcmVhIHdlaWdodCBtdWx0aXBsaWVyXG4gIFgyICs9IHYgKiBjeDtcbiAgWTIgKz0gdiAqIGN5O1xuICBaMiArPSB2ICogY3o7XG4gIFcxICs9IHc7XG4gIFgxICs9IHcgKiAoeDAgKyAoeDAgPSB4KSk7XG4gIFkxICs9IHcgKiAoeTAgKyAoeTAgPSB5KSk7XG4gIFoxICs9IHcgKiAoejAgKyAoejAgPSB6KSk7XG4gIGNlbnRyb2lkUG9pbnRDYXJ0ZXNpYW4oeDAsIHkwLCB6MCk7XG59XG5cbnZhciBjZW50cm9pZCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICBXMCA9IFcxID1cbiAgWDAgPSBZMCA9IFowID1cbiAgWDEgPSBZMSA9IFoxID1cbiAgWDIgPSBZMiA9IFoyID0gMDtcbiAgZ2VvU3RyZWFtKG9iamVjdCwgY2VudHJvaWRTdHJlYW0pO1xuXG4gIHZhciB4ID0gWDIsXG4gICAgICB5ID0gWTIsXG4gICAgICB6ID0gWjIsXG4gICAgICBtID0geCAqIHggKyB5ICogeSArIHogKiB6O1xuXG4gIC8vIElmIHRoZSBhcmVhLXdlaWdodGVkIGNjZW50cm9pZCBpcyB1bmRlZmluZWQsIGZhbGwgYmFjayB0byBsZW5ndGgtd2VpZ2h0ZWQgY2NlbnRyb2lkLlxuICBpZiAobSA8IGVwc2lsb24yJDEpIHtcbiAgICB4ID0gWDEsIHkgPSBZMSwgeiA9IFoxO1xuICAgIC8vIElmIHRoZSBmZWF0dXJlIGhhcyB6ZXJvIGxlbmd0aCwgZmFsbCBiYWNrIHRvIGFyaXRobWV0aWMgbWVhbiBvZiBwb2ludCB2ZWN0b3JzLlxuICAgIGlmIChXMSA8IGVwc2lsb24kMikgeCA9IFgwLCB5ID0gWTAsIHogPSBaMDtcbiAgICBtID0geCAqIHggKyB5ICogeSArIHogKiB6O1xuICAgIC8vIElmIHRoZSBmZWF0dXJlIHN0aWxsIGhhcyBhbiB1bmRlZmluZWQgY2NlbnRyb2lkLCB0aGVuIHJldHVybi5cbiAgICBpZiAobSA8IGVwc2lsb24yJDEpIHJldHVybiBbTmFOLCBOYU5dO1xuICB9XG5cbiAgcmV0dXJuIFthdGFuMiQxKHksIHgpICogZGVncmVlcyQxLCBhc2luJDEoeiAvIHNxcnQkMihtKSkgKiBkZWdyZWVzJDFdO1xufTtcblxudmFyIGNvbXBvc2UgPSBmdW5jdGlvbihhLCBiKSB7XG5cbiAgZnVuY3Rpb24gY29tcG9zZSh4LCB5KSB7XG4gICAgcmV0dXJuIHggPSBhKHgsIHkpLCBiKHhbMF0sIHhbMV0pO1xuICB9XG5cbiAgaWYgKGEuaW52ZXJ0ICYmIGIuaW52ZXJ0KSBjb21wb3NlLmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICByZXR1cm4geCA9IGIuaW52ZXJ0KHgsIHkpLCB4ICYmIGEuaW52ZXJ0KHhbMF0sIHhbMV0pO1xuICB9O1xuXG4gIHJldHVybiBjb21wb3NlO1xufTtcblxuZnVuY3Rpb24gcm90YXRpb25JZGVudGl0eShsYW1iZGEsIHBoaSkge1xuICByZXR1cm4gW2xhbWJkYSA+IHBpJDMgPyBsYW1iZGEgLSB0YXUkNCA6IGxhbWJkYSA8IC1waSQzID8gbGFtYmRhICsgdGF1JDQgOiBsYW1iZGEsIHBoaV07XG59XG5cbnJvdGF0aW9uSWRlbnRpdHkuaW52ZXJ0ID0gcm90YXRpb25JZGVudGl0eTtcblxuZnVuY3Rpb24gcm90YXRlUmFkaWFucyhkZWx0YUxhbWJkYSwgZGVsdGFQaGksIGRlbHRhR2FtbWEpIHtcbiAgcmV0dXJuIChkZWx0YUxhbWJkYSAlPSB0YXUkNCkgPyAoZGVsdGFQaGkgfHwgZGVsdGFHYW1tYSA/IGNvbXBvc2Uocm90YXRpb25MYW1iZGEoZGVsdGFMYW1iZGEpLCByb3RhdGlvblBoaUdhbW1hKGRlbHRhUGhpLCBkZWx0YUdhbW1hKSlcbiAgICA6IHJvdGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKSlcbiAgICA6IChkZWx0YVBoaSB8fCBkZWx0YUdhbW1hID8gcm90YXRpb25QaGlHYW1tYShkZWx0YVBoaSwgZGVsdGFHYW1tYSlcbiAgICA6IHJvdGF0aW9uSWRlbnRpdHkpO1xufVxuXG5mdW5jdGlvbiBmb3J3YXJkUm90YXRpb25MYW1iZGEoZGVsdGFMYW1iZGEpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKGxhbWJkYSwgcGhpKSB7XG4gICAgcmV0dXJuIGxhbWJkYSArPSBkZWx0YUxhbWJkYSwgW2xhbWJkYSA+IHBpJDMgPyBsYW1iZGEgLSB0YXUkNCA6IGxhbWJkYSA8IC1waSQzID8gbGFtYmRhICsgdGF1JDQgOiBsYW1iZGEsIHBoaV07XG4gIH07XG59XG5cbmZ1bmN0aW9uIHJvdGF0aW9uTGFtYmRhKGRlbHRhTGFtYmRhKSB7XG4gIHZhciByb3RhdGlvbiA9IGZvcndhcmRSb3RhdGlvbkxhbWJkYShkZWx0YUxhbWJkYSk7XG4gIHJvdGF0aW9uLmludmVydCA9IGZvcndhcmRSb3RhdGlvbkxhbWJkYSgtZGVsdGFMYW1iZGEpO1xuICByZXR1cm4gcm90YXRpb247XG59XG5cbmZ1bmN0aW9uIHJvdGF0aW9uUGhpR2FtbWEoZGVsdGFQaGksIGRlbHRhR2FtbWEpIHtcbiAgdmFyIGNvc0RlbHRhUGhpID0gY29zJDEoZGVsdGFQaGkpLFxuICAgICAgc2luRGVsdGFQaGkgPSBzaW4kMShkZWx0YVBoaSksXG4gICAgICBjb3NEZWx0YUdhbW1hID0gY29zJDEoZGVsdGFHYW1tYSksXG4gICAgICBzaW5EZWx0YUdhbW1hID0gc2luJDEoZGVsdGFHYW1tYSk7XG5cbiAgZnVuY3Rpb24gcm90YXRpb24obGFtYmRhLCBwaGkpIHtcbiAgICB2YXIgY29zUGhpID0gY29zJDEocGhpKSxcbiAgICAgICAgeCA9IGNvcyQxKGxhbWJkYSkgKiBjb3NQaGksXG4gICAgICAgIHkgPSBzaW4kMShsYW1iZGEpICogY29zUGhpLFxuICAgICAgICB6ID0gc2luJDEocGhpKSxcbiAgICAgICAgayA9IHogKiBjb3NEZWx0YVBoaSArIHggKiBzaW5EZWx0YVBoaTtcbiAgICByZXR1cm4gW1xuICAgICAgYXRhbjIkMSh5ICogY29zRGVsdGFHYW1tYSAtIGsgKiBzaW5EZWx0YUdhbW1hLCB4ICogY29zRGVsdGFQaGkgLSB6ICogc2luRGVsdGFQaGkpLFxuICAgICAgYXNpbiQxKGsgKiBjb3NEZWx0YUdhbW1hICsgeSAqIHNpbkRlbHRhR2FtbWEpXG4gICAgXTtcbiAgfVxuXG4gIHJvdGF0aW9uLmludmVydCA9IGZ1bmN0aW9uKGxhbWJkYSwgcGhpKSB7XG4gICAgdmFyIGNvc1BoaSA9IGNvcyQxKHBoaSksXG4gICAgICAgIHggPSBjb3MkMShsYW1iZGEpICogY29zUGhpLFxuICAgICAgICB5ID0gc2luJDEobGFtYmRhKSAqIGNvc1BoaSxcbiAgICAgICAgeiA9IHNpbiQxKHBoaSksXG4gICAgICAgIGsgPSB6ICogY29zRGVsdGFHYW1tYSAtIHkgKiBzaW5EZWx0YUdhbW1hO1xuICAgIHJldHVybiBbXG4gICAgICBhdGFuMiQxKHkgKiBjb3NEZWx0YUdhbW1hICsgeiAqIHNpbkRlbHRhR2FtbWEsIHggKiBjb3NEZWx0YVBoaSArIGsgKiBzaW5EZWx0YVBoaSksXG4gICAgICBhc2luJDEoayAqIGNvc0RlbHRhUGhpIC0geCAqIHNpbkRlbHRhUGhpKVxuICAgIF07XG4gIH07XG5cbiAgcmV0dXJuIHJvdGF0aW9uO1xufVxuXG52YXIgcm90YXRpb24gPSBmdW5jdGlvbihyb3RhdGUpIHtcbiAgcm90YXRlID0gcm90YXRlUmFkaWFucyhyb3RhdGVbMF0gKiByYWRpYW5zLCByb3RhdGVbMV0gKiByYWRpYW5zLCByb3RhdGUubGVuZ3RoID4gMiA/IHJvdGF0ZVsyXSAqIHJhZGlhbnMgOiAwKTtcblxuICBmdW5jdGlvbiBmb3J3YXJkKGNvb3JkaW5hdGVzKSB7XG4gICAgY29vcmRpbmF0ZXMgPSByb3RhdGUoY29vcmRpbmF0ZXNbMF0gKiByYWRpYW5zLCBjb29yZGluYXRlc1sxXSAqIHJhZGlhbnMpO1xuICAgIHJldHVybiBjb29yZGluYXRlc1swXSAqPSBkZWdyZWVzJDEsIGNvb3JkaW5hdGVzWzFdICo9IGRlZ3JlZXMkMSwgY29vcmRpbmF0ZXM7XG4gIH1cblxuICBmb3J3YXJkLmludmVydCA9IGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7XG4gICAgY29vcmRpbmF0ZXMgPSByb3RhdGUuaW52ZXJ0KGNvb3JkaW5hdGVzWzBdICogcmFkaWFucywgY29vcmRpbmF0ZXNbMV0gKiByYWRpYW5zKTtcbiAgICByZXR1cm4gY29vcmRpbmF0ZXNbMF0gKj0gZGVncmVlcyQxLCBjb29yZGluYXRlc1sxXSAqPSBkZWdyZWVzJDEsIGNvb3JkaW5hdGVzO1xuICB9O1xuXG4gIHJldHVybiBmb3J3YXJkO1xufTtcblxuLy8gR2VuZXJhdGVzIGEgY2lyY2xlIGNlbnRlcmVkIGF0IFswwrAsIDDCsF0sIHdpdGggYSBnaXZlbiByYWRpdXMgYW5kIHByZWNpc2lvbi5cbmZ1bmN0aW9uIGNpcmNsZVN0cmVhbShzdHJlYW0sIHJhZGl1cywgZGVsdGEsIGRpcmVjdGlvbiwgdDAsIHQxKSB7XG4gIGlmICghZGVsdGEpIHJldHVybjtcbiAgdmFyIGNvc1JhZGl1cyA9IGNvcyQxKHJhZGl1cyksXG4gICAgICBzaW5SYWRpdXMgPSBzaW4kMShyYWRpdXMpLFxuICAgICAgc3RlcCA9IGRpcmVjdGlvbiAqIGRlbHRhO1xuICBpZiAodDAgPT0gbnVsbCkge1xuICAgIHQwID0gcmFkaXVzICsgZGlyZWN0aW9uICogdGF1JDQ7XG4gICAgdDEgPSByYWRpdXMgLSBzdGVwIC8gMjtcbiAgfSBlbHNlIHtcbiAgICB0MCA9IGNpcmNsZVJhZGl1cyhjb3NSYWRpdXMsIHQwKTtcbiAgICB0MSA9IGNpcmNsZVJhZGl1cyhjb3NSYWRpdXMsIHQxKTtcbiAgICBpZiAoZGlyZWN0aW9uID4gMCA/IHQwIDwgdDEgOiB0MCA+IHQxKSB0MCArPSBkaXJlY3Rpb24gKiB0YXUkNDtcbiAgfVxuICBmb3IgKHZhciBwb2ludCwgdCA9IHQwOyBkaXJlY3Rpb24gPiAwID8gdCA+IHQxIDogdCA8IHQxOyB0IC09IHN0ZXApIHtcbiAgICBwb2ludCA9IHNwaGVyaWNhbChbY29zUmFkaXVzLCAtc2luUmFkaXVzICogY29zJDEodCksIC1zaW5SYWRpdXMgKiBzaW4kMSh0KV0pO1xuICAgIHN0cmVhbS5wb2ludChwb2ludFswXSwgcG9pbnRbMV0pO1xuICB9XG59XG5cbi8vIFJldHVybnMgdGhlIHNpZ25lZCBhbmdsZSBvZiBhIGNhcnRlc2lhbiBwb2ludCByZWxhdGl2ZSB0byBbY29zUmFkaXVzLCAwLCAwXS5cbmZ1bmN0aW9uIGNpcmNsZVJhZGl1cyhjb3NSYWRpdXMsIHBvaW50KSB7XG4gIHBvaW50ID0gY2FydGVzaWFuKHBvaW50KSwgcG9pbnRbMF0gLT0gY29zUmFkaXVzO1xuICBjYXJ0ZXNpYW5Ob3JtYWxpemVJblBsYWNlKHBvaW50KTtcbiAgdmFyIHJhZGl1cyA9IGFjb3MkMSgtcG9pbnRbMV0pO1xuICByZXR1cm4gKCgtcG9pbnRbMl0gPCAwID8gLXJhZGl1cyA6IHJhZGl1cykgKyB0YXUkNCAtIGVwc2lsb24kMikgJSB0YXUkNDtcbn1cblxudmFyIGNsaXBCdWZmZXIgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpbmVzID0gW10sXG4gICAgICBsaW5lO1xuICByZXR1cm4ge1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICBsaW5lLnB1c2goW3gsIHldKTtcbiAgICB9LFxuICAgIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgICBsaW5lcy5wdXNoKGxpbmUgPSBbXSk7XG4gICAgfSxcbiAgICBsaW5lRW5kOiBub29wJDQsXG4gICAgcmVqb2luOiBmdW5jdGlvbigpIHtcbiAgICAgIGlmIChsaW5lcy5sZW5ndGggPiAxKSBsaW5lcy5wdXNoKGxpbmVzLnBvcCgpLmNvbmNhdChsaW5lcy5zaGlmdCgpKSk7XG4gICAgfSxcbiAgICByZXN1bHQ6IGZ1bmN0aW9uKCkge1xuICAgICAgdmFyIHJlc3VsdCA9IGxpbmVzO1xuICAgICAgbGluZXMgPSBbXTtcbiAgICAgIGxpbmUgPSBudWxsO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9XG4gIH07XG59O1xuXG52YXIgcG9pbnRFcXVhbCA9IGZ1bmN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuIGFicyQxKGFbMF0gLSBiWzBdKSA8IGVwc2lsb24kMiAmJiBhYnMkMShhWzFdIC0gYlsxXSkgPCBlcHNpbG9uJDI7XG59O1xuXG5mdW5jdGlvbiBJbnRlcnNlY3Rpb24ocG9pbnQsIHBvaW50cywgb3RoZXIsIGVudHJ5KSB7XG4gIHRoaXMueCA9IHBvaW50O1xuICB0aGlzLnogPSBwb2ludHM7XG4gIHRoaXMubyA9IG90aGVyOyAvLyBhbm90aGVyIGludGVyc2VjdGlvblxuICB0aGlzLmUgPSBlbnRyeTsgLy8gaXMgYW4gZW50cnk/XG4gIHRoaXMudiA9IGZhbHNlOyAvLyB2aXNpdGVkXG4gIHRoaXMubiA9IHRoaXMucCA9IG51bGw7IC8vIG5leHQgJiBwcmV2aW91c1xufVxuXG4vLyBBIGdlbmVyYWxpemVkIHBvbHlnb24gY2xpcHBpbmcgYWxnb3JpdGhtOiBnaXZlbiBhIHBvbHlnb24gdGhhdCBoYXMgYmVlbiBjdXRcbi8vIGludG8gaXRzIHZpc2libGUgbGluZSBzZWdtZW50cywgYW5kIHJlam9pbnMgdGhlIHNlZ21lbnRzIGJ5IGludGVycG9sYXRpbmdcbi8vIGFsb25nIHRoZSBjbGlwIGVkZ2UuXG52YXIgY2xpcFJlam9pbiA9IGZ1bmN0aW9uKHNlZ21lbnRzLCBjb21wYXJlSW50ZXJzZWN0aW9uLCBzdGFydEluc2lkZSwgaW50ZXJwb2xhdGUsIHN0cmVhbSkge1xuICB2YXIgc3ViamVjdCA9IFtdLFxuICAgICAgY2xpcCA9IFtdLFxuICAgICAgaSxcbiAgICAgIG47XG5cbiAgc2VnbWVudHMuZm9yRWFjaChmdW5jdGlvbihzZWdtZW50KSB7XG4gICAgaWYgKChuID0gc2VnbWVudC5sZW5ndGggLSAxKSA8PSAwKSByZXR1cm47XG4gICAgdmFyIG4sIHAwID0gc2VnbWVudFswXSwgcDEgPSBzZWdtZW50W25dLCB4O1xuXG4gICAgLy8gSWYgdGhlIGZpcnN0IGFuZCBsYXN0IHBvaW50cyBvZiBhIHNlZ21lbnQgYXJlIGNvaW5jaWRlbnQsIHRoZW4gdHJlYXQgYXMgYVxuICAgIC8vIGNsb3NlZCByaW5nLiBUT0RPIGlmIGFsbCByaW5ncyBhcmUgY2xvc2VkLCB0aGVuIHRoZSB3aW5kaW5nIG9yZGVyIG9mIHRoZVxuICAgIC8vIGV4dGVyaW9yIHJpbmcgc2hvdWxkIGJlIGNoZWNrZWQuXG4gICAgaWYgKHBvaW50RXF1YWwocDAsIHAxKSkge1xuICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkgc3RyZWFtLnBvaW50KChwMCA9IHNlZ21lbnRbaV0pWzBdLCBwMFsxXSk7XG4gICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHN1YmplY3QucHVzaCh4ID0gbmV3IEludGVyc2VjdGlvbihwMCwgc2VnbWVudCwgbnVsbCwgdHJ1ZSkpO1xuICAgIGNsaXAucHVzaCh4Lm8gPSBuZXcgSW50ZXJzZWN0aW9uKHAwLCBudWxsLCB4LCBmYWxzZSkpO1xuICAgIHN1YmplY3QucHVzaCh4ID0gbmV3IEludGVyc2VjdGlvbihwMSwgc2VnbWVudCwgbnVsbCwgZmFsc2UpKTtcbiAgICBjbGlwLnB1c2goeC5vID0gbmV3IEludGVyc2VjdGlvbihwMSwgbnVsbCwgeCwgdHJ1ZSkpO1xuICB9KTtcblxuICBpZiAoIXN1YmplY3QubGVuZ3RoKSByZXR1cm47XG5cbiAgY2xpcC5zb3J0KGNvbXBhcmVJbnRlcnNlY3Rpb24pO1xuICBsaW5rJDEoc3ViamVjdCk7XG4gIGxpbmskMShjbGlwKTtcblxuICBmb3IgKGkgPSAwLCBuID0gY2xpcC5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICBjbGlwW2ldLmUgPSBzdGFydEluc2lkZSA9ICFzdGFydEluc2lkZTtcbiAgfVxuXG4gIHZhciBzdGFydCA9IHN1YmplY3RbMF0sXG4gICAgICBwb2ludHMsXG4gICAgICBwb2ludDtcblxuICB3aGlsZSAoMSkge1xuICAgIC8vIEZpbmQgZmlyc3QgdW52aXNpdGVkIGludGVyc2VjdGlvbi5cbiAgICB2YXIgY3VycmVudCA9IHN0YXJ0LFxuICAgICAgICBpc1N1YmplY3QgPSB0cnVlO1xuICAgIHdoaWxlIChjdXJyZW50LnYpIGlmICgoY3VycmVudCA9IGN1cnJlbnQubikgPT09IHN0YXJ0KSByZXR1cm47XG4gICAgcG9pbnRzID0gY3VycmVudC56O1xuICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICBkbyB7XG4gICAgICBjdXJyZW50LnYgPSBjdXJyZW50Lm8udiA9IHRydWU7XG4gICAgICBpZiAoY3VycmVudC5lKSB7XG4gICAgICAgIGlmIChpc1N1YmplY3QpIHtcbiAgICAgICAgICBmb3IgKGkgPSAwLCBuID0gcG9pbnRzLmxlbmd0aDsgaSA8IG47ICsraSkgc3RyZWFtLnBvaW50KChwb2ludCA9IHBvaW50c1tpXSlbMF0sIHBvaW50WzFdKTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpbnRlcnBvbGF0ZShjdXJyZW50LngsIGN1cnJlbnQubi54LCAxLCBzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50Lm47XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBpZiAoaXNTdWJqZWN0KSB7XG4gICAgICAgICAgcG9pbnRzID0gY3VycmVudC5wLno7XG4gICAgICAgICAgZm9yIChpID0gcG9pbnRzLmxlbmd0aCAtIDE7IGkgPj0gMDsgLS1pKSBzdHJlYW0ucG9pbnQoKHBvaW50ID0gcG9pbnRzW2ldKVswXSwgcG9pbnRbMV0pO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGludGVycG9sYXRlKGN1cnJlbnQueCwgY3VycmVudC5wLngsIC0xLCBzdHJlYW0pO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJlbnQgPSBjdXJyZW50LnA7XG4gICAgICB9XG4gICAgICBjdXJyZW50ID0gY3VycmVudC5vO1xuICAgICAgcG9pbnRzID0gY3VycmVudC56O1xuICAgICAgaXNTdWJqZWN0ID0gIWlzU3ViamVjdDtcbiAgICB9IHdoaWxlICghY3VycmVudC52KTtcbiAgICBzdHJlYW0ubGluZUVuZCgpO1xuICB9XG59O1xuXG5mdW5jdGlvbiBsaW5rJDEoYXJyYXkpIHtcbiAgaWYgKCEobiA9IGFycmF5Lmxlbmd0aCkpIHJldHVybjtcbiAgdmFyIG4sXG4gICAgICBpID0gMCxcbiAgICAgIGEgPSBhcnJheVswXSxcbiAgICAgIGI7XG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgYS5uID0gYiA9IGFycmF5W2ldO1xuICAgIGIucCA9IGE7XG4gICAgYSA9IGI7XG4gIH1cbiAgYS5uID0gYiA9IGFycmF5WzBdO1xuICBiLnAgPSBhO1xufVxuXG52YXIgc3VtJDIgPSBhZGRlcigpO1xuXG52YXIgcG9seWdvbkNvbnRhaW5zID0gZnVuY3Rpb24ocG9seWdvbiwgcG9pbnQpIHtcbiAgdmFyIGxhbWJkYSA9IHBvaW50WzBdLFxuICAgICAgcGhpID0gcG9pbnRbMV0sXG4gICAgICBub3JtYWwgPSBbc2luJDEobGFtYmRhKSwgLWNvcyQxKGxhbWJkYSksIDBdLFxuICAgICAgYW5nbGUgPSAwLFxuICAgICAgd2luZGluZyA9IDA7XG5cbiAgc3VtJDIucmVzZXQoKTtcblxuICBmb3IgKHZhciBpID0gMCwgbiA9IHBvbHlnb24ubGVuZ3RoOyBpIDwgbjsgKytpKSB7XG4gICAgaWYgKCEobSA9IChyaW5nID0gcG9seWdvbltpXSkubGVuZ3RoKSkgY29udGludWU7XG4gICAgdmFyIHJpbmcsXG4gICAgICAgIG0sXG4gICAgICAgIHBvaW50MCA9IHJpbmdbbSAtIDFdLFxuICAgICAgICBsYW1iZGEwID0gcG9pbnQwWzBdLFxuICAgICAgICBwaGkwID0gcG9pbnQwWzFdIC8gMiArIHF1YXJ0ZXJQaSxcbiAgICAgICAgc2luUGhpMCA9IHNpbiQxKHBoaTApLFxuICAgICAgICBjb3NQaGkwID0gY29zJDEocGhpMCk7XG5cbiAgICBmb3IgKHZhciBqID0gMDsgaiA8IG07ICsraiwgbGFtYmRhMCA9IGxhbWJkYTEsIHNpblBoaTAgPSBzaW5QaGkxLCBjb3NQaGkwID0gY29zUGhpMSwgcG9pbnQwID0gcG9pbnQxKSB7XG4gICAgICB2YXIgcG9pbnQxID0gcmluZ1tqXSxcbiAgICAgICAgICBsYW1iZGExID0gcG9pbnQxWzBdLFxuICAgICAgICAgIHBoaTEgPSBwb2ludDFbMV0gLyAyICsgcXVhcnRlclBpLFxuICAgICAgICAgIHNpblBoaTEgPSBzaW4kMShwaGkxKSxcbiAgICAgICAgICBjb3NQaGkxID0gY29zJDEocGhpMSksXG4gICAgICAgICAgZGVsdGEgPSBsYW1iZGExIC0gbGFtYmRhMCxcbiAgICAgICAgICBzaWduID0gZGVsdGEgPj0gMCA/IDEgOiAtMSxcbiAgICAgICAgICBhYnNEZWx0YSA9IHNpZ24gKiBkZWx0YSxcbiAgICAgICAgICBhbnRpbWVyaWRpYW4gPSBhYnNEZWx0YSA+IHBpJDMsXG4gICAgICAgICAgayA9IHNpblBoaTAgKiBzaW5QaGkxO1xuXG4gICAgICBzdW0kMi5hZGQoYXRhbjIkMShrICogc2lnbiAqIHNpbiQxKGFic0RlbHRhKSwgY29zUGhpMCAqIGNvc1BoaTEgKyBrICogY29zJDEoYWJzRGVsdGEpKSk7XG4gICAgICBhbmdsZSArPSBhbnRpbWVyaWRpYW4gPyBkZWx0YSArIHNpZ24gKiB0YXUkNCA6IGRlbHRhO1xuXG4gICAgICAvLyBBcmUgdGhlIGxvbmdpdHVkZXMgZWl0aGVyIHNpZGUgb2YgdGhlIHBvaW504oCZcyBtZXJpZGlhbiAobGFtYmRhKSxcbiAgICAgIC8vIGFuZCBhcmUgdGhlIGxhdGl0dWRlcyBzbWFsbGVyIHRoYW4gdGhlIHBhcmFsbGVsIChwaGkpP1xuICAgICAgaWYgKGFudGltZXJpZGlhbiBeIGxhbWJkYTAgPj0gbGFtYmRhIF4gbGFtYmRhMSA+PSBsYW1iZGEpIHtcbiAgICAgICAgdmFyIGFyYyA9IGNhcnRlc2lhbkNyb3NzKGNhcnRlc2lhbihwb2ludDApLCBjYXJ0ZXNpYW4ocG9pbnQxKSk7XG4gICAgICAgIGNhcnRlc2lhbk5vcm1hbGl6ZUluUGxhY2UoYXJjKTtcbiAgICAgICAgdmFyIGludGVyc2VjdGlvbiA9IGNhcnRlc2lhbkNyb3NzKG5vcm1hbCwgYXJjKTtcbiAgICAgICAgY2FydGVzaWFuTm9ybWFsaXplSW5QbGFjZShpbnRlcnNlY3Rpb24pO1xuICAgICAgICB2YXIgcGhpQXJjID0gKGFudGltZXJpZGlhbiBeIGRlbHRhID49IDAgPyAtMSA6IDEpICogYXNpbiQxKGludGVyc2VjdGlvblsyXSk7XG4gICAgICAgIGlmIChwaGkgPiBwaGlBcmMgfHwgcGhpID09PSBwaGlBcmMgJiYgKGFyY1swXSB8fCBhcmNbMV0pKSB7XG4gICAgICAgICAgd2luZGluZyArPSBhbnRpbWVyaWRpYW4gXiBkZWx0YSA+PSAwID8gMSA6IC0xO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLy8gRmlyc3QsIGRldGVybWluZSB3aGV0aGVyIHRoZSBTb3V0aCBwb2xlIGlzIGluc2lkZSBvciBvdXRzaWRlOlxuICAvL1xuICAvLyBJdCBpcyBpbnNpZGUgaWY6XG4gIC8vICogdGhlIHBvbHlnb24gd2luZHMgYXJvdW5kIGl0IGluIGEgY2xvY2t3aXNlIGRpcmVjdGlvbi5cbiAgLy8gKiB0aGUgcG9seWdvbiBkb2VzIG5vdCAoY3VtdWxhdGl2ZWx5KSB3aW5kIGFyb3VuZCBpdCwgYnV0IGhhcyBhIG5lZ2F0aXZlXG4gIC8vICAgKGNvdW50ZXItY2xvY2t3aXNlKSBhcmVhLlxuICAvL1xuICAvLyBTZWNvbmQsIGNvdW50IHRoZSAoc2lnbmVkKSBudW1iZXIgb2YgdGltZXMgYSBzZWdtZW50IGNyb3NzZXMgYSBsYW1iZGFcbiAgLy8gZnJvbSB0aGUgcG9pbnQgdG8gdGhlIFNvdXRoIHBvbGUuICBJZiBpdCBpcyB6ZXJvLCB0aGVuIHRoZSBwb2ludCBpcyB0aGVcbiAgLy8gc2FtZSBzaWRlIGFzIHRoZSBTb3V0aCBwb2xlLlxuXG4gIHJldHVybiAoYW5nbGUgPCAtZXBzaWxvbiQyIHx8IGFuZ2xlIDwgZXBzaWxvbiQyICYmIHN1bSQyIDwgLWVwc2lsb24kMikgXiAod2luZGluZyAmIDEpO1xufTtcblxudmFyIGNsaXAkMiA9IGZ1bmN0aW9uKHBvaW50VmlzaWJsZSwgY2xpcExpbmUsIGludGVycG9sYXRlLCBzdGFydCkge1xuICByZXR1cm4gZnVuY3Rpb24oc2luaykge1xuICAgIHZhciBsaW5lID0gY2xpcExpbmUoc2luayksXG4gICAgICAgIHJpbmdCdWZmZXIgPSBjbGlwQnVmZmVyKCksXG4gICAgICAgIHJpbmdTaW5rID0gY2xpcExpbmUocmluZ0J1ZmZlciksXG4gICAgICAgIHBvbHlnb25TdGFydGVkID0gZmFsc2UsXG4gICAgICAgIHBvbHlnb24sXG4gICAgICAgIHNlZ21lbnRzLFxuICAgICAgICByaW5nO1xuXG4gICAgdmFyIGNsaXAgPSB7XG4gICAgICBwb2ludDogcG9pbnQsXG4gICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgIGxpbmVFbmQ6IGxpbmVFbmQsXG4gICAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbGlwLnBvaW50ID0gcG9pbnRSaW5nO1xuICAgICAgICBjbGlwLmxpbmVTdGFydCA9IHJpbmdTdGFydDtcbiAgICAgICAgY2xpcC5saW5lRW5kID0gcmluZ0VuZDtcbiAgICAgICAgc2VnbWVudHMgPSBbXTtcbiAgICAgICAgcG9seWdvbiA9IFtdO1xuICAgICAgfSxcbiAgICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBjbGlwLnBvaW50ID0gcG9pbnQ7XG4gICAgICAgIGNsaXAubGluZVN0YXJ0ID0gbGluZVN0YXJ0O1xuICAgICAgICBjbGlwLmxpbmVFbmQgPSBsaW5lRW5kO1xuICAgICAgICBzZWdtZW50cyA9IG1lcmdlJDIoc2VnbWVudHMpO1xuICAgICAgICB2YXIgc3RhcnRJbnNpZGUgPSBwb2x5Z29uQ29udGFpbnMocG9seWdvbiwgc3RhcnQpO1xuICAgICAgICBpZiAoc2VnbWVudHMubGVuZ3RoKSB7XG4gICAgICAgICAgaWYgKCFwb2x5Z29uU3RhcnRlZCkgc2luay5wb2x5Z29uU3RhcnQoKSwgcG9seWdvblN0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICAgIGNsaXBSZWpvaW4oc2VnbWVudHMsIGNvbXBhcmVJbnRlcnNlY3Rpb24sIHN0YXJ0SW5zaWRlLCBpbnRlcnBvbGF0ZSwgc2luayk7XG4gICAgICAgIH0gZWxzZSBpZiAoc3RhcnRJbnNpZGUpIHtcbiAgICAgICAgICBpZiAoIXBvbHlnb25TdGFydGVkKSBzaW5rLnBvbHlnb25TdGFydCgpLCBwb2x5Z29uU3RhcnRlZCA9IHRydWU7XG4gICAgICAgICAgc2luay5saW5lU3RhcnQoKTtcbiAgICAgICAgICBpbnRlcnBvbGF0ZShudWxsLCBudWxsLCAxLCBzaW5rKTtcbiAgICAgICAgICBzaW5rLmxpbmVFbmQoKTtcbiAgICAgICAgfVxuICAgICAgICBpZiAocG9seWdvblN0YXJ0ZWQpIHNpbmsucG9seWdvbkVuZCgpLCBwb2x5Z29uU3RhcnRlZCA9IGZhbHNlO1xuICAgICAgICBzZWdtZW50cyA9IHBvbHlnb24gPSBudWxsO1xuICAgICAgfSxcbiAgICAgIHNwaGVyZTogZnVuY3Rpb24oKSB7XG4gICAgICAgIHNpbmsucG9seWdvblN0YXJ0KCk7XG4gICAgICAgIHNpbmsubGluZVN0YXJ0KCk7XG4gICAgICAgIGludGVycG9sYXRlKG51bGwsIG51bGwsIDEsIHNpbmspO1xuICAgICAgICBzaW5rLmxpbmVFbmQoKTtcbiAgICAgICAgc2luay5wb2x5Z29uRW5kKCk7XG4gICAgICB9XG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHBvaW50KGxhbWJkYSwgcGhpKSB7XG4gICAgICBpZiAocG9pbnRWaXNpYmxlKGxhbWJkYSwgcGhpKSkgc2luay5wb2ludChsYW1iZGEsIHBoaSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9pbnRMaW5lKGxhbWJkYSwgcGhpKSB7XG4gICAgICBsaW5lLnBvaW50KGxhbWJkYSwgcGhpKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lU3RhcnQoKSB7XG4gICAgICBjbGlwLnBvaW50ID0gcG9pbnRMaW5lO1xuICAgICAgbGluZS5saW5lU3RhcnQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lRW5kKCkge1xuICAgICAgY2xpcC5wb2ludCA9IHBvaW50O1xuICAgICAgbGluZS5saW5lRW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9pbnRSaW5nKGxhbWJkYSwgcGhpKSB7XG4gICAgICByaW5nLnB1c2goW2xhbWJkYSwgcGhpXSk7XG4gICAgICByaW5nU2luay5wb2ludChsYW1iZGEsIHBoaSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmluZ1N0YXJ0KCkge1xuICAgICAgcmluZ1NpbmsubGluZVN0YXJ0KCk7XG4gICAgICByaW5nID0gW107XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmluZ0VuZCgpIHtcbiAgICAgIHBvaW50UmluZyhyaW5nWzBdWzBdLCByaW5nWzBdWzFdKTtcbiAgICAgIHJpbmdTaW5rLmxpbmVFbmQoKTtcblxuICAgICAgdmFyIGNsZWFuID0gcmluZ1NpbmsuY2xlYW4oKSxcbiAgICAgICAgICByaW5nU2VnbWVudHMgPSByaW5nQnVmZmVyLnJlc3VsdCgpLFxuICAgICAgICAgIGksIG4gPSByaW5nU2VnbWVudHMubGVuZ3RoLCBtLFxuICAgICAgICAgIHNlZ21lbnQsXG4gICAgICAgICAgcG9pbnQ7XG5cbiAgICAgIHJpbmcucG9wKCk7XG4gICAgICBwb2x5Z29uLnB1c2gocmluZyk7XG4gICAgICByaW5nID0gbnVsbDtcblxuICAgICAgaWYgKCFuKSByZXR1cm47XG5cbiAgICAgIC8vIE5vIGludGVyc2VjdGlvbnMuXG4gICAgICBpZiAoY2xlYW4gJiAxKSB7XG4gICAgICAgIHNlZ21lbnQgPSByaW5nU2VnbWVudHNbMF07XG4gICAgICAgIGlmICgobSA9IHNlZ21lbnQubGVuZ3RoIC0gMSkgPiAwKSB7XG4gICAgICAgICAgaWYgKCFwb2x5Z29uU3RhcnRlZCkgc2luay5wb2x5Z29uU3RhcnQoKSwgcG9seWdvblN0YXJ0ZWQgPSB0cnVlO1xuICAgICAgICAgIHNpbmsubGluZVN0YXJ0KCk7XG4gICAgICAgICAgZm9yIChpID0gMDsgaSA8IG07ICsraSkgc2luay5wb2ludCgocG9pbnQgPSBzZWdtZW50W2ldKVswXSwgcG9pbnRbMV0pO1xuICAgICAgICAgIHNpbmsubGluZUVuZCgpO1xuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cblxuICAgICAgLy8gUmVqb2luIGNvbm5lY3RlZCBzZWdtZW50cy5cbiAgICAgIC8vIFRPRE8gcmV1c2UgcmluZ0J1ZmZlci5yZWpvaW4oKT9cbiAgICAgIGlmIChuID4gMSAmJiBjbGVhbiAmIDIpIHJpbmdTZWdtZW50cy5wdXNoKHJpbmdTZWdtZW50cy5wb3AoKS5jb25jYXQocmluZ1NlZ21lbnRzLnNoaWZ0KCkpKTtcblxuICAgICAgc2VnbWVudHMucHVzaChyaW5nU2VnbWVudHMuZmlsdGVyKHZhbGlkU2VnbWVudCkpO1xuICAgIH1cblxuICAgIHJldHVybiBjbGlwO1xuICB9O1xufTtcblxuZnVuY3Rpb24gdmFsaWRTZWdtZW50KHNlZ21lbnQpIHtcbiAgcmV0dXJuIHNlZ21lbnQubGVuZ3RoID4gMTtcbn1cblxuLy8gSW50ZXJzZWN0aW9ucyBhcmUgc29ydGVkIGFsb25nIHRoZSBjbGlwIGVkZ2UuIEZvciBib3RoIGFudGltZXJpZGlhbiBjdXR0aW5nXG4vLyBhbmQgY2lyY2xlIGNsaXBwaW5nLCB0aGUgc2FtZSBjb21wYXJpc29uIGlzIHVzZWQuXG5mdW5jdGlvbiBjb21wYXJlSW50ZXJzZWN0aW9uKGEsIGIpIHtcbiAgcmV0dXJuICgoYSA9IGEueClbMF0gPCAwID8gYVsxXSAtIGhhbGZQaSQyIC0gZXBzaWxvbiQyIDogaGFsZlBpJDIgLSBhWzFdKVxuICAgICAgIC0gKChiID0gYi54KVswXSA8IDAgPyBiWzFdIC0gaGFsZlBpJDIgLSBlcHNpbG9uJDIgOiBoYWxmUGkkMiAtIGJbMV0pO1xufVxuXG52YXIgY2xpcEFudGltZXJpZGlhbiA9IGNsaXAkMihcbiAgZnVuY3Rpb24oKSB7IHJldHVybiB0cnVlOyB9LFxuICBjbGlwQW50aW1lcmlkaWFuTGluZSxcbiAgY2xpcEFudGltZXJpZGlhbkludGVycG9sYXRlLFxuICBbLXBpJDMsIC1oYWxmUGkkMl1cbik7XG5cbi8vIFRha2VzIGEgbGluZSBhbmQgY3V0cyBpbnRvIHZpc2libGUgc2VnbWVudHMuIFJldHVybiB2YWx1ZXM6IDAgLSB0aGVyZSB3ZXJlXG4vLyBpbnRlcnNlY3Rpb25zIG9yIHRoZSBsaW5lIHdhcyBlbXB0eTsgMSAtIG5vIGludGVyc2VjdGlvbnM7IDIgLSB0aGVyZSB3ZXJlXG4vLyBpbnRlcnNlY3Rpb25zLCBhbmQgdGhlIGZpcnN0IGFuZCBsYXN0IHNlZ21lbnRzIHNob3VsZCBiZSByZWpvaW5lZC5cbmZ1bmN0aW9uIGNsaXBBbnRpbWVyaWRpYW5MaW5lKHN0cmVhbSkge1xuICB2YXIgbGFtYmRhMCA9IE5hTixcbiAgICAgIHBoaTAgPSBOYU4sXG4gICAgICBzaWduMCA9IE5hTixcbiAgICAgIGNsZWFuOyAvLyBubyBpbnRlcnNlY3Rpb25zXG5cbiAgcmV0dXJuIHtcbiAgICBsaW5lU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgY2xlYW4gPSAxO1xuICAgIH0sXG4gICAgcG9pbnQ6IGZ1bmN0aW9uKGxhbWJkYTEsIHBoaTEpIHtcbiAgICAgIHZhciBzaWduMSA9IGxhbWJkYTEgPiAwID8gcGkkMyA6IC1waSQzLFxuICAgICAgICAgIGRlbHRhID0gYWJzJDEobGFtYmRhMSAtIGxhbWJkYTApO1xuICAgICAgaWYgKGFicyQxKGRlbHRhIC0gcGkkMykgPCBlcHNpbG9uJDIpIHsgLy8gbGluZSBjcm9zc2VzIGEgcG9sZVxuICAgICAgICBzdHJlYW0ucG9pbnQobGFtYmRhMCwgcGhpMCA9IChwaGkwICsgcGhpMSkgLyAyID4gMCA/IGhhbGZQaSQyIDogLWhhbGZQaSQyKTtcbiAgICAgICAgc3RyZWFtLnBvaW50KHNpZ24wLCBwaGkwKTtcbiAgICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICAgICAgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICBzdHJlYW0ucG9pbnQoc2lnbjEsIHBoaTApO1xuICAgICAgICBzdHJlYW0ucG9pbnQobGFtYmRhMSwgcGhpMCk7XG4gICAgICAgIGNsZWFuID0gMDtcbiAgICAgIH0gZWxzZSBpZiAoc2lnbjAgIT09IHNpZ24xICYmIGRlbHRhID49IHBpJDMpIHsgLy8gbGluZSBjcm9zc2VzIGFudGltZXJpZGlhblxuICAgICAgICBpZiAoYWJzJDEobGFtYmRhMCAtIHNpZ24wKSA8IGVwc2lsb24kMikgbGFtYmRhMCAtPSBzaWduMCAqIGVwc2lsb24kMjsgLy8gaGFuZGxlIGRlZ2VuZXJhY2llc1xuICAgICAgICBpZiAoYWJzJDEobGFtYmRhMSAtIHNpZ24xKSA8IGVwc2lsb24kMikgbGFtYmRhMSAtPSBzaWduMSAqIGVwc2lsb24kMjtcbiAgICAgICAgcGhpMCA9IGNsaXBBbnRpbWVyaWRpYW5JbnRlcnNlY3QobGFtYmRhMCwgcGhpMCwgbGFtYmRhMSwgcGhpMSk7XG4gICAgICAgIHN0cmVhbS5wb2ludChzaWduMCwgcGhpMCk7XG4gICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgc3RyZWFtLnBvaW50KHNpZ24xLCBwaGkwKTtcbiAgICAgICAgY2xlYW4gPSAwO1xuICAgICAgfVxuICAgICAgc3RyZWFtLnBvaW50KGxhbWJkYTAgPSBsYW1iZGExLCBwaGkwID0gcGhpMSk7XG4gICAgICBzaWduMCA9IHNpZ24xO1xuICAgIH0sXG4gICAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgICBzdHJlYW0ubGluZUVuZCgpO1xuICAgICAgbGFtYmRhMCA9IHBoaTAgPSBOYU47XG4gICAgfSxcbiAgICBjbGVhbjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gMiAtIGNsZWFuOyAvLyBpZiBpbnRlcnNlY3Rpb25zLCByZWpvaW4gZmlyc3QgYW5kIGxhc3Qgc2VnbWVudHNcbiAgICB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIGNsaXBBbnRpbWVyaWRpYW5JbnRlcnNlY3QobGFtYmRhMCwgcGhpMCwgbGFtYmRhMSwgcGhpMSkge1xuICB2YXIgY29zUGhpMCxcbiAgICAgIGNvc1BoaTEsXG4gICAgICBzaW5MYW1iZGEwTGFtYmRhMSA9IHNpbiQxKGxhbWJkYTAgLSBsYW1iZGExKTtcbiAgcmV0dXJuIGFicyQxKHNpbkxhbWJkYTBMYW1iZGExKSA+IGVwc2lsb24kMlxuICAgICAgPyBhdGFuKChzaW4kMShwaGkwKSAqIChjb3NQaGkxID0gY29zJDEocGhpMSkpICogc2luJDEobGFtYmRhMSlcbiAgICAgICAgICAtIHNpbiQxKHBoaTEpICogKGNvc1BoaTAgPSBjb3MkMShwaGkwKSkgKiBzaW4kMShsYW1iZGEwKSlcbiAgICAgICAgICAvIChjb3NQaGkwICogY29zUGhpMSAqIHNpbkxhbWJkYTBMYW1iZGExKSlcbiAgICAgIDogKHBoaTAgKyBwaGkxKSAvIDI7XG59XG5cbmZ1bmN0aW9uIGNsaXBBbnRpbWVyaWRpYW5JbnRlcnBvbGF0ZShmcm9tLCB0bywgZGlyZWN0aW9uLCBzdHJlYW0pIHtcbiAgdmFyIHBoaTtcbiAgaWYgKGZyb20gPT0gbnVsbCkge1xuICAgIHBoaSA9IGRpcmVjdGlvbiAqIGhhbGZQaSQyO1xuICAgIHN0cmVhbS5wb2ludCgtcGkkMywgcGhpKTtcbiAgICBzdHJlYW0ucG9pbnQoMCwgcGhpKTtcbiAgICBzdHJlYW0ucG9pbnQocGkkMywgcGhpKTtcbiAgICBzdHJlYW0ucG9pbnQocGkkMywgMCk7XG4gICAgc3RyZWFtLnBvaW50KHBpJDMsIC1waGkpO1xuICAgIHN0cmVhbS5wb2ludCgwLCAtcGhpKTtcbiAgICBzdHJlYW0ucG9pbnQoLXBpJDMsIC1waGkpO1xuICAgIHN0cmVhbS5wb2ludCgtcGkkMywgMCk7XG4gICAgc3RyZWFtLnBvaW50KC1waSQzLCBwaGkpO1xuICB9IGVsc2UgaWYgKGFicyQxKGZyb21bMF0gLSB0b1swXSkgPiBlcHNpbG9uJDIpIHtcbiAgICB2YXIgbGFtYmRhID0gZnJvbVswXSA8IHRvWzBdID8gcGkkMyA6IC1waSQzO1xuICAgIHBoaSA9IGRpcmVjdGlvbiAqIGxhbWJkYSAvIDI7XG4gICAgc3RyZWFtLnBvaW50KC1sYW1iZGEsIHBoaSk7XG4gICAgc3RyZWFtLnBvaW50KDAsIHBoaSk7XG4gICAgc3RyZWFtLnBvaW50KGxhbWJkYSwgcGhpKTtcbiAgfSBlbHNlIHtcbiAgICBzdHJlYW0ucG9pbnQodG9bMF0sIHRvWzFdKTtcbiAgfVxufVxuXG52YXIgY2xpcENpcmNsZSA9IGZ1bmN0aW9uKHJhZGl1cykge1xuICB2YXIgY3IgPSBjb3MkMShyYWRpdXMpLFxuICAgICAgZGVsdGEgPSA2ICogcmFkaWFucyxcbiAgICAgIHNtYWxsUmFkaXVzID0gY3IgPiAwLFxuICAgICAgbm90SGVtaXNwaGVyZSA9IGFicyQxKGNyKSA+IGVwc2lsb24kMjsgLy8gVE9ETyBvcHRpbWlzZSBmb3IgdGhpcyBjb21tb24gY2FzZVxuXG4gIGZ1bmN0aW9uIGludGVycG9sYXRlKGZyb20sIHRvLCBkaXJlY3Rpb24sIHN0cmVhbSkge1xuICAgIGNpcmNsZVN0cmVhbShzdHJlYW0sIHJhZGl1cywgZGVsdGEsIGRpcmVjdGlvbiwgZnJvbSwgdG8pO1xuICB9XG5cbiAgZnVuY3Rpb24gdmlzaWJsZShsYW1iZGEsIHBoaSkge1xuICAgIHJldHVybiBjb3MkMShsYW1iZGEpICogY29zJDEocGhpKSA+IGNyO1xuICB9XG5cbiAgLy8gVGFrZXMgYSBsaW5lIGFuZCBjdXRzIGludG8gdmlzaWJsZSBzZWdtZW50cy4gUmV0dXJuIHZhbHVlcyB1c2VkIGZvciBwb2x5Z29uXG4gIC8vIGNsaXBwaW5nOiAwIC0gdGhlcmUgd2VyZSBpbnRlcnNlY3Rpb25zIG9yIHRoZSBsaW5lIHdhcyBlbXB0eTsgMSAtIG5vXG4gIC8vIGludGVyc2VjdGlvbnMgMiAtIHRoZXJlIHdlcmUgaW50ZXJzZWN0aW9ucywgYW5kIHRoZSBmaXJzdCBhbmQgbGFzdCBzZWdtZW50c1xuICAvLyBzaG91bGQgYmUgcmVqb2luZWQuXG4gIGZ1bmN0aW9uIGNsaXBMaW5lKHN0cmVhbSkge1xuICAgIHZhciBwb2ludDAsIC8vIHByZXZpb3VzIHBvaW50XG4gICAgICAgIGMwLCAvLyBjb2RlIGZvciBwcmV2aW91cyBwb2ludFxuICAgICAgICB2MCwgLy8gdmlzaWJpbGl0eSBvZiBwcmV2aW91cyBwb2ludFxuICAgICAgICB2MDAsIC8vIHZpc2liaWxpdHkgb2YgZmlyc3QgcG9pbnRcbiAgICAgICAgY2xlYW47IC8vIG5vIGludGVyc2VjdGlvbnNcbiAgICByZXR1cm4ge1xuICAgICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgICAgdjAwID0gdjAgPSBmYWxzZTtcbiAgICAgICAgY2xlYW4gPSAxO1xuICAgICAgfSxcbiAgICAgIHBvaW50OiBmdW5jdGlvbihsYW1iZGEsIHBoaSkge1xuICAgICAgICB2YXIgcG9pbnQxID0gW2xhbWJkYSwgcGhpXSxcbiAgICAgICAgICAgIHBvaW50MixcbiAgICAgICAgICAgIHYgPSB2aXNpYmxlKGxhbWJkYSwgcGhpKSxcbiAgICAgICAgICAgIGMgPSBzbWFsbFJhZGl1c1xuICAgICAgICAgICAgICA/IHYgPyAwIDogY29kZShsYW1iZGEsIHBoaSlcbiAgICAgICAgICAgICAgOiB2ID8gY29kZShsYW1iZGEgKyAobGFtYmRhIDwgMCA/IHBpJDMgOiAtcGkkMyksIHBoaSkgOiAwO1xuICAgICAgICBpZiAoIXBvaW50MCAmJiAodjAwID0gdjAgPSB2KSkgc3RyZWFtLmxpbmVTdGFydCgpO1xuICAgICAgICAvLyBIYW5kbGUgZGVnZW5lcmFjaWVzLlxuICAgICAgICAvLyBUT0RPIGlnbm9yZSBpZiBub3QgY2xpcHBpbmcgcG9seWdvbnMuXG4gICAgICAgIGlmICh2ICE9PSB2MCkge1xuICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChwb2ludDAsIHBvaW50MSk7XG4gICAgICAgICAgaWYgKCFwb2ludDIgfHwgcG9pbnRFcXVhbChwb2ludDAsIHBvaW50MikgfHwgcG9pbnRFcXVhbChwb2ludDEsIHBvaW50MikpIHtcbiAgICAgICAgICAgIHBvaW50MVswXSArPSBlcHNpbG9uJDI7XG4gICAgICAgICAgICBwb2ludDFbMV0gKz0gZXBzaWxvbiQyO1xuICAgICAgICAgICAgdiA9IHZpc2libGUocG9pbnQxWzBdLCBwb2ludDFbMV0pO1xuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodiAhPT0gdjApIHtcbiAgICAgICAgICBjbGVhbiA9IDA7XG4gICAgICAgICAgaWYgKHYpIHtcbiAgICAgICAgICAgIC8vIG91dHNpZGUgZ29pbmcgaW5cbiAgICAgICAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgIHBvaW50MiA9IGludGVyc2VjdChwb2ludDEsIHBvaW50MCk7XG4gICAgICAgICAgICBzdHJlYW0ucG9pbnQocG9pbnQyWzBdLCBwb2ludDJbMV0pO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICAvLyBpbnNpZGUgZ29pbmcgb3V0XG4gICAgICAgICAgICBwb2ludDIgPSBpbnRlcnNlY3QocG9pbnQwLCBwb2ludDEpO1xuICAgICAgICAgICAgc3RyZWFtLnBvaW50KHBvaW50MlswXSwgcG9pbnQyWzFdKTtcbiAgICAgICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgICAgfVxuICAgICAgICAgIHBvaW50MCA9IHBvaW50MjtcbiAgICAgICAgfSBlbHNlIGlmIChub3RIZW1pc3BoZXJlICYmIHBvaW50MCAmJiBzbWFsbFJhZGl1cyBeIHYpIHtcbiAgICAgICAgICB2YXIgdDtcbiAgICAgICAgICAvLyBJZiB0aGUgY29kZXMgZm9yIHR3byBwb2ludHMgYXJlIGRpZmZlcmVudCwgb3IgYXJlIGJvdGggemVybyxcbiAgICAgICAgICAvLyBhbmQgdGhlcmUgdGhpcyBzZWdtZW50IGludGVyc2VjdHMgd2l0aCB0aGUgc21hbGwgY2lyY2xlLlxuICAgICAgICAgIGlmICghKGMgJiBjMCkgJiYgKHQgPSBpbnRlcnNlY3QocG9pbnQxLCBwb2ludDAsIHRydWUpKSkge1xuICAgICAgICAgICAgY2xlYW4gPSAwO1xuICAgICAgICAgICAgaWYgKHNtYWxsUmFkaXVzKSB7XG4gICAgICAgICAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgICAgc3RyZWFtLnBvaW50KHRbMF1bMF0sIHRbMF1bMV0pO1xuICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFsxXVswXSwgdFsxXVsxXSk7XG4gICAgICAgICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICBzdHJlYW0ucG9pbnQodFsxXVswXSwgdFsxXVsxXSk7XG4gICAgICAgICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgICAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgICAgc3RyZWFtLnBvaW50KHRbMF1bMF0sIHRbMF1bMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgIH1cbiAgICAgICAgfVxuICAgICAgICBpZiAodiAmJiAoIXBvaW50MCB8fCAhcG9pbnRFcXVhbChwb2ludDAsIHBvaW50MSkpKSB7XG4gICAgICAgICAgc3RyZWFtLnBvaW50KHBvaW50MVswXSwgcG9pbnQxWzFdKTtcbiAgICAgICAgfVxuICAgICAgICBwb2ludDAgPSBwb2ludDEsIHYwID0gdiwgYzAgPSBjO1xuICAgICAgfSxcbiAgICAgIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgICAgICBpZiAodjApIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgIHBvaW50MCA9IG51bGw7XG4gICAgICB9LFxuICAgICAgLy8gUmVqb2luIGZpcnN0IGFuZCBsYXN0IHNlZ21lbnRzIGlmIHRoZXJlIHdlcmUgaW50ZXJzZWN0aW9ucyBhbmQgdGhlIGZpcnN0XG4gICAgICAvLyBhbmQgbGFzdCBwb2ludHMgd2VyZSB2aXNpYmxlLlxuICAgICAgY2xlYW46IGZ1bmN0aW9uKCkge1xuICAgICAgICByZXR1cm4gY2xlYW4gfCAoKHYwMCAmJiB2MCkgPDwgMSk7XG4gICAgICB9XG4gICAgfTtcbiAgfVxuXG4gIC8vIEludGVyc2VjdHMgdGhlIGdyZWF0IGNpcmNsZSBiZXR3ZWVuIGEgYW5kIGIgd2l0aCB0aGUgY2xpcCBjaXJjbGUuXG4gIGZ1bmN0aW9uIGludGVyc2VjdChhLCBiLCB0d28pIHtcbiAgICB2YXIgcGEgPSBjYXJ0ZXNpYW4oYSksXG4gICAgICAgIHBiID0gY2FydGVzaWFuKGIpO1xuXG4gICAgLy8gV2UgaGF2ZSB0d28gcGxhbmVzLCBuMS5wID0gZDEgYW5kIG4yLnAgPSBkMi5cbiAgICAvLyBGaW5kIGludGVyc2VjdGlvbiBsaW5lIHAodCkgPSBjMSBuMSArIGMyIG4yICsgdCAobjEg4qivIG4yKS5cbiAgICB2YXIgbjEgPSBbMSwgMCwgMF0sIC8vIG5vcm1hbFxuICAgICAgICBuMiA9IGNhcnRlc2lhbkNyb3NzKHBhLCBwYiksXG4gICAgICAgIG4ybjIgPSBjYXJ0ZXNpYW5Eb3QobjIsIG4yKSxcbiAgICAgICAgbjFuMiA9IG4yWzBdLCAvLyBjYXJ0ZXNpYW5Eb3QobjEsIG4yKSxcbiAgICAgICAgZGV0ZXJtaW5hbnQgPSBuMm4yIC0gbjFuMiAqIG4xbjI7XG5cbiAgICAvLyBUd28gcG9sYXIgcG9pbnRzLlxuICAgIGlmICghZGV0ZXJtaW5hbnQpIHJldHVybiAhdHdvICYmIGE7XG5cbiAgICB2YXIgYzEgPSAgY3IgKiBuMm4yIC8gZGV0ZXJtaW5hbnQsXG4gICAgICAgIGMyID0gLWNyICogbjFuMiAvIGRldGVybWluYW50LFxuICAgICAgICBuMXhuMiA9IGNhcnRlc2lhbkNyb3NzKG4xLCBuMiksXG4gICAgICAgIEEgPSBjYXJ0ZXNpYW5TY2FsZShuMSwgYzEpLFxuICAgICAgICBCID0gY2FydGVzaWFuU2NhbGUobjIsIGMyKTtcbiAgICBjYXJ0ZXNpYW5BZGRJblBsYWNlKEEsIEIpO1xuXG4gICAgLy8gU29sdmUgfHAodCl8XjIgPSAxLlxuICAgIHZhciB1ID0gbjF4bjIsXG4gICAgICAgIHcgPSBjYXJ0ZXNpYW5Eb3QoQSwgdSksXG4gICAgICAgIHV1ID0gY2FydGVzaWFuRG90KHUsIHUpLFxuICAgICAgICB0MiA9IHcgKiB3IC0gdXUgKiAoY2FydGVzaWFuRG90KEEsIEEpIC0gMSk7XG5cbiAgICBpZiAodDIgPCAwKSByZXR1cm47XG5cbiAgICB2YXIgdCA9IHNxcnQkMih0MiksXG4gICAgICAgIHEgPSBjYXJ0ZXNpYW5TY2FsZSh1LCAoLXcgLSB0KSAvIHV1KTtcbiAgICBjYXJ0ZXNpYW5BZGRJblBsYWNlKHEsIEEpO1xuICAgIHEgPSBzcGhlcmljYWwocSk7XG5cbiAgICBpZiAoIXR3bykgcmV0dXJuIHE7XG5cbiAgICAvLyBUd28gaW50ZXJzZWN0aW9uIHBvaW50cy5cbiAgICB2YXIgbGFtYmRhMCA9IGFbMF0sXG4gICAgICAgIGxhbWJkYTEgPSBiWzBdLFxuICAgICAgICBwaGkwID0gYVsxXSxcbiAgICAgICAgcGhpMSA9IGJbMV0sXG4gICAgICAgIHo7XG5cbiAgICBpZiAobGFtYmRhMSA8IGxhbWJkYTApIHogPSBsYW1iZGEwLCBsYW1iZGEwID0gbGFtYmRhMSwgbGFtYmRhMSA9IHo7XG5cbiAgICB2YXIgZGVsdGEgPSBsYW1iZGExIC0gbGFtYmRhMCxcbiAgICAgICAgcG9sYXIgPSBhYnMkMShkZWx0YSAtIHBpJDMpIDwgZXBzaWxvbiQyLFxuICAgICAgICBtZXJpZGlhbiA9IHBvbGFyIHx8IGRlbHRhIDwgZXBzaWxvbiQyO1xuXG4gICAgaWYgKCFwb2xhciAmJiBwaGkxIDwgcGhpMCkgeiA9IHBoaTAsIHBoaTAgPSBwaGkxLCBwaGkxID0gejtcblxuICAgIC8vIENoZWNrIHRoYXQgdGhlIGZpcnN0IHBvaW50IGlzIGJldHdlZW4gYSBhbmQgYi5cbiAgICBpZiAobWVyaWRpYW5cbiAgICAgICAgPyBwb2xhclxuICAgICAgICAgID8gcGhpMCArIHBoaTEgPiAwIF4gcVsxXSA8IChhYnMkMShxWzBdIC0gbGFtYmRhMCkgPCBlcHNpbG9uJDIgPyBwaGkwIDogcGhpMSlcbiAgICAgICAgICA6IHBoaTAgPD0gcVsxXSAmJiBxWzFdIDw9IHBoaTFcbiAgICAgICAgOiBkZWx0YSA+IHBpJDMgXiAobGFtYmRhMCA8PSBxWzBdICYmIHFbMF0gPD0gbGFtYmRhMSkpIHtcbiAgICAgIHZhciBxMSA9IGNhcnRlc2lhblNjYWxlKHUsICgtdyArIHQpIC8gdXUpO1xuICAgICAgY2FydGVzaWFuQWRkSW5QbGFjZShxMSwgQSk7XG4gICAgICByZXR1cm4gW3EsIHNwaGVyaWNhbChxMSldO1xuICAgIH1cbiAgfVxuXG4gIC8vIEdlbmVyYXRlcyBhIDQtYml0IHZlY3RvciByZXByZXNlbnRpbmcgdGhlIGxvY2F0aW9uIG9mIGEgcG9pbnQgcmVsYXRpdmUgdG9cbiAgLy8gdGhlIHNtYWxsIGNpcmNsZSdzIGJvdW5kaW5nIGJveC5cbiAgZnVuY3Rpb24gY29kZShsYW1iZGEsIHBoaSkge1xuICAgIHZhciByID0gc21hbGxSYWRpdXMgPyByYWRpdXMgOiBwaSQzIC0gcmFkaXVzLFxuICAgICAgICBjb2RlID0gMDtcbiAgICBpZiAobGFtYmRhIDwgLXIpIGNvZGUgfD0gMTsgLy8gbGVmdFxuICAgIGVsc2UgaWYgKGxhbWJkYSA+IHIpIGNvZGUgfD0gMjsgLy8gcmlnaHRcbiAgICBpZiAocGhpIDwgLXIpIGNvZGUgfD0gNDsgLy8gYmVsb3dcbiAgICBlbHNlIGlmIChwaGkgPiByKSBjb2RlIHw9IDg7IC8vIGFib3ZlXG4gICAgcmV0dXJuIGNvZGU7XG4gIH1cblxuICByZXR1cm4gY2xpcCQyKHZpc2libGUsIGNsaXBMaW5lLCBpbnRlcnBvbGF0ZSwgc21hbGxSYWRpdXMgPyBbMCwgLXJhZGl1c10gOiBbLXBpJDMsIHJhZGl1cyAtIHBpJDNdKTtcbn07XG5cbnZhciBjbGlwTGluZSA9IGZ1bmN0aW9uKGEsIGIsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICB0MCA9IDAsXG4gICAgICB0MSA9IDEsXG4gICAgICBkeCA9IGJ4IC0gYXgsXG4gICAgICBkeSA9IGJ5IC0gYXksXG4gICAgICByO1xuXG4gIHIgPSB4MCAtIGF4O1xuICBpZiAoIWR4ICYmIHIgPiAwKSByZXR1cm47XG4gIHIgLz0gZHg7XG4gIGlmIChkeCA8IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9IGVsc2UgaWYgKGR4ID4gMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH1cblxuICByID0geDEgLSBheDtcbiAgaWYgKCFkeCAmJiByIDwgMCkgcmV0dXJuO1xuICByIC89IGR4O1xuICBpZiAoZHggPCAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfSBlbHNlIGlmIChkeCA+IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9XG5cbiAgciA9IHkwIC0gYXk7XG4gIGlmICghZHkgJiYgciA+IDApIHJldHVybjtcbiAgciAvPSBkeTtcbiAgaWYgKGR5IDwgMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH0gZWxzZSBpZiAoZHkgPiAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfVxuXG4gIHIgPSB5MSAtIGF5O1xuICBpZiAoIWR5ICYmIHIgPCAwKSByZXR1cm47XG4gIHIgLz0gZHk7XG4gIGlmIChkeSA8IDApIHtcbiAgICBpZiAociA+IHQxKSByZXR1cm47XG4gICAgaWYgKHIgPiB0MCkgdDAgPSByO1xuICB9IGVsc2UgaWYgKGR5ID4gMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH1cblxuICBpZiAodDAgPiAwKSBhWzBdID0gYXggKyB0MCAqIGR4LCBhWzFdID0gYXkgKyB0MCAqIGR5O1xuICBpZiAodDEgPCAxKSBiWzBdID0gYXggKyB0MSAqIGR4LCBiWzFdID0gYXkgKyB0MSAqIGR5O1xuICByZXR1cm4gdHJ1ZTtcbn07XG5cbnZhciBjbGlwTWF4ID0gMWU5O1xudmFyIGNsaXBNaW4gPSAtY2xpcE1heDtcblxuLy8gVE9ETyBVc2UgZDMtcG9seWdvbuKAmXMgcG9seWdvbkNvbnRhaW5zIGhlcmUgZm9yIHRoZSByaW5nIGNoZWNrP1xuLy8gVE9ETyBFbGltaW5hdGUgZHVwbGljYXRlIGJ1ZmZlcmluZyBpbiBjbGlwQnVmZmVyIGFuZCBwb2x5Z29uLnB1c2g/XG5cbmZ1bmN0aW9uIGNsaXBSZWN0YW5nbGUoeDAsIHkwLCB4MSwgeTEpIHtcblxuICBmdW5jdGlvbiB2aXNpYmxlKHgsIHkpIHtcbiAgICByZXR1cm4geDAgPD0geCAmJiB4IDw9IHgxICYmIHkwIDw9IHkgJiYgeSA8PSB5MTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGludGVycG9sYXRlKGZyb20sIHRvLCBkaXJlY3Rpb24sIHN0cmVhbSkge1xuICAgIHZhciBhID0gMCwgYTEgPSAwO1xuICAgIGlmIChmcm9tID09IG51bGxcbiAgICAgICAgfHwgKGEgPSBjb3JuZXIoZnJvbSwgZGlyZWN0aW9uKSkgIT09IChhMSA9IGNvcm5lcih0bywgZGlyZWN0aW9uKSlcbiAgICAgICAgfHwgY29tcGFyZVBvaW50KGZyb20sIHRvKSA8IDAgXiBkaXJlY3Rpb24gPiAwKSB7XG4gICAgICBkbyBzdHJlYW0ucG9pbnQoYSA9PT0gMCB8fCBhID09PSAzID8geDAgOiB4MSwgYSA+IDEgPyB5MSA6IHkwKTtcbiAgICAgIHdoaWxlICgoYSA9IChhICsgZGlyZWN0aW9uICsgNCkgJSA0KSAhPT0gYTEpO1xuICAgIH0gZWxzZSB7XG4gICAgICBzdHJlYW0ucG9pbnQodG9bMF0sIHRvWzFdKTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBjb3JuZXIocCwgZGlyZWN0aW9uKSB7XG4gICAgcmV0dXJuIGFicyQxKHBbMF0gLSB4MCkgPCBlcHNpbG9uJDIgPyBkaXJlY3Rpb24gPiAwID8gMCA6IDNcbiAgICAgICAgOiBhYnMkMShwWzBdIC0geDEpIDwgZXBzaWxvbiQyID8gZGlyZWN0aW9uID4gMCA/IDIgOiAxXG4gICAgICAgIDogYWJzJDEocFsxXSAtIHkwKSA8IGVwc2lsb24kMiA/IGRpcmVjdGlvbiA+IDAgPyAxIDogMFxuICAgICAgICA6IGRpcmVjdGlvbiA+IDAgPyAzIDogMjsgLy8gYWJzKHBbMV0gLSB5MSkgPCBlcHNpbG9uXG4gIH1cblxuICBmdW5jdGlvbiBjb21wYXJlSW50ZXJzZWN0aW9uKGEsIGIpIHtcbiAgICByZXR1cm4gY29tcGFyZVBvaW50KGEueCwgYi54KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGNvbXBhcmVQb2ludChhLCBiKSB7XG4gICAgdmFyIGNhID0gY29ybmVyKGEsIDEpLFxuICAgICAgICBjYiA9IGNvcm5lcihiLCAxKTtcbiAgICByZXR1cm4gY2EgIT09IGNiID8gY2EgLSBjYlxuICAgICAgICA6IGNhID09PSAwID8gYlsxXSAtIGFbMV1cbiAgICAgICAgOiBjYSA9PT0gMSA/IGFbMF0gLSBiWzBdXG4gICAgICAgIDogY2EgPT09IDIgPyBhWzFdIC0gYlsxXVxuICAgICAgICA6IGJbMF0gLSBhWzBdO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHZhciBhY3RpdmVTdHJlYW0gPSBzdHJlYW0sXG4gICAgICAgIGJ1ZmZlclN0cmVhbSA9IGNsaXBCdWZmZXIoKSxcbiAgICAgICAgc2VnbWVudHMsXG4gICAgICAgIHBvbHlnb24sXG4gICAgICAgIHJpbmcsXG4gICAgICAgIHhfXywgeV9fLCB2X18sIC8vIGZpcnN0IHBvaW50XG4gICAgICAgIHhfLCB5Xywgdl8sIC8vIHByZXZpb3VzIHBvaW50XG4gICAgICAgIGZpcnN0LFxuICAgICAgICBjbGVhbjtcblxuICAgIHZhciBjbGlwU3RyZWFtID0ge1xuICAgICAgcG9pbnQ6IHBvaW50LFxuICAgICAgbGluZVN0YXJ0OiBsaW5lU3RhcnQsXG4gICAgICBsaW5lRW5kOiBsaW5lRW5kLFxuICAgICAgcG9seWdvblN0YXJ0OiBwb2x5Z29uU3RhcnQsXG4gICAgICBwb2x5Z29uRW5kOiBwb2x5Z29uRW5kXG4gICAgfTtcblxuICAgIGZ1bmN0aW9uIHBvaW50KHgsIHkpIHtcbiAgICAgIGlmICh2aXNpYmxlKHgsIHkpKSBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcG9seWdvbkluc2lkZSgpIHtcbiAgICAgIHZhciB3aW5kaW5nID0gMDtcblxuICAgICAgZm9yICh2YXIgaSA9IDAsIG4gPSBwb2x5Z29uLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgICBmb3IgKHZhciByaW5nID0gcG9seWdvbltpXSwgaiA9IDEsIG0gPSByaW5nLmxlbmd0aCwgcG9pbnQgPSByaW5nWzBdLCBhMCwgYTEsIGIwID0gcG9pbnRbMF0sIGIxID0gcG9pbnRbMV07IGogPCBtOyArK2opIHtcbiAgICAgICAgICBhMCA9IGIwLCBhMSA9IGIxLCBwb2ludCA9IHJpbmdbal0sIGIwID0gcG9pbnRbMF0sIGIxID0gcG9pbnRbMV07XG4gICAgICAgICAgaWYgKGExIDw9IHkxKSB7IGlmIChiMSA+IHkxICYmIChiMCAtIGEwKSAqICh5MSAtIGExKSA+IChiMSAtIGExKSAqICh4MCAtIGEwKSkgKyt3aW5kaW5nOyB9XG4gICAgICAgICAgZWxzZSB7IGlmIChiMSA8PSB5MSAmJiAoYjAgLSBhMCkgKiAoeTEgLSBhMSkgPCAoYjEgLSBhMSkgKiAoeDAgLSBhMCkpIC0td2luZGluZzsgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIHJldHVybiB3aW5kaW5nO1xuICAgIH1cblxuICAgIC8vIEJ1ZmZlciBnZW9tZXRyeSB3aXRoaW4gYSBwb2x5Z29uIGFuZCB0aGVuIGNsaXAgaXQgZW4gbWFzc2UuXG4gICAgZnVuY3Rpb24gcG9seWdvblN0YXJ0KCkge1xuICAgICAgYWN0aXZlU3RyZWFtID0gYnVmZmVyU3RyZWFtLCBzZWdtZW50cyA9IFtdLCBwb2x5Z29uID0gW10sIGNsZWFuID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBwb2x5Z29uRW5kKCkge1xuICAgICAgdmFyIHN0YXJ0SW5zaWRlID0gcG9seWdvbkluc2lkZSgpLFxuICAgICAgICAgIGNsZWFuSW5zaWRlID0gY2xlYW4gJiYgc3RhcnRJbnNpZGUsXG4gICAgICAgICAgdmlzaWJsZSA9IChzZWdtZW50cyA9IG1lcmdlJDIoc2VnbWVudHMpKS5sZW5ndGg7XG4gICAgICBpZiAoY2xlYW5JbnNpZGUgfHwgdmlzaWJsZSkge1xuICAgICAgICBzdHJlYW0ucG9seWdvblN0YXJ0KCk7XG4gICAgICAgIGlmIChjbGVhbkluc2lkZSkge1xuICAgICAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICBpbnRlcnBvbGF0ZShudWxsLCBudWxsLCAxLCBzdHJlYW0pO1xuICAgICAgICAgIHN0cmVhbS5saW5lRW5kKCk7XG4gICAgICAgIH1cbiAgICAgICAgaWYgKHZpc2libGUpIHtcbiAgICAgICAgICBjbGlwUmVqb2luKHNlZ21lbnRzLCBjb21wYXJlSW50ZXJzZWN0aW9uLCBzdGFydEluc2lkZSwgaW50ZXJwb2xhdGUsIHN0cmVhbSk7XG4gICAgICAgIH1cbiAgICAgICAgc3RyZWFtLnBvbHlnb25FbmQoKTtcbiAgICAgIH1cbiAgICAgIGFjdGl2ZVN0cmVhbSA9IHN0cmVhbSwgc2VnbWVudHMgPSBwb2x5Z29uID0gcmluZyA9IG51bGw7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVN0YXJ0KCkge1xuICAgICAgY2xpcFN0cmVhbS5wb2ludCA9IGxpbmVQb2ludDtcbiAgICAgIGlmIChwb2x5Z29uKSBwb2x5Z29uLnB1c2gocmluZyA9IFtdKTtcbiAgICAgIGZpcnN0ID0gdHJ1ZTtcbiAgICAgIHZfID0gZmFsc2U7XG4gICAgICB4XyA9IHlfID0gTmFOO1xuICAgIH1cblxuICAgIC8vIFRPRE8gcmF0aGVyIHRoYW4gc3BlY2lhbC1jYXNlIHBvbHlnb25zLCBzaW1wbHkgaGFuZGxlIHRoZW0gc2VwYXJhdGVseS5cbiAgICAvLyBJZGVhbGx5LCBjb2luY2lkZW50IGludGVyc2VjdGlvbiBwb2ludHMgc2hvdWxkIGJlIGppdHRlcmVkIHRvIGF2b2lkXG4gICAgLy8gY2xpcHBpbmcgaXNzdWVzLlxuICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICBpZiAoc2VnbWVudHMpIHtcbiAgICAgICAgbGluZVBvaW50KHhfXywgeV9fKTtcbiAgICAgICAgaWYgKHZfXyAmJiB2XykgYnVmZmVyU3RyZWFtLnJlam9pbigpO1xuICAgICAgICBzZWdtZW50cy5wdXNoKGJ1ZmZlclN0cmVhbS5yZXN1bHQoKSk7XG4gICAgICB9XG4gICAgICBjbGlwU3RyZWFtLnBvaW50ID0gcG9pbnQ7XG4gICAgICBpZiAodl8pIGFjdGl2ZVN0cmVhbS5saW5lRW5kKCk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVBvaW50KHgsIHkpIHtcbiAgICAgIHZhciB2ID0gdmlzaWJsZSh4LCB5KTtcbiAgICAgIGlmIChwb2x5Z29uKSByaW5nLnB1c2goW3gsIHldKTtcbiAgICAgIGlmIChmaXJzdCkge1xuICAgICAgICB4X18gPSB4LCB5X18gPSB5LCB2X18gPSB2O1xuICAgICAgICBmaXJzdCA9IGZhbHNlO1xuICAgICAgICBpZiAodikge1xuICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICh2ICYmIHZfKSBhY3RpdmVTdHJlYW0ucG9pbnQoeCwgeSk7XG4gICAgICAgIGVsc2Uge1xuICAgICAgICAgIHZhciBhID0gW3hfID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeF8pKSwgeV8gPSBNYXRoLm1heChjbGlwTWluLCBNYXRoLm1pbihjbGlwTWF4LCB5XykpXSxcbiAgICAgICAgICAgICAgYiA9IFt4ID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeCkpLCB5ID0gTWF0aC5tYXgoY2xpcE1pbiwgTWF0aC5taW4oY2xpcE1heCwgeSkpXTtcbiAgICAgICAgICBpZiAoY2xpcExpbmUoYSwgYiwgeDAsIHkwLCB4MSwgeTEpKSB7XG4gICAgICAgICAgICBpZiAoIXZfKSB7XG4gICAgICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgICAgYWN0aXZlU3RyZWFtLnBvaW50KGFbMF0sIGFbMV0pO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYWN0aXZlU3RyZWFtLnBvaW50KGJbMF0sIGJbMV0pO1xuICAgICAgICAgICAgaWYgKCF2KSBhY3RpdmVTdHJlYW0ubGluZUVuZCgpO1xuICAgICAgICAgICAgY2xlYW4gPSBmYWxzZTtcbiAgICAgICAgICB9IGVsc2UgaWYgKHYpIHtcbiAgICAgICAgICAgIGFjdGl2ZVN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICAgICAgICAgIGFjdGl2ZVN0cmVhbS5wb2ludCh4LCB5KTtcbiAgICAgICAgICAgIGNsZWFuID0gZmFsc2U7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgICB4XyA9IHgsIHlfID0geSwgdl8gPSB2O1xuICAgIH1cblxuICAgIHJldHVybiBjbGlwU3RyZWFtO1xuICB9O1xufVxuXG52YXIgbGVuZ3RoU3VtID0gYWRkZXIoKTtcbnZhciBsYW1iZGEwJDI7XG52YXIgc2luUGhpMCQxO1xudmFyIGNvc1BoaTAkMTtcblxudmFyIGxlbmd0aFN0cmVhbSA9IHtcbiAgc3BoZXJlOiBub29wJDQsXG4gIHBvaW50OiBub29wJDQsXG4gIGxpbmVTdGFydDogbGVuZ3RoTGluZVN0YXJ0LFxuICBsaW5lRW5kOiBub29wJDQsXG4gIHBvbHlnb25TdGFydDogbm9vcCQ0LFxuICBwb2x5Z29uRW5kOiBub29wJDRcbn07XG5cbmZ1bmN0aW9uIGxlbmd0aExpbmVTdGFydCgpIHtcbiAgbGVuZ3RoU3RyZWFtLnBvaW50ID0gbGVuZ3RoUG9pbnRGaXJzdDtcbiAgbGVuZ3RoU3RyZWFtLmxpbmVFbmQgPSBsZW5ndGhMaW5lRW5kO1xufVxuXG5mdW5jdGlvbiBsZW5ndGhMaW5lRW5kKCkge1xuICBsZW5ndGhTdHJlYW0ucG9pbnQgPSBsZW5ndGhTdHJlYW0ubGluZUVuZCA9IG5vb3AkNDtcbn1cblxuZnVuY3Rpb24gbGVuZ3RoUG9pbnRGaXJzdChsYW1iZGEsIHBoaSkge1xuICBsYW1iZGEgKj0gcmFkaWFucywgcGhpICo9IHJhZGlhbnM7XG4gIGxhbWJkYTAkMiA9IGxhbWJkYSwgc2luUGhpMCQxID0gc2luJDEocGhpKSwgY29zUGhpMCQxID0gY29zJDEocGhpKTtcbiAgbGVuZ3RoU3RyZWFtLnBvaW50ID0gbGVuZ3RoUG9pbnQ7XG59XG5cbmZ1bmN0aW9uIGxlbmd0aFBvaW50KGxhbWJkYSwgcGhpKSB7XG4gIGxhbWJkYSAqPSByYWRpYW5zLCBwaGkgKj0gcmFkaWFucztcbiAgdmFyIHNpblBoaSA9IHNpbiQxKHBoaSksXG4gICAgICBjb3NQaGkgPSBjb3MkMShwaGkpLFxuICAgICAgZGVsdGEgPSBhYnMkMShsYW1iZGEgLSBsYW1iZGEwJDIpLFxuICAgICAgY29zRGVsdGEgPSBjb3MkMShkZWx0YSksXG4gICAgICBzaW5EZWx0YSA9IHNpbiQxKGRlbHRhKSxcbiAgICAgIHggPSBjb3NQaGkgKiBzaW5EZWx0YSxcbiAgICAgIHkgPSBjb3NQaGkwJDEgKiBzaW5QaGkgLSBzaW5QaGkwJDEgKiBjb3NQaGkgKiBjb3NEZWx0YSxcbiAgICAgIHogPSBzaW5QaGkwJDEgKiBzaW5QaGkgKyBjb3NQaGkwJDEgKiBjb3NQaGkgKiBjb3NEZWx0YTtcbiAgbGVuZ3RoU3VtLmFkZChhdGFuMiQxKHNxcnQkMih4ICogeCArIHkgKiB5KSwgeikpO1xuICBsYW1iZGEwJDIgPSBsYW1iZGEsIHNpblBoaTAkMSA9IHNpblBoaSwgY29zUGhpMCQxID0gY29zUGhpO1xufVxuXG52YXIgbGVuZ3RoJDEgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgbGVuZ3RoU3VtLnJlc2V0KCk7XG4gIGdlb1N0cmVhbShvYmplY3QsIGxlbmd0aFN0cmVhbSk7XG4gIHJldHVybiArbGVuZ3RoU3VtO1xufTtcblxudmFyIGNvb3JkaW5hdGVzID0gW251bGwsIG51bGxdO1xudmFyIG9iamVjdCQzID0ge3R5cGU6IFwiTGluZVN0cmluZ1wiLCBjb29yZGluYXRlczogY29vcmRpbmF0ZXN9O1xuXG52YXIgZGlzdGFuY2UgPSBmdW5jdGlvbihhLCBiKSB7XG4gIGNvb3JkaW5hdGVzWzBdID0gYTtcbiAgY29vcmRpbmF0ZXNbMV0gPSBiO1xuICByZXR1cm4gbGVuZ3RoJDEob2JqZWN0JDMpO1xufTtcblxudmFyIGNvbnRhaW5zR2VvbWV0cnlUeXBlID0ge1xuICBTcGhlcmU6IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB0cnVlO1xuICB9LFxuICBQb2ludDogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHJldHVybiBjb250YWluc1BvaW50KG9iamVjdC5jb29yZGluYXRlcywgcG9pbnQpO1xuICB9LFxuICBNdWx0aVBvaW50OiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gICAgdmFyIGNvb3JkaW5hdGVzID0gb2JqZWN0LmNvb3JkaW5hdGVzLCBpID0gLTEsIG4gPSBjb29yZGluYXRlcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmIChjb250YWluc1BvaW50KGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHJldHVybiBjb250YWluc0xpbmUob2JqZWN0LmNvb3JkaW5hdGVzLCBwb2ludCk7XG4gIH0sXG4gIE11bHRpTGluZVN0cmluZzogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoY29udGFpbnNMaW5lKGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHJldHVybiBjb250YWluc1BvbHlnb24ob2JqZWN0LmNvb3JkaW5hdGVzLCBwb2ludCk7XG4gIH0sXG4gIE11bHRpUG9seWdvbjogZnVuY3Rpb24ob2JqZWN0LCBwb2ludCkge1xuICAgIHZhciBjb29yZGluYXRlcyA9IG9iamVjdC5jb29yZGluYXRlcywgaSA9IC0xLCBuID0gY29vcmRpbmF0ZXMubGVuZ3RoO1xuICAgIHdoaWxlICgrK2kgPCBuKSBpZiAoY29udGFpbnNQb2x5Z29uKGNvb3JkaW5hdGVzW2ldLCBwb2ludCkpIHJldHVybiB0cnVlO1xuICAgIHJldHVybiBmYWxzZTtcbiAgfSxcbiAgR2VvbWV0cnlDb2xsZWN0aW9uOiBmdW5jdGlvbihvYmplY3QsIHBvaW50KSB7XG4gICAgdmFyIGdlb21ldHJpZXMgPSBvYmplY3QuZ2VvbWV0cmllcywgaSA9IC0xLCBuID0gZ2VvbWV0cmllcy5sZW5ndGg7XG4gICAgd2hpbGUgKCsraSA8IG4pIGlmIChjb250YWluc0dlb21ldHJ5KGdlb21ldHJpZXNbaV0sIHBvaW50KSkgcmV0dXJuIHRydWU7XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjb250YWluc0dlb21ldHJ5KGdlb21ldHJ5LCBwb2ludCkge1xuICByZXR1cm4gZ2VvbWV0cnkgJiYgY29udGFpbnNHZW9tZXRyeVR5cGUuaGFzT3duUHJvcGVydHkoZ2VvbWV0cnkudHlwZSlcbiAgICAgID8gY29udGFpbnNHZW9tZXRyeVR5cGVbZ2VvbWV0cnkudHlwZV0oZ2VvbWV0cnksIHBvaW50KVxuICAgICAgOiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY29udGFpbnNQb2ludChjb29yZGluYXRlcywgcG9pbnQpIHtcbiAgcmV0dXJuIGRpc3RhbmNlKGNvb3JkaW5hdGVzLCBwb2ludCkgPT09IDA7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zTGluZShjb29yZGluYXRlcywgcG9pbnQpIHtcbiAgdmFyIGFiID0gZGlzdGFuY2UoY29vcmRpbmF0ZXNbMF0sIGNvb3JkaW5hdGVzWzFdKSxcbiAgICAgIGFvID0gZGlzdGFuY2UoY29vcmRpbmF0ZXNbMF0sIHBvaW50KSxcbiAgICAgIG9iID0gZGlzdGFuY2UocG9pbnQsIGNvb3JkaW5hdGVzWzFdKTtcbiAgcmV0dXJuIGFvICsgb2IgPD0gYWIgKyBlcHNpbG9uJDI7XG59XG5cbmZ1bmN0aW9uIGNvbnRhaW5zUG9seWdvbihjb29yZGluYXRlcywgcG9pbnQpIHtcbiAgcmV0dXJuICEhcG9seWdvbkNvbnRhaW5zKGNvb3JkaW5hdGVzLm1hcChyaW5nUmFkaWFucyksIHBvaW50UmFkaWFucyhwb2ludCkpO1xufVxuXG5mdW5jdGlvbiByaW5nUmFkaWFucyhyaW5nKSB7XG4gIHJldHVybiByaW5nID0gcmluZy5tYXAocG9pbnRSYWRpYW5zKSwgcmluZy5wb3AoKSwgcmluZztcbn1cblxuZnVuY3Rpb24gcG9pbnRSYWRpYW5zKHBvaW50KSB7XG4gIHJldHVybiBbcG9pbnRbMF0gKiByYWRpYW5zLCBwb2ludFsxXSAqIHJhZGlhbnNdO1xufVxuXG5mdW5jdGlvbiBncmF0aWN1bGVYKHkwLCB5MSwgZHkpIHtcbiAgdmFyIHkgPSBzZXF1ZW5jZSh5MCwgeTEgLSBlcHNpbG9uJDIsIGR5KS5jb25jYXQoeTEpO1xuICByZXR1cm4gZnVuY3Rpb24oeCkgeyByZXR1cm4geS5tYXAoZnVuY3Rpb24oeSkgeyByZXR1cm4gW3gsIHldOyB9KTsgfTtcbn1cblxuZnVuY3Rpb24gZ3JhdGljdWxlWSh4MCwgeDEsIGR4KSB7XG4gIHZhciB4ID0gc2VxdWVuY2UoeDAsIHgxIC0gZXBzaWxvbiQyLCBkeCkuY29uY2F0KHgxKTtcbiAgcmV0dXJuIGZ1bmN0aW9uKHkpIHsgcmV0dXJuIHgubWFwKGZ1bmN0aW9uKHgpIHsgcmV0dXJuIFt4LCB5XTsgfSk7IH07XG59XG5cbmZ1bmN0aW9uIGdyYXRpY3VsZSgpIHtcbiAgdmFyIHgxLCB4MCwgWDEsIFgwLFxuICAgICAgeTEsIHkwLCBZMSwgWTAsXG4gICAgICBkeCA9IDEwLCBkeSA9IGR4LCBEWCA9IDkwLCBEWSA9IDM2MCxcbiAgICAgIHgsIHksIFgsIFksXG4gICAgICBwcmVjaXNpb24gPSAyLjU7XG5cbiAgZnVuY3Rpb24gZ3JhdGljdWxlKCkge1xuICAgIHJldHVybiB7dHlwZTogXCJNdWx0aUxpbmVTdHJpbmdcIiwgY29vcmRpbmF0ZXM6IGxpbmVzKCl9O1xuICB9XG5cbiAgZnVuY3Rpb24gbGluZXMoKSB7XG4gICAgcmV0dXJuIHNlcXVlbmNlKGNlaWwoWDAgLyBEWCkgKiBEWCwgWDEsIERYKS5tYXAoWClcbiAgICAgICAgLmNvbmNhdChzZXF1ZW5jZShjZWlsKFkwIC8gRFkpICogRFksIFkxLCBEWSkubWFwKFkpKVxuICAgICAgICAuY29uY2F0KHNlcXVlbmNlKGNlaWwoeDAgLyBkeCkgKiBkeCwgeDEsIGR4KS5maWx0ZXIoZnVuY3Rpb24oeCkgeyByZXR1cm4gYWJzJDEoeCAlIERYKSA+IGVwc2lsb24kMjsgfSkubWFwKHgpKVxuICAgICAgICAuY29uY2F0KHNlcXVlbmNlKGNlaWwoeTAgLyBkeSkgKiBkeSwgeTEsIGR5KS5maWx0ZXIoZnVuY3Rpb24oeSkgeyByZXR1cm4gYWJzJDEoeSAlIERZKSA+IGVwc2lsb24kMjsgfSkubWFwKHkpKTtcbiAgfVxuXG4gIGdyYXRpY3VsZS5saW5lcyA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBsaW5lcygpLm1hcChmdW5jdGlvbihjb29yZGluYXRlcykgeyByZXR1cm4ge3R5cGU6IFwiTGluZVN0cmluZ1wiLCBjb29yZGluYXRlczogY29vcmRpbmF0ZXN9OyB9KTtcbiAgfTtcblxuICBncmF0aWN1bGUub3V0bGluZSA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBcIlBvbHlnb25cIixcbiAgICAgIGNvb3JkaW5hdGVzOiBbXG4gICAgICAgIFgoWDApLmNvbmNhdChcbiAgICAgICAgWShZMSkuc2xpY2UoMSksXG4gICAgICAgIFgoWDEpLnJldmVyc2UoKS5zbGljZSgxKSxcbiAgICAgICAgWShZMCkucmV2ZXJzZSgpLnNsaWNlKDEpKVxuICAgICAgXVxuICAgIH07XG4gIH07XG5cbiAgZ3JhdGljdWxlLmV4dGVudCA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBncmF0aWN1bGUuZXh0ZW50TWlub3IoKTtcbiAgICByZXR1cm4gZ3JhdGljdWxlLmV4dGVudE1ham9yKF8pLmV4dGVudE1pbm9yKF8pO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5leHRlbnRNYWpvciA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBbW1gwLCBZMF0sIFtYMSwgWTFdXTtcbiAgICBYMCA9ICtfWzBdWzBdLCBYMSA9ICtfWzFdWzBdO1xuICAgIFkwID0gK19bMF1bMV0sIFkxID0gK19bMV1bMV07XG4gICAgaWYgKFgwID4gWDEpIF8gPSBYMCwgWDAgPSBYMSwgWDEgPSBfO1xuICAgIGlmIChZMCA+IFkxKSBfID0gWTAsIFkwID0gWTEsIFkxID0gXztcbiAgICByZXR1cm4gZ3JhdGljdWxlLnByZWNpc2lvbihwcmVjaXNpb24pO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5leHRlbnRNaW5vciA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBbW3gwLCB5MF0sIFt4MSwgeTFdXTtcbiAgICB4MCA9ICtfWzBdWzBdLCB4MSA9ICtfWzFdWzBdO1xuICAgIHkwID0gK19bMF1bMV0sIHkxID0gK19bMV1bMV07XG4gICAgaWYgKHgwID4geDEpIF8gPSB4MCwgeDAgPSB4MSwgeDEgPSBfO1xuICAgIGlmICh5MCA+IHkxKSBfID0geTAsIHkwID0geTEsIHkxID0gXztcbiAgICByZXR1cm4gZ3JhdGljdWxlLnByZWNpc2lvbihwcmVjaXNpb24pO1xuICB9O1xuXG4gIGdyYXRpY3VsZS5zdGVwID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGdyYXRpY3VsZS5zdGVwTWlub3IoKTtcbiAgICByZXR1cm4gZ3JhdGljdWxlLnN0ZXBNYWpvcihfKS5zdGVwTWlub3IoXyk7XG4gIH07XG5cbiAgZ3JhdGljdWxlLnN0ZXBNYWpvciA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBbRFgsIERZXTtcbiAgICBEWCA9ICtfWzBdLCBEWSA9ICtfWzFdO1xuICAgIHJldHVybiBncmF0aWN1bGU7XG4gIH07XG5cbiAgZ3JhdGljdWxlLnN0ZXBNaW5vciA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBbZHgsIGR5XTtcbiAgICBkeCA9ICtfWzBdLCBkeSA9ICtfWzFdO1xuICAgIHJldHVybiBncmF0aWN1bGU7XG4gIH07XG5cbiAgZ3JhdGljdWxlLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBwcmVjaXNpb247XG4gICAgcHJlY2lzaW9uID0gK187XG4gICAgeCA9IGdyYXRpY3VsZVgoeTAsIHkxLCA5MCk7XG4gICAgeSA9IGdyYXRpY3VsZVkoeDAsIHgxLCBwcmVjaXNpb24pO1xuICAgIFggPSBncmF0aWN1bGVYKFkwLCBZMSwgOTApO1xuICAgIFkgPSBncmF0aWN1bGVZKFgwLCBYMSwgcHJlY2lzaW9uKTtcbiAgICByZXR1cm4gZ3JhdGljdWxlO1xuICB9O1xuXG4gIHJldHVybiBncmF0aWN1bGVcbiAgICAgIC5leHRlbnRNYWpvcihbWy0xODAsIC05MCArIGVwc2lsb24kMl0sIFsxODAsIDkwIC0gZXBzaWxvbiQyXV0pXG4gICAgICAuZXh0ZW50TWlub3IoW1stMTgwLCAtODAgLSBlcHNpbG9uJDJdLCBbMTgwLCA4MCArIGVwc2lsb24kMl1dKTtcbn1cblxudmFyIGlkZW50aXR5JDcgPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiB4O1xufTtcblxudmFyIGFyZWFTdW0kMSA9IGFkZGVyKCk7XG52YXIgYXJlYVJpbmdTdW0kMSA9IGFkZGVyKCk7XG52YXIgeDAwO1xudmFyIHkwMDtcbnZhciB4MCQxO1xudmFyIHkwJDE7XG5cbnZhciBhcmVhU3RyZWFtJDEgPSB7XG4gIHBvaW50OiBub29wJDQsXG4gIGxpbmVTdGFydDogbm9vcCQ0LFxuICBsaW5lRW5kOiBub29wJDQsXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgYXJlYVN0cmVhbSQxLmxpbmVTdGFydCA9IGFyZWFSaW5nU3RhcnQkMTtcbiAgICBhcmVhU3RyZWFtJDEubGluZUVuZCA9IGFyZWFSaW5nRW5kJDE7XG4gIH0sXG4gIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGFyZWFTdHJlYW0kMS5saW5lU3RhcnQgPSBhcmVhU3RyZWFtJDEubGluZUVuZCA9IGFyZWFTdHJlYW0kMS5wb2ludCA9IG5vb3AkNDtcbiAgICBhcmVhU3VtJDEuYWRkKGFicyQxKGFyZWFSaW5nU3VtJDEpKTtcbiAgICBhcmVhUmluZ1N1bSQxLnJlc2V0KCk7XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGFyZWEgPSBhcmVhU3VtJDEgLyAyO1xuICAgIGFyZWFTdW0kMS5yZXNldCgpO1xuICAgIHJldHVybiBhcmVhO1xuICB9XG59O1xuXG5mdW5jdGlvbiBhcmVhUmluZ1N0YXJ0JDEoKSB7XG4gIGFyZWFTdHJlYW0kMS5wb2ludCA9IGFyZWFQb2ludEZpcnN0JDE7XG59XG5cbmZ1bmN0aW9uIGFyZWFQb2ludEZpcnN0JDEoeCwgeSkge1xuICBhcmVhU3RyZWFtJDEucG9pbnQgPSBhcmVhUG9pbnQkMTtcbiAgeDAwID0geDAkMSA9IHgsIHkwMCA9IHkwJDEgPSB5O1xufVxuXG5mdW5jdGlvbiBhcmVhUG9pbnQkMSh4LCB5KSB7XG4gIGFyZWFSaW5nU3VtJDEuYWRkKHkwJDEgKiB4IC0geDAkMSAqIHkpO1xuICB4MCQxID0geCwgeTAkMSA9IHk7XG59XG5cbmZ1bmN0aW9uIGFyZWFSaW5nRW5kJDEoKSB7XG4gIGFyZWFQb2ludCQxKHgwMCwgeTAwKTtcbn1cblxudmFyIHgwJDIgPSBJbmZpbml0eTtcbnZhciB5MCQyID0geDAkMjtcbnZhciB4MSA9IC14MCQyO1xudmFyIHkxID0geDE7XG5cbnZhciBib3VuZHNTdHJlYW0kMSA9IHtcbiAgcG9pbnQ6IGJvdW5kc1BvaW50JDEsXG4gIGxpbmVTdGFydDogbm9vcCQ0LFxuICBsaW5lRW5kOiBub29wJDQsXG4gIHBvbHlnb25TdGFydDogbm9vcCQ0LFxuICBwb2x5Z29uRW5kOiBub29wJDQsXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGJvdW5kcyA9IFtbeDAkMiwgeTAkMl0sIFt4MSwgeTFdXTtcbiAgICB4MSA9IHkxID0gLSh5MCQyID0geDAkMiA9IEluZmluaXR5KTtcbiAgICByZXR1cm4gYm91bmRzO1xuICB9XG59O1xuXG5mdW5jdGlvbiBib3VuZHNQb2ludCQxKHgsIHkpIHtcbiAgaWYgKHggPCB4MCQyKSB4MCQyID0geDtcbiAgaWYgKHggPiB4MSkgeDEgPSB4O1xuICBpZiAoeSA8IHkwJDIpIHkwJDIgPSB5O1xuICBpZiAoeSA+IHkxKSB5MSA9IHk7XG59XG5cbi8vIFRPRE8gRW5mb3JjZSBwb3NpdGl2ZSBhcmVhIGZvciBleHRlcmlvciwgbmVnYXRpdmUgYXJlYSBmb3IgaW50ZXJpb3I/XG5cbnZhciBYMCQxID0gMDtcbnZhciBZMCQxID0gMDtcbnZhciBaMCQxID0gMDtcbnZhciBYMSQxID0gMDtcbnZhciBZMSQxID0gMDtcbnZhciBaMSQxID0gMDtcbnZhciBYMiQxID0gMDtcbnZhciBZMiQxID0gMDtcbnZhciBaMiQxID0gMDtcbnZhciB4MDAkMTtcbnZhciB5MDAkMTtcbnZhciB4MCQzO1xudmFyIHkwJDM7XG5cbnZhciBjZW50cm9pZFN0cmVhbSQxID0ge1xuICBwb2ludDogY2VudHJvaWRQb2ludCQxLFxuICBsaW5lU3RhcnQ6IGNlbnRyb2lkTGluZVN0YXJ0JDEsXG4gIGxpbmVFbmQ6IGNlbnRyb2lkTGluZUVuZCQxLFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkge1xuICAgIGNlbnRyb2lkU3RyZWFtJDEubGluZVN0YXJ0ID0gY2VudHJvaWRSaW5nU3RhcnQkMTtcbiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVFbmQgPSBjZW50cm9pZFJpbmdFbmQkMTtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgY2VudHJvaWRTdHJlYW0kMS5wb2ludCA9IGNlbnRyb2lkUG9pbnQkMTtcbiAgICBjZW50cm9pZFN0cmVhbSQxLmxpbmVTdGFydCA9IGNlbnRyb2lkTGluZVN0YXJ0JDE7XG4gICAgY2VudHJvaWRTdHJlYW0kMS5saW5lRW5kID0gY2VudHJvaWRMaW5lRW5kJDE7XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGNlbnRyb2lkID0gWjIkMSA/IFtYMiQxIC8gWjIkMSwgWTIkMSAvIFoyJDFdXG4gICAgICAgIDogWjEkMSA/IFtYMSQxIC8gWjEkMSwgWTEkMSAvIFoxJDFdXG4gICAgICAgIDogWjAkMSA/IFtYMCQxIC8gWjAkMSwgWTAkMSAvIFowJDFdXG4gICAgICAgIDogW05hTiwgTmFOXTtcbiAgICBYMCQxID0gWTAkMSA9IFowJDEgPVxuICAgIFgxJDEgPSBZMSQxID0gWjEkMSA9XG4gICAgWDIkMSA9IFkyJDEgPSBaMiQxID0gMDtcbiAgICByZXR1cm4gY2VudHJvaWQ7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUG9pbnQkMSh4LCB5KSB7XG4gIFgwJDEgKz0geDtcbiAgWTAkMSArPSB5O1xuICArK1owJDE7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkTGluZVN0YXJ0JDEoKSB7XG4gIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50Rmlyc3RMaW5lO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50Rmlyc3RMaW5lKHgsIHkpIHtcbiAgY2VudHJvaWRTdHJlYW0kMS5wb2ludCA9IGNlbnRyb2lkUG9pbnRMaW5lO1xuICBjZW50cm9pZFBvaW50JDEoeDAkMyA9IHgsIHkwJDMgPSB5KTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRQb2ludExpbmUoeCwgeSkge1xuICB2YXIgZHggPSB4IC0geDAkMywgZHkgPSB5IC0geTAkMywgeiA9IHNxcnQkMihkeCAqIGR4ICsgZHkgKiBkeSk7XG4gIFgxJDEgKz0geiAqICh4MCQzICsgeCkgLyAyO1xuICBZMSQxICs9IHogKiAoeTAkMyArIHkpIC8gMjtcbiAgWjEkMSArPSB6O1xuICBjZW50cm9pZFBvaW50JDEoeDAkMyA9IHgsIHkwJDMgPSB5KTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRMaW5lRW5kJDEoKSB7XG4gIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50JDE7XG59XG5cbmZ1bmN0aW9uIGNlbnRyb2lkUmluZ1N0YXJ0JDEoKSB7XG4gIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50Rmlyc3RSaW5nO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFJpbmdFbmQkMSgpIHtcbiAgY2VudHJvaWRQb2ludFJpbmcoeDAwJDEsIHkwMCQxKTtcbn1cblxuZnVuY3Rpb24gY2VudHJvaWRQb2ludEZpcnN0UmluZyh4LCB5KSB7XG4gIGNlbnRyb2lkU3RyZWFtJDEucG9pbnQgPSBjZW50cm9pZFBvaW50UmluZztcbiAgY2VudHJvaWRQb2ludCQxKHgwMCQxID0geDAkMyA9IHgsIHkwMCQxID0geTAkMyA9IHkpO1xufVxuXG5mdW5jdGlvbiBjZW50cm9pZFBvaW50UmluZyh4LCB5KSB7XG4gIHZhciBkeCA9IHggLSB4MCQzLFxuICAgICAgZHkgPSB5IC0geTAkMyxcbiAgICAgIHogPSBzcXJ0JDIoZHggKiBkeCArIGR5ICogZHkpO1xuXG4gIFgxJDEgKz0geiAqICh4MCQzICsgeCkgLyAyO1xuICBZMSQxICs9IHogKiAoeTAkMyArIHkpIC8gMjtcbiAgWjEkMSArPSB6O1xuXG4gIHogPSB5MCQzICogeCAtIHgwJDMgKiB5O1xuICBYMiQxICs9IHogKiAoeDAkMyArIHgpO1xuICBZMiQxICs9IHogKiAoeTAkMyArIHkpO1xuICBaMiQxICs9IHogKiAzO1xuICBjZW50cm9pZFBvaW50JDEoeDAkMyA9IHgsIHkwJDMgPSB5KTtcbn1cblxuZnVuY3Rpb24gUGF0aENvbnRleHQoY29udGV4dCkge1xuICB0aGlzLl9jb250ZXh0ID0gY29udGV4dDtcbn1cblxuUGF0aENvbnRleHQucHJvdG90eXBlID0ge1xuICBfcmFkaXVzOiA0LjUsXG4gIHBvaW50UmFkaXVzOiBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIHRoaXMuX3JhZGl1cyA9IF8sIHRoaXM7XG4gIH0sXG4gIHBvbHlnb25TdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IDA7XG4gIH0sXG4gIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkge1xuICAgIHRoaXMuX2xpbmUgPSBOYU47XG4gIH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fcG9pbnQgPSAwO1xuICB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHtcbiAgICBpZiAodGhpcy5fbGluZSA9PT0gMCkgdGhpcy5fY29udGV4dC5jbG9zZVBhdGgoKTtcbiAgICB0aGlzLl9wb2ludCA9IE5hTjtcbiAgfSxcbiAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICBzd2l0Y2ggKHRoaXMuX3BvaW50KSB7XG4gICAgICBjYXNlIDA6IHtcbiAgICAgICAgdGhpcy5fY29udGV4dC5tb3ZlVG8oeCwgeSk7XG4gICAgICAgIHRoaXMuX3BvaW50ID0gMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIDE6IHtcbiAgICAgICAgdGhpcy5fY29udGV4dC5saW5lVG8oeCwgeSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgZGVmYXVsdDoge1xuICAgICAgICB0aGlzLl9jb250ZXh0Lm1vdmVUbyh4ICsgdGhpcy5fcmFkaXVzLCB5KTtcbiAgICAgICAgdGhpcy5fY29udGV4dC5hcmMoeCwgeSwgdGhpcy5fcmFkaXVzLCAwLCB0YXUkNCk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcmVzdWx0OiBub29wJDRcbn07XG5cbnZhciBsZW5ndGhTdW0kMSA9IGFkZGVyKCk7XG52YXIgbGVuZ3RoUmluZztcbnZhciB4MDAkMjtcbnZhciB5MDAkMjtcbnZhciB4MCQ0O1xudmFyIHkwJDQ7XG5cbnZhciBsZW5ndGhTdHJlYW0kMSA9IHtcbiAgcG9pbnQ6IG5vb3AkNCxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBsZW5ndGhTdHJlYW0kMS5wb2ludCA9IGxlbmd0aFBvaW50Rmlyc3QkMTtcbiAgfSxcbiAgbGluZUVuZDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKGxlbmd0aFJpbmcpIGxlbmd0aFBvaW50JDEoeDAwJDIsIHkwMCQyKTtcbiAgICBsZW5ndGhTdHJlYW0kMS5wb2ludCA9IG5vb3AkNDtcbiAgfSxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICBsZW5ndGhSaW5nID0gdHJ1ZTtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgbGVuZ3RoUmluZyA9IG51bGw7XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGxlbmd0aCA9ICtsZW5ndGhTdW0kMTtcbiAgICBsZW5ndGhTdW0kMS5yZXNldCgpO1xuICAgIHJldHVybiBsZW5ndGg7XG4gIH1cbn07XG5cbmZ1bmN0aW9uIGxlbmd0aFBvaW50Rmlyc3QkMSh4LCB5KSB7XG4gIGxlbmd0aFN0cmVhbSQxLnBvaW50ID0gbGVuZ3RoUG9pbnQkMTtcbiAgeDAwJDIgPSB4MCQ0ID0geCwgeTAwJDIgPSB5MCQ0ID0geTtcbn1cblxuZnVuY3Rpb24gbGVuZ3RoUG9pbnQkMSh4LCB5KSB7XG4gIHgwJDQgLT0geCwgeTAkNCAtPSB5O1xuICBsZW5ndGhTdW0kMS5hZGQoc3FydCQyKHgwJDQgKiB4MCQ0ICsgeTAkNCAqIHkwJDQpKTtcbiAgeDAkNCA9IHgsIHkwJDQgPSB5O1xufVxuXG5mdW5jdGlvbiBQYXRoU3RyaW5nKCkge1xuICB0aGlzLl9zdHJpbmcgPSBbXTtcbn1cblxuUGF0aFN0cmluZy5wcm90b3R5cGUgPSB7XG4gIF9yYWRpdXM6IDQuNSxcbiAgX2NpcmNsZTogY2lyY2xlJDIoNC41KSxcbiAgcG9pbnRSYWRpdXM6IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoKF8gPSArXykgIT09IHRoaXMuX3JhZGl1cykgdGhpcy5fcmFkaXVzID0gXywgdGhpcy5fY2lyY2xlID0gbnVsbDtcbiAgICByZXR1cm4gdGhpcztcbiAgfSxcbiAgcG9seWdvblN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9saW5lID0gMDtcbiAgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7XG4gICAgdGhpcy5fbGluZSA9IE5hTjtcbiAgfSxcbiAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICB0aGlzLl9wb2ludCA9IDA7XG4gIH0sXG4gIGxpbmVFbmQ6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9saW5lID09PSAwKSB0aGlzLl9zdHJpbmcucHVzaChcIlpcIik7XG4gICAgdGhpcy5fcG9pbnQgPSBOYU47XG4gIH0sXG4gIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgc3dpdGNoICh0aGlzLl9wb2ludCkge1xuICAgICAgY2FzZSAwOiB7XG4gICAgICAgIHRoaXMuX3N0cmluZy5wdXNoKFwiTVwiLCB4LCBcIixcIiwgeSk7XG4gICAgICAgIHRoaXMuX3BvaW50ID0gMTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIDE6IHtcbiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goXCJMXCIsIHgsIFwiLFwiLCB5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBkZWZhdWx0OiB7XG4gICAgICAgIGlmICh0aGlzLl9jaXJjbGUgPT0gbnVsbCkgdGhpcy5fY2lyY2xlID0gY2lyY2xlJDIodGhpcy5fcmFkaXVzKTtcbiAgICAgICAgdGhpcy5fc3RyaW5nLnB1c2goXCJNXCIsIHgsIFwiLFwiLCB5LCB0aGlzLl9jaXJjbGUpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH0sXG4gIHJlc3VsdDogZnVuY3Rpb24oKSB7XG4gICAgaWYgKHRoaXMuX3N0cmluZy5sZW5ndGgpIHtcbiAgICAgIHZhciByZXN1bHQgPSB0aGlzLl9zdHJpbmcuam9pbihcIlwiKTtcbiAgICAgIHRoaXMuX3N0cmluZyA9IFtdO1xuICAgICAgcmV0dXJuIHJlc3VsdDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiBjaXJjbGUkMihyYWRpdXMpIHtcbiAgcmV0dXJuIFwibTAsXCIgKyByYWRpdXNcbiAgICAgICsgXCJhXCIgKyByYWRpdXMgKyBcIixcIiArIHJhZGl1cyArIFwiIDAgMSwxIDAsXCIgKyAtMiAqIHJhZGl1c1xuICAgICAgKyBcImFcIiArIHJhZGl1cyArIFwiLFwiICsgcmFkaXVzICsgXCIgMCAxLDEgMCxcIiArIDIgKiByYWRpdXNcbiAgICAgICsgXCJ6XCI7XG59XG5cbnZhciBnZW9QYXRoID0gZnVuY3Rpb24ocHJvamVjdGlvbiwgY29udGV4dCkge1xuICB2YXIgcG9pbnRSYWRpdXMgPSA0LjUsXG4gICAgICBwcm9qZWN0aW9uU3RyZWFtLFxuICAgICAgY29udGV4dFN0cmVhbTtcblxuICBmdW5jdGlvbiBwYXRoKG9iamVjdCkge1xuICAgIGlmIChvYmplY3QpIHtcbiAgICAgIGlmICh0eXBlb2YgcG9pbnRSYWRpdXMgPT09IFwiZnVuY3Rpb25cIikgY29udGV4dFN0cmVhbS5wb2ludFJhZGl1cygrcG9pbnRSYWRpdXMuYXBwbHkodGhpcywgYXJndW1lbnRzKSk7XG4gICAgICBnZW9TdHJlYW0ob2JqZWN0LCBwcm9qZWN0aW9uU3RyZWFtKGNvbnRleHRTdHJlYW0pKTtcbiAgICB9XG4gICAgcmV0dXJuIGNvbnRleHRTdHJlYW0ucmVzdWx0KCk7XG4gIH1cblxuICBwYXRoLmFyZWEgPSBmdW5jdGlvbihvYmplY3QpIHtcbiAgICBnZW9TdHJlYW0ob2JqZWN0LCBwcm9qZWN0aW9uU3RyZWFtKGFyZWFTdHJlYW0kMSkpO1xuICAgIHJldHVybiBhcmVhU3RyZWFtJDEucmVzdWx0KCk7XG4gIH07XG5cbiAgcGF0aC5tZWFzdXJlID0gZnVuY3Rpb24ob2JqZWN0KSB7XG4gICAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvblN0cmVhbShsZW5ndGhTdHJlYW0kMSkpO1xuICAgIHJldHVybiBsZW5ndGhTdHJlYW0kMS5yZXN1bHQoKTtcbiAgfTtcblxuICBwYXRoLmJvdW5kcyA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oYm91bmRzU3RyZWFtJDEpKTtcbiAgICByZXR1cm4gYm91bmRzU3RyZWFtJDEucmVzdWx0KCk7XG4gIH07XG5cbiAgcGF0aC5jZW50cm9pZCA9IGZ1bmN0aW9uKG9iamVjdCkge1xuICAgIGdlb1N0cmVhbShvYmplY3QsIHByb2plY3Rpb25TdHJlYW0oY2VudHJvaWRTdHJlYW0kMSkpO1xuICAgIHJldHVybiBjZW50cm9pZFN0cmVhbSQxLnJlc3VsdCgpO1xuICB9O1xuXG4gIHBhdGgucHJvamVjdGlvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcm9qZWN0aW9uU3RyZWFtID0gXyA9PSBudWxsID8gKHByb2plY3Rpb24gPSBudWxsLCBpZGVudGl0eSQ3KSA6IChwcm9qZWN0aW9uID0gXykuc3RyZWFtLCBwYXRoKSA6IHByb2plY3Rpb247XG4gIH07XG5cbiAgcGF0aC5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGNvbnRleHQ7XG4gICAgY29udGV4dFN0cmVhbSA9IF8gPT0gbnVsbCA/IChjb250ZXh0ID0gbnVsbCwgbmV3IFBhdGhTdHJpbmcpIDogbmV3IFBhdGhDb250ZXh0KGNvbnRleHQgPSBfKTtcbiAgICBpZiAodHlwZW9mIHBvaW50UmFkaXVzICE9PSBcImZ1bmN0aW9uXCIpIGNvbnRleHRTdHJlYW0ucG9pbnRSYWRpdXMocG9pbnRSYWRpdXMpO1xuICAgIHJldHVybiBwYXRoO1xuICB9O1xuXG4gIHBhdGgucG9pbnRSYWRpdXMgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gcG9pbnRSYWRpdXM7XG4gICAgcG9pbnRSYWRpdXMgPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IChjb250ZXh0U3RyZWFtLnBvaW50UmFkaXVzKCtfKSwgK18pO1xuICAgIHJldHVybiBwYXRoO1xuICB9O1xuXG4gIHJldHVybiBwYXRoLnByb2plY3Rpb24ocHJvamVjdGlvbikuY29udGV4dChjb250ZXh0KTtcbn07XG5cbmZ1bmN0aW9uIHRyYW5zZm9ybWVyKG1ldGhvZHMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHZhciBzID0gbmV3IFRyYW5zZm9ybVN0cmVhbTtcbiAgICBmb3IgKHZhciBrZXkgaW4gbWV0aG9kcykgc1trZXldID0gbWV0aG9kc1trZXldO1xuICAgIHMuc3RyZWFtID0gc3RyZWFtO1xuICAgIHJldHVybiBzO1xuICB9O1xufVxuXG5mdW5jdGlvbiBUcmFuc2Zvcm1TdHJlYW0oKSB7fVxuXG5UcmFuc2Zvcm1TdHJlYW0ucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogVHJhbnNmb3JtU3RyZWFtLFxuICBwb2ludDogZnVuY3Rpb24oeCwgeSkgeyB0aGlzLnN0cmVhbS5wb2ludCh4LCB5KTsgfSxcbiAgc3BoZXJlOiBmdW5jdGlvbigpIHsgdGhpcy5zdHJlYW0uc3BoZXJlKCk7IH0sXG4gIGxpbmVTdGFydDogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLmxpbmVTdGFydCgpOyB9LFxuICBsaW5lRW5kOiBmdW5jdGlvbigpIHsgdGhpcy5zdHJlYW0ubGluZUVuZCgpOyB9LFxuICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgeyB0aGlzLnN0cmVhbS5wb2x5Z29uU3RhcnQoKTsgfSxcbiAgcG9seWdvbkVuZDogZnVuY3Rpb24oKSB7IHRoaXMuc3RyZWFtLnBvbHlnb25FbmQoKTsgfVxufTtcblxuZnVuY3Rpb24gZml0KHByb2plY3Rpb24sIGZpdEJvdW5kcywgb2JqZWN0KSB7XG4gIHZhciBjbGlwID0gcHJvamVjdGlvbi5jbGlwRXh0ZW50ICYmIHByb2plY3Rpb24uY2xpcEV4dGVudCgpO1xuICBwcm9qZWN0aW9uLnNjYWxlKDE1MCkudHJhbnNsYXRlKFswLCAwXSk7XG4gIGlmIChjbGlwICE9IG51bGwpIHByb2plY3Rpb24uY2xpcEV4dGVudChudWxsKTtcbiAgZ2VvU3RyZWFtKG9iamVjdCwgcHJvamVjdGlvbi5zdHJlYW0oYm91bmRzU3RyZWFtJDEpKTtcbiAgZml0Qm91bmRzKGJvdW5kc1N0cmVhbSQxLnJlc3VsdCgpKTtcbiAgaWYgKGNsaXAgIT0gbnVsbCkgcHJvamVjdGlvbi5jbGlwRXh0ZW50KGNsaXApO1xuICByZXR1cm4gcHJvamVjdGlvbjtcbn1cblxuZnVuY3Rpb24gZml0RXh0ZW50KHByb2plY3Rpb24sIGV4dGVudCwgb2JqZWN0KSB7XG4gIHJldHVybiBmaXQocHJvamVjdGlvbiwgZnVuY3Rpb24oYikge1xuICAgIHZhciB3ID0gZXh0ZW50WzFdWzBdIC0gZXh0ZW50WzBdWzBdLFxuICAgICAgICBoID0gZXh0ZW50WzFdWzFdIC0gZXh0ZW50WzBdWzFdLFxuICAgICAgICBrID0gTWF0aC5taW4odyAvIChiWzFdWzBdIC0gYlswXVswXSksIGggLyAoYlsxXVsxXSAtIGJbMF1bMV0pKSxcbiAgICAgICAgeCA9ICtleHRlbnRbMF1bMF0gKyAodyAtIGsgKiAoYlsxXVswXSArIGJbMF1bMF0pKSAvIDIsXG4gICAgICAgIHkgPSArZXh0ZW50WzBdWzFdICsgKGggLSBrICogKGJbMV1bMV0gKyBiWzBdWzFdKSkgLyAyO1xuICAgIHByb2plY3Rpb24uc2NhbGUoMTUwICogaykudHJhbnNsYXRlKFt4LCB5XSk7XG4gIH0sIG9iamVjdCk7XG59XG5cbmZ1bmN0aW9uIGZpdFNpemUocHJvamVjdGlvbiwgc2l6ZSwgb2JqZWN0KSB7XG4gIHJldHVybiBmaXRFeHRlbnQocHJvamVjdGlvbiwgW1swLCAwXSwgc2l6ZV0sIG9iamVjdCk7XG59XG5cbmZ1bmN0aW9uIGZpdFdpZHRoKHByb2plY3Rpb24sIHdpZHRoLCBvYmplY3QpIHtcbiAgcmV0dXJuIGZpdChwcm9qZWN0aW9uLCBmdW5jdGlvbihiKSB7XG4gICAgdmFyIHcgPSArd2lkdGgsXG4gICAgICAgIGsgPSB3IC8gKGJbMV1bMF0gLSBiWzBdWzBdKSxcbiAgICAgICAgeCA9ICh3IC0gayAqIChiWzFdWzBdICsgYlswXVswXSkpIC8gMixcbiAgICAgICAgeSA9IC1rICogYlswXVsxXTtcbiAgICBwcm9qZWN0aW9uLnNjYWxlKDE1MCAqIGspLnRyYW5zbGF0ZShbeCwgeV0pO1xuICB9LCBvYmplY3QpO1xufVxuXG5mdW5jdGlvbiBmaXRIZWlnaHQocHJvamVjdGlvbiwgaGVpZ2h0LCBvYmplY3QpIHtcbiAgcmV0dXJuIGZpdChwcm9qZWN0aW9uLCBmdW5jdGlvbihiKSB7XG4gICAgdmFyIGggPSAraGVpZ2h0LFxuICAgICAgICBrID0gaCAvIChiWzFdWzFdIC0gYlswXVsxXSksXG4gICAgICAgIHggPSAtayAqIGJbMF1bMF0sXG4gICAgICAgIHkgPSAoaCAtIGsgKiAoYlsxXVsxXSArIGJbMF1bMV0pKSAvIDI7XG4gICAgcHJvamVjdGlvbi5zY2FsZSgxNTAgKiBrKS50cmFuc2xhdGUoW3gsIHldKTtcbiAgfSwgb2JqZWN0KTtcbn1cblxudmFyIG1heERlcHRoID0gMTY7XG52YXIgY29zTWluRGlzdGFuY2UgPSBjb3MkMSgzMCAqIHJhZGlhbnMpOyAvLyBjb3MobWluaW11bSBhbmd1bGFyIGRpc3RhbmNlKVxuXG52YXIgcmVzYW1wbGUgPSBmdW5jdGlvbihwcm9qZWN0LCBkZWx0YTIpIHtcbiAgcmV0dXJuICtkZWx0YTIgPyByZXNhbXBsZSQxKHByb2plY3QsIGRlbHRhMikgOiByZXNhbXBsZU5vbmUocHJvamVjdCk7XG59O1xuXG5mdW5jdGlvbiByZXNhbXBsZU5vbmUocHJvamVjdCkge1xuICByZXR1cm4gdHJhbnNmb3JtZXIoe1xuICAgIHBvaW50OiBmdW5jdGlvbih4LCB5KSB7XG4gICAgICB4ID0gcHJvamVjdCh4LCB5KTtcbiAgICAgIHRoaXMuc3RyZWFtLnBvaW50KHhbMF0sIHhbMV0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHJlc2FtcGxlJDEocHJvamVjdCwgZGVsdGEyKSB7XG5cbiAgZnVuY3Rpb24gcmVzYW1wbGVMaW5lVG8oeDAsIHkwLCBsYW1iZGEwLCBhMCwgYjAsIGMwLCB4MSwgeTEsIGxhbWJkYTEsIGExLCBiMSwgYzEsIGRlcHRoLCBzdHJlYW0pIHtcbiAgICB2YXIgZHggPSB4MSAtIHgwLFxuICAgICAgICBkeSA9IHkxIC0geTAsXG4gICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgaWYgKGQyID4gNCAqIGRlbHRhMiAmJiBkZXB0aC0tKSB7XG4gICAgICB2YXIgYSA9IGEwICsgYTEsXG4gICAgICAgICAgYiA9IGIwICsgYjEsXG4gICAgICAgICAgYyA9IGMwICsgYzEsXG4gICAgICAgICAgbSA9IHNxcnQkMihhICogYSArIGIgKiBiICsgYyAqIGMpLFxuICAgICAgICAgIHBoaTIgPSBhc2luJDEoYyAvPSBtKSxcbiAgICAgICAgICBsYW1iZGEyID0gYWJzJDEoYWJzJDEoYykgLSAxKSA8IGVwc2lsb24kMiB8fCBhYnMkMShsYW1iZGEwIC0gbGFtYmRhMSkgPCBlcHNpbG9uJDIgPyAobGFtYmRhMCArIGxhbWJkYTEpIC8gMiA6IGF0YW4yJDEoYiwgYSksXG4gICAgICAgICAgcCA9IHByb2plY3QobGFtYmRhMiwgcGhpMiksXG4gICAgICAgICAgeDIgPSBwWzBdLFxuICAgICAgICAgIHkyID0gcFsxXSxcbiAgICAgICAgICBkeDIgPSB4MiAtIHgwLFxuICAgICAgICAgIGR5MiA9IHkyIC0geTAsXG4gICAgICAgICAgZHogPSBkeSAqIGR4MiAtIGR4ICogZHkyO1xuICAgICAgaWYgKGR6ICogZHogLyBkMiA+IGRlbHRhMiAvLyBwZXJwZW5kaWN1bGFyIHByb2plY3RlZCBkaXN0YW5jZVxuICAgICAgICAgIHx8IGFicyQxKChkeCAqIGR4MiArIGR5ICogZHkyKSAvIGQyIC0gMC41KSA+IDAuMyAvLyBtaWRwb2ludCBjbG9zZSB0byBhbiBlbmRcbiAgICAgICAgICB8fCBhMCAqIGExICsgYjAgKiBiMSArIGMwICogYzEgPCBjb3NNaW5EaXN0YW5jZSkgeyAvLyBhbmd1bGFyIGRpc3RhbmNlXG4gICAgICAgIHJlc2FtcGxlTGluZVRvKHgwLCB5MCwgbGFtYmRhMCwgYTAsIGIwLCBjMCwgeDIsIHkyLCBsYW1iZGEyLCBhIC89IG0sIGIgLz0gbSwgYywgZGVwdGgsIHN0cmVhbSk7XG4gICAgICAgIHN0cmVhbS5wb2ludCh4MiwgeTIpO1xuICAgICAgICByZXNhbXBsZUxpbmVUbyh4MiwgeTIsIGxhbWJkYTIsIGEsIGIsIGMsIHgxLCB5MSwgbGFtYmRhMSwgYTEsIGIxLCBjMSwgZGVwdGgsIHN0cmVhbSk7XG4gICAgICB9XG4gICAgfVxuICB9XG4gIHJldHVybiBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICB2YXIgbGFtYmRhMDAsIHgwMCwgeTAwLCBhMDAsIGIwMCwgYzAwLCAvLyBmaXJzdCBwb2ludFxuICAgICAgICBsYW1iZGEwLCB4MCwgeTAsIGEwLCBiMCwgYzA7IC8vIHByZXZpb3VzIHBvaW50XG5cbiAgICB2YXIgcmVzYW1wbGVTdHJlYW0gPSB7XG4gICAgICBwb2ludDogcG9pbnQsXG4gICAgICBsaW5lU3RhcnQ6IGxpbmVTdGFydCxcbiAgICAgIGxpbmVFbmQ6IGxpbmVFbmQsXG4gICAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgeyBzdHJlYW0ucG9seWdvblN0YXJ0KCk7IHJlc2FtcGxlU3RyZWFtLmxpbmVTdGFydCA9IHJpbmdTdGFydDsgfSxcbiAgICAgIHBvbHlnb25FbmQ6IGZ1bmN0aW9uKCkgeyBzdHJlYW0ucG9seWdvbkVuZCgpOyByZXNhbXBsZVN0cmVhbS5saW5lU3RhcnQgPSBsaW5lU3RhcnQ7IH1cbiAgICB9O1xuXG4gICAgZnVuY3Rpb24gcG9pbnQoeCwgeSkge1xuICAgICAgeCA9IHByb2plY3QoeCwgeSk7XG4gICAgICBzdHJlYW0ucG9pbnQoeFswXSwgeFsxXSk7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gbGluZVN0YXJ0KCkge1xuICAgICAgeDAgPSBOYU47XG4gICAgICByZXNhbXBsZVN0cmVhbS5wb2ludCA9IGxpbmVQb2ludDtcbiAgICAgIHN0cmVhbS5saW5lU3RhcnQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiBsaW5lUG9pbnQobGFtYmRhLCBwaGkpIHtcbiAgICAgIHZhciBjID0gY2FydGVzaWFuKFtsYW1iZGEsIHBoaV0pLCBwID0gcHJvamVjdChsYW1iZGEsIHBoaSk7XG4gICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIGxhbWJkYTAsIGEwLCBiMCwgYzAsIHgwID0gcFswXSwgeTAgPSBwWzFdLCBsYW1iZGEwID0gbGFtYmRhLCBhMCA9IGNbMF0sIGIwID0gY1sxXSwgYzAgPSBjWzJdLCBtYXhEZXB0aCwgc3RyZWFtKTtcbiAgICAgIHN0cmVhbS5wb2ludCh4MCwgeTApO1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIGxpbmVFbmQoKSB7XG4gICAgICByZXNhbXBsZVN0cmVhbS5wb2ludCA9IHBvaW50O1xuICAgICAgc3RyZWFtLmxpbmVFbmQoKTtcbiAgICB9XG5cbiAgICBmdW5jdGlvbiByaW5nU3RhcnQoKSB7XG4gICAgICBsaW5lU3RhcnQoKTtcbiAgICAgIHJlc2FtcGxlU3RyZWFtLnBvaW50ID0gcmluZ1BvaW50O1xuICAgICAgcmVzYW1wbGVTdHJlYW0ubGluZUVuZCA9IHJpbmdFbmQ7XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gcmluZ1BvaW50KGxhbWJkYSwgcGhpKSB7XG4gICAgICBsaW5lUG9pbnQobGFtYmRhMDAgPSBsYW1iZGEsIHBoaSksIHgwMCA9IHgwLCB5MDAgPSB5MCwgYTAwID0gYTAsIGIwMCA9IGIwLCBjMDAgPSBjMDtcbiAgICAgIHJlc2FtcGxlU3RyZWFtLnBvaW50ID0gbGluZVBvaW50O1xuICAgIH1cblxuICAgIGZ1bmN0aW9uIHJpbmdFbmQoKSB7XG4gICAgICByZXNhbXBsZUxpbmVUbyh4MCwgeTAsIGxhbWJkYTAsIGEwLCBiMCwgYzAsIHgwMCwgeTAwLCBsYW1iZGEwMCwgYTAwLCBiMDAsIGMwMCwgbWF4RGVwdGgsIHN0cmVhbSk7XG4gICAgICByZXNhbXBsZVN0cmVhbS5saW5lRW5kID0gbGluZUVuZDtcbiAgICAgIGxpbmVFbmQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gcmVzYW1wbGVTdHJlYW07XG4gIH07XG59XG5cbnZhciB0cmFuc2Zvcm1SYWRpYW5zID0gdHJhbnNmb3JtZXIoe1xuICBwb2ludDogZnVuY3Rpb24oeCwgeSkge1xuICAgIHRoaXMuc3RyZWFtLnBvaW50KHggKiByYWRpYW5zLCB5ICogcmFkaWFucyk7XG4gIH1cbn0pO1xuXG5mdW5jdGlvbiB0cmFuc2Zvcm1Sb3RhdGUocm90YXRlKSB7XG4gIHJldHVybiB0cmFuc2Zvcm1lcih7XG4gICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICAgIHZhciByID0gcm90YXRlKHgsIHkpO1xuICAgICAgcmV0dXJuIHRoaXMuc3RyZWFtLnBvaW50KHJbMF0sIHJbMV0pO1xuICAgIH1cbiAgfSk7XG59XG5cbmZ1bmN0aW9uIHByb2plY3Rpb24kMShwcm9qZWN0KSB7XG4gIHJldHVybiBwcm9qZWN0aW9uTXV0YXRvcihmdW5jdGlvbigpIHsgcmV0dXJuIHByb2plY3Q7IH0pKCk7XG59XG5cbmZ1bmN0aW9uIHByb2plY3Rpb25NdXRhdG9yKHByb2plY3RBdCkge1xuICB2YXIgcHJvamVjdCxcbiAgICAgIGsgPSAxNTAsIC8vIHNjYWxlXG4gICAgICB4ID0gNDgwLCB5ID0gMjUwLCAvLyB0cmFuc2xhdGVcbiAgICAgIGR4LCBkeSwgbGFtYmRhID0gMCwgcGhpID0gMCwgLy8gY2VudGVyXG4gICAgICBkZWx0YUxhbWJkYSA9IDAsIGRlbHRhUGhpID0gMCwgZGVsdGFHYW1tYSA9IDAsIHJvdGF0ZSwgcHJvamVjdFJvdGF0ZSwgLy8gcm90YXRlXG4gICAgICB0aGV0YSA9IG51bGwsIHByZWNsaXAgPSBjbGlwQW50aW1lcmlkaWFuLCAvLyBjbGlwIGFuZ2xlXG4gICAgICB4MCA9IG51bGwsIHkwLCB4MSwgeTEsIHBvc3RjbGlwID0gaWRlbnRpdHkkNywgLy8gY2xpcCBleHRlbnRcbiAgICAgIGRlbHRhMiA9IDAuNSwgcHJvamVjdFJlc2FtcGxlID0gcmVzYW1wbGUocHJvamVjdFRyYW5zZm9ybSwgZGVsdGEyKSwgLy8gcHJlY2lzaW9uXG4gICAgICBjYWNoZSxcbiAgICAgIGNhY2hlU3RyZWFtO1xuXG4gIGZ1bmN0aW9uIHByb2plY3Rpb24ocG9pbnQpIHtcbiAgICBwb2ludCA9IHByb2plY3RSb3RhdGUocG9pbnRbMF0gKiByYWRpYW5zLCBwb2ludFsxXSAqIHJhZGlhbnMpO1xuICAgIHJldHVybiBbcG9pbnRbMF0gKiBrICsgZHgsIGR5IC0gcG9pbnRbMV0gKiBrXTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGludmVydChwb2ludCkge1xuICAgIHBvaW50ID0gcHJvamVjdFJvdGF0ZS5pbnZlcnQoKHBvaW50WzBdIC0gZHgpIC8gaywgKGR5IC0gcG9pbnRbMV0pIC8gayk7XG4gICAgcmV0dXJuIHBvaW50ICYmIFtwb2ludFswXSAqIGRlZ3JlZXMkMSwgcG9pbnRbMV0gKiBkZWdyZWVzJDFdO1xuICB9XG5cbiAgZnVuY3Rpb24gcHJvamVjdFRyYW5zZm9ybSh4LCB5KSB7XG4gICAgcmV0dXJuIHggPSBwcm9qZWN0KHgsIHkpLCBbeFswXSAqIGsgKyBkeCwgZHkgLSB4WzFdICoga107XG4gIH1cblxuICBwcm9qZWN0aW9uLnN0cmVhbSA9IGZ1bmN0aW9uKHN0cmVhbSkge1xuICAgIHJldHVybiBjYWNoZSAmJiBjYWNoZVN0cmVhbSA9PT0gc3RyZWFtID8gY2FjaGUgOiBjYWNoZSA9IHRyYW5zZm9ybVJhZGlhbnModHJhbnNmb3JtUm90YXRlKHJvdGF0ZSkocHJlY2xpcChwcm9qZWN0UmVzYW1wbGUocG9zdGNsaXAoY2FjaGVTdHJlYW0gPSBzdHJlYW0pKSkpKTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLnByZWNsaXAgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocHJlY2xpcCA9IF8sIHRoZXRhID0gdW5kZWZpbmVkLCByZXNldCgpKSA6IHByZWNsaXA7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5wb3N0Y2xpcCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwb3N0Y2xpcCA9IF8sIHgwID0geTAgPSB4MSA9IHkxID0gbnVsbCwgcmVzZXQoKSkgOiBwb3N0Y2xpcDtcbiAgfTtcblxuICBwcm9qZWN0aW9uLmNsaXBBbmdsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcmVjbGlwID0gK18gPyBjbGlwQ2lyY2xlKHRoZXRhID0gXyAqIHJhZGlhbnMpIDogKHRoZXRhID0gbnVsbCwgY2xpcEFudGltZXJpZGlhbiksIHJlc2V0KCkpIDogdGhldGEgKiBkZWdyZWVzJDE7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5jbGlwRXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBvc3RjbGlwID0gXyA9PSBudWxsID8gKHgwID0geTAgPSB4MSA9IHkxID0gbnVsbCwgaWRlbnRpdHkkNykgOiBjbGlwUmVjdGFuZ2xlKHgwID0gK19bMF1bMF0sIHkwID0gK19bMF1bMV0sIHgxID0gK19bMV1bMF0sIHkxID0gK19bMV1bMV0pLCByZXNldCgpKSA6IHgwID09IG51bGwgPyBudWxsIDogW1t4MCwgeTBdLCBbeDEsIHkxXV07XG4gIH07XG5cbiAgcHJvamVjdGlvbi5zY2FsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChrID0gK18sIHJlY2VudGVyKCkpIDogaztcbiAgfTtcblxuICBwcm9qZWN0aW9uLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gK19bMF0sIHkgPSArX1sxXSwgcmVjZW50ZXIoKSkgOiBbeCwgeV07XG4gIH07XG5cbiAgcHJvamVjdGlvbi5jZW50ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAobGFtYmRhID0gX1swXSAlIDM2MCAqIHJhZGlhbnMsIHBoaSA9IF9bMV0gJSAzNjAgKiByYWRpYW5zLCByZWNlbnRlcigpKSA6IFtsYW1iZGEgKiBkZWdyZWVzJDEsIHBoaSAqIGRlZ3JlZXMkMV07XG4gIH07XG5cbiAgcHJvamVjdGlvbi5yb3RhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZGVsdGFMYW1iZGEgPSBfWzBdICUgMzYwICogcmFkaWFucywgZGVsdGFQaGkgPSBfWzFdICUgMzYwICogcmFkaWFucywgZGVsdGFHYW1tYSA9IF8ubGVuZ3RoID4gMiA/IF9bMl0gJSAzNjAgKiByYWRpYW5zIDogMCwgcmVjZW50ZXIoKSkgOiBbZGVsdGFMYW1iZGEgKiBkZWdyZWVzJDEsIGRlbHRhUGhpICogZGVncmVlcyQxLCBkZWx0YUdhbW1hICogZGVncmVlcyQxXTtcbiAgfTtcblxuICBwcm9qZWN0aW9uLnByZWNpc2lvbiA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwcm9qZWN0UmVzYW1wbGUgPSByZXNhbXBsZShwcm9qZWN0VHJhbnNmb3JtLCBkZWx0YTIgPSBfICogXyksIHJlc2V0KCkpIDogc3FydCQyKGRlbHRhMik7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5maXRFeHRlbnQgPSBmdW5jdGlvbihleHRlbnQsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRFeHRlbnQocHJvamVjdGlvbiwgZXh0ZW50LCBvYmplY3QpO1xuICB9O1xuXG4gIHByb2plY3Rpb24uZml0U2l6ZSA9IGZ1bmN0aW9uKHNpemUsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRTaXplKHByb2plY3Rpb24sIHNpemUsIG9iamVjdCk7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5maXRXaWR0aCA9IGZ1bmN0aW9uKHdpZHRoLCBvYmplY3QpIHtcbiAgICByZXR1cm4gZml0V2lkdGgocHJvamVjdGlvbiwgd2lkdGgsIG9iamVjdCk7XG4gIH07XG5cbiAgcHJvamVjdGlvbi5maXRIZWlnaHQgPSBmdW5jdGlvbihoZWlnaHQsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRIZWlnaHQocHJvamVjdGlvbiwgaGVpZ2h0LCBvYmplY3QpO1xuICB9O1xuXG4gIGZ1bmN0aW9uIHJlY2VudGVyKCkge1xuICAgIHByb2plY3RSb3RhdGUgPSBjb21wb3NlKHJvdGF0ZSA9IHJvdGF0ZVJhZGlhbnMoZGVsdGFMYW1iZGEsIGRlbHRhUGhpLCBkZWx0YUdhbW1hKSwgcHJvamVjdCk7XG4gICAgdmFyIGNlbnRlciA9IHByb2plY3QobGFtYmRhLCBwaGkpO1xuICAgIGR4ID0geCAtIGNlbnRlclswXSAqIGs7XG4gICAgZHkgPSB5ICsgY2VudGVyWzFdICogaztcbiAgICByZXR1cm4gcmVzZXQoKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlc2V0KCkge1xuICAgIGNhY2hlID0gY2FjaGVTdHJlYW0gPSBudWxsO1xuICAgIHJldHVybiBwcm9qZWN0aW9uO1xuICB9XG5cbiAgcmV0dXJuIGZ1bmN0aW9uKCkge1xuICAgIHByb2plY3QgPSBwcm9qZWN0QXQuYXBwbHkodGhpcywgYXJndW1lbnRzKTtcbiAgICBwcm9qZWN0aW9uLmludmVydCA9IHByb2plY3QuaW52ZXJ0ICYmIGludmVydDtcbiAgICByZXR1cm4gcmVjZW50ZXIoKTtcbiAgfTtcbn1cblxuZnVuY3Rpb24gY29uaWNQcm9qZWN0aW9uKHByb2plY3RBdCkge1xuICB2YXIgcGhpMCA9IDAsXG4gICAgICBwaGkxID0gcGkkMyAvIDMsXG4gICAgICBtID0gcHJvamVjdGlvbk11dGF0b3IocHJvamVjdEF0KSxcbiAgICAgIHAgPSBtKHBoaTAsIHBoaTEpO1xuXG4gIHAucGFyYWxsZWxzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gbShwaGkwID0gX1swXSAqIHJhZGlhbnMsIHBoaTEgPSBfWzFdICogcmFkaWFucykgOiBbcGhpMCAqIGRlZ3JlZXMkMSwgcGhpMSAqIGRlZ3JlZXMkMV07XG4gIH07XG5cbiAgcmV0dXJuIHA7XG59XG5cbmZ1bmN0aW9uIGN5bGluZHJpY2FsRXF1YWxBcmVhUmF3KHBoaTApIHtcbiAgdmFyIGNvc1BoaTAgPSBjb3MkMShwaGkwKTtcblxuICBmdW5jdGlvbiBmb3J3YXJkKGxhbWJkYSwgcGhpKSB7XG4gICAgcmV0dXJuIFtsYW1iZGEgKiBjb3NQaGkwLCBzaW4kMShwaGkpIC8gY29zUGhpMF07XG4gIH1cblxuICBmb3J3YXJkLmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgICByZXR1cm4gW3ggLyBjb3NQaGkwLCBhc2luJDEoeSAqIGNvc1BoaTApXTtcbiAgfTtcblxuICByZXR1cm4gZm9yd2FyZDtcbn1cblxuZnVuY3Rpb24gY29uaWNFcXVhbEFyZWFSYXcoeTAsIHkxKSB7XG4gIHZhciBzeTAgPSBzaW4kMSh5MCksIG4gPSAoc3kwICsgc2luJDEoeTEpKSAvIDI7XG5cbiAgLy8gQXJlIHRoZSBwYXJhbGxlbHMgc3ltbWV0cmljYWwgYXJvdW5kIHRoZSBFcXVhdG9yP1xuICBpZiAoYWJzJDEobikgPCBlcHNpbG9uJDIpIHJldHVybiBjeWxpbmRyaWNhbEVxdWFsQXJlYVJhdyh5MCk7XG5cbiAgdmFyIGMgPSAxICsgc3kwICogKDIgKiBuIC0gc3kwKSwgcjAgPSBzcXJ0JDIoYykgLyBuO1xuXG4gIGZ1bmN0aW9uIHByb2plY3QoeCwgeSkge1xuICAgIHZhciByID0gc3FydCQyKGMgLSAyICogbiAqIHNpbiQxKHkpKSAvIG47XG4gICAgcmV0dXJuIFtyICogc2luJDEoeCAqPSBuKSwgcjAgLSByICogY29zJDEoeCldO1xuICB9XG5cbiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIHIweSA9IHIwIC0geTtcbiAgICByZXR1cm4gW2F0YW4yJDEoeCwgYWJzJDEocjB5KSkgLyBuICogc2lnbiQxKHIweSksIGFzaW4kMSgoYyAtICh4ICogeCArIHIweSAqIHIweSkgKiBuICogbikgLyAoMiAqIG4pKV07XG4gIH07XG5cbiAgcmV0dXJuIHByb2plY3Q7XG59XG5cbnZhciBjb25pY0VxdWFsQXJlYSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY29uaWNQcm9qZWN0aW9uKGNvbmljRXF1YWxBcmVhUmF3KVxuICAgICAgLnNjYWxlKDE1NS40MjQpXG4gICAgICAuY2VudGVyKFswLCAzMy42NDQyXSk7XG59O1xuXG52YXIgYWxiZXJzID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBjb25pY0VxdWFsQXJlYSgpXG4gICAgICAucGFyYWxsZWxzKFsyOS41LCA0NS41XSlcbiAgICAgIC5zY2FsZSgxMDcwKVxuICAgICAgLnRyYW5zbGF0ZShbNDgwLCAyNTBdKVxuICAgICAgLnJvdGF0ZShbOTYsIDBdKVxuICAgICAgLmNlbnRlcihbLTAuNiwgMzguN10pO1xufTtcblxuLy8gVGhlIHByb2plY3Rpb25zIG11c3QgaGF2ZSBtdXR1YWxseSBleGNsdXNpdmUgY2xpcCByZWdpb25zIG9uIHRoZSBzcGhlcmUsXG4vLyBhcyB0aGlzIHdpbGwgYXZvaWQgZW1pdHRpbmcgaW50ZXJsZWF2aW5nIGxpbmVzIGFuZCBwb2x5Z29ucy5cbmZ1bmN0aW9uIG11bHRpcGxleChzdHJlYW1zKSB7XG4gIHZhciBuID0gc3RyZWFtcy5sZW5ndGg7XG4gIHJldHVybiB7XG4gICAgcG9pbnQ6IGZ1bmN0aW9uKHgsIHkpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ucG9pbnQoeCwgeSk7IH0sXG4gICAgc3BoZXJlOiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0uc3BoZXJlKCk7IH0sXG4gICAgbGluZVN0YXJ0OiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ubGluZVN0YXJ0KCk7IH0sXG4gICAgbGluZUVuZDogZnVuY3Rpb24oKSB7IHZhciBpID0gLTE7IHdoaWxlICgrK2kgPCBuKSBzdHJlYW1zW2ldLmxpbmVFbmQoKTsgfSxcbiAgICBwb2x5Z29uU3RhcnQ6IGZ1bmN0aW9uKCkgeyB2YXIgaSA9IC0xOyB3aGlsZSAoKytpIDwgbikgc3RyZWFtc1tpXS5wb2x5Z29uU3RhcnQoKTsgfSxcbiAgICBwb2x5Z29uRW5kOiBmdW5jdGlvbigpIHsgdmFyIGkgPSAtMTsgd2hpbGUgKCsraSA8IG4pIHN0cmVhbXNbaV0ucG9seWdvbkVuZCgpOyB9XG4gIH07XG59XG5cbi8vIEEgY29tcG9zaXRlIHByb2plY3Rpb24gZm9yIHRoZSBVbml0ZWQgU3RhdGVzLCBjb25maWd1cmVkIGJ5IGRlZmF1bHQgZm9yXG4vLyA5NjDDlzUwMC4gVGhlIHByb2plY3Rpb24gYWxzbyB3b3JrcyBxdWl0ZSB3ZWxsIGF0IDk2MMOXNjAwIGlmIHlvdSBjaGFuZ2UgdGhlXG4vLyBzY2FsZSB0byAxMjg1IGFuZCBhZGp1c3QgdGhlIHRyYW5zbGF0ZSBhY2NvcmRpbmdseS4gVGhlIHNldCBvZiBzdGFuZGFyZFxuLy8gcGFyYWxsZWxzIGZvciBlYWNoIHJlZ2lvbiBjb21lcyBmcm9tIFVTR1MsIHdoaWNoIGlzIHB1Ymxpc2hlZCBoZXJlOlxuLy8gaHR0cDovL2Vnc2MudXNncy5nb3YvaXNiL3B1YnMvTWFwUHJvamVjdGlvbnMvcHJvamVjdGlvbnMuaHRtbCNhbGJlcnNcbnZhciBnZW9BbGJlcnNVc2EgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNhY2hlLFxuICAgICAgY2FjaGVTdHJlYW0sXG4gICAgICBsb3dlcjQ4ID0gYWxiZXJzKCksIGxvd2VyNDhQb2ludCxcbiAgICAgIGFsYXNrYSA9IGNvbmljRXF1YWxBcmVhKCkucm90YXRlKFsxNTQsIDBdKS5jZW50ZXIoWy0yLCA1OC41XSkucGFyYWxsZWxzKFs1NSwgNjVdKSwgYWxhc2thUG9pbnQsIC8vIEVQU0c6MzMzOFxuICAgICAgaGF3YWlpID0gY29uaWNFcXVhbEFyZWEoKS5yb3RhdGUoWzE1NywgMF0pLmNlbnRlcihbLTMsIDE5LjldKS5wYXJhbGxlbHMoWzgsIDE4XSksIGhhd2FpaVBvaW50LCAvLyBFU1JJOjEwMjAwN1xuICAgICAgcG9pbnQsIHBvaW50U3RyZWFtID0ge3BvaW50OiBmdW5jdGlvbih4LCB5KSB7IHBvaW50ID0gW3gsIHldOyB9fTtcblxuICBmdW5jdGlvbiBhbGJlcnNVc2EoY29vcmRpbmF0ZXMpIHtcbiAgICB2YXIgeCA9IGNvb3JkaW5hdGVzWzBdLCB5ID0gY29vcmRpbmF0ZXNbMV07XG4gICAgcmV0dXJuIHBvaW50ID0gbnVsbCxcbiAgICAgICAgKGxvd2VyNDhQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpXG4gICAgICAgIHx8IChhbGFza2FQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpXG4gICAgICAgIHx8IChoYXdhaWlQb2ludC5wb2ludCh4LCB5KSwgcG9pbnQpO1xuICB9XG5cbiAgYWxiZXJzVXNhLmludmVydCA9IGZ1bmN0aW9uKGNvb3JkaW5hdGVzKSB7XG4gICAgdmFyIGsgPSBsb3dlcjQ4LnNjYWxlKCksXG4gICAgICAgIHQgPSBsb3dlcjQ4LnRyYW5zbGF0ZSgpLFxuICAgICAgICB4ID0gKGNvb3JkaW5hdGVzWzBdIC0gdFswXSkgLyBrLFxuICAgICAgICB5ID0gKGNvb3JkaW5hdGVzWzFdIC0gdFsxXSkgLyBrO1xuICAgIHJldHVybiAoeSA+PSAwLjEyMCAmJiB5IDwgMC4yMzQgJiYgeCA+PSAtMC40MjUgJiYgeCA8IC0wLjIxNCA/IGFsYXNrYVxuICAgICAgICA6IHkgPj0gMC4xNjYgJiYgeSA8IDAuMjM0ICYmIHggPj0gLTAuMjE0ICYmIHggPCAtMC4xMTUgPyBoYXdhaWlcbiAgICAgICAgOiBsb3dlcjQ4KS5pbnZlcnQoY29vcmRpbmF0ZXMpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5zdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0pIHtcbiAgICByZXR1cm4gY2FjaGUgJiYgY2FjaGVTdHJlYW0gPT09IHN0cmVhbSA/IGNhY2hlIDogY2FjaGUgPSBtdWx0aXBsZXgoW2xvd2VyNDguc3RyZWFtKGNhY2hlU3RyZWFtID0gc3RyZWFtKSwgYWxhc2thLnN0cmVhbShzdHJlYW0pLCBoYXdhaWkuc3RyZWFtKHN0cmVhbSldKTtcbiAgfTtcblxuICBhbGJlcnNVc2EucHJlY2lzaW9uID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxvd2VyNDgucHJlY2lzaW9uKCk7XG4gICAgbG93ZXI0OC5wcmVjaXNpb24oXyksIGFsYXNrYS5wcmVjaXNpb24oXyksIGhhd2FpaS5wcmVjaXNpb24oXyk7XG4gICAgcmV0dXJuIHJlc2V0KCk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLnNjYWxlID0gZnVuY3Rpb24oXykge1xuICAgIGlmICghYXJndW1lbnRzLmxlbmd0aCkgcmV0dXJuIGxvd2VyNDguc2NhbGUoKTtcbiAgICBsb3dlcjQ4LnNjYWxlKF8pLCBhbGFza2Euc2NhbGUoXyAqIDAuMzUpLCBoYXdhaWkuc2NhbGUoXyk7XG4gICAgcmV0dXJuIGFsYmVyc1VzYS50cmFuc2xhdGUobG93ZXI0OC50cmFuc2xhdGUoKSk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLnRyYW5zbGF0ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHJldHVybiBsb3dlcjQ4LnRyYW5zbGF0ZSgpO1xuICAgIHZhciBrID0gbG93ZXI0OC5zY2FsZSgpLCB4ID0gK19bMF0sIHkgPSArX1sxXTtcblxuICAgIGxvd2VyNDhQb2ludCA9IGxvd2VyNDhcbiAgICAgICAgLnRyYW5zbGF0ZShfKVxuICAgICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjQ1NSAqIGssIHkgLSAwLjIzOCAqIGtdLCBbeCArIDAuNDU1ICogaywgeSArIDAuMjM4ICoga11dKVxuICAgICAgICAuc3RyZWFtKHBvaW50U3RyZWFtKTtcblxuICAgIGFsYXNrYVBvaW50ID0gYWxhc2thXG4gICAgICAgIC50cmFuc2xhdGUoW3ggLSAwLjMwNyAqIGssIHkgKyAwLjIwMSAqIGtdKVxuICAgICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjQyNSAqIGsgKyBlcHNpbG9uJDIsIHkgKyAwLjEyMCAqIGsgKyBlcHNpbG9uJDJdLCBbeCAtIDAuMjE0ICogayAtIGVwc2lsb24kMiwgeSArIDAuMjM0ICogayAtIGVwc2lsb24kMl1dKVxuICAgICAgICAuc3RyZWFtKHBvaW50U3RyZWFtKTtcblxuICAgIGhhd2FpaVBvaW50ID0gaGF3YWlpXG4gICAgICAgIC50cmFuc2xhdGUoW3ggLSAwLjIwNSAqIGssIHkgKyAwLjIxMiAqIGtdKVxuICAgICAgICAuY2xpcEV4dGVudChbW3ggLSAwLjIxNCAqIGsgKyBlcHNpbG9uJDIsIHkgKyAwLjE2NiAqIGsgKyBlcHNpbG9uJDJdLCBbeCAtIDAuMTE1ICogayAtIGVwc2lsb24kMiwgeSArIDAuMjM0ICogayAtIGVwc2lsb24kMl1dKVxuICAgICAgICAuc3RyZWFtKHBvaW50U3RyZWFtKTtcblxuICAgIHJldHVybiByZXNldCgpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5maXRFeHRlbnQgPSBmdW5jdGlvbihleHRlbnQsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRFeHRlbnQoYWxiZXJzVXNhLCBleHRlbnQsIG9iamVjdCk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLmZpdFNpemUgPSBmdW5jdGlvbihzaXplLCBvYmplY3QpIHtcbiAgICByZXR1cm4gZml0U2l6ZShhbGJlcnNVc2EsIHNpemUsIG9iamVjdCk7XG4gIH07XG5cbiAgYWxiZXJzVXNhLmZpdFdpZHRoID0gZnVuY3Rpb24od2lkdGgsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRXaWR0aChhbGJlcnNVc2EsIHdpZHRoLCBvYmplY3QpO1xuICB9O1xuXG4gIGFsYmVyc1VzYS5maXRIZWlnaHQgPSBmdW5jdGlvbihoZWlnaHQsIG9iamVjdCkge1xuICAgIHJldHVybiBmaXRIZWlnaHQoYWxiZXJzVXNhLCBoZWlnaHQsIG9iamVjdCk7XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVzZXQoKSB7XG4gICAgY2FjaGUgPSBjYWNoZVN0cmVhbSA9IG51bGw7XG4gICAgcmV0dXJuIGFsYmVyc1VzYTtcbiAgfVxuXG4gIHJldHVybiBhbGJlcnNVc2Euc2NhbGUoMTA3MCk7XG59O1xuXG5mdW5jdGlvbiBhemltdXRoYWxSYXcoc2NhbGUpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHgsIHkpIHtcbiAgICB2YXIgY3ggPSBjb3MkMSh4KSxcbiAgICAgICAgY3kgPSBjb3MkMSh5KSxcbiAgICAgICAgayA9IHNjYWxlKGN4ICogY3kpO1xuICAgIHJldHVybiBbXG4gICAgICBrICogY3kgKiBzaW4kMSh4KSxcbiAgICAgIGsgKiBzaW4kMSh5KVxuICAgIF07XG4gIH1cbn1cblxuZnVuY3Rpb24gYXppbXV0aGFsSW52ZXJ0KGFuZ2xlKSB7XG4gIHJldHVybiBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIHogPSBzcXJ0JDIoeCAqIHggKyB5ICogeSksXG4gICAgICAgIGMgPSBhbmdsZSh6KSxcbiAgICAgICAgc2MgPSBzaW4kMShjKSxcbiAgICAgICAgY2MgPSBjb3MkMShjKTtcbiAgICByZXR1cm4gW1xuICAgICAgYXRhbjIkMSh4ICogc2MsIHogKiBjYyksXG4gICAgICBhc2luJDEoeiAmJiB5ICogc2MgLyB6KVxuICAgIF07XG4gIH1cbn1cblxudmFyIGF6aW11dGhhbEVxdWFsQXJlYVJhdyA9IGF6aW11dGhhbFJhdyhmdW5jdGlvbihjeGN5KSB7XG4gIHJldHVybiBzcXJ0JDIoMiAvICgxICsgY3hjeSkpO1xufSk7XG5cbmF6aW11dGhhbEVxdWFsQXJlYVJhdy5pbnZlcnQgPSBhemltdXRoYWxJbnZlcnQoZnVuY3Rpb24oeikge1xuICByZXR1cm4gMiAqIGFzaW4kMSh6IC8gMik7XG59KTtcblxudmFyIGdlb0F6aW11dGhhbEVxdWFsQXJlYSA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gcHJvamVjdGlvbiQxKGF6aW11dGhhbEVxdWFsQXJlYVJhdylcbiAgICAgIC5zY2FsZSgxMjQuNzUpXG4gICAgICAuY2xpcEFuZ2xlKDE4MCAtIDFlLTMpO1xufTtcblxudmFyIGF6aW11dGhhbEVxdWlkaXN0YW50UmF3ID0gYXppbXV0aGFsUmF3KGZ1bmN0aW9uKGMpIHtcbiAgcmV0dXJuIChjID0gYWNvcyQxKGMpKSAmJiBjIC8gc2luJDEoYyk7XG59KTtcblxuYXppbXV0aGFsRXF1aWRpc3RhbnRSYXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGZ1bmN0aW9uKHopIHtcbiAgcmV0dXJuIHo7XG59KTtcblxudmFyIGdlb0F6aW11dGhhbEVxdWlkaXN0YW50ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uJDEoYXppbXV0aGFsRXF1aWRpc3RhbnRSYXcpXG4gICAgICAuc2NhbGUoNzkuNDE4OClcbiAgICAgIC5jbGlwQW5nbGUoMTgwIC0gMWUtMyk7XG59O1xuXG5mdW5jdGlvbiBtZXJjYXRvclJhdyhsYW1iZGEsIHBoaSkge1xuICByZXR1cm4gW2xhbWJkYSwgbG9nJDModGFuKChoYWxmUGkkMiArIHBoaSkgLyAyKSldO1xufVxuXG5tZXJjYXRvclJhdy5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gIHJldHVybiBbeCwgMiAqIGF0YW4oZXhwJDEoeSkpIC0gaGFsZlBpJDJdO1xufTtcblxudmFyIGdlb01lcmNhdG9yID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBtZXJjYXRvclByb2plY3Rpb24obWVyY2F0b3JSYXcpXG4gICAgICAuc2NhbGUoOTYxIC8gdGF1JDQpO1xufTtcblxuZnVuY3Rpb24gbWVyY2F0b3JQcm9qZWN0aW9uKHByb2plY3QpIHtcbiAgdmFyIG0gPSBwcm9qZWN0aW9uJDEocHJvamVjdCksXG4gICAgICBjZW50ZXIgPSBtLmNlbnRlcixcbiAgICAgIHNjYWxlID0gbS5zY2FsZSxcbiAgICAgIHRyYW5zbGF0ZSA9IG0udHJhbnNsYXRlLFxuICAgICAgY2xpcEV4dGVudCA9IG0uY2xpcEV4dGVudCxcbiAgICAgIHgwID0gbnVsbCwgeTAsIHgxLCB5MTsgLy8gY2xpcCBleHRlbnRcblxuICBtLnNjYWxlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHNjYWxlKF8pLCByZWNsaXAoKSkgOiBzY2FsZSgpO1xuICB9O1xuXG4gIG0udHJhbnNsYXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHRyYW5zbGF0ZShfKSwgcmVjbGlwKCkpIDogdHJhbnNsYXRlKCk7XG4gIH07XG5cbiAgbS5jZW50ZXIgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoY2VudGVyKF8pLCByZWNsaXAoKSkgOiBjZW50ZXIoKTtcbiAgfTtcblxuICBtLmNsaXBFeHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoKF8gPT0gbnVsbCA/IHgwID0geTAgPSB4MSA9IHkxID0gbnVsbCA6ICh4MCA9ICtfWzBdWzBdLCB5MCA9ICtfWzBdWzFdLCB4MSA9ICtfWzFdWzBdLCB5MSA9ICtfWzFdWzFdKSksIHJlY2xpcCgpKSA6IHgwID09IG51bGwgPyBudWxsIDogW1t4MCwgeTBdLCBbeDEsIHkxXV07XG4gIH07XG5cbiAgZnVuY3Rpb24gcmVjbGlwKCkge1xuICAgIHZhciBrID0gcGkkMyAqIHNjYWxlKCksXG4gICAgICAgIHQgPSBtKHJvdGF0aW9uKG0ucm90YXRlKCkpLmludmVydChbMCwgMF0pKTtcbiAgICByZXR1cm4gY2xpcEV4dGVudCh4MCA9PSBudWxsXG4gICAgICAgID8gW1t0WzBdIC0gaywgdFsxXSAtIGtdLCBbdFswXSArIGssIHRbMV0gKyBrXV0gOiBwcm9qZWN0ID09PSBtZXJjYXRvclJhd1xuICAgICAgICA/IFtbTWF0aC5tYXgodFswXSAtIGssIHgwKSwgeTBdLCBbTWF0aC5taW4odFswXSArIGssIHgxKSwgeTFdXVxuICAgICAgICA6IFtbeDAsIE1hdGgubWF4KHRbMV0gLSBrLCB5MCldLCBbeDEsIE1hdGgubWluKHRbMV0gKyBrLCB5MSldXSk7XG4gIH1cblxuICByZXR1cm4gcmVjbGlwKCk7XG59XG5cbmZ1bmN0aW9uIHRhbnkoeSkge1xuICByZXR1cm4gdGFuKChoYWxmUGkkMiArIHkpIC8gMik7XG59XG5cbmZ1bmN0aW9uIGNvbmljQ29uZm9ybWFsUmF3KHkwLCB5MSkge1xuICB2YXIgY3kwID0gY29zJDEoeTApLFxuICAgICAgbiA9IHkwID09PSB5MSA/IHNpbiQxKHkwKSA6IGxvZyQzKGN5MCAvIGNvcyQxKHkxKSkgLyBsb2ckMyh0YW55KHkxKSAvIHRhbnkoeTApKSxcbiAgICAgIGYgPSBjeTAgKiBwb3ckMih0YW55KHkwKSwgbikgLyBuO1xuXG4gIGlmICghbikgcmV0dXJuIG1lcmNhdG9yUmF3O1xuXG4gIGZ1bmN0aW9uIHByb2plY3QoeCwgeSkge1xuICAgIGlmIChmID4gMCkgeyBpZiAoeSA8IC1oYWxmUGkkMiArIGVwc2lsb24kMikgeSA9IC1oYWxmUGkkMiArIGVwc2lsb24kMjsgfVxuICAgIGVsc2UgeyBpZiAoeSA+IGhhbGZQaSQyIC0gZXBzaWxvbiQyKSB5ID0gaGFsZlBpJDIgLSBlcHNpbG9uJDI7IH1cbiAgICB2YXIgciA9IGYgLyBwb3ckMih0YW55KHkpLCBuKTtcbiAgICByZXR1cm4gW3IgKiBzaW4kMShuICogeCksIGYgLSByICogY29zJDEobiAqIHgpXTtcbiAgfVxuXG4gIHByb2plY3QuaW52ZXJ0ID0gZnVuY3Rpb24oeCwgeSkge1xuICAgIHZhciBmeSA9IGYgLSB5LCByID0gc2lnbiQxKG4pICogc3FydCQyKHggKiB4ICsgZnkgKiBmeSk7XG4gICAgcmV0dXJuIFthdGFuMiQxKHgsIGFicyQxKGZ5KSkgLyBuICogc2lnbiQxKGZ5KSwgMiAqIGF0YW4ocG93JDIoZiAvIHIsIDEgLyBuKSkgLSBoYWxmUGkkMl07XG4gIH07XG5cbiAgcmV0dXJuIHByb2plY3Q7XG59XG5cbnZhciBnZW9Db25pY0NvbmZvcm1hbCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gY29uaWNQcm9qZWN0aW9uKGNvbmljQ29uZm9ybWFsUmF3KVxuICAgICAgLnNjYWxlKDEwOS41KVxuICAgICAgLnBhcmFsbGVscyhbMzAsIDMwXSk7XG59O1xuXG5mdW5jdGlvbiBlcXVpcmVjdGFuZ3VsYXJSYXcobGFtYmRhLCBwaGkpIHtcbiAgcmV0dXJuIFtsYW1iZGEsIHBoaV07XG59XG5cbmVxdWlyZWN0YW5ndWxhclJhdy5pbnZlcnQgPSBlcXVpcmVjdGFuZ3VsYXJSYXc7XG5cbnZhciBnZW9FcXVpcmVjdGFuZ3VsYXIgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHByb2plY3Rpb24kMShlcXVpcmVjdGFuZ3VsYXJSYXcpXG4gICAgICAuc2NhbGUoMTUyLjYzKTtcbn07XG5cbmZ1bmN0aW9uIGNvbmljRXF1aWRpc3RhbnRSYXcoeTAsIHkxKSB7XG4gIHZhciBjeTAgPSBjb3MkMSh5MCksXG4gICAgICBuID0geTAgPT09IHkxID8gc2luJDEoeTApIDogKGN5MCAtIGNvcyQxKHkxKSkgLyAoeTEgLSB5MCksXG4gICAgICBnID0gY3kwIC8gbiArIHkwO1xuXG4gIGlmIChhYnMkMShuKSA8IGVwc2lsb24kMikgcmV0dXJuIGVxdWlyZWN0YW5ndWxhclJhdztcblxuICBmdW5jdGlvbiBwcm9qZWN0KHgsIHkpIHtcbiAgICB2YXIgZ3kgPSBnIC0geSwgbnggPSBuICogeDtcbiAgICByZXR1cm4gW2d5ICogc2luJDEobngpLCBnIC0gZ3kgKiBjb3MkMShueCldO1xuICB9XG5cbiAgcHJvamVjdC5pbnZlcnQgPSBmdW5jdGlvbih4LCB5KSB7XG4gICAgdmFyIGd5ID0gZyAtIHk7XG4gICAgcmV0dXJuIFthdGFuMiQxKHgsIGFicyQxKGd5KSkgLyBuICogc2lnbiQxKGd5KSwgZyAtIHNpZ24kMShuKSAqIHNxcnQkMih4ICogeCArIGd5ICogZ3kpXTtcbiAgfTtcblxuICByZXR1cm4gcHJvamVjdDtcbn1cblxudmFyIGdlb0NvbmljRXF1aWRpc3RhbnQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIGNvbmljUHJvamVjdGlvbihjb25pY0VxdWlkaXN0YW50UmF3KVxuICAgICAgLnNjYWxlKDEzMS4xNTQpXG4gICAgICAuY2VudGVyKFswLCAxMy45Mzg5XSk7XG59O1xuXG5mdW5jdGlvbiBnbm9tb25pY1Jhdyh4LCB5KSB7XG4gIHZhciBjeSA9IGNvcyQxKHkpLCBrID0gY29zJDEoeCkgKiBjeTtcbiAgcmV0dXJuIFtjeSAqIHNpbiQxKHgpIC8gaywgc2luJDEoeSkgLyBrXTtcbn1cblxuZ25vbW9uaWNSYXcuaW52ZXJ0ID0gYXppbXV0aGFsSW52ZXJ0KGF0YW4pO1xuXG52YXIgZ2VvR25vbW9uaWMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHByb2plY3Rpb24kMShnbm9tb25pY1JhdylcbiAgICAgIC5zY2FsZSgxNDQuMDQ5KVxuICAgICAgLmNsaXBBbmdsZSg2MCk7XG59O1xuXG5mdW5jdGlvbiBvcnRob2dyYXBoaWNSYXcoeCwgeSkge1xuICByZXR1cm4gW2NvcyQxKHkpICogc2luJDEoeCksIHNpbiQxKHkpXTtcbn1cblxub3J0aG9ncmFwaGljUmF3LmludmVydCA9IGF6aW11dGhhbEludmVydChhc2luJDEpO1xuXG52YXIgZ2VvT3J0aG9ncmFwaGljID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiBwcm9qZWN0aW9uJDEob3J0aG9ncmFwaGljUmF3KVxuICAgICAgLnNjYWxlKDI0OS41KVxuICAgICAgLmNsaXBBbmdsZSg5MCArIGVwc2lsb24kMik7XG59O1xuXG5mdW5jdGlvbiBzdGVyZW9ncmFwaGljUmF3KHgsIHkpIHtcbiAgdmFyIGN5ID0gY29zJDEoeSksIGsgPSAxICsgY29zJDEoeCkgKiBjeTtcbiAgcmV0dXJuIFtjeSAqIHNpbiQxKHgpIC8gaywgc2luJDEoeSkgLyBrXTtcbn1cblxuc3RlcmVvZ3JhcGhpY1Jhdy5pbnZlcnQgPSBhemltdXRoYWxJbnZlcnQoZnVuY3Rpb24oeikge1xuICByZXR1cm4gMiAqIGF0YW4oeik7XG59KTtcblxudmFyIGdlb1N0ZXJlb2dyYXBoaWMgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHByb2plY3Rpb24kMShzdGVyZW9ncmFwaGljUmF3KVxuICAgICAgLnNjYWxlKDI1MClcbiAgICAgIC5jbGlwQW5nbGUoMTQyKTtcbn07XG5cbmZ1bmN0aW9uIHRyYW5zdmVyc2VNZXJjYXRvclJhdyhsYW1iZGEsIHBoaSkge1xuICByZXR1cm4gW2xvZyQzKHRhbigoaGFsZlBpJDIgKyBwaGkpIC8gMikpLCAtbGFtYmRhXTtcbn1cblxudHJhbnN2ZXJzZU1lcmNhdG9yUmF3LmludmVydCA9IGZ1bmN0aW9uKHgsIHkpIHtcbiAgcmV0dXJuIFsteSwgMiAqIGF0YW4oZXhwJDEoeCkpIC0gaGFsZlBpJDJdO1xufTtcblxudmFyIGdlb1RyYW5zdmVyc2VNZXJjYXRvciA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbSA9IG1lcmNhdG9yUHJvamVjdGlvbih0cmFuc3ZlcnNlTWVyY2F0b3JSYXcpLFxuICAgICAgY2VudGVyID0gbS5jZW50ZXIsXG4gICAgICByb3RhdGUgPSBtLnJvdGF0ZTtcblxuICBtLmNlbnRlciA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IGNlbnRlcihbLV9bMV0sIF9bMF1dKSA6IChfID0gY2VudGVyKCksIFtfWzFdLCAtX1swXV0pO1xuICB9O1xuXG4gIG0ucm90YXRlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gcm90YXRlKFtfWzBdLCBfWzFdLCBfLmxlbmd0aCA+IDIgPyBfWzJdICsgOTAgOiA5MF0pIDogKF8gPSByb3RhdGUoKSwgW19bMF0sIF9bMV0sIF9bMl0gLSA5MF0pO1xuICB9O1xuXG4gIHJldHVybiByb3RhdGUoWzAsIDAsIDkwXSlcbiAgICAgIC5zY2FsZSgxNTkuMTU1KTtcbn07XG5cbnZhciBkZWZhdWx0UGF0aCA9IGdlb1BhdGgoKTtcblxudmFyIHByb2plY3Rpb25Qcm9wZXJ0aWVzID0gW1xuICAvLyBzdGFuZGFyZCBwcm9wZXJ0aWVzIGluIGQzLWdlb1xuICAnY2xpcEFuZ2xlJyxcbiAgJ2NsaXBFeHRlbnQnLFxuICAnc2NhbGUnLFxuICAndHJhbnNsYXRlJyxcbiAgJ2NlbnRlcicsXG4gICdyb3RhdGUnLFxuICAncGFyYWxsZWxzJyxcbiAgJ3ByZWNpc2lvbicsXG5cbiAgLy8gZXh0ZW5kZWQgcHJvcGVydGllcyBpbiBkMy1nZW8tcHJvamVjdGlvbnNcbiAgJ2NvZWZmaWNpZW50JyxcbiAgJ2Rpc3RhbmNlJyxcbiAgJ2ZyYWN0aW9uJyxcbiAgJ2xvYmVzJyxcbiAgJ3BhcmFsbGVsJyxcbiAgJ3JhZGl1cycsXG4gICdyYXRpbycsXG4gICdzcGFjaW5nJyxcbiAgJ3RpbHQnXG5dO1xuXG4vKipcbiAqIEF1Z21lbnQgcHJvamVjdGlvbnMgd2l0aCB0aGVpciB0eXBlIGFuZCBhIGNvcHkgbWV0aG9kLlxuICovXG5mdW5jdGlvbiBjcmVhdGUkMSh0eXBlLCBjb25zdHJ1Y3Rvcikge1xuICByZXR1cm4gZnVuY3Rpb24gcHJvamVjdGlvbiQkMSgpIHtcbiAgICB2YXIgcCA9IGNvbnN0cnVjdG9yKCk7XG5cbiAgICBwLnR5cGUgPSB0eXBlO1xuXG4gICAgcC5wYXRoID0gZ2VvUGF0aCgpLnByb2plY3Rpb24ocCk7XG5cbiAgICBwLmNvcHkgPSBwLmNvcHkgfHwgZnVuY3Rpb24oKSB7XG4gICAgICB2YXIgYyA9IHByb2plY3Rpb24kJDEoKTtcbiAgICAgIHByb2plY3Rpb25Qcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgICAgICBpZiAocC5oYXNPd25Qcm9wZXJ0eShwcm9wKSkgY1twcm9wXShwW3Byb3BdKCkpO1xuICAgICAgfSk7XG4gICAgICBjLnBhdGgucG9pbnRSYWRpdXMocC5wYXRoLnBvaW50UmFkaXVzKCkpO1xuICAgICAgcmV0dXJuIGM7XG4gICAgfTtcblxuICAgIHJldHVybiBwO1xuICB9O1xufVxuXG5mdW5jdGlvbiBwcm9qZWN0aW9uJCQxKHR5cGUsIHByb2opIHtcbiAgaWYgKCF0eXBlIHx8IHR5cGVvZiB0eXBlICE9PSAnc3RyaW5nJykge1xuICAgIHRocm93IG5ldyBFcnJvcignUHJvamVjdGlvbiB0eXBlIG11c3QgYmUgYSBuYW1lIHN0cmluZy4nKTtcbiAgfVxuICB0eXBlID0gdHlwZS50b0xvd2VyQ2FzZSgpO1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCA+IDEpIHtcbiAgICBwcm9qZWN0aW9uc1t0eXBlXSA9IGNyZWF0ZSQxKHR5cGUsIHByb2opO1xuICAgIHJldHVybiB0aGlzO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiBwcm9qZWN0aW9ucy5oYXNPd25Qcm9wZXJ0eSh0eXBlKSA/IHByb2plY3Rpb25zW3R5cGVdIDogbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBnZXRQcm9qZWN0aW9uUGF0aChwcm9qKSB7XG4gIHJldHVybiAocHJvaiAmJiBwcm9qLnBhdGgpIHx8IGRlZmF1bHRQYXRoO1xufVxuXG52YXIgcHJvamVjdGlvbnMgPSB7XG4gIC8vIGJhc2UgZDMtZ2VvIHByb2plY3Rpb24gdHlwZXNcbiAgYWxiZXJzOiAgICAgICAgICAgICAgIGFsYmVycyxcbiAgYWxiZXJzdXNhOiAgICAgICAgICAgIGdlb0FsYmVyc1VzYSxcbiAgYXppbXV0aGFsZXF1YWxhcmVhOiAgIGdlb0F6aW11dGhhbEVxdWFsQXJlYSxcbiAgYXppbXV0aGFsZXF1aWRpc3RhbnQ6IGdlb0F6aW11dGhhbEVxdWlkaXN0YW50LFxuICBjb25pY2NvbmZvcm1hbDogICAgICAgZ2VvQ29uaWNDb25mb3JtYWwsXG4gIGNvbmljZXF1YWxhcmVhOiAgICAgICBjb25pY0VxdWFsQXJlYSxcbiAgY29uaWNlcXVpZGlzdGFudDogICAgIGdlb0NvbmljRXF1aWRpc3RhbnQsXG4gIGVxdWlyZWN0YW5ndWxhcjogICAgICBnZW9FcXVpcmVjdGFuZ3VsYXIsXG4gIGdub21vbmljOiAgICAgICAgICAgICBnZW9Hbm9tb25pYyxcbiAgbWVyY2F0b3I6ICAgICAgICAgICAgIGdlb01lcmNhdG9yLFxuICBvcnRob2dyYXBoaWM6ICAgICAgICAgZ2VvT3J0aG9ncmFwaGljLFxuICBzdGVyZW9ncmFwaGljOiAgICAgICAgZ2VvU3RlcmVvZ3JhcGhpYyxcbiAgdHJhbnN2ZXJzZW1lcmNhdG9yOiAgIGdlb1RyYW5zdmVyc2VNZXJjYXRvclxufTtcblxuZm9yICh2YXIga2V5JDIgaW4gcHJvamVjdGlvbnMpIHtcbiAgcHJvamVjdGlvbiQkMShrZXkkMiwgcHJvamVjdGlvbnNba2V5JDJdKTtcbn1cblxuLyoqXG4gKiBNYXAgR2VvSlNPTiBkYXRhIHRvIGFuIFNWRyBwYXRoIHN0cmluZy5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihudW1iZXIsIG51bWJlcik6ICp9IHBhcmFtcy5wcm9qZWN0aW9uIC0gVGhlIGNhcnRvZ3JhcGhpY1xuICogICBwcm9qZWN0aW9uIHRvIGFwcGx5LlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBbcGFyYW1zLmZpZWxkXSAtIFRoZSBmaWVsZCB3aXRoIEdlb0pTT04gZGF0YSxcbiAqICAgb3IgbnVsbCBpZiB0aGUgdHVwbGUgaXRzZWxmIGlzIGEgR2VvSlNPTiBmZWF0dXJlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuYXM9J3BhdGgnXSAtIFRoZSBvdXRwdXQgZmllbGQgaW4gd2hpY2ggdG8gc3RvcmVcbiAqICAgdGhlIGdlbmVyYXRlZCBwYXRoIGRhdGEgKGRlZmF1bHQgJ3BhdGgnKS5cbiAqL1xuZnVuY3Rpb24gR2VvUGF0aChwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxuR2VvUGF0aC5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJHZW9QYXRoXCIsXG4gIFwibWV0YWRhdGFcIjoge1wibW9kaWZpZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcInByb2plY3Rpb25cIiwgXCJ0eXBlXCI6IFwicHJvamVjdGlvblwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJwb2ludFJhZGl1c1wiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJleHByXCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcImRlZmF1bHRcIjogXCJwYXRoXCIgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDY1ID0gaW5oZXJpdHMoR2VvUGF0aCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDY1LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBvdXQgPSBwdWxzZS5mb3JrKHB1bHNlLkFMTCksXG4gICAgICBwYXRoID0gdGhpcy52YWx1ZSxcbiAgICAgIGZpZWxkJCQxID0gXy5maWVsZCB8fCBpZGVudGl0eSxcbiAgICAgIGFzID0gXy5hcyB8fCAncGF0aCcsXG4gICAgICBmbGFnID0gb3V0LlNPVVJDRTtcblxuICBmdW5jdGlvbiBzZXQodCkgeyB0W2FzXSA9IHBhdGgoZmllbGQkJDEodCkpOyB9XG5cbiAgaWYgKCFwYXRoIHx8IF8ubW9kaWZpZWQoKSkge1xuICAgIC8vIHBhcmFtZXRlcnMgdXBkYXRlZCwgcmVzZXQgYW5kIHJlZmxvd1xuICAgIHRoaXMudmFsdWUgPSBwYXRoID0gZ2V0UHJvamVjdGlvblBhdGgoXy5wcm9qZWN0aW9uKTtcbiAgICBvdXQubWF0ZXJpYWxpemUoKS5yZWZsb3coKTtcbiAgfSBlbHNlIHtcbiAgICBmbGFnID0gZmllbGQkJDEgPT09IGlkZW50aXR5IHx8IHB1bHNlLm1vZGlmaWVkKGZpZWxkJCQxLmZpZWxkcylcbiAgICAgID8gb3V0LkFERF9NT0RcbiAgICAgIDogb3V0LkFERDtcbiAgfVxuXG4gIHZhciBwcmV2ID0gaW5pdFBhdGgocGF0aCwgXy5wb2ludFJhZGl1cyk7XG4gIG91dC52aXNpdChmbGFnLCBzZXQpO1xuICBwYXRoLnBvaW50UmFkaXVzKHByZXYpO1xuXG4gIHJldHVybiBvdXQubW9kaWZpZXMoYXMpO1xufTtcblxuZnVuY3Rpb24gaW5pdFBhdGgocGF0aCwgcG9pbnRSYWRpdXMpIHtcbiAgdmFyIHByZXYgPSBwYXRoLnBvaW50UmFkaXVzKCk7XG4gIHBhdGguY29udGV4dChudWxsKTtcbiAgaWYgKHBvaW50UmFkaXVzICE9IG51bGwpIHtcbiAgICBwYXRoLnBvaW50UmFkaXVzKHBvaW50UmFkaXVzKTtcbiAgfVxuICByZXR1cm4gcHJldjtcbn1cblxuLyoqXG4gKiBHZW8tY29kZSBhIGxvbmdpdHVkZS9sYXRpdHVkZSBwb2ludCB0byBhbiB4L3kgY29vcmRpbmF0ZS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihudW1iZXIsIG51bWJlcik6ICp9IHBhcmFtcy5wcm9qZWN0aW9uIC0gVGhlIGNhcnRvZ3JhcGhpY1xuICogICBwcm9qZWN0aW9uIHRvIGFwcGx5LlxuICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqPn0gcGFyYW1zLmZpZWxkcyAtIEEgdHdvLWVsZW1lbnQgYXJyYXkgb2ZcbiAqICAgZmllbGQgYWNjZXNzb3JzIGZvciB0aGUgbG9uZ2l0dWRlIGFuZCBsYXRpdHVkZSB2YWx1ZXMuXG4gKiBAcGFyYW0ge0FycmF5PHN0cmluZz59IFtwYXJhbXMuYXNdIC0gQSB0d28tZWxlbWVudCBhcnJheSBvZiBmaWVsZCBuYW1lc1xuICogICB1bmRlciB3aGljaCB0byBzdG9yZSB0aGUgcmVzdWx0LiBEZWZhdWx0cyB0byBbJ3gnLCd5J10uXG4gKi9cbmZ1bmN0aW9uIEdlb1BvaW50KHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5HZW9Qb2ludC5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJHZW9Qb2ludFwiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJwcm9qZWN0aW9uXCIsIFwidHlwZVwiOiBcInByb2plY3Rpb25cIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZHNcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJhcnJheVwiOiB0cnVlLCBcInJlcXVpcmVkXCI6IHRydWUsIFwibGVuZ3RoXCI6IDIgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsIFwiZGVmYXVsdFwiOiBbXCJ4XCIsIFwieVwiXSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkNjYgPSBpbmhlcml0cyhHZW9Qb2ludCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDY2LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBwcm9qID0gXy5wcm9qZWN0aW9uLFxuICAgICAgbG9uID0gXy5maWVsZHNbMF0sXG4gICAgICBsYXQgPSBfLmZpZWxkc1sxXSxcbiAgICAgIGFzID0gXy5hcyB8fCBbJ3gnLCAneSddLFxuICAgICAgeCA9IGFzWzBdLFxuICAgICAgeSA9IGFzWzFdLFxuICAgICAgbW9kO1xuXG4gIGZ1bmN0aW9uIHNldCh0KSB7XG4gICAgdmFyIHh5ID0gcHJvaihbbG9uKHQpLCBsYXQodCldKTtcbiAgICBpZiAoeHkpIHtcbiAgICAgIHRbeF0gPSB4eVswXTtcbiAgICAgIHRbeV0gPSB4eVsxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdFt4XSA9IHVuZGVmaW5lZDtcbiAgICAgIHRbeV0gPSB1bmRlZmluZWQ7XG4gICAgfVxuICB9XG5cbiAgaWYgKF8ubW9kaWZpZWQoKSkge1xuICAgIC8vIHBhcmFtZXRlcnMgdXBkYXRlZCwgcmVmbG93XG4gICAgcHVsc2UgPSBwdWxzZS5tYXRlcmlhbGl6ZSgpLnJlZmxvdyh0cnVlKS52aXNpdChwdWxzZS5TT1VSQ0UsIHNldCk7XG4gIH0gZWxzZSB7XG4gICAgbW9kID0gcHVsc2UubW9kaWZpZWQobG9uLmZpZWxkcykgfHwgcHVsc2UubW9kaWZpZWQobGF0LmZpZWxkcyk7XG4gICAgcHVsc2UudmlzaXQobW9kID8gcHVsc2UuQUREX01PRCA6IHB1bHNlLkFERCwgc2V0KTtcbiAgfVxuXG4gIHJldHVybiBwdWxzZS5tb2RpZmllcyhhcyk7XG59O1xuXG4vKipcbiAqIEFubm90YXRlIGl0ZW1zIHdpdGggYSBnZW9wYXRoIHNoYXBlIGdlbmVyYXRvci5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihudW1iZXIsIG51bWJlcik6ICp9IHBhcmFtcy5wcm9qZWN0aW9uIC0gVGhlIGNhcnRvZ3JhcGhpY1xuICogICBwcm9qZWN0aW9uIHRvIGFwcGx5LlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBbcGFyYW1zLmZpZWxkXSAtIFRoZSBmaWVsZCB3aXRoIEdlb0pTT04gZGF0YSxcbiAqICAgb3IgbnVsbCBpZiB0aGUgdHVwbGUgaXRzZWxmIGlzIGEgR2VvSlNPTiBmZWF0dXJlLlxuICogQHBhcmFtIHtzdHJpbmd9IFtwYXJhbXMuYXM9J3NoYXBlJ10gLSBUaGUgb3V0cHV0IGZpZWxkIGluIHdoaWNoIHRvIHN0b3JlXG4gKiAgIHRoZSBnZW5lcmF0ZWQgcGF0aCBkYXRhIChkZWZhdWx0ICdzaGFwZScpLlxuICovXG5mdW5jdGlvbiBHZW9TaGFwZShwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxuR2VvU2hhcGUuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiR2VvU2hhcGVcIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJtb2RpZmllc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwicHJvamVjdGlvblwiLCBcInR5cGVcIjogXCJwcm9qZWN0aW9uXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcImZpZWxkXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiZGVmYXVsdFwiOiBcImRhdHVtXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcInBvaW50UmFkaXVzXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImV4cHJcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiZGVmYXVsdFwiOiBcInNoYXBlXCIgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDY3ID0gaW5oZXJpdHMoR2VvU2hhcGUsIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ2Ny50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgb3V0ID0gcHVsc2UuZm9yayhwdWxzZS5BTEwpLFxuICAgICAgc2hhcGUgPSB0aGlzLnZhbHVlLFxuICAgICAgZGF0dW0gPSBfLmZpZWxkIHx8IGZpZWxkKCdkYXR1bScpLFxuICAgICAgYXMgPSBfLmFzIHx8ICdzaGFwZScsXG4gICAgICBmbGFnID0gb3V0LkFERF9NT0Q7XG5cbiAgaWYgKCFzaGFwZSB8fCBfLm1vZGlmaWVkKCkpIHtcbiAgICAvLyBwYXJhbWV0ZXJzIHVwZGF0ZWQsIHJlc2V0IGFuZCByZWZsb3dcbiAgICB0aGlzLnZhbHVlID0gc2hhcGUgPSBzaGFwZUdlbmVyYXRvcihcbiAgICAgIGdldFByb2plY3Rpb25QYXRoKF8ucHJvamVjdGlvbiksXG4gICAgICBkYXR1bSxcbiAgICAgIF8ucG9pbnRSYWRpdXNcbiAgICApO1xuICAgIG91dC5tYXRlcmlhbGl6ZSgpLnJlZmxvdygpO1xuICAgIGZsYWcgPSBvdXQuU09VUkNFO1xuICB9XG5cbiAgb3V0LnZpc2l0KGZsYWcsIGZ1bmN0aW9uKHQpIHsgdFthc10gPSBzaGFwZTsgfSk7XG5cbiAgcmV0dXJuIG91dC5tb2RpZmllcyhhcyk7XG59O1xuXG5mdW5jdGlvbiBzaGFwZUdlbmVyYXRvcihwYXRoLCBmaWVsZCQkMSwgcG9pbnRSYWRpdXMpIHtcbiAgdmFyIHNoYXBlID0gcG9pbnRSYWRpdXMgPT0gbnVsbFxuICAgID8gZnVuY3Rpb24oXykgeyByZXR1cm4gcGF0aChmaWVsZCQkMShfKSk7IH1cbiAgICA6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHZhciBwcmV2ID0gcGF0aC5wb2ludFJhZGl1cygpLFxuICAgICAgICAgIHZhbHVlID0gcGF0aC5wb2ludFJhZGl1cyhwb2ludFJhZGl1cykoZmllbGQkJDEoXykpO1xuICAgICAgcGF0aC5wb2ludFJhZGl1cyhwcmV2KTtcbiAgICAgIHJldHVybiB2YWx1ZTtcbiAgICB9O1xuICBzaGFwZS5jb250ZXh0ID0gZnVuY3Rpb24oXykge1xuICAgIHBhdGguY29udGV4dChfKTtcbiAgICByZXR1cm4gc2hhcGU7XG4gIH07XG5cbiAgcmV0dXJuIHNoYXBlO1xufVxuXG4vKipcbiAqIEdlb0pTT04gZmVhdHVyZSBnZW5lcmF0b3IgZm9yIGNyZWF0aW5nIGdyYXRpY3VsZXMuXG4gKiBAY29uc3RydWN0b3JcbiAqL1xuZnVuY3Rpb24gR3JhdGljdWxlKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBbXSwgcGFyYW1zKTtcbiAgdGhpcy5nZW5lcmF0b3IgPSBncmF0aWN1bGUoKTtcbn1cblxuR3JhdGljdWxlLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIkdyYXRpY3VsZVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcInNvdXJjZVwiOiB0cnVlLCBcImdlbmVyYXRlc1wiOiB0cnVlLCBcImNoYW5nZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImV4dGVudFwiLCBcInR5cGVcIjogXCJhcnJheVwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsXG4gICAgICBcImNvbnRlbnRcIjoge1widHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDJ9IH0sXG4gICAgeyBcIm5hbWVcIjogXCJleHRlbnRNYWpvclwiLCBcInR5cGVcIjogXCJhcnJheVwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsXG4gICAgICBcImNvbnRlbnRcIjoge1widHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDJ9IH0sXG4gICAgeyBcIm5hbWVcIjogXCJleHRlbnRNaW5vclwiLCBcInR5cGVcIjogXCJhcnJheVwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsXG4gICAgICBcImNvbnRlbnRcIjoge1widHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDJ9IH0sXG4gICAgeyBcIm5hbWVcIjogXCJzdGVwXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIgfSxcbiAgICB7IFwibmFtZVwiOiBcInN0ZXBNYWpvclwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiAyLCBcImRlZmF1bHRcIjogWzkwLCAzNjBdIH0sXG4gICAgeyBcIm5hbWVcIjogXCJzdGVwTWlub3JcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiwgXCJkZWZhdWx0XCI6IFsxMCwgMTBdIH0sXG4gICAgeyBcIm5hbWVcIjogXCJwcmVjaXNpb25cIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAyLjUgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDY4ID0gaW5oZXJpdHMoR3JhdGljdWxlLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkNjgudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIG91dCA9IHB1bHNlLmZvcmsoKSxcbiAgICAgIHNyYyA9IHRoaXMudmFsdWUsXG4gICAgICBnZW4gPSB0aGlzLmdlbmVyYXRvciwgdDtcblxuICBpZiAoIXNyYy5sZW5ndGggfHwgXy5tb2RpZmllZCgpKSB7XG4gICAgZm9yICh2YXIgcHJvcCBpbiBfKSB7XG4gICAgICBpZiAoaXNGdW5jdGlvbihnZW5bcHJvcF0pKSB7XG4gICAgICAgIGdlbltwcm9wXShfW3Byb3BdKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICB0ID0gZ2VuKCk7XG4gIGlmIChzcmMubGVuZ3RoKSB7XG4gICAgb3V0Lm1vZC5wdXNoKHJlcGxhY2Uoc3JjWzBdLCB0KSk7XG4gIH0gZWxzZSB7XG4gICAgb3V0LmFkZC5wdXNoKGluZ2VzdCh0KSk7XG4gIH1cbiAgc3JjWzBdID0gdDtcbiAgb3V0LnNvdXJjZSA9IHNyYztcblxuICByZXR1cm4gb3V0O1xufTtcblxuLyoqXG4gKiBNYWludGFpbnMgYSBjYXJ0b2dyYXBoaWMgcHJvamVjdGlvbi5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICovXG5mdW5jdGlvbiBQcm9qZWN0aW9uKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xuICB0aGlzLm1vZGlmaWVkKHRydWUpOyAvLyBhbHdheXMgdHJlYXQgYXMgbW9kaWZpZWRcbn1cblxudmFyIHByb3RvdHlwZSQ2OSA9IGluaGVyaXRzKFByb2plY3Rpb24sIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ2OS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgcHJvaiA9IHRoaXMudmFsdWU7XG5cbiAgaWYgKCFwcm9qIHx8IF8ubW9kaWZpZWQoJ3R5cGUnKSkge1xuICAgIHRoaXMudmFsdWUgPSAocHJvaiA9IGNyZWF0ZSQyKF8udHlwZSkpO1xuICAgIHByb2plY3Rpb25Qcm9wZXJ0aWVzLmZvckVhY2goZnVuY3Rpb24ocHJvcCkge1xuICAgICAgaWYgKF9bcHJvcF0gIT0gbnVsbCkgc2V0JDQocHJvaiwgcHJvcCwgX1twcm9wXSk7XG4gICAgfSk7XG4gIH0gZWxzZSB7XG4gICAgcHJvamVjdGlvblByb3BlcnRpZXMuZm9yRWFjaChmdW5jdGlvbihwcm9wKSB7XG4gICAgICBpZiAoXy5tb2RpZmllZChwcm9wKSkgc2V0JDQocHJvaiwgcHJvcCwgX1twcm9wXSk7XG4gICAgfSk7XG4gIH1cblxuICBpZiAoXy5wb2ludFJhZGl1cyAhPSBudWxsKSBwcm9qLnBhdGgucG9pbnRSYWRpdXMoXy5wb2ludFJhZGl1cyk7XG4gIGlmIChfLmZpdCkgZml0JDEocHJvaiwgXyk7XG5cbiAgcmV0dXJuIHB1bHNlLmZvcmsocHVsc2UuTk9fU09VUkNFIHwgcHVsc2UuTk9fRklFTERTKTtcbn07XG5cbmZ1bmN0aW9uIGZpdCQxKHByb2osIF8pIHtcbiAgdmFyIGRhdGEgPSBjb2xsZWN0R2VvSlNPTihfLmZpdCk7XG4gIF8uZXh0ZW50ID8gcHJvai5maXRFeHRlbnQoXy5leHRlbnQsIGRhdGEpXG4gICAgOiBfLnNpemUgPyBwcm9qLmZpdFNpemUoXy5zaXplLCBkYXRhKSA6IDA7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZSQyKHR5cGUpIHtcbiAgdmFyIGNvbnN0cnVjdG9yID0gcHJvamVjdGlvbiQkMSgodHlwZSB8fCAnbWVyY2F0b3InKS50b0xvd2VyQ2FzZSgpKTtcbiAgaWYgKCFjb25zdHJ1Y3RvcikgZXJyb3IkMSgnVW5yZWNvZ25pemVkIHByb2plY3Rpb24gdHlwZTogJyArIHR5cGUpO1xuICByZXR1cm4gY29uc3RydWN0b3IoKTtcbn1cblxuZnVuY3Rpb24gc2V0JDQocHJvaiwga2V5JCQxLCB2YWx1ZSkge1xuICAgaWYgKGlzRnVuY3Rpb24ocHJvaltrZXkkJDFdKSkgcHJvaltrZXkkJDFdKHZhbHVlKTtcbn1cblxuZnVuY3Rpb24gY29sbGVjdEdlb0pTT04oZmVhdHVyZXMpIHtcbiAgZmVhdHVyZXMgPSBhcnJheShmZWF0dXJlcyk7XG4gIHJldHVybiBmZWF0dXJlcy5sZW5ndGggPT09IDFcbiAgICA/IGZlYXR1cmVzWzBdXG4gICAgOiB7XG4gICAgICAgIHR5cGU6IEZlYXR1cmVDb2xsZWN0aW9uLFxuICAgICAgICBmZWF0dXJlczogZmVhdHVyZXMucmVkdWNlKGZ1bmN0aW9uKGxpc3QsIGYpIHtcbiAgICAgICAgICAgIChmICYmIGYudHlwZSA9PT0gRmVhdHVyZUNvbGxlY3Rpb24pID8gbGlzdC5wdXNoLmFwcGx5KGxpc3QsIGYuZmVhdHVyZXMpXG4gICAgICAgICAgICAgIDogaXNBcnJheShmKSA/IGxpc3QucHVzaC5hcHBseShsaXN0LCBmKVxuICAgICAgICAgICAgICA6IGxpc3QucHVzaChmKTtcbiAgICAgICAgICAgIHJldHVybiBsaXN0O1xuICAgICAgICAgIH0sIFtdKVxuICAgICAgfTtcbn1cblxuXG5cbnZhciBnZW8gPSBPYmplY3QuZnJlZXplKHtcblx0Y29udG91cjogQ29udG91cixcblx0Z2VvanNvbjogR2VvSlNPTixcblx0Z2VvcGF0aDogR2VvUGF0aCxcblx0Z2VvcG9pbnQ6IEdlb1BvaW50LFxuXHRnZW9zaGFwZTogR2VvU2hhcGUsXG5cdGdyYXRpY3VsZTogR3JhdGljdWxlLFxuXHRwcm9qZWN0aW9uOiBQcm9qZWN0aW9uXG59KTtcblxudmFyIGZvcmNlQ2VudGVyID0gZnVuY3Rpb24oeCwgeSkge1xuICB2YXIgbm9kZXM7XG5cbiAgaWYgKHggPT0gbnVsbCkgeCA9IDA7XG4gIGlmICh5ID09IG51bGwpIHkgPSAwO1xuXG4gIGZ1bmN0aW9uIGZvcmNlKCkge1xuICAgIHZhciBpLFxuICAgICAgICBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgICBub2RlLFxuICAgICAgICBzeCA9IDAsXG4gICAgICAgIHN5ID0gMDtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgc3ggKz0gbm9kZS54LCBzeSArPSBub2RlLnk7XG4gICAgfVxuXG4gICAgZm9yIChzeCA9IHN4IC8gbiAtIHgsIHN5ID0gc3kgLyBuIC0geSwgaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXSwgbm9kZS54IC09IHN4LCBub2RlLnkgLT0gc3k7XG4gICAgfVxuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gIH07XG5cbiAgZm9yY2UueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gK18sIGZvcmNlKSA6IHg7XG4gIH07XG5cbiAgZm9yY2UueSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh5ID0gK18sIGZvcmNlKSA6IHk7XG4gIH07XG5cbiAgcmV0dXJuIGZvcmNlO1xufTtcblxudmFyIGNvbnN0YW50JDggPSBmdW5jdGlvbih4KSB7XG4gIHJldHVybiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4geDtcbiAgfTtcbn07XG5cbnZhciBqaWdnbGUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIChNYXRoLnJhbmRvbSgpIC0gMC41KSAqIDFlLTY7XG59O1xuXG52YXIgdHJlZV9hZGQgPSBmdW5jdGlvbihkKSB7XG4gIHZhciB4ID0gK3RoaXMuX3guY2FsbChudWxsLCBkKSxcbiAgICAgIHkgPSArdGhpcy5feS5jYWxsKG51bGwsIGQpO1xuICByZXR1cm4gYWRkJDQodGhpcy5jb3Zlcih4LCB5KSwgeCwgeSwgZCk7XG59O1xuXG5mdW5jdGlvbiBhZGQkNCh0cmVlLCB4LCB5LCBkKSB7XG4gIGlmIChpc05hTih4KSB8fCBpc05hTih5KSkgcmV0dXJuIHRyZWU7IC8vIGlnbm9yZSBpbnZhbGlkIHBvaW50c1xuXG4gIHZhciBwYXJlbnQsXG4gICAgICBub2RlID0gdHJlZS5fcm9vdCxcbiAgICAgIGxlYWYgPSB7ZGF0YTogZH0sXG4gICAgICB4MCA9IHRyZWUuX3gwLFxuICAgICAgeTAgPSB0cmVlLl95MCxcbiAgICAgIHgxID0gdHJlZS5feDEsXG4gICAgICB5MSA9IHRyZWUuX3kxLFxuICAgICAgeG0sXG4gICAgICB5bSxcbiAgICAgIHhwLFxuICAgICAgeXAsXG4gICAgICByaWdodCxcbiAgICAgIGJvdHRvbSxcbiAgICAgIGksXG4gICAgICBqO1xuXG4gIC8vIElmIHRoZSB0cmVlIGlzIGVtcHR5LCBpbml0aWFsaXplIHRoZSByb290IGFzIGEgbGVhZi5cbiAgaWYgKCFub2RlKSByZXR1cm4gdHJlZS5fcm9vdCA9IGxlYWYsIHRyZWU7XG5cbiAgLy8gRmluZCB0aGUgZXhpc3RpbmcgbGVhZiBmb3IgdGhlIG5ldyBwb2ludCwgb3IgYWRkIGl0LlxuICB3aGlsZSAobm9kZS5sZW5ndGgpIHtcbiAgICBpZiAocmlnaHQgPSB4ID49ICh4bSA9ICh4MCArIHgxKSAvIDIpKSB4MCA9IHhtOyBlbHNlIHgxID0geG07XG4gICAgaWYgKGJvdHRvbSA9IHkgPj0gKHltID0gKHkwICsgeTEpIC8gMikpIHkwID0geW07IGVsc2UgeTEgPSB5bTtcbiAgICBpZiAocGFyZW50ID0gbm9kZSwgIShub2RlID0gbm9kZVtpID0gYm90dG9tIDw8IDEgfCByaWdodF0pKSByZXR1cm4gcGFyZW50W2ldID0gbGVhZiwgdHJlZTtcbiAgfVxuXG4gIC8vIElzIHRoZSBuZXcgcG9pbnQgaXMgZXhhY3RseSBjb2luY2lkZW50IHdpdGggdGhlIGV4aXN0aW5nIHBvaW50P1xuICB4cCA9ICt0cmVlLl94LmNhbGwobnVsbCwgbm9kZS5kYXRhKTtcbiAgeXAgPSArdHJlZS5feS5jYWxsKG51bGwsIG5vZGUuZGF0YSk7XG4gIGlmICh4ID09PSB4cCAmJiB5ID09PSB5cCkgcmV0dXJuIGxlYWYubmV4dCA9IG5vZGUsIHBhcmVudCA/IHBhcmVudFtpXSA9IGxlYWYgOiB0cmVlLl9yb290ID0gbGVhZiwgdHJlZTtcblxuICAvLyBPdGhlcndpc2UsIHNwbGl0IHRoZSBsZWFmIG5vZGUgdW50aWwgdGhlIG9sZCBhbmQgbmV3IHBvaW50IGFyZSBzZXBhcmF0ZWQuXG4gIGRvIHtcbiAgICBwYXJlbnQgPSBwYXJlbnQgPyBwYXJlbnRbaV0gPSBuZXcgQXJyYXkoNCkgOiB0cmVlLl9yb290ID0gbmV3IEFycmF5KDQpO1xuICAgIGlmIChyaWdodCA9IHggPj0gKHhtID0gKHgwICsgeDEpIC8gMikpIHgwID0geG07IGVsc2UgeDEgPSB4bTtcbiAgICBpZiAoYm90dG9tID0geSA+PSAoeW0gPSAoeTAgKyB5MSkgLyAyKSkgeTAgPSB5bTsgZWxzZSB5MSA9IHltO1xuICB9IHdoaWxlICgoaSA9IGJvdHRvbSA8PCAxIHwgcmlnaHQpID09PSAoaiA9ICh5cCA+PSB5bSkgPDwgMSB8ICh4cCA+PSB4bSkpKTtcbiAgcmV0dXJuIHBhcmVudFtqXSA9IG5vZGUsIHBhcmVudFtpXSA9IGxlYWYsIHRyZWU7XG59XG5cbmZ1bmN0aW9uIGFkZEFsbCQxKGRhdGEpIHtcbiAgdmFyIGQsIGksIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgeHogPSBuZXcgQXJyYXkobiksXG4gICAgICB5eiA9IG5ldyBBcnJheShuKSxcbiAgICAgIHgwID0gSW5maW5pdHksXG4gICAgICB5MCA9IEluZmluaXR5LFxuICAgICAgeDEgPSAtSW5maW5pdHksXG4gICAgICB5MSA9IC1JbmZpbml0eTtcblxuICAvLyBDb21wdXRlIHRoZSBwb2ludHMgYW5kIHRoZWlyIGV4dGVudC5cbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGlmIChpc05hTih4ID0gK3RoaXMuX3guY2FsbChudWxsLCBkID0gZGF0YVtpXSkpIHx8IGlzTmFOKHkgPSArdGhpcy5feS5jYWxsKG51bGwsIGQpKSkgY29udGludWU7XG4gICAgeHpbaV0gPSB4O1xuICAgIHl6W2ldID0geTtcbiAgICBpZiAoeCA8IHgwKSB4MCA9IHg7XG4gICAgaWYgKHggPiB4MSkgeDEgPSB4O1xuICAgIGlmICh5IDwgeTApIHkwID0geTtcbiAgICBpZiAoeSA+IHkxKSB5MSA9IHk7XG4gIH1cblxuICAvLyBJZiB0aGVyZSB3ZXJlIG5vICh2YWxpZCkgcG9pbnRzLCBpbmhlcml0IHRoZSBleGlzdGluZyBleHRlbnQuXG4gIGlmICh4MSA8IHgwKSB4MCA9IHRoaXMuX3gwLCB4MSA9IHRoaXMuX3gxO1xuICBpZiAoeTEgPCB5MCkgeTAgPSB0aGlzLl95MCwgeTEgPSB0aGlzLl95MTtcblxuICAvLyBFeHBhbmQgdGhlIHRyZWUgdG8gY292ZXIgdGhlIG5ldyBwb2ludHMuXG4gIHRoaXMuY292ZXIoeDAsIHkwKS5jb3Zlcih4MSwgeTEpO1xuXG4gIC8vIEFkZCB0aGUgbmV3IHBvaW50cy5cbiAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgIGFkZCQ0KHRoaXMsIHh6W2ldLCB5eltpXSwgZGF0YVtpXSk7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHRyZWVfY292ZXIgPSBmdW5jdGlvbih4LCB5KSB7XG4gIGlmIChpc05hTih4ID0gK3gpIHx8IGlzTmFOKHkgPSAreSkpIHJldHVybiB0aGlzOyAvLyBpZ25vcmUgaW52YWxpZCBwb2ludHNcblxuICB2YXIgeDAgPSB0aGlzLl94MCxcbiAgICAgIHkwID0gdGhpcy5feTAsXG4gICAgICB4MSA9IHRoaXMuX3gxLFxuICAgICAgeTEgPSB0aGlzLl95MTtcblxuICAvLyBJZiB0aGUgcXVhZHRyZWUgaGFzIG5vIGV4dGVudCwgaW5pdGlhbGl6ZSB0aGVtLlxuICAvLyBJbnRlZ2VyIGV4dGVudCBhcmUgbmVjZXNzYXJ5IHNvIHRoYXQgaWYgd2UgbGF0ZXIgZG91YmxlIHRoZSBleHRlbnQsXG4gIC8vIHRoZSBleGlzdGluZyBxdWFkcmFudCBib3VuZGFyaWVzIGRvbuKAmXQgY2hhbmdlIGR1ZSB0byBmbG9hdGluZyBwb2ludCBlcnJvciFcbiAgaWYgKGlzTmFOKHgwKSkge1xuICAgIHgxID0gKHgwID0gTWF0aC5mbG9vcih4KSkgKyAxO1xuICAgIHkxID0gKHkwID0gTWF0aC5mbG9vcih5KSkgKyAxO1xuICB9XG5cbiAgLy8gT3RoZXJ3aXNlLCBkb3VibGUgcmVwZWF0ZWRseSB0byBjb3Zlci5cbiAgZWxzZSBpZiAoeDAgPiB4IHx8IHggPiB4MSB8fCB5MCA+IHkgfHwgeSA+IHkxKSB7XG4gICAgdmFyIHogPSB4MSAtIHgwLFxuICAgICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgICAgcGFyZW50LFxuICAgICAgICBpO1xuXG4gICAgc3dpdGNoIChpID0gKHkgPCAoeTAgKyB5MSkgLyAyKSA8PCAxIHwgKHggPCAoeDAgKyB4MSkgLyAyKSkge1xuICAgICAgY2FzZSAwOiB7XG4gICAgICAgIGRvIHBhcmVudCA9IG5ldyBBcnJheSg0KSwgcGFyZW50W2ldID0gbm9kZSwgbm9kZSA9IHBhcmVudDtcbiAgICAgICAgd2hpbGUgKHogKj0gMiwgeDEgPSB4MCArIHosIHkxID0geTAgKyB6LCB4ID4geDEgfHwgeSA+IHkxKTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgICBjYXNlIDE6IHtcbiAgICAgICAgZG8gcGFyZW50ID0gbmV3IEFycmF5KDQpLCBwYXJlbnRbaV0gPSBub2RlLCBub2RlID0gcGFyZW50O1xuICAgICAgICB3aGlsZSAoeiAqPSAyLCB4MCA9IHgxIC0geiwgeTEgPSB5MCArIHosIHgwID4geCB8fCB5ID4geTEpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGNhc2UgMjoge1xuICAgICAgICBkbyBwYXJlbnQgPSBuZXcgQXJyYXkoNCksIHBhcmVudFtpXSA9IG5vZGUsIG5vZGUgPSBwYXJlbnQ7XG4gICAgICAgIHdoaWxlICh6ICo9IDIsIHgxID0geDAgKyB6LCB5MCA9IHkxIC0geiwgeCA+IHgxIHx8IHkwID4geSk7XG4gICAgICAgIGJyZWFrO1xuICAgICAgfVxuICAgICAgY2FzZSAzOiB7XG4gICAgICAgIGRvIHBhcmVudCA9IG5ldyBBcnJheSg0KSwgcGFyZW50W2ldID0gbm9kZSwgbm9kZSA9IHBhcmVudDtcbiAgICAgICAgd2hpbGUgKHogKj0gMiwgeDAgPSB4MSAtIHosIHkwID0geTEgLSB6LCB4MCA+IHggfHwgeTAgPiB5KTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX3Jvb3QgJiYgdGhpcy5fcm9vdC5sZW5ndGgpIHRoaXMuX3Jvb3QgPSBub2RlO1xuICB9XG5cbiAgLy8gSWYgdGhlIHF1YWR0cmVlIGNvdmVycyB0aGUgcG9pbnQgYWxyZWFkeSwganVzdCByZXR1cm4uXG4gIGVsc2UgcmV0dXJuIHRoaXM7XG5cbiAgdGhpcy5feDAgPSB4MDtcbiAgdGhpcy5feTAgPSB5MDtcbiAgdGhpcy5feDEgPSB4MTtcbiAgdGhpcy5feTEgPSB5MTtcbiAgcmV0dXJuIHRoaXM7XG59O1xuXG52YXIgdHJlZV9kYXRhID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkYXRhID0gW107XG4gIHRoaXMudmlzaXQoZnVuY3Rpb24obm9kZSkge1xuICAgIGlmICghbm9kZS5sZW5ndGgpIGRvIGRhdGEucHVzaChub2RlLmRhdGEpOyB3aGlsZSAobm9kZSA9IG5vZGUubmV4dClcbiAgfSk7XG4gIHJldHVybiBkYXRhO1xufTtcblxudmFyIHRyZWVfZXh0ZW50ID0gZnVuY3Rpb24oXykge1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aFxuICAgICAgPyB0aGlzLmNvdmVyKCtfWzBdWzBdLCArX1swXVsxXSkuY292ZXIoK19bMV1bMF0sICtfWzFdWzFdKVxuICAgICAgOiBpc05hTih0aGlzLl94MCkgPyB1bmRlZmluZWQgOiBbW3RoaXMuX3gwLCB0aGlzLl95MF0sIFt0aGlzLl94MSwgdGhpcy5feTFdXTtcbn07XG5cbnZhciBRdWFkID0gZnVuY3Rpb24obm9kZSwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdGhpcy5ub2RlID0gbm9kZTtcbiAgdGhpcy54MCA9IHgwO1xuICB0aGlzLnkwID0geTA7XG4gIHRoaXMueDEgPSB4MTtcbiAgdGhpcy55MSA9IHkxO1xufTtcblxudmFyIHRyZWVfZmluZCA9IGZ1bmN0aW9uKHgsIHksIHJhZGl1cykge1xuICB2YXIgZGF0YSxcbiAgICAgIHgwID0gdGhpcy5feDAsXG4gICAgICB5MCA9IHRoaXMuX3kwLFxuICAgICAgeDEsXG4gICAgICB5MSxcbiAgICAgIHgyLFxuICAgICAgeTIsXG4gICAgICB4MyA9IHRoaXMuX3gxLFxuICAgICAgeTMgPSB0aGlzLl95MSxcbiAgICAgIHF1YWRzID0gW10sXG4gICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgIHEsXG4gICAgICBpO1xuXG4gIGlmIChub2RlKSBxdWFkcy5wdXNoKG5ldyBRdWFkKG5vZGUsIHgwLCB5MCwgeDMsIHkzKSk7XG4gIGlmIChyYWRpdXMgPT0gbnVsbCkgcmFkaXVzID0gSW5maW5pdHk7XG4gIGVsc2Uge1xuICAgIHgwID0geCAtIHJhZGl1cywgeTAgPSB5IC0gcmFkaXVzO1xuICAgIHgzID0geCArIHJhZGl1cywgeTMgPSB5ICsgcmFkaXVzO1xuICAgIHJhZGl1cyAqPSByYWRpdXM7XG4gIH1cblxuICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7XG5cbiAgICAvLyBTdG9wIHNlYXJjaGluZyBpZiB0aGlzIHF1YWRyYW50IGNhbuKAmXQgY29udGFpbiBhIGNsb3NlciBub2RlLlxuICAgIGlmICghKG5vZGUgPSBxLm5vZGUpXG4gICAgICAgIHx8ICh4MSA9IHEueDApID4geDNcbiAgICAgICAgfHwgKHkxID0gcS55MCkgPiB5M1xuICAgICAgICB8fCAoeDIgPSBxLngxKSA8IHgwXG4gICAgICAgIHx8ICh5MiA9IHEueTEpIDwgeTApIGNvbnRpbnVlO1xuXG4gICAgLy8gQmlzZWN0IHRoZSBjdXJyZW50IHF1YWRyYW50LlxuICAgIGlmIChub2RlLmxlbmd0aCkge1xuICAgICAgdmFyIHhtID0gKHgxICsgeDIpIC8gMixcbiAgICAgICAgICB5bSA9ICh5MSArIHkyKSAvIDI7XG5cbiAgICAgIHF1YWRzLnB1c2goXG4gICAgICAgIG5ldyBRdWFkKG5vZGVbM10sIHhtLCB5bSwgeDIsIHkyKSxcbiAgICAgICAgbmV3IFF1YWQobm9kZVsyXSwgeDEsIHltLCB4bSwgeTIpLFxuICAgICAgICBuZXcgUXVhZChub2RlWzFdLCB4bSwgeTEsIHgyLCB5bSksXG4gICAgICAgIG5ldyBRdWFkKG5vZGVbMF0sIHgxLCB5MSwgeG0sIHltKVxuICAgICAgKTtcblxuICAgICAgLy8gVmlzaXQgdGhlIGNsb3Nlc3QgcXVhZHJhbnQgZmlyc3QuXG4gICAgICBpZiAoaSA9ICh5ID49IHltKSA8PCAxIHwgKHggPj0geG0pKSB7XG4gICAgICAgIHEgPSBxdWFkc1txdWFkcy5sZW5ndGggLSAxXTtcbiAgICAgICAgcXVhZHNbcXVhZHMubGVuZ3RoIC0gMV0gPSBxdWFkc1txdWFkcy5sZW5ndGggLSAxIC0gaV07XG4gICAgICAgIHF1YWRzW3F1YWRzLmxlbmd0aCAtIDEgLSBpXSA9IHE7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gVmlzaXQgdGhpcyBwb2ludC4gKFZpc2l0aW5nIGNvaW5jaWRlbnQgcG9pbnRzIGlzbuKAmXQgbmVjZXNzYXJ5ISlcbiAgICBlbHNlIHtcbiAgICAgIHZhciBkeCA9IHggLSArdGhpcy5feC5jYWxsKG51bGwsIG5vZGUuZGF0YSksXG4gICAgICAgICAgZHkgPSB5IC0gK3RoaXMuX3kuY2FsbChudWxsLCBub2RlLmRhdGEpLFxuICAgICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgICBpZiAoZDIgPCByYWRpdXMpIHtcbiAgICAgICAgdmFyIGQgPSBNYXRoLnNxcnQocmFkaXVzID0gZDIpO1xuICAgICAgICB4MCA9IHggLSBkLCB5MCA9IHkgLSBkO1xuICAgICAgICB4MyA9IHggKyBkLCB5MyA9IHkgKyBkO1xuICAgICAgICBkYXRhID0gbm9kZS5kYXRhO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIHJldHVybiBkYXRhO1xufTtcblxudmFyIHRyZWVfcmVtb3ZlID0gZnVuY3Rpb24oZCkge1xuICBpZiAoaXNOYU4oeCA9ICt0aGlzLl94LmNhbGwobnVsbCwgZCkpIHx8IGlzTmFOKHkgPSArdGhpcy5feS5jYWxsKG51bGwsIGQpKSkgcmV0dXJuIHRoaXM7IC8vIGlnbm9yZSBpbnZhbGlkIHBvaW50c1xuXG4gIHZhciBwYXJlbnQsXG4gICAgICBub2RlID0gdGhpcy5fcm9vdCxcbiAgICAgIHJldGFpbmVyLFxuICAgICAgcHJldmlvdXMsXG4gICAgICBuZXh0LFxuICAgICAgeDAgPSB0aGlzLl94MCxcbiAgICAgIHkwID0gdGhpcy5feTAsXG4gICAgICB4MSA9IHRoaXMuX3gxLFxuICAgICAgeTEgPSB0aGlzLl95MSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgeG0sXG4gICAgICB5bSxcbiAgICAgIHJpZ2h0LFxuICAgICAgYm90dG9tLFxuICAgICAgaSxcbiAgICAgIGo7XG5cbiAgLy8gSWYgdGhlIHRyZWUgaXMgZW1wdHksIGluaXRpYWxpemUgdGhlIHJvb3QgYXMgYSBsZWFmLlxuICBpZiAoIW5vZGUpIHJldHVybiB0aGlzO1xuXG4gIC8vIEZpbmQgdGhlIGxlYWYgbm9kZSBmb3IgdGhlIHBvaW50LlxuICAvLyBXaGlsZSBkZXNjZW5kaW5nLCBhbHNvIHJldGFpbiB0aGUgZGVlcGVzdCBwYXJlbnQgd2l0aCBhIG5vbi1yZW1vdmVkIHNpYmxpbmcuXG4gIGlmIChub2RlLmxlbmd0aCkgd2hpbGUgKHRydWUpIHtcbiAgICBpZiAocmlnaHQgPSB4ID49ICh4bSA9ICh4MCArIHgxKSAvIDIpKSB4MCA9IHhtOyBlbHNlIHgxID0geG07XG4gICAgaWYgKGJvdHRvbSA9IHkgPj0gKHltID0gKHkwICsgeTEpIC8gMikpIHkwID0geW07IGVsc2UgeTEgPSB5bTtcbiAgICBpZiAoIShwYXJlbnQgPSBub2RlLCBub2RlID0gbm9kZVtpID0gYm90dG9tIDw8IDEgfCByaWdodF0pKSByZXR1cm4gdGhpcztcbiAgICBpZiAoIW5vZGUubGVuZ3RoKSBicmVhaztcbiAgICBpZiAocGFyZW50WyhpICsgMSkgJiAzXSB8fCBwYXJlbnRbKGkgKyAyKSAmIDNdIHx8IHBhcmVudFsoaSArIDMpICYgM10pIHJldGFpbmVyID0gcGFyZW50LCBqID0gaTtcbiAgfVxuXG4gIC8vIEZpbmQgdGhlIHBvaW50IHRvIHJlbW92ZS5cbiAgd2hpbGUgKG5vZGUuZGF0YSAhPT0gZCkgaWYgKCEocHJldmlvdXMgPSBub2RlLCBub2RlID0gbm9kZS5uZXh0KSkgcmV0dXJuIHRoaXM7XG4gIGlmIChuZXh0ID0gbm9kZS5uZXh0KSBkZWxldGUgbm9kZS5uZXh0O1xuXG4gIC8vIElmIHRoZXJlIGFyZSBtdWx0aXBsZSBjb2luY2lkZW50IHBvaW50cywgcmVtb3ZlIGp1c3QgdGhlIHBvaW50LlxuICBpZiAocHJldmlvdXMpIHJldHVybiAobmV4dCA/IHByZXZpb3VzLm5leHQgPSBuZXh0IDogZGVsZXRlIHByZXZpb3VzLm5leHQpLCB0aGlzO1xuXG4gIC8vIElmIHRoaXMgaXMgdGhlIHJvb3QgcG9pbnQsIHJlbW92ZSBpdC5cbiAgaWYgKCFwYXJlbnQpIHJldHVybiB0aGlzLl9yb290ID0gbmV4dCwgdGhpcztcblxuICAvLyBSZW1vdmUgdGhpcyBsZWFmLlxuICBuZXh0ID8gcGFyZW50W2ldID0gbmV4dCA6IGRlbGV0ZSBwYXJlbnRbaV07XG5cbiAgLy8gSWYgdGhlIHBhcmVudCBub3cgY29udGFpbnMgZXhhY3RseSBvbmUgbGVhZiwgY29sbGFwc2Ugc3VwZXJmbHVvdXMgcGFyZW50cy5cbiAgaWYgKChub2RlID0gcGFyZW50WzBdIHx8IHBhcmVudFsxXSB8fCBwYXJlbnRbMl0gfHwgcGFyZW50WzNdKVxuICAgICAgJiYgbm9kZSA9PT0gKHBhcmVudFszXSB8fCBwYXJlbnRbMl0gfHwgcGFyZW50WzFdIHx8IHBhcmVudFswXSlcbiAgICAgICYmICFub2RlLmxlbmd0aCkge1xuICAgIGlmIChyZXRhaW5lcikgcmV0YWluZXJbal0gPSBub2RlO1xuICAgIGVsc2UgdGhpcy5fcm9vdCA9IG5vZGU7XG4gIH1cblxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIHJlbW92ZUFsbChkYXRhKSB7XG4gIGZvciAodmFyIGkgPSAwLCBuID0gZGF0YS5sZW5ndGg7IGkgPCBuOyArK2kpIHRoaXMucmVtb3ZlKGRhdGFbaV0pO1xuICByZXR1cm4gdGhpcztcbn1cblxudmFyIHRyZWVfcm9vdCA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gdGhpcy5fcm9vdDtcbn07XG5cbnZhciB0cmVlX3NpemUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNpemUgPSAwO1xuICB0aGlzLnZpc2l0KGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUubGVuZ3RoKSBkbyArK3NpemU7IHdoaWxlIChub2RlID0gbm9kZS5uZXh0KVxuICB9KTtcbiAgcmV0dXJuIHNpemU7XG59O1xuXG52YXIgdHJlZV92aXNpdCA9IGZ1bmN0aW9uKGNhbGxiYWNrKSB7XG4gIHZhciBxdWFkcyA9IFtdLCBxLCBub2RlID0gdGhpcy5fcm9vdCwgY2hpbGQsIHgwLCB5MCwgeDEsIHkxO1xuICBpZiAobm9kZSkgcXVhZHMucHVzaChuZXcgUXVhZChub2RlLCB0aGlzLl94MCwgdGhpcy5feTAsIHRoaXMuX3gxLCB0aGlzLl95MSkpO1xuICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7XG4gICAgaWYgKCFjYWxsYmFjayhub2RlID0gcS5ub2RlLCB4MCA9IHEueDAsIHkwID0gcS55MCwgeDEgPSBxLngxLCB5MSA9IHEueTEpICYmIG5vZGUubGVuZ3RoKSB7XG4gICAgICB2YXIgeG0gPSAoeDAgKyB4MSkgLyAyLCB5bSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzNdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4bSwgeW0sIHgxLCB5MSkpO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVsyXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeDAsIHltLCB4bSwgeTEpKTtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMV0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHhtLCB5MCwgeDEsIHltKSk7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzBdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4MCwgeTAsIHhtLCB5bSkpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbnZhciB0cmVlX3Zpc2l0QWZ0ZXIgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgcXVhZHMgPSBbXSwgbmV4dCA9IFtdLCBxO1xuICBpZiAodGhpcy5fcm9vdCkgcXVhZHMucHVzaChuZXcgUXVhZCh0aGlzLl9yb290LCB0aGlzLl94MCwgdGhpcy5feTAsIHRoaXMuX3gxLCB0aGlzLl95MSkpO1xuICB3aGlsZSAocSA9IHF1YWRzLnBvcCgpKSB7XG4gICAgdmFyIG5vZGUgPSBxLm5vZGU7XG4gICAgaWYgKG5vZGUubGVuZ3RoKSB7XG4gICAgICB2YXIgY2hpbGQsIHgwID0gcS54MCwgeTAgPSBxLnkwLCB4MSA9IHEueDEsIHkxID0gcS55MSwgeG0gPSAoeDAgKyB4MSkgLyAyLCB5bSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzBdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4MCwgeTAsIHhtLCB5bSkpO1xuICAgICAgaWYgKGNoaWxkID0gbm9kZVsxXSkgcXVhZHMucHVzaChuZXcgUXVhZChjaGlsZCwgeG0sIHkwLCB4MSwgeW0pKTtcbiAgICAgIGlmIChjaGlsZCA9IG5vZGVbMl0pIHF1YWRzLnB1c2gobmV3IFF1YWQoY2hpbGQsIHgwLCB5bSwgeG0sIHkxKSk7XG4gICAgICBpZiAoY2hpbGQgPSBub2RlWzNdKSBxdWFkcy5wdXNoKG5ldyBRdWFkKGNoaWxkLCB4bSwgeW0sIHgxLCB5MSkpO1xuICAgIH1cbiAgICBuZXh0LnB1c2gocSk7XG4gIH1cbiAgd2hpbGUgKHEgPSBuZXh0LnBvcCgpKSB7XG4gICAgY2FsbGJhY2socS5ub2RlLCBxLngwLCBxLnkwLCBxLngxLCBxLnkxKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGRlZmF1bHRYJDEoZCkge1xuICByZXR1cm4gZFswXTtcbn1cblxudmFyIHRyZWVfeCA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGhpcy5feCA9IF8sIHRoaXMpIDogdGhpcy5feDtcbn07XG5cbmZ1bmN0aW9uIGRlZmF1bHRZJDEoZCkge1xuICByZXR1cm4gZFsxXTtcbn1cblxudmFyIHRyZWVfeSA9IGZ1bmN0aW9uKF8pIHtcbiAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAodGhpcy5feSA9IF8sIHRoaXMpIDogdGhpcy5feTtcbn07XG5cbmZ1bmN0aW9uIHF1YWR0cmVlKG5vZGVzLCB4LCB5KSB7XG4gIHZhciB0cmVlID0gbmV3IFF1YWR0cmVlKHggPT0gbnVsbCA/IGRlZmF1bHRYJDEgOiB4LCB5ID09IG51bGwgPyBkZWZhdWx0WSQxIDogeSwgTmFOLCBOYU4sIE5hTiwgTmFOKTtcbiAgcmV0dXJuIG5vZGVzID09IG51bGwgPyB0cmVlIDogdHJlZS5hZGRBbGwobm9kZXMpO1xufVxuXG5mdW5jdGlvbiBRdWFkdHJlZSh4LCB5LCB4MCwgeTAsIHgxLCB5MSkge1xuICB0aGlzLl94ID0geDtcbiAgdGhpcy5feSA9IHk7XG4gIHRoaXMuX3gwID0geDA7XG4gIHRoaXMuX3kwID0geTA7XG4gIHRoaXMuX3gxID0geDE7XG4gIHRoaXMuX3kxID0geTE7XG4gIHRoaXMuX3Jvb3QgPSB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGxlYWZfY29weShsZWFmKSB7XG4gIHZhciBjb3B5ID0ge2RhdGE6IGxlYWYuZGF0YX0sIG5leHQgPSBjb3B5O1xuICB3aGlsZSAobGVhZiA9IGxlYWYubmV4dCkgbmV4dCA9IG5leHQubmV4dCA9IHtkYXRhOiBsZWFmLmRhdGF9O1xuICByZXR1cm4gY29weTtcbn1cblxudmFyIHRyZWVQcm90byA9IHF1YWR0cmVlLnByb3RvdHlwZSA9IFF1YWR0cmVlLnByb3RvdHlwZTtcblxudHJlZVByb3RvLmNvcHkgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNvcHkgPSBuZXcgUXVhZHRyZWUodGhpcy5feCwgdGhpcy5feSwgdGhpcy5feDAsIHRoaXMuX3kwLCB0aGlzLl94MSwgdGhpcy5feTEpLFxuICAgICAgbm9kZSA9IHRoaXMuX3Jvb3QsXG4gICAgICBub2RlcyxcbiAgICAgIGNoaWxkO1xuXG4gIGlmICghbm9kZSkgcmV0dXJuIGNvcHk7XG5cbiAgaWYgKCFub2RlLmxlbmd0aCkgcmV0dXJuIGNvcHkuX3Jvb3QgPSBsZWFmX2NvcHkobm9kZSksIGNvcHk7XG5cbiAgbm9kZXMgPSBbe3NvdXJjZTogbm9kZSwgdGFyZ2V0OiBjb3B5Ll9yb290ID0gbmV3IEFycmF5KDQpfV07XG4gIHdoaWxlIChub2RlID0gbm9kZXMucG9wKCkpIHtcbiAgICBmb3IgKHZhciBpID0gMDsgaSA8IDQ7ICsraSkge1xuICAgICAgaWYgKGNoaWxkID0gbm9kZS5zb3VyY2VbaV0pIHtcbiAgICAgICAgaWYgKGNoaWxkLmxlbmd0aCkgbm9kZXMucHVzaCh7c291cmNlOiBjaGlsZCwgdGFyZ2V0OiBub2RlLnRhcmdldFtpXSA9IG5ldyBBcnJheSg0KX0pO1xuICAgICAgICBlbHNlIG5vZGUudGFyZ2V0W2ldID0gbGVhZl9jb3B5KGNoaWxkKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29weTtcbn07XG5cbnRyZWVQcm90by5hZGQgPSB0cmVlX2FkZDtcbnRyZWVQcm90by5hZGRBbGwgPSBhZGRBbGwkMTtcbnRyZWVQcm90by5jb3ZlciA9IHRyZWVfY292ZXI7XG50cmVlUHJvdG8uZGF0YSA9IHRyZWVfZGF0YTtcbnRyZWVQcm90by5leHRlbnQgPSB0cmVlX2V4dGVudDtcbnRyZWVQcm90by5maW5kID0gdHJlZV9maW5kO1xudHJlZVByb3RvLnJlbW92ZSA9IHRyZWVfcmVtb3ZlO1xudHJlZVByb3RvLnJlbW92ZUFsbCA9IHJlbW92ZUFsbDtcbnRyZWVQcm90by5yb290ID0gdHJlZV9yb290O1xudHJlZVByb3RvLnNpemUgPSB0cmVlX3NpemU7XG50cmVlUHJvdG8udmlzaXQgPSB0cmVlX3Zpc2l0O1xudHJlZVByb3RvLnZpc2l0QWZ0ZXIgPSB0cmVlX3Zpc2l0QWZ0ZXI7XG50cmVlUHJvdG8ueCA9IHRyZWVfeDtcbnRyZWVQcm90by55ID0gdHJlZV95O1xuXG5mdW5jdGlvbiB4JDIoZCkge1xuICByZXR1cm4gZC54ICsgZC52eDtcbn1cblxuZnVuY3Rpb24geSQyKGQpIHtcbiAgcmV0dXJuIGQueSArIGQudnk7XG59XG5cbnZhciBmb3JjZUNvbGxpZGUgPSBmdW5jdGlvbihyYWRpdXMpIHtcbiAgdmFyIG5vZGVzLFxuICAgICAgcmFkaWksXG4gICAgICBzdHJlbmd0aCA9IDEsXG4gICAgICBpdGVyYXRpb25zID0gMTtcblxuICBpZiAodHlwZW9mIHJhZGl1cyAhPT0gXCJmdW5jdGlvblwiKSByYWRpdXMgPSBjb25zdGFudCQ4KHJhZGl1cyA9PSBudWxsID8gMSA6ICtyYWRpdXMpO1xuXG4gIGZ1bmN0aW9uIGZvcmNlKCkge1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgICB0cmVlLFxuICAgICAgICBub2RlLFxuICAgICAgICB4aSxcbiAgICAgICAgeWksXG4gICAgICAgIHJpLFxuICAgICAgICByaTI7XG5cbiAgICBmb3IgKHZhciBrID0gMDsgayA8IGl0ZXJhdGlvbnM7ICsraykge1xuICAgICAgdHJlZSA9IHF1YWR0cmVlKG5vZGVzLCB4JDIsIHkkMikudmlzaXRBZnRlcihwcmVwYXJlKTtcbiAgICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgICAgbm9kZSA9IG5vZGVzW2ldO1xuICAgICAgICByaSA9IHJhZGlpW25vZGUuaW5kZXhdLCByaTIgPSByaSAqIHJpO1xuICAgICAgICB4aSA9IG5vZGUueCArIG5vZGUudng7XG4gICAgICAgIHlpID0gbm9kZS55ICsgbm9kZS52eTtcbiAgICAgICAgdHJlZS52aXNpdChhcHBseSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgZnVuY3Rpb24gYXBwbHkocXVhZCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgICAgIHZhciBkYXRhID0gcXVhZC5kYXRhLCByaiA9IHF1YWQuciwgciA9IHJpICsgcmo7XG4gICAgICBpZiAoZGF0YSkge1xuICAgICAgICBpZiAoZGF0YS5pbmRleCA+IG5vZGUuaW5kZXgpIHtcbiAgICAgICAgICB2YXIgeCA9IHhpIC0gZGF0YS54IC0gZGF0YS52eCxcbiAgICAgICAgICAgICAgeSA9IHlpIC0gZGF0YS55IC0gZGF0YS52eSxcbiAgICAgICAgICAgICAgbCA9IHggKiB4ICsgeSAqIHk7XG4gICAgICAgICAgaWYgKGwgPCByICogcikge1xuICAgICAgICAgICAgaWYgKHggPT09IDApIHggPSBqaWdnbGUoKSwgbCArPSB4ICogeDtcbiAgICAgICAgICAgIGlmICh5ID09PSAwKSB5ID0gamlnZ2xlKCksIGwgKz0geSAqIHk7XG4gICAgICAgICAgICBsID0gKHIgLSAobCA9IE1hdGguc3FydChsKSkpIC8gbCAqIHN0cmVuZ3RoO1xuICAgICAgICAgICAgbm9kZS52eCArPSAoeCAqPSBsKSAqIChyID0gKHJqICo9IHJqKSAvIChyaTIgKyByaikpO1xuICAgICAgICAgICAgbm9kZS52eSArPSAoeSAqPSBsKSAqIHI7XG4gICAgICAgICAgICBkYXRhLnZ4IC09IHggKiAociA9IDEgLSByKTtcbiAgICAgICAgICAgIGRhdGEudnkgLT0geSAqIHI7XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICAgIHJldHVybjtcbiAgICAgIH1cbiAgICAgIHJldHVybiB4MCA+IHhpICsgciB8fCB4MSA8IHhpIC0gciB8fCB5MCA+IHlpICsgciB8fCB5MSA8IHlpIC0gcjtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBwcmVwYXJlKHF1YWQpIHtcbiAgICBpZiAocXVhZC5kYXRhKSByZXR1cm4gcXVhZC5yID0gcmFkaWlbcXVhZC5kYXRhLmluZGV4XTtcbiAgICBmb3IgKHZhciBpID0gcXVhZC5yID0gMDsgaSA8IDQ7ICsraSkge1xuICAgICAgaWYgKHF1YWRbaV0gJiYgcXVhZFtpXS5yID4gcXVhZC5yKSB7XG4gICAgICAgIHF1YWQuciA9IHF1YWRbaV0ucjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplKCkge1xuICAgIGlmICghbm9kZXMpIHJldHVybjtcbiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aCwgbm9kZTtcbiAgICByYWRpaSA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNbaV0sIHJhZGlpW25vZGUuaW5kZXhdID0gK3JhZGl1cyhub2RlLCBpLCBub2Rlcyk7XG4gIH1cblxuICBmb3JjZS5pbml0aWFsaXplID0gZnVuY3Rpb24oXykge1xuICAgIG5vZGVzID0gXztcbiAgICBpbml0aWFsaXplKCk7XG4gIH07XG5cbiAgZm9yY2UuaXRlcmF0aW9ucyA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChpdGVyYXRpb25zID0gK18sIGZvcmNlKSA6IGl0ZXJhdGlvbnM7XG4gIH07XG5cbiAgZm9yY2Uuc3RyZW5ndGggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc3RyZW5ndGggPSArXywgZm9yY2UpIDogc3RyZW5ndGg7XG4gIH07XG5cbiAgZm9yY2UucmFkaXVzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJhZGl1cyA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkOCgrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogcmFkaXVzO1xuICB9O1xuXG4gIHJldHVybiBmb3JjZTtcbn07XG5cbmZ1bmN0aW9uIGluZGV4KGQpIHtcbiAgcmV0dXJuIGQuaW5kZXg7XG59XG5cbmZ1bmN0aW9uIGZpbmQobm9kZUJ5SWQsIG5vZGVJZCkge1xuICB2YXIgbm9kZSA9IG5vZGVCeUlkLmdldChub2RlSWQpO1xuICBpZiAoIW5vZGUpIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmc6IFwiICsgbm9kZUlkKTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbnZhciBmb3JjZUxpbmsgPSBmdW5jdGlvbihsaW5rcykge1xuICB2YXIgaWQgPSBpbmRleCxcbiAgICAgIHN0cmVuZ3RoID0gZGVmYXVsdFN0cmVuZ3RoLFxuICAgICAgc3RyZW5ndGhzLFxuICAgICAgZGlzdGFuY2UgPSBjb25zdGFudCQ4KDMwKSxcbiAgICAgIGRpc3RhbmNlcyxcbiAgICAgIG5vZGVzLFxuICAgICAgY291bnQsXG4gICAgICBiaWFzLFxuICAgICAgaXRlcmF0aW9ucyA9IDE7XG5cbiAgaWYgKGxpbmtzID09IG51bGwpIGxpbmtzID0gW107XG5cbiAgZnVuY3Rpb24gZGVmYXVsdFN0cmVuZ3RoKGxpbmspIHtcbiAgICByZXR1cm4gMSAvIE1hdGgubWluKGNvdW50W2xpbmsuc291cmNlLmluZGV4XSwgY291bnRbbGluay50YXJnZXQuaW5kZXhdKTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGZvcmNlKGFscGhhKSB7XG4gICAgZm9yICh2YXIgayA9IDAsIG4gPSBsaW5rcy5sZW5ndGg7IGsgPCBpdGVyYXRpb25zOyArK2spIHtcbiAgICAgIGZvciAodmFyIGkgPSAwLCBsaW5rLCBzb3VyY2UsIHRhcmdldCwgeCwgeSwgbCwgYjsgaSA8IG47ICsraSkge1xuICAgICAgICBsaW5rID0gbGlua3NbaV0sIHNvdXJjZSA9IGxpbmsuc291cmNlLCB0YXJnZXQgPSBsaW5rLnRhcmdldDtcbiAgICAgICAgeCA9IHRhcmdldC54ICsgdGFyZ2V0LnZ4IC0gc291cmNlLnggLSBzb3VyY2UudnggfHwgamlnZ2xlKCk7XG4gICAgICAgIHkgPSB0YXJnZXQueSArIHRhcmdldC52eSAtIHNvdXJjZS55IC0gc291cmNlLnZ5IHx8IGppZ2dsZSgpO1xuICAgICAgICBsID0gTWF0aC5zcXJ0KHggKiB4ICsgeSAqIHkpO1xuICAgICAgICBsID0gKGwgLSBkaXN0YW5jZXNbaV0pIC8gbCAqIGFscGhhICogc3RyZW5ndGhzW2ldO1xuICAgICAgICB4ICo9IGwsIHkgKj0gbDtcbiAgICAgICAgdGFyZ2V0LnZ4IC09IHggKiAoYiA9IGJpYXNbaV0pO1xuICAgICAgICB0YXJnZXQudnkgLT0geSAqIGI7XG4gICAgICAgIHNvdXJjZS52eCArPSB4ICogKGIgPSAxIC0gYik7XG4gICAgICAgIHNvdXJjZS52eSArPSB5ICogYjtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplKCkge1xuICAgIGlmICghbm9kZXMpIHJldHVybjtcblxuICAgIHZhciBpLFxuICAgICAgICBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgICBtID0gbGlua3MubGVuZ3RoLFxuICAgICAgICBub2RlQnlJZCA9IG1hcChub2RlcywgaWQpLFxuICAgICAgICBsaW5rO1xuXG4gICAgZm9yIChpID0gMCwgY291bnQgPSBuZXcgQXJyYXkobik7IGkgPCBtOyArK2kpIHtcbiAgICAgIGxpbmsgPSBsaW5rc1tpXSwgbGluay5pbmRleCA9IGk7XG4gICAgICBpZiAodHlwZW9mIGxpbmsuc291cmNlICE9PSBcIm9iamVjdFwiKSBsaW5rLnNvdXJjZSA9IGZpbmQobm9kZUJ5SWQsIGxpbmsuc291cmNlKTtcbiAgICAgIGlmICh0eXBlb2YgbGluay50YXJnZXQgIT09IFwib2JqZWN0XCIpIGxpbmsudGFyZ2V0ID0gZmluZChub2RlQnlJZCwgbGluay50YXJnZXQpO1xuICAgICAgY291bnRbbGluay5zb3VyY2UuaW5kZXhdID0gKGNvdW50W2xpbmsuc291cmNlLmluZGV4XSB8fCAwKSArIDE7XG4gICAgICBjb3VudFtsaW5rLnRhcmdldC5pbmRleF0gPSAoY291bnRbbGluay50YXJnZXQuaW5kZXhdIHx8IDApICsgMTtcbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwLCBiaWFzID0gbmV3IEFycmF5KG0pOyBpIDwgbTsgKytpKSB7XG4gICAgICBsaW5rID0gbGlua3NbaV0sIGJpYXNbaV0gPSBjb3VudFtsaW5rLnNvdXJjZS5pbmRleF0gLyAoY291bnRbbGluay5zb3VyY2UuaW5kZXhdICsgY291bnRbbGluay50YXJnZXQuaW5kZXhdKTtcbiAgICB9XG5cbiAgICBzdHJlbmd0aHMgPSBuZXcgQXJyYXkobSksIGluaXRpYWxpemVTdHJlbmd0aCgpO1xuICAgIGRpc3RhbmNlcyA9IG5ldyBBcnJheShtKSwgaW5pdGlhbGl6ZURpc3RhbmNlKCk7XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplU3RyZW5ndGgoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuXG4gICAgZm9yICh2YXIgaSA9IDAsIG4gPSBsaW5rcy5sZW5ndGg7IGkgPCBuOyArK2kpIHtcbiAgICAgIHN0cmVuZ3Roc1tpXSA9ICtzdHJlbmd0aChsaW5rc1tpXSwgaSwgbGlua3MpO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemVEaXN0YW5jZSgpIHtcbiAgICBpZiAoIW5vZGVzKSByZXR1cm47XG5cbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IGxpbmtzLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgZGlzdGFuY2VzW2ldID0gK2Rpc3RhbmNlKGxpbmtzW2ldLCBpLCBsaW5rcyk7XG4gICAgfVxuICB9XG5cbiAgZm9yY2UuaW5pdGlhbGl6ZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBub2RlcyA9IF87XG4gICAgaW5pdGlhbGl6ZSgpO1xuICB9O1xuXG4gIGZvcmNlLmxpbmtzID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGxpbmtzID0gXywgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiBsaW5rcztcbiAgfTtcblxuICBmb3JjZS5pZCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChpZCA9IF8sIGZvcmNlKSA6IGlkO1xuICB9O1xuXG4gIGZvcmNlLml0ZXJhdGlvbnMgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaXRlcmF0aW9ucyA9ICtfLCBmb3JjZSkgOiBpdGVyYXRpb25zO1xuICB9O1xuXG4gIGZvcmNlLnN0cmVuZ3RoID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHN0cmVuZ3RoID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ4KCtfKSwgaW5pdGlhbGl6ZVN0cmVuZ3RoKCksIGZvcmNlKSA6IHN0cmVuZ3RoO1xuICB9O1xuXG4gIGZvcmNlLmRpc3RhbmNlID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRpc3RhbmNlID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ4KCtfKSwgaW5pdGlhbGl6ZURpc3RhbmNlKCksIGZvcmNlKSA6IGRpc3RhbmNlO1xuICB9O1xuXG4gIHJldHVybiBmb3JjZTtcbn07XG5cbnZhciBmcmFtZSA9IDA7XG52YXIgdGltZW91dCA9IDA7XG52YXIgaW50ZXJ2YWwgPSAwO1xudmFyIHBva2VEZWxheSA9IDEwMDA7XG52YXIgdGFza0hlYWQ7XG52YXIgdGFza1RhaWw7XG52YXIgY2xvY2tMYXN0ID0gMDtcbnZhciBjbG9ja05vdyA9IDA7XG52YXIgY2xvY2tTa2V3ID0gMDtcbnZhciBjbG9jayA9IHR5cGVvZiBwZXJmb3JtYW5jZSA9PT0gXCJvYmplY3RcIiAmJiBwZXJmb3JtYW5jZS5ub3cgPyBwZXJmb3JtYW5jZSA6IERhdGU7XG52YXIgc2V0RnJhbWUgPSB0eXBlb2Ygd2luZG93ID09PSBcIm9iamVjdFwiICYmIHdpbmRvdy5yZXF1ZXN0QW5pbWF0aW9uRnJhbWUgPyB3aW5kb3cucmVxdWVzdEFuaW1hdGlvbkZyYW1lLmJpbmQod2luZG93KSA6IGZ1bmN0aW9uKGYpIHsgc2V0VGltZW91dChmLCAxNyk7IH07XG5cbmZ1bmN0aW9uIG5vdygpIHtcbiAgcmV0dXJuIGNsb2NrTm93IHx8IChzZXRGcmFtZShjbGVhck5vdyksIGNsb2NrTm93ID0gY2xvY2subm93KCkgKyBjbG9ja1NrZXcpO1xufVxuXG5mdW5jdGlvbiBjbGVhck5vdygpIHtcbiAgY2xvY2tOb3cgPSAwO1xufVxuXG5mdW5jdGlvbiBUaW1lcigpIHtcbiAgdGhpcy5fY2FsbCA9XG4gIHRoaXMuX3RpbWUgPVxuICB0aGlzLl9uZXh0ID0gbnVsbDtcbn1cblxuVGltZXIucHJvdG90eXBlID0gdGltZXIucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogVGltZXIsXG4gIHJlc3RhcnQ6IGZ1bmN0aW9uKGNhbGxiYWNrLCBkZWxheSwgdGltZSkge1xuICAgIGlmICh0eXBlb2YgY2FsbGJhY2sgIT09IFwiZnVuY3Rpb25cIikgdGhyb3cgbmV3IFR5cGVFcnJvcihcImNhbGxiYWNrIGlzIG5vdCBhIGZ1bmN0aW9uXCIpO1xuICAgIHRpbWUgPSAodGltZSA9PSBudWxsID8gbm93KCkgOiArdGltZSkgKyAoZGVsYXkgPT0gbnVsbCA/IDAgOiArZGVsYXkpO1xuICAgIGlmICghdGhpcy5fbmV4dCAmJiB0YXNrVGFpbCAhPT0gdGhpcykge1xuICAgICAgaWYgKHRhc2tUYWlsKSB0YXNrVGFpbC5fbmV4dCA9IHRoaXM7XG4gICAgICBlbHNlIHRhc2tIZWFkID0gdGhpcztcbiAgICAgIHRhc2tUYWlsID0gdGhpcztcbiAgICB9XG4gICAgdGhpcy5fY2FsbCA9IGNhbGxiYWNrO1xuICAgIHRoaXMuX3RpbWUgPSB0aW1lO1xuICAgIHNsZWVwKCk7XG4gIH0sXG4gIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgIGlmICh0aGlzLl9jYWxsKSB7XG4gICAgICB0aGlzLl9jYWxsID0gbnVsbDtcbiAgICAgIHRoaXMuX3RpbWUgPSBJbmZpbml0eTtcbiAgICAgIHNsZWVwKCk7XG4gICAgfVxuICB9XG59O1xuXG5mdW5jdGlvbiB0aW1lcihjYWxsYmFjaywgZGVsYXksIHRpbWUpIHtcbiAgdmFyIHQgPSBuZXcgVGltZXI7XG4gIHQucmVzdGFydChjYWxsYmFjaywgZGVsYXksIHRpbWUpO1xuICByZXR1cm4gdDtcbn1cblxuZnVuY3Rpb24gdGltZXJGbHVzaCgpIHtcbiAgbm93KCk7IC8vIEdldCB0aGUgY3VycmVudCB0aW1lLCBpZiBub3QgYWxyZWFkeSBzZXQuXG4gICsrZnJhbWU7IC8vIFByZXRlbmQgd2XigJl2ZSBzZXQgYW4gYWxhcm0sIGlmIHdlIGhhdmVu4oCZdCBhbHJlYWR5LlxuICB2YXIgdCA9IHRhc2tIZWFkLCBlO1xuICB3aGlsZSAodCkge1xuICAgIGlmICgoZSA9IGNsb2NrTm93IC0gdC5fdGltZSkgPj0gMCkgdC5fY2FsbC5jYWxsKG51bGwsIGUpO1xuICAgIHQgPSB0Ll9uZXh0O1xuICB9XG4gIC0tZnJhbWU7XG59XG5cbmZ1bmN0aW9uIHdha2UoKSB7XG4gIGNsb2NrTm93ID0gKGNsb2NrTGFzdCA9IGNsb2NrLm5vdygpKSArIGNsb2NrU2tldztcbiAgZnJhbWUgPSB0aW1lb3V0ID0gMDtcbiAgdHJ5IHtcbiAgICB0aW1lckZsdXNoKCk7XG4gIH0gZmluYWxseSB7XG4gICAgZnJhbWUgPSAwO1xuICAgIG5hcCgpO1xuICAgIGNsb2NrTm93ID0gMDtcbiAgfVxufVxuXG5mdW5jdGlvbiBwb2tlKCkge1xuICB2YXIgbm93ID0gY2xvY2subm93KCksIGRlbGF5ID0gbm93IC0gY2xvY2tMYXN0O1xuICBpZiAoZGVsYXkgPiBwb2tlRGVsYXkpIGNsb2NrU2tldyAtPSBkZWxheSwgY2xvY2tMYXN0ID0gbm93O1xufVxuXG5mdW5jdGlvbiBuYXAoKSB7XG4gIHZhciB0MCwgdDEgPSB0YXNrSGVhZCwgdDIsIHRpbWUgPSBJbmZpbml0eTtcbiAgd2hpbGUgKHQxKSB7XG4gICAgaWYgKHQxLl9jYWxsKSB7XG4gICAgICBpZiAodGltZSA+IHQxLl90aW1lKSB0aW1lID0gdDEuX3RpbWU7XG4gICAgICB0MCA9IHQxLCB0MSA9IHQxLl9uZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0MiA9IHQxLl9uZXh0LCB0MS5fbmV4dCA9IG51bGw7XG4gICAgICB0MSA9IHQwID8gdDAuX25leHQgPSB0MiA6IHRhc2tIZWFkID0gdDI7XG4gICAgfVxuICB9XG4gIHRhc2tUYWlsID0gdDA7XG4gIHNsZWVwKHRpbWUpO1xufVxuXG5mdW5jdGlvbiBzbGVlcCh0aW1lKSB7XG4gIGlmIChmcmFtZSkgcmV0dXJuOyAvLyBTb29uZXN0IGFsYXJtIGFscmVhZHkgc2V0LCBvciB3aWxsIGJlLlxuICBpZiAodGltZW91dCkgdGltZW91dCA9IGNsZWFyVGltZW91dCh0aW1lb3V0KTtcbiAgdmFyIGRlbGF5ID0gdGltZSAtIGNsb2NrTm93OyAvLyBTdHJpY3RseSBsZXNzIHRoYW4gaWYgd2UgcmVjb21wdXRlZCBjbG9ja05vdy5cbiAgaWYgKGRlbGF5ID4gMjQpIHtcbiAgICBpZiAodGltZSA8IEluZmluaXR5KSB0aW1lb3V0ID0gc2V0VGltZW91dCh3YWtlLCB0aW1lIC0gY2xvY2subm93KCkgLSBjbG9ja1NrZXcpO1xuICAgIGlmIChpbnRlcnZhbCkgaW50ZXJ2YWwgPSBjbGVhckludGVydmFsKGludGVydmFsKTtcbiAgfSBlbHNlIHtcbiAgICBpZiAoIWludGVydmFsKSBjbG9ja0xhc3QgPSBjbG9jay5ub3coKSwgaW50ZXJ2YWwgPSBzZXRJbnRlcnZhbChwb2tlLCBwb2tlRGVsYXkpO1xuICAgIGZyYW1lID0gMSwgc2V0RnJhbWUod2FrZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24geCQzKGQpIHtcbiAgcmV0dXJuIGQueDtcbn1cblxuZnVuY3Rpb24geSQzKGQpIHtcbiAgcmV0dXJuIGQueTtcbn1cblxudmFyIGluaXRpYWxSYWRpdXMgPSAxMDtcbnZhciBpbml0aWFsQW5nbGUgPSBNYXRoLlBJICogKDMgLSBNYXRoLnNxcnQoNSkpO1xuXG52YXIgZm9yY2VTaW11bGF0aW9uID0gZnVuY3Rpb24obm9kZXMpIHtcbiAgdmFyIHNpbXVsYXRpb24sXG4gICAgICBhbHBoYSA9IDEsXG4gICAgICBhbHBoYU1pbiA9IDAuMDAxLFxuICAgICAgYWxwaGFEZWNheSA9IDEgLSBNYXRoLnBvdyhhbHBoYU1pbiwgMSAvIDMwMCksXG4gICAgICBhbHBoYVRhcmdldCA9IDAsXG4gICAgICB2ZWxvY2l0eURlY2F5ID0gMC42LFxuICAgICAgZm9yY2VzID0gbWFwKCksXG4gICAgICBzdGVwcGVyID0gdGltZXIoc3RlcCksXG4gICAgICBldmVudCA9IGRpc3BhdGNoKFwidGlja1wiLCBcImVuZFwiKTtcblxuICBpZiAobm9kZXMgPT0gbnVsbCkgbm9kZXMgPSBbXTtcblxuICBmdW5jdGlvbiBzdGVwKCkge1xuICAgIHRpY2soKTtcbiAgICBldmVudC5jYWxsKFwidGlja1wiLCBzaW11bGF0aW9uKTtcbiAgICBpZiAoYWxwaGEgPCBhbHBoYU1pbikge1xuICAgICAgc3RlcHBlci5zdG9wKCk7XG4gICAgICBldmVudC5jYWxsKFwiZW5kXCIsIHNpbXVsYXRpb24pO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIHRpY2soKSB7XG4gICAgdmFyIGksIG4gPSBub2Rlcy5sZW5ndGgsIG5vZGU7XG5cbiAgICBhbHBoYSArPSAoYWxwaGFUYXJnZXQgLSBhbHBoYSkgKiBhbHBoYURlY2F5O1xuXG4gICAgZm9yY2VzLmVhY2goZnVuY3Rpb24oZm9yY2UpIHtcbiAgICAgIGZvcmNlKGFscGhhKTtcbiAgICB9KTtcblxuICAgIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICAgIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgIGlmIChub2RlLmZ4ID09IG51bGwpIG5vZGUueCArPSBub2RlLnZ4ICo9IHZlbG9jaXR5RGVjYXk7XG4gICAgICBlbHNlIG5vZGUueCA9IG5vZGUuZngsIG5vZGUudnggPSAwO1xuICAgICAgaWYgKG5vZGUuZnkgPT0gbnVsbCkgbm9kZS55ICs9IG5vZGUudnkgKj0gdmVsb2NpdHlEZWNheTtcbiAgICAgIGVsc2Ugbm9kZS55ID0gbm9kZS5meSwgbm9kZS52eSA9IDA7XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZU5vZGVzKCkge1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUuaW5kZXggPSBpO1xuICAgICAgaWYgKGlzTmFOKG5vZGUueCkgfHwgaXNOYU4obm9kZS55KSkge1xuICAgICAgICB2YXIgcmFkaXVzID0gaW5pdGlhbFJhZGl1cyAqIE1hdGguc3FydChpKSwgYW5nbGUgPSBpICogaW5pdGlhbEFuZ2xlO1xuICAgICAgICBub2RlLnggPSByYWRpdXMgKiBNYXRoLmNvcyhhbmdsZSk7XG4gICAgICAgIG5vZGUueSA9IHJhZGl1cyAqIE1hdGguc2luKGFuZ2xlKTtcbiAgICAgIH1cbiAgICAgIGlmIChpc05hTihub2RlLnZ4KSB8fCBpc05hTihub2RlLnZ5KSkge1xuICAgICAgICBub2RlLnZ4ID0gbm9kZS52eSA9IDA7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZnVuY3Rpb24gaW5pdGlhbGl6ZUZvcmNlKGZvcmNlKSB7XG4gICAgaWYgKGZvcmNlLmluaXRpYWxpemUpIGZvcmNlLmluaXRpYWxpemUobm9kZXMpO1xuICAgIHJldHVybiBmb3JjZTtcbiAgfVxuXG4gIGluaXRpYWxpemVOb2RlcygpO1xuXG4gIHJldHVybiBzaW11bGF0aW9uID0ge1xuICAgIHRpY2s6IHRpY2ssXG5cbiAgICByZXN0YXJ0OiBmdW5jdGlvbigpIHtcbiAgICAgIHJldHVybiBzdGVwcGVyLnJlc3RhcnQoc3RlcCksIHNpbXVsYXRpb247XG4gICAgfSxcblxuICAgIHN0b3A6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHN0ZXBwZXIuc3RvcCgpLCBzaW11bGF0aW9uO1xuICAgIH0sXG5cbiAgICBub2RlczogZnVuY3Rpb24oXykge1xuICAgICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAobm9kZXMgPSBfLCBpbml0aWFsaXplTm9kZXMoKSwgZm9yY2VzLmVhY2goaW5pdGlhbGl6ZUZvcmNlKSwgc2ltdWxhdGlvbikgOiBub2RlcztcbiAgICB9LFxuXG4gICAgYWxwaGE6IGZ1bmN0aW9uKF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGFscGhhID0gK18sIHNpbXVsYXRpb24pIDogYWxwaGE7XG4gICAgfSxcblxuICAgIGFscGhhTWluOiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChhbHBoYU1pbiA9ICtfLCBzaW11bGF0aW9uKSA6IGFscGhhTWluO1xuICAgIH0sXG5cbiAgICBhbHBoYURlY2F5OiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChhbHBoYURlY2F5ID0gK18sIHNpbXVsYXRpb24pIDogK2FscGhhRGVjYXk7XG4gICAgfSxcblxuICAgIGFscGhhVGFyZ2V0OiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChhbHBoYVRhcmdldCA9ICtfLCBzaW11bGF0aW9uKSA6IGFscGhhVGFyZ2V0O1xuICAgIH0sXG5cbiAgICB2ZWxvY2l0eURlY2F5OiBmdW5jdGlvbihfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh2ZWxvY2l0eURlY2F5ID0gMSAtIF8sIHNpbXVsYXRpb24pIDogMSAtIHZlbG9jaXR5RGVjYXk7XG4gICAgfSxcblxuICAgIGZvcmNlOiBmdW5jdGlvbihuYW1lLCBfKSB7XG4gICAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA+IDEgPyAoKF8gPT0gbnVsbCA/IGZvcmNlcy5yZW1vdmUobmFtZSkgOiBmb3JjZXMuc2V0KG5hbWUsIGluaXRpYWxpemVGb3JjZShfKSkpLCBzaW11bGF0aW9uKSA6IGZvcmNlcy5nZXQobmFtZSk7XG4gICAgfSxcblxuICAgIGZpbmQ6IGZ1bmN0aW9uKHgsIHksIHJhZGl1cykge1xuICAgICAgdmFyIGkgPSAwLFxuICAgICAgICAgIG4gPSBub2Rlcy5sZW5ndGgsXG4gICAgICAgICAgZHgsXG4gICAgICAgICAgZHksXG4gICAgICAgICAgZDIsXG4gICAgICAgICAgbm9kZSxcbiAgICAgICAgICBjbG9zZXN0O1xuXG4gICAgICBpZiAocmFkaXVzID09IG51bGwpIHJhZGl1cyA9IEluZmluaXR5O1xuICAgICAgZWxzZSByYWRpdXMgKj0gcmFkaXVzO1xuXG4gICAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICAgIG5vZGUgPSBub2Rlc1tpXTtcbiAgICAgICAgZHggPSB4IC0gbm9kZS54O1xuICAgICAgICBkeSA9IHkgLSBub2RlLnk7XG4gICAgICAgIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG4gICAgICAgIGlmIChkMiA8IHJhZGl1cykgY2xvc2VzdCA9IG5vZGUsIHJhZGl1cyA9IGQyO1xuICAgICAgfVxuXG4gICAgICByZXR1cm4gY2xvc2VzdDtcbiAgICB9LFxuXG4gICAgb246IGZ1bmN0aW9uKG5hbWUsIF8pIHtcbiAgICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID4gMSA/IChldmVudC5vbihuYW1lLCBfKSwgc2ltdWxhdGlvbikgOiBldmVudC5vbihuYW1lKTtcbiAgICB9XG4gIH07XG59O1xuXG52YXIgZm9yY2VNYW55Qm9keSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMsXG4gICAgICBub2RlLFxuICAgICAgYWxwaGEsXG4gICAgICBzdHJlbmd0aCA9IGNvbnN0YW50JDgoLTMwKSxcbiAgICAgIHN0cmVuZ3RocyxcbiAgICAgIGRpc3RhbmNlTWluMiA9IDEsXG4gICAgICBkaXN0YW5jZU1heDIgPSBJbmZpbml0eSxcbiAgICAgIHRoZXRhMiA9IDAuODE7XG5cbiAgZnVuY3Rpb24gZm9yY2UoXykge1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCB0cmVlID0gcXVhZHRyZWUobm9kZXMsIHgkMywgeSQzKS52aXNpdEFmdGVyKGFjY3VtdWxhdGUpO1xuICAgIGZvciAoYWxwaGEgPSBfLCBpID0gMDsgaSA8IG47ICsraSkgbm9kZSA9IG5vZGVzW2ldLCB0cmVlLnZpc2l0KGFwcGx5KTtcbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlO1xuICAgIHN0cmVuZ3RocyA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBub2RlID0gbm9kZXNbaV0sIHN0cmVuZ3Roc1tub2RlLmluZGV4XSA9ICtzdHJlbmd0aChub2RlLCBpLCBub2Rlcyk7XG4gIH1cblxuICBmdW5jdGlvbiBhY2N1bXVsYXRlKHF1YWQpIHtcbiAgICB2YXIgc3RyZW5ndGggPSAwLCBxLCBjLCB3ZWlnaHQgPSAwLCB4LCB5LCBpO1xuXG4gICAgLy8gRm9yIGludGVybmFsIG5vZGVzLCBhY2N1bXVsYXRlIGZvcmNlcyBmcm9tIGNoaWxkIHF1YWRyYW50cy5cbiAgICBpZiAocXVhZC5sZW5ndGgpIHtcbiAgICAgIGZvciAoeCA9IHkgPSBpID0gMDsgaSA8IDQ7ICsraSkge1xuICAgICAgICBpZiAoKHEgPSBxdWFkW2ldKSAmJiAoYyA9IE1hdGguYWJzKHEudmFsdWUpKSkge1xuICAgICAgICAgIHN0cmVuZ3RoICs9IHEudmFsdWUsIHdlaWdodCArPSBjLCB4ICs9IGMgKiBxLngsIHkgKz0gYyAqIHEueTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcXVhZC54ID0geCAvIHdlaWdodDtcbiAgICAgIHF1YWQueSA9IHkgLyB3ZWlnaHQ7XG4gICAgfVxuXG4gICAgLy8gRm9yIGxlYWYgbm9kZXMsIGFjY3VtdWxhdGUgZm9yY2VzIGZyb20gY29pbmNpZGVudCBxdWFkcmFudHMuXG4gICAgZWxzZSB7XG4gICAgICBxID0gcXVhZDtcbiAgICAgIHEueCA9IHEuZGF0YS54O1xuICAgICAgcS55ID0gcS5kYXRhLnk7XG4gICAgICBkbyBzdHJlbmd0aCArPSBzdHJlbmd0aHNbcS5kYXRhLmluZGV4XTtcbiAgICAgIHdoaWxlIChxID0gcS5uZXh0KTtcbiAgICB9XG5cbiAgICBxdWFkLnZhbHVlID0gc3RyZW5ndGg7XG4gIH1cblxuICBmdW5jdGlvbiBhcHBseShxdWFkLCB4MSwgXywgeDIpIHtcbiAgICBpZiAoIXF1YWQudmFsdWUpIHJldHVybiB0cnVlO1xuXG4gICAgdmFyIHggPSBxdWFkLnggLSBub2RlLngsXG4gICAgICAgIHkgPSBxdWFkLnkgLSBub2RlLnksXG4gICAgICAgIHcgPSB4MiAtIHgxLFxuICAgICAgICBsID0geCAqIHggKyB5ICogeTtcblxuICAgIC8vIEFwcGx5IHRoZSBCYXJuZXMtSHV0IGFwcHJveGltYXRpb24gaWYgcG9zc2libGUuXG4gICAgLy8gTGltaXQgZm9yY2VzIGZvciB2ZXJ5IGNsb3NlIG5vZGVzOyByYW5kb21pemUgZGlyZWN0aW9uIGlmIGNvaW5jaWRlbnQuXG4gICAgaWYgKHcgKiB3IC8gdGhldGEyIDwgbCkge1xuICAgICAgaWYgKGwgPCBkaXN0YW5jZU1heDIpIHtcbiAgICAgICAgaWYgKHggPT09IDApIHggPSBqaWdnbGUoKSwgbCArPSB4ICogeDtcbiAgICAgICAgaWYgKHkgPT09IDApIHkgPSBqaWdnbGUoKSwgbCArPSB5ICogeTtcbiAgICAgICAgaWYgKGwgPCBkaXN0YW5jZU1pbjIpIGwgPSBNYXRoLnNxcnQoZGlzdGFuY2VNaW4yICogbCk7XG4gICAgICAgIG5vZGUudnggKz0geCAqIHF1YWQudmFsdWUgKiBhbHBoYSAvIGw7XG4gICAgICAgIG5vZGUudnkgKz0geSAqIHF1YWQudmFsdWUgKiBhbHBoYSAvIGw7XG4gICAgICB9XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICAvLyBPdGhlcndpc2UsIHByb2Nlc3MgcG9pbnRzIGRpcmVjdGx5LlxuICAgIGVsc2UgaWYgKHF1YWQubGVuZ3RoIHx8IGwgPj0gZGlzdGFuY2VNYXgyKSByZXR1cm47XG5cbiAgICAvLyBMaW1pdCBmb3JjZXMgZm9yIHZlcnkgY2xvc2Ugbm9kZXM7IHJhbmRvbWl6ZSBkaXJlY3Rpb24gaWYgY29pbmNpZGVudC5cbiAgICBpZiAocXVhZC5kYXRhICE9PSBub2RlIHx8IHF1YWQubmV4dCkge1xuICAgICAgaWYgKHggPT09IDApIHggPSBqaWdnbGUoKSwgbCArPSB4ICogeDtcbiAgICAgIGlmICh5ID09PSAwKSB5ID0gamlnZ2xlKCksIGwgKz0geSAqIHk7XG4gICAgICBpZiAobCA8IGRpc3RhbmNlTWluMikgbCA9IE1hdGguc3FydChkaXN0YW5jZU1pbjIgKiBsKTtcbiAgICB9XG5cbiAgICBkbyBpZiAocXVhZC5kYXRhICE9PSBub2RlKSB7XG4gICAgICB3ID0gc3RyZW5ndGhzW3F1YWQuZGF0YS5pbmRleF0gKiBhbHBoYSAvIGw7XG4gICAgICBub2RlLnZ4ICs9IHggKiB3O1xuICAgICAgbm9kZS52eSArPSB5ICogdztcbiAgICB9IHdoaWxlIChxdWFkID0gcXVhZC5uZXh0KTtcbiAgfVxuXG4gIGZvcmNlLmluaXRpYWxpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgbm9kZXMgPSBfO1xuICAgIGluaXRpYWxpemUoKTtcbiAgfTtcblxuICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkOCgrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogc3RyZW5ndGg7XG4gIH07XG5cbiAgZm9yY2UuZGlzdGFuY2VNaW4gPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZGlzdGFuY2VNaW4yID0gXyAqIF8sIGZvcmNlKSA6IE1hdGguc3FydChkaXN0YW5jZU1pbjIpO1xuICB9O1xuXG4gIGZvcmNlLmRpc3RhbmNlTWF4ID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGRpc3RhbmNlTWF4MiA9IF8gKiBfLCBmb3JjZSkgOiBNYXRoLnNxcnQoZGlzdGFuY2VNYXgyKTtcbiAgfTtcblxuICBmb3JjZS50aGV0YSA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aGV0YTIgPSBfICogXywgZm9yY2UpIDogTWF0aC5zcXJ0KHRoZXRhMik7XG4gIH07XG5cbiAgcmV0dXJuIGZvcmNlO1xufTtcblxudmFyIGZvcmNlWCA9IGZ1bmN0aW9uKHgpIHtcbiAgdmFyIHN0cmVuZ3RoID0gY29uc3RhbnQkOCgwLjEpLFxuICAgICAgbm9kZXMsXG4gICAgICBzdHJlbmd0aHMsXG4gICAgICB4ejtcblxuICBpZiAodHlwZW9mIHggIT09IFwiZnVuY3Rpb25cIikgeCA9IGNvbnN0YW50JDgoeCA9PSBudWxsID8gMCA6ICt4KTtcblxuICBmdW5jdGlvbiBmb3JjZShhbHBoYSkge1xuICAgIGZvciAodmFyIGkgPSAwLCBuID0gbm9kZXMubGVuZ3RoLCBub2RlOyBpIDwgbjsgKytpKSB7XG4gICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUudnggKz0gKHh6W2ldIC0gbm9kZS54KSAqIHN0cmVuZ3Roc1tpXSAqIGFscGhhO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGluaXRpYWxpemUoKSB7XG4gICAgaWYgKCFub2RlcykgcmV0dXJuO1xuICAgIHZhciBpLCBuID0gbm9kZXMubGVuZ3RoO1xuICAgIHN0cmVuZ3RocyA9IG5ldyBBcnJheShuKTtcbiAgICB4eiA9IG5ldyBBcnJheShuKTtcbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBzdHJlbmd0aHNbaV0gPSBpc05hTih4eltpXSA9ICt4KG5vZGVzW2ldLCBpLCBub2RlcykpID8gMCA6ICtzdHJlbmd0aChub2Rlc1tpXSwgaSwgbm9kZXMpO1xuICAgIH1cbiAgfVxuXG4gIGZvcmNlLmluaXRpYWxpemUgPSBmdW5jdGlvbihfKSB7XG4gICAgbm9kZXMgPSBfO1xuICAgIGluaXRpYWxpemUoKTtcbiAgfTtcblxuICBmb3JjZS5zdHJlbmd0aCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzdHJlbmd0aCA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkOCgrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogc3RyZW5ndGg7XG4gIH07XG5cbiAgZm9yY2UueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQ4KCtfKSwgaW5pdGlhbGl6ZSgpLCBmb3JjZSkgOiB4O1xuICB9O1xuXG4gIHJldHVybiBmb3JjZTtcbn07XG5cbnZhciBmb3JjZVkgPSBmdW5jdGlvbih5KSB7XG4gIHZhciBzdHJlbmd0aCA9IGNvbnN0YW50JDgoMC4xKSxcbiAgICAgIG5vZGVzLFxuICAgICAgc3RyZW5ndGhzLFxuICAgICAgeXo7XG5cbiAgaWYgKHR5cGVvZiB5ICE9PSBcImZ1bmN0aW9uXCIpIHkgPSBjb25zdGFudCQ4KHkgPT0gbnVsbCA/IDAgOiAreSk7XG5cbiAgZnVuY3Rpb24gZm9yY2UoYWxwaGEpIHtcbiAgICBmb3IgKHZhciBpID0gMCwgbiA9IG5vZGVzLmxlbmd0aCwgbm9kZTsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnZ5ICs9ICh5eltpXSAtIG5vZGUueSkgKiBzdHJlbmd0aHNbaV0gKiBhbHBoYTtcbiAgICB9XG4gIH1cblxuICBmdW5jdGlvbiBpbml0aWFsaXplKCkge1xuICAgIGlmICghbm9kZXMpIHJldHVybjtcbiAgICB2YXIgaSwgbiA9IG5vZGVzLmxlbmd0aDtcbiAgICBzdHJlbmd0aHMgPSBuZXcgQXJyYXkobik7XG4gICAgeXogPSBuZXcgQXJyYXkobik7XG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgc3RyZW5ndGhzW2ldID0gaXNOYU4oeXpbaV0gPSAreShub2Rlc1tpXSwgaSwgbm9kZXMpKSA/IDAgOiArc3RyZW5ndGgobm9kZXNbaV0sIGksIG5vZGVzKTtcbiAgICB9XG4gIH1cblxuICBmb3JjZS5pbml0aWFsaXplID0gZnVuY3Rpb24oXykge1xuICAgIG5vZGVzID0gXztcbiAgICBpbml0aWFsaXplKCk7XG4gIH07XG5cbiAgZm9yY2Uuc3RyZW5ndGggPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoc3RyZW5ndGggPSB0eXBlb2YgXyA9PT0gXCJmdW5jdGlvblwiID8gXyA6IGNvbnN0YW50JDgoK18pLCBpbml0aWFsaXplKCksIGZvcmNlKSA6IHN0cmVuZ3RoO1xuICB9O1xuXG4gIGZvcmNlLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkOCgrXyksIGluaXRpYWxpemUoKSwgZm9yY2UpIDogeTtcbiAgfTtcblxuICByZXR1cm4gZm9yY2U7XG59O1xuXG52YXIgRm9yY2VNYXAgPSB7XG4gIGNlbnRlcjogZm9yY2VDZW50ZXIsXG4gIGNvbGxpZGU6IGZvcmNlQ29sbGlkZSxcbiAgbmJvZHk6IGZvcmNlTWFueUJvZHksXG4gIGxpbms6IGZvcmNlTGluayxcbiAgeDogZm9yY2VYLFxuICB5OiBmb3JjZVlcbn07XG5cbnZhciBGb3JjZXMgPSAnZm9yY2VzJztcbnZhciBGb3JjZVBhcmFtcyA9IFtcbiAgICAgICdhbHBoYScsICdhbHBoYU1pbicsICdhbHBoYVRhcmdldCcsXG4gICAgICAndmVsb2NpdHlEZWNheScsICdmb3JjZXMnXG4gICAgXTtcbnZhciBGb3JjZUNvbmZpZyA9IFsnc3RhdGljJywgJ2l0ZXJhdGlvbnMnXTtcbnZhciBGb3JjZU91dHB1dCA9IFsneCcsICd5JywgJ3Z4JywgJ3Z5J107XG5cbi8qKlxuICogRm9yY2Ugc2ltdWxhdGlvbiBsYXlvdXQuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7QXJyYXk8b2JqZWN0Pn0gcGFyYW1zLmZvcmNlcyAtIFRoZSBmb3JjZXMgdG8gYXBwbHkuXG4gKi9cbmZ1bmN0aW9uIEZvcmNlKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5Gb3JjZS5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJGb3JjZVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJzdGF0aWNcIiwgXCJ0eXBlXCI6IFwiYm9vbGVhblwiLCBcImRlZmF1bHRcIjogZmFsc2UgfSxcbiAgICB7IFwibmFtZVwiOiBcInJlc3RhcnRcIiwgXCJ0eXBlXCI6IFwiYm9vbGVhblwiLCBcImRlZmF1bHRcIjogZmFsc2UgfSxcbiAgICB7IFwibmFtZVwiOiBcIml0ZXJhdGlvbnNcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAzMDAgfSxcbiAgICB7IFwibmFtZVwiOiBcImFscGhhXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYWxwaGFNaW5cIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAwLjAwMSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYWxwaGFUYXJnZXRcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJ2ZWxvY2l0eURlY2F5XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMC40IH0sXG4gICAgeyBcIm5hbWVcIjogXCJmb3JjZXNcIiwgXCJ0eXBlXCI6IFwicGFyYW1cIiwgXCJhcnJheVwiOiB0cnVlLFxuICAgICAgXCJwYXJhbXNcIjogW1xuICAgICAgICB7XG4gICAgICAgICAgXCJrZXlcIjoge1wiZm9yY2VcIjogXCJjZW50ZXJcIn0sXG4gICAgICAgICAgXCJwYXJhbXNcIjogW1xuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJ4XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9LFxuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJ5XCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJrZXlcIjoge1wiZm9yY2VcIjogXCJjb2xsaWRlXCJ9LFxuICAgICAgICAgIFwicGFyYW1zXCI6IFtcbiAgICAgICAgICAgIHsgXCJuYW1lXCI6IFwicmFkaXVzXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImV4cHJcIjogdHJ1ZSB9LFxuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJzdHJlbmd0aFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAuNyB9LFxuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJpdGVyYXRpb25zXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMSB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJrZXlcIjoge1wiZm9yY2VcIjogXCJuYm9keVwifSxcbiAgICAgICAgICBcInBhcmFtc1wiOiBbXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcInN0cmVuZ3RoXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogLTMwIH0sXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcInRoZXRhXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMC45IH0sXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcImRpc3RhbmNlTWluXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMSB9LFxuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJkaXN0YW5jZU1heFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiB9XG4gICAgICAgICAgXVxuICAgICAgICB9LFxuICAgICAgICB7XG4gICAgICAgICAgXCJrZXlcIjoge1wiZm9yY2VcIjogXCJsaW5rXCJ9LFxuICAgICAgICAgIFwicGFyYW1zXCI6IFtcbiAgICAgICAgICAgIHsgXCJuYW1lXCI6IFwibGlua3NcIiwgXCJ0eXBlXCI6IFwiZGF0YVwiIH0sXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcImlkXCIsIFwidHlwZVwiOiBcImZpZWxkXCIgfSxcbiAgICAgICAgICAgIHsgXCJuYW1lXCI6IFwiZGlzdGFuY2VcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAzMCwgXCJleHByXCI6IHRydWUgfSxcbiAgICAgICAgICAgIHsgXCJuYW1lXCI6IFwic3RyZW5ndGhcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZXhwclwiOiB0cnVlIH0sXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcIml0ZXJhdGlvbnNcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAxIH1cbiAgICAgICAgICBdXG4gICAgICAgIH0sXG4gICAgICAgIHtcbiAgICAgICAgICBcImtleVwiOiB7XCJmb3JjZVwiOiBcInhcIn0sXG4gICAgICAgICAgXCJwYXJhbXNcIjogW1xuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJzdHJlbmd0aFwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAuMSB9LFxuICAgICAgICAgICAgeyBcIm5hbWVcIjogXCJ4XCIsIFwidHlwZVwiOiBcImZpZWxkXCIgfVxuICAgICAgICAgIF1cbiAgICAgICAgfSxcbiAgICAgICAge1xuICAgICAgICAgIFwia2V5XCI6IHtcImZvcmNlXCI6IFwieVwifSxcbiAgICAgICAgICBcInBhcmFtc1wiOiBbXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcInN0cmVuZ3RoXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMC4xIH0sXG4gICAgICAgICAgICB7IFwibmFtZVwiOiBcInlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9XG4gICAgICAgICAgXVxuICAgICAgICB9XG4gICAgICBdIH0sXG4gICAge1xuICAgICAgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJtb2RpZnlcIjogZmFsc2UsXG4gICAgICBcImRlZmF1bHRcIjogRm9yY2VPdXRwdXRcbiAgICB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkNzAgPSBpbmhlcml0cyhGb3JjZSwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDcwLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBzaW0gPSB0aGlzLnZhbHVlLFxuICAgICAgY2hhbmdlID0gcHVsc2UuY2hhbmdlZChwdWxzZS5BRERfUkVNKSxcbiAgICAgIHBhcmFtcyA9IF8ubW9kaWZpZWQoRm9yY2VQYXJhbXMpLFxuICAgICAgaXRlcnMgPSBfLml0ZXJhdGlvbnMgfHwgMzAwO1xuXG4gIC8vIGNvbmZpZ3VyZSBzaW11bGF0aW9uXG4gIGlmICghc2ltKSB7XG4gICAgdGhpcy52YWx1ZSA9IHNpbSA9IHNpbXVsYXRpb24ocHVsc2Uuc291cmNlLCBfKTtcbiAgICBzaW0ub24oJ3RpY2snLCByZXJ1bihwdWxzZS5kYXRhZmxvdywgdGhpcykpO1xuICAgIGlmICghXy5zdGF0aWMpIHtcbiAgICAgIGNoYW5nZSA9IHRydWU7XG4gICAgICBzaW0udGljaygpOyAvLyBlbnN1cmUgd2UgcnVuIG9uIGluaXRcbiAgICB9XG4gICAgcHVsc2UubW9kaWZpZXMoJ2luZGV4Jyk7XG4gIH0gZWxzZSB7XG4gICAgaWYgKGNoYW5nZSkge1xuICAgICAgcHVsc2UubW9kaWZpZXMoJ2luZGV4Jyk7XG4gICAgICBzaW0ubm9kZXMocHVsc2Uuc291cmNlKTtcbiAgICB9XG4gICAgaWYgKHBhcmFtcyB8fCBwdWxzZS5jaGFuZ2VkKHB1bHNlLk1PRCkpIHtcbiAgICAgIHNldHVwKHNpbSwgXywgMCwgcHVsc2UpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHJ1biBzaW11bGF0aW9uXG4gIGlmIChwYXJhbXMgfHwgY2hhbmdlIHx8IF8ubW9kaWZpZWQoRm9yY2VDb25maWcpXG4gICAgICB8fCAocHVsc2UuY2hhbmdlZCgpICYmIF8ucmVzdGFydCkpXG4gIHtcbiAgICBzaW0uYWxwaGEoTWF0aC5tYXgoc2ltLmFscGhhKCksIF8uYWxwaGEgfHwgMSkpXG4gICAgICAgLmFscGhhRGVjYXkoMSAtIE1hdGgucG93KHNpbS5hbHBoYU1pbigpLCAxIC8gaXRlcnMpKTtcblxuICAgIGlmIChfLnN0YXRpYykge1xuICAgICAgZm9yIChzaW0uc3RvcCgpOyAtLWl0ZXJzID49IDA7KSBzaW0udGljaygpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoc2ltLnN0b3BwZWQoKSkgc2ltLnJlc3RhcnQoKTtcbiAgICAgIGlmICghY2hhbmdlKSByZXR1cm4gcHVsc2UuU3RvcFByb3BhZ2F0aW9uOyAvLyBkZWZlciB0byBzaW0gdGlja3NcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdGhpcy5maW5pc2goXywgcHVsc2UpO1xufTtcblxucHJvdG90eXBlJDcwLmZpbmlzaCA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBkYXRhZmxvdyA9IHB1bHNlLmRhdGFmbG93O1xuXG4gIC8vIGluc3BlY3QgZGVwZW5kZW5jaWVzLCB0b3VjaCBsaW5rIHNvdXJjZSBkYXRhXG4gIGZvciAodmFyIGFyZ3M9dGhpcy5fYXJnb3BzLCBqPTAsIG09YXJncy5sZW5ndGgsIGFyZzsgajxtOyArK2opIHtcbiAgICBhcmcgPSBhcmdzW2pdO1xuICAgIGlmIChhcmcubmFtZSAhPT0gRm9yY2VzIHx8IGFyZy5vcC5fYXJndmFsLmZvcmNlICE9PSAnbGluaycpIHtcbiAgICAgIGNvbnRpbnVlO1xuICAgIH1cbiAgICBmb3IgKHZhciBvcHM9YXJnLm9wLl9hcmdvcHMsIGk9MCwgbj1vcHMubGVuZ3RoLCBvcDsgaTxuOyArK2kpIHtcbiAgICAgIGlmIChvcHNbaV0ubmFtZSA9PT0gJ2xpbmtzJyAmJiAob3AgPSBvcHNbaV0ub3Auc291cmNlKSkge1xuICAgICAgICBkYXRhZmxvdy5wdWxzZShvcCwgZGF0YWZsb3cuY2hhbmdlc2V0KCkucmVmbG93KCkpO1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvLyByZWZsb3cgYWxsIG5vZGVzXG4gIHJldHVybiBwdWxzZS5yZWZsb3coXy5tb2RpZmllZCgpKS5tb2RpZmllcyhGb3JjZU91dHB1dCk7XG59O1xuXG5mdW5jdGlvbiByZXJ1bihkZiwgb3ApIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKCkgeyBkZi50b3VjaChvcCkucnVuKCk7IH1cbn1cblxuZnVuY3Rpb24gc2ltdWxhdGlvbihub2RlcywgXykge1xuICB2YXIgc2ltID0gZm9yY2VTaW11bGF0aW9uKG5vZGVzKSxcbiAgICAgIHN0b3BwZWQgPSBmYWxzZSxcbiAgICAgIHN0b3AgPSBzaW0uc3RvcCxcbiAgICAgIHJlc3RhcnQgPSBzaW0ucmVzdGFydDtcblxuICBzaW0uc3RvcHBlZCA9IGZ1bmN0aW9uKCkge1xuICAgIHJldHVybiBzdG9wcGVkO1xuICB9O1xuICBzaW0ucmVzdGFydCA9IGZ1bmN0aW9uKCkge1xuICAgIHN0b3BwZWQgPSBmYWxzZTtcbiAgICByZXR1cm4gcmVzdGFydCgpO1xuICB9O1xuICBzaW0uc3RvcCA9IGZ1bmN0aW9uKCkge1xuICAgIHN0b3BwZWQgPSB0cnVlO1xuICAgIHJldHVybiBzdG9wKCk7XG4gIH07XG5cbiAgcmV0dXJuIHNldHVwKHNpbSwgXywgdHJ1ZSkub24oJ2VuZCcsIGZ1bmN0aW9uKCkgeyBzdG9wcGVkID0gdHJ1ZTsgfSk7XG59XG5cbmZ1bmN0aW9uIHNldHVwKHNpbSwgXywgaW5pdCwgcHVsc2UpIHtcbiAgdmFyIGYgPSBhcnJheShfLmZvcmNlcyksIGksIG4sIHAsIG5hbWU7XG5cbiAgZm9yIChpPTAsIG49Rm9yY2VQYXJhbXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIHAgPSBGb3JjZVBhcmFtc1tpXTtcbiAgICBpZiAocCAhPT0gRm9yY2VzICYmIF8ubW9kaWZpZWQocCkpIHNpbVtwXShfW3BdKTtcbiAgfVxuXG4gIGZvciAoaT0wLCBuPWYubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIG5hbWUgPSBGb3JjZXMgKyBpO1xuICAgIHAgPSBpbml0IHx8IF8ubW9kaWZpZWQoRm9yY2VzLCBpKSA/IGdldEZvcmNlKGZbaV0pXG4gICAgICA6IHB1bHNlICYmIG1vZGlmaWVkKGZbaV0sIHB1bHNlKSA/IHNpbS5mb3JjZShuYW1lKVxuICAgICAgOiBudWxsO1xuICAgIGlmIChwKSBzaW0uZm9yY2UobmFtZSwgcCk7XG4gIH1cblxuICBmb3IgKG49KHNpbS5udW1Gb3JjZXMgfHwgMCk7IGk8bjsgKytpKSB7XG4gICAgc2ltLmZvcmNlKEZvcmNlcyArIGksIG51bGwpOyAvLyByZW1vdmVcbiAgfVxuXG4gIHNpbS5udW1Gb3JjZXMgPSBmLmxlbmd0aDtcbiAgcmV0dXJuIHNpbTtcbn1cblxuZnVuY3Rpb24gbW9kaWZpZWQoZiwgcHVsc2UpIHtcbiAgdmFyIGssIHY7XG4gIGZvciAoayBpbiBmKSB7XG4gICAgaWYgKGlzRnVuY3Rpb24odiA9IGZba10pICYmIHB1bHNlLm1vZGlmaWVkKGFjY2Vzc29yRmllbGRzKHYpKSlcbiAgICAgIHJldHVybiAxO1xuICB9XG4gIHJldHVybiAwO1xufVxuXG5mdW5jdGlvbiBnZXRGb3JjZShfKSB7XG4gIHZhciBmLCBwO1xuXG4gIGlmICghRm9yY2VNYXAuaGFzT3duUHJvcGVydHkoXy5mb3JjZSkpIHtcbiAgICBlcnJvciQxKCdVbnJlY29nbml6ZWQgZm9yY2U6ICcgKyBfLmZvcmNlKTtcbiAgfVxuICBmID0gRm9yY2VNYXBbXy5mb3JjZV0oKTtcblxuICBmb3IgKHAgaW4gXykge1xuICAgIGlmIChpc0Z1bmN0aW9uKGZbcF0pKSBzZXRGb3JjZVBhcmFtKGZbcF0sIF9bcF0sIF8pO1xuICB9XG5cbiAgcmV0dXJuIGY7XG59XG5cbmZ1bmN0aW9uIHNldEZvcmNlUGFyYW0oZiwgdiwgXykge1xuICBmKGlzRnVuY3Rpb24odikgPyBmdW5jdGlvbihkKSB7IHJldHVybiB2KGQsIF8pOyB9IDogdik7XG59XG5cblxuXG52YXIgZm9yY2UgPSBPYmplY3QuZnJlZXplKHtcblx0Zm9yY2U6IEZvcmNlXG59KTtcblxuZnVuY3Rpb24gZGVmYXVsdFNlcGFyYXRpb24oYSwgYikge1xuICByZXR1cm4gYS5wYXJlbnQgPT09IGIucGFyZW50ID8gMSA6IDI7XG59XG5cbmZ1bmN0aW9uIG1lYW5YKGNoaWxkcmVuKSB7XG4gIHJldHVybiBjaGlsZHJlbi5yZWR1Y2UobWVhblhSZWR1Y2UsIDApIC8gY2hpbGRyZW4ubGVuZ3RoO1xufVxuXG5mdW5jdGlvbiBtZWFuWFJlZHVjZSh4LCBjKSB7XG4gIHJldHVybiB4ICsgYy54O1xufVxuXG5mdW5jdGlvbiBtYXhZKGNoaWxkcmVuKSB7XG4gIHJldHVybiAxICsgY2hpbGRyZW4ucmVkdWNlKG1heFlSZWR1Y2UsIDApO1xufVxuXG5mdW5jdGlvbiBtYXhZUmVkdWNlKHksIGMpIHtcbiAgcmV0dXJuIE1hdGgubWF4KHksIGMueSk7XG59XG5cbmZ1bmN0aW9uIGxlYWZMZWZ0KG5vZGUpIHtcbiAgdmFyIGNoaWxkcmVuO1xuICB3aGlsZSAoY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuKSBub2RlID0gY2hpbGRyZW5bMF07XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBsZWFmUmlnaHQobm9kZSkge1xuICB2YXIgY2hpbGRyZW47XG4gIHdoaWxlIChjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4pIG5vZGUgPSBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbnZhciBjbHVzdGVyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzZXBhcmF0aW9uID0gZGVmYXVsdFNlcGFyYXRpb24sXG4gICAgICBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBub2RlU2l6ZSA9IGZhbHNlO1xuXG4gIGZ1bmN0aW9uIGNsdXN0ZXIocm9vdCkge1xuICAgIHZhciBwcmV2aW91c05vZGUsXG4gICAgICAgIHggPSAwO1xuXG4gICAgLy8gRmlyc3Qgd2FsaywgY29tcHV0aW5nIHRoZSBpbml0aWFsIHggJiB5IHZhbHVlcy5cbiAgICByb290LmVhY2hBZnRlcihmdW5jdGlvbihub2RlKSB7XG4gICAgICB2YXIgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgICAgaWYgKGNoaWxkcmVuKSB7XG4gICAgICAgIG5vZGUueCA9IG1lYW5YKGNoaWxkcmVuKTtcbiAgICAgICAgbm9kZS55ID0gbWF4WShjaGlsZHJlbik7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBub2RlLnggPSBwcmV2aW91c05vZGUgPyB4ICs9IHNlcGFyYXRpb24obm9kZSwgcHJldmlvdXNOb2RlKSA6IDA7XG4gICAgICAgIG5vZGUueSA9IDA7XG4gICAgICAgIHByZXZpb3VzTm9kZSA9IG5vZGU7XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICB2YXIgbGVmdCA9IGxlYWZMZWZ0KHJvb3QpLFxuICAgICAgICByaWdodCA9IGxlYWZSaWdodChyb290KSxcbiAgICAgICAgeDAgPSBsZWZ0LnggLSBzZXBhcmF0aW9uKGxlZnQsIHJpZ2h0KSAvIDIsXG4gICAgICAgIHgxID0gcmlnaHQueCArIHNlcGFyYXRpb24ocmlnaHQsIGxlZnQpIC8gMjtcblxuICAgIC8vIFNlY29uZCB3YWxrLCBub3JtYWxpemluZyB4ICYgeSB0byB0aGUgZGVzaXJlZCBzaXplLlxuICAgIHJldHVybiByb290LmVhY2hBZnRlcihub2RlU2l6ZSA/IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgIG5vZGUueCA9IChub2RlLnggLSByb290LngpICogZHg7XG4gICAgICBub2RlLnkgPSAocm9vdC55IC0gbm9kZS55KSAqIGR5O1xuICAgIH0gOiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBub2RlLnggPSAobm9kZS54IC0geDApIC8gKHgxIC0geDApICogZHg7XG4gICAgICBub2RlLnkgPSAoMSAtIChyb290LnkgPyBub2RlLnkgLyByb290LnkgOiAxKSkgKiBkeTtcbiAgICB9KTtcbiAgfVxuXG4gIGNsdXN0ZXIuc2VwYXJhdGlvbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzZXBhcmF0aW9uID0geCwgY2x1c3RlcikgOiBzZXBhcmF0aW9uO1xuICB9O1xuXG4gIGNsdXN0ZXIuc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IGZhbHNlLCBkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCBjbHVzdGVyKSA6IChub2RlU2l6ZSA/IG51bGwgOiBbZHgsIGR5XSk7XG4gIH07XG5cbiAgY2x1c3Rlci5ub2RlU2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IHRydWUsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIGNsdXN0ZXIpIDogKG5vZGVTaXplID8gW2R4LCBkeV0gOiBudWxsKTtcbiAgfTtcblxuICByZXR1cm4gY2x1c3Rlcjtcbn07XG5cbmZ1bmN0aW9uIGNvdW50KG5vZGUpIHtcbiAgdmFyIHN1bSA9IDAsXG4gICAgICBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4sXG4gICAgICBpID0gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoO1xuICBpZiAoIWkpIHN1bSA9IDE7XG4gIGVsc2Ugd2hpbGUgKC0taSA+PSAwKSBzdW0gKz0gY2hpbGRyZW5baV0udmFsdWU7XG4gIG5vZGUudmFsdWUgPSBzdW07XG59XG5cbnZhciBub2RlX2NvdW50ID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLmVhY2hBZnRlcihjb3VudCk7XG59O1xuXG52YXIgbm9kZV9lYWNoID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIG5vZGUgPSB0aGlzLCBjdXJyZW50LCBuZXh0ID0gW25vZGVdLCBjaGlsZHJlbiwgaSwgbjtcbiAgZG8ge1xuICAgIGN1cnJlbnQgPSBuZXh0LnJldmVyc2UoKSwgbmV4dCA9IFtdO1xuICAgIHdoaWxlIChub2RlID0gY3VycmVudC5wb3AoKSkge1xuICAgICAgY2FsbGJhY2sobm9kZSksIGNoaWxkcmVuID0gbm9kZS5jaGlsZHJlbjtcbiAgICAgIGlmIChjaGlsZHJlbikgZm9yIChpID0gMCwgbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgICBuZXh0LnB1c2goY2hpbGRyZW5baV0pO1xuICAgICAgfVxuICAgIH1cbiAgfSB3aGlsZSAobmV4dC5sZW5ndGgpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnZhciBub2RlX2VhY2hCZWZvcmUgPSBmdW5jdGlvbihjYWxsYmFjaykge1xuICB2YXIgbm9kZSA9IHRoaXMsIG5vZGVzID0gW25vZGVdLCBjaGlsZHJlbiwgaTtcbiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkge1xuICAgIGNhbGxiYWNrKG5vZGUpLCBjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW47XG4gICAgaWYgKGNoaWxkcmVuKSBmb3IgKGkgPSBjaGlsZHJlbi5sZW5ndGggLSAxOyBpID49IDA7IC0taSkge1xuICAgICAgbm9kZXMucHVzaChjaGlsZHJlbltpXSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIG5vZGVfZWFjaEFmdGVyID0gZnVuY3Rpb24oY2FsbGJhY2spIHtcbiAgdmFyIG5vZGUgPSB0aGlzLCBub2RlcyA9IFtub2RlXSwgbmV4dCA9IFtdLCBjaGlsZHJlbiwgaSwgbjtcbiAgd2hpbGUgKG5vZGUgPSBub2Rlcy5wb3AoKSkge1xuICAgIG5leHQucHVzaChub2RlKSwgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuO1xuICAgIGlmIChjaGlsZHJlbikgZm9yIChpID0gMCwgbiA9IGNoaWxkcmVuLmxlbmd0aDsgaSA8IG47ICsraSkge1xuICAgICAgbm9kZXMucHVzaChjaGlsZHJlbltpXSk7XG4gICAgfVxuICB9XG4gIHdoaWxlIChub2RlID0gbmV4dC5wb3AoKSkge1xuICAgIGNhbGxiYWNrKG5vZGUpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxudmFyIG5vZGVfc3VtID0gZnVuY3Rpb24odmFsdWUpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaEFmdGVyKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICB2YXIgc3VtID0gK3ZhbHVlKG5vZGUuZGF0YSkgfHwgMCxcbiAgICAgICAgY2hpbGRyZW4gPSBub2RlLmNoaWxkcmVuLFxuICAgICAgICBpID0gY2hpbGRyZW4gJiYgY2hpbGRyZW4ubGVuZ3RoO1xuICAgIHdoaWxlICgtLWkgPj0gMCkgc3VtICs9IGNoaWxkcmVuW2ldLnZhbHVlO1xuICAgIG5vZGUudmFsdWUgPSBzdW07XG4gIH0pO1xufTtcblxudmFyIG5vZGVfc29ydCA9IGZ1bmN0aW9uKGNvbXBhcmUpIHtcbiAgcmV0dXJuIHRoaXMuZWFjaEJlZm9yZShmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIG5vZGUuY2hpbGRyZW4uc29ydChjb21wYXJlKTtcbiAgICB9XG4gIH0pO1xufTtcblxudmFyIG5vZGVfcGF0aCA9IGZ1bmN0aW9uKGVuZCkge1xuICB2YXIgc3RhcnQgPSB0aGlzLFxuICAgICAgYW5jZXN0b3IgPSBsZWFzdENvbW1vbkFuY2VzdG9yKHN0YXJ0LCBlbmQpLFxuICAgICAgbm9kZXMgPSBbc3RhcnRdO1xuICB3aGlsZSAoc3RhcnQgIT09IGFuY2VzdG9yKSB7XG4gICAgc3RhcnQgPSBzdGFydC5wYXJlbnQ7XG4gICAgbm9kZXMucHVzaChzdGFydCk7XG4gIH1cbiAgdmFyIGsgPSBub2Rlcy5sZW5ndGg7XG4gIHdoaWxlIChlbmQgIT09IGFuY2VzdG9yKSB7XG4gICAgbm9kZXMuc3BsaWNlKGssIDAsIGVuZCk7XG4gICAgZW5kID0gZW5kLnBhcmVudDtcbiAgfVxuICByZXR1cm4gbm9kZXM7XG59O1xuXG5mdW5jdGlvbiBsZWFzdENvbW1vbkFuY2VzdG9yKGEsIGIpIHtcbiAgaWYgKGEgPT09IGIpIHJldHVybiBhO1xuICB2YXIgYU5vZGVzID0gYS5hbmNlc3RvcnMoKSxcbiAgICAgIGJOb2RlcyA9IGIuYW5jZXN0b3JzKCksXG4gICAgICBjID0gbnVsbDtcbiAgYSA9IGFOb2Rlcy5wb3AoKTtcbiAgYiA9IGJOb2Rlcy5wb3AoKTtcbiAgd2hpbGUgKGEgPT09IGIpIHtcbiAgICBjID0gYTtcbiAgICBhID0gYU5vZGVzLnBvcCgpO1xuICAgIGIgPSBiTm9kZXMucG9wKCk7XG4gIH1cbiAgcmV0dXJuIGM7XG59XG5cbnZhciBub2RlX2FuY2VzdG9ycyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZSA9IHRoaXMsIG5vZGVzID0gW25vZGVdO1xuICB3aGlsZSAobm9kZSA9IG5vZGUucGFyZW50KSB7XG4gICAgbm9kZXMucHVzaChub2RlKTtcbiAgfVxuICByZXR1cm4gbm9kZXM7XG59O1xuXG52YXIgbm9kZV9kZXNjZW5kYW50cyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgbm9kZXMgPSBbXTtcbiAgdGhpcy5lYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBub2Rlcy5wdXNoKG5vZGUpO1xuICB9KTtcbiAgcmV0dXJuIG5vZGVzO1xufTtcblxudmFyIG5vZGVfbGVhdmVzID0gZnVuY3Rpb24oKSB7XG4gIHZhciBsZWF2ZXMgPSBbXTtcbiAgdGhpcy5lYWNoQmVmb3JlKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIGxlYXZlcy5wdXNoKG5vZGUpO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBsZWF2ZXM7XG59O1xuXG52YXIgbm9kZV9saW5rcyA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcm9vdCA9IHRoaXMsIGxpbmtzID0gW107XG4gIHJvb3QuZWFjaChmdW5jdGlvbihub2RlKSB7XG4gICAgaWYgKG5vZGUgIT09IHJvb3QpIHsgLy8gRG9u4oCZdCBpbmNsdWRlIHRoZSByb2904oCZcyBwYXJlbnQsIGlmIGFueS5cbiAgICAgIGxpbmtzLnB1c2goe3NvdXJjZTogbm9kZS5wYXJlbnQsIHRhcmdldDogbm9kZX0pO1xuICAgIH1cbiAgfSk7XG4gIHJldHVybiBsaW5rcztcbn07XG5cbmZ1bmN0aW9uIGhpZXJhcmNoeShkYXRhLCBjaGlsZHJlbikge1xuICB2YXIgcm9vdCA9IG5ldyBOb2RlKGRhdGEpLFxuICAgICAgdmFsdWVkID0gK2RhdGEudmFsdWUgJiYgKHJvb3QudmFsdWUgPSBkYXRhLnZhbHVlKSxcbiAgICAgIG5vZGUsXG4gICAgICBub2RlcyA9IFtyb290XSxcbiAgICAgIGNoaWxkLFxuICAgICAgY2hpbGRzLFxuICAgICAgaSxcbiAgICAgIG47XG5cbiAgaWYgKGNoaWxkcmVuID09IG51bGwpIGNoaWxkcmVuID0gZGVmYXVsdENoaWxkcmVuO1xuXG4gIHdoaWxlIChub2RlID0gbm9kZXMucG9wKCkpIHtcbiAgICBpZiAodmFsdWVkKSBub2RlLnZhbHVlID0gK25vZGUuZGF0YS52YWx1ZTtcbiAgICBpZiAoKGNoaWxkcyA9IGNoaWxkcmVuKG5vZGUuZGF0YSkpICYmIChuID0gY2hpbGRzLmxlbmd0aCkpIHtcbiAgICAgIG5vZGUuY2hpbGRyZW4gPSBuZXcgQXJyYXkobik7XG4gICAgICBmb3IgKGkgPSBuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgbm9kZXMucHVzaChjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV0gPSBuZXcgTm9kZShjaGlsZHNbaV0pKTtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gbm9kZTtcbiAgICAgICAgY2hpbGQuZGVwdGggPSBub2RlLmRlcHRoICsgMTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICByZXR1cm4gcm9vdC5lYWNoQmVmb3JlKGNvbXB1dGVIZWlnaHQpO1xufVxuXG5mdW5jdGlvbiBub2RlX2NvcHkoKSB7XG4gIHJldHVybiBoaWVyYXJjaHkodGhpcykuZWFjaEJlZm9yZShjb3B5RGF0YSk7XG59XG5cbmZ1bmN0aW9uIGRlZmF1bHRDaGlsZHJlbihkKSB7XG4gIHJldHVybiBkLmNoaWxkcmVuO1xufVxuXG5mdW5jdGlvbiBjb3B5RGF0YShub2RlKSB7XG4gIG5vZGUuZGF0YSA9IG5vZGUuZGF0YS5kYXRhO1xufVxuXG5mdW5jdGlvbiBjb21wdXRlSGVpZ2h0KG5vZGUpIHtcbiAgdmFyIGhlaWdodCA9IDA7XG4gIGRvIG5vZGUuaGVpZ2h0ID0gaGVpZ2h0O1xuICB3aGlsZSAoKG5vZGUgPSBub2RlLnBhcmVudCkgJiYgKG5vZGUuaGVpZ2h0IDwgKytoZWlnaHQpKTtcbn1cblxuZnVuY3Rpb24gTm9kZShkYXRhKSB7XG4gIHRoaXMuZGF0YSA9IGRhdGE7XG4gIHRoaXMuZGVwdGggPVxuICB0aGlzLmhlaWdodCA9IDA7XG4gIHRoaXMucGFyZW50ID0gbnVsbDtcbn1cblxuTm9kZS5wcm90b3R5cGUgPSBoaWVyYXJjaHkucHJvdG90eXBlID0ge1xuICBjb25zdHJ1Y3RvcjogTm9kZSxcbiAgY291bnQ6IG5vZGVfY291bnQsXG4gIGVhY2g6IG5vZGVfZWFjaCxcbiAgZWFjaEFmdGVyOiBub2RlX2VhY2hBZnRlcixcbiAgZWFjaEJlZm9yZTogbm9kZV9lYWNoQmVmb3JlLFxuICBzdW06IG5vZGVfc3VtLFxuICBzb3J0OiBub2RlX3NvcnQsXG4gIHBhdGg6IG5vZGVfcGF0aCxcbiAgYW5jZXN0b3JzOiBub2RlX2FuY2VzdG9ycyxcbiAgZGVzY2VuZGFudHM6IG5vZGVfZGVzY2VuZGFudHMsXG4gIGxlYXZlczogbm9kZV9sZWF2ZXMsXG4gIGxpbmtzOiBub2RlX2xpbmtzLFxuICBjb3B5OiBub2RlX2NvcHlcbn07XG5cbnZhciBzbGljZSQ1ID0gQXJyYXkucHJvdG90eXBlLnNsaWNlO1xuXG5mdW5jdGlvbiBzaHVmZmxlJDEoYXJyYXkpIHtcbiAgdmFyIG0gPSBhcnJheS5sZW5ndGgsXG4gICAgICB0LFxuICAgICAgaTtcblxuICB3aGlsZSAobSkge1xuICAgIGkgPSBNYXRoLnJhbmRvbSgpICogbS0tIHwgMDtcbiAgICB0ID0gYXJyYXlbbV07XG4gICAgYXJyYXlbbV0gPSBhcnJheVtpXTtcbiAgICBhcnJheVtpXSA9IHQ7XG4gIH1cblxuICByZXR1cm4gYXJyYXk7XG59XG5cbnZhciBlbmNsb3NlID0gZnVuY3Rpb24oY2lyY2xlcykge1xuICB2YXIgaSA9IDAsIG4gPSAoY2lyY2xlcyA9IHNodWZmbGUkMShzbGljZSQ1LmNhbGwoY2lyY2xlcykpKS5sZW5ndGgsIEIgPSBbXSwgcCwgZTtcblxuICB3aGlsZSAoaSA8IG4pIHtcbiAgICBwID0gY2lyY2xlc1tpXTtcbiAgICBpZiAoZSAmJiBlbmNsb3Nlc1dlYWsoZSwgcCkpICsraTtcbiAgICBlbHNlIGUgPSBlbmNsb3NlQmFzaXMoQiA9IGV4dGVuZEJhc2lzKEIsIHApKSwgaSA9IDA7XG4gIH1cblxuICByZXR1cm4gZTtcbn07XG5cbmZ1bmN0aW9uIGV4dGVuZEJhc2lzKEIsIHApIHtcbiAgdmFyIGksIGo7XG5cbiAgaWYgKGVuY2xvc2VzV2Vha0FsbChwLCBCKSkgcmV0dXJuIFtwXTtcblxuICAvLyBJZiB3ZSBnZXQgaGVyZSB0aGVuIEIgbXVzdCBoYXZlIGF0IGxlYXN0IG9uZSBlbGVtZW50LlxuICBmb3IgKGkgPSAwOyBpIDwgQi5sZW5ndGg7ICsraSkge1xuICAgIGlmIChlbmNsb3Nlc05vdChwLCBCW2ldKVxuICAgICAgICAmJiBlbmNsb3Nlc1dlYWtBbGwoZW5jbG9zZUJhc2lzMihCW2ldLCBwKSwgQikpIHtcbiAgICAgIHJldHVybiBbQltpXSwgcF07XG4gICAgfVxuICB9XG5cbiAgLy8gSWYgd2UgZ2V0IGhlcmUgdGhlbiBCIG11c3QgaGF2ZSBhdCBsZWFzdCB0d28gZWxlbWVudHMuXG4gIGZvciAoaSA9IDA7IGkgPCBCLmxlbmd0aCAtIDE7ICsraSkge1xuICAgIGZvciAoaiA9IGkgKyAxOyBqIDwgQi5sZW5ndGg7ICsraikge1xuICAgICAgaWYgKGVuY2xvc2VzTm90KGVuY2xvc2VCYXNpczIoQltpXSwgQltqXSksIHApXG4gICAgICAgICAgJiYgZW5jbG9zZXNOb3QoZW5jbG9zZUJhc2lzMihCW2ldLCBwKSwgQltqXSlcbiAgICAgICAgICAmJiBlbmNsb3Nlc05vdChlbmNsb3NlQmFzaXMyKEJbal0sIHApLCBCW2ldKVxuICAgICAgICAgICYmIGVuY2xvc2VzV2Vha0FsbChlbmNsb3NlQmFzaXMzKEJbaV0sIEJbal0sIHApLCBCKSkge1xuICAgICAgICByZXR1cm4gW0JbaV0sIEJbal0sIHBdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIC8vIElmIHdlIGdldCBoZXJlIHRoZW4gc29tZXRoaW5nIGlzIHZlcnkgd3JvbmcuXG4gIHRocm93IG5ldyBFcnJvcjtcbn1cblxuZnVuY3Rpb24gZW5jbG9zZXNOb3QoYSwgYikge1xuICB2YXIgZHIgPSBhLnIgLSBiLnIsIGR4ID0gYi54IC0gYS54LCBkeSA9IGIueSAtIGEueTtcbiAgcmV0dXJuIGRyIDwgMCB8fCBkciAqIGRyIDwgZHggKiBkeCArIGR5ICogZHk7XG59XG5cbmZ1bmN0aW9uIGVuY2xvc2VzV2VhayhhLCBiKSB7XG4gIHZhciBkciA9IGEuciAtIGIuciArIDFlLTYsIGR4ID0gYi54IC0gYS54LCBkeSA9IGIueSAtIGEueTtcbiAgcmV0dXJuIGRyID4gMCAmJiBkciAqIGRyID4gZHggKiBkeCArIGR5ICogZHk7XG59XG5cbmZ1bmN0aW9uIGVuY2xvc2VzV2Vha0FsbChhLCBCKSB7XG4gIGZvciAodmFyIGkgPSAwOyBpIDwgQi5sZW5ndGg7ICsraSkge1xuICAgIGlmICghZW5jbG9zZXNXZWFrKGEsIEJbaV0pKSB7XG4gICAgICByZXR1cm4gZmFsc2U7XG4gICAgfVxuICB9XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBlbmNsb3NlQmFzaXMoQikge1xuICBzd2l0Y2ggKEIubGVuZ3RoKSB7XG4gICAgY2FzZSAxOiByZXR1cm4gZW5jbG9zZUJhc2lzMShCWzBdKTtcbiAgICBjYXNlIDI6IHJldHVybiBlbmNsb3NlQmFzaXMyKEJbMF0sIEJbMV0pO1xuICAgIGNhc2UgMzogcmV0dXJuIGVuY2xvc2VCYXNpczMoQlswXSwgQlsxXSwgQlsyXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gZW5jbG9zZUJhc2lzMShhKSB7XG4gIHJldHVybiB7XG4gICAgeDogYS54LFxuICAgIHk6IGEueSxcbiAgICByOiBhLnJcbiAgfTtcbn1cblxuZnVuY3Rpb24gZW5jbG9zZUJhc2lzMihhLCBiKSB7XG4gIHZhciB4MSA9IGEueCwgeTEgPSBhLnksIHIxID0gYS5yLFxuICAgICAgeDIgPSBiLngsIHkyID0gYi55LCByMiA9IGIucixcbiAgICAgIHgyMSA9IHgyIC0geDEsIHkyMSA9IHkyIC0geTEsIHIyMSA9IHIyIC0gcjEsXG4gICAgICBsID0gTWF0aC5zcXJ0KHgyMSAqIHgyMSArIHkyMSAqIHkyMSk7XG4gIHJldHVybiB7XG4gICAgeDogKHgxICsgeDIgKyB4MjEgLyBsICogcjIxKSAvIDIsXG4gICAgeTogKHkxICsgeTIgKyB5MjEgLyBsICogcjIxKSAvIDIsXG4gICAgcjogKGwgKyByMSArIHIyKSAvIDJcbiAgfTtcbn1cblxuZnVuY3Rpb24gZW5jbG9zZUJhc2lzMyhhLCBiLCBjKSB7XG4gIHZhciB4MSA9IGEueCwgeTEgPSBhLnksIHIxID0gYS5yLFxuICAgICAgeDIgPSBiLngsIHkyID0gYi55LCByMiA9IGIucixcbiAgICAgIHgzID0gYy54LCB5MyA9IGMueSwgcjMgPSBjLnIsXG4gICAgICBhMiA9IHgxIC0geDIsXG4gICAgICBhMyA9IHgxIC0geDMsXG4gICAgICBiMiA9IHkxIC0geTIsXG4gICAgICBiMyA9IHkxIC0geTMsXG4gICAgICBjMiA9IHIyIC0gcjEsXG4gICAgICBjMyA9IHIzIC0gcjEsXG4gICAgICBkMSA9IHgxICogeDEgKyB5MSAqIHkxIC0gcjEgKiByMSxcbiAgICAgIGQyID0gZDEgLSB4MiAqIHgyIC0geTIgKiB5MiArIHIyICogcjIsXG4gICAgICBkMyA9IGQxIC0geDMgKiB4MyAtIHkzICogeTMgKyByMyAqIHIzLFxuICAgICAgYWIgPSBhMyAqIGIyIC0gYTIgKiBiMyxcbiAgICAgIHhhID0gKGIyICogZDMgLSBiMyAqIGQyKSAvIChhYiAqIDIpIC0geDEsXG4gICAgICB4YiA9IChiMyAqIGMyIC0gYjIgKiBjMykgLyBhYixcbiAgICAgIHlhID0gKGEzICogZDIgLSBhMiAqIGQzKSAvIChhYiAqIDIpIC0geTEsXG4gICAgICB5YiA9IChhMiAqIGMzIC0gYTMgKiBjMikgLyBhYixcbiAgICAgIEEgPSB4YiAqIHhiICsgeWIgKiB5YiAtIDEsXG4gICAgICBCID0gMiAqIChyMSArIHhhICogeGIgKyB5YSAqIHliKSxcbiAgICAgIEMgPSB4YSAqIHhhICsgeWEgKiB5YSAtIHIxICogcjEsXG4gICAgICByID0gLShBID8gKEIgKyBNYXRoLnNxcnQoQiAqIEIgLSA0ICogQSAqIEMpKSAvICgyICogQSkgOiBDIC8gQik7XG4gIHJldHVybiB7XG4gICAgeDogeDEgKyB4YSArIHhiICogcixcbiAgICB5OiB5MSArIHlhICsgeWIgKiByLFxuICAgIHI6IHJcbiAgfTtcbn1cblxuZnVuY3Rpb24gcGxhY2UoYSwgYiwgYykge1xuICB2YXIgYXggPSBhLngsXG4gICAgICBheSA9IGEueSxcbiAgICAgIGRhID0gYi5yICsgYy5yLFxuICAgICAgZGIgPSBhLnIgKyBjLnIsXG4gICAgICBkeCA9IGIueCAtIGF4LFxuICAgICAgZHkgPSBiLnkgLSBheSxcbiAgICAgIGRjID0gZHggKiBkeCArIGR5ICogZHk7XG4gIGlmIChkYykge1xuICAgIHZhciB4ID0gMC41ICsgKChkYiAqPSBkYikgLSAoZGEgKj0gZGEpKSAvICgyICogZGMpLFxuICAgICAgICB5ID0gTWF0aC5zcXJ0KE1hdGgubWF4KDAsIDIgKiBkYSAqIChkYiArIGRjKSAtIChkYiAtPSBkYykgKiBkYiAtIGRhICogZGEpKSAvICgyICogZGMpO1xuICAgIGMueCA9IGF4ICsgeCAqIGR4ICsgeSAqIGR5O1xuICAgIGMueSA9IGF5ICsgeCAqIGR5IC0geSAqIGR4O1xuICB9IGVsc2Uge1xuICAgIGMueCA9IGF4ICsgZGI7XG4gICAgYy55ID0gYXk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW50ZXJzZWN0cyhhLCBiKSB7XG4gIHZhciBkeCA9IGIueCAtIGEueCxcbiAgICAgIGR5ID0gYi55IC0gYS55LFxuICAgICAgZHIgPSBhLnIgKyBiLnI7XG4gIHJldHVybiBkciAqIGRyIC0gMWUtNiA+IGR4ICogZHggKyBkeSAqIGR5O1xufVxuXG5mdW5jdGlvbiBzY29yZShub2RlKSB7XG4gIHZhciBhID0gbm9kZS5fLFxuICAgICAgYiA9IG5vZGUubmV4dC5fLFxuICAgICAgYWIgPSBhLnIgKyBiLnIsXG4gICAgICBkeCA9IChhLnggKiBiLnIgKyBiLnggKiBhLnIpIC8gYWIsXG4gICAgICBkeSA9IChhLnkgKiBiLnIgKyBiLnkgKiBhLnIpIC8gYWI7XG4gIHJldHVybiBkeCAqIGR4ICsgZHkgKiBkeTtcbn1cblxuZnVuY3Rpb24gTm9kZSQxKGNpcmNsZSkge1xuICB0aGlzLl8gPSBjaXJjbGU7XG4gIHRoaXMubmV4dCA9IG51bGw7XG4gIHRoaXMucHJldmlvdXMgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBwYWNrRW5jbG9zZShjaXJjbGVzKSB7XG4gIGlmICghKG4gPSBjaXJjbGVzLmxlbmd0aCkpIHJldHVybiAwO1xuXG4gIHZhciBhLCBiLCBjLCBuLCBhYSwgY2EsIGksIGosIGssIHNqLCBzaztcblxuICAvLyBQbGFjZSB0aGUgZmlyc3QgY2lyY2xlLlxuICBhID0gY2lyY2xlc1swXSwgYS54ID0gMCwgYS55ID0gMDtcbiAgaWYgKCEobiA+IDEpKSByZXR1cm4gYS5yO1xuXG4gIC8vIFBsYWNlIHRoZSBzZWNvbmQgY2lyY2xlLlxuICBiID0gY2lyY2xlc1sxXSwgYS54ID0gLWIuciwgYi54ID0gYS5yLCBiLnkgPSAwO1xuICBpZiAoIShuID4gMikpIHJldHVybiBhLnIgKyBiLnI7XG5cbiAgLy8gUGxhY2UgdGhlIHRoaXJkIGNpcmNsZS5cbiAgcGxhY2UoYiwgYSwgYyA9IGNpcmNsZXNbMl0pO1xuXG4gIC8vIEluaXRpYWxpemUgdGhlIGZyb250LWNoYWluIHVzaW5nIHRoZSBmaXJzdCB0aHJlZSBjaXJjbGVzIGEsIGIgYW5kIGMuXG4gIGEgPSBuZXcgTm9kZSQxKGEpLCBiID0gbmV3IE5vZGUkMShiKSwgYyA9IG5ldyBOb2RlJDEoYyk7XG4gIGEubmV4dCA9IGMucHJldmlvdXMgPSBiO1xuICBiLm5leHQgPSBhLnByZXZpb3VzID0gYztcbiAgYy5uZXh0ID0gYi5wcmV2aW91cyA9IGE7XG5cbiAgLy8gQXR0ZW1wdCB0byBwbGFjZSBlYWNoIHJlbWFpbmluZyBjaXJjbGXigKZcbiAgcGFjazogZm9yIChpID0gMzsgaSA8IG47ICsraSkge1xuICAgIHBsYWNlKGEuXywgYi5fLCBjID0gY2lyY2xlc1tpXSksIGMgPSBuZXcgTm9kZSQxKGMpO1xuXG4gICAgLy8gRmluZCB0aGUgY2xvc2VzdCBpbnRlcnNlY3RpbmcgY2lyY2xlIG9uIHRoZSBmcm9udC1jaGFpbiwgaWYgYW55LlxuICAgIC8vIOKAnENsb3NlbmVzc+KAnSBpcyBkZXRlcm1pbmVkIGJ5IGxpbmVhciBkaXN0YW5jZSBhbG9uZyB0aGUgZnJvbnQtY2hhaW4uXG4gICAgLy8g4oCcQWhlYWTigJ0gb3Ig4oCcYmVoaW5k4oCdIGlzIGxpa2V3aXNlIGRldGVybWluZWQgYnkgbGluZWFyIGRpc3RhbmNlLlxuICAgIGogPSBiLm5leHQsIGsgPSBhLnByZXZpb3VzLCBzaiA9IGIuXy5yLCBzayA9IGEuXy5yO1xuICAgIGRvIHtcbiAgICAgIGlmIChzaiA8PSBzaykge1xuICAgICAgICBpZiAoaW50ZXJzZWN0cyhqLl8sIGMuXykpIHtcbiAgICAgICAgICBiID0gaiwgYS5uZXh0ID0gYiwgYi5wcmV2aW91cyA9IGEsIC0taTtcbiAgICAgICAgICBjb250aW51ZSBwYWNrO1xuICAgICAgICB9XG4gICAgICAgIHNqICs9IGouXy5yLCBqID0gai5uZXh0O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKGludGVyc2VjdHMoay5fLCBjLl8pKSB7XG4gICAgICAgICAgYSA9IGssIGEubmV4dCA9IGIsIGIucHJldmlvdXMgPSBhLCAtLWk7XG4gICAgICAgICAgY29udGludWUgcGFjaztcbiAgICAgICAgfVxuICAgICAgICBzayArPSBrLl8uciwgayA9IGsucHJldmlvdXM7XG4gICAgICB9XG4gICAgfSB3aGlsZSAoaiAhPT0gay5uZXh0KTtcblxuICAgIC8vIFN1Y2Nlc3MhIEluc2VydCB0aGUgbmV3IGNpcmNsZSBjIGJldHdlZW4gYSBhbmQgYi5cbiAgICBjLnByZXZpb3VzID0gYSwgYy5uZXh0ID0gYiwgYS5uZXh0ID0gYi5wcmV2aW91cyA9IGIgPSBjO1xuXG4gICAgLy8gQ29tcHV0ZSB0aGUgbmV3IGNsb3Nlc3QgY2lyY2xlIHBhaXIgdG8gdGhlIGNlbnRyb2lkLlxuICAgIGFhID0gc2NvcmUoYSk7XG4gICAgd2hpbGUgKChjID0gYy5uZXh0KSAhPT0gYikge1xuICAgICAgaWYgKChjYSA9IHNjb3JlKGMpKSA8IGFhKSB7XG4gICAgICAgIGEgPSBjLCBhYSA9IGNhO1xuICAgICAgfVxuICAgIH1cbiAgICBiID0gYS5uZXh0O1xuICB9XG5cbiAgLy8gQ29tcHV0ZSB0aGUgZW5jbG9zaW5nIGNpcmNsZSBvZiB0aGUgZnJvbnQgY2hhaW4uXG4gIGEgPSBbYi5fXSwgYyA9IGI7IHdoaWxlICgoYyA9IGMubmV4dCkgIT09IGIpIGEucHVzaChjLl8pOyBjID0gZW5jbG9zZShhKTtcblxuICAvLyBUcmFuc2xhdGUgdGhlIGNpcmNsZXMgdG8gcHV0IHRoZSBlbmNsb3NpbmcgY2lyY2xlIGFyb3VuZCB0aGUgb3JpZ2luLlxuICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSBhID0gY2lyY2xlc1tpXSwgYS54IC09IGMueCwgYS55IC09IGMueTtcblxuICByZXR1cm4gYy5yO1xufVxuXG5mdW5jdGlvbiBvcHRpb25hbChmKSB7XG4gIHJldHVybiBmID09IG51bGwgPyBudWxsIDogcmVxdWlyZWQoZik7XG59XG5cbmZ1bmN0aW9uIHJlcXVpcmVkKGYpIHtcbiAgaWYgKHR5cGVvZiBmICE9PSBcImZ1bmN0aW9uXCIpIHRocm93IG5ldyBFcnJvcjtcbiAgcmV0dXJuIGY7XG59XG5cbmZ1bmN0aW9uIGNvbnN0YW50WmVybygpIHtcbiAgcmV0dXJuIDA7XG59XG5cbnZhciBjb25zdGFudCQ5ID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG5mdW5jdGlvbiBkZWZhdWx0UmFkaXVzKGQpIHtcbiAgcmV0dXJuIE1hdGguc3FydChkLnZhbHVlKTtcbn1cblxudmFyIHBhY2skMSA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcmFkaXVzID0gbnVsbCxcbiAgICAgIGR4ID0gMSxcbiAgICAgIGR5ID0gMSxcbiAgICAgIHBhZGRpbmcgPSBjb25zdGFudFplcm87XG5cbiAgZnVuY3Rpb24gcGFjayhyb290KSB7XG4gICAgcm9vdC54ID0gZHggLyAyLCByb290LnkgPSBkeSAvIDI7XG4gICAgaWYgKHJhZGl1cykge1xuICAgICAgcm9vdC5lYWNoQmVmb3JlKHJhZGl1c0xlYWYocmFkaXVzKSlcbiAgICAgICAgICAuZWFjaEFmdGVyKHBhY2tDaGlsZHJlbihwYWRkaW5nLCAwLjUpKVxuICAgICAgICAgIC5lYWNoQmVmb3JlKHRyYW5zbGF0ZUNoaWxkKDEpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgcm9vdC5lYWNoQmVmb3JlKHJhZGl1c0xlYWYoZGVmYXVsdFJhZGl1cykpXG4gICAgICAgICAgLmVhY2hBZnRlcihwYWNrQ2hpbGRyZW4oY29uc3RhbnRaZXJvLCAxKSlcbiAgICAgICAgICAuZWFjaEFmdGVyKHBhY2tDaGlsZHJlbihwYWRkaW5nLCByb290LnIgLyBNYXRoLm1pbihkeCwgZHkpKSlcbiAgICAgICAgICAuZWFjaEJlZm9yZSh0cmFuc2xhdGVDaGlsZChNYXRoLm1pbihkeCwgZHkpIC8gKDIgKiByb290LnIpKSk7XG4gICAgfVxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgcGFjay5yYWRpdXMgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocmFkaXVzID0gb3B0aW9uYWwoeCksIHBhY2spIDogcmFkaXVzO1xuICB9O1xuXG4gIHBhY2suc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCBwYWNrKSA6IFtkeCwgZHldO1xuICB9O1xuXG4gIHBhY2sucGFkZGluZyA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ5KCt4KSwgcGFjaykgOiBwYWRkaW5nO1xuICB9O1xuXG4gIHJldHVybiBwYWNrO1xufTtcblxuZnVuY3Rpb24gcmFkaXVzTGVhZihyYWRpdXMpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAoIW5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIG5vZGUuciA9IE1hdGgubWF4KDAsICtyYWRpdXMobm9kZSkgfHwgMCk7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiBwYWNrQ2hpbGRyZW4ocGFkZGluZywgaykge1xuICByZXR1cm4gZnVuY3Rpb24obm9kZSkge1xuICAgIGlmIChjaGlsZHJlbiA9IG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgIHZhciBjaGlsZHJlbixcbiAgICAgICAgICBpLFxuICAgICAgICAgIG4gPSBjaGlsZHJlbi5sZW5ndGgsXG4gICAgICAgICAgciA9IHBhZGRpbmcobm9kZSkgKiBrIHx8IDAsXG4gICAgICAgICAgZTtcblxuICAgICAgaWYgKHIpIGZvciAoaSA9IDA7IGkgPCBuOyArK2kpIGNoaWxkcmVuW2ldLnIgKz0gcjtcbiAgICAgIGUgPSBwYWNrRW5jbG9zZShjaGlsZHJlbik7XG4gICAgICBpZiAocikgZm9yIChpID0gMDsgaSA8IG47ICsraSkgY2hpbGRyZW5baV0uciAtPSByO1xuICAgICAgbm9kZS5yID0gZSArIHI7XG4gICAgfVxuICB9O1xufVxuXG5mdW5jdGlvbiB0cmFuc2xhdGVDaGlsZChrKSB7XG4gIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgdmFyIHBhcmVudCA9IG5vZGUucGFyZW50O1xuICAgIG5vZGUuciAqPSBrO1xuICAgIGlmIChwYXJlbnQpIHtcbiAgICAgIG5vZGUueCA9IHBhcmVudC54ICsgayAqIG5vZGUueDtcbiAgICAgIG5vZGUueSA9IHBhcmVudC55ICsgayAqIG5vZGUueTtcbiAgICB9XG4gIH07XG59XG5cbnZhciByb3VuZE5vZGUgPSBmdW5jdGlvbihub2RlKSB7XG4gIG5vZGUueDAgPSBNYXRoLnJvdW5kKG5vZGUueDApO1xuICBub2RlLnkwID0gTWF0aC5yb3VuZChub2RlLnkwKTtcbiAgbm9kZS54MSA9IE1hdGgucm91bmQobm9kZS54MSk7XG4gIG5vZGUueTEgPSBNYXRoLnJvdW5kKG5vZGUueTEpO1xufTtcblxudmFyIHRyZWVtYXBEaWNlID0gZnVuY3Rpb24ocGFyZW50LCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sXG4gICAgICBub2RlLFxuICAgICAgaSA9IC0xLFxuICAgICAgbiA9IG5vZGVzLmxlbmd0aCxcbiAgICAgIGsgPSBwYXJlbnQudmFsdWUgJiYgKHgxIC0geDApIC8gcGFyZW50LnZhbHVlO1xuXG4gIHdoaWxlICgrK2kgPCBuKSB7XG4gICAgbm9kZSA9IG5vZGVzW2ldLCBub2RlLnkwID0geTAsIG5vZGUueTEgPSB5MTtcbiAgICBub2RlLngwID0geDAsIG5vZGUueDEgPSB4MCArPSBub2RlLnZhbHVlICogaztcbiAgfVxufTtcblxudmFyIHBhcnRpdGlvbiQyID0gZnVuY3Rpb24oKSB7XG4gIHZhciBkeCA9IDEsXG4gICAgICBkeSA9IDEsXG4gICAgICBwYWRkaW5nID0gMCxcbiAgICAgIHJvdW5kID0gZmFsc2U7XG5cbiAgZnVuY3Rpb24gcGFydGl0aW9uKHJvb3QpIHtcbiAgICB2YXIgbiA9IHJvb3QuaGVpZ2h0ICsgMTtcbiAgICByb290LngwID1cbiAgICByb290LnkwID0gcGFkZGluZztcbiAgICByb290LngxID0gZHg7XG4gICAgcm9vdC55MSA9IGR5IC8gbjtcbiAgICByb290LmVhY2hCZWZvcmUocG9zaXRpb25Ob2RlKGR5LCBuKSk7XG4gICAgaWYgKHJvdW5kKSByb290LmVhY2hCZWZvcmUocm91bmROb2RlKTtcbiAgICByZXR1cm4gcm9vdDtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBvc2l0aW9uTm9kZShkeSwgbikge1xuICAgIHJldHVybiBmdW5jdGlvbihub2RlKSB7XG4gICAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgICB0cmVlbWFwRGljZShub2RlLCBub2RlLngwLCBkeSAqIChub2RlLmRlcHRoICsgMSkgLyBuLCBub2RlLngxLCBkeSAqIChub2RlLmRlcHRoICsgMikgLyBuKTtcbiAgICAgIH1cbiAgICAgIHZhciB4MCA9IG5vZGUueDAsXG4gICAgICAgICAgeTAgPSBub2RlLnkwLFxuICAgICAgICAgIHgxID0gbm9kZS54MSAtIHBhZGRpbmcsXG4gICAgICAgICAgeTEgPSBub2RlLnkxIC0gcGFkZGluZztcbiAgICAgIGlmICh4MSA8IHgwKSB4MCA9IHgxID0gKHgwICsgeDEpIC8gMjtcbiAgICAgIGlmICh5MSA8IHkwKSB5MCA9IHkxID0gKHkwICsgeTEpIC8gMjtcbiAgICAgIG5vZGUueDAgPSB4MDtcbiAgICAgIG5vZGUueTAgPSB5MDtcbiAgICAgIG5vZGUueDEgPSB4MTtcbiAgICAgIG5vZGUueTEgPSB5MTtcbiAgICB9O1xuICB9XG5cbiAgcGFydGl0aW9uLnJvdW5kID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJvdW5kID0gISF4LCBwYXJ0aXRpb24pIDogcm91bmQ7XG4gIH07XG5cbiAgcGFydGl0aW9uLnNpemUgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZHggPSAreFswXSwgZHkgPSAreFsxXSwgcGFydGl0aW9uKSA6IFtkeCwgZHldO1xuICB9O1xuXG4gIHBhcnRpdGlvbi5wYWRkaW5nID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmcgPSAreCwgcGFydGl0aW9uKSA6IHBhZGRpbmc7XG4gIH07XG5cbiAgcmV0dXJuIHBhcnRpdGlvbjtcbn07XG5cbnZhciBrZXlQcmVmaXggPSBcIiRcIjtcbnZhciBwcmVyb290ID0ge2RlcHRoOiAtMX07XG52YXIgYW1iaWd1b3VzID0ge307XG5cbmZ1bmN0aW9uIGRlZmF1bHRJZChkKSB7XG4gIHJldHVybiBkLmlkO1xufVxuXG5mdW5jdGlvbiBkZWZhdWx0UGFyZW50SWQoZCkge1xuICByZXR1cm4gZC5wYXJlbnRJZDtcbn1cblxudmFyIHN0cmF0aWZ5ID0gZnVuY3Rpb24oKSB7XG4gIHZhciBpZCA9IGRlZmF1bHRJZCxcbiAgICAgIHBhcmVudElkID0gZGVmYXVsdFBhcmVudElkO1xuXG4gIGZ1bmN0aW9uIHN0cmF0aWZ5KGRhdGEpIHtcbiAgICB2YXIgZCxcbiAgICAgICAgaSxcbiAgICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgICByb290LFxuICAgICAgICBwYXJlbnQsXG4gICAgICAgIG5vZGUsXG4gICAgICAgIG5vZGVzID0gbmV3IEFycmF5KG4pLFxuICAgICAgICBub2RlSWQsXG4gICAgICAgIG5vZGVLZXksXG4gICAgICAgIG5vZGVCeUtleSA9IHt9O1xuXG4gICAgZm9yIChpID0gMDsgaSA8IG47ICsraSkge1xuICAgICAgZCA9IGRhdGFbaV0sIG5vZGUgPSBub2Rlc1tpXSA9IG5ldyBOb2RlKGQpO1xuICAgICAgaWYgKChub2RlSWQgPSBpZChkLCBpLCBkYXRhKSkgIT0gbnVsbCAmJiAobm9kZUlkICs9IFwiXCIpKSB7XG4gICAgICAgIG5vZGVLZXkgPSBrZXlQcmVmaXggKyAobm9kZS5pZCA9IG5vZGVJZCk7XG4gICAgICAgIG5vZGVCeUtleVtub2RlS2V5XSA9IG5vZGVLZXkgaW4gbm9kZUJ5S2V5ID8gYW1iaWd1b3VzIDogbm9kZTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBmb3IgKGkgPSAwOyBpIDwgbjsgKytpKSB7XG4gICAgICBub2RlID0gbm9kZXNbaV0sIG5vZGVJZCA9IHBhcmVudElkKGRhdGFbaV0sIGksIGRhdGEpO1xuICAgICAgaWYgKG5vZGVJZCA9PSBudWxsIHx8ICEobm9kZUlkICs9IFwiXCIpKSB7XG4gICAgICAgIGlmIChyb290KSB0aHJvdyBuZXcgRXJyb3IoXCJtdWx0aXBsZSByb290c1wiKTtcbiAgICAgICAgcm9vdCA9IG5vZGU7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJlbnQgPSBub2RlQnlLZXlba2V5UHJlZml4ICsgbm9kZUlkXTtcbiAgICAgICAgaWYgKCFwYXJlbnQpIHRocm93IG5ldyBFcnJvcihcIm1pc3Npbmc6IFwiICsgbm9kZUlkKTtcbiAgICAgICAgaWYgKHBhcmVudCA9PT0gYW1iaWd1b3VzKSB0aHJvdyBuZXcgRXJyb3IoXCJhbWJpZ3VvdXM6IFwiICsgbm9kZUlkKTtcbiAgICAgICAgaWYgKHBhcmVudC5jaGlsZHJlbikgcGFyZW50LmNoaWxkcmVuLnB1c2gobm9kZSk7XG4gICAgICAgIGVsc2UgcGFyZW50LmNoaWxkcmVuID0gW25vZGVdO1xuICAgICAgICBub2RlLnBhcmVudCA9IHBhcmVudDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoIXJvb3QpIHRocm93IG5ldyBFcnJvcihcIm5vIHJvb3RcIik7XG4gICAgcm9vdC5wYXJlbnQgPSBwcmVyb290O1xuICAgIHJvb3QuZWFjaEJlZm9yZShmdW5jdGlvbihub2RlKSB7IG5vZGUuZGVwdGggPSBub2RlLnBhcmVudC5kZXB0aCArIDE7IC0tbjsgfSkuZWFjaEJlZm9yZShjb21wdXRlSGVpZ2h0KTtcbiAgICByb290LnBhcmVudCA9IG51bGw7XG4gICAgaWYgKG4gPiAwKSB0aHJvdyBuZXcgRXJyb3IoXCJjeWNsZVwiKTtcblxuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgc3RyYXRpZnkuaWQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoaWQgPSByZXF1aXJlZCh4KSwgc3RyYXRpZnkpIDogaWQ7XG4gIH07XG5cbiAgc3RyYXRpZnkucGFyZW50SWQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFyZW50SWQgPSByZXF1aXJlZCh4KSwgc3RyYXRpZnkpIDogcGFyZW50SWQ7XG4gIH07XG5cbiAgcmV0dXJuIHN0cmF0aWZ5O1xufTtcblxuZnVuY3Rpb24gZGVmYXVsdFNlcGFyYXRpb24kMShhLCBiKSB7XG4gIHJldHVybiBhLnBhcmVudCA9PT0gYi5wYXJlbnQgPyAxIDogMjtcbn1cblxuLy8gZnVuY3Rpb24gcmFkaWFsU2VwYXJhdGlvbihhLCBiKSB7XG4vLyAgIHJldHVybiAoYS5wYXJlbnQgPT09IGIucGFyZW50ID8gMSA6IDIpIC8gYS5kZXB0aDtcbi8vIH1cblxuLy8gVGhpcyBmdW5jdGlvbiBpcyB1c2VkIHRvIHRyYXZlcnNlIHRoZSBsZWZ0IGNvbnRvdXIgb2YgYSBzdWJ0cmVlIChvclxuLy8gc3ViZm9yZXN0KS4gSXQgcmV0dXJucyB0aGUgc3VjY2Vzc29yIG9mIHYgb24gdGhpcyBjb250b3VyLiBUaGlzIHN1Y2Nlc3NvciBpc1xuLy8gZWl0aGVyIGdpdmVuIGJ5IHRoZSBsZWZ0bW9zdCBjaGlsZCBvZiB2IG9yIGJ5IHRoZSB0aHJlYWQgb2Ygdi4gVGhlIGZ1bmN0aW9uXG4vLyByZXR1cm5zIG51bGwgaWYgYW5kIG9ubHkgaWYgdiBpcyBvbiB0aGUgaGlnaGVzdCBsZXZlbCBvZiBpdHMgc3VidHJlZS5cbmZ1bmN0aW9uIG5leHRMZWZ0KHYpIHtcbiAgdmFyIGNoaWxkcmVuID0gdi5jaGlsZHJlbjtcbiAgcmV0dXJuIGNoaWxkcmVuID8gY2hpbGRyZW5bMF0gOiB2LnQ7XG59XG5cbi8vIFRoaXMgZnVuY3Rpb24gd29ya3MgYW5hbG9nb3VzbHkgdG8gbmV4dExlZnQuXG5mdW5jdGlvbiBuZXh0UmlnaHQodikge1xuICB2YXIgY2hpbGRyZW4gPSB2LmNoaWxkcmVuO1xuICByZXR1cm4gY2hpbGRyZW4gPyBjaGlsZHJlbltjaGlsZHJlbi5sZW5ndGggLSAxXSA6IHYudDtcbn1cblxuLy8gU2hpZnRzIHRoZSBjdXJyZW50IHN1YnRyZWUgcm9vdGVkIGF0IHcrLiBUaGlzIGlzIGRvbmUgYnkgaW5jcmVhc2luZ1xuLy8gcHJlbGltKHcrKSBhbmQgbW9kKHcrKSBieSBzaGlmdC5cbmZ1bmN0aW9uIG1vdmVTdWJ0cmVlKHdtLCB3cCwgc2hpZnQpIHtcbiAgdmFyIGNoYW5nZSA9IHNoaWZ0IC8gKHdwLmkgLSB3bS5pKTtcbiAgd3AuYyAtPSBjaGFuZ2U7XG4gIHdwLnMgKz0gc2hpZnQ7XG4gIHdtLmMgKz0gY2hhbmdlO1xuICB3cC56ICs9IHNoaWZ0O1xuICB3cC5tICs9IHNoaWZ0O1xufVxuXG4vLyBBbGwgb3RoZXIgc2hpZnRzLCBhcHBsaWVkIHRvIHRoZSBzbWFsbGVyIHN1YnRyZWVzIGJldHdlZW4gdy0gYW5kIHcrLCBhcmVcbi8vIHBlcmZvcm1lZCBieSB0aGlzIGZ1bmN0aW9uLiBUbyBwcmVwYXJlIHRoZSBzaGlmdHMsIHdlIGhhdmUgdG8gYWRqdXN0XG4vLyBjaGFuZ2UodyspLCBzaGlmdCh3KyksIGFuZCBjaGFuZ2Uody0pLlxuZnVuY3Rpb24gZXhlY3V0ZVNoaWZ0cyh2KSB7XG4gIHZhciBzaGlmdCA9IDAsXG4gICAgICBjaGFuZ2UgPSAwLFxuICAgICAgY2hpbGRyZW4gPSB2LmNoaWxkcmVuLFxuICAgICAgaSA9IGNoaWxkcmVuLmxlbmd0aCxcbiAgICAgIHc7XG4gIHdoaWxlICgtLWkgPj0gMCkge1xuICAgIHcgPSBjaGlsZHJlbltpXTtcbiAgICB3LnogKz0gc2hpZnQ7XG4gICAgdy5tICs9IHNoaWZ0O1xuICAgIHNoaWZ0ICs9IHcucyArIChjaGFuZ2UgKz0gdy5jKTtcbiAgfVxufVxuXG4vLyBJZiB2aS3igJlzIGFuY2VzdG9yIGlzIGEgc2libGluZyBvZiB2LCByZXR1cm5zIHZpLeKAmXMgYW5jZXN0b3IuIE90aGVyd2lzZSxcbi8vIHJldHVybnMgdGhlIHNwZWNpZmllZCAoZGVmYXVsdCkgYW5jZXN0b3IuXG5mdW5jdGlvbiBuZXh0QW5jZXN0b3IodmltLCB2LCBhbmNlc3Rvcikge1xuICByZXR1cm4gdmltLmEucGFyZW50ID09PSB2LnBhcmVudCA/IHZpbS5hIDogYW5jZXN0b3I7XG59XG5cbmZ1bmN0aW9uIFRyZWVOb2RlKG5vZGUsIGkpIHtcbiAgdGhpcy5fID0gbm9kZTtcbiAgdGhpcy5wYXJlbnQgPSBudWxsO1xuICB0aGlzLmNoaWxkcmVuID0gbnVsbDtcbiAgdGhpcy5BID0gbnVsbDsgLy8gZGVmYXVsdCBhbmNlc3RvclxuICB0aGlzLmEgPSB0aGlzOyAvLyBhbmNlc3RvclxuICB0aGlzLnogPSAwOyAvLyBwcmVsaW1cbiAgdGhpcy5tID0gMDsgLy8gbW9kXG4gIHRoaXMuYyA9IDA7IC8vIGNoYW5nZVxuICB0aGlzLnMgPSAwOyAvLyBzaGlmdFxuICB0aGlzLnQgPSBudWxsOyAvLyB0aHJlYWRcbiAgdGhpcy5pID0gaTsgLy8gbnVtYmVyXG59XG5cblRyZWVOb2RlLnByb3RvdHlwZSA9IE9iamVjdC5jcmVhdGUoTm9kZS5wcm90b3R5cGUpO1xuXG5mdW5jdGlvbiB0cmVlUm9vdChyb290KSB7XG4gIHZhciB0cmVlID0gbmV3IFRyZWVOb2RlKHJvb3QsIDApLFxuICAgICAgbm9kZSxcbiAgICAgIG5vZGVzID0gW3RyZWVdLFxuICAgICAgY2hpbGQsXG4gICAgICBjaGlsZHJlbixcbiAgICAgIGksXG4gICAgICBuO1xuXG4gIHdoaWxlIChub2RlID0gbm9kZXMucG9wKCkpIHtcbiAgICBpZiAoY2hpbGRyZW4gPSBub2RlLl8uY2hpbGRyZW4pIHtcbiAgICAgIG5vZGUuY2hpbGRyZW4gPSBuZXcgQXJyYXkobiA9IGNoaWxkcmVuLmxlbmd0aCk7XG4gICAgICBmb3IgKGkgPSBuIC0gMTsgaSA+PSAwOyAtLWkpIHtcbiAgICAgICAgbm9kZXMucHVzaChjaGlsZCA9IG5vZGUuY2hpbGRyZW5baV0gPSBuZXcgVHJlZU5vZGUoY2hpbGRyZW5baV0sIGkpKTtcbiAgICAgICAgY2hpbGQucGFyZW50ID0gbm9kZTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAodHJlZS5wYXJlbnQgPSBuZXcgVHJlZU5vZGUobnVsbCwgMCkpLmNoaWxkcmVuID0gW3RyZWVdO1xuICByZXR1cm4gdHJlZTtcbn1cblxuLy8gTm9kZS1saW5rIHRyZWUgZGlhZ3JhbSB1c2luZyB0aGUgUmVpbmdvbGQtVGlsZm9yZCBcInRpZHlcIiBhbGdvcml0aG1cbnZhciB0cmVlJDEgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHNlcGFyYXRpb24gPSBkZWZhdWx0U2VwYXJhdGlvbiQxLFxuICAgICAgZHggPSAxLFxuICAgICAgZHkgPSAxLFxuICAgICAgbm9kZVNpemUgPSBudWxsO1xuXG4gIGZ1bmN0aW9uIHRyZWUocm9vdCkge1xuICAgIHZhciB0ID0gdHJlZVJvb3Qocm9vdCk7XG5cbiAgICAvLyBDb21wdXRlIHRoZSBsYXlvdXQgdXNpbmcgQnVjaGhlaW0gZXQgYWwu4oCZcyBhbGdvcml0aG0uXG4gICAgdC5lYWNoQWZ0ZXIoZmlyc3RXYWxrKSwgdC5wYXJlbnQubSA9IC10Lno7XG4gICAgdC5lYWNoQmVmb3JlKHNlY29uZFdhbGspO1xuXG4gICAgLy8gSWYgYSBmaXhlZCBub2RlIHNpemUgaXMgc3BlY2lmaWVkLCBzY2FsZSB4IGFuZCB5LlxuICAgIGlmIChub2RlU2l6ZSkgcm9vdC5lYWNoQmVmb3JlKHNpemVOb2RlKTtcblxuICAgIC8vIElmIGEgZml4ZWQgdHJlZSBzaXplIGlzIHNwZWNpZmllZCwgc2NhbGUgeCBhbmQgeSBiYXNlZCBvbiB0aGUgZXh0ZW50LlxuICAgIC8vIENvbXB1dGUgdGhlIGxlZnQtbW9zdCwgcmlnaHQtbW9zdCwgYW5kIGRlcHRoLW1vc3Qgbm9kZXMgZm9yIGV4dGVudHMuXG4gICAgZWxzZSB7XG4gICAgICB2YXIgbGVmdCA9IHJvb3QsXG4gICAgICAgICAgcmlnaHQgPSByb290LFxuICAgICAgICAgIGJvdHRvbSA9IHJvb3Q7XG4gICAgICByb290LmVhY2hCZWZvcmUoZnVuY3Rpb24obm9kZSkge1xuICAgICAgICBpZiAobm9kZS54IDwgbGVmdC54KSBsZWZ0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUueCA+IHJpZ2h0LngpIHJpZ2h0ID0gbm9kZTtcbiAgICAgICAgaWYgKG5vZGUuZGVwdGggPiBib3R0b20uZGVwdGgpIGJvdHRvbSA9IG5vZGU7XG4gICAgICB9KTtcbiAgICAgIHZhciBzID0gbGVmdCA9PT0gcmlnaHQgPyAxIDogc2VwYXJhdGlvbihsZWZ0LCByaWdodCkgLyAyLFxuICAgICAgICAgIHR4ID0gcyAtIGxlZnQueCxcbiAgICAgICAgICBreCA9IGR4IC8gKHJpZ2h0LnggKyBzICsgdHgpLFxuICAgICAgICAgIGt5ID0gZHkgLyAoYm90dG9tLmRlcHRoIHx8IDEpO1xuICAgICAgcm9vdC5lYWNoQmVmb3JlKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgbm9kZS54ID0gKG5vZGUueCArIHR4KSAqIGt4O1xuICAgICAgICBub2RlLnkgPSBub2RlLmRlcHRoICoga3k7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICByZXR1cm4gcm9vdDtcbiAgfVxuXG4gIC8vIENvbXB1dGVzIGEgcHJlbGltaW5hcnkgeC1jb29yZGluYXRlIGZvciB2LiBCZWZvcmUgdGhhdCwgRklSU1QgV0FMSyBpc1xuICAvLyBhcHBsaWVkIHJlY3Vyc2l2ZWx5IHRvIHRoZSBjaGlsZHJlbiBvZiB2LCBhcyB3ZWxsIGFzIHRoZSBmdW5jdGlvblxuICAvLyBBUFBPUlRJT04uIEFmdGVyIHNwYWNpbmcgb3V0IHRoZSBjaGlsZHJlbiBieSBjYWxsaW5nIEVYRUNVVEUgU0hJRlRTLCB0aGVcbiAgLy8gbm9kZSB2IGlzIHBsYWNlZCB0byB0aGUgbWlkcG9pbnQgb2YgaXRzIG91dGVybW9zdCBjaGlsZHJlbi5cbiAgZnVuY3Rpb24gZmlyc3RXYWxrKHYpIHtcbiAgICB2YXIgY2hpbGRyZW4gPSB2LmNoaWxkcmVuLFxuICAgICAgICBzaWJsaW5ncyA9IHYucGFyZW50LmNoaWxkcmVuLFxuICAgICAgICB3ID0gdi5pID8gc2libGluZ3Nbdi5pIC0gMV0gOiBudWxsO1xuICAgIGlmIChjaGlsZHJlbikge1xuICAgICAgZXhlY3V0ZVNoaWZ0cyh2KTtcbiAgICAgIHZhciBtaWRwb2ludCA9IChjaGlsZHJlblswXS56ICsgY2hpbGRyZW5bY2hpbGRyZW4ubGVuZ3RoIC0gMV0ueikgLyAyO1xuICAgICAgaWYgKHcpIHtcbiAgICAgICAgdi56ID0gdy56ICsgc2VwYXJhdGlvbih2Ll8sIHcuXyk7XG4gICAgICAgIHYubSA9IHYueiAtIG1pZHBvaW50O1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgdi56ID0gbWlkcG9pbnQ7XG4gICAgICB9XG4gICAgfSBlbHNlIGlmICh3KSB7XG4gICAgICB2LnogPSB3LnogKyBzZXBhcmF0aW9uKHYuXywgdy5fKTtcbiAgICB9XG4gICAgdi5wYXJlbnQuQSA9IGFwcG9ydGlvbih2LCB3LCB2LnBhcmVudC5BIHx8IHNpYmxpbmdzWzBdKTtcbiAgfVxuXG4gIC8vIENvbXB1dGVzIGFsbCByZWFsIHgtY29vcmRpbmF0ZXMgYnkgc3VtbWluZyB1cCB0aGUgbW9kaWZpZXJzIHJlY3Vyc2l2ZWx5LlxuICBmdW5jdGlvbiBzZWNvbmRXYWxrKHYpIHtcbiAgICB2Ll8ueCA9IHYueiArIHYucGFyZW50Lm07XG4gICAgdi5tICs9IHYucGFyZW50Lm07XG4gIH1cblxuICAvLyBUaGUgY29yZSBvZiB0aGUgYWxnb3JpdGhtLiBIZXJlLCBhIG5ldyBzdWJ0cmVlIGlzIGNvbWJpbmVkIHdpdGggdGhlXG4gIC8vIHByZXZpb3VzIHN1YnRyZWVzLiBUaHJlYWRzIGFyZSB1c2VkIHRvIHRyYXZlcnNlIHRoZSBpbnNpZGUgYW5kIG91dHNpZGVcbiAgLy8gY29udG91cnMgb2YgdGhlIGxlZnQgYW5kIHJpZ2h0IHN1YnRyZWUgdXAgdG8gdGhlIGhpZ2hlc3QgY29tbW9uIGxldmVsLiBUaGVcbiAgLy8gdmVydGljZXMgdXNlZCBmb3IgdGhlIHRyYXZlcnNhbHMgYXJlIHZpKywgdmktLCB2by0sIGFuZCB2byssIHdoZXJlIHRoZVxuICAvLyBzdXBlcnNjcmlwdCBvIG1lYW5zIG91dHNpZGUgYW5kIGkgbWVhbnMgaW5zaWRlLCB0aGUgc3Vic2NyaXB0IC0gbWVhbnMgbGVmdFxuICAvLyBzdWJ0cmVlIGFuZCArIG1lYW5zIHJpZ2h0IHN1YnRyZWUuIEZvciBzdW1taW5nIHVwIHRoZSBtb2RpZmllcnMgYWxvbmcgdGhlXG4gIC8vIGNvbnRvdXIsIHdlIHVzZSByZXNwZWN0aXZlIHZhcmlhYmxlcyBzaSssIHNpLSwgc28tLCBhbmQgc28rLiBXaGVuZXZlciB0d29cbiAgLy8gbm9kZXMgb2YgdGhlIGluc2lkZSBjb250b3VycyBjb25mbGljdCwgd2UgY29tcHV0ZSB0aGUgbGVmdCBvbmUgb2YgdGhlXG4gIC8vIGdyZWF0ZXN0IHVuY29tbW9uIGFuY2VzdG9ycyB1c2luZyB0aGUgZnVuY3Rpb24gQU5DRVNUT1IgYW5kIGNhbGwgTU9WRVxuICAvLyBTVUJUUkVFIHRvIHNoaWZ0IHRoZSBzdWJ0cmVlIGFuZCBwcmVwYXJlIHRoZSBzaGlmdHMgb2Ygc21hbGxlciBzdWJ0cmVlcy5cbiAgLy8gRmluYWxseSwgd2UgYWRkIGEgbmV3IHRocmVhZCAoaWYgbmVjZXNzYXJ5KS5cbiAgZnVuY3Rpb24gYXBwb3J0aW9uKHYsIHcsIGFuY2VzdG9yKSB7XG4gICAgaWYgKHcpIHtcbiAgICAgIHZhciB2aXAgPSB2LFxuICAgICAgICAgIHZvcCA9IHYsXG4gICAgICAgICAgdmltID0gdyxcbiAgICAgICAgICB2b20gPSB2aXAucGFyZW50LmNoaWxkcmVuWzBdLFxuICAgICAgICAgIHNpcCA9IHZpcC5tLFxuICAgICAgICAgIHNvcCA9IHZvcC5tLFxuICAgICAgICAgIHNpbSA9IHZpbS5tLFxuICAgICAgICAgIHNvbSA9IHZvbS5tLFxuICAgICAgICAgIHNoaWZ0O1xuICAgICAgd2hpbGUgKHZpbSA9IG5leHRSaWdodCh2aW0pLCB2aXAgPSBuZXh0TGVmdCh2aXApLCB2aW0gJiYgdmlwKSB7XG4gICAgICAgIHZvbSA9IG5leHRMZWZ0KHZvbSk7XG4gICAgICAgIHZvcCA9IG5leHRSaWdodCh2b3ApO1xuICAgICAgICB2b3AuYSA9IHY7XG4gICAgICAgIHNoaWZ0ID0gdmltLnogKyBzaW0gLSB2aXAueiAtIHNpcCArIHNlcGFyYXRpb24odmltLl8sIHZpcC5fKTtcbiAgICAgICAgaWYgKHNoaWZ0ID4gMCkge1xuICAgICAgICAgIG1vdmVTdWJ0cmVlKG5leHRBbmNlc3Rvcih2aW0sIHYsIGFuY2VzdG9yKSwgdiwgc2hpZnQpO1xuICAgICAgICAgIHNpcCArPSBzaGlmdDtcbiAgICAgICAgICBzb3AgKz0gc2hpZnQ7XG4gICAgICAgIH1cbiAgICAgICAgc2ltICs9IHZpbS5tO1xuICAgICAgICBzaXAgKz0gdmlwLm07XG4gICAgICAgIHNvbSArPSB2b20ubTtcbiAgICAgICAgc29wICs9IHZvcC5tO1xuICAgICAgfVxuICAgICAgaWYgKHZpbSAmJiAhbmV4dFJpZ2h0KHZvcCkpIHtcbiAgICAgICAgdm9wLnQgPSB2aW07XG4gICAgICAgIHZvcC5tICs9IHNpbSAtIHNvcDtcbiAgICAgIH1cbiAgICAgIGlmICh2aXAgJiYgIW5leHRMZWZ0KHZvbSkpIHtcbiAgICAgICAgdm9tLnQgPSB2aXA7XG4gICAgICAgIHZvbS5tICs9IHNpcCAtIHNvbTtcbiAgICAgICAgYW5jZXN0b3IgPSB2O1xuICAgICAgfVxuICAgIH1cbiAgICByZXR1cm4gYW5jZXN0b3I7XG4gIH1cblxuICBmdW5jdGlvbiBzaXplTm9kZShub2RlKSB7XG4gICAgbm9kZS54ICo9IGR4O1xuICAgIG5vZGUueSA9IG5vZGUuZGVwdGggKiBkeTtcbiAgfVxuXG4gIHRyZWUuc2VwYXJhdGlvbiA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChzZXBhcmF0aW9uID0geCwgdHJlZSkgOiBzZXBhcmF0aW9uO1xuICB9O1xuXG4gIHRyZWUuc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IGZhbHNlLCBkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCB0cmVlKSA6IChub2RlU2l6ZSA/IG51bGwgOiBbZHgsIGR5XSk7XG4gIH07XG5cbiAgdHJlZS5ub2RlU2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChub2RlU2l6ZSA9IHRydWUsIGR4ID0gK3hbMF0sIGR5ID0gK3hbMV0sIHRyZWUpIDogKG5vZGVTaXplID8gW2R4LCBkeV0gOiBudWxsKTtcbiAgfTtcblxuICByZXR1cm4gdHJlZTtcbn07XG5cbnZhciB0cmVlbWFwU2xpY2UgPSBmdW5jdGlvbihwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciBub2RlcyA9IHBhcmVudC5jaGlsZHJlbixcbiAgICAgIG5vZGUsXG4gICAgICBpID0gLTEsXG4gICAgICBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgayA9IHBhcmVudC52YWx1ZSAmJiAoeTEgLSB5MCkgLyBwYXJlbnQudmFsdWU7XG5cbiAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICBub2RlID0gbm9kZXNbaV0sIG5vZGUueDAgPSB4MCwgbm9kZS54MSA9IHgxO1xuICAgIG5vZGUueTAgPSB5MCwgbm9kZS55MSA9IHkwICs9IG5vZGUudmFsdWUgKiBrO1xuICB9XG59O1xuXG52YXIgcGhpID0gKDEgKyBNYXRoLnNxcnQoNSkpIC8gMjtcblxuZnVuY3Rpb24gc3F1YXJpZnlSYXRpbyhyYXRpbywgcGFyZW50LCB4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgcm93cyA9IFtdLFxuICAgICAgbm9kZXMgPSBwYXJlbnQuY2hpbGRyZW4sXG4gICAgICByb3csXG4gICAgICBub2RlVmFsdWUsXG4gICAgICBpMCA9IDAsXG4gICAgICBpMSA9IDAsXG4gICAgICBuID0gbm9kZXMubGVuZ3RoLFxuICAgICAgZHgsIGR5LFxuICAgICAgdmFsdWUgPSBwYXJlbnQudmFsdWUsXG4gICAgICBzdW1WYWx1ZSxcbiAgICAgIG1pblZhbHVlLFxuICAgICAgbWF4VmFsdWUsXG4gICAgICBuZXdSYXRpbyxcbiAgICAgIG1pblJhdGlvLFxuICAgICAgYWxwaGEsXG4gICAgICBiZXRhO1xuXG4gIHdoaWxlIChpMCA8IG4pIHtcbiAgICBkeCA9IHgxIC0geDAsIGR5ID0geTEgLSB5MDtcblxuICAgIC8vIEZpbmQgdGhlIG5leHQgbm9uLWVtcHR5IG5vZGUuXG4gICAgZG8gc3VtVmFsdWUgPSBub2Rlc1tpMSsrXS52YWx1ZTsgd2hpbGUgKCFzdW1WYWx1ZSAmJiBpMSA8IG4pO1xuICAgIG1pblZhbHVlID0gbWF4VmFsdWUgPSBzdW1WYWx1ZTtcbiAgICBhbHBoYSA9IE1hdGgubWF4KGR5IC8gZHgsIGR4IC8gZHkpIC8gKHZhbHVlICogcmF0aW8pO1xuICAgIGJldGEgPSBzdW1WYWx1ZSAqIHN1bVZhbHVlICogYWxwaGE7XG4gICAgbWluUmF0aW8gPSBNYXRoLm1heChtYXhWYWx1ZSAvIGJldGEsIGJldGEgLyBtaW5WYWx1ZSk7XG5cbiAgICAvLyBLZWVwIGFkZGluZyBub2RlcyB3aGlsZSB0aGUgYXNwZWN0IHJhdGlvIG1haW50YWlucyBvciBpbXByb3Zlcy5cbiAgICBmb3IgKDsgaTEgPCBuOyArK2kxKSB7XG4gICAgICBzdW1WYWx1ZSArPSBub2RlVmFsdWUgPSBub2Rlc1tpMV0udmFsdWU7XG4gICAgICBpZiAobm9kZVZhbHVlIDwgbWluVmFsdWUpIG1pblZhbHVlID0gbm9kZVZhbHVlO1xuICAgICAgaWYgKG5vZGVWYWx1ZSA+IG1heFZhbHVlKSBtYXhWYWx1ZSA9IG5vZGVWYWx1ZTtcbiAgICAgIGJldGEgPSBzdW1WYWx1ZSAqIHN1bVZhbHVlICogYWxwaGE7XG4gICAgICBuZXdSYXRpbyA9IE1hdGgubWF4KG1heFZhbHVlIC8gYmV0YSwgYmV0YSAvIG1pblZhbHVlKTtcbiAgICAgIGlmIChuZXdSYXRpbyA+IG1pblJhdGlvKSB7IHN1bVZhbHVlIC09IG5vZGVWYWx1ZTsgYnJlYWs7IH1cbiAgICAgIG1pblJhdGlvID0gbmV3UmF0aW87XG4gICAgfVxuXG4gICAgLy8gUG9zaXRpb24gYW5kIHJlY29yZCB0aGUgcm93IG9yaWVudGF0aW9uLlxuICAgIHJvd3MucHVzaChyb3cgPSB7dmFsdWU6IHN1bVZhbHVlLCBkaWNlOiBkeCA8IGR5LCBjaGlsZHJlbjogbm9kZXMuc2xpY2UoaTAsIGkxKX0pO1xuICAgIGlmIChyb3cuZGljZSkgdHJlZW1hcERpY2Uocm93LCB4MCwgeTAsIHgxLCB2YWx1ZSA/IHkwICs9IGR5ICogc3VtVmFsdWUgLyB2YWx1ZSA6IHkxKTtcbiAgICBlbHNlIHRyZWVtYXBTbGljZShyb3csIHgwLCB5MCwgdmFsdWUgPyB4MCArPSBkeCAqIHN1bVZhbHVlIC8gdmFsdWUgOiB4MSwgeTEpO1xuICAgIHZhbHVlIC09IHN1bVZhbHVlLCBpMCA9IGkxO1xuICB9XG5cbiAgcmV0dXJuIHJvd3M7XG59XG5cbnZhciB0cmVlbWFwU3F1YXJpZnkgPSAoZnVuY3Rpb24gY3VzdG9tKHJhdGlvKSB7XG5cbiAgZnVuY3Rpb24gc3F1YXJpZnkocGFyZW50LCB4MCwgeTAsIHgxLCB5MSkge1xuICAgIHNxdWFyaWZ5UmF0aW8ocmF0aW8sIHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpO1xuICB9XG5cbiAgc3F1YXJpZnkucmF0aW8gPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGN1c3RvbSgoeCA9ICt4KSA+IDEgPyB4IDogMSk7XG4gIH07XG5cbiAgcmV0dXJuIHNxdWFyaWZ5O1xufSkocGhpKTtcblxudmFyIHRyZWVtYXAgPSBmdW5jdGlvbigpIHtcbiAgdmFyIHRpbGUgPSB0cmVlbWFwU3F1YXJpZnksXG4gICAgICByb3VuZCA9IGZhbHNlLFxuICAgICAgZHggPSAxLFxuICAgICAgZHkgPSAxLFxuICAgICAgcGFkZGluZ1N0YWNrID0gWzBdLFxuICAgICAgcGFkZGluZ0lubmVyID0gY29uc3RhbnRaZXJvLFxuICAgICAgcGFkZGluZ1RvcCA9IGNvbnN0YW50WmVybyxcbiAgICAgIHBhZGRpbmdSaWdodCA9IGNvbnN0YW50WmVybyxcbiAgICAgIHBhZGRpbmdCb3R0b20gPSBjb25zdGFudFplcm8sXG4gICAgICBwYWRkaW5nTGVmdCA9IGNvbnN0YW50WmVybztcblxuICBmdW5jdGlvbiB0cmVlbWFwKHJvb3QpIHtcbiAgICByb290LngwID1cbiAgICByb290LnkwID0gMDtcbiAgICByb290LngxID0gZHg7XG4gICAgcm9vdC55MSA9IGR5O1xuICAgIHJvb3QuZWFjaEJlZm9yZShwb3NpdGlvbk5vZGUpO1xuICAgIHBhZGRpbmdTdGFjayA9IFswXTtcbiAgICBpZiAocm91bmQpIHJvb3QuZWFjaEJlZm9yZShyb3VuZE5vZGUpO1xuICAgIHJldHVybiByb290O1xuICB9XG5cbiAgZnVuY3Rpb24gcG9zaXRpb25Ob2RlKG5vZGUpIHtcbiAgICB2YXIgcCA9IHBhZGRpbmdTdGFja1tub2RlLmRlcHRoXSxcbiAgICAgICAgeDAgPSBub2RlLngwICsgcCxcbiAgICAgICAgeTAgPSBub2RlLnkwICsgcCxcbiAgICAgICAgeDEgPSBub2RlLngxIC0gcCxcbiAgICAgICAgeTEgPSBub2RlLnkxIC0gcDtcbiAgICBpZiAoeDEgPCB4MCkgeDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7XG4gICAgaWYgKHkxIDwgeTApIHkwID0geTEgPSAoeTAgKyB5MSkgLyAyO1xuICAgIG5vZGUueDAgPSB4MDtcbiAgICBub2RlLnkwID0geTA7XG4gICAgbm9kZS54MSA9IHgxO1xuICAgIG5vZGUueTEgPSB5MTtcbiAgICBpZiAobm9kZS5jaGlsZHJlbikge1xuICAgICAgcCA9IHBhZGRpbmdTdGFja1tub2RlLmRlcHRoICsgMV0gPSBwYWRkaW5nSW5uZXIobm9kZSkgLyAyO1xuICAgICAgeDAgKz0gcGFkZGluZ0xlZnQobm9kZSkgLSBwO1xuICAgICAgeTAgKz0gcGFkZGluZ1RvcChub2RlKSAtIHA7XG4gICAgICB4MSAtPSBwYWRkaW5nUmlnaHQobm9kZSkgLSBwO1xuICAgICAgeTEgLT0gcGFkZGluZ0JvdHRvbShub2RlKSAtIHA7XG4gICAgICBpZiAoeDEgPCB4MCkgeDAgPSB4MSA9ICh4MCArIHgxKSAvIDI7XG4gICAgICBpZiAoeTEgPCB5MCkgeTAgPSB5MSA9ICh5MCArIHkxKSAvIDI7XG4gICAgICB0aWxlKG5vZGUsIHgwLCB5MCwgeDEsIHkxKTtcbiAgICB9XG4gIH1cblxuICB0cmVlbWFwLnJvdW5kID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHJvdW5kID0gISF4LCB0cmVlbWFwKSA6IHJvdW5kO1xuICB9O1xuXG4gIHRyZWVtYXAuc2l6ZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChkeCA9ICt4WzBdLCBkeSA9ICt4WzFdLCB0cmVlbWFwKSA6IFtkeCwgZHldO1xuICB9O1xuXG4gIHRyZWVtYXAudGlsZSA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh0aWxlID0gcmVxdWlyZWQoeCksIHRyZWVtYXApIDogdGlsZTtcbiAgfTtcblxuICB0cmVlbWFwLnBhZGRpbmcgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyB0cmVlbWFwLnBhZGRpbmdJbm5lcih4KS5wYWRkaW5nT3V0ZXIoeCkgOiB0cmVlbWFwLnBhZGRpbmdJbm5lcigpO1xuICB9O1xuXG4gIHRyZWVtYXAucGFkZGluZ0lubmVyID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdJbm5lciA9IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4IDogY29uc3RhbnQkOSgreCksIHRyZWVtYXApIDogcGFkZGluZ0lubmVyO1xuICB9O1xuXG4gIHRyZWVtYXAucGFkZGluZ091dGVyID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdHJlZW1hcC5wYWRkaW5nVG9wKHgpLnBhZGRpbmdSaWdodCh4KS5wYWRkaW5nQm90dG9tKHgpLnBhZGRpbmdMZWZ0KHgpIDogdHJlZW1hcC5wYWRkaW5nVG9wKCk7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nVG9wID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdUb3AgPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6IGNvbnN0YW50JDkoK3gpLCB0cmVlbWFwKSA6IHBhZGRpbmdUb3A7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nUmlnaHQgPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAocGFkZGluZ1JpZ2h0ID0gdHlwZW9mIHggPT09IFwiZnVuY3Rpb25cIiA/IHggOiBjb25zdGFudCQ5KCt4KSwgdHJlZW1hcCkgOiBwYWRkaW5nUmlnaHQ7XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nQm90dG9tID0gZnVuY3Rpb24oeCkge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKHBhZGRpbmdCb3R0b20gPSB0eXBlb2YgeCA9PT0gXCJmdW5jdGlvblwiID8geCA6IGNvbnN0YW50JDkoK3gpLCB0cmVlbWFwKSA6IHBhZGRpbmdCb3R0b207XG4gIH07XG5cbiAgdHJlZW1hcC5wYWRkaW5nTGVmdCA9IGZ1bmN0aW9uKHgpIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/IChwYWRkaW5nTGVmdCA9IHR5cGVvZiB4ID09PSBcImZ1bmN0aW9uXCIgPyB4IDogY29uc3RhbnQkOSgreCksIHRyZWVtYXApIDogcGFkZGluZ0xlZnQ7XG4gIH07XG5cbiAgcmV0dXJuIHRyZWVtYXA7XG59O1xuXG52YXIgdHJlZW1hcEJpbmFyeSA9IGZ1bmN0aW9uKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIG5vZGVzID0gcGFyZW50LmNoaWxkcmVuLFxuICAgICAgaSwgbiA9IG5vZGVzLmxlbmd0aCxcbiAgICAgIHN1bSwgc3VtcyA9IG5ldyBBcnJheShuICsgMSk7XG5cbiAgZm9yIChzdW1zWzBdID0gc3VtID0gaSA9IDA7IGkgPCBuOyArK2kpIHtcbiAgICBzdW1zW2kgKyAxXSA9IHN1bSArPSBub2Rlc1tpXS52YWx1ZTtcbiAgfVxuXG4gIHBhcnRpdGlvbigwLCBuLCBwYXJlbnQudmFsdWUsIHgwLCB5MCwgeDEsIHkxKTtcblxuICBmdW5jdGlvbiBwYXJ0aXRpb24oaSwgaiwgdmFsdWUsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgaWYgKGkgPj0gaiAtIDEpIHtcbiAgICAgIHZhciBub2RlID0gbm9kZXNbaV07XG4gICAgICBub2RlLngwID0geDAsIG5vZGUueTAgPSB5MDtcbiAgICAgIG5vZGUueDEgPSB4MSwgbm9kZS55MSA9IHkxO1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIHZhciB2YWx1ZU9mZnNldCA9IHN1bXNbaV0sXG4gICAgICAgIHZhbHVlVGFyZ2V0ID0gKHZhbHVlIC8gMikgKyB2YWx1ZU9mZnNldCxcbiAgICAgICAgayA9IGkgKyAxLFxuICAgICAgICBoaSA9IGogLSAxO1xuXG4gICAgd2hpbGUgKGsgPCBoaSkge1xuICAgICAgdmFyIG1pZCA9IGsgKyBoaSA+Pj4gMTtcbiAgICAgIGlmIChzdW1zW21pZF0gPCB2YWx1ZVRhcmdldCkgayA9IG1pZCArIDE7XG4gICAgICBlbHNlIGhpID0gbWlkO1xuICAgIH1cblxuICAgIGlmICgodmFsdWVUYXJnZXQgLSBzdW1zW2sgLSAxXSkgPCAoc3Vtc1trXSAtIHZhbHVlVGFyZ2V0KSAmJiBpICsgMSA8IGspIC0taztcblxuICAgIHZhciB2YWx1ZUxlZnQgPSBzdW1zW2tdIC0gdmFsdWVPZmZzZXQsXG4gICAgICAgIHZhbHVlUmlnaHQgPSB2YWx1ZSAtIHZhbHVlTGVmdDtcblxuICAgIGlmICgoeDEgLSB4MCkgPiAoeTEgLSB5MCkpIHtcbiAgICAgIHZhciB4ayA9ICh4MCAqIHZhbHVlUmlnaHQgKyB4MSAqIHZhbHVlTGVmdCkgLyB2YWx1ZTtcbiAgICAgIHBhcnRpdGlvbihpLCBrLCB2YWx1ZUxlZnQsIHgwLCB5MCwgeGssIHkxKTtcbiAgICAgIHBhcnRpdGlvbihrLCBqLCB2YWx1ZVJpZ2h0LCB4aywgeTAsIHgxLCB5MSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHZhciB5ayA9ICh5MCAqIHZhbHVlUmlnaHQgKyB5MSAqIHZhbHVlTGVmdCkgLyB2YWx1ZTtcbiAgICAgIHBhcnRpdGlvbihpLCBrLCB2YWx1ZUxlZnQsIHgwLCB5MCwgeDEsIHlrKTtcbiAgICAgIHBhcnRpdGlvbihrLCBqLCB2YWx1ZVJpZ2h0LCB4MCwgeWssIHgxLCB5MSk7XG4gICAgfVxuICB9XG59O1xuXG52YXIgdHJlZW1hcFNsaWNlRGljZSA9IGZ1bmN0aW9uKHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgKHBhcmVudC5kZXB0aCAmIDEgPyB0cmVlbWFwU2xpY2UgOiB0cmVlbWFwRGljZSkocGFyZW50LCB4MCwgeTAsIHgxLCB5MSk7XG59O1xuXG52YXIgdHJlZW1hcFJlc3F1YXJpZnkgPSAoZnVuY3Rpb24gY3VzdG9tKHJhdGlvKSB7XG5cbiAgZnVuY3Rpb24gcmVzcXVhcmlmeShwYXJlbnQsIHgwLCB5MCwgeDEsIHkxKSB7XG4gICAgaWYgKChyb3dzID0gcGFyZW50Ll9zcXVhcmlmeSkgJiYgKHJvd3MucmF0aW8gPT09IHJhdGlvKSkge1xuICAgICAgdmFyIHJvd3MsXG4gICAgICAgICAgcm93LFxuICAgICAgICAgIG5vZGVzLFxuICAgICAgICAgIGksXG4gICAgICAgICAgaiA9IC0xLFxuICAgICAgICAgIG4sXG4gICAgICAgICAgbSA9IHJvd3MubGVuZ3RoLFxuICAgICAgICAgIHZhbHVlID0gcGFyZW50LnZhbHVlO1xuXG4gICAgICB3aGlsZSAoKytqIDwgbSkge1xuICAgICAgICByb3cgPSByb3dzW2pdLCBub2RlcyA9IHJvdy5jaGlsZHJlbjtcbiAgICAgICAgZm9yIChpID0gcm93LnZhbHVlID0gMCwgbiA9IG5vZGVzLmxlbmd0aDsgaSA8IG47ICsraSkgcm93LnZhbHVlICs9IG5vZGVzW2ldLnZhbHVlO1xuICAgICAgICBpZiAocm93LmRpY2UpIHRyZWVtYXBEaWNlKHJvdywgeDAsIHkwLCB4MSwgeTAgKz0gKHkxIC0geTApICogcm93LnZhbHVlIC8gdmFsdWUpO1xuICAgICAgICBlbHNlIHRyZWVtYXBTbGljZShyb3csIHgwLCB5MCwgeDAgKz0gKHgxIC0geDApICogcm93LnZhbHVlIC8gdmFsdWUsIHkxKTtcbiAgICAgICAgdmFsdWUgLT0gcm93LnZhbHVlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBwYXJlbnQuX3NxdWFyaWZ5ID0gcm93cyA9IHNxdWFyaWZ5UmF0aW8ocmF0aW8sIHBhcmVudCwgeDAsIHkwLCB4MSwgeTEpO1xuICAgICAgcm93cy5yYXRpbyA9IHJhdGlvO1xuICAgIH1cbiAgfVxuXG4gIHJlc3F1YXJpZnkucmF0aW8gPSBmdW5jdGlvbih4KSB7XG4gICAgcmV0dXJuIGN1c3RvbSgoeCA9ICt4KSA+IDEgPyB4IDogMSk7XG4gIH07XG5cbiAgcmV0dXJuIHJlc3F1YXJpZnk7XG59KShwaGkpO1xuXG4vKipcbiAgKiBOZXN0IHR1cGxlcyBpbnRvIGEgdHJlZSBzdHJ1Y3R1cmUsIGdyb3VwZWQgYnkga2V5IHZhbHVlcy5cbiAgKiBAY29uc3RydWN0b3JcbiAgKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gICogQHBhcmFtIHtBcnJheTxmdW5jdGlvbihvYmplY3QpOiAqPn0gcGFyYW1zLmtleXMgLSBUaGUga2V5IGZpZWxkcyB0byBuZXN0IGJ5LCBpbiBvcmRlci5cbiAgKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IFtwYXJhbXMua2V5XSAtIFVuaXF1ZSBrZXkgZmllbGQgZm9yIGVhY2ggdHVwbGUuXG4gICogICBJZiBub3QgcHJvdmlkZWQsIHRoZSB0dXBsZSBpZCBmaWVsZCBpcyB1c2VkLlxuICAqIEBwYXJhbSB7Ym9vbGVhbn0gW3BhcmFtcy5nZW5lcmF0ZT1mYWxzZV0gLSBBIGJvb2xlYW4gZmxhZyBpbmRpY2F0aW5nIGlmXG4gICogICBub24tbGVhZiBub2RlcyBnZW5lcmF0ZWQgYnkgdGhpcyB0cmFuc2Zvcm0gc2hvdWxkIGJlIGluY2x1ZGVkIGluIHRoZVxuICAqICAgb3V0cHV0LiBUaGUgZGVmYXVsdCAoZmFsc2UpIGluY2x1ZGVzIG9ubHkgdGhlIGlucHV0IGRhdGEgKGxlYWYgbm9kZXMpXG4gICogICBpbiB0aGUgZGF0YSBzdHJlYW0uXG4gICovXG5mdW5jdGlvbiBOZXN0KHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5OZXN0LkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIk5lc3RcIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJ0cmVlc291cmNlXCI6IHRydWUsIFwiZ2VuZXJhdGVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJrZXlzXCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwiYXJyYXlcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwia2V5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcImdlbmVyYXRlXCIsIFwidHlwZVwiOiBcImJvb2xlYW5cIiB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkNzEgPSBpbmhlcml0cyhOZXN0LCBUcmFuc2Zvcm0pO1xuXG5mdW5jdGlvbiBjaGlsZHJlbihuKSB7XG4gIHJldHVybiBuLnZhbHVlcztcbn1cblxucHJvdG90eXBlJDcxLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGlmICghcHVsc2Uuc291cmNlKSB7XG4gICAgZXJyb3IkMSgnTmVzdCB0cmFuc2Zvcm0gcmVxdWlyZXMgYW4gdXBzdHJlYW0gZGF0YSBzb3VyY2UuJyk7XG4gIH1cblxuICB2YXIga2V5JCQxID0gXy5rZXkgfHwgdHVwbGVpZCxcbiAgICAgIGdlbiA9IF8uZ2VuZXJhdGUsXG4gICAgICBtb2QgPSBfLm1vZGlmaWVkKCksXG4gICAgICBvdXQgPSBnZW4gfHwgbW9kID8gcHVsc2UuZm9yayhwdWxzZS5BTEwpIDogcHVsc2UsXG4gICAgICByb290LCB0cmVlLCBtYXAkJDE7XG5cbiAgaWYgKCF0aGlzLnZhbHVlIHx8IG1vZCB8fCBwdWxzZS5jaGFuZ2VkKCkpIHtcbiAgICAvLyBjb2xsZWN0IG5vZGVzIHRvIHJlbW92ZVxuICAgIGlmIChnZW4gJiYgdGhpcy52YWx1ZSkge1xuICAgICAgb3V0Lm1hdGVyaWFsaXplKG91dC5SRU0pO1xuICAgICAgdGhpcy52YWx1ZS5lYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIG91dC5yZW0ucHVzaChub2RlKTtcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIC8vIGdlbmVyYXRlIG5ldyB0cmVlIHN0cnVjdHVyZVxuICAgIHJvb3QgPSBhcnJheShfLmtleXMpXG4gICAgICAucmVkdWNlKGZ1bmN0aW9uKG4sIGspIHsgbi5rZXkoayk7IHJldHVybiBuOyB9LCBuZXN0KCkpXG4gICAgICAuZW50cmllcyhvdXQubWF0ZXJpYWxpemUob3V0LlNPVVJDRSkuc291cmNlKTtcbiAgICB0aGlzLnZhbHVlID0gdHJlZSA9IGhpZXJhcmNoeSh7dmFsdWVzOiByb290fSwgY2hpbGRyZW4pO1xuXG4gICAgLy8gY29sbGVjdCBub2RlcyB0byBhZGRcbiAgICBpZiAoZ2VuKSB7XG4gICAgICBvdXQubWF0ZXJpYWxpemUob3V0LkFERCk7XG4gICAgICBvdXQuc291cmNlID0gb3V0LnNvdXJjZS5zbGljZSgpO1xuICAgICAgdHJlZS5lYWNoKGZ1bmN0aW9uKG5vZGUpIHtcbiAgICAgICAgaWYgKG5vZGUuY2hpbGRyZW4pIHtcbiAgICAgICAgICBub2RlID0gaW5nZXN0KG5vZGUuZGF0YSk7XG4gICAgICAgICAgb3V0LmFkZC5wdXNoKG5vZGUpO1xuICAgICAgICAgIG91dC5zb3VyY2UucHVzaChub2RlKTtcbiAgICAgICAgfVxuICAgICAgfSk7XG4gICAgfVxuXG4gICAgLy8gYnVpbGQgbG9va3VwIHRhYmxlXG4gICAgbWFwJCQxID0gdHJlZS5sb29rdXAgPSB7fTtcbiAgICB0cmVlLmVhY2goZnVuY3Rpb24obm9kZSkge1xuICAgICAgaWYgKHR1cGxlaWQobm9kZS5kYXRhKSAhPSBudWxsKSB7XG4gICAgICAgIG1hcCQkMVtrZXkkJDEobm9kZS5kYXRhKV0gPSBub2RlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgb3V0LnNvdXJjZS5yb290ID0gdGhpcy52YWx1ZTtcbiAgcmV0dXJuIG91dDtcbn07XG5cbi8qKlxuICogQWJzdHJhY3QgY2xhc3MgZm9yIHRyZWUgbGF5b3V0LlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIEhpZXJhcmNoeUxheW91dChwYXJhbXMpIHtcbiAgVHJhbnNmb3JtLmNhbGwodGhpcywgbnVsbCwgcGFyYW1zKTtcbn1cblxudmFyIHByb3RvdHlwZSQ3MyA9IGluaGVyaXRzKEhpZXJhcmNoeUxheW91dCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDczLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGlmICghcHVsc2Uuc291cmNlIHx8ICFwdWxzZS5zb3VyY2Uucm9vdCkge1xuICAgIGVycm9yJDEodGhpcy5jb25zdHJ1Y3Rvci5uYW1lXG4gICAgICArICcgdHJhbnNmb3JtIHJlcXVpcmVzIGEgYmFja2luZyB0cmVlIGRhdGEgc291cmNlLicpO1xuICB9XG5cbiAgdmFyIGxheW91dCA9IHRoaXMubGF5b3V0KF8ubWV0aG9kKSxcbiAgICAgIGZpZWxkcyA9IHRoaXMuZmllbGRzLFxuICAgICAgcm9vdCA9IHB1bHNlLnNvdXJjZS5yb290LFxuICAgICAgYXMgPSBfLmFzIHx8IGZpZWxkcztcblxuICBpZiAoXy5maWVsZCkgcm9vdC5zdW0oXy5maWVsZCk7XG4gIGlmIChfLnNvcnQpIHJvb3Quc29ydChfLnNvcnQpO1xuXG4gIHNldFBhcmFtcyhsYXlvdXQsIHRoaXMucGFyYW1zLCBfKTtcbiAgdHJ5IHtcbiAgICB0aGlzLnZhbHVlID0gbGF5b3V0KHJvb3QpO1xuICB9IGNhdGNoIChlcnIpIHtcbiAgICBlcnJvciQxKGVycik7XG4gIH1cbiAgcm9vdC5lYWNoKGZ1bmN0aW9uKG5vZGUpIHsgc2V0RmllbGRzKG5vZGUsIGZpZWxkcywgYXMpOyB9KTtcblxuICByZXR1cm4gcHVsc2UucmVmbG93KF8ubW9kaWZpZWQoKSkubW9kaWZpZXMoYXMpLm1vZGlmaWVzKCdsZWFmJyk7XG59O1xuXG5mdW5jdGlvbiBzZXRQYXJhbXMobGF5b3V0LCBwYXJhbXMsIF8pIHtcbiAgZm9yICh2YXIgcCwgaT0wLCBuPXBhcmFtcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgcCA9IHBhcmFtc1tpXTtcbiAgICBpZiAocCBpbiBfKSBsYXlvdXRbcF0oX1twXSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gc2V0RmllbGRzKG5vZGUsIGZpZWxkcywgYXMpIHtcbiAgdmFyIHQgPSBub2RlLmRhdGE7XG4gIGZvciAodmFyIGk9MCwgbj1maWVsZHMubGVuZ3RoLTE7IGk8bjsgKytpKSB7XG4gICAgdFthc1tpXV0gPSBub2RlW2ZpZWxkc1tpXV07XG4gIH1cbiAgdFthc1tuXV0gPSBub2RlLmNoaWxkcmVuID8gbm9kZS5jaGlsZHJlbi5sZW5ndGggOiAwO1xufVxuXG52YXIgT3V0cHV0ID0gWyd4JywgJ3knLCAncicsICdkZXB0aCcsICdjaGlsZHJlbiddO1xuXG4vKipcbiAqIFBhY2tlZCBjaXJjbGUgdHJlZSBsYXlvdXQuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogKn0gcGFyYW1zLmZpZWxkIC0gVGhlIHZhbHVlIGZpZWxkIHRvIHNpemUgbm9kZXMuXG4gKi9cbmZ1bmN0aW9uIFBhY2socGFyYW1zKSB7XG4gIEhpZXJhcmNoeUxheW91dC5jYWxsKHRoaXMsIHBhcmFtcyk7XG59XG5cblBhY2suRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiUGFja1wiLFxuICBcIm1ldGFkYXRhXCI6IHtcInRyZWVcIjogdHJ1ZSwgXCJtb2RpZmllc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwic29ydFwiLCBcInR5cGVcIjogXCJjb21wYXJlXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcInBhZGRpbmdcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJyYWRpdXNcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJkZWZhdWx0XCI6IG51bGwgfSxcbiAgICB7IFwibmFtZVwiOiBcInNpemVcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMywgXCJkZWZhdWx0XCI6IE91dHB1dCB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkNzIgPSBpbmhlcml0cyhQYWNrLCBIaWVyYXJjaHlMYXlvdXQpO1xuXG5wcm90b3R5cGUkNzIubGF5b3V0ID0gcGFjayQxO1xuXG5wcm90b3R5cGUkNzIucGFyYW1zID0gWydzaXplJywgJ3BhZGRpbmcnXTtcblxucHJvdG90eXBlJDcyLmZpZWxkcyA9IE91dHB1dDtcblxudmFyIE91dHB1dCQxID0gW1wieDBcIiwgXCJ5MFwiLCBcIngxXCIsIFwieTFcIiwgXCJkZXB0aFwiLCBcImNoaWxkcmVuXCJdO1xuXG4vKipcbiAqIFBhcnRpdGlvbiB0cmVlIGxheW91dC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGQgLSBUaGUgdmFsdWUgZmllbGQgdG8gc2l6ZSBub2Rlcy5cbiAqL1xuZnVuY3Rpb24gUGFydGl0aW9uKHBhcmFtcykge1xuICBIaWVyYXJjaHlMYXlvdXQuY2FsbCh0aGlzLCBwYXJhbXMpO1xufVxuXG5QYXJ0aXRpb24uRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiUGFydGl0aW9uXCIsXG4gIFwibWV0YWRhdGFcIjoge1widHJlZVwiOiB0cnVlLCBcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJzb3J0XCIsIFwidHlwZVwiOiBcImNvbXBhcmVcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwicGFkZGluZ1wiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICB7IFwibmFtZVwiOiBcInJvdW5kXCIsIFwidHlwZVwiOiBcImJvb2xlYW5cIiwgXCJkZWZhdWx0XCI6IGZhbHNlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJzaXplXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIgfSxcbiAgICB7IFwibmFtZVwiOiBcImFzXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDQsIFwiZGVmYXVsdFwiOiBPdXRwdXQkMSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkNzQgPSBpbmhlcml0cyhQYXJ0aXRpb24sIEhpZXJhcmNoeUxheW91dCk7XG5cbnByb3RvdHlwZSQ3NC5sYXlvdXQgPSBwYXJ0aXRpb24kMjtcblxucHJvdG90eXBlJDc0LnBhcmFtcyA9IFsnc2l6ZScsICdyb3VuZCcsICdwYWRkaW5nJ107XG5cbnByb3RvdHlwZSQ3NC5maWVsZHMgPSBPdXRwdXQkMTtcblxuLyoqXG4gICogU3RyYXRpZnkgYSBjb2xsZWN0aW9uIG9mIHR1cGxlcyBpbnRvIGEgdHJlZSBzdHJ1Y3R1cmUgYmFzZWQgb25cbiAgKiBpZCBhbmQgcGFyZW50IGlkIGZpZWxkcy5cbiAgKiBAY29uc3RydWN0b3JcbiAgKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMua2V5IC0gVW5pcXVlIGtleSBmaWVsZCBmb3IgZWFjaCB0dXBsZS5cbiAgKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6ICp9IHBhcmFtcy5wYXJlbnRLZXkgLSBGaWVsZCB3aXRoIGtleSBmb3IgcGFyZW50IHR1cGxlLlxuICAqL1xuZnVuY3Rpb24gU3RyYXRpZnkocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIG51bGwsIHBhcmFtcyk7XG59XG5cblN0cmF0aWZ5LkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIlN0cmF0aWZ5XCIsXG4gIFwibWV0YWRhdGFcIjoge1widHJlZXNvdXJjZVwiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwia2V5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwicmVxdWlyZWRcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwicGFyZW50S2V5XCIsIFwidHlwZVwiOiBcImZpZWxkXCIsIFwicmVxdWlyZWRcIjogdHJ1ZSAgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDc1ID0gaW5oZXJpdHMoU3RyYXRpZnksIFRyYW5zZm9ybSk7XG5cbnByb3RvdHlwZSQ3NS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICBpZiAoIXB1bHNlLnNvdXJjZSkge1xuICAgIGVycm9yJDEoJ1N0cmF0aWZ5IHRyYW5zZm9ybSByZXF1aXJlcyBhbiB1cHN0cmVhbSBkYXRhIHNvdXJjZS4nKTtcbiAgfVxuXG4gIHZhciBtb2QgPSBfLm1vZGlmaWVkKCksIHRyZWUsIG1hcCxcbiAgICAgIHJ1biA9ICF0aGlzLnZhbHVlXG4gICAgICAgICB8fCBtb2RcbiAgICAgICAgIHx8IHB1bHNlLmNoYW5nZWQocHVsc2UuQUREX1JFTSlcbiAgICAgICAgIHx8IHB1bHNlLm1vZGlmaWVkKF8ua2V5LmZpZWxkcylcbiAgICAgICAgIHx8IHB1bHNlLm1vZGlmaWVkKF8ucGFyZW50S2V5LmZpZWxkcyk7XG5cbiAgaWYgKHJ1bikge1xuICAgIHRyZWUgPSBzdHJhdGlmeSgpLmlkKF8ua2V5KS5wYXJlbnRJZChfLnBhcmVudEtleSkocHVsc2Uuc291cmNlKTtcbiAgICBtYXAgPSB0cmVlLmxvb2t1cCA9IHt9O1xuICAgIHRyZWUuZWFjaChmdW5jdGlvbihub2RlKSB7IG1hcFtfLmtleShub2RlLmRhdGEpXSA9IG5vZGU7IH0pO1xuICAgIHRoaXMudmFsdWUgPSB0cmVlO1xuICB9XG5cbiAgcHVsc2Uuc291cmNlLnJvb3QgPSB0aGlzLnZhbHVlO1xuICByZXR1cm4gbW9kID8gcHVsc2UuZm9yayhwdWxzZS5BTEwpIDogcHVsc2U7XG59O1xuXG52YXIgTGF5b3V0cyA9IHtcbiAgdGlkeTogdHJlZSQxLFxuICBjbHVzdGVyOiBjbHVzdGVyXG59O1xuXG52YXIgT3V0cHV0JDIgPSBbXCJ4XCIsIFwieVwiLCBcImRlcHRoXCIsIFwiY2hpbGRyZW5cIl07XG5cbi8qKlxuICogVHJlZSBsYXlvdXQuIERlcGVuZGluZyBvbiB0aGUgbWV0aG9kIHBhcmFtZXRlciwgcGVyZm9ybXMgZWl0aGVyXG4gKiBSZWluZ29sZC1UaWxmb3JkICd0aWR5JyBsYXlvdXQgb3IgZGVuZHJvZ3JhbSAnY2x1c3RlcicgbGF5b3V0LlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zIC0gVGhlIHBhcmFtZXRlcnMgZm9yIHRoaXMgb3BlcmF0b3IuXG4gKi9cbmZ1bmN0aW9uIFRyZWUocGFyYW1zKSB7XG4gIEhpZXJhcmNoeUxheW91dC5jYWxsKHRoaXMsIHBhcmFtcyk7XG59XG5cblRyZWUuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiVHJlZVwiLFxuICBcIm1ldGFkYXRhXCI6IHtcInRyZWVcIjogdHJ1ZSwgXCJtb2RpZmllc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiZmllbGRcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwic29ydFwiLCBcInR5cGVcIjogXCJjb21wYXJlXCIgfSxcbiAgICB7IFwibmFtZVwiOiBcIm1ldGhvZFwiLCBcInR5cGVcIjogXCJlbnVtXCIsIFwiZGVmYXVsdFwiOiBcInRpZHlcIiwgXCJ2YWx1ZXNcIjogW1widGlkeVwiLCBcImNsdXN0ZXJcIl0gfSxcbiAgICB7IFwibmFtZVwiOiBcInNpemVcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiB9LFxuICAgIHsgXCJuYW1lXCI6IFwibm9kZVNpemVcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogMiB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogNCwgXCJkZWZhdWx0XCI6IE91dHB1dCQyIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQ3NiA9IGluaGVyaXRzKFRyZWUsIEhpZXJhcmNoeUxheW91dCk7XG5cbi8qKlxuICogVHJlZSBsYXlvdXQgZ2VuZXJhdG9yLiBTdXBwb3J0cyBib3RoICd0aWR5JyBhbmQgJ2NsdXN0ZXInIGxheW91dHMuXG4gKi9cbnByb3RvdHlwZSQ3Ni5sYXlvdXQgPSBmdW5jdGlvbihtZXRob2QpIHtcbiAgdmFyIG0gPSBtZXRob2QgfHwgJ3RpZHknO1xuICBpZiAoTGF5b3V0cy5oYXNPd25Qcm9wZXJ0eShtKSkgcmV0dXJuIExheW91dHNbbV0oKTtcbiAgZWxzZSBlcnJvciQxKCdVbnJlY29nbml6ZWQgVHJlZSBsYXlvdXQgbWV0aG9kOiAnICsgbSk7XG59O1xuXG5wcm90b3R5cGUkNzYucGFyYW1zID0gWydzaXplJywgJ25vZGVTaXplJywgJ3NlcGFyYXRpb24nXTtcblxucHJvdG90eXBlJDc2LmZpZWxkcyA9IE91dHB1dCQyO1xuXG4vKipcbiAgKiBHZW5lcmF0ZSB0dXBsZXMgcmVwcmVzZW50aW5nIGxpbmtzIGJldHdlZW4gdHJlZSBub2Rlcy5cbiAgKiBUaGUgcmVzdWx0aW5nIHR1cGxlcyB3aWxsIGNvbnRhaW4gJ3NvdXJjZScgYW5kICd0YXJnZXQnIGZpZWxkcyxcbiAgKiB3aGljaCBwb2ludCB0byBwYXJlbnQgYW5kIGNoaWxkIG5vZGUgdHVwbGVzLCByZXNwZWN0aXZlbHkuXG4gICogQGNvbnN0cnVjdG9yXG4gICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICAqIEBwYXJhbSB7ZnVuY3Rpb24ob2JqZWN0KTogKn0gW3BhcmFtcy5rZXldIC0gVW5pcXVlIGtleSBmaWVsZCBmb3IgZWFjaCB0dXBsZS5cbiAgKiAgIElmIG5vdCBwcm92aWRlZCwgdGhlIHR1cGxlIGlkIGZpZWxkIGlzIHVzZWQuXG4gICovXG5mdW5jdGlvbiBUcmVlTGlua3MocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIHt9LCBwYXJhbXMpO1xufVxuXG5UcmVlTGlua3MuRGVmaW5pdGlvbiA9IHtcbiAgXCJ0eXBlXCI6IFwiVHJlZUxpbmtzXCIsXG4gIFwibWV0YWRhdGFcIjoge1widHJlZVwiOiB0cnVlLCBcImdlbmVyYXRlc1wiOiB0cnVlLCBcImNoYW5nZXNcIjogdHJ1ZX0sXG4gIFwicGFyYW1zXCI6IFtcbiAgICB7IFwibmFtZVwiOiBcImtleVwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQ3NyA9IGluaGVyaXRzKFRyZWVMaW5rcywgVHJhbnNmb3JtKTtcblxuZnVuY3Rpb24gcGFyZW50VHVwbGUobm9kZSkge1xuICB2YXIgcDtcbiAgcmV0dXJuIG5vZGUucGFyZW50XG4gICAgICAmJiAocD1ub2RlLnBhcmVudC5kYXRhKVxuICAgICAgJiYgKHR1cGxlaWQocCkgIT0gbnVsbCkgJiYgcDtcbn1cblxucHJvdG90eXBlJDc3LnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGlmICghcHVsc2Uuc291cmNlIHx8ICFwdWxzZS5zb3VyY2Uucm9vdCkge1xuICAgIGVycm9yJDEoJ1RyZWVMaW5rcyB0cmFuc2Zvcm0gcmVxdWlyZXMgYSBiYWNraW5nIHRyZWUgZGF0YSBzb3VyY2UuJyk7XG4gIH1cblxuICB2YXIgcm9vdCA9IHB1bHNlLnNvdXJjZS5yb290LFxuICAgICAgbm9kZXMgPSByb290Lmxvb2t1cCxcbiAgICAgIGxpbmtzID0gdGhpcy52YWx1ZSxcbiAgICAgIGtleSQkMSA9IF8ua2V5IHx8IHR1cGxlaWQsXG4gICAgICBtb2RzID0ge30sXG4gICAgICBvdXQgPSBwdWxzZS5mb3JrKCk7XG5cbiAgZnVuY3Rpb24gbW9kaWZ5KGlkJCQxKSB7XG4gICAgdmFyIGxpbmsgPSBsaW5rc1tpZCQkMV07XG4gICAgaWYgKGxpbmspIHtcbiAgICAgIG1vZHNbaWQkJDFdID0gMTtcbiAgICAgIG91dC5tb2QucHVzaChsaW5rKTtcbiAgICB9XG4gIH1cblxuICAvLyBwcm9jZXNzIHJlbW92ZWQgdHVwbGVzXG4gIC8vIGFzc3VtZXMgdGhhdCBpZiBhIHBhcmVudCBub2RlIGlzIHJlbW92ZWQgdGhlIGNoaWxkIHdpbGwgYmUsIHRvby5cbiAgcHVsc2UudmlzaXQocHVsc2UuUkVNLCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGlkJCQxID0ga2V5JCQxKHQpLFxuICAgICAgICBsaW5rID0gbGlua3NbaWQkJDFdO1xuICAgIGlmIChsaW5rKSB7XG4gICAgICBkZWxldGUgbGlua3NbaWQkJDFdO1xuICAgICAgb3V0LnJlbS5wdXNoKGxpbmspO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gY3JlYXRlIG5ldyBsaW5rIGluc3RhbmNlcyBmb3IgYWRkZWQgbm9kZXMgd2l0aCB2YWxpZCBwYXJlbnRzXG4gIHB1bHNlLnZpc2l0KHB1bHNlLkFERCwgZnVuY3Rpb24odCkge1xuICAgIHZhciBpZCQkMSA9IGtleSQkMSh0KSwgcDtcbiAgICBpZiAocCA9IHBhcmVudFR1cGxlKG5vZGVzW2lkJCQxXSkpIHtcbiAgICAgIG91dC5hZGQucHVzaChsaW5rc1tpZCQkMV0gPSBpbmdlc3Qoe3NvdXJjZTogcCwgdGFyZ2V0OiB0fSkpO1xuICAgICAgbW9kc1tpZCQkMV0gPSAxO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gcHJvY2VzcyBtb2RpZmllZCBub2RlcyBhbmQgdGhlaXIgY2hpbGRyZW5cbiAgcHVsc2UudmlzaXQocHVsc2UuTU9ELCBmdW5jdGlvbih0KSB7XG4gICAgdmFyIGlkJCQxID0ga2V5JCQxKHQpLFxuICAgICAgICBub2RlID0gbm9kZXNbaWQkJDFdLFxuICAgICAgICBraWRzID0gbm9kZS5jaGlsZHJlbjtcblxuICAgIG1vZGlmeShpZCQkMSk7XG4gICAgaWYgKGtpZHMpIGZvciAodmFyIGk9MCwgbj1raWRzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICAgIGlmICghbW9kc1soaWQkJDE9a2V5JCQxKGtpZHNbaV0uZGF0YSkpXSkgbW9kaWZ5KGlkJCQxKTtcbiAgICB9XG4gIH0pO1xuXG4gIHJldHVybiBvdXQ7XG59O1xuXG52YXIgVGlsZXMgPSB7XG4gIGJpbmFyeTogdHJlZW1hcEJpbmFyeSxcbiAgZGljZTogdHJlZW1hcERpY2UsXG4gIHNsaWNlOiB0cmVlbWFwU2xpY2UsXG4gIHNsaWNlZGljZTogdHJlZW1hcFNsaWNlRGljZSxcbiAgc3F1YXJpZnk6IHRyZWVtYXBTcXVhcmlmeSxcbiAgcmVzcXVhcmlmeTogdHJlZW1hcFJlc3F1YXJpZnlcbn07XG5cbnZhciBPdXRwdXQkMyA9IFtcIngwXCIsIFwieTBcIiwgXCJ4MVwiLCBcInkxXCIsIFwiZGVwdGhcIiwgXCJjaGlsZHJlblwiXTtcblxuLyoqXG4gKiBUcmVlbWFwIGxheW91dC5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtmdW5jdGlvbihvYmplY3QpOiAqfSBwYXJhbXMuZmllbGQgLSBUaGUgdmFsdWUgZmllbGQgdG8gc2l6ZSBub2Rlcy5cbiAqL1xuZnVuY3Rpb24gVHJlZW1hcChwYXJhbXMpIHtcbiAgSGllcmFyY2h5TGF5b3V0LmNhbGwodGhpcywgcGFyYW1zKTtcbn1cblxuVHJlZW1hcC5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJUcmVlbWFwXCIsXG4gIFwibWV0YWRhdGFcIjoge1widHJlZVwiOiB0cnVlLCBcIm1vZGlmaWVzXCI6IHRydWV9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZFwiLCBcInR5cGVcIjogXCJmaWVsZFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJzb3J0XCIsIFwidHlwZVwiOiBcImNvbXBhcmVcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwibWV0aG9kXCIsIFwidHlwZVwiOiBcImVudW1cIiwgXCJkZWZhdWx0XCI6IFwic3F1YXJpZnlcIixcbiAgICAgIFwidmFsdWVzXCI6IFtcInNxdWFyaWZ5XCIsIFwicmVzcXVhcmlmeVwiLCBcImJpbmFyeVwiLCBcImRpY2VcIiwgXCJzbGljZVwiLCBcInNsaWNlZGljZVwiXSB9LFxuICAgIHsgXCJuYW1lXCI6IFwicGFkZGluZ1wiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICB7IFwibmFtZVwiOiBcInBhZGRpbmdJbm5lclwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICB7IFwibmFtZVwiOiBcInBhZGRpbmdPdXRlclwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICB7IFwibmFtZVwiOiBcInBhZGRpbmdUb3BcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJwYWRkaW5nUmlnaHRcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJwYWRkaW5nQm90dG9tXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImRlZmF1bHRcIjogMCB9LFxuICAgIHsgXCJuYW1lXCI6IFwicGFkZGluZ0xlZnRcIiwgXCJ0eXBlXCI6IFwibnVtYmVyXCIsIFwiZGVmYXVsdFwiOiAwIH0sXG4gICAgeyBcIm5hbWVcIjogXCJyYXRpb1wiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJkZWZhdWx0XCI6IDEuNjE4MDMzOTg4NzQ5ODk1IH0sXG4gICAgeyBcIm5hbWVcIjogXCJyb3VuZFwiLCBcInR5cGVcIjogXCJib29sZWFuXCIsIFwiZGVmYXVsdFwiOiBmYWxzZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwic2l6ZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiAyIH0sXG4gICAgeyBcIm5hbWVcIjogXCJhc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiA0LCBcImRlZmF1bHRcIjogT3V0cHV0JDMgfVxuICBdXG59O1xuXG52YXIgcHJvdG90eXBlJDc4ID0gaW5oZXJpdHMoVHJlZW1hcCwgSGllcmFyY2h5TGF5b3V0KTtcblxuLyoqXG4gKiBUcmVlbWFwIGxheW91dCBnZW5lcmF0b3IuIEFkZHMgJ21ldGhvZCcgYW5kICdyYXRpbycgcGFyYW1ldGVyc1xuICogdG8gY29uZmlndXJlIHRoZSB1bmRlcmx5aW5nIHRpbGUgbWV0aG9kLlxuICovXG5wcm90b3R5cGUkNzgubGF5b3V0ID0gZnVuY3Rpb24oKSB7XG4gIHZhciB4ID0gdHJlZW1hcCgpO1xuICB4LnJhdGlvID0gZnVuY3Rpb24oXykge1xuICAgIHZhciB0ID0geC50aWxlKCk7XG4gICAgaWYgKHQucmF0aW8pIHgudGlsZSh0LnJhdGlvKF8pKTtcbiAgfTtcbiAgeC5tZXRob2QgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKFRpbGVzLmhhc093blByb3BlcnR5KF8pKSB4LnRpbGUoVGlsZXNbX10pO1xuICAgIGVsc2UgZXJyb3IkMSgnVW5yZWNvZ25pemVkIFRyZWVtYXAgbGF5b3V0IG1ldGhvZDogJyArIF8pO1xuICB9O1xuICByZXR1cm4geDtcbn07XG5cbnByb3RvdHlwZSQ3OC5wYXJhbXMgPSBbXG4gICdtZXRob2QnLCAncmF0aW8nLCAnc2l6ZScsICdyb3VuZCcsXG4gICdwYWRkaW5nJywgJ3BhZGRpbmdJbm5lcicsICdwYWRkaW5nT3V0ZXInLFxuICAncGFkZGluZ1RvcCcsICdwYWRkaW5nUmlnaHQnLCAncGFkZGluZ0JvdHRvbScsICdwYWRkaW5nTGVmdCdcbl07XG5cbnByb3RvdHlwZSQ3OC5maWVsZHMgPSBPdXRwdXQkMztcblxuXG5cbnZhciB0cmVlID0gT2JqZWN0LmZyZWV6ZSh7XG5cdG5lc3Q6IE5lc3QsXG5cdHBhY2s6IFBhY2ssXG5cdHBhcnRpdGlvbjogUGFydGl0aW9uLFxuXHRzdHJhdGlmeTogU3RyYXRpZnksXG5cdHRyZWU6IFRyZWUsXG5cdHRyZWVsaW5rczogVHJlZUxpbmtzLFxuXHR0cmVlbWFwOiBUcmVlbWFwXG59KTtcblxudmFyIGNvbnN0YW50JDEwID0gZnVuY3Rpb24oeCkge1xuICByZXR1cm4gZnVuY3Rpb24oKSB7XG4gICAgcmV0dXJuIHg7XG4gIH07XG59O1xuXG5mdW5jdGlvbiB4JDQoZCkge1xuICByZXR1cm4gZFswXTtcbn1cblxuZnVuY3Rpb24geSQ0KGQpIHtcbiAgcmV0dXJuIGRbMV07XG59XG5cbmZ1bmN0aW9uIFJlZEJsYWNrVHJlZSgpIHtcbiAgdGhpcy5fID0gbnVsbDsgLy8gcm9vdCBub2RlXG59XG5cbmZ1bmN0aW9uIFJlZEJsYWNrTm9kZShub2RlKSB7XG4gIG5vZGUuVSA9IC8vIHBhcmVudCBub2RlXG4gIG5vZGUuQyA9IC8vIGNvbG9yIC0gdHJ1ZSBmb3IgcmVkLCBmYWxzZSBmb3IgYmxhY2tcbiAgbm9kZS5MID0gLy8gbGVmdCBub2RlXG4gIG5vZGUuUiA9IC8vIHJpZ2h0IG5vZGVcbiAgbm9kZS5QID0gLy8gcHJldmlvdXMgbm9kZVxuICBub2RlLk4gPSBudWxsOyAvLyBuZXh0IG5vZGVcbn1cblxuUmVkQmxhY2tUcmVlLnByb3RvdHlwZSA9IHtcbiAgY29uc3RydWN0b3I6IFJlZEJsYWNrVHJlZSxcblxuICBpbnNlcnQ6IGZ1bmN0aW9uKGFmdGVyLCBub2RlKSB7XG4gICAgdmFyIHBhcmVudCwgZ3JhbmRwYSwgdW5jbGU7XG5cbiAgICBpZiAoYWZ0ZXIpIHtcbiAgICAgIG5vZGUuUCA9IGFmdGVyO1xuICAgICAgbm9kZS5OID0gYWZ0ZXIuTjtcbiAgICAgIGlmIChhZnRlci5OKSBhZnRlci5OLlAgPSBub2RlO1xuICAgICAgYWZ0ZXIuTiA9IG5vZGU7XG4gICAgICBpZiAoYWZ0ZXIuUikge1xuICAgICAgICBhZnRlciA9IGFmdGVyLlI7XG4gICAgICAgIHdoaWxlIChhZnRlci5MKSBhZnRlciA9IGFmdGVyLkw7XG4gICAgICAgIGFmdGVyLkwgPSBub2RlO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgYWZ0ZXIuUiA9IG5vZGU7XG4gICAgICB9XG4gICAgICBwYXJlbnQgPSBhZnRlcjtcbiAgICB9IGVsc2UgaWYgKHRoaXMuXykge1xuICAgICAgYWZ0ZXIgPSBSZWRCbGFja0ZpcnN0KHRoaXMuXyk7XG4gICAgICBub2RlLlAgPSBudWxsO1xuICAgICAgbm9kZS5OID0gYWZ0ZXI7XG4gICAgICBhZnRlci5QID0gYWZ0ZXIuTCA9IG5vZGU7XG4gICAgICBwYXJlbnQgPSBhZnRlcjtcbiAgICB9IGVsc2Uge1xuICAgICAgbm9kZS5QID0gbm9kZS5OID0gbnVsbDtcbiAgICAgIHRoaXMuXyA9IG5vZGU7XG4gICAgICBwYXJlbnQgPSBudWxsO1xuICAgIH1cbiAgICBub2RlLkwgPSBub2RlLlIgPSBudWxsO1xuICAgIG5vZGUuVSA9IHBhcmVudDtcbiAgICBub2RlLkMgPSB0cnVlO1xuXG4gICAgYWZ0ZXIgPSBub2RlO1xuICAgIHdoaWxlIChwYXJlbnQgJiYgcGFyZW50LkMpIHtcbiAgICAgIGdyYW5kcGEgPSBwYXJlbnQuVTtcbiAgICAgIGlmIChwYXJlbnQgPT09IGdyYW5kcGEuTCkge1xuICAgICAgICB1bmNsZSA9IGdyYW5kcGEuUjtcbiAgICAgICAgaWYgKHVuY2xlICYmIHVuY2xlLkMpIHtcbiAgICAgICAgICBwYXJlbnQuQyA9IHVuY2xlLkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIGFmdGVyID0gZ3JhbmRwYTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBpZiAoYWZ0ZXIgPT09IHBhcmVudC5SKSB7XG4gICAgICAgICAgICBSZWRCbGFja1JvdGF0ZUxlZnQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICAgIGFmdGVyID0gcGFyZW50O1xuICAgICAgICAgICAgcGFyZW50ID0gYWZ0ZXIuVTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50LkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgZ3JhbmRwYSk7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHVuY2xlID0gZ3JhbmRwYS5MO1xuICAgICAgICBpZiAodW5jbGUgJiYgdW5jbGUuQykge1xuICAgICAgICAgIHBhcmVudC5DID0gdW5jbGUuQyA9IGZhbHNlO1xuICAgICAgICAgIGdyYW5kcGEuQyA9IHRydWU7XG4gICAgICAgICAgYWZ0ZXIgPSBncmFuZHBhO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGlmIChhZnRlciA9PT0gcGFyZW50LkwpIHtcbiAgICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICAgIGFmdGVyID0gcGFyZW50O1xuICAgICAgICAgICAgcGFyZW50ID0gYWZ0ZXIuVTtcbiAgICAgICAgICB9XG4gICAgICAgICAgcGFyZW50LkMgPSBmYWxzZTtcbiAgICAgICAgICBncmFuZHBhLkMgPSB0cnVlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBncmFuZHBhKTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgICAgcGFyZW50ID0gYWZ0ZXIuVTtcbiAgICB9XG4gICAgdGhpcy5fLkMgPSBmYWxzZTtcbiAgfSxcblxuICByZW1vdmU6IGZ1bmN0aW9uKG5vZGUpIHtcbiAgICBpZiAobm9kZS5OKSBub2RlLk4uUCA9IG5vZGUuUDtcbiAgICBpZiAobm9kZS5QKSBub2RlLlAuTiA9IG5vZGUuTjtcbiAgICBub2RlLk4gPSBub2RlLlAgPSBudWxsO1xuXG4gICAgdmFyIHBhcmVudCA9IG5vZGUuVSxcbiAgICAgICAgc2libGluZyxcbiAgICAgICAgbGVmdCA9IG5vZGUuTCxcbiAgICAgICAgcmlnaHQgPSBub2RlLlIsXG4gICAgICAgIG5leHQsXG4gICAgICAgIHJlZDtcblxuICAgIGlmICghbGVmdCkgbmV4dCA9IHJpZ2h0O1xuICAgIGVsc2UgaWYgKCFyaWdodCkgbmV4dCA9IGxlZnQ7XG4gICAgZWxzZSBuZXh0ID0gUmVkQmxhY2tGaXJzdChyaWdodCk7XG5cbiAgICBpZiAocGFyZW50KSB7XG4gICAgICBpZiAocGFyZW50LkwgPT09IG5vZGUpIHBhcmVudC5MID0gbmV4dDtcbiAgICAgIGVsc2UgcGFyZW50LlIgPSBuZXh0O1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLl8gPSBuZXh0O1xuICAgIH1cblxuICAgIGlmIChsZWZ0ICYmIHJpZ2h0KSB7XG4gICAgICByZWQgPSBuZXh0LkM7XG4gICAgICBuZXh0LkMgPSBub2RlLkM7XG4gICAgICBuZXh0LkwgPSBsZWZ0O1xuICAgICAgbGVmdC5VID0gbmV4dDtcbiAgICAgIGlmIChuZXh0ICE9PSByaWdodCkge1xuICAgICAgICBwYXJlbnQgPSBuZXh0LlU7XG4gICAgICAgIG5leHQuVSA9IG5vZGUuVTtcbiAgICAgICAgbm9kZSA9IG5leHQuUjtcbiAgICAgICAgcGFyZW50LkwgPSBub2RlO1xuICAgICAgICBuZXh0LlIgPSByaWdodDtcbiAgICAgICAgcmlnaHQuVSA9IG5leHQ7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBuZXh0LlUgPSBwYXJlbnQ7XG4gICAgICAgIHBhcmVudCA9IG5leHQ7XG4gICAgICAgIG5vZGUgPSBuZXh0LlI7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIHJlZCA9IG5vZGUuQztcbiAgICAgIG5vZGUgPSBuZXh0O1xuICAgIH1cblxuICAgIGlmIChub2RlKSBub2RlLlUgPSBwYXJlbnQ7XG4gICAgaWYgKHJlZCkgcmV0dXJuO1xuICAgIGlmIChub2RlICYmIG5vZGUuQykgeyBub2RlLkMgPSBmYWxzZTsgcmV0dXJuOyB9XG5cbiAgICBkbyB7XG4gICAgICBpZiAobm9kZSA9PT0gdGhpcy5fKSBicmVhaztcbiAgICAgIGlmIChub2RlID09PSBwYXJlbnQuTCkge1xuICAgICAgICBzaWJsaW5nID0gcGFyZW50LlI7XG4gICAgICAgIGlmIChzaWJsaW5nLkMpIHtcbiAgICAgICAgICBzaWJsaW5nLkMgPSBmYWxzZTtcbiAgICAgICAgICBwYXJlbnQuQyA9IHRydWU7XG4gICAgICAgICAgUmVkQmxhY2tSb3RhdGVMZWZ0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgc2libGluZyA9IHBhcmVudC5SO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoc2libGluZy5MICYmIHNpYmxpbmcuTC5DKVxuICAgICAgICAgICAgfHwgKHNpYmxpbmcuUiAmJiBzaWJsaW5nLlIuQykpIHtcbiAgICAgICAgICBpZiAoIXNpYmxpbmcuUiB8fCAhc2libGluZy5SLkMpIHtcbiAgICAgICAgICAgIHNpYmxpbmcuTC5DID0gZmFsc2U7XG4gICAgICAgICAgICBzaWJsaW5nLkMgPSB0cnVlO1xuICAgICAgICAgICAgUmVkQmxhY2tSb3RhdGVSaWdodCh0aGlzLCBzaWJsaW5nKTtcbiAgICAgICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuUjtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2libGluZy5DID0gcGFyZW50LkM7XG4gICAgICAgICAgcGFyZW50LkMgPSBzaWJsaW5nLlIuQyA9IGZhbHNlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBwYXJlbnQpO1xuICAgICAgICAgIG5vZGUgPSB0aGlzLl87XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuTDtcbiAgICAgICAgaWYgKHNpYmxpbmcuQykge1xuICAgICAgICAgIHNpYmxpbmcuQyA9IGZhbHNlO1xuICAgICAgICAgIHBhcmVudC5DID0gdHJ1ZTtcbiAgICAgICAgICBSZWRCbGFja1JvdGF0ZVJpZ2h0KHRoaXMsIHBhcmVudCk7XG4gICAgICAgICAgc2libGluZyA9IHBhcmVudC5MO1xuICAgICAgICB9XG4gICAgICAgIGlmICgoc2libGluZy5MICYmIHNpYmxpbmcuTC5DKVxuICAgICAgICAgIHx8IChzaWJsaW5nLlIgJiYgc2libGluZy5SLkMpKSB7XG4gICAgICAgICAgaWYgKCFzaWJsaW5nLkwgfHwgIXNpYmxpbmcuTC5DKSB7XG4gICAgICAgICAgICBzaWJsaW5nLlIuQyA9IGZhbHNlO1xuICAgICAgICAgICAgc2libGluZy5DID0gdHJ1ZTtcbiAgICAgICAgICAgIFJlZEJsYWNrUm90YXRlTGVmdCh0aGlzLCBzaWJsaW5nKTtcbiAgICAgICAgICAgIHNpYmxpbmcgPSBwYXJlbnQuTDtcbiAgICAgICAgICB9XG4gICAgICAgICAgc2libGluZy5DID0gcGFyZW50LkM7XG4gICAgICAgICAgcGFyZW50LkMgPSBzaWJsaW5nLkwuQyA9IGZhbHNlO1xuICAgICAgICAgIFJlZEJsYWNrUm90YXRlUmlnaHQodGhpcywgcGFyZW50KTtcbiAgICAgICAgICBub2RlID0gdGhpcy5fO1xuICAgICAgICAgIGJyZWFrO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgICBzaWJsaW5nLkMgPSB0cnVlO1xuICAgICAgbm9kZSA9IHBhcmVudDtcbiAgICAgIHBhcmVudCA9IHBhcmVudC5VO1xuICAgIH0gd2hpbGUgKCFub2RlLkMpO1xuXG4gICAgaWYgKG5vZGUpIG5vZGUuQyA9IGZhbHNlO1xuICB9XG59O1xuXG5mdW5jdGlvbiBSZWRCbGFja1JvdGF0ZUxlZnQodHJlZSwgbm9kZSkge1xuICB2YXIgcCA9IG5vZGUsXG4gICAgICBxID0gbm9kZS5SLFxuICAgICAgcGFyZW50ID0gcC5VO1xuXG4gIGlmIChwYXJlbnQpIHtcbiAgICBpZiAocGFyZW50LkwgPT09IHApIHBhcmVudC5MID0gcTtcbiAgICBlbHNlIHBhcmVudC5SID0gcTtcbiAgfSBlbHNlIHtcbiAgICB0cmVlLl8gPSBxO1xuICB9XG5cbiAgcS5VID0gcGFyZW50O1xuICBwLlUgPSBxO1xuICBwLlIgPSBxLkw7XG4gIGlmIChwLlIpIHAuUi5VID0gcDtcbiAgcS5MID0gcDtcbn1cblxuZnVuY3Rpb24gUmVkQmxhY2tSb3RhdGVSaWdodCh0cmVlLCBub2RlKSB7XG4gIHZhciBwID0gbm9kZSxcbiAgICAgIHEgPSBub2RlLkwsXG4gICAgICBwYXJlbnQgPSBwLlU7XG5cbiAgaWYgKHBhcmVudCkge1xuICAgIGlmIChwYXJlbnQuTCA9PT0gcCkgcGFyZW50LkwgPSBxO1xuICAgIGVsc2UgcGFyZW50LlIgPSBxO1xuICB9IGVsc2Uge1xuICAgIHRyZWUuXyA9IHE7XG4gIH1cblxuICBxLlUgPSBwYXJlbnQ7XG4gIHAuVSA9IHE7XG4gIHAuTCA9IHEuUjtcbiAgaWYgKHAuTCkgcC5MLlUgPSBwO1xuICBxLlIgPSBwO1xufVxuXG5mdW5jdGlvbiBSZWRCbGFja0ZpcnN0KG5vZGUpIHtcbiAgd2hpbGUgKG5vZGUuTCkgbm9kZSA9IG5vZGUuTDtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUVkZ2UobGVmdCwgcmlnaHQsIHYwLCB2MSkge1xuICB2YXIgZWRnZSA9IFtudWxsLCBudWxsXSxcbiAgICAgIGluZGV4ID0gZWRnZXMucHVzaChlZGdlKSAtIDE7XG4gIGVkZ2UubGVmdCA9IGxlZnQ7XG4gIGVkZ2UucmlnaHQgPSByaWdodDtcbiAgaWYgKHYwKSBzZXRFZGdlRW5kKGVkZ2UsIGxlZnQsIHJpZ2h0LCB2MCk7XG4gIGlmICh2MSkgc2V0RWRnZUVuZChlZGdlLCByaWdodCwgbGVmdCwgdjEpO1xuICBjZWxsc1tsZWZ0LmluZGV4XS5oYWxmZWRnZXMucHVzaChpbmRleCk7XG4gIGNlbGxzW3JpZ2h0LmluZGV4XS5oYWxmZWRnZXMucHVzaChpbmRleCk7XG4gIHJldHVybiBlZGdlO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCb3JkZXJFZGdlKGxlZnQsIHYwLCB2MSkge1xuICB2YXIgZWRnZSA9IFt2MCwgdjFdO1xuICBlZGdlLmxlZnQgPSBsZWZ0O1xuICByZXR1cm4gZWRnZTtcbn1cblxuZnVuY3Rpb24gc2V0RWRnZUVuZChlZGdlLCBsZWZ0LCByaWdodCwgdmVydGV4KSB7XG4gIGlmICghZWRnZVswXSAmJiAhZWRnZVsxXSkge1xuICAgIGVkZ2VbMF0gPSB2ZXJ0ZXg7XG4gICAgZWRnZS5sZWZ0ID0gbGVmdDtcbiAgICBlZGdlLnJpZ2h0ID0gcmlnaHQ7XG4gIH0gZWxzZSBpZiAoZWRnZS5sZWZ0ID09PSByaWdodCkge1xuICAgIGVkZ2VbMV0gPSB2ZXJ0ZXg7XG4gIH0gZWxzZSB7XG4gICAgZWRnZVswXSA9IHZlcnRleDtcbiAgfVxufVxuXG4vLyBMaWFuZ+KAk0JhcnNreSBsaW5lIGNsaXBwaW5nLlxuZnVuY3Rpb24gY2xpcEVkZ2UoZWRnZSwgeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIGEgPSBlZGdlWzBdLFxuICAgICAgYiA9IGVkZ2VbMV0sXG4gICAgICBheCA9IGFbMF0sXG4gICAgICBheSA9IGFbMV0sXG4gICAgICBieCA9IGJbMF0sXG4gICAgICBieSA9IGJbMV0sXG4gICAgICB0MCA9IDAsXG4gICAgICB0MSA9IDEsXG4gICAgICBkeCA9IGJ4IC0gYXgsXG4gICAgICBkeSA9IGJ5IC0gYXksXG4gICAgICByO1xuXG4gIHIgPSB4MCAtIGF4O1xuICBpZiAoIWR4ICYmIHIgPiAwKSByZXR1cm47XG4gIHIgLz0gZHg7XG4gIGlmIChkeCA8IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9IGVsc2UgaWYgKGR4ID4gMCkge1xuICAgIGlmIChyID4gdDEpIHJldHVybjtcbiAgICBpZiAociA+IHQwKSB0MCA9IHI7XG4gIH1cblxuICByID0geDEgLSBheDtcbiAgaWYgKCFkeCAmJiByIDwgMCkgcmV0dXJuO1xuICByIC89IGR4O1xuICBpZiAoZHggPCAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfSBlbHNlIGlmIChkeCA+IDApIHtcbiAgICBpZiAociA8IHQwKSByZXR1cm47XG4gICAgaWYgKHIgPCB0MSkgdDEgPSByO1xuICB9XG5cbiAgciA9IHkwIC0gYXk7XG4gIGlmICghZHkgJiYgciA+IDApIHJldHVybjtcbiAgciAvPSBkeTtcbiAgaWYgKGR5IDwgMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH0gZWxzZSBpZiAoZHkgPiAwKSB7XG4gICAgaWYgKHIgPiB0MSkgcmV0dXJuO1xuICAgIGlmIChyID4gdDApIHQwID0gcjtcbiAgfVxuXG4gIHIgPSB5MSAtIGF5O1xuICBpZiAoIWR5ICYmIHIgPCAwKSByZXR1cm47XG4gIHIgLz0gZHk7XG4gIGlmIChkeSA8IDApIHtcbiAgICBpZiAociA+IHQxKSByZXR1cm47XG4gICAgaWYgKHIgPiB0MCkgdDAgPSByO1xuICB9IGVsc2UgaWYgKGR5ID4gMCkge1xuICAgIGlmIChyIDwgdDApIHJldHVybjtcbiAgICBpZiAociA8IHQxKSB0MSA9IHI7XG4gIH1cblxuICBpZiAoISh0MCA+IDApICYmICEodDEgPCAxKSkgcmV0dXJuIHRydWU7IC8vIFRPRE8gQmV0dGVyIGNoZWNrP1xuXG4gIGlmICh0MCA+IDApIGVkZ2VbMF0gPSBbYXggKyB0MCAqIGR4LCBheSArIHQwICogZHldO1xuICBpZiAodDEgPCAxKSBlZGdlWzFdID0gW2F4ICsgdDEgKiBkeCwgYXkgKyB0MSAqIGR5XTtcbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIGNvbm5lY3RFZGdlKGVkZ2UsIHgwLCB5MCwgeDEsIHkxKSB7XG4gIHZhciB2MSA9IGVkZ2VbMV07XG4gIGlmICh2MSkgcmV0dXJuIHRydWU7XG5cbiAgdmFyIHYwID0gZWRnZVswXSxcbiAgICAgIGxlZnQgPSBlZGdlLmxlZnQsXG4gICAgICByaWdodCA9IGVkZ2UucmlnaHQsXG4gICAgICBseCA9IGxlZnRbMF0sXG4gICAgICBseSA9IGxlZnRbMV0sXG4gICAgICByeCA9IHJpZ2h0WzBdLFxuICAgICAgcnkgPSByaWdodFsxXSxcbiAgICAgIGZ4ID0gKGx4ICsgcngpIC8gMixcbiAgICAgIGZ5ID0gKGx5ICsgcnkpIC8gMixcbiAgICAgIGZtLFxuICAgICAgZmI7XG5cbiAgaWYgKHJ5ID09PSBseSkge1xuICAgIGlmIChmeCA8IHgwIHx8IGZ4ID49IHgxKSByZXR1cm47XG4gICAgaWYgKGx4ID4gcngpIHtcbiAgICAgIGlmICghdjApIHYwID0gW2Z4LCB5MF07XG4gICAgICBlbHNlIGlmICh2MFsxXSA+PSB5MSkgcmV0dXJuO1xuICAgICAgdjEgPSBbZngsIHkxXTtcbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKCF2MCkgdjAgPSBbZngsIHkxXTtcbiAgICAgIGVsc2UgaWYgKHYwWzFdIDwgeTApIHJldHVybjtcbiAgICAgIHYxID0gW2Z4LCB5MF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIGZtID0gKGx4IC0gcngpIC8gKHJ5IC0gbHkpO1xuICAgIGZiID0gZnkgLSBmbSAqIGZ4O1xuICAgIGlmIChmbSA8IC0xIHx8IGZtID4gMSkge1xuICAgICAgaWYgKGx4ID4gcngpIHtcbiAgICAgICAgaWYgKCF2MCkgdjAgPSBbKHkwIC0gZmIpIC8gZm0sIHkwXTtcbiAgICAgICAgZWxzZSBpZiAodjBbMV0gPj0geTEpIHJldHVybjtcbiAgICAgICAgdjEgPSBbKHkxIC0gZmIpIC8gZm0sIHkxXTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmICghdjApIHYwID0gWyh5MSAtIGZiKSAvIGZtLCB5MV07XG4gICAgICAgIGVsc2UgaWYgKHYwWzFdIDwgeTApIHJldHVybjtcbiAgICAgICAgdjEgPSBbKHkwIC0gZmIpIC8gZm0sIHkwXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKGx5IDwgcnkpIHtcbiAgICAgICAgaWYgKCF2MCkgdjAgPSBbeDAsIGZtICogeDAgKyBmYl07XG4gICAgICAgIGVsc2UgaWYgKHYwWzBdID49IHgxKSByZXR1cm47XG4gICAgICAgIHYxID0gW3gxLCBmbSAqIHgxICsgZmJdO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgaWYgKCF2MCkgdjAgPSBbeDEsIGZtICogeDEgKyBmYl07XG4gICAgICAgIGVsc2UgaWYgKHYwWzBdIDwgeDApIHJldHVybjtcbiAgICAgICAgdjEgPSBbeDAsIGZtICogeDAgKyBmYl07XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZWRnZVswXSA9IHYwO1xuICBlZGdlWzFdID0gdjE7XG4gIHJldHVybiB0cnVlO1xufVxuXG5mdW5jdGlvbiBjbGlwRWRnZXMoeDAsIHkwLCB4MSwgeTEpIHtcbiAgdmFyIGkgPSBlZGdlcy5sZW5ndGgsXG4gICAgICBlZGdlO1xuXG4gIHdoaWxlIChpLS0pIHtcbiAgICBpZiAoIWNvbm5lY3RFZGdlKGVkZ2UgPSBlZGdlc1tpXSwgeDAsIHkwLCB4MSwgeTEpXG4gICAgICAgIHx8ICFjbGlwRWRnZShlZGdlLCB4MCwgeTAsIHgxLCB5MSlcbiAgICAgICAgfHwgIShNYXRoLmFicyhlZGdlWzBdWzBdIC0gZWRnZVsxXVswXSkgPiBlcHNpbG9uJDNcbiAgICAgICAgICAgIHx8IE1hdGguYWJzKGVkZ2VbMF1bMV0gLSBlZGdlWzFdWzFdKSA+IGVwc2lsb24kMykpIHtcbiAgICAgIGRlbGV0ZSBlZGdlc1tpXTtcbiAgICB9XG4gIH1cbn1cblxuZnVuY3Rpb24gY3JlYXRlQ2VsbChzaXRlKSB7XG4gIHJldHVybiBjZWxsc1tzaXRlLmluZGV4XSA9IHtcbiAgICBzaXRlOiBzaXRlLFxuICAgIGhhbGZlZGdlczogW11cbiAgfTtcbn1cblxuZnVuY3Rpb24gY2VsbEhhbGZlZGdlQW5nbGUoY2VsbCwgZWRnZSkge1xuICB2YXIgc2l0ZSA9IGNlbGwuc2l0ZSxcbiAgICAgIHZhID0gZWRnZS5sZWZ0LFxuICAgICAgdmIgPSBlZGdlLnJpZ2h0O1xuICBpZiAoc2l0ZSA9PT0gdmIpIHZiID0gdmEsIHZhID0gc2l0ZTtcbiAgaWYgKHZiKSByZXR1cm4gTWF0aC5hdGFuMih2YlsxXSAtIHZhWzFdLCB2YlswXSAtIHZhWzBdKTtcbiAgaWYgKHNpdGUgPT09IHZhKSB2YSA9IGVkZ2VbMV0sIHZiID0gZWRnZVswXTtcbiAgZWxzZSB2YSA9IGVkZ2VbMF0sIHZiID0gZWRnZVsxXTtcbiAgcmV0dXJuIE1hdGguYXRhbjIodmFbMF0gLSB2YlswXSwgdmJbMV0gLSB2YVsxXSk7XG59XG5cbmZ1bmN0aW9uIGNlbGxIYWxmZWRnZVN0YXJ0KGNlbGwsIGVkZ2UpIHtcbiAgcmV0dXJuIGVkZ2VbKyhlZGdlLmxlZnQgIT09IGNlbGwuc2l0ZSldO1xufVxuXG5mdW5jdGlvbiBjZWxsSGFsZmVkZ2VFbmQoY2VsbCwgZWRnZSkge1xuICByZXR1cm4gZWRnZVsrKGVkZ2UubGVmdCA9PT0gY2VsbC5zaXRlKV07XG59XG5cbmZ1bmN0aW9uIHNvcnRDZWxsSGFsZmVkZ2VzKCkge1xuICBmb3IgKHZhciBpID0gMCwgbiA9IGNlbGxzLmxlbmd0aCwgY2VsbCwgaGFsZmVkZ2VzLCBqLCBtOyBpIDwgbjsgKytpKSB7XG4gICAgaWYgKChjZWxsID0gY2VsbHNbaV0pICYmIChtID0gKGhhbGZlZGdlcyA9IGNlbGwuaGFsZmVkZ2VzKS5sZW5ndGgpKSB7XG4gICAgICB2YXIgaW5kZXggPSBuZXcgQXJyYXkobSksXG4gICAgICAgICAgYXJyYXkgPSBuZXcgQXJyYXkobSk7XG4gICAgICBmb3IgKGogPSAwOyBqIDwgbTsgKytqKSBpbmRleFtqXSA9IGosIGFycmF5W2pdID0gY2VsbEhhbGZlZGdlQW5nbGUoY2VsbCwgZWRnZXNbaGFsZmVkZ2VzW2pdXSk7XG4gICAgICBpbmRleC5zb3J0KGZ1bmN0aW9uKGksIGopIHsgcmV0dXJuIGFycmF5W2pdIC0gYXJyYXlbaV07IH0pO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikgYXJyYXlbal0gPSBoYWxmZWRnZXNbaW5kZXhbal1dO1xuICAgICAgZm9yIChqID0gMDsgaiA8IG07ICsraikgaGFsZmVkZ2VzW2pdID0gYXJyYXlbal07XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIGNsaXBDZWxscyh4MCwgeTAsIHgxLCB5MSkge1xuICB2YXIgbkNlbGxzID0gY2VsbHMubGVuZ3RoLFxuICAgICAgaUNlbGwsXG4gICAgICBjZWxsLFxuICAgICAgc2l0ZSxcbiAgICAgIGlIYWxmZWRnZSxcbiAgICAgIGhhbGZlZGdlcyxcbiAgICAgIG5IYWxmZWRnZXMsXG4gICAgICBzdGFydCxcbiAgICAgIHN0YXJ0WCxcbiAgICAgIHN0YXJ0WSxcbiAgICAgIGVuZCxcbiAgICAgIGVuZFgsXG4gICAgICBlbmRZLFxuICAgICAgY292ZXIgPSB0cnVlO1xuXG4gIGZvciAoaUNlbGwgPSAwOyBpQ2VsbCA8IG5DZWxsczsgKytpQ2VsbCkge1xuICAgIGlmIChjZWxsID0gY2VsbHNbaUNlbGxdKSB7XG4gICAgICBzaXRlID0gY2VsbC5zaXRlO1xuICAgICAgaGFsZmVkZ2VzID0gY2VsbC5oYWxmZWRnZXM7XG4gICAgICBpSGFsZmVkZ2UgPSBoYWxmZWRnZXMubGVuZ3RoO1xuXG4gICAgICAvLyBSZW1vdmUgYW55IGRhbmdsaW5nIGNsaXBwZWQgZWRnZXMuXG4gICAgICB3aGlsZSAoaUhhbGZlZGdlLS0pIHtcbiAgICAgICAgaWYgKCFlZGdlc1toYWxmZWRnZXNbaUhhbGZlZGdlXV0pIHtcbiAgICAgICAgICBoYWxmZWRnZXMuc3BsaWNlKGlIYWxmZWRnZSwgMSk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSW5zZXJ0IGFueSBib3JkZXIgZWRnZXMgYXMgbmVjZXNzYXJ5LlxuICAgICAgaUhhbGZlZGdlID0gMCwgbkhhbGZlZGdlcyA9IGhhbGZlZGdlcy5sZW5ndGg7XG4gICAgICB3aGlsZSAoaUhhbGZlZGdlIDwgbkhhbGZlZGdlcykge1xuICAgICAgICBlbmQgPSBjZWxsSGFsZmVkZ2VFbmQoY2VsbCwgZWRnZXNbaGFsZmVkZ2VzW2lIYWxmZWRnZV1dKSwgZW5kWCA9IGVuZFswXSwgZW5kWSA9IGVuZFsxXTtcbiAgICAgICAgc3RhcnQgPSBjZWxsSGFsZmVkZ2VTdGFydChjZWxsLCBlZGdlc1toYWxmZWRnZXNbKytpSGFsZmVkZ2UgJSBuSGFsZmVkZ2VzXV0pLCBzdGFydFggPSBzdGFydFswXSwgc3RhcnRZID0gc3RhcnRbMV07XG4gICAgICAgIGlmIChNYXRoLmFicyhlbmRYIC0gc3RhcnRYKSA+IGVwc2lsb24kMyB8fCBNYXRoLmFicyhlbmRZIC0gc3RhcnRZKSA+IGVwc2lsb24kMykge1xuICAgICAgICAgIGhhbGZlZGdlcy5zcGxpY2UoaUhhbGZlZGdlLCAwLCBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSwgZW5kLFxuICAgICAgICAgICAgICBNYXRoLmFicyhlbmRYIC0geDApIDwgZXBzaWxvbiQzICYmIHkxIC0gZW5kWSA+IGVwc2lsb24kMyA/IFt4MCwgTWF0aC5hYnMoc3RhcnRYIC0geDApIDwgZXBzaWxvbiQzID8gc3RhcnRZIDogeTFdXG4gICAgICAgICAgICAgIDogTWF0aC5hYnMoZW5kWSAtIHkxKSA8IGVwc2lsb24kMyAmJiB4MSAtIGVuZFggPiBlcHNpbG9uJDMgPyBbTWF0aC5hYnMoc3RhcnRZIC0geTEpIDwgZXBzaWxvbiQzID8gc3RhcnRYIDogeDEsIHkxXVxuICAgICAgICAgICAgICA6IE1hdGguYWJzKGVuZFggLSB4MSkgPCBlcHNpbG9uJDMgJiYgZW5kWSAtIHkwID4gZXBzaWxvbiQzID8gW3gxLCBNYXRoLmFicyhzdGFydFggLSB4MSkgPCBlcHNpbG9uJDMgPyBzdGFydFkgOiB5MF1cbiAgICAgICAgICAgICAgOiBNYXRoLmFicyhlbmRZIC0geTApIDwgZXBzaWxvbiQzICYmIGVuZFggLSB4MCA+IGVwc2lsb24kMyA/IFtNYXRoLmFicyhzdGFydFkgLSB5MCkgPCBlcHNpbG9uJDMgPyBzdGFydFggOiB4MCwgeTBdXG4gICAgICAgICAgICAgIDogbnVsbCkpIC0gMSk7XG4gICAgICAgICAgKytuSGFsZmVkZ2VzO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChuSGFsZmVkZ2VzKSBjb3ZlciA9IGZhbHNlO1xuICAgIH1cbiAgfVxuXG4gIC8vIElmIHRoZXJlIHdlcmVu4oCZdCBhbnkgZWRnZXMsIGhhdmUgdGhlIGNsb3Nlc3Qgc2l0ZSBjb3ZlciB0aGUgZXh0ZW50LlxuICAvLyBJdCBkb2VzbuKAmXQgbWF0dGVyIHdoaWNoIGNvcm5lciBvZiB0aGUgZXh0ZW50IHdlIG1lYXN1cmUhXG4gIGlmIChjb3Zlcikge1xuICAgIHZhciBkeCwgZHksIGQyLCBkYyA9IEluZmluaXR5O1xuXG4gICAgZm9yIChpQ2VsbCA9IDAsIGNvdmVyID0gbnVsbDsgaUNlbGwgPCBuQ2VsbHM7ICsraUNlbGwpIHtcbiAgICAgIGlmIChjZWxsID0gY2VsbHNbaUNlbGxdKSB7XG4gICAgICAgIHNpdGUgPSBjZWxsLnNpdGU7XG4gICAgICAgIGR4ID0gc2l0ZVswXSAtIHgwO1xuICAgICAgICBkeSA9IHNpdGVbMV0gLSB5MDtcbiAgICAgICAgZDIgPSBkeCAqIGR4ICsgZHkgKiBkeTtcbiAgICAgICAgaWYgKGQyIDwgZGMpIGRjID0gZDIsIGNvdmVyID0gY2VsbDtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoY292ZXIpIHtcbiAgICAgIHZhciB2MDAgPSBbeDAsIHkwXSwgdjAxID0gW3gwLCB5MV0sIHYxMSA9IFt4MSwgeTFdLCB2MTAgPSBbeDEsIHkwXTtcbiAgICAgIGNvdmVyLmhhbGZlZGdlcy5wdXNoKFxuICAgICAgICBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSA9IGNvdmVyLnNpdGUsIHYwMCwgdjAxKSkgLSAxLFxuICAgICAgICBlZGdlcy5wdXNoKGNyZWF0ZUJvcmRlckVkZ2Uoc2l0ZSwgdjAxLCB2MTEpKSAtIDEsXG4gICAgICAgIGVkZ2VzLnB1c2goY3JlYXRlQm9yZGVyRWRnZShzaXRlLCB2MTEsIHYxMCkpIC0gMSxcbiAgICAgICAgZWRnZXMucHVzaChjcmVhdGVCb3JkZXJFZGdlKHNpdGUsIHYxMCwgdjAwKSkgLSAxXG4gICAgICApO1xuICAgIH1cbiAgfVxuXG4gIC8vIExhc3RseSBkZWxldGUgYW55IGNlbGxzIHdpdGggbm8gZWRnZXM7IHRoZXNlIHdlcmUgZW50aXJlbHkgY2xpcHBlZC5cbiAgZm9yIChpQ2VsbCA9IDA7IGlDZWxsIDwgbkNlbGxzOyArK2lDZWxsKSB7XG4gICAgaWYgKGNlbGwgPSBjZWxsc1tpQ2VsbF0pIHtcbiAgICAgIGlmICghY2VsbC5oYWxmZWRnZXMubGVuZ3RoKSB7XG4gICAgICAgIGRlbGV0ZSBjZWxsc1tpQ2VsbF07XG4gICAgICB9XG4gICAgfVxuICB9XG59XG5cbnZhciBjaXJjbGVQb29sID0gW107XG5cbnZhciBmaXJzdENpcmNsZTtcblxuZnVuY3Rpb24gQ2lyY2xlKCkge1xuICBSZWRCbGFja05vZGUodGhpcyk7XG4gIHRoaXMueCA9XG4gIHRoaXMueSA9XG4gIHRoaXMuYXJjID1cbiAgdGhpcy5zaXRlID1cbiAgdGhpcy5jeSA9IG51bGw7XG59XG5cbmZ1bmN0aW9uIGF0dGFjaENpcmNsZShhcmMpIHtcbiAgdmFyIGxBcmMgPSBhcmMuUCxcbiAgICAgIHJBcmMgPSBhcmMuTjtcblxuICBpZiAoIWxBcmMgfHwgIXJBcmMpIHJldHVybjtcblxuICB2YXIgbFNpdGUgPSBsQXJjLnNpdGUsXG4gICAgICBjU2l0ZSA9IGFyYy5zaXRlLFxuICAgICAgclNpdGUgPSByQXJjLnNpdGU7XG5cbiAgaWYgKGxTaXRlID09PSByU2l0ZSkgcmV0dXJuO1xuXG4gIHZhciBieCA9IGNTaXRlWzBdLFxuICAgICAgYnkgPSBjU2l0ZVsxXSxcbiAgICAgIGF4ID0gbFNpdGVbMF0gLSBieCxcbiAgICAgIGF5ID0gbFNpdGVbMV0gLSBieSxcbiAgICAgIGN4ID0gclNpdGVbMF0gLSBieCxcbiAgICAgIGN5ID0gclNpdGVbMV0gLSBieTtcblxuICB2YXIgZCA9IDIgKiAoYXggKiBjeSAtIGF5ICogY3gpO1xuICBpZiAoZCA+PSAtZXBzaWxvbjIkMikgcmV0dXJuO1xuXG4gIHZhciBoYSA9IGF4ICogYXggKyBheSAqIGF5LFxuICAgICAgaGMgPSBjeCAqIGN4ICsgY3kgKiBjeSxcbiAgICAgIHggPSAoY3kgKiBoYSAtIGF5ICogaGMpIC8gZCxcbiAgICAgIHkgPSAoYXggKiBoYyAtIGN4ICogaGEpIC8gZDtcblxuICB2YXIgY2lyY2xlID0gY2lyY2xlUG9vbC5wb3AoKSB8fCBuZXcgQ2lyY2xlO1xuICBjaXJjbGUuYXJjID0gYXJjO1xuICBjaXJjbGUuc2l0ZSA9IGNTaXRlO1xuICBjaXJjbGUueCA9IHggKyBieDtcbiAgY2lyY2xlLnkgPSAoY2lyY2xlLmN5ID0geSArIGJ5KSArIE1hdGguc3FydCh4ICogeCArIHkgKiB5KTsgLy8geSBib3R0b21cblxuICBhcmMuY2lyY2xlID0gY2lyY2xlO1xuXG4gIHZhciBiZWZvcmUgPSBudWxsLFxuICAgICAgbm9kZSA9IGNpcmNsZXMuXztcblxuICB3aGlsZSAobm9kZSkge1xuICAgIGlmIChjaXJjbGUueSA8IG5vZGUueSB8fCAoY2lyY2xlLnkgPT09IG5vZGUueSAmJiBjaXJjbGUueCA8PSBub2RlLngpKSB7XG4gICAgICBpZiAobm9kZS5MKSBub2RlID0gbm9kZS5MO1xuICAgICAgZWxzZSB7IGJlZm9yZSA9IG5vZGUuUDsgYnJlYWs7IH1cbiAgICB9IGVsc2Uge1xuICAgICAgaWYgKG5vZGUuUikgbm9kZSA9IG5vZGUuUjtcbiAgICAgIGVsc2UgeyBiZWZvcmUgPSBub2RlOyBicmVhazsgfVxuICAgIH1cbiAgfVxuXG4gIGNpcmNsZXMuaW5zZXJ0KGJlZm9yZSwgY2lyY2xlKTtcbiAgaWYgKCFiZWZvcmUpIGZpcnN0Q2lyY2xlID0gY2lyY2xlO1xufVxuXG5mdW5jdGlvbiBkZXRhY2hDaXJjbGUoYXJjKSB7XG4gIHZhciBjaXJjbGUgPSBhcmMuY2lyY2xlO1xuICBpZiAoY2lyY2xlKSB7XG4gICAgaWYgKCFjaXJjbGUuUCkgZmlyc3RDaXJjbGUgPSBjaXJjbGUuTjtcbiAgICBjaXJjbGVzLnJlbW92ZShjaXJjbGUpO1xuICAgIGNpcmNsZVBvb2wucHVzaChjaXJjbGUpO1xuICAgIFJlZEJsYWNrTm9kZShjaXJjbGUpO1xuICAgIGFyYy5jaXJjbGUgPSBudWxsO1xuICB9XG59XG5cbnZhciBiZWFjaFBvb2wgPSBbXTtcblxuZnVuY3Rpb24gQmVhY2goKSB7XG4gIFJlZEJsYWNrTm9kZSh0aGlzKTtcbiAgdGhpcy5lZGdlID1cbiAgdGhpcy5zaXRlID1cbiAgdGhpcy5jaXJjbGUgPSBudWxsO1xufVxuXG5mdW5jdGlvbiBjcmVhdGVCZWFjaChzaXRlKSB7XG4gIHZhciBiZWFjaCA9IGJlYWNoUG9vbC5wb3AoKSB8fCBuZXcgQmVhY2g7XG4gIGJlYWNoLnNpdGUgPSBzaXRlO1xuICByZXR1cm4gYmVhY2g7XG59XG5cbmZ1bmN0aW9uIGRldGFjaEJlYWNoKGJlYWNoKSB7XG4gIGRldGFjaENpcmNsZShiZWFjaCk7XG4gIGJlYWNoZXMucmVtb3ZlKGJlYWNoKTtcbiAgYmVhY2hQb29sLnB1c2goYmVhY2gpO1xuICBSZWRCbGFja05vZGUoYmVhY2gpO1xufVxuXG5mdW5jdGlvbiByZW1vdmVCZWFjaChiZWFjaCkge1xuICB2YXIgY2lyY2xlID0gYmVhY2guY2lyY2xlLFxuICAgICAgeCA9IGNpcmNsZS54LFxuICAgICAgeSA9IGNpcmNsZS5jeSxcbiAgICAgIHZlcnRleCA9IFt4LCB5XSxcbiAgICAgIHByZXZpb3VzID0gYmVhY2guUCxcbiAgICAgIG5leHQgPSBiZWFjaC5OLFxuICAgICAgZGlzYXBwZWFyaW5nID0gW2JlYWNoXTtcblxuICBkZXRhY2hCZWFjaChiZWFjaCk7XG5cbiAgdmFyIGxBcmMgPSBwcmV2aW91cztcbiAgd2hpbGUgKGxBcmMuY2lyY2xlXG4gICAgICAmJiBNYXRoLmFicyh4IC0gbEFyYy5jaXJjbGUueCkgPCBlcHNpbG9uJDNcbiAgICAgICYmIE1hdGguYWJzKHkgLSBsQXJjLmNpcmNsZS5jeSkgPCBlcHNpbG9uJDMpIHtcbiAgICBwcmV2aW91cyA9IGxBcmMuUDtcbiAgICBkaXNhcHBlYXJpbmcudW5zaGlmdChsQXJjKTtcbiAgICBkZXRhY2hCZWFjaChsQXJjKTtcbiAgICBsQXJjID0gcHJldmlvdXM7XG4gIH1cblxuICBkaXNhcHBlYXJpbmcudW5zaGlmdChsQXJjKTtcbiAgZGV0YWNoQ2lyY2xlKGxBcmMpO1xuXG4gIHZhciByQXJjID0gbmV4dDtcbiAgd2hpbGUgKHJBcmMuY2lyY2xlXG4gICAgICAmJiBNYXRoLmFicyh4IC0gckFyYy5jaXJjbGUueCkgPCBlcHNpbG9uJDNcbiAgICAgICYmIE1hdGguYWJzKHkgLSByQXJjLmNpcmNsZS5jeSkgPCBlcHNpbG9uJDMpIHtcbiAgICBuZXh0ID0gckFyYy5OO1xuICAgIGRpc2FwcGVhcmluZy5wdXNoKHJBcmMpO1xuICAgIGRldGFjaEJlYWNoKHJBcmMpO1xuICAgIHJBcmMgPSBuZXh0O1xuICB9XG5cbiAgZGlzYXBwZWFyaW5nLnB1c2gockFyYyk7XG4gIGRldGFjaENpcmNsZShyQXJjKTtcblxuICB2YXIgbkFyY3MgPSBkaXNhcHBlYXJpbmcubGVuZ3RoLFxuICAgICAgaUFyYztcbiAgZm9yIChpQXJjID0gMTsgaUFyYyA8IG5BcmNzOyArK2lBcmMpIHtcbiAgICByQXJjID0gZGlzYXBwZWFyaW5nW2lBcmNdO1xuICAgIGxBcmMgPSBkaXNhcHBlYXJpbmdbaUFyYyAtIDFdO1xuICAgIHNldEVkZ2VFbmQockFyYy5lZGdlLCBsQXJjLnNpdGUsIHJBcmMuc2l0ZSwgdmVydGV4KTtcbiAgfVxuXG4gIGxBcmMgPSBkaXNhcHBlYXJpbmdbMF07XG4gIHJBcmMgPSBkaXNhcHBlYXJpbmdbbkFyY3MgLSAxXTtcbiAgckFyYy5lZGdlID0gY3JlYXRlRWRnZShsQXJjLnNpdGUsIHJBcmMuc2l0ZSwgbnVsbCwgdmVydGV4KTtcblxuICBhdHRhY2hDaXJjbGUobEFyYyk7XG4gIGF0dGFjaENpcmNsZShyQXJjKTtcbn1cblxuZnVuY3Rpb24gYWRkQmVhY2goc2l0ZSkge1xuICB2YXIgeCA9IHNpdGVbMF0sXG4gICAgICBkaXJlY3RyaXggPSBzaXRlWzFdLFxuICAgICAgbEFyYyxcbiAgICAgIHJBcmMsXG4gICAgICBkeGwsXG4gICAgICBkeHIsXG4gICAgICBub2RlID0gYmVhY2hlcy5fO1xuXG4gIHdoaWxlIChub2RlKSB7XG4gICAgZHhsID0gbGVmdEJyZWFrUG9pbnQobm9kZSwgZGlyZWN0cml4KSAtIHg7XG4gICAgaWYgKGR4bCA+IGVwc2lsb24kMykgbm9kZSA9IG5vZGUuTDsgZWxzZSB7XG4gICAgICBkeHIgPSB4IC0gcmlnaHRCcmVha1BvaW50KG5vZGUsIGRpcmVjdHJpeCk7XG4gICAgICBpZiAoZHhyID4gZXBzaWxvbiQzKSB7XG4gICAgICAgIGlmICghbm9kZS5SKSB7XG4gICAgICAgICAgbEFyYyA9IG5vZGU7XG4gICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgICAgbm9kZSA9IG5vZGUuUjtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChkeGwgPiAtZXBzaWxvbiQzKSB7XG4gICAgICAgICAgbEFyYyA9IG5vZGUuUDtcbiAgICAgICAgICByQXJjID0gbm9kZTtcbiAgICAgICAgfSBlbHNlIGlmIChkeHIgPiAtZXBzaWxvbiQzKSB7XG4gICAgICAgICAgbEFyYyA9IG5vZGU7XG4gICAgICAgICAgckFyYyA9IG5vZGUuTjtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBsQXJjID0gckFyYyA9IG5vZGU7XG4gICAgICAgIH1cbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgY3JlYXRlQ2VsbChzaXRlKTtcbiAgdmFyIG5ld0FyYyA9IGNyZWF0ZUJlYWNoKHNpdGUpO1xuICBiZWFjaGVzLmluc2VydChsQXJjLCBuZXdBcmMpO1xuXG4gIGlmICghbEFyYyAmJiAhckFyYykgcmV0dXJuO1xuXG4gIGlmIChsQXJjID09PSByQXJjKSB7XG4gICAgZGV0YWNoQ2lyY2xlKGxBcmMpO1xuICAgIHJBcmMgPSBjcmVhdGVCZWFjaChsQXJjLnNpdGUpO1xuICAgIGJlYWNoZXMuaW5zZXJ0KG5ld0FyYywgckFyYyk7XG4gICAgbmV3QXJjLmVkZ2UgPSByQXJjLmVkZ2UgPSBjcmVhdGVFZGdlKGxBcmMuc2l0ZSwgbmV3QXJjLnNpdGUpO1xuICAgIGF0dGFjaENpcmNsZShsQXJjKTtcbiAgICBhdHRhY2hDaXJjbGUockFyYyk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgaWYgKCFyQXJjKSB7IC8vICYmIGxBcmNcbiAgICBuZXdBcmMuZWRnZSA9IGNyZWF0ZUVkZ2UobEFyYy5zaXRlLCBuZXdBcmMuc2l0ZSk7XG4gICAgcmV0dXJuO1xuICB9XG5cbiAgLy8gZWxzZSBsQXJjICE9PSByQXJjXG4gIGRldGFjaENpcmNsZShsQXJjKTtcbiAgZGV0YWNoQ2lyY2xlKHJBcmMpO1xuXG4gIHZhciBsU2l0ZSA9IGxBcmMuc2l0ZSxcbiAgICAgIGF4ID0gbFNpdGVbMF0sXG4gICAgICBheSA9IGxTaXRlWzFdLFxuICAgICAgYnggPSBzaXRlWzBdIC0gYXgsXG4gICAgICBieSA9IHNpdGVbMV0gLSBheSxcbiAgICAgIHJTaXRlID0gckFyYy5zaXRlLFxuICAgICAgY3ggPSByU2l0ZVswXSAtIGF4LFxuICAgICAgY3kgPSByU2l0ZVsxXSAtIGF5LFxuICAgICAgZCA9IDIgKiAoYnggKiBjeSAtIGJ5ICogY3gpLFxuICAgICAgaGIgPSBieCAqIGJ4ICsgYnkgKiBieSxcbiAgICAgIGhjID0gY3ggKiBjeCArIGN5ICogY3ksXG4gICAgICB2ZXJ0ZXggPSBbKGN5ICogaGIgLSBieSAqIGhjKSAvIGQgKyBheCwgKGJ4ICogaGMgLSBjeCAqIGhiKSAvIGQgKyBheV07XG5cbiAgc2V0RWRnZUVuZChyQXJjLmVkZ2UsIGxTaXRlLCByU2l0ZSwgdmVydGV4KTtcbiAgbmV3QXJjLmVkZ2UgPSBjcmVhdGVFZGdlKGxTaXRlLCBzaXRlLCBudWxsLCB2ZXJ0ZXgpO1xuICByQXJjLmVkZ2UgPSBjcmVhdGVFZGdlKHNpdGUsIHJTaXRlLCBudWxsLCB2ZXJ0ZXgpO1xuICBhdHRhY2hDaXJjbGUobEFyYyk7XG4gIGF0dGFjaENpcmNsZShyQXJjKTtcbn1cblxuZnVuY3Rpb24gbGVmdEJyZWFrUG9pbnQoYXJjLCBkaXJlY3RyaXgpIHtcbiAgdmFyIHNpdGUgPSBhcmMuc2l0ZSxcbiAgICAgIHJmb2N4ID0gc2l0ZVswXSxcbiAgICAgIHJmb2N5ID0gc2l0ZVsxXSxcbiAgICAgIHBieTIgPSByZm9jeSAtIGRpcmVjdHJpeDtcblxuICBpZiAoIXBieTIpIHJldHVybiByZm9jeDtcblxuICB2YXIgbEFyYyA9IGFyYy5QO1xuICBpZiAoIWxBcmMpIHJldHVybiAtSW5maW5pdHk7XG5cbiAgc2l0ZSA9IGxBcmMuc2l0ZTtcbiAgdmFyIGxmb2N4ID0gc2l0ZVswXSxcbiAgICAgIGxmb2N5ID0gc2l0ZVsxXSxcbiAgICAgIHBsYnkyID0gbGZvY3kgLSBkaXJlY3RyaXg7XG5cbiAgaWYgKCFwbGJ5MikgcmV0dXJuIGxmb2N4O1xuXG4gIHZhciBobCA9IGxmb2N4IC0gcmZvY3gsXG4gICAgICBhYnkyID0gMSAvIHBieTIgLSAxIC8gcGxieTIsXG4gICAgICBiID0gaGwgLyBwbGJ5MjtcblxuICBpZiAoYWJ5MikgcmV0dXJuICgtYiArIE1hdGguc3FydChiICogYiAtIDIgKiBhYnkyICogKGhsICogaGwgLyAoLTIgKiBwbGJ5MikgLSBsZm9jeSArIHBsYnkyIC8gMiArIHJmb2N5IC0gcGJ5MiAvIDIpKSkgLyBhYnkyICsgcmZvY3g7XG5cbiAgcmV0dXJuIChyZm9jeCArIGxmb2N4KSAvIDI7XG59XG5cbmZ1bmN0aW9uIHJpZ2h0QnJlYWtQb2ludChhcmMsIGRpcmVjdHJpeCkge1xuICB2YXIgckFyYyA9IGFyYy5OO1xuICBpZiAockFyYykgcmV0dXJuIGxlZnRCcmVha1BvaW50KHJBcmMsIGRpcmVjdHJpeCk7XG4gIHZhciBzaXRlID0gYXJjLnNpdGU7XG4gIHJldHVybiBzaXRlWzFdID09PSBkaXJlY3RyaXggPyBzaXRlWzBdIDogSW5maW5pdHk7XG59XG5cbnZhciBlcHNpbG9uJDMgPSAxZS02O1xudmFyIGVwc2lsb24yJDIgPSAxZS0xMjtcbnZhciBiZWFjaGVzO1xudmFyIGNlbGxzO1xudmFyIGNpcmNsZXM7XG52YXIgZWRnZXM7XG5cbmZ1bmN0aW9uIHRyaWFuZ2xlQXJlYShhLCBiLCBjKSB7XG4gIHJldHVybiAoYVswXSAtIGNbMF0pICogKGJbMV0gLSBhWzFdKSAtIChhWzBdIC0gYlswXSkgKiAoY1sxXSAtIGFbMV0pO1xufVxuXG5mdW5jdGlvbiBsZXhpY29ncmFwaGljKGEsIGIpIHtcbiAgcmV0dXJuIGJbMV0gLSBhWzFdXG4gICAgICB8fCBiWzBdIC0gYVswXTtcbn1cblxuZnVuY3Rpb24gRGlhZ3JhbShzaXRlcywgZXh0ZW50KSB7XG4gIHZhciBzaXRlID0gc2l0ZXMuc29ydChsZXhpY29ncmFwaGljKS5wb3AoKSxcbiAgICAgIHgsXG4gICAgICB5LFxuICAgICAgY2lyY2xlO1xuXG4gIGVkZ2VzID0gW107XG4gIGNlbGxzID0gbmV3IEFycmF5KHNpdGVzLmxlbmd0aCk7XG4gIGJlYWNoZXMgPSBuZXcgUmVkQmxhY2tUcmVlO1xuICBjaXJjbGVzID0gbmV3IFJlZEJsYWNrVHJlZTtcblxuICB3aGlsZSAodHJ1ZSkge1xuICAgIGNpcmNsZSA9IGZpcnN0Q2lyY2xlO1xuICAgIGlmIChzaXRlICYmICghY2lyY2xlIHx8IHNpdGVbMV0gPCBjaXJjbGUueSB8fCAoc2l0ZVsxXSA9PT0gY2lyY2xlLnkgJiYgc2l0ZVswXSA8IGNpcmNsZS54KSkpIHtcbiAgICAgIGlmIChzaXRlWzBdICE9PSB4IHx8IHNpdGVbMV0gIT09IHkpIHtcbiAgICAgICAgYWRkQmVhY2goc2l0ZSk7XG4gICAgICAgIHggPSBzaXRlWzBdLCB5ID0gc2l0ZVsxXTtcbiAgICAgIH1cbiAgICAgIHNpdGUgPSBzaXRlcy5wb3AoKTtcbiAgICB9IGVsc2UgaWYgKGNpcmNsZSkge1xuICAgICAgcmVtb3ZlQmVhY2goY2lyY2xlLmFyYyk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHNvcnRDZWxsSGFsZmVkZ2VzKCk7XG5cbiAgaWYgKGV4dGVudCkge1xuICAgIHZhciB4MCA9ICtleHRlbnRbMF1bMF0sXG4gICAgICAgIHkwID0gK2V4dGVudFswXVsxXSxcbiAgICAgICAgeDEgPSArZXh0ZW50WzFdWzBdLFxuICAgICAgICB5MSA9ICtleHRlbnRbMV1bMV07XG4gICAgY2xpcEVkZ2VzKHgwLCB5MCwgeDEsIHkxKTtcbiAgICBjbGlwQ2VsbHMoeDAsIHkwLCB4MSwgeTEpO1xuICB9XG5cbiAgdGhpcy5lZGdlcyA9IGVkZ2VzO1xuICB0aGlzLmNlbGxzID0gY2VsbHM7XG5cbiAgYmVhY2hlcyA9XG4gIGNpcmNsZXMgPVxuICBlZGdlcyA9XG4gIGNlbGxzID0gbnVsbDtcbn1cblxuRGlhZ3JhbS5wcm90b3R5cGUgPSB7XG4gIGNvbnN0cnVjdG9yOiBEaWFncmFtLFxuXG4gIHBvbHlnb25zOiBmdW5jdGlvbigpIHtcbiAgICB2YXIgZWRnZXMgPSB0aGlzLmVkZ2VzO1xuXG4gICAgcmV0dXJuIHRoaXMuY2VsbHMubWFwKGZ1bmN0aW9uKGNlbGwpIHtcbiAgICAgIHZhciBwb2x5Z29uID0gY2VsbC5oYWxmZWRnZXMubWFwKGZ1bmN0aW9uKGkpIHsgcmV0dXJuIGNlbGxIYWxmZWRnZVN0YXJ0KGNlbGwsIGVkZ2VzW2ldKTsgfSk7XG4gICAgICBwb2x5Z29uLmRhdGEgPSBjZWxsLnNpdGUuZGF0YTtcbiAgICAgIHJldHVybiBwb2x5Z29uO1xuICAgIH0pO1xuICB9LFxuXG4gIHRyaWFuZ2xlczogZnVuY3Rpb24oKSB7XG4gICAgdmFyIHRyaWFuZ2xlcyA9IFtdLFxuICAgICAgICBlZGdlcyA9IHRoaXMuZWRnZXM7XG5cbiAgICB0aGlzLmNlbGxzLmZvckVhY2goZnVuY3Rpb24oY2VsbCwgaSkge1xuICAgICAgaWYgKCEobSA9IChoYWxmZWRnZXMgPSBjZWxsLmhhbGZlZGdlcykubGVuZ3RoKSkgcmV0dXJuO1xuICAgICAgdmFyIHNpdGUgPSBjZWxsLnNpdGUsXG4gICAgICAgICAgaGFsZmVkZ2VzLFxuICAgICAgICAgIGogPSAtMSxcbiAgICAgICAgICBtLFxuICAgICAgICAgIHMwLFxuICAgICAgICAgIGUxID0gZWRnZXNbaGFsZmVkZ2VzW20gLSAxXV0sXG4gICAgICAgICAgczEgPSBlMS5sZWZ0ID09PSBzaXRlID8gZTEucmlnaHQgOiBlMS5sZWZ0O1xuXG4gICAgICB3aGlsZSAoKytqIDwgbSkge1xuICAgICAgICBzMCA9IHMxO1xuICAgICAgICBlMSA9IGVkZ2VzW2hhbGZlZGdlc1tqXV07XG4gICAgICAgIHMxID0gZTEubGVmdCA9PT0gc2l0ZSA/IGUxLnJpZ2h0IDogZTEubGVmdDtcbiAgICAgICAgaWYgKHMwICYmIHMxICYmIGkgPCBzMC5pbmRleCAmJiBpIDwgczEuaW5kZXggJiYgdHJpYW5nbGVBcmVhKHNpdGUsIHMwLCBzMSkgPCAwKSB7XG4gICAgICAgICAgdHJpYW5nbGVzLnB1c2goW3NpdGUuZGF0YSwgczAuZGF0YSwgczEuZGF0YV0pO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSk7XG5cbiAgICByZXR1cm4gdHJpYW5nbGVzO1xuICB9LFxuXG4gIGxpbmtzOiBmdW5jdGlvbigpIHtcbiAgICByZXR1cm4gdGhpcy5lZGdlcy5maWx0ZXIoZnVuY3Rpb24oZWRnZSkge1xuICAgICAgcmV0dXJuIGVkZ2UucmlnaHQ7XG4gICAgfSkubWFwKGZ1bmN0aW9uKGVkZ2UpIHtcbiAgICAgIHJldHVybiB7XG4gICAgICAgIHNvdXJjZTogZWRnZS5sZWZ0LmRhdGEsXG4gICAgICAgIHRhcmdldDogZWRnZS5yaWdodC5kYXRhXG4gICAgICB9O1xuICAgIH0pO1xuICB9LFxuXG4gIGZpbmQ6IGZ1bmN0aW9uKHgsIHksIHJhZGl1cykge1xuICAgIHZhciB0aGF0ID0gdGhpcywgaTAsIGkxID0gdGhhdC5fZm91bmQgfHwgMCwgbiA9IHRoYXQuY2VsbHMubGVuZ3RoLCBjZWxsO1xuXG4gICAgLy8gVXNlIHRoZSBwcmV2aW91c2x5LWZvdW5kIGNlbGwsIG9yIHN0YXJ0IHdpdGggYW4gYXJiaXRyYXJ5IG9uZS5cbiAgICB3aGlsZSAoIShjZWxsID0gdGhhdC5jZWxsc1tpMV0pKSBpZiAoKytpMSA+PSBuKSByZXR1cm4gbnVsbDtcbiAgICB2YXIgZHggPSB4IC0gY2VsbC5zaXRlWzBdLCBkeSA9IHkgLSBjZWxsLnNpdGVbMV0sIGQyID0gZHggKiBkeCArIGR5ICogZHk7XG5cbiAgICAvLyBUcmF2ZXJzZSB0aGUgaGFsZi1lZGdlcyB0byBmaW5kIGEgY2xvc2VyIGNlbGwsIGlmIGFueS5cbiAgICBkbyB7XG4gICAgICBjZWxsID0gdGhhdC5jZWxsc1tpMCA9IGkxXSwgaTEgPSBudWxsO1xuICAgICAgY2VsbC5oYWxmZWRnZXMuZm9yRWFjaChmdW5jdGlvbihlKSB7XG4gICAgICAgIHZhciBlZGdlID0gdGhhdC5lZGdlc1tlXSwgdiA9IGVkZ2UubGVmdDtcbiAgICAgICAgaWYgKCh2ID09PSBjZWxsLnNpdGUgfHwgIXYpICYmICEodiA9IGVkZ2UucmlnaHQpKSByZXR1cm47XG4gICAgICAgIHZhciB2eCA9IHggLSB2WzBdLCB2eSA9IHkgLSB2WzFdLCB2MiA9IHZ4ICogdnggKyB2eSAqIHZ5O1xuICAgICAgICBpZiAodjIgPCBkMikgZDIgPSB2MiwgaTEgPSB2LmluZGV4O1xuICAgICAgfSk7XG4gICAgfSB3aGlsZSAoaTEgIT09IG51bGwpO1xuXG4gICAgdGhhdC5fZm91bmQgPSBpMDtcblxuICAgIHJldHVybiByYWRpdXMgPT0gbnVsbCB8fCBkMiA8PSByYWRpdXMgKiByYWRpdXMgPyBjZWxsLnNpdGUgOiBudWxsO1xuICB9XG59O1xuXG52YXIgdm9yb25vaSQxID0gZnVuY3Rpb24oKSB7XG4gIHZhciB4ID0geCQ0LFxuICAgICAgeSA9IHkkNCxcbiAgICAgIGV4dGVudCA9IG51bGw7XG5cbiAgZnVuY3Rpb24gdm9yb25vaShkYXRhKSB7XG4gICAgcmV0dXJuIG5ldyBEaWFncmFtKGRhdGEubWFwKGZ1bmN0aW9uKGQsIGkpIHtcbiAgICAgIHZhciBzID0gW01hdGgucm91bmQoeChkLCBpLCBkYXRhKSAvIGVwc2lsb24kMykgKiBlcHNpbG9uJDMsIE1hdGgucm91bmQoeShkLCBpLCBkYXRhKSAvIGVwc2lsb24kMykgKiBlcHNpbG9uJDNdO1xuICAgICAgcy5pbmRleCA9IGk7XG4gICAgICBzLmRhdGEgPSBkO1xuICAgICAgcmV0dXJuIHM7XG4gICAgfSksIGV4dGVudCk7XG4gIH1cblxuICB2b3Jvbm9pLnBvbHlnb25zID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIHJldHVybiB2b3Jvbm9pKGRhdGEpLnBvbHlnb25zKCk7XG4gIH07XG5cbiAgdm9yb25vaS5saW5rcyA9IGZ1bmN0aW9uKGRhdGEpIHtcbiAgICByZXR1cm4gdm9yb25vaShkYXRhKS5saW5rcygpO1xuICB9O1xuXG4gIHZvcm9ub2kudHJpYW5nbGVzID0gZnVuY3Rpb24oZGF0YSkge1xuICAgIHJldHVybiB2b3Jvbm9pKGRhdGEpLnRyaWFuZ2xlcygpO1xuICB9O1xuXG4gIHZvcm9ub2kueCA9IGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA/ICh4ID0gdHlwZW9mIF8gPT09IFwiZnVuY3Rpb25cIiA/IF8gOiBjb25zdGFudCQxMCgrXyksIHZvcm9ub2kpIDogeDtcbiAgfTtcblxuICB2b3Jvbm9pLnkgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoeSA9IHR5cGVvZiBfID09PSBcImZ1bmN0aW9uXCIgPyBfIDogY29uc3RhbnQkMTAoK18pLCB2b3Jvbm9pKSA6IHk7XG4gIH07XG5cbiAgdm9yb25vaS5leHRlbnQgPSBmdW5jdGlvbihfKSB7XG4gICAgcmV0dXJuIGFyZ3VtZW50cy5sZW5ndGggPyAoZXh0ZW50ID0gXyA9PSBudWxsID8gbnVsbCA6IFtbK19bMF1bMF0sICtfWzBdWzFdXSwgWytfWzFdWzBdLCArX1sxXVsxXV1dLCB2b3Jvbm9pKSA6IGV4dGVudCAmJiBbW2V4dGVudFswXVswXSwgZXh0ZW50WzBdWzFdXSwgW2V4dGVudFsxXVswXSwgZXh0ZW50WzFdWzFdXV07XG4gIH07XG5cbiAgdm9yb25vaS5zaXplID0gZnVuY3Rpb24oXykge1xuICAgIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gKGV4dGVudCA9IF8gPT0gbnVsbCA/IG51bGwgOiBbWzAsIDBdLCBbK19bMF0sICtfWzFdXV0sIHZvcm9ub2kpIDogZXh0ZW50ICYmIFtleHRlbnRbMV1bMF0gLSBleHRlbnRbMF1bMF0sIGV4dGVudFsxXVsxXSAtIGV4dGVudFswXVsxXV07XG4gIH07XG5cbiAgcmV0dXJuIHZvcm9ub2k7XG59O1xuXG5mdW5jdGlvbiBWb3Jvbm9pKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5Wb3Jvbm9pLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIlZvcm9ub2lcIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJtb2RpZmllc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwieFwiLCBcInR5cGVcIjogXCJmaWVsZFwiLCBcInJlcXVpcmVkXCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcInlcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJyZXF1aXJlZFwiOiB0cnVlIH0sXG4gICAgeyBcIm5hbWVcIjogXCJzaXplXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIgfSxcbiAgICB7IFwibmFtZVwiOiBcImV4dGVudFwiLCBcInR5cGVcIjogXCJhcnJheVwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDIsXG4gICAgICBcImRlZmF1bHRcIjogW1stMWU1LCAtMWU1XSwgWzFlNSwgMWU1XV0sXG4gICAgICBcImNvbnRlbnRcIjoge1widHlwZVwiOiBcIm51bWJlclwiLCBcImFycmF5XCI6IHRydWUsIFwibGVuZ3RoXCI6IDJ9IH0sXG4gICAgeyBcIm5hbWVcIjogXCJhc1wiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJkZWZhdWx0XCI6IFwicGF0aFwiIH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQ3OSA9IGluaGVyaXRzKFZvcm9ub2ksIFRyYW5zZm9ybSk7XG5cbnZhciBkZWZhdWx0RXh0ZW50ID0gW1stMWU1LCAtMWU1XSwgWzFlNSwgMWU1XV07XG5cbnByb3RvdHlwZSQ3OS50cmFuc2Zvcm0gPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgYXMgPSBfLmFzIHx8ICdwYXRoJyxcbiAgICAgIGRhdGEgPSBwdWxzZS5zb3VyY2UsXG4gICAgICBkaWFncmFtLCBwb2x5Z29ucywgaSwgbjtcblxuICAvLyBjb25maWd1cmUgYW5kIGNvbnN0cnVjdCB2b3Jvbm9pIGRpYWdyYW1cbiAgZGlhZ3JhbSA9IHZvcm9ub2kkMSgpLngoXy54KS55KF8ueSk7XG4gIGlmIChfLnNpemUpIGRpYWdyYW0uc2l6ZShfLnNpemUpO1xuICBlbHNlIGRpYWdyYW0uZXh0ZW50KF8uZXh0ZW50IHx8IGRlZmF1bHRFeHRlbnQpO1xuXG4gIHRoaXMudmFsdWUgPSAoZGlhZ3JhbSA9IGRpYWdyYW0oZGF0YSkpO1xuXG4gIC8vIG1hcCBwb2x5Z29ucyB0byBwYXRoc1xuICBwb2x5Z29ucyA9IGRpYWdyYW0ucG9seWdvbnMoKTtcbiAgZm9yIChpPTAsIG49ZGF0YS5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgZGF0YVtpXVthc10gPSBwb2x5Z29uc1tpXVxuICAgICAgPyAnTScgKyBwb2x5Z29uc1tpXS5qb2luKCdMJykgKyAnWidcbiAgICAgIDogbnVsbDtcbiAgfVxuXG4gIHJldHVybiBwdWxzZS5yZWZsb3coXy5tb2RpZmllZCgpKS5tb2RpZmllcyhhcyk7XG59O1xuXG5cblxudmFyIHZvcm9ub2kgPSBPYmplY3QuZnJlZXplKHtcblx0dm9yb25vaTogVm9yb25vaVxufSk7XG5cbi8qXG5Db3B5cmlnaHQgKGMpIDIwMTMsIEphc29uIERhdmllcy5cbkFsbCByaWdodHMgcmVzZXJ2ZWQuXG5cblJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxubW9kaWZpY2F0aW9uLCBhcmUgcGVybWl0dGVkIHByb3ZpZGVkIHRoYXQgdGhlIGZvbGxvd2luZyBjb25kaXRpb25zIGFyZSBtZXQ6XG5cbiAgKiBSZWRpc3RyaWJ1dGlvbnMgb2Ygc291cmNlIGNvZGUgbXVzdCByZXRhaW4gdGhlIGFib3ZlIGNvcHlyaWdodCBub3RpY2UsIHRoaXNcbiAgICBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cblxuICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0IG5vdGljZSxcbiAgICB0aGlzIGxpc3Qgb2YgY29uZGl0aW9ucyBhbmQgdGhlIGZvbGxvd2luZyBkaXNjbGFpbWVyIGluIHRoZSBkb2N1bWVudGF0aW9uXG4gICAgYW5kL29yIG90aGVyIG1hdGVyaWFscyBwcm92aWRlZCB3aXRoIHRoZSBkaXN0cmlidXRpb24uXG5cbiAgKiBUaGUgbmFtZSBKYXNvbiBEYXZpZXMgbWF5IG5vdCBiZSB1c2VkIHRvIGVuZG9yc2Ugb3IgcHJvbW90ZSBwcm9kdWN0c1xuICAgIGRlcml2ZWQgZnJvbSB0aGlzIHNvZnR3YXJlIHdpdGhvdXQgc3BlY2lmaWMgcHJpb3Igd3JpdHRlbiBwZXJtaXNzaW9uLlxuXG5USElTIFNPRlRXQVJFIElTIFBST1ZJREVEIEJZIFRIRSBDT1BZUklHSFQgSE9MREVSUyBBTkQgQ09OVFJJQlVUT1JTIFwiQVMgSVNcIiBBTkRcbkFOWSBFWFBSRVNTIE9SIElNUExJRUQgV0FSUkFOVElFUywgSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFRIRSBJTVBMSUVEXG5XQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0UgQVJFXG5ESVNDTEFJTUVELiBJTiBOTyBFVkVOVCBTSEFMTCBKQVNPTiBEQVZJRVMgQkUgTElBQkxFIEZPUiBBTlkgRElSRUNULCBJTkRJUkVDVCxcbklOQ0lERU5UQUwsIFNQRUNJQUwsIEVYRU1QTEFSWSwgT1IgQ09OU0VRVUVOVElBTCBEQU1BR0VTIChJTkNMVURJTkcsIEJVVCBOT1RcbkxJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7IExPU1MgT0YgVVNFLCBEQVRBLCBPUlxuUFJPRklUUzsgT1IgQlVTSU5FU1MgSU5URVJSVVBUSU9OKSBIT1dFVkVSIENBVVNFRCBBTkQgT04gQU5ZIFRIRU9SWSBPRlxuTElBQklMSVRZLCBXSEVUSEVSIElOIENPTlRSQUNULCBTVFJJQ1QgTElBQklMSVRZLCBPUiBUT1JUIChJTkNMVURJTkcgTkVHTElHRU5DRVxuT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0YgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRlxuQURWSVNFRCBPRiBUSEUgUE9TU0lCSUxJVFkgT0YgU1VDSCBEQU1BR0UuXG4qL1xuXG4vLyBXb3JkIGNsb3VkIGxheW91dCBieSBKYXNvbiBEYXZpZXMsIGh0dHBzOi8vd3d3Lmphc29uZGF2aWVzLmNvbS93b3JkY2xvdWQvXG4vLyBBbGdvcml0aG0gZHVlIHRvIEpvbmF0aGFuIEZlaW5iZXJnLCBodHRwOi8vc3RhdGljLm1yZmVpbmJlcmcuY29tL2J2X2NoMDMucGRmXG5cbnZhciBjbG91ZFJhZGlhbnMgPSBNYXRoLlBJIC8gMTgwO1xudmFyIGN3ID0gMSA8PCAxMSA+PiA1O1xudmFyIGNoID0gMSA8PCAxMTtcblxudmFyIGNsb3VkID0gZnVuY3Rpb24oKSB7XG4gIHZhciBzaXplID0gWzI1NiwgMjU2XSxcbiAgICAgIHRleHQsXG4gICAgICBmb250LFxuICAgICAgZm9udFNpemUsXG4gICAgICBmb250U3R5bGUsXG4gICAgICBmb250V2VpZ2h0LFxuICAgICAgcm90YXRlLFxuICAgICAgcGFkZGluZyxcbiAgICAgIHNwaXJhbCA9IGFyY2hpbWVkZWFuU3BpcmFsLFxuICAgICAgd29yZHMgPSBbXSxcbiAgICAgIHJhbmRvbSA9IE1hdGgucmFuZG9tLFxuICAgICAgY2xvdWQgPSB7fTtcblxuICBjbG91ZC5sYXlvdXQgPSBmdW5jdGlvbigpIHtcbiAgICB2YXIgY29udGV4dEFuZFJhdGlvID0gZ2V0Q29udGV4dChjYW52YXMoKSksXG4gICAgICAgIGJvYXJkID0gemVyb0FycmF5KChzaXplWzBdID4+IDUpICogc2l6ZVsxXSksXG4gICAgICAgIGJvdW5kcyA9IG51bGwsXG4gICAgICAgIG4gPSB3b3Jkcy5sZW5ndGgsXG4gICAgICAgIGkgPSAtMSxcbiAgICAgICAgdGFncyA9IFtdLFxuICAgICAgICBkYXRhID0gd29yZHMubWFwKGZ1bmN0aW9uKGQpIHtcbiAgICAgICAgICByZXR1cm4ge1xuICAgICAgICAgICAgdGV4dDogdGV4dChkKSxcbiAgICAgICAgICAgIGZvbnQ6IGZvbnQoZCksXG4gICAgICAgICAgICBzdHlsZTogZm9udFN0eWxlKGQpLFxuICAgICAgICAgICAgd2VpZ2h0OiBmb250V2VpZ2h0KGQpLFxuICAgICAgICAgICAgcm90YXRlOiByb3RhdGUoZCksXG4gICAgICAgICAgICBzaXplOiB+fmZvbnRTaXplKGQpLFxuICAgICAgICAgICAgcGFkZGluZzogcGFkZGluZyhkKSxcbiAgICAgICAgICAgIHhvZmY6IDAsXG4gICAgICAgICAgICB5b2ZmOiAwLFxuICAgICAgICAgICAgeDE6IDAsXG4gICAgICAgICAgICB5MTogMCxcbiAgICAgICAgICAgIHgwOiAwLFxuICAgICAgICAgICAgeTA6IDAsXG4gICAgICAgICAgICBoYXNUZXh0OiBmYWxzZSxcbiAgICAgICAgICAgIHNwcml0ZTogbnVsbCxcbiAgICAgICAgICAgIGRhdHVtOiBkXG4gICAgICAgICAgfTtcbiAgICAgICAgfSkuc29ydChmdW5jdGlvbihhLCBiKSB7IHJldHVybiBiLnNpemUgLSBhLnNpemU7IH0pO1xuXG4gICAgd2hpbGUgKCsraSA8IG4pIHtcbiAgICAgIHZhciBkID0gZGF0YVtpXTtcbiAgICAgIGQueCA9IChzaXplWzBdICogKHJhbmRvbSgpICsgLjUpKSA+PiAxO1xuICAgICAgZC55ID0gKHNpemVbMV0gKiAocmFuZG9tKCkgKyAuNSkpID4+IDE7XG4gICAgICBjbG91ZFNwcml0ZShjb250ZXh0QW5kUmF0aW8sIGQsIGRhdGEsIGkpO1xuICAgICAgaWYgKGQuaGFzVGV4dCAmJiBwbGFjZShib2FyZCwgZCwgYm91bmRzKSkge1xuICAgICAgICB0YWdzLnB1c2goZCk7XG4gICAgICAgIGlmIChib3VuZHMpIGNsb3VkQm91bmRzKGJvdW5kcywgZCk7XG4gICAgICAgIGVsc2UgYm91bmRzID0gW3t4OiBkLnggKyBkLngwLCB5OiBkLnkgKyBkLnkwfSwge3g6IGQueCArIGQueDEsIHk6IGQueSArIGQueTF9XTtcbiAgICAgICAgLy8gVGVtcG9yYXJ5IGhhY2tcbiAgICAgICAgZC54IC09IHNpemVbMF0gPj4gMTtcbiAgICAgICAgZC55IC09IHNpemVbMV0gPj4gMTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICByZXR1cm4gdGFncztcbiAgfTtcblxuICBmdW5jdGlvbiBnZXRDb250ZXh0KGNhbnZhcyQkMSkge1xuICAgIGNhbnZhcyQkMS53aWR0aCA9IGNhbnZhcyQkMS5oZWlnaHQgPSAxO1xuICAgIHZhciByYXRpbyA9IE1hdGguc3FydChjYW52YXMkJDEuZ2V0Q29udGV4dChcIjJkXCIpLmdldEltYWdlRGF0YSgwLCAwLCAxLCAxKS5kYXRhLmxlbmd0aCA+PiAyKTtcbiAgICBjYW52YXMkJDEud2lkdGggPSAoY3cgPDwgNSkgLyByYXRpbztcbiAgICBjYW52YXMkJDEuaGVpZ2h0ID0gY2ggLyByYXRpbztcblxuICAgIHZhciBjb250ZXh0ID0gY2FudmFzJCQxLmdldENvbnRleHQoXCIyZFwiKTtcbiAgICBjb250ZXh0LmZpbGxTdHlsZSA9IGNvbnRleHQuc3Ryb2tlU3R5bGUgPSBcInJlZFwiO1xuICAgIGNvbnRleHQudGV4dEFsaWduID0gXCJjZW50ZXJcIjtcblxuICAgIHJldHVybiB7Y29udGV4dDogY29udGV4dCwgcmF0aW86IHJhdGlvfTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHBsYWNlKGJvYXJkLCB0YWcsIGJvdW5kcykge1xuICAgIHZhciBzdGFydFggPSB0YWcueCxcbiAgICAgICAgc3RhcnRZID0gdGFnLnksXG4gICAgICAgIG1heERlbHRhID0gTWF0aC5zcXJ0KHNpemVbMF0gKiBzaXplWzBdICsgc2l6ZVsxXSAqIHNpemVbMV0pLFxuICAgICAgICBzID0gc3BpcmFsKHNpemUpLFxuICAgICAgICBkdCA9IHJhbmRvbSgpIDwgLjUgPyAxIDogLTEsXG4gICAgICAgIHQgPSAtZHQsXG4gICAgICAgIGR4ZHksXG4gICAgICAgIGR4LFxuICAgICAgICBkeTtcblxuICAgIHdoaWxlIChkeGR5ID0gcyh0ICs9IGR0KSkge1xuICAgICAgZHggPSB+fmR4ZHlbMF07XG4gICAgICBkeSA9IH5+ZHhkeVsxXTtcblxuICAgICAgaWYgKE1hdGgubWluKE1hdGguYWJzKGR4KSwgTWF0aC5hYnMoZHkpKSA+PSBtYXhEZWx0YSkgYnJlYWs7XG5cbiAgICAgIHRhZy54ID0gc3RhcnRYICsgZHg7XG4gICAgICB0YWcueSA9IHN0YXJ0WSArIGR5O1xuXG4gICAgICBpZiAodGFnLnggKyB0YWcueDAgPCAwIHx8IHRhZy55ICsgdGFnLnkwIDwgMCB8fFxuICAgICAgICAgIHRhZy54ICsgdGFnLngxID4gc2l6ZVswXSB8fCB0YWcueSArIHRhZy55MSA+IHNpemVbMV0pIGNvbnRpbnVlO1xuICAgICAgLy8gVE9ETyBvbmx5IGNoZWNrIGZvciBjb2xsaXNpb25zIHdpdGhpbiBjdXJyZW50IGJvdW5kcy5cbiAgICAgIGlmICghYm91bmRzIHx8ICFjbG91ZENvbGxpZGUodGFnLCBib2FyZCwgc2l6ZVswXSkpIHtcbiAgICAgICAgaWYgKCFib3VuZHMgfHwgY29sbGlkZVJlY3RzKHRhZywgYm91bmRzKSkge1xuICAgICAgICAgIHZhciBzcHJpdGUgPSB0YWcuc3ByaXRlLFxuICAgICAgICAgICAgICB3ID0gdGFnLndpZHRoID4+IDUsXG4gICAgICAgICAgICAgIHN3ID0gc2l6ZVswXSA+PiA1LFxuICAgICAgICAgICAgICBseCA9IHRhZy54IC0gKHcgPDwgNCksXG4gICAgICAgICAgICAgIHN4ID0gbHggJiAweDdmLFxuICAgICAgICAgICAgICBtc3ggPSAzMiAtIHN4LFxuICAgICAgICAgICAgICBoID0gdGFnLnkxIC0gdGFnLnkwLFxuICAgICAgICAgICAgICB4ID0gKHRhZy55ICsgdGFnLnkwKSAqIHN3ICsgKGx4ID4+IDUpLFxuICAgICAgICAgICAgICBsYXN0O1xuICAgICAgICAgIGZvciAodmFyIGogPSAwOyBqIDwgaDsgaisrKSB7XG4gICAgICAgICAgICBsYXN0ID0gMDtcbiAgICAgICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IHc7IGkrKykge1xuICAgICAgICAgICAgICBib2FyZFt4ICsgaV0gfD0gKGxhc3QgPDwgbXN4KSB8IChpIDwgdyA/IChsYXN0ID0gc3ByaXRlW2ogKiB3ICsgaV0pID4+PiBzeCA6IDApO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgeCArPSBzdztcbiAgICAgICAgICB9XG4gICAgICAgICAgdGFnLnNwcml0ZSA9IG51bGw7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG4gICAgcmV0dXJuIGZhbHNlO1xuICB9XG5cbiAgY2xvdWQud29yZHMgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHdvcmRzID0gXztcbiAgICAgIHJldHVybiBjbG91ZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIHdvcmRzO1xuICAgIH1cbiAgfTtcblxuICBjbG91ZC5zaXplID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBzaXplID0gWytfWzBdLCArX1sxXV07XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzaXplO1xuICAgIH1cbiAgfTtcblxuICBjbG91ZC5mb250ID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBmb250ID0gZnVuY3RvcihfKTtcbiAgICAgIHJldHVybiBjbG91ZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZvbnQ7XG4gICAgfVxuICB9O1xuXG4gIGNsb3VkLmZvbnRTdHlsZSA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgZm9udFN0eWxlID0gZnVuY3RvcihfKTtcbiAgICAgIHJldHVybiBjbG91ZDtcbiAgICB9IGVsc2Uge1xuICAgICAgcmV0dXJuIGZvbnRTdHlsZTtcbiAgICB9XG4gIH07XG5cbiAgY2xvdWQuZm9udFdlaWdodCA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgZm9udFdlaWdodCA9IGZ1bmN0b3IoXyk7XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmb250V2VpZ2h0O1xuICAgIH1cbiAgfTtcblxuICBjbG91ZC5yb3RhdGUgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJvdGF0ZSA9IGZ1bmN0b3IoXyk7XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByb3RhdGU7XG4gICAgfVxuICB9O1xuXG4gIGNsb3VkLnRleHQgPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHRleHQgPSBmdW5jdG9yKF8pO1xuICAgICAgcmV0dXJuIGNsb3VkO1xuICAgIH0gZWxzZSB7XG4gICAgICByZXR1cm4gdGV4dDtcbiAgICB9XG4gIH07XG5cbiAgY2xvdWQuc3BpcmFsID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBzcGlyYWwgPSBzcGlyYWxzW19dIHx8IF87XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBzcGlyYWw7XG4gICAgfVxuICB9O1xuXG4gIGNsb3VkLmZvbnRTaXplID0gZnVuY3Rpb24oXykge1xuICAgIGlmIChhcmd1bWVudHMubGVuZ3RoKSB7XG4gICAgICBmb250U2l6ZSA9IGZ1bmN0b3IoXyk7XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBmb250U2l6ZTtcbiAgICB9XG4gIH07XG5cbiAgY2xvdWQucGFkZGluZyA9IGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgICAgcGFkZGluZyA9IGZ1bmN0b3IoXyk7XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBwYWRkaW5nO1xuICAgIH1cbiAgfTtcblxuICBjbG91ZC5yYW5kb20gPSBmdW5jdGlvbihfKSB7XG4gICAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICAgIHJhbmRvbSA9IF87XG4gICAgICByZXR1cm4gY2xvdWQ7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiByYW5kb207XG4gICAgfVxuICB9O1xuXG4gIHJldHVybiBjbG91ZDtcbn07XG5cbi8vIEZldGNoZXMgYSBtb25vY2hyb21lIHNwcml0ZSBiaXRtYXAgZm9yIHRoZSBzcGVjaWZpZWQgdGV4dC5cbi8vIExvYWQgaW4gYmF0Y2hlcyBmb3Igc3BlZWQuXG5mdW5jdGlvbiBjbG91ZFNwcml0ZShjb250ZXh0QW5kUmF0aW8sIGQsIGRhdGEsIGRpKSB7XG4gIGlmIChkLnNwcml0ZSkgcmV0dXJuO1xuICB2YXIgYyA9IGNvbnRleHRBbmRSYXRpby5jb250ZXh0LFxuICAgICAgcmF0aW8gPSBjb250ZXh0QW5kUmF0aW8ucmF0aW87XG5cbiAgYy5jbGVhclJlY3QoMCwgMCwgKGN3IDw8IDUpIC8gcmF0aW8sIGNoIC8gcmF0aW8pO1xuICB2YXIgeCA9IDAsXG4gICAgICB5ID0gMCxcbiAgICAgIG1heGggPSAwLFxuICAgICAgbiA9IGRhdGEubGVuZ3RoLFxuICAgICAgdywgdzMyLCBoLCBpLCBqO1xuICAtLWRpO1xuICB3aGlsZSAoKytkaSA8IG4pIHtcbiAgICBkID0gZGF0YVtkaV07XG4gICAgYy5zYXZlKCk7XG4gICAgYy5mb250ID0gZC5zdHlsZSArIFwiIFwiICsgZC53ZWlnaHQgKyBcIiBcIiArIH5+KChkLnNpemUgKyAxKSAvIHJhdGlvKSArIFwicHggXCIgKyBkLmZvbnQ7XG4gICAgdyA9IGMubWVhc3VyZVRleHQoZC50ZXh0ICsgXCJtXCIpLndpZHRoICogcmF0aW87XG4gICAgaCA9IGQuc2l6ZSA8PCAxO1xuICAgIGlmIChkLnJvdGF0ZSkge1xuICAgICAgdmFyIHNyID0gTWF0aC5zaW4oZC5yb3RhdGUgKiBjbG91ZFJhZGlhbnMpLFxuICAgICAgICAgIGNyID0gTWF0aC5jb3MoZC5yb3RhdGUgKiBjbG91ZFJhZGlhbnMpLFxuICAgICAgICAgIHdjciA9IHcgKiBjcixcbiAgICAgICAgICB3c3IgPSB3ICogc3IsXG4gICAgICAgICAgaGNyID0gaCAqIGNyLFxuICAgICAgICAgIGhzciA9IGggKiBzcjtcbiAgICAgIHcgPSAoTWF0aC5tYXgoTWF0aC5hYnMod2NyICsgaHNyKSwgTWF0aC5hYnMod2NyIC0gaHNyKSkgKyAweDFmKSA+PiA1IDw8IDU7XG4gICAgICBoID0gfn5NYXRoLm1heChNYXRoLmFicyh3c3IgKyBoY3IpLCBNYXRoLmFicyh3c3IgLSBoY3IpKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdyA9ICh3ICsgMHgxZikgPj4gNSA8PCA1O1xuICAgIH1cbiAgICBpZiAoaCA+IG1heGgpIG1heGggPSBoO1xuICAgIGlmICh4ICsgdyA+PSAoY3cgPDwgNSkpIHtcbiAgICAgIHggPSAwO1xuICAgICAgeSArPSBtYXhoO1xuICAgICAgbWF4aCA9IDA7XG4gICAgfVxuICAgIGlmICh5ICsgaCA+PSBjaCkgYnJlYWs7XG4gICAgYy50cmFuc2xhdGUoKHggKyAodyA+PiAxKSkgLyByYXRpbywgKHkgKyAoaCA+PiAxKSkgLyByYXRpbyk7XG4gICAgaWYgKGQucm90YXRlKSBjLnJvdGF0ZShkLnJvdGF0ZSAqIGNsb3VkUmFkaWFucyk7XG4gICAgYy5maWxsVGV4dChkLnRleHQsIDAsIDApO1xuICAgIGlmIChkLnBhZGRpbmcpIHtcbiAgICAgIGMubGluZVdpZHRoID0gMiAqIGQucGFkZGluZztcbiAgICAgIGMuc3Ryb2tlVGV4dChkLnRleHQsIDAsIDApO1xuICAgIH1cbiAgICBjLnJlc3RvcmUoKTtcbiAgICBkLndpZHRoID0gdztcbiAgICBkLmhlaWdodCA9IGg7XG4gICAgZC54b2ZmID0geDtcbiAgICBkLnlvZmYgPSB5O1xuICAgIGQueDEgPSB3ID4+IDE7XG4gICAgZC55MSA9IGggPj4gMTtcbiAgICBkLngwID0gLWQueDE7XG4gICAgZC55MCA9IC1kLnkxO1xuICAgIGQuaGFzVGV4dCA9IHRydWU7XG4gICAgeCArPSB3O1xuICB9XG4gIHZhciBwaXhlbHMgPSBjLmdldEltYWdlRGF0YSgwLCAwLCAoY3cgPDwgNSkgLyByYXRpbywgY2ggLyByYXRpbykuZGF0YSxcbiAgICAgIHNwcml0ZSA9IFtdO1xuICB3aGlsZSAoLS1kaSA+PSAwKSB7XG4gICAgZCA9IGRhdGFbZGldO1xuICAgIGlmICghZC5oYXNUZXh0KSBjb250aW51ZTtcbiAgICB3ID0gZC53aWR0aDtcbiAgICB3MzIgPSB3ID4+IDU7XG4gICAgaCA9IGQueTEgLSBkLnkwO1xuICAgIC8vIFplcm8gdGhlIGJ1ZmZlclxuICAgIGZvciAoaSA9IDA7IGkgPCBoICogdzMyOyBpKyspIHNwcml0ZVtpXSA9IDA7XG4gICAgeCA9IGQueG9mZjtcbiAgICBpZiAoeCA9PSBudWxsKSByZXR1cm47XG4gICAgeSA9IGQueW9mZjtcbiAgICB2YXIgc2VlbiA9IDAsXG4gICAgICAgIHNlZW5Sb3cgPSAtMTtcbiAgICBmb3IgKGogPSAwOyBqIDwgaDsgaisrKSB7XG4gICAgICBmb3IgKGkgPSAwOyBpIDwgdzsgaSsrKSB7XG4gICAgICAgIHZhciBrID0gdzMyICogaiArIChpID4+IDUpLFxuICAgICAgICAgICAgbSA9IHBpeGVsc1soKHkgKyBqKSAqIChjdyA8PCA1KSArICh4ICsgaSkpIDw8IDJdID8gMSA8PCAoMzEgLSAoaSAlIDMyKSkgOiAwO1xuICAgICAgICBzcHJpdGVba10gfD0gbTtcbiAgICAgICAgc2VlbiB8PSBtO1xuICAgICAgfVxuICAgICAgaWYgKHNlZW4pIHNlZW5Sb3cgPSBqO1xuICAgICAgZWxzZSB7XG4gICAgICAgIGQueTArKztcbiAgICAgICAgaC0tO1xuICAgICAgICBqLS07XG4gICAgICAgIHkrKztcbiAgICAgIH1cbiAgICB9XG4gICAgZC55MSA9IGQueTAgKyBzZWVuUm93O1xuICAgIGQuc3ByaXRlID0gc3ByaXRlLnNsaWNlKDAsIChkLnkxIC0gZC55MCkgKiB3MzIpO1xuICB9XG59XG5cbi8vIFVzZSBtYXNrLWJhc2VkIGNvbGxpc2lvbiBkZXRlY3Rpb24uXG5mdW5jdGlvbiBjbG91ZENvbGxpZGUodGFnLCBib2FyZCwgc3cpIHtcbiAgc3cgPj49IDU7XG4gIHZhciBzcHJpdGUgPSB0YWcuc3ByaXRlLFxuICAgICAgdyA9IHRhZy53aWR0aCA+PiA1LFxuICAgICAgbHggPSB0YWcueCAtICh3IDw8IDQpLFxuICAgICAgc3ggPSBseCAmIDB4N2YsXG4gICAgICBtc3ggPSAzMiAtIHN4LFxuICAgICAgaCA9IHRhZy55MSAtIHRhZy55MCxcbiAgICAgIHggPSAodGFnLnkgKyB0YWcueTApICogc3cgKyAobHggPj4gNSksXG4gICAgICBsYXN0O1xuICBmb3IgKHZhciBqID0gMDsgaiA8IGg7IGorKykge1xuICAgIGxhc3QgPSAwO1xuICAgIGZvciAodmFyIGkgPSAwOyBpIDw9IHc7IGkrKykge1xuICAgICAgaWYgKCgobGFzdCA8PCBtc3gpIHwgKGkgPCB3ID8gKGxhc3QgPSBzcHJpdGVbaiAqIHcgKyBpXSkgPj4+IHN4IDogMCkpXG4gICAgICAgICAgJiBib2FyZFt4ICsgaV0pIHJldHVybiB0cnVlO1xuICAgIH1cbiAgICB4ICs9IHN3O1xuICB9XG4gIHJldHVybiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gY2xvdWRCb3VuZHMoYm91bmRzLCBkKSB7XG4gIHZhciBiMCA9IGJvdW5kc1swXSxcbiAgICAgIGIxID0gYm91bmRzWzFdO1xuICBpZiAoZC54ICsgZC54MCA8IGIwLngpIGIwLnggPSBkLnggKyBkLngwO1xuICBpZiAoZC55ICsgZC55MCA8IGIwLnkpIGIwLnkgPSBkLnkgKyBkLnkwO1xuICBpZiAoZC54ICsgZC54MSA+IGIxLngpIGIxLnggPSBkLnggKyBkLngxO1xuICBpZiAoZC55ICsgZC55MSA+IGIxLnkpIGIxLnkgPSBkLnkgKyBkLnkxO1xufVxuXG5mdW5jdGlvbiBjb2xsaWRlUmVjdHMoYSwgYikge1xuICByZXR1cm4gYS54ICsgYS54MSA+IGJbMF0ueCAmJiBhLnggKyBhLngwIDwgYlsxXS54ICYmIGEueSArIGEueTEgPiBiWzBdLnkgJiYgYS55ICsgYS55MCA8IGJbMV0ueTtcbn1cblxuZnVuY3Rpb24gYXJjaGltZWRlYW5TcGlyYWwoc2l6ZSkge1xuICB2YXIgZSA9IHNpemVbMF0gLyBzaXplWzFdO1xuICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgIHJldHVybiBbZSAqICh0ICo9IC4xKSAqIE1hdGguY29zKHQpLCB0ICogTWF0aC5zaW4odCldO1xuICB9O1xufVxuXG5mdW5jdGlvbiByZWN0YW5ndWxhclNwaXJhbChzaXplKSB7XG4gIHZhciBkeSA9IDQsXG4gICAgICBkeCA9IGR5ICogc2l6ZVswXSAvIHNpemVbMV0sXG4gICAgICB4ID0gMCxcbiAgICAgIHkgPSAwO1xuICByZXR1cm4gZnVuY3Rpb24odCkge1xuICAgIHZhciBzaWduID0gdCA8IDAgPyAtMSA6IDE7XG4gICAgLy8gU2VlIHRyaWFuZ3VsYXIgbnVtYmVyczogVF9uID0gbiAqIChuICsgMSkgLyAyLlxuICAgIHN3aXRjaCAoKE1hdGguc3FydCgxICsgNCAqIHNpZ24gKiB0KSAtIHNpZ24pICYgMykge1xuICAgICAgY2FzZSAwOiAgeCArPSBkeDsgYnJlYWs7XG4gICAgICBjYXNlIDE6ICB5ICs9IGR5OyBicmVhaztcbiAgICAgIGNhc2UgMjogIHggLT0gZHg7IGJyZWFrO1xuICAgICAgZGVmYXVsdDogeSAtPSBkeTsgYnJlYWs7XG4gICAgfVxuICAgIHJldHVybiBbeCwgeV07XG4gIH07XG59XG5cbi8vIFRPRE8gcmV1c2UgYXJyYXlzP1xuZnVuY3Rpb24gemVyb0FycmF5KG4pIHtcbiAgdmFyIGEgPSBbXSxcbiAgICAgIGkgPSAtMTtcbiAgd2hpbGUgKCsraSA8IG4pIGFbaV0gPSAwO1xuICByZXR1cm4gYTtcbn1cblxuZnVuY3Rpb24gZnVuY3RvcihkKSB7XG4gIHJldHVybiB0eXBlb2YgZCA9PT0gXCJmdW5jdGlvblwiID8gZCA6IGZ1bmN0aW9uKCkgeyByZXR1cm4gZDsgfTtcbn1cblxudmFyIHNwaXJhbHMgPSB7XG4gIGFyY2hpbWVkZWFuOiBhcmNoaW1lZGVhblNwaXJhbCxcbiAgcmVjdGFuZ3VsYXI6IHJlY3Rhbmd1bGFyU3BpcmFsXG59O1xuXG52YXIgT3V0cHV0JDQgPSBbJ3gnLCAneScsICdmb250JywgJ2ZvbnRTaXplJywgJ2ZvbnRTdHlsZScsICdmb250V2VpZ2h0JywgJ2FuZ2xlJ107XG5cbnZhciBQYXJhbXMkMSA9IFsndGV4dCcsICdmb250JywgJ3JvdGF0ZScsICdmb250U2l6ZScsICdmb250U3R5bGUnLCAnZm9udFdlaWdodCddO1xuXG5mdW5jdGlvbiBXb3JkY2xvdWQocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIGNsb3VkKCksIHBhcmFtcyk7XG59XG5cbldvcmRjbG91ZC5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJXb3JkY2xvdWRcIixcbiAgXCJtZXRhZGF0YVwiOiB7XCJtb2RpZmllc1wiOiB0cnVlfSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwic2l6ZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiAyIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmb250XCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcImV4cHJcIjogdHJ1ZSwgXCJkZWZhdWx0XCI6IFwic2Fucy1zZXJpZlwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmb250U3R5bGVcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiZXhwclwiOiB0cnVlLCBcImRlZmF1bHRcIjogXCJub3JtYWxcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZm9udFdlaWdodFwiLCBcInR5cGVcIjogXCJzdHJpbmdcIiwgXCJleHByXCI6IHRydWUsIFwiZGVmYXVsdFwiOiBcIm5vcm1hbFwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmb250U2l6ZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJleHByXCI6IHRydWUsIFwiZGVmYXVsdFwiOiAxNCB9LFxuICAgIHsgXCJuYW1lXCI6IFwiZm9udFNpemVSYW5nZVwiLCBcInR5cGVcIjogXCJudW1iZXJcIiwgXCJhcnJheVwiOiBcIm51bGxhYmxlXCIsIFwiZGVmYXVsdFwiOiBbMTAsIDUwXSB9LFxuICAgIHsgXCJuYW1lXCI6IFwicm90YXRlXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImV4cHJcIjogdHJ1ZSwgXCJkZWZhdWx0XCI6IDAgfSxcbiAgICB7IFwibmFtZVwiOiBcInRleHRcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiB9LFxuICAgIHsgXCJuYW1lXCI6IFwic3BpcmFsXCIsIFwidHlwZVwiOiBcInN0cmluZ1wiLCBcInZhbHVlc1wiOiBbXCJhcmNoaW1lZGVhblwiLCBcInJlY3Rhbmd1bGFyXCJdIH0sXG4gICAgeyBcIm5hbWVcIjogXCJwYWRkaW5nXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcImV4cHJcIjogdHJ1ZSB9LFxuICAgIHsgXCJuYW1lXCI6IFwiYXNcIiwgXCJ0eXBlXCI6IFwic3RyaW5nXCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJsZW5ndGhcIjogNywgXCJkZWZhdWx0XCI6IE91dHB1dCQ0IH1cbiAgXVxufTtcblxudmFyIHByb3RvdHlwZSQ4MCA9IGluaGVyaXRzKFdvcmRjbG91ZCwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDgwLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGZ1bmN0aW9uIG1vZHAocGFyYW0pIHtcbiAgICB2YXIgcCA9IF9bcGFyYW1dO1xuICAgIHJldHVybiBpc0Z1bmN0aW9uKHApICYmIHB1bHNlLm1vZGlmaWVkKHAuZmllbGRzKTtcbiAgfVxuXG4gIHZhciBtb2QgPSBfLm1vZGlmaWVkKCk7XG4gIGlmICghKG1vZCB8fCBwdWxzZS5jaGFuZ2VkKHB1bHNlLkFERF9SRU0pIHx8IFBhcmFtcyQxLnNvbWUobW9kcCkpKSByZXR1cm47XG5cbiAgdmFyIGRhdGEgPSBwdWxzZS5tYXRlcmlhbGl6ZShwdWxzZS5TT1VSQ0UpLnNvdXJjZSxcbiAgICAgIGxheW91dCA9IHRoaXMudmFsdWUsXG4gICAgICBhcyA9IF8uYXMgfHwgT3V0cHV0JDQsXG4gICAgICBmb250U2l6ZSA9IF8uZm9udFNpemUgfHwgMTQsXG4gICAgICByYW5nZTtcblxuICBpc0Z1bmN0aW9uKGZvbnRTaXplKVxuICAgID8gKHJhbmdlID0gXy5mb250U2l6ZVJhbmdlKVxuICAgIDogKGZvbnRTaXplID0gY29uc3RhbnQoZm9udFNpemUpKTtcblxuICAvLyBjcmVhdGUgZm9udCBzaXplIHNjYWxpbmcgZnVuY3Rpb24gYXMgbmVlZGVkXG4gIGlmIChyYW5nZSkge1xuICAgIHZhciBmc2l6ZSA9IGZvbnRTaXplLFxuICAgICAgICBzaXplU2NhbGUgPSBzY2FsZSQxKCdzcXJ0JykoKVxuICAgICAgICAgIC5kb21haW4oZXh0ZW50JDIoZnNpemUsIGRhdGEpKVxuICAgICAgICAgIC5yYW5nZShyYW5nZSk7XG4gICAgZm9udFNpemUgPSBmdW5jdGlvbih4KSB7IHJldHVybiBzaXplU2NhbGUoZnNpemUoeCkpOyB9O1xuICB9XG5cbiAgZGF0YS5mb3JFYWNoKGZ1bmN0aW9uKHQpIHtcbiAgICB0W2FzWzBdXSA9IE5hTjtcbiAgICB0W2FzWzFdXSA9IE5hTjtcbiAgICB0W2FzWzNdXSA9IDA7XG4gIH0pO1xuXG4gIC8vIGNvbmZpZ3VyZSBsYXlvdXRcbiAgdmFyIHdvcmRzID0gbGF5b3V0XG4gICAgLndvcmRzKGRhdGEpXG4gICAgLnRleHQoXy50ZXh0KVxuICAgIC5zaXplKF8uc2l6ZSB8fCBbNTAwLCA1MDBdKVxuICAgIC5wYWRkaW5nKF8ucGFkZGluZyB8fCAxKVxuICAgIC5zcGlyYWwoXy5zcGlyYWwgfHwgJ2FyY2hpbWVkZWFuJylcbiAgICAucm90YXRlKF8ucm90YXRlIHx8IDApXG4gICAgLmZvbnQoXy5mb250IHx8ICdzYW5zLXNlcmlmJylcbiAgICAuZm9udFN0eWxlKF8uZm9udFN0eWxlIHx8ICdub3JtYWwnKVxuICAgIC5mb250V2VpZ2h0KF8uZm9udFdlaWdodCB8fCAnbm9ybWFsJylcbiAgICAuZm9udFNpemUoZm9udFNpemUpXG4gICAgLnJhbmRvbShleHBvcnRzLnJhbmRvbSlcbiAgICAubGF5b3V0KCk7XG5cbiAgdmFyIHNpemUgPSBsYXlvdXQuc2l6ZSgpLFxuICAgICAgZHggPSBzaXplWzBdID4+IDEsXG4gICAgICBkeSA9IHNpemVbMV0gPj4gMSxcbiAgICAgIGkgPSAwLFxuICAgICAgbiA9IHdvcmRzLmxlbmd0aCxcbiAgICAgIHcsIHQ7XG5cbiAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgdyA9IHdvcmRzW2ldO1xuICAgIHQgPSB3LmRhdHVtO1xuICAgIHRbYXNbMF1dID0gdy54ICsgZHg7XG4gICAgdFthc1sxXV0gPSB3LnkgKyBkeTtcbiAgICB0W2FzWzJdXSA9IHcuZm9udDtcbiAgICB0W2FzWzNdXSA9IHcuc2l6ZTtcbiAgICB0W2FzWzRdXSA9IHcuc3R5bGU7XG4gICAgdFthc1s1XV0gPSB3LndlaWdodDtcbiAgICB0W2FzWzZdXSA9IHcucm90YXRlO1xuICB9XG5cbiAgcmV0dXJuIHB1bHNlLnJlZmxvdyhtb2QpLm1vZGlmaWVzKGFzKTtcbn07XG5cbmZ1bmN0aW9uIGV4dGVudCQyKGZpZWxkJCQxLCBkYXRhKSB7XG4gIHZhciBtaW4gPSArSW5maW5pdHksXG4gICAgICBtYXggPSAtSW5maW5pdHksXG4gICAgICBpID0gMCxcbiAgICAgIG4gPSBkYXRhLmxlbmd0aCxcbiAgICAgIHY7XG5cbiAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgdiA9IGZpZWxkJCQxKGRhdGFbaV0pO1xuICAgIGlmICh2IDwgbWluKSBtaW4gPSB2O1xuICAgIGlmICh2ID4gbWF4KSBtYXggPSB2O1xuICB9XG5cbiAgcmV0dXJuIFttaW4sIG1heF07XG59XG5cblxuXG52YXIgd29yZGNsb3VkID0gT2JqZWN0LmZyZWV6ZSh7XG5cdHdvcmRjbG91ZDogV29yZGNsb3VkXG59KTtcblxuZnVuY3Rpb24gYXJyYXk4KG4pIHsgcmV0dXJuIG5ldyBVaW50OEFycmF5KG4pOyB9XG5cbmZ1bmN0aW9uIGFycmF5MTYobikgeyByZXR1cm4gbmV3IFVpbnQxNkFycmF5KG4pOyB9XG5cbmZ1bmN0aW9uIGFycmF5MzIobikgeyByZXR1cm4gbmV3IFVpbnQzMkFycmF5KG4pOyB9XG5cbi8qKlxuICogTWFpbnRhaW5zIENyb3NzRmlsdGVyIHN0YXRlLlxuICovXG5mdW5jdGlvbiBCaXRtYXBzKCkge1xuXG4gIHZhciB3aWR0aCA9IDgsXG4gICAgICBkYXRhID0gW10sXG4gICAgICBzZWVuID0gYXJyYXkzMigwKSxcbiAgICAgIGN1cnIgPSBhcnJheSQ1KDAsIHdpZHRoKSxcbiAgICAgIHByZXYgPSBhcnJheSQ1KDAsIHdpZHRoKTtcblxuICByZXR1cm4ge1xuXG4gICAgZGF0YTogZnVuY3Rpb24oKSB7IHJldHVybiBkYXRhOyB9LFxuXG4gICAgc2VlbjogZnVuY3Rpb24oKSB7XG4gICAgICByZXR1cm4gKHNlZW4gPSBsZW5ndGhlbihzZWVuLCBkYXRhLmxlbmd0aCkpO1xuICAgIH0sXG5cbiAgICBhZGQ6IGZ1bmN0aW9uKGFycmF5KSB7XG4gICAgICBmb3IgKHZhciBpPTAsIGo9ZGF0YS5sZW5ndGgsIG49YXJyYXkubGVuZ3RoLCB0OyBpPG47ICsraSkge1xuICAgICAgICB0ID0gYXJyYXlbaV07XG4gICAgICAgIHQuX2luZGV4ID0gaisrO1xuICAgICAgICBkYXRhLnB1c2godCk7XG4gICAgICB9XG4gICAgfSxcblxuICAgIHJlbW92ZTogZnVuY3Rpb24obnVtLCBtYXApIHsgLy8gbWFwOiBpbmRleCAtPiBib29sZWFuICh0cnVlID0+IHJlbW92ZSlcbiAgICAgIHZhciBuID0gZGF0YS5sZW5ndGgsXG4gICAgICAgICAgY29weSA9IEFycmF5KG4gLSBudW0pLFxuICAgICAgICAgIHJlaW5kZXggPSBkYXRhLCAvLyByZXVzZSBvbGQgZGF0YSBhcnJheSBmb3IgaW5kZXggbWFwXG4gICAgICAgICAgdCwgaSwgajtcblxuICAgICAgLy8gc2VlayBmb3J3YXJkIHRvIGZpcnN0IHJlbW92YWxcbiAgICAgIGZvciAoaT0wOyAhbWFwW2ldICYmIGk8bjsgKytpKSB7XG4gICAgICAgIGNvcHlbaV0gPSBkYXRhW2ldO1xuICAgICAgICByZWluZGV4W2ldID0gaTtcbiAgICAgIH1cblxuICAgICAgLy8gY29uZGVuc2UgYXJyYXlzXG4gICAgICBmb3IgKGo9aTsgaTxuOyArK2kpIHtcbiAgICAgICAgdCA9IGRhdGFbaV07XG4gICAgICAgIGlmICghbWFwW2ldKSB7XG4gICAgICAgICAgcmVpbmRleFtpXSA9IGo7XG4gICAgICAgICAgY3VycltqXSA9IGN1cnJbaV07XG4gICAgICAgICAgcHJldltqXSA9IHByZXZbaV07XG4gICAgICAgICAgY29weVtqXSA9IHQ7XG4gICAgICAgICAgdC5faW5kZXggPSBqKys7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcmVpbmRleFtpXSA9IC0xO1xuICAgICAgICB9XG4gICAgICAgIGN1cnJbaV0gPSAwOyAvLyBjbGVhciB1bnVzZWQgYml0c1xuICAgICAgfVxuXG4gICAgICBkYXRhID0gY29weTtcbiAgICAgIHJldHVybiByZWluZGV4O1xuICAgIH0sXG5cbiAgICBzaXplOiBmdW5jdGlvbigpIHsgcmV0dXJuIGRhdGEubGVuZ3RoOyB9LFxuXG4gICAgY3VycjogZnVuY3Rpb24oKSB7IHJldHVybiBjdXJyOyB9LFxuXG4gICAgcHJldjogZnVuY3Rpb24oKSB7IHJldHVybiBwcmV2OyB9LFxuXG4gICAgcmVzZXQ6IGZ1bmN0aW9uKGspIHsgcHJldltrXSA9IGN1cnJba107IH0sXG5cbiAgICBhbGw6IGZ1bmN0aW9uKCkge1xuICAgICAgcmV0dXJuIHdpZHRoIDwgMHgxMDEgPyAweGZmIDogd2lkdGggPCAweDEwMDAxID8gMHhmZmZmIDogMHhmZmZmZmZmZjtcbiAgICB9LFxuXG4gICAgc2V0OiBmdW5jdGlvbihrLCBvbmUpIHsgY3VycltrXSB8PSBvbmU7IH0sXG5cbiAgICBjbGVhcjogZnVuY3Rpb24oaywgb25lKSB7IGN1cnJba10gJj0gfm9uZTsgfSxcblxuICAgIHJlc2l6ZTogZnVuY3Rpb24obiwgbSkge1xuICAgICAgdmFyIGsgPSBjdXJyLmxlbmd0aDtcbiAgICAgIGlmIChuID4gayB8fCBtID4gd2lkdGgpIHtcbiAgICAgICAgd2lkdGggPSBNYXRoLm1heChtLCB3aWR0aCk7XG4gICAgICAgIGN1cnIgPSBhcnJheSQ1KG4sIHdpZHRoLCBjdXJyKTtcbiAgICAgICAgcHJldiA9IGFycmF5JDUobiwgd2lkdGgpO1xuICAgICAgfVxuICAgIH1cbiAgfTtcbn1cblxuZnVuY3Rpb24gbGVuZ3RoZW4oYXJyYXksIGxlbmd0aCwgY29weSkge1xuICBpZiAoYXJyYXkubGVuZ3RoID49IGxlbmd0aCkgcmV0dXJuIGFycmF5O1xuICBjb3B5ID0gY29weSB8fCBuZXcgYXJyYXkuY29uc3RydWN0b3IobGVuZ3RoKTtcbiAgY29weS5zZXQoYXJyYXkpO1xuICByZXR1cm4gY29weTtcbn1cblxuZnVuY3Rpb24gYXJyYXkkNShuLCBtLCBhcnJheSkge1xuICB2YXIgY29weSA9IChtIDwgMHgxMDEgPyBhcnJheTggOiBtIDwgMHgxMDAwMSA/IGFycmF5MTYgOiBhcnJheTMyKShuKTtcbiAgaWYgKGFycmF5KSBjb3B5LnNldChhcnJheSk7XG4gIHJldHVybiBjb3B5O1xufVxuXG52YXIgRGltZW5zaW9uID0gZnVuY3Rpb24oaW5kZXgsIGksIHF1ZXJ5KSB7XG4gIHZhciBiaXQgPSAoMSA8PCBpKTtcblxuICByZXR1cm4ge1xuICAgIG9uZTogICAgIGJpdCxcbiAgICB6ZXJvOiAgICB+Yml0LFxuICAgIHJhbmdlOiAgIHF1ZXJ5LnNsaWNlKCksXG4gICAgYmlzZWN0OiAgaW5kZXguYmlzZWN0LFxuICAgIGluZGV4OiAgIGluZGV4LmluZGV4LFxuICAgIHNpemU6ICAgIGluZGV4LnNpemUsXG5cbiAgICBvbkFkZDogZnVuY3Rpb24oYWRkZWQsIGN1cnIpIHtcbiAgICAgIHZhciBkaW0gPSB0aGlzLFxuICAgICAgICAgIHJhbmdlID0gZGltLmJpc2VjdChkaW0ucmFuZ2UsIGFkZGVkLnZhbHVlKSxcbiAgICAgICAgICBpZHggPSBhZGRlZC5pbmRleCxcbiAgICAgICAgICBsbyA9IHJhbmdlWzBdLFxuICAgICAgICAgIGhpID0gcmFuZ2VbMV0sXG4gICAgICAgICAgbjEgPSBpZHgubGVuZ3RoLCBpO1xuXG4gICAgICBmb3IgKGk9MDsgIGk8bG87ICsraSkgY3VycltpZHhbaV1dIHw9IGJpdDtcbiAgICAgIGZvciAoaT1oaTsgaTxuMTsgKytpKSBjdXJyW2lkeFtpXV0gfD0gYml0O1xuICAgICAgcmV0dXJuIGRpbTtcbiAgICB9XG4gIH07XG59O1xuXG4vKipcbiAqIE1haW50YWlucyBhIGxpc3Qgb2YgdmFsdWVzLCBzb3J0ZWQgYnkga2V5LlxuICovXG5mdW5jdGlvbiBTb3J0ZWRJbmRleCgpIHtcbiAgdmFyIGluZGV4ID0gYXJyYXkzMigwKSxcbiAgICAgIHZhbHVlID0gW10sXG4gICAgICBzaXplID0gMDtcblxuICBmdW5jdGlvbiBpbnNlcnQoa2V5LCBkYXRhLCBiYXNlKSB7XG4gICAgaWYgKCFkYXRhLmxlbmd0aCkgcmV0dXJuIFtdO1xuXG4gICAgdmFyIG4wID0gc2l6ZSxcbiAgICAgICAgbjEgPSBkYXRhLmxlbmd0aCxcbiAgICAgICAgYWRkdiA9IEFycmF5KG4xKSxcbiAgICAgICAgYWRkaSA9IGFycmF5MzIobjEpLFxuICAgICAgICBvbGR2LCBvbGRpLCBpO1xuXG4gICAgZm9yIChpPTA7IGk8bjE7ICsraSkge1xuICAgICAgYWRkdltpXSA9IGtleShkYXRhW2ldKTtcbiAgICAgIGFkZGlbaV0gPSBpO1xuICAgIH1cbiAgICBhZGR2ID0gc29ydChhZGR2LCBhZGRpKTtcblxuICAgIGlmIChuMCkge1xuICAgICAgb2xkdiA9IHZhbHVlO1xuICAgICAgb2xkaSA9IGluZGV4O1xuICAgICAgdmFsdWUgPSBBcnJheShuMCArIG4xKTtcbiAgICAgIGluZGV4ID0gYXJyYXkzMihuMCArIG4xKTtcbiAgICAgIG1lcmdlJDMoYmFzZSwgb2xkdiwgb2xkaSwgbjAsIGFkZHYsIGFkZGksIG4xLCB2YWx1ZSwgaW5kZXgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoYmFzZSA+IDApIGZvciAoaT0wOyBpPG4xOyArK2kpIHtcbiAgICAgICAgYWRkaVtpXSArPSBiYXNlO1xuICAgICAgfVxuICAgICAgdmFsdWUgPSBhZGR2O1xuICAgICAgaW5kZXggPSBhZGRpO1xuICAgIH1cbiAgICBzaXplID0gbjAgKyBuMTtcblxuICAgIHJldHVybiB7aW5kZXg6IGFkZGksIHZhbHVlOiBhZGR2fTtcbiAgfVxuXG4gIGZ1bmN0aW9uIHJlbW92ZShudW0sIG1hcCkge1xuICAgIC8vIG1hcDogaW5kZXggLT4gcmVtb3ZlXG4gICAgdmFyIG4gPSBzaXplLFxuICAgICAgICBpZHgsIGksIGo7XG5cbiAgICAvLyBzZWVrIGZvcndhcmQgdG8gZmlyc3QgcmVtb3ZhbFxuICAgIGZvciAoaT0wOyAhbWFwW2luZGV4W2ldXSAmJiBpPG47ICsraSk7XG5cbiAgICAvLyBjb25kZW5zZSBpbmRleCBhbmQgdmFsdWUgYXJyYXlzXG4gICAgZm9yIChqPWk7IGk8bjsgKytpKSB7XG4gICAgICBpZiAoIW1hcFtpZHg9aW5kZXhbaV1dKSB7XG4gICAgICAgIGluZGV4W2pdID0gaWR4O1xuICAgICAgICB2YWx1ZVtqXSA9IHZhbHVlW2ldO1xuICAgICAgICArK2o7XG4gICAgICB9XG4gICAgfVxuXG4gICAgc2l6ZSA9IG4gLSBudW07XG4gIH1cblxuICBmdW5jdGlvbiByZWluZGV4KG1hcCkge1xuICAgIGZvciAodmFyIGk9MCwgbj1zaXplOyBpPG47ICsraSkge1xuICAgICAgaW5kZXhbaV0gPSBtYXBbaW5kZXhbaV1dO1xuICAgIH1cbiAgfVxuXG4gIGZ1bmN0aW9uIGJpc2VjdChyYW5nZSwgYXJyYXkpIHtcbiAgICB2YXIgbjtcbiAgICBpZiAoYXJyYXkpIHtcbiAgICAgIG4gPSBhcnJheS5sZW5ndGg7XG4gICAgfSBlbHNlIHtcbiAgICAgIGFycmF5ID0gdmFsdWU7XG4gICAgICBuID0gc2l6ZTtcbiAgICB9XG4gICAgcmV0dXJuIFtcbiAgICAgIGJpc2VjdExlZnQoYXJyYXksIHJhbmdlWzBdLCAwLCBuKSxcbiAgICAgIGJpc2VjdFJpZ2h0KGFycmF5LCByYW5nZVsxXSwgMCwgbilcbiAgICBdO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBpbnNlcnQ6ICBpbnNlcnQsXG4gICAgcmVtb3ZlOiAgcmVtb3ZlLFxuICAgIGJpc2VjdDogIGJpc2VjdCxcbiAgICByZWluZGV4OiByZWluZGV4LFxuICAgIGluZGV4OiAgIGZ1bmN0aW9uKCkgeyByZXR1cm4gaW5kZXg7IH0sXG4gICAgc2l6ZTogICAgZnVuY3Rpb24oKSB7IHJldHVybiBzaXplOyB9XG4gIH07XG59XG5cbmZ1bmN0aW9uIHNvcnQodmFsdWVzLCBpbmRleCkge1xuICB2YWx1ZXMuc29ydC5jYWxsKGluZGV4LCBmdW5jdGlvbihhLCBiKSB7XG4gICAgdmFyIHggPSB2YWx1ZXNbYV0sXG4gICAgICAgIHkgPSB2YWx1ZXNbYl07XG4gICAgcmV0dXJuIHggPCB5ID8gLTEgOiB4ID4geSA/IDEgOiAwO1xuICB9KTtcbiAgcmV0dXJuIHBlcm11dGUodmFsdWVzLCBpbmRleCk7XG59XG5cbmZ1bmN0aW9uIG1lcmdlJDMoYmFzZSwgdmFsdWUwLCBpbmRleDAsIG4wLCB2YWx1ZTEsIGluZGV4MSwgbjEsIHZhbHVlLCBpbmRleCkge1xuICB2YXIgaTAgPSAwLCBpMSA9IDAsIGk7XG5cbiAgZm9yIChpPTA7IGkwIDwgbjAgJiYgaTEgPCBuMTsgKytpKSB7XG4gICAgaWYgKHZhbHVlMFtpMF0gPCB2YWx1ZTFbaTFdKSB7XG4gICAgICB2YWx1ZVtpXSA9IHZhbHVlMFtpMF07XG4gICAgICBpbmRleFtpXSA9IGluZGV4MFtpMCsrXTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWVbaV0gPSB2YWx1ZTFbaTFdO1xuICAgICAgaW5kZXhbaV0gPSBpbmRleDFbaTErK10gKyBiYXNlO1xuICAgIH1cbiAgfVxuXG4gIGZvciAoOyBpMCA8IG4wOyArK2kwLCArK2kpIHtcbiAgICB2YWx1ZVtpXSA9IHZhbHVlMFtpMF07XG4gICAgaW5kZXhbaV0gPSBpbmRleDBbaTBdO1xuICB9XG5cbiAgZm9yICg7IGkxIDwgbjE7ICsraTEsICsraSkge1xuICAgIHZhbHVlW2ldID0gdmFsdWUxW2kxXTtcbiAgICBpbmRleFtpXSA9IGluZGV4MVtpMV0gKyBiYXNlO1xuICB9XG59XG5cbi8qKlxuICogQW4gaW5kZXhlZCBtdWx0aS1kaW1lbnNpb25hbCBmaWx0ZXIuXG4gKiBAY29uc3RydWN0b3JcbiAqIEBwYXJhbSB7b2JqZWN0fSBwYXJhbXMgLSBUaGUgcGFyYW1ldGVycyBmb3IgdGhpcyBvcGVyYXRvci5cbiAqIEBwYXJhbSB7QXJyYXk8ZnVuY3Rpb24ob2JqZWN0KTogKj59IHBhcmFtcy5maWVsZHMgLSBBbiBhcnJheSBvZiBkaW1lbnNpb24gYWNjZXNzb3JzIHRvIGZpbHRlci5cbiAqIEBwYXJhbSB7QXJyYXl9IHBhcmFtcy5xdWVyeSAtIEFuIGFycmF5IG9mIHBlci1kaW1lbnNpb24gcmFuZ2UgcXVlcmllcy5cbiAqL1xuZnVuY3Rpb24gQ3Jvc3NGaWx0ZXIocGFyYW1zKSB7XG4gIFRyYW5zZm9ybS5jYWxsKHRoaXMsIEJpdG1hcHMoKSwgcGFyYW1zKTtcbiAgdGhpcy5faW5kaWNlcyA9IG51bGw7XG4gIHRoaXMuX2RpbXMgPSBudWxsO1xufVxuXG5Dcm9zc0ZpbHRlci5EZWZpbml0aW9uID0ge1xuICBcInR5cGVcIjogXCJDcm9zc0ZpbHRlclwiLFxuICBcIm1ldGFkYXRhXCI6IHt9LFxuICBcInBhcmFtc1wiOiBbXG4gICAgeyBcIm5hbWVcIjogXCJmaWVsZHNcIiwgXCJ0eXBlXCI6IFwiZmllbGRcIiwgXCJhcnJheVwiOiB0cnVlLCBcInJlcXVpcmVkXCI6IHRydWUgfSxcbiAgICB7IFwibmFtZVwiOiBcInF1ZXJ5XCIsIFwidHlwZVwiOiBcImFycmF5XCIsIFwiYXJyYXlcIjogdHJ1ZSwgXCJyZXF1aXJlZFwiOiB0cnVlLFxuICAgICAgXCJjb250ZW50XCI6IHtcInR5cGVcIjogXCJudW1iZXJcIiwgXCJhcnJheVwiOiB0cnVlLCBcImxlbmd0aFwiOiAyfSB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkODEgPSBpbmhlcml0cyhDcm9zc0ZpbHRlciwgVHJhbnNmb3JtKTtcblxucHJvdG90eXBlJDgxLnRyYW5zZm9ybSA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIGlmICghdGhpcy5fZGltcykge1xuICAgIHJldHVybiB0aGlzLmluaXQoXywgcHVsc2UpO1xuICB9IGVsc2Uge1xuICAgIHZhciBpbml0ID0gXy5tb2RpZmllZCgnZmllbGRzJylcbiAgICAgICAgICB8fCBfLmZpZWxkcy5zb21lKGZ1bmN0aW9uKGYpIHsgcmV0dXJuIHB1bHNlLm1vZGlmaWVkKGYuZmllbGRzKTsgfSk7XG5cbiAgICByZXR1cm4gaW5pdFxuICAgICAgPyB0aGlzLnJlaW5pdChfLCBwdWxzZSlcbiAgICAgIDogdGhpcy5ldmFsKF8sIHB1bHNlKTtcbiAgfVxufTtcblxucHJvdG90eXBlJDgxLmluaXQgPSBmdW5jdGlvbihfLCBwdWxzZSkge1xuICB2YXIgZmllbGRzID0gXy5maWVsZHMsXG4gICAgICBxdWVyeSA9IF8ucXVlcnksXG4gICAgICBpbmRpY2VzID0gdGhpcy5faW5kaWNlcyA9IHt9LFxuICAgICAgZGltcyA9IHRoaXMuX2RpbXMgPSBbXSxcbiAgICAgIG0gPSBxdWVyeS5sZW5ndGgsXG4gICAgICBpID0gMCwga2V5JCQxLCBpbmRleDtcblxuICAvLyBpbnN0YW50aWF0ZSBpbmRpY2VzIGFuZCBkaW1lbnNpb25zXG4gIGZvciAoOyBpPG07ICsraSkge1xuICAgIGtleSQkMSA9IGZpZWxkc1tpXS5mbmFtZTtcbiAgICBpbmRleCA9IGluZGljZXNba2V5JCQxXSB8fCAoaW5kaWNlc1trZXkkJDFdID0gU29ydGVkSW5kZXgoKSk7XG4gICAgZGltcy5wdXNoKERpbWVuc2lvbihpbmRleCwgaSwgcXVlcnlbaV0pKTtcbiAgfVxuXG4gIHJldHVybiB0aGlzLmV2YWwoXywgcHVsc2UpO1xufTtcblxucHJvdG90eXBlJDgxLnJlaW5pdCA9IGZ1bmN0aW9uKF8sIHB1bHNlKSB7XG4gIHZhciBvdXRwdXQgPSBwdWxzZS5tYXRlcmlhbGl6ZSgpLmZvcmsoKSxcbiAgICAgIGZpZWxkcyA9IF8uZmllbGRzLFxuICAgICAgcXVlcnkgPSBfLnF1ZXJ5LFxuICAgICAgaW5kaWNlcyA9IHRoaXMuX2luZGljZXMsXG4gICAgICBkaW1zID0gdGhpcy5fZGltcyxcbiAgICAgIGJpdHMgPSB0aGlzLnZhbHVlLFxuICAgICAgY3VyciA9IGJpdHMuY3VycigpLFxuICAgICAgcHJldiA9IGJpdHMucHJldigpLFxuICAgICAgYWxsID0gYml0cy5hbGwoKSxcbiAgICAgIG91dCA9IChvdXRwdXQucmVtID0gb3V0cHV0LmFkZCksXG4gICAgICBtb2QgPSBvdXRwdXQubW9kLFxuICAgICAgbSA9IHF1ZXJ5Lmxlbmd0aCxcbiAgICAgIGFkZHMgPSB7fSwgYWRkLCBpbmRleCwga2V5JCQxLFxuICAgICAgbW9kcywgcmVtTWFwLCBtb2RNYXAsIGksIG4sIGY7XG5cbiAgLy8gc2V0IHByZXYgdG8gY3VycmVudCBzdGF0ZVxuICBwcmV2LnNldChjdXJyKTtcblxuICAvLyBpZiBwdWxzZSBoYXMgcmVtb3ZlIHR1cGxlcywgcHJvY2VzcyB0aGVtIGZpcnN0XG4gIGlmIChwdWxzZS5yZW0ubGVuZ3RoKSB7XG4gICAgcmVtTWFwID0gdGhpcy5yZW1vdmUoXywgcHVsc2UsIG91dHB1dCk7XG4gIH1cblxuICAvLyBpZiBwdWxzZSBoYXMgYWRkZWQgdHVwbGVzLCBhZGQgdGhlbSB0byBzdGF0ZVxuICBpZiAocHVsc2UuYWRkLmxlbmd0aCkge1xuICAgIGJpdHMuYWRkKHB1bHNlLmFkZCk7XG4gIH1cblxuICAvLyBpZiBwdWxzZSBoYXMgbW9kaWZpZWQgdHVwbGVzLCBjcmVhdGUgYW4gaW5kZXggbWFwXG4gIGlmIChwdWxzZS5tb2QubGVuZ3RoKSB7XG4gICAgbW9kTWFwID0ge307XG4gICAgZm9yIChtb2RzPXB1bHNlLm1vZCwgaT0wLCBuPW1vZHMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgbW9kTWFwW21vZHNbaV0uX2luZGV4XSA9IDE7XG4gICAgfVxuICB9XG5cbiAgLy8gcmUtaW5pdGlhbGl6ZSBpbmRpY2VzIGFzIG5lZWRlZCwgdXBkYXRlIGN1cnIgYml0bWFwXG4gIGZvciAoaT0wOyBpPG07ICsraSkge1xuICAgIGYgPSBmaWVsZHNbaV07XG4gICAgaWYgKCFkaW1zW2ldIHx8IF8ubW9kaWZpZWQoJ2ZpZWxkcycsIGkpIHx8IHB1bHNlLm1vZGlmaWVkKGYuZmllbGRzKSkge1xuICAgICAga2V5JCQxID0gZi5mbmFtZTtcbiAgICAgIGlmICghKGFkZCA9IGFkZHNba2V5JCQxXSkpIHtcbiAgICAgICAgaW5kaWNlc1trZXkkJDFdID0gaW5kZXggPSBTb3J0ZWRJbmRleCgpO1xuICAgICAgICBhZGRzW2tleSQkMV0gPSBhZGQgPSBpbmRleC5pbnNlcnQoZiwgcHVsc2Uuc291cmNlLCAwKTtcbiAgICAgIH1cbiAgICAgIGRpbXNbaV0gPSBEaW1lbnNpb24oaW5kZXgsIGksIHF1ZXJ5W2ldKS5vbkFkZChhZGQsIGN1cnIpO1xuICAgIH1cbiAgfVxuXG4gIC8vIHZpc2l0IGVhY2ggdHVwbGVcbiAgLy8gaWYgZmlsdGVyIHN0YXRlIGNoYW5nZWQsIHB1c2ggaW5kZXggdG8gYWRkL3JlbVxuICAvLyBlbHNlIGlmIGluIG1vZCBhbmQgcGFzc2VzIGEgZmlsdGVyLCBwdXNoIGluZGV4IHRvIG1vZFxuICBmb3IgKGk9MCwgbj1iaXRzLmRhdGEoKS5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgaWYgKHJlbU1hcFtpXSkgeyAvLyBza2lwIGlmIHJlbW92ZWQgdHVwbGVcbiAgICAgIGNvbnRpbnVlO1xuICAgIH0gZWxzZSBpZiAocHJldltpXSAhPT0gY3VycltpXSkgeyAvLyBhZGQgaWYgc3RhdGUgY2hhbmdlZFxuICAgICAgb3V0LnB1c2goaSk7XG4gICAgfSBlbHNlIGlmIChtb2RNYXBbaV0gJiYgY3VycltpXSAhPT0gYWxsKSB7IC8vIG90aGVyd2lzZSwgcGFzcyBtb2RzIHRocm91Z2hcbiAgICAgIG1vZC5wdXNoKGkpO1xuICAgIH1cbiAgfVxuXG4gIGJpdHMubWFzayA9ICgxIDw8IG0pIC0gMTtcbiAgcmV0dXJuIG91dHB1dDtcbn07XG5cbnByb3RvdHlwZSQ4MS5ldmFsID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIG91dHB1dCA9IHB1bHNlLm1hdGVyaWFsaXplKCkuZm9yaygpLFxuICAgICAgbSA9IHRoaXMuX2RpbXMubGVuZ3RoLFxuICAgICAgbWFzayA9IDA7XG5cbiAgaWYgKHB1bHNlLnJlbS5sZW5ndGgpIHtcbiAgICB0aGlzLnJlbW92ZShfLCBwdWxzZSwgb3V0cHV0KTtcbiAgICBtYXNrIHw9ICgxIDw8IG0pIC0gMTtcbiAgfVxuXG4gIGlmIChfLm1vZGlmaWVkKCdxdWVyeScpICYmICFfLm1vZGlmaWVkKCdmaWVsZHMnKSkge1xuICAgIG1hc2sgfD0gdGhpcy51cGRhdGUoXywgcHVsc2UsIG91dHB1dCk7XG4gIH1cblxuICBpZiAocHVsc2UuYWRkLmxlbmd0aCkge1xuICAgIHRoaXMuaW5zZXJ0KF8sIHB1bHNlLCBvdXRwdXQpO1xuICAgIG1hc2sgfD0gKDEgPDwgbSkgLSAxO1xuICB9XG5cbiAgaWYgKHB1bHNlLm1vZC5sZW5ndGgpIHtcbiAgICB0aGlzLm1vZGlmeShwdWxzZSwgb3V0cHV0KTtcbiAgICBtYXNrIHw9ICgxIDw8IG0pIC0gMTtcbiAgfVxuXG4gIHRoaXMudmFsdWUubWFzayA9IG1hc2s7XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG5wcm90b3R5cGUkODEuaW5zZXJ0ID0gZnVuY3Rpb24oXywgcHVsc2UsIG91dHB1dCkge1xuICB2YXIgdHVwbGVzID0gcHVsc2UuYWRkLFxuICAgICAgYml0cyA9IHRoaXMudmFsdWUsXG4gICAgICBkaW1zID0gdGhpcy5fZGltcyxcbiAgICAgIGluZGljZXMgPSB0aGlzLl9pbmRpY2VzLFxuICAgICAgZmllbGRzID0gXy5maWVsZHMsXG4gICAgICBhZGRzID0ge30sXG4gICAgICBvdXQgPSBvdXRwdXQuYWRkLFxuICAgICAgayA9IGJpdHMuc2l6ZSgpLFxuICAgICAgbiA9IGsgKyB0dXBsZXMubGVuZ3RoLFxuICAgICAgbSA9IGRpbXMubGVuZ3RoLCBqLCBrZXkkJDEsIGFkZDtcblxuICAvLyByZXNpemUgYml0bWFwcyBhbmQgYWRkIHR1cGxlcyBhcyBuZWVkZWRcbiAgYml0cy5yZXNpemUobiwgbSk7XG4gIGJpdHMuYWRkKHR1cGxlcyk7XG5cbiAgdmFyIGN1cnIgPSBiaXRzLmN1cnIoKSxcbiAgICAgIHByZXYgPSBiaXRzLnByZXYoKSxcbiAgICAgIGFsbCAgPSBiaXRzLmFsbCgpO1xuXG4gIC8vIGFkZCB0byBkaW1lbnNpb25hbCBpbmRpY2VzXG4gIGZvciAoaj0wOyBqPG07ICsraikge1xuICAgIGtleSQkMSA9IGZpZWxkc1tqXS5mbmFtZTtcbiAgICBhZGQgPSBhZGRzW2tleSQkMV0gfHwgKGFkZHNba2V5JCQxXSA9IGluZGljZXNba2V5JCQxXS5pbnNlcnQoZmllbGRzW2pdLCB0dXBsZXMsIGspKTtcbiAgICBkaW1zW2pdLm9uQWRkKGFkZCwgY3Vycik7XG4gIH1cblxuICAvLyBzZXQgcHJldmlvdXMgZmlsdGVycywgb3V0cHV0IGlmIHBhc3NlcyBhdCBsZWFzdCBvbmUgZmlsdGVyXG4gIGZvciAoOyBrPG47ICsraykge1xuICAgIHByZXZba10gPSBhbGw7XG4gICAgaWYgKGN1cnJba10gIT09IGFsbCkgb3V0LnB1c2goayk7XG4gIH1cbn07XG5cbnByb3RvdHlwZSQ4MS5tb2RpZnkgPSBmdW5jdGlvbihwdWxzZSwgb3V0cHV0KSB7XG4gIHZhciBvdXQgPSBvdXRwdXQubW9kLFxuICAgICAgYml0cyA9IHRoaXMudmFsdWUsXG4gICAgICBjdXJyID0gYml0cy5jdXJyKCksXG4gICAgICBhbGwgID0gYml0cy5hbGwoKSxcbiAgICAgIHR1cGxlcyA9IHB1bHNlLm1vZCxcbiAgICAgIGksIG4sIGs7XG5cbiAgZm9yIChpPTAsIG49dHVwbGVzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBrID0gdHVwbGVzW2ldLl9pbmRleDtcbiAgICBpZiAoY3VycltrXSAhPT0gYWxsKSBvdXQucHVzaChrKTtcbiAgfVxufTtcblxucHJvdG90eXBlJDgxLnJlbW92ZSA9IGZ1bmN0aW9uKF8sIHB1bHNlLCBvdXRwdXQpIHtcbiAgdmFyIGluZGljZXMgPSB0aGlzLl9pbmRpY2VzLFxuICAgICAgYml0cyA9IHRoaXMudmFsdWUsXG4gICAgICBjdXJyID0gYml0cy5jdXJyKCksXG4gICAgICBwcmV2ID0gYml0cy5wcmV2KCksXG4gICAgICBhbGwgID0gYml0cy5hbGwoKSxcbiAgICAgIG1hcCA9IHt9LFxuICAgICAgb3V0ID0gb3V0cHV0LnJlbSxcbiAgICAgIHR1cGxlcyA9IHB1bHNlLnJlbSxcbiAgICAgIGksIG4sIGssIGY7XG5cbiAgLy8gcHJvY2VzcyB0dXBsZXMsIG91dHB1dCBpZiBwYXNzZXMgYXQgbGVhc3Qgb25lIGZpbHRlclxuICBmb3IgKGk9MCwgbj10dXBsZXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGsgPSB0dXBsZXNbaV0uX2luZGV4O1xuICAgIG1hcFtrXSA9IDE7IC8vIGJ1aWxkIGluZGV4IG1hcFxuICAgIHByZXZba10gPSAoZiA9IGN1cnJba10pO1xuICAgIGN1cnJba10gPSBhbGw7XG4gICAgaWYgKGYgIT09IGFsbCkgb3V0LnB1c2goayk7XG4gIH1cblxuICAvLyByZW1vdmUgZnJvbSBkaW1lbnNpb25hbCBpbmRpY2VzXG4gIGZvciAoayBpbiBpbmRpY2VzKSB7XG4gICAgaW5kaWNlc1trXS5yZW1vdmUobiwgbWFwKTtcbiAgfVxuXG4gIHRoaXMucmVpbmRleChwdWxzZSwgbiwgbWFwKTtcbiAgcmV0dXJuIG1hcDtcbn07XG5cbi8vIHJlaW5kZXggZmlsdGVycyBhbmQgaW5kaWNlcyBhZnRlciBwcm9wYWdhdGlvbiBjb21wbGV0ZXNcbnByb3RvdHlwZSQ4MS5yZWluZGV4ID0gZnVuY3Rpb24ocHVsc2UsIG51bSwgbWFwKSB7XG4gIHZhciBpbmRpY2VzID0gdGhpcy5faW5kaWNlcyxcbiAgICAgIGJpdHMgPSB0aGlzLnZhbHVlO1xuXG4gIHB1bHNlLnJ1bkFmdGVyKGZ1bmN0aW9uKCkge1xuICAgIHZhciBpbmRleE1hcCA9IGJpdHMucmVtb3ZlKG51bSwgbWFwKTtcbiAgICBmb3IgKHZhciBrZXkkJDEgaW4gaW5kaWNlcykgaW5kaWNlc1trZXkkJDFdLnJlaW5kZXgoaW5kZXhNYXApO1xuICB9KTtcbn07XG5cbnByb3RvdHlwZSQ4MS51cGRhdGUgPSBmdW5jdGlvbihfLCBwdWxzZSwgb3V0cHV0KSB7XG4gIHZhciBkaW1zID0gdGhpcy5fZGltcyxcbiAgICAgIHF1ZXJ5ID0gXy5xdWVyeSxcbiAgICAgIHN0YW1wID0gcHVsc2Uuc3RhbXAsXG4gICAgICBtID0gZGltcy5sZW5ndGgsXG4gICAgICBtYXNrID0gMCwgaSwgcTtcblxuICAvLyBzdXJ2ZXkgaG93IG1hbnkgcXVlcmllcyBoYXZlIGNoYW5nZWRcbiAgb3V0cHV0LmZpbHRlcnMgPSAwO1xuICBmb3IgKHE9MDsgcTxtOyArK3EpIHtcbiAgICBpZiAoXy5tb2RpZmllZCgncXVlcnknLCBxKSkgeyBpID0gcTsgKyttYXNrOyB9XG4gIH1cblxuICBpZiAobWFzayA9PT0gMSkge1xuICAgIC8vIG9ubHkgb25lIHF1ZXJ5IGNoYW5nZWQsIHVzZSBtb3JlIGVmZmljaWVudCB1cGRhdGVcbiAgICBtYXNrID0gZGltc1tpXS5vbmU7XG4gICAgdGhpcy5pbmNyZW1lbnRPbmUoZGltc1tpXSwgcXVlcnlbaV0sIG91dHB1dC5hZGQsIG91dHB1dC5yZW0pO1xuICB9IGVsc2Uge1xuICAgIC8vIG11bHRpcGxlIHF1ZXJpZXMgY2hhbmdlZCwgcGVyZm9ybSBmdWxsIHJlY29yZCBrZWVwaW5nXG4gICAgZm9yIChxPTAsIG1hc2s9MDsgcTxtOyArK3EpIHtcbiAgICAgIGlmICghXy5tb2RpZmllZCgncXVlcnknLCBxKSkgY29udGludWU7XG4gICAgICBtYXNrIHw9IGRpbXNbcV0ub25lO1xuICAgICAgdGhpcy5pbmNyZW1lbnRBbGwoZGltc1txXSwgcXVlcnlbcV0sIHN0YW1wLCBvdXRwdXQuYWRkKTtcbiAgICAgIG91dHB1dC5yZW0gPSBvdXRwdXQuYWRkOyAvLyBkdXBsaWNhdGUgYWRkL3JlbSBmb3IgZG93bnN0cmVhbSByZXNvbHZlXG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG1hc2s7XG59O1xuXG5wcm90b3R5cGUkODEuaW5jcmVtZW50QWxsID0gZnVuY3Rpb24oZGltLCBxdWVyeSwgc3RhbXAsIG91dCkge1xuICB2YXIgYml0cyA9IHRoaXMudmFsdWUsXG4gICAgICBzZWVuID0gYml0cy5zZWVuKCksXG4gICAgICBjdXJyID0gYml0cy5jdXJyKCksXG4gICAgICBwcmV2ID0gYml0cy5wcmV2KCksXG4gICAgICBpbmRleCA9IGRpbS5pbmRleCgpLFxuICAgICAgb2xkID0gZGltLmJpc2VjdChkaW0ucmFuZ2UpLFxuICAgICAgcmFuZ2UgPSBkaW0uYmlzZWN0KHF1ZXJ5KSxcbiAgICAgIGxvMSA9IHJhbmdlWzBdLFxuICAgICAgaGkxID0gcmFuZ2VbMV0sXG4gICAgICBsbzAgPSBvbGRbMF0sXG4gICAgICBoaTAgPSBvbGRbMV0sXG4gICAgICBvbmUkJDEgPSBkaW0ub25lLFxuICAgICAgaSwgaiwgaztcblxuICAvLyBGYXN0IGluY3JlbWVudGFsIHVwZGF0ZSBiYXNlZCBvbiBwcmV2aW91cyBsbyBpbmRleC5cbiAgaWYgKGxvMSA8IGxvMCkge1xuICAgIGZvciAoaSA9IGxvMSwgaiA9IE1hdGgubWluKGxvMCwgaGkxKTsgaSA8IGo7ICsraSkge1xuICAgICAgayA9IGluZGV4W2ldO1xuICAgICAgaWYgKHNlZW5ba10gIT09IHN0YW1wKSB7XG4gICAgICAgIHByZXZba10gPSBjdXJyW2tdO1xuICAgICAgICBzZWVuW2tdID0gc3RhbXA7XG4gICAgICAgIG91dC5wdXNoKGspO1xuICAgICAgfVxuICAgICAgY3VycltrXSBePSBvbmUkJDE7XG4gICAgfVxuICB9IGVsc2UgaWYgKGxvMSA+IGxvMCkge1xuICAgIGZvciAoaSA9IGxvMCwgaiA9IE1hdGgubWluKGxvMSwgaGkwKTsgaSA8IGo7ICsraSkge1xuICAgICAgayA9IGluZGV4W2ldO1xuICAgICAgaWYgKHNlZW5ba10gIT09IHN0YW1wKSB7XG4gICAgICAgIHByZXZba10gPSBjdXJyW2tdO1xuICAgICAgICBzZWVuW2tdID0gc3RhbXA7XG4gICAgICAgIG91dC5wdXNoKGspO1xuICAgICAgfVxuICAgICAgY3VycltrXSBePSBvbmUkJDE7XG4gICAgfVxuICB9XG5cbiAgLy8gRmFzdCBpbmNyZW1lbnRhbCB1cGRhdGUgYmFzZWQgb24gcHJldmlvdXMgaGkgaW5kZXguXG4gIGlmIChoaTEgPiBoaTApIHtcbiAgICBmb3IgKGkgPSBNYXRoLm1heChsbzEsIGhpMCksIGogPSBoaTE7IGkgPCBqOyArK2kpIHtcbiAgICAgIGsgPSBpbmRleFtpXTtcbiAgICAgIGlmIChzZWVuW2tdICE9PSBzdGFtcCkge1xuICAgICAgICBwcmV2W2tdID0gY3VycltrXTtcbiAgICAgICAgc2VlbltrXSA9IHN0YW1wO1xuICAgICAgICBvdXQucHVzaChrKTtcbiAgICAgIH1cbiAgICAgIGN1cnJba10gXj0gb25lJCQxO1xuICAgIH1cbiAgfSBlbHNlIGlmIChoaTEgPCBoaTApIHtcbiAgICBmb3IgKGkgPSBNYXRoLm1heChsbzAsIGhpMSksIGogPSBoaTA7IGkgPCBqOyArK2kpIHtcbiAgICAgIGsgPSBpbmRleFtpXTtcbiAgICAgIGlmIChzZWVuW2tdICE9PSBzdGFtcCkge1xuICAgICAgICBwcmV2W2tdID0gY3VycltrXTtcbiAgICAgICAgc2VlbltrXSA9IHN0YW1wO1xuICAgICAgICBvdXQucHVzaChrKTtcbiAgICAgIH1cbiAgICAgIGN1cnJba10gXj0gb25lJCQxO1xuICAgIH1cbiAgfVxuXG4gIGRpbS5yYW5nZSA9IHF1ZXJ5LnNsaWNlKCk7XG59O1xuXG5wcm90b3R5cGUkODEuaW5jcmVtZW50T25lID0gZnVuY3Rpb24oZGltLCBxdWVyeSwgYWRkLCByZW0pIHtcbiAgdmFyIGJpdHMgPSB0aGlzLnZhbHVlLFxuICAgICAgY3VyciA9IGJpdHMuY3VycigpLFxuICAgICAgaW5kZXggPSBkaW0uaW5kZXgoKSxcbiAgICAgIG9sZCA9IGRpbS5iaXNlY3QoZGltLnJhbmdlKSxcbiAgICAgIHJhbmdlID0gZGltLmJpc2VjdChxdWVyeSksXG4gICAgICBsbzEgPSByYW5nZVswXSxcbiAgICAgIGhpMSA9IHJhbmdlWzFdLFxuICAgICAgbG8wID0gb2xkWzBdLFxuICAgICAgaGkwID0gb2xkWzFdLFxuICAgICAgb25lJCQxID0gZGltLm9uZSxcbiAgICAgIGksIGosIGs7XG5cbiAgLy8gRmFzdCBpbmNyZW1lbnRhbCB1cGRhdGUgYmFzZWQgb24gcHJldmlvdXMgbG8gaW5kZXguXG4gIGlmIChsbzEgPCBsbzApIHtcbiAgICBmb3IgKGkgPSBsbzEsIGogPSBNYXRoLm1pbihsbzAsIGhpMSk7IGkgPCBqOyArK2kpIHtcbiAgICAgIGsgPSBpbmRleFtpXTtcbiAgICAgIGN1cnJba10gXj0gb25lJCQxO1xuICAgICAgYWRkLnB1c2goayk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGxvMSA+IGxvMCkge1xuICAgIGZvciAoaSA9IGxvMCwgaiA9IE1hdGgubWluKGxvMSwgaGkwKTsgaSA8IGo7ICsraSkge1xuICAgICAgayA9IGluZGV4W2ldO1xuICAgICAgY3VycltrXSBePSBvbmUkJDE7XG4gICAgICByZW0ucHVzaChrKTtcbiAgICB9XG4gIH1cblxuICAvLyBGYXN0IGluY3JlbWVudGFsIHVwZGF0ZSBiYXNlZCBvbiBwcmV2aW91cyBoaSBpbmRleC5cbiAgaWYgKGhpMSA+IGhpMCkge1xuICAgIGZvciAoaSA9IE1hdGgubWF4KGxvMSwgaGkwKSwgaiA9IGhpMTsgaSA8IGo7ICsraSkge1xuICAgICAgayA9IGluZGV4W2ldO1xuICAgICAgY3VycltrXSBePSBvbmUkJDE7XG4gICAgICBhZGQucHVzaChrKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAoaGkxIDwgaGkwKSB7XG4gICAgZm9yIChpID0gTWF0aC5tYXgobG8wLCBoaTEpLCBqID0gaGkwOyBpIDwgajsgKytpKSB7XG4gICAgICBrID0gaW5kZXhbaV07XG4gICAgICBjdXJyW2tdIF49IG9uZSQkMTtcbiAgICAgIHJlbS5wdXNoKGspO1xuICAgIH1cbiAgfVxuXG4gIGRpbS5yYW5nZSA9IHF1ZXJ5LnNsaWNlKCk7XG59O1xuXG4vKipcbiAqIFNlbGVjdGl2ZWx5IGZpbHRlcnMgdHVwbGVzIGJ5IHJlc29sdmluZyBhZ2FpbnN0IGEgZmlsdGVyIGJpdG1hcC5cbiAqIFVzZWZ1bCBmb3IgcHJvY2Vzc2luZyB0aGUgb3V0cHV0IG9mIGEgY3Jvc3MtZmlsdGVyIHRyYW5zZm9ybS5cbiAqIEBjb25zdHJ1Y3RvclxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcyAtIFRoZSBwYXJhbWV0ZXJzIGZvciB0aGlzIG9wZXJhdG9yLlxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtcy5pZ25vcmUgLSBBIGJpdCBtYXNrIGluZGljYXRpbmcgd2hpY2ggZmlsdGVycyB0byBpZ25vcmUuXG4gKiBAcGFyYW0ge29iamVjdH0gcGFyYW1zLmZpbHRlciAtIFRoZSBwZXItdHVwbGUgZmlsdGVyIGJpdG1hcHMuIFR5cGljYWxseSB0aGlzXG4gKiAgIHBhcmFtZXRlciB2YWx1ZSBpcyBhIHJlZmVyZW5jZSB0byBhIHtAbGluayBDcm9zc0ZpbHRlcn0gdHJhbnNmb3JtLlxuICovXG5mdW5jdGlvbiBSZXNvbHZlRmlsdGVyKHBhcmFtcykge1xuICBUcmFuc2Zvcm0uY2FsbCh0aGlzLCBudWxsLCBwYXJhbXMpO1xufVxuXG5SZXNvbHZlRmlsdGVyLkRlZmluaXRpb24gPSB7XG4gIFwidHlwZVwiOiBcIlJlc29sdmVGaWx0ZXJcIixcbiAgXCJtZXRhZGF0YVwiOiB7fSxcbiAgXCJwYXJhbXNcIjogW1xuICAgIHsgXCJuYW1lXCI6IFwiaWdub3JlXCIsIFwidHlwZVwiOiBcIm51bWJlclwiLCBcInJlcXVpcmVkXCI6IHRydWUsXG4gICAgICBcImRlc2NyaXB0aW9uXCI6IFwiQSBiaXQgbWFzayBpbmRpY2F0aW5nIHdoaWNoIGZpbHRlcnMgdG8gaWdub3JlLlwiIH0sXG4gICAgeyBcIm5hbWVcIjogXCJmaWx0ZXJcIiwgXCJ0eXBlXCI6IFwib2JqZWN0XCIsIFwicmVxdWlyZWRcIjogdHJ1ZSxcbiAgICAgIFwiZGVzY3JpcHRpb25cIjogXCJQZXItdHVwbGUgZmlsdGVyIGJpdG1hcHMgZnJvbSBhIENyb3NzRmlsdGVyIHRyYW5zZm9ybS5cIiB9XG4gIF1cbn07XG5cbnZhciBwcm90b3R5cGUkODIgPSBpbmhlcml0cyhSZXNvbHZlRmlsdGVyLCBUcmFuc2Zvcm0pO1xuXG5wcm90b3R5cGUkODIudHJhbnNmb3JtID0gZnVuY3Rpb24oXywgcHVsc2UpIHtcbiAgdmFyIGlnbm9yZSA9IH4oXy5pZ25vcmUgfHwgMCksIC8vIGJpdCBtYXNrIHdoZXJlIHplcm9zIC0+IGRpbXMgdG8gaWdub3JlXG4gICAgICBiaXRtYXAgPSBfLmZpbHRlcixcbiAgICAgIG1hc2sgPSBiaXRtYXAubWFzaztcblxuICAvLyBleGl0IGVhcmx5IGlmIG5vIHJlbGV2YW50IGZpbHRlciBjaGFuZ2VzXG4gIGlmICgobWFzayAmIGlnbm9yZSkgPT09IDApIHJldHVybiBwdWxzZS5TdG9wUHJvcGFnYXRpb247XG5cbiAgdmFyIG91dHB1dCA9IHB1bHNlLmZvcmsocHVsc2UuQUxMKSxcbiAgICAgIGRhdGEgPSBiaXRtYXAuZGF0YSgpLFxuICAgICAgY3VyciA9IGJpdG1hcC5jdXJyKCksXG4gICAgICBwcmV2ID0gYml0bWFwLnByZXYoKSxcbiAgICAgIHBhc3MgPSBmdW5jdGlvbihrKSB7XG4gICAgICAgIHJldHVybiAhKGN1cnJba10gJiBpZ25vcmUpID8gZGF0YVtrXSA6IG51bGw7XG4gICAgICB9O1xuXG4gIC8vIHByb3BhZ2F0ZSBhbGwgbW9kIHR1cGxlcyB0aGF0IHBhc3MgdGhlIGZpbHRlclxuICBvdXRwdXQuZmlsdGVyKG91dHB1dC5NT0QsIHBhc3MpO1xuXG4gIC8vIGRldGVybWluZSBhZGQgJiByZW0gdHVwbGVzIHZpYSBmaWx0ZXIgZnVuY3Rpb25zXG4gIC8vIGZvciBlZmZpY2llbmN5LCB3ZSBkbyAqbm90KiBwb3B1bGF0ZSBuZXcgYXJyYXlzLFxuICAvLyBpbnN0ZWFkIHdlIGFkZCBmaWx0ZXIgZnVuY3Rpb25zIGFwcGxpZWQgZG93bnN0cmVhbVxuXG4gIGlmICghKG1hc2sgJiAobWFzay0xKSkpIHsgLy8gb25seSBvbmUgZmlsdGVyIGNoYW5nZWRcbiAgICBvdXRwdXQuZmlsdGVyKG91dHB1dC5BREQsIHBhc3MpO1xuICAgIG91dHB1dC5maWx0ZXIob3V0cHV0LlJFTSwgZnVuY3Rpb24oaykge1xuICAgICAgcmV0dXJuIChjdXJyW2tdICYgaWdub3JlKSA9PT0gbWFzayA/IGRhdGFba10gOiBudWxsO1xuICAgIH0pO1xuXG4gIH0gZWxzZSB7IC8vIG11bHRpcGxlIGZpbHRlcnMgY2hhbmdlZFxuICAgIG91dHB1dC5maWx0ZXIob3V0cHV0LkFERCwgZnVuY3Rpb24oaykge1xuICAgICAgdmFyIGMgPSBjdXJyW2tdICYgaWdub3JlLFxuICAgICAgICAgIGYgPSAhYyAmJiAoYyBeIChwcmV2W2tdICYgaWdub3JlKSk7XG4gICAgICByZXR1cm4gZiA/IGRhdGFba10gOiBudWxsO1xuICAgIH0pO1xuICAgIG91dHB1dC5maWx0ZXIob3V0cHV0LlJFTSwgZnVuY3Rpb24oaykge1xuICAgICAgdmFyIGMgPSBjdXJyW2tdICYgaWdub3JlLFxuICAgICAgICAgIGYgPSBjICYmICEoYyBeIChjIF4gKHByZXZba10gJiBpZ25vcmUpKSk7XG4gICAgICByZXR1cm4gZiA/IGRhdGFba10gOiBudWxsO1xuICAgIH0pO1xuICB9XG5cbiAgLy8gYWRkIGZpbHRlciB0byBzb3VyY2UgZGF0YSBpbiBjYXNlIG9mIHJlZmxvdy4uLlxuICByZXR1cm4gb3V0cHV0LmZpbHRlcihvdXRwdXQuU09VUkNFLCBmdW5jdGlvbih0KSB7IHJldHVybiBwYXNzKHQuX2luZGV4KTsgfSk7XG59O1xuXG5cblxudmFyIHhmID0gT2JqZWN0LmZyZWV6ZSh7XG5cdGNyb3NzZmlsdGVyOiBDcm9zc0ZpbHRlcixcblx0cmVzb2x2ZWZpbHRlcjogUmVzb2x2ZUZpbHRlclxufSk7XG5cbnZhciB2ZXJzaW9uID0gXCIzLjIuMFwiO1xuXG52YXIgRGVmYXVsdCA9ICdkZWZhdWx0JztcblxudmFyIGN1cnNvciA9IGZ1bmN0aW9uKHZpZXcpIHtcbiAgdmFyIGN1cnNvciA9IHZpZXcuX3NpZ25hbHMuY3Vyc29yO1xuXG4gIC8vIGFkZCBjdXJzb3Igc2lnbmFsIHRvIGRhdGFmbG93LCBpZiBuZWVkZWRcbiAgaWYgKCFjdXJzb3IpIHtcbiAgICB2aWV3Ll9zaWduYWxzLmN1cnNvciA9IChjdXJzb3IgPSB2aWV3LmFkZCh7dXNlcjogRGVmYXVsdCwgaXRlbTogbnVsbH0pKTtcbiAgfVxuXG4gIC8vIGV2YWx1YXRlIGN1cnNvciBvbiBlYWNoIG1vdXNlbW92ZSBldmVudFxuICB2aWV3Lm9uKHZpZXcuZXZlbnRzKCd2aWV3JywgJ21vdXNlbW92ZScpLCBjdXJzb3IsXG4gICAgZnVuY3Rpb24oXywgZXZlbnQpIHtcbiAgICAgIHZhciB2YWx1ZSA9IGN1cnNvci52YWx1ZSxcbiAgICAgICAgICB1c2VyID0gdmFsdWUgPyAoaXNTdHJpbmcodmFsdWUpID8gdmFsdWUgOiB2YWx1ZS51c2VyKSA6IERlZmF1bHQsXG4gICAgICAgICAgaXRlbSA9IGV2ZW50Lml0ZW0gJiYgZXZlbnQuaXRlbS5jdXJzb3IgfHwgbnVsbDtcblxuICAgICAgcmV0dXJuICh2YWx1ZSAmJiB1c2VyID09PSB2YWx1ZS51c2VyICYmIGl0ZW0gPT0gdmFsdWUuaXRlbSkgPyB2YWx1ZVxuICAgICAgICA6IHt1c2VyOiB1c2VyLCBpdGVtOiBpdGVtfTtcbiAgICB9XG4gICk7XG5cbiAgLy8gd2hlbiBjdXJzb3Igc2lnbmFsIHVwZGF0ZXMsIHNldCB2aXNpYmxlIGN1cnNvclxuICB2aWV3LmFkZChudWxsLCBmdW5jdGlvbihfKSB7XG4gICAgdmFyIHVzZXIgPSBfLmN1cnNvcixcbiAgICAgICAgaXRlbSA9IHRoaXMudmFsdWU7XG5cbiAgICBpZiAoIWlzU3RyaW5nKHVzZXIpKSB7XG4gICAgICBpdGVtID0gdXNlci5pdGVtO1xuICAgICAgdXNlciA9IHVzZXIudXNlcjtcbiAgICB9XG5cbiAgICBzZXRDdXJzb3IodXNlciAmJiB1c2VyICE9PSBEZWZhdWx0ID8gdXNlciA6IChpdGVtIHx8IHVzZXIpKTtcblxuICAgIHJldHVybiBpdGVtO1xuICB9LCB7Y3Vyc29yOiBjdXJzb3J9KTtcbn07XG5cbmZ1bmN0aW9uIHNldEN1cnNvcihjdXJzb3IpIHtcbiAgLy8gc2V0IGN1cnNvciBvbiBkb2N1bWVudCBib2R5XG4gIC8vIHRoaXMgZW5zdXJlcyBjdXJzb3IgYXBwbGllcyBldmVuIGlmIGRyYWdnaW5nIG91dCBvZiB2aWV3XG4gIGlmICh0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGRvY3VtZW50LmJvZHkpIHtcbiAgICBkb2N1bWVudC5ib2R5LnN0eWxlLmN1cnNvciA9IGN1cnNvcjtcbiAgfVxufVxuXG5mdW5jdGlvbiBkYXRhcmVmKHZpZXcsIG5hbWUpIHtcbiAgdmFyIGRhdGEgPSB2aWV3Ll9ydW50aW1lLmRhdGE7XG4gIGlmICghZGF0YS5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgIGVycm9yJDEoJ1VucmVjb2duaXplZCBkYXRhIHNldDogJyArIG5hbWUpO1xuICB9XG4gIHJldHVybiBkYXRhW25hbWVdO1xufVxuXG5mdW5jdGlvbiBkYXRhKG5hbWUpIHtcbiAgcmV0dXJuIGRhdGFyZWYodGhpcywgbmFtZSkudmFsdWVzLnZhbHVlO1xufVxuXG5mdW5jdGlvbiBjaGFuZ2UobmFtZSwgY2hhbmdlcykge1xuICBpZiAoIWlzQ2hhbmdlU2V0KGNoYW5nZXMpKSB7XG4gICAgZXJyb3IkMSgnU2Vjb25kIGFyZ3VtZW50IHRvIGNoYW5nZXMgbXVzdCBiZSBhIGNoYW5nZXNldC4nKTtcbiAgfVxuICB2YXIgZGF0YXNldCA9IGRhdGFyZWYodGhpcywgbmFtZSk7XG4gIGRhdGFzZXQubW9kaWZpZWQgPSB0cnVlO1xuICByZXR1cm4gdGhpcy5wdWxzZShkYXRhc2V0LmlucHV0LCBjaGFuZ2VzKTtcbn1cblxuZnVuY3Rpb24gaW5zZXJ0KG5hbWUsIF8pIHtcbiAgcmV0dXJuIGNoYW5nZS5jYWxsKHRoaXMsIG5hbWUsIGNoYW5nZXNldCgpLmluc2VydChfKSk7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZShuYW1lLCBfKSB7XG4gIHJldHVybiBjaGFuZ2UuY2FsbCh0aGlzLCBuYW1lLCBjaGFuZ2VzZXQoKS5yZW1vdmUoXykpO1xufVxuXG5mdW5jdGlvbiB3aWR0aCh2aWV3KSB7XG4gIHZhciBwYWRkaW5nID0gdmlldy5wYWRkaW5nKCk7XG4gIHJldHVybiBNYXRoLm1heCgwLCB2aWV3Ll92aWV3V2lkdGggKyBwYWRkaW5nLmxlZnQgKyBwYWRkaW5nLnJpZ2h0KTtcbn1cblxuZnVuY3Rpb24gaGVpZ2h0JDEodmlldykge1xuICB2YXIgcGFkZGluZyA9IHZpZXcucGFkZGluZygpO1xuICByZXR1cm4gTWF0aC5tYXgoMCwgdmlldy5fdmlld0hlaWdodCArIHBhZGRpbmcudG9wICsgcGFkZGluZy5ib3R0b20pO1xufVxuXG5mdW5jdGlvbiBvZmZzZXQkMSh2aWV3KSB7XG4gIHZhciBwYWRkaW5nID0gdmlldy5wYWRkaW5nKCksXG4gICAgICBvcmlnaW4gPSB2aWV3Ll9vcmlnaW47XG4gIHJldHVybiBbXG4gICAgcGFkZGluZy5sZWZ0ICsgb3JpZ2luWzBdLFxuICAgIHBhZGRpbmcudG9wICsgb3JpZ2luWzFdXG4gIF07XG59XG5cbmZ1bmN0aW9uIHJlc2l6ZVJlbmRlcmVyKHZpZXcpIHtcbiAgdmFyIG9yaWdpbiA9IG9mZnNldCQxKHZpZXcpLFxuICAgICAgdyA9IHdpZHRoKHZpZXcpLFxuICAgICAgaCA9IGhlaWdodCQxKHZpZXcpO1xuXG4gIHZpZXcuX3JlbmRlcmVyLmJhY2tncm91bmQodmlldy5fYmFja2dyb3VuZCk7XG4gIHZpZXcuX3JlbmRlcmVyLnJlc2l6ZSh3LCBoLCBvcmlnaW4pO1xuICB2aWV3Ll9oYW5kbGVyLm9yaWdpbihvcmlnaW4pO1xuXG4gIHZpZXcuX3Jlc2l6ZUxpc3RlbmVycy5mb3JFYWNoKGZ1bmN0aW9uKGhhbmRsZXIpIHtcbiAgICBoYW5kbGVyKHcsIGgpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBFeHRlbmQgYW4gZXZlbnQgd2l0aCBhZGRpdGlvbmFsIHZpZXctc3BlY2lmaWMgbWV0aG9kcy5cbiAqIEFkZHMgYSBuZXcgcHJvcGVydHkgKCd2ZWdhJykgdG8gYW4gZXZlbnQgdGhhdCBwcm92aWRlcyBhIG51bWJlclxuICogb2YgbWV0aG9kcyBmb3IgcXVlcnlpbmcgaW5mb3JtYXRpb24gYWJvdXQgdGhlIGN1cnJlbnQgaW50ZXJhY3Rpb24uXG4gKiBUaGUgdmVnYSBvYmplY3QgcHJvdmlkZXMgdGhlIGZvbGxvd2luZyBtZXRob2RzOlxuICogICB2aWV3IC0gUmV0dXJucyB0aGUgYmFja2luZyBWaWV3IGluc3RhbmNlLlxuICogICBpdGVtIC0gUmV0dXJucyB0aGUgY3VycmVudGx5IGFjdGl2ZSBzY2VuZWdyYXBoIGl0ZW0gKGlmIGFueSkuXG4gKiAgIGdyb3VwIC0gUmV0dXJucyB0aGUgY3VycmVudGx5IGFjdGl2ZSBzY2VuZWdyYXBoIGdyb3VwIChpZiBhbnkpLlxuICogICAgIFRoaXMgbWV0aG9kIGFjY2VwdHMgYSBzaW5nbGUgc3RyaW5nLXR5cGVkIGFyZ3VtZW50IGluZGljYXRpbmcgdGhlIG5hbWVcbiAqICAgICBvZiB0aGUgZGVzaXJlZCBwYXJlbnQgZ3JvdXAuIFRoZSBzY2VuZWdyYXBoIHdpbGwgYmUgdHJhdmVyc2VkIGZyb21cbiAqICAgICB0aGUgaXRlbSB1cCB0b3dhcmRzIHRoZSByb290IHRvIHNlYXJjaCBmb3IgYSBtYXRjaGluZyBncm91cC4gSWYgbm9cbiAqICAgICBhcmd1bWVudCBpcyBwcm92aWRlZCB0aGUgZW5jbG9zaW5nIGdyb3VwIGZvciB0aGUgYWN0aXZlIGl0ZW0gaXNcbiAqICAgICByZXR1cm5lZCwgdW5sZXNzIHRoZSBpdGVtIGl0IGl0c2VsZiBhIGdyb3VwLCBpbiB3aGljaCBjYXNlIGl0IGlzXG4gKiAgICAgcmV0dXJuZWQgZGlyZWN0bHkuXG4gKiAgIHh5IC0gUmV0dXJucyBhIHR3by1lbGVtZW50IGFycmF5IGNvbnRhaW5pbmcgdGhlIHggYW5kIHkgY29vcmRpbmF0ZXMgZm9yXG4gKiAgICAgbW91c2Ugb3IgdG91Y2ggZXZlbnRzLiBGb3IgdG91Y2ggZXZlbnRzLCB0aGlzIGlzIGJhc2VkIG9uIHRoZSBmaXJzdFxuICogICAgIGVsZW1lbnRzIGluIHRoZSBjaGFuZ2VkVG91Y2hlcyBhcnJheS4gVGhpcyBtZXRob2QgYWNjZXB0cyBhIHNpbmdsZVxuICogICAgIGFyZ3VtZW50OiBlaXRoZXIgYW4gaXRlbSBpbnN0YW5jZSBvciBtYXJrIG5hbWUgdGhhdCBzaG91bGQgc2VydmUgYXNcbiAqICAgICB0aGUgcmVmZXJlbmNlIGNvb3JkaW5hdGUgc3lzdGVtLiBJZiBubyBhcmd1bWVudCBpcyBwcm92aWRlZCB0aGVcbiAqICAgICB0b3AtbGV2ZWwgdmlldyBjb29yZGluYXRlIHN5c3RlbSBpcyBhc3N1bWVkLlxuICogICB4IC0gUmV0dXJucyB0aGUgY3VycmVudCB4LWNvb3JkaW5hdGUsIGFjY2VwdHMgdGhlIHNhbWUgYXJndW1lbnRzIGFzIHh5LlxuICogICB5IC0gUmV0dXJucyB0aGUgY3VycmVudCB5LWNvb3JkaW5hdGUsIGFjY2VwdHMgdGhlIHNhbWUgYXJndW1lbnRzIGFzIHh5LlxuICogQHBhcmFtIHtFdmVudH0gZXZlbnQgLSBUaGUgaW5wdXQgZXZlbnQgdG8gZXh0ZW5kLlxuICogQHBhcmFtIHtJdGVtfSBpdGVtIC0gVGhlIGN1cnJlbnRseSBhY3RpdmUgc2NlbmVncmFwaCBpdGVtIChpZiBhbnkpLlxuICogQHJldHVybiB7RXZlbnR9IC0gVGhlIGV4dGVuZGVkIGlucHV0IGV2ZW50LlxuICovXG52YXIgZXZlbnRFeHRlbmQgPSBmdW5jdGlvbih2aWV3LCBldmVudCwgaXRlbSkge1xuICB2YXIgZWwgPSB2aWV3Ll9yZW5kZXJlci5zY2VuZSgpLFxuICAgICAgcCwgZSwgdHJhbnNsYXRlO1xuXG4gIGlmIChlbCkge1xuICAgIHRyYW5zbGF0ZSA9IG9mZnNldCQxKHZpZXcpO1xuICAgIGUgPSBldmVudC5jaGFuZ2VkVG91Y2hlcyA/IGV2ZW50LmNoYW5nZWRUb3VjaGVzWzBdIDogZXZlbnQ7XG4gICAgcCA9IHBvaW50JDQoZSwgZWwpO1xuICAgIHBbMF0gLT0gdHJhbnNsYXRlWzBdO1xuICAgIHBbMV0gLT0gdHJhbnNsYXRlWzFdO1xuICB9XG5cbiAgZXZlbnQuZGF0YWZsb3cgPSB2aWV3O1xuICBldmVudC52ZWdhID0gZXh0ZW5zaW9uKHZpZXcsIGl0ZW0sIHApO1xuICBldmVudC5pdGVtID0gaXRlbTtcbiAgcmV0dXJuIGV2ZW50O1xufTtcblxuZnVuY3Rpb24gZXh0ZW5zaW9uKHZpZXcsIGl0ZW0sIHBvaW50KSB7XG4gIHZhciBpdGVtR3JvdXAgPSBpdGVtXG4gICAgPyBpdGVtLm1hcmsubWFya3R5cGUgPT09ICdncm91cCcgPyBpdGVtIDogaXRlbS5tYXJrLmdyb3VwXG4gICAgOiBudWxsO1xuXG4gIGZ1bmN0aW9uIGdyb3VwKG5hbWUpIHtcbiAgICB2YXIgZyA9IGl0ZW1Hcm91cCwgaTtcbiAgICBpZiAobmFtZSkgZm9yIChpID0gaXRlbTsgaTsgaSA9IGkubWFyay5ncm91cCkge1xuICAgICAgaWYgKGkubWFyay5uYW1lID09PSBuYW1lKSB7IGcgPSBpOyBicmVhazsgfVxuICAgIH1cbiAgICByZXR1cm4gZyAmJiBnLm1hcmsgJiYgZy5tYXJrLmludGVyYWN0aXZlID8gZyA6IHt9O1xuICB9XG5cbiAgZnVuY3Rpb24geHkoaXRlbSkge1xuICAgIGlmICghaXRlbSkgcmV0dXJuIHBvaW50O1xuICAgIGlmIChpc1N0cmluZyhpdGVtKSkgaXRlbSA9IGdyb3VwKGl0ZW0pO1xuXG4gICAgdmFyIHAgPSBwb2ludC5zbGljZSgpO1xuICAgIHdoaWxlIChpdGVtKSB7XG4gICAgICBwWzBdIC09IGl0ZW0ueCB8fCAwO1xuICAgICAgcFsxXSAtPSBpdGVtLnkgfHwgMDtcbiAgICAgIGl0ZW0gPSBpdGVtLm1hcmsgJiYgaXRlbS5tYXJrLmdyb3VwO1xuICAgIH1cbiAgICByZXR1cm4gcDtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdmlldzogIGNvbnN0YW50KHZpZXcpLFxuICAgIGl0ZW06ICBjb25zdGFudChpdGVtIHx8IHt9KSxcbiAgICBncm91cDogZ3JvdXAsXG4gICAgeHk6ICAgIHh5LFxuICAgIHg6ICAgICBmdW5jdGlvbihpdGVtKSB7IHJldHVybiB4eShpdGVtKVswXTsgfSxcbiAgICB5OiAgICAgZnVuY3Rpb24oaXRlbSkgeyByZXR1cm4geHkoaXRlbSlbMV07IH1cbiAgfTtcbn1cblxudmFyIFZJRVcgPSAndmlldyc7XG52YXIgV0lORE9XID0gJ3dpbmRvdyc7XG5cbi8qKlxuICogSW5pdGlhbGl6ZSBldmVudCBoYW5kbGluZyBjb25maWd1cmF0aW9uLlxuICogQHBhcmFtIHtvYmplY3R9IGNvbmZpZyAtIFRoZSBjb25maWd1cmF0aW9uIHNldHRpbmdzLlxuICogQHJldHVybiB7b2JqZWN0fVxuICovXG5mdW5jdGlvbiBpbml0aWFsaXplRXZlbnRDb25maWcoY29uZmlnKSB7XG4gIGNvbmZpZyA9IGV4dGVuZCh7fSwgY29uZmlnKTtcblxuICB2YXIgZGVmID0gY29uZmlnLmRlZmF1bHRzO1xuICBpZiAoZGVmKSB7XG4gICAgaWYgKGlzQXJyYXkoZGVmLnByZXZlbnQpKSB7XG4gICAgICBkZWYucHJldmVudCA9IHRvU2V0KGRlZi5wcmV2ZW50KTtcbiAgICB9XG4gICAgaWYgKGlzQXJyYXkoZGVmLmFsbG93KSkge1xuICAgICAgZGVmLmFsbG93ID0gdG9TZXQoZGVmLmFsbG93KTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gY29uZmlnO1xufVxuXG5mdW5jdGlvbiBwcmV2ZW50KHZpZXcsIHR5cGUpIHtcbiAgdmFyIGRlZiA9IHZpZXcuX2V2ZW50Q29uZmlnLmRlZmF1bHRzLFxuICAgICAgcHJldmVudCA9IGRlZiAmJiBkZWYucHJldmVudCxcbiAgICAgIGFsbG93ID0gZGVmICYmIGRlZi5hbGxvdztcblxuICByZXR1cm4gcHJldmVudCA9PT0gZmFsc2UgfHwgYWxsb3cgPT09IHRydWUgPyBmYWxzZVxuICAgIDogcHJldmVudCA9PT0gdHJ1ZSB8fCBhbGxvdyA9PT0gZmFsc2UgPyB0cnVlXG4gICAgOiBwcmV2ZW50ID8gcHJldmVudFt0eXBlXVxuICAgIDogYWxsb3cgPyAhYWxsb3dbdHlwZV1cbiAgICA6IHZpZXcucHJldmVudERlZmF1bHQoKTtcbn1cblxuLyoqXG4gKiBDcmVhdGUgYSBuZXcgZXZlbnQgc3RyZWFtIGZyb20gYW4gZXZlbnQgc291cmNlLlxuICogQHBhcmFtIHtvYmplY3R9IHNvdXJjZSAtIFRoZSBldmVudCBzb3VyY2UgdG8gbW9uaXRvci5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIGV2ZW50IHR5cGUuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCk6IGJvb2xlYW59IFtmaWx0ZXJdIC0gRXZlbnQgZmlsdGVyIGZ1bmN0aW9uLlxuICogQHJldHVybiB7RXZlbnRTdHJlYW19XG4gKi9cbmZ1bmN0aW9uIGV2ZW50cyQxKHNvdXJjZSwgdHlwZSwgZmlsdGVyKSB7XG4gIHZhciB2aWV3ID0gdGhpcyxcbiAgICAgIHMgPSBuZXcgRXZlbnRTdHJlYW0oZmlsdGVyKSxcbiAgICAgIHNlbmQgPSBmdW5jdGlvbihlLCBpdGVtKSB7XG4gICAgICAgIGlmIChzb3VyY2UgPT09IFZJRVcgJiYgcHJldmVudCh2aWV3LCB0eXBlKSkge1xuICAgICAgICAgIGUucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgfVxuICAgICAgICB0cnkge1xuICAgICAgICAgIHMucmVjZWl2ZShldmVudEV4dGVuZCh2aWV3LCBlLCBpdGVtKSk7XG4gICAgICAgIH0gY2F0Y2ggKGVycm9yKSB7XG4gICAgICAgICAgdmlldy5lcnJvcihlcnJvcik7XG4gICAgICAgIH0gZmluYWxseSB7XG4gICAgICAgICAgdmlldy5ydW4oKTtcbiAgICAgICAgfVxuICAgICAgfSxcbiAgICAgIHNvdXJjZXM7XG5cbiAgaWYgKHNvdXJjZSA9PT0gVklFVykge1xuICAgIHZpZXcuYWRkRXZlbnRMaXN0ZW5lcih0eXBlLCBzZW5kKTtcbiAgICByZXR1cm4gcztcbiAgfVxuXG4gIGlmIChzb3VyY2UgPT09IFdJTkRPVykge1xuICAgIGlmICh0eXBlb2Ygd2luZG93ICE9PSAndW5kZWZpbmVkJykgc291cmNlcyA9IFt3aW5kb3ddO1xuICB9IGVsc2UgaWYgKHR5cGVvZiBkb2N1bWVudCAhPT0gJ3VuZGVmaW5lZCcpIHtcbiAgICBzb3VyY2VzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChzb3VyY2UpO1xuICB9XG5cbiAgaWYgKCFzb3VyY2VzKSB7XG4gICAgdmlldy53YXJuKCdDYW4gbm90IHJlc29sdmUgZXZlbnQgc291cmNlOiAnICsgc291cmNlKTtcbiAgICByZXR1cm4gcztcbiAgfVxuXG4gIGZvciAodmFyIGk9MCwgbj1zb3VyY2VzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBzb3VyY2VzW2ldLmFkZEV2ZW50TGlzdGVuZXIodHlwZSwgc2VuZCk7XG4gIH1cblxuICB2aWV3Ll9ldmVudExpc3RlbmVycy5wdXNoKHtcbiAgICB0eXBlOiAgICB0eXBlLFxuICAgIHNvdXJjZXM6IHNvdXJjZXMsXG4gICAgaGFuZGxlcjogc2VuZFxuICB9KTtcblxuICByZXR1cm4gcztcbn1cblxuZnVuY3Rpb24gaXRlbUZpbHRlcihldmVudCkge1xuICByZXR1cm4gZXZlbnQuaXRlbTtcbn1cblxuZnVuY3Rpb24gbWFya1RhcmdldChldmVudCkge1xuICAvLyBncmFiIHVwc3RyZWFtIGNvbGxlY3RvciBmZWVkaW5nIHRoZSBtYXJrIG9wZXJhdG9yXG4gIHZhciBzb3VyY2UgPSBldmVudC5pdGVtLm1hcmsuc291cmNlO1xuICByZXR1cm4gc291cmNlLnNvdXJjZSB8fCBzb3VyY2U7XG59XG5cbmZ1bmN0aW9uIGludm9rZShuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbihfLCBldmVudCkge1xuICAgIHJldHVybiBldmVudC52ZWdhLnZpZXcoKVxuICAgICAgLmNoYW5nZXNldCgpXG4gICAgICAuZW5jb2RlKGV2ZW50Lml0ZW0sIG5hbWUpO1xuICB9O1xufVxuXG52YXIgaG92ZXIgPSBmdW5jdGlvbihob3ZlclNldCwgbGVhdmVTZXQpIHtcbiAgaG92ZXJTZXQgPSBbaG92ZXJTZXQgfHwgJ2hvdmVyJ107XG4gIGxlYXZlU2V0ID0gW2xlYXZlU2V0IHx8ICd1cGRhdGUnLCBob3ZlclNldF07XG5cbiAgLy8gaW52b2tlIGhvdmVyIHNldCB1cG9uIG1vdXNlb3ZlclxuICB0aGlzLm9uKFxuICAgIHRoaXMuZXZlbnRzKCd2aWV3JywgJ21vdXNlb3ZlcicsIGl0ZW1GaWx0ZXIpLFxuICAgIG1hcmtUYXJnZXQsXG4gICAgaW52b2tlKGhvdmVyU2V0KVxuICApO1xuXG4gIC8vIGludm9rZSBsZWF2ZSBzZXQgdXBvbiBtb3VzZW91dFxuICB0aGlzLm9uKFxuICAgIHRoaXMuZXZlbnRzKCd2aWV3JywgJ21vdXNlb3V0JywgaXRlbUZpbHRlciksXG4gICAgbWFya1RhcmdldCxcbiAgICBpbnZva2UobGVhdmVTZXQpXG4gICk7XG5cbiAgcmV0dXJuIHRoaXM7XG59O1xuXG4vKipcbiAqIFJlbW92ZSBhbGwgZXh0ZXJuYWwgZXZlbnQgbGlzdGVuZXJzLlxuICovXG52YXIgZmluYWxpemUgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGxpc3RlbmVycyA9IHRoaXMuX2V2ZW50TGlzdGVuZXJzLFxuICAgICAgbiA9IGxpc3RlbmVycy5sZW5ndGgsIG0sIGU7XG5cbiAgd2hpbGUgKC0tbiA+PSAwKSB7XG4gICAgZSA9IGxpc3RlbmVyc1tuXTtcbiAgICBtID0gZS5zb3VyY2VzLmxlbmd0aDtcbiAgICB3aGlsZSAoLS1tID49IDApIHtcbiAgICAgIGUuc291cmNlc1ttXS5yZW1vdmVFdmVudExpc3RlbmVyKGUudHlwZSwgZS5oYW5kbGVyKTtcbiAgICB9XG4gIH1cbn07XG5cbnZhciBlbGVtZW50JDEgPSBmdW5jdGlvbih0YWcsIGF0dHIsIHRleHQpIHtcbiAgdmFyIGVsID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuICBmb3IgKHZhciBrZXkgaW4gYXR0cikgZWwuc2V0QXR0cmlidXRlKGtleSwgYXR0cltrZXldKTtcbiAgaWYgKHRleHQgIT0gbnVsbCkgZWwudGV4dENvbnRlbnQgPSB0ZXh0O1xuICByZXR1cm4gZWw7XG59O1xuXG52YXIgQmluZENsYXNzID0gJ3ZlZ2EtYmluZCc7XG52YXIgTmFtZUNsYXNzID0gJ3ZlZ2EtYmluZC1uYW1lJztcbnZhciBSYWRpb0NsYXNzID0gJ3ZlZ2EtYmluZC1yYWRpbyc7XG52YXIgT3B0aW9uQ2xhc3MgPSAndmVnYS1vcHRpb24tJztcblxuLyoqXG4gKiBCaW5kIGEgc2lnbmFsIHRvIGFuIGV4dGVybmFsIEhUTUwgaW5wdXQgZWxlbWVudC4gVGhlIHJlc3VsdGluZyB0d28td2F5XG4gKiBiaW5kaW5nIHdpbGwgcHJvcGFnYXRlIGlucHV0IGNoYW5nZXMgdG8gc2lnbmFscywgYW5kIHByb3BhZ2F0ZSBzaWduYWxcbiAqIGNoYW5nZXMgdG8gdGhlIGlucHV0IGVsZW1lbnQgc3RhdGUuIElmIHRoaXMgdmlldyBpbnN0YW5jZSBoYXMgbm8gcGFyZW50XG4gKiBlbGVtZW50LCB3ZSBhc3N1bWUgdGhlIHZpZXcgaXMgaGVhZGxlc3MgYW5kIG5vIGJpbmRpbmdzIGFyZSBjcmVhdGVkLlxuICogQHBhcmFtIHtFbGVtZW50fHN0cmluZ30gZWwgLSBUaGUgcGFyZW50IERPTSBlbGVtZW50IHRvIHdoaWNoIHRoZSBpbnB1dFxuICogICBlbGVtZW50IHNob3VsZCBiZSBhcHBlbmRlZCBhcyBhIGNoaWxkLiBJZiBzdHJpbmctdmFsdWVkLCB0aGlzIGFyZ3VtZW50XG4gKiAgIHdpbGwgYmUgdHJlYXRlZCBhcyBhIENTUyBzZWxlY3Rvci4gSWYgbnVsbCBvciB1bmRlZmluZWQsIHRoZSBwYXJlbnRcbiAqICAgZWxlbWVudCBvZiB0aGlzIHZpZXcgd2lsbCBiZSB1c2VkIGFzIHRoZSBlbGVtZW50LlxuICogQHBhcmFtIHtvYmplY3R9IHBhcmFtIC0gVGhlIGJpbmRpbmcgcGFyYW1ldGVycyB3aGljaCBzcGVjaWZ5IHRoZSBzaWduYWxcbiAqICAgdG8gYmluZCB0bywgdGhlIGlucHV0IGVsZW1lbnQgdHlwZSwgYW5kIHR5cGUtc3BlY2lmaWMgY29uZmlndXJhdGlvbi5cbiAqIEByZXR1cm4ge1ZpZXd9IC0gVGhpcyB2aWV3IGluc3RhbmNlLlxuICovXG52YXIgYmluZCQxID0gZnVuY3Rpb24odmlldywgZWwsIGJpbmRpbmcpIHtcbiAgaWYgKCFlbCkgcmV0dXJuO1xuXG4gIHZhciBwYXJhbSA9IGJpbmRpbmcucGFyYW0sXG4gICAgICBiaW5kID0gYmluZGluZy5zdGF0ZTtcblxuICBpZiAoIWJpbmQpIHtcbiAgICBiaW5kID0gYmluZGluZy5zdGF0ZSA9IHtcbiAgICAgIGVsZW1lbnRzOiBudWxsLFxuICAgICAgYWN0aXZlOiBmYWxzZSxcbiAgICAgIHNldDogbnVsbCxcbiAgICAgIHVwZGF0ZTogZnVuY3Rpb24odmFsdWUpIHtcbiAgICAgICAgYmluZC5zb3VyY2UgPSB0cnVlO1xuICAgICAgICB2aWV3LnNpZ25hbChwYXJhbS5zaWduYWwsIHZhbHVlKS5ydW4oKTtcbiAgICAgIH1cbiAgICB9O1xuICAgIGlmIChwYXJhbS5kZWJvdW5jZSkge1xuICAgICAgYmluZC51cGRhdGUgPSBkZWJvdW5jZShwYXJhbS5kZWJvdW5jZSwgYmluZC51cGRhdGUpO1xuICAgIH1cbiAgfVxuXG4gIGdlbmVyYXRlKGJpbmQsIGVsLCBwYXJhbSwgdmlldy5zaWduYWwocGFyYW0uc2lnbmFsKSk7XG5cbiAgaWYgKCFiaW5kLmFjdGl2ZSkge1xuICAgIHZpZXcub24odmlldy5fc2lnbmFsc1twYXJhbS5zaWduYWxdLCBudWxsLCBmdW5jdGlvbigpIHtcbiAgICAgIGJpbmQuc291cmNlXG4gICAgICAgID8gKGJpbmQuc291cmNlID0gZmFsc2UpXG4gICAgICAgIDogYmluZC5zZXQodmlldy5zaWduYWwocGFyYW0uc2lnbmFsKSk7XG4gICAgfSk7XG4gICAgYmluZC5hY3RpdmUgPSB0cnVlO1xuICB9XG5cbiAgcmV0dXJuIGJpbmQ7XG59O1xuXG4vKipcbiAqIEdlbmVyYXRlIGFuIEhUTUwgaW5wdXQgZm9ybSBlbGVtZW50IGFuZCBiaW5kIGl0IHRvIGEgc2lnbmFsLlxuICovXG5mdW5jdGlvbiBnZW5lcmF0ZShiaW5kLCBlbCwgcGFyYW0sIHZhbHVlKSB7XG4gIHZhciBkaXYgPSBlbGVtZW50JDEoJ2RpdicsIHsnY2xhc3MnOiBCaW5kQ2xhc3N9KTtcblxuICBkaXYuYXBwZW5kQ2hpbGQoZWxlbWVudCQxKCdzcGFuJyxcbiAgICB7J2NsYXNzJzogTmFtZUNsYXNzfSxcbiAgICAocGFyYW0ubmFtZSB8fCBwYXJhbS5zaWduYWwpXG4gICkpO1xuXG4gIGVsLmFwcGVuZENoaWxkKGRpdik7XG5cbiAgdmFyIGlucHV0ID0gZm9ybTtcbiAgc3dpdGNoIChwYXJhbS5pbnB1dCkge1xuICAgIGNhc2UgJ2NoZWNrYm94JzogaW5wdXQgPSBjaGVja2JveDsgYnJlYWs7XG4gICAgY2FzZSAnc2VsZWN0JzogICBpbnB1dCA9IHNlbGVjdDsgYnJlYWs7XG4gICAgY2FzZSAncmFkaW8nOiAgICBpbnB1dCA9IHJhZGlvOyBicmVhaztcbiAgICBjYXNlICdyYW5nZSc6ICAgIGlucHV0ID0gcmFuZ2UkMTsgYnJlYWs7XG4gIH1cblxuICBpbnB1dChiaW5kLCBkaXYsIHBhcmFtLCB2YWx1ZSk7XG59XG5cbi8qKlxuICogR2VuZXJhdGVzIGFuIGFyYml0cmFyeSBpbnB1dCBmb3JtIGVsZW1lbnQuXG4gKiBUaGUgaW5wdXQgdHlwZSBpcyBjb250cm9sbGVkIHZpYSB1c2VyLXByb3ZpZGVkIHBhcmFtZXRlcnMuXG4gKi9cbmZ1bmN0aW9uIGZvcm0oYmluZCwgZWwsIHBhcmFtLCB2YWx1ZSkge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQkMSgnaW5wdXQnKTtcblxuICBmb3IgKHZhciBrZXkkJDEgaW4gcGFyYW0pIHtcbiAgICBpZiAoa2V5JCQxICE9PSAnc2lnbmFsJyAmJiBrZXkkJDEgIT09ICdlbGVtZW50Jykge1xuICAgICAgbm9kZS5zZXRBdHRyaWJ1dGUoa2V5JCQxID09PSAnaW5wdXQnID8gJ3R5cGUnIDoga2V5JCQxLCBwYXJhbVtrZXkkJDFdKTtcbiAgICB9XG4gIH1cbiAgbm9kZS5zZXRBdHRyaWJ1dGUoJ25hbWUnLCBwYXJhbS5zaWduYWwpO1xuICBub2RlLnZhbHVlID0gdmFsdWU7XG5cbiAgZWwuYXBwZW5kQ2hpbGQobm9kZSk7XG5cbiAgbm9kZS5hZGRFdmVudExpc3RlbmVyKCdpbnB1dCcsIGZ1bmN0aW9uKCkge1xuICAgIGJpbmQudXBkYXRlKG5vZGUudmFsdWUpO1xuICB9KTtcblxuICBiaW5kLmVsZW1lbnRzID0gW25vZGVdO1xuICBiaW5kLnNldCA9IGZ1bmN0aW9uKHZhbHVlKSB7IG5vZGUudmFsdWUgPSB2YWx1ZTsgfTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBjaGVja2JveCBpbnB1dCBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBjaGVja2JveChiaW5kLCBlbCwgcGFyYW0sIHZhbHVlKSB7XG4gIHZhciBhdHRyID0ge3R5cGU6ICdjaGVja2JveCcsIG5hbWU6IHBhcmFtLnNpZ25hbH07XG4gIGlmICh2YWx1ZSkgYXR0ci5jaGVja2VkID0gdHJ1ZTtcbiAgdmFyIG5vZGUgPSBlbGVtZW50JDEoJ2lucHV0JywgYXR0cik7XG5cbiAgZWwuYXBwZW5kQ2hpbGQobm9kZSk7XG5cbiAgbm9kZS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHtcbiAgICBiaW5kLnVwZGF0ZShub2RlLmNoZWNrZWQpO1xuICB9KTtcblxuICBiaW5kLmVsZW1lbnRzID0gW25vZGVdO1xuICBiaW5kLnNldCA9IGZ1bmN0aW9uKHZhbHVlKSB7IG5vZGUuY2hlY2tlZCA9ICEhdmFsdWUgfHwgbnVsbDsgfTtcbn1cblxuLyoqXG4gKiBHZW5lcmF0ZXMgYSBzZWxlY3Rpb24gbGlzdCBpbnB1dCBlbGVtZW50LlxuICovXG5mdW5jdGlvbiBzZWxlY3QoYmluZCwgZWwsIHBhcmFtLCB2YWx1ZSkge1xuICB2YXIgbm9kZSA9IGVsZW1lbnQkMSgnc2VsZWN0Jywge25hbWU6IHBhcmFtLnNpZ25hbH0pO1xuXG4gIHBhcmFtLm9wdGlvbnMuZm9yRWFjaChmdW5jdGlvbihvcHRpb24pIHtcbiAgICB2YXIgYXR0ciA9IHt2YWx1ZTogb3B0aW9ufTtcbiAgICBpZiAodmFsdWVzRXF1YWwob3B0aW9uLCB2YWx1ZSkpIGF0dHIuc2VsZWN0ZWQgPSB0cnVlO1xuICAgIG5vZGUuYXBwZW5kQ2hpbGQoZWxlbWVudCQxKCdvcHRpb24nLCBhdHRyLCBvcHRpb24rJycpKTtcbiAgfSk7XG5cbiAgZWwuYXBwZW5kQ2hpbGQobm9kZSk7XG5cbiAgbm9kZS5hZGRFdmVudExpc3RlbmVyKCdjaGFuZ2UnLCBmdW5jdGlvbigpIHtcbiAgICBiaW5kLnVwZGF0ZShwYXJhbS5vcHRpb25zW25vZGUuc2VsZWN0ZWRJbmRleF0pO1xuICB9KTtcblxuICBiaW5kLmVsZW1lbnRzID0gW25vZGVdO1xuICBiaW5kLnNldCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgZm9yICh2YXIgaT0wLCBuPXBhcmFtLm9wdGlvbnMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgICAgaWYgKHZhbHVlc0VxdWFsKHBhcmFtLm9wdGlvbnNbaV0sIHZhbHVlKSkge1xuICAgICAgICBub2RlLnNlbGVjdGVkSW5kZXggPSBpOyByZXR1cm47XG4gICAgICB9XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHJhZGlvIGJ1dHRvbiBncm91cC5cbiAqL1xuZnVuY3Rpb24gcmFkaW8oYmluZCwgZWwsIHBhcmFtLCB2YWx1ZSkge1xuICB2YXIgZ3JvdXAgPSBlbGVtZW50JDEoJ3NwYW4nLCB7J2NsYXNzJzogUmFkaW9DbGFzc30pO1xuXG4gIGVsLmFwcGVuZENoaWxkKGdyb3VwKTtcblxuICBiaW5kLmVsZW1lbnRzID0gcGFyYW0ub3B0aW9ucy5tYXAoZnVuY3Rpb24ob3B0aW9uKSB7XG4gICAgdmFyIGlkJCQxID0gT3B0aW9uQ2xhc3MgKyBwYXJhbS5zaWduYWwgKyAnLScgKyBvcHRpb247XG5cbiAgICB2YXIgYXR0ciA9IHtcbiAgICAgIGlkOiAgICBpZCQkMSxcbiAgICAgIHR5cGU6ICAncmFkaW8nLFxuICAgICAgbmFtZTogIHBhcmFtLnNpZ25hbCxcbiAgICAgIHZhbHVlOiBvcHRpb25cbiAgICB9O1xuICAgIGlmICh2YWx1ZXNFcXVhbChvcHRpb24sIHZhbHVlKSkgYXR0ci5jaGVja2VkID0gdHJ1ZTtcblxuICAgIHZhciBpbnB1dCA9IGVsZW1lbnQkMSgnaW5wdXQnLCBhdHRyKTtcblxuICAgIGlucHV0LmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIGZ1bmN0aW9uKCkge1xuICAgICAgYmluZC51cGRhdGUob3B0aW9uKTtcbiAgICB9KTtcblxuICAgIGdyb3VwLmFwcGVuZENoaWxkKGlucHV0KTtcbiAgICBncm91cC5hcHBlbmRDaGlsZChlbGVtZW50JDEoJ2xhYmVsJywgeydmb3InOiBpZCQkMX0sIG9wdGlvbisnJykpO1xuXG4gICAgcmV0dXJuIGlucHV0O1xuICB9KTtcblxuICBiaW5kLnNldCA9IGZ1bmN0aW9uKHZhbHVlKSB7XG4gICAgdmFyIG5vZGVzID0gYmluZC5lbGVtZW50cyxcbiAgICAgICAgaSA9IDAsXG4gICAgICAgIG4gPSBub2Rlcy5sZW5ndGg7XG4gICAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgICBpZiAodmFsdWVzRXF1YWwobm9kZXNbaV0udmFsdWUsIHZhbHVlKSkgbm9kZXNbaV0uY2hlY2tlZCA9IHRydWU7XG4gICAgfVxuICB9O1xufVxuXG4vKipcbiAqIEdlbmVyYXRlcyBhIHNsaWRlciBpbnB1dCBlbGVtZW50LlxuICovXG5mdW5jdGlvbiByYW5nZSQxKGJpbmQsIGVsLCBwYXJhbSwgdmFsdWUpIHtcbiAgdmFsdWUgPSB2YWx1ZSAhPT0gdW5kZWZpbmVkID8gdmFsdWUgOiAoKCtwYXJhbS5tYXgpICsgKCtwYXJhbS5taW4pKSAvIDI7XG5cbiAgdmFyIG1pbiQkMSA9IHBhcmFtLm1pbiB8fCBNYXRoLm1pbigwLCArdmFsdWUpIHx8IDAsXG4gICAgICBtYXgkJDEgPSBwYXJhbS5tYXggfHwgTWF0aC5tYXgoMTAwLCArdmFsdWUpIHx8IDEwMCxcbiAgICAgIHN0ZXAgPSBwYXJhbS5zdGVwIHx8IHRpY2tTdGVwKG1pbiQkMSwgbWF4JCQxLCAxMDApO1xuXG4gIHZhciBub2RlID0gZWxlbWVudCQxKCdpbnB1dCcsIHtcbiAgICB0eXBlOiAgJ3JhbmdlJyxcbiAgICBuYW1lOiAgcGFyYW0uc2lnbmFsLFxuICAgIG1pbjogICBtaW4kJDEsXG4gICAgbWF4OiAgIG1heCQkMSxcbiAgICBzdGVwOiAgc3RlcFxuICB9KTtcbiAgbm9kZS52YWx1ZSA9IHZhbHVlO1xuXG4gIHZhciBsYWJlbCA9IGVsZW1lbnQkMSgnbGFiZWwnLCB7fSwgK3ZhbHVlKTtcblxuICBlbC5hcHBlbmRDaGlsZChub2RlKTtcbiAgZWwuYXBwZW5kQ2hpbGQobGFiZWwpO1xuXG4gIGZ1bmN0aW9uIHVwZGF0ZSgpIHtcbiAgICBsYWJlbC50ZXh0Q29udGVudCA9IG5vZGUudmFsdWU7XG4gICAgYmluZC51cGRhdGUoK25vZGUudmFsdWUpO1xuICB9XG5cbiAgLy8gc3Vic2NyaWJlIHRvIGJvdGggaW5wdXQgYW5kIGNoYW5nZVxuICAvLyBzaWduYWwgdXBkYXRlcyBoYWx0IHJlZHVuZGFudCB2YWx1ZXMsIG1haW50YWluaW5nIHBlcmZvcm1hbmNlXG4gIG5vZGUuYWRkRXZlbnRMaXN0ZW5lcignaW5wdXQnLCB1cGRhdGUpO1xuICBub2RlLmFkZEV2ZW50TGlzdGVuZXIoJ2NoYW5nZScsIHVwZGF0ZSk7XG5cbiAgYmluZC5lbGVtZW50cyA9IFtub2RlXTtcbiAgYmluZC5zZXQgPSBmdW5jdGlvbih2YWx1ZSkge1xuICAgIG5vZGUudmFsdWUgPSB2YWx1ZTtcbiAgICBsYWJlbC50ZXh0Q29udGVudCA9IHZhbHVlO1xuICB9O1xufVxuXG5mdW5jdGlvbiB2YWx1ZXNFcXVhbChhLCBiKSB7XG4gIHJldHVybiBhID09PSBiIHx8IChhKycnID09PSBiKycnKTtcbn1cblxudmFyIGluaXRpYWxpemVSZW5kZXJlciA9IGZ1bmN0aW9uKHZpZXcsIHIsIGVsLCBjb25zdHJ1Y3Rvciwgc2NhbGVGYWN0b3IpIHtcbiAgciA9IHIgfHwgbmV3IGNvbnN0cnVjdG9yKHZpZXcubG9hZGVyKCkpO1xuICByZXR1cm4gclxuICAgIC5pbml0aWFsaXplKGVsLCB3aWR0aCh2aWV3KSwgaGVpZ2h0JDEodmlldyksIG9mZnNldCQxKHZpZXcpLCBzY2FsZUZhY3RvcilcbiAgICAuYmFja2dyb3VuZCh2aWV3Ll9iYWNrZ3JvdW5kKTtcbn07XG5cbnZhciBpbml0aWFsaXplSGFuZGxlciA9IGZ1bmN0aW9uKHZpZXcsIHByZXZIYW5kbGVyLCBlbCwgY29uc3RydWN0b3IpIHtcbiAgdmFyIGhhbmRsZXIgPSBuZXcgY29uc3RydWN0b3Iodmlldy5sb2FkZXIoKSlcbiAgICAuc2NlbmUodmlldy5zY2VuZWdyYXBoKCkucm9vdClcbiAgICAuaW5pdGlhbGl6ZShlbCwgb2Zmc2V0JDEodmlldyksIHZpZXcpO1xuXG4gIGlmIChwcmV2SGFuZGxlcikge1xuICAgIGhhbmRsZXIuaGFuZGxlVG9vbHRpcCA9IHByZXZIYW5kbGVyLmhhbmRsZVRvb2x0aXA7XG4gICAgcHJldkhhbmRsZXIuaGFuZGxlcnMoKS5mb3JFYWNoKGZ1bmN0aW9uKGgpIHtcbiAgICAgIGhhbmRsZXIub24oaC50eXBlLCBoLmhhbmRsZXIpO1xuICAgIH0pO1xuICB9XG5cbiAgcmV0dXJuIGhhbmRsZXI7XG59O1xuXG52YXIgaW5pdGlhbGl6ZSQxID0gZnVuY3Rpb24oZWwsIGVsQmluZCkge1xuICB2YXIgdmlldyA9IHRoaXMsXG4gICAgICB0eXBlID0gdmlldy5fcmVuZGVyVHlwZSxcbiAgICAgIG1vZHVsZSA9IHJlbmRlck1vZHVsZSh0eXBlKSxcbiAgICAgIEhhbmRsZXIkJDEsIFJlbmRlcmVyJCQxO1xuXG4gIC8vIGNvbnRhaW5pbmcgZG9tIGVsZW1lbnRcbiAgZWwgPSB2aWV3Ll9lbCA9IGVsID8gbG9va3VwJDIodmlldywgZWwpIDogbnVsbDtcblxuICAvLyBzZWxlY3QgYXBwcm9wcmlhdGUgcmVuZGVyZXIgJiBoYW5kbGVyXG4gIGlmICghbW9kdWxlKSB2aWV3LmVycm9yKCdVbnJlY29nbml6ZWQgcmVuZGVyZXIgdHlwZTogJyArIHR5cGUpO1xuICBIYW5kbGVyJCQxID0gbW9kdWxlLmhhbmRsZXIgfHwgQ2FudmFzSGFuZGxlcjtcbiAgUmVuZGVyZXIkJDEgPSAoZWwgPyBtb2R1bGUucmVuZGVyZXIgOiBtb2R1bGUuaGVhZGxlc3MpO1xuXG4gIC8vIGluaXRpYWxpemUgcmVuZGVyZXIgYW5kIGlucHV0IGhhbmRsZXJcbiAgdmlldy5fcmVuZGVyZXIgPSAhUmVuZGVyZXIkJDEgPyBudWxsXG4gICAgOiBpbml0aWFsaXplUmVuZGVyZXIodmlldywgdmlldy5fcmVuZGVyZXIsIGVsLCBSZW5kZXJlciQkMSk7XG4gIHZpZXcuX2hhbmRsZXIgPSBpbml0aWFsaXplSGFuZGxlcih2aWV3LCB2aWV3Ll9oYW5kbGVyLCBlbCwgSGFuZGxlciQkMSk7XG4gIHZpZXcuX3JlZHJhdyA9IHRydWU7XG5cbiAgLy8gaW5pdGlhbGl6ZSBzaWduYWwgYmluZGluZ3NcbiAgaWYgKGVsKSB7XG4gICAgZWxCaW5kID0gZWxCaW5kID8gbG9va3VwJDIodmlldywgZWxCaW5kKVxuICAgICAgOiBlbC5hcHBlbmRDaGlsZChlbGVtZW50JDEoJ2RpdicsIHsnY2xhc3MnOiAndmVnYS1iaW5kaW5ncyd9KSk7XG5cbiAgICB2aWV3Ll9iaW5kLmZvckVhY2goZnVuY3Rpb24oXykge1xuICAgICAgaWYgKF8ucGFyYW0uZWxlbWVudCkge1xuICAgICAgICBfLmVsZW1lbnQgPSBsb29rdXAkMih2aWV3LCBfLnBhcmFtLmVsZW1lbnQpO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgdmlldy5fYmluZC5mb3JFYWNoKGZ1bmN0aW9uKF8pIHtcbiAgICAgIGJpbmQkMSh2aWV3LCBfLmVsZW1lbnQgfHwgZWxCaW5kLCBfKTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiB2aWV3O1xufTtcblxuZnVuY3Rpb24gbG9va3VwJDIodmlldywgZWwpIHtcbiAgaWYgKHR5cGVvZiBlbCA9PT0gJ3N0cmluZycpIHtcbiAgICBpZiAodHlwZW9mIGRvY3VtZW50ICE9PSAndW5kZWZpbmVkJykge1xuICAgICAgZWwgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKGVsKTtcbiAgICAgIGlmICghZWwpIHtcbiAgICAgICAgdmlldy5lcnJvcignU2lnbmFsIGJpbmQgZWxlbWVudCBub3QgZm91bmQ6ICcgKyBlbCk7XG4gICAgICAgIHJldHVybiBudWxsO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICB2aWV3LmVycm9yKCdET00gZG9jdW1lbnQgaW5zdGFuY2Ugbm90IGZvdW5kLicpO1xuICAgICAgcmV0dXJuIG51bGw7XG4gICAgfVxuICB9XG4gIGlmIChlbCkge1xuICAgIHRyeSB7XG4gICAgICBlbC5pbm5lckhUTUwgPSAnJztcbiAgICB9IGNhdGNoIChlKSB7XG4gICAgICBlbCA9IG51bGw7XG4gICAgICB2aWV3LmVycm9yKGUpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gZWw7XG59XG5cbi8qKlxuICogUmVuZGVyIHRoZSBjdXJyZW50IHNjZW5lIGluIGEgaGVhZGxlc3MgZmFzaGlvbi5cbiAqIFRoaXMgbWV0aG9kIGlzIGFzeW5jaHJvbm91cywgcmV0dXJuaW5nIGEgUHJvbWlzZSBpbnN0YW5jZS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBQcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSByZW5kZXJlci5cbiAqL1xudmFyIHJlbmRlckhlYWRsZXNzID0gZnVuY3Rpb24odmlldywgdHlwZSwgc2NhbGVGYWN0b3IpIHtcbiAgdmFyIG1vZHVsZSA9IHJlbmRlck1vZHVsZSh0eXBlKSxcbiAgICAgIGN0ciA9IG1vZHVsZSAmJiBtb2R1bGUuaGVhZGxlc3M7XG4gIHJldHVybiAhY3RyXG4gICAgPyBQcm9taXNlLnJlamVjdCgnVW5yZWNvZ25pemVkIHJlbmRlcmVyIHR5cGU6ICcgKyB0eXBlKVxuICAgIDogdmlldy5ydW5Bc3luYygpLnRoZW4oZnVuY3Rpb24oKSB7XG4gICAgICAgIHJldHVybiBpbml0aWFsaXplUmVuZGVyZXIodmlldywgbnVsbCwgbnVsbCwgY3RyLCBzY2FsZUZhY3RvcilcbiAgICAgICAgICAucmVuZGVyQXN5bmModmlldy5fc2NlbmVncmFwaC5yb290KTtcbiAgICAgIH0pO1xufTtcblxuLyoqXG4gKiBQcm9kdWNlIGFuIGltYWdlIFVSTCBmb3IgdGhlIHZpc3VhbGl6YXRpb24uIERlcGVuZGluZyBvbiB0aGUgdHlwZVxuICogcGFyYW1ldGVyLCB0aGUgZ2VuZXJhdGVkIFVSTCBjb250YWlucyBkYXRhIGZvciBlaXRoZXIgYSBQTkcgb3IgU1ZHIGltYWdlLlxuICogVGhlIFVSTCBjYW4gYmUgdXNlZCAoZm9yIGV4YW1wbGUpIHRvIGRvd25sb2FkIGltYWdlcyBvZiB0aGUgdmlzdWFsaXphdGlvbi5cbiAqIFRoaXMgbWV0aG9kIGlzIGFzeW5jaHJvbm91cywgcmV0dXJuaW5nIGEgUHJvbWlzZSBpbnN0YW5jZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSB0eXBlIC0gVGhlIGltYWdlIHR5cGUuIE9uZSBvZiAnc3ZnJywgJ3BuZycgb3IgJ2NhbnZhcycuXG4gKiAgIFRoZSAnY2FudmFzJyBhbmQgJ3BuZycgdHlwZXMgYXJlIHN5bm9ueW1zIGZvciBhIFBORyBpbWFnZS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYW4gaW1hZ2UgVVJMLlxuICovXG52YXIgcmVuZGVyVG9JbWFnZVVSTCA9IGZ1bmN0aW9uKHR5cGUsIHNjYWxlRmFjdG9yKSB7XG4gIHJldHVybiAodHlwZSAhPT0gUmVuZGVyVHlwZS5DYW52YXMgJiYgdHlwZSAhPT0gUmVuZGVyVHlwZS5TVkcgJiYgdHlwZSAhPT0gUmVuZGVyVHlwZS5QTkcpXG4gICAgPyBQcm9taXNlLnJlamVjdCgnVW5yZWNvZ25pemVkIGltYWdlIHR5cGU6ICcgKyB0eXBlKVxuICAgIDogcmVuZGVySGVhZGxlc3ModGhpcywgdHlwZSwgc2NhbGVGYWN0b3IpLnRoZW4oZnVuY3Rpb24ocmVuZGVyZXIpIHtcbiAgICAgICAgcmV0dXJuIHR5cGUgPT09IFJlbmRlclR5cGUuU1ZHXG4gICAgICAgICAgPyB0b0Jsb2JVUkwocmVuZGVyZXIuc3ZnKCksICdpbWFnZS9zdmcreG1sJylcbiAgICAgICAgICA6IHJlbmRlcmVyLmNhbnZhcygpLnRvRGF0YVVSTCgnaW1hZ2UvcG5nJyk7XG4gICAgICB9KTtcbn07XG5cbmZ1bmN0aW9uIHRvQmxvYlVSTChkYXRhLCBtaW1lKSB7XG4gIHZhciBibG9iID0gbmV3IEJsb2IoW2RhdGFdLCB7dHlwZTogbWltZX0pO1xuICByZXR1cm4gd2luZG93LlVSTC5jcmVhdGVPYmplY3RVUkwoYmxvYik7XG59XG5cbi8qKlxuICogUHJvZHVjZSBhIENhbnZhcyBpbnN0YW5jZSBjb250YWluaW5nIGEgcmVuZGVyZWQgdmlzdWFsaXphdGlvbi5cbiAqIFRoaXMgbWV0aG9kIGlzIGFzeW5jaHJvbm91cywgcmV0dXJuaW5nIGEgUHJvbWlzZSBpbnN0YW5jZS5cbiAqIEByZXR1cm4ge1Byb21pc2V9IC0gQSBwcm9taXNlIHRoYXQgcmVzb2x2ZXMgdG8gYSBDYW52YXMgaW5zdGFuY2UuXG4gKi9cbnZhciByZW5kZXJUb0NhbnZhcyA9IGZ1bmN0aW9uKHNjYWxlRmFjdG9yKSB7XG4gIHJldHVybiByZW5kZXJIZWFkbGVzcyh0aGlzLCBSZW5kZXJUeXBlLkNhbnZhcywgc2NhbGVGYWN0b3IpXG4gICAgLnRoZW4oZnVuY3Rpb24ocmVuZGVyZXIpIHsgcmV0dXJuIHJlbmRlcmVyLmNhbnZhcygpOyB9KTtcbn07XG5cbi8qKlxuICogUHJvZHVjZSBhIHJlbmRlcmVkIFNWRyBzdHJpbmcgb2YgdGhlIHZpc3VhbGl6YXRpb24uXG4gKiBUaGlzIG1ldGhvZCBpcyBhc3luY2hyb25vdXMsIHJldHVybmluZyBhIFByb21pc2UgaW5zdGFuY2UuXG4gKiBAcmV0dXJuIHtQcm9taXNlfSAtIEEgcHJvbWlzZSB0aGF0IHJlc29sdmVzIHRvIGFuIFNWRyBzdHJpbmcuXG4gKi9cbnZhciByZW5kZXJUb1NWRyA9IGZ1bmN0aW9uKHNjYWxlRmFjdG9yKSB7XG4gIHJldHVybiByZW5kZXJIZWFkbGVzcyh0aGlzLCBSZW5kZXJUeXBlLlNWRywgc2NhbGVGYWN0b3IpXG4gICAgLnRoZW4oZnVuY3Rpb24ocmVuZGVyZXIpIHsgcmV0dXJuIHJlbmRlcmVyLnN2ZygpOyB9KTtcbn07XG5cbnZhciBwYXJzZUF1dG9zaXplID0gZnVuY3Rpb24oc3BlYywgY29uZmlnKSB7XG4gIHNwZWMgPSBzcGVjIHx8IGNvbmZpZy5hdXRvc2l6ZTtcbiAgaWYgKGlzT2JqZWN0KHNwZWMpKSB7XG4gICAgcmV0dXJuIHNwZWM7XG4gIH0gZWxzZSB7XG4gICAgc3BlYyA9IHNwZWMgfHwgJ3BhZCc7XG4gICAgcmV0dXJuIHt0eXBlOiBzcGVjfTtcbiAgfVxufTtcblxudmFyIHBhcnNlUGFkZGluZyA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZykge1xuICBzcGVjID0gc3BlYyB8fCBjb25maWcucGFkZGluZztcbiAgcmV0dXJuIGlzT2JqZWN0KHNwZWMpXG4gICAgPyB7XG4gICAgICAgIHRvcDogICAgbnVtYmVyJDQoc3BlYy50b3ApLFxuICAgICAgICBib3R0b206IG51bWJlciQ0KHNwZWMuYm90dG9tKSxcbiAgICAgICAgbGVmdDogICBudW1iZXIkNChzcGVjLmxlZnQpLFxuICAgICAgICByaWdodDogIG51bWJlciQ0KHNwZWMucmlnaHQpXG4gICAgICB9XG4gICAgOiBwYWRkaW5nT2JqZWN0KG51bWJlciQ0KHNwZWMpKTtcbn07XG5cbmZ1bmN0aW9uIG51bWJlciQ0KF8pIHtcbiAgcmV0dXJuICtfIHx8IDA7XG59XG5cbmZ1bmN0aW9uIHBhZGRpbmdPYmplY3QoXykge1xuICByZXR1cm4ge3RvcDogXywgYm90dG9tOiBfLCBsZWZ0OiBfLCByaWdodDogX307XG59XG5cbnZhciBPVVRFUiA9ICdvdXRlcic7XG52YXIgT1VURVJfSU5WQUxJRCA9IFsndmFsdWUnLCAndXBkYXRlJywgJ3JlYWN0JywgJ2JpbmQnXTtcblxuZnVuY3Rpb24gb3V0ZXJFcnJvcihwcmVmaXgsIG5hbWUpIHtcbiAgZXJyb3IkMShwcmVmaXggKyAnIGZvciBcIm91dGVyXCIgcHVzaDogJyArICQobmFtZSkpO1xufVxuXG52YXIgcGFyc2VTaWduYWwgPSBmdW5jdGlvbihzaWduYWwsIHNjb3BlKSB7XG4gIHZhciBuYW1lID0gc2lnbmFsLm5hbWU7XG5cbiAgaWYgKHNpZ25hbC5wdXNoID09PSBPVVRFUikge1xuICAgIC8vIHNpZ25hbCBtdXN0IGFscmVhZHkgYmUgZGVmaW5lZCwgcmFpc2UgZXJyb3IgaWYgbm90XG4gICAgaWYgKCFzY29wZS5zaWduYWxzW25hbWVdKSBvdXRlckVycm9yKCdObyBwcmlvciBzaWduYWwgZGVmaW5pdGlvbicsIG5hbWUpO1xuICAgIC8vIHNpZ25hbCBwdXNoIG11c3Qgbm90IHVzZSBwcm9wZXJ0aWVzIHJlc2VydmVkIGZvciBzdGFuZGFyZCBkZWZpbml0aW9uXG4gICAgT1VURVJfSU5WQUxJRC5mb3JFYWNoKGZ1bmN0aW9uKHByb3ApIHtcbiAgICAgIGlmIChzaWduYWxbcHJvcF0gIT09IHVuZGVmaW5lZCkgb3V0ZXJFcnJvcignSW52YWxpZCBwcm9wZXJ0eSAnLCBwcm9wKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICAvLyBkZWZpbmUgYSBuZXcgc2lnbmFsIGluIHRoZSBjdXJyZW50IHNjb3BlXG4gICAgdmFyIG9wID0gc2NvcGUuYWRkU2lnbmFsKG5hbWUsIHNpZ25hbC52YWx1ZSk7XG4gICAgaWYgKHNpZ25hbC5yZWFjdCA9PT0gZmFsc2UpIG9wLnJlYWN0ID0gZmFsc2U7XG4gICAgaWYgKHNpZ25hbC5iaW5kKSBzY29wZS5hZGRCaW5kaW5nKG5hbWUsIHNpZ25hbC5iaW5kKTtcbiAgfVxufTtcblxuZnVuY3Rpb24gQVNUTm9kZSh0eXBlKSB7XG4gIHRoaXMudHlwZSA9IHR5cGU7XG59XG5cbkFTVE5vZGUucHJvdG90eXBlLnZpc2l0ID0gZnVuY3Rpb24odmlzaXRvcikge1xuICB2YXIgbm9kZSA9IHRoaXMsIGMsIGksIG47XG5cbiAgaWYgKHZpc2l0b3Iobm9kZSkpIHJldHVybiAxO1xuXG4gIGZvciAoYz1jaGlsZHJlbiQxKG5vZGUpLCBpPTAsIG49Yy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgaWYgKGNbaV0udmlzaXQodmlzaXRvcikpIHJldHVybiAxO1xuICB9XG59O1xuXG5mdW5jdGlvbiBjaGlsZHJlbiQxKG5vZGUpIHtcbiAgc3dpdGNoIChub2RlLnR5cGUpIHtcbiAgICBjYXNlICdBcnJheUV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIG5vZGUuZWxlbWVudHM7XG4gICAgY2FzZSAnQmluYXJ5RXhwcmVzc2lvbic6XG4gICAgY2FzZSAnTG9naWNhbEV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIFtub2RlLmxlZnQsIG5vZGUucmlnaHRdO1xuICAgIGNhc2UgJ0NhbGxFeHByZXNzaW9uJzpcbiAgICAgIHZhciBhcmdzID0gbm9kZS5hcmd1bWVudHMuc2xpY2UoKTtcbiAgICAgIGFyZ3MudW5zaGlmdChub2RlLmNhbGxlZSk7XG4gICAgICByZXR1cm4gYXJncztcbiAgICBjYXNlICdDb25kaXRpb25hbEV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIFtub2RlLnRlc3QsIG5vZGUuY29uc2VxdWVudCwgbm9kZS5hbHRlcm5hdGVdO1xuICAgIGNhc2UgJ01lbWJlckV4cHJlc3Npb24nOlxuICAgICAgcmV0dXJuIFtub2RlLm9iamVjdCwgbm9kZS5wcm9wZXJ0eV07XG4gICAgY2FzZSAnT2JqZWN0RXhwcmVzc2lvbic6XG4gICAgICByZXR1cm4gbm9kZS5wcm9wZXJ0aWVzO1xuICAgIGNhc2UgJ1Byb3BlcnR5JzpcbiAgICAgIHJldHVybiBbbm9kZS5rZXksIG5vZGUudmFsdWVdO1xuICAgIGNhc2UgJ1VuYXJ5RXhwcmVzc2lvbic6XG4gICAgICByZXR1cm4gW25vZGUuYXJndW1lbnRdO1xuICAgIGNhc2UgJ0lkZW50aWZpZXInOlxuICAgIGNhc2UgJ0xpdGVyYWwnOlxuICAgIGNhc2UgJ1Jhd0NvZGUnOlxuICAgIGRlZmF1bHQ6XG4gICAgICByZXR1cm4gW107XG4gIH1cbn1cblxuLypcbiAgVGhlIGZvbGxvd2luZyBleHByZXNzaW9uIHBhcnNlciBpcyBiYXNlZCBvbiBFc3ByaW1hIChodHRwOi8vZXNwcmltYS5vcmcvKS5cbiAgT3JpZ2luYWwgaGVhZGVyIGNvbW1lbnQgYW5kIGxpY2Vuc2UgZm9yIEVzcHJpbWEgaXMgaW5jbHVkZWQgaGVyZTpcblxuICBDb3B5cmlnaHQgKEMpIDIwMTMgQXJpeWEgSGlkYXlhdCA8YXJpeWEuaGlkYXlhdEBnbWFpbC5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxMyBUaGFkZGVlIFR5bCA8dGhhZGRlZS50eWxAZ21haWwuY29tPlxuICBDb3B5cmlnaHQgKEMpIDIwMTMgTWF0aGlhcyBCeW5lbnMgPG1hdGhpYXNAcWl3aS5iZT5cbiAgQ29weXJpZ2h0IChDKSAyMDEyIEFyaXlhIEhpZGF5YXQgPGFyaXlhLmhpZGF5YXRAZ21haWwuY29tPlxuICBDb3B5cmlnaHQgKEMpIDIwMTIgTWF0aGlhcyBCeW5lbnMgPG1hdGhpYXNAcWl3aS5iZT5cbiAgQ29weXJpZ2h0IChDKSAyMDEyIEpvb3N0LVdpbSBCb2VrZXN0ZWlqbiA8am9vc3Qtd2ltQGJvZWtlc3RlaWpuLm5sPlxuICBDb3B5cmlnaHQgKEMpIDIwMTIgS3JpcyBLb3dhbCA8a3Jpcy5rb3dhbEBjaXhhci5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxMiBZdXN1a2UgU3V6dWtpIDx1dGF0YW5lLnRlYUBnbWFpbC5jb20+XG4gIENvcHlyaWdodCAoQykgMjAxMiBBcnBhZCBCb3Jzb3MgPGFycGFkLmJvcnNvc0Bnb29nbGVtYWlsLmNvbT5cbiAgQ29weXJpZ2h0IChDKSAyMDExIEFyaXlhIEhpZGF5YXQgPGFyaXlhLmhpZGF5YXRAZ21haWwuY29tPlxuXG4gIFJlZGlzdHJpYnV0aW9uIGFuZCB1c2UgaW4gc291cmNlIGFuZCBiaW5hcnkgZm9ybXMsIHdpdGggb3Igd2l0aG91dFxuICBtb2RpZmljYXRpb24sIGFyZSBwZXJtaXR0ZWQgcHJvdmlkZWQgdGhhdCB0aGUgZm9sbG93aW5nIGNvbmRpdGlvbnMgYXJlIG1ldDpcblxuICAgICogUmVkaXN0cmlidXRpb25zIG9mIHNvdXJjZSBjb2RlIG11c3QgcmV0YWluIHRoZSBhYm92ZSBjb3B5cmlnaHRcbiAgICAgIG5vdGljZSwgdGhpcyBsaXN0IG9mIGNvbmRpdGlvbnMgYW5kIHRoZSBmb2xsb3dpbmcgZGlzY2xhaW1lci5cbiAgICAqIFJlZGlzdHJpYnV0aW9ucyBpbiBiaW5hcnkgZm9ybSBtdXN0IHJlcHJvZHVjZSB0aGUgYWJvdmUgY29weXJpZ2h0XG4gICAgICBub3RpY2UsIHRoaXMgbGlzdCBvZiBjb25kaXRpb25zIGFuZCB0aGUgZm9sbG93aW5nIGRpc2NsYWltZXIgaW4gdGhlXG4gICAgICBkb2N1bWVudGF0aW9uIGFuZC9vciBvdGhlciBtYXRlcmlhbHMgcHJvdmlkZWQgd2l0aCB0aGUgZGlzdHJpYnV0aW9uLlxuXG4gIFRISVMgU09GVFdBUkUgSVMgUFJPVklERUQgQlkgVEhFIENPUFlSSUdIVCBIT0xERVJTIEFORCBDT05UUklCVVRPUlMgXCJBUyBJU1wiXG4gIEFORCBBTlkgRVhQUkVTUyBPUiBJTVBMSUVEIFdBUlJBTlRJRVMsIElOQ0xVRElORywgQlVUIE5PVCBMSU1JVEVEIFRPLCBUSEVcbiAgSU1QTElFRCBXQVJSQU5USUVTIE9GIE1FUkNIQU5UQUJJTElUWSBBTkQgRklUTkVTUyBGT1IgQSBQQVJUSUNVTEFSIFBVUlBPU0VcbiAgQVJFIERJU0NMQUlNRUQuIElOIE5PIEVWRU5UIFNIQUxMIDxDT1BZUklHSFQgSE9MREVSPiBCRSBMSUFCTEUgRk9SIEFOWVxuICBESVJFQ1QsIElORElSRUNULCBJTkNJREVOVEFMLCBTUEVDSUFMLCBFWEVNUExBUlksIE9SIENPTlNFUVVFTlRJQUwgREFNQUdFU1xuICAoSU5DTFVESU5HLCBCVVQgTk9UIExJTUlURUQgVE8sIFBST0NVUkVNRU5UIE9GIFNVQlNUSVRVVEUgR09PRFMgT1IgU0VSVklDRVM7XG4gIExPU1MgT0YgVVNFLCBEQVRBLCBPUiBQUk9GSVRTOyBPUiBCVVNJTkVTUyBJTlRFUlJVUFRJT04pIEhPV0VWRVIgQ0FVU0VEIEFORFxuICBPTiBBTlkgVEhFT1JZIE9GIExJQUJJTElUWSwgV0hFVEhFUiBJTiBDT05UUkFDVCwgU1RSSUNUIExJQUJJTElUWSwgT1IgVE9SVFxuICAoSU5DTFVESU5HIE5FR0xJR0VOQ0UgT1IgT1RIRVJXSVNFKSBBUklTSU5HIElOIEFOWSBXQVkgT1VUIE9GIFRIRSBVU0UgT0ZcbiAgVEhJUyBTT0ZUV0FSRSwgRVZFTiBJRiBBRFZJU0VEIE9GIFRIRSBQT1NTSUJJTElUWSBPRiBTVUNIIERBTUFHRS5cbiovXG52YXIgc291cmNlJDE7XG52YXIgaW5kZXgkMTtcbnZhciBsZW5ndGgkMjtcbnZhciBsb29rYWhlYWQ7XG5cbnZhciBUb2tlbkJvb2xlYW5MaXRlcmFsID0gMTtcbnZhciBUb2tlbkVPRiA9IDI7XG52YXIgVG9rZW5JZGVudGlmaWVyID0gMztcbnZhciBUb2tlbktleXdvcmQgPSA0O1xudmFyIFRva2VuTnVsbExpdGVyYWwgPSA1O1xudmFyIFRva2VuTnVtZXJpY0xpdGVyYWwgPSA2O1xudmFyIFRva2VuUHVuY3R1YXRvciA9IDc7XG52YXIgVG9rZW5TdHJpbmdMaXRlcmFsID0gODtcblxudmFyIFN5bnRheEFycmF5RXhwcmVzc2lvbiA9ICdBcnJheUV4cHJlc3Npb24nO1xudmFyIFN5bnRheEJpbmFyeUV4cHJlc3Npb24gPSAnQmluYXJ5RXhwcmVzc2lvbic7XG52YXIgU3ludGF4Q2FsbEV4cHJlc3Npb24gPSAnQ2FsbEV4cHJlc3Npb24nO1xudmFyIFN5bnRheENvbmRpdGlvbmFsRXhwcmVzc2lvbiA9ICdDb25kaXRpb25hbEV4cHJlc3Npb24nO1xudmFyIFN5bnRheElkZW50aWZpZXIgPSAnSWRlbnRpZmllcic7XG52YXIgU3ludGF4TGl0ZXJhbCA9ICdMaXRlcmFsJztcbnZhciBTeW50YXhMb2dpY2FsRXhwcmVzc2lvbiA9ICdMb2dpY2FsRXhwcmVzc2lvbic7XG52YXIgU3ludGF4TWVtYmVyRXhwcmVzc2lvbiA9ICdNZW1iZXJFeHByZXNzaW9uJztcbnZhciBTeW50YXhPYmplY3RFeHByZXNzaW9uID0gJ09iamVjdEV4cHJlc3Npb24nO1xudmFyIFN5bnRheFByb3BlcnR5ID0gJ1Byb3BlcnR5JztcbnZhciBTeW50YXhVbmFyeUV4cHJlc3Npb24gPSAnVW5hcnlFeHByZXNzaW9uJztcblxuLy8gRXJyb3IgbWVzc2FnZXMgc2hvdWxkIGJlIGlkZW50aWNhbCB0byBWOC5cbnZhciBNZXNzYWdlVW5leHBlY3RlZFRva2VuID0gJ1VuZXhwZWN0ZWQgdG9rZW4gJTAnO1xudmFyIE1lc3NhZ2VVbmV4cGVjdGVkTnVtYmVyID0gJ1VuZXhwZWN0ZWQgbnVtYmVyJztcbnZhciBNZXNzYWdlVW5leHBlY3RlZFN0cmluZyA9ICdVbmV4cGVjdGVkIHN0cmluZyc7XG52YXIgTWVzc2FnZVVuZXhwZWN0ZWRJZGVudGlmaWVyID0gJ1VuZXhwZWN0ZWQgaWRlbnRpZmllcic7XG52YXIgTWVzc2FnZVVuZXhwZWN0ZWRSZXNlcnZlZCA9ICdVbmV4cGVjdGVkIHJlc2VydmVkIHdvcmQnO1xudmFyIE1lc3NhZ2VVbmV4cGVjdGVkRU9TID0gJ1VuZXhwZWN0ZWQgZW5kIG9mIGlucHV0JztcbnZhciBNZXNzYWdlSW52YWxpZFJlZ0V4cCA9ICdJbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbic7XG52YXIgTWVzc2FnZVVudGVybWluYXRlZFJlZ0V4cCA9ICdJbnZhbGlkIHJlZ3VsYXIgZXhwcmVzc2lvbjogbWlzc2luZyAvJztcbnZhciBNZXNzYWdlU3RyaWN0T2N0YWxMaXRlcmFsID0gJ09jdGFsIGxpdGVyYWxzIGFyZSBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZS4nO1xudmFyIE1lc3NhZ2VTdHJpY3REdXBsaWNhdGVQcm9wZXJ0eSA9ICdEdXBsaWNhdGUgZGF0YSBwcm9wZXJ0eSBpbiBvYmplY3QgbGl0ZXJhbCBub3QgYWxsb3dlZCBpbiBzdHJpY3QgbW9kZSc7XG5cbnZhciBJTExFR0FMID0gJ0lMTEVHQUwnO1xudmFyIERJU0FCTEVEID0gJ0Rpc2FibGVkLic7XG5cbi8vIFNlZSBhbHNvIHRvb2xzL2dlbmVyYXRlLXVuaWNvZGUtcmVnZXgucHkuXG52YXIgUmVnZXhOb25Bc2NpaUlkZW50aWZpZXJTdGFydCA9IG5ldyBSZWdFeHAoJ1tcXHhBQVxceEI1XFx4QkFcXHhDMC1cXHhENlxceEQ4LVxceEY2XFx4RjgtXFx1MDJDMVxcdTAyQzYtXFx1MDJEMVxcdTAyRTAtXFx1MDJFNFxcdTAyRUNcXHUwMkVFXFx1MDM3MC1cXHUwMzc0XFx1MDM3NlxcdTAzNzdcXHUwMzdBLVxcdTAzN0RcXHUwMzdGXFx1MDM4NlxcdTAzODgtXFx1MDM4QVxcdTAzOENcXHUwMzhFLVxcdTAzQTFcXHUwM0EzLVxcdTAzRjVcXHUwM0Y3LVxcdTA0ODFcXHUwNDhBLVxcdTA1MkZcXHUwNTMxLVxcdTA1NTZcXHUwNTU5XFx1MDU2MS1cXHUwNTg3XFx1MDVEMC1cXHUwNUVBXFx1MDVGMC1cXHUwNUYyXFx1MDYyMC1cXHUwNjRBXFx1MDY2RVxcdTA2NkZcXHUwNjcxLVxcdTA2RDNcXHUwNkQ1XFx1MDZFNVxcdTA2RTZcXHUwNkVFXFx1MDZFRlxcdTA2RkEtXFx1MDZGQ1xcdTA2RkZcXHUwNzEwXFx1MDcxMi1cXHUwNzJGXFx1MDc0RC1cXHUwN0E1XFx1MDdCMVxcdTA3Q0EtXFx1MDdFQVxcdTA3RjRcXHUwN0Y1XFx1MDdGQVxcdTA4MDAtXFx1MDgxNVxcdTA4MUFcXHUwODI0XFx1MDgyOFxcdTA4NDAtXFx1MDg1OFxcdTA4QTAtXFx1MDhCMlxcdTA5MDQtXFx1MDkzOVxcdTA5M0RcXHUwOTUwXFx1MDk1OC1cXHUwOTYxXFx1MDk3MS1cXHUwOTgwXFx1MDk4NS1cXHUwOThDXFx1MDk4RlxcdTA5OTBcXHUwOTkzLVxcdTA5QThcXHUwOUFBLVxcdTA5QjBcXHUwOUIyXFx1MDlCNi1cXHUwOUI5XFx1MDlCRFxcdTA5Q0VcXHUwOURDXFx1MDlERFxcdTA5REYtXFx1MDlFMVxcdTA5RjBcXHUwOUYxXFx1MEEwNS1cXHUwQTBBXFx1MEEwRlxcdTBBMTBcXHUwQTEzLVxcdTBBMjhcXHUwQTJBLVxcdTBBMzBcXHUwQTMyXFx1MEEzM1xcdTBBMzVcXHUwQTM2XFx1MEEzOFxcdTBBMzlcXHUwQTU5LVxcdTBBNUNcXHUwQTVFXFx1MEE3Mi1cXHUwQTc0XFx1MEE4NS1cXHUwQThEXFx1MEE4Ri1cXHUwQTkxXFx1MEE5My1cXHUwQUE4XFx1MEFBQS1cXHUwQUIwXFx1MEFCMlxcdTBBQjNcXHUwQUI1LVxcdTBBQjlcXHUwQUJEXFx1MEFEMFxcdTBBRTBcXHUwQUUxXFx1MEIwNS1cXHUwQjBDXFx1MEIwRlxcdTBCMTBcXHUwQjEzLVxcdTBCMjhcXHUwQjJBLVxcdTBCMzBcXHUwQjMyXFx1MEIzM1xcdTBCMzUtXFx1MEIzOVxcdTBCM0RcXHUwQjVDXFx1MEI1RFxcdTBCNUYtXFx1MEI2MVxcdTBCNzFcXHUwQjgzXFx1MEI4NS1cXHUwQjhBXFx1MEI4RS1cXHUwQjkwXFx1MEI5Mi1cXHUwQjk1XFx1MEI5OVxcdTBCOUFcXHUwQjlDXFx1MEI5RVxcdTBCOUZcXHUwQkEzXFx1MEJBNFxcdTBCQTgtXFx1MEJBQVxcdTBCQUUtXFx1MEJCOVxcdTBCRDBcXHUwQzA1LVxcdTBDMENcXHUwQzBFLVxcdTBDMTBcXHUwQzEyLVxcdTBDMjhcXHUwQzJBLVxcdTBDMzlcXHUwQzNEXFx1MEM1OFxcdTBDNTlcXHUwQzYwXFx1MEM2MVxcdTBDODUtXFx1MEM4Q1xcdTBDOEUtXFx1MEM5MFxcdTBDOTItXFx1MENBOFxcdTBDQUEtXFx1MENCM1xcdTBDQjUtXFx1MENCOVxcdTBDQkRcXHUwQ0RFXFx1MENFMFxcdTBDRTFcXHUwQ0YxXFx1MENGMlxcdTBEMDUtXFx1MEQwQ1xcdTBEMEUtXFx1MEQxMFxcdTBEMTItXFx1MEQzQVxcdTBEM0RcXHUwRDRFXFx1MEQ2MFxcdTBENjFcXHUwRDdBLVxcdTBEN0ZcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MEUwMS1cXHUwRTMwXFx1MEUzMlxcdTBFMzNcXHUwRTQwLVxcdTBFNDZcXHUwRTgxXFx1MEU4MlxcdTBFODRcXHUwRTg3XFx1MEU4OFxcdTBFOEFcXHUwRThEXFx1MEU5NC1cXHUwRTk3XFx1MEU5OS1cXHUwRTlGXFx1MEVBMS1cXHUwRUEzXFx1MEVBNVxcdTBFQTdcXHUwRUFBXFx1MEVBQlxcdTBFQUQtXFx1MEVCMFxcdTBFQjJcXHUwRUIzXFx1MEVCRFxcdTBFQzAtXFx1MEVDNFxcdTBFQzZcXHUwRURDLVxcdTBFREZcXHUwRjAwXFx1MEY0MC1cXHUwRjQ3XFx1MEY0OS1cXHUwRjZDXFx1MEY4OC1cXHUwRjhDXFx1MTAwMC1cXHUxMDJBXFx1MTAzRlxcdTEwNTAtXFx1MTA1NVxcdTEwNUEtXFx1MTA1RFxcdTEwNjFcXHUxMDY1XFx1MTA2NlxcdTEwNkUtXFx1MTA3MFxcdTEwNzUtXFx1MTA4MVxcdTEwOEVcXHUxMEEwLVxcdTEwQzVcXHUxMEM3XFx1MTBDRFxcdTEwRDAtXFx1MTBGQVxcdTEwRkMtXFx1MTI0OFxcdTEyNEEtXFx1MTI0RFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVBLVxcdTEyNURcXHUxMjYwLVxcdTEyODhcXHUxMjhBLVxcdTEyOERcXHUxMjkwLVxcdTEyQjBcXHUxMkIyLVxcdTEyQjVcXHUxMkI4LVxcdTEyQkVcXHUxMkMwXFx1MTJDMi1cXHUxMkM1XFx1MTJDOC1cXHUxMkQ2XFx1MTJEOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVBXFx1MTM4MC1cXHUxMzhGXFx1MTNBMC1cXHUxM0Y0XFx1MTQwMS1cXHUxNjZDXFx1MTY2Ri1cXHUxNjdGXFx1MTY4MS1cXHUxNjlBXFx1MTZBMC1cXHUxNkVBXFx1MTZFRS1cXHUxNkY4XFx1MTcwMC1cXHUxNzBDXFx1MTcwRS1cXHUxNzExXFx1MTcyMC1cXHUxNzMxXFx1MTc0MC1cXHUxNzUxXFx1MTc2MC1cXHUxNzZDXFx1MTc2RS1cXHUxNzcwXFx1MTc4MC1cXHUxN0IzXFx1MTdEN1xcdTE3RENcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4QThcXHUxOEFBXFx1MThCMC1cXHUxOEY1XFx1MTkwMC1cXHUxOTFFXFx1MTk1MC1cXHUxOTZEXFx1MTk3MC1cXHUxOTc0XFx1MTk4MC1cXHUxOUFCXFx1MTlDMS1cXHUxOUM3XFx1MUEwMC1cXHUxQTE2XFx1MUEyMC1cXHUxQTU0XFx1MUFBN1xcdTFCMDUtXFx1MUIzM1xcdTFCNDUtXFx1MUI0QlxcdTFCODMtXFx1MUJBMFxcdTFCQUVcXHUxQkFGXFx1MUJCQS1cXHUxQkU1XFx1MUMwMC1cXHUxQzIzXFx1MUM0RC1cXHUxQzRGXFx1MUM1QS1cXHUxQzdEXFx1MUNFOS1cXHUxQ0VDXFx1MUNFRS1cXHUxQ0YxXFx1MUNGNVxcdTFDRjZcXHUxRDAwLVxcdTFEQkZcXHUxRTAwLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjA3MVxcdTIwN0ZcXHUyMDkwLVxcdTIwOUNcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE2MC1cXHUyMTg4XFx1MkMwMC1cXHUyQzJFXFx1MkMzMC1cXHUyQzVFXFx1MkM2MC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0VFXFx1MkNGMlxcdTJDRjNcXHUyRDAwLVxcdTJEMjVcXHUyRDI3XFx1MkQyRFxcdTJEMzAtXFx1MkQ2N1xcdTJENkZcXHUyRDgwLVxcdTJEOTZcXHUyREEwLVxcdTJEQTZcXHUyREE4LVxcdTJEQUVcXHUyREIwLVxcdTJEQjZcXHUyREI4LVxcdTJEQkVcXHUyREMwLVxcdTJEQzZcXHUyREM4LVxcdTJEQ0VcXHUyREQwLVxcdTJERDZcXHUyREQ4LVxcdTJEREVcXHUyRTJGXFx1MzAwNS1cXHUzMDA3XFx1MzAyMS1cXHUzMDI5XFx1MzAzMS1cXHUzMDM1XFx1MzAzOC1cXHUzMDNDXFx1MzA0MS1cXHUzMDk2XFx1MzA5RC1cXHUzMDlGXFx1MzBBMS1cXHUzMEZBXFx1MzBGQy1cXHUzMEZGXFx1MzEwNS1cXHUzMTJEXFx1MzEzMS1cXHUzMThFXFx1MzFBMC1cXHUzMUJBXFx1MzFGMC1cXHUzMUZGXFx1MzQwMC1cXHU0REI1XFx1NEUwMC1cXHU5RkNDXFx1QTAwMC1cXHVBNDhDXFx1QTREMC1cXHVBNEZEXFx1QTUwMC1cXHVBNjBDXFx1QTYxMC1cXHVBNjFGXFx1QTYyQVxcdUE2MkJcXHVBNjQwLVxcdUE2NkVcXHVBNjdGLVxcdUE2OURcXHVBNkEwLVxcdUE2RUZcXHVBNzE3LVxcdUE3MUZcXHVBNzIyLVxcdUE3ODhcXHVBNzhCLVxcdUE3OEVcXHVBNzkwLVxcdUE3QURcXHVBN0IwXFx1QTdCMVxcdUE3RjctXFx1QTgwMVxcdUE4MDMtXFx1QTgwNVxcdUE4MDctXFx1QTgwQVxcdUE4MEMtXFx1QTgyMlxcdUE4NDAtXFx1QTg3M1xcdUE4ODItXFx1QThCM1xcdUE4RjItXFx1QThGN1xcdUE4RkJcXHVBOTBBLVxcdUE5MjVcXHVBOTMwLVxcdUE5NDZcXHVBOTYwLVxcdUE5N0NcXHVBOTg0LVxcdUE5QjJcXHVBOUNGXFx1QTlFMC1cXHVBOUU0XFx1QTlFNi1cXHVBOUVGXFx1QTlGQS1cXHVBOUZFXFx1QUEwMC1cXHVBQTI4XFx1QUE0MC1cXHVBQTQyXFx1QUE0NC1cXHVBQTRCXFx1QUE2MC1cXHVBQTc2XFx1QUE3QVxcdUFBN0UtXFx1QUFBRlxcdUFBQjFcXHVBQUI1XFx1QUFCNlxcdUFBQjktXFx1QUFCRFxcdUFBQzBcXHVBQUMyXFx1QUFEQi1cXHVBQUREXFx1QUFFMC1cXHVBQUVBXFx1QUFGMi1cXHVBQUY0XFx1QUIwMS1cXHVBQjA2XFx1QUIwOS1cXHVBQjBFXFx1QUIxMS1cXHVBQjE2XFx1QUIyMC1cXHVBQjI2XFx1QUIyOC1cXHVBQjJFXFx1QUIzMC1cXHVBQjVBXFx1QUI1Qy1cXHVBQjVGXFx1QUI2NFxcdUFCNjVcXHVBQkMwLVxcdUFCRTJcXHVBQzAwLVxcdUQ3QTNcXHVEN0IwLVxcdUQ3QzZcXHVEN0NCLVxcdUQ3RkJcXHVGOTAwLVxcdUZBNkRcXHVGQTcwLVxcdUZBRDlcXHVGQjAwLVxcdUZCMDZcXHVGQjEzLVxcdUZCMTdcXHVGQjFEXFx1RkIxRi1cXHVGQjI4XFx1RkIyQS1cXHVGQjM2XFx1RkIzOC1cXHVGQjNDXFx1RkIzRVxcdUZCNDBcXHVGQjQxXFx1RkI0M1xcdUZCNDRcXHVGQjQ2LVxcdUZCQjFcXHVGQkQzLVxcdUZEM0RcXHVGRDUwLVxcdUZEOEZcXHVGRDkyLVxcdUZEQzdcXHVGREYwLVxcdUZERkJcXHVGRTcwLVxcdUZFNzRcXHVGRTc2LVxcdUZFRkNcXHVGRjIxLVxcdUZGM0FcXHVGRjQxLVxcdUZGNUFcXHVGRjY2LVxcdUZGQkVcXHVGRkMyLVxcdUZGQzdcXHVGRkNBLVxcdUZGQ0ZcXHVGRkQyLVxcdUZGRDdcXHVGRkRBLVxcdUZGRENdJyk7XG52YXIgUmVnZXhOb25Bc2NpaUlkZW50aWZpZXJQYXJ0ID0gbmV3IFJlZ0V4cCgnW1xceEFBXFx4QjVcXHhCQVxceEMwLVxceEQ2XFx4RDgtXFx4RjZcXHhGOC1cXHUwMkMxXFx1MDJDNi1cXHUwMkQxXFx1MDJFMC1cXHUwMkU0XFx1MDJFQ1xcdTAyRUVcXHUwMzAwLVxcdTAzNzRcXHUwMzc2XFx1MDM3N1xcdTAzN0EtXFx1MDM3RFxcdTAzN0ZcXHUwMzg2XFx1MDM4OC1cXHUwMzhBXFx1MDM4Q1xcdTAzOEUtXFx1MDNBMVxcdTAzQTMtXFx1MDNGNVxcdTAzRjctXFx1MDQ4MVxcdTA0ODMtXFx1MDQ4N1xcdTA0OEEtXFx1MDUyRlxcdTA1MzEtXFx1MDU1NlxcdTA1NTlcXHUwNTYxLVxcdTA1ODdcXHUwNTkxLVxcdTA1QkRcXHUwNUJGXFx1MDVDMVxcdTA1QzJcXHUwNUM0XFx1MDVDNVxcdTA1QzdcXHUwNUQwLVxcdTA1RUFcXHUwNUYwLVxcdTA1RjJcXHUwNjEwLVxcdTA2MUFcXHUwNjIwLVxcdTA2NjlcXHUwNjZFLVxcdTA2RDNcXHUwNkQ1LVxcdTA2RENcXHUwNkRGLVxcdTA2RThcXHUwNkVBLVxcdTA2RkNcXHUwNkZGXFx1MDcxMC1cXHUwNzRBXFx1MDc0RC1cXHUwN0IxXFx1MDdDMC1cXHUwN0Y1XFx1MDdGQVxcdTA4MDAtXFx1MDgyRFxcdTA4NDAtXFx1MDg1QlxcdTA4QTAtXFx1MDhCMlxcdTA4RTQtXFx1MDk2M1xcdTA5NjYtXFx1MDk2RlxcdTA5NzEtXFx1MDk4M1xcdTA5ODUtXFx1MDk4Q1xcdTA5OEZcXHUwOTkwXFx1MDk5My1cXHUwOUE4XFx1MDlBQS1cXHUwOUIwXFx1MDlCMlxcdTA5QjYtXFx1MDlCOVxcdTA5QkMtXFx1MDlDNFxcdTA5QzdcXHUwOUM4XFx1MDlDQi1cXHUwOUNFXFx1MDlEN1xcdTA5RENcXHUwOUREXFx1MDlERi1cXHUwOUUzXFx1MDlFNi1cXHUwOUYxXFx1MEEwMS1cXHUwQTAzXFx1MEEwNS1cXHUwQTBBXFx1MEEwRlxcdTBBMTBcXHUwQTEzLVxcdTBBMjhcXHUwQTJBLVxcdTBBMzBcXHUwQTMyXFx1MEEzM1xcdTBBMzVcXHUwQTM2XFx1MEEzOFxcdTBBMzlcXHUwQTNDXFx1MEEzRS1cXHUwQTQyXFx1MEE0N1xcdTBBNDhcXHUwQTRCLVxcdTBBNERcXHUwQTUxXFx1MEE1OS1cXHUwQTVDXFx1MEE1RVxcdTBBNjYtXFx1MEE3NVxcdTBBODEtXFx1MEE4M1xcdTBBODUtXFx1MEE4RFxcdTBBOEYtXFx1MEE5MVxcdTBBOTMtXFx1MEFBOFxcdTBBQUEtXFx1MEFCMFxcdTBBQjJcXHUwQUIzXFx1MEFCNS1cXHUwQUI5XFx1MEFCQy1cXHUwQUM1XFx1MEFDNy1cXHUwQUM5XFx1MEFDQi1cXHUwQUNEXFx1MEFEMFxcdTBBRTAtXFx1MEFFM1xcdTBBRTYtXFx1MEFFRlxcdTBCMDEtXFx1MEIwM1xcdTBCMDUtXFx1MEIwQ1xcdTBCMEZcXHUwQjEwXFx1MEIxMy1cXHUwQjI4XFx1MEIyQS1cXHUwQjMwXFx1MEIzMlxcdTBCMzNcXHUwQjM1LVxcdTBCMzlcXHUwQjNDLVxcdTBCNDRcXHUwQjQ3XFx1MEI0OFxcdTBCNEItXFx1MEI0RFxcdTBCNTZcXHUwQjU3XFx1MEI1Q1xcdTBCNURcXHUwQjVGLVxcdTBCNjNcXHUwQjY2LVxcdTBCNkZcXHUwQjcxXFx1MEI4MlxcdTBCODNcXHUwQjg1LVxcdTBCOEFcXHUwQjhFLVxcdTBCOTBcXHUwQjkyLVxcdTBCOTVcXHUwQjk5XFx1MEI5QVxcdTBCOUNcXHUwQjlFXFx1MEI5RlxcdTBCQTNcXHUwQkE0XFx1MEJBOC1cXHUwQkFBXFx1MEJBRS1cXHUwQkI5XFx1MEJCRS1cXHUwQkMyXFx1MEJDNi1cXHUwQkM4XFx1MEJDQS1cXHUwQkNEXFx1MEJEMFxcdTBCRDdcXHUwQkU2LVxcdTBCRUZcXHUwQzAwLVxcdTBDMDNcXHUwQzA1LVxcdTBDMENcXHUwQzBFLVxcdTBDMTBcXHUwQzEyLVxcdTBDMjhcXHUwQzJBLVxcdTBDMzlcXHUwQzNELVxcdTBDNDRcXHUwQzQ2LVxcdTBDNDhcXHUwQzRBLVxcdTBDNERcXHUwQzU1XFx1MEM1NlxcdTBDNThcXHUwQzU5XFx1MEM2MC1cXHUwQzYzXFx1MEM2Ni1cXHUwQzZGXFx1MEM4MS1cXHUwQzgzXFx1MEM4NS1cXHUwQzhDXFx1MEM4RS1cXHUwQzkwXFx1MEM5Mi1cXHUwQ0E4XFx1MENBQS1cXHUwQ0IzXFx1MENCNS1cXHUwQ0I5XFx1MENCQy1cXHUwQ0M0XFx1MENDNi1cXHUwQ0M4XFx1MENDQS1cXHUwQ0NEXFx1MENENVxcdTBDRDZcXHUwQ0RFXFx1MENFMC1cXHUwQ0UzXFx1MENFNi1cXHUwQ0VGXFx1MENGMVxcdTBDRjJcXHUwRDAxLVxcdTBEMDNcXHUwRDA1LVxcdTBEMENcXHUwRDBFLVxcdTBEMTBcXHUwRDEyLVxcdTBEM0FcXHUwRDNELVxcdTBENDRcXHUwRDQ2LVxcdTBENDhcXHUwRDRBLVxcdTBENEVcXHUwRDU3XFx1MEQ2MC1cXHUwRDYzXFx1MEQ2Ni1cXHUwRDZGXFx1MEQ3QS1cXHUwRDdGXFx1MEQ4MlxcdTBEODNcXHUwRDg1LVxcdTBEOTZcXHUwRDlBLVxcdTBEQjFcXHUwREIzLVxcdTBEQkJcXHUwREJEXFx1MERDMC1cXHUwREM2XFx1MERDQVxcdTBEQ0YtXFx1MERENFxcdTBERDZcXHUwREQ4LVxcdTBEREZcXHUwREU2LVxcdTBERUZcXHUwREYyXFx1MERGM1xcdTBFMDEtXFx1MEUzQVxcdTBFNDAtXFx1MEU0RVxcdTBFNTAtXFx1MEU1OVxcdTBFODFcXHUwRTgyXFx1MEU4NFxcdTBFODdcXHUwRTg4XFx1MEU4QVxcdTBFOERcXHUwRTk0LVxcdTBFOTdcXHUwRTk5LVxcdTBFOUZcXHUwRUExLVxcdTBFQTNcXHUwRUE1XFx1MEVBN1xcdTBFQUFcXHUwRUFCXFx1MEVBRC1cXHUwRUI5XFx1MEVCQi1cXHUwRUJEXFx1MEVDMC1cXHUwRUM0XFx1MEVDNlxcdTBFQzgtXFx1MEVDRFxcdTBFRDAtXFx1MEVEOVxcdTBFREMtXFx1MEVERlxcdTBGMDBcXHUwRjE4XFx1MEYxOVxcdTBGMjAtXFx1MEYyOVxcdTBGMzVcXHUwRjM3XFx1MEYzOVxcdTBGM0UtXFx1MEY0N1xcdTBGNDktXFx1MEY2Q1xcdTBGNzEtXFx1MEY4NFxcdTBGODYtXFx1MEY5N1xcdTBGOTktXFx1MEZCQ1xcdTBGQzZcXHUxMDAwLVxcdTEwNDlcXHUxMDUwLVxcdTEwOURcXHUxMEEwLVxcdTEwQzVcXHUxMEM3XFx1MTBDRFxcdTEwRDAtXFx1MTBGQVxcdTEwRkMtXFx1MTI0OFxcdTEyNEEtXFx1MTI0RFxcdTEyNTAtXFx1MTI1NlxcdTEyNThcXHUxMjVBLVxcdTEyNURcXHUxMjYwLVxcdTEyODhcXHUxMjhBLVxcdTEyOERcXHUxMjkwLVxcdTEyQjBcXHUxMkIyLVxcdTEyQjVcXHUxMkI4LVxcdTEyQkVcXHUxMkMwXFx1MTJDMi1cXHUxMkM1XFx1MTJDOC1cXHUxMkQ2XFx1MTJEOC1cXHUxMzEwXFx1MTMxMi1cXHUxMzE1XFx1MTMxOC1cXHUxMzVBXFx1MTM1RC1cXHUxMzVGXFx1MTM4MC1cXHUxMzhGXFx1MTNBMC1cXHUxM0Y0XFx1MTQwMS1cXHUxNjZDXFx1MTY2Ri1cXHUxNjdGXFx1MTY4MS1cXHUxNjlBXFx1MTZBMC1cXHUxNkVBXFx1MTZFRS1cXHUxNkY4XFx1MTcwMC1cXHUxNzBDXFx1MTcwRS1cXHUxNzE0XFx1MTcyMC1cXHUxNzM0XFx1MTc0MC1cXHUxNzUzXFx1MTc2MC1cXHUxNzZDXFx1MTc2RS1cXHUxNzcwXFx1MTc3MlxcdTE3NzNcXHUxNzgwLVxcdTE3RDNcXHUxN0Q3XFx1MTdEQ1xcdTE3RERcXHUxN0UwLVxcdTE3RTlcXHUxODBCLVxcdTE4MERcXHUxODEwLVxcdTE4MTlcXHUxODIwLVxcdTE4NzdcXHUxODgwLVxcdTE4QUFcXHUxOEIwLVxcdTE4RjVcXHUxOTAwLVxcdTE5MUVcXHUxOTIwLVxcdTE5MkJcXHUxOTMwLVxcdTE5M0JcXHUxOTQ2LVxcdTE5NkRcXHUxOTcwLVxcdTE5NzRcXHUxOTgwLVxcdTE5QUJcXHUxOUIwLVxcdTE5QzlcXHUxOUQwLVxcdTE5RDlcXHUxQTAwLVxcdTFBMUJcXHUxQTIwLVxcdTFBNUVcXHUxQTYwLVxcdTFBN0NcXHUxQTdGLVxcdTFBODlcXHUxQTkwLVxcdTFBOTlcXHUxQUE3XFx1MUFCMC1cXHUxQUJEXFx1MUIwMC1cXHUxQjRCXFx1MUI1MC1cXHUxQjU5XFx1MUI2Qi1cXHUxQjczXFx1MUI4MC1cXHUxQkYzXFx1MUMwMC1cXHUxQzM3XFx1MUM0MC1cXHUxQzQ5XFx1MUM0RC1cXHUxQzdEXFx1MUNEMC1cXHUxQ0QyXFx1MUNENC1cXHUxQ0Y2XFx1MUNGOFxcdTFDRjlcXHUxRDAwLVxcdTFERjVcXHUxREZDLVxcdTFGMTVcXHUxRjE4LVxcdTFGMURcXHUxRjIwLVxcdTFGNDVcXHUxRjQ4LVxcdTFGNERcXHUxRjUwLVxcdTFGNTdcXHUxRjU5XFx1MUY1QlxcdTFGNURcXHUxRjVGLVxcdTFGN0RcXHUxRjgwLVxcdTFGQjRcXHUxRkI2LVxcdTFGQkNcXHUxRkJFXFx1MUZDMi1cXHUxRkM0XFx1MUZDNi1cXHUxRkNDXFx1MUZEMC1cXHUxRkQzXFx1MUZENi1cXHUxRkRCXFx1MUZFMC1cXHUxRkVDXFx1MUZGMi1cXHUxRkY0XFx1MUZGNi1cXHUxRkZDXFx1MjAwQ1xcdTIwMERcXHUyMDNGXFx1MjA0MFxcdTIwNTRcXHUyMDcxXFx1MjA3RlxcdTIwOTAtXFx1MjA5Q1xcdTIwRDAtXFx1MjBEQ1xcdTIwRTFcXHUyMEU1LVxcdTIwRjBcXHUyMTAyXFx1MjEwN1xcdTIxMEEtXFx1MjExM1xcdTIxMTVcXHUyMTE5LVxcdTIxMURcXHUyMTI0XFx1MjEyNlxcdTIxMjhcXHUyMTJBLVxcdTIxMkRcXHUyMTJGLVxcdTIxMzlcXHUyMTNDLVxcdTIxM0ZcXHUyMTQ1LVxcdTIxNDlcXHUyMTRFXFx1MjE2MC1cXHUyMTg4XFx1MkMwMC1cXHUyQzJFXFx1MkMzMC1cXHUyQzVFXFx1MkM2MC1cXHUyQ0U0XFx1MkNFQi1cXHUyQ0YzXFx1MkQwMC1cXHUyRDI1XFx1MkQyN1xcdTJEMkRcXHUyRDMwLVxcdTJENjdcXHUyRDZGXFx1MkQ3Ri1cXHUyRDk2XFx1MkRBMC1cXHUyREE2XFx1MkRBOC1cXHUyREFFXFx1MkRCMC1cXHUyREI2XFx1MkRCOC1cXHUyREJFXFx1MkRDMC1cXHUyREM2XFx1MkRDOC1cXHUyRENFXFx1MkREMC1cXHUyREQ2XFx1MkREOC1cXHUyRERFXFx1MkRFMC1cXHUyREZGXFx1MkUyRlxcdTMwMDUtXFx1MzAwN1xcdTMwMjEtXFx1MzAyRlxcdTMwMzEtXFx1MzAzNVxcdTMwMzgtXFx1MzAzQ1xcdTMwNDEtXFx1MzA5NlxcdTMwOTlcXHUzMDlBXFx1MzA5RC1cXHUzMDlGXFx1MzBBMS1cXHUzMEZBXFx1MzBGQy1cXHUzMEZGXFx1MzEwNS1cXHUzMTJEXFx1MzEzMS1cXHUzMThFXFx1MzFBMC1cXHUzMUJBXFx1MzFGMC1cXHUzMUZGXFx1MzQwMC1cXHU0REI1XFx1NEUwMC1cXHU5RkNDXFx1QTAwMC1cXHVBNDhDXFx1QTREMC1cXHVBNEZEXFx1QTUwMC1cXHVBNjBDXFx1QTYxMC1cXHVBNjJCXFx1QTY0MC1cXHVBNjZGXFx1QTY3NC1cXHVBNjdEXFx1QTY3Ri1cXHVBNjlEXFx1QTY5Ri1cXHVBNkYxXFx1QTcxNy1cXHVBNzFGXFx1QTcyMi1cXHVBNzg4XFx1QTc4Qi1cXHVBNzhFXFx1QTc5MC1cXHVBN0FEXFx1QTdCMFxcdUE3QjFcXHVBN0Y3LVxcdUE4MjdcXHVBODQwLVxcdUE4NzNcXHVBODgwLVxcdUE4QzRcXHVBOEQwLVxcdUE4RDlcXHVBOEUwLVxcdUE4RjdcXHVBOEZCXFx1QTkwMC1cXHVBOTJEXFx1QTkzMC1cXHVBOTUzXFx1QTk2MC1cXHVBOTdDXFx1QTk4MC1cXHVBOUMwXFx1QTlDRi1cXHVBOUQ5XFx1QTlFMC1cXHVBOUZFXFx1QUEwMC1cXHVBQTM2XFx1QUE0MC1cXHVBQTREXFx1QUE1MC1cXHVBQTU5XFx1QUE2MC1cXHVBQTc2XFx1QUE3QS1cXHVBQUMyXFx1QUFEQi1cXHVBQUREXFx1QUFFMC1cXHVBQUVGXFx1QUFGMi1cXHVBQUY2XFx1QUIwMS1cXHVBQjA2XFx1QUIwOS1cXHVBQjBFXFx1QUIxMS1cXHVBQjE2XFx1QUIyMC1cXHVBQjI2XFx1QUIyOC1cXHVBQjJFXFx1QUIzMC1cXHVBQjVBXFx1QUI1Qy1cXHVBQjVGXFx1QUI2NFxcdUFCNjVcXHVBQkMwLVxcdUFCRUFcXHVBQkVDXFx1QUJFRFxcdUFCRjAtXFx1QUJGOVxcdUFDMDAtXFx1RDdBM1xcdUQ3QjAtXFx1RDdDNlxcdUQ3Q0ItXFx1RDdGQlxcdUY5MDAtXFx1RkE2RFxcdUZBNzAtXFx1RkFEOVxcdUZCMDAtXFx1RkIwNlxcdUZCMTMtXFx1RkIxN1xcdUZCMUQtXFx1RkIyOFxcdUZCMkEtXFx1RkIzNlxcdUZCMzgtXFx1RkIzQ1xcdUZCM0VcXHVGQjQwXFx1RkI0MVxcdUZCNDNcXHVGQjQ0XFx1RkI0Ni1cXHVGQkIxXFx1RkJEMy1cXHVGRDNEXFx1RkQ1MC1cXHVGRDhGXFx1RkQ5Mi1cXHVGREM3XFx1RkRGMC1cXHVGREZCXFx1RkUwMC1cXHVGRTBGXFx1RkUyMC1cXHVGRTJEXFx1RkUzM1xcdUZFMzRcXHVGRTRELVxcdUZFNEZcXHVGRTcwLVxcdUZFNzRcXHVGRTc2LVxcdUZFRkNcXHVGRjEwLVxcdUZGMTlcXHVGRjIxLVxcdUZGM0FcXHVGRjNGXFx1RkY0MS1cXHVGRjVBXFx1RkY2Ni1cXHVGRkJFXFx1RkZDMi1cXHVGRkM3XFx1RkZDQS1cXHVGRkNGXFx1RkZEMi1cXHVGRkQ3XFx1RkZEQS1cXHVGRkRDXScpO1xuXG4vLyBFbnN1cmUgdGhlIGNvbmRpdGlvbiBpcyB0cnVlLCBvdGhlcndpc2UgdGhyb3cgYW4gZXJyb3IuXG4vLyBUaGlzIGlzIG9ubHkgdG8gaGF2ZSBhIGJldHRlciBjb250cmFjdCBzZW1hbnRpYywgaS5lLiBhbm90aGVyIHNhZmV0eSBuZXRcbi8vIHRvIGNhdGNoIGEgbG9naWMgZXJyb3IuIFRoZSBjb25kaXRpb24gc2hhbGwgYmUgZnVsZmlsbGVkIGluIG5vcm1hbCBjYXNlLlxuLy8gRG8gTk9UIHVzZSB0aGlzIHRvIGVuZm9yY2UgYSBjZXJ0YWluIGNvbmRpdGlvbiBvbiBhbnkgdXNlciBpbnB1dC5cblxuZnVuY3Rpb24gYXNzZXJ0KGNvbmRpdGlvbiwgbWVzc2FnZSkge1xuICAvKiBpc3RhbmJ1bCBpZ25vcmUgbmV4dCAqL1xuICBpZiAoIWNvbmRpdGlvbikge1xuICAgIHRocm93IG5ldyBFcnJvcignQVNTRVJUOiAnICsgbWVzc2FnZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaXNEZWNpbWFsRGlnaXQoY2gpIHtcbiAgcmV0dXJuIChjaCA+PSAweDMwICYmIGNoIDw9IDB4MzkpOyAvLyAwLi45XG59XG5cbmZ1bmN0aW9uIGlzSGV4RGlnaXQoY2gpIHtcbiAgcmV0dXJuICcwMTIzNDU2Nzg5YWJjZGVmQUJDREVGJy5pbmRleE9mKGNoKSA+PSAwO1xufVxuXG5mdW5jdGlvbiBpc09jdGFsRGlnaXQoY2gpIHtcbiAgcmV0dXJuICcwMTIzNDU2NycuaW5kZXhPZihjaCkgPj0gMDtcbn1cblxuLy8gNy4yIFdoaXRlIFNwYWNlXG5cbmZ1bmN0aW9uIGlzV2hpdGVTcGFjZShjaCkge1xuICByZXR1cm4gKGNoID09PSAweDIwKSB8fCAoY2ggPT09IDB4MDkpIHx8IChjaCA9PT0gMHgwQikgfHwgKGNoID09PSAweDBDKSB8fCAoY2ggPT09IDB4QTApIHx8XG4gICAgKGNoID49IDB4MTY4MCAmJiBbMHgxNjgwLCAweDE4MEUsIDB4MjAwMCwgMHgyMDAxLCAweDIwMDIsIDB4MjAwMywgMHgyMDA0LCAweDIwMDUsIDB4MjAwNiwgMHgyMDA3LCAweDIwMDgsIDB4MjAwOSwgMHgyMDBBLCAweDIwMkYsIDB4MjA1RiwgMHgzMDAwLCAweEZFRkZdLmluZGV4T2YoY2gpID49IDApO1xufVxuXG4vLyA3LjMgTGluZSBUZXJtaW5hdG9yc1xuXG5mdW5jdGlvbiBpc0xpbmVUZXJtaW5hdG9yKGNoKSB7XG4gIHJldHVybiAoY2ggPT09IDB4MEEpIHx8IChjaCA9PT0gMHgwRCkgfHwgKGNoID09PSAweDIwMjgpIHx8IChjaCA9PT0gMHgyMDI5KTtcbn1cblxuLy8gNy42IElkZW50aWZpZXIgTmFtZXMgYW5kIElkZW50aWZpZXJzXG5cbmZ1bmN0aW9uIGlzSWRlbnRpZmllclN0YXJ0KGNoKSB7XG4gIHJldHVybiAoY2ggPT09IDB4MjQpIHx8IChjaCA9PT0gMHg1RikgfHwgLy8gJCAoZG9sbGFyKSBhbmQgXyAodW5kZXJzY29yZSlcbiAgICAoY2ggPj0gMHg0MSAmJiBjaCA8PSAweDVBKSB8fCAvLyBBLi5aXG4gICAgKGNoID49IDB4NjEgJiYgY2ggPD0gMHg3QSkgfHwgLy8gYS4uelxuICAgIChjaCA9PT0gMHg1QykgfHwgLy8gXFwgKGJhY2tzbGFzaClcbiAgICAoKGNoID49IDB4ODApICYmIFJlZ2V4Tm9uQXNjaWlJZGVudGlmaWVyU3RhcnQudGVzdChTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKSkpO1xufVxuXG5mdW5jdGlvbiBpc0lkZW50aWZpZXJQYXJ0KGNoKSB7XG4gIHJldHVybiAoY2ggPT09IDB4MjQpIHx8IChjaCA9PT0gMHg1RikgfHwgLy8gJCAoZG9sbGFyKSBhbmQgXyAodW5kZXJzY29yZSlcbiAgICAoY2ggPj0gMHg0MSAmJiBjaCA8PSAweDVBKSB8fCAvLyBBLi5aXG4gICAgKGNoID49IDB4NjEgJiYgY2ggPD0gMHg3QSkgfHwgLy8gYS4uelxuICAgIChjaCA+PSAweDMwICYmIGNoIDw9IDB4MzkpIHx8IC8vIDAuLjlcbiAgICAoY2ggPT09IDB4NUMpIHx8IC8vIFxcIChiYWNrc2xhc2gpXG4gICAgKChjaCA+PSAweDgwKSAmJiBSZWdleE5vbkFzY2lpSWRlbnRpZmllclBhcnQudGVzdChTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKSkpO1xufVxuXG4vLyA3LjYuMS4xIEtleXdvcmRzXG5cbnZhciBrZXl3b3JkcyQxID0ge1xuICAnaWYnOjEsICdpbic6MSwgJ2RvJzoxLFxuICAndmFyJzoxLCAnZm9yJzoxLCAnbmV3JzoxLCAndHJ5JzoxLCAnbGV0JzoxLFxuICAndGhpcyc6MSwgJ2Vsc2UnOjEsICdjYXNlJzoxLCAndm9pZCc6MSwgJ3dpdGgnOjEsICdlbnVtJzoxLFxuICAnd2hpbGUnOjEsICdicmVhayc6MSwgJ2NhdGNoJzoxLCAndGhyb3cnOjEsICdjb25zdCc6MSwgJ3lpZWxkJzoxLCAnY2xhc3MnOjEsICdzdXBlcic6MSxcbiAgJ3JldHVybic6MSwgJ3R5cGVvZic6MSwgJ2RlbGV0ZSc6MSwgJ3N3aXRjaCc6MSwgJ2V4cG9ydCc6MSwgJ2ltcG9ydCc6MSwgJ3B1YmxpYyc6MSwgJ3N0YXRpYyc6MSxcbiAgJ2RlZmF1bHQnOjEsICdmaW5hbGx5JzoxLCAnZXh0ZW5kcyc6MSwgJ3BhY2thZ2UnOjEsICdwcml2YXRlJzoxLFxuICAnZnVuY3Rpb24nOjEsICdjb250aW51ZSc6MSwgJ2RlYnVnZ2VyJzoxLFxuICAnaW50ZXJmYWNlJzoxLCAncHJvdGVjdGVkJzoxLFxuICAnaW5zdGFuY2VvZic6MSwgJ2ltcGxlbWVudHMnOjFcbn07XG5cbmZ1bmN0aW9uIHNraXBDb21tZW50KCkge1xuICB2YXIgY2g7XG5cbiAgd2hpbGUgKGluZGV4JDEgPCBsZW5ndGgkMikge1xuICAgIGNoID0gc291cmNlJDEuY2hhckNvZGVBdChpbmRleCQxKTtcblxuICAgIGlmIChpc1doaXRlU3BhY2UoY2gpIHx8IGlzTGluZVRlcm1pbmF0b3IoY2gpKSB7XG4gICAgICArK2luZGV4JDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzY2FuSGV4RXNjYXBlKHByZWZpeCkge1xuICB2YXIgaSwgbGVuLCBjaCwgY29kZSA9IDA7XG5cbiAgbGVuID0gKHByZWZpeCA9PT0gJ3UnKSA/IDQgOiAyO1xuICBmb3IgKGkgPSAwOyBpIDwgbGVuOyArK2kpIHtcbiAgICBpZiAoaW5kZXgkMSA8IGxlbmd0aCQyICYmIGlzSGV4RGlnaXQoc291cmNlJDFbaW5kZXgkMV0pKSB7XG4gICAgICBjaCA9IHNvdXJjZSQxW2luZGV4JDErK107XG4gICAgICBjb2RlID0gY29kZSAqIDE2ICsgJzAxMjM0NTY3ODlhYmNkZWYnLmluZGV4T2YoY2gudG9Mb3dlckNhc2UoKSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VVbmV4cGVjdGVkVG9rZW4sIElMTEVHQUwpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbn1cblxuZnVuY3Rpb24gc2NhblVuaWNvZGVDb2RlUG9pbnRFc2NhcGUoKSB7XG4gIHZhciBjaCwgY29kZSwgY3UxLCBjdTI7XG5cbiAgY2ggPSBzb3VyY2UkMVtpbmRleCQxXTtcbiAgY29kZSA9IDA7XG5cbiAgLy8gQXQgbGVhc3QsIG9uZSBoZXggZGlnaXQgaXMgcmVxdWlyZWQuXG4gIGlmIChjaCA9PT0gJ30nKSB7XG4gICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZVVuZXhwZWN0ZWRUb2tlbiwgSUxMRUdBTCk7XG4gIH1cblxuICB3aGlsZSAoaW5kZXgkMSA8IGxlbmd0aCQyKSB7XG4gICAgY2ggPSBzb3VyY2UkMVtpbmRleCQxKytdO1xuICAgIGlmICghaXNIZXhEaWdpdChjaCkpIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgICBjb2RlID0gY29kZSAqIDE2ICsgJzAxMjM0NTY3ODlhYmNkZWYnLmluZGV4T2YoY2gudG9Mb3dlckNhc2UoKSk7XG4gIH1cblxuICBpZiAoY29kZSA+IDB4MTBGRkZGIHx8IGNoICE9PSAnfScpIHtcbiAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgfVxuXG4gIC8vIFVURi0xNiBFbmNvZGluZ1xuICBpZiAoY29kZSA8PSAweEZGRkYpIHtcbiAgICByZXR1cm4gU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKTtcbiAgfVxuICBjdTEgPSAoKGNvZGUgLSAweDEwMDAwKSA+PiAxMCkgKyAweEQ4MDA7XG4gIGN1MiA9ICgoY29kZSAtIDB4MTAwMDApICYgMTAyMykgKyAweERDMDA7XG4gIHJldHVybiBTdHJpbmcuZnJvbUNoYXJDb2RlKGN1MSwgY3UyKTtcbn1cblxuZnVuY3Rpb24gZ2V0RXNjYXBlZElkZW50aWZpZXIoKSB7XG4gIHZhciBjaCwgaWQ7XG5cbiAgY2ggPSBzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDErKyk7XG4gIGlkID0gU3RyaW5nLmZyb21DaGFyQ29kZShjaCk7XG5cbiAgLy8gJ1xcdScgKFUrMDA1QywgVSswMDc1KSBkZW5vdGVzIGFuIGVzY2FwZWQgY2hhcmFjdGVyLlxuICBpZiAoY2ggPT09IDB4NUMpIHtcbiAgICBpZiAoc291cmNlJDEuY2hhckNvZGVBdChpbmRleCQxKSAhPT0gMHg3NSkge1xuICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZVVuZXhwZWN0ZWRUb2tlbiwgSUxMRUdBTCk7XG4gICAgfVxuICAgICsraW5kZXgkMTtcbiAgICBjaCA9IHNjYW5IZXhFc2NhcGUoJ3UnKTtcbiAgICBpZiAoIWNoIHx8IGNoID09PSAnXFxcXCcgfHwgIWlzSWRlbnRpZmllclN0YXJ0KGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgICB9XG4gICAgaWQgPSBjaDtcbiAgfVxuXG4gIHdoaWxlIChpbmRleCQxIDwgbGVuZ3RoJDIpIHtcbiAgICBjaCA9IHNvdXJjZSQxLmNoYXJDb2RlQXQoaW5kZXgkMSk7XG4gICAgaWYgKCFpc0lkZW50aWZpZXJQYXJ0KGNoKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgICsraW5kZXgkMTtcbiAgICBpZCArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNoKTtcblxuICAgIC8vICdcXHUnIChVKzAwNUMsIFUrMDA3NSkgZGVub3RlcyBhbiBlc2NhcGVkIGNoYXJhY3Rlci5cbiAgICBpZiAoY2ggPT09IDB4NUMpIHtcbiAgICAgIGlkID0gaWQuc3Vic3RyKDAsIGlkLmxlbmd0aCAtIDEpO1xuICAgICAgaWYgKHNvdXJjZSQxLmNoYXJDb2RlQXQoaW5kZXgkMSkgIT09IDB4NzUpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZVVuZXhwZWN0ZWRUb2tlbiwgSUxMRUdBTCk7XG4gICAgICB9XG4gICAgICArK2luZGV4JDE7XG4gICAgICBjaCA9IHNjYW5IZXhFc2NhcGUoJ3UnKTtcbiAgICAgIGlmICghY2ggfHwgY2ggPT09ICdcXFxcJyB8fCAhaXNJZGVudGlmaWVyUGFydChjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgICAgIH1cbiAgICAgIGlkICs9IGNoO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBpZDtcbn1cblxuZnVuY3Rpb24gZ2V0SWRlbnRpZmllcigpIHtcbiAgdmFyIHN0YXJ0LCBjaDtcblxuICBzdGFydCA9IGluZGV4JDErKztcbiAgd2hpbGUgKGluZGV4JDEgPCBsZW5ndGgkMikge1xuICAgIGNoID0gc291cmNlJDEuY2hhckNvZGVBdChpbmRleCQxKTtcbiAgICBpZiAoY2ggPT09IDB4NUMpIHtcbiAgICAgIC8vIEJsYWNrc2xhc2ggKFUrMDA1QykgbWFya3MgVW5pY29kZSBlc2NhcGUgc2VxdWVuY2UuXG4gICAgICBpbmRleCQxID0gc3RhcnQ7XG4gICAgICByZXR1cm4gZ2V0RXNjYXBlZElkZW50aWZpZXIoKTtcbiAgICB9XG4gICAgaWYgKGlzSWRlbnRpZmllclBhcnQoY2gpKSB7XG4gICAgICArK2luZGV4JDE7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBzb3VyY2UkMS5zbGljZShzdGFydCwgaW5kZXgkMSk7XG59XG5cbmZ1bmN0aW9uIHNjYW5JZGVudGlmaWVyKCkge1xuICB2YXIgc3RhcnQsIGlkLCB0eXBlO1xuXG4gIHN0YXJ0ID0gaW5kZXgkMTtcblxuICAvLyBCYWNrc2xhc2ggKFUrMDA1Qykgc3RhcnRzIGFuIGVzY2FwZWQgY2hhcmFjdGVyLlxuICBpZCA9IChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpID09PSAweDVDKSA/IGdldEVzY2FwZWRJZGVudGlmaWVyKCkgOiBnZXRJZGVudGlmaWVyKCk7XG5cbiAgLy8gVGhlcmUgaXMgbm8ga2V5d29yZCBvciBsaXRlcmFsIHdpdGggb25seSBvbmUgY2hhcmFjdGVyLlxuICAvLyBUaHVzLCBpdCBtdXN0IGJlIGFuIGlkZW50aWZpZXIuXG4gIGlmIChpZC5sZW5ndGggPT09IDEpIHtcbiAgICB0eXBlID0gVG9rZW5JZGVudGlmaWVyO1xuICB9IGVsc2UgaWYgKGtleXdvcmRzJDEuaGFzT3duUHJvcGVydHkoaWQpKSB7XG4gICAgdHlwZSA9IFRva2VuS2V5d29yZDtcbiAgfSBlbHNlIGlmIChpZCA9PT0gJ251bGwnKSB7XG4gICAgdHlwZSA9IFRva2VuTnVsbExpdGVyYWw7XG4gIH0gZWxzZSBpZiAoaWQgPT09ICd0cnVlJyB8fCBpZCA9PT0gJ2ZhbHNlJykge1xuICAgIHR5cGUgPSBUb2tlbkJvb2xlYW5MaXRlcmFsO1xuICB9IGVsc2Uge1xuICAgIHR5cGUgPSBUb2tlbklkZW50aWZpZXI7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHR5cGU6IHR5cGUsXG4gICAgdmFsdWU6IGlkLFxuICAgIHN0YXJ0OiBzdGFydCxcbiAgICBlbmQ6IGluZGV4JDFcbiAgfTtcbn1cblxuLy8gNy43IFB1bmN0dWF0b3JzXG5cbmZ1bmN0aW9uIHNjYW5QdW5jdHVhdG9yKCkge1xuICB2YXIgc3RhcnQgPSBpbmRleCQxLFxuICAgIGNvZGUgPSBzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpLFxuICAgIGNvZGUyLFxuICAgIGNoMSA9IHNvdXJjZSQxW2luZGV4JDFdLFxuICAgIGNoMixcbiAgICBjaDMsXG4gICAgY2g0O1xuXG4gIHN3aXRjaCAoY29kZSkge1xuXG4gICAgLy8gQ2hlY2sgZm9yIG1vc3QgY29tbW9uIHNpbmdsZS1jaGFyYWN0ZXIgcHVuY3R1YXRvcnMuXG4gICAgY2FzZSAweDJFOiAvLyAuIGRvdFxuICAgIGNhc2UgMHgyODogLy8gKCBvcGVuIGJyYWNrZXRcbiAgICBjYXNlIDB4Mjk6IC8vICkgY2xvc2UgYnJhY2tldFxuICAgIGNhc2UgMHgzQjogLy8gOyBzZW1pY29sb25cbiAgICBjYXNlIDB4MkM6IC8vICwgY29tbWFcbiAgICBjYXNlIDB4N0I6IC8vIHsgb3BlbiBjdXJseSBicmFjZVxuICAgIGNhc2UgMHg3RDogLy8gfSBjbG9zZSBjdXJseSBicmFjZVxuICAgIGNhc2UgMHg1QjogLy8gW1xuICAgIGNhc2UgMHg1RDogLy8gXVxuICAgIGNhc2UgMHgzQTogLy8gOlxuICAgIGNhc2UgMHgzRjogLy8gP1xuICAgIGNhc2UgMHg3RTogLy8gflxuICAgICAgKytpbmRleCQxO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgdHlwZTogVG9rZW5QdW5jdHVhdG9yLFxuICAgICAgICB2YWx1ZTogU3RyaW5nLmZyb21DaGFyQ29kZShjb2RlKSxcbiAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICBlbmQ6IGluZGV4JDFcbiAgICAgIH07XG5cbiAgICBkZWZhdWx0OlxuICAgICAgY29kZTIgPSBzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEgKyAxKTtcblxuICAgICAgLy8gJz0nIChVKzAwM0QpIG1hcmtzIGFuIGFzc2lnbm1lbnQgb3IgY29tcGFyaXNvbiBvcGVyYXRvci5cbiAgICAgIGlmIChjb2RlMiA9PT0gMHgzRCkge1xuICAgICAgICBzd2l0Y2ggKGNvZGUpIHtcbiAgICAgICAgICBjYXNlIDB4MkI6IC8vICtcbiAgICAgICAgICBjYXNlIDB4MkQ6IC8vIC1cbiAgICAgICAgICBjYXNlIDB4MkY6IC8vIC9cbiAgICAgICAgICBjYXNlIDB4M0M6IC8vIDxcbiAgICAgICAgICBjYXNlIDB4M0U6IC8vID5cbiAgICAgICAgICBjYXNlIDB4NUU6IC8vIF5cbiAgICAgICAgICBjYXNlIDB4N0M6IC8vIHxcbiAgICAgICAgICBjYXNlIDB4MjU6IC8vICVcbiAgICAgICAgICBjYXNlIDB4MjY6IC8vICZcbiAgICAgICAgICBjYXNlIDB4MkE6IC8vICpcbiAgICAgICAgICAgIGluZGV4JDEgKz0gMjtcbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGU6IFRva2VuUHVuY3R1YXRvcixcbiAgICAgICAgICAgICAgdmFsdWU6IFN0cmluZy5mcm9tQ2hhckNvZGUoY29kZSkgKyBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUyKSxcbiAgICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgICBlbmQ6IGluZGV4JDFcbiAgICAgICAgICAgIH07XG5cbiAgICAgICAgICBjYXNlIDB4MjE6IC8vICFcbiAgICAgICAgICBjYXNlIDB4M0Q6IC8vID1cbiAgICAgICAgICAgIGluZGV4JDEgKz0gMjtcblxuICAgICAgICAgICAgLy8gIT09IGFuZCA9PT1cbiAgICAgICAgICAgIGlmIChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpID09PSAweDNEKSB7XG4gICAgICAgICAgICAgICsraW5kZXgkMTtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIHR5cGU6IFRva2VuUHVuY3R1YXRvcixcbiAgICAgICAgICAgICAgdmFsdWU6IHNvdXJjZSQxLnNsaWNlKHN0YXJ0LCBpbmRleCQxKSxcbiAgICAgICAgICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgICAgICAgICBlbmQ6IGluZGV4JDFcbiAgICAgICAgICAgIH07XG4gICAgICAgIH1cbiAgICAgIH1cbiAgfVxuXG4gIC8vIDQtY2hhcmFjdGVyIHB1bmN0dWF0b3I6ID4+Pj1cblxuICBjaDQgPSBzb3VyY2UkMS5zdWJzdHIoaW5kZXgkMSwgNCk7XG5cbiAgaWYgKGNoNCA9PT0gJz4+Pj0nKSB7XG4gICAgaW5kZXgkMSArPSA0O1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBUb2tlblB1bmN0dWF0b3IsXG4gICAgICB2YWx1ZTogY2g0LFxuICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgZW5kOiBpbmRleCQxXG4gICAgfTtcbiAgfVxuXG4gIC8vIDMtY2hhcmFjdGVyIHB1bmN0dWF0b3JzOiA9PT0gIT09ID4+PiA8PD0gPj49XG5cbiAgY2gzID0gY2g0LnN1YnN0cigwLCAzKTtcblxuICBpZiAoY2gzID09PSAnPj4+JyB8fCBjaDMgPT09ICc8PD0nIHx8IGNoMyA9PT0gJz4+PScpIHtcbiAgICBpbmRleCQxICs9IDM7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFRva2VuUHVuY3R1YXRvcixcbiAgICAgIHZhbHVlOiBjaDMsXG4gICAgICBzdGFydDogc3RhcnQsXG4gICAgICBlbmQ6IGluZGV4JDFcbiAgICB9O1xuICB9XG5cbiAgLy8gT3RoZXIgMi1jaGFyYWN0ZXIgcHVuY3R1YXRvcnM6ICsrIC0tIDw8ID4+ICYmIHx8XG4gIGNoMiA9IGNoMy5zdWJzdHIoMCwgMik7XG5cbiAgaWYgKChjaDEgPT09IGNoMlsxXSAmJiAoJystPD4mfCcuaW5kZXhPZihjaDEpID49IDApKSB8fCBjaDIgPT09ICc9PicpIHtcbiAgICBpbmRleCQxICs9IDI7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFRva2VuUHVuY3R1YXRvcixcbiAgICAgIHZhbHVlOiBjaDIsXG4gICAgICBzdGFydDogc3RhcnQsXG4gICAgICBlbmQ6IGluZGV4JDFcbiAgICB9O1xuICB9XG5cbiAgLy8gMS1jaGFyYWN0ZXIgcHVuY3R1YXRvcnM6IDwgPiA9ICEgKyAtICogJSAmIHwgXiAvXG5cbiAgaWYgKCc8Pj0hKy0qJSZ8Xi8nLmluZGV4T2YoY2gxKSA+PSAwKSB7XG4gICAgKytpbmRleCQxO1xuICAgIHJldHVybiB7XG4gICAgICB0eXBlOiBUb2tlblB1bmN0dWF0b3IsXG4gICAgICB2YWx1ZTogY2gxLFxuICAgICAgc3RhcnQ6IHN0YXJ0LFxuICAgICAgZW5kOiBpbmRleCQxXG4gICAgfTtcbiAgfVxuXG4gIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VVbmV4cGVjdGVkVG9rZW4sIElMTEVHQUwpO1xufVxuXG4vLyA3LjguMyBOdW1lcmljIExpdGVyYWxzXG5cbmZ1bmN0aW9uIHNjYW5IZXhMaXRlcmFsKHN0YXJ0KSB7XG4gIHZhciBudW1iZXIgPSAnJztcblxuICB3aGlsZSAoaW5kZXgkMSA8IGxlbmd0aCQyKSB7XG4gICAgaWYgKCFpc0hleERpZ2l0KHNvdXJjZSQxW2luZGV4JDFdKSkge1xuICAgICAgYnJlYWs7XG4gICAgfVxuICAgIG51bWJlciArPSBzb3VyY2UkMVtpbmRleCQxKytdO1xuICB9XG5cbiAgaWYgKG51bWJlci5sZW5ndGggPT09IDApIHtcbiAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgfVxuXG4gIGlmIChpc0lkZW50aWZpZXJTdGFydChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpKSkge1xuICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VVbmV4cGVjdGVkVG9rZW4sIElMTEVHQUwpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICB0eXBlOiBUb2tlbk51bWVyaWNMaXRlcmFsLFxuICAgIHZhbHVlOiBwYXJzZUludCgnMHgnICsgbnVtYmVyLCAxNiksXG4gICAgc3RhcnQ6IHN0YXJ0LFxuICAgIGVuZDogaW5kZXgkMVxuICB9O1xufVxuXG5mdW5jdGlvbiBzY2FuT2N0YWxMaXRlcmFsKHN0YXJ0KSB7XG4gIHZhciBudW1iZXIgPSAnMCcgKyBzb3VyY2UkMVtpbmRleCQxKytdO1xuICB3aGlsZSAoaW5kZXgkMSA8IGxlbmd0aCQyKSB7XG4gICAgaWYgKCFpc09jdGFsRGlnaXQoc291cmNlJDFbaW5kZXgkMV0pKSB7XG4gICAgICBicmVhaztcbiAgICB9XG4gICAgbnVtYmVyICs9IHNvdXJjZSQxW2luZGV4JDErK107XG4gIH1cblxuICBpZiAoaXNJZGVudGlmaWVyU3RhcnQoc291cmNlJDEuY2hhckNvZGVBdChpbmRleCQxKSkgfHwgaXNEZWNpbWFsRGlnaXQoc291cmNlJDEuY2hhckNvZGVBdChpbmRleCQxKSkpIHtcbiAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogVG9rZW5OdW1lcmljTGl0ZXJhbCxcbiAgICB2YWx1ZTogcGFyc2VJbnQobnVtYmVyLCA4KSxcbiAgICBvY3RhbDogdHJ1ZSxcbiAgICBzdGFydDogc3RhcnQsXG4gICAgZW5kOiBpbmRleCQxXG4gIH07XG59XG5cbmZ1bmN0aW9uIHNjYW5OdW1lcmljTGl0ZXJhbCgpIHtcbiAgdmFyIG51bWJlciwgc3RhcnQsIGNoO1xuXG4gIGNoID0gc291cmNlJDFbaW5kZXgkMV07XG4gIGFzc2VydChpc0RlY2ltYWxEaWdpdChjaC5jaGFyQ29kZUF0KDApKSB8fCAoY2ggPT09ICcuJyksXG4gICAgJ051bWVyaWMgbGl0ZXJhbCBtdXN0IHN0YXJ0IHdpdGggYSBkZWNpbWFsIGRpZ2l0IG9yIGEgZGVjaW1hbCBwb2ludCcpO1xuXG4gIHN0YXJ0ID0gaW5kZXgkMTtcbiAgbnVtYmVyID0gJyc7XG4gIGlmIChjaCAhPT0gJy4nKSB7XG4gICAgbnVtYmVyID0gc291cmNlJDFbaW5kZXgkMSsrXTtcbiAgICBjaCA9IHNvdXJjZSQxW2luZGV4JDFdO1xuXG4gICAgLy8gSGV4IG51bWJlciBzdGFydHMgd2l0aCAnMHgnLlxuICAgIC8vIE9jdGFsIG51bWJlciBzdGFydHMgd2l0aCAnMCcuXG4gICAgaWYgKG51bWJlciA9PT0gJzAnKSB7XG4gICAgICBpZiAoY2ggPT09ICd4JyB8fCBjaCA9PT0gJ1gnKSB7XG4gICAgICAgICsraW5kZXgkMTtcbiAgICAgICAgcmV0dXJuIHNjYW5IZXhMaXRlcmFsKHN0YXJ0KTtcbiAgICAgIH1cbiAgICAgIGlmIChpc09jdGFsRGlnaXQoY2gpKSB7XG4gICAgICAgIHJldHVybiBzY2FuT2N0YWxMaXRlcmFsKHN0YXJ0KTtcbiAgICAgIH1cblxuICAgICAgLy8gZGVjaW1hbCBudW1iZXIgc3RhcnRzIHdpdGggJzAnIHN1Y2ggYXMgJzA5JyBpcyBpbGxlZ2FsLlxuICAgICAgaWYgKGNoICYmIGlzRGVjaW1hbERpZ2l0KGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VVbmV4cGVjdGVkVG9rZW4sIElMTEVHQUwpO1xuICAgICAgfVxuICAgIH1cblxuICAgIHdoaWxlIChpc0RlY2ltYWxEaWdpdChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpKSkge1xuICAgICAgbnVtYmVyICs9IHNvdXJjZSQxW2luZGV4JDErK107XG4gICAgfVxuICAgIGNoID0gc291cmNlJDFbaW5kZXgkMV07XG4gIH1cblxuICBpZiAoY2ggPT09ICcuJykge1xuICAgIG51bWJlciArPSBzb3VyY2UkMVtpbmRleCQxKytdO1xuICAgIHdoaWxlIChpc0RlY2ltYWxEaWdpdChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpKSkge1xuICAgICAgbnVtYmVyICs9IHNvdXJjZSQxW2luZGV4JDErK107XG4gICAgfVxuICAgIGNoID0gc291cmNlJDFbaW5kZXgkMV07XG4gIH1cblxuICBpZiAoY2ggPT09ICdlJyB8fCBjaCA9PT0gJ0UnKSB7XG4gICAgbnVtYmVyICs9IHNvdXJjZSQxW2luZGV4JDErK107XG5cbiAgICBjaCA9IHNvdXJjZSQxW2luZGV4JDFdO1xuICAgIGlmIChjaCA9PT0gJysnIHx8IGNoID09PSAnLScpIHtcbiAgICAgIG51bWJlciArPSBzb3VyY2UkMVtpbmRleCQxKytdO1xuICAgIH1cbiAgICBpZiAoaXNEZWNpbWFsRGlnaXQoc291cmNlJDEuY2hhckNvZGVBdChpbmRleCQxKSkpIHtcbiAgICAgIHdoaWxlIChpc0RlY2ltYWxEaWdpdChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpKSkge1xuICAgICAgICBudW1iZXIgKz0gc291cmNlJDFbaW5kZXgkMSsrXTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZVVuZXhwZWN0ZWRUb2tlbiwgSUxMRUdBTCk7XG4gICAgfVxuICB9XG5cbiAgaWYgKGlzSWRlbnRpZmllclN0YXJ0KHNvdXJjZSQxLmNoYXJDb2RlQXQoaW5kZXgkMSkpKSB7XG4gICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZVVuZXhwZWN0ZWRUb2tlbiwgSUxMRUdBTCk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHR5cGU6IFRva2VuTnVtZXJpY0xpdGVyYWwsXG4gICAgdmFsdWU6IHBhcnNlRmxvYXQobnVtYmVyKSxcbiAgICBzdGFydDogc3RhcnQsXG4gICAgZW5kOiBpbmRleCQxXG4gIH07XG59XG5cbi8vIDcuOC40IFN0cmluZyBMaXRlcmFsc1xuXG5mdW5jdGlvbiBzY2FuU3RyaW5nTGl0ZXJhbCgpIHtcbiAgdmFyIHN0ciA9ICcnLFxuICAgIHF1b3RlLCBzdGFydCwgY2gsIGNvZGUsIG9jdGFsID0gZmFsc2U7XG5cbiAgcXVvdGUgPSBzb3VyY2UkMVtpbmRleCQxXTtcbiAgYXNzZXJ0KChxdW90ZSA9PT0gJ1xcJycgfHwgcXVvdGUgPT09ICdcIicpLFxuICAgICdTdHJpbmcgbGl0ZXJhbCBtdXN0IHN0YXJ0cyB3aXRoIGEgcXVvdGUnKTtcblxuICBzdGFydCA9IGluZGV4JDE7XG4gICsraW5kZXgkMTtcblxuICB3aGlsZSAoaW5kZXgkMSA8IGxlbmd0aCQyKSB7XG4gICAgY2ggPSBzb3VyY2UkMVtpbmRleCQxKytdO1xuXG4gICAgaWYgKGNoID09PSBxdW90ZSkge1xuICAgICAgcXVvdGUgPSAnJztcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSBpZiAoY2ggPT09ICdcXFxcJykge1xuICAgICAgY2ggPSBzb3VyY2UkMVtpbmRleCQxKytdO1xuICAgICAgaWYgKCFjaCB8fCAhaXNMaW5lVGVybWluYXRvcihjaC5jaGFyQ29kZUF0KDApKSkge1xuICAgICAgICBzd2l0Y2ggKGNoKSB7XG4gICAgICAgICAgY2FzZSAndSc6XG4gICAgICAgICAgY2FzZSAneCc6XG4gICAgICAgICAgICBpZiAoc291cmNlJDFbaW5kZXgkMV0gPT09ICd7Jykge1xuICAgICAgICAgICAgICArK2luZGV4JDE7XG4gICAgICAgICAgICAgIHN0ciArPSBzY2FuVW5pY29kZUNvZGVQb2ludEVzY2FwZSgpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RyICs9IHNjYW5IZXhFc2NhcGUoY2gpO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnbic6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcbic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdyJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFxyJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3QnOlxuICAgICAgICAgICAgc3RyICs9ICdcXHQnO1xuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgICAgY2FzZSAnYic6XG4gICAgICAgICAgICBzdHIgKz0gJ1xcYic7XG4gICAgICAgICAgICBicmVhaztcbiAgICAgICAgICBjYXNlICdmJzpcbiAgICAgICAgICAgIHN0ciArPSAnXFxmJztcbiAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIGNhc2UgJ3YnOlxuICAgICAgICAgICAgc3RyICs9ICdcXHgwQic7XG4gICAgICAgICAgICBicmVhaztcblxuICAgICAgICAgIGRlZmF1bHQ6XG4gICAgICAgICAgICBpZiAoaXNPY3RhbERpZ2l0KGNoKSkge1xuICAgICAgICAgICAgICBjb2RlID0gJzAxMjM0NTY3Jy5pbmRleE9mKGNoKTtcblxuICAgICAgICAgICAgICAvLyBcXDAgaXMgbm90IG9jdGFsIGVzY2FwZSBzZXF1ZW5jZVxuICAgICAgICAgICAgICBpZiAoY29kZSAhPT0gMCkge1xuICAgICAgICAgICAgICAgIG9jdGFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgIGlmIChpbmRleCQxIDwgbGVuZ3RoJDIgJiYgaXNPY3RhbERpZ2l0KHNvdXJjZSQxW2luZGV4JDFdKSkge1xuICAgICAgICAgICAgICAgIG9jdGFsID0gdHJ1ZTtcbiAgICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDggKyAnMDEyMzQ1NjcnLmluZGV4T2Yoc291cmNlJDFbaW5kZXgkMSsrXSk7XG5cbiAgICAgICAgICAgICAgICAvLyAzIGRpZ2l0cyBhcmUgb25seSBhbGxvd2VkIHdoZW4gc3RyaW5nIHN0YXJ0c1xuICAgICAgICAgICAgICAgIC8vIHdpdGggMCwgMSwgMiwgM1xuICAgICAgICAgICAgICAgIGlmICgnMDEyMycuaW5kZXhPZihjaCkgPj0gMCAmJlxuICAgICAgICAgICAgICAgICAgaW5kZXgkMSA8IGxlbmd0aCQyICYmXG4gICAgICAgICAgICAgICAgICBpc09jdGFsRGlnaXQoc291cmNlJDFbaW5kZXgkMV0pKSB7XG4gICAgICAgICAgICAgICAgICBjb2RlID0gY29kZSAqIDggKyAnMDEyMzQ1NjcnLmluZGV4T2Yoc291cmNlJDFbaW5kZXgkMSsrXSk7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICB9XG4gICAgICAgICAgICAgIHN0ciArPSBTdHJpbmcuZnJvbUNoYXJDb2RlKGNvZGUpO1xuICAgICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgICAgc3RyICs9IGNoO1xuICAgICAgICAgICAgfVxuICAgICAgICAgICAgYnJlYWs7XG4gICAgICAgIH1cbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGlmIChjaCA9PT0gJ1xccicgJiYgc291cmNlJDFbaW5kZXgkMV0gPT09ICdcXG4nKSB7XG4gICAgICAgICAgKytpbmRleCQxO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfSBlbHNlIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICBicmVhaztcbiAgICB9IGVsc2Uge1xuICAgICAgc3RyICs9IGNoO1xuICAgIH1cbiAgfVxuXG4gIGlmIChxdW90ZSAhPT0gJycpIHtcbiAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgdHlwZTogVG9rZW5TdHJpbmdMaXRlcmFsLFxuICAgIHZhbHVlOiBzdHIsXG4gICAgb2N0YWw6IG9jdGFsLFxuICAgIHN0YXJ0OiBzdGFydCxcbiAgICBlbmQ6IGluZGV4JDFcbiAgfTtcbn1cblxuZnVuY3Rpb24gdGVzdFJlZ0V4cChwYXR0ZXJuLCBmbGFncykge1xuICB2YXIgdG1wID0gcGF0dGVybjtcblxuICBpZiAoZmxhZ3MuaW5kZXhPZigndScpID49IDApIHtcbiAgICAvLyBSZXBsYWNlIGVhY2ggYXN0cmFsIHN5bWJvbCBhbmQgZXZlcnkgVW5pY29kZSBjb2RlIHBvaW50XG4gICAgLy8gZXNjYXBlIHNlcXVlbmNlIHdpdGggYSBzaW5nbGUgQVNDSUkgc3ltYm9sIHRvIGF2b2lkIHRocm93aW5nIG9uXG4gICAgLy8gcmVndWxhciBleHByZXNzaW9ucyB0aGF0IGFyZSBvbmx5IHZhbGlkIGluIGNvbWJpbmF0aW9uIHdpdGggdGhlXG4gICAgLy8gYC91YCBmbGFnLlxuICAgIC8vIE5vdGU6IHJlcGxhY2luZyB3aXRoIHRoZSBBU0NJSSBzeW1ib2wgYHhgIG1pZ2h0IGNhdXNlIGZhbHNlXG4gICAgLy8gbmVnYXRpdmVzIGluIHVubGlrZWx5IHNjZW5hcmlvcy4gRm9yIGV4YW1wbGUsIGBbXFx1ezYxfS1iXWAgaXMgYVxuICAgIC8vIHBlcmZlY3RseSB2YWxpZCBwYXR0ZXJuIHRoYXQgaXMgZXF1aXZhbGVudCB0byBgW2EtYl1gLCBidXQgaXRcbiAgICAvLyB3b3VsZCBiZSByZXBsYWNlZCBieSBgW3gtYl1gIHdoaWNoIHRocm93cyBhbiBlcnJvci5cbiAgICB0bXAgPSB0bXBcbiAgICAgIC5yZXBsYWNlKC9cXFxcdVxceyhbMC05YS1mQS1GXSspXFx9L2csIGZ1bmN0aW9uKCQwLCAkMSkge1xuICAgICAgICBpZiAocGFyc2VJbnQoJDEsIDE2KSA8PSAweDEwRkZGRikge1xuICAgICAgICAgIHJldHVybiAneCc7XG4gICAgICAgIH1cbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZUludmFsaWRSZWdFeHApO1xuICAgICAgfSlcbiAgICAgIC5yZXBsYWNlKC9bXFx1RDgwMC1cXHVEQkZGXVtcXHVEQzAwLVxcdURGRkZdL2csICd4Jyk7XG4gIH1cblxuICAvLyBGaXJzdCwgZGV0ZWN0IGludmFsaWQgcmVndWxhciBleHByZXNzaW9ucy5cbiAgdHJ5IHtcbiAgICBuZXcgUmVnRXhwKHRtcCk7XG4gIH0gY2F0Y2ggKGUpIHtcbiAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlSW52YWxpZFJlZ0V4cCk7XG4gIH1cblxuICAvLyBSZXR1cm4gYSByZWd1bGFyIGV4cHJlc3Npb24gb2JqZWN0IGZvciB0aGlzIHBhdHRlcm4tZmxhZyBwYWlyLCBvclxuICAvLyBgbnVsbGAgaW4gY2FzZSB0aGUgY3VycmVudCBlbnZpcm9ubWVudCBkb2Vzbid0IHN1cHBvcnQgdGhlIGZsYWdzIGl0XG4gIC8vIHVzZXMuXG4gIHRyeSB7XG4gICAgcmV0dXJuIG5ldyBSZWdFeHAocGF0dGVybiwgZmxhZ3MpO1xuICB9IGNhdGNoIChleGNlcHRpb24pIHtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxufVxuXG5mdW5jdGlvbiBzY2FuUmVnRXhwQm9keSgpIHtcbiAgdmFyIGNoLCBzdHIsIGNsYXNzTWFya2VyLCB0ZXJtaW5hdGVkLCBib2R5O1xuXG4gIGNoID0gc291cmNlJDFbaW5kZXgkMV07XG4gIGFzc2VydChjaCA9PT0gJy8nLCAnUmVndWxhciBleHByZXNzaW9uIGxpdGVyYWwgbXVzdCBzdGFydCB3aXRoIGEgc2xhc2gnKTtcbiAgc3RyID0gc291cmNlJDFbaW5kZXgkMSsrXTtcblxuICBjbGFzc01hcmtlciA9IGZhbHNlO1xuICB0ZXJtaW5hdGVkID0gZmFsc2U7XG4gIHdoaWxlIChpbmRleCQxIDwgbGVuZ3RoJDIpIHtcbiAgICBjaCA9IHNvdXJjZSQxW2luZGV4JDErK107XG4gICAgc3RyICs9IGNoO1xuICAgIGlmIChjaCA9PT0gJ1xcXFwnKSB7XG4gICAgICBjaCA9IHNvdXJjZSQxW2luZGV4JDErK107XG4gICAgICAvLyBFQ01BLTI2MiA3LjguNVxuICAgICAgaWYgKGlzTGluZVRlcm1pbmF0b3IoY2guY2hhckNvZGVBdCgwKSkpIHtcbiAgICAgICAgdGhyb3dFcnJvcih7fSwgTWVzc2FnZVVudGVybWluYXRlZFJlZ0V4cCk7XG4gICAgICB9XG4gICAgICBzdHIgKz0gY2g7XG4gICAgfSBlbHNlIGlmIChpc0xpbmVUZXJtaW5hdG9yKGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW50ZXJtaW5hdGVkUmVnRXhwKTtcbiAgICB9IGVsc2UgaWYgKGNsYXNzTWFya2VyKSB7XG4gICAgICBpZiAoY2ggPT09ICddJykge1xuICAgICAgICBjbGFzc01hcmtlciA9IGZhbHNlO1xuICAgICAgfVxuICAgIH0gZWxzZSB7XG4gICAgICBpZiAoY2ggPT09ICcvJykge1xuICAgICAgICB0ZXJtaW5hdGVkID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9IGVsc2UgaWYgKGNoID09PSAnWycpIHtcbiAgICAgICAgY2xhc3NNYXJrZXIgPSB0cnVlO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmICghdGVybWluYXRlZCkge1xuICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VVbnRlcm1pbmF0ZWRSZWdFeHApO1xuICB9XG5cbiAgLy8gRXhjbHVkZSBsZWFkaW5nIGFuZCB0cmFpbGluZyBzbGFzaC5cbiAgYm9keSA9IHN0ci5zdWJzdHIoMSwgc3RyLmxlbmd0aCAtIDIpO1xuICByZXR1cm4ge1xuICAgIHZhbHVlOiBib2R5LFxuICAgIGxpdGVyYWw6IHN0clxuICB9O1xufVxuXG5mdW5jdGlvbiBzY2FuUmVnRXhwRmxhZ3MoKSB7XG4gIHZhciBjaCwgc3RyLCBmbGFncztcblxuICBzdHIgPSAnJztcbiAgZmxhZ3MgPSAnJztcbiAgd2hpbGUgKGluZGV4JDEgPCBsZW5ndGgkMikge1xuICAgIGNoID0gc291cmNlJDFbaW5kZXgkMV07XG4gICAgaWYgKCFpc0lkZW50aWZpZXJQYXJ0KGNoLmNoYXJDb2RlQXQoMCkpKSB7XG4gICAgICBicmVhaztcbiAgICB9XG5cbiAgICArK2luZGV4JDE7XG4gICAgaWYgKGNoID09PSAnXFxcXCcgJiYgaW5kZXgkMSA8IGxlbmd0aCQyKSB7XG4gICAgICB0aHJvd0Vycm9yKHt9LCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCBJTExFR0FMKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmxhZ3MgKz0gY2g7XG4gICAgICBzdHIgKz0gY2g7XG4gICAgfVxuICB9XG5cbiAgaWYgKGZsYWdzLnNlYXJjaCgvW15naW11eV0vZykgPj0gMCkge1xuICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VJbnZhbGlkUmVnRXhwLCBmbGFncyk7XG4gIH1cblxuICByZXR1cm4ge1xuICAgIHZhbHVlOiBmbGFncyxcbiAgICBsaXRlcmFsOiBzdHJcbiAgfTtcbn1cblxuZnVuY3Rpb24gc2NhblJlZ0V4cCgpIHtcbiAgdmFyIHN0YXJ0LCBib2R5LCBmbGFncywgdmFsdWU7XG5cbiAgbG9va2FoZWFkID0gbnVsbDtcbiAgc2tpcENvbW1lbnQoKTtcbiAgc3RhcnQgPSBpbmRleCQxO1xuXG4gIGJvZHkgPSBzY2FuUmVnRXhwQm9keSgpO1xuICBmbGFncyA9IHNjYW5SZWdFeHBGbGFncygpO1xuICB2YWx1ZSA9IHRlc3RSZWdFeHAoYm9keS52YWx1ZSwgZmxhZ3MudmFsdWUpO1xuXG4gIHJldHVybiB7XG4gICAgbGl0ZXJhbDogYm9keS5saXRlcmFsICsgZmxhZ3MubGl0ZXJhbCxcbiAgICB2YWx1ZTogdmFsdWUsXG4gICAgcmVnZXg6IHtcbiAgICAgIHBhdHRlcm46IGJvZHkudmFsdWUsXG4gICAgICBmbGFnczogZmxhZ3MudmFsdWVcbiAgICB9LFxuICAgIHN0YXJ0OiBzdGFydCxcbiAgICBlbmQ6IGluZGV4JDFcbiAgfTtcbn1cblxuZnVuY3Rpb24gaXNJZGVudGlmaWVyTmFtZSh0b2tlbikge1xuICByZXR1cm4gdG9rZW4udHlwZSA9PT0gVG9rZW5JZGVudGlmaWVyIHx8XG4gICAgdG9rZW4udHlwZSA9PT0gVG9rZW5LZXl3b3JkIHx8XG4gICAgdG9rZW4udHlwZSA9PT0gVG9rZW5Cb29sZWFuTGl0ZXJhbCB8fFxuICAgIHRva2VuLnR5cGUgPT09IFRva2VuTnVsbExpdGVyYWw7XG59XG5cbmZ1bmN0aW9uIGFkdmFuY2UoKSB7XG4gIHZhciBjaDtcblxuICBza2lwQ29tbWVudCgpO1xuXG4gIGlmIChpbmRleCQxID49IGxlbmd0aCQyKSB7XG4gICAgcmV0dXJuIHtcbiAgICAgIHR5cGU6IFRva2VuRU9GLFxuICAgICAgc3RhcnQ6IGluZGV4JDEsXG4gICAgICBlbmQ6IGluZGV4JDFcbiAgICB9O1xuICB9XG5cbiAgY2ggPSBzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEpO1xuXG4gIGlmIChpc0lkZW50aWZpZXJTdGFydChjaCkpIHtcbiAgICByZXR1cm4gc2NhbklkZW50aWZpZXIoKTtcbiAgfVxuXG4gIC8vIFZlcnkgY29tbW9uOiAoIGFuZCApIGFuZCA7XG4gIGlmIChjaCA9PT0gMHgyOCB8fCBjaCA9PT0gMHgyOSB8fCBjaCA9PT0gMHgzQikge1xuICAgIHJldHVybiBzY2FuUHVuY3R1YXRvcigpO1xuICB9XG5cbiAgLy8gU3RyaW5nIGxpdGVyYWwgc3RhcnRzIHdpdGggc2luZ2xlIHF1b3RlIChVKzAwMjcpIG9yIGRvdWJsZSBxdW90ZSAoVSswMDIyKS5cbiAgaWYgKGNoID09PSAweDI3IHx8IGNoID09PSAweDIyKSB7XG4gICAgcmV0dXJuIHNjYW5TdHJpbmdMaXRlcmFsKCk7XG4gIH1cblxuXG4gIC8vIERvdCAoLikgVSswMDJFIGNhbiBhbHNvIHN0YXJ0IGEgZmxvYXRpbmctcG9pbnQgbnVtYmVyLCBoZW5jZSB0aGUgbmVlZFxuICAvLyB0byBjaGVjayB0aGUgbmV4dCBjaGFyYWN0ZXIuXG4gIGlmIChjaCA9PT0gMHgyRSkge1xuICAgIGlmIChpc0RlY2ltYWxEaWdpdChzb3VyY2UkMS5jaGFyQ29kZUF0KGluZGV4JDEgKyAxKSkpIHtcbiAgICAgIHJldHVybiBzY2FuTnVtZXJpY0xpdGVyYWwoKTtcbiAgICB9XG4gICAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG4gIH1cblxuICBpZiAoaXNEZWNpbWFsRGlnaXQoY2gpKSB7XG4gICAgcmV0dXJuIHNjYW5OdW1lcmljTGl0ZXJhbCgpO1xuICB9XG5cbiAgcmV0dXJuIHNjYW5QdW5jdHVhdG9yKCk7XG59XG5cbmZ1bmN0aW9uIGxleCgpIHtcbiAgdmFyIHRva2VuO1xuXG4gIHRva2VuID0gbG9va2FoZWFkO1xuICBpbmRleCQxID0gdG9rZW4uZW5kO1xuXG4gIGxvb2thaGVhZCA9IGFkdmFuY2UoKTtcblxuICBpbmRleCQxID0gdG9rZW4uZW5kO1xuXG4gIHJldHVybiB0b2tlbjtcbn1cblxuZnVuY3Rpb24gcGVlayQxKCkge1xuICB2YXIgcG9zO1xuXG4gIHBvcyA9IGluZGV4JDE7XG5cbiAgbG9va2FoZWFkID0gYWR2YW5jZSgpO1xuICBpbmRleCQxID0gcG9zO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hBcnJheUV4cHJlc3Npb24oZWxlbWVudHMpIHtcbiAgdmFyIG5vZGUgPSBuZXcgQVNUTm9kZShTeW50YXhBcnJheUV4cHJlc3Npb24pO1xuICBub2RlLmVsZW1lbnRzID0gZWxlbWVudHM7XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hCaW5hcnlFeHByZXNzaW9uKG9wZXJhdG9yLCBsZWZ0LCByaWdodCkge1xuICB2YXIgbm9kZSA9IG5ldyBBU1ROb2RlKChvcGVyYXRvciA9PT0gJ3x8JyB8fCBvcGVyYXRvciA9PT0gJyYmJykgPyBTeW50YXhMb2dpY2FsRXhwcmVzc2lvbiA6IFN5bnRheEJpbmFyeUV4cHJlc3Npb24pO1xuICBub2RlLm9wZXJhdG9yID0gb3BlcmF0b3I7XG4gIG5vZGUubGVmdCA9IGxlZnQ7XG4gIG5vZGUucmlnaHQgPSByaWdodDtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGZpbmlzaENhbGxFeHByZXNzaW9uKGNhbGxlZSwgYXJncykge1xuICB2YXIgbm9kZSA9IG5ldyBBU1ROb2RlKFN5bnRheENhbGxFeHByZXNzaW9uKTtcbiAgbm9kZS5jYWxsZWUgPSBjYWxsZWU7XG4gIG5vZGUuYXJndW1lbnRzID0gYXJncztcbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGZpbmlzaENvbmRpdGlvbmFsRXhwcmVzc2lvbih0ZXN0LCBjb25zZXF1ZW50LCBhbHRlcm5hdGUpIHtcbiAgdmFyIG5vZGUgPSBuZXcgQVNUTm9kZShTeW50YXhDb25kaXRpb25hbEV4cHJlc3Npb24pO1xuICBub2RlLnRlc3QgPSB0ZXN0O1xuICBub2RlLmNvbnNlcXVlbnQgPSBjb25zZXF1ZW50O1xuICBub2RlLmFsdGVybmF0ZSA9IGFsdGVybmF0ZTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGZpbmlzaElkZW50aWZpZXIobmFtZSkge1xuICB2YXIgbm9kZSA9IG5ldyBBU1ROb2RlKFN5bnRheElkZW50aWZpZXIpO1xuICBub2RlLm5hbWUgPSBuYW1lO1xuICByZXR1cm4gbm9kZTtcbn1cblxuZnVuY3Rpb24gZmluaXNoTGl0ZXJhbCh0b2tlbikge1xuICB2YXIgbm9kZSA9IG5ldyBBU1ROb2RlKFN5bnRheExpdGVyYWwpO1xuICBub2RlLnZhbHVlID0gdG9rZW4udmFsdWU7XG4gIG5vZGUucmF3ID0gc291cmNlJDEuc2xpY2UodG9rZW4uc3RhcnQsIHRva2VuLmVuZCk7XG4gIGlmICh0b2tlbi5yZWdleCkge1xuICAgIGlmIChub2RlLnJhdyA9PT0gJy8vJykge1xuICAgICAgbm9kZS5yYXcgPSAnLyg/OikvJztcbiAgICB9XG4gICAgbm9kZS5yZWdleCA9IHRva2VuLnJlZ2V4O1xuICB9XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hNZW1iZXJFeHByZXNzaW9uKGFjY2Vzc29yLCBvYmplY3QsIHByb3BlcnR5KSB7XG4gIHZhciBub2RlID0gbmV3IEFTVE5vZGUoU3ludGF4TWVtYmVyRXhwcmVzc2lvbik7XG4gIG5vZGUuY29tcHV0ZWQgPSBhY2Nlc3NvciA9PT0gJ1snO1xuICBub2RlLm9iamVjdCA9IG9iamVjdDtcbiAgbm9kZS5wcm9wZXJ0eSA9IHByb3BlcnR5O1xuICBpZiAoIW5vZGUuY29tcHV0ZWQpIHByb3BlcnR5Lm1lbWJlciA9IHRydWU7XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hPYmplY3RFeHByZXNzaW9uKHByb3BlcnRpZXMpIHtcbiAgdmFyIG5vZGUgPSBuZXcgQVNUTm9kZShTeW50YXhPYmplY3RFeHByZXNzaW9uKTtcbiAgbm9kZS5wcm9wZXJ0aWVzID0gcHJvcGVydGllcztcbiAgcmV0dXJuIG5vZGU7XG59XG5cbmZ1bmN0aW9uIGZpbmlzaFByb3BlcnR5KGtpbmQsIGtleSwgdmFsdWUpIHtcbiAgdmFyIG5vZGUgPSBuZXcgQVNUTm9kZShTeW50YXhQcm9wZXJ0eSk7XG4gIG5vZGUua2V5ID0ga2V5O1xuICBub2RlLnZhbHVlID0gdmFsdWU7XG4gIG5vZGUua2luZCA9IGtpbmQ7XG4gIHJldHVybiBub2RlO1xufVxuXG5mdW5jdGlvbiBmaW5pc2hVbmFyeUV4cHJlc3Npb24ob3BlcmF0b3IsIGFyZ3VtZW50KSB7XG4gIHZhciBub2RlID0gbmV3IEFTVE5vZGUoU3ludGF4VW5hcnlFeHByZXNzaW9uKTtcbiAgbm9kZS5vcGVyYXRvciA9IG9wZXJhdG9yO1xuICBub2RlLmFyZ3VtZW50ID0gYXJndW1lbnQ7XG4gIG5vZGUucHJlZml4ID0gdHJ1ZTtcbiAgcmV0dXJuIG5vZGU7XG59XG5cbi8vIFRocm93IGFuIGV4Y2VwdGlvblxuXG5mdW5jdGlvbiB0aHJvd0Vycm9yKHRva2VuLCBtZXNzYWdlRm9ybWF0KSB7XG4gIHZhciBlcnJvcixcbiAgICBhcmdzID0gQXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoYXJndW1lbnRzLCAyKSxcbiAgICBtc2cgPSBtZXNzYWdlRm9ybWF0LnJlcGxhY2UoXG4gICAgICAvJShcXGQpL2csXG4gICAgICBmdW5jdGlvbih3aG9sZSwgaW5kZXgpIHtcbiAgICAgICAgYXNzZXJ0KGluZGV4IDwgYXJncy5sZW5ndGgsICdNZXNzYWdlIHJlZmVyZW5jZSBtdXN0IGJlIGluIHJhbmdlJyk7XG4gICAgICAgIHJldHVybiBhcmdzW2luZGV4XTtcbiAgICAgIH1cbiAgICApO1xuXG5cbiAgZXJyb3IgPSBuZXcgRXJyb3IobXNnKTtcbiAgZXJyb3IuaW5kZXggPSBpbmRleCQxO1xuICBlcnJvci5kZXNjcmlwdGlvbiA9IG1zZztcbiAgdGhyb3cgZXJyb3I7XG59XG5cbi8vIFRocm93IGFuIGV4Y2VwdGlvbiBiZWNhdXNlIG9mIHRoZSB0b2tlbi5cblxuZnVuY3Rpb24gdGhyb3dVbmV4cGVjdGVkKHRva2VuKSB7XG4gIGlmICh0b2tlbi50eXBlID09PSBUb2tlbkVPRikge1xuICAgIHRocm93RXJyb3IodG9rZW4sIE1lc3NhZ2VVbmV4cGVjdGVkRU9TKTtcbiAgfVxuXG4gIGlmICh0b2tlbi50eXBlID09PSBUb2tlbk51bWVyaWNMaXRlcmFsKSB7XG4gICAgdGhyb3dFcnJvcih0b2tlbiwgTWVzc2FnZVVuZXhwZWN0ZWROdW1iZXIpO1xuICB9XG5cbiAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuU3RyaW5nTGl0ZXJhbCkge1xuICAgIHRocm93RXJyb3IodG9rZW4sIE1lc3NhZ2VVbmV4cGVjdGVkU3RyaW5nKTtcbiAgfVxuXG4gIGlmICh0b2tlbi50eXBlID09PSBUb2tlbklkZW50aWZpZXIpIHtcbiAgICB0aHJvd0Vycm9yKHRva2VuLCBNZXNzYWdlVW5leHBlY3RlZElkZW50aWZpZXIpO1xuICB9XG5cbiAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuS2V5d29yZCkge1xuICAgIHRocm93RXJyb3IodG9rZW4sIE1lc3NhZ2VVbmV4cGVjdGVkUmVzZXJ2ZWQpO1xuICB9XG5cbiAgLy8gQm9vbGVhbkxpdGVyYWwsIE51bGxMaXRlcmFsLCBvciBQdW5jdHVhdG9yLlxuICB0aHJvd0Vycm9yKHRva2VuLCBNZXNzYWdlVW5leHBlY3RlZFRva2VuLCB0b2tlbi52YWx1ZSk7XG59XG5cbi8vIEV4cGVjdCB0aGUgbmV4dCB0b2tlbiB0byBtYXRjaCB0aGUgc3BlY2lmaWVkIHB1bmN0dWF0b3IuXG4vLyBJZiBub3QsIGFuIGV4Y2VwdGlvbiB3aWxsIGJlIHRocm93bi5cblxuZnVuY3Rpb24gZXhwZWN0KHZhbHVlKSB7XG4gIHZhciB0b2tlbiA9IGxleCgpO1xuICBpZiAodG9rZW4udHlwZSAhPT0gVG9rZW5QdW5jdHVhdG9yIHx8IHRva2VuLnZhbHVlICE9PSB2YWx1ZSkge1xuICAgIHRocm93VW5leHBlY3RlZCh0b2tlbik7XG4gIH1cbn1cblxuLy8gUmV0dXJuIHRydWUgaWYgdGhlIG5leHQgdG9rZW4gbWF0Y2hlcyB0aGUgc3BlY2lmaWVkIHB1bmN0dWF0b3IuXG5cbmZ1bmN0aW9uIG1hdGNoKHZhbHVlKSB7XG4gIHJldHVybiBsb29rYWhlYWQudHlwZSA9PT0gVG9rZW5QdW5jdHVhdG9yICYmIGxvb2thaGVhZC52YWx1ZSA9PT0gdmFsdWU7XG59XG5cbi8vIFJldHVybiB0cnVlIGlmIHRoZSBuZXh0IHRva2VuIG1hdGNoZXMgdGhlIHNwZWNpZmllZCBrZXl3b3JkXG5cbmZ1bmN0aW9uIG1hdGNoS2V5d29yZChrZXl3b3JkKSB7XG4gIHJldHVybiBsb29rYWhlYWQudHlwZSA9PT0gVG9rZW5LZXl3b3JkICYmIGxvb2thaGVhZC52YWx1ZSA9PT0ga2V5d29yZDtcbn1cblxuLy8gMTEuMS40IEFycmF5IEluaXRpYWxpc2VyXG5cbmZ1bmN0aW9uIHBhcnNlQXJyYXlJbml0aWFsaXNlcigpIHtcbiAgdmFyIGVsZW1lbnRzID0gW107XG5cbiAgaW5kZXgkMSA9IGxvb2thaGVhZC5zdGFydDtcbiAgZXhwZWN0KCdbJyk7XG5cbiAgd2hpbGUgKCFtYXRjaCgnXScpKSB7XG4gICAgaWYgKG1hdGNoKCcsJykpIHtcbiAgICAgIGxleCgpO1xuICAgICAgZWxlbWVudHMucHVzaChudWxsKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZWxlbWVudHMucHVzaChwYXJzZUNvbmRpdGlvbmFsRXhwcmVzc2lvbigpKTtcblxuICAgICAgaWYgKCFtYXRjaCgnXScpKSB7XG4gICAgICAgIGV4cGVjdCgnLCcpO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGxleCgpO1xuXG4gIHJldHVybiBmaW5pc2hBcnJheUV4cHJlc3Npb24oZWxlbWVudHMpO1xufVxuXG4vLyAxMS4xLjUgT2JqZWN0IEluaXRpYWxpc2VyXG5cbmZ1bmN0aW9uIHBhcnNlT2JqZWN0UHJvcGVydHlLZXkoKSB7XG4gIHZhciB0b2tlbjtcblxuICBpbmRleCQxID0gbG9va2FoZWFkLnN0YXJ0O1xuICB0b2tlbiA9IGxleCgpO1xuXG4gIC8vIE5vdGU6IFRoaXMgZnVuY3Rpb24gaXMgY2FsbGVkIG9ubHkgZnJvbSBwYXJzZU9iamVjdFByb3BlcnR5KCksIHdoZXJlXG4gIC8vIEVPRiBhbmQgUHVuY3R1YXRvciB0b2tlbnMgYXJlIGFscmVhZHkgZmlsdGVyZWQgb3V0LlxuXG4gIGlmICh0b2tlbi50eXBlID09PSBUb2tlblN0cmluZ0xpdGVyYWwgfHwgdG9rZW4udHlwZSA9PT0gVG9rZW5OdW1lcmljTGl0ZXJhbCkge1xuICAgIGlmICh0b2tlbi5vY3RhbCkge1xuICAgICAgdGhyb3dFcnJvcih0b2tlbiwgTWVzc2FnZVN0cmljdE9jdGFsTGl0ZXJhbCk7XG4gICAgfVxuICAgIHJldHVybiBmaW5pc2hMaXRlcmFsKHRva2VuKTtcbiAgfVxuXG4gIHJldHVybiBmaW5pc2hJZGVudGlmaWVyKHRva2VuLnZhbHVlKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VPYmplY3RQcm9wZXJ0eSgpIHtcbiAgdmFyIHRva2VuLCBrZXksIGlkLCB2YWx1ZTtcblxuICBpbmRleCQxID0gbG9va2FoZWFkLnN0YXJ0O1xuICB0b2tlbiA9IGxvb2thaGVhZDtcblxuICBpZiAodG9rZW4udHlwZSA9PT0gVG9rZW5JZGVudGlmaWVyKSB7XG4gICAgaWQgPSBwYXJzZU9iamVjdFByb3BlcnR5S2V5KCk7XG4gICAgZXhwZWN0KCc6Jyk7XG4gICAgdmFsdWUgPSBwYXJzZUNvbmRpdGlvbmFsRXhwcmVzc2lvbigpO1xuICAgIHJldHVybiBmaW5pc2hQcm9wZXJ0eSgnaW5pdCcsIGlkLCB2YWx1ZSk7XG4gIH1cbiAgaWYgKHRva2VuLnR5cGUgPT09IFRva2VuRU9GIHx8IHRva2VuLnR5cGUgPT09IFRva2VuUHVuY3R1YXRvcikge1xuICAgIHRocm93VW5leHBlY3RlZCh0b2tlbik7XG4gIH0gZWxzZSB7XG4gICAga2V5ID0gcGFyc2VPYmplY3RQcm9wZXJ0eUtleSgpO1xuICAgIGV4cGVjdCgnOicpO1xuICAgIHZhbHVlID0gcGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKTtcbiAgICByZXR1cm4gZmluaXNoUHJvcGVydHkoJ2luaXQnLCBrZXksIHZhbHVlKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBwYXJzZU9iamVjdEluaXRpYWxpc2VyKCkge1xuICB2YXIgcHJvcGVydGllcyA9IFtdLFxuICAgIHByb3BlcnR5LCBuYW1lLCBrZXksIG1hcCA9IHt9LFxuICAgIHRvU3RyaW5nID0gU3RyaW5nO1xuXG4gIGluZGV4JDEgPSBsb29rYWhlYWQuc3RhcnQ7XG4gIGV4cGVjdCgneycpO1xuXG4gIHdoaWxlICghbWF0Y2goJ30nKSkge1xuICAgIHByb3BlcnR5ID0gcGFyc2VPYmplY3RQcm9wZXJ0eSgpO1xuXG4gICAgaWYgKHByb3BlcnR5LmtleS50eXBlID09PSBTeW50YXhJZGVudGlmaWVyKSB7XG4gICAgICBuYW1lID0gcHJvcGVydHkua2V5Lm5hbWU7XG4gICAgfSBlbHNlIHtcbiAgICAgIG5hbWUgPSB0b1N0cmluZyhwcm9wZXJ0eS5rZXkudmFsdWUpO1xuICAgIH1cblxuICAgIGtleSA9ICckJyArIG5hbWU7XG4gICAgaWYgKE9iamVjdC5wcm90b3R5cGUuaGFzT3duUHJvcGVydHkuY2FsbChtYXAsIGtleSkpIHtcbiAgICAgIHRocm93RXJyb3Ioe30sIE1lc3NhZ2VTdHJpY3REdXBsaWNhdGVQcm9wZXJ0eSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIG1hcFtrZXldID0gdHJ1ZTtcbiAgICB9XG5cbiAgICBwcm9wZXJ0aWVzLnB1c2gocHJvcGVydHkpO1xuXG4gICAgaWYgKCFtYXRjaCgnfScpKSB7XG4gICAgICBleHBlY3QoJywnKTtcbiAgICB9XG4gIH1cblxuICBleHBlY3QoJ30nKTtcblxuICByZXR1cm4gZmluaXNoT2JqZWN0RXhwcmVzc2lvbihwcm9wZXJ0aWVzKTtcbn1cblxuLy8gMTEuMS42IFRoZSBHcm91cGluZyBPcGVyYXRvclxuXG5mdW5jdGlvbiBwYXJzZUdyb3VwRXhwcmVzc2lvbigpIHtcbiAgdmFyIGV4cHI7XG5cbiAgZXhwZWN0KCcoJyk7XG5cbiAgZXhwciA9IHBhcnNlRXhwcmVzc2lvbiQxKCk7XG5cbiAgZXhwZWN0KCcpJyk7XG5cbiAgcmV0dXJuIGV4cHI7XG59XG5cblxuLy8gMTEuMSBQcmltYXJ5IEV4cHJlc3Npb25zXG5cbnZhciBsZWdhbEtleXdvcmRzID0ge1xuICBcImlmXCI6IDEsXG4gIFwidGhpc1wiOiAxXG59O1xuXG5mdW5jdGlvbiBwYXJzZVByaW1hcnlFeHByZXNzaW9uKCkge1xuICB2YXIgdHlwZSwgdG9rZW4sIGV4cHI7XG5cbiAgaWYgKG1hdGNoKCcoJykpIHtcbiAgICByZXR1cm4gcGFyc2VHcm91cEV4cHJlc3Npb24oKTtcbiAgfVxuXG4gIGlmIChtYXRjaCgnWycpKSB7XG4gICAgcmV0dXJuIHBhcnNlQXJyYXlJbml0aWFsaXNlcigpO1xuICB9XG5cbiAgaWYgKG1hdGNoKCd7JykpIHtcbiAgICByZXR1cm4gcGFyc2VPYmplY3RJbml0aWFsaXNlcigpO1xuICB9XG5cbiAgdHlwZSA9IGxvb2thaGVhZC50eXBlO1xuICBpbmRleCQxID0gbG9va2FoZWFkLnN0YXJ0O1xuXG5cbiAgaWYgKHR5cGUgPT09IFRva2VuSWRlbnRpZmllciB8fCBsZWdhbEtleXdvcmRzW2xvb2thaGVhZC52YWx1ZV0pIHtcbiAgICBleHByID0gZmluaXNoSWRlbnRpZmllcihsZXgoKS52YWx1ZSk7XG4gIH0gZWxzZSBpZiAodHlwZSA9PT0gVG9rZW5TdHJpbmdMaXRlcmFsIHx8IHR5cGUgPT09IFRva2VuTnVtZXJpY0xpdGVyYWwpIHtcbiAgICBpZiAobG9va2FoZWFkLm9jdGFsKSB7XG4gICAgICB0aHJvd0Vycm9yKGxvb2thaGVhZCwgTWVzc2FnZVN0cmljdE9jdGFsTGl0ZXJhbCk7XG4gICAgfVxuICAgIGV4cHIgPSBmaW5pc2hMaXRlcmFsKGxleCgpKTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBUb2tlbktleXdvcmQpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoRElTQUJMRUQpO1xuICB9IGVsc2UgaWYgKHR5cGUgPT09IFRva2VuQm9vbGVhbkxpdGVyYWwpIHtcbiAgICB0b2tlbiA9IGxleCgpO1xuICAgIHRva2VuLnZhbHVlID0gKHRva2VuLnZhbHVlID09PSAndHJ1ZScpO1xuICAgIGV4cHIgPSBmaW5pc2hMaXRlcmFsKHRva2VuKTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSBUb2tlbk51bGxMaXRlcmFsKSB7XG4gICAgdG9rZW4gPSBsZXgoKTtcbiAgICB0b2tlbi52YWx1ZSA9IG51bGw7XG4gICAgZXhwciA9IGZpbmlzaExpdGVyYWwodG9rZW4pO1xuICB9IGVsc2UgaWYgKG1hdGNoKCcvJykgfHwgbWF0Y2goJy89JykpIHtcbiAgICBleHByID0gZmluaXNoTGl0ZXJhbChzY2FuUmVnRXhwKCkpO1xuICAgIHBlZWskMSgpO1xuICB9IGVsc2Uge1xuICAgIHRocm93VW5leHBlY3RlZChsZXgoKSk7XG4gIH1cblxuICByZXR1cm4gZXhwcjtcbn1cblxuLy8gMTEuMiBMZWZ0LUhhbmQtU2lkZSBFeHByZXNzaW9uc1xuXG5mdW5jdGlvbiBwYXJzZUFyZ3VtZW50cygpIHtcbiAgdmFyIGFyZ3MgPSBbXTtcblxuICBleHBlY3QoJygnKTtcblxuICBpZiAoIW1hdGNoKCcpJykpIHtcbiAgICB3aGlsZSAoaW5kZXgkMSA8IGxlbmd0aCQyKSB7XG4gICAgICBhcmdzLnB1c2gocGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKSk7XG4gICAgICBpZiAobWF0Y2goJyknKSkge1xuICAgICAgICBicmVhaztcbiAgICAgIH1cbiAgICAgIGV4cGVjdCgnLCcpO1xuICAgIH1cbiAgfVxuXG4gIGV4cGVjdCgnKScpO1xuXG4gIHJldHVybiBhcmdzO1xufVxuXG5mdW5jdGlvbiBwYXJzZU5vbkNvbXB1dGVkUHJvcGVydHkoKSB7XG4gIHZhciB0b2tlbjtcbiAgaW5kZXgkMSA9IGxvb2thaGVhZC5zdGFydDtcbiAgdG9rZW4gPSBsZXgoKTtcblxuICBpZiAoIWlzSWRlbnRpZmllck5hbWUodG9rZW4pKSB7XG4gICAgdGhyb3dVbmV4cGVjdGVkKHRva2VuKTtcbiAgfVxuXG4gIHJldHVybiBmaW5pc2hJZGVudGlmaWVyKHRva2VuLnZhbHVlKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VOb25Db21wdXRlZE1lbWJlcigpIHtcbiAgZXhwZWN0KCcuJyk7XG5cbiAgcmV0dXJuIHBhcnNlTm9uQ29tcHV0ZWRQcm9wZXJ0eSgpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUNvbXB1dGVkTWVtYmVyKCkge1xuICB2YXIgZXhwcjtcblxuICBleHBlY3QoJ1snKTtcblxuICBleHByID0gcGFyc2VFeHByZXNzaW9uJDEoKTtcblxuICBleHBlY3QoJ10nKTtcblxuICByZXR1cm4gZXhwcjtcbn1cblxuZnVuY3Rpb24gcGFyc2VMZWZ0SGFuZFNpZGVFeHByZXNzaW9uQWxsb3dDYWxsKCkge1xuICB2YXIgZXhwciwgYXJncywgcHJvcGVydHk7XG5cbiAgZXhwciA9IHBhcnNlUHJpbWFyeUV4cHJlc3Npb24oKTtcblxuICBmb3IgKDs7KSB7XG4gICAgaWYgKG1hdGNoKCcuJykpIHtcbiAgICAgIHByb3BlcnR5ID0gcGFyc2VOb25Db21wdXRlZE1lbWJlcigpO1xuICAgICAgZXhwciA9IGZpbmlzaE1lbWJlckV4cHJlc3Npb24oJy4nLCBleHByLCBwcm9wZXJ0eSk7XG4gICAgfSBlbHNlIGlmIChtYXRjaCgnKCcpKSB7XG4gICAgICBhcmdzID0gcGFyc2VBcmd1bWVudHMoKTtcbiAgICAgIGV4cHIgPSBmaW5pc2hDYWxsRXhwcmVzc2lvbihleHByLCBhcmdzKTtcbiAgICB9IGVsc2UgaWYgKG1hdGNoKCdbJykpIHtcbiAgICAgIHByb3BlcnR5ID0gcGFyc2VDb21wdXRlZE1lbWJlcigpO1xuICAgICAgZXhwciA9IGZpbmlzaE1lbWJlckV4cHJlc3Npb24oJ1snLCBleHByLCBwcm9wZXJ0eSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGJyZWFrO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHByO1xufVxuXG4vLyAxMS4zIFBvc3RmaXggRXhwcmVzc2lvbnNcblxuZnVuY3Rpb24gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpIHtcbiAgdmFyIGV4cHIgPSBwYXJzZUxlZnRIYW5kU2lkZUV4cHJlc3Npb25BbGxvd0NhbGwoKTtcblxuICBpZiAobG9va2FoZWFkLnR5cGUgPT09IFRva2VuUHVuY3R1YXRvcikge1xuICAgIGlmICgobWF0Y2goJysrJykgfHwgbWF0Y2goJy0tJykpKSB7XG4gICAgICB0aHJvdyBuZXcgRXJyb3IoRElTQUJMRUQpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiBleHByO1xufVxuXG4vLyAxMS40IFVuYXJ5IE9wZXJhdG9yc1xuXG5mdW5jdGlvbiBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpIHtcbiAgdmFyIHRva2VuLCBleHByO1xuXG4gIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW5QdW5jdHVhdG9yICYmIGxvb2thaGVhZC50eXBlICE9PSBUb2tlbktleXdvcmQpIHtcbiAgICBleHByID0gcGFyc2VQb3N0Zml4RXhwcmVzc2lvbigpO1xuICB9IGVsc2UgaWYgKG1hdGNoKCcrKycpIHx8IG1hdGNoKCctLScpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKERJU0FCTEVEKTtcbiAgfSBlbHNlIGlmIChtYXRjaCgnKycpIHx8IG1hdGNoKCctJykgfHwgbWF0Y2goJ34nKSB8fCBtYXRjaCgnIScpKSB7XG4gICAgdG9rZW4gPSBsZXgoKTtcbiAgICBleHByID0gcGFyc2VVbmFyeUV4cHJlc3Npb24oKTtcbiAgICBleHByID0gZmluaXNoVW5hcnlFeHByZXNzaW9uKHRva2VuLnZhbHVlLCBleHByKTtcbiAgfSBlbHNlIGlmIChtYXRjaEtleXdvcmQoJ2RlbGV0ZScpIHx8IG1hdGNoS2V5d29yZCgndm9pZCcpIHx8IG1hdGNoS2V5d29yZCgndHlwZW9mJykpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoRElTQUJMRUQpO1xuICB9IGVsc2Uge1xuICAgIGV4cHIgPSBwYXJzZVBvc3RmaXhFeHByZXNzaW9uKCk7XG4gIH1cblxuICByZXR1cm4gZXhwcjtcbn1cblxuZnVuY3Rpb24gYmluYXJ5UHJlY2VkZW5jZSh0b2tlbikge1xuICB2YXIgcHJlYyA9IDA7XG5cbiAgaWYgKHRva2VuLnR5cGUgIT09IFRva2VuUHVuY3R1YXRvciAmJiB0b2tlbi50eXBlICE9PSBUb2tlbktleXdvcmQpIHtcbiAgICByZXR1cm4gMDtcbiAgfVxuXG4gIHN3aXRjaCAodG9rZW4udmFsdWUpIHtcbiAgICBjYXNlICd8fCc6XG4gICAgICBwcmVjID0gMTtcbiAgICAgIGJyZWFrO1xuXG4gICAgY2FzZSAnJiYnOlxuICAgICAgcHJlYyA9IDI7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ3wnOlxuICAgICAgcHJlYyA9IDM7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJ14nOlxuICAgICAgcHJlYyA9IDQ7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJyYnOlxuICAgICAgcHJlYyA9IDU7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJz09JzpcbiAgICBjYXNlICchPSc6XG4gICAgY2FzZSAnPT09JzpcbiAgICBjYXNlICchPT0nOlxuICAgICAgcHJlYyA9IDY7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJzwnOlxuICAgIGNhc2UgJz4nOlxuICAgIGNhc2UgJzw9JzpcbiAgICBjYXNlICc+PSc6XG4gICAgY2FzZSAnaW5zdGFuY2VvZic6XG4gICAgY2FzZSAnaW4nOlxuICAgICAgcHJlYyA9IDc7XG4gICAgICBicmVhaztcblxuICAgIGNhc2UgJzw8JzpcbiAgICBjYXNlICc+Pic6XG4gICAgY2FzZSAnPj4+JzpcbiAgICAgIHByZWMgPSA4O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICcrJzpcbiAgICBjYXNlICctJzpcbiAgICAgIHByZWMgPSA5O1xuICAgICAgYnJlYWs7XG5cbiAgICBjYXNlICcqJzpcbiAgICBjYXNlICcvJzpcbiAgICBjYXNlICclJzpcbiAgICAgIHByZWMgPSAxMTtcbiAgICAgIGJyZWFrO1xuXG4gICAgZGVmYXVsdDpcbiAgICAgIGJyZWFrO1xuICB9XG5cbiAgcmV0dXJuIHByZWM7XG59XG5cbi8vIDExLjUgTXVsdGlwbGljYXRpdmUgT3BlcmF0b3JzXG4vLyAxMS42IEFkZGl0aXZlIE9wZXJhdG9yc1xuLy8gMTEuNyBCaXR3aXNlIFNoaWZ0IE9wZXJhdG9yc1xuLy8gMTEuOCBSZWxhdGlvbmFsIE9wZXJhdG9yc1xuLy8gMTEuOSBFcXVhbGl0eSBPcGVyYXRvcnNcbi8vIDExLjEwIEJpbmFyeSBCaXR3aXNlIE9wZXJhdG9yc1xuLy8gMTEuMTEgQmluYXJ5IExvZ2ljYWwgT3BlcmF0b3JzXG5cbmZ1bmN0aW9uIHBhcnNlQmluYXJ5RXhwcmVzc2lvbigpIHtcbiAgdmFyIG1hcmtlciwgbWFya2VycywgZXhwciwgdG9rZW4sIHByZWMsIHN0YWNrLCByaWdodCwgb3BlcmF0b3IsIGxlZnQsIGk7XG5cbiAgbWFya2VyID0gbG9va2FoZWFkO1xuICBsZWZ0ID0gcGFyc2VVbmFyeUV4cHJlc3Npb24oKTtcblxuICB0b2tlbiA9IGxvb2thaGVhZDtcbiAgcHJlYyA9IGJpbmFyeVByZWNlZGVuY2UodG9rZW4pO1xuICBpZiAocHJlYyA9PT0gMCkge1xuICAgIHJldHVybiBsZWZ0O1xuICB9XG4gIHRva2VuLnByZWMgPSBwcmVjO1xuICBsZXgoKTtcblxuICBtYXJrZXJzID0gW21hcmtlciwgbG9va2FoZWFkXTtcbiAgcmlnaHQgPSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpO1xuXG4gIHN0YWNrID0gW2xlZnQsIHRva2VuLCByaWdodF07XG5cbiAgd2hpbGUgKChwcmVjID0gYmluYXJ5UHJlY2VkZW5jZShsb29rYWhlYWQpKSA+IDApIHtcblxuICAgIC8vIFJlZHVjZTogbWFrZSBhIGJpbmFyeSBleHByZXNzaW9uIGZyb20gdGhlIHRocmVlIHRvcG1vc3QgZW50cmllcy5cbiAgICB3aGlsZSAoKHN0YWNrLmxlbmd0aCA+IDIpICYmIChwcmVjIDw9IHN0YWNrW3N0YWNrLmxlbmd0aCAtIDJdLnByZWMpKSB7XG4gICAgICByaWdodCA9IHN0YWNrLnBvcCgpO1xuICAgICAgb3BlcmF0b3IgPSBzdGFjay5wb3AoKS52YWx1ZTtcbiAgICAgIGxlZnQgPSBzdGFjay5wb3AoKTtcbiAgICAgIG1hcmtlcnMucG9wKCk7XG4gICAgICBleHByID0gZmluaXNoQmluYXJ5RXhwcmVzc2lvbihvcGVyYXRvciwgbGVmdCwgcmlnaHQpO1xuICAgICAgc3RhY2sucHVzaChleHByKTtcbiAgICB9XG5cbiAgICAvLyBTaGlmdC5cbiAgICB0b2tlbiA9IGxleCgpO1xuICAgIHRva2VuLnByZWMgPSBwcmVjO1xuICAgIHN0YWNrLnB1c2godG9rZW4pO1xuICAgIG1hcmtlcnMucHVzaChsb29rYWhlYWQpO1xuICAgIGV4cHIgPSBwYXJzZVVuYXJ5RXhwcmVzc2lvbigpO1xuICAgIHN0YWNrLnB1c2goZXhwcik7XG4gIH1cblxuICAvLyBGaW5hbCByZWR1Y2UgdG8gY2xlYW4tdXAgdGhlIHN0YWNrLlxuICBpID0gc3RhY2subGVuZ3RoIC0gMTtcbiAgZXhwciA9IHN0YWNrW2ldO1xuICBtYXJrZXJzLnBvcCgpO1xuICB3aGlsZSAoaSA+IDEpIHtcbiAgICBtYXJrZXJzLnBvcCgpO1xuICAgIGV4cHIgPSBmaW5pc2hCaW5hcnlFeHByZXNzaW9uKHN0YWNrW2kgLSAxXS52YWx1ZSwgc3RhY2tbaSAtIDJdLCBleHByKTtcbiAgICBpIC09IDI7XG4gIH1cblxuICByZXR1cm4gZXhwcjtcbn1cblxuLy8gMTEuMTIgQ29uZGl0aW9uYWwgT3BlcmF0b3JcblxuZnVuY3Rpb24gcGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKSB7XG4gIHZhciBleHByLCBjb25zZXF1ZW50LCBhbHRlcm5hdGU7XG5cbiAgZXhwciA9IHBhcnNlQmluYXJ5RXhwcmVzc2lvbigpO1xuXG4gIGlmIChtYXRjaCgnPycpKSB7XG4gICAgbGV4KCk7XG4gICAgY29uc2VxdWVudCA9IHBhcnNlQ29uZGl0aW9uYWxFeHByZXNzaW9uKCk7XG4gICAgZXhwZWN0KCc6Jyk7XG4gICAgYWx0ZXJuYXRlID0gcGFyc2VDb25kaXRpb25hbEV4cHJlc3Npb24oKTtcblxuICAgIGV4cHIgPSBmaW5pc2hDb25kaXRpb25hbEV4cHJlc3Npb24oZXhwciwgY29uc2VxdWVudCwgYWx0ZXJuYXRlKTtcbiAgfVxuXG4gIHJldHVybiBleHByO1xufVxuXG4vLyAxMS4xNCBDb21tYSBPcGVyYXRvclxuXG5mdW5jdGlvbiBwYXJzZUV4cHJlc3Npb24kMSgpIHtcbiAgdmFyIGV4cHIgPSBwYXJzZUNvbmRpdGlvbmFsRXhwcmVzc2lvbigpO1xuXG4gIGlmIChtYXRjaCgnLCcpKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKERJU0FCTEVEKTsgLy8gbm8gc2VxdWVuY2UgZXhwcmVzc2lvbnNcbiAgfVxuXG4gIHJldHVybiBleHByO1xufVxuXG52YXIgcGFyc2UkMyA9IGZ1bmN0aW9uKGNvZGUpIHtcbiAgc291cmNlJDEgPSBjb2RlO1xuICBpbmRleCQxID0gMDtcbiAgbGVuZ3RoJDIgPSBzb3VyY2UkMS5sZW5ndGg7XG4gIGxvb2thaGVhZCA9IG51bGw7XG5cbiAgcGVlayQxKCk7XG5cbiAgdmFyIGV4cHIgPSBwYXJzZUV4cHJlc3Npb24kMSgpO1xuXG4gIGlmIChsb29rYWhlYWQudHlwZSAhPT0gVG9rZW5FT0YpIHtcbiAgICB0aHJvdyBuZXcgRXJyb3IoXCJVbmV4cGVjdCB0b2tlbiBhZnRlciBleHByZXNzaW9uLlwiKTtcbiAgfVxuICByZXR1cm4gZXhwcjtcbn07XG5cbnZhciBDb25zdGFudHMgPSB7XG4gIE5hTjogICAgICAgJ05hTicsXG4gIEU6ICAgICAgICAgJ01hdGguRScsXG4gIExOMjogICAgICAgJ01hdGguTE4yJyxcbiAgTE4xMDogICAgICAnTWF0aC5MTjEwJyxcbiAgTE9HMkU6ICAgICAnTWF0aC5MT0cyRScsXG4gIExPRzEwRTogICAgJ01hdGguTE9HMTBFJyxcbiAgUEk6ICAgICAgICAnTWF0aC5QSScsXG4gIFNRUlQxXzI6ICAgJ01hdGguU1FSVDFfMicsXG4gIFNRUlQyOiAgICAgJ01hdGguU1FSVDInLFxuICBNSU5fVkFMVUU6ICdOdW1iZXIuTUlOX1ZBTFVFJyxcbiAgTUFYX1ZBTFVFOiAnTnVtYmVyLk1BWF9WQUxVRSdcbn07XG5cbnZhciBGdW5jdGlvbnMgPSBmdW5jdGlvbihjb2RlZ2VuKSB7XG5cbiAgZnVuY3Rpb24gZm5jYWxsKG5hbWUsIGFyZ3MsIGNhc3QsIHR5cGUpIHtcbiAgICB2YXIgb2JqID0gY29kZWdlbihhcmdzWzBdKTtcbiAgICBpZiAoY2FzdCkge1xuICAgICAgb2JqID0gY2FzdCArICcoJyArIG9iaiArICcpJztcbiAgICAgIGlmIChjYXN0Lmxhc3RJbmRleE9mKCduZXcgJywgMCkgPT09IDApIG9iaiA9ICcoJyArIG9iaiArICcpJztcbiAgICB9XG4gICAgcmV0dXJuIG9iaiArICcuJyArIG5hbWUgKyAodHlwZSA8IDAgPyAnJyA6IHR5cGUgPT09IDAgP1xuICAgICAgJygpJyA6XG4gICAgICAnKCcgKyBhcmdzLnNsaWNlKDEpLm1hcChjb2RlZ2VuKS5qb2luKCcsJykgKyAnKScpO1xuICB9XG5cbiAgZnVuY3Rpb24gZm4obmFtZSwgY2FzdCwgdHlwZSkge1xuICAgIHJldHVybiBmdW5jdGlvbihhcmdzKSB7XG4gICAgICByZXR1cm4gZm5jYWxsKG5hbWUsIGFyZ3MsIGNhc3QsIHR5cGUpO1xuICAgIH07XG4gIH1cblxuICB2YXIgREFURSA9ICduZXcgRGF0ZScsXG4gICAgICBTVFJJTkcgPSAnU3RyaW5nJyxcbiAgICAgIFJFR0VYUCA9ICdSZWdFeHAnO1xuXG4gIHJldHVybiB7XG4gICAgLy8gTUFUSCBmdW5jdGlvbnNcbiAgICBpc05hTjogICAgJ2lzTmFOJyxcbiAgICBpc0Zpbml0ZTogJ2lzRmluaXRlJyxcbiAgICBhYnM6ICAgICAgJ01hdGguYWJzJyxcbiAgICBhY29zOiAgICAgJ01hdGguYWNvcycsXG4gICAgYXNpbjogICAgICdNYXRoLmFzaW4nLFxuICAgIGF0YW46ICAgICAnTWF0aC5hdGFuJyxcbiAgICBhdGFuMjogICAgJ01hdGguYXRhbjInLFxuICAgIGNlaWw6ICAgICAnTWF0aC5jZWlsJyxcbiAgICBjb3M6ICAgICAgJ01hdGguY29zJyxcbiAgICBleHA6ICAgICAgJ01hdGguZXhwJyxcbiAgICBmbG9vcjogICAgJ01hdGguZmxvb3InLFxuICAgIGxvZzogICAgICAnTWF0aC5sb2cnLFxuICAgIG1heDogICAgICAnTWF0aC5tYXgnLFxuICAgIG1pbjogICAgICAnTWF0aC5taW4nLFxuICAgIHBvdzogICAgICAnTWF0aC5wb3cnLFxuICAgIHJhbmRvbTogICAnTWF0aC5yYW5kb20nLFxuICAgIHJvdW5kOiAgICAnTWF0aC5yb3VuZCcsXG4gICAgc2luOiAgICAgICdNYXRoLnNpbicsXG4gICAgc3FydDogICAgICdNYXRoLnNxcnQnLFxuICAgIHRhbjogICAgICAnTWF0aC50YW4nLFxuXG4gICAgY2xhbXA6IGZ1bmN0aW9uKGFyZ3MpIHtcbiAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDMpIGVycm9yJDEoJ01pc3NpbmcgYXJndW1lbnRzIHRvIGNsYW1wIGZ1bmN0aW9uLicpO1xuICAgICAgaWYgKGFyZ3MubGVuZ3RoID4gMykgZXJyb3IkMSgnVG9vIG1hbnkgYXJndW1lbnRzIHRvIGNsYW1wIGZ1bmN0aW9uLicpO1xuICAgICAgdmFyIGEgPSBhcmdzLm1hcChjb2RlZ2VuKTtcbiAgICAgIHJldHVybiAnTWF0aC5tYXgoJythWzFdKycsIE1hdGgubWluKCcrYVsyXSsnLCcrYVswXSsnKSknO1xuICAgIH0sXG5cbiAgICAvLyBEQVRFIGZ1bmN0aW9uc1xuICAgIG5vdzogICAgICAgICAgICAgJ0RhdGUubm93JyxcbiAgICB1dGM6ICAgICAgICAgICAgICdEYXRlLlVUQycsXG4gICAgZGF0ZXRpbWU6ICAgICAgICBEQVRFLFxuICAgIGRhdGU6ICAgICAgICAgICAgZm4oJ2dldERhdGUnLCBEQVRFLCAwKSxcbiAgICBkYXk6ICAgICAgICAgICAgIGZuKCdnZXREYXknLCBEQVRFLCAwKSxcbiAgICB5ZWFyOiAgICAgICAgICAgIGZuKCdnZXRGdWxsWWVhcicsIERBVEUsIDApLFxuICAgIG1vbnRoOiAgICAgICAgICAgZm4oJ2dldE1vbnRoJywgREFURSwgMCksXG4gICAgaG91cnM6ICAgICAgICAgICBmbignZ2V0SG91cnMnLCBEQVRFLCAwKSxcbiAgICBtaW51dGVzOiAgICAgICAgIGZuKCdnZXRNaW51dGVzJywgREFURSwgMCksXG4gICAgc2Vjb25kczogICAgICAgICBmbignZ2V0U2Vjb25kcycsIERBVEUsIDApLFxuICAgIG1pbGxpc2Vjb25kczogICAgZm4oJ2dldE1pbGxpc2Vjb25kcycsIERBVEUsIDApLFxuICAgIHRpbWU6ICAgICAgICAgICAgZm4oJ2dldFRpbWUnLCBEQVRFLCAwKSxcbiAgICB0aW1lem9uZW9mZnNldDogIGZuKCdnZXRUaW1lem9uZU9mZnNldCcsIERBVEUsIDApLFxuICAgIHV0Y2RhdGU6ICAgICAgICAgZm4oJ2dldFVUQ0RhdGUnLCBEQVRFLCAwKSxcbiAgICB1dGNkYXk6ICAgICAgICAgIGZuKCdnZXRVVENEYXknLCBEQVRFLCAwKSxcbiAgICB1dGN5ZWFyOiAgICAgICAgIGZuKCdnZXRVVENGdWxsWWVhcicsIERBVEUsIDApLFxuICAgIHV0Y21vbnRoOiAgICAgICAgZm4oJ2dldFVUQ01vbnRoJywgREFURSwgMCksXG4gICAgdXRjaG91cnM6ICAgICAgICBmbignZ2V0VVRDSG91cnMnLCBEQVRFLCAwKSxcbiAgICB1dGNtaW51dGVzOiAgICAgIGZuKCdnZXRVVENNaW51dGVzJywgREFURSwgMCksXG4gICAgdXRjc2Vjb25kczogICAgICBmbignZ2V0VVRDU2Vjb25kcycsIERBVEUsIDApLFxuICAgIHV0Y21pbGxpc2Vjb25kczogZm4oJ2dldFVUQ01pbGxpc2Vjb25kcycsIERBVEUsIDApLFxuXG4gICAgLy8gc2hhcmVkIHNlcXVlbmNlIGZ1bmN0aW9uc1xuICAgIGxlbmd0aDogICAgICBmbignbGVuZ3RoJywgbnVsbCwgLTEpLFxuICAgIGluZGV4b2Y6ICAgICBmbignaW5kZXhPZicsIG51bGwpLFxuICAgIGxhc3RpbmRleG9mOiBmbignbGFzdEluZGV4T2YnLCBudWxsKSxcbiAgICBzbGljZTogICAgICAgZm4oJ3NsaWNlJywgbnVsbCksXG5cbiAgICAvLyBTVFJJTkcgZnVuY3Rpb25zXG4gICAgcGFyc2VGbG9hdDogICdwYXJzZUZsb2F0JyxcbiAgICBwYXJzZUludDogICAgJ3BhcnNlSW50JyxcbiAgICB1cHBlcjogICAgICAgZm4oJ3RvVXBwZXJDYXNlJywgU1RSSU5HLCAwKSxcbiAgICBsb3dlcjogICAgICAgZm4oJ3RvTG93ZXJDYXNlJywgU1RSSU5HLCAwKSxcbiAgICBzdWJzdHJpbmc6ICAgZm4oJ3N1YnN0cmluZycsIFNUUklORyksXG4gICAgcmVwbGFjZTogICAgIGZuKCdyZXBsYWNlJywgU1RSSU5HKSxcblxuICAgIC8vIFJFR0VYUCBmdW5jdGlvbnNcbiAgICByZWdleHA6ICBSRUdFWFAsXG4gICAgdGVzdDogICAgZm4oJ3Rlc3QnLCBSRUdFWFApLFxuXG4gICAgLy8gQ29udHJvbCBGbG93IGZ1bmN0aW9uc1xuICAgIGlmOiBmdW5jdGlvbihhcmdzKSB7XG4gICAgICAgIGlmIChhcmdzLmxlbmd0aCA8IDMpIGVycm9yJDEoJ01pc3NpbmcgYXJndW1lbnRzIHRvIGlmIGZ1bmN0aW9uLicpO1xuICAgICAgICBpZiAoYXJncy5sZW5ndGggPiAzKSBlcnJvciQxKCdUb28gbWFueSBhcmd1bWVudHMgdG8gaWYgZnVuY3Rpb24uJyk7XG4gICAgICAgIHZhciBhID0gYXJncy5tYXAoY29kZWdlbik7XG4gICAgICAgIHJldHVybiAnKCcrYVswXSsnPycrYVsxXSsnOicrYVsyXSsnKSc7XG4gICAgICB9XG4gIH07XG59O1xuXG52YXIgY29kZWdlbiA9IGZ1bmN0aW9uKG9wdCkge1xuICBvcHQgPSBvcHQgfHwge307XG5cbiAgdmFyIHdoaXRlbGlzdCA9IG9wdC53aGl0ZWxpc3QgPyB0b1NldChvcHQud2hpdGVsaXN0KSA6IHt9LFxuICAgICAgYmxhY2tsaXN0ID0gb3B0LmJsYWNrbGlzdCA/IHRvU2V0KG9wdC5ibGFja2xpc3QpIDoge30sXG4gICAgICBjb25zdGFudHMgPSBvcHQuY29uc3RhbnRzIHx8IENvbnN0YW50cyxcbiAgICAgIGZ1bmN0aW9ucyA9IChvcHQuZnVuY3Rpb25zIHx8IEZ1bmN0aW9ucykodmlzaXQpLFxuICAgICAgZ2xvYmFsdmFyID0gb3B0Lmdsb2JhbHZhcixcbiAgICAgIGZpZWxkdmFyID0gb3B0LmZpZWxkdmFyLFxuICAgICAgZ2xvYmFscyA9IHt9LFxuICAgICAgZmllbGRzID0ge30sXG4gICAgICBtZW1iZXJEZXB0aCA9IDA7XG5cbiAgdmFyIG91dHB1dEdsb2JhbCA9IGlzRnVuY3Rpb24oZ2xvYmFsdmFyKVxuICAgID8gZ2xvYmFsdmFyXG4gICAgOiBmdW5jdGlvbiAoaWQkJDEpIHsgcmV0dXJuIGdsb2JhbHZhciArICdbXCInICsgaWQkJDEgKyAnXCJdJzsgfTtcblxuICBmdW5jdGlvbiB2aXNpdChhc3QpIHtcbiAgICBpZiAoaXNTdHJpbmcoYXN0KSkgcmV0dXJuIGFzdDtcbiAgICB2YXIgZ2VuZXJhdG9yID0gR2VuZXJhdG9yc1thc3QudHlwZV07XG4gICAgaWYgKGdlbmVyYXRvciA9PSBudWxsKSBlcnJvciQxKCdVbnN1cHBvcnRlZCB0eXBlOiAnICsgYXN0LnR5cGUpO1xuICAgIHJldHVybiBnZW5lcmF0b3IoYXN0KTtcbiAgfVxuXG4gIHZhciBHZW5lcmF0b3JzID0ge1xuICAgIExpdGVyYWw6IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuIG4ucmF3O1xuICAgICAgfSxcblxuICAgIElkZW50aWZpZXI6IGZ1bmN0aW9uKG4pIHtcbiAgICAgIHZhciBpZCQkMSA9IG4ubmFtZTtcbiAgICAgIGlmIChtZW1iZXJEZXB0aCA+IDApIHtcbiAgICAgICAgcmV0dXJuIGlkJCQxO1xuICAgICAgfSBlbHNlIGlmIChibGFja2xpc3QuaGFzT3duUHJvcGVydHkoaWQkJDEpKSB7XG4gICAgICAgIHJldHVybiBlcnJvciQxKCdJbGxlZ2FsIGlkZW50aWZpZXI6ICcgKyBpZCQkMSk7XG4gICAgICB9IGVsc2UgaWYgKGNvbnN0YW50cy5oYXNPd25Qcm9wZXJ0eShpZCQkMSkpIHtcbiAgICAgICAgcmV0dXJuIGNvbnN0YW50c1tpZCQkMV07XG4gICAgICB9IGVsc2UgaWYgKHdoaXRlbGlzdC5oYXNPd25Qcm9wZXJ0eShpZCQkMSkpIHtcbiAgICAgICAgcmV0dXJuIGlkJCQxO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZ2xvYmFsc1tpZCQkMV0gPSAxO1xuICAgICAgICByZXR1cm4gb3V0cHV0R2xvYmFsKGlkJCQxKTtcbiAgICAgIH1cbiAgICB9LFxuXG4gICAgTWVtYmVyRXhwcmVzc2lvbjogZnVuY3Rpb24obikge1xuICAgICAgICB2YXIgZCA9ICFuLmNvbXB1dGVkO1xuICAgICAgICB2YXIgbyA9IHZpc2l0KG4ub2JqZWN0KTtcbiAgICAgICAgaWYgKGQpIG1lbWJlckRlcHRoICs9IDE7XG4gICAgICAgIHZhciBwID0gdmlzaXQobi5wcm9wZXJ0eSk7XG4gICAgICAgIGlmIChvID09PSBmaWVsZHZhcikgeyBmaWVsZHNbcF0gPSAxOyB9IC8vIEhBQ0tpc2guLi5cbiAgICAgICAgaWYgKGQpIG1lbWJlckRlcHRoIC09IDE7XG4gICAgICAgIHJldHVybiBvICsgKGQgPyAnLicrcCA6ICdbJytwKyddJyk7XG4gICAgICB9LFxuXG4gICAgQ2FsbEV4cHJlc3Npb246IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgaWYgKG4uY2FsbGVlLnR5cGUgIT09ICdJZGVudGlmaWVyJykge1xuICAgICAgICAgIGVycm9yJDEoJ0lsbGVnYWwgY2FsbGVlIHR5cGU6ICcgKyBuLmNhbGxlZS50eXBlKTtcbiAgICAgICAgfVxuICAgICAgICB2YXIgY2FsbGVlID0gbi5jYWxsZWUubmFtZTtcbiAgICAgICAgdmFyIGFyZ3MgPSBuLmFyZ3VtZW50cztcbiAgICAgICAgdmFyIGZuID0gZnVuY3Rpb25zLmhhc093blByb3BlcnR5KGNhbGxlZSkgJiYgZnVuY3Rpb25zW2NhbGxlZV07XG4gICAgICAgIGlmICghZm4pIGVycm9yJDEoJ1VucmVjb2duaXplZCBmdW5jdGlvbjogJyArIGNhbGxlZSk7XG4gICAgICAgIHJldHVybiBpc0Z1bmN0aW9uKGZuKVxuICAgICAgICAgID8gZm4oYXJncylcbiAgICAgICAgICA6IGZuICsgJygnICsgYXJncy5tYXAodmlzaXQpLmpvaW4oJywnKSArICcpJztcbiAgICAgIH0sXG5cbiAgICBBcnJheUV4cHJlc3Npb246IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuICdbJyArIG4uZWxlbWVudHMubWFwKHZpc2l0KS5qb2luKCcsJykgKyAnXSc7XG4gICAgICB9LFxuXG4gICAgQmluYXJ5RXhwcmVzc2lvbjogZnVuY3Rpb24obikge1xuICAgICAgICByZXR1cm4gJygnICsgdmlzaXQobi5sZWZ0KSArIG4ub3BlcmF0b3IgKyB2aXNpdChuLnJpZ2h0KSArICcpJztcbiAgICAgIH0sXG5cbiAgICBVbmFyeUV4cHJlc3Npb246IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuICcoJyArIG4ub3BlcmF0b3IgKyB2aXNpdChuLmFyZ3VtZW50KSArICcpJztcbiAgICAgIH0sXG5cbiAgICBDb25kaXRpb25hbEV4cHJlc3Npb246IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuICcoJyArIHZpc2l0KG4udGVzdCkgK1xuICAgICAgICAgICc/JyArIHZpc2l0KG4uY29uc2VxdWVudCkgK1xuICAgICAgICAgICc6JyArIHZpc2l0KG4uYWx0ZXJuYXRlKSArXG4gICAgICAgICAgJyknO1xuICAgICAgfSxcblxuICAgIExvZ2ljYWxFeHByZXNzaW9uOiBmdW5jdGlvbihuKSB7XG4gICAgICAgIHJldHVybiAnKCcgKyB2aXNpdChuLmxlZnQpICsgbi5vcGVyYXRvciArIHZpc2l0KG4ucmlnaHQpICsgJyknO1xuICAgICAgfSxcblxuICAgIE9iamVjdEV4cHJlc3Npb246IGZ1bmN0aW9uKG4pIHtcbiAgICAgICAgcmV0dXJuICd7JyArIG4ucHJvcGVydGllcy5tYXAodmlzaXQpLmpvaW4oJywnKSArICd9JztcbiAgICAgIH0sXG5cbiAgICBQcm9wZXJ0eTogZnVuY3Rpb24obikge1xuICAgICAgICBtZW1iZXJEZXB0aCArPSAxO1xuICAgICAgICB2YXIgayA9IHZpc2l0KG4ua2V5KTtcbiAgICAgICAgbWVtYmVyRGVwdGggLT0gMTtcbiAgICAgICAgcmV0dXJuIGsgKyAnOicgKyB2aXNpdChuLnZhbHVlKTtcbiAgICAgIH1cbiAgfTtcblxuICBmdW5jdGlvbiBjb2RlZ2VuKGFzdCkge1xuICAgIHZhciByZXN1bHQgPSB7XG4gICAgICBjb2RlOiAgICB2aXNpdChhc3QpLFxuICAgICAgZ2xvYmFsczogT2JqZWN0LmtleXMoZ2xvYmFscyksXG4gICAgICBmaWVsZHM6ICBPYmplY3Qua2V5cyhmaWVsZHMpXG4gICAgfTtcbiAgICBnbG9iYWxzID0ge307XG4gICAgZmllbGRzID0ge307XG4gICAgcmV0dXJuIHJlc3VsdDtcbiAgfVxuXG4gIGNvZGVnZW4uZnVuY3Rpb25zID0gZnVuY3Rpb25zO1xuICBjb2RlZ2VuLmNvbnN0YW50cyA9IGNvbnN0YW50cztcblxuICByZXR1cm4gY29kZWdlbjtcbn07XG5cbnZhciBmb3JtYXRDYWNoZSA9IHt9O1xuXG5mdW5jdGlvbiBmb3JtYXR0ZXIodHlwZSwgbWV0aG9kLCBzcGVjaWZpZXIpIHtcbiAgdmFyIGsgPSB0eXBlICsgJzonICsgc3BlY2lmaWVyLFxuICAgICAgZSA9IGZvcm1hdENhY2hlW2tdO1xuICBpZiAoIWUgfHwgZVswXSAhPT0gbWV0aG9kKSB7XG4gICAgZm9ybWF0Q2FjaGVba10gPSAoZSA9IFttZXRob2QsIG1ldGhvZChzcGVjaWZpZXIpXSk7XG4gIH1cbiAgcmV0dXJuIGVbMV07XG59XG5cbmZ1bmN0aW9uIGZvcm1hdCQxKF8sIHNwZWNpZmllcikge1xuICByZXR1cm4gZm9ybWF0dGVyKCdmb3JtYXQnLCBmb3JtYXQsIHNwZWNpZmllcikoXyk7XG59XG5cbmZ1bmN0aW9uIHRpbWVGb3JtYXQkMShfLCBzcGVjaWZpZXIpIHtcbiAgcmV0dXJuIGZvcm1hdHRlcigndGltZUZvcm1hdCcsIHRpbWVGb3JtYXQsIHNwZWNpZmllcikoXyk7XG59XG5cbmZ1bmN0aW9uIHV0Y0Zvcm1hdCQxKF8sIHNwZWNpZmllcikge1xuICByZXR1cm4gZm9ybWF0dGVyKCd1dGNGb3JtYXQnLCB1dGNGb3JtYXQsIHNwZWNpZmllcikoXyk7XG59XG5cbmZ1bmN0aW9uIHRpbWVQYXJzZSQxKF8sIHNwZWNpZmllcikge1xuICByZXR1cm4gZm9ybWF0dGVyKCd0aW1lUGFyc2UnLCB0aW1lUGFyc2UsIHNwZWNpZmllcikoXyk7XG59XG5cbmZ1bmN0aW9uIHV0Y1BhcnNlJDEoXywgc3BlY2lmaWVyKSB7XG4gIHJldHVybiBmb3JtYXR0ZXIoJ3V0Y1BhcnNlJywgdXRjUGFyc2UsIHNwZWNpZmllcikoXyk7XG59XG5cbnZhciBkYXRlT2JqID0gbmV3IERhdGUoMjAwMCwgMCwgMSk7XG5cbmZ1bmN0aW9uIHRpbWUkMihtb250aCwgZGF5LCBzcGVjaWZpZXIpIHtcbiAgZGF0ZU9iai5zZXRNb250aChtb250aCk7XG4gIGRhdGVPYmouc2V0RGF0ZShkYXkpO1xuICByZXR1cm4gdGltZUZvcm1hdCQxKGRhdGVPYmosIHNwZWNpZmllcik7XG59XG5cbmZ1bmN0aW9uIG1vbnRoRm9ybWF0KG1vbnRoKSB7XG4gIHJldHVybiB0aW1lJDIobW9udGgsIDEsICclQicpO1xufVxuXG5mdW5jdGlvbiBtb250aEFiYnJldkZvcm1hdChtb250aCkge1xuICByZXR1cm4gdGltZSQyKG1vbnRoLCAxLCAnJWInKTtcbn1cblxuZnVuY3Rpb24gZGF5Rm9ybWF0KGRheSkge1xuICByZXR1cm4gdGltZSQyKDAsIDIgKyBkYXksICclQScpO1xufVxuXG5mdW5jdGlvbiBkYXlBYmJyZXZGb3JtYXQoZGF5KSB7XG4gIHJldHVybiB0aW1lJDIoMCwgMiArIGRheSwgJyVhJyk7XG59XG5cbmZ1bmN0aW9uIHF1YXJ0ZXIoZGF0ZSkge1xuICByZXR1cm4gMSArIH5+KG5ldyBEYXRlKGRhdGUpLmdldE1vbnRoKCkgLyAzKTtcbn1cblxuZnVuY3Rpb24gdXRjcXVhcnRlcihkYXRlKSB7XG4gIHJldHVybiAxICsgfn4obmV3IERhdGUoZGF0ZSkuZ2V0VVRDTW9udGgoKSAvIDMpO1xufVxuXG5mdW5jdGlvbiBsb2ckNChkZiwgbWV0aG9kLCBhcmdzKSB7XG4gIHRyeSB7XG4gICAgZGZbbWV0aG9kXS5hcHBseShkZiwgWydFWFBSRVNTSU9OJ10uY29uY2F0KFtdLnNsaWNlLmNhbGwoYXJncykpKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZGYud2FybihlcnIpO1xuICB9XG4gIHJldHVybiBhcmdzW2FyZ3MubGVuZ3RoLTFdO1xufVxuXG5mdW5jdGlvbiB3YXJuKCkge1xuICByZXR1cm4gbG9nJDQodGhpcy5jb250ZXh0LmRhdGFmbG93LCAnd2FybicsIGFyZ3VtZW50cyk7XG59XG5cbmZ1bmN0aW9uIGluZm8oKSB7XG4gIHJldHVybiBsb2ckNCh0aGlzLmNvbnRleHQuZGF0YWZsb3csICdpbmZvJywgYXJndW1lbnRzKTtcbn1cblxuZnVuY3Rpb24gZGVidWcoKSB7XG4gIHJldHVybiBsb2ckNCh0aGlzLmNvbnRleHQuZGF0YWZsb3csICdkZWJ1ZycsIGFyZ3VtZW50cyk7XG59XG5cbnZhciBpblNjb3BlID0gZnVuY3Rpb24oaXRlbSkge1xuICB2YXIgZ3JvdXAgPSB0aGlzLmNvbnRleHQuZ3JvdXAsXG4gICAgICB2YWx1ZSA9IGZhbHNlO1xuXG4gIGlmIChncm91cCkgd2hpbGUgKGl0ZW0pIHtcbiAgICBpZiAoaXRlbSA9PT0gZ3JvdXApIHsgdmFsdWUgPSB0cnVlOyBicmVhazsgfVxuICAgIGl0ZW0gPSBpdGVtLm1hcmsuZ3JvdXA7XG4gIH1cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuLyoqXG4gKiBTcGFuLXByZXNlcnZpbmcgcmFuZ2UgY2xhbXAuIElmIHRoZSBzcGFuIG9mIHRoZSBpbnB1dCByYW5nZSBpcyBsZXNzXG4gKiB0aGFuIChtYXggLSBtaW4pIGFuZCBhbiBlbmRwb2ludCBleGNlZWRzIGVpdGhlciB0aGUgbWluIG9yIG1heCB2YWx1ZSxcbiAqIHRoZSByYW5nZSBpcyB0cmFuc2xhdGVkIHN1Y2ggdGhhdCB0aGUgc3BhbiBpcyBwcmVzZXJ2ZWQgYW5kIG9uZVxuICogZW5kcG9pbnQgdG91Y2hlcyB0aGUgYm91bmRhcnkgb2YgdGhlIG1pbi9tYXggcmFuZ2UuXG4gKiBJZiB0aGUgc3BhbiBleGNlZWRzIChtYXggLSBtaW4pLCB0aGUgcmFuZ2UgW21pbiwgbWF4XSBpcyByZXR1cm5lZC5cbiAqL1xudmFyIGNsYW1wUmFuZ2UgPSBmdW5jdGlvbihyYW5nZSwgbWluLCBtYXgpIHtcbiAgdmFyIGxvID0gcmFuZ2VbMF0sXG4gICAgICBoaSA9IHJhbmdlWzFdLFxuICAgICAgc3BhbjtcblxuICBpZiAoaGkgPCBsbykge1xuICAgIHNwYW4gPSBoaTtcbiAgICBoaSA9IGxvO1xuICAgIGxvID0gc3BhbjtcbiAgfVxuICBzcGFuID0gaGkgLSBsbztcblxuICByZXR1cm4gc3BhbiA+PSAobWF4IC0gbWluKVxuICAgID8gW21pbiwgbWF4XVxuICAgIDogW1xuICAgICAgICBNYXRoLm1pbihNYXRoLm1heChsbywgbWluKSwgbWF4IC0gc3BhbiksXG4gICAgICAgIE1hdGgubWluKE1hdGgubWF4KGhpLCBzcGFuKSwgbWF4KVxuICAgICAgXTtcbn07XG5cbmZ1bmN0aW9uIHBpbmNoRGlzdGFuY2UoZXZlbnQpIHtcbiAgdmFyIHQgPSBldmVudC50b3VjaGVzLFxuICAgICAgZHggPSB0WzBdLmNsaWVudFggLSB0WzFdLmNsaWVudFgsXG4gICAgICBkeSA9IHRbMF0uY2xpZW50WSAtIHRbMV0uY2xpZW50WTtcbiAgcmV0dXJuIE1hdGguc3FydChkeCAqIGR4ICsgZHkgKiBkeSk7XG59XG5cbmZ1bmN0aW9uIHBpbmNoQW5nbGUoZXZlbnQpIHtcbiAgdmFyIHQgPSBldmVudC50b3VjaGVzO1xuICByZXR1cm4gTWF0aC5hdGFuMihcbiAgICB0WzBdLmNsaWVudFkgLSB0WzFdLmNsaWVudFksXG4gICAgdFswXS5jbGllbnRYIC0gdFsxXS5jbGllbnRYXG4gICk7XG59XG5cbnZhciBfd2luZG93ID0gKHR5cGVvZiB3aW5kb3cgIT09ICd1bmRlZmluZWQnICYmIHdpbmRvdykgfHwgbnVsbDtcblxuZnVuY3Rpb24gc2NyZWVuKCkge1xuICByZXR1cm4gX3dpbmRvdyA/IF93aW5kb3cuc2NyZWVuIDoge307XG59XG5cbmZ1bmN0aW9uIHdpbmRvd1NpemUoKSB7XG4gIHJldHVybiBfd2luZG93XG4gICAgPyBbX3dpbmRvdy5pbm5lcldpZHRoLCBfd2luZG93LmlubmVySGVpZ2h0XVxuICAgIDogW3VuZGVmaW5lZCwgdW5kZWZpbmVkXTtcbn1cblxuZnVuY3Rpb24gY29udGFpbmVyU2l6ZSgpIHtcbiAgdmFyIHZpZXcgPSB0aGlzLmNvbnRleHQuZGF0YWZsb3csXG4gICAgICBlbCA9IHZpZXcuY29udGFpbmVyICYmIHZpZXcuY29udGFpbmVyKCk7XG4gIHJldHVybiBlbFxuICAgID8gW2VsLmNsaWVudFdpZHRoLCBlbC5jbGllbnRIZWlnaHRdXG4gICAgOiBbdW5kZWZpbmVkLCB1bmRlZmluZWRdO1xufVxuXG52YXIgZmx1c2ggPSBmdW5jdGlvbihyYW5nZSwgdmFsdWUsIHRocmVzaG9sZCwgbGVmdCwgcmlnaHQsIGNlbnRlcikge1xuICB2YXIgbCA9IE1hdGguYWJzKHZhbHVlIC0gcmFuZ2VbMF0pLFxuICAgICAgciA9IE1hdGguYWJzKHBlZWsocmFuZ2UpIC0gdmFsdWUpO1xuICByZXR1cm4gbCA8IHIgJiYgbCA8PSB0aHJlc2hvbGQgPyBsZWZ0XG4gICAgOiByIDw9IHRocmVzaG9sZCA/IHJpZ2h0XG4gICAgOiBjZW50ZXI7XG59O1xuXG52YXIgc3BhbiA9IGZ1bmN0aW9uKGFycmF5KSB7XG4gIHJldHVybiAoYXJyYXlbYXJyYXkubGVuZ3RoLTFdIC0gYXJyYXlbMF0pIHx8IDA7XG59O1xuXG52YXIgTGl0ZXJhbCA9ICdMaXRlcmFsJztcbnZhciBJZGVudGlmaWVyJDEgPSAnSWRlbnRpZmllcic7XG5cbnZhciBpbmRleFByZWZpeCAgPSAnQCc7XG52YXIgc2NhbGVQcmVmaXggID0gJyUnO1xudmFyIGRhdGFQcmVmaXggICA9ICc6JztcblxuZnVuY3Rpb24gZ2V0U2NhbGUobmFtZSwgY3R4KSB7XG4gIHZhciBzO1xuICByZXR1cm4gaXNGdW5jdGlvbihuYW1lKSA/IG5hbWVcbiAgICA6IGlzU3RyaW5nKG5hbWUpID8gKHMgPSBjdHguc2NhbGVzW25hbWVdKSAmJiBzLnZhbHVlXG4gICAgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGFkZFNjYWxlRGVwZW5kZW5jeShzY29wZSwgcGFyYW1zLCBuYW1lKSB7XG4gIHZhciBzY2FsZU5hbWUgPSBzY2FsZVByZWZpeCArIG5hbWU7XG4gIGlmICghcGFyYW1zLmhhc093blByb3BlcnR5KHNjYWxlTmFtZSkpIHtcbiAgICB0cnkge1xuICAgICAgcGFyYW1zW3NjYWxlTmFtZV0gPSBzY29wZS5zY2FsZVJlZihuYW1lKTtcbiAgICB9IGNhdGNoIChlcnIpIHtcbiAgICAgIC8vIFRPRE86IGVycm9yIGhhbmRsaW5nPyB3YXJuaW5nP1xuICAgIH1cbiAgfVxufVxuXG5mdW5jdGlvbiBzY2FsZVZpc2l0b3IobmFtZSwgYXJncywgc2NvcGUsIHBhcmFtcykge1xuICBpZiAoYXJnc1swXS50eXBlID09PSBMaXRlcmFsKSB7XG4gICAgLy8gYWRkIHNjYWxlIGRlcGVuZGVuY3lcbiAgICBhZGRTY2FsZURlcGVuZGVuY3koc2NvcGUsIHBhcmFtcywgYXJnc1swXS52YWx1ZSk7XG4gIH1cbiAgZWxzZSBpZiAoYXJnc1swXS50eXBlID09PSBJZGVudGlmaWVyJDEpIHtcbiAgICAvLyBpbmRpcmVjdCBzY2FsZSBsb29rdXA7IGFkZCBhbGwgc2NhbGVzIGFzIHBhcmFtZXRlcnNcbiAgICBmb3IgKG5hbWUgaW4gc2NvcGUuc2NhbGVzKSB7XG4gICAgICBhZGRTY2FsZURlcGVuZGVuY3koc2NvcGUsIHBhcmFtcywgbmFtZSk7XG4gICAgfVxuICB9XG59XG5cbmZ1bmN0aW9uIHJhbmdlJDIobmFtZSwgZ3JvdXApIHtcbiAgdmFyIHMgPSBnZXRTY2FsZShuYW1lLCAoZ3JvdXAgfHwgdGhpcykuY29udGV4dCk7XG4gIHJldHVybiBzICYmIHMucmFuZ2UgPyBzLnJhbmdlKCkgOiBbXTtcbn1cblxuZnVuY3Rpb24gZG9tYWluKG5hbWUsIGdyb3VwKSB7XG4gIHZhciBzID0gZ2V0U2NhbGUobmFtZSwgKGdyb3VwIHx8IHRoaXMpLmNvbnRleHQpO1xuICByZXR1cm4gcyA/IHMuZG9tYWluKCkgOiBbXTtcbn1cblxuZnVuY3Rpb24gYmFuZHdpZHRoKG5hbWUsIGdyb3VwKSB7XG4gIHZhciBzID0gZ2V0U2NhbGUobmFtZSwgKGdyb3VwIHx8IHRoaXMpLmNvbnRleHQpO1xuICByZXR1cm4gcyAmJiBzLmJhbmR3aWR0aCA/IHMuYmFuZHdpZHRoKCkgOiAwO1xufVxuXG5mdW5jdGlvbiBiYW5kc3BhY2UoY291bnQsIHBhZGRpbmdJbm5lciwgcGFkZGluZ091dGVyKSB7XG4gIHJldHVybiBiYW5kU3BhY2UoY291bnQgfHwgMCwgcGFkZGluZ0lubmVyIHx8IDAsIHBhZGRpbmdPdXRlciB8fCAwKTtcbn1cblxuZnVuY3Rpb24gY29weSQxKG5hbWUsIGdyb3VwKSB7XG4gIHZhciBzID0gZ2V0U2NhbGUobmFtZSwgKGdyb3VwIHx8IHRoaXMpLmNvbnRleHQpO1xuICByZXR1cm4gcyA/IHMuY29weSgpIDogdW5kZWZpbmVkO1xufVxuXG5mdW5jdGlvbiBzY2FsZSQyKG5hbWUsIHZhbHVlLCBncm91cCkge1xuICB2YXIgcyA9IGdldFNjYWxlKG5hbWUsIChncm91cCB8fCB0aGlzKS5jb250ZXh0KTtcbiAgcmV0dXJuIHMgPyBzKHZhbHVlKSA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gaW52ZXJ0KG5hbWUsIHJhbmdlLCBncm91cCkge1xuICB2YXIgcyA9IGdldFNjYWxlKG5hbWUsIChncm91cCB8fCB0aGlzKS5jb250ZXh0KTtcbiAgcmV0dXJuICFzID8gdW5kZWZpbmVkXG4gICAgOiBpc0FycmF5KHJhbmdlKSA/IChzLmludmVydFJhbmdlIHx8IHMuaW52ZXJ0KShyYW5nZSlcbiAgICA6IChzLmludmVydCB8fCBzLmludmVydEV4dGVudCkocmFuZ2UpO1xufVxuXG52YXIgc2NhbGVHcmFkaWVudCA9IGZ1bmN0aW9uKHNjYWxlLCBwMCwgcDEsIGNvdW50LCBncm91cCkge1xuICBzY2FsZSA9IGdldFNjYWxlKHNjYWxlLCAoZ3JvdXAgfHwgdGhpcykuY29udGV4dCk7XG5cbiAgdmFyIGdyYWRpZW50ID0gR3JhZGllbnQocDAsIHAxKSxcbiAgICAgIHN0b3BzID0gc2NhbGUuZG9tYWluKCksXG4gICAgICBtaW4gPSBzdG9wc1swXSxcbiAgICAgIG1heCA9IHN0b3BzW3N0b3BzLmxlbmd0aC0xXSxcbiAgICAgIGZyYWN0aW9uID0gc2NhbGVGcmFjdGlvbihzY2FsZSwgbWluLCBtYXgpO1xuXG4gIGlmIChzY2FsZS50aWNrcykge1xuICAgIHN0b3BzID0gc2NhbGUudGlja3MoK2NvdW50IHx8IDE1KTtcbiAgICBpZiAobWluICE9PSBzdG9wc1swXSkgc3RvcHMudW5zaGlmdChtaW4pO1xuICAgIGlmIChtYXggIT09IHN0b3BzW3N0b3BzLmxlbmd0aC0xXSkgc3RvcHMucHVzaChtYXgpO1xuICB9XG5cbiAgZm9yICh2YXIgaT0wLCBuPXN0b3BzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBncmFkaWVudC5zdG9wKGZyYWN0aW9uKHN0b3BzW2ldKSwgc2NhbGUoc3RvcHNbaV0pKTtcbiAgfVxuXG4gIHJldHVybiBncmFkaWVudDtcbn07XG5cbmZ1bmN0aW9uIGdlb01ldGhvZChtZXRob2ROYW1lLCBnbG9iYWxNZXRob2QpIHtcbiAgcmV0dXJuIGZ1bmN0aW9uKHByb2plY3Rpb24sIGdlb2pzb24sIGdyb3VwKSB7XG4gICAgaWYgKHByb2plY3Rpb24pIHtcbiAgICAgIC8vIHByb2plY3Rpb24gZGVmaW5lZCwgdXNlIGl0XG4gICAgICB2YXIgcCA9IGdldFNjYWxlKHByb2plY3Rpb24sIChncm91cCB8fCB0aGlzKS5jb250ZXh0KTtcbiAgICAgIHJldHVybiBwICYmIHAucGF0aFttZXRob2ROYW1lXShnZW9qc29uKTtcbiAgICB9IGVsc2Uge1xuICAgICAgLy8gcHJvamVjdGlvbiB1bmRlZmluZWQsIHVzZSBnbG9iYWwgbWV0aG9kXG4gICAgICByZXR1cm4gZ2xvYmFsTWV0aG9kKGdlb2pzb24pO1xuICAgIH1cbiAgfTtcbn1cblxudmFyIGdlb0FyZWEgPSBnZW9NZXRob2QoJ2FyZWEnLCBhcmVhJDQpO1xudmFyIGdlb0JvdW5kcyA9IGdlb01ldGhvZCgnYm91bmRzJywgYm91bmRzJDEpO1xudmFyIGdlb0NlbnRyb2lkID0gZ2VvTWV0aG9kKCdjZW50cm9pZCcsIGNlbnRyb2lkKTtcblxuZnVuY3Rpb24gZ2VvU2hhcGUocHJvamVjdGlvbiwgZ2VvanNvbiwgZ3JvdXApIHtcbiAgdmFyIHAgPSBnZXRTY2FsZShwcm9qZWN0aW9uLCAoZ3JvdXAgfHwgdGhpcykuY29udGV4dCk7XG4gIHJldHVybiBmdW5jdGlvbihjb250ZXh0JCQxKSB7XG4gICAgcmV0dXJuIHAgPyBwLnBhdGguY29udGV4dChjb250ZXh0JCQxKShnZW9qc29uKSA6ICcnO1xuICB9XG59XG5cbmZ1bmN0aW9uIHBhdGhTaGFwZShwYXRoKSB7XG4gIHZhciBwID0gbnVsbDtcbiAgcmV0dXJuIGZ1bmN0aW9uKGNvbnRleHQkJDEpIHtcbiAgICByZXR1cm4gY29udGV4dCQkMVxuICAgICAgPyBwYXRoUmVuZGVyKGNvbnRleHQkJDEsIChwID0gcCB8fCBwYXRoUGFyc2UocGF0aCkpKVxuICAgICAgOiBwYXRoO1xuICB9O1xufVxuXG5mdW5jdGlvbiBkYXRhJDEobmFtZSkge1xuICB2YXIgZGF0YSA9IHRoaXMuY29udGV4dC5kYXRhW25hbWVdO1xuICByZXR1cm4gZGF0YSA/IGRhdGEudmFsdWVzLnZhbHVlIDogW107XG59XG5cbmZ1bmN0aW9uIGRhdGFWaXNpdG9yKG5hbWUsIGFyZ3MsIHNjb3BlLCBwYXJhbXMpIHtcbiAgaWYgKGFyZ3NbMF0udHlwZSAhPT0gTGl0ZXJhbCkge1xuICAgIGVycm9yJDEoJ0ZpcnN0IGFyZ3VtZW50IHRvIGRhdGEgZnVuY3Rpb25zIG11c3QgYmUgYSBzdHJpbmcgbGl0ZXJhbC4nKTtcbiAgfVxuXG4gIHZhciBkYXRhID0gYXJnc1swXS52YWx1ZSxcbiAgICAgIGRhdGFOYW1lID0gZGF0YVByZWZpeCArIGRhdGE7XG5cbiAgaWYgKCFwYXJhbXMuaGFzT3duUHJvcGVydHkoZGF0YU5hbWUpKSB7XG4gICAgcGFyYW1zW2RhdGFOYW1lXSA9IHNjb3BlLmdldERhdGEoZGF0YSkudHVwbGVzUmVmKCk7XG4gIH1cbn1cblxuZnVuY3Rpb24gaW5kYXRhKG5hbWUsIGZpZWxkJCQxLCB2YWx1ZSkge1xuICB2YXIgaW5kZXggPSB0aGlzLmNvbnRleHQuZGF0YVtuYW1lXVsnaW5kZXg6JyArIGZpZWxkJCQxXSxcbiAgICAgIGVudHJ5ID0gaW5kZXggPyBpbmRleC52YWx1ZS5nZXQodmFsdWUpIDogdW5kZWZpbmVkO1xuICByZXR1cm4gZW50cnkgPyBlbnRyeS5jb3VudCA6IGVudHJ5O1xufVxuXG5mdW5jdGlvbiBpbmRhdGFWaXNpdG9yKG5hbWUsIGFyZ3MsIHNjb3BlLCBwYXJhbXMpIHtcbiAgaWYgKGFyZ3NbMF0udHlwZSAhPT0gTGl0ZXJhbCkgZXJyb3IkMSgnRmlyc3QgYXJndW1lbnQgdG8gaW5kYXRhIG11c3QgYmUgYSBzdHJpbmcgbGl0ZXJhbC4nKTtcbiAgaWYgKGFyZ3NbMV0udHlwZSAhPT0gTGl0ZXJhbCkgZXJyb3IkMSgnU2Vjb25kIGFyZ3VtZW50IHRvIGluZGF0YSBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwuJyk7XG5cbiAgdmFyIGRhdGEgPSBhcmdzWzBdLnZhbHVlLFxuICAgICAgZmllbGQkJDEgPSBhcmdzWzFdLnZhbHVlLFxuICAgICAgaW5kZXhOYW1lID0gaW5kZXhQcmVmaXggKyBmaWVsZCQkMTtcblxuICBpZiAoIXBhcmFtcy5oYXNPd25Qcm9wZXJ0eShpbmRleE5hbWUpKSB7XG4gICAgcGFyYW1zW2luZGV4TmFtZV0gPSBzY29wZS5nZXREYXRhKGRhdGEpLmluZGF0YVJlZihzY29wZSwgZmllbGQkJDEpO1xuICB9XG59XG5cbmZ1bmN0aW9uIHNldGRhdGEobmFtZSwgdHVwbGVzKSB7XG4gIHZhciBkZiA9IHRoaXMuY29udGV4dC5kYXRhZmxvdyxcbiAgICAgIGRhdGEgPSB0aGlzLmNvbnRleHQuZGF0YVtuYW1lXSxcbiAgICAgIGlucHV0ID0gZGF0YS5pbnB1dDtcblxuICBkZi5wdWxzZShpbnB1dCwgZGYuY2hhbmdlc2V0KCkucmVtb3ZlKHRydXRoeSkuaW5zZXJ0KHR1cGxlcykpO1xuICByZXR1cm4gMTtcbn1cblxudmFyIEVNUFRZID0ge307XG5cbmZ1bmN0aW9uIGRhdHVtKGQpIHsgcmV0dXJuIGQuZGF0YTsgfVxuXG5mdW5jdGlvbiB0cmVlTm9kZXMobmFtZSwgY29udGV4dCkge1xuICB2YXIgdHJlZSA9IGRhdGEkMS5jYWxsKGNvbnRleHQsIG5hbWUpO1xuICByZXR1cm4gdHJlZS5yb290ICYmIHRyZWUucm9vdC5sb29rdXAgfHwgRU1QVFk7XG59XG5cbmZ1bmN0aW9uIHRyZWVQYXRoKG5hbWUsIHNvdXJjZSwgdGFyZ2V0KSB7XG4gIHZhciBub2RlcyA9IHRyZWVOb2RlcyhuYW1lLCB0aGlzKSxcbiAgICAgIHMgPSBub2Rlc1tzb3VyY2VdLFxuICAgICAgdCA9IG5vZGVzW3RhcmdldF07XG4gIHJldHVybiBzICYmIHQgPyBzLnBhdGgodCkubWFwKGRhdHVtKSA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gdHJlZUFuY2VzdG9ycyhuYW1lLCBub2RlKSB7XG4gIHZhciBuID0gdHJlZU5vZGVzKG5hbWUsIHRoaXMpW25vZGVdO1xuICByZXR1cm4gbiA/IG4uYW5jZXN0b3JzKCkubWFwKGRhdHVtKSA6IHVuZGVmaW5lZDtcbn1cblxudmFyIGlucmFuZ2UgPSBmdW5jdGlvbih2YWx1ZSwgcmFuZ2UsIGxlZnQsIHJpZ2h0KSB7XG4gIHZhciByMCA9IHJhbmdlWzBdLCByMSA9IHJhbmdlW3JhbmdlLmxlbmd0aC0xXSwgdDtcbiAgaWYgKHIwID4gcjEpIHtcbiAgICB0ID0gcjA7XG4gICAgcjAgPSByMTtcbiAgICByMSA9IHQ7XG4gIH1cbiAgbGVmdCA9IGxlZnQgPT09IHVuZGVmaW5lZCB8fCBsZWZ0O1xuICByaWdodCA9IHJpZ2h0ID09PSB1bmRlZmluZWQgfHwgcmlnaHQ7XG5cbiAgcmV0dXJuIChsZWZ0ID8gcjAgPD0gdmFsdWUgOiByMCA8IHZhbHVlKSAmJlxuICAgIChyaWdodCA/IHZhbHVlIDw9IHIxIDogdmFsdWUgPCByMSk7XG59O1xuXG52YXIgZW5jb2RlJDEgPSBmdW5jdGlvbihpdGVtLCBuYW1lLCByZXR2YWwpIHtcbiAgaWYgKGl0ZW0pIHtcbiAgICB2YXIgZGYgPSB0aGlzLmNvbnRleHQuZGF0YWZsb3csXG4gICAgICAgIHRhcmdldCA9IGl0ZW0ubWFyay5zb3VyY2U7XG4gICAgZGYucHVsc2UodGFyZ2V0LCBkZi5jaGFuZ2VzZXQoKS5lbmNvZGUoaXRlbSwgbmFtZSkpO1xuICB9XG4gIHJldHVybiByZXR2YWwgIT09IHVuZGVmaW5lZCA/IHJldHZhbCA6IGl0ZW07XG59O1xuXG5mdW5jdGlvbiBlcXVhbChhLCBiKSB7XG4gIHJldHVybiBhID09PSBiIHx8IGEgIT09IGEgJiYgYiAhPT0gYiA/IHRydWVcbiAgICA6IGlzQXJyYXkoYSkgJiYgaXNBcnJheShiKSAmJiBhLmxlbmd0aCA9PT0gYi5sZW5ndGggPyBlcXVhbEFycmF5KGEsIGIpXG4gICAgOiBmYWxzZTtcbn1cblxuZnVuY3Rpb24gZXF1YWxBcnJheShhLCBiKSB7XG4gIGZvciAodmFyIGk9MCwgbj1hLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBpZiAoIWVxdWFsKGFbaV0sIGJbaV0pKSByZXR1cm4gZmFsc2U7XG4gIH1cbiAgcmV0dXJuIHRydWU7XG59XG5cbmZ1bmN0aW9uIHJlbW92ZVByZWRpY2F0ZShwcm9wcykge1xuICByZXR1cm4gZnVuY3Rpb24oXykge1xuICAgIGZvciAodmFyIGtleSQkMSBpbiBwcm9wcykge1xuICAgICAgaWYgKCFlcXVhbChfW2tleSQkMV0sIHByb3BzW2tleSQkMV0pKSByZXR1cm4gZmFsc2U7XG4gICAgfVxuICAgIHJldHVybiB0cnVlO1xuICB9O1xufVxuXG52YXIgbW9kaWZ5ID0gZnVuY3Rpb24obmFtZSwgaW5zZXJ0LCByZW1vdmUsIHRvZ2dsZSwgbW9kaWZ5LCB2YWx1ZXMpIHtcbiAgdmFyIGRmID0gdGhpcy5jb250ZXh0LmRhdGFmbG93LFxuICAgICAgZGF0YSA9IHRoaXMuY29udGV4dC5kYXRhW25hbWVdLFxuICAgICAgaW5wdXQgPSBkYXRhLmlucHV0LFxuICAgICAgY2hhbmdlcyA9IGRhdGEuY2hhbmdlcyxcbiAgICAgIHN0YW1wID0gZGYuc3RhbXAoKSxcbiAgICAgIHByZWRpY2F0ZSwga2V5JCQxO1xuXG4gIGlmIChkZi5fdHJpZ2dlciA9PT0gZmFsc2UgfHwgIShpbnB1dC52YWx1ZS5sZW5ndGggfHwgaW5zZXJ0IHx8IHRvZ2dsZSkpIHtcbiAgICAvLyBub3RoaW5nIHRvIGRvIVxuICAgIHJldHVybiAwO1xuICB9XG5cbiAgaWYgKCFjaGFuZ2VzIHx8IGNoYW5nZXMuc3RhbXAgPCBzdGFtcCkge1xuICAgIGRhdGEuY2hhbmdlcyA9IChjaGFuZ2VzID0gZGYuY2hhbmdlc2V0KCkpO1xuICAgIGNoYW5nZXMuc3RhbXAgPSBzdGFtcDtcbiAgICBkZi5ydW5BZnRlcihmdW5jdGlvbigpIHtcbiAgICAgIGRhdGEubW9kaWZpZWQgPSB0cnVlO1xuICAgICAgZGYucHVsc2UoaW5wdXQsIGNoYW5nZXMpLnJ1bigpO1xuICAgIH0sIHRydWUsIDEpO1xuICB9XG5cbiAgaWYgKHJlbW92ZSkge1xuICAgIHByZWRpY2F0ZSA9IHJlbW92ZSA9PT0gdHJ1ZSA/IHRydXRoeVxuICAgICAgOiAoaXNBcnJheShyZW1vdmUpIHx8IGlzVHVwbGUocmVtb3ZlKSkgPyByZW1vdmVcbiAgICAgIDogcmVtb3ZlUHJlZGljYXRlKHJlbW92ZSk7XG4gICAgY2hhbmdlcy5yZW1vdmUocHJlZGljYXRlKTtcbiAgfVxuXG4gIGlmIChpbnNlcnQpIHtcbiAgICBjaGFuZ2VzLmluc2VydChpbnNlcnQpO1xuICB9XG5cbiAgaWYgKHRvZ2dsZSkge1xuICAgIHByZWRpY2F0ZSA9IHJlbW92ZVByZWRpY2F0ZSh0b2dnbGUpO1xuICAgIGlmIChpbnB1dC52YWx1ZS5zb21lKHByZWRpY2F0ZSkpIHtcbiAgICAgIGNoYW5nZXMucmVtb3ZlKHByZWRpY2F0ZSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNoYW5nZXMuaW5zZXJ0KHRvZ2dsZSk7XG4gICAgfVxuICB9XG5cbiAgaWYgKG1vZGlmeSkge1xuICAgIGZvciAoa2V5JCQxIGluIHZhbHVlcykge1xuICAgICAgY2hhbmdlcy5tb2RpZnkobW9kaWZ5LCBrZXkkJDEsIHZhbHVlc1trZXkkJDFdKTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gMTtcbn07XG5cbnZhciBCSU4gPSAnYmluXyc7XG52YXIgSU5URVJTRUNUID0gJ2ludGVyc2VjdCc7XG52YXIgVU5JT04gPSAndW5pb24nO1xudmFyIFVOSVRfSU5ERVggPSAnaW5kZXg6dW5pdCc7XG5cbmZ1bmN0aW9uIHRlc3RQb2ludChkYXR1bSwgZW50cnkpIHtcbiAgdmFyIGZpZWxkcyA9IGVudHJ5LmZpZWxkcyxcbiAgICAgIHZhbHVlcyA9IGVudHJ5LnZhbHVlcyxcbiAgICAgIGdldHRlciA9IGVudHJ5LmdldHRlciB8fCAoZW50cnkuZ2V0dGVyID0gW10pLFxuICAgICAgbiA9IGZpZWxkcy5sZW5ndGgsXG4gICAgICBpID0gMCwgZHZhbDtcblxuICBmb3IgKDsgaTxuOyArK2kpIHtcbiAgICBnZXR0ZXJbaV0gPSBnZXR0ZXJbaV0gfHwgZmllbGQoZmllbGRzW2ldKTtcbiAgICBkdmFsID0gZ2V0dGVyW2ldKGRhdHVtKTtcbiAgICBpZiAoaXNEYXRlKGR2YWwpKSBkdmFsID0gdG9OdW1iZXIoZHZhbCk7XG4gICAgaWYgKGlzRGF0ZSh2YWx1ZXNbaV0pKSB2YWx1ZXNbaV0gPSB0b051bWJlcih2YWx1ZXNbaV0pO1xuICAgIGlmIChlbnRyeVtCSU4gKyBmaWVsZHNbaV1dKSB7XG4gICAgICBpZiAoaXNEYXRlKHZhbHVlc1tpXVswXSkpIHZhbHVlc1tpXSA9IHZhbHVlc1tpXS5tYXAodG9OdW1iZXIpO1xuICAgICAgaWYgKCFpbnJhbmdlKGR2YWwsIHZhbHVlc1tpXSwgdHJ1ZSwgZmFsc2UpKSByZXR1cm4gZmFsc2U7XG4gICAgfSBlbHNlIGlmIChkdmFsICE9PSB2YWx1ZXNbaV0pIHtcbiAgICAgIHJldHVybiBmYWxzZTtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLy8gVE9ETzogcmV2aXNpdCBkYXRlIGNvZXJjaW9uP1xuLy8gaGF2ZSBzZWxlY3Rpb25zIHBvcHVsYXRlIHdpdGggY29uc2lzdGVudCB0eXBlcyB1cG9uIHdyaXRlP1xuXG5mdW5jdGlvbiB0ZXN0SW50ZXJ2YWwoZGF0dW0sIGVudHJ5KSB7XG4gIHZhciBpdmFscyA9IGVudHJ5LmludGVydmFscyxcbiAgICAgIG4gPSBpdmFscy5sZW5ndGgsXG4gICAgICBpID0gMCxcbiAgICAgIGdldHRlciwgZXh0ZW50LCB2YWx1ZTtcblxuICBmb3IgKDsgaTxuOyArK2kpIHtcbiAgICBleHRlbnQgPSBpdmFsc1tpXS5leHRlbnQ7XG4gICAgZ2V0dGVyID0gaXZhbHNbaV0uZ2V0dGVyIHx8IChpdmFsc1tpXS5nZXR0ZXIgPSBmaWVsZChpdmFsc1tpXS5maWVsZCkpO1xuICAgIHZhbHVlID0gZ2V0dGVyKGRhdHVtKTtcbiAgICBpZiAoIWV4dGVudCB8fCBleHRlbnRbMF0gPT09IGV4dGVudFsxXSkgcmV0dXJuIGZhbHNlO1xuICAgIGlmIChpc0RhdGUodmFsdWUpKSB2YWx1ZSA9IHRvTnVtYmVyKHZhbHVlKTtcbiAgICBpZiAoaXNEYXRlKGV4dGVudFswXSkpIGV4dGVudCA9IGl2YWxzW2ldLmV4dGVudCA9IGV4dGVudC5tYXAodG9OdW1iZXIpO1xuICAgIGlmIChpc051bWJlcihleHRlbnRbMF0pICYmICFpbnJhbmdlKHZhbHVlLCBleHRlbnQpKSByZXR1cm4gZmFsc2U7XG4gICAgZWxzZSBpZiAoaXNTdHJpbmcoZXh0ZW50WzBdKSAmJiBleHRlbnQuaW5kZXhPZih2YWx1ZSkgPCAwKSByZXR1cm4gZmFsc2U7XG4gIH1cblxuICByZXR1cm4gdHJ1ZTtcbn1cblxuLyoqXG4gKiBUZXN0cyBpZiBhIHR1cGxlIGlzIGNvbnRhaW5lZCB3aXRoaW4gYW4gaW50ZXJhY3RpdmUgc2VsZWN0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG5hbWUgLSBUaGUgbmFtZSBvZiB0aGUgZGF0YSBzZXQgcmVwcmVzZW50aW5nIHRoZSBzZWxlY3Rpb24uXG4gKiBAcGFyYW0ge29iamVjdH0gZGF0dW0gLSBUaGUgdHVwbGUgdG8gdGVzdCBmb3IgaW5jbHVzaW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IG9wIC0gVGhlIHNldCBvcGVyYXRpb24gZm9yIGNvbWJpbmluZyBzZWxlY3Rpb25zLlxuICogICBPbmUgb2YgJ2ludGVyc2VjdCcgb3IgJ3VuaW9uJyAoZGVmYXVsdCkuXG4gKiBAcGFyYW0ge2Z1bmN0aW9uKG9iamVjdCxvYmplY3QpOmJvb2xlYW59IHRlc3QgLSBBIGJvb2xlYW4tdmFsdWVkIHRlc3RcbiAqICAgcHJlZGljYXRlIGZvciBkZXRlcm1pbmluZyBzZWxlY3Rpb24gc3RhdHVzIHdpdGhpbiBhIHNpbmdsZSB1bml0IGNoYXJ0LlxuICogQHJldHVybiB7Ym9vbGVhbn0gLSBUcnVlIGlmIHRoZSBkYXR1bSBpcyBpbiB0aGUgc2VsZWN0aW9uLCBmYWxzZSBvdGhlcndpc2UuXG4gKi9cbmZ1bmN0aW9uIHZsU2VsZWN0aW9uKG5hbWUsIGRhdHVtLCBvcCwgdGVzdCkge1xuICB2YXIgZGF0YSA9IHRoaXMuY29udGV4dC5kYXRhW25hbWVdLFxuICAgICAgZW50cmllcyA9IGRhdGEgPyBkYXRhLnZhbHVlcy52YWx1ZSA6IFtdLFxuICAgICAgdW5pdElkeCA9IGRhdGEgPyBkYXRhW1VOSVRfSU5ERVhdICYmIGRhdGFbVU5JVF9JTkRFWF0udmFsdWUgOiB1bmRlZmluZWQsXG4gICAgICBpbnRlcnNlY3QgPSBvcCA9PT0gSU5URVJTRUNULFxuICAgICAgbiA9IGVudHJpZXMubGVuZ3RoLFxuICAgICAgaSA9IDAsXG4gICAgICBlbnRyeSwgbWlzcywgY291bnQsIHVuaXQsIGI7XG5cbiAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgZW50cnkgPSBlbnRyaWVzW2ldO1xuXG4gICAgaWYgKHVuaXRJZHggJiYgaW50ZXJzZWN0KSB7XG4gICAgICAvLyBtdWx0aSBzZWxlY3Rpb25zIHVuaW9uIHdpdGhpbiB0aGUgc2FtZSB1bml0IGFuZCBpbnRlcnNlY3QgYWNyb3NzIHVuaXRzLlxuICAgICAgbWlzcyA9IG1pc3MgfHwge307XG4gICAgICBjb3VudCA9IG1pc3NbdW5pdD1lbnRyeS51bml0XSB8fCAwO1xuXG4gICAgICAvLyBpZiB3ZSd2ZSBhbHJlYWR5IG1hdGNoZWQgdGhpcyB1bml0LCBza2lwLlxuICAgICAgaWYgKGNvdW50ID09PSAtMSkgY29udGludWU7XG5cbiAgICAgIGIgPSB0ZXN0KGRhdHVtLCBlbnRyeSk7XG4gICAgICBtaXNzW3VuaXRdID0gYiA/IC0xIDogKytjb3VudDtcblxuICAgICAgLy8gaWYgd2UgbWF0Y2ggYW5kIHRoZXJlIGFyZSBubyBvdGhlciB1bml0cyByZXR1cm4gdHJ1ZVxuICAgICAgLy8gaWYgd2UndmUgbWlzc2VkIGFnYWluc3QgYWxsIHR1cGxlcyBpbiB0aGlzIHVuaXQgcmV0dXJuIGZhbHNlXG4gICAgICBpZiAoYiAmJiB1bml0SWR4LnNpemUgPT09IDEpIHJldHVybiB0cnVlO1xuICAgICAgaWYgKCFiICYmIGNvdW50ID09PSB1bml0SWR4LmdldCh1bml0KS5jb3VudCkgcmV0dXJuIGZhbHNlO1xuICAgIH0gZWxzZSB7XG4gICAgICBiID0gdGVzdChkYXR1bSwgZW50cnkpO1xuXG4gICAgICAvLyBpZiB3ZSBmaW5kIGEgbWlzcyBhbmQgd2UgZG8gcmVxdWlyZSBpbnRlcnNlY3Rpb24gcmV0dXJuIGZhbHNlXG4gICAgICAvLyBpZiB3ZSBmaW5kIGEgbWF0Y2ggYW5kIHdlIGRvbid0IHJlcXVpcmUgaW50ZXJzZWN0aW9uIHJldHVybiB0cnVlXG4gICAgICBpZiAoaW50ZXJzZWN0IF4gYikgcmV0dXJuIGI7XG4gICAgfVxuICB9XG5cbiAgLy8gaWYgaW50ZXJzZWN0aW5nIGFuZCB3ZSBtYWRlIGl0IGhlcmUsIHRoZW4gd2Ugc2F3IG5vIG1pc3Nlc1xuICAvLyBpZiBub3QgaW50ZXJzZWN0aW5nLCB0aGVuIHdlIHNhdyBubyBtYXRjaGVzXG4gIC8vIGlmIG5vIGFjdGl2ZSBzZWxlY3Rpb25zLCByZXR1cm4gZmFsc2VcbiAgcmV0dXJuIG4gJiYgaW50ZXJzZWN0O1xufVxuXG4vLyBBc3N1bWVzIHBvaW50IHNlbGVjdGlvbiB0dXBsZXMgYXJlIG9mIHRoZSBmb3JtOlxuLy8ge3VuaXQ6IHN0cmluZywgZW5jb2RpbmdzOiBhcnJheTxzdHJpbmc+LCBmaWVsZHM6IGFycmF5PHN0cmluZz4sIHZhbHVlczogYXJyYXk8Kj4sIGJpbnM6IG9iamVjdH1cbmZ1bmN0aW9uIHZsUG9pbnQobmFtZSwgZGF0dW0sIG9wKSB7XG4gIHJldHVybiB2bFNlbGVjdGlvbi5jYWxsKHRoaXMsIG5hbWUsIGRhdHVtLCBvcCwgdGVzdFBvaW50KTtcbn1cblxuLy8gQXNzdW1lcyBpbnRlcnZhbCBzZWxlY3Rpb24gdHlwbGVzIGFyZSBvZiB0aGUgZm9ybTpcbi8vIHt1bml0OiBzdHJpbmcsIGludGVydmFsczogYXJyYXk8e2VuY29kaW5nOiBzdHJpbmcsIGZpZWxkOnN0cmluZywgZXh0ZW50OmFycmF5PG51bWJlcj59Pn1cbmZ1bmN0aW9uIHZsSW50ZXJ2YWwobmFtZSwgZGF0dW0sIG9wKSB7XG4gIHJldHVybiB2bFNlbGVjdGlvbi5jYWxsKHRoaXMsIG5hbWUsIGRhdHVtLCBvcCwgdGVzdEludGVydmFsKTtcbn1cblxuZnVuY3Rpb24gdmxNdWx0aVZpc2l0b3IobmFtZSwgYXJncywgc2NvcGUsIHBhcmFtcykge1xuICBpZiAoYXJnc1swXS50eXBlICE9PSBMaXRlcmFsKSBlcnJvciQxKCdGaXJzdCBhcmd1bWVudCB0byBpbmRhdGEgbXVzdCBiZSBhIHN0cmluZyBsaXRlcmFsLicpO1xuXG4gIHZhciBkYXRhID0gYXJnc1swXS52YWx1ZSxcbiAgICAgIC8vIHZsTXVsdGksIHZsTXVsdGlEb21haW4gaGF2ZSBkaWZmZXJlbnQgIyBvZiBwYXJhbXMsIGJ1dCBvcCBpcyBhbHdheXMgbGFzdC5cbiAgICAgIG9wID0gYXJncy5sZW5ndGggPj0gMiAmJiBhcmdzW2FyZ3MubGVuZ3RoLTFdLnZhbHVlLFxuICAgICAgZmllbGQkJDEgPSAndW5pdCcsXG4gICAgICBpbmRleE5hbWUgPSBpbmRleFByZWZpeCArIGZpZWxkJCQxO1xuXG4gIGlmIChvcCA9PT0gSU5URVJTRUNUICYmICFwYXJhbXMuaGFzT3duUHJvcGVydHkoaW5kZXhOYW1lKSkge1xuICAgIHBhcmFtc1tpbmRleE5hbWVdID0gc2NvcGUuZ2V0RGF0YShkYXRhKS5pbmRhdGFSZWYoc2NvcGUsIGZpZWxkJCQxKTtcbiAgfVxuXG4gIGRhdGFWaXNpdG9yKG5hbWUsIGFyZ3MsIHNjb3BlLCBwYXJhbXMpO1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplcyBhIHBvaW50IHNlbGVjdGlvbiBhcyBhIHNjYWxlIGRvbWFpbi5cbiAqIEBwYXJhbSB7c3RyaW5nfSBuYW1lIC0gVGhlIG5hbWUgb2YgdGhlIGRhdGFzZXQgcmVwcmVzZW50aW5nIHRoZSBzZWxlY3Rpb24uXG4gKiBAcGFyYW0ge3N0cmluZ30gW2VuY29kaW5nXSAtIEEgcGFydGljdWxhciBlbmNvZGluZyBjaGFubmVsIHRvIG1hdGVyaWFsaXplLlxuICogQHBhcmFtIHtzdHJpbmd9IFtmaWVsZF0gLSBBIHBhcnRpY3VsYXIgZmllbGQgdG8gbWF0ZXJpYWxpemUuXG4gKiBAcGFyYW0ge3N0cmluZ30gW29wPSdpbnRlcnNlY3QnXSAtIFRoZSBzZXQgb3BlcmF0aW9uIGZvciBjb21iaW5pbmcgc2VsZWN0aW9ucy5cbiAqIE9uZSBvZiAnaW50ZXJzZWN0JyAoZGVmYXVsdCkgb3IgJ3VuaW9uJy5cbiAqIEByZXR1cm5zIHthcnJheX0gQW4gYXJyYXkgb2YgdmFsdWVzIHRvIHNlcnZlIGFzIGEgc2NhbGUgZG9tYWluLlxuICovXG5mdW5jdGlvbiB2bFBvaW50RG9tYWluKG5hbWUsIGVuY29kaW5nLCBmaWVsZCQkMSwgb3ApIHtcbiAgdmFyIGRhdGEgPSB0aGlzLmNvbnRleHQuZGF0YVtuYW1lXSxcbiAgICAgIGVudHJpZXMgPSBkYXRhID8gZGF0YS52YWx1ZXMudmFsdWUgOiBbXSxcbiAgICAgIHVuaXRJZHggPSBkYXRhID8gZGF0YVtVTklUX0lOREVYXSAmJiBkYXRhW1VOSVRfSU5ERVhdLnZhbHVlIDogdW5kZWZpbmVkLFxuICAgICAgZW50cnkgPSBlbnRyaWVzWzBdLFxuICAgICAgaSA9IDAsIG4sIGluZGV4LCB2YWx1ZXMsIGNvbnRpbnVvdXMsIHVuaXRzO1xuXG4gIGlmICghZW50cnkpIHJldHVybiB1bmRlZmluZWQ7XG5cbiAgZm9yIChuID0gZW5jb2RpbmcgPyBlbnRyeS5lbmNvZGluZ3MubGVuZ3RoIDogZW50cnkuZmllbGRzLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBpZiAoKGVuY29kaW5nICYmIGVudHJ5LmVuY29kaW5nc1tpXSA9PT0gZW5jb2RpbmcpIHx8XG4gICAgICAgIChmaWVsZCQkMSAmJiBlbnRyeS5maWVsZHNbaV0gPT09IGZpZWxkJCQxKSkge1xuICAgICAgaW5kZXggPSBpO1xuICAgICAgY29udGludW91cyA9IGVudHJ5W0JJTiArIGVudHJ5LmZpZWxkc1tpXV07XG4gICAgICBicmVhaztcbiAgICB9XG4gIH1cblxuICAvLyBtdWx0aSBzZWxlY3Rpb25zIHVuaW9uIHdpdGhpbiB0aGUgc2FtZSB1bml0IGFuZCBpbnRlcnNlY3QgYWNyb3NzIHVuaXRzLlxuICAvLyBpZiB3ZSd2ZSBnb3Qgb25seSBvbmUgdW5pdCwgZW5mb3JjZSB1bmlvbiBmb3IgbW9yZSBlZmZpY2llbnQgbWF0ZXJpYWxpemF0aW9uLlxuICBpZiAodW5pdElkeCAmJiB1bml0SWR4LnNpemUgPT09IDEpIHtcbiAgICBvcCA9IFVOSU9OO1xuICB9XG5cbiAgaWYgKHVuaXRJZHggJiYgb3AgPT09IElOVEVSU0VDVCkge1xuICAgIHVuaXRzID0gZW50cmllcy5yZWR1Y2UoZnVuY3Rpb24oYWNjLCBlbnRyeSkge1xuICAgICAgdmFyIHUgPSBhY2NbZW50cnkudW5pdF0gfHwgKGFjY1tlbnRyeS51bml0XSA9IFtdKTtcbiAgICAgIHUucHVzaCh7dW5pdDogZW50cnkudW5pdCwgdmFsdWU6IGVudHJ5LnZhbHVlc1tpbmRleF19KTtcbiAgICAgIHJldHVybiBhY2M7XG4gICAgfSwge30pO1xuXG4gICAgdmFsdWVzID0gT2JqZWN0LmtleXModW5pdHMpLm1hcChmdW5jdGlvbih1bml0KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICB1bml0OiB1bml0LFxuICAgICAgICB2YWx1ZTogY29udGludW91c1xuICAgICAgICAgID8gY29udGludW91c0RvbWFpbih1bml0c1t1bml0XSwgVU5JT04pXG4gICAgICAgICAgOiBkaXNjcmV0ZURvbWFpbih1bml0c1t1bml0XSwgVU5JT04pXG4gICAgICB9O1xuICAgIH0pO1xuICB9IGVsc2Uge1xuICAgIHZhbHVlcyA9IGVudHJpZXMubWFwKGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgICByZXR1cm4ge3VuaXQ6IGVudHJ5LnVuaXQsIHZhbHVlOiBlbnRyeS52YWx1ZXNbaW5kZXhdfTtcbiAgICB9KTtcbiAgfVxuXG4gIHJldHVybiBjb250aW51b3VzID8gY29udGludW91c0RvbWFpbih2YWx1ZXMsIG9wKSA6IGRpc2NyZXRlRG9tYWluKHZhbHVlcywgb3ApO1xufVxuXG4vKipcbiAqIE1hdGVyaWFsaXplcyBhbiBpbnRlcnZhbCBzZWxlY3Rpb24gYXMgYSBzY2FsZSBkb21haW4uXG4gKiBAcGFyYW0ge3N0cmluZ30gbmFtZSAtIFRoZSBuYW1lIG9mIHRoZSBkYXRhc2V0IHJlcHJlc2VudGluZyB0aGUgc2VsZWN0aW9uLlxuICogQHBhcmFtIHtzdHJpbmd9IFtlbmNvZGluZ10gLSBBIHBhcnRpY3VsYXIgZW5jb2RpbmcgY2hhbm5lbCB0byBtYXRlcmlhbGl6ZS5cbiAqIEBwYXJhbSB7c3RyaW5nfSBbZmllbGRdIC0gQSBwYXJ0aWN1bGFyIGZpZWxkIHRvIG1hdGVyaWFsaXplLlxuICogQHBhcmFtIHtzdHJpbmd9IFtvcD0ndW5pb24nXSAtIFRoZSBzZXQgb3BlcmF0aW9uIGZvciBjb21iaW5pbmcgc2VsZWN0aW9ucy5cbiAqIE9uZSBvZiAnaW50ZXJzZWN0JyBvciAndW5pb24nIChkZWZhdWx0KS5cbiAqIEByZXR1cm5zIHthcnJheX0gQW4gYXJyYXkgb2YgdmFsdWVzIHRvIHNlcnZlIGFzIGEgc2NhbGUgZG9tYWluLlxuICovXG5mdW5jdGlvbiB2bEludGVydmFsRG9tYWluKG5hbWUsIGVuY29kaW5nLCBmaWVsZCQkMSwgb3ApIHtcbiAgdmFyIGRhdGEgPSB0aGlzLmNvbnRleHQuZGF0YVtuYW1lXSxcbiAgICAgIGVudHJpZXMgPSBkYXRhID8gZGF0YS52YWx1ZXMudmFsdWUgOiBbXSxcbiAgICAgIGVudHJ5ID0gZW50cmllc1swXSxcbiAgICAgIGkgPSAwLCBuLCBpbnRlcnZhbCwgaW5kZXgsIHZhbHVlcywgZGlzY3JldGU7XG5cbiAgaWYgKCFlbnRyeSkgcmV0dXJuIHVuZGVmaW5lZDtcblxuICBmb3IgKG4gPSBlbnRyeS5pbnRlcnZhbHMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIGludGVydmFsID0gZW50cnkuaW50ZXJ2YWxzW2ldO1xuICAgIGlmICgoZW5jb2RpbmcgJiYgaW50ZXJ2YWwuZW5jb2RpbmcgPT09IGVuY29kaW5nKSB8fFxuICAgICAgICAoZmllbGQkJDEgJiYgaW50ZXJ2YWwuZmllbGQgPT09IGZpZWxkJCQxKSkge1xuICAgICAgaWYgKCFpbnRlcnZhbC5leHRlbnQpIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICBpbmRleCA9IGk7XG4gICAgICBkaXNjcmV0ZSA9IGludGVydmFsLmV4dGVudC5sZW5ndGggPiAyO1xuICAgICAgYnJlYWs7XG4gICAgfVxuICB9XG5cbiAgdmFsdWVzID0gZW50cmllcy5yZWR1Y2UoZnVuY3Rpb24oYWNjLCBlbnRyeSkge1xuICAgIHZhciBleHRlbnQgPSBlbnRyeS5pbnRlcnZhbHNbaW5kZXhdLmV4dGVudCxcbiAgICAgICAgdmFsdWUgPSBkaXNjcmV0ZVxuICAgICAgICAgICA/IGV4dGVudC5tYXAoZnVuY3Rpb24gKGQpIHsgcmV0dXJuIHt1bml0OiBlbnRyeS51bml0LCB2YWx1ZTogZH07IH0pXG4gICAgICAgICAgIDoge3VuaXQ6IGVudHJ5LnVuaXQsIHZhbHVlOiBleHRlbnR9O1xuXG4gICAgaWYgKGRpc2NyZXRlKSB7XG4gICAgICBhY2MucHVzaC5hcHBseShhY2MsIHZhbHVlKTtcbiAgICB9IGVsc2Uge1xuICAgICAgYWNjLnB1c2godmFsdWUpO1xuICAgIH1cbiAgICByZXR1cm4gYWNjO1xuICB9LCBbXSk7XG5cblxuICByZXR1cm4gZGlzY3JldGUgPyBkaXNjcmV0ZURvbWFpbih2YWx1ZXMsIG9wKSA6IGNvbnRpbnVvdXNEb21haW4odmFsdWVzLCBvcCk7XG59XG5cbmZ1bmN0aW9uIGRpc2NyZXRlRG9tYWluKGVudHJpZXMsIG9wKSB7XG4gIHZhciB1bml0cyA9IHt9LCBjb3VudCA9IDAsXG4gICAgICB2YWx1ZXMgPSB7fSwgZG9tYWluID0gW10sXG4gICAgICBpID0gMCwgbiA9IGVudHJpZXMubGVuZ3RoLFxuICAgICAgZW50cnksIHVuaXQsIHYsIGtleSQkMTtcblxuICBmb3IgKDsgaTxuOyArK2kpIHtcbiAgICBlbnRyeSA9IGVudHJpZXNbaV07XG4gICAgdW5pdCAgPSBlbnRyeS51bml0O1xuICAgIGtleSQkMSAgID0gZW50cnkudmFsdWU7XG5cbiAgICBpZiAoIXVuaXRzW3VuaXRdKSB1bml0c1t1bml0XSA9ICsrY291bnQ7XG4gICAgaWYgKCEodiA9IHZhbHVlc1trZXkkJDFdKSkge1xuICAgICAgdmFsdWVzW2tleSQkMV0gPSB2ID0ge3ZhbHVlOiBrZXkkJDEsIHVuaXRzOiB7fSwgY291bnQ6IDB9O1xuICAgIH1cbiAgICBpZiAoIXYudW5pdHNbdW5pdF0pIHYudW5pdHNbdW5pdF0gPSArK3YuY291bnQ7XG4gIH1cblxuICBmb3IgKGtleSQkMSBpbiB2YWx1ZXMpIHtcbiAgICB2ID0gdmFsdWVzW2tleSQkMV07XG4gICAgaWYgKG9wID09PSBJTlRFUlNFQ1QgJiYgdi5jb3VudCAhPT0gY291bnQpIGNvbnRpbnVlO1xuICAgIGRvbWFpbi5wdXNoKHYudmFsdWUpO1xuICB9XG5cbiAgcmV0dXJuIGRvbWFpbi5sZW5ndGggPyBkb21haW4gOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGNvbnRpbnVvdXNEb21haW4oZW50cmllcywgb3ApIHtcbiAgdmFyIG1lcmdlJCQxID0gb3AgPT09IElOVEVSU0VDVCA/IGludGVyc2VjdEludGVydmFsIDogdW5pb25JbnRlcnZhbCxcbiAgICAgIGkgPSAwLCBuID0gZW50cmllcy5sZW5ndGgsXG4gICAgICBleHRlbnQsIGRvbWFpbiwgbG8sIGhpO1xuXG4gIGZvciAoOyBpPG47ICsraSkge1xuICAgIGV4dGVudCA9IGVudHJpZXNbaV0udmFsdWU7XG4gICAgaWYgKGlzRGF0ZShleHRlbnRbMF0pKSBleHRlbnQgPSBleHRlbnQubWFwKHRvTnVtYmVyKTtcbiAgICBsbyA9IGV4dGVudFswXTtcbiAgICBoaSA9IGV4dGVudFsxXTtcbiAgICBpZiAobG8gPiBoaSkge1xuICAgICAgaGkgPSBleHRlbnRbMF07XG4gICAgICBsbyA9IGV4dGVudFsxXTtcbiAgICB9XG4gICAgZG9tYWluID0gZG9tYWluID8gbWVyZ2UkJDEoZG9tYWluLCBsbywgaGkpIDogW2xvLCBoaV07XG4gIH1cblxuICByZXR1cm4gZG9tYWluICYmIGRvbWFpbi5sZW5ndGggJiYgKCtkb21haW5bMF0gIT09ICtkb21haW5bMV0pXG4gICAgPyBkb21haW5cbiAgICA6IHVuZGVmaW5lZDtcbn1cblxuZnVuY3Rpb24gdW5pb25JbnRlcnZhbChkb21haW4sIGxvLCBoaSkge1xuICBpZiAoZG9tYWluWzBdID4gbG8pIGRvbWFpblswXSA9IGxvO1xuICBpZiAoZG9tYWluWzFdIDwgaGkpIGRvbWFpblsxXSA9IGhpO1xuICByZXR1cm4gZG9tYWluO1xufVxuXG5mdW5jdGlvbiBpbnRlcnNlY3RJbnRlcnZhbChkb21haW4sIGxvLCBoaSkge1xuICBpZiAoaGkgPCBkb21haW5bMF0gfHwgZG9tYWluWzFdIDwgbG8pIHtcbiAgICByZXR1cm4gW107XG4gIH0gZWxzZSB7XG4gICAgaWYgKGRvbWFpblswXSA8IGxvKSBkb21haW5bMF0gPSBsbztcbiAgICBpZiAoZG9tYWluWzFdID4gaGkpIGRvbWFpblsxXSA9IGhpO1xuICB9XG4gIHJldHVybiBkb21haW47XG59XG5cbi8vIEV4cHJlc3Npb24gZnVuY3Rpb24gY29udGV4dCBvYmplY3RcbnZhciBmdW5jdGlvbkNvbnRleHQgPSB7XG4gIHJhbmRvbTogZnVuY3Rpb24oKSB7IHJldHVybiBleHBvcnRzLnJhbmRvbSgpOyB9LCAvLyBvdmVycmlkZSBkZWZhdWx0XG4gIGlzQXJyYXk6IGlzQXJyYXksXG4gIGlzQm9vbGVhbjogaXNCb29sZWFuLFxuICBpc0RhdGU6IGlzRGF0ZSxcbiAgaXNOdW1iZXI6IGlzTnVtYmVyLFxuICBpc09iamVjdDogaXNPYmplY3QsXG4gIGlzUmVnRXhwOiBpc1JlZ0V4cCxcbiAgaXNTdHJpbmc6IGlzU3RyaW5nLFxuICBpc1R1cGxlOiBpc1R1cGxlLFxuICB0b0Jvb2xlYW46IHRvQm9vbGVhbixcbiAgdG9EYXRlOiB0b0RhdGUsXG4gIHRvTnVtYmVyOiB0b051bWJlcixcbiAgdG9TdHJpbmc6IHRvU3RyaW5nLFxuICBwYWQ6IHBhZCxcbiAgcGVlazogcGVlayxcbiAgdHJ1bmNhdGU6IHRydW5jYXRlLFxuICByZ2I6IHJnYixcbiAgbGFiOiBsYWIsXG4gIGhjbDogaGNsLFxuICBoc2w6IGhzbCxcbiAgc2VxdWVuY2U6IHNlcXVlbmNlLFxuICBmb3JtYXQ6IGZvcm1hdCQxLFxuICB1dGNGb3JtYXQ6IHV0Y0Zvcm1hdCQxLFxuICB1dGNQYXJzZTogdXRjUGFyc2UkMSxcbiAgdGltZUZvcm1hdDogdGltZUZvcm1hdCQxLFxuICB0aW1lUGFyc2U6IHRpbWVQYXJzZSQxLFxuICBtb250aEZvcm1hdDogbW9udGhGb3JtYXQsXG4gIG1vbnRoQWJicmV2Rm9ybWF0OiBtb250aEFiYnJldkZvcm1hdCxcbiAgZGF5Rm9ybWF0OiBkYXlGb3JtYXQsXG4gIGRheUFiYnJldkZvcm1hdDogZGF5QWJicmV2Rm9ybWF0LFxuICBxdWFydGVyOiBxdWFydGVyLFxuICB1dGNxdWFydGVyOiB1dGNxdWFydGVyLFxuICB3YXJuOiB3YXJuLFxuICBpbmZvOiBpbmZvLFxuICBkZWJ1ZzogZGVidWcsXG4gIGluU2NvcGU6IGluU2NvcGUsXG4gIGNsYW1wUmFuZ2U6IGNsYW1wUmFuZ2UsXG4gIHBpbmNoRGlzdGFuY2U6IHBpbmNoRGlzdGFuY2UsXG4gIHBpbmNoQW5nbGU6IHBpbmNoQW5nbGUsXG4gIHNjcmVlbjogc2NyZWVuLFxuICBjb250YWluZXJTaXplOiBjb250YWluZXJTaXplLFxuICB3aW5kb3dTaXplOiB3aW5kb3dTaXplLFxuICBzcGFuOiBzcGFuLFxuICBmbHVzaDogZmx1c2gsXG4gIGJhbmRzcGFjZTogYmFuZHNwYWNlLFxuICBpbnJhbmdlOiBpbnJhbmdlLFxuICBzZXRkYXRhOiBzZXRkYXRhLFxuICBwYXRoU2hhcGU6IHBhdGhTaGFwZSxcbiAgcGFuTGluZWFyOiBwYW5MaW5lYXIsXG4gIHBhbkxvZzogcGFuTG9nLFxuICBwYW5Qb3c6IHBhblBvdyxcbiAgem9vbUxpbmVhcjogem9vbUxpbmVhcixcbiAgem9vbUxvZzogem9vbUxvZyxcbiAgem9vbVBvdzogem9vbVBvdyxcbiAgZW5jb2RlOiBlbmNvZGUkMSxcbiAgbW9kaWZ5OiBtb2RpZnlcbn07XG5cbnZhciBldmVudEZ1bmN0aW9ucyA9IFsndmlldycsICdpdGVtJywgJ2dyb3VwJywgJ3h5JywgJ3gnLCAneSddO1xudmFyIGV2ZW50UHJlZml4ID0gJ2V2ZW50LnZlZ2EuJztcbnZhciB0aGlzUHJlZml4ID0gJ3RoaXMuJztcbnZhciBhc3RWaXNpdG9ycyA9IHt9OyAvLyBBU1QgdmlzaXRvcnMgZm9yIGRlcGVuZGVuY3kgYW5hbHlzaXNcblxuZnVuY3Rpb24gZXhwcmVzc2lvbkZ1bmN0aW9uKG5hbWUsIGZuLCB2aXNpdG9yKSB7XG4gIGlmIChhcmd1bWVudHMubGVuZ3RoID09PSAxKSB7XG4gICAgcmV0dXJuIGZ1bmN0aW9uQ29udGV4dFtuYW1lXTtcbiAgfVxuXG4gIC8vIHJlZ2lzdGVyIHdpdGggdGhlIGZ1bmN0aW9uQ29udGV4dFxuICBmdW5jdGlvbkNvbnRleHRbbmFtZV0gPSBmbjtcblxuICAvLyBpZiB0aGVyZSBpcyBhbiBhc3RWaXNpdG9yIHJlZ2lzdGVyIHRoYXQsIHRvb1xuICBpZiAodmlzaXRvcikgYXN0VmlzaXRvcnNbbmFtZV0gPSB2aXNpdG9yO1xuXG4gIC8vIGlmIHRoZSBjb2RlIGdlbmVyYXRvciBoYXMgYWxyZWFkeSBiZWVuIGluaXRpYWxpemVkLFxuICAvLyB3ZSBuZWVkIHRvIGFsc28gcmVnaXN0ZXIgdGhlIGZ1bmN0aW9uIHdpdGggaXRcbiAgaWYgKGNvZGVHZW5lcmF0b3IpIGNvZGVHZW5lcmF0b3IuZnVuY3Rpb25zW25hbWVdID0gdGhpc1ByZWZpeCArIG5hbWU7XG4gIHJldHVybiB0aGlzO1xufVxuXG4vLyByZWdpc3RlciBleHByZXNzaW9uIGZ1bmN0aW9ucyB3aXRoIGFzdCB2aXNpdG9yc1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdiYW5kd2lkdGgnLCBiYW5kd2lkdGgsIHNjYWxlVmlzaXRvcik7XG5leHByZXNzaW9uRnVuY3Rpb24oJ2NvcHknLCBjb3B5JDEsIHNjYWxlVmlzaXRvcik7XG5leHByZXNzaW9uRnVuY3Rpb24oJ2RvbWFpbicsIGRvbWFpbiwgc2NhbGVWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbigncmFuZ2UnLCByYW5nZSQyLCBzY2FsZVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdpbnZlcnQnLCBpbnZlcnQsIHNjYWxlVmlzaXRvcik7XG5leHByZXNzaW9uRnVuY3Rpb24oJ3NjYWxlJywgc2NhbGUkMiwgc2NhbGVWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbignZ3JhZGllbnQnLCBzY2FsZUdyYWRpZW50LCBzY2FsZVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdnZW9BcmVhJywgZ2VvQXJlYSwgc2NhbGVWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbignZ2VvQm91bmRzJywgZ2VvQm91bmRzLCBzY2FsZVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdnZW9DZW50cm9pZCcsIGdlb0NlbnRyb2lkLCBzY2FsZVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdnZW9TaGFwZScsIGdlb1NoYXBlLCBzY2FsZVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdpbmRhdGEnLCBpbmRhdGEsIGluZGF0YVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCdkYXRhJywgZGF0YSQxLCBkYXRhVmlzaXRvcik7XG5leHByZXNzaW9uRnVuY3Rpb24oJ3ZsU2luZ2xlJywgdmxQb2ludCwgZGF0YVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCd2bFNpbmdsZURvbWFpbicsIHZsUG9pbnREb21haW4sIGRhdGFWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbigndmxNdWx0aScsIHZsUG9pbnQsIHZsTXVsdGlWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbigndmxNdWx0aURvbWFpbicsIHZsUG9pbnREb21haW4sIHZsTXVsdGlWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbigndmxJbnRlcnZhbCcsIHZsSW50ZXJ2YWwsIGRhdGFWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbigndmxJbnRlcnZhbERvbWFpbicsIHZsSW50ZXJ2YWxEb21haW4sIGRhdGFWaXNpdG9yKTtcbmV4cHJlc3Npb25GdW5jdGlvbigndHJlZVBhdGgnLCB0cmVlUGF0aCwgZGF0YVZpc2l0b3IpO1xuZXhwcmVzc2lvbkZ1bmN0aW9uKCd0cmVlQW5jZXN0b3JzJywgdHJlZUFuY2VzdG9ycywgZGF0YVZpc2l0b3IpO1xuXG4vLyBCdWlsZCBleHByZXNzaW9uIGZ1bmN0aW9uIHJlZ2lzdHJ5XG5mdW5jdGlvbiBidWlsZEZ1bmN0aW9ucyhjb2RlZ2VuJCQxKSB7XG4gIHZhciBmbiA9IEZ1bmN0aW9ucyhjb2RlZ2VuJCQxKTtcbiAgZXZlbnRGdW5jdGlvbnMuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7IGZuW25hbWVdID0gZXZlbnRQcmVmaXggKyBuYW1lOyB9KTtcbiAgZm9yICh2YXIgbmFtZSBpbiBmdW5jdGlvbkNvbnRleHQpIHsgZm5bbmFtZV0gPSB0aGlzUHJlZml4ICsgbmFtZTsgfVxuICByZXR1cm4gZm47XG59XG5cbi8vIEV4cG9ydCBjb2RlIGdlbmVyYXRvciBhbmQgcGFyYW1ldGVyc1xudmFyIGNvZGVnZW5QYXJhbXMgPSB7XG4gIGJsYWNrbGlzdDogIFsnXyddLFxuICB3aGl0ZWxpc3Q6ICBbJ2RhdHVtJywgJ2V2ZW50JywgJ2l0ZW0nXSxcbiAgZmllbGR2YXI6ICAgJ2RhdHVtJyxcbiAgZ2xvYmFsdmFyOiAgZnVuY3Rpb24oaWQkJDEpIHsgcmV0dXJuICdfWycgKyAkKCckJyArIGlkJCQxKSArICddJzsgfSxcbiAgZnVuY3Rpb25zOiAgYnVpbGRGdW5jdGlvbnMsXG4gIGNvbnN0YW50czogIENvbnN0YW50cyxcbiAgdmlzaXRvcnM6ICAgYXN0VmlzaXRvcnNcbn07XG5cbnZhciBjb2RlR2VuZXJhdG9yID0gY29kZWdlbihjb2RlZ2VuUGFyYW1zKTtcblxudmFyIHNpZ25hbFByZWZpeCA9ICckJztcblxudmFyIHBhcnNlRXhwcmVzc2lvbiA9IGZ1bmN0aW9uKGV4cHIsIHNjb3BlLCBwcmVhbWJsZSkge1xuICB2YXIgcGFyYW1zID0ge30sIGFzdCwgZ2VuO1xuXG4gIC8vIHBhcnNlIHRoZSBleHByZXNzaW9uIHRvIGFuIGFic3RyYWN0IHN5bnRheCB0cmVlIChhc3QpXG4gIHRyeSB7XG4gICAgYXN0ID0gcGFyc2UkMyhleHByKTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgZXJyb3IkMSgnRXhwcmVzc2lvbiBwYXJzZSBlcnJvcjogJyArICQoZXhwcikpO1xuICB9XG5cbiAgLy8gYW5hbHl6ZSBhc3QgZnVuY3Rpb24gY2FsbHMgZm9yIGRlcGVuZGVuY2llc1xuICBhc3QudmlzaXQoZnVuY3Rpb24gdmlzaXRvcihub2RlKSB7XG4gICAgaWYgKG5vZGUudHlwZSAhPT0gJ0NhbGxFeHByZXNzaW9uJykgcmV0dXJuO1xuICAgIHZhciBuYW1lID0gbm9kZS5jYWxsZWUubmFtZSxcbiAgICAgICAgdmlzaXQgPSBjb2RlZ2VuUGFyYW1zLnZpc2l0b3JzW25hbWVdO1xuICAgIGlmICh2aXNpdCkgdmlzaXQobmFtZSwgbm9kZS5hcmd1bWVudHMsIHNjb3BlLCBwYXJhbXMpO1xuICB9KTtcblxuICAvLyBwZXJmb3JtIGNvZGUgZ2VuZXJhdGlvblxuICBnZW4gPSBjb2RlR2VuZXJhdG9yKGFzdCk7XG5cbiAgLy8gY29sbGVjdCBzaWduYWwgZGVwZW5kZW5jaWVzXG4gIGdlbi5nbG9iYWxzLmZvckVhY2goZnVuY3Rpb24obmFtZSkge1xuICAgIHZhciBzaWduYWxOYW1lID0gc2lnbmFsUHJlZml4ICsgbmFtZTtcbiAgICBpZiAoIXBhcmFtcy5oYXNPd25Qcm9wZXJ0eShzaWduYWxOYW1lKSAmJiBzY29wZS5nZXRTaWduYWwobmFtZSkpIHtcbiAgICAgIHBhcmFtc1tzaWduYWxOYW1lXSA9IHNjb3BlLnNpZ25hbFJlZihuYW1lKTtcbiAgICB9XG4gIH0pO1xuXG4gIC8vIHJldHVybiBnZW5lcmF0ZWQgZXhwcmVzc2lvbiBjb2RlIGFuZCBkZXBlbmRlbmNpZXNcbiAgcmV0dXJuIHtcbiAgICAkZXhwcjogICBwcmVhbWJsZSA/IHByZWFtYmxlICsgJ3JldHVybignICsgZ2VuLmNvZGUgKyAnKTsnIDogZ2VuLmNvZGUsXG4gICAgJGZpZWxkczogZ2VuLmZpZWxkcyxcbiAgICAkcGFyYW1zOiBwYXJhbXNcbiAgfTtcbn07XG5cbnZhciBWSUVXJDEgPSAndmlldyc7XG52YXIgU0NPUEUgPSAnc2NvcGUnO1xuXG52YXIgcGFyc2VTdHJlYW0gPSBmdW5jdGlvbihzdHJlYW0sIHNjb3BlKSB7XG4gIHJldHVybiBzdHJlYW0uc2lnbmFsID8gc2NvcGUuZ2V0U2lnbmFsKHN0cmVhbS5zaWduYWwpLmlkXG4gICAgOiBzdHJlYW0uc2NhbGUgPyBzY29wZS5nZXRTY2FsZShzdHJlYW0uc2NhbGUpLmlkXG4gICAgOiBwYXJzZVN0cmVhbSQxKHN0cmVhbSwgc2NvcGUpO1xufTtcblxuZnVuY3Rpb24gZXZlbnRTb3VyY2Uoc291cmNlKSB7XG4gICByZXR1cm4gc291cmNlID09PSBTQ09QRSA/IFZJRVckMSA6IChzb3VyY2UgfHwgVklFVyQxKTtcbn1cblxuZnVuY3Rpb24gcGFyc2VTdHJlYW0kMShzdHJlYW0sIHNjb3BlKSB7XG4gIHZhciBtZXRob2QgPSBzdHJlYW0ubWVyZ2UgPyBtZXJnZVN0cmVhbVxuICAgIDogc3RyZWFtLnN0cmVhbSA/IG5lc3RlZFN0cmVhbVxuICAgIDogc3RyZWFtLnR5cGUgPyBldmVudFN0cmVhbVxuICAgIDogZXJyb3IkMSgnSW52YWxpZCBzdHJlYW0gc3BlY2lmaWNhdGlvbjogJyArICQoc3RyZWFtKSk7XG5cbiAgcmV0dXJuIG1ldGhvZChzdHJlYW0sIHNjb3BlKTtcbn1cblxuZnVuY3Rpb24gbWVyZ2VTdHJlYW0oc3RyZWFtLCBzY29wZSkge1xuICB2YXIgbGlzdCA9IHN0cmVhbS5tZXJnZS5tYXAoZnVuY3Rpb24ocykge1xuICAgIHJldHVybiBwYXJzZVN0cmVhbSQxKHMsIHNjb3BlKTtcbiAgfSk7XG5cbiAgdmFyIGVudHJ5ID0gc3RyZWFtUGFyYW1ldGVycyh7bWVyZ2U6IGxpc3R9LCBzdHJlYW0sIHNjb3BlKTtcbiAgcmV0dXJuIHNjb3BlLmFkZFN0cmVhbShlbnRyeSkuaWQ7XG59XG5cbmZ1bmN0aW9uIG5lc3RlZFN0cmVhbShzdHJlYW0sIHNjb3BlKSB7XG4gIHZhciBpZCQkMSA9IHBhcnNlU3RyZWFtJDEoc3RyZWFtLnN0cmVhbSwgc2NvcGUpLFxuICAgICAgZW50cnkgPSBzdHJlYW1QYXJhbWV0ZXJzKHtzdHJlYW06IGlkJCQxfSwgc3RyZWFtLCBzY29wZSk7XG4gIHJldHVybiBzY29wZS5hZGRTdHJlYW0oZW50cnkpLmlkO1xufVxuXG5mdW5jdGlvbiBldmVudFN0cmVhbShzdHJlYW0sIHNjb3BlKSB7XG4gIHZhciBpZCQkMSA9IHNjb3BlLmV2ZW50KGV2ZW50U291cmNlKHN0cmVhbS5zb3VyY2UpLCBzdHJlYW0udHlwZSksXG4gICAgICBlbnRyeSA9IHN0cmVhbVBhcmFtZXRlcnMoe3N0cmVhbTogaWQkJDF9LCBzdHJlYW0sIHNjb3BlKTtcbiAgcmV0dXJuIE9iamVjdC5rZXlzKGVudHJ5KS5sZW5ndGggPT09IDEgPyBpZCQkMVxuICAgIDogc2NvcGUuYWRkU3RyZWFtKGVudHJ5KS5pZDtcbn1cblxuZnVuY3Rpb24gc3RyZWFtUGFyYW1ldGVycyhlbnRyeSwgc3RyZWFtLCBzY29wZSkge1xuICB2YXIgcGFyYW0gPSBzdHJlYW0uYmV0d2VlbjtcblxuICBpZiAocGFyYW0pIHtcbiAgICBpZiAocGFyYW0ubGVuZ3RoICE9PSAyKSB7XG4gICAgICBlcnJvciQxKCdTdHJlYW0gXCJiZXR3ZWVuXCIgcGFyYW1ldGVyIG11c3QgaGF2ZSAyIGVudHJpZXM6ICcgKyAkKHN0cmVhbSkpO1xuICAgIH1cbiAgICBlbnRyeS5iZXR3ZWVuID0gW1xuICAgICAgcGFyc2VTdHJlYW0kMShwYXJhbVswXSwgc2NvcGUpLFxuICAgICAgcGFyc2VTdHJlYW0kMShwYXJhbVsxXSwgc2NvcGUpXG4gICAgXTtcbiAgfVxuXG4gIHBhcmFtID0gc3RyZWFtLmZpbHRlciA/IGFycmF5KHN0cmVhbS5maWx0ZXIpIDogW107XG4gIGlmIChzdHJlYW0ubWFya3R5cGUgfHwgc3RyZWFtLm1hcmtuYW1lIHx8IHN0cmVhbS5tYXJrcm9sZSkge1xuICAgIC8vIGFkZCBmaWx0ZXIgZm9yIG1hcmsgdHlwZSwgbmFtZSBhbmQvb3Igcm9sZVxuICAgIHBhcmFtLnB1c2goZmlsdGVyTWFyayhzdHJlYW0ubWFya3R5cGUsIHN0cmVhbS5tYXJrbmFtZSwgc3RyZWFtLm1hcmtyb2xlKSk7XG4gIH1cbiAgaWYgKHN0cmVhbS5zb3VyY2UgPT09IFNDT1BFKSB7XG4gICAgLy8gYWRkIGZpbHRlciB0byBsaW1pdCBldmVudHMgZnJvbSBzdWItc2NvcGUgb25seVxuICAgIHBhcmFtLnB1c2goJ2luU2NvcGUoZXZlbnQuaXRlbSknKTtcbiAgfVxuICBpZiAocGFyYW0ubGVuZ3RoKSB7XG4gICAgZW50cnkuZmlsdGVyID0gcGFyc2VFeHByZXNzaW9uKCcoJyArIHBhcmFtLmpvaW4oJykmJignKSArICcpJykuJGV4cHI7XG4gIH1cblxuICBpZiAoKHBhcmFtID0gc3RyZWFtLnRocm90dGxlKSAhPSBudWxsKSB7XG4gICAgZW50cnkudGhyb3R0bGUgPSArcGFyYW07XG4gIH1cblxuICBpZiAoKHBhcmFtID0gc3RyZWFtLmRlYm91bmNlKSAhPSBudWxsKSB7XG4gICAgZW50cnkuZGVib3VuY2UgPSArcGFyYW07XG4gIH1cblxuICBpZiAoc3RyZWFtLmNvbnN1bWUpIHtcbiAgICBlbnRyeS5jb25zdW1lID0gdHJ1ZTtcbiAgfVxuXG4gIHJldHVybiBlbnRyeTtcbn1cblxuZnVuY3Rpb24gZmlsdGVyTWFyayh0eXBlLCBuYW1lLCByb2xlKSB7XG4gIHZhciBpdGVtID0gJ2V2ZW50Lml0ZW0nO1xuICByZXR1cm4gaXRlbVxuICAgICsgKHR5cGUgJiYgdHlwZSAhPT0gJyonID8gJyYmJyArIGl0ZW0gKyAnLm1hcmsubWFya3R5cGU9PT1cXCcnICsgdHlwZSArICdcXCcnIDogJycpXG4gICAgKyAocm9sZSA/ICcmJicgKyBpdGVtICsgJy5tYXJrLnJvbGU9PT1cXCcnICsgcm9sZSArICdcXCcnIDogJycpXG4gICAgKyAobmFtZSA/ICcmJicgKyBpdGVtICsgJy5tYXJrLm5hbWU9PT1cXCcnICsgbmFtZSArICdcXCcnIDogJycpO1xufVxuXG4vKipcbiAqIFBhcnNlIGFuIGV2ZW50IHNlbGVjdG9yIHN0cmluZy5cbiAqIFJldHVybnMgYW4gYXJyYXkgb2YgZXZlbnQgc3RyZWFtIGRlZmluaXRpb25zLlxuICovXG52YXIgc2VsZWN0b3IgPSBmdW5jdGlvbihzZWxlY3Rvciwgc291cmNlLCBtYXJrcykge1xuICBERUZBVUxUX1NPVVJDRSA9IHNvdXJjZSB8fCBWSUVXJDI7XG4gIE1BUktTID0gbWFya3MgfHwgREVGQVVMVF9NQVJLUztcbiAgcmV0dXJuIHBhcnNlTWVyZ2Uoc2VsZWN0b3IudHJpbSgpKS5tYXAocGFyc2VTZWxlY3Rvcik7XG59O1xuXG52YXIgVklFVyQyICAgID0gJ3ZpZXcnO1xudmFyIExCUkFDSyAgPSAnWyc7XG52YXIgUkJSQUNLICA9ICddJztcbnZhciBMQlJBQ0UgID0gJ3snO1xudmFyIFJCUkFDRSAgPSAnfSc7XG52YXIgQ09MT04gICA9ICc6JztcbnZhciBDT01NQSAgID0gJywnO1xudmFyIE5BTUUgICAgPSAnQCc7XG52YXIgR1QgICAgICA9ICc+JztcbnZhciBJTExFR0FMJDEgPSAvW1tcXF17fV0vO1xudmFyIERFRkFVTFRfU09VUkNFO1xudmFyIE1BUktTO1xudmFyIERFRkFVTFRfTUFSS1MgPSB7XG4gICAgICAnKic6IDEsXG4gICAgICBhcmM6IDEsXG4gICAgICBhcmVhOiAxLFxuICAgICAgZ3JvdXA6IDEsXG4gICAgICBpbWFnZTogMSxcbiAgICAgIGxpbmU6IDEsXG4gICAgICBwYXRoOiAxLFxuICAgICAgcmVjdDogMSxcbiAgICAgIHJ1bGU6IDEsXG4gICAgICBzaGFwZTogMSxcbiAgICAgIHN5bWJvbDogMSxcbiAgICAgIHRleHQ6IDEsXG4gICAgICB0cmFpbDogMVxuICAgIH07XG5cbmZ1bmN0aW9uIGlzTWFya1R5cGUodHlwZSkge1xuICByZXR1cm4gTUFSS1MuaGFzT3duUHJvcGVydHkodHlwZSk7XG59XG5cbmZ1bmN0aW9uIGZpbmQkMShzLCBpLCBlbmRDaGFyLCBwdXNoQ2hhciwgcG9wQ2hhcikge1xuICB2YXIgY291bnQgPSAwLFxuICAgICAgbiA9IHMubGVuZ3RoLFxuICAgICAgYztcbiAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgYyA9IHNbaV07XG4gICAgaWYgKCFjb3VudCAmJiBjID09PSBlbmRDaGFyKSByZXR1cm4gaTtcbiAgICBlbHNlIGlmIChwb3BDaGFyICYmIHBvcENoYXIuaW5kZXhPZihjKSA+PSAwKSAtLWNvdW50O1xuICAgIGVsc2UgaWYgKHB1c2hDaGFyICYmIHB1c2hDaGFyLmluZGV4T2YoYykgPj0gMCkgKytjb3VudDtcbiAgfVxuICByZXR1cm4gaTtcbn1cblxuZnVuY3Rpb24gcGFyc2VNZXJnZShzKSB7XG4gIHZhciBvdXRwdXQgPSBbXSxcbiAgICAgIHN0YXJ0ID0gMCxcbiAgICAgIG4gPSBzLmxlbmd0aCxcbiAgICAgIGkgPSAwO1xuXG4gIHdoaWxlIChpIDwgbikge1xuICAgIGkgPSBmaW5kJDEocywgaSwgQ09NTUEsIExCUkFDSyArIExCUkFDRSwgUkJSQUNLICsgUkJSQUNFKTtcbiAgICBvdXRwdXQucHVzaChzLnN1YnN0cmluZyhzdGFydCwgaSkudHJpbSgpKTtcbiAgICBzdGFydCA9ICsraTtcbiAgfVxuXG4gIGlmIChvdXRwdXQubGVuZ3RoID09PSAwKSB7XG4gICAgdGhyb3cgJ0VtcHR5IGV2ZW50IHNlbGVjdG9yOiAnICsgcztcbiAgfVxuICByZXR1cm4gb3V0cHV0O1xufVxuXG5mdW5jdGlvbiBwYXJzZVNlbGVjdG9yKHMpIHtcbiAgcmV0dXJuIHNbMF0gPT09ICdbJ1xuICAgID8gcGFyc2VCZXR3ZWVuKHMpXG4gICAgOiBwYXJzZVN0cmVhbSQyKHMpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUJldHdlZW4ocykge1xuICB2YXIgbiA9IHMubGVuZ3RoLFxuICAgICAgaSA9IDEsXG4gICAgICBiLCBzdHJlYW07XG5cbiAgaSA9IGZpbmQkMShzLCBpLCBSQlJBQ0ssIExCUkFDSywgUkJSQUNLKTtcbiAgaWYgKGkgPT09IG4pIHtcbiAgICB0aHJvdyAnRW1wdHkgYmV0d2VlbiBzZWxlY3RvcjogJyArIHM7XG4gIH1cblxuICBiID0gcGFyc2VNZXJnZShzLnN1YnN0cmluZygxLCBpKSk7XG4gIGlmIChiLmxlbmd0aCAhPT0gMikge1xuICAgIHRocm93ICdCZXR3ZWVuIHNlbGVjdG9yIG11c3QgaGF2ZSB0d28gZWxlbWVudHM6ICcgKyBzO1xuICB9XG5cbiAgcyA9IHMuc2xpY2UoaSArIDEpLnRyaW0oKTtcbiAgaWYgKHNbMF0gIT09IEdUKSB7XG4gICAgdGhyb3cgJ0V4cGVjdGVkIFxcJz5cXCcgYWZ0ZXIgYmV0d2VlbiBzZWxlY3RvcjogJyArIHM7XG4gIH1cblxuICBiID0gYi5tYXAocGFyc2VTZWxlY3Rvcik7XG5cbiAgc3RyZWFtID0gcGFyc2VTZWxlY3RvcihzLnNsaWNlKDEpLnRyaW0oKSk7XG4gIGlmIChzdHJlYW0uYmV0d2Vlbikge1xuICAgIHJldHVybiB7XG4gICAgICBiZXR3ZWVuOiBiLFxuICAgICAgc3RyZWFtOiBzdHJlYW1cbiAgICB9O1xuICB9IGVsc2Uge1xuICAgIHN0cmVhbS5iZXR3ZWVuID0gYjtcbiAgfVxuXG4gIHJldHVybiBzdHJlYW07XG59XG5cbmZ1bmN0aW9uIHBhcnNlU3RyZWFtJDIocykge1xuICB2YXIgc3RyZWFtID0ge3NvdXJjZTogREVGQVVMVF9TT1VSQ0V9LFxuICAgICAgc291cmNlID0gW10sXG4gICAgICB0aHJvdHRsZSA9IFswLCAwXSxcbiAgICAgIG1hcmtuYW1lID0gMCxcbiAgICAgIHN0YXJ0ID0gMCxcbiAgICAgIG4gPSBzLmxlbmd0aCxcbiAgICAgIGkgPSAwLCBqLFxuICAgICAgZmlsdGVyO1xuXG4gIC8vIGV4dHJhY3QgdGhyb3R0bGUgZnJvbSBlbmRcbiAgaWYgKHNbbi0xXSA9PT0gUkJSQUNFKSB7XG4gICAgaSA9IHMubGFzdEluZGV4T2YoTEJSQUNFKTtcbiAgICBpZiAoaSA+PSAwKSB7XG4gICAgICB0cnkge1xuICAgICAgICB0aHJvdHRsZSA9IHBhcnNlVGhyb3R0bGUocy5zdWJzdHJpbmcoaSsxLCBuLTEpKTtcbiAgICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgICAgdGhyb3cgJ0ludmFsaWQgdGhyb3R0bGUgc3BlY2lmaWNhdGlvbjogJyArIHM7XG4gICAgICB9XG4gICAgICBzID0gcy5zbGljZSgwLCBpKS50cmltKCk7XG4gICAgICBuID0gcy5sZW5ndGg7XG4gICAgfSBlbHNlIHRocm93ICdVbm1hdGNoZWQgcmlnaHQgYnJhY2U6ICcgKyBzO1xuICAgIGkgPSAwO1xuICB9XG5cbiAgaWYgKCFuKSB0aHJvdyBzO1xuXG4gIC8vIHNldCBuYW1lIGZsYWcgYmFzZWQgb24gZmlyc3QgY2hhclxuICBpZiAoc1swXSA9PT0gTkFNRSkgbWFya25hbWUgPSArK2k7XG5cbiAgLy8gZXh0cmFjdCBmaXJzdCBwYXJ0IG9mIG11bHRpLXBhcnQgc3RyZWFtIHNlbGVjdG9yXG4gIGogPSBmaW5kJDEocywgaSwgQ09MT04pO1xuICBpZiAoaiA8IG4pIHtcbiAgICBzb3VyY2UucHVzaChzLnN1YnN0cmluZyhzdGFydCwgaikudHJpbSgpKTtcbiAgICBzdGFydCA9IGkgPSArK2o7XG4gIH1cblxuICAvLyBleHRyYWN0IHJlbWFpbmluZyBwYXJ0IG9mIHN0cmVhbSBzZWxlY3RvclxuICBpID0gZmluZCQxKHMsIGksIExCUkFDSyk7XG4gIGlmIChpID09PSBuKSB7XG4gICAgc291cmNlLnB1c2gocy5zdWJzdHJpbmcoc3RhcnQsIG4pLnRyaW0oKSk7XG4gIH0gZWxzZSB7XG4gICAgc291cmNlLnB1c2gocy5zdWJzdHJpbmcoc3RhcnQsIGkpLnRyaW0oKSk7XG4gICAgZmlsdGVyID0gW107XG4gICAgc3RhcnQgPSArK2k7XG4gICAgaWYgKHN0YXJ0ID09PSBuKSB0aHJvdyAnVW5tYXRjaGVkIGxlZnQgYnJhY2tldDogJyArIHM7XG4gIH1cblxuICAvLyBleHRyYWN0IGZpbHRlcnNcbiAgd2hpbGUgKGkgPCBuKSB7XG4gICAgaSA9IGZpbmQkMShzLCBpLCBSQlJBQ0spO1xuICAgIGlmIChpID09PSBuKSB0aHJvdyAnVW5tYXRjaGVkIGxlZnQgYnJhY2tldDogJyArIHM7XG4gICAgZmlsdGVyLnB1c2gocy5zdWJzdHJpbmcoc3RhcnQsIGkpLnRyaW0oKSk7XG4gICAgaWYgKGkgPCBuLTEgJiYgc1srK2ldICE9PSBMQlJBQ0spIHRocm93ICdFeHBlY3RlZCBsZWZ0IGJyYWNrZXQ6ICcgKyBzO1xuICAgIHN0YXJ0ID0gKytpO1xuICB9XG5cbiAgLy8gbWFyc2hhbGwgZXZlbnQgc3RyZWFtIHNwZWNpZmljYXRpb25cbiAgaWYgKCEobiA9IHNvdXJjZS5sZW5ndGgpIHx8IElMTEVHQUwkMS50ZXN0KHNvdXJjZVtuLTFdKSkge1xuICAgIHRocm93ICdJbnZhbGlkIGV2ZW50IHNlbGVjdG9yOiAnICsgcztcbiAgfVxuXG4gIGlmIChuID4gMSkge1xuICAgIHN0cmVhbS50eXBlID0gc291cmNlWzFdO1xuICAgIGlmIChtYXJrbmFtZSkge1xuICAgICAgc3RyZWFtLm1hcmtuYW1lID0gc291cmNlWzBdLnNsaWNlKDEpO1xuICAgIH0gZWxzZSBpZiAoaXNNYXJrVHlwZShzb3VyY2VbMF0pKSB7XG4gICAgICBzdHJlYW0ubWFya3R5cGUgPSBzb3VyY2VbMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIHN0cmVhbS5zb3VyY2UgPSBzb3VyY2VbMF07XG4gICAgfVxuICB9IGVsc2Uge1xuICAgIHN0cmVhbS50eXBlID0gc291cmNlWzBdO1xuICB9XG4gIGlmIChzdHJlYW0udHlwZS5zbGljZSgtMSkgPT09ICchJykge1xuICAgIHN0cmVhbS5jb25zdW1lID0gdHJ1ZTtcbiAgICBzdHJlYW0udHlwZSA9IHN0cmVhbS50eXBlLnNsaWNlKDAsIC0xKTtcbiAgfVxuICBpZiAoZmlsdGVyICE9IG51bGwpIHN0cmVhbS5maWx0ZXIgPSBmaWx0ZXI7XG4gIGlmICh0aHJvdHRsZVswXSkgc3RyZWFtLnRocm90dGxlID0gdGhyb3R0bGVbMF07XG4gIGlmICh0aHJvdHRsZVsxXSkgc3RyZWFtLmRlYm91bmNlID0gdGhyb3R0bGVbMV07XG5cbiAgcmV0dXJuIHN0cmVhbTtcbn1cblxuZnVuY3Rpb24gcGFyc2VUaHJvdHRsZShzKSB7XG4gIHZhciBhID0gcy5zcGxpdChDT01NQSk7XG4gIGlmICghcy5sZW5ndGggfHwgYS5sZW5ndGggPiAyKSB0aHJvdyBzO1xuICByZXR1cm4gYS5tYXAoZnVuY3Rpb24oXykge1xuICAgIHZhciB4ID0gK187XG4gICAgaWYgKHggIT09IHgpIHRocm93IHM7XG4gICAgcmV0dXJuIHg7XG4gIH0pO1xufVxuXG52YXIgcHJlYW1ibGUgPSAndmFyIGRhdHVtPWV2ZW50Lml0ZW0mJmV2ZW50Lml0ZW0uZGF0dW07JztcblxudmFyIHBhcnNlVXBkYXRlID0gZnVuY3Rpb24oc3BlYywgc2NvcGUsIHRhcmdldCkge1xuICB2YXIgZXZlbnRzID0gc3BlYy5ldmVudHMsXG4gICAgICB1cGRhdGUgPSBzcGVjLnVwZGF0ZSxcbiAgICAgIGVuY29kZSA9IHNwZWMuZW5jb2RlLFxuICAgICAgc291cmNlcyA9IFtdLFxuICAgICAgdmFsdWUgPSAnJywgZW50cnk7XG5cbiAgaWYgKCFldmVudHMpIHtcbiAgICBlcnJvciQxKCdTaWduYWwgdXBkYXRlIG1pc3NpbmcgZXZlbnRzIHNwZWNpZmljYXRpb24uJyk7XG4gIH1cblxuICAvLyBpbnRlcnByZXQgYXMgYW4gZXZlbnQgc2VsZWN0b3Igc3RyaW5nXG4gIGlmIChpc1N0cmluZyhldmVudHMpKSB7XG4gICAgZXZlbnRzID0gc2VsZWN0b3IoZXZlbnRzKTtcbiAgfVxuXG4gIC8vIHNlcGFyYXRlIGV2ZW50IHN0cmVhbXMgZnJvbSBzaWduYWwgdXBkYXRlc1xuICBldmVudHMgPSBhcnJheShldmVudHMpLmZpbHRlcihmdW5jdGlvbihzdHJlYW0pIHtcbiAgICBpZiAoc3RyZWFtLnNpZ25hbCB8fCBzdHJlYW0uc2NhbGUpIHtcbiAgICAgIHNvdXJjZXMucHVzaChzdHJlYW0pO1xuICAgICAgcmV0dXJuIDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiAxO1xuICAgIH1cbiAgfSk7XG5cbiAgLy8gbWVyZ2UgZXZlbnQgc3RyZWFtcywgaW5jbHVkZSBhcyBzb3VyY2VcbiAgaWYgKGV2ZW50cy5sZW5ndGgpIHtcbiAgICBzb3VyY2VzLnB1c2goZXZlbnRzLmxlbmd0aCA+IDEgPyB7bWVyZ2U6IGV2ZW50c30gOiBldmVudHNbMF0pO1xuICB9XG5cbiAgaWYgKGVuY29kZSAhPSBudWxsKSB7XG4gICAgaWYgKHVwZGF0ZSkgZXJyb3IkMSgnU2lnbmFsIGVuY29kZSBhbmQgdXBkYXRlIGFyZSBtdXR1YWxseSBleGNsdXNpdmUuJyk7XG4gICAgdXBkYXRlID0gJ2VuY29kZShpdGVtKCksJyArICQoZW5jb2RlKSArICcpJztcbiAgfVxuXG4gIC8vIHJlc29sdmUgdXBkYXRlIHZhbHVlXG4gIHZhbHVlID0gaXNTdHJpbmcodXBkYXRlKSA/IHBhcnNlRXhwcmVzc2lvbih1cGRhdGUsIHNjb3BlLCBwcmVhbWJsZSlcbiAgICA6IHVwZGF0ZS5leHByICE9IG51bGwgPyBwYXJzZUV4cHJlc3Npb24odXBkYXRlLmV4cHIsIHNjb3BlLCBwcmVhbWJsZSlcbiAgICA6IHVwZGF0ZS52YWx1ZSAhPSBudWxsID8gdXBkYXRlLnZhbHVlXG4gICAgOiB1cGRhdGUuc2lnbmFsICE9IG51bGwgPyB7XG4gICAgICAgICRleHByOiAgICdfLnZhbHVlJyxcbiAgICAgICAgJHBhcmFtczoge3ZhbHVlOiBzY29wZS5zaWduYWxSZWYodXBkYXRlLnNpZ25hbCl9XG4gICAgICB9XG4gICAgOiBlcnJvciQxKCdJbnZhbGlkIHNpZ25hbCB1cGRhdGUgc3BlY2lmaWNhdGlvbi4nKTtcblxuICBlbnRyeSA9IHtcbiAgICB0YXJnZXQ6IHRhcmdldCxcbiAgICB1cGRhdGU6IHZhbHVlXG4gIH07XG5cbiAgaWYgKHNwZWMuZm9yY2UpIHtcbiAgICBlbnRyeS5vcHRpb25zID0ge2ZvcmNlOiB0cnVlfTtcbiAgfVxuXG4gIHNvdXJjZXMuZm9yRWFjaChmdW5jdGlvbihzb3VyY2UpIHtcbiAgICBzb3VyY2UgPSB7c291cmNlOiBwYXJzZVN0cmVhbShzb3VyY2UsIHNjb3BlKX07XG4gICAgc2NvcGUuYWRkVXBkYXRlKGV4dGVuZChzb3VyY2UsIGVudHJ5KSk7XG4gIH0pO1xufTtcblxudmFyIHBhcnNlU2lnbmFsVXBkYXRlcyA9IGZ1bmN0aW9uKHNpZ25hbCwgc2NvcGUpIHtcbiAgdmFyIG9wID0gc2NvcGUuZ2V0U2lnbmFsKHNpZ25hbC5uYW1lKTtcblxuICBpZiAoc2lnbmFsLnVwZGF0ZSkge1xuICAgIHZhciBleHByID0gcGFyc2VFeHByZXNzaW9uKHNpZ25hbC51cGRhdGUsIHNjb3BlKTtcbiAgICBvcC51cGRhdGUgPSBleHByLiRleHByO1xuICAgIG9wLnBhcmFtcyA9IGV4cHIuJHBhcmFtcztcbiAgfVxuXG4gIGlmIChzaWduYWwub24pIHtcbiAgICBzaWduYWwub24uZm9yRWFjaChmdW5jdGlvbihfKSB7XG4gICAgICBwYXJzZVVwZGF0ZShfLCBzY29wZSwgb3AuaWQpO1xuICAgIH0pO1xuICB9XG59O1xuXG5mdW5jdGlvbiBFbnRyeSh0eXBlLCB2YWx1ZSwgcGFyYW1zLCBwYXJlbnQpIHtcbiAgdGhpcy5pZCA9IC0xO1xuICB0aGlzLnR5cGUgPSB0eXBlO1xuICB0aGlzLnZhbHVlID0gdmFsdWU7XG4gIHRoaXMucGFyYW1zID0gcGFyYW1zO1xuICBpZiAocGFyZW50KSB0aGlzLnBhcmVudCA9IHBhcmVudDtcbn1cblxuZnVuY3Rpb24gZW50cnkodHlwZSwgdmFsdWUsIHBhcmFtcywgcGFyZW50KSB7XG4gIHJldHVybiBuZXcgRW50cnkodHlwZSwgdmFsdWUsIHBhcmFtcywgcGFyZW50KTtcbn1cblxuZnVuY3Rpb24gb3BlcmF0b3IodmFsdWUsIHBhcmFtcykge1xuICByZXR1cm4gZW50cnkoJ29wZXJhdG9yJywgdmFsdWUsIHBhcmFtcyk7XG59XG5cbi8vIC0tLS0tXG5cbmZ1bmN0aW9uIHJlZihvcCkge1xuICB2YXIgcmVmID0geyRyZWY6IG9wLmlkfTtcbiAgLy8gaWYgb3BlcmF0b3Igbm90IHlldCByZWdpc3RlcmVkLCBjYWNoZSByZWYgdG8gcmVzb2x2ZSBsYXRlclxuICBpZiAob3AuaWQgPCAwKSAob3AucmVmcyA9IG9wLnJlZnMgfHwgW10pLnB1c2gocmVmKTtcbiAgcmV0dXJuIHJlZjtcbn1cblxudmFyIHR1cGxlaWRSZWYgPSB7XG4gICR0dXBsZWlkOiAxLFxuICB0b1N0cmluZzogZnVuY3Rpb24oKSB7IHJldHVybiAnOl90dXBsZWlkXzonOyB9XG59O1xuXG5mdW5jdGlvbiBmaWVsZFJlZiQxKGZpZWxkJCQxLCBuYW1lKSB7XG4gIHJldHVybiBuYW1lID8geyRmaWVsZDogZmllbGQkJDEsICRuYW1lOiBuYW1lfSA6IHskZmllbGQ6IGZpZWxkJCQxfTtcbn1cblxudmFyIGtleUZpZWxkUmVmID0gZmllbGRSZWYkMSgna2V5Jyk7XG5cbmZ1bmN0aW9uIGNvbXBhcmVSZWYoZmllbGRzLCBvcmRlcnMpIHtcbiAgcmV0dXJuIHskY29tcGFyZTogZmllbGRzLCAkb3JkZXI6IG9yZGVyc307XG59XG5cbmZ1bmN0aW9uIGtleVJlZihmaWVsZHMsIGZsYXQpIHtcbiAgdmFyIHJlZiA9IHska2V5OiBmaWVsZHN9O1xuICBpZiAoZmxhdCkgcmVmLiRmbGF0ID0gdHJ1ZTtcbiAgcmV0dXJuIHJlZjtcbn1cblxuLy8gLS0tLS1cblxudmFyIEFzY2VuZGluZyAgPSAnYXNjZW5kaW5nJztcblxudmFyIERlc2NlbmRpbmcgPSAnZGVzY2VuZGluZyc7XG5cbmZ1bmN0aW9uIHNvcnRLZXkoc29ydCkge1xuICByZXR1cm4gIWlzT2JqZWN0KHNvcnQpID8gJydcbiAgICA6IChzb3J0Lm9yZGVyID09PSBEZXNjZW5kaW5nID8gJy0nIDogJysnKVxuICAgICAgKyBhZ2dyRmllbGQoc29ydC5vcCwgc29ydC5maWVsZCk7XG59XG5cbmZ1bmN0aW9uIGFnZ3JGaWVsZChvcCwgZmllbGQkJDEpIHtcbiAgcmV0dXJuIChvcCAmJiBvcC5zaWduYWwgPyAnJCcgKyBvcC5zaWduYWwgOiBvcCB8fCAnJylcbiAgICArIChvcCAmJiBmaWVsZCQkMSA/ICdfJyA6ICcnKVxuICAgICsgKGZpZWxkJCQxICYmIGZpZWxkJCQxLnNpZ25hbCA/ICckJyArIGZpZWxkJCQxLnNpZ25hbCA6IGZpZWxkJCQxIHx8ICcnKTtcbn1cblxuLy8gLS0tLS1cblxuZnVuY3Rpb24gaXNTaWduYWwoXykge1xuICByZXR1cm4gXyAmJiBfLnNpZ25hbDtcbn1cblxuZnVuY3Rpb24gdmFsdWUoc3BlY1ZhbHVlLCBkZWZhdWx0VmFsdWUpIHtcbiAgcmV0dXJuIHNwZWNWYWx1ZSAhPSBudWxsID8gc3BlY1ZhbHVlIDogZGVmYXVsdFZhbHVlO1xufVxuXG5mdW5jdGlvbiB0cmFuc2Zvcm0kMyhuYW1lKSB7XG4gIHJldHVybiBmdW5jdGlvbihwYXJhbXMsIHZhbHVlJCQxLCBwYXJlbnQpIHtcbiAgICByZXR1cm4gZW50cnkobmFtZSwgdmFsdWUkJDEsIHBhcmFtcyB8fCB1bmRlZmluZWQsIHBhcmVudCk7XG4gIH07XG59XG5cbnZhciBBZ2dyZWdhdGUkMSA9IHRyYW5zZm9ybSQzKCdhZ2dyZWdhdGUnKTtcbnZhciBBeGlzVGlja3MkMSA9IHRyYW5zZm9ybSQzKCdheGlzdGlja3MnKTtcbnZhciBCb3VuZCQxID0gdHJhbnNmb3JtJDMoJ2JvdW5kJyk7XG52YXIgQ29sbGVjdCQxID0gdHJhbnNmb3JtJDMoJ2NvbGxlY3QnKTtcbnZhciBDb21wYXJlJDEgPSB0cmFuc2Zvcm0kMygnY29tcGFyZScpO1xudmFyIERhdGFKb2luJDEgPSB0cmFuc2Zvcm0kMygnZGF0YWpvaW4nKTtcbnZhciBFbmNvZGUkMSA9IHRyYW5zZm9ybSQzKCdlbmNvZGUnKTtcblxudmFyIEZhY2V0JDEgPSB0cmFuc2Zvcm0kMygnZmFjZXQnKTtcbnZhciBGaWVsZCQxID0gdHJhbnNmb3JtJDMoJ2ZpZWxkJyk7XG52YXIgS2V5JDEgPSB0cmFuc2Zvcm0kMygna2V5Jyk7XG52YXIgTGVnZW5kRW50cmllcyQxID0gdHJhbnNmb3JtJDMoJ2xlZ2VuZGVudHJpZXMnKTtcbnZhciBNYXJrJDEgPSB0cmFuc2Zvcm0kMygnbWFyaycpO1xudmFyIE11bHRpRXh0ZW50JDEgPSB0cmFuc2Zvcm0kMygnbXVsdGlleHRlbnQnKTtcbnZhciBNdWx0aVZhbHVlcyQxID0gdHJhbnNmb3JtJDMoJ211bHRpdmFsdWVzJyk7XG52YXIgT3ZlcmxhcCQxID0gdHJhbnNmb3JtJDMoJ292ZXJsYXAnKTtcbnZhciBQYXJhbXMkMiA9IHRyYW5zZm9ybSQzKCdwYXJhbXMnKTtcbnZhciBQcmVGYWNldCQxID0gdHJhbnNmb3JtJDMoJ3ByZWZhY2V0Jyk7XG52YXIgUHJvamVjdGlvbiQxID0gdHJhbnNmb3JtJDMoJ3Byb2plY3Rpb24nKTtcbnZhciBQcm94eSQxID0gdHJhbnNmb3JtJDMoJ3Byb3h5Jyk7XG52YXIgUmVsYXkkMSA9IHRyYW5zZm9ybSQzKCdyZWxheScpO1xudmFyIFJlbmRlciQxID0gdHJhbnNmb3JtJDMoJ3JlbmRlcicpO1xudmFyIFNjYWxlJDEgPSB0cmFuc2Zvcm0kMygnc2NhbGUnKTtcbnZhciBTaWV2ZSQxID0gdHJhbnNmb3JtJDMoJ3NpZXZlJyk7XG52YXIgU29ydEl0ZW1zJDEgPSB0cmFuc2Zvcm0kMygnc29ydGl0ZW1zJyk7XG52YXIgVmlld0xheW91dCQxID0gdHJhbnNmb3JtJDMoJ3ZpZXdsYXlvdXQnKTtcbnZhciBWYWx1ZXMkMSA9IHRyYW5zZm9ybSQzKCd2YWx1ZXMnKTtcblxudmFyIEZJRUxEX1JFRl9JRCA9IDA7XG5cbnZhciB0eXBlcyA9IFtcbiAgJ2lkZW50aXR5JyxcbiAgJ29yZGluYWwnLCAnYmFuZCcsICdwb2ludCcsXG4gICdiaW4tbGluZWFyJywgJ2Jpbi1vcmRpbmFsJyxcbiAgJ2xpbmVhcicsICdwb3cnLCAnc3FydCcsICdsb2cnLCAnc2VxdWVudGlhbCcsXG4gICd0aW1lJywgJ3V0YycsXG4gICdxdWFudGl6ZScsICdxdWFudGlsZScsICd0aHJlc2hvbGQnXG5dO1xuXG52YXIgYWxsVHlwZXMgPSB0b1NldCh0eXBlcyk7XG52YXIgb3JkaW5hbFR5cGVzID0gdG9TZXQodHlwZXMuc2xpY2UoMSwgNikpO1xuXG5mdW5jdGlvbiBpc09yZGluYWwodHlwZSkge1xuICByZXR1cm4gb3JkaW5hbFR5cGVzLmhhc093blByb3BlcnR5KHR5cGUpO1xufVxuXG5mdW5jdGlvbiBpc1F1YW50aWxlKHR5cGUpIHtcbiAgcmV0dXJuIHR5cGUgPT09ICdxdWFudGlsZSc7XG59XG5cbmZ1bmN0aW9uIGluaXRTY2FsZShzcGVjLCBzY29wZSkge1xuICB2YXIgdHlwZSA9IHNwZWMudHlwZSB8fCAnbGluZWFyJztcblxuICBpZiAoIWFsbFR5cGVzLmhhc093blByb3BlcnR5KHR5cGUpKSB7XG4gICAgZXJyb3IkMSgnVW5yZWNvZ25pemVkIHNjYWxlIHR5cGU6ICcgKyAkKHR5cGUpKTtcbiAgfVxuXG4gIHNjb3BlLmFkZFNjYWxlKHNwZWMubmFtZSwge1xuICAgIHR5cGU6ICAgdHlwZSxcbiAgICBkb21haW46IHVuZGVmaW5lZFxuICB9KTtcbn1cblxuZnVuY3Rpb24gcGFyc2VTY2FsZShzcGVjLCBzY29wZSkge1xuICB2YXIgcGFyYW1zID0gc2NvcGUuZ2V0U2NhbGUoc3BlYy5uYW1lKS5wYXJhbXMsXG4gICAgICBrZXkkJDE7XG5cbiAgcGFyYW1zLmRvbWFpbiA9IHBhcnNlU2NhbGVEb21haW4oc3BlYy5kb21haW4sIHNwZWMsIHNjb3BlKTtcblxuICBpZiAoc3BlYy5yYW5nZSAhPSBudWxsKSB7XG4gICAgcGFyYW1zLnJhbmdlID0gcGFyc2VTY2FsZVJhbmdlKHNwZWMsIHNjb3BlLCBwYXJhbXMpO1xuICB9XG5cbiAgaWYgKHNwZWMuaW50ZXJwb2xhdGUgIT0gbnVsbCkge1xuICAgIHBhcnNlU2NhbGVJbnRlcnBvbGF0ZShzcGVjLmludGVycG9sYXRlLCBwYXJhbXMpO1xuICB9XG5cbiAgaWYgKHNwZWMubmljZSAhPSBudWxsKSB7XG4gICAgcGFyc2VTY2FsZU5pY2Uoc3BlYy5uaWNlLCBwYXJhbXMpO1xuICB9XG5cbiAgZm9yIChrZXkkJDEgaW4gc3BlYykge1xuICAgIGlmIChwYXJhbXMuaGFzT3duUHJvcGVydHkoa2V5JCQxKSB8fCBrZXkkJDEgPT09ICduYW1lJykgY29udGludWU7XG4gICAgcGFyYW1zW2tleSQkMV0gPSBwYXJzZUxpdGVyYWwoc3BlY1trZXkkJDFdLCBzY29wZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gcGFyc2VMaXRlcmFsKHYsIHNjb3BlKSB7XG4gIHJldHVybiAhaXNPYmplY3QodikgPyB2XG4gICAgOiB2LnNpZ25hbCA/IHNjb3BlLnNpZ25hbFJlZih2LnNpZ25hbClcbiAgICA6IGVycm9yJDEoJ1Vuc3VwcG9ydGVkIG9iamVjdDogJyArICQodikpO1xufVxuXG5mdW5jdGlvbiBwYXJzZUFycmF5KHYsIHNjb3BlKSB7XG4gIHJldHVybiB2LnNpZ25hbFxuICAgID8gc2NvcGUuc2lnbmFsUmVmKHYuc2lnbmFsKVxuICAgIDogdi5tYXAoZnVuY3Rpb24odikgeyByZXR1cm4gcGFyc2VMaXRlcmFsKHYsIHNjb3BlKTsgfSk7XG59XG5cbmZ1bmN0aW9uIGRhdGFMb29rdXBFcnJvcihuYW1lKSB7XG4gIGVycm9yJDEoJ0NhbiBub3QgZmluZCBkYXRhIHNldDogJyArICQobmFtZSkpO1xufVxuXG4vLyAtLSBTQ0FMRSBET01BSU4gLS0tLVxuXG5mdW5jdGlvbiBwYXJzZVNjYWxlRG9tYWluKGRvbWFpbiwgc3BlYywgc2NvcGUpIHtcbiAgaWYgKCFkb21haW4pIHtcbiAgICBpZiAoc3BlYy5kb21haW5NaW4gIT0gbnVsbCB8fCBzcGVjLmRvbWFpbk1heCAhPSBudWxsKSB7XG4gICAgICBlcnJvciQxKCdObyBzY2FsZSBkb21haW4gZGVmaW5lZCBmb3IgZG9tYWluTWluL2RvbWFpbk1heCB0byBvdmVycmlkZS4nKTtcbiAgICB9XG4gICAgcmV0dXJuOyAvLyBkZWZhdWx0IGRvbWFpblxuICB9XG5cbiAgcmV0dXJuIGRvbWFpbi5zaWduYWwgPyBzY29wZS5zaWduYWxSZWYoZG9tYWluLnNpZ25hbClcbiAgICA6IChpc0FycmF5KGRvbWFpbikgPyBleHBsaWNpdERvbWFpblxuICAgIDogZG9tYWluLmZpZWxkcyA/IG11bHRpcGxlRG9tYWluXG4gICAgOiBzaW5ndWxhckRvbWFpbikoZG9tYWluLCBzcGVjLCBzY29wZSk7XG59XG5cbmZ1bmN0aW9uIGV4cGxpY2l0RG9tYWluKGRvbWFpbiwgc3BlYywgc2NvcGUpIHtcbiAgcmV0dXJuIGRvbWFpbi5tYXAoZnVuY3Rpb24odikge1xuICAgIHJldHVybiBwYXJzZUxpdGVyYWwodiwgc2NvcGUpO1xuICB9KTtcbn1cblxuZnVuY3Rpb24gc2luZ3VsYXJEb21haW4oZG9tYWluLCBzcGVjLCBzY29wZSkge1xuICB2YXIgZGF0YSA9IHNjb3BlLmdldERhdGEoZG9tYWluLmRhdGEpO1xuICBpZiAoIWRhdGEpIGRhdGFMb29rdXBFcnJvcihkb21haW4uZGF0YSk7XG5cbiAgcmV0dXJuIGlzT3JkaW5hbChzcGVjLnR5cGUpXG4gICAgICA/IGRhdGEudmFsdWVzUmVmKHNjb3BlLCBkb21haW4uZmllbGQsIHBhcnNlU29ydChkb21haW4uc29ydCwgZmFsc2UpKVxuICAgICAgOiBpc1F1YW50aWxlKHNwZWMudHlwZSkgPyBkYXRhLmRvbWFpblJlZihzY29wZSwgZG9tYWluLmZpZWxkKVxuICAgICAgOiBkYXRhLmV4dGVudFJlZihzY29wZSwgZG9tYWluLmZpZWxkKTtcbn1cblxuZnVuY3Rpb24gbXVsdGlwbGVEb21haW4oZG9tYWluLCBzcGVjLCBzY29wZSkge1xuICB2YXIgZGF0YSA9IGRvbWFpbi5kYXRhLFxuICAgICAgZmllbGRzID0gZG9tYWluLmZpZWxkcy5yZWR1Y2UoZnVuY3Rpb24oZG9tLCBkKSB7XG4gICAgICAgIGQgPSBpc1N0cmluZyhkKSA/IHtkYXRhOiBkYXRhLCBmaWVsZDogZH1cbiAgICAgICAgICA6IChpc0FycmF5KGQpIHx8IGQuc2lnbmFsKSA/IGZpZWxkUmVmKGQsIHNjb3BlKVxuICAgICAgICAgIDogZDtcbiAgICAgICAgZG9tLnB1c2goZCk7XG4gICAgICAgIHJldHVybiBkb207XG4gICAgICB9LCBbXSk7XG5cbiAgcmV0dXJuIChpc09yZGluYWwoc3BlYy50eXBlKSA/IG9yZGluYWxNdWx0aXBsZURvbWFpblxuICAgIDogaXNRdWFudGlsZShzcGVjLnR5cGUpID8gcXVhbnRpbGVNdWx0aXBsZURvbWFpblxuICAgIDogbnVtZXJpY011bHRpcGxlRG9tYWluKShkb21haW4sIHNjb3BlLCBmaWVsZHMpO1xufVxuXG5mdW5jdGlvbiBmaWVsZFJlZihkYXRhLCBzY29wZSkge1xuICB2YXIgbmFtZSA9ICdfOnZlZ2E6XycgKyAoRklFTERfUkVGX0lEKyspLFxuICAgICAgY29sbCA9IENvbGxlY3QkMSh7fSk7XG5cbiAgaWYgKGlzQXJyYXkoZGF0YSkpIHtcbiAgICBjb2xsLnZhbHVlID0geyRpbmdlc3Q6IGRhdGF9O1xuICB9IGVsc2UgaWYgKGRhdGEuc2lnbmFsKSB7XG4gICAgdmFyIGNvZGUgPSAnc2V0ZGF0YSgnICsgJChuYW1lKSArICcsJyArIGRhdGEuc2lnbmFsICsgJyknO1xuICAgIGNvbGwucGFyYW1zLmlucHV0ID0gc2NvcGUuc2lnbmFsUmVmKGNvZGUpO1xuICB9XG4gIHNjb3BlLmFkZERhdGFQaXBlbGluZShuYW1lLCBbY29sbCwgU2lldmUkMSh7fSldKTtcbiAgcmV0dXJuIHtkYXRhOiBuYW1lLCBmaWVsZDogJ2RhdGEnfTtcbn1cblxuZnVuY3Rpb24gb3JkaW5hbE11bHRpcGxlRG9tYWluKGRvbWFpbiwgc2NvcGUsIGZpZWxkcykge1xuICB2YXIgY291bnRzLCBhLCBjLCB2O1xuXG4gIC8vIGdldCB2YWx1ZSBjb3VudHMgZm9yIGVhY2ggZG9tYWluIGZpZWxkXG4gIGNvdW50cyA9IGZpZWxkcy5tYXAoZnVuY3Rpb24oZikge1xuICAgIHZhciBkYXRhID0gc2NvcGUuZ2V0RGF0YShmLmRhdGEpO1xuICAgIGlmICghZGF0YSkgZGF0YUxvb2t1cEVycm9yKGYuZGF0YSk7XG4gICAgcmV0dXJuIGRhdGEuY291bnRzUmVmKHNjb3BlLCBmLmZpZWxkKTtcbiAgfSk7XG5cbiAgLy8gc3VtIGNvdW50cyBmcm9tIGFsbCBmaWVsZHNcbiAgYSA9IHNjb3BlLmFkZChBZ2dyZWdhdGUkMSh7XG4gICAgZ3JvdXBieToga2V5RmllbGRSZWYsXG4gICAgb3BzOlsnc3VtJ10sIGZpZWxkczogW3Njb3BlLmZpZWxkUmVmKCdjb3VudCcpXSwgYXM6Wydjb3VudCddLFxuICAgIHB1bHNlOiBjb3VudHNcbiAgfSkpO1xuXG4gIC8vIGNvbGxlY3QgYWdncmVnYXRlIG91dHB1dFxuICBjID0gc2NvcGUuYWRkKENvbGxlY3QkMSh7cHVsc2U6IHJlZihhKX0pKTtcblxuICAvLyBleHRyYWN0IHZhbHVlcyBmb3IgY29tYmluZWQgZG9tYWluXG4gIHYgPSBzY29wZS5hZGQoVmFsdWVzJDEoe1xuICAgIGZpZWxkOiBrZXlGaWVsZFJlZixcbiAgICBzb3J0OiAgc2NvcGUuc29ydFJlZihwYXJzZVNvcnQoZG9tYWluLnNvcnQsIHRydWUpKSxcbiAgICBwdWxzZTogcmVmKGMpXG4gIH0pKTtcblxuICByZXR1cm4gcmVmKHYpO1xufVxuXG5mdW5jdGlvbiBwYXJzZVNvcnQoc29ydCwgbXVsdGlkb21haW4pIHtcbiAgaWYgKHNvcnQpIHtcbiAgICBpZiAoIXNvcnQuZmllbGQgJiYgIXNvcnQub3ApIHtcbiAgICAgIGlmIChpc09iamVjdChzb3J0KSkgc29ydC5maWVsZCA9ICdrZXknO1xuICAgICAgZWxzZSBzb3J0ID0ge2ZpZWxkOiAna2V5J307XG4gICAgfSBlbHNlIGlmICghc29ydC5maWVsZCAmJiBzb3J0Lm9wICE9PSAnY291bnQnKSB7XG4gICAgICBlcnJvciQxKCdObyBmaWVsZCBwcm92aWRlZCBmb3Igc29ydCBhZ2dyZWdhdGUgb3A6ICcgKyBzb3J0Lm9wKTtcbiAgICB9IGVsc2UgaWYgKG11bHRpZG9tYWluICYmIHNvcnQuZmllbGQpIHtcbiAgICAgIGVycm9yJDEoJ011bHRpcGxlIGRvbWFpbiBzY2FsZXMgY2FuIG5vdCBzb3J0IGJ5IGZpZWxkLicpO1xuICAgIH0gZWxzZSBpZiAobXVsdGlkb21haW4gJiYgc29ydC5vcCAmJiBzb3J0Lm9wICE9PSAnY291bnQnKSB7XG4gICAgICBlcnJvciQxKCdNdWx0aXBsZSBkb21haW4gc2NhbGVzIHN1cHBvcnQgb3AgY291bnQgb25seS4nKTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNvcnQ7XG59XG5cbmZ1bmN0aW9uIHF1YW50aWxlTXVsdGlwbGVEb21haW4oZG9tYWluLCBzY29wZSwgZmllbGRzKSB7XG4gIC8vIGdldCB2YWx1ZSBhcnJheXMgZm9yIGVhY2ggZG9tYWluIGZpZWxkXG4gIHZhciB2YWx1ZXMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uKGYpIHtcbiAgICB2YXIgZGF0YSA9IHNjb3BlLmdldERhdGEoZi5kYXRhKTtcbiAgICBpZiAoIWRhdGEpIGRhdGFMb29rdXBFcnJvcihmLmRhdGEpO1xuICAgIHJldHVybiBkYXRhLmRvbWFpblJlZihzY29wZSwgZi5maWVsZCk7XG4gIH0pO1xuXG4gIC8vIGNvbWJpbmUgdmFsdWUgYXJyYXlzXG4gIHJldHVybiByZWYoc2NvcGUuYWRkKE11bHRpVmFsdWVzJDEoe3ZhbHVlczogdmFsdWVzfSkpKTtcbn1cblxuZnVuY3Rpb24gbnVtZXJpY011bHRpcGxlRG9tYWluKGRvbWFpbiwgc2NvcGUsIGZpZWxkcykge1xuICAvLyBnZXQgZXh0ZW50cyBmb3IgZWFjaCBkb21haW4gZmllbGRcbiAgdmFyIGV4dGVudHMgPSBmaWVsZHMubWFwKGZ1bmN0aW9uKGYpIHtcbiAgICB2YXIgZGF0YSA9IHNjb3BlLmdldERhdGEoZi5kYXRhKTtcbiAgICBpZiAoIWRhdGEpIGRhdGFMb29rdXBFcnJvcihmLmRhdGEpO1xuICAgIHJldHVybiBkYXRhLmV4dGVudFJlZihzY29wZSwgZi5maWVsZCk7XG4gIH0pO1xuXG4gIC8vIGNvbWJpbmUgZXh0ZW50c1xuICByZXR1cm4gcmVmKHNjb3BlLmFkZChNdWx0aUV4dGVudCQxKHtleHRlbnRzOiBleHRlbnRzfSkpKTtcbn1cblxuLy8gLS0gU0NBTEUgTklDRSAtLS0tLVxuXG5mdW5jdGlvbiBwYXJzZVNjYWxlTmljZShuaWNlLCBwYXJhbXMpIHtcbiAgcGFyYW1zLm5pY2UgPSBpc09iamVjdChuaWNlKVxuICAgID8ge1xuICAgICAgICBpbnRlcnZhbDogcGFyc2VMaXRlcmFsKG5pY2UuaW50ZXJ2YWwpLFxuICAgICAgICBzdGVwOiBwYXJzZUxpdGVyYWwobmljZS5zdGVwKVxuICAgICAgfVxuICAgIDogcGFyc2VMaXRlcmFsKG5pY2UpO1xufVxuXG4vLyAtLSBTQ0FMRSBJTlRFUlBPTEFUSU9OIC0tLS0tXG5cbmZ1bmN0aW9uIHBhcnNlU2NhbGVJbnRlcnBvbGF0ZShpbnRlcnBvbGF0ZSwgcGFyYW1zKSB7XG4gIHBhcmFtcy5pbnRlcnBvbGF0ZSA9IHBhcnNlTGl0ZXJhbChpbnRlcnBvbGF0ZS50eXBlIHx8IGludGVycG9sYXRlKTtcbiAgaWYgKGludGVycG9sYXRlLmdhbW1hICE9IG51bGwpIHtcbiAgICBwYXJhbXMuaW50ZXJwb2xhdGVHYW1tYSA9IHBhcnNlTGl0ZXJhbChpbnRlcnBvbGF0ZS5nYW1tYSk7XG4gIH1cbn1cblxuLy8gLS0gU0NBTEUgUkFOR0UgLS0tLS1cblxuZnVuY3Rpb24gcGFyc2VTY2FsZVJhbmdlKHNwZWMsIHNjb3BlLCBwYXJhbXMpIHtcbiAgdmFyIHJhbmdlID0gc3BlYy5yYW5nZSxcbiAgICAgIGNvbmZpZyA9IHNjb3BlLmNvbmZpZy5yYW5nZTtcblxuICBpZiAocmFuZ2Uuc2lnbmFsKSB7XG4gICAgcmV0dXJuIHNjb3BlLnNpZ25hbFJlZihyYW5nZS5zaWduYWwpO1xuICB9IGVsc2UgaWYgKGlzU3RyaW5nKHJhbmdlKSkge1xuICAgIGlmIChjb25maWcgJiYgY29uZmlnLmhhc093blByb3BlcnR5KHJhbmdlKSkge1xuICAgICAgc3BlYyA9IGV4dGVuZCh7fSwgc3BlYywge3JhbmdlOiBjb25maWdbcmFuZ2VdfSk7XG4gICAgICByZXR1cm4gcGFyc2VTY2FsZVJhbmdlKHNwZWMsIHNjb3BlLCBwYXJhbXMpO1xuICAgIH0gZWxzZSBpZiAocmFuZ2UgPT09ICd3aWR0aCcpIHtcbiAgICAgIHJhbmdlID0gWzAsIHtzaWduYWw6ICd3aWR0aCd9XTtcbiAgICB9IGVsc2UgaWYgKHJhbmdlID09PSAnaGVpZ2h0Jykge1xuICAgICAgcmFuZ2UgPSBpc09yZGluYWwoc3BlYy50eXBlKVxuICAgICAgICA/IFswLCB7c2lnbmFsOiAnaGVpZ2h0J31dXG4gICAgICAgIDogW3tzaWduYWw6ICdoZWlnaHQnfSwgMF07XG4gICAgfSBlbHNlIHtcbiAgICAgIGVycm9yJDEoJ1VucmVjb2duaXplZCBzY2FsZSByYW5nZSB2YWx1ZTogJyArICQocmFuZ2UpKTtcbiAgICB9XG4gIH0gZWxzZSBpZiAocmFuZ2Uuc2NoZW1lKSB7XG4gICAgcGFyYW1zLnNjaGVtZSA9IHBhcnNlTGl0ZXJhbChyYW5nZS5zY2hlbWUsIHNjb3BlKTtcbiAgICBpZiAocmFuZ2UuZXh0ZW50KSBwYXJhbXMuc2NoZW1lRXh0ZW50ID0gcGFyc2VBcnJheShyYW5nZS5leHRlbnQsIHNjb3BlKTtcbiAgICBpZiAocmFuZ2UuY291bnQpIHBhcmFtcy5zY2hlbWVDb3VudCA9IHBhcnNlTGl0ZXJhbChyYW5nZS5jb3VudCwgc2NvcGUpO1xuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmIChyYW5nZS5zdGVwKSB7XG4gICAgcGFyYW1zLnJhbmdlU3RlcCA9IHBhcnNlTGl0ZXJhbChyYW5nZS5zdGVwLCBzY29wZSk7XG4gICAgcmV0dXJuO1xuICB9IGVsc2UgaWYgKGlzT3JkaW5hbChzcGVjLnR5cGUpICYmICFpc0FycmF5KHJhbmdlKSkge1xuICAgIHJldHVybiBwYXJzZVNjYWxlRG9tYWluKHJhbmdlLCBzcGVjLCBzY29wZSk7XG4gIH0gZWxzZSBpZiAoIWlzQXJyYXkocmFuZ2UpKSB7XG4gICAgZXJyb3IkMSgnVW5zdXBwb3J0ZWQgcmFuZ2UgdHlwZTogJyArICQocmFuZ2UpKTtcbiAgfVxuXG4gIHJldHVybiByYW5nZS5tYXAoZnVuY3Rpb24odikge1xuICAgIHJldHVybiBwYXJzZUxpdGVyYWwodiwgc2NvcGUpO1xuICB9KTtcbn1cblxudmFyIHBhcnNlUHJvamVjdGlvbiA9IGZ1bmN0aW9uKHByb2osIHNjb3BlKSB7XG4gIHZhciBwYXJhbXMgPSB7fTtcblxuICBmb3IgKHZhciBuYW1lIGluIHByb2opIHtcbiAgICBpZiAobmFtZSA9PT0gJ25hbWUnKSBjb250aW51ZTtcbiAgICBwYXJhbXNbbmFtZV0gPSBwYXJzZVBhcmFtZXRlcihwcm9qW25hbWVdLCBzY29wZSk7XG4gIH1cblxuICBzY29wZS5hZGRQcm9qZWN0aW9uKHByb2oubmFtZSwgcGFyYW1zKTtcbn07XG5cbmZ1bmN0aW9uIHBhcnNlUGFyYW1ldGVyKF8sIHNjb3BlKSB7XG4gIHJldHVybiBpc0FycmF5KF8pID8gXy5tYXAoZnVuY3Rpb24oXykgeyByZXR1cm4gcGFyc2VQYXJhbWV0ZXIoXywgc2NvcGUpOyB9KVxuICAgIDogIWlzT2JqZWN0KF8pID8gX1xuICAgIDogXy5zaWduYWwgPyBzY29wZS5zaWduYWxSZWYoXy5zaWduYWwpXG4gICAgOiBlcnJvciQxKCdVbnN1cHBvcnRlZCBwYXJhbWV0ZXIgb2JqZWN0OiAnICsgJChfKSk7XG59XG5cbnZhciBUb3AkMSA9ICd0b3AnO1xudmFyIExlZnQkMSA9ICdsZWZ0JztcbnZhciBSaWdodCQxID0gJ3JpZ2h0JztcbnZhciBCb3R0b20kMSA9ICdib3R0b20nO1xuXG52YXIgSW5kZXggID0gJ2luZGV4JztcbnZhciBMYWJlbCAgPSAnbGFiZWwnO1xudmFyIE9mZnNldCA9ICdvZmZzZXQnO1xudmFyIFBlcmMgICA9ICdwZXJjJztcbnZhciBTaXplICAgPSAnc2l6ZSc7XG52YXIgVG90YWwgID0gJ3RvdGFsJztcbnZhciBWYWx1ZSAgPSAndmFsdWUnO1xuXG52YXIgR3VpZGVMYWJlbFN0eWxlID0gJ2d1aWRlLWxhYmVsJztcbnZhciBHdWlkZVRpdGxlU3R5bGUgPSAnZ3VpZGUtdGl0bGUnO1xudmFyIEdyb3VwVGl0bGVTdHlsZSA9ICdncm91cC10aXRsZSc7XG5cbnZhciBMZWdlbmRTY2FsZXMgPSBbXG4gICdzaGFwZScsXG4gICdzaXplJyxcbiAgJ2ZpbGwnLFxuICAnc3Ryb2tlJyxcbiAgJ3N0cm9rZURhc2gnLFxuICAnb3BhY2l0eSdcbl07XG5cbnZhciBTa2lwID0ge1xuICBuYW1lOiAxLFxuICBpbnRlcmFjdGl2ZTogMVxufTtcblxudmFyIFNraXAkMSA9IHRvU2V0KFsncnVsZSddKTtcbnZhciBTd2FwID0gdG9TZXQoWydncm91cCcsICdpbWFnZScsICdyZWN0J10pO1xuXG52YXIgYWRqdXN0U3BhdGlhbCA9IGZ1bmN0aW9uKGVuY29kZSwgbWFya3R5cGUpIHtcbiAgdmFyIGNvZGUgPSAnJztcblxuICBpZiAoU2tpcCQxW21hcmt0eXBlXSkgcmV0dXJuIGNvZGU7XG5cbiAgaWYgKGVuY29kZS54Mikge1xuICAgIGlmIChlbmNvZGUueCkge1xuICAgICAgaWYgKFN3YXBbbWFya3R5cGVdKSB7XG4gICAgICAgIGNvZGUgKz0gJ2lmKG8ueD5vLngyKSQ9by54LG8ueD1vLngyLG8ueDI9JDsnO1xuICAgICAgfVxuICAgICAgY29kZSArPSAnby53aWR0aD1vLngyLW8ueDsnO1xuICAgIH0gZWxzZSB7XG4gICAgICBjb2RlICs9ICdvLng9by54Mi0oby53aWR0aHx8MCk7JztcbiAgICB9XG4gIH1cblxuICBpZiAoZW5jb2RlLnhjKSB7XG4gICAgY29kZSArPSAnby54PW8ueGMtKG8ud2lkdGh8fDApLzI7JztcbiAgfVxuXG4gIGlmIChlbmNvZGUueTIpIHtcbiAgICBpZiAoZW5jb2RlLnkpIHtcbiAgICAgIGlmIChTd2FwW21hcmt0eXBlXSkge1xuICAgICAgICBjb2RlICs9ICdpZihvLnk+by55MikkPW8ueSxvLnk9by55MixvLnkyPSQ7JztcbiAgICAgIH1cbiAgICAgIGNvZGUgKz0gJ28uaGVpZ2h0PW8ueTItby55Oyc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvZGUgKz0gJ28ueT1vLnkyLShvLmhlaWdodHx8MCk7JztcbiAgICB9XG4gIH1cblxuICBpZiAoZW5jb2RlLnljKSB7XG4gICAgY29kZSArPSAnby55PW8ueWMtKG8uaGVpZ2h0fHwwKS8yOyc7XG4gIH1cblxuICByZXR1cm4gY29kZTtcbn07XG5cbnZhciBjb2xvciQyID0gZnVuY3Rpb24oZW5jLCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpIHtcbiAgZnVuY3Rpb24gY29sb3IodHlwZSwgeCwgeSwgeikge1xuICAgIHZhciBhID0gZW50cnkkMShudWxsLCB4LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpLFxuICAgICAgICBiID0gZW50cnkkMShudWxsLCB5LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpLFxuICAgICAgICBjID0gZW50cnkkMShudWxsLCB6LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpO1xuICAgIHJldHVybiAndGhpcy4nICsgdHlwZSArICcoJyArIFthLCBiLCBjXS5qb2luKCcsJykgKyAnKS50b1N0cmluZygpJztcbiAgfVxuXG4gIHJldHVybiAoZW5jLmMpID8gY29sb3IoJ2hjbCcsIGVuYy5oLCBlbmMuYywgZW5jLmwpXG4gICAgOiAoZW5jLmggfHwgZW5jLnMpID8gY29sb3IoJ2hzbCcsIGVuYy5oLCBlbmMucywgZW5jLmwpXG4gICAgOiAoZW5jLmwgfHwgZW5jLmEpID8gY29sb3IoJ2xhYicsIGVuYy5sLCBlbmMuYSwgZW5jLmIpXG4gICAgOiAoZW5jLnIgfHwgZW5jLmcgfHwgZW5jLmIpID8gY29sb3IoJ3JnYicsIGVuYy5yLCBlbmMuZywgZW5jLmIpXG4gICAgOiBudWxsO1xufTtcblxudmFyIGV4cHJlc3Npb24gPSBmdW5jdGlvbihjb2RlLCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpIHtcbiAgdmFyIGV4cHIgPSBwYXJzZUV4cHJlc3Npb24oY29kZSwgc2NvcGUpO1xuICBleHByLiRmaWVsZHMuZm9yRWFjaChmdW5jdGlvbihuYW1lKSB7IGZpZWxkc1tuYW1lXSA9IDE7IH0pO1xuICBleHRlbmQocGFyYW1zLCBleHByLiRwYXJhbXMpO1xuICByZXR1cm4gZXhwci4kZXhwcjtcbn07XG5cbnZhciBmaWVsZCQxID0gZnVuY3Rpb24ocmVmLCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpIHtcbiAgcmV0dXJuIHJlc29sdmUkMShpc09iamVjdChyZWYpID8gcmVmIDoge2RhdHVtOiByZWZ9LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpO1xufTtcblxuZnVuY3Rpb24gcmVzb2x2ZSQxKHJlZiwgc2NvcGUsIHBhcmFtcywgZmllbGRzKSB7XG4gIHZhciBvYmplY3QsIGxldmVsLCBmaWVsZCQkMTtcblxuICBpZiAocmVmLnNpZ25hbCkge1xuICAgIG9iamVjdCA9ICdkYXR1bSc7XG4gICAgZmllbGQkJDEgPSBleHByZXNzaW9uKHJlZi5zaWduYWwsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcyk7XG4gIH0gZWxzZSBpZiAocmVmLmdyb3VwIHx8IHJlZi5wYXJlbnQpIHtcbiAgICBsZXZlbCA9IE1hdGgubWF4KDEsIHJlZi5sZXZlbCB8fCAxKTtcbiAgICBvYmplY3QgPSAnaXRlbSc7XG5cbiAgICB3aGlsZSAobGV2ZWwtLSA+IDApIHtcbiAgICAgIG9iamVjdCArPSAnLm1hcmsuZ3JvdXAnO1xuICAgIH1cblxuICAgIGlmIChyZWYucGFyZW50KSB7XG4gICAgICBmaWVsZCQkMSA9IHJlZi5wYXJlbnQ7XG4gICAgICBvYmplY3QgKz0gJy5kYXR1bSc7XG4gICAgfSBlbHNlIHtcbiAgICAgIGZpZWxkJCQxID0gcmVmLmdyb3VwO1xuICAgIH1cbiAgfSBlbHNlIGlmIChyZWYuZGF0dW0pIHtcbiAgICBvYmplY3QgPSAnZGF0dW0nO1xuICAgIGZpZWxkJCQxID0gcmVmLmRhdHVtO1xuICB9IGVsc2Uge1xuICAgIGVycm9yJDEoJ0ludmFsaWQgZmllbGQgcmVmZXJlbmNlOiAnICsgJChyZWYpKTtcbiAgfVxuXG4gIGlmICghcmVmLnNpZ25hbCkge1xuICAgIGlmIChpc1N0cmluZyhmaWVsZCQkMSkpIHtcbiAgICAgIGZpZWxkc1tmaWVsZCQkMV0gPSAxOyAvLyBUT0RPIHJldmlldyBmaWVsZCB0cmFja2luZz9cbiAgICAgIGZpZWxkJCQxID0gc3BsaXRBY2Nlc3NQYXRoKGZpZWxkJCQxKS5tYXAoJCkuam9pbignXVsnKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZmllbGQkJDEgPSByZXNvbHZlJDEoZmllbGQkJDEsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcyk7XG4gICAgfVxuICB9XG5cbiAgcmV0dXJuIG9iamVjdCArICdbJyArIGZpZWxkJCQxICsgJ10nO1xufVxuXG52YXIgc2NhbGUkMyA9IGZ1bmN0aW9uKGVuYywgdmFsdWUsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcykge1xuICB2YXIgc2NhbGUgPSBnZXRTY2FsZSQxKGVuYy5zY2FsZSwgc2NvcGUsIHBhcmFtcywgZmllbGRzKSxcbiAgICAgIGludGVycCwgZnVuYywgZmxhZztcblxuICBpZiAoZW5jLnJhbmdlICE9IG51bGwpIHtcbiAgICAvLyBwdWxsIHZhbHVlIGZyb20gc2NhbGUgcmFuZ2VcbiAgICBpbnRlcnAgPSArZW5jLnJhbmdlO1xuICAgIGZ1bmMgPSBzY2FsZSArICcucmFuZ2UoKSc7XG4gICAgdmFsdWUgPSAoaW50ZXJwID09PSAwKSA/IChmdW5jICsgJ1swXScpXG4gICAgICA6ICcoJD0nICsgZnVuYyArICcsJyArICgoaW50ZXJwID09PSAxKSA/ICckWyQubGVuZ3RoLTFdJ1xuICAgICAgOiAnJFswXSsnICsgaW50ZXJwICsgJyooJFskLmxlbmd0aC0xXS0kWzBdKScpICsgJyknO1xuICB9IGVsc2Uge1xuICAgIC8vIHJ1biB2YWx1ZSB0aHJvdWdoIHNjYWxlIGFuZC9vciBwdWxsIHNjYWxlIGJhbmR3aWR0aFxuICAgIGlmICh2YWx1ZSAhPT0gdW5kZWZpbmVkKSB2YWx1ZSA9IHNjYWxlICsgJygnICsgdmFsdWUgKyAnKSc7XG5cbiAgICBpZiAoZW5jLmJhbmQgJiYgKGZsYWcgPSBoYXNCYW5kd2lkdGgoZW5jLnNjYWxlLCBzY29wZSkpKSB7XG4gICAgICBmdW5jID0gc2NhbGUgKyAnLmJhbmR3aWR0aCc7XG4gICAgICBpbnRlcnAgPSArZW5jLmJhbmQ7XG4gICAgICBpbnRlcnAgPSBmdW5jICsgJygpJyArIChpbnRlcnA9PT0xID8gJycgOiAnKicgKyBpbnRlcnApO1xuXG4gICAgICAvLyBpZiB3ZSBkb24ndCBrbm93IHRoZSBzY2FsZSB0eXBlLCBjaGVjayBmb3IgYmFuZHdpZHRoXG4gICAgICBpZiAoZmxhZyA8IDApIGludGVycCA9ICcoJyArIGZ1bmMgKyAnPycgKyBpbnRlcnAgKyAnOjApJztcblxuICAgICAgdmFsdWUgPSAodmFsdWUgPyB2YWx1ZSArICcrJyA6ICcnKSArIGludGVycDtcblxuICAgICAgaWYgKGVuYy5leHRyYSkge1xuICAgICAgICAvLyBpbmNsdWRlIGxvZ2ljIHRvIGhhbmRsZSBleHRyYW5lb3VzIGVsZW1lbnRzXG4gICAgICAgIHZhbHVlID0gJyhkYXR1bS5leHRyYT8nICsgc2NhbGUgKyAnKGRhdHVtLmV4dHJhLnZhbHVlKTonICsgdmFsdWUgKyAnKSc7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHZhbHVlID09IG51bGwpIHZhbHVlID0gJzAnO1xuICB9XG5cbiAgcmV0dXJuIHZhbHVlO1xufTtcblxuZnVuY3Rpb24gaGFzQmFuZHdpZHRoKG5hbWUsIHNjb3BlKSB7XG4gIGlmICghaXNTdHJpbmcobmFtZSkpIHJldHVybiAtMTtcbiAgdmFyIHR5cGUgPSBzY29wZS5zY2FsZVR5cGUobmFtZSk7XG4gIHJldHVybiB0eXBlID09PSAnYmFuZCcgfHwgdHlwZSA9PT0gJ3BvaW50JyA/IDEgOiAwO1xufVxuXG5mdW5jdGlvbiBnZXRTY2FsZSQxKG5hbWUsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcykge1xuICB2YXIgc2NhbGVOYW1lO1xuXG4gIGlmIChpc1N0cmluZyhuYW1lKSkge1xuICAgIC8vIGRpcmVjdCBzY2FsZSBsb29rdXA7IGFkZCBzY2FsZSBhcyBwYXJhbWV0ZXJcbiAgICBzY2FsZU5hbWUgPSBzY2FsZVByZWZpeCArIG5hbWU7XG4gICAgaWYgKCFwYXJhbXMuaGFzT3duUHJvcGVydHkoc2NhbGVOYW1lKSkge1xuICAgICAgcGFyYW1zW3NjYWxlTmFtZV0gPSBzY29wZS5zY2FsZVJlZihuYW1lKTtcbiAgICB9XG4gICAgc2NhbGVOYW1lID0gJChzY2FsZU5hbWUpO1xuICB9IGVsc2Uge1xuICAgIC8vIGluZGlyZWN0IHNjYWxlIGxvb2t1cDsgYWRkIGFsbCBzY2FsZXMgYXMgcGFyYW1ldGVyc1xuICAgIGZvciAoc2NhbGVOYW1lIGluIHNjb3BlLnNjYWxlcykge1xuICAgICAgcGFyYW1zW3NjYWxlUHJlZml4ICsgc2NhbGVOYW1lXSA9IHNjb3BlLnNjYWxlUmVmKHNjYWxlTmFtZSk7XG4gICAgfVxuICAgIHNjYWxlTmFtZSA9ICQoc2NhbGVQcmVmaXgpICsgJysnXG4gICAgICArIChuYW1lLnNpZ25hbFxuICAgICAgICA/ICcoJyArIGV4cHJlc3Npb24obmFtZS5zaWduYWwsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcykgKyAnKSdcbiAgICAgICAgOiBmaWVsZCQxKG5hbWUsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcykpO1xuICB9XG5cbiAgcmV0dXJuICdfWycgKyBzY2FsZU5hbWUgKyAnXSc7XG59XG5cbnZhciBncmFkaWVudCQxID0gZnVuY3Rpb24oZW5jLCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpIHtcbiAgcmV0dXJuICd0aGlzLmdyYWRpZW50KCdcbiAgICArIGdldFNjYWxlJDEoZW5jLmdyYWRpZW50LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpXG4gICAgKyAnLCcgKyAkKGVuYy5zdGFydClcbiAgICArICcsJyArICQoZW5jLnN0b3ApXG4gICAgKyAnLCcgKyAkKGVuYy5jb3VudClcbiAgICArICcpJztcbn07XG5cbnZhciBwcm9wZXJ0eSA9IGZ1bmN0aW9uKHByb3BlcnR5LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpIHtcbiAgcmV0dXJuIGlzT2JqZWN0KHByb3BlcnR5KVxuICAgICAgPyAnKCcgKyBlbnRyeSQxKG51bGwsIHByb3BlcnR5LCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpICsgJyknXG4gICAgICA6IHByb3BlcnR5O1xufTtcblxudmFyIGVudHJ5JDEgPSBmdW5jdGlvbihjaGFubmVsLCBlbmMsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcykge1xuICBpZiAoZW5jLmdyYWRpZW50ICE9IG51bGwpIHtcbiAgICByZXR1cm4gZ3JhZGllbnQkMShlbmMsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcyk7XG4gIH1cblxuICB2YXIgdmFsdWUgPSBlbmMuc2lnbmFsID8gZXhwcmVzc2lvbihlbmMuc2lnbmFsLCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpXG4gICAgOiBlbmMuY29sb3IgPyBjb2xvciQyKGVuYy5jb2xvciwgc2NvcGUsIHBhcmFtcywgZmllbGRzKVxuICAgIDogZW5jLmZpZWxkICE9IG51bGwgPyBmaWVsZCQxKGVuYy5maWVsZCwgc2NvcGUsIHBhcmFtcywgZmllbGRzKVxuICAgIDogZW5jLnZhbHVlICE9PSB1bmRlZmluZWQgPyAkKGVuYy52YWx1ZSlcbiAgICA6IHVuZGVmaW5lZDtcblxuICBpZiAoZW5jLnNjYWxlICE9IG51bGwpIHtcbiAgICB2YWx1ZSA9IHNjYWxlJDMoZW5jLCB2YWx1ZSwgc2NvcGUsIHBhcmFtcywgZmllbGRzKTtcbiAgfVxuXG4gIGlmICh2YWx1ZSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdmFsdWUgPSBudWxsO1xuICB9XG5cbiAgaWYgKGVuYy5leHBvbmVudCAhPSBudWxsKSB7XG4gICAgdmFsdWUgPSAnTWF0aC5wb3coJyArIHZhbHVlICsgJywnXG4gICAgICArIHByb3BlcnR5KGVuYy5leHBvbmVudCwgc2NvcGUsIHBhcmFtcywgZmllbGRzKSArICcpJztcbiAgfVxuXG4gIGlmIChlbmMubXVsdCAhPSBudWxsKSB7XG4gICAgdmFsdWUgKz0gJyonICsgcHJvcGVydHkoZW5jLm11bHQsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcyk7XG4gIH1cblxuICBpZiAoZW5jLm9mZnNldCAhPSBudWxsKSB7XG4gICAgdmFsdWUgKz0gJysnICsgcHJvcGVydHkoZW5jLm9mZnNldCwgc2NvcGUsIHBhcmFtcywgZmllbGRzKTtcbiAgfVxuXG4gIGlmIChlbmMucm91bmQpIHtcbiAgICB2YWx1ZSA9ICdNYXRoLnJvdW5kKCcgKyB2YWx1ZSArICcpJztcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbnZhciBzZXQkNSA9IGZ1bmN0aW9uKG9iaiwga2V5JCQxLCB2YWx1ZSkge1xuICByZXR1cm4gb2JqICsgJ1snICsgJChrZXkkJDEpICsgJ109JyArIHZhbHVlICsgJzsnO1xufTtcblxudmFyIHJ1bGUkMSA9IGZ1bmN0aW9uKGNoYW5uZWwsIHJ1bGVzLCBzY29wZSwgcGFyYW1zLCBmaWVsZHMpIHtcbiAgdmFyIGNvZGUgPSAnJztcblxuICBydWxlcy5mb3JFYWNoKGZ1bmN0aW9uKHJ1bGUpIHtcbiAgICB2YXIgdmFsdWUgPSBlbnRyeSQxKGNoYW5uZWwsIHJ1bGUsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcyk7XG4gICAgY29kZSArPSBydWxlLnRlc3RcbiAgICAgID8gZXhwcmVzc2lvbihydWxlLnRlc3QsIHNjb3BlLCBwYXJhbXMsIGZpZWxkcykgKyAnPycgKyB2YWx1ZSArICc6J1xuICAgICAgOiB2YWx1ZTtcbiAgfSk7XG5cbiAgcmV0dXJuIHNldCQ1KCdvJywgY2hhbm5lbCwgY29kZSk7XG59O1xuXG5mdW5jdGlvbiBwYXJzZUVuY29kZShlbmNvZGUsIG1hcmt0eXBlLCBwYXJhbXMsIHNjb3BlKSB7XG4gIHZhciBmaWVsZHMgPSB7fSxcbiAgICAgIGNvZGUgPSAndmFyIG89aXRlbSxkYXR1bT1vLmRhdHVtLCQ7JyxcbiAgICAgIGNoYW5uZWwsIGVuYywgdmFsdWU7XG5cbiAgZm9yIChjaGFubmVsIGluIGVuY29kZSkge1xuICAgIGVuYyA9IGVuY29kZVtjaGFubmVsXTtcbiAgICBpZiAoaXNBcnJheShlbmMpKSB7IC8vIHJ1bGVcbiAgICAgIGNvZGUgKz0gcnVsZSQxKGNoYW5uZWwsIGVuYywgc2NvcGUsIHBhcmFtcywgZmllbGRzKTtcbiAgICB9IGVsc2Uge1xuICAgICAgdmFsdWUgPSBlbnRyeSQxKGNoYW5uZWwsIGVuYywgc2NvcGUsIHBhcmFtcywgZmllbGRzKTtcbiAgICAgIGNvZGUgKz0gc2V0JDUoJ28nLCBjaGFubmVsLCB2YWx1ZSk7XG4gICAgfVxuICB9XG5cbiAgY29kZSArPSBhZGp1c3RTcGF0aWFsKGVuY29kZSwgbWFya3R5cGUpO1xuICBjb2RlICs9ICdyZXR1cm4gMTsnO1xuXG4gIHJldHVybiB7XG4gICAgJGV4cHI6ICAgY29kZSxcbiAgICAkZmllbGRzOiBPYmplY3Qua2V5cyhmaWVsZHMpLFxuICAgICRvdXRwdXQ6IE9iamVjdC5rZXlzKGVuY29kZSlcbiAgfTtcbn1cblxudmFyIE1hcmtSb2xlID0gJ21hcmsnO1xudmFyIEZyYW1lUm9sZSQxID0gJ2ZyYW1lJztcbnZhciBTY29wZVJvbGUkMSA9ICdzY29wZSc7XG5cbnZhciBBeGlzUm9sZSQyID0gJ2F4aXMnO1xudmFyIEF4aXNEb21haW5Sb2xlID0gJ2F4aXMtZG9tYWluJztcbnZhciBBeGlzR3JpZFJvbGUgPSAnYXhpcy1ncmlkJztcbnZhciBBeGlzTGFiZWxSb2xlID0gJ2F4aXMtbGFiZWwnO1xudmFyIEF4aXNUaWNrUm9sZSA9ICdheGlzLXRpY2snO1xudmFyIEF4aXNUaXRsZVJvbGUgPSAnYXhpcy10aXRsZSc7XG5cbnZhciBMZWdlbmRSb2xlJDIgPSAnbGVnZW5kJztcbnZhciBMZWdlbmRFbnRyeVJvbGUgPSAnbGVnZW5kLWVudHJ5JztcbnZhciBMZWdlbmRHcmFkaWVudFJvbGUgPSAnbGVnZW5kLWdyYWRpZW50JztcbnZhciBMZWdlbmRMYWJlbFJvbGUgPSAnbGVnZW5kLWxhYmVsJztcbnZhciBMZWdlbmRTeW1ib2xSb2xlID0gJ2xlZ2VuZC1zeW1ib2wnO1xudmFyIExlZ2VuZFRpdGxlUm9sZSA9ICdsZWdlbmQtdGl0bGUnO1xuXG52YXIgVGl0bGVSb2xlJDEgPSAndGl0bGUnO1xuXG5mdW5jdGlvbiBlbmNvZGVyKF8pIHtcbiAgcmV0dXJuIGlzT2JqZWN0KF8pID8gXyA6IHt2YWx1ZTogX307XG59XG5cbmZ1bmN0aW9uIGFkZEVuY29kZShvYmplY3QsIG5hbWUsIHZhbHVlKSB7XG4gIGlmICh2YWx1ZSAhPSBudWxsKSB7XG4gICAgb2JqZWN0W25hbWVdID0gaXNPYmplY3QodmFsdWUpICYmICFpc0FycmF5KHZhbHVlKSA/IHZhbHVlIDoge3ZhbHVlOiB2YWx1ZX07XG4gICAgcmV0dXJuIDE7XG4gIH0gZWxzZSB7XG4gICAgcmV0dXJuIDA7XG4gIH1cbn1cblxuZnVuY3Rpb24gZXh0ZW5kRW5jb2RlKGVuY29kZSwgZXh0cmEsIHNraXApIHtcbiAgZm9yICh2YXIgbmFtZSBpbiBleHRyYSkge1xuICAgIGlmIChza2lwICYmIHNraXAuaGFzT3duUHJvcGVydHkobmFtZSkpIGNvbnRpbnVlO1xuICAgIGVuY29kZVtuYW1lXSA9IGV4dGVuZChlbmNvZGVbbmFtZV0gfHwge30sIGV4dHJhW25hbWVdKTtcbiAgfVxuICByZXR1cm4gZW5jb2RlO1xufVxuXG5mdW5jdGlvbiBlbmNvZGVycyhlbmNvZGUsIHR5cGUsIHJvbGUsIHN0eWxlLCBzY29wZSwgcGFyYW1zKSB7XG4gIHZhciBlbmMsIGtleSQkMTtcbiAgcGFyYW1zID0gcGFyYW1zIHx8IHt9O1xuICBwYXJhbXMuZW5jb2RlcnMgPSB7JGVuY29kZTogKGVuYyA9IHt9KX07XG5cbiAgZW5jb2RlID0gYXBwbHlEZWZhdWx0cyhlbmNvZGUsIHR5cGUsIHJvbGUsIHN0eWxlLCBzY29wZS5jb25maWcpO1xuXG4gIGZvciAoa2V5JCQxIGluIGVuY29kZSkge1xuICAgIGVuY1trZXkkJDFdID0gcGFyc2VFbmNvZGUoZW5jb2RlW2tleSQkMV0sIHR5cGUsIHBhcmFtcywgc2NvcGUpO1xuICB9XG5cbiAgcmV0dXJuIHBhcmFtcztcbn1cblxuZnVuY3Rpb24gYXBwbHlEZWZhdWx0cyhlbmNvZGUsIHR5cGUsIHJvbGUsIHN0eWxlLCBjb25maWcpIHtcbiAgdmFyIGVudGVyID0ge30sIGtleSQkMSwgc2tpcCwgcHJvcHM7XG5cbiAgLy8gaWdub3JlIGxlZ2VuZCBhbmQgYXhpc1xuICBpZiAocm9sZSA9PSAnbGVnZW5kJyB8fCBTdHJpbmcocm9sZSkuaW5kZXhPZignYXhpcycpID09PSAwKSB7XG4gICAgcm9sZSA9IG51bGw7XG4gIH1cblxuICAvLyByZXNvbHZlIG1hcmsgY29uZmlnXG4gIHByb3BzID0gcm9sZSA9PT0gRnJhbWVSb2xlJDEgPyBjb25maWcuZ3JvdXBcbiAgICA6IChyb2xlID09PSBNYXJrUm9sZSkgPyBleHRlbmQoe30sIGNvbmZpZy5tYXJrLCBjb25maWdbdHlwZV0pXG4gICAgOiBudWxsO1xuXG4gIGZvciAoa2V5JCQxIGluIHByb3BzKSB7XG4gICAgLy8gZG8gbm90IGFwcGx5IGRlZmF1bHRzIGlmIHJlbGV2YW50IGZpZWxkcyBhcmUgZGVmaW5lZFxuICAgIHNraXAgPSBoYXMoa2V5JCQxLCBlbmNvZGUpXG4gICAgICB8fCAoa2V5JCQxID09PSAnZmlsbCcgfHwga2V5JCQxID09PSAnc3Ryb2tlJylcbiAgICAgICYmIChoYXMoJ2ZpbGwnLCBlbmNvZGUpIHx8IGhhcygnc3Ryb2tlJywgZW5jb2RlKSk7XG5cbiAgICBpZiAoIXNraXApIGVudGVyW2tleSQkMV0gPSB7dmFsdWU6IHByb3BzW2tleSQkMV19O1xuICB9XG5cbiAgLy8gcmVzb2x2ZSBzdHlsZXMsIGFwcGx5IHdpdGggaW5jcmVhc2luZyBwcmVjZWRlbmNlXG4gIGFycmF5KHN0eWxlKS5mb3JFYWNoKGZ1bmN0aW9uKG5hbWUpIHtcbiAgICB2YXIgcHJvcHMgPSBjb25maWcuc3R5bGUgJiYgY29uZmlnLnN0eWxlW25hbWVdO1xuICAgIGZvciAodmFyIGtleSQkMSBpbiBwcm9wcykge1xuICAgICAgaWYgKCFoYXMoa2V5JCQxLCBlbmNvZGUpKSB7XG4gICAgICAgIGVudGVyW2tleSQkMV0gPSB7dmFsdWU6IHByb3BzW2tleSQkMV19O1xuICAgICAgfVxuICAgIH1cbiAgfSk7XG5cbiAgZW5jb2RlID0gZXh0ZW5kKHt9LCBlbmNvZGUpOyAvLyBkZWZlbnNpdmUgY29weVxuICBlbmNvZGUuZW50ZXIgPSBleHRlbmQoZW50ZXIsIGVuY29kZS5lbnRlcik7XG5cbiAgcmV0dXJuIGVuY29kZTtcbn1cblxuZnVuY3Rpb24gaGFzKGtleSQkMSwgZW5jb2RlKSB7XG4gIHJldHVybiBlbmNvZGUgJiYgKFxuICAgIChlbmNvZGUuZW50ZXIgJiYgZW5jb2RlLmVudGVyW2tleSQkMV0pIHx8XG4gICAgKGVuY29kZS51cGRhdGUgJiYgZW5jb2RlLnVwZGF0ZVtrZXkkJDFdKVxuICApO1xufVxuXG52YXIgZ3VpZGVNYXJrID0gZnVuY3Rpb24odHlwZSwgcm9sZSwgc3R5bGUsIGtleSwgZGF0YVJlZiwgZW5jb2RlLCBleHRyYXMpIHtcbiAgcmV0dXJuIHtcbiAgICB0eXBlOiAgdHlwZSxcbiAgICBuYW1lOiAgZXh0cmFzID8gZXh0cmFzLm5hbWUgOiB1bmRlZmluZWQsXG4gICAgcm9sZTogIHJvbGUsXG4gICAgc3R5bGU6IChleHRyYXMgJiYgZXh0cmFzLnN0eWxlKSB8fCBzdHlsZSxcbiAgICBrZXk6ICAga2V5LFxuICAgIGZyb206ICBkYXRhUmVmLFxuICAgIGludGVyYWN0aXZlOiAhIShleHRyYXMgJiYgZXh0cmFzLmludGVyYWN0aXZlKSxcbiAgICBlbmNvZGU6IGV4dGVuZEVuY29kZShlbmNvZGUsIGV4dHJhcywgU2tpcClcbiAgfTtcbn07XG5cbnZhciBHcm91cE1hcmsgPSAnZ3JvdXAnO1xudmFyIFJlY3RNYXJrID0gJ3JlY3QnO1xudmFyIFJ1bGVNYXJrID0gJ3J1bGUnO1xudmFyIFN5bWJvbE1hcmsgPSAnc3ltYm9sJztcbnZhciBUZXh0TWFyayA9ICd0ZXh0JztcblxudmFyIGxlZ2VuZEdyYWRpZW50ID0gZnVuY3Rpb24oc3BlYywgc2NhbGUsIGNvbmZpZywgdXNlckVuY29kZSkge1xuICB2YXIgemVybyA9IHt2YWx1ZTogMH0sXG4gICAgICBlbmNvZGUgPSB7fSwgZW50ZXIsIHVwZGF0ZTtcblxuICBlbmNvZGUuZW50ZXIgPSBlbnRlciA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvLFxuICAgIHg6IHplcm8sXG4gICAgeTogemVyb1xuICB9O1xuICBhZGRFbmNvZGUoZW50ZXIsICd3aWR0aCcsIGNvbmZpZy5ncmFkaWVudFdpZHRoKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnaGVpZ2h0JywgY29uZmlnLmdyYWRpZW50SGVpZ2h0KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlJywgY29uZmlnLmdyYWRpZW50U3Ryb2tlQ29sb3IpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdzdHJva2VXaWR0aCcsIGNvbmZpZy5ncmFkaWVudFN0cm9rZVdpZHRoKTtcblxuICBlbmNvZGUuZXhpdCA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG5cbiAgZW5jb2RlLnVwZGF0ZSA9IHVwZGF0ZSA9IHtcbiAgICB4OiB6ZXJvLFxuICAgIHk6IHplcm8sXG4gICAgZmlsbDoge2dyYWRpZW50OiBzY2FsZX0sXG4gICAgb3BhY2l0eToge3ZhbHVlOiAxfVxuICB9O1xuICBhZGRFbmNvZGUodXBkYXRlLCAnd2lkdGgnLCBjb25maWcuZ3JhZGllbnRXaWR0aCk7XG4gIGFkZEVuY29kZSh1cGRhdGUsICdoZWlnaHQnLCBjb25maWcuZ3JhZGllbnRIZWlnaHQpO1xuXG4gIHJldHVybiBndWlkZU1hcmsoUmVjdE1hcmssIExlZ2VuZEdyYWRpZW50Um9sZSwgbnVsbCwgdW5kZWZpbmVkLCB1bmRlZmluZWQsIGVuY29kZSwgdXNlckVuY29kZSk7XG59O1xuXG52YXIgYWxpZ25FeHByID0gJ2RhdHVtLicgKyBQZXJjICsgJzw9MD9cImxlZnRcIidcbiAgKyAnOmRhdHVtLicgKyBQZXJjICsgJz49MT9cInJpZ2h0XCI6XCJjZW50ZXJcIic7XG5cbnZhciBsZWdlbmRHcmFkaWVudExhYmVscyA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZywgdXNlckVuY29kZSwgZGF0YVJlZikge1xuICB2YXIgemVybyA9IHt2YWx1ZTogMH0sXG4gICAgICBlbmNvZGUgPSB7fSwgZW50ZXIsIHVwZGF0ZTtcblxuICBlbmNvZGUuZW50ZXIgPSBlbnRlciA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZpbGwnLCBjb25maWcubGFiZWxDb2xvcik7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnQnLCBjb25maWcubGFiZWxGb250KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udFNpemUnLCBjb25maWcubGFiZWxGb250U2l6ZSk7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnRXZWlnaHQnLCBjb25maWcubGFiZWxGb250V2VpZ2h0KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnYmFzZWxpbmUnLCBjb25maWcuZ3JhZGllbnRMYWJlbEJhc2VsaW5lKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnbGltaXQnLCBjb25maWcuZ3JhZGllbnRMYWJlbExpbWl0KTtcblxuICBlbmNvZGUuZXhpdCA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG5cbiAgZW5jb2RlLnVwZGF0ZSA9IHVwZGF0ZSA9IHtcbiAgICBvcGFjaXR5OiB7dmFsdWU6IDF9LFxuICAgIHRleHQ6IHtmaWVsZDogTGFiZWx9XG4gIH07XG5cbiAgZW50ZXIueCA9IHVwZGF0ZS54ID0ge1xuICAgIGZpZWxkOiBQZXJjLFxuICAgIG11bHQ6IGNvbmZpZy5ncmFkaWVudFdpZHRoXG4gIH07XG5cbiAgZW50ZXIueSA9IHVwZGF0ZS55ID0ge1xuICAgIHZhbHVlOiBjb25maWcuZ3JhZGllbnRIZWlnaHQsXG4gICAgb2Zmc2V0OiBjb25maWcuZ3JhZGllbnRMYWJlbE9mZnNldFxuICB9O1xuXG4gIGVudGVyLmFsaWduID0gdXBkYXRlLmFsaWduID0ge3NpZ25hbDogYWxpZ25FeHByfTtcblxuICByZXR1cm4gZ3VpZGVNYXJrKFRleHRNYXJrLCBMZWdlbmRMYWJlbFJvbGUsIEd1aWRlTGFiZWxTdHlsZSwgUGVyYywgZGF0YVJlZiwgZW5jb2RlLCB1c2VyRW5jb2RlKTtcbn07XG5cbnZhciBsZWdlbmRMYWJlbHMgPSBmdW5jdGlvbihzcGVjLCBjb25maWcsIHVzZXJFbmNvZGUsIGRhdGFSZWYpIHtcbiAgdmFyIHplcm8gPSB7dmFsdWU6IDB9LFxuICAgICAgZW5jb2RlID0ge30sIGVudGVyLCB1cGRhdGU7XG5cbiAgZW5jb2RlLmVudGVyID0gZW50ZXIgPSB7XG4gICAgb3BhY2l0eTogemVyb1xuICB9O1xuICBhZGRFbmNvZGUoZW50ZXIsICdhbGlnbicsIGNvbmZpZy5sYWJlbEFsaWduKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnYmFzZWxpbmUnLCBjb25maWcubGFiZWxCYXNlbGluZSk7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZpbGwnLCBjb25maWcubGFiZWxDb2xvcik7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnQnLCBjb25maWcubGFiZWxGb250KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udFNpemUnLCBjb25maWcubGFiZWxGb250U2l6ZSk7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnRXZWlnaHQnLCBjb25maWcubGFiZWxGb250V2VpZ2h0KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnbGltaXQnLCBjb25maWcubGFiZWxMaW1pdCk7XG5cbiAgZW5jb2RlLmV4aXQgPSB7XG4gICAgb3BhY2l0eTogemVyb1xuICB9O1xuXG4gIGVuY29kZS51cGRhdGUgPSB1cGRhdGUgPSB7XG4gICAgb3BhY2l0eToge3ZhbHVlOiAxfSxcbiAgICB0ZXh0OiB7ZmllbGQ6IExhYmVsfVxuICB9O1xuXG4gIGVudGVyLnggPSB1cGRhdGUueCA9IHtcbiAgICBmaWVsZDogIE9mZnNldCxcbiAgICBvZmZzZXQ6IGNvbmZpZy5sYWJlbE9mZnNldFxuICB9O1xuXG4gIGVudGVyLnkgPSB1cGRhdGUueSA9IHtcbiAgICBmaWVsZDogIFNpemUsXG4gICAgbXVsdDogICAwLjUsXG4gICAgb2Zmc2V0OiB7XG4gICAgICBmaWVsZDogVG90YWwsXG4gICAgICBvZmZzZXQ6IHtcbiAgICAgICAgZmllbGQ6IHtncm91cDogJ2VudHJ5UGFkZGluZyd9LFxuICAgICAgICBtdWx0OiB7ZmllbGQ6IEluZGV4fVxuICAgICAgfVxuICAgIH1cbiAgfTtcblxuICByZXR1cm4gZ3VpZGVNYXJrKFRleHRNYXJrLCBMZWdlbmRMYWJlbFJvbGUsIEd1aWRlTGFiZWxTdHlsZSwgVmFsdWUsIGRhdGFSZWYsIGVuY29kZSwgdXNlckVuY29kZSk7XG59O1xuXG52YXIgbGVnZW5kU3ltYm9scyA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZywgdXNlckVuY29kZSwgZGF0YVJlZikge1xuICB2YXIgemVybyA9IHt2YWx1ZTogMH0sXG4gICAgICBlbmNvZGUgPSB7fSwgZW50ZXIsIHVwZGF0ZTtcblxuICBlbmNvZGUuZW50ZXIgPSBlbnRlciA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG4gIGFkZEVuY29kZShlbnRlciwgJ3NoYXBlJywgY29uZmlnLnN5bWJvbFR5cGUpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdzaXplJywgY29uZmlnLnN5bWJvbFNpemUpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdzdHJva2VXaWR0aCcsIGNvbmZpZy5zeW1ib2xTdHJva2VXaWR0aCk7XG4gIGlmICghc3BlYy5maWxsKSB7XG4gICAgYWRkRW5jb2RlKGVudGVyLCAnZmlsbCcsIGNvbmZpZy5zeW1ib2xGaWxsQ29sb3IpO1xuICAgIGFkZEVuY29kZShlbnRlciwgJ3N0cm9rZScsIGNvbmZpZy5zeW1ib2xTdHJva2VDb2xvcik7XG4gIH1cblxuICBlbmNvZGUuZXhpdCA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG5cbiAgZW5jb2RlLnVwZGF0ZSA9IHVwZGF0ZSA9IHtcbiAgICBvcGFjaXR5OiB7dmFsdWU6IDF9XG4gIH07XG5cbiAgZW50ZXIueCA9IHVwZGF0ZS54ID0ge1xuICAgIGZpZWxkOiBPZmZzZXQsXG4gICAgbXVsdDogIDAuNVxuICB9O1xuXG4gIGVudGVyLnkgPSB1cGRhdGUueSA9IHtcbiAgICBmaWVsZDogU2l6ZSxcbiAgICBtdWx0OiAgMC41LFxuICAgIG9mZnNldDoge1xuICAgICAgZmllbGQ6IFRvdGFsLFxuICAgICAgb2Zmc2V0OiB7XG4gICAgICAgIGZpZWxkOiB7Z3JvdXA6ICdlbnRyeVBhZGRpbmcnfSxcbiAgICAgICAgbXVsdDoge2ZpZWxkOiBJbmRleH1cbiAgICAgIH1cbiAgICB9XG4gIH07XG5cbiAgTGVnZW5kU2NhbGVzLmZvckVhY2goZnVuY3Rpb24oc2NhbGUpIHtcbiAgICBpZiAoc3BlY1tzY2FsZV0pIHtcbiAgICAgIHVwZGF0ZVtzY2FsZV0gPSBlbnRlcltzY2FsZV0gPSB7c2NhbGU6IHNwZWNbc2NhbGVdLCBmaWVsZDogVmFsdWV9O1xuICAgIH1cbiAgfSk7XG5cbiAgcmV0dXJuIGd1aWRlTWFyayhTeW1ib2xNYXJrLCBMZWdlbmRTeW1ib2xSb2xlLCBudWxsLCBWYWx1ZSwgZGF0YVJlZiwgZW5jb2RlLCB1c2VyRW5jb2RlKTtcbn07XG5cbnZhciBsZWdlbmRUaXRsZSA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZywgdXNlckVuY29kZSwgZGF0YVJlZikge1xuICB2YXIgemVybyA9IHt2YWx1ZTogMH0sXG4gICAgICB0aXRsZSA9IHNwZWMudGl0bGUsXG4gICAgICBlbmNvZGUgPSB7fSwgZW50ZXI7XG5cbiAgZW5jb2RlLmVudGVyID0gZW50ZXIgPSB7XG4gICAgeDoge2ZpZWxkOiB7Z3JvdXA6ICdwYWRkaW5nJ319LFxuICAgIHk6IHtmaWVsZDoge2dyb3VwOiAncGFkZGluZyd9fSxcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG4gIGFkZEVuY29kZShlbnRlciwgJ2FsaWduJywgY29uZmlnLnRpdGxlQWxpZ24pO1xuICBhZGRFbmNvZGUoZW50ZXIsICdiYXNlbGluZScsIGNvbmZpZy50aXRsZUJhc2VsaW5lKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZmlsbCcsIGNvbmZpZy50aXRsZUNvbG9yKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udCcsIGNvbmZpZy50aXRsZUZvbnQpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdmb250U2l6ZScsIGNvbmZpZy50aXRsZUZvbnRTaXplKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udFdlaWdodCcsIGNvbmZpZy50aXRsZUZvbnRXZWlnaHQpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdsaW1pdCcsIGNvbmZpZy50aXRsZUxpbWl0KTtcblxuICBlbmNvZGUuZXhpdCA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG5cbiAgZW5jb2RlLnVwZGF0ZSA9IHtcbiAgICBvcGFjaXR5OiB7dmFsdWU6IDF9LFxuICAgIHRleHQ6IHRpdGxlICYmIHRpdGxlLnNpZ25hbCA/IHtzaWduYWw6IHRpdGxlLnNpZ25hbH0gOiB7dmFsdWU6IHRpdGxlICsgJyd9XG4gIH07XG5cbiAgcmV0dXJuIGd1aWRlTWFyayhUZXh0TWFyaywgTGVnZW5kVGl0bGVSb2xlLCBHdWlkZVRpdGxlU3R5bGUsIG51bGwsIGRhdGFSZWYsIGVuY29kZSwgdXNlckVuY29kZSk7XG59O1xuXG52YXIgZ3VpZGVHcm91cCA9IGZ1bmN0aW9uKHJvbGUsIHN0eWxlLCBuYW1lLCBkYXRhUmVmLCBpbnRlcmFjdGl2ZSwgZW5jb2RlLCBtYXJrcykge1xuICByZXR1cm4ge1xuICAgIHR5cGU6IEdyb3VwTWFyayxcbiAgICBuYW1lOiBuYW1lLFxuICAgIHJvbGU6IHJvbGUsXG4gICAgc3R5bGU6IHN0eWxlLFxuICAgIGZyb206IGRhdGFSZWYsXG4gICAgaW50ZXJhY3RpdmU6IGludGVyYWN0aXZlIHx8IGZhbHNlLFxuICAgIGVuY29kZTogZW5jb2RlLFxuICAgIG1hcmtzOiBtYXJrc1xuICB9O1xufTtcblxudmFyIGNsaXAkMyA9IGZ1bmN0aW9uKGNsaXAsIHNjb3BlKSB7XG4gIHZhciBleHByO1xuXG4gIGlmIChpc09iamVjdChjbGlwKSkge1xuICAgIGlmIChjbGlwLnNpZ25hbCkge1xuICAgICAgZXhwciA9IGNsaXAuc2lnbmFsO1xuICAgIH0gZWxzZSBpZiAoY2xpcC5wYXRoKSB7XG4gICAgICBleHByID0gJ3BhdGhTaGFwZSgnICsgcGFyYW0oY2xpcC5wYXRoKSArICcpJztcbiAgICB9IGVsc2UgaWYgKGNsaXAuc3BoZXJlKSB7XG4gICAgICBleHByID0gJ2dlb1NoYXBlKCcgKyBwYXJhbShjbGlwLnNwaGVyZSkgKyAnLCB7dHlwZTogXCJTcGhlcmVcIn0pJztcbiAgICB9XG4gIH1cblxuICByZXR1cm4gZXhwclxuICAgID8gc2NvcGUuc2lnbmFsUmVmKGV4cHIpXG4gICAgOiAhIWNsaXA7XG59O1xuXG5mdW5jdGlvbiBwYXJhbSh2YWx1ZSkge1xuICByZXR1cm4gaXNPYmplY3QodmFsdWUpICYmIHZhbHVlLnNpZ25hbFxuICAgID8gdmFsdWUuc2lnbmFsXG4gICAgOiAkKHZhbHVlKTtcbn1cblxudmFyIHJvbGUgPSBmdW5jdGlvbihzcGVjKSB7XG4gIHZhciByb2xlID0gc3BlYy5yb2xlIHx8ICcnO1xuICByZXR1cm4gKCFyb2xlLmluZGV4T2YoJ2F4aXMnKSB8fCAhcm9sZS5pbmRleE9mKCdsZWdlbmQnKSlcbiAgICA/IHJvbGVcbiAgICA6IHNwZWMudHlwZSA9PT0gR3JvdXBNYXJrID8gU2NvcGVSb2xlJDEgOiAocm9sZSB8fCBNYXJrUm9sZSk7XG59O1xuXG52YXIgZGVmaW5pdGlvbiQxID0gZnVuY3Rpb24oc3BlYykge1xuICByZXR1cm4ge1xuICAgIG1hcmt0eXBlOiAgICBzcGVjLnR5cGUsXG4gICAgbmFtZTogICAgICAgIHNwZWMubmFtZSB8fCB1bmRlZmluZWQsXG4gICAgcm9sZTogICAgICAgIHNwZWMucm9sZSB8fCByb2xlKHNwZWMpLFxuICAgIHppbmRleDogICAgICArc3BlYy56aW5kZXggfHwgdW5kZWZpbmVkXG4gIH07XG59O1xuXG52YXIgaW50ZXJhY3RpdmUgPSBmdW5jdGlvbihzcGVjLCBzY29wZSkge1xuICByZXR1cm4gc3BlYyAmJiBzcGVjLnNpZ25hbCA/IHNjb3BlLnNpZ25hbFJlZihzcGVjLnNpZ25hbClcbiAgICA6IHNwZWMgPT09IGZhbHNlID8gZmFsc2VcbiAgICA6IHRydWU7XG59O1xuXG4vKipcbiAqIFBhcnNlIGEgZGF0YSB0cmFuc2Zvcm0gc3BlY2lmaWNhdGlvbi5cbiAqL1xudmFyIHBhcnNlVHJhbnNmb3JtID0gZnVuY3Rpb24oc3BlYywgc2NvcGUpIHtcbiAgdmFyIGRlZiA9IGRlZmluaXRpb24oc3BlYy50eXBlKTtcbiAgaWYgKCFkZWYpIGVycm9yJDEoJ1VucmVjb2duaXplZCB0cmFuc2Zvcm0gdHlwZTogJyArICQoc3BlYy50eXBlKSk7XG5cbiAgdmFyIHQgPSBlbnRyeShkZWYudHlwZS50b0xvd2VyQ2FzZSgpLCBudWxsLCBwYXJzZVBhcmFtZXRlcnMoZGVmLCBzcGVjLCBzY29wZSkpO1xuICBpZiAoc3BlYy5zaWduYWwpIHNjb3BlLmFkZFNpZ25hbChzcGVjLnNpZ25hbCwgc2NvcGUucHJveHkodCkpO1xuICB0Lm1ldGFkYXRhID0gZGVmLm1ldGFkYXRhIHx8IHt9O1xuXG4gIHJldHVybiB0O1xufTtcblxuLyoqXG4gKiBQYXJzZSBhbGwgcGFyYW1ldGVycyBvZiBhIGRhdGEgdHJhbnNmb3JtLlxuICovXG5mdW5jdGlvbiBwYXJzZVBhcmFtZXRlcnMoZGVmLCBzcGVjLCBzY29wZSkge1xuICB2YXIgcGFyYW1zID0ge30sIHBkZWYsIGksIG47XG4gIGZvciAoaT0wLCBuPWRlZi5wYXJhbXMubGVuZ3RoOyBpPG47ICsraSkge1xuICAgIHBkZWYgPSBkZWYucGFyYW1zW2ldO1xuICAgIHBhcmFtc1twZGVmLm5hbWVdID0gcGFyc2VQYXJhbWV0ZXIkMShwZGVmLCBzcGVjLCBzY29wZSk7XG4gIH1cbiAgcmV0dXJuIHBhcmFtcztcbn1cblxuLyoqXG4gKiBQYXJzZSBhIGRhdGEgdHJhbnNmb3JtIHBhcmFtZXRlci5cbiAqL1xuZnVuY3Rpb24gcGFyc2VQYXJhbWV0ZXIkMShkZWYsIHNwZWMsIHNjb3BlKSB7XG4gIHZhciB0eXBlID0gZGVmLnR5cGUsXG4gICAgICB2YWx1ZSQkMSA9IHNwZWNbZGVmLm5hbWVdO1xuXG4gIGlmICh0eXBlID09PSAnaW5kZXgnKSB7XG4gICAgcmV0dXJuIHBhcnNlSW5kZXhQYXJhbWV0ZXIoZGVmLCBzcGVjLCBzY29wZSk7XG4gIH0gZWxzZSBpZiAodmFsdWUkJDEgPT09IHVuZGVmaW5lZCkge1xuICAgIGlmIChkZWYucmVxdWlyZWQpIHtcbiAgICAgIGVycm9yJDEoJ01pc3NpbmcgcmVxdWlyZWQgJyArICQoc3BlYy50eXBlKVxuICAgICAgICAgICsgJyBwYXJhbWV0ZXI6ICcgKyAkKGRlZi5uYW1lKSk7XG4gICAgfVxuICAgIHJldHVybjtcbiAgfSBlbHNlIGlmICh0eXBlID09PSAncGFyYW0nKSB7XG4gICAgcmV0dXJuIHBhcnNlU3ViUGFyYW1ldGVycyhkZWYsIHNwZWMsIHNjb3BlKTtcbiAgfSBlbHNlIGlmICh0eXBlID09PSAncHJvamVjdGlvbicpIHtcbiAgICByZXR1cm4gc2NvcGUucHJvamVjdGlvblJlZihzcGVjW2RlZi5uYW1lXSk7XG4gIH1cblxuICByZXR1cm4gZGVmLmFycmF5ICYmICFpc1NpZ25hbCh2YWx1ZSQkMSlcbiAgICA/IHZhbHVlJCQxLm1hcChmdW5jdGlvbih2KSB7IHJldHVybiBwYXJhbWV0ZXJWYWx1ZShkZWYsIHYsIHNjb3BlKTsgfSlcbiAgICA6IHBhcmFtZXRlclZhbHVlKGRlZiwgdmFsdWUkJDEsIHNjb3BlKTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIHNpbmdsZSBwYXJhbWV0ZXIgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIHBhcmFtZXRlclZhbHVlKGRlZiwgdmFsdWUkJDEsIHNjb3BlKSB7XG4gIHZhciB0eXBlID0gZGVmLnR5cGU7XG5cbiAgaWYgKGlzU2lnbmFsKHZhbHVlJCQxKSkge1xuICAgIHJldHVybiBpc0V4cHIodHlwZSkgPyBlcnJvciQxKCdFeHByZXNzaW9uIHJlZmVyZW5jZXMgY2FuIG5vdCBiZSBzaWduYWxzLicpXG4gICAgICAgICA6IGlzRmllbGQodHlwZSkgPyBzY29wZS5maWVsZFJlZih2YWx1ZSQkMSlcbiAgICAgICAgIDogaXNDb21wYXJlKHR5cGUpID8gc2NvcGUuY29tcGFyZVJlZih2YWx1ZSQkMSlcbiAgICAgICAgIDogc2NvcGUuc2lnbmFsUmVmKHZhbHVlJCQxLnNpZ25hbCk7XG4gIH0gZWxzZSB7XG4gICAgdmFyIGV4cHIgPSBkZWYuZXhwciB8fCBpc0ZpZWxkKHR5cGUpO1xuICAgIHJldHVybiBleHByICYmIG91dGVyRXhwcih2YWx1ZSQkMSkgPyBwYXJzZUV4cHJlc3Npb24odmFsdWUkJDEuZXhwciwgc2NvcGUpXG4gICAgICAgICA6IGV4cHIgJiYgb3V0ZXJGaWVsZCh2YWx1ZSQkMSkgPyBmaWVsZFJlZiQxKHZhbHVlJCQxLmZpZWxkKVxuICAgICAgICAgOiBpc0V4cHIodHlwZSkgPyBwYXJzZUV4cHJlc3Npb24odmFsdWUkJDEsIHNjb3BlKVxuICAgICAgICAgOiBpc0RhdGEodHlwZSkgPyByZWYoc2NvcGUuZ2V0RGF0YSh2YWx1ZSQkMSkudmFsdWVzKVxuICAgICAgICAgOiBpc0ZpZWxkKHR5cGUpID8gZmllbGRSZWYkMSh2YWx1ZSQkMSlcbiAgICAgICAgIDogaXNDb21wYXJlKHR5cGUpID8gc2NvcGUuY29tcGFyZVJlZih2YWx1ZSQkMSlcbiAgICAgICAgIDogdmFsdWUkJDE7XG4gIH1cbn1cblxuLyoqXG4gKiBQYXJzZSBwYXJhbWV0ZXIgZm9yIGFjY2Vzc2luZyBhbiBpbmRleCBvZiBhbm90aGVyIGRhdGEgc2V0LlxuICovXG5mdW5jdGlvbiBwYXJzZUluZGV4UGFyYW1ldGVyKGRlZiwgc3BlYywgc2NvcGUpIHtcbiAgaWYgKCFpc1N0cmluZyhzcGVjLmZyb20pKSB7XG4gICAgZXJyb3IkMSgnTG9va3VwIFwiZnJvbVwiIHBhcmFtZXRlciBtdXN0IGJlIGEgc3RyaW5nIGxpdGVyYWwuJyk7XG4gIH1cbiAgcmV0dXJuIHNjb3BlLmdldERhdGEoc3BlYy5mcm9tKS5sb29rdXBSZWYoc2NvcGUsIHNwZWMua2V5KTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIHBhcmFtZXRlciB0aGF0IGNvbnRhaW5zIG9uZSBvciBtb3JlIHN1Yi1wYXJhbWV0ZXIgb2JqZWN0cy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VTdWJQYXJhbWV0ZXJzKGRlZiwgc3BlYywgc2NvcGUpIHtcbiAgdmFyIHZhbHVlJCQxID0gc3BlY1tkZWYubmFtZV07XG5cbiAgaWYgKGRlZi5hcnJheSkge1xuICAgIGlmICghaXNBcnJheSh2YWx1ZSQkMSkpIHsgLy8gc2lnbmFscyBub3QgYWxsb3dlZCFcbiAgICAgIGVycm9yJDEoJ0V4cGVjdGVkIGFuIGFycmF5IG9mIHN1Yi1wYXJhbWV0ZXJzLiBJbnN0ZWFkOiAnICsgJCh2YWx1ZSQkMSkpO1xuICAgIH1cbiAgICByZXR1cm4gdmFsdWUkJDEubWFwKGZ1bmN0aW9uKHYpIHtcbiAgICAgIHJldHVybiBwYXJzZVN1YlBhcmFtZXRlcihkZWYsIHYsIHNjb3BlKTtcbiAgICB9KTtcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gcGFyc2VTdWJQYXJhbWV0ZXIoZGVmLCB2YWx1ZSQkMSwgc2NvcGUpO1xuICB9XG59XG5cbi8qKlxuICogUGFyc2UgYSBzdWItcGFyYW1ldGVyIG9iamVjdC5cbiAqL1xuZnVuY3Rpb24gcGFyc2VTdWJQYXJhbWV0ZXIoZGVmLCB2YWx1ZSQkMSwgc2NvcGUpIHtcbiAgdmFyIHBhcmFtcywgcGRlZiwgaywgaSwgbjtcblxuICAvLyBsb29wIG92ZXIgZGVmcyB0byBmaW5kIG1hdGNoaW5nIGtleVxuICBmb3IgKGk9MCwgbj1kZWYucGFyYW1zLmxlbmd0aDsgaTxuOyArK2kpIHtcbiAgICBwZGVmID0gZGVmLnBhcmFtc1tpXTtcbiAgICBmb3IgKGsgaW4gcGRlZi5rZXkpIHtcbiAgICAgIGlmIChwZGVmLmtleVtrXSAhPT0gdmFsdWUkJDFba10pIHsgcGRlZiA9IG51bGw7IGJyZWFrOyB9XG4gICAgfVxuICAgIGlmIChwZGVmKSBicmVhaztcbiAgfVxuICAvLyByYWlzZSBlcnJvciBpZiBtYXRjaGluZyBrZXkgbm90IGZvdW5kXG4gIGlmICghcGRlZikgZXJyb3IkMSgnVW5zdXBwb3J0ZWQgcGFyYW1ldGVyOiAnICsgJCh2YWx1ZSQkMSkpO1xuXG4gIC8vIHBhcnNlIHBhcmFtcywgY3JlYXRlIFBhcmFtcyB0cmFuc2Zvcm0sIHJldHVybiByZWZcbiAgcGFyYW1zID0gZXh0ZW5kKHBhcnNlUGFyYW1ldGVycyhwZGVmLCB2YWx1ZSQkMSwgc2NvcGUpLCBwZGVmLmtleSk7XG4gIHJldHVybiByZWYoc2NvcGUuYWRkKFBhcmFtcyQyKHBhcmFtcykpKTtcbn1cblxuLy8gLS0gVXRpbGl0aWVzIC0tLS0tXG5cbmZ1bmN0aW9uIG91dGVyRXhwcihfKSB7XG4gIHJldHVybiBfICYmIF8uZXhwcjtcbn1cblxuZnVuY3Rpb24gb3V0ZXJGaWVsZChfKSB7XG4gIHJldHVybiBfICYmIF8uZmllbGQ7XG59XG5cbmZ1bmN0aW9uIGlzRGF0YShfKSB7XG4gIHJldHVybiBfID09PSAnZGF0YSc7XG59XG5cbmZ1bmN0aW9uIGlzRXhwcihfKSB7XG4gIHJldHVybiBfID09PSAnZXhwcic7XG59XG5cbmZ1bmN0aW9uIGlzRmllbGQoXykge1xuICByZXR1cm4gXyA9PT0gJ2ZpZWxkJztcbn1cblxuZnVuY3Rpb24gaXNDb21wYXJlKF8pIHtcbiAgcmV0dXJuIF8gPT09ICdjb21wYXJlJ1xufVxuXG52YXIgcGFyc2VEYXRhID0gZnVuY3Rpb24oZnJvbSwgZ3JvdXAsIHNjb3BlKSB7XG4gIHZhciBmYWNldCwga2V5JCQxLCBvcCwgZGF0YVJlZiwgcGFyZW50O1xuXG4gIC8vIGlmIG5vIHNvdXJjZSBkYXRhLCBnZW5lcmF0ZSBzaW5nbGV0b24gZGF0dW1cbiAgaWYgKCFmcm9tKSB7XG4gICAgZGF0YVJlZiA9IHJlZihzY29wZS5hZGQoQ29sbGVjdCQxKG51bGwsIFt7fV0pKSk7XG4gIH1cblxuICAvLyBpZiBmYWNldGVkLCBwcm9jZXNzIGZhY2V0IHNwZWNpZmljYXRpb25cbiAgZWxzZSBpZiAoZmFjZXQgPSBmcm9tLmZhY2V0KSB7XG4gICAgaWYgKCFncm91cCkgZXJyb3IkMSgnT25seSBncm91cCBtYXJrcyBjYW4gYmUgZmFjZXRlZC4nKTtcblxuICAgIC8vIHVzZSBwcmUtZmFjZXRlZCBzb3VyY2UgZGF0YSwgaWYgYXZhaWxhYmxlXG4gICAgaWYgKGZhY2V0LmZpZWxkICE9IG51bGwpIHtcbiAgICAgIGRhdGFSZWYgPSBwYXJlbnQgPSByZWYoc2NvcGUuZ2V0RGF0YShmYWNldC5kYXRhKS5vdXRwdXQpO1xuICAgIH0gZWxzZSB7XG4gICAgICAvLyBnZW5lcmF0ZSBmYWNldCBhZ2dyZWdhdGVzIGlmIG5vIGRpcmVjdCBkYXRhIHNwZWNpZmljYXRpb25cbiAgICAgIGlmICghZnJvbS5kYXRhKSB7XG4gICAgICAgIG9wID0gcGFyc2VUcmFuc2Zvcm0oZXh0ZW5kKHtcbiAgICAgICAgICB0eXBlOiAgICAnYWdncmVnYXRlJyxcbiAgICAgICAgICBncm91cGJ5OiBhcnJheShmYWNldC5ncm91cGJ5KVxuICAgICAgICB9LCBmYWNldC5hZ2dyZWdhdGUpLCBzY29wZSk7XG4gICAgICAgIG9wLnBhcmFtcy5rZXkgPSBzY29wZS5rZXlSZWYoZmFjZXQuZ3JvdXBieSk7XG4gICAgICAgIG9wLnBhcmFtcy5wdWxzZSA9IHJlZihzY29wZS5nZXREYXRhKGZhY2V0LmRhdGEpLm91dHB1dCk7XG4gICAgICAgIGRhdGFSZWYgPSBwYXJlbnQgPSByZWYoc2NvcGUuYWRkKG9wKSk7XG4gICAgICB9IGVsc2Uge1xuICAgICAgICBwYXJlbnQgPSByZWYoc2NvcGUuZ2V0RGF0YShmcm9tLmRhdGEpLmFnZ3JlZ2F0ZSk7XG4gICAgICB9XG5cbiAgICAgIGtleSQkMSA9IHNjb3BlLmtleVJlZihmYWNldC5ncm91cGJ5LCB0cnVlKTtcbiAgICB9XG4gIH1cblxuICAvLyBpZiBub3QgeWV0IGRlZmluZWQsIGdldCBzb3VyY2UgZGF0YSByZWZlcmVuY2VcbiAgaWYgKCFkYXRhUmVmKSB7XG4gICAgZGF0YVJlZiA9IGZyb20uJHJlZiA/IGZyb21cbiAgICAgIDogcmVmKHNjb3BlLmdldERhdGEoZnJvbS5kYXRhKS5vdXRwdXQpO1xuICB9XG5cbiAgcmV0dXJuIHtcbiAgICBrZXk6IGtleSQkMSxcbiAgICBwdWxzZTogZGF0YVJlZixcbiAgICBwYXJlbnQ6IHBhcmVudFxuICB9O1xufTtcblxuZnVuY3Rpb24gRGF0YVNjb3BlKHNjb3BlLCBpbnB1dCwgb3V0cHV0LCB2YWx1ZXMsIGFnZ3IpIHtcbiAgdGhpcy5zY29wZSA9IHNjb3BlOyAgIC8vIHBhcmVudCBzY29wZSBvYmplY3RcbiAgdGhpcy5pbnB1dCA9IGlucHV0OyAgIC8vIGZpcnN0IG9wZXJhdG9yIGluIHBpcGVsaW5lICh0dXBsZSBpbnB1dClcbiAgdGhpcy5vdXRwdXQgPSBvdXRwdXQ7IC8vIGxhc3Qgb3BlcmF0b3IgaW4gcGlwZWxpbmUgKHR1cGxlIG91dHB1dClcbiAgdGhpcy52YWx1ZXMgPSB2YWx1ZXM7IC8vIG9wZXJhdG9yIGZvciBhY2Nlc3NpbmcgdHVwbGVzIChidXQgbm90IHR1cGxlIGZsb3cpXG5cbiAgLy8gbGFzdCBhZ2dyZWdhdGUgaW4gdHJhbnNmb3JtIHBpcGVsaW5lXG4gIHRoaXMuYWdncmVnYXRlID0gYWdncjtcblxuICAvLyBsb29rdXAgdGFibGUgb2YgZmllbGQgaW5kaWNlc1xuICB0aGlzLmluZGV4ID0ge307XG59XG5cbkRhdGFTY29wZS5mcm9tRW50cmllcyA9IGZ1bmN0aW9uKHNjb3BlLCBlbnRyaWVzKSB7XG4gIHZhciBuID0gZW50cmllcy5sZW5ndGgsXG4gICAgICBpID0gMSxcbiAgICAgIGlucHV0ICA9IGVudHJpZXNbMF0sXG4gICAgICB2YWx1ZXMgPSBlbnRyaWVzW24tMV0sXG4gICAgICBvdXRwdXQgPSBlbnRyaWVzW24tMl0sXG4gICAgICBhZ2dyID0gbnVsbDtcblxuICAvLyBhZGQgb3BlcmF0b3IgZW50cmllcyB0byB0aGlzIHNjb3BlLCB3aXJlIHVwIHB1bHNlIGNoYWluXG4gIHNjb3BlLmFkZChlbnRyaWVzWzBdKTtcbiAgZm9yICg7IGk8bjsgKytpKSB7XG4gICAgZW50cmllc1tpXS5wYXJhbXMucHVsc2UgPSByZWYoZW50cmllc1tpLTFdKTtcbiAgICBzY29wZS5hZGQoZW50cmllc1tpXSk7XG4gICAgaWYgKGVudHJpZXNbaV0udHlwZSA9PT0gJ2FnZ3JlZ2F0ZScpIGFnZ3IgPSBlbnRyaWVzW2ldO1xuICB9XG5cbiAgcmV0dXJuIG5ldyBEYXRhU2NvcGUoc2NvcGUsIGlucHV0LCBvdXRwdXQsIHZhbHVlcywgYWdncik7XG59O1xuXG52YXIgcHJvdG90eXBlJDg0ID0gRGF0YVNjb3BlLnByb3RvdHlwZTtcblxucHJvdG90eXBlJDg0LmNvdW50c1JlZiA9IGZ1bmN0aW9uKHNjb3BlLCBmaWVsZCQkMSwgc29ydCkge1xuICB2YXIgZHMgPSB0aGlzLFxuICAgICAgY2FjaGUgPSBkcy5jb3VudHMgfHwgKGRzLmNvdW50cyA9IHt9KSxcbiAgICAgIGsgPSBmaWVsZEtleShmaWVsZCQkMSksIHYsIGEsIHA7XG5cbiAgaWYgKGsgIT0gbnVsbCkge1xuICAgIHNjb3BlID0gZHMuc2NvcGU7XG4gICAgdiA9IGNhY2hlW2tdO1xuICB9XG5cbiAgaWYgKCF2KSB7XG4gICAgcCA9IHtcbiAgICAgIGdyb3VwYnk6IHNjb3BlLmZpZWxkUmVmKGZpZWxkJCQxLCAna2V5JyksXG4gICAgICBwdWxzZTogcmVmKGRzLm91dHB1dClcbiAgICB9O1xuICAgIGlmIChzb3J0ICYmIHNvcnQuZmllbGQpIGFkZFNvcnRGaWVsZChzY29wZSwgcCwgc29ydCk7XG4gICAgYSA9IHNjb3BlLmFkZChBZ2dyZWdhdGUkMShwKSk7XG4gICAgdiA9IHNjb3BlLmFkZChDb2xsZWN0JDEoe3B1bHNlOiByZWYoYSl9KSk7XG4gICAgdiA9IHthZ2c6IGEsIHJlZjogcmVmKHYpfTtcbiAgICBpZiAoayAhPSBudWxsKSBjYWNoZVtrXSA9IHY7XG4gIH0gZWxzZSBpZiAoc29ydCAmJiBzb3J0LmZpZWxkKSB7XG4gICAgYWRkU29ydEZpZWxkKHNjb3BlLCB2LmFnZy5wYXJhbXMsIHNvcnQpO1xuICB9XG5cbiAgcmV0dXJuIHYucmVmO1xufTtcblxuZnVuY3Rpb24gZmllbGRLZXkoZmllbGQkJDEpIHtcbiAgcmV0dXJuIGlzU3RyaW5nKGZpZWxkJCQxKSA/IGZpZWxkJCQxIDogbnVsbDtcbn1cblxuZnVuY3Rpb24gYWRkU29ydEZpZWxkKHNjb3BlLCBwLCBzb3J0KSB7XG4gIHZhciBhcyA9IGFnZ3JGaWVsZChzb3J0Lm9wLCBzb3J0LmZpZWxkKSwgcztcblxuICBpZiAocC5vcHMpIHtcbiAgICBmb3IgKHZhciBpPTAsIG49cC5hcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgICBpZiAocC5hc1tpXSA9PT0gYXMpIHJldHVybjtcbiAgICB9XG4gIH0gZWxzZSB7XG4gICAgcC5vcHMgPSBbJ2NvdW50J107XG4gICAgcC5maWVsZHMgPSBbbnVsbF07XG4gICAgcC5hcyA9IFsnY291bnQnXTtcbiAgfVxuICBpZiAoc29ydC5vcCkge1xuICAgIHAub3BzLnB1c2goKHM9c29ydC5vcC5zaWduYWwpID8gc2NvcGUuc2lnbmFsUmVmKHMpIDogc29ydC5vcCk7XG4gICAgcC5maWVsZHMucHVzaChzY29wZS5maWVsZFJlZihzb3J0LmZpZWxkKSk7XG4gICAgcC5hcy5wdXNoKGFzKTtcbiAgfVxufVxuXG5mdW5jdGlvbiBjYWNoZShzY29wZSwgZHMsIG5hbWUsIG9wdHlwZSwgZmllbGQkJDEsIGNvdW50cywgaW5kZXgpIHtcbiAgdmFyIGNhY2hlID0gZHNbbmFtZV0gfHwgKGRzW25hbWVdID0ge30pLFxuICAgICAgc29ydCA9IHNvcnRLZXkoY291bnRzKSxcbiAgICAgIGsgPSBmaWVsZEtleShmaWVsZCQkMSksIHYsIG9wO1xuXG4gIGlmIChrICE9IG51bGwpIHtcbiAgICBzY29wZSA9IGRzLnNjb3BlO1xuICAgIGsgPSBrICsgKHNvcnQgPyAnfCcgKyBzb3J0IDogJycpO1xuICAgIHYgPSBjYWNoZVtrXTtcbiAgfVxuXG4gIGlmICghdikge1xuICAgIHZhciBwYXJhbXMgPSBjb3VudHNcbiAgICAgID8ge2ZpZWxkOiBrZXlGaWVsZFJlZiwgcHVsc2U6IGRzLmNvdW50c1JlZihzY29wZSwgZmllbGQkJDEsIGNvdW50cyl9XG4gICAgICA6IHtmaWVsZDogc2NvcGUuZmllbGRSZWYoZmllbGQkJDEpLCBwdWxzZTogcmVmKGRzLm91dHB1dCl9O1xuICAgIGlmIChzb3J0KSBwYXJhbXMuc29ydCA9IHNjb3BlLnNvcnRSZWYoY291bnRzKTtcbiAgICBvcCA9IHNjb3BlLmFkZChlbnRyeShvcHR5cGUsIHVuZGVmaW5lZCwgcGFyYW1zKSk7XG4gICAgaWYgKGluZGV4KSBkcy5pbmRleFtmaWVsZCQkMV0gPSBvcDtcbiAgICB2ID0gcmVmKG9wKTtcbiAgICBpZiAoayAhPSBudWxsKSBjYWNoZVtrXSA9IHY7XG4gIH1cbiAgcmV0dXJuIHY7XG59XG5cbnByb3RvdHlwZSQ4NC50dXBsZXNSZWYgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHJlZih0aGlzLnZhbHVlcyk7XG59O1xuXG5wcm90b3R5cGUkODQuZXh0ZW50UmVmID0gZnVuY3Rpb24oc2NvcGUsIGZpZWxkJCQxKSB7XG4gIHJldHVybiBjYWNoZShzY29wZSwgdGhpcywgJ2V4dGVudCcsICdleHRlbnQnLCBmaWVsZCQkMSwgZmFsc2UpO1xufTtcblxucHJvdG90eXBlJDg0LmRvbWFpblJlZiA9IGZ1bmN0aW9uKHNjb3BlLCBmaWVsZCQkMSkge1xuICByZXR1cm4gY2FjaGUoc2NvcGUsIHRoaXMsICdkb21haW4nLCAndmFsdWVzJywgZmllbGQkJDEsIGZhbHNlKTtcbn07XG5cbnByb3RvdHlwZSQ4NC52YWx1ZXNSZWYgPSBmdW5jdGlvbihzY29wZSwgZmllbGQkJDEsIHNvcnQpIHtcbiAgcmV0dXJuIGNhY2hlKHNjb3BlLCB0aGlzLCAndmFscycsICd2YWx1ZXMnLCBmaWVsZCQkMSwgc29ydCB8fCB0cnVlKTtcbn07XG5cbnByb3RvdHlwZSQ4NC5sb29rdXBSZWYgPSBmdW5jdGlvbihzY29wZSwgZmllbGQkJDEpIHtcbiAgcmV0dXJuIGNhY2hlKHNjb3BlLCB0aGlzLCAnbG9va3VwJywgJ3R1cGxlaW5kZXgnLCBmaWVsZCQkMSwgZmFsc2UpO1xufTtcblxucHJvdG90eXBlJDg0LmluZGF0YVJlZiA9IGZ1bmN0aW9uKHNjb3BlLCBmaWVsZCQkMSkge1xuICByZXR1cm4gY2FjaGUoc2NvcGUsIHRoaXMsICdpbmRhdGEnLCAndHVwbGVpbmRleCcsIGZpZWxkJCQxLCB0cnVlLCB0cnVlKTtcbn07XG5cbnZhciBwYXJzZUZhY2V0ID0gZnVuY3Rpb24oc3BlYywgc2NvcGUsIGdyb3VwKSB7XG4gIHZhciBmYWNldCA9IHNwZWMuZnJvbS5mYWNldCxcbiAgICAgIG5hbWUgPSBmYWNldC5uYW1lLFxuICAgICAgZGF0YSA9IHJlZihzY29wZS5nZXREYXRhKGZhY2V0LmRhdGEpLm91dHB1dCksXG4gICAgICBzdWJzY29wZSwgc291cmNlLCB2YWx1ZXMsIG9wO1xuXG4gIGlmICghZmFjZXQubmFtZSkge1xuICAgIGVycm9yJDEoJ0ZhY2V0IG11c3QgaGF2ZSBhIG5hbWU6ICcgKyAkKGZhY2V0KSk7XG4gIH1cbiAgaWYgKCFmYWNldC5kYXRhKSB7XG4gICAgZXJyb3IkMSgnRmFjZXQgbXVzdCByZWZlcmVuY2UgYSBkYXRhIHNldDogJyArICQoZmFjZXQpKTtcbiAgfVxuXG4gIGlmIChmYWNldC5maWVsZCkge1xuICAgIG9wID0gc2NvcGUuYWRkKFByZUZhY2V0JDEoe1xuICAgICAgZmllbGQ6IHNjb3BlLmZpZWxkUmVmKGZhY2V0LmZpZWxkKSxcbiAgICAgIHB1bHNlOiBkYXRhXG4gICAgfSkpO1xuICB9IGVsc2UgaWYgKGZhY2V0Lmdyb3VwYnkpIHtcbiAgICBvcCA9IHNjb3BlLmFkZChGYWNldCQxKHtcbiAgICAgIGtleTogICBzY29wZS5rZXlSZWYoZmFjZXQuZ3JvdXBieSksXG4gICAgICBncm91cDogcmVmKHNjb3BlLnByb3h5KGdyb3VwLnBhcmVudCkpLFxuICAgICAgcHVsc2U6IGRhdGFcbiAgICB9KSk7XG4gIH0gZWxzZSB7XG4gICAgZXJyb3IkMSgnRmFjZXQgbXVzdCBzcGVjaWZ5IGdyb3VwYnkgb3IgZmllbGQ6ICcgKyAkKGZhY2V0KSk7XG4gIH1cblxuICAvLyBpbml0aWFsaXplIGZhY2V0IHN1YnNjb3BlXG4gIHN1YnNjb3BlID0gc2NvcGUuZm9yaygpO1xuICBzb3VyY2UgPSBzdWJzY29wZS5hZGQoQ29sbGVjdCQxKCkpO1xuICB2YWx1ZXMgPSBzdWJzY29wZS5hZGQoU2lldmUkMSh7cHVsc2U6IHJlZihzb3VyY2UpfSkpO1xuICBzdWJzY29wZS5hZGREYXRhKG5hbWUsIG5ldyBEYXRhU2NvcGUoc3Vic2NvcGUsIHNvdXJjZSwgc291cmNlLCB2YWx1ZXMpKTtcbiAgc3Vic2NvcGUuYWRkU2lnbmFsKCdwYXJlbnQnLCBudWxsKTtcblxuICAvLyBwYXJzZSBmYWNldGVkIHN1YmZsb3dcbiAgb3AucGFyYW1zLnN1YmZsb3cgPSB7XG4gICAgJHN1YmZsb3c6IHBhcnNlU3BlYyhzcGVjLCBzdWJzY29wZSkudG9SdW50aW1lKClcbiAgfTtcbn07XG5cbnZhciBwYXJzZVN1YmZsb3cgPSBmdW5jdGlvbihzcGVjLCBzY29wZSwgaW5wdXQpIHtcbiAgdmFyIG9wID0gc2NvcGUuYWRkKFByZUZhY2V0JDEoe3B1bHNlOiBpbnB1dC5wdWxzZX0pKSxcbiAgICAgIHN1YnNjb3BlID0gc2NvcGUuZm9yaygpO1xuXG4gIHN1YnNjb3BlLmFkZChTaWV2ZSQxKCkpO1xuICBzdWJzY29wZS5hZGRTaWduYWwoJ3BhcmVudCcsIG51bGwpO1xuXG4gIC8vIHBhcnNlIGdyb3VwIG1hcmsgc3ViZmxvd1xuICBvcC5wYXJhbXMuc3ViZmxvdyA9IHtcbiAgICAkc3ViZmxvdzogcGFyc2VTcGVjKHNwZWMsIHN1YnNjb3BlKS50b1J1bnRpbWUoKVxuICB9O1xufTtcblxudmFyIHBhcnNlVHJpZ2dlciA9IGZ1bmN0aW9uKHNwZWMsIHNjb3BlLCBuYW1lKSB7XG4gIHZhciByZW1vdmUgPSBzcGVjLnJlbW92ZSxcbiAgICAgIGluc2VydCA9IHNwZWMuaW5zZXJ0LFxuICAgICAgdG9nZ2xlID0gc3BlYy50b2dnbGUsXG4gICAgICBtb2RpZnkgPSBzcGVjLm1vZGlmeSxcbiAgICAgIHZhbHVlcyA9IHNwZWMudmFsdWVzLFxuICAgICAgb3AgPSBzY29wZS5hZGQob3BlcmF0b3IoKSksXG4gICAgICB1cGRhdGUsIGV4cHI7XG5cbiAgdXBkYXRlID0gJ2lmKCcgKyBzcGVjLnRyaWdnZXIgKyAnLG1vZGlmeShcIidcbiAgICArIG5hbWUgKyAnXCIsJ1xuICAgICsgW2luc2VydCwgcmVtb3ZlLCB0b2dnbGUsIG1vZGlmeSwgdmFsdWVzXVxuICAgICAgICAubWFwKGZ1bmN0aW9uKF8pIHsgcmV0dXJuIF8gPT0gbnVsbCA/ICdudWxsJyA6IF87IH0pXG4gICAgICAgIC5qb2luKCcsJylcbiAgICArICcpLDApJztcblxuICBleHByID0gcGFyc2VFeHByZXNzaW9uKHVwZGF0ZSwgc2NvcGUpO1xuICBvcC51cGRhdGUgPSBleHByLiRleHByO1xuICBvcC5wYXJhbXMgPSBleHByLiRwYXJhbXM7XG59O1xuXG52YXIgcGFyc2VNYXJrID0gZnVuY3Rpb24oc3BlYywgc2NvcGUpIHtcbiAgdmFyIHJvbGUkJDEgPSByb2xlKHNwZWMpLFxuICAgICAgZ3JvdXAgPSBzcGVjLnR5cGUgPT09IEdyb3VwTWFyayxcbiAgICAgIGZhY2V0ID0gc3BlYy5mcm9tICYmIHNwZWMuZnJvbS5mYWNldCxcbiAgICAgIGxheW91dCA9IHNwZWMubGF5b3V0IHx8IHJvbGUkJDEgPT09IFNjb3BlUm9sZSQxIHx8IHJvbGUkJDEgPT09IEZyYW1lUm9sZSQxLFxuICAgICAgbmVzdGVkID0gcm9sZSQkMSA9PT0gTWFya1JvbGUgfHwgbGF5b3V0IHx8IGZhY2V0LFxuICAgICAgb3ZlcmxhcCA9IHNwZWMub3ZlcmxhcCxcbiAgICAgIG9wcywgb3AsIGlucHV0LCBzdG9yZSwgYm91bmQsIHJlbmRlciwgc2lldmUsIG5hbWUsXG4gICAgICBqb2luUmVmLCBtYXJrUmVmLCBlbmNvZGVSZWYsIGxheW91dFJlZiwgYm91bmRSZWY7XG5cbiAgLy8gcmVzb2x2ZSBpbnB1dCBkYXRhXG4gIGlucHV0ID0gcGFyc2VEYXRhKHNwZWMuZnJvbSwgZ3JvdXAsIHNjb3BlKTtcblxuICAvLyBkYXRhIGpvaW4gdG8gbWFwIHR1cGxlcyB0byB2aXN1YWwgaXRlbXNcbiAgb3AgPSBzY29wZS5hZGQoRGF0YUpvaW4kMSh7XG4gICAga2V5OiAgIGlucHV0LmtleSB8fCAoc3BlYy5rZXkgPyBmaWVsZFJlZiQxKHNwZWMua2V5KSA6IHVuZGVmaW5lZCksXG4gICAgcHVsc2U6IGlucHV0LnB1bHNlLFxuICAgIGNsZWFuOiAhZ3JvdXBcbiAgfSkpO1xuICBqb2luUmVmID0gcmVmKG9wKTtcblxuICAvLyBjb2xsZWN0IHZpc3VhbCBpdGVtc1xuICBvcCA9IHN0b3JlID0gc2NvcGUuYWRkKENvbGxlY3QkMSh7cHVsc2U6IGpvaW5SZWZ9KSk7XG5cbiAgLy8gY29ubmVjdCB2aXN1YWwgaXRlbXMgdG8gc2NlbmVncmFwaFxuICBvcCA9IHNjb3BlLmFkZChNYXJrJDEoe1xuICAgIG1hcmtkZWY6ICAgICBkZWZpbml0aW9uJDEoc3BlYyksXG4gICAgaW50ZXJhY3RpdmU6IGludGVyYWN0aXZlKHNwZWMuaW50ZXJhY3RpdmUsIHNjb3BlKSxcbiAgICBjbGlwOiAgICAgICAgY2xpcCQzKHNwZWMuY2xpcCwgc2NvcGUpLFxuICAgIGNvbnRleHQ6ICAgICB7JGNvbnRleHQ6IHRydWV9LFxuICAgIGdyb3VwczogICAgICBzY29wZS5sb29rdXAoKSxcbiAgICBwYXJlbnQ6ICAgICAgc2NvcGUuc2lnbmFscy5wYXJlbnQgPyBzY29wZS5zaWduYWxSZWYoJ3BhcmVudCcpIDogbnVsbCxcbiAgICBpbmRleDogICAgICAgc2NvcGUubWFya3BhdGgoKSxcbiAgICBwdWxzZTogICAgICAgcmVmKG9wKVxuICB9KSk7XG4gIG1hcmtSZWYgPSByZWYob3ApO1xuXG4gIC8vIGFkZCB2aXN1YWwgZW5jb2RlcnNcbiAgb3AgPSBzY29wZS5hZGQoRW5jb2RlJDEoXG4gICAgZW5jb2RlcnMoc3BlYy5lbmNvZGUsIHNwZWMudHlwZSwgcm9sZSQkMSwgc3BlYy5zdHlsZSwgc2NvcGUsIHtwdWxzZTogbWFya1JlZn0pXG4gICkpO1xuXG4gIC8vIG1vbml0b3IgcGFyZW50IG1hcmtzIHRvIHByb3BhZ2F0ZSBjaGFuZ2VzXG4gIG9wLnBhcmFtcy5wYXJlbnQgPSBzY29wZS5lbmNvZGUoKTtcblxuICAvLyBhZGQgcG9zdC1lbmNvZGluZyB0cmFuc2Zvcm1zLCBpZiBkZWZpbmVkXG4gIGlmIChzcGVjLnRyYW5zZm9ybSkge1xuICAgIHNwZWMudHJhbnNmb3JtLmZvckVhY2goZnVuY3Rpb24oXykge1xuICAgICAgdmFyIHR4ID0gcGFyc2VUcmFuc2Zvcm0oXywgc2NvcGUpO1xuICAgICAgaWYgKHR4Lm1ldGFkYXRhLmdlbmVyYXRlcyB8fCB0eC5tZXRhZGF0YS5jaGFuZ2VzKSB7XG4gICAgICAgIGVycm9yJDEoJ01hcmsgdHJhbnNmb3JtcyBzaG91bGQgbm90IGdlbmVyYXRlIG5ldyBkYXRhLicpO1xuICAgICAgfVxuICAgICAgdHgucGFyYW1zLnB1bHNlID0gcmVmKG9wKTtcbiAgICAgIHNjb3BlLmFkZChvcCA9IHR4KTtcbiAgICB9KTtcbiAgfVxuXG4gIC8vIGlmIGl0ZW0gc29ydCBzcGVjaWZpZWQsIHBlcmZvcm0gcG9zdC1lbmNvZGluZ1xuICBpZiAoc3BlYy5zb3J0KSB7XG4gICAgb3AgPSBzY29wZS5hZGQoU29ydEl0ZW1zJDEoe1xuICAgICAgc29ydDogIHNjb3BlLmNvbXBhcmVSZWYoc3BlYy5zb3J0LCB0cnVlKSwgLy8gc3RhYmxlIHNvcnRcbiAgICAgIHB1bHNlOiByZWYob3ApXG4gICAgfSkpO1xuICB9XG5cbiAgZW5jb2RlUmVmID0gcmVmKG9wKTtcblxuICAvLyBhZGQgdmlldyBsYXlvdXQgb3BlcmF0b3IgaWYgbmVlZGVkXG4gIGlmIChmYWNldCB8fCBsYXlvdXQpIHtcbiAgICBsYXlvdXQgPSBzY29wZS5hZGQoVmlld0xheW91dCQxKHtcbiAgICAgIGxheW91dDogICAgICAgc2NvcGUub2JqZWN0UHJvcGVydHkoc3BlYy5sYXlvdXQpLFxuICAgICAgbGVnZW5kTWFyZ2luOiBzY29wZS5jb25maWcubGVnZW5kTWFyZ2luLFxuICAgICAgbWFyazogICAgICAgICBtYXJrUmVmLFxuICAgICAgcHVsc2U6ICAgICAgICBlbmNvZGVSZWZcbiAgICB9KSk7XG4gICAgbGF5b3V0UmVmID0gcmVmKGxheW91dCk7XG4gIH1cblxuICAvLyBjb21wdXRlIGJvdW5kaW5nIGJveGVzXG4gIGJvdW5kID0gc2NvcGUuYWRkKEJvdW5kJDEoe21hcms6IG1hcmtSZWYsIHB1bHNlOiBsYXlvdXRSZWYgfHwgZW5jb2RlUmVmfSkpO1xuICBib3VuZFJlZiA9IHJlZihib3VuZCk7XG5cbiAgLy8gaWYgZ3JvdXAgbWFyaywgcmVjdXJzZSB0byBwYXJzZSBuZXN0ZWQgY29udGVudFxuICBpZiAoZ3JvdXApIHtcbiAgICAvLyBqdWdnbGUgbGF5b3V0ICYgYm91bmRzIHRvIGVuc3VyZSB0aGV5IHJ1biAqYWZ0ZXIqIGFueSBmYWNldGluZyB0cmFuc2Zvcm1zXG4gICAgaWYgKG5lc3RlZCkgeyBvcHMgPSBzY29wZS5vcGVyYXRvcnM7IG9wcy5wb3AoKTsgaWYgKGxheW91dCkgb3BzLnBvcCgpOyB9XG5cbiAgICBzY29wZS5wdXNoU3RhdGUoZW5jb2RlUmVmLCBsYXlvdXRSZWYgfHwgYm91bmRSZWYsIGpvaW5SZWYpO1xuICAgIGZhY2V0ID8gcGFyc2VGYWNldChzcGVjLCBzY29wZSwgaW5wdXQpICAgICAgICAgIC8vIGV4cGxpY2l0IGZhY2V0XG4gICAgICAgIDogbmVzdGVkID8gcGFyc2VTdWJmbG93KHNwZWMsIHNjb3BlLCBpbnB1dCkgLy8gc3RhbmRhcmQgbWFyayBncm91cFxuICAgICAgICA6IHBhcnNlU3BlYyhzcGVjLCBzY29wZSk7IC8vIGd1aWRlIGdyb3VwLCB3ZSBjYW4gYXZvaWQgbmVzdGVkIHNjb3Blc1xuICAgIHNjb3BlLnBvcFN0YXRlKCk7XG5cbiAgICBpZiAobmVzdGVkKSB7IGlmIChsYXlvdXQpIG9wcy5wdXNoKGxheW91dCk7IG9wcy5wdXNoKGJvdW5kKTsgfVxuICB9XG5cbiAgaWYgKG92ZXJsYXApIHtcbiAgICBvcCA9IHtcbiAgICAgIG1ldGhvZDogb3ZlcmxhcC5tZXRob2QgPT09IHRydWUgPyAncGFyaXR5JyA6IG92ZXJsYXAubWV0aG9kLFxuICAgICAgcHVsc2U6ICBib3VuZFJlZlxuICAgIH07XG4gICAgaWYgKG92ZXJsYXAub3JkZXIpIHtcbiAgICAgIG9wLnNvcnQgPSBzY29wZS5jb21wYXJlUmVmKHtmaWVsZDogb3ZlcmxhcC5vcmRlcn0pO1xuICAgIH1cbiAgICBpZiAob3ZlcmxhcC5ib3VuZCkge1xuICAgICAgb3AuYm91bmRTY2FsZSA9IHNjb3BlLnNjYWxlUmVmKG92ZXJsYXAuYm91bmQuc2NhbGUpO1xuICAgICAgb3AuYm91bmRPcmllbnQgPSBvdmVybGFwLmJvdW5kLm9yaWVudDtcbiAgICAgIG9wLmJvdW5kVG9sZXJhbmNlID0gb3ZlcmxhcC5ib3VuZC50b2xlcmFuY2U7XG4gICAgfVxuICAgIGJvdW5kUmVmID0gcmVmKHNjb3BlLmFkZChPdmVybGFwJDEob3ApKSk7XG4gIH1cblxuICAvLyByZW5kZXIgLyBzaWV2ZSBpdGVtc1xuICByZW5kZXIgPSBzY29wZS5hZGQoUmVuZGVyJDEoe3B1bHNlOiBib3VuZFJlZn0pKTtcbiAgc2lldmUgPSBzY29wZS5hZGQoU2lldmUkMSh7cHVsc2U6IHJlZihyZW5kZXIpfSwgdW5kZWZpbmVkLCBzY29wZS5wYXJlbnQoKSkpO1xuXG4gIC8vIGlmIG1hcmsgaXMgbmFtZWQsIG1ha2UgYWNjZXNzaWJsZSBhcyByZWFjdGl2ZSBnZW9tZXRyeVxuICAvLyBhZGQgdHJpZ2dlciB1cGRhdGVzIGlmIGRlZmluZWRcbiAgaWYgKHNwZWMubmFtZSAhPSBudWxsKSB7XG4gICAgbmFtZSA9IHNwZWMubmFtZTtcbiAgICBzY29wZS5hZGREYXRhKG5hbWUsIG5ldyBEYXRhU2NvcGUoc2NvcGUsIHN0b3JlLCByZW5kZXIsIHNpZXZlKSk7XG4gICAgaWYgKHNwZWMub24pIHNwZWMub24uZm9yRWFjaChmdW5jdGlvbihvbikge1xuICAgICAgaWYgKG9uLmluc2VydCB8fCBvbi5yZW1vdmUgfHwgb24udG9nZ2xlKSB7XG4gICAgICAgIGVycm9yJDEoJ01hcmtzIG9ubHkgc3VwcG9ydCBtb2RpZnkgdHJpZ2dlcnMuJyk7XG4gICAgICB9XG4gICAgICBwYXJzZVRyaWdnZXIob24sIHNjb3BlLCBuYW1lKTtcbiAgICB9KTtcbiAgfVxufTtcblxudmFyIHBhcnNlTGVnZW5kID0gZnVuY3Rpb24oc3BlYywgc2NvcGUpIHtcbiAgdmFyIHR5cGUgPSBzcGVjLnR5cGUgfHwgJ3N5bWJvbCcsXG4gICAgICBjb25maWcgPSBzY29wZS5jb25maWcubGVnZW5kLFxuICAgICAgZW5jb2RlID0gc3BlYy5lbmNvZGUgfHwge30sXG4gICAgICBsZWdlbmRFbmNvZGUgPSBlbmNvZGUubGVnZW5kIHx8IHt9LFxuICAgICAgbmFtZSA9IGxlZ2VuZEVuY29kZS5uYW1lIHx8IHVuZGVmaW5lZCxcbiAgICAgIGludGVyYWN0aXZlID0gbGVnZW5kRW5jb2RlLmludGVyYWN0aXZlLFxuICAgICAgc3R5bGUgPSBsZWdlbmRFbmNvZGUuc3R5bGUsXG4gICAgICBkYXR1bSwgZGF0YVJlZiwgZW50cnlSZWYsIGdyb3VwLCB0aXRsZSxcbiAgICAgIGVudHJ5RW5jb2RlLCBwYXJhbXMsIGNoaWxkcmVuO1xuXG4gIC8vIHJlc29sdmUgJ2Nhbm9uaWNhbCcgc2NhbGUgbmFtZVxuICB2YXIgc2NhbGUgPSBzcGVjLnNpemUgfHwgc3BlYy5zaGFwZSB8fCBzcGVjLmZpbGwgfHwgc3BlYy5zdHJva2VcbiAgICAgICAgICAgfHwgc3BlYy5zdHJva2VEYXNoIHx8IHNwZWMub3BhY2l0eTtcblxuICBpZiAoIXNjYWxlKSB7XG4gICAgZXJyb3IkMSgnTWlzc2luZyB2YWxpZCBzY2FsZSBmb3IgbGVnZW5kLicpO1xuICB9XG5cbiAgLy8gc2luZ2xlLWVsZW1lbnQgZGF0YSBzb3VyY2UgZm9yIGF4aXMgZ3JvdXBcbiAgZGF0dW0gPSB7XG4gICAgb3JpZW50OiB2YWx1ZShzcGVjLm9yaWVudCwgY29uZmlnLm9yaWVudCksXG4gICAgdGl0bGU6ICBzcGVjLnRpdGxlICE9IG51bGxcbiAgfTtcbiAgZGF0YVJlZiA9IHJlZihzY29wZS5hZGQoQ29sbGVjdCQxKG51bGwsIFtkYXR1bV0pKSk7XG5cbiAgLy8gZW5jb2RpbmcgcHJvcGVydGllcyBmb3IgbGVnZW5kIGdyb3VwXG5cbiAgbGVnZW5kRW5jb2RlID0gZXh0ZW5kRW5jb2RlKHtcbiAgICBlbnRlcjogbGVnZW5kRW50ZXIoY29uZmlnKSxcbiAgICB1cGRhdGU6IHtcbiAgICAgIG9mZnNldDogICAgICAgIGVuY29kZXIodmFsdWUoc3BlYy5vZmZzZXQsIGNvbmZpZy5vZmZzZXQpKSxcbiAgICAgIHBhZGRpbmc6ICAgICAgIGVuY29kZXIodmFsdWUoc3BlYy5wYWRkaW5nLCBjb25maWcucGFkZGluZykpLFxuICAgICAgdGl0bGVQYWRkaW5nOiAgZW5jb2Rlcih2YWx1ZShzcGVjLnRpdGxlUGFkZGluZywgY29uZmlnLnRpdGxlUGFkZGluZykpXG4gICAgfVxuICB9LCBsZWdlbmRFbmNvZGUsIFNraXApO1xuXG4gIC8vIGVuY29kaW5nIHByb3BlcnRpZXMgZm9yIGxlZ2VuZCBlbnRyeSBzdWItZ3JvdXBcbiAgZW50cnlFbmNvZGUgPSB7XG4gICAgdXBkYXRlOiB7XG4gICAgICB4OiB7ZmllbGQ6IHtncm91cDogJ3BhZGRpbmcnfX0sXG4gICAgICB5OiB7ZmllbGQ6IHtncm91cDogJ3BhZGRpbmcnfX0sXG4gICAgICBlbnRyeVBhZGRpbmc6IGVuY29kZXIodmFsdWUoc3BlYy5lbnRyeVBhZGRpbmcsIGNvbmZpZy5lbnRyeVBhZGRpbmcpKVxuICAgIH1cbiAgfTtcblxuICBpZiAodHlwZSA9PT0gJ2dyYWRpZW50Jykge1xuICAgIC8vIGRhdGEgc291cmNlIGZvciBncmFkaWVudCBsYWJlbHNcbiAgICBlbnRyeVJlZiA9IHJlZihzY29wZS5hZGQoTGVnZW5kRW50cmllcyQxKHtcbiAgICAgIHR5cGU6ICAgJ2dyYWRpZW50JyxcbiAgICAgIHNjYWxlOiAgc2NvcGUuc2NhbGVSZWYoc2NhbGUpLFxuICAgICAgY291bnQ6ICBzY29wZS5vYmplY3RQcm9wZXJ0eShzcGVjLnRpY2tDb3VudCksXG4gICAgICB2YWx1ZXM6IHNjb3BlLm9iamVjdFByb3BlcnR5KHNwZWMudmFsdWVzKSxcbiAgICAgIGZvcm1hdFNwZWNpZmllcjogc2NvcGUucHJvcGVydHkoc3BlYy5mb3JtYXQpXG4gICAgfSkpKTtcblxuICAgIGNoaWxkcmVuID0gW1xuICAgICAgbGVnZW5kR3JhZGllbnQoc3BlYywgc2NhbGUsIGNvbmZpZywgZW5jb2RlLmdyYWRpZW50KSxcbiAgICAgIGxlZ2VuZEdyYWRpZW50TGFiZWxzKHNwZWMsIGNvbmZpZywgZW5jb2RlLmxhYmVscywgZW50cnlSZWYpXG4gICAgXTtcbiAgfVxuXG4gIGVsc2Uge1xuICAgIC8vIGRhdGEgc291cmNlIGZvciBsZWdlbmQgZW50cmllc1xuICAgIGVudHJ5UmVmID0gcmVmKHNjb3BlLmFkZChMZWdlbmRFbnRyaWVzJDEocGFyYW1zID0ge1xuICAgICAgc2NhbGU6ICBzY29wZS5zY2FsZVJlZihzY2FsZSksXG4gICAgICBjb3VudDogIHNjb3BlLm9iamVjdFByb3BlcnR5KHNwZWMudGlja0NvdW50KSxcbiAgICAgIHZhbHVlczogc2NvcGUub2JqZWN0UHJvcGVydHkoc3BlYy52YWx1ZXMpLFxuICAgICAgZm9ybWF0U3BlY2lmaWVyOiBzY29wZS5wcm9wZXJ0eShzcGVjLmZvcm1hdClcbiAgICB9KSkpO1xuXG4gICAgY2hpbGRyZW4gPSBbXG4gICAgICBsZWdlbmRTeW1ib2xzKHNwZWMsIGNvbmZpZywgZW5jb2RlLnN5bWJvbHMsIGVudHJ5UmVmKSxcbiAgICAgIGxlZ2VuZExhYmVscyhzcGVjLCBjb25maWcsIGVuY29kZS5sYWJlbHMsIGVudHJ5UmVmKVxuICAgIF07XG5cbiAgICBwYXJhbXMuc2l6ZSA9IHNpemVFeHByZXNzaW9uKHNwZWMsIHNjb3BlLCBjaGlsZHJlbik7XG4gIH1cblxuICAvLyBnZW5lcmF0ZSBsZWdlbmQgbWFya3NcbiAgY2hpbGRyZW4gPSBbXG4gICAgZ3VpZGVHcm91cChMZWdlbmRFbnRyeVJvbGUsIG51bGwsIG51bGwsIGRhdGFSZWYsIGludGVyYWN0aXZlLCBlbnRyeUVuY29kZSwgY2hpbGRyZW4pXG4gIF07XG5cbiAgLy8gaW5jbHVkZSBsZWdlbmQgdGl0bGUgaWYgZGVmaW5lZFxuICBpZiAoZGF0dW0udGl0bGUpIHtcbiAgICB0aXRsZSA9IGxlZ2VuZFRpdGxlKHNwZWMsIGNvbmZpZywgZW5jb2RlLnRpdGxlLCBkYXRhUmVmKTtcbiAgICBlbnRyeUVuY29kZS51cGRhdGUueS5vZmZzZXQgPSB7XG4gICAgICBmaWVsZDoge2dyb3VwOiAndGl0bGVQYWRkaW5nJ30sXG4gICAgICBvZmZzZXQ6IGdldFZhbHVlJDEoc2NvcGUsIHRpdGxlLmVuY29kZSwgJ2ZvbnRTaXplJywgR3VpZGVUaXRsZVN0eWxlKVxuICAgIH07XG4gICAgY2hpbGRyZW4ucHVzaCh0aXRsZSk7XG4gIH1cblxuICAvLyBidWlsZCBsZWdlbmQgc3BlY2lmaWNhdGlvblxuICBncm91cCA9IGd1aWRlR3JvdXAoTGVnZW5kUm9sZSQyLCBzdHlsZSwgbmFtZSwgZGF0YVJlZiwgaW50ZXJhY3RpdmUsIGxlZ2VuZEVuY29kZSwgY2hpbGRyZW4pO1xuICBpZiAoc3BlYy56aW5kZXgpIGdyb3VwLnppbmRleCA9IHNwZWMuemluZGV4O1xuXG4gIC8vIHBhcnNlIGxlZ2VuZCBzcGVjaWZpY2F0aW9uXG4gIHJldHVybiBwYXJzZU1hcmsoZ3JvdXAsIHNjb3BlKTtcbn07XG5cbmZ1bmN0aW9uIHNpemVFeHByZXNzaW9uKHNwZWMsIHNjb3BlLCBtYXJrcykge1xuICB2YXIgZm9udFNpemUgPSBnZXRWYWx1ZSQxKHNjb3BlLCBtYXJrc1sxXS5lbmNvZGUsICdmb250U2l6ZScsIEd1aWRlTGFiZWxTdHlsZSk7XG4gIGlmIChzcGVjLnNpemUpIHtcbiAgICByZXR1cm4geyRleHByOiAnTWF0aC5tYXgoTWF0aC5jZWlsKE1hdGguc3FydChfLnNjYWxlKGRhdHVtKSkpLCcgKyBmb250U2l6ZSArICcpJ307XG4gIH0gZWxzZSB7XG4gICAgdmFyIHN5bWJvbFNpemUgPSBnZXRWYWx1ZSQxKHNjb3BlLCBtYXJrc1swXS5lbmNvZGUsICdzaXplJyk7XG4gICAgcmV0dXJuIE1hdGgubWF4KE1hdGguY2VpbChNYXRoLnNxcnQoc3ltYm9sU2l6ZSkpLCBmb250U2l6ZSk7XG4gIH1cbn1cblxuZnVuY3Rpb24gbGVnZW5kRW50ZXIoY29uZmlnKSB7XG4gIHZhciBlbnRlciA9IHt9LFxuICAgICAgY291bnQgPSBhZGRFbmNvZGUoZW50ZXIsICdmaWxsJywgY29uZmlnLmZpbGxDb2xvcilcbiAgICAgICAgICAgICsgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlJywgY29uZmlnLnN0cm9rZUNvbG9yKVxuICAgICAgICAgICAgKyBhZGRFbmNvZGUoZW50ZXIsICdzdHJva2VXaWR0aCcsIGNvbmZpZy5zdHJva2VXaWR0aClcbiAgICAgICAgICAgICsgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlRGFzaCcsIGNvbmZpZy5zdHJva2VEYXNoKVxuICAgICAgICAgICAgKyBhZGRFbmNvZGUoZW50ZXIsICdjb3JuZXJSYWRpdXMnLCBjb25maWcuY29ybmVyUmFkaXVzKTtcbiAgcmV0dXJuIGNvdW50ID8gZW50ZXIgOiB1bmRlZmluZWQ7XG59XG5cbmZ1bmN0aW9uIGdldFZhbHVlJDEoc2NvcGUsIGVuY29kZSwgbmFtZSwgc3R5bGUpIHtcbiAgdmFyIHYgPSBlbmNvZGUgJiYgKFxuICAgIChlbmNvZGUudXBkYXRlICYmIGVuY29kZS51cGRhdGVbbmFtZV0pIHx8XG4gICAgKGVuY29kZS5lbnRlciAmJiBlbmNvZGUuZW50ZXJbbmFtZV0pXG4gICk7XG4gIHJldHVybiArKHYgPyB2LnZhbHVlIC8vIFRPRE8gc3VwcG9ydCBzaWduYWw/XG4gICAgOiAoc3R5bGUgJiYgKHYgPSBzY29wZS5jb25maWcuc3R5bGVbc3R5bGVdKSAmJiB2W25hbWVdKSk7XG59XG5cbnZhciBwYXJzZVRpdGxlID0gZnVuY3Rpb24oc3BlYywgc2NvcGUpIHtcbiAgc3BlYyA9IGlzU3RyaW5nKHNwZWMpID8ge3RleHQ6IHNwZWN9IDogc3BlYztcblxuICB2YXIgY29uZmlnID0gc2NvcGUuY29uZmlnLnRpdGxlLFxuICAgICAgZW5jb2RlID0gZXh0ZW5kKHt9LCBzcGVjLmVuY29kZSksXG4gICAgICBkYXR1bSwgZGF0YVJlZiwgdGl0bGU7XG5cbiAgLy8gc2luZ2xlLWVsZW1lbnQgZGF0YSBzb3VyY2UgZm9yIGdyb3VwIHRpdGxlXG4gIGRhdHVtID0ge1xuICAgIG9yaWVudDogc3BlYy5vcmllbnQgIT0gbnVsbCA/IHNwZWMub3JpZW50IDogY29uZmlnLm9yaWVudFxuICB9O1xuICBkYXRhUmVmID0gcmVmKHNjb3BlLmFkZChDb2xsZWN0JDEobnVsbCwgW2RhdHVtXSkpKTtcblxuICAvLyBidWlsZCB0aXRsZSBzcGVjaWZpY2F0aW9uXG4gIGVuY29kZS5uYW1lID0gc3BlYy5uYW1lO1xuICBlbmNvZGUuaW50ZXJhY3RpdmUgPSBzcGVjLmludGVyYWN0aXZlO1xuICB0aXRsZSA9IGJ1aWxkVGl0bGUoc3BlYywgY29uZmlnLCBlbmNvZGUsIGRhdGFSZWYpO1xuICBpZiAoc3BlYy56aW5kZXgpIHRpdGxlLnppbmRleCA9IHNwZWMuemluZGV4O1xuXG4gIC8vIHBhcnNlIHRpdGxlIHNwZWNpZmljYXRpb25cbiAgcmV0dXJuIHBhcnNlTWFyayh0aXRsZSwgc2NvcGUpO1xufTtcblxuZnVuY3Rpb24gYnVpbGRUaXRsZShzcGVjLCBjb25maWcsIHVzZXJFbmNvZGUsIGRhdGFSZWYpIHtcbiAgdmFyIHRpdGxlID0gc3BlYy50ZXh0LFxuICAgICAgb3JpZW50ID0gc3BlYy5vcmllbnQgfHwgY29uZmlnLm9yaWVudCxcbiAgICAgIGFuY2hvciA9IHNwZWMuYW5jaG9yIHx8IGNvbmZpZy5hbmNob3IsXG4gICAgICBzaWduID0gKG9yaWVudCA9PT0gTGVmdCQxIHx8IG9yaWVudCA9PT0gVG9wJDEpID8gLTEgOiAxLFxuICAgICAgaG9yaXpvbnRhbCA9IChvcmllbnQgPT09IFRvcCQxIHx8IG9yaWVudCA9PT0gQm90dG9tJDEpLFxuICAgICAgZXh0ZW50ID0ge2dyb3VwOiAoaG9yaXpvbnRhbCA/ICd3aWR0aCcgOiAnaGVpZ2h0Jyl9LFxuICAgICAgZW5jb2RlID0ge30sIGVudGVyLCB1cGRhdGUsIHBvcywgb3BwLCBtdWx0LCBhbGlnbjtcblxuICBlbmNvZGUuZW50ZXIgPSBlbnRlciA9IHtcbiAgICBvcGFjaXR5OiB7dmFsdWU6IDB9XG4gIH07XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZpbGwnLCBjb25maWcuY29sb3IpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdmb250JywgY29uZmlnLmZvbnQpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdmb250U2l6ZScsIGNvbmZpZy5mb250U2l6ZSk7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnRXZWlnaHQnLCBjb25maWcuZm9udFdlaWdodCk7XG5cbiAgZW5jb2RlLmV4aXQgPSB7XG4gICAgb3BhY2l0eToge3ZhbHVlOiAwfVxuICB9O1xuXG4gIGVuY29kZS51cGRhdGUgPSB1cGRhdGUgPSB7XG4gICAgb3BhY2l0eToge3ZhbHVlOiAxfSxcbiAgICB0ZXh0OiBpc09iamVjdCh0aXRsZSkgPyB0aXRsZSA6IHt2YWx1ZTogdGl0bGUgKyAnJ30sXG4gICAgb2Zmc2V0OiBlbmNvZGVyKChzcGVjLm9mZnNldCAhPSBudWxsID8gc3BlYy5vZmZzZXQgOiBjb25maWcub2Zmc2V0KSB8fCAwKVxuICB9O1xuXG4gIGlmIChhbmNob3IgPT09ICdzdGFydCcpIHtcbiAgICBtdWx0ID0gMDtcbiAgICBhbGlnbiA9ICdsZWZ0JztcbiAgfSBlbHNlIHtcbiAgICBpZiAoYW5jaG9yID09PSAnZW5kJykge1xuICAgICAgbXVsdCA9IDE7XG4gICAgICBhbGlnbiA9ICdyaWdodCc7XG4gICAgfSBlbHNlIHtcbiAgICAgIG11bHQgPSAwLjU7XG4gICAgICBhbGlnbiA9ICdjZW50ZXInO1xuICAgIH1cbiAgfVxuXG4gIHBvcyA9IHtmaWVsZDogZXh0ZW50LCBtdWx0OiBtdWx0fTtcblxuICBvcHAgPSBzaWduIDwgMCA/IHt2YWx1ZTogMH1cbiAgICA6IGhvcml6b250YWwgPyB7ZmllbGQ6IHtncm91cDogJ2hlaWdodCd9fVxuICAgIDoge2ZpZWxkOiB7Z3JvdXA6ICd3aWR0aCd9fTtcblxuICBpZiAoaG9yaXpvbnRhbCkge1xuICAgIHVwZGF0ZS54ID0gcG9zO1xuICAgIHVwZGF0ZS55ID0gb3BwO1xuICAgIHVwZGF0ZS5hbmdsZSA9IHt2YWx1ZTogMH07XG4gICAgdXBkYXRlLmJhc2VsaW5lID0ge3ZhbHVlOiBvcmllbnQgPT09IFRvcCQxID8gJ2JvdHRvbScgOiAndG9wJ307XG4gIH0gZWxzZSB7XG4gICAgdXBkYXRlLnggPSBvcHA7XG4gICAgdXBkYXRlLnkgPSBwb3M7XG4gICAgdXBkYXRlLmFuZ2xlID0ge3ZhbHVlOiBzaWduICogOTB9O1xuICAgIHVwZGF0ZS5iYXNlbGluZSA9IHt2YWx1ZTogJ2JvdHRvbSd9O1xuICB9XG4gIHVwZGF0ZS5hbGlnbiA9IHt2YWx1ZTogYWxpZ259O1xuICB1cGRhdGUubGltaXQgPSB7ZmllbGQ6IGV4dGVudH07XG5cbiAgYWRkRW5jb2RlKHVwZGF0ZSwgJ2FuZ2xlJywgY29uZmlnLmFuZ2xlKTtcbiAgYWRkRW5jb2RlKHVwZGF0ZSwgJ2Jhc2VsaW5lJywgY29uZmlnLmJhc2VsaW5lKTtcbiAgYWRkRW5jb2RlKHVwZGF0ZSwgJ2xpbWl0JywgY29uZmlnLmxpbWl0KTtcblxuICByZXR1cm4gZ3VpZGVNYXJrKFRleHRNYXJrLCBUaXRsZVJvbGUkMSwgc3BlYy5zdHlsZSB8fCBHcm91cFRpdGxlU3R5bGUsIG51bGwsIGRhdGFSZWYsIGVuY29kZSwgdXNlckVuY29kZSk7XG59XG5cbmZ1bmN0aW9uIHBhcnNlRGF0YSQxKGRhdGEsIHNjb3BlKSB7XG4gIHZhciB0cmFuc2Zvcm1zID0gW107XG5cbiAgaWYgKGRhdGEudHJhbnNmb3JtKSB7XG4gICAgZGF0YS50cmFuc2Zvcm0uZm9yRWFjaChmdW5jdGlvbih0eCkge1xuICAgICAgdHJhbnNmb3Jtcy5wdXNoKHBhcnNlVHJhbnNmb3JtKHR4LCBzY29wZSkpO1xuICAgIH0pO1xuICB9XG5cbiAgaWYgKGRhdGEub24pIHtcbiAgICBkYXRhLm9uLmZvckVhY2goZnVuY3Rpb24ob24pIHtcbiAgICAgIHBhcnNlVHJpZ2dlcihvbiwgc2NvcGUsIGRhdGEubmFtZSk7XG4gICAgfSk7XG4gIH1cblxuICBzY29wZS5hZGREYXRhUGlwZWxpbmUoZGF0YS5uYW1lLCBhbmFseXplKGRhdGEsIHNjb3BlLCB0cmFuc2Zvcm1zKSk7XG59XG5cbi8qKlxuICogQW5hbHl6ZSBhIGRhdGEgcGlwZWxpbmUsIGFkZCBuZWVkZWQgb3BlcmF0b3JzLlxuICovXG5mdW5jdGlvbiBhbmFseXplKGRhdGEsIHNjb3BlLCBvcHMpIHtcbiAgLy8gUE9TU0lCTEUgVE9ET3M6XG4gIC8vIC0gZXJyb3IgY2hlY2tpbmcgZm9yIHRyZWVzb3VyY2Ugb24gdHJlZSBvcGVyYXRvcnMgKEJVVCB3aGF0IGlmIHRyZWUgaXMgdXBzdHJlYW0/KVxuICAvLyAtIHRoaXMgaXMgbG9jYWwgYW5hbHlzaXMsIHBlcmhhcHMgc29tZSB0YXNrcyBiZXR0ZXIgZm9yIGdsb2JhbCBhbmFseXNpcy4uLlxuXG4gIHZhciBvdXRwdXQgPSBbXSxcbiAgICAgIHNvdXJjZSA9IG51bGwsXG4gICAgICBtb2RpZnkgPSBmYWxzZSxcbiAgICAgIGdlbmVyYXRlID0gZmFsc2UsXG4gICAgICB1cHN0cmVhbSwgaSwgbiwgdCwgbTtcblxuICBpZiAoZGF0YS52YWx1ZXMpIHtcbiAgICAvLyBoYXJkLXdpcmVkIGlucHV0IGRhdGEgc2V0XG4gICAgb3V0cHV0LnB1c2goc291cmNlID0gY29sbGVjdCh7JGluZ2VzdDogZGF0YS52YWx1ZXMsICRmb3JtYXQ6IGRhdGEuZm9ybWF0fSkpO1xuICB9IGVsc2UgaWYgKGRhdGEudXJsKSB7XG4gICAgLy8gbG9hZCBkYXRhIGZyb20gZXh0ZXJuYWwgc291cmNlXG4gICAgb3V0cHV0LnB1c2goc291cmNlID0gY29sbGVjdCh7JHJlcXVlc3Q6IGRhdGEudXJsLCAkZm9ybWF0OiBkYXRhLmZvcm1hdH0pKTtcbiAgfSBlbHNlIGlmIChkYXRhLnNvdXJjZSkge1xuICAgIC8vIGRlcml2ZXMgZnJvbSBvbmUgb3IgbW9yZSBvdGhlciBkYXRhIHNldHNcbiAgICBzb3VyY2UgPSB1cHN0cmVhbSA9IGFycmF5KGRhdGEuc291cmNlKS5tYXAoZnVuY3Rpb24oZCkge1xuICAgICAgcmV0dXJuIHJlZihzY29wZS5nZXREYXRhKGQpLm91dHB1dCk7XG4gICAgfSk7XG4gICAgb3V0cHV0LnB1c2gobnVsbCk7IC8vIHBvcHVsYXRlIGxhdGVyXG4gIH1cblxuICAvLyBzY2FuIGRhdGEgdHJhbnNmb3JtcywgYWRkIGNvbGxlY3RvcnMgYXMgbmVlZGVkXG4gIGZvciAoaT0wLCBuPW9wcy5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdCA9IG9wc1tpXTtcbiAgICBtID0gdC5tZXRhZGF0YTtcblxuICAgIGlmICghc291cmNlICYmICFtLnNvdXJjZSkge1xuICAgICAgb3V0cHV0LnB1c2goc291cmNlID0gY29sbGVjdCgpKTtcbiAgICB9XG4gICAgb3V0cHV0LnB1c2godCk7XG5cbiAgICBpZiAobS5nZW5lcmF0ZXMpIGdlbmVyYXRlID0gdHJ1ZTtcbiAgICBpZiAobS5tb2RpZmllcyAmJiAhZ2VuZXJhdGUpIG1vZGlmeSA9IHRydWU7XG5cbiAgICBpZiAobS5zb3VyY2UpIHNvdXJjZSA9IHQ7XG4gICAgZWxzZSBpZiAobS5jaGFuZ2VzKSBzb3VyY2UgPSBudWxsO1xuICB9XG5cbiAgaWYgKHVwc3RyZWFtKSB7XG4gICAgbiA9IHVwc3RyZWFtLmxlbmd0aCAtIDE7XG4gICAgb3V0cHV0WzBdID0gUmVsYXkkMSh7XG4gICAgICBkZXJpdmU6IG1vZGlmeSxcbiAgICAgIHB1bHNlOiBuID8gdXBzdHJlYW0gOiB1cHN0cmVhbVswXVxuICAgIH0pO1xuICAgIGlmIChtb2RpZnkgfHwgbikge1xuICAgICAgLy8gY29sbGVjdCBkZXJpdmVkIGFuZCBtdWx0aS1wdWxzZSB0dXBsZXNcbiAgICAgIG91dHB1dC5zcGxpY2UoMSwgMCwgY29sbGVjdCgpKTtcbiAgICB9XG4gIH1cblxuICBpZiAoIXNvdXJjZSkgb3V0cHV0LnB1c2goY29sbGVjdCgpKTtcbiAgb3V0cHV0LnB1c2goU2lldmUkMSh7fSkpO1xuICByZXR1cm4gb3V0cHV0O1xufVxuXG5mdW5jdGlvbiBjb2xsZWN0KHZhbHVlcykge1xuICB2YXIgcyA9IENvbGxlY3QkMSh7fSwgdmFsdWVzKTtcbiAgcy5tZXRhZGF0YSA9IHtzb3VyY2U6IHRydWV9O1xuICByZXR1cm4gcztcbn1cblxudmFyIGF4aXNDb25maWcgPSBmdW5jdGlvbihzcGVjLCBzY29wZSkge1xuICB2YXIgY29uZmlnID0gc2NvcGUuY29uZmlnLFxuICAgICAgb3JpZW50ID0gc3BlYy5vcmllbnQsXG4gICAgICB4eSA9IChvcmllbnQgPT09IFRvcCQxIHx8IG9yaWVudCA9PT0gQm90dG9tJDEpID8gY29uZmlnLmF4aXNYIDogY29uZmlnLmF4aXNZLFxuICAgICAgb3IgPSBjb25maWdbJ2F4aXMnICsgb3JpZW50WzBdLnRvVXBwZXJDYXNlKCkgKyBvcmllbnQuc2xpY2UoMSldLFxuICAgICAgYmFuZCA9IHNjb3BlLnNjYWxlVHlwZShzcGVjLnNjYWxlKSA9PT0gJ2JhbmQnICYmIGNvbmZpZy5heGlzQmFuZDtcblxuICByZXR1cm4gKHh5IHx8IG9yIHx8IGJhbmQpXG4gICAgPyBleHRlbmQoe30sIGNvbmZpZy5heGlzLCB4eSwgb3IsIGJhbmQpXG4gICAgOiBjb25maWcuYXhpcztcbn07XG5cbnZhciBheGlzRG9tYWluID0gZnVuY3Rpb24oc3BlYywgY29uZmlnLCB1c2VyRW5jb2RlLCBkYXRhUmVmKSB7XG4gIHZhciBvcmllbnQgPSBzcGVjLm9yaWVudCxcbiAgICAgIHplcm8gPSB7dmFsdWU6IDB9LFxuICAgICAgZW5jb2RlID0ge30sIGVudGVyLCB1cGRhdGUsIHUsIHUyLCB2O1xuXG4gIGVuY29kZS5lbnRlciA9IGVudGVyID0ge1xuICAgIG9wYWNpdHk6IHplcm9cbiAgfTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlJywgY29uZmlnLmRvbWFpbkNvbG9yKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlV2lkdGgnLCBjb25maWcuZG9tYWluV2lkdGgpO1xuXG4gIGVuY29kZS5leGl0ID0ge1xuICAgIG9wYWNpdHk6IHplcm9cbiAgfTtcblxuICBlbmNvZGUudXBkYXRlID0gdXBkYXRlID0ge1xuICAgIG9wYWNpdHk6IHt2YWx1ZTogMX1cbiAgfTtcblxuICBpZiAob3JpZW50ID09PSBUb3AkMSB8fCBvcmllbnQgPT09IEJvdHRvbSQxKSB7XG4gICAgdSA9ICd4JztcbiAgICB2ID0gJ3knO1xuICB9IGVsc2Uge1xuICAgIHUgPSAneSc7XG4gICAgdiA9ICd4JztcbiAgfVxuICB1MiA9IHUgKyAnMic7XG5cbiAgZW50ZXJbdl0gPSB6ZXJvO1xuICB1cGRhdGVbdV0gPSBlbnRlclt1XSA9IHBvc2l0aW9uKHNwZWMsIDApO1xuICB1cGRhdGVbdTJdID0gZW50ZXJbdTJdID0gcG9zaXRpb24oc3BlYywgMSk7XG5cbiAgcmV0dXJuIGd1aWRlTWFyayhSdWxlTWFyaywgQXhpc0RvbWFpblJvbGUsIG51bGwsIG51bGwsIGRhdGFSZWYsIGVuY29kZSwgdXNlckVuY29kZSk7XG59O1xuXG5mdW5jdGlvbiBwb3NpdGlvbihzcGVjLCBwb3MpIHtcbiAgcmV0dXJuIHtzY2FsZTogc3BlYy5zY2FsZSwgcmFuZ2U6IHBvc307XG59XG5cbnZhciBheGlzR3JpZCA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZywgdXNlckVuY29kZSwgZGF0YVJlZikge1xuICB2YXIgb3JpZW50ID0gc3BlYy5vcmllbnQsXG4gICAgICB2c2NhbGUgPSBzcGVjLmdyaWRTY2FsZSxcbiAgICAgIHNpZ24gPSAob3JpZW50ID09PSBMZWZ0JDEgfHwgb3JpZW50ID09PSBUb3AkMSkgPyAxIDogLTEsXG4gICAgICBvZmZzZXQgPSBzaWduICogc3BlYy5vZmZzZXQgfHwgMCxcbiAgICAgIHplcm8gPSB7dmFsdWU6IDB9LFxuICAgICAgZW5jb2RlID0ge30sIGVudGVyLCBleGl0LCB1cGRhdGUsIHRpY2tQb3MsIHUsIHYsIHYyLCBzO1xuXG4gIGVuY29kZS5lbnRlciA9IGVudGVyID0ge1xuICAgIG9wYWNpdHk6IHplcm9cbiAgfTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlJywgY29uZmlnLmdyaWRDb2xvcik7XG4gIGFkZEVuY29kZShlbnRlciwgJ3N0cm9rZVdpZHRoJywgY29uZmlnLmdyaWRXaWR0aCk7XG4gIGFkZEVuY29kZShlbnRlciwgJ3N0cm9rZURhc2gnLCBjb25maWcuZ3JpZERhc2gpO1xuXG4gIGVuY29kZS5leGl0ID0gZXhpdCA9IHtcbiAgICBvcGFjaXR5OiB6ZXJvXG4gIH07XG5cbiAgZW5jb2RlLnVwZGF0ZSA9IHVwZGF0ZSA9IHt9O1xuICBhZGRFbmNvZGUodXBkYXRlLCAnb3BhY2l0eScsIGNvbmZpZy5ncmlkT3BhY2l0eSk7XG5cbiAgdGlja1BvcyA9IHtcbiAgICBzY2FsZTogIHNwZWMuc2NhbGUsXG4gICAgZmllbGQ6ICBWYWx1ZSxcbiAgICBiYW5kOiAgIGNvbmZpZy5iYW5kUG9zaXRpb24sXG4gICAgcm91bmQ6ICBjb25maWcudGlja1JvdW5kLFxuICAgIGV4dHJhOiAgY29uZmlnLnRpY2tFeHRyYSxcbiAgICBvZmZzZXQ6IGNvbmZpZy50aWNrT2Zmc2V0XG4gIH07XG5cbiAgaWYgKG9yaWVudCA9PT0gVG9wJDEgfHwgb3JpZW50ID09PSBCb3R0b20kMSkge1xuICAgIHUgPSAneCc7XG4gICAgdiA9ICd5JztcbiAgICBzID0gJ2hlaWdodCc7XG4gIH0gZWxzZSB7XG4gICAgdSA9ICd5JztcbiAgICB2ID0gJ3gnO1xuICAgIHMgPSAnd2lkdGgnO1xuICB9XG4gIHYyID0gdiArICcyJztcblxuICB1cGRhdGVbdV0gPSBlbnRlclt1XSA9IGV4aXRbdV0gPSB0aWNrUG9zO1xuXG4gIGlmICh2c2NhbGUpIHtcbiAgICBlbnRlclt2XSA9IHtzY2FsZTogdnNjYWxlLCByYW5nZTogMCwgbXVsdDogc2lnbiwgb2Zmc2V0OiBvZmZzZXR9O1xuICAgIHVwZGF0ZVt2Ml0gPSBlbnRlclt2Ml0gPSB7c2NhbGU6IHZzY2FsZSwgcmFuZ2U6IDEsIG11bHQ6IHNpZ24sIG9mZnNldDogb2Zmc2V0fTtcbiAgfSBlbHNlIHtcbiAgICBlbnRlclt2XSA9IHt2YWx1ZTogb2Zmc2V0fTtcbiAgICB1cGRhdGVbdjJdID0gZW50ZXJbdjJdID0ge3NpZ25hbDogcywgbXVsdDogc2lnbiwgb2Zmc2V0OiBvZmZzZXR9O1xuICB9XG5cbiAgcmV0dXJuIGd1aWRlTWFyayhSdWxlTWFyaywgQXhpc0dyaWRSb2xlLCBudWxsLCBWYWx1ZSwgZGF0YVJlZiwgZW5jb2RlLCB1c2VyRW5jb2RlKTtcbn07XG5cbnZhciBheGlzVGlja3MgPSBmdW5jdGlvbihzcGVjLCBjb25maWcsIHVzZXJFbmNvZGUsIGRhdGFSZWYsIHNpemUpIHtcbiAgdmFyIG9yaWVudCA9IHNwZWMub3JpZW50LFxuICAgICAgc2lnbiA9IChvcmllbnQgPT09IExlZnQkMSB8fCBvcmllbnQgPT09IFRvcCQxKSA/IC0xIDogMSxcbiAgICAgIHplcm8gPSB7dmFsdWU6IDB9LFxuICAgICAgZW5jb2RlID0ge30sIGVudGVyLCBleGl0LCB1cGRhdGUsIHRpY2tTaXplLCB0aWNrUG9zO1xuXG4gIGVuY29kZS5lbnRlciA9IGVudGVyID0ge1xuICAgIG9wYWNpdHk6IHplcm9cbiAgfTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnc3Ryb2tlJywgY29uZmlnLnRpY2tDb2xvcik7XG4gIGFkZEVuY29kZShlbnRlciwgJ3N0cm9rZVdpZHRoJywgY29uZmlnLnRpY2tXaWR0aCk7XG5cbiAgZW5jb2RlLmV4aXQgPSBleGl0ID0ge1xuICAgIG9wYWNpdHk6IHplcm9cbiAgfTtcblxuICBlbmNvZGUudXBkYXRlID0gdXBkYXRlID0ge1xuICAgIG9wYWNpdHk6IHt2YWx1ZTogMX1cbiAgfTtcblxuICB0aWNrU2l6ZSA9IGVuY29kZXIoc2l6ZSk7XG4gIHRpY2tTaXplLm11bHQgPSBzaWduO1xuXG4gIHRpY2tQb3MgPSB7XG4gICAgc2NhbGU6ICBzcGVjLnNjYWxlLFxuICAgIGZpZWxkOiAgVmFsdWUsXG4gICAgYmFuZDogICBjb25maWcuYmFuZFBvc2l0aW9uLFxuICAgIHJvdW5kOiAgY29uZmlnLnRpY2tSb3VuZCxcbiAgICBleHRyYTogIGNvbmZpZy50aWNrRXh0cmEsXG4gICAgb2Zmc2V0OiBjb25maWcudGlja09mZnNldFxuICB9O1xuXG4gIGlmIChvcmllbnQgPT09IFRvcCQxIHx8IG9yaWVudCA9PT0gQm90dG9tJDEpIHtcbiAgICB1cGRhdGUueSA9IGVudGVyLnkgPSB6ZXJvO1xuICAgIHVwZGF0ZS55MiA9IGVudGVyLnkyID0gdGlja1NpemU7XG4gICAgdXBkYXRlLnggPSBlbnRlci54ID0gZXhpdC54ID0gdGlja1BvcztcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGUueCA9IGVudGVyLnggPSB6ZXJvO1xuICAgIHVwZGF0ZS54MiA9IGVudGVyLngyID0gdGlja1NpemU7XG4gICAgdXBkYXRlLnkgPSBlbnRlci55ID0gZXhpdC55ID0gdGlja1BvcztcbiAgfVxuXG4gIHJldHVybiBndWlkZU1hcmsoUnVsZU1hcmssIEF4aXNUaWNrUm9sZSwgbnVsbCwgVmFsdWUsIGRhdGFSZWYsIGVuY29kZSwgdXNlckVuY29kZSk7XG59O1xuXG5mdW5jdGlvbiBmbHVzaEV4cHIoc2NhbGUsIHRocmVzaG9sZCwgYSwgYiwgYykge1xuICByZXR1cm4ge1xuICAgIHNpZ25hbDogJ2ZsdXNoKHJhbmdlKFwiJyArIHNjYWxlICsgJ1wiKSwgJ1xuICAgICAgKyAnc2NhbGUoXCInICsgc2NhbGUgKyAnXCIsIGRhdHVtLnZhbHVlKSwgJ1xuICAgICAgKyB0aHJlc2hvbGQgKyAnLCcgKyBhICsgJywnICsgYiArICcsJyArIGMgKyAnKSdcbiAgfTtcbn1cblxudmFyIGF4aXNMYWJlbHMgPSBmdW5jdGlvbihzcGVjLCBjb25maWcsIHVzZXJFbmNvZGUsIGRhdGFSZWYsIHNpemUpIHtcbiAgdmFyIG9yaWVudCA9IHNwZWMub3JpZW50LFxuICAgICAgc2lnbiA9IChvcmllbnQgPT09IExlZnQkMSB8fCBvcmllbnQgPT09IFRvcCQxKSA/IC0xIDogMSxcbiAgICAgIHNjYWxlID0gc3BlYy5zY2FsZSxcbiAgICAgIHBhZCA9IHZhbHVlKHNwZWMubGFiZWxQYWRkaW5nLCBjb25maWcubGFiZWxQYWRkaW5nKSxcbiAgICAgIGJvdW5kID0gdmFsdWUoc3BlYy5sYWJlbEJvdW5kLCBjb25maWcubGFiZWxCb3VuZCksXG4gICAgICBmbHVzaCA9IHZhbHVlKHNwZWMubGFiZWxGbHVzaCwgY29uZmlnLmxhYmVsRmx1c2gpLFxuICAgICAgZmx1c2hPbiA9IGZsdXNoICE9IG51bGwgJiYgZmx1c2ggIT09IGZhbHNlICYmIChmbHVzaCA9ICtmbHVzaCkgPT09IGZsdXNoLFxuICAgICAgZmx1c2hPZmZzZXQgPSArdmFsdWUoc3BlYy5sYWJlbEZsdXNoT2Zmc2V0LCBjb25maWcubGFiZWxGbHVzaE9mZnNldCksXG4gICAgICBvdmVybGFwID0gdmFsdWUoc3BlYy5sYWJlbE92ZXJsYXAsIGNvbmZpZy5sYWJlbE92ZXJsYXApLFxuICAgICAgemVybyA9IHt2YWx1ZTogMH0sXG4gICAgICBlbmNvZGUgPSB7fSwgZW50ZXIsIGV4aXQsIHVwZGF0ZSwgdGlja1NpemUsIHRpY2tQb3M7XG5cbiAgZW5jb2RlLmVudGVyID0gZW50ZXIgPSB7XG4gICAgb3BhY2l0eTogemVyb1xuICB9O1xuICBhZGRFbmNvZGUoZW50ZXIsICdhbmdsZScsIGNvbmZpZy5sYWJlbEFuZ2xlKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZmlsbCcsIGNvbmZpZy5sYWJlbENvbG9yKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udCcsIGNvbmZpZy5sYWJlbEZvbnQpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdmb250U2l6ZScsIGNvbmZpZy5sYWJlbEZvbnRTaXplKTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udFdlaWdodCcsIGNvbmZpZy5sYWJlbEZvbnRXZWlnaHQpO1xuICBhZGRFbmNvZGUoZW50ZXIsICdsaW1pdCcsIGNvbmZpZy5sYWJlbExpbWl0KTtcblxuICBlbmNvZGUuZXhpdCA9IGV4aXQgPSB7XG4gICAgb3BhY2l0eTogemVyb1xuICB9O1xuXG4gIGVuY29kZS51cGRhdGUgPSB1cGRhdGUgPSB7XG4gICAgb3BhY2l0eToge3ZhbHVlOiAxfSxcbiAgICB0ZXh0OiB7ZmllbGQ6IExhYmVsfVxuICB9O1xuXG4gIHRpY2tTaXplID0gZW5jb2RlcihzaXplKTtcbiAgdGlja1NpemUubXVsdCA9IHNpZ247XG4gIHRpY2tTaXplLm9mZnNldCA9IGVuY29kZXIocGFkKTtcbiAgdGlja1NpemUub2Zmc2V0Lm11bHQgPSBzaWduO1xuXG4gIHRpY2tQb3MgPSB7XG4gICAgc2NhbGU6ICBzY2FsZSxcbiAgICBmaWVsZDogIFZhbHVlLFxuICAgIGJhbmQ6ICAgMC41LFxuICAgIG9mZnNldDogY29uZmlnLnRpY2tPZmZzZXRcbiAgfTtcblxuICBpZiAob3JpZW50ID09PSBUb3AkMSB8fCBvcmllbnQgPT09IEJvdHRvbSQxKSB7XG4gICAgdXBkYXRlLnkgPSBlbnRlci55ID0gdGlja1NpemU7XG4gICAgdXBkYXRlLnggPSBlbnRlci54ID0gZXhpdC54ID0gdGlja1BvcztcbiAgICBhZGRFbmNvZGUodXBkYXRlLCAnYWxpZ24nLCBmbHVzaE9uXG4gICAgICA/IGZsdXNoRXhwcihzY2FsZSwgZmx1c2gsICdcImxlZnRcIicsICdcInJpZ2h0XCInLCAnXCJjZW50ZXJcIicpXG4gICAgICA6ICdjZW50ZXInKTtcbiAgICBpZiAoZmx1c2hPbiAmJiBmbHVzaE9mZnNldCkge1xuICAgICAgYWRkRW5jb2RlKHVwZGF0ZSwgJ2R4JywgZmx1c2hFeHByKHNjYWxlLCBmbHVzaCwgLWZsdXNoT2Zmc2V0LCBmbHVzaE9mZnNldCwgMCkpO1xuICAgIH1cblxuICAgIGFkZEVuY29kZSh1cGRhdGUsICdiYXNlbGluZScsIG9yaWVudCA9PT0gVG9wJDEgPyAnYm90dG9tJyA6ICd0b3AnKTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGUueCA9IGVudGVyLnggPSB0aWNrU2l6ZTtcbiAgICB1cGRhdGUueSA9IGVudGVyLnkgPSBleGl0LnkgPSB0aWNrUG9zO1xuICAgIGFkZEVuY29kZSh1cGRhdGUsICdhbGlnbicsIG9yaWVudCA9PT0gUmlnaHQkMSA/ICdsZWZ0JyA6ICdyaWdodCcpO1xuICAgIGFkZEVuY29kZSh1cGRhdGUsICdiYXNlbGluZScsIGZsdXNoT25cbiAgICAgID8gZmx1c2hFeHByKHNjYWxlLCBmbHVzaCwgJ1wiYm90dG9tXCInLCAnXCJ0b3BcIicsICdcIm1pZGRsZVwiJylcbiAgICAgIDogJ21pZGRsZScpO1xuICAgIGlmIChmbHVzaE9uICYmIGZsdXNoT2Zmc2V0KSB7XG4gICAgICBhZGRFbmNvZGUodXBkYXRlLCAnZHknLCBmbHVzaEV4cHIoc2NhbGUsIGZsdXNoLCBmbHVzaE9mZnNldCwgLWZsdXNoT2Zmc2V0LCAwKSk7XG4gICAgfVxuICB9XG5cbiAgc3BlYyA9IGd1aWRlTWFyayhUZXh0TWFyaywgQXhpc0xhYmVsUm9sZSwgR3VpZGVMYWJlbFN0eWxlLCBWYWx1ZSwgZGF0YVJlZiwgZW5jb2RlLCB1c2VyRW5jb2RlKTtcbiAgaWYgKG92ZXJsYXAgfHwgYm91bmQpIHtcbiAgICBzcGVjLm92ZXJsYXAgPSB7XG4gICAgICBtZXRob2Q6IG92ZXJsYXAsXG4gICAgICBvcmRlcjogICdkYXR1bS5pbmRleCcsXG4gICAgICBib3VuZDogIGJvdW5kID8ge3NjYWxlOiBzY2FsZSwgb3JpZW50OiBvcmllbnQsIHRvbGVyYW5jZTogK2JvdW5kfSA6IG51bGxcbiAgICB9O1xuICB9XG4gIHJldHVybiBzcGVjO1xufTtcblxudmFyIGF4aXNUaXRsZSA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZywgdXNlckVuY29kZSwgZGF0YVJlZikge1xuICB2YXIgb3JpZW50ID0gc3BlYy5vcmllbnQsXG4gICAgICB0aXRsZSA9IHNwZWMudGl0bGUsXG4gICAgICBzaWduID0gKG9yaWVudCA9PT0gTGVmdCQxIHx8IG9yaWVudCA9PT0gVG9wJDEpID8gLTEgOiAxLFxuICAgICAgaG9yaXpvbnRhbCA9IChvcmllbnQgPT09IFRvcCQxIHx8IG9yaWVudCA9PT0gQm90dG9tJDEpLFxuICAgICAgZW5jb2RlID0ge30sIGVudGVyLCB1cGRhdGUsIHRpdGxlUG9zO1xuXG4gIGVuY29kZS5lbnRlciA9IGVudGVyID0ge1xuICAgIG9wYWNpdHk6IHt2YWx1ZTogMH1cbiAgfTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnYWxpZ24nLCBjb25maWcudGl0bGVBbGlnbik7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZpbGwnLCBjb25maWcudGl0bGVDb2xvcik7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnQnLCBjb25maWcudGl0bGVGb250KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnZm9udFNpemUnLCBjb25maWcudGl0bGVGb250U2l6ZSk7XG4gIGFkZEVuY29kZShlbnRlciwgJ2ZvbnRXZWlnaHQnLCBjb25maWcudGl0bGVGb250V2VpZ2h0KTtcbiAgYWRkRW5jb2RlKGVudGVyLCAnbGltaXQnLCBjb25maWcudGl0bGVMaW1pdCk7XG5cbiAgZW5jb2RlLmV4aXQgPSB7XG4gICAgb3BhY2l0eToge3ZhbHVlOiAwfVxuICB9O1xuXG4gIGVuY29kZS51cGRhdGUgPSB1cGRhdGUgPSB7XG4gICAgb3BhY2l0eToge3ZhbHVlOiAxfSxcbiAgICB0ZXh0OiB0aXRsZSAmJiB0aXRsZS5zaWduYWwgPyB7c2lnbmFsOiB0aXRsZS5zaWduYWx9IDoge3ZhbHVlOiB0aXRsZSArICcnfVxuICB9O1xuXG4gIHRpdGxlUG9zID0ge1xuICAgIHNjYWxlOiBzcGVjLnNjYWxlLFxuICAgIHJhbmdlOiAwLjVcbiAgfTtcblxuICBpZiAoaG9yaXpvbnRhbCkge1xuICAgIHVwZGF0ZS54ID0gdGl0bGVQb3M7XG4gICAgdXBkYXRlLmFuZ2xlID0ge3ZhbHVlOiAwfTtcbiAgICB1cGRhdGUuYmFzZWxpbmUgPSB7dmFsdWU6IG9yaWVudCA9PT0gVG9wJDEgPyAnYm90dG9tJyA6ICd0b3AnfTtcbiAgfSBlbHNlIHtcbiAgICB1cGRhdGUueSA9IHRpdGxlUG9zO1xuICAgIHVwZGF0ZS5hbmdsZSA9IHt2YWx1ZTogc2lnbiAqIDkwfTtcbiAgICB1cGRhdGUuYmFzZWxpbmUgPSB7dmFsdWU6ICdib3R0b20nfTtcbiAgfVxuXG4gIGFkZEVuY29kZSh1cGRhdGUsICdhbmdsZScsIGNvbmZpZy50aXRsZUFuZ2xlKTtcbiAgYWRkRW5jb2RlKHVwZGF0ZSwgJ2Jhc2VsaW5lJywgY29uZmlnLnRpdGxlQmFzZWxpbmUpO1xuXG4gICFhZGRFbmNvZGUodXBkYXRlLCAneCcsIGNvbmZpZy50aXRsZVgpXG4gICAgJiYgaG9yaXpvbnRhbCAmJiAhaGFzKCd4JywgdXNlckVuY29kZSlcbiAgICAmJiAoZW5jb2RlLmVudGVyLmF1dG8gPSB7dmFsdWU6IHRydWV9KTtcblxuICAhYWRkRW5jb2RlKHVwZGF0ZSwgJ3knLCBjb25maWcudGl0bGVZKVxuICAgICYmICFob3Jpem9udGFsICYmICFoYXMoJ3knLCB1c2VyRW5jb2RlKVxuICAgICYmIChlbmNvZGUuZW50ZXIuYXV0byA9IHt2YWx1ZTogdHJ1ZX0pO1xuXG4gIHJldHVybiBndWlkZU1hcmsoVGV4dE1hcmssIEF4aXNUaXRsZVJvbGUsIEd1aWRlVGl0bGVTdHlsZSwgbnVsbCwgZGF0YVJlZiwgZW5jb2RlLCB1c2VyRW5jb2RlKTtcbn07XG5cbnZhciBwYXJzZUF4aXMgPSBmdW5jdGlvbihzcGVjLCBzY29wZSkge1xuICB2YXIgY29uZmlnID0gYXhpc0NvbmZpZyhzcGVjLCBzY29wZSksXG4gICAgICBlbmNvZGUgPSBzcGVjLmVuY29kZSB8fCB7fSxcbiAgICAgIGF4aXNFbmNvZGUgPSBlbmNvZGUuYXhpcyB8fCB7fSxcbiAgICAgIG5hbWUgPSBheGlzRW5jb2RlLm5hbWUgfHwgdW5kZWZpbmVkLFxuICAgICAgaW50ZXJhY3RpdmUgPSBheGlzRW5jb2RlLmludGVyYWN0aXZlLFxuICAgICAgc3R5bGUgPSBheGlzRW5jb2RlLnN0eWxlLFxuICAgICAgZGF0dW0sIGRhdGFSZWYsIHRpY2tzUmVmLCBzaXplLCBncm91cCwgY2hpbGRyZW47XG5cbiAgLy8gc2luZ2xlLWVsZW1lbnQgZGF0YSBzb3VyY2UgZm9yIGF4aXMgZ3JvdXBcbiAgZGF0dW0gPSB7XG4gICAgb3JpZW50OiBzcGVjLm9yaWVudCxcbiAgICB0aWNrczogICEhdmFsdWUoc3BlYy50aWNrcywgY29uZmlnLnRpY2tzKSxcbiAgICBsYWJlbHM6ICEhdmFsdWUoc3BlYy5sYWJlbHMsIGNvbmZpZy5sYWJlbHMpLFxuICAgIGdyaWQ6ICAgISF2YWx1ZShzcGVjLmdyaWQsIGNvbmZpZy5ncmlkKSxcbiAgICBkb21haW46ICEhdmFsdWUoc3BlYy5kb21haW4sIGNvbmZpZy5kb21haW4pLFxuICAgIHRpdGxlOiAgISF2YWx1ZShzcGVjLnRpdGxlLCBmYWxzZSlcbiAgfTtcbiAgZGF0YVJlZiA9IHJlZihzY29wZS5hZGQoQ29sbGVjdCQxKHt9LCBbZGF0dW1dKSkpO1xuXG4gIC8vIGVuY29kaW5nIHByb3BlcnRpZXMgZm9yIGF4aXMgZ3JvdXAgaXRlbVxuICBheGlzRW5jb2RlID0gZXh0ZW5kRW5jb2RlKHtcbiAgICB1cGRhdGU6IHtcbiAgICAgIHJhbmdlOiAgICAgICAge3NpZ25hbDogJ2FicyhzcGFuKHJhbmdlKFwiJyArIHNwZWMuc2NhbGUgKyAnXCIpKSknfSxcbiAgICAgIG9mZnNldDogICAgICAgZW5jb2Rlcih2YWx1ZShzcGVjLm9mZnNldCwgMCkpLFxuICAgICAgcG9zaXRpb246ICAgICBlbmNvZGVyKHZhbHVlKHNwZWMucG9zaXRpb24sIDApKSxcbiAgICAgIHRpdGxlUGFkZGluZzogZW5jb2Rlcih2YWx1ZShzcGVjLnRpdGxlUGFkZGluZywgY29uZmlnLnRpdGxlUGFkZGluZykpLFxuICAgICAgbWluRXh0ZW50OiAgICBlbmNvZGVyKHZhbHVlKHNwZWMubWluRXh0ZW50LCBjb25maWcubWluRXh0ZW50KSksXG4gICAgICBtYXhFeHRlbnQ6ICAgIGVuY29kZXIodmFsdWUoc3BlYy5tYXhFeHRlbnQsIGNvbmZpZy5tYXhFeHRlbnQpKVxuICAgIH1cbiAgfSwgZW5jb2RlLmF4aXMsIFNraXApO1xuXG4gIC8vIGRhdGEgc291cmNlIGZvciBheGlzIHRpY2tzXG4gIHRpY2tzUmVmID0gcmVmKHNjb3BlLmFkZChBeGlzVGlja3MkMSh7XG4gICAgc2NhbGU6ICBzY29wZS5zY2FsZVJlZihzcGVjLnNjYWxlKSxcbiAgICBleHRyYTogIGNvbmZpZy50aWNrRXh0cmEsXG4gICAgY291bnQ6ICBzY29wZS5vYmplY3RQcm9wZXJ0eShzcGVjLnRpY2tDb3VudCksXG4gICAgdmFsdWVzOiBzY29wZS5vYmplY3RQcm9wZXJ0eShzcGVjLnZhbHVlcyksXG4gICAgZm9ybWF0U3BlY2lmaWVyOiBzY29wZS5wcm9wZXJ0eShzcGVjLmZvcm1hdClcbiAgfSkpKTtcblxuICAvLyBnZW5lcmF0ZSBheGlzIG1hcmtzXG4gIGNoaWxkcmVuID0gW107XG5cbiAgLy8gaW5jbHVkZSBheGlzIGdyaWRsaW5lcyBpZiByZXF1ZXN0ZWRcbiAgaWYgKGRhdHVtLmdyaWQpIHtcbiAgICBjaGlsZHJlbi5wdXNoKGF4aXNHcmlkKHNwZWMsIGNvbmZpZywgZW5jb2RlLmdyaWQsIHRpY2tzUmVmKSk7XG4gIH1cblxuICAvLyBpbmNsdWRlIGF4aXMgdGlja3MgaWYgcmVxdWVzdGVkXG4gIGlmIChkYXR1bS50aWNrcykge1xuICAgIHNpemUgPSB2YWx1ZShzcGVjLnRpY2tTaXplLCBjb25maWcudGlja1NpemUpO1xuICAgIGNoaWxkcmVuLnB1c2goYXhpc1RpY2tzKHNwZWMsIGNvbmZpZywgZW5jb2RlLnRpY2tzLCB0aWNrc1JlZiwgc2l6ZSkpO1xuICB9XG5cbiAgLy8gaW5jbHVkZSBheGlzIGxhYmVscyBpZiByZXF1ZXN0ZWRcbiAgaWYgKGRhdHVtLmxhYmVscykge1xuICAgIHNpemUgPSBkYXR1bS50aWNrcyA/IHNpemUgOiAwO1xuICAgIGNoaWxkcmVuLnB1c2goYXhpc0xhYmVscyhzcGVjLCBjb25maWcsIGVuY29kZS5sYWJlbHMsIHRpY2tzUmVmLCBzaXplKSk7XG4gIH1cblxuICAvLyBpbmNsdWRlIGF4aXMgZG9tYWluIHBhdGggaWYgcmVxdWVzdGVkXG4gIGlmIChkYXR1bS5kb21haW4pIHtcbiAgICBjaGlsZHJlbi5wdXNoKGF4aXNEb21haW4oc3BlYywgY29uZmlnLCBlbmNvZGUuZG9tYWluLCBkYXRhUmVmKSk7XG4gIH1cblxuICAvLyBpbmNsdWRlIGF4aXMgdGl0bGUgaWYgZGVmaW5lZFxuICBpZiAoZGF0dW0udGl0bGUpIHtcbiAgICBjaGlsZHJlbi5wdXNoKGF4aXNUaXRsZShzcGVjLCBjb25maWcsIGVuY29kZS50aXRsZSwgZGF0YVJlZikpO1xuICB9XG5cbiAgLy8gYnVpbGQgYXhpcyBzcGVjaWZpY2F0aW9uXG4gIGdyb3VwID0gZ3VpZGVHcm91cChBeGlzUm9sZSQyLCBzdHlsZSwgbmFtZSwgZGF0YVJlZiwgaW50ZXJhY3RpdmUsIGF4aXNFbmNvZGUsIGNoaWxkcmVuKTtcbiAgaWYgKHNwZWMuemluZGV4KSBncm91cC56aW5kZXggPSBzcGVjLnppbmRleDtcblxuICAvLyBwYXJzZSBheGlzIHNwZWNpZmljYXRpb25cbiAgcmV0dXJuIHBhcnNlTWFyayhncm91cCwgc2NvcGUpO1xufTtcblxudmFyIHBhcnNlU3BlYyA9IGZ1bmN0aW9uKHNwZWMsIHNjb3BlLCBwcmVwcm9jZXNzZWQpIHtcbiAgdmFyIHNpZ25hbHMgPSBhcnJheShzcGVjLnNpZ25hbHMpLFxuICAgICAgc2NhbGVzID0gYXJyYXkoc3BlYy5zY2FsZXMpO1xuXG4gIGlmICghcHJlcHJvY2Vzc2VkKSBzaWduYWxzLmZvckVhY2goZnVuY3Rpb24oXykge1xuICAgIHBhcnNlU2lnbmFsKF8sIHNjb3BlKTtcbiAgfSk7XG5cbiAgYXJyYXkoc3BlYy5wcm9qZWN0aW9ucykuZm9yRWFjaChmdW5jdGlvbihfKSB7XG4gICAgcGFyc2VQcm9qZWN0aW9uKF8sIHNjb3BlKTtcbiAgfSk7XG5cbiAgc2NhbGVzLmZvckVhY2goZnVuY3Rpb24oXykge1xuICAgIGluaXRTY2FsZShfLCBzY29wZSk7XG4gIH0pO1xuXG4gIGFycmF5KHNwZWMuZGF0YSkuZm9yRWFjaChmdW5jdGlvbihfKSB7XG4gICAgcGFyc2VEYXRhJDEoXywgc2NvcGUpO1xuICB9KTtcblxuICBzY2FsZXMuZm9yRWFjaChmdW5jdGlvbihfKSB7XG4gICAgcGFyc2VTY2FsZShfLCBzY29wZSk7XG4gIH0pO1xuXG4gIHNpZ25hbHMuZm9yRWFjaChmdW5jdGlvbihfKSB7XG4gICAgcGFyc2VTaWduYWxVcGRhdGVzKF8sIHNjb3BlKTtcbiAgfSk7XG5cbiAgYXJyYXkoc3BlYy5heGVzKS5mb3JFYWNoKGZ1bmN0aW9uKF8pIHtcbiAgICBwYXJzZUF4aXMoXywgc2NvcGUpO1xuICB9KTtcblxuICBhcnJheShzcGVjLm1hcmtzKS5mb3JFYWNoKGZ1bmN0aW9uKF8pIHtcbiAgICBwYXJzZU1hcmsoXywgc2NvcGUpO1xuICB9KTtcblxuICBhcnJheShzcGVjLmxlZ2VuZHMpLmZvckVhY2goZnVuY3Rpb24oXykge1xuICAgIHBhcnNlTGVnZW5kKF8sIHNjb3BlKTtcbiAgfSk7XG5cbiAgaWYgKHNwZWMudGl0bGUpIHtcbiAgICBwYXJzZVRpdGxlKHNwZWMudGl0bGUsIHNjb3BlKTtcbiAgfVxuXG4gIHNjb3BlLnBhcnNlTGFtYmRhcygpO1xuICByZXR1cm4gc2NvcGU7XG59O1xuXG52YXIgZGVmaW5lZCA9IHRvU2V0KFsnd2lkdGgnLCAnaGVpZ2h0JywgJ3BhZGRpbmcnLCAnYXV0b3NpemUnXSk7XG5cbmZ1bmN0aW9uIHBhcnNlVmlldyhzcGVjLCBzY29wZSkge1xuICB2YXIgY29uZmlnID0gc2NvcGUuY29uZmlnLFxuICAgICAgb3AsIGlucHV0LCBlbmNvZGUsIHBhcmVudCwgcm9vdDtcblxuICBzY29wZS5iYWNrZ3JvdW5kID0gc3BlYy5iYWNrZ3JvdW5kIHx8IGNvbmZpZy5iYWNrZ3JvdW5kO1xuICBzY29wZS5ldmVudENvbmZpZyA9IGNvbmZpZy5ldmVudHM7XG4gIHJvb3QgPSByZWYoc2NvcGUucm9vdCA9IHNjb3BlLmFkZChvcGVyYXRvcigpKSk7XG4gIHNjb3BlLmFkZFNpZ25hbCgnd2lkdGgnLCBzcGVjLndpZHRoIHx8IDApO1xuICBzY29wZS5hZGRTaWduYWwoJ2hlaWdodCcsIHNwZWMuaGVpZ2h0IHx8IDApO1xuICBzY29wZS5hZGRTaWduYWwoJ3BhZGRpbmcnLCBwYXJzZVBhZGRpbmcoc3BlYy5wYWRkaW5nLCBjb25maWcpKTtcbiAgc2NvcGUuYWRkU2lnbmFsKCdhdXRvc2l6ZScsIHBhcnNlQXV0b3NpemUoc3BlYy5hdXRvc2l6ZSwgY29uZmlnKSk7XG5cbiAgYXJyYXkoc3BlYy5zaWduYWxzKS5mb3JFYWNoKGZ1bmN0aW9uKF8pIHtcbiAgICBpZiAoIWRlZmluZWRbXy5uYW1lXSkgcGFyc2VTaWduYWwoXywgc2NvcGUpO1xuICB9KTtcblxuICAvLyBTdG9yZSByb290IGdyb3VwIGl0ZW1cbiAgaW5wdXQgPSBzY29wZS5hZGQoQ29sbGVjdCQxKCkpO1xuXG4gIC8vIEVuY29kZSByb290IGdyb3VwIGl0ZW1cbiAgZW5jb2RlID0gZXh0ZW5kRW5jb2RlKHtcbiAgICBlbnRlcjogeyB4OiB7dmFsdWU6IDB9LCB5OiB7dmFsdWU6IDB9IH0sXG4gICAgdXBkYXRlOiB7IHdpZHRoOiB7c2lnbmFsOiAnd2lkdGgnfSwgaGVpZ2h0OiB7c2lnbmFsOiAnaGVpZ2h0J30gfVxuICB9LCBzcGVjLmVuY29kZSk7XG5cbiAgZW5jb2RlID0gc2NvcGUuYWRkKEVuY29kZSQxKFxuICAgIGVuY29kZXJzKGVuY29kZSwgR3JvdXBNYXJrLCBGcmFtZVJvbGUkMSwgc3BlYy5zdHlsZSwgc2NvcGUsIHtwdWxzZTogcmVmKGlucHV0KX0pKVxuICApO1xuXG4gIC8vIFBlcmZvcm0gdmlldyBsYXlvdXRcbiAgcGFyZW50ID0gc2NvcGUuYWRkKFZpZXdMYXlvdXQkMSh7XG4gICAgbGF5b3V0OiAgICAgICBzY29wZS5vYmplY3RQcm9wZXJ0eShzcGVjLmxheW91dCksXG4gICAgbGVnZW5kTWFyZ2luOiBjb25maWcubGVnZW5kTWFyZ2luLFxuICAgIGF1dG9zaXplOiAgICAgc2NvcGUuc2lnbmFsUmVmKCdhdXRvc2l6ZScpLFxuICAgIG1hcms6ICAgICAgICAgcm9vdCxcbiAgICBwdWxzZTogICAgICAgIHJlZihlbmNvZGUpXG4gIH0pKTtcbiAgc2NvcGUub3BlcmF0b3JzLnBvcCgpO1xuXG4gIC8vIFBhcnNlIHJlbWFpbmRlciBvZiBzcGVjaWZpY2F0aW9uXG4gIHNjb3BlLnB1c2hTdGF0ZShyZWYoZW5jb2RlKSwgcmVmKHBhcmVudCksIG51bGwpO1xuICBwYXJzZVNwZWMoc3BlYywgc2NvcGUsIHRydWUpO1xuICBzY29wZS5vcGVyYXRvcnMucHVzaChwYXJlbnQpO1xuXG4gIC8vIEJvdW5kIC8gcmVuZGVyIC8gc2lldmUgcm9vdCBpdGVtXG4gIG9wID0gc2NvcGUuYWRkKEJvdW5kJDEoe21hcms6IHJvb3QsIHB1bHNlOiByZWYocGFyZW50KX0pKTtcbiAgb3AgPSBzY29wZS5hZGQoUmVuZGVyJDEoe3B1bHNlOiByZWYob3ApfSkpO1xuICBvcCA9IHNjb3BlLmFkZChTaWV2ZSQxKHtwdWxzZTogcmVmKG9wKX0pKTtcblxuICAvLyBUcmFjayBtZXRhZGF0YSBmb3Igcm9vdCBpdGVtXG4gIHNjb3BlLmFkZERhdGEoJ3Jvb3QnLCBuZXcgRGF0YVNjb3BlKHNjb3BlLCBpbnB1dCwgaW5wdXQsIG9wKSk7XG5cbiAgcmV0dXJuIHNjb3BlO1xufVxuXG5mdW5jdGlvbiBTY29wZShjb25maWcpIHtcbiAgdGhpcy5jb25maWcgPSBjb25maWc7XG5cbiAgdGhpcy5iaW5kaW5ncyA9IFtdO1xuICB0aGlzLmZpZWxkID0ge307XG4gIHRoaXMuc2lnbmFscyA9IHt9O1xuICB0aGlzLmxhbWJkYXMgPSB7fTtcbiAgdGhpcy5zY2FsZXMgPSB7fTtcbiAgdGhpcy5ldmVudHMgPSB7fTtcbiAgdGhpcy5kYXRhID0ge307XG5cbiAgdGhpcy5zdHJlYW1zID0gW107XG4gIHRoaXMudXBkYXRlcyA9IFtdO1xuICB0aGlzLm9wZXJhdG9ycyA9IFtdO1xuICB0aGlzLmJhY2tncm91bmQgPSBudWxsO1xuICB0aGlzLmV2ZW50Q29uZmlnID0gbnVsbDtcblxuICB0aGlzLl9pZCA9IDA7XG4gIHRoaXMuX3N1YmlkID0gMDtcbiAgdGhpcy5fbmV4dHN1YiA9IFswXTtcblxuICB0aGlzLl9wYXJlbnQgPSBbXTtcbiAgdGhpcy5fZW5jb2RlID0gW107XG4gIHRoaXMuX2xvb2t1cCA9IFtdO1xuICB0aGlzLl9tYXJrcGF0aCA9IFtdO1xufVxuXG5mdW5jdGlvbiBTdWJzY29wZShzY29wZSkge1xuICB0aGlzLmNvbmZpZyA9IHNjb3BlLmNvbmZpZztcblxuICB0aGlzLmZpZWxkID0gT2JqZWN0LmNyZWF0ZShzY29wZS5maWVsZCk7XG4gIHRoaXMuc2lnbmFscyA9IE9iamVjdC5jcmVhdGUoc2NvcGUuc2lnbmFscyk7XG4gIHRoaXMubGFtYmRhcyA9IE9iamVjdC5jcmVhdGUoc2NvcGUubGFtYmRhcyk7XG4gIHRoaXMuc2NhbGVzID0gT2JqZWN0LmNyZWF0ZShzY29wZS5zY2FsZXMpO1xuICB0aGlzLmV2ZW50cyA9IE9iamVjdC5jcmVhdGUoc2NvcGUuZXZlbnRzKTtcbiAgdGhpcy5kYXRhID0gT2JqZWN0LmNyZWF0ZShzY29wZS5kYXRhKTtcblxuICB0aGlzLnN0cmVhbXMgPSBbXTtcbiAgdGhpcy51cGRhdGVzID0gW107XG4gIHRoaXMub3BlcmF0b3JzID0gW107XG5cbiAgdGhpcy5faWQgPSAwO1xuICB0aGlzLl9zdWJpZCA9ICsrc2NvcGUuX25leHRzdWJbMF07XG4gIHRoaXMuX25leHRzdWIgPSBzY29wZS5fbmV4dHN1YjtcblxuICB0aGlzLl9wYXJlbnQgPSBzY29wZS5fcGFyZW50LnNsaWNlKCk7XG4gIHRoaXMuX2VuY29kZSA9IHNjb3BlLl9lbmNvZGUuc2xpY2UoKTtcbiAgdGhpcy5fbG9va3VwID0gc2NvcGUuX2xvb2t1cC5zbGljZSgpO1xuICB0aGlzLl9tYXJrcGF0aCA9IHNjb3BlLl9tYXJrcGF0aDtcbn1cblxudmFyIHByb3RvdHlwZSQ4NSA9IFNjb3BlLnByb3RvdHlwZSA9IFN1YnNjb3BlLnByb3RvdHlwZTtcblxuLy8gLS0tLVxuXG5wcm90b3R5cGUkODUuZm9yayA9IGZ1bmN0aW9uKCkge1xuICByZXR1cm4gbmV3IFN1YnNjb3BlKHRoaXMpO1xufTtcblxucHJvdG90eXBlJDg1LnRvUnVudGltZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLmZpbmlzaCgpO1xuICByZXR1cm4ge1xuICAgIGJhY2tncm91bmQ6ICB0aGlzLmJhY2tncm91bmQsXG4gICAgb3BlcmF0b3JzOiAgIHRoaXMub3BlcmF0b3JzLFxuICAgIHN0cmVhbXM6ICAgICB0aGlzLnN0cmVhbXMsXG4gICAgdXBkYXRlczogICAgIHRoaXMudXBkYXRlcyxcbiAgICBiaW5kaW5nczogICAgdGhpcy5iaW5kaW5ncyxcbiAgICBldmVudENvbmZpZzogdGhpcy5ldmVudENvbmZpZ1xuICB9O1xufTtcblxucHJvdG90eXBlJDg1LmlkID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiAodGhpcy5fc3ViaWQgPyB0aGlzLl9zdWJpZCArICc6JyA6IDApICsgdGhpcy5faWQrKztcbn07XG5cbnByb3RvdHlwZSQ4NS5hZGQgPSBmdW5jdGlvbihvcCkge1xuICB0aGlzLm9wZXJhdG9ycy5wdXNoKG9wKTtcbiAgb3AuaWQgPSB0aGlzLmlkKCk7XG4gIC8vIGlmIHByZS1yZWdpc3RyYXRpb24gcmVmZXJlbmNlcyBleGlzdCwgcmVzb2x2ZSB0aGVtIG5vd1xuICBpZiAob3AucmVmcykge1xuICAgIG9wLnJlZnMuZm9yRWFjaChmdW5jdGlvbihyZWYkJDEpIHsgcmVmJCQxLiRyZWYgPSBvcC5pZDsgfSk7XG4gICAgb3AucmVmcyA9IG51bGw7XG4gIH1cbiAgcmV0dXJuIG9wO1xufTtcblxucHJvdG90eXBlJDg1LnByb3h5ID0gZnVuY3Rpb24ob3ApIHtcbiAgdmFyIHZyZWYgPSBvcCBpbnN0YW5jZW9mIEVudHJ5ID8gcmVmKG9wKSA6IG9wO1xuICByZXR1cm4gdGhpcy5hZGQoUHJveHkkMSh7dmFsdWU6IHZyZWZ9KSk7XG59O1xuXG5wcm90b3R5cGUkODUuYWRkU3RyZWFtID0gZnVuY3Rpb24oc3RyZWFtKSB7XG4gIHRoaXMuc3RyZWFtcy5wdXNoKHN0cmVhbSk7XG4gIHN0cmVhbS5pZCA9IHRoaXMuaWQoKTtcbiAgcmV0dXJuIHN0cmVhbTtcbn07XG5cbnByb3RvdHlwZSQ4NS5hZGRVcGRhdGUgPSBmdW5jdGlvbih1cGRhdGUpIHtcbiAgdGhpcy51cGRhdGVzLnB1c2godXBkYXRlKTtcbiAgcmV0dXJuIHVwZGF0ZTtcbn07XG5cbi8vIEFwcGx5IG1ldGFkYXRhXG5wcm90b3R5cGUkODUuZmluaXNoID0gZnVuY3Rpb24oKSB7XG4gIHZhciBuYW1lLCBkcztcblxuICAvLyBhbm5vdGF0ZSByb290XG4gIGlmICh0aGlzLnJvb3QpIHRoaXMucm9vdC5yb290ID0gdHJ1ZTtcblxuICAvLyBhbm5vdGF0ZSBzaWduYWxzXG4gIGZvciAobmFtZSBpbiB0aGlzLnNpZ25hbHMpIHtcbiAgICB0aGlzLnNpZ25hbHNbbmFtZV0uc2lnbmFsID0gbmFtZTtcbiAgfVxuXG4gIC8vIGFubm90YXRlIHNjYWxlc1xuICBmb3IgKG5hbWUgaW4gdGhpcy5zY2FsZXMpIHtcbiAgICB0aGlzLnNjYWxlc1tuYW1lXS5zY2FsZSA9IG5hbWU7XG4gIH1cblxuICAvLyBhbm5vdGF0ZSBkYXRhIHNldHNcbiAgZnVuY3Rpb24gYW5ub3RhdGUob3AsIG5hbWUsIHR5cGUpIHtcbiAgICB2YXIgZGF0YSwgbGlzdDtcbiAgICBpZiAob3ApIHtcbiAgICAgIGRhdGEgPSBvcC5kYXRhIHx8IChvcC5kYXRhID0ge30pO1xuICAgICAgbGlzdCA9IGRhdGFbbmFtZV0gfHwgKGRhdGFbbmFtZV0gPSBbXSk7XG4gICAgICBsaXN0LnB1c2godHlwZSk7XG4gICAgfVxuICB9XG4gIGZvciAobmFtZSBpbiB0aGlzLmRhdGEpIHtcbiAgICBkcyA9IHRoaXMuZGF0YVtuYW1lXTtcbiAgICBhbm5vdGF0ZShkcy5pbnB1dCwgIG5hbWUsICdpbnB1dCcpO1xuICAgIGFubm90YXRlKGRzLm91dHB1dCwgbmFtZSwgJ291dHB1dCcpO1xuICAgIGFubm90YXRlKGRzLnZhbHVlcywgbmFtZSwgJ3ZhbHVlcycpO1xuICAgIGZvciAodmFyIGZpZWxkJCQxIGluIGRzLmluZGV4KSB7XG4gICAgICBhbm5vdGF0ZShkcy5pbmRleFtmaWVsZCQkMV0sIG5hbWUsICdpbmRleDonICsgZmllbGQkJDEpO1xuICAgIH1cbiAgfVxuXG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gLS0tLVxuXG5wcm90b3R5cGUkODUucHVzaFN0YXRlID0gZnVuY3Rpb24oZW5jb2RlLCBwYXJlbnQsIGxvb2t1cCkge1xuICB0aGlzLl9lbmNvZGUucHVzaChyZWYodGhpcy5hZGQoU2lldmUkMSh7cHVsc2U6IGVuY29kZX0pKSkpO1xuICB0aGlzLl9wYXJlbnQucHVzaChwYXJlbnQpO1xuICB0aGlzLl9sb29rdXAucHVzaChsb29rdXAgPyByZWYodGhpcy5wcm94eShsb29rdXApKSA6IG51bGwpO1xuICB0aGlzLl9tYXJrcGF0aC5wdXNoKC0xKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5wb3BTdGF0ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9lbmNvZGUucG9wKCk7XG4gIHRoaXMuX3BhcmVudC5wb3AoKTtcbiAgdGhpcy5fbG9va3VwLnBvcCgpO1xuICB0aGlzLl9tYXJrcGF0aC5wb3AoKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5wYXJlbnQgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHBlZWsodGhpcy5fcGFyZW50KTtcbn07XG5cbnByb3RvdHlwZSQ4NS5lbmNvZGUgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHBlZWsodGhpcy5fZW5jb2RlKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5sb29rdXAgPSBmdW5jdGlvbigpIHtcbiAgcmV0dXJuIHBlZWsodGhpcy5fbG9va3VwKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5tYXJrcGF0aCA9IGZ1bmN0aW9uKCkge1xuICB2YXIgcCA9IHRoaXMuX21hcmtwYXRoO1xuICByZXR1cm4gKytwW3AubGVuZ3RoLTFdO1xufTtcblxuLy8gLS0tLVxuXG5wcm90b3R5cGUkODUuZmllbGRSZWYgPSBmdW5jdGlvbihmaWVsZCQkMSwgbmFtZSkge1xuICBpZiAoaXNTdHJpbmcoZmllbGQkJDEpKSByZXR1cm4gZmllbGRSZWYkMShmaWVsZCQkMSwgbmFtZSk7XG4gIGlmICghZmllbGQkJDEuc2lnbmFsKSB7XG4gICAgZXJyb3IkMSgnVW5zdXBwb3J0ZWQgZmllbGQgcmVmZXJlbmNlOiAnICsgJChmaWVsZCQkMSkpO1xuICB9XG5cbiAgdmFyIHMgPSBmaWVsZCQkMS5zaWduYWwsXG4gICAgICBmID0gdGhpcy5maWVsZFtzXSxcbiAgICAgIHBhcmFtcztcblxuICBpZiAoIWYpIHsgLy8gVE9ETzogcmVwbGFjZSB3aXRoIHVwZGF0ZSBzaWduYWxSZWY/XG4gICAgcGFyYW1zID0ge25hbWU6IHRoaXMuc2lnbmFsUmVmKHMpfTtcbiAgICBpZiAobmFtZSkgcGFyYW1zLmFzID0gbmFtZTtcbiAgICB0aGlzLmZpZWxkW3NdID0gZiA9IHJlZih0aGlzLmFkZChGaWVsZCQxKHBhcmFtcykpKTtcbiAgfVxuICByZXR1cm4gZjtcbn07XG5cbnByb3RvdHlwZSQ4NS5jb21wYXJlUmVmID0gZnVuY3Rpb24oY21wLCBzdGFibGUpIHtcbiAgZnVuY3Rpb24gY2hlY2soXykge1xuICAgIGlmIChpc1NpZ25hbChfKSkge1xuICAgICAgc2lnbmFsID0gdHJ1ZTtcbiAgICAgIHJldHVybiByZWYoc2lnW18uc2lnbmFsXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBfO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzaWcgPSB0aGlzLnNpZ25hbHMsXG4gICAgICBzaWduYWwgPSBmYWxzZSxcbiAgICAgIGZpZWxkcyA9IGFycmF5KGNtcC5maWVsZCkubWFwKGNoZWNrKSxcbiAgICAgIG9yZGVycyA9IGFycmF5KGNtcC5vcmRlcikubWFwKGNoZWNrKTtcblxuICBpZiAoc3RhYmxlKSB7XG4gICAgZmllbGRzLnB1c2godHVwbGVpZFJlZik7XG4gIH1cblxuICByZXR1cm4gc2lnbmFsXG4gICAgPyByZWYodGhpcy5hZGQoQ29tcGFyZSQxKHtmaWVsZHM6IGZpZWxkcywgb3JkZXJzOiBvcmRlcnN9KSkpXG4gICAgOiBjb21wYXJlUmVmKGZpZWxkcywgb3JkZXJzKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5rZXlSZWYgPSBmdW5jdGlvbihmaWVsZHMsIGZsYXQpIHtcbiAgZnVuY3Rpb24gY2hlY2soXykge1xuICAgIGlmIChpc1NpZ25hbChfKSkge1xuICAgICAgc2lnbmFsID0gdHJ1ZTtcbiAgICAgIHJldHVybiByZWYoc2lnW18uc2lnbmFsXSk7XG4gICAgfSBlbHNlIHtcbiAgICAgIHJldHVybiBfO1xuICAgIH1cbiAgfVxuXG4gIHZhciBzaWcgPSB0aGlzLnNpZ25hbHMsXG4gICAgICBzaWduYWwgPSBmYWxzZTtcbiAgZmllbGRzID0gYXJyYXkoZmllbGRzKS5tYXAoY2hlY2spO1xuXG4gIHJldHVybiBzaWduYWxcbiAgICA/IHJlZih0aGlzLmFkZChLZXkkMSh7ZmllbGRzOiBmaWVsZHMsIGZsYXQ6IGZsYXR9KSkpXG4gICAgOiBrZXlSZWYoZmllbGRzLCBmbGF0KTtcbn07XG5cbnByb3RvdHlwZSQ4NS5zb3J0UmVmID0gZnVuY3Rpb24oc29ydCkge1xuICBpZiAoIXNvcnQpIHJldHVybiBzb3J0O1xuXG4gIC8vIGluY2x1ZGluZyBpZCBlbnN1cmVzIHN0YWJsZSBzb3J0aW5nXG4gIHZhciBhID0gW2FnZ3JGaWVsZChzb3J0Lm9wLCBzb3J0LmZpZWxkKSwgdHVwbGVpZFJlZl0sXG4gICAgICBvID0gc29ydC5vcmRlciB8fCBBc2NlbmRpbmc7XG5cbiAgcmV0dXJuIG8uc2lnbmFsXG4gICAgPyByZWYodGhpcy5hZGQoQ29tcGFyZSQxKHtcbiAgICAgICAgZmllbGRzOiBhLFxuICAgICAgICBvcmRlcnM6IFtvID0gdGhpcy5zaWduYWxSZWYoby5zaWduYWwpLCBvXVxuICAgICAgfSkpKVxuICAgIDogY29tcGFyZVJlZihhLCBbbywgb10pO1xufTtcblxuLy8gLS0tLVxuXG5wcm90b3R5cGUkODUuZXZlbnQgPSBmdW5jdGlvbihzb3VyY2UsIHR5cGUpIHtcbiAgdmFyIGtleSQkMSA9IHNvdXJjZSArICc6JyArIHR5cGU7XG4gIGlmICghdGhpcy5ldmVudHNba2V5JCQxXSkge1xuICAgIHZhciBpZCQkMSA9IHRoaXMuaWQoKTtcbiAgICB0aGlzLnN0cmVhbXMucHVzaCh7XG4gICAgICBpZDogaWQkJDEsXG4gICAgICBzb3VyY2U6IHNvdXJjZSxcbiAgICAgIHR5cGU6IHR5cGVcbiAgICB9KTtcbiAgICB0aGlzLmV2ZW50c1trZXkkJDFdID0gaWQkJDE7XG4gIH1cbiAgcmV0dXJuIHRoaXMuZXZlbnRzW2tleSQkMV07XG59O1xuXG4vLyAtLS0tXG5cbnByb3RvdHlwZSQ4NS5hZGRTaWduYWwgPSBmdW5jdGlvbihuYW1lLCB2YWx1ZSQkMSkge1xuICBpZiAodGhpcy5zaWduYWxzLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgZXJyb3IkMSgnRHVwbGljYXRlIHNpZ25hbCBuYW1lOiAnICsgJChuYW1lKSk7XG4gIH1cbiAgdmFyIG9wID0gdmFsdWUkJDEgaW5zdGFuY2VvZiBFbnRyeSA/IHZhbHVlJCQxIDogdGhpcy5hZGQob3BlcmF0b3IodmFsdWUkJDEpKTtcbiAgcmV0dXJuIHRoaXMuc2lnbmFsc1tuYW1lXSA9IG9wO1xufTtcblxucHJvdG90eXBlJDg1LmdldFNpZ25hbCA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgaWYgKCF0aGlzLnNpZ25hbHNbbmFtZV0pIHtcbiAgICBlcnJvciQxKCdVbnJlY29nbml6ZWQgc2lnbmFsIG5hbWU6ICcgKyAkKG5hbWUpKTtcbiAgfVxuICByZXR1cm4gdGhpcy5zaWduYWxzW25hbWVdO1xufTtcblxucHJvdG90eXBlJDg1LnNpZ25hbFJlZiA9IGZ1bmN0aW9uKHMpIHtcbiAgaWYgKHRoaXMuc2lnbmFsc1tzXSkge1xuICAgIHJldHVybiByZWYodGhpcy5zaWduYWxzW3NdKTtcbiAgfSBlbHNlIGlmICghdGhpcy5sYW1iZGFzLmhhc093blByb3BlcnR5KHMpKSB7XG4gICAgdGhpcy5sYW1iZGFzW3NdID0gdGhpcy5hZGQob3BlcmF0b3IobnVsbCkpO1xuICB9XG4gIHJldHVybiByZWYodGhpcy5sYW1iZGFzW3NdKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5wYXJzZUxhbWJkYXMgPSBmdW5jdGlvbigpIHtcbiAgdmFyIGNvZGUgPSBPYmplY3Qua2V5cyh0aGlzLmxhbWJkYXMpO1xuICBmb3IgKHZhciBpPTAsIG49Y29kZS5sZW5ndGg7IGk8bjsgKytpKSB7XG4gICAgdmFyIHMgPSBjb2RlW2ldLFxuICAgICAgICBlID0gcGFyc2VFeHByZXNzaW9uKHMsIHRoaXMpLFxuICAgICAgICBvcCA9IHRoaXMubGFtYmRhc1tzXTtcbiAgICBvcC5wYXJhbXMgPSBlLiRwYXJhbXM7XG4gICAgb3AudXBkYXRlID0gZS4kZXhwcjtcbiAgfVxufTtcblxucHJvdG90eXBlJDg1LnByb3BlcnR5ID0gZnVuY3Rpb24oc3BlYykge1xuICByZXR1cm4gc3BlYyAmJiBzcGVjLnNpZ25hbCA/IHRoaXMuc2lnbmFsUmVmKHNwZWMuc2lnbmFsKSA6IHNwZWM7XG59O1xuXG5wcm90b3R5cGUkODUub2JqZWN0UHJvcGVydHkgPSBmdW5jdGlvbihzcGVjKSB7XG4gIHJldHVybiAoIXNwZWMgfHwgIWlzT2JqZWN0KHNwZWMpKSA/IHNwZWNcbiAgICA6IHRoaXMuc2lnbmFsUmVmKHNwZWMuc2lnbmFsIHx8IHByb3BlcnR5TGFtYmRhKHNwZWMpKTtcbn07XG5cbmZ1bmN0aW9uIHByb3BlcnR5TGFtYmRhKHNwZWMpIHtcbiAgcmV0dXJuIChpc0FycmF5KHNwZWMpID8gYXJyYXlMYW1iZGEgOiBvYmplY3RMYW1iZGEpKHNwZWMpO1xufVxuXG5mdW5jdGlvbiBhcnJheUxhbWJkYShhcnJheSQkMSkge1xuICB2YXIgY29kZSA9ICdbJyxcbiAgICAgIGkgPSAwLFxuICAgICAgbiA9IGFycmF5JCQxLmxlbmd0aCxcbiAgICAgIHZhbHVlJCQxO1xuXG4gIGZvciAoOyBpPG47ICsraSkge1xuICAgIHZhbHVlJCQxID0gYXJyYXkkJDFbaV07XG4gICAgY29kZSArPSAoaSA+IDAgPyAnLCcgOiAnJylcbiAgICAgICsgKGlzT2JqZWN0KHZhbHVlJCQxKVxuICAgICAgICA/ICh2YWx1ZSQkMS5zaWduYWwgfHwgcHJvcGVydHlMYW1iZGEodmFsdWUkJDEpKVxuICAgICAgICA6ICQodmFsdWUkJDEpKTtcbiAgfVxuICByZXR1cm4gY29kZSArICddJztcbn1cblxuZnVuY3Rpb24gb2JqZWN0TGFtYmRhKG9iaikge1xuICB2YXIgY29kZSA9ICd7JyxcbiAgICAgIGkgPSAwLFxuICAgICAga2V5JCQxLCB2YWx1ZSQkMTtcblxuICBmb3IgKGtleSQkMSBpbiBvYmopIHtcbiAgICB2YWx1ZSQkMSA9IG9ialtrZXkkJDFdO1xuICAgIGNvZGUgKz0gKCsraSA+IDEgPyAnLCcgOiAnJylcbiAgICAgICsgJChrZXkkJDEpICsgJzonXG4gICAgICArIChpc09iamVjdCh2YWx1ZSQkMSlcbiAgICAgICAgPyAodmFsdWUkJDEuc2lnbmFsIHx8IHByb3BlcnR5TGFtYmRhKHZhbHVlJCQxKSlcbiAgICAgICAgOiAkKHZhbHVlJCQxKSk7XG4gIH1cbiAgcmV0dXJuIGNvZGUgKyAnfSc7XG59XG5cbnByb3RvdHlwZSQ4NS5hZGRCaW5kaW5nID0gZnVuY3Rpb24obmFtZSwgYmluZCkge1xuICBpZiAoIXRoaXMuYmluZGluZ3MpIHtcbiAgICBlcnJvciQxKCdOZXN0ZWQgc2lnbmFscyBkbyBub3Qgc3VwcG9ydCBiaW5kaW5nOiAnICsgJChuYW1lKSk7XG4gIH1cbiAgdGhpcy5iaW5kaW5ncy5wdXNoKGV4dGVuZCh7c2lnbmFsOiBuYW1lfSwgYmluZCkpO1xufTtcblxuLy8gLS0tLVxuXG5wcm90b3R5cGUkODUuYWRkU2NhbGVQcm9qID0gZnVuY3Rpb24obmFtZSwgdHJhbnNmb3JtKSB7XG4gIGlmICh0aGlzLnNjYWxlcy5oYXNPd25Qcm9wZXJ0eShuYW1lKSkge1xuICAgIGVycm9yJDEoJ0R1cGxpY2F0ZSBzY2FsZSBvciBwcm9qZWN0aW9uIG5hbWU6ICcgKyAkKG5hbWUpKTtcbiAgfVxuICB0aGlzLnNjYWxlc1tuYW1lXSA9IHRoaXMuYWRkKHRyYW5zZm9ybSk7XG59O1xuXG5wcm90b3R5cGUkODUuYWRkU2NhbGUgPSBmdW5jdGlvbihuYW1lLCBwYXJhbXMpIHtcbiAgdGhpcy5hZGRTY2FsZVByb2oobmFtZSwgU2NhbGUkMShwYXJhbXMpKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5hZGRQcm9qZWN0aW9uID0gZnVuY3Rpb24obmFtZSwgcGFyYW1zKSB7XG4gIHRoaXMuYWRkU2NhbGVQcm9qKG5hbWUsIFByb2plY3Rpb24kMShwYXJhbXMpKTtcbn07XG5cbnByb3RvdHlwZSQ4NS5nZXRTY2FsZSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgaWYgKCF0aGlzLnNjYWxlc1tuYW1lXSkge1xuICAgIGVycm9yJDEoJ1VucmVjb2duaXplZCBzY2FsZSBuYW1lOiAnICsgJChuYW1lKSk7XG4gIH1cbiAgcmV0dXJuIHRoaXMuc2NhbGVzW25hbWVdO1xufTtcblxucHJvdG90eXBlJDg1LnByb2plY3Rpb25SZWYgPVxucHJvdG90eXBlJDg1LnNjYWxlUmVmID0gZnVuY3Rpb24obmFtZSkge1xuICByZXR1cm4gcmVmKHRoaXMuZ2V0U2NhbGUobmFtZSkpO1xufTtcblxucHJvdG90eXBlJDg1LnByb2plY3Rpb25UeXBlID1cbnByb3RvdHlwZSQ4NS5zY2FsZVR5cGUgPSBmdW5jdGlvbihuYW1lKSB7XG4gIHJldHVybiB0aGlzLmdldFNjYWxlKG5hbWUpLnBhcmFtcy50eXBlO1xufTtcblxuLy8gLS0tLVxuXG5wcm90b3R5cGUkODUuYWRkRGF0YSA9IGZ1bmN0aW9uKG5hbWUsIGRhdGFTY29wZSkge1xuICBpZiAodGhpcy5kYXRhLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgZXJyb3IkMSgnRHVwbGljYXRlIGRhdGEgc2V0IG5hbWU6ICcgKyAkKG5hbWUpKTtcbiAgfVxuICByZXR1cm4gKHRoaXMuZGF0YVtuYW1lXSA9IGRhdGFTY29wZSk7XG59O1xuXG5wcm90b3R5cGUkODUuZ2V0RGF0YSA9IGZ1bmN0aW9uKG5hbWUpIHtcbiAgaWYgKCF0aGlzLmRhdGFbbmFtZV0pIHtcbiAgICBlcnJvciQxKCdVbmRlZmluZWQgZGF0YSBzZXQgbmFtZTogJyArICQobmFtZSkpO1xuICB9XG4gIHJldHVybiB0aGlzLmRhdGFbbmFtZV07XG59O1xuXG5wcm90b3R5cGUkODUuYWRkRGF0YVBpcGVsaW5lID0gZnVuY3Rpb24obmFtZSwgZW50cmllcykge1xuICBpZiAodGhpcy5kYXRhLmhhc093blByb3BlcnR5KG5hbWUpKSB7XG4gICAgZXJyb3IkMSgnRHVwbGljYXRlIGRhdGEgc2V0IG5hbWU6ICcgKyAkKG5hbWUpKTtcbiAgfVxuICByZXR1cm4gdGhpcy5hZGREYXRhKG5hbWUsIERhdGFTY29wZS5mcm9tRW50cmllcyh0aGlzLCBlbnRyaWVzKSk7XG59O1xuXG52YXIgZGVmYXVsdHMgPSBmdW5jdGlvbihjb25maWdzKSB7XG4gIHZhciBvdXRwdXQgPSBkZWZhdWx0cyQxKCk7XG4gIChjb25maWdzIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uKGNvbmZpZykge1xuICAgIHZhciBrZXkkJDEsIHZhbHVlLCBzdHlsZTtcbiAgICBpZiAoY29uZmlnKSB7XG4gICAgICBmb3IgKGtleSQkMSBpbiBjb25maWcpIHtcbiAgICAgICAgaWYgKGtleSQkMSA9PT0gJ3N0eWxlJykge1xuICAgICAgICAgIHN0eWxlID0gb3V0cHV0LnN0eWxlIHx8IChvdXRwdXQuc3R5bGUgPSB7fSk7XG4gICAgICAgICAgZm9yIChrZXkkJDEgaW4gY29uZmlnLnN0eWxlKSB7XG4gICAgICAgICAgICBzdHlsZVtrZXkkJDFdID0gZXh0ZW5kKHN0eWxlW2tleSQkMV0gfHwge30sIGNvbmZpZy5zdHlsZVtrZXkkJDFdKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgdmFsdWUgPSBjb25maWdba2V5JCQxXTtcbiAgICAgICAgICBvdXRwdXRba2V5JCQxXSA9IGlzT2JqZWN0KHZhbHVlKSAmJiAhaXNBcnJheSh2YWx1ZSlcbiAgICAgICAgICAgID8gZXh0ZW5kKGlzT2JqZWN0KG91dHB1dFtrZXkkJDFdKSA/IG91dHB1dFtrZXkkJDFdIDoge30sIHZhbHVlKVxuICAgICAgICAgICAgOiB2YWx1ZTtcbiAgICAgICAgfVxuICAgICAgfVxuICAgIH1cbiAgfSk7XG4gIHJldHVybiBvdXRwdXQ7XG59O1xuXG52YXIgZGVmYXVsdEZvbnQgPSAnc2Fucy1zZXJpZic7XG52YXIgZGVmYXVsdFN5bWJvbFNpemUgPSAzMDtcbnZhciBkZWZhdWx0U3Ryb2tlV2lkdGggPSAyO1xudmFyIGRlZmF1bHRDb2xvciA9ICcjNGM3OGE4JztcbnZhciBibGFjayA9IFwiIzAwMFwiO1xudmFyIGdyYXkgPSAnIzg4OCc7XG52YXIgbGlnaHRHcmF5ID0gJyNkZGQnO1xuXG4vKipcbiAqIFN0YW5kYXJkIGNvbmZpZ3VyYXRpb24gZGVmYXVsdHMgZm9yIFZlZ2Egc3BlY2lmaWNhdGlvbiBwYXJzaW5nLlxuICogVXNlcnMgY2FuIHByb3ZpZGUgdGhlaXIgb3duIChzdWItKXNldCBvZiB0aGVzZSBkZWZhdWx0IHZhbHVlc1xuICogYnkgcGFzc2luZyBpbiBhIGNvbmZpZyBvYmplY3QgdG8gdGhlIHRvcC1sZXZlbCBwYXJzZSBtZXRob2QuXG4gKi9cbmZ1bmN0aW9uIGRlZmF1bHRzJDEoKSB7XG4gIHJldHVybiB7XG4gICAgLy8gZGVmYXVsdCBwYWRkaW5nIGFyb3VuZCB2aXN1YWxpemF0aW9uXG4gICAgcGFkZGluZzogMCxcblxuICAgIC8vIGRlZmF1bHQgZm9yIGF1dG9tYXRpYyBzaXppbmc7IG9wdGlvbnM6IFwibm9uZVwiLCBcInBhZFwiLCBcImZpdFwiXG4gICAgLy8gb3IgcHJvdmlkZSBhbiBvYmplY3QgKGUuZy4sIHtcInR5cGVcIjogXCJwYWRcIiwgXCJyZXNpemVcIjogdHJ1ZX0pXG4gICAgYXV0b3NpemU6ICdwYWQnLFxuXG4gICAgLy8gZGVmYXVsdCB2aWV3IGJhY2tncm91bmQgY29sb3JcbiAgICAvLyBjb3ZlcnMgdGhlIGVudGlyZSB2aWV3IGNvbXBvbmVudFxuICAgIGJhY2tncm91bmQ6IG51bGwsXG5cbiAgICAvLyBkZWZhdWx0IGV2ZW50IGhhbmRsaW5nIGNvbmZpZ3VyYXRpb25cbiAgICAvLyBwcmV2ZW50RGVmYXVsdCBmb3Igdmlldy1zb3VyY2VkIGV2ZW50IHR5cGVzIGV4Y2VwdCAnd2hlZWwnXG4gICAgZXZlbnRzOiB7XG4gICAgICBkZWZhdWx0czoge2FsbG93OiBbJ3doZWVsJ119XG4gICAgfSxcblxuICAgIC8vIGRlZmF1bHRzIGZvciB0b3AtbGV2ZWwgZ3JvdXAgbWFya3NcbiAgICAvLyBhY2NlcHRzIG1hcmsgcHJvcGVydGllcyAoZmlsbCwgc3Ryb2tlLCBldGMpXG4gICAgLy8gY292ZXJzIHRoZSBkYXRhIHJlY3RhbmdsZSB3aXRoaW4gZ3JvdXAgd2lkdGgvaGVpZ2h0XG4gICAgZ3JvdXA6IG51bGwsXG5cbiAgICAvLyBkZWZhdWx0cyBmb3IgYmFzaWMgbWFyayB0eXBlc1xuICAgIC8vIGVhY2ggc3Vic2V0IGFjY2VwdHMgbWFyayBwcm9wZXJ0aWVzIChmaWxsLCBzdHJva2UsIGV0YylcbiAgICBtYXJrOiBudWxsLFxuICAgIGFyYzogeyBmaWxsOiBkZWZhdWx0Q29sb3IgfSxcbiAgICBhcmVhOiB7IGZpbGw6IGRlZmF1bHRDb2xvciB9LFxuICAgIGltYWdlOiBudWxsLFxuICAgIGxpbmU6IHtcbiAgICAgIHN0cm9rZTogZGVmYXVsdENvbG9yLFxuICAgICAgc3Ryb2tlV2lkdGg6IGRlZmF1bHRTdHJva2VXaWR0aFxuICAgIH0sXG4gICAgcGF0aDogeyBzdHJva2U6IGRlZmF1bHRDb2xvciB9LFxuICAgIHJlY3Q6IHsgZmlsbDogZGVmYXVsdENvbG9yIH0sXG4gICAgcnVsZTogeyBzdHJva2U6IGJsYWNrIH0sXG4gICAgc2hhcGU6IHsgc3Ryb2tlOiBkZWZhdWx0Q29sb3IgfSxcbiAgICBzeW1ib2w6IHtcbiAgICAgIGZpbGw6IGRlZmF1bHRDb2xvcixcbiAgICAgIHNpemU6IDY0XG4gICAgfSxcbiAgICB0ZXh0OiB7XG4gICAgICBmaWxsOiBibGFjayxcbiAgICAgIGZvbnQ6IGRlZmF1bHRGb250LFxuICAgICAgZm9udFNpemU6IDExXG4gICAgfSxcblxuICAgIC8vIHN0eWxlIGRlZmluaXRpb25zXG4gICAgc3R5bGU6IHtcbiAgICAgIC8vIGF4aXMgJiBsZWdlbmQgbGFiZWxzXG4gICAgICBcImd1aWRlLWxhYmVsXCI6IHtcbiAgICAgICAgZmlsbDogYmxhY2ssXG4gICAgICAgIGZvbnQ6IGRlZmF1bHRGb250LFxuICAgICAgICBmb250U2l6ZTogMTBcbiAgICAgIH0sXG4gICAgICAvLyBheGlzICYgbGVnZW5kIHRpdGxlc1xuICAgICAgXCJndWlkZS10aXRsZVwiOiB7XG4gICAgICAgIGZpbGw6IGJsYWNrLFxuICAgICAgICBmb250OiBkZWZhdWx0Rm9udCxcbiAgICAgICAgZm9udFNpemU6IDExLFxuICAgICAgICBmb250V2VpZ2h0OiAnYm9sZCdcbiAgICAgIH0sXG4gICAgICAvLyBoZWFkZXJzLCBpbmNsdWRpbmcgY2hhcnQgdGl0bGVcbiAgICAgIFwiZ3JvdXAtdGl0bGVcIjoge1xuICAgICAgICBmaWxsOiBibGFjayxcbiAgICAgICAgZm9udDogZGVmYXVsdEZvbnQsXG4gICAgICAgIGZvbnRTaXplOiAxMyxcbiAgICAgICAgZm9udFdlaWdodDogJ2JvbGQnXG4gICAgICB9LFxuICAgICAgLy8gZGVmYXVsdHMgZm9yIHN0eWxlZCBwb2ludCBtYXJrcyBpbiBWZWdhLUxpdGVcbiAgICAgIHBvaW50OiB7XG4gICAgICAgIHNpemU6IGRlZmF1bHRTeW1ib2xTaXplLFxuICAgICAgICBzdHJva2VXaWR0aDogZGVmYXVsdFN0cm9rZVdpZHRoLFxuICAgICAgICBzaGFwZTogJ2NpcmNsZSdcbiAgICAgIH0sXG4gICAgICBjaXJjbGU6IHtcbiAgICAgICAgc2l6ZTogZGVmYXVsdFN5bWJvbFNpemUsXG4gICAgICAgIHN0cm9rZVdpZHRoOiBkZWZhdWx0U3Ryb2tlV2lkdGhcbiAgICAgIH0sXG4gICAgICBzcXVhcmU6IHtcbiAgICAgICAgc2l6ZTogZGVmYXVsdFN5bWJvbFNpemUsXG4gICAgICAgIHN0cm9rZVdpZHRoOiBkZWZhdWx0U3Ryb2tlV2lkdGgsXG4gICAgICAgIHNoYXBlOiAnc3F1YXJlJ1xuICAgICAgfSxcbiAgICAgIC8vIGRlZmF1bHRzIGZvciBzdHlsZWQgZ3JvdXAgbWFya3MgaW4gVmVnYS1MaXRlXG4gICAgICBjZWxsOiB7XG4gICAgICAgIGZpbGw6ICd0cmFuc3BhcmVudCcsXG4gICAgICAgIHN0cm9rZTogbGlnaHRHcmF5XG4gICAgICB9XG4gICAgfSxcblxuICAgIC8vIGRlZmF1bHRzIGZvciBheGVzXG4gICAgYXhpczoge1xuICAgICAgbWluRXh0ZW50OiAwLFxuICAgICAgbWF4RXh0ZW50OiAyMDAsXG4gICAgICBiYW5kUG9zaXRpb246IDAuNSxcbiAgICAgIGRvbWFpbjogdHJ1ZSxcbiAgICAgIGRvbWFpbldpZHRoOiAxLFxuICAgICAgZG9tYWluQ29sb3I6IGdyYXksXG4gICAgICBncmlkOiBmYWxzZSxcbiAgICAgIGdyaWRXaWR0aDogMSxcbiAgICAgIGdyaWRDb2xvcjogbGlnaHRHcmF5LFxuICAgICAgZ3JpZE9wYWNpdHk6IDEsXG4gICAgICBsYWJlbHM6IHRydWUsXG4gICAgICBsYWJlbEFuZ2xlOiAwLFxuICAgICAgbGFiZWxMaW1pdDogMTgwLFxuICAgICAgbGFiZWxQYWRkaW5nOiAyLFxuICAgICAgdGlja3M6IHRydWUsXG4gICAgICB0aWNrQ29sb3I6IGdyYXksXG4gICAgICB0aWNrT2Zmc2V0OiAwLFxuICAgICAgdGlja1JvdW5kOiB0cnVlLFxuICAgICAgdGlja1NpemU6IDUsXG4gICAgICB0aWNrV2lkdGg6IDEsXG4gICAgICB0aXRsZUFsaWduOiAnY2VudGVyJyxcbiAgICAgIHRpdGxlUGFkZGluZzogNFxuICAgIH0sXG5cbiAgICAvLyBjb3JyZWN0aW9uIGZvciBjZW50ZXJpbmcgYmlhc1xuICAgIGF4aXNCYW5kOiB7XG4gICAgICB0aWNrT2Zmc2V0OiAtMVxuICAgIH0sXG5cbiAgICAvLyBkZWZhdWx0cyBmb3IgbGVnZW5kc1xuICAgIGxlZ2VuZDoge1xuICAgICAgb3JpZW50OiAncmlnaHQnLFxuICAgICAgb2Zmc2V0OiAxOCxcbiAgICAgIHBhZGRpbmc6IDAsXG4gICAgICBlbnRyeVBhZGRpbmc6IDUsXG4gICAgICB0aXRsZVBhZGRpbmc6IDUsXG4gICAgICBncmFkaWVudFdpZHRoOiAxMDAsXG4gICAgICBncmFkaWVudEhlaWdodDogMjAsXG4gICAgICBncmFkaWVudFN0cm9rZUNvbG9yOiBsaWdodEdyYXksXG4gICAgICBncmFkaWVudFN0cm9rZVdpZHRoOiAwLFxuICAgICAgZ3JhZGllbnRMYWJlbEJhc2VsaW5lOiAndG9wJyxcbiAgICAgIGdyYWRpZW50TGFiZWxPZmZzZXQ6IDIsXG4gICAgICBsYWJlbEFsaWduOiAnbGVmdCcsXG4gICAgICBsYWJlbEJhc2VsaW5lOiAnbWlkZGxlJyxcbiAgICAgIGxhYmVsT2Zmc2V0OiA4LFxuICAgICAgbGFiZWxMaW1pdDogMTYwLFxuICAgICAgc3ltYm9sVHlwZTogJ2NpcmNsZScsXG4gICAgICBzeW1ib2xTaXplOiAxMDAsXG4gICAgICBzeW1ib2xGaWxsQ29sb3I6ICd0cmFuc3BhcmVudCcsXG4gICAgICBzeW1ib2xTdHJva2VDb2xvcjogZ3JheSxcbiAgICAgIHN5bWJvbFN0cm9rZVdpZHRoOiAxLjUsXG4gICAgICB0aXRsZUFsaWduOiAnbGVmdCcsXG4gICAgICB0aXRsZUJhc2VsaW5lOiAndG9wJyxcbiAgICAgIHRpdGxlTGltaXQ6IDE4MFxuICAgIH0sXG5cbiAgICAvLyBkZWZhdWx0cyBmb3IgZ3JvdXAgdGl0bGVcbiAgICB0aXRsZToge1xuICAgICAgb3JpZW50OiAndG9wJyxcbiAgICAgIGFuY2hvcjogJ21pZGRsZScsXG4gICAgICBvZmZzZXQ6IDRcbiAgICB9LFxuXG4gICAgLy8gZGVmYXVsdHMgZm9yIHNjYWxlIHJhbmdlc1xuICAgIHJhbmdlOiB7XG4gICAgICBjYXRlZ29yeToge1xuICAgICAgICBzY2hlbWU6ICd0YWJsZWF1MTAnXG4gICAgICB9LFxuICAgICAgb3JkaW5hbDoge1xuICAgICAgICBzY2hlbWU6ICdibHVlcycsXG4gICAgICAgIGV4dGVudDogWzAuMiwgMV1cbiAgICAgIH0sXG4gICAgICBoZWF0bWFwOiB7XG4gICAgICAgIHNjaGVtZTogJ3ZpcmlkaXMnXG4gICAgICB9LFxuICAgICAgcmFtcDoge1xuICAgICAgICBzY2hlbWU6ICdibHVlcycsXG4gICAgICAgIGV4dGVudDogWzAuMiwgMV1cbiAgICAgIH0sXG4gICAgICBkaXZlcmdpbmc6IHtcbiAgICAgICAgc2NoZW1lOiAnYmx1ZW9yYW5nZSdcbiAgICAgIH0sXG4gICAgICBzeW1ib2w6IFtcbiAgICAgICAgJ2NpcmNsZScsXG4gICAgICAgICdzcXVhcmUnLFxuICAgICAgICAndHJpYW5nbGUtdXAnLFxuICAgICAgICAnY3Jvc3MnLFxuICAgICAgICAnZGlhbW9uZCcsXG4gICAgICAgICd0cmlhbmdsZS1yaWdodCcsXG4gICAgICAgICd0cmlhbmdsZS1kb3duJyxcbiAgICAgICAgJ3RyaWFuZ2xlLWxlZnQnXG4gICAgICBdXG4gICAgfVxuICB9O1xufVxuXG52YXIgcGFyc2UkMiA9IGZ1bmN0aW9uKHNwZWMsIGNvbmZpZykge1xuICBpZiAoIWlzT2JqZWN0KHNwZWMpKSBlcnJvciQxKCdJbnB1dCBWZWdhIHNwZWNpZmljYXRpb24gbXVzdCBiZSBhbiBvYmplY3QuJyk7XG4gIHJldHVybiBwYXJzZVZpZXcoc3BlYywgbmV3IFNjb3BlKGRlZmF1bHRzKFtjb25maWcsIHNwZWMuY29uZmlnXSkpKVxuICAgIC50b1J1bnRpbWUoKTtcbn07XG5cbi8qKlxuICogUGFyc2UgYW4gZXhwcmVzc2lvbiBnaXZlbiB0aGUgYXJndW1lbnQgc2lnbmF0dXJlIGFuZCBib2R5IGNvZGUuXG4gKi9cbmZ1bmN0aW9uIGV4cHJlc3Npb24kMShhcmdzLCBjb2RlLCBjdHgpIHtcbiAgLy8gd3JhcCBjb2RlIGluIHJldHVybiBzdGF0ZW1lbnQgaWYgZXhwcmVzc2lvbiBkb2VzIG5vdCB0ZXJtaW5hdGVcbiAgaWYgKGNvZGVbY29kZS5sZW5ndGgtMV0gIT09ICc7Jykge1xuICAgIGNvZGUgPSAncmV0dXJuKCcgKyBjb2RlICsgJyk7JztcbiAgfVxuICB2YXIgZm4gPSBGdW5jdGlvbi5hcHBseShudWxsLCBhcmdzLmNvbmNhdChjb2RlKSk7XG4gIHJldHVybiBjdHggJiYgY3R4LmZ1bmN0aW9ucyA/IGZuLmJpbmQoY3R4LmZ1bmN0aW9ucykgOiBmbjtcbn1cblxuLyoqXG4gKiBQYXJzZSBhbiBleHByZXNzaW9uIHVzZWQgdG8gdXBkYXRlIGFuIG9wZXJhdG9yIHZhbHVlLlxuICovXG5mdW5jdGlvbiBvcGVyYXRvckV4cHJlc3Npb24oY29kZSwgY3R4KSB7XG4gIHJldHVybiBleHByZXNzaW9uJDEoWydfJ10sIGNvZGUsIGN0eCk7XG59XG5cbi8qKlxuICogUGFyc2UgYW4gZXhwcmVzc2lvbiBwcm92aWRlZCBhcyBhbiBvcGVyYXRvciBwYXJhbWV0ZXIgdmFsdWUuXG4gKi9cbmZ1bmN0aW9uIHBhcmFtZXRlckV4cHJlc3Npb24oY29kZSwgY3R4KSB7XG4gIHJldHVybiBleHByZXNzaW9uJDEoWydkYXR1bScsICdfJ10sIGNvZGUsIGN0eCk7XG59XG5cbi8qKlxuICogUGFyc2UgYW4gZXhwcmVzc2lvbiBhcHBsaWVkIHRvIGFuIGV2ZW50IHN0cmVhbS5cbiAqL1xuZnVuY3Rpb24gZXZlbnRFeHByZXNzaW9uKGNvZGUsIGN0eCkge1xuICByZXR1cm4gZXhwcmVzc2lvbiQxKFsnZXZlbnQnXSwgY29kZSwgY3R4KTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhbiBleHByZXNzaW9uIHVzZWQgdG8gaGFuZGxlIGFuIGV2ZW50LWRyaXZlbiBvcGVyYXRvciB1cGRhdGUuXG4gKi9cbmZ1bmN0aW9uIGhhbmRsZXJFeHByZXNzaW9uKGNvZGUsIGN0eCkge1xuICByZXR1cm4gZXhwcmVzc2lvbiQxKFsnXycsICdldmVudCddLCBjb2RlLCBjdHgpO1xufVxuXG4vKipcbiAqIFBhcnNlIGFuIGV4cHJlc3Npb24gdGhhdCBwZXJmb3JtcyB2aXN1YWwgZW5jb2RpbmcuXG4gKi9cbmZ1bmN0aW9uIGVuY29kZUV4cHJlc3Npb24oY29kZSwgY3R4KSB7XG4gIHJldHVybiBleHByZXNzaW9uJDEoWydpdGVtJywgJ18nXSwgY29kZSwgY3R4KTtcbn1cblxuLyoqXG4gKiBQYXJzZSBhIHNldCBvZiBvcGVyYXRvciBwYXJhbWV0ZXJzLlxuICovXG5mdW5jdGlvbiBwYXJzZVBhcmFtZXRlcnMkMShzcGVjLCBjdHgsIHBhcmFtcykge1xuICBwYXJhbXMgPSBwYXJhbXMgfHwge307XG4gIHZhciBrZXkkJDEsIHZhbHVlO1xuXG4gIGZvciAoa2V5JCQxIGluIHNwZWMpIHtcbiAgICB2YWx1ZSA9IHNwZWNba2V5JCQxXTtcblxuICAgIGlmICh2YWx1ZSAmJiB2YWx1ZS4kZXhwciAmJiB2YWx1ZS4kcGFyYW1zKSB7XG4gICAgICAvLyBpZiBleHByZXNzaW9uLCBwYXJzZSBpdHMgcGFyYW1ldGVyc1xuICAgICAgcGFyc2VQYXJhbWV0ZXJzJDEodmFsdWUuJHBhcmFtcywgY3R4LCBwYXJhbXMpO1xuICAgIH1cblxuICAgIHBhcmFtc1trZXkkJDFdID0gaXNBcnJheSh2YWx1ZSlcbiAgICAgID8gdmFsdWUubWFwKGZ1bmN0aW9uKHYpIHsgcmV0dXJuIHBhcnNlUGFyYW1ldGVyJDIodiwgY3R4KTsgfSlcbiAgICAgIDogcGFyc2VQYXJhbWV0ZXIkMih2YWx1ZSwgY3R4KTtcbiAgfVxuICByZXR1cm4gcGFyYW1zO1xufVxuXG4vKipcbiAqIFBhcnNlIGEgc2luZ2xlIHBhcmFtZXRlci5cbiAqL1xuZnVuY3Rpb24gcGFyc2VQYXJhbWV0ZXIkMihzcGVjLCBjdHgpIHtcbiAgaWYgKCFzcGVjIHx8ICFpc09iamVjdChzcGVjKSkgcmV0dXJuIHNwZWM7XG5cbiAgZm9yICh2YXIgaT0wLCBuPVBBUlNFUlMubGVuZ3RoLCBwOyBpPG47ICsraSkge1xuICAgIHAgPSBQQVJTRVJTW2ldO1xuICAgIGlmIChzcGVjLmhhc093blByb3BlcnR5KHAua2V5KSkge1xuICAgICAgcmV0dXJuIHAucGFyc2Uoc3BlYywgY3R4KTtcbiAgICB9XG4gIH1cbiAgcmV0dXJuIHNwZWM7XG59XG5cbi8qKiBSZWZlcmVuY2UgcGFyc2Vycy4gKi9cbnZhciBQQVJTRVJTID0gW1xuICB7a2V5OiAnJHJlZicsICAgICAgcGFyc2U6IGdldE9wZXJhdG9yfSxcbiAge2tleTogJyRrZXknLCAgICAgIHBhcnNlOiBnZXRLZXl9LFxuICB7a2V5OiAnJGV4cHInLCAgICAgcGFyc2U6IGdldEV4cHJlc3Npb259LFxuICB7a2V5OiAnJGZpZWxkJywgICAgcGFyc2U6IGdldEZpZWxkJDF9LFxuICB7a2V5OiAnJGVuY29kZScsICAgcGFyc2U6IGdldEVuY29kZX0sXG4gIHtrZXk6ICckY29tcGFyZScsICBwYXJzZTogZ2V0Q29tcGFyZX0sXG4gIHtrZXk6ICckY29udGV4dCcsICBwYXJzZTogZ2V0Q29udGV4dH0sXG4gIHtrZXk6ICckc3ViZmxvdycsICBwYXJzZTogZ2V0U3ViZmxvd30sXG4gIHtrZXk6ICckdHVwbGVpZCcsICBwYXJzZTogZ2V0VHVwbGVJZH1cbl07XG5cbi8qKlxuICogUmVzb2x2ZSBhbiBvcGVyYXRvciByZWZlcmVuY2UuXG4gKi9cbmZ1bmN0aW9uIGdldE9wZXJhdG9yKF8sIGN0eCkge1xuICByZXR1cm4gY3R4LmdldChfLiRyZWYpIHx8IGVycm9yJDEoJ09wZXJhdG9yIG5vdCBkZWZpbmVkOiAnICsgXy4kcmVmKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGFuIGV4cHJlc3Npb24gcmVmZXJlbmNlLlxuICovXG5mdW5jdGlvbiBnZXRFeHByZXNzaW9uKF8sIGN0eCkge1xuICB2YXIgayA9ICdlOicgKyBfLiRleHByO1xuICByZXR1cm4gY3R4LmZuW2tdXG4gICAgfHwgKGN0eC5mbltrXSA9IGFjY2Vzc29yKHBhcmFtZXRlckV4cHJlc3Npb24oXy4kZXhwciwgY3R4KSwgXy4kZmllbGRzLCBfLiRuYW1lKSk7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIGtleSBhY2Nlc3NvciByZWZlcmVuY2UuXG4gKi9cbmZ1bmN0aW9uIGdldEtleShfLCBjdHgpIHtcbiAgdmFyIGsgPSAnazonICsgXy4ka2V5ICsgJ18nICsgKCEhXy4kZmxhdCk7XG4gIHJldHVybiBjdHguZm5ba10gfHwgKGN0eC5mbltrXSA9IGtleShfLiRrZXksIF8uJGZsYXQpKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgZmllbGQgYWNjZXNzb3IgcmVmZXJlbmNlLlxuICovXG5mdW5jdGlvbiBnZXRGaWVsZCQxKF8sIGN0eCkge1xuICBpZiAoIV8uJGZpZWxkKSByZXR1cm4gbnVsbDtcbiAgdmFyIGsgPSAnZjonICsgXy4kZmllbGQgKyAnXycgKyBfLiRuYW1lO1xuICByZXR1cm4gY3R4LmZuW2tdIHx8IChjdHguZm5ba10gPSBmaWVsZChfLiRmaWVsZCwgXy4kbmFtZSkpO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYSBjb21wYXJhdG9yIGZ1bmN0aW9uIHJlZmVyZW5jZS5cbiAqL1xuZnVuY3Rpb24gZ2V0Q29tcGFyZShfLCBjdHgpIHtcbiAgdmFyIGsgPSAnYzonICsgXy4kY29tcGFyZSArICdfJyArIF8uJG9yZGVyLFxuICAgICAgYyA9IGFycmF5KF8uJGNvbXBhcmUpLm1hcChmdW5jdGlvbihfKSB7XG4gICAgICAgIHJldHVybiAoXyAmJiBfLiR0dXBsZWlkKSA/IHR1cGxlaWQgOiBfO1xuICAgICAgfSk7XG4gIHJldHVybiBjdHguZm5ba10gfHwgKGN0eC5mbltrXSA9IGNvbXBhcmUoYywgXy4kb3JkZXIpKTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGFuIGVuY29kZSBvcGVyYXRvciByZWZlcmVuY2UuXG4gKi9cbmZ1bmN0aW9uIGdldEVuY29kZShfLCBjdHgpIHtcbiAgdmFyIHNwZWMgPSBfLiRlbmNvZGUsXG4gICAgICBlbmNvZGUgPSB7fSwgbmFtZSwgZW5jO1xuXG4gIGZvciAobmFtZSBpbiBzcGVjKSB7XG4gICAgZW5jID0gc3BlY1tuYW1lXTtcbiAgICBlbmNvZGVbbmFtZV0gPSBhY2Nlc3NvcihlbmNvZGVFeHByZXNzaW9uKGVuYy4kZXhwciwgY3R4KSwgZW5jLiRmaWVsZHMpO1xuICAgIGVuY29kZVtuYW1lXS5vdXRwdXQgPSBlbmMuJG91dHB1dDtcbiAgfVxuICByZXR1cm4gZW5jb2RlO1xufVxuXG4vKipcbiAqIFJlc29sdmUgYW4gY29udGV4dCByZWZlcmVuY2UuXG4gKi9cbmZ1bmN0aW9uIGdldENvbnRleHQoXywgY3R4KSB7XG4gIHJldHVybiBjdHg7XG59XG5cbi8qKlxuICogUmVzb2x2ZSBhIHJlY3Vyc2l2ZSBzdWJmbG93IHNwZWNpZmljYXRpb24uXG4gKi9cbmZ1bmN0aW9uIGdldFN1YmZsb3coXywgY3R4KSB7XG4gIHZhciBzcGVjID0gXy4kc3ViZmxvdztcbiAgcmV0dXJuIGZ1bmN0aW9uKGRhdGFmbG93LCBrZXkkJDEsIHBhcmVudCkge1xuICAgIHZhciBzdWJjdHggPSBwYXJzZURhdGFmbG93KHNwZWMsIGN0eC5mb3JrKCkpLFxuICAgICAgICBvcCA9IHN1YmN0eC5nZXQoc3BlYy5vcGVyYXRvcnNbMF0uaWQpLFxuICAgICAgICBwID0gc3ViY3R4LnNpZ25hbHMucGFyZW50O1xuICAgIGlmIChwKSBwLnNldChwYXJlbnQpO1xuICAgIHJldHVybiBvcDtcbiAgfTtcbn1cblxuLyoqXG4gKiBSZXNvbHZlIGEgdHVwbGUgaWQgcmVmZXJlbmNlLlxuICovXG5mdW5jdGlvbiBnZXRUdXBsZUlkKCkge1xuICByZXR1cm4gdHVwbGVpZDtcbn1cblxuZnVuY3Rpb24gY2Fub25pY2FsVHlwZSh0eXBlKSB7XG4gIHJldHVybiAodHlwZSArICcnKS50b0xvd2VyQ2FzZSgpO1xufVxuZnVuY3Rpb24gaXNPcGVyYXRvcih0eXBlKSB7XG4gICByZXR1cm4gY2Fub25pY2FsVHlwZSh0eXBlKSA9PT0gJ29wZXJhdG9yJztcbn1cblxuZnVuY3Rpb24gaXNDb2xsZWN0KHR5cGUpIHtcbiAgcmV0dXJuIGNhbm9uaWNhbFR5cGUodHlwZSkgPT09ICdjb2xsZWN0Jztcbn1cblxuLyoqXG4gKiBQYXJzZSBhIGRhdGFmbG93IG9wZXJhdG9yLlxuICovXG52YXIgcGFyc2VPcGVyYXRvciA9IGZ1bmN0aW9uKHNwZWMsIGN0eCkge1xuICBpZiAoaXNPcGVyYXRvcihzcGVjLnR5cGUpIHx8ICFzcGVjLnR5cGUpIHtcbiAgICBjdHgub3BlcmF0b3Ioc3BlYyxcbiAgICAgIHNwZWMudXBkYXRlID8gb3BlcmF0b3JFeHByZXNzaW9uKHNwZWMudXBkYXRlLCBjdHgpIDogbnVsbCk7XG4gIH0gZWxzZSB7XG4gICAgY3R4LnRyYW5zZm9ybShzcGVjLCBzcGVjLnR5cGUpO1xuICB9XG59O1xuXG4vKipcbiAqIFBhcnNlIGFuZCBhc3NpZ24gb3BlcmF0b3IgcGFyYW1ldGVycy5cbiAqL1xuZnVuY3Rpb24gcGFyc2VPcGVyYXRvclBhcmFtZXRlcnMoc3BlYywgY3R4KSB7XG4gIHZhciBvcCwgcGFyYW1zO1xuICBpZiAoc3BlYy5wYXJhbXMpIHtcbiAgICBpZiAoIShvcCA9IGN0eC5nZXQoc3BlYy5pZCkpKSB7XG4gICAgICBlcnJvciQxKCdJbnZhbGlkIG9wZXJhdG9yIGlkOiAnICsgc3BlYy5pZCk7XG4gICAgfVxuICAgIHBhcmFtcyA9IHBhcnNlUGFyYW1ldGVycyQxKHNwZWMucGFyYW1zLCBjdHgpO1xuICAgIGN0eC5kYXRhZmxvdy5jb25uZWN0KG9wLCBvcC5wYXJhbWV0ZXJzKHBhcmFtcykpO1xuICB9XG59XG5cbi8qKlxuICogUGFyc2UgYW4gZXZlbnQgc3RyZWFtIHNwZWNpZmljYXRpb24uXG4gKi9cbnZhciBwYXJzZVN0cmVhbSQzID0gZnVuY3Rpb24oc3BlYywgY3R4KSB7XG4gIHZhciBmaWx0ZXIgPSBzcGVjLmZpbHRlciAhPSBudWxsID8gZXZlbnRFeHByZXNzaW9uKHNwZWMuZmlsdGVyLCBjdHgpIDogdW5kZWZpbmVkLFxuICAgICAgc3RyZWFtID0gc3BlYy5zdHJlYW0gIT0gbnVsbCA/IGN0eC5nZXQoc3BlYy5zdHJlYW0pIDogdW5kZWZpbmVkLFxuICAgICAgYXJncztcblxuICBpZiAoc3BlYy5zb3VyY2UpIHtcbiAgICBzdHJlYW0gPSBjdHguZXZlbnRzKHNwZWMuc291cmNlLCBzcGVjLnR5cGUsIGZpbHRlcik7XG4gIH1cbiAgZWxzZSBpZiAoc3BlYy5tZXJnZSkge1xuICAgIGFyZ3MgPSBzcGVjLm1lcmdlLm1hcChjdHguZ2V0LmJpbmQoY3R4KSk7XG4gICAgc3RyZWFtID0gYXJnc1swXS5tZXJnZS5hcHBseShhcmdzWzBdLCBhcmdzLnNsaWNlKDEpKTtcbiAgfVxuXG4gIGlmIChzcGVjLmJldHdlZW4pIHtcbiAgICBhcmdzID0gc3BlYy5iZXR3ZWVuLm1hcChjdHguZ2V0LmJpbmQoY3R4KSk7XG4gICAgc3RyZWFtID0gc3RyZWFtLmJldHdlZW4oYXJnc1swXSwgYXJnc1sxXSk7XG4gIH1cblxuICBpZiAoc3BlYy5maWx0ZXIpIHtcbiAgICBzdHJlYW0gPSBzdHJlYW0uZmlsdGVyKGZpbHRlcik7XG4gIH1cblxuICBpZiAoc3BlYy50aHJvdHRsZSAhPSBudWxsKSB7XG4gICAgc3RyZWFtID0gc3RyZWFtLnRocm90dGxlKCtzcGVjLnRocm90dGxlKTtcbiAgfVxuXG4gIGlmIChzcGVjLmRlYm91bmNlICE9IG51bGwpIHtcbiAgICBzdHJlYW0gPSBzdHJlYW0uZGVib3VuY2UoK3NwZWMuZGVib3VuY2UpO1xuICB9XG5cbiAgaWYgKHN0cmVhbSA9PSBudWxsKSB7XG4gICAgZXJyb3IkMSgnSW52YWxpZCBzdHJlYW0gZGVmaW5pdGlvbjogJyArIEpTT04uc3RyaW5naWZ5KHNwZWMpKTtcbiAgfVxuXG4gIGlmIChzcGVjLmNvbnN1bWUpIHN0cmVhbS5jb25zdW1lKHRydWUpO1xuXG4gIGN0eC5zdHJlYW0oc3BlYywgc3RyZWFtKTtcbn07XG5cbi8qKlxuICogUGFyc2UgYW4gZXZlbnQtZHJpdmVuIG9wZXJhdG9yIHVwZGF0ZS5cbiAqL1xudmFyIHBhcnNlVXBkYXRlJDEgPSBmdW5jdGlvbihzcGVjLCBjdHgpIHtcbiAgdmFyIHNvdXJjZSA9IGN0eC5nZXQoc3BlYy5zb3VyY2UpLFxuICAgICAgdGFyZ2V0ID0gbnVsbCxcbiAgICAgIHVwZGF0ZSA9IHNwZWMudXBkYXRlLFxuICAgICAgcGFyYW1zID0gdW5kZWZpbmVkO1xuXG4gIGlmICghc291cmNlKSBlcnJvciQxKCdTb3VyY2Ugbm90IGRlZmluZWQ6ICcgKyBzcGVjLnNvdXJjZSk7XG5cbiAgaWYgKHNwZWMudGFyZ2V0ICYmIHNwZWMudGFyZ2V0LiRleHByKSB7XG4gICAgdGFyZ2V0ID0gZXZlbnRFeHByZXNzaW9uKHNwZWMudGFyZ2V0LiRleHByLCBjdHgpO1xuICB9IGVsc2Uge1xuICAgIHRhcmdldCA9IGN0eC5nZXQoc3BlYy50YXJnZXQpO1xuICB9XG5cbiAgaWYgKHVwZGF0ZSAmJiB1cGRhdGUuJGV4cHIpIHtcbiAgICBpZiAodXBkYXRlLiRwYXJhbXMpIHtcbiAgICAgIHBhcmFtcyA9IHBhcnNlUGFyYW1ldGVycyQxKHVwZGF0ZS4kcGFyYW1zLCBjdHgpO1xuICAgIH1cbiAgICB1cGRhdGUgPSBoYW5kbGVyRXhwcmVzc2lvbih1cGRhdGUuJGV4cHIsIGN0eCk7XG4gIH1cblxuICBjdHgudXBkYXRlKHNwZWMsIHNvdXJjZSwgdGFyZ2V0LCB1cGRhdGUsIHBhcmFtcyk7XG59O1xuXG4vKipcbiAqIFBhcnNlIGEgc2VyaWFsaXplZCBkYXRhZmxvdyBzcGVjaWZpY2F0aW9uLlxuICovXG52YXIgcGFyc2VEYXRhZmxvdyA9IGZ1bmN0aW9uKHNwZWMsIGN0eCkge1xuICB2YXIgb3BlcmF0b3JzID0gc3BlYy5vcGVyYXRvcnMgfHwgW107XG5cbiAgLy8gcGFyc2UgYmFja2dyb3VuZFxuICBpZiAoc3BlYy5iYWNrZ3JvdW5kKSB7XG4gICAgY3R4LmJhY2tncm91bmQgPSBzcGVjLmJhY2tncm91bmQ7XG4gIH1cblxuICAvLyBwYXJzZSBldmVudCBjb25maWd1cmF0aW9uXG4gIGlmIChzcGVjLmV2ZW50Q29uZmlnKSB7XG4gICAgY3R4LmV2ZW50Q29uZmlnID0gc3BlYy5ldmVudENvbmZpZztcbiAgfVxuXG4gIC8vIHBhcnNlIG9wZXJhdG9yc1xuICBvcGVyYXRvcnMuZm9yRWFjaChmdW5jdGlvbihlbnRyeSkge1xuICAgIHBhcnNlT3BlcmF0b3IoZW50cnksIGN0eCk7XG4gIH0pO1xuXG4gIC8vIHBhcnNlIG9wZXJhdG9yIHBhcmFtZXRlcnNcbiAgb3BlcmF0b3JzLmZvckVhY2goZnVuY3Rpb24oZW50cnkpIHtcbiAgICBwYXJzZU9wZXJhdG9yUGFyYW1ldGVycyhlbnRyeSwgY3R4KTtcbiAgfSk7XG5cbiAgLy8gcGFyc2Ugc3RyZWFtc1xuICAoc3BlYy5zdHJlYW1zIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgcGFyc2VTdHJlYW0kMyhlbnRyeSwgY3R4KTtcbiAgfSk7XG5cbiAgLy8gcGFyc2UgdXBkYXRlc1xuICAoc3BlYy51cGRhdGVzIHx8IFtdKS5mb3JFYWNoKGZ1bmN0aW9uKGVudHJ5KSB7XG4gICAgcGFyc2VVcGRhdGUkMShlbnRyeSwgY3R4KTtcbiAgfSk7XG5cbiAgcmV0dXJuIGN0eC5yZXNvbHZlKCk7XG59O1xuXG52YXIgU0tJUCQzID0ge3NraXA6IHRydWV9O1xuXG5mdW5jdGlvbiBnZXRTdGF0ZShvcHRpb25zKSB7XG4gIHZhciBjdHggPSB0aGlzLFxuICAgICAgc3RhdGUgPSB7fTtcblxuICBpZiAob3B0aW9ucy5zaWduYWxzKSB7XG4gICAgdmFyIHNpZ25hbHMgPSAoc3RhdGUuc2lnbmFscyA9IHt9KTtcbiAgICBPYmplY3Qua2V5cyhjdHguc2lnbmFscykuZm9yRWFjaChmdW5jdGlvbihrZXkkJDEpIHtcbiAgICAgIHZhciBvcCA9IGN0eC5zaWduYWxzW2tleSQkMV07XG4gICAgICBpZiAob3B0aW9ucy5zaWduYWxzKGtleSQkMSwgb3ApKSB7XG4gICAgICAgIHNpZ25hbHNba2V5JCQxXSA9IG9wLnZhbHVlO1xuICAgICAgfVxuICAgIH0pO1xuICB9XG5cbiAgaWYgKG9wdGlvbnMuZGF0YSkge1xuICAgIHZhciBkYXRhID0gKHN0YXRlLmRhdGEgPSB7fSk7XG4gICAgT2JqZWN0LmtleXMoY3R4LmRhdGEpLmZvckVhY2goZnVuY3Rpb24oa2V5JCQxKSB7XG4gICAgICB2YXIgZGF0YXNldCA9IGN0eC5kYXRhW2tleSQkMV07XG4gICAgICBpZiAob3B0aW9ucy5kYXRhKGtleSQkMSwgZGF0YXNldCkpIHtcbiAgICAgICAgZGF0YVtrZXkkJDFdID0gZGF0YXNldC5pbnB1dC52YWx1ZTtcbiAgICAgIH1cbiAgICB9KTtcbiAgfVxuXG4gIGlmIChjdHguc3ViY29udGV4dCAmJiBvcHRpb25zLnJlY3Vyc2UgIT09IGZhbHNlKSB7XG4gICAgc3RhdGUuc3ViY29udGV4dCA9IGN0eC5zdWJjb250ZXh0Lm1hcChmdW5jdGlvbihjdHgpIHtcbiAgICAgIHJldHVybiBjdHguZ2V0U3RhdGUob3B0aW9ucyk7XG4gICAgfSk7XG4gIH1cblxuICByZXR1cm4gc3RhdGU7XG59XG5cbmZ1bmN0aW9uIHNldFN0YXRlKHN0YXRlKSB7XG4gIHZhciBjdHggPSB0aGlzLFxuICAgICAgZGYgPSBjdHguZGF0YWZsb3csXG4gICAgICBkYXRhID0gc3RhdGUuZGF0YSxcbiAgICAgIHNpZ25hbHMgPSBzdGF0ZS5zaWduYWxzO1xuXG4gIE9iamVjdC5rZXlzKHNpZ25hbHMgfHwge30pLmZvckVhY2goZnVuY3Rpb24oa2V5JCQxKSB7XG4gICAgZGYudXBkYXRlKGN0eC5zaWduYWxzW2tleSQkMV0sIHNpZ25hbHNba2V5JCQxXSwgU0tJUCQzKTtcbiAgfSk7XG5cbiAgT2JqZWN0LmtleXMoZGF0YSB8fCB7fSkuZm9yRWFjaChmdW5jdGlvbihrZXkkJDEpIHtcbiAgICBkZi5wdWxzZShcbiAgICAgIGN0eC5kYXRhW2tleSQkMV0uaW5wdXQsXG4gICAgICBkZi5jaGFuZ2VzZXQoKS5yZW1vdmUodHJ1dGh5KS5pbnNlcnQoZGF0YVtrZXkkJDFdKVxuICAgICk7XG4gIH0pO1xuXG4gIChzdGF0ZS5zdWJjb250ZXh0ICB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihzdWJzdGF0ZSwgaSkge1xuICAgIHZhciBzdWJjdHggPSBjdHguc3ViY29udGV4dFtpXTtcbiAgICBpZiAoc3ViY3R4KSBzdWJjdHguc2V0U3RhdGUoc3Vic3RhdGUpO1xuICB9KTtcbn1cblxuLyoqXG4gKiBDb250ZXh0IG9iamVjdHMgc3RvcmUgdGhlIGN1cnJlbnQgcGFyc2Ugc3RhdGUuXG4gKiBFbmFibGVzIGxvb2t1cCBvZiBwYXJzZWQgb3BlcmF0b3JzLCBldmVudCBzdHJlYW1zLCBhY2Nlc3NvcnMsIGV0Yy5cbiAqIFByb3ZpZGVzIGEgJ2ZvcmsnIG1ldGhvZCBmb3IgY3JlYXRpbmcgY2hpbGQgY29udGV4dHMgZm9yIHN1YmZsb3dzLlxuICovXG52YXIgY29udGV4dCQyID0gZnVuY3Rpb24oZGYsIHRyYW5zZm9ybXMsIGZ1bmN0aW9ucykge1xuICByZXR1cm4gbmV3IENvbnRleHQoZGYsIHRyYW5zZm9ybXMsIGZ1bmN0aW9ucyk7XG59O1xuXG5mdW5jdGlvbiBDb250ZXh0KGRmLCB0cmFuc2Zvcm1zLCBmdW5jdGlvbnMpIHtcbiAgdGhpcy5kYXRhZmxvdyA9IGRmO1xuICB0aGlzLnRyYW5zZm9ybXMgPSB0cmFuc2Zvcm1zO1xuICB0aGlzLmV2ZW50cyA9IGRmLmV2ZW50cy5iaW5kKGRmKTtcbiAgdGhpcy5zaWduYWxzID0ge307XG4gIHRoaXMuc2NhbGVzID0ge307XG4gIHRoaXMubm9kZXMgPSB7fTtcbiAgdGhpcy5kYXRhID0ge307XG4gIHRoaXMuZm4gPSB7fTtcbiAgaWYgKGZ1bmN0aW9ucykge1xuICAgIHRoaXMuZnVuY3Rpb25zID0gT2JqZWN0LmNyZWF0ZShmdW5jdGlvbnMpO1xuICAgIHRoaXMuZnVuY3Rpb25zLmNvbnRleHQgPSB0aGlzO1xuICB9XG59XG5cbmZ1bmN0aW9uIENvbnRleHRGb3JrKGN0eCkge1xuICB0aGlzLmRhdGFmbG93ID0gY3R4LmRhdGFmbG93O1xuICB0aGlzLnRyYW5zZm9ybXMgPSBjdHgudHJhbnNmb3JtcztcbiAgdGhpcy5mdW5jdGlvbnMgPSBjdHguZnVuY3Rpb25zO1xuICB0aGlzLmV2ZW50cyA9IGN0eC5ldmVudHM7XG4gIHRoaXMuc2lnbmFscyA9IE9iamVjdC5jcmVhdGUoY3R4LnNpZ25hbHMpO1xuICB0aGlzLnNjYWxlcyA9IE9iamVjdC5jcmVhdGUoY3R4LnNjYWxlcyk7XG4gIHRoaXMubm9kZXMgPSBPYmplY3QuY3JlYXRlKGN0eC5ub2Rlcyk7XG4gIHRoaXMuZGF0YSA9IE9iamVjdC5jcmVhdGUoY3R4LmRhdGEpO1xuICB0aGlzLmZuID0gT2JqZWN0LmNyZWF0ZShjdHguZm4pO1xuICBpZiAoY3R4LmZ1bmN0aW9ucykge1xuICAgIHRoaXMuZnVuY3Rpb25zID0gT2JqZWN0LmNyZWF0ZShjdHguZnVuY3Rpb25zKTtcbiAgICB0aGlzLmZ1bmN0aW9ucy5jb250ZXh0ID0gdGhpcztcbiAgfVxufVxuXG5Db250ZXh0LnByb3RvdHlwZSA9IENvbnRleHRGb3JrLnByb3RvdHlwZSA9IHtcbiAgZm9yazogZnVuY3Rpb24oKSB7XG4gICAgdmFyIGN0eCA9IG5ldyBDb250ZXh0Rm9yayh0aGlzKTtcbiAgICAodGhpcy5zdWJjb250ZXh0IHx8ICh0aGlzLnN1YmNvbnRleHQgPSBbXSkpLnB1c2goY3R4KTtcbiAgICByZXR1cm4gY3R4O1xuICB9LFxuICBnZXQ6IGZ1bmN0aW9uKGlkKSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZXNbaWRdO1xuICB9LFxuICBzZXQ6IGZ1bmN0aW9uKGlkLCBub2RlKSB7XG4gICAgcmV0dXJuIHRoaXMubm9kZXNbaWRdID0gbm9kZTtcbiAgfSxcbiAgYWRkOiBmdW5jdGlvbihzcGVjLCBvcCkge1xuICAgIHZhciBjdHggPSB0aGlzLFxuICAgICAgICBkZiA9IGN0eC5kYXRhZmxvdyxcbiAgICAgICAgZGF0YTtcblxuICAgIGN0eC5zZXQoc3BlYy5pZCwgb3ApO1xuXG4gICAgaWYgKGlzQ29sbGVjdChzcGVjLnR5cGUpICYmIChkYXRhID0gc3BlYy52YWx1ZSkpIHtcbiAgICAgIGlmIChkYXRhLiRpbmdlc3QpIHtcbiAgICAgICAgZGYuaW5nZXN0KG9wLCBkYXRhLiRpbmdlc3QsIGRhdGEuJGZvcm1hdCk7XG4gICAgICB9IGVsc2UgaWYgKGRhdGEuJHJlcXVlc3QpIHtcbiAgICAgICAgZGYucmVxdWVzdChvcCwgZGF0YS4kcmVxdWVzdCwgZGF0YS4kZm9ybWF0KTtcbiAgICAgIH0gZWxzZSB7XG4gICAgICAgIGRmLnB1bHNlKG9wLCBkZi5jaGFuZ2VzZXQoKS5pbnNlcnQoZGF0YSkpO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChzcGVjLnJvb3QpIHtcbiAgICAgIGN0eC5yb290ID0gb3A7XG4gICAgfVxuXG4gICAgaWYgKHNwZWMucGFyZW50KSB7XG4gICAgICB2YXIgcCA9IGN0eC5nZXQoc3BlYy5wYXJlbnQuJHJlZik7XG4gICAgICBpZiAocCkge1xuICAgICAgICBkZi5jb25uZWN0KHAsIFtvcF0pO1xuICAgICAgICBvcC50YXJnZXRzKCkuYWRkKHApO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgKGN0eC51bnJlc29sdmVkID0gY3R4LnVucmVzb2x2ZWQgfHwgW10pLnB1c2goZnVuY3Rpb24oKSB7XG4gICAgICAgICAgcCA9IGN0eC5nZXQoc3BlYy5wYXJlbnQuJHJlZik7XG4gICAgICAgICAgZGYuY29ubmVjdChwLCBbb3BdKTtcbiAgICAgICAgICBvcC50YXJnZXRzKCkuYWRkKHApO1xuICAgICAgICB9KTtcbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAoc3BlYy5zaWduYWwpIHtcbiAgICAgIGN0eC5zaWduYWxzW3NwZWMuc2lnbmFsXSA9IG9wO1xuICAgIH1cblxuICAgIGlmIChzcGVjLnNjYWxlKSB7XG4gICAgICBjdHguc2NhbGVzW3NwZWMuc2NhbGVdID0gb3A7XG4gICAgfVxuXG4gICAgaWYgKHNwZWMuZGF0YSkge1xuICAgICAgZm9yICh2YXIgbmFtZSBpbiBzcGVjLmRhdGEpIHtcbiAgICAgICAgZGF0YSA9IGN0eC5kYXRhW25hbWVdIHx8IChjdHguZGF0YVtuYW1lXSA9IHt9KTtcbiAgICAgICAgc3BlYy5kYXRhW25hbWVdLmZvckVhY2goZnVuY3Rpb24ocm9sZSkgeyBkYXRhW3JvbGVdID0gb3A7IH0pO1xuICAgICAgfVxuICAgIH1cbiAgfSxcbiAgcmVzb2x2ZTogZnVuY3Rpb24oKSB7XG4gICAgKHRoaXMudW5yZXNvbHZlZCB8fCBbXSkuZm9yRWFjaChmdW5jdGlvbihmbikgeyBmbigpOyB9KTtcbiAgICBkZWxldGUgdGhpcy51bnJlc29sdmVkO1xuICAgIHJldHVybiB0aGlzO1xuICB9LFxuICBvcGVyYXRvcjogZnVuY3Rpb24oc3BlYywgdXBkYXRlLCBwYXJhbXMpIHtcbiAgICB0aGlzLmFkZChzcGVjLCB0aGlzLmRhdGFmbG93LmFkZChzcGVjLnZhbHVlLCB1cGRhdGUsIHBhcmFtcywgc3BlYy5yZWFjdCkpO1xuICB9LFxuICB0cmFuc2Zvcm06IGZ1bmN0aW9uKHNwZWMsIHR5cGUsIHBhcmFtcykge1xuICAgIHRoaXMuYWRkKHNwZWMsIHRoaXMuZGF0YWZsb3cuYWRkKHRoaXMudHJhbnNmb3Jtc1tjYW5vbmljYWxUeXBlKHR5cGUpXSwgcGFyYW1zKSk7XG4gIH0sXG4gIHN0cmVhbTogZnVuY3Rpb24oc3BlYywgc3RyZWFtKSB7XG4gICAgdGhpcy5zZXQoc3BlYy5pZCwgc3RyZWFtKTtcbiAgfSxcbiAgdXBkYXRlOiBmdW5jdGlvbihzcGVjLCBzdHJlYW0sIHRhcmdldCwgdXBkYXRlLCBwYXJhbXMpIHtcbiAgICB0aGlzLmRhdGFmbG93Lm9uKHN0cmVhbSwgdGFyZ2V0LCB1cGRhdGUsIHBhcmFtcywgc3BlYy5vcHRpb25zKTtcbiAgfSxcbiAgZ2V0U3RhdGU6IGdldFN0YXRlLFxuICBzZXRTdGF0ZTogc2V0U3RhdGVcbn07XG5cbnZhciBydW50aW1lID0gZnVuY3Rpb24odmlldywgc3BlYywgZnVuY3Rpb25zKSB7XG4gIHZhciBmbiA9IGZ1bmN0aW9ucyB8fCBmdW5jdGlvbkNvbnRleHQ7XG4gIHJldHVybiBwYXJzZURhdGFmbG93KHNwZWMsIGNvbnRleHQkMih2aWV3LCB0cmFuc2Zvcm1zLCBmbikpO1xufTtcblxudmFyIFBhZGRpbmckMSA9ICdwYWRkaW5nJztcblxuZnVuY3Rpb24gdmlld1dpZHRoKHZpZXcsIHdpZHRoKSB7XG4gIHZhciBhID0gdmlldy5hdXRvc2l6ZSgpLFxuICAgICAgcCA9IHZpZXcucGFkZGluZygpO1xuICByZXR1cm4gd2lkdGggLSAoYSAmJiBhLmNvbnRhaW5zID09PSBQYWRkaW5nJDEgPyBwLmxlZnQgKyBwLnJpZ2h0IDogMCk7XG59XG5cbmZ1bmN0aW9uIHZpZXdIZWlnaHQodmlldywgaGVpZ2h0KSB7XG4gIHZhciBhID0gdmlldy5hdXRvc2l6ZSgpLFxuICAgICAgcCA9IHZpZXcucGFkZGluZygpO1xuICByZXR1cm4gaGVpZ2h0IC0gKGEgJiYgYS5jb250YWlucyA9PT0gUGFkZGluZyQxID8gcC50b3AgKyBwLmJvdHRvbSA6IDApO1xufVxuXG5mdW5jdGlvbiBpbml0aWFsaXplUmVzaXplKHZpZXcpIHtcbiAgdmFyIHMgPSB2aWV3Ll9zaWduYWxzLFxuICAgICAgdyA9IHMud2lkdGgsXG4gICAgICBoID0gcy5oZWlnaHQsXG4gICAgICBwID0gcy5wYWRkaW5nO1xuXG4gIGZ1bmN0aW9uIHJlc2V0U2l6ZSgpIHtcbiAgICB2aWV3Ll9hdXRvc2l6ZSA9IHZpZXcuX3Jlc2l6ZSA9IDE7XG4gIH1cblxuICAvLyByZXNwb25kIHRvIHdpZHRoIHNpZ25hbFxuICB2aWV3Ll9yZXNpemVXaWR0aCA9IHZpZXcuYWRkKG51bGwsXG4gICAgZnVuY3Rpb24oXykge1xuICAgICAgdmlldy5fd2lkdGggPSBfLnNpemU7XG4gICAgICB2aWV3Ll92aWV3V2lkdGggPSB2aWV3V2lkdGgodmlldywgXy5zaXplKTtcbiAgICAgIHJlc2V0U2l6ZSgpO1xuICAgIH0sXG4gICAge3NpemU6IHd9XG4gICk7XG5cbiAgLy8gcmVzcG9uZCB0byBoZWlnaHQgc2lnbmFsXG4gIHZpZXcuX3Jlc2l6ZUhlaWdodCA9IHZpZXcuYWRkKG51bGwsXG4gICAgZnVuY3Rpb24oXykge1xuICAgICAgdmlldy5faGVpZ2h0ID0gXy5zaXplO1xuICAgICAgdmlldy5fdmlld0hlaWdodCA9IHZpZXdIZWlnaHQodmlldywgXy5zaXplKTtcbiAgICAgIHJlc2V0U2l6ZSgpO1xuICAgIH0sXG4gICAge3NpemU6IGh9XG4gICk7XG5cbiAgLy8gcmVzcG9uZCB0byBwYWRkaW5nIHNpZ25hbFxuICB2YXIgcmVzaXplUGFkZGluZyA9IHZpZXcuYWRkKG51bGwsIHJlc2V0U2l6ZSwge3BhZDogcH0pO1xuXG4gIC8vIHNldCByYW5rIHRvIHJ1biBpbW1lZGlhdGVseSBhZnRlciBzb3VyY2Ugc2lnbmFsXG4gIHZpZXcuX3Jlc2l6ZVdpZHRoLnJhbmsgPSB3LnJhbmsgKyAxO1xuICB2aWV3Ll9yZXNpemVIZWlnaHQucmFuayA9IGgucmFuayArIDE7XG4gIHJlc2l6ZVBhZGRpbmcucmFuayA9IHAucmFuayArIDE7XG59XG5cbmZ1bmN0aW9uIHJlc2l6ZVZpZXcodmlld1dpZHRoLCB2aWV3SGVpZ2h0LCB3aWR0aCwgaGVpZ2h0LCBvcmlnaW4sIGF1dG8pIHtcbiAgdGhpcy5ydW5BZnRlcihmdW5jdGlvbih2aWV3KSB7XG4gICAgdmFyIHJlcnVuID0gMDtcblxuICAgIC8vIHJlc2V0IGF1dG9zaXplIGZsYWdcbiAgICB2aWV3Ll9hdXRvc2l6ZSA9IDA7XG5cbiAgICAvLyB3aWR0aCB2YWx1ZSBjaGFuZ2VkOiB1cGRhdGUgc2lnbmFsLCBza2lwIHJlc2l6ZSBvcFxuICAgIGlmICh2aWV3LndpZHRoKCkgIT09IHdpZHRoKSB7XG4gICAgICByZXJ1biA9IDE7XG4gICAgICB2aWV3LndpZHRoKHdpZHRoKTtcbiAgICAgIHZpZXcuX3Jlc2l6ZVdpZHRoLnNraXAodHJ1ZSk7XG4gICAgfVxuXG4gICAgLy8gaGVpZ2h0IHZhbHVlIGNoYW5nZWQ6IHVwZGF0ZSBzaWduYWwsIHNraXAgcmVzaXplIG9wXG4gICAgaWYgKHZpZXcuaGVpZ2h0KCkgIT09IGhlaWdodCkge1xuICAgICAgcmVydW4gPSAxO1xuICAgICAgdmlldy5oZWlnaHQoaGVpZ2h0KTtcbiAgICAgIHZpZXcuX3Jlc2l6ZUhlaWdodC5za2lwKHRydWUpO1xuICAgIH1cblxuICAgIC8vIHZpZXcgd2lkdGggY2hhbmdlZDogdXBkYXRlIHZpZXcgcHJvcGVydHksIHNldCByZXNpemUgZmxhZ1xuICAgIGlmICh2aWV3Ll92aWV3V2lkdGggIT09IHZpZXdXaWR0aCkge1xuICAgICAgdmlldy5fcmVzaXplID0gMTtcbiAgICAgIHZpZXcuX3ZpZXdXaWR0aCA9IHZpZXdXaWR0aDtcbiAgICB9XG5cbiAgICAvLyB2aWV3IGhlaWdodCBjaGFuZ2VkOiB1cGRhdGUgdmlldyBwcm9wZXJ0eSwgc2V0IHJlc2l6ZSBmbGFnXG4gICAgaWYgKHZpZXcuX3ZpZXdIZWlnaHQgIT09IHZpZXdIZWlnaHQpIHtcbiAgICAgIHZpZXcuX3Jlc2l6ZSA9IDE7XG4gICAgICB2aWV3Ll92aWV3SGVpZ2h0ID0gdmlld0hlaWdodDtcbiAgICB9XG5cbiAgICAvLyBvcmlnaW4gY2hhbmdlZDogdXBkYXRlIHZpZXcgcHJvcGVydHksIHNldCByZXNpemUgZmxhZ1xuICAgIGlmICh2aWV3Ll9vcmlnaW5bMF0gIT09IG9yaWdpblswXSB8fCB2aWV3Ll9vcmlnaW5bMV0gIT09IG9yaWdpblsxXSkge1xuICAgICAgdmlldy5fcmVzaXplID0gMTtcbiAgICAgIHZpZXcuX29yaWdpbiA9IG9yaWdpbjtcbiAgICB9XG5cbiAgICAvLyBydW4gZGF0YWZsb3cgb24gd2lkdGgvaGVpZ2h0IHNpZ25hbCBjaGFuZ2VcbiAgICBpZiAocmVydW4pIHZpZXcucnVuKCdlbnRlcicpO1xuICAgIGlmIChhdXRvKSB2aWV3LnJ1bkFmdGVyKGZ1bmN0aW9uKCkgeyB2aWV3LnJlc2l6ZSgpOyB9KTtcbiAgfSwgZmFsc2UsIDEpO1xufVxuXG4vKipcbiAqIEdldCB0aGUgY3VycmVudCB2aWV3IHN0YXRlLCBjb25zaXN0aW5nIG9mIHNpZ25hbCB2YWx1ZXMgYW5kL29yIGRhdGEgc2V0cy5cbiAqIEBwYXJhbSB7b2JqZWN0fSBbb3B0aW9uc10gLSBPcHRpb25zIGZsYWdzIGluZGljYXRpbmcgd2hpY2ggc3RhdGUgdG8gZXhwb3J0LlxuICogICBJZiB1bnNwZWNpZmllZCwgYWxsIHNpZ25hbHMgYW5kIGRhdGEgc2V0cyB3aWxsIGJlIGV4cG9ydGVkLlxuICogQHBhcmFtIHtmdW5jdGlvbihzdHJpbmcsIE9wZXJhdG9yKTpib29sZWFufSBbb3B0aW9ucy5zaWduYWxzXSAtIE9wdGlvbmFsXG4gKiAgIHByZWRpY2F0ZSBmdW5jdGlvbiBmb3IgdGVzdGluZyBpZiBhIHNpZ25hbCBzaG91bGQgYmUgaW5jbHVkZWQgaW4gdGhlXG4gKiAgIGV4cG9ydGVkIHN0YXRlLiBJZiB1bnNwZWNpZmllZCwgYWxsIHNpZ25hbHMgd2lsbCBiZSBpbmNsdWRlZCwgZXhjZXB0IGZvclxuICogICB0aG9zZSBuYW1lZCAncGFyZW50JyBvciB0aG9zZSB3aGljaCByZWZlciB0byBhIFRyYW5zZm9ybSB2YWx1ZS5cbiAqIEBwYXJhbSB7ZnVuY3Rpb24oc3RyaW5nLCBvYmplY3QpOmJvb2xlYW59IFtvcHRpb25zLmRhdGFdIC0gT3B0aW9uYWxcbiAqICAgcHJlZGljYXRlIGZ1bmN0aW9uIGZvciB0ZXN0aW5nIGlmIGEgZGF0YSBzZXQncyBpbnB1dCBzaG91bGQgYmUgaW5jbHVkZWRcbiAqICAgaW4gdGhlIGV4cG9ydGVkIHN0YXRlLiBJZiB1bnNwZWNpZmllZCwgYWxsIGRhdGEgc2V0cyB0aGF0IGhhdmUgYmVlblxuICogICBleHBsaWNpdGx5IG1vZGlmaWVkIHdpbGwgYmUgaW5jbHVkZWQuXG4gKiBAcGFyYW0ge2Jvb2xlYW59IFtvcHRpb25zLnJlY3Vyc2U9dHJ1ZV0gLSBGbGFnIGluZGljYXRpbmcgaWYgdGhlIGV4cG9ydGVkXG4gKiAgIHN0YXRlIHNob3VsZCByZWN1cnNpdmVseSBpbmNsdWRlIHN0YXRlIGZyb20gZ3JvdXAgbWFyayBzdWItY29udGV4dHMuXG4gKiBAcmV0dXJuIHtvYmplY3R9IC0gQW4gb2JqZWN0IGNvbnRhaW5pbmcgdGhlIGV4cG9ydGVkIHN0YXRlIHZhbHVlcy5cbiAqL1xuZnVuY3Rpb24gZ2V0U3RhdGUkMShvcHRpb25zKSB7XG4gIHJldHVybiB0aGlzLl9ydW50aW1lLmdldFN0YXRlKG9wdGlvbnMgfHwge1xuICAgIGRhdGE6ICAgIGRhdGFUZXN0LFxuICAgIHNpZ25hbHM6IHNpZ25hbFRlc3QsXG4gICAgcmVjdXJzZTogdHJ1ZVxuICB9KTtcbn1cblxuZnVuY3Rpb24gZGF0YVRlc3QobmFtZSwgZGF0YSkge1xuICByZXR1cm4gZGF0YS5tb2RpZmllZFxuICAgICAgJiYgaXNBcnJheShkYXRhLmlucHV0LnZhbHVlKVxuICAgICAgJiYgbmFtZS5pbmRleE9mKCdfOnZlZ2E6XycpO1xufVxuXG5mdW5jdGlvbiBzaWduYWxUZXN0KG5hbWUsIG9wKSB7XG4gIHJldHVybiAhKG5hbWUgPT09ICdwYXJlbnQnIHx8IG9wIGluc3RhbmNlb2YgdHJhbnNmb3Jtcy5wcm94eSk7XG59XG5cbi8qKlxuICogU2V0cyB0aGUgY3VycmVudCB2aWV3IHN0YXRlIGFuZCB1cGRhdGVzIHRoZSB2aWV3IGJ5IGludm9raW5nIHJ1bi5cbiAqIEBwYXJhbSB7b2JqZWN0fSBzdGF0ZSAtIEEgc3RhdGUgb2JqZWN0IGNvbnRhaW5pbmcgc2lnbmFsIGFuZC9vclxuICogICBkYXRhIHNldCB2YWx1ZXMsIGZvbGxvd2luZyB0aGUgZm9ybWF0IHVzZWQgYnkgdGhlIGdldFN0YXRlIG1ldGhvZC5cbiAqIEByZXR1cm4ge1ZpZXd9IC0gVGhpcyB2aWV3IGluc3RhbmNlLlxuICovXG5mdW5jdGlvbiBzZXRTdGF0ZSQxKHN0YXRlKSB7XG4gIHZhciB2aWV3ID0gdGhpcztcbiAgdmlldy5ydW5BZnRlcihmdW5jdGlvbigpIHtcbiAgICB2aWV3Ll90cmlnZ2VyID0gZmFsc2U7XG4gICAgdmlldy5fcnVudGltZS5zZXRTdGF0ZShzdGF0ZSk7XG4gICAgdmlldy5ydW4oKS5ydW5BZnRlcihmdW5jdGlvbigpIHsgdmlldy5fdHJpZ2dlciA9IHRydWU7IH0pO1xuICB9KTtcbiAgcmV0dXJuIHRoaXM7XG59XG5cbi8qKlxuICogQ3JlYXRlIGEgbmV3IFZpZXcgaW5zdGFuY2UgZnJvbSBhIFZlZ2EgZGF0YWZsb3cgcnVudGltZSBzcGVjaWZpY2F0aW9uLlxuICogVGhlIGdlbmVyYXRlZCBWaWV3IHdpbGwgbm90IGltbWVkaWF0ZWx5IGJlIHJlYWR5IGZvciBkaXNwbGF5LiBDYWxsZXJzXG4gKiBzaG91bGQgYWxzbyBpbnZva2UgdGhlIGluaXRpYWxpemUgbWV0aG9kIChlLmcuLCB0byBzZXQgdGhlIHBhcmVudFxuICogRE9NIGVsZW1lbnQgaW4gYnJvd3Nlci1iYXNlZCBkZXBsb3ltZW50KSBhbmQgdGhlbiBpbnZva2UgdGhlIHJ1blxuICogbWV0aG9kIHRvIGV2YWx1YXRlIHRoZSBkYXRhZmxvdyBncmFwaC4gUmVuZGVyaW5nIHdpbGwgYXV0b21hdGljYWxseVxuICogYmUgcGVmb3JtZWQgdXBvbiBkYXRhZmxvdyBydW5zLlxuICogQGNvbnN0cnVjdG9yXG4gKiBAcGFyYW0ge29iamVjdH0gc3BlYyAtIFRoZSBWZWdhIGRhdGFmbG93IHJ1bnRpbWUgc3BlY2lmaWNhdGlvbi5cbiAqL1xuZnVuY3Rpb24gVmlldyhzcGVjLCBvcHRpb25zKSB7XG4gIHZhciB2aWV3ID0gdGhpcztcbiAgb3B0aW9ucyA9IG9wdGlvbnMgfHwge307XG5cbiAgRGF0YWZsb3cuY2FsbCh2aWV3KTtcbiAgdmlldy5sb2FkZXIob3B0aW9ucy5sb2FkZXIgfHwgdmlldy5fbG9hZGVyKTtcbiAgdmlldy5sb2dMZXZlbChvcHRpb25zLmxvZ0xldmVsIHx8IDApO1xuXG4gIHZpZXcuX2VsID0gbnVsbDtcbiAgdmlldy5fcmVuZGVyVHlwZSA9IG9wdGlvbnMucmVuZGVyZXIgfHwgUmVuZGVyVHlwZS5DYW52YXM7XG4gIHZpZXcuX3NjZW5lZ3JhcGggPSBuZXcgU2NlbmVncmFwaCgpO1xuICB2YXIgcm9vdCA9IHZpZXcuX3NjZW5lZ3JhcGgucm9vdDtcblxuICAvLyBpbml0aWFsaXplIHJlbmRlcmVyLCBoYW5kbGVyIGFuZCBldmVudCBtYW5hZ2VtZW50XG4gIHZpZXcuX3JlbmRlcmVyID0gbnVsbDtcbiAgdmlldy5fcmVkcmF3ID0gdHJ1ZTtcbiAgdmlldy5faGFuZGxlciA9IG5ldyBDYW52YXNIYW5kbGVyKCkuc2NlbmUocm9vdCk7XG4gIHZpZXcuX3ByZXZlbnREZWZhdWx0ID0gZmFsc2U7XG4gIHZpZXcuX2V2ZW50TGlzdGVuZXJzID0gW107XG4gIHZpZXcuX3Jlc2l6ZUxpc3RlbmVycyA9IFtdO1xuXG4gIC8vIGluaXRpYWxpemUgZGF0YWZsb3cgZ3JhcGhcbiAgdmFyIGN0eCA9IHJ1bnRpbWUodmlldywgc3BlYywgb3B0aW9ucy5mdW5jdGlvbnMpO1xuICB2aWV3Ll9ydW50aW1lID0gY3R4O1xuICB2aWV3Ll9zaWduYWxzID0gY3R4LnNpZ25hbHM7XG4gIHZpZXcuX2JpbmQgPSAoc3BlYy5iaW5kaW5ncyB8fCBbXSkubWFwKGZ1bmN0aW9uKF8pIHtcbiAgICByZXR1cm4ge1xuICAgICAgc3RhdGU6IG51bGwsXG4gICAgICBwYXJhbTogZXh0ZW5kKHt9LCBfKVxuICAgIH07XG4gIH0pO1xuXG4gIC8vIGluaXRpYWxpemUgc2NlbmVncmFwaFxuICBpZiAoY3R4LnJvb3QpIGN0eC5yb290LnNldChyb290KTtcbiAgcm9vdC5zb3VyY2UgPSBjdHguZGF0YS5yb290LmlucHV0O1xuICB2aWV3LnB1bHNlKFxuICAgIGN0eC5kYXRhLnJvb3QuaW5wdXQsXG4gICAgdmlldy5jaGFuZ2VzZXQoKS5pbnNlcnQocm9vdC5pdGVtcylcbiAgKTtcblxuICAvLyBpbml0aWFsaXplIGJhY2tncm91bmQgY29sb3JcbiAgdmlldy5fYmFja2dyb3VuZCA9IGN0eC5iYWNrZ3JvdW5kIHx8IG51bGw7XG5cbiAgLy8gaW5pdGlhbGl6ZSBldmVudCBjb25maWd1cmF0aW9uXG4gIHZpZXcuX2V2ZW50Q29uZmlnID0gaW5pdGlhbGl6ZUV2ZW50Q29uZmlnKGN0eC5ldmVudENvbmZpZyk7XG5cbiAgLy8gaW5pdGlhbGl6ZSB2aWV3IHNpemVcbiAgdmlldy5fd2lkdGggPSB2aWV3LndpZHRoKCk7XG4gIHZpZXcuX2hlaWdodCA9IHZpZXcuaGVpZ2h0KCk7XG4gIHZpZXcuX3ZpZXdXaWR0aCA9IHZpZXdXaWR0aCh2aWV3LCB2aWV3Ll93aWR0aCk7XG4gIHZpZXcuX3ZpZXdIZWlnaHQgPSB2aWV3SGVpZ2h0KHZpZXcsIHZpZXcuX2hlaWdodCk7XG4gIHZpZXcuX29yaWdpbiA9IFswLCAwXTtcbiAgdmlldy5fcmVzaXplID0gMDtcbiAgdmlldy5fYXV0b3NpemUgPSAxO1xuICBpbml0aWFsaXplUmVzaXplKHZpZXcpO1xuXG4gIC8vIGluaXRpYWxpemUgY3Vyc29yXG4gIGN1cnNvcih2aWV3KTtcbn1cblxudmFyIHByb3RvdHlwZSQ4MyA9IGluaGVyaXRzKFZpZXcsIERhdGFmbG93KTtcblxuLy8gLS0gREFUQUZMT1cgLyBSRU5ERVJJTkcgLS0tLVxuXG5wcm90b3R5cGUkODMucnVuID0gZnVuY3Rpb24oZW5jb2RlKSB7XG4gIERhdGFmbG93LnByb3RvdHlwZS5ydW4uY2FsbCh0aGlzLCBlbmNvZGUpO1xuICBpZiAodGhpcy5fcmVkcmF3IHx8IHRoaXMuX3Jlc2l6ZSkge1xuICAgIHRyeSB7XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH0gY2F0Y2ggKGUpIHtcbiAgICAgIHRoaXMuZXJyb3IoZSk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDgzLnJlbmRlciA9IGZ1bmN0aW9uKCkge1xuICBpZiAodGhpcy5fcmVuZGVyZXIpIHtcbiAgICBpZiAodGhpcy5fcmVzaXplKSB7XG4gICAgICB0aGlzLl9yZXNpemUgPSAwO1xuICAgICAgcmVzaXplUmVuZGVyZXIodGhpcyk7XG4gICAgfVxuICAgIHRoaXMuX3JlbmRlcmVyLnJlbmRlcih0aGlzLl9zY2VuZWdyYXBoLnJvb3QpO1xuICB9XG4gIHRoaXMuX3JlZHJhdyA9IGZhbHNlO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ4My5kaXJ0eSA9IGZ1bmN0aW9uKGl0ZW0pIHtcbiAgdGhpcy5fcmVkcmF3ID0gdHJ1ZTtcbiAgdGhpcy5fcmVuZGVyZXIgJiYgdGhpcy5fcmVuZGVyZXIuZGlydHkoaXRlbSk7XG59O1xuXG4vLyAtLSBHRVQgLyBTRVQgLS0tLVxuXG5wcm90b3R5cGUkODMuY29udGFpbmVyID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9lbDtcbn07XG5cbnByb3RvdHlwZSQ4My5zY2VuZWdyYXBoID0gZnVuY3Rpb24oKSB7XG4gIHJldHVybiB0aGlzLl9zY2VuZWdyYXBoO1xufTtcblxuZnVuY3Rpb24gbG9va3VwU2lnbmFsKHZpZXcsIG5hbWUpIHtcbiAgcmV0dXJuIHZpZXcuX3NpZ25hbHMuaGFzT3duUHJvcGVydHkobmFtZSlcbiAgICA/IHZpZXcuX3NpZ25hbHNbbmFtZV1cbiAgICA6IGVycm9yJDEoJ1VucmVjb2duaXplZCBzaWduYWwgbmFtZTogJyArICQobmFtZSkpO1xufVxuXG5wcm90b3R5cGUkODMuc2lnbmFsID0gZnVuY3Rpb24obmFtZSwgdmFsdWUsIG9wdGlvbnMpIHtcbiAgdmFyIG9wID0gbG9va3VwU2lnbmFsKHRoaXMsIG5hbWUpO1xuICByZXR1cm4gYXJndW1lbnRzLmxlbmd0aCA9PT0gMVxuICAgID8gb3AudmFsdWVcbiAgICA6IHRoaXMudXBkYXRlKG9wLCB2YWx1ZSwgb3B0aW9ucyk7XG59O1xuXG5wcm90b3R5cGUkODMuYmFja2dyb3VuZCA9IGZ1bmN0aW9uKF8pIHtcbiAgaWYgKGFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICB0aGlzLl9iYWNrZ3JvdW5kID0gXztcbiAgICB0aGlzLl9yZXNpemUgPSAxO1xuICAgIHJldHVybiB0aGlzO1xuICB9IGVsc2Uge1xuICAgIHJldHVybiB0aGlzLl9iYWNrZ3JvdW5kO1xuICB9XG59O1xuXG5wcm90b3R5cGUkODMud2lkdGggPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy5zaWduYWwoJ3dpZHRoJywgXykgOiB0aGlzLnNpZ25hbCgnd2lkdGgnKTtcbn07XG5cbnByb3RvdHlwZSQ4My5oZWlnaHQgPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy5zaWduYWwoJ2hlaWdodCcsIF8pIDogdGhpcy5zaWduYWwoJ2hlaWdodCcpO1xufTtcblxucHJvdG90eXBlJDgzLnBhZGRpbmcgPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy5zaWduYWwoJ3BhZGRpbmcnLCBfKSA6IHRoaXMuc2lnbmFsKCdwYWRkaW5nJyk7XG59O1xuXG5wcm90b3R5cGUkODMuYXV0b3NpemUgPSBmdW5jdGlvbihfKSB7XG4gIHJldHVybiBhcmd1bWVudHMubGVuZ3RoID8gdGhpcy5zaWduYWwoJ2F1dG9zaXplJywgXykgOiB0aGlzLnNpZ25hbCgnYXV0b3NpemUnKTtcbn07XG5cbnByb3RvdHlwZSQ4My5yZW5kZXJlciA9IGZ1bmN0aW9uKHR5cGUpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fcmVuZGVyVHlwZTtcbiAgaWYgKCFyZW5kZXJNb2R1bGUodHlwZSkpIGVycm9yJDEoJ1VucmVjb2duaXplZCByZW5kZXJlciB0eXBlOiAnICsgdHlwZSk7XG4gIGlmICh0eXBlICE9PSB0aGlzLl9yZW5kZXJUeXBlKSB7XG4gICAgdGhpcy5fcmVuZGVyVHlwZSA9IHR5cGU7XG4gICAgaWYgKHRoaXMuX3JlbmRlcmVyKSB7XG4gICAgICB0aGlzLl9yZW5kZXJlciA9IG51bGw7XG4gICAgICB0aGlzLmluaXRpYWxpemUodGhpcy5fZWwpO1xuICAgIH1cbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ4My5sb2FkZXIgPSBmdW5jdGlvbihsb2FkZXIpIHtcbiAgaWYgKCFhcmd1bWVudHMubGVuZ3RoKSByZXR1cm4gdGhpcy5fbG9hZGVyO1xuICBpZiAobG9hZGVyICE9PSB0aGlzLl9sb2FkZXIpIHtcbiAgICBEYXRhZmxvdy5wcm90b3R5cGUubG9hZGVyLmNhbGwodGhpcywgbG9hZGVyKTtcbiAgICBpZiAodGhpcy5fcmVuZGVyZXIpIHtcbiAgICAgIHRoaXMuX3JlbmRlcmVyID0gbnVsbDtcbiAgICAgIHRoaXMuaW5pdGlhbGl6ZSh0aGlzLl9lbCk7XG4gICAgfVxuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDgzLnJlc2l6ZSA9IGZ1bmN0aW9uKCkge1xuICB0aGlzLl9hdXRvc2l6ZSA9IDE7XG4gIHJldHVybiB0aGlzO1xufTtcblxuLy8gLS0gU0laSU5HIC0tLS1cbnByb3RvdHlwZSQ4My5fcmVzaXplVmlldyA9IHJlc2l6ZVZpZXc7XG5cbi8vIC0tIEVWRU5UIEhBTkRMSU5HIC0tLS1cblxucHJvdG90eXBlJDgzLmFkZEV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBoYW5kbGVyKSB7XG4gIHRoaXMuX2hhbmRsZXIub24odHlwZSwgaGFuZGxlcik7XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDgzLnJlbW92ZUV2ZW50TGlzdGVuZXIgPSBmdW5jdGlvbih0eXBlLCBoYW5kbGVyKSB7XG4gIHRoaXMuX2hhbmRsZXIub2ZmKHR5cGUsIGhhbmRsZXIpO1xuICByZXR1cm4gdGhpcztcbn07XG5cbnByb3RvdHlwZSQ4My5hZGRSZXNpemVMaXN0ZW5lciA9IGZ1bmN0aW9uKGhhbmRsZXIpIHtcbiAgdmFyIGwgPSB0aGlzLl9yZXNpemVMaXN0ZW5lcnM7XG4gIGlmIChsLmluZGV4T2YoaGFuZGxlcikgPCAwKSB7XG4gICAgLy8gYWRkIGhhbmRsZXIgaWYgaXQgaXNuJ3QgYWxyZWFkeSByZWdpc3RlcmVkXG4gICAgbC5wdXNoKGhhbmRsZXIpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDgzLnJlbW92ZVJlc2l6ZUxpc3RlbmVyID0gZnVuY3Rpb24oaGFuZGxlcikge1xuICB2YXIgbCA9IHRoaXMuX3Jlc2l6ZUxpc3RlbmVycyxcbiAgICAgIGkgPSBsLmluZGV4T2YoaGFuZGxlcik7XG4gIGlmIChpID49IDApIHtcbiAgICBsLnNwbGljZShpLCAxKTtcbiAgfVxuICByZXR1cm4gdGhpcztcbn07XG5cbmZ1bmN0aW9uIGZpbmRIYW5kbGVyKHNpZ25hbCwgaGFuZGxlcikge1xuICB2YXIgdCA9IHNpZ25hbC5fdGFyZ2V0cyB8fCBbXSxcbiAgICAgIGggPSB0LmZpbHRlcihmdW5jdGlvbihvcCkge1xuICAgICAgICAgICAgdmFyIHUgPSBvcC5fdXBkYXRlO1xuICAgICAgICAgICAgcmV0dXJuIHUgJiYgdS5oYW5kbGVyID09PSBoYW5kbGVyO1xuICAgICAgICAgIH0pO1xuICByZXR1cm4gaC5sZW5ndGggPyBoWzBdIDogbnVsbDtcbn1cblxucHJvdG90eXBlJDgzLmFkZFNpZ25hbExpc3RlbmVyID0gZnVuY3Rpb24obmFtZSwgaGFuZGxlcikge1xuICB2YXIgcyA9IGxvb2t1cFNpZ25hbCh0aGlzLCBuYW1lKSxcbiAgICAgIGggPSBmaW5kSGFuZGxlcihzLCBoYW5kbGVyKTtcblxuICBpZiAoIWgpIHtcbiAgICBoID0gZnVuY3Rpb24oKSB7IGhhbmRsZXIobmFtZSwgcy52YWx1ZSk7IH07XG4gICAgaC5oYW5kbGVyID0gaGFuZGxlcjtcbiAgICB0aGlzLm9uKHMsIG51bGwsIGgpO1xuICB9XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDgzLnJlbW92ZVNpZ25hbExpc3RlbmVyID0gZnVuY3Rpb24obmFtZSwgaGFuZGxlcikge1xuICB2YXIgcyA9IGxvb2t1cFNpZ25hbCh0aGlzLCBuYW1lKSxcbiAgICAgIGggPSBmaW5kSGFuZGxlcihzLCBoYW5kbGVyKTtcblxuICBpZiAoaCkgcy5fdGFyZ2V0cy5yZW1vdmUoaCk7XG4gIHJldHVybiB0aGlzO1xufTtcblxucHJvdG90eXBlJDgzLnByZXZlbnREZWZhdWx0ID0gZnVuY3Rpb24oXykge1xuICBpZiAoYXJndW1lbnRzLmxlbmd0aCkge1xuICAgIHRoaXMuX3ByZXZlbnREZWZhdWx0ID0gXztcbiAgICByZXR1cm4gdGhpcztcbiAgfSBlbHNlIHtcbiAgICByZXR1cm4gdGhpcy5fcHJldmVudERlZmF1bHQ7XG4gIH1cbn07XG5cbnByb3RvdHlwZSQ4My50b29sdGlwSGFuZGxlciA9IGZ1bmN0aW9uKF8pIHtcbiAgdmFyIGggPSB0aGlzLl9oYW5kbGVyO1xuICBpZiAoIWFyZ3VtZW50cy5sZW5ndGgpIHtcbiAgICByZXR1cm4gaC5oYW5kbGVUb29sdGlwO1xuICB9IGVsc2Uge1xuICAgIGguaGFuZGxlVG9vbHRpcCA9IF8gfHwgSGFuZGxlci5wcm90b3R5cGUuaGFuZGxlVG9vbHRpcDtcbiAgICByZXR1cm4gdGhpcztcbiAgfVxufTtcblxucHJvdG90eXBlJDgzLmV2ZW50cyA9IGV2ZW50cyQxO1xucHJvdG90eXBlJDgzLmZpbmFsaXplID0gZmluYWxpemU7XG5wcm90b3R5cGUkODMuaG92ZXIgPSBob3ZlcjtcblxuLy8gLS0gREFUQSAtLS0tXG5wcm90b3R5cGUkODMuZGF0YSA9IGRhdGE7XG5wcm90b3R5cGUkODMuY2hhbmdlID0gY2hhbmdlO1xucHJvdG90eXBlJDgzLmluc2VydCA9IGluc2VydDtcbnByb3RvdHlwZSQ4My5yZW1vdmUgPSByZW1vdmU7XG5cbi8vIC0tIElOSVRJQUxJWkFUSU9OIC0tLS1cbnByb3RvdHlwZSQ4My5pbml0aWFsaXplID0gaW5pdGlhbGl6ZSQxO1xuXG4vLyAtLSBIRUFETEVTUyBSRU5ERVJJTkcgLS0tLVxucHJvdG90eXBlJDgzLnRvSW1hZ2VVUkwgPSByZW5kZXJUb0ltYWdlVVJMO1xucHJvdG90eXBlJDgzLnRvQ2FudmFzID0gcmVuZGVyVG9DYW52YXM7XG5wcm90b3R5cGUkODMudG9TVkcgPSByZW5kZXJUb1NWRztcblxuLy8gLS0gU0FWRSAvIFJFU1RPUkUgU1RBVEUgLS0tLVxucHJvdG90eXBlJDgzLmdldFN0YXRlID0gZ2V0U3RhdGUkMTtcbnByb3RvdHlwZSQ4My5zZXRTdGF0ZSA9IHNldFN0YXRlJDE7XG5cbi8vIC0tIFRyYW5zZm9ybXMgLS0tLS1cblxuZXh0ZW5kKHRyYW5zZm9ybXMsIHR4LCB2dHgsIGVuY29kZSwgZ2VvLCBmb3JjZSwgdHJlZSwgdm9yb25vaSwgd29yZGNsb3VkLCB4Zik7XG5cbmV4cG9ydHMudmVyc2lvbiA9IHZlcnNpb247XG5leHBvcnRzLkRhdGFmbG93ID0gRGF0YWZsb3c7XG5leHBvcnRzLkV2ZW50U3RyZWFtID0gRXZlbnRTdHJlYW07XG5leHBvcnRzLlBhcmFtZXRlcnMgPSBQYXJhbWV0ZXJzO1xuZXhwb3J0cy5QdWxzZSA9IFB1bHNlO1xuZXhwb3J0cy5NdWx0aVB1bHNlID0gTXVsdGlQdWxzZTtcbmV4cG9ydHMuT3BlcmF0b3IgPSBPcGVyYXRvcjtcbmV4cG9ydHMuVHJhbnNmb3JtID0gVHJhbnNmb3JtO1xuZXhwb3J0cy5jaGFuZ2VzZXQgPSBjaGFuZ2VzZXQ7XG5leHBvcnRzLmluZ2VzdCA9IGluZ2VzdDtcbmV4cG9ydHMuaXNUdXBsZSA9IGlzVHVwbGU7XG5leHBvcnRzLmRlZmluaXRpb24gPSBkZWZpbml0aW9uO1xuZXhwb3J0cy50cmFuc2Zvcm0gPSB0cmFuc2Zvcm0kMTtcbmV4cG9ydHMudHJhbnNmb3JtcyA9IHRyYW5zZm9ybXM7XG5leHBvcnRzLnR1cGxlaWQgPSB0dXBsZWlkO1xuZXhwb3J0cy5zY2FsZSA9IHNjYWxlJDE7XG5leHBvcnRzLnNjaGVtZSA9IGdldFNjaGVtZTtcbmV4cG9ydHMuaW50ZXJwb2xhdGUgPSBpbnRlcnBvbGF0ZSQxO1xuZXhwb3J0cy5pbnRlcnBvbGF0ZVJhbmdlID0gaW50ZXJwb2xhdGVSYW5nZTtcbmV4cG9ydHMudGltZUludGVydmFsID0gdGltZUludGVydmFsO1xuZXhwb3J0cy51dGNJbnRlcnZhbCA9IHV0Y0ludGVydmFsO1xuZXhwb3J0cy5wcm9qZWN0aW9uID0gcHJvamVjdGlvbiQkMTtcbmV4cG9ydHMuVmlldyA9IFZpZXc7XG5leHBvcnRzLnBhcnNlID0gcGFyc2UkMjtcbmV4cG9ydHMuZXhwcmVzc2lvbkZ1bmN0aW9uID0gZXhwcmVzc2lvbkZ1bmN0aW9uO1xuZXhwb3J0cy5mb3JtYXRMb2NhbGUgPSBkZWZhdWx0TG9jYWxlJDE7XG5leHBvcnRzLnRpbWVGb3JtYXRMb2NhbGUgPSBkZWZhdWx0TG9jYWxlO1xuZXhwb3J0cy5ydW50aW1lID0gcGFyc2VEYXRhZmxvdztcbmV4cG9ydHMucnVudGltZUNvbnRleHQgPSBjb250ZXh0JDI7XG5leHBvcnRzLmJpbiA9IGJpbjtcbmV4cG9ydHMuYm9vdHN0cmFwQ0kgPSBib290c3RyYXBDSTtcbmV4cG9ydHMucXVhcnRpbGVzID0gcXVhcnRpbGVzO1xuZXhwb3J0cy5zZXRSYW5kb20gPSBzZXRSYW5kb207XG5leHBvcnRzLnJhbmRvbUludGVnZXIgPSBpbnRlZ2VyO1xuZXhwb3J0cy5yYW5kb21LREUgPSByYW5kb21LREU7XG5leHBvcnRzLnJhbmRvbU1peHR1cmUgPSByYW5kb21NaXh0dXJlO1xuZXhwb3J0cy5yYW5kb21Ob3JtYWwgPSByYW5kb21Ob3JtYWw7XG5leHBvcnRzLnJhbmRvbVVuaWZvcm0gPSByYW5kb21Vbmlmb3JtO1xuZXhwb3J0cy5hY2Nlc3NvciA9IGFjY2Vzc29yO1xuZXhwb3J0cy5hY2Nlc3Nvck5hbWUgPSBhY2Nlc3Nvck5hbWU7XG5leHBvcnRzLmFjY2Vzc29yRmllbGRzID0gYWNjZXNzb3JGaWVsZHM7XG5leHBvcnRzLmlkID0gaWQ7XG5leHBvcnRzLmlkZW50aXR5ID0gaWRlbnRpdHk7XG5leHBvcnRzLnplcm8gPSB6ZXJvO1xuZXhwb3J0cy5vbmUgPSBvbmU7XG5leHBvcnRzLnRydXRoeSA9IHRydXRoeTtcbmV4cG9ydHMuZmFsc3kgPSBmYWxzeTtcbmV4cG9ydHMubG9nZ2VyID0gbG9nZ2VyO1xuZXhwb3J0cy5Ob25lID0gTm9uZTtcbmV4cG9ydHMuRXJyb3IgPSBFcnJvciQxO1xuZXhwb3J0cy5XYXJuID0gV2FybjtcbmV4cG9ydHMuSW5mbyA9IEluZm87XG5leHBvcnRzLkRlYnVnID0gRGVidWc7XG5leHBvcnRzLnBhbkxpbmVhciA9IHBhbkxpbmVhcjtcbmV4cG9ydHMucGFuTG9nID0gcGFuTG9nO1xuZXhwb3J0cy5wYW5Qb3cgPSBwYW5Qb3c7XG5leHBvcnRzLnpvb21MaW5lYXIgPSB6b29tTGluZWFyO1xuZXhwb3J0cy56b29tTG9nID0gem9vbUxvZztcbmV4cG9ydHMuem9vbVBvdyA9IHpvb21Qb3c7XG5leHBvcnRzLmFycmF5ID0gYXJyYXk7XG5leHBvcnRzLmNvbXBhcmUgPSBjb21wYXJlO1xuZXhwb3J0cy5jb25zdGFudCA9IGNvbnN0YW50O1xuZXhwb3J0cy5kZWJvdW5jZSA9IGRlYm91bmNlO1xuZXhwb3J0cy5lcnJvciA9IGVycm9yJDE7XG5leHBvcnRzLmV4dGVuZCA9IGV4dGVuZDtcbmV4cG9ydHMuZXh0ZW50SW5kZXggPSBleHRlbnRJbmRleDtcbmV4cG9ydHMuZmFzdG1hcCA9IGZhc3RtYXA7XG5leHBvcnRzLmZpZWxkID0gZmllbGQ7XG5leHBvcnRzLmluaGVyaXRzID0gaW5oZXJpdHM7XG5leHBvcnRzLmlzQXJyYXkgPSBpc0FycmF5O1xuZXhwb3J0cy5pc0Jvb2xlYW4gPSBpc0Jvb2xlYW47XG5leHBvcnRzLmlzRGF0ZSA9IGlzRGF0ZTtcbmV4cG9ydHMuaXNGdW5jdGlvbiA9IGlzRnVuY3Rpb247XG5leHBvcnRzLmlzTnVtYmVyID0gaXNOdW1iZXI7XG5leHBvcnRzLmlzT2JqZWN0ID0gaXNPYmplY3Q7XG5leHBvcnRzLmlzUmVnRXhwID0gaXNSZWdFeHA7XG5leHBvcnRzLmlzU3RyaW5nID0gaXNTdHJpbmc7XG5leHBvcnRzLmtleSA9IGtleTtcbmV4cG9ydHMubWVyZ2UgPSBtZXJnZTtcbmV4cG9ydHMucGFkID0gcGFkO1xuZXhwb3J0cy5wZWVrID0gcGVlaztcbmV4cG9ydHMucmVwZWF0ID0gcmVwZWF0O1xuZXhwb3J0cy5zcGxpdEFjY2Vzc1BhdGggPSBzcGxpdEFjY2Vzc1BhdGg7XG5leHBvcnRzLnN0cmluZ1ZhbHVlID0gJDtcbmV4cG9ydHMudG9Cb29sZWFuID0gdG9Cb29sZWFuO1xuZXhwb3J0cy50b0RhdGUgPSB0b0RhdGU7XG5leHBvcnRzLnRvTnVtYmVyID0gdG9OdW1iZXI7XG5leHBvcnRzLnRvU3RyaW5nID0gdG9TdHJpbmc7XG5leHBvcnRzLnRvU2V0ID0gdG9TZXQ7XG5leHBvcnRzLnRydW5jYXRlID0gdHJ1bmNhdGU7XG5leHBvcnRzLnZpc2l0QXJyYXkgPSB2aXNpdEFycmF5O1xuZXhwb3J0cy5sb2FkZXIgPSBsb2FkZXI7XG5leHBvcnRzLnJlYWQgPSByZWFkO1xuZXhwb3J0cy5pbmZlclR5cGUgPSBpbmZlclR5cGU7XG5leHBvcnRzLmluZmVyVHlwZXMgPSBpbmZlclR5cGVzO1xuZXhwb3J0cy50eXBlUGFyc2VycyA9IHR5cGVQYXJzZXJzO1xuZXhwb3J0cy5mb3JtYXRzID0gZm9ybWF0cyQxO1xuZXhwb3J0cy5Cb3VuZHMgPSBCb3VuZHM7XG5leHBvcnRzLkdyYWRpZW50ID0gR3JhZGllbnQ7XG5leHBvcnRzLkdyb3VwSXRlbSA9IEdyb3VwSXRlbTtcbmV4cG9ydHMuUmVzb3VyY2VMb2FkZXIgPSBSZXNvdXJjZUxvYWRlcjtcbmV4cG9ydHMuSXRlbSA9IEl0ZW07XG5leHBvcnRzLlNjZW5lZ3JhcGggPSBTY2VuZWdyYXBoO1xuZXhwb3J0cy5IYW5kbGVyID0gSGFuZGxlcjtcbmV4cG9ydHMuUmVuZGVyZXIgPSBSZW5kZXJlcjtcbmV4cG9ydHMuQ2FudmFzSGFuZGxlciA9IENhbnZhc0hhbmRsZXI7XG5leHBvcnRzLkNhbnZhc1JlbmRlcmVyID0gQ2FudmFzUmVuZGVyZXI7XG5leHBvcnRzLlNWR0hhbmRsZXIgPSBTVkdIYW5kbGVyO1xuZXhwb3J0cy5TVkdSZW5kZXJlciA9IFNWR1JlbmRlcmVyO1xuZXhwb3J0cy5TVkdTdHJpbmdSZW5kZXJlciA9IFNWR1N0cmluZ1JlbmRlcmVyO1xuZXhwb3J0cy5SZW5kZXJUeXBlID0gUmVuZGVyVHlwZTtcbmV4cG9ydHMucmVuZGVyTW9kdWxlID0gcmVuZGVyTW9kdWxlO1xuZXhwb3J0cy5NYXJrcyA9IG1hcmtzO1xuZXhwb3J0cy5ib3VuZENsaXAgPSBib3VuZENsaXA7XG5leHBvcnRzLmJvdW5kQ29udGV4dCA9IGNvbnRleHQ7XG5leHBvcnRzLmJvdW5kU3Ryb2tlID0gYm91bmRTdHJva2U7XG5leHBvcnRzLmJvdW5kSXRlbSA9IGJvdW5kSXRlbSQxO1xuZXhwb3J0cy5ib3VuZE1hcmsgPSBib3VuZE1hcms7XG5leHBvcnRzLnBhdGhDdXJ2ZXMgPSBjdXJ2ZXM7XG5leHBvcnRzLnBhdGhTeW1ib2xzID0gc3ltYm9scyQxO1xuZXhwb3J0cy5wYXRoUmVjdGFuZ2xlID0gdmdfcmVjdDtcbmV4cG9ydHMucGF0aFRyYWlsID0gdmdfdHJhaWw7XG5leHBvcnRzLnBhdGhQYXJzZSA9IHBhdGhQYXJzZTtcbmV4cG9ydHMucGF0aFJlbmRlciA9IHBhdGhSZW5kZXI7XG5leHBvcnRzLnBvaW50ID0gcG9pbnQkNDtcbmV4cG9ydHMuZG9tQ3JlYXRlID0gZG9tQ3JlYXRlO1xuZXhwb3J0cy5kb21GaW5kID0gZG9tRmluZDtcbmV4cG9ydHMuZG9tQ2hpbGQgPSBkb21DaGlsZDtcbmV4cG9ydHMuZG9tQ2xlYXIgPSBkb21DbGVhcjtcbmV4cG9ydHMub3BlblRhZyA9IG9wZW5UYWc7XG5leHBvcnRzLmNsb3NlVGFnID0gY2xvc2VUYWc7XG5leHBvcnRzLmZvbnQgPSBmb250O1xuZXhwb3J0cy50ZXh0TWV0cmljcyA9IHRleHRNZXRyaWNzO1xuZXhwb3J0cy5yZXNldFNWR0NsaXBJZCA9IHJlc2V0U1ZHQ2xpcElkO1xuZXhwb3J0cy5zY2VuZUVxdWFsID0gc2NlbmVFcXVhbDtcbmV4cG9ydHMucGF0aEVxdWFsID0gcGF0aEVxdWFsO1xuZXhwb3J0cy5zY2VuZVRvSlNPTiA9IHNjZW5lVG9KU09OO1xuZXhwb3J0cy5zY2VuZUZyb21KU09OID0gc2NlbmVGcm9tSlNPTjtcbmV4cG9ydHMuc2NlbmVaT3JkZXIgPSB6b3JkZXI7XG5leHBvcnRzLnNjZW5lVmlzaXQgPSB2aXNpdDtcbmV4cG9ydHMuc2NlbmVQaWNrVmlzaXQgPSBwaWNrVmlzaXQ7XG5cbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCAnX19lc01vZHVsZScsIHsgdmFsdWU6IHRydWUgfSk7XG5cbn0pKSk7XG4iLCJcInVzZSBzdHJpY3RcIjtcbk9iamVjdC5kZWZpbmVQcm9wZXJ0eShleHBvcnRzLCBcIl9fZXNNb2R1bGVcIiwgeyB2YWx1ZTogdHJ1ZSB9KTtcbi8qKlxuICogUGFyc2UgYSB2ZWdhIHNjaGVtYSB1cmwgaW50byBsaWJyYXJ5IGFuZCB2ZXJzaW9uLlxuICovXG5mdW5jdGlvbiBkZWZhdWx0XzEodXJsKSB7XG4gICAgdmFyIHJlZ2V4ID0gL1xcL3NjaGVtYVxcLyhbXFx3LV0rKVxcLyhbXFx3XFwuXFwtXSspXFwuanNvbiQvZztcbiAgICB2YXIgX2EgPSByZWdleC5leGVjKHVybCkuc2xpY2UoMSwgMyksIGxpYnJhcnkgPSBfYVswXSwgdmVyc2lvbiA9IF9hWzFdO1xuICAgIHJldHVybiB7IGxpYnJhcnk6IGxpYnJhcnksIHZlcnNpb246IHZlcnNpb24gfTtcbn1cbmV4cG9ydHMuZGVmYXVsdCA9IGRlZmF1bHRfMTtcbi8vIyBzb3VyY2VNYXBwaW5nVVJMPWluZGV4LmpzLm1hcCIsImltcG9ydCAqIGFzIHZlcnNpb25Db21wYXJlIGZyb20gJ2NvbXBhcmUtdmVyc2lvbnMnO1xuaW1wb3J0ICogYXMgZDMgZnJvbSAnZDMtc2VsZWN0aW9uJztcbmltcG9ydCAqIGFzIHZlZ2FJbXBvcnQgZnJvbSAndmVnYS1saWInO1xuaW1wb3J0ICogYXMgVmVnYUxpdGUgZnJvbSAndmVnYS1saXRlJztcbmltcG9ydCBzY2hlbWFQYXJzZXIgZnJvbSAndmVnYS1zY2hlbWEtdXJsLXBhcnNlcic7XG5cbmltcG9ydCB7IENvbmZpZyBhcyBWZ0NvbmZpZywgTG9hZGVyLCBTcGVjIGFzIFZnU3BlYywgVmlldyB9IGZyb20gJ3ZlZ2EtbGliJztcbmltcG9ydCB7IENvbmZpZyBhcyBWbENvbmZpZyB9IGZyb20gJ3ZlZ2EtbGl0ZS9idWlsZC9zcmMvY29uZmlnJztcbmltcG9ydCB7IFRvcExldmVsRXh0ZW5kZWRTcGVjIGFzIFZsU3BlYyB9IGZyb20gJ3ZlZ2EtbGl0ZS9idWlsZC9zcmMvc3BlYyc7XG5pbXBvcnQgeyBwb3N0IH0gZnJvbSAnLi9wb3N0JztcblxuZXhwb3J0IGNvbnN0IHZlZ2EgPSB2ZWdhSW1wb3J0O1xuZXhwb3J0IGNvbnN0IHZsID0gVmVnYUxpdGU7XG5cbmV4cG9ydCB0eXBlIE1vZGUgPSAndmVnYScgfCAndmVnYS1saXRlJztcblxuZXhwb3J0IGludGVyZmFjZSBFbWJlZE9wdGlvbnMge1xuICBhY3Rpb25zPzogYm9vbGVhbiB8IHtleHBvcnQ/OiBib29sZWFuLCBzb3VyY2U/OiBib29sZWFuLCBlZGl0b3I/OiBib29sZWFufTtcbiAgbW9kZT86IE1vZGU7XG4gIGxvZ0xldmVsPzogbnVtYmVyO1xuICBsb2FkZXI/OiBMb2FkZXI7XG4gIHJlbmRlcmVyPzogJ2NhbnZhcycgfCAnc3ZnJztcbiAgb25CZWZvcmVQYXJzZT86IChzcGVjOiBWaXN1YWxpemF0aW9uU3BlYykgPT4gVmlzdWFsaXphdGlvblNwZWM7XG4gIHdpZHRoPzogbnVtYmVyO1xuICBoZWlnaHQ/OiBudW1iZXI7XG4gIHBhZGRpbmc/OiBudW1iZXIgfCB7bGVmdD86IG51bWJlciwgcmlnaHQ/OiBudW1iZXIsIHRvcD86IG51bWJlciwgYm90dG9tPzogbnVtYmVyfTtcbiAgY29uZmlnPzogc3RyaW5nIHwgVmxDb25maWcgfCBWZ0NvbmZpZztcbiAgc291cmNlSGVhZGVyPzogc3RyaW5nO1xuICBzb3VyY2VGb290ZXI/OiBzdHJpbmc7XG4gIGVkaXRvclVybD86IHN0cmluZztcbn1cblxuY29uc3QgTkFNRVMgPSB7XG4gICd2ZWdhJzogICAgICAnVmVnYScsXG4gICd2ZWdhLWxpdGUnOiAnVmVnYS1MaXRlJyxcbn07XG5cbmNvbnN0IFZFUlNJT04gPSB7XG4gICd2ZWdhJzogICAgICB2ZWdhLnZlcnNpb24sXG4gICd2ZWdhLWxpdGUnOiB2bCA/IHZsLnZlcnNpb24gOiAnbm90IGF2YWlsYWJsZScsXG59O1xuXG5jb25zdCBQUkVQUk9DRVNTT1IgPSB7XG4gICd2ZWdhJzogICAgICAodmdqc29uLCBfKSA9PiB2Z2pzb24sXG4gICd2ZWdhLWxpdGUnOiAodmxqc29uLCBjb25maWcpID0+IHZsLmNvbXBpbGUodmxqc29uLCBjb25maWcpLnNwZWMsXG59O1xuXG5leHBvcnQgdHlwZSBWaXN1YWxpemF0aW9uU3BlYyA9IFZsU3BlYyB8IFZnU3BlYztcblxuLyoqXG4gKiBFbWJlZCBhIFZlZ2EgdmlzdWFsaXphdGlvbiBjb21wb25lbnQgaW4gYSB3ZWIgcGFnZS4gVGhpcyBmdW5jdGlvbiByZXR1cm5zIGEgcHJvbWlzZS5cbiAqXG4gKiBAcGFyYW0gZWwgICAgICAgIERPTSBlbGVtZW50IGluIHdoaWNoIHRvIHBsYWNlIGNvbXBvbmVudCAoRE9NIG5vZGUgb3IgQ1NTIHNlbGVjdG9yKS5cbiAqIEBwYXJhbSBzcGVjICAgICAgU3RyaW5nIDogQSBVUkwgc3RyaW5nIGZyb20gd2hpY2ggdG8gbG9hZCB0aGUgVmVnYSBzcGVjaWZpY2F0aW9uLlxuICogICAgICAgICAgICAgICAgICBPYmplY3QgOiBUaGUgVmVnYS9WZWdhLUxpdGUgc3BlY2lmaWNhdGlvbiBhcyBhIHBhcnNlZCBKU09OIG9iamVjdC5cbiAqIEBwYXJhbSBvcHQgICAgICAgQSBKYXZhU2NyaXB0IG9iamVjdCBjb250YWluaW5nIG9wdGlvbnMgZm9yIGVtYmVkZGluZy5cbiAqL1xuZXhwb3J0IGRlZmF1bHQgZnVuY3Rpb24gZW1iZWQoZWw6IEhUTUxCYXNlRWxlbWVudCB8IHN0cmluZywgc3BlYzogc3RyaW5nIHwgVmlzdWFsaXphdGlvblNwZWMsIG9wdDogRW1iZWRPcHRpb25zKTogUHJvbWlzZTx7fSB8IHsgdmlldzogVmlldzsgc3BlYzogVmlzdWFsaXphdGlvblNwZWMgfT4ge1xuICB0cnkge1xuICAgIG9wdCA9IG9wdCB8fCB7fTtcbiAgICBjb25zdCBhY3Rpb25zICA9IG9wdC5hY3Rpb25zICE9PSB1bmRlZmluZWQgPyBvcHQuYWN0aW9ucyA6IHRydWU7XG5cbiAgICBjb25zdCBsb2FkZXI6IExvYWRlciA9IG9wdC5sb2FkZXIgfHwgdmVnYS5sb2FkZXIoKTtcbiAgICBjb25zdCByZW5kZXJlciA9IG9wdC5yZW5kZXJlciB8fCAnY2FudmFzJztcbiAgICBjb25zdCBsb2dMZXZlbCA9IG9wdC5sb2dMZXZlbCB8fCB2ZWdhLldhcm47XG5cbiAgICAvLyBMb2FkIHRoZSB2aXN1YWxpemF0aW9uIHNwZWNpZmljYXRpb24uXG4gICAgaWYgKHZlZ2EuaXNTdHJpbmcoc3BlYykpIHtcbiAgICAgIHJldHVybiBsb2FkZXIubG9hZChzcGVjKS50aGVuKFxuICAgICAgICBkYXRhID0+IGVtYmVkKGVsLCBKU09OLnBhcnNlKGRhdGEpLCBvcHQpLFxuICAgICAgKS5jYXRjaChQcm9taXNlLnJlamVjdCk7XG4gICAgfVxuXG4gICAgLy8gTG9hZCBWZWdhIHRoZW1lL2NvbmZpZ3VyYXRpb24uXG4gICAgY29uc3QgY29uZmlnID0gb3B0LmNvbmZpZztcbiAgICBpZiAodmVnYS5pc1N0cmluZyhjb25maWcpKSB7XG4gICAgICByZXR1cm4gbG9hZGVyLmxvYWQoY29uZmlnKS50aGVuKGRhdGEgPT4ge1xuICAgICAgICBvcHQuY29uZmlnID0gSlNPTi5wYXJzZShkYXRhKTtcbiAgICAgICAgcmV0dXJuIGVtYmVkKGVsLCBzcGVjLCBvcHQpO1xuICAgICAgfSkuY2F0Y2goUHJvbWlzZS5yZWplY3QpO1xuICAgIH1cblxuICAgIC8vIERlY2lkZSBtb2RlXG4gICAgbGV0IHBhcnNlZDoge2xpYnJhcnk6IHN0cmluZywgdmVyc2lvbjogc3RyaW5nfTtcbiAgICBsZXQgbW9kZTogTW9kZTtcblxuICAgIGlmIChzcGVjLiRzY2hlbWEpIHtcbiAgICAgIHBhcnNlZCA9IHNjaGVtYVBhcnNlcihzcGVjLiRzY2hlbWEpO1xuICAgICAgaWYgKG9wdC5tb2RlICYmIG9wdC5tb2RlICE9PSBwYXJzZWQubGlicmFyeSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYFRoZSBnaXZlbiB2aXN1YWxpemF0aW9uIHNwZWMgaXMgd3JpdHRlbiBpbiAke05BTUVTW3BhcnNlZC5saWJyYXJ5XX0sIGJ1dCBtb2RlIGFyZ3VtZW50IHNldHMgJHtOQU1FU1tvcHQubW9kZV19LmApO1xuICAgICAgfVxuXG4gICAgICBtb2RlID0gcGFyc2VkLmxpYnJhcnkgYXMgTW9kZTtcblxuICAgICAgaWYgKHZlcnNpb25Db21wYXJlKHBhcnNlZC52ZXJzaW9uLCBWRVJTSU9OW21vZGVdKSA+IDApIHtcbiAgICAgICAgY29uc29sZS53YXJuKGBUaGUgaW5wdXQgc3BlYyB1c2VzICR7bW9kZX0gJHtwYXJzZWQudmVyc2lvbn0sIGJ1dCB0aGUgY3VycmVudCB2ZXJzaW9uIG9mICR7TkFNRVNbbW9kZV19IGlzICR7VkVSU0lPTlttb2RlXX0uYCk7XG4gICAgICB9XG4gICAgfSBlbHNlIHtcbiAgICAgIG1vZGUgPSBvcHQubW9kZSB8fCAndmVnYSc7XG4gICAgfVxuXG4gICAgbGV0IHZnU3BlYzogVmdTcGVjID0gUFJFUFJPQ0VTU09SW21vZGVdKHNwZWMsIGNvbmZpZyk7XG5cbiAgICBpZiAobW9kZSA9PT0gJ3ZlZ2EtbGl0ZScpIHtcbiAgICAgIGlmICh2Z1NwZWMuJHNjaGVtYSkge1xuICAgICAgICBwYXJzZWQgPSBzY2hlbWFQYXJzZXIodmdTcGVjLiRzY2hlbWEpO1xuXG4gICAgICAgIGlmICh2ZXJzaW9uQ29tcGFyZShwYXJzZWQudmVyc2lvbiwgVkVSU0lPTi52ZWdhKSA+IDApIHtcbiAgICAgICAgICBjb25zb2xlLndhcm4oYFRoZSBjb21waWxlZCBzcGVjIHVzZXMgVmVnYSAke3BhcnNlZC52ZXJzaW9ufSwgYnV0IGN1cnJlbnQgdmVyc2lvbiBpcyAke1ZFUlNJT04udmVnYX0uYCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICAvLyBlbnN1cmUgY29udGFpbmVyIGRpdiBoYXMgY2xhc3MgJ3ZlZ2EtZW1iZWQnXG4gICAgY29uc3QgZGl2ID0gZDMuc2VsZWN0KGVsIGFzIGFueSkgIC8vIGQzLnNlbGVjdCBzdXBwb3J0cyBlbGVtZW50cyBhbmQgc3RyaW5nc1xuICAgICAgLmNsYXNzZWQoJ3ZlZ2EtZW1iZWQnLCB0cnVlKVxuICAgICAgLmh0bWwoJycpOyAvLyBjbGVhciBjb250YWluZXJcblxuICAgIGlmIChvcHQub25CZWZvcmVQYXJzZSkge1xuICAgICAgLy8gQWxsb3cgVmVnYSBzcGVjIHRvIGJlIG1vZGlmaWVkIGJlZm9yZSBiZWluZyB1c2VkXG4gICAgICB2Z1NwZWMgPSBvcHQub25CZWZvcmVQYXJzZSh2Z1NwZWMpO1xuICAgIH1cblxuICAgIGNvbnN0IHJ1bnRpbWUgPSB2ZWdhLnBhcnNlKHZnU3BlYywgb3B0LmNvbmZpZyk7ICAvLyBtYXkgdGhyb3cgYW4gRXJyb3IgaWYgcGFyc2luZyBmYWlsc1xuXG4gICAgY29uc3QgdmlldyA9IG5ldyB2ZWdhLlZpZXcocnVudGltZSwge2xvYWRlciwgbG9nTGV2ZWwsIHJlbmRlcmVyfSlcbiAgICAgIC5pbml0aWFsaXplKGVsKTtcblxuICAgIC8vIFZlZ2EtTGl0ZSBkb2VzIG5vdCBuZWVkIGhvdmVyIHNvIHdlIGNhbiBpbXByb3ZlIHBlcmYgYnkgbm90IGFjdGl2YXRpbmcgaXRcbiAgICBpZiAobW9kZSAhPT0gJ3ZlZ2EtbGl0ZScpIHtcbiAgICAgIHZpZXcuaG92ZXIoKTtcbiAgICB9XG5cbiAgICBpZiAob3B0KSB7XG4gICAgICBpZiAob3B0LndpZHRoKSB7XG4gICAgICAgIHZpZXcud2lkdGgob3B0LndpZHRoKTtcbiAgICAgIH1cbiAgICAgIGlmIChvcHQuaGVpZ2h0KSB7XG4gICAgICAgIHZpZXcuaGVpZ2h0KG9wdC5oZWlnaHQpO1xuICAgICAgfVxuICAgICAgaWYgKG9wdC5wYWRkaW5nKSB7XG4gICAgICAgIHZpZXcucGFkZGluZyhvcHQucGFkZGluZyk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdmlldy5ydW4oKTtcblxuICAgIGlmIChhY3Rpb25zICE9PSBmYWxzZSkge1xuICAgICAgLy8gYWRkIGNoaWxkIGRpdiB0byBob3VzZSBhY3Rpb24gbGlua3NcbiAgICAgIGNvbnN0IGN0cmwgPSBkaXYuYXBwZW5kKCdkaXYnKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAndmVnYS1hY3Rpb25zJyk7XG5cbiAgICAgIC8vIGFkZCAnRXhwb3J0JyBhY3Rpb25cbiAgICAgIGlmIChhY3Rpb25zID09PSB0cnVlIHx8IGFjdGlvbnMuZXhwb3J0ICE9PSBmYWxzZSkge1xuICAgICAgICBjb25zdCBleHQgPSByZW5kZXJlciA9PT0gJ2NhbnZhcycgPyAncG5nJyA6ICdzdmcnO1xuICAgICAgICBjdHJsLmFwcGVuZCgnYScpXG4gICAgICAgICAgLnRleHQoYEV4cG9ydCBhcyAke2V4dC50b1VwcGVyQ2FzZSgpfWApXG4gICAgICAgICAgLmF0dHIoJ2hyZWYnLCAnIycpXG4gICAgICAgICAgLmF0dHIoJ3RhcmdldCcsICdfYmxhbmsnKVxuICAgICAgICAgIC5hdHRyKCdkb3dubG9hZCcsIGB2aXN1YWxpemF0aW9uLiR7ZXh0fWApXG4gICAgICAgICAgLm9uKCdtb3VzZWRvd24nLCBmdW5jdGlvbih0aGlzOiBIVE1MTGlua0VsZW1lbnQpIHtcbiAgICAgICAgICAgIHZpZXcudG9JbWFnZVVSTChleHQpLnRoZW4odXJsID0+IHtcbiAgICAgICAgICAgICAgdGhpcy5ocmVmID0gIHVybDtcbiAgICAgICAgICAgIH0pLmNhdGNoKGVycm9yID0+IHsgdGhyb3cgZXJyb3I7IH0pO1xuICAgICAgICAgICAgZDMuZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gYWRkICdWaWV3IFNvdXJjZScgYWN0aW9uXG4gICAgICBpZiAoYWN0aW9ucyA9PT0gdHJ1ZSB8fCBhY3Rpb25zLnNvdXJjZSAhPT0gZmFsc2UpIHtcbiAgICAgICAgY3RybC5hcHBlbmQoJ2EnKVxuICAgICAgICAgIC50ZXh0KCdWaWV3IFNvdXJjZScpXG4gICAgICAgICAgLmF0dHIoJ2hyZWYnLCAnIycpXG4gICAgICAgICAgLm9uKCdjbGljaycsICgpID0+IHtcbiAgICAgICAgICAgIHZpZXdTb3VyY2UoSlNPTi5zdHJpbmdpZnkoc3BlYywgbnVsbCwgMiksIG9wdC5zb3VyY2VIZWFkZXIgfHwgJycsIG9wdC5zb3VyY2VGb290ZXIgfHwgJycpO1xuICAgICAgICAgICAgZDMuZXZlbnQucHJldmVudERlZmF1bHQoKTtcbiAgICAgICAgICB9KTtcbiAgICAgIH1cblxuICAgICAgLy8gYWRkICdPcGVuIGluIFZlZ2EgRWRpdG9yJyBhY3Rpb25cbiAgICAgIGlmIChhY3Rpb25zID09PSB0cnVlIHx8IGFjdGlvbnMuZWRpdG9yICE9PSBmYWxzZSkge1xuICAgICAgICBjb25zdCBlZGl0b3JVcmwgPSBvcHQuZWRpdG9yVXJsIHx8ICdodHRwczovL3ZlZ2EuZ2l0aHViLmlvL2VkaXRvci8nO1xuICAgICAgICBjdHJsLmFwcGVuZCgnYScpXG4gICAgICAgICAgLnRleHQoJ09wZW4gaW4gVmVnYSBFZGl0b3InKVxuICAgICAgICAgIC5hdHRyKCdocmVmJywgJyMnKVxuICAgICAgICAgIC5vbignY2xpY2snLCAoKSA9PiB7XG4gICAgICAgICAgICBwb3N0KHdpbmRvdywgZWRpdG9yVXJsLCB7XG4gICAgICAgICAgICAgIG1vZGUsXG4gICAgICAgICAgICAgIHNwZWM6IEpTT04uc3RyaW5naWZ5KHNwZWMsIG51bGwsIDIpLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgICAgICBkMy5ldmVudC5wcmV2ZW50RGVmYXVsdCgpO1xuICAgICAgICAgIH0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIHJldHVybiBQcm9taXNlLnJlc29sdmUoe3ZpZXcsIHNwZWN9KTtcbiAgfSBjYXRjaCAoZXJyKSB7XG4gICAgcmV0dXJuIFByb21pc2UucmVqZWN0KGVycik7XG4gIH1cbn1cblxuZnVuY3Rpb24gdmlld1NvdXJjZShzb3VyY2U6IHN0cmluZywgc291cmNlSGVhZGVyOiBzdHJpbmcsIHNvdXJjZUZvb3Rlcjogc3RyaW5nKSB7XG4gIGNvbnN0IGhlYWRlciA9IGA8aHRtbD48aGVhZD4ke3NvdXJjZUhlYWRlcn08L2hlYWQ+PGJvZHk+PHByZT48Y29kZSBjbGFzcz1cImpzb25cIj5gO1xuICBjb25zdCBmb290ZXIgPSBgPC9jb2RlPjwvcHJlPiR7c291cmNlRm9vdGVyfTwvYm9keT48L2h0bWw+YDtcbiAgY29uc3Qgd2luID0gd2luZG93Lm9wZW4oJycpO1xuICB3aW4uZG9jdW1lbnQud3JpdGUoaGVhZGVyICsgc291cmNlICsgZm9vdGVyKTtcbiAgd2luLmRvY3VtZW50LnRpdGxlID0gJ1ZlZ2EgSlNPTiBTb3VyY2UnO1xufVxuIiwiaW1wb3J0ICogYXMgdmVnYSBmcm9tICd2ZWdhLWxpYic7XG5pbXBvcnQgKiBhcyB2bCBmcm9tICd2ZWdhLWxpdGUnO1xuXG5pbXBvcnQgZW1iZWQgZnJvbSAnLi9lbWJlZCc7XG5cbmNvbnN0IGVtYmVkTW9kdWxlOiB0eXBlb2YgZW1iZWQgJiB7ZGVmYXVsdD86IHR5cGVvZiBlbWJlZCwgdmVnYT8sIHZsP30gPSBlbWJlZDtcblxuZW1iZWRNb2R1bGUuZGVmYXVsdCA9IGVtYmVkO1xuXG4vLyBleHBvc2UgVmVnYSBhbmQgVmVnYS1MaXRlIGxpYnNcbmVtYmVkTW9kdWxlLnZlZ2EgPSB2ZWdhO1xuZW1iZWRNb2R1bGUudmwgPSB2bDtcblxuZXhwb3J0ID0gZW1iZWRNb2R1bGU7XG4iLCIvKipcbiAqIE9wZW4gZWRpdG9yIHVybCBpbiBhIG5ldyB3aW5kb3csIGFuZCBwYXNzIGEgbWVzc2FnZS5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIHBvc3Qod2luZG93OiBXaW5kb3csIHVybDogc3RyaW5nLCBkYXRhOiBhbnkpIHtcbiAgY29uc3QgZWRpdG9yID0gd2luZG93Lm9wZW4odXJsKTtcbiAgY29uc3Qgd2FpdCA9IDEwMDAwO1xuICBjb25zdCBzdGVwID0gMjUwO1xuICBsZXQgY291bnQgPSB+fih3YWl0IC8gc3RlcCk7XG5cbiAgZnVuY3Rpb24gbGlzdGVuKGV2dCkge1xuICAgIGlmIChldnQuc291cmNlID09PSBlZGl0b3IpIHtcbiAgICAgIGNvdW50ID0gMDtcbiAgICAgIHdpbmRvdy5yZW1vdmVFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuLCBmYWxzZSk7XG4gICAgfVxuICB9XG4gIHdpbmRvdy5hZGRFdmVudExpc3RlbmVyKCdtZXNzYWdlJywgbGlzdGVuLCBmYWxzZSk7XG5cbiAgLy8gc2VuZCBtZXNzYWdlXG4gIC8vIHBlcmlvZGljYWxseSByZXNlbmQgdW50aWwgYWNrIHJlY2VpdmVkIG9yIHRpbWVvdXRcbiAgZnVuY3Rpb24gc2VuZCgpIHtcbiAgICBpZiAoY291bnQgPD0gMCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBlZGl0b3IucG9zdE1lc3NhZ2UoZGF0YSwgJyonKTtcbiAgICBzZXRUaW1lb3V0KHNlbmQsIHN0ZXApO1xuICAgIGNvdW50IC09IDE7XG4gIH1cbiAgc2V0VGltZW91dChzZW5kLCBzdGVwKTtcbn1cbiJdfQ== diff --git a/build/vega-embed.min.js b/build/vega-embed.min.js new file mode 100644 index 00000000..6119a7d3 --- /dev/null +++ b/build/vega-embed.min.js @@ -0,0 +1 @@ +!function(t){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=t();else if("function"==typeof define&&define.amd)define([],t);else{("undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self?self:this).vegaEmbed=t()}}(function(){return function(){return function t(e,n,r){function i(o,u){if(!n[o]){if(!e[o]){var s="function"==typeof require&&require;if(!u&&s)return s(o,!0);if(a)return a(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var c=n[o]={exports:{}};e[o][0].call(c.exports,function(t){var n=e[o][1][t];return i(n||t)},c,c.exports,t,e,n,r)}return n[o].exports}for(var a="function"==typeof require&&require,o=0;oc)return 1;if(c>f)return-1}if([o[2],u[2]].every(e.test.bind(e))){var l=e.exec(o[2])[1].split(".").map(r),h=e.exec(u[2])[1].split(".").map(r);for(s=0;sh[s])return 1;if(h[s]>l[s])return-1}}else if([o[2],u[2]].some(e.test.bind(e)))return e.test(o[2])?-1:1;return 0}},"object"==typeof n?e.exports=i():r.compareVersions=i()},{}],3:[function(t,e,n){var r;r=this,function(t){"use strict";var e="http://www.w3.org/1999/xhtml",n={svg:"http://www.w3.org/2000/svg",xhtml:e,xlink:"http://www.w3.org/1999/xlink",xml:"http://www.w3.org/XML/1998/namespace",xmlns:"http://www.w3.org/2000/xmlns/"};function r(t){var e=t+="",r=e.indexOf(":");return r>=0&&"xmlns"!==(e=t.slice(0,r))&&(t=t.slice(r+1)),n.hasOwnProperty(e)?{space:n[e],local:t}:t}function i(t){var n=r(t);return(n.local?function(t){return function(){return this.ownerDocument.createElementNS(t.space,t.local)}}:function(t){return function(){var n=this.ownerDocument,r=this.namespaceURI;return r===e&&n.documentElement.namespaceURI===e?n.createElement(t):n.createElementNS(r,t)}})(n)}function a(){}function o(t){return null==t?a:function(){return this.querySelector(t)}}function u(){return[]}function s(t){return null==t?u:function(){return this.querySelectorAll(t)}}var f=function(t){return function(){return this.matches(t)}};if("undefined"!=typeof document){var c=document.documentElement;if(!c.matches){var l=c.webkitMatchesSelector||c.msMatchesSelector||c.mozMatchesSelector||c.oMatchesSelector;f=function(t){return function(){return l.call(this,t)}}}}var h=f;function d(t){return new Array(t.length)}function p(t,e){this.ownerDocument=t.ownerDocument,this.namespaceURI=t.namespaceURI,this._next=null,this._parent=t,this.__data__=e}p.prototype={constructor:p,appendChild:function(t){return this._parent.insertBefore(t,this._next)},insertBefore:function(t,e){return this._parent.insertBefore(t,e)},querySelector:function(t){return this._parent.querySelector(t)},querySelectorAll:function(t){return this._parent.querySelectorAll(t)}};var v="$";function g(t,e,n,r,i,a){for(var o,u=0,s=e.length,f=a.length;ue?1:t>=e?0:NaN}function b(t){return t.ownerDocument&&t.ownerDocument.defaultView||t.document&&t||t.defaultView}function _(t,e){return t.style.getPropertyValue(e)||b(t).getComputedStyle(t,null).getPropertyValue(e)}function x(t){return t.trim().split(/^|\s+/)}function w(t){return t.classList||new M(t)}function M(t){this._node=t,this._names=x(t.getAttribute("class")||"")}function k(t,e){for(var n=w(t),r=-1,i=e.length;++r=0&&(this._names.splice(e,1),this._node.setAttribute("class",this._names.join(" ")))},contains:function(t){return this._names.indexOf(t)>=0}};var T={};(t.event=null,"undefined"!=typeof document)&&("onmouseenter"in document.documentElement||(T={mouseenter:"mouseover",mouseleave:"mouseout"}));function P(t,e,n){return t=L(t,e,n),function(e){var n=e.relatedTarget;n&&(n===this||8&n.compareDocumentPosition(this))||t.call(this,e)}}function L(e,n,r){return function(i){var a=t.event;t.event=i;try{e.call(this,this.__data__,n,r)}finally{t.event=a}}}function q(t){return function(){var e=this.__on;if(e){for(var n,r=0,i=-1,a=e.length;r=M&&(M=w+1);!(x=b[M])&&++M=0;)(r=i[a])&&(o&&o!==r.nextSibling&&o.parentNode.insertBefore(r,o),o=r);return this},sort:function(t){function e(e,n){return e&&n?t(e.__data__,n.__data__):!e-!n}t||(t=y);for(var n=this._groups,r=n.length,i=new Array(r),a=0;a1?this.each((null==e?function(t){return function(){this.style.removeProperty(t)}}:"function"==typeof e?function(t,e,n){return function(){var r=e.apply(this,arguments);null==r?this.style.removeProperty(t):this.style.setProperty(t,r,n)}}:function(t,e,n){return function(){this.style.setProperty(t,e,n)}})(t,e,null==n?"":n)):_(this.node(),t)},property:function(t,e){return arguments.length>1?this.each((null==e?function(t){return function(){delete this[t]}}:"function"==typeof e?function(t,e){return function(){var n=e.apply(this,arguments);null==n?delete this[t]:this[t]=n}}:function(t,e){return function(){this[t]=e}})(t,e)):this.node()[t]},classed:function(t,e){var n=x(t+"");if(arguments.length<2){for(var r=w(this.node()),i=-1,a=n.length;++i=0&&(e=t.slice(n+1),t=t.slice(0,n)),{type:t,name:e}})}(t+""),o=a.length;if(!(arguments.length<2)){for(u=e?U:q,null==n&&(n=!1),r=0;re&&c(),u=e=n+1):"]"===r&&(u||o("Access path missing open bracket: "+t),u>0&&c(),u=0,e=n+1):n>e?c():e=n+1}return u&&o("Access path missing closing bracket: "+t),a&&o("Access path missing closing quote: "+t),n>e&&(n++,c()),i},s=Array.isArray,f=function(t){return t===Object(t)},c=function(t){return"string"==typeof t};function l(t){return s(t)?"["+t.map(l)+"]":f(t)||c(t)?JSON.stringify(t).replace("\u2028","\\u2028").replace("\u2029","\\u2029"):t}var h=function(t,e){var r=u(t),i="return _["+r.map(l).join("][")+"];";return n(Function("_",i),[t=1===r.length?r[0]:t],e||t)},d=[],p=h("id"),v=n(function(t){return t},d,"identity"),g=n(function(){return 0},d,"zero"),m=n(function(){return 1},d,"one"),y=n(function(){return!0},d,"true"),b=n(function(){return!1},d,"false");function _(t,e,n){var r=[e].concat([].slice.call(n));console[t].apply(console,r)}var x=1,w=3,M=4,k=function(t){var e=t||0;return{level:function(t){return arguments.length?(e=+t,this):e},error:function(){return e>=x&&_("error","ERROR",arguments),this},warn:function(){return e>=2&&_("warn","WARN",arguments),this},info:function(){return e>=w&&_("log","INFO",arguments),this},debug:function(){return e>=M&&_("log","DEBUG",arguments),this}}},E=function(t){return t[t.length-1]},S=function(t){return null==t||""===t?null:+t};function A(t){return function(e){return t*Math.exp(e)}}function C(t){return function(e){return Math.log(t*e)}}function N(t){return function(e){return e<0?-Math.pow(-e,t):Math.pow(e,t)}}function z(t,e,n,r){var i=n(t[0]),a=n(E(t)),o=(a-i)*e;return[r(i-o),r(a-o)]}function O(t,e){return z(t,e,S,v)}function D(t,e){var n=Math.sign(t[0]);return z(t,e,C(n),A(n))}function R(t,e,n){return z(t,e,N(n),N(1/n))}function T(t,e,n,r,i){var a=r(t[0]),o=r(E(t)),u=null!=e?r(e):(a+o)/2;return[i(u+(a-u)*n),i(u+(o-u)*n)]}function P(t,e,n){return T(t,e,n,S,v)}function L(t,e,n){var r=Math.sign(t[0]);return T(t,e,n,C(r),A(r))}function q(t,e,n,r){return T(t,e,n,N(r),N(1/r))}var U=function(t){return null!=t?s(t)?t:[t]:[]},j=function(t){return"function"==typeof t},F=function(t,e){var r,i,o,s,f,c,h,d,p,v=[],g=(t=U(t)).map(function(t,e){return null==t?null:(v.push(e),j(t)?t:u(t).map(l).join("]["))}),m=v.length-1,y=U(e),b="var u,v;return ";if(m<0)return null;for(i=0;i<=m;++i)o=g[r=v[i]],j(o)?(s="(u=this."+(c="f"+r)+"(a))",f="(v=this."+c+"(b))",(h=h||{})[c]=o):(s="(u=a["+o+"])",f="(v=b["+o+"])"),c="((v=v instanceof Date?+v:v),(u=u instanceof Date?+u:u))","descending"!==y[r]?(p=1,d=-1):(p=-1,d=1),b+="("+s+"<"+f+"||u==null)&&v!=null?"+d+":(u>v||v==null)&&u!=null?"+p+":"+c+"!==u&&v===v?"+d+":v!==v&&u===u?"+p+(r=r){n=i=r;break}for(a=o=u;++ur&&(n=r,a=u),i=r){n=i=r;break}for(a=o=u;++ur&&(n=r,a=u),i0?n[s++]:e[u++];for(;u=0;)n+=t;return n},et=function(t,e,n,r){var i=n||" ",a=t+"",o=e-a.length;return o<=0?a:"left"===r?tt(i,o)+a:"center"===r?tt(i,~~(o/2))+a+tt(i,Math.ceil(o/2)):a+tt(i,o)},nt=function(t){return null==t||""===t?null:!(!t||"false"===t||"0"===t)&&!!t};function rt(t){return J(t)?t:X(t)?t:Date.parse(t)}var it=function(t,e){return e=e||rt,null==t||""===t?null:e(t)},at=function(t){return null==t||""===t?null:t+""},ot=function(t){for(var e={},n=0,r=t.length;n=0&&n.splice(i,1)),n},n}var ct=Symbol("vega_id"),lt=1;function ht(t){return!(!t||!dt(t))}function dt(t){return t[ct]}function pt(t,e){return t[ct]=e,t}function vt(t){var e=t===Object(t)?t:{data:t};return dt(e)?e:pt(e,lt++)}function gt(t){return mt(t,vt({}))}function mt(t,e){for(var n in t)e[n]=t[n];return e}function yt(t,e){return pt(e,dt(t))}function bt(t){return t&&t.constructor===_t}function _t(){var t=[],e=[],n=[],r=[],i=[],a=!1;return{constructor:_t,insert:function(e){for(var n=U(e),r=0,i=n.length;r=0?(a[e]!==n||r)&&(a[e]=n,o[e+":"+t]=-1,o[t]=-1):(a!==n||r)&&(i[t]=n,o[t]=s(n)?1+n.length:-1),i},Mt.modified=function(t,e){var n,r=this[xt];if(!arguments.length){for(n in r)if(r[n])return!0;return!1}if(s(t)){for(n=0;n=0?e+1t?(e=n,1):0})},Dt.debounce=function(t){var e=Ot();return this.targets().add(Ot(null,null,$(t,function(t){var n=t.dataflow;e.receive(t),n&&n.run&&n.run()}))),e},Dt.between=function(t,e){var n=!1;return t.targets().add(Ot(null,null,function(){n=!0})),e.targets().add(Ot(null,null,function(){n=!1})),this.filter(function(){return n})};function Rt(){}function Tt(t,e){var n=new Rt;if(t instanceof Rt)t.each(function(t,e){n.set(e,t)});else if(Array.isArray(t)){var r,i=-1,a=t.length;if(null==e)for(;++i=r.length)return null!=t&&n.sort(t),null!=e?e(n):n;for(var s,f,c,l=-1,h=n.length,d=r[i++],p=Tt(),v=o();++lr.length)return n;var o,u=i[a-1];return null!=e&&a>=r.length?o=n.entries():(o=[],n.each(function(e,n){o.push({key:n,values:t(e,a)})})),null!=u?o.sort(function(t,e){return u(t.key,e.key)}):o}(a(t,0,Ut,jt),0)},key:function(t){return r.push(t),n},sortKeys:function(t){return i[r.length-1]=t,n},sortValues:function(e){return t=e,n},rollup:function(t){return e=t,n}}};function Lt(){return{}}function qt(t,e,n){t[e]=n}function Ut(){return Tt()}function jt(t,e,n){t.set(e,n)}function Ft(){}var It=Tt.prototype;Ft.prototype=function(t,e){var n=new Ft;if(t instanceof Ft)t.each(function(t){n.add(t)});else if(t){var r=-1,i=t.length;if(null==e)for(;++r=0&&(e=t.slice(n+1),t=t.slice(0,n)),t&&!r.hasOwnProperty(t))throw new Error("unknown type: "+t);return{type:t,name:e}})),o=-1,u=a.length;if(!(arguments.length<2)){if(null!=e&&"function"!=typeof e)throw new Error("invalid callback: "+e);for(;++o0)for(var n,r,i=new Array(n),a=0;a=200&&r<300||304===r){if(i)try{e=i.call(n,s)}catch(t){return void o.call("error",n,t)}else e=s;o.call("load",n,e)}else o.call("error",n,t)}if("undefined"==typeof XDomainRequest||"withCredentials"in s||!/^(http(s)?:)?\/\//.test(t)||(s=new XDomainRequest),"onload"in s?s.onload=s.onerror=s.ontimeout=h:s.onreadystatechange=function(t){s.readyState>3&&h(t)},s.onprogress=function(t){o.call("progress",n,t)},n={header:function(t,e){return t=(t+"").toLowerCase(),arguments.length<2?u.get(t):(null==e?u.remove(t):u.set(t,e+""),n)},mimeType:function(t){return arguments.length?(r=null==t?null:t+"",n):r},responseType:function(t){return arguments.length?(a=t,n):a},timeout:function(t){return arguments.length?(l=+t,n):l},user:function(t){return arguments.length<1?f:(f=null==t?null:t+"",n)},password:function(t){return arguments.length<1?c:(c=null==t?null:t+"",n)},response:function(t){return i=t,n},get:function(t,e){return n.send("GET",t,e)},post:function(t,e){return n.send("POST",t,e)},send:function(e,i,h){return s.open(e,t,!0,f,c),null==r||u.has("accept")||u.set("accept",r+",*/*"),s.setRequestHeader&&u.each(function(t,e){s.setRequestHeader(e,t)}),null!=r&&s.overrideMimeType&&s.overrideMimeType(r),null!=a&&(s.responseType=a),l>0&&(s.timeout=l),null==h&&"function"==typeof i&&(h=i,i=null),null!=h&&1===h.length&&(h=function(t){return function(e,n){t(null==e?n:null)}}(h)),null!=h&&n.on("error",h).on("load",function(t){h(null,t)}),o.call("beforesend",n,s),s.send(null==i?null:i),n},abort:function(){return s.abort(),n},on:function(){var t=o.on.apply(o,arguments);return t===o?n:t}},null!=e){if("function"!=typeof e)throw new Error("invalid callback: "+e);return n.get(e)}return n};var Vt={},Xt={},Jt=34,Zt=10,Qt=13;function Kt(t){return new Function("d","return {"+t.map(function(t,e){return JSON.stringify(t)+": d["+e+"]"}).join(",")+"}")}var te=function(t){var e=new RegExp('["'+t+"\n\r]"),n=t.charCodeAt(0);function r(t,e){var r,i=[],a=t.length,o=0,u=0,s=a<=0,f=!1;function c(){if(s)return Xt;if(f)return f=!1,Vt;var e,r,i=o;if(t.charCodeAt(i)===Jt){for(;o++=a?s=!0:(r=t.charCodeAt(o++))===Zt?f=!0:r===Qt&&(f=!0,t.charCodeAt(o)===Zt&&++o),t.slice(i+1,e-1).replace(/""/g,'"')}for(;o1)r=function(t,e,n){var r,i=[],a=[];function o(t){var e=t<0?~t:t;(a[e]||(a[e]=[])).push({i:t,g:r})}function u(t){t.forEach(o)}function s(t){t.forEach(u)}return function t(e){switch(r=e,e.type){case"GeometryCollection":e.geometries.forEach(t);break;case"LineString":u(e.arcs);break;case"MultiLineString":case"Polygon":s(e.arcs);break;case"MultiPolygon":e.arcs.forEach(s)}}(e),a.forEach(null==n?function(t){i.push(t[0].i)}:function(t){n(t[0].g,t[t.length-1].g)&&i.push(t[0].i)}),i}(0,e,n);else for(i=0,r=new Array(a=t.arcs.length);i1?(Ne[t]=e,this):Ne.hasOwnProperty(t)?Ne[t]:null},Oe=new Date,De=new Date;function Re(t,e,n,r){function i(e){return t(e=new Date(+e)),e}return i.floor=i,i.ceil=function(n){return t(n=new Date(n-1)),e(n,1),t(n),n},i.round=function(t){var e=i(t),n=i.ceil(t);return t-e0))return u;do{u.push(o=new Date(+n)),e(n,a),t(n)}while(o=e)for(;t(e),!n(e);)e.setTime(e-1)},function(t,r){if(t>=t)if(r<0)for(;++r<=0;)for(;e(t,-1),!n(t););else for(;--r>=0;)for(;e(t,1),!n(t););})},n&&(i.count=function(e,r){return Oe.setTime(+e),De.setTime(+r),t(Oe),t(De),Math.floor(n(Oe,De))},i.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?i.filter(r?function(e){return r(e)%t==0}:function(e){return i.count(0,e)%t==0}):i:null}),i}var Te=Re(function(){},function(t,e){t.setTime(+t+e)},function(t,e){return e-t});Te.every=function(t){return t=Math.floor(t),isFinite(t)&&t>0?t>1?Re(function(e){e.setTime(Math.floor(e/t)*t)},function(e,n){e.setTime(+e+n*t)},function(e,n){return(n-e)/t}):Te:null};var Pe=6e4,Le=6048e5,qe=Re(function(t){t.setTime(1e3*Math.floor(t/1e3))},function(t,e){t.setTime(+t+1e3*e)},function(t,e){return(e-t)/1e3},function(t){return t.getUTCSeconds()}),Ue=Re(function(t){t.setTime(Math.floor(t/Pe)*Pe)},function(t,e){t.setTime(+t+e*Pe)},function(t,e){return(e-t)/Pe},function(t){return t.getMinutes()}),je=Re(function(t){var e=t.getTimezoneOffset()*Pe%36e5;e<0&&(e+=36e5),t.setTime(36e5*Math.floor((+t-e)/36e5)+e)},function(t,e){t.setTime(+t+36e5*e)},function(t,e){return(e-t)/36e5},function(t){return t.getHours()}),Fe=Re(function(t){t.setHours(0,0,0,0)},function(t,e){t.setDate(t.getDate()+e)},function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Pe)/864e5},function(t){return t.getDate()-1});function Ie(t){return Re(function(e){e.setDate(e.getDate()-(e.getDay()+7-t)%7),e.setHours(0,0,0,0)},function(t,e){t.setDate(t.getDate()+7*e)},function(t,e){return(e-t-(e.getTimezoneOffset()-t.getTimezoneOffset())*Pe)/Le})}var $e=Ie(0),Be=Ie(1),We=(Ie(2),Ie(3),Ie(4)),He=(Ie(5),Ie(6),Re(function(t){t.setDate(1),t.setHours(0,0,0,0)},function(t,e){t.setMonth(t.getMonth()+e)},function(t,e){return e.getMonth()-t.getMonth()+12*(e.getFullYear()-t.getFullYear())},function(t){return t.getMonth()})),Ye=Re(function(t){t.setMonth(0,1),t.setHours(0,0,0,0)},function(t,e){t.setFullYear(t.getFullYear()+e)},function(t,e){return e.getFullYear()-t.getFullYear()},function(t){return t.getFullYear()});Ye.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Re(function(e){e.setFullYear(Math.floor(e.getFullYear()/t)*t),e.setMonth(0,1),e.setHours(0,0,0,0)},function(e,n){e.setFullYear(e.getFullYear()+n*t)}):null};var Ge=Re(function(t){t.setUTCSeconds(0,0)},function(t,e){t.setTime(+t+e*Pe)},function(t,e){return(e-t)/Pe},function(t){return t.getUTCMinutes()}),Ve=Re(function(t){t.setUTCMinutes(0,0,0)},function(t,e){t.setTime(+t+36e5*e)},function(t,e){return(e-t)/36e5},function(t){return t.getUTCHours()}),Xe=Re(function(t){t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCDate(t.getUTCDate()+e)},function(t,e){return(e-t)/864e5},function(t){return t.getUTCDate()-1});function Je(t){return Re(function(e){e.setUTCDate(e.getUTCDate()-(e.getUTCDay()+7-t)%7),e.setUTCHours(0,0,0,0)},function(t,e){t.setUTCDate(t.getUTCDate()+7*e)},function(t,e){return(e-t)/Le})}var Ze=Je(0),Qe=Je(1),Ke=(Je(2),Je(3),Je(4)),tn=(Je(5),Je(6),Re(function(t){t.setUTCDate(1),t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCMonth(t.getUTCMonth()+e)},function(t,e){return e.getUTCMonth()-t.getUTCMonth()+12*(e.getUTCFullYear()-t.getUTCFullYear())},function(t){return t.getUTCMonth()})),en=Re(function(t){t.setUTCMonth(0,1),t.setUTCHours(0,0,0,0)},function(t,e){t.setUTCFullYear(t.getUTCFullYear()+e)},function(t,e){return e.getUTCFullYear()-t.getUTCFullYear()},function(t){return t.getUTCFullYear()});function nn(t){if(0<=t.y&&t.y<100){var e=new Date(-1,t.m,t.d,t.H,t.M,t.S,t.L);return e.setFullYear(t.y),e}return new Date(t.y,t.m,t.d,t.H,t.M,t.S,t.L)}function rn(t){if(0<=t.y&&t.y<100){var e=new Date(Date.UTC(-1,t.m,t.d,t.H,t.M,t.S,t.L));return e.setUTCFullYear(t.y),e}return new Date(Date.UTC(t.y,t.m,t.d,t.H,t.M,t.S,t.L))}function an(t){return{y:t,m:0,d:1,H:0,M:0,S:0,L:0}}en.every=function(t){return isFinite(t=Math.floor(t))&&t>0?Re(function(e){e.setUTCFullYear(Math.floor(e.getUTCFullYear()/t)*t),e.setUTCMonth(0,1),e.setUTCHours(0,0,0,0)},function(e,n){e.setUTCFullYear(e.getUTCFullYear()+n*t)}):null};var on,un,sn,fn,cn,ln={"-":"",_:" ",0:"0"},hn=/^\s*\d+/,dn=/^%/,pn=/[\\^$*+?|[\]().{}]/g;function vn(t,e,n){var r=t<0?"-":"",i=(r?-t:t)+"",a=i.length;return r+(a68?1900:2e3),n+r[0].length):-1}function Sn(t,e,n){var r=/^(Z)|([+-]\d\d)(?::?(\d\d))?/.exec(e.slice(n,n+6));return r?(t.Z=r[1]?0:-(r[2]+(r[3]||"00")),n+r[0].length):-1}function An(t,e,n){var r=hn.exec(e.slice(n,n+2));return r?(t.m=r[0]-1,n+r[0].length):-1}function Cn(t,e,n){var r=hn.exec(e.slice(n,n+2));return r?(t.d=+r[0],n+r[0].length):-1}function Nn(t,e,n){var r=hn.exec(e.slice(n,n+3));return r?(t.m=0,t.d=+r[0],n+r[0].length):-1}function zn(t,e,n){var r=hn.exec(e.slice(n,n+2));return r?(t.H=+r[0],n+r[0].length):-1}function On(t,e,n){var r=hn.exec(e.slice(n,n+2));return r?(t.M=+r[0],n+r[0].length):-1}function Dn(t,e,n){var r=hn.exec(e.slice(n,n+2));return r?(t.S=+r[0],n+r[0].length):-1}function Rn(t,e,n){var r=hn.exec(e.slice(n,n+3));return r?(t.L=+r[0],n+r[0].length):-1}function Tn(t,e,n){var r=hn.exec(e.slice(n,n+6));return r?(t.L=Math.floor(r[0]/1e3),n+r[0].length):-1}function Pn(t,e,n){var r=dn.exec(e.slice(n,n+1));return r?n+r[0].length:-1}function Ln(t,e,n){var r=hn.exec(e.slice(n));return r?(t.Q=+r[0],n+r[0].length):-1}function qn(t,e,n){var r=hn.exec(e.slice(n));return r?(t.Q=1e3*+r[0],n+r[0].length):-1}function Un(t,e){return vn(t.getDate(),e,2)}function jn(t,e){return vn(t.getHours(),e,2)}function Fn(t,e){return vn(t.getHours()%12||12,e,2)}function In(t,e){return vn(1+Fe.count(Ye(t),t),e,3)}function $n(t,e){return vn(t.getMilliseconds(),e,3)}function Bn(t,e){return $n(t,e)+"000"}function Wn(t,e){return vn(t.getMonth()+1,e,2)}function Hn(t,e){return vn(t.getMinutes(),e,2)}function Yn(t,e){return vn(t.getSeconds(),e,2)}function Gn(t){var e=t.getDay();return 0===e?7:e}function Vn(t,e){return vn($e.count(Ye(t),t),e,2)}function Xn(t,e){var n=t.getDay();return t=n>=4||0===n?We(t):We.ceil(t),vn(We.count(Ye(t),t)+(4===Ye(t).getDay()),e,2)}function Jn(t){return t.getDay()}function Zn(t,e){return vn(Be.count(Ye(t),t),e,2)}function Qn(t,e){return vn(t.getFullYear()%100,e,2)}function Kn(t,e){return vn(t.getFullYear()%1e4,e,4)}function tr(t){var e=t.getTimezoneOffset();return(e>0?"-":(e*=-1,"+"))+vn(e/60|0,"0",2)+vn(e%60,"0",2)}function er(t,e){return vn(t.getUTCDate(),e,2)}function nr(t,e){return vn(t.getUTCHours(),e,2)}function rr(t,e){return vn(t.getUTCHours()%12||12,e,2)}function ir(t,e){return vn(1+Xe.count(en(t),t),e,3)}function ar(t,e){return vn(t.getUTCMilliseconds(),e,3)}function or(t,e){return ar(t,e)+"000"}function ur(t,e){return vn(t.getUTCMonth()+1,e,2)}function sr(t,e){return vn(t.getUTCMinutes(),e,2)}function fr(t,e){return vn(t.getUTCSeconds(),e,2)}function cr(t){var e=t.getUTCDay();return 0===e?7:e}function lr(t,e){return vn(Ze.count(en(t),t),e,2)}function hr(t,e){var n=t.getUTCDay();return t=n>=4||0===n?Ke(t):Ke.ceil(t),vn(Ke.count(en(t),t)+(4===en(t).getUTCDay()),e,2)}function dr(t){return t.getUTCDay()}function pr(t,e){return vn(Qe.count(en(t),t),e,2)}function vr(t,e){return vn(t.getUTCFullYear()%100,e,2)}function gr(t,e){return vn(t.getUTCFullYear()%1e4,e,4)}function mr(){return"+0000"}function yr(){return"%"}function br(t){return+t}function _r(t){return Math.floor(+t/1e3)}function xr(t){return on=function(t){var e=t.dateTime,n=t.date,r=t.time,i=t.periods,a=t.days,o=t.shortDays,u=t.months,s=t.shortMonths,f=mn(i),c=yn(i),l=mn(a),h=yn(a),d=mn(o),p=yn(o),v=mn(u),g=yn(u),m=mn(s),y=yn(s),b={a:function(t){return o[t.getDay()]},A:function(t){return a[t.getDay()]},b:function(t){return s[t.getMonth()]},B:function(t){return u[t.getMonth()]},c:null,d:Un,e:Un,f:Bn,H:jn,I:Fn,j:In,L:$n,m:Wn,M:Hn,p:function(t){return i[+(t.getHours()>=12)]},Q:br,s:_r,S:Yn,u:Gn,U:Vn,V:Xn,w:Jn,W:Zn,x:null,X:null,y:Qn,Y:Kn,Z:tr,"%":yr},_={a:function(t){return o[t.getUTCDay()]},A:function(t){return a[t.getUTCDay()]},b:function(t){return s[t.getUTCMonth()]},B:function(t){return u[t.getUTCMonth()]},c:null,d:er,e:er,f:or,H:nr,I:rr,j:ir,L:ar,m:ur,M:sr,p:function(t){return i[+(t.getUTCHours()>=12)]},Q:br,s:_r,S:fr,u:cr,U:lr,V:hr,w:dr,W:pr,x:null,X:null,y:vr,Y:gr,Z:mr,"%":yr},x={a:function(t,e,n){var r=d.exec(e.slice(n));return r?(t.w=p[r[0].toLowerCase()],n+r[0].length):-1},A:function(t,e,n){var r=l.exec(e.slice(n));return r?(t.w=h[r[0].toLowerCase()],n+r[0].length):-1},b:function(t,e,n){var r=m.exec(e.slice(n));return r?(t.m=y[r[0].toLowerCase()],n+r[0].length):-1},B:function(t,e,n){var r=v.exec(e.slice(n));return r?(t.m=g[r[0].toLowerCase()],n+r[0].length):-1},c:function(t,n,r){return k(t,e,n,r)},d:Cn,e:Cn,f:Tn,H:zn,I:zn,j:Nn,L:Rn,m:An,M:On,p:function(t,e,n){var r=f.exec(e.slice(n));return r?(t.p=c[r[0].toLowerCase()],n+r[0].length):-1},Q:Ln,s:qn,S:Dn,u:_n,U:xn,V:wn,w:bn,W:Mn,x:function(t,e,r){return k(t,n,e,r)},X:function(t,e,n){return k(t,r,e,n)},y:En,Y:kn,Z:Sn,"%":Pn};function w(t,e){return function(n){var r,i,a,o=[],u=-1,s=0,f=t.length;for(n instanceof Date||(n=new Date(+n));++u53)return null;"w"in a||(a.w=1),"Z"in a?(r=(i=(r=rn(an(a.y))).getUTCDay())>4||0===i?Qe.ceil(r):Qe(r),r=Xe.offset(r,7*(a.V-1)),a.y=r.getUTCFullYear(),a.m=r.getUTCMonth(),a.d=r.getUTCDate()+(a.w+6)%7):(r=(i=(r=e(an(a.y))).getDay())>4||0===i?Be.ceil(r):Be(r),r=Fe.offset(r,7*(a.V-1)),a.y=r.getFullYear(),a.m=r.getMonth(),a.d=r.getDate()+(a.w+6)%7)}else("W"in a||"U"in a)&&("w"in a||(a.w="u"in a?a.u%7:"W"in a?1:0),i="Z"in a?rn(an(a.y)).getUTCDay():e(an(a.y)).getDay(),a.m=0,a.d="W"in a?(a.w+6)%7+7*a.W-(i+5)%7:a.w+7*a.U-(i+6)%7);return"Z"in a?(a.H+=a.Z/100|0,a.M+=a.Z%100,rn(a)):e(a)}}function k(t,e,n,r){for(var i,a,o=0,u=e.length,s=n.length;o=s)return-1;if(37===(i=e.charCodeAt(o++))){if(i=e.charAt(o++),!(a=x[i in ln?e.charAt(o++):i])||(r=a(t,n,r))<0)return-1}else if(i!=n.charCodeAt(r++))return-1}return r}return b.x=w(n,b),b.X=w(r,b),b.c=w(e,b),_.x=w(n,_),_.X=w(r,_),_.c=w(e,_),{format:function(t){var e=w(t+="",b);return e.toString=function(){return t},e},parse:function(t){var e=M(t+="",nn);return e.toString=function(){return t},e},utcFormat:function(t){var e=w(t+="",_);return e.toString=function(){return t},e},utcParse:function(t){var e=M(t,rn);return e.toString=function(){return t},e}}}(t),un=on.format,sn=on.parse,fn=on.utcFormat,cn=on.utcParse,on}xr({dateTime:"%x, %X",date:"%-m/%-d/%Y",time:"%-I:%M:%S %p",periods:["AM","PM"],days:["Sunday","Monday","Tuesday","Wednesday","Thursday","Friday","Saturday"],shortDays:["Sun","Mon","Tue","Wed","Thu","Fri","Sat"],months:["January","February","March","April","May","June","July","August","September","October","November","December"],shortMonths:["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"]});Date.prototype.toISOString||fn("%Y-%m-%dT%H:%M:%S.%LZ");+new Date("2000-01-01T00:00:00.000Z")||cn("%Y-%m-%dT%H:%M:%S.%LZ");var wr=function(t,e,n){var r=ze((e=e||{}).type||"json");return r||o("Unknown data format type: "+e.type),t=r(t,e),e.parse&&function(t,e,n){if(!t.length)return;n=n||sn;var r,i,a,o,u,s,f,c=t.columns||Object.keys(t[0]);"auto"===e&&(e=ge(t,c));for(c=Object.keys(e),r=c.map(function(t){var r,i,a=e[t];if(a&&(0===a.indexOf("date:")||0===a.indexOf("utc:")))return("'"===(i=(r=a.split(/:(.+)?/,2))[1])[0]&&"'"===i[i.length-1]||'"'===i[0]&&'"'===i[i.length-1])&&(i=i.slice(1,-1)),"utc"===r[0]?cn(i):n(i);if(!he[a])throw Error("Illegal format pattern: "+t+":"+a);return he[a]}),o=0,s=t.length,f=c.length;oe&&r(i,a=t[o=n-1>>1])<0;)t[n]=a,n=o;return t[n]=i}function jr(t,e,n){for(var r,i=e,a=t.length,o=t[e],u=2*e+1;u=0&&(u=r),t[e]=t[u],u=2*(e=u)+1;return t[e]=o,Ur(t,i,e,n)}function Fr(){this._log=k(),this.logLevel(x),this._clock=0,this._rank=0;try{this._loader=ie()}catch(t){}this._touched=ft(p),this._pulses={},this._pulse=null,this._heap=new Lr(function(t,e){return t.qrank-e.qrank}),this._postrun=[]}qr.size=function(){return this.nodes.length},qr.clear=function(){return this.nodes=[],this},qr.peek=function(){return this.nodes[0]},qr.push=function(t){var e=this.nodes;return e.push(t),Ur(e,0,e.length-1,this.cmp)},qr.pop=function(){var t,e=this.nodes,n=e.pop();return e.length?(t=e[0],e[0]=n,jr(e,0,this.cmp)):t=n,t},qr.replace=function(t){var e=this.nodes,n=e[0];return e[0]=t,jr(e,0,this.cmp),n},qr.pushpop=function(t){var e=this.nodes,n=e[0];return e.length&&this.cmp(n,t)<0&&(e[0]=t,t=n,jr(e,0,this.cmp)),t};var Ir=Fr.prototype;function $r(t){return function(){return this._log[t].apply(this,arguments)}}function Br(t,e){St.call(this,t,null,e)}Ir.stamp=function(){return this._clock},Ir.loader=function(t){return arguments.length?(this._loader=t,this):this._loader},Ir.cleanThreshold=1e4,Ir.add=function(t,e,n,r){var i,a=1;return t instanceof St?i=t:t&&t.prototype instanceof St?i=new t:j(t)?i=new St(null,t):(a=0,i=new St(t,e)),this.rank(i),a&&(r=n,n=e),n&&this.connect(i,i.parameters(n,r)),this.touch(i),i},Ir.connect=function(t,e){var n,r,i=t.rank;for(n=0,r=e.length;n=0;)i.push(e=n[r]),e===t&&o("Cycle detected in dataflow graph.")},Ir.pulse=function(t,e,n){this.touch(t,n||Pr);var r=new Ar(this,this._clock+(this._pulse?0:1)),i=t.pulse&&t.pulse.source||[];return r.target=t,this._pulses[t.id]=e.pulse(r,i),this},Ir.touch=function(t,e){var n=e||Pr;return this._pulse?this._enqueue(t):this._touched.add(t),n.skip&&t.skip(!0),this},Ir.update=function(t,e,n){var r=n||Pr;return(t.set(e)||r.force)&&this.touch(t,r),this},Ir.changeset=_t,Ir.ingest=function(t,e,n){return this.pulse(t,this.changeset().insert(wr(e,n)))},Ir.request=function(t,e,n){var r=this,i=r._pending||function(t){var e,n,r=new Promise(function(t,r){e=t,n=r});return r.requests=0,r.done=function(){0==--r.requests&&t.runAfter(function(){t._pending=null;try{t.run(),e(t)}catch(t){n(t)}})},t._pending=r}(r);i.requests+=1,r.loader().load(e,{context:"dataflow"}).then(function(e){r.ingest(t,e,n)},function(t){r.error("Loading failed",e,t)}).catch(function(t){r.error("Data ingestion failed",e,t)}).then(i.done,i.done)},Ir.events=function(t,e,n,r){for(var i,a=this,o=Ot(n,r),u=function(t){t.dataflow=a;try{o.receive(t)}catch(t){a.error(t)}finally{a.run()}},s=0,f=(i="string"==typeof t&&"undefined"!=typeof document?document.querySelectorAll(t):U(t)).length;s=w&&(r=Date.now(),a.debug("-- START PROPAGATION ("+a._clock+") -----")),a._touched.forEach(function(t){a._enqueue(t,!0)}),a._touched=ft(p);try{for(;a._heap.size()>0;)(e=a._heap.pop()).rank===e.qrank?(n=e.run(a._getPulse(e,t)),u>=M&&a.debug(e.id,n===Sr?"STOP":n,e),n!==Sr&&(a._pulse=n,e._targets&&e._targets.forEach(function(t){a._enqueue(t)})),++o):a._enqueue(e,!0)}catch(t){i=t}if(a._pulses={},a._pulse=null,u>=w&&(r=Date.now()-r,a.info("> Pulse "+a._clock+": "+o+" operators; "+r+"ms")),i&&(a._postrun=[],a.error(i)),a._onrun)try{a._onrun(a,o,i)}catch(t){a.error(t)}if(a._postrun.length){var s=a._postrun;a._postrun=[],s.sort(function(t,e){return e.priority-t.priority}).forEach(function(t){Tr(a,t.callback)})}return o},Ir.runAsync=function(){return this._pending||Promise.resolve(this.run())},Ir.runAfter=function(t,e,n){this._pulse||e?this._postrun.push({priority:n||0,callback:t}):Tr(this,t)},Ir._enqueue=function(t,e){var n=!this._pulses[t.id];n&&(this._pulses[t.id]=this._pulse),(n||e)&&(t.qrank=t.rank,this._heap.push(t))},Ir._getPulse=function(t,e){var n,r=t.source,i=this._clock;return r&&s(r)?new Dr(this,i,n=r.map(function(t){return t.pulse}),e):(n=this._pulses[t.id],r&&((r=r.pulse)&&r!==Sr?r.stamp===i&&n.target!==t?n=r:n.source=r.source:n.source=[]),n)},Ir.error=$r("error"),Ir.warn=$r("warn"),Ir.info=$r("info"),Ir.debug=$r("debug"),Ir.logLevel=$r("level");var Wr=G(Br,St);Wr.run=function(t){return t.stamp<=this.stamp?t.StopPropagation:(this.skip()?this.skip(!1):e=this.evaluate(t),(e=e||t)!==t.StopPropagation&&(this.pulse=e),this.stamp=t.stamp,e);var e},Wr.evaluate=function(t){var e=this.marshall(t.stamp),n=this.transform(e,t);return e.clear(),n},Wr.transform=function(){};var Hr={};function Yr(t){var e=Gr(t);return e&&e.Definition||null}function Gr(t){return t=t&&t.toLowerCase(),Hr.hasOwnProperty(t)?Hr[t]:null}function Vr(t){return t&&t.length?1===t.length?t[0]:(e=t,function(t){for(var n=e.length,r=1,i=String(e[0](t));r 1 ? this.dev / (this.valid-1) : 0",req:["mean"],idx:1}),variancep:Kr({name:"variancep",set:"this.valid > 1 ? this.dev / this.valid : 0",req:["variance"],idx:2}),stdev:Kr({name:"stdev",set:"this.valid > 1 ? Math.sqrt(this.dev / (this.valid-1)) : 0",req:["variance"],idx:2}),stdevp:Kr({name:"stdevp",set:"this.valid > 1 ? Math.sqrt(this.dev / this.valid) : 0",req:["variance"],idx:2}),stderr:Kr({name:"stderr",set:"this.valid > 1 ? Math.sqrt(this.dev / (this.valid * (this.valid-1))) : 0",req:["variance"],idx:2}),distinct:Kr({name:"distinct",set:"cell.data.distinct(this.get)",req:["values"],idx:3}),ci0:Kr({name:"ci0",set:"cell.data.ci0(this.get)",req:["values"],idx:3}),ci1:Kr({name:"ci1",set:"cell.data.ci1(this.get)",req:["values"],idx:3}),median:Kr({name:"median",set:"cell.data.q2(this.get)",req:["values"],idx:3}),q1:Kr({name:"q1",set:"cell.data.q1(this.get)",req:["values"],idx:3}),q3:Kr({name:"q3",set:"cell.data.q3(this.get)",req:["values"],idx:3}),argmin:Kr({name:"argmin",init:"this.argmin = null;",add:"if (v < this.min) this.argmin = t;",rem:"if (v <= this.min) this.argmin = null;",set:"this.argmin || cell.data.argmin(this.get)",req:["min"],str:["values"],idx:3}),argmax:Kr({name:"argmax",init:"this.argmax = null;",add:"if (v > this.max) this.argmax = t;",rem:"if (v >= this.max) this.argmax = null;",set:"this.argmax || cell.data.argmax(this.get)",req:["max"],str:["values"],idx:3}),min:Kr({name:"min",init:"this.min = null;",add:"if (v < this.min || this.min === null) this.min = v;",rem:"if (v <= this.min) this.min = NaN;",set:"this.min = (isNaN(this.min) ? cell.data.min(this.get) : this.min)",str:["values"],idx:4}),max:Kr({name:"max",init:"this.max = null;",add:"if (v > this.max || this.max === null) this.max = v;",rem:"if (v >= this.max) this.max = NaN;",set:"this.max = (isNaN(this.max) ? cell.data.max(this.get) : this.max)",str:["values"],idx:4})},Zr=Object.keys(Jr);function Qr(t,e){return Jr[t](e)}function Kr(t){return function(e){var n=B({init:"",add:"",rem:"",idx:0},t);return n.out=e||t.name,n}}function ti(t,e){return t.idx-e.idx}function ei(t,e){var n=e||v,r="var cell = this.cell; this.valid = 0; this.missing = 0;",i="this.cell = cell; this.init();",a="if(v==null){++this.missing; return;} if(v!==v) return; ++this.valid;",o="if(v==null){--this.missing; return;} if(v!==v) return; --this.valid;",u="var cell = this.cell;";return function(t,e){var n,r=t.reduce(function t(n,r){function i(e){n[e]||t(n,n[e]=Jr[e]())}return r.req&&r.req.forEach(i),e&&r.str&&r.str.forEach(i),n},t.reduce(function(t,e){return t[e.name]=e,t},{})),i=[];for(n in r)i.push(r[n]);return i.sort(ti)}(t,!0).forEach(function(t){r+=t.init,a+=t.add,o+=t.rem}),t.slice().sort(ti).forEach(function(t){u+="t['"+t.out+"']="+t.set+";"}),u+="return t;",(i=Function("cell",i)).prototype.init=Function(r),i.prototype.add=Function("v","t",a),i.prototype.rem=Function("v","t",o),i.prototype.set=Function("t",u),i.prototype.get=n,i.fields=t.map(function(t){return t.out}),i}var ni=function(t){var e,n,r,i,a,o,u,s,f=t.maxbins||20,c=t.base||10,l=Math.log(c),h=t.divide||[5,2],d=t.extent[0],p=t.extent[1],v=p-d;if(t.step)e=t.step;else if(t.steps){for(a=v/f,o=0,u=t.steps.length;of;)e*=c;for(o=0,u=h.length;o=r&&v/a<=f&&(e=a)}return i=(a=Math.log(e))>=0?0:1+~~(-a/l),s=Math.pow(c,-i-1),(t.nice||void 0===t.nice)&&(d=d<(a=Math.floor(d/e+s)*e)?a-e:a,p=Math.ceil(p/e)*e),{start:d,stop:p,step:e}},ri=function(t,e){var n,r=[],i=t.length,a=-1;if(null==e)for(;++ae?1:t>=e?0:NaN},oi=function(t){var e;return 1===t.length&&(e=t,t=function(t,n){return ai(e(t),n)}),{left:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[a],n)<0?r=a+1:i=a}return r},right:function(e,n,r,i){for(null==r&&(r=0),null==i&&(i=e.length);r>>1;t(e[a],n)>0?i=a:r=a+1}return r}}};var ui=oi(ai),si=ui.right,fi=ui.left;var ci=function(t){return null===t?NaN:+t},li=function(t,e){var n,r,i=t.length,a=0,o=-1,u=0,s=0;if(null==e)for(;++o1)return s/(a-1)},hi=function(t,e){var n,r,i,a=t.length,o=-1;if(null==e){for(;++o=n)for(r=i=n;++on&&(r=n),i=n)for(r=i=n;++on&&(r=n),i0)return[t];if((r=e0)for(t=Math.ceil(t/o),e=Math.floor(e/o),a=new Array(i=Math.ceil(e-t+1));++u=0?(a>=pi?10:a>=vi?5:a>=gi?2:1)*Math.pow(10,i):-Math.pow(10,-i)/(a>=pi?10:a>=vi?5:a>=gi?2:1)}function bi(t,e,n){var r=Math.abs(e-t)/Math.max(0,n),i=Math.pow(10,Math.floor(Math.log(r)/Math.LN10)),a=r/i;return a>=pi?i*=10:a>=vi?i*=5:a>=gi&&(i*=2),e=1)return+n(t[r-1],r-1,t);var r,i=(r-1)*e,a=Math.floor(i),o=+n(t[a],a,t);return o+(+n(t[a+1],a+1,t)-o)*(i-a)}},wi=function(t,e){var n,r,i=t.length,a=-1;if(null==e){for(;++a=n)for(r=n;++ar&&(r=n)}else for(;++a=n)for(r=n;++ar&&(r=n);return r},Mi=function(t){for(var e,n,r,i=t.length,a=-1,o=0;++a=0;)for(e=(r=t[i]).length;--e>=0;)n[--o]=r[e];return n},ki=function(t,e){for(var n=e.length,r=new Array(n);n--;)r[n]=t[e[n]];return r};var Ei=function(t,n,r,i){var a,o,u,s,f=ri(t,i),c=f.length,l=n;for(u=0,s=Array(l);u1);return n=Math.sqrt(-2*Math.log(t)/t),a=r+u*n*i,r+o*n*i},pdf:function(t){var e=Math.exp(Math.pow(t-r,2)/(-2*Math.pow(i,2)));return 1/(i*Math.sqrt(2*Math.PI))*e},cdf:function(t){var e,n=(t-r)/i,a=Math.abs(n);if(a>37)e=0;else{var o=Math.exp(-a*a/2);a<7.07106781186547?(e=o*((((((.0352624965998911*a+.700383064443688)*a+6.37396220353165)*a+33.912866078383)*a+112.079291497871)*a+221.213596169931)*a+220.206867912376),e/=((((((.0883883476483184*a+1.75566716318264)*a+16.064177579207)*a+86.7807322029461)*a+296.564248779674)*a+637.333633378831)*a+793.826512519948)*a+440.413735824752):e=o/(a+1/(a+2/(a+3/(a+4/(a+.65)))))/2.506628274631}return n>0?1-e:e},icdf:function(t){if(t<=0||t>=1)return NaN;var e=2*t-1,n=8*(Math.PI-3)/(3*Math.PI*(4-Math.PI)),a=2/(Math.PI*n)+Math.log(1-Math.pow(e,2))/2,o=Math.log(1-e*e)/n,u=(e>0?1:-1)*Math.sqrt(Math.sqrt(a*a-o)-a);return r+i*Math.SQRT2*u}};return o.mean(t).stdev(n)},Ci=function(t,n){var r=Ai(),i={},a=0;return i.data=function(e){return arguments.length?(t=e,a=e?e.length:0,i.bandwidth(n)):t},i.bandwidth=function(e){return arguments.length?(!(n=e)&&t&&(a=(r=t).length,o=Si(r),u=(o[2]-o[0])/1.34,n=1.06*Math.min(Math.sqrt(li(r)),u)*Math.pow(a,-.2)),i):n;var r,a,o,u},i.sample=function(){return t[~~(e.random()*a)]+n*r.sample()},i.pdf=function(e){for(var i=0,o=0;o=r&&t<=i?1/a:0},o.cdf=function(t){return ti?1:(t-r)/a},o.icdf=function(t){return t>=0&&t<=1?r+t*a:NaN},o.min(t).max(n)};function Oi(t){this._key=t?h(t):dt,this.reset()}var Di=Oi.prototype;function Ri(t){Br.call(this,null,t),this._adds=[],this._mods=[],this._alen=0,this._mlen=0,this._drop=!0,this._cross=!1,this._dims=[],this._dnames=[],this._measures=[],this._countOnly=!1,this._counts=null,this._prev=null,this._inputs=null,this._outputs=null}Di.reset=function(){this._add=[],this._rem=[],this._ext=null,this._get=null,this._q=null},Di.add=function(t){this._add.push(t)},Di.rem=function(t){this._rem.push(t)},Di.values=function(){if(this._get=null,0===this._rem.length)return this._add;var t,e,n,r=this._add,i=this._rem,a=this._key,o=r.length,u=i.length,s=Array(o-u),f={};for(t=0;t=0;)e=t(n[r])+"",i.hasOwnProperty(e)||(i[e]=1,++a);return a},Di.extent=function(t){if(this._get!==t||!this._ext){var e=this.values(),n=W(e,t);this._ext=[e[n[0]],e[n[1]]],this._get=t}return this._ext},Di.argmin=function(t){return this.extent(t)[0]||{}},Di.argmax=function(t){return this.extent(t)[1]||{}},Di.min=function(t){var e=this.extent(t)[0];return null!=e?t(e):1/0},Di.max=function(t){var e=this.extent(t)[1];return null!=e?t(e):-1/0},Di.quartile=function(t){return this._get===t&&this._q||(this._q=Si(this.values(),t),this._get=t),this._q},Di.q1=function(t){return this.quartile(t)[0]},Di.q2=function(t){return this.quartile(t)[1]},Di.q3=function(t){return this.quartile(t)[2]},Di.ci=function(t){return this._get===t&&this._ci||(this._ci=Ei(this.values(),1e3,.05,t),this._get=t),this._ci},Di.ci0=function(t){return this.ci(t)[0]},Di.ci1=function(t){return this.ci(t)[1]},Ri.Definition={type:"Aggregate",metadata:{generates:!0,changes:!0},params:[{name:"groupby",type:"field",array:!0},{name:"ops",type:"enum",array:!0,values:Zr},{name:"fields",type:"field",null:!0,array:!0},{name:"as",type:"string",null:!0,array:!0},{name:"drop",type:"boolean",default:!0},{name:"cross",type:"boolean",default:!1},{name:"key",type:"field"}]};var Ti=G(Ri,Br);function Pi(t){Br.call(this,null,t)}Ti.transform=function(t,e){var n,r=this,i=e.fork(e.NO_SOURCE|e.NO_FIELDS);return this.stamp=i.stamp,this.value&&((n=t.modified())||e.modified(this._inputs))?(this._prev=this.value,this.value=n?this.init(t):{},e.visit(e.SOURCE,function(t){r.add(t)})):(this.value=this.value||this.init(t),e.visit(e.REM,function(t){r.rem(t)}),e.visit(e.ADD,function(t){r.add(t)})),i.modifies(this._outputs),r._drop=!1!==t.drop,t.cross&&r._dims.length>1&&(r._drop=!1,this.cross()),r.changes(i)},Ti.cross=function(){var t=this,e=t.value,n=t._dnames,r=n.map(function(){return{}}),i=n.length;function a(t){var e,a,o,u;for(e in t)for(o=t[e].tuple,a=0;aa&&(a=e))}),this.value=[i,a]};var Ki=G(Qi,St);function ta(t){Br.call(this,{},t),this._keys=Y();var e=this._targets=[];e.active=0,e.forEach=function(t){for(var n=0,r=e.active;nn.cleanThreshold&&n.runAfter(o.clean),e},G(na,St),ia.Definition={type:"Filter",metadata:{changes:!0},params:[{name:"expr",type:"expr",required:!0}]},G(ia,Br).transform=function(t,e){var n=e.dataflow,r=this.value,i=e.fork(),a=i.add,o=i.rem,u=i.mod,s=t.expr,f=!0;function c(e){var n=dt(e),i=s(e,t),c=r.get(n);i&&c?(r.delete(n),a.push(e)):i||c?f&&i&&!c&&u.push(e):(r.set(n,1),o.push(e))}return e.visit(e.REM,function(t){var e=dt(t);r.has(e)?r.delete(e):o.push(t)}),e.visit(e.ADD,function(e){s(e,t)?a.push(e):r.set(dt(e),1)}),e.visit(e.MOD,c),t.modified()&&(f=!1,e.visit(e.REFLOW,c)),r.empty>n.cleanThreshold&&n.runAfter(r.clean),i},oa.Definition={type:"Flatten",metadata:{generates:!0,source:!0},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"as",type:"string",array:!0}]},G(oa,Br).transform=function(t,e){var n=e.fork(e.NO_SOURCE),r=t.fields,i=aa(r,t.as||[]),a=i.length;return n.rem=this.value,e.visit(e.SOURCE,function(t){for(var e,o,u,s=r.map(function(e){return e(t)}),f=s.reduce(function(t,e){return Math.max(t,e.length)},0),c=0;c0){for(n=[];--u>=0;)n.push(i=vt(s(t))),a.push(i);o.add=o.add.length?o.materialize(o.ADD).add.concat(n):n}else r=a.slice(0,-u),o.rem=o.rem.length?o.materialize(o.REM).rem.concat(r):r,a=a.slice(-u);return o.source=this.value=a,o};var ca={value:"value",median:function(t,e){var n,r=t.length,i=-1,a=[];if(null==e)for(;++i=n)for(r=n;++an&&(r=n)}else for(;++a=n)for(r=n;++an&&(r=n);return r},max:wi},la=[];function ha(t){Br.call(this,[],t)}function da(t){Ri.call(this,t)}ha.Definition={type:"Impute",metadata:{generates:!0,changes:!0},params:[{name:"field",type:"field",required:!0},{name:"key",type:"field",required:!0},{name:"keyvals",array:!0},{name:"groupby",type:"field",array:!0},{name:"method",type:"enum",default:"value",values:["value","mean","median","max","min"]},{name:"value",default:0}]},G(ha,Br).transform=function(t,e){var n,r,a,u,s,f,c,l,h,d,p=e.fork(e.ALL),v=function(t){var e,n=t.method||ca.value;if(null!=ca[n])return n===ca.value?(e=void 0!==t.value?t.value:0,function(){return e}):ca[n];o("Unrecognized imputation method: "+n)}(t),g=function(t){var e=t.field;return function(t){return t?e(t):NaN}}(t),m=i(t.field),y=i(t.key),b=(t.groupby||[]).map(i),_=function(t,e,n,r){var i,a,o,u,s,f,c,l,h=function(t){return t(l)},d=[],p=r?r.slice():[],v={},g={};for(p.forEach(function(t,e){v[t]=e+1}),u=0,c=t.length;ua&&(a=r[1]);return[i,a]}function _a(t){St.call(this,null,xa,t)}function xa(t){return this.value&&!t.modified()?this.value:t.values.reduce(function(t,e){return t.concat(e)},[])}function wa(t){Br.call(this,null,t)}function Ma(t){Ri.call(this,t)}pa.transform=function(t,e){var n,r=this,i=t.modified();return r.value&&(i||e.modified(r._inputs))?(n=r.value=i?r.init(t):{},e.visit(e.SOURCE,function(t){r.add(t)})):(n=r.value=r.value||this.init(t),e.visit(e.REM,function(t){r.rem(t)}),e.visit(e.ADD,function(t){r.add(t)})),r.changes(),e.visit(e.SOURCE,function(t){B(t,n[r.cellkey(t)].tuple)}),e.reflow(i).modifies(this._outputs)},pa.changes=function(){var t,e,n=this._adds,r=this._mods;for(t=0,e=this._alen;t1&&!u&&o('Multi-field lookup requires explicit "as" parameter.'),u&&u.length!==p*r&&o('The "as" parameter has too few output field names.'),u=u||c.map(i),n=function(t){for(var e,n,i=0,a=0;ie||null==e)&&null!=t?1:(e=e instanceof Date?+e:e,(t=t instanceof Date?+t:t)!==t&&e==e?-1:e!=e&&t==t?1:0)}),e?i.slice(0,e):i}(r,t.limit||0,e);return{key:t.key,groupby:t.groupby,ops:s.map(function(){return o}),fields:s.map(function(t){return function(t,e,r,i){return n(function(n){return e(n)===t?r(n):NaN},i,t+"")}(t,r,i,u)}),as:s.map(function(t){return t+""}),modified:t.modified.bind(t)}}(t,e),e)},G(Ea,ta).transform=function(t,e){var n=this,r=t.subflow,i=t.field;return(t.modified("field")||i&&e.modified(a(i)))&&o("PreFacet does not support field modification."),this._targets.active=0,e.visit(e.MOD,function(t){var a=n.subflow(dt(t),r,e,t);i?i(t).forEach(function(t){a.mod(t)}):a.mod(t)}),e.visit(e.ADD,function(t){var a=n.subflow(dt(t),r,e,t);i?i(t).forEach(function(t){a.add(vt(t))}):a.add(t)}),e.visit(e.REM,function(t){var a=n.subflow(dt(t),r,e,t);i?i(t).forEach(function(t){a.rem(t)}):a.rem(t)}),e},Sa.Definition={type:"Project",metadata:{generates:!0,changes:!0,modifies:!0},params:[{name:"fields",type:"field",array:!0},{name:"as",type:"string",null:!0,array:!0}]},G(Sa,Br).transform=function(t,e){var n,r,i=t.fields,a=aa(t.fields,t.as||[]),o=i?function(t,e){return function(t,e,n,r){for(var i=0,a=n.length;i=s&&(n=o[i],f[dt(n)]&&r.rem.push(n),o[i]=t),++u}if(n.rem.length&&(n.visit(n.REM,function(t){var e=dt(t);f[e]&&(f[e]=-1,r.rem.push(t)),--u}),o=o.filter(function(t){return-1!==f[dt(t)]})),(n.rem.length||i)&&o.lengtha){for(var l=0,h=o.length-a;ln.cleanThreshold&&n.runAfter(i.clean),e.fork()},G(Ra,Br).transform=function(t,e){(!this.value||t.modified("field")||t.modified("sort")||e.changed()||t.sort&&e.modified(t.sort.fields))&&(this.value=(t.sort?e.source.slice().sort(t.sort):e.source).map(t.field))};var Ta={row_number:function(){return{next:function(t){return t.index+1}}},rank:function(){var t;return{init:function(){t=1},next:function(e){var n=e.index,r=e.data;return n&&e.compare(r[n-1],r[n])?t=n+1:t}}},dense_rank:function(){var t;return{init:function(){t=1},next:function(e){var n=e.index,r=e.data;return n&&e.compare(r[n-1],r[n])?++t:t}}},percent_rank:function(){var t=Ta.rank(),e=t.next;return{init:t.init,next:function(t){return(e(t)-1)/(t.data.length-1)}}},cume_dist:function(){var t;return{init:function(){t=0},next:function(e){var n=e.index,r=e.data,i=e.compare;if(t0||o("ntile num must be greater than zero.");var n=Ta.cume_dist(),r=n.next;return{init:n.init,next:function(t){return Math.ceil(e*r(t))}}},lag:function(t,e){return e=+e||1,{next:function(n){var r=n.index-e;return r>=0?t(n.data[r]):null}}},lead:function(t,e){return e=+e||1,{next:function(n){var r=n.index+e,i=n.data;return r0||o("nth_value nth must be greater than zero."),{next:function(n){var r=n.i0+(e-1);return r0&&!i(a[n],a[n-1])&&(t.i0=e.left(a,a[n])),rthis.x2&&(this.x2=t),e>this.y2&&(this.y2=e),this},Ha.expand=function(t){return this.x1-=t,this.y1-=t,this.x2+=t,this.y2+=t,this},Ha.round=function(){return this.x1=Math.floor(this.x1),this.y1=Math.floor(this.y1),this.x2=Math.ceil(this.x2),this.y2=Math.ceil(this.y2),this},Ha.translate=function(t,e){return this.x1+=t,this.x2+=t,this.y1+=e,this.y2+=e,this},Ha.rotate=function(t,e,n){var r=Math.cos(t),i=Math.sin(t),a=e-e*r+n*i,o=n-e*i-n*r,u=this.x1,s=this.x2,f=this.y1,c=this.y2;return this.clear().add(r*u-i*f+a,i*u+r*f+o).add(r*u-i*c+a,i*u+r*c+o).add(r*s-i*f+a,i*s+r*f+o).add(r*s-i*c+a,i*s+r*c+o)},Ha.union=function(t){return t.x1this.x2&&(this.x2=t.x2),t.y2>this.y2&&(this.y2=t.y2),this},Ha.intersect=function(t){return t.x1>this.x1&&(this.x1=t.x1),t.y1>this.y1&&(this.y1=t.y1),t.x2=t.x2&&this.y1<=t.y1&&this.y2>=t.y2},Ha.alignsWith=function(t){return t&&(this.x1==t.x1||this.x2==t.x2||this.y1==t.y1||this.y2==t.y2)},Ha.intersects=function(t){return t&&!(this.x2t.x2||this.y2t.y2)},Ha.contains=function(t,e){return!(tthis.x2||ethis.y2)},Ha.width=function(){return this.x2-this.x1},Ha.height=function(){return this.y2-this.y1};var Ya,Ga=0,Va=function(t,e){var n,r=[];return n={id:"gradient_"+Ga++,x1:t?t[0]:0,y1:t?t[1]:0,x2:e?e[0]:1,y2:e?e[1]:0,stops:r,stop:function(t,e){return r.push({offset:t,color:e}),n}}};function Xa(t){this.mark=t,this.bounds=this.bounds||new Wa}function Ja(t){Xa.call(this,t),this.items=this.items||[]}G(Ja,Xa);try{if(!(Ya=t("canvas")))throw 1}catch(e){try{Ya=t("canvas-prebuilt")}catch(t){Ya=null}}function Za(t,e){return function(t,e){if("undefined"!=typeof document&&document.createElement){var n=document.createElement("canvas");if(n&&n.getContext)return n.width=t,n.height=e,n}return null}(t,e)||function(t,e){if(Ya)try{return new Ya(t,e)}catch(t){}return null}(t,e)||null}function Qa(){return("undefined"!=typeof Image?Image:null)||Ya&&Ya.Image||null||null}function Ka(t){this._pending=0,this._loader=t||ie()}var to=Ka.prototype;function eo(t){t._pending+=1}function no(t){t._pending-=1}to.pending=function(){return this._pending},to.sanitizeURL=function(t){var e=this;return eo(e),e._loader.sanitize(t,{context:"href"}).then(function(t){return no(e),t}).catch(function(){return no(e),null})},to.loadImage=function(t){var e=this,n=Qa();return eo(e),e._loader.sanitize(t,{context:"image"}).then(function(t){var r=t.href;if(!r||!n)throw{url:r};var i=new n;return i.onload=function(){no(e),i.loaded=!0},i.onerror=function(){no(e),i.loaded=!1},i.src=r,i}).catch(function(t){return no(e),{loaded:!1,width:0,height:0,src:t&&t.url||""}})},to.ready=function(){var t=this;return new Promise(function(e){!function n(r){t.pending()?setTimeout(function(){n(!0)},10):e(r)}(!1)})};var ro=Math.PI,io=2*ro,ao=io-1e-6;function oo(){this._x0=this._y0=this._x1=this._y1=null,this._=""}function uo(){return new oo}oo.prototype=uo.prototype={constructor:oo,moveTo:function(t,e){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)},closePath:function(){null!==this._x1&&(this._x1=this._x0,this._y1=this._y0,this._+="Z")},lineTo:function(t,e){this._+="L"+(this._x1=+t)+","+(this._y1=+e)},quadraticCurveTo:function(t,e,n,r){this._+="Q"+ +t+","+ +e+","+(this._x1=+n)+","+(this._y1=+r)},bezierCurveTo:function(t,e,n,r,i,a){this._+="C"+ +t+","+ +e+","+ +n+","+ +r+","+(this._x1=+i)+","+(this._y1=+a)},arcTo:function(t,e,n,r,i){t=+t,e=+e,n=+n,r=+r,i=+i;var a=this._x1,o=this._y1,u=n-t,s=r-e,f=a-t,c=o-e,l=f*f+c*c;if(i<0)throw new Error("negative radius: "+i);if(null===this._x1)this._+="M"+(this._x1=t)+","+(this._y1=e);else if(l>1e-6)if(Math.abs(c*u-s*f)>1e-6&&i){var h=n-a,d=r-o,p=u*u+s*s,v=h*h+d*d,g=Math.sqrt(p),m=Math.sqrt(l),y=i*Math.tan((ro-Math.acos((p+l-v)/(2*g*m)))/2),b=y/m,_=y/g;Math.abs(b-1)>1e-6&&(this._+="L"+(t+b*f)+","+(e+b*c)),this._+="A"+i+","+i+",0,0,"+ +(c*h>f*d)+","+(this._x1=t+_*u)+","+(this._y1=e+_*s)}else this._+="L"+(this._x1=t)+","+(this._y1=e);else;},arc:function(t,e,n,r,i,a){t=+t,e=+e;var o=(n=+n)*Math.cos(r),u=n*Math.sin(r),s=t+o,f=e+u,c=1^a,l=a?r-i:i-r;if(n<0)throw new Error("negative radius: "+n);null===this._x1?this._+="M"+s+","+f:(Math.abs(this._x1-s)>1e-6||Math.abs(this._y1-f)>1e-6)&&(this._+="L"+s+","+f),n&&(l<0&&(l=l%io+io),l>ao?this._+="A"+n+","+n+",0,1,"+c+","+(t-o)+","+(e-u)+"A"+n+","+n+",0,1,"+c+","+(this._x1=s)+","+(this._y1=f):l>1e-6&&(this._+="A"+n+","+n+",0,"+ +(l>=ro)+","+c+","+(this._x1=t+n*Math.cos(i))+","+(this._y1=e+n*Math.sin(i))))},rect:function(t,e,n,r){this._+="M"+(this._x0=this._x1=+t)+","+(this._y0=this._y1=+e)+"h"+ +n+"v"+ +r+"h"+-n+"Z"},toString:function(){return this._}};var so=function(t){return function(){return t}},fo=Math.abs,co=Math.atan2,lo=Math.cos,ho=Math.max,po=Math.min,vo=Math.sin,go=Math.sqrt,mo=1e-12,yo=Math.PI,bo=yo/2,_o=2*yo;function xo(t){return t>=1?bo:t<=-1?-bo:Math.asin(t)}function wo(t){return t.innerRadius}function Mo(t){return t.outerRadius}function ko(t){return t.startAngle}function Eo(t){return t.endAngle}function So(t){return t&&t.padAngle}function Ao(t,e,n,r,i,a,o){var u=t-n,s=e-r,f=(o?a:-a)/go(u*u+s*s),c=f*s,l=-f*u,h=t+c,d=e+l,p=n+c,v=r+l,g=(h+p)/2,m=(d+v)/2,y=p-h,b=v-d,_=y*y+b*b,x=i-a,w=h*v-p*d,M=(b<0?-1:1)*go(ho(0,x*x*_-w*w)),k=(w*b-y*M)/_,E=(-w*y-b*M)/_,S=(w*b+y*M)/_,A=(-w*y+b*M)/_,C=k-g,N=E-m,z=S-g,O=A-m;return C*C+N*N>z*z+O*O&&(k=S,E=A),{cx:k,cy:E,x01:-c,y01:-l,x11:k*(i/x-1),y11:E*(i/x-1)}}function Co(t){this._context=t}Co.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:this._context.lineTo(t,e)}}};var No=function(t){return new Co(t)};function zo(t){return t[0]}function Oo(t){return t[1]}var Do=function(){var t=zo,e=Oo,n=so(!0),r=null,i=No,a=null;function o(o){var u,s,f,c=o.length,l=!1;for(null==r&&(a=i(f=uo())),u=0;u<=c;++u)!(u=c;--l)u.point(g[l],m[l]);u.lineEnd(),u.areaEnd()}v&&(g[f]=+t(h,f,s),m[f]=+n(h,f,s),u.point(e?+e(h,f,s):g[f],r?+r(h,f,s):m[f]))}if(d)return u=null,d+""||null}function f(){return Do().defined(i).curve(o).context(a)}return s.x=function(n){return arguments.length?(t="function"==typeof n?n:so(+n),e=null,s):t},s.x0=function(e){return arguments.length?(t="function"==typeof e?e:so(+e),s):t},s.x1=function(t){return arguments.length?(e=null==t?null:"function"==typeof t?t:so(+t),s):e},s.y=function(t){return arguments.length?(n="function"==typeof t?t:so(+t),r=null,s):n},s.y0=function(t){return arguments.length?(n="function"==typeof t?t:so(+t),s):n},s.y1=function(t){return arguments.length?(r=null==t?null:"function"==typeof t?t:so(+t),s):r},s.lineX0=s.lineY0=function(){return f().x(t).y(n)},s.lineY1=function(){return f().x(t).y(r)},s.lineX1=function(){return f().x(e).y(n)},s.defined=function(t){return arguments.length?(i="function"==typeof t?t:so(!!t),s):i},s.curve=function(t){return arguments.length?(o=t,null!=a&&(u=o(a)),s):o},s.context=function(t){return arguments.length?(null==t?a=u=null:u=o(a=t),s):a},s},To={draw:function(t,e){var n=Math.sqrt(e/yo);t.moveTo(n,0),t.arc(0,0,n,0,_o)}},Po=function(){};function Lo(t,e,n){t._context.bezierCurveTo((2*t._x0+t._x1)/3,(2*t._y0+t._y1)/3,(t._x0+2*t._x1)/3,(t._y0+2*t._y1)/3,(t._x0+4*t._x1+e)/6,(t._y0+4*t._y1+n)/6)}function qo(t){this._context=t}qo.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){switch(this._point){case 3:Lo(this,this._x1,this._y1);case 2:this._context.lineTo(this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3,this._context.lineTo((5*this._x0+this._x1)/6,(5*this._y0+this._y1)/6);default:Lo(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function Uo(t){this._context=t}Uo.prototype={areaStart:Po,areaEnd:Po,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._y0=this._y1=this._y2=this._y3=this._y4=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x2,this._y2),this._context.closePath();break;case 2:this._context.moveTo((this._x2+2*this._x3)/3,(this._y2+2*this._y3)/3),this._context.lineTo((this._x3+2*this._x2)/3,(this._y3+2*this._y2)/3),this._context.closePath();break;case 3:this.point(this._x2,this._y2),this.point(this._x3,this._y3),this.point(this._x4,this._y4)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x2=t,this._y2=e;break;case 1:this._point=2,this._x3=t,this._y3=e;break;case 2:this._point=3,this._x4=t,this._y4=e,this._context.moveTo((this._x0+4*this._x1+t)/6,(this._y0+4*this._y1+e)/6);break;default:Lo(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function jo(t){this._context=t}jo.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._y0=this._y1=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3;var n=(this._x0+4*this._x1+t)/6,r=(this._y0+4*this._y1+e)/6;this._line?this._context.lineTo(n,r):this._context.moveTo(n,r);break;case 3:this._point=4;default:Lo(this,t,e)}this._x0=this._x1,this._x1=t,this._y0=this._y1,this._y1=e}};function Fo(t,e){this._basis=new qo(t),this._beta=e}Fo.prototype={lineStart:function(){this._x=[],this._y=[],this._basis.lineStart()},lineEnd:function(){var t=this._x,e=this._y,n=t.length-1;if(n>0)for(var r,i=t[0],a=e[0],o=t[n]-i,u=e[n]-a,s=-1;++s<=n;)r=s/n,this._basis.point(this._beta*t[s]+(1-this._beta)*(i+r*o),this._beta*e[s]+(1-this._beta)*(a+r*u));this._x=this._y=null,this._basis.lineEnd()},point:function(t,e){this._x.push(+t),this._y.push(+e)}};var Io=function t(e){function n(t){return 1===e?new qo(t):new Fo(t,e)}return n.beta=function(e){return t(+e)},n}(.85);function $o(t,e,n){t._context.bezierCurveTo(t._x1+t._k*(t._x2-t._x0),t._y1+t._k*(t._y2-t._y0),t._x2+t._k*(t._x1-e),t._y2+t._k*(t._y1-n),t._x2,t._y2)}function Bo(t,e){this._context=t,this._k=(1-e)/6}Bo.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:$o(this,this._x1,this._y1)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2,this._x1=t,this._y1=e;break;case 2:this._point=3;default:$o(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Wo=function t(e){function n(t){return new Bo(t,e)}return n.tension=function(e){return t(+e)},n}(0);function Ho(t,e){this._context=t,this._k=(1-e)/6}Ho.prototype={areaStart:Po,areaEnd:Po,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:$o(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Yo=function t(e){function n(t){return new Ho(t,e)}return n.tension=function(e){return t(+e)},n}(0);function Go(t,e){this._context=t,this._k=(1-e)/6}Go.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:$o(this,t,e)}this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Vo=function t(e){function n(t){return new Go(t,e)}return n.tension=function(e){return t(+e)},n}(0);function Xo(t,e,n){var r=t._x1,i=t._y1,a=t._x2,o=t._y2;if(t._l01_a>mo){var u=2*t._l01_2a+3*t._l01_a*t._l12_a+t._l12_2a,s=3*t._l01_a*(t._l01_a+t._l12_a);r=(r*u-t._x0*t._l12_2a+t._x2*t._l01_2a)/s,i=(i*u-t._y0*t._l12_2a+t._y2*t._l01_2a)/s}if(t._l23_a>mo){var f=2*t._l23_2a+3*t._l23_a*t._l12_a+t._l12_2a,c=3*t._l23_a*(t._l23_a+t._l12_a);a=(a*f+t._x1*t._l23_2a-e*t._l12_2a)/c,o=(o*f+t._y1*t._l23_2a-n*t._l12_2a)/c}t._context.bezierCurveTo(r,i,a,o,t._x2,t._y2)}function Jo(t,e){this._context=t,this._alpha=e}Jo.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 2:this._context.lineTo(this._x2,this._y2);break;case 3:this.point(this._x2,this._y2)}(this._line||0!==this._line&&1===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;break;case 2:this._point=3;default:Xo(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Zo=function t(e){function n(t){return e?new Jo(t,e):new Bo(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function Qo(t,e){this._context=t,this._alpha=e}Qo.prototype={areaStart:Po,areaEnd:Po,lineStart:function(){this._x0=this._x1=this._x2=this._x3=this._x4=this._x5=this._y0=this._y1=this._y2=this._y3=this._y4=this._y5=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){switch(this._point){case 1:this._context.moveTo(this._x3,this._y3),this._context.closePath();break;case 2:this._context.lineTo(this._x3,this._y3),this._context.closePath();break;case 3:this.point(this._x3,this._y3),this.point(this._x4,this._y4),this.point(this._x5,this._y5)}},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1,this._x3=t,this._y3=e;break;case 1:this._point=2,this._context.moveTo(this._x4=t,this._y4=e);break;case 2:this._point=3,this._x5=t,this._y5=e;break;default:Xo(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var Ko=function t(e){function n(t){return e?new Qo(t,e):new Ho(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function tu(t,e){this._context=t,this._alpha=e}tu.prototype={areaStart:function(){this._line=0},areaEnd:function(){this._line=NaN},lineStart:function(){this._x0=this._x1=this._x2=this._y0=this._y1=this._y2=NaN,this._l01_a=this._l12_a=this._l23_a=this._l01_2a=this._l12_2a=this._l23_2a=this._point=0},lineEnd:function(){(this._line||0!==this._line&&3===this._point)&&this._context.closePath(),this._line=1-this._line},point:function(t,e){if(t=+t,e=+e,this._point){var n=this._x2-t,r=this._y2-e;this._l23_a=Math.sqrt(this._l23_2a=Math.pow(n*n+r*r,this._alpha))}switch(this._point){case 0:this._point=1;break;case 1:this._point=2;break;case 2:this._point=3,this._line?this._context.lineTo(this._x2,this._y2):this._context.moveTo(this._x2,this._y2);break;case 3:this._point=4;default:Xo(this,t,e)}this._l01_a=this._l12_a,this._l12_a=this._l23_a,this._l01_2a=this._l12_2a,this._l12_2a=this._l23_2a,this._x0=this._x1,this._x1=this._x2,this._x2=t,this._y0=this._y1,this._y1=this._y2,this._y2=e}};var eu=function t(e){function n(t){return e?new tu(t,e):new Go(t,0)}return n.alpha=function(e){return t(+e)},n}(.5);function nu(t){this._context=t}nu.prototype={areaStart:Po,areaEnd:Po,lineStart:function(){this._point=0},lineEnd:function(){this._point&&this._context.closePath()},point:function(t,e){t=+t,e=+e,this._point?this._context.lineTo(t,e):(this._point=1,this._context.moveTo(t,e))}};function ru(t){return t<0?-1:1}function iu(t,e,n){var r=t._x1-t._x0,i=e-t._x1,a=(t._y1-t._y0)/(r||i<0&&-0),o=(n-t._y1)/(i||r<0&&-0),u=(a*i+o*r)/(r+i);return(ru(a)+ru(o))*Math.min(Math.abs(a),Math.abs(o),.5*Math.abs(u))||0}function au(t,e){var n=t._x1-t._x0;return n?(3*(t._y1-t._y0)/n-e)/2:e}function ou(t,e,n){var r=t._x0,i=t._y0,a=t._x1,o=t._y1,u=(a-r)/3;t._context.bezierCurveTo(r+u,i+u*e,a-u,o-u*n,a,o)}function uu(t){this._context=t}function su(t){this._context=new fu(t)}function fu(t){this._context=t}function cu(t){this._context=t}function lu(t){var e,n,r=t.length-1,i=new Array(r),a=new Array(r),o=new Array(r);for(i[0]=0,a[0]=2,o[0]=t[0]+2*t[1],e=1;e=0;--e)i[e]=(o[e]-i[e+1])/a[e];for(a[r-1]=(t[r]+i[r-1])/2,e=0;e=0&&(this._t=1-this._t,this._line=1-this._line)},point:function(t,e){switch(t=+t,e=+e,this._point){case 0:this._point=1,this._line?this._context.lineTo(t,e):this._context.moveTo(t,e);break;case 1:this._point=2;default:if(this._t<=0)this._context.lineTo(this._x,e),this._context.lineTo(t,e);else{var n=this._x*(1-this._t)+t*this._t;this._context.lineTo(n,this._y),this._context.lineTo(n,e)}}this._x=t,this._y=e}};var du={basis:{curve:function(t){return new qo(t)}},"basis-closed":{curve:function(t){return new Uo(t)}},"basis-open":{curve:function(t){return new jo(t)}},bundle:{curve:Io,tension:"beta",value:.85},cardinal:{curve:Wo,tension:"tension",value:0},"cardinal-open":{curve:Vo,tension:"tension",value:0},"cardinal-closed":{curve:Yo,tension:"tension",value:0},"catmull-rom":{curve:Zo,tension:"alpha",value:.5},"catmull-rom-closed":{curve:Ko,tension:"alpha",value:.5},"catmull-rom-open":{curve:eu,tension:"alpha",value:.5},linear:{curve:No},"linear-closed":{curve:function(t){return new nu(t)}},monotone:{horizontal:function(t){return new su(t)},vertical:function(t){return new uu(t)}},natural:{curve:function(t){return new cu(t)}},step:{curve:function(t){return new hu(t,.5)}},"step-after":{curve:function(t){return new hu(t,1)}},"step-before":{curve:function(t){return new hu(t,0)}}};function pu(t,e,n){var r=du.hasOwnProperty(t)&&du[t],i=null;return r&&(i=r.curve||r[e||"vertical"],r.tension&&null!=n&&(i=i[r.tension](n))),i}var vu={m:2,l:2,h:1,v:1,c:6,s:4,q:4,t:2,a:7},gu=[/([MLHVCSQTAZmlhvcsqtaz])/g,/###/,/(\d)([-+])/g,/\s|,|###/],mu=function(t){var e,n,r,i,a,o,u,s,f,c,l,h=[];for(s=0,c=(e=t.slice().replace(gu[0],"###$1").split(gu[1]).slice(1)).length;su)for(f=1,l=i.length;f1&&(n*=v=Math.sqrt(v),r*=v);var g=h/n,m=l/n,y=-l/r,b=h/r,_=g*u+m*s,x=y*u+b*s,w=g*t+m*e,M=y*t+b*e,k=1/((w-_)*(w-_)+(M-x)*(M-x))-.25;k<0&&(k=0);var E=Math.sqrt(k);a==i&&(E=-E);var S=.5*(_+w)-E*(M-x),A=.5*(x+M)+E*(w-_),C=Math.atan2(x-A,_-S),N=Math.atan2(M-A,w-S)-C;N<0&&1===a?N+=2*Math.PI:N>0&&0===a&&(N-=2*Math.PI);for(var z=Math.ceil(Math.abs(N/(.5*Math.PI+.001))),O=[],D=0;Dd;if(u||(u=s=uo()),hmo)if(v>_o-mo)u.moveTo(h*lo(d),h*vo(d)),u.arc(0,0,h,d,p,!g),l>mo&&(u.moveTo(l*lo(p),l*vo(p)),u.arc(0,0,l,p,d,g));else{var m,y,b=d,_=p,x=d,w=p,M=v,k=v,E=o.apply(this,arguments)/2,S=E>mo&&(r?+r.apply(this,arguments):go(l*l+h*h)),A=po(fo(h-l)/2,+n.apply(this,arguments)),C=A,N=A;if(S>mo){var z=xo(S/l*vo(E)),O=xo(S/h*vo(E));(M-=2*z)>mo?(x+=z*=g?1:-1,w-=z):(M=0,x=w=(d+p)/2),(k-=2*O)>mo?(b+=O*=g?1:-1,_-=O):(k=0,b=_=(d+p)/2)}var D=h*lo(b),R=h*vo(b),T=l*lo(w),P=l*vo(w);if(A>mo){var L=h*lo(_),q=h*vo(_),U=l*lo(x),j=l*vo(x);if(vmo?function(t,e,n,r,i,a,o,u){var s=n-t,f=r-e,c=o-i,l=u-a,h=(c*(e-a)-l*(t-i))/(l*s-c*f);return[t+h*s,e+h*f]}(D,R,U,j,L,q,T,P):[T,P],I=D-F[0],$=R-F[1],B=L-F[0],W=q-F[1],H=1/vo(((c=(I*B+$*W)/(go(I*I+$*$)*go(B*B+W*W)))>1?0:c<-1?yo:Math.acos(c))/2),Y=go(F[0]*F[0]+F[1]*F[1]);C=po(A,(l-Y)/(H-1)),N=po(A,(h-Y)/(H+1))}}k>mo?N>mo?(m=Ao(U,j,D,R,h,N,g),y=Ao(L,q,T,P,h,N,g),u.moveTo(m.cx+m.x01,m.cy+m.y01),Nmo&&M>mo?C>mo?(m=Ao(T,P,L,q,l,-C,g),y=Ao(D,R,U,j,l,-C,g),u.lineTo(m.cx+m.x01,m.cy+m.y01),Ces)return is(t-n,e-n),void is(t+n,e+n);var o,u,s,f,c=1/0,l=-1/0,h=1/0,d=-1/0;function p(t){s=n*Math.cos(t),f=n*Math.sin(t),sl&&(l=s),fd&&(d=f)}if(p(r),p(i),i!==r)if((r%=Ku)<0&&(r+=Ku),(i%=Ku)<0&&(i+=Ku),ii;++u,o-=ts)p(o);else for(o=r-r%ts+ts,u=0;u<4&&o0&&(t.globalAlpha=n,t.fillStyle=as(t,e,e.fill),!0)},us=[],ss=function(t,e,n){var r=null!=(r=e.strokeWidth)?r:1;return!(r<=0)&&((n*=null==e.strokeOpacity?1:e.strokeOpacity)>0&&(t.globalAlpha=n,t.strokeStyle=as(t,e,e.stroke),t.lineWidth=r,t.lineCap=e.strokeCap||"butt",t.lineJoin=e.strokeJoin||"miter",t.miterLimit=e.strokeMiterLimit||10,t.setLineDash&&(t.setLineDash(e.strokeDash||us),t.lineDashOffset=e.strokeDashOffset||0),!0))};function fs(t,e){return t.zindex-e.zindex||t.index-e.index}function cs(t){if(!t.zdirty)return t.zitems;var e,n,r,i=t.items,a=[];for(n=0,r=i.length;n=0;)if(n=e(i[r]))return n;if(i===a)for(r=(i=t.items).length;--r>=0;)if(!i[r].zindex&&(n=e(i[r])))return n;return null}function ds(t){return function(e,n,r){ls(n,function(n){r&&!r.intersects(n.bounds)||ps(t,e,n,n)})}}function ps(t,e,n,r){var i=null==n.opacity?1:n.opacity;0!==i&&(t(e,r)||(n.fill&&os(e,n,i)&&e.fill(),n.stroke&&ss(e,n,i)&&e.stroke()))}var vs=function(){return!0};function gs(t){return t||(t=vs),function(e,n,r,i,a,o){return e.pixelRatio>1&&(r*=e.pixelRatio,i*=e.pixelRatio),hs(n,function(n){var u=n.bounds;if((!u||u.contains(a,o))&&u)return t(e,n,r,i,a,o)?n:void 0})}}function ms(t,e){return function(n,r,i,a){var o,u,s=Array.isArray(r)?r[0]:r,f=null==e?s.fill:e,c=s.stroke&&n.isPointInStroke;return c&&(o=s.strokeWidth,u=s.strokeCap,n.lineWidth=null!=o?o:1,n.lineCap=null!=u?u:"butt"),!t(n,r)&&(f&&n.isPointInPath(i,a)||c&&n.isPointInStroke(i,a))}}function ys(t){return gs(ms(t))}var bs=function(t,e){return"translate("+t+","+e+")"},_s=function(t){return bs(t.x||0,t.y||0)},xs=function(t,e){function n(t,n){var r=n.x||0,i=n.y||0;t.translate(r,i),t.beginPath(),e(t,n),t.translate(-r,-i)}return{type:t,tag:"path",nested:!1,attr:function(t,n){t("transform",_s(n)),t("d",e(null,n))},bound:function(t,n){return e(ns(t),n),Qu(t,n).translate(n.x||0,n.y||0)},draw:ds(n),pick:ys(n)}},ws=xs("arc",function(t,e){return Bu.context(t)(e)}),Ms=function(t,e){function n(t,n){t.beginPath(),e(t,n)}var r,i=ms(n);return{type:t,tag:"path",nested:!0,attr:function(t,n){var r=n.mark.items;r.length&&t("d",e(null,r))},bound:function(t,n){var r=n.items;return 0===r.length?t:(e(ns(t),r),Qu(t,r[0]))},draw:(r=n,function(t,e,n){!e.items.length||n&&!n.intersects(e.bounds)||ps(r,t,e.items[0],e.items)}),pick:function(t,e,n,r,a,o){var u=e.items,s=e.bounds;return!u||!u.length||s&&!s.contains(a,o)?null:(t.pixelRatio>1&&(n*=t.pixelRatio,r*=t.pixelRatio),i(t,u,n,r)?u[0]:null)}}},ks=Ms("area",function(t,e){var n=e[0],r=n.interpolate||"linear";return("horizontal"===n.orient?Hu:Wu).curve(pu(r,n.orient,n.tension)).context(t)(e)}),Es=1;var Ss=function(t,e,n){var r=e.clip,i=t._defs,a=e.clip_id||(e.clip_id="clip"+Es++),o=i.clipping[a]||(i.clipping[a]={id:a});return j(r)?o.path=r(null):(o.width=n.width||0,o.height=n.height||0),"url(#"+a+")"},As=.5;var Cs={type:"group",tag:"g",nested:!1,attr:function(t,e){t("transform",_s(e))},bound:function(t,e){if(!e.clip&&e.items)for(var n=e.items,r=0,i=n.length;r0&&(t.beginPath(),i=e.stroke?As:0,Ju(t,e,i,i),e.fill&&os(t,e,a)&&t.fill(),e.stroke&&ss(t,e,a)&&t.stroke()),e.clip&&(t.beginPath(),t.rect(0,0,s,f),t.clip()),n&&n.translate(-o,-u),ls(e,function(e){r.draw(t,e,n)}),n&&n.translate(o,u),t.restore()})},pick:function(t,e,n,r,i,a){if(e.bounds&&!e.bounds.contains(i,a)||!e.items)return null;var o=this;return hs(e,function(u){var s,f,c,l;if(!(l=u.bounds)||l.contains(i,a))return f=u.x||0,c=u.y||0,t.save(),t.translate(f,c),f=i-f,c=a-c,s=hs(u,function(t){return function(t,e,n){return(!1!==t.interactive||"group"===t.marktype)&&t.bounds&&t.bounds.contains(e,n)}(t,f,c)?o.pick(t,n,r,f,c):null}),t.restore(),s||((s=!1!==e.interactive&&(u.fill||u.stroke)&&f>=0&&f<=u.width&&c>=0&&c<=u.height)?u:null)})},background:function(t,e){var n=e.stroke?As:0;t("class","background"),t("d",Ju(null,e,n,n))},foreground:function(t,e,n){t("clip-path",e.clip?Ss(n,e,e):null)}};function Ns(t,e){var n=t.image;return n&&n.url===t.url||(n={loaded:!1,width:0,height:0},e.loadImage(t.url).then(function(e){t.image=e,t.image.url=t.url})),n}function zs(t,e){return"center"===t?e/2:"right"===t?e:0}function Os(t,e){return"middle"===t?e/2:"bottom"===t?e:0}var Ds={type:"image",tag:"image",nested:!1,attr:function(t,e,n){var r=Ns(e,n),i=e.x||0,a=e.y||0,o=(null!=e.width?e.width:r.width)||0,u=(null!=e.height?e.height:r.height)||0,s=!1===e.aspect?"none":"xMidYMid";i-=zs(e.align,o),a-=Os(e.baseline,u),t("href",r.src||"","http://www.w3.org/1999/xlink","xlink:href"),t("transform",bs(i,a)),t("width",o),t("height",u),t("preserveAspectRatio",s)},bound:function(t,e){var n=e.image,r=e.x||0,i=e.y||0,a=(null!=e.width?e.width:n&&n.width)||0,o=(null!=e.height?e.height:n&&n.height)||0;return r-=zs(e.align,a),i-=Os(e.baseline,o),t.set(r,i,r+a,i+o)},draw:function(t,e,n){var r=this;ls(e,function(e){if(!n||n.intersects(e.bounds)){var i,a,o,u,s=Ns(e,r),f=e.x||0,c=e.y||0,l=(null!=e.width?e.width:s.width)||0,h=(null!=e.height?e.height:s.height)||0;f-=zs(e.align,l),c-=Os(e.baseline,h),!1!==e.aspect&&(a=s.width/s.height,o=e.width/e.height,a==a&&o==o&&a!==o&&(o0?function(t){var e,n=+t.limit,r=t.text+"";js?(js.font=Qs(t),e=Vs):(Fs=Xs(t),e=Ys);if(e(r)>>1,e(r.slice(i))>n?u=i+1:s=i;return a+r.slice(u)}for(;u>>1),e(r.slice(0,i))e;)t.removeChild(n[--r]);return t}function yf(t){return"mark-"+t.marktype+(t.role?" role-"+t.role:"")+(t.name?" "+t.name:"")}function bf(t){this._active=null,this._handlers={},this._loader=t||ie()}hf.toJSON=function(t){return ff(this.root,t||0)},hf.mark=function(t,e,n){var r=df(t,e=e||this.root.items[0]);return e.items[n]=r,r.zindex&&(r.group.zdirty=!0),r};var _f=bf.prototype;function xf(t){this._el=null,this._bgcolor=null,this._loader=new Ka(t)}_f.initialize=function(t,e,n){return this._el=t,this._obj=n||null,this.origin(e)},_f.element=function(){return this._el},_f.origin=function(t){return this._origin=t||[0,0],this},_f.scene=function(t){return arguments.length?(this._scene=t,this):this._scene},_f.on=function(){},_f.off=function(){},_f._handlerIndex=function(t,e,n){for(var r=t?t.length:0;--r>=0;)if(t[r].type===e&&!n||t[r].handler===n)return r;return-1},_f.handlers=function(){var t,e=this._handlers,n=[];for(t in e)n.push.apply(n,e[t]);return n},_f.eventName=function(t){var e=t.indexOf(".");return e<0?t:t.slice(0,e)},_f.handleHref=function(t,e,n){this._loader.sanitize(n,{context:"href"}).then(function(e){var n=new MouseEvent(t.type,t),r=pf(null,"a");for(var i in e)r.setAttribute(i,e[i]);r.dispatchEvent(n)}).catch(function(){})},_f.handleTooltip=function(t,e,n){this._el.setAttribute("title",n||"")};var wf=xf.prototype;wf.initialize=function(t,e,n,r,i){return this._el=t,this.resize(e,n,r,i)},wf.element=function(){return this._el},wf.scene=function(){return this._el&&this._el.firstChild},wf.background=function(t){return 0===arguments.length?this._bgcolor:(this._bgcolor=t,this)},wf.resize=function(t,e,n,r){return this._width=t,this._height=e,this._origin=n||[0,0],this._scale=r||1,this},wf.dirty=function(){},wf.render=function(t){var e=this;return e._call=function(){e._render(t)},e._call(),e._call=null,e},wf._render=function(){},wf.renderAsync=function(t){var e=this.render(t);return this._ready?this._ready.then(function(){return e}):Promise.resolve(e)},wf._load=function(t,e){var n=this,r=n._loader[t](e);if(!n._ready){var i=n._call;n._ready=n._loader.ready().then(function(t){t&&i(),n._ready=null})}return r},wf.sanitizeURL=function(t){return this._load("sanitizeURL",t)},wf.loadImage=function(t){return this._load("loadImage",t)};var Mf=function(t,e){var n=e.getBoundingClientRect();return[t.clientX-n.left-(e.clientLeft||0),t.clientY-n.top-(e.clientTop||0)]};function kf(t){bf.call(this,t),this._down=null,this._touch=null,this._first=!0}var Ef=G(kf,bf);function Sf(t,e,n){return function(r){var i=this._active,a=this.pickEvent(r);a===i?this.fire(t,r):(i&&i.exit||this.fire(n,r),this._active=a,this.fire(e,r),this.fire(t,r))}}function Af(t){return function(e){this.fire(t,e),this._active=null}}Ef.initialize=function(t,e,n){var r=this._canvas=t&&vf(t,"canvas");if(r){var i=this;this.events.forEach(function(t){r.addEventListener(t,function(e){Ef[t]?Ef[t].call(i,e):i.fire(t,e)})})}return bf.prototype.initialize.call(this,t,e,n)},Ef.canvas=function(){return this._canvas},Ef.context=function(){return this._canvas.getContext("2d")},Ef.events=["keydown","keypress","keyup","dragenter","dragleave","dragover","mousedown","mouseup","mousemove","mouseout","mouseover","click","dblclick","wheel","mousewheel","touchstart","touchmove","touchend"],Ef.DOMMouseScroll=function(t){this.fire("mousewheel",t)},Ef.mousemove=Sf("mousemove","mouseover","mouseout"),Ef.dragover=Sf("dragover","dragenter","dragleave"),Ef.mouseout=Af("mouseout"),Ef.dragleave=Af("dragleave"),Ef.mousedown=function(t){this._down=this._active,this.fire("mousedown",t)},Ef.click=function(t){this._down===this._active&&(this.fire("click",t),this._down=null)},Ef.touchstart=function(t){this._touch=this.pickEvent(t.changedTouches[0]),this._first&&(this._active=this._touch,this._first=!1),this.fire("touchstart",t,!0)},Ef.touchmove=function(t){this.fire("touchmove",t,!0)},Ef.touchend=function(t){this.fire("touchend",t,!0),this._touch=null},Ef.fire=function(t,e,n){var r,i,a=n?this._touch:this._active,o=this._handlers[t];if("click"===t&&a&&a.href?this.handleHref(e,a,a.href):("mouseover"===t||"mouseout"===t)&&a&&a.tooltip&&this.handleTooltip(e,a,"mouseover"===t?a.tooltip:null),o)for(e.vegaType=t,r=0,i=o.length;r=0&&r.splice(i,1),this},Ef.pickEvent=function(t){var e=Mf(t,this._canvas),n=this._origin;return this.pick(this._scene,e[0],e[1],e[0]-n[0],e[1]-n[1])},Ef.pick=function(t,e,n,r,i){var a=this.context();return rf[t.marktype].pick.call(this,a,t,e,n,r,i)};var Cf="undefined"!=typeof window&&window.devicePixelRatio||1;function Nf(t){xf.call(this,t),this._redraw=!1,this._dirty=new Wa}var zf=G(Nf,xf),Of=xf.prototype,Df=new Wa;function Rf(t){bf.call(this,t);var e=this;e._hrefHandler=Pf(e,function(t,n){n&&n.href&&e.handleHref(t,n,n.href)}),e._tooltipHandler=Pf(e,function(t,n){n&&n.tooltip&&e.handleTooltip(t,n,"mouseover"===t.type?n.tooltip:null)})}zf.initialize=function(t,e,n,r,i){return this._canvas=Za(1,1),t&&(mf(t,0).appendChild(this._canvas),this._canvas.setAttribute("class","marks")),Of.initialize.call(this,t,e,n,r,i)},zf.resize=function(t,e,n,r){return Of.resize.call(this,t,e,n,r),function(t,e,n,r,i){var a="undefined"!=typeof HTMLElement&&t instanceof HTMLElement&&null!=t.parentNode,o=t.getContext("2d"),u=a?Cf:i;t.width=e*u,t.height=n*u,a&&1!==u&&(t.style.width=e+"px",t.style.height=n+"px"),o.pixelRatio=u,o.setTransform(u,0,0,u,u*r[0],u*r[1])}(this._canvas,this._width,this._height,this._origin,this._scale),this._redraw=!0,this},zf.canvas=function(){return this._canvas},zf.context=function(){return this._canvas?this._canvas.getContext("2d"):null},zf.dirty=function(t){var e=function(t,e){if(null==e)return t;for(var n=Df.clear().union(t);null!=e;e=e.mark.group)n.translate(e.x||0,e.y||0);return n}(t.bounds,t.mark.group);this._dirty.union(e)},zf._render=function(t){var e=this.context(),n=this._origin,r=this._width,i=this._height,a=this._dirty;return e.save(),this._redraw||a.empty()?(this._redraw=!1,a=null):a=function(t,e,n){return e.expand(1).round(),e.translate(-n[0]%1,-n[1]%1),t.beginPath(),t.rect(e.x1,e.y1,e.width(),e.height()),t.clip(),e}(e,a,n),this.clear(-n[0],-n[1],r,i),this.draw(e,t,a),e.restore(),this._dirty.clear(),this},zf.draw=function(t,e,n){var r=rf[e.marktype];e.clip&&function(t,e){var n=e.clip;if(t.save(),t.beginPath(),j(n))n(t);else{var r=e.group;t.rect(0,0,r.width||0,r.height||0)}t.clip()}(t,e),r.draw.call(this,t,e,n),e.clip&&t.restore()},zf.clear=function(t,e,n,r){var i=this.context();i.clearRect(t,e,n,r),null!=this._bgcolor&&(i.fillStyle=this._bgcolor,i.fillRect(t,e,n,r))};var Tf=G(Rf,bf);function Pf(t,e){return function(n){var r=n.target.__data__;n.vegaType=n.type,r=Array.isArray(r)?r[0]:r,e.call(t._obj,n,r)}}function Lf(t,e,n){var r,i,a="<"+t;if(e)for(r in e)null!=(i=e[r])&&(a+=" "+r+'="'+i+'"');return n&&(a+=" "+n),a+">"}function qf(t){return""}Tf.initialize=function(t,e,n){var r=this._svg;return r&&(r.removeEventListener("click",this._hrefHandler),r.removeEventListener("mouseover",this._tooltipHandler),r.removeEventListener("mouseout",this._tooltipHandler)),this._svg=r=t&&vf(t,"svg"),r&&(r.addEventListener("click",this._hrefHandler),r.addEventListener("mouseover",this._tooltipHandler),r.addEventListener("mouseout",this._tooltipHandler)),bf.prototype.initialize.call(this,t,e,n)},Tf.svg=function(){return this._svg},Tf.on=function(t,e){var n=this.eventName(t),r=this._handlers;if(this._handlerIndex(r[n],t,e)<0){var i={type:t,handler:e,listener:Pf(this,e)};(r[n]||(r[n]=[])).push(i),this._svg&&this._svg.addEventListener(n,i.listener)}return this},Tf.off=function(t,e){var n=this.eventName(t),r=this._handlers[n],i=this._handlerIndex(r,t,e);return i>=0&&(this._svg&&this._svg.removeEventListener(n,r[i].listener),r.splice(i,1)),this};var Uf={version:"1.1",xmlns:"http://www.w3.org/2000/svg","xmlns:xlink":"http://www.w3.org/1999/xlink"},jf={fill:"fill",fillOpacity:"fill-opacity",stroke:"stroke",strokeOpacity:"stroke-opacity",strokeWidth:"stroke-width",strokeCap:"stroke-linecap",strokeJoin:"stroke-linejoin",strokeDash:"stroke-dasharray",strokeDashOffset:"stroke-dashoffset",strokeMiterLimit:"stroke-miterlimit",opacity:"opacity"},Ff=Object.keys(jf),If=Uf.xmlns;function $f(t){xf.call(this,t),this._dirtyID=1,this._dirty=[],this._svg=null,this._root=null,this._defs=null}var Bf=G($f,xf),Wf=xf.prototype;function Hf(t,e,n){var r,i,a;for((t=gf(t,n,"linearGradient",If)).setAttribute("id",e.id),t.setAttribute("x1",e.x1),t.setAttribute("x2",e.x2),t.setAttribute("y1",e.y1),t.setAttribute("y2",e.y2),r=0,i=e.stops.length;r0?Lf("defs")+a+qf("defs"):""},ec.attributes=function(t,e){return tc={},t(rc,e,this),tc},ec.href=function(t){var e,n=this,r=t.href;if(r){if(e=n._hrefs&&n._hrefs[r])return e;n.sanitizeURL(r).then(function(t){t["xlink:href"]=t.href,t.href=null,(n._hrefs||(n._hrefs={}))[r]=t})}return null},ec.mark=function(t){var e,n=this,r=rf[t.marktype],i=r.tag,a=this._defs,o="";function u(u){var s=n.href(u);s&&(o+=Lf("a",s)),e="g"!==i?ic(u,t,i,a):null,o+=Lf(i,n.attributes(r.attr,u),e),"text"===i?o+=Zs(u).replace(/&/g,"&").replace(//g,">"):"g"===i&&(o+=Lf("path",n.attributes(r.background,u),ic(u,t,"bgrect",a))+qf("path"),o+=Lf("g",n.attributes(r.foreground,u))+n.markGroup(u)+qf("g")),o+=qf(i),s&&(o+=qf("a"))}return"g"!==i&&!1===t.interactive&&(e='style="pointer-events: none;"'),o+=Lf("g",{class:yf(t),"clip-path":t.clip?Ss(n,t,t.group):null},e),r.nested?t.items&&t.items.length&&u(t.items[0]):ls(t,u),o+qf("g")},ec.markGroup=function(t){var e=this,n="";return ls(t,function(t){n+=e.mark(t)}),n};var ac={Canvas:"canvas",PNG:"png",SVG:"svg",None:"none"},oc={};function uc(t,e){return t=String(t||"").toLowerCase(),arguments.length>1?(oc[t]=e,this):oc[t]}oc.canvas=oc.png={renderer:Nf,headless:Nf,handler:kf},oc.svg={renderer:$f,headless:Kf,handler:Rf},oc.none={};var sc=new Wa,fc=function(t){var e=t.clip;if(j(e))e(ns(sc.clear()));else{if(!e)return;sc.set(0,0,t.group.width,t.group.height)}t.bounds.intersect(sc)},cc=1e-9;function lc(t,e,n){return t===e||("path"===n?hc(t,e):t instanceof Date&&e instanceof Date?+t==+e:J(t)&&J(e)?Math.abs(t-e)<=cc:t&&e&&(f(t)||f(e))?null!=t&&null!=e&&function(t,e){var n,r,i=Object.keys(t),a=Object.keys(e);if(i.length!==a.length)return!1;for(i.sort(),a.sort(),r=i.length-1;r>=0;r--)if(i[r]!=a[r])return!1;for(r=i.length-1;r>=0;r--)if(n=i[r],!lc(t[n],e[n],n))return!1;return typeof t==typeof e}(t,e):t==e)}function hc(t,e){return lc(mu(t),mu(e))}function dc(t){Br.call(this,null,t)}function pc(t,e,n){return e(t.bounds.clear(),t,n)}G(dc,Br).transform=function(t,e){var n,r=e.dataflow,i=t.mark,a=i.marktype,o=rf[a],u=o.bound,s=i.bounds;return o.nested?(i.items.length&&r.dirty(i.items[0]),s=pc(i,u),i.items.forEach(function(t){t.bounds.clear().union(s)})):"group"===a||t.modified()?(e.visit(e.MOD,function(t){r.dirty(t)}),s.clear(),i.items.forEach(function(t){s.union(pc(t,u))})):(n=e.changed(e.REM),e.visit(e.ADD,function(t){s.union(pc(t,u))}),e.visit(e.MOD,function(t){n=n||s.alignsWith(t.bounds),r.dirty(t),s.union(pc(t,u))}),n&&(s.clear(),i.items.forEach(function(t){s.union(t.bounds)}))),fc(i),e.modifies("bounds")};var vc=":vega_identifier:";function gc(t){Br.call(this,0,t)}function mc(t){Br.call(this,null,t)}gc.Definition={type:"Identifier",metadata:{modifies:!0},params:[{name:"as",type:"string",required:!0}]},G(gc,Br).transform=function(t,e){var n=function(t){var e=t._signals[vc];e||(t._signals[vc]=e=t.add(0));return e}(e.dataflow),r=n.value,i=t.as;return e.visit(e.ADD,function(t){t[i]||(t[i]=++r)}),n.set(this.value=r),e},G(mc,Br).transform=function(t,e){var n=this.value;n||((n=e.dataflow.scenegraph().mark(t.markdef,function(t){var e=t.groups,n=t.parent;return e&&1===e.size?e.get(Object.keys(e.object)[0]):e&&n?e.lookup(n):null}(t),t.index)).group.context=t.context,t.context.group||(t.context.group=n.group),n.source=this,n.clip=t.clip,n.interactive=t.interactive,this.value=n);var r="group"===n.marktype?Ja:Xa;return e.visit(e.ADD,function(t){r.call(t,n)}),(t.modified("clip")||t.modified("interactive"))&&(n.clip=t.clip,n.interactive=!!t.interactive,n.zdirty=!0,e.reflow()),n.items=e.source,e};var yc="top",bc="left",_c="right",xc="bottom";function wc(t){Br.call(this,null,t)}var Mc={parity:function(t){return t.filter(function(t,e){return e%2?t.opacity=0:1})},greedy:function(t){var e;return t.filter(function(t,n){return n&&kc(e.bounds,t.bounds)?t.opacity=0:(e=t,1)})}};function kc(t,e){return!(t.x2-1e.x2||t.y2-1e.y2)}function Ec(t){for(var e,n=1,r=t.length,i=t[0].bounds;n1&&e.height()>1}function Ac(t){Br.call(this,null,t)}G(wc,Br).transform=function(t,e){var n=Mc[t.method]||Mc.parity,r=e.materialize(e.SOURCE).source;if(r){t.sort&&(r=r.slice().sort(t.sort)),"greedy"===t.method&&(r=r.filter(Sc)),r.forEach(function(t){t.opacity=1});var i,a,o,u,s,f=r;if(f.length>=3&&Ec(f)){e=e.reflow(t.modified()).modifies("opacity");do{f=n(f)}while(f.length>=3&&Ec(f));f.length<3&&!E(r).opacity&&(f.length>1&&(E(f).opacity=0),E(r).opacity=1)}if(t.boundScale){var c=(i=t.boundScale,a=t.boundOrient,o=t.boundTolerance,u=i.range(),s=new Wa,a===yc||a===xc?s.set(u[0],-1/0,u[1],1/0):s.set(-1/0,u[0],1/0,u[1]),s.expand(o||1),function(t){return s.encloses(t.bounds)});r.forEach(function(t){c(t)||(t.opacity=0)})}return e}},G(Ac,Br).transform=function(t,e){var n=e.dataflow;if(e.visit(e.ALL,function(t){n.dirty(t)}),e.fields&&e.fields.zindex){var r=e.source&&e.source[0];r&&(r.mark.zdirty=!0)}};var Cc="axis",Nc="legend",zc="row-header",Oc="row-footer",Dc="row-title",Rc="column-header",Tc="column-footer",Pc="column-title";function Lc(t,e){for(var n=0,r=t.length;ni&&(t.warn("Grid headers exceed limit: "+i),e=e.slice(0,i)),k+=a,v=0,m=e.length;v=0&&null==(_=n[g]);g-=h);u?(x=null==d?_.x:Math.round(_.bounds.x1+d*_.bounds.width()),w=k):(x=k,w=null==d?_.y:Math.round(_.bounds.y1+d*_.bounds.height())),y.union(b.bounds.translate(x-(b.x||0),w-(b.y||0))),b.x=x,b.y=w,t.dirty(b),E=o(E,y[f])}return E}function Hc(t,e,n,r,i,a){if(e){t.dirty(e);var o=n,u=n;r?o=Math.round(i.x1+a*i.width()):u=Math.round(i.y1+a*i.height()),e.bounds.translate(o-(e.x||0),u-(e.y||0)),e.mark.bounds.clear().union(e.bounds),e.x=o,e.y=u,t.dirty(e)}}var Yc="fit",Gc="fit-x",Vc="fit-y",Xc="pad",Jc="none",Zc="padding",Qc="axis",Kc="title",tl="frame",el="legend",nl="scope",rl="row-header",il="row-footer",al="column-header",ol="column-footer",ul=.5,sl=new Wa;function fl(t){Br.call(this,null,t)}function cl(t,e,n){return t[e]===n?0:(t[e]=n,1)}function ll(t){var e=t.items[0].datum.orient;return e===bc||e===_c}function hl(t,e,n,r){var i,a,o=e.items[0],u=o.datum,s=u.orient,f=function(t){var e=+t.grid;return[t.ticks?e++:-1,t.labels?e++:-1,e+ +t.domain]}(u),c=o.range,l=o.offset,h=o.position,d=o.minExtent,p=o.maxExtent,v=u.title&&o.items[f[2]].items[0],g=o.titlePadding,m=o.bounds,y=0,b=0;switch(sl.clear().union(m),m.clear(),(i=f[0])>-1&&m.union(o.items[i].bounds),(i=f[1])>-1&&m.union(o.items[i].bounds),s){case yc:y=h||0,b=-l,a=Math.max(d,Math.min(p,-m.y1)),v&&(v.auto?(a+=g,v.y=-a,a+=v.bounds.height(),m.add(v.bounds.x1,0).add(v.bounds.x2,0)):m.union(v.bounds)),m.add(0,-a).add(c,0);break;case bc:y=-l,b=h||0,a=Math.max(d,Math.min(p,-m.x1)),v&&(v.auto?(a+=g,v.x=-a,a+=v.bounds.width(),m.add(0,v.bounds.y1).add(0,v.bounds.y2)):m.union(v.bounds)),m.add(-a,0).add(0,c);break;case _c:y=n+l,b=h||0,a=Math.max(d,Math.min(p,m.x2)),v&&(v.auto?(a+=g,v.x=a,a+=v.bounds.width(),m.add(0,v.bounds.y1).add(0,v.bounds.y2)):m.union(v.bounds)),m.add(0,0).add(a,c);break;case xc:y=h||0,b=r+l,a=Math.max(d,Math.min(p,m.y2)),v&&(v.auto?(a+=g,v.y=a,a+=v.bounds.height(),m.add(v.bounds.x1,0).add(v.bounds.x2,0)):m.union(v.bounds)),m.add(0,0).add(c,a);break;default:y=o.x,b=o.y}return Qu(m.translate(y,b),o),cl(o,"x",y+ul)|cl(o,"y",b+ul)&&(o.bounds=sl,t.dirty(o),o.bounds=m,t.dirty(o)),o.mark.bounds.clear().union(m)}function dl(t,e,n,r,i,a,o){var u,s,f,c=e.items[0],l=c.datum.orient,h=c.offset,d=c.bounds,p=0,v=0;switch(l===yc||l===xc?(f=i,p=n[l]):l!==bc&&l!==_c||(f=r,v=n[l]),sl.clear().union(d),d.clear(),c.items.forEach(function(t){d.union(t.bounds)}),u=Math.round(d.width())+2*c.padding-1,s=Math.round(d.height())+2*c.padding-1,l){case bc:p-=u+h-Math.floor(f.x1),n.left+=s+n.margin;break;case _c:p+=h+Math.ceil(f.x2),n.right+=s+n.margin;break;case yc:v-=s+h-Math.floor(f.y1),n.top+=u+n.margin;break;case xc:v+=h+Math.ceil(f.y2),n.bottom+=u+n.margin;break;case"top-left":p+=h,v+=h;break;case"top-right":p+=a-u-h,v+=h;break;case"bottom-left":p+=h,v+=o-s-h;break;case"bottom-right":p+=a-u-h,v+=o-s-h;break;default:p=c.x,v=c.y}return Qu(d.set(p,v,p+u,v+s),c),cl(c,"x",p)|cl(c,"width",u)|cl(c,"y",v)|cl(c,"height",s)&&(c.bounds=sl,t.dirty(c),c.bounds=d,t.dirty(c)),c.mark.bounds.clear().union(d)}G(fl,Br).transform=function(t,e){var n=e.dataflow;return t.mark.items.forEach(function(e){t.layout&&Bc(n,e,t.layout),function(t,e,n){var r,i,a,o,u,s,f=e.items,c=Math.max(0,e.width||0),l=Math.max(0,e.height||0),h=(new Wa).set(0,0,c,l),d=h.clone(),p=h.clone(),v=h.clone(),g=[];for(u=0,s=f.length;u=u&&o[i]<=s&&(f<0&&(f=i),n=i);if(!(f<0))return u=t.invertExtent(o[f]),s=t.invertExtent(o[n]),[void 0===u[0]?u[1]:u[0],void 0===s[1]?s[0]:s[1]]}},Cl=function(t,e,n){var r=t-e+2*n;return t?r>0?r:1:0},Nl=Array.prototype,zl=Nl.map,Ol=Nl.slice,Dl={name:"implicit"};function Rl(t){var e=Tt(),n=[],r=Dl;function i(i){var a=i+"",o=e.get(a);if(!o){if(r!==Dl)return r;e.set(a,o=n.push(i))}return t[(o-1)%t.length]}return t=null==t?[]:Ol.call(t),i.domain=function(t){if(!arguments.length)return n.slice();n=[],e=Tt();for(var r,a,o=-1,u=t.length;++o>8&15|e>>4&240,e>>4&15|240&e,(15&e)<<4|15&e,1):(e=Il.exec(t))?Jl(parseInt(e[1],16)):(e=$l.exec(t))?new th(e[1],e[2],e[3],1):(e=Bl.exec(t))?new th(255*e[1]/100,255*e[2]/100,255*e[3]/100,1):(e=Wl.exec(t))?Zl(e[1],e[2],e[3],e[4]):(e=Hl.exec(t))?Zl(255*e[1]/100,255*e[2]/100,255*e[3]/100,e[4]):(e=Yl.exec(t))?eh(e[1],e[2]/100,e[3]/100,1):(e=Gl.exec(t))?eh(e[1],e[2]/100,e[3]/100,e[4]):Vl.hasOwnProperty(t)?Jl(Vl[t]):"transparent"===t?new th(NaN,NaN,NaN,0):null}function Jl(t){return new th(t>>16&255,t>>8&255,255&t,1)}function Zl(t,e,n,r){return r<=0&&(t=e=n=NaN),new th(t,e,n,r)}function Ql(t){return t instanceof Ll||(t=Xl(t)),t?new th((t=t.rgb()).r,t.g,t.b,t.opacity):new th}function Kl(t,e,n,r){return 1===arguments.length?Ql(t):new th(t,e,n,null==r?1:r)}function th(t,e,n,r){this.r=+t,this.g=+e,this.b=+n,this.opacity=+r}function eh(t,e,n,r){return r<=0?t=e=n=NaN:n<=0||n>=1?t=e=NaN:e<=0&&(t=NaN),new rh(t,e,n,r)}function nh(t,e,n,r){return 1===arguments.length?function(t){if(t instanceof rh)return new rh(t.h,t.s,t.l,t.opacity);if(t instanceof Ll||(t=Xl(t)),!t)return new rh;if(t instanceof rh)return t;var e=(t=t.rgb()).r/255,n=t.g/255,r=t.b/255,i=Math.min(e,n,r),a=Math.max(e,n,r),o=NaN,u=a-i,s=(a+i)/2;return u?(o=e===a?(n-r)/u+6*(n0&&s<1?0:o,new rh(o,u,s,t.opacity)}(t):new rh(t,e,n,null==r?1:r)}function rh(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function ih(t,e,n){return 255*(t<60?e+(n-e)*t/60:t<180?n:t<240?e+(n-e)*(240-t)/60:e)}Tl(Ll,Xl,{displayable:function(){return this.rgb().displayable()},toString:function(){return this.rgb()+""}}),Tl(th,Kl,Pl(Ll,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new th(this.r*t,this.g*t,this.b*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new th(this.r*t,this.g*t,this.b*t,this.opacity)},rgb:function(){return this},displayable:function(){return 0<=this.r&&this.r<=255&&0<=this.g&&this.g<=255&&0<=this.b&&this.b<=255&&0<=this.opacity&&this.opacity<=1},toString:function(){var t=this.opacity;return(1===(t=isNaN(t)?1:Math.max(0,Math.min(1,t)))?"rgb(":"rgba(")+Math.max(0,Math.min(255,Math.round(this.r)||0))+", "+Math.max(0,Math.min(255,Math.round(this.g)||0))+", "+Math.max(0,Math.min(255,Math.round(this.b)||0))+(1===t?")":", "+t+")")}})),Tl(rh,nh,Pl(Ll,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new rh(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new rh(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=this.h%360+360*(this.h<0),e=isNaN(t)||isNaN(this.s)?0:this.s,n=this.l,r=n+(n<.5?n:1-n)*e,i=2*n-r;return new th(ih(t>=240?t-240:t+120,i,r),ih(t,i,r),ih(t<120?t+240:t-120,i,r),this.opacity)},displayable:function(){return(0<=this.s&&this.s<=1||isNaN(this.s))&&0<=this.l&&this.l<=1&&0<=this.opacity&&this.opacity<=1}}));var ah=Math.PI/180,oh=180/Math.PI,uh=.95047,sh=1,fh=1.08883,ch=4/29,lh=6/29,hh=3*lh*lh,dh=lh*lh*lh;function ph(t){if(t instanceof gh)return new gh(t.l,t.a,t.b,t.opacity);if(t instanceof wh){var e=t.h*ah;return new gh(t.l,Math.cos(e)*t.c,Math.sin(e)*t.c,t.opacity)}t instanceof th||(t=Ql(t));var n=_h(t.r),r=_h(t.g),i=_h(t.b),a=mh((.4124564*n+.3575761*r+.1804375*i)/uh),o=mh((.2126729*n+.7151522*r+.072175*i)/sh);return new gh(116*o-16,500*(a-o),200*(o-mh((.0193339*n+.119192*r+.9503041*i)/fh)),t.opacity)}function vh(t,e,n,r){return 1===arguments.length?ph(t):new gh(t,e,n,null==r?1:r)}function gh(t,e,n,r){this.l=+t,this.a=+e,this.b=+n,this.opacity=+r}function mh(t){return t>dh?Math.pow(t,1/3):t/hh+ch}function yh(t){return t>lh?t*t*t:hh*(t-ch)}function bh(t){return 255*(t<=.0031308?12.92*t:1.055*Math.pow(t,1/2.4)-.055)}function _h(t){return(t/=255)<=.04045?t/12.92:Math.pow((t+.055)/1.055,2.4)}function xh(t,e,n,r){return 1===arguments.length?function(t){if(t instanceof wh)return new wh(t.h,t.c,t.l,t.opacity);t instanceof gh||(t=ph(t));var e=Math.atan2(t.b,t.a)*oh;return new wh(e<0?e+360:e,Math.sqrt(t.a*t.a+t.b*t.b),t.l,t.opacity)}(t):new wh(t,e,n,null==r?1:r)}function wh(t,e,n,r){this.h=+t,this.c=+e,this.l=+n,this.opacity=+r}Tl(gh,vh,Pl(Ll,{brighter:function(t){return new gh(this.l+18*(null==t?1:t),this.a,this.b,this.opacity)},darker:function(t){return new gh(this.l-18*(null==t?1:t),this.a,this.b,this.opacity)},rgb:function(){var t=(this.l+16)/116,e=isNaN(this.a)?t:t+this.a/500,n=isNaN(this.b)?t:t-this.b/200;return t=sh*yh(t),new th(bh(3.2404542*(e=uh*yh(e))-1.5371385*t-.4985314*(n=fh*yh(n))),bh(-.969266*e+1.8760108*t+.041556*n),bh(.0556434*e-.2040259*t+1.0572252*n),this.opacity)}})),Tl(wh,xh,Pl(Ll,{brighter:function(t){return new wh(this.h,this.c,this.l+18*(null==t?1:t),this.opacity)},darker:function(t){return new wh(this.h,this.c,this.l-18*(null==t?1:t),this.opacity)},rgb:function(){return ph(this).rgb()}}));var Mh=-.14861,kh=1.78277,Eh=-.29227,Sh=-.90649,Ah=1.97294,Ch=Ah*Sh,Nh=Ah*kh,zh=kh*Eh-Sh*Mh;function Oh(t,e,n,r){return 1===arguments.length?function(t){if(t instanceof Dh)return new Dh(t.h,t.s,t.l,t.opacity);t instanceof th||(t=Ql(t));var e=t.r/255,n=t.g/255,r=t.b/255,i=(zh*r+Ch*e-Nh*n)/(zh+Ch-Nh),a=r-i,o=(Ah*(n-i)-Eh*a)/Sh,u=Math.sqrt(o*o+a*a)/(Ah*i*(1-i)),s=u?Math.atan2(o,a)*oh-120:NaN;return new Dh(s<0?s+360:s,u,i,t.opacity)}(t):new Dh(t,e,n,null==r?1:r)}function Dh(t,e,n,r){this.h=+t,this.s=+e,this.l=+n,this.opacity=+r}function Rh(t,e,n,r,i){var a=t*t,o=a*t;return((1-3*t+3*a-o)*e+(4-6*a+3*o)*n+(1+3*t+3*a-3*o)*r+o*i)/6}Tl(Dh,Oh,Pl(Ll,{brighter:function(t){return t=null==t?1/.7:Math.pow(1/.7,t),new Dh(this.h,this.s,this.l*t,this.opacity)},darker:function(t){return t=null==t?.7:Math.pow(.7,t),new Dh(this.h,this.s,this.l*t,this.opacity)},rgb:function(){var t=isNaN(this.h)?0:(this.h+120)*ah,e=+this.l,n=isNaN(this.s)?0:this.s*e*(1-e),r=Math.cos(t),i=Math.sin(t);return new th(255*(e+n*(Mh*r+kh*i)),255*(e+n*(Eh*r+Sh*i)),255*(e+n*(Ah*r)),this.opacity)}}));var Th=function(t){var e=t.length-1;return function(n){var r=n<=0?n=0:n>=1?(n=1,e-1):Math.floor(n*e),i=t[r],a=t[r+1],o=r>0?t[r-1]:2*i-a,u=r180||n<-180?n-360*Math.round(n/360):n):Lh(isNaN(t)?e:t)}function jh(t){return 1==(t=+t)?Fh:function(e,n){return n-e?function(t,e,n){return t=Math.pow(t,n),e=Math.pow(e,n)-t,n=1/n,function(r){return Math.pow(t+r*e,n)}}(e,n,t):Lh(isNaN(e)?n:e)}}function Fh(t,e){var n=e-t;return n?qh(t,n):Lh(isNaN(t)?e:t)}var Ih=function t(e){var n=jh(e);function r(t,e){var r=n((t=Kl(t)).r,(e=Kl(e)).r),i=n(t.g,e.g),a=n(t.b,e.b),o=Fh(t.opacity,e.opacity);return function(e){return t.r=r(e),t.g=i(e),t.b=a(e),t.opacity=o(e),t+""}}return r.gamma=t,r}(1);function $h(t){return function(e){var n,r,i=e.length,a=new Array(i),o=new Array(i),u=new Array(i);for(n=0;na&&(i=e.slice(a,i),u[o]?u[o]+=i:u[++o]=i),(n=n[0])===(r=r[0])?u[o]?u[o]+=r:u[++o]=r:(u[++o]=null,s.push({i:o,x:Gh(n,r)})),a=Jh.lastIndex;return a180?e+=360:e-t>180&&(t+=360),a.push({i:n.push(i(n)+"rotate(",null,r)-2,x:Gh(t,e)})):e&&n.push(i(n)+"rotate("+e+r)}(a.rotate,o.rotate,u,s),function(t,e,n,a){t!==e?a.push({i:n.push(i(n)+"skewX(",null,r)-2,x:Gh(t,e)}):e&&n.push(i(n)+"skewX("+e+r)}(a.skewX,o.skewX,u,s),function(t,e,n,r,a,o){if(t!==n||e!==r){var u=a.push(i(a)+"scale(",null,",",null,")");o.push({i:u-4,x:Gh(t,n)},{i:u-2,x:Gh(e,r)})}else 1===n&&1===r||a.push(i(a)+"scale("+n+","+r+")")}(a.scaleX,a.scaleY,o.scaleX,o.scaleY,u,s),a=o=null,function(t){for(var e,n=-1,r=s.length;++n2?Ad:Sd,r=i=null,c}function c(e){return(r||(r=n(a,o,s?function(t){return function(e,n){var r=t(e=+e,n=+n);return function(t){return t<=e?0:t>=n?1:r(t)}}}(t):t,u)))(+e)}return c.invert=function(t){return(i||(i=n(o,a,Ed,s?function(t){return function(e,n){var r=t(e=+e,n=+n);return function(t){return t<=0?e:t>=1?n:r(t)}}}(e):e)))(+t)},c.domain=function(t){return arguments.length?(a=zl.call(t,Md),f()):a.slice()},c.range=function(t){return arguments.length?(o=Ol.call(t),f()):o.slice()},c.rangeRound=function(t){return o=Ol.call(t),u=rd,f()},c.clamp=function(t){return arguments.length?(s=!!t,f()):s},c.interpolate=function(t){return arguments.length?(u=t,f()):u},f()}var zd,Od=function(t,e){if((n=(t=e?t.toExponential(e-1):t.toExponential()).indexOf("e"))<0)return null;var n,r=t.slice(0,n);return[r.length>1?r[0]+r.slice(2):r,+t.slice(n+1)]},Dd=function(t){return(t=Od(Math.abs(t)))?t[1]:NaN},Rd=function(t,e){var n=Od(t,e);if(!n)return t+"";var r=n[0],i=n[1];return i<0?"0."+new Array(-i).join("0")+r:r.length>i+1?r.slice(0,i+1)+"."+r.slice(i+1):r+new Array(i-r.length+2).join("0")},Td={"":function(t,e){t=t.toPrecision(e);t:for(var n,r=t.length,i=1,a=-1;i0&&(a=0)}return a>0?t.slice(0,a)+t.slice(n+1):t},"%":function(t,e){return(100*t).toFixed(e)},b:function(t){return Math.round(t).toString(2)},c:function(t){return t+""},d:function(t){return Math.round(t).toString(10)},e:function(t,e){return t.toExponential(e)},f:function(t,e){return t.toFixed(e)},g:function(t,e){return t.toPrecision(e)},o:function(t){return Math.round(t).toString(8)},p:function(t,e){return Rd(100*t,e)},r:Rd,s:function(t,e){var n=Od(t,e);if(!n)return t+"";var r=n[0],i=n[1],a=i-(zd=3*Math.max(-8,Math.min(8,Math.floor(i/3))))+1,o=r.length;return a===o?r:a>o?r+new Array(a-o+1).join("0"):a>0?r.slice(0,a)+"."+r.slice(a):"0."+new Array(1-a).join("0")+Od(t,Math.max(0,e+a-1))[0]},X:function(t){return Math.round(t).toString(16).toUpperCase()},x:function(t){return Math.round(t).toString(16)}},Pd=/^(?:(.)?([<>=^]))?([+\-\( ])?([$#])?(0)?(\d+)?(,)?(\.\d+)?([a-z%])?$/i;function Ld(t){return new qd(t)}function qd(t){if(!(e=Pd.exec(t)))throw new Error("invalid format: "+t);var e,n=e[1]||" ",r=e[2]||">",i=e[3]||"-",a=e[4]||"",o=!!e[5],u=e[6]&&+e[6],s=!!e[7],f=e[8]&&+e[8].slice(1),c=e[9]||"";"n"===c?(s=!0,c="g"):Td[c]||(c=""),(o||"0"===n&&"="===r)&&(o=!0,n="0",r="="),this.fill=n,this.align=r,this.sign=i,this.symbol=a,this.zero=o,this.width=u,this.comma=s,this.precision=f,this.type=c}Ld.prototype=qd.prototype,qd.prototype.toString=function(){return this.fill+this.align+this.sign+this.symbol+(this.zero?"0":"")+(null==this.width?"":Math.max(1,0|this.width))+(this.comma?",":"")+(null==this.precision?"":"."+Math.max(0,0|this.precision))+this.type};var Ud,jd,Fd,Id=function(t){return t},$d=["y","z","a","f","p","n","µ","m","","k","M","G","T","P","E","Z","Y"],Bd=function(t){var e,n,r=t.grouping&&t.thousands?(e=t.grouping,n=t.thousands,function(t,r){for(var i=t.length,a=[],o=0,u=e[0],s=0;i>0&&u>0&&(s+u+1>r&&(u=Math.max(1,r-s)),a.push(t.substring(i-=u,i+u)),!((s+=u+1)>r));)u=e[o=(o+1)%e.length];return a.reverse().join(n)}):Id,i=t.currency,a=t.decimal,o=t.numerals?function(t){return function(e){return e.replace(/[0-9]/g,function(e){return t[+e]})}}(t.numerals):Id,u=t.percent||"%";function s(t){var e=(t=Ld(t)).fill,n=t.align,s=t.sign,f=t.symbol,c=t.zero,l=t.width,h=t.comma,d=t.precision,p=t.type,v="$"===f?i[0]:"#"===f&&/[boxX]/.test(p)?"0"+p.toLowerCase():"",g="$"===f?i[1]:/[%p]/.test(p)?u:"",m=Td[p],y=!p||/[defgprs%]/.test(p);function b(t){var i,u,f,b=v,_=g;if("c"===p)_=m(t)+_,t="";else{var x=(t=+t)<0;if(t=m(Math.abs(t),d),x&&0==+t&&(x=!1),b=(x?"("===s?s:"-":"-"===s||"("===s?"":s)+b,_=("s"===p?$d[8+zd/3]:"")+_+(x&&"("===s?")":""),y)for(i=-1,u=t.length;++i(f=t.charCodeAt(i))||f>57){_=(46===f?a+t.slice(i+1):t.slice(i))+_,t=t.slice(0,i);break}}h&&!c&&(t=r(t,1/0));var w=b.length+t.length+_.length,M=w>1)+b+t+_+M.slice(w);break;default:t=M+b+t+_}return o(t)}return d=null==d?p?6:12:/[gprs]/.test(p)?Math.max(1,Math.min(21,d)):Math.max(0,Math.min(20,d)),b.toString=function(){return t+""},b}return{format:s,formatPrefix:function(t,e){var n=s(((t=Ld(t)).type="f",t)),r=3*Math.max(-8,Math.min(8,Math.floor(Dd(e)/3))),i=Math.pow(10,-r),a=$d[8+r/3];return function(t){return n(i*t)+a}}}};function Wd(t){return Ud=Bd(t),jd=Ud.format,Fd=Ud.formatPrefix,Ud}Wd({decimal:".",thousands:",",grouping:[3],currency:["$",""]});var Hd=function(t,e,n){var r,i=t[0],a=t[t.length-1],o=bi(i,a,null==e?10:e);switch((n=Ld(null==n?",f":n)).type){case"s":var u=Math.max(Math.abs(i),Math.abs(a));return null!=n.precision||isNaN(r=function(t,e){return Math.max(0,3*Math.max(-8,Math.min(8,Math.floor(Dd(e)/3)))-Dd(Math.abs(t)))}(o,u))||(n.precision=r),Fd(n,u);case"":case"e":case"g":case"p":case"r":null!=n.precision||isNaN(r=function(t,e){return t=Math.abs(t),e=Math.abs(e)-t,Math.max(0,Dd(e)-Dd(t))+1}(o,Math.max(Math.abs(i),Math.abs(a))))||(n.precision=r-("e"===n.type));break;case"f":case"%":null!=n.precision||isNaN(r=function(t){return Math.max(0,-Dd(Math.abs(t)))}(o))||(n.precision=r-2*("%"===n.type))}return jd(n)};function Yd(t){var e=t.domain;return t.ticks=function(t){var n=e();return mi(n[0],n[n.length-1],null==t?10:t)},t.tickFormat=function(t,n){return Hd(e(),t,n)},t.nice=function(n){null==n&&(n=10);var r,i=e(),a=0,o=i.length-1,u=i[a],s=i[o];return s0?r=yi(u=Math.floor(u/r)*r,s=Math.ceil(s/r)*r,n):r<0&&(r=yi(u=Math.ceil(u*r)/r,s=Math.floor(s*r)/r,n)),r>0?(i[a]=Math.floor(u/r)*r,i[o]=Math.ceil(s/r)*r,e(i)):r<0&&(i[a]=Math.ceil(u*r)/r,i[o]=Math.floor(s*r)/r,e(i)),t},t}function Gd(){var t=Nd(Ed,Gh);return t.copy=function(){return Cd(t,Gd())},Yd(t)}var Vd=function(t,e){var n,r=0,i=(t=t.slice()).length-1,a=t[r],o=t[i];return oa[1-c])))return n=Math.max(0,si(l,s)-1),o=s===f?n:si(l,f)-1,s-l[n]>e+1e-10&&++n,c&&(u=n,n=h-o,o=h-u),n>o?void 0:r().slice(n,o+1)}},n.invert=function(t){var e=n.invertRange([t,t]);return e?e[0]:e},n.copy=function(){return dp().domain(r()).range(a).round(o).paddingInner(u).paddingOuter(s).align(f)},c()}var pp=Array.prototype.map,vp=Array.prototype.slice;function gp(t){return pp.call(t,function(t){return+t})}function mp(t,e){return arguments.length>1?(yp[t]=function(t,e){return function(){var n=e();return n.invertRange||(n.invertRange=n.invert?Sl(n):n.invertExtent?Al(n):void 0),n.type=t,n}}(t,e),this):yp.hasOwnProperty(t)?yp[t]:void 0}var yp={identity:function t(){var e=[0,1];function n(t){return+t}return n.invert=n,n.domain=n.range=function(t){return arguments.length?(e=zl.call(t,Md),n):e.slice()},n.copy=function(){return t().domain(e)},Yd(n)},linear:Gd,log:function t(){var e=Nd(Xd,Jd).domain([1,10]),n=e.domain,r=10,i=Kd(10),a=Qd(10);function o(){return i=Kd(r),a=Qd(r),n()[0]<0&&(i=tp(i),a=tp(a)),e}return e.base=function(t){return arguments.length?(r=+t,o()):r},e.domain=function(t){return arguments.length?(n(t),o()):n()},e.ticks=function(t){var e,o=n(),u=o[0],s=o[o.length-1];(e=s0){for(;hs)break;v.push(l)}}else for(;h=1;--c)if(!((l=f*c)s)break;v.push(l)}}else v=mi(h,d,Math.min(d-h,p)).map(a);return e?v.reverse():v},e.tickFormat=function(t,n){if(null==n&&(n=10===r?".0e":","),"function"!=typeof n&&(n=jd(n)),t===1/0)return n;null==t&&(t=10);var o=Math.max(1,r*t/e.ticks().length);return function(t){var e=t/a(Math.round(i(t)));return e*r0?r[i-1]:e[0],i=r?[i[r-1],n]:[i[o-1],i[o]]},o.copy=function(){return t().domain([e,n]).range(a)},Yd(o)},threshold:function t(){var e=[.5],n=[0,1],r=1;function i(t){if(t<=t)return n[si(e,t,0,r)]}return i.domain=function(t){return arguments.length?(e=Ol.call(t),r=Math.min(e.length,n.length-1),i):e.slice()},i.range=function(t){return arguments.length?(n=Ol.call(t),r=Math.min(e.length,n.length-1),i):n.slice()},i.invertExtent=function(t){var r=n.indexOf(t);return[e[r-1],e[r]]},i.copy=function(){return t().domain(e).range(n)},i},time:function(){return hp(Ye,He,$e,Fe,je,Ue,qe,Te,un).domain([new Date(2e3,0,1),new Date(2e3,0,2)])},utc:function(){return hp(en,tn,Ze,Xe,Ve,Ge,qe,Te,fn).domain([Date.UTC(2e3,0,1),Date.UTC(2e3,0,2)])},band:dp,point:function(){return function t(e){var n=e.copy;return e.padding=e.paddingOuter,delete e.paddingInner,e.copy=function(){return t(n())},e}(dp().paddingInner(1))},sequential:function t(e){var n=Gd(),r=0,i=1,a=!1;function o(){var t=n.domain();r=t[0],i=E(t)-r}function u(t){var n=(t-r)/i;return e(a?Math.max(0,Math.min(1,n)):n)}return u.clamp=function(t){return arguments.length?(a=!!t,u):a},u.domain=function(t){return arguments.length?(n.domain(t),o(),u):n.domain()},u.interpolator=function(t){return arguments.length?(e=t,u):e},u.copy=function(){return t().domain(n.domain()).clamp(a).interpolator(e)},u.ticks=function(t){return n.ticks(t)},u.tickFormat=function(t,e){return n.tickFormat(t,e)},u.nice=function(t){return n.nice(t),o(),u},u},"bin-linear":function t(){var e=Gd(),n=[];function r(t){return e(t)}return r.domain=function(t){return arguments.length?(function(t){n=gp(t),e.domain([n[0],E(n)])}(t),r):n.slice()},r.range=function(t){return arguments.length?(e.range(t),r):e.range()},r.rangeRound=function(t){return arguments.length?(e.rangeRound(t),r):e.rangeRound()},r.interpolate=function(t){return arguments.length?(e.interpolate(t),r):e.interpolate()},r.invert=function(t){return e.invert(t)},r.ticks=function(t){var e=n.length,i=~~(e/(t||e));return i<2?r.domain():n.filter(function(t,e){return!(e%i)})},r.tickFormat=function(){return e.tickFormat.apply(e,arguments)},r.copy=function(){return t().domain(r.domain()).range(r.range())},r},"bin-ordinal":function t(){var e=[],n=[];function r(t){return null==t||t!=t?void 0:n[(si(e,t)-1)%n.length]}return r.domain=function(t){return arguments.length?(e=gp(t),r):e.slice()},r.range=function(t){return arguments.length?(n=vp.call(t),r):n.slice()},r.copy=function(){return t().domain(r.domain()).range(r.range())},r}};for(var bp in yp)mp(bp,yp[bp]);function _p(t){for(var e=t.length/6|0,n=new Array(e),r=0;r1)&&(t-=Math.floor(t));var e=Math.abs(t-.5);return Iv.h=360*t-100,Iv.s=1.5-1.5*e,Iv.l=.8-.9*e,Iv+""},interpolateWarm:jv,interpolateCool:Fv,interpolateViridis:Bv,interpolateMagma:Wv,interpolateInferno:Hv,interpolatePlasma:Yv}),Vv={blueorange:Sp},Xv={category10:Cp,accent:Np,dark2:zp,paired:Op,pastel1:Dp,pastel2:Rp,set1:Tp,set2:Pp,set3:Lp,category20:xp,category20b:wp,category20c:Mp,tableau10:kp,tableau20:Ep,viridis:Bv,magma:Wv,inferno:Hv,plasma:Yv,blueorange:Bh(E(Sp))};function Jv(t,e){Xv[t]=Gv["interpolate"+e],Vv[t]=Gv["scheme"+e]}Jv("blues","Blues"),Jv("greens","Greens"),Jv("greys","Greys"),Jv("purples","Purples"),Jv("reds","Reds"),Jv("oranges","Oranges"),Jv("brownbluegreen","BrBG"),Jv("purplegreen","PRGn"),Jv("pinkyellowgreen","PiYG"),Jv("purpleorange","PuOr"),Jv("redblue","RdBu"),Jv("redgrey","RdGy"),Jv("redyellowblue","RdYlBu"),Jv("redyellowgreen","RdYlGn"),Jv("spectral","Spectral"),Jv("bluegreen","BuGn"),Jv("bluepurple","BuPu"),Jv("greenblue","GnBu"),Jv("orangered","OrRd"),Jv("purplebluegreen","PuBuGn"),Jv("purpleblue","PuBu"),Jv("purplered","PuRd"),Jv("redpurple","RdPu"),Jv("yellowgreenblue","YlGnBu"),Jv("yellowgreen","YlGn"),Jv("yelloworangebrown","YlOrBr"),Jv("yelloworangered","YlOrRd");var Zv=function(t,e){if(arguments.length>1)return Xv[t]=e,this;var n=t.split("-");return t=n[0],(n=+n[1]+1)&&Vv.hasOwnProperty(t)?Vv[t][n-1]:!n&&Xv.hasOwnProperty(t)?Xv[t]:void 0};function Qv(t,e){var n=e[0],r=E(e)-n;return function(e){return t(n+e*r)}}function Kv(t,e,n){var r=n-e;return r?"linear"===t.type||"sequential"===t.type?function(t){return(t-e)/r}:t.copy().domain([e,n]).range([0,1]).interpolate(tg):I(0)}function tg(t,e){var n=e-t;return function(e){return t+e*n}}function eg(t,e){var n=xd[function(t){return"interpolate"+t.toLowerCase().split("-").map(function(t){return t[0].toUpperCase()+t.slice(1)}).join("")}(t)];return null!=e&&n&&n.gamma?n.gamma(e):n}var ng={millisecond:Te,second:qe,minute:Ue,hour:je,day:Fe,week:$e,month:He,year:Ye},rg={millisecond:Te,second:qe,minute:Ge,hour:Ve,day:Xe,week:Ze,month:tn,year:en};function ig(t){return ng.hasOwnProperty(t)&&ng[t]}function ag(t){return rg.hasOwnProperty(t)&&rg[t]}function og(t,e){var n;return f(e)&&(n=e.step,e=e.interval),c(e)&&(e="time"===t.type?ig(e):"utc"===t.type?ag(e):o("Only time and utc scales accept interval strings."),n&&(e=e.every(n))),e}function ug(t,e,n){var r=t.range(),i=r[0],a=E(r);if(i>a&&(r=a,a=i,i=r),e=e.filter(function(e){return!((e=t(e))a)}),n>0&&e.length>1){for(var o=[e[0],E(e)];e.length>n&&e.length>=3;)e=e.filter(function(t,e){return!(e%2)});e.length<3&&(e=o)}return e}function sg(t,e){return t.ticks?t.ticks(e):t.domain()}function fg(t,e,n){var r,i,a=t.tickFormat?t.tickFormat(e,n):String;return t.type===vl?(r=a,i=function(t){var e=Ld(t||",");if(null==e.precision){switch(e.precision=12,e.type){case"%":e.precision-=2;break;case"e":e.precision-=1}return n=jd(e),r=jd(".1f")(1)[1],function(t){var e,i,a=n(t),o=a.indexOf(r);if(o<0)return a;for(e=function(t,e){var n,r=t.lastIndexOf("e");if(r>0)return r;for(r=t.length;--r>e;)if((n=t.charCodeAt(r))>=48&&n<=57)return r+1}(a,o),i=eo;)if("0"!==a[e]){++e;break}return a.slice(0,e)+i}}return jd(e);var n,r}(n),function(t){return r(t)?i(t):""}):a}function cg(t){Br.call(this,null,t)}function lg(t){Br.call(this,null,t)}function hg(){return vt({})}function dg(t){return t.exit}function pg(t){Br.call(this,null,t)}G(cg,Br).transform=function(t,e){if(this.value&&!t.modified())return e.StopPropagation;var n=e.fork(e.NO_SOURCE|e.NO_FIELDS),r=this.value,i=t.scale,a=null==t.count?t.values?t.values.length:10:og(i,t.count),o=t.format||fg(i,a,t.formatSpecifier),u=t.values?ug(i,t.values,a):sg(i,a);return r&&(n.rem=r),r=u.map(function(t,e){return vt({index:e/(u.length-1),value:t,label:o(t)})}),t.extra&&r.push(vt({index:-1,extra:{value:r[0].value},label:""})),n.source=r,n.add=r,this.value=r,n},G(lg,Br).transform=function(t,e){var n=e.dataflow,r=e.fork(e.NO_SOURCE|e.NO_FIELDS),i=t.item||hg,a=t.key||dt,u=this.value;return s(r.encode)&&(r.encode=null),u&&(t.modified("key")||e.modified(a))&&o("DataJoin does not support modified key function or fields."),u||(e=e.addAll(),this.value=u=Y().test(dg),u.lookup=function(t){return u.get(a(t))}),e.visit(e.ADD,function(t){var e=a(t),n=u.get(e);n?n.exit?(u.empty--,r.add.push(n)):r.mod.push(n):(u.set(e,n=i(t)),r.add.push(n)),n.datum=t,n.exit=!1}),e.visit(e.MOD,function(t){var e=a(t),n=u.get(e);n&&(n.datum=t,r.mod.push(n))}),e.visit(e.REM,function(t){var e=a(t),n=u.get(e);t!==n.datum||n.exit||(r.rem.push(n),n.exit=!0,++u.empty)}),e.changed(e.ADD_MOD)&&r.modifies("datum"),t.clean&&u.empty>n.cleanThreshold&&n.runAfter(u.clean),r},G(pg,Br).transform=function(t,e){var n=e.fork(e.ADD_REM),r=t.encoders,i=e.encode;if(s(i)){if(!n.changed()&&!i.every(function(t){return r[t]}))return e.StopPropagation;i=i[0]}var a="enter"===i,o=r.update||b,u=r.enter||b,f=r.exit||b,c=(i&&!a?r[i]:o)||b;if(e.changed(e.ADD)&&(e.visit(e.ADD,function(e){u(e,t),o(e,t),c!==b&&c!==o&&c(e,t)}),n.modifies(u.output),n.modifies(o.output),c!==b&&c!==o&&n.modifies(c.output)),e.changed(e.REM)&&f!==b&&(e.visit(e.REM,function(e){f(e,t)}),n.modifies(f.output)),a||c!==b){var l=e.MOD|(t.modified()?e.REFLOW:0);a?(e.visit(l,function(e){var r=u(e,t);(c(e,t)||r)&&n.mod.push(e)}),n.mod.length&&n.modifies(u.output)):e.visit(l,function(e){c(e,t)&&n.mod.push(e)}),n.mod.length&&n.modifies(c.output)}return n.changed()?n:e.StopPropagation};var vg={};function gg(t){var e=t.domain();return e.max=e.pop(),e}function mg(t,e){return vg[t.type]?function(t){return function(e,n,r){var i=r[n+1]||r.max||1/0,a=yg(e,t),o=yg(i,t);return a&&o?a+"–"+o:o?"< "+o:"≥ "+a}}(e):function(t){return function(e){return t(e)}}(e)}function yg(t,e){return isFinite(t)?e(t):null}function bg(t){Br.call(this,[],t)}vg[xl]=function(t){var e=[-1/0].concat(t.quantiles());return e.max=1/0,e},vg[wl]=function(t){var e=t.domain(),n=e[0],r=E(e),i=t.range().length,a=new Array(i),o=0;a[0]=-1/0;for(;++oMath.PI?n<=t:n>t;return"M"+e*i+","+e*a+"A"+e+","+e+" 0 0,"+(s?1:0)+" "+e*o+","+e*u+"L"+r*o+","+r*u},"diagonal-horizontal":function(t,e,n,r){var i=(t+n)/2;return"M"+t+","+e+"C"+i+","+e+" "+i+","+r+" "+n+","+r},"diagonal-vertical":function(t,e,n,r){var i=(e+r)/2;return"M"+t+","+e+"C"+t+","+i+" "+n+","+i+" "+n+","+r},"diagonal-radial":function(t,e,n,r){var i=Math.cos(t),a=Math.sin(t),o=Math.cos(n),u=Math.sin(n),s=(e+r)/2;return"M"+e*i+","+e*a+"C"+s*i+","+s*a+" "+s*o+","+s*u+" "+r*o+","+r*u}});function xg(t){return t.source.x}function wg(t){return t.source.y}function Mg(t){return t.target.x}function kg(t){return t.target.y}function Eg(t){Br.call(this,{},t)}function Sg(t,e,n,r){return"M"+t+","+e+"L"+n+","+r}function Ag(t,e,n,r){var i=n-t,a=r-e,o=Math.sqrt(i*i+a*a)/2;return"M"+t+","+e+"A"+o+","+o+" "+180*Math.atan2(a,i)/Math.PI+" 0 1 "+n+","+r}function Cg(t,e,n,r){var i=n-t,a=r-e,o=.2*(i+a),u=.2*(a-i);return"M"+t+","+e+"C"+(t+o)+","+(e+u)+" "+(n+u)+","+(r-o)+" "+n+","+r}function Ng(t){Br.call(this,null,t)}Eg.Definition={type:"LinkPath",metadata:{modifies:!0},params:[{name:"sourceX",type:"field",default:"source.x"},{name:"sourceY",type:"field",default:"source.y"},{name:"targetX",type:"field",default:"target.x"},{name:"targetY",type:"field",default:"target.y"},{name:"orient",type:"enum",default:"vertical",values:["horizontal","vertical","radial"]},{name:"shape",type:"enum",default:"line",values:["line","arc","curve","diagonal","orthogonal"]},{name:"as",type:"string",default:"path"}]},G(Eg,Br).transform=function(t,e){var n=t.sourceX||xg,r=t.sourceY||wg,i=t.targetX||Mg,a=t.targetY||kg,u=t.as||"path",s=t.orient||"vertical",f=t.shape||"line",c=_g.get(f+"-"+s)||_g.get(f);return c||o("LinkPath unsupported type: "+t.shape+(t.orient?"-"+t.orient:"")),e.visit(e.SOURCE,function(t){t[u]=c(n(t),r(t),i(t),a(t))}),e.reflow(t.modified()).modifies(u)},Ng.Definition={type:"Pie",metadata:{modifies:!0},params:[{name:"field",type:"field"},{name:"startAngle",type:"number",default:0},{name:"endAngle",type:"number",default:6.283185307179586},{name:"sort",type:"boolean",default:!1},{name:"as",type:"string",array:!0,length:2,default:["startAngle","endAngle"]}]},G(Ng,Br).transform=function(t,e){var n,r,i,a=t.as||["startAngle","endAngle"],o=a[0],u=a[1],s=t.field||m,f=t.startAngle||0,c=null!=t.endAngle?t.endAngle:2*Math.PI,l=e.source,h=l.map(s),d=h.length,p=f,v=(c-f)/function(t,e){var n,r=t.length,i=-1,a=0;if(null==e)for(;++i-1)return r;var i,a,o=e.domain,u=t.type,s=e.zero||void 0===e.zero&&Og[u];if(!o)return 0;Dg[u]&&e.padding&&o[0]!==E(o)&&(o=function(t,e,n,r,i){var a=Math.abs(E(n)-n[0]),o=a/(a-2*r),u=t===vl?L(e,null,o):t===ml?q(e,null,o,.5):t===gl?q(e,null,o,i):P(e,null,o);return(e=e.slice())[0]=u[0],e[e.length-1]=u[1],e}(u,o,e.range,e.padding,e.exponent));(s||null!=e.domainMin||null!=e.domainMax||null!=e.domainMid)&&(i=(o=o.slice()).length-1||1,s&&(o[0]>0&&(o[0]=0),o[i]<0&&(o[i]=0)),null!=e.domainMin&&(o[0]=e.domainMin),null!=e.domainMax&&(o[i]=e.domainMax),null!=e.domainMid&&(((a=e.domainMid)o[i])&&n.warn("Scale domainMid exceeds domain min or max.",a),o.splice(i,0,a)));t.domain(o),u===_l&&t.unknown(void 0);e.nice&&t.nice&&t.nice(!0!==e.nice&&og(t,e.nice)||null);return o.length}(i,t,r)),e.fork(e.NO_SOURCE|e.NO_FIELDS)},G(qg,Br).transform=function(t,e){var n=t.modified("sort")||e.changed(e.ADD)||e.modified(t.sort.fields)||e.modified("datum");return n&&e.source.sort(t.sort),this.modified(n),e};function Ug(t){Br.call(this,null,t)}function jg(t,e,n,r,i){for(var a,o=(e-t.sum)/2,u=t.length,s=0;sh&&(h=l),n&&c.sort(n)}return d.max=h,d}(e.source,t.groupby,t.sort,f),r=0,i=n.length,a=n.max;rr!=d>r&&n<(h-f)*(r-c)/(d-c)+f&&(i=-i)}return i}function Xg(t,e,n){var r,i,a,o;return function(t,e,n){return(e[0]-t[0])*(n[1]-t[1])==(n[0]-t[0])*(e[1]-t[1])}(t,e,n)&&(i=t[r=+(t[0]===e[0])],a=n[r],o=e[r],i<=a&&a<=o||o<=a&&a<=i)}var Jg=function(){},Zg=[[],[[[1,1.5],[.5,1]]],[[[1.5,1],[1,1.5]]],[[[1.5,1],[.5,1]]],[[[1,.5],[1.5,1]]],[[[1,1.5],[.5,1]],[[1,.5],[1.5,1]]],[[[1,.5],[1,1.5]]],[[[1,.5],[.5,1]]],[[[.5,1],[1,.5]]],[[[1,1.5],[1,.5]]],[[[.5,1],[1,.5]],[[1.5,1],[1,1.5]]],[[[1.5,1],[1,.5]]],[[[.5,1],[1.5,1]]],[[[1,1.5],[1.5,1]]],[[[.5,1],[1,1.5]]],[]],Qg=function(){var t=1,e=1,n=_i,r=u;function i(t){var e=n(t);if(Array.isArray(e))e=e.slice().sort(Wg);else{var r=hi(t),i=r[0],o=r[1];e=bi(i,o,e),e=di(Math.floor(i/e)*e,Math.floor(o/e)*e,e)}return e.map(function(e){return a(t,e)})}function a(n,i){var a=[],u=[];return function(n,r,i){var a,u,s,f,c,l,h=new Array,d=new Array;a=u=-1,f=n[0]>=r,Zg[f<<1].forEach(p);for(;++a=r,Zg[s|f<<1].forEach(p);Zg[f<<0].forEach(p);for(;++u=r,c=n[u*t]>=r,Zg[f<<1|c<<2].forEach(p);++a=r,l=c,c=n[u*t+a+1]>=r,Zg[s|f<<1|c<<2|l<<3].forEach(p);Zg[f|c<<3].forEach(p)}a=-1,c=n[u*t]>=r,Zg[c<<2].forEach(p);for(;++a=r,Zg[c<<2|l<<3].forEach(p);function p(t){var e,n,r=[t[0][0]+a,t[0][1]+u],s=[t[1][0]+a,t[1][1]+u],f=o(r),c=o(s);(e=d[f])?(n=h[c])?(delete d[e.end],delete h[n.start],e===n?(e.ring.push(s),i(e.ring)):h[e.start]=d[n.end]={start:e.start,end:n.end,ring:e.ring.concat(n.ring)}):(delete d[e.end],e.ring.push(s),d[e.end=c]=e):(e=h[c])?(n=d[f])?(delete h[e.start],delete d[n.end],e===n?(e.ring.push(s),i(e.ring)):h[n.start]=d[e.end]={start:n.start,end:e.end,ring:n.ring.concat(e.ring)}):(delete h[e.start],e.ring.unshift(r),h[e.start=f]=e):h[f]=d[c]={start:f,end:c,ring:[r,s]}}Zg[c<<3].forEach(p)}(n,i,function(t){r(t,n,i),Hg(t)>0?a.push([t]):u.push(t)}),u.forEach(function(t){for(var e,n=0,r=a.length;n0&&o0&&u0&&a>0))throw new Error("invalid size");return t=r,e=a,i},i.thresholds=function(t){return arguments.length?(n="function"==typeof t?t:Array.isArray(t)?Yg(Bg.call(t)):Yg(t),i):n},i.smooth=function(t){return arguments.length?(r=t?u:Jg,i):r===u},i};function Kg(t,e,n){for(var r=t.width,i=t.height,a=1+(n<<1),o=0;o=n&&(u>=a&&(s-=t.data[u-a+o*r]),e.data[u-n+o*r]=s/Math.min(u+1,r-1+a-u,a))}function tm(t,e,n){for(var r=t.width,i=t.height,a=1+(n<<1),o=0;o=n&&(u>=a&&(s-=t.data[o+(u-a)*r]),e.data[o+(u-n)*r]=s/Math.min(u+1,i-1+a-u,a))}function em(t){return t[0]}function nm(t){return t[1]}var rm=["values","size"],im=["x","y","size","cellSize","bandwidth"];function am(t){Br.call(this,null,t)}am.Definition={type:"Contour",metadata:{generates:!0},params:[{name:"size",type:"number",array:!0,length:2,required:!0},{name:"values",type:"number",array:!0},{name:"x",type:"field"},{name:"y",type:"field"},{name:"cellSize",type:"number"},{name:"bandwidth",type:"number"},{name:"count",type:"number"},{name:"nice",type:"number",default:!1},{name:"thresholds",type:"number",array:!0}]},G(am,Br).transform=function(t,e){if(this.value&&!e.changed()&&!t.modified())return e.StopPropagation;var n,r,i,a,o=e.fork(e.NO_SOURCE|e.NO_FIELDS),u=t.count||10;return t.values?(n=Qg(),r=rm,i=t.values):(n=function(){var t=em,e=nm,n=960,r=500,i=20,a=2,o=3*i,u=n+2*o>>a,s=r+2*o>>a,f=Yg(20);function c(n){var r=new Float32Array(u*s),c=new Float32Array(u*s);n.forEach(function(n,i,f){var c=t(n,i,f)+o>>a,l=e(n,i,f)+o>>a;c>=0&&c=0&&l>a),tm({width:u,height:s,data:c},{width:u,height:s,data:r},i>>a),Kg({width:u,height:s,data:r},{width:u,height:s,data:c},i>>a),tm({width:u,height:s,data:c},{width:u,height:s,data:r},i>>a),Kg({width:u,height:s,data:r},{width:u,height:s,data:c},i>>a),tm({width:u,height:s,data:c},{width:u,height:s,data:r},i>>a);var h=f(r);if(!Array.isArray(h)){var d=wi(r);h=bi(0,d,h),(h=di(0,Math.floor(d/h)*h,h)).shift()}return Qg().thresholds(h).size([u,s])(r).map(l)}function l(t){return t.value*=Math.pow(2,-2*a),t.coordinates.forEach(h),t}function h(t){t.forEach(d)}function d(t){t.forEach(p)}function p(t){t[0]=t[0]*Math.pow(2,a)-o,t[1]=t[1]*Math.pow(2,a)-o}function v(){return u=n+2*(o=3*i)>>a,s=r+2*o>>a,c}return c.x=function(e){return arguments.length?(t="function"==typeof e?e:Yg(+e),c):t},c.y=function(t){return arguments.length?(e="function"==typeof t?t:Yg(+t),c):e},c.size=function(t){if(!arguments.length)return[n,r];var e=Math.ceil(t[0]),i=Math.ceil(t[1]);if(!(e>=0||e>=0))throw new Error("invalid size");return n=e,r=i,v()},c.cellSize=function(t){if(!arguments.length)return 1<=1))throw new Error("invalid cell size");return a=Math.floor(Math.log(t)/Math.LN2),v()},c.thresholds=function(t){return arguments.length?(f="function"==typeof t?t:Array.isArray(t)?Yg(Bg.call(t)):Yg(t),c):f},c.bandwidth=function(t){if(!arguments.length)return Math.sqrt(i*(i+1));if(!((t=+t)>=0))throw new Error("invalid bandwidth");return i=Math.round((Math.sqrt(4*t*t+1)-1)/2),v()},c}(),r=im,i=e.materialize(e.SOURCE).source),n.thresholds(t.thresholds||(t.nice?u:(a=u,function(t){for(var e=hi(t),n=e[0],r=e[1]-n,i=[],o=1;o<=a;++o)i.push(n+r*o/(a+1));return i}))),r.forEach(function(e){null!=t[e]&&n[e](t[e])}),this.value&&(o.rem=this.value),i=i&&i.length?n(i).map(vt):[],this.value=o.source=o.add=i,o};var om="FeatureCollection";function um(t){Br.call(this,null,t)}um.Definition={type:"GeoJSON",metadata:{},params:[{name:"fields",type:"field",array:!0,length:2},{name:"geojson",type:"field"}]},G(um,Br).transform=function(t,e){var n,r=this._features,i=this._points,o=t.fields,u=o&&o[0],s=o&&o[1],f=t.geojson,c=e.ADD;n=t.modified()||e.changed(e.REM)||e.modified(a(f))||u&&e.modified(a(u))||s&&e.modified(a(s)),this.value&&!n||(c=e.SOURCE,this._features=r=[],this._points=i=[]),f&&e.visit(c,function(t){r.push(f(t))}),u&&s&&(e.visit(c,function(t){var e=u(t),n=s(t);null!=e&&null!=n&&(e=+e)===e&&(n=+n)===n&&i.push([e,n])}),r=r.concat({type:"Feature",geometry:{type:"MultiPoint",coordinates:i}})),this.value={type:om,features:r}};var sm=function(){return new fm};function fm(){this.reset()}fm.prototype={constructor:fm,reset:function(){this.s=this.t=0},add:function(t){lm(cm,t,this.t),lm(this,cm.s,this.s),this.s?this.t+=cm.t:this.s=cm.t},valueOf:function(){return this.s}};var cm=new fm;function lm(t,e,n){var r=t.s=e+n,i=r-e,a=r-i;t.t=e-a+(n-i)}var hm=1e-6,dm=Math.PI,pm=dm/2,vm=dm/4,gm=2*dm,mm=180/dm,ym=dm/180,bm=Math.abs,_m=Math.atan,xm=Math.atan2,wm=Math.cos,Mm=Math.ceil,km=Math.exp,Em=Math.log,Sm=Math.pow,Am=Math.sin,Cm=Math.sign||function(t){return t>0?1:t<0?-1:0},Nm=Math.sqrt,zm=Math.tan;function Om(t){return t>1?0:t<-1?dm:Math.acos(t)}function Dm(t){return t>1?pm:t<-1?-pm:Math.asin(t)}function Rm(){}function Tm(t,e){t&&Lm.hasOwnProperty(t.type)&&Lm[t.type](t,e)}var Pm={Feature:function(t,e){Tm(t.geometry,e)},FeatureCollection:function(t,e){for(var n=t.features,r=-1,i=n.length;++r=0?1:-1,i=r*n,a=wm(e),o=Am(e),u=Bm*o,s=$m*a+u*wm(i),f=u*r*Am(i);Hm.add(xm(f,s)),Im=t,$m=a,Bm=o}var Qm,Km,ty,ey,ny,ry,iy,ay;function oy(t){return[xm(t[1],t[0]),Dm(t[2])]}function uy(t){var e=t[0],n=t[1],r=wm(n);return[r*wm(e),r*Am(e),Am(n)]}function sy(t,e){return t[0]*e[0]+t[1]*e[1]+t[2]*e[2]}function fy(t,e){return[t[1]*e[2]-t[2]*e[1],t[2]*e[0]-t[0]*e[2],t[0]*e[1]-t[1]*e[0]]}function cy(t,e){t[0]+=e[0],t[1]+=e[1],t[2]+=e[2]}function ly(t,e){return[t[0]*e,t[1]*e,t[2]*e]}function hy(t){var e=Nm(t[0]*t[0]+t[1]*t[1]+t[2]*t[2]);t[0]/=e,t[1]/=e,t[2]/=e}var dy,py,vy=sm(),gy={point:my,lineStart:by,lineEnd:_y,polygonStart:function(){gy.point=xy,gy.lineStart=wy,gy.lineEnd=My,vy.reset(),Gm.polygonStart()},polygonEnd:function(){Gm.polygonEnd(),gy.point=my,gy.lineStart=by,gy.lineEnd=_y,Hm<0?(Qm=-(ty=180),Km=-(ey=90)):vy>hm?ey=90:vy<-hm&&(Km=-90),py[0]=Qm,py[1]=ty}};function my(t,e){dy.push(py=[Qm=t,ty=t]),eey&&(ey=e)}function yy(t,e){var n=uy([t*ym,e*ym]);if(ay){var r=fy(ay,n),i=fy([r[1],-r[0],0],r);hy(i),i=oy(i);var a,o=t-ny,u=o>0?1:-1,s=i[0]*mm*u,f=bm(o)>180;f^(u*nyey&&(ey=a):f^(u*ny<(s=(s+360)%360-180)&&sey&&(ey=e)),f?tky(Qm,ty)&&(ty=t):ky(t,ty)>ky(Qm,ty)&&(Qm=t):ty>=Qm?(tty&&(ty=t)):t>ny?ky(Qm,t)>ky(Qm,ty)&&(ty=t):ky(t,ty)>ky(Qm,ty)&&(Qm=t)}else dy.push(py=[Qm=t,ty=t]);eey&&(ey=e),ay=n,ny=t}function by(){gy.point=yy}function _y(){py[0]=Qm,py[1]=ty,gy.point=my,ay=null}function xy(t,e){if(ay){var n=t-ny;vy.add(bm(n)>180?n+(n>0?360:-360):n)}else ry=t,iy=e;Gm.point(t,e),yy(t,e)}function wy(){Gm.lineStart()}function My(){xy(ry,iy),Gm.lineEnd(),bm(vy)>hm&&(Qm=-(ty=180)),py[0]=Qm,py[1]=ty,ay=null}function ky(t,e){return(e-=t)<0?e+360:e}function Ey(t,e){return t[0]-e[0]}function Sy(t,e){return t[0]<=t[1]?t[0]<=e&&e<=t[1]:edm?t-gm:t<-dm?t+gm:t,e]}function nb(t,e,n){return(t%=gm)?e||n?tb(ib(t),ab(e,n)):ib(t):e||n?ab(e,n):eb}function rb(t){return function(e,n){return[(e+=t)>dm?e-gm:e<-dm?e+gm:e,n]}}function ib(t){var e=rb(t);return e.invert=rb(-t),e}function ab(t,e){var n=wm(t),r=Am(t),i=wm(e),a=Am(e);function o(t,e){var o=wm(e),u=wm(t)*o,s=Am(t)*o,f=Am(e),c=f*n+u*r;return[xm(s*i-c*a,u*n-f*r),Dm(c*i+s*a)]}return o.invert=function(t,e){var o=wm(e),u=wm(t)*o,s=Am(t)*o,f=Am(e),c=f*i-s*a;return[xm(s*i+f*a,u*n+c*r),Dm(c*n-u*r)]},o}eb.invert=eb;var ob=function(t){function e(e){return(e=t(e[0]*ym,e[1]*ym))[0]*=mm,e[1]*=mm,e}return t=nb(t[0]*ym,t[1]*ym,t.length>2?t[2]*ym:0),e.invert=function(e){return(e=t.invert(e[0]*ym,e[1]*ym))[0]*=mm,e[1]*=mm,e},e};function ub(t,e){(e=uy(e))[0]-=t,hy(e);var n=Om(-e[1]);return((-e[2]<0?-n:n)+gm-hm)%gm}var sb=function(){var t,e=[];return{point:function(e,n){t.push([e,n])},lineStart:function(){e.push(t=[])},lineEnd:Rm,rejoin:function(){e.length>1&&e.push(e.pop().concat(e.shift()))},result:function(){var n=e;return e=[],t=null,n}}},fb=function(t,e){return bm(t[0]-e[0])=0;--a)i.point((c=f[a])[0],c[1]);else r(h.x,h.p.x,-1,i);h=h.p}f=(h=h.o).z,d=!d}while(!h.v);i.lineEnd()}}};function hb(t){if(e=t.length){for(var e,n,r=0,i=t[0];++r=0?1:-1,k=M*w,E=k>dm,S=p*_;if(db.add(xm(S*M*Am(k),v*x+S*wm(k))),a+=E?w+M*gm:w,E^h>=n^y>=n){var A=fy(uy(l),uy(m));hy(A);var C=fy(i,A);hy(C);var N=(E^w>=0?-1:1)*Dm(C[2]);(r>N||r===N&&(A[0]||A[1]))&&(o+=E^w>=0?1:-1)}}return(a<-hm||a0){for(l||(i.polygonStart(),l=!0),i.lineStart(),t=0;t1&&2&s&&h.push(h.pop().concat(h.shift())),o.push(h.filter(gb))}return h}};function gb(t){return t.length>1}function mb(t,e){return((t=t.x)[0]<0?t[1]-pm-hm:pm-t[1])-((e=e.x)[0]<0?e[1]-pm-hm:pm-e[1])}var yb=vb(function(){return!0},function(t){var e,n=NaN,r=NaN,i=NaN;return{lineStart:function(){t.lineStart(),e=1},point:function(a,o){var u=a>0?dm:-dm,s=bm(a-n);bm(s-dm)0?pm:-pm),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(u,r),t.point(a,r),e=0):i!==u&&s>=dm&&(bm(n-i)hm?_m((Am(e)*(a=wm(r))*Am(n)-Am(r)*(i=wm(e))*Am(t))/(i*a*o)):(e+r)/2}(n,r,a,o),t.point(i,r),t.lineEnd(),t.lineStart(),t.point(u,r),e=0),t.point(n=a,r=o),i=u},lineEnd:function(){t.lineEnd(),n=r=NaN},clean:function(){return 2-e}}},function(t,e,n,r){var i;if(null==t)i=n*pm,r.point(-dm,i),r.point(0,i),r.point(dm,i),r.point(dm,0),r.point(dm,-i),r.point(0,-i),r.point(-dm,-i),r.point(-dm,0),r.point(-dm,i);else if(bm(t[0]-e[0])>hm){var a=t[0]0,i=bm(e)>hm;function a(t,n){return wm(t)*wm(n)>e}function o(t,n,r){var i=[1,0,0],a=fy(uy(t),uy(n)),o=sy(a,a),u=a[0],s=o-u*u;if(!s)return!r&&t;var f=e*o/s,c=-e*u/s,l=fy(i,a),h=ly(i,f);cy(h,ly(a,c));var d=l,p=sy(h,d),v=sy(d,d),g=p*p-v*(sy(h,h)-1);if(!(g<0)){var m=Nm(g),y=ly(d,(-p-m)/v);if(cy(y,h),y=oy(y),!r)return y;var b,_=t[0],x=n[0],w=t[1],M=n[1];x<_&&(b=_,_=x,x=b);var k=x-_,E=bm(k-dm)0^y[1]<(bm(y[0]-_)dm^(_<=y[0]&&y[0]<=x)){var S=ly(d,(-p+m)/v);return cy(S,h),[y,oy(S)]}}}function u(e,n){var i=r?t:dm-t,a=0;return e<-i?a|=1:e>i&&(a|=2),n<-i?a|=4:n>i&&(a|=8),a}return vb(a,function(t){var e,n,s,f,c;return{lineStart:function(){f=s=!1,c=1},point:function(l,h){var d,p=[l,h],v=a(l,h),g=r?v?0:u(l,h):v?u(l+(l<0?dm:-dm),h):0;if(!e&&(f=s=v)&&t.lineStart(),v!==s&&(!(d=o(e,p))||fb(e,d)||fb(p,d))&&(p[0]+=hm,p[1]+=hm,v=a(p[0],p[1])),v!==s)c=0,v?(t.lineStart(),d=o(p,e),t.point(d[0],d[1])):(d=o(e,p),t.point(d[0],d[1]),t.lineEnd()),e=d;else if(i&&e&&r^v){var m;g&n||!(m=o(p,e,!0))||(c=0,r?(t.lineStart(),t.point(m[0][0],m[0][1]),t.point(m[1][0],m[1][1]),t.lineEnd()):(t.point(m[1][0],m[1][1]),t.lineEnd(),t.lineStart(),t.point(m[0][0],m[0][1])))}!v||e&&fb(e,p)||t.point(p[0],p[1]),e=p,s=v,n=g},lineEnd:function(){s&&t.lineEnd(),e=null},clean:function(){return c|(f&&s)<<1}}},function(e,r,i,a){!function(t,e,n,r,i,a){if(n){var o=wm(e),u=Am(e),s=r*n;null==i?(i=e+r*gm,a=e-s/2):(i=ub(o,i),a=ub(o,a),(r>0?ia)&&(i+=r*gm));for(var f,c=i;r>0?c>a:c0)){if(o/=l,l<0){if(o0){if(o>c)return;o>f&&(f=o)}if(o=i-u,l||!(o<0)){if(o/=l,l<0){if(o>c)return;o>f&&(f=o)}else if(l>0){if(o0)){if(o/=h,h<0){if(o0){if(o>c)return;o>f&&(f=o)}if(o=a-s,h||!(o<0)){if(o/=h,h<0){if(o>c)return;o>f&&(f=o)}else if(h>0){if(o0&&(t[0]=u+f*l,t[1]=s+f*h),c<1&&(e[0]=u+c*l,e[1]=s+c*h),!0}}}}},xb=1e9,wb=-xb;function Mb(t,e,n,r){function i(i,a){return t<=i&&i<=n&&e<=a&&a<=r}function a(i,a,u,f){var c=0,l=0;if(null==i||(c=o(i,u))!==(l=o(a,u))||s(i,a)<0^u>0)do{f.point(0===c||3===c?t:n,c>1?r:e)}while((c=(c+u+4)%4)!==l);else f.point(a[0],a[1])}function o(r,i){return bm(r[0]-t)0?0:3:bm(r[0]-n)0?2:1:bm(r[1]-e)0?1:0:i>0?3:2}function u(t,e){return s(t.x,e.x)}function s(t,e){var n=o(t,1),r=o(e,1);return n!==r?n-r:0===n?e[1]-t[1]:1===n?t[0]-e[0]:2===n?t[1]-e[1]:e[0]-t[0]}return function(o){var s,f,c,l,h,d,p,v,g,m,y,b=o,_=sb(),x={point:w,lineStart:function(){x.point=M,f&&f.push(c=[]);m=!0,g=!1,p=v=NaN},lineEnd:function(){s&&(M(l,h),d&&g&&_.rejoin(),s.push(_.result()));x.point=w,g&&b.lineEnd()},polygonStart:function(){b=_,s=[],f=[],y=!0},polygonEnd:function(){var e=function(){for(var e=0,n=0,i=f.length;nr&&(h-a)*(r-o)>(d-o)*(t-a)&&++e:d<=r&&(h-a)*(r-o)<(d-o)*(t-a)&&--e;return e}(),n=y&&e,i=(s=Mi(s)).length;(n||i)&&(o.polygonStart(),n&&(o.lineStart(),a(null,null,1,o),o.lineEnd()),i&&lb(s,u,e,a,o),o.polygonEnd());b=o,s=f=c=null}};function w(t,e){i(t,e)&&b.point(t,e)}function M(a,o){var u=i(a,o);if(f&&c.push([a,o]),m)l=a,h=o,d=u,m=!1,u&&(b.lineStart(),b.point(a,o));else if(u&&g)b.point(a,o);else{var s=[p=Math.max(wb,Math.min(xb,p)),v=Math.max(wb,Math.min(xb,v))],_=[a=Math.max(wb,Math.min(xb,a)),o=Math.max(wb,Math.min(xb,o))];_b(s,_,t,e,n,r)?(g||(b.lineStart(),b.point(s[0],s[1])),b.point(_[0],_[1]),u||b.lineEnd(),y=!1):u&&(b.lineStart(),b.point(a,o),y=!1)}p=a,v=o,g=u}return x}}sm();function kb(t,e,n){var r=di(t,e-hm,n).concat(e);return function(t){return r.map(function(e){return[t,e]})}}function Eb(t,e,n){var r=di(t,e-hm,n).concat(e);return function(t){return r.map(function(e){return[e,t]})}}var Sb,Ab,Cb,Nb,zb=function(t){return t},Ob=sm(),Db=sm(),Rb={point:Rm,lineStart:Rm,lineEnd:Rm,polygonStart:function(){Rb.lineStart=Tb,Rb.lineEnd=qb},polygonEnd:function(){Rb.lineStart=Rb.lineEnd=Rb.point=Rm,Ob.add(bm(Db)),Db.reset()},result:function(){var t=Ob/2;return Ob.reset(),t}};function Tb(){Rb.point=Pb}function Pb(t,e){Rb.point=Lb,Sb=Cb=t,Ab=Nb=e}function Lb(t,e){Db.add(Nb*t-Cb*e),Cb=t,Nb=e}function qb(){Lb(Sb,Ab)}var Ub=1/0,jb=Ub,Fb=-Ub,Ib=Fb,$b={point:function(t,e){tFb&&(Fb=t);eIb&&(Ib=e)},lineStart:Rm,lineEnd:Rm,polygonStart:Rm,polygonEnd:Rm,result:function(){var t=[[Ub,jb],[Fb,Ib]];return Fb=Ib=-(jb=Ub=1/0),t}};var Bb,Wb,Hb,Yb,Gb=0,Vb=0,Xb=0,Jb=0,Zb=0,Qb=0,Kb=0,t_=0,e_=0,n_={point:r_,lineStart:i_,lineEnd:u_,polygonStart:function(){n_.lineStart=s_,n_.lineEnd=f_},polygonEnd:function(){n_.point=r_,n_.lineStart=i_,n_.lineEnd=u_},result:function(){var t=e_?[Kb/e_,t_/e_]:Qb?[Jb/Qb,Zb/Qb]:Xb?[Gb/Xb,Vb/Xb]:[NaN,NaN];return Gb=Vb=Xb=Jb=Zb=Qb=Kb=t_=e_=0,t}};function r_(t,e){Gb+=t,Vb+=e,++Xb}function i_(){n_.point=a_}function a_(t,e){n_.point=o_,r_(Hb=t,Yb=e)}function o_(t,e){var n=t-Hb,r=e-Yb,i=Nm(n*n+r*r);Jb+=i*(Hb+t)/2,Zb+=i*(Yb+e)/2,Qb+=i,r_(Hb=t,Yb=e)}function u_(){n_.point=r_}function s_(){n_.point=c_}function f_(){l_(Bb,Wb)}function c_(t,e){n_.point=l_,r_(Bb=Hb=t,Wb=Yb=e)}function l_(t,e){var n=t-Hb,r=e-Yb,i=Nm(n*n+r*r);Jb+=i*(Hb+t)/2,Zb+=i*(Yb+e)/2,Qb+=i,Kb+=(i=Yb*t-Hb*e)*(Hb+t),t_+=i*(Yb+e),e_+=3*i,r_(Hb=t,Yb=e)}function h_(t){this._context=t}h_.prototype={_radius:4.5,pointRadius:function(t){return this._radius=t,this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._context.closePath(),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._context.moveTo(t,e),this._point=1;break;case 1:this._context.lineTo(t,e);break;default:this._context.moveTo(t+this._radius,e),this._context.arc(t,e,this._radius,0,gm)}},result:Rm};var d_,p_,v_,g_,m_,y_=sm(),b_={point:Rm,lineStart:function(){b_.point=__},lineEnd:function(){d_&&x_(p_,v_),b_.point=Rm},polygonStart:function(){d_=!0},polygonEnd:function(){d_=null},result:function(){var t=+y_;return y_.reset(),t}};function __(t,e){b_.point=x_,p_=g_=t,v_=m_=e}function x_(t,e){g_-=t,m_-=e,y_.add(Nm(g_*g_+m_*m_)),g_=t,m_=e}function w_(){this._string=[]}function M_(t){return"m0,"+t+"a"+t+","+t+" 0 1,1 0,"+-2*t+"a"+t+","+t+" 0 1,1 0,"+2*t+"z"}w_.prototype={_radius:4.5,_circle:M_(4.5),pointRadius:function(t){return(t=+t)!==this._radius&&(this._radius=t,this._circle=null),this},polygonStart:function(){this._line=0},polygonEnd:function(){this._line=NaN},lineStart:function(){this._point=0},lineEnd:function(){0===this._line&&this._string.push("Z"),this._point=NaN},point:function(t,e){switch(this._point){case 0:this._string.push("M",t,",",e),this._point=1;break;case 1:this._string.push("L",t,",",e);break;default:null==this._circle&&(this._circle=M_(this._radius)),this._string.push("M",t,",",e,this._circle)}},result:function(){if(this._string.length){var t=this._string.join("");return this._string=[],t}return null}};var k_=function(t,e){var n,r,i=4.5;function a(t){return t&&("function"==typeof i&&r.pointRadius(+i.apply(this,arguments)),Wm(t,n(r))),r.result()}return a.area=function(t){return Wm(t,n(Rb)),Rb.result()},a.measure=function(t){return Wm(t,n(b_)),b_.result()},a.bounds=function(t){return Wm(t,n($b)),$b.result()},a.centroid=function(t){return Wm(t,n(n_)),n_.result()},a.projection=function(e){return arguments.length?(n=null==e?(t=null,zb):(t=e).stream,a):t},a.context=function(t){return arguments.length?(r=null==t?(e=null,new w_):new h_(e=t),"function"!=typeof i&&r.pointRadius(i),a):e},a.pointRadius=function(t){return arguments.length?(i="function"==typeof t?t:(r.pointRadius(+t),+t),a):i},a.projection(t).context(e)};function E_(t){return function(e){var n=new S_;for(var r in t)n[r]=t[r];return n.stream=e,n}}function S_(){}function A_(t,e,n){var r=t.clipExtent&&t.clipExtent();return t.scale(150).translate([0,0]),null!=r&&t.clipExtent(null),Wm(n,t.stream($b)),e($b.result()),null!=r&&t.clipExtent(r),t}function C_(t,e,n){return A_(t,function(n){var r=e[1][0]-e[0][0],i=e[1][1]-e[0][1],a=Math.min(r/(n[1][0]-n[0][0]),i/(n[1][1]-n[0][1])),o=+e[0][0]+(r-a*(n[1][0]+n[0][0]))/2,u=+e[0][1]+(i-a*(n[1][1]+n[0][1]))/2;t.scale(150*a).translate([o,u])},n)}function N_(t,e,n){return C_(t,[[0,0],e],n)}function z_(t,e,n){return A_(t,function(n){var r=+e,i=r/(n[1][0]-n[0][0]),a=(r-i*(n[1][0]+n[0][0]))/2,o=-i*n[0][1];t.scale(150*i).translate([a,o])},n)}function O_(t,e,n){return A_(t,function(n){var r=+e,i=r/(n[1][1]-n[0][1]),a=-i*n[0][0],o=(r-i*(n[1][1]+n[0][1]))/2;t.scale(150*i).translate([a,o])},n)}S_.prototype={constructor:S_,point:function(t,e){this.stream.point(t,e)},sphere:function(){this.stream.sphere()},lineStart:function(){this.stream.lineStart()},lineEnd:function(){this.stream.lineEnd()},polygonStart:function(){this.stream.polygonStart()},polygonEnd:function(){this.stream.polygonEnd()}};var D_=16,R_=wm(30*ym),T_=function(t,e){return+e?function(t,e){function n(r,i,a,o,u,s,f,c,l,h,d,p,v,g){var m=f-r,y=c-i,b=m*m+y*y;if(b>4*e&&v--){var _=o+h,x=u+d,w=s+p,M=Nm(_*_+x*x+w*w),k=Dm(w/=M),E=bm(bm(w)-1)e||bm((m*N+y*z)/b-.5)>.3||o*h+u*d+s*p2?t[2]%360*ym:0,C()):[g*mm,m*mm,y*mm]},E.precision=function(t){return arguments.length?(k=T_(A,M=t*t),N()):Nm(M)},E.fitExtent=function(t,e){return C_(E,t,e)},E.fitSize=function(t,e){return N_(E,t,e)},E.fitWidth=function(t,e){return z_(E,t,e)},E.fitHeight=function(t,e){return O_(E,t,e)},function(){return e=t.apply(this,arguments),E.invert=e.invert&&S,C()}}function U_(t){var e=0,n=dm/3,r=q_(t),i=r(e,n);return i.parallels=function(t){return arguments.length?r(e=t[0]*ym,n=t[1]*ym):[e*mm,n*mm]},i}function j_(t,e){var n=Am(t),r=(n+Am(e))/2;if(bm(r)0?e<-pm+hm&&(e=-pm+hm):e>pm-hm&&(e=pm-hm);var n=i/Sm(V_(e),r);return[n*Am(r*t),i-n*wm(r*t)]}return a.invert=function(t,e){var n=i-e,a=Cm(r)*Nm(t*t+n*n);return[xm(t,bm(n))/r*Cm(n),2*_m(Sm(i/a,1/r))-pm]},a}function J_(t,e){return[t,e]}J_.invert=J_;function Z_(t,e){var n=wm(t),r=t===e?Am(t):(n-wm(e))/(e-t),i=n/r+t;if(bm(r)1?(ox[t]=function(t,e){return function n(){var r=e();return r.type=t,r.path=k_().projection(r),r.copy=r.copy||function(){var t=n();return rx.forEach(function(e){r.hasOwnProperty(e)&&t[e](r[e]())}),t.path.pointRadius(r.path.pointRadius()),t},r}}(t,e),this):ox.hasOwnProperty(t)?ox[t]:null}function ax(t){return t&&t.path||nx}var ox={albers:I_,albersusa:function(){var t,e,n,r,i,a,o=I_(),u=F_().rotate([154,0]).center([-2,58.5]).parallels([55,65]),s=F_().rotate([157,0]).center([-3,19.9]).parallels([8,18]),f={point:function(t,e){a=[t,e]}};function c(t){var e=t[0],o=t[1];return a=null,n.point(e,o),a||(r.point(e,o),a)||(i.point(e,o),a)}function l(){return t=e=null,c}return c.invert=function(t){var e=o.scale(),n=o.translate(),r=(t[0]-n[0])/e,i=(t[1]-n[1])/e;return(i>=.12&&i<.234&&r>=-.425&&r<-.214?u:i>=.166&&i<.234&&r>=-.214&&r<-.115?s:o).invert(t)},c.stream=function(n){return t&&e===n?t:(r=[o.stream(e=n),u.stream(n),s.stream(n)],i=r.length,t={point:function(t,e){for(var n=-1;++n2?t[2]+90:90]):[(t=n())[0],t[1],t[2]-90]},n([0,0,90]).scale(159.155)}};for(var ux in ox)ix(ux,ox[ux]);function sx(t){Br.call(this,null,t)}function fx(t){Br.call(this,null,t)}function cx(t){Br.call(this,null,t)}function lx(t){Br.call(this,[],t),this.generator=function(){var t,e,n,r,i,a,o,u,s,f,c,l,h=10,d=h,p=90,v=360,g=2.5;function m(){return{type:"MultiLineString",coordinates:y()}}function y(){return di(Mm(r/p)*p,n,p).map(c).concat(di(Mm(u/v)*v,o,v).map(l)).concat(di(Mm(e/h)*h,t,h).filter(function(t){return bm(t%p)>hm}).map(s)).concat(di(Mm(a/d)*d,i,d).filter(function(t){return bm(t%v)>hm}).map(f))}return m.lines=function(){return y().map(function(t){return{type:"LineString",coordinates:t}})},m.outline=function(){return{type:"Polygon",coordinates:[c(r).concat(l(o).slice(1),c(n).reverse().slice(1),l(u).reverse().slice(1))]}},m.extent=function(t){return arguments.length?m.extentMajor(t).extentMinor(t):m.extentMinor()},m.extentMajor=function(t){return arguments.length?(r=+t[0][0],n=+t[1][0],u=+t[0][1],o=+t[1][1],r>n&&(t=r,r=n,n=t),u>o&&(t=u,u=o,o=t),m.precision(g)):[[r,u],[n,o]]},m.extentMinor=function(n){return arguments.length?(e=+n[0][0],t=+n[1][0],a=+n[0][1],i=+n[1][1],e>t&&(n=e,e=t,t=n),a>i&&(n=a,a=i,i=n),m.precision(g)):[[e,a],[t,i]]},m.step=function(t){return arguments.length?m.stepMajor(t).stepMinor(t):m.stepMinor()},m.stepMajor=function(t){return arguments.length?(p=+t[0],v=+t[1],m):[p,v]},m.stepMinor=function(t){return arguments.length?(h=+t[0],d=+t[1],m):[h,d]},m.precision=function(h){return arguments.length?(g=+h,s=kb(a,i,90),f=Eb(e,t,g),c=kb(u,o,90),l=Eb(r,n,g),m):g},m.extentMajor([[-180,-90+hm],[180,90-hm]]).extentMinor([[-180,-80-hm],[180,80+hm]])}()}function hx(t){Br.call(this,null,t),this.modified(!0)}function dx(t,e,n){j(t[e])&&t[e](n)}sx.Definition={type:"GeoPath",metadata:{modifies:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"path"}]},G(sx,Br).transform=function(t,e){var n=e.fork(e.ALL),r=this.value,i=t.field||v,a=t.as||"path",o=n.SOURCE;!r||t.modified()?(this.value=r=ax(t.projection),n.materialize().reflow()):o=i===v||e.modified(i.fields)?n.ADD_MOD:n.ADD;var u=function(t,e){var n=t.pointRadius();t.context(null),null!=e&&t.pointRadius(e);return n}(r,t.pointRadius);return n.visit(o,function(t){t[a]=r(i(t))}),r.pointRadius(u),n.modifies(a)},fx.Definition={type:"GeoPoint",metadata:{modifies:!0},params:[{name:"projection",type:"projection",required:!0},{name:"fields",type:"field",array:!0,required:!0,length:2},{name:"as",type:"string",array:!0,length:2,default:["x","y"]}]},G(fx,Br).transform=function(t,e){var n,r=t.projection,i=t.fields[0],a=t.fields[1],o=t.as||["x","y"],u=o[0],s=o[1];function f(t){var e=r([i(t),a(t)]);e?(t[u]=e[0],t[s]=e[1]):(t[u]=void 0,t[s]=void 0)}return t.modified()?e=e.materialize().reflow(!0).visit(e.SOURCE,f):(n=e.modified(i.fields)||e.modified(a.fields),e.visit(n?e.ADD_MOD:e.ADD,f)),e.modifies(o)},cx.Definition={type:"GeoShape",metadata:{modifies:!0},params:[{name:"projection",type:"projection"},{name:"field",type:"field",default:"datum"},{name:"pointRadius",type:"number",expr:!0},{name:"as",type:"string",default:"shape"}]},G(cx,Br).transform=function(t,e){var n=e.fork(e.ALL),r=this.value,i=t.field||h("datum"),a=t.as||"shape",o=n.ADD_MOD;return r&&!t.modified()||(this.value=r=function(t,e,n){var r=null==n?function(n){return t(e(n))}:function(r){var i=t.pointRadius(),a=t.pointRadius(n)(e(r));return t.pointRadius(i),a};return r.context=function(e){return t.context(e),r},r}(ax(t.projection),i,t.pointRadius),n.materialize().reflow(),o=n.SOURCE),n.visit(o,function(t){t[a]=r}),n.modifies(a)},lx.Definition={type:"Graticule",metadata:{source:!0,generates:!0,changes:!0},params:[{name:"extent",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMajor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"extentMinor",type:"array",array:!0,length:2,content:{type:"number",array:!0,length:2}},{name:"step",type:"number",array:!0,length:2},{name:"stepMajor",type:"number",array:!0,length:2,default:[90,360]},{name:"stepMinor",type:"number",array:!0,length:2,default:[10,10]},{name:"precision",type:"number",default:2.5}]},G(lx,Br).transform=function(t,e){var n,r=e.fork(),i=this.value,a=this.generator;if(!i.length||t.modified())for(var o in t)j(a[o])&&a[o](t[o]);return n=a(),i.length?r.mod.push(yt(i[0],n)):r.add.push(vt(n)),i[0]=n,r.source=i,r},G(hx,Br).transform=function(t,e){var n=this.value;return!n||t.modified("type")?(this.value=n=function(t){var e=ix((t||"mercator").toLowerCase());e||o("Unrecognized projection type: "+t);return e()}(t.type),rx.forEach(function(e){null!=t[e]&&dx(n,e,t[e])})):rx.forEach(function(e){t.modified(e)&&dx(n,e,t[e])}),null!=t.pointRadius&&n.path.pointRadius(t.pointRadius),t.fit&&function(t,e){var n=(r=e.fit,1===(r=U(r)).length?r[0]:{type:om,features:r.reduce(function(t,e){return e&&e.type===om?t.push.apply(t,e.features):s(e)?t.push.apply(t,e):t.push(e),t},[])});var r;e.extent?t.fitExtent(e.extent,n):e.size&&t.fitSize(e.size,n)}(n,t),e.fork(e.NO_SOURCE|e.NO_FIELDS)};var px=Object.freeze({contour:am,geojson:um,geopath:sx,geopoint:fx,geoshape:cx,graticule:lx,projection:hx}),vx=function(t){return function(){return t}},gx=function(){return 1e-6*(Math.random()-.5)};function mx(t,e,n,r){if(isNaN(e)||isNaN(n))return t;var i,a,o,u,s,f,c,l,h,d=t._root,p={data:r},v=t._x0,g=t._y0,m=t._x1,y=t._y1;if(!d)return t._root=p,t;for(;d.length;)if((f=e>=(a=(v+m)/2))?v=a:m=a,(c=n>=(o=(g+y)/2))?g=o:y=o,i=d,!(d=d[l=c<<1|f]))return i[l]=p,t;if(u=+t._x.call(null,d.data),s=+t._y.call(null,d.data),e===u&&n===s)return p.next=d,i?i[l]=p:t._root=p,t;do{i=i?i[l]=new Array(4):t._root=new Array(4),(f=e>=(a=(v+m)/2))?v=a:m=a,(c=n>=(o=(g+y)/2))?g=o:y=o}while((l=c<<1|f)==(h=(s>=o)<<1|u>=a));return i[h]=d,i[l]=p,t}var yx=function(t,e,n,r,i){this.node=t,this.x0=e,this.y0=n,this.x1=r,this.y1=i};function bx(t){return t[0]}function _x(t){return t[1]}function xx(t,e,n){var r=new wx(null==e?bx:e,null==n?_x:n,NaN,NaN,NaN,NaN);return null==t?r:r.addAll(t)}function wx(t,e,n,r,i,a){this._x=t,this._y=e,this._x0=n,this._y0=r,this._x1=i,this._y1=a,this._root=void 0}function Mx(t){for(var e={data:t.data},n=e;t=t.next;)n=n.next={data:t.data};return e}var kx=xx.prototype=wx.prototype;function Ex(t){return t.x+t.vx}function Sx(t){return t.y+t.vy}kx.copy=function(){var t,e,n=new wx(this._x,this._y,this._x0,this._y0,this._x1,this._y1),r=this._root;if(!r)return n;if(!r.length)return n._root=Mx(r),n;for(t=[{source:r,target:n._root=new Array(4)}];r=t.pop();)for(var i=0;i<4;++i)(e=r.source[i])&&(e.length?t.push({source:e,target:r.target[i]=new Array(4)}):r.target[i]=Mx(e));return n},kx.add=function(t){var e=+this._x.call(null,t),n=+this._y.call(null,t);return mx(this.cover(e,n),e,n,t)},kx.addAll=function(t){var e,n,r,i,a=t.length,o=new Array(a),u=new Array(a),s=1/0,f=1/0,c=-1/0,l=-1/0;for(n=0;nc&&(c=r),il&&(l=i));for(ct||t>i||r>e||e>a))return this;var o,u,s=i-n,f=this._root;switch(u=(e<(r+a)/2)<<1|t<(n+i)/2){case 0:do{(o=new Array(4))[u]=f,f=o}while(a=r+(s*=2),t>(i=n+s)||e>a);break;case 1:do{(o=new Array(4))[u]=f,f=o}while(a=r+(s*=2),(n=i-s)>t||e>a);break;case 2:do{(o=new Array(4))[u]=f,f=o}while(r=a-(s*=2),t>(i=n+s)||r>e);break;case 3:do{(o=new Array(4))[u]=f,f=o}while(r=a-(s*=2),(n=i-s)>t||r>e)}this._root&&this._root.length&&(this._root=f)}return this._x0=n,this._y0=r,this._x1=i,this._y1=a,this},kx.data=function(){var t=[];return this.visit(function(e){if(!e.length)do{t.push(e.data)}while(e=e.next)}),t},kx.extent=function(t){return arguments.length?this.cover(+t[0][0],+t[0][1]).cover(+t[1][0],+t[1][1]):isNaN(this._x0)?void 0:[[this._x0,this._y0],[this._x1,this._y1]]},kx.find=function(t,e,n){var r,i,a,o,u,s,f,c=this._x0,l=this._y0,h=this._x1,d=this._y1,p=[],v=this._root;for(v&&p.push(new yx(v,c,l,h,d)),null==n?n=1/0:(c=t-n,l=e-n,h=t+n,d=e+n,n*=n);s=p.pop();)if(!(!(v=s.node)||(i=s.x0)>h||(a=s.y0)>d||(o=s.x1)=m)<<1|t>=g)&&(s=p[p.length-1],p[p.length-1]=p[p.length-1-f],p[p.length-1-f]=s)}else{var y=t-+this._x.call(null,v.data),b=e-+this._y.call(null,v.data),_=y*y+b*b;if(_=(u=(p+g)/2))?p=u:g=u,(c=o>=(s=(v+m)/2))?v=s:m=s,e=d,!(d=d[l=c<<1|f]))return this;if(!d.length)break;(e[l+1&3]||e[l+2&3]||e[l+3&3])&&(n=e,h=l)}for(;d.data!==t;)if(r=d,!(d=d.next))return this;return(i=d.next)&&delete d.next,r?(i?r.next=i:delete r.next,this):e?(i?e[l]=i:delete e[l],(d=e[0]||e[1]||e[2]||e[3])&&d===(e[3]||e[2]||e[1]||e[0])&&!d.length&&(n?n[h]=d:this._root=d),this):(this._root=i,this)},kx.removeAll=function(t){for(var e=0,n=t.length;e=0&&e._call.call(null,t),e=e._next;--Ox}()}finally{Ox=0,function(){var t,e,n=Nx,r=1/0;for(;n;)n._call?(r>n._time&&(r=n._time),t=n,n=n._next):(e=n._next,n._next=null,n=t?t._next=e:Nx=e);zx=t,Yx(r)}(),Lx=0}}function Hx(){var t=Ux.now(),e=t-Px;e>Tx&&(qx-=e,Px=t)}function Yx(t){Ox||(Dx&&(Dx=clearTimeout(Dx)),t-Lx>24?(t<1/0&&(Dx=setTimeout(Wx,t-Ux.now()-qx)),Rx&&(Rx=clearInterval(Rx))):(Rx||(Px=Ux.now(),Rx=setInterval(Hx,Tx)),Ox=1,jx(Wx)))}function Gx(t){return t.x}function Vx(t){return t.y}$x.prototype=Bx.prototype={constructor:$x,restart:function(t,e,n){if("function"!=typeof t)throw new TypeError("callback is not a function");n=(null==n?Fx():+n)+(null==e?0:+e),this._next||zx===this||(zx?zx._next=this:Nx=this,zx=this),this._call=t,this._time=n,Yx()},stop:function(){this._call&&(this._call=null,this._time=1/0,Yx())}};var Xx=10,Jx=Math.PI*(3-Math.sqrt(5)),Zx=function(t){var e,n=1,r=.001,i=1-Math.pow(r,1/300),a=0,o=.6,u=Tt(),s=Bx(c),f=Bt("tick","end");function c(){l(),f.call("tick",e),n1?(null==n?u.remove(t):u.set(t,d(n)),e):u.get(t)},find:function(e,n,r){var i,a,o,u,s,f=0,c=t.length;for(null==r?r=1/0:r*=r,f=0;f1?(f.on(t,n),e):f.on(t)}}},Qx={center:function(t,e){var n;function r(){var r,i,a=n.length,o=0,u=0;for(r=0;rs+d||if+d||au.index){var p=s-o.x-o.vx,v=f-o.y-o.vy,g=p*p+v*v;gt.r&&(t.r=t[e].r)}function u(){if(e){var r,i,a=e.length;for(n=new Array(a),r=0;r=o)){(t.data!==e||t.next)&&(0===c&&(d+=(c=gx())*c),0===l&&(d+=(l=gx())*l),d=0;)i.tick();else if(i.stopped()&&i.restart(),!a)return e.StopPropagation;return this.finish(t,e)},iw.finish=function(t,e){for(var n,r=e.dataflow,i=this._argops,a=0,o=i.length;a=0;)e+=n[r].value;else e=1;t.value=e}function pw(t,e){var n,r,i,a,o,u=new yw(t),s=+t.value&&(u.value=t.value),f=[u];for(null==e&&(e=vw);n=f.pop();)if(s&&(n.value=+n.data.value),(i=e(n.data))&&(o=i.length))for(n.children=new Array(o),a=o-1;a>=0;--a)f.push(r=n.children[a]=new yw(i[a])),r.parent=n,r.depth=n.depth+1;return u.eachBefore(mw)}function vw(t){return t.children}function gw(t){t.data=t.data.data}function mw(t){var e=0;do{t.height=e}while((t=t.parent)&&t.height<++e)}function yw(t){this.data=t,this.depth=this.height=0,this.parent=null}yw.prototype=pw.prototype={constructor:yw,count:function(){return this.eachAfter(dw)},each:function(t){var e,n,r,i,a=this,o=[a];do{for(e=o.reverse(),o=[];a=e.pop();)if(t(a),n=a.children)for(r=0,i=n.length;r=0;--n)i.push(e[n]);return this},sum:function(t){return this.eachAfter(function(e){for(var n=+t(e.data)||0,r=e.children,i=r&&r.length;--i>=0;)n+=r[i].value;e.value=n})},sort:function(t){return this.eachBefore(function(e){e.children&&e.children.sort(t)})},path:function(t){for(var e=this,n=function(t,e){if(t===e)return t;var n=t.ancestors(),r=e.ancestors(),i=null;for(t=n.pop(),e=r.pop();t===e;)i=t,t=n.pop(),e=r.pop();return i}(e,t),r=[e];e!==n;)e=e.parent,r.push(e);for(var i=r.length;t!==n;)r.splice(i,0,t),t=t.parent;return r},ancestors:function(){for(var t=this,e=[t];t=t.parent;)e.push(t);return e},descendants:function(){var t=[];return this.each(function(e){t.push(e)}),t},leaves:function(){var t=[];return this.eachBefore(function(e){e.children||t.push(e)}),t},links:function(){var t=this,e=[];return t.each(function(n){n!==t&&e.push({source:n.parent,target:n})}),e},copy:function(){return pw(this).eachBefore(gw)}};var bw=Array.prototype.slice;var _w=function(t){for(var e,n,r=0,i=(t=function(t){for(var e,n,r=t.length;r;)n=Math.random()*r--|0,e=t[r],t[r]=t[n],t[n]=e;return t}(bw.call(t))).length,a=[];r0&&n*n>r*r+i*i}function kw(t,e){for(var n=0;nn*n+r*r}function zw(t){var e=t._,n=t.next._,r=e.r+n.r,i=(e.x*n.r+n.x*e.r)/r,a=(e.y*n.r+n.y*e.r)/r;return i*i+a*a}function Ow(t){this._=t,this.next=null,this.previous=null}function Dw(t){if("function"!=typeof t)throw new Error;return t}function Rw(){return 0}var Tw=function(t){return function(){return t}};function Pw(t){return Math.sqrt(t.value)}function Lw(t){return function(e){e.children||(e.r=Math.max(0,+t(e)||0))}}function qw(t,e){return function(n){if(r=n.children){var r,i,a,o=r.length,u=t(n)*e||0;if(u)for(i=0;i1))return e.r;if(n=t[1],e.x=-n.r,n.x=e.r,n.y=0,!(i>2))return e.r+n.r;Cw(n,e,r=t[2]),e=new Ow(e),n=new Ow(n),r=new Ow(r),e.next=r.previous=n,n.next=e.previous=r,r.next=n.previous=e;t:for(u=3;uh&&(h=u),g=c*c*v,(d=Math.max(h/g,g/l))>p){c-=u;break}p=d}m.push(o={value:c,dice:s1?e:1)},n}(Kw),nM=function t(e){function n(t,n,r,i,a){if((o=t._squarify)&&o.ratio===e)for(var o,u,s,f,c,l=-1,h=o.length,d=t.value;++l1?e:1)},n}(Kw);function rM(t){Br.call(this,null,t)}function iM(t){return t.values}function aM(t){Br.call(this,null,t)}rM.Definition={type:"Nest",metadata:{treesource:!0,generates:!0},params:[{name:"keys",type:"field",array:!0},{name:"key",type:"field"},{name:"generate",type:"boolean"}]},G(rM,Br).transform=function(t,e){e.source||o("Nest transform requires an upstream data source.");var n,r,i,a=t.key||dt,u=t.generate,s=t.modified(),f=u||s?e.fork(e.ALL):e;return(!this.value||s||e.changed())&&(u&&this.value&&(f.materialize(f.REM),this.value.each(function(t){t.children&&f.rem.push(t)})),n=U(t.keys).reduce(function(t,e){return t.key(e),t},Pt()).entries(f.materialize(f.SOURCE).source),this.value=r=pw({values:n},iM),u&&(f.materialize(f.ADD),f.source=f.source.slice(),r.each(function(t){t.children&&(t=vt(t.data),f.add.push(t),f.source.push(t))})),i=r.lookup={},r.each(function(t){null!=dt(t.data)&&(i[a(t.data)]=t)})),f.source.root=this.value,f},G(aM,Br).transform=function(t,e){e.source&&e.source.root||o(this.constructor.name+" transform requires a backing tree data source.");var n=this.layout(t.method),r=this.fields,i=e.source.root,a=t.as||r;t.field&&i.sum(t.field),t.sort&&i.sort(t.sort),function(t,e,n){for(var r,i=0,a=e.length;i0)throw new Error("cycle");return a}return n.id=function(e){return arguments.length?(t=Dw(e),n):t},n.parentId=function(t){return arguments.length?(e=Dw(t),n):e},n}().id(t.key).parentId(t.parentKey)(e.source),r=n.lookup={},n.each(function(e){r[t.key(e.data)]=e}),this.value=n),e.source.root=this.value,i?e.fork(e.ALL):e};var dM={tidy:function(){var t=Yw,e=1,n=1,r=null;function i(i){var s=function(t){for(var e,n,r,i,a,o=new Zw(t,0),u=[o];e=u.pop();)if(r=e._.children)for(e.children=new Array(a=r.length),i=a-1;i>=0;--i)u.push(n=e.children[i]=new Zw(r[i],i)),n.parent=e;return(o.parent=new Zw(null,0)).children=[o],o}(i);if(s.eachAfter(a),s.parent.m=-s.z,s.eachBefore(o),r)i.eachBefore(u);else{var f=i,c=i,l=i;i.eachBefore(function(t){t.xc.x&&(c=t),t.depth>l.depth&&(l=t)});var h=f===c?1:t(f,c)/2,d=h-f.x,p=e/(c.x+h+d),v=n/(l.depth||1);i.eachBefore(function(t){t.x=(t.x+d)*p,t.y=t.depth*v})}return i}function a(e){var n=e.children,r=e.parent.children,i=e.i?r[e.i-1]:null;if(n){!function(t){for(var e,n=0,r=0,i=t.children,a=i.length;--a>=0;)(e=i[a]).z+=n,e.m+=n,n+=e.s+(r+=e.c)}(e);var a=(n[0].z+n[n.length-1].z)/2;i?(e.z=i.z+t(e._,i._),e.m=e.z-a):e.z=a}else i&&(e.z=i.z+t(e._,i._));e.parent.A=function(e,n,r){if(n){for(var i,a=e,o=e,u=n,s=a.parent.children[0],f=a.m,c=o.m,l=u.m,h=s.m;u=Vw(u),a=Gw(a),u&&a;)s=Gw(s),(o=Vw(o)).a=e,(i=u.z+l-a.z-f+t(u._,a._))>0&&(Xw(Jw(u,e,r),e,i),f+=i,c+=i),l+=u.m,f+=a.m,h+=s.m,c+=o.m;u&&!Vw(o)&&(o.t=u,o.m+=l-c),a&&!Gw(s)&&(s.t=a,s.m+=f-h,r=e)}return r}(e,i,e.parent.A||r[0])}function o(t){t._.x=t.z+t.parent.m,t.m+=t.parent.m}function u(t){t.x*=e,t.y=t.depth*n}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i},cluster:function(){var t=cw,e=1,n=1,r=!1;function i(i){var a,o=0;i.eachAfter(function(e){var n=e.children;n?(e.x=function(t){return t.reduce(lw,0)/t.length}(n),e.y=function(t){return 1+t.reduce(hw,0)}(n)):(e.x=a?o+=t(e,a):0,e.y=0,a=e)});var u=function(t){for(var e;e=t.children;)t=e[0];return t}(i),s=function(t){for(var e;e=t.children;)t=e[e.length-1];return t}(i),f=u.x-t(u,s)/2,c=s.x+t(s,u)/2;return i.eachAfter(r?function(t){t.x=(t.x-i.x)*e,t.y=(i.y-t.y)*n}:function(t){t.x=(t.x-f)/(c-f)*e,t.y=(1-(i.y?t.y/i.y:1))*n})}return i.separation=function(e){return arguments.length?(t=e,i):t},i.size=function(t){return arguments.length?(r=!1,e=+t[0],n=+t[1],i):r?null:[e,n]},i.nodeSize=function(t){return arguments.length?(r=!0,e=+t[0],n=+t[1],i):r?[e,n]:null},i}},pM=["x","y","depth","children"];function vM(t){aM.call(this,t)}vM.Definition={type:"Tree",metadata:{tree:!0,modifies:!0},params:[{name:"field",type:"field"},{name:"sort",type:"compare"},{name:"method",type:"enum",default:"tidy",values:["tidy","cluster"]},{name:"size",type:"number",array:!0,length:2},{name:"nodeSize",type:"number",array:!0,length:2},{name:"as",type:"string",array:!0,length:4,default:pM}]};var gM=G(vM,aM);function mM(t){Br.call(this,{},t)}gM.layout=function(t){var e=t||"tidy";if(dM.hasOwnProperty(e))return dM[e]();o("Unrecognized Tree layout method: "+e)},gM.params=["size","nodeSize","separation"],gM.fields=pM,mM.Definition={type:"TreeLinks",metadata:{tree:!0,generates:!0,changes:!0},params:[{name:"key",type:"field"}]},G(mM,Br).transform=function(t,e){e.source&&e.source.root||o("TreeLinks transform requires a backing tree data source.");var n=e.source.root.lookup,r=this.value,i=t.key||dt,a={},u=e.fork();function s(t){var e=r[t];e&&(a[t]=1,u.mod.push(e))}return e.visit(e.REM,function(t){var e=i(t),n=r[e];n&&(delete r[e],u.rem.push(n))}),e.visit(e.ADD,function(t){var e,o=i(t);(e=function(t){var e;return t.parent&&(e=t.parent.data)&&null!=dt(e)&&e}(n[o]))&&(u.add.push(r[o]=vt({source:e,target:t})),a[o]=1)}),e.visit(e.MOD,function(t){var e=i(t),r=n[e].children;if(s(e),r)for(var o=0,u=r.length;o=n-1){var c=u[e];return c.x0=i,c.y0=a,c.x1=o,void(c.y1=s)}for(var l=f[e],h=r/2+l,d=e+1,p=n-1;d>>1;f[v]s-a){var y=(i*m+o*g)/r;t(e,d,g,i,a,y,s),t(d,n,m,y,a,o,s)}else{var b=(a*m+s*g)/r;t(e,d,g,i,a,o,b),t(d,n,m,i,b,o,s)}}(0,s,t.value,e,n,r,i)},dice:Fw,slice:Qw,slicedice:function(t,e,n,r,i){(1&t.depth?Qw:Fw)(t,e,n,r,i)},squarify:eM,resquarify:nM},bM=["x0","y0","x1","y1","depth","children"];function _M(t){aM.call(this,t)}_M.Definition={type:"Treemap",metadata:{tree:!0,modifies:!0},params:[{name:"field",type:"field"},{name:"sort",type:"compare"},{name:"method",type:"enum",default:"squarify",values:["squarify","resquarify","binary","dice","slice","slicedice"]},{name:"padding",type:"number",default:0},{name:"paddingInner",type:"number",default:0},{name:"paddingOuter",type:"number",default:0},{name:"paddingTop",type:"number",default:0},{name:"paddingRight",type:"number",default:0},{name:"paddingBottom",type:"number",default:0},{name:"paddingLeft",type:"number",default:0},{name:"ratio",type:"number",default:1.618033988749895},{name:"round",type:"boolean",default:!1},{name:"size",type:"number",array:!0,length:2},{name:"as",type:"string",array:!0,length:4,default:bM}]};var xM=G(_M,aM);xM.layout=function(){var t=function(){var t=eM,e=!1,n=1,r=1,i=[0],a=Rw,o=Rw,u=Rw,s=Rw,f=Rw;function c(t){return t.x0=t.y0=0,t.x1=n,t.y1=r,t.eachBefore(l),i=[0],e&&t.eachBefore(jw),t}function l(e){var n=i[e.depth],r=e.x0+n,c=e.y0+n,l=e.x1-n,h=e.y1-n;l0)){if(a/=h,h<0){if(a0){if(a>l)return;a>c&&(c=a)}if(a=r-s,h||!(a<0)){if(a/=h,h<0){if(a>l)return;a>c&&(c=a)}else if(h>0){if(a0)){if(a/=d,d<0){if(a0){if(a>l)return;a>c&&(c=a)}if(a=i-f,d||!(a<0)){if(a/=d,d<0){if(a>l)return;a>c&&(c=a)}else if(d>0){if(a0||l<1)||(c>0&&(t[0]=[s+c*h,f+c*d]),l<1&&(t[1]=[s+l*h,f+l*d]),!0)}}}}}function PM(t,e,n,r,i){var a=t[1];if(a)return!0;var o,u,s=t[0],f=t.left,c=t.right,l=f[0],h=f[1],d=c[0],p=c[1],v=(l+d)/2,g=(h+p)/2;if(p===h){if(v=r)return;if(l>d){if(s){if(s[1]>=i)return}else s=[v,n];a=[v,i]}else{if(s){if(s[1]1)if(l>d){if(s){if(s[1]>=i)return}else s=[(n-u)/o,n];a=[(i-u)/o,i]}else{if(s){if(s[1]=r)return}else s=[e,o*e+u];a=[r,o*r+u]}else{if(s){if(s[0]=-ek)){var d=s*s+f*f,p=c*c+l*l,v=(l*d-f*p)/h,g=(s*p-c*d)/h,m=FM.pop()||new function(){AM(this),this.x=this.y=this.arc=this.site=this.cy=null};m.arc=t,m.site=i,m.x=v+o,m.y=(m.cy=g+u)+Math.sqrt(v*v+g*g),t.circle=m;for(var y=null,b=QM._;b;)if(m.ytk)u=u.L;else{if(!((i=a-XM(u,o))>tk)){r>-tk?(e=u.P,n=u):i>-tk?(e=u,n=u.N):e=n=u;break}if(!u.R){e=u;break}u=u.R}!function(t){ZM[t.index]={site:t,halfedges:[]}}(t);var s=WM(t);if(JM.insert(e,s),e||n){if(e===n)return $M(e),n=WM(e.site),JM.insert(s,n),s.edge=n.edge=OM(e.site,s.site),IM(e),void IM(n);if(n){$M(e),$M(n);var f=e.site,c=f[0],l=f[1],h=t[0]-c,d=t[1]-l,p=n.site,v=p[0]-c,g=p[1]-l,m=2*(h*g-d*v),y=h*h+d*d,b=v*v+g*g,_=[(g*y-d*b)/m+c,(h*b-v*y)/m+l];RM(n.edge,f,p,_),s.edge=OM(f,t,null,_),n.edge=OM(t,p,null,_),IM(e),IM(n)}else s.edge=OM(e.site,s.site)}}function VM(t,e){var n=t.site,r=n[0],i=n[1],a=i-e;if(!a)return r;var o=t.P;if(!o)return-1/0;var u=(n=o.site)[0],s=n[1],f=s-e;if(!f)return u;var c=u-r,l=1/a-1/f,h=c/f;return l?(-h+Math.sqrt(h*h-2*l*(c*c/(-2*f)-s+f/2+i-a/2)))/l+r:(r+u)/2}function XM(t,e){var n=t.N;if(n)return VM(n,e);var r=t.site;return r[1]===e?r[0]:1/0}var JM,ZM,QM,KM,tk=1e-6,ek=1e-12;function nk(t,e){return e[1]-t[1]||e[0]-t[0]}function rk(t,e){var n,r,i,a=t.sort(nk).pop();for(KM=[],ZM=new Array(t.length),JM=new SM,QM=new SM;;)if(i=jM,a&&(!i||a[1]tk||Math.abs(i[0][1]-i[1][1])>tk)||delete KM[a]}(o,u,s,f),function(t,e,n,r){var i,a,o,u,s,f,c,l,h,d,p,v,g=ZM.length,m=!0;for(i=0;itk||Math.abs(v-h)>tk)&&(s.splice(u,0,KM.push(DM(o,d,Math.abs(p-t)tk?[t,Math.abs(l-t)tk?[Math.abs(h-r)tk?[n,Math.abs(l-n)tk?[Math.abs(h-e)=u)return null;var s=t-i.site[0],f=e-i.site[1],c=s*s+f*f;do{i=a.cells[r=o],o=null,i.halfedges.forEach(function(n){var r=a.edges[n],u=r.left;if(u!==i.site&&u||(u=r.right)){var s=t-u[0],f=e-u[1],l=s*s+f*f;l=d));)if(e.x=l+i,e.y=h+a,!(e.x+e.x0<0||e.y+e.y0<0||e.x+e.x1>u[0]||e.y+e.y1>u[1]||n&&hk(e,t,u[0])||n&&(f=n,!((o=e).x+o.x1>f[0].x&&o.x+o.x0f[0].y&&o.y+o.y0>5,_=u[0]>>5,x=e.x-(b<<4),w=127&x,M=32-w,k=e.y1-e.y0,E=(e.y+e.y0)*_+(x>>5),S=0;S>>w:0);E+=_}return e.sprite=null,!0}return!1}return l.layout=function(){for(var s=function(t){t.width=t.height=1;var e=Math.sqrt(t.getContext("2d").getImageData(0,0,1,1).data.length>>2);t.width=(sk<<5)/e,t.height=fk/e;var n=t.getContext("2d");return n.fillStyle=n.strokeStyle="red",n.textAlign="center",{context:n,ratio:e}}(Za()),l=function(t){var e=[],n=-1;for(;++n>5)*u[1]),d=null,p=f.length,v=-1,g=[],m=f.map(function(u){return{text:t(u),font:e(u),style:r(u),weight:i(u),rotate:a(u),size:~~n(u),padding:o(u),xoff:0,yoff:0,x1:0,y1:0,x0:0,y0:0,hasText:!1,sprite:null,datum:u}}).sort(function(t,e){return e.size-t.size});++v>1,y.y=u[1]*(c()+.5)>>1,lk(s,y,m,v),y.hasText&&h(l,y,d)&&(g.push(y),d?dk(d,y):d=[{x:y.x+y.x0,y:y.y+y.y0},{x:y.x+y.x1,y:y.y+y.y1}],y.x-=u[0]>>1,y.y-=u[1]>>1)}return g},l.words=function(t){return arguments.length?(f=t,l):f},l.size=function(t){return arguments.length?(u=[+t[0],+t[1]],l):u},l.font=function(t){return arguments.length?(e=vk(t),l):e},l.fontStyle=function(t){return arguments.length?(r=vk(t),l):r},l.fontWeight=function(t){return arguments.length?(i=vk(t),l):i},l.rotate=function(t){return arguments.length?(a=vk(t),l):a},l.text=function(e){return arguments.length?(t=vk(e),l):t},l.spiral=function(t){return arguments.length?(s=gk[t]||t,l):s},l.fontSize=function(t){return arguments.length?(n=vk(t),l):n},l.padding=function(t){return arguments.length?(o=vk(t),l):o},l.random=function(t){return arguments.length?(c=t,l):c},l};function lk(t,e,n,r){if(!e.sprite){var i=t.context,a=t.ratio;i.clearRect(0,0,(sk<<5)/a,fk/a);var o,u,s,f,c,l=0,h=0,d=0,p=n.length;for(--r;++r>5<<5,s=~~Math.max(Math.abs(y+b),Math.abs(y-b))}else o=o+31>>5<<5;if(s>d&&(d=s),l+o>=sk<<5&&(l=0,h+=d,d=0),h+s>=fk)break;i.translate((l+(o>>1))/a,(h+(s>>1))/a),e.rotate&&i.rotate(e.rotate*uk),i.fillText(e.text,0,0),e.padding&&(i.lineWidth=2*e.padding,i.strokeText(e.text,0,0)),i.restore(),e.width=o,e.height=s,e.xoff=l,e.yoff=h,e.x1=o>>1,e.y1=s>>1,e.x0=-e.x1,e.y0=-e.y1,e.hasText=!0,l+=o}for(var x=i.getImageData(0,0,(sk<<5)/a,fk/a).data,w=[];--r>=0;)if((e=n[r]).hasText){for(u=(o=e.width)>>5,s=e.y1-e.y0,f=0;f>5),S=x[(h+c)*(sk<<5)+(l+f)<<2]?1<<31-f%32:0;w[E]|=S,M|=S}M?k=c:(e.y0++,s--,c--,h++)}e.y1=e.y0+k,e.sprite=w.slice(0,(e.y1-e.y0)*u)}}}function hk(t,e,n){n>>=5;for(var r,i=t.sprite,a=t.width>>5,o=t.x-(a<<4),u=127&o,s=32-u,f=t.y1-t.y0,c=(t.y+t.y0)*n+(o>>5),l=0;l>>u:0))&e[c+h])return!0;c+=n}return!1}function dk(t,e){var n=t[0],r=t[1];e.x+e.x0r.x&&(r.x=e.x+e.x1),e.y+e.y1>r.y&&(r.y=e.y+e.y1)}function pk(t){var e=t[0]/t[1];return function(t){return[e*(t*=.1)*Math.cos(t),t*Math.sin(t)]}}function vk(t){return"function"==typeof t?t:function(){return t}}var gk={archimedean:pk,rectangular:function(t){var e=4*t[0]/t[1],n=0,r=0;return function(t){var i=t<0?-1:1;switch(Math.sqrt(1+4*i*t)-i&3){case 0:n+=e;break;case 1:r+=4;break;case 2:n-=e;break;default:r-=4}return[n,r]}}},mk=["x","y","font","fontSize","fontStyle","fontWeight","angle"],yk=["text","font","rotate","fontSize","fontStyle","fontWeight"];function bk(t){Br.call(this,ck(),t)}bk.Definition={type:"Wordcloud",metadata:{modifies:!0},params:[{name:"size",type:"number",array:!0,length:2},{name:"font",type:"string",expr:!0,default:"sans-serif"},{name:"fontStyle",type:"string",expr:!0,default:"normal"},{name:"fontWeight",type:"string",expr:!0,default:"normal"},{name:"fontSize",type:"number",expr:!0,default:14},{name:"fontSizeRange",type:"number",array:"nullable",default:[10,50]},{name:"rotate",type:"number",expr:!0,default:0},{name:"text",type:"field"},{name:"spiral",type:"string",values:["archimedean","rectangular"]},{name:"padding",type:"number",expr:!0},{name:"as",type:"string",array:!0,length:7,default:mk}]},G(bk,Br).transform=function(t,n){var r=t.modified();if(r||n.changed(n.ADD_REM)||yk.some(function(e){var r=t[e];return j(r)&&n.modified(r.fields)})){var i,a=n.materialize(n.SOURCE).source,o=this.value,u=t.as||mk,s=t.fontSize||14;if(j(s)?i=t.fontSizeRange:s=I(s),i){var f=s,c=mp("sqrt")().domain(function(t,e){for(var n,r=1/0,i=-1/0,a=0,o=e.length;ai&&(i=n);return[r,i]}(f,a)).range(i);s=function(t){return c(f(t))}}a.forEach(function(t){t[u[0]]=NaN,t[u[1]]=NaN,t[u[3]]=0});for(var l,h,d=o.words(a).text(t.text).size(t.size||[500,500]).padding(t.padding||1).spiral(t.spiral||"archimedean").rotate(t.rotate||0).font(t.font||"sans-serif").fontStyle(t.fontStyle||"normal").fontWeight(t.fontWeight||"normal").fontSize(s).random(e.random).layout(),p=o.size(),v=p[0]>>1,g=p[1]>>1,m=0,y=d.length;mi?1:0}),ki(t,e)}(l,h),f)o=e,u=t,e=Array(f+c),t=xk(f+c),function(t,e,n,r,i,a,o,u,s){var f,c=0,l=0;for(f=0;c0)for(s=0;s=e?t:((i=i||new t.constructor(e)).set(t),i);var t,e,i},add:function(t){for(var e,r=0,i=n.length,a=t.length;ri.length||n>e)&&(e=Math.max(n,e),i=wk(t,e,i),a=wk(t,e))}}),t),this._indices=null,this._dims=null}Ek.Definition={type:"CrossFilter",metadata:{},params:[{name:"fields",type:"field",array:!0,required:!0},{name:"query",type:"array",array:!0,required:!0,content:{type:"number",array:!0,length:2}}]};var Sk=G(Ek,Br);function Ak(t){Br.call(this,null,t)}Sk.transform=function(t,e){return this._dims?t.modified("fields")||t.fields.some(function(t){return e.modified(t.fields)})?this.reinit(t,e):this.eval(t,e):this.init(t,e)},Sk.init=function(t,e){for(var n,r,i=t.fields,a=t.query,o=this._indices={},u=this._dims=[],s=a.length,f=0;fg)for(i=g,a=Math.min(p,m);im)for(i=Math.max(p,m),a=v;id)for(i=d,a=Math.min(l,p);ip)for(i=Math.max(l,p),a=h;i=48&&t<=57}function VE(t){return"0123456789abcdefABCDEF".indexOf(t)>=0}function XE(t){return"01234567".indexOf(t)>=0}function JE(t){return 32===t||9===t||11===t||12===t||160===t||t>=5760&&[5760,6158,8192,8193,8194,8195,8196,8197,8198,8199,8200,8201,8202,8239,8287,12288,65279].indexOf(t)>=0}function ZE(t){return 10===t||13===t||8232===t||8233===t}function QE(t){return 36===t||95===t||t>=65&&t<=90||t>=97&&t<=122||92===t||t>=128&&WE.test(String.fromCharCode(t))}function KE(t){return 36===t||95===t||t>=65&&t<=90||t>=97&&t<=122||t>=48&&t<=57||92===t||t>=128&&HE.test(String.fromCharCode(t))}var tS={if:1,in:1,do:1,var:1,for:1,new:1,try:1,let:1,this:1,else:1,case:1,void:1,with:1,enum:1,while:1,break:1,catch:1,throw:1,const:1,yield:1,class:1,super:1,return:1,typeof:1,delete:1,switch:1,export:1,import:1,public:1,static:1,default:1,finally:1,extends:1,package:1,private:1,function:1,continue:1,debugger:1,interface:1,protected:1,instanceof:1,implements:1};function eS(){for(var t;sE1114111||"}"!==t)&&yS({},DE,$E),e<=65535?String.fromCharCode(e):(n=55296+(e-65536>>10),r=56320+(e-65536&1023),String.fromCharCode(n,r))}function iS(){var t,e;for(t=uE.charCodeAt(sE++),e=String.fromCharCode(t),92===t&&(117!==uE.charCodeAt(sE)&&yS({},DE,$E),++sE,(t=nS("u"))&&"\\"!==t&&QE(t.charCodeAt(0))||yS({},DE,$E),e=t);sE>>="===(r=uE.substr(sE,4))?{type:bE,value:r,start:i,end:sE+=4}:">>>"===(n=r.substr(0,3))||"<<="===n||">>="===n?{type:bE,value:n,start:i,end:sE+=3}:o===(e=n.substr(0,2))[1]&&"+-<>&|".indexOf(o)>=0||"=>"===e?{type:bE,value:e,start:i,end:sE+=2}:"<>=!+-*%&|^/".indexOf(o)>=0?{type:bE,value:o,start:i,end:++sE}:void yS({},DE,$E)}function uS(){var t,e,n;if(YE(GE((n=uE[sE]).charCodeAt(0))||"."===n,"Numeric literal must start with a decimal digit or a decimal point"),e=sE,t="","."!==n){if(t=uE[sE++],n=uE[sE],"0"===t){if("x"===n||"X"===n)return++sE,function(t){for(var e="";sE=0&&yS({},UE,n),{value:n,literal:e}}(),r=function(t,e){var n=t;e.indexOf("u")>=0&&(n=n.replace(/\\u\{([0-9a-fA-F]+)\}/g,function(t,e){if(parseInt(e,16)<=1114111)return"x";yS({},UE)}).replace(/[\uD800-\uDBFF][\uDC00-\uDFFF]/g,"x"));try{new RegExp(n)}catch(t){yS({},UE)}try{return new RegExp(t,e)}catch(t){return null}}(e.value,n.value),{literal:e.literal+n.literal,value:r,regex:{pattern:e.value,flags:n.value},start:t,end:sE}}function fS(){var t;return eS(),sE>=fE?{type:pE,start:sE,end:sE}:QE(t=uE.charCodeAt(sE))?aS():40===t||41===t||59===t?oS():39===t||34===t?function(){var t,e,n,r,i="",a=!1;for(YE("'"===(t=uE[sE])||'"'===t,"String literal must starts with a quote"),e=sE,++sE;sE=0&&sE":case"<=":case">=":case"instanceof":case"in":e=7;break;case"<<":case">>":case">>>":e=8;break;case"+":case"-":e=9;break;case"*":case"/":case"%":e=11}return e}function PS(){var t,e;return t=function(){var t,e,n,r,i,a,o,u,s,f;if(t=cE,s=RS(),0===(i=TS(r=cE)))return s;for(r.prec=i,cS(),e=[t,cE],a=[s,r,o=RS()];(i=TS(cE))>0;){for(;a.length>2&&i<=a[a.length-2].prec;)o=a.pop(),u=a.pop().value,s=a.pop(),e.pop(),n=hS(u,s,o),a.push(n);(r=cS()).prec=i,a.push(r),e.push(cE),n=RS(),a.push(n)}for(n=a[f=a.length-1],e.pop();f>1;)e.pop(),n=hS(a[f-1].value,a[f-2],n),f-=2;return n}(),xS("?")&&(cS(),e=PS(),_S(":"),t=function(t,e,n){var r=new hE(kE);return r.test=t,r.consequent=e,r.alternate=n,r}(t,e,PS())),t}function LS(){var t=PS();if(xS(","))throw new Error(BE);return t}var qS={NaN:"NaN",E:"Math.E",LN2:"Math.LN2",LN10:"Math.LN10",LOG2E:"Math.LOG2E",LOG10E:"Math.LOG10E",PI:"Math.PI",SQRT1_2:"Math.SQRT1_2",SQRT2:"Math.SQRT2",MIN_VALUE:"Number.MIN_VALUE",MAX_VALUE:"Number.MAX_VALUE"},US=function(t){function e(e,n,r){return function(i){return function(e,n,r,i){var a=t(n[0]);return r&&(a=r+"("+a+")",0===r.lastIndexOf("new ",0)&&(a="("+a+")")),a+"."+e+(i<0?"":0===i?"()":"("+n.slice(1).map(t).join(",")+")")}(e,i,n,r)}}var n="new Date";return{isNaN:"isNaN",isFinite:"isFinite",abs:"Math.abs",acos:"Math.acos",asin:"Math.asin",atan:"Math.atan",atan2:"Math.atan2",ceil:"Math.ceil",cos:"Math.cos",exp:"Math.exp",floor:"Math.floor",log:"Math.log",max:"Math.max",min:"Math.min",pow:"Math.pow",random:"Math.random",round:"Math.round",sin:"Math.sin",sqrt:"Math.sqrt",tan:"Math.tan",clamp:function(e){e.length<3&&o("Missing arguments to clamp function."),e.length>3&&o("Too many arguments to clamp function.");var n=e.map(t);return"Math.max("+n[1]+", Math.min("+n[2]+","+n[0]+"))"},now:"Date.now",utc:"Date.UTC",datetime:n,date:e("getDate",n,0),day:e("getDay",n,0),year:e("getFullYear",n,0),month:e("getMonth",n,0),hours:e("getHours",n,0),minutes:e("getMinutes",n,0),seconds:e("getSeconds",n,0),milliseconds:e("getMilliseconds",n,0),time:e("getTime",n,0),timezoneoffset:e("getTimezoneOffset",n,0),utcdate:e("getUTCDate",n,0),utcday:e("getUTCDay",n,0),utcyear:e("getUTCFullYear",n,0),utcmonth:e("getUTCMonth",n,0),utchours:e("getUTCHours",n,0),utcminutes:e("getUTCMinutes",n,0),utcseconds:e("getUTCSeconds",n,0),utcmilliseconds:e("getUTCMilliseconds",n,0),length:e("length",null,-1),indexof:e("indexOf",null),lastindexof:e("lastIndexOf",null),slice:e("slice",null),parseFloat:"parseFloat",parseInt:"parseInt",upper:e("toUpperCase","String",0),lower:e("toLowerCase","String",0),substring:e("substring","String"),replace:e("replace","String"),regexp:"RegExp",test:e("test","RegExp"),if:function(e){e.length<3&&o("Missing arguments to if function."),e.length>3&&o("Too many arguments to if function.");var n=e.map(t);return"("+n[0]+"?"+n[1]+":"+n[2]+")"}}},jS={};function FS(t,e,n){var r=t+":"+n,i=jS[r];return i&&i[0]===e||(jS[r]=i=[e,e(n)]),i[1]}function IS(t,e){return FS("timeFormat",un,e)(t)}var $S=new Date(2e3,0,1);function BS(t,e,n){return $S.setMonth(t),$S.setDate(e),IS($S,n)}function WS(t,e,n){try{t[e].apply(t,["EXPRESSION"].concat([].slice.call(n)))}catch(e){t.warn(e)}return n[n.length-1]}var HS="undefined"!=typeof window&&window||null;var YS="Literal",GS="Identifier",VS="@",XS="%",JS=":";function ZS(t,e){var n;return j(t)?t:c(t)?(n=e.scales[t])&&n.value:void 0}function QS(t,e,n){var r=XS+n;if(!e.hasOwnProperty(r))try{e[r]=t.scaleRef(n)}catch(t){}}function KS(t,e,n,r){if(e[0].type===YS)QS(n,r,e[0].value);else if(e[0].type===GS)for(t in n.scales)QS(n,r,t)}function tA(t,e){return function(n,r,i){if(n){var a=ZS(n,(i||this).context);return a&&a.path[t](r)}return e(r)}}var eA=tA("area",function(t){return Ym.reset(),Wm(t,Gm),2*Ym}),nA=tA("bounds",function(t){var e,n,r,i,a,o,u;if(ey=ty=-(Qm=Km=1/0),dy=[],Wm(t,gy),n=dy.length){for(dy.sort(Ey),e=1,a=[r=dy[0]];eky(r[0],r[1])&&(r[1]=i[1]),ky(i[0],r[1])>ky(r[0],r[1])&&(r[0]=i[0])):a.push(r=i);for(o=-1/0,e=0,r=a[n=a.length-1];e<=n;r=i,++e)i=a[e],(u=ky(r[1],i[0]))>o&&(o=u,Qm=i[0],ty=r[1])}return dy=py=null,Qm===1/0||Km===1/0?[[NaN,NaN],[NaN,NaN]]:[[Qm,Km],[ty,ey]]}),rA=tA("centroid",function(t){Ay=Cy=Ny=zy=Oy=Dy=Ry=Ty=Py=Ly=qy=0,Wm(t,By);var e=Py,n=Ly,r=qy,i=e*e+n*n+r*r;return i<1e-12&&(e=Dy,n=Ry,r=Ty,Cyo&&(i=a,a=o,o=i),n=void 0===n||n,r=void 0===r||r,(n?a<=t:a=2&&e[e.length-1].value,u=VS+"unit";a!==dA||r.hasOwnProperty(u)||(r[u]=n.getData(i).indataRef(n,"unit")),aA(0,e,n,r)}function xA(t,e,n,r){var i,a,o,u,s,f=this.context.data[t],c=f?f.values.value:[],l=f?f[vA]&&f[vA].value:void 0,h=c[0],d=0;if(h){for(i=e?h.encodings.length:h.fields.length;d(a=n[1])&&(a=n[0],i=n[1]),r=r?o(r,i,a):[i,a];return r&&r.length&&+r[0]!=+r[1]?r:void 0}function kA(t,e,n){return t[0]>e&&(t[0]=e),t[1]n&&(t[1]=n),t)}var SA={random:function(){return e.random()},isArray:s,isBoolean:V,isDate:X,isNumber:J,isObject:f,isRegExp:Z,isString:c,isTuple:ht,toBoolean:nt,toDate:it,toNumber:S,toString:at,pad:et,peek:E,truncate:ut,rgb:Kl,lab:vh,hcl:xh,hsl:nh,sequence:di,format:function(t,e){return FS("format",jd,e)(t)},utcFormat:function(t,e){return FS("utcFormat",fn,e)(t)},utcParse:function(t,e){return FS("utcParse",cn,e)(t)},timeFormat:IS,timeParse:function(t,e){return FS("timeParse",sn,e)(t)},monthFormat:function(t){return BS(t,1,"%B")},monthAbbrevFormat:function(t){return BS(t,1,"%b")},dayFormat:function(t){return BS(0,2+t,"%A")},dayAbbrevFormat:function(t){return BS(0,2+t,"%a")},quarter:function(t){return 1+~~(new Date(t).getMonth()/3)},utcquarter:function(t){return 1+~~(new Date(t).getUTCMonth()/3)},warn:function(){return WS(this.context.dataflow,"warn",arguments)},info:function(){return WS(this.context.dataflow,"info",arguments)},debug:function(){return WS(this.context.dataflow,"debug",arguments)},inScope:function(t){var e=this.context.group,n=!1;if(e)for(;t;){if(t===e){n=!0;break}t=t.mark.group}return n},clampRange:function(t,e,n){var r,i=t[0],a=t[1];return a=n-e?[e,n]:[Math.min(Math.max(i,e),n-r),Math.min(Math.max(a,r),n)]},pinchDistance:function(t){var e=t.touches,n=e[0].clientX-e[1].clientX,r=e[0].clientY-e[1].clientY;return Math.sqrt(n*n+r*r)},pinchAngle:function(t){var e=t.touches;return Math.atan2(e[0].clientY-e[1].clientY,e[0].clientX-e[1].clientX)},screen:function(){return HS?HS.screen:{}},containerSize:function(){var t=this.context.dataflow,e=t.container&&t.container();return e?[e.clientWidth,e.clientHeight]:[void 0,void 0]},windowSize:function(){return HS?[HS.innerWidth,HS.innerHeight]:[void 0,void 0]},span:function(t){return t[t.length-1]-t[0]||0},flush:function(t,e,n,r,i,a){var o=Math.abs(e-t[0]),u=Math.abs(E(t)-e);return o2;break}return u=c.reduce(function(t,e){var n=e.intervals[o].extent,r=s?n.map(function(t){return{unit:e.unit,value:t}}):{unit:e.unit,value:n};return s?t.push.apply(t,r):t.push(r),t},[]),s?wA(u,r):MA(u,r)}},aA),OA("treePath",function(t,e,n){var r=sA(t,this),i=r[e],a=r[n];return i&&a?i.path(a).map(uA):void 0},aA),OA("treeAncestors",function(t,e){var n=sA(t,this)[e];return n?n.ancestors().map(uA):void 0},aA);var DA={blacklist:["_"],whitelist:["datum","event","item"],fieldvar:"datum",globalvar:function(t){return"_["+l("$"+t)+"]"},functions:function(t){var e=US(t);for(var n in AA.forEach(function(t){e[t]=CA+t}),SA)e[n]=NA+n;return e},constants:qS,visitors:zA},RA=function(t){var e=(t=t||{}).whitelist?ot(t.whitelist):{},n=t.blacklist?ot(t.blacklist):{},r=t.constants||qS,i=(t.functions||US)(d),a=t.globalvar,u=t.fieldvar,s={},f={},l=0,h=j(a)?a:function(t){return a+'["'+t+'"]'};function d(t){if(c(t))return t;var e=p[t.type];return null==e&&o("Unsupported type: "+t.type),e(t)}var p={Literal:function(t){return t.raw},Identifier:function(t){var i=t.name;return l>0?i:n.hasOwnProperty(i)?o("Illegal identifier: "+i):r.hasOwnProperty(i)?r[i]:e.hasOwnProperty(i)?i:(s[i]=1,h(i))},MemberExpression:function(t){var e=!t.computed,n=d(t.object);e&&(l+=1);var r=d(t.property);return n===u&&(f[r]=1),e&&(l-=1),n+(e?"."+r:"["+r+"]")},CallExpression:function(t){"Identifier"!==t.callee.type&&o("Illegal callee type: "+t.callee.type);var e=t.callee.name,n=t.arguments,r=i.hasOwnProperty(e)&&i[e];return r||o("Unrecognized function: "+e),j(r)?r(n):r+"("+n.map(d).join(",")+")"},ArrayExpression:function(t){return"["+t.elements.map(d).join(",")+"]"},BinaryExpression:function(t){return"("+d(t.left)+t.operator+d(t.right)+")"},UnaryExpression:function(t){return"("+t.operator+d(t.argument)+")"},ConditionalExpression:function(t){return"("+d(t.test)+"?"+d(t.consequent)+":"+d(t.alternate)+")"},LogicalExpression:function(t){return"("+d(t.left)+t.operator+d(t.right)+")"},ObjectExpression:function(t){return"{"+t.properties.map(d).join(",")+"}"},Property:function(t){l+=1;var e=d(t.key);return l-=1,e+":"+d(t.value)}};function v(t){var e={code:d(t),globals:Object.keys(s),fields:Object.keys(f)};return s={},f={},e}return v.functions=i,v.constants=r,v}(DA),TA=function(t,e,n){var r,i,a={};try{r=function(t){sE=0,fE=(uE=t).length,cE=null,lS();var e=LS();if(cE.type!==pE)throw new Error("Unexpect token after expression.");return e}(t)}catch(e){o("Expression parse error: "+l(t))}return r.visit(function(t){if("CallExpression"===t.type){var n=t.callee.name,r=DA.visitors[n];r&&r(n,t.arguments,e,a)}}),(i=RA(r)).globals.forEach(function(t){var n="$"+t;!a.hasOwnProperty(n)&&e.getSignal(t)&&(a[n]=e.signalRef(t))}),{$expr:n?n+"return("+i.code+");":i.code,$fields:i.fields,$params:a}},PA="view",LA="scope";function qA(t,e){return(t.merge?UA:t.stream?jA:t.type?FA:o("Invalid stream specification: "+l(t)))(t,e)}function UA(t,e){var n=IA({merge:t.merge.map(function(t){return qA(t,e)})},t,e);return e.addStream(n).id}function jA(t,e){var n=IA({stream:qA(t.stream,e)},t,e);return e.addStream(n).id}function FA(t,e){var n,r=e.event((n=t.source)===LA?PA:n||PA,t.type),i=IA({stream:r},t,e);return 1===Object.keys(i).length?r:e.addStream(i).id}function IA(t,e,n){var r,i,a,u,s=e.between;return s&&(2!==s.length&&o('Stream "between" parameter must have 2 entries: '+l(e)),t.between=[qA(s[0],n),qA(s[1],n)]),s=e.filter?U(e.filter):[],(e.marktype||e.markname||e.markrole)&&s.push((r=e.marktype,i=e.markname,a=e.markrole,(u="event.item")+(r&&"*"!==r?"&&"+u+".mark.marktype==='"+r+"'":"")+(a?"&&"+u+".mark.role==='"+a+"'":"")+(i?"&&"+u+".mark.name==='"+i+"'":""))),e.source===LA&&s.push("inScope(event.item)"),s.length&&(t.filter=TA("("+s.join(")&&(")+")").$expr),null!=(s=e.throttle)&&(t.throttle=+s),null!=(s=e.debounce)&&(t.debounce=+s),e.consume&&(t.consume=!0),t}var $A,BA,WA="view",HA="[",YA="]",GA="{",VA="}",XA=":",JA=",",ZA="@",QA=">",KA=/[[\]{}]/,tC={"*":1,arc:1,area:1,group:1,image:1,line:1,path:1,rect:1,rule:1,shape:1,symbol:1,text:1,trail:1};function eC(t,e,n,r,i){for(var a,o=0,u=t.length;e=0?--o:r&&r.indexOf(a)>=0&&++o}return e}function nC(t){for(var e=[],n=0,r=t.length,i=0;i' after between selector: "+t;if(e=e.map(rC),(n=rC(t.slice(1).trim())).between)return{between:e,stream:n};n.between=e;return n}(t):function(t){var e,n,r={source:$A},i=[],a=[0,0],o=0,u=0,s=t.length,f=0;if(t[s-1]===VA){if(!((f=t.lastIndexOf(GA))>=0))throw"Unmatched right brace: "+t;try{a=function(t){var e=t.split(JA);if(!t.length||e.length>2)throw t;return e.map(function(e){var n=+e;if(n!=n)throw t;return n})}(t.substring(f+1,s-1))}catch(e){throw"Invalid throttle specification: "+t}t=t.slice(0,f).trim(),s=t.length,f=0}if(!s)throw t;t[0]===ZA&&(o=++f);(e=eC(t,f,XA))1?(r.type=i[1],o?r.markname=i[0].slice(1):(c=i[0],BA.hasOwnProperty(c)?r.marktype=i[0]:r.source=i[0])):r.type=i[0];var c;"!"===r.type.slice(-1)&&(r.consume=!0,r.type=r.type.slice(0,-1));null!=n&&(r.filter=n);a[0]&&(r.throttle=a[0]);a[1]&&(r.debounce=a[1]);return r}(t)}var iC="var datum=event.item&&event.item.datum;",aC=function(t,e,n){var r,i,a=t.events,u=t.update,s=t.encode,f=[];a||o("Signal update missing events specification."),c(a)&&(a=function(t,e,n){return $A=e||WA,BA=n||tC,nC(t.trim()).map(rC)}(a)),(a=U(a).filter(function(t){return t.signal||t.scale?(f.push(t),0):1})).length&&f.push(a.length>1?{merge:a}:a[0]),null!=s&&(u&&o("Signal encode and update are mutually exclusive."),u="encode(item(),"+l(s)+")"),r=c(u)?TA(u,e,iC):null!=u.expr?TA(u.expr,e,iC):null!=u.value?u.value:null!=u.signal?{$expr:"_.value",$params:{value:e.signalRef(u.signal)}}:o("Invalid signal update specification."),i={target:n,update:r},t.force&&(i.options={force:!0}),f.forEach(function(t){t={source:function(t,e){return t.signal?e.getSignal(t.signal).id:t.scale?e.getScale(t.scale).id:qA(t,e)}(t,e)},e.addUpdate(B(t,i))})};function oC(t,e,n,r){this.id=-1,this.type=t,this.value=e,this.params=n,r&&(this.parent=r)}function uC(t,e,n,r){return new oC(t,e,n,r)}function sC(t,e){return uC("operator",t,e)}function fC(t){var e={$ref:t.id};return t.id<0&&(t.refs=t.refs||[]).push(e),e}var cC={$tupleid:1,toString:function(){return":_tupleid_:"}};function lC(t,e){return e?{$field:t,$name:e}:{$field:t}}var hC=lC("key");function dC(t,e){return{$compare:t,$order:e}}var pC="descending";function vC(t,e){return(t&&t.signal?"$"+t.signal:t||"")+(t&&e?"_":"")+(e&&e.signal?"$"+e.signal:e||"")}function gC(t){return t&&t.signal}function mC(t,e){return null!=t?t:e}function yC(t){return function(e,n,r){return uC(t,n,e||void 0,r)}}var bC=yC("aggregate"),_C=yC("axisticks"),xC=yC("bound"),wC=yC("collect"),MC=yC("compare"),kC=yC("datajoin"),EC=yC("encode"),SC=yC("facet"),AC=yC("field"),CC=yC("key"),NC=yC("legendentries"),zC=yC("mark"),OC=yC("multiextent"),DC=yC("multivalues"),RC=yC("overlap"),TC=yC("params"),PC=yC("prefacet"),LC=yC("projection"),qC=yC("proxy"),UC=yC("relay"),jC=yC("render"),FC=yC("scale"),IC=yC("sieve"),$C=yC("sortitems"),BC=yC("viewlayout"),WC=yC("values"),HC=0,YC=["identity","ordinal","band","point","bin-linear","bin-ordinal","linear","pow","sqrt","log","sequential","time","utc","quantize","quantile","threshold"],GC=ot(YC),VC=ot(YC.slice(1,6));function XC(t){return VC.hasOwnProperty(t)}function JC(t){return"quantile"===t}function ZC(t,e){var n,r=e.getScale(t.name).params;for(n in r.domain=tN(t.domain,t,e),null!=t.range&&(r.range=function t(e,n,r){var i=e.range,a=n.config.range;if(i.signal)return n.signalRef(i.signal);if(c(i)){if(a&&a.hasOwnProperty(i))return e=B({},e,{range:a[i]}),t(e,n,r);"width"===i?i=[0,{signal:"width"}]:"height"===i?i=XC(e.type)?[0,{signal:"height"}]:[{signal:"height"},0]:o("Unrecognized scale range value: "+l(i))}else{if(i.scheme)return r.scheme=QC(i.scheme,n),i.extent&&(r.schemeExtent=function(t,e){return t.signal?e.signalRef(t.signal):t.map(function(t){return QC(t,e)})}(i.extent,n)),void(i.count&&(r.schemeCount=QC(i.count,n)));if(i.step)return void(r.rangeStep=QC(i.step,n));if(XC(e.type)&&!s(i))return tN(i,e,n);s(i)||o("Unsupported range type: "+l(i))}return i.map(function(t){return QC(t,n)})}(t,e,r)),null!=t.interpolate&&function(t,e){e.interpolate=QC(t.type||t),null!=t.gamma&&(e.interpolateGamma=QC(t.gamma))}(t.interpolate,r),null!=t.nice&&function(t,e){e.nice=f(t)?{interval:QC(t.interval),step:QC(t.step)}:QC(t)}(t.nice,r),t)r.hasOwnProperty(n)||"name"===n||(r[n]=QC(t[n],e))}function QC(t,e){return f(t)?t.signal?e.signalRef(t.signal):o("Unsupported object: "+l(t)):t}function KC(t){o("Can not find data set: "+l(t))}function tN(t,e,n){if(t)return t.signal?n.signalRef(t.signal):(s(t)?function(t,e,n){return t.map(function(t){return QC(t,n)})}:t.fields?function(t,e,n){var r=t.data,i=t.fields.reduce(function(t,e){return e=c(e)?{data:r,field:e}:s(e)||e.signal?function(t,e){var n="_:vega:_"+HC++,r=wC({});if(s(t))r.value={$ingest:t};else if(t.signal){var i="setdata("+l(n)+","+t.signal+")";r.params.input=e.signalRef(i)}return e.addDataPipeline(n,[r,IC({})]),{data:n,field:"data"}}(e,n):e,t.push(e),t},[]);return(XC(e.type)?function(t,e,n){var r,i,a;return r=n.map(function(t){var n=e.getData(t.data);return n||KC(t.data),n.countsRef(e,t.field)}),i=e.add(bC({groupby:hC,ops:["sum"],fields:[e.fieldRef("count")],as:["count"],pulse:r})),a=e.add(wC({pulse:fC(i)})),fC(e.add(WC({field:hC,sort:e.sortRef(eN(t.sort,!0)),pulse:fC(a)})))}:JC(e.type)?function(t,e,n){var r=n.map(function(t){var n=e.getData(t.data);return n||KC(t.data),n.domainRef(e,t.field)});return fC(e.add(DC({values:r})))}:function(t,e,n){var r=n.map(function(t){var n=e.getData(t.data);return n||KC(t.data),n.extentRef(e,t.field)});return fC(e.add(OC({extents:r})))})(t,n,i)}:function(t,e,n){var r=n.getData(t.data);r||KC(t.data);return XC(e.type)?r.valuesRef(n,t.field,eN(t.sort,!1)):JC(e.type)?r.domainRef(n,t.field):r.extentRef(n,t.field)})(t,e,n);null==e.domainMin&&null==e.domainMax||o("No scale domain defined for domainMin/domainMax to override.")}function eN(t,e){return t&&(t.field||t.op?t.field||"count"===t.op?e&&t.field?o("Multiple domain scales can not sort by field."):e&&t.op&&"count"!==t.op&&o("Multiple domain scales support op count only."):o("No field provided for sort aggregate op: "+t.op):f(t)?t.field="key":t={field:"key"}),t}function nN(t,e){return s(t)?t.map(function(t){return nN(t,e)}):f(t)?t.signal?e.signalRef(t.signal):o("Unsupported parameter object: "+l(t)):t}var rN="top",iN="left",aN="bottom",oN="value",uN="guide-label",sN="group-title",fN=["shape","size","fill","stroke","strokeDash","opacity"],cN={name:1,interactive:1},lN=ot(["rule"]),hN=ot(["group","image","rect"]),dN=function(t,e){var n="";return lN[e]?n:(t.x2&&(t.x?(hN[e]&&(n+="if(o.x>o.x2)$=o.x,o.x=o.x2,o.x2=$;"),n+="o.width=o.x2-o.x;"):n+="o.x=o.x2-(o.width||0);"),t.xc&&(n+="o.x=o.xc-(o.width||0)/2;"),t.y2&&(t.y?(hN[e]&&(n+="if(o.y>o.y2)$=o.y,o.y=o.y2,o.y2=$;"),n+="o.height=o.y2-o.y;"):n+="o.y=o.y2-(o.height||0);"),t.yc&&(n+="o.y=o.yc-(o.height||0)/2;"),n)},pN=function(t,e,n,r){var i=TA(t,e);return i.$fields.forEach(function(t){r[t]=1}),B(n,i.$params),i.$expr},vN=function(t,e,n,r){return function t(e,n,r,i){var a,s,f;if(e.signal)a="datum",f=pN(e.signal,n,r,i);else if(e.group||e.parent){for(s=Math.max(1,e.level||1),a="item";s-- >0;)a+=".mark.group";e.parent?(f=e.parent,a+=".datum"):f=e.group}else e.datum?(a="datum",f=e.datum):o("Invalid field reference: "+l(e));e.signal||(c(f)?(i[f]=1,f=u(f).map(l).join("][")):f=t(f,n,r,i));return a+"["+f+"]"}(f(t)?t:{datum:t},e,n,r)};var gN=function(t,e,n,r,i){var a,o,u,s=mN(t.scale,n,r,i);return null!=t.range?(o=s+".range()",e=0===(a=+t.range)?o+"[0]":"($="+o+","+(1===a?"$[$.length-1]":"$[0]+"+a+"*($[$.length-1]-$[0])")+")"):(void 0!==e&&(e=s+"("+e+")"),t.band&&(u=function(t,e){if(!c(t))return-1;var n=e.scaleType(t);return"band"===n||"point"===n?1:0}(t.scale,n))&&(a=(o=s+".bandwidth")+"()"+(1===(a=+t.band)?"":"*"+a),u<0&&(a="("+o+"?"+a+":0)"),e=(e?e+"+":"")+a,t.extra&&(e="(datum.extra?"+s+"(datum.extra.value):"+e+")")),null==e&&(e="0")),e};function mN(t,e,n,r){var i;if(c(t))i=XS+t,n.hasOwnProperty(i)||(n[i]=e.scaleRef(t)),i=l(i);else{for(i in e.scales)n[XS+i]=e.scaleRef(i);i=l(XS)+"+"+(t.signal?"("+pN(t.signal,e,n,r)+")":vN(t,e,n,r))}return"_["+i+"]"}var yN=function(t,e,n,r){return f(t)?"("+bN(null,t,e,n,r)+")":t},bN=function(t,e,n,r,i){if(null!=e.gradient)return function(t,e,n,r){return"this.gradient("+mN(t.gradient,e,n,r)+","+l(t.start)+","+l(t.stop)+","+l(t.count)+")"}(e,n,r,i);var a=e.signal?pN(e.signal,n,r,i):e.color?function(t,e,n,r){function i(t,i,a,o){return"this."+t+"("+[bN(null,i,e,n,r),bN(null,a,e,n,r),bN(null,o,e,n,r)].join(",")+").toString()"}return t.c?i("hcl",t.h,t.c,t.l):t.h||t.s?i("hsl",t.h,t.s,t.l):t.l||t.a?i("lab",t.l,t.a,t.b):t.r||t.g||t.b?i("rgb",t.r,t.g,t.b):null}(e.color,n,r,i):null!=e.field?vN(e.field,n,r,i):void 0!==e.value?l(e.value):void 0;return null!=e.scale&&(a=gN(e,a,n,r,i)),void 0===a&&(a=null),null!=e.exponent&&(a="Math.pow("+a+","+yN(e.exponent,n,r,i)+")"),null!=e.mult&&(a+="*"+yN(e.mult,n,r,i)),null!=e.offset&&(a+="+"+yN(e.offset,n,r,i)),e.round&&(a="Math.round("+a+")"),a},_N=function(t,e,n){return t+"["+l(e)+"]="+n+";"},xN=function(t,e,n,r,i){var a="";return e.forEach(function(e){var o=bN(t,e,n,r,i);a+=e.test?pN(e.test,n,r,i)+"?"+o+":":o}),_N("o",t,a)};function wN(t,e,n,r){var i,a,o,u={},f="var o=item,datum=o.datum,$;";for(i in t)a=t[i],s(a)?f+=xN(i,a,r,n,u):(o=bN(i,a,r,n,u),f+=_N("o",i,o));return f+=dN(t,e),{$expr:f+="return 1;",$fields:Object.keys(u),$output:Object.keys(t)}}var MN="mark",kN="frame",EN="title";function SN(t){return f(t)?t:{value:t}}function AN(t,e,n){return null!=n?(t[e]=f(n)&&!s(n)?n:{value:n},1):0}function CN(t,e,n){for(var r in e)n&&n.hasOwnProperty(r)||(t[r]=B(t[r]||{},e[r]));return t}function NN(t,e,n,r,i,a){var o,u;for(u in(a=a||{}).encoders={$encode:o={}},t=function(t,e,n,r,i){var a,o,u={};"legend"!=n&&0!==String(n).indexOf("axis")||(n=null);for(a in o=n===kN?i.group:n===MN?B({},i.mark,i[e]):null)zN(a,t)||("fill"===a||"stroke"===a)&&(zN("fill",t)||zN("stroke",t))||(u[a]={value:o[a]});return U(r).forEach(function(e){var n=i.style&&i.style[e];for(var r in n)zN(r,t)||(u[r]={value:n[r]})}),(t=B({},t)).enter=B(u,t.enter),t}(t,e,n,r,i.config))o[u]=wN(t[u],e,a,i);return a}function zN(t,e){return e&&(e.enter&&e.enter[t]||e.update&&e.update[t])}var ON=function(t,e,n,r,i,a,o){return{type:t,name:o?o.name:void 0,role:e,style:o&&o.style||n,key:r,from:i,interactive:!(!o||!o.interactive),encode:CN(a,o,cN)}},DN="group",RN="text",TN=function(t,e,n,r,i,a,o){return{type:DN,name:n,role:t,style:e,from:r,interactive:i||!1,encode:a,marks:o}};function PN(t){return f(t)&&t.signal?t.signal:l(t)}var LN=function(t){var e=t.role||"";return e.indexOf("axis")&&e.indexOf("legend")?t.type===DN?"scope":e||MN:e},qN=function(t,e){var n=Yr(t.type);n||o("Unrecognized transform type: "+l(t.type));var r=uC(n.type.toLowerCase(),null,UN(n,t,e));return t.signal&&e.addSignal(t.signal,e.proxy(r)),r.metadata=n.metadata||{},r};function UN(t,e,n){var r,i,a,o={};for(i=0,a=t.params.length;i=1?"right":"center"'},ON(RN,"legend-label",uN,"perc",r,u,n)}(0,h,d.labels,i)]):(i=fC(e.add(NC(f={scale:e.scaleRef(y),count:e.objectProperty(t.tickCount),values:e.objectProperty(t.values),formatSpecifier:e.property(t.format)}))),c=[function(t,e,n,r){var i,a,o={value:0},u={};return u.enter=i={opacity:o},AN(i,"shape",e.symbolType),AN(i,"size",e.symbolSize),AN(i,"strokeWidth",e.symbolStrokeWidth),t.fill||(AN(i,"fill",e.symbolFillColor),AN(i,"stroke",e.symbolStrokeColor)),u.exit={opacity:o},u.update=a={opacity:{value:1}},i.x=a.x={field:"offset",mult:.5},i.y=a.y={field:"size",mult:.5,offset:{field:"total",offset:{field:{group:"entryPadding"},mult:{field:"index"}}}},fN.forEach(function(e){t[e]&&(a[e]=i[e]={scale:t[e],field:oN})}),ON("symbol","legend-symbol",null,oN,r,u,n)}(t,h,d.symbols,i),function(t,e,n,r){var i,a,o={value:0},u={};return u.enter=i={opacity:o},AN(i,"align",e.labelAlign),AN(i,"baseline",e.labelBaseline),AN(i,"fill",e.labelColor),AN(i,"font",e.labelFont),AN(i,"fontSize",e.labelFontSize),AN(i,"fontWeight",e.labelFontWeight),AN(i,"limit",e.labelLimit),u.exit={opacity:o},u.update=a={opacity:{value:1},text:{field:"label"}},i.x=a.x={field:"offset",offset:e.labelOffset},i.y=a.y={field:"size",mult:.5,offset:{field:"total",offset:{field:{group:"entryPadding"},mult:{field:"index"}}}},ON(RN,"legend-label",uN,oN,r,u,n)}(0,h,d.labels,i)],f.size=function(t,e,n){var r=KN(e,n[1].encode,"fontSize",uN);if(t.size)return{$expr:"Math.max(Math.ceil(Math.sqrt(_.scale(datum))),"+r+")"};var i=KN(e,n[0].encode,"size");return Math.max(Math.ceil(Math.sqrt(i)),r)}(t,e,c)),c=[TN("legend-entry",null,null,r,g,s,c)],n.title&&(u=function(t,e,n,r){var i,a={value:0},o=t.title,u={};return u.enter=i={x:{field:{group:"padding"}},y:{field:{group:"padding"}},opacity:a},AN(i,"align",e.titleAlign),AN(i,"baseline",e.titleBaseline),AN(i,"fill",e.titleColor),AN(i,"font",e.titleFont),AN(i,"fontSize",e.titleFontSize),AN(i,"fontWeight",e.titleFontWeight),AN(i,"limit",e.titleLimit),u.exit={opacity:a},u.update={opacity:{value:1},text:o&&o.signal?{signal:o.signal}:{value:o+""}},ON(RN,"legend-title","guide-title",null,r,u,n)}(t,h,d.title,r),s.update.y.offset={field:{group:"titlePadding"},offset:KN(e,u.encode,"fontSize","guide-title")},c.push(u)),a=TN("legend",m,v,r,g,p,c),t.zindex&&(a.zindex=t.zindex),ZN(a,e)};function KN(t,e,n,r){var i=e&&(e.update&&e.update[n]||e.enter&&e.enter[n]);return+(i?i.value:r&&(i=t.config.style[r])&&i[n])}var tz=function(t,e){t=c(t)?{text:t}:t;var n,r,i,a=e.config.title,o=B({},t.encode);return n={orient:null!=t.orient?t.orient:a.orient},r=fC(e.add(wC(null,[n]))),o.name=t.name,o.interactive=t.interactive,i=function(t,e,n,r){var i,a,o,u,s,c,l=t.text,h=t.orient||e.orient,d=t.anchor||e.anchor,p=h===iN||h===rN?-1:1,v=h===rN||h===aN,g={group:v?"width":"height"},m={};m.enter=i={opacity:{value:0}},AN(i,"fill",e.color),AN(i,"font",e.font),AN(i,"fontSize",e.fontSize),AN(i,"fontWeight",e.fontWeight),m.exit={opacity:{value:0}},m.update=a={opacity:{value:1},text:f(l)?l:{value:l+""},offset:SN((null!=t.offset?t.offset:e.offset)||0)},"start"===d?(s=0,c="left"):"end"===d?(s=1,c="right"):(s=.5,c="center");o={field:g,mult:s},u=p<0?{value:0}:v?{field:{group:"height"}}:{field:{group:"width"}},v?(a.x=o,a.y=u,a.angle={value:0},a.baseline={value:h===rN?"bottom":"top"}):(a.x=u,a.y=o,a.angle={value:90*p},a.baseline={value:"bottom"});return a.align={value:c},a.limit={field:g},AN(a,"angle",e.angle),AN(a,"baseline",e.baseline),AN(a,"limit",e.limit),ON(RN,EN,t.style||sN,null,r,m,n)}(t,a,o,r),t.zindex&&(i.zindex=t.zindex),ZN(i,e)};function ez(t,e){var n=[];t.transform&&t.transform.forEach(function(t){n.push(qN(t,e))}),t.on&&t.on.forEach(function(n){JN(n,e,t.name)}),e.addDataPipeline(t.name,function(t,e,n){var r,i,a,o,u,s=[],f=null,c=!1,l=!1;t.values?s.push(f=nz({$ingest:t.values,$format:t.format})):t.url?s.push(f=nz({$request:t.url,$format:t.format})):t.source&&(f=r=U(t.source).map(function(t){return fC(e.getData(t).output)}),s.push(null));for(i=0,a=n.length;i0?",":"")+(f(e)?e.signal||lz(e):l(e));return n+"]"}:function(t){var e,n,r="{",i=0;for(e in t)n=t[e],r+=(++i>1?",":"")+l(e)+":"+(f(n)?n.signal||lz(n):l(n));return r+"}"})(t)}cz.fork=function(){return new fz(this)},cz.toRuntime=function(){return this.finish(),{background:this.background,operators:this.operators,streams:this.streams,updates:this.updates,bindings:this.bindings,eventConfig:this.eventConfig}},cz.id=function(){return(this._subid?this._subid+":":0)+this._id++},cz.add=function(t){return this.operators.push(t),t.id=this.id(),t.refs&&(t.refs.forEach(function(e){e.$ref=t.id}),t.refs=null),t},cz.proxy=function(t){var e=t instanceof oC?fC(t):t;return this.add(qC({value:e}))},cz.addStream=function(t){return this.streams.push(t),t.id=this.id(),t},cz.addUpdate=function(t){return this.updates.push(t),t},cz.finish=function(){var t,e;for(t in this.root&&(this.root.root=!0),this.signals)this.signals[t].signal=t;for(t in this.scales)this.scales[t].scale=t;function n(t,e,n){var r;t&&((r=t.data||(t.data={}))[e]||(r[e]=[])).push(n)}for(t in this.data)for(var r in n((e=this.data[t]).input,t,"input"),n(e.output,t,"output"),n(e.values,t,"values"),e.index)n(e.index[r],t,"index:"+r);return this},cz.pushState=function(t,e,n){this._encode.push(fC(this.add(IC({pulse:t})))),this._parent.push(e),this._lookup.push(n?fC(this.proxy(n)):null),this._markpath.push(-1)},cz.popState=function(){this._encode.pop(),this._parent.pop(),this._lookup.pop(),this._markpath.pop()},cz.parent=function(){return E(this._parent)},cz.encode=function(){return E(this._encode)},cz.lookup=function(){return E(this._lookup)},cz.markpath=function(){var t=this._markpath;return++t[t.length-1]},cz.fieldRef=function(t,e){if(c(t))return lC(t,e);t.signal||o("Unsupported field reference: "+l(t));var n,r=t.signal,i=this.field[r];return i||(n={name:this.signalRef(r)},e&&(n.as=e),this.field[r]=i=fC(this.add(AC(n)))),i},cz.compareRef=function(t,e){function n(t){return gC(t)?(i=!0,fC(r[t.signal])):t}var r=this.signals,i=!1,a=U(t.field).map(n),o=U(t.order).map(n);return e&&a.push(cC),i?fC(this.add(MC({fields:a,orders:o}))):dC(a,o)},cz.keyRef=function(t,e){var n=this.signals,r=!1;return t=U(t).map(function(t){return gC(t)?(r=!0,fC(n[t.signal])):t}),r?fC(this.add(CC({fields:t,flat:e}))):function(t,e){var n={$key:t};return e&&(n.$flat=!0),n}(t,e)},cz.sortRef=function(t){if(!t)return t;var e=[vC(t.op,t.field),cC],n=t.order||"ascending";return n.signal?fC(this.add(MC({fields:e,orders:[n=this.signalRef(n.signal),n]}))):dC(e,[n,n])},cz.event=function(t,e){var n=t+":"+e;if(!this.events[n]){var r=this.id();this.streams.push({id:r,source:t,type:e}),this.events[n]=r}return this.events[n]},cz.addSignal=function(t,e){this.signals.hasOwnProperty(t)&&o("Duplicate signal name: "+l(t));var n=e instanceof oC?e:this.add(sC(e));return this.signals[t]=n},cz.getSignal=function(t){return this.signals[t]||o("Unrecognized signal name: "+l(t)),this.signals[t]},cz.signalRef=function(t){return this.signals[t]?fC(this.signals[t]):(this.lambdas.hasOwnProperty(t)||(this.lambdas[t]=this.add(sC(null))),fC(this.lambdas[t]))},cz.parseLambdas=function(){for(var t=Object.keys(this.lambdas),e=0,n=t.length;e=0&&e.splice(n,1),this},Iz.addSignalListener=function(t,e){var n=$z(this,t),r=Bz(n,e);return r||((r=function(){e(t,n.value)}).handler=e,this.on(n,null,r)),this},Iz.removeSignalListener=function(t,e){var n=$z(this,t),r=Bz(n,e);return r&&n._targets.remove(r),this},Iz.preventDefault=function(t){return arguments.length?(this._preventDefault=t,this):this._preventDefault},Iz.tooltipHandler=function(t){var e=this._handler;return arguments.length?(e.handleTooltip=t||bf.prototype.handleTooltip,this):e.handleTooltip},Iz.events=function(t,e,n){var r,i=this,a=new zt(n),o=function(n,r){t===Lk&&function(t,e){var n=t._eventConfig.defaults,r=n&&n.prevent,i=n&&n.allow;return!1!==r&&!0!==i&&(!0===r||!1===i||(r?r[e]:i?!i[e]:t.preventDefault()))}(i,e)&&n.preventDefault();try{a.receive(Pk(i,n,r))}catch(t){i.error(t)}finally{i.run()}};if(t===Lk)return i.addEventListener(e,o),a;if(t===qk?"undefined"!=typeof window&&(r=[window]):"undefined"!=typeof document&&(r=document.querySelectorAll(t)),!r)return i.warn("Can not resolve event source: "+t),a;for(var u=0,s=r.length;u=0;)for(t=(e=n[r]).sources.length;--t>=0;)e.sources[t].removeEventListener(e.type,e.handler)},Iz.hover=function(t,e){return t=[t||"hover"],e=[e||"update",t],this.on(this.events("view","mouseover",Uk),jk,Fk(t)),this.on(this.events("view","mouseout",Uk),jk,Fk(e)),this},Iz.data=function(t){return zk(this,t).values.value},Iz.change=Ok,Iz.insert=function(t,e){return Ok.call(this,t,_t().insert(e))},Iz.remove=function(t,e){return Ok.call(this,t,_t().remove(e))},Iz.initialize=function(t,e){var n,r,i=this,a=i._renderType,o=uc(a);return t=i._el=t?tE(i,t):null,o||i.error("Unrecognized renderer type: "+a),n=o.handler||kf,r=t?o.renderer:o.headless,i._renderer=r?Kk(i,i._renderer,t,r):null,i._handler=function(t,e,n,r){var i=new r(t.loader()).scene(t.scenegraph().root).initialize(n,Tk(t),t);return e&&(i.handleTooltip=e.handleTooltip,e.handlers().forEach(function(t){i.on(t.type,t.handler)})),i}(i,i._handler,t,n),i._redraw=!0,t&&(e=e?tE(i,e):t.appendChild(Ik("div",{class:"vega-bindings"})),i._bind.forEach(function(t){t.param.element&&(t.element=tE(i,t.param.element))}),i._bind.forEach(function(t){Yk(i,t.element||e,t)})),i},Iz.toImageURL=function(t,e){return t!==ac.Canvas&&t!==ac.SVG&&t!==ac.PNG?Promise.reject("Unrecognized image type: "+t):eE(this,t,e).then(function(e){return t===ac.SVG?(n=e.svg(),r=new Blob([n],{type:"image/svg+xml"}),window.URL.createObjectURL(r)):e.canvas().toDataURL("image/png");var n,r})},Iz.toCanvas=function(t){return eE(this,ac.Canvas,t).then(function(t){return t.canvas()})},Iz.toSVG=function(t){return eE(this,ac.SVG,t).then(function(t){return t.svg()})},Iz.getState=function(t){return this._runtime.getState(t||{data:Uz,signals:jz,recurse:!0})},Iz.setState=function(t){var e=this;return e.runAfter(function(){e._trigger=!1,e._runtime.setState(t),e.run().runAfter(function(){e._trigger=!0})}),this},B(Hr,Ba,pl,$g,px,fw,wM,ok,_k,Ck),e.version="3.2.0",e.Dataflow=Fr,e.EventStream=zt,e.Parameters=wt,e.Pulse=Ar,e.MultiPulse=Dr,e.Operator=St,e.Transform=Br,e.changeset=_t,e.ingest=vt,e.isTuple=ht,e.definition=Yr,e.transform=Gr,e.transforms=Hr,e.tupleid=dt,e.scale=mp,e.scheme=Zv,e.interpolate=eg,e.interpolateRange=Qv,e.timeInterval=ig,e.utcInterval=ag,e.projection=ix,e.View=Fz,e.parse=function(t,e){return f(t)||o("Input Vega specification must be an object."),function(t,e){var n,r,i,a,o,u=e.config;return e.background=t.background||u.background,e.eventConfig=u.events,o=fC(e.root=e.add(sC())),e.addSignal("width",t.width||0),e.addSignal("height",t.height||0),e.addSignal("padding",rE(t.padding,u)),e.addSignal("autosize",nE(t.autosize,u)),U(t.signals).forEach(function(t){uz[t.name]||lE(t,e)}),r=e.add(wC()),i=CN({enter:{x:{value:0},y:{value:0}},update:{width:{signal:"width"},height:{signal:"height"}}},t.encode),i=e.add(EC(NN(i,DN,kN,t.style,e,{pulse:fC(r)}))),a=e.add(BC({layout:e.objectProperty(t.layout),legendMargin:u.legendMargin,autosize:e.signalRef("autosize"),mark:o,pulse:fC(i)})),e.operators.pop(),e.pushState(fC(i),fC(a),null),oz(t,e,!0),e.operators.push(a),n=e.add(xC({mark:o,pulse:fC(a)})),n=e.add(jC({pulse:fC(n)})),n=e.add(IC({pulse:fC(n)})),e.addData("root",new HN(e,r,r,n)),e}(t,new sz(hz([e,t.config]))).toRuntime()},e.expressionFunction=OA,e.formatLocale=Wd,e.timeFormatLocale=xr,e.runtime=Nz,e.runtimeContext=Oz,e.bin=ni,e.bootstrapCI=Ei,e.quartiles=Si,e.setRandom=function(t){e.random=t},e.randomInteger=function(t,n){null==n&&(n=t,t=0);var r,i,a,o={};return o.min=function(t){return arguments.length?(a=i-(r=t||0),o):r},o.max=function(t){return arguments.length?(a=(i=t||0)-r,o):i},o.sample=function(){return r+Math.floor(a*e.random())},o.pdf=function(t){return t===Math.floor(t)&&t>=r&&t=i?1:(e-r+1)/a},o.icdf=function(t){return t>=0&&t<=1?r-1+Math.floor(t*a):NaN},o.min(t).max(n)},e.randomKDE=Ci,e.randomMixture=Ni,e.randomNormal=Ai,e.randomUniform=zi,e.accessor=n,e.accessorName=i,e.accessorFields=a,e.id=p,e.identity=v,e.zero=g,e.one=m,e.truthy=y,e.falsy=b,e.logger=k,e.None=0,e.Error=x,e.Warn=2,e.Info=w,e.Debug=M,e.panLinear=O,e.panLog=D,e.panPow=R,e.zoomLinear=P,e.zoomLog=L,e.zoomPow=q,e.array=U,e.compare=F,e.constant=I,e.debounce=$,e.error=o,e.extend=B,e.extentIndex=W,e.fastmap=Y,e.field=h,e.inherits=G,e.isArray=s,e.isBoolean=V,e.isDate=X,e.isFunction=j,e.isNumber=J,e.isObject=f,e.isRegExp=Z,e.isString=c,e.key=Q,e.merge=K,e.pad=et,e.peek=E,e.repeat=tt,e.splitAccessPath=u,e.stringValue=l,e.toBoolean=nt,e.toDate=it,e.toNumber=S,e.toString=at,e.toSet=ot,e.truncate=ut,e.visitArray=st,e.loader=ie,e.read=wr,e.inferType=ve,e.inferTypes=ge,e.typeParsers=he,e.formats=ze,e.Bounds=Wa,e.Gradient=Va,e.GroupItem=Ja,e.ResourceLoader=Ka,e.Item=Xa,e.Scenegraph=lf,e.Handler=bf,e.Renderer=xf,e.CanvasHandler=kf,e.CanvasRenderer=Nf,e.SVGHandler=Rf,e.SVGRenderer=$f,e.SVGStringRenderer=Kf,e.RenderType=ac,e.renderModule=uc,e.Marks=rf,e.boundClip=fc,e.boundContext=ns,e.boundStroke=Qu,e.boundItem=af,e.boundMark=uf,e.pathCurves=pu,e.pathSymbols=Nu,e.pathRectangle=Lu,e.pathTrail=Uu,e.pathParse=mu,e.pathRender=ku,e.point=Mf,e.domCreate=pf,e.domFind=vf,e.domChild=gf,e.domClear=mf,e.openTag=Lf,e.closeTag=qf,e.font=Qs,e.textMetrics=Ws,e.resetSVGClipId=function(){Es=1},e.sceneEqual=lc,e.pathEqual=hc,e.sceneToJSON=ff,e.sceneFromJSON=cf,e.sceneZOrder=cs,e.sceneVisit=ls,e.scenePickVisit=hs,Object.defineProperty(e,"__esModule",{value:!0})}("object"==typeof n&&void 0!==e?n:i.vega=i.vega||{})}).call(this,t("buffer").Buffer)},{buffer:1,canvas:1,"canvas-prebuilt":1,fs:1}],5:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.default=function(t){var e=/\/schema\/([\w-]+)\/([\w\.\-]+)\.json$/g.exec(t).slice(1,3);return{library:e[0],version:e[1]}}},{}],6:[function(t,e,n){(function(e){"use strict";Object.defineProperty(n,"__esModule",{value:!0});var r=t("compare-versions"),i=t("d3-selection"),a=t("vega-lib"),o="undefined"!=typeof window?window.vl:void 0!==e?e.vl:null,u=t("vega-schema-url-parser"),s=t("./post");n.vega=a,n.vl=o;var f={vega:"Vega","vega-lite":"Vega-Lite"},c={vega:n.vega.version,"vega-lite":n.vl?n.vl.version:"not available"},l={vega:function(t,e){return t},"vega-lite":function(t,e){return n.vl.compile(t,e).spec}};n.default=function t(e,a,o){try{var h=void 0===(o=o||{}).actions||o.actions,d=o.loader||n.vega.loader(),p=o.renderer||"canvas",v=o.logLevel||n.vega.Warn;if(n.vega.isString(a))return d.load(a).then(function(n){return t(e,JSON.parse(n),o)}).catch(Promise.reject);var g=o.config;if(n.vega.isString(g))return d.load(g).then(function(n){return o.config=JSON.parse(n),t(e,a,o)}).catch(Promise.reject);var m,y=void 0;a.$schema?(y=u.default(a.$schema),o.mode&&o.mode!==y.library&&console.warn("The given visualization spec is written in "+f[y.library]+", but mode argument sets "+f[o.mode]+"."),m=y.library,r(y.version,c[m])>0&&console.warn("The input spec uses "+m+" "+y.version+", but the current version of "+f[m]+" is "+c[m]+".")):m=o.mode||"vega";var b=l[m](a,g);"vega-lite"===m&&b.$schema&&(y=u.default(b.$schema),r(y.version,c.vega)>0&&console.warn("The compiled spec uses Vega "+y.version+", but current version is "+c.vega+"."));var _=i.select(e).classed("vega-embed",!0).html("");o.onBeforeParse&&(b=o.onBeforeParse(b));var x=n.vega.parse(b,o.config),w=new n.vega.View(x,{loader:d,logLevel:v,renderer:p}).initialize(e);if("vega-lite"!==m&&w.hover(),o&&(o.width&&w.width(o.width),o.height&&w.height(o.height),o.padding&&w.padding(o.padding)),w.run(),!1!==h){var M=_.append("div").attr("class","vega-actions");if(!0===h||!1!==h.export){var k="canvas"===p?"png":"svg";M.append("a").text("Export as "+k.toUpperCase()).attr("href","#").attr("target","_blank").attr("download","visualization."+k).on("mousedown",function(){var t=this;w.toImageURL(k).then(function(e){t.href=e}).catch(function(t){throw t}),i.event.preventDefault()})}if(!0!==h&&!1===h.source||M.append("a").text("View Source").attr("href","#").on("click",function(){var t,e,n,r,u,s;t=JSON.stringify(a,null,2),e=o.sourceHeader||"",n=o.sourceFooter||"",r=""+e+'
',u="
"+n+"",(s=window.open("")).document.write(r+t+u),s.document.title="Vega JSON Source",i.event.preventDefault()}),!0===h||!1!==h.editor){var E=o.editorUrl||"https://vega.github.io/editor/";M.append("a").text("Open in Vega Editor").attr("href","#").on("click",function(){s.post(window,E,{mode:m,spec:JSON.stringify(a,null,2)}),i.event.preventDefault()})}}return Promise.resolve({view:w,spec:a})}catch(t){return Promise.reject(t)}}}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./post":8,"compare-versions":2,"d3-selection":3,"vega-lib":4,"vega-schema-url-parser":5}],7:[function(t,e,n){(function(n){"use strict";var r=t("vega-lib"),i="undefined"!=typeof window?window.vl:void 0!==n?n.vl:null,a=t("./embed"),o=a.default;o.default=a.default,o.vega=r,o.vl=i,e.exports=o}).call(this,"undefined"!=typeof global?global:"undefined"!=typeof self?self:"undefined"!=typeof window?window:{})},{"./embed":6,"vega-lib":4}],8:[function(t,e,n){"use strict";Object.defineProperty(n,"__esModule",{value:!0}),n.post=function(t,e,n){var r=t.open(e),i=250,a=~~(1e4/i);t.addEventListener("message",function e(n){n.source===r&&(a=0,t.removeEventListener("message",e,!1))},!1),setTimeout(function t(){a<=0||(r.postMessage(n,"*"),setTimeout(t,i),a-=1)},i)}},{}]},{},[7])(7)});