UNPKG

@blox/material

Version:

Material Components for Angular

453 lines 52.8 kB
import { ContentChild, ContentChildren, Directive, ElementRef, EventEmitter, HostBinding, Input, Optional, Output, Renderer2, Self, Inject, HostListener, forwardRef } from '@angular/core'; import { DOCUMENT } from '@angular/common'; import { MDCDialogFoundation, util, cssClasses } from '@material/dialog'; import { ponyfill } from '@material/dom'; import { MdcEventRegistry } from '../../utils/mdc.event.registry'; import { MdcButtonDirective } from '../button/mdc.button.directive'; import { AbstractMdcFocusInitial, AbstractMdcFocusTrap } from '../focus-trap/abstract.mdc.focus-trap'; import { HasId } from '../abstract/mixin.mdc.hasid'; import { applyMixins } from '../../utils/mixins'; class MdcDialogTitleDirectiveBase { } MdcDialogTitleDirectiveBase.decorators = [ { type: Directive } ]; applyMixins(MdcDialogTitleDirectiveBase, [HasId]); /** * Directive for the title of an `mdcDialog`. * A title is optional. If used, it should be the first child of an `mdcDialogSurface`. * Please note that there should be no whitespace separating the start/end tag and the title * itself. (The easiest way to achieve this is to *not* set the `preserveWhitespaces` option to * `true` the `angularCompilerOptions`). */ export class MdcDialogTitleDirective extends MdcDialogTitleDirectiveBase { constructor() { super(...arguments); /** @internal */ this._cls = true; } ngOnInit() { this.initId(); } } MdcDialogTitleDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogTitle]' },] } ]; MdcDialogTitleDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog__title',] }] }; class MdcDialogContentDirectiveBase { } MdcDialogContentDirectiveBase.decorators = [ { type: Directive } ]; applyMixins(MdcDialogContentDirectiveBase, [HasId]); /** * Directive for the content part of an `mdcDialog`. * This should be added as a child element of an `mdcDialogSurface`. */ export class MdcDialogContentDirective extends MdcDialogContentDirectiveBase { constructor(_elm) { super(); this._elm = _elm; /** @internal */ this._cls = true; } ngOnInit() { this.initId(); } } MdcDialogContentDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogContent]' },] } ]; MdcDialogContentDirective.ctorParameters = () => [ { type: ElementRef } ]; MdcDialogContentDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog__content',] }] }; /** * Directive for the actions (footer) of an `mdcDialog`. * This is an (optional) last child of the `mdcDialogSurface` directive. * This directive should contain buttons, for that should use the `mdcButton` * directive. * * Action buttons should typically close the dialog, and should therefore * also set a value for the `mdcDialogTrigger` directive. */ export class MdcDialogActionsDirective { constructor(_rndr) { this._rndr = _rndr; /** @internal */ this._cls = true; } ngAfterContentInit() { this.initButtons(); this._buttons.changes.subscribe(() => { this.initButtons(); }); } initButtons() { this._buttons.forEach(btn => { this._rndr.addClass(btn._elm.nativeElement, 'mdc-dialog__button'); }); } } MdcDialogActionsDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogActions]', },] } ]; MdcDialogActionsDirective.ctorParameters = () => [ { type: Renderer2 } ]; MdcDialogActionsDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog__actions',] }], _buttons: [{ type: ContentChildren, args: [MdcButtonDirective, { descendants: true },] }] }; /** * Any element within a dialog may include this directive (and assigne a non empty value to it) * to indicate that interacting with it should close the dialog with the specified action. * * This action is then reflected via the `action` field in the `closing` and `closed` events of * the dialog. A value of `close` will also trigger the `cancel` event of the dialog, and a value of * `accept` will trigger the `accept` event. * * Any action buttons within the dialog that equate to a dismissal with no further action should * use set `mdcDialogTrigger="close"`. This will make it easy to handle all such interactions consistently * (via either the `cancel`, `closing`, or `closed` events), while separately handling other actions. */ export class MdcDialogTriggerDirective { constructor(_elm) { this._elm = _elm; /** * Set the `action` value that should be send to `closing` and `closed` events when a user * interacts with this element. (When set to an empty string the button/element will not be wired * to close the dialog). */ this.mdcDialogTrigger = null; } } MdcDialogTriggerDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogTrigger]' },] } ]; MdcDialogTriggerDirective.ctorParameters = () => [ { type: ElementRef } ]; MdcDialogTriggerDirective.propDecorators = { mdcDialogTrigger: [{ type: Input }] }; /** * This directive can be used to mark one of the dialogs action buttons as the default action. * This action will then be triggered by pressing the enter key while the dialog has focus. * The default action also will receive focus when the dialog is opened. Unless another * element within the dialog has the `mdcFocusInitial` directive. */ export class MdcDialogDefaultDirective extends AbstractMdcFocusInitial { constructor(_elm) { super(); this._elm = _elm; /** @internal */ this.priority = 0; // must be lower than prio of MdcFocusInitialDirective } } MdcDialogDefaultDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogDefault]', providers: [{ provide: AbstractMdcFocusInitial, useExisting: forwardRef(() => MdcDialogDefaultDirective) }] },] } ]; MdcDialogDefaultDirective.ctorParameters = () => [ { type: ElementRef } ]; /** * Directive for the surface of a dialog. The surface contains the actual content of a dialog, * wrapped in elements with the `mdcDialogHeader`, `mdcDialogContent`, and `mdcDialogActions` * directives. * * # Accessibility * * The role attribute will be set to `alertdialog` by default * * The `aria-modal` attribute will be set to `true` by default * * If there is an `mdcDialogTitle`, the `aria-labelledBy` attribute will be set to the id * of that element (and a unique id will be assigned to it, if none was provided) * * If there is an `mdcDialogContent`, the `aria-describedby` attribute will be set to the * id of that element (and a unique id will be assigned to it, if none was provided) */ export class MdcDialogSurfaceDirective { constructor() { /** @internal */ this._cls = true; /** @internal */ this._role = 'alertdialog'; /** @internal */ this._modal = 'true'; /** @internal */ this._labelledBy = null; /** @internal */ this._describedBy = null; } ngAfterContentInit() { this._titles.changes.subscribe(() => this.setAriaLabels()); this._contents.changes.subscribe(() => this.setAriaLabels()); this.setAriaLabels(); } setAriaLabels() { var _a, _b; this._labelledBy = (_a = this._titles.first) === null || _a === void 0 ? void 0 : _a.id; this._describedBy = (_b = this._contents.first) === null || _b === void 0 ? void 0 : _b.id; } } MdcDialogSurfaceDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogSurface]' },] } ]; MdcDialogSurfaceDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog__surface',] }], _role: [{ type: HostBinding, args: ['attr.role',] }], _modal: [{ type: HostBinding, args: ['attr.aria-modal',] }], _labelledBy: [{ type: HostBinding, args: ['attr.aria-labelledby',] }], _describedBy: [{ type: HostBinding, args: ['attr.aria-describedby',] }], _titles: [{ type: ContentChildren, args: [MdcDialogTitleDirective,] }], _contents: [{ type: ContentChildren, args: [MdcDialogContentDirective,] }] }; /** * This directive should be the first child of an `mdcDialog`, and contains the `mdcDialogSurface`. */ export class MdcDialogContainerDirective { constructor() { /** @internal */ this._cls = true; } } MdcDialogContainerDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogContainer]' },] } ]; MdcDialogContainerDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog__container',] }] }; /** * Directive for the backdrop of a dialog. The backdrop provides the styles for overlaying the * page content when the dialog is opened. This guides user attention to the dialog. */ export class MdcDialogScrimDirective { constructor() { /** @internal */ this._cls = true; } } MdcDialogScrimDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialogScrim]' },] } ]; MdcDialogScrimDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog__scrim',] }] }; /** * Directive for creating a modal dialog with Material Design styling. The dialog should have two * child elements: a surface (marked with the <code>mdcDialogSurface</code> directive), and a * backdrop (marked with the <code>mdcDialogBackdrop</code> directive). * * When the dialog is opened, it will activate a focus trap on the elements within the dialog, * so that the surface behind the dialog is not accessible. See `mdcFocusTrap` for more information. */ export class MdcDialogDirective { constructor(_elm, _rndr, _registry, _focusTrap, doc) { this._elm = _elm; this._rndr = _rndr; this._registry = _registry; this._focusTrap = _focusTrap; /** @internal */ this._cls = true; /** @internal */ this._surface = null; /** * Event emitted when the user accepts the dialog, e.g. by pressing enter or clicking the button * with `mdcDialogTrigger="accept"`. */ this.accept = new EventEmitter(); /** * Event emitted when the user cancels the dialog, e.g. by clicking outside the dialog, pressing the escape key, * or clicking an element with `mdcDialogTrigger="close"`. */ this.cancel = new EventEmitter(); /** * Event emitted when the dialog starts opening. */ this.opening = new EventEmitter(); /** * Event emitted when the dialog is opened. */ this.opened = new EventEmitter(); /** * Event emitted when the dialog starts closing. The 'action' field contains the reason for closing, see * `mdcDialogTrigger` for more information. */ this.closing = new EventEmitter(); /** * Event emitted when the dialog is closed. The 'action' field contains the reason for closing, see * `mdcDialogTrigger` for more information. */ this.closed = new EventEmitter(); this._onDocumentKeydown = (event) => this.onDocumentKeydown(event); this.focusTrapHandle = null; this.mdcAdapter = { addClass: (className) => this._rndr.addClass(this._elm.nativeElement, className), removeClass: (className) => this._rndr.removeClass(this._elm.nativeElement, className), addBodyClass: (className) => this._rndr.addClass(this.document.body, className), removeBodyClass: (className) => this._rndr.removeClass(this.document.body, className), areButtonsStacked: () => { var _a, _b; return ((_a = this._footers) === null || _a === void 0 ? void 0 : _a.first) ? util.areTopsMisaligned((_b = this._footers.first) === null || _b === void 0 ? void 0 : _b._buttons.map(b => b._elm.nativeElement)) : false; }, clickDefaultButton: () => { var _a, _b; return (_b = (_a = this._defaultActions) === null || _a === void 0 ? void 0 : _a.first) === null || _b === void 0 ? void 0 : _b._elm.nativeElement.click(); }, eventTargetMatches: (target, selector) => target ? ponyfill.matches(target, selector) : false, getActionFromEvent: (evt) => { const action = this.closest(evt.target, this._triggers.toArray()); return (action === null || action === void 0 ? void 0 : action.mdcDialogTrigger) || null; }, getInitialFocusEl: () => null, hasClass: (className) => { if (className === cssClasses.STACKED) return false; // currently not supporting (auto-)stacking of buttons return this._elm.nativeElement.classList.contains(className); }, isContentScrollable: () => { var _a; return util.isScrollable((_a = this._content) === null || _a === void 0 ? void 0 : _a._elm.nativeElement); }, notifyClosed: (action) => { this.closed.emit({ action }); }, notifyClosing: (action) => { this.document.removeEventListener('keydown', this._onDocumentKeydown); this.closing.emit({ action }); if (action === 'accept') this.accept.emit(); else if (action === 'close') this.cancel.emit(); }, notifyOpened: () => { this.opened.emit(); }, notifyOpening: () => { this.document.addEventListener('keydown', this._onDocumentKeydown); this.opening.emit(); }, releaseFocus: () => this.untrapFocus(), // we're currently not supporting auto-stacking, cause we can't just reverse buttons in the dom // and expect that to not break stuff in angular: reverseButtons: () => undefined, trapFocus: () => this.trapFocus() }; this.foundation = null; this.document = doc; // work around ngc issue https://github.com/angular/angular/issues/20351 } ngAfterContentInit() { this.foundation = new MDCDialogFoundation(this.mdcAdapter); this.foundation.init(); this.foundation.setAutoStackButtons(false); // currently not supported } ngOnDestroy() { var _a; this.document.removeEventListener('keydown', this._onDocumentKeydown); (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.destroy(); this.foundation = null; } /** * Call this method to open the dialog. */ open() { this.foundation.open(); } /** * Call this method to close the dialog with the specified action, e.g. `accept` to indicate an acceptance action * (and trigger the `accept` event), or `close` to indicate dismissal (and trigger the `cancel` event). */ close(action = 'close') { this.foundation.close(action); } /** * Recalculates layout and automatically adds/removes modifier classes (for instance to detect if the dialog content * should be scrollable) */ layout() { this.foundation.layout(); } 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 */ onClick(event) { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleClick(event); } /** @internal */ onKeydown(event) { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleKeydown(event); } /** @internal */ onDocumentKeydown(event) { var _a; (_a = this.foundation) === null || _a === void 0 ? void 0 : _a.handleDocumentKeydown(event); } get _content() { return this._contents.first; } closest(elm, choices) { let match = elm; while (match && match !== this._elm.nativeElement) { for (let i = 0; i != choices.length; ++i) { if (choices[i]._elm.nativeElement === match) return choices[i]; } match = match.parentElement; } return null; } } MdcDialogDirective.decorators = [ { type: Directive, args: [{ selector: '[mdcDialog]', exportAs: 'mdcDialog' },] } ]; MdcDialogDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: MdcEventRegistry }, { type: AbstractMdcFocusTrap, decorators: [{ type: Optional }, { type: Self }] }, { type: undefined, decorators: [{ type: Inject, args: [DOCUMENT,] }] } ]; MdcDialogDirective.propDecorators = { _cls: [{ type: HostBinding, args: ['class.mdc-dialog',] }], _surface: [{ type: ContentChild, args: [MdcDialogSurfaceDirective,] }], _triggers: [{ type: ContentChildren, args: [MdcDialogTriggerDirective, { descendants: true },] }], _contents: [{ type: ContentChildren, args: [MdcDialogContentDirective, { descendants: true },] }], _footers: [{ type: ContentChildren, args: [MdcDialogActionsDirective, { descendants: true },] }], _defaultActions: [{ type: ContentChildren, args: [MdcDialogDefaultDirective, { descendants: true },] }], accept: [{ type: Output }], cancel: [{ type: Output }], opening: [{ type: Output }], opened: [{ type: Output }], closing: [{ type: Output }], closed: [{ type: Output }], onClick: [{ type: HostListener, args: ['click', ['$event'],] }], onKeydown: [{ type: HostListener, args: ['keydown', ['$event'],] }] }; export const DIALOG_DIRECTIVES = [ MdcDialogDirective, MdcDialogTitleDirective, MdcDialogContentDirective, MdcDialogSurfaceDirective, MdcDialogContainerDirective, MdcDialogActionsDirective, MdcDialogTriggerDirective, MdcDialogDefaultDirective, MdcDialogScrimDirective ]; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWRjLmRpYWxvZy5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvY29tcG9uZW50cy9kaWFsb2cvbWRjLmRpYWxvZy5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFvQixZQUFZLEVBQUUsZUFBZSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQzFGLFFBQVEsRUFBRSxNQUFNLEVBQWEsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLFVBQVUsRUFBRSxNQUFNLGVBQWUsQ0FBQztBQUM3SCxPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUFFLG1CQUFtQixFQUFvQixJQUFJLEVBQUUsVUFBVSxFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFDM0YsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLGVBQWUsQ0FBQTtBQUN4QyxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNsRSxPQUFPLEVBQUUsa0JBQWtCLEVBQUUsTUFBTSxnQ0FBZ0MsQ0FBQztBQUNwRSxPQUFPLEVBQUUsdUJBQXVCLEVBQUUsb0JBQW9CLEVBQW1CLE1BQU0sdUNBQXVDLENBQUM7QUFDdkgsT0FBTyxFQUFFLEtBQUssRUFBRSxNQUFNLDZCQUE2QixDQUFDO0FBQ3BELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSxvQkFBb0IsQ0FBQztBQUVqRCxNQUNNLDJCQUEyQjs7O1lBRGhDLFNBQVM7O0FBR1YsV0FBVyxDQUFDLDJCQUEyQixFQUFFLENBQUMsS0FBSyxDQUFDLENBQUMsQ0FBQztBQUNsRDs7Ozs7O0dBTUc7QUFJSCxNQUFNLE9BQU8sdUJBQXdCLFNBQVEsMkJBQTJCO0lBSHhFOztRQUlJLGdCQUFnQjtRQUNpQyxTQUFJLEdBQUcsSUFBSSxDQUFDO0lBS2pFLENB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QUFNO3FCQUlOLE1BQU07c0JBS04sTUFBTTtxQkFLTixNQUFNO3NCQXdHTixZQUFZLFNBQUMsT0FBTyxFQUFFLENBQUMsUUFBUSxDQUFDO3dCQUtoQyxZQUFZLFNBQUMsU0FBUyxFQUFFLENBQUMsUUFBUSxDQUFDOztBQTBCdkMsTUFBTSxDQUFDLE1BQU0saUJBQWlCLEdBQUc7SUFDN0Isa0JBQWtCLEVBQUUsdUJBQXVCLEVBQUUseUJBQXlCLEVBQUUseUJBQXlCLEVBQUUsMkJBQTJCO0lBQzlILHlCQUF5QixFQUFFLHlCQUF5QixFQUFFLHlCQUF5QixFQUFFLHVCQUF1QjtDQUMzRyxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgQWZ0ZXJDb250ZW50SW5pdCwgQ29udGVudENoaWxkLCBDb250ZW50Q2hpbGRyZW4sIERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgRXZlbnRFbWl0dGVyLCBIb3N0QmluZGluZywgSW5wdXQsXG4gICAgT25EZXN0cm95LCBPbkluaXQsIE9wdGlvbmFsLCBPdXRwdXQsIFF1ZXJ5TGlzdCwgUmVuZGVyZXIyLCBTZWxmLCBJbmplY3QsIEhvc3RMaXN0ZW5lciwgZm9yd2FyZFJlZiB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgRE9DVU1FTlQgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xuaW1wb3J0IHsgTURDRGlhbG9nRm91bmRhdGlvbiwgTURDRGlhbG9nQWRhcHRlciwgdXRpbCwgY3NzQ2xhc3NlcyB9IGZyb20gJ0BtYXRlcmlhbC9kaWFsb2cnO1xuaW1wb3J0IHsgcG9ueWZpbGwgfSBmcm9tICdAbWF0ZXJpYWwvZG9tJ1xuaW1wb3J0IHsgTWRjRXZlbnRSZWdpc3RyeSB9IGZyb20gJy4uLy4uL3V0aWxzL21kYy5ldmVudC5yZWdpc3RyeSc7XG5pbXBvcnQgeyBNZGNCdXR0b25EaXJlY3RpdmUgfSBmcm9tICcuLi9idXR0b24vbWRjLmJ1dHRvbi5kaXJlY3RpdmUnO1xuaW1wb3J0IHsgQWJzdHJhY3RNZGNGb2N1c0luaXRpYWwsIEFic3RyYWN0TWRjRm9jdXNUcmFwLCBGb2N1c1RyYXBIYW5kbGUgfSBmcm9tICcuLi9mb2N1cy10cmFwL2Fic3RyYWN0Lm1kYy5mb2N1cy10cmFwJztcbmltcG9ydCB7IEhhc0lkIH0gZnJvbSAnLi4vYWJzdHJhY3QvbWl4aW4ubWRjLmhhc2lkJztcbmltcG9ydCB7IGFwcGx5TWl4aW5zIH0gZnJvbSAnLi4vLi4vdXRpbHMvbWl4aW5zJztcblxuQERpcmVjdGl2ZSgpXG5jbGFzcyBNZGNEaWFsb2dUaXRsZURpcmVjdGl2ZUJhc2Uge31cbmludGVyZmFjZSBNZGNEaWFsb2dUaXRsZURpcmVjdGl2ZUJhc2UgZXh0ZW5kcyBIYXNJZCB7fVxuYXBwbHlNaXhpbnMoTWRjRGlhbG9nVGl0bGVEaXJlY3RpdmVCYXNlLCBbSGFzSWRdKTtcbi8qKlxuICogRGlyZWN0aXZlIGZvciB0aGUgdGl0bGUgb2YgYW4gYG1kY0RpYWxvZ2AuXG4gKiBBIHRpdGxlIGlzIG9wdGlvbmFsLiBJZiB1c2VkLCBpdCBzaG91bGQgYmUgdGhlIGZpcnN0IGNoaWxkIG9mIGFuIGBtZGNEaWFsb2dTdXJmYWNlYC5cbiAqIFBsZWFzZSBub3RlIHRoYXQgdGhlcmUgc2hvdWxkIGJlIG5vIHdoaXRlc3BhY2Ugc2VwYXJhdGluZyB0aGUgc3RhcnQvZW5kIHRhZyBhbmQgdGhlIHRpdGxlXG4gKiBpdHNlbGYuIChUaGUgZWFzaWVzdCB3YXkgdG8gYWNoaWV2ZSB0aGlzIGlzIHRvICpub3QqIHNldCB0aGUgYHByZXNlcnZlV2hpdGVzcGFjZXNgIG9wdGlvbiB0b1xuICogYHRydWVgIHRoZSBgYW5ndWxhckNvbXBpbGVyT3B0aW9uc2ApLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEaWFsb2dUaXRsZV0nXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RpYWxvZ1RpdGxlRGlyZWN0aXZlIGV4dGVuZHMgTWRjRGlhbG9nVGl0bGVEaXJlY3RpdmVCYXNlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX190aXRsZScpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xuXG4gICAgbmdPbkluaXQoKSB7XG4gICAgICAgIHRoaXMuaW5pdElkKCk7XG4gICAgfVxufVxuXG5ARGlyZWN0aXZlKClcbmNsYXNzIE1kY0RpYWxvZ0NvbnRlbnREaXJlY3RpdmVCYXNlIHt9XG5pbnRlcmZhY2UgTWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZUJhc2UgZXh0ZW5kcyBIYXNJZCB7fVxuYXBwbHlNaXhpbnMoTWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZUJhc2UsIFtIYXNJZF0pO1xuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRoZSBjb250ZW50IHBhcnQgb2YgYW4gYG1kY0RpYWxvZ2AuXG4gKiBUaGlzIHNob3VsZCBiZSBhZGRlZCBhcyBhIGNoaWxkIGVsZW1lbnQgb2YgYW4gYG1kY0RpYWxvZ1N1cmZhY2VgLlxuICovXG5ARGlyZWN0aXZlKHtcbiAgICBzZWxlY3RvcjogJ1ttZGNEaWFsb2dDb250ZW50XSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZSBleHRlbmRzIE1kY0RpYWxvZ0NvbnRlbnREaXJlY3RpdmVCYXNlIGltcGxlbWVudHMgT25Jbml0IHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX19jb250ZW50JykgcmVhZG9ubHkgX2NscyA9IHRydWU7XG5cbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZikge1xuICAgICAgICBzdXBlcigpO1xuICAgIH1cblxuICAgIG5nT25Jbml0KCkge1xuICAgICAgICB0aGlzLmluaXRJZCgpO1xuICAgIH1cbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRoZSBhY3Rpb25zIChmb290ZXIpIG9mIGFuIGBtZGNEaWFsb2dgLlxuICogVGhpcyBpcyBhbiAob3B0aW9uYWwpIGxhc3QgY2hpbGQgb2YgdGhlIGBtZGNEaWFsb2dTdXJmYWNlYCBkaXJlY3RpdmUuXG4gKiBUaGlzIGRpcmVjdGl2ZSBzaG91bGQgY29udGFpbiBidXR0b25zLCBmb3IgdGhhdCBzaG91bGQgdXNlIHRoZSBgbWRjQnV0dG9uYFxuICogZGlyZWN0aXZlLlxuICogXG4gKiBBY3Rpb24gYnV0dG9ucyBzaG91bGQgdHlwaWNhbGx5IGNsb3NlIHRoZSBkaWFsb2csIGFuZCBzaG91bGQgdGhlcmVmb3JlXG4gKiBhbHNvIHNldCBhIHZhbHVlIGZvciB0aGUgYG1kY0RpYWxvZ1RyaWdnZXJgIGRpcmVjdGl2ZS5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nQWN0aW9uc10nLFxufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dBY3Rpb25zRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50SW5pdCB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRpYWxvZ19fYWN0aW9ucycpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0J1dHRvbkRpcmVjdGl2ZSwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX2J1dHRvbnM/OiBRdWVyeUxpc3Q8TWRjQnV0dG9uRGlyZWN0aXZlPjtcblxuICAgIGNvbnN0cnVjdG9yKHByaXZhdGUgX3JuZHI6IFJlbmRlcmVyMikge1xuICAgIH1cblxuICAgIG5nQWZ0ZXJDb250ZW50SW5pdCgpIHtcbiAgICAgICAgdGhpcy5pbml0QnV0dG9ucygpO1xuICAgICAgICB0aGlzLl9idXR0b25zIS5jaGFuZ2VzLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmluaXRCdXR0b25zKCk7XG4gICAgICAgIH0pO1xuICAgIH1cblxuICAgIHByaXZhdGUgaW5pdEJ1dHRvbnMoKSB7XG4gICAgICAgIHRoaXMuX2J1dHRvbnMhLmZvckVhY2goYnRuID0+IHtcbiAgICAgICAgICAgIHRoaXMuX3JuZHIuYWRkQ2xhc3MoYnRuLl9lbG0ubmF0aXZlRWxlbWVudCwgJ21kYy1kaWFsb2dfX2J1dHRvbicpO1xuICAgICAgICB9KTtcbiAgICB9XG59XG5cbi8qKlxuICogQW55IGVsZW1lbnQgd2l0aGluIGEgZGlhbG9nIG1heSBpbmNsdWRlIHRoaXMgZGlyZWN0aXZlIChhbmQgYXNzaWduZSBhIG5vbiBlbXB0eSB2YWx1ZSB0byBpdClcbiAqIHRvIGluZGljYXRlIHRoYXQgaW50ZXJhY3Rpbmcgd2l0aCBpdCBzaG91bGQgY2xvc2UgdGhlIGRpYWxvZyB3aXRoIHRoZSBzcGVjaWZpZWQgYWN0aW9uLlxuICogXG4gKiBUaGlzIGFjdGlvbiBpcyB0aGVuIHJlZmxlY3RlZCB2aWEgdGhlIGBhY3Rpb25gIGZpZWxkIGluIHRoZSBgY2xvc2luZ2AgYW5kIGBjbG9zZWRgIGV2ZW50cyBvZlxuICogdGhlIGRpYWxvZy4gQSB2YWx1ZSBvZiBgY2xvc2VgIHdpbGwgYWxzbyB0cmlnZ2VyIHRoZSBgY2FuY2VsYCBldmVudCBvZiB0aGUgZGlhbG9nLCBhbmQgYSB2YWx1ZSBvZlxuICogYGFjY2VwdGAgd2lsbCB0cmlnZ2VyIHRoZSBgYWNjZXB0YCBldmVudC5cbiAqIFxuICogQW55IGFjdGlvbiBidXR0b25zIHdpdGhpbiB0aGUgZGlhbG9nIHRoYXQgZXF1YXRlIHRvIGEgZGlzbWlzc2FsIHdpdGggbm8gZnVydGhlciBhY3Rpb24gc2hvdWxkXG4gKiB1c2Ugc2V0IGBtZGNEaWFsb2dUcmlnZ2VyPVwiY2xvc2VcImAuIFRoaXMgd2lsbCBtYWtlIGl0IGVhc3kgdG8gaGFuZGxlIGFsbCBzdWNoIGludGVyYWN0aW9ucyBjb25zaXN0ZW50bHlcbiAqICh2aWEgZWl0aGVyIHRoZSBgY2FuY2VsYCwgYGNsb3NpbmdgLCBvciBgY2xvc2VkYCBldmVudHMpLCB3aGlsZSBzZXBhcmF0ZWx5IGhhbmRsaW5nIG90aGVyIGFjdGlvbnMuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RpYWxvZ1RyaWdnZXJdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dUcmlnZ2VyRGlyZWN0aXZlIHtcbiAgICBjb25zdHJ1Y3RvcihwdWJsaWMgX2VsbTogRWxlbWVudFJlZikge1xuICAgIH1cblxuICAgIC8qKlxuICAgICAqIFNldCB0aGUgYGFjdGlvbmAgdmFsdWUgdGhhdCBzaG91bGQgYmUgc2VuZCB0byBgY2xvc2luZ2AgYW5kIGBjbG9zZWRgIGV2ZW50cyB3aGVuIGEgdXNlclxuICAgICAqIGludGVyYWN0cyB3aXRoIHRoaXMgZWxlbWVudC4gKFdoZW4gc2V0IHRvIGFuIGVtcHR5IHN0cmluZyB0aGUgYnV0dG9uL2VsZW1lbnQgd2lsbCBub3QgYmUgd2lyZWRcbiAgICAgKiB0byBjbG9zZSB0aGUgZGlhbG9nKS5cbiAgICAgKi9cbiAgICBASW5wdXQoKSBtZGNEaWFsb2dUcmlnZ2VyOiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbn1cblxuLyoqXG4gKiBUaGlzIGRpcmVjdGl2ZSBjYW4gYmUgdXNlZCB0byBtYXJrIG9uZSBvZiB0aGUgZGlhbG9ncyBhY3Rpb24gYnV0dG9ucyBhcyB0aGUgZGVmYXVsdCBhY3Rpb24uXG4gKiBUaGlzIGFjdGlvbiB3aWxsIHRoZW4gYmUgdHJpZ2dlcmVkIGJ5IHByZXNzaW5nIHRoZSBlbnRlciBrZXkgd2hpbGUgdGhlIGRpYWxvZyBoYXMgZm9jdXMuXG4gKiBUaGUgZGVmYXVsdCBhY3Rpb24gYWxzbyB3aWxsIHJlY2VpdmUgZm9jdXMgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC4gVW5sZXNzIGFub3RoZXJcbiAqIGVsZW1lbnQgd2l0aGluIHRoZSBkaWFsb2cgaGFzIHRoZSBgbWRjRm9jdXNJbml0aWFsYCBkaXJlY3RpdmUuXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RpYWxvZ0RlZmF1bHRdJyxcbiAgICBwcm92aWRlcnM6IFt7cHJvdmlkZTogQWJzdHJhY3RNZGNGb2N1c0luaXRpYWwsIHVzZUV4aXN0aW5nOiBmb3J3YXJkUmVmKCgpID0+IE1kY0RpYWxvZ0RlZmF1bHREaXJlY3RpdmUpIH1dXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RpYWxvZ0RlZmF1bHREaXJlY3RpdmUgZXh0ZW5kcyBBYnN0cmFjdE1kY0ZvY3VzSW5pdGlhbCB7XG4gICAgLyoqIEBpbnRlcm5hbCAqLyByZWFkb25seSBwcmlvcml0eSA9IDA7IC8vIG11c3QgYmUgbG93ZXIgdGhhbiBwcmlvIG9mIE1kY0ZvY3VzSW5pdGlhbERpcmVjdGl2ZVxuXG4gICAgY29uc3RydWN0b3IocHVibGljIF9lbG06IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgc3VwZXIoKTtcbiAgICB9XG59XG5cbi8qKlxuICogRGlyZWN0aXZlIGZvciB0aGUgc3VyZmFjZSBvZiBhIGRpYWxvZy4gVGhlIHN1cmZhY2UgY29udGFpbnMgdGhlIGFjdHVhbCBjb250ZW50IG9mIGEgZGlhbG9nLFxuICogd3JhcHBlZCBpbiBlbGVtZW50cyB3aXRoIHRoZSBgbWRjRGlhbG9nSGVhZGVyYCwgYG1kY0RpYWxvZ0NvbnRlbnRgLCBhbmQgYG1kY0RpYWxvZ0FjdGlvbnNgXG4gKiBkaXJlY3RpdmVzLlxuICogXG4gKiAjIEFjY2Vzc2liaWxpdHlcbiAqICogVGhlIHJvbGUgYXR0cmlidXRlIHdpbGwgYmUgc2V0IHRvIGBhbGVydGRpYWxvZ2AgYnkgZGVmYXVsdFxuICogKiBUaGUgYGFyaWEtbW9kYWxgIGF0dHJpYnV0ZSB3aWxsIGJlIHNldCB0byBgdHJ1ZWAgYnkgZGVmYXVsdFxuICogKiBJZiB0aGVyZSBpcyBhbiBgbWRjRGlhbG9nVGl0bGVgLCB0aGUgYGFyaWEtbGFiZWxsZWRCeWAgYXR0cmlidXRlIHdpbGwgYmUgc2V0IHRvIHRoZSBpZFxuICogICBvZiB0aGF0IGVsZW1lbnQgKGFuZCBhIHVuaXF1ZSBpZCB3aWxsIGJlIGFzc2lnbmVkIHRvIGl0LCBpZiBub25lIHdhcyBwcm92aWRlZClcbiAqICogSWYgdGhlcmUgaXMgYW4gYG1kY0RpYWxvZ0NvbnRlbnRgLCB0aGUgYGFyaWEtZGVzY3JpYmVkYnlgIGF0dHJpYnV0ZSB3aWxsIGJlIHNldCB0byB0aGVcbiAqICAgaWQgb2YgdGhhdCBlbGVtZW50IChhbmQgYSB1bmlxdWUgaWQgd2lsbCBiZSBhc3NpZ25lZCB0byBpdCwgaWYgbm9uZSB3YXMgcHJvdmlkZWQpXG4gKi9cbkBEaXJlY3RpdmUoe1xuICAgIHNlbGVjdG9yOiAnW21kY0RpYWxvZ1N1cmZhY2VdJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dTdXJmYWNlRGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX19zdXJmYWNlJykgcmVhZG9ubHkgX2NscyA9IHRydWU7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJykgX3JvbGUgPSAnYWxlcnRkaWFsb2cnO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBASG9zdEJpbmRpbmcoJ2F0dHIuYXJpYS1tb2RhbCcpIF9tb2RhbCA9ICd0cnVlJztcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtbGFiZWxsZWRieScpIF9sYWJlbGxlZEJ5OiBzdHJpbmcgfCBudWxsID0gbnVsbDtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtZGVzY3JpYmVkYnknKSBfZGVzY3JpYmVkQnk6IHN0cmluZyB8IG51bGwgPSBudWxsO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0RpYWxvZ1RpdGxlRGlyZWN0aXZlKSBfdGl0bGVzPzogUXVlcnlMaXN0PE1kY0RpYWxvZ1RpdGxlRGlyZWN0aXZlPjtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNEaWFsb2dDb250ZW50RGlyZWN0aXZlKSBfY29udGVudHM/OiBRdWVyeUxpc3Q8TWRjRGlhbG9nQ29udGVudERpcmVjdGl2ZT47XG5cbiAgICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgICAgIHRoaXMuX3RpdGxlcyEuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zZXRBcmlhTGFiZWxzKCkpO1xuICAgICAgICB0aGlzLl9jb250ZW50cyEuY2hhbmdlcy5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zZXRBcmlhTGFiZWxzKCkpO1xuICAgICAgICB0aGlzLnNldEFyaWFMYWJlbHMoKTtcbiAgICB9XG5cbiAgICBwcml2YXRlIHNldEFyaWFMYWJlbHMoKSB7XG4gICAgICAgIHRoaXMuX2xhYmVsbGVkQnkgPSB0aGlzLl90aXRsZXMhLmZpcnN0Py5pZDtcbiAgICAgICAgdGhpcy5fZGVzY3JpYmVkQnkgPSB0aGlzLl9jb250ZW50cyEuZmlyc3Q/LmlkO1xuICAgIH1cbn1cblxuLyoqXG4gKiBUaGlzIGRpcmVjdGl2ZSBzaG91bGQgYmUgdGhlIGZpcnN0IGNoaWxkIG9mIGFuIGBtZGNEaWFsb2dgLCBhbmQgY29udGFpbnMgdGhlIGBtZGNEaWFsb2dTdXJmYWNlYC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nQ29udGFpbmVyXSdcbn0pXG5leHBvcnQgY2xhc3MgTWRjRGlhbG9nQ29udGFpbmVyRGlyZWN0aXZlIHtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQEhvc3RCaW5kaW5nKCdjbGFzcy5tZGMtZGlhbG9nX19jb250YWluZXInKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIHRoZSBiYWNrZHJvcCBvZiBhIGRpYWxvZy4gVGhlIGJhY2tkcm9wIHByb3ZpZGVzIHRoZSBzdHlsZXMgZm9yIG92ZXJsYXlpbmcgdGhlXG4gKiBwYWdlIGNvbnRlbnQgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC4gVGhpcyBndWlkZXMgdXNlciBhdHRlbnRpb24gdG8gdGhlIGRpYWxvZy5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nU2NyaW1dJ1xufSlcbmV4cG9ydCBjbGFzcyBNZGNEaWFsb2dTY3JpbURpcmVjdGl2ZSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRpYWxvZ19fc2NyaW0nKSByZWFkb25seSBfY2xzID0gdHJ1ZTtcbn1cblxuLyoqXG4gKiBEaXJlY3RpdmUgZm9yIGNyZWF0aW5nIGEgbW9kYWwgZGlhbG9nIHdpdGggTWF0ZXJpYWwgRGVzaWduIHN0eWxpbmcuIFRoZSBkaWFsb2cgc2hvdWxkIGhhdmUgdHdvXG4gKiBjaGlsZCBlbGVtZW50czogYSBzdXJmYWNlIChtYXJrZWQgd2l0aCB0aGUgPGNvZGU+bWRjRGlhbG9nU3VyZmFjZTwvY29kZT4gZGlyZWN0aXZlKSwgYW5kIGFcbiAqIGJhY2tkcm9wIChtYXJrZWQgd2l0aCB0aGUgPGNvZGU+bWRjRGlhbG9nQmFja2Ryb3A8L2NvZGU+IGRpcmVjdGl2ZSkuXG4gKiBcbiAqIFdoZW4gdGhlIGRpYWxvZyBpcyBvcGVuZWQsIGl0IHdpbGwgYWN0aXZhdGUgYSBmb2N1cyB0cmFwIG9uIHRoZSBlbGVtZW50cyB3aXRoaW4gdGhlIGRpYWxvZyxcbiAqIHNvIHRoYXQgdGhlIHN1cmZhY2UgYmVoaW5kIHRoZSBkaWFsb2cgaXMgbm90IGFjY2Vzc2libGUuIFNlZSBgbWRjRm9jdXNUcmFwYCBmb3IgbW9yZSBpbmZvcm1hdGlvbi5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6ICdbbWRjRGlhbG9nXScsXG4gICAgZXhwb3J0QXM6ICdtZGNEaWFsb2cnXG59KVxuZXhwb3J0IGNsYXNzIE1kY0RpYWxvZ0RpcmVjdGl2ZSBpbXBsZW1lbnRzIEFmdGVyQ29udGVudEluaXQsIE9uRGVzdHJveSB7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBIb3N0QmluZGluZygnY2xhc3MubWRjLWRpYWxvZycpIHJlYWRvbmx5IF9jbHMgPSB0cnVlO1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkKE1kY0RpYWxvZ1N1cmZhY2VEaXJlY3RpdmUpIF9zdXJmYWNlOiBNZGNEaWFsb2dTdXJmYWNlRGlyZWN0aXZlIHwgbnVsbCA9IG51bGw7XG4gICAgLyoqIEBpbnRlcm5hbCAqL1xuICAgIEBDb250ZW50Q2hpbGRyZW4oTWRjRGlhbG9nVHJpZ2dlckRpcmVjdGl2ZSwge2Rlc2NlbmRhbnRzOiB0cnVlfSkgX3RyaWdnZXJzPzogUXVlcnlMaXN0PE1kY0RpYWxvZ1RyaWdnZXJEaXJlY3RpdmU+O1xuICAgIC8qKiBAaW50ZXJuYWwgKi9cbiAgICBAQ29udGVudENoaWxkcmVuKE1kY0RpYWxvZ0NvbnRlbnREaXJlY3RpdmUsIHtkZXNjZW5kYW50czogdHJ1ZX0pIF9jb250ZW50cz86IFF1ZXJ5TGlzdDxNZGNEaWFsb2dDb250ZW50RGlyZWN0aXZlPjtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNEaWFsb2dBY3Rpb25zRGlyZWN0aXZlLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfZm9vdGVycz86IFF1ZXJ5TGlzdDxNZGNEaWFsb2dBY3Rpb25zRGlyZWN0aXZlPjtcbiAgICAvKiogQGludGVybmFsICovXG4gICAgQENvbnRlbnRDaGlsZHJlbihNZGNEaWFsb2dEZWZhdWx0RGlyZWN0aXZlLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfZGVmYXVsdEFjdGlvbnM/OiBRdWVyeUxpc3Q8TWRjRGlhbG9nRGVmYXVsdERpcmVjdGl2ZT47XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB1c2VyIGFjY2VwdHMgdGhlIGRpYWxvZywgZS5nLiBieSBwcmVzc2luZyBlbnRlciBvciBjbGlja2luZyB0aGUgYnV0dG9uXG4gICAgICogd2l0aCBgbWRjRGlhbG9nVHJpZ2dlcj1cImFjY2VwdFwiYC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgYWNjZXB0OiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSB1c2VyIGNhbmNlbHMgdGhlIGRpYWxvZywgZS5nLiBieSBjbGlja2luZyBvdXRzaWRlIHRoZSBkaWFsb2csIHByZXNzaW5nIHRoZSBlc2NhcGUga2V5LFxuICAgICAqIG9yIGNsaWNraW5nIGFuIGVsZW1lbnQgd2l0aCBgbWRjRGlhbG9nVHJpZ2dlcj1cImNsb3NlXCJgLlxuICAgICAqL1xuICAgIEBPdXRwdXQoKSByZWFkb25seSBjYW5jZWw6IEV2ZW50RW1pdHRlcjx2b2lkPiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGRpYWxvZyBzdGFydHMgb3BlbmluZy5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbmluZzogRXZlbnRFbWl0dGVyPHZvaWQ+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIC8qKlxuICAgICAqIEV2ZW50IGVtaXR0ZWQgd2hlbiB0aGUgZGlhbG9nIGlzIG9wZW5lZC5cbiAgICAgKi9cbiAgICBAT3V0cHV0KCkgcmVhZG9ubHkgb3BlbmVkOiBFdmVudEVtaXR0ZXI8dm9pZD4gPSBuZXcgRXZlbnRFbWl0dGVyKCk7XG4gICAgLyoqXG4gICAgICogRXZlbnQgZW1pdHRlZCB3aGVuIHRoZSBkaWFsb2cgc3RhcnRzIGNsb3NpbmcuIFRoZSAnYWN0aW9uJyBmaWVsZCBjb250YWlucyB0aGUgcmVhc29uIGZvciBjbG9zaW5nLCBzZWVcbiAgICAgKiBgbWRjRGlhbG9nVHJpZ2dlcmAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGNsb3Npbmc6IEV2ZW50RW1pdHRlcjx7YWN0aW9uOiBzdHJpbmd9PiA9IG5ldyBFdmVudEVtaXR0ZXIoKTtcbiAgICAvKipcbiAgICAgKiBFdmVudCBlbWl0dGVkIHdoZW4gdGhlIGRpYWxvZyBpcyBjbG9zZWQuIFRoZSAnYWN0aW9uJyBmaWVsZCBjb250YWlucyB0aGUgcmVhc29uIGZvciBjbG9zaW5nLCBzZWVcbiAgICAgKiBgbWRjRGlhbG9nVHJpZ2dlcmAgZm9yIG1vcmUgaW5mb3JtYXRpb24uXG4gICAgICovXG4gICAgQE91dHB1dCgpIHJlYWRvbmx5IGNsb3NlZDogRXZlbnRFbWl0dGVyPHthY3Rpb246IHN0cmluZ30+ID0gbmV3IEV2ZW50RW1pdHRlcigpO1xuICAgIHByaXZhdGUgX29uRG9jdW1lbnRLZXlkb3duID0gKGV2ZW50OiBLZXlib2FyZEV2ZW50KSA9PiB0aGlzLm9uRG9jdW1lbnRLZXlkb3duKGV2ZW50KTtcbiAgICBwcml2YXRlIGZvY3VzVHJhcEhhbmRsZTogRm9jdXNUcmFwSGFuZGxlIHwgbnVsbCA9IG51bGw7XG4gICAgcHJpdmF0ZSBtZGNBZGFwdGVyOiBNRENEaWFsb2dBZGFwdGVyID0ge1xuICAgICAgICBhZGRDbGFzczogKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB0aGlzLl9ybmRyLmFkZENsYXNzKHRoaXMuX2VsbS5uYXRpdmVFbGVtZW50LCBjbGFzc05hbWUpLFxuICAgICAgICByZW1vdmVDbGFzczogKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB0aGlzLl9ybmRyLnJlbW92ZUNsYXNzKHRoaXMuX2VsbS5uYXRpdmVFbGVtZW50LCBjbGFzc05hbWUpLFxuICAgICAgICBhZGRCb2R5Q2xhc3M6IChjbGFzc05hbWU6IHN0cmluZykgPT4gdGhpcy5fcm5kci5hZGRDbGFzcyh0aGlzLmRvY3VtZW50LmJvZHksIGNsYXNzTmFtZSksXG4gICAgICAgIHJlbW92ZUJvZHlDbGFzczogKGNsYXNzTmFtZTogc3RyaW5nKSA9PiB0aGlzLl9ybmRyLnJlbW92ZUNsYXNzKHRoaXMuZG9jdW1lbnQuYm9keSwgY2xhc3NOYW1lKSxcbiAgICAgICAgYXJlQnV0dG9uc1N0YWNrZWQ6ICgpID0+IHRoaXMuX2Zvb3RlcnM/LmZpcnN0ID8gdXRpbC5hcmVUb3BzTWlzYWxpZ25lZCh0aGlzLl9mb290ZXJzLmZpcnN0Py5fYnV0dG9ucyEubWFwKGIgPT4gYi5fZWxtLm5hdGl2ZUVsZW1lbnQpKSA6IGZhbHNlLFxuICAgICAgICBjbGlja0RlZmF1bHRCdXR0b246ICgpID0+IHRoaXMuX2RlZmF1bHRBY3Rpb25zPy5maXJzdD8uX2VsbS5uYXRpdmVFbGVtZW50LmNsaWNrKCksXG4gICAgICAgIGV2ZW50VGFyZ2V0TWF0Y2hlczogKHRhcmdldCwgc2VsZWN0b3IpID0+IHRhcmdldCA/IHBvbnlmaWxsLm1hdGNoZXModGFyZ2V0IGFzIEVsZW1lbnQsIHNlbGVjdG9yKSA6IGZhbHNlLFxuICAgICAgICBnZXRBY3Rpb25Gcm9tRXZlbnQ6IChldnQ6IEV2ZW50KSA9PiB7XG4gICAgICAgICAgICBjb25zdCBhY3Rpb24gPSB0aGlzLmNsb3Nlc3QoZXZ0LnRhcmdldCBhcyBFbGVtZW50LCB0aGlzLl90cmlnZ2VycyEudG9BcnJheSgpKTtcbiAgICAgICAgICAgIHJldHVybiBhY3Rpb24/Lm1kY0RpYWxvZ1RyaWdnZXIgfHwgbnVsbDtcbiAgICAgICAgfSxcbiAgICAgICAgZ2V0SW5pdGlhbEZvY3VzRWw6ICgpID0+IG51bGwsIC8vIGlnbm9yZWQgaW4gb3VyIGltcGxlbWVudGF0aW9uLiBtZGNGb2N1c1RyYXAgZGV0ZXJtaW5lcyB0aGlzIGJ5IGl0c2VsZlxuICAgICAgICBoYXNDbGFzczogKGNsYXNzTmFtZSkgPT4ge1xuICAgICAgICAgICAgaWYgKGNsYXNzTmFtZSA9PT0gY3NzQ2xhc3Nlcy5TVEFDS0VEKVxuICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsgLy8gY3VycmVudGx5IG5vdCBzdXBwb3J0aW5nIChhdXRvLSlzdGFja2luZyBvZiBidXR0b25zXG4gICAgICAgICAgICByZXR1cm4gdGhpcy5fZWxtLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0LmNvbnRhaW5zKGNsYXNzTmFtZSk7XG4gICAgICAgIH0sXG4gICAgICAgIGlzQ29udGVudFNjcm9sbGFibGU6ICgpID0+IHV0aWwuaXNTY3JvbGxhYmxlKHRoaXMuX2NvbnRlbnQ/Ll9lbG0ubmF0aXZlRWxlbWVudCksXG4gICAgICAgIG5vdGlmeUNsb3NlZDogKGFjdGlvbikgPT4ge1xuICAgICAgICAgICAgdGhpcy5jbG9zZWQuZW1pdCh7YWN0aW9ufSk7XG4gICAgICAgIH0sXG4gICAgICAgIG5vdGlmeUNsb3Npbmc6IChhY3Rpb24pID0+IHtcbiAgICAgICAgICAgIHRoaXMuZG9jdW1lbnQucmVtb3ZlRXZlbnRMaXN0ZW5lcigna2V5ZG93bicsIHRoaXMuX29uRG9jdW1lbnRLZXlkb3duKTtcbiAgICAgICAgICAgIHRoaXMuY2xvc2luZy5lbWl0KHthY3Rpb259KTtcbiAgICAgICAgICAgIGlmIChhY3Rpb24gPT09ICdhY2NlcHQnKVxuICAgICAgICAgICAgICAgIHRoaXMuYWNjZXB0LmVtaXQoKTtcbiAgICAgICAgICAgIGVsc2UgaWYgKGFjdGlvbiA9PT0gJ2Nsb3NlJylcbiAgICAgICAgICAgICAgICB0aGlzLmNhbmNlbC5lbWl0KCk7XG4gICAgICAgIH0sXG4gICAgICAgIG5vdGlmeU9wZW5lZDogKCkgPT4ge1xuICAgICAgICAgICAgdGhpcy5vcGVuZWQuZW1pdCgpO1xuICAgICAgICB9LFxuICAgICAgICBub3RpZnlPcGVuaW5nOiAoKSA9PiB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50LmFkZEV2ZW50TGlzdGVuZXIoJ2tleWRvd24nLCB0aGlzLl9vbkRvY3VtZW50S2V5ZG93bik7XG4gICAgICAgICAgICB0aGlzLm9wZW5pbmcuZW1pdCgpO1xuICAgICAgICB9LFxuICAgICAgICByZWxlYXNlRm9jdXM6ICgpID0+IHRoaXMudW50cmFwRm9jdXMoKSxcbiAgICAgICAgLy8gd2UncmUgY3VycmVudGx5IG5vdCBzdXBwb3J0aW5nIGF1dG8tc3RhY2tpbmcsIGNhdXNlIHdlIGNhbid0IGp1c3QgcmV2ZXJzZSBidXR0b25zIGluIHRoZSBkb21cbiAgICAgICAgLy8gYW5kIGV4cGVjdCB0aGF0IHRvIG5vdCBicmVhayBzdHVmZiBpbiBhbmd1bGFyOlxuICAgICAgICByZXZlcnNlQnV0dG9uczogKCkgPT4gdW5kZWZpbmVkLFxuICAgICAgICB0cmFwRm9jdXM6ICgpID0+IHRoaXMudHJhcEZvY3VzKClcbiAgICB9O1xuICAgIHByaXZhdGUgZm91bmRhdGlvbjogTURDRGlhbG9nRm91bmRhdGlvbiB8IG51bGwgPSBudWxsO1xuICAgIHByaXZhdGUgZG9jdW1lbnQ6IERvY3VtZW50O1xuXG4gICAgY29uc3RydWN0b3IocHJpdmF0ZSBfZWxtOiBFbGVtZW50UmVmLCBwcml2YXRlIF9ybmRyOiBSZW5kZXJlcjIsIHByaXZhdGUgX3JlZ2lzdHJ5OiBNZGNFdmVudFJlZ2lzdHJ5LFxuICAgICAgICBAT3B0aW9uYWwoKSBAU2VsZigpIHByaXZhdGUgX2ZvY3VzVHJhcDogQWJzdHJhY3RNZGNGb2N1c1RyYXAsXG4gICAgICAgIEBJbmplY3QoRE9DVU1FTlQpIGRvYzogYW55KSB7XG4gICAgICAgICAgICB0aGlzLmRvY3VtZW50ID0gZG9jIGFzIERvY3VtZW50OyAvLyB3b3JrIGFyb3VuZCBuZ2MgaXNzdWUgaHR0cHM6Ly9naXRodWIuY29tL2FuZ3VsYXIvYW5ndWxhci9pc3N1ZXMvMjAzNTFcbiAgICB9XG5cbiAgICBuZ0FmdGVyQ29udGVudEluaXQoKSB7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbiA9IG5ldyBNRENEaWFsb2dGb3VuZGF0aW9uKHRoaXMubWRjQWRhcHRlcik7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbi5pbml0KCk7XG4gICAgICAgIHRoaXMuZm91bmRhdGlvbi5zZXRBdXRvU3RhY2tCdXR0b25zKGZhbHNlKTsgLy8gY3VycmVudGx5IG5vdCBzdXBwb3J0ZWRcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgdGhpcy5kb2N1bWVudC5yZW1vdmVFdmVudExpc3RlbmVyKCdrZXlkb3duJywgdGhpcy5fb25Eb2N1bWVudEtleWRvd24pO1xuICAgICAgICB0aGlzLmZvdW5kYXRpb24/LmRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5mb3VuZGF0aW9uID0gbnVsbDtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIHRvIG9wZW4gdGhlIGRpYWxvZy5cbiAgICAgKi9cbiAgICBvcGVuKCkge1xuICAgICAgICB0aGlzLmZvdW5kYXRpb24hLm9wZW4oKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBDYWxsIHRoaXMgbWV0aG9kIHRvIGNsb3NlIHRoZSBkaWFsb2cgd2l0aC