angular2-collapsible
Version:
Angular collapsible component styled with Materialize CSS.
601 lines (593 loc) • 62 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/collapsible-table/collapsible-table.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, HostBinding, HostListener, ElementRef, ContentChildren } from '@angular/core';
import { CollapsibleTableRowComponent } from '../collapsible-table-row/collapsible-table-row.component';
import { CollapsibleService } from '../services/collapsible.service';
export class CollapsibleTableComponent {
/**
* @param {?} el
* @param {?} collapsibleService
*/
constructor(el, collapsibleService) {
this.el = el;
this.collapsibleService = collapsibleService;
// allows navigation between table rows using arrow keys
this.allowKeyboardNavigation = true;
this.fixedTableHeight = 'auto';
this.tabindex = 0;
this.selectedRows = [];
// specifies collapsible type. Can be either 'accordion' or 'expandable'
this.type = 'accordion';
this.mouseDownHold = false;
}
/**
* @return {?}
*/
ngOnInit() {
}
/**
* @return {?}
*/
ngAfterContentInit() {
// this.updateFixedTableHeight();
/*
LOG(`CollapsibleTableComponent::ngOnInit()\n` +
`this = {\n` +
`bordered = ${this.bordered}\n` +
`borderedHorizontally = ${this.borderedHorizontally}\n` +
`borderedVertically = ${this.borderedVertically}\n` +
`striped = ${this.striped}\n` +
`stripedOddColor = ${this.stripedOddColor}\n` +
`stripedEvenColor = ${this.stripedEvenColor}\n` +
`highlight = ${this.highlight}\n` +
`highlightColor = ${this.highlightColor}\n` +
`highlightTextColor = ${this.highlightTextColor}\n` +
`activeColor = ${this.activeColor}\n` +
`activeTextColor = ${this.activeTextColor}\n` +
`centered = ${this.centered}\n` +
`responsive = ${this.responsive}\n` +
`select = ${this.select}\n` +
`selectColor = ${this.selectColor}\n` +
`selectTextColor = ${this.selectTextColor}\n` +
`selectMultipleRows = ${this.selectMultipleRows}\n` +
`noTextSelect = ${this.noTextSelect}\n` +
`}`);
*/
}
/**
* @param {?} changes
* @return {?}
*/
ngOnChanges(changes) {
for (const change in changes) {
if (changes.hasOwnProperty(change)) {
if (this.collapsibleTableRows != null) {
switch (change) {
case 'striped':
case 'stripedOddColor':
case 'stripedOddTextColor':
case 'stripedEvenColor':
case 'stripedEvenTextColor':
this.updateTable('striped');
break;
case 'highlight':
case 'highlightColor':
case 'highlightTextColor':
this.updateTable('highlight');
break;
case 'activeColor':
case 'activeTextColor':
this.updateTable('active');
break;
case 'select':
case 'selectColor':
case 'selectTextColor':
case 'selectMultipleRows':
case 'allowDeselectingRows':
this.updateTable('select');
break;
}
}
// update collapsible table type in CollapsibleService
if (change === 'type') {
this.type = changes.type.currentValue;
this.collapsibleService.setType(this.type);
}
}
}
this.collapsibleService.setCollapsibleTable(this);
}
/**
* @return {?}
*/
focus() {
this.el.nativeElement.focus();
}
/**
* @param {?} index
* @return {?}
*/
addSelectedRow(index) {
switch (true) {
case this.selectMultipleRows && this.selectedRows.indexOf(index) === -1:
this.selectedRows.push(index);
this.selectedRows.sort((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
(a, b) => a - b));
break;
case !this.selectMultipleRows:
this.selectedRows = [];
this.deselectAllRows();
this.selectedRows.push(index);
this.selectedRows.sort((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
(a, b) => a - b));
break;
}
}
/**
* @param {?} index
* @return {?}
*/
removeSelectedRow(index) {
if (this.selectedRows.indexOf(index) !== -1) {
this.selectedRows.splice(this.selectedRows.indexOf(index), 1);
}
}
/**
* @return {?}
*/
clearSelectedRows() {
this.selectedRows = [];
}
/**
* @return {?}
*/
deselectAllRows() {
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @return {?}
*/
row => {
row.selected = false;
row.updateRow();
}));
}
/**
* @param {?} index
* @return {?}
*/
selectRow(index) {
if (this.select) {
switch (true) {
case index === 0:
this.selectRow(1);
break;
case index === this.collapsibleTableRows.length:
this.selectRow(this.collapsibleTableRows.length - 1);
break;
case 0 < index && index <= this.collapsibleTableRows.length - 1:
this.addSelectedRow(index);
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @param {?} i
* @return {?}
*/
(row, i) => {
if (index !== i) {
if (!this.selectMultipleRows) {
row.selected = false;
}
}
else {
row.selected = true;
}
row.updateRow();
}));
break;
}
}
}
/**
* @param {?} firstRowIndex
* @param {?} lastRowIndex
* @return {?}
*/
selectRows(firstRowIndex, lastRowIndex) {
if (this.selectMultipleRows &&
0 < firstRowIndex && firstRowIndex < lastRowIndex &&
lastRowIndex <= this.collapsibleTableRows.length - 1) {
this.clearSelectedRows();
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @param {?} i
* @return {?}
*/
(row, i) => {
if (firstRowIndex <= i && i <= lastRowIndex) {
this.addSelectedRow(i);
row.selected = true;
}
else {
row.selected = false;
}
row.updateRow();
}));
}
}
/**
* @param {?} index
* @return {?}
*/
toggleRowSelection(index) {
if (this.select &&
0 < index && index <= this.collapsibleTableRows.length - 1) {
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @param {?} i
* @return {?}
*/
(row, i) => {
if (index === i) {
if (row.selected) {
this.removeSelectedRow(index);
}
else {
this.addSelectedRow(index);
}
row.selected = !row.selected;
row.updateRow();
}
}));
}
}
/*updateFixedTableHeight() {
this.fixedTableHeight = this.el.nativeElement.offsetHeight + 'px';
let elem: Element = this.el.nativeElement;
let rowHeights = 0;
if (this.collapsibleTableRowComponent != null) {
this.collapsibleTableRowComponent.forEach(row => {
});
}
}*/
/**
* @param {?} row
* @return {?}
*/
updateStriped(row) {
if (this.striped && row.isBodyRow) {
row.isParentStriped = true;
if (row.isOddRow) {
row.parentStripedRowBackgroundColor = this.stripedOddColor || CollapsibleTableRowComponent.DEFAULT_STRIPED_ODD_ROW_COLOR;
row.parentStripedRowTextColor = this.stripedOddTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
row.rowBackgroundColor = row.parentStripedRowBackgroundColor;
row.rowTextColor = row.parentStripedRowTextColor;
}
else {
row.parentStripedRowBackgroundColor = this.stripedEvenColor || CollapsibleTableRowComponent.DEFAULT_STRIPED_EVEN_ROW_COLOR;
row.parentStripedRowTextColor = this.stripedEvenTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
row.rowBackgroundColor = row.parentStripedRowBackgroundColor;
row.rowTextColor = row.parentStripedRowTextColor;
}
}
else {
row.isParentStriped = false;
row.rowBackgroundColor = undefined;
row.rowTextColor = undefined;
}
}
/**
* @param {?} row
* @return {?}
*/
updateHighlight(row) {
row.isParentHighlight = this.highlight;
row.parentHighlightRowBackgroundColor = this.highlightColor || CollapsibleTableRowComponent.DEFAULT_HIGHLIGHT_ROW_COLOR;
row.parentHighlightRowTextColor = this.highlightTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
}
/**
* @param {?} row
* @return {?}
*/
updateActive(row) {
row.activeRowBackgroundColor = this.activeColor || CollapsibleTableRowComponent.DEFAULT_ACTIVE_ROW_COLOR;
row.activeRowTextColor = this.activeTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
}
/**
* @param {?} row
* @return {?}
*/
updateSelect(row) {
row.parentAllowsSelect = this.select;
row.parentAllowsSelectMultipleRows = this.selectMultipleRows;
row.parentAllowsDeselectingRows = this.allowDeselectingRows;
if (row.selected) {
row.selectedRowBackgroundColor = this.selectColor || CollapsibleTableRowComponent.DEFAULT_SELECTED_ROW_COLOR;
row.selectedRowTextColor = this.selectTextColor || CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
row.rowBackgroundColor = row.selectedRowBackgroundColor;
row.rowTextColor = row.selectedRowTextColor;
}
}
/**
* @param {?=} change
* @return {?}
*/
updateTable(change) {
if (this.collapsibleTableRows != null) {
if (change != null) {
switch (change) {
case 'striped':
// propagate changes to each of the CollapsibleTableRowComponent children
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @return {?}
*/
row => { this.updateStriped(row); }));
break;
case 'highlight':
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @return {?}
*/
row => { this.updateHighlight(row); }));
break;
case 'active':
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @return {?}
*/
row => { this.updateActive(row); }));
break;
case 'select':
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @return {?}
*/
row => { this.updateSelect(row); }));
break;
}
}
else {
// propagate changes to each of the CollapsibleTableRowComponent children
this.collapsibleTableRows.forEach((/**
* @param {?} row
* @return {?}
*/
row => {
this.updateStriped(row);
this.updateHighlight(row);
this.updateSelect(row);
this.updateActive(row);
}));
}
}
}
/**
* @param {?} event
* @return {?}
*/
keydown(event) {
// select a row only if 'select' property is set to 'true'
if (this.select && this.allowKeyboardNavigation) {
/** @enum {number} */
const Key = {
arrowUp: 38,
arrowDown: 40,
home: 36,
end: 35,
};
Key[Key.arrowUp] = 'arrowUp';
Key[Key.arrowDown] = 'arrowDown';
Key[Key.home] = 'home';
Key[Key.end] = 'end';
/** @type {?} */
let index = 1;
/** @type {?} */
const whichKey = event['which'];
if (Key[whichKey] != null) {
event.preventDefault();
event.stopPropagation();
switch (whichKey) {
case Key.arrowUp:
// select previous row
if (this.selectedRows.length > 0) {
index = this.selectedRows[this.selectedRows.length - 1];
index--;
}
break;
case Key.arrowDown:
// select next row
if (this.selectedRows.length > 0) {
index = this.selectedRows[this.selectedRows.length - 1];
index++;
}
break;
case Key.home:
index = 1;
break;
case Key.end:
index = this.collapsibleTableRows.length - 1;
break;
}
this.clearSelectedRows();
this.deselectAllRows();
this.selectRow(index);
this.updateTable();
}
}
}
/**
* @return {?}
*/
mousedown() {
this.mouseDownHold = true;
}
/**
* @return {?}
*/
mouseup() {
this.mouseDownHold = false;
}
}
CollapsibleTableComponent.decorators = [
{ type: Component, args: [{
selector: 'collapsible-table',
template: `<ng-content></ng-content>`,
providers: [
CollapsibleService
],
styles: [`
:host {
display: table;
position: relative;
width: 100%;
border-collapse: collapse;
}
:host thead {
border-bottom: 1px solid #d0d0d0;
}
:host /deep/ tbody /deep/ collapsible-table-row {
cursor: pointer;
}
:host /deep/ collapsible-table-row th,
:host /deep/ collapsible-table-row td {
border-radius: 0;
}
:host[bordered='true'] {
border-top: 1px solid #d0d0d0;
border-right: 1px solid #d0d0d0;
border-left: 1px solid #d0d0d0;
}
:host[bordered='true'] /deep/ collapsible-table-row,
:host[borderedHorizontally='true'] /deep/ collapsible-table-row {
border-bottom: 1px solid #d0d0d0;
}
:host[bordered='true'] /deep/ collapsible-table-row th,
:host[bordered='true'] /deep/ collapsible-table-row td,
:host[borderedVertically='true'] /deep/ collapsible-table-row th:not(:last-child),
:host[borderedVertically='true'] /deep/ collapsible-table-row td:not(:last-child) {
border-right: 1px solid #d0d0d0;
}
:host(.centered) /deep/ * {
text-align: center;
}
:host(.noTextSelect) /deep/ collapsible-table-row th,
:host(.noTextSelect) /deep/ collapsible-table-row td {
user-select: none;
}
`]
}] }
];
/** @nocollapse */
CollapsibleTableComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: CollapsibleService }
];
CollapsibleTableComponent.propDecorators = {
bordered: [{ type: Input }, { type: HostBinding, args: ['attr.bordered',] }],
borderedHorizontally: [{ type: Input }, { type: HostBinding, args: ['attr.borderedHorizontally',] }],
borderedVertically: [{ type: Input }, { type: HostBinding, args: ['attr.borderedVertically',] }],
striped: [{ type: Input }, { type: HostBinding, args: ['attr.striped',] }],
stripedOddColor: [{ type: Input }, { type: HostBinding, args: ['attr.stripedOddColor',] }],
stripedOddTextColor: [{ type: Input }, { type: HostBinding, args: ['attr.stripedOddTextColor',] }],
stripedEvenColor: [{ type: Input }, { type: HostBinding, args: ['attr.stripedEvenColor',] }],
stripedEvenTextColor: [{ type: Input }, { type: HostBinding, args: ['attr.stripedEvenTextColor',] }],
highlight: [{ type: Input }, { type: HostBinding, args: ['attr.highlight',] }],
highlightColor: [{ type: Input }, { type: HostBinding, args: ['attr.highlightColor',] }],
highlightTextColor: [{ type: Input }, { type: HostBinding, args: ['attr.highlightTextColor',] }],
activeColor: [{ type: Input }, { type: HostBinding, args: ['attr.activeColor',] }],
activeTextColor: [{ type: Input }, { type: HostBinding, args: ['attr.activeTextColor',] }],
centered: [{ type: Input }, { type: HostBinding, args: ['class.centered',] }, { type: HostBinding, args: ['attr.centered',] }],
responsive: [{ type: Input }, { type: HostBinding, args: ['attr.responsive',] }],
select: [{ type: Input }, { type: HostBinding, args: ['attr.select',] }],
selectMultipleRows: [{ type: Input }, { type: HostBinding, args: ['attr.selectMultipleRows',] }],
selectColor: [{ type: Input }, { type: HostBinding, args: ['attr.selectColor',] }],
selectTextColor: [{ type: Input }, { type: HostBinding, args: ['attr.selectTextColor',] }],
allowDeselectingRows: [{ type: Input }, { type: HostBinding, args: ['attr.allowDeselectingRows',] }],
allowKeyboardNavigation: [{ type: Input }, { type: HostBinding, args: ['attr.allowKeyboardNavigation',] }],
noTextSelect: [{ type: Input }, { type: HostBinding, args: ['class.noTextSelect',] }, { type: HostBinding, args: ['attr.noTextSelect',] }],
tabindex: [{ type: HostBinding, args: ['attr.tabindex',] }],
type: [{ type: Input }, { type: HostBinding, args: ['attr.type',] }],
collapsibleTableRows: [{ type: ContentChildren, args: [CollapsibleTableRowComponent,] }],
keydown: [{ type: HostListener, args: ['keydown', ['$event'],] }],
mousedown: [{ type: HostListener, args: ['mousedown',] }],
mouseup: [{ type: HostListener, args: ['mouseup',] }]
};
if (false) {
/** @type {?} */
CollapsibleTableComponent.prototype.bordered;
/** @type {?} */
CollapsibleTableComponent.prototype.borderedHorizontally;
/** @type {?} */
CollapsibleTableComponent.prototype.borderedVertically;
/** @type {?} */
CollapsibleTableComponent.prototype.striped;
/** @type {?} */
CollapsibleTableComponent.prototype.stripedOddColor;
/** @type {?} */
CollapsibleTableComponent.prototype.stripedOddTextColor;
/** @type {?} */
CollapsibleTableComponent.prototype.stripedEvenColor;
/** @type {?} */
CollapsibleTableComponent.prototype.stripedEvenTextColor;
/** @type {?} */
CollapsibleTableComponent.prototype.highlight;
/** @type {?} */
CollapsibleTableComponent.prototype.highlightColor;
/** @type {?} */
CollapsibleTableComponent.prototype.highlightTextColor;
/** @type {?} */
CollapsibleTableComponent.prototype.activeColor;
/** @type {?} */
CollapsibleTableComponent.prototype.activeTextColor;
/** @type {?} */
CollapsibleTableComponent.prototype.centered;
/** @type {?} */
CollapsibleTableComponent.prototype.responsive;
/** @type {?} */
CollapsibleTableComponent.prototype.select;
/** @type {?} */
CollapsibleTableComponent.prototype.selectMultipleRows;
/** @type {?} */
CollapsibleTableComponent.prototype.selectColor;
/** @type {?} */
CollapsibleTableComponent.prototype.selectTextColor;
/** @type {?} */
CollapsibleTableComponent.prototype.allowDeselectingRows;
/** @type {?} */
CollapsibleTableComponent.prototype.allowKeyboardNavigation;
/** @type {?} */
CollapsibleTableComponent.prototype.noTextSelect;
/** @type {?} */
CollapsibleTableComponent.prototype.fixedTableHeight;
/** @type {?} */
CollapsibleTableComponent.prototype.tabindex;
/** @type {?} */
CollapsibleTableComponent.prototype.selectedRows;
/** @type {?} */
CollapsibleTableComponent.prototype.type;
/** @type {?} */
CollapsibleTableComponent.prototype.collapsibleTableRows;
/** @type {?} */
CollapsibleTableComponent.prototype.mouseDownHold;
/**
* @type {?}
* @private
*/
CollapsibleTableComponent.prototype.el;
/**
* @type {?}
* @private
*/
CollapsibleTableComponent.prototype.collapsibleService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGFwc2libGUtdGFibGUuY29tcG9uZW50LmpzIiwic291cmNlUm9vdCI6Im5nOi8vYW5ndWxhcjItY29sbGFwc2libGUvIiwic291cmNlcyI6WyJsaWIvY29sbGFwc2libGUtdGFibGUvY29sbGFwc2libGUtdGFibGUuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFFVCxLQUFLLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFDaEMsVUFBVSxFQUFFLGVBQWUsRUFDOUIsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUFFLDRCQUE0QixFQUFFLE1BQU0sMERBQTBELENBQUM7QUFDeEcsT0FBTyxFQUFFLGtCQUFrQixFQUFFLE1BQU0saUNBQWlDLENBQUM7QUF5RHJFLE1BQU0sT0FBTyx5QkFBeUI7Ozs7O0lBNEdsQyxZQUNZLEVBQWMsRUFDZCxrQkFBc0M7UUFEdEMsT0FBRSxHQUFGLEVBQUUsQ0FBWTtRQUNkLHVCQUFrQixHQUFsQixrQkFBa0IsQ0FBb0I7O1FBdkJsRCw0QkFBdUIsR0FBRyxJQUFJLENBQUM7UUFPL0IscUJBQWdCLEdBQUcsTUFBTSxDQUFDO1FBRUksYUFBUSxHQUFHLENBQUMsQ0FBQztRQUUzQyxpQkFBWSxHQUFrQixFQUFFLENBQUM7O1FBSVAsU0FBSSxHQUErQixXQUFXLENBQUM7UUFJekUsa0JBQWEsR0FBRyxLQUFLLENBQUM7SUFJZ0MsQ0FBQzs7OztJQUV2RCxRQUFRO0lBQ1IsQ0FBQzs7OztJQUVELGtCQUFrQjtRQUNkLGlDQUFpQztRQUNqQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztjQXNCTTtJQUNWLENBQUM7Ozs7O0lBRUQsV0FBVyxDQUFDLE9BQXNCO1FBQzlCLEtBQUssTUFBTSxNQUFNLElBQUksT0FBTyxFQUFFO1lBQzFCLElBQUksT0FBTyxDQUFDLGNBQWMsQ0FBQyxNQUFNLENBQUMsRUFBRTtnQkFDaEMsSUFBSSxJQUFJLENBQUMsb0JBQW9CLElBQUksSUFB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ckQsb0RBQzZEOztJQUc3RCx5REFDd0U7O0lBR3hFLDREQUUrQjs7SUFHL0IsaURBRXdEOztJQUV4RCxxREFBMEI7O0lBRTFCLDZDQUEyQzs7SUFFM0MsaURBQWlDOztJQUdqQyx5Q0FDeUU7O0lBRXpFLHlEQUF5Rzs7SUFFekcsa0RBQXNCOzs7OztJQUdsQix1Q0FBc0I7Ozs7O0lBQ3RCLHVEQUE4QyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XHJcbiAgICBDb21wb25lbnQsXHJcbiAgICBPbkluaXQsIE9uQ2hhbmdlcywgU2ltcGxlQ2hhbmdlcywgQWZ0ZXJDb250ZW50SW5pdCxcclxuICAgIElucHV0LCBIb3N0QmluZGluZywgSG9zdExpc3RlbmVyLFxyXG4gICAgRWxlbWVudFJlZiwgQ29udGVudENoaWxkcmVuXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcblxyXG5pbXBvcnQgeyBDb2xsYXBzaWJsZVRhYmxlUm93Q29tcG9uZW50IH0gZnJvbSAnLi4vY29sbGFwc2libGUtdGFibGUtcm93L2NvbGxhcHNpYmxlLXRhYmxlLXJvdy5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb2xsYXBzaWJsZVNlcnZpY2UgfSBmcm9tICcuLi9zZXJ2aWNlcy9jb2xsYXBzaWJsZS5zZXJ2aWNlJztcclxuXHJcbkBDb21wb25lbnQoe1xyXG4gICAgc2VsZWN0b3I6ICdjb2xsYXBzaWJsZS10YWJsZScsXHJcbiAgICB0ZW1wbGF0ZTogYDxuZy1jb250ZW50PjwvbmctY29udGVudD5gLFxyXG4gICAgc3R5bGVzOiBbYFxyXG4gICAgICAgIDpob3N0IHtcclxuICAgICAgICAgICAgZGlzcGxheTogdGFibGU7XHJcbiAgICAgICAgICAgIHBvc2l0aW9uOiByZWxhdGl2ZTtcclxuICAgICAgICAgICAgd2lkdGg6IDEwMCU7XHJcbiAgICAgICAgICAgIGJvcmRlci1jb2xsYXBzZTogY29sbGFwc2U7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICA6aG9zdCB0aGVhZCB7XHJcbiAgICAgICAgICAgIGJvcmRlci1ib3R0b206IDFweCBzb2xpZCAjZDBkMGQwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgOmhvc3QgL2RlZXAvIHRib2R5IC9kZWVwLyBjb2xsYXBzaWJsZS10YWJsZS1yb3cge1xyXG4gICAgICAgICAgICBjdXJzb3I6IHBvaW50ZXI7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICA6aG9zdCAvZGVlcC8gY29sbGFwc2libGUtdGFibGUtcm93IHRoLFxyXG4gICAgICAgIDpob3N0IC9kZWVwLyBjb2xsYXBzaWJsZS10YWJsZS1yb3cgdGQge1xyXG4gICAgICAgICAgICBib3JkZXItcmFkaXVzOiAwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgOmhvc3RbYm9yZGVyZWQ9J3RydWUnXSB7XHJcbiAgICAgICAgICAgIGJvcmRlci10b3A6IDFweCBzb2xpZCAjZDBkMGQwO1xyXG4gICAgICAgICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZDBkMGQwO1xyXG4gICAgICAgICAgICBib3JkZXItbGVmdDogMXB4IHNvbGlkICNkMGQwZDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICA6aG9zdFtib3JkZXJlZD0ndHJ1ZSddIC9kZWVwLyBjb2xsYXBzaWJsZS10YWJsZS1yb3csXHJcbiAgICAgICAgOmhvc3RbYm9yZGVyZWRIb3Jpem9udGFsbHk9J3RydWUnXSAvZGVlcC8gY29sbGFwc2libGUtdGFibGUtcm93IHtcclxuICAgICAgICAgICAgYm9yZGVyLWJvdHRvbTogMXB4IHNvbGlkICNkMGQwZDA7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICA6aG9zdFtib3JkZXJlZD0ndHJ1ZSddIC9kZWVwLyBjb2xsYXBzaWJsZS10YWJsZS1yb3cgdGgsXHJcbiAgICAgICAgOmhvc3RbYm9yZGVyZWQ9J3RydWUnXSAvZGVlcC8gY29sbGFwc2libGUtdGFibGUtcm93IHRkLFxyXG4gICAgICAgIDpob3N0W2JvcmRlcmVkVmVydGljYWxseT0ndHJ1ZSddIC9kZWVwLyBjb2xsYXBzaWJsZS10YWJsZS1yb3cgdGg6bm90KDpsYXN0LWNoaWxkKSxcclxuICAgICAgICA6aG9zdFtib3JkZXJlZFZlcnRpY2FsbHk9J3RydWUnXSAvZGVlcC8gY29sbGFwc2libGUtdGFibGUtcm93IHRkOm5vdCg6bGFzdC1jaGlsZCkge1xyXG4gICAgICAgICAgICBib3JkZXItcmlnaHQ6IDFweCBzb2xpZCAjZDBkMGQwO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgOmhvc3QoLmNlbnRlcmVkKSAvZGVlcC8gKiB7XHJcbiAgICAgICAgICAgIHRleHQtYWxpZ246IGNlbnRlcjtcclxuICAgICAgICB9XHJcblxyXG4gICAgICAgIDpob3N0KC5ub1RleHRTZWxlY3QpIC9kZWVwLyBjb2xsYXBzaWJsZS10YWJsZS1yb3cgdGgsXHJcbiAgICAgICAgOmhvc3QoLm5vVGV4dFNlbGVjdCkgL2RlZXAvIGNvbGxhcHNpYmxlLXRhYmxlLXJvdyB0ZCB7XHJcbiAgICAgICAgICAgIHVzZXItc2VsZWN0OiBub25lO1xyXG4gICAgICAgIH1cclxuICAgIGBdLFxyXG4gICAgcHJvdmlkZXJzOiBbXHJcbiAgICAgICAgQ29sbGFwc2libGVTZXJ2aWNlXHJcbiAgICBdXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBDb2xsYXBzaWJsZVRhYmxlQ29tcG9uZW50IGltcGxlbWVudHMgT25Jbml0LCBPbkNoYW5nZXMsIEFmdGVyQ29udGVudEluaXQge1xyXG4gICAgLy8gY29tcG9uZW50IG9wdGlvbnNcclxuICAgIC8vXHJcbiAgICAvLyBtYWtlcyB0aGUgdGFibGUgYm9yZGVyZWRcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYm9yZGVyZWQnKSBib3JkZXJlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvLyBtYWtlcyB0aGUgdGFibGUgYm9yZGVyZWQgaG9yaXpvbnRhbGx5IG9ubHlcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYm9yZGVyZWRIb3Jpem9udGFsbHknKSBib3JkZXJlZEhvcml6b250YWxseTogYm9vbGVhbjtcclxuXHJcbiAgICAvLyBtYWtlcyB0aGUgdGFibGUgYm9yZGVyZWQgdmVydGljYWxseSBvbmx5XHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmJvcmRlcmVkVmVydGljYWxseScpIGJvcmRlcmVkVmVydGljYWxseTogYm9vbGVhbjtcclxuXHJcbiAgICAvLyBtYWtlcyB0aGUgdGFibGUgc3RyaXBlZFxyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnYXR0ci5zdHJpcGVkJykgc3RyaXBlZDogYm9vbGVhbjtcclxuXHJcbiAgICAvLyBhIGNvbG9yIG9mIGFuIG9kZCBzdHJpcGVkIHJvd1xyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnYXR0ci5zdHJpcGVkT2RkQ29sb3InKSBzdHJpcGVkT2RkQ29sb3I6IHN0cmluZztcclxuXHJcbiAgICAvLyBhIHRleHQgY29sb3Igb2YgYW4gb2RkIHN0cmlwZWQgcm93XHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLnN0cmlwZWRPZGRUZXh0Q29sb3InKSBzdHJpcGVkT2RkVGV4dENvbG9yOiBzdHJpbmc7XHJcblxyXG4gICAgLy8gYSBjb2xvciBvZiBhbiBldmVuIHN0cmlwZWQgcm93XHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLnN0cmlwZWRFdmVuQ29sb3InKSBzdHJpcGVkRXZlbkNvbG9yOiBzdHJpbmc7XHJcblxyXG4gICAgLy8gYSB0ZXh0IGNvbG9yIG9mIGFuIGV2ZW4gc3RyaXBlZCByb3dcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuc3RyaXBlZEV2ZW5UZXh0Q29sb3InKSBzdHJpcGVkRXZlblRleHRDb2xvcjogc3RyaW5nO1xyXG5cclxuICAgIC8vIGhpZ2hsaWdodCB0YWJsZSByb3dzIG9uIG1vdXNlIGhvdmVyXHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmhpZ2hsaWdodCcpIGhpZ2hsaWdodDogYm9vbGVhbjtcclxuXHJcbiAgICAvLyBhIGNvbG9yIG9mIGEgaGlnaGxpZ2h0ZWQgcm93XHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmhpZ2hsaWdodENvbG9yJykgaGlnaGxpZ2h0Q29sb3I6IHN0cmluZztcclxuXHJcbiAgICAvLyBhIHRleHQgY29sb3Igb2YgYSBoaWdobGlnaHRlZCByb3dcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuaGlnaGxpZ2h0VGV4dENvbG9yJykgaGlnaGxpZ2h0VGV4dENvbG9yOiBzdHJpbmc7XHJcblxyXG4gICAgLy8gYSBjb2xvciBvZiBhbiBhY3RpdmUgcm93XHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFjdGl2ZUNvbG9yJykgYWN0aXZlQ29sb3I6IHN0cmluZztcclxuXHJcbiAgICAvLyBhIHRleHQgY29sb3Igb2YgYW4gYWN0aXZlIHJvd1xyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnYXR0ci5hY3RpdmVUZXh0Q29sb3InKSBhY3RpdmVUZXh0Q29sb3I6IHN0cmluZztcclxuXHJcbiAgICAvLyBjZW50ZXIgYWxpZ24gYWxsIHRoZSB0ZXh0IGluIHRoZSB0YWJsZVxyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnY2xhc3MuY2VudGVyZWQnKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmNlbnRlcmVkJykgY2VudGVyZWQ6IGJvb2xlYW47XHJcblxyXG4gICAgLy8gbWFrZXMgdGhlIHRhYmxlIGhvcml6b250YWxseSBzY3JvbGxhYmxlIG9uIHNtYWxsZXIgc2NyZWVuIHdpZHRoc1xyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnYXR0ci5yZXNwb25zaXZlJykgcmVzcG9uc2l2ZTogYm9vbGVhbjtcclxuXHJcbiAgICAvLyBhbGxvd3MgdG8gc2VsZWN0IHJvd3NcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuc2VsZWN0Jykgc2VsZWN0OiBib29sZWFuO1xyXG5cclxuICAgIC8vIGFsbG93cyB0byBzZWxlY3QgbXVsdGlwbGUgcm93c1xyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnYXR0ci5zZWxlY3RNdWx0aXBsZVJvd3MnKSBzZWxlY3RNdWx0aXBsZVJvd3M6IGJvb2xlYW47XHJcblxyXG4gICAgLy8gYSBjb2xvciBvZiBhIHNlbGVjdGVkIHJvd1xyXG4gICAgQElucHV0KClcclxuICAgIEBIb3N0QmluZGluZygnYXR0ci5zZWxlY3RDb2xvcicpIHNlbGVjdENvbG9yOiBzdHJpbmc7XHJcblxyXG4gICAgLy8gYSB0ZXh0IGNvbG9yIG9mIGEgc2VsZWN0ZWQgcm93XHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLnNlbGVjdFRleHRDb2xvcicpIHNlbGVjdFRleHRDb2xvcjogc3RyaW5nO1xyXG5cclxuICAgIC8vIGFsbG93cyBkZXNlbGVjdGluZyBzZWxlY3RlZCByb3dzXHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFsbG93RGVzZWxlY3RpbmdSb3dzJykgYWxsb3dEZXNlbGVjdGluZ1Jvd3M6IGJvb2xlYW47XHJcblxyXG4gICAgLy8gYWxsb3dzIG5hdmlnYXRpb24gYmV0d2VlbiB0YWJsZSByb3dzIHVzaW5nIGFycm93IGtleXNcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYWxsb3dLZXlib2FyZE5hdmlnYXRpb24nKVxyXG4gICAgYWxsb3dLZXlib2FyZE5hdmlnYXRpb24gPSB0cnVlO1xyXG5cclxuICAgIC8vIGRpc2FibGVzIHVzZXIgc2VsZWN0IHdpdGhpbmcgdGhlIHRhYmxlXHJcbiAgICBASW5wdXQoKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5ub1RleHRTZWxlY3QnKVxyXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLm5vVGV4dFNlbGVjdCcpIG5vVGV4dFNlbGVjdDogYm9vbGVhbjtcclxuXHJcbiAgICBmaXhlZFRhYmxlSGVpZ2h0ID0gJ2F1dG8nO1xyXG5cclxuICAgIEBIb3N0QmluZGluZygnYXR0ci50YWJpbmRleCcpIHRhYmluZGV4ID0gMDtcclxuXHJcbiAgICBzZWxlY3RlZFJvd3M6IEFycmF5PG51bWJlcj4gPSBbXTtcclxuXHJcbiAgICAvLyBzcGVjaWZpZXMgY29sbGFwc2libGUgdHlwZS4gQ2FuIGJlIGVpdGhlciAnYWNjb3JkaW9uJyBvciAnZXhwYW5kYWJsZSdcclxuICAgIEBJbnB1dCgpXHJcbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIudHlwZScpIHR5cGU6ICdhY2NvcmRpb24nIHwgJ2V4cGFuZGFibGUnID0gJ2FjY29yZGlvbic7XHJcblxyXG4gICAgQENvbnRlbnRDaGlsZHJlbihDb2xsYXBzaWJsZVRhYmxlUm93Q29tcG9uZW50KSBjb2xsYXBzaWJsZVRhYmxlUm93czogQXJyYXk8Q29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudD47XHJcblxyXG4gICAgbW91c2VEb3duSG9sZCA9IGZhbHNlO1xyXG5cclxuICAgIGNvbnN0cnVjdG9yKFxyXG4gICAgICAgIHByaXZhdGUgZWw6IEVsZW1lbnRSZWYsXHJcbiAgICAgICAgcHJpdmF0ZSBjb2xsYXBzaWJsZVNlcnZpY2U6IENvbGxhcHNpYmxlU2VydmljZSkgeyB9XHJcblxyXG4gICAgbmdPbkluaXQoKSB7XHJcbiAgICB9XHJcblxyXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xyXG4gICAgICAgIC8vIHRoaXMudXBkYXRlRml4ZWRUYWJsZUhlaWdodCgpO1xyXG4gICAgICAgIC8qXHJcbiAgICAgICAgTE9HKGBDb2xsYXBzaWJsZVRhYmxlQ29tcG9uZW50OjpuZ09uSW5pdCgpXFxuYCArXHJcbiAgICAgICAgICAgIGB0aGlzID0ge1xcbmAgK1xyXG4gICAgICAgICAgICBgYm9yZGVyZWQgPSAke3RoaXMuYm9yZGVyZWR9XFxuYCArXHJcbiAgICAgICAgICAgIGBib3JkZXJlZEhvcml6b250YWxseSA9ICR7dGhpcy5ib3JkZXJlZEhvcml6b250YWxseX1cXG5gICtcclxuICAgICAgICAgICAgYGJvcmRlcmVkVmVydGljYWxseSA9ICR7dGhpcy5ib3JkZXJlZFZlcnRpY2FsbHl9XFxuYCArXHJcbiAgICAgICAgICAgIGBzdHJpcGVkID0gJHt0aGlzLnN0cmlwZWR9XFxuYCArXHJcbiAgICAgICAgICAgIGBzdHJpcGVkT2RkQ29sb3IgPSAke3RoaXMuc3RyaXBlZE9kZENvbG9yfVxcbmAgK1xyXG4gICAgICAgICAgICBgc3RyaXBlZEV2ZW5Db2xvciA9ICR7dGhpcy5zdHJpcGVkRXZlbkNvbG9yfVxcbmAgK1xyXG4gICAgICAgICAgICBgaGlnaGxpZ2h0ID0gJHt0aGlzLmhpZ2hsaWdodH1cXG5gICtcclxuICAgICAgICAgICAgYGhpZ2hsaWdodENvbG9yID0gJHt0aGlzLmhpZ2hsaWdodENvbG9yfVxcbmAgK1xyXG4gICAgICAgICAgICBgaGlnaGxpZ2h0VGV4dENvbG9yID0gJHt0aGlzLmhpZ2hsaWdodFRleHRDb2xvcn1cXG5gICtcclxuICAgICAgICAgICAgYGFjdGl2ZUNvbG9yID0gJHt0aGlzLmFjdGl2ZUNvbG9yfVxcbmAgK1xyXG4gICAgICAgICAgICBgYWN0aXZlVGV4dENvbG9yID0gJHt0aGlzLmFjdGl2ZVRleHRDb2xvcn1cXG5gICtcclxuICAgICAgICAgICAgYGNlbnRlcmVkID0gJHt0aGlzLmNlbnRlcmVkfVxcbmAgK1xyXG4gICAgICAgICAgICBgcmVzcG9uc2l2ZSA9ICR7dGhpcy5yZXNwb25zaXZlfVxcbmAgK1xyXG4gICAgICAgICAgICBgc2VsZWN0ID0gJHt0aGlzLnNlbGVjdH1cXG5gICtcclxuICAgICAgICAgICAgYHNlbGVjdENvbG9yID0gJHt0aGlzLnNlbGVjdENvbG9yfVxcbmAgK1xyXG4gICAgICAgICAgICBgc2VsZWN0VGV4dENvbG9yID0gJHt0aGlzLnNlbGVjdFRleHRDb2xvcn1cXG5gICtcclxuICAgICAgICAgICAgYHNlbGVjdE11bHRpcGxlUm93cyA9ICR7dGhpcy5zZWxlY3RNdWx0aXBsZVJvd3N9XFxuYCArXHJcbiAgICAgICAgICAgIGBub1RleHRTZWxlY3QgPSAke3RoaXMubm9UZXh0U2VsZWN0fVxcbmAgK1xyXG4gICAgICAgICAgICBgfWApO1xyXG4gICAgICAgICAgICAqL1xyXG4gICAgfVxyXG5cclxuICAgIG5nT25DaGFuZ2VzKGNoYW5nZXM6IFNpbXBsZUNoYW5nZXMpOiB2b2lkIHtcclxuICAgICAgICBmb3IgKGNvbnN0IGNoYW5nZSBpbiBjaGFuZ2VzKSB7XHJcbiAgICAgICAgICAgIGlmIChjaGFuZ2VzLmhhc093blByb3BlcnR5KGNoYW5nZSkpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLmNvbGxhcHNpYmxlVGFibGVSb3dzICE9IG51bGwpIHtcclxuICAgICAgICAgICAgICAgICAgICBzd2l0Y2ggKGNoYW5nZSkge1xyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzdHJpcGVkJzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc3RyaXBlZE9kZENvbG9yJzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc3RyaXBlZE9kZFRleHRDb2xvcic6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2UgJ3N0cmlwZWRFdmVuQ29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzdHJpcGVkRXZlblRleHRDb2xvcic6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVRhYmxlKCdzdHJpcGVkJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnaGlnaGxpZ2h0JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnaGlnaGxpZ2h0Q29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdoaWdobGlnaHRUZXh0Q29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVUYWJsZSgnaGlnaGxpZ2h0Jyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnYWN0aXZlQ29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdhY3RpdmVUZXh0Q29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGhpcy51cGRhdGVUYWJsZSgnYWN0aXZlJyk7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2VsZWN0JzpcclxuICAgICAgICAgICAgICAgICAgICAgICAgY2FzZSAnc2VsZWN0Q29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzZWxlY3RUZXh0Q29sb3InOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdzZWxlY3RNdWx0aXBsZVJvd3MnOlxyXG4gICAgICAgICAgICAgICAgICAgICAgICBjYXNlICdhbGxvd0Rlc2VsZWN0aW5nUm93cyc6XHJcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB0aGlzLnVwZGF0ZVRhYmxlKCdzZWxlY3QnKTtcclxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgICAgICAvLyB1cGRhdGUgY29sbGFwc2libGUgdGFibGUgdHlwZSBpbiBDb2xsYXBzaWJsZVNlcnZpY2VcclxuICAgICAgICAgICAgICAgIGlmIChjaGFuZ2UgPT09ICd0eXBlJykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMudHlwZSA9IGNoYW5nZXMudHlwZS5jdXJyZW50VmFsdWU7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5jb2xsYXBzaWJsZVNlcnZpY2Uuc2V0VHlwZSh0aGlzLnR5cGUpO1xyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgICAgIHRoaXMuY29sbGFwc2libGVTZXJ2aWNlLnNldENvbGxhcHNpYmxlVGFibGUodGhpcyk7XHJcbiAgICB9XHJcblxyXG4gICAgZm9jdXMoKSB7XHJcbiAgICAgICAgdGhpcy5lbC5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XHJcbiAgICB9XHJcblxyXG4gICAgYWRkU2VsZWN0ZWRSb3coaW5kZXg6IG51bWJlcik6IHZvaWQge1xyXG4gICAgICAgIHN3aXRjaCAodHJ1ZSkge1xyXG4gICAgICAgICAgICBjYXNlIHRoaXMuc2VsZWN0TXVsdGlwbGVSb3dzICYmIHRoaXMuc2VsZWN0ZWRSb3dzLmluZGV4T2YoaW5kZXgpID09PSAtMTpcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSb3dzLnB1c2goaW5kZXgpO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJvd3Muc29ydCgoYSwgYikgPT4gYSAtIGIpO1xyXG4gICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIGNhc2UgIXRoaXMuc2VsZWN0TXVsdGlwbGVSb3dzOlxyXG4gICAgICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJvd3MgPSBbXTtcclxuICAgICAgICAgICAgICAgIHRoaXMuZGVzZWxlY3RBbGxSb3dzKCk7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnNlbGVjdGVkUm93cy5wdXNoKGluZGV4KTtcclxuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRSb3dzLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcclxuICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICByZW1vdmVTZWxlY3RlZFJvdyhpbmRleDogbnVtYmVyKTogdm9pZCB7XHJcbiAgICAgICAgaWYgKHRoaXMuc2VsZWN0ZWRSb3dzLmluZGV4T2YoaW5kZXgpICE9PSAtMSkge1xyXG4gICAgICAgICAgICB0aGlzLnNlbGVjdGVkUm93cy5zcGxpY2UodGhpcy5zZWxlY3RlZFJvd3MuaW5kZXhPZihpbmRleCksIDEpO1xyXG4gICAgICAgIH1cclxuICAgIH1cclxuXHJcbiAgICBjbGVhclNlbGVjdGVkUm93cygpIHtcclxuICAgICAgICB0aGlzLnNlbGVjdGVkUm93cyA9IFtdO1xyXG4gICAgfVxyXG5cclx