UNPKG

ng-zorro-antd

Version:

An enterprise-class UI components based on Ant Design and Angular

511 lines 49.7 kB
/** * @fileoverview added by tsickle * Generated from: progress.component.ts * @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import { __decorate, __metadata } from "tslib"; /** * @license * Copyright Alibaba.com All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://github.com/NG-ZORRO/ng-zorro-antd/blob/master/LICENSE */ import { ChangeDetectionStrategy, Component, Input, ViewEncapsulation } from '@angular/core'; import { NzConfigService, WithConfig } from 'ng-zorro-antd/core/config'; import { InputNumber, isNotNil } from 'ng-zorro-antd/core/util'; import { Subject } from 'rxjs'; import { takeUntil } from 'rxjs/operators'; import { handleCircleGradient, handleLinearGradient } from './utils'; /** @type {?} */ var gradientIdSeed = 0; /** @type {?} */ var NZ_CONFIG_COMPONENT_NAME = 'progress'; /** @type {?} */ var statusIconNameMap = new Map([ ['success', 'check'], ['exception', 'close'] ]); /** @type {?} */ var statusColorMap = new Map([ ['normal', '#108ee9'], ['exception', '#ff5500'], ['success', '#87d068'] ]); /** @type {?} */ var defaultFormatter = (/** * @param {?} p * @return {?} */ function (p) { return p + "%"; }); var ɵ0 = defaultFormatter; var NzProgressComponent = /** @class */ (function () { function NzProgressComponent(nzConfigService) { this.nzConfigService = nzConfigService; this.nzWidth = 132; this.nzPercent = 0; this.nzType = 'line'; this.steps = []; /** * Gradient style when `nzType` is `line`. */ this.lineGradient = null; /** * If user uses gradient color. */ this.isGradient = false; /** * If the linear progress is a step progress. */ this.isSteps = false; /** * Each progress whose `nzType` is circle or dashboard should have unique id to * define `<linearGradient>`. */ this.gradientId = gradientIdSeed++; /** * Paths to rendered in the template. */ this.progressCirclePath = []; this.trackByFn = (/** * @param {?} index * @return {?} */ function (index) { return "" + index; }); this.cachedStatus = 'normal'; this.inferredStatus = 'normal'; this.destroy$ = new Subject(); } Object.defineProperty(NzProgressComponent.prototype, "formatter", { get: /** * @return {?} */ function () { return this.nzFormat || defaultFormatter; }, enumerable: true, configurable: true }); Object.defineProperty(NzProgressComponent.prototype, "status", { get: /** * @return {?} */ function () { return this.nzStatus || this.inferredStatus; }, enumerable: true, configurable: true }); Object.defineProperty(NzProgressComponent.prototype, "strokeWidth", { get: /** * @return {?} */ function () { return this.nzStrokeWidth || (this.nzType === 'line' && this.nzSize !== 'small' ? 8 : 6); }, enumerable: true, configurable: true }); Object.defineProperty(NzProgressComponent.prototype, "isCircleStyle", { get: /** * @return {?} */ function () { return this.nzType === 'circle' || this.nzType === 'dashboard'; }, enumerable: true, configurable: true }); /** * @param {?} changes * @return {?} */ NzProgressComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { var nzSteps = changes.nzSteps, nzGapPosition = changes.nzGapPosition, nzStrokeLinecap = changes.nzStrokeLinecap, nzStrokeColor = changes.nzStrokeColor, nzGapDegree = changes.nzGapDegree, nzType = changes.nzType, nzStatus = changes.nzStatus, nzPercent = changes.nzPercent, nzSuccessPercent = changes.nzSuccessPercent; if (nzStatus) { this.cachedStatus = this.nzStatus || this.cachedStatus; } if (nzPercent || nzSuccessPercent) { /** @type {?} */ var fillAll = parseInt(this.nzPercent.toString(), 10) >= 100; if (fillAll) { if ((isNotNil(this.nzSuccessPercent) && (/** @type {?} */ (this.nzSuccessPercent)) >= 100) || this.nzSuccessPercent === undefined) { this.inferredStatus = 'success'; } } else { this.inferredStatus = this.cachedStatus; } } if (nzStatus || nzPercent || nzSuccessPercent) { this.updateIcon(); } if (nzStrokeColor) { this.setStrokeColor(); } if (nzGapPosition || nzStrokeLinecap || nzGapDegree || nzType || nzPercent || nzStrokeColor) { this.getCirclePaths(); } if (nzSteps) { this.isSteps = isNotNil(nzSteps.currentValue); this.getSteps(); } }; /** * @return {?} */ NzProgressComponent.prototype.ngOnInit = /** * @return {?} */ function () { var _this = this; this.nzConfigService .getConfigChangeEventForComponent(NZ_CONFIG_COMPONENT_NAME) .pipe(takeUntil(this.destroy$)) .subscribe((/** * @return {?} */ function () { _this.updateIcon(); _this.setStrokeColor(); _this.getCirclePaths(); })); }; /** * @return {?} */ NzProgressComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.destroy$.next(); this.destroy$.complete(); }; /** * @private * @return {?} */ NzProgressComponent.prototype.updateIcon = /** * @private * @return {?} */ function () { /** @type {?} */ var ret = statusIconNameMap.get(this.status); this.icon = ret ? ret + (this.isCircleStyle ? '-o' : '-circle-fill') : ''; }; /** * Calculate step render configs. */ /** * Calculate step render configs. * @private * @return {?} */ NzProgressComponent.prototype.getSteps = /** * Calculate step render configs. * @private * @return {?} */ function () { /** @type {?} */ var current = Math.floor((/** @type {?} */ (this.nzSteps)) * (this.nzPercent / 100)); /** @type {?} */ var stepWidth = this.nzSize === 'small' ? 2 : 14; for (var i = 0; i < (/** @type {?} */ (this.nzSteps)); i++) { /** @type {?} */ var color = void 0; if (i <= current - 1) { color = this.nzStrokeColor; } /** @type {?} */ var stepStyle = { backgroundColor: "" + color, width: stepWidth + "px", height: this.strokeWidth + "px" }; this.steps.push(stepStyle); } }; /** * Calculate paths when the type is circle or dashboard. */ /** * Calculate paths when the type is circle or dashboard. * @private * @return {?} */ NzProgressComponent.prototype.getCirclePaths = /** * Calculate paths when the type is circle or dashboard. * @private * @return {?} */ function () { var _this = this; if (!this.isCircleStyle) { return; } /** @type {?} */ var values = isNotNil(this.nzSuccessPercent) ? [(/** @type {?} */ (this.nzSuccessPercent)), this.nzPercent] : [this.nzPercent]; // Calculate shared styles. /** @type {?} */ var radius = 50 - this.strokeWidth / 2; /** @type {?} */ var gapPosition = this.nzGapPosition || (this.nzType === 'circle' ? 'top' : 'bottom'); /** @type {?} */ var len = Math.PI * 2 * radius; /** @type {?} */ var gapDegree = this.nzGapDegree || (this.nzType === 'circle' ? 0 : 75); /** @type {?} */ var beginPositionX = 0; /** @type {?} */ var beginPositionY = -radius; /** @type {?} */ var endPositionX = 0; /** @type {?} */ var endPositionY = radius * -2; switch (gapPosition) { case 'left': beginPositionX = -radius; beginPositionY = 0; endPositionX = radius * 2; endPositionY = 0; break; case 'right': beginPositionX = radius; beginPositionY = 0; endPositionX = radius * -2; endPositionY = 0; break; case 'bottom': beginPositionY = radius; endPositionY = radius * 2; break; default: } this.pathString = "M 50,50 m " + beginPositionX + "," + beginPositionY + "\n a " + radius + "," + radius + " 0 1 1 " + endPositionX + "," + -endPositionY + "\n a " + radius + "," + radius + " 0 1 1 " + -endPositionX + "," + endPositionY; this.trailPathStyle = { strokeDasharray: len - gapDegree + "px " + len + "px", strokeDashoffset: "-" + gapDegree / 2 + "px", transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s' }; // Calculate styles for each path. this.progressCirclePath = values .map((/** * @param {?} value * @param {?} index * @return {?} */ function (value, index) { /** @type {?} */ var isSuccessPercent = values.length === 2 && index === 0; return { stroke: _this.isGradient && !isSuccessPercent ? "url(#gradient-" + _this.gradientId + ")" : null, strokePathStyle: { stroke: !_this.isGradient ? (isSuccessPercent ? statusColorMap.get('success') : ((/** @type {?} */ (_this.nzStrokeColor)))) : null, transition: 'stroke-dashoffset .3s ease 0s, stroke-dasharray .3s ease 0s, stroke .3s, stroke-width .06s ease .3s', strokeDasharray: ((value || 0) / 100) * (len - gapDegree) + "px " + len + "px", strokeDashoffset: "-" + gapDegree / 2 + "px" } }; })) .reverse(); }; /** * @private * @return {?} */ NzProgressComponent.prototype.setStrokeColor = /** * @private * @return {?} */ function () { /** @type {?} */ var color = this.nzStrokeColor; /** @type {?} */ var isGradient = (this.isGradient = !!color && typeof color !== 'string'); if (isGradient && !this.isCircleStyle) { this.lineGradient = handleLinearGradient((/** @type {?} */ (color))); } else if (isGradient && this.isCircleStyle) { this.circleGradient = handleCircleGradient((/** @type {?} */ (this.nzStrokeColor))); } else { this.lineGradient = null; this.circleGradient = []; } }; NzProgressComponent.decorators = [ { type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, selector: 'nz-progress', exportAs: 'nzProgress', preserveWhitespaces: false, template: "\n <ng-template #progressInfoTemplate>\n <span class=\"ant-progress-text\" *ngIf=\"nzShowInfo\">\n <ng-container *ngIf=\"(status === 'exception' || status === 'success') && !nzFormat; else formatTemplate\">\n <i nz-icon [nzType]=\"icon\"></i>\n </ng-container>\n <ng-template #formatTemplate>\n <ng-container *nzStringTemplateOutlet=\"formatter; context: { $implicit: nzPercent }\">\n {{ $any(formatter)(nzPercent) }}\n </ng-container>\n </ng-template>\n </span>\n </ng-template>\n\n <div\n [ngClass]=\"'ant-progress ant-progress-status-' + status\"\n [class.ant-progress-line]=\"nzType == 'line'\"\n [class.ant-progress-small]=\"nzSize == 'small'\"\n [class.ant-progress-show-info]=\"nzShowInfo\"\n [class.ant-progress-circle]=\"isCircleStyle\"\n [class.ant-progress-steps]=\"isSteps\"\n >\n <!-- line progress -->\n <div *ngIf=\"nzType === 'line'\">\n <ng-container *ngIf=\"!isSteps\">\n <div class=\"ant-progress-outer\" *ngIf=\"!isSteps\">\n <div class=\"ant-progress-inner\">\n <div\n class=\"ant-progress-bg\"\n [style.width.%]=\"nzPercent\"\n [style.border-radius]=\"nzStrokeLinecap === 'round' ? '100px' : '0'\"\n [style.background]=\"!isGradient ? nzStrokeColor : null\"\n [style.background-image]=\"isGradient ? lineGradient : null\"\n [style.height.px]=\"strokeWidth\"\n ></div>\n <div\n *ngIf=\"nzSuccessPercent || nzSuccessPercent === 0\"\n class=\"ant-progress-success-bg\"\n [style.width.%]=\"nzSuccessPercent\"\n [style.border-radius]=\"nzStrokeLinecap === 'round' ? '100px' : '0'\"\n [style.height.px]=\"strokeWidth\"\n ></div>\n </div>\n </div>\n <ng-template [ngTemplateOutlet]=\"progressInfoTemplate\"></ng-template>\n </ng-container>\n <!-- Step style progress -->\n <div class=\"ant-progress-steps-outer\" *ngIf=\"isSteps\">\n <div *ngFor=\"let step of steps; let i = index\" class=\"ant-progress-steps-item\" [ngStyle]=\"step\"></div>\n <ng-template [ngTemplateOutlet]=\"progressInfoTemplate\"></ng-template>\n </div>\n </div>\n\n <!-- circle / dashboard progress -->\n <div\n [style.width.px]=\"this.nzWidth\"\n [style.height.px]=\"this.nzWidth\"\n [style.fontSize.px]=\"this.nzWidth * 0.15 + 6\"\n class=\"ant-progress-inner\"\n [class.ant-progress-circle-gradient]=\"isGradient\"\n *ngIf=\"isCircleStyle\"\n >\n <svg class=\"ant-progress-circle \" viewBox=\"0 0 100 100\">\n <defs *ngIf=\"isGradient\">\n <linearGradient [id]=\"'gradient-' + gradientId\" x1=\"100%\" y1=\"0%\" x2=\"0%\" y2=\"0%\">\n <stop *ngFor=\"let i of circleGradient\" [attr.offset]=\"i.offset\" [attr.stop-color]=\"i.color\"></stop>\n </linearGradient>\n </defs>\n <path\n class=\"ant-progress-circle-trail\"\n stroke=\"#f3f3f3\"\n fill-opacity=\"0\"\n [attr.stroke-width]=\"strokeWidth\"\n [attr.d]=\"pathString\"\n [ngStyle]=\"trailPathStyle\"\n ></path>\n <path\n *ngFor=\"let p of progressCirclePath; trackBy: trackByFn\"\n class=\"ant-progress-circle-path\"\n fill-opacity=\"0\"\n [attr.d]=\"pathString\"\n [attr.stroke-linecap]=\"nzStrokeLinecap\"\n [attr.stroke]=\"p.stroke\"\n [attr.stroke-width]=\"nzPercent ? strokeWidth : 0\"\n [ngStyle]=\"p.strokePathStyle\"\n ></path>\n </svg>\n <ng-template [ngTemplateOutlet]=\"progressInfoTemplate\"></ng-template>\n </div>\n </div>\n " }] } ]; /** @nocollapse */ NzProgressComponent.ctorParameters = function () { return [ { type: NzConfigService } ]; }; NzProgressComponent.propDecorators = { nzShowInfo: [{ type: Input }], nzWidth: [{ type: Input }], nzStrokeColor: [{ type: Input }], nzSize: [{ type: Input }], nzFormat: [{ type: Input }], nzSuccessPercent: [{ type: Input }], nzPercent: [{ type: Input }], nzStrokeWidth: [{ type: Input }], nzGapDegree: [{ type: Input }], nzStatus: [{ type: Input }], nzType: [{ type: Input }], nzGapPosition: [{ type: Input }], nzStrokeLinecap: [{ type: Input }], nzSteps: [{ type: Input }] }; __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME, true), __metadata("design:type", Boolean) ], NzProgressComponent.prototype, "nzShowInfo", void 0); __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME), __metadata("design:type", Object) ], NzProgressComponent.prototype, "nzStrokeColor", void 0); __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME, 'default'), __metadata("design:type", String) ], NzProgressComponent.prototype, "nzSize", void 0); __decorate([ InputNumber(), __metadata("design:type", Number) ], NzProgressComponent.prototype, "nzSuccessPercent", void 0); __decorate([ InputNumber(), __metadata("design:type", Number) ], NzProgressComponent.prototype, "nzPercent", void 0); __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME), InputNumber(), __metadata("design:type", Number) ], NzProgressComponent.prototype, "nzStrokeWidth", void 0); __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME), InputNumber(), __metadata("design:type", Number) ], NzProgressComponent.prototype, "nzGapDegree", void 0); __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME, 'top'), __metadata("design:type", String) ], NzProgressComponent.prototype, "nzGapPosition", void 0); __decorate([ WithConfig(NZ_CONFIG_COMPONENT_NAME, 'round'), __metadata("design:type", String) ], NzProgressComponent.prototype, "nzStrokeLinecap", void 0); __decorate([ InputNumber(), __metadata("design:type", Number) ], NzProgressComponent.prototype, "nzSteps", void 0); return NzProgressComponent; }()); export { NzProgressComponent }; if (false) { /** @type {?} */ NzProgressComponent.ngAcceptInputType_nzSuccessPercent; /** @type {?} */ NzProgressComponent.ngAcceptInputType_nzPercent; /** @type {?} */ NzProgressComponent.ngAcceptInputType_nzStrokeWidth; /** @type {?} */ NzProgressComponent.ngAcceptInputType_nzGapDegree; /** @type {?} */ NzProgressComponent.ngAcceptInputType_nzSteps; /** @type {?} */ NzProgressComponent.prototype.nzShowInfo; /** @type {?} */ NzProgressComponent.prototype.nzWidth; /** @type {?} */ NzProgressComponent.prototype.nzStrokeColor; /** @type {?} */ NzProgressComponent.prototype.nzSize; /** @type {?} */ NzProgressComponent.prototype.nzFormat; /** @type {?} */ NzProgressComponent.prototype.nzSuccessPercent; /** @type {?} */ NzProgressComponent.prototype.nzPercent; /** @type {?} */ NzProgressComponent.prototype.nzStrokeWidth; /** @type {?} */ NzProgressComponent.prototype.nzGapDegree; /** @type {?} */ NzProgressComponent.prototype.nzStatus; /** @type {?} */ NzProgressComponent.prototype.nzType; /** @type {?} */ NzProgressComponent.prototype.nzGapPosition; /** @type {?} */ NzProgressComponent.prototype.nzStrokeLinecap; /** @type {?} */ NzProgressComponent.prototype.nzSteps; /** @type {?} */ NzProgressComponent.prototype.steps; /** * Gradient style when `nzType` is `line`. * @type {?} */ NzProgressComponent.prototype.lineGradient; /** * If user uses gradient color. * @type {?} */ NzProgressComponent.prototype.isGradient; /** * If the linear progress is a step progress. * @type {?} */ NzProgressComponent.prototype.isSteps; /** * Each progress whose `nzType` is circle or dashboard should have unique id to * define `<linearGradient>`. * @type {?} */ NzProgressComponent.prototype.gradientId; /** * Paths to rendered in the template. * @type {?} */ NzProgressComponent.prototype.progressCirclePath; /** @type {?} */ NzProgressComponent.prototype.circleGradient; /** @type {?} */ NzProgressComponent.prototype.trailPathStyle; /** @type {?} */ NzProgressComponent.prototype.pathString; /** @type {?} */ NzProgressComponent.prototype.icon; /** @type {?} */ NzProgressComponent.prototype.trackByFn; /** * @type {?} * @private */ NzProgressComponent.prototype.cachedStatus; /** * @type {?} * @private */ NzProgressComponent.prototype.inferredStatus; /** * @type {?} * @private */ NzProgressComponent.prototype.destroy$; /** @type {?} */ NzProgressComponent.prototype.nzConfigService; } export { ɵ0 }; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvZ3Jlc3MuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vbmctem9ycm8tYW50ZC9wcm9ncmVzcy8iLCJzb3VyY2VzIjpbInByb2dyZXNzLmNvbXBvbmVudC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7O0FBUUEsT0FBTyxFQUFFLHVCQUF1QixFQUFFLFNBQVMsRUFBRSxLQUFLLEVBQStDLGlCQUFpQixFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzFJLE9BQU8sRUFBRSxlQUFlLEVBQUUsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFFeEUsT0FBTyxFQUFFLFdBQVcsRUFBRSxRQUFRLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNoRSxPQUFPLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQy9CLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQWMzQyxPQUFPLEVBQUUsb0JBQW9CLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSxTQUFTLENBQUM7O0lBRWpFLGNBQWMsR0FBRyxDQUFDOztJQUVoQix3QkFBd0IsR0FBRyxVQUFVOztJQUNyQyxpQkFBaUIsR0FBRyxJQUFJLEdBQUcsQ0FBQztJQUNoQyxDQUFDLFNBQVMsRUFBRSxPQUFPLENBQUM7SUFDcEIsQ0FBQyxXQUFXLEVBQUUsT0FBTyxDQUFDO0NBQ3ZCLENBQUM7O0lBQ0ksY0FBYyxHQUFHLElBQUksR0FBRyxDQUFDO0lBQzdCLENBQUMsUUFBUSxFQUFFLFNBQVMsQ0FBQztJQUNyQixDQUFDLFdBQVcsRUFBRSxTQUFTLENBQUM7SUFDeEIsQ0FBQyxTQUFTLEVBQUUsU0FBUyxDQUFDO0NBQ3ZCLENBQUM7O0lBQ0ksZ0JBQWdCOzs7O0FBQXdCLFVBQUMsQ0FBUyxJQUFhLE9BQUcsQ0FBQyxNQUFHLEVBQVAsQ0FBTyxDQUFBOztBQUU1RTtJQTJLRSw2QkFBbUIsZUFBZ0M7UUFBaEMsb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBakUxQyxZQUFP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LFdBQVcsRUFBRTs7OERBQXVCO0lBQ3RCO1FBQXBELFVBQVUsQ0FBQyx3QkFBd0IsQ0FBQyxFQUFFLFdBQVcsRUFBRTs7NERBQXFCO0lBRzVCO1FBQTVDLFVBQVUsQ0FBQyx3QkFBd0IsRUFBRSxLQUFLLENBQUM7OzhEQUEwQztJQUN2QztRQUE5QyxVQUFVLENBQUMsd0JBQXdCLEVBQUUsT0FBTyxDQUFDOztnRUFBOEM7SUFFN0U7UUFBZCxXQUFXLEVBQUU7O3dEQUFrQjtJQW9OM0MsMEJBQUM7Q0FBQSxBQTNVRCxJQTJVQztTQXpPWSxtQkFBbUI7OztJQUM5Qix1REFBdUQ7O0lBQ3ZELGdEQUFnRDs7SUFDaEQsb0RBQW9EOztJQUNwRCxrREFBa0Q7O0lBQ2xELDhDQUE4Qzs7SUFFOUMseUNBQXlFOztJQUN6RSxzQ0FBdUI7O0lBQ3ZCLDRDQUF3Rjs7SUFDeEYscUNBQXNGOztJQUN0Rix1Q0FBd0M7O0lBQ3hDLCtDQUFrRDs7SUFDbEQsd0NBQThDOztJQUM5Qyw0Q0FBb0Y7O0lBQ3BGLDBDQUFrRjs7SUFDbEYsdUNBQXdDOztJQUN4QyxxQ0FBNkM7O0lBQzdDLDRDQUErRjs7SUFDL0YsOENBQXFHOztJQUVyRyxzQ0FBeUM7O0lBRXpDLG9DQUFpQzs7Ozs7SUFHakMsMkNBQW1DOzs7OztJQUduQyx5Q0FBbUI7Ozs7O0lBR25CLHNDQUFnQjs7Ozs7O0lBTWhCLHlDQUE4Qjs7Ozs7SUFHOUIsaURBQWdEOztJQUVoRCw2Q0FBeUQ7O0lBRXpELDZDQUFpQzs7SUFFakMseUNBQW1COztJQUVuQixtQ0FBYTs7SUFFYix3Q0FBMEM7Ozs7O0lBa0IxQywyQ0FBc0Q7Ozs7O0lBQ3RELDZDQUF3RDs7Ozs7SUFDeEQsdUNBQXVDOztJQUUzQiw4Q0FBdUMiLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIEBsaWNlbnNlXG4gKiBDb3B5cmlnaHQgQWxpYmFiYS5jb20gQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3ksIENvbXBvbmVudCwgSW5wdXQsIE9uQ2hhbmdlcywgT25EZXN0cm95LCBPbkluaXQsIFNpbXBsZUNoYW5nZXMsIFZpZXdFbmNhcHN1bGF0aW9uIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBOekNvbmZpZ1NlcnZpY2UsIFdpdGhDb25maWcgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IE5nU3R5bGVJbnRlcmZhY2UsIE51bWJlcklucHV0IH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3R5cGVzJztcbmltcG9ydCB7IElucHV0TnVtYmVyLCBpc05vdE5pbCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS91dGlsJztcbmltcG9ydCB7IFN1YmplY3QgfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHRha2VVbnRpbCB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcblxuaW1wb3J0IHtcbiAgTnpQcm9ncmVzc0NpcmNsZVBhdGgsXG4gIE56UHJvZ3Jlc3NDb2xvckdyYWRpZW50LFxuICBOelByb2dyZXNzRm9ybWF0dGVyLFxuICBOelByb2dyZXNzR2FwUG9zaXRpb25UeXBlLFxuICBOelByb2dyZXNzR3JhZGllbnRQcm9ncmVzcyxcbiAgTnpQcm9ncmVzc1N0YXR1c1R5cGUsXG4gIE56UHJvZ3Jlc3NTdGVwSXRlbSxcbiAgTnpQcm9ncmVzc1N0cm9rZUNvbG9yVHlwZSxcbiAgTnpQcm9ncmVzc1N0cm9rZUxpbmVjYXBUeXBlLFxuICBOelByb2dyZXNzVHlwZVR5cGVcbn0gZnJvbSAnLi90eXBpbmdzJztcbmltcG9ydCB7IGhhbmRsZUNpcmNsZUdyYWRpZW50LCBoYW5kbGVMaW5lYXJHcmFkaWVudCB9IGZyb20gJy4vdXRpbHMnO1xuXG5sZXQgZ3JhZGllbnRJZFNlZWQgPSAwO1xuXG5jb25zdCBOWl9DT05GSUdfQ09NUE9ORU5UX05BTUUgPSAncHJvZ3Jlc3MnO1xuY29uc3Qgc3RhdHVzSWNvbk5hbWVNYXAgPSBuZXcgTWFwKFtcbiAgWydzdWNjZXNzJywgJ2NoZWNrJ10sXG4gIFsnZXhjZXB0aW9uJywgJ2Nsb3NlJ11cbl0pO1xuY29uc3Qgc3RhdHVzQ29sb3JNYXAgPSBuZXcgTWFwKFtcbiAgWydub3JtYWwnLCAnIzEwOGVlOSddLFxuICBbJ2V4Y2VwdGlvbicsICcjZmY1NTAwJ10sXG4gIFsnc3VjY2VzcycsICcjODdkMDY4J11cbl0pO1xuY29uc3QgZGVmYXVsdEZvcm1hdHRlcjogTnpQcm9ncmVzc0Zvcm1hdHRlciA9IChwOiBudW1iZXIpOiBzdHJpbmcgPT4gYCR7cH0lYDtcblxuQENvbXBvbmVudCh7XG4gIGNoYW5nZURldGVjdGlvbjogQ2hhbmdlRGV0ZWN0aW9uU3RyYXRlZ3kuT25QdXNoLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBzZWxlY3RvcjogJ256LXByb2dyZXNzJyxcbiAgZXhwb3J0QXM6ICduelByb2dyZXNzJyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHRlbXBsYXRlOiBgXG4gICAgPG5nLXRlbXBsYXRlICNwcm9ncmVzc0luZm9UZW1wbGF0ZT5cbiAgICAgIDxzcGFuIGNsYXNzPVwiYW50LXByb2dyZXNzLXRleHRcIiAqbmdJZj1cIm56U2hvd0luZm9cIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIihzdGF0dXMgPT09ICdleGNlcHRpb24nIHx8IHN0YXR1cyA9PT0gJ3N1Y2Nlc3MnKSAmJiAhbnpGb3JtYXQ7IGVsc2UgZm9ybWF0VGVtcGxhdGVcIj5cbiAgICAgICAgICA8aSBuei1pY29uIFtuelR5cGVdPVwiaWNvblwiPjwvaT5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSAjZm9ybWF0VGVtcGxhdGU+XG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbnpTdHJpbmdUZW1wbGF0ZU91dGxldD1cImZvcm1hdHRlcjsgY29udGV4dDogeyAkaW1wbGljaXQ6IG56UGVyY2VudCB9XCI+XG4gICAgICAgICAgICB7eyAkYW55KGZvcm1hdHRlcikobnpQZXJjZW50KSB9fVxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8L25nLXRlbXBsYXRlPlxuICAgICAgPC9zcGFuPlxuICAgIDwvbmctdGVtcGxhdGU+XG5cbiAgICA8ZGl2XG4gICAgICBbbmdDbGFzc109XCInYW50LXByb2dyZXNzIGFudC1wcm9ncmVzcy1zdGF0dXMtJyArIHN0YXR1c1wiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLWxpbmVdPVwibnpUeXBlID09ICdsaW5lJ1wiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLXNtYWxsXT1cIm56U2l6ZSA9PSAnc21hbGwnXCJcbiAgICAgIFtjbGFzcy5hbnQtcHJvZ3Jlc3Mtc2hvdy1pbmZvXT1cIm56U2hvd0luZm9cIlxuICAgICAgW2NsYXNzLmFudC1wcm9ncmVzcy1jaXJjbGVdPVwiaXNDaXJjbGVTdHlsZVwiXG4gICAgICBbY2xhc3MuYW50LXByb2dyZXNzLXN0ZXBzXT1cImlzU3RlcHNcIlxuICAgID5cbiAgICAgIDwhLS0gbGluZSBwcm9ncmVzcyAtLT5cbiAgICAgIDxkaXYgKm5nSWY9XCJuelR5cGUgPT09ICdsaW5lJ1wiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiIWlzU3RlcHNcIj5cbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LXByb2dyZXNzLW91dGVyXCIgKm5nSWY9XCIhaXNTdGVwc1wiPlxuICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1wcm9ncmVzcy1pbm5lclwiPlxuICAgICAgICAgICAgICA8ZGl2XG4gICAgICAgICAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtYmdcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS53aWR0aC4lXT1cIm56UGVyY2VudFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJvcmRlci1yYWRpdXNdPVwibnpTdHJva2VMaW5lY2FwID09PSAncm91bmQnID8gJzEwMHB4JyA6ICcwJ1wiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmRdPVwiIWlzR3JhZGllbnQgPyBuelN0cm9rZUNvbG9yIDogbnVsbFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJhY2tncm91bmQtaW1hZ2VdPVwiaXNHcmFkaWVudCA/IGxpbmVHcmFkaWVudCA6IG51bGxcIlxuICAgICAgICAgICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwic3Ryb2tlV2lkdGhcIlxuICAgICAgICAgICAgICA+PC9kaXY+XG4gICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAqbmdJZj1cIm56U3VjY2Vzc1BlcmNlbnQgfHwgbnpTdWNjZXNzUGVyY2VudCA9PT0gMFwiXG4gICAgICAgICAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3Mtc3VjY2Vzcy1iZ1wiXG4gICAgICAgICAgICAgICAgW3N0eWxlLndpZHRoLiVdPVwibnpTdWNjZXNzUGVyY2VudFwiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmJvcmRlci1yYWRpdXNdPVwibnpTdHJva2VMaW5lY2FwID09PSAncm91bmQnID8gJzEwMHB4JyA6ICcwJ1wiXG4gICAgICAgICAgICAgICAgW3N0eWxlLmhlaWdodC5weF09XCJzdHJva2VXaWR0aFwiXG4gICAgICAgICAgICAgID48L2Rpdj5cbiAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJwcm9ncmVzc0luZm9UZW1wbGF0ZVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICA8IS0tIFN0ZXAgc3R5bGUgcHJvZ3Jlc3MgLS0+XG4gICAgICAgIDxkaXYgY2xhc3M9XCJhbnQtcHJvZ3Jlc3Mtc3RlcHMtb3V0ZXJcIiAqbmdJZj1cImlzU3RlcHNcIj5cbiAgICAgICAgICA8ZGl2ICpuZ0Zvcj1cImxldCBzdGVwIG9mIHN0ZXBzOyBsZXQgaSA9IGluZGV4XCIgY2xhc3M9XCJhbnQtcHJvZ3Jlc3Mtc3RlcHMtaXRlbVwiIFtuZ1N0eWxlXT1cInN0ZXBcIj48L2Rpdj5cbiAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwicHJvZ3Jlc3NJbmZvVGVtcGxhdGVcIj48L25nLXRlbXBsYXRlPlxuICAgICAgICA8L2Rpdj5cbiAgICAgIDwvZGl2PlxuXG4gICAgICA8IS0tIGNpcmNsZSAvIGRhc2hib2FyZCBwcm9ncmVzcyAtLT5cbiAgICAgIDxkaXZcbiAgICAgICAgW3N0eWxlLndpZHRoLnB4XT1cInRoaXMubnpXaWR0aFwiXG4gICAgICAgIFtzdHlsZS5oZWlnaHQucHhdPVwidGhpcy5ueldpZHRoXCJcbiAgICAgICAgW3N0eWxlLmZvbnRTaXplLnB4XT1cInRoaXMubnpXaWR0aCAqIDAuMTUgKyA2XCJcbiAgICAgICAgY2xhc3M9XCJhbnQtcHJvZ3Jlc3MtaW5uZXJcIlxuICAgICAgICBbY2xhc3MuYW50LXByb2dyZXNzLWNpcmNsZS1ncmFkaWVudF09XCJpc0dyYWRpZW50XCJcbiAgICAgICAgKm5nSWY9XCJpc0NpcmNsZVN0eWxlXCJcbiAgICAgID5cbiAgICAgICAgPHN2ZyBjbGFzcz1cImFudC1wcm9ncmVzcy1jaXJjbGUgXCIgdmlld0JveD1cIjAgMCAxMDAgMTAwXCI+XG4gICAgICAgICAgPGRlZnMgKm5nSWY9XCJpc0dyYWRpZW50XCI+XG4gICAgICAgICAgICA8bGluZWFyR3JhZGllbnQgW2lkXT1cIidncmFkaWVudC0nICsgZ3JhZGllbnRJZFwiIHgxPVwiMTAwJVwiIHkxPVwiMCVcIiB4Mj1cIjAlXCIgeTI9XCIwJVwiPlxuICAgICAgICAgICAgICA8c3RvcCAqbmdGb3I9XCJsZXQgaSBvZiBjaXJjbGVHcmFkaWVudFwiIFthdHRyLm9mZnNldF09XCJpLm9mZnNldFwiIFthdHRyLnN0b3AtY29sb3JdPVwiaS5jb2xvclwiPjwvc3RvcD5cbiAgICAgICAgICAgIDwvbGluZWFyR3JhZGllbnQ+XG4gICAgICAgICAgPC9kZWZzPlxuICAgICAgICAgIDxwYXRoXG4gICAgICAgICAgICBjbGFzcz1cImFudC1wcm9ncmVzcy1jaXJjbGUtdHJhaWxcIlxuICAgICAgICAgICAgc3Ryb2tlPVwiI2YzZjNmM1wiXG4gICAgICAgICAgICBmaWxsLW9wYWNpdHk9XCIwXCJcbiAgICAgICAgICAgIFthdHRyLnN0cm9rZS13aWR0aF09XCJzdHJva2VXaWR0aFwiXG4gICAgICAgICAgICBbYXR0ci5kXT1cInBhdGhTdHJpbmdcIlxuICAgICAgICAgICAgW25nU3R5bGVdPVwidHJhaWxQYXRoU3R5bGVcIlxuICAgICAgICAgID48L3BhdGg+XG4gICAgICAgICAgPHBhdGhcbiAgICAgICAgICAgICpuZ0Zvcj1cImxldCBwIG9mIHByb2dyZXNzQ2lyY2xlUGF0aDsgdHJhY2tCeTogdHJhY2tCeUZuXCJcbiAgICAgICAgICAgIGNsYXNzPVwiYW50LXByb2dyZXNzLWNpcmNsZS1wYXRoXCJcbiAgICAgICAgICAgIGZpbGwtb3BhY2l0eT1cIjBcIlxuICAgICAgICAgICAgW2F0dHIuZF09XCJwYXRoU3RyaW5nXCJcbiAgICAgICAgICAgIFthdHRyLnN0cm9rZS1saW5lY2FwXT1cIm56U3Ryb2tlTGluZWNhcFwiXG4gICAgICAgICAgICBbYXR0ci5zdHJva2VdPVwicC5zdHJva2VcIlxuICAgICAgICAgICAgW2F0dHIuc3Ryb2tlLXdpZHRoXT1cIm56UGVyY2VudCA/IHN0cm9rZVdpZHRoIDogMFwiXG4gICAgICAgICAgICBbbmdTdHlsZV09XCJwLnN0cm9rZVBhdGhTdHlsZVwiXG4gICAgICAgICAgPjwvcGF0aD5cbiAgICAgICAgPC9zdmc+XG4gICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJwcm9ncmVzc0luZm9UZW1wbGF0ZVwiPjwvbmctdGVtcGxhdGU+XG4gICAgICA8L2Rpdj5cbiAgICA8L2Rpdj5cbiAgYFxufSlcbmV4cG9ydCBjbGFzcyBOelByb2dyZXNzQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelN1Y2Nlc3NQZXJjZW50OiBOdW1iZXJJbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256UGVyY2VudDogTnVtYmVySW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uelN0cm9rZVdpZHRoOiBOdW1iZXJJbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256R2FwRGVncmVlOiBOdW1iZXJJbnB1dDtcbiAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX256U3RlcHM6IE51bWJlcklucHV0O1xuXG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKE5aX0NPTkZJR19DT01QT05FTlRfTkFNRSwgdHJ1ZSkgbnpTaG93SW5mbzogYm9vbGVhbjtcbiAgQElucHV0KCkgbnpXaWR0aCA9IDEzMjtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FKSBuelN0cm9rZUNvbG9yOiBOelByb2dyZXNzU3Ryb2tlQ29sb3JUeXBlO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZyhOWl9DT05GSUdfQ09NUE9ORU5UX05BTUUsICdkZWZhdWx0JykgbnpTaXplOiAnZGVmYXVsdCcgfCAnc21hbGwnO1xuICBASW5wdXQoKSBuekZvcm1hdD86IE56UHJvZ3Jlc3NGb3JtYXR0ZXI7XG4gIEBJbnB1dCgpIEBJbnB1dE51bWJlcigpIG56U3VjY2Vzc1BlcmNlbnQ/OiBudW1iZXI7XG4gIEBJbnB1dCgpIEBJbnB1dE51bWJlcigpIG56UGVyY2VudDogbnVtYmVyID0gMDtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FKSBASW5wdXROdW1iZXIoKSBuelN0cm9rZVdpZHRoOiBudW1iZXI7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKE5aX0NPTkZJR19DT01QT05FTlRfTkFNRSkgQElucHV0TnVtYmVyKCkgbnpHYXBEZWdyZWU6IG51bWJlcjtcbiAgQElucHV0KCkgbnpTdGF0dXM6IE56UHJvZ3Jlc3NTdGF0dXNUeXBlO1xuICBASW5wdXQoKSBuelR5cGU6IE56UHJvZ3Jlc3NUeXBlVHlwZSA9ICdsaW5lJztcbiAgQElucHV0KCkgQFdpdGhDb25maWcoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FLCAndG9wJykgbnpHYXBQb3NpdGlvbjogTnpQcm9ncmVzc0dhcFBvc2l0aW9uVHlwZTtcbiAgQElucHV0KCkgQFdpdGhDb25maWcoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FLCAncm91bmQnKSBuelN0cm9rZUxpbmVjYXA6IE56UHJvZ3Jlc3NTdHJva2VMaW5lY2FwVHlwZTtcblxuICBASW5wdXQoKSBASW5wdXROdW1iZXIoKSBuelN0ZXBzPzogbnVtYmVyO1xuXG4gIHN0ZXBzOiBOelByb2dyZXNzU3RlcEl0ZW1bXSA9IFtdO1xuXG4gIC8qKiBHcmFkaWVudCBzdHlsZSB3aGVuIGBuelR5cGVgIGlzIGBsaW5lYC4gKi9cbiAgbGluZUdyYWRpZW50OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcblxuICAvKiogSWYgdXNlciB1c2VzIGdyYWRpZW50IGNvbG9yLiAqL1xuICBpc0dyYWRpZW50ID0gZmFsc2U7XG5cbiAgLyoqIElmIHRoZSBsaW5lYXIgcHJvZ3Jlc3MgaXMgYSBzdGVwIHByb2dyZXNzLiAqL1xuICBpc1N0ZXBzID0gZmFsc2U7XG5cbiAgLyoqXG4gICAqIEVhY2ggcHJvZ3Jlc3Mgd2hvc2UgYG56VHlwZWAgaXMgY2lyY2xlIG9yIGRhc2hib2FyZCBzaG91bGQgaGF2ZSB1bmlxdWUgaWQgdG9cbiAgICogZGVmaW5lIGA8bGluZWFyR3JhZGllbnQ+YC5cbiAgICovXG4gIGdyYWRpZW50SWQgPSBncmFkaWVudElkU2VlZCsrO1xuXG4gIC8qKiBQYXRocyB0byByZW5kZXJlZCBpbiB0aGUgdGVtcGxhdGUuICovXG4gIHByb2dyZXNzQ2lyY2xlUGF0aDogTnpQcm9ncmVzc0NpcmNsZVBhdGhbXSA9IFtdO1xuXG4gIGNpcmNsZUdyYWRpZW50OiBBcnJheTx7IG9mZnNldDogc3RyaW5nOyBjb2xvcjogc3RyaW5nIH0+O1xuXG4gIHRyYWlsUGF0aFN0eWxlOiBOZ1N0eWxlSW50ZXJmYWNlO1xuXG4gIHBhdGhTdHJpbmc6IHN0cmluZztcblxuICBpY29uOiBzdHJpbmc7XG5cbiAgdHJhY2tCeUZuID0gKGluZGV4OiBudW1iZXIpID0+IGAke2luZGV4fWA7XG5cbiAgZ2V0IGZvcm1hdHRlcigpOiBOelByb2dyZXNzRm9ybWF0dGVyIHtcbiAgICByZXR1cm4gdGhpcy5uekZvcm1hdCB8fCBkZWZhdWx0Rm9ybWF0dGVyO1xuICB9XG5cbiAgZ2V0IHN0YXR1cygpOiBOelByb2dyZXNzU3RhdHVzVHlwZSB7XG4gICAgcmV0dXJuIHRoaXMubnpTdGF0dXMgfHwgdGhpcy5pbmZlcnJlZFN0YXR1cztcbiAgfVxuXG4gIGdldCBzdHJva2VXaWR0aCgpOiBudW1iZXIge1xuICAgIHJldHVybiB0aGlzLm56U3Ryb2tlV2lkdGggfHwgKHRoaXMubnpUeXBlID09PSAnbGluZScgJiYgdGhpcy5uelNpemUgIT09ICdzbWFsbCcgPyA4IDogNik7XG4gIH1cblxuICBnZXQgaXNDaXJjbGVTdHlsZSgpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5uelR5cGUgPT09ICdjaXJjbGUnIHx8IHRoaXMubnpUeXBlID09PSAnZGFzaGJvYXJkJztcbiAgfVxuXG4gIHByaXZhdGUgY2FjaGVkU3RhdHVzOiBOelByb2dyZXNzU3RhdHVzVHlwZSA9ICdub3JtYWwnO1xuICBwcml2YXRlIGluZmVycmVkU3RhdHVzOiBOelByb2dyZXNzU3RhdHVzVHlwZSA9ICdub3JtYWwnO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcihwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UpIHt9XG5cbiAgbmdPbkNoYW5nZXMoY2hhbmdlczogU2ltcGxlQ2hhbmdlcyk6IHZvaWQge1xuICAgIGNvbnN0IHsgbnpTdGVwcywgbnpHYXBQb3NpdGlvbiwgbnpTdHJva2VMaW5lY2FwLCBuelN0cm9rZUNvbG9yLCBuekdhcERlZ3JlZSwgbnpUeXBlLCBuelN0YXR1cywgbnpQZXJjZW50LCBuelN1Y2Nlc3NQZXJjZW50IH0gPSBjaGFuZ2VzO1xuXG4gICAgaWYgKG56U3RhdHVzKSB7XG4gICAgICB0aGlzLmNhY2hlZFN0YXR1cyA9IHRoaXMubnpTdGF0dXMgfHwgdGhpcy5jYWNoZWRTdGF0dXM7XG4gICAgfVxuXG4gICAgaWYgKG56UGVyY2VudCB8fCBuelN1Y2Nlc3NQZXJjZW50KSB7XG4gICAgICBjb25zdCBmaWxsQWxsID0gcGFyc2VJbnQodGhpcy5uelBlcmNlbnQudG9TdHJpbmcoKSwgMTApID49IDEwMDtcbiAgICAgIGlmIChmaWxsQWxsKSB7XG4gICAgICAgIGlmICgoaXNOb3ROaWwodGhpcy5uelN1Y2Nlc3NQZXJjZW50KSAmJiB0aGlzLm56U3VjY2Vzc1BlcmNlbnQhID49IDEwMCkgfHwgdGhpcy5uelN1Y2Nlc3NQZXJjZW50ID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICB0aGlzLmluZmVycmVkU3RhdHVzID0gJ3N1Y2Nlc3MnO1xuICAgICAgICB9XG4gICAgICB9IGVsc2Uge1xuICAgICAgICB0aGlzLmluZmVycmVkU3RhdHVzID0gdGhpcy5jYWNoZWRTdGF0dXM7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKG56U3RhdHVzIHx8IG56UGVyY2VudCB8fCBuelN1Y2Nlc3NQZXJjZW50KSB7XG4gICAgICB0aGlzLnVwZGF0ZUljb24oKTtcbiAgICB9XG5cbiAgICBpZiAobnpTdHJva2VDb2xvcikge1xuICAgICAgdGhpcy5zZXRTdHJva2VDb2xvcigpO1xuICAgIH1cblxuICAgIGlmIChuekdhcFBvc2l0aW9uIHx8IG56U3Ryb2tlTGluZWNhcCB8fCBuekdhcERlZ3JlZSB8fCBuelR5cGUgfHwgbnpQZXJjZW50IHx8IG56U3Ryb2tlQ29sb3IpIHtcbiAgICAgIHRoaXMuZ2V0Q2lyY2xlUGF0aHMoKTtcbiAgICB9XG5cbiAgICBpZiAobnpTdGVwcykge1xuICAgICAgdGhpcy5pc1N0ZXBzID0gaXNOb3ROaWwobnpTdGVwcy5jdXJyZW50VmFsdWUpO1xuICAgICAgdGhpcy5nZXRTdGVwcygpO1xuICAgIH1cbiAgfVxuXG4gIG5nT25Jbml0KCk6IHZvaWQge1xuICAgIHRoaXMubnpDb25maWdTZXJ2aWNlXG4gICAgICAuZ2V0Q29uZmlnQ2hhbmdlRXZlbnRGb3JDb21wb25lbnQoTlpfQ09ORklHX0NPTVBPTkVOVF9OQU1FKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMudXBkYXRlSWNvbigpO1xuICAgICAgICB0aGlzLnNldFN0cm9rZUNvbG9yKCk7XG4gICAgICAgIHRoaXMuZ2V0Q2lyY2xlUGF0aHMoKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgcHJpdmF0ZSB1cGRhdGVJY29uKCk6IHZvaWQge1xuICAgIGNvbnN0IHJldCA9IHN0YXR1c0ljb25OYW1lTWFwLmdldCh0aGlzLnN0YXR1cyk7XG4gICAgdGhpcy5pY29uID0gcmV0ID8gcmV0ICsgKHRoaXMuaXNDaXJjbGVTdHlsZSA/ICctbycgOiAnLWNpcmNsZS1maWxsJykgOiAnJztcbiAgfVxuXG4gIC8qKlxuICAgKiBDYWxjdWxhdGUgc3RlcCByZW5kZXIgY29uZmlncy5cbiAgICovXG4gIHByaXZhdGUgZ2V0U3RlcHMoKTogdm9pZCB7XG4gICAgY29uc3QgY3VycmVudCA9IE1hdGguZmxvb3IodGhpcy5uelN0ZXBzISAqICh0aGlzLm56UGVyY2VudCAvIDEwMCkpO1xuICAgIGNvbnN0IHN0ZXBXaWR0aCA9IHRoaXMubnpTaXplID09PSAnc21hbGwnID8gMiA6IDE0O1xuXG4gICAgZm9yIChsZXQgaSA9IDA7IGkgPCB0aGlzLm56U3RlcHMhOyBpKyspIHtcbiAgICAgIGxldCBjb2xvcjtcbiAgICAgIGlmIChpIDw9IGN1cnJlbnQgLSAxKSB7XG4gICAgICAgIGNvbG9yID0gdGhpcy5uelN0cm9rZUNvbG9yO1xuICAgICAgfVxuICAgICAgY29uc3Qgc3RlcFN0eWxlID0ge1xuICAgICAgICBiYWNrZ3JvdW5kQ29sb3I6IGAke2NvbG9yfWAsXG4gICAgICAgIHdpZHRoOiBgJHtzdGVwV2lkdGh9cHhgLFxuICAgICAgICBoZWlnaHQ6IGAke3RoaXMuc3Ryb2tlV2lkdGh9cHhgXG4gICAgICB9O1xuICAgICAgdGhpcy5zdGVwcy5wdXNoKHN0ZXBTdHlsZSk7XG4gICAgfVxuICB9XG5cbiAgLyoqXG4gICAqIENhbGN1bGF0ZSBwYXRocyB3aGVuIHRoZSB0eXBlIGlzIGNpcmNsZSBvciBkYXNoYm9hcmQuXG4gICAqL1xuICBwcml2YXRlIGdldENpcmNsZVBhdGhzKCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5pc0NpcmNsZVN0eWxlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuXG4gICAgY29uc3QgdmFsdWVzID0gaXNOb3ROaWwodGhpcy5uelN1Y2Nlc3NQZXJjZW50KSA/IFt0aGlzLm56U3VjY2Vzc1BlcmNlbnQhLCB0aGlzLm56UGVyY2VudF0gOiBbdGhpcy5uelBlcmNlbnRdO1xuXG4gICAgLy8gQ2FsY3VsYXRlIHNoYXJlZCBzdHlsZXMuXG4gICAgY29uc3QgcmFkaXVzID0gNTAgLSB0aGlzLnN0cm9rZVdpZHRoIC8gMjtcbiAgICBjb25zdCBnYXBQb3NpdGlvbiA9IHRoaXMubnpHYXBQb3NpdGlvbiB8fCAodGhpcy5uelR5cGUgPT09ICdjaXJjbGUnID8gJ3RvcCcgOiAnYm90dG9tJyk7XG4gICAgY29uc3QgbGVuID0gTWF0aC5QSSAqIDIgKiByYWRpdXM7XG4gICAgY29uc3QgZ2FwRGVncmVlID0gdGhpcy5uekdhcERlZ3JlZSB8fCAodGhpcy5uelR5cGUgPT09ICdjaXJjbGUnID8gMCA6IDc1KTtcblxuICAgIGxldCBiZWdpblBvc2l0aW9uWCA9IDA7XG4gICAgbGV0IGJlZ2luUG9zaXRpb25ZID0gLXJhZGl1cztcbiAgICBsZXQgZW5kUG9zaXRpb25YID0gMDtcbiAgICBsZXQgZW5kUG9zaXRpb25ZID0gcmFkaXVzICogLTI7XG5cbiAgICBzd2l0Y2ggKGdhcFBvc2l0aW9uKSB7XG4gICAgICBjYXNlICdsZWZ0JzpcbiAgICAgICAgYmVnaW5Qb3NpdGlvblggPSAtcmFkaXVzO1xuICAgICAgICBiZWdpblBvc2l0aW9uWSA9IDA7XG4gICAgICAgIGVuZFBvc2l0aW9uWCA9IHJhZGl1cyAqIDI7XG4gICAgICAgIGVuZFBvc2l0aW9uWSA9IDA7XG4gICAgICAgIGJyZWFrO1xuICAgICAgY2FzZSAncmlnaHQnOlxuICAgICAgICBiZWdpblBvc2l0aW9uWCA9IHJhZGl1cztcbiAgICAgICAgYmVnaW5Qb3NpdGlvblkgPSAwO1xuICAgICAgICBlbmRQb3NpdGlvblggPSByYWRpdXMgKiAtMjtcbiAgICAgICAgZW5kUG9zaXRpb25ZID0gMDtcbiAgICAgICAgYnJlYWs7XG4gICAgICBjYXNlICdib3R0b20nOlxuICAgICAgICBiZWdpblBvc2l0aW9uWSA9IHJhZGl1cztcbiAgICAgICAgZW5kUG9zaXRpb25ZID0gcmFkaXVzICogMjtcbiAgICAgICAgYnJlYWs7XG4gICAgICBkZWZhdWx0OlxuICAgIH1cblxuICAgIHRoaXMucGF0aFN0cmluZyA9IGBNIDUwLDUwIG0gJHtiZWdpblBvc2l0aW9uWH0sJHtiZWdpblBvc2l0aW9uWX1cbiAgICAgICBhICR7cmFkaXVzfSwke3JhZGl1c30gMCAxIDEgJHtlbmRQb3NpdGlvblh9LCR7LWVuZFBvc2l0aW9uWX1cbiAgICAgICBhICR7cmFkaXVzfSwke3JhZGl1c30gMCAxIDEgJHstZW5kUG9zaXRpb25YfSwke2VuZFBvc2l0aW9uWX1gO1xuXG4gICAgdGhpcy50cmFpbFBhdGhTdHlsZSA9IHtcbiAgICAgIHN0cm9rZURhc2hhcnJheTogYCR7bGVuIC0gZ2FwRGVncmVlfXB4ICR7bGVufXB4YCxcbiAgICAgIHN0cm9rZURhc2hvZmZzZXQ6IGAtJHtnYXBEZWdyZWUgLyAyfXB4YCxcbiAgICAgIHRyYW5zaXRpb246ICdzdHJva2UtZGFzaG9mZnNldCAuM3MgZWFzZSAwcywgc3Ryb2tlLWRhc2hhcnJheSAuM3MgZWFzZSAwcywgc3Ryb2tlIC4zcydcbiAgICB9O1xuXG4gICAgLy8gQ2FsY3VsYXRlIHN0eWxlcyBmb3IgZWFjaCBwYXRoLlxuICAgIHRoaXMucHJvZ3Jlc3NDaXJjbGVQYXRoID0gdmFsdWVzXG4gICAgICAubWFwKCh2YWx1ZSwgaW5kZXgpID0+IHtcbiAgICAgICAgY29uc3QgaXNTdWNjZXNzUGVyY2VudCA9IHZhbHVlcy5sZW5ndGggPT09IDIgJiYgaW5kZXggPT09IDA7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgc3Ryb2tlOiB0aGlzLmlzR3JhZGllbnQgJiYgIWlzU3VjY2Vzc1BlcmNlbnQgPyBgdXJsKCNncmFkaWVudC0ke3RoaXMuZ3JhZGllbnRJZH0pYCA6IG51bGwsXG4gICAgICAgICAgc3Ryb2tlUGF0aFN0eWxlOiB7XG4gICAgICAgICAgICBzdHJva2U6ICF0aGlzLmlzR3JhZGllbnQgPyAoaXNTdWNjZXNzUGVyY2VudCA/IHN0YXR1c0NvbG9yTWFwLmdldCgnc3VjY2VzcycpIDogKHRoaXMubnpTdHJva2VDb2xvciBhcyBzdHJpbmcpKSA6IG51bGwsXG4gICAgICAgICAgICB0cmFuc2l0aW9uOiAnc3Ryb2tlLWRhc2hvZmZzZXQgLjNzIGVhc2UgMHMsIHN0cm9rZS1kYXNoYXJyYXkgLjNzIGVhc2UgMHMsIHN0cm9rZSAuM3MsIHN0cm9rZS13aWR0aCAuMDZzIGVhc2UgLjNzJyxcbiAgICAgICAgICAgIHN0cm9rZURhc2hhcnJheTogYCR7KCh2YWx1ZSB8fCAwKSAvIDEwMCkgKiAobGVuIC0gZ2FwRGVncmVlKX1weCAke2xlbn1weGAsXG4gICAgICAgICAgICBzdHJva2VEYXNob2Zmc2V0OiBgLSR7Z2FwRGVncmVlIC8gMn1weGBcbiAgICAgICAgICB9XG4gICAgICAgIH07XG4gICAgICB9KVxuICAgICAgLnJldmVyc2UoKTtcbiAgfVxuXG4gIHByaXZhdGUgc2V0U3Ryb2tlQ29sb3IoKTogdm9pZCB7XG4gICAgY29uc3QgY29sb3IgPSB0aGlzLm56U3Ryb2tlQ29sb3I7XG4gICAgY29uc3QgaXNHcmFkaWVudCA9ICh0aGlzLmlzR3JhZGllbnQgPSAhIWNvbG9yICYmIHR5cGVvZiBjb2xvciAhPT0gJ3N0cmluZycpO1xuICAgIGlmIChpc0dyYWRpZW50ICYmICF0aGlzLmlzQ2lyY2xlU3R5bGUpIHtcbiAgICAgIHRoaXMubGluZUdyYWRpZW50ID0gaGFuZGxlTGluZWFyR3JhZGllbnQoY29sb3IgYXMgTnpQcm9ncmVzc0NvbG9yR3JhZGllbnQpO1xuICAgIH0gZWxzZSBpZiAoaXNHcmFkaWVudCAmJiB0aGlzLmlzQ2lyY2xlU3R5bGUpIHtcbiAgICAgIHRoaXMuY2lyY2xlR3JhZGllbnQgPSBoYW5kbGVDaXJjbGVHcmFkaWVudCh0aGlzLm56U3Ryb2tlQ29sb3IgYXMgTnpQcm9ncmVzc0dyYWRpZW50UHJvZ3Jlc3MpO1xuICAgIH0gZWxzZSB7XG4gICAgICB0aGlzLmxpbmVHcmFkaWVudCA9IG51bGw7XG4gICAgICB0aGlzLmNpcmNsZUdyYWRpZW50ID0gW107XG4gICAgfVxuICB9XG59XG4iXX0=