ngx-pluto
Version:
504 lines • 37.8 kB
JavaScript
/**
* @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 {?} */
var $ = require('jquery');
/**
* 环形占比图
*
* <example-url>https://stackblitz.com/edit/np-circle-bar-sample?embed=1&file=src/app/app.component.ts</example-url>
*/
var NpCircleBar = /** @class */ (function () {
function NpCircleBar() {
/**
* 百分比值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 {?}
*/
NpCircleBar.prototype.ngOnInit = /**
* @return {?}
*/
function () {
((/** @type {?} */ ($))).easing.circleProgressEasing = (/**
* @param {?} x
* @return {?}
*/
function (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 {?}
*/
NpCircleBar.prototype.init = /**
* @return {?}
*/
function () {
this.radius = this.size / 2;
this.initWidget();
this.initFill();
this.draw();
this.circleInited.next();
};
/**
* @private
* @return {?}
*/
NpCircleBar.prototype.initWidget = /**
* @private
* @return {?}
*/
function () {
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 {?} */
var 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 {?}
*/
NpCircleBar.prototype.initFill = /**
* @private
* @return {?}
*/
function () {
var _this = this;
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 {?} */
var gr = this.fill.gradient;
if (gr.length === 1) {
this.arcFill = gr[0];
}
else {
/** @type {?} */
var ga = this.fill.gradientAngle || 0;
// gradient direction angle; 0 by default
/** @type {?} */
var 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 {?} */
var 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 {?} */
var img_1 = null;
if (this.fill.image instanceof Image) {
img_1 = this.fill.image;
}
else {
img_1 = new Image();
img_1.src = this.fill.image;
}
/** @type {?} */
var setImageFill = (/**
* @return {?}
*/
function () {
/** @type {?} */
var bg = _this.canvas;
bg.width = _this.size;
bg.height = _this.size;
bg.getContext('2d').drawImage(img_1, 0, 0, _this.size, _this.size);
_this.arcFill = _this.ctx.createPattern(bg, 'no-repeat');
_this.drawFrame(_this.lastFrameValue);
});
if (img_1.complete) {
setImageFill();
}
else {
img_1.onload = setImageFill;
}
}
};
/**
* @private
* @return {?}
*/
NpCircleBar.prototype.draw = /**
* @private
* @return {?}
*/
function () {
if (this.animation) {
this.drawAnimated(this.value);
}
else {
this.drawFrame(this.value);
}
};
/**
* @private
* @param {?} v
* @return {?}
*/
NpCircleBar.prototype.drawFrame = /**
* @private
* @param {?} v
* @return {?}
*/
function (v) {
this.lastFrameValue = v;
this.ctx.clearRect(0, 0, this.size, this.size);
this.drawEmptyArc(v);
this.drawArc(v);
};
/**
* @private
* @param {?} v
* @return {?}
*/
NpCircleBar.prototype.drawArc = /**
* @private
* @param {?} v
* @return {?}
*/
function (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 {?}
*/
NpCircleBar.prototype.drawEmptyArc = /**
* @private
* @param {?} v
* @return {?}
*/
function (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 {?}
*/
NpCircleBar.prototype.drawAnimated = /**
* @private
* @param {?} v
* @return {?}
*/
function (v) {
var _this = this;
/** @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 {?}
*/
function (animationProgress) {
/** @type {?} */
var stepValue = self.animationStartValue * (1 - animationProgress) + v * animationProgress;
self.drawFrame(stepValue);
self.circleAnimationProgress.next({ animationProgress: animationProgress, stepValue: stepValue });
})
}))
.promise()
.always((/**
* @return {?}
*/
function () {
// trigger on both successful & failure animation end
_this.circleAnimationEnd.next();
}));
};
/**
* @private
* @return {?}
*/
NpCircleBar.prototype.getThickness = /**
* @private
* @return {?}
*/
function () {
return isNumber(this.thickness) ? this.thickness : this.size / 14;
};
/**
* @private
* @return {?}
*/
NpCircleBar.prototype.getValue = /**
* @private
* @return {?}
*/
function () {
return this.value;
};
/**
* @param {?} newValue
* @return {?}
*/
NpCircleBar.prototype.setValue = /**
* @param {?} newValue
* @return {?}
*/
function (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 = function () { return []; };
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 }]
};
return NpCircleBar;
}());
export { NpCircleBar };
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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY2lyY2xlLWJhci5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1wbHV0by8iLCJzb3VyY2VzIjpbImxpYi9jaXJjbGUtYmFyL2NpcmNsZS1iYXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7OztBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQWdELEtBQUssRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLE1BQU0sRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDNUksT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLE1BQU0sQ0FBQzs7SUFDMUIsQ0FBQyxHQUFHLE9BQU8sQ0FBQyxRQUFRLENBQUM7Ozs7OztBQU8zQjtJQTJDRTs7OztRQWpDUyxVQUFLLEdBQVcsR0FBRyxDQUFDOzs7O1FBRXBCLFNBQUksR0FBVyxLQUFLLENBQUM7Ozs7UUFFckIsZUFBVSxHQUFXLENBQUMsQ0FBQzs7OztRQUV2QixjQUFTLEdBQVcsTUFBTSxDQUFDOzs7O1FBRTNCLFNBQUksR0FBUSxFQUFFLFFBQVEsRUFBRSxDQUFDLFNBQVMsRUFBRSxTQUFTLENBQUMsRUFBRSxDQUFDOzs7O1FBRWpELGNBQVMsR0FBVyxvQkFBb0IsQ0FBQzs7OztRQUV6QyxjQUFTLEdBQXFCLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsc0JBQXNCLEVBQUUsQ0FBQzs7OztRQUVqRix3QkFBbUIsR0FBVyxHQUFHLENBQUM7Ozs7UUFFbEMsWUFBTyxHQUFZLEtBQUssQ0FBQzs7OztRQUV6QixZQUFPLEdBQWdDLE9BQU8sQ0FBQztRQUMvQyxlQUFVLEdBQXlCLFNBQVMsQ0FBQztRQUU1QyxpQkFBWSxHQUFHLElBQUksWUFBWSxFQUFFLENBQUM7UUFDbEMseUJBQW9CLEdBQUcsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUMxQyw0QkFBdUIsR0FBRyxJQUFJLFlBQVksRUFBTyxDQUFDO1FBQ2xELHVCQUFrQixHQUFHLElBQUksWUFBWSxFQUFPLENBQUM7UUFFdkQsT0FBRSxHQUFHLElBQUks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ZUFBZTtvQkFDekIsb0dBQThCOztpQkFFL0I7Ozs7OzRCQUdFLFNBQVMsU0FBQyxpQkFBaUI7d0JBRzNCLEtBQUs7dUJBRUwsS0FBSzs2QkFFTCxLQUFLOzRCQUVMLEtBQUs7dUJBRUwsS0FBSzs0QkFFTCxLQUFLOzRCQUVMLEtBQUs7c0NBRUwsS0FBSzswQkFFTCxLQUFLOzBCQUVMLEtBQUs7NkJBQ0wsS0FBSzsrQkFFTCxNQUFNO3VDQUNOLE1BQU07MENBQ04sTUFBTTtxQ0FDTixNQUFNOztJQXVPVCxrQkFBQztDQUFBLEFBelFELElBeVFDO1NBcFFZLFdBQVc7OztJQUV0QixnQ0FBb0Q7Ozs7O0lBR3BELDRCQUE2Qjs7Ozs7SUFFN0IsMkJBQThCOzs7OztJQUU5QixpQ0FBZ0M7Ozs7O0lBRWhDLGdDQUFvQzs7Ozs7SUFFcEMsMkJBQTBEOzs7OztJQUUxRCxnQ0FBa0Q7Ozs7O0lBRWxELGdDQUEwRjs7Ozs7SUFFMUYsMENBQTJDOzs7OztJQUUzQyw4QkFBa0M7Ozs7O0lBRWxDLDhCQUF3RDs7SUFDeEQsaUNBQXNEOztJQUV0RCxtQ0FBNEM7O0lBQzVDLDJDQUFvRDs7SUFDcEQsOENBQTREOztJQUM1RCx5Q0FBdUQ7O0lBRXZELHlCQUFVOztJQUNWLDZCQUFpQzs7SUFDakMsMEJBQXFDOztJQUNyQyw2QkFBYTs7SUFDYiw4QkFBZTs7SUFDZixxQ0FBcUIiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIFZpZXdFbmNhcHN1bGF0aW9uLCBPbkluaXQsIENoYW5nZURldGVjdG9yUmVmLCBJbnB1dCwgVmlld0NoaWxkLCBFbGVtZW50UmVmLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBpc051bWJlciB9IGZyb20gJ3V0aWwnO1xyXG5jb25zdCAkID0gcmVxdWlyZSgnanF1ZXJ5Jyk7XHJcblxyXG4vKipcclxuICog546v5b2i5Y2g5q+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