angular2-collapsible
Version:
Angular collapsible component styled with Materialize CSS.
457 lines • 51.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* Generated from: lib/collapsible-table-row/collapsible-table-row.component.ts
* @suppress {checkTypes,constantProperty,extraRequire,missingOverride,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Component, Input, HostBinding, HostListener, ElementRef } from '@angular/core';
import { DomSanitizer } from '@angular/platform-browser';
import { CollapsibleTableRowDetailComponent } from '../collapsible-table-row-detail/collapsible-table-row-detail.component';
import { CollapsibleService } from '../services/collapsible.service';
export class CollapsibleTableRowComponent {
/**
* @param {?} el
* @param {?} sanitizer
* @param {?} collapsibleService
*/
constructor(el, sanitizer, collapsibleService) {
this.el = el;
this.sanitizer = sanitizer;
this.collapsibleService = collapsibleService;
this.backgroundTransitionDuration = '0.3s';
// transition-timing-function: easeInQuad
this.backgroundTransitionTimingFunction = this.sanitizer
.bypassSecurityTrustStyle(CollapsibleTableRowComponent.EASE_OUT_QUAD);
this.isHeadRow = false;
this.isBodyRow = false;
this.isOddRow = false;
this.isEvenRow = false;
this.isParentStriped = false;
this.isParentHighlight = false;
this.parentAllowsSelect = false;
this.parentAllowsSelectMultipleRows = false;
this.parentAllowsDeselectingRows = false;
this.dragSelection = false;
}
/**
* @return {?}
*/
ngOnInit() {
/** @type {?} */
const elem = this.el.nativeElement;
/** @type {?} */
const tbody = elem.parentElement;
if (tbody.tagName === 'TBODY') {
/** @type {?} */
const collapsibleTableRows = tbody.querySelectorAll('collapsible-table-row');
for (let i = 0; i < collapsibleTableRows.length; i++) {
/** @type {?} */
const collapsibleTableRow = collapsibleTableRows[i];
if (collapsibleTableRow === elem) {
this.index = i + 1;
break;
}
}
}
// retrieve parent CollapsibleTableComponent through the CollapsibleService
this.parentCollapsibleTable = this.collapsibleService.getCollapsibleTable();
if (this.parentCollapsibleTable != null) {
// check if collapsible-table is marked to show striped table
this.isParentStriped = this.parentCollapsibleTable.striped;
// check if collapsible-table is marked to highlight current row
this.isParentHighlight = this.parentCollapsibleTable.highlight;
this.parentHighlightRowBackgroundColor = this.parentCollapsibleTable.highlightColor ||
CollapsibleTableRowComponent.DEFAULT_HIGHLIGHT_ROW_COLOR;
this.parentHighlightRowTextColor = this.parentCollapsibleTable.highlightTextColor ||
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
// check if collapsible-table specifies the active row color
this.activeRowBackgroundColor = this.parentCollapsibleTable.activeColor ||
CollapsibleTableRowComponent.DEFAULT_ACTIVE_ROW_COLOR;
this.activeRowTextColor = this.parentCollapsibleTable.activeTextColor ||
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
// check if collapsible-table allows selecting rows
this.parentAllowsSelect = this.parentCollapsibleTable.select;
this.parentAllowsSelectMultipleRows = this.parentCollapsibleTable.selectMultipleRows;
// check if collapsible-table specifies a color for the selected row
this.selectedRowBackgroundColor = this.parentCollapsibleTable.selectColor ||
CollapsibleTableRowComponent.DEFAULT_SELECTED_ROW_COLOR;
this.selectedRowTextColor = this.parentCollapsibleTable.selectTextColor ||
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
// check if collapsible-table allows to deselect rows
this.parentAllowsDeselectingRows = this.parentCollapsibleTable.allowDeselectingRows != null ?
this.parentCollapsibleTable.allowDeselectingRows : false;
}
}
/**
* @return {?}
*/
ngAfterContentInit() {
this.updateRow();
}
/**
* @return {?}
*/
updateRow() {
/** @type {?} */
const elem = this.el.nativeElement;
// determine if the row is inside the 'thead'
/** @type {?} */
const th = elem.querySelector('th');
if (th != null) {
this.isHeadRow = true;
}
// determine if the row is inside the 'tbody'
/** @type {?} */
const td = elem.querySelector('td');
if (td != null) {
this.isBodyRow = true;
// determine if the row is 'odd' or 'event'
if (this.index % 2 === 0) {
this.isEvenRow = true;
this.parentStripedRowBackgroundColor = this.parentCollapsibleTable.stripedEvenColor ||
CollapsibleTableRowComponent.DEFAULT_STRIPED_EVEN_ROW_COLOR;
this.parentStripedRowTextColor = this.parentCollapsibleTable.stripedEvenTextColor ||
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
}
else {
this.isOddRow = true;
this.parentStripedRowBackgroundColor = this.parentCollapsibleTable.stripedOddColor ||
CollapsibleTableRowComponent.DEFAULT_STRIPED_ODD_ROW_COLOR;
this.parentStripedRowTextColor = this.parentCollapsibleTable.stripedOddTextColor ||
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
}
switch (true) {
case this.parentAllowsSelect && this.selected:
this.rowBackgroundColor = this.selectedRowBackgroundColor;
this.rowTextColor = this.selectedRowTextColor;
break;
case this.isParentStriped:
this.rowBackgroundColor = this.parentStripedRowBackgroundColor;
this.rowTextColor = this.parentStripedRowTextColor;
break;
}
}
}
/**
* @return {?}
*/
getHeight() {
return this.el.nativeElement.offsetHeight;
}
/**
* @private
* @param {?} event
* @return {?}
*/
isLeftMouseButton(event) {
/** @type {?} */
const button = event.button;
/** @type {?} */
const which = event['which'];
/** @type {?} */
const target = (/** @type {?} */ ((event.target || event.srcElement || event.currentTarget)));
if (['TR', 'TD'].indexOf(target.tagName) > -1) {
if ('button' in event) {
return button === 0;
}
else {
return (which || button) === 1;
}
}
return false;
}
/**
* @param {?} event
* @return {?}
*/
mousedown(event) {
// handle only if the Left mouse button pressed
// and the row is a body row
if (this.isLeftMouseButton(event) && this.isBodyRow) {
if (this.parentCollapsibleTable.noTextSelect) {
event.preventDefault();
}
if (this.isBodyRow) {
if (this.parentAllowsSelect && !this.parentAllowsDeselectingRows) {
this.prevSelectedRows = this.parentCollapsibleTable.selectedRows;
this.parentCollapsibleTable.clearSelectedRows();
this.parentCollapsibleTable.deselectAllRows();
}
this.rowBackgroundColor = this.activeRowBackgroundColor;
this.rowTextColor = this.activeRowTextColor;
}
}
}
/**
* @param {?} event
* @return {?}
*/
mouseup(event) {
// handle only if the Left mouse button pressed
// and the row is a body row
if (this.isLeftMouseButton(event) && this.isBodyRow) {
// handle selection
if (this.parentAllowsSelect) {
if (!this.parentAllowsDeselectingRows) {
this.parentCollapsibleTable.selectRow(this.index);
}
else {
if (!this.dragSelection) {
this.parentCollapsibleTable.toggleRowSelection(this.index);
}
}
}
// check row state
this.parentCollapsibleTable.updateTable();
/*switch (true) {
// parent allows selecting rows and the row is selected
case this.parentAllowsSelect && this.selected:
this.rowBackgroundColor = this.selectedRowBackgroundColor;
this.rowTextColor = this.selectedRowTextColor;
this.parentCollapsibleTable.updateTable();
break;
// highlighted
case this.isParentHighlight:
this.rowBackgroundColor = this.parentHighlightRowBackgroundColor;
this.rowTextColor = this.parentHighlightRowTextColor;
break;
// striped
case this.isParentStriped:
this.rowBackgroundColor = this.parentStripedRowBackgroundColor;
this.rowTextColor = this.parentStripedRowTextColor;
break;
default:
this.rowBackgroundColor = undefined;
this.rowTextColor = undefined;
break;
}*/
// select multiple rows using the 'Shift' key
if (this.parentAllowsSelect &&
this.parentAllowsSelectMultipleRows &&
event != null && event.shiftKey) {
if (this.prevSelectedRows != null &&
this.prevSelectedRows.length > 0 &&
this.parentCollapsibleTable.selectedRows.length > 0) {
/** @type {?} */
const rangeSelectedRows = this.prevSelectedRows.concat(this.parentCollapsibleTable.selectedRows);
rangeSelectedRows.sort((/**
* @param {?} a
* @param {?} b
* @return {?}
*/
(a, b) => a - b));
/** @type {?} */
const firstRowIndex = Math.min.apply(null, rangeSelectedRows);
/** @type {?} */
const lastRowIndex = Math.max.apply(null, rangeSelectedRows);
this.parentCollapsibleTable.selectRows(firstRowIndex, lastRowIndex);
}
}
// set dragSelection flag to false. Prevents selection drag behavior
this.dragSelection = false;
// focus the collapsible table
this.parentCollapsibleTable.focus();
}
}
/**
* @param {?} event
* @return {?}
*/
mouseenter(event) {
// handle only if the row is a body row
if (this.isBodyRow) {
switch (true) {
// the use is trying to select multiple rows by holding a mouse button
case this.parentAllowsSelect && this.parentAllowsSelectMultipleRows && this.parentCollapsibleTable.mouseDownHold:
this.parentCollapsibleTable.selectRow(this.index);
this.dragSelection = true;
break;
// parent allows selecting rows and the row is selected
case this.parentAllowsSelect && this.selected:
break;
// highlighted
case this.isParentHighlight:
this.rowBackgroundColor = this.parentHighlightRowBackgroundColor;
this.rowTextColor = this.parentHighlightRowTextColor;
break;
}
}
}
/**
* @param {?} event
* @return {?}
*/
mouseleave(event) {
// handle only if the row is a body row
if (this.isBodyRow) {
// check row state
switch (true) {
// the use is trying to select multiple rows by holding a mouse button
case this.parentAllowsSelect && this.parentAllowsSelectMultipleRows && this.parentCollapsibleTable.mouseDownHold:
this.parentCollapsibleTable.selectRow(this.index);
this.dragSelection = false;
break;
// parent allows selecting rows and the row is selected
case this.parentAllowsSelect && this.selected:
break;
// stripped
case this.isParentStriped:
this.rowBackgroundColor = this.parentStripedRowBackgroundColor;
this.rowTextColor = this.parentStripedRowTextColor;
break;
default:
this.rowBackgroundColor = undefined;
this.rowTextColor = undefined;
break;
}
}
}
/**
* @param {?} event
* @return {?}
*/
click(event) {
if (this.detail != null) {
/** @type {?} */
const target = (/** @type {?} */ ((event.target || event.srcElement || event.currentTarget)));
if (target != null && ['TR', 'TD'].indexOf(target.tagName) > -1) {
this.detail.subject.next();
}
}
}
}
CollapsibleTableRowComponent.EASE_OUT_QUAD = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)';
CollapsibleTableRowComponent.DEFAULT_STRIPED_ODD_ROW_COLOR = 'rgba(242,242,242,0.8)';
CollapsibleTableRowComponent.DEFAULT_STRIPED_EVEN_ROW_COLOR = 'transparent';
CollapsibleTableRowComponent.DEFAULT_HIGHLIGHT_ROW_COLOR = 'rgba(222,222,222, 0.8)';
CollapsibleTableRowComponent.DEFAULT_ACTIVE_ROW_COLOR = 'rgba(212,212,212, 0.8)';
CollapsibleTableRowComponent.DEFAULT_SELECTED_ROW_COLOR = 'rgba(212,212,212, 0.8)';
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR = 'black';
CollapsibleTableRowComponent.decorators = [
{ type: Component, args: [{
selector: 'collapsible-table-row',
template: `<ng-content></ng-content>`,
styles: [`
:host {
display: table-row;
transition-property: background-color, color;
}
`]
}] }
];
/** @nocollapse */
CollapsibleTableRowComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: DomSanitizer },
{ type: CollapsibleService }
];
CollapsibleTableRowComponent.propDecorators = {
detail: [{ type: Input }],
rowTextColor: [{ type: HostBinding, args: ['style.color',] }],
rowBackgroundColor: [{ type: HostBinding, args: ['style.background-color',] }],
backgroundTransitionDuration: [{ type: HostBinding, args: ['style.transition-duration',] }],
backgroundTransitionTimingFunction: [{ type: HostBinding, args: ['style.transition-timing-function',] }],
selected: [{ type: HostBinding, args: ['class.selected',] }],
mousedown: [{ type: HostListener, args: ['mousedown', ['$event'],] }],
mouseup: [{ type: HostListener, args: ['mouseup', ['$event'],] }],
mouseenter: [{ type: HostListener, args: ['mouseenter', ['$event'],] }],
mouseleave: [{ type: HostListener, args: ['mouseleave', ['$event'],] }],
click: [{ type: HostListener, args: ['click', ['$event'],] }]
};
if (false) {
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.EASE_OUT_QUAD;
/** @type {?} */
CollapsibleTableRowComponent.DEFAULT_STRIPED_ODD_ROW_COLOR;
/** @type {?} */
CollapsibleTableRowComponent.DEFAULT_STRIPED_EVEN_ROW_COLOR;
/** @type {?} */
CollapsibleTableRowComponent.DEFAULT_HIGHLIGHT_ROW_COLOR;
/** @type {?} */
CollapsibleTableRowComponent.DEFAULT_ACTIVE_ROW_COLOR;
/** @type {?} */
CollapsibleTableRowComponent.DEFAULT_SELECTED_ROW_COLOR;
/** @type {?} */
CollapsibleTableRowComponent.DEFAULT_ROW_TEXT_COLOR;
/** @type {?} */
CollapsibleTableRowComponent.prototype.detail;
/** @type {?} */
CollapsibleTableRowComponent.prototype.rowTextColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.rowBackgroundColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.backgroundTransitionDuration;
/** @type {?} */
CollapsibleTableRowComponent.prototype.backgroundTransitionTimingFunction;
/** @type {?} */
CollapsibleTableRowComponent.prototype.selected;
/** @type {?} */
CollapsibleTableRowComponent.prototype.isHeadRow;
/** @type {?} */
CollapsibleTableRowComponent.prototype.isBodyRow;
/** @type {?} */
CollapsibleTableRowComponent.prototype.isOddRow;
/** @type {?} */
CollapsibleTableRowComponent.prototype.isEvenRow;
/** @type {?} */
CollapsibleTableRowComponent.prototype.isParentStriped;
/** @type {?} */
CollapsibleTableRowComponent.prototype.isParentHighlight;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentAllowsSelect;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentAllowsSelectMultipleRows;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentStripedRowBackgroundColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentStripedRowTextColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentHighlightRowBackgroundColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentHighlightRowTextColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.activeRowBackgroundColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.activeRowTextColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.selectedRowBackgroundColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.selectedRowTextColor;
/** @type {?} */
CollapsibleTableRowComponent.prototype.parentAllowsDeselectingRows;
/** @type {?} */
CollapsibleTableRowComponent.prototype.index;
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.prototype.parentCollapsibleTable;
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.prototype.prevSelectedRows;
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.prototype.dragSelection;
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.prototype.el;
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.prototype.sanitizer;
/**
* @type {?}
* @private
*/
CollapsibleTableRowComponent.prototype.collapsibleService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sbGFwc2libGUtdGFibGUtcm93LmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL2FuZ3VsYXIyLWNvbGxhcHNpYmxlLyIsInNvdXJjZXMiOlsibGliL2NvbGxhcHNpYmxlLXRhYmxlLXJvdy9jb2xsYXBzaWJsZS10YWJsZS1yb3cuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7O0FBQUEsT0FBTyxFQUNILFNBQVMsRUFFVCxLQUFLLEVBQUUsV0FBVyxFQUFFLFlBQVksRUFDaEMsVUFBVSxFQUNiLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUV6RCxPQUFPLEVBQUUsa0NBQWtDLEVBQUUsTUFBTSx3RUFBd0UsQ0FBQztBQUU1SCxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxpQ0FBaUMsQ0FBQztBQVlyRSxNQUFNLE9BQU8sNEJBQTRCOzs7Ozs7SUFtRHJDLFlBQ1ksRUFBYyxFQUNkLFNBQXVCLEVBQ3ZCLGtCQUFzQztRQUZ0QyxPQUFFLEdBQUYsRUFBRSxDQUFZO1FBQ2QsY0FBUyxHQUFULFNBQVMsQ0FBYztRQUN2Qix1QkFBa0IsR0FBbEIsa0JBQWtCLENBQW9CO1FBcENSLGlDQUE0QixHQUFHLE1BQU0sQ0FBQzs7UUFHaEYsdUNBQWtDLEdBQUcsSUFBSSxDQUFDLFNBQVM7YUFDOUMsd0JBQXdCLENBQUMsNEJBQTRCLENBQUMsYUFBYSxDQUFDLENBQUM7UUFJMUUsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixjQUFTLEdBQUcsS0FBSyxDQUFDO1FBQ2xCLGFBQVEsR0FBRyxLQUFLLENBQUM7UUFDakIsY0FBUyxHQUFHLEtBQUssQ0FBQztRQUNsQixvQkFBZSxHQUFHLEtBQUssQ0FBQztRQUN4QixzQkFBaUIsR0FBRyxLQUFLLENBQUM7UUFDMUIsdUJBQWtCLEdBQUcsS0FBSyxDQUFDO1FBQzNCLG1DQUE4QixHQUFHLEtBQUssQ0FBQztRQVV2QyxnQ0FB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QUM7eUJBaUVsQyxZQUFZLFNBQUMsWUFBWSxFQUFFLENBQUMsUUFBUSxDQUFDO3lCQXNCckMsWUFBWSxTQUFDLFlBQVksRUFBRSxDQUFDLFFBQVEsQ0FBQztvQkEyQnJDLFlBQVksU0FBQyxPQUFPLEVBQUUsQ0FBQyxRQUFRLENBQUM7Ozs7Ozs7SUFoVGpDLDJDQUFzRTs7SUFFdEUsMkRBQXNFOztJQUN0RSw0REFBNkQ7O0lBQzdELHlEQUFxRTs7SUFDckUsc0RBQWtFOztJQUNsRSx3REFBb0U7O0lBRXBFLG9EQUErQzs7SUFFL0MsOENBQW9EOztJQUVwRCxvREFBaUQ7O0lBRWpELDBEQUFrRTs7SUFFbEUsb0VBQWdGOztJQUVoRiwwRUFFMEU7O0lBRTFFLGdEQUFpRDs7SUFFakQsaURBQWtCOztJQUNsQixpREFBa0I7O0lBQ2xCLGdEQUFpQjs7SUFDakIsaURBQWtCOztJQUNsQix1REFBd0I7O0lBQ3hCLHlEQUEwQjs7SUFDMUIsMERBQTJCOztJQUMzQixzRUFBdUM7O0lBRXZDLHVFQUF3Qzs7SUFDeEMsaUVBQWtDOztJQUNsQyx5RUFBMEM7O0lBQzFDLG1FQUFvQzs7SUFDcEMsZ0VBQWlDOztJQUNqQywwREFBMkI7O0lBQzNCLGtFQUFtQzs7SUFDbkMsNERBQTZCOztJQUM3QixtRUFBb0M7O0lBRXBDLDZDQUFjOzs7OztJQUVkLDhEQUEwRDs7Ozs7SUFDMUQsd0RBQXdDOzs7OztJQUN4QyxxREFBOEI7Ozs7O0lBRzFCLDBDQUFzQjs7Ozs7SUFDdEIsaURBQStCOzs7OztJQUMvQiwwREFBOEMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQge1xyXG4gICAgQ29tcG9uZW50LFxyXG4gICAgT25Jbml0LCBBZnRlckNvbnRlbnRJbml0LFxyXG4gICAgSW5wdXQsIEhvc3RCaW5kaW5nLCBIb3N0TGlzdGVuZXIsXHJcbiAgICBFbGVtZW50UmVmXHJcbn0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IERvbVNhbml0aXplciB9IGZyb20gJ0Bhbmd1bGFyL3BsYXRmb3JtLWJyb3dzZXInO1xyXG5cclxuaW1wb3J0IHsgQ29sbGFwc2libGVUYWJsZVJvd0RldGFpbENvbXBvbmVudCB9IGZyb20gJy4uL2NvbGxhcHNpYmxlLXRhYmxlLXJvdy1kZXRhaWwvY29sbGFwc2libGUtdGFibGUtcm93LWRldGFpbC5jb21wb25lbnQnO1xyXG5pbXBvcnQgeyBDb2xsYXBzaWJsZVRhYmxlQ29tcG9uZW50IH0gZnJvbSAnLi4vY29sbGFwc2libGUtdGFibGUvY29sbGFwc2libGUtdGFibGUuY29tcG9uZW50JztcclxuaW1wb3J0IHsgQ29sbGFwc2libGVTZXJ2aWNlIH0gZnJvbSAnLi4vc2VydmljZXMvY29sbGFwc2libGUuc2VydmljZSc7XHJcblxyXG5AQ29tcG9uZW50KHtcclxuICAgIHNlbGVjdG9yOiAnY29sbGFwc2libGUtdGFibGUtcm93JyxcclxuICAgIHRlbXBsYXRlOiBgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PmAsXHJcbiAgICBzdHlsZXM6IFtgXHJcbiAgICAgICAgOmhvc3Qge1xyXG4gICAgICAgICAgICBkaXNwbGF5OiB0YWJsZS1yb3c7XHJcbiAgICAgICAgICAgIHRyYW5zaXRpb24tcHJvcGVydHk6IGJhY2tncm91bmQtY29sb3IsIGNvbG9yO1xyXG4gICAgICAgIH1cclxuICAgIGBdLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudCBpbXBsZW1lbnRzIE9uSW5pdCwgQWZ0ZXJDb250ZW50SW5pdCB7XHJcblxyXG4gICAgcHJpdmF0ZSBzdGF0aWMgRUFTRV9PVVRfUVVBRCA9ICdjdWJpYy1iZXppZXIoMC4yNSwgMC40NiwgMC40NSwgMC45NCknO1xyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9TVFJJUEVEX09ERF9ST1dfQ09MT1IgPSAncmdiYSgyNDIsMjQyLDI0MiwwLjgpJztcclxuICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9TVFJJUEVEX0VWRU5fUk9XX0NPTE9SID0gJ3RyYW5zcGFyZW50JztcclxuICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9ISUdITElHSFRfUk9XX0NPTE9SID0gJ3JnYmEoMjIyLDIyMiwyMjIsIDAuOCknO1xyXG4gICAgcHVibGljIHN0YXRpYyBERUZBVUxUX0FDVElWRV9ST1dfQ09MT1IgPSAncmdiYSgyMTIsMjEyLDIxMiwgMC44KSc7XHJcbiAgICBwdWJsaWMgc3RhdGljIERFRkFVTFRfU0VMRUNURURfUk9XX0NPTE9SID0gJ3JnYmEoMjEyLDIxMiwyMTIsIDAuOCknO1xyXG5cclxuICAgIHB1YmxpYyBzdGF0aWMgREVGQVVMVF9ST1dfVEVYVF9DT0xPUiA9ICdibGFjayc7XHJcblxyXG4gICAgQElucHV0KCkgZGV0YWlsOiBDb2xsYXBzaWJsZVRhYmxlUm93RGV0YWlsQ29tcG9uZW50O1xyXG5cclxuICAgIEBIb3N0QmluZGluZygnc3R5bGUuY29sb3InKSByb3dUZXh0Q29sb3I6IHN0cmluZztcclxuXHJcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLmJhY2tncm91bmQtY29sb3InKSByb3dCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcclxuXHJcbiAgICBASG9zdEJpbmRpbmcoJ3N0eWxlLnRyYW5zaXRpb24tZHVyYXRpb24nKSBiYWNrZ3JvdW5kVHJhbnNpdGlvbkR1cmF0aW9uID0gJzAuM3MnO1xyXG4gICAgLy8gdHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb246IGVhc2VJblF1YWRcclxuICAgIEBIb3N0QmluZGluZygnc3R5bGUudHJhbnNpdGlvbi10aW1pbmctZnVuY3Rpb24nKVxyXG4gICAgYmFja2dyb3VuZFRyYW5zaXRpb25UaW1pbmdGdW5jdGlvbiA9IHRoaXMuc2FuaXRpemVyXHJcbiAgICAgICAgLmJ5cGFzc1NlY3VyaXR5VHJ1c3RTdHlsZShDb2xsYXBzaWJsZVRhYmxlUm93Q29tcG9uZW50LkVBU0VfT1VUX1FVQUQpO1xyXG5cclxuICAgIEBIb3N0QmluZGluZygnY2xhc3Muc2VsZWN0ZWQnKSBzZWxlY3RlZDogYm9vbGVhbjtcclxuXHJcbiAgICBpc0hlYWRSb3cgPSBmYWxzZTtcclxuICAgIGlzQm9keVJvdyA9IGZhbHNlO1xyXG4gICAgaXNPZGRSb3cgPSBmYWxzZTtcclxuICAgIGlzRXZlblJvdyA9IGZhbHNlO1xyXG4gICAgaXNQYXJlbnRTdHJpcGVkID0gZmFsc2U7XHJcbiAgICBpc1BhcmVudEhpZ2hsaWdodCA9IGZhbHNlO1xyXG4gICAgcGFyZW50QWxsb3dzU2VsZWN0ID0gZmFsc2U7XHJcbiAgICBwYXJlbnRBbGxvd3NTZWxlY3RNdWx0aXBsZVJvd3MgPSBmYWxzZTtcclxuXHJcbiAgICBwYXJlbnRTdHJpcGVkUm93QmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XHJcbiAgICBwYXJlbnRTdHJpcGVkUm93VGV4dENvbG9yOiBzdHJpbmc7XHJcbiAgICBwYXJlbnRIaWdobGlnaHRSb3dCYWNrZ3JvdW5kQ29sb3I6IHN0cmluZztcclxuICAgIHBhcmVudEhpZ2hsaWdodFJvd1RleHRDb2xvcjogc3RyaW5nO1xyXG4gICAgYWN0aXZlUm93QmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XHJcbiAgICBhY3RpdmVSb3dUZXh0Q29sb3I6IHN0cmluZztcclxuICAgIHNlbGVjdGVkUm93QmFja2dyb3VuZENvbG9yOiBzdHJpbmc7XHJcbiAgICBzZWxlY3RlZFJvd1RleHRDb2xvcjogc3RyaW5nO1xyXG4gICAgcGFyZW50QWxsb3dzRGVzZWxlY3RpbmdSb3dzID0gZmFsc2U7XHJcblxyXG4gICAgaW5kZXg6IG51bWJlcjtcclxuXHJcbiAgICBwcml2YXRlIHBhcmVudENvbGxhcHNpYmxlVGFibGU6IENvbGxhcHNpYmxlVGFibGVDb21wb25lbnQ7XHJcbiAgICBwcml2YXRlIHByZXZTZWxlY3RlZFJvd3M6IEFycmF5PG51bWJlcj47XHJcbiAgICBwcml2YXRlIGRyYWdTZWxlY3Rpb24gPSBmYWxzZTtcclxuXHJcbiAgICBjb25zdHJ1Y3RvcihcclxuICAgICAgICBwcml2YXRlIGVsOiBFbGVtZW50UmVmLFxyXG4gICAgICAgIHByaXZhdGUgc2FuaXRpemVyOiBEb21TYW5pdGl6ZXIsXHJcbiAgICAgICAgcHJpdmF0ZSBjb2xsYXBzaWJsZVNlcnZpY2U6IENvbGxhcHNpYmxlU2VydmljZSkgeyB9XHJcblxyXG4gICAgbmdPbkluaXQoKSB7XHJcbiAgICAgICAgY29uc3QgZWxlbTogRWxlbWVudCA9IHRoaXMuZWwubmF0aXZlRWxlbWVudDtcclxuICAgICAgICBjb25zdCB0Ym9keTogRWxlbWVudCA9IGVsZW0ucGFyZW50RWxlbWVudDtcclxuICAgICAgICBpZiAodGJvZHkudGFnTmFtZSA9PT0gJ1RCT0RZJykge1xyXG4gICAgICAgICAgICBjb25zdCBjb2xsYXBzaWJsZVRhYmxlUm93czogTm9kZUxpc3RPZjxFbGVtZW50PiA9IHRib2R5LnF1ZXJ5U2VsZWN0b3JBbGwoJ2NvbGxhcHNpYmxlLXRhYmxlLXJvdycpO1xyXG4gICAgICAgICAgICBmb3IgKGxldCBpID0gMDsgaSA8IGNvbGxhcHNpYmxlVGFibGVSb3dzLmxlbmd0aDsgaSsrKSB7XHJcbiAgICAgICAgICAgICAgICBjb25zdCBjb2xsYXBzaWJsZVRhYmxlUm93OiBFbGVtZW50ID0gY29sbGFwc2libGVUYWJsZVJvd3NbaV07XHJcbiAgICAgICAgICAgICAgICBpZiAoY29sbGFwc2libGVUYWJsZVJvdyA9PT0gZWxlbSkge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuaW5kZXggPSBpICsgMTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgLy8gcmV0cmlldmUgcGFyZW50IENvbGxhcHNpYmxlVGFibGVDb21wb25lbnQgdGhyb3VnaCB0aGUgQ29sbGFwc2libGVTZXJ2aWNlXHJcbiAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlID0gdGhpcy5jb2xsYXBzaWJsZVNlcnZpY2UuZ2V0Q29sbGFwc2libGVUYWJsZSgpO1xyXG5cclxuICAgICAgICBpZiAodGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlICE9IG51bGwpIHtcclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgY29sbGFwc2libGUtdGFibGUgaXMgbWFya2VkIHRvIHNob3cgc3RyaXBlZCB0YWJsZVxyXG4gICAgICAgICAgICB0aGlzLmlzUGFyZW50U3RyaXBlZCA9IHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5zdHJpcGVkO1xyXG5cclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgY29sbGFwc2libGUtdGFibGUgaXMgbWFya2VkIHRvIGhpZ2hsaWdodCBjdXJyZW50IHJvd1xyXG4gICAgICAgICAgICB0aGlzLmlzUGFyZW50SGlnaGxpZ2h0ID0gdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLmhpZ2hsaWdodDtcclxuICAgICAgICAgICAgdGhpcy5wYXJlbnRIaWdobGlnaHRSb3dCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnBhcmVudENvbGxhcHNpYmxlVGFibGUuaGlnaGxpZ2h0Q29sb3IgfHxcclxuICAgICAgICAgICAgICAgIENvbGxhcHNpYmxlVGFibGVSb3dDb21wb25lbnQuREVGQVVMVF9ISUdITElHSFRfUk9XX0NPTE9SO1xyXG4gICAgICAgICAgICB0aGlzLnBhcmVudEhpZ2hsaWdodFJvd1RleHRDb2xvciA9IHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5oaWdobGlnaHRUZXh0Q29sb3IgfHxcclxuICAgICAgICAgICAgICAgIENvbGxhcHNpYmxlVGFibGVSb3dDb21wb25lbnQuREVGQVVMVF9ST1dfVEVYVF9DT0xPUjtcclxuXHJcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGNvbGxhcHNpYmxlLXRhYmxlIHNwZWNpZmllcyB0aGUgYWN0aXZlIHJvdyBjb2xvclxyXG4gICAgICAgICAgICB0aGlzLmFjdGl2ZVJvd0JhY2tncm91bmRDb2xvciA9IHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5hY3RpdmVDb2xvciB8fFxyXG4gICAgICAgICAgICAgICAgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudC5ERUZBVUxUX0FDVElWRV9ST1dfQ09MT1I7XHJcbiAgICAgICAgICAgIHRoaXMuYWN0aXZlUm93VGV4dENvbG9yID0gdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLmFjdGl2ZVRleHRDb2xvciB8fFxyXG4gICAgICAgICAgICAgICAgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudC5ERUZBVUxUX1JPV19URVhUX0NPTE9SO1xyXG5cclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgY29sbGFwc2libGUtdGFibGUgYWxsb3dzIHNlbGVjdGluZyByb3dzXHJcbiAgICAgICAgICAgIHRoaXMucGFyZW50QWxsb3dzU2VsZWN0ID0gdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLnNlbGVjdDtcclxuICAgICAgICAgICAgdGhpcy5wYXJlbnRBbGxvd3NTZWxlY3RNdWx0aXBsZVJvd3MgPSB0aGlzLnBhcmVudENvbGxhcHNpYmxlVGFibGUuc2VsZWN0TXVsdGlwbGVSb3dzO1xyXG5cclxuICAgICAgICAgICAgLy8gY2hlY2sgaWYgY29sbGFwc2libGUtdGFibGUgc3BlY2lmaWVzIGEgY29sb3IgZm9yIHRoZSBzZWxlY3RlZCByb3dcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJvd0JhY2tncm91bmRDb2xvciA9IHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5zZWxlY3RDb2xvciB8fFxyXG4gICAgICAgICAgICAgICAgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudC5ERUZBVUxUX1NFTEVDVEVEX1JPV19DT0xPUjtcclxuICAgICAgICAgICAgdGhpcy5zZWxlY3RlZFJvd1RleHRDb2xvciA9IHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5zZWxlY3RUZXh0Q29sb3IgfHxcclxuICAgICAgICAgICAgICAgIENvbGxhcHNpYmxlVGFibGVSb3dDb21wb25lbnQuREVGQVVMVF9ST1dfVEVYVF9DT0xPUjtcclxuXHJcbiAgICAgICAgICAgIC8vIGNoZWNrIGlmIGNvbGxhcHNpYmxlLXRhYmxlIGFsbG93cyB0byBkZXNlbGVjdCByb3dzXHJcbiAgICAgICAgICAgIHRoaXMucGFyZW50QWxsb3dzRGVzZWxlY3RpbmdSb3dzID0gdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLmFsbG93RGVzZWxlY3RpbmdSb3dzICE9IG51bGwgP1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLmFsbG93RGVzZWxlY3RpbmdSb3dzIDogZmFsc2U7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpOiB2b2lkIHtcclxuICAgICAgICB0aGlzLnVwZGF0ZVJvdygpO1xyXG4gICAgfVxyXG5cclxuICAgIHVwZGF0ZVJvdygpOiB2b2lkIHtcclxuICAgICAgICBjb25zdCBlbGVtOiBFbGVtZW50ID0gdGhpcy5lbC5uYXRpdmVFbGVtZW50O1xyXG5cclxuICAgICAgICAvLyBkZXRlcm1pbmUgaWYgdGhlIHJvdyBpcyBpbnNpZGUgdGhlICd0aGVhZCdcclxuICAgICAgICBjb25zdCB0aCA9IGVsZW0ucXVlcnlTZWxlY3RvcigndGgnKTtcclxuICAgICAgICBpZiAodGggIT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmlzSGVhZFJvdyA9IHRydWU7XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICAvLyBkZXRlcm1pbmUgaWYgdGhlIHJvdyBpcyBpbnNpZGUgdGhlICd0Ym9keSdcclxuICAgICAgICBjb25zdCB0ZCA9IGVsZW0ucXVlcnlTZWxlY3RvcigndGQnKTtcclxuICAgICAgICBpZiAodGQgIT0gbnVsbCkge1xyXG4gICAgICAgICAgICB0aGlzLmlzQm9keVJvdyA9IHRydWU7XHJcbiAgICAgICAgICAgIC8vIGRldGVybWluZSBpZiB0aGUgcm93IGlzICdvZGQnIG9yICdldmVudCdcclxuICAgICAgICAgICAgaWYgKHRoaXMuaW5kZXggJSAyID09PSAwKSB7XHJcbiAgICAgICAgICAgICAgICB0aGlzLmlzRXZlblJvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudFN0cmlwZWRSb3dCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnBhcmVudENvbGxhcHNpYmxlVGFibGUuc3RyaXBlZEV2ZW5Db2xvciB8fFxyXG4gICAgICAgICAgICAgICAgICAgIENvbGxhcHNpYmxlVGFibGVSb3dDb21wb25lbnQuREVGQVVMVF9TVFJJUEVEX0VWRU5fUk9XX0NPTE9SO1xyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRTdHJpcGVkUm93VGV4dENvbG9yID0gdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLnN0cmlwZWRFdmVuVGV4dENvbG9yIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudC5ERUZBVUxUX1JPV19URVhUX0NPTE9SO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgdGhpcy5pc09kZFJvdyA9IHRydWU7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnBhcmVudFN0cmlwZWRSb3dCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnBhcmVudENvbGxhcHNpYmxlVGFibGUuc3RyaXBlZE9kZENvbG9yIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudC5ERUZBVUxUX1NUUklQRURfT0REX1JPV19DT0xPUjtcclxuICAgICAgICAgICAgICAgIHRoaXMucGFyZW50U3RyaXBlZFJvd1RleHRDb2xvciA9IHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5zdHJpcGVkT2RkVGV4dENvbG9yIHx8XHJcbiAgICAgICAgICAgICAgICAgICAgQ29sbGFwc2libGVUYWJsZVJvd0NvbXBvbmVudC5ERUZBVUxUX1JPV19URVhUX0NPTE9SO1xyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIGNhc2UgdGhpcy5wYXJlbnRBbGxvd3NTZWxlY3QgJiYgdGhpcy5zZWxlY3RlZDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd0JhY2tncm91bmRDb2xvciA9IHRoaXMuc2VsZWN0ZWRSb3dCYWNrZ3JvdW5kQ29sb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3dUZXh0Q29sb3IgPSB0aGlzLnNlbGVjdGVkUm93VGV4dENvbG9yO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgY2FzZSB0aGlzLmlzUGFyZW50U3RyaXBlZDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd0JhY2tncm91bmRDb2xvciA9IHRoaXMucGFyZW50U3RyaXBlZFJvd0JhY2tncm91bmRDb2xvcjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd1RleHRDb2xvciA9IHRoaXMucGFyZW50U3RyaXBlZFJvd1RleHRDb2xvcjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgZ2V0SGVpZ2h0KCk6IG51bWJlciB7XHJcbiAgICAgICAgcmV0dXJuIHRoaXMuZWwubmF0aXZlRWxlbWVudC5vZmZzZXRIZWlnaHQ7XHJcbiAgICB9XHJcblxyXG4gICAgcHJpdmF0ZSBpc0xlZnRNb3VzZUJ1dHRvbihldmVudDogTW91c2VFdmVudCk6IGJvb2xlYW4ge1xyXG4gICAgICAgIGNvbnN0IGJ1dHRvbjogbnVtYmVyID0gZXZlbnQuYnV0dG9uO1xyXG4gICAgICAgIGNvbnN0IHdoaWNoOiBudW1iZXIgPSBldmVudFsnd2hpY2gnXTtcclxuICAgICAgICBjb25zdCB0YXJnZXQgPSA8SFRNTEVsZW1lbnQ+KGV2ZW50LnRhcmdldCB8fCBldmVudC5zcmNFbGVtZW50IHx8IGV2ZW50LmN1cnJlbnRUYXJnZXQpO1xyXG5cclxuICAgICAgICBpZiAoWydUUicsICdURCddLmluZGV4T2YodGFyZ2V0LnRhZ05hbWUpID4gLTEpIHtcclxuICAgICAgICAgICAgaWYgKCdidXR0b24nIGluIGV2ZW50KSB7XHJcbiAgICAgICAgICAgICAgICByZXR1cm4gYnV0dG9uID09PSAwO1xyXG4gICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuICh3aGljaCB8fCBidXR0b24pID09PSAxO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG5cclxuICAgICAgICByZXR1cm4gZmFsc2U7XHJcbiAgICB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2Vkb3duJywgWyckZXZlbnQnXSlcclxuICAgIG1vdXNlZG93bihldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgICAgIC8vIGhhbmRsZSBvbmx5IGlmIHRoZSBMZWZ0IG1vdXNlIGJ1dHRvbiBwcmVzc2VkXHJcbiAgICAgICAgLy8gYW5kIHRoZSByb3cgaXMgYSBib2R5IHJvd1xyXG4gICAgICAgIGlmICh0aGlzLmlzTGVmdE1vdXNlQnV0dG9uKGV2ZW50KSAmJiB0aGlzLmlzQm9keVJvdykge1xyXG4gICAgICAgICAgICBpZiAodGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLm5vVGV4dFNlbGVjdCkge1xyXG4gICAgICAgICAgICAgICAgZXZlbnQucHJldmVudERlZmF1bHQoKTtcclxuICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICBpZiAodGhpcy5pc0JvZHlSb3cpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudEFsbG93c1NlbGVjdCAmJiAhdGhpcy5wYXJlbnRBbGxvd3NEZXNlbGVjdGluZ1Jvd3MpIHtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnByZXZTZWxlY3RlZFJvd3MgPSB0aGlzLnBhcmVudENvbGxhcHNpYmxlVGFibGUuc2VsZWN0ZWRSb3dzO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5jbGVhclNlbGVjdGVkUm93cygpO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5kZXNlbGVjdEFsbFJvd3MoKTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgICAgIHRoaXMucm93QmFja2dyb3VuZENvbG9yID0gdGhpcy5hY3RpdmVSb3dCYWNrZ3JvdW5kQ29sb3I7XHJcbiAgICAgICAgICAgICAgICB0aGlzLnJvd1RleHRDb2xvciA9IHRoaXMuYWN0aXZlUm93VGV4dENvbG9yO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNldXAnLCBbJyRldmVudCddKVxyXG4gICAgbW91c2V1cChldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgICAgIC8vIGhhbmRsZSBvbmx5IGlmIHRoZSBMZWZ0IG1vdXNlIGJ1dHRvbiBwcmVzc2VkXHJcbiAgICAgICAgLy8gYW5kIHRoZSByb3cgaXMgYSBib2R5IHJvd1xyXG4gICAgICAgIGlmICh0aGlzLmlzTGVmdE1vdXNlQnV0dG9uKGV2ZW50KSAmJiB0aGlzLmlzQm9keVJvdykge1xyXG4gICAgICAgICAgICAvLyBoYW5kbGUgc2VsZWN0aW9uXHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudEFsbG93c1NlbGVjdCkge1xyXG4gICAgICAgICAgICAgICAgaWYgKCF0aGlzLnBhcmVudEFsbG93c0Rlc2VsZWN0aW5nUm93cykge1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5zZWxlY3RSb3codGhpcy5pbmRleCk7XHJcbiAgICAgICAgICAgICAgICB9IGVsc2Uge1xyXG4gICAgICAgICAgICAgICAgICAgIGlmICghdGhpcy5kcmFnU2VsZWN0aW9uKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgICAgIHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS50b2dnbGVSb3dTZWxlY3Rpb24odGhpcy5pbmRleCk7XHJcbiAgICAgICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICAgICAgfVxyXG4gICAgICAgICAgICB9XHJcblxyXG4gICAgICAgICAgICAvLyBjaGVjayByb3cgc3RhdGVcclxuICAgICAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLnVwZGF0ZVRhYmxlKCk7XHJcbiAgICAgICAgICAgIC8qc3dpdGNoICh0cnVlKSB7XHJcbiAgICAgICAgICAgICAgICAvLyBwYXJlbnQgYWxsb3dzIHNlbGVjdGluZyByb3dzIGFuZCB0aGUgcm93IGlzIHNlbGVjdGVkXHJcbiAgICAgICAgICAgICAgICBjYXNlIHRoaXMucGFyZW50QWxsb3dzU2VsZWN0ICYmIHRoaXMuc2VsZWN0ZWQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3dCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnNlbGVjdGVkUm93QmFja2dyb3VuZENvbG9yO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm93VGV4dENvbG9yID0gdGhpcy5zZWxlY3RlZFJvd1RleHRDb2xvcjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnBhcmVudENvbGxhcHNpYmxlVGFibGUudXBkYXRlVGFibGUoKTtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIC8vIGhpZ2hsaWdodGVkXHJcbiAgICAgICAgICAgICAgICBjYXNlIHRoaXMuaXNQYXJlbnRIaWdobGlnaHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3dCYWNrZ3JvdW5kQ29sb3IgPSB0aGlzLnBhcmVudEhpZ2hsaWdodFJvd0JhY2tncm91bmRDb2xvcjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd1RleHRDb2xvciA9IHRoaXMucGFyZW50SGlnaGxpZ2h0Um93VGV4dENvbG9yO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgLy8gc3RyaXBlZFxyXG4gICAgICAgICAgICAgICAgY2FzZSB0aGlzLmlzUGFyZW50U3RyaXBlZDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd0JhY2tncm91bmRDb2xvciA9IHRoaXMucGFyZW50U3RyaXBlZFJvd0JhY2tncm91bmRDb2xvcjtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd1RleHRDb2xvciA9IHRoaXMucGFyZW50U3RyaXBlZFJvd1RleHRDb2xvcjtcclxuICAgICAgICAgICAgICAgICAgICBicmVhaztcclxuICAgICAgICAgICAgICAgIGRlZmF1bHQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3dCYWNrZ3JvdW5kQ29sb3IgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5yb3dUZXh0Q29sb3IgPSB1bmRlZmluZWQ7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH0qL1xyXG5cclxuICAgICAgICAgICAgLy8gc2VsZWN0IG11bHRpcGxlIHJvd3MgdXNpbmcgdGhlICdTaGlmdCcga2V5XHJcbiAgICAgICAgICAgIGlmICh0aGlzLnBhcmVudEFsbG93c1NlbGVjdCAmJlxyXG4gICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRBbGxvd3NTZWxlY3RNdWx0aXBsZVJvd3MgJiZcclxuICAgICAgICAgICAgICAgIGV2ZW50ICE9IG51bGwgJiYgZXZlbnQuc2hpZnRLZXkpIHtcclxuICAgICAgICAgICAgICAgIGlmICh0aGlzLnByZXZTZWxlY3RlZFJvd3MgIT0gbnVsbCAmJlxyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucHJldlNlbGVjdGVkUm93cy5sZW5ndGggPiAwICYmXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLnNlbGVjdGVkUm93cy5sZW5ndGggPiAwKSB7XHJcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgcmFuZ2VTZWxlY3RlZFJvd3MgPSB0aGlzLnByZXZTZWxlY3RlZFJvd3MuY29uY2F0KHRoaXMucGFyZW50Q29sbGFwc2libGVUYWJsZS5zZWxlY3RlZFJvd3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIHJhbmdlU2VsZWN0ZWRSb3dzLnNvcnQoKGEsIGIpID0+IGEgLSBiKTtcclxuICAgICAgICAgICAgICAgICAgICBjb25zdCBmaXJzdFJvd0luZGV4ID0gTWF0aC5taW4uYXBwbHkobnVsbCwgcmFuZ2VTZWxlY3RlZFJvd3MpO1xyXG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGxhc3RSb3dJbmRleCA9IE1hdGgubWF4LmFwcGx5KG51bGwsIHJhbmdlU2VsZWN0ZWRSb3dzKTtcclxuXHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLnNlbGVjdFJvd3MoZmlyc3RSb3dJbmRleCwgbGFzdFJvd0luZGV4KTtcclxuICAgICAgICAgICAgICAgIH1cclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgLy8gc2V0IGRyYWdTZWxlY3Rpb24gZmxhZyB0byBmYWxzZS4gUHJldmVudHMgc2VsZWN0aW9uIGRyYWcgYmVoYXZpb3JcclxuICAgICAgICAgICAgdGhpcy5kcmFnU2VsZWN0aW9uID0gZmFsc2U7XHJcblxyXG4gICAgICAgICAgICAvLyBmb2N1cyB0aGUgY29sbGFwc2libGUgdGFibGVcclxuICAgICAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLmZvY3VzKCk7XHJcbiAgICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIEBIb3N0TGlzdGVuZXIoJ21vdXNlZW50ZXInLCBbJyRldmVudCddKVxyXG4gICAgbW91c2VlbnRlcihldmVudDogTW91c2VFdmVudCkge1xyXG4gICAgICAgIC8vIGhhbmRsZSBvbmx5IGlmIHRoZSByb3cgaXMgYSBib2R5IHJvd1xyXG4gICAgICAgIGlmICh0aGlzLmlzQm9keVJvdykge1xyXG4gICAgICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIC8vIHRoZSB1c2UgaXMgdHJ5aW5nIHRvIHNlbGVjdCBtdWx0aXBsZSByb3dzIGJ5IGhvbGRpbmcgYSBtb3VzZSBidXR0b25cclxuICAgICAgICAgICAgICAgIGNhc2UgdGhpcy5wYXJlbnRBbGxvd3NTZWxlY3QgJiYgdGhpcy5wYXJlbnRBbGxvd3NTZWxlY3RNdWx0aXBsZVJvd3MgJiYgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLm1vdXNlRG93bkhvbGQ6XHJcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5wYXJlbnRDb2xsYXBzaWJsZVRhYmxlLnNlbGVjdFJvdyh0aGlzLmluZGV4KTtcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLmRyYWdTZWxlY3Rpb24gPSB0cnVlO1xyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgLy8gcGFyZW50IGFsbG93cyBzZWxlY3Rpbmcgcm93cyBhbmQgdGhlIHJvdyBpcyBzZWxlY3RlZFxyXG4gICAgICAgICAgICAgICAgY2FzZSB0aGlzLnBhcmVudEFsbG93c1NlbGVjdCAmJiB0aGlzLnNlbGVjdGVkOlxyXG4gICAgICAgICAgICAgICAgICAgIGJyZWFrO1xyXG4gICAgICAgICAgICAgICAgLy8gaGlnaGxpZ2h0ZWRcclxuICAgICAgICAgICAgICAgIGNhc2UgdGhpcy5pc1BhcmVudEhpZ2hsaWdodDpcclxuICAgICAgICAgICAgICAgICAgICB0aGlzLnJvd0JhY2tncm91bmRDb2xvciA9IHRoaXMucGFyZW50SGlnaGxpZ2h0Um93QmFja2dyb3VuZENvbG9yO1xyXG4gICAgICAgICAgICAgICAgICAgIHRoaXMucm93VGV4dENvbG9yID0gdGhpcy5wYXJlbnRIaWdobGlnaHRSb3dUZXh0Q29sb3I7XHJcbiAgICAgICAgICAgICAgICAgICAgYnJlYWs7XHJcbiAgICAgICAgICAgIH1cclxuICAgICAgICB9XHJcbiAgICB9XHJcblxyXG4gICAgQEhvc3RMaXN0ZW5lcignbW91c2VsZWF2ZScsIFsnJGV2ZW50J10pXHJcbiAgICBtb3VzZWxlYXZlKGV2ZW50OiBNb3VzZUV2ZW50KSB7XHJcbiAgICAgICAgLy8gaGFuZGxlIG9ubHkgaWYgdGhlIHJvdyBpcyBhIGJvZHkgcm93XHJcbiAgICAgICAgaWYgKHRoaXMuaXNCb2R5Um93KSB7XHJcbiAgICAgICAgICAgIC8vIGNoZWNrIHJvdyBzdGF0ZVxyXG4gICAgICAgICAgICBzd2l0Y2ggKHRydWUpIHtcclxuICAgICAgICAgICAgICAgIC8vIHRoZSB1c2UgaXMgdHJ5aW5nIHRvIHNlbGVjdCBtdWx0aXBsZSByb3dzIGJ5IGhvbGRpbmcgYSBtb3VzZSBidXR0b25cclxuICAgICAgICAgICAgICAgIGNhc2UgdGhpcy5wYXJlbnRBbGxvd