UNPKG

@hmcts/media-viewer

Version:
120 lines 43.9 kB
import { Component, Input, ViewChild } from '@angular/core'; import { FormControl, FormGroup, Validators } from '@angular/forms'; import { combineLatest } from 'rxjs'; import { select } from '@ngrx/store'; import * as fromSelectors from '../../store/selectors/annotation.selectors'; import * as fromAnnoActions from '../../store/actions/annotation.actions'; import * as fromTagSelectors from '../../store/selectors/tag.selectors'; import * as i0 from "@angular/core"; import * as i1 from "@ngrx/store"; import * as i2 from "../../print.service"; import * as i3 from "../../toolbar/toolbar-event.service"; import * as i4 from "@angular/forms"; import * as i5 from "@angular/cdk/a11y"; import * as i6 from "@angular/common"; import * as i7 from "@angular/router"; import * as i8 from "@swimlane/ngx-datatable"; import * as i9 from "../../shared/gov-uk-date/gov-uk-date.component"; import * as i10 from "../../shared/gov-uk-fieldset/gov-uk-fieldset.component"; import * as i11 from "rpx-xui-translation"; import * as i12 from "../pipes/unsnake/unsnake.pipe"; export class CommentsSummaryComponent { constructor(store, printService, toolbarEvents, fb) { this.store = store; this.printService = printService; this.toolbarEvents = toolbarEvents; this.fb = fb; this.showFilters = false; this.hasFilter = false; this.fromFilterValid = true; this.toFilterValid = true; } ngOnInit() { this.filtersFg = this.fb.group({ dateRangeFrom: new FormGroup({ day: new FormControl('', [Validators.required]), month: new FormControl('', [Validators.required]), year: new FormControl('', [Validators.required]) }), dateRangeTo: new FormGroup({ day: new FormControl('', [Validators.required]), month: new FormControl('', [Validators.required]), year: new FormControl('', [Validators.required]) }), tagFilters: this.fb.group({}), }); this.comments$ = this.store.pipe(select(fromSelectors.getCommentSummary)); this.buildCheckBoxForm(); this.container.nativeElement.focus(); } buildCheckBoxForm() { this.filtersFg.reset(); const checkboxes = this.filtersFg.get('tagFilters'); const filters$ = this.store.pipe(select(fromSelectors.getCommentSummaryFilters)); this.allTags$ = this.store.pipe(select(fromTagSelectors.getAllTagsArr)); this.$subscriptions = combineLatest([this.allTags$, filters$]).subscribe(([tags, filters]) => { this.hasFilter = filters.hasFilter; tags.forEach((val) => { const checkBoxValue = (filters.filters.tagFilters && filters.filters.tagFilters.hasOwnProperty(val.key)) ? filters.filters.tagFilters[val.key] : false; checkboxes.addControl(val.key, new FormControl(checkBoxValue)); }); this.filtersFg.updateValueAndValidity(); }); } onClearFilters() { this.store.dispatch(new fromAnnoActions.ClearCommentSummaryFilters()); this.buildCheckBoxForm(); } onFilter() { const { value } = this.filtersFg; const hasDateFrom = (value.dateRangeFrom.year && value.dateRangeFrom.month && value.dateRangeFrom.day); const hasDateTo = (value.dateRangeTo.year && value.dateRangeTo.month && value.dateRangeTo.day); const dateRangeFrom = hasDateFrom ? new Date(value.dateRangeFrom.year, value.dateRangeFrom.month - 1, value.dateRangeFrom.day).getTime() : null; const dateRangeTo = hasDateTo ? new Date(value.dateRangeTo.year, value.dateRangeTo.month - 1, value.dateRangeTo.day).getTime() : null; this.fromFilterValid = hasDateFrom ? true : false; this.toFilterValid = hasDateTo ? true : false; if (this.filtersFg.valid) { this.store.dispatch(new fromAnnoActions.ApplyCommentSymmaryFilter({ ...value, dateRangeFrom, dateRangeTo })); } } onFiltersToggle() { this.showFilters = !this.showFilters; } onClose() { this.toolbarEvents.toggleCommentsSummary(false); } onPrint() { this.printService.printElementNatively(this.commentsTable.nativeElement, 1000, 900); } navigateToPage(pageNumber) { if (this.contentType === 'pdf') { this.toolbarEvents.setPage(pageNumber); } this.toolbarEvents.toggleCommentsSummary(false); this.toolbarEvents.toggleCommentsPanel(true); } ngOnDestroy() { this.$subscriptions.unsubscribe(); } /** @nocollapse */ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CommentsSummaryComponent, deps: [{ token: i1.Store }, { token: i2.PrintService }, { token: i3.ToolbarEventService }, { token: i4.FormBuilder }], target: i0.ɵɵFactoryTarget.Component }); } /** @nocollapse */ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.3.12", type: CommentsSummaryComponent, selector: "mv-comments-summary", inputs: { title: "title", contentType: "contentType" }, viewQueries: [{ propertyName: "container", first: true, predicate: ["outerContainer"], descendants: true, static: true }, { propertyName: "commentsTable", first: true, predicate: ["commentContainer"], descendants: true }], ngImport: i0, template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onClose()\">\n <div\n #outerContainer\n id=\"modal\"\n class=\"modal-content govuk-width-container clearfix\"\n (click)=\"$event.stopPropagation()\"\n cdkTrapFocus\n tabindex=\"0\"\n >\n <div id=\"comment-container\" class=\"comment-container\" #commentContainer>\n <h2 class=\"govuk-heading-m\">{{ title }}</h2>\n <ng-container *ngIf=\"comments$ | async as comments\">\n <ng-container *ngIf=\"comments.length\">\n <button\n type=\"submit\"\n class=\"govuk-button govuk-!-margin-right-1\"\n (click)=\"onFiltersToggle()\"\n >\n {{\n !showFilters\n ? (\"Show Filters\" | rpxTranslate)\n : (\"Hide Filters\" | rpxTranslate)\n }}\n </button>\n <button\n type=\"submit\"\n class=\"govuk-button govuk-button--secondary\"\n (click)=\"onClearFilters()\"\n *ngIf=\"hasFilter\"\n >\n {{ \"Clear Filters\" | rpxTranslate }}\n </button>\n <ng-container *ngIf=\"showFilters\">\n <form [formGroup]=\"filtersFg\" (ngSubmit)=\"onFilter()\">\n <div class=\"dates\">\n <div class=\"dates__from\">\n <mv-gov-uk-date\n [config]=\"{ id: 'dateRangeFrom', legend: 'From' }\"\n [formGroup]=\"filtersFg.controls['dateRangeFrom']\"\n [errorMessage]=\"{\n isInvalid: !fromFilterValid,\n messages: ['From date is required']\n }\"\n ></mv-gov-uk-date>\n </div>\n <div class=\"dates__to\">\n <mv-gov-uk-date\n [config]=\"{ id: 'dateRangeTo', legend: 'To' }\"\n [formGroup]=\"filtersFg.controls['dateRangeTo']\"\n [errorMessage]=\"{\n isInvalid: !toFilterValid,\n messages: ['To date is required']\n }\"\n ></mv-gov-uk-date>\n </div>\n <div class=\"dates__tags\">\n <mv-gov-uk-fieldset\n [config]=\"{\n legend: 'Tags',\n classes: 'govuk-label--m',\n id: 'filters'\n }\"\n [isHeading]=\"false\"\n >\n <div\n class=\"govuk-checkboxes--scroll\"\n [formGroup]=\"filtersFg.controls['tagFilters']\"\n >\n <div class=\"govuk-checkboxes govuk-checkboxes--small\">\n <div\n class=\"govuk-checkboxes__item\"\n *ngFor=\"let item of allTags$ | async\"\n >\n <input\n [formControlName]=\"item.key\"\n class=\"govuk-checkboxes__input\"\n [value]=\"false\"\n type=\"checkbox\"\n />\n <label class=\"govuk-label govuk-checkboxes__label\">\n {{ item.key | unsnake }} ({{ item.length }})\n </label>\n </div>\n </div>\n </div>\n </mv-gov-uk-fieldset>\n </div>\n <div class=\"dates__cta\">\n <button type=\"submit\" class=\"govuk-button\">\n {{ \"Filter comments\" | rpxTranslate }}\n </button>\n </div>\n </div>\n </form>\n </ng-container>\n <ng-container *ngIf=\"comments[0]\">\n <ngx-datatable\n [rows]=\"comments\"\n rowHeight=\"auto\"\n headerHeight=\"auto\"\n [columnMode]=\"'flex'\"\n [sorts]=\"[{ prop: 'date', dir: 'desc' }]\"\n >\n <ngx-datatable-column\n name=\"{{ 'User' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n [sortable]=\"false\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Page' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n >\n <ng-template ngx-datatable-cell-template let-value=\"value\">\n <a\n [routerLink]=\"[]\"\n class=\"comment-summary_pages\"\n (click)=\"navigateToPage(value)\"\n >{{ value }}</a\n >\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Date' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Comment' | rpxTranslate }}\"\n [flexGrow]=\"3\"\n [sortable]=\"false\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Tags' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n [sortable]=\"false\"\n >\n <ng-template ngx-datatable-cell-template let-value=\"value\">\n <span class=\"hmcts-badge\" *ngFor=\"let tag of value\">{{\n tag.label\n }}</span>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!comments[0]\">\n <h3 class=\"govuk-heading-s\">\n {{\n \"No comments available. Select text to add a highlight or comment.\"\n | rpxTranslate\n }}\n </h3>\n </ng-container>\n </ng-container>\n </div>\n\n <div class=\"button-container\">\n <button (click)=\"onPrint()\" class=\"govuk-button govuk-button--secondary\">\n {{ \"Print\" | rpxTranslate }}\n </button>\n <button id=\"modal-close-button\" (click)=\"onClose()\" class=\"govuk-button\">\n {{ \"Close\" | rpxTranslate }}\n </button>\n </div>\n </div>\n</div>\n", dependencies: [{ kind: "directive", type: i5.CdkTrapFocus, selector: "[cdkTrapFocus]", inputs: ["cdkTrapFocus", "cdkTrapFocusAutoCapture"], exportAs: ["cdkTrapFocus"] }, { kind: "directive", type: i6.NgForOf, selector: "[ngFor][ngForOf]", inputs: ["ngForOf", "ngForTrackBy", "ngForTemplate"] }, { kind: "directive", type: i6.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i4.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i4.CheckboxControlValueAccessor, selector: "input[type=checkbox][formControlName],input[type=checkbox][formControl],input[type=checkbox][ngModel]" }, { kind: "directive", type: i4.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i4.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i7.RouterLink, selector: "[routerLink]", inputs: ["target", "queryParams", "fragment", "queryParamsHandling", "state", "info", "relativeTo", "preserveFragment", "skipLocationChange", "replaceUrl", "routerLink"] }, { kind: "directive", type: i4.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: i4.FormControlName, selector: "[formControlName]", inputs: ["formControlName", "disabled", "ngModel"], outputs: ["ngModelChange"] }, { kind: "component", type: i8.DatatableComponent, selector: "ngx-datatable", inputs: ["targetMarkerTemplate", "rows", "groupRowsBy", "groupedRows", "columns", "selected", "scrollbarV", "scrollbarH", "rowHeight", "columnMode", "headerHeight", "footerHeight", "externalPaging", "externalSorting", "limit", "count", "offset", "loadingIndicator", "selectionType", "reorderable", "swapColumns", "sortType", "sorts", "cssClasses", "messages", "rowClass", "selectCheck", "displayCheck", "groupExpansionDefault", "trackByProp", "selectAllRowsOnPage", "virtualization", "treeFromRelation", "treeToRelation", "summaryRow", "summaryHeight", "summaryPosition", "rowIdentity"], outputs: ["scroll", "activate", "select", "sort", "page", "reorder", "resize", "tableContextmenu", "treeAction"] }, { kind: "directive", type: i8.DataTableColumnDirective, selector: "ngx-datatable-column", inputs: ["name", "prop", "frozenLeft", "frozenRight", "flexGrow", "resizeable", "comparator", "pipe", "sortable", "draggable", "canAutoResize", "minWidth", "width", "maxWidth", "checkboxable", "headerCheckboxable", "headerClass", "cellClass", "isTreeColumn", "treeLevelIndent", "summaryFunc", "summaryTemplate", "cellTemplate", "headerTemplate", "treeToggleTemplate"] }, { kind: "directive", type: i8.DataTableColumnCellDirective, selector: "[ngx-datatable-cell-template]" }, { kind: "component", type: i9.GovUkDateComponent, selector: "mv-gov-uk-date", inputs: ["config", "errorMessage", "formGroup"] }, { kind: "component", type: i10.GovUkFieldsetComponent, selector: "mv-gov-uk-fieldset", inputs: ["config", "isHeading", "errorMessage"] }, { kind: "pipe", type: i6.AsyncPipe, name: "async" }, { kind: "pipe", type: i11.RpxTranslatePipe, name: "rpxTranslate" }, { kind: "pipe", type: i12.UnsnakePipe, name: "unsnake" }] }); } } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.3.12", ngImport: i0, type: CommentsSummaryComponent, decorators: [{ type: Component, args: [{ selector: 'mv-comments-summary', template: "<div id=\"modal-background\" class=\"modal\" (click)=\"onClose()\">\n <div\n #outerContainer\n id=\"modal\"\n class=\"modal-content govuk-width-container clearfix\"\n (click)=\"$event.stopPropagation()\"\n cdkTrapFocus\n tabindex=\"0\"\n >\n <div id=\"comment-container\" class=\"comment-container\" #commentContainer>\n <h2 class=\"govuk-heading-m\">{{ title }}</h2>\n <ng-container *ngIf=\"comments$ | async as comments\">\n <ng-container *ngIf=\"comments.length\">\n <button\n type=\"submit\"\n class=\"govuk-button govuk-!-margin-right-1\"\n (click)=\"onFiltersToggle()\"\n >\n {{\n !showFilters\n ? (\"Show Filters\" | rpxTranslate)\n : (\"Hide Filters\" | rpxTranslate)\n }}\n </button>\n <button\n type=\"submit\"\n class=\"govuk-button govuk-button--secondary\"\n (click)=\"onClearFilters()\"\n *ngIf=\"hasFilter\"\n >\n {{ \"Clear Filters\" | rpxTranslate }}\n </button>\n <ng-container *ngIf=\"showFilters\">\n <form [formGroup]=\"filtersFg\" (ngSubmit)=\"onFilter()\">\n <div class=\"dates\">\n <div class=\"dates__from\">\n <mv-gov-uk-date\n [config]=\"{ id: 'dateRangeFrom', legend: 'From' }\"\n [formGroup]=\"filtersFg.controls['dateRangeFrom']\"\n [errorMessage]=\"{\n isInvalid: !fromFilterValid,\n messages: ['From date is required']\n }\"\n ></mv-gov-uk-date>\n </div>\n <div class=\"dates__to\">\n <mv-gov-uk-date\n [config]=\"{ id: 'dateRangeTo', legend: 'To' }\"\n [formGroup]=\"filtersFg.controls['dateRangeTo']\"\n [errorMessage]=\"{\n isInvalid: !toFilterValid,\n messages: ['To date is required']\n }\"\n ></mv-gov-uk-date>\n </div>\n <div class=\"dates__tags\">\n <mv-gov-uk-fieldset\n [config]=\"{\n legend: 'Tags',\n classes: 'govuk-label--m',\n id: 'filters'\n }\"\n [isHeading]=\"false\"\n >\n <div\n class=\"govuk-checkboxes--scroll\"\n [formGroup]=\"filtersFg.controls['tagFilters']\"\n >\n <div class=\"govuk-checkboxes govuk-checkboxes--small\">\n <div\n class=\"govuk-checkboxes__item\"\n *ngFor=\"let item of allTags$ | async\"\n >\n <input\n [formControlName]=\"item.key\"\n class=\"govuk-checkboxes__input\"\n [value]=\"false\"\n type=\"checkbox\"\n />\n <label class=\"govuk-label govuk-checkboxes__label\">\n {{ item.key | unsnake }} ({{ item.length }})\n </label>\n </div>\n </div>\n </div>\n </mv-gov-uk-fieldset>\n </div>\n <div class=\"dates__cta\">\n <button type=\"submit\" class=\"govuk-button\">\n {{ \"Filter comments\" | rpxTranslate }}\n </button>\n </div>\n </div>\n </form>\n </ng-container>\n <ng-container *ngIf=\"comments[0]\">\n <ngx-datatable\n [rows]=\"comments\"\n rowHeight=\"auto\"\n headerHeight=\"auto\"\n [columnMode]=\"'flex'\"\n [sorts]=\"[{ prop: 'date', dir: 'desc' }]\"\n >\n <ngx-datatable-column\n name=\"{{ 'User' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n [sortable]=\"false\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Page' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n >\n <ng-template ngx-datatable-cell-template let-value=\"value\">\n <a\n [routerLink]=\"[]\"\n class=\"comment-summary_pages\"\n (click)=\"navigateToPage(value)\"\n >{{ value }}</a\n >\n </ng-template>\n </ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Date' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Comment' | rpxTranslate }}\"\n [flexGrow]=\"3\"\n [sortable]=\"false\"\n ></ngx-datatable-column>\n <ngx-datatable-column\n name=\"{{ 'Tags' | rpxTranslate }}\"\n [flexGrow]=\"1\"\n [sortable]=\"false\"\n >\n <ng-template ngx-datatable-cell-template let-value=\"value\">\n <span class=\"hmcts-badge\" *ngFor=\"let tag of value\">{{\n tag.label\n }}</span>\n </ng-template>\n </ngx-datatable-column>\n </ngx-datatable>\n </ng-container>\n </ng-container>\n <ng-container *ngIf=\"!comments[0]\">\n <h3 class=\"govuk-heading-s\">\n {{\n \"No comments available. Select text to add a highlight or comment.\"\n | rpxTranslate\n }}\n </h3>\n </ng-container>\n </ng-container>\n </div>\n\n <div class=\"button-container\">\n <button (click)=\"onPrint()\" class=\"govuk-button govuk-button--secondary\">\n {{ \"Print\" | rpxTranslate }}\n </button>\n <button id=\"modal-close-button\" (click)=\"onClose()\" class=\"govuk-button\">\n {{ \"Close\" | rpxTranslate }}\n </button>\n </div>\n </div>\n</div>\n" }] }], ctorParameters: () => [{ type: i1.Store }, { type: i2.PrintService }, { type: i3.ToolbarEventService }, { type: i4.FormBuilder }], propDecorators: { title: [{ type: Input }], contentType: [{ type: Input }], container: [{ type: ViewChild, args: ['outerContainer', { static: true }] }], commentsTable: [{ type: ViewChild, args: ['commentContainer', { static: false }] }] } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbWVudHMtc3VtbWFyeS5jb21wb25lbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9tZWRpYS12aWV3ZXIvc3JjL2xpYi9hbm5vdGF0aW9ucy9jb21tZW50cy1zdW1tYXJ5L2NvbW1lbnRzLXN1bW1hcnkuY29tcG9uZW50LnRzIiwiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvbWVkaWEtdmlld2VyL3NyYy9saWIvYW5ub3RhdGlvbnMvY29tbWVudHMtc3VtbWFyeS9jb21tZW50cy1zdW1tYXJ5LmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFBRSxTQUFTLEVBQUUsS0FBSyxFQUFFLFNBQVMsRUFBaUMsTUFBTSxlQUFlLENBQUM7QUFDM0YsT0FBTyxFQUFlLFdBQVcsRUFBRSxTQUFTLEVBQXNCLFVBQVUsRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQ3JHLE9BQU8sRUFBRSxhQUFhLEVBQTRCLE1BQU0sTUFBTSxDQUFDO0FBQy9ELE9BQU8sRUFBRSxNQUFNLEVBQVMsTUFBTSxhQUFhLENBQUM7QUFJNUMsT0FBTyxLQUFLLGFBQWEsTUFBTSw0Q0FBNEMsQ0FBQztBQUU1RSxPQUFPLEtBQUssZUFBZSxNQUFNLHdDQUF3QyxDQUFDO0FBQzFFLE9BQU8sS0FBSyxnQkFBZ0IsTUFBTSxxQ0FBcUMsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7QUFNeEUsTUFBTSxPQUFPLHdCQUF3QjtJQWVuQyxZQUNVLEtBQTBDLEVBQ2pDLFlBQTBCLEVBQzFCLGFBQWtDLEVBQzNDLEVBQWU7UUFIZixVQUFLLEdBQUwsS0FBSyxDQUFxQztRQUNqQyxpQkFBWSxHQUFaLFlBQVksQ0FBYztRQUMxQixrQkFBYSxHQUFiLGFBQWEsQ0FBcUI7UUFDM0MsT0FBRSxHQUFGLEVBQUUsQ0FBYTtRQVR6QixnQkFBVyxHQUFHLEtBQUssQ0FBQztRQUNwQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xC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LHdCQUF3QjtrQkFKcEMsU0FBUzsrQkFDRSxxQkFBcUI7aUtBS3RCLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUN5QyxTQUFTO3NCQUF2RCxTQUFTO3VCQUFDLGdCQUFnQixFQUFFLEVBQUUsTUFBTSxFQUFFLElBQUksRUFBRTtnQkFDSyxhQUFhO3NCQUE5RCxTQUFTO3VCQUFDLGtCQUFrQixFQUFFLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IENvbXBvbmVudCwgSW5wdXQsIFZpZXdDaGlsZCwgRWxlbWVudFJlZiwgT25Jbml0LCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7IEZvcm1CdWlsZGVyLCBGb3JtQ29udHJvbCwgRm9ybUdyb3VwLCBVbnR5cGVkRm9ybUNvbnRyb2wsIFZhbGlkYXRvcnMgfSBmcm9tICdAYW5ndWxhci9mb3Jtcyc7XG5pbXBvcnQgeyBjb21iaW5lTGF0ZXN0LCBPYnNlcnZhYmxlLCBTdWJzY3JpcHRpb24gfSBmcm9tICdyeGpzJztcbmltcG9ydCB7IHNlbGVjdCwgU3RvcmUgfSBmcm9tICdAbmdyeC9zdG9yZSc7XG5cbmltcG9ydCB7IFByaW50U2VydmljZSB9IGZyb20gJy4uLy4uL3ByaW50LnNlcnZpY2UnO1xuaW1wb3J0IHsgVG9vbGJhckV2ZW50U2VydmljZSB9IGZyb20gJy4uLy4uL3Rvb2xiYXIvdG9vbGJhci1ldmVudC5zZXJ2aWNlJztcbmltcG9ydCAqIGFzIGZyb21TZWxlY3RvcnMgZnJvbSAnLi4vLi4vc3RvcmUvc2VsZWN0b3JzL2Fubm90YXRpb24uc2VsZWN0b3JzJztcbmltcG9ydCAqIGFzIGZyb21TdG9yZSBmcm9tICcuLi8uLi9zdG9yZS9yZWR1Y2Vycy9yZWR1Y2Vycyc7XG5pbXBvcnQgKiBhcyBmcm9tQW5ub0FjdGlvbnMgZnJvbSAnLi4vLi4vc3RvcmUvYWN0aW9ucy9hbm5vdGF0aW9uLmFjdGlvbnMnO1xuaW1wb3J0ICogYXMgZnJvbVRhZ1NlbGVjdG9ycyBmcm9tICcuLi8uLi9zdG9yZS9zZWxlY3RvcnMvdGFnLnNlbGVjdG9ycyc7XG5cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ212LWNvbW1lbnRzLXN1bW1hcnknLFxuICB0ZW1wbGF0ZVVybDogJy4vY29tbWVudHMtc3VtbWFyeS5jb21wb25lbnQuaHRtbCcsXG59KVxuZXhwb3J0IGNsYXNzIENvbW1lbnRzU3VtbWFyeUNvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgT25EZXN0cm95IHtcblxuICBASW5wdXQoKSB0aXRsZTogc3RyaW5nO1xuICBASW5wdXQoKSBjb250ZW50VHlwZTogc3RyaW5nO1xuICBAVmlld0NoaWxkKCdvdXRlckNvbnRhaW5lcicsIHsgc3RhdGljOiB0cnVlIH0pIGNvbnRhaW5lcjogRWxlbWVudFJlZjtcbiAgQFZpZXdDaGlsZCgnY29tbWVudENvbnRhaW5lcicsIHsgc3RhdGljOiBmYWxzZSB9KSBjb21tZW50c1RhYmxlOiBFbGVtZW50UmVmO1xuICBwdWJsaWMgY29tbWVudHMkOiBPYnNlcnZhYmxlPGFueT47XG4gIHB1YmxpYyBmaWx0ZXJzRmc6IEZvcm1Hcm91cDtcbiAgcHJpdmF0ZSAkc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uO1xuICBhbGxUYWdzJDogT2JzZXJ2YWJsZTx7IGtleTogc3RyaW5nOyBsZW5ndGg6IG51bWJlciB9W10+O1xuICBzaG93RmlsdGVycyA9IGZhbHNlO1xuICBoYXNGaWx0ZXIgPSBmYWxzZTtcbiAgZnJvbUZpbHRlclZhbGlkOiBib29sZWFuID0gdHJ1ZTtcbiAgdG9GaWx0ZXJWYWxpZDogYm9vbGVhbiA9IHRydWU7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJpdmF0ZSBzdG9yZTogU3RvcmU8ZnJvbVN0b3JlLkFubm90YXRpb25TZXRTdGF0ZT4sXG4gICAgcHJpdmF0ZSByZWFkb25seSBwcmludFNlcnZpY2U6IFByaW50U2VydmljZSxcbiAgICBwcml2YXRlIHJlYWRvbmx5IHRvb2xiYXJFdmVudHM6IFRvb2xiYXJFdmVudFNlcnZpY2UsXG4gICAgcHJpdmF0ZSBmYjogRm9ybUJ1aWxkZXJcbiAgKSB7IH1cblxuICBuZ09uSW5pdCgpOiB2b2lkIHtcbiAgICB0aGlzLmZpbHRlcnNGZyA9IHRoaXMuZmIuZ3JvdXAoe1xuICAgICAgZGF0ZVJhbmdlRnJvbTogbmV3IEZvcm1Hcm91cCh7XG4gICAgICAgIGRheTogbmV3IEZvcm1Db250cm9sKCcnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF0pLFxuICAgICAgICBtb250aDogbmV3IEZvcm1Db250cm9sKCcnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF0pLFxuICAgICAgICB5ZWFyOiBuZXcgRm9ybUNvbnRyb2woJycsIFtWYWxpZGF0b3JzLnJlcXVpcmVkXSlcbiAgICAgIH0pLFxuICAgICAgZGF0ZVJhbmdlVG86IG5ldyBGb3JtR3JvdXAoe1xuICAgICAgICBkYXk6IG5ldyBGb3JtQ29udHJvbCgnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWRdKSxcbiAgICAgICAgbW9udGg6IG5ldyBGb3JtQ29udHJvbCgnJywgW1ZhbGlkYXRvcnMucmVxdWlyZWRdKSxcbiAgICAgICAgeWVhcjogbmV3IEZvcm1Db250cm9sKCcnLCBbVmFsaWRhdG9ycy5yZXF1aXJlZF0pXG4gICAgICB9KSxcbiAgICAgIHRhZ0ZpbHRlcnM6IHRoaXMuZmIuZ3JvdXAoe30pLFxuICAgIH0pO1xuICAgIHRoaXMuY29tbWVudHMkID0gdGhpcy5zdG9yZS5waXBlKHNlbGVjdChmcm9tU2VsZWN0b3JzLmdldENvbW1lbnRTdW1tYXJ5KSk7XG4gICAgdGhpcy5idWlsZENoZWNrQm94Rm9ybSgpO1xuICAgIHRoaXMuY29udGFpbmVyLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKTtcbiAgfVxuXG4gIGJ1aWxkQ2hlY2tCb3hGb3JtKCkge1xuICAgIHRoaXMuZmlsdGVyc0ZnLnJlc2V0KCk7XG4gICAgY29uc3QgY2hlY2tib3hlcyA9IDxGb3JtR3JvdXA+dGhpcy5maWx0ZXJzRmcuZ2V0KCd0YWdGaWx0ZXJzJyk7XG4gICAgY29uc3QgZmlsdGVycyQgPSB0aGlzLnN0b3JlLnBpcGUoc2VsZWN0KGZyb21TZWxlY3RvcnMuZ2V0Q29tbWVudFN1bW1hcnlGaWx0ZXJzKSk7XG4gICAgdGhpcy5hbGxUYWdzJCA9IHRoaXMuc3RvcmUucGlwZShzZWxlY3QoZnJvbVRhZ1NlbGVjdG9ycy5nZXRBbGxUYWdzQXJyKSk7XG4gICAgdGhpcy4kc3Vic2NyaXB0aW9ucyA9IGNvbWJpbmVMYXRlc3QoW3RoaXMuYWxsVGFncyQsIGZpbHRlcnMkXSkuc3Vic2NyaWJlKChbdGFncywgZmlsdGVyc10pID0+IHtcbiAgICAgIHRoaXMuaGFzRmlsdGVyID0gZmlsdGVycy5oYXNGaWx0ZXI7XG4gICAgICB0YWdzLmZvckVhY2goKHZhbCkgPT4ge1xuICAgICAgICBjb25zdCBjaGVja0JveFZhbHVlID0gKGZpbHRlcnMuZmlsdGVycy50YWdGaWx0ZXJzICYmXG4gICAgICAgICAgZmlsdGVycy5maWx0ZXJzLnRhZ0ZpbHRlcnMuaGFzT3duUHJvcGVydHkodmFsLmtleSkpID9cbiAgICAgICAgICBmaWx0ZXJzLmZpbHRlcnMudGFnRmlsdGVyc1t2YWwua2V5XSA6IGZhbHNlO1xuICAgICAgICBjaGVja2JveGVzLmFkZENvbnRyb2wodmFsLmtleSwgbmV3IEZvcm1Db250cm9sKGNoZWNrQm94VmFsdWUpKTtcbiAgICAgIH0pO1xuICAgICAgdGhpcy5maWx0ZXJzRmcudXBkYXRlVmFsdWVBbmRWYWxpZGl0eSgpO1xuICAgIH0pO1xuICB9XG5cbiAgb25DbGVhckZpbHRlcnMoKSB7XG4gICAgdGhpcy5zdG9yZS5kaXNwYXRjaChuZXcgZnJvbUFubm9BY3Rpb25zLkNsZWFyQ29tbWVudFN1bW1hcnlGaWx0ZXJzKCkpO1xuICAgIHRoaXMuYnVpbGRDaGVja0JveEZvcm0oKTtcbiAgfVxuXG4gIG9uRmlsdGVyKCkge1xuICAgIGNvbnN0IHsgdmFsdWUgfSA9IHRoaXMuZmlsdGVyc0ZnO1xuXG5cbiAgICBjb25zdCBoYXNEYXRlRnJvbSA9ICh2YWx1ZS5kYXRlUmFuZ2VGcm9tLnllYXIgJiYgdmFsdWUuZGF0ZVJhbmdlRnJvbS5tb250aCAmJiB2YWx1ZS5kYXRlUmFuZ2VGcm9tLmRheSk7XG4gICAgY29uc3QgaGFzRGF0ZVRvID0gKHZhbHVlLmRhdGVSYW5nZVRvLnllYXIgJiYgdmFsdWUuZGF0ZVJhbmdlVG8ubW9udGggJiYgdmFsdWUuZGF0ZVJhbmdlVG8uZGF5KTtcbiAgICBjb25zdCBkYXRlUmFuZ2VGcm9tID0gaGFzRGF0ZUZyb20gP1xuICAgICAgbmV3IERhdGUodmFsdWUuZGF0ZVJhbmdlRnJvbS55ZWFyLCB2YWx1ZS5kYXRlUmFuZ2VGcm9tLm1vbnRoIC0gMSwgdmFsdWUuZGF0ZVJhbmdlRnJvbS5kYXkpLmdldFRpbWUoKSA6IG51bGw7XG4gICAgY29uc3QgZGF0ZVJhbmdlVG8gPSBoYXNEYXRlVG8gP1xuICAgICAgbmV3IERhdGUodmFsdWUuZGF0ZVJhbmdlVG8ueWVhciwgdmFsdWUuZGF0ZVJhbmdlVG8ubW9udGggLSAxLCB2YWx1ZS5kYXRlUmFuZ2VUby5kYXkpLmdldFRpbWUoKSA6IG51bGw7XG5cbiAgICB0aGlzLmZyb21GaWx0ZXJWYWxpZCA9IGhhc0RhdGVGcm9tID8gdHJ1ZSA6IGZhbHNlO1xuICAgIHRoaXMudG9GaWx0ZXJWYWxpZCA9IGhhc0RhdGVUbyA/IHRydWUgOiBmYWxzZTtcblxuICAgIGlmICh0aGlzLmZpbHRlcnNGZy52YWxpZCkge1xuICAgICAgdGhpcy5zdG9yZS5kaXNwYXRjaChuZXcgZnJvbUFubm9BY3Rpb25zLkFwcGx5Q29tbWVudFN5bW1hcnlGaWx0ZXIoeyAuLi52YWx1ZSwgZGF0ZVJhbmdlRnJvbSwgZGF0ZVJhbmdlVG8gfSkpO1xuICAgIH1cbiAgfVxuXG4gIG9uRmlsdGVyc1RvZ2dsZSgpIHtcbiAgICB0aGlzLnNob3dGaWx0ZXJzID0gIXRoaXMuc2hvd0ZpbHRlcnM7XG4gIH1cblxuICBwdWJsaWMgb25DbG9zZSgpOiB2b2lkIHtcbiAgICB0aGlzLnRvb2xiYXJFdmVudHMudG9nZ2xlQ29tbWVudHNTdW1tYXJ5KGZhbHNlKTtcbiAgfVxuXG4gIHB1YmxpYyBvblByaW50KCk6IHZvaWQge1xuICAgIHRoaXMucHJpbnRTZXJ2aWNlLnByaW50RWxlbWVudE5hdGl2ZWx5KHRoaXMuY29tbWVudHNUYWJsZS5uYXRpdmVFbGVtZW50LCAxMDAwLCA5MDApO1xuICB9XG5cbiAgbmF2aWdhdGVUb1BhZ2UocGFnZU51bWJlcjogbnVtYmVyKSB7XG4gICAgaWYgKHRoaXMuY29udGVudFR5cGUgPT09ICdwZGYnKSB7XG4gICAgICB0aGlzLnRvb2xiYXJFdmVudHMuc2V0UGFnZShwYWdlTnVtYmVyKTtcbiAgICB9XG4gICAgdGhpcy50b29sYmFyRXZlbnRzLnRvZ2dsZUNvbW1lbnRzU3VtbWFyeShmYWxzZSk7XG4gICAgdGhpcy50b29sYmFyRXZlbnRzLnRvZ2dsZUNvbW1lbnRzUGFuZWwodHJ1ZSk7XG4gIH1cblxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcbiAgICB0aGlzLiRzdWJzY3JpcHRpb25zLnVuc3Vic2NyaWJlKCk7XG4gIH1cbn1cbiIsIjxkaXYgaWQ9XCJtb2RhbC1iYWNrZ3JvdW5kXCIgY2xhc3M9XCJtb2RhbFwiIChjbGljayk9XCJvbkNsb3NlKClcIj5cbiAgPGRpdlxuICAgICNvdXRlckNvbnRhaW5lclxuICAgIGlkPVwibW9kYWxcIlxuICAgIGNsYXNzPVwibW9kYWwtY29udGVudCBnb3Z1ay13aWR0aC1jb250YWluZXIgY2xlYXJmaXhcIlxuICAgIChjbGljayk9XCIkZXZlbnQuc3RvcFByb3BhZ2F0aW9uKClcIlxuICAgIGNka1RyYXBGb2N1c1xuICAgIHRhYmluZGV4PVwiMFwiXG4gID5cbiAgICA8ZGl2IGlkPVwiY29tbWVudC1jb250YWluZXJcIiBjbGFzcz1cImNvbW1lbnQtY29udGFpbmVyXCIgI2NvbW1lbnRDb250YWluZXI+XG4gICAgICA8aDIgY2xhc3M9XCJnb3Z1ay1oZWFkaW5nLW1cIj57eyB0aXRsZSB9fTwvaDI+XG4gICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwiY29tbWVudHMkIHwgYXN5bmMgYXMgY29tbWVudHNcIj5cbiAgICAgICAgPG5nLWNvbnRhaW5lciAqbmdJZj1cImNvbW1lbnRzLmxlbmd0aFwiPlxuICAgICAgICAgIDxidXR0b25cbiAgICAgICAgICAgIHR5cGU9XCJzdWJtaXRcIlxuICAgICAgICAgICAgY2xhc3M9XCJnb3Z1ay1idXR0b24gZ292dWstIS1tYXJnaW4tcmlnaHQtMVwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25GaWx0ZXJzVG9nZ2xlKClcIlxuICAgICAgICAgID5cbiAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgICFzaG93RmlsdGVyc1xuICAgICAgICAgICAgICAgID8gKFwiU2hvdyBGaWx0ZXJzXCIgfCBycHhUcmFuc2xhdGUpXG4gICAgICAgICAgICAgICAgOiAoXCJIaWRlIEZpbHRlcnNcIiB8IHJweFRyYW5zbGF0ZSlcbiAgICAgICAgICAgIH19XG4gICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgPGJ1dHRvblxuICAgICAgICAgICAgdHlwZT1cInN1Ym1pdFwiXG4gICAgICAgICAgICBjbGFzcz1cImdvdnVrLWJ1dHRvbiBnb3Z1ay1idXR0b24tLXNlY29uZGFyeVwiXG4gICAgICAgICAgICAoY2xpY2spPVwib25DbGVhckZpbHRlcnMoKVwiXG4gICAgICAgICAgICAqbmdJZj1cImhhc0ZpbHRlclwiXG4gICAgICAgICAgPlxuICAgICAgICAgICAge3sgXCJDbGVhciBGaWx0ZXJzXCIgfCBycHhUcmFuc2xhdGUgfX1cbiAgICAgICAgICA8L2J1dHRvbj5cbiAgICAgICAgICA8bmctY29udGFpbmVyICpuZ0lmPVwic2hvd0ZpbHRlcnNcIj5cbiAgICAgICAgICAgIDxmb3JtIFtmb3JtR3JvdXBdPVwiZmlsdGVyc0ZnXCIgKG5nU3VibWl0KT1cIm9uRmlsdGVyKClcIj5cbiAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVzXCI+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVzX19mcm9tXCI+XG4gICAgICAgICAgICAgICAgICA8bXYtZ292LXVrLWRhdGVcbiAgICAgICAgICAgICAgICAgICAgW2NvbmZpZ109XCJ7IGlkOiAnZGF0ZVJhbmdlRnJvbScsIGxlZ2VuZDogJ0Zyb20nIH1cIlxuICAgICAgICAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImZpbHRlcnNGZy5jb250cm9sc1snZGF0ZVJhbmdlRnJvbSddXCJcbiAgICAgICAgICAgICAgICAgICAgW2Vycm9yTWVzc2FnZV09XCJ7XG4gICAgICAgICAgICAgICAgICAgICAgaXNJbnZhbGlkOiAhZnJvbUZpbHRlclZhbGlkLFxuICAgICAgICAgICAgICAgICAgICAgIG1lc3NhZ2VzOiBbJ0Zyb20gZGF0ZSBpcyByZXF1aXJlZCddXG4gICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgPjwvbXYtZ292LXVrLWRhdGU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVzX190b1wiPlxuICAgICAgICAgICAgICAgICAgPG12LWdvdi11ay1kYXRlXG4gICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwieyBpZDogJ2RhdGVSYW5nZVRvJywgbGVnZW5kOiAnVG8nIH1cIlxuICAgICAgICAgICAgICAgICAgICBbZm9ybUdyb3VwXT1cImZpbHRlcnNGZy5jb250cm9sc1snZGF0ZVJhbmdlVG8nXVwiXG4gICAgICAgICAgICAgICAgICAgIFtlcnJvck1lc3NhZ2VdPVwie1xuICAgICAgICAgICAgICAgICAgICAgIGlzSW52YWxpZDogIXRvRmlsdGVyVmFsaWQsXG4gICAgICAgICAgICAgICAgICAgICAgbWVzc2FnZXM6IFsnVG8gZGF0ZSBpcyByZXF1aXJlZCddXG4gICAgICAgICAgICAgICAgICAgIH1cIlxuICAgICAgICAgICAgICAgICAgPjwvbXYtZ292LXVrLWRhdGU+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgPGRpdiBjbGFzcz1cImRhdGVzX190YWdzXCI+XG4gICAgICAgICAgICAgICAgICA8bXYtZ292LXVrLWZpZWxkc2V0XG4gICAgICAgICAgICAgICAgICAgIFtjb25maWddPVwie1xuICAgICAgICAgICAgICAgICAgICAgIGxlZ2VuZDogJ1RhZ3MnLFxuICAgICAgICAgICAgICAgICAgICAgIGNsYXNzZXM6ICdnb3Z1ay1sYWJlbC0tbScsXG4gICAgICAgICAgICAgICAgICAgICAgaWQ6ICdmaWx0ZXJzJ1xuICAgICAgICAgICAgICAgICAgICB9XCJcbiAgICAgICAgICAgICAgICAgICAgW2lzSGVhZGluZ109XCJmYWxzZVwiXG4gICAgICAgICAgICAgICAgICA+XG4gICAgICAgICAgICAgICAgICAgIDxkaXZcbiAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImdvdnVrLWNoZWNrYm94ZXMtLXNjcm9sbFwiXG4gICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Hcm91cF09XCJmaWx0ZXJzRmcuY29udHJvbHNbJ3RhZ0ZpbHRlcnMnXVwiXG4gICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZ292dWstY2hlY2tib3hlcyBnb3Z1ay1jaGVja2JveGVzLS1zbWFsbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgPGRpdlxuICAgICAgICAgICAgICAgICAgICAgICAgICBjbGFzcz1cImdvdnVrLWNoZWNrYm94ZXNfX2l0ZW1cIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAqbmdGb3I9XCJsZXQgaXRlbSBvZiBhbGxUYWdzJCB8IGFzeW5jXCJcbiAgICAgICAgICAgICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgPGlucHV0XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW2Zvcm1Db250cm9sTmFtZV09XCJpdGVtLmtleVwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgY2xhc3M9XCJnb3Z1ay1jaGVja2JveGVzX19pbnB1dFwiXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgW3ZhbHVlXT1cImZhbHNlXCJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxuICAgICAgICAgICAgICAgICAgICAgICAgICAvPlxuICAgICAgICAgICAgICAgICAgICAgICAgICA8bGFiZWwgY2xhc3M9XCJnb3Z1ay1sYWJlbCBnb3Z1ay1jaGVja2JveGVzX19sYWJlbFwiPlxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHt7IGl0ZW0ua2V5IHwgdW5zbmFrZSB9fSAoe3sgaXRlbS5sZW5ndGggfX0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgIDwvbGFiZWw+XG4gICAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgICAgICA8L212LWdvdi11ay1maWVsZHNldD5cbiAgICAgICAgICAgICAgICA8L2Rpdj5cbiAgICAgICAgICAgICAgICA8ZGl2IGNsYXNzPVwiZGF0ZXNfX2N0YVwiPlxuICAgICAgICAgICAgICAgICAgPGJ1dHRvbiB0eXBlPVwic3VibWl0XCIgY2xhc3M9XCJnb3Z1ay1idXR0b25cIj5cbiAgICAgICAgICAgICAgICAgICAge3sgXCJGaWx0ZXIgY29tbWVudHNcIiB8IHJweFRyYW5zbGF0ZSB9fVxuICAgICAgICAgICAgICAgICAgPC9idXR0b24+XG4gICAgICAgICAgICAgICAgPC9kaXY+XG4gICAgICAgICAgICAgIDwvZGl2PlxuICAgICAgICAgICAgPC9mb3JtPlxuICAgICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCJjb21tZW50c1swXVwiPlxuICAgICAgICAgICAgPG5neC1kYXRhdGFibGVcbiAgICAgICAgICAgICAgW3Jvd3NdPVwiY29tbWVudHNcIlxuICAgICAgICAgICAgICByb3dIZWlnaHQ9XCJhdXRvXCJcbiAgICAgICAgICAgICAgaGVhZGVySGVpZ2h0PVwiYXV0b1wiXG4gICAgICAgICAgICAgIFtjb2x1bW5Nb2RlXT1cIidmbGV4J1wiXG4gICAgICAgICAgICAgIFtzb3J0c109XCJbeyBwcm9wOiAnZGF0ZScsIGRpcjogJ2Rlc2MnIH1dXCJcbiAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgPG5neC1kYXRhdGFibGUtY29sdW1uXG4gICAgICAgICAgICAgICAgbmFtZT1cInt7ICdVc2VyJyB8IHJweFRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICAgICAgW2ZsZXhHcm93XT1cIjFcIlxuICAgICAgICAgICAgICAgIFtzb3J0YWJsZV09XCJmYWxzZVwiXG4gICAgICAgICAgICAgID48L25neC1kYXRhdGFibGUtY29sdW1uPlxuICAgICAgICAgICAgICA8bmd4LWRhdGF0YWJsZS1jb2x1bW5cbiAgICAgICAgICAgICAgICBuYW1lPVwie3sgJ1BhZ2UnIHwgcnB4VHJhbnNsYXRlIH19XCJcbiAgICAgICAgICAgICAgICBbZmxleEdyb3ddPVwiMVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbmd4LWRhdGF0YWJsZS1jZWxsLXRlbXBsYXRlIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICA8YVxuICAgICAgICAgICAgICAgICAgICBbcm91dGVyTGlua109XCJbXVwiXG4gICAgICAgICAgICAgICAgICAgIGNsYXNzPVwiY29tbWVudC1zdW1tYXJ5X3BhZ2VzXCJcbiAgICAgICAgICAgICAgICAgICAgKGNsaWNrKT1cIm5hdmlnYXRlVG9QYWdlKHZhbHVlKVwiXG4gICAgICAgICAgICAgICAgICAgID57eyB2YWx1ZSB9fTwvYVxuICAgICAgICAgICAgICAgICAgPlxuICAgICAgICAgICAgICAgIDwvbmctdGVtcGxhdGU+XG4gICAgICAgICAgICAgIDwvbmd4LWRhdGF0YWJsZS1jb2x1bW4+XG4gICAgICAgICAgICAgIDxuZ3gtZGF0YXRhYmxlLWNvbHVtblxuICAgICAgICAgICAgICAgIG5hbWU9XCJ7eyAnRGF0ZScgfCBycHhUcmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICAgIFtmbGV4R3Jvd109XCIxXCJcbiAgICAgICAgICAgICAgPjwvbmd4LWRhdGF0YWJsZS1jb2x1bW4+XG4gICAgICAgICAgICAgIDxuZ3gtZGF0YXRhYmxlLWNvbHVtblxuICAgICAgICAgICAgICAgIG5hbWU9XCJ7eyAnQ29tbWVudCcgfCBycHhUcmFuc2xhdGUgfX1cIlxuICAgICAgICAgICAgICAgIFtmbGV4R3Jvd109XCIzXCJcbiAgICAgICAgICAgICAgICBbc29ydGFibGVdPVwiZmFsc2VcIlxuICAgICAgICAgICAgICA+PC9uZ3gtZGF0YXRhYmxlLWNvbHVtbj5cbiAgICAgICAgICAgICAgPG5neC1kYXRhdGFibGUtY29sdW1uXG4gICAgICAgICAgICAgICAgbmFtZT1cInt7ICdUYWdzJyB8IHJweFRyYW5zbGF0ZSB9fVwiXG4gICAgICAgICAgICAgICAgW2ZsZXhHcm93XT1cIjFcIlxuICAgICAgICAgICAgICAgIFtzb3J0YWJsZV09XCJmYWxzZVwiXG4gICAgICAgICAgICAgID5cbiAgICAgICAgICAgICAgICA8bmctdGVtcGxhdGUgbmd4LWRhdGF0YWJsZS1jZWxsLXRlbXBsYXRlIGxldC12YWx1ZT1cInZhbHVlXCI+XG4gICAgICAgICAgICAgICAgICA8c3BhbiBjbGFzcz1cImhtY3RzLWJhZGdlXCIgKm5nRm9yPVwibGV0IHRhZyBvZiB2YWx1ZVwiPnt7XG4gICAgICAgICAgICAgICAgICAgIHRhZy5sYWJlbFxuICAgICAgICAgICAgICAgICAgfX08L3NwYW4+XG4gICAgICAgICAgICAgICAgPC9uZy10ZW1wbGF0ZT5cbiAgICAgICAgICAgICAgPC9uZ3gtZGF0YXRhYmxlLWNvbHVtbj5cbiAgICAgICAgICAgIDwvbmd4LWRhdGF0YWJsZT5cbiAgICAgICAgICA8L25nLWNvbnRhaW5lcj5cbiAgICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgICAgIDxuZy1jb250YWluZXIgKm5nSWY9XCIhY29tbWVudHNbMF1cIj5cbiAgICAgICAgICA8aDMgY2xhc3M9XCJnb3Z1ay1oZWFkaW5nLXNcIj5cbiAgICAgICAgICAgIHt7XG4gICAgICAgICAgICAgIFwiTm8gY29tbWVudHMgYXZhaWxhYmxlLiBTZWxlY3QgdGV4dCB0byBhZGQgYSBoaWdobGlnaHQgb3IgY29tbWVudC5cIlxuICAgICAgICAgICAgICAgIHwgcnB4VHJhbnNsYXRlXG4gICAgICAgICAgICB9fVxuICAgICAgICAgIDwvaDM+XG4gICAgICAgIDwvbmctY29udGFpbmVyPlxuICAgICAgPC9uZy1jb250YWluZXI+XG4gICAgPC9kaXY+XG5cbiAgICA8ZGl2IGNsYXNzPVwiYnV0dG9uLWNvbnRhaW5lclwiPlxuICAgICAgPGJ1dHRvbiAoY2xpY2spPVwib25QcmludCgpXCIgY2xhc3M9XCJnb3Z1ay1idXR0b24gZ292dWstYnV0dG9uLS1zZWNvbmRhcnlcIj5cbiAgICAgICAge3sgXCJQcmludFwiIHwgcnB4VHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICAgIDxidXR0b24gaWQ9XCJtb2RhbC1jbG9zZS1idXR0b25cIiAoY2xpY2spPVwib25DbG9zZSgpXCIgY2xhc3M9XCJnb3Z1ay1idXR0b25cIj5cbiAgICAgICAge3sgXCJDbG9zZVwiIHwgcnB4VHJhbnNsYXRlIH19XG4gICAgICA8L2J1dHRvbj5cbiAgICA8L2Rpdj5cbiAgPC9kaXY+XG48L2Rpdj5cbiJdfQ==