diff --git a/.babelrc b/.babelrc
new file mode 100644
index 0000000..ac95979
--- /dev/null
+++ b/.babelrc
@@ -0,0 +1,10 @@
+{
+ "presets": [
+ [
+ "es2015",
+ {
+ "modules": false
+ }
+ ]
+ ]
+}
diff --git a/dist/frappe-charts.min.js b/dist/frappe-charts.min.js
new file mode 100644
index 0000000..c91504c
--- /dev/null
+++ b/dist/frappe-charts.min.js
@@ -0,0 +1,2246 @@
+(function () {
+'use strict';
+
+let frappe = {chart:{}, chart_types:['line', 'bar', 'percentage', 'heatmap']};
+
+frappe.chart.FrappeChart = class {
+ constructor({
+ parent = "",
+ height = 240,
+
+ title = '', subtitle = '',
+
+ data = {},
+ format_lambdas = {},
+
+ summary = [],
+
+ is_navigable = 0,
+
+ type = ''
+ }) {
+ if(Object.getPrototypeOf(this) === frappe.chart.FrappeChart.prototype) {
+ if(type === 'line') {
+ return new frappe.chart.LineChart(arguments[0]);
+ } else if(type === 'bar') {
+ return new frappe.chart.BarChart(arguments[0]);
+ } else if(type === 'percentage') {
+ return new frappe.chart.PercentageChart(arguments[0]);
+ } else if(type === 'heatmap') {
+ return new frappe.chart.HeatMap(arguments[0]);
+ } else {
+ return new frappe.chart.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;
+ }
+
+ $$.createSVG('svg', {
+ className: 'chart',
+ inside: parent,
+ width: 1000,
+ height: height
+ });
+
+ this.set_margins(height);
+ }
+
+ get_different_chart(type) {
+ if(!frappe.chart_types.includes(type)) {
+ console.error(`'${type}' is not a valid chart type.`);
+ }
+ if(type === this.type) return;
+
+ // Only across compatible types
+ let 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 be 'change_chart_type(type)'
+ // that will update only the required elements, but for now ...
+ return new frappe.chart.FrappeChart({
+ parent: this.raw_chart_args.parent,
+ data: this.raw_chart_args.data,
+ type: type,
+ height: this.raw_chart_args.height
+ });
+ }
+
+ set_margins(height) {
+ this.base_height = height;
+ this.height = height - 40;
+ this.translate_x = 60;
+ this.translate_y = 10;
+ }
+
+ setup() {
+ this.bind_window_events();
+ this.refresh(true);
+ }
+
+ bind_window_events() {
+ window.addEventListener('resize', () => this.refresh());
+ window.addEventListener('orientationchange', () => this.refresh());
+ }
+
+ refresh(init=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);
+ }
+ }
+
+ set_width() {
+ let special_values_width = 0;
+ this.specific_values.map(val => {
+ if(this.get_strwidth(val.title) > special_values_width) {
+ special_values_width = this.get_strwidth(val.title) - 40;
+ }
+ });
+ this.base_width = this.parent.offsetWidth - special_values_width;
+ this.width = this.base_width - this.translate_x * 2;
+ }
+
+ setup_base_values() {}
+
+ setup_container() {
+ this.container = $$.create('div', {
+ className: 'chart-container',
+ innerHTML: `
${this.title}
+ ${this.subtitle}
+
+ `
+ });
+
+ // 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();
+ }
+
+ 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;
+ }
+
+ make_draw_area() {
+ this.draw_area = $$.createSVG("g", {
+ className: this.type + '-chart',
+ inside: this.svg,
+ transform: `translate(${this.translate_x}, ${this.translate_y})`
+ });
+ }
+
+ setup_components() { }
+
+ make_tooltip() {
+ this.tip = new frappe.chart.SvgTip({
+ parent: this.chart_wrapper,
+ });
+ this.bind_tooltip();
+ }
+
+
+ show_summary() {}
+ show_custom_summary() {
+ this.summary.map(d => {
+ let stats = $$.create('div', {
+ className: 'stats',
+ innerHTML: `${d.title}: ${d.value}`
+ });
+ this.stats_wrapper.appendChild(stats);
+ });
+ }
+
+ setup_navigation(init=false) {
+ this.make_overlay();
+
+ if(init) {
+ this.bind_overlay();
+
+ document.addEventListener('keydown', (e) => {
+ if($$.isElementInViewport(this.chart_wrapper)) {
+ e = e || window.event;
+
+ if (e.keyCode == '37') {
+ this.on_left_arrow();
+ } else if (e.keyCode == '39') {
+ this.on_right_arrow();
+ } else if (e.keyCode == '38') {
+ this.on_up_arrow();
+ } else if (e.keyCode == '40') {
+ this.on_down_arrow();
+ } else if (e.keyCode == '13') {
+ this.on_enter_key();
+ }
+ }
+ });
+ }
+ }
+
+ make_overlay() {}
+ bind_overlay() {}
+
+ on_left_arrow() {}
+ on_right_arrow() {}
+ on_up_arrow() {}
+ on_down_arrow() {}
+ on_enter_key() {}
+
+ get_data_point(index=this.current_index) {
+ // check for length
+ let data_point = {
+ index: index
+ };
+ let y = this.y[0];
+ ['svg_units', 'y_tops', 'values'].map(key => {
+ let data_key = key.slice(0, key.length-1);
+ data_point[data_key] = y[key][index];
+ });
+ data_point.label = this.x[index];
+ return data_point;
+ }
+
+ 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
+ get_strwidth(string) {
+ return string.length * 8;
+ }
+
+ // Objects
+ setup_utils() { }
+};
+
+frappe.chart.AxisChart = class AxisChart extends frappe.chart.FrappeChart {
+ constructor(args) {
+ super(args);
+
+ this.x = this.data.labels;
+ this.y = this.data.datasets;
+
+ this.get_y_label = this.format_lambdas.y_label;
+ this.get_y_tooltip = this.format_lambdas.y_tooltip;
+ this.get_x_tooltip = this.format_lambdas.x_tooltip;
+
+ this.colors = ['green', 'blue', 'violet', 'red', 'orange',
+ 'yellow', 'light-blue', 'light-green', 'purple', 'magenta'];
+
+ this.zero_line = this.height;
+ }
+
+ setup_values() {
+ this.data.datasets.map(d => {
+ d.values = d.values.map(val => (!isNaN(val) ? val : 0));
+ });
+ this.setup_x();
+ this.setup_y();
+ }
+
+ setup_x() {
+ 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((d, i) =>
+ $$.float_2(this.x_offset + i * this.avg_unit_width));
+
+ if(!this.x_old_axis_positions) {
+ this.x_old_axis_positions = this.x_axis_positions.slice();
+ }
+ }
+
+ setup_y() {
+ if(this.y_axis_values) {
+ this.y_old_axis_values = this.y_axis_values.slice();
+ }
+
+ let 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();
+ }
+
+ const y_pts = this.y_axis_values;
+ const 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;
+
+ const zero_index = y_pts.indexOf(0);
+ const interval = y_pts[1] - y_pts[0];
+ const 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;
+ }
+
+ setup_components() {
+ super.setup_components();
+ this.setup_marker_components();
+ this.setup_aggregation_components();
+ this.setup_graph_components();
+ }
+
+ 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});
+ }
+
+ 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});
+ }
+
+ setup_graph_components() {
+ this.svg_units_groups = [];
+ this.y.map((d, i) => {
+ this.svg_units_groups[i] = $$.createSVG('g', {
+ className: 'data-points data-points-' + i,
+ inside: this.draw_area
+ });
+ });
+ }
+
+ make_graph_components(init=false) {
+ this.make_y_axis();
+ this.make_x_axis();
+ this.draw_graph(init);
+ this.make_y_specifics();
+ }
+
+ // make VERTICAL lines for x values
+ make_x_axis(animate=false) {
+ let start_at, height, text_start_at, 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((point, i) => {
+ this.x_axis_group.appendChild(
+ this.make_x_line(
+ height,
+ text_start_at,
+ point,
+ 'x-value-text',
+ axis_line_class,
+ this.x_axis_positions[i]
+ )
+ );
+ });
+ }
+
+ // make HORIZONTAL lines for y values
+ make_y_axis(animate=false) {
+ if(animate) {
+ this.make_anim_y_axis();
+ this.make_anim_y_specifics();
+ return;
+ }
+
+ let [width, text_end_at, axis_line_class, start_at] = this.get_y_axis_line_props();
+
+ this.y_axis_group.textContent = '';
+ this.y_axis_values.map((value, i) => {
+ this.y_axis_group.appendChild(
+ this.make_y_line(
+ start_at,
+ width,
+ text_end_at,
+ value,
+ 'y-value-text',
+ axis_line_class,
+ this.zero_line - value * this.multiplier,
+ (value === 0 && i !== 0) // Non-first Zero line
+ )
+ );
+ });
+ }
+
+ get_y_axis_line_props(specific=false) {
+ if(specific) {
+ return[this.width, this.width + 5, 'specific-value', 0];
+ }
+ let width, 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];
+ }
+
+ draw_graph(init=false) {
+ if(init) {
+ this.draw_new_graph_and_animate();
+ return;
+ }
+ this.y.map((d, i) => {
+ d.svg_units = [];
+ this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
+ this.make_new_units(d, i);
+ });
+ }
+
+ draw_new_graph_and_animate() {
+ let data = [];
+ this.y.map((d, i) => {
+ // Anim: Don't draw initial values, store them and update later
+ d.y_tops = new Array(d.values.length).fill(this.zero_line); // no value
+ data.push({values: d.values});
+ d.svg_units = [];
+
+ this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
+ this.make_new_units(d, i);
+ });
+
+ setTimeout(() => {
+ this.update_values(data);
+ }, 350);
+ }
+
+ setup_navigation(init) {
+ // Hack: defer nav till initial update_values
+ setTimeout(() => {
+ super.setup_navigation(init);
+ }, 500);
+ }
+
+ 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
+ );
+ }
+
+ make_new_units_for_dataset(x_values, y_values, color, dataset_index, no_of_datasets, group, array, unit) {
+ 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((y, i) => {
+ let data_unit = this.draw[unit.type](
+ x_values[i],
+ y,
+ unit.args,
+ color,
+ dataset_index,
+ no_of_datasets
+ );
+ group.appendChild(data_unit);
+ array.push(data_unit);
+ });
+ }
+
+ make_y_specifics() {
+ this.specific_y_group.textContent = '';
+ this.specific_values.map(d => {
+ this.specific_y_group.appendChild(
+ this.make_y_line(
+ 0,
+ this.width,
+ this.width + 5,
+ d.title.toUpperCase(),
+ 'specific-value',
+ 'specific-value',
+ this.zero_line - d.value * this.multiplier,
+ false,
+ d.line_type
+ )
+ );
+ });
+ }
+
+ bind_tooltip() {
+ // TODO: could be in tooltip itself, as it is a given functionality for its parent
+ this.chart_wrapper.addEventListener('mousemove', (e) => {
+ let offset = $$.offset(this.chart_wrapper);
+ let relX = e.pageX - offset.left - this.translate_x;
+ let relY = e.pageY - offset.top - this.translate_y;
+
+ if(relY < this.height + this.translate_y * 2) {
+ this.map_tooltip_x_position_and_show(relX);
+ } else {
+ this.tip.hide_tip();
+ }
+ });
+ }
+
+ map_tooltip_x_position_and_show(relX) {
+ for(var i=this.x_axis_positions.length - 1; i >= 0 ; i--) {
+ let 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) {
+ let x = x_val + this.translate_x;
+ let y = this.y_min_tops[i] + this.translate_y;
+
+ let title = this.x.formatted && this.x.formatted.length>0
+ ? this.x.formatted[i] : this.x[i];
+ let values = this.y.map((set, j) => {
+ return {
+ title: set.title,
+ value: set.formatted ? set.formatted[i] : set.values[i],
+ color: set.color || this.colors[j],
+ }
+ });
+
+ // TODO: upside-down tooltips for negative values?
+ this.tip.set_values(x, y, title, '', values);
+ this.tip.show_tip();
+ break;
+ }
+ }
+ }
+
+ // API
+ show_sums() {
+ this.updating = true;
+
+ this.y_sums = new Array(this.x_axis_positions.length).fill(0);
+ this.y.map(d => {
+ d.values.map( (value, i) => {
+ this.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( val => $$.float_2(this.zero_line - val * this.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;
+ }
+
+ hide_sums() {
+ if(this.updating) return;
+ this.y_sums = [];
+ this.sum_group.textContent = '';
+ this.sum_units = [];
+ this.update_values();
+ }
+
+ show_average() {
+ this.old_specific_values = this.specific_values.slice();
+ this.y.map((d, i) => {
+ let sum = 0;
+ d.values.map(e => {sum+=e;});
+ let average = sum/d.values.length;
+
+ this.specific_values.push({
+ title: "AVG" + " " + (i+1),
+ line_type: "dashed",
+ value: average,
+ auto: 1
+ });
+ });
+
+ console.log(this.specific_values);
+
+ this.update_values();
+ }
+
+ hide_average() {
+ this.old_specific_values = this.specific_values.slice();
+
+ let indices_to_remove = [];
+ this.specific_values.map((d, i) => {
+ if(d.auto) indices_to_remove.unshift(i);
+ });
+
+ console.log(indices_to_remove);
+
+ indices_to_remove.map(index => {
+ this.specific_values.splice(index, 1);
+ });
+
+ console.log(this.specific_values);
+
+ this.update_values();
+ }
+
+ update_values(new_y, new_x) {
+ 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(d => d.y_tops.slice());
+
+ this.old_y_values = this.y.map(d => 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((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(() => {
+ if(!this.updating) this.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(() => {
+ if(!this.updating) {
+ this.make_y_axis();
+ this.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;
+ }
+
+ add_data_point(y_point, x_point, index=this.x.length) {
+ let new_y = this.y.map(data_set => { return {values:data_set.values}; });
+ new_y.map((d, i) => { d.values.splice(index, 0, y_point[i]); });
+ let new_x = this.x.slice();
+ new_x.splice(index, 0, x_point);
+
+ this.update_values(new_y, new_x);
+ }
+
+ remove_data_point(index = this.x.length-1) {
+ if(this.x.length < 3) return;
+
+ let new_y = this.y.map(data_set => { return {values:data_set.values}; });
+ new_y.map((d, i) => { d.values.splice(index, 1); });
+ let new_x = this.x.slice();
+ new_x.splice(index, 1);
+
+ this.update_values(new_y, new_x);
+ }
+
+ run_animation() {
+ let 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(() => {
+ if(anim_svg.parentNode == this.chart_wrapper) {
+ this.chart_wrapper.removeChild(anim_svg);
+ this.chart_wrapper.appendChild(this.svg);
+ }
+ }, 200);
+ }
+
+ animate_graphs() {
+ this.y.map((d, i) => {
+ // Pre-prep, equilize no of positions between old and new
+ let [old_x, old_y, new_x, new_y] = this.calc_old_and_new_postions(d, i);
+ if(this.no_of_extra_pts >= 0) {
+ this.make_path && this.make_path(d, i, old_x, old_y, d.color || this.colors[i]);
+ this.make_new_units_for_dataset(old_x, old_y, d.color || this.colors[i], i, this.y.length);
+ }
+ d.path && this.animate_path(d, i, old_x, old_y, new_x, new_y);
+ this.animate_units(d, i, old_x, old_y, new_x, new_y);
+ });
+
+ // TODO: replace with real units
+ setTimeout(() => {
+ this.y.map((d, i) => {
+ this.make_path && this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
+ this.make_new_units(d, i);
+ });
+ }, 300);
+ }
+
+ animate_path(d, i, old_x, old_y, new_x, new_y) {
+ // Animate path
+ const new_points_list = new_y.map((y, i) => (new_x[i] + ',' + y));
+ const new_path_str = new_points_list.join("L");
+
+ const 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) {
+ let reg_start_pt = `0,${this.zero_line}L`;
+ let reg_end_pt = `L${this.width},${this.zero_line}`;
+
+ const 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);
+ }
+ }
+
+ animate_units(d, index, old_x, old_y, new_x, new_y) {
+ let type = this.unit_args.type;
+
+ d.svg_units.map((unit, i) => {
+ this.elements_to_animate.push(this.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
+ ));
+ });
+ }
+
+ calc_old_and_new_postions(d, i) {
+ let old_x = this.x_old_axis_positions.slice();
+ let new_x = this.x_axis_positions.slice();
+
+ let old_y = this.old_y_axis_tops[i].slice();
+ let new_y = d.y_tops.slice();
+
+ const last_old_x_pos = old_x[old_x.length - 1];
+ const last_old_y_pos = old_y[old_y.length - 1];
+
+ const last_new_x_pos = new_x[new_x.length - 1];
+ const 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
+ let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_old_x_pos);
+ let 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
+ let filler_x = new Array(Math.abs(this.no_of_extra_pts)).fill(last_new_x_pos);
+ let 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];
+ }
+
+ make_anim_x_axis(height, text_start_at, axis_line_class) {
+ // Animate X AXIS to account for more or less axis lines
+
+ const old_pos = this.x_old_axis_positions;
+ const new_pos = this.x_axis_positions;
+
+ const old_vals = this.old_x_values;
+ const new_vals = this.x;
+
+ const last_line_pos = old_pos[old_pos.length - 1];
+
+ let add_and_animate_line = (value, old_pos, new_pos, i) => {
+ const x_line = this.make_x_line(
+ height,
+ text_start_at,
+ value, // new value
+ 'x-value-text',
+ axis_line_class,
+ old_pos // old position
+ );
+ this.x_axis_group.appendChild(x_line);
+
+ this.elements_to_animate && this.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
+ );
+ }
+
+ make_anim_y_axis() {
+ // Animate Y AXIS to account for more or less axis lines
+
+ const old_pos = this.y_old_axis_values.map(value =>
+ this.zero_line - value * this.multiplier);
+ const new_pos = this.y_axis_values.map(value =>
+ this.zero_line - value * this.multiplier);
+
+ const old_vals = this.y_old_axis_values;
+ const new_vals = this.y_axis_values;
+
+ const 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
+ );
+ }
+
+ make_anim_y_specifics() {
+ this.specific_y_group.textContent = '';
+ this.specific_values.map((d, i) => {
+ this.add_and_animate_y_line(
+ d.title,
+ this.old_zero_line - d.value * this.old_multiplier,
+ this.zero_line - d.value * this.multiplier,
+ 0,
+ this.specific_y_group,
+ d.line_type,
+ true
+ );
+ });
+ }
+
+ make_new_axis_anim_lines(old_pos, new_pos, old_vals, new_vals, last_line_pos, add_and_animate_line, group) {
+ let superimposed_positions, superimposed_values;
+ let 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
+ const filler_vals = new Array(Math.abs(no_of_extras)).fill("");
+ superimposed_values = new_vals.concat(filler_vals);
+
+ const filler_pos = new Array(Math.abs(no_of_extras)).fill(last_line_pos);
+ superimposed_positions = new_pos.concat(filler_pos);
+ }
+
+ superimposed_values.map((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
+ const extra_values = new_vals.slice(old_vals.length);
+ const extra_positions = new_pos.slice(old_pos.length);
+
+ extra_values.map((value, i) => {
+ add_and_animate_line(value, last_line_pos, extra_positions[i], i, group);
+ });
+ }
+ }
+
+ make_x_line(height, text_start_at, point, label_class, axis_line_class, x_pos) {
+ let allowed_space = this.avg_unit_width * 1.5;
+
+ if(this.get_strwidth(point) > allowed_space) {
+ let allowed_letters = allowed_space / 8;
+ point = point.slice(0, allowed_letters-3) + " ...";
+ }
+
+ let line = $$.createSVG('line', {
+ x1: 0,
+ x2: 0,
+ y1: 0,
+ y2: height
+ });
+
+ let text = $$.createSVG('text', {
+ className: label_class,
+ x: 0,
+ y: text_start_at,
+ dy: '.71em',
+ innerHTML: point
+ });
+
+ let 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;
+ }
+
+ make_y_line(start_at, width, text_end_at, point, label_class, axis_line_class, y_pos, darker=false, line_type="") {
+ let line = $$.createSVG('line', {
+ className: line_type === "dashed" ? "dashed": "",
+ x1: start_at,
+ x2: width,
+ y1: 0,
+ y2: 0
+ });
+
+ let text = $$.createSVG('text', {
+ className: label_class,
+ x: text_end_at,
+ y: 0,
+ dy: '.32em',
+ innerHTML: point+""
+ });
+
+ let 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;
+ }
+
+ add_and_animate_y_line(value, old_pos, new_pos, i, group, type, specific=false) {
+ let [width, text_end_at, axis_line_class, start_at] = this.get_y_axis_line_props(specific);
+ let axis_label_class = !specific ? 'y-value-text' : 'specific-value';
+ value = !specific ? value : (value+"").toUpperCase();
+ const 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 }`}
+ ]);
+ }
+
+ get_y_axis_points(array) {
+ //*** Where the magic happens ***
+
+ // Calculates best-fit y intervals from given values
+ // and returns the interval array
+
+ // TODO: Fractions
+
+ let max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size;
+
+ // Critical values
+ let max_val = parseInt(Math.max(...array));
+ let min_val = parseInt(Math.min(...array));
+ if(min_val >= 0) {
+ min_val = 0;
+ }
+
+ let get_params = (value1, value2) => {
+ let bound1, bound2, no_of_parts_1, no_of_parts_2, interval_size;
+ if((value1+"").length <= 1) {
+ [bound1, no_of_parts_1] = [10, 5];
+ } else {
+ [bound1, no_of_parts_1] = this.calc_upper_bound_and_no_of_parts(value1);
+ }
+
+ interval_size = bound1 / no_of_parts_1;
+ no_of_parts_2 = this.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];
+ };
+
+ const abs_min_val = min_val * -1;
+ if(abs_min_val <= max_val) {
+ // Get the positive region intervals
+ // then calc negative ones accordingly
+ [max_bound, min_bound, pos_no_of_parts, neg_no_of_parts, part_size]
+ = get_params(max_val, abs_min_val);
+ if(abs_min_val === 0) {
+ min_bound = 0; neg_no_of_parts = 0;
+ }
+ } else {
+ // Get the negative region here first
+ [min_bound, max_bound, neg_no_of_parts, pos_no_of_parts, part_size]
+ = get_params(abs_min_val, max_val);
+ }
+
+ // 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;
+ }
+
+ let 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
+ );
+ }
+
+ get_intervals(start, interval_size, count) {
+ let intervals = [];
+ for(var i = 0; i <= count; i++){
+ intervals.push(start);
+ start += interval_size;
+ }
+ return intervals;
+ }
+
+ 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
+
+ const part_size = Math.pow(10, ((max_val+"").length - 1));
+ const no_of_parts = this.calc_no_of_parts(max_val, part_size);
+
+ // Use it to get a nice even upper bound
+ const upper_bound = part_size * no_of_parts;
+
+ return [upper_bound, no_of_parts];
+ }
+
+ calc_no_of_parts(value, divisor) {
+ // value should be a positive number, divisor should be greater than 0
+ // returns an even no of parts
+ let 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;
+ }
+
+ 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;
+ }
+
+ 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;
+ }
+
+ get_all_y_values() {
+ let all_values = [];
+
+ // Add in all the y values in the datasets
+ this.y.map(d => {
+ all_values = all_values.concat(d.values);
+ });
+
+ // Add in all the specific values
+ return all_values.concat(this.specific_values.map(d => d.value));
+ }
+
+ calc_y_dependencies() {
+ this.y_min_tops = new Array(this.x_axis_positions.length).fill(9999);
+ this.y.map(d => {
+ d.y_tops = d.values.map( val => $$.float_2(this.zero_line - val * this.multiplier));
+ d.y_tops.map( (y_top, i) => {
+ if(y_top < this.y_min_tops[i]) {
+ this.y_min_tops[i] = y_top;
+ }
+ });
+ });
+ }
+
+ get_bar_height_and_y_attr(y_top) {
+ let height, y;
+ 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];
+ }
+
+ setup_utils() {
+ this.draw = {
+ 'bar': (x, y_top, args, color, index, no_of_datasets) => {
+ let total_width = this.avg_unit_width - args.space_width;
+ let start_x = x - total_width/2;
+
+ let width = total_width / no_of_datasets;
+ let current_x = start_x + width * index;
+
+ let [height, y] = this.get_bar_height_and_y_attr(y_top);
+
+ return $$.createSVG('rect', {
+ className: `bar mini fill ${color}`,
+ x: current_x,
+ y: y,
+ width: width,
+ height: height
+ });
+
+ },
+ 'dot': (x, y, args, color) => {
+ return $$.createSVG('circle', {
+ className: `fill ${color}`,
+ cx: x,
+ cy: y,
+ r: args.radius
+ });
+ }
+ };
+
+ this.animate = {
+ 'bar': (bar_obj, x, y_top, index) => {
+ let start = x - this.avg_unit_width/4;
+ let width = (this.avg_unit_width/2)/this.y.length;
+ let [height, y] = this.get_bar_height_and_y_attr(y_top);
+
+ 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': (dot_obj, x, y_top) => {
+ return [dot_obj, {cx: x, cy: y_top}, 300, "easein"];
+ // dot.animate({cy: y_top}, 250, mina.easein);
+ }
+ };
+ }
+};
+
+frappe.chart.BarChart = class BarChart extends frappe.chart.AxisChart {
+ constructor(args) {
+ super(args);
+
+ this.type = 'bar';
+ this.x_axis_mode = args.x_axis_mode || 'tick';
+ this.y_axis_mode = args.y_axis_mode || 'span';
+ this.setup();
+ }
+
+ setup_values() {
+ super.setup_values();
+ this.x_offset = this.avg_unit_width;
+ this.unit_args = {
+ type: 'bar',
+ args: {
+ space_width: this.avg_unit_width/2,
+ }
+ };
+ }
+
+ make_overlay() {
+ // Just make one out of the first element
+ let index = this.x.length - 1;
+ let 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);
+ }
+
+ bind_overlay() {
+ // on event, update overlay
+ this.parent.addEventListener('data-select', (e) => {
+ this.update_overlay(e.svg_unit);
+ });
+ }
+
+ update_overlay(unit) {
+ let attributes = [];
+ Object.keys(unit.attributes).map(index => {
+ attributes.push(unit.attributes[index]);
+ });
+
+ attributes.filter(attr => attr.specified).map(attr => {
+ this.overlay.setAttribute(attr.name, attr.nodeValue);
+ });
+ }
+
+ on_left_arrow() {
+ this.update_current_data_point(this.current_index - 1);
+ }
+
+ on_right_arrow() {
+ this.update_current_data_point(this.current_index + 1);
+ }
+
+ set_avg_unit_width_and_x_offset() {
+ this.avg_unit_width = this.width/(this.x.length + 1);
+ this.x_offset = this.avg_unit_width;
+ }
+};
+
+frappe.chart.LineChart = class LineChart extends frappe.chart.AxisChart {
+ constructor(args) {
+ super(args);
+ if(Object.getPrototypeOf(this) !== frappe.chart.LineChart.prototype) {
+ return;
+ }
+
+ this.type = 'line';
+ this.region_fill = args.region_fill;
+ this.x_axis_mode = args.x_axis_mode || 'span';
+ this.y_axis_mode = args.y_axis_mode || 'span';
+
+ this.setup();
+ }
+
+ setup_graph_components() {
+ this.setup_path_groups();
+ super.setup_graph_components();
+ }
+
+ setup_path_groups() {
+ this.paths_groups = [];
+ this.y.map((d, i) => {
+ this.paths_groups[i] = $$.createSVG('g', {
+ className: 'path-group path-group-' + i,
+ inside: this.draw_area
+ });
+ });
+ }
+
+ setup_values() {
+ super.setup_values();
+ this.unit_args = {
+ type: 'dot',
+ args: { radius: 8 }
+ };
+ }
+
+ make_paths() {
+ this.y.map((d, i) => {
+ this.make_path(d, i, this.x_axis_positions, d.y_tops, d.color || this.colors[i]);
+ });
+ }
+
+ make_path(d, i, x_positions, y_positions, color) {
+ // let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
+ // let 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) {
+ // let 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
+ // });
+
+ // 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})`;
+ // }
+ }
+};
+
+frappe.chart.PercentageChart = class PercentageChart extends frappe.chart.FrappeChart {
+ constructor(args) {
+ super(args);
+ this.type = 'percentage';
+
+ this.get_y_label = this.format_lambdas.y_label;
+ this.get_x_tooltip = this.format_lambdas.x_tooltip;
+ this.get_y_tooltip = this.format_lambdas.y_tooltip;
+
+ this.max_slices = 10;
+ this.max_legend_points = 6;
+
+ this.colors = args.colors;
+
+ if(!this.colors || this.colors.length < this.data.labels.length) {
+ this.colors = ['light-blue', 'blue', 'violet', 'red', 'orange',
+ 'yellow', 'green', 'light-green', 'purple', 'magenta'];
+ }
+
+ this.setup();
+ }
+
+ 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';
+ }
+
+ 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
+ });
+ }
+
+ setup_components() {
+ this.percentage_bar = $$.create('div', {
+ className: 'progress',
+ inside: this.chart
+ });
+ }
+
+ setup_values() {
+ this.slice_totals = [];
+ let all_totals = this.data.labels.map((d, i) => {
+ let total = 0;
+ this.data.datasets.map(e => {
+ total += e.values[i];
+ });
+ return [total, d];
+ }).filter(d => { return d[0] > 0; }); // keep only positive results
+
+ let totals = all_totals;
+
+ if(all_totals.length > this.max_slices) {
+ all_totals.sort((a, b) => { return b[0] - a[0]; });
+
+ totals = all_totals.slice(0, this.max_slices-1);
+ let others = all_totals.slice(this.max_slices-1);
+
+ let sum_of_others = 0;
+ others.map(d => {sum_of_others += d[0];});
+
+ totals.push([sum_of_others, 'Rest']);
+
+ this.colors[this.max_slices-1] = 'grey';
+ }
+
+ this.labels = [];
+ totals.map(d => {
+ this.slice_totals.push(d[0]);
+ this.labels.push(d[1]);
+ });
+
+ this.legend_totals = this.slice_totals.slice(0, this.max_legend_points);
+ }
+
+ setup_utils() { }
+
+ make_graph_components() {
+ this.grand_total = this.slice_totals.reduce((a, b) => a + b, 0);
+ this.slices = [];
+ this.slice_totals.map((total, i) => {
+ let slice = $$.create('div', {
+ className: `progress-bar background ${this.colors[i]}`,
+ style: `width: ${total*100/this.grand_total}%`,
+ inside: this.percentage_bar
+ });
+ this.slices.push(slice);
+ });
+ }
+
+ bind_tooltip() {
+ this.slices.map((slice, i) => {
+ slice.addEventListener('mouseenter', () => {
+ let g_off = $$.offset(this.chart_wrapper), p_off = $$.offset(slice);
+
+ let x = p_off.left - g_off.left + slice.offsetWidth/2;
+ let y = p_off.top - g_off.top - 6;
+ let title = (this.formatted_labels && this.formatted_labels.length>0
+ ? this.formatted_labels[i] : this.labels[i]) + ': ';
+ let percent = (this.slice_totals[i]*100/this.grand_total).toFixed(1);
+
+ this.tip.set_values(x, y, title, percent + "%");
+ this.tip.show_tip();
+ });
+ });
+ }
+
+ show_summary() {
+ let x_values = this.formatted_labels && this.formatted_labels.length > 0
+ ? this.formatted_labels : this.labels;
+ this.legend_totals.map((d, i) => {
+ if(d) {
+ let stats = $$.create('div', {
+ className: 'stats',
+ inside: this.stats_wrapper
+ });
+ stats.innerHTML = `
+ ${x_values[i]}:
+ ${d}
+ `;
+ }
+ });
+ }
+};
+
+frappe.chart.HeatMap = class HeatMap extends frappe.chart.FrappeChart {
+ constructor({
+ start = '',
+ domain = '',
+ subdomain = '',
+ data = {},
+ discrete_domains = 0,
+ count_label = ''
+ }) {
+ super(arguments[0]);
+
+ this.type = 'heatmap';
+
+ this.domain = domain;
+ this.subdomain = subdomain;
+ this.data = data;
+ this.discrete_domains = discrete_domains;
+ this.count_label = count_label;
+
+ let today = new Date();
+ this.start = start || this.add_days(today, 365);
+
+ this.legend_colors = ['#ebedf0', '#c6e48b', '#7bc96f', '#239a3b', '#196127'];
+
+ this.translate_x = 0;
+ this.setup();
+ }
+
+ 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;
+ }
+
+ set_width() {
+ this.base_width = (this.no_of_cols) * 12;
+
+ if(this.discrete_domains) {
+ this.base_width += (12 * 12);
+ }
+ }
+
+ 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)`
+ });
+ }
+
+ 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);
+ }
+
+ render_all_weeks_and_store_x_values(no_of_weeks) {
+ let 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++) {
+ let data_group, month_change = 0;
+ let day = new Date(current_week_sunday);
+
+ [data_group, month_change] = this.get_week_squares_group(day, this.week_col);
+ 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();
+ }
+
+ get_week_squares_group(current_date, index) {
+ const no_of_weekdays = 7;
+ const square_side = 10;
+ const cell_padding = 2;
+ const step = 1;
+
+ let month_change = 0;
+ let week_col_change = 0;
+
+ let 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)) {
+ let data_value = 0;
+ let color_index = 0;
+
+ let 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);
+ }
+
+ let 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()
+ });
+
+ let 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];
+ }
+
+ render_month_labels() {
+ // 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((start, i) => {
+ let month_name = this.month_names[this.months[i]].substring(0, 3);
+
+ $$.createSVG('text', {
+ className: 'y-value-text',
+ inside: this.domain_label_group,
+ x: start + 12,
+ y: 10,
+ dy: '.32em',
+ innerHTML: month_name
+ });
+
+ });
+ }
+
+ make_graph_components() {
+ Array.prototype.slice.call(
+ this.container.querySelectorAll('.graph-stats-container, .sub-title, .title')
+ ).map(d => {
+ d.style.display = 'None';
+ });
+ this.chart_wrapper.style.marginTop = '0px';
+ this.chart_wrapper.style.paddingTop = '0px';
+ }
+
+ bind_tooltip() {
+ Array.prototype.slice.call(
+ document.querySelectorAll(".data-group .day")
+ ).map(el => {
+ el.addEventListener('mouseenter', (e) => {
+ let count = e.target.getAttribute('data-value');
+ let date_parts = e.target.getAttribute('data-date').split('-');
+
+ let month = this.month_names[parseInt(date_parts[1])-1].substring(0, 3);
+
+ let g_off = this.chart_wrapper.getBoundingClientRect(), p_off = e.target.getBoundingClientRect();
+
+ let width = parseInt(e.target.getAttribute('width'));
+ let x = p_off.left - g_off.left + (width+2)/2;
+ let y = p_off.top - g_off.top - (width+2)/2;
+ let value = count + ' ' + this.count_label;
+ let name = ' on ' + month + ' ' + date_parts[0] + ', ' + date_parts[2];
+
+ this.tip.set_values(x, y, name, value, [], 1);
+ this.tip.show_tip();
+ });
+ });
+ }
+
+ update(data) {
+ this.data = data;
+ this.setup_values();
+ this.bind_tooltip();
+ }
+
+ get_distribution(data={}, mapper_array) {
+ let data_values = Object.keys(data).map(key => data[key]);
+ let data_max_value = Math.max(...data_values);
+
+ let distribution_step = 1 / (mapper_array.length - 1);
+ let distribution = [];
+
+ mapper_array.map((color, i) => {
+ let checkpoint = data_max_value * (distribution_step * i);
+ distribution.push(checkpoint);
+ });
+
+ return distribution;
+ }
+
+ get_max_checkpoint(value, distribution) {
+ return distribution.filter((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
+ treat_as_utc(date_str) {
+ let result = new Date(date_str);
+ result.setMinutes(result.getMinutes() - result.getTimezoneOffset());
+ return result;
+ }
+
+ get_dd_mm_yyyy(date) {
+ let dd = date.getDate();
+ let mm = date.getMonth() + 1; // getMonth() is zero-based
+ return [
+ (dd>9 ? '' : '0') + dd,
+ (mm>9 ? '' : '0') + mm,
+ date.getFullYear()
+ ].join('-');
+ }
+
+ get_weeks_between(start_date_str, end_date_str) {
+ return Math.ceil(this.get_days_between(start_date_str, end_date_str) / 7);
+ }
+
+ get_days_between(start_date_str, end_date_str) {
+ let 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
+ add_days(date, number_of_days) {
+ date.setDate(date.getDate() + number_of_days);
+ }
+
+ get_month_name() {}
+};
+
+frappe.chart.SvgTip = class {
+ constructor({
+ parent = null
+ }) {
+ 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();
+ }
+
+ setup() {
+ this.make_tooltip();
+ }
+
+ refresh() {
+ this.fill();
+ this.calc_position();
+ // this.show_tip();
+ }
+
+ make_tooltip() {
+ this.container = $$.create('div', {
+ inside: this.parent,
+ className: 'graph-svg-tip comparison',
+ innerHTML: `
+
+ `
+ });
+ this.hide_tip();
+
+ this.title = this.container.querySelector('.title');
+ this.data_point_list = this.container.querySelector('.data-point-list');
+
+ this.parent.addEventListener('mouseleave', () => {
+ this.hide_tip();
+ });
+ }
+
+ fill() {
+ let title;
+ if(this.title_value_first) {
+ title = `${this.title_value}${this.title_name}`;
+ } else {
+ title = `${this.title_name}${this.title_value}`;
+ }
+ this.title.innerHTML = title;
+ this.data_point_list.innerHTML = '';
+
+ this.list_values.map((set) => {
+ let li = $$.create('li', {
+ className: `border-top ${set.color || 'black'}`,
+ innerHTML: `${set.value ? set.value : '' }
+ ${set.title ? set.title : '' }`
+ });
+
+ this.data_point_list.appendChild(li);
+ });
+ }
+
+ calc_position() {
+ this.top = this.y - this.container.offsetHeight;
+ this.left = this.x - this.container.offsetWidth/2;
+ let max_left = this.parent.offsetWidth - this.container.offsetWidth;
+
+ let 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) {
+ let delta = this.left - max_left;
+ pointer.style.left = `calc(50% + ${delta}px)`;
+ this.left = max_left;
+ } else {
+ pointer.style.left = `50%`;
+ }
+ }
+
+ set_values(x, y, title_name = '', title_value = '', list_values = [], title_value_first = 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();
+ }
+
+ hide_tip() {
+ this.container.style.top = '0px';
+ this.container.style.left = '0px';
+ this.container.style.opacity = '0';
+ }
+
+ show_tip() {
+ this.container.style.top = this.top + 'px';
+ this.container.style.left = this.left + 'px';
+ this.container.style.opacity = '1';
+ }
+};
+
+// Helpers
+frappe.chart.utils = {};
+$$.float_2 = d => parseFloat(d.toFixed(2));
+function $$(expr, con) {
+ return typeof expr === "string"? (con || document).querySelector(expr) : expr || null;
+}
+
+$$.arrays_equal = (arr1, arr2) => {
+ if(arr1.length !== arr2.length) return false;
+ let are_equal = true;
+ arr1.map((d, i) => {
+ if(arr2[i] !== d) are_equal = false;
+ });
+ return are_equal;
+};
+
+$$.shuffle = (array) => {
+ // https://stackoverflow.com/a/2450976/6495043
+ // Awesomeness: https://bost.ocks.org/mike/shuffle/
+
+ var currentIndex = array.length, temporaryValue, randomIndex;
+
+ // While there remain elements to shuffle...
+ while (0 !== currentIndex) {
+
+ // Pick a remaining element...
+ randomIndex = Math.floor(Math.random() * currentIndex);
+ currentIndex -= 1;
+
+ // And swap it with the current element.
+ temporaryValue = array[currentIndex];
+ array[currentIndex] = array[randomIndex];
+ array[randomIndex] = temporaryValue;
+ }
+
+ return array;
+
+};
+
+// $$.findNodeIndex = (node) =>
+// {
+// var i = 0;
+// while (node = node.previousSibling) {
+// if (node.nodeType === 1) { ++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 = (svg_container, elements) => {
+ // let parent = elements[0][0]['unit'].parentNode;
+
+ let new_elements = [];
+ let anim_elements = [];
+
+ elements.map(element => {
+ let obj = element[0];
+ let parent = obj.unit.parentNode;
+ // let index = $$.findNodeIndex(obj.unit);
+
+ let anim_element, new_element;
+
+ element[0] = obj.unit;
+
+ [anim_element, new_element] = $$.animateSVG(...element);
+
+ 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;
+ }
+ });
+
+ let anim_svg = svg_container.cloneNode(true);
+
+ anim_elements.map((anim_element, i) => {
+ anim_element[1].replaceChild(new_elements[i], anim_element[0]);
+ elements[i][0] = new_elements[i];
+ });
+
+ return anim_svg;
+};
+
+// $$.animateMotion = (element, props, dur, easing_type="linear")
+
+$$.animateSVG = (element, props, dur, easing_type="linear", type=undefined, old_values={}) => {
+ let 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"
+ };
+
+ let anim_element = element.cloneNode(true);
+ let new_element = element.cloneNode(true);
+
+ for(var attributeName in props) {
+ let animate_element;
+ 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");
+ }
+ let current_value = old_values[attributeName] || element.getAttribute(attributeName);
+ let value = props[attributeName];
+
+ let 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 = (element) => {
+ let 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 = (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);
+};
+
+}());
+//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZnJhcHBlLWNoYXJ0cy5taW4uanMiLCJzb3VyY2VzIjpbIi4uL3NyYy9jaGFydHMuanMiXSwic291cmNlc0NvbnRlbnQiOlsibGV0IGZyYXBwZSA9IHtjaGFydDp7fSwgY2hhcnRfdHlwZXM6WydsaW5lJywgJ2JhcicsICdwZXJjZW50YWdlJywgJ2hlYXRtYXAnXX07XG5cbmZyYXBwZS5jaGFydC5GcmFwcGVDaGFydCA9IGNsYXNzIHtcblx0Y29uc3RydWN0b3Ioe1xuXHRcdHBhcmVudCA9IFwiXCIsXG5cdFx0aGVpZ2h0ID0gMjQwLFxuXG5cdFx0dGl0bGUgPSAnJywgc3VidGl0bGUgPSAnJyxcblxuXHRcdGRhdGEgPSB7fSxcblx0XHRmb3JtYXRfbGFtYmRhcyA9IHt9LFxuXG5cdFx0c3VtbWFyeSA9IFtdLFxuXG5cdFx0aXNfbmF2aWdhYmxlID0gMCxcblxuXHRcdHR5cGUgPSAnJ1xuXHR9KSB7XG5cdFx0aWYoT2JqZWN0LmdldFByb3RvdHlwZU9mKHRoaXMpID09PSBmcmFwcGUuY2hhcnQuRnJhcHBlQ2hhcnQucHJvdG90eXBlKSB7XG5cdFx0XHRpZih0eXBlID09PSAnbGluZScpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBmcmFwcGUuY2hhcnQuTGluZUNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ2JhcicpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBmcmFwcGUuY2hhcnQuQmFyQ2hhcnQoYXJndW1lbnRzWzBdKTtcblx0XHRcdH0gZWxzZSBpZih0eXBlID09PSAncGVyY2VudGFnZScpIHtcblx0XHRcdFx0cmV0dXJuIG5ldyBmcmFwcGUuY2hhcnQuUGVyY2VudGFnZUNoYXJ0KGFyZ3VtZW50c1swXSk7XG5cdFx0XHR9IGVsc2UgaWYodHlwZSA9PT0gJ2hlYXRtYXAnKSB7XG5cdFx0XHRcdHJldHVybiBuZXcgZnJhcHBlLmNoYXJ0LkhlYXRNYXAoYXJndW1lbnRzWzBdKTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdHJldHVybiBuZXcgZnJhcHBlLmNoYXJ0LkxpbmVDaGFydChhcmd1bWVudHNbMF0pO1xuXHRcdFx0fVxuXHRcdH1cblxuXHRcdHRoaXMucmF3X2NoYXJ0X2FyZ3MgPSBhcmd1bWVudHNbMF07XG5cblx0XHR0aGlzLnBhcmVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IocGFyZW50KTtcblx0XHR0aGlzLnRpdGxlID0gdGl0bGU7XG5cdFx0dGhpcy5zdWJ0aXRsZSA9IHN1YnRpdGxlO1xuXG5cdFx0dGhpcy5kYXRhID0gZGF0YTtcblx0XHR0aGlzLmZvcm1hdF9sYW1iZGFzID0gZm9ybWF0X2xhbWJkYXM7XG5cblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcyA9IGRhdGEuc3BlY2lmaWNfdmFsdWVzIHx8IFtdO1xuXHRcdHRoaXMuc3VtbWFyeSA9IHN1bW1hcnk7XG5cblx0XHR0aGlzLmlzX25hdmlnYWJsZSA9IGlzX25hdmlnYWJsZTtcblx0XHRpZih0aGlzLmlzX25hdmlnYWJsZSkge1xuXHRcdFx0dGhpcy5jdXJyZW50X2luZGV4ID0gMDtcblx0XHR9XG5cblx0XHQkJC5jcmVhdGVTVkcoJ3N2ZycsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2NoYXJ0Jyxcblx0XHRcdGluc2lkZTogcGFyZW50LFxuXHRcdFx0d2lkdGg6IDEwMDAsXG5cdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdH0pO1xuXG5cdFx0dGhpcy5zZXRfbWFyZ2lucyhoZWlnaHQpO1xuXHR9XG5cblx0Z2V0X2RpZmZlcmVudF9jaGFydCh0eXBlKSB7XG5cdFx0aWYoIWZyYXBwZS5jaGFydF90eXBlcy5pbmNsdWRlcyh0eXBlKSkge1xuXHRcdFx0Y29uc29sZS5lcnJvcihgJyR7dHlwZX0nIGlzIG5vdCBhIHZhbGlkIGNoYXJ0IHR5cGUuYCk7XG5cdFx0fVxuXHRcdGlmKHR5cGUgPT09IHRoaXMudHlwZSkgcmV0dXJuO1xuXG5cdFx0Ly8gT25seSBhY3Jvc3MgY29tcGF0aWJsZSB0eXBlc1xuXHRcdGxldCBjb21wYXRpYmxlX3R5cGVzID0ge1xuXHRcdFx0YmFyOiBbJ2xpbmUnLCAncGVyY2VudGFnZSddLFxuXHRcdFx0bGluZTogWydiYXInLCAncGVyY2VudGFnZSddLFxuXHRcdFx0cGVyY2VudGFnZTogWydiYXInLCAnbGluZSddLFxuXHRcdFx0aGVhdG1hcDogW11cblx0XHR9XG5cblx0XHRpZighY29tcGF0aWJsZV90eXBlc1t0aGlzLnR5cGVdLmluY2x1ZGVzKHR5cGUpKSB7XG5cdFx0XHRjb25zb2xlLmVycm9yKGAnJHt0aGlzLnR5cGV9JyBjaGFydCBjYW5ub3QgYmUgY29udmVydGVkIHRvIGEgJyR7dHlwZX0nIGNoYXJ0LmApO1xuXHRcdH1cblxuXHRcdC8vIE9rYXksIHRoaXMgaXMgYW50aWNsaW1hY3RpY1xuXHRcdC8vIHRoaXMgZnVuY3Rpb24gd2lsbCBuZWVkIHRvIGJlICdjaGFuZ2VfY2hhcnRfdHlwZSh0eXBlKSdcblx0XHQvLyB0aGF0IHdpbGwgdXBkYXRlIG9ubHkgdGhlIHJlcXVpcmVkIGVsZW1lbnRzLCBidXQgZm9yIG5vdyAuLi5cblx0XHRyZXR1cm4gbmV3IGZyYXBwZS5jaGFydC5GcmFwcGVDaGFydCh7XG5cdFx0XHRwYXJlbnQ6IHRoaXMucmF3X2NoYXJ0X2FyZ3MucGFyZW50LFxuXHRcdFx0ZGF0YTogdGhpcy5yYXdfY2hhcnRfYXJncy5kYXRhLFxuXHRcdFx0dHlwZTogdHlwZSxcblx0XHRcdGhlaWdodDogdGhpcy5yYXdfY2hhcnRfYXJncy5oZWlnaHRcblx0XHR9KTtcblx0fVxuXG5cdHNldF9tYXJnaW5zKGhlaWdodCkge1xuXHRcdHRoaXMuYmFzZV9oZWlnaHQgPSBoZWlnaHQ7XG5cdFx0dGhpcy5oZWlnaHQgPSBoZWlnaHQgLSA0MDtcblx0XHR0aGlzLnRyYW5zbGF0ZV94ID0gNjA7XG5cdFx0dGhpcy50cmFuc2xhdGVfeSA9IDEwO1xuXHR9XG5cblx0c2V0dXAoKSB7XG5cdFx0dGhpcy5iaW5kX3dpbmRvd19ldmVudHMoKTtcblx0XHR0aGlzLnJlZnJlc2godHJ1ZSk7XG5cdH1cblxuXHRiaW5kX3dpbmRvd19ldmVudHMoKSB7XG5cdFx0d2luZG93LmFkZEV2ZW50TGlzdGVuZXIoJ3Jlc2l6ZScsICgpID0+IHRoaXMucmVmcmVzaCgpKTtcblx0XHR3aW5kb3cuYWRkRXZlbnRMaXN0ZW5lcignb3JpZW50YXRpb25jaGFuZ2UnLCAoKSA9PiB0aGlzLnJlZnJlc2goKSk7XG5cdH1cblxuXHRyZWZyZXNoKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLnNldHVwX2Jhc2VfdmFsdWVzKCk7XG5cdFx0dGhpcy5zZXRfd2lkdGgoKTtcblxuXHRcdHRoaXMuc2V0dXBfY29udGFpbmVyKCk7XG5cdFx0dGhpcy5zZXR1cF9jb21wb25lbnRzKCk7XG5cblx0XHR0aGlzLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMuc2V0dXBfdXRpbHMoKTtcblxuXHRcdHRoaXMubWFrZV9ncmFwaF9jb21wb25lbnRzKGluaXQpO1xuXHRcdHRoaXMubWFrZV90b29sdGlwKCk7XG5cblx0XHRpZih0aGlzLnN1bW1hcnkubGVuZ3RoID4gMCkge1xuXHRcdFx0dGhpcy5zaG93X2N1c3RvbV9zdW1tYXJ5KCk7XG5cdFx0fSBlbHNlIHtcblx0XHRcdHRoaXMuc2hvd19zdW1tYXJ5KCk7XG5cdFx0fVxuXG5cdFx0aWYodGhpcy5pc19uYXZpZ2FibGUpIHtcblx0XHRcdHRoaXMuc2V0dXBfbmF2aWdhdGlvbihpbml0KTtcblx0XHR9XG5cdH1cblxuXHRzZXRfd2lkdGgoKSB7XG5cdFx0bGV0IHNwZWNpYWxfdmFsdWVzX3dpZHRoID0gMDtcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAodmFsID0+IHtcblx0XHRcdGlmKHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgPiBzcGVjaWFsX3ZhbHVlc193aWR0aCkge1xuXHRcdFx0XHRzcGVjaWFsX3ZhbHVlc193aWR0aCA9IHRoaXMuZ2V0X3N0cndpZHRoKHZhbC50aXRsZSkgLSA0MDtcblx0XHRcdH1cblx0XHR9KTtcblx0XHR0aGlzLmJhc2Vfd2lkdGggPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHNwZWNpYWxfdmFsdWVzX3dpZHRoO1xuXHRcdHRoaXMud2lkdGggPSB0aGlzLmJhc2Vfd2lkdGggLSB0aGlzLnRyYW5zbGF0ZV94ICogMjtcblx0fVxuXG5cdHNldHVwX2Jhc2VfdmFsdWVzKCkge31cblxuXHRzZXR1cF9jb250YWluZXIoKSB7XG5cdFx0dGhpcy5jb250YWluZXIgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2NoYXJ0LWNvbnRhaW5lcicsXG5cdFx0XHRpbm5lckhUTUw6IGA8aDYgY2xhc3M9XCJ0aXRsZVwiIHN0eWxlPVwibWFyZ2luLXRvcDogMTVweDtcIj4ke3RoaXMudGl0bGV9PC9oNj5cblx0XHRcdFx0PGg2IGNsYXNzPVwic3ViLXRpdGxlIHVwcGVyY2FzZVwiPiR7dGhpcy5zdWJ0aXRsZX08L2g2PlxuXHRcdFx0XHQ8ZGl2IGNsYXNzPVwiZnJhcHBlLWNoYXJ0IGdyYXBoaWNzXCI+PC9kaXY+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJncmFwaC1zdGF0cy1jb250YWluZXJcIj48L2Rpdj5gXG5cdFx0fSk7XG5cblx0XHQvLyBDaGFydCBuZWVkcyBhIGRlZGljYXRlZCBwYXJlbnQgZWxlbWVudFxuXHRcdHRoaXMucGFyZW50LmlubmVySFRNTCA9ICcnO1xuXHRcdHRoaXMucGFyZW50LmFwcGVuZENoaWxkKHRoaXMuY29udGFpbmVyKTtcblxuXHRcdHRoaXMuY2hhcnRfd3JhcHBlciA9IHRoaXMuY29udGFpbmVyLnF1ZXJ5U2VsZWN0b3IoJy5mcmFwcGUtY2hhcnQnKTtcblx0XHR0aGlzLnN0YXRzX3dyYXBwZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuZ3JhcGgtc3RhdHMtY29udGFpbmVyJyk7XG5cblx0XHR0aGlzLm1ha2VfY2hhcnRfYXJlYSgpO1xuXHRcdHRoaXMubWFrZV9kcmF3X2FyZWEoKTtcblx0fVxuXG5cdG1ha2VfY2hhcnRfYXJlYSgpIHtcblx0XHR0aGlzLnN2ZyA9ICQkLmNyZWF0ZVNWRygnc3ZnJywge1xuXHRcdFx0Y2xhc3NOYW1lOiAnY2hhcnQnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmNoYXJ0X3dyYXBwZXIsXG5cdFx0XHR3aWR0aDogdGhpcy5iYXNlX3dpZHRoLFxuXHRcdFx0aGVpZ2h0OiB0aGlzLmJhc2VfaGVpZ2h0XG5cdFx0fSk7XG5cblx0XHR0aGlzLnN2Z19kZWZzID0gJCQuY3JlYXRlU1ZHKCdkZWZzJywge1xuXHRcdFx0aW5zaWRlOiB0aGlzLnN2Zyxcblx0XHR9KTtcblxuXHRcdHJldHVybiB0aGlzLnN2Zztcblx0fVxuXG5cdG1ha2VfZHJhd19hcmVhKCkge1xuXHRcdHRoaXMuZHJhd19hcmVhID0gJCQuY3JlYXRlU1ZHKFwiZ1wiLCB7XG5cdFx0XHRjbGFzc05hbWU6IHRoaXMudHlwZSArICctY2hhcnQnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLnN2Zyxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgke3RoaXMudHJhbnNsYXRlX3h9LCAke3RoaXMudHJhbnNsYXRlX3l9KWBcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7IH1cblxuXHRtYWtlX3Rvb2x0aXAoKSB7XG5cdFx0dGhpcy50aXAgPSBuZXcgZnJhcHBlLmNoYXJ0LlN2Z1RpcCh7XG5cdFx0XHRwYXJlbnQ6IHRoaXMuY2hhcnRfd3JhcHBlcixcblx0XHR9KTtcblx0XHR0aGlzLmJpbmRfdG9vbHRpcCgpO1xuXHR9XG5cblxuXHRzaG93X3N1bW1hcnkoKSB7fVxuXHRzaG93X2N1c3RvbV9zdW1tYXJ5KCkge1xuXHRcdHRoaXMuc3VtbWFyeS5tYXAoZCA9PiB7XG5cdFx0XHRsZXQgc3RhdHMgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnc3RhdHMnLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3BhbiBjbGFzcz1cImluZGljYXRvciAke2QuY29sb3J9XCI+JHtkLnRpdGxlfTogJHtkLnZhbHVlfTwvc3Bhbj5gXG5cdFx0XHR9KTtcblx0XHRcdHRoaXMuc3RhdHNfd3JhcHBlci5hcHBlbmRDaGlsZChzdGF0cyk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF9uYXZpZ2F0aW9uKGluaXQ9ZmFsc2UpIHtcblx0XHR0aGlzLm1ha2Vfb3ZlcmxheSgpO1xuXG5cdFx0aWYoaW5pdCkge1xuXHRcdFx0dGhpcy5iaW5kX292ZXJsYXkoKTtcblxuXHRcdFx0ZG9jdW1lbnQuYWRkRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIChlKSA9PiB7XG5cdFx0XHRcdGlmKCQkLmlzRWxlbWVudEluVmlld3BvcnQodGhpcy5jaGFydF93cmFwcGVyKSkge1xuXHRcdFx0XHRcdGUgPSBlIHx8IHdpbmRvdy5ldmVudDtcblxuXHRcdFx0XHRcdGlmIChlLmtleUNvZGUgPT0gJzM3Jykge1xuXHRcdFx0XHRcdFx0dGhpcy5vbl9sZWZ0X2Fycm93KCk7XG5cdFx0XHRcdFx0fSBlbHNlIGlmIChlLmtleUNvZGUgPT0gJzM5Jykge1xuXHRcdFx0XHRcdFx0dGhpcy5vbl9yaWdodF9hcnJvdygpO1xuXHRcdFx0XHRcdH0gZWxzZSBpZiAoZS5rZXlDb2RlID09ICczOCcpIHtcblx0XHRcdFx0XHRcdHRoaXMub25fdXBfYXJyb3coKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSAnNDAnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX2Rvd25fYXJyb3coKTtcblx0XHRcdFx0XHR9IGVsc2UgaWYgKGUua2V5Q29kZSA9PSAnMTMnKSB7XG5cdFx0XHRcdFx0XHR0aGlzLm9uX2VudGVyX2tleSgpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fVxuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG5cblx0bWFrZV9vdmVybGF5KCkge31cblx0YmluZF9vdmVybGF5KCkge31cblxuXHRvbl9sZWZ0X2Fycm93KCkge31cblx0b25fcmlnaHRfYXJyb3coKSB7fVxuXHRvbl91cF9hcnJvdygpIHt9XG5cdG9uX2Rvd25fYXJyb3coKSB7fVxuXHRvbl9lbnRlcl9rZXkoKSB7fVxuXG5cdGdldF9kYXRhX3BvaW50KGluZGV4PXRoaXMuY3VycmVudF9pbmRleCkge1xuXHRcdC8vIGNoZWNrIGZvciBsZW5ndGhcblx0XHRsZXQgZGF0YV9wb2ludCA9IHtcblx0XHRcdGluZGV4OiBpbmRleFxuXHRcdH07XG5cdFx0bGV0IHkgPSB0aGlzLnlbMF07XG5cdFx0WydzdmdfdW5pdHMnLCAneV90b3BzJywgJ3ZhbHVlcyddLm1hcChrZXkgPT4ge1xuXHRcdFx0bGV0IGRhdGFfa2V5ID0ga2V5LnNsaWNlKDAsIGtleS5sZW5ndGgtMSk7XG5cdFx0XHRkYXRhX3BvaW50W2RhdGFfa2V5XSA9IHlba2V5XVtpbmRleF07XG5cdFx0fSk7XG5cdFx0ZGF0YV9wb2ludC5sYWJlbCA9IHRoaXMueFtpbmRleF07XG5cdFx0cmV0dXJuIGRhdGFfcG9pbnQ7XG5cdH1cblxuXHR1cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KGluZGV4KSB7XG5cdFx0aWYoaW5kZXggPCAwKSBpbmRleCA9IDA7XG5cdFx0aWYoaW5kZXggPj0gdGhpcy54Lmxlbmd0aCkgaW5kZXggPSB0aGlzLngubGVuZ3RoIC0gMTtcblx0XHRpZihpbmRleCA9PT0gdGhpcy5jdXJyZW50X2luZGV4KSByZXR1cm47XG5cdFx0dGhpcy5jdXJyZW50X2luZGV4ID0gaW5kZXg7XG5cdFx0JCQuZmlyZSh0aGlzLnBhcmVudCwgXCJkYXRhLXNlbGVjdFwiLCB0aGlzLmdldF9kYXRhX3BvaW50KCkpO1xuXHR9XG5cblx0Ly8gSGVscGVyc1xuXHRnZXRfc3Ryd2lkdGgoc3RyaW5nKSB7XG5cdFx0cmV0dXJuIHN0cmluZy5sZW5ndGggKiA4O1xuXHR9XG5cblx0Ly8gT2JqZWN0c1xuXHRzZXR1cF91dGlscygpIHsgfVxufVxuXG5mcmFwcGUuY2hhcnQuQXhpc0NoYXJ0ID0gY2xhc3MgQXhpc0NoYXJ0IGV4dGVuZHMgZnJhcHBlLmNoYXJ0LkZyYXBwZUNoYXJ0IHtcblx0Y29uc3RydWN0b3IoYXJncykge1xuXHRcdHN1cGVyKGFyZ3MpO1xuXG5cdFx0dGhpcy54ID0gdGhpcy5kYXRhLmxhYmVscztcblx0XHR0aGlzLnkgPSB0aGlzLmRhdGEuZGF0YXNldHM7XG5cblx0XHR0aGlzLmdldF95X2xhYmVsID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X2xhYmVsO1xuXHRcdHRoaXMuZ2V0X3lfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueV90b29sdGlwO1xuXHRcdHRoaXMuZ2V0X3hfdG9vbHRpcCA9IHRoaXMuZm9ybWF0X2xhbWJkYXMueF90b29sdGlwO1xuXG5cdFx0dGhpcy5jb2xvcnMgPSBbJ2dyZWVuJywgJ2JsdWUnLCAndmlvbGV0JywgJ3JlZCcsICdvcmFuZ2UnLFxuXHRcdFx0XHQneWVsbG93JywgJ2xpZ2h0LWJsdWUnLCAnbGlnaHQtZ3JlZW4nLCAncHVycGxlJywgJ21hZ2VudGEnXTtcblxuXHRcdHRoaXMuemVyb19saW5lID0gdGhpcy5oZWlnaHQ7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5kYXRhLmRhdGFzZXRzLm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzID0gZC52YWx1ZXMubWFwKHZhbCA9PiAoIWlzTmFOKHZhbCkgPyB2YWwgOiAwKSk7XG5cdFx0fSk7XG5cdFx0dGhpcy5zZXR1cF94KCk7XG5cdFx0dGhpcy5zZXR1cF95KCk7XG5cdH1cblxuXHRzZXR1cF94KCkge1xuXHRcdHRoaXMuc2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpO1xuXG5cdFx0aWYodGhpcy54X2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gIHRoaXMueF9heGlzX3Bvc2l0aW9ucy5zbGljZSgpO1xuXHRcdH1cblx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMgPSB0aGlzLngubWFwKChkLCBpKSA9PlxuXHRcdFx0JCQuZmxvYXRfMih0aGlzLnhfb2Zmc2V0ICsgaSAqIHRoaXMuYXZnX3VuaXRfd2lkdGgpKTtcblxuXHRcdGlmKCF0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zKSB7XG5cdFx0XHR0aGlzLnhfb2xkX2F4aXNfcG9zaXRpb25zID0gdGhpcy54X2F4aXNfcG9zaXRpb25zLnNsaWNlKCk7XG5cdFx0fVxuXHR9XG5cblx0c2V0dXBfeSgpIHtcblx0XHRpZih0aGlzLnlfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSAgdGhpcy55X2F4aXNfdmFsdWVzLnNsaWNlKCk7XG5cdFx0fVxuXG5cdFx0bGV0IHZhbHVlcyA9IHRoaXMuZ2V0X2FsbF95X3ZhbHVlcygpO1xuXG5cdFx0aWYodGhpcy55X3N1bXMgJiYgdGhpcy55X3N1bXMubGVuZ3RoID4gMCkge1xuXHRcdFx0dmFsdWVzID0gdmFsdWVzLmNvbmNhdCh0aGlzLnlfc3Vtcyk7XG5cdFx0fVxuXG5cdFx0dGhpcy55X2F4aXNfdmFsdWVzID0gdGhpcy5nZXRfeV9heGlzX3BvaW50cyh2YWx1ZXMpO1xuXG5cdFx0aWYoIXRoaXMueV9vbGRfYXhpc192YWx1ZXMpIHtcblx0XHRcdHRoaXMueV9vbGRfYXhpc192YWx1ZXMgPSB0aGlzLnlfYXhpc192YWx1ZXMuc2xpY2UoKTtcblx0XHR9XG5cblx0XHRjb25zdCB5X3B0cyA9IHRoaXMueV9heGlzX3ZhbHVlcztcblx0XHRjb25zdCB2YWx1ZV9yYW5nZSA9IHlfcHRzW3lfcHRzLmxlbmd0aC0xXSAtIHlfcHRzWzBdO1xuXG5cdFx0aWYodGhpcy5tdWx0aXBsaWVyKSB0aGlzLm9sZF9tdWx0aXBsaWVyID0gdGhpcy5tdWx0aXBsaWVyO1xuXHRcdHRoaXMubXVsdGlwbGllciA9IHRoaXMuaGVpZ2h0IC8gdmFsdWVfcmFuZ2U7XG5cdFx0aWYoIXRoaXMub2xkX211bHRpcGxpZXIpIHRoaXMub2xkX211bHRpcGxpZXIgPSB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRjb25zdCB6ZXJvX2luZGV4ID0geV9wdHMuaW5kZXhPZigwKTtcblx0XHRjb25zdCBpbnRlcnZhbCA9IHlfcHRzWzFdIC0geV9wdHNbMF07XG5cdFx0Y29uc3QgaW50ZXJ2YWxfaGVpZ2h0ID0gaW50ZXJ2YWwgKiB0aGlzLm11bHRpcGxpZXI7XG5cblx0XHRpZih0aGlzLnplcm9fbGluZSkgdGhpcy5vbGRfemVyb19saW5lID0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0dGhpcy56ZXJvX2xpbmUgPSB0aGlzLmhlaWdodCAtICh6ZXJvX2luZGV4ICogaW50ZXJ2YWxfaGVpZ2h0KTtcblx0XHRpZighdGhpcy5vbGRfemVyb19saW5lKSB0aGlzLm9sZF96ZXJvX2xpbmUgPSB0aGlzLnplcm9fbGluZTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0c3VwZXIuc2V0dXBfY29tcG9uZW50cygpO1xuXHRcdHRoaXMuc2V0dXBfbWFya2VyX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2FnZ3JlZ2F0aW9uX2NvbXBvbmVudHMoKTtcblx0XHR0aGlzLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX21hcmtlcl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMueV9heGlzX2dyb3VwID0gJCQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ3kgYXhpcycsIGluc2lkZTogdGhpcy5kcmF3X2FyZWF9KTtcblx0XHR0aGlzLnhfYXhpc19ncm91cCA9ICQkLmNyZWF0ZVNWRygnZycsIHtjbGFzc05hbWU6ICd4IGF4aXMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwID0gJCQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ3NwZWNpZmljIGF4aXMnLCBpbnNpZGU6IHRoaXMuZHJhd19hcmVhfSk7XG5cdH1cblxuXHRzZXR1cF9hZ2dyZWdhdGlvbl9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMuc3VtX2dyb3VwID0gJCQuY3JlYXRlU1ZHKCdnJywge2NsYXNzTmFtZTogJ2RhdGEtcG9pbnRzJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHRcdHRoaXMuYXZlcmFnZV9ncm91cCA9ICQkLmNyZWF0ZVNWRygnZycsIHtjbGFzc05hbWU6ICdjaGFydC1hcmVhJywgaW5zaWRlOiB0aGlzLmRyYXdfYXJlYX0pO1xuXHR9XG5cblx0c2V0dXBfZ3JhcGhfY29tcG9uZW50cygpIHtcblx0XHR0aGlzLnN2Z191bml0c19ncm91cHMgPSBbXTtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHR0aGlzLnN2Z191bml0c19ncm91cHNbaV0gPSAkJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogJ2RhdGEtcG9pbnRzIGRhdGEtcG9pbnRzLScgKyBpLFxuXHRcdFx0XHRpbnNpZGU6IHRoaXMuZHJhd19hcmVhXG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfZ3JhcGhfY29tcG9uZW50cyhpbml0PWZhbHNlKSB7XG5cdFx0dGhpcy5tYWtlX3lfYXhpcygpO1xuXHRcdHRoaXMubWFrZV94X2F4aXMoKTtcblx0XHR0aGlzLmRyYXdfZ3JhcGgoaW5pdCk7XG5cdFx0dGhpcy5tYWtlX3lfc3BlY2lmaWNzKCk7XG5cdH1cblxuXHQvLyBtYWtlIFZFUlRJQ0FMIGxpbmVzIGZvciB4IHZhbHVlc1xuXHRtYWtlX3hfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0bGV0IHN0YXJ0X2F0LCBoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyA9ICcnO1xuXHRcdGlmKHRoaXMueF9heGlzX21vZGUgPT09ICdzcGFuJykge1x0XHQvLyBsb25nIHNwYW5uaW5nIGxpbmVzXG5cdFx0XHRzdGFydF9hdCA9IC03O1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy5oZWlnaHQgKyAxNTtcblx0XHRcdHRleHRfc3RhcnRfYXQgPSB0aGlzLmhlaWdodCArIDI1O1xuXHRcdH0gZWxzZSBpZih0aGlzLnhfYXhpc19tb2RlID09PSAndGljaycpe1x0Ly8gc2hvcnQgbGFiZWwgbGluZXNcblx0XHRcdHN0YXJ0X2F0ID0gdGhpcy5oZWlnaHQ7XG5cdFx0XHRoZWlnaHQgPSA2O1xuXHRcdFx0dGV4dF9zdGFydF9hdCA9IDk7XG5cdFx0XHRheGlzX2xpbmVfY2xhc3MgPSAneC1heGlzLWxhYmVsJztcblx0XHR9XG5cblx0XHR0aGlzLnhfYXhpc19ncm91cC5zZXRBdHRyaWJ1dGUoJ3RyYW5zZm9ybScsIGB0cmFuc2xhdGUoMCwke3N0YXJ0X2F0fSlgKTtcblxuXHRcdGlmKGFuaW1hdGUpIHtcblx0XHRcdHRoaXMubWFrZV9hbmltX3hfYXhpcyhoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcyk7XG5cdFx0XHRyZXR1cm47XG5cdFx0fVxuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLngubWFwKChwb2ludCwgaSkgPT4ge1xuXHRcdFx0dGhpcy54X2F4aXNfZ3JvdXAuYXBwZW5kQ2hpbGQoXG5cdFx0XHRcdHRoaXMubWFrZV94X2xpbmUoXG5cdFx0XHRcdFx0aGVpZ2h0LFxuXHRcdFx0XHRcdHRleHRfc3RhcnRfYXQsXG5cdFx0XHRcdFx0cG9pbnQsXG5cdFx0XHRcdFx0J3gtdmFsdWUtdGV4dCcsXG5cdFx0XHRcdFx0YXhpc19saW5lX2NsYXNzLFxuXHRcdFx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpXVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Ly8gbWFrZSBIT1JJWk9OVEFMIGxpbmVzIGZvciB5IHZhbHVlc1xuXHRtYWtlX3lfYXhpcyhhbmltYXRlPWZhbHNlKSB7XG5cdFx0aWYoYW5pbWF0ZSkge1xuXHRcdFx0dGhpcy5tYWtlX2FuaW1feV9heGlzKCk7XG5cdFx0XHR0aGlzLm1ha2VfYW5pbV95X3NwZWNpZmljcygpO1xuXHRcdFx0cmV0dXJuO1xuXHRcdH1cblxuXHRcdGxldCBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XSA9IHRoaXMuZ2V0X3lfYXhpc19saW5lX3Byb3BzKCk7XG5cblx0XHR0aGlzLnlfYXhpc19ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMueV9heGlzX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHR0aGlzLnlfYXhpc19ncm91cC5hcHBlbmRDaGlsZChcblx0XHRcdFx0dGhpcy5tYWtlX3lfbGluZShcblx0XHRcdFx0XHRzdGFydF9hdCxcblx0XHRcdFx0XHR3aWR0aCxcblx0XHRcdFx0XHR0ZXh0X2VuZF9hdCxcblx0XHRcdFx0XHR2YWx1ZSxcblx0XHRcdFx0XHQneS12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCkgLy8gTm9uLWZpcnN0IFplcm8gbGluZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19saW5lX3Byb3BzKHNwZWNpZmljPWZhbHNlKSB7XG5cdFx0aWYoc3BlY2lmaWMpIHtcblx0XHRcdHJldHVyblt0aGlzLndpZHRoLCB0aGlzLndpZHRoICsgNSwgJ3NwZWNpZmljLXZhbHVlJywgMF07XG5cdFx0fVxuXHRcdGxldCB3aWR0aCwgdGV4dF9lbmRfYXQgPSAtOSwgYXhpc19saW5lX2NsYXNzID0gJycsIHN0YXJ0X2F0ID0gMDtcblx0XHRpZih0aGlzLnlfYXhpc19tb2RlID09PSAnc3BhbicpIHtcdFx0Ly8gbG9uZyBzcGFubmluZyBsaW5lc1xuXHRcdFx0d2lkdGggPSB0aGlzLndpZHRoICsgNjtcblx0XHRcdHN0YXJ0X2F0ID0gLTY7XG5cdFx0fSBlbHNlIGlmKHRoaXMueV9heGlzX21vZGUgPT09ICd0aWNrJyl7XHQvLyBzaG9ydCBsYWJlbCBsaW5lc1xuXHRcdFx0d2lkdGggPSAtNjtcblx0XHRcdGF4aXNfbGluZV9jbGFzcyA9ICd5LWF4aXMtbGFiZWwnO1xuXHRcdH1cblxuXHRcdHJldHVybiBbd2lkdGgsIHRleHRfZW5kX2F0LCBheGlzX2xpbmVfY2xhc3MsIHN0YXJ0X2F0XTtcblx0fVxuXG5cdGRyYXdfZ3JhcGgoaW5pdD1mYWxzZSkge1xuXHRcdGlmKGluaXQpIHtcblx0XHRcdHRoaXMuZHJhd19uZXdfZ3JhcGhfYW5kX2FuaW1hdGUoKTtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0ZC5zdmdfdW5pdHMgPSBbXTtcblx0XHRcdHRoaXMubWFrZV9wYXRoICYmIHRoaXMubWFrZV9wYXRoKGQsIGksIHRoaXMueF9heGlzX3Bvc2l0aW9ucywgZC55X3RvcHMsIGQuY29sb3IgfHwgdGhpcy5jb2xvcnNbaV0pO1xuXHRcdFx0dGhpcy5tYWtlX25ld191bml0cyhkLCBpKTtcblx0XHR9KTtcblx0fVxuXG5cdGRyYXdfbmV3X2dyYXBoX2FuZF9hbmltYXRlKCkge1xuXHRcdGxldCBkYXRhID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0Ly8gQW5pbTogRG9uJ3QgZHJhdyBpbml0aWFsIHZhbHVlcywgc3RvcmUgdGhlbSBhbmQgdXBkYXRlIGxhdGVyXG5cdFx0XHRkLnlfdG9wcyA9IG5ldyBBcnJheShkLnZhbHVlcy5sZW5ndGgpLmZpbGwodGhpcy56ZXJvX2xpbmUpOyAvLyBubyB2YWx1ZVxuXHRcdFx0ZGF0YS5wdXNoKHt2YWx1ZXM6IGQudmFsdWVzfSk7XG5cdFx0XHRkLnN2Z191bml0cyA9IFtdO1xuXG5cdFx0XHR0aGlzLm1ha2VfcGF0aCAmJiB0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHMoZCwgaSk7XG5cdFx0fSk7XG5cblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhkYXRhKTtcblx0XHR9LCAzNTApO1xuXHR9XG5cblx0c2V0dXBfbmF2aWdhdGlvbihpbml0KSB7XG5cdFx0Ly8gSGFjazogZGVmZXIgbmF2IHRpbGwgaW5pdGlhbCB1cGRhdGVfdmFsdWVzXG5cdFx0c2V0VGltZW91dCgoKSA9PiB7XG5cdFx0XHRzdXBlci5zZXR1cF9uYXZpZ2F0aW9uKGluaXQpO1xuXHRcdH0sIDUwMCk7XG5cdH1cblxuXHRtYWtlX25ld191bml0cyhkLCBpKSB7XG5cdFx0dGhpcy5tYWtlX25ld191bml0c19mb3JfZGF0YXNldChcblx0XHRcdHRoaXMueF9heGlzX3Bvc2l0aW9ucyxcblx0XHRcdGQueV90b3BzLFxuXHRcdFx0ZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSxcblx0XHRcdGksXG5cdFx0XHR0aGlzLnkubGVuZ3RoXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfbmV3X3VuaXRzX2Zvcl9kYXRhc2V0KHhfdmFsdWVzLCB5X3ZhbHVlcywgY29sb3IsIGRhdGFzZXRfaW5kZXgsIG5vX29mX2RhdGFzZXRzLCBncm91cCwgYXJyYXksIHVuaXQpIHtcblx0XHRpZighZ3JvdXApIGdyb3VwID0gdGhpcy5zdmdfdW5pdHNfZ3JvdXBzW2RhdGFzZXRfaW5kZXhdO1xuXHRcdGlmKCFhcnJheSkgYXJyYXkgPSB0aGlzLnlbZGF0YXNldF9pbmRleF0uc3ZnX3VuaXRzO1xuXHRcdGlmKCF1bml0KSB1bml0ID0gdGhpcy51bml0X2FyZ3M7XG5cblx0XHRncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdGFycmF5Lmxlbmd0aCA9IDA7XG5cblx0XHR5X3ZhbHVlcy5tYXAoKHksIGkpID0+IHtcblx0XHRcdGxldCBkYXRhX3VuaXQgPSB0aGlzLmRyYXdbdW5pdC50eXBlXShcblx0XHRcdFx0eF92YWx1ZXNbaV0sXG5cdFx0XHRcdHksXG5cdFx0XHRcdHVuaXQuYXJncyxcblx0XHRcdFx0Y29sb3IsXG5cdFx0XHRcdGRhdGFzZXRfaW5kZXgsXG5cdFx0XHRcdG5vX29mX2RhdGFzZXRzXG5cdFx0XHQpO1xuXHRcdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoZGF0YV91bml0KTtcblx0XHRcdGFycmF5LnB1c2goZGF0YV91bml0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfeV9zcGVjaWZpY3MoKSB7XG5cdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4ge1xuXHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLmFwcGVuZENoaWxkKFxuXHRcdFx0XHR0aGlzLm1ha2VfeV9saW5lKFxuXHRcdFx0XHRcdDAsXG5cdFx0XHRcdFx0dGhpcy53aWR0aCxcblx0XHRcdFx0XHR0aGlzLndpZHRoICsgNSxcblx0XHRcdFx0XHRkLnRpdGxlLnRvVXBwZXJDYXNlKCksXG5cdFx0XHRcdFx0J3NwZWNpZmljLXZhbHVlJyxcblx0XHRcdFx0XHQnc3BlY2lmaWMtdmFsdWUnLFxuXHRcdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0XHRmYWxzZSxcblx0XHRcdFx0XHRkLmxpbmVfdHlwZVxuXHRcdFx0XHQpXG5cdFx0XHQpO1xuXHRcdH0pO1xuXHR9XG5cblx0YmluZF90b29sdGlwKCkge1xuXHRcdC8vIFRPRE86IGNvdWxkIGJlIGluIHRvb2x0aXAgaXRzZWxmLCBhcyBpdCBpcyBhIGdpdmVuIGZ1bmN0aW9uYWxpdHkgZm9yIGl0cyBwYXJlbnRcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuYWRkRXZlbnRMaXN0ZW5lcignbW91c2Vtb3ZlJywgKGUpID0+IHtcblx0XHRcdGxldCBvZmZzZXQgPSAkJC5vZmZzZXQodGhpcy5jaGFydF93cmFwcGVyKTtcblx0XHRcdGxldCByZWxYID0gZS5wYWdlWCAtIG9mZnNldC5sZWZ0IC0gdGhpcy50cmFuc2xhdGVfeDtcblx0XHRcdGxldCByZWxZID0gZS5wYWdlWSAtIG9mZnNldC50b3AgLSB0aGlzLnRyYW5zbGF0ZV95O1xuXG5cdFx0XHRpZihyZWxZIDwgdGhpcy5oZWlnaHQgKyB0aGlzLnRyYW5zbGF0ZV95ICogMikge1xuXHRcdFx0XHR0aGlzLm1hcF90b29sdGlwX3hfcG9zaXRpb25fYW5kX3Nob3cocmVsWCk7XG5cdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHR0aGlzLnRpcC5oaWRlX3RpcCgpO1xuXHRcdFx0fVxuXHRcdH0pO1xuXHR9XG5cblx0bWFwX3Rvb2x0aXBfeF9wb3NpdGlvbl9hbmRfc2hvdyhyZWxYKSB7XG5cdFx0Zm9yKHZhciBpPXRoaXMueF9heGlzX3Bvc2l0aW9ucy5sZW5ndGggLSAxOyBpID49IDAgOyBpLS0pIHtcblx0XHRcdGxldCB4X3ZhbCA9IHRoaXMueF9heGlzX3Bvc2l0aW9uc1tpXTtcblx0XHRcdC8vIGxldCBkZWx0YSA9IGkgPT09IDAgPyB0aGlzLmF2Z191bml0X3dpZHRoIDogeF92YWwgLSB0aGlzLnhfYXhpc19wb3NpdGlvbnNbaS0xXTtcblx0XHRcdGlmKHJlbFggPiB4X3ZhbCAtIHRoaXMuYXZnX3VuaXRfd2lkdGgvMikge1xuXHRcdFx0XHRsZXQgeCA9IHhfdmFsICsgdGhpcy50cmFuc2xhdGVfeDtcblx0XHRcdFx0bGV0IHkgPSB0aGlzLnlfbWluX3RvcHNbaV0gKyB0aGlzLnRyYW5zbGF0ZV95O1xuXG5cdFx0XHRcdGxldCB0aXRsZSA9IHRoaXMueC5mb3JtYXR0ZWQgJiYgdGhpcy54LmZvcm1hdHRlZC5sZW5ndGg+MFxuXHRcdFx0XHRcdD8gdGhpcy54LmZvcm1hdHRlZFtpXSA6IHRoaXMueFtpXTtcblx0XHRcdFx0bGV0IHZhbHVlcyA9IHRoaXMueS5tYXAoKHNldCwgaikgPT4ge1xuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHR0aXRsZTogc2V0LnRpdGxlLFxuXHRcdFx0XHRcdFx0dmFsdWU6IHNldC5mb3JtYXR0ZWQgPyBzZXQuZm9ybWF0dGVkW2ldIDogc2V0LnZhbHVlc1tpXSxcblx0XHRcdFx0XHRcdGNvbG9yOiBzZXQuY29sb3IgfHwgdGhpcy5jb2xvcnNbal0sXG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KTtcblxuXHRcdFx0XHQvLyBUT0RPOiB1cHNpZGUtZG93biB0b29sdGlwcyBmb3IgbmVnYXRpdmUgdmFsdWVzP1xuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIHRpdGxlLCAnJywgdmFsdWVzKTtcblx0XHRcdFx0dGhpcy50aXAuc2hvd190aXAoKTtcblx0XHRcdFx0YnJlYWs7XG5cdFx0XHR9XG5cdFx0fVxuXHR9XG5cblx0Ly8gQVBJXG5cdHNob3dfc3VtcygpIHtcblx0XHR0aGlzLnVwZGF0aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMueV9zdW1zID0gbmV3IEFycmF5KHRoaXMueF9heGlzX3Bvc2l0aW9ucy5sZW5ndGgpLmZpbGwoMCk7XG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGQudmFsdWVzLm1hcCggKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdHRoaXMueV9zdW1zW2ldICs9IHZhbHVlO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHQvLyBSZW1ha2UgeSBheGlzLCBhbmltYXRlXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cblx0XHQvLyBUaGVuIG1ha2Ugc3VtIHVuaXRzLCBkb24ndCBhbmltYXRlXG5cdFx0dGhpcy5zdW1fdW5pdHMgPSBbXTtcblxuXHRcdHRoaXMubWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQoXG5cdFx0XHR0aGlzLnhfYXhpc19wb3NpdGlvbnMsXG5cdFx0XHR0aGlzLnlfc3Vtcy5tYXAoIHZhbCA9PiAkJC5mbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSksXG5cdFx0XHQnbGlnaHQtZ3JleScsXG5cdFx0XHQwLFxuXHRcdFx0MSxcblx0XHRcdHRoaXMuc3VtX2dyb3VwLFxuXHRcdFx0dGhpcy5zdW1fdW5pdHNcblx0XHQpO1xuXG5cdFx0Ly8gdGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgb2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblxuXHRcdHRoaXMudXBkYXRpbmcgPSBmYWxzZTtcblx0fVxuXG5cdGhpZGVfc3VtcygpIHtcblx0XHRpZih0aGlzLnVwZGF0aW5nKSByZXR1cm47XG5cdFx0dGhpcy55X3N1bXMgPSBbXTtcblx0XHR0aGlzLnN1bV9ncm91cC50ZXh0Q29udGVudCA9ICcnO1xuXHRcdHRoaXMuc3VtX3VuaXRzID0gW107XG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKCk7XG5cdH1cblxuXHRzaG93X2F2ZXJhZ2UoKSB7XG5cdFx0dGhpcy5vbGRfc3BlY2lmaWNfdmFsdWVzID0gdGhpcy5zcGVjaWZpY192YWx1ZXMuc2xpY2UoKTtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRsZXQgc3VtID0gMDtcblx0XHRcdGQudmFsdWVzLm1hcChlID0+IHtzdW0rPWV9KTtcblx0XHRcdGxldCBhdmVyYWdlID0gc3VtL2QudmFsdWVzLmxlbmd0aDtcblxuXHRcdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMucHVzaCh7XG5cdFx0XHRcdHRpdGxlOiBcIkFWR1wiICsgXCIgXCIgKyAoaSsxKSxcblx0XHRcdFx0bGluZV90eXBlOiBcImRhc2hlZFwiLFxuXHRcdFx0XHR2YWx1ZTogYXZlcmFnZSxcblx0XHRcdFx0YXV0bzogMVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cblx0XHRjb25zb2xlLmxvZyh0aGlzLnNwZWNpZmljX3ZhbHVlcyk7XG5cblx0XHR0aGlzLnVwZGF0ZV92YWx1ZXMoKTtcblx0fVxuXG5cdGhpZGVfYXZlcmFnZSgpIHtcblx0XHR0aGlzLm9sZF9zcGVjaWZpY192YWx1ZXMgPSB0aGlzLnNwZWNpZmljX3ZhbHVlcy5zbGljZSgpO1xuXG5cdFx0bGV0IGluZGljZXNfdG9fcmVtb3ZlID0gW107XG5cdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRpZihkLmF1dG8pIGluZGljZXNfdG9fcmVtb3ZlLnVuc2hpZnQoaSk7XG5cdFx0fSk7XG5cblx0XHRjb25zb2xlLmxvZyhpbmRpY2VzX3RvX3JlbW92ZSk7XG5cblx0XHRpbmRpY2VzX3RvX3JlbW92ZS5tYXAoaW5kZXggPT4ge1xuXHRcdFx0dGhpcy5zcGVjaWZpY192YWx1ZXMuc3BsaWNlKGluZGV4LCAxKTtcblx0XHR9KTtcblxuXHRcdGNvbnNvbGUubG9nKHRoaXMuc3BlY2lmaWNfdmFsdWVzKTtcblxuXHRcdHRoaXMudXBkYXRlX3ZhbHVlcygpO1xuXHR9XG5cblx0dXBkYXRlX3ZhbHVlcyhuZXdfeSwgbmV3X3gpIHtcblx0XHRpZighbmV3X3gpIHtcblx0XHRcdG5ld194ID0gdGhpcy54O1xuXHRcdH1cblx0XHR0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUgPSBbXTtcblx0XHR0aGlzLnVwZGF0aW5nID0gdHJ1ZTtcblxuXHRcdHRoaXMub2xkX3hfdmFsdWVzID0gdGhpcy54LnNsaWNlKCk7XG5cdFx0dGhpcy5vbGRfeV9heGlzX3RvcHMgPSB0aGlzLnkubWFwKGQgPT4gZC55X3RvcHMuc2xpY2UoKSk7XG5cblx0XHR0aGlzLm9sZF95X3ZhbHVlcyA9IHRoaXMueS5tYXAoZCA9PiBkLnZhbHVlcyk7XG5cblx0XHR0aGlzLm5vX29mX2V4dHJhX3B0cyA9IG5ld194Lmxlbmd0aCAtIHRoaXMueC5sZW5ndGg7XG5cblx0XHQvLyBKdXN0IHVwZGF0ZSB2YWx1ZXMgcHJvcCwgc2V0dXBfeC95KCkgd2lsbCBkbyB0aGUgcmVzdFxuXHRcdGlmKG5ld195KSB0aGlzLnkubWFwKChkLCBpKSA9PiB7ZC52YWx1ZXMgPSBuZXdfeVtpXS52YWx1ZXM7fSk7XG5cdFx0aWYobmV3X3gpIHRoaXMueCA9IG5ld194O1xuXG5cdFx0dGhpcy5zZXR1cF94KCk7XG5cdFx0dGhpcy5zZXR1cF95KCk7XG5cblx0XHQvLyBBbmltYXRlIG9ubHkgaWYgcG9zaXRpb25zIGhhdmUgY2hhbmdlZFxuXHRcdGlmKCEkJC5hcnJheXNfZXF1YWwodGhpcy54X29sZF9heGlzX3Bvc2l0aW9ucywgdGhpcy54X2F4aXNfcG9zaXRpb25zKSkge1xuXHRcdFx0dGhpcy5tYWtlX3hfYXhpcyh0cnVlKTtcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZighdGhpcy51cGRhdGluZykgdGhpcy5tYWtlX3hfYXhpcygpO1xuXHRcdFx0fSwgMzAwKVxuXHRcdH1cblxuXHRcdGlmKCEkJC5hcnJheXNfZXF1YWwodGhpcy55X29sZF9heGlzX3ZhbHVlcywgdGhpcy55X2F4aXNfdmFsdWVzKSB8fFxuXHRcdFx0KHRoaXMub2xkX3NwZWNpZmljX3ZhbHVlcyAmJlxuXHRcdFx0ISQkLmFycmF5c19lcXVhbCh0aGlzLm9sZF9zcGVjaWZpY192YWx1ZXMsIHRoaXMuc3BlY2lmaWNfdmFsdWVzKSkpIHtcblxuXHRcdFx0dGhpcy5tYWtlX3lfYXhpcyh0cnVlKTtcblx0XHRcdHNldFRpbWVvdXQoKCkgPT4ge1xuXHRcdFx0XHRpZighdGhpcy51cGRhdGluZykge1xuXHRcdFx0XHRcdHRoaXMubWFrZV95X2F4aXMoKTtcblx0XHRcdFx0XHR0aGlzLm1ha2VfeV9zcGVjaWZpY3MoKTtcblx0XHRcdFx0fVxuXHRcdFx0fSwgMzAwKVxuXHRcdH1cblxuXHRcdC8vIENoYW5nZSBpbiBkYXRhLCBzbyBjYWxjdWxhdGUgZGVwZW5kZW5jaWVzXG5cdFx0dGhpcy5jYWxjX3lfZGVwZW5kZW5jaWVzKCk7XG5cblx0XHR0aGlzLmFuaW1hdGVfZ3JhcGhzKCk7XG5cblx0XHQvLyBUcmlnZ2VyIGFuaW1hdGlvbiB3aXRoIHRoZSBhbmltYXRhYmxlIGVsZW1lbnRzIGluIHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZVxuXHRcdHRoaXMucnVuX2FuaW1hdGlvbigpO1xuXG5cdFx0dGhpcy51cGRhdGluZyA9IGZhbHNlO1xuXHR9XG5cblx0YWRkX2RhdGFfcG9pbnQoeV9wb2ludCwgeF9wb2ludCwgaW5kZXg9dGhpcy54Lmxlbmd0aCkge1xuXHRcdGxldCBuZXdfeSA9IHRoaXMueS5tYXAoZGF0YV9zZXQgPT4geyByZXR1cm4ge3ZhbHVlczpkYXRhX3NldC52YWx1ZXN9OyB9KTtcblx0XHRuZXdfeS5tYXAoKGQsIGkpID0+IHsgZC52YWx1ZXMuc3BsaWNlKGluZGV4LCAwLCB5X3BvaW50W2ldKTsgfSk7XG5cdFx0bGV0IG5ld194ID0gdGhpcy54LnNsaWNlKCk7XG5cdFx0bmV3X3guc3BsaWNlKGluZGV4LCAwLCB4X3BvaW50KTtcblxuXHRcdHRoaXMudXBkYXRlX3ZhbHVlcyhuZXdfeSwgbmV3X3gpO1xuXHR9XG5cblx0cmVtb3ZlX2RhdGFfcG9pbnQoaW5kZXggPSB0aGlzLngubGVuZ3RoLTEpIHtcblx0XHRpZih0aGlzLngubGVuZ3RoIDwgMykgcmV0dXJuO1xuXG5cdFx0bGV0IG5ld195ID0gdGhpcy55Lm1hcChkYXRhX3NldCA9PiB7IHJldHVybiB7dmFsdWVzOmRhdGFfc2V0LnZhbHVlc307IH0pO1xuXHRcdG5ld195Lm1hcCgoZCwgaSkgPT4geyBkLnZhbHVlcy5zcGxpY2UoaW5kZXgsIDEpOyB9KTtcblx0XHRsZXQgbmV3X3ggPSB0aGlzLnguc2xpY2UoKTtcblx0XHRuZXdfeC5zcGxpY2UoaW5kZXgsIDEpO1xuXG5cdFx0dGhpcy51cGRhdGVfdmFsdWVzKG5ld195LCBuZXdfeCk7XG5cdH1cblxuXHRydW5fYW5pbWF0aW9uKCkge1xuXHRcdGxldCBhbmltX3N2ZyA9ICQkLnJ1blNWR0FuaW1hdGlvbih0aGlzLnN2ZywgdGhpcy5lbGVtZW50c190b19hbmltYXRlKTtcblxuXHRcdGlmKHRoaXMuc3ZnLnBhcmVudE5vZGUgPT0gdGhpcy5jaGFydF93cmFwcGVyKSB7XG5cdFx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIucmVtb3ZlQ2hpbGQodGhpcy5zdmcpO1xuXHRcdFx0dGhpcy5jaGFydF93cmFwcGVyLmFwcGVuZENoaWxkKGFuaW1fc3ZnKTtcblxuXHRcdH1cblxuXHRcdC8vIFJlcGxhY2UgdGhlIG5ldyBzdmcgKGRhdGEgaGFzIGxvbmcgYmVlbiByZXBsYWNlZClcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdGlmKGFuaW1fc3ZnLnBhcmVudE5vZGUgPT0gdGhpcy5jaGFydF93cmFwcGVyKSB7XG5cdFx0XHRcdHRoaXMuY2hhcnRfd3JhcHBlci5yZW1vdmVDaGlsZChhbmltX3N2Zyk7XG5cdFx0XHRcdHRoaXMuY2hhcnRfd3JhcHBlci5hcHBlbmRDaGlsZCh0aGlzLnN2Zyk7XG5cdFx0XHR9XG5cdFx0fSwgMjAwKTtcblx0fVxuXG5cdGFuaW1hdGVfZ3JhcGhzKCkge1xuXHRcdHRoaXMueS5tYXAoKGQsIGkpID0+IHtcblx0XHRcdC8vIFByZS1wcmVwLCBlcXVpbGl6ZSBubyBvZiBwb3NpdGlvbnMgYmV0d2VlbiBvbGQgYW5kIG5ld1xuXHRcdFx0bGV0IFtvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeV0gPSB0aGlzLmNhbGNfb2xkX2FuZF9uZXdfcG9zdGlvbnMoZCwgaSk7XG5cdFx0XHRpZih0aGlzLm5vX29mX2V4dHJhX3B0cyA+PSAwKSB7XG5cdFx0XHRcdHRoaXMubWFrZV9wYXRoICYmIHRoaXMubWFrZV9wYXRoKGQsIGksIG9sZF94LCBvbGRfeSwgZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSk7XG5cdFx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHNfZm9yX2RhdGFzZXQob2xkX3gsIG9sZF95LCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldLCBpLCB0aGlzLnkubGVuZ3RoKTtcblx0XHRcdH1cblx0XHRcdGQucGF0aCAmJiB0aGlzLmFuaW1hdGVfcGF0aChkLCBpLCBvbGRfeCwgb2xkX3ksIG5ld194LCBuZXdfeSk7XG5cdFx0XHR0aGlzLmFuaW1hdGVfdW5pdHMoZCwgaSwgb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3kpO1xuXHRcdH0pO1xuXG5cdFx0Ly8gVE9ETzogcmVwbGFjZSB3aXRoIHJlYWwgdW5pdHNcblx0XHRzZXRUaW1lb3V0KCgpID0+IHtcblx0XHRcdHRoaXMueS5tYXAoKGQsIGkpID0+IHtcblx0XHRcdFx0dGhpcy5tYWtlX3BhdGggJiYgdGhpcy5tYWtlX3BhdGgoZCwgaSwgdGhpcy54X2F4aXNfcG9zaXRpb25zLCBkLnlfdG9wcywgZC5jb2xvciB8fCB0aGlzLmNvbG9yc1tpXSk7XG5cdFx0XHRcdHRoaXMubWFrZV9uZXdfdW5pdHMoZCwgaSk7XG5cdFx0XHR9KTtcblx0XHR9LCAzMDApO1xuXHR9XG5cblx0YW5pbWF0ZV9wYXRoKGQsIGksIG9sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195KSB7XG5cdFx0Ly8gQW5pbWF0ZSBwYXRoXG5cdFx0Y29uc3QgbmV3X3BvaW50c19saXN0ID0gbmV3X3kubWFwKCh5LCBpKSA9PiAobmV3X3hbaV0gKyAnLCcgKyB5KSk7XG5cdFx0Y29uc3QgbmV3X3BhdGhfc3RyID0gbmV3X3BvaW50c19saXN0LmpvaW4oXCJMXCIpO1xuXG5cdFx0Y29uc3QgcGF0aF9hcmdzID0gW3t1bml0OiBkLnBhdGgsIG9iamVjdDogZCwga2V5OiAncGF0aCd9LCB7ZDpcIk1cIituZXdfcGF0aF9zdHJ9LCAyNTAsIFwiZWFzZWluXCJdO1xuXHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZS5wdXNoKHBhdGhfYXJncyk7XG5cblx0XHQvLyBBbmltYXRlIHJlZ2lvblxuXHRcdGlmKGQucmVnaW9uX3BhdGgpIHtcblx0XHRcdGxldCByZWdfc3RhcnRfcHQgPSBgMCwke3RoaXMuemVyb19saW5lfUxgO1xuXHRcdFx0bGV0IHJlZ19lbmRfcHQgPSBgTCR7dGhpcy53aWR0aH0sJHt0aGlzLnplcm9fbGluZX1gO1xuXG5cdFx0XHRjb25zdCByZWdpb25fYXJncyA9IFtcblx0XHRcdFx0e3VuaXQ6IGQucmVnaW9uX3BhdGgsIG9iamVjdDogZCwga2V5OiAncmVnaW9uX3BhdGgnfSxcblx0XHRcdFx0e2Q6XCJNXCIgKyByZWdfc3RhcnRfcHQgKyBuZXdfcGF0aF9zdHIgKyByZWdfZW5kX3B0fSxcblx0XHRcdFx0MjUwLFxuXHRcdFx0XHRcImVhc2VpblwiXG5cdFx0XHRdO1xuXHRcdFx0dGhpcy5lbGVtZW50c190b19hbmltYXRlLnB1c2gocmVnaW9uX2FyZ3MpO1xuXHRcdH1cblx0fVxuXG5cdGFuaW1hdGVfdW5pdHMoZCwgaW5kZXgsIG9sZF94LCBvbGRfeSwgbmV3X3gsIG5ld195KSB7XG5cdFx0bGV0IHR5cGUgPSB0aGlzLnVuaXRfYXJncy50eXBlO1xuXG5cdFx0ZC5zdmdfdW5pdHMubWFwKCh1bml0LCBpKSA9PiB7XG5cdFx0XHR0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaCh0aGlzLmFuaW1hdGVbdHlwZV0oXG5cdFx0XHRcdHt1bml0OnVuaXQsIGFycmF5OmQuc3ZnX3VuaXRzLCBpbmRleDogaX0sIC8vIHVuaXQsIHdpdGggaW5mbyB0byByZXBsYWNlIHdoZXJlIGl0IGNhbWUgZnJvbSBpbiB0aGUgZGF0YVxuXHRcdFx0XHRuZXdfeFtpXSxcblx0XHRcdFx0bmV3X3lbaV0sXG5cdFx0XHRcdGluZGV4XG5cdFx0XHQpKTtcblx0XHR9KTtcblx0fVxuXG5cdGNhbGNfb2xkX2FuZF9uZXdfcG9zdGlvbnMoZCwgaSkge1xuXHRcdGxldCBvbGRfeCA9IHRoaXMueF9vbGRfYXhpc19wb3NpdGlvbnMuc2xpY2UoKTtcblx0XHRsZXQgbmV3X3ggPSB0aGlzLnhfYXhpc19wb3NpdGlvbnMuc2xpY2UoKTtcblxuXHRcdGxldCBvbGRfeSA9IHRoaXMub2xkX3lfYXhpc190b3BzW2ldLnNsaWNlKCk7XG5cdFx0bGV0IG5ld195ID0gZC55X3RvcHMuc2xpY2UoKTtcblxuXHRcdGNvbnN0IGxhc3Rfb2xkX3hfcG9zID0gb2xkX3hbb2xkX3gubGVuZ3RoIC0gMV07XG5cdFx0Y29uc3QgbGFzdF9vbGRfeV9wb3MgPSBvbGRfeVtvbGRfeS5sZW5ndGggLSAxXTtcblxuXHRcdGNvbnN0IGxhc3RfbmV3X3hfcG9zID0gbmV3X3hbbmV3X3gubGVuZ3RoIC0gMV07XG5cdFx0Y29uc3QgbGFzdF9uZXdfeV9wb3MgPSBuZXdfeVtuZXdfeS5sZW5ndGggLSAxXTtcblxuXHRcdGlmKHRoaXMubm9fb2ZfZXh0cmFfcHRzID49IDApIHtcblx0XHRcdC8vIEZpcnN0IHN1YnN0aXR1dGUgY3VycmVudCBwYXRoIHdpdGggYSBzcXVpZ2dsZWQgb25lIChsb29raW5nIHRoZSBzYW1lIGJ1dFxuXHRcdFx0Ly8gaGF2aW5nIG1vcmUgcG9pbnRzIGF0IGVuZCksXG5cdFx0XHQvLyB0aGVuIGFuaW1hdGUgdG8gc3RyZXRjaCBpdCBsYXRlciB0byBuZXcgcG9pbnRzXG5cdFx0XHQvLyAobmV3IHBvaW50cyBhbHJlYWR5IGhhdmUgbW9yZSBwb2ludHMpXG5cblx0XHRcdC8vIEhlbmNlLCB0aGUgZXh0cmEgZW5kIHBvaW50cyB3aWxsIGNvcnJlc3BvbmQgdG8gY3VycmVudChvbGQpIHBvc2l0aW9uc1xuXHRcdFx0bGV0IGZpbGxlcl94ID0gbmV3IEFycmF5KE1hdGguYWJzKHRoaXMubm9fb2ZfZXh0cmFfcHRzKSkuZmlsbChsYXN0X29sZF94X3Bvcyk7XG5cdFx0XHRsZXQgZmlsbGVyX3kgPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3Rfb2xkX3lfcG9zKTtcblxuXHRcdFx0b2xkX3ggPSBvbGRfeC5jb25jYXQoZmlsbGVyX3gpO1xuXHRcdFx0b2xkX3kgPSBvbGRfeS5jb25jYXQoZmlsbGVyX3kpO1xuXG5cdFx0fSBlbHNlIHtcblx0XHRcdC8vIEp1c3QgbW9kaWZ5IHRoZSBuZXcgcG9pbnRzIHRvIGhhdmUgZXh0cmEgcG9pbnRzXG5cdFx0XHQvLyB3aXRoIHRoZSBzYW1lIHBvc2l0aW9uIGF0IGVuZFxuXHRcdFx0bGV0IGZpbGxlcl94ID0gbmV3IEFycmF5KE1hdGguYWJzKHRoaXMubm9fb2ZfZXh0cmFfcHRzKSkuZmlsbChsYXN0X25ld194X3Bvcyk7XG5cdFx0XHRsZXQgZmlsbGVyX3kgPSBuZXcgQXJyYXkoTWF0aC5hYnModGhpcy5ub19vZl9leHRyYV9wdHMpKS5maWxsKGxhc3RfbmV3X3lfcG9zKTtcblxuXHRcdFx0bmV3X3ggPSBuZXdfeC5jb25jYXQoZmlsbGVyX3gpO1xuXHRcdFx0bmV3X3kgPSBuZXdfeS5jb25jYXQoZmlsbGVyX3kpO1xuXHRcdH1cblxuXHRcdHJldHVybiBbb2xkX3gsIG9sZF95LCBuZXdfeCwgbmV3X3ldO1xuXHR9XG5cblx0bWFrZV9hbmltX3hfYXhpcyhoZWlnaHQsIHRleHRfc3RhcnRfYXQsIGF4aXNfbGluZV9jbGFzcykge1xuXHRcdC8vIEFuaW1hdGUgWCBBWElTIHRvIGFjY291bnQgZm9yIG1vcmUgb3IgbGVzcyBheGlzIGxpbmVzXG5cblx0XHRjb25zdCBvbGRfcG9zID0gdGhpcy54X29sZF9heGlzX3Bvc2l0aW9ucztcblx0XHRjb25zdCBuZXdfcG9zID0gdGhpcy54X2F4aXNfcG9zaXRpb25zO1xuXG5cdFx0Y29uc3Qgb2xkX3ZhbHMgPSB0aGlzLm9sZF94X3ZhbHVlcztcblx0XHRjb25zdCBuZXdfdmFscyA9IHRoaXMueDtcblxuXHRcdGNvbnN0IGxhc3RfbGluZV9wb3MgPSBvbGRfcG9zW29sZF9wb3MubGVuZ3RoIC0gMV07XG5cblx0XHRsZXQgYWRkX2FuZF9hbmltYXRlX2xpbmUgPSAodmFsdWUsIG9sZF9wb3MsIG5ld19wb3MsIGkpID0+IHtcblx0XHRcdGNvbnN0IHhfbGluZSA9IHRoaXMubWFrZV94X2xpbmUoXG5cdFx0XHRcdGhlaWdodCxcblx0XHRcdFx0dGV4dF9zdGFydF9hdCxcblx0XHRcdFx0dmFsdWUsIC8vIG5ldyB2YWx1ZVxuXHRcdFx0XHQneC12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0YXhpc19saW5lX2NsYXNzLFxuXHRcdFx0XHRvbGRfcG9zIC8vIG9sZCBwb3NpdGlvblxuXHRcdFx0KTtcblx0XHRcdHRoaXMueF9heGlzX2dyb3VwLmFwcGVuZENoaWxkKHhfbGluZSk7XG5cblx0XHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZSAmJiB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChbXG5cdFx0XHRcdHt1bml0OiB4X2xpbmUsIGFycmF5OiBbMF0sIGluZGV4OiAwfSxcblx0XHRcdFx0e3RyYW5zZm9ybTogYCR7IG5ld19wb3MgfSwgMGB9LFxuXHRcdFx0XHQyNTAsXG5cdFx0XHRcdFwiZWFzZWluXCIsXG5cdFx0XHRcdFwidHJhbnNsYXRlXCIsXG5cdFx0XHRcdHt0cmFuc2Zvcm06IGAkeyBvbGRfcG9zIH0sIDBgfVxuXHRcdFx0XSk7XG5cdFx0fVxuXG5cdFx0dGhpcy54X2F4aXNfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblxuXHRcdHRoaXMubWFrZV9uZXdfYXhpc19hbmltX2xpbmVzKFxuXHRcdFx0b2xkX3Bvcyxcblx0XHRcdG5ld19wb3MsXG5cdFx0XHRvbGRfdmFscyxcblx0XHRcdG5ld192YWxzLFxuXHRcdFx0bGFzdF9saW5lX3Bvcyxcblx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X2F4aXMoKSB7XG5cdFx0Ly8gQW5pbWF0ZSBZIEFYSVMgdG8gYWNjb3VudCBmb3IgbW9yZSBvciBsZXNzIGF4aXMgbGluZXNcblxuXHRcdGNvbnN0IG9sZF9wb3MgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzLm1hcCh2YWx1ZSA9PlxuXHRcdFx0dGhpcy56ZXJvX2xpbmUgLSB2YWx1ZSAqIHRoaXMubXVsdGlwbGllcik7XG5cdFx0Y29uc3QgbmV3X3BvcyA9IHRoaXMueV9heGlzX3ZhbHVlcy5tYXAodmFsdWUgPT5cblx0XHRcdHRoaXMuemVyb19saW5lIC0gdmFsdWUgKiB0aGlzLm11bHRpcGxpZXIpO1xuXG5cdFx0Y29uc3Qgb2xkX3ZhbHMgPSB0aGlzLnlfb2xkX2F4aXNfdmFsdWVzO1xuXHRcdGNvbnN0IG5ld192YWxzID0gdGhpcy55X2F4aXNfdmFsdWVzO1xuXG5cdFx0Y29uc3QgbGFzdF9saW5lX3BvcyA9IG9sZF9wb3Nbb2xkX3Bvcy5sZW5ndGggLSAxXTtcblxuXHRcdHRoaXMueV9heGlzX2dyb3VwLnRleHRDb250ZW50ID0gJyc7XG5cblx0XHR0aGlzLm1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhcblx0XHRcdG9sZF9wb3MsXG5cdFx0XHRuZXdfcG9zLFxuXHRcdFx0b2xkX3ZhbHMsXG5cdFx0XHRuZXdfdmFscyxcblx0XHRcdGxhc3RfbGluZV9wb3MsXG5cdFx0XHR0aGlzLmFkZF9hbmRfYW5pbWF0ZV95X2xpbmUuYmluZCh0aGlzKSxcblx0XHRcdHRoaXMueV9heGlzX2dyb3VwXG5cdFx0KTtcblx0fVxuXG5cdG1ha2VfYW5pbV95X3NwZWNpZmljcygpIHtcblx0XHR0aGlzLnNwZWNpZmljX3lfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLnNwZWNpZmljX3ZhbHVlcy5tYXAoKGQsIGkpID0+IHtcblx0XHRcdHRoaXMuYWRkX2FuZF9hbmltYXRlX3lfbGluZShcblx0XHRcdFx0ZC50aXRsZSxcblx0XHRcdFx0dGhpcy5vbGRfemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMub2xkX211bHRpcGxpZXIsXG5cdFx0XHRcdHRoaXMuemVyb19saW5lIC0gZC52YWx1ZSAqIHRoaXMubXVsdGlwbGllcixcblx0XHRcdFx0MCxcblx0XHRcdFx0dGhpcy5zcGVjaWZpY195X2dyb3VwLFxuXHRcdFx0XHRkLmxpbmVfdHlwZSxcblx0XHRcdFx0dHJ1ZVxuXHRcdFx0KTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfbmV3X2F4aXNfYW5pbV9saW5lcyhvbGRfcG9zLCBuZXdfcG9zLCBvbGRfdmFscywgbmV3X3ZhbHMsIGxhc3RfbGluZV9wb3MsIGFkZF9hbmRfYW5pbWF0ZV9saW5lLCBncm91cCkge1xuXHRcdGxldCBzdXBlcmltcG9zZWRfcG9zaXRpb25zLCBzdXBlcmltcG9zZWRfdmFsdWVzO1xuXHRcdGxldCBub19vZl9leHRyYXMgPSBuZXdfdmFscy5sZW5ndGggLSBvbGRfdmFscy5sZW5ndGg7XG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gTW9yZSBheGlzIGFyZSBuZWVkZWRcblx0XHRcdC8vIEZpcnN0IG1ha2Ugb25seSB0aGUgc3VwZXJpbXBvc2VkIChzYW1lIHBvc2l0aW9uKSBvbmVzXG5cdFx0XHQvLyBBZGQgaW4gdGhlIGV4dHJhcyBhdCB0aGUgZW5kIGxhdGVyXG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZSgwLCBvbGRfcG9zLmxlbmd0aCk7XG5cdFx0XHRzdXBlcmltcG9zZWRfdmFsdWVzID0gbmV3X3ZhbHMuc2xpY2UoMCwgb2xkX3ZhbHMubGVuZ3RoKTtcblx0XHR9IGVsc2Uge1xuXHRcdFx0Ly8gQXhpcyBoYXZlIHRvIGJlIHJlZHVjZWRcblx0XHRcdC8vIEZha2UgaXQgYnkgbW92aW5nIGFsbCBjdXJyZW50IGV4dHJhIGF4aXMgdG8gdGhlIGxhc3QgcG9zaXRpb25cblx0XHRcdC8vIFlvdSdsbCBuZWVkIGZpbGxlciBwb3NpdGlvbnMgYW5kIHZhbHVlcyBpbiB0aGUgbmV3IGFycmF5c1xuXHRcdFx0Y29uc3QgZmlsbGVyX3ZhbHMgPSBuZXcgQXJyYXkoTWF0aC5hYnMobm9fb2ZfZXh0cmFzKSkuZmlsbChcIlwiKTtcblx0XHRcdHN1cGVyaW1wb3NlZF92YWx1ZXMgPSBuZXdfdmFscy5jb25jYXQoZmlsbGVyX3ZhbHMpO1xuXG5cdFx0XHRjb25zdCBmaWxsZXJfcG9zID0gbmV3IEFycmF5KE1hdGguYWJzKG5vX29mX2V4dHJhcykpLmZpbGwobGFzdF9saW5lX3Bvcyk7XG5cdFx0XHRzdXBlcmltcG9zZWRfcG9zaXRpb25zID0gbmV3X3Bvcy5jb25jYXQoZmlsbGVyX3Bvcyk7XG5cdFx0fVxuXG5cdFx0c3VwZXJpbXBvc2VkX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRhZGRfYW5kX2FuaW1hdGVfbGluZSh2YWx1ZSwgb2xkX3Bvc1tpXSwgc3VwZXJpbXBvc2VkX3Bvc2l0aW9uc1tpXSwgaSwgZ3JvdXApO1xuXHRcdH0pO1xuXG5cdFx0aWYobm9fb2ZfZXh0cmFzID4gMCkge1xuXHRcdFx0Ly8gQWRkIGluIGV4dHJhIGF4aXMgaW4gdGhlIGVuZFxuXHRcdFx0Ly8gYW5kIHRoZW4gYW5pbWF0ZSB0byBuZXcgcG9zaXRpb25zXG5cdFx0XHRjb25zdCBleHRyYV92YWx1ZXMgPSBuZXdfdmFscy5zbGljZShvbGRfdmFscy5sZW5ndGgpO1xuXHRcdFx0Y29uc3QgZXh0cmFfcG9zaXRpb25zID0gbmV3X3Bvcy5zbGljZShvbGRfcG9zLmxlbmd0aCk7XG5cblx0XHRcdGV4dHJhX3ZhbHVlcy5tYXAoKHZhbHVlLCBpKSA9PiB7XG5cdFx0XHRcdGFkZF9hbmRfYW5pbWF0ZV9saW5lKHZhbHVlLCBsYXN0X2xpbmVfcG9zLCBleHRyYV9wb3NpdGlvbnNbaV0sIGksIGdyb3VwKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxuXG5cdG1ha2VfeF9saW5lKGhlaWdodCwgdGV4dF9zdGFydF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHhfcG9zKSB7XG5cdFx0bGV0IGFsbG93ZWRfc3BhY2UgPSB0aGlzLmF2Z191bml0X3dpZHRoICogMS41O1xuXG5cdFx0aWYodGhpcy5nZXRfc3Ryd2lkdGgocG9pbnQpID4gYWxsb3dlZF9zcGFjZSkge1xuXHRcdFx0bGV0IGFsbG93ZWRfbGV0dGVycyA9IGFsbG93ZWRfc3BhY2UgLyA4O1xuXHRcdFx0cG9pbnQgPSBwb2ludC5zbGljZSgwLCBhbGxvd2VkX2xldHRlcnMtMykgKyBcIiAuLi5cIjtcblx0XHR9XG5cblx0XHRsZXQgbGluZSA9ICQkLmNyZWF0ZVNWRygnbGluZScsIHtcblx0XHRcdHgxOiAwLFxuXHRcdFx0eDI6IDAsXG5cdFx0XHR5MTogMCxcblx0XHRcdHkyOiBoZWlnaHRcblx0XHR9KTtcblxuXHRcdGxldCB0ZXh0ID0gJCQuY3JlYXRlU1ZHKCd0ZXh0Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiBsYWJlbF9jbGFzcyxcblx0XHRcdHg6IDAsXG5cdFx0XHR5OiB0ZXh0X3N0YXJ0X2F0LFxuXHRcdFx0ZHk6ICcuNzFlbScsXG5cdFx0XHRpbm5lckhUTUw6IHBvaW50XG5cdFx0fSk7XG5cblx0XHRsZXQgeF9sZXZlbCA9ICQkLmNyZWF0ZVNWRygnZycsIHtcblx0XHRcdGNsYXNzTmFtZTogYHRpY2sgJHtheGlzX2xpbmVfY2xhc3N9YCxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgkeyB4X3BvcyB9LCAwKWBcblx0XHR9KTtcblxuXHRcdHhfbGV2ZWwuYXBwZW5kQ2hpbGQobGluZSk7XG5cdFx0eF9sZXZlbC5hcHBlbmRDaGlsZCh0ZXh0KTtcblxuXHRcdHJldHVybiB4X2xldmVsO1xuXHR9XG5cblx0bWFrZV95X2xpbmUoc3RhcnRfYXQsIHdpZHRoLCB0ZXh0X2VuZF9hdCwgcG9pbnQsIGxhYmVsX2NsYXNzLCBheGlzX2xpbmVfY2xhc3MsIHlfcG9zLCBkYXJrZXI9ZmFsc2UsIGxpbmVfdHlwZT1cIlwiKSB7XG5cdFx0bGV0IGxpbmUgPSAkJC5jcmVhdGVTVkcoJ2xpbmUnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGxpbmVfdHlwZSA9PT0gXCJkYXNoZWRcIiA/IFwiZGFzaGVkXCI6IFwiXCIsXG5cdFx0XHR4MTogc3RhcnRfYXQsXG5cdFx0XHR4Mjogd2lkdGgsXG5cdFx0XHR5MTogMCxcblx0XHRcdHkyOiAwXG5cdFx0fSk7XG5cblx0XHRsZXQgdGV4dCA9ICQkLmNyZWF0ZVNWRygndGV4dCcsIHtcblx0XHRcdGNsYXNzTmFtZTogbGFiZWxfY2xhc3MsXG5cdFx0XHR4OiB0ZXh0X2VuZF9hdCxcblx0XHRcdHk6IDAsXG5cdFx0XHRkeTogJy4zMmVtJyxcblx0XHRcdGlubmVySFRNTDogcG9pbnQrXCJcIlxuXHRcdH0pO1xuXG5cdFx0bGV0IHlfbGV2ZWwgPSAkJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRjbGFzc05hbWU6IGB0aWNrICR7YXhpc19saW5lX2NsYXNzfWAsXG5cdFx0XHR0cmFuc2Zvcm06IGB0cmFuc2xhdGUoMCwgJHt5X3Bvc30pYFxuXHRcdH0pO1xuXG5cdFx0aWYoZGFya2VyKSB7XG5cdFx0XHRsaW5lLnN0eWxlLnN0cm9rZSA9IFwicmdiYSgyNywgMzEsIDM1LCAwLjYpXCI7XG5cdFx0fVxuXG5cdFx0eV9sZXZlbC5hcHBlbmRDaGlsZChsaW5lKTtcblx0XHR5X2xldmVsLmFwcGVuZENoaWxkKHRleHQpO1xuXG5cdFx0cmV0dXJuIHlfbGV2ZWw7XG5cdH1cblxuXHRhZGRfYW5kX2FuaW1hdGVfeV9saW5lKHZhbHVlLCBvbGRfcG9zLCBuZXdfcG9zLCBpLCBncm91cCwgdHlwZSwgc3BlY2lmaWM9ZmFsc2UpIHtcblx0XHRsZXQgW3dpZHRoLCB0ZXh0X2VuZF9hdCwgYXhpc19saW5lX2NsYXNzLCBzdGFydF9hdF0gPSB0aGlzLmdldF95X2F4aXNfbGluZV9wcm9wcyhzcGVjaWZpYyk7XG5cdFx0bGV0IGF4aXNfbGFiZWxfY2xhc3MgPSAhc3BlY2lmaWMgPyAneS12YWx1ZS10ZXh0JyA6ICdzcGVjaWZpYy12YWx1ZSc7XG5cdFx0dmFsdWUgPSAhc3BlY2lmaWMgPyB2YWx1ZSA6ICh2YWx1ZStcIlwiKS50b1VwcGVyQ2FzZSgpO1xuXHRcdGNvbnN0IHlfbGluZSA9IHRoaXMubWFrZV95X2xpbmUoXG5cdFx0XHRzdGFydF9hdCxcblx0XHRcdHdpZHRoLFxuXHRcdFx0dGV4dF9lbmRfYXQsXG5cdFx0XHR2YWx1ZSxcblx0XHRcdGF4aXNfbGFiZWxfY2xhc3MsXG5cdFx0XHRheGlzX2xpbmVfY2xhc3MsXG5cdFx0XHRvbGRfcG9zLCAgLy8gb2xkIHBvc2l0aW9uXG5cdFx0XHQodmFsdWUgPT09IDAgJiYgaSAhPT0gMCksIC8vIE5vbi1maXJzdCBaZXJvIGxpbmVcblx0XHRcdHR5cGVcblx0XHQpO1xuXG5cdFx0Z3JvdXAuYXBwZW5kQ2hpbGQoeV9saW5lKTtcblxuXHRcdHRoaXMuZWxlbWVudHNfdG9fYW5pbWF0ZSAmJiB0aGlzLmVsZW1lbnRzX3RvX2FuaW1hdGUucHVzaChbXG5cdFx0XHR7dW5pdDogeV9saW5lLCBhcnJheTogWzBdLCBpbmRleDogMH0sXG5cdFx0XHR7dHJhbnNmb3JtOiBgMCwgJHsgbmV3X3BvcyB9YH0sXG5cdFx0XHQyNTAsXG5cdFx0XHRcImVhc2VpblwiLFxuXHRcdFx0XCJ0cmFuc2xhdGVcIixcblx0XHRcdHt0cmFuc2Zvcm06IGAwLCAkeyBvbGRfcG9zIH1gfVxuXHRcdF0pO1xuXHR9XG5cblx0Z2V0X3lfYXhpc19wb2ludHMoYXJyYXkpIHtcblx0XHQvLyoqKiBXaGVyZSB0aGUgbWFnaWMgaGFwcGVucyAqKipcblxuXHRcdC8vIENhbGN1bGF0ZXMgYmVzdC1maXQgeSBpbnRlcnZhbHMgZnJvbSBnaXZlbiB2YWx1ZXNcblx0XHQvLyBhbmQgcmV0dXJucyB0aGUgaW50ZXJ2YWwgYXJyYXlcblxuXHRcdC8vIFRPRE86IEZyYWN0aW9uc1xuXG5cdFx0bGV0IG1heF9ib3VuZCwgbWluX2JvdW5kLCBwb3Nfbm9fb2ZfcGFydHMsIG5lZ19ub19vZl9wYXJ0cywgcGFydF9zaXplO1xuXG5cdFx0Ly8gQ3JpdGljYWwgdmFsdWVzXG5cdFx0bGV0IG1heF92YWwgPSBwYXJzZUludChNYXRoLm1heCguLi5hcnJheSkpO1xuXHRcdGxldCBtaW5fdmFsID0gcGFyc2VJbnQoTWF0aC5taW4oLi4uYXJyYXkpKTtcblx0XHRpZihtaW5fdmFsID49IDApIHtcblx0XHRcdG1pbl92YWwgPSAwO1xuXHRcdH1cblxuXHRcdGxldCBnZXRfcGFyYW1zID0gKHZhbHVlMSwgdmFsdWUyKSA9PiB7XG5cdFx0XHRsZXQgYm91bmQxLCBib3VuZDIsIG5vX29mX3BhcnRzXzEsIG5vX29mX3BhcnRzXzIsIGludGVydmFsX3NpemU7XG5cdFx0XHRpZigodmFsdWUxK1wiXCIpLmxlbmd0aCA8PSAxKSB7XG5cdFx0XHRcdFtib3VuZDEsIG5vX29mX3BhcnRzXzFdID0gWzEwLCA1XTtcblx0XHRcdH0gZWxzZSB7XG5cdFx0XHRcdFtib3VuZDEsIG5vX29mX3BhcnRzXzFdID0gdGhpcy5jYWxjX3VwcGVyX2JvdW5kX2FuZF9ub19vZl9wYXJ0cyh2YWx1ZTEpO1xuXHRcdFx0fVxuXG5cdFx0XHRpbnRlcnZhbF9zaXplID0gYm91bmQxIC8gbm9fb2ZfcGFydHNfMTtcblx0XHRcdG5vX29mX3BhcnRzXzIgPSB0aGlzLmNhbGNfbm9fb2ZfcGFydHModmFsdWUyLCBpbnRlcnZhbF9zaXplKTtcblx0XHRcdGJvdW5kMiA9IG5vX29mX3BhcnRzXzIgKiBpbnRlcnZhbF9zaXplO1xuXG5cdFx0XHRyZXR1cm4gW2JvdW5kMSwgYm91bmQyLCBub19vZl9wYXJ0c18xLCBub19vZl9wYXJ0c18yLCBpbnRlcnZhbF9zaXplXTtcblx0XHR9XG5cblx0XHRjb25zdCBhYnNfbWluX3ZhbCA9IG1pbl92YWwgKiAtMTtcblx0XHRpZihhYnNfbWluX3ZhbCA8PSBtYXhfdmFsKSB7XG5cdFx0XHQvLyBHZXQgdGhlIHBvc2l0aXZlIHJlZ2lvbiBpbnRlcnZhbHNcblx0XHRcdC8vIHRoZW4gY2FsYyBuZWdhdGl2ZSBvbmVzIGFjY29yZGluZ2x5XG5cdFx0XHRbbWF4X2JvdW5kLCBtaW5fYm91bmQsIHBvc19ub19vZl9wYXJ0cywgbmVnX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhtYXhfdmFsLCBhYnNfbWluX3ZhbCk7XG5cdFx0XHRpZihhYnNfbWluX3ZhbCA9PT0gMCkge1xuXHRcdFx0XHRtaW5fYm91bmQgPSAwOyBuZWdfbm9fb2ZfcGFydHMgPSAwO1xuXHRcdFx0fVxuXHRcdH0gZWxzZSB7XG5cdFx0XHQvLyBHZXQgdGhlIG5lZ2F0aXZlIHJlZ2lvbiBoZXJlIGZpcnN0XG5cdFx0XHRbbWluX2JvdW5kLCBtYXhfYm91bmQsIG5lZ19ub19vZl9wYXJ0cywgcG9zX25vX29mX3BhcnRzLCBwYXJ0X3NpemVdXG5cdFx0XHRcdD0gZ2V0X3BhcmFtcyhhYnNfbWluX3ZhbCwgbWF4X3ZhbCk7XG5cdFx0fVxuXG5cdFx0Ly8gTWFrZSBib3RoIHJlZ2lvbiBwYXJ0cyBldmVuXG5cdFx0aWYocG9zX25vX29mX3BhcnRzICUgMiAhPT0gMCAmJiBuZWdfbm9fb2ZfcGFydHMgPiAwKSBwb3Nfbm9fb2ZfcGFydHMrKztcblx0XHRpZihuZWdfbm9fb2ZfcGFydHMgJSAyICE9PSAwKSB7XG5cdFx0XHQvLyBldmVyeSBpbmNyZWFzZSBpbiBub19vZl9wYXJ0cyBlbnRhaWxzIGFuIGluY3JlYXNlIGluIGNvcnJlc3BvbmRpbmcgYm91bmRcblx0XHRcdC8vIGV4Y2VwdCBoZXJlLCBpdCBoYXBwZW5zIGltcGxpY2l0bHkgYWZ0ZXIgZXZlcnkgY2FsY19ub19vZl9wYXJ0cygpIGNhbGxcblx0XHRcdG5lZ19ub19vZl9wYXJ0cysrO1xuXHRcdFx0bWluX2JvdW5kICs9IHBhcnRfc2l6ZTtcblx0XHR9XG5cblx0XHRsZXQgbm9fb2ZfcGFydHMgPSBwb3Nfbm9fb2ZfcGFydHMgKyBuZWdfbm9fb2ZfcGFydHM7XG5cdFx0aWYobm9fb2ZfcGFydHMgPiA1KSB7XG5cdFx0XHRub19vZl9wYXJ0cyAvPSAyO1xuXHRcdFx0cGFydF9zaXplICo9IDI7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIHRoaXMuZ2V0X2ludGVydmFscyhcblx0XHRcdCgtMSkgKiBtaW5fYm91bmQsXG5cdFx0XHRwYXJ0X3NpemUsXG5cdFx0XHRub19vZl9wYXJ0c1xuXHRcdCk7XG5cdH1cblxuXHRnZXRfaW50ZXJ2YWxzKHN0YXJ0LCBpbnRlcnZhbF9zaXplLCBjb3VudCkge1xuXHRcdGxldCBpbnRlcnZhbHMgPSBbXTtcblx0XHRmb3IodmFyIGkgPSAwOyBpIDw9IGNvdW50OyBpKyspe1xuXHRcdFx0aW50ZXJ2YWxzLnB1c2goc3RhcnQpO1xuXHRcdFx0c3RhcnQgKz0gaW50ZXJ2YWxfc2l6ZTtcblx0XHR9XG5cdFx0cmV0dXJuIGludGVydmFscztcblx0fVxuXG5cdGNhbGNfdXBwZXJfYm91bmRfYW5kX25vX29mX3BhcnRzKG1heF92YWwpIHtcblx0XHQvLyBHaXZlbiBhIHBvc2l0aXZlIHZhbHVlLCBjYWxjdWxhdGVzIGEgbmljZS1udW1iZXIgdXBwZXIgYm91bmRcblx0XHQvLyBhbmQgYSBjb25zZXF1ZW50IG9wdGltYWwgbnVtYmVyIG9mIHBhcnRzXG5cblx0XHRjb25zdCBwYXJ0X3NpemUgPSBNYXRoLnBvdygxMCwgKChtYXhfdmFsK1wiXCIpLmxlbmd0aCAtIDEpKTtcblx0XHRjb25zdCBub19vZl9wYXJ0cyA9IHRoaXMuY2FsY19ub19vZl9wYXJ0cyhtYXhfdmFsLCBwYXJ0X3NpemUpO1xuXG5cdFx0Ly8gVXNlIGl0IHRvIGdldCBhIG5pY2UgZXZlbiB1cHBlciBib3VuZFxuXHRcdGNvbnN0IHVwcGVyX2JvdW5kID0gcGFydF9zaXplICogbm9fb2ZfcGFydHM7XG5cblx0XHRyZXR1cm4gW3VwcGVyX2JvdW5kLCBub19vZl9wYXJ0c107XG5cdH1cblxuXHRjYWxjX25vX29mX3BhcnRzKHZhbHVlLCBkaXZpc29yKSB7XG5cdFx0Ly8gdmFsdWUgc2hvdWxkIGJlIGEgcG9zaXRpdmUgbnVtYmVyLCBkaXZpc29yIHNob3VsZCBiZSBncmVhdGVyIHRoYW4gMFxuXHRcdC8vIHJldHVybnMgYW4gZXZlbiBubyBvZiBwYXJ0c1xuXHRcdGxldCBub19vZl9wYXJ0cyA9IE1hdGguY2VpbCh2YWx1ZSAvIGRpdmlzb3IpO1xuXHRcdGlmKG5vX29mX3BhcnRzICUgMiAhPT0gMCkgbm9fb2ZfcGFydHMrKzsgLy8gTWFrZSBpdCBhbiBldmVuIG51bWJlclxuXG5cdFx0cmV0dXJuIG5vX29mX3BhcnRzO1xuXHR9XG5cblx0Z2V0X29wdGltYWxfbm9fb2ZfcGFydHMobm9fb2ZfcGFydHMpIHtcblx0XHQvLyBha2EgRGl2aWRlIGJ5IDIgaWYgdG9vIGxhcmdlXG5cdFx0cmV0dXJuIChub19vZl9wYXJ0cyA8IDUpID8gbm9fb2ZfcGFydHMgOiBub19vZl9wYXJ0cyAvIDI7XG5cdH1cblxuXHRzZXRfYXZnX3VuaXRfd2lkdGhfYW5kX3hfb2Zmc2V0KCkge1xuXHRcdC8vIFNldCB0aGUgLi4uIHlvdSBnZXQgaXRcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCAtIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSAwO1xuXHR9XG5cblx0Z2V0X2FsbF95X3ZhbHVlcygpIHtcblx0XHRsZXQgYWxsX3ZhbHVlcyA9IFtdO1xuXG5cdFx0Ly8gQWRkIGluIGFsbCB0aGUgeSB2YWx1ZXMgaW4gdGhlIGRhdGFzZXRzXG5cdFx0dGhpcy55Lm1hcChkID0+IHtcblx0XHRcdGFsbF92YWx1ZXMgPSBhbGxfdmFsdWVzLmNvbmNhdChkLnZhbHVlcyk7XG5cdFx0fSk7XG5cblx0XHQvLyBBZGQgaW4gYWxsIHRoZSBzcGVjaWZpYyB2YWx1ZXNcblx0XHRyZXR1cm4gYWxsX3ZhbHVlcy5jb25jYXQodGhpcy5zcGVjaWZpY192YWx1ZXMubWFwKGQgPT4gZC52YWx1ZSkpO1xuXHR9XG5cblx0Y2FsY195X2RlcGVuZGVuY2llcygpIHtcblx0XHR0aGlzLnlfbWluX3RvcHMgPSBuZXcgQXJyYXkodGhpcy54X2F4aXNfcG9zaXRpb25zLmxlbmd0aCkuZmlsbCg5OTk5KTtcblx0XHR0aGlzLnkubWFwKGQgPT4ge1xuXHRcdFx0ZC55X3RvcHMgPSBkLnZhbHVlcy5tYXAoIHZhbCA9PiAkJC5mbG9hdF8yKHRoaXMuemVyb19saW5lIC0gdmFsICogdGhpcy5tdWx0aXBsaWVyKSk7XG5cdFx0XHRkLnlfdG9wcy5tYXAoICh5X3RvcCwgaSkgPT4ge1xuXHRcdFx0XHRpZih5X3RvcCA8IHRoaXMueV9taW5fdG9wc1tpXSkge1xuXHRcdFx0XHRcdHRoaXMueV9taW5fdG9wc1tpXSA9IHlfdG9wO1xuXHRcdFx0XHR9XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdGdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIoeV90b3ApIHtcblx0XHRsZXQgaGVpZ2h0LCB5O1xuXHRcdGlmICh5X3RvcCA8PSB0aGlzLnplcm9fbGluZSkge1xuXHRcdFx0aGVpZ2h0ID0gdGhpcy56ZXJvX2xpbmUgLSB5X3RvcDtcblx0XHRcdHkgPSB5X3RvcDtcblxuXHRcdFx0Ly8gSW4gY2FzZSBvZiBpbnZpc2libGUgYmFyc1xuXHRcdFx0aWYoaGVpZ2h0ID09PSAwKSB7XG5cdFx0XHRcdGhlaWdodCA9IHRoaXMuaGVpZ2h0ICogMC4wMTtcblx0XHRcdFx0eSAtPSBoZWlnaHQ7XG5cdFx0XHR9XG5cdFx0fSBlbHNlIHtcblx0XHRcdGhlaWdodCA9IHlfdG9wIC0gdGhpcy56ZXJvX2xpbmU7XG5cdFx0XHR5ID0gdGhpcy56ZXJvX2xpbmU7XG5cblx0XHRcdC8vIEluIGNhc2Ugb2YgaW52aXNpYmxlIGJhcnNcblx0XHRcdGlmKGhlaWdodCA9PT0gMCkge1xuXHRcdFx0XHRoZWlnaHQgPSB0aGlzLmhlaWdodCAqIDAuMDE7XG5cdFx0XHR9XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtoZWlnaHQsIHldO1xuXHR9XG5cblx0c2V0dXBfdXRpbHMoKSB7XG5cdFx0dGhpcy5kcmF3ID0ge1xuXHRcdFx0J2Jhcic6ICh4LCB5X3RvcCwgYXJncywgY29sb3IsIGluZGV4LCBub19vZl9kYXRhc2V0cykgPT4ge1xuXHRcdFx0XHRsZXQgdG90YWxfd2lkdGggPSB0aGlzLmF2Z191bml0X3dpZHRoIC0gYXJncy5zcGFjZV93aWR0aDtcblx0XHRcdFx0bGV0IHN0YXJ0X3ggPSB4IC0gdG90YWxfd2lkdGgvMjtcblxuXHRcdFx0XHRsZXQgd2lkdGggPSB0b3RhbF93aWR0aCAvIG5vX29mX2RhdGFzZXRzO1xuXHRcdFx0XHRsZXQgY3VycmVudF94ID0gc3RhcnRfeCArIHdpZHRoICogaW5kZXg7XG5cblx0XHRcdFx0bGV0IFtoZWlnaHQsIHldID0gdGhpcy5nZXRfYmFyX2hlaWdodF9hbmRfeV9hdHRyKHlfdG9wKTtcblxuXHRcdFx0XHRyZXR1cm4gJCQuY3JlYXRlU1ZHKCdyZWN0Jywge1xuXHRcdFx0XHRcdGNsYXNzTmFtZTogYGJhciBtaW5pIGZpbGwgJHtjb2xvcn1gLFxuXHRcdFx0XHRcdHg6IGN1cnJlbnRfeCxcblx0XHRcdFx0XHR5OiB5LFxuXHRcdFx0XHRcdHdpZHRoOiB3aWR0aCxcblx0XHRcdFx0XHRoZWlnaHQ6IGhlaWdodFxuXHRcdFx0XHR9KTtcblxuXHRcdFx0fSxcblx0XHRcdCdkb3QnOiAoeCwgeSwgYXJncywgY29sb3IpID0+IHtcblx0XHRcdFx0cmV0dXJuICQkLmNyZWF0ZVNWRygnY2lyY2xlJywge1xuXHRcdFx0XHRcdGNsYXNzTmFtZTogYGZpbGwgJHtjb2xvcn1gLFxuXHRcdFx0XHRcdGN4OiB4LFxuXHRcdFx0XHRcdGN5OiB5LFxuXHRcdFx0XHRcdHI6IGFyZ3MucmFkaXVzXG5cdFx0XHRcdH0pO1xuXHRcdFx0fVxuXHRcdH07XG5cblx0XHR0aGlzLmFuaW1hdGUgPSB7XG5cdFx0XHQnYmFyJzogKGJhcl9vYmosIHgsIHlfdG9wLCBpbmRleCkgPT4ge1xuXHRcdFx0XHRsZXQgc3RhcnQgPSB4IC0gdGhpcy5hdmdfdW5pdF93aWR0aC80O1xuXHRcdFx0XHRsZXQgd2lkdGggPSAodGhpcy5hdmdfdW5pdF93aWR0aC8yKS90aGlzLnkubGVuZ3RoO1xuXHRcdFx0XHRsZXQgW2hlaWdodCwgeV0gPSB0aGlzLmdldF9iYXJfaGVpZ2h0X2FuZF95X2F0dHIoeV90b3ApO1xuXG5cdFx0XHRcdHggPSBzdGFydCArICh3aWR0aCAqIGluZGV4KTtcblxuXHRcdFx0XHRyZXR1cm4gW2Jhcl9vYmosIHt3aWR0aDogd2lkdGgsIGhlaWdodDogaGVpZ2h0LCB4OiB4LCB5OiB5fSwgMjUwLCBcImVhc2VpblwiXTtcblx0XHRcdFx0Ly8gYmFyLmFuaW1hdGUoe2hlaWdodDogYXJncy5uZXdfaGVpZ2h0LCB5OiB5X3RvcH0sIDI1MCwgbWluYS5lYXNlaW4pO1xuXHRcdFx0fSxcblx0XHRcdCdkb3QnOiAoZG90X29iaiwgeCwgeV90b3ApID0+IHtcblx0XHRcdFx0cmV0dXJuIFtkb3Rfb2JqLCB7Y3g6IHgsIGN5OiB5X3RvcH0sIDMwMCwgXCJlYXNlaW5cIl07XG5cdFx0XHRcdC8vIGRvdC5hbmltYXRlKHtjeTogeV90b3B9LCAyNTAsIG1pbmEuZWFzZWluKTtcblx0XHRcdH1cblx0XHR9O1xuXHR9XG59XG5cbmZyYXBwZS5jaGFydC5CYXJDaGFydCA9IGNsYXNzIEJhckNoYXJ0IGV4dGVuZHMgZnJhcHBlLmNoYXJ0LkF4aXNDaGFydCB7XG5cdGNvbnN0cnVjdG9yKGFyZ3MpIHtcblx0XHRzdXBlcihhcmdzKTtcblxuXHRcdHRoaXMudHlwZSA9ICdiYXInO1xuXHRcdHRoaXMueF9heGlzX21vZGUgPSBhcmdzLnhfYXhpc19tb2RlIHx8ICd0aWNrJztcblx0XHR0aGlzLnlfYXhpc19tb2RlID0gYXJncy55X2F4aXNfbW9kZSB8fCAnc3Bhbic7XG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0c2V0dXBfdmFsdWVzKCkge1xuXHRcdHN1cGVyLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHRcdHRoaXMudW5pdF9hcmdzID0ge1xuXHRcdFx0dHlwZTogJ2JhcicsXG5cdFx0XHRhcmdzOiB7XG5cdFx0XHRcdHNwYWNlX3dpZHRoOiB0aGlzLmF2Z191bml0X3dpZHRoLzIsXG5cdFx0XHR9XG5cdFx0fTtcblx0fVxuXG5cdG1ha2Vfb3ZlcmxheSgpIHtcblx0XHQvLyBKdXN0IG1ha2Ugb25lIG91dCBvZiB0aGUgZmlyc3QgZWxlbWVudFxuXHRcdGxldCBpbmRleCA9IHRoaXMueC5sZW5ndGggLSAxO1xuXHRcdGxldCB1bml0ID0gdGhpcy55WzBdLnN2Z191bml0c1tpbmRleF07XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KGluZGV4KTtcblxuXHRcdGlmKHRoaXMub3ZlcmxheSkge1xuXHRcdFx0dGhpcy5vdmVybGF5LnBhcmVudE5vZGUucmVtb3ZlQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0XHR9XG5cblx0XHR0aGlzLm92ZXJsYXkgPSB1bml0LmNsb25lTm9kZSgpO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5maWxsID0gJyMwMDAwMDAnO1xuXHRcdHRoaXMub3ZlcmxheS5zdHlsZS5vcGFjaXR5ID0gJzAuNCc7XG5cdFx0dGhpcy5kcmF3X2FyZWEuYXBwZW5kQ2hpbGQodGhpcy5vdmVybGF5KTtcblx0fVxuXG5cdGJpbmRfb3ZlcmxheSgpIHtcblx0XHQvLyBvbiBldmVudCwgdXBkYXRlIG92ZXJsYXlcblx0XHR0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdkYXRhLXNlbGVjdCcsIChlKSA9PiB7XG5cdFx0XHR0aGlzLnVwZGF0ZV9vdmVybGF5KGUuc3ZnX3VuaXQpO1xuXHRcdH0pO1xuXHR9XG5cblx0dXBkYXRlX292ZXJsYXkodW5pdCkge1xuXHRcdGxldCBhdHRyaWJ1dGVzID0gW107XG5cdFx0T2JqZWN0LmtleXModW5pdC5hdHRyaWJ1dGVzKS5tYXAoaW5kZXggPT4ge1xuXHRcdFx0YXR0cmlidXRlcy5wdXNoKHVuaXQuYXR0cmlidXRlc1tpbmRleF0pO1xuXHRcdH0pO1xuXG5cdFx0YXR0cmlidXRlcy5maWx0ZXIoYXR0ciA9PiBhdHRyLnNwZWNpZmllZCkubWFwKGF0dHIgPT4ge1xuXHRcdFx0dGhpcy5vdmVybGF5LnNldEF0dHJpYnV0ZShhdHRyLm5hbWUsIGF0dHIubm9kZVZhbHVlKTtcblx0XHR9KTtcblx0fVxuXG5cdG9uX2xlZnRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCAtIDEpO1xuXHR9XG5cblx0b25fcmlnaHRfYXJyb3coKSB7XG5cdFx0dGhpcy51cGRhdGVfY3VycmVudF9kYXRhX3BvaW50KHRoaXMuY3VycmVudF9pbmRleCArIDEpO1xuXHR9XG5cblx0c2V0X2F2Z191bml0X3dpZHRoX2FuZF94X29mZnNldCgpIHtcblx0XHR0aGlzLmF2Z191bml0X3dpZHRoID0gdGhpcy53aWR0aC8odGhpcy54Lmxlbmd0aCArIDEpO1xuXHRcdHRoaXMueF9vZmZzZXQgPSB0aGlzLmF2Z191bml0X3dpZHRoO1xuXHR9XG59XG5cbmZyYXBwZS5jaGFydC5MaW5lQ2hhcnQgPSBjbGFzcyBMaW5lQ2hhcnQgZXh0ZW5kcyBmcmFwcGUuY2hhcnQuQXhpc0NoYXJ0IHtcblx0Y29uc3RydWN0b3IoYXJncykge1xuXHRcdHN1cGVyKGFyZ3MpO1xuXHRcdGlmKE9iamVjdC5nZXRQcm90b3R5cGVPZih0aGlzKSAhPT0gZnJhcHBlLmNoYXJ0LkxpbmVDaGFydC5wcm90b3R5cGUpIHtcblx0XHRcdHJldHVybjtcblx0XHR9XG5cblx0XHR0aGlzLnR5cGUgPSAnbGluZSc7XG5cdFx0dGhpcy5yZWdpb25fZmlsbCA9IGFyZ3MucmVnaW9uX2ZpbGw7XG5cdFx0dGhpcy54X2F4aXNfbW9kZSA9IGFyZ3MueF9heGlzX21vZGUgfHwgJ3NwYW4nO1xuXHRcdHRoaXMueV9heGlzX21vZGUgPSBhcmdzLnlfYXhpc19tb2RlIHx8ICdzcGFuJztcblxuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdHNldHVwX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5zZXR1cF9wYXRoX2dyb3VwcygpO1xuXHRcdHN1cGVyLnNldHVwX2dyYXBoX2NvbXBvbmVudHMoKTtcblx0fVxuXG5cdHNldHVwX3BhdGhfZ3JvdXBzKCkge1xuXHRcdHRoaXMucGF0aHNfZ3JvdXBzID0gW107XG5cdFx0dGhpcy55Lm1hcCgoZCwgaSkgPT4ge1xuXHRcdFx0dGhpcy5wYXRoc19ncm91cHNbaV0gPSAkJC5jcmVhdGVTVkcoJ2cnLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogJ3BhdGgtZ3JvdXAgcGF0aC1ncm91cC0nICsgaSxcblx0XHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYVxuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0c3VwZXIuc2V0dXBfdmFsdWVzKCk7XG5cdFx0dGhpcy51bml0X2FyZ3MgPSB7XG5cdFx0XHR0eXBlOiAnZG90Jyxcblx0XHRcdGFyZ3M6IHsgcmFkaXVzOiA4IH1cblx0XHR9O1xuXHR9XG5cblx0bWFrZV9wYXRocygpIHtcblx0XHR0aGlzLnkubWFwKChkLCBpKSA9PiB7XG5cdFx0XHR0aGlzLm1ha2VfcGF0aChkLCBpLCB0aGlzLnhfYXhpc19wb3NpdGlvbnMsIGQueV90b3BzLCBkLmNvbG9yIHx8IHRoaXMuY29sb3JzW2ldKTtcblx0XHR9KTtcblx0fVxuXG5cdG1ha2VfcGF0aChkLCBpLCB4X3Bvc2l0aW9ucywgeV9wb3NpdGlvbnMsIGNvbG9yKSB7XG5cdFx0Ly8gbGV0IHBvaW50c19saXN0ID0geV9wb3NpdGlvbnMubWFwKCh5LCBpKSA9PiAoeF9wb3NpdGlvbnNbaV0gKyAnLCcgKyB5KSk7XG5cdFx0Ly8gbGV0IHBvaW50c19zdHIgPSBwb2ludHNfbGlzdC5qb2luKFwiTFwiKTtcblxuXHRcdC8vIHRoaXMucGF0aHNfZ3JvdXBzW2ldLnRleHRDb250ZW50ID0gJyc7XG5cblx0XHQvLyBkLnBhdGggPSAkJC5jcmVhdGVTVkcoJ3BhdGgnLCB7XG5cdFx0Ly8gXHRpbnNpZGU6IHRoaXMucGF0aHNfZ3JvdXBzW2ldLFxuXHRcdC8vIFx0Y2xhc3NOYW1lOiBgc3Ryb2tlICR7Y29sb3J9YCxcblx0XHQvLyBcdGQ6IFwiTVwiK3BvaW50c19zdHJcblx0XHQvLyB9KTtcblxuXHRcdC8vIGlmKHRoaXMucmVnaW9uX2ZpbGwpIHtcblx0XHQvLyBcdGxldCBncmFkaWVudF9pZCA9J3BhdGgtZmlsbC1ncmFkaWVudCcgKyAnLScgKyBjb2xvcjtcblxuXHRcdC8vIFx0dGhpcy5ncmFkaWVudF9kZWYgPSAkJC5jcmVhdGVTVkcoJ2xpbmVhckdyYWRpZW50Jywge1xuXHRcdC8vIFx0XHRpbnNpZGU6IHRoaXMuc3ZnX2RlZnMsXG5cdFx0Ly8gXHRcdGlkOiBncmFkaWVudF9pZCxcblx0XHQvLyBcdFx0eDE6IDAsXG5cdFx0Ly8gXHRcdHgyOiAwLFxuXHRcdC8vIFx0XHR5MTogMCxcblx0XHQvLyBcdFx0eTI6IDFcblx0XHQvLyBcdH0pO1xuXG5cdFx0Ly8gXHRmdW5jdGlvbiBzZXRfZ3JhZGllbnRfc3RvcChncmFkX2VsZW0sIG9mZnNldCwgY29sb3IsIG9wYWNpdHkpIHtcblx0XHQvLyBcdFx0JCQuY3JlYXRlU1ZHKCdzdG9wJywge1xuXHRcdC8vIFx0XHRcdCdjbGFzc05hbWUnOiAnc3RvcC1jb2xvciAnICsgY29sb3IsXG5cdFx0Ly8gXHRcdFx0J2luc2lkZSc6IGdyYWRfZWxlbSxcblx0XHQvLyBcdFx0XHQnb2Zmc2V0Jzogb2Zmc2V0LFxuXHRcdC8vIFx0XHRcdCdzdG9wLW9wYWNpdHknOiBvcGFjaXR5XG5cdFx0Ly8gXHRcdH0pO1xuXHRcdC8vIFx0fVxuXG5cdFx0Ly8gXHRzZXRfZ3JhZGllbnRfc3RvcCh0aGlzLmdyYWRpZW50X2RlZiwgXCIwJVwiLCBjb2xvciwgMC40KTtcblx0XHQvLyBcdHNldF9ncmFkaWVudF9zdG9wKHRoaXMuZ3JhZGllbnRfZGVmLCBcIjUwJVwiLCBjb2xvciwgMC4yKTtcblx0XHQvLyBcdHNldF9ncmFkaWVudF9zdG9wKHRoaXMuZ3JhZGllbnRfZGVmLCBcIjEwMCVcIiwgY29sb3IsIDApO1xuXG5cdFx0Ly8gXHRkLnJlZ2lvbl9wYXRoID0gJCQuY3JlYXRlU1ZHKCdwYXRoJywge1xuXHRcdC8vIFx0XHRpbnNpZGU6IHRoaXMucGF0aHNfZ3JvdXBzW2ldLFxuXHRcdC8vIFx0XHRjbGFzc05hbWU6IGByZWdpb24tZmlsbGAsXG5cdFx0Ly8gXHRcdGQ6IFwiTVwiICsgYDAsJHt0aGlzLnplcm9fbGluZX1MYCArIHBvaW50c19zdHIgKyBgTCR7dGhpcy53aWR0aH0sJHt0aGlzLnplcm9fbGluZX1gLFxuXHRcdC8vIFx0fSk7XG5cblx0XHQvLyBcdGQucmVnaW9uX3BhdGguc3R5bGUuc3Ryb2tlID0gXCJub25lXCI7XG5cdFx0Ly8gXHRkLnJlZ2lvbl9wYXRoLnN0eWxlLmZpbGwgPSBgdXJsKCMke2dyYWRpZW50X2lkfSlgO1xuXHRcdC8vIH1cblx0fVxufVxuXG5mcmFwcGUuY2hhcnQuUGVyY2VudGFnZUNoYXJ0ID0gY2xhc3MgUGVyY2VudGFnZUNoYXJ0IGV4dGVuZHMgZnJhcHBlLmNoYXJ0LkZyYXBwZUNoYXJ0IHtcblx0Y29uc3RydWN0b3IoYXJncykge1xuXHRcdHN1cGVyKGFyZ3MpO1xuXHRcdHRoaXMudHlwZSA9ICdwZXJjZW50YWdlJztcblxuXHRcdHRoaXMuZ2V0X3lfbGFiZWwgPSB0aGlzLmZvcm1hdF9sYW1iZGFzLnlfbGFiZWw7XG5cdFx0dGhpcy5nZXRfeF90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy54X3Rvb2x0aXA7XG5cdFx0dGhpcy5nZXRfeV90b29sdGlwID0gdGhpcy5mb3JtYXRfbGFtYmRhcy55X3Rvb2x0aXA7XG5cblx0XHR0aGlzLm1heF9zbGljZXMgPSAxMDtcblx0XHR0aGlzLm1heF9sZWdlbmRfcG9pbnRzID0gNjtcblxuXHRcdHRoaXMuY29sb3JzID0gYXJncy5jb2xvcnM7XG5cblx0XHRpZighdGhpcy5jb2xvcnMgfHwgdGhpcy5jb2xvcnMubGVuZ3RoIDwgdGhpcy5kYXRhLmxhYmVscy5sZW5ndGgpIHtcblx0XHRcdHRoaXMuY29sb3JzID0gWydsaWdodC1ibHVlJywgJ2JsdWUnLCAndmlvbGV0JywgJ3JlZCcsICdvcmFuZ2UnLFxuXHRcdFx0XHQneWVsbG93JywgJ2dyZWVuJywgJ2xpZ2h0LWdyZWVuJywgJ3B1cnBsZScsICdtYWdlbnRhJ107XG5cdFx0fVxuXG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0bWFrZV9jaGFydF9hcmVhKCkge1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5jbGFzc05hbWUgKz0gJyAnICsgJ2dyYXBoLWZvY3VzLW1hcmdpbic7XG5cdFx0dGhpcy5jaGFydF93cmFwcGVyLnN0eWxlLm1hcmdpblRvcCA9ICc0NXB4JztcblxuXHRcdHRoaXMuc3RhdHNfd3JhcHBlci5jbGFzc05hbWUgKz0gJyAnICsgJ2dyYXBoLWZvY3VzLW1hcmdpbic7XG5cdFx0dGhpcy5zdGF0c193cmFwcGVyLnN0eWxlLm1hcmdpbkJvdHRvbSA9ICczMHB4Jztcblx0XHR0aGlzLnN0YXRzX3dyYXBwZXIuc3R5bGUucGFkZGluZ1RvcCA9ICcwcHgnO1xuXHR9XG5cblx0bWFrZV9kcmF3X2FyZWEoKSB7XG5cdFx0dGhpcy5jaGFydF9kaXYgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ2RpdicsXG5cdFx0XHRpbnNpZGU6IHRoaXMuY2hhcnRfd3JhcHBlcixcblx0XHRcdHdpZHRoOiB0aGlzLmJhc2Vfd2lkdGgsXG5cdFx0XHRoZWlnaHQ6IHRoaXMuYmFzZV9oZWlnaHRcblx0XHR9KTtcblxuXHRcdHRoaXMuY2hhcnQgPSAkJC5jcmVhdGUoJ2RpdicsIHtcblx0XHRcdGNsYXNzTmFtZTogJ3Byb2dyZXNzLWNoYXJ0Jyxcblx0XHRcdGluc2lkZTogdGhpcy5jaGFydF9kaXZcblx0XHR9KTtcblx0fVxuXG5cdHNldHVwX2NvbXBvbmVudHMoKSB7XG5cdFx0dGhpcy5wZXJjZW50YWdlX2JhciA9ICQkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0Y2xhc3NOYW1lOiAncHJvZ3Jlc3MnLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmNoYXJ0XG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5zbGljZV90b3RhbHMgPSBbXTtcblx0XHRsZXQgYWxsX3RvdGFscyA9IHRoaXMuZGF0YS5sYWJlbHMubWFwKChkLCBpKSA9PiB7XG5cdFx0XHRsZXQgdG90YWwgPSAwO1xuXHRcdFx0dGhpcy5kYXRhLmRhdGFzZXRzLm1hcChlID0+IHtcblx0XHRcdFx0dG90YWwgKz0gZS52YWx1ZXNbaV07XG5cdFx0XHR9KTtcblx0XHRcdHJldHVybiBbdG90YWwsIGRdO1xuXHRcdH0pLmZpbHRlcihkID0+IHsgcmV0dXJuIGRbMF0gPiAwOyB9KTsgLy8ga2VlcCBvbmx5IHBvc2l0aXZlIHJlc3VsdHNcblxuXHRcdGxldCB0b3RhbHMgPSBhbGxfdG90YWxzO1xuXG5cdFx0aWYoYWxsX3RvdGFscy5sZW5ndGggPiB0aGlzLm1heF9zbGljZXMpIHtcblx0XHRcdGFsbF90b3RhbHMuc29ydCgoYSwgYikgPT4geyByZXR1cm4gYlswXSAtIGFbMF07IH0pO1xuXG5cdFx0XHR0b3RhbHMgPSBhbGxfdG90YWxzLnNsaWNlKDAsIHRoaXMubWF4X3NsaWNlcy0xKTtcblx0XHRcdGxldCBvdGhlcnMgPSBhbGxfdG90YWxzLnNsaWNlKHRoaXMubWF4X3NsaWNlcy0xKTtcblxuXHRcdFx0bGV0IHN1bV9vZl9vdGhlcnMgPSAwO1xuXHRcdFx0b3RoZXJzLm1hcChkID0+IHtzdW1fb2Zfb3RoZXJzICs9IGRbMF19KTtcblxuXHRcdFx0dG90YWxzLnB1c2goW3N1bV9vZl9vdGhlcnMsICdSZXN0J10pO1xuXG5cdFx0XHR0aGlzLmNvbG9yc1t0aGlzLm1heF9zbGljZXMtMV0gPSAnZ3JleSc7XG5cdFx0fVxuXG5cdFx0dGhpcy5sYWJlbHMgPSBbXTtcblx0XHR0b3RhbHMubWFwKGQgPT4ge1xuXHRcdFx0dGhpcy5zbGljZV90b3RhbHMucHVzaChkWzBdKTtcblx0XHRcdHRoaXMubGFiZWxzLnB1c2goZFsxXSk7XG5cdFx0fSk7XG5cblx0XHR0aGlzLmxlZ2VuZF90b3RhbHMgPSB0aGlzLnNsaWNlX3RvdGFscy5zbGljZSgwLCB0aGlzLm1heF9sZWdlbmRfcG9pbnRzKTtcblx0fVxuXG5cdHNldHVwX3V0aWxzKCkgeyB9XG5cblx0bWFrZV9ncmFwaF9jb21wb25lbnRzKCkge1xuXHRcdHRoaXMuZ3JhbmRfdG90YWwgPSB0aGlzLnNsaWNlX3RvdGFscy5yZWR1Y2UoKGEsIGIpID0+IGEgKyBiLCAwKTtcblx0XHR0aGlzLnNsaWNlcyA9IFtdO1xuXHRcdHRoaXMuc2xpY2VfdG90YWxzLm1hcCgodG90YWwsIGkpID0+IHtcblx0XHRcdGxldCBzbGljZSA9ICQkLmNyZWF0ZSgnZGl2Jywge1xuXHRcdFx0XHRjbGFzc05hbWU6IGBwcm9ncmVzcy1iYXIgYmFja2dyb3VuZCAke3RoaXMuY29sb3JzW2ldfWAsXG5cdFx0XHRcdHN0eWxlOiBgd2lkdGg6ICR7dG90YWwqMTAwL3RoaXMuZ3JhbmRfdG90YWx9JWAsXG5cdFx0XHRcdGluc2lkZTogdGhpcy5wZXJjZW50YWdlX2JhclxuXHRcdFx0fSk7XG5cdFx0XHR0aGlzLnNsaWNlcy5wdXNoKHNsaWNlKTtcblx0XHR9KTtcblx0fVxuXG5cdGJpbmRfdG9vbHRpcCgpIHtcblx0XHR0aGlzLnNsaWNlcy5tYXAoKHNsaWNlLCBpKSA9PiB7XG5cdFx0XHRzbGljZS5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgKCkgPT4ge1xuXHRcdFx0XHRsZXQgZ19vZmYgPSAkJC5vZmZzZXQodGhpcy5jaGFydF93cmFwcGVyKSwgcF9vZmYgPSAkJC5vZmZzZXQoc2xpY2UpO1xuXG5cdFx0XHRcdGxldCB4ID0gcF9vZmYubGVmdCAtIGdfb2ZmLmxlZnQgKyBzbGljZS5vZmZzZXRXaWR0aC8yO1xuXHRcdFx0XHRsZXQgeSA9IHBfb2ZmLnRvcCAtIGdfb2ZmLnRvcCAtIDY7XG5cdFx0XHRcdGxldCB0aXRsZSA9ICh0aGlzLmZvcm1hdHRlZF9sYWJlbHMgJiYgdGhpcy5mb3JtYXR0ZWRfbGFiZWxzLmxlbmd0aD4wXG5cdFx0XHRcdFx0PyB0aGlzLmZvcm1hdHRlZF9sYWJlbHNbaV0gOiB0aGlzLmxhYmVsc1tpXSkgKyAnOiAnO1xuXHRcdFx0XHRsZXQgcGVyY2VudCA9ICh0aGlzLnNsaWNlX3RvdGFsc1tpXSoxMDAvdGhpcy5ncmFuZF90b3RhbCkudG9GaXhlZCgxKTtcblxuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIHRpdGxlLCBwZXJjZW50ICsgXCIlXCIpO1xuXHRcdFx0XHR0aGlzLnRpcC5zaG93X3RpcCgpO1xuXHRcdFx0fSk7XG5cdFx0fSk7XG5cdH1cblxuXHRzaG93X3N1bW1hcnkoKSB7XG5cdFx0bGV0IHhfdmFsdWVzID0gdGhpcy5mb3JtYXR0ZWRfbGFiZWxzICYmIHRoaXMuZm9ybWF0dGVkX2xhYmVscy5sZW5ndGggPiAwXG5cdFx0XHQ/IHRoaXMuZm9ybWF0dGVkX2xhYmVscyA6IHRoaXMubGFiZWxzO1xuXHRcdHRoaXMubGVnZW5kX3RvdGFscy5tYXAoKGQsIGkpID0+IHtcblx0XHRcdGlmKGQpIHtcblx0XHRcdFx0bGV0IHN0YXRzID0gJCQuY3JlYXRlKCdkaXYnLCB7XG5cdFx0XHRcdFx0Y2xhc3NOYW1lOiAnc3RhdHMnLFxuXHRcdFx0XHRcdGluc2lkZTogdGhpcy5zdGF0c193cmFwcGVyXG5cdFx0XHRcdH0pO1xuXHRcdFx0XHRzdGF0cy5pbm5lckhUTUwgPSBgPHNwYW4gY2xhc3M9XCJpbmRpY2F0b3IgJHt0aGlzLmNvbG9yc1tpXX1cIj5cblx0XHRcdFx0XHQ8c3BhbiBjbGFzcz1cInRleHQtbXV0ZWRcIj4ke3hfdmFsdWVzW2ldfTo8L3NwYW4+XG5cdFx0XHRcdFx0JHtkfVxuXHRcdFx0XHQ8L3NwYW4+YDtcblx0XHRcdH1cblx0XHR9KTtcblx0fVxufVxuXG5mcmFwcGUuY2hhcnQuSGVhdE1hcCA9IGNsYXNzIEhlYXRNYXAgZXh0ZW5kcyBmcmFwcGUuY2hhcnQuRnJhcHBlQ2hhcnQge1xuXHRjb25zdHJ1Y3Rvcih7XG5cdFx0c3RhcnQgPSAnJyxcblx0XHRkb21haW4gPSAnJyxcblx0XHRzdWJkb21haW4gPSAnJyxcblx0XHRkYXRhID0ge30sXG5cdFx0ZGlzY3JldGVfZG9tYWlucyA9IDAsXG5cdFx0Y291bnRfbGFiZWwgPSAnJ1xuXHR9KSB7XG5cdFx0c3VwZXIoYXJndW1lbnRzWzBdKTtcblxuXHRcdHRoaXMudHlwZSA9ICdoZWF0bWFwJztcblxuXHRcdHRoaXMuZG9tYWluID0gZG9tYWluO1xuXHRcdHRoaXMuc3ViZG9tYWluID0gc3ViZG9tYWluO1xuXHRcdHRoaXMuZGF0YSA9IGRhdGE7XG5cdFx0dGhpcy5kaXNjcmV0ZV9kb21haW5zID0gZGlzY3JldGVfZG9tYWlucztcblx0XHR0aGlzLmNvdW50X2xhYmVsID0gY291bnRfbGFiZWw7XG5cblx0XHRsZXQgdG9kYXkgPSBuZXcgRGF0ZSgpO1xuXHRcdHRoaXMuc3RhcnQgPSBzdGFydCB8fCB0aGlzLmFkZF9kYXlzKHRvZGF5LCAzNjUpO1xuXG5cdFx0dGhpcy5sZWdlbmRfY29sb3JzID0gWycjZWJlZGYwJywgJyNjNmU0OGInLCAnIzdiYzk2ZicsICcjMjM5YTNiJywgJyMxOTYxMjcnXTtcblxuXHRcdHRoaXMudHJhbnNsYXRlX3ggPSAwO1xuXHRcdHRoaXMuc2V0dXAoKTtcblx0fVxuXG5cdHNldHVwX2Jhc2VfdmFsdWVzKCkge1xuXHRcdHRoaXMudG9kYXkgPSBuZXcgRGF0ZSgpO1xuXG5cdFx0aWYoIXRoaXMuc3RhcnQpIHtcblx0XHRcdHRoaXMuc3RhcnQgPSBuZXcgRGF0ZSgpO1xuXHRcdFx0dGhpcy5zdGFydC5zZXRGdWxsWWVhciggdGhpcy5zdGFydC5nZXRGdWxsWWVhcigpIC0gMSApO1xuXHRcdH1cblx0XHR0aGlzLmZpcnN0X3dlZWtfc3RhcnQgPSBuZXcgRGF0ZSh0aGlzLnN0YXJ0LnRvRGF0ZVN0cmluZygpKTtcblx0XHR0aGlzLmxhc3Rfd2Vla19zdGFydCA9IG5ldyBEYXRlKHRoaXMudG9kYXkudG9EYXRlU3RyaW5nKCkpO1xuXHRcdGlmKHRoaXMuZmlyc3Rfd2Vla19zdGFydC5nZXREYXkoKSAhPT0gNykge1xuXHRcdFx0dGhpcy5hZGRfZGF5cyh0aGlzLmZpcnN0X3dlZWtfc3RhcnQsICgtMSkgKiB0aGlzLmZpcnN0X3dlZWtfc3RhcnQuZ2V0RGF5KCkpO1xuXHRcdH1cblx0XHRpZih0aGlzLmxhc3Rfd2Vla19zdGFydC5nZXREYXkoKSAhPT0gNykge1xuXHRcdFx0dGhpcy5hZGRfZGF5cyh0aGlzLmxhc3Rfd2Vla19zdGFydCwgKC0xKSAqIHRoaXMubGFzdF93ZWVrX3N0YXJ0LmdldERheSgpKTtcblx0XHR9XG5cdFx0dGhpcy5ub19vZl9jb2xzID0gdGhpcy5nZXRfd2Vla3NfYmV0d2Vlbih0aGlzLmZpcnN0X3dlZWtfc3RhcnQgKyAnJywgdGhpcy5sYXN0X3dlZWtfc3RhcnQgKyAnJykgKyAxO1xuXHR9XG5cblx0c2V0X3dpZHRoKCkge1xuXHRcdHRoaXMuYmFzZV93aWR0aCA9ICh0aGlzLm5vX29mX2NvbHMpICogMTI7XG5cblx0XHRpZih0aGlzLmRpc2NyZXRlX2RvbWFpbnMpIHtcblx0XHRcdHRoaXMuYmFzZV93aWR0aCArPSAoMTIgKiAxMik7XG5cdFx0fVxuXHR9XG5cblx0c2V0dXBfY29tcG9uZW50cygpIHtcblx0XHR0aGlzLmRvbWFpbl9sYWJlbF9ncm91cCA9ICQkLmNyZWF0ZVNWRyhcImdcIiwge1xuXHRcdFx0Y2xhc3NOYW1lOiBcImRvbWFpbi1sYWJlbC1ncm91cCBjaGFydC1sYWJlbFwiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYVxuXHRcdH0pO1xuXHRcdHRoaXMuZGF0YV9ncm91cHMgPSAkJC5jcmVhdGVTVkcoXCJnXCIsIHtcblx0XHRcdGNsYXNzTmFtZTogXCJkYXRhLWdyb3Vwc1wiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRyYXdfYXJlYSxcblx0XHRcdHRyYW5zZm9ybTogYHRyYW5zbGF0ZSgwLCAyMClgXG5cdFx0fSk7XG5cdH1cblxuXHRzZXR1cF92YWx1ZXMoKSB7XG5cdFx0dGhpcy5kb21haW5fbGFiZWxfZ3JvdXAudGV4dENvbnRlbnQgPSAnJztcblx0XHR0aGlzLmRhdGFfZ3JvdXBzLnRleHRDb250ZW50ID0gJyc7XG5cdFx0dGhpcy5kaXN0cmlidXRpb24gPSB0aGlzLmdldF9kaXN0cmlidXRpb24odGhpcy5kYXRhLCB0aGlzLmxlZ2VuZF9jb2xvcnMpO1xuXHRcdHRoaXMubW9udGhfbmFtZXMgPSBbXCJKYW51YXJ5XCIsIFwiRmVicnVhcnlcIiwgXCJNYXJjaFwiLCBcIkFwcmlsXCIsIFwiTWF5XCIsIFwiSnVuZVwiLFxuXHRcdFx0XCJKdWx5XCIsIFwiQXVndXN0XCIsIFwiU2VwdGVtYmVyXCIsIFwiT2N0b2JlclwiLCBcIk5vdmVtYmVyXCIsIFwiRGVjZW1iZXJcIlxuXHRcdF07XG5cblx0XHR0aGlzLnJlbmRlcl9hbGxfd2Vla3NfYW5kX3N0b3JlX3hfdmFsdWVzKHRoaXMubm9fb2ZfY29scyk7XG5cdH1cblxuXHRyZW5kZXJfYWxsX3dlZWtzX2FuZF9zdG9yZV94X3ZhbHVlcyhub19vZl93ZWVrcykge1xuXHRcdGxldCBjdXJyZW50X3dlZWtfc3VuZGF5ID0gbmV3IERhdGUodGhpcy5maXJzdF93ZWVrX3N0YXJ0KTtcblx0XHR0aGlzLndlZWtfY29sID0gMDtcblx0XHR0aGlzLmN1cnJlbnRfbW9udGggPSBjdXJyZW50X3dlZWtfc3VuZGF5LmdldE1vbnRoKCk7XG5cblx0XHR0aGlzLm1vbnRocyA9IFt0aGlzLmN1cnJlbnRfbW9udGggKyAnJ107XG5cdFx0dGhpcy5tb250aF93ZWVrcyA9IHt9LCB0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cyA9IFtdO1xuXHRcdHRoaXMubW9udGhfd2Vla3NbdGhpcy5jdXJyZW50X21vbnRoXSA9IDA7XG5cdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucHVzaCgxMyk7XG5cblx0XHRmb3IodmFyIGkgPSAwOyBpIDwgbm9fb2Zfd2Vla3M7IGkrKykge1xuXHRcdFx0bGV0IGRhdGFfZ3JvdXAsIG1vbnRoX2NoYW5nZSA9IDA7XG5cdFx0XHRsZXQgZGF5ID0gbmV3IERhdGUoY3VycmVudF93ZWVrX3N1bmRheSk7XG5cblx0XHRcdFtkYXRhX2dyb3VwLCBtb250aF9jaGFuZ2VdID0gdGhpcy5nZXRfd2Vla19zcXVhcmVzX2dyb3VwKGRheSwgdGhpcy53ZWVrX2NvbCk7XG5cdFx0XHR0aGlzLmRhdGFfZ3JvdXBzLmFwcGVuZENoaWxkKGRhdGFfZ3JvdXApO1xuXHRcdFx0dGhpcy53ZWVrX2NvbCArPSAxICsgcGFyc2VJbnQodGhpcy5kaXNjcmV0ZV9kb21haW5zICYmIG1vbnRoX2NoYW5nZSk7XG5cdFx0XHR0aGlzLm1vbnRoX3dlZWtzW3RoaXMuY3VycmVudF9tb250aF0rKztcblx0XHRcdGlmKG1vbnRoX2NoYW5nZSkge1xuXHRcdFx0XHR0aGlzLmN1cnJlbnRfbW9udGggPSAodGhpcy5jdXJyZW50X21vbnRoICsgMSkgJSAxMjtcblx0XHRcdFx0dGhpcy5tb250aHMucHVzaCh0aGlzLmN1cnJlbnRfbW9udGggKyAnJyk7XG5cdFx0XHRcdHRoaXMubW9udGhfd2Vla3NbdGhpcy5jdXJyZW50X21vbnRoXSA9IDE7XG5cdFx0XHR9XG5cdFx0XHR0aGlzLmFkZF9kYXlzKGN1cnJlbnRfd2Vla19zdW5kYXksIDcpO1xuXHRcdH1cblx0XHR0aGlzLnJlbmRlcl9tb250aF9sYWJlbHMoKTtcblx0fVxuXG5cdGdldF93ZWVrX3NxdWFyZXNfZ3JvdXAoY3VycmVudF9kYXRlLCBpbmRleCkge1xuXHRcdGNvbnN0IG5vX29mX3dlZWtkYXlzID0gNztcblx0XHRjb25zdCBzcXVhcmVfc2lkZSA9IDEwO1xuXHRcdGNvbnN0IGNlbGxfcGFkZGluZyA9IDI7XG5cdFx0Y29uc3Qgc3RlcCA9IDE7XG5cblx0XHRsZXQgbW9udGhfY2hhbmdlID0gMDtcblx0XHRsZXQgd2Vla19jb2xfY2hhbmdlID0gMDtcblxuXHRcdGxldCBkYXRhX2dyb3VwID0gJCQuY3JlYXRlU1ZHKFwiZ1wiLCB7XG5cdFx0XHRjbGFzc05hbWU6IFwiZGF0YS1ncm91cFwiLFxuXHRcdFx0aW5zaWRlOiB0aGlzLmRhdGFfZ3JvdXBzXG5cdFx0fSk7XG5cblx0XHRmb3IodmFyIHkgPSAwLCBpID0gMDsgaSA8IG5vX29mX3dlZWtkYXlzOyBpICs9IHN0ZXAsIHkgKz0gKHNxdWFyZV9zaWRlICsgY2VsbF9wYWRkaW5nKSkge1xuXHRcdFx0bGV0IGRhdGFfdmFsdWUgPSAwO1xuXHRcdFx0bGV0IGNvbG9yX2luZGV4ID0gMDtcblxuXHRcdFx0bGV0IHRpbWVzdGFtcCA9IE1hdGguZmxvb3IoY3VycmVudF9kYXRlLmdldFRpbWUoKS8xMDAwKS50b0ZpeGVkKDEpO1xuXG5cdFx0XHRpZih0aGlzLmRhdGFbdGltZXN0YW1wXSkge1xuXHRcdFx0XHRkYXRhX3ZhbHVlID0gdGhpcy5kYXRhW3RpbWVzdGFtcF07XG5cdFx0XHRcdGNvbG9yX2luZGV4ID0gdGhpcy5nZXRfbWF4X2NoZWNrcG9pbnQoZGF0YV92YWx1ZSwgdGhpcy5kaXN0cmlidXRpb24pO1xuXHRcdFx0fVxuXG5cdFx0XHRpZih0aGlzLmRhdGFbTWF0aC5yb3VuZCh0aW1lc3RhbXApXSkge1xuXHRcdFx0XHRkYXRhX3ZhbHVlID0gdGhpcy5kYXRhW01hdGgucm91bmQodGltZXN0YW1wKV07XG5cdFx0XHRcdGNvbG9yX2luZGV4ID0gdGhpcy5nZXRfbWF4X2NoZWNrcG9pbnQoZGF0YV92YWx1ZSwgdGhpcy5kaXN0cmlidXRpb24pO1xuXHRcdFx0fVxuXG5cdFx0XHRsZXQgeCA9IDEzICsgKGluZGV4ICsgd2Vla19jb2xfY2hhbmdlKSAqIDEyO1xuXG5cdFx0XHQkJC5jcmVhdGVTVkcoXCJyZWN0XCIsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAnZGF5Jyxcblx0XHRcdFx0aW5zaWRlOiBkYXRhX2dyb3VwLFxuXHRcdFx0XHR4OiB4LFxuXHRcdFx0XHR5OiB5LFxuXHRcdFx0XHR3aWR0aDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGhlaWdodDogc3F1YXJlX3NpZGUsXG5cdFx0XHRcdGZpbGw6ICB0aGlzLmxlZ2VuZF9jb2xvcnNbY29sb3JfaW5kZXhdLFxuXHRcdFx0XHQnZGF0YS1kYXRlJzogdGhpcy5nZXRfZGRfbW1feXl5eShjdXJyZW50X2RhdGUpLFxuXHRcdFx0XHQnZGF0YS12YWx1ZSc6IGRhdGFfdmFsdWUsXG5cdFx0XHRcdCdkYXRhLWRheSc6IGN1cnJlbnRfZGF0ZS5nZXREYXkoKVxuXHRcdFx0fSk7XG5cblx0XHRcdGxldCBuZXh0X2RhdGUgPSBuZXcgRGF0ZShjdXJyZW50X2RhdGUpO1xuXHRcdFx0dGhpcy5hZGRfZGF5cyhuZXh0X2RhdGUsIDEpO1xuXHRcdFx0aWYobmV4dF9kYXRlLmdldE1vbnRoKCkgLSBjdXJyZW50X2RhdGUuZ2V0TW9udGgoKSkge1xuXHRcdFx0XHRtb250aF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHRpZih0aGlzLmRpc2NyZXRlX2RvbWFpbnMpIHtcblx0XHRcdFx0XHR3ZWVrX2NvbF9jaGFuZ2UgPSAxO1xuXHRcdFx0XHR9XG5cblx0XHRcdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucHVzaCgxMyArIChpbmRleCArIHdlZWtfY29sX2NoYW5nZSkgKiAxMik7XG5cdFx0XHR9XG5cdFx0XHRjdXJyZW50X2RhdGUgPSBuZXh0X2RhdGU7XG5cdFx0fVxuXG5cdFx0cmV0dXJuIFtkYXRhX2dyb3VwLCBtb250aF9jaGFuZ2VdO1xuXHR9XG5cblx0cmVuZGVyX21vbnRoX2xhYmVscygpIHtcblx0XHQvLyB0aGlzLmZpcnN0X21vbnRoX2xhYmVsID0gMTtcblx0XHQvLyBpZiAodGhpcy5maXJzdF93ZWVrX3N0YXJ0LmdldERhdGUoKSA+IDgpIHtcblx0XHQvLyBcdHRoaXMuZmlyc3RfbW9udGhfbGFiZWwgPSAwO1xuXHRcdC8vIH1cblx0XHQvLyB0aGlzLmxhc3RfbW9udGhfbGFiZWwgPSAxO1xuXG5cdFx0Ly8gbGV0IGZpcnN0X21vbnRoID0gdGhpcy5tb250aHMuc2hpZnQoKTtcblx0XHQvLyBsZXQgZmlyc3RfbW9udGhfc3RhcnQgPSB0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5zaGlmdCgpO1xuXHRcdC8vIHJlbmRlciBmaXJzdCBtb250aCBpZlxuXG5cdFx0Ly8gbGV0IGxhc3RfbW9udGggPSB0aGlzLm1vbnRocy5wb3AoKTtcblx0XHQvLyBsZXQgbGFzdF9tb250aF9zdGFydCA9IHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnBvcCgpO1xuXHRcdC8vIHJlbmRlciBsYXN0IG1vbnRoIGlmXG5cblx0XHR0aGlzLm1vbnRocy5zaGlmdCgpO1xuXHRcdHRoaXMubW9udGhfc3RhcnRfcG9pbnRzLnNoaWZ0KCk7XG5cdFx0dGhpcy5tb250aHMucG9wKCk7XG5cdFx0dGhpcy5tb250aF9zdGFydF9wb2ludHMucG9wKCk7XG5cblx0XHR0aGlzLm1vbnRoX3N0YXJ0X3BvaW50cy5tYXAoKHN0YXJ0LCBpKSA9PiB7XG5cdFx0XHRsZXQgbW9udGhfbmFtZSA9ICB0aGlzLm1vbnRoX25hbWVzW3RoaXMubW9udGhzW2ldXS5zdWJzdHJpbmcoMCwgMyk7XG5cblx0XHRcdCQkLmNyZWF0ZVNWRygndGV4dCcsIHtcblx0XHRcdFx0Y2xhc3NOYW1lOiAneS12YWx1ZS10ZXh0Jyxcblx0XHRcdFx0aW5zaWRlOiB0aGlzLmRvbWFpbl9sYWJlbF9ncm91cCxcblx0XHRcdFx0eDogc3RhcnQgKyAxMixcblx0XHRcdFx0eTogMTAsXG5cdFx0XHRcdGR5OiAnLjMyZW0nLFxuXHRcdFx0XHRpbm5lckhUTUw6IG1vbnRoX25hbWVcblx0XHRcdH0pO1xuXG5cdFx0fSk7XG5cdH1cblxuXHRtYWtlX2dyYXBoX2NvbXBvbmVudHMoKSB7XG5cdFx0QXJyYXkucHJvdG90eXBlLnNsaWNlLmNhbGwoXG5cdFx0XHR0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yQWxsKCcuZ3JhcGgtc3RhdHMtY29udGFpbmVyLCAuc3ViLXRpdGxlLCAudGl0bGUnKVxuXHRcdCkubWFwKGQgPT4ge1xuXHRcdFx0ZC5zdHlsZS5kaXNwbGF5ID0gJ05vbmUnO1xuXHRcdH0pO1xuXHRcdHRoaXMuY2hhcnRfd3JhcHBlci5zdHlsZS5tYXJnaW5Ub3AgPSAnMHB4Jztcblx0XHR0aGlzLmNoYXJ0X3dyYXBwZXIuc3R5bGUucGFkZGluZ1RvcCA9ICcwcHgnO1xuXHR9XG5cblx0YmluZF90b29sdGlwKCkge1xuXHRcdEFycmF5LnByb3RvdHlwZS5zbGljZS5jYWxsKFxuXHRcdFx0ZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbChcIi5kYXRhLWdyb3VwIC5kYXlcIilcblx0XHQpLm1hcChlbCA9PiB7XG5cdFx0XHRlbC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWVudGVyJywgKGUpID0+IHtcblx0XHRcdFx0bGV0IGNvdW50ID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLXZhbHVlJyk7XG5cdFx0XHRcdGxldCBkYXRlX3BhcnRzID0gZS50YXJnZXQuZ2V0QXR0cmlidXRlKCdkYXRhLWRhdGUnKS5zcGxpdCgnLScpO1xuXG5cdFx0XHRcdGxldCBtb250aCA9IHRoaXMubW9udGhfbmFtZXNbcGFyc2VJbnQoZGF0ZV9wYXJ0c1sxXSktMV0uc3Vic3RyaW5nKDAsIDMpO1xuXG5cdFx0XHRcdGxldCBnX29mZiA9IHRoaXMuY2hhcnRfd3JhcHBlci5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKSwgcF9vZmYgPSBlLnRhcmdldC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuXHRcdFx0XHRsZXQgd2lkdGggPSBwYXJzZUludChlLnRhcmdldC5nZXRBdHRyaWJ1dGUoJ3dpZHRoJykpO1xuXHRcdFx0XHRsZXQgeCA9IHBfb2ZmLmxlZnQgLSBnX29mZi5sZWZ0ICsgKHdpZHRoKzIpLzI7XG5cdFx0XHRcdGxldCB5ID0gcF9vZmYudG9wIC0gZ19vZmYudG9wIC0gKHdpZHRoKzIpLzI7XG5cdFx0XHRcdGxldCB2YWx1ZSA9IGNvdW50ICsgJyAnICsgdGhpcy5jb3VudF9sYWJlbDtcblx0XHRcdFx0bGV0IG5hbWUgPSAnIG9uICcgKyBtb250aCArICcgJyArIGRhdGVfcGFydHNbMF0gKyAnLCAnICsgZGF0ZV9wYXJ0c1syXTtcblxuXHRcdFx0XHR0aGlzLnRpcC5zZXRfdmFsdWVzKHgsIHksIG5hbWUsIHZhbHVlLCBbXSwgMSk7XG5cdFx0XHRcdHRoaXMudGlwLnNob3dfdGlwKCk7XG5cdFx0XHR9KTtcblx0XHR9KTtcblx0fVxuXG5cdHVwZGF0ZShkYXRhKSB7XG5cdFx0dGhpcy5kYXRhID0gZGF0YTtcblx0XHR0aGlzLnNldHVwX3ZhbHVlcygpO1xuXHRcdHRoaXMuYmluZF90b29sdGlwKCk7XG5cdH1cblxuXHRnZXRfZGlzdHJpYnV0aW9uKGRhdGE9e30sIG1hcHBlcl9hcnJheSkge1xuXHRcdGxldCBkYXRhX3ZhbHVlcyA9IE9iamVjdC5rZXlzKGRhdGEpLm1hcChrZXkgPT4gZGF0YVtrZXldKTtcblx0XHRsZXQgZGF0YV9tYXhfdmFsdWUgPSBNYXRoLm1heCguLi5kYXRhX3ZhbHVlcyk7XG5cblx0XHRsZXQgZGlzdHJpYnV0aW9uX3N0ZXAgPSAxIC8gKG1hcHBlcl9hcnJheS5sZW5ndGggLSAxKTtcblx0XHRsZXQgZGlzdHJpYnV0aW9uID0gW107XG5cblx0XHRtYXBwZXJfYXJyYXkubWFwKChjb2xvciwgaSkgPT4ge1xuXHRcdFx0bGV0IGNoZWNrcG9pbnQgPSBkYXRhX21heF92YWx1ZSAqIChkaXN0cmlidXRpb25fc3RlcCAqIGkpO1xuXHRcdFx0ZGlzdHJpYnV0aW9uLnB1c2goY2hlY2twb2ludCk7XG5cdFx0fSk7XG5cblx0XHRyZXR1cm4gZGlzdHJpYnV0aW9uO1xuXHR9XG5cblx0Z2V0X21heF9jaGVja3BvaW50KHZhbHVlLCBkaXN0cmlidXRpb24pIHtcblx0XHRyZXR1cm4gZGlzdHJpYnV0aW9uLmZpbHRlcigoZCwgaSkgPT4ge1xuXHRcdFx0aWYoaSA9PT0gMSkge1xuXHRcdFx0XHRyZXR1cm4gZGlzdHJpYnV0aW9uWzBdIDwgdmFsdWU7XG5cdFx0XHR9XG5cdFx0XHRyZXR1cm4gZCA8PSB2YWx1ZTtcblx0XHR9KS5sZW5ndGggLSAxO1xuXHR9XG5cblx0Ly8gVE9ETzogZGF0ZSB1dGlscywgbW92ZSB0aGVzZSBvdXRcblxuXHQvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMTEyNTIxNjcvNjQ5NTA0M1xuXHR0cmVhdF9hc191dGMoZGF0ZV9zdHIpIHtcblx0XHRsZXQgcmVzdWx0ID0gbmV3IERhdGUoZGF0ZV9zdHIpO1xuXHRcdHJlc3VsdC5zZXRNaW51dGVzKHJlc3VsdC5nZXRNaW51dGVzKCkgLSByZXN1bHQuZ2V0VGltZXpvbmVPZmZzZXQoKSk7XG5cdFx0cmV0dXJuIHJlc3VsdDtcblx0fVxuXG5cdGdldF9kZF9tbV95eXl5KGRhdGUpIHtcblx0XHRsZXQgZGQgPSBkYXRlLmdldERhdGUoKTtcblx0XHRsZXQgbW0gPSBkYXRlLmdldE1vbnRoKCkgKyAxOyAvLyBnZXRNb250aCgpIGlzIHplcm8tYmFzZWRcblx0XHRyZXR1cm4gW1xuXHRcdFx0KGRkPjkgPyAnJyA6ICcwJykgKyBkZCxcblx0XHRcdChtbT45ID8gJycgOiAnMCcpICsgbW0sXG5cdFx0XHRkYXRlLmdldEZ1bGxZZWFyKClcblx0XHRdLmpvaW4oJy0nKTtcblx0fVxuXG5cdGdldF93ZWVrc19iZXR3ZWVuKHN0YXJ0X2RhdGVfc3RyLCBlbmRfZGF0ZV9zdHIpIHtcblx0XHRyZXR1cm4gTWF0aC5jZWlsKHRoaXMuZ2V0X2RheXNfYmV0d2VlbihzdGFydF9kYXRlX3N0ciwgZW5kX2RhdGVfc3RyKSAvIDcpO1xuXHR9XG5cblx0Z2V0X2RheXNfYmV0d2VlbihzdGFydF9kYXRlX3N0ciwgZW5kX2RhdGVfc3RyKSB7XG5cdFx0bGV0IG1pbGxpc2Vjb25kc19wZXJfZGF5ID0gMjQgKiA2MCAqIDYwICogMTAwMDtcblx0XHRyZXR1cm4gKHRoaXMudHJlYXRfYXNfdXRjKGVuZF9kYXRlX3N0cikgLSB0aGlzLnRyZWF0X2FzX3V0YyhzdGFydF9kYXRlX3N0cikpIC8gbWlsbGlzZWNvbmRzX3Blcl9kYXk7XG5cdH1cblxuXHQvLyBtdXRhdGVzXG5cdGFkZF9kYXlzKGRhdGUsIG51bWJlcl9vZl9kYXlzKSB7XG5cdFx0ZGF0ZS5zZXREYXRlKGRhdGUuZ2V0RGF0ZSgpICsgbnVtYmVyX29mX2RheXMpO1xuXHR9XG5cblx0Z2V0X21vbnRoX25hbWUoKSB7fVxufVxuXG5mcmFwcGUuY2hhcnQuU3ZnVGlwID0gY2xhc3Mge1xuXHRjb25zdHJ1Y3Rvcih7XG5cdFx0cGFyZW50ID0gbnVsbFxuXHR9KSB7XG5cdFx0dGhpcy5wYXJlbnQgPSBwYXJlbnQ7XG5cdFx0dGhpcy50aXRsZV9uYW1lID0gJyc7XG5cdFx0dGhpcy50aXRsZV92YWx1ZSA9ICcnO1xuXHRcdHRoaXMubGlzdF92YWx1ZXMgPSBbXTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlX2ZpcnN0ID0gMDtcblxuXHRcdHRoaXMueCA9IDA7XG5cdFx0dGhpcy55ID0gMDtcblxuXHRcdHRoaXMudG9wID0gMDtcblx0XHR0aGlzLmxlZnQgPSAwO1xuXG5cdFx0dGhpcy5zZXR1cCgpO1xuXHR9XG5cblx0c2V0dXAoKSB7XG5cdFx0dGhpcy5tYWtlX3Rvb2x0aXAoKTtcblx0fVxuXG5cdHJlZnJlc2goKSB7XG5cdFx0dGhpcy5maWxsKCk7XG5cdFx0dGhpcy5jYWxjX3Bvc2l0aW9uKCk7XG5cdFx0Ly8gdGhpcy5zaG93X3RpcCgpO1xuXHR9XG5cblx0bWFrZV90b29sdGlwKCkge1xuXHRcdHRoaXMuY29udGFpbmVyID0gJCQuY3JlYXRlKCdkaXYnLCB7XG5cdFx0XHRpbnNpZGU6IHRoaXMucGFyZW50LFxuXHRcdFx0Y2xhc3NOYW1lOiAnZ3JhcGgtc3ZnLXRpcCBjb21wYXJpc29uJyxcblx0XHRcdGlubmVySFRNTDogYDxzcGFuIGNsYXNzPVwidGl0bGVcIj48L3NwYW4+XG5cdFx0XHRcdDx1bCBjbGFzcz1cImRhdGEtcG9pbnQtbGlzdFwiPjwvdWw+XG5cdFx0XHRcdDxkaXYgY2xhc3M9XCJzdmctcG9pbnRlclwiPjwvZGl2PmBcblx0XHR9KTtcblx0XHR0aGlzLmhpZGVfdGlwKCk7XG5cblx0XHR0aGlzLnRpdGxlID0gdGhpcy5jb250YWluZXIucXVlcnlTZWxlY3RvcignLnRpdGxlJyk7XG5cdFx0dGhpcy5kYXRhX3BvaW50X2xpc3QgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuZGF0YS1wb2ludC1saXN0Jyk7XG5cblx0XHR0aGlzLnBhcmVudC5hZGRFdmVudExpc3RlbmVyKCdtb3VzZWxlYXZlJywgKCkgPT4ge1xuXHRcdFx0dGhpcy5oaWRlX3RpcCgpO1xuXHRcdH0pO1xuXHR9XG5cblx0ZmlsbCgpIHtcblx0XHRsZXQgdGl0bGU7XG5cdFx0aWYodGhpcy50aXRsZV92YWx1ZV9maXJzdCkge1xuXHRcdFx0dGl0bGUgPSBgPHN0cm9uZz4ke3RoaXMudGl0bGVfdmFsdWV9PC9zdHJvbmc+JHt0aGlzLnRpdGxlX25hbWV9YDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0dGl0bGUgPSBgJHt0aGlzLnRpdGxlX25hbWV9PHN0cm9uZz4ke3RoaXMudGl0bGVfdmFsdWV9PC9zdHJvbmc+YDtcblx0XHR9XG5cdFx0dGhpcy50aXRsZS5pbm5lckhUTUwgPSB0aXRsZTtcblx0XHR0aGlzLmRhdGFfcG9pbnRfbGlzdC5pbm5lckhUTUwgPSAnJztcblxuXHRcdHRoaXMubGlzdF92YWx1ZXMubWFwKChzZXQpID0+IHtcblx0XHRcdGxldCBsaSA9ICQkLmNyZWF0ZSgnbGknLCB7XG5cdFx0XHRcdGNsYXNzTmFtZTogYGJvcmRlci10b3AgJHtzZXQuY29sb3IgfHwgJ2JsYWNrJ31gLFxuXHRcdFx0XHRpbm5lckhUTUw6IGA8c3Ryb25nIHN0eWxlPVwiZGlzcGxheTogYmxvY2s7XCI+JHtzZXQudmFsdWUgPyBzZXQudmFsdWUgOiAnJyB9PC9zdHJvbmc+XG5cdFx0XHRcdFx0JHtzZXQudGl0bGUgPyBzZXQudGl0bGUgOiAnJyB9YFxuXHRcdFx0fSk7XG5cblx0XHRcdHRoaXMuZGF0YV9wb2ludF9saXN0LmFwcGVuZENoaWxkKGxpKTtcblx0XHR9KTtcblx0fVxuXG5cdGNhbGNfcG9zaXRpb24oKSB7XG5cdFx0dGhpcy50b3AgPSB0aGlzLnkgLSB0aGlzLmNvbnRhaW5lci5vZmZzZXRIZWlnaHQ7XG5cdFx0dGhpcy5sZWZ0ID0gdGhpcy54IC0gdGhpcy5jb250YWluZXIub2Zmc2V0V2lkdGgvMjtcblx0XHRsZXQgbWF4X2xlZnQgPSB0aGlzLnBhcmVudC5vZmZzZXRXaWR0aCAtIHRoaXMuY29udGFpbmVyLm9mZnNldFdpZHRoO1xuXG5cdFx0bGV0IHBvaW50ZXIgPSB0aGlzLmNvbnRhaW5lci5xdWVyeVNlbGVjdG9yKCcuc3ZnLXBvaW50ZXInKTtcblxuXHRcdGlmKHRoaXMubGVmdCA8IDApIHtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSAtICR7LTEgKiB0aGlzLmxlZnR9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IDA7XG5cdFx0fSBlbHNlIGlmKHRoaXMubGVmdCA+IG1heF9sZWZ0KSB7XG5cdFx0XHRsZXQgZGVsdGEgPSB0aGlzLmxlZnQgLSBtYXhfbGVmdDtcblx0XHRcdHBvaW50ZXIuc3R5bGUubGVmdCA9IGBjYWxjKDUwJSArICR7ZGVsdGF9cHgpYDtcblx0XHRcdHRoaXMubGVmdCA9IG1heF9sZWZ0O1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRwb2ludGVyLnN0eWxlLmxlZnQgPSBgNTAlYDtcblx0XHR9XG5cdH1cblxuXHRzZXRfdmFsdWVzKHgsIHksIHRpdGxlX25hbWUgPSAnJywgdGl0bGVfdmFsdWUgPSAnJywgbGlzdF92YWx1ZXMgPSBbXSwgdGl0bGVfdmFsdWVfZmlyc3QgPSAwKSB7XG5cdFx0dGhpcy50aXRsZV9uYW1lID0gdGl0bGVfbmFtZTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlID0gdGl0bGVfdmFsdWU7XG5cdFx0dGhpcy5saXN0X3ZhbHVlcyA9IGxpc3RfdmFsdWVzO1xuXHRcdHRoaXMueCA9IHg7XG5cdFx0dGhpcy55ID0geTtcblx0XHR0aGlzLnRpdGxlX3ZhbHVlX2ZpcnN0ID0gdGl0bGVfdmFsdWVfZmlyc3Q7XG5cdFx0dGhpcy5yZWZyZXNoKCk7XG5cdH1cblxuXHRoaWRlX3RpcCgpIHtcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS50b3AgPSAnMHB4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gJzBweCc7XG5cdFx0dGhpcy5jb250YWluZXIuc3R5bGUub3BhY2l0eSA9ICcwJztcblx0fVxuXG5cdHNob3dfdGlwKCkge1xuXHRcdHRoaXMuY29udGFpbmVyLnN0eWxlLnRvcCA9IHRoaXMudG9wICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5sZWZ0ID0gdGhpcy5sZWZ0ICsgJ3B4Jztcblx0XHR0aGlzLmNvbnRhaW5lci5zdHlsZS5vcGFjaXR5ID0gJzEnO1xuXHR9XG59XG5cbi8vIEhlbHBlcnNcbmZyYXBwZS5jaGFydC51dGlscyA9IHt9O1xuJCQuZmxvYXRfMiA9IGQgPT4gcGFyc2VGbG9hdChkLnRvRml4ZWQoMikpO1xuZnVuY3Rpb24gJCQoZXhwciwgY29uKSB7XG5cdHJldHVybiB0eXBlb2YgZXhwciA9PT0gXCJzdHJpbmdcIj8gKGNvbiB8fCBkb2N1bWVudCkucXVlcnlTZWxlY3RvcihleHByKSA6IGV4cHIgfHwgbnVsbDtcbn1cblxuJCQuYXJyYXlzX2VxdWFsID0gKGFycjEsIGFycjIpID0+IHtcblx0aWYoYXJyMS5sZW5ndGggIT09IGFycjIubGVuZ3RoKSByZXR1cm4gZmFsc2U7XG5cdGxldCBhcmVfZXF1YWwgPSB0cnVlO1xuXHRhcnIxLm1hcCgoZCwgaSkgPT4ge1xuXHRcdGlmKGFycjJbaV0gIT09IGQpIGFyZV9lcXVhbCA9IGZhbHNlO1xuXHR9KTtcblx0cmV0dXJuIGFyZV9lcXVhbDtcbn1cblxuJCQuc2h1ZmZsZSA9IChhcnJheSkgPT4ge1xuXHQvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvMjQ1MDk3Ni82NDk1MDQzXG5cdC8vIEF3ZXNvbWVuZXNzOiBodHRwczovL2Jvc3Qub2Nrcy5vcmcvbWlrZS9zaHVmZmxlL1xuXG5cdHZhciBjdXJyZW50SW5kZXggPSBhcnJheS5sZW5ndGgsIHRlbXBvcmFyeVZhbHVlLCByYW5kb21JbmRleDtcblxuXHQvLyBXaGlsZSB0aGVyZSByZW1haW4gZWxlbWVudHMgdG8gc2h1ZmZsZS4uLlxuXHR3aGlsZSAoMCAhPT0gY3VycmVudEluZGV4KSB7XG5cblx0XHQvLyBQaWNrIGEgcmVtYWluaW5nIGVsZW1lbnQuLi5cblx0XHRyYW5kb21JbmRleCA9IE1hdGguZmxvb3IoTWF0aC5yYW5kb20oKSAqIGN1cnJlbnRJbmRleCk7XG5cdFx0Y3VycmVudEluZGV4IC09IDE7XG5cblx0XHQvLyBBbmQgc3dhcCBpdCB3aXRoIHRoZSBjdXJyZW50IGVsZW1lbnQuXG5cdFx0dGVtcG9yYXJ5VmFsdWUgPSBhcnJheVtjdXJyZW50SW5kZXhdO1xuXHRcdGFycmF5W2N1cnJlbnRJbmRleF0gPSBhcnJheVtyYW5kb21JbmRleF07XG5cdFx0YXJyYXlbcmFuZG9tSW5kZXhdID0gdGVtcG9yYXJ5VmFsdWU7XG5cdH1cblxuXHRyZXR1cm4gYXJyYXk7XG5cbn1cblxuLy8gJCQuZmluZE5vZGVJbmRleCA9IChub2RlKSA9PlxuLy8ge1xuLy8gXHR2YXIgaSA9IDA7XG4vLyBcdHdoaWxlIChub2RlID0gbm9kZS5wcmV2aW91c1NpYmxpbmcpIHtcbi8vIFx0XHRpZiAobm9kZS5ub2RlVHlwZSA9PT0gMSkgeyArK2k7IH1cbi8vIFx0fVxuLy8gXHRyZXR1cm4gaTtcbi8vIH1cblxuJCQuY3JlYXRlID0gZnVuY3Rpb24odGFnLCBvKSB7XG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudCh0YWcpO1xuXG5cdGZvciAodmFyIGkgaW4gbykge1xuXHRcdHZhciB2YWwgPSBvW2ldO1xuXG5cdFx0aWYgKGkgPT09IFwiaW5zaWRlXCIpIHtcblx0XHRcdCQkKHZhbCkuYXBwZW5kQ2hpbGQoZWxlbWVudCk7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKGkgPT09IFwiYXJvdW5kXCIpIHtcblx0XHRcdHZhciByZWYgPSAkJCh2YWwpO1xuXHRcdFx0cmVmLnBhcmVudE5vZGUuaW5zZXJ0QmVmb3JlKGVsZW1lbnQsIHJlZik7XG5cdFx0XHRlbGVtZW50LmFwcGVuZENoaWxkKHJlZik7XG5cdFx0fVxuXHRcdGVsc2UgaWYgKGkgaW4gZWxlbWVudCkge1xuXHRcdFx0ZWxlbWVudFtpXSA9IHZhbDtcblx0XHR9XG5cdFx0ZWxzZSB7XG5cdFx0XHRlbGVtZW50LnNldEF0dHJpYnV0ZShpLCB2YWwpO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBlbGVtZW50O1xufTtcblxuJCQuY3JlYXRlU1ZHID0gZnVuY3Rpb24odGFnLCBvKSB7XG5cdHZhciBlbGVtZW50ID0gZG9jdW1lbnQuY3JlYXRlRWxlbWVudE5TKFwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiwgdGFnKTtcblxuXHRmb3IgKHZhciBpIGluIG8pIHtcblx0XHR2YXIgdmFsID0gb1tpXTtcblxuXHRcdGlmIChpID09PSBcImluc2lkZVwiKSB7XG5cdFx0XHQkJCh2YWwpLmFwcGVuZENoaWxkKGVsZW1lbnQpO1xuXHRcdH1cblx0XHRlbHNlIGlmIChpID09PSBcImFyb3VuZFwiKSB7XG5cdFx0XHR2YXIgcmVmID0gJCQodmFsKTtcblx0XHRcdHJlZi5wYXJlbnROb2RlLmluc2VydEJlZm9yZShlbGVtZW50LCByZWYpO1xuXHRcdFx0ZWxlbWVudC5hcHBlbmRDaGlsZChyZWYpO1xuXHRcdH1cblx0XHRlbHNlIHtcblx0XHRcdGlmKGkgPT09IFwiY2xhc3NOYW1lXCIpIHsgaSA9IFwiY2xhc3NcIjsgfVxuXHRcdFx0aWYoaSA9PT0gXCJpbm5lckhUTUxcIikge1xuXHRcdFx0XHRlbGVtZW50Wyd0ZXh0Q29udGVudCddID0gdmFsO1xuXHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0ZWxlbWVudC5zZXRBdHRyaWJ1dGUoaSwgdmFsKTtcblx0XHRcdH1cblx0XHR9XG5cdH1cblxuXHRyZXR1cm4gZWxlbWVudDtcbn07XG5cbiQkLnJ1blNWR0FuaW1hdGlvbiA9IChzdmdfY29udGFpbmVyLCBlbGVtZW50cykgPT4ge1xuXHQvLyBsZXQgcGFyZW50ID0gZWxlbWVudHNbMF1bMF1bJ3VuaXQnXS5wYXJlbnROb2RlO1xuXG5cdGxldCBuZXdfZWxlbWVudHMgPSBbXTtcblx0bGV0IGFuaW1fZWxlbWVudHMgPSBbXTtcblxuXHRlbGVtZW50cy5tYXAoZWxlbWVudCA9PiB7XG5cdFx0bGV0IG9iaiA9IGVsZW1lbnRbMF07XG5cdFx0bGV0IHBhcmVudCA9IG9iai51bml0LnBhcmVudE5vZGU7XG5cdFx0Ly8gbGV0IGluZGV4ID0gJCQuZmluZE5vZGVJbmRleChvYmoudW5pdCk7XG5cblx0XHRsZXQgYW5pbV9lbGVtZW50LCBuZXdfZWxlbWVudDtcblxuXHRcdGVsZW1lbnRbMF0gPSBvYmoudW5pdDtcblxuXHRcdFthbmltX2VsZW1lbnQsIG5ld19lbGVtZW50XSA9ICQkLmFuaW1hdGVTVkcoLi4uZWxlbWVudCk7XG5cblx0XHRuZXdfZWxlbWVudHMucHVzaChuZXdfZWxlbWVudCk7XG5cdFx0YW5pbV9lbGVtZW50cy5wdXNoKFthbmltX2VsZW1lbnQsIHBhcmVudF0pO1xuXG5cdFx0cGFyZW50LnJlcGxhY2VDaGlsZChhbmltX2VsZW1lbnQsIG9iai51bml0KTtcblxuXHRcdGlmKG9iai5hcnJheSkge1xuXHRcdFx0b2JqLmFycmF5W29iai5pbmRleF0gPSBuZXdfZWxlbWVudDtcblx0XHR9IGVsc2Uge1xuXHRcdFx0b2JqLm9iamVjdFtvYmoua2V5XSA9IG5ld19lbGVtZW50O1xuXHRcdH1cblx0fSk7XG5cblx0bGV0IGFuaW1fc3ZnID0gc3ZnX2NvbnRhaW5lci5jbG9uZU5vZGUodHJ1ZSk7XG5cblx0YW5pbV9lbGVtZW50cy5tYXAoKGFuaW1fZWxlbWVudCwgaSkgPT4ge1xuXHRcdGFuaW1fZWxlbWVudFsxXS5yZXBsYWNlQ2hpbGQobmV3X2VsZW1lbnRzW2ldLCBhbmltX2VsZW1lbnRbMF0pO1xuXHRcdGVsZW1lbnRzW2ldWzBdID0gbmV3X2VsZW1lbnRzW2ldO1xuXHR9KTtcblxuXHRyZXR1cm4gYW5pbV9zdmc7XG59XG5cbi8vICQkLmFuaW1hdGVNb3Rpb24gPSAoZWxlbWVudCwgcHJvcHMsIGR1ciwgZWFzaW5nX3R5cGU9XCJsaW5lYXJcIilcblxuJCQuYW5pbWF0ZVNWRyA9IChlbGVtZW50LCBwcm9wcywgZHVyLCBlYXNpbmdfdHlwZT1cImxpbmVhclwiLCB0eXBlPXVuZGVmaW5lZCwgb2xkX3ZhbHVlcz17fSkgPT4ge1xuXHRsZXQgZWFzaW5nID0ge1xuXHRcdGVhc2U6IFwiMC4yNSAwLjEgMC4yNSAxXCIsXG5cdFx0bGluZWFyOiBcIjAgMCAxIDFcIixcblx0XHQvLyBlYXNlaW46IFwiMC40MiAwIDEgMVwiLFxuXHRcdGVhc2VpbjogXCIwLjEgMC44IDAuMiAxXCIsXG5cdFx0ZWFzZW91dDogXCIwIDAgMC41OCAxXCIsXG5cdFx0ZWFzZWlub3V0OiBcIjAuNDIgMCAwLjU4IDFcIlxuXHR9XG5cblx0bGV0IGFuaW1fZWxlbWVudCA9IGVsZW1lbnQuY2xvbmVOb2RlKHRydWUpO1xuXHRsZXQgbmV3X2VsZW1lbnQgPSBlbGVtZW50LmNsb25lTm9kZSh0cnVlKTtcblxuXHRmb3IodmFyIGF0dHJpYnV0ZU5hbWUgaW4gcHJvcHMpIHtcblx0XHRsZXQgYW5pbWF0ZV9lbGVtZW50O1xuXHRcdGlmKGF0dHJpYnV0ZU5hbWUgPT09ICd0cmFuc2Zvcm0nKSB7XG5cdFx0XHRhbmltYXRlX2VsZW1lbnQgPSBkb2N1bWVudC5jcmVhdGVFbGVtZW50TlMoXCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiLCBcImFuaW1hdGVUcmFuc2Zvcm1cIik7XG5cdFx0fSBlbHNlIHtcblx0XHRcdGFuaW1hdGVfZWxlbWVudCA9IGRvY3VtZW50LmNyZWF0ZUVsZW1lbnROUyhcImh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnXCIsIFwiYW5pbWF0ZVwiKTtcblx0XHR9XG5cdFx0bGV0IGN1cnJlbnRfdmFsdWUgPSBvbGRfdmFsdWVzW2F0dHJpYnV0ZU5hbWVdIHx8IGVsZW1lbnQuZ2V0QXR0cmlidXRlKGF0dHJpYnV0ZU5hbWUpO1xuXHRcdGxldCB2YWx1ZSA9IHByb3BzW2F0dHJpYnV0ZU5hbWVdO1xuXG5cdFx0bGV0IGFuaW1fYXR0ciA9IHtcblx0XHRcdGF0dHJpYnV0ZU5hbWU6IGF0dHJpYnV0ZU5hbWUsXG5cdFx0XHRmcm9tOiBjdXJyZW50X3ZhbHVlLFxuXHRcdFx0dG86IHZhbHVlLFxuXHRcdFx0YmVnaW46IFwiMHNcIixcblx0XHRcdGR1cjogZHVyLzEwMDAgKyBcInNcIixcblx0XHRcdHZhbHVlczogY3VycmVudF92YWx1ZSArIFwiO1wiICsgdmFsdWUsXG5cdFx0XHRrZXlTcGxpbmVzOiBlYXNpbmdbZWFzaW5nX3R5cGVdLFxuXHRcdFx0a2V5VGltZXM6IFwiMDsxXCIsXG5cdFx0XHRjYWxjTW9kZTogXCJzcGxpbmVcIixcblx0XHRcdGZpbGw6ICdmcmVlemUnXG5cdFx0fVxuXG5cdFx0aWYodHlwZSkge1xuXHRcdFx0YW5pbV9hdHRyW1widHlwZVwiXSA9IHR5cGU7XG5cdFx0fVxuXG5cdFx0Zm9yICh2YXIgaSBpbiBhbmltX2F0dHIpIHtcblx0XHRcdGFuaW1hdGVfZWxlbWVudC5zZXRBdHRyaWJ1dGUoaSwgYW5pbV9hdHRyW2ldKTtcblx0XHR9XG5cblx0XHRhbmltX2VsZW1lbnQuYXBwZW5kQ2hpbGQoYW5pbWF0ZV9lbGVtZW50KTtcblxuXHRcdGlmKHR5cGUpIHtcblx0XHRcdG5ld19lbGVtZW50LnNldEF0dHJpYnV0ZShhdHRyaWJ1dGVOYW1lLCBgdHJhbnNsYXRlKCR7dmFsdWV9KWApO1xuXHRcdH0gZWxzZSB7XG5cdFx0XHRuZXdfZWxlbWVudC5zZXRBdHRyaWJ1dGUoYXR0cmlidXRlTmFtZSwgdmFsdWUpO1xuXHRcdH1cblx0fVxuXG5cdHJldHVybiBbYW5pbV9lbGVtZW50LCBuZXdfZWxlbWVudF07XG59XG5cbiQkLm9mZnNldCA9IChlbGVtZW50KSA9PiB7XG5cdGxldCByZWN0ID0gZWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblx0cmV0dXJuIHtcblx0XHQvLyBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNzQzNjYwMi82NDk1MDQzXG5cdFx0Ly8gcmVjdC50b3AgdmFyaWVzIHdpdGggc2Nyb2xsLCBzbyB3ZSBhZGQgd2hhdGV2ZXIgaGFzIGJlZW5cblx0XHQvLyBzY3JvbGxlZCB0byBpdCB0byBnZXQgYWJzb2x1dGUgZGlzdGFuY2UgZnJvbSBhY3R1YWwgcGFnZSB0b3Bcblx0XHR0b3A6IHJlY3QudG9wICsgKGRvY3VtZW50LmRvY3VtZW50RWxlbWVudC5zY3JvbGxUb3AgfHwgZG9jdW1lbnQuYm9keS5zY3JvbGxUb3ApLFxuXHRcdGxlZnQ6IHJlY3QubGVmdCArIChkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuc2Nyb2xsTGVmdCB8fCBkb2N1bWVudC5ib2R5LnNjcm9sbExlZnQpXG5cdH1cbn07XG5cbiQkLmlzRWxlbWVudEluVmlld3BvcnQgPSAoZWwpID0+IHtcblx0Ly8gQWx0aG91Z2ggc3RyYWlnaHRmb3J3YXJkOiBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNzU1NzQzMy82NDk1MDQzXG4gICAgdmFyIHJlY3QgPSBlbC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgIHJldHVybiAoXG4gICAgICAgIHJlY3QudG9wID49IDAgJiZcbiAgICAgICAgcmVjdC5sZWZ0ID49IDAgJiZcbiAgICAgICAgcmVjdC5ib3R0b20gPD0gKHdpbmRvdy5pbm5lckhlaWdodCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50SGVpZ2h0KSAmJiAvKm9yICQod2luZG93KS5oZWlnaHQoKSAqL1xuICAgICAgICByZWN0LnJpZ2h0IDw9ICh3aW5kb3cuaW5uZXJXaWR0aCB8fCBkb2N1bWVudC5kb2N1bWVudEVsZW1lbnQuY2xpZW50V2lkdGgpIC8qb3IgJCh3aW5kb3cpLndpZHRoKCkgKi9cbiAgICApO1xufVxuXG4kJC5iaW5kID0gZnVuY3Rpb24oZWxlbWVudCwgbykge1xuXHRpZiAoZWxlbWVudCkge1xuXHRcdGZvciAodmFyIGV2ZW50IGluIG8pIHtcblx0XHRcdHZhciBjYWxsYmFjayA9IG9bZXZlbnRdO1xuXG5cdFx0XHRldmVudC5zcGxpdCgvXFxzKy8pLmZvckVhY2goZnVuY3Rpb24gKGV2ZW50KSB7XG5cdFx0XHRcdGVsZW1lbnQuYWRkRXZlbnRMaXN0ZW5lcihldmVudCwgY2FsbGJhY2spO1xuXHRcdFx0fSk7XG5cdFx0fVxuXHR9XG59O1xuXG4kJC51bmJpbmQgPSBmdW5jdGlvbihlbGVtZW50LCBvKSB7XG5cdGlmIChlbGVtZW50KSB7XG5cdFx0Zm9yICh2YXIgZXZlbnQgaW4gbykge1xuXHRcdFx0dmFyIGNhbGxiYWNrID0gb1tldmVudF07XG5cblx0XHRcdGV2ZW50LnNwbGl0KC9cXHMrLykuZm9yRWFjaChmdW5jdGlvbihldmVudCkge1xuXHRcdFx0XHRlbGVtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoZXZlbnQsIGNhbGxiYWNrKTtcblx0XHRcdH0pO1xuXHRcdH1cblx0fVxufTtcblxuJCQuZmlyZSA9IGZ1bmN0aW9uKHRhcmdldCwgdHlwZSwgcHJvcGVydGllcykge1xuXHR2YXIgZXZ0ID0gZG9jdW1lbnQuY3JlYXRlRXZlbnQoXCJIVE1MRXZlbnRzXCIpO1xuXG5cdGV2dC5pbml0RXZlbnQodHlwZSwgdHJ1ZSwgdHJ1ZSApO1xuXG5cdGZvciAodmFyIGogaW4gcHJvcGVydGllcykge1xuXHRcdGV2dFtqXSA9IHByb3BlcnRpZXNbal07XG5cdH1cblxuXHRyZXR1cm4gdGFyZ2V0LmRpc3BhdGNoRXZlbnQoZXZ0KTtcbn07XG4iXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsSUFBSSxNQUFNLEdBQUcsQ0FBQyxLQUFLLENBQUMsRUFBRSxFQUFFLFdBQVcsQ0FBQyxDQUFDLE1BQU0sRUFBRSxLQUFLLEVBQUUsWUFBWSxFQUFFLFNBQVMsQ0FBQyxDQUFDLENBQUM7O0FBRTlFLE1BQU0sQ0FBQyxLQUFLLENBQUMsV0FBVyxHQUFHLE1BQU07Q0FDaEMsV0FBVyxDQUFDO0VBQ1gsTUFBTSxHQUFHLEVBQUU7RUFDWCxNQUFNLEdBQUcsR0FBRzs7RUFFWixLQUFLLEdBQUcsRUFBRSxFQUFFLFFBQVEsR0FBRyxFQUFFOztFQUV6QixJQUFJ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LENBQUMsQ0FBQyxNQUFNLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7RUFDaEUsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztFQUMzQixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLEVBQUUsT0FBTyxDQUFDLENBQUM7O0VBRWhDLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxFQUFFLEtBQUssQ0FBQyxDQUFDO0VBQ2pDOztDQUVELGlCQUFpQixDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEVBQUU7RUFDMUMsR0FBRyxJQUFJLENBQUMsQ0FBQyxDQUFDLE1BQU0sR0FBRyxDQUFDLEVBQUUsT0FBTzs7RUFFN0IsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxHQUFHLENBQUMsUUFBUSxJQUFJLEVBQUUsT0FBTyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7RUFDekUsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUM7RUFDcEQsSUFBSSxLQUFLLEdBQUcsSUFBSSxDQUFDLENBQUMsQ0FBQyxLQUFLLEVBQUUsQ0FBQztFQUMzQixLQUFLLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQzs7RUFFdkIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxLQUFLLEVBQUUsS0FBSyxDQUFDLENBQUM7RUFDakM7O0NBRUQsYUFBYSxHQUFHO0VBQ2YsSUFBSSxRQUFRLEdBQUcsRUFBRSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxt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
diff --git a/docs/index.html b/docs/index.html
index df0be2b..8666583 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -88,7 +88,6 @@
-
diff --git a/package-lock.json b/package-lock.json
new file mode 100644
index 0000000..1d520d8
--- /dev/null
+++ b/package-lock.json
@@ -0,0 +1,70 @@
+{
+ "name": "charts",
+ "version": "0.0.1",
+ "lockfileVersion": 1,
+ "requires": true,
+ "dependencies": {
+ "balanced-match": {
+ "version": "1.0.0",
+ "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
+ "integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
+ "dev": true
+ },
+ "brace-expansion": {
+ "version": "1.1.8",
+ "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.8.tgz",
+ "integrity": "sha1-wHshHHyVLsH479Uad+8NHTmQopI=",
+ "dev": true,
+ "requires": {
+ "balanced-match": "1.0.0",
+ "concat-map": "0.0.1"
+ }
+ },
+ "concat-map": {
+ "version": "0.0.1",
+ "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
+ "integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
+ "dev": true
+ },
+ "estree-walker": {
+ "version": "0.2.1",
+ "resolved": "https://registry.npmjs.org/estree-walker/-/estree-walker-0.2.1.tgz",
+ "integrity": "sha1-va/oCVOD2EFNXcLs9MkXO225QS4=",
+ "dev": true
+ },
+ "minimatch": {
+ "version": "3.0.4",
+ "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
+ "integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
+ "dev": true,
+ "requires": {
+ "brace-expansion": "1.1.8"
+ }
+ },
+ "rollup": {
+ "version": "0.50.0",
+ "resolved": "https://registry.npmjs.org/rollup/-/rollup-0.50.0.tgz",
+ "integrity": "sha512-7RqCBQ9iwsOBPkjYgoIaeUij606mSkDMExP0NT7QDI3bqkHYQHrQ83uoNIXwPcQm/vP2VbsUz3kiyZZ1qPlLTQ==",
+ "dev": true
+ },
+ "rollup-plugin-babel": {
+ "version": "3.0.2",
+ "resolved": "https://registry.npmjs.org/rollup-plugin-babel/-/rollup-plugin-babel-3.0.2.tgz",
+ "integrity": "sha512-ALGPBFtwJZcYHsNPM6RGJlEncTzAARPvZOGjNPZgDe5hS5t6sJGjiOWibEFVEz5LQN7S7spvCBILaS4N1Cql2w==",
+ "dev": true,
+ "requires": {
+ "rollup-pluginutils": "1.5.2"
+ }
+ },
+ "rollup-pluginutils": {
+ "version": "1.5.2",
+ "resolved": "https://registry.npmjs.org/rollup-pluginutils/-/rollup-pluginutils-1.5.2.tgz",
+ "integrity": "sha1-HhVud4+UtyVb+hs9AXi+j1xVJAg=",
+ "dev": true,
+ "requires": {
+ "estree-walker": "0.2.1",
+ "minimatch": "3.0.4"
+ }
+ }
+ }
+}
diff --git a/package.json b/package.json
new file mode 100644
index 0000000..879ca80
--- /dev/null
+++ b/package.json
@@ -0,0 +1,30 @@
+{
+ "name": "charts",
+ "version": "0.0.1",
+ "description": "https://frappe.github.io/charts",
+ "main": "dist/frappe-charts.js",
+ "directories": {
+ "doc": "docs"
+ },
+ "scripts": {
+ "test": "mocha --compilers js:babel-core/register --colors -w ./test/*.spec.js"
+ },
+ "repository": {
+ "type": "git",
+ "url": "git+https://github.com/frappe/charts.git"
+ },
+ "keywords": [
+ "\"js",
+ "charts\""
+ ],
+ "author": "Prateeksha Singh",
+ "license": "MIT",
+ "bugs": {
+ "url": "https://github.com/frappe/charts/issues"
+ },
+ "homepage": "https://github.com/frappe/charts#readme",
+ "devDependencies": {
+ "rollup": "^0.50.0",
+ "rollup-plugin-babel": "^3.0.2"
+ }
+}
diff --git a/rollup.config.js b/rollup.config.js
new file mode 100644
index 0000000..b1e3ca1
--- /dev/null
+++ b/rollup.config.js
@@ -0,0 +1,14 @@
+// Rollup plugins
+import babel from 'rollup-plugin-babel';
+
+export default {
+ entry: 'src/charts.js',
+ dest: 'dist/frappe-charts.min.js',
+ format: 'iife',
+ sourceMap: 'inline',
+ plugins: [
+ babel({
+ exclude: 'node_modules/**',
+ }),
+ ],
+};
diff --git a/src/charts.js b/src/charts.js
index 32154ce..9ecc827 100644
--- a/src/charts.js
+++ b/src/charts.js
@@ -1,5 +1,3 @@
-"use strict";
-
let frappe = {chart:{}, chart_types:['line', 'bar', 'percentage', 'heatmap']};
frappe.chart.FrappeChart = class {
@@ -1378,7 +1376,7 @@ frappe.chart.LineChart = class LineChart extends frappe.chart.AxisChart {
super.setup_values();
this.unit_args = {
type: 'dot',
- args: { radius: 4 }
+ args: { radius: 8 }
};
}
@@ -1389,51 +1387,51 @@ frappe.chart.LineChart = class LineChart extends frappe.chart.AxisChart {
}
make_path(d, i, x_positions, y_positions, color) {
- let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
- let 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) {
- let 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
- });
-
- 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})`;
- }
+ // let points_list = y_positions.map((y, i) => (x_positions[i] + ',' + y));
+ // let 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) {
+ // let 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
+ // });
+
+ // 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})`;
+ // }
}
}