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

/**
* @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==