|
- var Chart = (function () {
- 'use strict';
-
- var asyncGenerator = function () {
- function AwaitValue(value) {
- this.value = value;
- }
-
- function AsyncGenerator(gen) {
- var front, back;
-
- function send(key, arg) {
- return new Promise(function (resolve, reject) {
- var request = {
- key: key,
- arg: arg,
- resolve: resolve,
- reject: reject,
- next: null
- };
-
- if (back) {
- back = back.next = request;
- } else {
- front = back = request;
- resume(key, arg);
- }
- });
- }
-
- function resume(key, arg) {
- try {
- var result = gen[key](arg);
- var value = result.value;
-
- if (value instanceof AwaitValue) {
- Promise.resolve(value.value).then(function (arg) {
- resume("next", arg);
- }, function (arg) {
- resume("throw", arg);
- });
- } else {
- settle(result.done ? "return" : "normal", result.value);
- }
- } catch (err) {
- settle("throw", err);
- }
- }
-
- function settle(type, value) {
- switch (type) {
- case "return":
- front.resolve({
- value: value,
- done: true
- });
- break;
-
- case "throw":
- front.reject(value);
- break;
-
- default:
- front.resolve({
- value: value,
- done: false
- });
- break;
- }
-
- front = front.next;
-
- if (front) {
- resume(front.key, front.arg);
- } else {
- back = null;
- }
- }
-
- this._invoke = send;
-
- if (typeof gen.return !== "function") {
- this.return = undefined;
- }
- }
-
- if (typeof Symbol === "function" && Symbol.asyncIterator) {
- AsyncGenerator.prototype[Symbol.asyncIterator] = function () {
- return this;
- };
- }
-
- AsyncGenerator.prototype.next = function (arg) {
- return this._invoke("next", arg);
- };
-
- AsyncGenerator.prototype.throw = function (arg) {
- return this._invoke("throw", arg);
- };
-
- AsyncGenerator.prototype.return = function (arg) {
- return this._invoke("return", arg);
- };
-
- return {
- wrap: function (fn) {
- return function () {
- return new AsyncGenerator(fn.apply(this, arguments));
- };
- },
- await: function (value) {
- return new AwaitValue(value);
- }
- };
- }();
-
-
-
-
-
- var classCallCheck = function (instance, Constructor) {
- if (!(instance instanceof Constructor)) {
- throw new TypeError("Cannot call a class as a function");
- }
- };
-
- var createClass = function () {
- function defineProperties(target, props) {
- for (var i = 0; i < props.length; i++) {
- var descriptor = props[i];
- descriptor.enumerable = descriptor.enumerable || false;
- descriptor.configurable = true;
- if ("value" in descriptor) descriptor.writable = true;
- Object.defineProperty(target, descriptor.key, descriptor);
- }
- }
-
- return function (Constructor, protoProps, staticProps) {
- if (protoProps) defineProperties(Constructor.prototype, protoProps);
- if (staticProps) defineProperties(Constructor, staticProps);
- return Constructor;
- };
- }();
-
-
-
-
-
-
-
- var get = function get(object, property, receiver) {
- if (object === null) object = Function.prototype;
- var desc = Object.getOwnPropertyDescriptor(object, property);
-
- if (desc === undefined) {
- var parent = Object.getPrototypeOf(object);
-
- if (parent === null) {
- return undefined;
- } else {
- return get(parent, property, receiver);
- }
- } else if ("value" in desc) {
- return desc.value;
- } else {
- var getter = desc.get;
-
- if (getter === undefined) {
- return undefined;
- }
-
- return getter.call(receiver);
- }
- };
-
- var inherits = function (subClass, superClass) {
- if (typeof superClass !== "function" && superClass !== null) {
- throw new TypeError("Super expression must either be null or a function, not " + typeof superClass);
- }
-
- subClass.prototype = Object.create(superClass && superClass.prototype, {
- constructor: {
- value: subClass,
- enumerable: false,
- writable: true,
- configurable: true
- }
- });
- if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass;
- };
-
-
-
-
-
-
-
-
-
-
-
- var possibleConstructorReturn = function (self, call) {
- if (!self) {
- throw new ReferenceError("this hasn't been initialised - super() hasn't been called");
- }
-
- return call && (typeof call === "object" || typeof call === "function") ? call : self;
- };
-
-
-
-
-
- var slicedToArray = function () {
- function sliceIterator(arr, i) {
- var _arr = [];
- var _n = true;
- var _d = false;
- var _e = undefined;
-
- try {
- for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) {
- _arr.push(_s.value);
-
- if (i && _arr.length === i) break;
- }
- } catch (err) {
- _d = true;
- _e = err;
- } finally {
- try {
- if (!_n && _i["return"]) _i["return"]();
- } finally {
- if (_d) throw _e;
- }
- }
-
- return _arr;
- }
-
- return function (arr, i) {
- if (Array.isArray(arr)) {
- return arr;
- } else if (Symbol.iterator in Object(arr)) {
- return sliceIterator(arr, i);
- } else {
- throw new TypeError("Invalid attempt to destructure non-iterable instance");
- }
- };
- }();
-
-
-
-
-
-
-
-
-
-
-
-
-
- var toConsumableArray = function (arr) {
- if (Array.isArray(arr)) {
- for (var i = 0, arr2 = Array(arr.length); i < arr.length; i++) arr2[i] = arr[i];
-
- return arr2;
- } else {
- return Array.from(arr);
- }
- };
-
- function $(expr, con) {
- return typeof expr === "string" ? (con || document).querySelector(expr) : expr || null;
- }
-
- $.findNodeIndex = function (node) {
- var i = 0;
- while (node.previousSibling) {
- node = node.previousSibling;
- i++;
- }
- return i;
- };
-
- $.create = function (tag, o) {
- var element = document.createElement(tag);
-
- for (var i in o) {
- var val = o[i];
-
- if (i === "inside") {
- $(val).appendChild(element);
- } else if (i === "around") {
- var ref = $(val);
- ref.parentNode.insertBefore(element, ref);
- element.appendChild(ref);
- } else if (i in element) {
- element[i] = val;
- } else {
- element.setAttribute(i, val);
- }
- }
-
- return element;
- };
-
- $.createSVG = function (tag, o) {
- var element = document.createElementNS("http://www.w3.org/2000/svg", tag);
-
- for (var i in o) {
- var val = o[i];
-
- if (i === "inside") {
- $(val).appendChild(element);
- } else if (i === "around") {
- var ref = $(val);
- ref.parentNode.insertBefore(element, ref);
- element.appendChild(ref);
- } else {
- if (i === "className") {
- i = "class";
- }
- if (i === "innerHTML") {
- element['textContent'] = val;
- } else {
- element.setAttribute(i, val);
- }
- }
- }
-
- return element;
- };
-
- $.runSVGAnimation = function (svg_container, elements) {
- // let parent = elements[0][0]['unit'].parentNode;
-
- var new_elements = [];
- var anim_elements = [];
-
- elements.map(function (element) {
- var obj = element[0];
- var parent = obj.unit.parentNode;
- // let index = let findNodeIndex(obj.unit);
-
- var anim_element = void 0,
- new_element = void 0;
-
- element[0] = obj.unit;
-
- var _$$animateSVG = $.animateSVG.apply($, toConsumableArray(element));
-
- var _$$animateSVG2 = slicedToArray(_$$animateSVG, 2);
-
- anim_element = _$$animateSVG2[0];
- new_element = _$$animateSVG2[1];
-
-
- new_elements.push(new_element);
- anim_elements.push([anim_element, parent]);
-
- parent.replaceChild(anim_element, obj.unit);
-
- if (obj.array) {
- obj.array[obj.index] = new_element;
- } else {
- obj.object[obj.key] = new_element;
- }
- });
-
- var anim_svg = svg_container.cloneNode(true);
-
- anim_elements.map(function (anim_element, i) {
- anim_element[1].replaceChild(new_elements[i], anim_element[0]);
- elements[i][0] = new_elements[i];
- });
-
- return anim_svg;
- };
-
- $.animateSVG = function (element, props, dur) {
- var easing_type = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : "linear";
- var type = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : undefined;
- var old_values = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : {};
-
- var easing = {
- ease: "0.25 0.1 0.25 1",
- linear: "0 0 1 1",
- // easein: "0.42 0 1 1",
- easein: "0.1 0.8 0.2 1",
- easeout: "0 0 0.58 1",
- easeinout: "0.42 0 0.58 1"
- };
-
- var anim_element = element.cloneNode(true);
- var new_element = element.cloneNode(true);
-
- for (var attributeName in props) {
- var animate_element = void 0;
- if (attributeName === 'transform') {
- animate_element = document.createElementNS("http://www.w3.org/2000/svg", "animateTransform");
- } else {
- animate_element = document.createElementNS("http://www.w3.org/2000/svg", "animate");
- }
- var current_value = old_values[attributeName] || element.getAttribute(attributeName);
- var value = props[attributeName];
-
- var anim_attr = {
- attributeName: attributeName,
- from: current_value,
- to: value,
- begin: "0s",
- dur: dur / 1000 + "s",
- values: current_value + ";" + value,
- keySplines: easing[easing_type],
- keyTimes: "0;1",
- calcMode: "spline",
- fill: 'freeze'
- };
-
- if (type) {
- anim_attr["type"] = type;
- }
-
- for (var i in anim_attr) {
- animate_element.setAttribute(i, anim_attr[i]);
- }
-
- anim_element.appendChild(animate_element);
-
- if (type) {
- new_element.setAttribute(attributeName, "translate(" + value + ")");
- } else {
- new_element.setAttribute(attributeName, value);
- }
- }
-
- return [anim_element, new_element];
- };
-
- $.offset = function (element) {
- var rect = element.getBoundingClientRect();
- return {
- // https://stackoverflow.com/a/7436602/6495043
- // rect.top varies with scroll, so we add whatever has been
- // scrolled to it to get absolute distance from actual page top
- top: rect.top + (document.documentElement.scrollTop || document.body.scrollTop),
- left: rect.left + (document.documentElement.scrollLeft || document.body.scrollLeft)
- };
- };
-
- $.isElementInViewport = function (el) {
- // Although straightforward: https://stackoverflow.com/a/7557433/6495043
- var rect = el.getBoundingClientRect();
-
- return rect.top >= 0 && rect.left >= 0 && rect.bottom <= (window.innerHeight || document.documentElement.clientHeight) && /*or $(window).height() */
- rect.right <= (window.innerWidth || document.documentElement.clientWidth) /*or $(window).width() */
- ;
- };
-
- $.bind = function (element, o) {
- if (element) {
- for (var event in o) {
- var callback = o[event];
-
- event.split(/\s+/).forEach(function (event) {
- element.addEventListener(event, callback);
- });
- }
- }
- };
-
- $.unbind = function (element, o) {
- if (element) {
- for (var event in o) {
- var callback = o[event];
-
- event.split(/\s+/).forEach(function (event) {
- element.removeEventListener(event, callback);
- });
- }
- }
- };
-
- $.fire = function (target, type, properties) {
- var evt = document.createEvent("HTMLEvents");
-
- evt.initEvent(type, true, true);
-
- for (var j in properties) {
- evt[j] = properties[j];
- }
-
- return target.dispatchEvent(evt);
- };
-
- function float_2(d) {
- return parseFloat(d.toFixed(2));
- }
-
- function arrays_equal(arr1, arr2) {
- if (arr1.length !== arr2.length) return false;
- var are_equal = true;
- arr1.map(function (d, i) {
- if (arr2[i] !== d) are_equal = false;
- });
- return are_equal;
- }
-
- var Chart = function () {
- function Chart(_ref) {
- var _ref$parent = _ref.parent,
- parent = _ref$parent === undefined ? "" : _ref$parent,
- _ref$height = _ref.height,
- height = _ref$height === undefined ? 240 : _ref$height,
- _ref$title = _ref.title,
- title = _ref$title === undefined ? '' : _ref$title,
- _ref$subtitle = _ref.subtitle,
- subtitle = _ref$subtitle === undefined ? '' : _ref$subtitle,
- _ref$data = _ref.data,
- data = _ref$data === undefined ? {} : _ref$data,
- _ref$format_lambdas = _ref.format_lambdas,
- format_lambdas = _ref$format_lambdas === undefined ? {} : _ref$format_lambdas,
- _ref$summary = _ref.summary,
- summary = _ref$summary === undefined ? [] : _ref$summary,
- _ref$is_navigable = _ref.is_navigable,
- is_navigable = _ref$is_navigable === undefined ? 0 : _ref$is_navigable,
- _ref$type = _ref.type,
- type = _ref$type === undefined ? '' : _ref$type;
- classCallCheck(this, Chart);
-
- if (Object.getPrototypeOf(this) === Chart.prototype) {
- if (type === 'line') {
- return new LineChart(arguments[0]);
- } else if (type === 'bar') {
- return new BarChart(arguments[0]);
- } else if (type === 'percentage') {
- return new PercentageChart(arguments[0]);
- } else if (type === 'heatmap') {
- return new HeatMap(arguments[0]);
- } else {
- return new LineChart(arguments[0]);
- }
- }
-
- this.raw_chart_args = arguments[0];
-
- this.parent = document.querySelector(parent);
- this.title = title;
- this.subtitle = subtitle;
-
- this.data = data;
- this.format_lambdas = format_lambdas;
-
- this.specific_values = data.specific_values || [];
- this.summary = summary;
-
- this.is_navigable = is_navigable;
- if (this.is_navigable) {
- this.current_index = 0;
- }
-
- this.chart_types = ['line', 'bar', 'percentage', 'heatmap'];
-
- this.set_margins(height);
- }
-
- createClass(Chart, [{
- key: 'get_different_chart',
- value: function get_different_chart(type) {
- if (!this.chart_types.includes(type)) {
- console.error('\'' + type + '\' is not a valid chart type.');
- }
- if (type === this.type) return;
-
- // Only across compatible types
- var compatible_types = {
- bar: ['line', 'percentage'],
- line: ['bar', 'percentage'],
- percentage: ['bar', 'line'],
- heatmap: []
- };
-
- if (!compatible_types[this.type].includes(type)) {
- console.error('\'' + this.type + '\' chart cannot be converted to a \'' + type + '\' chart.');
- }
-
- // Okay, this is anticlimactic
- // this function will need to actually be 'change_chart_type(type)'
- // that will update only the required elements, but for now ...
- return new Chart({
- parent: this.raw_chart_args.parent,
- data: this.raw_chart_args.data,
- type: type,
- height: this.raw_chart_args.height
- });
- }
- }, {
- key: 'set_margins',
- value: function set_margins(height) {
- this.base_height = height;
- this.height = height - 40;
- this.translate_x = 60;
- this.translate_y = 10;
- }
- }, {
- key: 'setup',
- value: function setup() {
- this.bind_window_events();
- this.refresh(true);
- }
- }, {
- key: 'bind_window_events',
- value: function bind_window_events() {
- var _this = this;
-
- window.addEventListener('resize', function () {
- return _this.refresh();
- });
- window.addEventListener('orientationchange', function () {
- return _this.refresh();
- });
- }
- }, {
- key: 'refresh',
- value: function refresh() {
- var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- this.setup_base_values();
- this.set_width();
-
- this.setup_container();
- this.setup_components();
-
- this.setup_values();
- this.setup_utils();
-
- this.make_graph_components(init);
- this.make_tooltip();
-
- if (this.summary.length > 0) {
- this.show_custom_summary();
- } else {
- this.show_summary();
- }
-
- if (this.is_navigable) {
- this.setup_navigation(init);
- }
- }
- }, {
- key: 'set_width',
- value: function set_width() {
- var _this2 = this;
-
- var special_values_width = 0;
- this.specific_values.map(function (val) {
- if (_this2.get_strwidth(val.title) > special_values_width) {
- special_values_width = _this2.get_strwidth(val.title) - 40;
- }
- });
- this.base_width = this.parent.offsetWidth - special_values_width;
- this.width = this.base_width - this.translate_x * 2;
- }
- }, {
- key: 'setup_base_values',
- value: function setup_base_values() {}
- }, {
- key: 'setup_container',
- value: function setup_container() {
- this.container = $.create('div', {
- className: 'chart-container',
- innerHTML: '<h6 class="title" style="margin-top: 15px;">' + this.title + '</h6>\n\t\t\t\t<h6 class="sub-title uppercase">' + this.subtitle + '</h6>\n\t\t\t\t<div class="frappe-chart graphics"></div>\n\t\t\t\t<div class="graph-stats-container"></div>'
- });
-
- // Chart needs a dedicated parent element
- this.parent.innerHTML = '';
- this.parent.appendChild(this.container);
-
- this.chart_wrapper = this.container.querySelector('.frappe-chart');
- this.stats_wrapper = this.container.querySelector('.graph-stats-container');
-
- this.make_chart_area();
- this.make_draw_area();
- }
- }, {
- key: 'make_chart_area',
- value: function make_chart_area() {
- this.svg = $.createSVG('svg', {
- className: 'chart',
- inside: this.chart_wrapper,
- width: this.base_width,
- height: this.base_height
- });
-
- this.svg_defs = $.createSVG('defs', {
- inside: this.svg
- });
-
- return this.svg;
- }
- }, {
- key: 'make_draw_area',
- value: function make_draw_area() {
- this.draw_area = $.createSVG("g", {
- className: this.type + '-chart',
- inside: this.svg,
- transform: 'translate(' + this.translate_x + ', ' + this.translate_y + ')'
- });
- }
- }, {
- key: 'setup_components',
- value: function setup_components() {}
- }, {
- key: 'make_tooltip',
- value: function make_tooltip() {
- this.tip = new SvgTip({
- parent: this.chart_wrapper
- });
- this.bind_tooltip();
- }
- }, {
- key: 'show_summary',
- value: function show_summary() {}
- }, {
- key: 'show_custom_summary',
- value: function show_custom_summary() {
- var _this3 = this;
-
- this.summary.map(function (d) {
- var stats = $.create('div', {
- className: 'stats',
- innerHTML: '<span class="indicator ' + d.color + '">' + d.title + ': ' + d.value + '</span>'
- });
- _this3.stats_wrapper.appendChild(stats);
- });
- }
- }, {
- key: 'setup_navigation',
- value: function setup_navigation() {
- var _this4 = this;
-
- var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- this.make_overlay();
-
- if (init) {
- this.bind_overlay();
-
- document.addEventListener('keydown', function (e) {
- if ($.isElementInViewport(_this4.chart_wrapper)) {
- e = e || window.event;
-
- if (e.keyCode == '37') {
- _this4.on_left_arrow();
- } else if (e.keyCode == '39') {
- _this4.on_right_arrow();
- } else if (e.keyCode == '38') {
- _this4.on_up_arrow();
- } else if (e.keyCode == '40') {
- _this4.on_down_arrow();
- } else if (e.keyCode == '13') {
- _this4.on_enter_key();
- }
- }
- });
- }
- }
- }, {
- key: 'make_overlay',
- value: function make_overlay() {}
- }, {
- key: 'bind_overlay',
- value: function bind_overlay() {}
- }, {
- key: 'on_left_arrow',
- value: function on_left_arrow() {}
- }, {
- key: 'on_right_arrow',
- value: function on_right_arrow() {}
- }, {
- key: 'on_up_arrow',
- value: function on_up_arrow() {}
- }, {
- key: 'on_down_arrow',
- value: function on_down_arrow() {}
- }, {
- key: 'on_enter_key',
- value: function on_enter_key() {}
- }, {
- key: 'get_data_point',
- value: function get_data_point() {
- var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.current_index;
-
- // check for length
- var data_point = {
- index: index
- };
- var y = this.y[0];
- ['svg_units', 'y_tops', 'values'].map(function (key) {
- var data_key = key.slice(0, key.length - 1);
- data_point[data_key] = y[key][index];
- });
- data_point.label = this.x[index];
- return data_point;
- }
- }, {
- key: 'update_current_data_point',
- value: function update_current_data_point(index) {
- if (index < 0) index = 0;
- if (index >= this.x.length) index = this.x.length - 1;
- if (index === this.current_index) return;
- this.current_index = index;
- $.fire(this.parent, "data-select", this.get_data_point());
- }
-
- // Helpers
-
- }, {
- key: 'get_strwidth',
- value: function get_strwidth(string) {
- return string.length * 8;
- }
-
- // Objects
-
- }, {
- key: 'setup_utils',
- value: function setup_utils() {}
- }]);
- return Chart;
- }();
-
- var AxisChart = function (_Chart) {
- inherits(AxisChart, _Chart);
-
- function AxisChart(args) {
- classCallCheck(this, AxisChart);
-
- var _this5 = possibleConstructorReturn(this, (AxisChart.__proto__ || Object.getPrototypeOf(AxisChart)).call(this, args));
-
- _this5.x = _this5.data.labels;
- _this5.y = _this5.data.datasets;
-
- _this5.get_y_label = _this5.format_lambdas.y_label;
- _this5.get_y_tooltip = _this5.format_lambdas.y_tooltip;
- _this5.get_x_tooltip = _this5.format_lambdas.x_tooltip;
-
- _this5.colors = ['green', 'blue', 'violet', 'red', 'orange', 'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
-
- _this5.zero_line = _this5.height;
- return _this5;
- }
-
- createClass(AxisChart, [{
- key: 'setup_values',
- value: function setup_values() {
- this.data.datasets.map(function (d) {
- d.values = d.values.map(function (val) {
- return !isNaN(val) ? val : 0;
- });
- });
- this.setup_x();
- this.setup_y();
- }
- }, {
- key: 'setup_x',
- value: function setup_x() {
- var _this6 = this;
-
- this.set_avg_unit_width_and_x_offset();
-
- if (this.x_axis_positions) {
- this.x_old_axis_positions = this.x_axis_positions.slice();
- }
- this.x_axis_positions = this.x.map(function (d, i) {
- return float_2(_this6.x_offset + i * _this6.avg_unit_width);
- });
-
- if (!this.x_old_axis_positions) {
- this.x_old_axis_positions = this.x_axis_positions.slice();
- }
- }
- }, {
- key: 'setup_y',
- value: function setup_y() {
- if (this.y_axis_values) {
- this.y_old_axis_values = this.y_axis_values.slice();
- }
-
- var values = this.get_all_y_values();
-
- if (this.y_sums && this.y_sums.length > 0) {
- values = values.concat(this.y_sums);
- }
-
- this.y_axis_values = this.get_y_axis_points(values);
-
- if (!this.y_old_axis_values) {
- this.y_old_axis_values = this.y_axis_values.slice();
- }
-
- var y_pts = this.y_axis_values;
- var value_range = y_pts[y_pts.length - 1] - y_pts[0];
-
- if (this.multiplier) this.old_multiplier = this.multiplier;
- this.multiplier = this.height / value_range;
- if (!this.old_multiplier) this.old_multiplier = this.multiplier;
-
- var zero_index = y_pts.indexOf(0);
- var interval = y_pts[1] - y_pts[0];
- var interval_height = interval * this.multiplier;
-
- if (this.zero_line) this.old_zero_line = this.zero_line;
- this.zero_line = this.height - zero_index * interval_height;
- if (!this.old_zero_line) this.old_zero_line = this.zero_line;
- }
- }, {
- key: 'setup_components',
- value: function setup_components() {
- get(AxisChart.prototype.__proto__ || Object.getPrototypeOf(AxisChart.prototype), 'setup_components', this).call(this);
- this.setup_marker_components();
- this.setup_aggregation_components();
- this.setup_graph_components();
- }
- }, {
- key: 'setup_marker_components',
- value: function setup_marker_components() {
- this.y_axis_group = $.createSVG('g', { className: 'y axis', inside: this.draw_area });
- this.x_axis_group = $.createSVG('g', { className: 'x axis', inside: this.draw_area });
- this.specific_y_group = $.createSVG('g', { className: 'specific axis', inside: this.draw_area });
- }
- }, {
- key: 'setup_aggregation_components',
- value: function setup_aggregation_components() {
- this.sum_group = $.createSVG('g', { className: 'data-points', inside: this.draw_area });
- this.average_group = $.createSVG('g', { className: 'chart-area', inside: this.draw_area });
- }
- }, {
- key: 'setup_graph_components',
- value: function setup_graph_components() {
- var _this7 = this;
-
- this.svg_units_groups = [];
- this.y.map(function (d, i) {
- _this7.svg_units_groups[i] = $.createSVG('g', {
- className: 'data-points data-points-' + i,
- inside: _this7.draw_area
- });
- });
- }
- }, {
- key: 'make_graph_components',
- value: function make_graph_components() {
- var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- this.make_y_axis();
- this.make_x_axis();
- this.draw_graph(init);
- this.make_y_specifics();
- }
-
- // make VERTICAL lines for x values
-
- }, {
- key: 'make_x_axis',
- value: function make_x_axis() {
- var _this8 = this;
-
- var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- var start_at = void 0,
- height = void 0,
- text_start_at = void 0,
- axis_line_class = '';
- if (this.x_axis_mode === 'span') {
- // long spanning lines
- start_at = -7;
- height = this.height + 15;
- text_start_at = this.height + 25;
- } else if (this.x_axis_mode === 'tick') {
- // short label lines
- start_at = this.height;
- height = 6;
- text_start_at = 9;
- axis_line_class = 'x-axis-label';
- }
-
- this.x_axis_group.setAttribute('transform', 'translate(0,' + start_at + ')');
-
- if (animate) {
- this.make_anim_x_axis(height, text_start_at, axis_line_class);
- return;
- }
-
- this.x_axis_group.textContent = '';
- this.x.map(function (point, i) {
- _this8.x_axis_group.appendChild(_this8.make_x_line(height, text_start_at, point, 'x-value-text', axis_line_class, _this8.x_axis_positions[i]));
- });
- }
-
- // make HORIZONTAL lines for y values
-
- }, {
- key: 'make_y_axis',
- value: function make_y_axis() {
- var _this9 = this;
-
- var animate = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- if (animate) {
- this.make_anim_y_axis();
- this.make_anim_y_specifics();
- return;
- }
-
- var _get_y_axis_line_prop = this.get_y_axis_line_props(),
- _get_y_axis_line_prop2 = slicedToArray(_get_y_axis_line_prop, 4),
- width = _get_y_axis_line_prop2[0],
- text_end_at = _get_y_axis_line_prop2[1],
- axis_line_class = _get_y_axis_line_prop2[2],
- start_at = _get_y_axis_line_prop2[3];
-
- this.y_axis_group.textContent = '';
- this.y_axis_values.map(function (value, i) {
- _this9.y_axis_group.appendChild(_this9.make_y_line(start_at, width, text_end_at, value, 'y-value-text', axis_line_class, _this9.zero_line - value * _this9.multiplier, value === 0 && i !== 0 // Non-first Zero line
- ));
- });
- }
- }, {
- key: 'get_y_axis_line_props',
- value: function get_y_axis_line_props() {
- var specific = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- if (specific) {
- return [this.width, this.width + 5, 'specific-value', 0];
- }
- var width = void 0,
- text_end_at = -9,
- axis_line_class = '',
- start_at = 0;
- if (this.y_axis_mode === 'span') {
- // long spanning lines
- width = this.width + 6;
- start_at = -6;
- } else if (this.y_axis_mode === 'tick') {
- // short label lines
- width = -6;
- axis_line_class = 'y-axis-label';
- }
-
- return [width, text_end_at, axis_line_class, start_at];
- }
- }, {
- key: 'draw_graph',
- value: function draw_graph() {
- var _this10 = this;
-
- var init = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : false;
-
- if (init) {
- this.draw_new_graph_and_animate();
- return;
- }
- this.y.map(function (d, i) {
- d.svg_units = [];
- _this10.make_path && _this10.make_path(d, i, _this10.x_axis_positions, d.y_tops, d.color || _this10.colors[i]);
- _this10.make_new_units(d, i);
- });
- }
- }, {
- key: 'draw_new_graph_and_animate',
- value: function draw_new_graph_and_animate() {
- var _this11 = this;
-
- var data = [];
- this.y.map(function (d, i) {
- // Anim: Don't draw initial values, store them and update later
- d.y_tops = new Array(d.values.length).fill(_this11.zero_line); // no value
- data.push({ values: d.values });
- d.svg_units = [];
-
- _this11.make_path && _this11.make_path(d, i, _this11.x_axis_positions, d.y_tops, d.color || _this11.colors[i]);
- _this11.make_new_units(d, i);
- });
-
- setTimeout(function () {
- _this11.update_values(data);
- }, 350);
- }
- }, {
- key: 'setup_navigation',
- value: function setup_navigation(init) {
- var _this12 = this;
-
- // Hack: defer nav till initial update_values
- setTimeout(function () {
- get(AxisChart.prototype.__proto__ || Object.getPrototypeOf(AxisChart.prototype), 'setup_navigation', _this12).call(_this12, init);
- }, 500);
- }
- }, {
- key: 'make_new_units',
- value: function make_new_units(d, i) {
- this.make_new_units_for_dataset(this.x_axis_positions, d.y_tops, d.color || this.colors[i], i, this.y.length);
- }
- }, {
- key: 'make_new_units_for_dataset',
- value: function make_new_units_for_dataset(x_values, y_values, color, dataset_index, no_of_datasets, group, array, unit) {
- var _this13 = this;
-
- if (!group) group = this.svg_units_groups[dataset_index];
- if (!array) array = this.y[dataset_index].svg_units;
- if (!unit) unit = this.unit_args;
-
- group.textContent = '';
- array.length = 0;
-
- y_values.map(function (y, i) {
- var data_unit = _this13.draw[unit.type](x_values[i], y, unit.args, color, dataset_index, no_of_datasets);
- group.appendChild(data_unit);
- array.push(data_unit);
- });
- }
- }, {
- key: 'make_y_specifics',
- value: function make_y_specifics() {
- var _this14 = this;
-
- this.specific_y_group.textContent = '';
- this.specific_values.map(function (d) {
- _this14.specific_y_group.appendChild(_this14.make_y_line(0, _this14.width, _this14.width + 5, d.title.toUpperCase(), 'specific-value', 'specific-value', _this14.zero_line - d.value * _this14.multiplier, false, d.line_type));
- });
- }
- }, {
- key: 'bind_tooltip',
- value: function bind_tooltip() {
- var _this15 = this;
-
- // TODO: could be in tooltip itself, as it is a given functionality for its parent
- this.chart_wrapper.addEventListener('mousemove', function (e) {
- var offset = $.offset(_this15.chart_wrapper);
- var relX = e.pageX - offset.left - _this15.translate_x;
- var relY = e.pageY - offset.top - _this15.translate_y;
-
- if (relY < _this15.height + _this15.translate_y * 2) {
- _this15.map_tooltip_x_position_and_show(relX);
- } else {
- _this15.tip.hide_tip();
- }
- });
- }
- }, {
- key: 'map_tooltip_x_position_and_show',
- value: function map_tooltip_x_position_and_show(relX) {
- var _this16 = this;
-
- for (var i = this.x_axis_positions.length - 1; i >= 0; i--) {
- var x_val = this.x_axis_positions[i];
- // let delta = i === 0 ? this.avg_unit_width : x_val - this.x_axis_positions[i-1];
- if (relX > x_val - this.avg_unit_width / 2) {
- var x = x_val + this.translate_x;
- var y = this.y_min_tops[i] + this.translate_y;
-
- var title = this.x.formatted && this.x.formatted.length > 0 ? this.x.formatted[i] : this.x[i];
- var values = this.y.map(function (set$$1, j) {
- return {
- title: set$$1.title,
- value: set$$1.formatted ? set$$1.formatted[i] : set$$1.values[i],
- color: set$$1.color || _this16.colors[j]
- };
- });
-
- // TODO: upside-down tooltips for negative values?
- this.tip.set_values(x, y, title, '', values);
- this.tip.show_tip();
- break;
- }
- }
- }
-
- // API
-
- }, {
- key: 'show_sums',
- value: function show_sums() {
- var _this17 = this;
-
- this.updating = true;
-
- this.y_sums = new Array(this.x_axis_positions.length).fill(0);
- this.y.map(function (d) {
- d.values.map(function (value, i) {
- _this17.y_sums[i] += value;
- });
- });
-
- // Remake y axis, animate
- this.update_values();
-
- // Then make sum units, don't animate
- this.sum_units = [];
-
- this.make_new_units_for_dataset(this.x_axis_positions, this.y_sums.map(function (val) {
- return float_2(_this17.zero_line - val * _this17.multiplier);
- }), 'light-grey', 0, 1, this.sum_group, this.sum_units);
-
- // this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
-
- this.updating = false;
- }
- }, {
- key: 'hide_sums',
- value: function hide_sums() {
- if (this.updating) return;
- this.y_sums = [];
- this.sum_group.textContent = '';
- this.sum_units = [];
- this.update_values();
- }
- }, {
- key: 'show_average',
- value: function show_average() {
- var _this18 = this;
-
- this.old_specific_values = this.specific_values.slice();
- this.y.map(function (d, i) {
- var sum = 0;
- d.values.map(function (e) {
- sum += e;
- });
- var average = sum / d.values.length;
-
- _this18.specific_values.push({
- title: "AVG" + " " + (i + 1),
- line_type: "dashed",
- value: average,
- auto: 1
- });
- });
-
- this.update_values();
- }
- }, {
- key: 'hide_average',
- value: function hide_average() {
- var _this19 = this;
-
- this.old_specific_values = this.specific_values.slice();
-
- var indices_to_remove = [];
- this.specific_values.map(function (d, i) {
- if (d.auto) indices_to_remove.unshift(i);
- });
-
- indices_to_remove.map(function (index) {
- _this19.specific_values.splice(index, 1);
- });
-
- this.update_values();
- }
- }, {
- key: 'update_values',
- value: function update_values(new_y, new_x) {
- var _this20 = this;
-
- if (!new_x) {
- new_x = this.x;
- }
- this.elements_to_animate = [];
- this.updating = true;
-
- this.old_x_values = this.x.slice();
- this.old_y_axis_tops = this.y.map(function (d) {
- return d.y_tops.slice();
- });
-
- this.old_y_values = this.y.map(function (d) {
- return d.values;
- });
-
- this.no_of_extra_pts = new_x.length - this.x.length;
-
- // Just update values prop, setup_x/y() will do the rest
- if (new_y) this.y.map(function (d, i) {
- d.values = new_y[i].values;
- });
- if (new_x) this.x = new_x;
-
- this.setup_x();
- this.setup_y();
-
- // Animate only if positions have changed
- if (!arrays_equal(this.x_old_axis_positions, this.x_axis_positions)) {
- this.make_x_axis(true);
- setTimeout(function () {
- if (!_this20.updating) _this20.make_x_axis();
- }, 300);
- }
-
- if (!arrays_equal(this.y_old_axis_values, this.y_axis_values) || this.old_specific_values && !arrays_equal(this.old_specific_values, this.specific_values)) {
-
- this.make_y_axis(true);
- setTimeout(function () {
- if (!_this20.updating) {
- _this20.make_y_axis();
- _this20.make_y_specifics();
- }
- }, 300);
- }
-
- // Change in data, so calculate dependencies
- this.calc_y_dependencies();
-
- this.animate_graphs();
-
- // Trigger animation with the animatable elements in this.elements_to_animate
- this.run_animation();
-
- this.updating = false;
- }
- }, {
- key: 'add_data_point',
- value: function add_data_point(y_point, x_point) {
- var index = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : this.x.length;
-
- var new_y = this.y.map(function (data_set) {
- return { values: data_set.values };
- });
- new_y.map(function (d, i) {
- d.values.splice(index, 0, y_point[i]);
- });
- var new_x = this.x.slice();
- new_x.splice(index, 0, x_point);
-
- this.update_values(new_y, new_x);
- }
- }, {
- key: 'remove_data_point',
- value: function remove_data_point() {
- var index = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : this.x.length - 1;
-
- if (this.x.length < 3) return;
-
- var new_y = this.y.map(function (data_set) {
- return { values: data_set.values };
- });
- new_y.map(function (d) {
- d.values.splice(index, 1);
- });
- var new_x = this.x.slice();
- new_x.splice(index, 1);
-
- this.update_values(new_y, new_x);
- }
- }, {
- key: 'run_animation',
- value: function run_animation() {
- var _this21 = this;
-
- var anim_svg = $.runSVGAnimation(this.svg, this.elements_to_animate);
-
- if (this.svg.parentNode == this.chart_wrapper) {
- this.chart_wrapper.removeChild(this.svg);
- this.chart_wrapper.appendChild(anim_svg);
- }
-
- // Replace the new svg (data has long been replaced)
- setTimeout(function () {
- if (anim_svg.parentNode == _this21.chart_wrapper) {
- _this21.chart_wrapper.removeChild(anim_svg);
- _this21.chart_wrapper.appendChild(_this21.svg);
- }
- }, 200);
- }
- }, {
- key: 'animate_graphs',
- value: function animate_graphs() {
- var _this22 = this;
-
- this.y.map(function (d, i) {
- // Pre-prep, equilize no of positions between old and new
- var _calc_old_and_new_pos = _this22.calc_old_and_new_postions(d, i),
- _calc_old_and_new_pos2 = slicedToArray(_calc_old_and_new_pos, 4),
- old_x = _calc_old_and_new_pos2[0],
- old_y = _calc_old_and_new_pos2[1],
- new_x = _calc_old_and_new_pos2[2],
- new_y = _calc_old_and_new_pos2[3];
-
- if (_this22.no_of_extra_pts >= 0) {
- _this22.make_path && _this22.make_path(d, i, old_x, old_y, d.color || _this22.colors[i]);
- _this22.make_new_units_for_dataset(old_x, old_y, d.color || _this22.colors[i], i, _this22.y.length);
- }
- d.path && _this22.animate_path(d, i, old_x, old_y, new_x, new_y);
- _this22.animate_units(d, i, old_x, old_y, new_x, new_y);
- });
-
- // TODO: replace with real units
- setTimeout(function () {
- _this22.y.map(function (d, i) {
- _this22.make_path && _this22.make_path(d, i, _this22.x_axis_positions, d.y_tops, d.color || _this22.colors[i]);
- _this22.make_new_units(d, i);
- });
- }, 300);
- }
- }, {
- key: 'animate_path',
- value: function animate_path(d, i, old_x, old_y, new_x, new_y) {
- // Animate path
- var new_points_list = new_y.map(function (y, i) {
- return new_x[i] + ',' + y;
- });
- var new_path_str = new_points_list.join("L");
-
- var path_args = [{ unit: d.path, object: d, key: 'path' }, { d: "M" + new_path_str }, 250, "easein"];
- this.elements_to_animate.push(path_args);
-
- // Animate region
- if (d.region_path) {
- var reg_start_pt = '0,' + this.zero_line + 'L';
- var reg_end_pt = 'L' + this.width + ',' + this.zero_line;
-
- var region_args = [{ unit: d.region_path, object: d, key: 'region_path' }, { d: "M" + reg_start_pt + new_path_str + reg_end_pt }, 250, "easein"];
- this.elements_to_animate.push(region_args);
- }
- }
- }, {
- key: 'animate_units',
- value: function animate_units(d, index, old_x, old_y, new_x, new_y) {
- var _this23 = this;
-
- var type = this.unit_args.type;
-
- d.svg_units.map(function (unit, i) {
- _this23.elements_to_animate.push(_this23.animate[type]({ unit: unit, array: d.svg_units, index: i }, // unit, with info to replace where it came from in the data
- new_x[i], new_y[i], index));
- });
- }
- }, {
- key: 'calc_old_and_new_postions',
- value: function calc_old_and_new_postions(d, i) {
- var old_x = this.x_old_axis_positions.slice();
- var new_x = this.x_axis_positions.slice();
-
- var old_y = this.old_y_axis_tops[i].slice();
- var new_y = d.y_tops.slice();
-
- var last_old_x_pos = old_x[old_x.length - 1];
- var last_old_y_pos = old_y[old_y.length - 1];
-
- var last_new_x_pos = new_x[new_x.length - 1];
- var last_new_y_pos = new_y[new_y.length - 1];
-
- if (this.no_of_extra_pts >= 0) {
- // First substitute current path with a squiggled one (looking the same but
- // having more points at end),
- // then animate to stretch it later to new points
- // (new points already have more points)
-
- // Hence, the extra end points will correspond to current(old) positions
- var filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_x_pos);
- var filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_y_pos);
-
- old_x = old_x.concat(filler_x);
- old_y = old_y.concat(filler_y);
- } else {
- // Just modify the new points to have extra points
- // with the same position at end
- var _filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_x_pos);
- var _filler_y = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_y_pos);
-
- new_x = new_x.concat(_filler_x);
- new_y = new_y.concat(_filler_y);
- }
-
- return [old_x, old_y, new_x, new_y];
- }
- }, {
- key: 'make_anim_x_axis',
- value: function make_anim_x_axis(height, text_start_at, axis_line_class) {
- var _this24 = this;
-
- // Animate X AXIS to account for more or less axis lines
-
- var old_pos = this.x_old_axis_positions;
- var new_pos = this.x_axis_positions;
-
- var old_vals = this.old_x_values;
- var new_vals = this.x;
-
- var last_line_pos = old_pos[old_pos.length - 1];
-
- var add_and_animate_line = function add_and_animate_line(value, old_pos, new_pos) {
- var x_line = _this24.make_x_line(height, text_start_at, value, // new value
- 'x-value-text', axis_line_class, old_pos // old position
- );
- _this24.x_axis_group.appendChild(x_line);
-
- _this24.elements_to_animate && _this24.elements_to_animate.push([{ unit: x_line, array: [0], index: 0 }, { transform: new_pos + ', 0' }, 250, "easein", "translate", { transform: old_pos + ', 0' }]);
- };
-
- this.x_axis_group.textContent = '';
-
- this.make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, add_and_animate_line);
- }
- }, {
- key: 'make_anim_y_axis',
- value: function make_anim_y_axis() {
- var _this25 = this;
-
- // Animate Y AXIS to account for more or less axis lines
-
- var old_pos = this.y_old_axis_values.map(function (value) {
- return _this25.zero_line - value * _this25.multiplier;
- });
- var new_pos = this.y_axis_values.map(function (value) {
- return _this25.zero_line - value * _this25.multiplier;
- });
-
- var old_vals = this.y_old_axis_values;
- var new_vals = this.y_axis_values;
-
- var last_line_pos = old_pos[old_pos.length - 1];
-
- this.y_axis_group.textContent = '';
-
- this.make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, this.add_and_animate_y_line.bind(this), this.y_axis_group);
- }
- }, {
- key: 'make_anim_y_specifics',
- value: function make_anim_y_specifics() {
- var _this26 = this;
-
- this.specific_y_group.textContent = '';
- this.specific_values.map(function (d) {
- _this26.add_and_animate_y_line(d.title, _this26.old_zero_line - d.value * _this26.old_multiplier, _this26.zero_line - d.value * _this26.multiplier, 0, _this26.specific_y_group, d.line_type, true);
- });
- }
- }, {
- key: 'make_new_axis_anim_lines',
- value: function make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, add_and_animate_line, group) {
- var superimposed_positions = void 0,
- superimposed_values = void 0;
- var no_of_extras = new_vals.length - old_vals.length;
- if (no_of_extras > 0) {
- // More axis are needed
- // First make only the superimposed (same position) ones
- // Add in the extras at the end later
- superimposed_positions = new_pos.slice(0, old_pos.length);
- superimposed_values = new_vals.slice(0, old_vals.length);
- } else {
- // Axis have to be reduced
- // Fake it by moving all current extra axis to the last position
- // You'll need filler positions and values in the new arrays
- var filler_vals = new Array(Math.abs(no_of_extras)).fill("");
- superimposed_values = new_vals.concat(filler_vals);
-
- var filler_pos = new Array(Math.abs(no_of_extras)).fill(last_line_pos);
- superimposed_positions = new_pos.concat(filler_pos);
- }
-
- superimposed_values.map(function (value, i) {
- add_and_animate_line(value, old_pos[i], superimposed_positions[i], i, group);
- });
-
- if (no_of_extras > 0) {
- // Add in extra axis in the end
- // and then animate to new positions
- var extra_values = new_vals.slice(old_vals.length);
- var extra_positions = new_pos.slice(old_pos.length);
-
- extra_values.map(function (value, i) {
- add_and_animate_line(value, last_line_pos, extra_positions[i], i, group);
- });
- }
- }
- }, {
- key: 'make_x_line',
- value: function make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
- var allowed_space = this.avg_unit_width * 1.5;
-
- if (this.get_strwidth(point) > allowed_space) {
- var allowed_letters = allowed_space / 8;
- point = point.slice(0, allowed_letters - 3) + " ...";
- }
-
- var line = $.createSVG('line', {
- x1: 0,
- x2: 0,
- y1: 0,
- y2: height
- });
-
- var text = $.createSVG('text', {
- className: label_class,
- x: 0,
- y: text_start_at,
- dy: '.71em',
- innerHTML: point
- });
-
- var x_level = $.createSVG('g', {
- className: 'tick ' + axis_line_class,
- transform: 'translate(' + x_pos + ', 0)'
- });
-
- x_level.appendChild(line);
- x_level.appendChild(text);
-
- return x_level;
- }
- }, {
- key: 'make_y_line',
- value: function make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos) {
- var darker = arguments.length > 7 && arguments[7] !== undefined ? arguments[7] : false;
- var line_type = arguments.length > 8 && arguments[8] !== undefined ? arguments[8] : "";
-
- var line = $.createSVG('line', {
- className: line_type === "dashed" ? "dashed" : "",
- x1: start_at,
- x2: width,
- y1: 0,
- y2: 0
- });
-
- var text = $.createSVG('text', {
- className: label_class,
- x: text_end_at,
- y: 0,
- dy: '.32em',
- innerHTML: point + ""
- });
-
- var y_level = $.createSVG('g', {
- className: 'tick ' + axis_line_class,
- transform: 'translate(0, ' + y_pos + ')'
- });
-
- if (darker) {
- line.style.stroke = "rgba(27, 31, 35, 0.6)";
- }
-
- y_level.appendChild(line);
- y_level.appendChild(text);
-
- return y_level;
- }
- }, {
- key: 'add_and_animate_y_line',
- value: function add_and_animate_y_line(value, old_pos, new_pos, i, group, type) {
- var specific = arguments.length > 6 && arguments[6] !== undefined ? arguments[6] : false;
-
- var _get_y_axis_line_prop3 = this.get_y_axis_line_props(specific),
- _get_y_axis_line_prop4 = slicedToArray(_get_y_axis_line_prop3, 4),
- width = _get_y_axis_line_prop4[0],
- text_end_at = _get_y_axis_line_prop4[1],
- axis_line_class = _get_y_axis_line_prop4[2],
- start_at = _get_y_axis_line_prop4[3];
-
- var axis_label_class = !specific ? 'y-value-text' : 'specific-value';
- value = !specific ? value : (value + "").toUpperCase();
- var y_line = this.make_y_line(start_at, width, text_end_at, value, axis_label_class, axis_line_class, old_pos, // old position
- value === 0 && i !== 0, // Non-first Zero line
- type);
-
- group.appendChild(y_line);
-
- this.elements_to_animate && this.elements_to_animate.push([{ unit: y_line, array: [0], index: 0 }, { transform: '0, ' + new_pos }, 250, "easein", "translate", { transform: '0, ' + old_pos }]);
- }
- }, {
- key: 'get_y_axis_points',
- value: function get_y_axis_points(array) {
- var _this27 = this;
-
- //*** Where the magic happens ***
-
- // Calculates best-fit y intervals from given values
- // and returns the interval array
-
- // TODO: Fractions
-
- var max_bound = void 0,
- min_bound = void 0,
- pos_no_of_parts = void 0,
- neg_no_of_parts = void 0,
- part_size = void 0; // eslint-disable-line no-unused-vars
-
- // Critical values
- var max_val = parseInt(Math.max.apply(Math, toConsumableArray(array)));
- var min_val = parseInt(Math.min.apply(Math, toConsumableArray(array)));
- if (min_val >= 0) {
- min_val = 0;
- }
-
- var get_params = function get_params(value1, value2) {
- var bound1 = void 0,
- bound2 = void 0,
- no_of_parts_1 = void 0,
- no_of_parts_2 = void 0,
- interval_size = void 0;
- if ((value1 + "").length <= 1) {
- bound1 = 10;
- no_of_parts_1 = 5;
- } else {
- var _calc_upper_bound_and = _this27.calc_upper_bound_and_no_of_parts(value1);
-
- var _calc_upper_bound_and2 = slicedToArray(_calc_upper_bound_and, 2);
-
- bound1 = _calc_upper_bound_and2[0];
- no_of_parts_1 = _calc_upper_bound_and2[1];
- }
-
- interval_size = bound1 / no_of_parts_1;
- no_of_parts_2 = _this27.calc_no_of_parts(value2, interval_size);
- bound2 = no_of_parts_2 * interval_size;
-
- return [bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size];
- };
-
- var abs_min_val = min_val * -1;
- if (abs_min_val <= max_val) {
- var _get_params = get_params(max_val, abs_min_val);
- // Get the positive region intervals
- // then calc negative ones accordingly
-
-
- var _get_params2 = slicedToArray(_get_params, 5);
-
- min_bound = _get_params2[1];
- pos_no_of_parts = _get_params2[2];
- neg_no_of_parts = _get_params2[3];
- part_size = _get_params2[4];
-
- if (abs_min_val === 0) {
- min_bound = 0;neg_no_of_parts = 0;
- }
- } else {
- var _get_params3 = get_params(abs_min_val, max_val);
- // Get the negative region here first
-
-
- var _get_params4 = slicedToArray(_get_params3, 5);
-
- min_bound = _get_params4[0];
- neg_no_of_parts = _get_params4[2];
- pos_no_of_parts = _get_params4[3];
- part_size = _get_params4[4];
- }
-
- // Make both region parts even
- if (pos_no_of_parts % 2 !== 0 && neg_no_of_parts > 0) pos_no_of_parts++;
- if (neg_no_of_parts % 2 !== 0) {
- // every increase in no_of_parts entails an increase in corresponding bound
- // except here, it happens implicitly after every calc_no_of_parts() call
- neg_no_of_parts++;
- min_bound += part_size;
- }
-
- var no_of_parts = pos_no_of_parts + neg_no_of_parts;
- if (no_of_parts > 5) {
- no_of_parts /= 2;
- part_size *= 2;
- }
-
- return this.get_intervals(-1 * min_bound, part_size, no_of_parts);
- }
- }, {
- key: 'get_intervals',
- value: function get_intervals(start, interval_size, count) {
- var intervals = [];
- for (var i = 0; i <= count; i++) {
- intervals.push(start);
- start += interval_size;
- }
- return intervals;
- }
- }, {
- key: 'calc_upper_bound_and_no_of_parts',
- value: function calc_upper_bound_and_no_of_parts(max_val) {
- // Given a positive value, calculates a nice-number upper bound
- // and a consequent optimal number of parts
-
- var part_size = Math.pow(10, (max_val + "").length - 1);
- var no_of_parts = this.calc_no_of_parts(max_val, part_size);
-
- // Use it to get a nice even upper bound
- var upper_bound = part_size * no_of_parts;
-
- return [upper_bound, no_of_parts];
- }
- }, {
- key: 'calc_no_of_parts',
- value: function calc_no_of_parts(value, divisor) {
- // value should be a positive number, divisor should be greater than 0
- // returns an even no of parts
- var no_of_parts = Math.ceil(value / divisor);
- if (no_of_parts % 2 !== 0) no_of_parts++; // Make it an even number
-
- return no_of_parts;
- }
- }, {
- key: 'get_optimal_no_of_parts',
- value: function get_optimal_no_of_parts(no_of_parts) {
- // aka Divide by 2 if too large
- return no_of_parts < 5 ? no_of_parts : no_of_parts / 2;
- }
- }, {
- key: 'set_avg_unit_width_and_x_offset',
- value: function set_avg_unit_width_and_x_offset() {
- // Set the ... you get it
- this.avg_unit_width = this.width / (this.x.length - 1);
- this.x_offset = 0;
- }
- }, {
- key: 'get_all_y_values',
- value: function get_all_y_values() {
- var all_values = [];
-
- // Add in all the y values in the datasets
- this.y.map(function (d) {
- all_values = all_values.concat(d.values);
- });
-
- // Add in all the specific values
- return all_values.concat(this.specific_values.map(function (d) {
- return d.value;
- }));
- }
- }, {
- key: 'calc_y_dependencies',
- value: function calc_y_dependencies() {
- var _this28 = this;
-
- this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
- this.y.map(function (d) {
- d.y_tops = d.values.map(function (val) {
- return float_2(_this28.zero_line - val * _this28.multiplier);
- });
- d.y_tops.map(function (y_top, i) {
- if (y_top < _this28.y_min_tops[i]) {
- _this28.y_min_tops[i] = y_top;
- }
- });
- });
- }
- }, {
- key: 'get_bar_height_and_y_attr',
- value: function get_bar_height_and_y_attr(y_top) {
- var height = void 0,
- y = void 0;
- if (y_top <= this.zero_line) {
- height = this.zero_line - y_top;
- y = y_top;
-
- // In case of invisible bars
- if (height === 0) {
- height = this.height * 0.01;
- y -= height;
- }
- } else {
- height = y_top - this.zero_line;
- y = this.zero_line;
-
- // In case of invisible bars
- if (height === 0) {
- height = this.height * 0.01;
- }
- }
-
- return [height, y];
- }
- }, {
- key: 'setup_utils',
- value: function setup_utils() {
- var _this29 = this;
-
- this.draw = {
- 'bar': function bar(x, y_top, args, color, index, no_of_datasets) {
- var total_width = _this29.avg_unit_width - args.space_width;
- var start_x = x - total_width / 2;
-
- var width = total_width / no_of_datasets;
- var current_x = start_x + width * index;
-
- var _get_bar_height_and_y = _this29.get_bar_height_and_y_attr(y_top),
- _get_bar_height_and_y2 = slicedToArray(_get_bar_height_and_y, 2),
- height = _get_bar_height_and_y2[0],
- y = _get_bar_height_and_y2[1];
-
- return $.createSVG('rect', {
- className: 'bar mini fill ' + color,
- x: current_x,
- y: y,
- width: width,
- height: height
- });
- },
- 'dot': function dot(x, y, args, color) {
- return $.createSVG('circle', {
- className: 'fill ' + color,
- cx: x,
- cy: y,
- r: args.radius
- });
- }
- };
-
- this.animate = {
- 'bar': function bar(bar_obj, x, y_top, index) {
- var start = x - _this29.avg_unit_width / 4;
- var width = _this29.avg_unit_width / 2 / _this29.y.length;
-
- var _get_bar_height_and_y3 = _this29.get_bar_height_and_y_attr(y_top),
- _get_bar_height_and_y4 = slicedToArray(_get_bar_height_and_y3, 2),
- height = _get_bar_height_and_y4[0],
- y = _get_bar_height_and_y4[1];
-
- x = start + width * index;
-
- return [bar_obj, { width: width, height: height, x: x, y: y }, 250, "easein"];
- // bar.animate({height: args.new_height, y: y_top}, 250, mina.easein);
- },
- 'dot': function dot(dot_obj, x, y_top) {
- return [dot_obj, { cx: x, cy: y_top }, 300, "easein"];
- // dot.animate({cy: y_top}, 250, mina.easein);
- }
- };
- }
- }]);
- return AxisChart;
- }(Chart);
-
- var BarChart = function (_AxisChart) {
- inherits(BarChart, _AxisChart);
-
- function BarChart(args) {
- classCallCheck(this, BarChart);
-
- var _this30 = possibleConstructorReturn(this, (BarChart.__proto__ || Object.getPrototypeOf(BarChart)).call(this, args));
-
- _this30.type = 'bar';
- _this30.x_axis_mode = args.x_axis_mode || 'tick';
- _this30.y_axis_mode = args.y_axis_mode || 'span';
- _this30.setup();
- return _this30;
- }
-
- createClass(BarChart, [{
- key: 'setup_values',
- value: function setup_values() {
- get(BarChart.prototype.__proto__ || Object.getPrototypeOf(BarChart.prototype), 'setup_values', this).call(this);
- this.x_offset = this.avg_unit_width;
- this.unit_args = {
- type: 'bar',
- args: {
- space_width: this.avg_unit_width / 2
- }
- };
- }
- }, {
- key: 'make_overlay',
- value: function make_overlay() {
- // Just make one out of the first element
- var index = this.x.length - 1;
- var unit = this.y[0].svg_units[index];
- this.update_current_data_point(index);
-
- if (this.overlay) {
- this.overlay.parentNode.removeChild(this.overlay);
- }
-
- this.overlay = unit.cloneNode();
- this.overlay.style.fill = '#000000';
- this.overlay.style.opacity = '0.4';
- this.draw_area.appendChild(this.overlay);
- }
- }, {
- key: 'bind_overlay',
- value: function bind_overlay() {
- var _this31 = this;
-
- // on event, update overlay
- this.parent.addEventListener('data-select', function (e) {
- _this31.update_overlay(e.svg_unit);
- });
- }
- }, {
- key: 'update_overlay',
- value: function update_overlay(unit) {
- var _this32 = this;
-
- var attributes = [];
- Object.keys(unit.attributes).map(function (index) {
- attributes.push(unit.attributes[index]);
- });
-
- attributes.filter(function (attr) {
- return attr.specified;
- }).map(function (attr) {
- _this32.overlay.setAttribute(attr.name, attr.nodeValue);
- });
- }
- }, {
- key: 'on_left_arrow',
- value: function on_left_arrow() {
- this.update_current_data_point(this.current_index - 1);
- }
- }, {
- key: 'on_right_arrow',
- value: function on_right_arrow() {
- this.update_current_data_point(this.current_index + 1);
- }
- }, {
- key: 'set_avg_unit_width_and_x_offset',
- value: function set_avg_unit_width_and_x_offset() {
- this.avg_unit_width = this.width / (this.x.length + 1);
- this.x_offset = this.avg_unit_width;
- }
- }]);
- return BarChart;
- }(AxisChart);
-
- var LineChart = function (_AxisChart2) {
- inherits(LineChart, _AxisChart2);
-
- function LineChart(args) {
- classCallCheck(this, LineChart);
-
- var _this33 = possibleConstructorReturn(this, (LineChart.__proto__ || Object.getPrototypeOf(LineChart)).call(this, args));
-
- if (Object.getPrototypeOf(_this33) !== LineChart.prototype) {
- return possibleConstructorReturn(_this33);
- }
-
- _this33.type = 'line';
- _this33.region_fill = args.region_fill;
- _this33.x_axis_mode = args.x_axis_mode || 'span';
- _this33.y_axis_mode = args.y_axis_mode || 'span';
-
- _this33.setup();
- return _this33;
- }
-
- createClass(LineChart, [{
- key: 'setup_graph_components',
- value: function setup_graph_components() {
- this.setup_path_groups();
- get(LineChart.prototype.__proto__ || Object.getPrototypeOf(LineChart.prototype), 'setup_graph_components', this).call(this);
- }
- }, {
- key: 'setup_path_groups',
- value: function setup_path_groups() {
- var _this34 = this;
-
- this.paths_groups = [];
- this.y.map(function (d, i) {
- _this34.paths_groups[i] = $.createSVG('g', {
- className: 'path-group path-group-' + i,
- inside: _this34.draw_area
- });
- });
- }
- }, {
- key: 'setup_values',
- value: function setup_values() {
- get(LineChart.prototype.__proto__ || Object.getPrototypeOf(LineChart.prototype), 'setup_values', this).call(this);
- this.unit_args = {
- type: 'dot',
- args: { radius: 8 }
- };
- }
- }, {
- key: 'make_paths',
- value: function make_paths() {
- var _this35 = this;
-
- this.y.map(function (d, i) {
- _this35.make_path(d, i, _this35.x_axis_positions, d.y_tops, d.color || _this35.colors[i]);
- });
- }
- }, {
- key: 'make_path',
- value: function make_path(d, i, x_positions, y_positions, color) {
- var points_list = y_positions.map(function (y, i) {
- return x_positions[i] + ',' + y;
- });
- var points_str = points_list.join("L");
-
- this.paths_groups[i].textContent = '';
-
- d.path = $.createSVG('path', {
- inside: this.paths_groups[i],
- className: 'stroke ' + color,
- d: "M" + points_str
- });
-
- if (this.region_fill) {
- var gradient_id = 'path-fill-gradient' + '-' + color;
-
- this.gradient_def = $.createSVG('linearGradient', {
- inside: this.svg_defs,
- id: gradient_id,
- x1: 0,
- x2: 0,
- y1: 0,
- y2: 1
- });
-
- var set_gradient_stop = function set_gradient_stop(grad_elem, offset, color, opacity) {
- $.createSVG('stop', {
- 'className': 'stop-color ' + color,
- 'inside': grad_elem,
- 'offset': offset,
- 'stop-opacity': opacity
- });
- };
-
- set_gradient_stop(this.gradient_def, "0%", color, 0.4);
- set_gradient_stop(this.gradient_def, "50%", color, 0.2);
- set_gradient_stop(this.gradient_def, "100%", color, 0);
-
- d.region_path = $.createSVG('path', {
- inside: this.paths_groups[i],
- className: 'region-fill',
- d: "M" + ('0,' + this.zero_line + 'L') + points_str + ('L' + this.width + ',' + this.zero_line)
- });
-
- d.region_path.style.stroke = "none";
- d.region_path.style.fill = 'url(#' + gradient_id + ')';
- }
- }
- }]);
- return LineChart;
- }(AxisChart);
-
- var PercentageChart = function (_Chart2) {
- inherits(PercentageChart, _Chart2);
-
- function PercentageChart(args) {
- classCallCheck(this, PercentageChart);
-
- var _this36 = possibleConstructorReturn(this, (PercentageChart.__proto__ || Object.getPrototypeOf(PercentageChart)).call(this, args));
-
- _this36.type = 'percentage';
-
- _this36.get_y_label = _this36.format_lambdas.y_label;
- _this36.get_x_tooltip = _this36.format_lambdas.x_tooltip;
- _this36.get_y_tooltip = _this36.format_lambdas.y_tooltip;
-
- _this36.max_slices = 10;
- _this36.max_legend_points = 6;
-
- _this36.colors = args.colors;
-
- if (!_this36.colors || _this36.colors.length < _this36.data.labels.length) {
- _this36.colors = ['light-blue', 'blue', 'violet', 'red', 'orange', 'yellow', 'green', 'light-green', 'purple', 'magenta'];
- }
-
- _this36.setup();
- return _this36;
- }
-
- createClass(PercentageChart, [{
- key: 'make_chart_area',
- value: function make_chart_area() {
- this.chart_wrapper.className += ' ' + 'graph-focus-margin';
- this.chart_wrapper.style.marginTop = '45px';
-
- this.stats_wrapper.className += ' ' + 'graph-focus-margin';
- this.stats_wrapper.style.marginBottom = '30px';
- this.stats_wrapper.style.paddingTop = '0px';
- }
- }, {
- key: 'make_draw_area',
- value: function make_draw_area() {
- this.chart_div = $.create('div', {
- className: 'div',
- inside: this.chart_wrapper,
- width: this.base_width,
- height: this.base_height
- });
-
- this.chart = $.create('div', {
- className: 'progress-chart',
- inside: this.chart_div
- });
- }
- }, {
- key: 'setup_components',
- value: function setup_components() {
- this.percentage_bar = $.create('div', {
- className: 'progress',
- inside: this.chart
- });
- }
- }, {
- key: 'setup_values',
- value: function setup_values() {
- var _this37 = this;
-
- this.slice_totals = [];
- var all_totals = this.data.labels.map(function (d, i) {
- var total = 0;
- _this37.data.datasets.map(function (e) {
- total += e.values[i];
- });
- return [total, d];
- }).filter(function (d) {
- return d[0] > 0;
- }); // keep only positive results
-
- var totals = all_totals;
-
- if (all_totals.length > this.max_slices) {
- all_totals.sort(function (a, b) {
- return b[0] - a[0];
- });
-
- totals = all_totals.slice(0, this.max_slices - 1);
- var others = all_totals.slice(this.max_slices - 1);
-
- var sum_of_others = 0;
- others.map(function (d) {
- sum_of_others += d[0];
- });
-
- totals.push([sum_of_others, 'Rest']);
-
- this.colors[this.max_slices - 1] = 'grey';
- }
-
- this.labels = [];
- totals.map(function (d) {
- _this37.slice_totals.push(d[0]);
- _this37.labels.push(d[1]);
- });
-
- this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
- }
- }, {
- key: 'setup_utils',
- value: function setup_utils() {}
- }, {
- key: 'make_graph_components',
- value: function make_graph_components() {
- var _this38 = this;
-
- this.grand_total = this.slice_totals.reduce(function (a, b) {
- return a + b;
- }, 0);
- this.slices = [];
- this.slice_totals.map(function (total, i) {
- var slice = $.create('div', {
- className: 'progress-bar background ' + _this38.colors[i],
- style: 'width: ' + total * 100 / _this38.grand_total + '%',
- inside: _this38.percentage_bar
- });
- _this38.slices.push(slice);
- });
- }
- }, {
- key: 'bind_tooltip',
- value: function bind_tooltip() {
- var _this39 = this;
-
- this.slices.map(function (slice, i) {
- slice.addEventListener('mouseenter', function () {
- var g_off = $.offset(_this39.chart_wrapper),
- p_off = $.offset(slice);
-
- var x = p_off.left - g_off.left + slice.offsetWidth / 2;
- var y = p_off.top - g_off.top - 6;
- var title = (_this39.formatted_labels && _this39.formatted_labels.length > 0 ? _this39.formatted_labels[i] : _this39.labels[i]) + ': ';
- var percent = (_this39.slice_totals[i] * 100 / _this39.grand_total).toFixed(1);
-
- _this39.tip.set_values(x, y, title, percent + "%");
- _this39.tip.show_tip();
- });
- });
- }
- }, {
- key: 'show_summary',
- value: function show_summary() {
- var _this40 = this;
-
- var x_values = this.formatted_labels && this.formatted_labels.length > 0 ? this.formatted_labels : this.labels;
- this.legend_totals.map(function (d, i) {
- if (d) {
- var stats = $.create('div', {
- className: 'stats',
- inside: _this40.stats_wrapper
- });
- stats.innerHTML = '<span class="indicator ' + _this40.colors[i] + '">\n\t\t\t\t\t<span class="text-muted">' + x_values[i] + ':</span>\n\t\t\t\t\t' + d + '\n\t\t\t\t</span>';
- }
- });
- }
- }]);
- return PercentageChart;
- }(Chart);
-
- var HeatMap = function (_Chart3) {
- inherits(HeatMap, _Chart3);
-
- function HeatMap(_ref2) {
- var _ref2$start = _ref2.start,
- start = _ref2$start === undefined ? '' : _ref2$start,
- _ref2$domain = _ref2.domain,
- domain = _ref2$domain === undefined ? '' : _ref2$domain,
- _ref2$subdomain = _ref2.subdomain,
- subdomain = _ref2$subdomain === undefined ? '' : _ref2$subdomain,
- _ref2$data = _ref2.data,
- data = _ref2$data === undefined ? {} : _ref2$data,
- _ref2$discrete_domain = _ref2.discrete_domains,
- discrete_domains = _ref2$discrete_domain === undefined ? 0 : _ref2$discrete_domain,
- _ref2$count_label = _ref2.count_label,
- count_label = _ref2$count_label === undefined ? '' : _ref2$count_label;
- classCallCheck(this, HeatMap);
-
- var _this41 = possibleConstructorReturn(this, (HeatMap.__proto__ || Object.getPrototypeOf(HeatMap)).call(this, arguments[0]));
-
- _this41.type = 'heatmap';
-
- _this41.domain = domain;
- _this41.subdomain = subdomain;
- _this41.data = data;
- _this41.discrete_domains = discrete_domains;
- _this41.count_label = count_label;
-
- var today = new Date();
- _this41.start = start || _this41.add_days(today, 365);
-
- _this41.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
-
- _this41.translate_x = 0;
- _this41.setup();
- return _this41;
- }
-
- createClass(HeatMap, [{
- key: 'setup_base_values',
- value: function setup_base_values() {
- this.today = new Date();
-
- if (!this.start) {
- this.start = new Date();
- this.start.setFullYear(this.start.getFullYear() - 1);
- }
- this.first_week_start = new Date(this.start.toDateString());
- this.last_week_start = new Date(this.today.toDateString());
- if (this.first_week_start.getDay() !== 7) {
- this.add_days(this.first_week_start, -1 * this.first_week_start.getDay());
- }
- if (this.last_week_start.getDay() !== 7) {
- this.add_days(this.last_week_start, -1 * this.last_week_start.getDay());
- }
- this.no_of_cols = this.get_weeks_between(this.first_week_start + '', this.last_week_start + '') + 1;
- }
- }, {
- key: 'set_width',
- value: function set_width() {
- this.base_width = this.no_of_cols * 12;
-
- if (this.discrete_domains) {
- this.base_width += 12 * 12;
- }
- }
- }, {
- key: 'setup_components',
- value: function setup_components() {
- this.domain_label_group = $.createSVG("g", {
- className: "domain-label-group chart-label",
- inside: this.draw_area
- });
- this.data_groups = $.createSVG("g", {
- className: "data-groups",
- inside: this.draw_area,
- transform: 'translate(0, 20)'
- });
- }
- }, {
- key: 'setup_values',
- value: function setup_values() {
- this.domain_label_group.textContent = '';
- this.data_groups.textContent = '';
- this.distribution = this.get_distribution(this.data, this.legend_colors);
- this.month_names = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
-
- this.render_all_weeks_and_store_x_values(this.no_of_cols);
- }
- }, {
- key: 'render_all_weeks_and_store_x_values',
- value: function render_all_weeks_and_store_x_values(no_of_weeks) {
- var current_week_sunday = new Date(this.first_week_start);
- this.week_col = 0;
- this.current_month = current_week_sunday.getMonth();
-
- this.months = [this.current_month + ''];
- this.month_weeks = {}, this.month_start_points = [];
- this.month_weeks[this.current_month] = 0;
- this.month_start_points.push(13);
-
- for (var i = 0; i < no_of_weeks; i++) {
- var data_group = void 0,
- month_change = 0;
- var day = new Date(current_week_sunday);
-
- var _get_week_squares_gro = this.get_week_squares_group(day, this.week_col);
-
- var _get_week_squares_gro2 = slicedToArray(_get_week_squares_gro, 2);
-
- data_group = _get_week_squares_gro2[0];
- month_change = _get_week_squares_gro2[1];
-
- this.data_groups.appendChild(data_group);
- this.week_col += 1 + parseInt(this.discrete_domains && month_change);
- this.month_weeks[this.current_month]++;
- if (month_change) {
- this.current_month = (this.current_month + 1) % 12;
- this.months.push(this.current_month + '');
- this.month_weeks[this.current_month] = 1;
- }
- this.add_days(current_week_sunday, 7);
- }
- this.render_month_labels();
- }
- }, {
- key: 'get_week_squares_group',
- value: function get_week_squares_group(current_date, index) {
- var no_of_weekdays = 7;
- var square_side = 10;
- var cell_padding = 2;
- var step = 1;
-
- var month_change = 0;
- var week_col_change = 0;
-
- var data_group = $.createSVG("g", {
- className: "data-group",
- inside: this.data_groups
- });
-
- for (var y = 0, i = 0; i < no_of_weekdays; i += step, y += square_side + cell_padding) {
- var data_value = 0;
- var color_index = 0;
-
- var timestamp = Math.floor(current_date.getTime() / 1000).toFixed(1);
-
- if (this.data[timestamp]) {
- data_value = this.data[timestamp];
- color_index = this.get_max_checkpoint(data_value, this.distribution);
- }
-
- if (this.data[Math.round(timestamp)]) {
- data_value = this.data[Math.round(timestamp)];
- color_index = this.get_max_checkpoint(data_value, this.distribution);
- }
-
- var x = 13 + (index + week_col_change) * 12;
-
- $.createSVG("rect", {
- className: 'day',
- inside: data_group,
- x: x,
- y: y,
- width: square_side,
- height: square_side,
- fill: this.legend_colors[color_index],
- 'data-date': this.get_dd_mm_yyyy(current_date),
- 'data-value': data_value,
- 'data-day': current_date.getDay()
- });
-
- var next_date = new Date(current_date);
- this.add_days(next_date, 1);
- if (next_date.getMonth() - current_date.getMonth()) {
- month_change = 1;
- if (this.discrete_domains) {
- week_col_change = 1;
- }
-
- this.month_start_points.push(13 + (index + week_col_change) * 12);
- }
- current_date = next_date;
- }
-
- return [data_group, month_change];
- }
- }, {
- key: 'render_month_labels',
- value: function render_month_labels() {
- var _this42 = this;
-
- // this.first_month_label = 1;
- // if (this.first_week_start.getDate() > 8) {
- // this.first_month_label = 0;
- // }
- // this.last_month_label = 1;
-
- // let first_month = this.months.shift();
- // let first_month_start = this.month_start_points.shift();
- // render first month if
-
- // let last_month = this.months.pop();
- // let last_month_start = this.month_start_points.pop();
- // render last month if
-
- this.months.shift();
- this.month_start_points.shift();
- this.months.pop();
- this.month_start_points.pop();
-
- this.month_start_points.map(function (start, i) {
- var month_name = _this42.month_names[_this42.months[i]].substring(0, 3);
-
- $.createSVG('text', {
- className: 'y-value-text',
- inside: _this42.domain_label_group,
- x: start + 12,
- y: 10,
- dy: '.32em',
- innerHTML: month_name
- });
- });
- }
- }, {
- key: 'make_graph_components',
- value: function make_graph_components() {
- Array.prototype.slice.call(this.container.querySelectorAll('.graph-stats-container, .sub-title, .title')).map(function (d) {
- d.style.display = 'None';
- });
- this.chart_wrapper.style.marginTop = '0px';
- this.chart_wrapper.style.paddingTop = '0px';
- }
- }, {
- key: 'bind_tooltip',
- value: function bind_tooltip() {
- var _this43 = this;
-
- Array.prototype.slice.call(document.querySelectorAll(".data-group .day")).map(function (el) {
- el.addEventListener('mouseenter', function (e) {
- var count = e.target.getAttribute('data-value');
- var date_parts = e.target.getAttribute('data-date').split('-');
-
- var month = _this43.month_names[parseInt(date_parts[1]) - 1].substring(0, 3);
-
- var g_off = _this43.chart_wrapper.getBoundingClientRect(),
- p_off = e.target.getBoundingClientRect();
-
- var width = parseInt(e.target.getAttribute('width'));
- var x = p_off.left - g_off.left + (width + 2) / 2;
- var y = p_off.top - g_off.top - (width + 2) / 2;
- var value = count + ' ' + _this43.count_label;
- var name = ' on ' + month + ' ' + date_parts[0] + ', ' + date_parts[2];
-
- _this43.tip.set_values(x, y, name, value, [], 1);
- _this43.tip.show_tip();
- });
- });
- }
- }, {
- key: 'update',
- value: function update(data) {
- this.data = data;
- this.setup_values();
- this.bind_tooltip();
- }
- }, {
- key: 'get_distribution',
- value: function get_distribution() {
- var data = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : {};
- var mapper_array = arguments[1];
-
- var data_values = Object.keys(data).map(function (key) {
- return data[key];
- });
- var data_max_value = Math.max.apply(Math, toConsumableArray(data_values));
-
- var distribution_step = 1 / (mapper_array.length - 1);
- var distribution = [];
-
- mapper_array.map(function (color, i) {
- var checkpoint = data_max_value * (distribution_step * i);
- distribution.push(checkpoint);
- });
-
- return distribution;
- }
- }, {
- key: 'get_max_checkpoint',
- value: function get_max_checkpoint(value, distribution) {
- return distribution.filter(function (d, i) {
- if (i === 1) {
- return distribution[0] < value;
- }
- return d <= value;
- }).length - 1;
- }
-
- // TODO: date utils, move these out
-
- // https://stackoverflow.com/a/11252167/6495043
-
- }, {
- key: 'treat_as_utc',
- value: function treat_as_utc(date_str) {
- var result = new Date(date_str);
- result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
- return result;
- }
- }, {
- key: 'get_dd_mm_yyyy',
- value: function get_dd_mm_yyyy(date) {
- var dd = date.getDate();
- var mm = date.getMonth() + 1; // getMonth() is zero-based
- return [(dd > 9 ? '' : '0') + dd, (mm > 9 ? '' : '0') + mm, date.getFullYear()].join('-');
- }
- }, {
- key: 'get_weeks_between',
- value: function get_weeks_between(start_date_str, end_date_str) {
- return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
- }
- }, {
- key: 'get_days_between',
- value: function get_days_between(start_date_str, end_date_str) {
- var milliseconds_per_day = 24 * 60 * 60 * 1000;
- return (this.treat_as_utc(end_date_str) - this.treat_as_utc(start_date_str)) / milliseconds_per_day;
- }
-
- // mutates
-
- }, {
- key: 'add_days',
- value: function add_days(date, number_of_days) {
- date.setDate(date.getDate() + number_of_days);
- }
- }, {
- key: 'get_month_name',
- value: function get_month_name() {}
- }]);
- return HeatMap;
- }(Chart);
-
- var SvgTip = function () {
- function SvgTip(_ref3) {
- var _ref3$parent = _ref3.parent,
- parent = _ref3$parent === undefined ? null : _ref3$parent;
- classCallCheck(this, SvgTip);
-
- this.parent = parent;
- this.title_name = '';
- this.title_value = '';
- this.list_values = [];
- this.title_value_first = 0;
-
- this.x = 0;
- this.y = 0;
-
- this.top = 0;
- this.left = 0;
-
- this.setup();
- }
-
- createClass(SvgTip, [{
- key: 'setup',
- value: function setup() {
- this.make_tooltip();
- }
- }, {
- key: 'refresh',
- value: function refresh() {
- this.fill();
- this.calc_position();
- // this.show_tip();
- }
- }, {
- key: 'make_tooltip',
- value: function make_tooltip() {
- var _this44 = this;
-
- this.container = $.create('div', {
- inside: this.parent,
- className: 'graph-svg-tip comparison',
- innerHTML: '<span class="title"></span>\n\t\t\t\t<ul class="data-point-list"></ul>\n\t\t\t\t<div class="svg-pointer"></div>'
- });
- this.hide_tip();
-
- this.title = this.container.querySelector('.title');
- this.data_point_list = this.container.querySelector('.data-point-list');
-
- this.parent.addEventListener('mouseleave', function () {
- _this44.hide_tip();
- });
- }
- }, {
- key: 'fill',
- value: function fill() {
- var _this45 = this;
-
- var title = void 0;
- if (this.title_value_first) {
- title = '<strong>' + this.title_value + '</strong>' + this.title_name;
- } else {
- title = this.title_name + '<strong>' + this.title_value + '</strong>';
- }
- this.title.innerHTML = title;
- this.data_point_list.innerHTML = '';
-
- this.list_values.map(function (set$$1) {
- var li = $.create('li', {
- className: 'border-top ' + (set$$1.color || 'black'),
- innerHTML: '<strong style="display: block;">' + (set$$1.value ? set$$1.value : '') + '</strong>\n\t\t\t\t\t' + (set$$1.title ? set$$1.title : '')
- });
-
- _this45.data_point_list.appendChild(li);
- });
- }
- }, {
- key: 'calc_position',
- value: function calc_position() {
- this.top = this.y - this.container.offsetHeight;
- this.left = this.x - this.container.offsetWidth / 2;
- var max_left = this.parent.offsetWidth - this.container.offsetWidth;
-
- var pointer = this.container.querySelector('.svg-pointer');
-
- if (this.left < 0) {
- pointer.style.left = 'calc(50% - ' + -1 * this.left + 'px)';
- this.left = 0;
- } else if (this.left > max_left) {
- var delta = this.left - max_left;
- pointer.style.left = 'calc(50% + ' + delta + 'px)';
- this.left = max_left;
- } else {
- pointer.style.left = '50%';
- }
- }
- }, {
- key: 'set_values',
- value: function set_values(x, y) {
- var title_name = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : '';
- var title_value = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : '';
- var list_values = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : [];
- var title_value_first = arguments.length > 5 && arguments[5] !== undefined ? arguments[5] : 0;
-
- this.title_name = title_name;
- this.title_value = title_value;
- this.list_values = list_values;
- this.x = x;
- this.y = y;
- this.title_value_first = title_value_first;
- this.refresh();
- }
- }, {
- key: 'hide_tip',
- value: function hide_tip() {
- this.container.style.top = '0px';
- this.container.style.left = '0px';
- this.container.style.opacity = '0';
- }
- }, {
- key: 'show_tip',
- value: function show_tip() {
- this.container.style.top = this.top + 'px';
- this.container.style.left = this.left + 'px';
- this.container.style.opacity = '1';
- }
- }]);
- return SvgTip;
- }();
-
- return Chart;
-
- }());
- //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhcHBlLWNoYXJ0cy5taW4uanMiLCJzb3VyY2VzIjpbIi4uL3NyYy9kb20uanMiLCIuLi9zcmMvdXRpbHMuanMiLCIuLi9zcmMvY2hhcnRzLmpzIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uICQoZXhwciwgY29uKSB7XG5cdHJldHVybiB0eXBlb2YgZXhwciA9PT0gXCJzdHJpbmdcIj8gKGNvbiB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvcihleHByKSA6IGV4cHIgfHwgbnVsbDtcbn1cblxuJC5maW5kTm9kZUluZGV4ID0gKG5vZGUpID0+XG57XG5cdHZhciBpID0gMDtcblx0d2hpbGUgKG5vZGUucHJldmlvdXNTaWJsaW5nKSB7XG5cdFx0bm9kZSA9IG5vZGUucHJldmlvdXNTaWJsaW5nO1xuXHRcdGkrKztcblx0fVxuXHRyZXR1cm4gaTtcbn07XG5cbiQuY3JlYXRlID0gKHRhZywgbykgPT4ge1xuXHR2YXIgZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnQodGFnKTtcblxuXHRmb3IgKHZhciBpIGluIG8pIHtcblx0XHR2YXIgdmFsID0gb1tpXTtcblxuXHRcdGlmIChpID09PSBcImluc2lkZVwiKSB7XG5cdFx0XHQkKHZhbCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKGkgPT09IFwiYXJvdW5kXCIpIHtcblx0XHRcdHZhciByZWYgPSAkKHZhbCk7XG5cdFx0XHRyZWYucGFyZW50Tm9kZS5pbnNlcnRCZWZvcmUoZWxlbWVudCwgcmVmKTtcblx0XHRcdGVsZW1lbnQuYXBwZW5kQ2hpbGQocmVmKTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAoaSBpbiBlbGVtZW50KSB7XG5cdFx0XHRlbGVtZW50W2ldID0gdmFsO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGVsZW1lbnQuc2V0QXR0cmlidXRlKGksIHZhbCk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIGVsZW1lbnQ7XG59O1xuXG4kLmNyZWF0ZVNWRyA9ICh0YWcsIG8pID0+IHtcblx0dmFyIGVsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCB0YWcpO1xuXG5cdGZvciAodmFyIGkgaW4gbykge1xuXHRcdHZhciB2YWwgPSBvW2ldO1xuXG5cdFx0aWYgKGkgPT09IFwiaW5zaWRlXCIpIHtcblx0XHRcdCQodmFsKS5hcHBlbmRDaGlsZChlbGVtZW50KTtcblx0XHR9XG5cdFx0ZWxzZSBpZiAoaSA9PT0gXCJhcm91bmRcIikge1xuXHRcdFx0dmFyIHJlZiA9ICQodmFsKTtcblx0XHRcdHJlZi5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50LCByZWYpO1xuXHRcdFx0ZWxlbWVudC5hcHBlbmRDaGlsZChyZWYpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGlmKGkgPT09IFwiY2xhc3NOYW1lXCIpIHsgaSA9IFwiY2xhc3NcIjsgfVxuXHRcdFx0aWYoaSA9PT0gXCJpbm5lckhUTUxcIikge1xuXHRcdFx0XHRlbGVtZW50Wyd0ZXh0Q29udGVudCddID0gdmFsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoaSwgdmFsKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudDtcbn07XG5cbiQucnVuU1ZHQW5pbWF0aW9uID0gKHN2Z19jb250YWluZXIsIGVsZW1lbnRzKSA9PiB7XG5cdC8vIGxldCBwYXJlbnQgPSBlbGVtZW50c1swXVswXVsndW5pdCddLnBhcmVudE5vZGU7XG5cblx0bGV0IG5ld19lbGVtZW50cyA9IFtdO1xuXHRsZXQgYW5pbV9lbGVtZW50cyA9IFtdO1xuXG5cdGVsZW1lbnRzLm1hcChlbGVtZW50ID0+IHtcblx0XHRsZXQgb2JqID0gZWxlbWVudFswXTtcblx0XHRsZXQgcGFyZW50ID0gb2JqLnVuaXQucGFyZW50Tm9kZTtcblx0XHQvLyBsZXQgaW5kZXggPSBsZXQgZmluZE5vZGVJbmRleChvYmoudW5pdCk7XG5cblx0XHRsZXQgYW5pbV9lbGVtZW50LCBuZXdfZWxlbWVudDtcblxuXHRcdGVsZW1lbnRbMF0gPSBvYmoudW5pdDtcblxuXHRcdFthbmltX2VsZW1lbnQsIG5ld19lbGVtZW50XSA9ICQuYW5pbWF0ZVNWRyguLi5lbGVtZW50KTtcblxuXHRcdG5ld19lbGVtZW50cy5wdXNoKG5ld19lbGVtZW50KTtcblx0XHRhbmltX2VsZW1lbnRzLnB1c2goW2FuaW1fZWxlbWVudCwgcGFyZW50XSk7XG5cblx0XHRwYXJlbnQucmVwbGFjZUNoaWxkKGFuaW1fZWxlbWVudCwgb2JqLnVuaXQpO1xuXG5cdFx0aWYob2JqLmFycmF5KSB7XG5cdFx0XHRvYmouYXJyYXlbb2JqLmluZGV4XSA9IG5ld19lbGVtZW50O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRvYmoub2JqZWN0W29iai5rZXldID0gbmV3X2VsZW1lbnQ7XG5cdFx0fVxuXHR9KTtcblxuXHRsZXQgYW5pbV9zdmcgPSBzdmdfY29udGFpbmVyLmNsb25lTm9kZSh0cnVlKTtcblxuXHRhbmltX2VsZW1lbnRzLm1hcCgoYW5pbV9lbGVtZW50LCBpKSA9PiB7XG5cdFx0YW5pbV9lbGVtZW50WzFdLnJlcGxhY2VDaGlsZChuZXdfZWxlbWVudHNbaV0sIGFuaW1fZWxlbWVudFswXSk7XG5cdFx0ZWxlbWVudHNbaV1bMF0gPSBuZXdfZWxlbWVudHNbaV07XG5cdH0pO1xuXG5cdHJldHVybiBhbmltX3N2Zztcbn07XG5cbiQuYW5pbWF0ZVNWRyA9IChlbGVtZW50LCBwcm9wcywgZHVyLCBlYXNpbmdfdHlwZT1cImxpbmVhclwiLCB0eXBlPXVuZGVmaW5lZCwgb2xkX3ZhbHVlcz17fSkgPT4ge1xuXHRsZXQgZWFzaW5nID0ge1xuXHRcdGVhc2U6IFwiMC4yNSAwLjEgMC4yNSAxXCIsXG5cdFx0bGluZWFyOiBcIjAgMCAxIDFcIixcblx0XHQvLyBlYXNlaW46IFwiMC40MiAwIDEgMVwiLFxuXHRcdGVhc2VpbjogXCIwLjEgMC44IDAuMiAxXCIsXG5cdFx0ZWFzZW91dDogXCIwIDAgMC41OCAxXCIsXG5cdFx0ZWFzZWlub3V0OiBcIjAuNDIgMCAwLjU4IDFcIlxuXHR9O1xuXG5cdGxldCBhbmltX2VsZW1lbnQgPSBlbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcblx0bGV0IG5ld19lbGVtZW50ID0gZWxlbWVudC5jbG9uZU5vZGUodHJ1ZSk7XG5cblx0Zm9yKHZhciBhdHRyaWJ1dGVOYW1lIGluIHByb3BzKSB7XG5cdFx0bGV0IGFuaW1hdGVfZWxlbWVudDtcblx0XHRpZihhdHRyaWJ1dGVOYW1lID09PSAndHJhbnNmb3JtJykge1xuXHRcdFx0YW5pbWF0ZV9lbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgXCJhbmltYXRlVHJhbnNmb3JtXCIpO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRhbmltYXRlX2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcImFuaW1hdGVcIik7XG5cdFx0fVxuXHRcdGxldCBjdXJyZW50X3ZhbHVlID0gb2xkX3ZhbHVlc1thdHRyaWJ1dGVOYW1lXSB8fCBlbGVtZW50LmdldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lKTtcblx0XHRsZXQgdmFsdWUgPSBwcm9wc1thdHRyaWJ1dGVOYW1lXTtcblxuXHRcdGxldCBhbmltX2F0dHIgPSB7XG5cdFx0XHRhdHRyaWJ1dGVOYW1lOiBhdHRyaWJ1dGVOYW1lLFxuXHRcdFx0ZnJvbTogY3VycmVudF92YWx1ZSxcblx0XHRcdHRvOiB2YWx1ZSxcblx0XHRcdGJlZ2luOiBcIjBzXCIsXG5cdFx0XHRkdXI6IGR1ci8xMDAwICsgXCJzXCIsXG5cdFx0XHR2YWx1ZXM6IGN1cnJlbnRfdmFsdWUgKyBcIjtcIiArIHZhbHVlLFxuXHRcdFx0a2V5U3BsaW5lczogZWFzaW5nW2Vhc2luZ190eXBlXSxcblx0XHRcdGtleVRpbWVzOiBcIjA7MVwiLFxuXHRcdFx0Y2FsY01vZGU6IFwic3BsaW5lXCIsXG5cdFx0XHRmaWxsOiAnZnJlZXplJ1xuXHRcdH07XG5cblx0XHRpZih0eXBlKSB7XG5cdFx0XHRhbmltX2F0dHJbXCJ0eXBlXCJdID0gdHlwZTtcblx0XHR9XG5cblx0XHRmb3IgKHZhciBpIGluIGFuaW1fYXR0cikge1xuXHRcdFx0YW5pbWF0ZV9lbGVtZW50LnNldEF0dHJpYnV0ZShpLCBhbmltX2F0dHJbaV0pO1xuXHRcdH1cblxuXHRcdGFuaW1fZWxlbWVudC5hcHBlbmRDaGlsZChhbmltYXRlX2VsZW1lbnQpO1xuXG5cdFx0aWYodHlwZSkge1xuXHRcdFx0bmV3X2VsZW1lbnQuc2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUsIGB0cmFuc2xhdGUoJHt2YWx1ZX0pYCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdG5ld19lbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCB2YWx1ZSk7XG5cdFx0fVxuXHR9XG5cblx0cmV0dXJuIFthbmltX2VsZW1lbnQsIG5ld19lbGVtZW50XTtcbn07XG5cbiQub2Zmc2V0ID0gKGVsZW1lbnQpID0+IHtcblx0bGV0IHJlY3QgPSBlbGVtZW50LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXHRyZXR1cm4ge1xuXHRcdC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS83NDM2NjAyLzY0OTUwNDNcblx0XHQvLyByZWN0LnRvcCB2YXJpZXMgd2l0aCBzY3JvbGwsIHNvIHdlIGFkZCB3aGF0ZXZlciBoYXMgYmVlblxuXHRcdC8vIHNjcm9sbGVkIHRvIGl0IHRvIGdldCBhYnNvbHV0ZSBkaXN0YW5jZSBmcm9tIGFjdHVhbCBwYWdlIHRvcFxuXHRcdHRvcDogcmVjdC50b3AgKyAoZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50LnNjcm9sbFRvcCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbFRvcCksXG5cdFx0bGVmdDogcmVjdC5sZWZ0ICsgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxMZWZ0IHx8IGRvY3VtZW50LmJvZHkuc2Nyb2xsTGVmdClcblx0fTtcbn07XG5cbiQuaXNFbGVtZW50SW5WaWV3cG9ydCA9IChlbCkgPT4ge1xuXHQvLyBBbHRob3VnaCBzdHJhaWdodGZvcndhcmQ6IGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS83NTU3NDMzLzY0OTUwNDNcblx0dmFyIHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRyZXR1cm4gKFxuXHRcdHJlY3QudG9wID49IDAgJiZcbiAgICAgICAgcmVjdC5sZWZ0ID49IDAgJiZcbiAgICAgICAgcmVjdC5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJiAvKm9yICQod2luZG93KS5oZWlnaHQoKSAqL1xuICAgICAgICByZWN0LnJpZ2h0IDw9ICh3aW5kb3cuaW5uZXJXaWR0aCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpIC8qb3IgJCh3aW5kb3cpLndpZHRoKCkgKi9cblx0KTtcbn07XG5cbiQuYmluZCA9IChlbGVtZW50LCBvKSA9PiB7XG5cdGlmIChlbGVtZW50KSB7XG5cdFx0Zm9yICh2YXIgZXZlbnQgaW4gbykge1xuXHRcdFx0dmFyIGNhbGxiYWNrID0gb1tldmVudF07XG5cblx0XHRcdGV2ZW50LnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbiAoZXZlbnQpIHtcblx0XHRcdFx0ZWxlbWVudC5hZGRFdmVudExpc3RlbmVyKGV2ZW50LCBjYWxsYmFjayk7XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cbn07XG5cbiQudW5iaW5kID0gKGVsZW1lbnQsIG8pID0+IHtcblx0aWYgKGVsZW1lbnQpIHtcblx0XHRmb3IgKHZhciBldmVudCBpbiBvKSB7XG5cdFx0XHR2YXIgY2FsbGJhY2sgPSBvW2V2ZW50XTtcblxuXHRcdFx0ZXZlbnQuc3BsaXQoL1xccysvKS5mb3JFYWNoKGZ1bmN0aW9uKGV2ZW50KSB7XG5cdFx0XHRcdGVsZW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcihldmVudCwgY2FsbGJhY2spO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59O1xuXG4kLmZpcmUgPSAodGFyZ2V0LCB0eXBlLCBwcm9wZXJ0aWVzKSA9PiB7XG5cdHZhciBldnQgPSBkb2N1bWVudC5jcmVhdGVFdmVudChcIkhUTUxFdmVudHNcIik7XG5cblx0ZXZ0LmluaXRFdmVudCh0eXBlLCB0cnVlLCB0cnVlICk7XG5cblx0Zm9yICh2YXIgaiBpbiBwcm9wZXJ0aWVzKSB7XG5cdFx0ZXZ0W2pdID0gcHJvcGVydGllc1tqXTtcblx0fVxuXG5cdHJldHVybiB0YXJnZXQuZGlzcGF0Y2hFdmVudChldnQpO1xufTtcbiIsImV4cG9ydCBmdW5jdGlvbiBmbG9hdF8yKGQpIHtcblx0cmV0dXJuIHBhcnNlRmxvYXQoZC50b0ZpeGVkKDIpKTtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGFycmF5c19lcXVhbChhcnIxLCBhcnIyKSB7XG5cdGlmKGFycjEubGVuZ3RoICE9PSBhcnIyLmxlbmd0aCkgcmV0dXJuIGZhbHNlO1xuXHRsZXQgYXJlX2VxdWFsID0gdHJ1ZTtcblx0YXJyMS5tYXAoKGQsIGkpID0+IHtcblx0XHRpZihhcnIyW2ldICE9PSBkKSBhcmVfZXF1YWwgPSBmYWxzZTtcblx0fSk7XG5cdHJldHVybiBhcmVfZXF1YWw7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBzaHVmZmxlKGFycmF5KSB7XG5cdC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8yNDUwOTc2LzY0OTUwNDNcblx0Ly8gQXdlc29tZW5lc3M6IGh0dHBzOi8vYm9zdC5vY2tzLm9yZy9taWtlL3NodWZmbGUvXG5cblx0dmFyIGN1cnJlbnRJbmRleCA9IGFycmF5Lmxlbmd0aCwgdGVtcG9yYXJ5VmFsdWUsIHJhbmRvbUluZGV4O1xuXG5cdC8vIFdoaWxlIHRoZXJlIHJlbWFpbiBlbGVtZW50cyB0byBzaHVmZmxlLi4uXG5cdHdoaWxlICgwICE9PSBjdXJyZW50SW5kZXgpIHtcblxuXHRcdC8vIFBpY2sgYSByZW1haW5pbmcgZWxlbWVudC4uLlxuXHRcdHJhbmRvbUluZGV4ID0gTWF0aC5mbG9vcihNYXRoLnJhbmRvbSgpICogY3VycmVudEluZGV4KTtcblx0XHRjdXJyZW50SW5kZXggLT0gMTtcblxuXHRcdC8vIEFuZCBzd2FwIGl0IHdpdGggdGhlIGN1cnJlbnQgZWxlbWVudC5cblx0XHR0ZW1wb3JhcnlWYWx1ZSA9IGFycmF5W2N1cnJlbnRJbmRleF07XG5cdFx0YXJyYXlbY3VycmVudEluZGV4XSA9IGFycmF5W3JhbmRvbUluZGV4XTtcblx0XHRhcnJheVtyYW5kb21JbmRleF0gPSB0ZW1wb3JhcnlWYWx1ZTtcblx0fVxuXG5cdHJldHVybiBhcnJheTtcbn1cbiIsImltcG9ydCAkIGZyb20gJy4vZG9tJztcbmltcG9ydCB7IGZsb2F0XzIsIGFycmF5c19lcXVhbCB9IGZyb20gJy4vdXRpbHMnO1xuXG5leHBvcnQgZGVmYXVsdCBjbGFzcyBDaGFydCB7XG5cdGNvbnN0cnVjdG9yKHtcblx0XHRwYXJlbnQgPSBcIlwiLFxuXHRcdGhlaWdodCA9IDI0MCxcblxuXHRcdHRpdGxlID0gJycsIHN1YnRpdGxlID0gJycsXG5cblx0XHRkYXRhID0ge30sXG5cdFx0Zm9ybWF0X2xhbWJkYXMgPSB7fSxcblxuXHRcdHN1bW1hcnkgPSBbXSxcblxuXHRcdGlzX25hdmlnYWJsZSA9IDAsXG5cblx0XHR0eXBlID0gJydcblx0fSkge1xuXHRcdGlmKE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSA9PT0gQ2hhcnQucHJvdG90eXBlKSB7XG5cdFx0XHRpZih0eXBlID09PSAnbGluZScpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBMaW5lQ2hhcnQoYXJndW1lbnRzWzBdKTtcblx0XHRcdH0gZWxzZSBpZih0eXBlID09PSAnYmFyJykge1xuXHRcdFx0XHRyZXR1cm4gbmV3IEJhckNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ3BlcmNlbnRhZ2UnKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgUGVyY2VudGFnZUNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ2hlYXRtYXAnKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgSGVhdE1hcChhcmd1bWVudHNbMF0pO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBMaW5lQ2hhcnQoYXJndW1lbnRzWzBdKTtcblx0XHRcdH1cblx0XHR9XG5cblx0XHR0aGlzLnJhd19jaGFydF9hcmdzID0gYXJndW1lbnRzWzBdO1xuXG5cdFx0dGhpcy5wYXJlbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKHBhcmVudCk7XG5cdFx0dGhpcy50aXRsZSA9IHRpdGxlO1xuXHRcdHRoaXMuc3VidGl0bGUgPSBzdWJ0aXRsZTtcblxuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cdFx0dGhpcy5mb3JtYXRfbGFtYmRhcyA9IGZvcm1hdF9sYW1iZGFzO1xuXG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMgPSBkYXRhLnNwZWNpZmljX3ZhbHVlcyB8fCBbXTtcblx0XHR0aGlzLnN1bW1hcnkgPSBzdW1tYXJ5O1xuXG5cdFx0dGhpcy5pc19uYXZpZ2FibGUgPSBpc19uYXZpZ2FibGU7XG5cdFx0aWYodGhpcy5pc19uYXZpZ2FibGUpIHtcblx0XHRcdHRoaXMuY3VycmVudF9pbmRleCA9IDA7XG5cdFx0fVxuXG5cdFx0dGhpcy5jaGFydF90eXBlcyA9IFsnbGluZScsICdiYXInLCAncGVyY2VudGFnZScsICdoZWF0bWFwJ107XG5cblx0XHR0aGlzLnNldF9tYXJnaW5zKGhlaWdodCk7XG5cdH1cblxuXHRnZXRfZGlmZmVyZW50X2NoYXJ0KHR5cGUpIHtcblx0XHRpZighdGhpcy5jaGFydF90eXBlcy5pbmNsdWRlcyh0eXBlKSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGNoYXJ0IHR5cGUuYCk7XG5cdFx0fVxuXHRcdGlmKHR5cGUgPT09IHRoaXMudHlwZSkgcmV0dXJuO1xuXG5cdFx0Ly8gT25seSBhY3Jvc3MgY29tcGF0aWJsZSB0eXBlc1xuXHRcdGxldCBjb21wYXRpYmxlX3R5cGVzID0ge1xuXHRcdFx0YmFyOiBbJ2xpbmUnLCAncGVyY2VudGFnZSddLFxuXHRcdFx0bGluZTogWydiYXInLCAncGVyY2VudGFnZSddLFxuXHRcdFx0cGVyY2VudGFnZTogWydiYXInLCAnbGluZSddLFxuXHRcdFx0aGVhdG1hcDogW11cblx0XHR9O1xuXG5cdFx0aWYoIWNvbXBhdGlibGVfdHlwZXNbdGhpcy50eXBlXS5pbmNsdWRlcyh0eXBlKSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJyR7dGhpcy50eXBlfScgY2hhcnQgY2Fubm90IGJlIGNvbnZlcnRlZCB0byBhICcke3R5cGV9JyBjaGFydC5gKTtcblx0XHR9XG5cblx0XHQvLyBPa2F5LCB0aGlzIGlzIGFudGljbGltYWN0aWNcblx0XHQvLyB0aGlzIGZ1bmN0aW9uIHdpbGwgbmVlZCB0byBhY3R1YWxseSBiZSAnY2hhbmdlX2NoYXJ0X3R5cGUodHlwZSknXG5cdFx0Ly8gdGhhdCB3aWxsIHVwZGF0ZSBvbmx5IHRoZSByZXF1aXJlZCBlbGVtZW50cywgYnV0IGZvciBub3cgLi4uXG5cdFx0cmV0dXJuIG5ldyBDaGFydCh7XG5cdFx0XHRwYXJlbnQ6IHRoaXMucmF3X2NoYXJ0X2FyZ3MucGFyZW50LFxuXHRcdFx0ZGF0YTogdGhpcy5yYXdfY2hhcnRfYXJncy5kYXRhLFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGhlaWdodDogdGhpcy5yYXdfY2hhcnRfYXJncy5oZWlnaHRcblx0XHR9KTtcblx0fVxuXG5cdHNldF9tYXJnaW5zKGhlaWdodCkge1xuXHRcdHRoaXMuYmFzZV9oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQgLSA0MDtcblx0XHR0aGlzLnRyYW5zbGF0ZV94ID0gNjA7XG5cdFx0dGhpcy50cmFuc2xhdGVfeSA9IDEwO1xuXHR9XG5cblx0c2V0dXAoKSB7XG5cdFx0dGhpcy5iaW5kX3dpbmRvd19ldmVudHMoKTtcblx0XHR0aGlzLnJlZnJlc2godHJ1ZSk7XG5cdH1cblxuXHRiaW5kX3dpbmRvd19ldmVudHMoKSB7XG5cdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsICgpID0+IHRoaXMucmVmcmVzaCgpKTtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCAoKSA9PiB0aGlzLnJlZnJlc2goKSk7XG5cdH1cblxuXHRyZWZyZXNoKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLnNldHVwX2Jhc2VfdmFsdWVzKCk7XG5cdFx0dGhpcy5zZXRfd2lkdGgoKTtcblxuXHRcdHRoaXMuc2V0dXBfY29udGFpbmVyKCk7XG5cdFx0dGhpcy5zZXR1cF9jb21wb25lbnRzKCk7XG5cblx0XHR0aGlzLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMuc2V0dXBfdXRpbHMoKTtcblxuXHRcdHRoaXMubWFrZV9ncmFwaF9jb21wb25lbnRzKGluaXQpO1xuXHRcdHRoaXMubWFrZV90b29sdGlwKCk7XG5cblx0XHRpZih0aGlzLnN1bW1hcnkubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhpcy5zaG93X2N1c3RvbV9zdW1tYXJ5KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuc2hvd19zdW1tYXJ5KCk7XG5cdFx0fVxuXG5cdFx0aWYodGhpcy5pc19uYXZpZ2FibGUpIHtcblx0XHRcdHRoaXMuc2V0dXBfbmF2aWdhdGlvbihpbml0KTtcblx0XHR9XG5cdH1cblxuXHRzZXRfd2lkdGgoKSB7XG5cdFx0bGV0IHNwZWNpYWxfdmFsdWVzX3dpZHRoID0gMDtcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAodmFsID0+IHtcblx0XHRcdGlmKHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgPiBzcGVjaWFsX3ZhbHVlc193aWR0aCkge1xuXHRcdFx0XHRzcGVjaWFsX3ZhbHVlc193aWR0aCA9IHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgLSA0MDtcblx0XHRcdH1cblx0XHR9KTtcblx0XHR0aGlzLmJhc2Vfd2lkdGggPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHNwZWNpYWxfdmFsdWVzX3dpZHRoO1xuXHRcdHRoaXMud2lkdGggPSB0aGlzLmJhc2Vfd2lkdGggLSB0aGlzLnRyYW5zbGF0ZV94ICogMjtcblx0fVxuXG5cdHNldHVwX2Jhc2VfdmFsdWVzKCkge31cblxuXHRzZXR1cF9jb250YWluZXIoKSB7XG5cdFx0dGhpcy5jb250YWluZXIgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiAnY2hhcnQtY29udGFpbmVyJyxcblx0XHRcdGlubmVySFRNTDogYDxoNiBjbGFzcz1cInRpdGxlXCIgc3R5bGU9XCJtYXJnaW4tdG9wOiAxNXB4O1wiPiR7dGhpcy50aXRsZX08L2g2PlxuXHRcdFx0XHQ8aDYgY2xhc3M9XCJzdWItdGl0bGUgdXBwZXJjYXNlXCI+JHt0aGlzLnN1YnRpdGxlfTwvaDY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJmcmFwcGUtY2hhcnQgZ3JhcGhpY3NcIj48L2Rpdj5cblx0XHRcdFx0PGRpdiBjbGFzcz1cImdyYXBoLXN0YXRzLWNvbnRhaW5lclwiPjwvZGl2PmBcblx0XHR9KTtcblxuXHRcdC8vIENoYXJ0IG5lZWRzIGEgZGVkaWNhdGVkIHBhcmVudCBlbGVtZW50XG5cdFx0dGhpcy5wYXJlbnQuaW5uZXJIVE1MID0gJyc7XG5cdFx0dGhpcy5wYXJlbnQuYXBwZW5kQ2hpbGQodGhpcy5jb250YWluZXIpO1xuXG5cdFx0dGhpcy5jaGFydF93cmFwcGVyID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignLmZyYXBwZS1jaGFydCcpO1xuXHRcdHRoaXMuc3RhdHNfd3JhcHBlciA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5ncmFwaC1zdGF0cy1jb250YWluZXInKTtcblxuXHRcdHRoaXMubWFrZV9jaGFydF9hcmVhKCk7XG5cdFx0dGhpcy5tYWtlX2RyYXdfYXJlYSgpO1xuXHR9XG5cblx0bWFrZV9jaGFydF9hcmVhKCkge1xuXHRcdHRoaXMuc3ZnID0gJC5jcmVhdGVTVkcoJ3N2ZycsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2NoYXJ0Jyxcblx0XHRcdGluc2lkZTogdGhpcy5jaGFydF93cmFwcGVyLFxuXHRcdFx0d2lkdGg6IHRoaXMuYmFzZV93aWR0aCxcblx0XHRcdGhlaWdodDogdGhpcy5iYXNlX2hlaWdodFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5zdmdfZGVmcyA9ICQuY3JlYXRlU1ZHKCdkZWZzJywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnN2Zyxcblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLnN2Zztcblx0fVxuXG5cdG1ha2VfZHJhd19hcmVhKCkge1xuXHRcdHRoaXMuZHJhd19hcmVhID0gJC5jcmVhdGVTVkcoXCJnXCIsIHtcblx0XHRcdGNsYXNzTmFtZTogdGhpcy50eXBlICsgJy1jaGFydCcsXG5cdFx0XHRpbnNpZGU6IHRoaXMuc3ZnLFxuXHRcdFx0dHJhbnNmb3JtOiBgdHJhbnNsYXRlKCR7dGhpcy50cmFuc2xhdGVfeH0sICR7dGhpcy50cmFuc2xhdGVfeX0pYFxuXHRcdH0pO1xuXHR9XG5cblx0c2V0dXBfY29tcG9uZW50cygpIHsgfVxuXG5cdG1ha2VfdG9vbHRpcCgpIHtcblx0XHR0aGlzLnRpcCA9IG5ldyBTdmdUaXAoe1xuXHRcdFx0cGFyZW50OiB0aGlzLmNoYXJ0X3dyYXBwZXIsXG5cdFx0fSk7XG5cdFx0dGhpcy5iaW5kX3Rvb2x0aXAoKTtcblx0fVxuXG5cblx0c2hvd19zdW1tYXJ5KCkge31cblx0c2hvd19jdXN0b21fc3VtbWFyeSgpIHtcblx0XHR0aGlzLnN1bW1hcnkubWFwKGQgPT4ge1xuXHRcdFx0bGV0IHN0YXRzID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnc3RhdHMnLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3BhbiBjbGFzcz1cImluZGljYXRvciAke2QuY29sb3J9XCI+JHtkLnRpdGxlfTogJHtkLnZhbHVlfTwvc3Bhbj5gXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuc3RhdHNfd3JhcHBlci5hcHBlbmRDaGlsZChzdGF0cyk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF9uYXZpZ2F0aW9uKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLm1ha2Vfb3ZlcmxheSgpO1xuXG5cdFx0aWYoaW5pdCkge1xuXHRcdFx0dGhpcy5iaW5kX292ZXJsYXkoKTtcblxuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XG5cdFx0XHRcdGlmKCQuaXNFbGVtZW50SW5WaWV3cG9ydCh0aGlzLmNoYXJ0X3dyYXBwZXIpKSB7XG5cdFx0XHRcdFx0ZSA9IGUgfHwgd2luZG93LmV2ZW50O1xuXG5cdFx0XHRcdFx0aWYgKGUua2V5Q29kZSA9PSAnMzcnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX2xlZnRfYXJyb3coKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSAnMzknKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX3JpZ2h0X2Fycm93KCk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChlLmtleUNvZGUgPT0gJzM4Jykge1xuXHRcdFx0XHRcdFx0dGhpcy5vbl91cF9hcnJvdygpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZS5rZXlDb2RlID09ICc0MCcpIHtcblx0XHRcdFx0XHRcdHRoaXMub25fZG93bl9hcnJvdygpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZS5rZXlDb2RlID09ICcxMycpIHtcblx0XHRcdFx0XHRcdHRoaXMub25fZW50ZXJfa2V5KCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9XG5cdH1cblxuXHRtYWtlX292ZXJsYXkoKSB7fVxuXHRiaW5kX292ZXJsYXkoKSB7fVxuXG5cdG9uX2xlZnRfYXJyb3coKSB7fVxuXHRvbl9yaWdodF9hcnJvdygpIHt9XG5cdG9uX3VwX2Fycm93KCkge31cblx0b25fZG93bl9hcnJvdygpIHt9XG5cdG9uX2VudGVyX2tleSgpIHt9XG5cblx0Z2V0X2RhdGFfcG9pbnQoaW5kZXg9dGhpcy5jdXJyZW50X2luZGV4KSB7XG5cdFx0Ly8gY2hlY2sgZm9yIGxlbmd0aFxuXHRcdGxldCBkYXRhX3BvaW50ID0ge1xuXHRcdFx0aW5kZXg6IGluZGV4XG5cdFx0fTtcblx0XHRsZXQgeSA9IHRoaXMueVswXTtcblx0XHRbJ3N2Z191bml0cycsICd5X3RvcHMnLCAndmFsdWVzJ10ubWFwKGtleSA9PiB7XG5cdFx0XHRsZXQgZGF0YV9rZXkgPSBrZXkuc2xpY2UoMCwga2V5Lmxlbmd0aC0xKTtcblx0XHRcdGRhdGFfcG9pbnRbZGF0YV9rZXldID0geVtrZXldW2luZGV4XTtcblx0XHR9KTtcblx0XHRkYXRhX3BvaW50LmxhYmVsID0gdGhpcy54W2luZGV4XTtcblx0XHRyZXR1cm4gZGF0YV9wb2ludDtcblx0fVxuXG5cdHVwZGF0ZV9jdXJyZW50X2RhdGFfcG9pbnQoaW5kZXgpIHtcblx0XHRpZihpbmRleCA8IDApIGluZGV4ID0gMDtcblx0XHRpZihpbmRleCA+PSB0aGlzLngubGVuZ3RoKSBpbmRleCA9IHRoaXMueC5sZW5ndGggLSAxO1xuXHRcdGlmKGluZGV4ID09PSB0aGlzLmN1cnJlbnRfaW5kZXgpIHJldHVybjtcblx0XHR0aGlzLmN1cnJlbnRfaW5kZXggPSBpbmRleDtcblx0XHQkLmZpcmUodGhpcy5wYXJlbnQsIFwiZGF0YS1zZWxlY3RcIiwgdGhpcy5nZXRfZGF0YV9wb2ludCgpKTtcblx0fVxuXG5cdC8vIEhlbHBlcnNcblx0Z2V0X3N0cndpZHRoKHN0cmluZykge1xuXHRcdHJldHVybiBzdHJpbmcubGVuZ3RoICogODtcblx0fVxuXG5cdC8vIE9iamVjdHNcblx0c2V0dXBfdXRpbHMoKSB7IH1cbn1cblxuY2xhc3MgQXhpc0NoYXJ0IGV4dGVuZHMgQ2hhcnQge1xuXHRjb25zdHJ1Y3RvcihhcmdzKSB7XG5cdFx0c3VwZXIoYXJncyk7XG5cblx0XHR0aGlzLnggPSB0aGlzLmRhdGEubGFiZWxzO1xuXHRcdHRoaXMueSA9IHRoaXMuZGF0YS5kYXRhc2V0cztcblxuXHRcdHRoaXMuZ2V0X3lfbGFiZWwgPSB0aGlzLmZvcm1hdF9sYW1iZGFzLnlfbGFiZWw7XG5cdFx0dGhpcy5nZXRfeV90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X3Rvb2x0aXA7XG5cdFx0dGhpcy5nZXRfeF90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy54X3Rvb2x0aXA7XG5cblx0XHR0aGlzLmNvbG9ycyA9IFsnZ3JlZW4nLCAnYmx1ZScsICd2aW9sZXQnLCAncmVkJywgJ29yYW5nZScsXG5cdFx0XHQneWVsbG93JywgJ2xpZ2h0LWJsdWUnLCAnbGlnaHQtZ3JlZW4nLCAncHVycGxlJywgJ21hZ2VudGEnXTtcblxuXHRcdHRoaXMuemVyb19saW5lID0gdGhpcy5oZWlnaHQ7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5kYXRhLmRhdGFzZXRzLm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzID0gZC52YWx1ZXMubWFwKHZhbCA9PiAoIWlzTmFOKHZhbCkgPyB2YWwgOiAwKSk7XG5cdFx0fSk7XG5cdFx0dGhpcy5zZXR1cF94KCk7XG5cdFx0dGhpcy5zZXR1cF95KCk7XG5cdH1cblxuXHRzZXR1cF94KCkge1xuXHRcdHRoaXMuc2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpO1xuXG5cdFx0aWYodGhpcy54X2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gIHRoaXMueF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXHRcdH1cblx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMgPSB0aGlzLngubWFwKChkLCBpKSA9PlxuXHRcdFx0ZmxvYXRfMih0aGlzLnhfb2Zmc2V0ICsgaSAqIHRoaXMuYXZnX3VuaXRfd2lkdGgpKTtcblxuXHRcdGlmKCF0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gdGhpcy54X2F4aXNfcG9zaXRpb25zLnNsaWNlKCk7XG5cdFx0fVxuXHR9XG5cblx0c2V0dXBfeSgpIHtcblx0XHRpZih0aGlzLnlfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSAgdGhpcy55X2F4aXNfdmFsdWVzLnNsaWNlKCk7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlcyA9IHRoaXMuZ2V0X2FsbF95X3ZhbHVlcygpO1xuXG5cdFx0aWYodGhpcy55X3N1bXMgJiYgdGhpcy55X3N1bXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dmFsdWVzID0gdmFsdWVzLmNvbmNhdCh0aGlzLnlfc3Vtcyk7XG5cdFx0fVxuXG5cdFx0dGhpcy55X2F4aXNfdmFsdWVzID0gdGhpcy5nZXRfeV9heGlzX3BvaW50cyh2YWx1ZXMpO1xuXG5cdFx0aWYoIXRoaXMueV9vbGRfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSB0aGlzLnlfYXhpc192YWx1ZXMuc2xpY2UoKTtcblx0XHR9XG5cblx0XHRjb25zdCB5X3B0cyA9IHRoaXMueV9heGlzX3ZhbHVlcztcblx0XHRjb25zdCB2YWx1ZV9yYW5nZSA9IHlfcHRzW3lfcHRzLmxlbmd0aC0xXSAtIHlfcHRzWzBdO1xuXG5cdFx0aWYodGhpcy5tdWx0aXBsaWVyKSB0aGlzLm9sZF9tdWx0aXBsaWVyID0gdGhpcy5tdWx0aXBsaWVyO1xuXHRcdHRoaXMubXVsdGlwbGllciA9IHRoaXMuaGVpZ2h0IC8gdmFsdWVfcmFuZ2U7XG5cdFx0aWYoIXRoaXMub2xkX211bHRpcGxpZXIpIHRoaXMub2xkX211bHRpcGxpZXIgPSB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRjb25zdCB6ZXJvX2luZGV4ID0geV9wdHMuaW5kZXhPZigwKTtcblx0XHRjb25zdCBpbnRlcnZhbCA9IHlfcHRzWzFdIC0geV9wdHNbMF07XG5cdFx0Y29uc3QgaW50ZXJ2YWxfaGVpZ2h0ID0gaW50ZXJ2YWwgKiB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRpZih0aGlzLnplcm9fbGluZSkgdGhpcy5vbGRfemVyb19saW5lID0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0dGhpcy56ZXJvX2xpbmUgPSB0aGlzLmhlaWdodCAtICh6ZXJvX2luZGV4ICogaW50ZXJ2YWxfaGVpZ2h0KTtcblx0XHRpZighdGhpcy5vbGRfemVyb19saW5lKSB0aGlzLm9sZF96ZXJvX2xpbmUgPSB0aGlzLnplcm9fbGluZTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0c3VwZXIuc2V0dXBfY29tcG9uZW50cygpO1xuXHRcdHRoaXMuc2V0dXBfbWFya2VyX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2FnZ3JlZ2F0aW9uX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX21hcmtlcl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMueV9heGlzX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAneSBheGlzJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHRcdHRoaXMueF9heGlzX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAneCBheGlzJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHRcdHRoaXMuc3BlY2lmaWNfeV9ncm91cCA9ICQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ3NwZWNpZmljIGF4aXMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdH1cblxuXHRzZXR1cF9hZ2dyZWdhdGlvbl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMuc3VtX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAnZGF0YS1wb2ludHMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdFx0dGhpcy5hdmVyYWdlX2dyb3VwID0gJC5jcmVhdGVTVkcoJ2cnLCB7Y2xhc3NOYW1lOiAnY2hhcnQtYXJlYScsIGluc2lkZTogdGhpcy5kcmF3X2FyZWF9KTtcblx0fVxuXG5cdHNldHVwX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5zdmdfdW5pdHNfZ3JvdXBzID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0dGhpcy5zdmdfdW5pdHNfZ3JvdXBzW2ldID0gJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogJ2RhdGEtcG9pbnRzIGRhdGEtcG9pbnRzLScgKyBpLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfZ3JhcGhfY29tcG9uZW50cyhpbml0PWZhbHNlKSB7XG5cdFx0dGhpcy5tYWtlX3lfYXhpcygpO1xuXHRcdHRoaXMubWFrZV94X2F4aXMoKTtcblx0XHR0aGlzLmRyYXdfZ3JhcGgoaW5pdCk7XG5cdFx0dGhpcy5tYWtlX3lfc3BlY2lmaWNzKCk7XG5cdH1cblxuXHQvLyBtYWtlIFZFUlRJQ0FMIGxpbmVzIGZvciB4IHZhbHVlc1xuXHRtYWtlX3hfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0bGV0IHN0YXJ0X2F0LCBoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyA9ICcnO1xuXHRcdGlmKHRoaXMueF9heGlzX21vZGUgPT09ICdzcGFuJykge1x0XHQvLyBsb25nIHNwYW5uaW5nIGxpbmVzXG5cdFx0XHRzdGFydF9hdCA9IC03O1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAxNTtcblx0XHRcdHRleHRfc3RhcnRfYXQgPSB0aGlzLmhlaWdodCArIDI1O1xuXHRcdH0gZWxzZSBpZih0aGlzLnhfYXhpc19tb2RlID09PSAndGljaycpe1x0Ly8gc2hvcnQgbGFiZWwgbGluZXNcblx0XHRcdHN0YXJ0X2F0ID0gdGhpcy5oZWlnaHQ7XG5cdFx0XHRoZWlnaHQgPSA2O1xuXHRcdFx0dGV4dF9zdGFydF9hdCA9IDk7XG5cdFx0XHRheGlzX2xpbmVfY2xhc3MgPSAneC1heGlzLWxhYmVsJztcblx0XHR9XG5cblx0XHR0aGlzLnhfYXhpc19ncm91cC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoMCwke3N0YXJ0X2F0fSlgKTtcblxuXHRcdGlmKGFuaW1hdGUpIHtcblx0XHRcdHRoaXMubWFrZV9hbmltX3hfYXhpcyhoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLngubWFwKChwb2ludCwgaSkgPT4ge1xuXHRcdFx0dGhpcy54X2F4aXNfZ3JvdXAuYXBwZW5kQ2hpbGQoXG5cdFx0XHRcdHRoaXMubWFrZV94X2xpbmUoXG5cdFx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHRcdHRleHRfc3RhcnRfYXQsXG5cdFx0XHRcdFx0cG9pbnQsXG5cdFx0XHRcdFx0J3gtdmFsdWUtdGV4dCcsXG5cdFx0XHRcdFx0YXhpc19saW5lX2NsYXNzLFxuXHRcdFx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpXVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gbWFrZSBIT1JJWk9OVEFMIGxpbmVzIGZvciB5IHZhbHVlc1xuXHRtYWtlX3lfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0aWYoYW5pbWF0ZSkge1xuXHRcdFx0dGhpcy5tYWtlX2FuaW1feV9heGlzKCk7XG5cdFx0XHR0aGlzLm1ha2VfYW5pbV95X3NwZWNpZmljcygpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XSA9IHRoaXMuZ2V0X3lfYXhpc19saW5lX3Byb3BzKCk7XG5cblx0XHR0aGlzLnlfYXhpc19ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMueV9heGlzX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHR0aGlzLnlfYXhpc19ncm91cC5hcHBlbmRDaGlsZChcblx0XHRcdFx0dGhpcy5tYWtlX3lfbGluZShcblx0XHRcdFx0XHRzdGFydF9hdCxcblx0XHRcdFx0XHR3aWR0aCxcblx0XHRcdFx0XHR0ZXh0X2VuZF9hdCxcblx0XHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0XHQneS12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCkgLy8gTm9uLWZpcnN0IFplcm8gbGluZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19saW5lX3Byb3BzKHNwZWNpZmljPWZhbHNlKSB7XG5cdFx0aWYoc3BlY2lmaWMpIHtcblx0XHRcdHJldHVyblt0aGlzLndpZHRoLCB0aGlzLndpZHRoICsgNSwgJ3NwZWNpZmljLXZhbHVlJywgMF07XG5cdFx0fVxuXHRcdGxldCB3aWR0aCwgdGV4dF9lbmRfYXQgPSAtOSwgYXhpc19saW5lX2NsYXNzID0gJycsIHN0YXJ0X2F0ID0gMDtcblx0XHRpZih0aGlzLnlfYXhpc19tb2RlID09PSAnc3BhbicpIHtcdFx0Ly8gbG9uZyBzcGFubmluZyBsaW5lc1xuXHRcdFx0d2lkdGggPSB0aGlzLndpZHRoICsgNjtcblx0XHRcdHN0YXJ0X2F0ID0gLTY7XG5cdFx0fSBlbHNlIGlmKHRoaXMueV9heGlzX21vZGUgPT09ICd0aWNrJyl7XHQvLyBzaG9ydCBsYWJlbCBsaW5lc1xuXHRcdFx0d2lkdGggPSAtNjtcblx0XHRcdGF4aXNfbGluZV9jbGFzcyA9ICd5LWF4aXMtbGFiZWwnO1xuXHRcdH1cblxuXHRcdHJldHVybiBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XTtcblx0fVxuXG5cdGRyYXdfZ3JhcGgoaW5pdD1mYWxzZSkge1xuXHRcdGlmKGluaXQpIHtcblx0XHRcdHRoaXMuZHJhd19uZXdfZ3JhcGhfYW5kX2FuaW1hdGUoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0ZC5zdmdfdW5pdHMgPSBbXTtcblx0XHRcdHRoaXMubWFrZV9wYXRoICYmIHRoaXMubWFrZV9wYXRoKGQsIGksIHRoaXMueF9heGlzX3Bvc2l0aW9ucywgZC55X3RvcHMsIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0pO1xuXHRcdFx0dGhpcy5tYWtlX25ld191bml0cyhkLCBpKTtcblx0XHR9KTtcblx0fVxuXG5cdGRyYXdfbmV3X2dyYXBoX2FuZF9hbmltYXRlKCkge1xuXHRcdGxldCBkYXRhID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0Ly8gQW5pbTogRG9uJ3QgZHJhdyBpbml0aWFsIHZhbHVlcywgc3RvcmUgdGhlbSBhbmQgdXBkYXRlIGxhdGVyXG5cdFx0XHRkLnlfdG9wcyA9IG5ldyBBcnJheShkLnZhbHVlcy5sZW5ndGgpLmZpbGwodGhpcy56ZXJvX2xpbmUpOyAvLyBubyB2YWx1ZVxuXHRcdFx0ZGF0YS5wdXNoKHt2YWx1ZXM6IGQudmFsdWVzfSk7XG5cdFx0XHRkLnN2Z191bml0cyA9IFtdO1xuXG5cdFx0XHR0aGlzLm1ha2VfcGF0aCAmJiB0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHMoZCwgaSk7XG5cdFx0fSk7XG5cblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhkYXRhKTtcblx0XHR9LCAzNTApO1xuXHR9XG5cblx0c2V0dXBfbmF2aWdhdGlvbihpbml0KSB7XG5cdFx0Ly8gSGFjazogZGVmZXIgbmF2IHRpbGwgaW5pdGlhbCB1cGRhdGVfdmFsdWVzXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRzdXBlci5zZXR1cF9uYXZpZ2F0aW9uKGluaXQpO1xuXHRcdH0sIDUwMCk7XG5cdH1cblxuXHRtYWtlX25ld191bml0cyhkLCBpKSB7XG5cdFx0dGhpcy5tYWtlX25ld191bml0c19mb3JfZGF0YXNldChcblx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9ucyxcblx0XHRcdGQueV90b3BzLFxuXHRcdFx0ZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSxcblx0XHRcdGksXG5cdFx0XHR0aGlzLnkubGVuZ3RoXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfbmV3X3VuaXRzX2Zvcl9kYXRhc2V0KHhfdmFsdWVzLCB5X3ZhbHVlcywgY29sb3IsIGRhdGFzZXRfaW5kZXgsIG5vX29mX2RhdGFzZXRzLCBncm91cCwgYXJyYXksIHVuaXQpIHtcblx0XHRpZighZ3JvdXApIGdyb3VwID0gdGhpcy5zdmdfdW5pdHNfZ3JvdXBzW2RhdGFzZXRfaW5kZXhdO1xuXHRcdGlmKCFhcnJheSkgYXJyYXkgPSB0aGlzLnlbZGF0YXNldF9pbmRleF0uc3ZnX3VuaXRzO1xuXHRcdGlmKCF1bml0KSB1bml0ID0gdGhpcy51bml0X2FyZ3M7XG5cblx0XHRncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdGFycmF5Lmxlbmd0aCA9IDA7XG5cblx0XHR5X3ZhbHVlcy5tYXAoKHksIGkpID0+IHtcblx0XHRcdGxldCBkYXRhX3VuaXQgPSB0aGlzLmRyYXdbdW5pdC50eXBlXShcblx0XHRcdFx0eF92YWx1ZXNbaV0sXG5cdFx0XHRcdHksXG5cdFx0XHRcdHVuaXQuYXJncyxcblx0XHRcdFx0Y29sb3IsXG5cdFx0XHRcdGRhdGFzZXRfaW5kZXgsXG5cdFx0XHRcdG5vX29mX2RhdGFzZXRzXG5cdFx0XHQpO1xuXHRcdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoZGF0YV91bml0KTtcblx0XHRcdGFycmF5LnB1c2goZGF0YV91bml0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfeV9zcGVjaWZpY3MoKSB7XG5cdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4ge1xuXHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLmFwcGVuZENoaWxkKFxuXHRcdFx0XHR0aGlzLm1ha2VfeV9saW5lKFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0dGhpcy53aWR0aCxcblx0XHRcdFx0XHR0aGlzLndpZHRoICsgNSxcblx0XHRcdFx0XHRkLnRpdGxlLnRvVXBwZXJDYXNlKCksXG5cdFx0XHRcdFx0J3NwZWNpZmljLXZhbHVlJyxcblx0XHRcdFx0XHQnc3BlY2lmaWMtdmFsdWUnLFxuXHRcdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0XHRkLmxpbmVfdHlwZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YmluZF90b29sdGlwKCkge1xuXHRcdC8vIFRPRE86IGNvdWxkIGJlIGluIHRvb2x0aXAgaXRzZWxmLCBhcyBpdCBpcyBhIGdpdmVuIGZ1bmN0aW9uYWxpdHkgZm9yIGl0cyBwYXJlbnRcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcblx0XHRcdGxldCBvZmZzZXQgPSAkLm9mZnNldCh0aGlzLmNoYXJ0X3dyYXBwZXIpO1xuXHRcdFx0bGV0IHJlbFggPSBlLnBhZ2VYIC0gb2Zmc2V0LmxlZnQgLSB0aGlzLnRyYW5zbGF0ZV94O1xuXHRcdFx0bGV0IHJlbFkgPSBlLnBhZ2VZIC0gb2Zmc2V0LnRvcCAtIHRoaXMudHJhbnNsYXRlX3k7XG5cblx0XHRcdGlmKHJlbFkgPCB0aGlzLmhlaWdodCArIHRoaXMudHJhbnNsYXRlX3kgKiAyKSB7XG5cdFx0XHRcdHRoaXMubWFwX3Rvb2x0aXBfeF9wb3NpdGlvbl9hbmRfc2hvdyhyZWxYKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHRoaXMudGlwLmhpZGVfdGlwKCk7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cblxuXHRtYXBfdG9vbHRpcF94X3Bvc2l0aW9uX2FuZF9zaG93KHJlbFgpIHtcblx0XHRmb3IodmFyIGk9dGhpcy54X2F4aXNfcG9zaXRpb25zLmxlbmd0aCAtIDE7IGkgPj0gMCA7IGktLSkge1xuXHRcdFx0bGV0IHhfdmFsID0gdGhpcy54X2F4aXNfcG9zaXRpb25zW2ldO1xuXHRcdFx0Ly8gbGV0IGRlbHRhID0gaSA9PT0gMCA/IHRoaXMuYXZnX3VuaXRfd2lkdGggOiB4X3ZhbCAtIHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpLTFdO1xuXHRcdFx0aWYocmVsWCA+IHhfdmFsIC0gdGhpcy5hdmdfdW5pdF93aWR0aC8yKSB7XG5cdFx0XHRcdGxldCB4ID0geF92YWwgKyB0aGlzLnRyYW5zbGF0ZV94O1xuXHRcdFx0XHRsZXQgeSA9IHRoaXMueV9taW5fdG9wc1tpXSArIHRoaXMudHJhbnNsYXRlX3k7XG5cblx0XHRcdFx0bGV0IHRpdGxlID0gdGhpcy54LmZvcm1hdHRlZCAmJiB0aGlzLnguZm9ybWF0dGVkLmxlbmd0aD4wXG5cdFx0XHRcdFx0PyB0aGlzLnguZm9ybWF0dGVkW2ldIDogdGhpcy54W2ldO1xuXHRcdFx0XHRsZXQgdmFsdWVzID0gdGhpcy55Lm1hcCgoc2V0LCBqKSA9PiB7XG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdHRpdGxlOiBzZXQudGl0bGUsXG5cdFx0XHRcdFx0XHR2YWx1ZTogc2V0LmZvcm1hdHRlZCA/IHNldC5mb3JtYXR0ZWRbaV0gOiBzZXQudmFsdWVzW2ldLFxuXHRcdFx0XHRcdFx0Y29sb3I6IHNldC5jb2xvciB8fCB0aGlzLmNvbG9yc1tqXSxcblx0XHRcdFx0XHR9O1xuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHQvLyBUT0RPOiB1cHNpZGUtZG93biB0b29sdGlwcyBmb3IgbmVnYXRpdmUgdmFsdWVzP1xuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIHRpdGxlLCAnJywgdmFsdWVzKTtcblx0XHRcdFx0dGhpcy50aXAuc2hvd190aXAoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQVBJXG5cdHNob3dfc3VtcygpIHtcblx0XHR0aGlzLnVwZGF0aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMueV9zdW1zID0gbmV3IEFycmF5KHRoaXMueF9heGlzX3Bvc2l0aW9ucy5sZW5ndGgpLmZpbGwoMCk7XG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzLm1hcCggKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdHRoaXMueV9zdW1zW2ldICs9IHZhbHVlO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHQvLyBSZW1ha2UgeSBheGlzLCBhbmltYXRlXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cblx0XHQvLyBUaGVuIG1ha2Ugc3VtIHVuaXRzLCBkb24ndCBhbmltYXRlXG5cdFx0dGhpcy5zdW1fdW5pdHMgPSBbXTtcblxuXHRcdHRoaXMubWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQoXG5cdFx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMsXG5cdFx0XHR0aGlzLnlfc3Vtcy5tYXAoIHZhbCA9PiBmbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSksXG5cdFx0XHQnbGlnaHQtZ3JleScsXG5cdFx0XHQwLFxuXHRcdFx0MSxcblx0XHRcdHRoaXMuc3VtX2dyb3VwLFxuXHRcdFx0dGhpcy5zdW1fdW5pdHNcblx0XHQpO1xuXG5cdFx0Ly8gdGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblxuXHRcdHRoaXMudXBkYXRpbmcgPSBmYWxzZTtcblx0fVxuXG5cdGhpZGVfc3VtcygpIHtcblx0XHRpZih0aGlzLnVwZGF0aW5nKSByZXR1cm47XG5cdFx0dGhpcy55X3N1bXMgPSBbXTtcblx0XHR0aGlzLnN1bV9ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMuc3VtX3VuaXRzID0gW107XG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cdH1cblxuXHRzaG93X2F2ZXJhZ2UoKSB7XG5cdFx0dGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzID0gdGhpcy5zcGVjaWZpY192YWx1ZXMuc2xpY2UoKTtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRsZXQgc3VtID0gMDtcblx0XHRcdGQudmFsdWVzLm1hcChlID0+IHtzdW0rPWU7fSk7XG5cdFx0XHRsZXQgYXZlcmFnZSA9IHN1bS9kLnZhbHVlcy5sZW5ndGg7XG5cblx0XHRcdHRoaXMuc3BlY2lmaWNfdmFsdWVzLnB1c2goe1xuXHRcdFx0XHR0aXRsZTogXCJBVkdcIiArIFwiIFwiICsgKGkrMSksXG5cdFx0XHRcdGxpbmVfdHlwZTogXCJkYXNoZWRcIixcblx0XHRcdFx0dmFsdWU6IGF2ZXJhZ2UsXG5cdFx0XHRcdGF1dG86IDFcblx0XHRcdH0pO1xuXHRcdH0pO1xuXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cdH1cblxuXHRoaWRlX2F2ZXJhZ2UoKSB7XG5cdFx0dGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzID0gdGhpcy5zcGVjaWZpY192YWx1ZXMuc2xpY2UoKTtcblxuXHRcdGxldCBpbmRpY2VzX3RvX3JlbW92ZSA9IFtdO1xuXHRcdHRoaXMuc3BlY2lmaWNfdmFsdWVzLm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0aWYoZC5hdXRvKSBpbmRpY2VzX3RvX3JlbW92ZS51bnNoaWZ0KGkpO1xuXHRcdH0pO1xuXG5cdFx0aW5kaWNlc190b19yZW1vdmUubWFwKGluZGV4ID0+IHtcblx0XHRcdHRoaXMuc3BlY2lmaWNfdmFsdWVzLnNwbGljZShpbmRleCwgMSk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLnVwZGF0ZV92YWx1ZXMoKTtcblx0fVxuXG5cdHVwZGF0ZV92YWx1ZXMobmV3X3ksIG5ld194KSB7XG5cdFx0aWYoIW5ld194KSB7XG5cdFx0XHRuZXdfeCA9IHRoaXMueDtcblx0XHR9XG5cdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlID0gW107XG5cdFx0dGhpcy51cGRhdGluZyA9IHRydWU7XG5cblx0XHR0aGlzLm9sZF94X3ZhbHVlcyA9IHRoaXMueC5zbGljZSgpO1xuXHRcdHRoaXMub2xkX3lfYXhpc190b3BzID0gdGhpcy55Lm1hcChkID0+IGQueV90b3BzLnNsaWNlKCkpO1xuXG5cdFx0dGhpcy5vbGRfeV92YWx1ZXMgPSB0aGlzLnkubWFwKGQgPT4gZC52YWx1ZXMpO1xuXG5cdFx0dGhpcy5ub19vZl9leHRyYV9wdHMgPSBuZXdfeC5sZW5ndGggLSB0aGlzLngubGVuZ3RoO1xuXG5cdFx0Ly8gSnVzdCB1cGRhdGUgdmFsdWVzIHByb3AsIHNldHVwX3gveSgpIHdpbGwgZG8gdGhlIHJlc3Rcblx0XHRpZihuZXdfeSkgdGhpcy55Lm1hcCgoZCwgaSkgPT4ge2QudmFsdWVzID0gbmV3X3lbaV0udmFsdWVzO30pO1xuXHRcdGlmKG5ld194KSB0aGlzLnggPSBuZXdfeDtcblxuXHRcdHRoaXMuc2V0dXBfeCgpO1xuXHRcdHRoaXMuc2V0dXBfeSgpO1xuXG5cdFx0Ly8gQW5pbWF0ZSBvbmx5IGlmIHBvc2l0aW9ucyBoYXZlIGNoYW5nZWRcblx0XHRpZighYXJyYXlzX2VxdWFsKHRoaXMueF9vbGRfYXhpc19wb3NpdGlvbnMsIHRoaXMueF9heGlzX3Bvc2l0aW9ucykpIHtcblx0XHRcdHRoaXMubWFrZV94X2F4aXModHJ1ZSk7XG5cdFx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdFx0aWYoIXRoaXMudXBkYXRpbmcpIHRoaXMubWFrZV94X2F4aXMoKTtcblx0XHRcdH0sIDMwMCk7XG5cdFx0fVxuXG5cdFx0aWYoIWFycmF5c19lcXVhbCh0aGlzLnlfb2xkX2F4aXNfdmFsdWVzLCB0aGlzLnlfYXhpc192YWx1ZXMpIHx8XG5cdFx0XHQodGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzICYmXG5cdFx0XHQhYXJyYXlzX2VxdWFsKHRoaXMub2xkX3NwZWNpZmljX3ZhbHVlcywgdGhpcy5zcGVjaWZpY192YWx1ZXMpKSkge1xuXG5cdFx0XHR0aGlzLm1ha2VfeV9heGlzKHRydWUpO1xuXHRcdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRcdGlmKCF0aGlzLnVwZGF0aW5nKSB7XG5cdFx0XHRcdFx0dGhpcy5tYWtlX3lfYXhpcygpO1xuXHRcdFx0XHRcdHRoaXMubWFrZV95X3NwZWNpZmljcygpO1xuXHRcdFx0XHR9XG5cdFx0XHR9LCAzMDApO1xuXHRcdH1cblxuXHRcdC8vIENoYW5nZSBpbiBkYXRhLCBzbyBjYWxjdWxhdGUgZGVwZW5kZW5jaWVzXG5cdFx0dGhpcy5jYWxjX3lfZGVwZW5kZW5jaWVzKCk7XG5cblx0XHR0aGlzLmFuaW1hdGVfZ3JhcGhzKCk7XG5cblx0XHQvLyBUcmlnZ2VyIGFuaW1hdGlvbiB3aXRoIHRoZSBhbmltYXRhYmxlIGVsZW1lbnRzIGluIHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZVxuXHRcdHRoaXMucnVuX2FuaW1hdGlvbigpO1xuXG5cdFx0dGhpcy51cGRhdGluZyA9IGZhbHNlO1xuXHR9XG5cblx0YWRkX2RhdGFfcG9pbnQoeV9wb2ludCwgeF9wb2ludCwgaW5kZXg9dGhpcy54Lmxlbmd0aCkge1xuXHRcdGxldCBuZXdfeSA9IHRoaXMueS5tYXAoZGF0YV9zZXQgPT4geyByZXR1cm4ge3ZhbHVlczpkYXRhX3NldC52YWx1ZXN9OyB9KTtcblx0XHRuZXdfeS5tYXAoKGQsIGkpID0+IHsgZC52YWx1ZXMuc3BsaWNlKGluZGV4LCAwLCB5X3BvaW50W2ldKTsgfSk7XG5cdFx0bGV0IG5ld194ID0gdGhpcy54LnNsaWNlKCk7XG5cdFx0bmV3X3guc3BsaWNlKGluZGV4LCAwLCB4X3BvaW50KTtcblxuXHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhuZXdfeSwgbmV3X3gpO1xuXHR9XG5cblx0cmVtb3ZlX2RhdGFfcG9pbnQoaW5kZXggPSB0aGlzLngubGVuZ3RoLTEpIHtcblx0XHRpZih0aGlzLngubGVuZ3RoIDwgMykgcmV0dXJuO1xuXG5cdFx0bGV0IG5ld195ID0gdGhpcy55Lm1hcChkYXRhX3NldCA9PiB7IHJldHVybiB7dmFsdWVzOmRhdGFfc2V0LnZhbHVlc307IH0pO1xuXHRcdG5ld195Lm1hcCgoZCkgPT4geyBkLnZhbHVlcy5zcGxpY2UoaW5kZXgsIDEpOyB9KTtcblx0XHRsZXQgbmV3X3ggPSB0aGlzLnguc2xpY2UoKTtcblx0XHRuZXdfeC5zcGxpY2UoaW5kZXgsIDEpO1xuXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKG5ld195LCBuZXdfeCk7XG5cdH1cblxuXHRydW5fYW5pbWF0aW9uKCkge1xuXHRcdGxldCBhbmltX3N2ZyA9ICQucnVuU1ZHQW5pbWF0aW9uKHRoaXMuc3ZnLCB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUpO1xuXG5cdFx0aWYodGhpcy5zdmcucGFyZW50Tm9kZSA9PSB0aGlzLmNoYXJ0X3dyYXBwZXIpIHtcblx0XHRcdHRoaXMuY2hhcnRfd3JhcHBlci5yZW1vdmVDaGlsZCh0aGlzLnN2Zyk7XG5cdFx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuYXBwZW5kQ2hpbGQoYW5pbV9zdmcpO1xuXG5cdFx0fVxuXG5cdFx0Ly8gUmVwbGFjZSB0aGUgbmV3IHN2ZyAoZGF0YSBoYXMgbG9uZyBiZWVuIHJlcGxhY2VkKVxuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0aWYoYW5pbV9zdmcucGFyZW50Tm9kZSA9PSB0aGlzLmNoYXJ0X3dyYXBwZXIpIHtcblx0XHRcdFx0dGhpcy5jaGFydF93cmFwcGVyLnJlbW92ZUNoaWxkKGFuaW1fc3ZnKTtcblx0XHRcdFx0dGhpcy5jaGFydF93cmFwcGVyLmFwcGVuZENoaWxkKHRoaXMuc3ZnKTtcblx0XHRcdH1cblx0XHR9LCAyMDApO1xuXHR9XG5cblx0YW5pbWF0ZV9ncmFwaHMoKSB7XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0Ly8gUHJlLXByZXAsIGVxdWlsaXplIG5vIG9mIHBvc2l0aW9ucyBiZXR3ZWVuIG9sZCBhbmQgbmV3XG5cdFx0XHRsZXQgW29sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195XSA9IHRoaXMuY2FsY19vbGRfYW5kX25ld19wb3N0aW9ucyhkLCBpKTtcblx0XHRcdGlmKHRoaXMubm9fb2ZfZXh0cmFfcHRzID49IDApIHtcblx0XHRcdFx0dGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdFx0dGhpcy5tYWtlX25ld191bml0c19mb3JfZGF0YXNldChvbGRfeCwgb2xkX3ksIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0sIGksIHRoaXMueS5sZW5ndGgpO1xuXHRcdFx0fVxuXHRcdFx0ZC5wYXRoICYmIHRoaXMuYW5pbWF0ZV9wYXRoKGQsIGksIG9sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195KTtcblx0XHRcdHRoaXMuYW5pbWF0ZV91bml0cyhkLCBpLCBvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeSk7XG5cdFx0fSk7XG5cblx0XHQvLyBUT0RPOiByZXBsYWNlIHdpdGggcmVhbCB1bml0c1xuXHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0XHR0aGlzLm1ha2VfcGF0aCAmJiB0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdFx0dGhpcy5tYWtlX25ld191bml0cyhkLCBpKTtcblx0XHRcdH0pO1xuXHRcdH0sIDMwMCk7XG5cdH1cblxuXHRhbmltYXRlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3kpIHtcblx0XHQvLyBBbmltYXRlIHBhdGhcblx0XHRjb25zdCBuZXdfcG9pbnRzX2xpc3QgPSBuZXdfeS5tYXAoKHksIGkpID0+IChuZXdfeFtpXSArICcsJyArIHkpKTtcblx0XHRjb25zdCBuZXdfcGF0aF9zdHIgPSBuZXdfcG9pbnRzX2xpc3Quam9pbihcIkxcIik7XG5cblx0XHRjb25zdCBwYXRoX2FyZ3MgPSBbe3VuaXQ6IGQucGF0aCwgb2JqZWN0OiBkLCBrZXk6ICdwYXRoJ30sIHtkOlwiTVwiK25ld19wYXRoX3N0cn0sIDI1MCwgXCJlYXNlaW5cIl07XG5cdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlLnB1c2gocGF0aF9hcmdzKTtcblxuXHRcdC8vIEFuaW1hdGUgcmVnaW9uXG5cdFx0aWYoZC5yZWdpb25fcGF0aCkge1xuXHRcdFx0bGV0IHJlZ19zdGFydF9wdCA9IGAwLCR7dGhpcy56ZXJvX2xpbmV9TGA7XG5cdFx0XHRsZXQgcmVnX2VuZF9wdCA9IGBMJHt0aGlzLndpZHRofSwke3RoaXMuemVyb19saW5lfWA7XG5cblx0XHRcdGNvbnN0IHJlZ2lvbl9hcmdzID0gW1xuXHRcdFx0XHR7dW5pdDogZC5yZWdpb25fcGF0aCwgb2JqZWN0OiBkLCBrZXk6ICdyZWdpb25fcGF0aCd9LFxuXHRcdFx0XHR7ZDpcIk1cIiArIHJlZ19zdGFydF9wdCArIG5ld19wYXRoX3N0ciArIHJlZ19lbmRfcHR9LFxuXHRcdFx0XHQyNTAsXG5cdFx0XHRcdFwiZWFzZWluXCJcblx0XHRcdF07XG5cdFx0XHR0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChyZWdpb25fYXJncyk7XG5cdFx0fVxuXHR9XG5cblx0YW5pbWF0ZV91bml0cyhkLCBpbmRleCwgb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3kpIHtcblx0XHRsZXQgdHlwZSA9IHRoaXMudW5pdF9hcmdzLnR5cGU7XG5cblx0XHRkLnN2Z191bml0cy5tYXAoKHVuaXQsIGkpID0+IHtcblx0XHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZS5wdXNoKHRoaXMuYW5pbWF0ZVt0eXBlXShcblx0XHRcdFx0e3VuaXQ6dW5pdCwgYXJyYXk6ZC5zdmdfdW5pdHMsIGluZGV4OiBpfSwgLy8gdW5pdCwgd2l0aCBpbmZvIHRvIHJlcGxhY2Ugd2hlcmUgaXQgY2FtZSBmcm9tIGluIHRoZSBkYXRhXG5cdFx0XHRcdG5ld194W2ldLFxuXHRcdFx0XHRuZXdfeVtpXSxcblx0XHRcdFx0aW5kZXhcblx0XHRcdCkpO1xuXHRcdH0pO1xuXHR9XG5cblx0Y2FsY19vbGRfYW5kX25ld19wb3N0aW9ucyhkLCBpKSB7XG5cdFx0bGV0IG9sZF94ID0gdGhpcy54X29sZF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXHRcdGxldCBuZXdfeCA9IHRoaXMueF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXG5cdFx0bGV0IG9sZF95ID0gdGhpcy5vbGRfeV9heGlzX3RvcHNbaV0uc2xpY2UoKTtcblx0XHRsZXQgbmV3X3kgPSBkLnlfdG9wcy5zbGljZSgpO1xuXG5cdFx0Y29uc3QgbGFzdF9vbGRfeF9wb3MgPSBvbGRfeFtvbGRfeC5sZW5ndGggLSAxXTtcblx0XHRjb25zdCBsYXN0X29sZF95X3BvcyA9IG9sZF95W29sZF95Lmxlbmd0aCAtIDFdO1xuXG5cdFx0Y29uc3QgbGFzdF9uZXdfeF9wb3MgPSBuZXdfeFtuZXdfeC5sZW5ndGggLSAxXTtcblx0XHRjb25zdCBsYXN0X25ld195X3BvcyA9IG5ld195W25ld195Lmxlbmd0aCAtIDFdO1xuXG5cdFx0aWYodGhpcy5ub19vZl9leHRyYV9wdHMgPj0gMCkge1xuXHRcdFx0Ly8gRmlyc3Qgc3Vic3RpdHV0ZSBjdXJyZW50IHBhdGggd2l0aCBhIHNxdWlnZ2xlZCBvbmUgKGxvb2tpbmcgdGhlIHNhbWUgYnV0XG5cdFx0XHQvLyBoYXZpbmcgbW9yZSBwb2ludHMgYXQgZW5kKSxcblx0XHRcdC8vIHRoZW4gYW5pbWF0ZSB0byBzdHJldGNoIGl0IGxhdGVyIHRvIG5ldyBwb2ludHNcblx0XHRcdC8vIChuZXcgcG9pbnRzIGFscmVhZHkgaGF2ZSBtb3JlIHBvaW50cylcblxuXHRcdFx0Ly8gSGVuY2UsIHRoZSBleHRyYSBlbmQgcG9pbnRzIHdpbGwgY29ycmVzcG9uZCB0byBjdXJyZW50KG9sZCkgcG9zaXRpb25zXG5cdFx0XHRsZXQgZmlsbGVyX3ggPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3Rfb2xkX3hfcG9zKTtcblx0XHRcdGxldCBmaWxsZXJfeSA9IG5ldyBBcnJheShNYXRoLmFicyh0aGlzLm5vX29mX2V4dHJhX3B0cykpLmZpbGwobGFzdF9vbGRfeV9wb3MpO1xuXG5cdFx0XHRvbGRfeCA9IG9sZF94LmNvbmNhdChmaWxsZXJfeCk7XG5cdFx0XHRvbGRfeSA9IG9sZF95LmNvbmNhdChmaWxsZXJfeSk7XG5cblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gSnVzdCBtb2RpZnkgdGhlIG5ldyBwb2ludHMgdG8gaGF2ZSBleHRyYSBwb2ludHNcblx0XHRcdC8vIHdpdGggdGhlIHNhbWUgcG9zaXRpb24gYXQgZW5kXG5cdFx0XHRsZXQgZmlsbGVyX3ggPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3RfbmV3X3hfcG9zKTtcblx0XHRcdGxldCBmaWxsZXJfeSA9IG5ldyBBcnJheShNYXRoLmFicyh0aGlzLm5vX29mX2V4dHJhX3B0cykpLmZpbGwobGFzdF9uZXdfeV9wb3MpO1xuXG5cdFx0XHRuZXdfeCA9IG5ld194LmNvbmNhdChmaWxsZXJfeCk7XG5cdFx0XHRuZXdfeSA9IG5ld195LmNvbmNhdChmaWxsZXJfeSk7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeV07XG5cdH1cblxuXHRtYWtlX2FuaW1feF9heGlzKGhlaWdodCwgdGV4dF9zdGFydF9hdCwgYXhpc19saW5lX2NsYXNzKSB7XG5cdFx0Ly8gQW5pbWF0ZSBYIEFYSVMgdG8gYWNjb3VudCBmb3IgbW9yZSBvciBsZXNzIGF4aXMgbGluZXNcblxuXHRcdGNvbnN0IG9sZF9wb3MgPSB0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zO1xuXHRcdGNvbnN0IG5ld19wb3MgPSB0aGlzLnhfYXhpc19wb3NpdGlvbnM7XG5cblx0XHRjb25zdCBvbGRfdmFscyA9IHRoaXMub2xkX3hfdmFsdWVzO1xuXHRcdGNvbnN0IG5ld192YWxzID0gdGhpcy54O1xuXG5cdFx0Y29uc3QgbGFzdF9saW5lX3BvcyA9IG9sZF9wb3Nbb2xkX3Bvcy5sZW5ndGggLSAxXTtcblxuXHRcdGxldCBhZGRfYW5kX2FuaW1hdGVfbGluZSA9ICh2YWx1ZSwgb2xkX3BvcywgbmV3X3BvcykgPT4ge1xuXHRcdFx0Y29uc3QgeF9saW5lID0gdGhpcy5tYWtlX3hfbGluZShcblx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHR0ZXh0X3N0YXJ0X2F0LFxuXHRcdFx0XHR2YWx1ZSwgLy8gbmV3IHZhbHVlXG5cdFx0XHRcdCd4LXZhbHVlLXRleHQnLFxuXHRcdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRcdG9sZF9wb3MgLy8gb2xkIHBvc2l0aW9uXG5cdFx0XHQpO1xuXHRcdFx0dGhpcy54X2F4aXNfZ3JvdXAuYXBwZW5kQ2hpbGQoeF9saW5lKTtcblxuXHRcdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlICYmIHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZS5wdXNoKFtcblx0XHRcdFx0e3VuaXQ6IHhfbGluZSwgYXJyYXk6IFswXSwgaW5kZXg6IDB9LFxuXHRcdFx0XHR7dHJhbnNmb3JtOiBgJHsgbmV3X3BvcyB9LCAwYH0sXG5cdFx0XHRcdDI1MCxcblx0XHRcdFx0XCJlYXNlaW5cIixcblx0XHRcdFx0XCJ0cmFuc2xhdGVcIixcblx0XHRcdFx0e3RyYW5zZm9ybTogYCR7IG9sZF9wb3MgfSwgMGB9XG5cdFx0XHRdKTtcblx0XHR9O1xuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblxuXHRcdHRoaXMubWFrZV9uZXdfYXhpc19hbmltX2xpbmVzKFxuXHRcdFx0b2xkX3Bvcyxcblx0XHRcdG5ld19wb3MsXG5cdFx0XHRvbGRfdmFscyxcblx0XHRcdG5ld192YWxzLFxuXHRcdFx0bGFzdF9saW5lX3Bvcyxcblx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X2F4aXMoKSB7XG5cdFx0Ly8gQW5pbWF0ZSBZIEFYSVMgdG8gYWNjb3VudCBmb3IgbW9yZSBvciBsZXNzIGF4aXMgbGluZXNcblxuXHRcdGNvbnN0IG9sZF9wb3MgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzLm1hcCh2YWx1ZSA9PlxuXHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcik7XG5cdFx0Y29uc3QgbmV3X3BvcyA9IHRoaXMueV9heGlzX3ZhbHVlcy5tYXAodmFsdWUgPT5cblx0XHRcdHRoaXMuemVyb19saW5lIC0gdmFsdWUgKiB0aGlzLm11bHRpcGxpZXIpO1xuXG5cdFx0Y29uc3Qgb2xkX3ZhbHMgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzO1xuXHRcdGNvbnN0IG5ld192YWxzID0gdGhpcy55X2F4aXNfdmFsdWVzO1xuXG5cdFx0Y29uc3QgbGFzdF9saW5lX3BvcyA9IG9sZF9wb3Nbb2xkX3Bvcy5sZW5ndGggLSAxXTtcblxuXHRcdHRoaXMueV9heGlzX2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cblx0XHR0aGlzLm1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhcblx0XHRcdG9sZF9wb3MsXG5cdFx0XHRuZXdfcG9zLFxuXHRcdFx0b2xkX3ZhbHMsXG5cdFx0XHRuZXdfdmFscyxcblx0XHRcdGxhc3RfbGluZV9wb3MsXG5cdFx0XHR0aGlzLmFkZF9hbmRfYW5pbWF0ZV95X2xpbmUuYmluZCh0aGlzKSxcblx0XHRcdHRoaXMueV9heGlzX2dyb3VwXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X3NwZWNpZmljcygpIHtcblx0XHR0aGlzLnNwZWNpZmljX3lfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAoKGQpID0+IHtcblx0XHRcdHRoaXMuYWRkX2FuZF9hbmltYXRlX3lfbGluZShcblx0XHRcdFx0ZC50aXRsZSxcblx0XHRcdFx0dGhpcy5vbGRfemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMub2xkX211bHRpcGxpZXIsXG5cdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0MCxcblx0XHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLFxuXHRcdFx0XHRkLmxpbmVfdHlwZSxcblx0XHRcdFx0dHJ1ZVxuXHRcdFx0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhvbGRfcG9zLCBuZXdfcG9zLCBvbGRfdmFscywgbmV3X3ZhbHMsIGxhc3RfbGluZV9wb3MsIGFkZF9hbmRfYW5pbWF0ZV9saW5lLCBncm91cCkge1xuXHRcdGxldCBzdXBlcmltcG9zZWRfcG9zaXRpb25zLCBzdXBlcmltcG9zZWRfdmFsdWVzO1xuXHRcdGxldCBub19vZl9leHRyYXMgPSBuZXdfdmFscy5sZW5ndGggLSBvbGRfdmFscy5sZW5ndGg7XG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gTW9yZSBheGlzIGFyZSBuZWVkZWRcblx0XHRcdC8vIEZpcnN0IG1ha2Ugb25seSB0aGUgc3VwZXJpbXBvc2VkIChzYW1lIHBvc2l0aW9uKSBvbmVzXG5cdFx0XHQvLyBBZGQgaW4gdGhlIGV4dHJhcyBhdCB0aGUgZW5kIGxhdGVyXG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZSgwLCBvbGRfcG9zLmxlbmd0aCk7XG5cdFx0XHRzdXBlcmltcG9zZWRfdmFsdWVzID0gbmV3X3ZhbHMuc2xpY2UoMCwgb2xkX3ZhbHMubGVuZ3RoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQXhpcyBoYXZlIHRvIGJlIHJlZHVjZWRcblx0XHRcdC8vIEZha2UgaXQgYnkgbW92aW5nIGFsbCBjdXJyZW50IGV4dHJhIGF4aXMgdG8gdGhlIGxhc3QgcG9zaXRpb25cblx0XHRcdC8vIFlvdSdsbCBuZWVkIGZpbGxlciBwb3NpdGlvbnMgYW5kIHZhbHVlcyBpbiB0aGUgbmV3IGFycmF5c1xuXHRcdFx0Y29uc3QgZmlsbGVyX3ZhbHMgPSBuZXcgQXJyYXkoTWF0aC5hYnMobm9fb2ZfZXh0cmFzKSkuZmlsbChcIlwiKTtcblx0XHRcdHN1cGVyaW1wb3NlZF92YWx1ZXMgPSBuZXdfdmFscy5jb25jYXQoZmlsbGVyX3ZhbHMpO1xuXG5cdFx0XHRjb25zdCBmaWxsZXJfcG9zID0gbmV3IEFycmF5KE1hdGguYWJzKG5vX29mX2V4dHJhcykpLmZpbGwobGFzdF9saW5lX3Bvcyk7XG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5jb25jYXQoZmlsbGVyX3Bvcyk7XG5cdFx0fVxuXG5cdFx0c3VwZXJpbXBvc2VkX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRhZGRfYW5kX2FuaW1hdGVfbGluZSh2YWx1ZSwgb2xkX3Bvc1tpXSwgc3VwZXJpbXBvc2VkX3Bvc2l0aW9uc1tpXSwgaSwgZ3JvdXApO1xuXHRcdH0pO1xuXG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gQWRkIGluIGV4dHJhIGF4aXMgaW4gdGhlIGVuZFxuXHRcdFx0Ly8gYW5kIHRoZW4gYW5pbWF0ZSB0byBuZXcgcG9zaXRpb25zXG5cdFx0XHRjb25zdCBleHRyYV92YWx1ZXMgPSBuZXdfdmFscy5zbGljZShvbGRfdmFscy5sZW5ndGgpO1xuXHRcdFx0Y29uc3QgZXh0cmFfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZShvbGRfcG9zLmxlbmd0aCk7XG5cblx0XHRcdGV4dHJhX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lKHZhbHVlLCBsYXN0X2xpbmVfcG9zLCBleHRyYV9wb3NpdGlvbnNbaV0sIGksIGdyb3VwKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdG1ha2VfeF9saW5lKGhlaWdodCwgdGV4dF9zdGFydF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHhfcG9zKSB7XG5cdFx0bGV0IGFsbG93ZWRfc3BhY2UgPSB0aGlzLmF2Z191bml0X3dpZHRoICogMS41O1xuXG5cdFx0aWYodGhpcy5nZXRfc3Ryd2lkdGgocG9pbnQpID4gYWxsb3dlZF9zcGFjZSkge1xuXHRcdFx0bGV0IGFsbG93ZWRfbGV0dGVycyA9IGFsbG93ZWRfc3BhY2UgLyA4O1xuXHRcdFx0cG9pbnQgPSBwb2ludC5zbGljZSgwLCBhbGxvd2VkX2xldHRlcnMtMykgKyBcIiAuLi5cIjtcblx0XHR9XG5cblx0XHRsZXQgbGluZSA9ICQuY3JlYXRlU1ZHKCdsaW5lJywge1xuXHRcdFx0eDE6IDAsXG5cdFx0XHR4MjogMCxcblx0XHRcdHkxOiAwLFxuXHRcdFx0eTI6IGhlaWdodFxuXHRcdH0pO1xuXG5cdFx0bGV0IHRleHQgPSAkLmNyZWF0ZVNWRygndGV4dCcsIHtcblx0XHRcdGNsYXNzTmFtZTogbGFiZWxfY2xhc3MsXG5cdFx0XHR4OiAwLFxuXHRcdFx0eTogdGV4dF9zdGFydF9hdCxcblx0XHRcdGR5OiAnLjcxZW0nLFxuXHRcdFx0aW5uZXJIVE1MOiBwb2ludFxuXHRcdH0pO1xuXG5cdFx0bGV0IHhfbGV2ZWwgPSAkLmNyZWF0ZVNWRygnZycsIHtcblx0XHRcdGNsYXNzTmFtZTogYHRpY2sgJHtheGlzX2xpbmVfY2xhc3N9YCxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgkeyB4X3BvcyB9LCAwKWBcblx0XHR9KTtcblxuXHRcdHhfbGV2ZWwuYXBwZW5kQ2hpbGQobGluZSk7XG5cdFx0eF9sZXZlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuXHRcdHJldHVybiB4X2xldmVsO1xuXHR9XG5cblx0bWFrZV95X2xpbmUoc3RhcnRfYXQsIHdpZHRoLCB0ZXh0X2VuZF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHlfcG9zLCBkYXJrZXI9ZmFsc2UsIGxpbmVfdHlwZT1cIlwiKSB7XG5cdFx0bGV0IGxpbmUgPSAkLmNyZWF0ZVNWRygnbGluZScsIHtcblx0XHRcdGNsYXNzTmFtZTogbGluZV90eXBlID09PSBcImRhc2hlZFwiID8gXCJkYXNoZWRcIjogXCJcIixcblx0XHRcdHgxOiBzdGFydF9hdCxcblx0XHRcdHgyOiB3aWR0aCxcblx0XHRcdHkxOiAwLFxuXHRcdFx0eTI6IDBcblx0XHR9KTtcblxuXHRcdGxldCB0ZXh0ID0gJC5jcmVhdGVTVkcoJ3RleHQnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGxhYmVsX2NsYXNzLFxuXHRcdFx0eDogdGV4dF9lbmRfYXQsXG5cdFx0XHR5OiAwLFxuXHRcdFx0ZHk6ICcuMzJlbScsXG5cdFx0XHRpbm5lckhUTUw6IHBvaW50K1wiXCJcblx0XHR9KTtcblxuXHRcdGxldCB5X2xldmVsID0gJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGB0aWNrICR7YXhpc19saW5lX2NsYXNzfWAsXG5cdFx0XHR0cmFuc2Zvcm06IGB0cmFuc2xhdGUoMCwgJHt5X3Bvc30pYFxuXHRcdH0pO1xuXG5cdFx0aWYoZGFya2VyKSB7XG5cdFx0XHRsaW5lLnN0eWxlLnN0cm9rZSA9IFwicmdiYSgyNywgMzEsIDM1LCAwLjYpXCI7XG5cdFx0fVxuXG5cdFx0eV9sZXZlbC5hcHBlbmRDaGlsZChsaW5lKTtcblx0XHR5X2xldmVsLmFwcGVuZENoaWxkKHRleHQpO1xuXG5cdFx0cmV0dXJuIHlfbGV2ZWw7XG5cdH1cblxuXHRhZGRfYW5kX2FuaW1hdGVfeV9saW5lKHZhbHVlLCBvbGRfcG9zLCBuZXdfcG9zLCBpLCBncm91cCwgdHlwZSwgc3BlY2lmaWM9ZmFsc2UpIHtcblx0XHRsZXQgW3dpZHRoLCB0ZXh0X2VuZF9hdCwgYXhpc19saW5lX2NsYXNzLCBzdGFydF9hdF0gPSB0aGlzLmdldF95X2F4aXNfbGluZV9wcm9wcyhzcGVjaWZpYyk7XG5cdFx0bGV0IGF4aXNfbGFiZWxfY2xhc3MgPSAhc3BlY2lmaWMgPyAneS12YWx1ZS10ZXh0JyA6ICdzcGVjaWZpYy12YWx1ZSc7XG5cdFx0dmFsdWUgPSAhc3BlY2lmaWMgPyB2YWx1ZSA6ICh2YWx1ZStcIlwiKS50b1VwcGVyQ2FzZSgpO1xuXHRcdGNvbnN0IHlfbGluZSA9IHRoaXMubWFrZV95X2xpbmUoXG5cdFx0XHRzdGFydF9hdCxcblx0XHRcdHdpZHRoLFxuXHRcdFx0dGV4dF9lbmRfYXQsXG5cdFx0XHR2YWx1ZSxcblx0XHRcdGF4aXNfbGFiZWxfY2xhc3MsXG5cdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRvbGRfcG9zLCAgLy8gb2xkIHBvc2l0aW9uXG5cdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCksIC8vIE5vbi1maXJzdCBaZXJvIGxpbmVcblx0XHRcdHR5cGVcblx0XHQpO1xuXG5cdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoeV9saW5lKTtcblxuXHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZSAmJiB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChbXG5cdFx0XHR7dW5pdDogeV9saW5lLCBhcnJheTogWzBdLCBpbmRleDogMH0sXG5cdFx0XHR7dHJhbnNmb3JtOiBgMCwgJHsgbmV3X3BvcyB9YH0sXG5cdFx0XHQyNTAsXG5cdFx0XHRcImVhc2VpblwiLFxuXHRcdFx0XCJ0cmFuc2xhdGVcIixcblx0XHRcdHt0cmFuc2Zvcm06IGAwLCAkeyBvbGRfcG9zIH1gfVxuXHRcdF0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19wb2ludHMoYXJyYXkpIHtcblx0XHQvLyoqKiBXaGVyZSB0aGUgbWFnaWMgaGFwcGVucyAqKipcblxuXHRcdC8vIENhbGN1bGF0ZXMgYmVzdC1maXQgeSBpbnRlcnZhbHMgZnJvbSBnaXZlbiB2YWx1ZXNcblx0XHQvLyBhbmQgcmV0dXJucyB0aGUgaW50ZXJ2YWwgYXJyYXlcblxuXHRcdC8vIFRPRE86IEZyYWN0aW9uc1xuXG5cdFx0bGV0IG1heF9ib3VuZCwgbWluX2JvdW5kLCBwb3Nfbm9fb2ZfcGFydHMsIG5lZ19ub19vZl9wYXJ0cywgcGFydF9zaXplOyAvLyBlc2xpbnQtZGlzYWJsZS1saW5lIG5vLXVudXNlZC12YXJzXG5cblx0XHQvLyBDcml0aWNhbCB2YWx1ZXNcblx0XHRsZXQgbWF4X3ZhbCA9IHBhcnNlSW50KE1hdGgubWF4KC4uLmFycmF5KSk7XG5cdFx0bGV0IG1pbl92YWwgPSBwYXJzZUludChNYXRoLm1pbiguLi5hcnJheSkpO1xuXHRcdGlmKG1pbl92YWwgPj0gMCkge1xuXHRcdFx0bWluX3ZhbCA9IDA7XG5cdFx0fVxuXG5cdFx0bGV0IGdldF9wYXJhbXMgPSAodmFsdWUxLCB2YWx1ZTIpID0+IHtcblx0XHRcdGxldCBib3VuZDEsIGJvdW5kMiwgbm9fb2ZfcGFydHNfMSwgbm9fb2ZfcGFydHNfMiwgaW50ZXJ2YWxfc2l6ZTtcblx0XHRcdGlmKCh2YWx1ZTErXCJcIikubGVuZ3RoIDw9IDEpIHtcblx0XHRcdFx0W2JvdW5kMSwgbm9fb2ZfcGFydHNfMV0gPSBbMTAsIDVdO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0W2JvdW5kMSwgbm9fb2ZfcGFydHNfMV0gPSB0aGlzLmNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzKHZhbHVlMSk7XG5cdFx0XHR9XG5cblx0XHRcdGludGVydmFsX3NpemUgPSBib3VuZDEgLyBub19vZl9wYXJ0c18xO1xuXHRcdFx0bm9fb2ZfcGFydHNfMiA9IHRoaXMuY2FsY19ub19vZl9wYXJ0cyh2YWx1ZTIsIGludGVydmFsX3NpemUpO1xuXHRcdFx0Ym91bmQyID0gbm9fb2ZfcGFydHNfMiAqIGludGVydmFsX3NpemU7XG5cblx0XHRcdHJldHVybiBbYm91bmQxLCBib3VuZDIsIG5vX29mX3BhcnRzXzEsIG5vX29mX3BhcnRzXzIsIGludGVydmFsX3NpemVdO1xuXHRcdH07XG5cblx0XHRjb25zdCBhYnNfbWluX3ZhbCA9IG1pbl92YWwgKiAtMTtcblx0XHRpZihhYnNfbWluX3ZhbCA8PSBtYXhfdmFsKSB7XG5cdFx0XHQvLyBHZXQgdGhlIHBvc2l0aXZlIHJlZ2lvbiBpbnRlcnZhbHNcblx0XHRcdC8vIHRoZW4gY2FsYyBuZWdhdGl2ZSBvbmVzIGFjY29yZGluZ2x5XG5cdFx0XHRbbWF4X2JvdW5kLCBtaW5fYm91bmQsIHBvc19ub19vZl9wYXJ0cywgbmVnX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhtYXhfdmFsLCBhYnNfbWluX3ZhbCk7XG5cdFx0XHRpZihhYnNfbWluX3ZhbCA9PT0gMCkge1xuXHRcdFx0XHRtaW5fYm91bmQgPSAwOyBuZWdfbm9fb2ZfcGFydHMgPSAwO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBHZXQgdGhlIG5lZ2F0aXZlIHJlZ2lvbiBoZXJlIGZpcnN0XG5cdFx0XHRbbWluX2JvdW5kLCBtYXhfYm91bmQsIG5lZ19ub19vZl9wYXJ0cywgcG9zX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhhYnNfbWluX3ZhbCwgbWF4X3ZhbCk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBib3RoIHJlZ2lvbiBwYXJ0cyBldmVuXG5cdFx0aWYocG9zX25vX29mX3BhcnRzICUgMiAhPT0gMCAmJiBuZWdfbm9fb2ZfcGFydHMgPiAwKSBwb3Nfbm9fb2ZfcGFydHMrKztcblx0XHRpZihuZWdfbm9fb2ZfcGFydHMgJSAyICE9PSAwKSB7XG5cdFx0XHQvLyBldmVyeSBpbmNyZWFzZSBpbiBub19vZl9wYXJ0cyBlbnRhaWxzIGFuIGluY3JlYXNlIGluIGNvcnJlc3BvbmRpbmcgYm91bmRcblx0XHRcdC8vIGV4Y2VwdCBoZXJlLCBpdCBoYXBwZW5zIGltcGxpY2l0bHkgYWZ0ZXIgZXZlcnkgY2FsY19ub19vZl9wYXJ0cygpIGNhbGxcblx0XHRcdG5lZ19ub19vZl9wYXJ0cysrO1xuXHRcdFx0bWluX2JvdW5kICs9IHBhcnRfc2l6ZTtcblx0XHR9XG5cblx0XHRsZXQgbm9fb2ZfcGFydHMgPSBwb3Nfbm9fb2ZfcGFydHMgKyBuZWdfbm9fb2ZfcGFydHM7XG5cdFx0aWYobm9fb2ZfcGFydHMgPiA1KSB7XG5cdFx0XHRub19vZl9wYXJ0cyAvPSAyO1xuXHRcdFx0cGFydF9zaXplICo9IDI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0X2ludGVydmFscyhcblx0XHRcdCgtMSkgKiBtaW5fYm91bmQsXG5cdFx0XHRwYXJ0X3NpemUsXG5cdFx0XHRub19vZl9wYXJ0c1xuXHRcdCk7XG5cdH1cblxuXHRnZXRfaW50ZXJ2YWxzKHN0YXJ0LCBpbnRlcnZhbF9zaXplLCBjb3VudCkge1xuXHRcdGxldCBpbnRlcnZhbHMgPSBbXTtcblx0XHRmb3IodmFyIGkgPSAwOyBpIDw9IGNvdW50OyBpKyspe1xuXHRcdFx0aW50ZXJ2YWxzLnB1c2goc3RhcnQpO1xuXHRcdFx0c3RhcnQgKz0gaW50ZXJ2YWxfc2l6ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGludGVydmFscztcblx0fVxuXG5cdGNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzKG1heF92YWwpIHtcblx0XHQvLyBHaXZlbiBhIHBvc2l0aXZlIHZhbHVlLCBjYWxjdWxhdGVzIGEgbmljZS1udW1iZXIgdXBwZXIgYm91bmRcblx0XHQvLyBhbmQgYSBjb25zZXF1ZW50IG9wdGltYWwgbnVtYmVyIG9mIHBhcnRzXG5cblx0XHRjb25zdCBwYXJ0X3NpemUgPSBNYXRoLnBvdygxMCwgKChtYXhfdmFsK1wiXCIpLmxlbmd0aCAtIDEpKTtcblx0XHRjb25zdCBub19vZl9wYXJ0cyA9IHRoaXMuY2FsY19ub19vZl9wYXJ0cyhtYXhfdmFsLCBwYXJ0X3NpemUpO1xuXG5cdFx0Ly8gVXNlIGl0IHRvIGdldCBhIG5pY2UgZXZlbiB1cHBlciBib3VuZFxuXHRcdGNvbnN0IHVwcGVyX2JvdW5kID0gcGFydF9zaXplICogbm9fb2ZfcGFydHM7XG5cblx0XHRyZXR1cm4gW3VwcGVyX2JvdW5kLCBub19vZl9wYXJ0c107XG5cdH1cblxuXHRjYWxjX25vX29mX3BhcnRzKHZhbHVlLCBkaXZpc29yKSB7XG5cdFx0Ly8gdmFsdWUgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyLCBkaXZpc29yIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMFxuXHRcdC8vIHJldHVybnMgYW4gZXZlbiBubyBvZiBwYXJ0c1xuXHRcdGxldCBub19vZl9wYXJ0cyA9IE1hdGguY2VpbCh2YWx1ZSAvIGRpdmlzb3IpO1xuXHRcdGlmKG5vX29mX3BhcnRzICUgMiAhPT0gMCkgbm9fb2ZfcGFydHMrKzsgLy8gTWFrZSBpdCBhbiBldmVuIG51bWJlclxuXG5cdFx0cmV0dXJuIG5vX29mX3BhcnRzO1xuXHR9XG5cblx0Z2V0X29wdGltYWxfbm9fb2ZfcGFydHMobm9fb2ZfcGFydHMpIHtcblx0XHQvLyBha2EgRGl2aWRlIGJ5IDIgaWYgdG9vIGxhcmdlXG5cdFx0cmV0dXJuIChub19vZl9wYXJ0cyA8IDUpID8gbm9fb2ZfcGFydHMgOiBub19vZl9wYXJ0cyAvIDI7XG5cdH1cblxuXHRzZXRfYXZnX3VuaXRfd2lkdGhfYW5kX3hfb2Zmc2V0KCkge1xuXHRcdC8vIFNldCB0aGUgLi4uIHlvdSBnZXQgaXRcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCAtIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSAwO1xuXHR9XG5cblx0Z2V0X2FsbF95X3ZhbHVlcygpIHtcblx0XHRsZXQgYWxsX3ZhbHVlcyA9IFtdO1xuXG5cdFx0Ly8gQWRkIGluIGFsbCB0aGUgeSB2YWx1ZXMgaW4gdGhlIGRhdGFzZXRzXG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGFsbF92YWx1ZXMgPSBhbGxfdmFsdWVzLmNvbmNhdChkLnZhbHVlcyk7XG5cdFx0fSk7XG5cblx0XHQvLyBBZGQgaW4gYWxsIHRoZSBzcGVjaWZpYyB2YWx1ZXNcblx0XHRyZXR1cm4gYWxsX3ZhbHVlcy5jb25jYXQodGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4gZC52YWx1ZSkpO1xuXHR9XG5cblx0Y2FsY195X2RlcGVuZGVuY2llcygpIHtcblx0XHR0aGlzLnlfbWluX3RvcHMgPSBuZXcgQXJyYXkodGhpcy54X2F4aXNfcG9zaXRpb25zLmxlbmd0aCkuZmlsbCg5OTk5KTtcblx0XHR0aGlzLnkubWFwKGQgPT4ge1xuXHRcdFx0ZC55X3RvcHMgPSBkLnZhbHVlcy5tYXAoIHZhbCA9PiBmbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSk7XG5cdFx0XHRkLnlfdG9wcy5tYXAoICh5X3RvcCwgaSkgPT4ge1xuXHRcdFx0XHRpZih5X3RvcCA8IHRoaXMueV9taW5fdG9wc1tpXSkge1xuXHRcdFx0XHRcdHRoaXMueV9taW5fdG9wc1tpXSA9IHlfdG9wO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdGdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIoeV90b3ApIHtcblx0XHRsZXQgaGVpZ2h0LCB5O1xuXHRcdGlmICh5X3RvcCA8PSB0aGlzLnplcm9fbGluZSkge1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy56ZXJvX2xpbmUgLSB5X3RvcDtcblx0XHRcdHkgPSB5X3RvcDtcblxuXHRcdFx0Ly8gSW4gY2FzZSBvZiBpbnZpc2libGUgYmFyc1xuXHRcdFx0aWYoaGVpZ2h0ID09PSAwKSB7XG5cdFx0XHRcdGhlaWdodCA9IHRoaXMuaGVpZ2h0ICogMC4wMTtcblx0XHRcdFx0eSAtPSBoZWlnaHQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGhlaWdodCA9IHlfdG9wIC0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0XHR5ID0gdGhpcy56ZXJvX2xpbmU7XG5cblx0XHRcdC8vIEluIGNhc2Ugb2YgaW52aXNpYmxlIGJhcnNcblx0XHRcdGlmKGhlaWdodCA9PT0gMCkge1xuXHRcdFx0XHRoZWlnaHQgPSB0aGlzLmhlaWdodCAqIDAuMDE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtoZWlnaHQsIHldO1xuXHR9XG5cblx0c2V0dXBfdXRpbHMoKSB7XG5cdFx0dGhpcy5kcmF3ID0ge1xuXHRcdFx0J2Jhcic6ICh4LCB5X3RvcCwgYXJncywgY29sb3IsIGluZGV4LCBub19vZl9kYXRhc2V0cykgPT4ge1xuXHRcdFx0XHRsZXQgdG90YWxfd2lkdGggPSB0aGlzLmF2Z191bml0X3dpZHRoIC0gYXJncy5zcGFjZV93aWR0aDtcblx0XHRcdFx0bGV0IHN0YXJ0X3ggPSB4IC0gdG90YWxfd2lkdGgvMjtcblxuXHRcdFx0XHRsZXQgd2lkdGggPSB0b3RhbF93aWR0aCAvIG5vX29mX2RhdGFzZXRzO1xuXHRcdFx0XHRsZXQgY3VycmVudF94ID0gc3RhcnRfeCArIHdpZHRoICogaW5kZXg7XG5cblx0XHRcdFx0bGV0IFtoZWlnaHQsIHldID0gdGhpcy5nZXRfYmFyX2hlaWdodF9hbmRfeV9hdHRyKHlfdG9wKTtcblxuXHRcdFx0XHRyZXR1cm4gJC5jcmVhdGVTVkcoJ3JlY3QnLCB7XG5cdFx0XHRcdFx0Y2xhc3NOYW1lOiBgYmFyIG1pbmkgZmlsbCAke2NvbG9yfWAsXG5cdFx0XHRcdFx0eDogY3VycmVudF94LFxuXHRcdFx0XHRcdHk6IHksXG5cdFx0XHRcdFx0d2lkdGg6IHdpZHRoLFxuXHRcdFx0XHRcdGhlaWdodDogaGVpZ2h0XG5cdFx0XHRcdH0pO1xuXG5cdFx0XHR9LFxuXHRcdFx0J2RvdCc6ICh4LCB5LCBhcmdzLCBjb2xvcikgPT4ge1xuXHRcdFx0XHRyZXR1cm4gJC5jcmVhdGVTVkcoJ2NpcmNsZScsIHtcblx0XHRcdFx0XHRjbGFzc05hbWU6IGBmaWxsICR7Y29sb3J9YCxcblx0XHRcdFx0XHRjeDogeCxcblx0XHRcdFx0XHRjeTogeSxcblx0XHRcdFx0XHRyOiBhcmdzLnJhZGl1c1xuXHRcdFx0XHR9KTtcblx0XHRcdH1cblx0XHR9O1xuXG5cdFx0dGhpcy5hbmltYXRlID0ge1xuXHRcdFx0J2Jhcic6IChiYXJfb2JqLCB4LCB5X3RvcCwgaW5kZXgpID0+IHtcblx0XHRcdFx0bGV0IHN0YXJ0ID0geCAtIHRoaXMuYXZnX3VuaXRfd2lkdGgvNDtcblx0XHRcdFx0bGV0IHdpZHRoID0gKHRoaXMuYXZnX3VuaXRfd2lkdGgvMikvdGhpcy55Lmxlbmd0aDtcblx0XHRcdFx0bGV0IFtoZWlnaHQsIHldID0gdGhpcy5nZXRfYmFyX2hlaWdodF9hbmRfeV9hdHRyKHlfdG9wKTtcblxuXHRcdFx0XHR4ID0gc3RhcnQgKyAod2lkdGggKiBpbmRleCk7XG5cblx0XHRcdFx0cmV0dXJuIFtiYXJfb2JqLCB7d2lkdGg6IHdpZHRoLCBoZWlnaHQ6IGhlaWdodCwgeDogeCwgeTogeX0sIDI1MCwgXCJlYXNlaW5cIl07XG5cdFx0XHRcdC8vIGJhci5hbmltYXRlKHtoZWlnaHQ6IGFyZ3MubmV3X2hlaWdodCwgeTogeV90b3B9LCAyNTAsIG1pbmEuZWFzZWluKTtcblx0XHRcdH0sXG5cdFx0XHQnZG90JzogKGRvdF9vYmosIHgsIHlfdG9wKSA9PiB7XG5cdFx0XHRcdHJldHVybiBbZG90X29iaiwge2N4OiB4LCBjeTogeV90b3B9LCAzMDAsIFwiZWFzZWluXCJdO1xuXHRcdFx0XHQvLyBkb3QuYW5pbWF0ZSh7Y3k6IHlfdG9wfSwgMjUwLCBtaW5hLmVhc2Vpbik7XG5cdFx0XHR9XG5cdFx0fTtcblx0fVxufVxuXG5jbGFzcyBCYXJDaGFydCBleHRlbmRzIEF4aXNDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblxuXHRcdHRoaXMudHlwZSA9ICdiYXInO1xuXHRcdHRoaXMueF9heGlzX21vZGUgPSBhcmdzLnhfYXhpc19tb2RlIHx8ICd0aWNrJztcblx0XHR0aGlzLnlfYXhpc19tb2RlID0gYXJncy55X2F4aXNfbW9kZSB8fCAnc3Bhbic7XG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0c2V0dXBfdmFsdWVzKCkge1xuXHRcdHN1cGVyLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHRcdHRoaXMudW5pdF9hcmdzID0ge1xuXHRcdFx0dHlwZTogJ2JhcicsXG5cdFx0XHRhcmdzOiB7XG5cdFx0XHRcdHNwYWNlX3dpZHRoOiB0aGlzLmF2Z191bml0X3dpZHRoLzIsXG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdG1ha2Vfb3ZlcmxheSgpIHtcblx0XHQvLyBKdXN0IG1ha2Ugb25lIG91dCBvZiB0aGUgZmlyc3QgZWxlbWVudFxuXHRcdGxldCBpbmRleCA9IHRoaXMueC5sZW5ndGggLSAxO1xuXHRcdGxldCB1bml0ID0gdGhpcy55WzBdLnN2Z191bml0c1tpbmRleF07XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KGluZGV4KTtcblxuXHRcdGlmKHRoaXMub3ZlcmxheSkge1xuXHRcdFx0dGhpcy5vdmVybGF5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0XHR9XG5cblx0XHR0aGlzLm92ZXJsYXkgPSB1bml0LmNsb25lTm9kZSgpO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5maWxsID0gJyMwMDAwMDAnO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5vcGFjaXR5ID0gJzAuNCc7XG5cdFx0dGhpcy5kcmF3X2FyZWEuYXBwZW5kQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0fVxuXG5cdGJpbmRfb3ZlcmxheSgpIHtcblx0XHQvLyBvbiBldmVudCwgdXBkYXRlIG92ZXJsYXlcblx0XHR0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdkYXRhLXNlbGVjdCcsIChlKSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZV9vdmVybGF5KGUuc3ZnX3VuaXQpO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlX292ZXJsYXkodW5pdCkge1xuXHRcdGxldCBhdHRyaWJ1dGVzID0gW107XG5cdFx0T2JqZWN0LmtleXModW5pdC5hdHRyaWJ1dGVzKS5tYXAoaW5kZXggPT4ge1xuXHRcdFx0YXR0cmlidXRlcy5wdXNoKHVuaXQuYXR0cmlidXRlc1tpbmRleF0pO1xuXHRcdH0pO1xuXG5cdFx0YXR0cmlidXRlcy5maWx0ZXIoYXR0ciA9PiBhdHRyLnNwZWNpZmllZCkubWFwKGF0dHIgPT4ge1xuXHRcdFx0dGhpcy5vdmVybGF5LnNldEF0dHJpYnV0ZShhdHRyLm5hbWUsIGF0dHIubm9kZVZhbHVlKTtcblx0XHR9KTtcblx0fVxuXG5cdG9uX2xlZnRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCAtIDEpO1xuXHR9XG5cblx0b25fcmlnaHRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCArIDEpO1xuXHR9XG5cblx0c2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpIHtcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCArIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHR9XG59XG5cbmNsYXNzIExpbmVDaGFydCBleHRlbmRzIEF4aXNDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblx0XHRpZihPYmplY3QuZ2V0UHJvdG90eXBlT2YodGhpcykgIT09IExpbmVDaGFydC5wcm90b3R5cGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLnR5cGUgPSAnbGluZSc7XG5cdFx0dGhpcy5yZWdpb25fZmlsbCA9IGFyZ3MucmVnaW9uX2ZpbGw7XG5cdFx0dGhpcy54X2F4aXNfbW9kZSA9IGFyZ3MueF9heGlzX21vZGUgfHwgJ3NwYW4nO1xuXHRcdHRoaXMueV9heGlzX21vZGUgPSBhcmdzLnlfYXhpc19tb2RlIHx8ICdzcGFuJztcblxuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdHNldHVwX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5zZXR1cF9wYXRoX2dyb3VwcygpO1xuXHRcdHN1cGVyLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX3BhdGhfZ3JvdXBzKCkge1xuXHRcdHRoaXMucGF0aHNfZ3JvdXBzID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0dGhpcy5wYXRoc19ncm91cHNbaV0gPSAkLmNyZWF0ZVNWRygnZycsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAncGF0aC1ncm91cCBwYXRoLWdyb3VwLScgKyBpLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX3ZhbHVlcygpIHtcblx0XHRzdXBlci5zZXR1cF92YWx1ZXMoKTtcblx0XHR0aGlzLnVuaXRfYXJncyA9IHtcblx0XHRcdHR5cGU6ICdkb3QnLFxuXHRcdFx0YXJnczogeyByYWRpdXM6IDggfVxuXHRcdH07XG5cdH1cblxuXHRtYWtlX3BhdGhzKCkge1xuXHRcdHRoaXMueS5tYXAoKGQsIGkpID0+IHtcblx0XHRcdHRoaXMubWFrZV9wYXRoKGQsIGksIHRoaXMueF9heGlzX3Bvc2l0aW9ucywgZC55X3RvcHMsIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0pO1xuXHRcdH0pO1xuXHR9XG5cblx0bWFrZV9wYXRoKGQsIGksIHhfcG9zaXRpb25zLCB5X3Bvc2l0aW9ucywgY29sb3IpIHtcblx0XHRsZXQgcG9pbnRzX2xpc3QgPSB5X3Bvc2l0aW9ucy5tYXAoKHksIGkpID0+ICh4X3Bvc2l0aW9uc1tpXSArICcsJyArIHkpKTtcblx0XHRsZXQgcG9pbnRzX3N0ciA9IHBvaW50c19saXN0LmpvaW4oXCJMXCIpO1xuXG5cdFx0dGhpcy5wYXRoc19ncm91cHNbaV0udGV4dENvbnRlbnQgPSAnJztcblxuXHRcdGQucGF0aCA9ICQuY3JlYXRlU1ZHKCdwYXRoJywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnBhdGhzX2dyb3Vwc1tpXSxcblx0XHRcdGNsYXNzTmFtZTogYHN0cm9rZSAke2NvbG9yfWAsXG5cdFx0XHRkOiBcIk1cIitwb2ludHNfc3RyXG5cdFx0fSk7XG5cblx0XHRpZih0aGlzLnJlZ2lvbl9maWxsKSB7XG5cdFx0XHRsZXQgZ3JhZGllbnRfaWQgPSdwYXRoLWZpbGwtZ3JhZGllbnQnICsgJy0nICsgY29sb3I7XG5cblx0XHRcdHRoaXMuZ3JhZGllbnRfZGVmID0gJC5jcmVhdGVTVkcoJ2xpbmVhckdyYWRpZW50Jywge1xuXHRcdFx0XHRpbnNpZGU6IHRoaXMuc3ZnX2RlZnMsXG5cdFx0XHRcdGlkOiBncmFkaWVudF9pZCxcblx0XHRcdFx0eDE6IDAsXG5cdFx0XHRcdHgyOiAwLFxuXHRcdFx0XHR5MTogMCxcblx0XHRcdFx0eTI6IDFcblx0XHRcdH0pO1xuXG5cdFx0XHRsZXQgc2V0X2dyYWRpZW50X3N0b3AgPSAoZ3JhZF9lbGVtLCBvZmZzZXQsIGNvbG9yLCBvcGFjaXR5KSA9PiB7XG5cdFx0XHRcdCQuY3JlYXRlU1ZHKCdzdG9wJywge1xuXHRcdFx0XHRcdCdjbGFzc05hbWUnOiAnc3RvcC1jb2xvciAnICsgY29sb3IsXG5cdFx0XHRcdFx0J2luc2lkZSc6IGdyYWRfZWxlbSxcblx0XHRcdFx0XHQnb2Zmc2V0Jzogb2Zmc2V0LFxuXHRcdFx0XHRcdCdzdG9wLW9wYWNpdHknOiBvcGFjaXR5XG5cdFx0XHRcdH0pO1xuXHRcdFx0fTtcblxuXHRcdFx0c2V0X2dyYWRpZW50X3N0b3AodGhpcy5ncmFkaWVudF9kZWYsIFwiMCVcIiwgY29sb3IsIDAuNCk7XG5cdFx0XHRzZXRfZ3JhZGllbnRfc3RvcCh0aGlzLmdyYWRpZW50X2RlZiwgXCI1MCVcIiwgY29sb3IsIDAuMik7XG5cdFx0XHRzZXRfZ3JhZGllbnRfc3RvcCh0aGlzLmdyYWRpZW50X2RlZiwgXCIxMDAlXCIsIGNvbG9yLCAwKTtcblxuXHRcdFx0ZC5yZWdpb25fcGF0aCA9ICQuY3JlYXRlU1ZHKCdwYXRoJywge1xuXHRcdFx0XHRpbnNpZGU6IHRoaXMucGF0aHNfZ3JvdXBzW2ldLFxuXHRcdFx0XHRjbGFzc05hbWU6IGByZWdpb24tZmlsbGAsXG5cdFx0XHRcdGQ6IFwiTVwiICsgYDAsJHt0aGlzLnplcm9fbGluZX1MYCArIHBvaW50c19zdHIgKyBgTCR7dGhpcy53aWR0aH0sJHt0aGlzLnplcm9fbGluZX1gLFxuXHRcdFx0fSk7XG5cblx0XHRcdGQucmVnaW9uX3BhdGguc3R5bGUuc3Ryb2tlID0gXCJub25lXCI7XG5cdFx0XHRkLnJlZ2lvbl9wYXRoLnN0eWxlLmZpbGwgPSBgdXJsKCMke2dyYWRpZW50X2lkfSlgO1xuXHRcdH1cblx0fVxufVxuXG5jbGFzcyBQZXJjZW50YWdlQ2hhcnQgZXh0ZW5kcyBDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblx0XHR0aGlzLnR5cGUgPSAncGVyY2VudGFnZSc7XG5cblx0XHR0aGlzLmdldF95X2xhYmVsID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X2xhYmVsO1xuXHRcdHRoaXMuZ2V0X3hfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueF90b29sdGlwO1xuXHRcdHRoaXMuZ2V0X3lfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueV90b29sdGlwO1xuXG5cdFx0dGhpcy5tYXhfc2xpY2VzID0gMTA7XG5cdFx0dGhpcy5tYXhfbGVnZW5kX3BvaW50cyA9IDY7XG5cblx0XHR0aGlzLmNvbG9ycyA9IGFyZ3MuY29sb3JzO1xuXG5cdFx0aWYoIXRoaXMuY29sb3JzIHx8IHRoaXMuY29sb3JzLmxlbmd0aCA8IHRoaXMuZGF0YS5sYWJlbHMubGVuZ3RoKSB7XG5cdFx0XHR0aGlzLmNvbG9ycyA9IFsnbGlnaHQtYmx1ZScsICdibHVlJywgJ3Zpb2xldCcsICdyZWQnLCAnb3JhbmdlJyxcblx0XHRcdFx0J3llbGxvdycsICdncmVlbicsICdsaWdodC1ncmVlbicsICdwdXJwbGUnLCAnbWFnZW50YSddO1xuXHRcdH1cblxuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdG1ha2VfY2hhcnRfYXJlYSgpIHtcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuY2xhc3NOYW1lICs9ICcgJyArICdncmFwaC1mb2N1cy1tYXJnaW4nO1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5zdHlsZS5tYXJnaW5Ub3AgPSAnNDVweCc7XG5cblx0XHR0aGlzLnN0YXRzX3dyYXBwZXIuY2xhc3NOYW1lICs9ICcgJyArICdncmFwaC1mb2N1cy1tYXJnaW4nO1xuXHRcdHRoaXMuc3RhdHNfd3JhcHBlci5zdHlsZS5tYXJnaW5Cb3R0b20gPSAnMzBweCc7XG5cdFx0dGhpcy5zdGF0c193cmFwcGVyLnN0eWxlLnBhZGRpbmdUb3AgPSAnMHB4Jztcblx0fVxuXG5cdG1ha2VfZHJhd19hcmVhKCkge1xuXHRcdHRoaXMuY2hhcnRfZGl2ID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2RpdicsXG5cdFx0XHRpbnNpZGU6IHRoaXMuY2hhcnRfd3JhcHBlcixcblx0XHRcdHdpZHRoOiB0aGlzLmJhc2Vfd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IHRoaXMuYmFzZV9oZWlnaHRcblx0XHR9KTtcblxuXHRcdHRoaXMuY2hhcnQgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiAncHJvZ3Jlc3MtY2hhcnQnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmNoYXJ0X2RpdlxuXHRcdH0pO1xuXHR9XG5cblx0c2V0dXBfY29tcG9uZW50cygpIHtcblx0XHR0aGlzLnBlcmNlbnRhZ2VfYmFyID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ3Byb2dyZXNzJyxcblx0XHRcdGluc2lkZTogdGhpcy5jaGFydFxuXHRcdH0pO1xuXHR9XG5cblx0c2V0dXBfdmFsdWVzKCkge1xuXHRcdHRoaXMuc2xpY2VfdG90YWxzID0gW107XG5cdFx0bGV0IGFsbF90b3RhbHMgPSB0aGlzLmRhdGEubGFiZWxzLm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0bGV0IHRvdGFsID0gMDtcblx0XHRcdHRoaXMuZGF0YS5kYXRhc2V0cy5tYXAoZSA9PiB7XG5cdFx0XHRcdHRvdGFsICs9IGUudmFsdWVzW2ldO1xuXHRcdFx0fSk7XG5cdFx0XHRyZXR1cm4gW3RvdGFsLCBkXTtcblx0XHR9KS5maWx0ZXIoZCA9PiB7IHJldHVybiBkWzBdID4gMDsgfSk7IC8vIGtlZXAgb25seSBwb3NpdGl2ZSByZXN1bHRzXG5cblx0XHRsZXQgdG90YWxzID0gYWxsX3RvdGFscztcblxuXHRcdGlmKGFsbF90b3RhbHMubGVuZ3RoID4gdGhpcy5tYXhfc2xpY2VzKSB7XG5cdFx0XHRhbGxfdG90YWxzLnNvcnQoKGEsIGIpID0+IHsgcmV0dXJuIGJbMF0gLSBhWzBdOyB9KTtcblxuXHRcdFx0dG90YWxzID0gYWxsX3RvdGFscy5zbGljZSgwLCB0aGlzLm1heF9zbGljZXMtMSk7XG5cdFx0XHRsZXQgb3RoZXJzID0gYWxsX3RvdGFscy5zbGljZSh0aGlzLm1heF9zbGljZXMtMSk7XG5cblx0XHRcdGxldCBzdW1fb2Zfb3RoZXJzID0gMDtcblx0XHRcdG90aGVycy5tYXAoZCA9PiB7c3VtX29mX290aGVycyArPSBkWzBdO30pO1xuXG5cdFx0XHR0b3RhbHMucHVzaChbc3VtX29mX290aGVycywgJ1Jlc3QnXSk7XG5cblx0XHRcdHRoaXMuY29sb3JzW3RoaXMubWF4X3NsaWNlcy0xXSA9ICdncmV5Jztcblx0XHR9XG5cblx0XHR0aGlzLmxhYmVscyA9IFtdO1xuXHRcdHRvdGFscy5tYXAoZCA9PiB7XG5cdFx0XHR0aGlzLnNsaWNlX3RvdGFscy5wdXNoKGRbMF0pO1xuXHRcdFx0dGhpcy5sYWJlbHMucHVzaChkWzFdKTtcblx0XHR9KTtcblxuXHRcdHRoaXMubGVnZW5kX3RvdGFscyA9IHRoaXMuc2xpY2VfdG90YWxzLnNsaWNlKDAsIHRoaXMubWF4X2xlZ2VuZF9wb2ludHMpO1xuXHR9XG5cblx0c2V0dXBfdXRpbHMoKSB7IH1cblxuXHRtYWtlX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5ncmFuZF90b3RhbCA9IHRoaXMuc2xpY2VfdG90YWxzLnJlZHVjZSgoYSwgYikgPT4gYSArIGIsIDApO1xuXHRcdHRoaXMuc2xpY2VzID0gW107XG5cdFx0dGhpcy5zbGljZV90b3RhbHMubWFwKCh0b3RhbCwgaSkgPT4ge1xuXHRcdFx0bGV0IHNsaWNlID0gJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiBgcHJvZ3Jlc3MtYmFyIGJhY2tncm91bmQgJHt0aGlzLmNvbG9yc1tpXX1gLFxuXHRcdFx0XHRzdHlsZTogYHdpZHRoOiAke3RvdGFsKjEwMC90aGlzLmdyYW5kX3RvdGFsfSVgLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMucGVyY2VudGFnZV9iYXJcblx0XHRcdH0pO1xuXHRcdFx0dGhpcy5zbGljZXMucHVzaChzbGljZSk7XG5cdFx0fSk7XG5cdH1cblxuXHRiaW5kX3Rvb2x0aXAoKSB7XG5cdFx0dGhpcy5zbGljZXMubWFwKChzbGljZSwgaSkgPT4ge1xuXHRcdFx0c2xpY2UuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VlbnRlcicsICgpID0+IHtcblx0XHRcdFx0bGV0IGdfb2ZmID0gJC5vZmZzZXQodGhpcy5jaGFydF93cmFwcGVyKSwgcF9vZmYgPSAkLm9mZnNldChzbGljZSk7XG5cblx0XHRcdFx0bGV0IHggPSBwX29mZi5sZWZ0IC0gZ19vZmYubGVmdCArIHNsaWNlLm9mZnNldFdpZHRoLzI7XG5cdFx0XHRcdGxldCB5ID0gcF9vZmYudG9wIC0gZ19vZmYudG9wIC0gNjtcblx0XHRcdFx0bGV0IHRpdGxlID0gKHRoaXMuZm9ybWF0dGVkX2xhYmVscyAmJiB0aGlzLmZvcm1hdHRlZF9sYWJlbHMubGVuZ3RoPjBcblx0XHRcdFx0XHQ/IHRoaXMuZm9ybWF0dGVkX2xhYmVsc1tpXSA6IHRoaXMubGFiZWxzW2ldKSArICc6ICc7XG5cdFx0XHRcdGxldCBwZXJjZW50ID0gKHRoaXMuc2xpY2VfdG90YWxzW2ldKjEwMC90aGlzLmdyYW5kX3RvdGFsKS50b0ZpeGVkKDEpO1xuXG5cdFx0XHRcdHRoaXMudGlwLnNldF92YWx1ZXMoeCwgeSwgdGl0bGUsIHBlcmNlbnQgKyBcIiVcIik7XG5cdFx0XHRcdHRoaXMudGlwLnNob3dfdGlwKCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHNob3dfc3VtbWFyeSgpIHtcblx0XHRsZXQgeF92YWx1ZXMgPSB0aGlzLmZvcm1hdHRlZF9sYWJlbHMgJiYgdGhpcy5mb3JtYXR0ZWRfbGFiZWxzLmxlbmd0aCA+IDBcblx0XHRcdD8gdGhpcy5mb3JtYXR0ZWRfbGFiZWxzIDogdGhpcy5sYWJlbHM7XG5cdFx0dGhpcy5sZWdlbmRfdG90YWxzLm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0aWYoZCkge1xuXHRcdFx0XHRsZXQgc3RhdHMgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0XHRcdGNsYXNzTmFtZTogJ3N0YXRzJyxcblx0XHRcdFx0XHRpbnNpZGU6IHRoaXMuc3RhdHNfd3JhcHBlclxuXHRcdFx0XHR9KTtcblx0XHRcdFx0c3RhdHMuaW5uZXJIVE1MID0gYDxzcGFuIGNsYXNzPVwiaW5kaWNhdG9yICR7dGhpcy5jb2xvcnNbaV19XCI+XG5cdFx0XHRcdFx0PHNwYW4gY2xhc3M9XCJ0ZXh0LW11dGVkXCI+JHt4X3ZhbHVlc1tpXX06PC9zcGFuPlxuXHRcdFx0XHRcdCR7ZH1cblx0XHRcdFx0PC9zcGFuPmA7XG5cdFx0XHR9XG5cdFx0fSk7XG5cdH1cbn1cblxuY2xhc3MgSGVhdE1hcCBleHRlbmRzIENoYXJ0IHtcblx0Y29uc3RydWN0b3Ioe1xuXHRcdHN0YXJ0ID0gJycsXG5cdFx0ZG9tYWluID0gJycsXG5cdFx0c3ViZG9tYWluID0gJycsXG5cdFx0ZGF0YSA9IHt9LFxuXHRcdGRpc2NyZXRlX2RvbWFpbnMgPSAwLFxuXHRcdGNvdW50X2xhYmVsID0gJydcblx0fSkge1xuXHRcdHN1cGVyKGFyZ3VtZW50c1swXSk7XG5cblx0XHR0aGlzLnR5cGUgPSAnaGVhdG1hcCc7XG5cblx0XHR0aGlzLmRvbWFpbiA9IGRvbWFpbjtcblx0XHR0aGlzLnN1YmRvbWFpbiA9IHN1YmRvbWFpbjtcblx0XHR0aGlzLmRhdGEgPSBkYXRhO1xuXHRcdHRoaXMuZGlzY3JldGVfZG9tYWlucyA9IGRpc2NyZXRlX2RvbWFpbnM7XG5cdFx0dGhpcy5jb3VudF9sYWJlbCA9IGNvdW50X2xhYmVsO1xuXG5cdFx0bGV0IHRvZGF5ID0gbmV3IERhdGUoKTtcblx0XHR0aGlzLnN0YXJ0ID0gc3RhcnQgfHwgdGhpcy5hZGRfZGF5cyh0b2RheSwgMzY1KTtcblxuXHRcdHRoaXMubGVnZW5kX2NvbG9ycyA9IFsnI2ViZWRmMCcsICcjYzZlNDhiJywgJyM3YmM5NmYnLCAnIzIzOWEzYicsICcjMTk2MTI3J107XG5cblx0XHR0aGlzLnRyYW5zbGF0ZV94ID0gMDtcblx0XHR0aGlzLnNldHVwKCk7XG5cdH1cblxuXHRzZXR1cF9iYXNlX3ZhbHVlcygpIHtcblx0XHR0aGlzLnRvZGF5ID0gbmV3IERhdGUoKTtcblxuXHRcdGlmKCF0aGlzLnN0YXJ0KSB7XG5cdFx0XHR0aGlzLnN0YXJ0ID0gbmV3IERhdGUoKTtcblx0XHRcdHRoaXMuc3RhcnQuc2V0RnVsbFllYXIoIHRoaXMuc3RhcnQuZ2V0RnVsbFllYXIoKSAtIDEgKTtcblx0XHR9XG5cdFx0dGhpcy5maXJzdF93ZWVrX3N0YXJ0ID0gbmV3IERhdGUodGhpcy5zdGFydC50b0RhdGVTdHJpbmcoKSk7XG5cdFx0dGhpcy5sYXN0X3dlZWtfc3RhcnQgPSBuZXcgRGF0ZSh0aGlzLnRvZGF5LnRvRGF0ZVN0cmluZygpKTtcblx0XHRpZih0aGlzLmZpcnN0X3dlZWtfc3RhcnQuZ2V0RGF5KCkgIT09IDcpIHtcblx0XHRcdHRoaXMuYWRkX2RheXModGhpcy5maXJzdF93ZWVrX3N0YXJ0LCAoLTEpICogdGhpcy5maXJzdF93ZWVrX3N0YXJ0LmdldERheSgpKTtcblx0XHR9XG5cdFx0aWYodGhpcy5sYXN0X3dlZWtfc3RhcnQuZ2V0RGF5KCkgIT09IDcpIHtcblx0XHRcdHRoaXMuYWRkX2RheXModGhpcy5sYXN0X3dlZWtfc3RhcnQsICgtMSkgKiB0aGlzLmxhc3Rfd2Vla19zdGFydC5nZXREYXkoKSk7XG5cdFx0fVxuXHRcdHRoaXMubm9fb2ZfY29scyA9IHRoaXMuZ2V0X3dlZWtzX2JldHdlZW4odGhpcy5maXJzdF93ZWVrX3N0YXJ0ICsgJycsIHRoaXMubGFzdF93ZWVrX3N0YXJ0ICsgJycpICsgMTtcblx0fVxuXG5cdHNldF93aWR0aCgpIHtcblx0XHR0aGlzLmJhc2Vfd2lkdGggPSAodGhpcy5ub19vZl9jb2xzKSAqIDEyO1xuXG5cdFx0aWYodGhpcy5kaXNjcmV0ZV9kb21haW5zKSB7XG5cdFx0XHR0aGlzLmJhc2Vfd2lkdGggKz0gKDEyICogMTIpO1xuXHRcdH1cblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5kb21haW5fbGFiZWxfZ3JvdXAgPSAkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRvbWFpbi1sYWJlbC1ncm91cCBjaGFydC1sYWJlbFwiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYVxuXHRcdH0pO1xuXHRcdHRoaXMuZGF0YV9ncm91cHMgPSAkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRhdGEtZ3JvdXBzXCIsXG5cdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhLFxuXHRcdFx0dHJhbnNmb3JtOiBgdHJhbnNsYXRlKDAsIDIwKWBcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX3ZhbHVlcygpIHtcblx0XHR0aGlzLmRvbWFpbl9sYWJlbF9ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMuZGF0YV9ncm91cHMudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLmRpc3RyaWJ1dGlvbiA9IHRoaXMuZ2V0X2Rpc3RyaWJ1dGlvbih0aGlzLmRhdGEsIHRoaXMubGVnZW5kX2NvbG9ycyk7XG5cdFx0dGhpcy5tb250aF9uYW1lcyA9IFtcIkphbnVhcnlcIiwgXCJGZWJydWFyeVwiLCBcIk1hcmNoXCIsIFwiQXByaWxcIiwgXCJNYXlcIiwgXCJKdW5lXCIsXG5cdFx0XHRcIkp1bHlcIiwgXCJBdWd1c3RcIiwgXCJTZXB0ZW1iZXJcIiwgXCJPY3RvYmVyXCIsIFwiTm92ZW1iZXJcIiwgXCJEZWNlbWJlclwiXG5cdFx0XTtcblxuXHRcdHRoaXMucmVuZGVyX2FsbF93ZWVrc19hbmRfc3RvcmVfeF92YWx1ZXModGhpcy5ub19vZl9jb2xzKTtcblx0fVxuXG5cdHJlbmRlcl9hbGxfd2Vla3NfYW5kX3N0b3JlX3hfdmFsdWVzKG5vX29mX3dlZWtzKSB7XG5cdFx0bGV0IGN1cnJlbnRfd2Vla19zdW5kYXkgPSBuZXcgRGF0ZSh0aGlzLmZpcnN0X3dlZWtfc3RhcnQpO1xuXHRcdHRoaXMud2Vla19jb2wgPSAwO1xuXHRcdHRoaXMuY3VycmVudF9tb250aCA9IGN1cnJlbnRfd2Vla19zdW5kYXkuZ2V0TW9udGgoKTtcblxuXHRcdHRoaXMubW9udGhzID0gW3RoaXMuY3VycmVudF9tb250aCArICcnXTtcblx0XHR0aGlzLm1vbnRoX3dlZWtzID0ge30sIHRoaXMubW9udGhfc3RhcnRfcG9pbnRzID0gW107XG5cdFx0dGhpcy5tb250aF93ZWVrc1t0aGlzLmN1cnJlbnRfbW9udGhdID0gMDtcblx0XHR0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5wdXNoKDEzKTtcblxuXHRcdGZvcih2YXIgaSA9IDA7IGkgPCBub19vZl93ZWVrczsgaSsrKSB7XG5cdFx0XHRsZXQgZGF0YV9ncm91cCwgbW9udGhfY2hhbmdlID0gMDtcblx0XHRcdGxldCBkYXkgPSBuZXcgRGF0ZShjdXJyZW50X3dlZWtfc3VuZGF5KTtcblxuXHRcdFx0W2RhdGFfZ3JvdXAsIG1vbnRoX2NoYW5nZV0gPSB0aGlzLmdldF93ZWVrX3NxdWFyZXNfZ3JvdXAoZGF5LCB0aGlzLndlZWtfY29sKTtcblx0XHRcdHRoaXMuZGF0YV9ncm91cHMuYXBwZW5kQ2hpbGQoZGF0YV9ncm91cCk7XG5cdFx0XHR0aGlzLndlZWtfY29sICs9IDEgKyBwYXJzZUludCh0aGlzLmRpc2NyZXRlX2RvbWFpbnMgJiYgbW9udGhfY2hhbmdlKTtcblx0XHRcdHRoaXMubW9udGhfd2Vla3NbdGhpcy5jdXJyZW50X21vbnRoXSsrO1xuXHRcdFx0aWYobW9udGhfY2hhbmdlKSB7XG5cdFx0XHRcdHRoaXMuY3VycmVudF9tb250aCA9ICh0aGlzLmN1cnJlbnRfbW9udGggKyAxKSAlIDEyO1xuXHRcdFx0XHR0aGlzLm1vbnRocy5wdXNoKHRoaXMuY3VycmVudF9tb250aCArICcnKTtcblx0XHRcdFx0dGhpcy5tb250aF93ZWVrc1t0aGlzLmN1cnJlbnRfbW9udGhdID0gMTtcblx0XHRcdH1cblx0XHRcdHRoaXMuYWRkX2RheXMoY3VycmVudF93ZWVrX3N1bmRheSwgNyk7XG5cdFx0fVxuXHRcdHRoaXMucmVuZGVyX21vbnRoX2xhYmVscygpO1xuXHR9XG5cblx0Z2V0X3dlZWtfc3F1YXJlc19ncm91cChjdXJyZW50X2RhdGUsIGluZGV4KSB7XG5cdFx0Y29uc3Qgbm9fb2Zfd2Vla2RheXMgPSA3O1xuXHRcdGNvbnN0IHNxdWFyZV9zaWRlID0gMTA7XG5cdFx0Y29uc3QgY2VsbF9wYWRkaW5nID0gMjtcblx0XHRjb25zdCBzdGVwID0gMTtcblxuXHRcdGxldCBtb250aF9jaGFuZ2UgPSAwO1xuXHRcdGxldCB3ZWVrX2NvbF9jaGFuZ2UgPSAwO1xuXG5cdFx0bGV0IGRhdGFfZ3JvdXAgPSAkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRhdGEtZ3JvdXBcIixcblx0XHRcdGluc2lkZTogdGhpcy5kYXRhX2dyb3Vwc1xuXHRcdH0pO1xuXG5cdFx0Zm9yKHZhciB5ID0gMCwgaSA9IDA7IGkgPCBub19vZl93ZWVrZGF5czsgaSArPSBzdGVwLCB5ICs9IChzcXVhcmVfc2lkZSArIGNlbGxfcGFkZGluZykpIHtcblx0XHRcdGxldCBkYXRhX3ZhbHVlID0gMDtcblx0XHRcdGxldCBjb2xvcl9pbmRleCA9IDA7XG5cblx0XHRcdGxldCB0aW1lc3RhbXAgPSBNYXRoLmZsb29yKGN1cnJlbnRfZGF0ZS5nZXRUaW1lKCkvMTAwMCkudG9GaXhlZCgxKTtcblxuXHRcdFx0aWYodGhpcy5kYXRhW3RpbWVzdGFtcF0pIHtcblx0XHRcdFx0ZGF0YV92YWx1ZSA9IHRoaXMuZGF0YVt0aW1lc3RhbXBdO1xuXHRcdFx0XHRjb2xvcl9pbmRleCA9IHRoaXMuZ2V0X21heF9jaGVja3BvaW50KGRhdGFfdmFsdWUsIHRoaXMuZGlzdHJpYnV0aW9uKTtcblx0XHRcdH1cblxuXHRcdFx0aWYodGhpcy5kYXRhW01hdGgucm91bmQodGltZXN0YW1wKV0pIHtcblx0XHRcdFx0ZGF0YV92YWx1ZSA9IHRoaXMuZGF0YVtNYXRoLnJvdW5kKHRpbWVzdGFtcCldO1xuXHRcdFx0XHRjb2xvcl9pbmRleCA9IHRoaXMuZ2V0X21heF9jaGVja3BvaW50KGRhdGFfdmFsdWUsIHRoaXMuZGlzdHJpYnV0aW9uKTtcblx0XHRcdH1cblxuXHRcdFx0bGV0IHggPSAxMyArIChpbmRleCArIHdlZWtfY29sX2NoYW5nZSkgKiAxMjtcblxuXHRcdFx0JC5jcmVhdGVTVkcoXCJyZWN0XCIsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnZGF5Jyxcblx0XHRcdFx0aW5zaWRlOiBkYXRhX2dyb3VwLFxuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGhlaWdodDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGZpbGw6ICB0aGlzLmxlZ2VuZF9jb2xvcnNbY29sb3JfaW5kZXhdLFxuXHRcdFx0XHQnZGF0YS1kYXRlJzogdGhpcy5nZXRfZGRfbW1feXl5eShjdXJyZW50X2RhdGUpLFxuXHRcdFx0XHQnZGF0YS12YWx1ZSc6IGRhdGFfdmFsdWUsXG5cdFx0XHRcdCdkYXRhLWRheSc6IGN1cnJlbnRfZGF0ZS5nZXREYXkoKVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBuZXh0X2RhdGUgPSBuZXcgRGF0ZShjdXJyZW50X2RhdGUpO1xuXHRcdFx0dGhpcy5hZGRfZGF5cyhuZXh0X2RhdGUsIDEpO1xuXHRcdFx0aWYobmV4dF9kYXRlLmdldE1vbnRoKCkgLSBjdXJyZW50X2RhdGUuZ2V0TW9udGgoKSkge1xuXHRcdFx0XHRtb250aF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHRpZih0aGlzLmRpc2NyZXRlX2RvbWFpbnMpIHtcblx0XHRcdFx0XHR3ZWVrX2NvbF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucHVzaCgxMyArIChpbmRleCArIHdlZWtfY29sX2NoYW5nZSkgKiAxMik7XG5cdFx0XHR9XG5cdFx0XHRjdXJyZW50X2RhdGUgPSBuZXh0X2RhdGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtkYXRhX2dyb3VwLCBtb250aF9jaGFuZ2VdO1xuXHR9XG5cblx0cmVuZGVyX21vbnRoX2xhYmVscygpIHtcblx0XHQvLyB0aGlzLmZpcnN0X21vbnRoX2xhYmVsID0gMTtcblx0XHQvLyBpZiAodGhpcy5maXJzdF93ZWVrX3N0YXJ0LmdldERhdGUoKSA+IDgpIHtcblx0XHQvLyBcdHRoaXMuZmlyc3RfbW9udGhfbGFiZWwgPSAwO1xuXHRcdC8vIH1cblx0XHQvLyB0aGlzLmxhc3RfbW9udGhfbGFiZWwgPSAxO1xuXG5cdFx0Ly8gbGV0IGZpcnN0X21vbnRoID0gdGhpcy5tb250aHMuc2hpZnQoKTtcblx0XHQvLyBsZXQgZmlyc3RfbW9udGhfc3RhcnQgPSB0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5zaGlmdCgpO1xuXHRcdC8vIHJlbmRlciBmaXJzdCBtb250aCBpZlxuXG5cdFx0Ly8gbGV0IGxhc3RfbW9udGggPSB0aGlzLm1vbnRocy5wb3AoKTtcblx0XHQvLyBsZXQgbGFzdF9tb250aF9zdGFydCA9IHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnBvcCgpO1xuXHRcdC8vIHJlbmRlciBsYXN0IG1vbnRoIGlmXG5cblx0XHR0aGlzLm1vbnRocy5zaGlmdCgpO1xuXHRcdHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnNoaWZ0KCk7XG5cdFx0dGhpcy5tb250aHMucG9wKCk7XG5cdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucG9wKCk7XG5cblx0XHR0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5tYXAoKHN0YXJ0LCBpKSA9PiB7XG5cdFx0XHRsZXQgbW9udGhfbmFtZSA9ICB0aGlzLm1vbnRoX25hbWVzW3RoaXMubW9udGhzW2ldXS5zdWJzdHJpbmcoMCwgMyk7XG5cblx0XHRcdCQuY3JlYXRlU1ZHKCd0ZXh0Jywge1xuXHRcdFx0XHRjbGFzc05hbWU6ICd5LXZhbHVlLXRleHQnLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZG9tYWluX2xhYmVsX2dyb3VwLFxuXHRcdFx0XHR4OiBzdGFydCArIDEyLFxuXHRcdFx0XHR5OiAxMCxcblx0XHRcdFx0ZHk6ICcuMzJlbScsXG5cdFx0XHRcdGlubmVySFRNTDogbW9udGhfbmFtZVxuXHRcdFx0fSk7XG5cblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfZ3JhcGhfY29tcG9uZW50cygpIHtcblx0XHRBcnJheS5wcm90b3R5cGUuc2xpY2UuY2FsbChcblx0XHRcdHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3JBbGwoJy5ncmFwaC1zdGF0cy1jb250YWluZXIsIC5zdWItdGl0bGUsIC50aXRsZScpXG5cdFx0KS5tYXAoZCA9PiB7XG5cdFx0XHRkLnN0eWxlLmRpc3BsYXkgPSAnTm9uZSc7XG5cdFx0fSk7XG5cdFx0dGhpcy5jaGFydF93cmFwcGVyLnN0eWxlLm1hcmdpblRvcCA9ICcwcHgnO1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5zdHlsZS5wYWRkaW5nVG9wID0gJzBweCc7XG5cdH1cblxuXHRiaW5kX3Rvb2x0aXAoKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoXG5cdFx0XHRkb2N1bWVudC5xdWVyeVNlbGVjdG9yQWxsKFwiLmRhdGEtZ3JvdXAgLmRheVwiKVxuXHRcdCkubWFwKGVsID0+IHtcblx0XHRcdGVsLmFkZEV2ZW50TGlzdGVuZXIoJ21vdXNlZW50ZXInLCAoZSkgPT4ge1xuXHRcdFx0XHRsZXQgY291bnQgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtdmFsdWUnKTtcblx0XHRcdFx0bGV0IGRhdGVfcGFydHMgPSBlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ2RhdGEtZGF0ZScpLnNwbGl0KCctJyk7XG5cblx0XHRcdFx0bGV0IG1vbnRoID0gdGhpcy5tb250aF9uYW1lc1twYXJzZUludChkYXRlX3BhcnRzWzFdKS0xXS5zdWJzdHJpbmcoMCwgMyk7XG5cblx0XHRcdFx0bGV0IGdfb2ZmID0gdGhpcy5jaGFydF93cmFwcGVyLmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpLCBwX29mZiA9IGUudGFyZ2V0LmdldEJvdW5kaW5nQ2xpZW50UmVjdCgpO1xuXG5cdFx0XHRcdGxldCB3aWR0aCA9IHBhcnNlSW50KGUudGFyZ2V0LmdldEF0dHJpYnV0ZSgnd2lkdGgnKSk7XG5cdFx0XHRcdGxldCB4ID0gcF9vZmYubGVmdCAtIGdfb2ZmLmxlZnQgKyAod2lkdGgrMikvMjtcblx0XHRcdFx0bGV0IHkgPSBwX29mZi50b3AgLSBnX29mZi50b3AgLSAod2lkdGgrMikvMjtcblx0XHRcdFx0bGV0IHZhbHVlID0gY291bnQgKyAnICcgKyB0aGlzLmNvdW50X2xhYmVsO1xuXHRcdFx0XHRsZXQgbmFtZSA9ICcgb24gJyArIG1vbnRoICsgJyAnICsgZGF0ZV9wYXJ0c1swXSArICcsICcgKyBkYXRlX3BhcnRzWzJdO1xuXG5cdFx0XHRcdHRoaXMudGlwLnNldF92YWx1ZXMoeCwgeSwgbmFtZSwgdmFsdWUsIFtdLCAxKTtcblx0XHRcdFx0dGhpcy50aXAuc2hvd190aXAoKTtcblx0XHRcdH0pO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlKGRhdGEpIHtcblx0XHR0aGlzLmRhdGEgPSBkYXRhO1xuXHRcdHRoaXMuc2V0dXBfdmFsdWVzKCk7XG5cdFx0dGhpcy5iaW5kX3Rvb2x0aXAoKTtcblx0fVxuXG5cdGdldF9kaXN0cmlidXRpb24oZGF0YT17fSwgbWFwcGVyX2FycmF5KSB7XG5cdFx0bGV0IGRhdGFfdmFsdWVzID0gT2JqZWN0LmtleXMoZGF0YSkubWFwKGtleSA9PiBkYXRhW2tleV0pO1xuXHRcdGxldCBkYXRhX21heF92YWx1ZSA9IE1hdGgubWF4KC4uLmRhdGFfdmFsdWVzKTtcblxuXHRcdGxldCBkaXN0cmlidXRpb25fc3RlcCA9IDEgLyAobWFwcGVyX2FycmF5Lmxlbmd0aCAtIDEpO1xuXHRcdGxldCBkaXN0cmlidXRpb24gPSBbXTtcblxuXHRcdG1hcHBlcl9hcnJheS5tYXAoKGNvbG9yLCBpKSA9PiB7XG5cdFx0XHRsZXQgY2hlY2twb2ludCA9IGRhdGFfbWF4X3ZhbHVlICogKGRpc3RyaWJ1dGlvbl9zdGVwICogaSk7XG5cdFx0XHRkaXN0cmlidXRpb24ucHVzaChjaGVja3BvaW50KTtcblx0XHR9KTtcblxuXHRcdHJldHVybiBkaXN0cmlidXRpb247XG5cdH1cblxuXHRnZXRfbWF4X2NoZWNrcG9pbnQodmFsdWUsIGRpc3RyaWJ1dGlvbikge1xuXHRcdHJldHVybiBkaXN0cmlidXRpb24uZmlsdGVyKChkLCBpKSA9PiB7XG5cdFx0XHRpZihpID09PSAxKSB7XG5cdFx0XHRcdHJldHVybiBkaXN0cmlidXRpb25bMF0gPCB2YWx1ZTtcblx0XHRcdH1cblx0XHRcdHJldHVybiBkIDw9IHZhbHVlO1xuXHRcdH0pLmxlbmd0aCAtIDE7XG5cdH1cblxuXHQvLyBUT0RPOiBkYXRlIHV0aWxzLCBtb3ZlIHRoZXNlIG91dFxuXG5cdC8vIGh0dHBzOi8vc3RhY2tvdmVyZmxvdy5jb20vYS8xMTI1MjE2Ny82NDk1MDQzXG5cdHRyZWF0X2FzX3V0YyhkYXRlX3N0cikge1xuXHRcdGxldCByZXN1bHQgPSBuZXcgRGF0ZShkYXRlX3N0cik7XG5cdFx0cmVzdWx0LnNldE1pbnV0ZXMocmVzdWx0LmdldE1pbnV0ZXMoKSAtIHJlc3VsdC5nZXRUaW1lem9uZU9mZnNldCgpKTtcblx0XHRyZXR1cm4gcmVzdWx0O1xuXHR9XG5cblx0Z2V0X2RkX21tX3l5eXkoZGF0ZSkge1xuXHRcdGxldCBkZCA9IGRhdGUuZ2V0RGF0ZSgpO1xuXHRcdGxldCBtbSA9IGRhdGUuZ2V0TW9udGgoKSArIDE7IC8vIGdldE1vbnRoKCkgaXMgemVyby1iYXNlZFxuXHRcdHJldHVybiBbXG5cdFx0XHQoZGQ+OSA/ICcnIDogJzAnKSArIGRkLFxuXHRcdFx0KG1tPjkgPyAnJyA6ICcwJykgKyBtbSxcblx0XHRcdGRhdGUuZ2V0RnVsbFllYXIoKVxuXHRcdF0uam9pbignLScpO1xuXHR9XG5cblx0Z2V0X3dlZWtzX2JldHdlZW4oc3RhcnRfZGF0ZV9zdHIsIGVuZF9kYXRlX3N0cikge1xuXHRcdHJldHVybiBNYXRoLmNlaWwodGhpcy5nZXRfZGF5c19iZXR3ZWVuKHN0YXJ0X2RhdGVfc3RyLCBlbmRfZGF0ZV9zdHIpIC8gNyk7XG5cdH1cblxuXHRnZXRfZGF5c19iZXR3ZWVuKHN0YXJ0X2RhdGVfc3RyLCBlbmRfZGF0ZV9zdHIpIHtcblx0XHRsZXQgbWlsbGlzZWNvbmRzX3Blcl9kYXkgPSAyNCAqIDYwICogNjAgKiAxMDAwO1xuXHRcdHJldHVybiAodGhpcy50cmVhdF9hc191dGMoZW5kX2RhdGVfc3RyKSAtIHRoaXMudHJlYXRfYXNfdXRjKHN0YXJ0X2RhdGVfc3RyKSkgLyBtaWxsaXNlY29uZHNfcGVyX2RheTtcblx0fVxuXG5cdC8vIG11dGF0ZXNcblx0YWRkX2RheXMoZGF0ZSwgbnVtYmVyX29mX2RheXMpIHtcblx0XHRkYXRlLnNldERhdGUoZGF0ZS5nZXREYXRlKCkgKyBudW1iZXJfb2ZfZGF5cyk7XG5cdH1cblxuXHRnZXRfbW9udGhfbmFtZSgpIHt9XG59XG5cbmNsYXNzIFN2Z1RpcCB7XG5cdGNvbnN0cnVjdG9yKHtcblx0XHRwYXJlbnQgPSBudWxsXG5cdH0pIHtcblx0XHR0aGlzLnBhcmVudCA9IHBhcmVudDtcblx0XHR0aGlzLnRpdGxlX25hbWUgPSAnJztcblx0XHR0aGlzLnRpdGxlX3ZhbHVlID0gJyc7XG5cdFx0dGhpcy5saXN0X3ZhbHVlcyA9IFtdO1xuXHRcdHRoaXMudGl0bGVfdmFsdWVfZmlyc3QgPSAwO1xuXG5cdFx0dGhpcy54ID0gMDtcblx0XHR0aGlzLnkgPSAwO1xuXG5cdFx0dGhpcy50b3AgPSAwO1xuXHRcdHRoaXMubGVmdCA9IDA7XG5cblx0XHR0aGlzLnNldHVwKCk7XG5cdH1cblxuXHRzZXR1cCgpIHtcblx0XHR0aGlzLm1ha2VfdG9vbHRpcCgpO1xuXHR9XG5cblx0cmVmcmVzaCgpIHtcblx0XHR0aGlzLmZpbGwoKTtcblx0XHR0aGlzLmNhbGNfcG9zaXRpb24oKTtcblx0XHQvLyB0aGlzLnNob3dfdGlwKCk7XG5cdH1cblxuXHRtYWtlX3Rvb2x0aXAoKSB7XG5cdFx0dGhpcy5jb250YWluZXIgPSAkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnBhcmVudCxcblx0XHRcdGNsYXNzTmFtZTogJ2dyYXBoLXN2Zy10aXAgY29tcGFyaXNvbicsXG5cdFx0XHRpbm5lckhUTUw6IGA8c3BhbiBjbGFzcz1cInRpdGxlXCI+PC9zcGFuPlxuXHRcdFx0XHQ8dWwgY2xhc3M9XCJkYXRhLXBvaW50LWxpc3RcIj48L3VsPlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwic3ZnLXBvaW50ZXJcIj48L2Rpdj5gXG5cdFx0fSk7XG5cdFx0dGhpcy5oaWRlX3RpcCgpO1xuXG5cdFx0dGhpcy50aXRsZSA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy50aXRsZScpO1xuXHRcdHRoaXMuZGF0YV9wb2ludF9saXN0ID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignLmRhdGEtcG9pbnQtbGlzdCcpO1xuXG5cdFx0dGhpcy5wYXJlbnQuYWRkRXZlbnRMaXN0ZW5lcignbW91c2VsZWF2ZScsICgpID0+IHtcblx0XHRcdHRoaXMuaGlkZV90aXAoKTtcblx0XHR9KTtcblx0fVxuXG5cdGZpbGwoKSB7XG5cdFx0bGV0IHRpdGxlO1xuXHRcdGlmKHRoaXMudGl0bGVfdmFsdWVfZmlyc3QpIHtcblx0XHRcdHRpdGxlID0gYDxzdHJvbmc+JHt0aGlzLnRpdGxlX3ZhbHVlfTwvc3Ryb25nPiR7dGhpcy50aXRsZV9uYW1lfWA7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRpdGxlID0gYCR7dGhpcy50aXRsZV9uYW1lfTxzdHJvbmc+JHt0aGlzLnRpdGxlX3ZhbHVlfTwvc3Ryb25nPmA7XG5cdFx0fVxuXHRcdHRoaXMudGl0bGUuaW5uZXJIVE1MID0gdGl0bGU7XG5cdFx0dGhpcy5kYXRhX3BvaW50X2xpc3QuaW5uZXJIVE1MID0gJyc7XG5cblx0XHR0aGlzLmxpc3RfdmFsdWVzLm1hcCgoc2V0KSA9PiB7XG5cdFx0XHRsZXQgbGkgPSAkLmNyZWF0ZSgnbGknLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogYGJvcmRlci10b3AgJHtzZXQuY29sb3IgfHwgJ2JsYWNrJ31gLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3Ryb25nIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7XCI+JHtzZXQudmFsdWUgPyBzZXQudmFsdWUgOiAnJyB9PC9zdHJvbmc+XG5cdFx0XHRcdFx0JHtzZXQudGl0bGUgPyBzZXQudGl0bGUgOiAnJyB9YFxuXHRcdFx0fSk7XG5cblx0XHRcdHRoaXMuZGF0YV9wb2ludF9saXN0LmFwcGVuZENoaWxkKGxpKTtcblx0XHR9KTtcblx0fVxuXG5cdGNhbGNfcG9zaXRpb24oKSB7XG5cdFx0dGhpcy50b3AgPSB0aGlzLnkgLSB0aGlzLmNvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG5cdFx0dGhpcy5sZWZ0ID0gdGhpcy54IC0gdGhpcy5jb250YWluZXIub2Zmc2V0V2lkdGgvMjtcblx0XHRsZXQgbWF4X2xlZnQgPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHRoaXMuY29udGFpbmVyLm9mZnNldFdpZHRoO1xuXG5cdFx0bGV0IHBvaW50ZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuc3ZnLXBvaW50ZXInKTtcblxuXHRcdGlmKHRoaXMubGVmdCA8IDApIHtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSAtICR7LTEgKiB0aGlzLmxlZnR9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IDA7XG5cdFx0fSBlbHNlIGlmKHRoaXMubGVmdCA+IG1heF9sZWZ0KSB7XG5cdFx0XHRsZXQgZGVsdGEgPSB0aGlzLmxlZnQgLSBtYXhfbGVmdDtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSArICR7ZGVsdGF9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IG1heF9sZWZ0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwb2ludGVyLnN0eWxlLmxlZnQgPSBgNTAlYDtcblx0XHR9XG5cdH1cblxuXHRzZXRfdmFsdWVzKHgsIHksIHRpdGxlX25hbWUgPSAnJywgdGl0bGVfdmFsdWUgPSAnJywgbGlzdF92YWx1ZXMgPSBbXSwgdGl0bGVfdmFsdWVfZmlyc3QgPSAwKSB7XG5cdFx0dGhpcy50aXRsZV9uYW1lID0gdGl0bGVfbmFtZTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlID0gdGl0bGVfdmFsdWU7XG5cdFx0dGhpcy5saXN0X3ZhbHVlcyA9IGxpc3RfdmFsdWVzO1xuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlX2ZpcnN0ID0gdGl0bGVfdmFsdWVfZmlyc3Q7XG5cdFx0dGhpcy5yZWZyZXNoKCk7XG5cdH1cblxuXHRoaWRlX3RpcCgpIHtcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS50b3AgPSAnMHB4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gJzBweCc7XG5cdFx0dGhpcy5jb250YWluZXIuc3R5bGUub3BhY2l0eSA9ICcwJztcblx0fVxuXG5cdHNob3dfdGlwKCkge1xuXHRcdHRoaXMuY29udGFpbmVyLnN0eWxlLnRvcCA9IHRoaXMudG9wICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gdGhpcy5sZWZ0ICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5vcGFjaXR5ID0gJzEnO1xuXHR9XG59XG4iXSwibmFtZXMiOlsiJCIsImV4cHIiLCJjb24iLCJkb2N1bWVudCIsInF1ZXJ5U2VsZWN0b3IiLCJmaW5kTm9kZUluZGV4Iiwibm9kZSIsImkiLCJwcmV2aW91c1NpYmxpbmciLCJjcmVhdGUiLCJ0YWciLCJvIiwiZWxlbWVudCIsImNyZWF0ZUVsZW1lbnQiLCJ2YWwiLCJhcHBlbmRDaGlsZCIsInJlZiIsInBhcmVudE5vZGUiLCJpbnNlcnRCZWZvcmUiLCJzZXRBdHRyaWJ1dGUiLCJjcmVhdGVTVkciLCJjcmVhdGVFbGVtZW50TlMiLCJydW5TVkdBbmltYXRpb24iLCJzdmdfY29udGFpbmVyIiwiZWxlbWVudHMiLCJuZXdfZWxlbWVudHMiLCJhbmltX2VsZW1lbnRzIiwibWFwIiwib2JqIiwicGFyZW50IiwidW5pdCIsImFuaW1fZWxlbWVudCIsIm5ld19lbGVtZW50IiwiYW5pbWF0ZVNWRyIsInB1c2giLCJyZXBsYWNlQ2hpbGQiLCJhcnJheSIsImluZGV4Iiwib2JqZWN0Iiwia2V5IiwiYW5pbV9zdmciLCJjbG9uZU5vZGUiLCJwcm9wcyIsImR1ciIsImVhc2luZ190eXBlIiwidHlwZSIsInVuZGVmaW5lZCIsIm9sZF92YWx1ZXMiLCJlYXNpbmciLCJhdHRyaWJ1dGVOYW1lIiwiYW5pbWF0ZV9lbGVtZW50IiwiY3VycmVudF92YWx1ZSIsImdldEF0dHJpYnV0ZSIsInZhbHVlIiwiYW5pbV9hdHRyIiwib2Zmc2V0IiwicmVjdCIsImdldEJvdW5kaW5nQ2xpZW50UmVjdCIsInRvcCIsImRvY3VtZW50RWxlbWVudCIsInNjcm9sbFRvcCIsImJvZHkiLCJsZWZ0Iiwic2Nyb2xsTGVmdCIsImlzRWxlbWVudEluVmlld3BvcnQiLCJlbCIsImJvdHRvbSIsIndpbmRvdyIsImlubmVySGVpZ2h0IiwiY2xpZW50SGVpZ2h0IiwicmlnaHQiLCJpbm5lcldpZHRoIiwiY2xpZW50V2lkdGgiLCJiaW5kIiwiZXZlbnQiLCJjYWxsYmFjayIsInNwbGl0IiwiZm9yRWFjaCIsImFkZEV2ZW50TGlzdGVuZXIiLCJ1bmJpbmQiLCJyZW1vdmVFdmVudExpc3RlbmVyIiwiZmlyZSIsInRhcmdldCIsInByb3BlcnRpZXMiLCJldnQiLCJjcmVhdGVFdmVudCIsImluaXRFdmVudCIsImoiLCJkaXNwYXRjaEV2ZW50IiwiZmxvYXRfMiIsImQiLCJwYXJzZUZsb2F0IiwidG9GaXhlZCIsImFycmF5c19lcXVhbCIsImFycjEiLCJhcnIyIiwibGVuZ3RoIiwiYXJlX2VxdWFsIiwiQ2hhcnQiLCJoZWlnaHQiLCJ0aXRsZSIsInN1YnRpdGxlIiwiZGF0YSIsImZvcm1hdF9sYW1iZGFzIiwic3VtbWFyeSIsImlzX25hdmlnYWJsZSIsIk9iamVjdCIsImdldFByb3RvdHlwZU9mIiwicHJvdG90eXBlIiwiTGluZUNoYXJ0IiwiYXJndW1lbnRzIiwiQmFyQ2hhcnQiLCJQZXJjZW50YWdlQ2hhcnQiLCJIZWF0TWFwIiwicmF3X2NoYXJ0X2FyZ3MiLCJzcGVjaWZpY192YWx1ZXMiLCJjdXJyZW50X2luZGV4IiwiY2hhcnRfdHlwZXMiLCJzZXRfbWFyZ2lucyIsImluY2x1ZGVzIiwiZXJyb3IiLCJjb21wYXRpYmxlX3R5cGVzIiwiYmFzZV9oZWlnaHQiLCJ0cmFuc2xhdGVfeCIsInRyYW5zbGF0ZV95IiwiYmluZF93aW5kb3dfZXZlbnRzIiwicmVmcmVzaCIsImluaXQiLCJzZXR1cF9iYXNlX3ZhbHVlcyIsInNldF93aWR0aCIsInNldHVwX2NvbnRhaW5lciIsInNldHVwX2NvbXBvbmVudHMiLCJzZXR1cF92YWx1ZXMiLCJzZXR1cF91dGlscyIsIm1ha2VfZ3JhcGhfY29tcG9uZW50cyIsIm1ha2VfdG9vbHRpcCIsInNob3dfY3VzdG9tX3N1bW1hcnkiLCJzaG93X3N1bW1hcnkiLCJzZXR1cF9uYXZpZ2F0aW9uIiwic3BlY2lhbF92YWx1ZXNfd2lkdGgiLCJnZXRfc3Ryd2lkdGgiLCJiYXNlX3dpZHRoIiwib2Zmc2V0V2lkdGgiLCJ3aWR0aCIsImNvbnRhaW5lciIsImlubmVySFRNTCIsImNoYXJ0X3dyYXBwZXIiLCJzdGF0c193cmFwcGVyIiwibWFrZV9jaGFydF9hcmVhIiwibWFrZV9kcmF3X2FyZWEiLCJzdmciLCJzdmdfZGVmcyIsImRyYXdfYXJlYSIsInRpcCIsIlN2Z1RpcCIsImJpbmRfdG9vbHRpcCIsInN0YXRzIiwiY29sb3IiLCJtYWtlX292ZXJsYXkiLCJiaW5kX292ZXJsYXkiLCJlIiwia2V5Q29kZSIsIm9uX2xlZnRfYXJyb3ciLCJvbl9yaWdodF9hcnJvdyIsIm9uX3VwX2Fycm93Iiwib25fZG93bl9hcnJvdyIsIm9uX2VudGVyX2tleSIsImRhdGFfcG9pbnQiLCJ5IiwiZGF0YV9rZXkiLCJzbGljZSIsImxhYmVsIiwieCIsImdldF9kYXRhX3BvaW50Iiwic3RyaW5nIiwiQXhpc0NoYXJ0IiwiYXJncyIsImxhYmVscyIsImRhdGFzZXRzIiwiZ2V0X3lfbGFiZWwiLCJ5X2xhYmVsIiwiZ2V0X3lfdG9vbHRpcCIsInlfdG9vbHRpcCIsImdldF94X3Rvb2x0aXAiLCJ4X3Rvb2x0aXAiLCJjb2xvcnMiLCJ6ZXJvX2xpbmUiLCJ2YWx1ZXMiLCJpc05hTiIsInNldHVwX3giLCJzZXR1cF95Iiwic2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCIsInhfYXhpc19wb3NpdGlvbnMiLCJ4X29sZF9heGlzX3Bvc2l0aW9ucyIsInhfb2Zmc2V0IiwiYXZnX3VuaXRfd2lkdGgiLCJ5X2F4aXNfdmFsdWVzIiwieV9vbGRfYXhpc192YWx1ZXMiLCJnZXRfYWxsX3lfdmFsdWVzIiwieV9zdW1zIiwiY29uY2F0IiwiZ2V0X3lfYXhpc19wb2ludHMiLCJ5X3B0cyIsInZhbHVlX3JhbmdlIiwibXVsdGlwbGllciIsIm9sZF9tdWx0aXBsaWVyIiwiemVyb19pbmRleCIsImluZGV4T2YiLCJpbnRlcnZhbCIsImludGVydmFsX2hlaWdodCIsIm9sZF96ZXJvX2xpbmUiLCJzZXR1cF9tYXJrZXJfY29tcG9uZW50cyIsInNldHVwX2FnZ3JlZ2F0aW9uX2NvbXBvbmVudHMiLCJzZXR1cF9ncmFwaF9jb21wb25lbnRzIiwieV9heGlzX2dyb3VwIiwiY2xhc3NOYW1lIiwiaW5zaWRlIiwieF9heGlzX2dyb3VwIiwic3BlY2lmaWNfeV9ncm91cCIsInN1bV9ncm91cCIsImF2ZXJhZ2VfZ3JvdXAiLCJzdmdfdW5pdHNfZ3JvdXBzIiwibWFrZV95X2F4aXMiLCJtYWtlX3hfYXhpcyIsImRyYXdfZ3JhcGgiLCJtYWtlX3lfc3BlY2lmaWNzIiwiYW5pbWF0ZSIsInN0YXJ0X2F0IiwidGV4dF9zdGFydF9hdCIsImF4aXNfbGluZV9jbGFzcyIsInhfYXhpc19tb2RlIiwibWFrZV9hbmltX3hfYXhpcyIsInRleHRDb250ZW50IiwicG9pbnQiLCJtYWtlX3hfbGluZSIsIm1ha2VfYW5pbV95X2F4aXMiLCJtYWtlX2FuaW1feV9zcGVjaWZpY3MiLCJnZXRfeV9heGlzX2xpbmVfcHJvcHMiLCJ0ZXh0X2VuZF9hdCIsIm1ha2VfeV9saW5lIiwic3BlY2lmaWMiLCJ5X2F4aXNfbW9kZSIsImRyYXdfbmV3X2dyYXBoX2FuZF9hbmltYXRlIiwic3ZnX3VuaXRzIiwibWFrZV9wYXRoIiwieV90b3BzIiwibWFrZV9uZXdfdW5pdHMiLCJBcnJheSIsImZpbGwiLCJ1cGRhdGVfdmFsdWVzIiwibWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQiLCJ4X3ZhbHVlcyIsInlfdmFsdWVzIiwiZGF0YXNldF9pbmRleCIsIm5vX29mX2RhdGFzZXRzIiwiZ3JvdXAiLCJ1bml0X2FyZ3MiLCJkYXRhX3VuaXQiLCJkcmF3IiwidG9VcHBlckNhc2UiLCJsaW5lX3R5cGUiLCJyZWxYIiwicGFnZVgiLCJyZWxZIiwicGFnZVkiLCJtYXBfdG9vbHRpcF94X3Bvc2l0aW9uX2FuZF9zaG93IiwiaGlkZV90aXAiLCJ4X3ZhbCIsInlfbWluX3RvcHMiLCJmb3JtYXR0ZWQiLCJzZXQiLCJzZXRfdmFsdWVzIiwic2hvd190aXAiLCJ1cGRhdGluZyIsInN1bV91bml0cyIsIm9sZF9zcGVjaWZpY192YWx1ZXMiLCJzdW0iLCJhdmVyYWdlIiwiaW5kaWNlc190b19yZW1vdmUiLCJhdXRvIiwidW5zaGlmdCIsInNwbGljZSIsIm5ld195IiwibmV3X3giLCJlbGVtZW50c190b19hbmltYXRlIiwib2xkX3hfdmFsdWVzIiwib2xkX3lfYXhpc190b3BzIiwib2xkX3lfdmFsdWVzIiwibm9fb2ZfZXh0cmFfcHRzIiwiY2FsY195X2RlcGVuZGVuY2llcyIsImFuaW1hdGVfZ3JhcGhzIiwicnVuX2FuaW1hdGlvbiIsInlfcG9pbnQiLCJ4X3BvaW50IiwiZGF0YV9zZXQiLCJyZW1vdmVDaGlsZCIsImNhbGNfb2xkX2FuZF9uZXdfcG9zdGlvbnMiLCJvbGRfeCIsIm9sZF95IiwicGF0aCIsImFuaW1hdGVfcGF0aCIsImFuaW1hdGVfdW5pdHMiLCJuZXdfcG9pbnRzX2xpc3QiLCJuZXdfcGF0aF9zdHIiLCJqb2luIiwicGF0aF9hcmdzIiwicmVnaW9uX3BhdGgiLCJyZWdfc3RhcnRfcHQiLCJyZWdfZW5kX3B0IiwicmVnaW9uX2FyZ3MiLCJsYXN0X29sZF94X3BvcyIsImxhc3Rfb2xkX3lfcG9zIiwibGFzdF9uZXdfeF9wb3MiLCJsYXN0X25ld195X3BvcyIsImZpbGxlcl94IiwiTWF0aCIsImFicyIsImZpbGxlcl95Iiwib2xkX3BvcyIsIm5ld19wb3MiLCJvbGRfdmFscyIsIm5ld192YWxzIiwibGFzdF9saW5lX3BvcyIsImFkZF9hbmRfYW5pbWF0ZV9saW5lIiwieF9saW5lIiwidHJhbnNmb3JtIiwibWFrZV9uZXdfYXhpc19hbmltX2xpbmVzIiwiYWRkX2FuZF9hbmltYXRlX3lfbGluZSIsInN1cGVyaW1wb3NlZF9wb3NpdGlvbnMiLCJzdXBlcmltcG9zZWRfdmFsdWVzIiwibm9fb2ZfZXh0cmFzIiwiZmlsbGVyX3ZhbHMiLCJmaWxsZXJfcG9zIiwiZXh0cmFfdmFsdWVzIiwiZXh0cmFfcG9zaXRpb25zIiwibGFiZWxfY2xhc3MiLCJ4X3BvcyIsImFsbG93ZWRfc3BhY2UiLCJhbGxvd2VkX2xldHRlcnMiLCJsaW5lIiwidGV4dCIsInhfbGV2ZWwiLCJ5X3BvcyIsImRhcmtlciIsInlfbGV2ZWwiLCJzdHlsZSIsInN0cm9rZSIsImF4aXNfbGFiZWxfY2xhc3MiLCJ5X2xpbmUiLCJtYXhfYm91bmQiLCJtaW5fYm91bmQiLCJwb3Nfbm9fb2ZfcGFydHMiLCJuZWdfbm9fb2ZfcGFydHMiLCJwYXJ0X3NpemUiLCJtYXhfdmFsIiwicGFyc2VJbnQiLCJtYXgiLCJtaW5fdmFsIiwibWluIiwiZ2V0X3BhcmFtcyIsInZhbHVlMSIsInZhbHVlMiIsImJvdW5kMSIsImJvdW5kMiIsIm5vX29mX3BhcnRzXzEiLCJub19vZl9wYXJ0c18yIiwiaW50ZXJ2YWxfc2l6ZSIsImNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzIiwiY2FsY19ub19vZl9wYXJ0cyIsImFic19taW5fdmFsIiwibm9fb2ZfcGFydHMiLCJnZXRfaW50ZXJ2YWxzIiwic3RhcnQiLCJjb3VudCIsImludGVydmFscyIsInBvdyIsInVwcGVyX2JvdW5kIiwiZGl2aXNvciIsImNlaWwiLCJhbGxfdmFsdWVzIiwieV90b3AiLCJ0b3RhbF93aWR0aCIsInNwYWNlX3dpZHRoIiwic3RhcnRfeCIsImN1cnJlbnRfeCIsImdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIiLCJyYWRpdXMiLCJiYXJfb2JqIiwiZG90X29iaiIsImN4IiwiY3kiLCJzZXR1cCIsInVwZGF0ZV9jdXJyZW50X2RhdGFfcG9pbnQiLCJvdmVybGF5Iiwib3BhY2l0eSIsInVwZGF0ZV9vdmVybGF5Iiwic3ZnX3VuaXQiLCJhdHRyaWJ1dGVzIiwia2V5cyIsImZpbHRlciIsImF0dHIiLCJzcGVjaWZpZWQiLCJuYW1lIiwibm9kZVZhbHVlIiwicmVnaW9uX2ZpbGwiLCJzZXR1cF9wYXRoX2dyb3VwcyIsInBhdGhzX2dyb3VwcyIsInhfcG9zaXRpb25zIiwieV9wb3NpdGlvbnMiLCJwb2ludHNfbGlzdCIsInBvaW50c19zdHIiLCJncmFkaWVudF9pZCIsImdyYWRpZW50X2RlZiIsInNldF9ncmFkaWVudF9zdG9wIiwiZ3JhZF9lbGVtIiwibWF4X3NsaWNlcyIsIm1heF9sZWdlbmRfcG9pbnRzIiwibWFyZ2luVG9wIiwibWFyZ2luQm90dG9tIiwicGFkZGluZ1RvcCIsImNoYXJ0X2RpdiIsImNoYXJ0IiwicGVyY2VudGFnZV9iYXIiLCJzbGljZV90b3RhbHMiLCJhbGxfdG90YWxzIiwidG90YWwiLCJ0b3RhbHMiLCJzb3J0IiwiYSIsImIiLCJvdGhlcnMiLCJzdW1fb2Zfb3RoZXJzIiwibGVnZW5kX3RvdGFscyIsImdyYW5kX3RvdGFsIiwicmVkdWNlIiwic2xpY2VzIiwiZ19vZmYiLCJwX29mZiIsImZvcm1hdHRlZF9sYWJlbHMiLCJwZXJjZW50IiwiZG9tYWluIiwic3ViZG9tYWluIiwiZGlzY3JldGVfZG9tYWlucyIsImNvdW50X2xhYmVsIiwidG9kYXkiLCJEYXRlIiwiYWRkX2RheXMiLCJsZWdlbmRfY29sb3JzIiwic2V0RnVsbFllYXIiLCJnZXRGdWxsWWVhciIsImZpcnN0X3dlZWtfc3RhcnQiLCJ0b0RhdGVTdHJpbmciLCJsYXN0X3dlZWtfc3RhcnQiLCJnZXREYXkiLCJub19vZl9jb2xzIiwiZ2V0X3dlZWtzX2JldHdlZW4iLCJkb21haW5fbGFiZWxfZ3JvdXAiLCJkYXRhX2dyb3VwcyIsImRpc3RyaWJ1dGlvbiIsImdldF9kaXN0cmlidXRpb24iLCJtb250aF9uYW1lcyIsInJlbmRlcl9hbGxfd2Vla3NfYW5kX3N0b3JlX3hfdmFsdWVzIiwibm9fb2Zfd2Vla3MiLCJjdXJyZW50X3dlZWtfc3VuZGF5Iiwid2Vla19jb2wiLCJjdXJyZW50X21vbnRoIiwiZ2V0TW9udGgiLCJtb250aHMiLCJtb250aF93ZWVrcyIsIm1vbnRoX3N0YXJ0X3BvaW50cyIsImRhdGFfZ3JvdXAiLCJtb250aF9jaGFuZ2UiLCJkYXkiLCJnZXRfd2Vla19zcXVhcmVzX2dyb3VwIiwicmVuZGVyX21vbnRoX2xhYmVscyIsImN1cnJlbnRfZGF0ZSIsIm5vX29mX3dlZWtkYXlzIiwic3F1YXJlX3NpZGUiLCJjZWxsX3BhZGRpbmciLCJzdGVwIiwid2Vla19jb2xfY2hhbmdlIiwiZGF0YV92YWx1ZSIsImNvbG9yX2luZGV4IiwidGltZXN0YW1wIiwiZmxvb3IiLCJnZXRUaW1lIiwiZ2V0X21heF9jaGVja3BvaW50Iiwicm91bmQiLCJnZXRfZGRfbW1feXl5eSIsIm5leHRfZGF0ZSIsInNoaWZ0IiwicG9wIiwibW9udGhfbmFtZSIsInN1YnN0cmluZyIsImNhbGwiLCJxdWVyeVNlbGVjdG9yQWxsIiwiZGlzcGxheSIsImRhdGVfcGFydHMiLCJtb250aCIsIm1hcHBlcl9hcnJheSIsImRhdGFfdmFsdWVzIiwiZGF0YV9tYXhfdmFsdWUiLCJkaXN0cmlidXRpb25fc3RlcCIsImNoZWNrcG9pbnQiLCJkYXRlX3N0ciIsInJlc3VsdCIsInNldE1pbnV0ZXMiLCJnZXRNaW51dGVzIiwiZ2V0VGltZXpvbmVPZmZzZXQiLCJkYXRlIiwiZGQiLCJnZXREYXRlIiwibW0iLCJzdGFydF9kYXRlX3N0ciIsImVuZF9kYXRlX3N0ciIsImdldF9kYXlzX2JldHdlZW4iLCJtaWxsaXNlY29uZHNfcGVyX2RheSIsInRyZWF0X2FzX3V0YyIsIm51bWJlcl9vZl9kYXlzIiwic2V0RGF0ZSIsInRpdGxlX25hbWUiLCJ0aXRsZV92YWx1ZSIsImxpc3RfdmFsdWVzIiwidGl0bGVfdmFsdWVfZmlyc3QiLCJjYWxjX3Bvc2l0aW9uIiwiZGF0YV9wb2ludF9saXN0IiwibGkiLCJvZmZzZXRIZWlnaHQiLCJtYXhfbGVmdCIsInBvaW50ZXIiLCJkZWx0YSJdLCJtYXBwaW5ncyI6Ijs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBQWUsU0FBU0EsQ0FBVCxDQUFXQyxJQUFYLEVBQWlCQyxHQUFqQixFQUFzQjtRQUM3QixPQUFPRCxJQUFQLEtBQWdCLFFBQWhCLEdBQTBCLENBQUNDLE9BQU9DLFFBQVIsRUFBa0JDLGFBQWxCLENBQWdDSCxJQUFoQyxDQUExQixHQUFrRUEsUUFBUSxJQUFqRjs7O0FBR0RE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
|