UNPKG

@blox/material

Version:

Material Components for Angular

392 lines 44.5 kB
import { ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Input, Output, Renderer2, Inject, Optional, Self, HostListener } from '@angular/core'; import { MDCDismissibleDrawerFoundation, MDCModalDrawerFoundation } from '@material/drawer'; import { asBoolean } from '../../utils/value.utils'; import { DOCUMENT } from '@angular/common'; import { AbstractMdcFocusTrap } from '../focus-trap/abstract.mdc.focus-trap'; import { MdcListItemDirective } from '../list/mdc.list.directive'; /** * Directive for the title of a drawer. The use of this directive is optional. * If used, it should be placed as first element inside an `mdcDrawerHeader` */ export class MdcDrawerTitleDirective { constructor() { /** @internal */ this._cls = true; } } MdcDrawerTitleDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawerTitle]' },] } ]; MdcDrawerTitleDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer__title',] }] }; /** * Directive for the subtitle of a drawer. The use of this directive is optional. * If used, it should be placed as a sibling element of `mdcDrawerTitle` * inside an `mdcDrawerHeader` */ export class MdcDrawerSubtitleDirective { constructor() { /** @internal */ this._cls = true; } } MdcDrawerSubtitleDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawerSubtitle]' },] } ]; MdcDrawerSubtitleDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer__subtitle',] }] }; /** * A toolbar header is an optional first child of an `mdcDrawer`. * The header will not scroll with the rest of the drawer content, so is a * good place to place titles and account switchers. * * Directives that are typically used inside an `mdcDrawerHeader`: * `mdcDrawerTitle`, and `mdcDrawerSubTitle` */ export class MdcDrawerHeaderDirective { constructor() { /** @internal */ this._cls = true; } } MdcDrawerHeaderDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawerHeader]' },] } ]; MdcDrawerHeaderDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer__header',] }] }; /** * Directive for the drawer content. You would typically also apply the `mdcList` * or `mdcListGroup` directive to the drawer content (see the examples). */ export class MdcDrawerContentDirective { constructor() { /** @internal */ this._cls = true; } } MdcDrawerContentDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawerContent]' },] } ]; MdcDrawerContentDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer__content',] }] }; export class MdcDrawerScrimDirective { constructor() { /** @internal */ this._cls = true; } } MdcDrawerScrimDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawerScrim]' },] } ]; MdcDrawerScrimDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer-scrim',] }] }; /** * Directive for a (navigation) drawer. The following drawer types are * supported: * * `permanent`: the default type if none was specified. * * `dismissible`: the drawer is hidden by default, and can slide into view. * Typically used when navigation is not common, and the main app content is * prioritized. * * `modal`: the drawer is hidden by default. When activated, the drawer is elevated * above the UI of the app. It uses a scrim to block interaction with the rest of * the app with a scrim. * * Drawers may contain an `mdcDrawerHeader`, and should contain an `mdcDrawerContent` * directive. */ export class MdcDrawerDirective { constructor(_elm, _rndr, doc, _focusTrap) { this._elm = _elm; this._rndr = _rndr; this._focusTrap = _focusTrap; /** @internal */ this._cls = true; this._onDocumentClick = (event) => this.onDocumentClick(event); this.focusTrapHandle = null; this.type = 'permanent'; this.previousFocus = null; this._open = null; this.mdcAdapter = { addClass: (className) => this._rndr.addClass(this._elm.nativeElement, className), removeClass: (className) => this._rndr.removeClass(this._elm.nativeElement, className), hasClass: (className) => this._elm.nativeElement.classList.contains(className), elementHasClass: (element, className) => element.classList.contains(className), saveFocus: () => this.previousFocus = this.document.activeElement, restoreFocus: () => { const prev = this.previousFocus; if (prev && prev.focus && this._elm.nativeElement.contains(this.document.activeElement)) prev.focus(); }, focusActiveNavigationItem: () => { const active = this._items.find(item => item.active); active === null || active === void 0 ? void 0 : active._elm.nativeElement.focus(); }, notifyClose: () => { this.fixOpenClose(false); this.afterClosed.emit(); this.document.removeEventListener('click', this._onDocumentClick); }, notifyOpen: () => { this.fixOpenClose(true); this.afterOpened.emit(); if (this.type === 'modal') this.document.addEventListener('click', this._onDocumentClick); }, trapFocus: () => this.trapFocus(), releaseFocus: () => this.untrapFocus() }; this.foundation = null; // MDCModalDrawerFoundation extends MDCDismissibleDrawerFoundation /** * Event emitted when the drawer is opened or closed. The event value will be * `true` when the drawer is opened, and `false` when the * drawer is closed. (When this event is triggered, the drawer is starting to open/close, * but the animation may not have fully completed yet) */ this.openChange = new EventEmitter(); /** * Event emitted after the drawer has fully opened. When this event is emitted the full * opening animation has completed, and the drawer is visible. */ this.afterOpened = new EventEmitter(); /** * Event emitted after the drawer has fully closed. When this event is emitted the full * closing animation has completed, and the drawer is not visible anymore. */ this.afterClosed = new EventEmitter(); this.document = doc; // work around ngc issue https://github.com/angular/angular/issues/20351 } ngAfterContentInit() { this.initDrawer(); } ngOnDestroy() { this.destroyDrawer(); } destroyDrawer() { // when foundation is reconstructed and then .open() is called, // if these classes are still available the foundation assumes open was already called, // and it won't do anything: this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--animate'); this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--closing'); this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--open'); this._rndr.removeClass(this._elm.nativeElement, 'mdc-drawer--opening'); if (this.foundation) { this.document.removeEventListener('click', this._onDocumentClick); this.foundation.destroy(); this.foundation = null; } } initDrawer() { this.destroyDrawer(); let newFoundation = null; const thiz = this; if (this.type === 'dismissible') newFoundation = new class extends MDCDismissibleDrawerFoundation { close() { const emit = thiz._open; thiz._open = false; super.close(); emit ? thiz.openChange.emit(thiz._open) : undefined; } open() { const emit = !thiz._open; thiz._open = true; super.open(); emit ? thiz.openChange.emit(thiz._open) : undefined; } }(this.mdcAdapter); else if (this.type === 'modal') newFoundation = new class extends MDCModalDrawerFoundation { close() { const emit = thiz._open; thiz._open = false; super.close(); emit ? thiz.openChange.emit(thiz._open) : undefined; } open() { const emit = !thiz._open; thiz._open = true; super.open(); emit ? thiz.openChange.emit(thiz._open) : undefined; } }(this.mdcAdapter); // else: permanent drawer -> doesn't need a foundation, just styling if (newFoundation) { this.foundation = newFoundation; newFoundation.init(); if (this._open) newFoundation.open(); } } /** @internal */ get _isModal() { return this.type === 'modal'; } /** @internal */ get _isDismisible() { return this.type === 'dismissible'; } /** * Set the type of drawer. Either `permanent`, `dismissible`, or `modal`. * The default type is `permanent`. */ get mdcDrawer() { return this.type; } set mdcDrawer(value) { if (value !== 'dismissible' && value !== 'modal') value = 'permanent'; if (value !== this.type) { this.type = value; this.initDrawer(); } } /** * Input to open (assign value `true`) or close (assign value `false`) * the drawer. */ get open() { return !!this._open; } set open(value) { let newValue = asBoolean(value); if (newValue !== this._open) { if (this.foundation) { newValue ? this.foundation.open() : this.foundation.close(); } else { this._open = newValue; this.openChange.emit(newValue); } } } fixOpenClose(open) { // the foundation ignores calls to open/close while an opening/closing animation is running. // so when the animation ends, we're just going to try again // (needs to be done in the next micro cycle, because otherwise foundation will still think it's // running the opening/closing animation): Promise.resolve().then(() => { if (this._open !== open) { if (this._open) this.foundation.open(); else this.foundation.close(); } }); } trapFocus() { this.untrapFocus(); if (this._focusTrap) this.focusTrapHandle = this._focusTrap.trapFocus(); } untrapFocus() { if (this.focusTrapHandle && this.focusTrapHandle.active) { this.focusTrapHandle.untrap(); this.focusTrapHandle = null; } } /** @internal */ onKeydown(event) { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleKeydown(event); } /** @internal */ handleTransitionEnd(event) { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleTransitionEnd(event); } /** @internal */ onDocumentClick(event) { var _a; if (this.type === 'modal') { // instead of listening to click event on mdcDrawerScrim (which would require wiring between // mdcDrawerScrim and mdcDrawer), we just listen to document clicks. let el = event.target; while (el) { if (el === this._elm.nativeElement) return; el = el.parentElement; } (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleScrimClick(); } } } MdcDrawerDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawer]' },] } ]; MdcDrawerDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] }, { type: AbstractMdcFocusTrap, decorators: [{ type: Optional }, { type: Self }] } ]; MdcDrawerDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer',] }], _items: [{ type: ContentChildren, args: [MdcListItemDirective, { descendants: true },] }], openChange: [{ type: Output }], afterOpened: [{ type: Output }], afterClosed: [{ type: Output }], _isModal: [{ type: HostBinding, args: ['class.mdc-drawer--modal',] }], _isDismisible: [{ type: HostBinding, args: ['class.mdc-drawer--dismissible',] }], mdcDrawer: [{ type: Input }], open: [{ type: Input }], onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }], handleTransitionEnd: [{ type: HostListener, args: ['transitionend', ['$event'],] }] }; /** * Use this directive for marking the sibling element after a dismissible `mdcDrawer`. * This will apply styling so that the open/close animations work correctly. */ export class MdcDrawerAppContent { constructor() { /** @internal */ this._cls = true; } /** * Set this to false to disable the styling for sibbling app content of a dismissible drawer. * This is typically only used when your `mdcDrawer` type is dynamic. In those cases you can * disable the `mdcDrawerAppContent` when you set your drawer type to anything other than * `dismissible`. */ get mdcDrawerAppContent() { return this._cls; } set mdcDrawerAppContent(value) { this._cls = asBoolean(value); } } MdcDrawerAppContent.decorators = [ { type: Directive, args: [{ selector: '[mdcDrawerAppContent]' },] } ]; MdcDrawerAppContent.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-drawer-app-content',] }], mdcDrawerAppContent: [{ type: Input }] }; export const DRAWER_DIRECTIVES = [ MdcDrawerTitleDirective, MdcDrawerSubtitleDirective, MdcDrawerHeaderDirective, MdcDrawerContentDirective, MdcDrawerScrimDirective, MdcDrawerDirective, MdcDrawerAppContent ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLmRyYXdlci5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kcmF3ZXIvbWRjLmRyYXdlci5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixlQUFlLEVBQUUsU0FBUyxFQUFFLFVBQVUsRUFBRSxZQUFZLEVBQUUsV0FBVyxFQUN4RixLQUFLLEVBQWEsTUFBTSxFQUFhLFNBQVMsRUFBRSxNQUFNLEVBQUUsUUFBUSxFQUFFLElBQUksRUFBRSxZQUFZLEVBQUUsTUFBTSxlQUFlLENBQUM7QUFDaEgsT0FBTyxFQUFFLDhCQUE4QixFQUFFLHdCQUF3QixFQUFvQixNQUFNLGtCQUFrQixDQUFDO0FBQzlHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSx5QkFBeUIsQ0FBQztBQUNwRCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLG9CQUFvQixFQUFtQixNQUFNLHVDQUF1QyxDQUFDO0FBQzlGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLDRCQUE0QixDQUFDO0FBRWxFOzs7R0FHRztBQUlILE1BQU0sT0FBTyx1QkFBdUI7SUFIcEM7UUFJSSxnQkFBZ0I7UUFDaUMsU0FBSSxHQUFHLElBQUksQ0FBQztJQUNqRSxDQUFDOzs7WUFOQSxTQUFTLFNBQUM7Z0JBQ1AsUUFBUSxFQUFFLGtCQUFrQjthQUMvQjs7O21CQUdJLFdBQVcsU0FBQyx5QkFBeUI7O0FBRzFDOzs7O0dBSUc7QUFJSCxNQUFNLE9BQU8sMEJBQTBCO0lBSHZDO1FBSUksZ0JBQWdCO1FBQ29DLFNBQUksR0FBRyxJQUFJLENBQUM7SUFDcEUsQ0FBQzs7O1lBTkEsU0FBUyxTQUFDO2dCQUNQLFFBQVEsRUFBRSxxQkFBcUI7YUFDbEM7OzttQkFHSSxXQUFXLFNBQUMsNEJBQTRCOztBQUc3Qzs7Ozs7OztHQU9HO0FBSUgsTUFBTSxPQUFPLHdCQUF3QjtJQUhyQztRQUlJLGdCQUFnQjtRQUNrQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2xFLENBQUM7OztZQU5BLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsbUJBQW1CO2FBQ2hDOzs7bUJBR0ksV0FBVyxTQUFDLDBCQUEwQjs7QUFHM0M7OztHQUdHO0FBSUgsTUFBTSxPQUFPLHlCQUF5QjtJQUh0QztRQUlJLGdCQUFnQjtRQUNtQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ25FLENBQUM7OztZQU5BLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsb0JBQW9CO2FBQ2pDOzs7bUJBR0ksV0FBVyxTQUFDLDJCQUEyQjs7QUFNNUMsTUFBTSxPQUFPLHVCQUF1QjtJQUhwQztRQUlJLGdCQUFnQjtRQUNnQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBQ2hFLENBQUM7OztZQU5BLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsa0JBQWtCO2FBQy9COzs7bUJBR0ksV0FBVyxTQUFDLHdCQUF3Qjs7QUFHekM7Ozs7Ozs7Ozs7Ozs7R0FhRztBQUlILE1BQU0sT0FBTyxrQkFBa0I7SUEyRDNCLFlBQW1CLElBQWdCLEVBQVksS0FBZ0IsRUFBb0IsR0FBUSxFQUMzRCxVQUFnQztRQUQ3QyxTQUFJLEdBQUosSUFBSSxDQUFZO1FBQVksVUFBSyxHQUFMLEtBQUssQ0FBVztRQUMvQixlQUFVLEdBQVYsVUFBVSxDQUFzQjtRQTNEaEUsZ0JBQWdCO1FBQzBCLFNBQUksR0FBRyxJQUFJLENBQUM7UUFHOUMscUJBQWdCLEdBQUcsQ0FBQyxLQUFpQixFQUFFLEVBQUUsQ0FBQyxJQUFJLENBQUMsZUFBZSxDQUFDLEtBQUssQ0FBQyxDQUFDO1FBQ3RFLG9CQUFlLEdBQTJCLElBQUksQ0FBQztRQUMvQyxTQUFJLEdBQTBDLFdBQVcsQ0FBQztRQUMxRCxrQkFBYSxHQUFzQyxJQUFJLENBQUM7UUFDeEQsVUFBSyxHQUFtQixJQUFJLENBQUM7UUFFN0IsZUFBVSxHQUFxQjtZQUNuQyxRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQztZQUNqRixXQUFXLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLFNBQVMsQ0FBQztZQUN0RixRQUFRLEVBQUUsQ0FBQyxTQUFTLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxDQUFDLFNBQVMsQ0FBQyxRQUFRLENBQUMsU0FBUyxDQUFDO1lBQzlFLGVBQWUsRUFBRSxDQUFDLE9BQU8sRUFBRSxTQUFTLEVBQUUsRUFBRSxDQUFDLE9BQU8sQ0FBQyxTQUFTLENBQUMsUUFBUSxDQUFDLFNBQVMsQ0FBQztZQUM5RSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLGFBQWEsR0FBRyxJQUFJLENBQUMsUUFBUSxDQUFDLGFBQWE7WUFDakUsWUFBWSxFQUFFLEdBQUcsRUFBRTtnQkFDZixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsYUFBd0MsQ0FBQztnQkFDM0QsSUFBSSxJQUFJLElBQUksSUFBSSxDQUFDLEtBQUssSUFBSSxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsSUFBSSxDQUFDLFFBQVEsQ0FBQyxhQUFhLENBQUM7b0JBQ25GLElBQUksQ0FBQyxLQUFLLEVBQUUsQ0FBQztZQUNyQixDQUFDO1lBQ0QseUJBQXlCLEVBQUUsR0FBRyxFQUFFO2dCQUM1QixNQUFNLE1BQU0sR0FBRyxJQUFJLENBQUMsTUFBTyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsRUFBRSxDQUFDLElBQUksQ0FBQyxNQUFNLENBQUMsQ0FBQztnQkFDdEQsTUFBTSxhQUFOLE1BQU0sdUJBQU4sTUFBTSxDQUFFLElBQUksQ0FBQyxhQUFhLENBQUMsS0FBSyxHQUFHO1lBQ3ZDLENBQUM7WUFDRCxXQUFXLEVBQUUsR0FBRyxFQUFFO2dCQUNkLElBQUksQ0FBQyxZQUFZLENBQUMsS0FBSyxDQUFDLENBQUM7Z0JBQ3pCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ3RFLENBQUM7WUFDRCxVQUFVLEVBQUUsR0FBRyxFQUFFO2dCQUNiLElBQUksQ0FBQyxZQUFZLENBQUMsSUFBSSxDQUFDLENBQUM7Z0JBQ3hCLElBQUksQ0FBQyxXQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7Z0JBQ3hCLElBQUksSUFBSSxDQUFDLElBQUksS0FBSyxPQUFPO29CQUNyQixJQUFJLENBQUMsUUFBUSxDQUFDLGdCQUFnQixDQUFDLE9BQU8sRUFBRSxJQUFJLENBQUMsZ0JBQWdCLENBQUMsQ0FBQztZQUN2RSxDQUFDO1lBQ0QsU0FBUyxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxTQUFTLEVBQUU7WUFDakMsWUFBWSxFQUFFLEdBQUcsRUFBRSxDQUFDLElBQUksQ0FBQyxXQUFXLEVBQUU7U0FDekMsQ0FBQztRQUNNLGVBQVUsR0FBMEMsSUFBSSxDQUFDLENBQUMsa0VBQWtFO1FBQ3BJOzs7OztXQUtHO1FBQ2dCLGVBQVUsR0FBMEIsSUFBSSxZQUFZLEVBQVcsQ0FBQztRQUNuRjs7O1dBR0c7UUFDZ0IsZ0JBQVcsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUN4RTs7O1dBR0c7UUFDZ0IsZ0JBQVcsR0FBdUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQUlwRSxJQUFJLENBQUMsUUFBUSxHQUFHLEdBQWUsQ0FBQyxDQUFDLHdFQUF3RTtJQUM3RyxDQUFDO0lBRUQsa0JBQWtCO1FBQ2QsSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFRCxXQUFXO1FBQ1AsSUFBSSxDQUFDLGFBQWEsRUFBRSxDQUFDO0lBQ3pCLENBQUM7SUFFTyxhQUFhO1FBQ2pCLCtEQUErRDtRQUMvRCx1RkFBdUY7UUFDdkYsNEJBQTRCO1FBQzVCLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDdkUsSUFBSSxDQUFDLEtBQUssQ0FBQyxXQUFXLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUUscUJBQXFCLENBQUMsQ0FBQztRQUN2RSxJQUFJLENBQUMsS0FBSyxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLGFBQWEsRUFBRSxrQkFBa0IsQ0FBQyxDQUFDO1FBQ3BFLElBQUksQ0FBQyxLQUFLLENBQUMsV0FBVyxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFLHFCQUFxQixDQUFDLENBQUM7UUFDdkUsSUFBSSxJQUFJLENBQUMsVUFBVSxFQUFFO1lBQ2pCLElBQUksQ0FBQyxRQUFRLENBQUMsbUJBQW1CLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO1lBQ2xFLElBQUksQ0FBQyxVQUFVLENBQUMsT0FBTyxFQUFFLENBQUM7WUFDMUIsSUFBSSxDQUFDLFVBQVUsR0FBRyxJQUFJLENBQUM7U0FDMUI7SUFDTCxDQUFDO0lBRU8sVUFBVTtRQUNkLElBQUksQ0FBQyxhQUFhLEVBQUUsQ0FBQztRQUNyQixJQUFJLGFBQWEsR0FBMEMsSUFBSSxDQUFDO1FBQ2hFLE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQztRQUNsQixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssYUFBYTtZQUMzQixhQUFhLEdBQUcsSUFBSSxLQUFNLFNBQVEsOEJBQThCO2dCQUM1RCxLQUFLO29CQUNELE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ3hCLElBQUksQ0FBQyxLQUFLLEdBQUcsS0FBSyxDQUFDO29CQUNuQixLQUFLLENBQUMsS0FBSyxFQUFFLENBQUM7b0JBQ2QsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDeEQsQ0FBQztnQkFDRCxJQUFJO29CQUNBLE1BQU0sSUFBSSxHQUFHLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQztvQkFDekIsSUFBSSxDQUFDLEtBQUssR0FBRyxJQUFJLENBQUM7b0JBQ2xCLEtBQUssQ0FBQyxJQUFJLEVBQUUsQ0FBQztvQkFDYixJQUFJLENBQUMsQ0FBQyxDQUFDLElBQUksQ0FBQyxVQUFVLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQyxDQUFDLENBQUMsU0FBUyxDQUFDO2dCQUN4RCxDQUFDO2FBQ0osQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLENBQUM7YUFDbEIsSUFBSSxJQUFJLENBQUMsSUFBSSxLQUFLLE9BQU87WUFDMUIsYUFBYSxHQUFHLElBQUksS0FBTSxTQUFRLHdCQUF3QjtnQkFDdEQsS0FBSztvQkFDRCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsS0FBSyxDQUFDO29CQUN4QixJQUFJLENBQUMsS0FBSyxHQUFHLEtBQUssQ0FBQztvQkFDbkIsS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO29CQUNkLElBQUksQ0FBQyxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxTQUFTLENBQUM7Z0JBQ3hELENBQUM7Z0JBQ0QsSUFBSTtvQkFDQSxNQUFNLElBQUksR0FBRyxDQUFDLElBQUksQ0FBQyxLQUFLLENBQUM7b0JBQ3pCLElBQUksQ0FBQyxLQUFLLEdBQUcsSUFBSSxDQUFDO29CQUNsQixLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7b0JBQ2IsSUFBSSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQyxDQUFDLFNBQVMsQ0FBQztnQkFDeEQsQ0FBQzthQUNKLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxDQUFDO1FBQ3ZCLG9FQUFvRTtRQUNwRSxJQUFJLGFBQWEsRUFBRTtZQUNmLElBQUksQ0FBQyxVQUFVLEdBQUcsYUFBYSxDQUFDO1lBQ2hDLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUNyQixJQUFJLElBQUksQ0FBQyxLQUFLO2dCQUNWLGFBQWEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztTQUM1QjtJQUNMLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsSUFBNEMsUUFBUTtRQUNoRCxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxDQUFDO0lBQ2pDLENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsSUFBa0QsYUFBYTtRQUMzRCxPQUFPLElBQUksQ0FBQyxJQUFJLEtBQUssYUFBYSxDQUFDO0lBQ3ZDLENBQUM7SUFFRDs7O09BR0c7SUFDSCxJQUFhLFNBQVM7UUFDbEIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLFNBQVMsQ0FBQyxLQUE0QztRQUN0RCxJQUFJLEtBQUssS0FBSyxhQUFhLElBQUksS0FBSyxLQUFLLE9BQU87WUFDNUMsS0FBSyxHQUFHLFdBQVcsQ0FBQztRQUN4QixJQUFJLEtBQUssS0FBSyxJQUFJLENBQUMsSUFBSSxFQUFFO1lBQ3JCLElBQUksQ0FBQyxJQUFJLEdBQUcsS0FBSyxDQUFDO1lBQ2xCLElBQUksQ0FBQyxVQUFVLEVBQUUsQ0FBQztTQUNyQjtJQUNMLENBQUM7SUFJRDs7O09BR0c7SUFDSCxJQUFhLElBQUk7UUFDYixPQUFPLENBQUMsQ0FBQyxJQUFJLENBQUMsS0FBSyxDQUFDO0lBQ3hCLENBQUM7SUFFRCxJQUFJLElBQUksQ0FBQyxLQUFjO1FBQ25CLElBQUksUUFBUSxHQUFHLFNBQVMsQ0FBQyxLQUFLLENBQUMsQ0FBQztRQUNoQyxJQUFJLFFBQVEsS0FBSyxJQUFJLENBQUMsS0FBSyxFQUFFO1lBQ3pCLElBQUksSUFBSSxDQUFDLFVBQVUsRUFBRTtnQkFDakIsUUFBUSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksRUFBRSxDQUFDLENBQUMsQ0FBQyxJQUFJLENBQUMsVUFBVSxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQy9EO2lCQUFNO2dCQUNILElBQUksQ0FBQyxLQUFLLEdBQUcsUUFBUSxDQUFDO2dCQUN0QixJQUFJLENBQUMsVUFBVSxDQUFDLElBQUksQ0FBQyxRQUFRLENBQUMsQ0FBQzthQUNsQztTQUNKO0lBQ0wsQ0FBQztJQUlPLFlBQVksQ0FBQyxJQUFhO1FBQzlCLDRGQUE0RjtRQUM1Riw0REFBNEQ7UUFDNUQsZ0dBQWdHO1FBQ2hHLDBDQUEwQztRQUMxQyxPQUFPLENBQUMsT0FBTyxFQUFFLENBQUMsSUFBSSxDQUFDLEdBQUcsRUFBRTtZQUN4QixJQUFJLElBQUksQ0FBQyxLQUFLLEtBQUssSUFBSSxFQUFFO2dCQUNyQixJQUFJLElBQUksQ0FBQyxLQUFLO29CQUNWLElBQUksQ0FBQyxVQUFXLENBQUMsSUFBSSxFQUFFLENBQUM7O29CQUV4QixJQUFJLENBQUMsVUFBVyxDQUFDLEtBQUssRUFBRSxDQUFDO2FBQ2hDO1FBQ0wsQ0FBQyxDQUFDLENBQUM7SUFDUCxDQUFDO0lBRU8sU0FBUztRQUNiLElBQUksQ0FBQyxXQUFXLEVBQUUsQ0FBQztRQUNuQixJQUFJLElBQUksQ0FBQyxVQUFVO1lBQ2YsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUMsVUFBVSxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzNELENBQUM7SUFFTyxXQUFXO1FBQ2YsSUFBSSxJQUFJLENBQUMsZUFBZSxJQUFJLElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFO1lBQ3JELElBQUksQ0FBQyxlQUFlLENBQUMsTUFBTSxFQUFFLENBQUM7WUFDOUIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLENBQUM7U0FDL0I7SUFDTCxDQUFDO0lBRUQsZ0JBQWdCO0lBQ3FCLFNBQVMsQ0FBQyxLQUFvQjs7UUFDL0QsTUFBQSxJQUFJLENBQUMsVUFBVSwwQ0FBRSxhQUFhLENBQUMsS0FBSyxFQUFFO0lBQzFDLENBQUM7SUFFRCxnQkFBZ0I7SUFDMkIsbUJBQW1CLENBQUMsS0FBc0I7O1FBQ2pGLE1BQUEsSUFBSSxDQUFDLFVBQVUsMENBQUUsbUJBQW1CLENBQUMsS0FBSyxFQUFFO0lBQ2hELENBQUM7SUFFRCxnQkFBZ0I7SUFDaEIsZUFBZSxDQUFDLEtBQWlCOztRQUM3QixJQUFJLElBQUksQ0FBQyxJQUFJLEtBQUssT0FBTyxFQUFFO1lBQ3ZCLDRGQUE0RjtZQUM1RixvRUFBb0U7WUFDcEUsSUFBSSxFQUFFLEdBQW1CLEtBQUssQ0FBQyxNQUFpQixDQUFDO1lBQ2pELE9BQU8sRUFBRSxFQUFFO2dCQUNQLElBQUksRUFBRSxLQUFLLElBQUksQ0FBQyxJQUFJLENBQUMsYUFBYTtvQkFDOUIsT0FBTztnQkFDWCxFQUFFLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQzthQUN6QjtZQUNELE1BQUMsSUFBSSxDQUFDLFVBQXVDLDBDQUFFLGdCQUFnQixHQUFHO1NBQ3JFO0lBQ0wsQ0FBQzs7O1lBM09KLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsYUFBYTthQUMxQjs7O1lBckZzRCxVQUFVO1lBQ3hCLFNBQVM7NENBZ0pvQixNQUFNLFNBQUMsUUFBUTtZQTVJNUUsb0JBQW9CLHVCQTZJcEIsUUFBUSxZQUFJLElBQUk7OzttQkExRHBCLFdBQVcsU0FBQyxrQkFBa0I7cUJBRTlCLGVBQWUsU0FBQyxvQkFBb0IsRUFBRSxFQUFDLFdBQVcsRUFBRSxJQUFJLEVBQUM7eUJBMkN6RCxNQUFNOzBCQUtOLE1BQU07MEJBS04sTUFBTTt1QkEwRU4sV0FBVyxTQUFDLHlCQUF5Qjs0QkFLckMsV0FBVyxTQUFDLCtCQUErQjt3QkFRM0MsS0FBSzttQkFtQkwsS0FBSzt3QkErQ0wsWUFBWSxTQUFDLFNBQVMsRUFBRSxDQUFDLFFBQVEsQ0FBQztrQ0FLbEMsWUFBWSxTQUFDLGVBQWUsRUFBRSxDQUFDLFFBQVEsQ0FBQzs7QUFvQjdDOzs7R0FHRztBQUlILE1BQU0sT0FBTyxtQkFBbUI7SUFIaEM7UUFJSSxnQkFBZ0I7UUFDNkIsU0FBSSxHQUFHLElBQUksQ0FBQztJQWlCN0QsQ0FBQztJQWZHOzs7OztPQUtHO0lBQ0gsSUFBYSxtQkFBbUI7UUFDNUIsT0FBTyxJQUFJLENBQUMsSUFBSSxDQUFDO0lBQ3JCLENBQUM7SUFFRCxJQUFJLG1CQUFtQixDQUFDLEtBQWM7UUFDbEMsSUFBSSxDQUFDLElBQUksR0FBRyxTQUFTLENBQUMsS0FBSyxDQUFDLENBQUM7SUFDakMsQ0FBQzs7O1lBbkJKLFNBQVMsU0FBQztnQkFDUCxRQUFRLEVBQUUsdUJBQXVCO2FBQ3BDOzs7bUJBR0ksV0FBVyxTQUFDLDhCQUE4QjtrQ0FRMUMsS0FBSzs7QUFXVixNQUFNLENBQUMsTUFBTSxpQkFBaUIsR0FBRztJQUM3Qix1QkFBdUI7SUFDdkIsMEJBQTBCO0lBQzFCLHdCQUF3QjtJQUN4Qix5QkFBeUI7SUFDekIsdUJBQXVCO0lBQ3ZCLGtCQUFrQjtJQUNsQixtQkFBbUI7Q0FDdEIsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IEFmdGVyQ29udGVudEluaXQsIENvbnRlbnRDaGlsZHJlbiwgRGlyZWN0aXZlLCBFbGVtZW50UmVmLCBFdmVudEVtaXR0ZXIsIEhvc3RCaW5kaW5nLFxuICAgIElucHV0LCBPbkRlc3Ryb3ksIE91dHB1dCwgUXVlcnlMaXN0LCBSZW5kZXJlcjIsIEluamVjdCwgT3B0aW9uYWwsIFNlbGYsIEhvc3RMaXN0ZW5lciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgTURDRGlzbWlzc2libGVEcmF3ZXJGb3VuZGF0aW9uLCBNRENNb2RhbERyYXdlckZvdW5kYXRpb24sIE1EQ0RyYXdlckFkYXB0ZXIgfSBmcm9tICdAbWF0ZXJpYWwvZHJhd2VyJztcbmltcG9ydCB7IGFzQm9vbGVhbiB9IGZyb20gJy4uLy4uL3V0aWxzL3ZhbHVlLnV0aWxzJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7IEFic3RyYWN0TWRjRm9jdXNUcmFwLCBGb2N1c1RyYXBIYW5kbGUgfSBmcm9tICcuLi9mb2N1cy10cmFwL2Fic3RyYWN0Lm1kYy5mb2N1cy10cmFwJztcbmltcG9ydCB7IE1kY0xpc3RJdGVtRGlyZWN0aXZlIH0gZnJvbSAnLi4vbGlzdC9tZGMubGlzdC5kaXJlY3RpdmUnO1xuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgdGhlIHRpdGxlIG9mIGEgZHJhd2VyLiBUaGUgdXNlIG9mIHRoaXMgZGlyZWN0aXZlIGlzIG9wdGlvbmFsLlxuICogSWYgdXNlZCwgaXQgc2hvdWxkIGJlIHBsYWNlZCBhcyBmaXJzdCBlbGVtZW50IGluc2lkZSBhbiBgbWRjRHJhd2VySGVhZGVyYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJUaXRsZV0nXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RyYXdlclRpdGxlRGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZHJhd2VyX190aXRsZScpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xufVxuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgdGhlIHN1YnRpdGxlIG9mIGEgZHJhd2VyLiBUaGUgdXNlIG9mIHRoaXMgZGlyZWN0aXZlIGlzIG9wdGlvbmFsLlxuICogSWYgdXNlZCwgaXQgc2hvdWxkIGJlIHBsYWNlZCBhcyBhIHNpYmxpbmcgZWxlbWVudCBvZiBgbWRjRHJhd2VyVGl0bGVgXG4gKiBpbnNpZGUgYW4gYG1kY0RyYXdlckhlYWRlcmBcbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRHJhd2VyU3VidGl0bGVdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJTdWJ0aXRsZURpcmVjdGl2ZSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRyYXdlcl9fc3VidGl0bGUnKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBBIHRvb2xiYXIgaGVhZGVyIGlzIGFuIG9wdGlvbmFsIGZpcnN0IGNoaWxkIG9mIGFuIGBtZGNEcmF3ZXJgLlxuICogVGhlIGhlYWRlciB3aWxsIG5vdCBzY3JvbGwgd2l0aCB0aGUgcmVzdCBvZiB0aGUgZHJhd2VyIGNvbnRlbnQsIHNvIGlzIGFcbiAqIGdvb2QgcGxhY2UgdG8gcGxhY2UgdGl0bGVzIGFuZCBhY2NvdW50IHN3aXRjaGVycy5cbiAqIFxuICogRGlyZWN0aXZlcyB0aGF0IGFyZSB0eXBpY2FsbHkgdXNlZCBpbnNpZGUgYW4gYG1kY0RyYXdlckhlYWRlcmA6XG4gKiBgbWRjRHJhd2VyVGl0bGVgLCBhbmQgYG1kY0RyYXdlclN1YlRpdGxlYFxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJIZWFkZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJIZWFkZXJEaXJlY3RpdmUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXJfX2hlYWRlcicpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xufVxuXG4vKipcbiAqIERpcmVjdGl2ZSBmb3IgdGhlIGRyYXdlciBjb250ZW50LiBZb3Ugd291bGQgdHlwaWNhbGx5IGFsc28gYXBwbHkgdGhlIGBtZGNMaXN0YFxuICogb3IgYG1kY0xpc3RHcm91cGAgZGlyZWN0aXZlIHRvIHRoZSBkcmF3ZXIgY29udGVudCAoc2VlIHRoZSBleGFtcGxlcykuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RyYXdlckNvbnRlbnRdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJDb250ZW50RGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZHJhd2VyX19jb250ZW50JykgcmVhZG9ubHkgX2NscyA9IHRydWU7XG59XG5cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RyYXdlclNjcmltXSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRHJhd2VyU2NyaW1EaXJlY3RpdmUge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXItc2NyaW0nKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIGEgKG5hdmlnYXRpb24pIGRyYXdlci4gVGhlIGZvbGxvd2luZyBkcmF3ZXIgdHlwZXMgYXJlXG4gKiBzdXBwb3J0ZWQ6XG4gKiAqIGBwZXJtYW5lbnRgOiB0aGUgZGVmYXVsdCB0eXBlIGlmIG5vbmUgd2FzIHNwZWNpZmllZC5cbiAqICogYGRpc21pc3NpYmxlYDogdGhlIGRyYXdlciBpcyBoaWRkZW4gYnkgZGVmYXVsdCwgYW5kIGNhbiBzbGlkZSBpbnRvIHZpZXcuXG4gKiAgIFR5cGljYWxseSB1c2VkIHdoZW4gbmF2aWdhdGlvbiBpcyBub3QgY29tbW9uLCBhbmQgdGhlIG1haW4gYXBwIGNvbnRlbnQgaXNcbiAqICAgcHJpb3JpdGl6ZWQuXG4gKiAqIGBtb2RhbGA6IHRoZSBkcmF3ZXIgaXMgaGlkZGVuIGJ5IGRlZmF1bHQuIFdoZW4gYWN0aXZhdGVkLCB0aGUgZHJhd2VyIGlzIGVsZXZhdGVkXG4gKiAgIGFib3ZlIHRoZSBVSSBvZiB0aGUgYXBwLiBJdCB1c2VzIGEgc2NyaW0gdG8gYmxvY2sgaW50ZXJhY3Rpb24gd2l0aCB0aGUgcmVzdCBvZlxuICogICB0aGUgYXBwIHdpdGggYSBzY3JpbS5cbiAqIFxuICogRHJhd2VycyBtYXkgY29udGFpbiBhbiBgbWRjRHJhd2VySGVhZGVyYCwgYW5kIHNob3VsZCBjb250YWluIGFuIGBtZGNEcmF3ZXJDb250ZW50YFxuICogZGlyZWN0aXZlLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEcmF3ZXJEaXJlY3RpdmUgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXInKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNMaXN0SXRlbURpcmVjdGl2ZSwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX2l0ZW1zPzogUXVlcnlMaXN0PE1kY0xpc3RJdGVtRGlyZWN0aXZlPjtcbiAgICBwcml2YXRlIF9vbkRvY3VtZW50Q2xpY2sgPSAoZXZlbnQ6IE1vdXNlRXZlbnQpID0+IHRoaXMub25Eb2N1bWVudENsaWNrKGV2ZW50KTtcbiAgICBwcml2YXRlIGZvY3VzVHJhcEhhbmRsZTogRm9jdXNUcmFwSGFuZGxlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSB0eXBlOiAncGVybWFuZW50JyB8ICdkaXNtaXNzaWJsZScgfCAnbW9kYWwnID0gJ3Blcm1hbmVudCc7XG4gICAgcHJpdmF0ZSBwcmV2aW91c0ZvY3VzOiBFbGVtZW50IHwgSFRNTE9yU1ZHRWxlbWVudCB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgX29wZW46IGJvb2xlYW4gfCBudWxsID0gbnVsbDtcbiAgICBwcml2YXRlIGRvY3VtZW50OiBEb2N1bWVudDtcbiAgICBwcml2YXRlIG1kY0FkYXB0ZXI6IE1EQ0RyYXdlckFkYXB0ZXIgPSB7XG4gICAgICAgIGFkZENsYXNzOiAoY2xhc3NOYW1lKSA9PiAgdGhpcy5fcm5kci5hZGRDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgY2xhc3NOYW1lKSxcbiAgICAgICAgcmVtb3ZlQ2xhc3M6IChjbGFzc05hbWUpID0+IHRoaXMuX3JuZHIucmVtb3ZlQ2xhc3ModGhpcy5fZWxtLm5hdGl2ZUVsZW1lbnQsIGNsYXNzTmFtZSksXG4gICAgICAgIGhhc0NsYXNzOiAoY2xhc3NOYW1lKSA9PiB0aGlzLl9lbG0ubmF0aXZlRWxlbWVudC5jbGFzc0xpc3QuY29udGFpbnMoY2xhc3NOYW1lKSxcbiAgICAgICAgZWxlbWVudEhhc0NsYXNzOiAoZWxlbWVudCwgY2xhc3NOYW1lKSA9PiBlbGVtZW50LmNsYXNzTGlzdC5jb250YWlucyhjbGFzc05hbWUpLFxuICAgICAgICBzYXZlRm9jdXM6ICgpID0+IHRoaXMucHJldmlvdXNGb2N1cyA9IHRoaXMuZG9jdW1lbnQuYWN0aXZlRWxlbWVudCxcbiAgICAgICAgcmVzdG9yZUZvY3VzOiAoKSA9PiB7XG4gICAgICAgICAgICBjb25zdCBwcmV2ID0gdGhpcy5wcmV2aW91c0ZvY3VzIGFzIEhUTUxPclNWR0VsZW1lbnQgfCBudWxsO1xuICAgICAgICAgICAgaWYgKHByZXYgJiYgcHJldi5mb2N1cyAmJiB0aGlzLl9lbG0ubmF0aXZlRWxlbWVudC5jb250YWlucyh0aGlzLmRvY3VtZW50LmFjdGl2ZUVsZW1lbnQpKVxuICAgICAgICAgICAgICAgIHByZXYuZm9jdXMoKTtcbiAgICAgICAgfSxcbiAgICAgICAgZm9jdXNBY3RpdmVOYXZpZ2F0aW9uSXRlbTogKCkgPT4ge1xuICAgICAgICAgICAgY29uc3QgYWN0aXZlID0gdGhpcy5faXRlbXMhLmZpbmQoaXRlbSA9PiBpdGVtLmFjdGl2ZSk7XG4gICAgICAgICAgICBhY3RpdmU/Ll9lbG0ubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgICAgICB9LFxuICAgICAgICBub3RpZnlDbG9zZTogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5maXhPcGVuQ2xvc2UoZmFsc2UpO1xuICAgICAgICAgICAgdGhpcy5hZnRlckNsb3NlZC5lbWl0KCk7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LnJlbW92ZUV2ZW50TGlzdGVuZXIoJ2NsaWNrJywgdGhpcy5fb25Eb2N1bWVudENsaWNrKTtcbiAgICAgICAgfSxcbiAgICAgICAgbm90aWZ5T3BlbjogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5maXhPcGVuQ2xvc2UodHJ1ZSk7XG4gICAgICAgICAgICB0aGlzLmFmdGVyT3BlbmVkLmVtaXQoKTtcbiAgICAgICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdtb2RhbCcpXG4gICAgICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5hZGRFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uRG9jdW1lbnRDbGljayk7XG4gICAgICAgIH0sXG4gICAgICAgIHRyYXBGb2N1czogKCkgPT4gdGhpcy50cmFwRm9jdXMoKSxcbiAgICAgICAgcmVsZWFzZUZvY3VzOiAoKSA9PiB0aGlzLnVudHJhcEZvY3VzKClcbiAgICB9O1xuICAgIHByaXZhdGUgZm91bmRhdGlvbjogTURDRGlzbWlzc2libGVEcmF3ZXJGb3VuZGF0aW9uIHwgbnVsbCA9IG51bGw7IC8vIE1EQ01vZGFsRHJhd2VyRm91bmRhdGlvbiBleHRlbmRzIE1EQ0Rpc21pc3NpYmxlRHJhd2VyRm91bmRhdGlvblxuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgZHJhd2VyIGlzIG9wZW5lZCBvciBjbG9zZWQuIFRoZSBldmVudCB2YWx1ZSB3aWxsIGJlXG4gICAgICogYHRydWVgIHdoZW4gdGhlIGRyYXdlciBpcyBvcGVuZWQsIGFuZCBgZmFsc2VgIHdoZW4gdGhlXG4gICAgICogZHJhd2VyIGlzIGNsb3NlZC4gKFdoZW4gdGhpcyBldmVudCBpcyB0cmlnZ2VyZWQsIHRoZSBkcmF3ZXIgaXMgc3RhcnRpbmcgdG8gb3Blbi9jbG9zZSxcbiAgICAgKiBidXQgdGhlIGFuaW1hdGlvbiBtYXkgbm90IGhhdmUgZnVsbHkgY29tcGxldGVkIHlldClcbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbkNoYW5nZTogRXZlbnRFbWl0dGVyPGJvb2xlYW4+ID0gbmV3IEV2ZW50RW1pdHRlcjxib29sZWFuPigpO1xuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgYWZ0ZXIgdGhlIGRyYXdlciBoYXMgZnVsbHkgb3BlbmVkLiBXaGVuIHRoaXMgZXZlbnQgaXMgZW1pdHRlZCB0aGUgZnVsbFxuICAgICAqIG9wZW5pbmcgYW5pbWF0aW9uIGhhcyBjb21wbGV0ZWQsIGFuZCB0aGUgZHJhd2VyIGlzIHZpc2libGUuXG4gICAgICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGFmdGVyT3BlbmVkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCBhZnRlciB0aGUgZHJhd2VyIGhhcyBmdWxseSBjbG9zZWQuIFdoZW4gdGhpcyBldmVudCBpcyBlbWl0dGVkIHRoZSBmdWxsXG4gICAgICogY2xvc2luZyBhbmltYXRpb24gaGFzIGNvbXBsZXRlZCwgYW5kIHRoZSBkcmF3ZXIgaXMgbm90IHZpc2libGUgYW55bW9yZS5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgYWZ0ZXJDbG9zZWQ6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICBcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZiwgcHJvdGVjdGVkIF9ybmRyOiBSZW5kZXJlcjIsIEBJbmplY3QoRE9DVU1FTlQpIGRvYzogYW55LFxuICAgICAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgX2ZvY3VzVHJhcDogQWJzdHJhY3RNZGNGb2N1c1RyYXApIHtcbiAgICAgICAgdGhpcy5kb2N1bWVudCA9IGRvYyBhcyBEb2N1bWVudDsgLy8gd29yayBhcm91bmQgbmdjIGlzc3VlIGh0dHBzOi8vZ2l0aHViLmNvbS9hbmd1bGFyL2FuZ3VsYXIvaXNzdWVzLzIwMzUxXG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICB0aGlzLmluaXREcmF3ZXIoKTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95RHJhd2VyKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBkZXN0cm95RHJhd2VyKCkge1xuICAgICAgICAvLyB3aGVuIGZvdW5kYXRpb24gaXMgcmVjb25zdHJ1Y3RlZCBhbmQgdGhlbiAub3BlbigpIGlzIGNhbGxlZCxcbiAgICAgICAgLy8gaWYgdGhlc2UgY2xhc3NlcyBhcmUgc3RpbGwgYXZhaWxhYmxlIHRoZSBmb3VuZGF0aW9uIGFzc3VtZXMgb3BlbiB3YXMgYWxyZWFkeSBjYWxsZWQsXG4gICAgICAgIC8vIGFuZCBpdCB3b24ndCBkbyBhbnl0aGluZzpcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLWFuaW1hdGUnKTtcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLWNsb3NpbmcnKTtcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLW9wZW4nKTtcbiAgICAgICAgdGhpcy5fcm5kci5yZW1vdmVDbGFzcyh0aGlzLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kcmF3ZXItLW9wZW5pbmcnKTtcbiAgICAgICAgaWYgKHRoaXMuZm91bmRhdGlvbikge1xuICAgICAgICAgICAgdGhpcy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdjbGljaycsIHRoaXMuX29uRG9jdW1lbnRDbGljayk7XG4gICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24uZGVzdHJveSgpO1xuICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uID0gbnVsbDtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdERyYXdlcigpIHtcbiAgICAgICAgdGhpcy5kZXN0cm95RHJhd2VyKCk7XG4gICAgICAgIGxldCBuZXdGb3VuZGF0aW9uOiBNRENEaXNtaXNzaWJsZURyYXdlckZvdW5kYXRpb24gfCBudWxsID0gbnVsbDtcbiAgICAgICAgY29uc3QgdGhpeiA9IHRoaXM7XG4gICAgICAgIGlmICh0aGlzLnR5cGUgPT09ICdkaXNtaXNzaWJsZScpXG4gICAgICAgICAgICBuZXdGb3VuZGF0aW9uID0gbmV3IGNsYXNzIGV4dGVuZHMgTURDRGlzbWlzc2libGVEcmF3ZXJGb3VuZGF0aW9ue1xuICAgICAgICAgICAgICAgIGNsb3NlKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbWl0ID0gdGhpei5fb3BlbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpei5fb3BlbiA9IGZhbHNlO1xuICAgICAgICAgICAgICAgICAgICBzdXBlci5jbG9zZSgpO1xuICAgICAgICAgICAgICAgICAgICBlbWl0ID8gdGhpei5vcGVuQ2hhbmdlLmVtaXQodGhpei5fb3BlbikgOiB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgfVxuICAgICAgICAgICAgICAgIG9wZW4oKSB7XG4gICAgICAgICAgICAgICAgICAgIGNvbnN0IGVtaXQgPSAhdGhpei5fb3BlbjtcbiAgICAgICAgICAgICAgICAgICAgdGhpei5fb3BlbiA9IHRydWU7XG4gICAgICAgICAgICAgICAgICAgIHN1cGVyLm9wZW4oKTtcbiAgICAgICAgICAgICAgICAgICAgZW1pdCA/IHRoaXoub3BlbkNoYW5nZS5lbWl0KHRoaXouX29wZW4pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH0odGhpcy5tZGNBZGFwdGVyKTtcbiAgICAgICAgZWxzZSBpZiAodGhpcy50eXBlID09PSAnbW9kYWwnKVxuICAgICAgICAgICAgbmV3Rm91bmRhdGlvbiA9IG5ldyBjbGFzcyBleHRlbmRzIE1EQ01vZGFsRHJhd2VyRm91bmRhdGlvbntcbiAgICAgICAgICAgICAgICBjbG9zZSgpIHtcbiAgICAgICAgICAgICAgICAgICAgY29uc3QgZW1pdCA9IHRoaXouX29wZW47XG4gICAgICAgICAgICAgICAgICAgIHRoaXouX29wZW4gPSBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgc3VwZXIuY2xvc2UoKTtcbiAgICAgICAgICAgICAgICAgICAgZW1pdCA/IHRoaXoub3BlbkNoYW5nZS5lbWl0KHRoaXouX29wZW4pIDogdW5kZWZpbmVkO1xuICAgICAgICAgICAgICAgIH1cbiAgICAgICAgICAgICAgICBvcGVuKCkge1xuICAgICAgICAgICAgICAgICAgICBjb25zdCBlbWl0ID0gIXRoaXouX29wZW47XG4gICAgICAgICAgICAgICAgICAgIHRoaXouX29wZW4gPSB0cnVlO1xuICAgICAgICAgICAgICAgICAgICBzdXBlci5vcGVuKCk7XG4gICAgICAgICAgICAgICAgICAgIGVtaXQgPyB0aGl6Lm9wZW5DaGFuZ2UuZW1pdCh0aGl6Ll9vcGVuKSA6IHVuZGVmaW5lZDtcbiAgICAgICAgICAgICAgICB9XG4gICAgICAgICAgICB9KHRoaXMubWRjQWRhcHRlcik7XG4gICAgICAgIC8vIGVsc2U6IHBlcm1hbmVudCBkcmF3ZXIgLT4gZG9lc24ndCBuZWVkIGEgZm91bmRhdGlvbiwganVzdCBzdHlsaW5nXG4gICAgICAgIGlmIChuZXdGb3VuZGF0aW9uKSB7XG4gICAgICAgICAgICB0aGlzLmZvdW5kYXRpb24gPSBuZXdGb3VuZGF0aW9uO1xuICAgICAgICAgICAgbmV3Rm91bmRhdGlvbi5pbml0KCk7XG4gICAgICAgICAgICBpZiAodGhpcy5fb3BlbilcbiAgICAgICAgICAgICAgICBuZXdGb3VuZGF0aW9uLm9wZW4oKTtcbiAgICAgICAgfVxuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXItLW1vZGFsJykgZ2V0IF9pc01vZGFsKCkge1xuICAgICAgICByZXR1cm4gdGhpcy50eXBlID09PSAnbW9kYWwnO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2NsYXNzLm1kYy1kcmF3ZXItLWRpc21pc3NpYmxlJykgZ2V0IF9pc0Rpc21pc2libGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLnR5cGUgPT09ICdkaXNtaXNzaWJsZSc7XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogU2V0IHRoZSB0eXBlIG9mIGRyYXdlci4gRWl0aGVyIGBwZXJtYW5lbnRgLCBgZGlzbWlzc2libGVgLCBvciBgbW9kYWxgLlxuICAgICAqIFRoZSBkZWZhdWx0IHR5cGUgaXMgYHBlcm1hbmVudGAuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IG1kY0RyYXdlcigpOiAncGVybWFuZW50JyB8ICdkaXNtaXNzaWJsZScgfCAnbW9kYWwnIHtcbiAgICAgICAgcmV0dXJuIHRoaXMudHlwZTtcbiAgICB9XG5cbiAgICBzZXQgbWRjRHJhd2VyKHZhbHVlOiAncGVybWFuZW50JyB8ICdkaXNtaXNzaWJsZScgfCAnbW9kYWwnKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gJ2Rpc21pc3NpYmxlJyAmJiB2YWx1ZSAhPT0gJ21vZGFsJylcbiAgICAgICAgICAgIHZhbHVlID0gJ3Blcm1hbmVudCc7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdGhpcy50eXBlKSB7XG4gICAgICAgICAgICB0aGlzLnR5cGUgPSB2YWx1ZTtcbiAgICAgICAgICAgIHRoaXMuaW5pdERyYXdlcigpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgc3RhdGljIG5nQWNjZXB0SW5wdXRUeXBlX21kY0RyYXdlcjogJ3Blcm1hbmVudCcgfCAnZGlzbWlzc2libGUnIHwgJ21vZGFsJyB8ICcnO1xuXG4gICAgLyoqXG4gICAgICogSW5wdXQgdG8gb3BlbiAoYXNzaWduIHZhbHVlIGB0cnVlYCkgb3IgY2xvc2UgKGFzc2lnbiB2YWx1ZSBgZmFsc2VgKVxuICAgICAqIHRoZSBkcmF3ZXIuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IG9wZW4oKSB7XG4gICAgICAgIHJldHVybiAhIXRoaXMuX29wZW47XG4gICAgfVxuXG4gICAgc2V0IG9wZW4odmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgbGV0IG5ld1ZhbHVlID0gYXNCb29sZWFuKHZhbHVlKTtcbiAgICAgICAgaWYgKG5ld1ZhbHVlICE9PSB0aGlzLl9vcGVuKSB7XG4gICAgICAgICAgICBpZiAodGhpcy5mb3VuZGF0aW9uKSB7XG4gICAgICAgICAgICAgICAgbmV3VmFsdWUgPyB0aGlzLmZvdW5kYXRpb24ub3BlbigpIDogdGhpcy5mb3VuZGF0aW9uLmNsb3NlKCk7XG4gICAgICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgICAgICAgIHRoaXMuX29wZW4gPSBuZXdWYWx1ZTtcbiAgICAgICAgICAgICAgICB0aGlzLm9wZW5DaGFuZ2UuZW1pdChuZXdWYWx1ZSk7XG4gICAgICAgICAgICB9XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfb3BlbjogYm9vbGVhbiB8ICcnO1xuXG4gICAgcHJpdmF0ZSBmaXhPcGVuQ2xvc2Uob3BlbjogYm9vbGVhbikge1xuICAgICAgICAvLyB0aGUgZm91bmRhdGlvbiBpZ25vcmVzIGNhbGxzIHRvIG9wZW4vY2xvc2Ugd2hpbGUgYW4gb3BlbmluZy9jbG9zaW5nIGFuaW1hdGlvbiBpcyBydW5uaW5nLlxuICAgICAgICAvLyBzbyB3aGVuIHRoZSBhbmltYXRpb24gZW5kcywgd2UncmUganVzdCBnb2luZyB0byB0cnkgYWdhaW5cbiAgICAgICAgLy8gKG5lZWRzIHRvIGJlIGRvbmUgaW4gdGhlIG5leHQgbWljcm8gY3ljbGUsIGJlY2F1c2Ugb3RoZXJ3aXNlIGZvdW5kYXRpb24gd2lsbCBzdGlsbCB0aGluayBpdCdzXG4gICAgICAgIC8vIHJ1bm5pbmcgdGhlIG9wZW5pbmcvY2xvc2luZyBhbmltYXRpb24pOlxuICAgICAgICBQcm9taXNlLnJlc29sdmUoKS50aGVuKCgpID0+IHtcbiAgICAgICAgICAgIGlmICh0aGlzLl9vcGVuICE9PSBvcGVuKSB7XG4gICAgICAgICAgICAgICAgaWYgKHRoaXMuX29wZW4pXG4gICAgICAgICAgICAgICAgICAgIHRoaXMuZm91bmRhdGlvbiEub3BlbigpO1xuICAgICAgICAgICAgICAgIGVsc2VcbiAgICAgICAgICAgICAgICAgICAgdGhpcy5mb3VuZGF0aW9uIS5jbG9zZSgpO1xuICAgICAgICAgICAgfVxuICAgICAgICB9KTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHRyYXBGb2N1cygpIHtcbiAgICAgICAgdGhpcy51bnRyYXBGb2N1cygpO1xuICAgICAgICBpZiAodGhpcy5fZm9jdXNUcmFwKVxuICAgICAgICAgICAgdGhpcy5mb2N1c1RyYXBIYW5kbGUgPSB0aGlzLl9mb2N1c1RyYXAudHJhcEZvY3VzKCk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSB1bnRyYXBGb2N1cygpIHtcbiAgICAgICAgaWYgKHRoaXMuZm9jdXNUcmFwSGFuZGxlICYmIHRoaXMuZm9jdXNUcmFwSGFuZGxlLmFjdGl2ZSkge1xuICAgICAgICAgICAgdGhpcy5mb2N1c1RyYXBIYW5kbGUudW50cmFwKCk7XG4gICAgICAgICAgICB0aGlzLmZvY3VzVHJhcEhhbmRsZSA9IG51bGw7XG4gICAgICAgIH1cbiAgICB9XG5cbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RMaXN0ZW5lcigna2V5ZG93bicsIFsnJGV2ZW50J10pIG9uS2V5ZG93bihldmVudDogS2V5Ym9hcmRFdmVudCkge1xuICAgICAgICB0aGlzLmZvdW5kYXRpb24/LmhhbmRsZUtleWRvd24oZXZlbnQpO1xuICAgIH1cblxuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdExpc3RlbmVyKCd0cmFuc2l0aW9uZW5kJywgWyckZXZlbnQnXSkgaGFuZGxlVHJhbnNpdGlvbkVuZChldmVudDogVHJhbnNpdGlvbkV2ZW50KSB7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbj8uaGFuZGxlVHJhbnNpdGlvbkVuZChldmVudCk7XG4gICAgfVxuXG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIG9uRG9jdW1lbnRDbGljayhldmVudDogTW91c2VFdmVudCkge1xuICAgICAgICBpZiAodGhpcy50eXBlID09PSAnbW9kYWwnKSB7XG4gICAgICAgICAgICAvLyBpbnN0ZWFkIG9mIGxpc3RlbmluZyB0byBjbGljayBldmVudCBvbiBtZGNEcmF3ZXJTY3JpbSAod2hpY2ggd291bGQgcmVxdWlyZSB3aXJpbmcgYmV0d2VlblxuICAgICAgICAgICAgLy8gbWRjRHJhd2VyU2NyaW0gYW5kIG1kY0RyYXdlciksIHdlIGp1c3QgbGlzdGVuIHRvIGRvY3VtZW50IGNsaWNrcy5cbiAgICAgICAgICAgIGxldCBlbDogRWxlbWVudCB8IG51bGwgPSBldmVudC50YXJnZXQgYXMgRWxlbWVudDtcbiAgICAgICAgICAgIHdoaWxlIChlbCkge1xuICAgICAgICAgICAgICAgIGlmIChlbCA9PT0gdGhpcy5fZWxtLm5hdGl2ZUVsZW1lbnQpXG4gICAgICAgICAgICAgICAgICAgIHJldHVybjtcbiAgICAgICAgICAgICAgICBlbCA9IGVsLnBhcmVudEVsZW1lbnQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICAodGhpcy5mb3VuZGF0aW9uIGFzIE1EQ01vZGFsRHJhd2VyRm91bmRhdGlvbik/LmhhbmRsZVNjcmltQ2xpY2soKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuLyoqXG4gKiBVc2UgdGhpcyBkaXJlY3RpdmUgZm9yIG1hcmtpbmcgdGhlIHNpYmxpbmcgZWxlbWVudCBhZnRlciBhIGRpc21pc3NpYmxlIGBtZGNEcmF3ZXJgLlxuICogVGhpcyB3aWxsIGFwcGx5IHN0eWxpbmcgc28gdGhhdCB0aGUgb3Blbi9jbG9zZSBhbmltYXRpb25zIHdvcmsgY29ycmVjdGx5LlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEcmF3ZXJBcHBDb250ZW50XSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRHJhd2VyQXBwQ29udGVudCB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRyYXdlci1hcHAtY29udGVudCcpIF9jbHMgPSB0cnVlO1xuXG4gICAgLyoqXG4gICAgICogU2V0IHRoaXMgdG8gZmFsc2UgdG8gZGlzYWJsZSB0aGUgc3R5bGluZyBmb3Igc2liYmxpbmcgYXBwIGNvbnRlbnQgb2YgYSBkaXNtaXNzaWJsZSBkcmF3ZXIuXG4gICAgICogVGhpcyBpcyB0eXBpY2FsbHkgb25seSB1c2VkIHdoZW4geW91ciBgbWRjRHJhd2VyYCB0eXBlIGlzIGR5bmFtaWMuIEluIHRob3NlIGNhc2VzIHlvdSBjYW5cbiAgICAgKiBkaXNhYmxlIHRoZSBgbWRjRHJhd2VyQXBwQ29udGVudGAgd2hlbiB5b3Ugc2V0IHlvdXIgZHJhd2VyIHR5cGUgdG8gYW55dGhpbmcgb3RoZXIgdGhhblxuICAgICAqIGBkaXNtaXNzaWJsZWAuXG4gICAgICovXG4gICAgQElucHV0KCkgZ2V0IG1kY0RyYXdlckFwcENvbnRlbnQoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9jbHM7XG4gICAgfVxuXG4gICAgc2V0IG1kY0RyYXdlckFwcENvbnRlbnQodmFsdWU6IGJvb2xlYW4pIHtcbiAgICAgICAgdGhpcy5fY2xzID0gYXNCb29sZWFuKHZhbHVlKTtcbiAgICB9XG5cbiAgICBzdGF0aWMgbmdBY2NlcHRJbnB1dFR5cGVfbWRjRHJhd2VyQXBwQ29udGVudDogYm9vbGVhbiB8ICcnO1xufVxuXG5leHBvcnQgY29uc3QgRFJBV0VSX0RJUkVDVElWRVMgPSBbXG4gICAgTWRjRHJhd2VyVGl0bGVEaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VyU3VidGl0bGVEaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VySGVhZGVyRGlyZWN0aXZlLFxuICAgIE1kY0RyYXdlckNvbnRlbnREaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VyU2NyaW1EaXJlY3RpdmUsXG4gICAgTWRjRHJhd2VyRGlyZWN0aXZlLFxuICAgIE1kY0RyYXdlckFwcENvbnRlbnRcbl07XG4iXX0=