lemon-ngx-trend
Version:
ngx-trend Angular component for Lemoncloud
239 lines • 30.1 kB
JavaScript
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlbmQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbGVtb24tbmd4LXRyZW5kLyIsInNvdXJjZXMiOlsidHJlbmQvdHJlbmQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQSxPQUFPLEVBQ0wsT0FBTyxFQUNQLFNBQVMsRUFDVCxLQUFLLEVBQ0wsS0FBSyxFQUNMLFVBQVUsRUFDVixPQUFPLEdBQ1IsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQ0wsU0FBUyxFQUNULFVBQVUsRUFDVixLQUFLLEVBRUwsU0FBUyxHQUNWLE1BQU0sZUFBZSxDQUFDO0FBRXZCLE9BQU8sRUFBRSxlQUFlLEVBQUUsZUFBZSxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFNBQVMsRUFBRSxNQUFNLHlCQUF5QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxVQUFVLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNyRCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQTJHbkQ7SUFzQ0U7UUFsQ1MsYUFBUSxHQUFHLEtBQUssQ0FBQztRQUNqQixxQkFBZ0IsR0FBRyxJQUFJLENBQUM7UUFDeEIsbUJBQWMsR0FBRyxNQUFNLENBQUM7UUFHeEIsWUFBTyxHQUFHLENBQUMsQ0FBQztRQUNaLFdBQU0sR0FBRyxFQUFFLENBQUM7UUFDWixXQUFNLEdBQUcsT0FBTyxDQUFDO1FBQ2pCLGtCQUFhLEdBQUcsRUFBRSxDQUFDO1FBQ25CLGdCQUFXLEdBQUcsQ0FBQyxDQUFDO1FBQ2hCLGFBQVEsR0FBYSxFQUFFLENBQUM7UUFFeEIsY0FBUyxHQUFvQixLQUFLLENBQUM7UUFDbkMsYUFBUSxHQUFvQixNQUFNLENBQUM7UUFFNUMsbUJBQW1CO1FBQ1YsZUFBVSxHQUFHLEtBQUssQ0FBQztRQUNuQixnQkFBVyxHQUFHLE9BQU8sQ0FBQztRQUN0QixnQkFBVyxHQUFHLENBQUMsQ0FBQztRQUNoQixrQkFBYSxHQUFH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SCxDQUFDLENBQ0g7d0JBQ0QsbUVBQW1FO3dCQUNuRSxrRUFBa0U7d0JBQ2xFLHFFQUFxRTt3QkFDckUsZ0VBQWdFO3dCQUNoRSw4Q0FBOEM7d0JBQzlDLEtBQUssQ0FBQzs0QkFDSixtQkFBbUIsRUFBRSxFQUFFOzRCQUN2QixrQkFBa0IsRUFBRSxFQUFFO3lCQUN2QixDQUFDO3FCQUNILENBQUM7aUJBQ0gsQ0FBQztnQkFDRixPQUFPLENBQUMsaUJBQWlCLEVBQUU7b0JBQ3pCLEtBQUssQ0FBQyxVQUFVLEVBQUUsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQztvQkFDOUQsVUFBVSxDQUFDLGFBQWEsRUFBRTt3QkFDeEIsS0FBSyxDQUFDLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxDQUFDO3dCQUMvQixPQUFPLENBQUMsMEJBQTBCLEVBQ2hDLFNBQVMsQ0FBQyxDQUFFLEtBQUssQ0FBQyxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsQ0FBQzt5QkFDM0MsQ0FBQyxDQUNIO3FCQUNGLENBQUM7aUJBQ0gsQ0FBQzthQUNIO1NBQ0YsQ0FBQzs7T0FDVyxjQUFjLENBMEgxQjtJQUFELHFCQUFDO0NBQUEsQUExSEQsSUEwSEM7U0ExSFksY0FBYyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGFuaW1hdGUsXG4gIGtleWZyYW1lcyxcbiAgc3RhdGUsXG4gIHN0eWxlLFxuICB0cmFuc2l0aW9uLFxuICB0cmlnZ2VyLFxufSBmcm9tICdAYW5ndWxhci9hbmltYXRpb25zJztcbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgRWxlbWVudFJlZixcbiAgSW5wdXQsXG4gIE9uQ2hhbmdlcyxcbiAgVmlld0NoaWxkLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuaW1wb3J0IHsgYnVpbGRMaW5lYXJQYXRoLCBidWlsZFNtb290aFBhdGggfSBmcm9tICcuLi9oZWxwZXJzL0RPTS5oZWxwZXJzJztcbmltcG9ydCB7IG5vcm1hbGl6ZSB9IGZyb20gJy4uL2hlbHBlcnMvbWF0aC5oZWxwZXJzJztcbmltcG9ydCB7IGdlbmVyYXRlSWQgfSBmcm9tICcuLi9oZWxwZXJzL21pc2MuaGVscGVycyc7XG5pbXBvcnQgeyBub3JtYWxpemVEYXRhc2V0IH0gZnJvbSAnLi90cmVuZC5oZWxwZXJzJztcblxuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICduZ3gtdHJlbmQnLFxuICB0ZW1wbGF0ZTogYFxuICA8c3ZnICpuZ0lmPVwiZGF0YSAmJiBkYXRhLmxlbmd0aCA+PSAyXCJcbiAgICBbYXR0ci53aWR0aF09XCJzdmdXaWR0aFwiXG4gICAgW2F0dHIuaGVpZ2h0XT1cInN2Z0hlaWdodFwiXG4gICAgW2F0dHIuc3Ryb2tlXT1cInN0cm9rZVwiXG4gICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cInN0cm9rZVdpZHRoXCJcbiAgICBbYXR0ci5zdHJva2UtbGluZWNhcF09XCJzdHJva2VMaW5lY2FwXCJcbiAgICBbYXR0ci52aWV3Qm94XT1cInZpZXdCb3hcIlxuICAgIFthdHRyLnByZXNlcnZlQXNwZWN0UmF0aW9dPVwicHJlc2VydmVBc3BlY3RSYXRpb1wiXG4gID5cbiAgICA8ZGVmcyAqbmdJZj1cImdyYWRpZW50ICYmIGdyYWRpZW50Lmxlbmd0aFwiPlxuICAgICAgPGxpbmVhckdyYWRpZW50IFthdHRyLmlkXT1cImdyYWRpZW50SWRcIiB4MT1cIjAlXCIgeTE9XCIwJVwiIHgyPVwiMCVcIiB5Mj1cIjEwMCVcIj5cbiAgICAgICAgPHN0b3BcbiAgICAgICAgICAqbmdGb3I9XCJsZXQgZyBvZiBncmFkaWVudFRyaW1tZWQ7XCJcbiAgICAgICAgICBbYXR0ci5rZXldPVwiZy5pZHhcIlxuICAgICAgICAgIFthdHRyLm9mZnNldF09XCJnLm9mZnNldFwiXG4gICAgICAgICAgW2F0dHIuc3RvcC1jb2xvcl09XCJnLnN0b3BDb2xvclwiXG4gICAgICAgIC8+XG4gICAgICA8L2xpbmVhckdyYWRpZW50PlxuICAgIDwvZGVmcz5cbiAgICA8cGF0aCBmaWxsPVwibm9uZVwiICNwYXRoRWxcbiAgICAgIFthdHRyLnN0cm9rZV09XCJwYXRoU3Ryb2tlXCIgW2F0dHIuZF09XCJkXCJcbiAgICAgIFtAcGF0aEFuaW1hdGlvbl09XCJ7XG4gICAgICAgIHZhbHVlOiBhbmltYXRpb25TdGF0ZSxcbiAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgYXV0b0RyYXdEdXJhdGlvbjogYXV0b0RyYXdEdXJhdGlvbixcbiAgICAgICAgICBhdXRvRHJhd0Vhc2luZzogYXV0b0RyYXdFYXNpbmcsXG4gICAgICAgICAgbGluZUxlbmd0aDogbGluZUxlbmd0aFxuICAgICAgICB9XG4gICAgICB9XCIgLz5cbiAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0NpcmNsZVwiID5cbiAgICAgIDxzdHlsZT5cbiAgICAgICAgLnNtYWxsIHsgZm9udC1zaXplOiAxMnB4OyBmb250LXdlaWdodDogNDAwOyB0ZXh0LWFuY2hvcjogZW5kOyBzdHJva2Utd2lkdGg6IDA7fVxuICAgICAgPC9zdHlsZT5cbiAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGNpcmNsZSBvZiBjaXJjbGVDb29yZGluYXRlczsgaW5kZXggYXMgaVwiPlxuICAgICAgICA8Y2lyY2xlIFthdHRyLmN4XT1cImNpcmNsZS54XCIgW2F0dHIuY3ldPVwiY2lyY2xlLnlcIiBbYXR0ci5yXT1cImNpcmNsZVdpZHRoXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5maWxsXT1cImNpcmNsZUNvbG9yXCIgW2F0dHIuc3Ryb2tlXT1cImNpcmNsZUNvbG9yXCJcbiAgICAgICAgICAgICAgICBbYXR0ci5zdHJva2VXaWR0aF09XCJjaXJjbGVXaWR0aFwiXG4gICAgICAgICAgICAgICAgW0BjaXJjbGVBbmltYXRpb25dPVwie1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IGFuaW1hdGlvblN0YXRlLFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9EcmF3RHVyYXRpb246IGF1dG9EcmF3RHVyYXRpb25cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgLz5cbiAgICAgICAgPHRleHQgKm5nSWY9XCJzaG93TGFzdExhYmVsICYmIGkgPT09IGNpcmNsZUNvb3JkaW5hdGVzLmxlbmd0aCAtIDFcIlxuICAgICAgICAgICAgICBjbGFzcz1cInNtYWxsXCJcbiAgICAgICAgICAgICAgW0BjaXJjbGVBbmltYXRpb25dPVwie1xuICAgICAgICAgICAgICAgICAgdmFsdWU6IGFuaW1hdGlvblN0YXRlLFxuICAgICAgICAgICAgICAgICAgcGFyYW1zOiB7XG4gICAgICAgICAgICAgICAgICAgIGF1dG9EcmF3RHVyYXRpb246IGF1dG9EcmF3RHVyYXRpb25cbiAgICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgW2F0dHIuZmlsbF09XCJsYWJlbENvbG9yXCJcbiAgICAgICAgICAgICAgW2F0dHIueF09XCJsYXN0TGFiZWxDb29yZGluYXRlcy54XCJcbiAgICAgICAgICAgICAgW2F0dHIueV09XCJsYXN0TGFiZWxDb29yZGluYXRlcy55XCI+e3sgZGF0YVtkYXRhLmxlbmd0aC0xXSB8IG51bWJlciB9fTwvdGV4dD5cbiAgICAgIDwvbmctY29udGFpbmVyPlxuICAgIDwvbmctY29udGFpbmVyPlxuICA8L3N2Zz5cbiAgYCxcbiAgYW5pbWF0aW9uczogW1xuICAgIHRyaWdnZXIoJ3BhdGhBbmltYXRpb24nLCBbXG4gICAgICBzdGF0ZSgnaW5hY3RpdmUnLCBzdHlsZSh7IGRpc3BsYXk6ICdub25lJyB9KSksXG4gICAgICB0cmFuc2l0aW9uKCcqID0+IGFjdGl2ZScsIFtcbiAgICAgICAgc3R5bGUoeyBkaXNwbGF5OiAnaW5pdGlhbCcgfSksXG4gICAgICAgIC8vIFdlIGRvIHRoZSBhbmltYXRpb24gdXNpbmcgdGhlIGRhc2ggYXJyYXkvb2Zmc2V0IHRyaWNrXG4gICAgICAgIC8vIGh0dHBzOi8vY3NzLXRyaWNrcy5jb20vc3ZnLWxpbmUtYW5pbWF0aW9uLXdvcmtzL1xuICAgICAgICBhbmltYXRlKCd7eyBhdXRvRHJhd0R1cmF0aW9uIH19bXMge3sgYXV0b0RyYXdFYXNpbmcgfX0nLFxuICAgICAgICAgIGtleWZyYW1lcyhbXG4gICAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaGFycmF5JzogJ3t7IGxpbmVMZW5ndGggfX1weCcsXG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6ICd7eyBsaW5lTGVuZ3RoIH19cHgnLFxuICAgICAgICAgICAgfSksXG4gICAgICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaGFycmF5JzogJ3t7IGxpbmVMZW5ndGggfX1weCcsXG4gICAgICAgICAgICAgICdzdHJva2UtZGFzaG9mZnNldCc6IDAsXG4gICAgICAgICAgICB9KSxcbiAgICAgICAgICBdKSxcbiAgICAgICAgKSxcbiAgICAgICAgLy8gT25lIHVuZm9ydHVuYXRlIHNpZGUtZWZmZWN0IG9mIHRoZSBhdXRvLWRyYXcgaXMgdGhhdCB0aGUgbGluZSBpc1xuICAgICAgICAvLyBhY3R1YWxseSAxIGJpZyBkYXNoLCB0aGUgc2FtZSBsZW5ndGggYXMgdGhlIGxpbmUgaXRzZWxmLiBJZiB0aGVcbiAgICAgICAgLy8gbGluZSBsZW5ndGggY2hhbmdlcyAoZWcuIHJhZGl1cyBjaGFuZ2UsIG5ldyBkYXRhKSwgdGhhdCBkYXNoIHdvbid0XG4gICAgICAgIC8vIGJlIHRoZSBzYW1lIGxlbmd0aCBhbnltb3JlLiBXZSBjYW4gZml4IHRoYXQgYnkgcmVtb3ZpbmcgdGhvc2VcbiAgICAgICAgLy8gcHJvcGVydGllcyBvbmNlIHRoZSBhdXRvLWRyYXcgaXMgY29tcGxldGVkLlxuICAgICAgICBzdHlsZSh7XG4gICAgICAgICAgJ3N0cm9rZS1kYXNob2Zmc2V0JzogJycsXG4gICAgICAgICAgJ3N0cm9rZS1kYXNoYXJyYXknOiAnJyxcbiAgICAgICAgfSksXG4gICAgICBdKSxcbiAgICBdKSxcbiAgICB0cmlnZ2VyKCdjaXJjbGVBbmltYXRpb24nLCBbXG4gICAgICBzdGF0ZSgnaW5hY3RpdmUnLCBzdHlsZSh7IHZpc2liaWxpdHk6ICdoaWRkZW4nLCBvcGFjaXR5OiAwIH0pKSxcbiAgICAgIHRyYW5zaXRpb24oJyogPT4gYWN0aXZlJywgW1xuICAgICAgICBzdHlsZSh7IHZpc2liaWxpdHk6ICdoaWRkZW4nIH0pLFxuICAgICAgICBhbmltYXRlKCd7eyBhdXRvRHJhd0R1cmF0aW9uIH19bXMnLFxuICAgICAgICAgIGtleWZyYW1lcyhbIHN0eWxlKHsgdmlzaWJpbGl0eTogJ3Zpc2libGUnIH0pLFxuICAgICAgICAgIF0pLFxuICAgICAgICApLFxuICAgICAgXSksXG4gICAgXSlcbiAgXSxcbn0pXG5leHBvcnQgY2xhc3MgVHJlbmRDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMge1xuICBpZDogbnVtYmVyO1xuICBASW5wdXQoKSBkYXRhOiAobnVtYmVyIHwge3ZhbHVlOiBudW1iZXJ9KVtdO1xuICBASW5wdXQoKSBzbW9vdGg6IGJvb2xlYW47XG4gIEBJbnB1dCgpIGF1dG9EcmF3ID0gZmFsc2U7XG4gIEBJbnB1dCgpIGF1dG9EcmF3RHVyYXRpb24gPSAyMDAwO1xuICBASW5wdXQoKSBhdXRvRHJhd0Vhc2luZyA9ICdlYXNlJztcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlcjtcbiAgQElucHV0KCkgaGVpZ2h0OiBudW1iZXI7XG4gIEBJbnB1dCgpIHBhZGRpbmcgPSA4O1xuICBASW5wdXQoKSByYWRpdXMgPSAxMDtcbiAgQElucHV0KCkgc3Ryb2tlID0gJ2JsYWNrJztcbiAgQElucHV0KCkgc3Ryb2tlTGluZWNhcCA9ICcnO1xuICBASW5wdXQoKSBzdHJva2VXaWR0aCA9IDE7XG4gIEBJbnB1dCgpIGdyYWRpZW50OiBzdHJpbmdbXSA9IFtdO1xuICBASW5wdXQoKSBwcmVzZXJ2ZUFzcGVjdFJhdGlvOiBzdHJpbmc7XG4gIEBJbnB1dCgpIHN2Z0hlaWdodDogc3RyaW5nIHwgbnVtYmVyID0gJzI1JSc7XG4gIEBJbnB1dCgpIHN2Z1dpZHRoOiBzdHJpbmcgfCBudW1iZXIgPSAnMTAwJSc7XG4gIEBWaWV3Q2hpbGQoJ3BhdGhFbCcpIHBhdGhFbDogRWxlbWVudFJlZjtcbiAgLy8gQWRkZWQgZm9yIENpcmNsZVxuICBASW5wdXQoKSBzaG93Q2lyY2xlID0gZmFsc2U7XG4gIEBJbnB1dCgpIGNpcmNsZUNvbG9yID0gJ2JsYWNrJztcbiAgQElucHV0KCkgY2lyY2xlV2lkdGggPSAxO1xuICBASW5wdXQoKSBzaG93TGFzdExhYmVsID0gZmFsc2U7XG4gIEBJbnB1dCgpIGxhYmVsQ29sb3IgPSAnYmxhY2snO1xuICBASW5wdXQoKSBtYXhWYWx1ZTtcbiAgQElucHV0KCkgbWluVmFsdWU7XG4gIGNpcmNsZUNvb3JkaW5hdGVzOiBhbnlbXTtcbiAgbGFzdExhYmVsQ29vcmRpbmF0ZXM6IHsgeDogYW55LCB5OiBhbnkgfTtcblxuICBncmFkaWVudFRyaW1tZWQ6IGFueVtdO1xuICBkOiBhbnk7XG4gIHZpZXdCb3g6IHN0cmluZztcbiAgcGF0aFN0cm9rZTogYW55O1xuICBncmFkaWVudElkOiBzdHJpbmc7XG4gIGxpbmVMZW5ndGg6IG51bWJlcjtcbiAgYW5pbWF0aW9uU3RhdGUgPSAnJztcblxuICBjb25zdHJ1Y3RvcigpIHtcbiAgICB0aGlzLmlkID0gZ2VuZXJhdGVJZCgpO1xuICAgIHRoaXMuZ3JhZGllbnRJZCA9IGBuZ3gtdHJlbmQtdmVydGljYWwtZ3JhZGllbnQtJHt0aGlzLmlkfWA7XG4gIH1cblxuICBuZ09uQ2hhbmdlcygpIHtcbiAgICAvLyBXZSBuZWVkIGF0IGxlYXN0IDIgcG9pbnRzIHRvIGRyYXcgYSBncmFwaC5cbiAgICBpZiAoIXRoaXMuZGF0YSB8fCB0aGlzLmRhdGEubGVuZ3RoIDwgMikge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIC8vIGBkYXRhYCBjYW4gZWl0aGVyIGJlIGFuIGFycmF5IG9mIG51bWJlcnM6XG4gICAgLy8gWzEsIDIsIDNdXG4gICAgLy8gb3IsIGFuIGFycmF5IG9mIG9iamVjdHMgY29udGFpbmluZyBhIHZhbHVlOlxuICAgIC8vIFt7IHZhbHVlOiAxIH0sIHsgdmFsdWU6IDIgfSwgeyB2YWx1ZTogMyB9XVxuICAgIC8vXG4gICAgLy8gRm9yIG5vdywgd2UncmUganVzdCBnb2luZyB0byBjb252ZXJ0IHRoZSBzZWNvbmQgZm9ybSB0byB0aGUgZmlyc3QuXG4gICAgLy8gTGF0ZXIgb24sIGlmL3doZW4gd2Ugc3VwcG9ydCB0b29sdGlwcywgd2UgbWF5IGFkanVzdC5cbiAgICBjb25zdCBwbGFpblZhbHVlcyA9IHRoaXMuZGF0YS5tYXAoKHBvaW50KSA9PiB7XG4gICAgICBpZiAodHlwZW9mIHBvaW50ID09PSAnbnVtYmVyJykge1xuICAgICAgICByZXR1cm4gcG9pbnQ7XG4gICAgICB9XG4gICAgICByZXR1cm4gcG9pbnQudmFsdWU7XG4gICAgfSk7XG5cbiAgICAvLyByZXNldCB0byByZS1ydW4gYW5pbWF0aW9uXG4gICAgdGhpcy5hbmltYXRpb25TdGF0ZSA9ICdpbmFjdGl2ZSc7XG5cbiAgICAvLyBPdXIgdmlld2JveCBuZWVkcyB0byBiZSBpbiBhYnNvbHV0ZSB1bml0cywgc28gd2UnbGwgZGVmYXVsdCB0byAzMDB4NzVcbiAgICAvLyBPdXIgU1ZHIGNhbiBiZSBhICUsIHRob3VnaDsgdGhpcyBpcyB3aGF0IG1ha2VzIGl0IHNjYWxhYmxlLlxuICAgIC8vIEJ5IGRlZmF1bHRpbmcgdG8gcGVyY2VudGFnZXMsIHRoZSBTVkcgd2lsbCBncm93IHRvIGZpbGwgaXRzIHBhcmVudFxuICAgIC8vIGNvbnRhaW5lciwgcHJlc2VydmluZyBhIDEvNCBhc3BlY3QgcmF0aW8uXG4gICAgY29uc3Qgdmlld0JveFdpZHRoID0gdGhpcy53aWR0aCB8fCAzMDA7XG4gICAgY29uc3Qgdmlld0JveEhlaWdodCA9IHRoaXMuaGVpZ2h0IHx8IDc1O1xuICAgIHRoaXMuc3ZnV2lkdGggPSB0aGlzLndpZHRoIHx8ICcxMDAlJztcbiAgICB0aGlzLnN2Z0hlaWdodCA9IHRoaXMuaGVpZ2h0IHx8ICcyNSUnO1xuICAgIHRoaXMudmlld0JveCA9IGAwIDAgJHt2aWV3Qm94V2lkdGh9ICR7dmlld0JveEhlaWdodH1gO1xuICAgIGNvbnN0IHJvb3QgPSBsb2NhdGlvbi5ocmVmLnNwbGl0KGxvY2F0aW9uLmhhc2ggfHwgJyMnKVswXTtcbiAgICB0aGlzLnBhdGhTdHJva2UgPSAodGhpcy5ncmFkaWVudCAmJiB0aGlzLmdyYWRpZW50Lmxlbmd0aCkgPyBgdXJsKCcke3Jvb3R9IyR7dGhpcy5ncmFkaWVudElkfScpYCA6IHVuZGVmaW5lZDtcblxuICAgIHRoaXMuZ3JhZGllbnRUcmltbWVkID0gdGhpcy5ncmFkaWVudC5zbGljZSgpLnJldmVyc2UoKS5tYXAoKHZhbCwgaWR4KSA9PiB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBpZHgsXG4gICAgICAgIHN0b3BDb2xvcjogdmFsLFxuICAgICAgICBvZmZzZXQ6IG5vcm1hbGl6ZShpZHgsIDAsIHRoaXMuZ3JhZGllbnQubGVuZ3RoIC0gMSB8fCAxKSxcbiAgICAgIH07XG4gICAgfSk7XG5cbiAgICBjb25zdCBub3JtYWxpemVkVmFsdWVzID0gbm9ybWFsaXplRGF0YXNldChwbGFpblZhbHVlcyxcbiAgICAgIHRoaXMucGFkZGluZyxcbiAgICAgIHZpZXdCb3hXaWR0aCAtIHRoaXMucGFkZGluZyxcbiAgICAgIC8vIE5PVEU6IEJlY2F1c2UgU1ZHcyBhcmUgaW5kZXhlZCBmcm9tIHRoZSB0b3AgbGVmdCwgYnV0IG1vc3QgZGF0YSBpc1xuICAgICAgLy8gaW5kZXhlZCBmcm9tIHRoZSBib3R0b20gbGVmdCwgd2UncmUgaW52ZXJ0aW5nIHRoZSBZIG1pbi9tYXguXG4gICAgICB2aWV3Qm94SGVpZ2h0IC0gdGhpcy5wYWRkaW5nLFxuICAgICAgdGhpcy5wYWRkaW5nLFxuICAgICAgdGhpcy5taW5WYWx1ZSxcbiAgICAgIHRoaXMubWF4VmFsdWVcbiAgICApO1xuICAgIHRoaXMuY2lyY2xlQ29vcmRpbmF0ZXMgPSBub3JtYWxpemVkVmFsdWVzO1xuICAgIHRoaXMubGFzdExhYmVsQ29vcmRpbmF0ZXMgPSB0aGlzLmdldExhYmVsQ29vcmRpbmF0ZU9mTGFzdCgpO1xuXG5cbiAgICBpZiAodGhpcy5hdXRvRHJhdyAmJiB0aGlzLmFuaW1hdGlvblN0YXRlICE9PSAnYWN0aXZlJykge1xuICAgICAgdGhpcy5hbmltYXRpb25TdGF0ZSA9ICdpbmFjdGl2ZSc7XG4gICAgICBzZXRUaW1lb3V0KCgpID0+IHtcbiAgICAgICAgdGhpcy5saW5lTGVuZ3RoID0gdGhpcy5wYXRoRWwubmF0aXZlRWxlbWVudC5nZXRUb3RhbExlbmd0aCgpO1xuICAgICAgICB0aGlzLmFuaW1hdGlvblN0YXRlID0gJ2FjdGl2ZSc7XG4gICAgICB9KTtcbiAgICB9XG5cbiAgICB0aGlzLmQgPSB0aGlzLnNtb290aFxuICAgICAgPyBidWlsZFNtb290aFBhdGgobm9ybWFsaXplZFZhbHVlcywgdGhpcy5yYWRpdXMpXG4gICAgICA6IGJ1aWxkTGluZWFyUGF0aChub3JtYWxpemVkVmFsdWVzKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0TGFiZWxDb29yZGluYXRlT2ZMYXN0KCkge1xuICAgIGNvbnN0IGxhc3RJbmRleCA9IHRoaXMuY2lyY2xlQ29vcmRpbmF0ZXMubGVuZ3RoIC0gMTtcbiAgICBjb25zdCB7IHgsIHkgfSA9IHRoaXMuY2lyY2xlQ29vcmRpbmF0ZXNbbGFzdEluZGV4XTtcbiAgICBjb25zdCByZXN1bHQgPSB7XG4gICAgICB4LFxuICAgICAgeTogeSArIDE1XG4gICAgfTtcbiAgICByZXR1cm4gcmVzdWx0O1xuICB9XG59XG4iXX0=