@covalent/core
Version:
Core Teradata UI Platform for layouts, icons, custom components and themes. This should be added as a dependency for any project that wants to use layouts, icons and themes for Angular Material.
285 lines • 38.5 kB
JavaScript
import { ConfigurableFocusTrapFactory, FocusMonitor, } from '@angular/cdk/a11y';
import { BasePortalOutlet, CdkPortalOutlet, } from '@angular/cdk/portal';
import { DOCUMENT } from '@angular/common';
import { ChangeDetectionStrategy, ChangeDetectorRef, Component, Directive, ElementRef, EventEmitter, HostBinding, HostListener, Inject, Optional, ViewChild, ViewEncapsulation, } from '@angular/core';
import { tdSideSheetAnimations } from './side-sheet.animation';
import { CovalentSideSheetConfig } from './side-sheet.config';
import * as i0 from "@angular/core";
import * as i1 from "@angular/cdk/a11y";
import * as i2 from "./side-sheet.config";
import * as i3 from "@angular/cdk/portal";
export function _getFocusedElementPierceShadowDom() {
let activeElement = typeof document !== 'undefined' && document
? document.activeElement
: null;
while (activeElement && activeElement.shadowRoot) {
const newActiveElement = activeElement.shadowRoot
.activeElement;
if (newActiveElement === activeElement) {
break;
}
else {
activeElement = newActiveElement;
}
}
return activeElement;
}
/**
* Base class for the `CovalentSideSheetContainer`. The base class does not implement
* animations as these are left to implementers of the side-sheet container.
*/
export class _CovalentSideSheetContainerBase extends BasePortalOutlet {
_elementRef;
_focusTrapFactory;
_changeDetectorRef;
_config;
_focusMonitor;
_document;
/** The portal outlet inside of this container into which the side-sheet content will be loaded. */
_portalOutlet;
/** The class that traps and manages focus within the side-sheet. */
_focusTrap;
/** Emits when an animation state changes. */
_animationStateChanged = new EventEmitter();
/** Element that was focused before the side-sheet was opened. Save this to restore upon close. */
_elementFocusedBeforeSideSheetWasOpened = null;
/**
* Type of interaction that led to the side-sheet being closed. This is used to determine
* whether the focus style will be applied when returning focus to its original location
* after the side-sheet is closed.
*/
_closeInteractionType = null;
/** ID of the element that should be considered as the side-sheet's label. */
_ariaLabelledBy;
/** ID for the container DOM element. */
_id;
constructor(_elementRef, _focusTrapFactory, _changeDetectorRef, _document,
/** The side-sheet configuration. */
_config, _focusMonitor) {
super();
this._elementRef = _elementRef;
this._focusTrapFactory = _focusTrapFactory;
this._changeDetectorRef = _changeDetectorRef;
this._config = _config;
this._focusMonitor = _focusMonitor;
this._ariaLabelledBy = _config.ariaLabelledBy || null;
this._document = _document;
}
/** Initializes the side-sheet container with the attached content. */
_initializeWithAttachedContent() {
this._setupFocusTrap();
// Save the previously focused element. This element will be re-focused
// when the side-sheet closes.
this._capturePreviouslyFocusedElement();
}
/**
* Attach a ComponentPortal as content to this side-sheet container.
* @param portal Portal to be attached as the side-sheet content.
*/
attachComponentPortal(portal) {
return this._portalOutlet.attachComponentPortal(portal);
}
/**
* Attach a TemplatePortal as content to this side-sheet container.
* @param portal Portal to be attached as the side-sheet content.
*/
attachTemplatePortal(portal) {
return this._portalOutlet.attachTemplatePortal(portal);
}
/**
* Attaches a DOM portal to the side-sheet container.
* @param portal Portal to be attached.
* @deprecated To be turned into a method.
*/
attachDomPortal = (portal) => {
return this._portalOutlet.attachDomPortal(portal);
};
/** Moves focus back into the side-sheet if it was moved out. */
_recaptureFocus() {
if (!this._containsFocus()) {
this._trapFocus();
}
}
/**
* Moves the focus inside the focus trap. When autoFocus is not set to 'side-sheet', if focus
* cannot be moved then focus will go to the side-sheet container.
*/
_trapFocus() {
const element = this._elementRef.nativeElement;
if (!this._config.autoFocus) {
if (!this._containsFocus()) {
element.focus();
}
}
else {
this._focusTrap
.focusInitialElementWhenReady()
.then((focusedSuccessfully) => {
// If we weren't able to find a focusable element in the side-sheet, then focus the side-sheet
// container instead.
if (!focusedSuccessfully) {
this._focusSideSheetContainer();
}
});
}
}
/** Restores focus to the element that was focused before the side-sheet opened. */
_restoreFocus() {
const previousElement = this._elementFocusedBeforeSideSheetWasOpened;
// We need the extra check, because IE can set the `activeElement` to null in some cases.
if (this._config.restoreFocus &&
previousElement &&
typeof previousElement.focus === 'function') {
const activeElement = _getFocusedElementPierceShadowDom();
const element = this._elementRef.nativeElement;
// Make sure that focus is still inside the side-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)) {
if (this._focusMonitor) {
this._focusMonitor.focusVia(previousElement, this._closeInteractionType);
this._closeInteractionType = null;
}
else {
previousElement.focus();
}
}
}
if (this._focusTrap) {
this._focusTrap.destroy();
}
}
/** Sets up the focus trap. */
_setupFocusTrap() {
this._focusTrap = this._focusTrapFactory.create(this._elementRef.nativeElement);
}
/** Captures the element that was focused before the side-sheet was opened. */
_capturePreviouslyFocusedElement() {
if (this._document) {
this._elementFocusedBeforeSideSheetWasOpened =
_getFocusedElementPierceShadowDom();
}
}
/** Focuses the side-sheet container. */
_focusSideSheetContainer() {
// Note that there is no focus method when rendering on the server.
if (this._elementRef.nativeElement.focus) {
this._elementRef.nativeElement.focus();
}
}
/** Returns whether focus is inside the side-sheet. */
_containsFocus() {
const element = this._elementRef.nativeElement;
const activeElement = _getFocusedElementPierceShadowDom();
return element === activeElement || element.contains(activeElement);
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: _CovalentSideSheetContainerBase, deps: [{ token: i0.ElementRef }, { token: i1.ConfigurableFocusTrapFactory }, { token: i0.ChangeDetectorRef }, { token: DOCUMENT, optional: true }, { token: i2.CovalentSideSheetConfig }, { token: i1.FocusMonitor }], target: i0.ɵɵFactoryTarget.Directive });
static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "17.1.2", type: _CovalentSideSheetContainerBase, viewQueries: [{ propertyName: "_portalOutlet", first: true, predicate: CdkPortalOutlet, descendants: true, static: true }], usesInheritance: true, ngImport: i0 });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: _CovalentSideSheetContainerBase, decorators: [{
type: Directive
}], ctorParameters: () => [{ type: i0.ElementRef }, { type: i1.ConfigurableFocusTrapFactory }, { type: i0.ChangeDetectorRef }, { type: undefined, decorators: [{
type: Optional
}, {
type: Inject,
args: [DOCUMENT]
}] }, { type: i2.CovalentSideSheetConfig }, { type: i1.FocusMonitor }], propDecorators: { _portalOutlet: [{
type: ViewChild,
args: [CdkPortalOutlet, { static: true }]
}] } });
/**
* Internal component that wraps the generated side-sheet content.
* This animation below is the only reason for duplicating most of the Material dialog code
*/
export class CovalentSideSheetContainerComponent extends _CovalentSideSheetContainerBase {
/** State of the side-sheet animation. */
_state = 'enter';
tdSideSheetContainerClass = true;
tabIndex = -1;
arialModal = true;
idAttr = this._id;
roleAttr = this._config.role;
arialLabelByAttr = this._config.ariaLabel
? null
: this._ariaLabelledBy;
arialDescribeByAttr = this._config.ariaDescribedBy || null;
arialLabelAttr = this._config.ariaLabel;
get sideSheetAnimationState() {
return this._state;
}
onAnimateStart($event) {
this._onAnimationStart($event);
}
onAnimateDone($event) {
this._onAnimationDone($event);
}
/** Callback, invoked whenever an animation on the host completes. */
_onAnimationDone({ toState, totalTime }) {
if (toState === 'enter') {
this._trapFocus();
this._animationStateChanged.next({ state: 'opened', totalTime });
}
else if (toState === 'exit') {
this._restoreFocus();
this._animationStateChanged.next({ state: 'closed', totalTime });
}
}
/** Callback, invoked when an animation on the host starts. */
_onAnimationStart({ toState, totalTime }) {
if (toState === 'enter') {
this._animationStateChanged.next({ state: 'opening', totalTime });
}
else if (toState === 'exit' || toState === 'void') {
this._animationStateChanged.next({ state: 'closing', totalTime });
}
}
/** Starts the side-sheet exit animation. */
_startExitAnimation() {
this._state = 'exit';
this._changeDetectorRef.markForCheck();
}
static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetContainerComponent, deps: null, target: i0.ɵɵFactoryTarget.Component });
static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "17.1.2", type: CovalentSideSheetContainerComponent, selector: "td-side-sheet-container", host: { listeners: { "@sideSheetContainer.start": "onAnimateStart($event)", "@sideSheetContainer.done": "onAnimateDone($event)" }, properties: { "class.td-side-sheet-container": "this.tdSideSheetContainerClass", "tabindex": "this.tabIndex", "aria-modal": "this.arialModal", "id": "this.idAttr", "attr.role": "this.roleAttr", "attr.aria-labelledby": "this.arialLabelByAttr", "attr.aria-describedby": "this.arialDescribeByAttr", "attr.aria-label": "this.arialLabelAttr", "@sideSheetContainer": "this.sideSheetAnimationState" } }, usesInheritance: true, ngImport: i0, template: ` <ng-template cdkPortalOutlet></ng-template> `, isInline: true, styles: [".td-side-sheet-container{box-shadow:0 8px 10px -5px #0003,0 16px 24px 2px #00000024,0 6px 30px 5px #0000001f;display:block;padding:24px;box-sizing:border-box;overflow:auto;outline:0;width:100%;height:100%;min-height:inherit;max-height:inherit}.td-side-sheet-wrapper{display:flex;flex-direction:column;height:100%}.td-side-sheet-content{margin:0 -24px;padding:0 24px;overflow:auto;flex:1;-webkit-overflow-scrolling:touch}.td-side-sheet-title{margin:-16px 0 20px;display:flex;align-items:center}.td-side-sheet-actions{padding:8px 0;margin:0 -16px -24px;display:flex;justify-content:space-between;flex-wrap:wrap;align-items:center;box-sizing:content-box}.td-side-sheet-actions[align=end]{justify-content:flex-end}.td-side-sheet-actions[align=center]{justify-content:center}.td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:8px}[dir=rtl] .td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:0;margin-right:8px}\n"], dependencies: [{ kind: "directive", type: i3.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }], animations: [tdSideSheetAnimations.sideSheetContainer], changeDetection: i0.ChangeDetectionStrategy.Default, encapsulation: i0.ViewEncapsulation.None });
}
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "17.1.2", ngImport: i0, type: CovalentSideSheetContainerComponent, decorators: [{
type: Component,
args: [{ selector: 'td-side-sheet-container', template: ` <ng-template cdkPortalOutlet></ng-template> `, encapsulation: ViewEncapsulation.None, changeDetection: ChangeDetectionStrategy.Default, animations: [tdSideSheetAnimations.sideSheetContainer], styles: [".td-side-sheet-container{box-shadow:0 8px 10px -5px #0003,0 16px 24px 2px #00000024,0 6px 30px 5px #0000001f;display:block;padding:24px;box-sizing:border-box;overflow:auto;outline:0;width:100%;height:100%;min-height:inherit;max-height:inherit}.td-side-sheet-wrapper{display:flex;flex-direction:column;height:100%}.td-side-sheet-content{margin:0 -24px;padding:0 24px;overflow:auto;flex:1;-webkit-overflow-scrolling:touch}.td-side-sheet-title{margin:-16px 0 20px;display:flex;align-items:center}.td-side-sheet-actions{padding:8px 0;margin:0 -16px -24px;display:flex;justify-content:space-between;flex-wrap:wrap;align-items:center;box-sizing:content-box}.td-side-sheet-actions[align=end]{justify-content:flex-end}.td-side-sheet-actions[align=center]{justify-content:center}.td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:8px}[dir=rtl] .td-side-sheet-actions .mat-mdc-button-base+.mat-mdc-button-base{margin-left:0;margin-right:8px}\n"] }]
}], propDecorators: { tdSideSheetContainerClass: [{
type: HostBinding,
args: ['class.td-side-sheet-container']
}], tabIndex: [{
type: HostBinding,
args: ['tabindex']
}], arialModal: [{
type: HostBinding,
args: ['aria-modal']
}], idAttr: [{
type: HostBinding,
args: ['id']
}], roleAttr: [{
type: HostBinding,
args: ['attr.role']
}], arialLabelByAttr: [{
type: HostBinding,
args: ['attr.aria-labelledby']
}], arialDescribeByAttr: [{
type: HostBinding,
args: ['attr.aria-describedby']
}], arialLabelAttr: [{
type: HostBinding,
args: ['attr.aria-label']
}], sideSheetAnimationState: [{
type: HostBinding,
args: ['@sideSheetContainer']
}], onAnimateStart: [{
type: HostListener,
args: ['@sideSheetContainer.start', ['$event']]
}], onAnimateDone: [{
type: HostListener,
args: ['@sideSheetContainer.done', ['$event']]
}] } });
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZS1zaGVldC1jb250YWluZXIuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9saWJzL2FuZ3VsYXIvc2lkZS1zaGVldC9zcmMvc2lkZS1zaGVldC1jb250YWluZXIudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBRUEsT0FBTyxFQUVMLDRCQUE0QixFQUM1QixZQUFZLEdBRWIsTUFBTSxtQkFBbUIsQ0FBQztBQUMzQixPQUFPLEVBQ0wsZ0JBQWdCLEVBQ2hCLGVBQWUsR0FJaEIsTUFBTSxxQkFBcUIsQ0FBQztBQUM3QixPQUFPLEVBQUUsUUFBUSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFDM0MsT0FBTyxFQUNMLHVCQUF1QixFQUN2QixpQkFBaUIsRUFDakIsU0FBUyxFQUVULFNBQVMsRUFDVCxVQUFVLEVBRVYsWUFBWSxFQUNaLFdBQVcsRUFDWCxZQUFZLEVBQ1osTUFBTSxFQUNOLFFBQVEsRUFDUixTQUFTLEVBQ1QsaUJBQWlCLEdBQ2xCLE1BQU0sZUFBZSxDQUFDO0FBQ3ZCLE9BQU8sRUFBRSxxQkFBcUIsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQy9ELE9BQU8sRUFBRSx1QkFBdUIsRUFBRSxNQUFNLHFCQUFxQixDQUFDOzs7OztBQUU5RCxNQUFNLFVBQVUsaUNBQWlDO0lBQy9DLElBQUksYUFBYSxHQUNmLE9BQU8sUUFBUSxLQUFLLFdBQVcsSUFBSSxRQUFRO1FBQ3pDLENBQUMsQ0FBRSxRQUFRLENBQUMsYUFBb0M7UUFDaEQsQ0FBQyxDQUFDLElBQUksQ0FBQztJQUVYLE9BQU8sYUFBYSxJQUFJLGFBQWEsQ0FBQyxVQUFVLEVBQUUsQ0FBQztRQUNqRCxNQUFNLGdCQUFnQixHQUFHLGFBQWEsQ0FBQyxVQUFVO2FBQzlDLGFBQW1DLENBQUM7UUFDdkMsSUFBSSxnQkFBZ0IsS0FBSyxhQUFhLEVBQUUsQ0FBQztZQUN2QyxNQUFNO1FBQ1IsQ0FBQzthQUFNLENBQUM7WUFDTixhQUFhLEdBQUcsZ0JBQWdCLENB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QUFXO3VCQUFDLHFCQUFxQjtnQkFHcUIsY0FBYztzQkFBcEUsWUFBWTt1QkFBQywyQkFBMkIsRUFBRSxDQUFDLFFBQVEsQ0FBQztnQkFNQyxhQUFhO3NCQUFsRSxZQUFZO3VCQUFDLDBCQUEwQixFQUFFLENBQUMsUUFBUSxDQUFDIiwic291cmNlc0NvbnRlbnQiOlsiLyogdHNsaW50OmRpc2FibGUgKi9cbmltcG9ydCB7IEFuaW1hdGlvbkV2ZW50IH0gZnJvbSAnQGFuZ3VsYXIvYW5pbWF0aW9ucyc7XG5pbXBvcnQge1xuICBDb25maWd1cmFibGVGb2N1c1RyYXAsXG4gIENvbmZpZ3VyYWJsZUZvY3VzVHJhcEZhY3RvcnksXG4gIEZvY3VzTW9uaXRvcixcbiAgRm9jdXNPcmlnaW4sXG59IGZyb20gJ0Bhbmd1bGFyL2Nkay9hMTF5JztcbmltcG9ydCB7XG4gIEJhc2VQb3J0YWxPdXRsZXQsXG4gIENka1BvcnRhbE91dGxldCxcbiAgQ29tcG9uZW50UG9ydGFsLFxuICBEb21Qb3J0YWwsXG4gIFRlbXBsYXRlUG9ydGFsLFxufSBmcm9tICdAYW5ndWxhci9jZGsvcG9ydGFsJztcbmltcG9ydCB7IERPQ1VNRU5UIH0gZnJvbSAnQGFuZ3VsYXIvY29tbW9uJztcbmltcG9ydCB7XG4gIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICBDaGFuZ2VEZXRlY3RvclJlZixcbiAgQ29tcG9uZW50LFxuICBDb21wb25lbnRSZWYsXG4gIERpcmVjdGl2ZSxcbiAgRWxlbWVudFJlZixcbiAgRW1iZWRkZWRWaWV3UmVmLFxuICBFdmVudEVtaXR0ZXIsXG4gIEhvc3RCaW5kaW5nLFxuICBIb3N0TGlzdGVuZXIsXG4gIEluamVjdCxcbiAgT3B0aW9uYWwsXG4gIFZpZXdDaGlsZCxcbiAgVmlld0VuY2Fwc3VsYXRpb24sXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xuaW1wb3J0IHsgdGRTaWRlU2hlZXRBbmltYXRpb25zIH0gZnJvbSAnLi9zaWRlLXNoZWV0LmFuaW1hdGlvbic7XG5pbXBvcnQgeyBDb3ZhbGVudFNpZGVTaGVldENvbmZpZyB9IGZyb20gJy4vc2lkZS1zaGVldC5jb25maWcnO1xuXG5leHBvcnQgZnVuY3Rpb24gX2dldEZvY3VzZWRFbGVtZW50UGllcmNlU2hhZG93RG9tKCk6IEhUTUxFbGVtZW50IHwgbnVsbCB7XG4gIGxldCBhY3RpdmVFbGVtZW50ID1cbiAgICB0eXBlb2YgZG9jdW1lbnQgIT09ICd1bmRlZmluZWQnICYmIGRvY3VtZW50XG4gICAgICA/IChkb2N1bWVudC5hY3RpdmVFbGVtZW50IGFzIEhUTUxFbGVtZW50IHwgbnVsbClcbiAgICAgIDogbnVsbDtcblxuICB3aGlsZSAoYWN0aXZlRWxlbWVudCAmJiBhY3RpdmVFbGVtZW50LnNoYWRvd1Jvb3QpIHtcbiAgICBjb25zdCBuZXdBY3RpdmVFbGVtZW50ID0gYWN0aXZlRWxlbWVudC5zaGFkb3dSb290XG4gICAgICAuYWN0aXZlRWxlbWVudCBhcyBIVE1MRWxlbWVudCB8IG51bGw7XG4gICAgaWYgKG5ld0FjdGl2ZUVsZW1lbnQgPT09IGFjdGl2ZUVsZW1lbnQpIHtcbiAgICAgIGJyZWFrO1xuICAgIH0gZWxzZSB7XG4gICAgICBhY3RpdmVFbGVtZW50ID0gbmV3QWN0aXZlRWxlbWVudDtcbiAgICB9XG4gIH1cblxuICByZXR1cm4gYWN0aXZlRWxlbWVudDtcbn1cblxuLyoqXG4gKiBCYXNlIGNsYXNzIGZvciB0aGUgYENvdmFsZW50U2lkZVNoZWV0Q29udGFpbmVyYC4gVGhlIGJhc2UgY2xhc3MgZG9lcyBub3QgaW1wbGVtZW50XG4gKiBhbmltYXRpb25zIGFzIHRoZXNlIGFyZSBsZWZ0IHRvIGltcGxlbWVudGVycyBvZiB0aGUgc2lkZS1zaGVldCBjb250YWluZXIuXG4gKi9cbkBEaXJlY3RpdmUoKVxuZXhwb3J0IGFic3RyYWN0IGNsYXNzIF9Db3ZhbGVudFNpZGVTaGVldENvbnRhaW5lckJhc2UgZXh0ZW5kcyBCYXNlUG9ydGFsT3V0bGV0IHtcbiAgcHJvdGVjdGVkIF9kb2N1bWVudDogRG9jdW1lbnQ7XG5cbiAgLyoqIFRoZSBwb3J0YWwgb3V0bGV0IGluc2lkZSBvZiB0aGlzIGNvbnRhaW5lciBpbnRvIHdoaWNoIHRoZSBzaWRlLXNoZWV0IGNvbnRlbnQgd2lsbCBiZSBsb2FkZWQuICovXG4gIEBWaWV3Q2hpbGQoQ2RrUG9ydGFsT3V0bGV0LCB7IHN0YXRpYzogdHJ1ZSB9KSBfcG9ydGFsT3V0bGV0ITogQ2RrUG9ydGFsT3V0bGV0O1xuXG4gIC8qKiBUaGUgY2xhc3MgdGhhdCB0cmFwcyBhbmQgbWFuYWdlcyBmb2N1cyB3aXRoaW4gdGhlIHNpZGUtc2hlZXQuICovXG4gIHByaXZhdGUgX2ZvY3VzVHJhcCE6IENvbmZpZ3VyYWJsZUZvY3VzVHJhcDtcblxuICAvKiogRW1pdHMgd2hlbiBhbiBhbmltYXRpb24gc3RhdGUgY2hhbmdlcy4gKi9cbiAgX2FuaW1hdGlvblN0YXRlQ2hhbmdlZCA9IG5ldyBFdmVudEVtaXR0ZXI8e1xuICAgIHN0YXRlOiAnb3BlbmVkJyB8ICdvcGVuaW5nJyB8ICdjbG9zaW5nJyB8ICdjbG9zZWQnO1xuICAgIHRvdGFsVGltZTogbnVtYmVyO1xuICB9PigpO1xuXG4gIC8qKiBFbGVtZW50IHRoYXQgd2FzIGZvY3VzZWQgYmVmb3JlIHRoZSBzaWRlLXNoZWV0IHdhcyBvcGVuZWQuIFNhdmUgdGhpcyB0byByZXN0b3JlIHVwb24gY2xvc2UuICovXG4gIHByaXZhdGUgX2VsZW1lbnRGb2N1c2VkQmVmb3JlU2lkZVNoZWV0V2FzT3BlbmVkOiBIVE1MRWxlbWVudCB8IG51bGwgPSBudWxsO1xuXG4gIC8qKlxuICAgKiBUeXBlIG9mIGludGVyYWN0aW9uIHRoYXQgbGVkIHRvIHRoZSBzaWRlLXNoZWV0IGJlaW5nIGNsb3NlZC4gVGhpcyBpcyB1c2VkIHRvIGRldGVybWluZVxuICAgKiB3aGV0aGVyIHRoZSBmb2N1cyBzdHlsZSB3aWxsIGJlIGFwcGxpZWQgd2hlbiByZXR1cm5pbmcgZm9jdXMgdG8gaXRzIG9yaWdpbmFsIGxvY2F0aW9uXG4gICAqIGFmdGVyIHRoZSBzaWRlLXNoZWV0IGlzIGNsb3NlZC5cbiAgICovXG4gIF9jbG9zZUludGVyYWN0aW9uVHlwZTogRm9jdXNPcmlnaW4gfCBudWxsID0gbnVsbDtcblxuICAvKiogSUQgb2YgdGhlIGVsZW1lbnQgdGhhdCBzaG91bGQgYmUgY29uc2lkZXJlZCBhcyB0aGUgc2lkZS1zaGVldCdzIGxhYmVsLiAqL1xuICBfYXJpYUxhYmVsbGVkQnk6IHN0cmluZyB8IG51bGw7XG5cbiAgLyoqIElEIGZvciB0aGUgY29udGFpbmVyIERPTSBlbGVtZW50LiAqL1xuICBfaWQhOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIF9lbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgIHByb3RlY3RlZCBfZm9jdXNUcmFwRmFjdG9yeTogQ29uZmlndXJhYmxlRm9jdXNUcmFwRmFjdG9yeSxcbiAgICBwcm90ZWN0ZWQgX2NoYW5nZURldGVjdG9yUmVmOiBDaGFuZ2VEZXRlY3RvclJlZixcbiAgICBAT3B0aW9uYWwoKSBASW5qZWN0KERPQ1VNRU5UKSBfZG9jdW1lbnQ6IGFueSxcbiAgICAvKiogVGhlIHNpZGUtc2hlZXQgY29uZmlndXJhdGlvbi4gKi9cbiAgICBwdWJsaWMgX2NvbmZpZzogQ292YWxlbnRTaWRlU2hlZXRDb25maWcsXG4gICAgcHJpdmF0ZSBfZm9jdXNNb25pdG9yPzogRm9jdXNNb25pdG9yXG4gICkge1xuICAgIHN1cGVyKCk7XG4gICAgdGhpcy5fYXJpYUxhYmVsbGVkQnkgPSBfY29uZmlnLmFyaWFMYWJlbGxlZEJ5IHx8IG51bGw7XG4gICAgdGhpcy5fZG9jdW1lbnQgPSBfZG9jdW1lbnQ7XG4gIH1cblxuICAvKiogU3RhcnRzIHRoZSBzaWRlLXNoZWV0IGV4aXQgYW5pbWF0aW9uLiAqL1xuICBhYnN0cmFjdCBfc3RhcnRFeGl0QW5pbWF0aW9uKCk6IHZvaWQ7XG5cbiAgLyoqIEluaXRpYWxpemVzIHRoZSBzaWRlLXNoZWV0IGNvbnRhaW5lciB3aXRoIHRoZSBhdHRhY2hlZCBjb250ZW50LiAqL1xuICBfaW5pdGlhbGl6ZVdpdGhBdHRhY2hlZENvbnRlbnQoKSB7XG4gICAgdGhpcy5fc2V0dXBGb2N1c1RyYXAoKTtcbiAgICAvLyBTYXZlIHRoZSBwcmV2aW91c2x5IGZvY3VzZWQgZWxlbWVudC4gVGhpcyBlbGVtZW50IHdpbGwgYmUgcmUtZm9jdXNlZFxuICAgIC8vIHdoZW4gdGhlIHNpZGUtc2hlZXQgY2xvc2VzLlxuICAgIHRoaXMuX2NhcHR1cmVQcmV2aW91c2x5Rm9jdXNlZEVsZW1lbnQoKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2ggYSBDb21wb25lbnRQb3J0YWwgYXMgY29udGVudCB0byB0aGlzIHNpZGUtc2hlZXQgY29udGFpbmVyLlxuICAgKiBAcGFyYW0gcG9ydGFsIFBvcnRhbCB0byBiZSBhdHRhY2hlZCBhcyB0aGUgc2lkZS1zaGVldCBjb250ZW50LlxuICAgKi9cbiAgYXR0YWNoQ29tcG9uZW50UG9ydGFsPFQ+KHBvcnRhbDogQ29tcG9uZW50UG9ydGFsPFQ+KTogQ29tcG9uZW50UmVmPFQ+IHtcbiAgICByZXR1cm4gdGhpcy5fcG9ydGFsT3V0bGV0LmF0dGFjaENvbXBvbmVudFBvcnRhbChwb3J0YWwpO1xuICB9XG5cbiAgLyoqXG4gICAqIEF0dGFjaCBhIFRlbXBsYXRlUG9ydGFsIGFzIGNvbnRlbnQgdG8gdGhpcyBzaWRlLXNoZWV0IGNvbnRhaW5lci5cbiAgICogQHBhcmFtIHBvcnRhbCBQb3J0YWwgdG8gYmUgYXR0YWNoZWQgYXMgdGhlIHNpZGUtc2hlZXQgY29udGVudC5cbiAgICovXG4gIGF0dGFjaFRlbXBsYXRlUG9ydGFsPEM+KHBvcnRhbDogVGVtcGxhdGVQb3J0YWw8Qz4pOiBFbWJlZGRlZFZpZXdSZWY8Qz4ge1xuICAgIHJldHVybiB0aGlzLl9wb3J0YWxPdXRsZXQuYXR0YWNoVGVtcGxhdGVQb3J0YWwocG9ydGFsKTtcbiAgfVxuXG4gIC8qKlxuICAgKiBBdHRhY2hlcyBhIERPTSBwb3J0YWwgdG8gdGhlIHNpZGUtc2hlZXQgY29udGFpbmVyLlxuICAgKiBAcGFyYW0gcG9ydGFsIFBvcnRhbCB0byBiZSBhdHRhY2hlZC5cbiAgICogQGRlcHJlY2F0ZWQgVG8gYmUgdHVybmVkIGludG8gYSBtZXRob2QuXG4gICAqL1xuICBvdmVycmlkZSBhdHRhY2hEb21Qb3J0YWwgPSAocG9ydGFsOiBEb21Qb3J0YWwpID0+IHtcbiAgICByZXR1cm4gdGhpcy5fcG9ydGFsT3V0bGV0LmF0dGFjaERvbVBvcnRhbChwb3J0YWwpO1xuICB9O1xuXG4gIC8qKiBNb3ZlcyBmb2N1cyBiYWNrIGludG8gdGhlIHNpZGUtc2hlZXQgaWYgaXQgd2FzIG1vdmVkIG91dC4gKi9cbiAgX3JlY2FwdHVyZUZvY3VzKCkge1xuICAgIGlmICghdGhpcy5fY29udGFpbnNGb2N1cygpKSB7XG4gICAgICB0aGlzLl90cmFwRm9jdXMoKTtcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogTW92ZXMgdGhlIGZvY3VzIGluc2lkZSB0aGUgZm9jdXMgdHJhcC4gV2hlbiBhdXRvRm9jdXMgaXMgbm90IHNldCB0byAnc2lkZS1zaGVldCcsIGlmIGZvY3VzXG4gICAqIGNhbm5vdCBiZSBtb3ZlZCB0aGVuIGZvY3VzIHdpbGwgZ28gdG8gdGhlIHNpZGUtc2hlZXQgY29udGFpbmVyLlxuICAgKi9cbiAgcHJvdGVjdGVkIF90cmFwRm9jdXMoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBpZiAoIXRoaXMuX2NvbmZpZy5hdXRvRm9jdXMpIHtcbiAgICAgIGlmICghdGhpcy5fY29udGFpbnNGb2N1cygpKSB7XG4gICAgICAgIGVsZW1lbnQuZm9jdXMoKTtcbiAgICAgIH1cbiAgICB9IGVsc2Uge1xuICAgICAgdGhpcy5fZm9jdXNUcmFwXG4gICAgICAgIC5mb2N1c0luaXRpYWxFbGVtZW50V2hlblJlYWR5KClcbiAgICAgICAgLnRoZW4oKGZvY3VzZWRTdWNjZXNzZnVsbHkpID0+IHtcbiAgICAgICAgICAvLyBJZiB3ZSB3ZXJlbid0IGFibGUgdG8gZmluZCBhIGZvY3VzYWJsZSBlbGVtZW50IGluIHRoZSBzaWRlLXNoZWV0LCB0aGVuIGZvY3VzIHRoZSBzaWRlLXNoZWV0XG4gICAgICAgICAgLy8gY29udGFpbmVyIGluc3RlYWQuXG4gICAgICAgICAgaWYgKCFmb2N1c2VkU3VjY2Vzc2Z1bGx5KSB7XG4gICAgICAgICAgICB0aGlzLl9mb2N1c1NpZGVTaGVldENvbnRhaW5lcigpO1xuICAgICAgICAgIH1cbiAgICAgICAgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJlc3RvcmVzIGZvY3VzIHRvIHRoZSBlbGVtZW50IHRoYXQgd2FzIGZvY3VzZWQgYmVmb3JlIHRoZSBzaWRlLXNoZWV0IG9wZW5lZC4gKi9cbiAgcHJvdGVjdGVkIF9yZXN0b3JlRm9jdXMoKSB7XG4gICAgY29uc3QgcHJldmlvdXNFbGVtZW50ID0gdGhpcy5fZWxlbWVudEZvY3VzZWRCZWZvcmVTaWRlU2hlZXRXYXNPcGVuZWQ7XG5cbiAgICAvLyBXZSBuZWVkIHRoZSBleHRyYSBjaGVjaywgYmVjYXVzZSBJRSBjYW4gc2V0IHRoZSBgYWN0aXZlRWxlbWVudGAgdG8gbnVsbCBpbiBzb21lIGNhc2VzLlxuICAgIGlmIChcbiAgICAgIHRoaXMuX2NvbmZpZy5yZXN0b3JlRm9jdXMgJiZcbiAgICAgIHByZXZpb3VzRWxlbWVudCAmJlxuICAgICAgdHlwZW9mIHByZXZpb3VzRWxlbWVudC5mb2N1cyA9PT0gJ2Z1bmN0aW9uJ1xuICAgICkge1xuICAgICAgY29uc3QgYWN0aXZlRWxlbWVudCA9IF9nZXRGb2N1c2VkRWxlbWVudFBpZXJjZVNoYWRvd0RvbSgpO1xuICAgICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcblxuICAgICAgLy8gTWFrZSBzdXJlIHRoYXQgZm9jdXMgaXMgc3RpbGwgaW5zaWRlIHRoZSBzaWRlLXNoZWV0IG9yIGlzIG9uIHRoZSBib2R5ICh1c3VhbGx5IGJlY2F1c2UgYVxuICAgICAgLy8gbm9uLWZvY3VzYWJsZSBlbGVtZW50IGxpa2UgdGhlIGJhY2tkcm9wIHdhcyBjbGlja2VkKSBiZWZvcmUgbW92aW5nIGl0LiBJdCdzIHBvc3NpYmxlIHRoYXRcbiAgICAgIC8vIHRoZSBjb25zdW1lciBtb3ZlZCBpdCB0aGVtc2VsdmVzIGJlZm9yZSB0aGUgYW5pbWF0aW9uIHdhcyBkb25lLCBpbiB3aGljaCBjYXNlIHdlIHNob3VsZG4ndFxuICAgICAgLy8gZG8gYW55dGhpbmcuXG4gICAgICBpZiAoXG4gICAgICAgICFhY3RpdmVFbGVtZW50IHx8XG4gICAgICAgIGFjdGl2ZUVsZW1lbnQgPT09IHRoaXMuX2RvY3VtZW50LmJvZHkgfHxcbiAgICAgICAgYWN0aXZlRWxlbWVudCA9PT0gZWxlbWVudCB8fFxuICAgICAgICBlbGVtZW50LmNvbnRhaW5zKGFjdGl2ZUVsZW1lbnQpXG4gICAgICApIHtcbiAgICAgICAgaWYgKHRoaXMuX2ZvY3VzTW9uaXRvcikge1xuICAgICAgICAgIHRoaXMuX2ZvY3VzTW9uaXRvci5mb2N1c1ZpYShcbiAgICAgICAgICAgIHByZXZpb3VzRWxlbWVudCxcbiAgICAgICAgICAgIHRoaXMuX2Nsb3NlSW50ZXJhY3Rpb25UeXBlXG4gICAgICAgICAgKTtcbiAgICAgICAgICB0aGlzLl9jbG9zZUludGVyYWN0aW9uVHlwZSA9IG51bGw7XG4gICAgICAgIH0gZWxzZSB7XG4gICAgICAgICAgcHJldmlvdXNFbGVtZW50LmZvY3VzKCk7XG4gICAgICAgIH1cbiAgICAgIH1cbiAgICB9XG5cbiAgICBpZiAodGhpcy5fZm9jdXNUcmFwKSB7XG4gICAgICB0aGlzLl9mb2N1c1RyYXAuZGVzdHJveSgpO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBTZXRzIHVwIHRoZSBmb2N1cyB0cmFwLiAqL1xuICBwcml2YXRlIF9zZXR1cEZvY3VzVHJhcCgpIHtcbiAgICB0aGlzLl9mb2N1c1RyYXAgPSB0aGlzLl9mb2N1c1RyYXBGYWN0b3J5LmNyZWF0ZShcbiAgICAgIHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudFxuICAgICk7XG4gIH1cblxuICAvKiogQ2FwdHVyZXMgdGhlIGVsZW1lbnQgdGhhdCB3YXMgZm9jdXNlZCBiZWZvcmUgdGhlIHNpZGUtc2hlZXQgd2FzIG9wZW5lZC4gKi9cbiAgcHJpdmF0ZSBfY2FwdHVyZVByZXZpb3VzbHlGb2N1c2VkRWxlbWVudCgpIHtcbiAgICBpZiAodGhpcy5fZG9jdW1lbnQpIHtcbiAgICAgIHRoaXMuX2VsZW1lbnRGb2N1c2VkQmVmb3JlU2lkZVNoZWV0V2FzT3BlbmVkID1cbiAgICAgICAgX2dldEZvY3VzZWRFbGVtZW50UGllcmNlU2hhZG93RG9tKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIEZvY3VzZXMgdGhlIHNpZGUtc2hlZXQgY29udGFpbmVyLiAqL1xuICBwcml2YXRlIF9mb2N1c1NpZGVTaGVldENvbnRhaW5lcigpIHtcbiAgICAvLyBOb3RlIHRoYXQgdGhlcmUgaXMgbm8gZm9jdXMgbWV0aG9kIHdoZW4gcmVuZGVyaW5nIG9uIHRoZSBzZXJ2ZXIuXG4gICAgaWYgKHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cykge1xuICAgICAgdGhpcy5fZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50LmZvY3VzKCk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFJldHVybnMgd2hldGhlciBmb2N1cyBpcyBpbnNpZGUgdGhlIHNpZGUtc2hlZXQuICovXG4gIHByaXZhdGUgX2NvbnRhaW5zRm9jdXMoKSB7XG4gICAgY29uc3QgZWxlbWVudCA9IHRoaXMuX2VsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcbiAgICBjb25zdCBhY3RpdmVFbGVtZW50ID0gX2dldEZvY3VzZWRFbGVtZW50UGllcmNlU2hhZG93RG9tKCk7XG4gICAgcmV0dXJuIGVsZW1lbnQgPT09IGFjdGl2ZUVsZW1lbnQgfHwgZWxlbWVudC5jb250YWlucyhhY3RpdmVFbGVtZW50KTtcbiAgfVxufVxuXG4vKipcbiAqIEludGVybmFsIGNvbXBvbmVudCB0aGF0IHdyYXBzIHRoZSBnZW5lcmF0ZWQgc2lkZS1zaGVldCBjb250ZW50LlxuICogVGhpcyBhbmltYXRpb24gYmVsb3cgaXMgdGhlIG9ubHkgcmVhc29uIGZvciBkdXBsaWNhdGluZyBtb3N0IG9mIHRoZSBNYXRlcmlhbCBkaWFsb2cgY29kZVxuICovXG5AQ29tcG9uZW50KHtcbiAgc2VsZWN0b3I6ICd0ZC1zaWRlLXNoZWV0LWNvbnRhaW5lcicsXG4gIHRlbXBsYXRlOiBgIDxuZy10ZW1wbGF0ZSBjZGtQb3J0YWxPdXRsZXQ+PC9uZy10ZW1wbGF0ZT4gYCxcbiAgc3R5bGVVcmxzOiBbJ3NpZGUtc2hlZXQuc2NzcyddLFxuICBlbmNhcHN1bGF0aW9uOiBWaWV3RW5jYXBzdWxhdGlvbi5Ob25lLFxuICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5LkRlZmF1bHQsXG4gIGFuaW1hdGlvbnM6IFt0ZFNpZGVTaGVldEFuaW1hdGlvbnMuc2lkZVNoZWV0Q29udGFpbmVyXSxcbn0pXG5leHBvcnQgY2xhc3MgQ292YWxlbnRTaWRlU2hlZXRDb250YWluZXJDb21wb25lbnQgZXh0ZW5kcyBfQ292YWxlbnRTaWRlU2hlZXRDb250YWluZXJCYXNlIHtcbiAgLyoqIFN0YXRlIG9mIHRoZSBzaWRlLXNoZWV0IGFuaW1hdGlvbi4gKi9cbiAgX3N0YXRlOiAndm9pZCcgfCAnZW50ZXInIHwgJ2V4aXQnID0gJ2VudGVyJztcblxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLnRkLXNpZGUtc2hlZXQtY29udGFpbmVyJykgdGRTaWRlU2hlZXRDb250YWluZXJDbGFzcyA9XG4gICAgdHJ1ZTtcbiAgQEhvc3RCaW5kaW5nKCd0YWJpbmRleCcpIHRhYkluZGV4ID0gLTE7XG4gIEBIb3N0QmluZGluZygnYXJpYS1tb2RhbCcpIGFyaWFsTW9kYWwgPSB0cnVlO1xuICBASG9zdEJpbmRpbmcoJ2lkJykgaWRBdHRyID0gdGhpcy5faWQ7XG4gIEBIb3N0QmluZGluZygnYXR0ci5yb2xlJykgcm9sZUF0dHIgPSB0aGlzLl9jb25maWcucm9sZTtcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtbGFiZWxsZWRieScpIGFyaWFsTGFiZWxCeUF0dHIgPSB0aGlzLl9jb25maWcuYXJpYUxhYmVsXG4gICAgPyBudWxsXG4gICAgOiB0aGlzLl9hcmlhTGFiZWxsZWRCeTtcbiAgQEhvc3RCaW5kaW5nKCdhdHRyLmFyaWEtZGVzY3JpYmVkYnknKSBhcmlhbERlc2NyaWJlQnlBdHRyID1cbiAgICB0aGlzLl9jb25maWcuYXJpYURlc2NyaWJlZEJ5IHx8IG51bGw7XG4gIEBIb3N0QmluZGluZygnYXR0ci5hcmlhLWxhYmVsJykgYXJpYWxMYWJlbEF0dHIgPSB0aGlzLl9jb25maWcuYXJpYUxhYmVsO1xuICBASG9zdEJpbmRpbmcoJ0BzaWRlU2hlZXRDb250YWluZXInKSBnZXQgc2lkZVNoZWV0QW5pbWF0aW9uU3RhdGUoKSB7XG4gICAgcmV0dXJuIHRoaXMuX3N0YXRlO1xuICB9XG4gIEBIb3N0TGlzdGVuZXIoJ0BzaWRlU2hlZXRDb250YWluZXIuc3RhcnQnLCBbJyRldmVudCddKSBvbkFuaW1hdGVTdGFydChcbiAgICAkZXZlbnQ6IEFuaW1hdGlvbkV2ZW50XG4gICkge1xuICAgIHRoaXMuX29uQW5pbWF0aW9uU3RhcnQoJGV2ZW50KTtcbiAgfVxuXG4gIEBIb3N0TGlzdGVuZXIoJ0BzaWRlU2hlZXRDb250YWluZXIuZG9uZScsIFsnJGV2ZW50J10pIG9uQW5pbWF0ZURvbmUoXG4gICAgJGV2ZW50OiBBbmltYXRpb25FdmVudFxuICApIHtcbiAgICB0aGlzLl9vbkFuaW1hdGlvbkRvbmUoJGV2ZW50KTtcbiAgfVxuXG4gIC8qKiBDYWxsYmFjaywgaW52b2tlZCB3aGVuZXZlciBhbiBhbmltYXRpb24gb24gdGhlIGhvc3QgY29tcGxldGVzLiAqL1xuICBfb25BbmltYXRpb25Eb25lKHsgdG9TdGF0ZSwgdG90YWxUaW1lIH06IEFuaW1hdGlvbkV2ZW50KSB7XG4gICAgaWYgKHRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuX3RyYXBGb2N1cygpO1xuICAgICAgdGhpcy5fYW5pbWF0aW9uU3RhdGVDaGFuZ2VkLm5leHQoeyBzdGF0ZTogJ29wZW5lZCcsIHRvdGFsVGltZSB9KTtcbiAgICB9IGVsc2UgaWYgKHRvU3RhdGUgPT09ICdleGl0Jykge1xuICAgICAgdGhpcy5fcmVzdG9yZUZvY3VzKCk7XG4gICAgICB0aGlzLl9hbmltYXRpb25TdGF0ZUNoYW5nZWQubmV4dCh7IHN0YXRlOiAnY2xvc2VkJywgdG90YWxUaW1lIH0pO1xuICAgIH1cbiAgfVxuXG4gIC8qKiBDYWxsYmFjaywgaW52b2tlZCB3aGVuIGFuIGFuaW1hdGlvbiBvbiB0aGUgaG9zdCBzdGFydHMuICovXG4gIF9vbkFuaW1hdGlvblN0YXJ0KHsgdG9TdGF0ZSwgdG90YWxUaW1lIH06IEFuaW1hdGlvbkV2ZW50KSB7XG4gICAgaWYgKHRvU3RhdGUgPT09ICdlbnRlcicpIHtcbiAgICAgIHRoaXMuX2FuaW1hdGlvblN0YXRlQ2hhbmdlZC5uZXh0KHsgc3RhdGU6ICdvcGVuaW5nJywgdG90YWxUaW1lIH0pO1xuICAgIH0gZWxzZSBpZiAodG9TdGF0ZSA9PT0gJ2V4aXQnIHx8IHRvU3RhdGUgPT09ICd2b2lkJykge1xuICAgICAgdGhpcy5fYW5pbWF0aW9uU3RhdGVDaGFuZ2VkLm5leHQoeyBzdGF0ZTogJ2Nsb3NpbmcnLCB0b3RhbFRpbWUgfSk7XG4gICAgfVxuICB9XG5cbiAgLyoqIFN0YXJ0cyB0aGUgc2lkZS1zaGVldCBleGl0IGFuaW1hdGlvbi4gKi9cbiAgX3N0YXJ0RXhpdEFuaW1hdGlvbigpOiB2b2lkIHtcbiAgICB0aGlzLl9zdGF0ZSA9ICdleGl0JztcbiAgICB0aGlzLl9jaGFuZ2VEZXRlY3RvclJlZi5tYXJrRm9yQ2hlY2soKTtcbiAgfVxufVxuIl19