cfc-ds
Version:
Design System do Conselho Federal de Contabilidade baseado no govbr-ds
221 lines • 42.7 kB
JavaScript
import { Component, EventEmitter, Input, Output, ContentChildren, } from '@angular/core';
import { ColumnTemplateDirective } from '../../directives/column-template.directive';
import * as i0 from "@angular/core";
import * as i1 from "@angular/common";
import * as i2 from "../icon/icon.component";
export class SortEvent {
key;
direction;
}
export class SimpleColumn {
key;
field;
label;
sortable = false;
customCell = false;
width;
constructor(key, label) {
this.key = key;
this.label = label;
this.field = key;
}
static fromArray(array) {
return array.map(item => new SimpleColumn(item.key, item.label).withCustomCell(item.customCell));
}
static column(key, label) {
return new SimpleColumn(key, label);
}
static custom(key, label) {
return new SimpleColumn(key, label).withCustomCell(true);
}
static sortable(key, label, field = 'id') {
return new SimpleColumn(key, label).withSortable(true).withField(field);
}
static action() {
return new SimpleColumn('actions', 'Ações').withCustomCell(true).withSortable(false);
}
withField(field) {
this.field = field;
return this;
}
withSortable(sortable = false) {
this.sortable = sortable;
return this;
}
withCustomCell(customCell = false) {
this.customCell = customCell;
return this;
}
withWidth(width) {
this.width = width;
return this;
}
}
export class TableComponent {
columns;
lines;
customTable;
pagination = { totalElements: 0 };
hasCheckbox = false;
noItensMessage = '';
sortable = false;
emptyMessageTitle = 'Nenhum item encontrado';
emptyMessageDescription = 'Não foi possível encontrar nenhum item com os critérios de busca atuais.';
emptyMessageIcon = 'clipboard';
selectedLines = new EventEmitter();
listActions = [];
selectLines = [];
filteredModule;
sort = new EventEmitter();
sortKey = null;
sortDirection = 'asc';
onItensPerPageChange = new EventEmitter();
onPageChange = new EventEmitter();
templates;
internalTemplates;
get allTemplates() {
return [...this.internalTemplates, ...(this.templates || [])];
}
ngOnInit() {
}
ngAfterViewInit() {
this.initializeTable();
}
initializeTable() {
const tableList = [];
const tables = Array.from(window.document.querySelectorAll('.br-table'));
for (const [index, brTable] of tables.entries()) {
tableList.push(new window.core.BRTable('br-table', brTable, index));
}
}
getNestedValue(obj, path) {
return path.split('.').reduce((acc, part) => acc && acc[part], obj);
}
selectAllCheckbox() {
const mainCheckbox = document.querySelector('.checked-all');
const checkboxes = document.querySelectorAll('.checkbox-item');
const bar = document.querySelector('.selected-bar');
const countElement = document.querySelector('.count');
const textElement = document.querySelector('.text');
if (mainCheckbox.checked) {
if (countElement) {
countElement.innerHTML = String(checkboxes.length);
}
if (textElement) {
textElement.innerHTML = String('itens selecionados');
}
if (bar) {
bar.classList.add('show');
}
}
else {
if (countElement) {
countElement.innerHTML = String(0);
}
if (bar) {
bar.classList.remove('show');
}
}
checkboxes.forEach((checkbox) => {
if (checkbox instanceof HTMLInputElement) {
checkbox.checked = mainCheckbox.checked;
const tr = checkbox.closest('tr');
if (tr) {
tr.classList.toggle('is-selected', checkbox.checked);
}
}
});
if (this.selectLines.length > 0) {
this.selectLines = [];
}
this.lines.forEach((line) => {
if (mainCheckbox.checked) {
this.selectLines.push(line);
}
else {
const itemIndex = this.selectLines.indexOf(line);
this.selectLines.splice(itemIndex, 1);
}
});
console.log(this.selectLines);
}
selectCheckbox(line) {
const mainCheckbox = document.querySelector('.checked-all');
const bar = document.querySelector('.selected-bar');
if (bar) {
bar.classList.add('show');
}
mainCheckbox.checked = false;
const itemIndex = this.selectLines.indexOf(line);
if (itemIndex > -1) {
this.selectLines.splice(itemIndex, 1);
}
else {
this.selectLines.push(line);
}
this.selectedLines.emit(this.selectLines);
console.log(this.selectLines);
}
onSort(column) {
if (this.sortKey === column.key) {
this.sortDirection = this.sortDirection === 'asc' ? 'desc' : this.sortDirection === 'desc' ? '' : 'asc';
}
else {
this.sortKey = column.key;
this.sortDirection = 'asc';
}
this.sort.emit({ key: column.key, direction: this.sortDirection });
}
getTemplate(key) {
const template = this.allTemplates.find(t => t.key === key);
return template ? template.templateRef : null;
}
get disabledActions() {
const countElement = document.querySelector('.count');
const countValue = parseInt(countElement?.textContent || '0');
if (countValue >= 2) {
return true;
}
return false;
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableComponent, deps: [], target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "18.2.13", type: TableComponent, selector: "cfc-table", inputs: { columns: "columns", lines: "lines", customTable: "customTable", pagination: "pagination", hasCheckbox: "hasCheckbox", noItensMessage: "noItensMessage", sortable: "sortable", emptyMessageTitle: "emptyMessageTitle", emptyMessageDescription: "emptyMessageDescription", emptyMessageIcon: "emptyMessageIcon", templates: "templates" }, outputs: { selectedLines: "selectedLines", sort: "sort", onItensPerPageChange: "onItensPerPageChange", onPageChange: "onPageChange" }, queries: [{ propertyName: "internalTemplates", predicate: ColumnTemplateDirective, descendants: true }], ngImport: i0, template: "<div class=\"br-table\" data-selection=\"data-selection\">\r\n <div class=\"table-header\">\r\n <div class=\"selected-bar\">\r\n <div class=\"info\">\r\n <span class=\"count\">0</span><span class=\"text\">item selecionado</span>\r\n </div>\r\n </div>\r\n </div>\r\n <table>\r\n\r\n <thead>\r\n <tr>\r\n @if(hasCheckbox){\r\n <th class=\"column-checkbox\" scope=\"col\">\r\n <div class=\"br-checkbox hidden-label\">\r\n <input\r\n id=\"check-all-90050\"\r\n name=\"check-all-90050\"\r\n type=\"checkbox\"\r\n aria-label=\"Selecionar tudo\"\r\n data-parent=\"check-01-90050\"\r\n class=\"checked-all\"\r\n (change)=\"selectAllCheckbox()\"\r\n />\r\n <label for=\"check-all-90050\">Selecionar todas as linhas</label>\r\n </div>\r\n </th>\r\n } @for (column of columns; track $index) {\r\n\r\n <th\r\n scope=\"col\"\r\n (click)=\"sortable ? onSort(column) : null\"\r\n [className]=\"column.customCell ? 'sortable' : ''\"\r\n [style.width]=\"column.width\"\r\n >\r\n {{ column.label }}\r\n <span *ngIf=\"column.key === sortKey\">\r\n {{\r\n sortDirection === \"asc\"\r\n ? \"\u2191\"\r\n : sortDirection === \"desc\"\r\n ? \"\u2193\"\r\n : \"\"\r\n }}\r\n </span>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n @if (!!lines && lines.length > 0) {\r\n <tbody>\r\n @for (line of lines; track $index) {\r\n <tr>\r\n @if(hasCheckbox){\r\n <td>\r\n <div class=\"br-checkbox hidden-label\">\r\n <input\r\n [attr.id]=\"'check-line-' + $index + '-90050'\"\r\n [attr.name]=\"'check-line-' + $index + '-90050'\"\r\n type=\"checkbox\"\r\n [attr.aria-label]=\"'Selecionar linha' + $index\"\r\n data-child=\"check-01-90050\"\r\n class=\"checkbox-item\"\r\n (change)=\"selectCheckbox(line)\"\r\n />\r\n <label [attr.for]=\"'check-line-' + $index + '-90050'\"\r\n >Selecionar linha {{ $index }}</label\r\n >\r\n </div>\r\n </td>\r\n }\r\n\r\n @for (column of columns; track $index) {\r\n <td [attr.data-th]=\"column.label + $index\">\r\n\r\n @if(getTemplate(column.key)){\r\n <ng-container>\r\n <ng-template\r\n [ngTemplateOutlet]=\"getTemplate(column.key)\"\r\n [ngTemplateOutletContext]=\"{\r\n line: line,\r\n value: line[column.key],\r\n index: $index,\r\n column: column\r\n }\"\r\n />\r\n </ng-container>\r\n\r\n }\r\n @else if(column.customCell){\r\n<!-- MATEM COMPATIBILIDADE COM A PRIMEIRA VERSAO -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n customTable;\r\n context: {\r\n $implicit: line,\r\n item: line,\r\n column: column,\r\n urlActionBase: filteredModule?.urlBase,\r\n disabled: disabledActions\r\n }\r\n \"\r\n ></ng-container>\r\n\r\n } @else {\r\n <ng-container >\r\n {{ getNestedValue(line, column.key) }}\r\n </ng-container>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n } @if(!!lines && lines.length === 0 && !!noItensMessage) {\r\n <tr>\r\n <td [colSpan]=\"columns.length\">\r\n {{ noItensMessage }}\r\n </td>\r\n </tr>\r\n }\r\n </table>\r\n @if(!!lines && lines.length === 0) {\r\n <div class=\"empty-state\">\r\n <cfc-icon [iconName]=\"emptyMessageIcon\" size=\"60px\" class=\"mb-3\"></cfc-icon>\r\n <p class=\"text-base text-weight-semi-bold mb-baseh\">{{ emptyMessageTitle }}</p>\r\n <p class=\"m-0\">{{ emptyMessageDescription }}</p>\r\n </div>\r\n }\r\n\r\n</div>\r\n\r\n", styles: [".message{display:flex;flex-direction:column;justify-content:center;align-items:center}.message i{font-size:32px}thead th{background-color:#f0f0f0!important;color:#1351b4;width:auto}thead th[scope=col]{cursor:default}thead th.sortable[scope=col],tbody tr{cursor:pointer}.row-selected{background-color:#1351b4}.row-selected td{color:#fff}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:48px}.br-table table{width:100%;table-layout:auto}.br-table th,.br-table td{width:auto;white-space:nowrap}.br-table th[style*=width],.br-table td[style*=width]{white-space:normal}\n"], dependencies: [{ kind: "directive", type: i1.NgIf, selector: "[ngIf]", inputs: ["ngIf", "ngIfThen", "ngIfElse"] }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "component", type: i2.IconComponent, selector: "cfc-icon", inputs: ["iconName", "familyName", "className", "size", "color"] }] });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: TableComponent, decorators: [{
type: Component,
args: [{ selector: 'cfc-table', template: "<div class=\"br-table\" data-selection=\"data-selection\">\r\n <div class=\"table-header\">\r\n <div class=\"selected-bar\">\r\n <div class=\"info\">\r\n <span class=\"count\">0</span><span class=\"text\">item selecionado</span>\r\n </div>\r\n </div>\r\n </div>\r\n <table>\r\n\r\n <thead>\r\n <tr>\r\n @if(hasCheckbox){\r\n <th class=\"column-checkbox\" scope=\"col\">\r\n <div class=\"br-checkbox hidden-label\">\r\n <input\r\n id=\"check-all-90050\"\r\n name=\"check-all-90050\"\r\n type=\"checkbox\"\r\n aria-label=\"Selecionar tudo\"\r\n data-parent=\"check-01-90050\"\r\n class=\"checked-all\"\r\n (change)=\"selectAllCheckbox()\"\r\n />\r\n <label for=\"check-all-90050\">Selecionar todas as linhas</label>\r\n </div>\r\n </th>\r\n } @for (column of columns; track $index) {\r\n\r\n <th\r\n scope=\"col\"\r\n (click)=\"sortable ? onSort(column) : null\"\r\n [className]=\"column.customCell ? 'sortable' : ''\"\r\n [style.width]=\"column.width\"\r\n >\r\n {{ column.label }}\r\n <span *ngIf=\"column.key === sortKey\">\r\n {{\r\n sortDirection === \"asc\"\r\n ? \"\u2191\"\r\n : sortDirection === \"desc\"\r\n ? \"\u2193\"\r\n : \"\"\r\n }}\r\n </span>\r\n </th>\r\n }\r\n </tr>\r\n </thead>\r\n @if (!!lines && lines.length > 0) {\r\n <tbody>\r\n @for (line of lines; track $index) {\r\n <tr>\r\n @if(hasCheckbox){\r\n <td>\r\n <div class=\"br-checkbox hidden-label\">\r\n <input\r\n [attr.id]=\"'check-line-' + $index + '-90050'\"\r\n [attr.name]=\"'check-line-' + $index + '-90050'\"\r\n type=\"checkbox\"\r\n [attr.aria-label]=\"'Selecionar linha' + $index\"\r\n data-child=\"check-01-90050\"\r\n class=\"checkbox-item\"\r\n (change)=\"selectCheckbox(line)\"\r\n />\r\n <label [attr.for]=\"'check-line-' + $index + '-90050'\"\r\n >Selecionar linha {{ $index }}</label\r\n >\r\n </div>\r\n </td>\r\n }\r\n\r\n @for (column of columns; track $index) {\r\n <td [attr.data-th]=\"column.label + $index\">\r\n\r\n @if(getTemplate(column.key)){\r\n <ng-container>\r\n <ng-template\r\n [ngTemplateOutlet]=\"getTemplate(column.key)\"\r\n [ngTemplateOutletContext]=\"{\r\n line: line,\r\n value: line[column.key],\r\n index: $index,\r\n column: column\r\n }\"\r\n />\r\n </ng-container>\r\n\r\n }\r\n @else if(column.customCell){\r\n<!-- MATEM COMPATIBILIDADE COM A PRIMEIRA VERSAO -->\r\n <ng-container\r\n *ngTemplateOutlet=\"\r\n customTable;\r\n context: {\r\n $implicit: line,\r\n item: line,\r\n column: column,\r\n urlActionBase: filteredModule?.urlBase,\r\n disabled: disabledActions\r\n }\r\n \"\r\n ></ng-container>\r\n\r\n } @else {\r\n <ng-container >\r\n {{ getNestedValue(line, column.key) }}\r\n </ng-container>\r\n }\r\n </td>\r\n }\r\n </tr>\r\n }\r\n </tbody>\r\n } @if(!!lines && lines.length === 0 && !!noItensMessage) {\r\n <tr>\r\n <td [colSpan]=\"columns.length\">\r\n {{ noItensMessage }}\r\n </td>\r\n </tr>\r\n }\r\n </table>\r\n @if(!!lines && lines.length === 0) {\r\n <div class=\"empty-state\">\r\n <cfc-icon [iconName]=\"emptyMessageIcon\" size=\"60px\" class=\"mb-3\"></cfc-icon>\r\n <p class=\"text-base text-weight-semi-bold mb-baseh\">{{ emptyMessageTitle }}</p>\r\n <p class=\"m-0\">{{ emptyMessageDescription }}</p>\r\n </div>\r\n }\r\n\r\n</div>\r\n\r\n", styles: [".message{display:flex;flex-direction:column;justify-content:center;align-items:center}.message i{font-size:32px}thead th{background-color:#f0f0f0!important;color:#1351b4;width:auto}thead th[scope=col]{cursor:default}thead th.sortable[scope=col],tbody tr{cursor:pointer}.row-selected{background-color:#1351b4}.row-selected td{color:#fff}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding-top:48px}.br-table table{width:100%;table-layout:auto}.br-table th,.br-table td{width:auto;white-space:nowrap}.br-table th[style*=width],.br-table td[style*=width]{white-space:normal}\n"] }]
}], propDecorators: { columns: [{
type: Input
}], lines: [{
type: Input
}], customTable: [{
type: Input
}], pagination: [{
type: Input
}], hasCheckbox: [{
type: Input
}], noItensMessage: [{
type: Input
}], sortable: [{
type: Input
}], emptyMessageTitle: [{
type: Input
}], emptyMessageDescription: [{
type: Input
}], emptyMessageIcon: [{
type: Input
}], selectedLines: [{
type: Output
}], sort: [{
type: Output
}], onItensPerPageChange: [{
type: Output
}], onPageChange: [{
type: Output
}], templates: [{
type: Input
}], internalTemplates: [{
type: ContentChildren,
args: [ColumnTemplateDirective, { descendants: true }]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vcHJvamVjdHMvY2ZjLWRzL3NyYy9saWIvY29tcG9uZW50cy90YWJsZS90YWJsZS5jb21wb25lbnQudHMiLCIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9jZmMtZHMvc3JjL2xpYi9jb21wb25lbnRzL3RhYmxlL3RhYmxlLmNvbXBvbmVudC5odG1sIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sRUFFTCxTQUFTLEVBQ1QsWUFBWSxFQUNaLEtBQUssRUFFTCxNQUFNLEVBR04sZUFBZSxHQUNoQixNQUFNLGVBQWUsQ0FBQztBQUd2QixPQUFPLEVBQUUsdUJBQXVCLEVBQUUsTUFBTSw0Q0FBNEMsQ0FBQzs7OztBQUdyRixNQUFNLE9BQU8sU0FBUztJQUNwQixHQUFHLENBQVU7SUFDYixTQUFTLENBQXVCO0NBQ2pDO0FBRUQsTUFBTSxPQUFPLFlBQVk7SUFDdkIsR0FBRyxDQUFTO0lBQ1osS0FBSyxDQUFTO0lBQ2QsS0FBSyxDQUFTO0lBQ2QsUUFBUSxHQUFZLEtBQUssQ0FBQztJQUMxQixVQUFVLEdBQVksS0FBSyxDQUFDO0lBQzVCLEtBQUssQ0FBVTtJQUVmLFlBQVksR0FBVyxFQUFFLEtBQWE7UUFDcEMsSUFBSSxDQUFDLEdBQUcsR0FBRyxHQUFHLENBQUM7UUFDZixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNuQixJQUFJLENBQUMsS0FBSyxHQUFHLEdBQUcsQ0FBQztJQUNuQixDQUFDO0lBRUQsTUFBTSxDQUFDLFNBQVMsQ0FBQyxLQUE2RDtRQUM1RSxPQUFPLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUUsQ0FBQyxJQUFJLFlBQVksQ0FBQyxJQUFJLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDLENBQUM7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SUFvSUE7OzRGRG5EYSxjQUFjO2tCQUwxQixTQUFTOytCQUNFLFdBQVc7OEJBS1osT0FBTztzQkFBZixLQUFLO2dCQUNHLEtBQUs7c0JBQWIsS0FBSztnQkFDRyxXQUFXO3NCQUFuQixLQUFLO2dCQUNHLFVBQVU7c0JBQWxCLEtBQUs7Z0JBQ0csV0FBVztzQkFBbkIsS0FBSztnQkFDRyxjQUFjO3NCQUF0QixLQUFLO2dCQUNHLFFBQVE7c0JBQWhCLEtBQUs7Z0JBQ0csaUJBQWlCO3NCQUF6QixLQUFLO2dCQUNHLHVCQUF1QjtzQkFBL0IsS0FBSztnQkFDRyxnQkFBZ0I7c0JBQXhCLEtBQUs7Z0JBQ0ksYUFBYTtzQkFBdEIsTUFBTTtnQkFPRyxJQUFJO3NCQUFiLE1BQU07Z0JBS0csb0JBQW9CO3NCQUE3QixNQUFNO2dCQUNHLFlBQVk7c0JBQXJCLE1BQU07Z0JBRUUsU0FBUztzQkFBakIsS0FBSztnQkFJTixpQkFBaUI7c0JBRGhCLGVBQWU7dUJBQUMsdUJBQXVCLEVBQUUsRUFBRSxXQUFXLEVBQUUsSUFBSSxFQUFFIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBBZnRlclZpZXdJbml0LFxyXG4gIENvbXBvbmVudCxcclxuICBFdmVudEVtaXR0ZXIsXHJcbiAgSW5wdXQsXHJcbiAgT25Jbml0LFxyXG4gIE91dHB1dCxcclxuICBUZW1wbGF0ZVJlZixcclxuICBRdWVyeUxpc3QsXHJcbiAgQ29udGVudENoaWxkcmVuLFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBSb3V0ZXIgfSBmcm9tICdAYW5ndWxhci9yb3V0ZXInO1xyXG5pbXBvcnQgeyBDb2x1bW5zIH0gZnJvbSAnLi4vLi4vbW9kZWxzL3RhYmxlLm1vZGVsJztcclxuaW1wb3J0IHsgQ29sdW1uVGVtcGxhdGVEaXJlY3RpdmUgfSBmcm9tICcuLi8uLi9kaXJlY3RpdmVzL2NvbHVtbi10ZW1wbGF0ZS5kaXJlY3RpdmUnO1xyXG5cclxuXHJcbmV4cG9ydCBjbGFzcyBTb3J0RXZlbnQge1xyXG4gIGtleSE6IHN0cmluZztcclxuICBkaXJlY3Rpb24hOiAnJyB8ICdhc2MnIHwgJ2Rlc2MnO1xyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgU2ltcGxlQ29sdW1uIHtcclxuICBrZXk6IHN0cmluZztcclxuICBmaWVsZDogc3RyaW5nO1xyXG4gIGxhYmVsOiBzdHJpbmc7XHJcbiAgc29ydGFibGU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBjdXN0b21DZWxsOiBib29sZWFuID0gZmFsc2U7XHJcbiAgd2lkdGg/OiBzdHJpbmc7XHJcblxyXG4gIGNvbnN0cnVjdG9yKGtleTogc3RyaW5nLCBsYWJlbDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLmtleSA9IGtleTtcclxuICAgIHRoaXMubGFiZWwgPSBsYWJlbDtcclxuICAgIHRoaXMuZmllbGQgPSBrZXk7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgZnJvbUFycmF5KGFycmF5OiB7IGtleTogc3RyaW5nLCBsYWJlbDogc3RyaW5nLCBjdXN0b21DZWxsPzogYm9vbGVhbiB9W10pOiBTaW1wbGVDb2x1bW5bXSB7XHJcbiAgICByZXR1cm4gYXJyYXkubWFwKGl0ZW0gPT4gbmV3IFNpbXBsZUNvbHVtbihpdGVtLmtleSwgaXRlbS5sYWJlbCkud2l0aEN1c3RvbUNlbGwoaXRlbS5jdXN0b21DZWxsKSk7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgY29sdW1uKGtleTogc3RyaW5nLCBsYWJlbDogc3RyaW5nKTogU2ltcGxlQ29sdW1uIHtcclxuICAgIHJldHVybiBuZXcgU2ltcGxlQ29sdW1uKGtleSwgbGFiZWwpO1xyXG4gIH1cclxuXHJcbiAgc3RhdGljIGN1c3RvbShrZXk6IHN0cmluZywgbGFiZWw6IHN0cmluZyk6IFNpbXBsZUNvbHVtbiB7XHJcbiAgICByZXR1cm4gbmV3IFNpbXBsZUNvbHVtbihrZXksIGxhYmVsKS53aXRoQ3VzdG9tQ2VsbCh0cnVlKTtcclxuICB9XHJcblxyXG4gIHN0YXRpYyBzb3J0YWJsZShrZXk6IHN0cmluZywgbGFiZWw6IHN0cmluZywgZmllbGQ6IHN0cmluZyA9ICdpZCcpOiBTaW1wbGVDb2x1bW4ge1xyXG4gICAgcmV0dXJuIG5ldyBTaW1wbGVDb2x1bW4oa2V5LCBsYWJlbCkud2l0aFNvcnRhYmxlKHRydWUpLndpdGhGaWVsZChmaWVsZCk7XHJcbiAgfVxyXG5cclxuICBzdGF0aWMgYWN0aW9uKCk6IFNpbXBsZUNvbHVtbiB7XHJcbiAgICByZXR1cm4gbmV3IFNpbXBsZUNvbHVtbignYWN0aW9ucycsICdBw6fDtWVzJykud2l0aEN1c3RvbUNlbGwodHJ1ZSkud2l0aFNvcnRhYmxlKGZhbHNlKTtcclxuICB9XHJcblxyXG4gIHdpdGhGaWVsZChmaWVsZDogc3RyaW5nKTogU2ltcGxlQ29sdW1uIHtcclxuICAgIHRoaXMuZmllbGQgPSBmaWVsZDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgd2l0aFNvcnRhYmxlKHNvcnRhYmxlOiBib29sZWFuID0gZmFsc2UpOiBTaW1wbGVDb2x1bW4ge1xyXG4gICAgdGhpcy5zb3J0YWJsZSA9IHNvcnRhYmxlO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG5cclxuICB3aXRoQ3VzdG9tQ2VsbChjdXN0b21DZWxsOiBib29sZWFuID0gZmFsc2UpOiBTaW1wbGVDb2x1bW4ge1xyXG4gICAgdGhpcy5jdXN0b21DZWxsID0gY3VzdG9tQ2VsbDtcclxuICAgIHJldHVybiB0aGlzO1xyXG4gIH1cclxuXHJcbiAgd2l0aFdpZHRoKHdpZHRoOiBzdHJpbmcpOiBTaW1wbGVDb2x1bW4ge1xyXG4gICAgdGhpcy53aWR0aCA9IHdpZHRoO1xyXG4gICAgcmV0dXJuIHRoaXM7XHJcbiAgfVxyXG59XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ2NmYy10YWJsZScsXHJcbiAgdGVtcGxhdGVVcmw6ICcuL3RhYmxlLmNvbXBvbmVudC5odG1sJyxcclxuICBzdHlsZVVybDogJy4vdGFibGUuY29tcG9uZW50LnNjc3MnLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgVGFibGVDb21wb25lbnQgaW1wbGVtZW50cyBPbkluaXQsIEFmdGVyVmlld0luaXQge1xyXG4gIEBJbnB1dCgpIGNvbHVtbnMhOiBDb2x1bW5zW107XHJcbiAgQElucHV0KCkgbGluZXMhOiBhbnk7XHJcbiAgQElucHV0KCkgY3VzdG9tVGFibGUhOiBUZW1wbGF0ZVJlZjxhbnk+O1xyXG4gIEBJbnB1dCgpIHBhZ2luYXRpb246IGFueSA9IHsgdG90YWxFbGVtZW50czogMCB9O1xyXG4gIEBJbnB1dCgpIGhhc0NoZWNrYm94OiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgbm9JdGVuc01lc3NhZ2U6IHN0cmluZyA9ICcnO1xyXG4gIEBJbnB1dCgpIHNvcnRhYmxlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQElucHV0KCkgZW1wdHlNZXNzYWdlVGl0bGU6IHN0cmluZyA9ICdOZW5odW0gaXRlbSBlbmNvbnRyYWRvJztcclxuICBASW5wdXQoKSBlbXB0eU1lc3NhZ2VEZXNjcmlwdGlvbjogc3RyaW5nID0gJ07Do28gZm9pIHBvc3PDrXZlbCBlbmNvbnRyYXIgbmVuaHVtIGl0ZW0gY29tIG9zIGNyaXTDqXJpb3MgZGUgYnVzY2EgYXR1YWlzLic7XHJcbiAgQElucHV0KCkgZW1wdHlNZXNzYWdlSWNvbjogc3RyaW5nID0gJ2NsaXBib2FyZCc7XHJcbiAgQE91dHB1dCgpIHNlbGVjdGVkTGluZXMgPSBuZXcgRXZlbnRFbWl0dGVyKCk7XHJcblxyXG5cclxuICBsaXN0QWN0aW9ucyA9IFtdO1xyXG4gIHNlbGVjdExpbmVzOiBhbnlbXSA9IFtdO1xyXG4gIGZpbHRlcmVkTW9kdWxlOiBhbnk7XHJcblxyXG4gIEBPdXRwdXQoKSBzb3J0ID0gbmV3IEV2ZW50RW1pdHRlcjxTb3J0RXZlbnQ+KCk7XHJcblxyXG4gIHNvcnRLZXk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xyXG4gIHNvcnREaXJlY3Rpb246ICdhc2MnIHwgJ2Rlc2MnIHwgJycgPSAnYXNjJztcclxuXHJcbiAgQE91dHB1dCgpIG9uSXRlbnNQZXJQYWdlQ2hhbmdlID0gbmV3IEV2ZW50RW1pdHRlcjxudW1iZXI+KCk7XHJcbiAgQE91dHB1dCgpIG9uUGFnZUNoYW5nZSA9IG5ldyBFdmVudEVtaXR0ZXI8bnVtYmVyPigpO1xyXG5cclxuICBASW5wdXQoKSB0ZW1wbGF0ZXM/OiBRdWVyeUxpc3Q8Q29sdW1uVGVtcGxhdGVEaXJlY3RpdmU+O1xyXG5cclxuXHJcbiAgQENvbnRlbnRDaGlsZHJlbihDb2x1bW5UZW1wbGF0ZURpcmVjdGl2ZSwgeyBkZXNjZW5kYW50czogdHJ1ZSB9KVxyXG4gIGludGVybmFsVGVtcGxhdGVzITogUXVlcnlMaXN0PENvbHVtblRlbXBsYXRlRGlyZWN0aXZlPjtcclxuXHJcbiAgZ2V0IGFsbFRlbXBsYXRlcygpOiBDb2x1bW5UZW1wbGF0ZURpcmVjdGl2ZVtdIHtcclxuICAgIHJldHVybiBbLi4udGhpcy5pbnRlcm5hbFRlbXBsYXRlcywgLi4uKHRoaXMudGVtcGxhdGVzIHx8IFtdKV07XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpOiB2b2lkIHtcclxuICB9XHJcblxyXG4gIG5nQWZ0ZXJWaWV3SW5pdCgpOiB2b2lkIHtcclxuICAgIHRoaXMuaW5pdGlhbGl6ZVRhYmxlKCk7XHJcbiAgfVxyXG5cclxuICBpbml0aWFsaXplVGFibGUoKTogdm9pZCB7XHJcbiAgICBjb25zdCB0YWJsZUxpc3QgPSBbXTtcclxuICAgIGNvbnN0IHRhYmxlcyA9IEFycmF5LmZyb20od2luZG93LmRvY3VtZW50LnF1ZXJ5U2VsZWN0b3JBbGwoJy5ici10YWJsZScpKTtcclxuXHJcbiAgICBmb3IgKGNvbnN0IFtpbmRleCwgYnJUYWJsZV0gb2YgdGFibGVzLmVudHJpZXMoKSkge1xyXG4gICAgICB0YWJsZUxpc3QucHVzaChcclxuICAgICAgICBuZXcgKHdpbmRvdyBhcyBhbnkpLmNvcmUuQlJUYWJsZSgnYnItdGFibGUnLCBiclRhYmxlLCBpbmRleClcclxuICAgICAgKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIGdldE5lc3RlZFZhbHVlKG9iajogYW55LCBwYXRoOiBzdHJpbmcpOiBhbnkge1xyXG4gICAgcmV0dXJuIHBhdGguc3BsaXQoJy4nKS5yZWR1Y2UoKGFjYywgcGFydCkgPT4gYWNjICYmIGFjY1twYXJ0XSwgb2JqKTtcclxuICB9XHJcblxyXG5cclxuICBzZWxlY3RBbGxDaGVja2JveCgpIHtcclxuICAgIGNvbnN0IG1haW5DaGVja2JveCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoXHJcbiAgICAgICcuY2hlY2tlZC1hbGwnXHJcbiAgICApIGFzIEhUTUxJbnB1dEVsZW1lbnQ7XHJcbiAgICBjb25zdCBjaGVja2JveGVzID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvckFsbCgnLmNoZWNrYm94LWl0ZW0nKTtcclxuICAgIGNvbnN0IGJhciA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5zZWxlY3RlZC1iYXInKTtcclxuICAgIGNvbnN0IGNvdW50RWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IoJy5jb3VudCcpO1xyXG4gICAgY29uc3QgdGV4dEVsZW1lbnQgPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKCcudGV4dCcpO1xyXG4gICAgaWYgKG1haW5DaGVja2JveC5jaGVja2VkKSB7XHJcbiAgICAgIGlmIChjb3VudEVsZW1lbnQpIHtcclxuICAgICAgICBjb3VudEVsZW1lbnQuaW5uZXJIVE1MID0gU3RyaW5nKGNoZWNrYm94ZXMubGVuZ3RoKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAodGV4dEVsZW1lbnQpIHtcclxuICAgICAgICB0ZXh0RWxlbWVudC5pbm5lckhUTUwgPSBTdHJpbmcoJ2l0ZW5zIHNlbGVjaW9uYWRvcycpO1xyXG4gICAgICB9XHJcbiAgICAgIGlmIChiYXIpIHtcclxuICAgICAgICBiYXIuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBpZiAoY291bnRFbGVtZW50KSB7XHJcbiAgICAgICAgY291bnRFbGVtZW50LmlubmVySFRNTCA9IFN0cmluZygwKTtcclxuICAgICAgfVxyXG4gICAgICBpZiAoYmFyKSB7XHJcbiAgICAgICAgYmFyLmNsYXNzTGlzdC5yZW1vdmUoJ3Nob3cnKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNoZWNrYm94ZXMuZm9yRWFjaCgoY2hlY2tib3gpID0+IHtcclxuICAgICAgaWYgKGNoZWNrYm94IGluc3RhbmNlb2YgSFRNTElucHV0RWxlbWVudCkge1xyXG4gICAgICAgIGNoZWNrYm94LmNoZWNrZWQgPSBtYWluQ2hlY2tib3guY2hlY2tlZDtcclxuICAgICAgICBjb25zdCB0ciA9IGNoZWNrYm94LmNsb3Nlc3QoJ3RyJyk7XHJcbiAgICAgICAgaWYgKHRyKSB7XHJcbiAgICAgICAgICB0ci5jbGFzc0xpc3QudG9nZ2xlKCdpcy1zZWxlY3RlZCcsIGNoZWNrYm94LmNoZWNrZWQpO1xyXG4gICAgICAgIH1cclxuICAgICAgfVxyXG4gICAgfSk7XHJcblxyXG4gICAgaWYgKHRoaXMuc2VsZWN0TGluZXMubGVuZ3RoID4gMCkge1xyXG4gICAgICB0aGlzLnNlbGVjdExpbmVzID0gW107XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5saW5lcy5mb3JFYWNoKChsaW5lOiBhbnkpID0+IHtcclxuICAgICAgaWYgKG1haW5DaGVja2JveC5jaGVja2VkKSB7XHJcbiAgICAgICAgdGhpcy5zZWxlY3RMaW5lcy5wdXNoKGxpbmUpO1xyXG4gICAgICB9IGVsc2Uge1xyXG4gICAgICAgIGNvbnN0IGl0ZW1JbmRleCA9IHRoaXMuc2VsZWN0TGluZXMuaW5kZXhPZihsaW5lKTtcclxuICAgICAgICB0aGlzLnNlbGVjdExpbmVzLnNwbGljZShpdGVtSW5kZXgsIDEpO1xyXG4gICAgICB9XHJcbiAgICB9KTtcclxuICAgIGNvbnNvbGUubG9nKHRoaXMuc2VsZWN0TGluZXMpO1xyXG4gIH1cclxuXHJcbiAgc2VsZWN0Q2hlY2tib3gobGluZTogYW55KSB7XHJcbiAgICBjb25zdCBtYWluQ2hlY2tib3ggPSBkb2N1bWVudC5xdWVyeVNlbGVjdG9yKFxyXG4gICAgICAnLmNoZWNrZWQtYWxsJ1xyXG4gICAgKSBhcyBIVE1MSW5wdXRFbGVtZW50O1xyXG4gICAgY29uc3QgYmFyID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLnNlbGVjdGVkLWJhcicpO1xyXG4gICAgaWYgKGJhcikge1xyXG4gICAgICBiYXIuY2xhc3NMaXN0LmFkZCgnc2hvdycpO1xyXG4gICAgfVxyXG4gICAgbWFpbkNoZWNrYm94LmNoZWNrZWQgPSBmYWxzZTtcclxuICAgIGNvbnN0IGl0ZW1JbmRleCA9IHRoaXMuc2VsZWN0TGluZXMuaW5kZXhPZihsaW5lKTtcclxuICAgIGlmIChpdGVtSW5kZXggPiAtMSkge1xyXG4gICAgICB0aGlzLnNlbGVjdExpbmVzLnNwbGljZShpdGVtSW5kZXgsIDEpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgdGhpcy5zZWxlY3RMaW5lcy5wdXNoKGxpbmUpO1xyXG4gICAgfVxyXG4gICAgdGhpcy5zZWxlY3RlZExpbmVzLmVtaXQodGhpcy5zZWxlY3RMaW5lcyk7XHJcbiAgICBjb25zb2xlLmxvZyh0aGlzLnNlbGVjdExpbmVzKTtcclxuICB9XHJcblxyXG4gIG9uU29ydChjb2x1bW46IENvbHVtbnMpOiB2b2lkIHtcclxuICAgIGlmICh0aGlzLnNvcnRLZXkgPT09IGNvbHVtbi5rZXkpIHtcclxuICAgICAgdGhpcy5zb3J0RGlyZWN0aW9uID0gdGhpcy5zb3J0RGlyZWN0aW9uID09PSAnYXNjJyA/ICdkZXNjJyA6IHRoaXMuc29ydERpcmVjdGlvbiA9PT0gJ2Rlc2MnID8gJycgOiAnYXNjJztcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc29ydEtleSA9IGNvbHVtbi5rZXk7XHJcbiAgICAgIHRoaXMuc29ydERpcmVjdGlvbiA9ICdhc2MnO1xyXG4gICAgfVxyXG5cclxuICAgIHRoaXMuc29ydC5lbWl0KHsga2V5OiBjb2x1bW4ua2V5LCBkaXJlY3Rpb246IHRoaXMuc29ydERpcmVjdGlvbiB9KTtcclxuICB9XHJcblxyXG4gIGdldFRlbXBsYXRlKGtleTogc3RyaW5nKTogVGVtcGxhdGVSZWY8YW55PiB8IG51bGwge1xyXG4gICAgY29uc3QgdGVtcGxhdGUgPSB0aGlzLmFsbFRlbXBsYXRlcy5maW5kKHQgPT4gdC5rZXkgPT09IGtleSk7XHJcbiAgICByZXR1cm4gdGVtcGxhdGUgPyB0ZW1wbGF0ZS50ZW1wbGF0ZVJlZiA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXQgZGlzYWJsZWRBY3Rpb25zKCkge1xyXG4gICAgY29uc3QgY291bnRFbGVtZW50ID0gZG9jdW1lbnQucXVlcnlTZWxlY3RvcignLmNvdW50Jyk7XHJcbiAgICBjb25zdCBjb3VudFZhbHVlID0gcGFyc2VJbnQoY291bnRFbGVtZW50Py50ZXh0Q29udGVudCB8fCAnMCcpO1xyXG4gICAgaWYgKGNvdW50VmFsdWUgPj0gMikge1xyXG4gICAgICByZXR1cm4gdHJ1ZTtcclxuICAgIH1cclxuICAgIHJldHVybiBmYWxzZTtcclxuICB9XHJcbn1cclxuIiwiPGRpdiBjbGFzcz1cImJyLXRhYmxlXCIgZGF0YS1zZWxlY3Rpb249XCJkYXRhLXNlbGVjdGlvblwiPlxyXG4gIDxkaXYgY2xhc3M9XCJ0YWJsZS1oZWFkZXJcIj5cclxuICAgIDxkaXYgY2xhc3M9XCJzZWxlY3RlZC1iYXJcIj5cclxuICAgICAgPGRpdiBjbGFzcz1cImluZm9cIj5cclxuICAgICAgICA8c3BhbiBjbGFzcz1cImNvdW50XCI+MDwvc3Bhbj48c3BhbiBjbGFzcz1cInRleHRcIj5pdGVtIHNlbGVjaW9uYWRvPC9zcGFuPlxyXG4gICAgICA8L2Rpdj5cclxuICAgIDwvZGl2PlxyXG4gIDwvZGl2PlxyXG4gIDx0YWJsZT5cclxuXHJcbiAgICA8dGhlYWQ+XHJcbiAgICAgIDx0cj5cclxuICAgICAgICBAaWYoaGFzQ2hlY2tib3gpe1xyXG4gICAgICAgIDx0aCBjbGFzcz1cImNvbHVtbi1jaGVja2JveFwiIHNjb3BlPVwiY29sXCI+XHJcbiAgICAgICAgICA8ZGl2IGNsYXNzPVwiYnItY2hlY2tib3ggaGlkZGVuLWxhYmVsXCI+XHJcbiAgICAgICAgICAgIDxpbnB1dFxyXG4gICAgICAgICAgICAgIGlkPVwiY2hlY2stYWxsLTkwMDUwXCJcclxuICAgICAgICAgICAgICBuYW1lPVwiY2hlY2stYWxsLTkwMDUwXCJcclxuICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxyXG4gICAgICAgICAgICAgIGFyaWEtbGFiZWw9XCJTZWxlY2lvbmFyIHR1ZG9cIlxyXG4gICAgICAgICAgICAgIGRhdGEtcGFyZW50PVwiY2hlY2stMDEtOTAwNTBcIlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiY2hlY2tlZC1hbGxcIlxyXG4gICAgICAgICAgICAgIChjaGFuZ2UpPVwic2VsZWN0QWxsQ2hlY2tib3goKVwiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDxsYWJlbCBmb3I9XCJjaGVjay1hbGwtOTAwNTBcIj5TZWxlY2lvbmFyIHRvZGFzIGFzIGxpbmhhczwvbGFiZWw+XHJcbiAgICAgICAgICA8L2Rpdj5cclxuICAgICAgICA8L3RoPlxyXG4gICAgICAgIH0gQGZvciAoY29sdW1uIG9mIGNvbHVtbnM7IHRyYWNrICRpbmRleCkge1xyXG5cclxuICAgICAgICA8dGhcclxuICAgICAgICAgIHNjb3BlPVwiY29sXCJcclxuICAgICAgICAgIChjbGljayk9XCJzb3J0YWJsZSA/IG9uU29ydChjb2x1bW4pIDogbnVsbFwiXHJcbiAgICAgICAgICBbY2xhc3NOYW1lXT1cImNvbHVtbi5jdXN0b21DZWxsID8gJ3NvcnRhYmxlJyA6ICcnXCJcclxuICAgICAgICAgIFtzdHlsZS53aWR0aF09XCJjb2x1bW4ud2lkdGhcIlxyXG4gICAgICAgID5cclxuICAgICAgICAgIHt7IGNvbHVtbi5sYWJlbCB9fVxyXG4gICAgICAgICAgPHNwYW4gKm5nSWY9XCJjb2x1bW4ua2V5ID09PSBzb3J0S2V5XCI+XHJcbiAgICAgICAgICAgIHt7XHJcbiAgICAgICAgICAgICAgc29ydERpcmVjdGlvbiA9PT0gXCJhc2NcIlxyXG4gICAgICAgICAgICAgICAgPyBcIuKGkVwiXHJcbiAgICAgICAgICAgICAgICA6IHNvcnREaXJlY3Rpb24gPT09IFwiZGVzY1wiXHJcbiAgICAgICAgICAgICAgICA/IFwi4oaTXCJcclxuICAgICAgICAgICAgICAgIDogXCJcIlxyXG4gICAgICAgICAgICB9fVxyXG4gICAgICAgICAgPC9zcGFuPlxyXG4gICAgICAgIDwvdGg+XHJcbiAgICAgICAgfVxyXG4gICAgICA8L3RyPlxyXG4gICAgPC90aGVhZD5cclxuICAgICBAaWYgKCEhbGluZXMgJiYgbGluZXMubGVuZ3RoID4gMCkge1xyXG4gICAgPHRib2R5PlxyXG4gICAgICBAZm9yIChsaW5lIG9mIGxpbmVzOyB0cmFjayAkaW5kZXgpIHtcclxuICAgICAgPHRyPlxyXG4gICAgICAgIEBpZihoYXNDaGVja2JveCl7XHJcbiAgICAgICAgPHRkPlxyXG4gICAgICAgICAgPGRpdiBjbGFzcz1cImJyLWNoZWNrYm94IGhpZGRlbi1sYWJlbFwiPlxyXG4gICAgICAgICAgICA8aW5wdXRcclxuICAgICAgICAgICAgICBbYXR0ci5pZF09XCInY2hlY2stbGluZS0nICsgJGluZGV4ICsgJy05MDA1MCdcIlxyXG4gICAgICAgICAgICAgIFthdHRyLm5hbWVdPVwiJ2NoZWNrLWxpbmUtJyArICRpbmRleCArICctOTAwNTAnXCJcclxuICAgICAgICAgICAgICB0eXBlPVwiY2hlY2tib3hcIlxyXG4gICAgICAgICAgICAgIFthdHRyLmFyaWEtbGFiZWxdPVwiJ1NlbGVjaW9uYXIgbGluaGEnICsgJGluZGV4XCJcclxuICAgICAgICAgICAgICBkYXRhLWNoaWxkPVwiY2hlY2stMDEtOTAwNTBcIlxyXG4gICAgICAgICAgICAgIGNsYXNzPVwiY2hlY2tib3gtaXRlbVwiXHJcbiAgICAgICAgICAgICAgKGNoYW5nZSk9XCJzZWxlY3RDaGVja2JveChsaW5lKVwiXHJcbiAgICAgICAgICAgIC8+XHJcbiAgICAgICAgICAgIDxsYWJlbCBbYXR0ci5mb3JdPVwiJ2NoZWNrLWxpbmUtJyArICRpbmRleCArICctOTAwNTAnXCJcclxuICAgICAgICAgICAgICA+U2VsZWNpb25hciBsaW5oYSB7eyAkaW5kZXggfX08L2xhYmVsXHJcbiAgICAgICAgICAgID5cclxuICAgICAgICAgIDwvZGl2PlxyXG4gICAgICAgIDwvdGQ+XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICBAZm9yIChjb2x1bW4gb2YgY29sdW1uczsgdHJhY2sgJGluZGV4KSB7XHJcbiAgICAgICAgPHRkIFthdHRyLmRhdGEtdGhdPVwiY29sdW1uLmxhYmVsICsgJGluZGV4XCI+XHJcblxyXG4gICAgICAgICAgQGlmKGdldFRlbXBsYXRlKGNvbHVtbi5rZXkpKXtcclxuICAgICAgICAgICAgPG5nLWNvbnRhaW5lcj5cclxuICAgICAgICAgICAgICA8bmctdGVtcGxhdGVcclxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0XT1cImdldFRlbXBsYXRlKGNvbHVtbi5rZXkpXCJcclxuICAgICAgICAgICAgICAgIFtuZ1RlbXBsYXRlT3V0bGV0Q29udGV4dF09XCJ7XHJcbiAgICAgICAgICAgICAgICAgIGxpbmU6IGxpbmUsXHJcbiAgICAgICAgICAgICAgICAgIHZhbHVlOiBsaW5lW2NvbHVtbi5rZXldLFxyXG4gICAgICAgICAgICAgICAgICBpbmRleDogJGluZGV4LFxyXG4gICAgICAgICAgICAgICAgICBjb2x1bW46IGNvbHVtblxyXG4gICAgICAgICAgICAgICAgfVwiXHJcbiAgICAgICAgICAgICAgLz5cclxuICAgICAgICAgICAgPC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgfVxyXG4gICAgICAgICAgQGVsc2UgaWYoY29sdW1uLmN1c3RvbUNlbGwpe1xyXG48IS0tIE1BVEVNIENPTVBBVElCSUxJREFERSBDT00gQSBQUklNRUlSQSBWRVJTQU8gLS0+XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXJcclxuICAgICAgICAgICAgKm5nVGVtcGxhdGVPdXRsZXQ9XCJcclxuICAgICAgICAgICAgICBjdXN0b21UYWJsZTtcclxuICAgICAgICAgICAgICBjb250ZXh0OiB7XHJcbiAgICAgICAgICAgICAgICAkaW1wbGljaXQ6IGxpbmUsXHJcbiAgICAgICAgICAgICAgICBpdGVtOiBsaW5lLFxyXG4gICAgICAgICAgICAgICAgY29sdW1uOiBjb2x1bW4sXHJcbiAgICAgICAgICAgICAgICB1cmxBY3Rpb25CYXNlOiBmaWx0ZXJlZE1vZHVsZT8udXJsQmFzZSxcclxuICAgICAgICAgICAgICAgIGRpc2FibGVkOiBkaXNhYmxlZEFjdGlvbnNcclxuICAgICAgICAgICAgICB9XHJcbiAgICAgICAgICAgIFwiXHJcbiAgICAgICAgICA+PC9uZy1jb250YWluZXI+XHJcblxyXG4gICAgICAgICAgfSBAZWxzZSB7XHJcbiAgICAgICAgICAgIDxuZy1jb250YWluZXIgPlxyXG4gICAgICAgICAgICAgIHt7IGdldE5lc3RlZFZhbHVlKGxpbmUsIGNvbHVtbi5rZXkpIH19XHJcbiAgICAgICAgICAgIDwvbmctY29udGFpbmVyPlxyXG4gICAgICAgICAgfVxyXG4gICAgICAgIDwvdGQ+XHJcbiAgICAgICAgfVxyXG4gICAgICA8L3RyPlxyXG4gICAgICB9XHJcbiAgICA8L3Rib2R5PlxyXG4gICAgfSBAaWYoISFsaW5lcyAmJiBsaW5lcy5sZW5ndGggPT09IDAgJiYgISFub0l0ZW5zTWVzc2FnZSkge1xyXG4gICAgPHRyPlxyXG4gICAgICA8dGQgW2NvbFNwYW5dPVwiY29sdW1ucy5sZW5ndGhcIj5cclxuICAgICAgICB7eyBub0l0ZW5zTWVzc2FnZSB9fVxyXG4gICAgICA8L3RkPlxyXG4gICAgPC90cj5cclxuICAgIH1cclxuICA8L3RhYmxlPlxyXG4gIEBpZighIWxpbmVzICYmIGxpbmVzLmxlbmd0aCA9PT0gMCkge1xyXG4gICA8ZGl2IGNsYXNzPVwiZW1wdHktc3RhdGVcIj5cclxuICAgPGNmYy1pY29uIFtpY29uTmFtZV09XCJlbXB0eU1lc3NhZ2VJY29uXCIgc2l6ZT1cIjYwcHhcIiBjbGFzcz1cIm1iLTNcIj48L2NmYy1pY29uPlxyXG4gICA8cCBjbGFzcz1cInRleHQtYmFzZSB0ZXh0LXdlaWdodC1zZW1pLWJvbGQgbWItYmFzZWhcIj57eyBlbXB0eU1lc3NhZ2VUaXRsZSB9fTwvcD5cclxuICAgPHAgY2xhc3M9XCJtLTBcIj57eyBlbXB0eU1lc3NhZ2VEZXNjcmlwdGlvbiB9fTwvcD5cclxuICAgPC9kaXY+XHJcbiAgfVxyXG5cclxuPC9kaXY+XHJcblxyXG4iXX0=