UNPKG

ng-zorro-antd

Version:

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

370 lines (368 loc) 38.8 kB
import { __decorate } from "tslib"; import { ChangeDetectionStrategy, Component, ContentChildren, Input, Optional, ViewEncapsulation } from '@angular/core'; import { merge, Subject } from 'rxjs'; import { auditTime, startWith, switchMap, takeUntil, tap } from 'rxjs/operators'; import { WithConfig } from 'ng-zorro-antd/core/config'; import { warn } from 'ng-zorro-antd/core/logger'; import { gridResponsiveMap, NzBreakpointEnum } from 'ng-zorro-antd/core/services'; import { InputBoolean } from 'ng-zorro-antd/core/util'; import { NzDescriptionsItemComponent } from './descriptions-item.component'; import * as i0 from "@angular/core"; import * as i1 from "ng-zorro-antd/core/config"; import * as i2 from "ng-zorro-antd/core/services"; import * as i3 from "@angular/cdk/bidi"; import * as i4 from "@angular/common"; import * as i5 from "ng-zorro-antd/core/outlet"; const NZ_CONFIG_MODULE_NAME = 'descriptions'; const defaultColumnMap = { xxl: 3, xl: 3, lg: 3, md: 3, sm: 2, xs: 1 }; export class NzDescriptionsComponent { constructor(nzConfigService, cdr, breakpointService, directionality) { this.nzConfigService = nzConfigService; this.cdr = cdr; this.breakpointService = breakpointService; this.directionality = directionality; this._nzModuleName = NZ_CONFIG_MODULE_NAME; this.nzBordered = false; this.nzLayout = 'horizontal'; this.nzColumn = defaultColumnMap; this.nzSize = 'default'; this.nzTitle = ''; this.nzColon = true; this.itemMatrix = []; this.realColumn = 3; this.dir = 'ltr'; this.breakpoint = NzBreakpointEnum.md; this.destroy$ = new Subject(); } ngOnInit() { this.dir = this.directionality.value; this.directionality.change?.pipe(takeUntil(this.destroy$)).subscribe((direction) => { this.dir = direction; }); } ngOnChanges(changes) { if (changes.nzColumn) { this.prepareMatrix(); } } ngAfterContentInit() { const contentChange$ = this.items.changes.pipe(startWith(this.items), takeUntil(this.destroy$)); merge(contentChange$, contentChange$.pipe(switchMap(() => merge(...this.items.map(i => i.inputChange$)).pipe(auditTime(16)))), this.breakpointService.subscribe(gridResponsiveMap).pipe(tap(bp => (this.breakpoint = bp)))) .pipe(takeUntil(this.destroy$)) .subscribe(() => { this.prepareMatrix(); this.cdr.markForCheck(); }); } ngOnDestroy() { this.destroy$.next(); this.destroy$.complete(); } /** * Prepare the render matrix according to description items' spans. */ prepareMatrix() { if (!this.items) { return; } let currentRow = []; let width = 0; const column = (this.realColumn = this.getColumn()); const items = this.items.toArray(); const length = items.length; const matrix = []; const flushRow = () => { matrix.push(currentRow); currentRow = []; width = 0; }; for (let i = 0; i < length; i++) { const item = items[i]; const { nzTitle: title, content, nzSpan: span } = item; width += span; // If the last item make the row's length exceeds `nzColumn`, the last // item should take all the space left. This logic is implemented in the template. // Warn user about that. if (width >= column) { if (width > column) { warn(`"nzColumn" is ${column} but we have row length ${width}`); } currentRow.push({ title, content, span: column - (width - span) }); flushRow(); } else if (i === length - 1) { currentRow.push({ title, content, span: column - (width - span) }); flushRow(); } else { currentRow.push({ title, content, span }); } } this.itemMatrix = matrix; } getColumn() { if (typeof this.nzColumn !== 'number') { return this.nzColumn[this.breakpoint]; } return this.nzColumn; } } NzDescriptionsComponent.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NzDescriptionsComponent, deps: [{ token: i1.NzConfigService }, { token: i0.ChangeDetectorRef }, { token: i2.NzBreakpointService }, { token: i3.Directionality, optional: true }], target: i0.ɵɵFactoryTarget.Component }); NzDescriptionsComponent.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "14.2.12", type: NzDescriptionsComponent, selector: "nz-descriptions", inputs: { nzBordered: "nzBordered", nzLayout: "nzLayout", nzColumn: "nzColumn", nzSize: "nzSize", nzTitle: "nzTitle", nzExtra: "nzExtra", nzColon: "nzColon" }, host: { properties: { "class.ant-descriptions-bordered": "nzBordered", "class.ant-descriptions-middle": "nzSize === \"middle\"", "class.ant-descriptions-small": "nzSize === \"small\"", "class.ant-descriptions-rtl": "dir === \"rtl\"" }, classAttribute: "ant-descriptions" }, queries: [{ propertyName: "items", predicate: NzDescriptionsItemComponent }], exportAs: ["nzDescriptions"], usesOnChanges: true, ngImport: i0, template: ` <div *ngIf="nzTitle || nzExtra" class="ant-descriptions-header"> <div *ngIf="nzTitle" class="ant-descriptions-title"> <ng-container *nzStringTemplateOutlet="nzTitle">{{ nzTitle }}</ng-container> </div> <div *ngIf="nzExtra" class="ant-descriptions-extra"> <ng-container *nzStringTemplateOutlet="nzExtra">{{ nzExtra }}</ng-container> </div> </div> <div class="ant-descriptions-view"> <table> <tbody> <ng-container *ngIf="nzLayout === 'horizontal'"> <tr class="ant-descriptions-row" *ngFor="let row of itemMatrix; let i = index"> <ng-container *ngFor="let item of row; let isLast = last"> <!-- Horizontal & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> <!-- Horizontal & Bordered --> <ng-container *ngIf="nzBordered"> <td class="ant-descriptions-item-label"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> <td class="ant-descriptions-item-content" [colSpan]="item.span * 2 - 1"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </ng-container> </tr> </ng-container> <ng-container *ngIf="nzLayout === 'vertical'"> <!-- Vertical & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> </div> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> </tr> </ng-container> </ng-container> <!-- Vertical & Bordered --> <ng-container *ngIf="nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-label" [colSpan]="item.span"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-content" [colSpan]="item.span"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </tr> </ng-container> </ng-container> </ng-container> </tbody> </table> </div> `, isInline: true, dependencies: [{ kind: "directive", type: i4.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i4.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i5.NzStringTemplateOutletDirective, selector: "[nzStringTemplateOutlet]", inputs: ["nzStringTemplateOutletContext", "nzStringTemplateOutlet"], exportAs: ["nzStringTemplateOutlet"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); __decorate([ InputBoolean(), WithConfig() ], NzDescriptionsComponent.prototype, "nzBordered", void 0); __decorate([ WithConfig() ], NzDescriptionsComponent.prototype, "nzColumn", void 0); __decorate([ WithConfig() ], NzDescriptionsComponent.prototype, "nzSize", void 0); __decorate([ WithConfig(), InputBoolean() ], NzDescriptionsComponent.prototype, "nzColon", void 0); i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "14.2.12", ngImport: i0, type: NzDescriptionsComponent, decorators: [{ type: Component, args: [{ changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, selector: 'nz-descriptions', exportAs: 'nzDescriptions', preserveWhitespaces: false, template: ` <div *ngIf="nzTitle || nzExtra" class="ant-descriptions-header"> <div *ngIf="nzTitle" class="ant-descriptions-title"> <ng-container *nzStringTemplateOutlet="nzTitle">{{ nzTitle }}</ng-container> </div> <div *ngIf="nzExtra" class="ant-descriptions-extra"> <ng-container *nzStringTemplateOutlet="nzExtra">{{ nzExtra }}</ng-container> </div> </div> <div class="ant-descriptions-view"> <table> <tbody> <ng-container *ngIf="nzLayout === 'horizontal'"> <tr class="ant-descriptions-row" *ngFor="let row of itemMatrix; let i = index"> <ng-container *ngFor="let item of row; let isLast = last"> <!-- Horizontal & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> <!-- Horizontal & Bordered --> <ng-container *ngIf="nzBordered"> <td class="ant-descriptions-item-label"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> <td class="ant-descriptions-item-content" [colSpan]="item.span * 2 - 1"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </ng-container> </tr> </ng-container> <ng-container *ngIf="nzLayout === 'vertical'"> <!-- Vertical & NOT Bordered --> <ng-container *ngIf="!nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-label" [class.ant-descriptions-item-no-colon]="!nzColon"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </span> </div> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item" [colSpan]="item.span"> <div class="ant-descriptions-item-container"> <span class="ant-descriptions-item-content"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </span> </div> </td> </ng-container> </tr> </ng-container> </ng-container> <!-- Vertical & Bordered --> <ng-container *ngIf="nzBordered"> <ng-container *ngFor="let row of itemMatrix; let i = index"> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-label" [colSpan]="item.span"> <ng-container *nzStringTemplateOutlet="item.title"> {{ item.title }} </ng-container> </td> </ng-container> </tr> <tr class="ant-descriptions-row"> <ng-container *ngFor="let item of row; let isLast = last"> <td class="ant-descriptions-item-content" [colSpan]="item.span"> <ng-template [ngTemplateOutlet]="item.content"></ng-template> </td> </ng-container> </tr> </ng-container> </ng-container> </ng-container> </tbody> </table> </div> `, host: { class: 'ant-descriptions', '[class.ant-descriptions-bordered]': 'nzBordered', '[class.ant-descriptions-middle]': 'nzSize === "middle"', '[class.ant-descriptions-small]': 'nzSize === "small"', '[class.ant-descriptions-rtl]': 'dir === "rtl"' } }] }], ctorParameters: function () { return [{ type: i1.NzConfigService }, { type: i0.ChangeDetectorRef }, { type: i2.NzBreakpointService }, { type: i3.Directionality, decorators: [{ type: Optional }] }]; }, propDecorators: { items: [{ type: ContentChildren, args: [NzDescriptionsItemComponent] }], nzBordered: [{ type: Input }], nzLayout: [{ type: Input }], nzColumn: [{ type: Input }], nzSize: [{ type: Input }], nzTitle: [{ type: Input }], nzExtra: [{ type: Input }], nzColon: [{ type: Input }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVzY3JpcHRpb25zLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uL2NvbXBvbmVudHMvZGVzY3JpcHRpb25zL2Rlc2NyaXB0aW9ucy5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IjtBQU1BLE9BQU8sRUFFTCx1QkFBdUIsRUFFdkIsU0FBUyxFQUNULGVBQWUsRUFDZixLQUFLLEVBSUwsUUFBUSxFQUlSLGlCQUFpQixFQUNsQixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQUUsS0FBSyxFQUFFLE9BQU8sRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUN0QyxPQUFPLEVBQUUsU0FBUyxFQUFFLFNBQVMsRUFBRSxTQUFTLEVBQUUsU0FBUyxFQUFFLEdBQUcsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBRWpGLE9BQU8sRUFBZ0MsVUFBVSxFQUFFLE1BQU0sMkJBQTJCLENBQUM7QUFDckYsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLDJCQUEyQixDQUFDO0FBQ2pELE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxnQkFBZ0IsRUFBdUIsTUFBTSw2QkFBNkIsQ0FBQztBQUV2RyxPQUFPLEVBQUUsWUFBWSxFQUFFLE1BQU0seUJBQXlCLENBQUM7QUFFdkQsT0FBTyxFQUFFLDJCQUEyQixFQUFFLE1BQU0sK0JBQStCLENBQUM7Ozs7Ozs7QUFHNUUsTUFBTSxxQkFBcUIsR0FBZ0IsY0FBYyxDQUFDO0FBQzFELE1BQU0sZ0JBQWdCLEdBQTBDO0lBQzlELEdBQUcsRUFBRSxDQUFDO0lBQ04sRUFBRSxFQUFFLENBQUM7SUFDTCxFQUFFLEVBQUUsQ0FBQztJQUNMLEVBQUUsRUFBRSxDQUFDO0lBQ0wsRUFBRSxFQUFFLENBQUM7SUFDTCxFQUFFLEVBQUUsQ0FBQztDQUNOLENBQUM7QUFxSEYsTUFBTSxPQUFPLHVCQUF1QjtJQXNCbEMsWUFDUyxlQUFnQyxFQUMvQixHQUFzQixFQUN0QixpQkFBc0MsRUFDMUIsY0FBOEI7UUFIM0Msb0JBQWUsR0FBZixlQUFlLENBQWlCO1FBQy9CLFFBQUcsR0FBSCxHQUFHLENBQW1CO1FBQ3RCLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBcUI7UUFDMUIsbUJBQWMsR0FBZCxjQUFjLENBQWdCO1FBekIzQyxrQkFBYSxHQUFnQixxQkFBcUIsQ0FBQztRQU1yQixlQUFVLEdBQVksS0FBSyxDQUFDO1FBQzFELGFBQVEsR0FBeUIsWUFBWSxDQUFDO1FBQ2hDLGFBQVEsR0FBbUQsZ0JBQWdCLENBQUM7UUFDNUUsV0FBTSxHQUF1QixTQUFTLENBQUM7UUFDckQsWUFBTyxHQUErQixFQUFFLENBQUM7UUFFWCxZQUFPLEdBQVksSUFBSSxDQUFDO1FBRS9ELGVBQVUsR0FBc0MsRUFBRSxDQUFDO1FBQ25ELGVBQVUsR0FBRyxDQUFDLENBQUM7UUFDZixRQUFHLEdBQWMsS0FBSyxDQUFDO1FBRWYsZUFBVSxHQUFxQixnQkFBZ0IsQ0FBQyxFQUFFLENBQUM7UUFDbkQsYUFBUSxHQUFHLElBQUksT0FBTyxFQUFRLENBQUM7SUFPcEMsQ0FBQztJQUNKLFFBQVE7UUFDTixJQUFJLENBQUMsR0FBRyxHQUFHLElBQUksQ0FBQyxjQUFjLENBQUMsS0FBSyxDQUFDO1FBQ3JDLElBQUksQ0FBQyxjQUFjLENBQUMsTUFBTSxFQUFFLElBQUksQ0FBQyxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDLENBQUMsU0FBb0IsRUFBRSxFQUFFO1lBQzVGLElBQUksQ0FBQyxHQUFHLEdBQUcsU0FBUyxDQUFDO1FBQ3ZCLENBQUMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELFdBQVcsQ0FBQyxPQUFzQjtRQUNoQyxJQUFJLE9BQU8sQ0FBQyxRQUFRLEVBQUU7WUFDcEIsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1NBQ3RCO0lBQ0gsQ0FBQztJQUVELGtCQUFrQjtRQUNoQixNQUFNLGNBQWMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRSxTQUFTLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxDQUFDLENBQUM7UUFFaEcsS0FBSyxDQUNILGNBQWMsRUFDZCxjQUFjLENBQUMsSUFBSSxDQUFDLFNBQVMsQ0FBQyxHQUFHLEVBQUUsQ0FBQyxLQUFLLENBQUMsR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxZQUFZLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxTQUFTLENBQUMsRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLEVBQ3ZHLElBQUksQ0FBQyxpQkFBaUIsQ0FBQyxTQUFTLENBQUMsaUJBQWlCLENBQUMsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxFQUFFLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxHQUFHLEVBQUUsQ0FBQyxDQUFDLENBQUMsQ0FDNUY7YUFDRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUM5QixTQUFTLENBQUMsR0FBRyxFQUFFO1lBQ2QsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQ3JCLElBQUksQ0FBQyxHQUFHLENBQUMsWUFBWSxFQUFFLENBQUM7UUFDMUIsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRUQsV0FBVztRQUNULElBQUksQ0FBQyxRQUFRLENBQUMsSUFBSSxFQUFFLENBQUM7UUFDckIsSUFBSSxDQUFDLFFBQVEsQ0FBQyxRQUFRLEVBQUUsQ0FBQztJQUMzQixDQUFDO0lBRUQ7O09BRUc7SUFDSyxhQUFhO1FBQ25CLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ2YsT0FBTztTQUNSO1FBRUQsSUFBSSxVQUFVLEdBQW9DLEVBQUUsQ0FBQztRQUNyRCxJQUFJLEtBQUssR0FBRyxDQUFDLENBQUM7UUFFZCxNQUFNLE1BQU0sR0FBRyxDQUFDLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLFNBQVMsRUFBRSxDQUFDLENBQUM7UUFDcEQsTUFBTSxLQUFLLEdBQUcsSUFBSSxDQUFDLEtBQUssQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUNuQyxNQUFNLE1BQU0sR0FBRyxLQUFLLENBQUMsTUFBTSxDQUFDO1FBQzVCLE1BQU0sTUFBTSxHQUFzQyxFQUFFLENBQUM7UUFDckQsTUFBTSxRQUFRLEdBQUcsR0FBUyxFQUFFO1lBQzFCLE1BQU0sQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7WUFDeEIsVUFBVSxHQUFHLEVBQUUsQ0FBQztZQUNoQixLQUFLLEdBQUcsQ0FBQyxDQUFDO1FBQ1osQ0FBQyxDQUFDO1FBRUYsS0FBSyxJQUFJLENBQUMsR0FBRyxDQUFDLEVBQUUsQ0FBQyxHQUFHLE1BQU0sRUFBRSxDQUFDLEVBQUUsRUFBRTtZQUMvQixNQUFNLElBQUksR0FBRyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDdEIsTUFBTSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLE1BQU0sRUFBRSxJQUFJLEVBQUUsR0FBRyxJQUFJLENBQUM7WUFFdkQsS0FBSyxJQUFJLElBQUksQ0FBQztZQUVkLHNFQUFzRTtZQUN0RSxrRkFBa0Y7WUFDbEYsd0JBQXdCO1lBQ3hCLElBQUksS0FBSyxJQUFJLE1BQU0sRUFBRTtnQkFDbkIsSUFBSSxLQUFLLEdBQUcsTUFBTSxFQUFFO29CQUNsQixJQUFJLENBQUMsaUJBQWlCLE1BQU0sMkJBQTJCLEtBQUssRUFBRSxDQUFDLENBQUM7aUJBQ2pFO2dCQUNELFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxRQUFRLEVBQUUsQ0FBQzthQUNaO2lCQUFNLElBQUksQ0FBQyxLQUFLLE1BQU0sR0FBRyxDQUFDLEVBQUU7Z0JBQzNCLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxNQUFNLEdBQUcsQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDLEVBQUUsQ0FBQyxDQUFDO2dCQUNuRSxRQUFRLEVBQUUsQ0FBQzthQUNaO2lCQUFNO2dCQUNMLFVBQVUsQ0FBQyxJQUFJLENBQUMsRUFBRSxLQUFLLEVBQUUsT0FBTyxFQUFFLElBQUksRUFBRSxDQUFDLENBQUM7YUFDM0M7U0FDRjtRQUVELElBQUksQ0FBQyxVQUFVLEdBQUcsTUFBTSxDQUFDO0lBQzNCLENBQUM7SUFFTyxTQUFTO1FBQ2YsSUFBSSxPQUFPLElBQUksQ0FBQyxRQUFRLEtBQUssUUFBUSxFQUFFO1lBQ3JDLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7U0FDdkM7UUFFRCxPQUFPLElBQUksQ0FBQyxRQUFRLENBQUM7SUFDdkIsQ0FBQzs7cUhBbEhVLHVCQUF1Qjt5R0FBdkIsdUJBQXVCLCtmQUtqQiwyQkFBMkIsZ0ZBbEhsQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9HVDs7SUFnQlMsWUFBWSxFQUFFO0lBQUUsVUFBVSxFQUFFOzJEQUE2Qjs7SUFFekQsVUFBVSxFQUFFO3lEQUE2RTs7SUFDekYsVUFBVSxFQUFFO3VEQUF3Qzs7SUFHcEQsVUFBVSxFQUFFO0lBQUUsWUFBWSxFQUFFO3dEQUF5Qjs0RkFicEQsdUJBQXVCO2tCQW5IbkMsU0FBUzttQkFBQztvQkFDVCxlQUFlLEVBQUUsdUJBQXVCLENBQUMsTUFBTTtvQkFDL0MsYUFBYSxFQUFFLGlCQUFpQixDQUFDLElBQUk7b0JBQ3JDLFFBQVEsRUFBRSxpQkFBaUI7b0JBQzNCLFFBQVEsRUFBRSxnQkFBZ0I7b0JBQzFCLG1CQUFtQixFQUFFLEtBQUs7b0JBQzFCLFFBQVEsRUFBRTs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztHQW9HVDtvQkFDRCxJQUFJLEVBQUU7d0JBQ0osS0FBSyxFQUFFLGtCQUFrQjt3QkFDekIsbUNBQW1DLEVBQUUsWUFBWTt3QkFDakQsaUNBQWlDLEVBQUUscUJBQXFCO3dCQUN4RCxnQ0FBZ0MsRUFBRSxvQkFBb0I7d0JBQ3RELDhCQUE4QixFQUFFLGVBQWU7cUJBQ2hEO2lCQUNGOzswQkEyQkksUUFBUTs0Q0FyQm1DLEtBQUs7c0JBQWxELGVBQWU7dUJBQUMsMkJBQTJCO2dCQUVMLFVBQVU7c0JBQWhELEtBQUs7Z0JBQ0csUUFBUTtzQkFBaEIsS0FBSztnQkFDaUIsUUFBUTtzQkFBOUIsS0FBSztnQkFDaUIsTUFBTTtzQkFBNUIsS0FBSztnQkFDRyxPQUFPO3NCQUFmLEtBQUs7Z0JBQ0csT0FBTztzQkFBZixLQUFLO2dCQUNpQyxPQUFPO3NCQUE3QyxLQUFLIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2dpdGh1Yi5jb20vTkctWk9SUk8vbmctem9ycm8tYW50ZC9ibG9iL21hc3Rlci9MSUNFTlNFXG4gKi9cblxuaW1wb3J0IHsgRGlyZWN0aW9uLCBEaXJlY3Rpb25hbGl0eSB9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7XG4gIEFmdGVyQ29udGVudEluaXQsXG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb250ZW50Q2hpbGRyZW4sXG4gIElucHV0LFxuICBPbkNoYW5nZXMsXG4gIE9uRGVzdHJveSxcbiAgT25Jbml0LFxuICBPcHRpb25hbCxcbiAgUXVlcnlMaXN0LFxuICBTaW1wbGVDaGFuZ2VzLFxuICBUZW1wbGF0ZVJlZixcbiAgVmlld0VuY2Fwc3VsYXRpb25cbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBtZXJnZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgYXVkaXRUaW1lLCBzdGFydFdpdGgsIHN3aXRjaE1hcCwgdGFrZVVudGlsLCB0YXAgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5cbmltcG9ydCB7IE56Q29uZmlnS2V5LCBOekNvbmZpZ1NlcnZpY2UsIFdpdGhDb25maWcgfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvY29uZmlnJztcbmltcG9ydCB7IHdhcm4gfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvbG9nZ2VyJztcbmltcG9ydCB7IGdyaWRSZXNwb25zaXZlTWFwLCBOekJyZWFrcG9pbnRFbnVtLCBOekJyZWFrcG9pbnRTZXJ2aWNlIH0gZnJvbSAnbmctem9ycm8tYW50ZC9jb3JlL3NlcnZpY2VzJztcbmltcG9ydCB7IEJvb2xlYW5JbnB1dCB9IGZyb20gJ25nLXpvcnJvLWFudGQvY29yZS90eXBlcyc7XG5pbXBvcnQgeyBJbnB1dEJvb2xlYW4gfSBmcm9tICduZy16b3Jyby1hbnRkL2NvcmUvdXRpbCc7XG5cbmltcG9ydCB7IE56RGVzY3JpcHRpb25zSXRlbUNvbXBvbmVudCB9IGZyb20gJy4vZGVzY3JpcHRpb25zLWl0ZW0uY29tcG9uZW50JztcbmltcG9ydCB7IE56RGVzY3JpcHRpb25zSXRlbVJlbmRlclByb3BzLCBOekRlc2NyaXB0aW9uc0xheW91dCwgTnpEZXNjcmlwdGlvbnNTaXplIH0gZnJvbSAnLi90eXBpbmdzJztcblxuY29uc3QgTlpfQ09ORklHX01PRFVMRV9OQU1FOiBOekNvbmZpZ0tleSA9ICdkZXNjcmlwdGlvbnMnO1xuY29uc3QgZGVmYXVsdENvbHVtbk1hcDogeyBba2V5IGluIE56QnJlYWtwb2ludEVudW1dOiBudW1iZXIgfSA9IHtcbiAgeHhsOiAzLFxuICB4bDogMyxcbiAgbGc6IDMsXG4gIG1kOiAzLFxuICBzbTogMixcbiAgeHM6IDFcbn07XG5cbkBDb21wb25lbnQoe1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbiAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgc2VsZWN0b3I6ICduei1kZXNjcmlwdGlvbnMnLFxuICBleHBvcnRBczogJ256RGVzY3JpcHRpb25zJyxcbiAgcHJlc2VydmVXaGl0ZXNwYWNlczogZmFsc2UsXG4gIHRlbXBsYXRlOiBgXG4gICAgPGRpdiAqbmdJZj1cIm56VGl0bGUgfHwgbnpFeHRyYVwiIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1oZWFkZXJcIj5cbiAgICAgIDxkaXYgKm5nSWY9XCJuelRpdGxlXCIgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLXRpdGxlXCI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJuelRpdGxlXCI+e3sgbnpUaXRsZSB9fTwvbmctY29udGFpbmVyPlxuICAgICAgPC9kaXY+XG4gICAgICA8ZGl2ICpuZ0lmPVwibnpFeHRyYVwiIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1leHRyYVwiPlxuICAgICAgICA8bmctY29udGFpbmVyICpuelN0cmluZ1RlbXBsYXRlT3V0bGV0PVwibnpFeHRyYVwiPnt7IG56RXh0cmEgfX08L25nLWNvbnRhaW5lcj5cbiAgICAgIDwvZGl2PlxuICAgIDwvZGl2PlxuICAgIDxkaXYgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLXZpZXdcIj5cbiAgICAgIDx0YWJsZT5cbiAgICAgICAgPHRib2R5PlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJuekxheW91dCA9PT0gJ2hvcml6b250YWwnXCI+XG4gICAgICAgICAgICA8dHIgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLXJvd1wiICpuZ0Zvcj1cImxldCByb3cgb2YgaXRlbU1hdHJpeDsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvdzsgbGV0IGlzTGFzdCA9IGxhc3RcIj5cbiAgICAgICAgICAgICAgICA8IS0tIEhvcml6b250YWwgJiBOT1QgQm9yZGVyZWQgLS0+XG4gICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFuekJvcmRlcmVkXCI+XG4gICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW1cIiBbY29sU3Bhbl09XCJpdGVtLnNwYW5cIj5cbiAgICAgICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1jb250YWluZXJcIj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1sYWJlbFwiIFtjbGFzcy5hbnQtZGVzY3JpcHRpb25zLWl0ZW0tbm8tY29sb25dPVwiIW56Q29sb25cIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJpdGVtLnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0udGl0bGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtaXRlbS1jb250ZW50XCI+XG4gICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbS5jb250ZW50XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICA8L3NwYW4+XG4gICAgICAgICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICA8IS0tIEhvcml6b250YWwgJiBCb3JkZXJlZCAtLT5cbiAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibnpCb3JkZXJlZFwiPlxuICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWxhYmVsXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJpdGVtLnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS50aXRsZSB9fVxuICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgIDwvdGQ+XG4gICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tY29udGVudFwiIFtjb2xTcGFuXT1cIml0ZW0uc3BhbiAqIDIgLSAxXCI+XG4gICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJpdGVtLmNvbnRlbnRcIj48L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L3RyPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuXG4gICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIm56TGF5b3V0ID09PSAndmVydGljYWwnXCI+XG4gICAgICAgICAgICA8IS0tIFZlcnRpY2FsICYgTk9UIEJvcmRlcmVkIC0tPlxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cIiFuekJvcmRlcmVkXCI+XG4gICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IHJvdyBvZiBpdGVtTWF0cml4OyBsZXQgaSA9IGluZGV4XCI+XG4gICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygcm93OyBsZXQgaXNMYXN0ID0gbGFzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW1cIiBbY29sU3Bhbl09XCJpdGVtLnNwYW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tbGFiZWxcIiBbY2xhc3MuYW50LWRlc2NyaXB0aW9ucy1pdGVtLW5vLWNvbG9uXT1cIiFuekNvbG9uXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm56U3RyaW5nVGVtcGxhdGVPdXRsZXQ9XCJpdGVtLnRpdGxlXCI+XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge3sgaXRlbS50aXRsZSB9fVxuICAgICAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygcm93OyBsZXQgaXNMYXN0ID0gbGFzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW1cIiBbY29sU3Bhbl09XCJpdGVtLnNwYW5cIj5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWNvbnRhaW5lclwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPHNwYW4gY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tY29udGVudFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgW25nVGVtcGxhdGVPdXRsZXRdPVwiaXRlbS5jb250ZW50XCI+PC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgICAgICAgICAgIDwvc3Bhbj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8IS0tIFZlcnRpY2FsICYgQm9yZGVyZWQgLS0+XG4gICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwibnpCb3JkZXJlZFwiPlxuICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCByb3cgb2YgaXRlbU1hdHJpeDsgbGV0IGkgPSBpbmRleFwiPlxuICAgICAgICAgICAgICAgIDx0ciBjbGFzcz1cImFudC1kZXNjcmlwdGlvbnMtcm93XCI+XG4gICAgICAgICAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0Zvcj1cImxldCBpdGVtIG9mIHJvdzsgbGV0IGlzTGFzdCA9IGxhc3RcIj5cbiAgICAgICAgICAgICAgICAgICAgPHRkIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1pdGVtLWxhYmVsXCIgW2NvbFNwYW5dPVwiaXRlbS5zcGFuXCI+XG4gICAgICAgICAgICAgICAgICAgICAgPG5nLWNvbnRhaW5lciAqbnpTdHJpbmdUZW1wbGF0ZU91dGxldD1cIml0ZW0udGl0bGVcIj5cbiAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0udGl0bGUgfX1cbiAgICAgICAgICAgICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICAgICAgICAgICAgPC90ZD5cbiAgICAgICAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgICAgICAgIDwvdHI+XG4gICAgICAgICAgICAgICAgPHRyIGNsYXNzPVwiYW50LWRlc2NyaXB0aW9ucy1yb3dcIj5cbiAgICAgICAgICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nRm9yPVwibGV0IGl0ZW0gb2Ygcm93OyBsZXQgaXNMYXN0ID0gbGFzdFwiPlxuICAgICAgICAgICAgICAgICAgICA8dGQgY2xhc3M9XCJhbnQtZGVzY3JpcHRpb25zLWl0ZW0tY29udGVudFwiIFtjb2xTcGFuXT1cIml0ZW0uc3BhblwiPlxuICAgICAgICAgICAgICAgICAgICAgIDxuZy10ZW1wbGF0ZSBbbmdUZW1wbGF0ZU91dGxldF09XCJpdGVtLmNvbnRlbnRcIj48L25nLXRlbXBsYXRlPlxuICAgICAgICAgICAgICAgICAgICA8L3RkPlxuICAgICAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICAgICAgPC90cj5cbiAgICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC90Ym9keT5cbiAgICAgIDwvdGFibGU+XG4gICAgPC9kaXY+XG4gIGAsXG4gIGhvc3Q6IHtcbiAgICBjbGFzczogJ2FudC1kZXNjcmlwdGlvbnMnLFxuICAgICdbY2xhc3MuYW50LWRlc2NyaXB0aW9ucy1ib3JkZXJlZF0nOiAnbnpCb3JkZXJlZCcsXG4gICAgJ1tjbGFzcy5hbnQtZGVzY3JpcHRpb25zLW1pZGRsZV0nOiAnbnpTaXplID09PSBcIm1pZGRsZVwiJyxcbiAgICAnW2NsYXNzLmFudC1kZXNjcmlwdGlvbnMtc21hbGxdJzogJ256U2l6ZSA9PT0gXCJzbWFsbFwiJyxcbiAgICAnW2NsYXNzLmFudC1kZXNjcmlwdGlvbnMtcnRsXSc6ICdkaXIgPT09IFwicnRsXCInXG4gIH1cbn0pXG5leHBvcnQgY2xhc3MgTnpEZXNjcmlwdGlvbnNDb21wb25lbnQgaW1wbGVtZW50cyBPbkNoYW5nZXMsIE9uRGVzdHJveSwgQWZ0ZXJDb250ZW50SW5pdCwgT25Jbml0IHtcbiAgcmVhZG9ubHkgX256TW9kdWxlTmFtZTogTnpDb25maWdLZXkgPSBOWl9DT05GSUdfTU9EVUxFX05BTUU7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekJvcmRlcmVkOiBCb29sZWFuSW5wdXQ7XG4gIHN0YXRpYyBuZ0FjY2VwdElucHV0VHlwZV9uekNvbG9uOiBCb29sZWFuSW5wdXQ7XG5cbiAgQENvbnRlbnRDaGlsZHJlbihOekRlc2NyaXB0aW9uc0l0ZW1Db21wb25lbnQpIGl0ZW1zITogUXVlcnlMaXN0PE56RGVzY3JpcHRpb25zSXRlbUNvbXBvbmVudD47XG5cbiAgQElucHV0KCkgQElucHV0Qm9vbGVhbigpIEBXaXRoQ29uZmlnKCkgbnpCb3JkZXJlZDogYm9vbGVhbiA9IGZhbHNlO1xuICBASW5wdXQoKSBuekxheW91dDogTnpEZXNjcmlwdGlvbnNMYXlvdXQgPSAnaG9yaXpvbnRhbCc7XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgbnpDb2x1bW46IG51bWJlciB8IHsgW2tleSBpbiBOekJyZWFrcG9pbnRFbnVtXTogbnVtYmVyIH0gPSBkZWZhdWx0Q29sdW1uTWFwO1xuICBASW5wdXQoKSBAV2l0aENvbmZpZygpIG56U2l6ZTogTnpEZXNjcmlwdGlvbnNTaXplID0gJ2RlZmF1bHQnO1xuICBASW5wdXQoKSBuelRpdGxlOiBzdHJpbmcgfCBUZW1wbGF0ZVJlZjx2b2lkPiA9ICcnO1xuICBASW5wdXQoKSBuekV4dHJhPzogc3RyaW5nIHwgVGVtcGxhdGVSZWY8dm9pZD47XG4gIEBJbnB1dCgpIEBXaXRoQ29uZmlnKCkgQElucHV0Qm9vbGVhbigpIG56Q29sb246IGJvb2xlYW4gPSB0cnVlO1xuXG4gIGl0ZW1NYXRyaXg6IE56RGVzY3JpcHRpb25zSXRlbVJlbmRlclByb3BzW11bXSA9IFtdO1xuICByZWFsQ29sdW1uID0gMztcbiAgZGlyOiBEaXJlY3Rpb24gPSAnbHRyJztcblxuICBwcml2YXRlIGJyZWFrcG9pbnQ6IE56QnJlYWtwb2ludEVudW0gPSBOekJyZWFrcG9pbnRFbnVtLm1kO1xuICBwcml2YXRlIGRlc3Ryb3kkID0gbmV3IFN1YmplY3Q8dm9pZD4oKTtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwdWJsaWMgbnpDb25maWdTZXJ2aWNlOiBOekNvbmZpZ1NlcnZpY2UsXG4gICAgcHJpdmF0ZSBjZHI6IENoYW5nZURldGVjdG9yUmVmLFxuICAgIHByaXZhdGUgYnJlYWtwb2ludFNlcnZpY2U6IE56QnJlYWtwb2ludFNlcnZpY2UsXG4gICAgQE9wdGlvbmFsKCkgcHJpdmF0ZSBkaXJlY3Rpb25hbGl0eTogRGlyZWN0aW9uYWxpdHlcbiAgKSB7fVxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmRpciA9IHRoaXMuZGlyZWN0aW9uYWxpdHkudmFsdWU7XG4gICAgdGhpcy5kaXJlY3Rpb25hbGl0eS5jaGFuZ2U/LnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKS5zdWJzY3JpYmUoKGRpcmVjdGlvbjogRGlyZWN0aW9uKSA9PiB7XG4gICAgICB0aGlzLmRpciA9IGRpcmVjdGlvbjtcbiAgICB9KTtcbiAgfVxuXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcbiAgICBpZiAoY2hhbmdlcy5uekNvbHVtbikge1xuICAgICAgdGhpcy5wcmVwYXJlTWF0cml4KCk7XG4gICAgfVxuICB9XG5cbiAgbmdBZnRlckNvbnRlbnRJbml0KCk6IHZvaWQge1xuICAgIGNvbnN0IGNvbnRlbnRDaGFuZ2UkID0gdGhpcy5pdGVtcy5jaGFuZ2VzLnBpcGUoc3RhcnRXaXRoKHRoaXMuaXRlbXMpLCB0YWtlVW50aWwodGhpcy5kZXN0cm95JCkpO1xuXG4gICAgbWVyZ2UoXG4gICAgICBjb250ZW50Q2hhbmdlJCxcbiAgICAgIGNvbnRlbnRDaGFuZ2UkLnBpcGUoc3dpdGNoTWFwKCgpID0+IG1lcmdlKC4uLnRoaXMuaXRlbXMubWFwKGkgPT4gaS5pbnB1dENoYW5nZSQpKS5waXBlKGF1ZGl0VGltZSgxNikpKSksXG4gICAgICB0aGlzLmJyZWFrcG9pbnRTZXJ2aWNlLnN1YnNjcmliZShncmlkUmVzcG9uc2l2ZU1hcCkucGlwZSh0YXAoYnAgPT4gKHRoaXMuYnJlYWtwb2ludCA9IGJwKSkpXG4gICAgKVxuICAgICAgLnBpcGUodGFrZVVudGlsKHRoaXMuZGVzdHJveSQpKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMucHJlcGFyZU1hdHJpeCgpO1xuICAgICAgICB0aGlzLmNkci5tYXJrRm9yQ2hlY2soKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgbmdPbkRlc3Ryb3koKTogdm9pZCB7XG4gICAgdGhpcy5kZXN0cm95JC5uZXh0KCk7XG4gICAgdGhpcy5kZXN0cm95JC5jb21wbGV0ZSgpO1xuICB9XG5cbiAgLyoqXG4gICAqIFByZXBhcmUgdGhlIHJlbmRlciBtYXRyaXggYWNjb3JkaW5nIHRvIGRlc2NyaXB0aW9uIGl0ZW1zJyBzcGFucy5cbiAgICovXG4gIHByaXZhdGUgcHJlcGFyZU1hdHJpeCgpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuaXRlbXMpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBsZXQgY3VycmVudFJvdzogTnpEZXNjcmlwdGlvbnNJdGVtUmVuZGVyUHJvcHNbXSA9IFtdO1xuICAgIGxldCB3aWR0aCA9IDA7XG5cbiAgICBjb25zdCBjb2x1bW4gPSAodGhpcy5yZWFsQ29sdW1uID0gdGhpcy5nZXRDb2x1bW4oKSk7XG4gICAgY29uc3QgaXRlbXMgPSB0aGlzLml0ZW1zLnRvQXJyYXkoKTtcbiAgICBjb25zdCBsZW5ndGggPSBpdGVtcy5sZW5ndGg7XG4gICAgY29uc3QgbWF0cml4OiBOekRlc2NyaXB0aW9uc0l0ZW1SZW5kZXJQcm9wc1tdW10gPSBbXTtcbiAgICBjb25zdCBmbHVzaFJvdyA9ICgpOiB2b2lkID0+IHtcbiAgICAgIG1hdHJpeC5wdXNoKGN1cnJlbnRSb3cpO1xuICAgICAgY3VycmVudFJvdyA9IFtdO1xuICAgICAgd2lkdGggPSAwO1xuICAgIH07XG5cbiAgICBmb3IgKGxldCBpID0gMDsgaSA8IGxlbmd0aDsgaSsrKSB7XG4gICAgICBjb25zdCBpdGVtID0gaXRlbXNbaV07XG4gICAgICBjb25zdCB7IG56VGl0bGU6IHRpdGxlLCBjb250ZW50LCBuelNwYW46IHNwYW4gfSA9IGl0ZW07XG5cbiAgICAgIHdpZHRoICs9IHNwYW47XG5cbiAgICAgIC8vIElmIHRoZSBsYXN0IGl0ZW0gbWFrZSB0aGUgcm93J3MgbGVuZ3RoIGV4Y2VlZHMgYG56Q29sdW1uYCwgdGhlIGxhc3RcbiAgICAgIC8vIGl0ZW0gc2hvdWxkIHRha2UgYWxsIHRoZSBzcGFjZSBsZWZ0LiBUaGlzIGxvZ2ljIGlzIGltcGxlbWVudGVkIGluIHRoZSB0ZW1wbGF0ZS5cbiAgICAgIC8vIFdhcm4gdXNlciBhYm91dCB0aGF0LlxuICAgICAgaWYgKHdpZHRoID49IGNvbHVtbikge1xuICAgICAgICBpZiAod2lkdGggPiBjb2x1bW4pIHtcbiAgICAgICAgICB3YXJuKGBcIm56Q29sdW1uXCIgaXMgJHtjb2x1bW59IGJ1dCB3ZSBoYXZlIHJvdyBsZW5ndGggJHt3aWR0aH1gKTtcbiAgICAgICAgfVxuICAgICAgICBjdXJyZW50Um93LnB1c2goeyB0aXRsZSwgY29udGVudCwgc3BhbjogY29sdW1uIC0gKHdpZHRoIC0gc3BhbikgfSk7XG4gICAgICAgIGZsdXNoUm93KCk7XG4gICAgICB9IGVsc2UgaWYgKGkgPT09IGxlbmd0aCAtIDEpIHtcbiAgICAgICAgY3VycmVudFJvdy5wdXNoKHsgdGl0bGUsIGNvbnRlbnQsIHNwYW46IGNvbHVtbiAtICh3aWR0aCAtIHNwYW4pIH0pO1xuICAgICAgICBmbHVzaFJvdygpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY3VycmVudFJvdy5wdXNoKHsgdGl0bGUsIGNvbnRlbnQsIHNwYW4gfSk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgdGhpcy5pdGVtTWF0cml4ID0gbWF0cml4O1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRDb2x1bW4oKTogbnVtYmVyIHtcbiAgICBpZiAodHlwZW9mIHRoaXMubnpDb2x1bW4gIT09ICdudW1iZXInKSB7XG4gICAgICByZXR1cm4gdGhpcy5uekNvbHVtblt0aGlzLmJyZWFrcG9pbnRdO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm56Q29sdW1uO1xuICB9XG59XG4iXX0=