ngx-pluto
Version:
450 lines • 36.2 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 {?} */
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