UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

722 lines 52.8 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ import * as tslib_1 from "tslib"; /* * @license * Copyright Akveo. All Rights Reserved. * Licensed under the MIT License. See License.txt in the project root for license information. */ import { Component, HostBinding, Input, ElementRef } from '@angular/core'; import { takeWhile } from 'rxjs/operators'; import { convertToBoolProperty } from '../helpers'; import { NbThemeService } from '../../services/theme.service'; import { NbSidebarService } from './sidebar.service'; /* * Sidebar header container. * * Placeholder which contains a sidebar header content, * placed at the very top of the sidebar outside of the scroll area. */ var NbSidebarHeaderComponent = /** @class */ (function () { function NbSidebarHeaderComponent() { } NbSidebarHeaderComponent.decorators = [ { type: Component, args: [{ selector: 'nb-sidebar-header', template: "\n <ng-content></ng-content>\n " }] } ]; return NbSidebarHeaderComponent; }()); export { NbSidebarHeaderComponent }; /* * Sidebar footer container. * * Placeholder which contains a sidebar footer content, * placed at the very bottom of the sidebar outside of the scroll area. */ var NbSidebarFooterComponent = /** @class */ (function () { function NbSidebarFooterComponent() { } NbSidebarFooterComponent.decorators = [ { type: Component, args: [{ selector: 'nb-sidebar-footer', template: "\n <ng-content></ng-content>\n " }] } ]; return NbSidebarFooterComponent; }()); export { NbSidebarFooterComponent }; /* * Layout sidebar component. * * @stacked-example(Showcase, sidebar/sidebar-showcase.component) * * ### Installation * * Import `NbSidebarModule.forRoot()` to your app module. * ```ts * @NgModule({ * imports: [ * // ... * NbSidebarModule.forRoot(), * ], * }) * export class AppModule { } * ``` * and `NbSidebarModule` to your feature module where the component should be shown: * ```ts * @NgModule({ * imports: [ * // ... * NbSidebarModule, * ], * }) * export class PageModule { } * ``` * ### Usage * * Sidebar can be placed on the left or the right side of the layout, * or on start/end position of layout (depends on document direction, left to right or right to left) * It can be fixed (shown above the content) or can push the layout when opened. * * There are three states - `expanded`, `collapsed`, `compacted`. * By default sidebar content is fixed and saves its position while the page is being scrolled. * * Compacted sidebar example: * @stacked-example(Compacted Sidebar, sidebar/sidebar-compacted.component) * * Sidebar also supports a `responsive` behavior, listening to window size change and changing its size respectably. * * In a pair with header it is possible to setup a configuration when header is placed on a side of the sidebar * and not on top of it. To achieve this simply put a `subheader` property to the header like this: * ```html * <nb-layout-header subheader></nb-layout-header> * ``` * @stacked-example(Subheader, layout/layout-sidebar-subheader.component) * Note that in such configuration sidebar shadow is removed and header cannot be make `fixed`. * * @additional-example(Right Sidebar, sidebar/sidebar-right.component) * @additional-example(Fixed Sidebar, sidebar/sidebar-fixed.component) * * @styles * * sidebar-font-size: Sidebar content font size * sidebar-line-height: Sidebar content line height * sidebar-fg: Foreground color * sidebar-bg: Background color * sidebar-height: Content height * sidebar-width: Expanded width * sidebar-width-compact: Compacted width * sidebar-padding: Sidebar content padding * sidebar-header-height: Sidebar header height * sidebar-footer-height: Sidebar footer height * sidebar-shadow: Sidebar container shadow * */ var NbSidebarComponent = /** @class */ (function () { function NbSidebarComponent(sidebarService, themeService, element) { this.sidebarService = sidebarService; this.themeService = themeService; this.element = element; this.responsiveValue = false; this.alive = true; this.containerFixedValue = true; this.fixedValue = false; this.rightValue = false; this.leftValue = true; this.startValue = false; this.endValue = false; // TODO: get width by the key and define only max width for the tablets and mobiles /* * Controls on which screen sizes sidebar should be switched to compacted state. * Works only when responsive mode is on. * Default values are `['xs', 'is', 'sm', 'md', 'lg']`. * * @type string[] */ this.compactedBreakpoints = ['xs', 'is', 'sm', 'md', 'lg']; /* * Controls on which screen sizes sidebar should be switched to collapsed state. * Works only when responsive mode is on. * Default values are `['xs', 'is']`. * * @type string[] */ this.collapsedBreakpoints = ['xs', 'is']; this.responsiveState = NbSidebarComponent.RESPONSIVE_STATE_PC; } Object.defineProperty(NbSidebarComponent.prototype, "expanded", { // TODO: rename stateValue to state (take a look to the card component) get: // TODO: rename stateValue to state (take a look to the card component) /** * @return {?} */ function () { return this.stateValue === NbSidebarComponent.STATE_EXPANDED; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "collapsed", { get: /** * @return {?} */ function () { return this.stateValue === NbSidebarComponent.STATE_COLLAPSED; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "compacted", { get: /** * @return {?} */ function () { return this.stateValue === NbSidebarComponent.STATE_COMPACTED; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "right", { /* * Places sidebar on the right side * @type {boolean} */ set: /* * Places sidebar on the right side * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.rightValue = convertToBoolProperty(val); this.leftValue = !this.rightValue; this.startValue = false; this.endValue = false; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "left", { /* * Places sidebar on the left side * @type {boolean} */ set: /* * Places sidebar on the left side * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.leftValue = convertToBoolProperty(val); this.rightValue = !this.leftValue; this.startValue = false; this.endValue = false; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "start", { /* * Places sidebar on the start edge of layout * @type {boolean} */ set: /* * Places sidebar on the start edge of layout * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.startValue = convertToBoolProperty(val); this.endValue = !this.startValue; this.leftValue = false; this.rightValue = false; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "end", { /* * Places sidebar on the end edge of layout * @type {boolean} */ set: /* * Places sidebar on the end edge of layout * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.endValue = convertToBoolProperty(val); this.startValue = !this.endValue; this.leftValue = false; this.rightValue = false; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "fixed", { /* * Makes sidebar fixed (shown above the layout content) * @type {boolean} */ set: /* * Makes sidebar fixed (shown above the layout content) * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.fixedValue = convertToBoolProperty(val); }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "containerFixed", { /* * Makes sidebar container fixed * @type {boolean} */ set: /* * Makes sidebar container fixed * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.containerFixedValue = convertToBoolProperty(val); }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "state", { /* * Initial sidebar state, `expanded`|`collapsed`|`compacted` * @type {string} */ set: /* * Initial sidebar state, `expanded`|`collapsed`|`compacted` * @type {string} */ /** * @param {?} val * @return {?} */ function (val) { this.stateValue = val; }, enumerable: true, configurable: true }); Object.defineProperty(NbSidebarComponent.prototype, "responsive", { /* * Makes sidebar listen to media query events and change its behaviour * @type {boolean} */ set: /* * Makes sidebar listen to media query events and change its behaviour * @type {boolean} */ /** * @param {?} val * @return {?} */ function (val) { this.responsiveValue = convertToBoolProperty(val); }, enumerable: true, configurable: true }); /** * @param {?} enabled * @return {?} */ NbSidebarComponent.prototype.toggleResponsive = /** * @param {?} enabled * @return {?} */ function (enabled) { if (enabled) { this.mediaQuerySubscription = this.onMediaQueryChanges(); } else if (this.mediaQuerySubscription) { this.mediaQuerySubscription.unsubscribe(); } }; /** * @param {?} changes * @return {?} */ NbSidebarComponent.prototype.ngOnChanges = /** * @param {?} changes * @return {?} */ function (changes) { if (changes.responsive) { this.toggleResponsive(this.responsiveValue); } }; /** * @return {?} */ NbSidebarComponent.prototype.ngOnInit = /** * @return {?} */ function () { var _this = this; this.sidebarService.onToggle() .pipe(takeWhile(function () { return _this.alive; })) .subscribe(function (data) { if (!_this.tag || _this.tag === data.tag) { _this.toggle(data.compact); } }); this.sidebarService.onExpand() .pipe(takeWhile(function () { return _this.alive; })) .subscribe(function (data) { if (!_this.tag || _this.tag === data.tag) { _this.expand(); } }); this.sidebarService.onCollapse() .pipe(takeWhile(function () { return _this.alive; })) .subscribe(function (data) { if (!_this.tag || _this.tag === data.tag) { _this.collapse(); } }); }; /** * @return {?} */ NbSidebarComponent.prototype.ngOnDestroy = /** * @return {?} */ function () { this.alive = false; if (this.mediaQuerySubscription) { this.mediaQuerySubscription.unsubscribe(); } }; // TODO: this is more of a workaround, should be a better way to make components communicate to each other // TODO: this is more of a workaround, should be a better way to make components communicate to each other /** * @param {?} event * @return {?} */ NbSidebarComponent.prototype.onClick = // TODO: this is more of a workaround, should be a better way to make components communicate to each other /** * @param {?} event * @return {?} */ function (event) { /** @type {?} */ var menu = this.element.nativeElement.querySelector('nb-menu'); if (menu && menu.contains(event.target)) { /** @type {?} */ var link = event.target; /** @type {?} */ var linkChildren = ['span', 'i']; // if we clicked on span - get the link if (linkChildren.includes(link.tagName.toLowerCase()) && link.parentNode) { link = event.target.parentNode; } // we only expand if an item has children if (link && link.nextElementSibling && link.nextElementSibling.classList.contains('menu-items')) { this.expand(); } } }; /* * Collapses the sidebar */ /* * Collapses the sidebar */ /** * @return {?} */ NbSidebarComponent.prototype.collapse = /* * Collapses the sidebar */ /** * @return {?} */ function () { this.state = NbSidebarComponent.STATE_COLLAPSED; }; /* * Expands the sidebar */ /* * Expands the sidebar */ /** * @return {?} */ NbSidebarComponent.prototype.expand = /* * Expands the sidebar */ /** * @return {?} */ function () { this.state = NbSidebarComponent.STATE_EXPANDED; }; /* * Compacts the sidebar (minimizes) */ /* * Compacts the sidebar (minimizes) */ /** * @return {?} */ NbSidebarComponent.prototype.compact = /* * Compacts the sidebar (minimizes) */ /** * @return {?} */ function () { this.state = NbSidebarComponent.STATE_COMPACTED; }; /* * Toggles sidebar state (expanded|collapsed|compacted) * @param {boolean} compact If true, then sidebar state will be changed between expanded & compacted, * otherwise - between expanded & collapsed. False by default. * * Toggle sidebar state * * ```ts * this.sidebar.toggle(true); * ``` */ /* * Toggles sidebar state (expanded|collapsed|compacted) * @param {boolean} compact If true, then sidebar state will be changed between expanded & compacted, * otherwise - between expanded & collapsed. False by default. * * Toggle sidebar state * * ```ts * this.sidebar.toggle(true); * ``` */ /** * @param {?=} compact * @return {?} */ NbSidebarComponent.prototype.toggle = /* * Toggles sidebar state (expanded|collapsed|compacted) * @param {boolean} compact If true, then sidebar state will be changed between expanded & compacted, * otherwise - between expanded & collapsed. False by default. * * Toggle sidebar state * * ```ts * this.sidebar.toggle(true); * ``` */ /** * @param {?=} compact * @return {?} */ function (compact) { if (compact === void 0) { compact = false; } if (this.responsiveEnabled()) { if (this.responsiveState === NbSidebarComponent.RESPONSIVE_STATE_MOBILE) { compact = false; } } /** @type {?} */ var closedStates = [NbSidebarComponent.STATE_COMPACTED, NbSidebarComponent.STATE_COLLAPSED]; if (compact) { this.state = closedStates.includes(this.stateValue) ? NbSidebarComponent.STATE_EXPANDED : NbSidebarComponent.STATE_COMPACTED; } else { this.state = closedStates.includes(this.stateValue) ? NbSidebarComponent.STATE_EXPANDED : NbSidebarComponent.STATE_COLLAPSED; } }; /** * @protected * @return {?} */ NbSidebarComponent.prototype.onMediaQueryChanges = /** * @protected * @return {?} */ function () { var _this = this; return this.themeService.onMediaQueryChange() .subscribe(function (_a) { var _b = tslib_1.__read(_a, 2), prev = _b[0], current = _b[1]; /** @type {?} */ var isCollapsed = _this.collapsedBreakpoints.includes(current.name); /** @type {?} */ var isCompacted = _this.compactedBreakpoints.includes(current.name); if (isCompacted) { _this.fixed = _this.containerFixedValue; _this.compact(); _this.responsiveState = NbSidebarComponent.RESPONSIVE_STATE_TABLET; } if (isCollapsed) { _this.fixed = true; _this.collapse(); _this.responsiveState = NbSidebarComponent.RESPONSIVE_STATE_MOBILE; } if (!isCollapsed && !isCompacted && prev.width < current.width) { _this.expand(); _this.fixed = false; _this.responsiveState = NbSidebarComponent.RESPONSIVE_STATE_PC; } }); }; /** * @protected * @return {?} */ NbSidebarComponent.prototype.responsiveEnabled = /** * @protected * @return {?} */ function () { return this.responsiveValue; }; NbSidebarComponent.STATE_EXPANDED = 'expanded'; NbSidebarComponent.STATE_COLLAPSED = 'collapsed'; NbSidebarComponent.STATE_COMPACTED = 'compacted'; NbSidebarComponent.RESPONSIVE_STATE_MOBILE = 'mobile'; NbSidebarComponent.RESPONSIVE_STATE_TABLET = 'tablet'; NbSidebarComponent.RESPONSIVE_STATE_PC = 'pc'; NbSidebarComponent.decorators = [ { type: Component, args: [{ selector: 'nb-sidebar', template: "\n <div class=\"main-container\"\n [class.main-container-fixed]=\"containerFixedValue\">\n <ng-content select=\"nb-sidebar-header\"></ng-content>\n <div class=\"scrollable\" (click)=\"onClick($event)\">\n <ng-content></ng-content>\n </div>\n <ng-content select=\"nb-sidebar-footer\"></ng-content>\n </div>\n ", styles: [":host{display:flex;flex-direction:column;overflow:hidden;z-index:auto;order:0}:host .scrollable{overflow-y:auto;overflow-x:hidden;flex:1}:host .main-container{-webkit-transform:translate3d(0,0,0);transform:translate3d(0,0,0);display:flex;flex-direction:column}:host .main-container-fixed{position:fixed}:host.right{margin-right:0;margin-left:auto}[dir=ltr] :host.right{order:4}[dir=rtl] :host.right{order:0}:host.end{order:4}[dir=ltr] :host.end{margin-right:0;margin-left:auto}[dir=rtl] :host.end{margin-left:0;margin-right:auto}:host.fixed{position:fixed;height:100%;z-index:999;top:0;bottom:0;left:0}:host.fixed.right{right:0}[dir=ltr] :host.fixed.start{left:0}[dir=rtl] :host.fixed.start{right:0}[dir=ltr] :host.fixed.end{right:0}[dir=rtl] :host.fixed.end{left:0}:host /deep/ nb-sidebar-footer{margin-top:auto;display:block}:host /deep/ nb-sidebar-header{display:block}"] }] } ]; /** @nocollapse */ NbSidebarComponent.ctorParameters = function () { return [ { type: NbSidebarService }, { type: NbThemeService }, { type: ElementRef } ]; }; NbSidebarComponent.propDecorators = { fixedValue: [{ type: HostBinding, args: ['class.fixed',] }], rightValue: [{ type: HostBinding, args: ['class.right',] }], leftValue: [{ type: HostBinding, args: ['class.left',] }], startValue: [{ type: HostBinding, args: ['class.start',] }], endValue: [{ type: HostBinding, args: ['class.end',] }], expanded: [{ type: HostBinding, args: ['class.expanded',] }], collapsed: [{ type: HostBinding, args: ['class.collapsed',] }], compacted: [{ type: HostBinding, args: ['class.compacted',] }], right: [{ type: Input }], left: [{ type: Input }], start: [{ type: Input }], end: [{ type: Input }], fixed: [{ type: Input }], containerFixed: [{ type: Input }], state: [{ type: Input }], responsive: [{ type: Input }], tag: [{ type: Input }], compactedBreakpoints: [{ type: Input }], collapsedBreakpoints: [{ type: Input }] }; return NbSidebarComponent; }()); export { NbSidebarComponent }; if (false) { /** @type {?} */ NbSidebarComponent.STATE_EXPANDED; /** @type {?} */ NbSidebarComponent.STATE_COLLAPSED; /** @type {?} */ NbSidebarComponent.STATE_COMPACTED; /** @type {?} */ NbSidebarComponent.RESPONSIVE_STATE_MOBILE; /** @type {?} */ NbSidebarComponent.RESPONSIVE_STATE_TABLET; /** @type {?} */ NbSidebarComponent.RESPONSIVE_STATE_PC; /** * @type {?} * @protected */ NbSidebarComponent.prototype.stateValue; /** * @type {?} * @protected */ NbSidebarComponent.prototype.responsiveValue; /** * @type {?} * @private */ NbSidebarComponent.prototype.alive; /** @type {?} */ NbSidebarComponent.prototype.containerFixedValue; /** @type {?} */ NbSidebarComponent.prototype.fixedValue; /** @type {?} */ NbSidebarComponent.prototype.rightValue; /** @type {?} */ NbSidebarComponent.prototype.leftValue; /** @type {?} */ NbSidebarComponent.prototype.startValue; /** @type {?} */ NbSidebarComponent.prototype.endValue; /** @type {?} */ NbSidebarComponent.prototype.tag; /** @type {?} */ NbSidebarComponent.prototype.compactedBreakpoints; /** @type {?} */ NbSidebarComponent.prototype.collapsedBreakpoints; /** * @type {?} * @private */ NbSidebarComponent.prototype.mediaQuerySubscription; /** * @type {?} * @private */ NbSidebarComponent.prototype.responsiveState; /** * @type {?} * @private */ NbSidebarComponent.prototype.sidebarService; /** * @type {?} * @private */ NbSidebarComponent.prototype.themeService; /** * @type {?} * @private */ NbSidebarComponent.prototype.element; } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZWJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9zaWRlYmFyL3NpZGViYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7QUFNQSxPQUFPLEVBQUUsU0FBUyxFQUFFLFdBQVcsRUFBRSxLQUFLLEVBQXFCLFVBQVUsRUFBYSxNQUFNLGVBQWUsQ0FBQztBQUV4RyxPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFFM0MsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sWUFBWSxDQUFDO0FBQ25ELE9BQU8sRUFBRSxjQUFjLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUU5RCxPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQzs7Ozs7OztBQVNyRDtJQUFBO0lBT0EsQ0FBQzs7Z0JBUEEsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFFBQVEsRUFBRSxxQ0FFVDtpQkFDRjs7SUFFRCwrQkFBQztDQUFBLEFBUEQsSUFPQztTQURZLHdCQUF3Qjs7Ozs7OztBQVNyQztJQUFBO0lBT0EsQ0FBQzs7Z0JBUEEsU0FBUyxTQUFDO29CQUNULFFBQVEsRUFBRSxtQkFBbUI7b0JBQzdCLFFBQVEsRUFBRSxxQ0FFVDtpQkFDRjs7SUFFRCwrQkFBQztDQUFBLEFBUEQsSUFPQztTQURZLHdCQUF3Qjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFzRXJDO0lBcUtFLDRCQUFvQixjQUFnQyxFQUMxQyxZQUE0QixFQUM1QixPQUFtQjtRQUZULG1CQUFjLEdBQWQsY0FBYyxDQUFrQjtRQUMxQyxpQkFBWSxHQUFaLFlBQVksQ0FBZ0I7UUFDNUIsWUFBTyxHQUFQLE9BQU8sQ0FBWTtRQTlJbkIsb0JBQWUsR0FBWSxLQUFL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QWlCOzRCQUk3QixXQUFXLFNBQUMsaUJBQWlCO3dCQVM3QixLQUFLO3VCQVlMLEtBQUs7d0JBWUwsS0FBSztzQkFZTCxLQUFLO3dCQVlMLEtBQUs7aUNBU0wsS0FBSzt3QkFTTCxLQUFLOzZCQVNMLEtBQUs7c0JBV0wsS0FBSzt1Q0FVTCxLQUFLO3VDQVNMLEtBQUs7O0lBMEpSLHlCQUFDO0NBQUEsQUExVEQsSUEwVEM7U0E1U1ksa0JBQWtCOzs7SUFFN0Isa0NBQW9EOztJQUNwRCxtQ0FBc0Q7O0lBQ3RELG1DQUFzRDs7SUFFdEQsMkNBQTJEOztJQUMzRCwyQ0FBMkQ7O0lBQzNELHVDQUFtRDs7Ozs7SUFFbkQsd0NBQTZCOzs7OztJQUM3Qiw2Q0FBMkM7Ozs7O0lBRTNDLG1DQUFxQjs7SUFFckIsaURBQW9DOztJQUVwQyx3Q0FBd0Q7O0lBQ3hELHdDQUF3RDs7SUFDeEQsdUNBQXFEOztJQUNyRCx3Q0FBd0Q7O0lBQ3hELHNDQUFvRDs7SUEwR3BELGlDQUFxQjs7SUFVckIsa0RBQXlFOztJQVN6RSxrREFBdUQ7Ozs7O0lBRXZELG9EQUE2Qzs7Ozs7SUFDN0MsNkNBQWlFOzs7OztJQUVyRCw0Q0FBd0M7Ozs7O0lBQ2xELDBDQUFvQzs7Ozs7SUFDcEMscUNBQTJCIiwic291cmNlc0NvbnRlbnQiOlsiLypcclxuICogQGxpY2Vuc2VcclxuICogQ29weXJpZ2h0IEFrdmVvLiBBbGwgUmlnaHRzIFJlc2VydmVkLlxyXG4gKiBMaWNlbnNlZCB1bmRlciB0aGUgTUlUIExpY2Vuc2UuIFNlZSBMaWNlbnNlLnR4dCBpbiB0aGUgcHJvamVjdCByb290IGZvciBsaWNlbnNlIGluZm9ybWF0aW9uLlxyXG4gKi9cclxuXHJcbmltcG9ydCB7IENvbXBvbmVudCwgSG9zdEJpbmRpbmcsIElucHV0LCBPbkluaXQsIE9uRGVzdHJveSwgRWxlbWVudFJlZiwgT25DaGFuZ2VzIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XHJcbmltcG9ydCB7IFN1YnNjcmlwdGlvbiB9IGZyb20gJ3J4anMnO1xyXG5pbXBvcnQgeyB0YWtlV2hpbGUgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcblxyXG5pbXBvcnQgeyBjb252ZXJ0VG9Cb29sUHJvcGVydHkgfSBmcm9tICcuLi9oZWxwZXJzJztcclxuaW1wb3J0IHsgTmJUaGVtZVNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy90aGVtZS5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTmJNZWRpYUJyZWFrcG9pbnQgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9icmVha3BvaW50cy5zZXJ2aWNlJztcclxuaW1wb3J0IHsgTmJTaWRlYmFyU2VydmljZSB9IGZyb20gJy4vc2lkZWJhci5zZXJ2aWNlJztcclxuXHJcblxyXG4vKlxyXG4gKiBTaWRlYmFyIGhlYWRlciBjb250YWluZXIuXHJcbiAqXHJcbiAqIFBsYWNlaG9sZGVyIHdoaWNoIGNvbnRhaW5zIGEgc2lkZWJhciBoZWFkZXIgY29udGVudCxcclxuICogcGxhY2VkIGF0IHRoZSB2ZXJ5IHRvcCBvZiB0aGUgc2lkZWJhciBvdXRzaWRlIG9mIHRoZSBzY3JvbGwgYXJlYS5cclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmItc2lkZWJhci1oZWFkZXInLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8bmctY29udGVudD48L25nLWNvbnRlbnQ+XHJcbiAgYCxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5iU2lkZWJhckhlYWRlckNvbXBvbmVudCB7XHJcbn1cclxuXHJcbi8qXHJcbiAqIFNpZGViYXIgZm9vdGVyIGNvbnRhaW5lci5cclxuICpcclxuICogUGxhY2Vob2xkZXIgd2hpY2ggY29udGFpbnMgYSBzaWRlYmFyIGZvb3RlciBjb250ZW50LFxyXG4gKiBwbGFjZWQgYXQgdGhlIHZlcnkgYm90dG9tIG9mIHRoZSBzaWRlYmFyIG91dHNpZGUgb2YgdGhlIHNjcm9sbCBhcmVhLlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduYi1zaWRlYmFyLWZvb3RlcicsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmJTaWRlYmFyRm9vdGVyQ29tcG9uZW50IHtcclxufVxyXG5cclxuLypcclxuICogTGF5b3V0IHNpZGViYXIgY29tcG9uZW50LlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFNob3djYXNlLCBzaWRlYmFyL3NpZGViYXItc2hvd2Nhc2UuY29tcG9uZW50KVxyXG4gKlxyXG4gKiAjIyMgSW5zdGFsbGF0aW9uXHJcbiAqXHJcbiAqIEltcG9ydCBgTmJTaWRlYmFyTW9kdWxlLmZvclJvb3QoKWAgdG8geW91ciBhcHAgbW9kdWxlLlxyXG4gKiBgYGB0c1xyXG4gKiBATmdNb2R1bGUoe1xyXG4gKiAgIGltcG9ydHM6IFtcclxuICogICBcdC8vIC4uLlxyXG4gKiAgICAgTmJTaWRlYmFyTW9kdWxlLmZvclJvb3QoKSxcclxuICogICBdLFxyXG4gKiB9KVxyXG4gKiBleHBvcnQgY2xhc3MgQXBwTW9kdWxlIHsgfVxyXG4gKiBgYGBcclxuICogYW5kIGBOYlNpZGViYXJNb2R1bGVgIHRvIHlvdXIgZmVhdHVyZSBtb2R1bGUgd2hlcmUgdGhlIGNvbXBvbmVudCBzaG91bGQgYmUgc2hvd246XHJcbiAqIGBgYHRzXHJcbiAqIEBOZ01vZHVsZSh7XHJcbiAqICAgaW1wb3J0czogW1xyXG4gKiAgIFx0Ly8gLi4uXHJcbiAqICAgICBOYlNpZGViYXJNb2R1bGUsXHJcbiAqICAgXSxcclxuICogfSlcclxuICogZXhwb3J0IGNsYXNzIFBhZ2VNb2R1bGUgeyB9XHJcbiAqIGBgYFxyXG4gKiAjIyMgVXNhZ2VcclxuICpcclxuICogU2lkZWJhciBjYW4gYmUgcGxhY2VkIG9uIHRoZSBsZWZ0IG9yIHRoZSByaWdodCBzaWRlIG9mIHRoZSBsYXlvdXQsXHJcbiAqIG9yIG9uIHN0YXJ0L2VuZCBwb3NpdGlvbiBvZiBsYXlvdXQgKGRlcGVuZHMgb24gZG9jdW1lbnQgZGlyZWN0aW9uLCBsZWZ0IHRvIHJpZ2h0IG9yIHJpZ2h0IHRvIGxlZnQpXHJcbiAqIEl0IGNhbiBiZSBmaXhlZCAoc2hvd24gYWJvdmUgdGhlIGNvbnRlbnQpIG9yIGNhbiBwdXNoIHRoZSBsYXlvdXQgd2hlbiBvcGVuZWQuXHJcbiAqXHJcbiAqIFRoZXJlIGFyZSB0aHJlZSBzdGF0ZXMgLSBgZXhwYW5kZWRgLCBgY29sbGFwc2VkYCwgYGNvbXBhY3RlZGAuXHJcbiAqIEJ5IGRlZmF1bHQgc2lkZWJhciBjb250ZW50IGlzIGZpeGVkIGFuZCBzYXZlcyBpdHMgcG9zaXRpb24gd2hpbGUgdGhlIHBhZ2UgaXMgYmVpbmcgc2Nyb2xsZWQuXHJcbiAqXHJcbiAqIENvbXBhY3RlZCBzaWRlYmFyIGV4YW1wbGU6XHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoQ29tcGFjdGVkIFNpZGViYXIsIHNpZGViYXIvc2lkZWJhci1jb21wYWN0ZWQuY29tcG9uZW50KVxyXG4gKlxyXG4gKiBTaWRlYmFyIGFsc28gc3VwcG9ydHMgYSBgcmVzcG9uc2l2ZWAgYmVoYXZpb3IsIGxpc3RlbmluZyB0byB3aW5kb3cgc2l6ZSBjaGFuZ2UgYW5kIGNoYW5naW5nIGl0cyBzaXplIHJlc3BlY3RhYmx5LlxyXG4gKlxyXG4gKiBJbiBhIHBhaXIgd2l0aCBoZWFkZXIgaXQgaXMgcG9zc2libGUgdG8gc2V0dXAgYSBjb25maWd1cmF0aW9uIHdoZW4gaGVhZGVyIGlzIHBsYWNlZCBvbiBhIHNpZGUgb2YgdGhlIHNpZGViYXJcclxuICogYW5kIG5vdCBvbiB0b3Agb2YgaXQuIFRvIGFjaGlldmUgdGhpcyBzaW1wbHkgcHV0IGEgYHN1YmhlYWRlcmAgcHJvcGVydHkgdG8gdGhlIGhlYWRlciBsaWtlIHRoaXM6XHJcbiAqIGBgYGh0bWxcclxuICogPG5iLWxheW91dC1oZWFkZXIgc3ViaGVhZGVyPjwvbmItbGF5b3V0LWhlYWRlcj5cclxuICogYGBgXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU3ViaGVhZGVyLCBsYXlvdXQvbGF5b3V0LXNpZGViYXItc3ViaGVhZGVyLmNvbXBvbmVudClcclxuICogTm90ZSB0aGF0IGluIHN1Y2ggY29uZmlndXJhdGlvbiBzaWRlYmFyIHNoYWRvdyBpcyByZW1vdmVkIGFuZCBoZWFkZXIgY2Fubm90IGJlIG1ha2UgYGZpeGVkYC5cclxuICpcclxuICogQGFkZGl0aW9uYWwtZXhhbXBsZShSaWdodCBTaWRlYmFyLCBzaWRlYmFyL3NpZGViYXItcmlnaHQuY29tcG9uZW50KVxyXG4gKiBAYWRkaXRpb25hbC1leGFtcGxlKEZpeGVkIFNpZGViYXIsIHNpZGViYXIvc2lkZWJhci1maXhlZC5jb21wb25lbnQpXHJcbiAqXHJcbiAqIEBzdHlsZXNcclxuICpcclxuICogc2lkZWJhci1mb250LXNpemU6IFNpZGViYXIgY29udGVudCBmb250IHNpemVcclxuICogc2lkZWJhci1saW5lLWhlaWdodDogU2lkZWJhciBjb250ZW50IGxpbmUgaGVpZ2h0XHJcbiAqIHNpZGViYXItZmc6IEZvcmVncm91bmQgY29sb3JcclxuICogc2lkZWJhci1iZzogQmFja2dyb3VuZCBjb2xvclxyXG4gKiBzaWRlYmFyLWhlaWdodDogQ29udGVudCBoZWlnaHRcclxuICogc2lkZWJhci13aWR0aDogRXhwYW5kZWQgd2lkdGhcclxuICogc2lkZWJhci13aWR0aC1jb21wYWN0OiBDb21wYWN0ZWQgd2lkdGhcclxuICogc2lkZWJhci1wYWRkaW5nOiBTaWRlYmFyIGNvbnRlbnQgcGFkZGluZ1xyXG4gKiBzaWRlYmFyLWhlYWRlci1oZWlnaHQ6IFNpZGViYXIgaGVhZGVyIGhlaWdodFxyXG4gKiBzaWRlYmFyLWZvb3Rlci1oZWlnaHQ6IFNpZGViYXIgZm9vdGVyIGhlaWdodFxyXG4gKiBzaWRlYmFyLXNoYWRvdzogU2lkZWJhciBjb250YWluZXIgc2hhZG93XHJcbiAqXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25iLXNpZGViYXInLFxyXG4gIHN0eWxlVXJsczogWycuL3NpZGViYXIuY29tcG9uZW50LnNjc3MnXSxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPGRpdiBjbGFzcz1cIm1haW4tY29udGFpbmVyXCJcclxuICAgICAgICAgW2NsYXNzLm1haW4tY29udGFpbmVyLWZpeGVkXT1cImNvbnRhaW5lckZpeGVkVmFsdWVcIj5cclxuICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwibmItc2lkZWJhci1oZWFkZXJcIj48L25nLWNvbnRlbnQ+XHJcbiAgICAgIDxkaXYgY2xhc3M9XCJzY3JvbGxhYmxlXCIgKGNsaWNrKT1cIm9uQ2xpY2soJGV2ZW50KVwiPlxyXG4gICAgICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICAgICAgPC9kaXY+XHJcbiAgICAgIDxuZy1jb250ZW50IHNlbGVjdD1cIm5iLXNpZGViYXItZm9vdGVyXCI+PC9uZy1jb250ZW50PlxyXG4gICAgPC9kaXY+XHJcbiAgYCxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5iU2lkZWJhckNvbXBvbmVudCBpbXBsZW1lbnRzIE9uQ2hhbmdlcywgT25Jbml0LCBPbkRlc3Ryb3kge1xyXG5cclxuICBzdGF0aWMgcmVhZG9ubHkgU1RBVEVfRVhQQU5ERUQ6IHN0cmluZyA9ICdleHBhbmRlZCc7XHJcbiAgc3RhdGljIHJlYWRvbmx5IFNUQVRFX0NPTExBUFNFRDogc3RyaW5nID0gJ2NvbGxhcHNlZCc7XHJcbiAgc3RhdGljIHJlYWRvbmx5IFNUQVRFX0NPTVBBQ1RFRDogc3RyaW5nID0gJ2NvbXBhY3RlZCc7XHJcblxyXG4gIHN0YXRpYyByZWFkb25seSBSRVNQT05TSVZFX1NUQVRFX01PQklMRTogc3RyaW5nID0gJ21vYmlsZSc7XHJcbiAgc3RhdGljIHJlYWRvbmx5IFJFU1BPTlNJVkVfU1RBVEVfVEFCTEVUOiBzdHJpbmcgPSAndGFibGV0JztcclxuICBzdGF0aWMgcmVhZG9ubHkgUkVTUE9OU0lWRV9TVEFURV9QQzogc3RyaW5nID0gJ3BjJztcclxuXHJcbiAgcHJvdGVjdGVkIHN0YXRlVmFsdWU6IHN0cmluZztcclxuICBwcm90ZWN0ZWQgcmVzcG9uc2l2ZVZhbHVlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIHByaXZhdGUgYWxpdmUgPSB0cnVlO1xyXG5cclxuICBjb250YWluZXJGaXhlZFZhbHVlOiBib29sZWFuID0gdHJ1ZTtcclxuXHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5maXhlZCcpIGZpeGVkVmFsdWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLnJpZ2h0JykgcmlnaHRWYWx1ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBIb3N0QmluZGluZygnY2xhc3MubGVmdCcpIGxlZnRWYWx1ZTogYm9vbGVhbiA9IHRydWU7XHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5zdGFydCcpIHN0YXJ0VmFsdWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmVuZCcpIGVuZFZhbHVlOiBib29sZWFuID0gZmFsc2U7XHJcblxyXG4gIC8vIFRPRE86IHJlbmFtZSBzdGF0ZVZhbHVlIHRvIHN0YXRlICh0YWtlIGEgbG9vayB0byB0aGUgY2FyZCBjb21wb25lbnQpXHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5leHBhbmRlZCcpXHJcbiAgZ2V0IGV4cGFuZGVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGVWYWx1ZSA9PT0gTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0VYUEFOREVEO1xyXG4gIH1cclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmNvbGxhcHNlZCcpXHJcbiAgZ2V0IGNvbGxhcHNlZCgpIHtcclxuICAgIHJldHVybiB0aGlzLnN0YXRlVmFsdWUgPT09IE5iU2lkZWJhckNvbXBvbmVudC5TVEFURV9DT0xMQVBTRUQ7XHJcbiAgfVxyXG4gIEBIb3N0QmluZGluZygnY2xhc3MuY29tcGFjdGVkJylcclxuICBnZXQgY29tcGFjdGVkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGVWYWx1ZSA9PT0gTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0NPTVBBQ1RFRDtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogUGxhY2VzIHNpZGViYXIgb24gdGhlIHJpZ2h0IHNpZGVcclxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCByaWdodCh2YWw6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMucmlnaHRWYWx1ZSA9IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSh2YWwpO1xyXG4gICAgdGhpcy5sZWZ0VmFsdWUgPSAhdGhpcy5yaWdodFZhbHVlO1xyXG4gICAgdGhpcy5zdGFydFZhbHVlID0gZmFsc2U7XHJcbiAgICB0aGlzLmVuZFZhbHVlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFBsYWNlcyBzaWRlYmFyIG9uIHRoZSBsZWZ0IHNpZGVcclxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBsZWZ0KHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5sZWZ0VmFsdWUgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkodmFsKTtcclxuICAgIHRoaXMucmlnaHRWYWx1ZSA9ICF0aGlzLmxlZnRWYWx1ZTtcclxuICAgIHRoaXMuc3RhcnRWYWx1ZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5lbmRWYWx1ZSA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBQbGFjZXMgc2lkZWJhciBvbiB0aGUgc3RhcnQgZWRnZSBvZiBsYXlvdXRcclxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzdGFydCh2YWw6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuc3RhcnRWYWx1ZSA9IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSh2YWwpO1xyXG4gICAgdGhpcy5lbmRWYWx1ZSA9ICF0aGlzLnN0YXJ0VmFsdWU7XHJcbiAgICB0aGlzLmxlZnRWYWx1ZSA9IGZhbHNlO1xyXG4gICAgdGhpcy5yaWdodFZhbHVlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFBsYWNlcyBzaWRlYmFyIG9uIHRoZSBlbmQgZWRnZSBvZiBsYXlvdXRcclxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBlbmQodmFsOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmVuZFZhbHVlID0gY29udmVydFRvQm9vbFByb3BlcnR5KHZhbCk7XHJcbiAgICB0aGlzLnN0YXJ0VmFsdWUgPSAhdGhpcy5lbmRWYWx1ZTtcclxuICAgIHRoaXMubGVmdFZhbHVlID0gZmFsc2U7XHJcbiAgICB0aGlzLnJpZ2h0VmFsdWUgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogTWFrZXMgc2lkZWJhciBmaXhlZCAoc2hvd24gYWJvdmUgdGhlIGxheW91dCBjb250ZW50KVxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGZpeGVkKHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5maXhlZFZhbHVlID0gY29udmVydFRvQm9vbFByb3BlcnR5KHZhbCk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIE1ha2VzIHNpZGViYXIgY29udGFpbmVyIGZpeGVkXHJcbiAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgY29udGFpbmVyRml4ZWQodmFsOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmNvbnRhaW5lckZpeGVkVmFsdWUgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkodmFsKTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogSW5pdGlhbCBzaWRlYmFyIHN0YXRlLCBgZXhwYW5kZWRgfGBjb2xsYXBzZWRgfGBjb21wYWN0ZWRgXHJcbiAgICogQHR5cGUge3N0cmluZ31cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBzdGF0ZSh2YWw6IHN0cmluZykge1xyXG4gICAgdGhpcy5zdGF0ZVZhbHVlID0gdmFsO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBNYWtlcyBzaWRlYmFyIGxpc3RlbiB0byBtZWRpYSBxdWVyeSBldmVudHMgYW5kIGNoYW5nZSBpdHMgYmVoYXZpb3VyXHJcbiAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgcmVzcG9uc2l2ZSh2YWw6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMucmVzcG9uc2l2ZVZhbHVlID0gY29udmVydFRvQm9vbFByb3BlcnR5KHZhbCk7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFRhZ3MgYSBzaWRlYmFyIHdpdGggc29tZSBJRCwgY2FuIGJlIGxhdGVyIHVzZWQgaW4gdGhlIHNpZGViYXIgc2VydmljZVxyXG4gICAqIHRvIGRldGVybWluZSB3aGljaCBzaWRlYmFyIHRyaWdnZXJlZCB0aGUgYWN0aW9uLCBpZiBtdWx0aXBsZSBzaWRlYmFycyBleGlzdCBvbiB0aGUgcGFnZS5cclxuICAgKlxyXG4gICAqIEB0eXBlIHtzdHJpbmd9XHJcbiAgICovXHJcbiAgQElucHV0KCkgdGFnOiBzdHJpbmc7XHJcblxyXG4gIC8vIFRPRE86IGdldCB3aWR0aCBieSB0aGUga2V5IGFuZCBkZWZpbmUgb25seSBtYXggd2lkdGggZm9yIHRoZSB0YWJsZXRzIGFuZCBtb2JpbGVzXHJcbiAgLypcclxuICAgKiBDb250cm9scyBvbiB3aGljaCBzY3JlZW4gc2l6ZXMgc2lkZWJhciBzaG91bGQgYmUgc3dpdGNoZWQgdG8gY29tcGFjdGVkIHN0YXRlLlxyXG4gICAqIFdvcmtzIG9ubHkgd2hlbiByZXNwb25zaXZlIG1vZGUgaXMgb24uXHJcbiAgICogRGVmYXVsdCB2YWx1ZXMgYXJlIGBbJ3hzJywgJ2lzJywgJ3NtJywgJ21kJywgJ2xnJ11gLlxyXG4gICAqXHJcbiAgICogQHR5cGUgc3RyaW5nW11cclxuICAgKi9cclxuICBASW5wdXQoKSBjb21wYWN0ZWRCcmVha3BvaW50czogc3RyaW5nW10gPSBbJ3hzJywgJ2lzJywgJ3NtJywgJ21kJywgJ2xnJ107XHJcblxyXG4gIC8qXHJcbiAgICogQ29udHJvbHMgb24gd2hpY2ggc2NyZWVuIHNpemVzIHNpZGViYXIgc2hvdWxkIGJlIHN3aXRjaGVkIHRvIGNvbGxhcHNlZCBzdGF0ZS5cclxuICAgKiBXb3JrcyBvbmx5IHdoZW4gcmVzcG9uc2l2ZSBtb2RlIGlzIG9uLlxyXG4gICAqIERlZmF1bHQgdmFsdWVzIGFyZSBgWyd4cycsICdpcyddYC5cclxuICAgKlxyXG4gICAqIEB0eXBlIHN0cmluZ1tdXHJcbiAgICovXHJcbiAgQElucHV0KCkgY29sbGFwc2VkQnJlYWtwb2ludHM6IHN0cmluZ1tdID0gWyd4cycsICdpcyddO1xyXG5cclxuICBwcml2YXRlIG1lZGlhUXVlcnlTdWJzY3JpcHRpb246IFN1YnNjcmlwdGlvbjtcclxuICBwcml2YXRlIHJlc3BvbnNpdmVTdGF0ZSA9IE5iU2lkZWJhckNvbXBvbmVudC5SRVNQT05TSVZFX1NUQVRFX1BDO1xyXG5cclxuICBjb25zdHJ1Y3Rvcihwcml2YXRlIHNpZGViYXJTZXJ2aWNlOiBOYlNpZGViYXJTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSB0aGVtZVNlcnZpY2U6IE5iVGhlbWVTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBlbGVtZW50OiBFbGVtZW50UmVmKSB7XHJcbiAgfVxyXG5cclxuICB0b2dnbGVSZXNwb25zaXZlKGVuYWJsZWQ6IGJvb2xlYW4pIHtcclxuICAgIGlmIChlbmFibGVkKSB7XHJcbiAgICAgIHRoaXMubWVkaWFRdWVyeVN1YnNjcmlwdGlvbiA9IHRoaXMub25NZWRpYVF1ZXJ5Q2hhbmdlcygpO1xyXG4gICAgfSBlbHNlIGlmICh0aGlzLm1lZGlhUXVlcnlTdWJzY3JpcHRpb24pIHtcclxuICAgICAgdGhpcy5tZWRpYVF1ZXJ5U3Vic2NyaXB0aW9uLnVuc3Vic2NyaWJlKCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uQ2hhbmdlcyhjaGFuZ2VzKSB7XHJcbiAgICBpZiAoY2hhbmdlcy5yZXNwb25zaXZlKSB7XHJcbiAgICAgIHRoaXMudG9nZ2xlUmVzcG9uc2l2ZSh0aGlzLnJlc3BvbnNpdmVWYWx1ZSk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBuZ09uSW5pdCgpIHtcclxuICAgIHRoaXMuc2lkZWJhclNlcnZpY2Uub25Ub2dnbGUoKVxyXG4gICAgICAucGlwZSh0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGE6IHsgY29tcGFjdDogYm9vbGVhbiwgdGFnOiBzdHJpbmcgfSkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy50YWcgfHwgdGhpcy50YWcgPT09IGRhdGEudGFnKSB7XHJcbiAgICAgICAgICB0aGlzLnRvZ2dsZShkYXRhLmNvbXBhY3QpO1xyXG4gICAgICAgIH1cclxuICAgICAgfSk7XHJcblxyXG4gICAgdGhpcy5zaWRlYmFyU2VydmljZS5vbkV4cGFuZCgpXHJcbiAgICAgIC5waXBlKHRha2VXaGlsZSgoKSA9PiB0aGlzLmFsaXZlKSlcclxuICAgICAgLnN1YnNjcmliZSgoZGF0YTogeyB0YWc6IHN0cmluZyB9KSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnRhZyB8fCB0aGlzLnRhZyA9PT0gZGF0YS50YWcpIHtcclxuICAgICAgICAgIHRoaXMuZXhwYW5kKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICB0aGlzLnNpZGViYXJTZXJ2aWNlLm9uQ29sbGFwc2UoKVxyXG4gICAgICAucGlwZSh0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSkpXHJcbiAgICAgIC5zdWJzY3JpYmUoKGRhdGE6IHsgdGFnOiBzdHJpbmcgfSkgPT4ge1xyXG4gICAgICAgIGlmICghdGhpcy50YWcgfHwgdGhpcy50YWcgPT09IGRhdGEudGFnKSB7XHJcbiAgICAgICAgICB0aGlzLmNvbGxhcHNlKCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5hbGl2ZSA9IGZhbHNlO1xyXG4gICAgaWYgKHRoaXMubWVkaWFRdWVyeVN1YnNjcmlwdGlvbikge1xyXG4gICAgICB0aGlzLm1lZGlhUXVlcnlTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIC8vIFRPRE86IHRoaXMgaXMgbW9yZSBvZiBhIHdvcmthcm91bmQsIHNob3VsZCBiZSBhIGJldHRlciB3YXkgdG8gbWFrZSBjb21wb25lbnRzIGNvbW11bmljYXRlIHRvIGVhY2ggb3RoZXJcclxuICBvbkNsaWNrKGV2ZW50KTogdm9pZCB7XHJcbiAgICBjb25zdCBtZW51ID0gdGhpcy5lbGVtZW50Lm5hdGl2ZUVsZW1lbnQucXVlcnlTZWxlY3RvcignbmItbWVudScpO1xyXG5cclxuICAgIGlmIChtZW51ICYmIG1lbnUuY29udGFpbnMoZXZlbnQudGFyZ2V0KSkge1xyXG4gICAgICBsZXQgbGluayA9IGV2ZW50LnRhcmdldDtcclxuICAgICAgY29uc3QgbGlua0NoaWxkcmVuID0gWydzcGFuJywgJ2knXTtcclxuXHJcbiAgICAgIC8vIGlmIHdlIGNsaWNrZWQgb24gc3BhbiAtIGdldCB0aGUgbGlua1xyXG4gICAgICBpZiAobGlua0NoaWxkcmVuLmluY2x1ZGVzKGxpbmsudGFnTmFtZS50b0xvd2VyQ2FzZSgpKSAmJiBsaW5rLnBhcmVudE5vZGUpIHtcclxuICAgICAgICBsaW5rID0gZXZlbnQudGFyZ2V0LnBhcmVudE5vZGU7XHJcbiAgICAgIH1cclxuXHJcbiAgICAgIC8vIHdlIG9ubHkgZXhwYW5kIGlmIGFuIGl0ZW0gaGFzIGNoaWxkcmVuXHJcbiAgICAgIGlmIChsaW5rICYmIGxpbmsubmV4dEVsZW1lbnRTaWJsaW5nICYmIGxpbmsubmV4dEVsZW1lbnRTaWJsaW5nLmNsYXNzTGlzdC5jb250YWlucygnbWVudS1pdGVtcycpKSB7XHJcbiAgICAgICAgdGhpcy5leHBhbmQoKTtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBDb2xsYXBzZXMgdGhlIHNpZGViYXJcclxuICAgKi9cclxuICBjb2xsYXBzZSgpIHtcclxuICAgIHRoaXMuc3RhdGUgPSBOYlNpZGViYXJDb21wb25lbnQuU1RBVEVfQ09MTEFQU0VEO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBFeHBhbmRzIHRoZSBzaWRlYmFyXHJcbiAgICovXHJcbiAgZXhwYW5kKCkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IE5iU2lkZWJhckNvbXBvbmVudC5TVEFURV9FWFBBTkRFRDtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogQ29tcGFjdHMgdGhlIHNpZGViYXIgKG1pbmltaXplcylcclxuICAgKi9cclxuICBjb21wYWN0KCkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IE5iU2lkZWJhckNvbXBvbmVudC5TVEFURV9DT01QQUNURUQ7XHJcbiAgfVxyXG5