UNPKG

ngx-pluto

Version:
450 lines 36.2 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { Component, Input, ViewChild, ElementRef, Output, EventEmitter } from '@angular/core'; import { isNumber } from 'util'; /** @type {?} */ const $ = require('jquery'); /** * 环形占比图 * * <example-url>https://stackblitz.com/edit/np-circle-bar-sample?embed=1&file=src/app/app.component.ts</example-url> */ export class NpCircleBar { constructor() { /** * 百分比值0 ~ 1, 例如0.25,则占比1/4。 */ this.value = 0.0; /** * 环的直径 */ this.size = 100.0; /** * 环形占比开始的角度,例如0代表3点钟方向开始占比,π代表9点钟方向,2π转了一圈又到了3点钟方向开始,以此类推。 */ this.startAngle = 0; /** * 环的厚度 */ this.thickness = 'auto'; /** * 环形占比渐变色gradient,例如:{ gradient: ['#3aeabb', '#fdd250'] } */ this.fill = { gradient: ['#3aeabb', '#fdd250'] }; /** * 环形未占比填充颜色,例如:rgba(0, 0, 0, 0.1) */ this.emptyFill = 'rgba(0, 0, 0, 0.1)'; /** * 加载动画效果,例如:{ duration: 1200, easing: 'circleProgressEasing' } */ this.animation = { duration: 1200, easing: 'circleProgressEasing' }; /** * 加载动画初始值 */ this.animationStartValue = 0.0; /** * 加载动画是否逆时针 */ this.reverse = false; /** * 环形图截面形状,butt | round | square,默认round即圆环截面 */ this.lineCap = 'round'; this.insertMode = 'prepend'; this.circleInited = new EventEmitter(); this.circleAnimationStart = new EventEmitter(); this.circleAnimationProgress = new EventEmitter(); this.circleAnimationEnd = new EventEmitter(); this.el = null; this.canvas = null; this.ctx = null; this.radius = 0.0; this.arcFill = null; this.lastFrameValue = 0.0; } /** * @return {?} */ ngOnInit() { ((/** @type {?} */ ($))).easing.circleProgressEasing = (/** * @param {?} x * @return {?} */ (x) => { if (x < 0.5) { x = 2 * x; return 0.5 * x * x * x; } else { x = 2 - 2 * x; return 1 - 0.5 * x * x * x; } }); this.init(); } /** * @return {?} */ init() { this.radius = this.size / 2; this.initWidget(); this.initFill(); this.draw(); this.circleInited.next(); } /** * @private * @return {?} */ initWidget() { if (this.canvas === null) { this.canvas = this.canvasRef.nativeElement; this.canvas.width = this.size; this.canvas.height = this.size; this.ctx = this.canvas.getContext('2d'); if (window.devicePixelRatio > 1) { /** @type {?} */ let scaleBy = window.devicePixelRatio; this.canvas.style.width = this.canvas.style.height = this.size + 'px'; this.canvas.width = this.canvas.height = this.size * scaleBy; this.ctx.scale(scaleBy, scaleBy); } } } /** * @private * @return {?} */ initFill() { if (!this.fill) { throw Error('The fill is not specified!'); } if (typeof this.fill === 'string') { this.fill = { color: this.fill }; } if (this.fill.color) { this.arcFill = this.fill.color; } if (this.fill.gradient) { /** @type {?} */ let gr = this.fill.gradient; if (gr.length === 1) { this.arcFill = gr[0]; } else { /** @type {?} */ let ga = this.fill.gradientAngle || 0; // gradient direction angle; 0 by default /** @type {?} */ let gd = this.fill.gradientDirection || [ this.size / 2 * (1 - Math.cos(ga)), this.size / 2 * (1 + Math.sin(ga)), this.size / 2 * (1 + Math.cos(ga)), this.size / 2 * (1 - Math.sin(ga)) // y1 ]; /** @type {?} */ let lg = this.ctx.createLinearGradient.apply(this.ctx, gd); for (var i = 0; i < gr.length; i++) { /** @type {?} */ var color = gr[i]; /** @type {?} */ var pos = i / (gr.length - 1); if (Array.isArray(color)) { pos = color[1]; color = color[0]; } lg.addColorStop(pos, color); } this.arcFill = lg; } } if (this.fill.image) { /** @type {?} */ let img = null; if (this.fill.image instanceof Image) { img = this.fill.image; } else { img = new Image(); img.src = this.fill.image; } /** @type {?} */ let setImageFill = (/** * @return {?} */ () => { /** @type {?} */ var bg = this.canvas; bg.width = this.size; bg.height = this.size; bg.getContext('2d').drawImage(img, 0, 0, this.size, this.size); this.arcFill = this.ctx.createPattern(bg, 'no-repeat'); this.drawFrame(this.lastFrameValue); }); if (img.complete) { setImageFill(); } else { img.onload = setImageFill; } } } /** * @private * @return {?} */ draw() { if (this.animation) { this.drawAnimated(this.value); } else { this.drawFrame(this.value); } } /** * @private * @param {?} v * @return {?} */ drawFrame(v) { this.lastFrameValue = v; this.ctx.clearRect(0, 0, this.size, this.size); this.drawEmptyArc(v); this.drawArc(v); } /** * @private * @param {?} v * @return {?} */ drawArc(v) { if (v === 0) { return; } /** @type {?} */ var ctx = this.ctx; /** @type {?} */ var r = this.radius; /** @type {?} */ var t = this.getThickness(); /** @type {?} */ var a = this.startAngle; ctx.save(); ctx.beginPath(); if (!this.reverse) { ctx.arc(r, r, r - t / 2, a, a + Math.PI * 2 * v); } else { ctx.arc(r, r, r - t / 2, a - Math.PI * 2 * v, a); } ctx.lineWidth = t; ctx.lineCap = this.lineCap; ctx.strokeStyle = this.arcFill; ctx.stroke(); ctx.restore(); } /** * @private * @param {?} v * @return {?} */ drawEmptyArc(v) { /** @type {?} */ var ctx = this.ctx; /** @type {?} */ var r = this.radius; /** @type {?} */ var t = this.getThickness(); /** @type {?} */ var a = this.startAngle; if (v < 1) { ctx.save(); ctx.beginPath(); if (v <= 0) { ctx.arc(r, r, r - t / 2, 0, Math.PI * 2); } else { if (!this.reverse) { ctx.arc(r, r, r - t / 2, a + Math.PI * 2 * v, a); } else { ctx.arc(r, r, r - t / 2, a, a - Math.PI * 2 * v); } } ctx.lineWidth = t; ctx.strokeStyle = this.emptyFill; ctx.stroke(); ctx.restore(); } } /** * @private * @param {?} v * @return {?} */ drawAnimated(v) { /** @type {?} */ var self = this; /** @type {?} */ var el = this.el; /** @type {?} */ var canvas = $(this.canvas); // stop previous animation before new "start" event is triggered canvas.stop(true, false); this.circleAnimationStart.next(); canvas .css({ animationProgress: 0 }) .animate({ animationProgress: 1 }, $.extend({}, this.animation, { step: (/** * @param {?} animationProgress * @return {?} */ (animationProgress) => { /** @type {?} */ var stepValue = self.animationStartValue * (1 - animationProgress) + v * animationProgress; self.drawFrame(stepValue); self.circleAnimationProgress.next({ animationProgress: animationProgress, stepValue: stepValue }); }) })) .promise() .always((/** * @return {?} */ () => { // trigger on both successful & failure animation end this.circleAnimationEnd.next(); })); } /** * @private * @return {?} */ getThickness() { return isNumber(this.thickness) ? this.thickness : this.size / 14; } /** * @private * @return {?} */ getValue() { return this.value; } /** * @param {?} newValue * @return {?} */ setValue(newValue) { if (this.animation) { this.animationStartValue = this.lastFrameValue; } this.value = newValue; this.draw(); } } NpCircleBar.decorators = [ { type: Component, args: [{ selector: `np-circle-bar`, template: "<div class=\"circle-bar-wrapper\">\r\n <canvas #circleBarCanvas></canvas>\r\n</div>\r\n", styles: [":host{height:-webkit-fit-content;height:-moz-fit-content;height:fit-content}"] }] } ]; /** @nocollapse */ NpCircleBar.ctorParameters = () => []; NpCircleBar.propDecorators = { canvasRef: [{ type: ViewChild, args: ['circleBarCanvas',] }], value: [{ type: Input }], size: [{ type: Input }], startAngle: [{ type: Input }], thickness: [{ type: Input }], fill: [{ type: Input }], emptyFill: [{ type: Input }], animation: [{ type: Input }], animationStartValue: [{ type: Input }], reverse: [{ type: Input }], lineCap: [{ type: Input }], insertMode: [{ type: Input }], circleInited: [{ type: Output }], circleAnimationStart: [{ type: Output }], circleAnimationProgress: [{ type: Output }], circleAnimationEnd: [{ type: Output }] }; if (false) { /** @type {?} */ NpCircleBar.prototype.canvasRef; /** * 百分比值0 ~ 1, 例如0.25,则占比1/4。 * @type {?} */ NpCircleBar.prototype.value; /** * 环的直径 * @type {?} */ NpCircleBar.prototype.size; /** * 环形占比开始的角度,例如0代表3点钟方向开始占比,π代表9点钟方向,2π转了一圈又到了3点钟方向开始,以此类推。 * @type {?} */ NpCircleBar.prototype.startAngle; /** * 环的厚度 * @type {?} */ NpCircleBar.prototype.thickness; /** * 环形占比渐变色gradient,例如:{ gradient: ['#3aeabb', '#fdd250'] } * @type {?} */ NpCircleBar.prototype.fill; /** * 环形未占比填充颜色,例如:rgba(0, 0, 0, 0.1) * @type {?} */ NpCircleBar.prototype.emptyFill; /** * 加载动画效果,例如:{ duration: 1200, easing: 'circleProgressEasing' } * @type {?} */ NpCircleBar.prototype.animation; /** * 加载动画初始值 * @type {?} */ NpCircleBar.prototype.animationStartValue; /** * 加载动画是否逆时针 * @type {?} */ NpCircleBar.prototype.reverse; /** * 环形图截面形状,butt | round | square,默认round即圆环截面 * @type {?} */ NpCircleBar.prototype.lineCap; /** @type {?} */ NpCircleBar.prototype.insertMode; /** @type {?} */ NpCircleBar.prototype.circleInited; /** @type {?} */ NpCircleBar.prototype.circleAnimationStart; /** @type {?} */ NpCircleBar.prototype.circleAnimationProgress; /** @type {?} */ NpCircleBar.prototype.circleAnimationEnd; /** @type {?} */ NpCircleBar.prototype.el; /** @type {?} */ NpCircleBar.prototype.canvas; /** @type {?} */ NpCircleBar.prototype.ctx; /** @type {?} */ NpCircleBar.prototype.radius; /** @type {?} */ NpCircleBar.prototype.arcFill; /** @type {?} */ NpCircleBar.prototype.lastFrameValue; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY2xlLWJhci5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1wbHV0by8iLCJzb3VyY2VzIjpbImxpYi9jaXJjbGUtYmFyL2NpcmNsZS1iYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWdELEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUksT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7TUFDMUIsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7Ozs7OztBQVkzQixNQUFNLE9BQU8sV0FBVztJQXNDdEI7Ozs7UUFqQ1MsVUFBSyxHQUFXLEdBQUcsQ0FBQzs7OztRQUVwQixTQUFJLEdBQVcsS0FBSyxDQUFDOzs7O1FBRXJCLGVBQVUsR0FBVyxDQUFDLENBQUM7Ozs7UUFFdkIsY0FBUyxHQUFXLE1BQU0sQ0FBQzs7OztRQUUzQixTQUFJLEdBQVEsRUFBRSxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDLEVBQUUsQ0FBQzs7OztRQUVqRCxjQUFTLEdBQVcsb0JBQW9CLENBQUM7Ozs7UUFFekMsY0FBUyxHQUFxQixFQUFFLFFBQVEsRUFBRSxJQUFJLEVBQUUsTUFBTSxFQUFFLHNCQUFzQixFQUFFLENBQUM7Ozs7UUFFakYsd0JBQW1CLEdBQVcsR0FBRyxDQUFDOzs7O1FBRWxDLFlBQU8sR0FBWSxLQUFLLENBQUM7Ozs7UUFFekIsWUFBTyxHQUFnQyxPQUFPLENBQUM7UUFDL0MsZUFBVSxHQUF5QixTQUFTLENBQUM7UUFFNUMsaUJBQVksR0FBRyxJQUFJLFlBQVksRUFBRSxDQUFDO1FBQ2xDLHlCQUFvQixHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDMUMsNEJBQXVCLEdBQUcsSUFBSSxZQUFZLEVBQU8sQ0FBQztRQUNsRCx1QkFBa0IsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBRXZE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QkFFTCxLQUFLO21CQUVMLEtBQUs7d0JBRUwsS0FBSzt3QkFFTCxLQUFLO2tDQUVMLEtBQUs7c0JBRUwsS0FBSztzQkFFTCxLQUFLO3lCQUNMLEtBQUs7MkJBRUwsTUFBTTttQ0FDTixNQUFNO3NDQUNOLE1BQU07aUNBQ04sTUFBTTs7OztJQTNCUCxnQ0FBb0Q7Ozs7O0lBR3BELDRCQUE2Qjs7Ozs7SUFFN0IsMkJBQThCOzs7OztJQUU5QixpQ0FBZ0M7Ozs7O0lBRWhDLGdDQUFvQzs7Ozs7SUFFcEMsMkJBQTBEOzs7OztJQUUxRCxnQ0FBa0Q7Ozs7O0lBRWxELGdDQUEwRjs7Ozs7SUFFMUYsMENBQTJDOzs7OztJQUUzQyw4QkFBa0M7Ozs7O0lBRWxDLDhCQUF3RDs7SUFDeEQsaUNBQXNEOztJQUV0RCxtQ0FBNEM7O0lBQzVDLDJDQUFvRDs7SUFDcEQsOENBQTREOztJQUM1RCx5Q0FBdUQ7O0lBRXZELHlCQUFVOztJQUNWLDZCQUFpQzs7SUFDakMsMEJBQXFDOztJQUNyQyw2QkFBYTs7SUFDYiw4QkFBZTs7SUFDZixxQ0FBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIFZpZXdFbmNhcHN1bGF0aW9uLCBPbkluaXQsIENoYW5nZURldGVjdG9yUmVmLCBJbnB1dCwgVmlld0NoaWxkLCBFbGVtZW50UmVmLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gJ3V0aWwnO1xyXG5jb25zdCAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XHJcblxyXG4vKipcclxuICog546v5b2i5Y2g5q+U5Zu+XHJcbiAqIFxyXG4gKiA8ZXhhbXBsZS11cmw+aHR0cHM6Ly9zdGFja2JsaXR6LmNvbS9lZGl0L25wLWNpcmNsZS1iYXItc2FtcGxlP2VtYmVkPTEmZmlsZT1zcmMvYXBwL2FwcC5jb21wb25lbnQudHM8L2V4YW1wbGUtdXJsPlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6IGBucC1jaXJjbGUtYmFyYCxcclxuICB0ZW1wbGF0ZVVybDogJ2NpcmNsZS1iYXIuaHRtbCcsXHJcbiAgc3R5bGVVcmxzOiBbJ2NpcmNsZS1iYXIuc2NzcyddXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOcENpcmNsZUJhciBpbXBsZW1lbnRzIE9uSW5pdCB7XHJcblxyXG4gIEBWaWV3Q2hpbGQoJ2NpcmNsZUJhckNhbnZhcycpIGNhbnZhc1JlZjogRWxlbWVudFJlZjtcclxuXHJcbiAgLyoq55m+5YiG5q+U5YC8MCB+IDHvvIwg5L6L5aaCMC4yNe+8jOWImeWNoOavlDEvNOOAgiAqL1xyXG4gIEBJbnB1dCgpIHZhbHVlOiBudW1iZXIgPSAwLjA7XHJcbiAgLyoq546v55qE55u05b6EICovXHJcbiAgQElucHV0KCkgc2l6ZTogbnVtYmVyID0gMTAwLjA7XHJcbiAgLyoq546v5b2i5Y2g5q+U5byA5aeL55qE6KeS5bqm77yM5L6L5aaCMOS7o+ihqDPngrnpkp/mlrnlkJHlvIDlp4vljaDmr5TvvIzPgOS7o+ihqDnngrnpkp/mlrnlkJHvvIwyz4DovazkuobkuIDlnIjlj4jliLDkuoYz54K56ZKf5pa55ZCR5byA5aeL77yM5Lul5q2k57G75o6o44CCICovXHJcbiAgQElucHV0KCkgc3RhcnRBbmdsZTogbnVtYmVyID0gMDtcclxuICAvKirnjq/nmoTljprluqYgKi9cclxuICBASW5wdXQoKSB0aGlja25lc3M6IHN0cmluZyA9ICdhdXRvJztcclxuICAvKirnjq/lvaLljaDmr5TmuJDlj5joibJncmFkaWVudO+8jOS+i+Wmgu+8mnsgZ3JhZGllbnQ6IFsnIzNhZWFiYicsICcjZmRkMjUwJ10gfSAqL1xyXG4gIEBJbnB1dCgpIGZpbGw6IGFueSA9IHsgZ3JhZGllbnQ6IFsnIzNhZWFiYicsICcjZmRkMjUwJ10gfTtcclxuICAvKirnjq/lvaLmnKrljaDmr5TloavlhYXpopzoibLvvIzkvovlpoLvvJpyZ2JhKDAsIDAsIDAsIDAuMSkgKi9cclxuICBASW5wdXQoKSBlbXB0eUZpbGw6IHN0cmluZyA9ICdyZ2JhKDAsIDAsIDAsIDAuMSknO1xyXG4gIC8qKuWKoOi9veWKqOeUu+aViOaenO+8jOS+i+Wmgu+8mnsgZHVyYXRpb246IDEyMDAsIGVhc2luZzogJ2NpcmNsZVByb2dyZXNzRWFzaW5nJyB9Ki9cclxuICBASW5wdXQoKSBhbmltYXRpb246IG9iamVjdCB8IGJvb2xlYW4gPSB7IGR1cmF0aW9uOiAxMjAwLCBlYXNpbmc6ICdjaXJjbGVQcm9ncmVzc0Vhc2luZycgfTtcclxuICAvKirliqDovb3liqjnlLvliJ3lp4vlgLwgKi9cclxuICBASW5wdXQoKSBhbmltYXRpb25TdGFydFZhbHVlOiBudW1iZXIgPSAwLjA7XHJcbiAgLyoq5Yqg6L295Yqo55S75piv5ZCm6YCG5pe26ZKIICovXHJcbiAgQElucHV0KCkgcmV2ZXJzZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIC8qKueOr+W9ouWbvuaIqumdouW9oueKtu+8jGJ1dHQgfCByb3VuZCB8IHNxdWFyZe+8jOm7mOiupHJvdW5k5Y2z5ZyG546v5oiq6Z2iICovXHJcbiAgQElucHV0KCkgbGluZUNhcDogJ2J1dHQnIHwgJ3JvdW5kJyB8ICdzcXVhcmUnID0gJ3JvdW5kJztcclxuICBASW5wdXQoKSBpbnNlcnRNb2RlOiAnYXBwZW5kJyB8ICdwcmVwZW5kJyA9ICdwcmVwZW5kJztcclxuXHJcbiAgQE91dHB1dCgpIGNpcmNsZUluaXRlZCA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcclxuICBAT3V0cHV0KCkgY2lyY2xlQW5pbWF0aW9uU3RhcnQgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcbiAgQE91dHB1dCgpIGNpcmNsZUFuaW1hdGlvblByb2dyZXNzID0gbmV3IEV2ZW50RW1pdHRlcjxhbnk+KCk7XHJcbiAgQE91dHB1dCgpIGNpcmNsZUFuaW1hdGlvbkVuZCA9IG5ldyBFdmVudEVtaXR0ZXI8YW55PigpO1xyXG5cclxuICBlbCA9IG51bGw7XHJcbiAgY2FudmFzOiBIVE1MQ2FudmFzRWxlbWVudCA9IG51bGw7XHJcbiAgY3R4OiBDYW52YXNSZW5kZXJpbmdDb250ZXh0MkQgPSBudWxsO1xyXG4gIHJhZGl1cyA9IDAuMDtcclxuICBhcmNGaWxsID0gbnVsbDtcclxuICBsYXN0RnJhbWVWYWx1ZSA9IDAuMDtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7IH1cclxuXHJcbiAgbmdPbkluaXQoKSB7XHJcbiAgICAoPGFueT4kKS5lYXNpbmcuY2lyY2xlUHJvZ3Jlc3NFYXNpbmcgPSAoeCkgPT4ge1xyXG4gICAgICBpZiAoeCA8IDAuNSkge1xyXG4gICAgICAgIHggPSAyICogeDtcclxuICAgICAgICByZXR1cm4gMC41ICogeCAqIHggKiB4O1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIHggPSAyIC0gMiAqIHg7XHJcbiAgICAgICAgcmV0dXJuIDEgLSAwLjUgKiB4ICogeCAqIHg7XHJcbiAgICAgIH1cclxuICAgIH07XHJcblxyXG4gICAgdGhpcy5pbml0KCk7XHJcbiAgfVxyXG5cclxuICBwdWJsaWMgaW5pdCgpIHtcclxuICAgIHRoaXMucmFkaXVzID0gdGhpcy5zaXplIC8gMjtcclxuICAgIHRoaXMuaW5pdFdpZGdldCgpO1xyXG4gICAgdGhpcy5pbml0RmlsbCgpO1xyXG4gICAgdGhpcy5kcmF3KCk7XHJcblxyXG4gICAgdGhpcy5jaXJjbGVJbml0ZWQubmV4dCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0V2lkZ2V0KCkge1xyXG4gICAgaWYgKHRoaXMuY2FudmFzID09PSBudWxsKSB7XHJcbiAgICAgIHRoaXMuY2FudmFzID0gdGhpcy5jYW52YXNSZWYubmF0aXZlRWxlbWVudDtcclxuICAgICAgdGhpcy5jYW52YXMud2lkdGggPSB0aGlzLnNpemU7XHJcbiAgICAgIHRoaXMuY2FudmFzLmhlaWdodCA9IHRoaXMuc2l6ZTtcclxuICAgICAgdGhpcy5jdHggPSB0aGlzLmNhbnZhcy5nZXRDb250ZXh0KCcyZCcpO1xyXG5cclxuICAgICAgaWYgKHdpbmRvdy5kZXZpY2VQaXhlbFJhdGlvID4gMSkge1xyXG4gICAgICAgIGxldCBzY2FsZUJ5ID0gd2luZG93LmRldmljZVBpeGVsUmF0aW87XHJcbiAgICAgICAgdGhpcy5jYW52YXMuc3R5bGUud2lkdGggPSB0aGlzLmNhbnZhcy5zdHlsZS5oZWlnaHQgPSB0aGlzLnNpemUgKyAncHgnO1xyXG4gICAgICAgIHRoaXMuY2FudmFzLndpZHRoID0gdGhpcy5jYW52YXMuaGVpZ2h0ID0gdGhpcy5zaXplICogc2NhbGVCeTtcclxuICAgICAgICB0aGlzLmN0eC5zY2FsZShzY2FsZUJ5LCBzY2FsZUJ5KTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBpbml0RmlsbCgpIHtcclxuICAgIGlmICghdGhpcy5maWxsKSB7XHJcbiAgICAgIHRocm93IEVycm9yKCdUaGUgZmlsbCBpcyBub3Qgc3BlY2lmaWVkIScpO1xyXG4gICAgfVxyXG5cclxuICAgIGlmICh0eXBlb2YgdGhpcy5maWxsID09PSAnc3RyaW5nJykge1xyXG4gICAgICB0aGlzLmZpbGwgPSB7IGNvbG9yOiB0aGlzLmZpbGwgfTtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5maWxsLmNvbG9yKSB7XHJcbiAgICAgIHRoaXMuYXJjRmlsbCA9IHRoaXMuZmlsbC5jb2xvcjtcclxuICAgIH1cclxuXHJcbiAgICBpZiAodGhpcy5maWxsLmdyYWRpZW50KSB7XHJcbiAgICAgIGxldCBnciA9IHRoaXMuZmlsbC5ncmFkaWVudDtcclxuXHJcbiAgICAgIGlmIChnci5sZW5ndGggPT09IDEpIHtcclxuICAgICAgICB0aGlzLmFyY0ZpbGwgPSBnclswXTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBsZXQgZ2EgPSB0aGlzLmZpbGwuZ3JhZGllbnRBbmdsZSB8fCAwOyAgLy8gZ3JhZGllbnQgZGlyZWN0aW9uIGFuZ2xlOyAwIGJ5IGRlZmF1bHRcclxuICAgICAgICBsZXQgZ2QgPSB0aGlzLmZpbGwuZ3JhZGllbnREaXJlY3Rpb24gfHwgW1xyXG4gICAgICAgICAgdGhpcy5zaXplIC8gMiAqICgxIC0gTWF0aC5jb3MoZ2EpKSwgLy8geDBcclxuICAgICAgICAgIHRoaXMuc2l6ZSAvIDIgKiAoMSArIE1hdGguc2luKGdhKSksIC8vIHkwXHJcbiAgICAgICAgICB0aGlzLnNpemUgLyAyICogKDEgKyBNYXRoLmNvcyhnYSkpLCAvLyB4MVxyXG4gICAgICAgICAgdGhpcy5zaXplIC8gMiAqICgxIC0gTWF0aC5zaW4oZ2EpKSAgLy8geTFcclxuICAgICAgICBdO1xyXG5cclxuICAgICAgICBsZXQgbGcgPSB0aGlzLmN0eC5jcmVhdGVMaW5lYXJHcmFkaWVudC5hcHBseSh0aGlzLmN0eCwgZ2QpO1xyXG4gICAgICAgIGZvciAodmFyIGkgPSAwOyBpIDwgZ3IubGVuZ3RoOyBpKyspIHtcclxuICAgICAgICAgIHZhciBjb2xvciA9IGdyW2ldLFxyXG4gICAgICAgICAgICBwb3MgPSBpIC8gKGdyLmxlbmd0aCAtIDEpO1xyXG5cclxuICAgICAgICAgIGlmIChBcnJheS5pc0FycmF5KGNvbG9yKSkge1xyXG4gICAgICAgICAgICBwb3MgPSBjb2xvclsxXTtcclxuICAgICAgICAgICAgY29sb3IgPSBjb2xvclswXTtcclxuICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICBsZy5hZGRDb2xvclN0b3AocG9zLCBjb2xvcik7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICB0aGlzLmFyY0ZpbGwgPSBsZztcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGlmICh0aGlzLmZpbGwuaW1hZ2UpIHtcclxuICAgICAgbGV0IGltZyA9IG51bGw7XHJcblxyXG4gICAgICBpZiAodGhpcy5maWxsLmltYWdlIGluc3RhbmNlb2YgSW1hZ2UpIHtcclxuICAgICAgICBpbWcgPSB0aGlzLmZpbGwuaW1hZ2U7XHJcbiAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgaW1nID0gbmV3IEltYWdlKCk7XHJcbiAgICAgICAgaW1nLnNyYyA9IHRoaXMuZmlsbC5pbWFnZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgbGV0IHNldEltYWdlRmlsbCA9ICgpID0+IHtcclxuICAgICAgICB2YXIgYmcgPSB0aGlzLmNhbnZhcztcclxuICAgICAgICBiZy53aWR0aCA9IHRoaXMuc2l6ZTtcclxuICAgICAgICBiZy5oZWlnaHQgPSB0aGlzLnNpemU7XHJcbiAgICAgICAgYmcuZ2V0Q29udGV4dCgnMmQnKS5kcmF3SW1hZ2UoaW1nLCAwLCAwLCB0aGlzLnNpemUsIHRoaXMuc2l6ZSk7XHJcbiAgICAgICAgdGhpcy5hcmNGaWxsID0gdGhpcy5jdHguY3JlYXRlUGF0dGVybihiZywgJ25vLXJlcGVhdCcpO1xyXG4gICAgICAgIHRoaXMuZHJhd0ZyYW1lKHRoaXMubGFzdEZyYW1lVmFsdWUpO1xyXG4gICAgICB9XHJcblxyXG4gICAgICBpZiAoaW1nLmNvbXBsZXRlKSB7XHJcbiAgICAgICAgc2V0SW1hZ2VGaWxsKCk7XHJcbiAgICAgIH1cclxuICAgICAgZWxzZSB7XHJcbiAgICAgICAgaW1nLm9ubG9hZCA9IHNldEltYWdlRmlsbDtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkcmF3KCkge1xyXG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uKSB7XHJcbiAgICAgIHRoaXMuZHJhd0FuaW1hdGVkKHRoaXMudmFsdWUpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5kcmF3RnJhbWUodGhpcy52YWx1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGRyYXdGcmFtZSh2OiBudW1iZXIpIHtcclxuICAgIHRoaXMubGFzdEZyYW1lVmFsdWUgPSB2O1xyXG4gICAgdGhpcy5jdHguY2xlYXJSZWN0KDAsIDAsIHRoaXMuc2l6ZSwgdGhpcy5zaXplKTtcclxuICAgIHRoaXMuZHJhd0VtcHR5QXJjKHYpO1xyXG4gICAgdGhpcy5kcmF3QXJjKHYpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBkcmF3QXJjKHY6IG51bWJlcikge1xyXG4gICAgaWYgKHYgPT09IDApIHtcclxuICAgICAgcmV0dXJuO1xyXG4gICAgfVxyXG5cclxuICAgIHZhciBjdHggPSB0aGlzLmN0eCxcclxuICAgICAgciA9IHRoaXMucmFkaXVzLFxyXG4gICAgICB0ID0gdGhpcy5nZXRUaGlja25lc3MoKSxcclxuICAgICAgYSA9IHRoaXMuc3RhcnRBbmdsZTtcclxuXHJcbiAgICBjdHguc2F2ZSgpO1xyXG4gICAgY3R4LmJlZ2luUGF0aCgpO1xyXG5cclxuICAgIGlmICghdGhpcy5yZXZlcnNlKSB7XHJcbiAgICAgIGN0eC5hcmMociwgciwgciAtIHQgLyAyLCBhLCBhICsgTWF0aC5QSSAqIDIgKiB2KTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIGN0eC5hcmMociwgciwgciAtIHQgLyAyLCBhIC0gTWF0aC5QSSAqIDIgKiB2LCBhKTtcclxuICAgIH1cclxuXHJcbiAgICBjdHgubGluZVdpZHRoID0gdDtcclxuICAgIGN0eC5saW5lQ2FwID0gdGhpcy5saW5lQ2FwO1xyXG4gICAgY3R4LnN0cm9rZVN0eWxlID0gdGhpcy5hcmNGaWxsO1xyXG4gICAgY3R4LnN0cm9rZSgpO1xyXG4gICAgY3R4LnJlc3RvcmUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0VtcHR5QXJjKHY6IG51bWJlcikge1xyXG4gICAgdmFyIGN0eCA9IHRoaXMuY3R4LFxyXG4gICAgICByID0gdGhpcy5yYWRpdXMsXHJcbiAgICAgIHQgPSB0aGlzLmdldFRoaWNrbmVzcygpLFxyXG4gICAgICBhID0gdGhpcy5zdGFydEFuZ2xlO1xyXG5cclxuICAgIGlmICh2IDwgMSkge1xyXG4gICAgICBjdHguc2F2ZSgpO1xyXG4gICAgICBjdHguYmVnaW5QYXRoKCk7XHJcblxyXG4gICAgICBpZiAodiA8PSAwKSB7XHJcbiAgICAgICAgY3R4LmFyYyhyLCByLCByIC0gdCAvIDIsIDAsIE1hdGguUEkgKiAyKTtcclxuICAgICAgfSBlbHNlIHtcclxuICAgICAgICBpZiAoIXRoaXMucmV2ZXJzZSkge1xyXG4gICAgICAgICAgY3R4LmFyYyhyLCByLCByIC0gdCAvIDIsIGEgKyBNYXRoLlBJICogMiAqIHYsIGEpO1xyXG4gICAgICAgIH0gZWxzZSB7XHJcbiAgICAgICAgICBjdHguYXJjKHIsIHIsIHIgLSB0IC8gMiwgYSwgYSAtIE1hdGguUEkgKiAyICogdik7XHJcbiAgICAgICAgfVxyXG4gICAgICB9XHJcblxyXG4gICAgICBjdHgubGluZVdpZHRoID0gdDtcclxuICAgICAgY3R4LnN0cm9rZVN0eWxlID0gdGhpcy5lbXB0eUZpbGw7XHJcbiAgICAgIGN0eC5zdHJva2UoKTtcclxuICAgICAgY3R4LnJlc3RvcmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByaXZhdGUgZHJhd0FuaW1hdGVkKHY6IG51bWJlcikge1xyXG4gICAgdmFyIHNlbGYgPSB0aGlzLFxyXG4gICAgICBlbCA9IHRoaXMuZWwsXHJcbiAgICAgIGNhbnZhcyA9ICQodGhpcy5jYW52YXMpO1xyXG5cclxuICAgIC8vIHN0b3AgcHJldmlvdXMgYW5pbWF0aW9uIGJlZm9yZSBuZXcgXCJzdGFydFwiIGV2ZW50IGlzIHRyaWdnZXJlZFxyXG4gICAgY2FudmFzLnN0b3AodHJ1ZSwgZmFsc2UpO1xyXG4gICAgdGhpcy5jaXJjbGVBbmltYXRpb25TdGFydC5uZXh0KCk7XHJcblxyXG4gICAgY2FudmFzXHJcbiAgICAgIC5jc3MoeyBhbmltYXRpb25Qcm9ncmVzczogMCB9KVxyXG4gICAgICAuYW5pbWF0ZSh7IGFuaW1hdGlvblByb2dyZXNzOiAxIH0sICQuZXh0ZW5kKHt9LCB0aGlzLmFuaW1hdGlvbiwge1xyXG4gICAgICAgIHN0ZXA6IChhbmltYXRpb25Qcm9ncmVzcykgPT4ge1xyXG4gICAgICAgICAgdmFyIHN0ZXBWYWx1ZSA9IHNlbGYuYW5pbWF0aW9uU3RhcnRWYWx1ZSAqICgxIC0gYW5pbWF0aW9uUHJvZ3Jlc3MpICsgdiAqIGFuaW1hdGlvblByb2dyZXNzO1xyXG4gICAgICAgICAgc2VsZi5kcmF3RnJhbWUoc3RlcFZhbHVlKTtcclxuICAgICAgICAgIHNlbGYuY2lyY2xlQW5pbWF0aW9uUHJvZ3Jlc3MubmV4dCh7IGFuaW1hdGlvblByb2dyZXNzOiBhbmltYXRpb25Qcm9ncmVzcywgc3RlcFZhbHVlOiBzdGVwVmFsdWUgfSk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KSlcclxuICAgICAgLnByb21pc2UoKVxyXG4gICAgICAuYWx3YXlzKCgpID0+IHtcclxuICAgICAgICAvLyB0cmlnZ2VyIG9uIGJvdGggc3VjY2Vzc2Z1bCAmIGZhaWx1cmUgYW5pbWF0aW9uIGVuZFxyXG4gICAgICAgIHRoaXMuY2lyY2xlQW5pbWF0aW9uRW5kLm5leHQoKTtcclxuICAgICAgfSk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldFRoaWNrbmVzcygpIHtcclxuICAgIHJldHVybiBpc051bWJlcih0aGlzLnRoaWNrbmVzcykgPyB0aGlzLnRoaWNrbmVzcyA6IHRoaXMuc2l6ZSAvIDE0O1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXRWYWx1ZSgpIHtcclxuICAgIHJldHVybiB0aGlzLnZhbHVlO1xyXG4gIH1cclxuXHJcbiAgc2V0VmFsdWUobmV3VmFsdWU6IG51bWJlcikge1xyXG4gICAgaWYgKHRoaXMuYW5pbWF0aW9uKSB7XHJcbiAgICAgIHRoaXMuYW5pbWF0aW9uU3RhcnRWYWx1ZSA9IHRoaXMubGFzdEZyYW1lVmFsdWU7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy52YWx1ZSA9IG5ld1ZhbHVlO1xyXG4gICAgdGhpcy5kcmF3KCk7XHJcbiAgfVxyXG59XHJcblxyXG5cclxuIl19