@hpe/angular-toolkit
Version:
Hewlett-Packard Enterprise : Angular toolkit for rapid project development
601 lines (590 loc) • 61.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes} checked by tsc
*/
//=============================================================================
//===
//=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.
//===
//=== Use of this source code is governed by an MIT-style license that can be
//=== found in the LICENSE file
//=============================================================================
import { Component, EventEmitter, Input, Output, ViewChild } from '@angular/core';
import { ContextMenu, DataTable } from "primeng/primeng";
import { FilterChangeEvent } from "@hpe/angular-toolkit/model";
import { RowSelectedEvent } from "@hpe/angular-toolkit/model";
import { RowUnselectedEvent } from "@hpe/angular-toolkit/model";
import { MenuSelectionMode } from "@hpe/angular-toolkit/model";
import { Lib } from "@hpe/angular-toolkit/lib";
import { AbstractSubscriber } from "@hpe/angular-toolkit/service";
import { EventBusService } from "@hpe/angular-toolkit/service";
import { LabelService } from "@hpe/angular-toolkit/service";
//=============================================================================
export class ListTable extends AbstractSubscriber {
/**
* @param {?} eventBusService
* @param {?} labelService
*/
constructor(eventBusService, labelService) {
super(eventBusService);
this.labelService = labelService;
//-------------------------------------------------------------------------
this.onFilterChange = new EventEmitter();
this.onRowSelected = new EventEmitter();
this.onRowUnselected = new EventEmitter();
this.alignMap = {
'left': 'alignLeft',
'center': 'alignCenter',
'right': 'alignRight'
};
this.rowsPerPage = 8;
this.rowSet = [4, 8, 12, 16, 20, 50];
this.loading = false;
this.multiSelection = false;
}
/**
* @return {?}
*/
exportAll() {
this.pTable.exportCSV();
}
/**
* @return {?}
*/
exportSelected() {
this.pTable.exportCSV({ selectionOnly: true });
}
/**
* @return {?}
*/
get allValue() {
return this.labelService.getLabel("list-table", "all");
}
/**
* @return {?}
*/
get noRecords() {
return this.labelService.getLabel("list-table", "noRecords");
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
let /** @type {?} */ rebuildColumnValues = false;
if (changes["columns"]) {
this.initColumns();
rebuildColumnValues = true;
}
if (changes["data"]) {
this.initData();
rebuildColumnValues = true;
}
if (changes["visibleColumns"]) {
this.initVisibleColumns();
}
if (rebuildColumnValues) {
this.initColumnValues();
}
// "labels" ???
}
/**
* @param {?} event
* @return {?}
*/
onRowSelect(event) {
//--- In case of multi-selection, the selectedRow variable is an array of rows
let /** @type {?} */ row = this.restoreRow(event.data);
let /** @type {?} */ rows = this.calcSelectedRows(this.selectedRow);
this.onRowSelected.emit(new RowSelectedEvent(row, rows));
}
/**
* @param {?} event
* @return {?}
*/
onRowUnselect(event) {
//--- In case of multi-selection, the selectedRow variable is an array of rows
let /** @type {?} */ row = this.restoreRow(event.data);
let /** @type {?} */ rows = this.calcSelectedRows(this.selectedRow);
this.onRowUnselected.emit(new RowUnselectedEvent(row, rows));
}
/**
* @param {?} event
* @return {?}
*/
onContextMenuSelect(event) {
//--- In case of multi-selection, the selectedRow variable is an array of rows
let /** @type {?} */ row = this.restoreRow(event.data);
let /** @type {?} */ rows = this.calcSelectedRows(this.selectedRow);
let /** @type {?} */ rse = new RowSelectedEvent(row, rows);
//--- Emit event
this.onRowSelected.emit(rse);
//--- Setup context menu
this.activeMenu = this.selectMenuItems(this.contextMenu, rse, null);
}
/**
* @param {?} event
* @return {?}
*/
onFilter(event) {
this.onFilterChange.emit(new FilterChangeEvent(this.getFilteredSize()));
}
/**
* @param {?} value
* @param {?} col
* @return {?}
*/
filter(value, col) {
this.pTable.filter(value, col.field, col.filterMatchMode);
}
/**
* @return {?}
*/
initColumns() {
console.log("Initializing columns : " + JSON.stringify(this.columns));
this.colToIndex = new Map();
if (this.columns == null) {
//--- Do nothing for now
}
else {
let /** @type {?} */ index = 0;
this.columns.forEach((col) => {
this.colToIndex.set(col.field, index++);
col.displayHeader = this.calcHeader(col);
col.filterMatchMode = this.calcFilterMatchMode(col);
});
}
}
/**
* @param {?} col
* @return {?}
*/
calcHeader(col) {
return col.header
|| (this.labelGroup && this.labelService.getLabel(this.labelGroup, col.field))
|| col.field;
}
/**
* @param {?} col
* @return {?}
*/
calcFilterMatchMode(col) {
if (col.filter == null) {
return "contains";
}
if (col.filter == "select") {
return "equals";
}
if (col.filter == "list") {
return "in";
}
return null;
}
/**
* @return {?}
*/
initData() {
console.log("Initializing data : " + JSON.stringify(this.data));
if (this.columns == null || this.data == null) {
this.displayData = null;
}
else {
this.displayData = [];
this.data.forEach((row) => {
let /** @type {?} */ displayRow = {};
this.displayData.push(displayRow);
for (let /** @type {?} */ key in row) {
let /** @type {?} */ cell = new ListTableCell();
displayRow[key] = cell;
let /** @type {?} */ value = row[key];
let /** @type {?} */ colNdx = this.colToIndex.get(key);
let /** @type {?} */ col = this.columns[colNdx];
cell.originalValue = value;
cell.displayValue = this.calcDisplayValue(row, col, value);
cell.style = this.calcDisplayStyle(row, col, value);
}
});
}
}
/**
* @param {?} row
* @param {?} col
* @param {?} value
* @return {?}
*/
calcDisplayValue(row, col, value) {
if (col.transcoder != null) {
value = col.transcoder.transcode(value);
}
return (value != null)
? value.toString()
: null;
}
/**
* @param {?} row
* @param {?} col
* @param {?} value
* @return {?}
*/
calcDisplayStyle(row, col, value) {
let /** @type {?} */ styles = ['cell'];
if (col.alignment != null) {
styles.push(this.alignMap[col.alignment]);
}
if (col.styler != null) {
let /** @type {?} */ style = col.styler.style(value, row);
if (style.icon != null) {
styles.push("fa");
styles.push(style.icon);
}
if (style.extraClass != null) {
styles.push(style.extraClass);
}
}
return styles;
}
/**
* @return {?}
*/
initVisibleColumns() {
console.log("Initializing visible columns : " + JSON.stringify(this.visibleColumns));
if (this.columns == null || this.visibleColumns == null) {
this.displayColumns = null;
}
else {
this.displayColumns = [];
this.visibleColumns.forEach((name) => {
let /** @type {?} */ index = this.colToIndex.get(name);
if (index != null) {
this.displayColumns.push(this.columns[index]);
}
});
}
}
/**
* @return {?}
*/
initColumnValues() {
this.columnValues = new Map();
//--- exit if we still do not have columns or values
if (this.columns == null || this.data == null) {
return null;
}
console.log("Calculating column values for : ");
this.columns.forEach((col) => {
console.log(" --> " + col.field);
this.columnValues.set(col.field, this.getColumnValues(col));
});
}
/**
* @param {?} col
* @return {?}
*/
getColumnValues(col) {
let /** @type {?} */ field = col.field;
let /** @type {?} */ values = new Set();
//--- first, collect distinct values
this.data.forEach(row => {
let /** @type {?} */ value = row[field];
//--- null values causes issues with filters
if (value != null) {
values.add(value);
}
});
//--- second, build final list as an array of (value, label) entries
let /** @type {?} */ list = [];
//--- only the dropdown filter needs the "All" option
if (col.filter == "select") {
list.push({
label: this.allValue,
value: null
});
}
values.forEach((value) => {
if (col.transcoder != null) {
value = col.transcoder.transcode(value);
}
let /** @type {?} */ label = (value != null)
? value.toString()
: null;
list.push({
label: label,
value: label
});
});
return list;
}
/**
* @return {?}
*/
getFilteredSize() {
if (this.pTable) {
if (this.pTable.filteredValue) {
return this.pTable.filteredValue.length;
}
}
if (this.data) {
return this.data.length;
}
return null;
}
/**
* @param {?} data
* @return {?}
*/
restoreRow(data) {
let /** @type {?} */ row = {};
for (let /** @type {?} */ key in data) {
row[key] = data[key].originalValue;
}
return row;
}
/**
* @param {?} rows
* @return {?}
*/
calcSelectedRows(rows) {
let /** @type {?} */ result = [];
if (rows != null) {
rows.forEach((row) => {
result.push(this.restoreRow(row));
});
}
return result;
}
/**
* @param {?} menu
* @param {?} rse
* @param {?} parentId
* @return {?}
*/
selectMenuItems(menu, rse, parentId) {
//--- Filter menu items depending on selector
let /** @type {?} */ result = [];
menu.forEach((menu) => {
let /** @type {?} */ m = Lib.menu.clone(menu);
//--- Concatenate parentId
if (parentId != null) {
m.id = parentId + "." + m.id;
}
m.command = (event) => {
this.fireEvent(m.id, rse);
};
if (this.menuSelector == null) {
result.push(m);
}
else {
let /** @type {?} */ mode = this.menuSelector.select(m.id, rse);
m.disabled = (mode == MenuSelectionMode.DISABLE);
if (mode == MenuSelectionMode.EXCLUDE) {
//--- Exclude menu from list
}
else {
//--- Mode is INCLUDE or DISABLE
result.push(m);
}
}
//--- Recurse on children
if (menu.items != null) {
m.items = this.selectMenuItems(menu.items, rse, m.id);
if (menu.items != null && m.items == null) {
m.disabled = true;
}
}
});
return (result.length != 0)
? result
: null;
}
/**
* @param {?} code
* @param {?} event
* @return {?}
*/
fireEvent(code, event) {
//--- Hide context-menu (it seems that with our config it does not disappear automatically)
this.pContextMenu.hide();
let /** @type {?} */ tableEvent = {
code: code,
params: event
};
super.emitToApp(tableEvent);
}
}
ListTable.decorators = [
{ type: Component, args: [{
selector: 'hpe-list-table',
template: `<!--
=============================================================================
===
=== (C) Copyright 2018 Hewlett Packard Enterprise Development LP.
===
=== Use of this source code is governed by an MIT-style license that can be
=== found in the LICENSE file
=============================================================================
-->
<p-table #tt
[columns] = "displayColumns"
[value] = "displayData"
[dataKey] = "rowId"
[selectionMode] = "multiSelection ? 'multiple' : 'single'"
[paginator] = "true"
[rows] = "rowsPerPage"
[rowsPerPageOptions] = "rowSet"
[pageLinks] = "10"
[loading] = "loading"
[metaKeySelection] = "true"
[contextMenu] = "cm"
[(selection)] = "selectedRow"
(onRowSelect) = "onRowSelect($event)"
(onRowUnselect) = "onRowUnselect($event)"
contextMenuSelectionMode = "joint"
(onContextMenuSelect) = "onContextMenuSelect($event)"
(onFilter) = "onFilter($event)">
<ng-template pTemplate="header" let-columns>
<tr>
<th *ngFor="let col of columns" [pSortableColumn]="col.field">
{{col.displayHeader}}
<p-sortIcon [field]="col.field"></p-sortIcon>
</th>
</tr>
<tr class="ui-fluid">
<th *ngFor="let col of columns">
<input *ngIf="col.filter == null"
pInputText
type = "text"
(input) = "filter($event.target.value, col)"
class = "filter">
<p-dropdown *ngIf = "col.filter == 'select'"
[options] = "columnValues.get(col.field)"
[style] = "{'width':'100%'}"
(onChange) = "filter($event.value, col)"
></p-dropdown>
<p-multiSelect *ngIf = "col.filter == 'list'"
[options] = "columnValues.get(col.field)"
[defaultLabel] = "allValue"
(onChange) = "filter($event.value, col)"
class = "filter"></p-multiSelect>
</th>
</tr>
</ng-template>
<ng-template pTemplate="body" let-row let-columns="columns">
<tr [pSelectableRow]="row" [pContextMenuRow]="row">
<td *ngFor="let col of columns">
<span [ngClass]="row[col.field].style">{{row[col.field]}}</span>
</td>
</tr>
</ng-template>
<ng-template pTemplate="emptymessage" let-columns>
<tr>
<td [attr.colspan]="columns.length">
{{noRecords}}
</td>
</tr>
</ng-template>
</p-table>
<p-contextMenu #cm [model]="activeMenu" appendTo="body"></p-contextMenu>
`,
styles: [`.cell{width:100%;display:inline-block;padding:.7em;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.filter{width:100%}.alignLeft{text-align:left}.alignCenter{text-align:center}.alignRight{text-align:right}:host ::ng-deep .ui-paginator{border:none;background-image:inherit}:host ::ng-deep .ui-table .ui-table-thead>tr>th{border:none}:host ::ng-deep .ui-table .ui-table-thead>tr>th:not(.ui-state-highlight){background-color:#fff}:host ::ng-deep .ui-table .ui-table-thead>tr>th:hover{background-color:#c6c9ca}:host ::ng-deep .ui-table .ui-table-tbody>tr.ui-state-highlight{background-color:#a0c0c0}:host ::ng-deep .ui-table .ui-table-thead>tr:last-child{border-bottom:2px solid #c6c9ca}:host ::ng-deep .ui-table .ui-sortable-column.ui-state-highlight{background-color:#5f7a76}:host ::ng-deep .ui-table .ui-table-tbody>tr>td{border-left:none;border-right:none}`]
},] },
];
/** @nocollapse */
ListTable.ctorParameters = () => [
{ type: EventBusService, },
{ type: LabelService, },
];
ListTable.propDecorators = {
"rowId": [{ type: Input },],
"columns": [{ type: Input },],
"data": [{ type: Input },],
"visibleColumns": [{ type: Input },],
"multiSelection": [{ type: Input },],
"rowsPerPage": [{ type: Input },],
"rowSet": [{ type: Input },],
"loading": [{ type: Input },],
"labelGroup": [{ type: Input },],
"contextMenu": [{ type: Input },],
"menuSelector": [{ type: Input },],
"onFilterChange": [{ type: Output },],
"onRowSelected": [{ type: Output },],
"onRowUnselected": [{ type: Output },],
"pTable": [{ type: ViewChild, args: ['tt',] },],
"pContextMenu": [{ type: ViewChild, args: ['cm',] },],
};
function ListTable_tsickle_Closure_declarations() {
/** @type {!Array<{type: !Function, args: (undefined|!Array<?>)}>} */
ListTable.decorators;
/**
* @nocollapse
* @type {function(): !Array<(null|{type: ?, decorators: (undefined|!Array<{type: !Function, args: (undefined|!Array<?>)}>)})>}
*/
ListTable.ctorParameters;
/** @type {!Object<string,!Array<{type: !Function, args: (undefined|!Array<?>)}>>} */
ListTable.propDecorators;
/** @type {?} */
ListTable.prototype.rowId;
/** @type {?} */
ListTable.prototype.columns;
/** @type {?} */
ListTable.prototype.data;
/** @type {?} */
ListTable.prototype.visibleColumns;
/** @type {?} */
ListTable.prototype.multiSelection;
/** @type {?} */
ListTable.prototype.rowsPerPage;
/** @type {?} */
ListTable.prototype.rowSet;
/** @type {?} */
ListTable.prototype.loading;
/** @type {?} */
ListTable.prototype.labelGroup;
/** @type {?} */
ListTable.prototype.contextMenu;
/** @type {?} */
ListTable.prototype.menuSelector;
/** @type {?} */
ListTable.prototype.onFilterChange;
/** @type {?} */
ListTable.prototype.onRowSelected;
/** @type {?} */
ListTable.prototype.onRowUnselected;
/** @type {?} */
ListTable.prototype.pTable;
/** @type {?} */
ListTable.prototype.pContextMenu;
/** @type {?} */
ListTable.prototype.selectedRow;
/** @type {?} */
ListTable.prototype.displayColumns;
/** @type {?} */
ListTable.prototype.displayData;
/** @type {?} */
ListTable.prototype.activeMenu;
/** @type {?} */
ListTable.prototype.columnValues;
/** @type {?} */
ListTable.prototype.colToIndex;
/** @type {?} */
ListTable.prototype.alignMap;
/** @type {?} */
ListTable.prototype.labelService;
}
class ListTableCell {
/**
* @return {?}
*/
toString() {
return this.displayValue;
}
}
function ListTableCell_tsickle_Closure_declarations() {
/** @type {?} */
ListTableCell.prototype.originalValue;
/** @type {?} */
ListTableCell.prototype.displayValue;
/** @type {?} */
ListTableCell.prototype.style;
}
//=============================================================================
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibGlzdC10YWJsZS5qcyIsInNvdXJjZVJvb3QiOiJuZzovL0BocGUvYW5ndWxhci10b29sa2l0L2d1aS9wYW5lbC8iLCJzb3VyY2VzIjpbImxpc3QtdGFibGUvbGlzdC10YWJsZS50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7OztBQVFBLE9BQU8sRUFBQyxTQUFTLEVBQUUsWUFBWSxFQUFFLEtBQUssRUFBYSxNQUFNLEVBQWlCLFNBQVMsRUFBQyxNQUFNLGVBQWUsQ0FBQztBQUUxRyxPQUFPLEVBQUMsV0FBVyxFQUFFLFNBQVMsRUFBQyxNQUFNLGlCQUFpQixDQUFDO0FBUXZELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFPLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBQyxnQkFBZ0IsRUFBQyxNQUFRLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBQyxrQkFBa0IsRUFBQyxNQUFNLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBQyxpQkFBaUIsRUFBQyxNQUFPLDRCQUE0QixDQUFDO0FBQzlELE9BQU8sRUFBQyxHQUFHLEVBQUMsTUFBcUIsMEJBQTBCLENBQUM7QUFDNUQsT0FBTyxFQUFDLGtCQUFrQixFQUFDLE1BQU0sOEJBQThCLENBQUM7QUFDaEUsT0FBTyxFQUFDLGVBQWUsRUFBQyxNQUFTLDhCQUE4QixDQUFDO0FBQ2hFLE9BQU8sRUFBQyxZQUFZLEVBQUMsTUFBWSw4QkFBOEIsQ0FBQztBQUloRTtBQXdGQSxNQUFNLGdCQUFpQixTQUFRLGtCQUFrQjs7Ozs7SUE4RDdDLFlBQW9CLGVBQWlDLEVBQ2pDO1FBRW5CLEtBQUssQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUZKLGlCQUFZLEdBQVosWUFBWTs7OEJBekMyQixJQUFJLFlBQVksRUFBcUI7NkJBQ3JDLElBQUksWUFBWSxFQUFvQjsrQkFDcEMsSUFBSSxZQUFZLEVBQXNCO3dCQTBCakY7WUFDbEIsTUFBTSxFQUFLLFdBQVc7WUFDdEIsUUFBUSxFQUFHLGFBQWE7WUFDeEIsT0FBTyxFQUFJLFlBQVk7U0FDdkI7UUFhRyxJQUFJLENBQUMsV0FBVyxHQUFNLENBQUMsQ0FBQztRQUMzQixJQUFJLENBQUMsTUFBTSxHQUFXLENBQUMsQ0FBQyxFQUFFLENBQUMsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLEVBQUUsRUFBRSxFQUFFLENBQUMsQ0FBQztRQUM3QyxJQUFJLENBQUMsT0FBTyxHQUFVLEtBQUssQ0FBQztRQUM1QixJQUFJLENBQUMsY0FBYyxHQUFHLEtBQUssQ0FBQztLQUM1Qjs7OztJQVFNLFNBQVM7UUFDZixJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFDOzs7OztJQUtsQixjQUFjO1FBQ3BCLElBQUksQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLEVBQUMsYUFBYSxFQUFDLElBQUksRUFBQyxDQUFDLENBQUM7Ozs7O0lBTzdDLElBQUksUUFBUTtRQUNYLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsS0FBSyxDQUFDLENBQUM7S0FDdkQ7Ozs7SUFJRCxJQUFJLFNBQVM7UUFDWixNQUFNLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLFdBQVcsQ0FBQyxDQUFDO0tBQzdEOzs7OztJQVFELFdBQVcsQ0FBQyxPQUFzQjtRQUU5QixxQkFBSSxtQkFBbUIsR0FBYSxLQUFLLENBQUM7UUFFN0MsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUN4QixJQUFJLENBQUMsV0FBVyxFQUFFLENBQUM7WUFDbkIsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1NBQzNCO1FBRUQsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLE1BQU0sQ0FBQyxDQUFDLENBQUMsQ0FBQztZQUNyQixJQUFJLENBQUMsUUFBUSxFQUFFLENBQUM7WUFDaEIsbUJBQW1CLEdBQUcsSUFBSSxDQUFDO1NBQzNCO1FBRUQsRUFBRSxDQUFDLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLENBQUMsQ0FBQyxDQUFDO1lBQy9CLElBQUksQ0FBQyxrQkFBa0IsRUFBRSxDQUFDO1NBQzFCO1FBRUQsRUFBRSxDQUFDLENBQUMsbUJBQW1CLENBQUMsQ0FBQyxDQUFDO1lBQ3pCLElBQUksQ0FBQyxnQkFBZ0IsRUFBRSxDQUFDO1NBQ3hCOztLQUVEOzs7OztJQVFFLFdBQVcsQ0FBQyxLQUFXOztRQUd6QixxQkFBSSxHQUFHLEdBQVUsSUFBSSxDQUFDLFVBQVUsQ0FBQyxLQUFLLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDN0MscUJBQUksSUFBSSxHQUFTLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7UUFFekQsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsSUFBSSxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztLQUN0RDs7Ozs7SUFJSixhQUFhLENBQUMsS0FBVzs7UUFHeEIscUJBQUksR0FBRyxHQUFVLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQzdDLHFCQUFJLElBQUksR0FBUyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBRXpELElBQUksQ0FBQyxlQUFlLENBQUMsSUFBSSxDQUFDLElBQUksa0JBQWtCLENBQUMsR0FBRyxFQUFFLElBQUksQ0FBQyxDQUFDLENBQUM7S0FDN0Q7Ozs7O0lBSUQsbUJBQW1CLENBQUMsS0FBSzs7UUFHeEIscUJBQUksR0FBRyxHQUFJLElBQUksQ0FBQyxVQUFVLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO1FBQ3ZDLHFCQUFJLElBQUksR0FBRyxJQUFJLENBQUMsZ0JBQWdCLENBQUMsSUFBSSxDQUFDLFdBQVcsQ0FBQyxDQUFDO1FBQ25ELHFCQUFJLEdBQUcsR0FBSSxJQUFJLGdCQUFnQixDQUFDLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQzs7UUFHM0MsSUFBSSxDQUFDLGFBQWEsQ0FBQyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUM7O1FBSTFCLElBQUksQ0FBQyxVQUFVLEdBQUcsSUFBSSxDQUFDLGVBQWUsQ0FBQyxJQUFJLENBQUMsV0FBVyxFQUFFLEdBQUcsRUFBRSxJQUFJLENBQUMsQ0FBQztLQUNwRTs7Ozs7SUFJSixRQUFRLENBQUMsS0FBSztRQUNiLElBQUksQ0FBQyxjQUFjLENBQUMsSUFBSSxDQUFDLElBQUksaUJBQWlCLENBQUMsSUFBSSxDQUFDLGVBQWUsRUFBRSxDQUFDLENBQUMsQ0FBQztLQUN4RTs7Ozs7O0lBUUQsTUFBTSxDQUFDLEtBQVcsRUFBRSxHQUFxQjtRQUN4QyxJQUFJLENBQUMsTUFBTSxDQUFDLE1BQU0sQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsZUFBZSxDQUFDLENBQUM7S0FDMUQ7Ozs7SUFRTyxXQUFXO1FBRWxCLE9BQU8sQ0FBQyxHQUFHLENBQUMseUJBQXlCLEdBQUUsSUFBSSxDQUFDLFNBQVMsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsQ0FBQztRQUVyRSxJQUFJLENBQUMsVUFBVSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7UUFFNUIsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDOztTQUUxQjtRQUNELElBQUksQ0FBQyxDQUFDO1lBQ0wscUJBQUksS0FBSyxHQUFZLENBQUMsQ0FBQztZQUV2QixJQUFJLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FBRSxDQUFDLEdBQXFCLEVBQUUsRUFBRTtnQkFDL0MsSUFBSSxDQUFDLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxDQUFDLEtBQUssRUFBRSxLQUFLLEVBQUUsQ0FBQyxDQUFDO2dCQUV4QyxHQUFHLENBQUMsYUFBYSxHQUFLLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLENBQUM7Z0JBQzNDLEdBQUcsQ0FBQyxlQUFlLEdBQUcsSUFBSSxDQUFDLG1CQUFtQixDQUFDLEdBQUcsQ0FBQyxDQUFDO2FBQ3BELENBQUMsQ0FBQztTQUNIOzs7Ozs7SUFTTSxVQUFVLENBQUMsR0FBcUI7UUFFdkMsTUFBTSxDQUFDLEdBQUcsQ0FBQyxNQUFNO2VBQ1osQ0FBQyxJQUFJLENBQUMsVUFBVSxJQUFJLElBQUksQ0FBQyxZQUFZLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxVQUFVLEVBQUUsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO2VBQzNFLEdBQUcsQ0FBQyxLQUFLLENBQUM7Ozs7OztJQUtSLG1CQUFtQixDQUFDLEdBQW9CO1FBRS9DLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxNQUFNLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUN4QixNQUFNLENBQUMsVUFBVSxDQUFDO1NBQ2xCO1FBRUQsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzVCLE1BQU0sQ0FBQyxRQUFRLENBQUM7U0FDaEI7UUFFRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLE1BQU0sQ0FBQyxDQUFDLENBQUM7WUFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQztTQUNaO1FBRUQsTUFBTSxDQUFDLElBQUksQ0FBQzs7Ozs7SUFLTCxRQUFRO1FBRWYsT0FBTyxDQUFDLEdBQUcsQ0FBQyxzQkFBc0IsR0FBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO1FBRS9ELEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMvQyxJQUFJLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztTQUN4QjtRQUNELElBQUksQ0FBQyxDQUFDO1lBQ0wsSUFBSSxDQUFDLFdBQVcsR0FBRyxFQUFFLENBQUM7WUFFdEIsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUUsQ0FBQyxHQUFTLEVBQUUsRUFBRTtnQkFDaEMscUJBQUksVUFBVSxHQUFHLEVBQUUsQ0FBQztnQkFDcEIsSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7Z0JBRWxDLEdBQUcsQ0FBQyxDQUFDLHFCQUFJLEdBQUcsSUFBSSxHQUFHLENBQUMsQ0FBQyxDQUFDO29CQUNyQixxQkFBSSxJQUFJLEdBQW1CLElBQUksYUFBYSxFQUFFLENBQUM7b0JBQy9DLFVBQVUsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUM7b0JBRXZCLHFCQUFJLEtBQUssR0FBRyxHQUFHLENBQUMsR0FBRyxDQUFDLENBQUM7b0JBQ3JCLHFCQUFJLE1BQU0sR0FBRSxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxHQUFHLENBQUMsQ0FBQztvQkFDckMscUJBQUksR0FBRyxHQUFLLElBQUksQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLENBQUM7b0JBRWpDLElBQUksQ0FBQyxhQUFhLEdBQUcsS0FBSyxDQUFDO29CQUMzQixJQUFJLENBQUMsWUFBWSxHQUFJLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO29CQUM1RCxJQUFJLENBQUMsS0FBSyxHQUFXLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxHQUFHLEVBQUUsR0FBRyxFQUFFLEtBQUssQ0FBQyxDQUFDO2lCQUM1RDthQUNELENBQUMsQ0FBQztTQUNIOzs7Ozs7OztJQUtNLGdCQUFnQixDQUFDLEdBQVMsRUFBRSxHQUFxQixFQUFFLEtBQVc7UUFFckUsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQzVCLEtBQUssR0FBRyxHQUFHLENBQUMsVUFBVSxDQUFDLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztTQUN4QztRQUVELE1BQU0sQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUM7WUFDcEIsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7WUFDbEIsQ0FBQyxDQUFDLElBQUksQ0FBQzs7Ozs7Ozs7SUFLRixnQkFBZ0IsQ0FBQyxHQUFTLEVBQUUsR0FBcUIsRUFBRSxLQUFXO1FBRXJFLHFCQUFJLE1BQU0sR0FBYSxDQUFDLE1BQU0sQ0FBQyxDQUFDO1FBRWhDLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxTQUFTLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMzQixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDLENBQUM7U0FDMUM7UUFFRCxFQUFFLENBQUMsQ0FBQyxHQUFHLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDeEIscUJBQUksS0FBSyxHQUFjLEdBQUcsQ0FBQyxNQUFNLENBQUMsS0FBSyxDQUFDLEtBQUssRUFBRSxHQUFHLENBQUMsQ0FBQztZQUVwRCxFQUFFLENBQUMsQ0FBQyxLQUFLLENBQUMsSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ3hCLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ2xCLE1BQU0sQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDO2FBQ3hCO1lBRUQsRUFBRSxDQUFDLENBQUMsS0FBSyxDQUFDLFVBQVUsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUM5QixNQUFNLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxVQUFVLENBQUMsQ0FBQzthQUM5QjtTQUNEO1FBRUQsTUFBTSxDQUFDLE1BQU0sQ0FBQzs7Ozs7SUFLUCxrQkFBa0I7UUFFekIsT0FBTyxDQUFDLEdBQUcsQ0FBQyxpQ0FBaUMsR0FBRSxJQUFJLENBQUMsU0FBUyxDQUFDLElBQUksQ0FBQyxjQUFjLENBQUMsQ0FBQyxDQUFDO1FBRXBGLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxjQUFjLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUN6RCxJQUFJLENBQUMsY0FBYyxHQUFHLElBQUksQ0FBQztTQUMzQjtRQUNELElBQUksQ0FBQyxDQUFDO1lBQ0wsSUFBSSxDQUFDLGNBQWMsR0FBRyxFQUFFLENBQUM7WUFFekIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxPQUFPLENBQUUsQ0FBQyxJQUFhLEVBQUUsRUFBRTtnQkFDOUMscUJBQUksS0FBSyxHQUFZLElBQUksQ0FBQyxVQUFVLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyxDQUFDO2dCQUUvQyxFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztvQkFDbkIsSUFBSSxDQUFDLGNBQWMsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDO2lCQUM5QzthQUNELENBQUMsQ0FBQztTQUNIOzs7OztJQUtNLGdCQUFnQjtRQUV2QixJQUFJLENBQUMsWUFBWSxHQUFHLElBQUksR0FBRyxFQUFFLENBQUM7O1FBSTlCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLElBQUksSUFBSSxJQUFJLElBQUksQ0FBQyxJQUFJLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztZQUMvQyxNQUFNLENBQUMsSUFBSSxDQUFDO1NBQ1o7UUFFRCxPQUFPLENBQUMsR0FBRyxDQUFDLGtDQUFrQyxDQUFDLENBQUM7UUFFaEQsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFvQixFQUFFLEVBQUU7WUFDN0MsT0FBTyxDQUFDLEdBQUcsQ0FBQyxTQUFTLEdBQUcsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDO1lBQ25DLElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxLQUFLLEVBQUUsSUFBSSxDQUFDLGVBQWUsQ0FBQyxHQUFHLENBQUMsQ0FBQyxDQUFDO1NBQzVELENBQUMsQ0FBQzs7Ozs7O0lBT0ksZUFBZSxDQUFDLEdBQXFCO1FBRXpDLHFCQUFJLEtBQUssR0FBYSxHQUFHLENBQUMsS0FBSyxDQUFDO1FBQ25DLHFCQUFJLE1BQU0sR0FBYyxJQUFJLEdBQUcsRUFBRSxDQUFDOztRQUlsQyxJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxHQUFHLENBQUMsRUFBRTtZQUN2QixxQkFBSSxLQUFLLEdBQVMsR0FBRyxDQUFDLEtBQUssQ0FBQyxDQUFDOztZQUk3QixFQUFFLENBQUMsQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDbkIsTUFBTSxDQUFDLEdBQUcsQ0FBQyxLQUFLLENBQUMsQ0FBQzthQUNsQjtTQUNELENBQUMsQ0FBQzs7UUFJSCxxQkFBSSxJQUFJLEdBQW9CLEVBQUUsQ0FBQzs7UUFJL0IsRUFBRSxDQUFDLENBQUMsR0FBRyxDQUFDLE1BQU0sSUFBSSxRQUFRLENBQUMsQ0FBQyxDQUFDO1lBQzVCLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ1QsS0FBSyxFQUFFLElBQUksQ0FBQyxRQUFRO2dCQUNwQixLQUFLLEVBQUUsSUFBSTthQUNYLENBQUMsQ0FBQztTQUNIO1FBRUQsTUFBTSxDQUFDLE9BQU8sQ0FBRSxDQUFDLEtBQVMsRUFBRSxFQUFFO1lBQzdCLEVBQUUsQ0FBQyxDQUFDLEdBQUcsQ0FBQyxVQUFVLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDNUIsS0FBSyxHQUFHLEdBQUcsQ0FBQyxVQUFVLENBQUMsU0FBUyxDQUFDLEtBQUssQ0FBQyxDQUFDO2FBQ3hDO1lBRUQscUJBQUksS0FBSyxHQUFXLENBQUMsS0FBSyxJQUFJLElBQUksQ0FBQztnQkFDN0IsQ0FBQyxDQUFDLEtBQUssQ0FBQyxRQUFRLEVBQUU7Z0JBQ2xCLENBQUMsQ0FBQyxJQUFJLENBQUM7WUFFYixJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUNULEtBQUssRUFBRSxLQUFLO2dCQUNaLEtBQUssRUFBRSxLQUFLO2FBQ1osQ0FBQyxDQUFDO1NBQ0gsQ0FBQyxDQUFDO1FBRUgsTUFBTSxDQUFDLElBQUksQ0FBQzs7Ozs7SUFPTCxlQUFlO1FBRXRCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDO1lBQ2pCLEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLENBQUMsQ0FBQztnQkFDL0IsTUFBTSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsYUFBYSxDQUFDLE1BQU0sQ0FBQzthQUN4QztTQUNEO1FBRUQsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUM7WUFDZixNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUM7U0FDeEI7UUFFRCxNQUFNLENBQUMsSUFBSSxDQUFDOzs7Ozs7SUFLTCxVQUFVLENBQUMsSUFBVTtRQUV6QixxQkFBSSxHQUFHLEdBQVMsRUFBRSxDQUFDO1FBRW5CLEdBQUcsQ0FBQyxDQUFDLHFCQUFJLEdBQUcsSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ3RCLEdBQUcsQ0FBQyxHQUFHLENBQUMsR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsYUFBYSxDQUFDO1NBQ25DO1FBRUQsTUFBTSxDQUFDLEdBQUcsQ0FBQzs7Ozs7O0lBS1AsZ0JBQWdCLENBQUMsSUFBWTtRQUVqQyxxQkFBSSxNQUFNLEdBQVcsRUFBRSxDQUFDO1FBRXhCLEVBQUUsQ0FBQyxDQUFDLElBQUksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO1lBQ2xCLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQyxHQUFTLEVBQUUsRUFBRTtnQkFDMUIsTUFBTSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEdBQUcsQ0FBQyxDQUFDLENBQUM7YUFDbEMsQ0FBQyxDQUFDO1NBQ0g7UUFFSixNQUFNLENBQUMsTUFBTSxDQUFDOzs7Ozs7OztJQUtQLGVBQWUsQ0FBQyxJQUFhLEVBQUUsR0FBc0IsRUFBRSxRQUFpQjs7UUFJL0UscUJBQUksTUFBTSxHQUFZLEVBQUUsQ0FBQztRQUV6QixJQUFJLENBQUMsT0FBTyxDQUFDLENBQUMsSUFBVyxFQUFFLEVBQUU7WUFDNUIscUJBQUksQ0FBQyxHQUFHLEdBQUcsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxDQUFDOztZQUk3QixFQUFFLENBQUMsQ0FBQyxRQUFRLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDdEIsQ0FBQyxDQUFDLEVBQUUsR0FBRyxRQUFRLEdBQUUsR0FBRyxHQUFFLENBQUMsQ0FBQyxFQUFFLENBQUM7YUFDM0I7WUFFRCxDQUFDLENBQUMsT0FBTyxHQUFHLENBQUMsS0FBSyxFQUFFLEVBQUU7Z0JBQ3JCLElBQUksQ0FBQyxTQUFTLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQzthQUMxQixDQUFDO1lBRUYsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFlBQVksSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO2dCQUMvQixNQUFNLENBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDO2FBQ2Y7WUFDRCxJQUFJLENBQUMsQ0FBQztnQkFDTCxxQkFBSSxJQUFJLEdBQUcsSUFBSSxDQUFDLFlBQVksQ0FBQyxNQUFNLENBQUMsQ0FBQyxDQUFDLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFFL0MsQ0FBQyxDQUFDLFFBQVEsR0FBRyxDQUFDLElBQUksSUFBSSxpQkFBaUIsQ0FBQyxPQUFPLENBQUMsQ0FBQztnQkFFakQsRUFBRSxDQUFDLENBQUMsSUFBSSxJQUFJLGlCQUFpQixDQUFDLE9BQU8sQ0FBQyxDQUFDLENBQUM7O2lCQUV2QztnQkFDRCxJQUFJLENBQUMsQ0FBQzs7b0JBRUwsTUFBTSxDQUFDLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztpQkFDZjthQUNEOztZQUlELEVBQUUsQ0FBQyxDQUFDLElBQUksQ0FBQyxLQUFLLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQztnQkFDeEIsQ0FBQyxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUMsZUFBZSxDQUFDLElBQUksQ0FBQyxLQUFLLEVBQUUsR0FBRyxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQztnQkFFdEQsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLElBQUksQ0FBQyxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsQ0FBQyxDQUFDO29CQUMzQyxDQUFDLENBQUMsUUFBUSxHQUFHLElBQUksQ0FBQztpQkFDbEI7YUFDRDtTQUNELENBQUMsQ0FBQztRQUVILE1BQU0sQ0FBQyxDQUFDLE1BQU0sQ0FBQyxNQUFNLElBQUksQ0FBQyxDQUFDO1lBQ3hCLENBQUMsQ0FBQyxNQUFNO1lBQ1IsQ0FBQyxDQUFDLElBQUksQ0FBQzs7Ozs7OztJQUtILFNBQVMsQ0FBQyxJQUFZLEVBQUUsS0FBd0I7O1FBSXBELElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxFQUFFLENBQUM7UUFFNUIscUJBQUksVUFBVSxHQUFhO1lBQzFCLElBQUksRUFBSSxJQUFJO1lBQ1osTUFBTSxFQUFFLEtBQUs7U0FDYixDQUFDO1FBRUYsS0FBSyxDQUFDLFNBQVMsQ0FBQyxVQUFVLENBQUMsQ0FBQzs7OztZQTFtQjdCLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQVUsZ0JBQWdCO2dCQUNsQyxRQUFRLEVBQUU7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0NBZ0ZiO2dCQUNHLE1BQU0sRUFBRSxDQUFDLG8yQkFBbzJCLENBQUM7YUFDajNCOzs7O1lBekZPLGVBQWU7WUFDZixZQUFZOzs7c0JBb0dsQixLQUFLO3dCQUNGLEtBQUs7cUJBQ0wsS0FBSzsrQkFDTCxLQUFLOytCQUNSLEtBQUs7NEJBQ0wsS0FBSzt1QkFDTCxLQUFLO3dCQUNMLEtBQUs7MkJBQ0wsS0FBSzs0QkFDTCxLQUFLOzZCQUNMLEtBQUs7K0JBSUwsTUFBTTs4QkFDTixNQUFNO2dDQUNOLE1BQU07dUJBSU4sU0FBUyxTQUFDLElBQUk7NkJBQ2QsU0FBUyxTQUFDLElBQUk7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUEyZmhCOzs7O0lBUVEsUUFBUTtRQUNkLE1BQU0sQ0FBQyxJQUFJLENBQUMsWUFBWSxDQUFDOztDQUUxQiIsInNvdXJjZXNDb250ZW50IjpbIi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi8vPT09XG4vLz09PSAoQykgQ29weXJpZ2h0IDIwMTggSGV3bGV0dCBQYWNrYXJkIEVudGVycHJpc2UgRGV2ZWxvcG1lbnQgTFAuXG4vLz09PVxuLy89PT0gVXNlIG9mIHRoaXMgc291cmNlIGNvZGUgaXMgZ292ZXJuZWQgYnkgYW4gTUlULXN0eWxlIGxpY2Vuc2UgdGhhdCBjYW4gYmVcbi8vPT09IGZvdW5kIGluIHRoZSBMSUNFTlNFIGZpbGVcbi8vPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cblxuaW1wb3J0IHtDb21wb25lbnQsIEV2ZW50RW1pdHRlciwgSW5wdXQsIE9uQ2hhbmdlcywgT3V0cHV0LCBTaW1wbGVDaGFuZ2VzLCBWaWV3Q2hpbGR9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuXG5pbXBvcnQge0NvbnRleHRNZW51LCBEYXRhVGFibGV9IGZyb20gXCJwcmltZW5nL3ByaW1lbmdcIjtcblxuaW1wb3J0IHtBcHBFdmVudH0gICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtDZWxsU3R5bGV9ICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtEcm9wZG93bkl0ZW19ICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtNZW51fSAgICAgICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtMaXN0VGFibGVDb2x1bW59ICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtNZW51U2VsZWN0b3J9ICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtGaWx0ZXJDaGFuZ2VFdmVudH0gIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtSb3dTZWxlY3RlZEV2ZW50fSAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtSb3dVbnNlbGVjdGVkRXZlbnR9IGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtNZW51U2VsZWN0aW9uTW9kZX0gIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9tb2RlbFwiO1xuaW1wb3J0IHtMaWJ9ICAgICAgICAgICAgICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9saWJcIjtcbmltcG9ydCB7QWJzdHJhY3RTdWJzY3JpYmVyfSBmcm9tIFwiQGhwZS9hbmd1bGFyLXRvb2xraXQvc2VydmljZVwiO1xuaW1wb3J0IHtFdmVudEJ1c1NlcnZpY2V9ICAgIGZyb20gXCJAaHBlL2FuZ3VsYXItdG9vbGtpdC9zZXJ2aWNlXCI7XG5pbXBvcnQge0xhYmVsU2VydmljZX0gICAgICAgZnJvbSBcIkBocGUvYW5ndWxhci10b29sa2l0L3NlcnZpY2VcIjtcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5AQ29tcG9uZW50KHtcbiAgICBzZWxlY3RvciAgICA6ICAgICAnaHBlLWxpc3QtdGFibGUnLFxuICAgIHRlbXBsYXRlOiBgPCEtLVxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbj09PVxuPT09IChDKSBDb3B5cmlnaHQgMjAxOCBIZXdsZXR0IFBhY2thcmQgRW50ZXJwcmlzZSBEZXZlbG9wbWVudCBMUC5cbj09PVxuPT09IFVzZSBvZiB0aGlzIHNvdXJjZSBjb2RlIGlzIGdvdmVybmVkIGJ5IGFuIE1JVC1zdHlsZSBsaWNlbnNlIHRoYXQgY2FuIGJlXG49PT0gZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZVxuPT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT1cbi0tPlxuXG48cC10YWJsZSAjdHRcblx0XHRbY29sdW1uc10gICAgICAgICAgICAgICAgPSBcImRpc3BsYXlDb2x1bW5zXCJcblx0XHRbdmFsdWVdICAgICAgICAgICAgICAgICAgPSBcImRpc3BsYXlEYXRhXCJcblx0XHRbZGF0YUtleV0gICAgICAgICAgICAgICAgPSBcInJvd0lkXCJcblx0XHRbc2VsZWN0aW9uTW9kZV0gICAgICAgICAgPSBcIm11bHRpU2VsZWN0aW9uID8gJ211bHRpcGxlJyA6ICdzaW5nbGUnXCJcblx0XHRbcGFnaW5hdG9yXSAgICAgICAgICAgICAgPSBcInRydWVcIlxuXHRcdFtyb3dzXSAgICAgICAgICAgICAgICAgICA9IFwicm93c1BlclBhZ2VcIlxuXHRcdFtyb3dzUGVyUGFnZU9wdGlvbnNdICAgICA9IFwicm93U2V0XCJcblx0XHRbcGFnZUxpbmtzXSAgICAgICAgICAgICAgPSBcIjEwXCJcblx0XHRbbG9hZGluZ10gICAgICAgICAgICAgICAgPSBcImxvYWRpbmdcIlxuXHRcdFttZXRhS2V5U2VsZWN0aW9uXSAgICAgICA9IFwidHJ1ZVwiXG5cdFx0W2NvbnRleHRNZW51XSAgICAgICAgICAgID0gXCJjbVwiXG5cdFx0WyhzZWxlY3Rpb24pXSAgICAgICAgICAgID0gXCJzZWxlY3RlZFJvd1wiXG5cdFx0KG9uUm93U2VsZWN0KSAgICAgICAgICAgID0gXCJvblJvd1NlbGVjdCgkZXZlbnQpXCJcblx0XHQob25Sb3dVbnNlbGVjdCkgICAgICAgICAgPSBcIm9uUm93VW5zZWxlY3QoJGV2ZW50KVwiXG5cdFx0Y29udGV4dE1lbnVTZWxlY3Rpb25Nb2RlID0gXCJqb2ludFwiXG5cdFx0KG9uQ29udGV4dE1lbnVTZWxlY3QpICAgID0gXCJvbkNvbnRleHRNZW51U2VsZWN0KCRldmVudClcIlxuXHRcdChvbkZpbHRlcikgICAgICAgICAgICAgICA9IFwib25GaWx0ZXIoJGV2ZW50KVwiPlxuXG5cdDxuZy10ZW1wbGF0ZSBwVGVtcGxhdGU9XCJoZWFkZXJcIiBsZXQtY29sdW1ucz5cblx0XHQ8dHI+XG5cdFx0XHQ8dGggKm5nRm9yPVwibGV0IGNvbCBvZiBjb2x1bW5zXCIgW3BTb3J0YWJsZUNvbHVtbl09XCJjb2wuZmllbGRcIj5cblx0XHRcdFx0e3tjb2wuZGlzcGxheUhlYWRlcn19XG5cdFx0XHRcdDxwLXNvcnRJY29uIFtmaWVsZF09XCJjb2wuZmllbGRcIj48L3Atc29ydEljb24+XG5cdFx0XHQ8L3RoPlxuXHRcdDwvdHI+XG5cblx0XHQ8dHIgY2xhc3M9XCJ1aS1mbHVpZFwiPlxuXHRcdFx0PHRoICpuZ0Zvcj1cImxldCBjb2wgb2YgY29sdW1uc1wiPlxuXG5cdFx0XHRcdDxpbnB1dCAgICAgICAgICAqbmdJZj1cImNvbC5maWx0ZXIgPT0gbnVsbFwiXG5cdFx0XHRcdFx0XHRcdFx0cElucHV0VGV4dFxuXHRcdFx0XHRcdFx0XHRcdHR5cGUgICAgPSBcInRleHRcIlxuXHRcdFx0XHRcdFx0XHRcdChpbnB1dCkgPSBcImZpbHRlcigkZXZlbnQudGFyZ2V0LnZhbHVlLCBjb2wpXCJcblx0XHRcdFx0XHRcdFx0XHRjbGFzcyAgID0gXCJmaWx0ZXJcIj5cblxuXHRcdFx0XHQ8cC1kcm9wZG93biAgICAgKm5nSWYgPSBcImNvbC5maWx0ZXIgPT0gJ3NlbGVjdCdcIlxuXHRcdFx0XHRcdFx0XHRcdFtvcHRpb25zXSAgPSBcImNvbHVtblZhbHVlcy5nZXQoY29sLmZpZWxkKVwiXG5cdFx0XHRcdFx0XHRcdFx0W3N0eWxlXSAgICA9IFwieyd3aWR0aCc6JzEwMCUnfVwiXG5cdFx0XHRcdFx0XHRcdFx0KG9uQ2hhbmdlKSA9IFwiZmlsdGVyKCRldmVudC52YWx1ZSwgY29sKVwiXG5cdFx0XHRcdFx0XHRcdFx0PjwvcC1kcm9wZG93bj5cblxuXHRcdFx0XHQ8cC1tdWx0aVNlbGVjdCAgKm5nSWYgPSBcImNvbC5maWx0ZXIgPT0gJ2xpc3QnXCJcblx0XHRcdFx0XHRcdFx0XHRbb3B0aW9uc10gICAgICA9IFwiY29sdW1uVmFsdWVzLmdldChjb2wuZmllbGQpXCJcblx0XHRcdFx0XHRcdFx0XHRbZGVmYXVsdExhYmVsXSA9IFwiYWxsVmFsdWVcIlxuXHRcdFx0XHRcdFx0XHRcdChvbkNoYW5nZSkgICAgID0gXCJmaWx0ZXIoJGV2ZW50LnZhbHVlLCBjb2wpXCJcblx0XHRcdFx0XHRcdFx0XHRjbGFzcyAgICAgICAgICA9IFwiZmlsdGVyXCI+PC9wLW11bHRpU2VsZWN0PlxuXG5cdFx0XHQ8L3RoPlxuXHRcdDwvdHI+XG5cdDwvbmctdGVtcGxhdGU+XG5cblx0PG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImJvZHlcIiBsZXQtcm93IGxldC1jb2x1bW5zPVwiY29sdW1uc1wiPlxuXHRcdDx0ciBbcFNlbGVjdGFibGVSb3ddPVwicm93XCIgW3BDb250ZXh0TWVudVJvd109XCJyb3dcIj5cblx0XHRcdDx0ZCAqbmdGb3I9XCJsZXQgY29sIG9mIGNvbHVtbnNcIj5cblx0XHRcdFx0PHNwYW4gW25nQ2xhc3NdPVwicm93W2NvbC5maWVsZF0uc3R5bGVcIj57e3Jvd1tjb2wuZmllbGRdfX08L3NwYW4+XG5cdFx0XHQ8L3RkPlxuXHRcdDwvdHI+XG5cdDwvbmctdGVtcGxhdGU+XG5cblx0PG5nLXRlbXBsYXRlIHBUZW1wbGF0ZT1cImVtcHR5bWVzc2FnZVwiIGxldC1jb2x1bW5zPlxuXHRcdDx0cj5cblx0XHRcdDx0ZCBbYXR0ci5jb2xzcGFuXT1cImNvbHVtbnMubGVuZ3RoXCI+XG5cdFx0XHRcdHt7bm9SZWNvcmRzfX1cblx0XHRcdDwvdGQ+XG5cdFx0PC90cj5cblx0PC9uZy10ZW1wbGF0ZT5cbjwvcC10YWJsZT5cblxuPHAtY29udGV4dE1lbnUgI2NtIFttb2RlbF09XCJhY3RpdmVNZW51XCIgYXBwZW5kVG89XCJib2R5XCI+PC9wLWNvbnRleHRNZW51PlxuYCxcbiAgICBzdHlsZXM6IFtgLmNlbGx7d2lkdGg6MTAwJTtkaXNwbGF5OmlubGluZS1ibG9jaztwYWRkaW5nOi43ZW07b3ZlcmZsb3c6aGlkZGVuO3RleHQtb3ZlcmZsb3c6ZWxsaXBzaXM7d2hpdGUtc3BhY2U6bm93cmFwfS5maWx0ZXJ7d2lkdGg6MTAwJX0uYWxpZ25MZWZ0e3RleHQtYWxpZ246bGVmdH0uYWxpZ25DZW50ZXJ7dGV4dC1hbGlnbjpjZW50ZXJ9LmFsaWduUmlnaHR7dGV4dC1hbGlnbjpyaWdodH06aG9zdCA6Om5nLWRlZXAgLnVpLXBhZ2luYXRvcntib3JkZXI6bm9uZTtiYWNrZ3JvdW5kLWltYWdlOmluaGVyaXR9Omhvc3QgOjpuZy1kZWVwIC51aS10YWJsZSAudWktdGFibGUtdGhlYWQ+dHI+dGh7Ym9yZGVyOm5vbmV9Omhvc3QgOjpuZy1kZWVwIC51aS10YWJsZSAudWktdGFibGUtdGhlYWQ+dHI+dGg6bm90KC51aS1zdGF0ZS1oaWdobGlnaHQpe2JhY2tncm91bmQtY29sb3I6I2ZmZn06aG9zdCA6Om5nLWRlZXAgLnVpLXRhYmxlIC51aS10YWJsZS10aGVhZD50cj50aDpob3ZlcntiYWNrZ3JvdW5kLWNvbG9yOiNjNmM5Y2F9Omhvc3QgOjpuZy1kZWVwIC51aS10YWJsZSAudWktdGFibGUtdGJvZHk+dHIudWktc3RhdGUtaGlnaGxpZ2h0e2JhY2tncm91bmQtY29sb3I6I2EwYzBjMH06aG9zdCA6Om5nLWRlZXAgLnVpLXRhYmxlIC51aS10YWJsZS10aGVhZD50cjpsYXN0LWNoaWxke2JvcmRlci1ib3R0b206MnB4IHNvbGlkICNjNmM5Y2F9Omhvc3QgOjpuZy1kZWVwIC51aS10YWJsZSAudWktc29ydGFibGUtY29sdW1uLnVpLXN0YXRlLWhpZ2hsaWdodHtiYWNrZ3JvdW5kLWNvbG9yOiM1ZjdhNzZ9Omhvc3QgOjpuZy1kZWVwIC51aS10YWJsZSAudWktdGFibGUtdGJvZHk+dHI+dGR7Ym9yZGVyLWxlZnQ6bm9uZTtib3JkZXItcmlnaHQ6bm9uZX1gXVxufSlcblxuLy89PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PT09PVxuXG5leHBvcnQgY2xhc3MgTGlzdFRhYmxlIGV4dGVuZHMgQWJzdHJhY3RTdWJzY3JpYmVyIGltcGxlbWVudHMgT25DaGFuZ2VzIHtcblxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vLS0tXG4gICAgLy8tLS0gVmFyaWFibGVzXG4gICAgLy8tLS1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRASW5wdXQoKSByb3dJZCAgICAgICAgICA6IGFueTtcbiAgICBASW5wdXQoKSBjb2x1bW5zICAgICAgICA6IExpc3RUYWJsZUNvbHVtbltdO1xuICAgIEBJbnB1dCgpIGRhdGEgICAgICAgICAgIDogYW55W107XG4gICAgQElucHV0KCkgdmlzaWJsZUNvbHVtbnMgOiBzdHJpbmdbXTtcblx0QElucHV0KCkgbXVsdGlTZWxlY3Rpb24gOiBib29sZWFuO1xuXHRASW5wdXQoKSByb3dzUGVyUGFnZSAgICA6IG51bWJlcjtcblx0QElucHV0KCkgcm93U2V0ICAgICAgICAgOiBudW1iZXJbXTtcblx0QElucHV0KCkgbG9hZGluZyAgICAgICAgOiBib29sZWFuO1xuXHRASW5wdXQoKSBsYWJlbEdyb3VwICAgICA6IHN0cmluZztcblx0QElucHV0KCkgY29udGV4dE1lbnUgICAgOiBNZW51W107XG5cdEBJbnB1dCgpIG1lbnVTZWxlY3RvciAgIDogTWVudVNlbGVjdG9yO1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdEBPdXRwdXQoKSBvbkZpbHRlckNoYW5nZSA6IEV2ZW50RW1pdHRlcjxGaWx0ZXJDaGFuZ2VFdmVudD4gID0gbmV3IEV2ZW50RW1pdHRlcjxGaWx0ZXJDaGFuZ2VFdmVudD4oKTtcblx0QE91dHB1dCgpIG9uUm93U2VsZWN0ZWQgIDogRXZlbnRFbWl0dGVyPFJvd1NlbGVjdGVkRXZlbnQ+ICAgPSBuZXcgRXZlbnRFbWl0dGVyPFJvd1NlbGVjdGVkRXZlbnQ+KCk7XG5cdEBPdXRwdXQoKSBvblJvd1Vuc2VsZWN0ZWQ6IEV2ZW50RW1pdHRlcjxSb3dVbnNlbGVjdGVkRXZlbnQ+ID0gbmV3IEV2ZW50RW1pdHRlcjxSb3dVbnNlbGVjdGVkRXZlbnQ+KCk7XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0QFZpZXdDaGlsZCgndHQnKSBwcml2YXRlIHBUYWJsZSAgICAgICA6IERhdGFUYWJsZTtcblx0QFZpZXdDaGlsZCgnY20nKSBwcml2YXRlIHBDb250ZXh0TWVudSA6IENvbnRleHRNZW51O1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHNlbGVjdGVkUm93ICAgIDogYW55O1xuXHRkaXNwbGF5Q29sdW1ucyA6IExpc3RUYWJsZUNvbHVtbltdO1xuXHRkaXNwbGF5RGF0YSAgICA6IGFueVtdO1xuXHRhY3RpdmVNZW51ICAgICA6IE1lbnVbXTtcblxuXHQvLy0tLSBNYXAgY29udGFpbmluZyBmb3Igb25lIGNvbHVtbiBhIGxpc3Qgb2YgKGtleSwgdmFsdWUpIHBhaXJzLiBUaGUga2V5XG5cdC8vLS0tIGlzIHRoZSBhY3R1YWwgY29sdW1uJ3MgdmFsdWUgd2hpbGUgdGhlIHZhbHVlIGlzIHRoZSB0cmFuc2NvZGVkIG9uZS5cblx0Ly8tLS0gSXQgaXMgdXNlZCB0byBkaXNwbGF5IGRyb3Bkb3duIGZpbHRlcnNcblxuXHRjb2x1bW5WYWx1ZXM6IE1hcDxzdHJpbmcsIERyb3Bkb3duSXRlbVtdPjtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRwcml2YXRlIGNvbFRvSW5kZXggOiBNYXA8c3RyaW5nLCBudW1iZXI+O1xuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgYWxpZ25NYXAgPSB7XG5cdFx0J2xlZnQnICAgOiAnYWxpZ25MZWZ0Jyxcblx0XHQnY2VudGVyJyA6ICdhbGlnbkNlbnRlcicsXG5cdFx0J3JpZ2h0JyAgOiAnYWxpZ25SaWdodCdcblx0fTtcblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLy0tLVxuICAgIC8vLS0tIENvbnN0cnVjdG9yXG4gICAgLy8tLS1cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuICAgIGNvbnN0cnVjdG9yKCAgICAgICAgZXZlbnRCdXNTZXJ2aWNlIDogRXZlbnRCdXNTZXJ2aWNlLFxuICAgICAgICAgICAgICAgIHByaXZhdGUgbGFiZWxTZXJ2aWNlICAgIDogTGFiZWxTZXJ2aWNlKSB7XG5cbiAgICBcdHN1cGVyKGV2ZW50QnVzU2VydmljZSk7XG5cbiAgICBcdHRoaXMucm93c1BlclBhZ2UgICAgPSA4O1xuXHRcdHRoaXMucm93U2V0ICAgICAgICAgPSBbNCwgOCwgMTIsIDE2LCAyMCwgNTBdO1xuXHRcdHRoaXMubG9hZGluZyAgICAgICAgPSBmYWxzZTtcblx0XHR0aGlzLm11bHRpU2VsZWN0aW9uID0gZmFsc2U7XG5cdH1cblxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuICAgIC8vLS0tXG4gICAgLy8tLS0gQVBJIG1ldGhvZHNcbiAgICAvLy0tLVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHB1YmxpYyBleHBvcnRBbGwoKSA6IHZvaWQge1xuXHRcdHRoaXMucFRhYmxlLmV4cG9ydENTVigpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0cHVibGljIGV4cG9ydFNlbGVjdGVkKCkgOiB2b2lkIHtcblx0XHR0aGlzLnBUYWJsZS5leHBvcnRDU1Yoe3NlbGVjdGlvbk9ubHk6dHJ1ZX0pO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tIExvY2FsaXphdGlvbiBtZXRob2RzXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdGdldCBhbGxWYWx1ZSgpIDogc3RyaW5nIHtcblx0XHRyZXR1cm4gdGhpcy5sYWJlbFNlcnZpY2UuZ2V0TGFiZWwoXCJsaXN0LXRhYmxlXCIsIFwiYWxsXCIpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0Z2V0IG5vUmVjb3JkcygpIDogc3RyaW5nIHtcblx0XHRyZXR1cm4gdGhpcy5sYWJlbFNlcnZpY2UuZ2V0TGFiZWwoXCJsaXN0LXRhYmxlXCIsIFwibm9SZWNvcmRzXCIpO1xuXHR9XG5cbiAgICAvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cbiAgICAvLy0tLVxuICAgIC8vLS0tIExpZmVjeWNsZSBldmVudHNcbiAgICAvLy0tLVxuICAgIC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpIHtcblxuICAgIFx0bGV0IHJlYnVpbGRDb2x1bW5WYWx1ZXMgOiBib29sZWFuID0gZmFsc2U7XG5cblx0XHRpZiAoY2hhbmdlc1tcImNvbHVtbnNcIl0pIHtcblx0XHRcdHRoaXMuaW5pdENvbHVtbnMoKTtcblx0XHRcdHJlYnVpbGRDb2x1bW5WYWx1ZXMgPSB0cnVlO1xuXHRcdH1cblxuXHRcdGlmIChjaGFuZ2VzW1wiZGF0YVwiXSkge1xuXHRcdFx0dGhpcy5pbml0RGF0YSgpO1xuXHRcdFx0cmVidWlsZENvbHVtblZhbHVlcyA9IHRydWU7XG5cdFx0fVxuXG5cdFx0aWYgKGNoYW5nZXNbXCJ2aXNpYmxlQ29sdW1uc1wiXSkge1xuXHRcdFx0dGhpcy5pbml0VmlzaWJsZUNvbHVtbnMoKTtcblx0XHR9XG5cblx0XHRpZiAocmVidWlsZENvbHVtblZhbHVlcykge1xuXHRcdFx0dGhpcy5pbml0Q29sdW1uVmFsdWVzKCk7XG5cdFx0fVxuXHRcdC8vXHRcdFwibGFiZWxzXCIgPz8/XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gRXZlbnRzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG4gICAgb25Sb3dTZWxlY3QoZXZlbnQgOiBhbnkpIHtcblxuXHRcdC8vLS0tIEluIGNhc2Ugb2YgbXVsdGktc2VsZWN0aW9uLCB0aGUgc2VsZWN0ZWRSb3cgdmFyaWFibGUgaXMgYW4gYXJyYXkgb2Ygcm93c1xuXHRcdGxldCByb3cgOiBhbnkgID0gdGhpcy5yZXN0b3JlUm93KGV2ZW50LmRhdGEpO1xuXHRcdGxldCByb3dzOiBhbnlbXT0gdGhpcy5jYWxjU2VsZWN0ZWRSb3dzKHRoaXMuc2VsZWN0ZWRSb3cpO1xuXG5cdFx0dGhpcy5vblJvd1NlbGVjdGVkLmVtaXQobmV3IFJvd1NlbGVjdGVkRXZlbnQocm93LCByb3dzKSk7XG4gICAgfVxuXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdG9uUm93VW5zZWxlY3QoZXZlbnQgOiBhbnkpIHtcblxuXHRcdC8vLS0tIEluIGNhc2Ugb2YgbXVsdGktc2VsZWN0aW9uLCB0aGUgc2VsZWN0ZWRSb3cgdmFyaWFibGUgaXMgYW4gYXJyYXkgb2Ygcm93c1xuXHRcdGxldCByb3cgOiBhbnkgID0gdGhpcy5yZXN0b3JlUm93KGV2ZW50LmRhdGEpO1xuXHRcdGxldCByb3dzOiBhbnlbXT0gdGhpcy5jYWxjU2VsZWN0ZWRSb3dzKHRoaXMuc2VsZWN0ZWRSb3cpO1xuXG5cdFx0dGhpcy5vblJvd1Vuc2VsZWN0ZWQuZW1pdChuZXcgUm93VW5zZWxlY3RlZEV2ZW50KHJvdywgcm93cykpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0b25Db250ZXh0TWVudVNlbGVjdChldmVudCkge1xuXG5cdFx0Ly8tLS0gSW4gY2FzZSBvZiBtdWx0aS1zZWxlY3Rpb24sIHRoZSBzZWxlY3RlZFJvdyB2YXJpYWJsZSBpcyBhbiBhcnJheSBvZiByb3dzXG5cdFx0bGV0IHJvdyAgPSB0aGlzLnJlc3RvcmVSb3coZXZlbnQuZGF0YSk7XG5cdFx0bGV0IHJvd3MgPSB0aGlzLmNhbGNTZWxlY3RlZFJvd3ModGhpcy5zZWxlY3RlZFJvdyk7XG5cdFx0bGV0IHJzZSAgPSBuZXcgUm93U2VsZWN0ZWRFdmVudChyb3csIHJvd3MpO1xuXG4gICAgXHQvLy0tLSBFbWl0IGV2ZW50XG5cdFx0dGhpcy5vblJvd1NlbGVjdGVkLmVtaXQocnNlKTtcblxuXHRcdC8vLS0tIFNldHVwIGNvbnRleHQgbWVudVxuXG4gICAgXHR0aGlzLmFjdGl2ZU1lbnUgPSB0aGlzLnNlbGVjdE1lbnVJdGVtcyh0aGlzLmNvbnRleHRNZW51LCByc2UsIG51bGwpO1xuICAgIH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblxuXHRvbkZpbHRlcihldmVudCkge1xuXHRcdHRoaXMub25GaWx0ZXJDaGFuZ2UuZW1pdChuZXcgRmlsdGVyQ2hhbmdlRXZlbnQodGhpcy5nZXRGaWx0ZXJlZFNpemUoKSkpO1xuXHR9XG5cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cdC8vLS0tXG5cdC8vLS0tIExvY2FsIG1ldGhvZHNcblx0Ly8tLS1cblx0Ly8tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tXG5cblx0ZmlsdGVyKHZhbHVlIDogYW55LCBjb2wgOiBMaXN0VGFibGVDb2x1bW4pIHtcblx0XHR0aGlzLnBUYWJsZS5maWx0ZXIodmFsdWUsIGNvbC5maWVsZCwgY29sLmZpbHRlck1hdGNoTW9kZSk7XG5cdH1cblxuXHQvLy0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1cblx0Ly8tLS1cblx0Ly8tLS0gUHJpdmF0ZSBtZXRob2RzXG5cdC8vLS0tXG5cdC8vLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLVxuXG5cdHByaXZhdGUgaW5pdENvbHVtbnMoKSA6IHZvaWQge1xuXG5cdFx0Y29uc29sZS5sb2coXCJJbml0aWFsaXppbmcgY29sdW1ucyA6I