UNPKG

angular2-collapsible

Version:

Angular collapsible component styled with Materialize CSS.

457 lines 51.7 kB
/** * @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