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.
 
 
 
 

236 lines
34 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 { Component, ViewChild, ElementRef, ChangeDetectionStrategy, ViewEncapsulation, ChangeDetectorRef, EventEmitter, Inject, Optional, } from '@angular/core';
import { BasePortalOutlet, CdkPortalOutlet, } from '@angular/cdk/portal';
import { BreakpointObserver, Breakpoints } from '@angular/cdk/layout';
import { MatBottomSheetConfig } from './bottom-sheet-config';
import { matBottomSheetAnimations } from './bottom-sheet-animations';
import { DOCUMENT } from '@angular/common';
import { FocusTrapFactory } from '@angular/cdk/a11y';
import { _getFocusedElementPierceShadowDom } from '@angular/cdk/platform';
// TODO(crisbeto): consolidate some logic between this, MatDialog and MatSnackBar
/**
* Internal component that wraps user-provided bottom sheet content.
* @docs-private
*/
import * as ɵngcc0 from '@angular/core';
import * as ɵngcc1 from '@angular/cdk/a11y';
import * as ɵngcc2 from '@angular/cdk/layout';
import * as ɵngcc3 from './bottom-sheet-config';
import * as ɵngcc4 from '@angular/cdk/portal';
function MatBottomSheetContainer_ng_template_0_Template(rf, ctx) { }
export class MatBottomSheetContainer extends BasePortalOutlet {
constructor(_elementRef, _changeDetectorRef, _focusTrapFactory, breakpointObserver, document,
/** The bottom sheet configuration. */
bottomSheetConfig) {
super();
this._elementRef = _elementRef;
this._changeDetectorRef = _changeDetectorRef;
this._focusTrapFactory = _focusTrapFactory;
this.bottomSheetConfig = bottomSheetConfig;
/** The state of the bottom sheet animations. */
this._animationState = 'void';
/** Emits whenever the state of the animation changes. */
this._animationStateChanged = new EventEmitter();
/** Element that was focused before the bottom sheet was opened. */
this._elementFocusedBeforeOpened = null;
/**
* Attaches a DOM portal to the bottom sheet container.
* @deprecated To be turned into a method.
* @breaking-change 10.0.0
*/
this.attachDomPortal = (portal) => {
this._validatePortalAttached();
this._setPanelClass();
this._savePreviouslyFocusedElement();
return this._portalOutlet.attachDomPortal(portal);
};
this._document = document;
this._breakpointSubscription = breakpointObserver
.observe([Breakpoints.Medium, Breakpoints.Large, Breakpoints.XLarge])
.subscribe(() => {
this._toggleClass('mat-bottom-sheet-container-medium', breakpointObserver.isMatched(Breakpoints.Medium));
this._toggleClass('mat-bottom-sheet-container-large', breakpointObserver.isMatched(Breakpoints.Large));
this._toggleClass('mat-bottom-sheet-container-xlarge', breakpointObserver.isMatched(Breakpoints.XLarge));
});
}
/** Attach a component portal as content to this bottom sheet container. */
attachComponentPortal(portal) {
this._validatePortalAttached();
this._setPanelClass();
this._savePreviouslyFocusedElement();
return this._portalOutlet.attachComponentPortal(portal);
}
/** Attach a template portal as content to this bottom sheet container. */
attachTemplatePortal(portal) {
this._validatePortalAttached();
this._setPanelClass();
this._savePreviouslyFocusedElement();
return this._portalOutlet.attachTemplatePortal(portal);
}
/** Begin animation of bottom sheet entrance into view. */
enter() {
if (!this._destroyed) {
this._animationState = 'visible';
this._changeDetectorRef.detectChanges();
}
}
/** Begin animation of the bottom sheet exiting from view. */
exit() {
if (!this._destroyed) {
this._animationState = 'hidden';
this._changeDetectorRef.markForCheck();
}
}
ngOnDestroy() {
this._breakpointSubscription.unsubscribe();
this._destroyed = true;
}
_onAnimationDone(event) {
if (event.toState === 'hidden') {
this._restoreFocus();
}
else if (event.toState === 'visible') {
this._trapFocus();
}
this._animationStateChanged.emit(event);
}
_onAnimationStart(event) {
this._animationStateChanged.emit(event);
}
_toggleClass(cssClass, add) {
const classList = this._elementRef.nativeElement.classList;
add ? classList.add(cssClass) : classList.remove(cssClass);
}
_validatePortalAttached() {
if (this._portalOutlet.hasAttached() && (typeof ngDevMode === 'undefined' || ngDevMode)) {
throw Error('Attempting to attach bottom sheet content after content is already attached');
}
}
_setPanelClass() {
const element = this._elementRef.nativeElement;
const panelClass = this.bottomSheetConfig.panelClass;
if (Array.isArray(panelClass)) {
// Note that we can't use a spread here, because IE doesn't support multiple arguments.
panelClass.forEach(cssClass => element.classList.add(cssClass));
}
else if (panelClass) {
element.classList.add(panelClass);
}
}
/** Moves the focus inside the focus trap. */
_trapFocus() {
const element = this._elementRef.nativeElement;
if (!this._focusTrap) {
this._focusTrap = this._focusTrapFactory.create(element);
}
if (this.bottomSheetConfig.autoFocus) {
this._focusTrap.focusInitialElementWhenReady();
}
else {
const activeElement = _getFocusedElementPierceShadowDom();
// Otherwise ensure that focus is on the container. It's possible that a different
// component tried to move focus while the open animation was running. See:
// https://github.com/angular/components/issues/16215. Note that we only want to do this
// if the focus isn't inside the bottom sheet already, because it's possible that the
// consumer turned off `autoFocus` in order to move focus themselves.
if (activeElement !== element && !element.contains(activeElement)) {
element.focus();
}
}
}
/** Restores focus to the element that was focused before the bottom sheet was opened. */
_restoreFocus() {
const toFocus = this._elementFocusedBeforeOpened;
// We need the extra check, because IE can set the `activeElement` to null in some cases.
if (this.bottomSheetConfig.restoreFocus && toFocus && typeof toFocus.focus === 'function') {
const activeElement = _getFocusedElementPierceShadowDom();
const element = this._elementRef.nativeElement;
// Make sure that focus is still inside the bottom sheet or is on the body (usually because a
// non-focusable element like the backdrop was clicked) before moving it. It's possible that
// the consumer moved it themselves before the animation was done, in which case we shouldn't
// do anything.
if (!activeElement || activeElement === this._document.body || activeElement === element ||
element.contains(activeElement)) {
toFocus.focus();
}
}
if (this._focusTrap) {
this._focusTrap.destroy();
}
}
/** Saves a reference to the element that was focused before the bottom sheet was opened. */
_savePreviouslyFocusedElement() {
this._elementFocusedBeforeOpened = _getFocusedElementPierceShadowDom();
// The `focus` method isn't available during server-side rendering.
if (this._elementRef.nativeElement.focus) {
Promise.resolve().then(() => this._elementRef.nativeElement.focus());
}
}
}
MatBottomSheetContainer.ɵfac = function MatBottomSheetContainer_Factory(t) { return new (t || MatBottomSheetContainer)(ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ElementRef), ɵngcc0.ɵɵdirectiveInject(ɵngcc0.ChangeDetectorRef), ɵngcc0.ɵɵdirectiveInject(ɵngcc1.FocusTrapFactory), ɵngcc0.ɵɵdirectiveInject(ɵngcc2.BreakpointObserver), ɵngcc0.ɵɵdirectiveInject(DOCUMENT, 8), ɵngcc0.ɵɵdirectiveInject(ɵngcc3.MatBottomSheetConfig)); };
MatBottomSheetContainer.ɵcmp = /*@__PURE__*/ ɵngcc0.ɵɵdefineComponent({ type: MatBottomSheetContainer, selectors: [["mat-bottom-sheet-container"]], viewQuery: function MatBottomSheetContainer_Query(rf, ctx) { if (rf & 1) {
ɵngcc0.ɵɵviewQuery(CdkPortalOutlet, 7);
} if (rf & 2) {
let _t;
ɵngcc0.ɵɵqueryRefresh(_t = ɵngcc0.ɵɵloadQuery()) && (ctx._portalOutlet = _t.first);
} }, hostAttrs: ["tabindex", "-1", "role", "dialog", "aria-modal", "true", 1, "mat-bottom-sheet-container"], hostVars: 2, hostBindings: function MatBottomSheetContainer_HostBindings(rf, ctx) { if (rf & 1) {
ɵngcc0.ɵɵsyntheticHostListener("@state.start", function MatBottomSheetContainer_animation_state_start_HostBindingHandler($event) { return ctx._onAnimationStart($event); })("@state.done", function MatBottomSheetContainer_animation_state_done_HostBindingHandler($event) { return ctx._onAnimationDone($event); });
} if (rf & 2) {
ɵngcc0.ɵɵattribute("aria-label", ctx.bottomSheetConfig == null ? null : ctx.bottomSheetConfig.ariaLabel);
ɵngcc0.ɵɵsyntheticHostProperty("@state", ctx._animationState);
} }, features: [ɵngcc0.ɵɵInheritDefinitionFeature], decls: 1, vars: 0, consts: [["cdkPortalOutlet", ""]], template: function MatBottomSheetContainer_Template(rf, ctx) { if (rf & 1) {
ɵngcc0.ɵɵtemplate(0, MatBottomSheetContainer_ng_template_0_Template, 0, 0, "ng-template", 0);
} }, directives: [ɵngcc4.CdkPortalOutlet], styles: [".mat-bottom-sheet-container{padding:8px 16px;min-width:100vw;box-sizing:border-box;display:block;outline:0;max-height:80vh;overflow:auto}.cdk-high-contrast-active .mat-bottom-sheet-container{outline:1px solid}.mat-bottom-sheet-container-xlarge,.mat-bottom-sheet-container-large,.mat-bottom-sheet-container-medium{border-top-left-radius:4px;border-top-right-radius:4px}.mat-bottom-sheet-container-medium{min-width:384px;max-width:calc(100vw - 128px)}.mat-bottom-sheet-container-large{min-width:512px;max-width:calc(100vw - 256px)}.mat-bottom-sheet-container-xlarge{min-width:576px;max-width:calc(100vw - 384px)}\n"], encapsulation: 2, data: { animation: [matBottomSheetAnimations.bottomSheetState] } });
MatBottomSheetContainer.ctorParameters = () => [
{ type: ElementRef },
{ type: ChangeDetectorRef },
{ type: FocusTrapFactory },
{ type: BreakpointObserver },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [DOCUMENT,] }] },
{ type: MatBottomSheetConfig }
];
MatBottomSheetContainer.propDecorators = {
_portalOutlet: [{ type: ViewChild, args: [CdkPortalOutlet, { static: true },] }]
};
(function () { (typeof ngDevMode === "undefined" || ngDevMode) && ɵngcc0.ɵsetClassMetadata(MatBottomSheetContainer, [{
type: Component,
args: [{
selector: 'mat-bottom-sheet-container',
template: "<ng-template cdkPortalOutlet></ng-template>\r\n",
// In Ivy embedded views will be change detected from their declaration place, rather than where
// they were stamped out. This means that we can't have the bottom sheet container be OnPush,
// because it might cause the sheets that were opened from a template not to be out of date.
// tslint:disable-next-line:validate-decorators
changeDetection: ChangeDetectionStrategy.Default,
encapsulation: ViewEncapsulation.None,
animations: [matBottomSheetAnimations.bottomSheetState],
host: {
'class': 'mat-bottom-sheet-container',
'tabindex': '-1',
'role': 'dialog',
'aria-modal': 'true',
'[attr.aria-label]': 'bottomSheetConfig?.ariaLabel',
'[@state]': '_animationState',
'(@state.start)': '_onAnimationStart($event)',
'(@state.done)': '_onAnimationDone($event)'
},
styles: [".mat-bottom-sheet-container{padding:8px 16px;min-width:100vw;box-sizing:border-box;display:block;outline:0;max-height:80vh;overflow:auto}.cdk-high-contrast-active .mat-bottom-sheet-container{outline:1px solid}.mat-bottom-sheet-container-xlarge,.mat-bottom-sheet-container-large,.mat-bottom-sheet-container-medium{border-top-left-radius:4px;border-top-right-radius:4px}.mat-bottom-sheet-container-medium{min-width:384px;max-width:calc(100vw - 128px)}.mat-bottom-sheet-container-large{min-width:512px;max-width:calc(100vw - 256px)}.mat-bottom-sheet-container-xlarge{min-width:576px;max-width:calc(100vw - 384px)}\n"]
}]
}], function () { return [{ type: ɵngcc0.ElementRef }, { type: ɵngcc0.ChangeDetectorRef }, { type: ɵngcc1.FocusTrapFactory }, { type: ɵngcc2.BreakpointObserver }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }, { type: ɵngcc3.MatBottomSheetConfig }]; }, { _portalOutlet: [{
type: ViewChild,
args: [CdkPortalOutlet, { static: true }]
}] }); })();
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiYm90dG9tLXNoZWV0LWNvbnRhaW5lci5qcyIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vc3JjL21hdGVyaWFsL2JvdHRvbS1zaGVldC9ib3R0b20tc2hlZXQtY29udGFpbmVyLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBO0FBQ0E7QUFDQTtBQUNBO0FBQ0E7QUFDQTtBQUNBLEdBQUc7QUFFSCxPQUFPLEVBQ0wsU0FBUyxFQUdULFNBQVMsRUFFVCxVQUFVLEVBQ1YsdUJBQXVCLEVBQ3ZCLGlCQUFpQixFQUNqQixpQkFBaUIsRUFDakIsWUFBWSxFQUNaLE1BQU0sRUFDTixRQUFRLEdBQ1QsTUFBTSxlQUFlLENBQUM7QUFFdkIsT0FBTyxFQUNMLGdCQUFnQixFQUdoQixlQUFlLEdBRWhCLE1BQU0scUJBQXFCLENBQUM7QUFDN0IsT0FBTyxFQUFDLGtCQUFrQixFQUFFLFdBQVcsRUFBQyxNQUFNLHFCQUFxQixDQUFDO0FBQ3BFLE9BQU8sRUFBQyxvQkFBb0IsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQzNELE9BQU8sRUFBQyx3QkFBd0IsRUFBQyxNQUFNLDJCQUEyQixDQUFDO0FBRW5FLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSxpQkFBaUIsQ0FBQztBQUN6QyxPQUFPLEVBQVksZ0JBQWdCLEVBQUMsTUFBTSxtQkFBbUIsQ0FBQztBQUM5RCxPQUFPLEVBQUMsaUNBQWlDLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUV4RSxpRkFBaUY7QUFFakY7QUFDQTtBQUNBO0FBQ0EsR0FBRzs7Ozs7Ozs7QUF1QkgsTUFBTSxPQUFPLHVCQUF3QixTQUFRLGdCQUFnQjtBQUFHLElBd0I5RCxZQUNVLFdBQW9DLEVBQ3BDLGtCQUFxQyxFQUNyQyxpQkFBbUMsRUFDM0Msa0JBQXNDLEVBQ1IsUUFBYTtBQUM5QyxJQUFHLHNDQUFzQztBQUMxQyxJQUFXLGlCQUF1QztBQUNsRCxRQUFJLEtBQUssRUFBRSxDQUFDO0FBQ1osUUFSWSxnQkFBVyxHQUFYLFdBQVcs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LE1BQU0sU0FBQyxRQUFRO0FBQVMsWUFoRWpDLG9CQUFvQjtBQUFHO0FBQUc7QUFDakIsNEJBc0NkLFNBQVMsU0FBQyxlQUFlLEVBQUUsRUFBQyxNQUFNLEVBQUUsSUFBSSxFQUFDO0FBQU07Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztvQkFBRTtBQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7XG4gIENvbXBvbmVudCxcbiAgQ29tcG9uZW50UmVmLFxuICBFbWJlZGRlZFZpZXdSZWYsXG4gIFZpZXdDaGlsZCxcbiAgT25EZXN0cm95LFxuICBFbGVtZW50UmVmLFxuICBDaGFuZ2VEZXRlY3Rpb25TdHJhdGVneSxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG4gIENoYW5nZURldGVjdG9yUmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEluamVjdCxcbiAgT3B0aW9uYWwsXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHtBbmltYXRpb25FdmVudH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQge1xuICBCYXNlUG9ydGFsT3V0bGV0LFxuICBDb21wb25lbnRQb3J0YWwsXG4gIFRlbXBsYXRlUG9ydGFsLFxuICBDZGtQb3J0YWxPdXRsZXQsXG4gIERvbVBvcnRhbCxcbn0gZnJvbSAnQGFuZ3VsYXIvY2RrL3BvcnRhbCc7XG5pbXBvcnQge0JyZWFrcG9pbnRPYnNlcnZlciwgQnJlYWtwb2ludHN9IGZyb20gJ0Bhbmd1bGFyL2Nkay9sYXlvdXQnO1xuaW1wb3J0IHtNYXRCb3R0b21TaGVldENvbmZpZ30gZnJvbSAnLi9ib3R0b20tc2hlZXQtY29uZmlnJztcbmltcG9ydCB7bWF0Qm90dG9tU2hlZXRBbmltYXRpb25zfSBmcm9tICcuL2JvdHRvbS1zaGVldC1hbmltYXRpb25zJztcbmltcG9ydCB7U3Vic2NyaXB0aW9ufSBmcm9tICdyeGpzJztcbmltcG9ydCB7RE9DVU1FTlR9IGZyb20gJ0Bhbmd1bGFyL2NvbW1vbic7XG5pbXBvcnQge0ZvY3VzVHJhcCwgRm9jdXNUcmFwRmFjdG9yeX0gZnJvbSAnQGFuZ3VsYXIvY2RrL2ExMXknO1xuaW1wb3J0IHtfZ2V0Rm9jdXNlZEVsZW1lbnRQaWVyY2VTaGFkb3dEb219IGZyb20gJ0Bhbmd1bGFyL2Nkay9wbGF0Zm9ybSc7XG5cbi8vIFRPRE8oY3Jpc2JldG8pOiBjb25zb2xpZGF0ZSBzb21lIGxvZ2ljIGJldHdlZW4gdGhpcywgTWF0RGlhbG9nIGFuZCBNYXRTbmFja0JhclxuXG4vKipcbiAqIEludGVybmFsIGNvbXBvbmVudCB0aGF0IHdyYXBzIHVzZXItcHJvdmlkZWQgYm90dG9tIHNoZWV0IGNvbnRlbnQuXG4gKiBAZG9jcy1wcml2YXRlXG4gKi9cbkBDb21wb25lbnQoe1xuICBzZWxlY3RvcjogJ21hdC1ib3R0b20tc2hlZXQtY29udGFpbmVyJyxcbiAgdGVtcGxhdGVVcmw6ICdib3R0b20tc2hlZXQtY29udGFpbmVyLmh0bWwnLFxuICBzdHlsZVVybHM6IFsnYm90dG9tLXNoZWV0LWNvbnRhaW5lci5jc3MnXSxcbiAgLy8gSW4gSXZ5IGVtYmVkZGVkIHZpZXdzIHdpbGwgYmUgY2hhbmdlIGRldGVjdGVkIGZyb20gdGhlaXIgZGVjbGFyYXRpb24gcGxhY2UsIHJhdGhlciB0aGFuIHdoZXJlXG4gIC8vIHRoZXkgd2VyZSBzdGFtcGVkIG91dC4gVGhpcyBtZWFucyB0aGF0IHdlIGNhbid0IGhhdmUgdGhlIGJvdHRvbSBzaGVldCBjb250YWluZXIgYmUgT25QdXNoLFxuICAvLyBiZWNhdXNlIGl0IG1pZ2h0IGNhdXNlIHRoZSBzaGVldHMgdGhhdCB3ZXJlIG9wZW5lZCBmcm9tIGEgdGVtcGxhdGUgbm90IHRvIGJlIG91dCBvZiBkYXRlLlxuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dmFsaWRhdGUtZGVjb3JhdG9yc1xuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LkRlZmF1bHQsXG4gIGVuY2Fwc3VsYXRpb246IFZpZXdFbmNhcHN1bGF0aW9uLk5vbmUsXG4gIGFuaW1hdGlvbnM6IFttYXRCb3R0b21TaGVldEFuaW1hdGlvbnMuYm90dG9tU2hlZXRTdGF0ZV0sXG4gIGhvc3Q6IHtcbiAgICAnY2xhc3MnOiAnbWF0LWJvdHRvbS1zaGVldC1jb250YWluZXInLFxuICAgICd0YWJpbmRleCc6ICctMScsXG4gICAgJ3JvbGUnOiAnZGlhbG9nJyxcbiAgICAnYXJpYS1tb2RhbCc6ICd0cnVlJyxcbiAgICAnW2F0dHIuYXJpYS1sYWJlbF0nOiAnYm90dG9tU2hlZXRDb25maWc/LmFyaWFMYWJlbCcsXG4gICAgJ1tAc3RhdGVdJzogJ19hbmltYXRpb25TdGF0ZScsXG4gICAgJyhAc3RhdGUuc3RhcnQpJzogJ19vbkFuaW1hdGlvblN0YXJ0KCRldmVudCknLFxuICAgICcoQHN0YXRlLmRvbmUpJzogJ19vbkFuaW1hdGlvbkRvbmUoJGV2ZW50KSdcbiAgfSxcbn0pXG5leHBvcnQgY2xhc3MgTWF0Qm90dG9tU2hlZXRDb250YWluZXIgZXh0ZW5kcyBCYXNlUG9ydGFsT3V0bGV0IGltcGxlbWVudHMgT25EZXN0cm95IHtcbiAgcHJpdmF0ZSBfYnJlYWtwb2ludFN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xuXG4gIC8qKiBUaGUgcG9ydGFsIG91dGxldCBpbnNpZGUgb2YgdGhpcyBjb250YWluZXIgaW50byB3aGljaCB0aGUgY29udGVudCB3aWxsIGJlIGxvYWRlZC4gKi9cbiAgQFZpZXdDaGlsZChDZGtQb3J0YWxPdXRsZXQsIHtzdGF0aWM6IHRydWV9KSBfcG9ydGFsT3V0bGV0OiBDZGtQb3J0YWxPdXRsZXQ7XG5cbiAgLyoqIFRoZSBzdGF0ZSBvZiB0aGUgYm90dG9tIHNoZWV0IGFuaW1hdGlvbnMuICovXG4gIF9hbmltYXRpb25TdGF0ZTogJ3ZvaWQnIHwgJ3Zpc2libGUnIHwgJ2hpZGRlbicgPSAndm9pZCc7XG5cbiAgLyoqIEVtaXRzIHdoZW5ldmVyIHRoZSBzdGF0ZSBvZiB0aGUgYW5pbWF0aW9uIGNoYW5nZXMuICovXG4gIF9hbmltYXRpb25TdGF0ZUNoYW5nZWQgPSBuZXcgRXZlbnRFbWl0dGVyPEFuaW1hdGlvbkV2ZW50PigpO1xuXG4gIC8qKiBUaGUgY2xhc3MgdGhhdCB0cmFwcyBhbmQgbWFuYWdlcyBmb2N1cyB3aXRoaW4gdGhlIGJvdHRvbSBzaGVldC4gKi9cbiAgcHJpdmF0ZSBfZm9jdXNUcmFwOiBGb2N1c1RyYXA7XG5cbiAgLyoqIEVsZW1lbnQgdGhhdCB3YXMgZm9jdXNlZCBiZWZvcmUgdGhlIGJvdHRvbSBzaGVldCB3YXMgb3BlbmVkLiAqL1xuICBwcml2YXRlIF9lbGVtZW50Rm9jdXNlZEJlZm9yZU9wZW5lZDogSFRNTEVsZW1lbnQgfCBudWxsID0gbnVsbDtcblxuICAvKiogU2VydmVyLXNpZGUgcmVuZGVyaW5nLWNvbXBhdGlibGUgcmVmZXJlbmNlIHRvIHRoZSBnbG9iYWwgZG9jdW1lbnQgb2JqZWN0LiAqL1xuICBwcml2YXRlIF9kb2N1bWVudDogRG9jdW1lbnQ7XG5cbiAgLyoqIFdoZXRoZXIgdGhlIGNvbXBvbmVudCBoYXMgYmVlbiBkZXN0cm95ZWQuICovXG4gIHByaXZhdGUgX2Rlc3Ryb3llZDogYm9vbGVhbjtcblxuICBjb25zdHJ1Y3RvcihcbiAgICBwcml2YXRlIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PixcbiAgICBwcml2YXRlIF9jaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgcHJpdmF0ZSBfZm9jdXNUcmFwRmFjdG9yeTogRm9jdXNUcmFwRmFjdG9yeSxcbiAgICBicmVha3BvaW50T2JzZXJ2ZXI6IEJyZWFrcG9pbnRPYnNlcnZlcixcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERPQ1VNRU5UKSBkb2N1bWVudDogYW55LFxuICAgIC8qKiBUaGUgYm90dG9tIHNoZWV0IGNvbmZpZ3VyYXRpb24uICovXG4gICAgcHVibGljIGJvdHRvbVNoZWV0Q29uZmlnOiBNYXRCb3R0b21TaGVldENvbmZpZykge1xuICAgIHN1cGVyKCk7XG5cbiAgICB0aGlzLl9kb2N1bWVudCA9IGRvY3VtZW50O1xuICAgIHRoaXMuX2JyZWFrcG9pbnRTdWJzY3JpcHRpb24gPSBicmVha3BvaW50T2JzZXJ2ZXJcbiAgICAgIC5vYnNlcnZlKFtCcmVha3BvaW50cy5NZWRpdW0sIEJyZWFrcG9pbnRzLkxhcmdlLCBCcmVha3BvaW50cy5YTGFyZ2VdKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuX3RvZ2dsZUNsYXNzKCdtYXQtYm90dG9tLXNoZWV0LWNvbnRhaW5lci1tZWRpdW0nLFxuICAgICAgICAgICAgYnJlYWtwb2ludE9ic2VydmVyLmlzTWF0Y2hlZChCcmVha3BvaW50cy5NZWRpdW0pKTtcbiAgICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3MoJ21hdC1ib3R0b20tc2hlZXQtY29udGFpbmVyLWxhcmdlJyxcbiAgICAgICAgICAgIGJyZWFrcG9pbnRPYnNlcnZlci5pc01hdGNoZWQoQnJlYWtwb2ludHMuTGFyZ2UpKTtcbiAgICAgICAgdGhpcy5fdG9nZ2xlQ2xhc3MoJ21hdC1ib3R0b20tc2hlZXQtY29udGFpbmVyLXhsYXJnZScsXG4gICAgICAgICAgICBicmVha3BvaW50T2JzZXJ2ZXIuaXNNYXRjaGVkKEJyZWFrcG9pbnRzLlhMYXJnZSkpO1xuICAgICAgfSk7XG4gIH1cblxuICAvKiogQXR0YWNoIGEgY29tcG9uZW50IHBvcnRhbCBhcyBjb250ZW50IHRvIHRoaXMgYm90dG9tIHNoZWV0IGNvbnRhaW5lci4gKi9cbiAgYXR0YWNoQ29tcG9uZW50UG9ydGFsPFQ+KHBvcnRhbDogQ29tcG9uZW50UG9ydGFsPFQ+KTogQ29tcG9uZW50UmVmPFQ+IHtcbiAgICB0aGlzLl92YWxpZGF0ZVBvcnRhbEF0dGFjaGVkKCk7XG4gICAgdGhpcy5fc2V0UGFuZWxDbGFzcygpO1xuICAgIHRoaXMuX3NhdmVQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQoKTtcbiAgICByZXR1cm4gdGhpcy5fcG9ydGFsT3V0bGV0LmF0dGFjaENvbXBvbmVudFBvcnRhbChwb3J0YWwpO1xuICB9XG5cbiAgLyoqIEF0dGFjaCBhIHRlbXBsYXRlIHBvcnRhbCBhcyBjb250ZW50IHRvIHRoaXMgYm90dG9tIHNoZWV0IGNvbnRhaW5lci4gKi9cbiAgYXR0YWNoVGVtcGxhdGVQb3J0YWw8Qz4ocG9ydGFsOiBUZW1wbGF0ZVBvcnRhbDxDPik6IEVtYmVkZGVkVmlld1JlZjxDPiB7XG4gICAgdGhpcy5fdmFsaWRhdGVQb3J0YWxBdHRhY2hlZCgpO1xuICAgIHRoaXMuX3NldFBhbmVsQ2xhc3MoKTtcbiAgICB0aGlzLl9zYXZlUHJldmlvdXNseUZvY3VzZWRFbGVtZW50KCk7XG4gICAgcmV0dXJuIHRoaXMuX3BvcnRhbE91dGxldC5hdHRhY2hUZW1wbGF0ZVBvcnRhbChwb3J0YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaGVzIGEgRE9NIHBvcnRhbCB0byB0aGUgYm90dG9tIHNoZWV0IGNvbnRhaW5lci5cbiAgICogQGRlcHJlY2F0ZWQgVG8gYmUgdHVybmVkIGludG8gYSBtZXRob2QuXG4gICAqIEBicmVha2luZy1jaGFuZ2UgMTAuMC4wXG4gICAqL1xuICBvdmVycmlkZSBhdHRhY2hEb21Qb3J0YWwgPSAocG9ydGFsOiBEb21Qb3J0YWwpID0+IHtcbiAgICB0aGlzLl92YWxpZGF0ZVBvcnRhbEF0dGFjaGVkKCk7XG4gICAgdGhpcy5fc2V0UGFuZWxDbGFzcygpO1xuICAgIHRoaXMuX3NhdmVQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQoKTtcbiAgICByZXR1cm4gdGhpcy5fcG9ydGFsT3V0bGV0LmF0dGFjaERvbVBvcnRhbChwb3J0YWwpO1xuICB9XG5cbiAgLyoqIEJlZ2luIGFuaW1hdGlvbiBvZiBib3R0b20gc2hlZXQgZW50cmFuY2UgaW50byB2aWV3LiAqL1xuICBlbnRlcigpOiB2b2lkIHtcbiAgICBpZiAoIXRoaXMuX2Rlc3Ryb3llZCkge1xuICAgICAgdGhpcy5fYW5pbWF0aW9uU3RhdGUgPSAndmlzaWJsZSc7XG4gICAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5kZXRlY3RDaGFuZ2VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEJlZ2luIGFuaW1hdGlvbiBvZiB0aGUgYm90dG9tIHNoZWV0IGV4aXRpbmcgZnJvbSB2aWV3LiAqL1xuICBleGl0KCk6IHZvaWQge1xuICAgIGlmICghdGhpcy5fZGVzdHJveWVkKSB7XG4gICAgICB0aGlzLl9hbmltYXRpb25TdGF0ZSA9ICdoaWRkZW4nO1xuICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgfVxuICB9XG5cbiAgbmdPbkRlc3Ryb3koKSB7XG4gICAgdGhpcy5fYnJlYWtwb2ludFN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xuICAgIHRoaXMuX2Rlc3Ryb3llZCA9IHRydWU7XG4gIH1cblxuICBfb25BbmltYXRpb25Eb25lKGV2ZW50OiBBbmltYXRpb25FdmVudCkge1xuICAgIGlmIChldmVudC50b1N0YXRlID09PSAnaGlkZGVuJykge1xuICAgICAgdGhpcy5fcmVzdG9yZUZvY3VzKCk7XG4gICAgfSBlbHNlIGlmIChldmVudC50b1N0YXRlID09PSAndmlzaWJsZScpIHtcbiAgICAgIHRoaXMuX3RyYXBGb2N1cygpO1xuICAgIH1cblxuICAgIHRoaXMuX2FuaW1hdGlvblN0YXRlQ2hhbmdlZC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIF9vbkFuaW1hdGlvblN0YXJ0KGV2ZW50OiBBbmltYXRpb25FdmVudCkge1xuICAgIHRoaXMuX2FuaW1hdGlvblN0YXRlQ2hhbmdlZC5lbWl0KGV2ZW50KTtcbiAgfVxuXG4gIHByaXZhdGUgX3RvZ2dsZUNsYXNzKGNzc0NsYXNzOiBzdHJpbmcsIGFkZDogYm9vbGVhbikge1xuICAgIGNvbnN0IGNsYXNzTGlzdCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5jbGFzc0xpc3Q7XG4gICAgYWRkID8gY2xhc3NMaXN0LmFkZChjc3NDbGFzcykgOiBjbGFzc0xpc3QucmVtb3ZlKGNzc0NsYXNzKTtcbiAgfVxuXG4gIHByaXZhdGUgX3ZhbGlkYXRlUG9ydGFsQXR0YWNoZWQoKSB7XG4gICAgaWYgKHRoaXMuX3BvcnRhbE91dGxldC5oYXNBdHRhY2hlZCgpICYmICh0eXBlb2YgbmdEZXZNb2RlID09PSAndW5kZWZpbmVkJyB8fCBuZ0Rldk1vZGUpKSB7XG4gICAgICB0aHJvdyBFcnJvcignQXR0ZW1wdGluZyB0byBhdHRhY2ggYm90dG9tIHNoZWV0IGNvbnRlbnQgYWZ0ZXIgY29udGVudCBpcyBhbHJlYWR5IGF0dGFjaGVkJyk7XG4gICAgfVxuICB9XG5cbiAgcHJpdmF0ZSBfc2V0UGFuZWxDbGFzcygpIHtcbiAgICBjb25zdCBlbGVtZW50OiBIVE1MRWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBwYW5lbENsYXNzID0gdGhpcy5ib3R0b21TaGVldENvbmZpZy5wYW5lbENsYXNzO1xuXG4gICAgaWYgKEFycmF5LmlzQXJyYXkocGFuZWxDbGFzcykpIHtcbiAgICAgIC8vIE5vdGUgdGhhdCB3ZSBjYW4ndCB1c2UgYSBzcHJlYWQgaGVyZSwgYmVjYXVzZSBJRSBkb2Vzbid0IHN1cHBvcnQgbXVsdGlwbGUgYXJndW1lbnRzLlxuICAgICAgcGFuZWxDbGFzcy5mb3JFYWNoKGNzc0NsYXNzID0+IGVsZW1lbnQuY2xhc3NMaXN0LmFkZChjc3NDbGFzcykpO1xuICAgIH0gZWxzZSBpZiAocGFuZWxDbGFzcykge1xuICAgICAgZWxlbWVudC5jbGFzc0xpc3QuYWRkKHBhbmVsQ2xhc3MpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBNb3ZlcyB0aGUgZm9jdXMgaW5zaWRlIHRoZSBmb2N1cyB0cmFwLiAqL1xuICBwcml2YXRlIF90cmFwRm9jdXMoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblxuICAgIGlmICghdGhpcy5fZm9jdXNUcmFwKSB7XG4gICAgICB0aGlzLl9mb2N1c1RyYXAgPSB0aGlzLl9mb2N1c1RyYXBGYWN0b3J5LmNyZWF0ZShlbGVtZW50KTtcbiAgICB9XG5cbiAgICBpZiAodGhpcy5ib3R0b21TaGVldENvbmZpZy5hdXRvRm9jdXMpIHtcbiAgICAgIHRoaXMuX2ZvY3VzVHJhcC5mb2N1c0luaXRpYWxFbGVtZW50V2hlblJlYWR5KCk7XG4gICAgfSBlbHNlIHtcbiAgICAgIGNvbnN0IGFjdGl2ZUVsZW1lbnQgPSBfZ2V0Rm9jdXNlZEVsZW1lbnRQaWVyY2VTaGFkb3dEb20oKTtcblxuICAgICAgLy8gT3RoZXJ3aXNlIGVuc3VyZSB0aGF0IGZvY3VzIGlzIG9uIHRoZSBjb250YWluZXIuIEl0J3MgcG9zc2libGUgdGhhdCBhIGRpZmZlcmVudFxuICAgICAgLy8gY29tcG9uZW50IHRyaWVkIHRvIG1vdmUgZm9jdXMgd2hpbGUgdGhlIG9wZW4gYW5pbWF0aW9uIHdhcyBydW5uaW5nLiBTZWU6XG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vYW5ndWxhci9jb21wb25lbnRzL2lzc3Vlcy8xNjIxNS4gTm90ZSB0aGF0IHdlIG9ubHkgd2FudCB0byBkbyB0aGlzXG4gICAgICAvLyBpZiB0aGUgZm9jdXMgaXNuJ3QgaW5zaWRlIHRoZSBib3R0b20gc2hlZXQgYWxyZWFkeSwgYmVjYXVzZSBpdCdzIHBvc3NpYmxlIHRoYXQgdGhlXG4gICAgICAvLyBjb25zdW1lciB0dXJuZWQgb2ZmIGBhdXRvRm9jdXNgIGluIG9yZGVyIHRvIG1vdmUgZm9jdXMgdGhlbXNlbHZlcy5cbiAgICAgIGlmIChhY3RpdmVFbGVtZW50ICE9PSBlbGVtZW50ICYmICFlbGVtZW50LmNvbnRhaW5zKGFjdGl2ZUVsZW1lbnQpKSB7XG4gICAgICAgIGVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9XG4gIH1cblxuICAvKiogUmVzdG9yZXMgZm9jdXMgdG8gdGhlIGVsZW1lbnQgdGhhdCB3YXMgZm9jdXNlZCBiZWZvcmUgdGhlIGJvdHRvbSBzaGVldCB3YXMgb3BlbmVkLiAqL1xuICBwcml2YXRlIF9yZXN0b3JlRm9jdXMoKSB7XG4gICAgY29uc3QgdG9Gb2N1cyA9IHRoaXMuX2VsZW1lbnRGb2N1c2VkQmVmb3JlT3BlbmVkO1xuXG4gICAgLy8gV2UgbmVlZCB0aGUgZXh0cmEgY2hlY2ssIGJlY2F1c2UgSUUgY2FuIHNldCB0aGUgYGFjdGl2ZUVsZW1lbnRgIHRvIG51bGwgaW4gc29tZSBjYXNlcy5cbiAgICBpZiAodGhpcy5ib3R0b21TaGVldENvbmZpZy5yZXN0b3JlRm9jdXMgJiYgdG9Gb2N1cyAmJiB0eXBlb2YgdG9Gb2N1cy5mb2N1cyA9PT0gJ2Z1bmN0aW9uJykge1xuICAgICAgY29uc3QgYWN0aXZlRWxlbWVudCA9IF9nZXRGb2N1c2VkRWxlbWVudFBpZXJjZVNoYWRvd0RvbSgpO1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblxuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgZm9jdXMgaXMgc3RpbGwgaW5zaWRlIHRoZSBib3R0b20gc2hlZXQgb3IgaXMgb24gdGhlIGJvZHkgKHVzdWFsbHkgYmVjYXVzZSBhXG4gICAgICAvLyBub24tZm9jdXNhYmxlIGVsZW1lbnQgbGlrZSB0aGUgYmFja2Ryb3Agd2FzIGNsaWNrZWQpIGJlZm9yZSBtb3ZpbmcgaXQuIEl0J3MgcG9zc2libGUgdGhhdFxuICAgICAgLy8gdGhlIGNvbnN1bWVyIG1vdmVkIGl0IHRoZW1zZWx2ZXMgYmVmb3JlIHRoZSBhbmltYXRpb24gd2FzIGRvbmUsIGluIHdoaWNoIGNhc2Ugd2Ugc2hvdWxkbid0XG4gICAgICAvLyBkbyBhbnl0aGluZy5cbiAgICAgIGlmICghYWN0aXZlRWxlbWVudCB8fCBhY3RpdmVFbGVtZW50ID09PSB0aGlzLl9kb2N1bWVudC5ib2R5IHx8IGFjdGl2ZUVsZW1lbnQgPT09IGVsZW1lbnQgfHxcbiAgICAgICAgZWxlbWVudC5jb250YWlucyhhY3RpdmVFbGVtZW50KSkge1xuICAgICAgICB0b0ZvY3VzLmZvY3VzKCk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgaWYgKHRoaXMuX2ZvY3VzVHJhcCkge1xuICAgICAgdGhpcy5fZm9jdXNUcmFwLmRlc3Ryb3koKTtcbiAgICB9XG4gIH1cblxuICAvKiogU2F2ZXMgYSByZWZlcmVuY2UgdG8gdGhlIGVsZW1lbnQgdGhhdCB3YXMgZm9jdXNlZCBiZWZvcmUgdGhlIGJvdHRvbSBzaGVldCB3YXMgb3BlbmVkLiAqL1xuICBwcml2YXRlIF9zYXZlUHJldmlvdXNseUZvY3VzZWRFbGVtZW50KCkge1xuICAgIHRoaXMuX2VsZW1lbnRGb2N1c2VkQmVmb3JlT3BlbmVkID0gX2dldEZvY3VzZWRFbGVtZW50UGllcmNlU2hhZG93RG9tKCk7XG5cbiAgICAvLyBUaGUgYGZvY3VzYCBtZXRob2QgaXNuJ3QgYXZhaWxhYmxlIGR1cmluZyBzZXJ2ZXItc2lkZSByZW5kZXJpbmcuXG4gICAgaWYgKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cykge1xuICAgICAgUHJvbWlzZS5yZXNvbHZlKCkudGhlbigoKSA9PiB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuZm9jdXMoKSk7XG4gICAgfVxuICB9XG59XG4iXX0=