mgx-circular-progress-bar
Version:
A library for circular progress bars components, an elegant way to rappresent your percentages.
414 lines (403 loc) • 47.2 kB
JavaScript
import { Component, Input, ViewChild, NgModule } from '@angular/core';
import { CommonModule } from '@angular/common';
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressFullBarComponent {
constructor() {
this.total = 1;
this.barValue = 0;
this.percentage = 0;
this.diameter = 150;
this.color = '#3282b8';
this.bgColor = '#eee';
this.contentSize = 83;
this.pathPosition = 90;
this.mgxPrefix = 'mgx-circular-progress-full-bar';
this.percentual = 0;
this.context = { percentual: 0, $implicit: 0 };
}
/**
* @return {?}
*/
ngOnChanges() {
/** @type {?} */
const circle = this.circlePath.nativeElement;
/** @type {?} */
const len = 2 * Math.PI * this.pathPosition;
circle.style.strokeDasharray = len;
this.showWarnings();
this.percentual = +this.percentage || (+this.barValue / +this.total) * 100;
this.percentual = isNaN(this.percentual) ? 0 : +this.percentual.toFixed(2);
if (this.percentual > 100) {
circle.style.strokeDashoffset = 0;
this.percentual = 100;
}
else {
circle.style.strokeDashoffset = len - (this.percentual / 100) * len;
}
this.context.percentual = this.percentual;
this.context.$implicit = this.percentual;
}
/**
* @return {?}
*/
showWarnings() {
if (!this.percentual || isNaN(this.percentual)) {
if (isNaN(this.barValue)) {
console.warn(`${this.mgxPrefix} barValue: ${this.barValue}`);
}
else if (isNaN(this.total)) {
console.warn(`${this.mgxPrefix} total: ${this.total}`);
}
else if (this.barValue > this.total) {
console.warn(`${this.mgxPrefix} barValue: ${this.barValue} is more than total: ${this.total}`);
}
}
}
/**
* @param {?=} reducer
* @return {?}
*/
getFontSize(reducer = 1) {
return `${(this.fontSize || (this.diameter / 4)) / reducer}px`;
}
}
MgxCircularProgressFullBarComponent.decorators = [
{ type: Component, args: [{
selector: 'mgx-circular-progress-full-bar',
template: `<div class="contain">
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" [ngStyle]="{'width.px': diameter, 'height.px': diameter }"
viewBox="0 0 200 200">
<circle id="base-circle" [attr.fill]="bgColor" stroke-width="15" cx="100" cy="100" [attr.r]="contentSize" />
<circle id="path" #circlePath [attr.stroke]="color" fill="none" stroke-width="15" cx="100" cy="100"
[attr.r]="pathPosition" rotate="50" />
</svg>
<div class="label">
<ng-container *ngIf="contentTemplate; else projectContent">
<ng-template *ngTemplateOutlet="contentTemplate; context: context"></ng-template>
</ng-container>
<ng-template #projectContent>
<div #contentRef>
<ng-content></ng-content>
</div>
<div *ngIf="!contentRef?.childNodes?.length" [style.font-size]="getFontSize()">{{percentual}}<span
[style.font-size]="getFontSize(1.2)">%</span></div>
</ng-template>
</div>
</div>`,
styles: [`.contain{display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;box-sizing:border-box;position:relative}#path{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg);transform-origin:center center;-webkit-transform-origin:center center;-ms-transform-origin:center center;-moz-transform-origin:center center;transition:stroke-dashoffset .3s ease-in-out;-webkit-transition:stroke-dashoffset .3s ease-in-out;-ms-transition:stroke-dashoffset .3s ease-in-out;-moz-transition:stroke-dashoffset .3s ease-in-out}#pie-path{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg)}.label{position:absolute;top:0;right:0;bottom:0;left:0;display:-webkit-box;display:flex;flex-wrap:wrap;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;font-family:Kreon VariableFont;color:#7f8c8d}`]
},] },
];
/** @nocollapse */
MgxCircularProgressFullBarComponent.ctorParameters = () => [];
MgxCircularProgressFullBarComponent.propDecorators = {
total: [{ type: Input }],
barValue: [{ type: Input }],
percentage: [{ type: Input }],
contentTemplate: [{ type: Input }],
diameter: [{ type: Input }],
fontSize: [{ type: Input }],
color: [{ type: Input }],
bgColor: [{ type: Input }],
contentSize: [{ type: Input }],
pathPosition: [{ type: Input }],
circlePath: [{ type: ViewChild, args: ['circlePath',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressFullBarModule {
}
MgxCircularProgressFullBarModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [MgxCircularProgressFullBarComponent],
exports: [MgxCircularProgressFullBarComponent]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressPieComponent {
constructor() {
/* Data section */
this.total = 1;
this.barValue = 0;
this.percentage = 0;
this.diameter = 150;
this.color = '#3282b8';
this.bgColor = '#eee';
this.bgSize = 10;
this.mgxPrefix = 'mgx-circular-progress-pie';
this.percentual = 0;
}
/**
* @return {?}
*/
ngOnChanges() {
this.showWarnings();
this.percentual = +this.percentage || (+this.barValue / +this.total) * 100;
this.percentual = isNaN(this.percentual) ? 0 : +this.percentual.toFixed(2);
if (this.percentual > 100) {
this.setSlice(1);
this.percentual = 100;
}
else {
this.setSlice(this.percentual / 100);
}
}
/**
* @param {?} percent
* @return {?}
*/
setSlice(percent) {
const [endX, endY] = this.getCoordinatesForPercent(percent);
/** @type {?} */
const largeArcFlag = percent > .5 ? 1 : 0;
this.pathData = [
`M 1 0`,
// Move
`A 1 1 0 ${largeArcFlag} 1 ${endX} ${endY}`,
`L 0 0`,
].join(' ');
}
/**
* @param {?} percent
* @return {?}
*/
getCoordinatesForPercent(percent) {
/** @type {?} */
const x = Math.cos(2 * Math.PI * percent);
/** @type {?} */
const y = Math.sin(2 * Math.PI * percent);
return [x, y];
}
/**
* @return {?}
*/
showWarnings() {
if (!this.percentage || isNaN(this.percentage)) {
if (isNaN(this.barValue)) {
console.warn(`${this.mgxPrefix} barValue: ${this.barValue}`);
}
else if (isNaN(this.total)) {
console.warn(`${this.mgxPrefix} total: ${this.total}`);
}
else if (this.barValue > this.total) {
console.warn(`${this.mgxPrefix} barValue: ${this.barValue} is more than total: ${this.total}`);
}
}
}
/**
* @param {?=} reducer
* @return {?}
*/
getFontSize(reducer = 1) {
return `${(this.fontSize || (this.diameter / 4)) / reducer}px`;
}
}
MgxCircularProgressPieComponent.decorators = [
{ type: Component, args: [{
selector: 'mgx-circular-progress-pie',
template: `<div class="contain">
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" [ngStyle]="{'width.px': diameter, 'height.px': diameter }"
viewBox="-1 -1 2 2">
<circle id="base-circle" [attr.stroke]="bgColor" [attr.fill]="bgColor" cx="0" cy="0" [attr.r]="bgSize / 20" />
<path id="pie-path" [attr.fill]="color" [attr.d]="pathData" rotate="50"></path>
</svg>
<div class="label">
<ng-container *ngIf="contentTemplate; else projectContent">
<ng-template *ngTemplateOutlet="contentTemplate"></ng-template>
</ng-container>
<ng-template #projectContent>
<div #contentRef>
<ng-content></ng-content>
</div>
<div *ngIf="!contentRef?.childNodes?.length" [style.font-size]="getFontSize()">
{{percentual}}<span [style.font-size]="getFontSize(1.2)">%</span>
</div>
</ng-template>
</div>
</div>`,
styles: [`.contain{display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;box-sizing:border-box;position:relative}#path{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg);transform-origin:center center;-webkit-transform-origin:center center;-ms-transform-origin:center center;-moz-transform-origin:center center;transition:stroke-dashoffset .3s ease-in-out;-webkit-transition:stroke-dashoffset .3s ease-in-out;-ms-transition:stroke-dashoffset .3s ease-in-out;-moz-transition:stroke-dashoffset .3s ease-in-out}#pie-path{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg)}.label{position:absolute;top:0;right:0;bottom:0;left:0;display:-webkit-box;display:flex;flex-wrap:wrap;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;font-family:Kreon VariableFont;color:#7f8c8d}`]
},] },
];
/** @nocollapse */
MgxCircularProgressPieComponent.ctorParameters = () => [];
MgxCircularProgressPieComponent.propDecorators = {
total: [{ type: Input }],
barValue: [{ type: Input }],
percentage: [{ type: Input }],
contentTemplate: [{ type: Input }],
diameter: [{ type: Input }],
fontSize: [{ type: Input }],
color: [{ type: Input }],
bgColor: [{ type: Input }],
bgSize: [{ type: Input }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressPieModule {
}
MgxCircularProgressPieModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [MgxCircularProgressPieComponent],
exports: [MgxCircularProgressPieComponent]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressBarComponent {
constructor() {
/* Data section */
this.total = 1;
this.barValue = 0;
this.percentage = 0;
this.diameter = 150;
this.color = '#3282b8';
this.bgColor = '#eee';
this.radius = 90;
this.mgxPrefix = 'mgx-circular-progress-bar';
this.percentual = 0;
this.context = { percentual: 0, $implicit: 0 };
}
/**
* @return {?}
*/
ngOnChanges() {
/** @type {?} */
const circle = this.circlePath.nativeElement;
/** @type {?} */
const len = 2 * Math.PI * this.radius;
circle.style.strokeDasharray = len;
this.showWarnings();
this.percentual = +this.percentage || (+this.barValue / +this.total) * 100;
this.percentual = isNaN(this.percentual) ? 0 : +this.percentual.toFixed(2);
if (this.percentual > 100) {
circle.style.strokeDashoffset = 0;
this.percentual = 100;
}
else {
circle.style.strokeDashoffset = len - (this.percentual / 100) * len;
}
this.context.percentual = this.percentual;
this.context.$implicit = this.percentual;
}
/**
* @return {?}
*/
showWarnings() {
if (!this.percentage || isNaN(this.percentage)) {
if (isNaN(this.barValue)) {
console.warn(`${this.mgxPrefix} barValue: ${this.barValue}`);
}
else if (isNaN(this.total)) {
console.warn(`${this.mgxPrefix} total: ${this.total}`);
}
else if (this.barValue > this.total) {
console.warn(`${this.mgxPrefix} barValue: ${this.barValue} is more than total: ${this.total}`);
}
}
}
/**
* @param {?=} reducer
* @return {?}
*/
getFontSize(reducer = 1) {
return `${(this.fontSize || (this.diameter / 4)) / reducer}px`;
}
}
MgxCircularProgressBarComponent.decorators = [
{ type: Component, args: [{
selector: 'mgx-circular-progress-bar',
template: `
<div class="contain">
<svg xmlns="http://www.w3.org/2000/svg" x="0" y="0" [ngStyle]="{'width.px': diameter, 'height.px': diameter }" viewBox="0 0 200 200">
<circle id="base-circle" [attr.stroke]="bgColor" fill="none" stroke-width="15" cx="100" cy="100"
[attr.r]="radius" />
<circle id="path" #circlePath [attr.stroke]="color" fill="none" stroke-width="15" cx="100" cy="100"
[attr.r]="radius" rotate="50" />
</svg>
<div class="label">
<ng-container *ngIf="contentTemplate; else projectContent">
<ng-template *ngTemplateOutlet="contentTemplate; context: context"></ng-template>
</ng-container>
<ng-template #projectContent>
<div #contentRef>
<ng-content></ng-content>
</div>
<div *ngIf="!contentRef?.childNodes?.length" [style.font-size]="getFontSize()">
{{percentual}}<span [style.font-size]="getFontSize(1.2)">%</span>
</div>
</ng-template>
</div>
</div>`,
styles: [`.contain{display:-webkit-box;display:flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;-webkit-box-orient:vertical;-webkit-box-direction:normal;flex-direction:column;box-sizing:border-box;position:relative}#path{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg);transform-origin:center center;-webkit-transform-origin:center center;-ms-transform-origin:center center;-moz-transform-origin:center center;transition:stroke-dashoffset .3s ease-in-out;-webkit-transition:stroke-dashoffset .3s ease-in-out;-ms-transition:stroke-dashoffset .3s ease-in-out;-moz-transition:stroke-dashoffset .3s ease-in-out}#pie-path{transform:rotate(-90deg);-webkit-transform:rotate(-90deg);-ms-transform:rotate(-90deg);-moz-transform:rotate(-90deg)}.label{position:absolute;top:0;right:0;bottom:0;left:0;display:-webkit-box;display:flex;flex-wrap:wrap;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;font-family:Kreon VariableFont;color:#7f8c8d}`]
},] },
];
/** @nocollapse */
MgxCircularProgressBarComponent.ctorParameters = () => [];
MgxCircularProgressBarComponent.propDecorators = {
total: [{ type: Input }],
barValue: [{ type: Input }],
percentage: [{ type: Input }],
contentTemplate: [{ type: Input }],
diameter: [{ type: Input }],
fontSize: [{ type: Input }],
color: [{ type: Input }],
bgColor: [{ type: Input }],
circlePath: [{ type: ViewChild, args: ['circlePath',] }]
};
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressBarModule {
}
MgxCircularProgressBarModule.decorators = [
{ type: NgModule, args: [{
imports: [CommonModule],
declarations: [MgxCircularProgressBarComponent],
exports: [MgxCircularProgressBarComponent]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
class MgxCircularProgressModule {
}
MgxCircularProgressModule.decorators = [
{ type: NgModule, args: [{
imports: [
CommonModule,
MgxCircularProgressBarModule,
MgxCircularProgressPieModule,
MgxCircularProgressFullBarModule
],
exports: [
MgxCircularProgressBarModule,
MgxCircularProgressPieModule,
MgxCircularProgressFullBarModule
]
},] },
];
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
export { MgxCircularProgressModule, MgxCircularProgressBarModule, MgxCircularProgressFullBarModule, MgxCircularProgressPieModule, MgxCircularProgressBarComponent as ɵa, MgxCircularProgressFullBarComponent as ɵc, MgxCircularProgressPieComponent as ɵb };
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWd4LWNpcmN1bGFyLXByb2dyZXNzLWJhci5qcy5tYXAiLCJzb3VyY2VzIjpbIm5nOi8vbWd4LWNpcmN1bGFyLXByb2dyZXNzLWJhci9saWIvbWd4LWNpcmN1bGFyLXByb2dyZXNzLWZ1bGwtYmFyL21neC1jaXJjdWxhci1wcm9ncmVzcy1mdWxsLWJhci5jb21wb25lbnQudHMiLCJuZzovL21neC1jaXJjdWxhci1wcm9ncmVzcy1iYXIvbGliL21neC1jaXJjdWxhci1wcm9ncmVzcy1mdWxsLWJhci9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtZnVsbC1iYXIubW9kdWxlLnRzIiwibmc6Ly9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL2xpYi9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtcGllL21neC1jaXJjdWxhci1wcm9ncmVzcy1waWUuY29tcG9uZW50LnRzIiwibmc6Ly9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL2xpYi9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtcGllL21neC1jaXJjdWxhci1wcm9ncmVzcy1waWUubW9kdWxlLnRzIiwibmc6Ly9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL2xpYi9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL21neC1jaXJjdWxhci1wcm9ncmVzcy1iYXIuY29tcG9uZW50LnRzIiwibmc6Ly9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL2xpYi9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL21neC1jaXJjdWxhci1wcm9ncmVzcy1iYXIubW9kdWxlLnRzIiwibmc6Ly9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyL2xpYi9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyLm1vZHVsZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBDb21wb25lbnQsIElucHV0LCBPbkNoYW5nZXMsIFZpZXdDaGlsZCwgRWxlbWVudFJlZiwgVGVtcGxhdGVSZWYgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcblxuQENvbXBvbmVudCh7XG4gIHNlbGVjdG9yOiAnbWd4LWNpcmN1bGFyLXByb2dyZXNzLWZ1bGwtYmFyJyxcbiAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwiY29udGFpblwiPlxuICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHg9XCIwXCIgeT1cIjBcIiBbbmdTdHlsZV09XCJ7J3dpZHRoLnB4JzogZGlhbWV0ZXIsICdoZWlnaHQucHgnOiBkaWFtZXRlciB9XCJcbiAgICAgICAgdmlld0JveD1cIjAgMCAyMDAgMjAwXCI+XG4gICAgICAgIDxjaXJjbGUgaWQ9XCJiYXNlLWNpcmNsZVwiIFthdHRyLmZpbGxdPVwiYmdDb2xvclwiIHN0cm9rZS13aWR0aD1cIjE1XCIgY3g9XCIxMDBcIiBjeT1cIjEwMFwiIFthdHRyLnJdPVwiY29udGVudFNpemVcIiAvPlxuICAgICAgICA8Y2lyY2xlIGlkPVwicGF0aFwiICNjaXJjbGVQYXRoIFthdHRyLnN0cm9rZV09XCJjb2xvclwiIGZpbGw9XCJub25lXCIgc3Ryb2tlLXdpZHRoPVwiMTVcIiBjeD1cIjEwMFwiIGN5PVwiMTAwXCJcbiAgICAgICAgICAgIFthdHRyLnJdPVwicGF0aFBvc2l0aW9uXCIgcm90YXRlPVwiNTBcIiAvPlxuICAgIDwvc3ZnPlxuICAgIDxkaXYgY2xhc3M9XCJsYWJlbFwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29udGVudFRlbXBsYXRlOyBlbHNlIHByb2plY3RDb250ZW50XCI+XG4gICAgICAgICAgICA8bmctdGVtcGxhdGUgKm5nVGVtcGxhdGVPdXRsZXQ9XCJjb250ZW50VGVtcGxhdGU7IGNvbnRleHQ6IGNvbnRleHRcIj48L25nLXRlbXBsYXRlPlxuICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPG5nLXRlbXBsYXRlICNwcm9qZWN0Q29udGVudD5cbiAgICAgICAgICAgIDxkaXYgI2NvbnRlbnRSZWY+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICA8ZGl2ICpuZ0lmPVwiIWNvbnRlbnRSZWY/LmNoaWxkTm9kZXM/Lmxlbmd0aFwiIFtzdHlsZS5mb250LXNpemVdPVwiZ2V0Rm9udFNpemUoKVwiPnt7cGVyY2VudHVhbH19PHNwYW5cbiAgICAgICAgICAgICAgICAgICAgW3N0eWxlLmZvbnQtc2l6ZV09XCJnZXRGb250U2l6ZSgxLjIpXCI+JiMzNzs8L3NwYW4+PC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG48L2Rpdj5gLFxuICBzdHlsZXM6IFtgLmNvbnRhaW57ZGlzcGxheTotd2Via2l0LWJveDtkaXNwbGF5OmZsZXg7LXdlYmtpdC1ib3gtcGFjazpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjstd2Via2l0LWJveC1hbGlnbjpjZW50ZXI7YWxpZ24taXRlbXM6Y2VudGVyOy13ZWJraXQtYm94LW9yaWVudDp2ZXJ0aWNhbDstd2Via2l0LWJveC1kaXJlY3Rpb246bm9ybWFsO2ZsZXgtZGlyZWN0aW9uOmNvbHVtbjtib3gtc2l6aW5nOmJvcmRlci1ib3g7cG9zaXRpb246cmVsYXRpdmV9I3BhdGh7dHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy1tcy10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7LW1vei10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7dHJhbnNmb3JtLW9yaWdpbjpjZW50ZXIgY2VudGVyOy13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjpjZW50ZXIgY2VudGVyOy1tcy10cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciBjZW50ZXI7LW1vei10cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciBjZW50ZXI7dHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZS1pbi1vdXQ7LXdlYmtpdC10cmFuc2l0aW9uOnN0cm9rZS1kYXNob2Zmc2V0IC4zcyBlYXNlLWluLW91dDstbXMtdHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZS1pbi1vdXQ7LW1vei10cmFuc2l0aW9uOnN0cm9rZS1kYXNob2Zmc2V0IC4zcyBlYXNlLWluLW91dH0jcGllLXBhdGh7dHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy1tcy10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7LW1vei10cmFuc2Zvcm06cm90YXRlKC05MGRlZyl9LmxhYmVse3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO3JpZ2h0OjA7Ym90dG9tOjA7bGVmdDowO2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTpmbGV4O2ZsZXgtd3JhcDp3cmFwOy13ZWJraXQtYm94LXBhY2s6Y2VudGVyO2p1c3RpZnktY29udGVudDpjZW50ZXI7LXdlYmtpdC1ib3gtYWxpZ246Y2VudGVyO2FsaWduLWl0ZW1zOmNlbnRlcjtmb250LWZhbWlseTpLcmVvbiBWYXJpYWJsZUZvbnQ7Y29sb3I6IzdmOGM4ZH1gXVxufSlcbmV4cG9ydCBjbGFzcyBNZ3hDaXJjdWxhclByb2dyZXNzRnVsbEJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcyB7XG5cbiAgQElucHV0KCkgdG90YWw6IG51bWJlciA9IDE7XG4gIEBJbnB1dCgpIGJhclZhbHVlOiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBwZXJjZW50YWdlOiBudW1iZXIgPSAwO1xuXG4gIC8qIERpc3BsYXkgc2VjdGlvbiAqL1xuICBASW5wdXQoKSBjb250ZW50VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgpIGRpYW1ldGVyOiBudW1iZXIgPSAxNTA7XG4gIEBJbnB1dCgpIGZvbnRTaXplOiBudW1iZXI7XG4gIEBJbnB1dCgpIGNvbG9yOiBzdHJpbmcgPSAnIzMyODJiOCc7XG4gIEBJbnB1dCgpIGJnQ29sb3I6IHN0cmluZyA9ICcjZWVlJztcbiAgQElucHV0KCkgY29udGVudFNpemU6IG51bWJlciA9IDgzO1xuICBASW5wdXQoKSBwYXRoUG9zaXRpb246IG51bWJlciA9IDkwO1xuICBAVmlld0NoaWxkKCdjaXJjbGVQYXRoJykgY2lyY2xlUGF0aDogRWxlbWVudFJlZjtcblxuICBwcml2YXRlIG1neFByZWZpeCA9ICdtZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtZnVsbC1iYXInO1xuICBwZXJjZW50dWFsOiBudW1iZXIgPSAwO1xuICBjb250ZXh0OiBhbnkgPSB7IHBlcmNlbnR1YWw6IDAsICRpbXBsaWNpdDogMCB9O1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgY29uc3QgY2lyY2xlID0gdGhpcy5jaXJjbGVQYXRoLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgbGVuID0gMiAqIE1hdGguUEkgKiB0aGlzLnBhdGhQb3NpdGlvbjtcbiAgICBjaXJjbGUuc3R5bGUuc3Ryb2tlRGFzaGFycmF5ID0gbGVuO1xuXG4gICAgdGhpcy5zaG93V2FybmluZ3MoKTtcblxuICAgIHRoaXMucGVyY2VudHVhbCA9ICt0aGlzLnBlcmNlbnRhZ2UgfHwgKCt0aGlzLmJhclZhbHVlIC8gK3RoaXMudG90YWwpICogMTAwO1xuXG4gICAgdGhpcy5wZXJjZW50dWFsID0gaXNOYU4odGhpcy5wZXJjZW50dWFsKSA/IDAgOiArdGhpcy5wZXJjZW50dWFsLnRvRml4ZWQoMik7XG5cbiAgICBpZiAodGhpcy5wZXJjZW50dWFsID4gMTAwKSB7XG4gICAgICBjaXJjbGUuc3R5bGUuc3Ryb2tlRGFzaG9mZnNldCA9IDA7XG4gICAgICB0aGlzLnBlcmNlbnR1YWwgPSAxMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNpcmNsZS5zdHlsZS5zdHJva2VEYXNob2Zmc2V0ID0gbGVuIC0gKHRoaXMucGVyY2VudHVhbCAvIDEwMCkgKiBsZW47XG4gICAgfVxuXG4gICAgdGhpcy5jb250ZXh0LnBlcmNlbnR1YWwgPSB0aGlzLnBlcmNlbnR1YWw7XG4gICAgdGhpcy5jb250ZXh0LiRpbXBsaWNpdCA9IHRoaXMucGVyY2VudHVhbDtcblxuICB9XG5cbiAgcHJpdmF0ZSBzaG93V2FybmluZ3MoKSB7XG4gICAgaWYgKCF0aGlzLnBlcmNlbnR1YWwgfHwgaXNOYU4odGhpcy5wZXJjZW50dWFsKSkge1xuICAgICAgaWYgKGlzTmFOKHRoaXMuYmFyVmFsdWUpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgJHt0aGlzLm1neFByZWZpeH0gYmFyVmFsdWU6ICR7dGhpcy5iYXJWYWx1ZX1gKTtcbiAgICAgIH0gZWxzZSBpZiAoaXNOYU4odGhpcy50b3RhbCkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGAke3RoaXMubWd4UHJlZml4fSB0b3RhbDogJHt0aGlzLnRvdGFsfWApO1xuICAgICAgfSBlbHNlIGlmICh0aGlzLmJhclZhbHVlID4gdGhpcy50b3RhbCkge1xuICAgICAgICBjb25zb2xlLndhcm4oYCR7dGhpcy5tZ3hQcmVmaXh9IGJhclZhbHVlOiAke3RoaXMuYmFyVmFsdWV9IGlzIG1vcmUgdGhhbiB0b3RhbDogJHt0aGlzLnRvdGFsfWApO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGdldEZvbnRTaXplKHJlZHVjZXI6IG51bWJlciA9IDEpIHtcbiAgICByZXR1cm4gYCR7KHRoaXMuZm9udFNpemUgfHwgKHRoaXMuZGlhbWV0ZXIgLyA0KSkgLyByZWR1Y2VyfXB4YDtcbiAgfVxuXG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBNZ3hDaXJjdWxhclByb2dyZXNzRnVsbEJhckNvbXBvbmVudCB9IGZyb20gJy4vbWd4LWNpcmN1bGFyLXByb2dyZXNzLWZ1bGwtYmFyLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXHJcbiAgICBkZWNsYXJhdGlvbnM6IFtNZ3hDaXJjdWxhclByb2dyZXNzRnVsbEJhckNvbXBvbmVudF0sXHJcbiAgICBleHBvcnRzOiBbTWd4Q2lyY3VsYXJQcm9ncmVzc0Z1bGxCYXJDb21wb25lbnRdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBNZ3hDaXJjdWxhclByb2dyZXNzRnVsbEJhck1vZHVsZSB7IH1cclxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25DaGFuZ2VzLCBUZW1wbGF0ZVJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICdtZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtcGllJyxcbiAgdGVtcGxhdGU6IGA8ZGl2IGNsYXNzPVwiY29udGFpblwiPlxuICAgIDxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHg9XCIwXCIgeT1cIjBcIiBbbmdTdHlsZV09XCJ7J3dpZHRoLnB4JzogZGlhbWV0ZXIsICdoZWlnaHQucHgnOiBkaWFtZXRlciB9XCJcbiAgICAgICAgdmlld0JveD1cIi0xIC0xIDIgMlwiPlxuICAgICAgICA8Y2lyY2xlIGlkPVwiYmFzZS1jaXJjbGVcIiBbYXR0ci5zdHJva2VdPVwiYmdDb2xvclwiIFthdHRyLmZpbGxdPVwiYmdDb2xvclwiIGN4PVwiMFwiIGN5PVwiMFwiIFthdHRyLnJdPVwiYmdTaXplIC8gMjBcIiAvPlxuICAgICAgICA8cGF0aCBpZD1cInBpZS1wYXRoXCIgW2F0dHIuZmlsbF09XCJjb2xvclwiIFthdHRyLmRdPVwicGF0aERhdGFcIiByb3RhdGU9XCI1MFwiPjwvcGF0aD5cbiAgICA8L3N2Zz5cbiAgICA8ZGl2IGNsYXNzPVwibGFiZWxcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnRUZW1wbGF0ZTsgZWxzZSBwcm9qZWN0Q29udGVudFwiPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29udGVudFRlbXBsYXRlXCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjcHJvamVjdENvbnRlbnQ+XG4gICAgICAgICAgICA8ZGl2ICNjb250ZW50UmVmPlxuICAgICAgICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFjb250ZW50UmVmPy5jaGlsZE5vZGVzPy5sZW5ndGhcIiBbc3R5bGUuZm9udC1zaXplXT1cImdldEZvbnRTaXplKClcIj5cbiAgICAgICAgICAgICAgICB7e3BlcmNlbnR1YWx9fTxzcGFuIFtzdHlsZS5mb250LXNpemVdPVwiZ2V0Rm9udFNpemUoMS4yKVwiPiYjMzc7PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG48L2Rpdj5gLFxuICBzdHlsZXM6IFtgLmNvbnRhaW57ZGlzcGxheTotd2Via2l0LWJveDtkaXNwbGF5OmZsZXg7LXdlYmtpdC1ib3gtcGFjazpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjstd2Via2l0LWJveC1hbGlnbjpjZW50ZXI7YWxpZ24taXRlbXM6Y2VudGVyOy13ZWJraXQtYm94LW9yaWVudDp2ZXJ0aWNhbDstd2Via2l0LWJveC1kaXJlY3Rpb246bm9ybWFsO2ZsZXgtZGlyZWN0aW9uOmNvbHVtbjtib3gtc2l6aW5nOmJvcmRlci1ib3g7cG9zaXRpb246cmVsYXRpdmV9I3BhdGh7dHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy1tcy10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7LW1vei10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7dHJhbnNmb3JtLW9yaWdpbjpjZW50ZXIgY2VudGVyOy13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjpjZW50ZXIgY2VudGVyOy1tcy10cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciBjZW50ZXI7LW1vei10cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciBjZW50ZXI7dHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZS1pbi1vdXQ7LXdlYmtpdC10cmFuc2l0aW9uOnN0cm9rZS1kYXNob2Zmc2V0IC4zcyBlYXNlLWluLW91dDstbXMtdHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZS1pbi1vdXQ7LW1vei10cmFuc2l0aW9uOnN0cm9rZS1kYXNob2Zmc2V0IC4zcyBlYXNlLWluLW91dH0jcGllLXBhdGh7dHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy1tcy10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7LW1vei10cmFuc2Zvcm06cm90YXRlKC05MGRlZyl9LmxhYmVse3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO3JpZ2h0OjA7Ym90dG9tOjA7bGVmdDowO2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTpmbGV4O2ZsZXgtd3JhcDp3cmFwOy13ZWJraXQtYm94LXBhY2s6Y2VudGVyO2p1c3RpZnktY29udGVudDpjZW50ZXI7LXdlYmtpdC1ib3gtYWxpZ246Y2VudGVyO2FsaWduLWl0ZW1zOmNlbnRlcjtmb250LWZhbWlseTpLcmVvbiBWYXJpYWJsZUZvbnQ7Y29sb3I6IzdmOGM4ZH1gXVxufSlcbmV4cG9ydCBjbGFzcyBNZ3hDaXJjdWxhclByb2dyZXNzUGllQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICAvKiBEYXRhIHNlY3Rpb24gKi9cbiAgQElucHV0KCkgdG90YWw6IG51bWJlciA9IDE7XG4gIEBJbnB1dCgpIGJhclZhbHVlOiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBwZXJjZW50YWdlOiBudW1iZXIgPSAwO1xuXG4gIC8qIERpc3BsYXkgc2VjdGlvbiAqL1xuICBASW5wdXQoKSBjb250ZW50VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgpIGRpYW1ldGVyOiBudW1iZXIgPSAxNTA7XG4gIEBJbnB1dCgpIGZvbnRTaXplOiBudW1iZXI7XG4gIEBJbnB1dCgpIGNvbG9yOiBzdHJpbmcgPSAnIzMyODJiOCc7XG4gIEBJbnB1dCgpIGJnQ29sb3I6IHN0cmluZyA9ICcjZWVlJztcbiAgQElucHV0KCkgYmdTaXplOiBudW1iZXIgPSAxMDtcbiAgXG4gIHByaXZhdGUgbWd4UHJlZml4ID0gJ21neC1jaXJjdWxhci1wcm9ncmVzcy1waWUnO1xuICBwYXRoRGF0YTogc3RyaW5nO1xuICBuZXdQYXRoRGF0YTogc3RyaW5nO1xuICBwZXJjZW50dWFsOiBudW1iZXIgPSAwO1xuXG4gIGNvbnN0cnVjdG9yKCkge31cbiBcbiAgbmdPbkNoYW5nZXMoKSB7XG5cbiAgICB0aGlzLnNob3dXYXJuaW5ncygpO1xuXG4gICAgdGhpcy5wZXJjZW50dWFsID0gK3RoaXMucGVyY2VudGFnZSB8fCAoK3RoaXMuYmFyVmFsdWUgLyArdGhpcy50b3RhbCkgKiAxMDA7XG5cbiAgICB0aGlzLnBlcmNlbnR1YWwgPSBpc05hTih0aGlzLnBlcmNlbnR1YWwpID8gMCA6ICt0aGlzLnBlcmNlbnR1YWwudG9GaXhlZCgyKTtcbiAgICBpZiAodGhpcy5wZXJjZW50dWFsID4gMTAwKSB7XG4gICAgICB0aGlzLnNldFNsaWNlKDEpXG4gICAgICB0aGlzLnBlcmNlbnR1YWwgPSAxMDA7XG4gICAgfSBlbHNlIHtcbiAgICAgIHRoaXMuc2V0U2xpY2UodGhpcy5wZXJjZW50dWFsIC8gMTAwKVxuICAgIH1cblxuICB9XG5cbiAgcHJpdmF0ZSBzZXRTbGljZShwZXJjZW50KXtcbiAgICBjb25zdCBbZW5kWCwgZW5kWV0gPSB0aGlzLmdldENvb3JkaW5hdGVzRm9yUGVyY2VudChwZXJjZW50KTtcbiAgICBjb25zdCBsYXJnZUFyY0ZsYWcgPSBwZXJjZW50ID4gLjUgPyAxIDogMDtcbiAgICB0aGlzLnBhdGhEYXRhID0gWyBcbiAgICAgIGBNIDEgMGAsIC8vIE1vdmVcbiAgICAgIGBBIDEgMSAwICR7bGFyZ2VBcmNGbGFnfSAxICR7ZW5kWH0gJHtlbmRZfWAsIC8vIEFyY1xuICAgICAgYEwgMCAwYCwgLy8gTGluZVxuICAgIF0uam9pbignICcpOyBcbiAgfVxuXG5cbiAgcHJpdmF0ZSBnZXRDb29yZGluYXRlc0ZvclBlcmNlbnQocGVyY2VudCkge1xuICAgIGNvbnN0IHggPSBNYXRoLmNvcygyICogTWF0aC5QSSAqIHBlcmNlbnQpO1xuICAgIGNvbnN0IHkgPSBNYXRoLnNpbigyICogTWF0aC5QSSAqIHBlcmNlbnQpO1xuICAgIHJldHVybiBbeCwgeV07XG4gIH1cblxuICBwcml2YXRlIHNob3dXYXJuaW5ncygpIHtcbiAgICBpZiAoIXRoaXMucGVyY2VudGFnZSB8fCBpc05hTih0aGlzLnBlcmNlbnRhZ2UpKSB7XG4gICAgICBpZiAoaXNOYU4odGhpcy5iYXJWYWx1ZSkpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGAke3RoaXMubWd4UHJlZml4fSBiYXJWYWx1ZTogJHt0aGlzLmJhclZhbHVlfWApO1xuICAgICAgfSBlbHNlIGlmIChpc05hTih0aGlzLnRvdGFsKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYCR7dGhpcy5tZ3hQcmVmaXh9IHRvdGFsOiAke3RoaXMudG90YWx9YCk7XG4gICAgICB9IGVsc2UgaWYgKHRoaXMuYmFyVmFsdWUgPiB0aGlzLnRvdGFsKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgJHt0aGlzLm1neFByZWZpeH0gYmFyVmFsdWU6ICR7dGhpcy5iYXJWYWx1ZX0gaXMgbW9yZSB0aGFuIHRvdGFsOiAke3RoaXMudG90YWx9YCk7XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgZ2V0Rm9udFNpemUocmVkdWNlcjogbnVtYmVyID0gMSkge1xuICAgIHJldHVybiBgJHsodGhpcy5mb250U2l6ZSB8fCAodGhpcy5kaWFtZXRlciAvIDQpKSAvIHJlZHVjZXJ9cHhgO1xuICB9XG59XG4iLCJpbXBvcnQgeyBOZ01vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBNZ3hDaXJjdWxhclByb2dyZXNzUGllQ29tcG9uZW50IH0gZnJvbSAnLi9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtcGllLmNvbXBvbmVudCc7XHJcbmltcG9ydCB7IENvbW1vbk1vZHVsZSB9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XHJcblxyXG5ATmdNb2R1bGUoe1xyXG4gICAgaW1wb3J0czogW0NvbW1vbk1vZHVsZV0sXHJcbiAgICBkZWNsYXJhdGlvbnM6IFtNZ3hDaXJjdWxhclByb2dyZXNzUGllQ29tcG9uZW50XSxcclxuICAgIGV4cG9ydHM6IFtNZ3hDaXJjdWxhclByb2dyZXNzUGllQ29tcG9uZW50XVxyXG59KVxyXG5leHBvcnQgY2xhc3MgTWd4Q2lyY3VsYXJQcm9ncmVzc1BpZU1vZHVsZSB7IH1cclxuIiwiaW1wb3J0IHsgQ29tcG9uZW50LCBJbnB1dCwgT25DaGFuZ2VzLCBWaWV3Q2hpbGQsIEVsZW1lbnRSZWYsIFRlbXBsYXRlUmVmIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21neC1jaXJjdWxhci1wcm9ncmVzcy1iYXInLFxuICB0ZW1wbGF0ZTogYFxuICA8ZGl2IGNsYXNzPVwiY29udGFpblwiPlxuICAgIDxzdmcgIHhtbG5zPVwiaHR0cDovL3d3dy53My5vcmcvMjAwMC9zdmdcIiB4PVwiMFwiIHk9XCIwXCIgW25nU3R5bGVdPVwieyd3aWR0aC5weCc6IGRpYW1ldGVyLCAnaGVpZ2h0LnB4JzogZGlhbWV0ZXIgfVwiIHZpZXdCb3g9XCIwIDAgMjAwIDIwMFwiPlxuICAgICAgICA8Y2lyY2xlIGlkPVwiYmFzZS1jaXJjbGVcIiBbYXR0ci5zdHJva2VdPVwiYmdDb2xvclwiIGZpbGw9XCJub25lXCIgc3Ryb2tlLXdpZHRoPVwiMTVcIiBjeD1cIjEwMFwiIGN5PVwiMTAwXCJcbiAgICAgICAgICAgIFthdHRyLnJdPVwicmFkaXVzXCIgLz5cbiAgICAgICAgPGNpcmNsZSBpZD1cInBhdGhcIiAjY2lyY2xlUGF0aCBbYXR0ci5zdHJva2VdPVwiY29sb3JcIiBmaWxsPVwibm9uZVwiIHN0cm9rZS13aWR0aD1cIjE1XCIgY3g9XCIxMDBcIiBjeT1cIjEwMFwiXG4gICAgICAgICAgICBbYXR0ci5yXT1cInJhZGl1c1wiIHJvdGF0ZT1cIjUwXCIgLz5cbiAgICA8L3N2Zz5cbiAgICA8ZGl2IGNsYXNzPVwibGFiZWxcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbnRlbnRUZW1wbGF0ZTsgZWxzZSBwcm9qZWN0Q29udGVudFwiPlxuICAgICAgICAgICAgPG5nLXRlbXBsYXRlICpuZ1RlbXBsYXRlT3V0bGV0PVwiY29udGVudFRlbXBsYXRlOyBjb250ZXh0OiBjb250ZXh0XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjcHJvamVjdENvbnRlbnQ+XG4gICAgICAgICAgICA8ZGl2ICNjb250ZW50UmVmPlxuICAgICAgICAgICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPGRpdiAqbmdJZj1cIiFjb250ZW50UmVmPy5jaGlsZE5vZGVzPy5sZW5ndGhcIiBbc3R5bGUuZm9udC1zaXplXT1cImdldEZvbnRTaXplKClcIj5cbiAgICAgICAgICAgICAgICB7e3BlcmNlbnR1YWx9fTxzcGFuIFtzdHlsZS5mb250LXNpemVdPVwiZ2V0Rm9udFNpemUoMS4yKVwiPiYjMzc7PC9zcGFuPlxuICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgPC9kaXY+XG48L2Rpdj5gLFxuICBzdHlsZXM6IFtgLmNvbnRhaW57ZGlzcGxheTotd2Via2l0LWJveDtkaXNwbGF5OmZsZXg7LXdlYmtpdC1ib3gtcGFjazpjZW50ZXI7anVzdGlmeS1jb250ZW50OmNlbnRlcjstd2Via2l0LWJveC1hbGlnbjpjZW50ZXI7YWxpZ24taXRlbXM6Y2VudGVyOy13ZWJraXQtYm94LW9yaWVudDp2ZXJ0aWNhbDstd2Via2l0LWJveC1kaXJlY3Rpb246bm9ybWFsO2ZsZXgtZGlyZWN0aW9uOmNvbHVtbjtib3gtc2l6aW5nOmJvcmRlci1ib3g7cG9zaXRpb246cmVsYXRpdmV9I3BhdGh7dHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy1tcy10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7LW1vei10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7dHJhbnNmb3JtLW9yaWdpbjpjZW50ZXIgY2VudGVyOy13ZWJraXQtdHJhbnNmb3JtLW9yaWdpbjpjZW50ZXIgY2VudGVyOy1tcy10cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciBjZW50ZXI7LW1vei10cmFuc2Zvcm0tb3JpZ2luOmNlbnRlciBjZW50ZXI7dHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZS1pbi1vdXQ7LXdlYmtpdC10cmFuc2l0aW9uOnN0cm9rZS1kYXNob2Zmc2V0IC4zcyBlYXNlLWluLW91dDstbXMtdHJhbnNpdGlvbjpzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZS1pbi1vdXQ7LW1vei10cmFuc2l0aW9uOnN0cm9rZS1kYXNob2Zmc2V0IC4zcyBlYXNlLWluLW91dH0jcGllLXBhdGh7dHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy13ZWJraXQtdHJhbnNmb3JtOnJvdGF0ZSgtOTBkZWcpOy1tcy10cmFuc2Zvcm06cm90YXRlKC05MGRlZyk7LW1vei10cmFuc2Zvcm06cm90YXRlKC05MGRlZyl9LmxhYmVse3Bvc2l0aW9uOmFic29sdXRlO3RvcDowO3JpZ2h0OjA7Ym90dG9tOjA7bGVmdDowO2Rpc3BsYXk6LXdlYmtpdC1ib3g7ZGlzcGxheTpmbGV4O2ZsZXgtd3JhcDp3cmFwOy13ZWJraXQtYm94LXBhY2s6Y2VudGVyO2p1c3RpZnktY29udGVudDpjZW50ZXI7LXdlYmtpdC1ib3gtYWxpZ246Y2VudGVyO2FsaWduLWl0ZW1zOmNlbnRlcjtmb250LWZhbWlseTpLcmVvbiBWYXJpYWJsZUZvbnQ7Y29sb3I6IzdmOGM4ZH1gXVxufSlcbmV4cG9ydCBjbGFzcyBNZ3hDaXJjdWxhclByb2dyZXNzQmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICAvKiBEYXRhIHNlY3Rpb24gKi9cbiAgQElucHV0KCkgdG90YWw6IG51bWJlciA9IDE7XG4gIEBJbnB1dCgpIGJhclZhbHVlOiBudW1iZXIgPSAwO1xuICBASW5wdXQoKSBwZXJjZW50YWdlOiBudW1iZXIgPSAwO1xuXG4gIC8qIERpc3BsYXkgc2VjdGlvbiAqL1xuICBASW5wdXQoKSBjb250ZW50VGVtcGxhdGU6IFRlbXBsYXRlUmVmPGFueT47XG4gIEBJbnB1dCgpIGRpYW1ldGVyOiBudW1iZXIgPSAxNTA7XG4gIEBJbnB1dCgpIGZvbnRTaXplOiBudW1iZXI7XG4gIEBJbnB1dCgpIGNvbG9yOiBzdHJpbmcgPSAnIzMyODJiOCc7XG4gIEBJbnB1dCgpIGJnQ29sb3I6IHN0cmluZyA9ICcjZWVlJztcbiAgcHVibGljIHJhZGl1czogbnVtYmVyID0gOTA7XG4gIHByaXZhdGUgbWd4UHJlZml4ID0gJ21neC1jaXJjdWxhci1wcm9ncmVzcy1iYXInO1xuICBwZXJjZW50dWFsOiBudW1iZXIgPSAwO1xuICBjb250ZXh0OiBhbnkgPSB7IHBlcmNlbnR1YWw6IDAsICRpbXBsaWNpdDogMCB9O1xuXG4gIEBWaWV3Q2hpbGQoJ2NpcmNsZVBhdGgnKSBjaXJjbGVQYXRoOiBFbGVtZW50UmVmO1xuXG4gIGNvbnN0cnVjdG9yKCkgeyB9XG5cbiAgbmdPbkNoYW5nZXMoKSB7XG4gICAgY29uc3QgY2lyY2xlID0gdGhpcy5jaXJjbGVQYXRoLm5hdGl2ZUVsZW1lbnQ7XG4gICAgY29uc3QgbGVuID0gMiAqIE1hdGguUEkgKiB0aGlzLnJhZGl1cztcbiAgICBjaXJjbGUuc3R5bGUuc3Ryb2tlRGFzaGFycmF5ID0gbGVuO1xuXG4gICAgdGhpcy5zaG93V2FybmluZ3MoKTtcblxuICAgIHRoaXMucGVyY2VudHVhbCA9ICt0aGlzLnBlcmNlbnRhZ2UgfHwgKCt0aGlzLmJhclZhbHVlIC8gK3RoaXMudG90YWwpICogMTAwO1xuXG4gICAgdGhpcy5wZXJjZW50dWFsID0gaXNOYU4odGhpcy5wZXJjZW50dWFsKSA/IDAgOiArdGhpcy5wZXJjZW50dWFsLnRvRml4ZWQoMik7XG4gICAgaWYgKHRoaXMucGVyY2VudHVhbCA+IDEwMCkge1xuICAgICAgY2lyY2xlLnN0eWxlLnN0cm9rZURhc2hvZmZzZXQgPSAwO1xuICAgICAgdGhpcy5wZXJjZW50dWFsID0gMTAwO1xuICAgIH0gZWxzZSB7XG4gICAgICBjaXJjbGUuc3R5bGUuc3Ryb2tlRGFzaG9mZnNldCA9IGxlbiAtICh0aGlzLnBlcmNlbnR1YWwgLyAxMDApICogbGVuO1xuICAgIH1cblxuICAgIHRoaXMuY29udGV4dC5wZXJjZW50dWFsID0gdGhpcy5wZXJjZW50dWFsO1xuICAgIHRoaXMuY29udGV4dC4kaW1wbGljaXQgPSB0aGlzLnBlcmNlbnR1YWw7XG5cbiAgfVxuXG4gIHByaXZhdGUgc2hvd1dhcm5pbmdzKCkge1xuICAgIGlmICghdGhpcy5wZXJjZW50YWdlIHx8IGlzTmFOKHRoaXMucGVyY2VudGFnZSkpIHtcbiAgICAgIGlmIChpc05hTih0aGlzLmJhclZhbHVlKSkge1xuICAgICAgICBjb25zb2xlLndhcm4oYCR7dGhpcy5tZ3hQcmVmaXh9IGJhclZhbHVlOiAke3RoaXMuYmFyVmFsdWV9YCk7XG4gICAgICB9IGVsc2UgaWYgKGlzTmFOKHRoaXMudG90YWwpKSB7XG4gICAgICAgIGNvbnNvbGUud2FybihgJHt0aGlzLm1neFByZWZpeH0gdG90YWw6ICR7dGhpcy50b3RhbH1gKTtcbiAgICAgIH0gZWxzZSBpZiAodGhpcy5iYXJWYWx1ZSA+IHRoaXMudG90YWwpIHtcbiAgICAgICAgY29uc29sZS53YXJuKGAke3RoaXMubWd4UHJlZml4fSBiYXJWYWx1ZTogJHt0aGlzLmJhclZhbHVlfSBpcyBtb3JlIHRoYW4gdG90YWw6ICR7dGhpcy50b3RhbH1gKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICBnZXRGb250U2l6ZShyZWR1Y2VyOiBudW1iZXIgPSAxKSB7XG4gICAgcmV0dXJuIGAkeyh0aGlzLmZvbnRTaXplIHx8ICh0aGlzLmRpYW1ldGVyIC8gNCkpIC8gcmVkdWNlcn1weGA7XG4gIH1cblxufVxuIiwiaW1wb3J0IHsgTmdNb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgTWd4Q2lyY3VsYXJQcm9ncmVzc0JhckNvbXBvbmVudCB9IGZyb20gJy4vbWd4LWNpcmN1bGFyLXByb2dyZXNzLWJhci5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5cclxuQE5nTW9kdWxlKHtcclxuICAgIGltcG9ydHM6IFtDb21tb25Nb2R1bGVdLFxyXG4gICAgZGVjbGFyYXRpb25zOiBbTWd4Q2lyY3VsYXJQcm9ncmVzc0JhckNvbXBvbmVudF0sXHJcbiAgICBleHBvcnRzOiBbTWd4Q2lyY3VsYXJQcm9ncmVzc0JhckNvbXBvbmVudF1cclxufSlcclxuZXhwb3J0IGNsYXNzIE1neENpcmN1bGFyUHJvZ3Jlc3NCYXJNb2R1bGUgeyB9XHJcbiIsImltcG9ydCB7IE5nTW9kdWxlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBDb21tb25Nb2R1bGUgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTWd4Q2lyY3VsYXJQcm9ncmVzc0Z1bGxCYXJNb2R1bGUgfSBmcm9tICcuL21neC1jaXJjdWxhci1wcm9ncmVzcy1mdWxsLWJhci9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtZnVsbC1iYXIubW9kdWxlJztcbmltcG9ydCB7IE1neENpcmN1bGFyUHJvZ3Jlc3NQaWVNb2R1bGUgfSBmcm9tICcuL21neC1jaXJjdWxhci1wcm9ncmVzcy1waWUvbWd4LWNpcmN1bGFyLXByb2dyZXNzLXBpZS5tb2R1bGUnO1xuaW1wb3J0IHsgTWd4Q2lyY3VsYXJQcm9ncmVzc0Jhck1vZHVsZSB9IGZyb20gJy4vbWd4LWNpcmN1bGFyLXByb2dyZXNzLWJhci9tZ3gtY2lyY3VsYXItcHJvZ3Jlc3MtYmFyLm1vZHVsZSc7XG5cbkBOZ01vZHVsZSh7XG4gIGltcG9ydHM6IFtcbiAgICBDb21tb25Nb2R1bGUsXG4gICAgTWd4Q2lyY3VsYXJQcm9ncmVzc0Jhck1vZHVsZSxcbiAgICBNZ3hDaXJjdWxhclByb2dyZXNzUGllTW9kdWxlLFxuICAgIE1neENpcmN1bGFyUHJvZ3Jlc3NGdWxsQmFyTW9kdWxlXG4gIF0sXG4gIGV4cG9ydHM6IFtcbiAgICBNZ3hDaXJjdWxhclByb2dyZXNzQmFyTW9kdWxlLFxuICAgIE1neENpcmN1bGFyUHJvZ3Jlc3NQaWVNb2R1bGUsXG4gICAgTWd4Q2lyY3VsYXJQcm9ncmVzc0Z1bGxCYXJNb2R1bGVcbiAgXVxufSlcbmV4cG9ydCBjbGFzcyBNZ3hDaXJjdWxhclByb2dyZXNzTW9kdWxlIHsgfVxuIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7QUFBQTtJQThDRTtxQkFsQnlCLENBQUM7d0JBQ0UsQ0FBQzswQkFDQyxDQUFDO3dCQUlILEdBQUc7cUJBRU4sU0FBUzt1QkFDUCxNQUFNOzJCQUNGLEVBQUU7NEJBQ0QsRUFBRTt5QkFHZCxnQ0FBZ0M7MEJBQy9CLENBQUM7dUJBQ1AsRUFBRSxVQUFVLEVBQUUsQ0FBQyxFQUFFLFNBQVMsRUFBRSxDQUFDLEVBQUU7S0FFN0I7Ozs7SUFFakIsV0FBVzs7UUFDVCxNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLGFBQWEsQ0FBQzs7UUFDN0MsTUFBTSxHQUFHLEdBQUcsQ0FBQyxHQUFHLElBQUksQ0FBQyxFQUFFLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQztRQUM1QyxNQUFNLENBQUMsS0FBSyxDQUFDLGVBQWUsR0FBRyxHQUFHLENBQUM7UUFFbkMsSUFBSSxDQUFDLFlBQVksRUFBRSxDQUFDO1FBRXBCLElBQUksQ0FBQyxVQUFVLEdBQUcsQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLENBQUMsQ0FBQyxJQUFJLENBQUMsUUFBUSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssSUFB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