You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
347 lines
51 KiB
347 lines
51 KiB
/**
|
|
* @license
|
|
* Copyright Google LLC All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by an MIT-style license that can be
|
|
* found in the LICENSE file at https://angular.io/license
|
|
*/
|
|
import { Directionality } from '@angular/cdk/bidi';
|
|
import { Overlay, OverlayConfig, OverlayContainer, } from '@angular/cdk/overlay';
|
|
import { ComponentPortal, TemplatePortal } from '@angular/cdk/portal';
|
|
import { Location } from '@angular/common';
|
|
import { Directive, Inject, Injectable, InjectFlags, InjectionToken, Injector, Optional, SkipSelf, TemplateRef, Type, } from '@angular/core';
|
|
import { defer, of as observableOf, Subject } from 'rxjs';
|
|
import { startWith } from 'rxjs/operators';
|
|
import { MatDialogConfig } from './dialog-config';
|
|
import { MatDialogContainer } from './dialog-container';
|
|
import { MatDialogRef } from './dialog-ref';
|
|
/** Injection token that can be used to access the data that was passed in to a dialog. */
|
|
import * as ɵngcc0 from '@angular/core';
|
|
import * as ɵngcc1 from '@angular/cdk/overlay';
|
|
import * as ɵngcc2 from '@angular/common';
|
|
import * as ɵngcc3 from './dialog-config';
|
|
export const MAT_DIALOG_DATA = new InjectionToken('MatDialogData');
|
|
/** Injection token that can be used to specify default dialog options. */
|
|
export const MAT_DIALOG_DEFAULT_OPTIONS = new InjectionToken('mat-dialog-default-options');
|
|
/** Injection token that determines the scroll handling while the dialog is open. */
|
|
export const MAT_DIALOG_SCROLL_STRATEGY = new InjectionToken('mat-dialog-scroll-strategy');
|
|
/** @docs-private */
|
|
export function MAT_DIALOG_SCROLL_STRATEGY_FACTORY(overlay) {
|
|
return () => overlay.scrollStrategies.block();
|
|
}
|
|
/** @docs-private */
|
|
export function MAT_DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY(overlay) {
|
|
return () => overlay.scrollStrategies.block();
|
|
}
|
|
/** @docs-private */
|
|
export const MAT_DIALOG_SCROLL_STRATEGY_PROVIDER = {
|
|
provide: MAT_DIALOG_SCROLL_STRATEGY,
|
|
deps: [Overlay],
|
|
useFactory: MAT_DIALOG_SCROLL_STRATEGY_PROVIDER_FACTORY,
|
|
};
|
|
/**
|
|
* Base class for dialog services. The base dialog service allows
|
|
* for arbitrary dialog refs and dialog container components.
|
|
*/
|
|
export class _MatDialogBase {
|
|
constructor(_overlay, _injector, _defaultOptions, _parentDialog, _overlayContainer, scrollStrategy, _dialogRefConstructor, _dialogContainerType, _dialogDataToken) {
|
|
this._overlay = _overlay;
|
|
this._injector = _injector;
|
|
this._defaultOptions = _defaultOptions;
|
|
this._parentDialog = _parentDialog;
|
|
this._overlayContainer = _overlayContainer;
|
|
this._dialogRefConstructor = _dialogRefConstructor;
|
|
this._dialogContainerType = _dialogContainerType;
|
|
this._dialogDataToken = _dialogDataToken;
|
|
this._openDialogsAtThisLevel = [];
|
|
this._afterAllClosedAtThisLevel = new Subject();
|
|
this._afterOpenedAtThisLevel = new Subject();
|
|
this._ariaHiddenElements = new Map();
|
|
// TODO (jelbourn): tighten the typing right-hand side of this expression.
|
|
/**
|
|
* Stream that emits when all open dialog have finished closing.
|
|
* Will emit on subscribe if there are no open dialogs to begin with.
|
|
*/
|
|
this.afterAllClosed = defer(() => this.openDialogs.length ?
|
|
this._getAfterAllClosed() :
|
|
this._getAfterAllClosed().pipe(startWith(undefined)));
|
|
this._scrollStrategy = scrollStrategy;
|
|
}
|
|
/** Keeps track of the currently-open dialogs. */
|
|
get openDialogs() {
|
|
return this._parentDialog ? this._parentDialog.openDialogs : this._openDialogsAtThisLevel;
|
|
}
|
|
/** Stream that emits when a dialog has been opened. */
|
|
get afterOpened() {
|
|
return this._parentDialog ? this._parentDialog.afterOpened : this._afterOpenedAtThisLevel;
|
|
}
|
|
_getAfterAllClosed() {
|
|
const parent = this._parentDialog;
|
|
return parent ? parent._getAfterAllClosed() : this._afterAllClosedAtThisLevel;
|
|
}
|
|
open(componentOrTemplateRef, config) {
|
|
config = _applyConfigDefaults(config, this._defaultOptions || new MatDialogConfig());
|
|
if (config.id && this.getDialogById(config.id) &&
|
|
(typeof ngDevMode === 'undefined' || ngDevMode)) {
|
|
throw Error(`Dialog with id "${config.id}" exists already. The dialog id must be unique.`);
|
|
}
|
|
const overlayRef = this._createOverlay(config);
|
|
const dialogContainer = this._attachDialogContainer(overlayRef, config);
|
|
const dialogRef = this._attachDialogContent(componentOrTemplateRef, dialogContainer, overlayRef, config);
|
|
// If this is the first dialog that we're opening, hide all the non-overlay content.
|
|
if (!this.openDialogs.length) {
|
|
this._hideNonDialogContentFromAssistiveTechnology();
|
|
}
|
|
this.openDialogs.push(dialogRef);
|
|
dialogRef.afterClosed().subscribe(() => this._removeOpenDialog(dialogRef));
|
|
this.afterOpened.next(dialogRef);
|
|
// Notify the dialog container that the content has been attached.
|
|
dialogContainer._initializeWithAttachedContent();
|
|
return dialogRef;
|
|
}
|
|
/**
|
|
* Closes all of the currently-open dialogs.
|
|
*/
|
|
closeAll() {
|
|
this._closeDialogs(this.openDialogs);
|
|
}
|
|
/**
|
|
* Finds an open dialog by its id.
|
|
* @param id ID to use when looking up the dialog.
|
|
*/
|
|
getDialogById(id) {
|
|
return this.openDialogs.find(dialog => dialog.id === id);
|
|
}
|
|
ngOnDestroy() {
|
|
// Only close the dialogs at this level on destroy
|
|
// since the parent service may still be active.
|
|
this._closeDialogs(this._openDialogsAtThisLevel);
|
|
this._afterAllClosedAtThisLevel.complete();
|
|
this._afterOpenedAtThisLevel.complete();
|
|
}
|
|
/**
|
|
* Creates the overlay into which the dialog will be loaded.
|
|
* @param config The dialog configuration.
|
|
* @returns A promise resolving to the OverlayRef for the created overlay.
|
|
*/
|
|
_createOverlay(config) {
|
|
const overlayConfig = this._getOverlayConfig(config);
|
|
return this._overlay.create(overlayConfig);
|
|
}
|
|
/**
|
|
* Creates an overlay config from a dialog config.
|
|
* @param dialogConfig The dialog configuration.
|
|
* @returns The overlay configuration.
|
|
*/
|
|
_getOverlayConfig(dialogConfig) {
|
|
const state = new OverlayConfig({
|
|
positionStrategy: this._overlay.position().global(),
|
|
scrollStrategy: dialogConfig.scrollStrategy || this._scrollStrategy(),
|
|
panelClass: dialogConfig.panelClass,
|
|
hasBackdrop: dialogConfig.hasBackdrop,
|
|
direction: dialogConfig.direction,
|
|
minWidth: dialogConfig.minWidth,
|
|
minHeight: dialogConfig.minHeight,
|
|
maxWidth: dialogConfig.maxWidth,
|
|
maxHeight: dialogConfig.maxHeight,
|
|
disposeOnNavigation: dialogConfig.closeOnNavigation
|
|
});
|
|
if (dialogConfig.backdropClass) {
|
|
state.backdropClass = dialogConfig.backdropClass;
|
|
}
|
|
return state;
|
|
}
|
|
/**
|
|
* Attaches a dialog container to a dialog's already-created overlay.
|
|
* @param overlay Reference to the dialog's underlying overlay.
|
|
* @param config The dialog configuration.
|
|
* @returns A promise resolving to a ComponentRef for the attached container.
|
|
*/
|
|
_attachDialogContainer(overlay, config) {
|
|
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
|
|
const injector = Injector.create({
|
|
parent: userInjector || this._injector,
|
|
providers: [{ provide: MatDialogConfig, useValue: config }]
|
|
});
|
|
const containerPortal = new ComponentPortal(this._dialogContainerType, config.viewContainerRef, injector, config.componentFactoryResolver);
|
|
const containerRef = overlay.attach(containerPortal);
|
|
return containerRef.instance;
|
|
}
|
|
/**
|
|
* Attaches the user-provided component to the already-created dialog container.
|
|
* @param componentOrTemplateRef The type of component being loaded into the dialog,
|
|
* or a TemplateRef to instantiate as the content.
|
|
* @param dialogContainer Reference to the wrapping dialog container.
|
|
* @param overlayRef Reference to the overlay in which the dialog resides.
|
|
* @param config The dialog configuration.
|
|
* @returns A promise resolving to the MatDialogRef that should be returned to the user.
|
|
*/
|
|
_attachDialogContent(componentOrTemplateRef, dialogContainer, overlayRef, config) {
|
|
// Create a reference to the dialog we're creating in order to give the user a handle
|
|
// to modify and close it.
|
|
const dialogRef = new this._dialogRefConstructor(overlayRef, dialogContainer, config.id);
|
|
if (componentOrTemplateRef instanceof TemplateRef) {
|
|
dialogContainer.attachTemplatePortal(new TemplatePortal(componentOrTemplateRef, null, { $implicit: config.data, dialogRef }));
|
|
}
|
|
else {
|
|
const injector = this._createInjector(config, dialogRef, dialogContainer);
|
|
const contentRef = dialogContainer.attachComponentPortal(new ComponentPortal(componentOrTemplateRef, config.viewContainerRef, injector));
|
|
dialogRef.componentInstance = contentRef.instance;
|
|
}
|
|
dialogRef
|
|
.updateSize(config.width, config.height)
|
|
.updatePosition(config.position);
|
|
return dialogRef;
|
|
}
|
|
/**
|
|
* Creates a custom injector to be used inside the dialog. This allows a component loaded inside
|
|
* of a dialog to close itself and, optionally, to return a value.
|
|
* @param config Config object that is used to construct the dialog.
|
|
* @param dialogRef Reference to the dialog.
|
|
* @param dialogContainer Dialog container element that wraps all of the contents.
|
|
* @returns The custom injector that can be used inside the dialog.
|
|
*/
|
|
_createInjector(config, dialogRef, dialogContainer) {
|
|
const userInjector = config && config.viewContainerRef && config.viewContainerRef.injector;
|
|
// The dialog container should be provided as the dialog container and the dialog's
|
|
// content are created out of the same `ViewContainerRef` and as such, are siblings
|
|
// for injector purposes. To allow the hierarchy that is expected, the dialog
|
|
// container is explicitly provided in the injector.
|
|
const providers = [
|
|
{ provide: this._dialogContainerType, useValue: dialogContainer },
|
|
{ provide: this._dialogDataToken, useValue: config.data },
|
|
{ provide: this._dialogRefConstructor, useValue: dialogRef }
|
|
];
|
|
if (config.direction && (!userInjector ||
|
|
!userInjector.get(Directionality, null, InjectFlags.Optional))) {
|
|
providers.push({
|
|
provide: Directionality,
|
|
useValue: { value: config.direction, change: observableOf() }
|
|
});
|
|
}
|
|
return Injector.create({ parent: userInjector || this._injector, providers });
|
|
}
|
|
/**
|
|
* Removes a dialog from the array of open dialogs.
|
|
* @param dialogRef Dialog to be removed.
|
|
*/
|
|
_removeOpenDialog(dialogRef) {
|
|
const index = this.openDialogs.indexOf(dialogRef);
|
|
if (index > -1) {
|
|
this.openDialogs.splice(index, 1);
|
|
// If all the dialogs were closed, remove/restore the `aria-hidden`
|
|
// to a the siblings and emit to the `afterAllClosed` stream.
|
|
if (!this.openDialogs.length) {
|
|
this._ariaHiddenElements.forEach((previousValue, element) => {
|
|
if (previousValue) {
|
|
element.setAttribute('aria-hidden', previousValue);
|
|
}
|
|
else {
|
|
element.removeAttribute('aria-hidden');
|
|
}
|
|
});
|
|
this._ariaHiddenElements.clear();
|
|
this._getAfterAllClosed().next();
|
|
}
|
|
}
|
|
}
|
|
/**
|
|
* Hides all of the content that isn't an overlay from assistive technology.
|
|
*/
|
|
_hideNonDialogContentFromAssistiveTechnology() {
|
|
const overlayContainer = this._overlayContainer.getContainerElement();
|
|
// Ensure that the overlay container is attached to the DOM.
|
|
if (overlayContainer.parentElement) {
|
|
const siblings = overlayContainer.parentElement.children;
|
|
for (let i = siblings.length - 1; i > -1; i--) {
|
|
let sibling = siblings[i];
|
|
if (sibling !== overlayContainer &&
|
|
sibling.nodeName !== 'SCRIPT' &&
|
|
sibling.nodeName !== 'STYLE' &&
|
|
!sibling.hasAttribute('aria-live')) {
|
|
this._ariaHiddenElements.set(sibling, sibling.getAttribute('aria-hidden'));
|
|
sibling.setAttribute('aria-hidden', 'true');
|
|
}
|
|
}
|
|
}
|
|
}
|
|
/** Closes all of the dialogs in an array. */
|
|
_closeDialogs(dialogs) {
|
|
let i = dialogs.length;
|
|
while (i--) {
|
|
// The `_openDialogs` property isn't updated after close until the rxjs subscription
|
|
// runs on the next microtask, in addition to modifying the array as we're going
|
|
// through it. We loop through all of them and call close without assuming that
|
|
// they'll be removed from the list instantaneously.
|
|
dialogs[i].close();
|
|
}
|
|
}
|
|
}
|
|
_MatDialogBase.ɵfac = function _MatDialogBase_Factory(t) { return new (t || _MatDialogBase)(ɵngcc0.ɵɵdirectiveInject(ɵngcc1.Overlay), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.Injector), ɵngcc0.ɵɵdirectiveInject(undefined), ɵngcc0.ɵɵdirectiveInject(undefined), ɵngcc0.ɵɵdirectiveInject(ɵngcc1.OverlayContainer), ɵngcc0.ɵɵdirectiveInject(undefined), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.Type), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.Type), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.InjectionToken)); };
|
|
_MatDialogBase.ɵdir = /*@__PURE__*/ ɵngcc0.ɵɵdefineDirective({ type: _MatDialogBase });
|
|
_MatDialogBase.ctorParameters = () => [
|
|
{ type: Overlay },
|
|
{ type: Injector },
|
|
{ type: undefined },
|
|
{ type: undefined },
|
|
{ type: OverlayContainer },
|
|
{ type: undefined },
|
|
{ type: Type },
|
|
{ type: Type },
|
|
{ type: InjectionToken }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(_MatDialogBase, [{
|
|
type: Directive
|
|
}], function () { return [{ type: ɵngcc1.Overlay }, { type: ɵngcc0.Injector }, { type: undefined }, { type: undefined }, { type: ɵngcc1.OverlayContainer }, { type: undefined }, { type: ɵngcc0.Type }, { type: ɵngcc0.Type }, { type: ɵngcc0.InjectionToken }]; }, null); })();
|
|
/**
|
|
* Service to open Material Design modal dialogs.
|
|
*/
|
|
export class MatDialog extends _MatDialogBase {
|
|
constructor(overlay, injector,
|
|
/**
|
|
* @deprecated `_location` parameter to be removed.
|
|
* @breaking-change 10.0.0
|
|
*/
|
|
location, defaultOptions, scrollStrategy, parentDialog, overlayContainer) {
|
|
super(overlay, injector, defaultOptions, parentDialog, overlayContainer, scrollStrategy, MatDialogRef, MatDialogContainer, MAT_DIALOG_DATA);
|
|
}
|
|
}
|
|
MatDialog.ɵfac = function MatDialog_Factory(t) { return new (t || MatDialog)(ɵngcc0.ɵɵinject(ɵngcc1.Overlay), ɵngcc0.ɵɵinject(ɵngcc0.Injector), ɵngcc0.ɵɵinject(ɵngcc2.Location, 8), ɵngcc0.ɵɵinject(MAT_DIALOG_DEFAULT_OPTIONS, 8), ɵngcc0.ɵɵinject(MAT_DIALOG_SCROLL_STRATEGY), ɵngcc0.ɵɵinject(MatDialog, 12), ɵngcc0.ɵɵinject(ɵngcc1.OverlayContainer)); };
|
|
MatDialog.ɵprov = /*@__PURE__*/ ɵngcc0.ɵɵdefineInjectable({ token: MatDialog, factory: MatDialog.ɵfac });
|
|
MatDialog.ctorParameters = () => [
|
|
{ type: Overlay },
|
|
{ type: Injector },
|
|
{ type: Location, decorators: [{ type: Optional }] },
|
|
{ type: MatDialogConfig, decorators: [{ type: Optional }, { type: Inject, args: [MAT_DIALOG_DEFAULT_OPTIONS,] }] },
|
|
{ type: undefined, decorators: [{ type: Inject, args: [MAT_DIALOG_SCROLL_STRATEGY,] }] },
|
|
{ type: MatDialog, decorators: [{ type: Optional }, { type: SkipSelf }] },
|
|
{ type: OverlayContainer }
|
|
];
|
|
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatDialog, [{
|
|
type: Injectable
|
|
}], function () { return [{ type: ɵngcc1.Overlay }, { type: ɵngcc0.Injector }, { type: ɵngcc2.Location, decorators: [{
|
|
type: Optional
|
|
}] }, { type: ɵngcc3.MatDialogConfig, decorators: [{
|
|
type: Optional
|
|
}, {
|
|
type: Inject,
|
|
args: [MAT_DIALOG_DEFAULT_OPTIONS]
|
|
}] }, { type: undefined, decorators: [{
|
|
type: Inject,
|
|
args: [MAT_DIALOG_SCROLL_STRATEGY]
|
|
}] }, { type: MatDialog, decorators: [{
|
|
type: Optional
|
|
}, {
|
|
type: SkipSelf
|
|
}] }, { type: ɵngcc1.OverlayContainer }]; }, null); })();
|
|
/**
|
|
* Applies default options to the dialog config.
|
|
* @param config Config to be modified.
|
|
* @param defaultOptions Default options provided.
|
|
* @returns The new configuration object.
|
|
*/
|
|
function _applyConfigDefaults(config, defaultOptions) {
|
|
return Object.assign(Object.assign({}, defaultOptions), config);
|
|
}
|
|
|
|
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGlhbG9nLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9zcmMvbWF0ZXJpYWwvZGlhbG9nL2RpYWxvZy50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQTtBQUNBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBRUgsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFDTCxPQUFPLEVBQ1AsYUFBYSxFQUNiLGdCQUFnQixHQUdqQixNQUFNLHNCQUFzQixDQUFDO0FBQzlCLE9BQU8sRUFBQyxlQUFlLEVBQWlCLGNBQWMsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ25GLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQ0wsU0FBUyxFQUNULE1BQU0sRUFDTixVQUFVLEVBQ1YsV0FBVyxFQUNYLGNBQWMsRUFDZCxRQUFRLEVBRVIsUUFBUSxFQUNSLFFBQVEsRUFFUixXQUFXLEVBQ1gsSUFBSSxHQUNMLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBQyxLQUFLLEVBQWMsRUFBRSxJQUFJLFlBQVksRUFBRSxPQUFPLEVBQUMsTUFBTSxNQUFNLENBQUM7QUFDcEUsT0FBTyxFQUFDLFNBQVMsRUFBQyxNQUFNLGdCQUFnQixDQUFDO0FBQ3pDLE9BQU8sRUFBQyxlQUFlLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUNoRCxPQUFPLEVBQUMsa0JBQWtCLEVBQTBCLE1BQU0sb0JBQW9CLENBQUM7QUFDL0UsT0FBTyxFQUFDLFlBQVksRUFBQyxNQUFNLGNBQWMsQ0FBQztBQUcxQywwRkFBMEY7Ozs7O0FBQzFGLE1BQU0sQ0FBQyxNQUFNLGVBQWUsR0FBRyxJQUFJLGNBQWMsQ0FBTSxlQUFlLENBQUMsQ0FBQztBQUV4RSwwRUFBMEU7QUFDMUUsTUFBTSxDQUFDLE1BQU0sMEJBQTBCLEdBQ25DLElBQUksY0FBYyxDQUFrQiw0QkFBNEIsQ0FBQyxDQUFDO0FBRXRF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OVdkLGVBQWUsdUJBK1doQixRQUFRLFlBQUksTUFBTSxTQUFDLDBCQUEwQjtBQUFTLDRDQUN0RCxNQUFNLFNBQUMsMEJBQTBCO0FBQVMsWUFDTCxTQUFTLHVCQUE5QyxRQUFRLFlBQUksUUFBUTtBQUFPLFlBdlloQyxnQkFBZ0I7QUFDakI7Ozs7Ozs7Ozs7Ozs7Ozs7O3FFQUFFO0FBNllIO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQSxHQUFHO0FBQ0gsU0FBUyxvQkFBb0IsQ0FDekIsTUFBd0IsRUFBRSxjQUFnQztBQUFJLElBQ2hFLHVDQUFXLGNBQWMsR0FBSyxNQUFNLEVBQUU7QUFDeEMsQ0FBQztBQUNEIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7RGlyZWN0aW9uYWxpdHl9IGZyb20gJ0Bhbmd1bGFyL2Nkay9iaWRpJztcbmltcG9ydCB7XG4gIE92ZXJsYXksXG4gIE92ZXJsYXlDb25maWcsXG4gIE92ZXJsYXlDb250YWluZXIsXG4gIE92ZXJsYXlSZWYsXG4gIFNjcm9sbFN0cmF0ZWd5LFxufSBmcm9tICdAYW5ndWxhci9jZGsvb3ZlcmxheSc7XG5pbXBvcnQge0NvbXBvbmVudFBvcnRhbCwgQ29tcG9uZW50VHlwZSwgVGVtcGxhdGVQb3J0YWx9IGZyb20gJ0Bhbmd1bGFyL2Nkay9wb3J0YWwnO1xuaW1wb3J0IHtMb2NhdGlvbn0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIERpcmVjdGl2ZSxcbiAgSW5qZWN0LFxuICBJbmplY3RhYmxlLFxuICBJbmplY3RGbGFncyxcbiAgSW5qZWN0aW9uVG9rZW4sXG4gIEluamVjdG9yLFxuICBPbkRlc3Ryb3ksXG4gIE9wdGlvbmFsLFxuICBTa2lwU2VsZixcbiAgU3RhdGljUHJvdmlkZXIsXG4gIFRlbXBsYXRlUmVmLFxuICBUeXBlLFxufSBmcm9tICdAYW5ndWxhci9jb3JlJztcbmltcG9ydCB7ZGVmZXIsIE9ic2VydmFibGUsIG9mIGFzIG9ic2VydmFibGVPZiwgU3ViamVjdH0gZnJvbSAncnhqcyc7XG5pbXBvcnQge3N0YXJ0V2l0aH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHtNYXREaWFsb2dDb25maWd9IGZyb20gJy4vZGlhbG9nLWNvbmZpZyc7XG5pbXBvcnQge01hdERpYWxvZ0NvbnRhaW5lciwgX01hdERpYWxvZ0NvbnRhaW5lckJhc2V9IGZyb20gJy4vZGlhbG9nLWNvbnRhaW5lcic7XG5pbXBvcnQge01hdERpYWxvZ1JlZn0gZnJvbSAnLi9kaWFsb2ctcmVmJztcblxuXG4vKiogSW5qZWN0aW9uIHRva2VuIHRoYXQgY2FuIGJlIHVzZWQgdG8gYWNjZXNzIHRoZSBkYXRhIHRoYXQgd2FzIHBhc3NlZCBpbiB0byBhIGRpYWxvZy4gKi9cbmV4cG9ydCBjb25zdCBNQVRfRElBTE9HX0RBVEEgPSBuZXcgSW5qZWN0aW9uVG9rZW48YW55PignTWF0RGlhbG9nRGF0YScpO1xuXG4vKiogSW5qZWN0aW9uIHRva2VuIHRoYXQgY2FuIGJlIHVzZWQgdG8gc3BlY2lmeSBkZWZhdWx0IGRpYWxvZyBvcHRpb25zLiAqL1xuZXhwb3J0IGNvbnN0IE1BVF9ESUFMT0dfREVGQVVMVF9PUFRJT05TID1cbiAgICBuZXcgSW5qZWN0aW9uVG9rZW48TWF0RGlhbG9nQ29uZmlnPignbWF0LWRpYWxvZy1kZWZhdWx0LW9wdGlvbnMnKTtcblxuLyoqIEluamVjdGlvbiB0b2tlbiB0aGF0IGRldGVybWluZXMgdGhlIHNjcm9sbCBoYW5kbGluZyB3aGlsZSB0aGUgZGlhbG9nIGlzIG9wZW4uICovXG5leHBvcnQgY29uc3QgTUFUX0RJQUxPR19TQ1JPTExfU1RSQVRFR1kgPVxuICAgIG5ldyBJbmplY3Rpb25Ub2tlbjwoKSA9PiBTY3JvbGxTdHJhdGVneT4oJ21hdC1kaWFsb2ctc2Nyb2xsLXN0cmF0ZWd5Jyk7XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgZnVuY3Rpb24gTUFUX0RJQUxPR19TQ1JPTExfU1RSQVRFR1lfRkFDVE9SWShvdmVybGF5OiBPdmVybGF5KTogKCkgPT4gU2Nyb2xsU3RyYXRlZ3kge1xuICByZXR1cm4gKCkgPT4gb3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLmJsb2NrKCk7XG59XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgZnVuY3Rpb24gTUFUX0RJQUxPR19TQ1JPTExfU1RSQVRFR1lfUFJPVklERVJfRkFDVE9SWShvdmVybGF5OiBPdmVybGF5KTpcbiAgKCkgPT4gU2Nyb2xsU3RyYXRlZ3kge1xuICByZXR1cm4gKCkgPT4gb3ZlcmxheS5zY3JvbGxTdHJhdGVnaWVzLmJsb2NrKCk7XG59XG5cbi8qKiBAZG9jcy1wcml2YXRlICovXG5leHBvcnQgY29uc3QgTUFUX0RJQUxPR19TQ1JPTExfU1RSQVRFR1lfUFJPVklERVIgPSB7XG4gIHByb3ZpZGU6IE1BVF9ESUFMT0dfU0NST0xMX1NUUkFURUdZLFxuICBkZXBzOiBbT3ZlcmxheV0sXG4gIHVzZUZhY3Rvcnk6IE1BVF9ESUFMT0dfU0NST0xMX1NUUkFURUdZX1BST1ZJREVSX0ZBQ1RPUlksXG59O1xuXG4vKipcbiAqIEJhc2UgY2xhc3MgZm9yIGRpYWxvZyBzZXJ2aWNlcy4gVGhlIGJhc2UgZGlhbG9nIHNlcnZpY2UgYWxsb3dzXG4gKiBmb3IgYXJiaXRyYXJ5IGRpYWxvZyByZWZzIGFuZCBkaWFsb2cgY29udGFpbmVyIGNvbXBvbmVudHMuXG4gKi9cbkBEaXJlY3RpdmUoKVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIF9NYXREaWFsb2dCYXNlPEMgZXh0ZW5kcyBfTWF0RGlhbG9nQ29udGFpbmVyQmFzZT4gaW1wbGVtZW50cyBPbkRlc3Ryb3kge1xuICBwcml2YXRlIF9vcGVuRGlhbG9nc0F0VGhpc0xldmVsOiBNYXREaWFsb2dSZWY8YW55PltdID0gW107XG4gIHByaXZhdGUgcmVhZG9ubHkgX2FmdGVyQWxsQ2xvc2VkQXRUaGlzTGV2ZWwgPSBuZXcgU3ViamVjdDx2b2lkPigpO1xuICBwcml2YXRlIHJlYWRvbmx5IF9hZnRlck9wZW5lZEF0VGhpc0xldmVsID0gbmV3IFN1YmplY3Q8TWF0RGlhbG9nUmVmPGFueT4+KCk7XG4gIHByaXZhdGUgX2FyaWFIaWRkZW5FbGVtZW50cyA9IG5ldyBNYXA8RWxlbWVudCwgc3RyaW5nfG51bGw+KCk7XG4gIHByaXZhdGUgX3Njcm9sbFN0cmF0ZWd5OiAoKSA9PiBTY3JvbGxTdHJhdGVneTtcblxuICAvKiogS2VlcHMgdHJhY2sgb2YgdGhlIGN1cnJlbnRseS1vcGVuIGRpYWxvZ3MuICovXG4gIGdldCBvcGVuRGlhbG9ncygpOiBNYXREaWFsb2dSZWY8YW55PltdIHtcbiAgICByZXR1cm4gdGhpcy5fcGFyZW50RGlhbG9nID8gdGhpcy5fcGFyZW50RGlhbG9nLm9wZW5EaWFsb2dzIDogdGhpcy5fb3BlbkRpYWxvZ3NBdFRoaXNMZXZlbDtcbiAgfVxuXG4gIC8qKiBTdHJlYW0gdGhhdCBlbWl0cyB3aGVuIGEgZGlhbG9nIGhhcyBiZWVuIG9wZW5lZC4gKi9cbiAgZ2V0IGFmdGVyT3BlbmVkKCk6IFN1YmplY3Q8TWF0RGlhbG9nUmVmPGFueT4+IHtcbiAgICByZXR1cm4gdGhpcy5fcGFyZW50RGlhbG9nID8gdGhpcy5fcGFyZW50RGlhbG9nLmFmdGVyT3BlbmVkIDogdGhpcy5fYWZ0ZXJPcGVuZWRBdFRoaXNMZXZlbDtcbiAgfVxuXG4gIF9nZXRBZnRlckFsbENsb3NlZCgpOiBTdWJqZWN0PHZvaWQ+IHtcbiAgICBjb25zdCBwYXJlbnQgPSB0aGlzLl9wYXJlbnREaWFsb2c7XG4gICAgcmV0dXJuIHBhcmVudCA/IHBhcmVudC5fZ2V0QWZ0ZXJBbGxDbG9zZWQoKSA6IHRoaXMuX2FmdGVyQWxsQ2xvc2VkQXRUaGlzTGV2ZWw7XG4gIH1cblxuICAvLyBUT0RPIChqZWxib3Vybik6IHRpZ2h0ZW4gdGhlIHR5cGluZyByaWdodC1oYW5kIHNpZGUgb2YgdGhpcyBleHByZXNzaW9uLlxuICAvKipcbiAgICogU3RyZWFtIHRoYXQgZW1pdHMgd2hlbiBhbGwgb3BlbiBkaWFsb2cgaGF2ZSBmaW5pc2hlZCBjbG9zaW5nLlxuICAgKiBXaWxsIGVtaXQgb24gc3Vic2NyaWJlIGlmIHRoZXJlIGFyZSBubyBvcGVuIGRpYWxvZ3MgdG8gYmVnaW4gd2l0aC5cbiAgICovXG4gIHJlYWRvbmx5IGFmdGVyQWxsQ2xvc2VkOiBPYnNlcnZhYmxlPHZvaWQ+ID0gZGVmZXIoKCkgPT4gdGhpcy5vcGVuRGlhbG9ncy5sZW5ndGggP1xuICAgICAgdGhpcy5fZ2V0QWZ0ZXJBbGxDbG9zZWQoKSA6XG4gICAgICB0aGlzLl9nZXRBZnRlckFsbENsb3NlZCgpLnBpcGUoc3RhcnRXaXRoKHVuZGVmaW5lZCkpKSBhcyBPYnNlcnZhYmxlPGFueT47XG5cbiAgY29uc3RydWN0b3IoXG4gICAgICBwcml2YXRlIF9vdmVybGF5OiBPdmVybGF5LFxuICAgICAgcHJpdmF0ZSBfaW5qZWN0b3I6IEluamVjdG9yLFxuICAgICAgcHJpdmF0ZSBfZGVmYXVsdE9wdGlvbnM6IE1hdERpYWxvZ0NvbmZpZ3x1bmRlZmluZWQsXG4gICAgICBwcml2YXRlIF9wYXJlbnREaWFsb2c6IF9NYXREaWFsb2dCYXNlPEM+fHVuZGVmaW5lZCxcbiAgICAgIHByaXZhdGUgX292ZXJsYXlDb250YWluZXI6IE92ZXJsYXlDb250YWluZXIsXG4gICAgICBzY3JvbGxTdHJhdGVneTogYW55LFxuICAgICAgcHJpdmF0ZSBfZGlhbG9nUmVmQ29uc3RydWN0b3I6IFR5cGU8TWF0RGlhbG9nUmVmPGFueT4+LFxuICAgICAgcHJpdmF0ZSBfZGlhbG9nQ29udGFpbmVyVHlwZTogVHlwZTxDPixcbiAgICAgIHByaXZhdGUgX2RpYWxvZ0RhdGFUb2tlbjogSW5qZWN0aW9uVG9rZW48YW55Pikge1xuICAgIHRoaXMuX3Njcm9sbFN0cmF0ZWd5ID0gc2Nyb2xsU3RyYXRlZ3k7XG4gIH1cblxuICAvKipcbiAgICogT3BlbnMgYSBtb2RhbCBkaWFsb2cgY29udGFpbmluZyB0aGUgZ2l2ZW4gY29tcG9uZW50LlxuICAgKiBAcGFyYW0gY29tcG9uZW50IFR5cGUgb2YgdGhlIGNvbXBvbmVudCB0byBsb2FkIGludG8gdGhlIGRpYWxvZy5cbiAgICogQHBhcmFtIGNvbmZpZyBFeHRyYSBjb25maWd1cmF0aW9uIG9wdGlvbnMuXG4gICAqIEByZXR1cm5zIFJlZmVyZW5jZSB0byB0aGUgbmV3bHktb3BlbmVkIGRpYWxvZy5cbiAgICovXG4gIG9wZW48VCwgRCA9IGFueSwgUiA9IGFueT4oY29tcG9uZW50OiBDb21wb25lbnRUeXBlPFQ+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZz86IE1hdERpYWxvZ0NvbmZpZzxEPik6IE1hdERpYWxvZ1JlZjxULCBSPjtcblxuICAvKipcbiAgICogT3BlbnMgYSBtb2RhbCBkaWFsb2cgY29udGFpbmluZyB0aGUgZ2l2ZW4gdGVtcGxhdGUuXG4gICAqIEBwYXJhbSB0ZW1wbGF0ZSBUZW1wbGF0ZVJlZiB0byBpbnN0YW50aWF0ZSBhcyB0aGUgZGlhbG9nIGNvbnRlbnQuXG4gICAqIEBwYXJhbSBjb25maWcgRXh0cmEgY29uZmlndXJhdGlvbiBvcHRpb25zLlxuICAgKiBAcmV0dXJucyBSZWZlcmVuY2UgdG8gdGhlIG5ld2x5LW9wZW5lZCBkaWFsb2cuXG4gICAqL1xuICBvcGVuPFQsIEQgPSBhbnksIFIgPSBhbnk+KHRlbXBsYXRlOiBUZW1wbGF0ZVJlZjxUPixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWc/OiBNYXREaWFsb2dDb25maWc8RD4pOiBNYXREaWFsb2dSZWY8VCwgUj47XG5cbiAgb3BlbjxULCBEID0gYW55LCBSID0gYW55Pih0ZW1wbGF0ZTogQ29tcG9uZW50VHlwZTxUPiB8IFRlbXBsYXRlUmVmPFQ+LFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmZpZz86IE1hdERpYWxvZ0NvbmZpZzxEPik6IE1hdERpYWxvZ1JlZjxULCBSPjtcblxuICBvcGVuPFQsIEQgPSBhbnksIFIgPSBhbnk+KGNvbXBvbmVudE9yVGVtcGxhdGVSZWY6IENvbXBvbmVudFR5cGU8VD4gfCBUZW1wbGF0ZVJlZjxUPixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWc/OiBNYXREaWFsb2dDb25maWc8RD4pOiBNYXREaWFsb2dSZWY8VCwgUj4ge1xuICAgIGNvbmZpZyA9IF9hcHBseUNvbmZpZ0RlZmF1bHRzKGNvbmZpZywgdGhpcy5fZGVmYXVsdE9wdGlvbnMgfHwgbmV3IE1hdERpYWxvZ0NvbmZpZygpKTtcblxuICAgIGlmIChjb25maWcuaWQgJiYgdGhpcy5nZXREaWFsb2dCeUlkKGNvbmZpZy5pZCkgJiZcbiAgICAgICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpKSB7XG4gICAgICB0aHJvdyBFcnJvcihgRGlhbG9nIHdpdGggaWQgXCIke2NvbmZpZy5pZH1cIiBleGlzdHMgYWxyZWFkeS4gVGhlIGRpYWxvZyBpZCBtdXN0IGJlIHVuaXF1ZS5gKTtcbiAgICB9XG5cbiAgICBjb25zdCBvdmVybGF5UmVmID0gdGhpcy5fY3JlYXRlT3ZlcmxheShjb25maWcpO1xuICAgIGNvbnN0IGRpYWxvZ0NvbnRhaW5lciA9IHRoaXMuX2F0dGFjaERpYWxvZ0NvbnRhaW5lcihvdmVybGF5UmVmLCBjb25maWcpO1xuICAgIGNvbnN0IGRpYWxvZ1JlZiA9IHRoaXMuX2F0dGFjaERpYWxvZ0NvbnRlbnQ8VCwgUj4oY29tcG9uZW50T3JUZW1wbGF0ZVJlZixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGRpYWxvZ0NvbnRhaW5lcixcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG92ZXJsYXlSZWYsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25maWcpO1xuXG4gICAgLy8gSWYgdGhpcyBpcyB0aGUgZmlyc3QgZGlhbG9nIHRoYXQgd2UncmUgb3BlbmluZywgaGlkZSBhbGwgdGhlIG5vbi1vdmVybGF5IGNvbnRlbnQuXG4gICAgaWYgKCF0aGlzLm9wZW5EaWFsb2dzLmxlbmd0aCkge1xuICAgICAgdGhpcy5faGlkZU5vbkRpYWxvZ0NvbnRlbnRGcm9tQXNzaXN0aXZlVGVjaG5vbG9neSgpO1xuICAgIH1cblxuICAgIHRoaXMub3BlbkRpYWxvZ3MucHVzaChkaWFsb2dSZWYpO1xuICAgIGRpYWxvZ1JlZi5hZnRlckNsb3NlZCgpLnN1YnNjcmliZSgoKSA9PiB0aGlzLl9yZW1vdmVPcGVuRGlhbG9nKGRpYWxvZ1JlZikpO1xuICAgIHRoaXMuYWZ0ZXJPcGVuZWQubmV4dChkaWFsb2dSZWYpO1xuXG4gICAgLy8gTm90aWZ5IHRoZSBkaWFsb2cgY29udGFpbmVyIHRoYXQgdGhlIGNvbnRlbnQgaGFzIGJlZW4gYXR0YWNoZWQuXG4gICAgZGlhbG9nQ29udGFpbmVyLl9pbml0aWFsaXplV2l0aEF0dGFjaGVkQ29udGVudCgpO1xuXG4gICAgcmV0dXJuIGRpYWxvZ1JlZjtcbiAgfVxuXG4gIC8qKlxuICAgKiBDbG9zZXMgYWxsIG9mIHRoZSBjdXJyZW50bHktb3BlbiBkaWFsb2dzLlxuICAgKi9cbiAgY2xvc2VBbGwoKTogdm9pZCB7XG4gICAgdGhpcy5fY2xvc2VEaWFsb2dzKHRoaXMub3BlbkRpYWxvZ3MpO1xuICB9XG5cbiAgLyoqXG4gICAqIEZpbmRzIGFuIG9wZW4gZGlhbG9nIGJ5IGl0cyBpZC5cbiAgICogQHBhcmFtIGlkIElEIHRvIHVzZSB3aGVuIGxvb2tpbmcgdXAgdGhlIGRpYWxvZy5cbiAgICovXG4gIGdldERpYWxvZ0J5SWQoaWQ6IHN0cmluZyk6IE1hdERpYWxvZ1JlZjxhbnk+IHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5vcGVuRGlhbG9ncy5maW5kKGRpYWxvZyA9PiBkaWFsb2cuaWQgPT09IGlkKTtcbiAgfVxuXG4gIG5nT25EZXN0cm95KCkge1xuICAgIC8vIE9ubHkgY2xvc2UgdGhlIGRpYWxvZ3MgYXQgdGhpcyBsZXZlbCBvbiBkZXN0cm95XG4gICAgLy8gc2luY2UgdGhlIHBhcmVudCBzZXJ2aWNlIG1heSBzdGlsbCBiZSBhY3RpdmUuXG4gICAgdGhpcy5fY2xvc2VEaWFsb2dzKHRoaXMuX29wZW5EaWFsb2dzQXRUaGlzTGV2ZWwpO1xuICAgIHRoaXMuX2FmdGVyQWxsQ2xvc2VkQXRUaGlzTGV2ZWwuY29tcGxldGUoKTtcbiAgICB0aGlzLl9hZnRlck9wZW5lZEF0VGhpc0xldmVsLmNvbXBsZXRlKCk7XG4gIH1cblxuICAvKipcbiAgICogQ3JlYXRlcyB0aGUgb3ZlcmxheSBpbnRvIHdoaWNoIHRoZSBkaWFsb2cgd2lsbCBiZSBsb2FkZWQuXG4gICAqIEBwYXJhbSBjb25maWcgVGhlIGRpYWxvZyBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgcmVzb2x2aW5nIHRvIHRoZSBPdmVybGF5UmVmIGZvciB0aGUgY3JlYXRlZCBvdmVybGF5LlxuICAgKi9cbiAgcHJpdmF0ZSBfY3JlYXRlT3ZlcmxheShjb25maWc6IE1hdERpYWxvZ0NvbmZpZyk6IE92ZXJsYXlSZWYge1xuICAgIGNvbnN0IG92ZXJsYXlDb25maWcgPSB0aGlzLl9nZXRPdmVybGF5Q29uZmlnKGNvbmZpZyk7XG4gICAgcmV0dXJuIHRoaXMuX292ZXJsYXkuY3JlYXRlKG92ZXJsYXlDb25maWcpO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYW4gb3ZlcmxheSBjb25maWcgZnJvbSBhIGRpYWxvZyBjb25maWcuXG4gICAqIEBwYXJhbSBkaWFsb2dDb25maWcgVGhlIGRpYWxvZyBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyBUaGUgb3ZlcmxheSBjb25maWd1cmF0aW9uLlxuICAgKi9cbiAgcHJpdmF0ZSBfZ2V0T3ZlcmxheUNvbmZpZyhkaWFsb2dDb25maWc6IE1hdERpYWxvZ0NvbmZpZyk6IE92ZXJsYXlDb25maWcge1xuICAgIGNvbnN0IHN0YXRlID0gbmV3IE92ZXJsYXlDb25maWcoe1xuICAgICAgcG9zaXRpb25TdHJhdGVneTogdGhpcy5fb3ZlcmxheS5wb3NpdGlvbigpLmdsb2JhbCgpLFxuICAgICAgc2Nyb2xsU3RyYXRlZ3k6IGRpYWxvZ0NvbmZpZy5zY3JvbGxTdHJhdGVneSB8fCB0aGlzLl9zY3JvbGxTdHJhdGVneSgpLFxuICAgICAgcGFuZWxDbGFzczogZGlhbG9nQ29uZmlnLnBhbmVsQ2xhc3MsXG4gICAgICBoYXNCYWNrZHJvcDogZGlhbG9nQ29uZmlnLmhhc0JhY2tkcm9wLFxuICAgICAgZGlyZWN0aW9uOiBkaWFsb2dDb25maWcuZGlyZWN0aW9uLFxuICAgICAgbWluV2lkdGg6IGRpYWxvZ0NvbmZpZy5taW5XaWR0aCxcbiAgICAgIG1pbkhlaWdodDogZGlhbG9nQ29uZmlnLm1pbkhlaWdodCxcbiAgICAgIG1heFdpZHRoOiBkaWFsb2dDb25maWcubWF4V2lkdGgsXG4gICAgICBtYXhIZWlnaHQ6IGRpYWxvZ0NvbmZpZy5tYXhIZWlnaHQsXG4gICAgICBkaXNwb3NlT25OYXZpZ2F0aW9uOiBkaWFsb2dDb25maWcuY2xvc2VPbk5hdmlnYXRpb25cbiAgICB9KTtcblxuICAgIGlmIChkaWFsb2dDb25maWcuYmFja2Ryb3BDbGFzcykge1xuICAgICAgc3RhdGUuYmFja2Ryb3BDbGFzcyA9IGRpYWxvZ0NvbmZpZy5iYWNrZHJvcENsYXNzO1xuICAgIH1cblxuICAgIHJldHVybiBzdGF0ZTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2hlcyBhIGRpYWxvZyBjb250YWluZXIgdG8gYSBkaWFsb2cncyBhbHJlYWR5LWNyZWF0ZWQgb3ZlcmxheS5cbiAgICogQHBhcmFtIG92ZXJsYXkgUmVmZXJlbmNlIHRvIHRoZSBkaWFsb2cncyB1bmRlcmx5aW5nIG92ZXJsYXkuXG4gICAqIEBwYXJhbSBjb25maWcgVGhlIGRpYWxvZyBjb25maWd1cmF0aW9uLlxuICAgKiBAcmV0dXJucyBBIHByb21pc2UgcmVzb2x2aW5nIHRvIGEgQ29tcG9uZW50UmVmIGZvciB0aGUgYXR0YWNoZWQgY29udGFpbmVyLlxuICAgKi9cbiAgcHJpdmF0ZSBfYXR0YWNoRGlhbG9nQ29udGFpbmVyKG92ZXJsYXk6IE92ZXJsYXlSZWYsIGNvbmZpZzogTWF0RGlhbG9nQ29uZmlnKTogQyB7XG4gICAgY29uc3QgdXNlckluamVjdG9yID0gY29uZmlnICYmIGNvbmZpZy52aWV3Q29udGFpbmVyUmVmICYmIGNvbmZpZy52aWV3Q29udGFpbmVyUmVmLmluamVjdG9yO1xuICAgIGNvbnN0IGluamVjdG9yID0gSW5qZWN0b3IuY3JlYXRlKHtcbiAgICAgIHBhcmVudDogdXNlckluamVjdG9yIHx8IHRoaXMuX2luamVjdG9yLFxuICAgICAgcHJvdmlkZXJzOiBbe3Byb3ZpZGU6IE1hdERpYWxvZ0NvbmZpZywgdXNlVmFsdWU6IGNvbmZpZ31dXG4gICAgfSk7XG5cbiAgICBjb25zdCBjb250YWluZXJQb3J0YWwgPSBuZXcgQ29tcG9uZW50UG9ydGFsKHRoaXMuX2RpYWxvZ0NvbnRhaW5lclR5cGUsXG4gICAgICAgIGNvbmZpZy52aWV3Q29udGFpbmVyUmVmLCBpbmplY3RvciwgY29uZmlnLmNvbXBvbmVudEZhY3RvcnlSZXNvbHZlcik7XG4gICAgY29uc3QgY29udGFpbmVyUmVmID0gb3ZlcmxheS5hdHRhY2g8Qz4oY29udGFpbmVyUG9ydGFsKTtcblxuICAgIHJldHVybiBjb250YWluZXJSZWYuaW5zdGFuY2U7XG4gIH1cblxuICAvKipcbiAgICogQXR0YWNoZXMgdGhlIHVzZXItcHJvdmlkZWQgY29tcG9uZW50IHRvIHRoZSBhbHJlYWR5LWNyZWF0ZWQgZGlhbG9nIGNvbnRhaW5lci5cbiAgICogQHBhcmFtIGNvbXBvbmVudE9yVGVtcGxhdGVSZWYgVGhlIHR5cGUgb2YgY29tcG9uZW50IGJlaW5nIGxvYWRlZCBpbnRvIHRoZSBkaWFsb2csXG4gICAqICAgICBvciBhIFRlbXBsYXRlUmVmIHRvIGluc3RhbnRpYXRlIGFzIHRoZSBjb250ZW50LlxuICAgKiBAcGFyYW0gZGlhbG9nQ29udGFpbmVyIFJlZmVyZW5jZSB0byB0aGUgd3JhcHBpbmcgZGlhbG9nIGNvbnRhaW5lci5cbiAgICogQHBhcmFtIG92ZXJsYXlSZWYgUmVmZXJlbmNlIHRvIHRoZSBvdmVybGF5IGluIHdoaWNoIHRoZSBkaWFsb2cgcmVzaWRlcy5cbiAgICogQHBhcmFtIGNvbmZpZyBUaGUgZGlhbG9nIGNvbmZpZ3VyYXRpb24uXG4gICAqIEByZXR1cm5zIEEgcHJvbWlzZSByZXNvbHZpbmcgdG8gdGhlIE1hdERpYWxvZ1JlZiB0aGF0IHNob3VsZCBiZSByZXR1cm5lZCB0byB0aGUgdXNlci5cbiAgICovXG4gIHByaXZhdGUgX2F0dGFjaERpYWxvZ0NvbnRlbnQ8VCwgUj4oXG4gICAgICBjb21wb25lbnRPclRlbXBsYXRlUmVmOiBDb21wb25lbnRUeXBlPFQ+IHwgVGVtcGxhdGVSZWY8VD4sXG4gICAgICBkaWFsb2dDb250YWluZXI6IEMsXG4gICAgICBvdmVybGF5UmVmOiBPdmVybGF5UmVmLFxuICAgICAgY29uZmlnOiBNYXREaWFsb2dDb25maWcpOiBNYXREaWFsb2dSZWY8VCwgUj4ge1xuXG4gICAgLy8gQ3JlYXRlIGEgcmVmZXJlbmNlIHRvIHRoZSBkaWFsb2cgd2UncmUgY3JlYXRpbmcgaW4gb3JkZXIgdG8gZ2l2ZSB0aGUgdXNlciBhIGhhbmRsZVxuICAgIC8vIHRvIG1vZGlmeSBhbmQgY2xvc2UgaXQuXG4gICAgY29uc3QgZGlhbG9nUmVmID0gbmV3IHRoaXMuX2RpYWxvZ1JlZkNvbnN0cnVjdG9yKG92ZXJsYXlSZWYsIGRpYWxvZ0NvbnRhaW5lciwgY29uZmlnLmlkKTtcblxuICAgIGlmIChjb21wb25lbnRPclRlbXBsYXRlUmVmIGluc3RhbmNlb2YgVGVtcGxhdGVSZWYpIHtcbiAgICAgIGRpYWxvZ0NvbnRhaW5lci5hdHRhY2hUZW1wbGF0ZVBvcnRhbChcbiAgICAgICAgbmV3IFRlbXBsYXRlUG9ydGFsPFQ+KGNvbXBvbmVudE9yVGVtcGxhdGVSZWYsIG51bGwhLFxuICAgICAgICAgIDxhbnk+eyRpbXBsaWNpdDogY29uZmlnLmRhdGEsIGRpYWxvZ1JlZn0pKTtcbiAgICB9IGVsc2Uge1xuICAgICAgY29uc3QgaW5qZWN0b3IgPSB0aGlzLl9jcmVhdGVJbmplY3RvcjxUPihjb25maWcsIGRpYWxvZ1JlZiwgZGlhbG9nQ29udGFpbmVyKTtcbiAgICAgIGNvbnN0IGNvbnRlbnRSZWYgPSBkaWFsb2dDb250YWluZXIuYXR0YWNoQ29tcG9uZW50UG9ydGFsPFQ+KFxuICAgICAgICAgIG5ldyBDb21wb25lbnRQb3J0YWwoY29tcG9uZW50T3JUZW1wbGF0ZVJlZiwgY29uZmlnLnZpZXdDb250YWluZXJSZWYsIGluamVjdG9yKSk7XG4gICAgICBkaWFsb2dSZWYuY29tcG9uZW50SW5zdGFuY2UgPSBjb250ZW50UmVmLmluc3RhbmNlO1xuICAgIH1cblxuICAgIGRpYWxvZ1JlZlxuICAgICAgLnVwZGF0ZVNpemUoY29uZmlnLndpZHRoLCBjb25maWcuaGVpZ2h0KVxuICAgICAgLnVwZGF0ZVBvc2l0aW9uKGNvbmZpZy5wb3NpdGlvbik7XG5cbiAgICByZXR1cm4gZGlhbG9nUmVmO1xuICB9XG5cbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBjdXN0b20gaW5qZWN0b3IgdG8gYmUgdXNlZCBpbnNpZGUgdGhlIGRpYWxvZy4gVGhpcyBhbGxvd3MgYSBjb21wb25lbnQgbG9hZGVkIGluc2lkZVxuICAgKiBvZiBhIGRpYWxvZyB0byBjbG9zZSBpdHNlbGYgYW5kLCBvcHRpb25hbGx5LCB0byByZXR1cm4gYSB2YWx1ZS5cbiAgICogQHBhcmFtIGNvbmZpZyBDb25maWcgb2JqZWN0IHRoYXQgaXMgdXNlZCB0byBjb25zdHJ1Y3QgdGhlIGRpYWxvZy5cbiAgICogQHBhcmFtIGRpYWxvZ1JlZiBSZWZlcmVuY2UgdG8gdGhlIGRpYWxvZy5cbiAgICogQHBhcmFtIGRpYWxvZ0NvbnRhaW5lciBEaWFsb2cgY29udGFpbmVyIGVsZW1lbnQgdGhhdCB3cmFwcyBhbGwgb2YgdGhlIGNvbnRlbnRzLlxuICAgKiBAcmV0dXJucyBUaGUgY3VzdG9tIGluamVjdG9yIHRoYXQgY2FuIGJlIHVzZWQgaW5zaWRlIHRoZSBkaWFsb2cuXG4gICAqL1xuICBwcml2YXRlIF9jcmVhdGVJbmplY3RvcjxUPihcbiAgICAgIGNvbmZpZzogTWF0RGlhbG9nQ29uZmlnLFxuICAgICAgZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8VD4sXG4gICAgICBkaWFsb2dDb250YWluZXI6IEMpOiBJbmplY3RvciB7XG5cbiAgICBjb25zdCB1c2VySW5qZWN0b3IgPSBjb25maWcgJiYgY29uZmlnLnZpZXdDb250YWluZXJSZWYgJiYgY29uZmlnLnZpZXdDb250YWluZXJSZWYuaW5qZWN0b3I7XG5cbiAgICAvLyBUaGUgZGlhbG9nIGNvbnRhaW5lciBzaG91bGQgYmUgcHJvdmlkZWQgYXMgdGhlIGRpYWxvZyBjb250YWluZXIgYW5kIHRoZSBkaWFsb2cnc1xuICAgIC8vIGNvbnRlbnQgYXJlIGNyZWF0ZWQgb3V0IG9mIHRoZSBzYW1lIGBWaWV3Q29udGFpbmVyUmVmYCBhbmQgYXMgc3VjaCwgYXJlIHNpYmxpbmdzXG4gICAgLy8gZm9yIGluamVjdG9yIHB1cnBvc2VzLiBUbyBhbGxvdyB0aGUgaGllcmFyY2h5IHRoYXQgaXMgZXhwZWN0ZWQsIHRoZSBkaWFsb2dcbiAgICAvLyBjb250YWluZXIgaXMgZXhwbGljaXRseSBwcm92aWRlZCBpbiB0aGUgaW5qZWN0b3IuXG4gICAgY29uc3QgcHJvdmlkZXJzOiBTdGF0aWNQcm92aWRlcltdID0gW1xuICAgICAge3Byb3ZpZGU6IHRoaXMuX2RpYWxvZ0NvbnRhaW5lclR5cGUsIHVzZVZhbHVlOiBkaWFsb2dDb250YWluZXJ9LFxuICAgICAge3Byb3ZpZGU6IHRoaXMuX2RpYWxvZ0RhdGFUb2tlbiwgdXNlVmFsdWU6IGNvbmZpZy5kYXRhfSxcbiAgICAgIHtwcm92aWRlOiB0aGlzLl9kaWFsb2dSZWZDb25zdHJ1Y3RvciwgdXNlVmFsdWU6IGRpYWxvZ1JlZn1cbiAgICBdO1xuXG4gICAgaWYgKGNvbmZpZy5kaXJlY3Rpb24gJiYgKCF1c2VySW5qZWN0b3IgfHxcbiAgICAgICAgIXVzZXJJbmplY3Rvci5nZXQ8RGlyZWN0aW9uYWxpdHkgfCBudWxsPihEaXJlY3Rpb25hbGl0eSwgbnVsbCwgSW5qZWN0RmxhZ3MuT3B0aW9uYWwpKSkge1xuICAgICAgcHJvdmlkZXJzLnB1c2goe1xuICAgICAgICBwcm92aWRlOiBEaXJlY3Rpb25hbGl0eSxcbiAgICAgICAgdXNlVmFsdWU6IHt2YWx1ZTogY29uZmlnLmRpcmVjdGlvbiwgY2hhbmdlOiBvYnNlcnZhYmxlT2YoKX1cbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHJldHVybiBJbmplY3Rvci5jcmVhdGUoe3BhcmVudDogdXNlckluamVjdG9yIHx8IHRoaXMuX2luamVjdG9yLCBwcm92aWRlcnN9KTtcbiAgfVxuXG4gIC8qKlxuICAgKiBSZW1vdmVzIGEgZGlhbG9nIGZyb20gdGhlIGFycmF5IG9mIG9wZW4gZGlhbG9ncy5cbiAgICogQHBhcmFtIGRpYWxvZ1JlZiBEaWFsb2cgdG8gYmUgcmVtb3ZlZC5cbiAgICovXG4gIHByaXZhdGUgX3JlbW92ZU9wZW5EaWFsb2coZGlhbG9nUmVmOiBNYXREaWFsb2dSZWY8YW55Pikge1xuICAgIGNvbnN0IGluZGV4ID0gdGhpcy5vcGVuRGlhbG9ncy5pbmRleE9mKGRpYWxvZ1JlZik7XG5cbiAgICBpZiAoaW5kZXggPiAtMSkge1xuICAgICAgdGhpcy5vcGVuRGlhbG9ncy5zcGxpY2UoaW5kZXgsIDEpO1xuXG4gICAgICAvLyBJZiBhbGwgdGhlIGRpYWxvZ3Mgd2VyZSBjbG9zZWQsIHJlbW92ZS9yZXN0b3JlIHRoZSBgYXJpYS1oaWRkZW5gXG4gICAgICAvLyB0byBhIHRoZSBzaWJsaW5ncyBhbmQgZW1pdCB0byB0aGUgYGFmdGVyQWxsQ2xvc2VkYCBzdHJlYW0uXG4gICAgICBpZiAoIXRoaXMub3BlbkRpYWxvZ3MubGVuZ3RoKSB7XG4gICAgICAgIHRoaXMuX2FyaWFIaWRkZW5FbGVtZW50cy5mb3JFYWNoKChwcmV2aW91c1ZhbHVlLCBlbGVtZW50KSA9PiB7XG4gICAgICAgICAgaWYgKHByZXZpb3VzVmFsdWUpIHtcbiAgICAgICAgICAgIGVsZW1lbnQuc2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicsIHByZXZpb3VzVmFsdWUpO1xuICAgICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgICBlbGVtZW50LnJlbW92ZUF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nKTtcbiAgICAgICAgICB9XG4gICAgICAgIH0pO1xuXG4gICAgICAgIHRoaXMuX2FyaWFIaWRkZW5FbGVtZW50cy5jbGVhcigpO1xuICAgICAgICB0aGlzLl9nZXRBZnRlckFsbENsb3NlZCgpLm5leHQoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogSGlkZXMgYWxsIG9mIHRoZSBjb250ZW50IHRoYXQgaXNuJ3QgYW4gb3ZlcmxheSBmcm9tIGFzc2lzdGl2ZSB0ZWNobm9sb2d5LlxuICAgKi9cbiAgcHJpdmF0ZSBfaGlkZU5vbkRpYWxvZ0NvbnRlbnRGcm9tQXNzaXN0aXZlVGVjaG5vbG9neSgpIHtcbiAgICBjb25zdCBvdmVybGF5Q29udGFpbmVyID0gdGhpcy5fb3ZlcmxheUNvbnRhaW5lci5nZXRDb250YWluZXJFbGVtZW50KCk7XG5cbiAgICAvLyBFbnN1cmUgdGhhdCB0aGUgb3ZlcmxheSBjb250YWluZXIgaXMgYXR0YWNoZWQgdG8gdGhlIERPTS5cbiAgICBpZiAob3ZlcmxheUNvbnRhaW5lci5wYXJlbnRFbGVtZW50KSB7XG4gICAgICBjb25zdCBzaWJsaW5ncyA9IG92ZXJsYXlDb250YWluZXIucGFyZW50RWxlbWVudC5jaGlsZHJlbjtcblxuICAgICAgZm9yIChsZXQgaSA9IHNpYmxpbmdzLmxlbmd0aCAtIDE7IGkgPiAtMTsgaS0tKSB7XG4gICAgICAgIGxldCBzaWJsaW5nID0gc2libGluZ3NbaV07XG5cbiAgICAgICAgaWYgKHNpYmxpbmcgIT09IG92ZXJsYXlDb250YWluZXIgJiZcbiAgICAgICAgICBzaWJsaW5nLm5vZGVOYW1lICE9PSAnU0NSSVBUJyAmJlxuICAgICAgICAgIHNpYmxpbmcubm9kZU5hbWUgIT09ICdTVFlMRScgJiZcbiAgICAgICAgICAhc2libGluZy5oYXNBdHRyaWJ1dGUoJ2FyaWEtbGl2ZScpKSB7XG5cbiAgICAgICAgICB0aGlzLl9hcmlhSGlkZGVuRWxlbWVudHMuc2V0KHNpYmxpbmcsIHNpYmxpbmcuZ2V0QXR0cmlidXRlKCdhcmlhLWhpZGRlbicpKTtcbiAgICAgICAgICBzaWJsaW5nLnNldEF0dHJpYnV0ZSgnYXJpYS1oaWRkZW4nLCAndHJ1ZScpO1xuICAgICAgICB9XG4gICAgICB9XG4gICAgfVxuICB9XG5cbiAgLyoqIENsb3NlcyBhbGwgb2YgdGhlIGRpYWxvZ3MgaW4gYW4gYXJyYXkuICovXG4gIHByaXZhdGUgX2Nsb3NlRGlhbG9ncyhkaWFsb2dzOiBNYXREaWFsb2dSZWY8YW55PltdKSB7XG4gICAgbGV0IGkgPSBkaWFsb2dzLmxlbmd0aDtcblxuICAgIHdoaWxlIChpLS0pIHtcbiAgICAgIC8vIFRoZSBgX29wZW5EaWFsb2dzYCBwcm9wZXJ0eSBpc24ndCB1cGRhdGVkIGFmdGVyIGNsb3NlIHVudGlsIHRoZSByeGpzIHN1YnNjcmlwdGlvblxuICAgICAgLy8gcnVucyBvbiB0aGUgbmV4dCBtaWNyb3Rhc2ssIGluIGFkZGl0aW9uIHRvIG1vZGlmeWluZyB0aGUgYXJyYXkgYXMgd2UncmUgZ29pbmdcbiAgICAgIC8vIHRocm91Z2ggaXQuIFdlIGxvb3AgdGhyb3VnaCBhbGwgb2YgdGhlbSBhbmQgY2FsbCBjbG9zZSB3aXRob3V0IGFzc3VtaW5nIHRoYXRcbiAgICAgIC8vIHRoZXknbGwgYmUgcmVtb3ZlZCBmcm9tIHRoZSBsaXN0IGluc3RhbnRhbmVvdXNseS5cbiAgICAgIGRpYWxvZ3NbaV0uY2xvc2UoKTtcbiAgICB9XG4gIH1cblxufVxuXG4vKipcbiAqIFNlcnZpY2UgdG8gb3BlbiBNYXRlcmlhbCBEZXNpZ24gbW9kYWwgZGlhbG9ncy5cbiAqL1xuQEluamVjdGFibGUoKVxuZXhwb3J0IGNsYXNzIE1hdERpYWxvZyBleHRlbmRzIF9NYXREaWFsb2dCYXNlPE1hdERpYWxvZ0NvbnRhaW5lcj4ge1xuICBjb25zdHJ1Y3RvcihcbiAgICAgIG92ZXJsYXk6IE92ZXJsYXksXG4gICAgICBpbmplY3RvcjogSW5qZWN0b3IsXG4gICAgICAvKipcbiAgICAgICAqIEBkZXByZWNhdGVkIGBfbG9jYXRpb25gIHBhcmFtZXRlciB0byBiZSByZW1vdmVkLlxuICAgICAgICogQGJyZWFraW5nLWNoYW5nZSAxMC4wLjBcbiAgICAgICAqL1xuICAgICAgQE9wdGlvbmFsKCkgbG9jYXRpb246IExvY2F0aW9uLFxuICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChNQVRfRElBTE9HX0RFRkFVTFRfT1BUSU9OUykgZGVmYXVsdE9wdGlvbnM6IE1hdERpYWxvZ0NvbmZpZyxcbiAgICAgIEBJbmplY3QoTUFUX0RJQUxPR19TQ1JPTExfU1RSQVRFR1kpIHNjcm9sbFN0cmF0ZWd5OiBhbnksXG4gICAgICBAT3B0aW9uYWwoKSBAU2tpcFNlbGYoKSBwYXJlbnREaWFsb2c6IE1hdERpYWxvZyxcbiAgICAgIG92ZXJsYXlDb250YWluZXI6IE92ZXJsYXlDb250YWluZXIpIHtcbiAgICBzdXBlcihvdmVybGF5LCBpbmplY3RvciwgZGVmYXVsdE9wdGlvbnMsIHBhcmVudERpYWxvZywgb3ZlcmxheUNvbnRhaW5lciwgc2Nyb2xsU3RyYXRlZ3ksXG4gICAgICAgIE1hdERpYWxvZ1JlZiwgTWF0RGlhbG9nQ29udGFpbmVyLCBNQVRfRElBTE9HX0RBVEEpO1xuICB9XG59XG5cbi8qKlxuICogQXBwbGllcyBkZWZhdWx0IG9wdGlvbnMgdG8gdGhlIGRpYWxvZyBjb25maWcuXG4gKiBAcGFyYW0gY29uZmlnIENvbmZpZyB0byBiZSBtb2RpZmllZC5cbiAqIEBwYXJhbSBkZWZhdWx0T3B0aW9ucyBEZWZhdWx0IG9wdGlvbnMgcHJvdmlkZWQuXG4gKiBAcmV0dXJucyBUaGUgbmV3IGNvbmZpZ3VyYXRpb24gb2JqZWN0LlxuICovXG5mdW5jdGlvbiBfYXBwbHlDb25maWdEZWZhdWx0cyhcbiAgICBjb25maWc/OiBNYXREaWFsb2dDb25maWcsIGRlZmF1bHRPcHRpb25zPzogTWF0RGlhbG9nQ29uZmlnKTogTWF0RGlhbG9nQ29uZmlnIHtcbiAgcmV0dXJuIHsuLi5kZWZhdWx0T3B0aW9ucywgLi4uY29uZmlnfTtcbn1cbiJdfQ==
|