ng-d3-graphs
Version:
<img src="./assets/ng-d3.png" alt="drawing" width="250" height="250"/>
195 lines • 27.6 kB
JavaScript
import * as tslib_1 from "tslib";
import { Component, ElementRef, HostListener, Input, OnInit, ViewEncapsulation } from '@angular/core';
import * as d3 from 'd3';
import { Subject } from 'rxjs';
import { debounceTime } from 'rxjs/operators';
import { axisConfig } from '../shared/config/axis.config';
import { D3Service } from '../shared/services/d3.service';
let BandComponent = class BandComponent {
constructor(container, d3Service) {
this.container = container;
this.d3Service = d3Service;
this.data = [];
this.labels = [];
this.options = {};
this.labelsAndData = [];
this.viewBox = {};
this._options = {
width: 879,
height: 804,
margin: { top: 50, right: 50, bottom: 50, left: 50 },
yAxisLabel: '',
gridTicks: 0,
timeParser: axisConfig.xAxisTimeParser,
timeFormat: axisConfig.xAxisTimeFormat,
xAxisTicks: axisConfig.xAxisTicks,
};
this.parseTime = d3.timeParse(this.options.timeParser);
this.formatTime = d3.timeFormat(this.options.timeFormat);
this.onResize$ = new Subject();
}
onResize() {
this.onResize$.next();
}
ngOnInit() {
this.options = Object.assign({}, this._options, this.options);
this.viewBox = {
minX: -this.options.margin.left,
minY: -10,
width: this.options.width + this.options.margin.left +
this.options.margin.right,
height: this.options.height + this.options.margin.top,
};
this.parseTime = d3.timeParse(this.options.timeParser);
this.formatTime = d3.timeFormat(this.options.timeFormat);
this.labels = this.formatLabels();
this.labelsAndData = this.combineLabelsDataToOne();
this.onResizeEvent();
this.render();
}
formatLabels() {
return this.labels.map(d => this.parseTime(d));
}
combineLabelsDataToOne() {
const N = this.labels.length;
const result = [];
for (let index = 0; index < N; index++) {
result.push({
x: this.labels[index],
low: this.data[index].low,
high: this.data[index].high,
});
}
return result;
}
render() {
const currentWidth = parseInt(d3.select(this.container.nativeElement).select('div').style('width'), 10);
const currentHeight = parseInt(d3.select(this.container.nativeElement).select('div').style('height'), 10);
const width = this.options.width - this.options.margin.left -
this.options.margin.right;
const height = this.options.height - this.options.margin.top -
this.options.margin.bottom;
this.viewBox = {
minX: -this.options.margin.left,
minY: -10,
width: this.options.width,
height: this.options.height - this.options.margin.top,
};
const svg = d3.select(this.container.nativeElement)
.select('div')
.append('svg')
.attr('width', currentWidth)
.attr('height', currentHeight)
.attr('viewBox', `${this.viewBox.minX} ${this.viewBox.minY} ${this.viewBox.width} ${this.viewBox.height}`)
.classed('svg-content', true)
.append('g');
const x = d3.scaleTime()
.domain(d3.extent(this.labels, (d) => new Date(d)))
.range([0, width]);
const y = d3.scaleLinear()
.domain([
d3.min(this.data, (d) => d.low), d3.max(this.data, (d) => d.high)
])
.nice(this.options.gridTicks)
.range([height, 0]);
// add the X gridlines
svg.append('g')
.attr('class', 'grid')
.call(this.make_x_gridlines(x).tickSize(height)
// .tickFormat('')
);
// add the Y gridlines
svg.append('g')
.attr('class', 'grid')
.call(this.make_y_gridlines(y).tickSize(-width)
// .tickFormat('')
);
const xAxis = this.d3Service.getXaxisTime(svg, height, x, this.options.timeFormat, this.options.xAxisTicks);
const yAxis = (g) => g.attr('transform', `translate(${0},0)`).call(d3.axisLeft(y));
const curve = d3.curveStep;
const area = d3.area()
.curve(curve)
.x((d) => x(d.x))
.y0((d) => y(d.low))
.y1((d) => y(d.high));
const _yAxis = svg.append('g').call(yAxis);
// this.d3Service.addLabelAxisX(svg, width, height, this.options);
// text label for the x axis
this.addLabelAxisX(svg, width, height);
// text label for the y axis
this.addLabelAxisY(svg, height);
svg.append('path')
.datum(this.labelsAndData)
.attr('fill', 'steelblue')
.attr('d', area);
this.removeAxisTicks(xAxis);
this.removeAxisTicks(_yAxis);
this.changeAxisColor(xAxis, axisConfig);
this.changeAxisColor(_yAxis, axisConfig);
}
changeAxisColor(axis, config) {
this.d3Service.changeAxisColor(axis, config);
}
removeAxisTicks(axis) {
this.d3Service.removeAxisTicks(axis);
}
addLabelAxisY(svg, height) {
svg.append('text')
.attr('transform', 'rotate(0)')
.attr('y', 0 - this.options.margin.top / 2)
.attr('x', 0)
.attr('dy', '1em')
.style('text-anchor', 'start')
.text(this.options.yAxisLabel);
}
addLabelAxisX(svg, width, height) {
svg.append('text')
.attr('transform', 'translate(' + width / 2 + ' ,' +
(height + this.options.margin.top - 15) + ')')
.style('text-anchor', 'middle')
.text(this.options.xAxisLabel);
}
// gridlines in x axis function
make_x_gridlines(x) {
return d3.axisBottom(x).ticks(this.options.gridTicks);
}
// gridlines in y axis function
make_y_gridlines(y) {
return d3.axisLeft(y).ticks(this.options.gridTicks);
}
onResizeEvent() {
this.onResize$.pipe(debounceTime(200)).subscribe(() => {
const svgExist = d3.select(this.container.nativeElement).select('svg');
if (svgExist) {
svgExist.remove();
}
this.render();
});
}
};
BandComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: D3Service }
];
tslib_1.__decorate([
Input()
], BandComponent.prototype, "data", void 0);
tslib_1.__decorate([
Input()
], BandComponent.prototype, "labels", void 0);
tslib_1.__decorate([
Input()
], BandComponent.prototype, "options", void 0);
tslib_1.__decorate([
HostListener('window:resize')
], BandComponent.prototype, "onResize", null);
BandComponent = tslib_1.__decorate([
Component({
selector: 'ng-band',
template: "<div class=\"svg-container\"></div>\n",
encapsulation: ViewEncapsulation.None,
styles: [".svg-container{display:inline-block;position:relative;width:100%;height:100%;padding-bottom:100%;vertical-align:top;overflow:hidden}.svg-content{display:inline-block;position:absolute;top:0;left:0}.grid line{stroke:#d3d3d3;stroke-opacity:.4;shape-rendering:crispEdges}.grid path{stroke-width:0}.grid text{display:none}.area{fill:#4682b4}"]
})
], BandComponent);
export { BandComponent };
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYmFuZC5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy1kMy1ncmFwaHMvIiwic291cmNlcyI6WyJiYW5kL2JhbmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxpQkFBaUIsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUNwRyxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUV6QixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFHeEQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBa0J4RCxJQUFhLGFBQWEsR0FBMUIsTUFBYSxhQUFhO0lBMkJ4QixZQUFvQixTQUFxQixFQUFVLFNBQW9CO1FBQW5ELGNBQVMsR0FBVCxTQUFTLENBQVk7UUFBVSxjQUFTLEdBQVQsU0FBUyxDQUFXO1FBMUI5RCxTQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ2pCLFdBQU0sR0FBVSxFQUFFLENBQUM7UUFDbkIsWUFBTyxHQUFpQixFQUFpQixDQUFDO1FBQ25ELGtCQUFhLEdBQW9CLEVBQUUsQ0FBQztRQUNwQyxZQUFPLEdBQVksRUFBYSxDQUFDO1FBRWpDLGFBQVEsR0FBZ0I7WUFDdEIsS0FBSyxFQUFFLEdBQUc7WUFDVixNQUFNLEVBQUUsR0FBRztZQUNYLE1BQU0sRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUM7WUFDbEQsVUFBVSxFQUFFLEVBQUU7WUFDZCxTQUFTLEVBQUUsQ0FBQztZQUNaLFVBQVUsRUFBRSxVQUFVLENBQUMsZUFBZTtZQUN0QyxVQUFVLEVBQUUsVUFBVSxDQUFDLGVBQWU7WUFDdEMsVUFBVSxFQUFFLFVBQVUsQ0FBQyxVQUFVO1NBQ2xDLENBQUM7UUFFRixjQUFTLEdBQUcsRUFBRSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ2xELGVBQVUsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFcEQsY0FBUyxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFNMEMsQ0FBQztJQUozRSxRQUFRO1FBQ04sSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLEVBQUUsQ0FBQztJQUN4QixDQUFDO0lBSUQsUUFBUTtRQUNOLElBQUksQ0FBQyxPQUFPLHFCQUFPLElBQUksQ0FBQyxRQUFRLEVBQUssSUFBSSxDQUFDLE9BQU8sQ0FBQyxDQUFDO1FBQ25ELElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixJQUFJLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJO1lBQy9CLElBQUksRUFBRSxDQUFDLEVBQUU7WUFDVCxLQUFLLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSTtnQkFDaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsS0FBSztZQUM3QixNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRztTQUN0RCxDQUFDO1FBRUYsSUFBSSxDQUFDLFNBQVMsR0FBRyxFQUFFLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFDdkQsSUFBSSxDQUFDLFVBQVUsR0FBRyxFQUFFLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDbEMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUVuRCxJQUFJLENBQUMsYUFBYSxFQUFFLENBQUM7UUFFckIsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO0lBQ2hCLENBQUM7SUFFTyxZQUFZO1FBQ2xCLE9BQU8sSUFBSSxDQUFDLE1BQU0sQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7SUFDakQsQ0FBQztJQUVPLHNCQUFzQjtRQUM1QixNQUFNLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUM3QixNQUFNLE1BQU0sR0FBb0IsRUFBRSxDQUFDO1FBQ25DLEtBQUssSUFBSSxLQUFLLEdBQUcsQ0FBQyxFQUFFLEtBQUssR0FBRyxDQUFDLEVBQUUsS0FBSyxFQUFFLEVBQUU7WUFDdEMsTUFBTSxDQUFDLElBQUksQ0FBQztnQkFDVixDQUFDLEVBQUUsSUFBSSxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUM7Z0JBQ3JCLEdBQUcsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLEdBQUc7Z0JBQ3pCLElBQUksRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLElBQUk7YUFDNUIsQ0FBQyxDQUFDO1NBQ0o7UUFDRCxPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBRU8sTUFBTTtRQUNaLE1BQU0sWUFBWSxHQUFHLFFBQVEsQ0FDekIsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxLQUFLLENBQUMsT0FBTyxDQUFDLEVBQ3BFLEVBQUUsQ0FBQyxDQUFDO1FBQ1IsTUFBTSxhQUFhLEdBQUcsUUFBUSxDQUMxQixFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsYUFBYSxDQUFDLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsRUFDckUsRUFBRSxDQUFDLENBQUM7UUFFUixNQUFNLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJO1lBQ3ZELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQztRQUM5QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHO1lBQ3hELElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQztRQUMvQixJQUFJLENBQUMsT0FBTyxHQUFHO1lBQ2IsSUFBSSxFQUFFLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsSUFBSTtZQUMvQixJQUFJLEVBQUUsQ0FBQyxFQUFFO1lBQ1QsS0FBSyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsS0FBSztZQUN6QixNQUFNLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLENBQUMsR0FBRztTQUN0RCxDQUFDO1FBRUYsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQzthQUNsQyxNQUFNLENBQUMsS0FBSyxDQUFDO2FBQ2IsTUFBTSxDQUFDLEtBQUssQ0FBQzthQUNiLElBQUksQ0FBQyxPQUFPLEVBQUUsWUFBWSxDQUFDO2FBQzNCLElBQUksQ0FBQyxRQUFRLEVBQUUsYUFBYSxDQUFDO2FBQzdCLElBQUksQ0FDRCxTQUFTLEVBQ1QsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLElBQUksSUFDckMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQzthQUNuRCxPQUFPLENBQUMsYUFBYSxFQUFFLElBQUksQ0FBQzthQUM1QixNQUFNLENBQUMsR0FBRyxDQUFDLENBQUM7UUFFN0IsTUFBTSxDQUFDLEdBQ0gsRUFBRSxDQUFDLFNBQVMsRUFBRTthQUNULE1BQU0sQ0FBQyxFQUFFLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDbEQsS0FBSyxDQUFDLENBQUMsQ0FBQyxFQUFFLEtBQUssQ0FBQyxDQUFDLENBQUM7UUFFM0IsTUFBTSxDQUFDLEdBQ0gsRUFBRSxDQUFDLFdBQVcsRUFBRTthQUNYLE1BQU0sQ0FBQztZQUNOLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQztTQUNsRSxDQUFDO2FBQ0QsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDO2FBQzVCLEtBQUssQ0FBQyxDQUFDLE1BQU0sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBRTVCLHNCQUFzQjtRQUN0QixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQzthQUNWLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO2FBQ3JCLElBQUksQ0FDRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLE1BQU0sQ0FBQztRQUN6QyxrQkFBa0I7U0FDckIsQ0FBQztRQUVOLHNCQUFzQjtRQUN0QixHQUFHLENBQUMsTUFBTSxDQUFDLEdBQUcsQ0FBQzthQUNWLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDO2FBQ3JCLElBQUksQ0FDRCxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQyxDQUFDLENBQUMsUUFBUSxDQUFDLENBQUMsS0FBSyxDQUFDO1FBQ3pDLGtCQUFrQjtTQUNyQixDQUFDO1FBRU4sTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLFNBQVMsQ0FBQyxZQUFZLENBQ3JDLEdBQUcsRUFBRSxNQUFNLEVBQUUsQ0FBQyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsVUFBVSxDQUFDLENBQUM7UUFFdEUsTUFBTSxLQUFLLEdBQUcsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUNoQixDQUFDLENBQUMsSUFBSSxDQUFDLFdBQVcsRUFBRSxhQUFhLENBQUMsS0FBSyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQztRQUVsRSxNQUFNLEtBQUssR0FBUSxFQUFFLENBQUMsU0FBUyxDQUFDO1FBQ2hDLE1BQU0sSUFBSSxHQUFHLEVBQUUsQ0FBQyxJQUFJLEVBQWlCO2FBQ25CLEtBQUssQ0FBQyxLQUFLLENBQUM7YUFDWixDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUM7YUFDaEIsRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ25CLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxFQUFFLENBQUMsQ0FBQyxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRXZDLE1BQU0sTUFBTSxHQUFHLEdBQUcsQ0FBQyxNQUFNLENBQUMsR0FBRyxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBRTNDLGtFQUFrRTtRQUVsRSw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLGFBQWEsQ0FBQyxHQUFHLEVBQUUsS0FBSyxFQUFFLE1BQU0sQ0FBQyxDQUFDO1FBQ3ZDLDRCQUE0QjtRQUM1QixJQUFJLENBQUMsYUFBYSxDQUFDLEdBQUcsRUFBRSxNQUFNLENBQUMsQ0FBQztRQUVoQyxHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUNiLEtBQUssQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDO2FBQ3pCLElBQUksQ0FBQyxNQUFNLEVBQUUsV0FBVyxDQUFDO2FBQ3pCLElBQUksQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFFckIsSUFBSSxDQUFDLGVBQWUsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUM1QixJQUFJLENBQUMsZUFBZSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRTdCLElBQUksQ0FBQyxlQUFlLENBQUMsS0FBSyxFQUFFLFVBQVUsQ0FBQyxDQUFDO1FBQ3hDLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLFVBQVUsQ0FBQyxDQUFDO0lBQzNDLENBQUM7SUFFTyxlQUFlLENBQ25CLElBQXlELEVBQUUsTUFBVztRQUN4RSxJQUFJLENBQUMsU0FBUyxDQUFDLGVBQWUsQ0FBQyxJQUFJLEVBQUUsTUFBTSxDQUFDLENBQUM7SUFDL0MsQ0FBQztJQUdPLGVBQWUsQ0FDbkIsSUFBeUQ7UUFDM0QsSUFBSSxDQUFDLFNBQVMsQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLENBQUM7SUFDdkMsQ0FBQztJQUdPLGFBQWEsQ0FDakIsR0FBd0QsRUFDeEQsTUFBYztRQUNoQixHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUNiLElBQUksQ0FBQyxXQUFXLEVBQUUsV0FBVyxDQUFDO2FBQzlCLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQyxHQUFHLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEdBQUcsR0FBRyxDQUFDLENBQUM7YUFDMUMsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDLENBQUM7YUFDWixJQUFJLENBQUMsSUFBSSxFQUFFLEtBQUssQ0FBQzthQUNqQixLQUFLLENBQUMsYUFBYSxFQUFFLE9BQU8sQ0FBQzthQUM3QixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxVQUFVLENBQUMsQ0FBQztJQUNyQyxDQUFDO0lBRU8sYUFBYSxDQUNqQixHQUF3RCxFQUFFLEtBQWEsRUFDdkUsTUFBYztRQUNoQixHQUFHLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQzthQUNiLElBQUksQ0FDRCxXQUFXLEVBQ1gsWUFBWSxHQUFHLEtBQUssR0FBRyxDQUFDLEdBQUcsSUFBSTtZQUMzQixDQUFDLE1BQU0sR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxHQUFHLEdBQUcsRUFBRSxDQUFDLEdBQUcsR0FBRyxDQUFDO2FBQ3JELEtBQUssQ0FBQyxhQUFhLEVBQUUsUUFBUSxDQUFDO2FBQzlCLElBQUksQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVUsQ0FBQyxDQUFDO0lBQ3JDLENBQUM7SUFFRCwrQkFBK0I7SUFDdkIsZ0JBQWdCLENBQUMsQ0FBQztRQUN4QixPQUFPLEVBQUUsQ0FBQyxVQUFVLENBQUMsQ0FBQyxDQUFDLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsU0FBUyxDQUFDLENBQUM7SUFDeEQsQ0FBQztJQUVELCtCQUErQjtJQUN2QixnQkFBZ0IsQ0FBQyxDQUFDO1FBQ3hCLE9BQU8sRUFBRSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsQ0FBQztJQUN0RCxDQUFDO0lBRUQsYUFBYTtRQUNYLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUU7WUFDcEQsTUFBTSxRQUFRLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLGFBQWEsQ0FBQyxDQUFDLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQztZQUN2RSxJQUFJLFFBQVEsRUFBRTtnQkFDWixRQUFRLENBQUMsTUFBTSxFQUFFLENBQUM7YUFDbkI7WUFDRCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7UUFDaEIsQ0FBQyxDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YsQ0FBQTs7WUE3TGdDLFVBQVU7WUFBcUIsU0FBUzs7QUExQjlEO0lBQVIsS0FBSyxFQUFFOzJDQUFrQjtBQUNqQjtJQUFSLEtBQUssRUFBRTs2Q0FBb0I7QUFDbkI7SUFBUixLQUFLLEVBQUU7OENBQTJDO0FBb0JuRDtJQURDLFlBQVksQ0FBQyxlQUFlLENBQUM7NkNBRzdCO0FBekJVLGFBQWE7SUFOekIsU0FBUyxDQUFDO1FBQ1QsUUFBUSxFQUFFLFNBQVM7UUFDbkIsaURBQW9DO1FBRXBDLGFBQWEsRUFBRSxpQkFBaUIsQ0FBQyxJQUFJOztLQUN0QyxDQUFDO0dBQ1csYUFBYSxDQXdOekI7U0F4TlksYUFBYSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7Q29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9ufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCAqIGFzIGQzIGZyb20gJ2QzJztcbmltcG9ydCB7U2NhbGVUaW1lfSBmcm9tICdkMyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWV9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtheGlzQ29uZmlnfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnL2F4aXMuY29uZmlnJztcbmltcG9ydCB7R3JhcGhPcHRpb25zfSBmcm9tICcuLi9zaGFyZWQvbW9kZWxzL2dyYXBoLW9wdGlvbnMuaW50ZXJmYWNlJztcbmltcG9ydCB7Vmlld0JveH0gZnJvbSAnLi4vc2hhcmVkL21vZGVscy92aWV3Ym94LmludGVyZmFjZSc7XG5pbXBvcnQge0QzU2VydmljZX0gZnJvbSAnLi4vc2hhcmVkL3NlcnZpY2VzL2QzLnNlcnZpY2UnO1xuXG5pbnRlcmZhY2UgTGFiZWxzQW5kRGF0YSB7XG4gIHg6IGFueTtcbiAgbG93OiBhbnk7XG4gIGhpZ2g6IGFueTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBCYW5kT3B0aW9ucyBleHRlbmRzIEdyYXBoT3B0aW9ucyB7XG4gIGdyaWRUaWNrcz86IG51bWJlcjtcbn1cblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbmctYmFuZCcsXG4gIHRlbXBsYXRlVXJsOiAnLi9iYW5kLmNvbXBvbmVudC5odG1sJyxcbiAgc3R5bGVVcmxzOiBbJy4vYmFuZC5jb21wb25lbnQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxufSlcbmV4cG9ydCBjbGFzcyBCYW5kQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgZGF0YTogYW55W10gPSBbXTtcbiAgQElucHV0KCkgbGFiZWxzOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBvcHRpb25zPzogQmFuZE9wdGlvbnMgPSB7fSBhcyBCYW5kT3B0aW9ucztcbiAgbGFiZWxzQW5kRGF0YTogTGFiZWxzQW5kRGF0YVtdID0gW107XG4gIHZpZXdCb3g6IFZpZXdCb3ggPSB7fSBhcyBWaWV3Qm94O1xuXG4gIF9vcHRpb25zOiBCYW5kT3B0aW9ucyA9IHtcbiAgICB3aWR0aDogODc5LFxuICAgIGhlaWdodDogODA0LFxuICAgIG1hcmdpbjoge3RvcDogNTAsIHJpZ2h0OiA1MCwgYm90dG9tOiA1MCwgbGVmdDogNTB9LFxuICAgIHlBeGlzTGFiZWw6ICcnLFxuICAgIGdyaWRUaWNrczogMCxcbiAgICB0aW1lUGFyc2VyOiBheGlzQ29uZmlnLnhBeGlzVGltZVBhcnNlcixcbiAgICB0aW1lRm9ybWF0OiBheGlzQ29uZmlnLnhBeGlzVGltZUZvcm1hdCxcbiAgICB4QXhpc1RpY2tzOiBheGlzQ29uZmlnLnhBeGlzVGlja3MsXG4gIH07XG5cbiAgcGFyc2VUaW1lID0gZDMudGltZVBhcnNlKHRoaXMub3B0aW9ucy50aW1lUGFyc2VyKTtcbiAgZm9ybWF0VGltZSA9IGQzLnRpbWVGb3JtYXQodGhpcy5vcHRpb25zLnRpbWVGb3JtYXQpO1xuXG4gIG9uUmVzaXplJCA9IG5ldyBTdWJqZWN0PHZvaWQ+KCk7XG4gIEBIb3N0TGlzdGVuZXIoJ3dpbmRvdzpyZXNpemUnKVxuICBvblJlc2l6ZSgpOiB2b2lkIHtcbiAgICB0aGlzLm9uUmVzaXplJC5uZXh0KCk7XG4gIH1cblxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIGNvbnRhaW5lcjogRWxlbWVudFJlZiwgcHJpdmF0ZSBkM1NlcnZpY2U6IEQzU2VydmljZSkge31cblxuICBuZ09uSW5pdCgpIHtcbiAgICB0aGlzLm9wdGlvbnMgPSB7Li4udGhpcy5fb3B0aW9ucywgLi4udGhpcy5vcHRpb25zfTtcbiAgICB0aGlzLnZpZXdCb3ggPSB7XG4gICAgICBtaW5YOiAtdGhpcy5vcHRpb25zLm1hcmdpbi5sZWZ0LFxuICAgICAgbWluWTogLTEwLFxuICAgICAgd2lkdGg6IHRoaXMub3B0aW9ucy53aWR0aCArIHRoaXMub3B0aW9ucy5tYXJnaW4ubGVmdCArXG4gICAgICAgICAgdGhpcy5vcHRpb25zLm1hcmdpbi5yaWdodCxcbiAgICAgIGhlaWdodDogdGhpcy5vcHRpb25zLmhlaWdodCArIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wLFxuICAgIH07XG5cbiAgICB0aGlzLnBhcnNlVGltZSA9IGQzLnRpbWVQYXJzZSh0aGlzLm9wdGlvbnMudGltZVBhcnNlcik7XG4gICAgdGhpcy5mb3JtYXRUaW1lID0gZDMudGltZUZvcm1hdCh0aGlzLm9wdGlvbnMudGltZUZvcm1hdCk7XG5cbiAgICB0aGlzLmxhYmVscyA9IHRoaXMuZm9ybWF0TGFiZWxzKCk7XG4gICAgdGhpcy5sYWJlbHNBbmREYXRhID0gdGhpcy5jb21iaW5lTGFiZWxzRGF0YVRvT25lKCk7XG5cbiAgICB0aGlzLm9uUmVzaXplRXZlbnQoKTtcblxuICAgIHRoaXMucmVuZGVyKCk7XG4gIH1cblxuICBwcml2YXRlIGZvcm1hdExhYmVscygpOiBhbnlbXSB7XG4gICAgcmV0dXJuIHRoaXMubGFiZWxzLm1hcChkID0+IHRoaXMucGFyc2VUaW1lKGQpKTtcbiAgfVxuXG4gIHByaXZhdGUgY29tYmluZUxhYmVsc0RhdGFUb09uZSgpOiBMYWJlbHNBbmREYXRhW10ge1xuICAgIGNvbnN0IE4gPSB0aGlzLmxhYmVscy5sZW5ndGg7XG4gICAgY29uc3QgcmVzdWx0OiBMYWJlbHNBbmREYXRhW10gPSBbXTtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgTjsgaW5kZXgrKykge1xuICAgICAgcmVzdWx0LnB1c2goe1xuICAgICAgICB4OiB0aGlzLmxhYmVsc1tpbmRleF0sXG4gICAgICAgIGxvdzogdGhpcy5kYXRhW2luZGV4XS5sb3csXG4gICAgICAgIGhpZ2g6IHRoaXMuZGF0YVtpbmRleF0uaGlnaCxcbiAgICAgIH0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgcHJpdmF0ZSByZW5kZXIoKSB7XG4gICAgY29uc3QgY3VycmVudFdpZHRoID0gcGFyc2VJbnQoXG4gICAgICAgIGQzLnNlbGVjdCh0aGlzLmNvbnRhaW5lci5uYXRpdmVFbGVtZW50KS5zZWxlY3QoJ2RpdicpLnN0eWxlKCd3aWR0aCcpLFxuICAgICAgICAxMCk7XG4gICAgY29uc3QgY3VycmVudEhlaWdodCA9IHBhcnNlSW50KFxuICAgICAgICBkMy5zZWxlY3QodGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudCkuc2VsZWN0KCdkaXYnKS5zdHlsZSgnaGVpZ2h0JyksXG4gICAgICAgIDEwKTtcblxuICAgIGNvbnN0IHdpZHRoID0gdGhpcy5vcHRpb25zLndpZHRoIC0gdGhpcy5vcHRpb25zLm1hcmdpbi5sZWZ0IC1cbiAgICAgICAgdGhpcy5vcHRpb25zLm1hcmdpbi5yaWdodDtcbiAgICBjb25zdCBoZWlnaHQgPSB0aGlzLm9wdGlvbnMuaGVpZ2h0IC0gdGhpcy5vcHRpb25zLm1hcmdpbi50b3AgLVxuICAgICAgICB0aGlzLm9wdGlvbnMubWFyZ2luLmJvdHRvbTtcbiAgICB0aGlzLnZpZXdCb3ggPSB7XG4gICAgICBtaW5YOiAtdGhpcy5vcHRpb25zLm1hcmdpbi5sZWZ0LFxuICAgICAgbWluWTogLTEwLFxuICAgICAgd2lkdGg6IHRoaXMub3B0aW9ucy53aWR0aCxcbiAgICAgIGhlaWdodDogdGhpcy5vcHRpb25zLmhlaWdodCAtIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wLFxuICAgIH07XG5cbiAgICBjb25zdCBzdmcgPSBkMy5zZWxlY3QodGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudClcbiAgICAgICAgICAgICAgICAgICAgLnNlbGVjdCgnZGl2JylcbiAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgnc3ZnJylcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ3dpZHRoJywgY3VycmVudFdpZHRoKVxuICAgICAgICAgICAgICAgICAgICAuYXR0cignaGVpZ2h0JywgY3VycmVudEhlaWdodClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAgICAgICAgICAgICAndmlld0JveCcsXG4gICAgICAgICAgICAgICAgICAgICAgICBgJHt0aGlzLnZpZXdCb3gubWluWH0gJHt0aGlzLnZpZXdCb3gubWluWX0gJHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnZpZXdCb3gud2lkdGh9ICR7dGhpcy52aWV3Qm94LmhlaWdodH1gKVxuICAgICAgICAgICAgICAgICAgICAuY2xhc3NlZCgnc3ZnLWNvbnRlbnQnLCB0cnVlKVxuICAgICAgICAgICAgICAgICAgICAuYXBwZW5kKCdnJyk7XG5cbiAgICBjb25zdCB4OiBTY2FsZVRpbWU8YW55LCBhbnk+ID1cbiAgICAgICAgZDMuc2NhbGVUaW1lKClcbiAgICAgICAgICAgIC5kb21haW4oZDMuZXh0ZW50KHRoaXMubGFiZWxzLCAoZCkgPT4gbmV3IERhdGUoZCkpKVxuICAgICAgICAgICAgLnJhbmdlKFswLCB3aWR0aF0pO1xuXG4gICAgY29uc3QgeSA9XG4gICAgICAgIGQzLnNjYWxlTGluZWFyKClcbiAgICAgICAgICAgIC5kb21haW4oW1xuICAgICAgICAgICAgICBkMy5taW4odGhpcy5kYXRhLCAoZCkgPT4gZC5sb3cpLCBkMy5tYXgodGhpcy5kYXRhLCAoZCkgPT4gZC5oaWdoKVxuICAgICAgICAgICAgXSlcbiAgICAgICAgICAgIC5uaWNlKHRoaXMub3B0aW9ucy5ncmlkVGlja3MpXG4gICAgICAgICAgICAucmFuZ2UoW2hlaWdodCwgMF0pO1xuXG4gICAgLy8gYWRkIHRoZSBYIGdyaWRsaW5lc1xuICAgIHN2Zy5hcHBlbmQoJ2cnKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAnZ3JpZCcpXG4gICAgICAgIC5jYWxsKFxuICAgICAgICAgICAgdGhpcy5tYWtlX3hfZ3JpZGxpbmVzKHgpLnRpY2tTaXplKGhlaWdodClcbiAgICAgICAgICAgIC8vIC50aWNrRm9ybWF0KCcnKVxuICAgICAgICApO1xuXG4gICAgLy8gYWRkIHRoZSBZIGdyaWRsaW5lc1xuICAgIHN2Zy5hcHBlbmQoJ2cnKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAnZ3JpZCcpXG4gICAgICAgIC5jYWxsKFxuICAgICAgICAgICAgdGhpcy5tYWtlX3lfZ3JpZGxpbmVzKHkpLnRpY2tTaXplKC13aWR0aClcbiAgICAgICAgICAgIC8vIC50aWNrRm9ybWF0KCcnKVxuICAgICAgICApO1xuXG4gICAgY29uc3QgeEF4aXMgPSB0aGlzLmQzU2VydmljZS5nZXRYYXhpc1RpbWUoXG4gICAgICAgIHN2ZywgaGVpZ2h0LCB4LCB0aGlzLm9wdGlvbnMudGltZUZvcm1hdCwgdGhpcy5vcHRpb25zLnhBeGlzVGlja3MpO1xuXG4gICAgY29uc3QgeUF4aXMgPSAoZykgPT5cbiAgICAgICAgZy5hdHRyKCd0cmFuc2Zvcm0nLCBgdHJhbnNsYXRlKCR7MH0sMClgKS5jYWxsKGQzLmF4aXNMZWZ0KHkpKTtcblxuICAgIGNvbnN0IGN1cnZlOiBhbnkgPSBkMy5jdXJ2ZVN0ZXA7XG4gICAgY29uc3QgYXJlYSA9IGQzLmFyZWE8TGFiZWxzQW5kRGF0YT4oKVxuICAgICAgICAgICAgICAgICAgICAgLmN1cnZlKGN1cnZlKVxuICAgICAgICAgICAgICAgICAgICAgLngoKGQpID0+IHgoZC54KSlcbiAgICAgICAgICAgICAgICAgICAgIC55MCgoZCkgPT4geShkLmxvdykpXG4gICAgICAgICAgICAgICAgICAgICAueTEoKGQpID0+IHkoZC5oaWdoKSk7XG5cbiAgICBjb25zdCBfeUF4aXMgPSBzdmcuYXBwZW5kKCdnJykuY2FsbCh5QXhpcyk7XG5cbiAgICAvLyB0aGlzLmQzU2VydmljZS5hZGRMYWJlbEF4aXNYKHN2Zywgd2lkdGgsIGhlaWdodCwgdGhpcy5vcHRpb25zKTtcblxuICAgIC8vIHRleHQgbGFiZWwgZm9yIHRoZSB4IGF4aXNcbiAgICB0aGlzLmFkZExhYmVsQXhpc1goc3ZnLCB3aWR0aCwgaGVpZ2h0KTtcbiAgICAvLyB0ZXh0IGxhYmVsIGZvciB0aGUgeSBheGlzXG4gICAgdGhpcy5hZGRMYWJlbEF4aXNZKHN2ZywgaGVpZ2h0KTtcblxuICAgIHN2Zy5hcHBlbmQoJ3BhdGgnKVxuICAgICAgICAuZGF0dW0odGhpcy5sYWJlbHNBbmREYXRhKVxuICAgICAgICAuYXR0cignZmlsbCcsICdzdGVlbGJsdWUnKVxuICAgICAgICAuYXR0cignZCcsIGFyZWEpO1xuXG4gICAgdGhpcy5yZW1vdmVBeGlzVGlja3MoeEF4aXMpO1xuICAgIHRoaXMucmVtb3ZlQXhpc1RpY2tzKF95QXhpcyk7XG5cbiAgICB0aGlzLmNoYW5nZUF4aXNDb2xvcih4QXhpcywgYXhpc0NvbmZpZyk7XG4gICAgdGhpcy5jaGFuZ2VBeGlzQ29sb3IoX3lBeGlzLCBheGlzQ29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgY2hhbmdlQXhpc0NvbG9yKFxuICAgICAgYXhpczogZDMuU2VsZWN0aW9uPFNWR0dFbGVtZW50LCB1bmtub3duLCBudWxsLCB1bmRlZmluZWQ+LCBjb25maWc6IGFueSkge1xuICAgIHRoaXMuZDNTZXJ2aWNlLmNoYW5nZUF4aXNDb2xvcihheGlzLCBjb25maWcpO1xuICB9XG5cblxuICBwcml2YXRlIHJlbW92ZUF4aXNUaWNrcyhcbiAgICAgIGF4aXM6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPikge1xuICAgIHRoaXMuZDNTZXJ2aWNlLnJlbW92ZUF4aXNUaWNrcyhheGlzKTtcbiAgfVxuXG5cbiAgcHJpdmF0ZSBhZGRMYWJlbEF4aXNZKFxuICAgICAgc3ZnOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIG51bGwsIHVuZGVmaW5lZD4sXG4gICAgICBoZWlnaHQ6IG51bWJlcikge1xuICAgIHN2Zy5hcHBlbmQoJ3RleHQnKVxuICAgICAgICAuYXR0cigndHJhbnNmb3JtJywgJ3JvdGF0ZSgwKScpXG4gICAgICAgIC5hdHRyKCd5JywgMCAtIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wIC8gMilcbiAgICAgICAgLmF0dHIoJ3gnLCAwKVxuICAgICAgICAuYXR0cignZHknLCAnMWVtJylcbiAgICAgICAgLnN0eWxlKCd0ZXh0LWFuY2hvcicsICdzdGFydCcpXG4gICAgICAgIC50ZXh0KHRoaXMub3B0aW9ucy55QXhpc0xhYmVsKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkTGFiZWxBeGlzWChcbiAgICAgIHN2ZzogZDMuU2VsZWN0aW9uPFNWR0dFbGVtZW50LCB1bmtub3duLCBudWxsLCB1bmRlZmluZWQ+LCB3aWR0aDogbnVtYmVyLFxuICAgICAgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICBzdmcuYXBwZW5kKCd0ZXh0JylcbiAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAndHJhbnNmb3JtJyxcbiAgICAgICAgICAgICd0cmFuc2xhdGUoJyArIHdpZHRoIC8gMiArICcgLCcgK1xuICAgICAgICAgICAgICAgIChoZWlnaHQgKyB0aGlzLm9wdGlvbnMubWFyZ2luLnRvcCAtIDE1KSArICcpJylcbiAgICAgICAgLnN0eWxlKCd0ZXh0LWFuY2hvcicsICdtaWRkbGUnKVxuICAgICAgICAudGV4dCh0aGlzLm9wdGlvbnMueEF4aXNMYWJlbCk7XG4gIH1cblxuICAvLyBncmlkbGluZXMgaW4geCBheGlzIGZ1bmN0aW9uXG4gIHByaXZhdGUgbWFrZV94X2dyaWRsaW5lcyh4KSB7XG4gICAgcmV0dXJuIGQzLmF4aXNCb3R0b20oeCkudGlja3ModGhpcy5vcHRpb25zLmdyaWRUaWNrcyk7XG4gIH1cblxuICAvLyBncmlkbGluZXMgaW4geSBheGlzIGZ1bmN0aW9uXG4gIHByaXZhdGUgbWFrZV95X2dyaWRsaW5lcyh5KSB7XG4gICAgcmV0dXJuIGQzLmF4aXNMZWZ0KHkpLnRpY2tzKHRoaXMub3B0aW9ucy5ncmlkVGlja3MpO1xuICB9XG5cbiAgb25SZXNpemVFdmVudCgpOiB2b2lkIHtcbiAgICB0aGlzLm9uUmVzaXplJC5waXBlKGRlYm91bmNlVGltZSgyMDApKS5zdWJzY3JpYmUoKCkgPT4ge1xuICAgICAgY29uc3Qgc3ZnRXhpc3QgPSBkMy5zZWxlY3QodGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudCkuc2VsZWN0KCdzdmcnKTtcbiAgICAgIGlmIChzdmdFeGlzdCkge1xuICAgICAgICBzdmdFeGlzdC5yZW1vdmUoKTtcbiAgICAgIH1cbiAgICAgIHRoaXMucmVuZGVyKCk7XG4gICAgfSk7XG4gIH1cbn1cbiJdfQ==