ngx-mat-lib
Version:
A bunch of utilities and components to use in your Angular 7+ apps!
386 lines (385 loc) • 40.5 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,uselessCode} checked by tsc
*/
// tslint:disable:member-ordering
import { Component, ViewEncapsulation, ChangeDetectionStrategy, ChangeDetectorRef, ElementRef, NgZone, ViewChild, Input, Optional, ContentChildren, QueryList, forwardRef, Directive, Inject, Attribute, } from "@angular/core";
import { ANIMATION_MODULE_TYPE } from "@angular/platform-browser/animations";
import { Directionality } from "@angular/cdk/bidi";
import { coerceBooleanProperty } from "@angular/cdk/coercion";
import { ViewportRuler } from "@angular/cdk/overlay";
import { FocusMonitor } from "@angular/cdk/a11y";
import { Platform } from "@angular/cdk/platform";
import { mixinDisableRipple, MAT_RIPPLE_GLOBAL_OPTIONS, RippleRenderer, mixinTabIndex, mixinDisabled, } from "@angular/material/core";
import { XmatInkBarDirective } from "./xmat-ink-bar.directive";
import { XmatPaginatedTabHeaderDirective } from "./xmat-paginated-tab-header";
import { takeUntil, startWith } from "rxjs/operators";
/**
* Base class with all of the `MatTabNav` functionality.
* \@docs-private
* @abstract
*/
export class _XmatTabNavBase extends XmatPaginatedTabHeaderDirective {
/**
* @param {?} elementRef
* @param {?} dir
* @param {?} ngZone
* @param {?} changeDetectorRef
* @param {?} viewportRuler
* @param {?=} platform
* @param {?=} animationMode
*/
constructor(elementRef, dir, ngZone, changeDetectorRef, viewportRuler, /**
* @deprecated @breaking-change 9.0.0 `platform` parameter to become required.
*/
platform, animationMode) {
super(elementRef, changeDetectorRef, viewportRuler, dir, ngZone, platform, animationMode);
this._disableRipple = false;
/**
* Theme color of the nav bar.
*/
this.color = "primary";
}
/**
* Background color of the tab nav.
* @return {?}
*/
get backgroundColor() {
return this._backgroundColor;
}
/**
* @param {?} value
* @return {?}
*/
set backgroundColor(value) {
/** @type {?} */
const classList = this._elementRef.nativeElement.classList;
classList.remove(`mat-background-${this.backgroundColor}`);
if (value) {
classList.add(`mat-background-${value}`);
}
this._backgroundColor = value;
}
/**
* Whether the ripple effect is disabled or not.
* @return {?}
*/
get disableRipple() {
return this._disableRipple;
}
/**
* @param {?} value
* @return {?}
*/
set disableRipple(value) {
this._disableRipple = coerceBooleanProperty(value);
}
/**
* @return {?}
*/
_itemSelected() {
// noop
}
/**
* @return {?}
*/
ngAfterContentInit() {
// We need this to run before the `changes` subscription in parent to ensure that the
// selectedIndex is up-to-date by the time the super class starts looking for it.
this._items.changes.pipe(startWith(null), takeUntil(this._destroyed)).subscribe(() => {
this.updateActiveLink();
});
super.ngAfterContentInit();
}
/**
* Notifies the component that the active link has been changed.
* \@breaking-change 8.0.0 `element` parameter to be removed.
* @param {?=} _element
* @return {?}
*/
updateActiveLink(_element) {
if (!this._items) {
return;
}
/** @type {?} */
const items = this._items.toArray();
for (let i = 0; i < items.length; i++) {
if (items[i].active) {
this.selectedIndex = i;
this._changeDetectorRef.markForCheck();
return;
}
}
// The ink bar should hide itself if no items are active.
this.selectedIndex = -1;
this._inkBar.hide();
}
}
/** @nocollapse */
_XmatTabNavBase.ctorParameters = () => [
{ type: ElementRef },
{ type: Directionality, decorators: [{ type: Optional }] },
{ type: NgZone },
{ type: ChangeDetectorRef },
{ type: ViewportRuler },
{ type: Platform, decorators: [{ type: Optional }] },
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
];
_XmatTabNavBase.propDecorators = {
backgroundColor: [{ type: Input }],
disableRipple: [{ type: Input }],
color: [{ type: Input }]
};
if (false) {
/**
* Query list of all tab links of the tab navigation.
* @type {?}
*/
_XmatTabNavBase.prototype._items;
/** @type {?} */
_XmatTabNavBase.prototype._backgroundColor;
/** @type {?} */
_XmatTabNavBase.prototype._disableRipple;
/**
* Theme color of the nav bar.
* @type {?}
*/
_XmatTabNavBase.prototype.color;
}
export class XmatTabNavComponent extends _XmatTabNavBase {
/**
* @param {?} elementRef
* @param {?} dir
* @param {?} ngZone
* @param {?} changeDetectorRef
* @param {?} viewportRuler
* @param {?=} platform
* @param {?=} animationMode
*/
constructor(elementRef, dir, ngZone, changeDetectorRef, viewportRuler, /**
* @deprecated @breaking-change 9.0.0 `platform` parameter to become required.
*/
platform, animationMode) {
super(elementRef, dir, ngZone, changeDetectorRef, viewportRuler, platform, animationMode);
}
}
XmatTabNavComponent.decorators = [
{ type: Component, args: [{
// tslint:disable-next-line:component-selector
selector: "[xmat-tab-nav-bar]",
// tslint:disable-next-line:use-input-property-decorator
inputs: ["color", "disableRipple"],
template: "<div class=\"mat-tab-header-pagination mat-tab-header-pagination-before mat-elevation-z4\"\n #previousPaginator\n aria-hidden=\"true\"\n mat-ripple\n [matRippleDisabled]=\"_disableScrollBefore || disableRipple\"\n [class.mat-tab-header-pagination-disabled]=\"_disableScrollBefore\"\n (click)=\"_handlePaginatorClick('before')\"\n (mousedown)=\"_handlePaginatorPress('before')\"\n (touchend)=\"_stopInterval()\">\n <div class=\"mat-tab-header-pagination-chevron\"></div>\n</div>\n\n<div class=\"mat-tab-link-container\" #tabListContainer (keydown)=\"_handleKeydown($event)\">\n <div class=\"mat-tab-list\" #tabList (cdkObserveContent)=\"_onContentChanges()\">\n <div class=\"mat-tab-links\">\n <ng-content></ng-content>\n </div>\n <xmat-ink-bar></xmat-ink-bar>\n </div>\n</div>\n\n<div class=\"mat-tab-header-pagination mat-tab-header-pagination-after mat-elevation-z4\"\n #nextPaginator\n aria-hidden=\"true\"\n mat-ripple [matRippleDisabled]=\"_disableScrollAfter || disableRipple\"\n [class.mat-tab-header-pagination-disabled]=\"_disableScrollAfter\"\n (mousedown)=\"_handlePaginatorPress('after')\"\n (click)=\"_handlePaginatorClick('after')\"\n (touchend)=\"_stopInterval()\">\n <div class=\"mat-tab-header-pagination-chevron\"></div>\n</div>\n",
// host: {"class": "mat-tab-nav-bar"},
host: {
"class": "mat-tab-nav-bar mat-tab-header",
"[class.mat-tab-header-pagination-controls-enabled]": "_showPaginationControls",
"[class.mat-tab-header-rtl]": "_getLayoutDirection() == \"rtl\"",
"[class.mat-primary]": "color !== \"warn\" && color !== \"accent\"",
"[class.mat-accent]": "color === \"accent\"",
"[class.mat-warn]": "color === \"warn\"",
},
encapsulation: ViewEncapsulation.None,
changeDetection: ChangeDetectionStrategy.OnPush,
styles: [".mat-tab-header{display:-webkit-box;display:flex;overflow:hidden;position:relative;flex-shrink:0}.mat-tab-header-pagination{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none;position:relative;display:none;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;min-width:32px;cursor:pointer;z-index:2;-webkit-tap-highlight-color:transparent;touch-action:none}.mat-tab-header-pagination-controls-enabled .mat-tab-header-pagination{display:-webkit-box;display:flex}.mat-tab-header-pagination-before,.mat-tab-header-rtl .mat-tab-header-pagination-after{padding-left:4px}.mat-tab-header-pagination-before .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-after .mat-tab-header-pagination-chevron{-webkit-transform:rotate(-135deg);transform:rotate(-135deg)}.mat-tab-header-pagination-after,.mat-tab-header-rtl .mat-tab-header-pagination-before{padding-right:4px}.mat-tab-header-pagination-after .mat-tab-header-pagination-chevron,.mat-tab-header-rtl .mat-tab-header-pagination-before .mat-tab-header-pagination-chevron{-webkit-transform:rotate(45deg);transform:rotate(45deg)}.mat-tab-header-pagination-chevron{border-style:solid;border-width:2px 2px 0 0;content:'';height:8px;width:8px}.mat-tab-header-pagination-disabled{box-shadow:none;cursor:default}.mat-tab-list{-webkit-box-flex:1;flex-grow:1;position:relative;-webkit-transition:-webkit-transform .5s cubic-bezier(.35,0,.25,1);transition:transform .5s cubic-bezier(.35,0,.25,1);transition:transform .5s cubic-bezier(.35,0,.25,1),-webkit-transform .5s cubic-bezier(.35,0,.25,1)}.mat-tab-links{display:-webkit-box;display:flex}[mat-align-tabs=center] .mat-tab-links{-webkit-box-pack:center;justify-content:center}[mat-align-tabs=end] .mat-tab-links{-webkit-box-pack:end;justify-content:flex-end}.mat-ink-bar{position:absolute;bottom:0;height:2px;-webkit-transition:.5s cubic-bezier(.35,0,.25,1);transition:.5s cubic-bezier(.35,0,.25,1)}._mat-animation-noopable.mat-ink-bar{-webkit-transition:none;transition:none;-webkit-animation:none;animation:none}.mat-tab-group-inverted-header .mat-ink-bar{bottom:auto;top:0}@media (-ms-high-contrast:active){.mat-ink-bar{outline:solid 2px;height:0}}.mat-tab-link-container{display:-webkit-box;display:flex;-webkit-box-flex:1;flex-grow:1;overflow:hidden;z-index:1}.mat-tab-link{height:48px;padding:0 24px;cursor:pointer;box-sizing:border-box;opacity:.6;min-width:160px;text-align:center;display:-webkit-inline-box;display:inline-flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;white-space:nowrap;vertical-align:top;text-decoration:none;position:relative;overflow:hidden;-webkit-tap-highlight-color:transparent}.mat-tab-link:focus{outline:0}.mat-tab-link:focus:not(.mat-tab-disabled){opacity:1}.mat-tab-link.mat-tab-disabled{cursor:default;pointer-events:none}.mat-tab-link .mat-tab-label-content{display:-webkit-inline-box;display:inline-flex;-webkit-box-pack:center;justify-content:center;-webkit-box-align:center;align-items:center;white-space:nowrap}@media (-ms-high-contrast:active){.mat-tab-link:focus{outline:dotted 2px}.mat-tab-link.mat-tab-disabled{opacity:.5}.mat-tab-link{opacity:1}}[mat-stretch-tabs] .mat-tab-link{flex-basis:0;-webkit-box-flex:1;flex-grow:1}@media (max-width:599px){.mat-tab-link{min-width:72px}}"]
}] }
];
/** @nocollapse */
XmatTabNavComponent.ctorParameters = () => [
{ type: ElementRef },
{ type: Directionality, decorators: [{ type: Optional }] },
{ type: NgZone },
{ type: ChangeDetectorRef },
{ type: ViewportRuler },
{ type: Platform, decorators: [{ type: Optional }] },
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
];
XmatTabNavComponent.propDecorators = {
_items: [{ type: ContentChildren, args: [forwardRef(() => XmatTabLinkDirective), { descendants: true },] }],
_inkBar: [{ type: ViewChild, args: [XmatInkBarDirective,] }],
_tabListContainer: [{ type: ViewChild, args: ["tabListContainer",] }],
_tabList: [{ type: ViewChild, args: ["tabList",] }],
_nextPaginator: [{ type: ViewChild, args: ["nextPaginator",] }],
_previousPaginator: [{ type: ViewChild, args: ["previousPaginator",] }]
};
if (false) {
/** @type {?} */
XmatTabNavComponent.prototype._items;
/** @type {?} */
XmatTabNavComponent.prototype._inkBar;
/** @type {?} */
XmatTabNavComponent.prototype._tabListContainer;
/** @type {?} */
XmatTabNavComponent.prototype._tabList;
/** @type {?} */
XmatTabNavComponent.prototype._nextPaginator;
/** @type {?} */
XmatTabNavComponent.prototype._previousPaginator;
}
class XmatTabLinkMixinBase {
}
/** @type {?} */
const _XmatTabLinkMixinBase = mixinTabIndex(mixinDisableRipple(mixinDisabled(XmatTabLinkMixinBase)));
/**
* Base class with all of the `MatTabLink` functionality.
*/
export class _XmatTabLinkBase extends _XmatTabLinkMixinBase {
/**
* @param {?} _tabNavBar
* @param {?} elementRef
* @param {?} globalRippleOptions
* @param {?} tabIndex
* @param {?} _focusMonitor
* @param {?=} animationMode
*/
constructor(_tabNavBar, elementRef, globalRippleOptions, tabIndex, _focusMonitor, animationMode) {
super();
this._tabNavBar = _tabNavBar;
this.elementRef = elementRef;
this._focusMonitor = _focusMonitor;
/**
* Whether the tab link is active or not.
*/
this._isActive = false;
this.rippleConfig = globalRippleOptions || {};
// tslint:disable-next-line:radix
this.tabIndex = parseInt(tabIndex) || 0;
if (animationMode === "NoopAnimations") {
this.rippleConfig.animation = { enterDuration: 0, exitDuration: 0 };
}
_focusMonitor.monitor(elementRef);
}
/**
* Whether the link is active.
* @return {?}
*/
get active() {
return this._isActive;
}
/**
* @param {?} value
* @return {?}
*/
set active(value) {
if (value !== this._isActive) {
this._isActive = value;
this._tabNavBar.updateActiveLink(this.elementRef);
}
}
/**
* Whether ripples are disabled on interaction.
* \@docs-private
* @return {?}
*/
get rippleDisabled() {
return this.disabled || this.disableRipple || this._tabNavBar.disableRipple ||
!!this.rippleConfig.disabled;
}
/**
* @return {?}
*/
focus() {
this.elementRef.nativeElement.focus();
}
/**
* @return {?}
*/
ngOnDestroy() {
this._focusMonitor.stopMonitoring(this.elementRef);
}
}
/** @nocollapse */
_XmatTabLinkBase.ctorParameters = () => [
{ type: _XmatTabNavBase },
{ type: ElementRef },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_RIPPLE_GLOBAL_OPTIONS,] }] },
{ type: String, decorators: [{ type: Attribute, args: ["tabindex",] }] },
{ type: FocusMonitor },
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
];
_XmatTabLinkBase.propDecorators = {
active: [{ type: Input }]
};
if (false) {
/**
* Whether the tab link is active or not.
* @type {?}
*/
_XmatTabLinkBase.prototype._isActive;
/**
* Ripple configuration for ripples that are launched on pointer down. The ripple config
* is set to the global ripple options since we don't have any configurable options for
* the tab link ripples.
* \@docs-private
* @type {?}
*/
_XmatTabLinkBase.prototype.rippleConfig;
/** @type {?} */
_XmatTabLinkBase.prototype._tabNavBar;
/** @type {?} */
_XmatTabLinkBase.prototype.elementRef;
/** @type {?} */
_XmatTabLinkBase.prototype._focusMonitor;
}
/**
* Link inside of a `mat-tab-nav-bar`.
*/
export class XmatTabLinkDirective extends _XmatTabLinkBase {
/**
* @param {?} tabNavBar
* @param {?} elementRef
* @param {?} ngZone
* @param {?} platform
* @param {?} globalRippleOptions
* @param {?} tabIndex
* @param {?} focusMonitor
* @param {?=} animationMode
*/
constructor(tabNavBar, elementRef, ngZone, platform, globalRippleOptions, tabIndex, focusMonitor, animationMode) {
super(tabNavBar, elementRef, globalRippleOptions, tabIndex, focusMonitor, animationMode);
this._tabLinkRipple = new RippleRenderer(this, ngZone, elementRef, platform);
this._tabLinkRipple.setupTriggerEvents(elementRef.nativeElement);
}
/**
* @return {?}
*/
ngOnDestroy() {
super.ngOnDestroy();
this._tabLinkRipple._removeTriggerEvents();
}
}
XmatTabLinkDirective.decorators = [
{ type: Directive, args: [{
selector: "[xmat-tab-link], [xmatTabLink]",
exportAs: "xmatTabLink",
// tslint:disable-next-line:use-input-property-decorator
inputs: ["disabled", "disableRipple", "tabIndex"],
host: {
"class": "mat-tab-link",
"[attr.aria-current]": "active ? \"page\" : null",
"[attr.aria-disabled]": "disabled",
"[attr.tabIndex]": "tabIndex",
"[class.mat-tab-disabled]": "disabled",
"[class.mat-tab-label-active]": "active",
}
},] }
];
/** @nocollapse */
XmatTabLinkDirective.ctorParameters = () => [
{ type: XmatTabNavComponent },
{ type: ElementRef },
{ type: NgZone },
{ type: Platform },
{ type: undefined, decorators: [{ type: Optional }, { type: Inject, args: [MAT_RIPPLE_GLOBAL_OPTIONS,] }] },
{ type: String, decorators: [{ type: Attribute, args: ["tabindex",] }] },
{ type: FocusMonitor },
{ type: String, decorators: [{ type: Optional }, { type: Inject, args: [ANIMATION_MODULE_TYPE,] }] }
];
if (false) {
/**
* Reference to the RippleRenderer for the tab-link.
* @type {?}
*/
XmatTabLinkDirective.prototype._tabLinkRipple;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoieG1hdC1uYXYtYmFyLmNvbXBvbmVudC5qcyIsInNvdXJjZVJvb3QiOiJuZzovL25neC1tYXQtbGliLyIsInNvdXJjZXMiOlsibGliL2NvbXBvbmVudHMveG1hdC1uYXYtYmFyL3htYXQtbmF2LWJhci5jb21wb25lbnQudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7QUFFQSxPQUFPLEVBQ0gsU0FBUyxFQUNULGlCQUFpQixFQUNqQix1QkFBdUIsRUFDdkIsaUJBQWlCLEVBQ2pCLFVBQVUsRUFDVixNQUFNLEVBQ04sU0FBUyxFQUNULEtBQUssRUFDTCxRQUFRLEVBR1IsZUFBZSxFQUNmLFNBQVMsRUFDVCxVQUFVLEVBRVYsU0FBUyxFQUNULE1BQU0sRUFDTixTQUFTLEdBQ1osTUFBTSxlQUFlLENBQUM7QUFDdkIsT0FBTyxFQUFDLHFCQUFxQixFQUFDLE1BQU0sc0NBQXNDLENBQUM7QUFDM0UsT0FBTyxFQUFDLGNBQWMsRUFBQyxNQUFNLG1CQUFtQixDQUFDO0FBQ2pELE9BQU8sRUFBQyxxQkFBcUIsRUFBQyxNQUFNLHVCQUF1QixDQUFDO0FBQzVELE9BQU8sRUFBQyxhQUFhLEVBQUMsTUFBTSxzQkFBc0IsQ0FBQztBQUNuRCxPQUFPLEVBQUMsWUFBWSxFQUFrQixNQUFNLG1CQUFtQixDQUFDO0FBQ2hFLE9BQU8sRUFBQyxRQUFRLEVBQUMsTUFBTSx1QkFBdUIsQ0FBQztBQUMvQyxPQUFPLEVBS0gsa0JBQWtCLEVBS2xCLHlCQUF5QixFQUV6QixjQUFjLEVBQ2QsYUFBYSxFQUViLGFBQWEsR0FFaEIsTUFBTSx3QkFBd0IsQ0FBQztBQUVoQyxPQUFPLEVBQUMsbUJBQW1CLEVBQUMsTUFBTSwwQkFBMEIsQ0FBQztBQUM3RCxPQUFPLEVBQUMsK0JBQStCLEVBQTZCLE1BQU0sNkJBQTZCLENBQUM7QUFFeEcsT0FBTyxFQUFDLFNBQVMsRUFBRSxTQUFTLEVBQUMsTUFBTSxnQkFBZ0IsQ0FBQzs7Ozs7O0FBT3BELE1BQU0sT0FBZ0IsZUFBZ0IsU0FBUSwrQkFB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cUIsRUFBRSwwQkFBMEI7b0JBQ2pELHNCQUFzQixFQUFFLFVBQVU7b0JBQ2xDLGlCQUFpQixFQUFFLFVBQVU7b0JBQzdCLDBCQUEwQixFQUFFLFVBQVU7b0JBQ3RDLDhCQUE4QixFQUFFLFFBQVE7aUJBQzNDO2FBQ0o7Ozs7WUFNa0IsbUJBQW1CO1lBMVJsQyxVQUFVO1lBQ1YsTUFBTTtZQW1CRixRQUFROzRDQXdRUCxRQUFRLFlBQUksTUFBTSxTQUFDLHlCQUF5Qjt5Q0FDNUMsU0FBUyxTQUFDLFVBQVU7WUExUXJCLFlBQVk7eUNBMlFYLFFBQVEsWUFBSSxNQUFNLFNBQUMscUJBQXFCIiwic291cmNlc0NvbnRlbnQiOlsiLy8gdHNsaW50OmRpc2FibGU6bWVtYmVyLW9yZGVyaW5nXG5cbmltcG9ydCB7XG4gICAgQ29tcG9uZW50LFxuICAgIFZpZXdFbmNhcHN1bGF0aW9uLFxuICAgIENoYW5nZURldGVjdGlvblN0cmF0ZWd5LFxuICAgIENoYW5nZURldGVjdG9yUmVmLFxuICAgIEVsZW1lbnRSZWYsXG4gICAgTmdab25lLFxuICAgIFZpZXdDaGlsZCxcbiAgICBJbnB1dCxcbiAgICBPcHRpb25hbCxcbiAgICBPbkRlc3Ryb3ksXG4gICAgQWZ0ZXJDb250ZW50Q2hlY2tlZCxcbiAgICBDb250ZW50Q2hpbGRyZW4sXG4gICAgUXVlcnlMaXN0LFxuICAgIGZvcndhcmRSZWYsXG4gICAgQWZ0ZXJDb250ZW50SW5pdCxcbiAgICBEaXJlY3RpdmUsXG4gICAgSW5qZWN0LFxuICAgIEF0dHJpYnV0ZSxcbn0gZnJvbSBcIkBhbmd1bGFyL2NvcmVcIjtcbmltcG9ydCB7QU5JTUFUSU9OX01PRFVMRV9UWVBFfSBmcm9tIFwiQGFuZ3VsYXIvcGxhdGZvcm0tYnJvd3Nlci9hbmltYXRpb25zXCI7XG5pbXBvcnQge0RpcmVjdGlvbmFsaXR5fSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2JpZGlcIjtcbmltcG9ydCB7Y29lcmNlQm9vbGVhblByb3BlcnR5fSBmcm9tIFwiQGFuZ3VsYXIvY2RrL2NvZXJjaW9uXCI7XG5pbXBvcnQge1ZpZXdwb3J0UnVsZXJ9IGZyb20gXCJAYW5ndWxhci9jZGsvb3ZlcmxheVwiO1xuaW1wb3J0IHtGb2N1c01vbml0b3IsIEZvY3VzYWJsZU9wdGlvbn0gZnJvbSBcIkBhbmd1bGFyL2Nkay9hMTF5XCI7XG5pbXBvcnQge1BsYXRmb3JtfSBmcm9tIFwiQGFuZ3VsYXIvY2RrL3BsYXRmb3JtXCI7XG5pbXBvcnQge1xuICAgIFRoZW1lUGFsZXR0ZSxcbiAgICBDYW5Db2xvcixcbiAgICBDYW5EaXNhYmxlUmlwcGxlLFxuICAgIENhbkRpc2FibGVSaXBwbGVDdG9yLFxuICAgIG1peGluRGlzYWJsZVJpcHBsZSxcbiAgICBSaXBwbGVUYXJnZXQsXG4gICAgQ2FuRGlzYWJsZSxcbiAgICBIYXNUYWJJbmRleCxcbiAgICBSaXBwbGVHbG9iYWxPcHRpb25zLFxuICAgIE1BVF9SSVBQTEVfR0xPQkFMX09QVElPTlMsXG4gICAgUmlwcGxlQ29uZmlnLFxuICAgIFJpcHBsZVJlbmRlcmVyLFxuICAgIG1peGluVGFiSW5kZXgsXG4gICAgQ2FuRGlzYWJsZUN0b3IsXG4gICAgbWl4aW5EaXNhYmxlZCxcbiAgICBIYXNUYWJJbmRleEN0b3IsXG59IGZyb20gXCJAYW5ndWxhci9tYXRlcmlhbC9jb3JlXCI7XG4vL1xuaW1wb3J0IHtYbWF0SW5rQmFyRGlyZWN0aXZlfSBmcm9tIFwiLi94bWF0LWluay1iYXIuZGlyZWN0aXZlXCI7XG5pbXBvcnQge1htYXRQYWdpbmF0ZWRUYWJIZWFkZXJEaXJlY3RpdmUsIFhtYXRQYWdpbmF0ZWRUYWJIZWFkZXJJdGVtfSBmcm9tIFwiLi94bWF0LXBhZ2luYXRlZC10YWItaGVhZGVyXCI7XG4vL1xuaW1wb3J0IHt0YWtlVW50aWwsIHN0YXJ0V2l0aH0gZnJvbSBcInJ4anMvb3BlcmF0b3JzXCI7XG5cbi8qKlxuICogQmFzZSBjbGFzcyB3aXRoIGFsbCBvZiB0aGUgYE1hdFRhYk5hdmAgZnVuY3Rpb25hbGl0eS5cbiAqIEBkb2NzLXByaXZhdGVcbiAqL1xuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOm5hbWluZy1jb252ZW50aW9uIGNsYXNzLW5hbWVcbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBfWG1hdFRhYk5hdkJhc2UgZXh0ZW5kcyBYbWF0UGFnaW5hdGVkVGFiSGVhZGVyRGlyZWN0aXZlXG4gICAgaW1wbGVtZW50cyBBZnRlckNvbnRlbnRDaGVja2VkLCBBZnRlckNvbnRlbnRJbml0LCBPbkRlc3Ryb3kge1xuXG4gICAgLyoqIFF1ZXJ5IGxpc3Qgb2YgYWxsIHRhYiBsaW5rcyBvZiB0aGUgdGFiIG5hdmlnYXRpb24uICovXG4gICAgYWJzdHJhY3QgX2l0ZW1zOiBRdWVyeUxpc3Q8WG1hdFBhZ2luYXRlZFRhYkhlYWRlckl0ZW0gJiB7IGFjdGl2ZTogYm9vbGVhbiB9PjtcblxuICAgIC8qKiBCYWNrZ3JvdW5kIGNvbG9yIG9mIHRoZSB0YWIgbmF2LiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IGJhY2tncm91bmRDb2xvcigpOiBUaGVtZVBhbGV0dGUge1xuICAgICAgICByZXR1cm4gdGhpcy5fYmFja2dyb3VuZENvbG9yO1xuICAgIH1cblxuICAgIHNldCBiYWNrZ3JvdW5kQ29sb3IodmFsdWU6IFRoZW1lUGFsZXR0ZSkge1xuICAgICAgICBjb25zdCBjbGFzc0xpc3QgPSB0aGlzLl9lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2xhc3NMaXN0O1xuICAgICAgICBjbGFzc0xpc3QucmVtb3ZlKGBtYXQtYmFja2dyb3VuZC0ke3RoaXMuYmFja2dyb3VuZENvbG9yfWApO1xuXG4gICAgICAgIGlmICh2YWx1ZSkge1xuICAgICAgICAgICAgY2xhc3NMaXN0LmFkZChgbWF0LWJhY2tncm91bmQtJHt2YWx1ZX1gKTtcbiAgICAgICAgfVxuXG4gICAgICAgIHRoaXMuX2JhY2tncm91bmRDb2xvciA9IHZhbHVlO1xuICAgIH1cblxuICAgIHByaXZhdGUgX2JhY2tncm91bmRDb2xvcjogVGhlbWVQYWxldHRlO1xuXG4gICAgLyoqIFdoZXRoZXIgdGhlIHJpcHBsZSBlZmZlY3QgaXMgZGlzYWJsZWQgb3Igbm90LiAqL1xuICAgIEBJbnB1dCgpXG4gICAgZ2V0IGRpc2FibGVSaXBwbGUoKSB7XG4gICAgICAgIHJldHVybiB0aGlzLl9kaXNhYmxlUmlwcGxlO1xuICAgIH1cblxuICAgIHNldCBkaXNhYmxlUmlwcGxlKHZhbHVlOiBhbnkpIHtcbiAgICAgICAgdGhpcy5fZGlzYWJsZVJpcHBsZSA9IGNvZXJjZUJvb2xlYW5Qcm9wZXJ0eSh2YWx1ZSk7XG4gICAgfVxuXG4gICAgcHJpdmF0ZSBfZGlzYWJsZVJpcHBsZTogYm9vbGVhbiA9IGZhbHNlO1xuXG4gICAgLyoqIFRoZW1lIGNvbG9yIG9mIHRoZSBuYXYgYmFyLiAqL1xuICAgIEBJbnB1dCgpIGNvbG9yOiBUaGVtZVBhbGV0dGUgPSBcInByaW1hcnlcIjtcblxuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgZGlyOiBEaXJlY3Rpb25hbGl0eSxcbiAgICAgICAgICAgICAgICBuZ1pvbmU6IE5nWm9uZSxcbiAgICAgICAgICAgICAgICBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgICAgICAgICAgdmlld3BvcnRSdWxlcjogVmlld3BvcnRSdWxlcixcbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBAZGVwcmVjYXRlZCBAYnJlYWtpbmctY2hhbmdlIDkuMC4wIGBwbGF0Zm9ybWAgcGFyYW1ldGVyIHRvIGJlY29tZSByZXF1aXJlZC5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBwbGF0Zm9ybT86IFBsYXRmb3JtLFxuICAgICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQU5JTUFUSU9OX01PRFVMRV9UWVBFKSBhbmltYXRpb25Nb2RlPzogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGVsZW1lbnRSZWYsIGNoYW5nZURldGVjdG9yUmVmLCB2aWV3cG9ydFJ1bGVyLCBkaXIsIG5nWm9uZSwgcGxhdGZvcm0sIGFuaW1hdGlvbk1vZGUpO1xuICAgIH1cblxuICAgIHByb3RlY3RlZCBfaXRlbVNlbGVjdGVkKCkge1xuICAgICAgICAvLyBub29wXG4gICAgfVxuXG4gICAgbmdBZnRlckNvbnRlbnRJbml0KCkge1xuICAgICAgICAvLyBXZSBuZWVkIHRoaXMgdG8gcnVuIGJlZm9yZSB0aGUgYGNoYW5nZXNgIHN1YnNjcmlwdGlvbiBpbiBwYXJlbnQgdG8gZW5zdXJlIHRoYXQgdGhlXG4gICAgICAgIC8vIHNlbGVjdGVkSW5kZXggaXMgdXAtdG8tZGF0ZSBieSB0aGUgdGltZSB0aGUgc3VwZXIgY2xhc3Mgc3RhcnRzIGxvb2tpbmcgZm9yIGl0LlxuICAgICAgICB0aGlzLl9pdGVtcy5jaGFuZ2VzLnBpcGUoc3RhcnRXaXRoKG51bGwpLCB0YWtlVW50aWwodGhpcy5fZGVzdHJveWVkKSkuc3Vic2NyaWJlKCgpID0+IHtcbiAgICAgICAgICAgIHRoaXMudXBkYXRlQWN0aXZlTGluaygpO1xuICAgICAgICB9KTtcblxuICAgICAgICBzdXBlci5uZ0FmdGVyQ29udGVudEluaXQoKTtcbiAgICB9XG5cbiAgICAvKipcbiAgICAgKiBOb3RpZmllcyB0aGUgY29tcG9uZW50IHRoYXQgdGhlIGFjdGl2ZSBsaW5rIGhhcyBiZWVuIGNoYW5nZWQuXG4gICAgICogQGJyZWFraW5nLWNoYW5nZSA4LjAuMCBgZWxlbWVudGAgcGFyYW1ldGVyIHRvIGJlIHJlbW92ZWQuXG4gICAgICovXG4gICAgdXBkYXRlQWN0aXZlTGluayhfZWxlbWVudD86IEVsZW1lbnRSZWYpIHtcbiAgICAgICAgaWYgKCF0aGlzLl9pdGVtcykge1xuICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICB9XG5cbiAgICAgICAgY29uc3QgaXRlbXMgPSB0aGlzLl9pdGVtcy50b0FycmF5KCk7XG5cbiAgICAgICAgZm9yIChsZXQgaSA9IDA7IGkgPCBpdGVtcy5sZW5ndGg7IGkrKykge1xuICAgICAgICAgICAgaWYgKGl0ZW1zW2ldLmFjdGl2ZSkge1xuICAgICAgICAgICAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IGk7XG4gICAgICAgICAgICAgICAgdGhpcy5fY2hhbmdlRGV0ZWN0b3JSZWYubWFya0ZvckNoZWNrKCk7XG4gICAgICAgICAgICAgICAgcmV0dXJuO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG5cbiAgICAgICAgLy8gVGhlIGluayBiYXIgc2hvdWxkIGhpZGUgaXRzZWxmIGlmIG5vIGl0ZW1zIGFyZSBhY3RpdmUuXG4gICAgICAgIHRoaXMuc2VsZWN0ZWRJbmRleCA9IC0xO1xuICAgICAgICB0aGlzLl9pbmtCYXIuaGlkZSgpO1xuICAgIH1cbn1cblxuXG5AQ29tcG9uZW50KHtcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y29tcG9uZW50LXNlbGVjdG9yXG4gICAgc2VsZWN0b3I6IFwiW3htYXQtdGFiLW5hdi1iYXJdXCIsXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOnVzZS1pbnB1dC1wcm9wZXJ0eS1kZWNvcmF0b3JcbiAgICBpbnB1dHM6IFtcImNvbG9yXCIsIFwiZGlzYWJsZVJpcHBsZVwiXSxcbiAgICB0ZW1wbGF0ZVVybDogXCJ4bWF0LW5hdi1iYXIuY29tcG9uZW50Lmh0bWxcIixcbiAgICBzdHlsZVVybHM6IFtcInhtYXQtbmF2LWJhci5jb21wb25lbnQuc2Nzc1wiXSxcbiAgICAvLyBob3N0OiB7XCJjbGFzc1wiOiBcIm1hdC10YWItbmF2LWJhclwifSxcbiAgICBob3N0OiB7XG4gICAgICAgIFwiY2xhc3NcIjogXCJtYXQtdGFiLW5hdi1iYXIgbWF0LXRhYi1oZWFkZXJcIixcbiAgICAgICAgXCJbY2xhc3MubWF0LXRhYi1oZWFkZXItcGFnaW5hdGlvbi1jb250cm9scy1lbmFibGVkXVwiOiBcIl9zaG93UGFnaW5hdGlvbkNvbnRyb2xzXCIsXG4gICAgICAgIFwiW2NsYXNzLm1hdC10YWItaGVhZGVyLXJ0bF1cIjogXCJfZ2V0TGF5b3V0RGlyZWN0aW9uKCkgPT0gXFxcInJ0bFxcXCJcIixcbiAgICAgICAgXCJbY2xhc3MubWF0LXByaW1hcnldXCI6IFwiY29sb3IgIT09IFxcXCJ3YXJuXFxcIiAmJiBjb2xvciAhPT0gXFxcImFjY2VudFxcXCJcIixcbiAgICAgICAgXCJbY2xhc3MubWF0LWFjY2VudF1cIjogXCJjb2xvciA9PT0gXFxcImFjY2VudFxcXCJcIixcbiAgICAgICAgXCJbY2xhc3MubWF0LXdhcm5dXCI6IFwiY29sb3IgPT09IFxcXCJ3YXJuXFxcIlwiLFxuICAgIH0sXG4gICAgZW5jYXBzdWxhdGlvbjogVmlld0VuY2Fwc3VsYXRpb24uTm9uZSxcbiAgICBjaGFuZ2VEZXRlY3Rpb246IENoYW5nZURldGVjdGlvblN0cmF0ZWd5Lk9uUHVzaCxcbn0pXG5leHBvcnQgY2xhc3MgWG1hdFRhYk5hdkNvbXBvbmVudCBleHRlbmRzIF9YbWF0VGFiTmF2QmFzZVxuICAgIGltcGxlbWVudHMgQWZ0ZXJDb250ZW50Q2hlY2tlZCwgQWZ0ZXJDb250ZW50SW5pdCwgQ2FuQ29sb3IsIENhbkRpc2FibGVSaXBwbGUsIE9uRGVzdHJveSB7XG5cbiAgICBAQ29udGVudENoaWxkcmVuKGZvcndhcmRSZWYoKCkgPT4gWG1hdFRhYkxpbmtEaXJlY3RpdmUpLCB7ZGVzY2VuZGFudHM6IHRydWV9KSBfaXRlbXM6IFF1ZXJ5TGlzdDxYbWF0VGFiTGlua0RpcmVjdGl2ZT47XG4gICAgQFZpZXdDaGlsZChYbWF0SW5rQmFyRGlyZWN0aXZlKSBfaW5rQmFyOiBYbWF0SW5rQmFyRGlyZWN0aXZlO1xuICAgIEBWaWV3Q2hpbGQoXCJ0YWJMaXN0Q29udGFpbmVyXCIpIF90YWJMaXN0Q29udGFpbmVyOiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoXCJ0YWJMaXN0XCIpIF90YWJMaXN0OiBFbGVtZW50UmVmO1xuICAgIEBWaWV3Q2hpbGQoXCJuZXh0UGFnaW5hdG9yXCIpIF9uZXh0UGFnaW5hdG9yOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcbiAgICBAVmlld0NoaWxkKFwicHJldmlvdXNQYWdpbmF0b3JcIikgX3ByZXZpb3VzUGFnaW5hdG9yOiBFbGVtZW50UmVmPEhUTUxFbGVtZW50PjtcblxuICAgIGNvbnN0cnVjdG9yKGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsXG4gICAgICAgICAgICAgICAgQE9wdGlvbmFsKCkgZGlyOiBEaXJlY3Rpb25hbGl0eSxcbiAgICAgICAgICAgICAgICBuZ1pvbmU6IE5nWm9uZSxcbiAgICAgICAgICAgICAgICBjaGFuZ2VEZXRlY3RvclJlZjogQ2hhbmdlRGV0ZWN0b3JSZWYsXG4gICAgICAgICAgICAgICAgdmlld3BvcnRSdWxlcjogVmlld3BvcnRSdWxlcixcbiAgICAgICAgICAgICAgICAvKipcbiAgICAgICAgICAgICAgICAgKiBAZGVwcmVjYXRlZCBAYnJlYWtpbmctY2hhbmdlIDkuMC4wIGBwbGF0Zm9ybWAgcGFyYW1ldGVyIHRvIGJlY29tZSByZXF1aXJlZC5cbiAgICAgICAgICAgICAgICAgKi9cbiAgICAgICAgICAgICAgICBAT3B0aW9uYWwoKSBwbGF0Zm9ybT86IFBsYXRmb3JtLFxuICAgICAgICAgICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQU5JTUFUSU9OX01PRFVMRV9UWVBFKSBhbmltYXRpb25Nb2RlPzogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKGVsZW1lbnRSZWYsIGRpciwgbmdab25lLCBjaGFuZ2VEZXRlY3RvclJlZiwgdmlld3BvcnRSdWxlciwgcGxhdGZvcm0sIGFuaW1hdGlvbk1vZGUpO1xuICAgIH1cbn1cblxuXG4vLyBCb2lsZXJwbGF0ZSBmb3IgYXBwbHlpbmcgbWl4aW5zIHRvIE1hdFRhYkxpbmsuXG5jbGFzcyBYbWF0VGFiTGlua01peGluQmFzZSB7XG59XG5cbmNvbnN0IF9YbWF0VGFiTGlua01peGluQmFzZTpcbiAgICBIYXNUYWJJbmRleEN0b3IgJiBDYW5EaXNhYmxlUmlwcGxlQ3RvciAmIENhbkRpc2FibGVDdG9yICYgdHlwZW9mIFhtYXRUYWJMaW5rTWl4aW5CYXNlID1cbiAgICBtaXhpblRhYkluZGV4KG1peGluRGlzYWJsZVJpcHBsZShtaXhpbkRpc2FibGVkKFhtYXRUYWJMaW5rTWl4aW5CYXNlKSkpO1xuXG4vKiogQmFzZSBjbGFzcyB3aXRoIGFsbCBvZiB0aGUgYE1hdFRhYkxpbmtgIGZ1bmN0aW9uYWxpdHkuICovXG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6Y2xhc3MtbmFtZSBuYW1pbmctY29udmVudGlvblxuZXhwb3J0IGNsYXNzIF9YbWF0VGFiTGlua0Jhc2UgZXh0ZW5kcyBfWG1hdFRhYkxpbmtNaXhpbkJhc2UgaW1wbGVtZW50cyBPbkRlc3Ryb3ksIENhbkRpc2FibGUsXG4gICAgQ2FuRGlzYWJsZVJpcHBsZSwgSGFzVGFiSW5kZXgsIFJpcHBsZVRhcmdldCwgRm9jdXNhYmxlT3B0aW9uIHtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSB0YWIgbGluayBpcyBhY3RpdmUgb3Igbm90LiAqL1xuICAgIHByb3RlY3RlZCBfaXNBY3RpdmU6IGJvb2xlYW4gPSBmYWxzZTtcblxuICAgIC8qKiBXaGV0aGVyIHRoZSBsaW5rIGlzIGFjdGl2ZS4gKi9cbiAgICBASW5wdXQoKVxuICAgIGdldCBhY3RpdmUoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLl9pc0FjdGl2ZTtcbiAgICB9XG5cbiAgICBzZXQgYWN0aXZlKHZhbHVlOiBib29sZWFuKSB7XG4gICAgICAgIGlmICh2YWx1ZSAhPT0gdGhpcy5faXNBY3RpdmUpIHtcbiAgICAgICAgICAgIHRoaXMuX2lzQWN0aXZlID0gdmFsdWU7XG4gICAgICAgICAgICB0aGlzLl90YWJOYXZCYXIudXBkYXRlQWN0aXZlTGluayh0aGlzLmVsZW1lbnRSZWYpO1xuICAgICAgICB9XG4gICAgfVxuXG4gICAgLyoqXG4gICAgICogUmlwcGxlIGNvbmZpZ3VyYXRpb24gZm9yIHJpcHBsZXMgdGhhdCBhcmUgbGF1bmNoZWQgb24gcG9pbnRlciBkb3duLiBUaGUgcmlwcGxlIGNvbmZpZ1xuICAgICAqIGlzIHNldCB0byB0aGUgZ2xvYmFsIHJpcHBsZSBvcHRpb25zIHNpbmNlIHdlIGRvbid0IGhhdmUgYW55IGNvbmZpZ3VyYWJsZSBvcHRpb25zIGZvclxuICAgICAqIHRoZSB0YWIgbGluayByaXBwbGVzLlxuICAgICAqIEBkb2NzLXByaXZhdGVcbiAgICAgKi9cbiAgICByaXBwbGVDb25maWc6IFJpcHBsZUNvbmZpZyAmIFJpcHBsZUdsb2JhbE9wdGlvbnM7XG5cbiAgICAvKipcbiAgICAgKiBXaGV0aGVyIHJpcHBsZXMgYXJlIGRpc2FibGVkIG9uIGludGVyYWN0aW9uLlxuICAgICAqIEBkb2NzLXByaXZhdGVcbiAgICAgKi9cbiAgICBnZXQgcmlwcGxlRGlzYWJsZWQoKTogYm9vbGVhbiB7XG4gICAgICAgIHJldHVybiB0aGlzLmRpc2FibGVkIHx8IHRoaXMuZGlzYWJsZVJpcHBsZSB8fCB0aGlzLl90YWJOYXZCYXIuZGlzYWJsZVJpcHBsZSB8fFxuICAgICAgICAgICAgISF0aGlzLnJpcHBsZUNvbmZpZy5kaXNhYmxlZDtcbiAgICB9XG5cbiAgICBjb25zdHJ1Y3RvcihcbiAgICAgICAgcHJpdmF0ZSBfdGFiTmF2QmFyOiBfWG1hdFRhYk5hdkJhc2UsIHB1YmxpYyBlbGVtZW50UmVmOiBFbGVtZW50UmVmLFxuICAgICAgICBAT3B0aW9uYWwoKSBASW5qZWN0KE1BVF9SSVBQTEVfR0xPQkFMX09QVElPTlMpIGdsb2JhbFJpcHBsZU9wdGlvbnM6IFJpcHBsZUdsb2JhbE9wdGlvbnMgfCBudWxsLFxuICAgICAgICBAQXR0cmlidXRlKFwidGFiaW5kZXhcIikgdGFiSW5kZXg6IHN0cmluZywgcHJpdmF0ZSBfZm9jdXNNb25pdG9yOiBGb2N1c01vbml0b3IsXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoQU5JTUFUSU9OX01PRFVMRV9UWVBFKSBhbmltYXRpb25Nb2RlPzogc3RyaW5nKSB7XG4gICAgICAgIHN1cGVyKCk7XG5cbiAgICAgICAgdGhpcy5yaXBwbGVDb25maWcgPSBnbG9iYWxSaXBwbGVPcHRpb25zIHx8IHt9O1xuICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6cmFkaXhcbiAgICAgICAgdGhpcy50YWJJbmRleCA9IHBhcnNlSW50KHRhYkluZGV4KSB8fCAwO1xuXG4gICAgICAgIGlmIChhbmltYXRpb25Nb2RlID09PSBcIk5vb3BBbmltYXRpb25zXCIpIHtcbiAgICAgICAgICAgIHRoaXMucmlwcGxlQ29uZmlnLmFuaW1hdGlvbiA9IHtlbnRlckR1cmF0aW9uOiAwLCBleGl0RHVyYXRpb246IDB9O1xuICAgICAgICB9XG5cbiAgICAgICAgX2ZvY3VzTW9uaXRvci5tb25pdG9yKGVsZW1lbnRSZWYpO1xuICAgIH1cblxuICAgIGZvY3VzKCkge1xuICAgICAgICB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudC5mb2N1cygpO1xuICAgIH1cblxuICAgIG5nT25EZXN0cm95KCkge1xuICAgICAgICB0aGlzLl9mb2N1c01vbml0b3Iuc3RvcE1vbml0b3JpbmcodGhpcy5lbGVtZW50UmVmKTtcbiAgICB9XG59XG5cbi8qKlxuICogTGluayBpbnNpZGUgb2YgYSBgbWF0LXRhYi1uYXYtYmFyYC5cbiAqL1xuQERpcmVjdGl2ZSh7XG4gICAgc2VsZWN0b3I6IFwiW3htYXQtdGFiLWxpbmtdLCBbeG1hdFRhYkxpbmtdXCIsXG4gICAgZXhwb3J0QXM6IFwieG1hdFRhYkxpbmtcIixcbiAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmU6dXNlLWlucHV0LXByb3BlcnR5LWRlY29yYXRvclxuICAgIGlucHV0czogW1wiZGlzYWJsZWRcIiwgXCJkaXNhYmxlUmlwcGxlXCIsIFwidGFiSW5kZXhcIl0sXG4gICAgaG9zdDoge1xuICAgICAgICBcImNsYXNzXCI6IFwibWF0LXRhYi1saW5rXCIsXG4gICAgICAgIFwiW2F0dHIuYXJpYS1jdXJyZW50XVwiOiBcImFjdGl2ZSA/IFxcXCJwYWdlXFxcIiA6IG51bGxcIixcbiAgICAgICAgXCJbYXR0ci5hcmlhLWRpc2FibGVkXVwiOiBcImRpc2FibGVkXCIsXG4gICAgICAgIFwiW2F0dHIudGFiSW5kZXhdXCI6IFwidGFiSW5kZXhcIixcbiAgICAgICAgXCJbY2xhc3MubWF0LXRhYi1kaXNhYmxlZF1cIjogXCJkaXNhYmxlZFwiLFxuICAgICAgICBcIltjbGFzcy5tYXQtdGFiLWxhYmVsLWFjdGl2ZV1cIjogXCJhY3RpdmVcIixcbiAgICB9XG59KVxuZXhwb3J0IGNsYXNzIFhtYXRUYWJMaW5rRGlyZWN0aXZlIGV4dGVuZHMgX1htYXRUYWJMaW5rQmFzZSBpbXBsZW1lbnRzIE9uRGVzdHJveSB7XG4gICAgLyoqIFJlZmVyZW5jZSB0byB0aGUgUmlwcGxlUmVuZGVyZXIgZm9yIHRoZSB0YWItbGluay4gKi9cbiAgICBwcml2YXRlIF90YWJMaW5rUmlwcGxlOiBSaXBwbGVSZW5kZXJlcjtcblxuICAgIGNvbnN0cnVjdG9yKFxuICAgICAgICB0YWJOYXZCYXI6IFhtYXRUYWJOYXZDb21wb25lbnQsIGVsZW1lbnRSZWY6IEVsZW1lbnRSZWYsIG5nWm9uZTogTmdab25lLFxuICAgICAgICBwbGF0Zm9ybTogUGxhdGZvcm0sXG4gICAgICAgIEBPcHRpb25hbCgpIEBJbmplY3QoTUFUX1JJUFBMRV9HTE9CQUxfT1BUSU9OUykgZ2xvYmFsUmlwcGxlT3B0aW9uczogUmlwcGxlR2xvYmFsT3B0aW9ucyB8IG51bGwsXG4gICAgICAgIEBBdHRyaWJ1dGUoXCJ0YWJpbmRleFwiKSB0YWJJbmRleDogc3RyaW5nLCBmb2N1c01vbml0b3I6IEZvY3VzTW9uaXRvcixcbiAgICAgICAgQE9wdGlvbmFsKCkgQEluamVjdChBTklNQVRJT05fTU9EVUxFX1RZUEUpIGFuaW1hdGlvbk1vZGU/OiBzdHJpbmcpIHtcbiAgICAgICAgc3VwZXIodGFiTmF2QmFyLCBlbGVtZW50UmVmLCBnbG9iYWxSaXBwbGVPcHRpb25zLCB0YWJJbmRleCwgZm9jdXNNb25pdG9yLCBhbmltYXRpb25Nb2RlKTtcbiAgICAgICAgdGhpcy5fdGFiTGlua1JpcHBsZSA9IG5ldyBSaXBwbGVSZW5kZXJlcih0aGlzLCBuZ1pvbmUsIGVsZW1lbnRSZWYsIHBsYXRmb3JtKTtcbiAgICAgICAgdGhpcy5fdGFiTGlua1JpcHBsZS5zZXR1cFRyaWdnZXJFdmVudHMoZWxlbWVudFJlZi5uYXRpdmVFbGVtZW50KTtcbiAgICB9XG5cbiAgICBuZ09uRGVzdHJveSgpIHtcbiAgICAgICAgc3VwZXIubmdPbkRlc3Ryb3koKTtcbiAgICAgICAgdGhpcy5fdGFiTGlua1JpcHBsZS5fcmVtb3ZlVHJpZ2dlckV2ZW50cygpO1xuICAgIH1cbn1cbiJdfQ==