UNPKG

ngx-beautiful-charts

Version:
354 lines 34.3 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; import { Component, Input, ElementRef } from '@angular/core'; import { colorSchemes } from '../../constants/color-schemes'; import { TimelineChartService } from './timeline-chart.service'; import { GlobalParametersService } from '../../global/global-parameters.service'; var TimelineChartComponent = /** @class */ (function () { function TimelineChartComponent(timelineChartService, globalParametersService, currentElement) { this.timelineChartService = timelineChartService; this.globalParametersService = globalParametersService; this.currentElement = currentElement; this.colorScheme = 'colorful'; this.customColorScheme = []; this.xPadding = 60; this.yPadding = this.xPadding / 2; this.timeData = []; } /** * @return {?} */ TimelineChartComponent.prototype.computeBarDimensions = /** * @return {?} */ function () { this.barWidth = this.timelineChartService.rectHeight * .05; this.barStartY = this.yPadding + this.timelineChartService.rectHeight / 2 - this.barWidth / 2; this.barEndY = this.yPadding + this.timelineChartService.rectHeight / 2 + this.barWidth / 2; }; /** * @return {?} */ TimelineChartComponent.prototype.setColors = /** * @return {?} */ function () { var e_1, _a; /** @type {?} */ var cnt = 0; try { for (var _b = tslib_1.__values(this.data), _c = _b.next(); !_c.done; _c = _b.next()) { var oneTimeData = _c.value; if (!oneTimeData.color) { if (this.customColorScheme.length > 0) { oneTimeData.color = this.customColorScheme[cnt % this.customColorScheme.length]; } else { oneTimeData.color = colorSchemes[this.colorScheme][cnt % 10]; } cnt++; } } } catch (e_1_1) { e_1 = { error: e_1_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_1) throw e_1.error; } } }; /** * @return {?} */ TimelineChartComponent.prototype.setDimensions = /** * @return {?} */ function () { if (this.width && !this.height) this.height = this.width / 2; else if (!this.width && this.height) this.width = this.height * 2; else if (!this.width && !this.height) { /** @type {?} */ var host = this.currentElement.nativeElement; if (host.parentNode != null) { /** @type {?} */ var dims = host.parentNode.getBoundingClientRect(); this.width = dims.width; this.height = dims.width / 2; } } // console.log('---set dimensions---'); // console.log('width: ' + this.width); // console.log('height: ' + this.height); // console.log('--------------------'); }; /** * @param {?} text * @param {?} width * @return {?} */ TimelineChartComponent.prototype.textWrap = /** * @param {?} text * @param {?} width * @return {?} */ function (text, width) { /** @type {?} */ var noOfCharactersPerLine = width / 10; /** @type {?} */ var newLineStr = '\n'; /** @type {?} */ var done = false; /** @type {?} */ var res = []; do { /** @type {?} */ var found = false; for (var i = noOfCharactersPerLine - 1; i >= 0; i--) { if ((text.charAt(i) === ' ')) { res.push([text.slice(0, i), newLineStr].join('')); text = text.slice(i + 1); found = true; break; } } if (!found) { res.push([text.slice(0, noOfCharactersPerLine), newLineStr].join('')); text = text.slice(noOfCharactersPerLine); } if (text.length < noOfCharactersPerLine) done = true; } while (!done); res.push(text); return res; }; /** * @return {?} */ TimelineChartComponent.prototype.computeTimeData = /** * @return {?} */ function () { var e_2, _a; // const distanceBetweenTimeBubbles = this.width * .8 / (this.data.length - 1); /** @type {?} */ var minTime = Math.min.apply(Math, tslib_1.__spread(this.data.map((/** * @param {?} timeData * @return {?} */ function (timeData) { return timeData.time; })))); /** @type {?} */ var maxTime = Math.max.apply(Math, tslib_1.__spread(this.data.map((/** * @param {?} timeData * @return {?} */ function (timeData) { return timeData.time; })))); /** @type {?} */ var perTimeWidth = this.timelineChartService.rectWidth * .8 / (maxTime - minTime); this.data.sort((/** * @param {?} a * @param {?} b * @return {?} */ function (a, b) { return a.time < b.time ? -1 : a.time > b.time ? 1 : 0; })); /** @type {?} */ var diffs = []; for (var i = 1; i < this.data.length; i++) { diffs.push(this.data[i].time - this.data[i - 1].time); } /** @type {?} */ var minDiff = Math.min.apply(Math, tslib_1.__spread(diffs)); this.timeBubbleRadius = Math.min(minDiff * perTimeWidth * .4); /** @type {?} */ var maxRadius = this.timelineChartService.rectWidth * .8 / (this.data.length - 1) * .25; /** @type {?} */ var minRadius = this.timelineChartService.rectWidth * .8 * .04; // console.log('max: ' + maxRadius); // console.log('min: ' + minRadius); if (this.timeBubbleRadius > maxRadius) this.timeBubbleRadius = maxRadius; if (this.timeBubbleRadius < minRadius) this.timeBubbleRadius = minRadius; this.textBlockHeight = this.timelineChartService.rectHeight * 2 / 16; this.timeData = []; /** @type {?} */ var cnt = 0; /** @type {?} */ var up = 1; try { for (var _b = tslib_1.__values(this.data), _c = _b.next(); !_c.done; _c = _b.next()) { var oneTimeData = _c.value; /** @type {?} */ var color = oneTimeData.color; /** @type {?} */ var x = (oneTimeData.time - minTime) * perTimeWidth; /** @type {?} */ var timeBubble = { centre: { x: x, y: this.barStartY + this.barWidth / 2 }, text: oneTimeData.displayTime ? oneTimeData.displayTime : oneTimeData.time // oneTimeData.displayTime ? // this.textWrap(oneTimeData.displayTime, this.timeBubbleRadius * 2) : // [oneTimeData.time] }; /** @type {?} */ var start = { x: x, y: (up === 1) ? this.barStartY : this.barEndY }; /** @type {?} */ var end = { x: x, y: (up === 1) ? this.barStartY - this.timelineChartService.rectHeight / 4 : this.barEndY + this.timelineChartService.rectHeight / 4 }; /** @type {?} */ var line = 'M ' + start.x + ' ' + start.y + ' ' + end.x + ' ' + end.y; /** @type {?} */ var textBlock = { position: { x: x, y: (up === 1) ? this.barStartY - this.timelineChartService.rectHeight * 7 / 16 : this.barEndY + this.timelineChartService.rectHeight * 4 / 16 }, text: this.textWrap(oneTimeData.text, this.timeBubbleRadius * 4) }; this.timeData.push({ timeBubble: timeBubble, line: line, textBlock: textBlock, color: color }); up = up * -1; cnt++; } } catch (e_2_1) { e_2 = { error: e_2_1 }; } finally { try { if (_c && !_c.done && (_a = _b.return)) _a.call(_b); } finally { if (e_2) throw e_2.error; } } }; /** * @return {?} */ TimelineChartComponent.prototype.ngOnInit = /** * @return {?} */ function () { this.componentID = this.globalParametersService.addNewComponent(); this.computeBarDimensions(); this.setColors(); this.timelineChartService.setValues({ componentID: this.componentID, width: this.width, height: this.height, xPadding: this.xPadding, yPadding: this.yPadding }); /** @type {?} */ var transX = this.xPadding + this.timelineChartService.rectWidth * .1; this.gTranslate = 'translate(' + transX + 'px, ' + this.yPadding + 'px)'; this.computeBarDimensions(); this.computeTimeData(); }; /** * @return {?} */ TimelineChartComponent.prototype.ngOnChanges = /** * @return {?} */ function () { this.computeBarDimensions(); this.setColors(); this.timelineChartService.setValues({ componentID: this.componentID, width: this.width, height: this.height, xPadding: this.xPadding, yPadding: this.yPadding }); /** @type {?} */ var transX = this.xPadding + this.timelineChartService.rectWidth * .1; this.gTranslate = 'translate(' + transX + 'px, ' + this.yPadding + 'px)'; this.computeBarDimensions(); this.computeTimeData(); }; TimelineChartComponent.decorators = [ { type: Component, args: [{ selector: 'ngx-timeline-chart', template: "<svg [attr.width]=\"width\" [attr.height]=\"height\" version=\"1.1\" xmlns=\"http://www.w3.org/2000/svg\">\n <g [ngStyle]=\"{'transform': gTranslate}\">\n <rect x=\"0\" \n [attr.y]=\"barStartY\" \n [attr.width]=\"timelineChartService.rectWidth * .8\" \n [attr.height]=\"barWidth\" \n fill=\"grey\" />\n\n <g *ngFor=\"let timeDataInst of timeData\">\n <circle class=\"time-bubble\" [attr.cx]=\"timeDataInst.timeBubble.centre.x\" \n [attr.cy]=\"timeDataInst.timeBubble.centre.y\" \n [attr.r]=\"timeBubbleRadius\" [attr.fill]=\"timeDataInst.color\">\n </circle>\n\n <text class=\"time-bubble-text\" [attr.x]=\"timeDataInst.timeBubble.centre.x\"\n [attr.y]=\"timeDataInst.timeBubble.centre.y\"\n text-anchor=\"middle\" dominant-baseline=\"middle\">\n {{ timeDataInst.timeBubble.text }}\n <!-- <tspan *ngFor=\"let line of timeDataInst.timeBubble.text\" \n [attr.x]=\"timeDataInst.timeBubble.centre.x\"\n [attr.dx]=\"0\"\n [attr.dy]=\"14\">\n {{ line }}\n </tspan> -->\n </text>\n \n <path class=\"line-path\"\n [attr.d]=\"timeDataInst.line\" fill=\"none\" [attr.stroke]=\"timeDataInst.color\" />\n\n <text class=\"time-block-text\" [attr.x]=\"timeDataInst.textBlock.position.x\"\n [attr.y]=\"timeDataInst.textBlock.position.y\"\n [attr.height]=\"textBlockHeight\"\n text-anchor=\"middle\" dominant-baseline=\"middle\">\n <tspan *ngFor=\"let line of timeDataInst.textBlock.text\" \n [attr.x]=\"timeDataInst.textBlock.position.x\"\n [attr.dx]=\"0\"\n [attr.dy]=\"14\">\n {{ line }}\n </tspan>\n </text>\n\n </g>\n </g>\n</svg>\n\n", providers: [TimelineChartService], styles: [".time-bubble-text{font-size:12px}"] }] } ]; /** @nocollapse */ TimelineChartComponent.ctorParameters = function () { return [ { type: TimelineChartService }, { type: GlobalParametersService }, { type: ElementRef } ]; }; TimelineChartComponent.propDecorators = { data: [{ type: Input }], width: [{ type: Input }], height: [{ type: Input }], colorScheme: [{ type: Input }], customColorScheme: [{ type: Input }] }; return TimelineChartComponent; }()); export { TimelineChartComponent }; if (false) { /** @type {?} */ TimelineChartComponent.prototype.data; /** @type {?} */ TimelineChartComponent.prototype.width; /** @type {?} */ TimelineChartComponent.prototype.height; /** @type {?} */ TimelineChartComponent.prototype.colorScheme; /** @type {?} */ TimelineChartComponent.prototype.customColorScheme; /** @type {?} */ TimelineChartComponent.prototype.componentID; /** @type {?} */ TimelineChartComponent.prototype.xPadding; /** @type {?} */ TimelineChartComponent.prototype.yPadding; /** @type {?} */ TimelineChartComponent.prototype.gTranslate; /** @type {?} */ TimelineChartComponent.prototype.barWidth; /** @type {?} */ TimelineChartComponent.prototype.barStartY; /** @type {?} */ TimelineChartComponent.prototype.barEndY; /** @type {?} */ TimelineChartComponent.prototype.timeBubbleRadius; /** @type {?} */ TimelineChartComponent.prototype.textBlockHeight; /** @type {?} */ TimelineChartComponent.prototype.timeData; /** @type {?} */ TimelineChartComponent.prototype.timelineChartService; /** * @type {?} * @private */ TimelineChartComponent.prototype.globalParametersService; /** * @type {?} * @private */ TimelineChartComponent.prototype.currentElement; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGltZWxpbmUtY2hhcnQuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmd4LWJlYXV0aWZ1bC1jaGFydHMvIiwic291cmNlcyI6WyJsaWIvdGltZWxpbmUtY2hhcnQvdGltZWxpbmUtY2hhcnQuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUFFLFNBQVMsRUFBVSxLQUFLLEVBQWEsVUFBVSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQ2hGLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwrQkFBK0IsQ0FBQztBQUM3RCxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSwwQkFBMEIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSx3Q0FBd0MsQ0FBQztBQUVqRjtJQWdLRSxnQ0FBbUIsb0JBQTBDLEVBQ3pDLHVCQUFnRCxFQUNoRCxjQUEwQjtRQUYzQix5QkFBb0IsR0FBcEIsb0JBQW9CLENBQXNCO1FBQ3pDLDRCQUF1QixHQUF2Qix1QkFBdUIsQ0FBeUI7UUFDaEQsbUJBQWMsR0FBZCxjQUFjLENBQVk7UUF2SnJDLGdCQUFXLEdBQUcsVUFBVSxDQUFDO1FBQ3pCLHNCQUFpQixHQUFhLEVBQUUsQ0FBQztRQUkxQyxhQUFRLEdBQUcsRUFBRSxDQUFDO1FBQ2QsYUFBUSxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBUzdCLGFBQVEsR0FBRyxFQUFFLENBQUM7SUF5SWQsQ0FBQzs7OztJQXJJRCxxREFBb0I7OztJQUFwQjtRQUNFLElBQUksQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLG9CQUFvQixDQUFDLFVBQVUsR0FBRyxHQUFHLENBQUM7UUFDM0QsSUFBSSxDQUFDLFNBQVMsR0FBRyxJQUFJLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQyxvQkFBb0IsQ0FBQyxVQUFVLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxRQUFRLEdBQUcsQ0FBQyxDQUFDO1FBQzlGLElBQUks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REFBOEM7b0JBRTlDLFNBQVMsRUFBRSxDQUFDLG9CQUFvQixDQUFDOztpQkFDbEM7Ozs7Z0JBUlEsb0JBQW9CO2dCQUNwQix1QkFBdUI7Z0JBSGMsVUFBVTs7O3VCQWFyRCxLQUFLO3dCQUNMLEtBQUs7eUJBQ0wsS0FBSzs4QkFDTCxLQUFLO29DQUNMLEtBQUs7O0lBeUxSLDZCQUFDO0NBQUEsQUFyTUQsSUFxTUM7U0EvTFksc0JBQXNCOzs7SUFFakMsc0NBQW1COztJQUNuQix1Q0FBdUI7O0lBQ3ZCLHdDQUF3Qjs7SUFDeEIsNkNBQWtDOztJQUNsQyxtREFBMEM7O0lBRzFDLDZDQUFZOztJQUNaLDBDQUFjOztJQUNkLDBDQUE2Qjs7SUFDN0IsNENBQW1COztJQUVuQiwwQ0FBaUI7O0lBQ2pCLDJDQUFrQjs7SUFDbEIseUNBQWdCOztJQUVoQixrREFBeUI7O0lBQ3pCLGlEQUF3Qjs7SUFDeEIsMENBQWM7O0lBc0lGLHNEQUFpRDs7Ozs7SUFDakQseURBQXdEOzs7OztJQUN4RCxnREFBa0MiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIE9uSW5pdCwgSW5wdXQsIE9uQ2hhbmdlcywgRWxlbWVudFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgY29sb3JTY2hlbWVzIH0gZnJvbSAnLi4vLi4vY29uc3RhbnRzL2NvbG9yLXNjaGVtZXMnO1xuaW1wb3J0IHsgVGltZWxpbmVDaGFydFNlcnZpY2UgfSBmcm9tICcuL3RpbWVsaW5lLWNoYXJ0LnNlcnZpY2UnO1xuaW1wb3J0IHsgR2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UgfSBmcm9tICcuLi8uLi9nbG9iYWwvZ2xvYmFsLXBhcmFtZXRlcnMuc2VydmljZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ25neC10aW1lbGluZS1jaGFydCcsXG4gIHRlbXBsYXRlVXJsOiAnLi90aW1lbGluZS1jaGFydC5jb21wb25lbnQuaHRtbCcsXG4gIHN0eWxlVXJsczogWycuL3RpbWVsaW5lLWNoYXJ0LmNvbXBvbmVudC5zY3NzJ10sXG4gIHByb3ZpZGVyczogW1RpbWVsaW5lQ2hhcnRTZXJ2aWNlXVxufSlcbmV4cG9ydCBjbGFzcyBUaW1lbGluZUNoYXJ0Q29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMge1xuXG4gIEBJbnB1dCgpIGRhdGE6IGFueTtcbiAgQElucHV0KCkgd2lkdGg6IG51bWJlcjtcbiAgQElucHV0KCkgaGVpZ2h0OiBudW1iZXI7XG4gIEBJbnB1dCgpIGNvbG9yU2NoZW1lID0gJ2NvbG9yZnVsJztcbiAgQElucHV0KCkgY3VzdG9tQ29sb3JTY2hlbWU6IHN0cmluZ1tdID0gW107XG5cblxuICBjb21wb25lbnRJRDtcbiAgeFBhZGRpbmcgPSA2MDtcbiAgeVBhZGRpbmcgPSB0aGlzLnhQYWRkaW5nIC8gMjtcbiAgZ1RyYW5zbGF0ZTogc3RyaW5nO1xuXG4gIGJhcldpZHRoOiBudW1iZXI7XG4gIGJhclN0YXJ0WTogbnVtYmVyO1xuICBiYXJFbmRZOiBudW1iZXI7XG5cbiAgdGltZUJ1YmJsZVJhZGl1czogbnVtYmVyO1xuICB0ZXh0QmxvY2tIZWlnaHQ6IG51bWJlcjtcbiAgdGltZURhdGEgPSBbXTtcblxuXG5cbiAgY29tcHV0ZUJhckRpbWVuc2lvbnMoKSB7XG4gICAgdGhpcy5iYXJXaWR0aCA9IHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2UucmVjdEhlaWdodCAqIC4wNTtcbiAgICB0aGlzLmJhclN0YXJ0WSA9IHRoaXMueVBhZGRpbmcgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RIZWlnaHQgLyAyIC0gdGhpcy5iYXJXaWR0aCAvIDI7XG4gICAgdGhpcy5iYXJFbmRZID0gdGhpcy55UGFkZGluZyArIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2UucmVjdEhlaWdodCAvIDIgKyB0aGlzLmJhcldpZHRoIC8gMjtcbiAgfVxuXG4gIHNldENvbG9ycygpIHtcbiAgICBsZXQgY250ID0gMDtcbiAgICBmb3IgKGNvbnN0IG9uZVRpbWVEYXRhIG9mIHRoaXMuZGF0YSkge1xuICAgICAgaWYgKCFvbmVUaW1lRGF0YS5jb2xvcikge1xuICAgICAgICBpZiAodGhpcy5jdXN0b21Db2xvclNjaGVtZS5sZW5ndGggPiAwKSB7XG4gICAgICAgICAgb25lVGltZURhdGEuY29sb3IgPSB0aGlzLmN1c3RvbUNvbG9yU2NoZW1lW2NudCAlIHRoaXMuY3VzdG9tQ29sb3JTY2hlbWUubGVuZ3RoXTtcbiAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICBvbmVUaW1lRGF0YS5jb2xvciA9IGNvbG9yU2NoZW1lc1t0aGlzLmNvbG9yU2NoZW1lXVtjbnQgJSAxMF07XG4gICAgICAgIH1cbiAgICAgICAgY250Kys7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgc2V0RGltZW5zaW9ucygpIHtcbiAgICBpZiAodGhpcy53aWR0aCAmJiAhdGhpcy5oZWlnaHQpIHRoaXMuaGVpZ2h0ID0gdGhpcy53aWR0aCAvIDI7XG4gICAgZWxzZSBpZiAoIXRoaXMud2lkdGggJiYgdGhpcy5oZWlnaHQpIHRoaXMud2lkdGggPSB0aGlzLmhlaWdodCAqIDI7XG4gICAgZWxzZSBpZiAoIXRoaXMud2lkdGggJiYgIXRoaXMuaGVpZ2h0KSB7XG4gICAgICBjb25zdCBob3N0ID0gdGhpcy5jdXJyZW50RWxlbWVudC5uYXRpdmVFbGVtZW50O1xuICAgICAgaWYgKGhvc3QucGFyZW50Tm9kZSAhPSBudWxsKSB7XG4gICAgICAgIGNvbnN0IGRpbXMgPSBob3N0LnBhcmVudE5vZGUuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICAgIHRoaXMud2lkdGggPSBkaW1zLndpZHRoO1xuICAgICAgICB0aGlzLmhlaWdodCA9IGRpbXMud2lkdGggLyAyO1xuICAgICAgfVxuICAgIH1cbiAgICAvLyBjb25zb2xlLmxvZygnLS0tc2V0IGRpbWVuc2lvbnMtLS0nKTtcbiAgICAvLyBjb25zb2xlLmxvZygnd2lkdGg6ICcgKyB0aGlzLndpZHRoKTtcbiAgICAvLyBjb25zb2xlLmxvZygnaGVpZ2h0OiAnICsgdGhpcy5oZWlnaHQpO1xuICAgIC8vIGNvbnNvbGUubG9nKCctLS0tLS0tLS0tLS0tLS0tLS0tLScpO1xuICB9XG5cbiAgdGV4dFdyYXAodGV4dCwgd2lkdGgpIHtcbiAgICBjb25zdCBub09mQ2hhcmFjdGVyc1BlckxpbmUgPSB3aWR0aCAvIDEwO1xuICAgIGNvbnN0IG5ld0xpbmVTdHIgPSAnXFxuJztcbiAgICBsZXQgZG9uZSA9IGZhbHNlO1xuICAgIGNvbnN0IHJlcyA9IFtdO1xuICAgIGRvIHtcbiAgICAgIGxldCBmb3VuZCA9IGZhbHNlO1xuICAgICAgZm9yIChsZXQgaSA9IG5vT2ZDaGFyYWN0ZXJzUGVyTGluZSAtIDE7IGkgPj0gMDsgaS0tKSB7XG4gICAgICAgICAgaWYgKCh0ZXh0LmNoYXJBdChpKSAgPT09ICcgJykpIHtcbiAgICAgICAgICAgICAgcmVzLnB1c2goW3RleHQuc2xpY2UoMCwgaSksIG5ld0xpbmVTdHJdLmpvaW4oJycpKTtcbiAgICAgICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2UoaSArIDEpO1xuICAgICAgICAgICAgICBmb3VuZCA9IHRydWU7XG4gICAgICAgICAgICAgIGJyZWFrO1xuICAgICAgICAgIH1cbiAgICAgIH1cbiAgICAgIGlmICghZm91bmQpIHtcbiAgICAgICAgICByZXMucHVzaChbdGV4dC5zbGljZSgwLCBub09mQ2hhcmFjdGVyc1BlckxpbmUpLCBuZXdMaW5lU3RyXS5qb2luKCcnKSk7XG4gICAgICAgICAgdGV4dCA9IHRleHQuc2xpY2Uobm9PZkNoYXJhY3RlcnNQZXJMaW5lKTtcbiAgICAgIH1cbiAgICAgIGlmICh0ZXh0Lmxlbmd0aCA8IG5vT2ZDaGFyYWN0ZXJzUGVyTGluZSkgZG9uZSA9IHRydWU7XG4gICAgfSB3aGlsZSAoIWRvbmUpO1xuICAgIHJlcy5wdXNoKHRleHQpO1xuICAgIHJldHVybiByZXM7XG4gIH1cblxuICBjb21wdXRlVGltZURhdGEoKSB7XG4gICAgLy8gY29uc3QgZGlzdGFuY2VCZXR3ZWVuVGltZUJ1YmJsZXMgPSB0aGlzLndpZHRoICogLjggLyAodGhpcy5kYXRhLmxlbmd0aCAtIDEpO1xuICAgIGNvbnN0IG1pblRpbWUgPSBNYXRoLm1pbiguLi50aGlzLmRhdGEubWFwKHRpbWVEYXRhID0+IHRpbWVEYXRhLnRpbWUpKTtcbiAgICBjb25zdCBtYXhUaW1lID0gTWF0aC5tYXgoLi4udGhpcy5kYXRhLm1hcCh0aW1lRGF0YSA9PiB0aW1lRGF0YS50aW1lKSk7XG4gICAgY29uc3QgcGVyVGltZVdpZHRoID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0V2lkdGggKiAuOCAvIChtYXhUaW1lIC0gbWluVGltZSk7XG4gICAgdGhpcy5kYXRhLnNvcnQoKGEsIGIpID0+IGEudGltZSA8IGIudGltZSA/IC0xIDogYS50aW1lID4gYi50aW1lID8gMSA6IDApO1xuICAgIGNvbnN0IGRpZmZzID0gW107XG4gICAgZm9yIChsZXQgaSA9IDE7IGkgPCB0aGlzLmRhdGEubGVuZ3RoOyBpKyspIHtcbiAgICAgIGRpZmZzLnB1c2godGhpcy5kYXRhW2ldLnRpbWUgLSB0aGlzLmRhdGFbaSAtIDFdLnRpbWUpO1xuICAgIH1cbiAgICBjb25zdCBtaW5EaWZmID0gTWF0aC5taW4oLi4uZGlmZnMpO1xuICAgIHRoaXMudGltZUJ1YmJsZVJhZGl1cyA9IE1hdGgubWluKG1pbkRpZmYgKiBwZXJUaW1lV2lkdGggKiAuNCk7XG4gICAgY29uc3QgbWF4UmFkaXVzID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0V2lkdGggKiAuOCAvICh0aGlzLmRhdGEubGVuZ3RoIC0gMSkgKiAuMjU7XG4gICAgY29uc3QgbWluUmFkaXVzID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0V2lkdGggKiAuOCAqIC4wNDtcblxuICAgIC8vIGNvbnNvbGUubG9nKCdtYXg6ICcgKyBtYXhSYWRpdXMpO1xuICAgIC8vIGNvbnNvbGUubG9nKCdtaW46ICcgKyBtaW5SYWRpdXMpO1xuXG5cbiAgICBpZiAodGhpcy50aW1lQnViYmxlUmFkaXVzID4gbWF4UmFkaXVzKSB0aGlzLnRpbWVCdWJibGVSYWRpdXMgPSBtYXhSYWRpdXM7XG4gICAgaWYgKHRoaXMudGltZUJ1YmJsZVJhZGl1cyA8IG1pblJhZGl1cykgdGhpcy50aW1lQnViYmxlUmFkaXVzID0gbWluUmFkaXVzO1xuICAgIHRoaXMudGV4dEJsb2NrSGVpZ2h0ID0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0SGVpZ2h0ICogMiAvIDE2O1xuICAgIHRoaXMudGltZURhdGEgPSBbXTtcbiAgICBsZXQgY250ID0gMDtcbiAgICBsZXQgdXAgPSAxO1xuICAgIGZvciAoY29uc3Qgb25lVGltZURhdGEgb2YgdGhpcy5kYXRhKSB7XG4gICAgICBjb25zdCBjb2xvciA9IG9uZVRpbWVEYXRhLmNvbG9yO1xuICAgICAgY29uc3QgeCA9IChvbmVUaW1lRGF0YS50aW1lIC0gbWluVGltZSkgKiBwZXJUaW1lV2lkdGg7XG4gICAgICBjb25zdCB0aW1lQnViYmxlID0ge1xuICAgICAgICBjZW50cmU6IHtcbiAgICAgICAgICB4LFxuICAgICAgICAgIHk6IHRoaXMuYmFyU3RhcnRZICsgdGhpcy5iYXJXaWR0aCAvIDJcbiAgICAgICAgfSxcbiAgICAgICAgdGV4dDogb25lVGltZURhdGEuZGlzcGxheVRpbWUgPyBvbmVUaW1lRGF0YS5kaXNwbGF5VGltZSA6IG9uZVRpbWVEYXRhLnRpbWVcbiAgICAgICAgLy8gb25lVGltZURhdGEuZGlzcGxheVRpbWUgP1xuICAgICAgICAvLyB0aGlzLnRleHRXcmFwKG9uZVRpbWVEYXRhLmRpc3BsYXlUaW1lLCB0aGlzLnRpbWVCdWJibGVSYWRpdXMgKiAyKSA6XG4gICAgICAgIC8vIFtvbmVUaW1lRGF0YS50aW1lXVxuICAgICAgfTtcbiAgICAgIGNvbnN0IHN0YXJ0ID0ge1xuICAgICAgICB4LFxuICAgICAgICB5OiAodXAgPT09IDEpID8gdGhpcy5iYXJTdGFydFkgOiB0aGlzLmJhckVuZFlcbiAgICAgIH07XG4gICAgICBjb25zdCBlbmQgPSB7XG4gICAgICAgIHgsXG4gICAgICAgIHk6ICh1cCA9PT0gMSkgPyB0aGlzLmJhclN0YXJ0WSAtIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2UucmVjdEhlaWdodCAvIDQgOiB0aGlzLmJhckVuZFkgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RIZWlnaHQgLyA0XG4gICAgICB9O1xuICAgICAgY29uc3QgbGluZSA9ICdNICcgKyBzdGFydC54ICsgJyAnICsgc3RhcnQueSArICcgJyArIGVuZC54ICsgJyAnICsgZW5kLnk7XG5cbiAgICAgIGNvbnN0IHRleHRCbG9jayA9IHtcbiAgICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgICB4LFxuICAgICAgICAgIHk6ICh1cCA9PT0gMSkgP1xuICAgICAgICAgIHRoaXMuYmFyU3RhcnRZIC0gdGhpcy50aW1lbGluZUNoYXJ0U2VydmljZS5yZWN0SGVpZ2h0ICogNyAvIDE2IDpcbiAgICAgICAgICB0aGlzLmJhckVuZFkgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RIZWlnaHQgKiA0IC8gMTZcbiAgICAgICAgfSxcbiAgICAgICAgdGV4dDogdGhpcy50ZXh0V3JhcChvbmVUaW1lRGF0YS50ZXh0LCB0aGlzLnRpbWVCdWJibGVSYWRpdXMgKiA0KVxuICAgICAgfTtcbiAgICAgIHRoaXMudGltZURhdGEucHVzaCh7XG4gICAgICAgIHRpbWVCdWJibGUsXG4gICAgICAgIGxpbmUsXG4gICAgICAgIHRleHRCbG9jayxcbiAgICAgICAgY29sb3JcbiAgICAgIH0pO1xuICAgICAgdXAgPSB1cCAqIC0xO1xuICAgICAgY250Kys7XG4gICAgfVxuICB9XG5cbiAgY29uc3RydWN0b3IocHVibGljIHRpbWVsaW5lQ2hhcnRTZXJ2aWNlOiBUaW1lbGluZUNoYXJ0U2VydmljZSxcbiAgICAgICAgICAgICAgcHJpdmF0ZSBnbG9iYWxQYXJhbWV0ZXJzU2VydmljZTogR2xvYmFsUGFyYW1ldGVyc1NlcnZpY2UsXG4gICAgICAgICAgICAgIHByaXZhdGUgY3VycmVudEVsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcbiAgfVxuXG4gIG5nT25Jbml0KCkge1xuICAgIHRoaXMuY29tcG9uZW50SUQgPSB0aGlzLmdsb2JhbFBhcmFtZXRlcnNTZXJ2aWNlLmFkZE5ld0NvbXBvbmVudCgpO1xuICAgIHRoaXMuY29tcHV0ZUJhckRpbWVuc2lvbnMoKTtcbiAgICB0aGlzLnNldENvbG9ycygpO1xuICAgIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2Uuc2V0VmFsdWVzKHtcbiAgICAgIGNvbXBvbmVudElEOiB0aGlzLmNvbXBvbmVudElELFxuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0LFxuICAgICAgeFBhZGRpbmc6IHRoaXMueFBhZGRpbmcsXG4gICAgICB5UGFkZGluZzogdGhpcy55UGFkZGluZ1xuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zWCA9IHRoaXMueFBhZGRpbmcgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RXaWR0aCAqIC4xO1xuICAgIHRoaXMuZ1RyYW5zbGF0ZSA9ICd0cmFuc2xhdGUoJyArIHRyYW5zWCArICdweCwgJyArIHRoaXMueVBhZGRpbmcgKyAncHgpJztcbiAgICB0aGlzLmNvbXB1dGVCYXJEaW1lbnNpb25zKCk7XG4gICAgdGhpcy5jb21wdXRlVGltZURhdGEoKTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKCkge1xuICAgIHRoaXMuY29tcHV0ZUJhckRpbWVuc2lvbnMoKTtcbiAgICB0aGlzLnNldENvbG9ycygpO1xuICAgIHRoaXMudGltZWxpbmVDaGFydFNlcnZpY2Uuc2V0VmFsdWVzKHtcbiAgICAgIGNvbXBvbmVudElEOiB0aGlzLmNvbXBvbmVudElELFxuICAgICAgd2lkdGg6IHRoaXMud2lkdGgsXG4gICAgICBoZWlnaHQ6IHRoaXMuaGVpZ2h0LFxuICAgICAgeFBhZGRpbmc6IHRoaXMueFBhZGRpbmcsXG4gICAgICB5UGFkZGluZzogdGhpcy55UGFkZGluZ1xuICAgIH0pO1xuICAgIGNvbnN0IHRyYW5zWCA9IHRoaXMueFBhZGRpbmcgKyB0aGlzLnRpbWVsaW5lQ2hhcnRTZXJ2aWNlLnJlY3RXaWR0aCAqIC4xO1xuICAgIHRoaXMuZ1RyYW5zbGF0ZSA9ICd0cmFuc2xhdGUoJyArIHRyYW5zWCArICdweCwgJyArIHRoaXMueVBhZGRpbmcgKyAncHgpJztcbiAgICB0aGlzLmNvbXB1dGVCYXJEaW1lbnNpb25zKCk7XG4gICAgdGhpcy5jb21wdXRlVGltZURhdGEoKTtcbiAgfVxufVxuIl19