UNPKG

lemon-ngx-trend

Version:

ngx-trend Angular component for Lemoncloud

239 lines 30.1 kB
import * as tslib_1 from "tslib"; import { animate, keyframes, state, style, transition, trigger, } from '@angular/animations'; import { Component, ElementRef, Input, ViewChild, } from '@angular/core'; import { buildLinearPath, buildSmoothPath } from '../helpers/DOM.helpers'; import { normalize } from '../helpers/math.helpers'; import { generateId } from '../helpers/misc.helpers'; import { normalizeDataset } from './trend.helpers'; var TrendComponent = /** @class */ (function () { function TrendComponent() { this.autoDraw = false; this.autoDrawDuration = 2000; this.autoDrawEasing = 'ease'; this.padding = 8; this.radius = 10; this.stroke = 'black'; this.strokeLinecap = ''; this.strokeWidth = 1; this.gradient = []; this.svgHeight = '25%'; this.svgWidth = '100%'; // Added for Circle this.showCircle = false; this.circleColor = 'black'; this.circleWidth = 1; this.showLastLabel = false; this.labelColor = 'black'; this.animationState = ''; this.id = generateId(); this.gradientId = "ngx-trend-vertical-gradient-" + this.id; } TrendComponent.prototype.ngOnChanges = function () { var _this = this; // We need at least 2 points to draw a graph. if (!this.data || this.data.length < 2) { return; } // `data` can either be an array of numbers: // [1, 2, 3] // or, an array of objects containing a value: // [{ value: 1 }, { value: 2 }, { value: 3 }] // // For now, we're just going to convert the second form to the first. // Later on, if/when we support tooltips, we may adjust. var plainValues = this.data.map(function (point) { if (typeof point === 'number') { return point; } return point.value; }); // reset to re-run animation this.animationState = 'inactive'; // Our viewbox needs to be in absolute units, so we'll default to 300x75 // Our SVG can be a %, though; this is what makes it scalable. // By defaulting to percentages, the SVG will grow to fill its parent // container, preserving a 1/4 aspect ratio. var viewBoxWidth = this.width || 300; var viewBoxHeight = this.height || 75; this.svgWidth = this.width || '100%'; this.svgHeight = this.height || '25%'; this.viewBox = "0 0 " + viewBoxWidth + " " + viewBoxHeight; var root = location.href.split(location.hash || '#')[0]; this.pathStroke = (this.gradient && this.gradient.length) ? "url('" + root + "#" + this.gradientId + "')" : undefined; this.gradientTrimmed = this.gradient.slice().reverse().map(function (val, idx) { return { idx: idx, stopColor: val, offset: normalize(idx, 0, _this.gradient.length - 1 || 1), }; }); var normalizedValues = normalizeDataset(plainValues, this.padding, viewBoxWidth - this.padding, // NOTE: Because SVGs are indexed from the top left, but most data is // indexed from the bottom left, we're inverting the Y min/max. viewBoxHeight - this.padding, this.padding, this.minValue, this.maxValue); this.circleCoordinates = normalizedValues; this.lastLabelCoordinates = this.getLabelCoordinateOfLast(); if (this.autoDraw && this.animationState !== 'active') { this.animationState = 'inactive'; setTimeout(function () { _this.lineLength = _this.pathEl.nativeElement.getTotalLength(); _this.animationState = 'active'; }); } this.d = this.smooth ? buildSmoothPath(normalizedValues, this.radius) : buildLinearPath(normalizedValues); }; TrendComponent.prototype.getLabelCoordinateOfLast = function () { var lastIndex = this.circleCoordinates.length - 1; var _a = this.circleCoordinates[lastIndex], x = _a.x, y = _a.y; var result = { x: x, y: y + 15 }; return result; }; tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Array) ], TrendComponent.prototype, "data", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Boolean) ], TrendComponent.prototype, "smooth", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "autoDraw", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "autoDrawDuration", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "autoDrawEasing", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Number) ], TrendComponent.prototype, "width", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Number) ], TrendComponent.prototype, "height", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "padding", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "radius", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "stroke", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "strokeLinecap", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "strokeWidth", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Array) ], TrendComponent.prototype, "gradient", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", String) ], TrendComponent.prototype, "preserveAspectRatio", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "svgHeight", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "svgWidth", void 0); tslib_1.__decorate([ ViewChild('pathEl'), tslib_1.__metadata("design:type", ElementRef) ], TrendComponent.prototype, "pathEl", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "showCircle", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "circleColor", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "circleWidth", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "showLastLabel", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "labelColor", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "maxValue", void 0); tslib_1.__decorate([ Input(), tslib_1.__metadata("design:type", Object) ], TrendComponent.prototype, "minValue", void 0); TrendComponent = tslib_1.__decorate([ Component({ selector: 'ngx-trend', template: "\n <svg *ngIf=\"data && data.length >= 2\"\n [attr.width]=\"svgWidth\"\n [attr.height]=\"svgHeight\"\n [attr.stroke]=\"stroke\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.stroke-linecap]=\"strokeLinecap\"\n [attr.viewBox]=\"viewBox\"\n [attr.preserveAspectRatio]=\"preserveAspectRatio\"\n >\n <defs *ngIf=\"gradient && gradient.length\">\n <linearGradient [attr.id]=\"gradientId\" x1=\"0%\" y1=\"0%\" x2=\"0%\" y2=\"100%\">\n <stop\n *ngFor=\"let g of gradientTrimmed;\"\n [attr.key]=\"g.idx\"\n [attr.offset]=\"g.offset\"\n [attr.stop-color]=\"g.stopColor\"\n />\n </linearGradient>\n </defs>\n <path fill=\"none\" #pathEl\n [attr.stroke]=\"pathStroke\" [attr.d]=\"d\"\n [@pathAnimation]=\"{\n value: animationState,\n params: {\n autoDrawDuration: autoDrawDuration,\n autoDrawEasing: autoDrawEasing,\n lineLength: lineLength\n }\n }\" />\n <ng-container *ngIf=\"showCircle\" >\n <style>\n .small { font-size: 12px; font-weight: 400; text-anchor: end; stroke-width: 0;}\n </style>\n <ng-container *ngFor=\"let circle of circleCoordinates; index as i\">\n <circle [attr.cx]=\"circle.x\" [attr.cy]=\"circle.y\" [attr.r]=\"circleWidth\"\n [attr.fill]=\"circleColor\" [attr.stroke]=\"circleColor\"\n [attr.strokeWidth]=\"circleWidth\"\n [@circleAnimation]=\"{\n value: animationState,\n params: {\n autoDrawDuration: autoDrawDuration\n }\n }\"\n />\n <text *ngIf=\"showLastLabel && i === circleCoordinates.length - 1\"\n class=\"small\"\n [@circleAnimation]=\"{\n value: animationState,\n params: {\n autoDrawDuration: autoDrawDuration\n }\n }\"\n [attr.fill]=\"labelColor\"\n [attr.x]=\"lastLabelCoordinates.x\"\n [attr.y]=\"lastLabelCoordinates.y\">{{ data[data.length-1] | number }}</text>\n </ng-container>\n </ng-container>\n </svg>\n ", animations: [ trigger('pathAnimation', [ state('inactive', style({ display: 'none' })), transition('* => active', [ style({ display: 'initial' }), // We do the animation using the dash array/offset trick // https://css-tricks.com/svg-line-animation-works/ animate('{{ autoDrawDuration }}ms {{ autoDrawEasing }}', keyframes([ style({ 'stroke-dasharray': '{{ lineLength }}px', 'stroke-dashoffset': '{{ lineLength }}px', }), style({ 'stroke-dasharray': '{{ lineLength }}px', 'stroke-dashoffset': 0, }), ])), // One unfortunate side-effect of the auto-draw is that the line is // actually 1 big dash, the same length as the line itself. If the // line length changes (eg. radius change, new data), that dash won't // be the same length anymore. We can fix that by removing those // properties once the auto-draw is completed. style({ 'stroke-dashoffset': '', 'stroke-dasharray': '', }), ]), ]), trigger('circleAnimation', [ state('inactive', style({ visibility: 'hidden', opacity: 0 })), transition('* => active', [ style({ visibility: 'hidden' }), animate('{{ autoDrawDuration }}ms', keyframes([style({ visibility: 'visible' }), ])), ]), ]) ] }), tslib_1.__metadata("design:paramtypes", []) ], TrendComponent); return TrendComponent; }()); export { TrendComponent }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlbmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbGVtb24tbmd4LXRyZW5kLyIsInNvdXJjZXMiOlsidHJlbmQvdHJlbmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsT0FBTyxFQUNQLFNBQVMsRUFDVCxLQUFLLEVBQ0wsS0FBSyxFQUNMLFVBQVUsRUFDVixPQUFPLEdBQ1IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBRUwsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQTJHbkQ7SUFzQ0U7UUFsQ1MsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDeEIsbUJBQWMsR0FBRyxNQUFNLENBQUM7UUFHeEIsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFDWixXQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ2pCLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ25CLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLGFBQVEsR0FBYSxFQUFFLENBQUM7UUFFeEIsY0FBUyxHQUFvQixLQUFLLENBQUM7UUFDbkMsYUFBUSxHQUFvQixNQUFNLENBQUM7UUFFNUMsbUJBQW1CO1FBQ1YsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixnQkFBVyxHQUFHLE9BQU8sQ0FBQztRQUN0QixnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUNoQixrQkFBYSxHQUFHLEtBQUssQ0FBQztRQUN0QixlQUFVLEdBQUcsT0FBTyxDQUFDO1FBWTlCLG1CQUFjLEdBQUcsRUFBRSxDQUFDO1FBR2xCLElBQUksQ0FBQyxFQUFFLEdBQUcsVUFBVSxFQUFFLENBQUM7UUFDdkIsSUFBSSxDQUFDLFVBQVUsR0FBRyxpQ0FBK0IsSUFBSSxDQUFDLEVBQUksQ0FBQztJQUM3RCxDQUFDO0lBRUQsb0NBQVcsR0FBWDtRQUFBLGlCQW9FQztRQW5FQyw2Q0FBNkM7UUFDN0MsSUFBSSxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLEdBQUcsQ0FBQyxFQUFFO1lBQ3RDLE9BQU87U0FDUjtRQUVELDRDQUE0QztRQUM1QyxZQUFZO1FBQ1osOENBQThDO1FBQzlDLDZDQUE2QztRQUM3QyxFQUFFO1FBQ0YscUVBQXFFO1FBQ3JFLHdEQUF3RDtRQUN4RCxJQUFNLFdBQVcsR0FBRyxJQUFJLENBQUMsSUFBSSxDQUFDLEdBQUcsQ0FBQyxVQUFDLEtBQUs7WUFDdEMsSUFBSSxPQUFPLEtBQUssS0FBSyxRQUFRLEVBQUU7Z0JBQzdCLE9BQU8sS0FBSyxDQUFDO2FBQ2Q7WUFDRCxPQUFPLEtBQUssQ0FBQyxLQUFLLENBQUM7UUFDckIsQ0FBQyxDQUFDLENBQUM7UUFFSCw0QkFBNEI7UUFDNUIsSUFBSSxDQUFDLGNBQWMsR0FBRyxVQUFVLENBQUM7UUFFakMsd0VBQXdFO1FBQ3hFLDhEQUE4RDtRQUM5RCxxRUFBcUU7UUFDckUsNENBQTRDO1FBQzVDLElBQU0sWUFBWSxHQUFHLElBQUksQ0FBQyxLQUFLLElBQUksR0FBRyxDQUFDO1FBQ3ZDLElBQU0sYUFBYSxHQUFHLElBQUksQ0FBQyxNQUFNLElBQUksRUFBRSxDQUFDO1FBQ3hDLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLEtBQUssSUFBSSxNQUFNLENBQUM7UUFDckMsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsTUFBTSxJQUFJLEtBQUssQ0FBQztRQUN0QyxJQUFJLENBQUMsT0FBTyxHQUFHLFNBQU8sWUFBWSxTQUFJLGFBQWUsQ0FBQztRQUN0RCxJQUFNLElBQUksR0FBRyxRQUFRLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxRQUFRLENBQUMsSUFBSSxJQUFJLEdBQUcsQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO1FBQzFELElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxRQUFRLENBQUMsTUFBTSxDQUFDLENBQUMsQ0FBQyxDQUFDLFVBQVEsSUFBSSxTQUFJLElBQUksQ0FBQyxVQUFVLE9BQUksQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO1FBRTVHLElBQUksQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLFFBQVEsQ0FBQyxLQUFLLEVBQUUsQ0FBQyxPQUFPLEVBQUUsQ0FBQyxHQUFHLENBQUMsVUFBQyxHQUFHLEVBQUUsR0FBRztZQUNsRSxPQUFPO2dCQUNMLEdBQUcsS0FBQTtnQkFDSCxTQUFTLEVBQUUsR0FBRztnQkFDZCxNQUFNLEVBQUUsU0FBUyxDQUFDLEdBQUcsRUFBRSxDQUFDLEVBQUUsS0FBSSxDQUFDLFFBQVEsQ0FBQyxNQUFNLEdBQUcsQ0FBQyxJQUFJLENBQUMsQ0FBQzthQUN6RCxDQUFDO1FBQ0osQ0FBQyxDQUFDLENBQUM7UUFFSCxJQUFNLGdCQUFnQixHQUFHLGdCQUFnQixDQUFDLFdBQVcsRUFDbkQsSUFBSSxDQUFDLE9BQU8sRUFDWixZQUFZLEdBQUcsSUFBSSxDQUFDLE9BQU87UUFDM0IscUVBQXFFO1FBQ3JFLCtEQUErRDtRQUMvRCxhQUFhLEdBQUcsSUFBSSxDQUFDLE9BQU8sRUFDNUIsSUFBSSxDQUFDLE9BQU8sRUFDWixJQUFJLENBQUMsUUFBUSxFQUNiLElBQUksQ0FBQyxRQUFRLENBQ2QsQ0FBQztRQUNGLElBQUksQ0FBQyxpQkFBaUIsR0FBRyxnQkFBZ0IsQ0FBQztRQUMxQyxJQUFJLENBQUMsb0JBQW9CLEdBQUcsSUFBSSxDQUFDLHdCQUF3QixFQUFFLENBQUM7UUFHNUQsSUFBSSxJQUFJLENBQUMsUUFBUSxJQUFJLElBQUksQ0FBQyxjQUFjLEtBQUssUUFBUSxFQUFFO1lBQ3JELElBQUksQ0FBQyxjQUFjLEdBQUcsVUFBVSxDQUFDO1lBQ2pDLFVBQVUsQ0FBQztnQkFDVCxLQUFJLENBQUMsVUFBVSxHQUFHLEtBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLGNBQWMsRUFBRSxDQUFDO2dCQUM3RCxLQUFJLENBQUMsY0FBYyxHQUFHLFFBQVEsQ0FBQztZQUNqQyxDQUFDLENBQUMsQ0FBQztTQUNKO1FBRUQsSUFBSSxDQUFDLENBQUMsR0FBRyxJQUFJLENBQUMsTUFBTTtZQUNsQixDQUFDLENBQUMsZUFBZSxDQUFDLGdCQUFnQixFQUFFLElBQUksQ0FBQyxNQUFNLENBQUM7WUFDaEQsQ0FBQyxDQUFDLGVBQWUsQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0lBQ3hDLENBQUM7SUFFTyxpREFBd0IsR0FBaEM7UUFDRSxJQUFNLFNBQVMsR0FBRyxJQUFJLENBQUMsaUJBQWlCLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQztRQUM5QyxJQUFBLHNDQUE0QyxFQUExQyxRQUFDLEVBQUUsUUFBdUMsQ0FBQztRQUNuRCxJQUFNLE1BQU0sR0FBRztZQUNiLENBQUMsR0FBQTtZQUNELENBQUMsRUFBRSxDQUFDLEdBQUcsRUFBRTtTQUNWLENBQUM7UUFDRixPQUFPLE1BQU0sQ0FBQztJQUNoQixDQUFDO0lBdkhRO1FBQVIsS0FBSyxFQUFFOztnREFBb0M7SUFDbkM7UUFBUixLQUFLLEVBQUU7O2tEQUFpQjtJQUNoQjtRQUFSLEtBQUssRUFBRTs7b0RBQWtCO0lBQ2pCO1FBQVIsS0FBSyxFQUFFOzs0REFBeUI7SUFDeEI7UUFBUixLQUFLLEVBQUU7OzBEQUF5QjtJQUN4QjtRQUFSLEtBQUssRUFBRTs7aURBQWU7SUFDZDtRQUFSLEtBQUssRUFBRTs7a0RBQWdCO0lBQ2Y7UUFBUixLQUFLLEVBQUU7O21EQUFhO0lBQ1o7UUFBUixLQUFLLEVBQUU7O2tEQUFhO0lBQ1o7UUFBUixLQUFLLEVBQUU7O2tEQUFrQjtJQUNqQjtRQUFSLEtBQUssRUFBRTs7eURBQW9CO0lBQ25CO1FBQVIsS0FBSyxFQUFFOzt1REFBaUI7SUFDaEI7UUFBUixLQUFLLEVBQUU7O29EQUF5QjtJQUN4QjtRQUFSLEtBQUssRUFBRTs7K0RBQTZCO0lBQzVCO1FBQVIsS0FBSyxFQUFFOztxREFBb0M7SUFDbkM7UUFBUixLQUFLLEVBQUU7O29EQUFvQztJQUN2QjtRQUFwQixTQUFTLENBQUMsUUFBUSxDQUFDOzBDQUFTLFVBQVU7a0RBQUM7SUFFL0I7UUFBUixLQUFLLEVBQUU7O3NEQUFvQjtJQUNuQjtRQUFSLEtBQUssRUFBRTs7dURBQXVCO0lBQ3RCO1FBQVIsS0FBSyxFQUFFOzt1REFBaUI7SUFDaEI7UUFBUixLQUFLLEVBQUU7O3lEQUF1QjtJQUN0QjtRQUFSLEtBQUssRUFBRTs7c0RBQXNCO0lBQ3JCO1FBQVIsS0FBSyxFQUFFOztvREFBVTtJQUNUO1FBQVIsS0FBSyxFQUFFOztvREFBVTtJQTFCUCxjQUFjO1FBeEcxQixTQUFTLENBQUM7WUFDVCxRQUFRLEVBQUUsV0FBVztZQUNyQixRQUFRLEVBQUUseXJFQTJEVDtZQUNELFVBQVUsRUFBRTtnQkFDVixPQUFPLENBQUMsZUFBZSxFQUFFO29CQUN2QixLQUFLLENBQUMsVUFBVSxFQUFFLEtBQUssQ0FBQyxFQUFFLE9BQU8sRUFBRSxNQUFNLEVBQUUsQ0FBQyxDQUFDO29CQUM3QyxVQUFVLENBQUMsYUFBYSxFQUFFO3dCQUN4QixLQUFLLENBQUMsRUFBRSxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUM7d0JBQzdCLHdEQUF3RDt3QkFDeEQsbURBQW1EO3dCQUNuRCxPQUFPLENBQUMsK0NBQStDLEVBQ3JELFNBQVMsQ0FBQzs0QkFDUixLQUFLLENBQUM7Z0NBQ0osa0JBQWtCLEVBQUUsb0JBQW9CO2dDQUN4QyxtQkFBbUIsRUFBRSxvQkFBb0I7NkJBQzFDLENBQUM7NEJBQ0YsS0FBSyxDQUFDO2dDQUNKLGtCQUFrQixFQUFFLG9CQUFvQjtnQ0FDeEMsbUJBQW1CLEVBQUUsQ0FBQzs2QkFDdkIsQ0FBQzt5QkFDSCxDQUFDLENBQ0g7d0JBQ0QsbUVBQW1FO3dCQUNuRSxrRUFBa0U7d0JBQ2xFLHFFQUFxRTt3QkFDckUsZ0VBQWdFO3dCQUNoRSw4Q0FBOEM7d0JBQzlDLEtBQUssQ0FBQzs0QkFDSixtQkFBbUIsRUFBRSxFQUFFOzRCQUN2QixrQkFBa0IsRUFBRSxFQUFFO3lCQUN2QixDQUFDO3FCQUNILENBQUM7aUJBQ0gsQ0FBQztnQkFDRixPQUFPLENBQUMsaUJBQWlCLEVBQUU7b0JBQ3pCLEtBQUssQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDOUQsVUFBVSxDQUFDLGFBQWEsRUFBRTt3QkFDeEIsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxDQUFDO3dCQUMvQixPQUFPLENBQUMsMEJBQTBCLEVBQ2hDLFNBQVMsQ0FBQyxDQUFFLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQzt5QkFDM0MsQ0FBQyxDQUNIO3FCQUNGLENBQUM7aUJBQ0gsQ0FBQzthQUNIO1NBQ0YsQ0FBQzs7T0FDVyxjQUFjLENBMEgxQjtJQUFELHFCQUFDO0NBQUEsQUExSEQsSUEwSEM7U0ExSFksY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGFuaW1hdGUsXG4gIGtleWZyYW1lcyxcbiAgc3RhdGUsXG4gIHN0eWxlLFxuICB0cmFuc2l0aW9uLFxuICB0cmlnZ2VyLFxufSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgYnVpbGRMaW5lYXJQYXRoLCBidWlsZFNtb290aFBhdGggfSBmcm9tICcuLi9oZWxwZXJzL0RPTS5oZWxwZXJzJztcbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJy4uL2hlbHBlcnMvbWF0aC5oZWxwZXJzJztcbmltcG9ydCB7IGdlbmVyYXRlSWQgfSBmcm9tICcuLi9oZWxwZXJzL21pc2MuaGVscGVycyc7XG5pbXBvcnQgeyBub3JtYWxpemVEYXRhc2V0IH0gZnJvbSAnLi90cmVuZC5oZWxwZXJzJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtdHJlbmQnLFxuICB0ZW1wbGF0ZTogYFxuICA8c3ZnICpuZ0lmPVwiZGF0YSAmJiBkYXRhLmxlbmd0aCA+PSAyXCJcbiAgICBbYXR0ci53aWR0aF09XCJzdmdXaWR0aFwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cInN2Z0hlaWdodFwiXG4gICAgW2F0dHIuc3Ryb2tlXT1cInN0cm9rZVwiXG4gICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cInN0cm9rZVdpZHRoXCJcbiAgICBbYXR0ci5zdHJva2UtbGluZWNhcF09XCJzdHJva2VMaW5lY2FwXCJcbiAgICBbYXR0ci52aWV3Qm94XT1cInZpZXdCb3hcIlxuICAgIFthdHRyLnByZXNlcnZlQXNwZWN0UmF0aW9dPVwicHJlc2VydmVBc3BlY3RSYXRpb1wiXG4gID5cbiAgICA8ZGVmcyAqbmdJZj1cImdyYWRpZW50ICYmIGdyYWRpZW50Lmxlbmd0aFwiPlxuICAgICAgPGxpbmVhckdyYWRpZW50IFthdHRyLmlkXT1cImdyYWRpZW50SWRcIiB4MT1cIjAlXCIgeTE9XCIwJVwiIHgyPVwiMCVcIiB5Mj1cIjEwMCVcIj5cbiAgICAgICAgPHN0b3BcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgZyBvZiBncmFkaWVudFRyaW1tZWQ7XCJcbiAgICAgICAgICBbYXR0ci5rZXldPVwiZy5pZHhcIlxuICAgICAgICAgIFthdHRyLm9mZnNldF09XCJnLm9mZnNldFwiXG4gICAgICAgICAgW2F0dHIuc3RvcC1jb2xvcl09XCJnLnN0b3BDb2xvclwiXG4gICAgICAgIC8+XG4gICAgICA8L2xpbmVhckdyYWRpZW50PlxuICAgIDwvZGVmcz5cbiAgICA8cGF0aCBmaWxsPVwibm9uZVwiICNwYXRoRWxcbiAgICAgIFthdHRyLnN0cm9rZV09XCJwYXRoU3Ryb2tlXCIgW2F0dHIuZF09XCJkXCJcbiAgICAgIFtAcGF0aEFuaW1hdGlvbl09XCJ7XG4gICAgICAgIHZhbHVlOiBhbmltYXRpb25TdGF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgYXV0b0RyYXdEdXJhdGlvbjogYXV0b0RyYXdEdXJhdGlvbixcbiAgICAgICAgICBhdXRvRHJhd0Vhc2luZzogYXV0b0RyYXdFYXNpbmcsXG4gICAgICAgICAgbGluZUxlbmd0aDogbGluZUxlbmd0aFxuICAgICAgICB9XG4gICAgICB9XCIgLz5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0NpcmNsZVwiID5cbiAgICAgIDxzdHlsZT5cbiAgICAgICAgLnNtYWxsIHsgZm9udC1zaXplOiAxMnB4OyBmb250LXdlaWdodDogNDAwOyB0ZXh0LWFuY2hvcjogZW5kOyBzdHJva2Utd2lkdGg6IDA7fVxuICAgICAgPC9zdHlsZT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNpcmNsZSBvZiBjaXJjbGVDb29yZGluYXRlczsgaW5kZXggYXMgaVwiPlxuICAgICAgICA8Y2lyY2xlIFthdHRyLmN4XT1cImNpcmNsZS54XCIgW2F0dHIuY3ldPVwiY2lyY2xlLnlcIiBbYXR0ci5yXT1cImNpcmNsZVdpZHRoXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5maWxsXT1cImNpcmNsZUNvbG9yXCIgW2F0dHIuc3Ryb2tlXT1cImNpcmNsZUNvbG9yXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5zdHJva2VXaWR0aF09XCJjaXJjbGVXaWR0aFwiXG4gICAgICAgICAgICAgICAgW0BjaXJjbGVBbmltYXRpb25dPVwie1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IGFuaW1hdGlvblN0YXRlLFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9EcmF3RHVyYXRpb246IGF1dG9EcmF3RHVyYXRpb25cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgLz5cbiAgICAgICAgPHRleHQgKm5nSWY9XCJzaG93TGFzdExhYmVsICYmIGkgPT09IGNpcmNsZUNvb3JkaW5hdGVzLmxlbmd0aCAtIDFcIlxuICAgICAgICAgICAgICBjbGFzcz1cInNtYWxsXCJcbiAgICAgICAgICAgICAgW0BjaXJjbGVBbmltYXRpb25dPVwie1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IGFuaW1hdGlvblN0YXRlLFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9EcmF3RHVyYXRpb246IGF1dG9EcmF3RHVyYXRpb25cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgW2F0dHIuZmlsbF09XCJsYWJlbENvbG9yXCJcbiAgICAgICAgICAgICAgW2F0dHIueF09XCJsYXN0TGFiZWxDb29yZGluYXRlcy54XCJcbiAgICAgICAgICAgICAgW2F0dHIueV09XCJsYXN0TGFiZWxDb29yZGluYXRlcy55XCI+e3sgZGF0YVtkYXRhLmxlbmd0aC0xXSB8IG51bWJlciB9fTwvdGV4dD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3N2Zz5cbiAgYCxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ3BhdGhBbmltYXRpb24nLCBbXG4gICAgICBzdGF0ZSgnaW5hY3RpdmUnLCBzdHlsZSh7IGRpc3BsYXk6ICdub25lJyB9KSksXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IGFjdGl2ZScsIFtcbiAgICAgICAgc3R5bGUoeyBkaXNwbGF5OiAnaW5pdGlhbCcgfSksXG4gICAgICAgIC8vIFdlIGRvIHRoZSBhbmltYXRpb24gdXNpbmcgdGhlIGRhc2ggYXJyYXkvb2Zmc2V0IHRyaWNrXG4gICAgICAgIC8vIGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vc3ZnLWxpbmUtYW5pbWF0aW9uLXdvcmtzL1xuICAgICAgICBhbmltYXRlKCd7eyBhdXRvRHJhd0R1cmF0aW9uIH19bXMge3sgYXV0b0RyYXdFYXNpbmcgfX0nLFxuICAgICAgICAgIGtleWZyYW1lcyhbXG4gICAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaGFycmF5JzogJ3t7IGxpbmVMZW5ndGggfX1weCcsXG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6ICd7eyBsaW5lTGVuZ3RoIH19cHgnLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaGFycmF5JzogJ3t7IGxpbmVMZW5ndGggfX1weCcsXG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6IDAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgKSxcbiAgICAgICAgLy8gT25lIHVuZm9ydHVuYXRlIHNpZGUtZWZmZWN0IG9mIHRoZSBhdXRvLWRyYXcgaXMgdGhhdCB0aGUgbGluZSBpc1xuICAgICAgICAvLyBhY3R1YWxseSAxIGJpZyBkYXNoLCB0aGUgc2FtZSBsZW5ndGggYXMgdGhlIGxpbmUgaXRzZWxmLiBJZiB0aGVcbiAgICAgICAgLy8gbGluZSBsZW5ndGggY2hhbmdlcyAoZWcuIHJhZGl1cyBjaGFuZ2UsIG5ldyBkYXRhKSwgdGhhdCBkYXNoIHdvbid0XG4gICAgICAgIC8vIGJlIHRoZSBzYW1lIGxlbmd0aCBhbnltb3JlLiBXZSBjYW4gZml4IHRoYXQgYnkgcmVtb3ZpbmcgdGhvc2VcbiAgICAgICAgLy8gcHJvcGVydGllcyBvbmNlIHRoZSBhdXRvLWRyYXcgaXMgY29tcGxldGVkLlxuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgJ3N0cm9rZS1kYXNob2Zmc2V0JzogJycsXG4gICAgICAgICAgJ3N0cm9rZS1kYXNoYXJyYXknOiAnJyxcbiAgICAgICAgfSksXG4gICAgICBdKSxcbiAgICBdKSxcbiAgICB0cmlnZ2VyKCdjaXJjbGVBbmltYXRpb24nLCBbXG4gICAgICBzdGF0ZSgnaW5hY3RpdmUnLCBzdHlsZSh7IHZpc2liaWxpdHk6ICdoaWRkZW4nLCBvcGFjaXR5OiAwIH0pKSxcbiAgICAgIHRyYW5zaXRpb24oJyogPT4gYWN0aXZlJywgW1xuICAgICAgICBzdHlsZSh7IHZpc2liaWxpdHk6ICdoaWRkZW4nIH0pLFxuICAgICAgICBhbmltYXRlKCd7eyBhdXRvRHJhd0R1cmF0aW9uIH19bXMnLFxuICAgICAgICAgIGtleWZyYW1lcyhbIHN0eWxlKHsgdmlzaWJpbGl0eTogJ3Zpc2libGUnIH0pLFxuICAgICAgICAgIF0pLFxuICAgICAgICApLFxuICAgICAgXSksXG4gICAgXSlcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVHJlbmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBpZDogbnVtYmVyO1xuICBASW5wdXQoKSBkYXRhOiAobnVtYmVyIHwge3ZhbHVlOiBudW1iZXJ9KVtdO1xuICBASW5wdXQoKSBzbW9vdGg6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGF1dG9EcmF3ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGF1dG9EcmF3RHVyYXRpb24gPSAyMDAwO1xuICBASW5wdXQoKSBhdXRvRHJhd0Vhc2luZyA9ICdlYXNlJztcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlcjtcbiAgQElucHV0KCkgaGVpZ2h0OiBudW1iZXI7XG4gIEBJbnB1dCgpIHBhZGRpbmcgPSA4O1xuICBASW5wdXQoKSByYWRpdXMgPSAxMDtcbiAgQElucHV0KCkgc3Ryb2tlID0gJ2JsYWNrJztcbiAgQElucHV0KCkgc3Ryb2tlTGluZWNhcCA9ICcnO1xuICBASW5wdXQoKSBzdHJva2VXaWR0aCA9IDE7XG4gIEBJbnB1dCgpIGdyYWRpZW50OiBzdHJpbmdbXSA9IFtdO1xuICBASW5wdXQoKSBwcmVzZXJ2ZUFzcGVjdFJhdGlvOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN2Z0hlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gJzI1JSc7XG4gIEBJbnB1dCgpIHN2Z1dpZHRoOiBzdHJpbmcgfCBudW1iZXIgPSAnMTAwJSc7XG4gIEBWaWV3Q2hpbGQoJ3BhdGhFbCcpIHBhdGhFbDogRWxlbWVudFJlZjtcbiAgLy8gQWRkZWQgZm9yIENpcmNsZVxuICBASW5wdXQoKSBzaG93Q2lyY2xlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNpcmNsZUNvbG9yID0gJ2JsYWNrJztcbiAgQElucHV0KCkgY2lyY2xlV2lkdGggPSAxO1xuICBASW5wdXQoKSBzaG93TGFzdExhYmVsID0gZmFsc2U7XG4gIEBJbnB1dCgpIGxhYmVsQ29sb3IgPSAnYmxhY2snO1xuICBASW5wdXQoKSBtYXhWYWx1ZTtcbiAgQElucHV0KCkgbWluVmFsdWU7XG4gIGNpcmNsZUNvb3JkaW5hdGVzOiBhbnlbXTtcbiAgbGFzdExhYmVsQ29vcmRpbmF0ZXM6IHsgeDogYW55LCB5OiBhbnkgfTtcblxuICBncmFkaWVudFRyaW1tZWQ6IGFueVtdO1xuICBkOiBhbnk7XG4gIHZpZXdCb3g6IHN0cmluZztcbiAgcGF0aFN0cm9rZTogYW55O1xuICBncmFkaWVudElkOiBzdHJpbmc7XG4gIGxpbmVMZW5ndGg6IG51bWJlcjtcbiAgYW5pbWF0aW9uU3RhdGUgPSAnJztcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmlkID0gZ2VuZXJhdGVJZCgpO1xuICAgIHRoaXMuZ3JhZGllbnRJZCA9IGBuZ3gtdHJlbmQtdmVydGljYWwtZ3JhZGllbnQtJHt0aGlzLmlkfWA7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICAvLyBXZSBuZWVkIGF0IGxlYXN0IDIgcG9pbnRzIHRvIGRyYXcgYSBncmFwaC5cbiAgICBpZiAoIXRoaXMuZGF0YSB8fCB0aGlzLmRhdGEubGVuZ3RoIDwgMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGBkYXRhYCBjYW4gZWl0aGVyIGJlIGFuIGFycmF5IG9mIG51bWJlcnM6XG4gICAgLy8gWzEsIDIsIDNdXG4gICAgLy8gb3IsIGFuIGFycmF5IG9mIG9iamVjdHMgY29udGFpbmluZyBhIHZhbHVlOlxuICAgIC8vIFt7IHZhbHVlOiAxIH0sIHsgdmFsdWU6IDIgfSwgeyB2YWx1ZTogMyB9XVxuICAgIC8vXG4gICAgLy8gRm9yIG5vdywgd2UncmUganVzdCBnb2luZyB0byBjb252ZXJ0IHRoZSBzZWNvbmQgZm9ybSB0byB0aGUgZmlyc3QuXG4gICAgLy8gTGF0ZXIgb24sIGlmL3doZW4gd2Ugc3VwcG9ydCB0b29sdGlwcywgd2UgbWF5IGFkanVzdC5cbiAgICBjb25zdCBwbGFpblZhbHVlcyA9IHRoaXMuZGF0YS5tYXAoKHBvaW50KSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHBvaW50ID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gcG9pbnQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcG9pbnQudmFsdWU7XG4gICAgfSk7XG5cbiAgICAvLyByZXNldCB0byByZS1ydW4gYW5pbWF0aW9uXG4gICAgdGhpcy5hbmltYXRpb25TdGF0ZSA9ICdpbmFjdGl2ZSc7XG5cbiAgICAvLyBPdXIgdmlld2JveCBuZWVkcyB0byBiZSBpbiBhYnNvbHV0ZSB1bml0cywgc28gd2UnbGwgZGVmYXVsdCB0byAzMDB4NzVcbiAgICAvLyBPdXIgU1ZHIGNhbiBiZSBhICUsIHRob3VnaDsgdGhpcyBpcyB3aGF0IG1ha2VzIGl0IHNjYWxhYmxlLlxuICAgIC8vIEJ5IGRlZmF1bHRpbmcgdG8gcGVyY2VudGFnZXMsIHRoZSBTVkcgd2lsbCBncm93IHRvIGZpbGwgaXRzIHBhcmVudFxuICAgIC8vIGNvbnRhaW5lciwgcHJlc2VydmluZyBhIDEvNCBhc3BlY3QgcmF0aW8uXG4gICAgY29uc3Qgdmlld0JveFdpZHRoID0gdGhpcy53aWR0aCB8fCAzMDA7XG4gICAgY29uc3Qgdmlld0JveEhlaWdodCA9IHRoaXMuaGVpZ2h0IHx8IDc1O1xuICAgIHRoaXMuc3ZnV2lkdGggPSB0aGlzLndpZHRoIHx8ICcxMDAlJztcbiAgICB0aGlzLnN2Z0hlaWdodCA9IHRoaXMuaGVpZ2h0IHx8ICcyNSUnO1xuICAgIHRoaXMudmlld0JveCA9IGAwIDAgJHt2aWV3Qm94V2lkdGh9ICR7dmlld0JveEhlaWdodH1gO1xuICAgIGNvbnN0IHJvb3QgPSBsb2NhdGlvbi5ocmVmLnNwbGl0KGxvY2F0aW9uLmhhc2ggfHwgJyMnKVswXTtcbiAgICB0aGlzLnBhdGhTdHJva2UgPSAodGhpcy5ncmFkaWVudCAmJiB0aGlzLmdyYWRpZW50Lmxlbmd0aCkgPyBgdXJsKCcke3Jvb3R9IyR7dGhpcy5ncmFkaWVudElkfScpYCA6IHVuZGVmaW5lZDtcblxuICAgIHRoaXMuZ3JhZGllbnRUcmltbWVkID0gdGhpcy5ncmFkaWVudC5zbGljZSgpLnJldmVyc2UoKS5tYXAoKHZhbCwgaWR4KSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZHgsXG4gICAgICAgIHN0b3BDb2xvcjogdmFsLFxuICAgICAgICBvZmZzZXQ6IG5vcm1hbGl6ZShpZHgsIDAsIHRoaXMuZ3JhZGllbnQubGVuZ3RoIC0gMSB8fCAxKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBub3JtYWxpemVkVmFsdWVzID0gbm9ybWFsaXplRGF0YXNldChwbGFpblZhbHVlcyxcbiAgICAgIHRoaXMucGFkZGluZyxcbiAgICAgIHZpZXdCb3hXaWR0aCAtIHRoaXMucGFkZGluZyxcbiAgICAgIC8vIE5PVEU6IEJlY2F1c2UgU1ZHcyBhcmUgaW5kZXhlZCBmcm9tIHRoZSB0b3AgbGVmdCwgYnV0IG1vc3QgZGF0YSBpc1xuICAgICAgLy8gaW5kZXhlZCBmcm9tIHRoZSBib3R0b20gbGVmdCwgd2UncmUgaW52ZXJ0aW5nIHRoZSBZIG1pbi9tYXguXG4gICAgICB2aWV3Qm94SGVpZ2h0IC0gdGhpcy5wYWRkaW5nLFxuICAgICAgdGhpcy5wYWRkaW5nLFxuICAgICAgdGhpcy5taW5WYWx1ZSxcbiAgICAgIHRoaXMubWF4VmFsdWVcbiAgICApO1xuICAgIHRoaXMuY2lyY2xlQ29vcmRpbmF0ZXMgPSBub3JtYWxpemVkVmFsdWVzO1xuICAgIHRoaXMubGFzdExhYmVsQ29vcmRpbmF0ZXMgPSB0aGlzLmdldExhYmVsQ29vcmRpbmF0ZU9mTGFzdCgpO1xuXG5cbiAgICBpZiAodGhpcy5hdXRvRHJhdyAmJiB0aGlzLmFuaW1hdGlvblN0YXRlICE9PSAnYWN0aXZlJykge1xuICAgICAgdGhpcy5hbmltYXRpb25TdGF0ZSA9ICdpbmFjdGl2ZSc7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5saW5lTGVuZ3RoID0gdGhpcy5wYXRoRWwubmF0aXZlRWxlbWVudC5nZXRUb3RhbExlbmd0aCgpO1xuICAgICAgICB0aGlzLmFuaW1hdGlvblN0YXRlID0gJ2FjdGl2ZSc7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmQgPSB0aGlzLnNtb290aFxuICAgICAgPyBidWlsZFNtb290aFBhdGgobm9ybWFsaXplZFZhbHVlcywgdGhpcy5yYWRpdXMpXG4gICAgICA6IGJ1aWxkTGluZWFyUGF0aChub3JtYWxpemVkVmFsdWVzKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TGFiZWxDb29yZGluYXRlT2ZMYXN0KCkge1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IHRoaXMuY2lyY2xlQ29vcmRpbmF0ZXMubGVuZ3RoIC0gMTtcbiAgICBjb25zdCB7IHgsIHkgfSA9IHRoaXMuY2lyY2xlQ29vcmRpbmF0ZXNbbGFzdEluZGV4XTtcbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICB4LFxuICAgICAgeTogeSArIDE1XG4gICAgfTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iXX0=