UNPKG

ng-d3-graphs

Version:

<img src="./assets/ng-d3.png" alt="drawing" width="250" height="250"/>

212 lines 30.6 kB
import * as tslib_1 from "tslib"; import { ChangeDetectionStrategy, 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 LineComponent = class LineComponent { constructor(container, d3Service) { this.container = container; this.d3Service = d3Service; this.data = []; this.labels = []; this.options = {}; this._options = { width: 879, height: 804, margin: { top: 50, right: 50, bottom: 50, left: 50 }, gridTicks: 0, yAxisLabel: '', xAxisLabel: '', timeParser: axisConfig.xAxisTimeParser, timeFormat: axisConfig.xAxisTimeFormat, xAxisTicks: axisConfig.xAxisTicks, }; this.parseTime = d3.timeParse(this.options.timeParser); this.formatTime = d3.timeFormat(this.options.timeFormat); this.viewBox = {}; this.labelsAndData = []; this.AxisDataX = []; this.onResize$ = new Subject(); } onResize() { this.onResize$.next(); } ngOnInit() { this.options = Object.assign({}, this._options, this.options); this.viewBox = this.d3Service.getViewBoxDefault(this.options); this.parseTime = d3.timeParse(this.options.timeParser); this.formatTime = d3.timeFormat(this.options.timeFormat); this.labels = this.labels.map(d => this.parseTime(d)); this.labelsAndData = this.combineLabelsDataToOne(); this.onResizeEvent(); this.render(); } 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().range([0, width]); const y = d3.scaleLinear().range([height, 0]).nice(); const valueline = d3.line().x((d) => x(d.x)).y((d) => y(d.y)); x.domain(d3.extent(this.labels, (d) => (d))); y.domain([0, d3.max(this.data, (d) => d)]); // 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('') ); svg.append('path') .datum(this.labelsAndData) .attr('class', 'line') .attr('d', valueline); // add the X Axis const xAxis = this.d3Service.getXaxisTime(svg, height, x, this.options.timeFormat, this.options.xAxisTicks); // text label for the x axis this.addLabelAxisX(svg, width, height); // add the Y Axis const yAxis = svg.append('g').call(d3.axisLeft(y)); // text label for the y axis this.addLabelAxisY(svg, height); this.removeAxisTicks(xAxis); this.removeAxisTicks(yAxis); this.changeAxisColor(xAxis, axisConfig); this.changeAxisColor(yAxis, axisConfig); this.addDots(svg, x, y); } addDots(svg, x, y) { const dotRadius = 3; const dotColor = '#4682b4'; // add tootlip const { tooltip, tooltipRect, tooltipText, tooltipConfig } = this.d3Service.addTooltip(this.container); svg.selectAll('dot') .data(this.labelsAndData) .enter() .append('circle') .attr('r', dotRadius) .attr('fill', dotColor) .attr('cx', (d) => { return x(d.x); }) .attr('cy', (d) => { return y(d.y); }) .on('mouseover', (d) => { this.onMouseOver(d, x, y, tooltip, tooltipRect, tooltipText); }) .on('mouseout', (d) => { this.onMouseOut(d, tooltip, tooltipText, tooltipConfig); }); } onMouseOver(d, xScale, yScale, tooltip, tooltipRect, tooltipText) { // show tooltip if (tooltip) { this.d3Service.showTooltip(d, xScale, yScale, tooltip, tooltipRect, tooltipText, this.formatTime); } } onMouseOut(d, tooltip, tooltipText, tooltipConfig) { // hide tooltip if (tooltip) { this.d3Service.hideTooltip(tooltipText, tooltip); } } 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); } combineLabelsDataToOne() { const result = []; const N = this.data.length; for (let index = 0; index < N; index++) { result.push({ x: this.labels[index], y: this.data[index] }); } return result; } // 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(); }); } }; LineComponent.ctorParameters = () => [ { type: ElementRef }, { type: D3Service } ]; tslib_1.__decorate([ Input() ], LineComponent.prototype, "data", void 0); tslib_1.__decorate([ Input() ], LineComponent.prototype, "labels", void 0); tslib_1.__decorate([ Input() ], LineComponent.prototype, "options", void 0); tslib_1.__decorate([ HostListener('window:resize') ], LineComponent.prototype, "onResize", null); LineComponent = tslib_1.__decorate([ Component({ selector: 'ng-line', template: "<div class=\"svg-container\"></div>\n", encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.OnPush, 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}.line{fill:none;stroke:#4682b4;stroke-width:2px}div.tooltip{position:absolute;text-align:center;min-width:60px;min-height:28px;padding:5px;font:12px sans-serif;background:#b0c4de;border:0;border-radius:5px;pointer-events:none;color:#000}"] }) ], LineComponent); export { LineComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGluZS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly9uZy1kMy1ncmFwaHMvIiwic291cmNlcyI6WyJsaW5lL2xpbmUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQUMsdUJBQXVCLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsS0FBSyxFQUFFLE1BQU0sRUFBRSxpQkFBaUIsR0FBRSxNQUFNLGVBQWUsQ0FBQztBQUM5SCxPQUFPLEtBQUssRUFBRSxNQUFNLElBQUksQ0FBQztBQUN6QixPQUFPLEVBQUMsT0FBTyxFQUFDLE1BQU0sTUFBTSxDQUFDO0FBQzdCLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQztBQUU1QyxPQUFPLEVBQUMsVUFBVSxFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFHeEQsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLCtCQUErQixDQUFDO0FBdUJ4RCxJQUFhLGFBQWEsR0FBMUIsTUFBYSxhQUFhO0lBK0J4QixZQUFvQixTQUFxQixFQUFVLFNBQW9CO1FBQW5ELGNBQVMsR0FBVCxTQUFTLENBQVk7UUFBVSxjQUFTLEdBQVQsU0FBUyxDQUFXO1FBOUI5RCxTQUFJLEdBQVUsRUFBRSxDQUFDO1FBQ2pCLFdBQU0sR0FBVSxFQUFFLENBQUM7UUFDbkIsWUFBTyxHQUFpQixFQUFpQixDQUFDO1FBRTNDLGFBQVEsR0FBZ0I7WUFDOUIsS0FBSyxFQUFFLEdBQUc7WUFDVixNQUFNLEVBQUUsR0FBRztZQUNYLE1BQU0sRUFBRSxFQUFDLEdBQUcsRUFBRSxFQUFFLEVBQUUsS0FBSyxFQUFFLEVBQUUsRUFBRSxNQUFNLEVBQUUsRUFBRSxFQUFFLElBQUksRUFBRSxFQUFFLEVBQUM7WUFDbEQsU0FBUyxFQUFFLENBQUM7WUFDWixVQUFVLEVBQUUsRUFBRTtZQUNkLFVBQVUsRUFBRSxFQUFFO1lBQ2QsVUFBVSxFQUFFLFVBQVUsQ0FBQyxlQUFlO1lBQ3RDLFVBQVUs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QWtCO0FBQ2pCO0lBQVIsS0FBSyxFQUFFOzZDQUFvQjtBQUNuQjtJQUFSLEtBQUssRUFBRTs4Q0FBMkM7QUF3Qm5EO0lBREMsWUFBWSxDQUFDLGVBQWUsQ0FBQzs2Q0FHN0I7QUE3QlUsYUFBYTtJQVB6QixTQUFTLENBQUM7UUFDVCxRQUFRLEVBQUUsU0FBUztRQUNuQixpREFBb0M7UUFFcEMsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7UUFDckMsZUFBZSxFQUFFLHVCQUF1QixDQUFDLE1BQU07O0tBQ2hELENBQUM7R0FDVyxhQUFhLENBdVB6QjtTQXZQWSxhQUFhIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSwgQ29tcG9uZW50LCBFbGVtZW50UmVmLCBIb3N0TGlzdGVuZXIsIElucHV0LCBPbkluaXQsIFZpZXdFbmNhcHN1bGF0aW9uLH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgKiBhcyBkMyBmcm9tICdkMyc7XG5pbXBvcnQge1N1YmplY3R9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHtkZWJvdW5jZVRpbWV9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtheGlzQ29uZmlnfSBmcm9tICcuLi9zaGFyZWQvY29uZmlnL2F4aXMuY29uZmlnJztcbmltcG9ydCB7R3JhcGhPcHRpb25zfSBmcm9tICcuLi9zaGFyZWQvbW9kZWxzL2dyYXBoLW9wdGlvbnMuaW50ZXJmYWNlJztcbmltcG9ydCB7Vmlld0JveH0gZnJvbSAnLi4vc2hhcmVkL21vZGVscy92aWV3Ym94LmludGVyZmFjZSc7XG5pbXBvcnQge0QzU2VydmljZX0gZnJvbSAnLi4vc2hhcmVkL3NlcnZpY2VzL2QzLnNlcnZpY2UnO1xuXG5pbnRlcmZhY2UgTGFiZWxzQW5kRGF0YSB7XG4gIHg6IGFueTtcbiAgeTogYW55O1xufVxuXG5pbnRlcmZhY2UgQXhpc0RhdGFYIHtcbiAgaWQ6IG51bWJlcjtcbiAgdmFsdWU6IGFueTtcbn1cblxuaW50ZXJmYWNlIExpbmVPcHRpb25zIGV4dGVuZHMgR3JhcGhPcHRpb25zIHtcbiAgZ3JpZFRpY2tzPzogbnVtYmVyO1xufVxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZy1saW5lJyxcbiAgdGVtcGxhdGVVcmw6ICcuL2xpbmUuY29tcG9uZW50Lmh0bWwnLFxuICBzdHlsZVVybHM6IFsnLi9saW5lLmNvbXBvbmVudC5zY3NzJ10sXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxufSlcbmV4cG9ydCBjbGFzcyBMaW5lQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0IHtcbiAgQElucHV0KCkgZGF0YTogYW55W10gPSBbXTtcbiAgQElucHV0KCkgbGFiZWxzOiBhbnlbXSA9IFtdO1xuICBASW5wdXQoKSBvcHRpb25zPzogTGluZU9wdGlvbnMgPSB7fSBhcyBMaW5lT3B0aW9ucztcblxuICBwcml2YXRlIF9vcHRpb25zOiBMaW5lT3B0aW9ucyA9IHtcbiAgICB3aWR0aDogODc5LFxuICAgIGhlaWdodDogODA0LFxuICAgIG1hcmdpbjoge3RvcDogNTAsIHJpZ2h0OiA1MCwgYm90dG9tOiA1MCwgbGVmdDogNTB9LFxuICAgIGdyaWRUaWNrczogMCxcbiAgICB5QXhpc0xhYmVsOiAnJyxcbiAgICB4QXhpc0xhYmVsOiAnJyxcbiAgICB0aW1lUGFyc2VyOiBheGlzQ29uZmlnLnhBeGlzVGltZVBhcnNlcixcbiAgICB0aW1lRm9ybWF0OiBheGlzQ29uZmlnLnhBeGlzVGltZUZvcm1hdCxcbiAgICB4QXhpc1RpY2tzOiBheGlzQ29uZmlnLnhBeGlzVGlja3MsXG4gIH07XG5cbiAgcGFyc2VUaW1lID0gZDMudGltZVBhcnNlKHRoaXMub3B0aW9ucy50aW1lUGFyc2VyKTtcbiAgZm9ybWF0VGltZSA9IGQzLnRpbWVGb3JtYXQodGhpcy5vcHRpb25zLnRpbWVGb3JtYXQpO1xuXG4gIHByaXZhdGUgdmlld0JveDogVmlld0JveCA9IHt9IGFzIFZpZXdCb3g7XG5cbiAgbGFiZWxzQW5kRGF0YTogTGFiZWxzQW5kRGF0YVtdID0gW107XG4gIEF4aXNEYXRhWDogQXhpc0RhdGFYW10gPSBbXTtcblxuICBvblJlc2l6ZSQgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBASG9zdExpc3RlbmVyKCd3aW5kb3c6cmVzaXplJylcbiAgb25SZXNpemUoKTogdm9pZCB7XG4gICAgdGhpcy5vblJlc2l6ZSQubmV4dCgpO1xuICB9XG5cbiAgY29uc3RydWN0b3IocHJpdmF0ZSBjb250YWluZXI6IEVsZW1lbnRSZWYsIHByaXZhdGUgZDNTZXJ2aWNlOiBEM1NlcnZpY2UpIHt9XG5cbiAgbmdPbkluaXQoKSB7XG4gICAgdGhpcy5vcHRpb25zID0gey4uLnRoaXMuX29wdGlvbnMsIC4uLnRoaXMub3B0aW9uc307XG4gICAgdGhpcy52aWV3Qm94ID0gdGhpcy5kM1NlcnZpY2UuZ2V0Vmlld0JveERlZmF1bHQodGhpcy5vcHRpb25zKTtcblxuICAgIHRoaXMucGFyc2VUaW1lID0gZDMudGltZVBhcnNlKHRoaXMub3B0aW9ucy50aW1lUGFyc2VyKTtcbiAgICB0aGlzLmZvcm1hdFRpbWUgPSBkMy50aW1lRm9ybWF0KHRoaXMub3B0aW9ucy50aW1lRm9ybWF0KTtcblxuXG4gICAgdGhpcy5sYWJlbHMgPSB0aGlzLmxhYmVscy5tYXAoZCA9PiB0aGlzLnBhcnNlVGltZShkKSk7XG5cbiAgICB0aGlzLmxhYmVsc0FuZERhdGEgPSB0aGlzLmNvbWJpbmVMYWJlbHNEYXRhVG9PbmUoKTtcblxuICAgIHRoaXMub25SZXNpemVFdmVudCgpO1xuXG4gICAgdGhpcy5yZW5kZXIoKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVuZGVyKCk6IHZvaWQge1xuICAgIGNvbnN0IGN1cnJlbnRXaWR0aCA9IHBhcnNlSW50KFxuICAgICAgICBkMy5zZWxlY3QodGhpcy5jb250YWluZXIubmF0aXZlRWxlbWVudCkuc2VsZWN0KCdkaXYnKS5zdHlsZSgnd2lkdGgnKSxcbiAgICAgICAgMTApO1xuICAgIGNvbnN0IGN1cnJlbnRIZWlnaHQgPSBwYXJzZUludChcbiAgICAgICAgZDMuc2VsZWN0KHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpLnNlbGVjdCgnZGl2Jykuc3R5bGUoJ2hlaWdodCcpLFxuICAgICAgICAxMCk7XG5cbiAgICBjb25zdCB3aWR0aCA9IHRoaXMub3B0aW9ucy53aWR0aCAtIHRoaXMub3B0aW9ucy5tYXJnaW4ubGVmdCAtXG4gICAgICAgIHRoaXMub3B0aW9ucy5tYXJnaW4ucmlnaHQ7XG4gICAgY29uc3QgaGVpZ2h0ID0gdGhpcy5vcHRpb25zLmhlaWdodCAtIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wIC1cbiAgICAgICAgdGhpcy5vcHRpb25zLm1hcmdpbi5ib3R0b207XG4gICAgdGhpcy52aWV3Qm94ID0ge1xuICAgICAgbWluWDogLXRoaXMub3B0aW9ucy5tYXJnaW4ubGVmdCxcbiAgICAgIG1pblk6IC0xMCxcbiAgICAgIHdpZHRoOiB0aGlzLm9wdGlvbnMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMub3B0aW9ucy5oZWlnaHQgLSB0aGlzLm9wdGlvbnMubWFyZ2luLnRvcCxcbiAgICB9O1xuXG4gICAgY29uc3Qgc3ZnID0gZDMuc2VsZWN0KHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIC5zZWxlY3QoJ2RpdicpXG4gICAgICAgICAgICAgICAgICAgIC5hcHBlbmQoJ3N2ZycpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKCd3aWR0aCcsIGN1cnJlbnRXaWR0aClcbiAgICAgICAgICAgICAgICAgICAgLmF0dHIoJ2hlaWdodCcsIGN1cnJlbnRIZWlnaHQpXG4gICAgICAgICAgICAgICAgICAgIC5hdHRyKFxuICAgICAgICAgICAgICAgICAgICAgICAgJ3ZpZXdCb3gnLFxuICAgICAgICAgICAgICAgICAgICAgICAgYCR7dGhpcy52aWV3Qm94Lm1pblh9ICR7dGhpcy52aWV3Qm94Lm1pbll9ICR7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy52aWV3Qm94LndpZHRofSAke3RoaXMudmlld0JveC5oZWlnaHR9YClcbiAgICAgICAgICAgICAgICAgICAgLmNsYXNzZWQoJ3N2Zy1jb250ZW50JywgdHJ1ZSlcbiAgICAgICAgICAgICAgICAgICAgLmFwcGVuZCgnZycpO1xuXG4gICAgY29uc3QgeCA9IGQzLnNjYWxlVGltZSgpLnJhbmdlKFswLCB3aWR0aF0pO1xuICAgIGNvbnN0IHkgPSBkMy5zY2FsZUxpbmVhcigpLnJhbmdlKFtoZWlnaHQsIDBdKS5uaWNlKCk7XG4gICAgY29uc3QgdmFsdWVsaW5lID0gZDMubGluZTxhbnk+KCkueCgoZCkgPT4geChkLngpKS55KChkKSA9PiB5KGQueSkpO1xuXG4gICAgeC5kb21haW4oZDMuZXh0ZW50KHRoaXMubGFiZWxzLCAoZCkgPT4gKGQpKSk7XG4gICAgeS5kb21haW4oWzAsIGQzLm1heCh0aGlzLmRhdGEsIChkKSA9PiBkKV0pO1xuXG4gICAgLy8gYWRkIHRoZSBYIGdyaWRsaW5lc1xuICAgIHN2Zy5hcHBlbmQoJ2cnKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAnZ3JpZCcpXG4gICAgICAgIC5jYWxsKFxuICAgICAgICAgICAgdGhpcy5tYWtlX3hfZ3JpZGxpbmVzKHgpLnRpY2tTaXplKGhlaWdodClcbiAgICAgICAgICAgIC8vIC50aWNrRm9ybWF0KCcnKVxuICAgICAgICApO1xuXG4gICAgLy8gYWRkIHRoZSBZIGdyaWRsaW5lc1xuICAgIHN2Zy5hcHBlbmQoJ2cnKVxuICAgICAgICAuYXR0cignY2xhc3MnLCAnZ3JpZCcpXG4gICAgICAgIC5jYWxsKFxuICAgICAgICAgICAgdGhpcy5tYWtlX3lfZ3JpZGxpbmVzKHkpLnRpY2tTaXplKC13aWR0aClcbiAgICAgICAgICAgIC8vIC50aWNrRm9ybWF0KCcnKVxuICAgICAgICApO1xuXG4gICAgc3ZnLmFwcGVuZCgncGF0aCcpXG4gICAgICAgIC5kYXR1bSh0aGlzLmxhYmVsc0FuZERhdGEpXG4gICAgICAgIC5hdHRyKCdjbGFzcycsICdsaW5lJylcbiAgICAgICAgLmF0dHIoJ2QnLCB2YWx1ZWxpbmUpO1xuXG4gICAgLy8gYWRkIHRoZSBYIEF4aXNcbiAgICBjb25zdCB4QXhpcyA9IHRoaXMuZDNTZXJ2aWNlLmdldFhheGlzVGltZShcbiAgICAgICAgc3ZnLCBoZWlnaHQsIHgsIHRoaXMub3B0aW9ucy50aW1lRm9ybWF0LCB0aGlzLm9wdGlvbnMueEF4aXNUaWNrcyk7XG5cblxuICAgIC8vIHRleHQgbGFiZWwgZm9yIHRoZSB4IGF4aXNcbiAgICB0aGlzLmFkZExhYmVsQXhpc1goc3ZnLCB3aWR0aCwgaGVpZ2h0KTtcblxuICAgIC8vIGFkZCB0aGUgWSBBeGlzXG4gICAgY29uc3QgeUF4aXMgPSBzdmcuYXBwZW5kKCdnJykuY2FsbChkMy5heGlzTGVmdCh5KSk7XG5cbiAgICAvLyB0ZXh0IGxhYmVsIGZvciB0aGUgeSBheGlzXG4gICAgdGhpcy5hZGRMYWJlbEF4aXNZKHN2ZywgaGVpZ2h0KTtcblxuICAgIHRoaXMucmVtb3ZlQXhpc1RpY2tzKHhBeGlzKTtcbiAgICB0aGlzLnJlbW92ZUF4aXNUaWNrcyh5QXhpcyk7XG5cbiAgICB0aGlzLmNoYW5nZUF4aXNDb2xvcih4QXhpcywgYXhpc0NvbmZpZyk7XG4gICAgdGhpcy5jaGFuZ2VBeGlzQ29sb3IoeUF4aXMsIGF4aXNDb25maWcpO1xuXG4gICAgdGhpcy5hZGREb3RzKHN2ZywgeCwgeSk7XG4gIH1cblxuICBwcml2YXRlIGFkZERvdHMoXG4gICAgICBzdmc6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPixcbiAgICAgIHg6IGQzLlNjYWxlVGltZTxudW1iZXIsIG51bWJlcj4sIHk6IGQzLlNjYWxlTGluZWFyPG51bWJlciwgbnVtYmVyPikge1xuICAgIGNvbnN0IGRvdFJhZGl1cyA9IDM7XG4gICAgY29uc3QgZG90Q29sb3IgPSAnIzQ2ODJiNCc7XG5cbiAgICAvLyBhZGQgdG9vdGxpcFxuICAgIGNvbnN0IHt0b29sdGlwLCB0b29sdGlwUmVjdCwgdG9vbHRpcFRleHQsIHRvb2x0aXBDb25maWd9ID1cbiAgICAgICAgdGhpcy5kM1NlcnZpY2UuYWRkVG9vbHRpcCh0aGlzLmNvbnRhaW5lcik7XG5cbiAgICBzdmcuc2VsZWN0QWxsKCdkb3QnKVxuICAgICAgICAuZGF0YSh0aGlzLmxhYmVsc0FuZERhdGEpXG4gICAgICAgIC5lbnRlcigpXG4gICAgICAgIC5hcHBlbmQoJ2NpcmNsZScpXG4gICAgICAgIC5hdHRyKCdyJywgZG90UmFkaXVzKVxuICAgICAgICAuYXR0cignZmlsbCcsIGRvdENvbG9yKVxuICAgICAgICAuYXR0cihcbiAgICAgICAgICAgICdjeCcsXG4gICAgICAgICAgICAoZCkgPT4ge1xuICAgICAgICAgICAgICByZXR1cm4geChkLngpO1xuICAgICAgICAgICAgfSlcbiAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAnY3knLFxuICAgICAgICAgICAgKGQpID0+IHtcbiAgICAgICAgICAgICAgcmV0dXJuIHkoZC55KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIC5vbignbW91c2VvdmVyJyxcbiAgICAgICAgICAgIChkKSA9PiB7XG4gICAgICAgICAgICAgIHRoaXMub25Nb3VzZU92ZXIoZCwgeCwgeSwgdG9vbHRpcCwgdG9vbHRpcFJlY3QsIHRvb2x0aXBUZXh0KTtcbiAgICAgICAgICAgIH0pXG4gICAgICAgIC5vbignbW91c2VvdXQnLCAoZCkgPT4ge1xuICAgICAgICAgIHRoaXMub25Nb3VzZU91dChkLCB0b29sdGlwLCB0b29sdGlwVGV4dCwgdG9vbHRpcENvbmZpZyk7XG4gICAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBvbk1vdXNlT3ZlcihkLCB4U2NhbGUsIHlTY2FsZSwgdG9vbHRpcD8sIHRvb2x0aXBSZWN0PywgdG9vbHRpcFRleHQ/KSB7XG4gICAgLy8gc2hvdyB0b29sdGlwXG4gICAgaWYgKHRvb2x0aXApIHtcbiAgICAgIHRoaXMuZDNTZXJ2aWNlLnNob3dUb29sdGlwKFxuICAgICAgICAgIGQsIHhTY2FsZSwgeVNjYWxlLCB0b29sdGlwLCB0b29sdGlwUmVjdCwgdG9vbHRpcFRleHQsXG4gICAgICAgICAgdGhpcy5mb3JtYXRUaW1lKTtcbiAgICB9XG4gIH1cblxuXG4gIHByaXZhdGUgb25Nb3VzZU91dChkLCB0b29sdGlwPywgdG9vbHRpcFRleHQ/LCB0b29sdGlwQ29uZmlnPykge1xuICAgIC8vIGhpZGUgdG9vbHRpcFxuICAgIGlmICh0b29sdGlwKSB7XG4gICAgICB0aGlzLmQzU2VydmljZS5oaWRlVG9vbHRpcCh0b29sdGlwVGV4dCwgdG9vbHRpcCk7XG4gICAgfVxuICB9XG5cblxuICBwcml2YXRlIGNoYW5nZUF4aXNDb2xvcihcbiAgICAgIGF4aXM6IGQzLlNlbGVjdGlvbjxTVkdHRWxlbWVudCwgdW5rbm93biwgbnVsbCwgdW5kZWZpbmVkPiwgY29uZmlnOiBhbnkpIHtcbiAgICB0aGlzLmQzU2VydmljZS5jaGFuZ2VBeGlzQ29sb3IoYXhpcywgY29uZmlnKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlQXhpc1RpY2tzKFxuICAgICAgYXhpczogZDMuU2VsZWN0aW9uPFNWR0dFbGVtZW50LCB1bmtub3duLCBudWxsLCB1bmRlZmluZWQ+KSB7XG4gICAgdGhpcy5kM1NlcnZpY2UucmVtb3ZlQXhpc1RpY2tzKGF4aXMpO1xuICB9XG5cbiAgcHJpdmF0ZSBhZGRMYWJlbEF4aXNZKFxuICAgICAgc3ZnOiBkMy5TZWxlY3Rpb248U1ZHR0VsZW1lbnQsIHVua25vd24sIG51bGwsIHVuZGVmaW5lZD4sXG4gICAgICBoZWlnaHQ6IG51bWJlcikge1xuICAgIHN2Zy5hcHBlbmQoJ3RleHQnKVxuICAgICAgICAuYXR0cigndHJhbnNmb3JtJywgJ3JvdGF0ZSgwKScpXG4gICAgICAgIC5hdHRyKCd5JywgMCAtIHRoaXMub3B0aW9ucy5tYXJnaW4udG9wIC8gMilcbiAgICAgICAgLmF0dHIoJ3gnLCAwKVxuICAgICAgICAuYXR0cignZHknLCAnMWVtJylcbiAgICAgICAgLnN0eWxlKCd0ZXh0LWFuY2hvcicsICdzdGFydCcpXG4gICAgICAgIC50ZXh0KHRoaXMub3B0aW9ucy55QXhpc0xhYmVsKTtcbiAgfVxuXG4gIHByaXZhdGUgYWRkTGFiZWxBeGlzWChcbiAgICAgIHN2ZzogZDMuU2VsZWN0aW9uPFNWR0dFbGVtZW50LCB1bmtub3duLCBudWxsLCB1bmRlZmluZWQ+LCB3aWR0aDogbnVtYmVyLFxuICAgICAgaGVpZ2h0OiBudW1iZXIpIHtcbiAgICBzdmcuYXBwZW5kKCd0ZXh0JylcbiAgICAgICAgLmF0dHIoXG4gICAgICAgICAgICAndHJhbnNmb3JtJyxcbiAgICAgICAgICAgICd0cmFuc2xhdGUoJyArIHdpZHRoIC8gMiArICcgLCcgK1xuICAgICAgICAgICAgICAgIChoZWlnaHQgKyB0aGlzLm9wdGlvbnMubWFyZ2luLnRvcCAtIDE1KSArICcpJylcbiAgICAgICAgLnN0eWxlKCd0ZXh0LWFuY2hvcicsICdtaWRkbGUnKVxuICAgICAgICAudGV4dCh0aGlzLm9wdGlvbnMueEF4aXNMYWJlbCk7XG4gIH1cblxuICBwcml2YXRlIGNvbWJpbmVMYWJlbHNEYXRhVG9PbmUoKTogTGFiZWxzQW5kRGF0YVtdIHtcbiAgICBjb25zdCByZXN1bHQgPSBbXTtcbiAgICBjb25zdCBOID0gdGhpcy5kYXRhLmxlbmd0aDtcbiAgICBmb3IgKGxldCBpbmRleCA9IDA7IGluZGV4IDwgTjsgaW5kZXgrKykge1xuICAgICAgcmVzdWx0LnB1c2goe3g6IHRoaXMubGFiZWxzW2luZGV4XSwgeTogdGhpcy5kYXRhW2luZGV4XX0pO1xuICAgIH1cbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG5cbiAgLy8gZ3JpZGxpbmVzIGluIHggYXhpcyBmdW5jdGlvblxuICBwcml2YXRlIG1ha2VfeF9ncmlkbGluZXMoeCkge1xuICAgIHJldHVybiBkMy5heGlzQm90dG9tKHgpLnRpY2tzKHRoaXMub3B0aW9ucy5ncmlkVGlja3MpO1xuICB9XG5cbiAgLy8gZ3JpZGxpbmVzIGluIHkgYXhpcyBmdW5jdGlvblxuICBwcml2YXRlIG1ha2VfeV9ncmlkbGluZXMoeSkge1xuICAgIHJldHVybiBkMy5heGlzTGVmdCh5KS50aWNrcyh0aGlzLm9wdGlvbnMuZ3JpZFRpY2tzKTtcbiAgfVxuXG4gIG9uUmVzaXplRXZlbnQoKTogdm9pZCB7XG4gICAgdGhpcy5vblJlc2l6ZSQucGlwZShkZWJvdW5jZVRpbWUoMjAwKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgIGNvbnN0IHN2Z0V4aXN0ID0gZDMuc2VsZWN0KHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQpLnNlbGVjdCgnc3ZnJyk7XG4gICAgICBpZiAoc3ZnRXhpc3QpIHtcbiAgICAgICAgc3ZnRXhpc3QucmVtb3ZlKCk7XG4gICAgICB9XG4gICAgICB0aGlzLnJlbmRlcigpO1xuICAgIH0pO1xuICB9XG59XG4iXX0=