UNPKG

theme-lib

Version:

This is a simple example Angular Library published to npm.

565 lines 46 kB
/** * @fileoverview added by tsickle * @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc */ /* * @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. */ export class NbSidebarHeaderComponent { } NbSidebarHeaderComponent.decorators = [ { type: Component, args: [{ selector: 'nb-sidebar-header', template: ` <ng-content></ng-content> ` }] } ]; /* * Sidebar footer container. * * Placeholder which contains a sidebar footer content, * placed at the very bottom of the sidebar outside of the scroll area. */ export class NbSidebarFooterComponent { } NbSidebarFooterComponent.decorators = [ { type: Component, args: [{ selector: 'nb-sidebar-footer', template: ` <ng-content></ng-content> ` }] } ]; /* * 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 * */ export class NbSidebarComponent { /** * @param {?} sidebarService * @param {?} themeService * @param {?} element */ constructor(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; } // TODO: rename stateValue to state (take a look to the card component) /** * @return {?} */ get expanded() { return this.stateValue === NbSidebarComponent.STATE_EXPANDED; } /** * @return {?} */ get collapsed() { return this.stateValue === NbSidebarComponent.STATE_COLLAPSED; } /** * @return {?} */ get compacted() { return this.stateValue === NbSidebarComponent.STATE_COMPACTED; } /* * Places sidebar on the right side * @type {boolean} */ /** * @param {?} val * @return {?} */ set right(val) { this.rightValue = convertToBoolProperty(val); this.leftValue = !this.rightValue; this.startValue = false; this.endValue = false; } /* * Places sidebar on the left side * @type {boolean} */ /** * @param {?} val * @return {?} */ set left(val) { this.leftValue = convertToBoolProperty(val); this.rightValue = !this.leftValue; this.startValue = false; this.endValue = false; } /* * Places sidebar on the start edge of layout * @type {boolean} */ /** * @param {?} val * @return {?} */ set start(val) { this.startValue = convertToBoolProperty(val); this.endValue = !this.startValue; this.leftValue = false; this.rightValue = false; } /* * Places sidebar on the end edge of layout * @type {boolean} */ /** * @param {?} val * @return {?} */ set end(val) { this.endValue = convertToBoolProperty(val); this.startValue = !this.endValue; this.leftValue = false; this.rightValue = false; } /* * Makes sidebar fixed (shown above the layout content) * @type {boolean} */ /** * @param {?} val * @return {?} */ set fixed(val) { this.fixedValue = convertToBoolProperty(val); } /* * Makes sidebar container fixed * @type {boolean} */ /** * @param {?} val * @return {?} */ set containerFixed(val) { this.containerFixedValue = convertToBoolProperty(val); } /* * Initial sidebar state, `expanded`|`collapsed`|`compacted` * @type {string} */ /** * @param {?} val * @return {?} */ set state(val) { this.stateValue = val; } /* * Makes sidebar listen to media query events and change its behaviour * @type {boolean} */ /** * @param {?} val * @return {?} */ set responsive(val) { this.responsiveValue = convertToBoolProperty(val); } /** * @param {?} enabled * @return {?} */ toggleResponsive(enabled) { if (enabled) { this.mediaQuerySubscription = this.onMediaQueryChanges(); } else if (this.mediaQuerySubscription) { this.mediaQuerySubscription.unsubscribe(); } } /** * @param {?} changes * @return {?} */ ngOnChanges(changes) { if (changes.responsive) { this.toggleResponsive(this.responsiveValue); } } /** * @return {?} */ ngOnInit() { this.sidebarService.onToggle() .pipe(takeWhile(() => this.alive)) .subscribe((data) => { if (!this.tag || this.tag === data.tag) { this.toggle(data.compact); } }); this.sidebarService.onExpand() .pipe(takeWhile(() => this.alive)) .subscribe((data) => { if (!this.tag || this.tag === data.tag) { this.expand(); } }); this.sidebarService.onCollapse() .pipe(takeWhile(() => this.alive)) .subscribe((data) => { if (!this.tag || this.tag === data.tag) { this.collapse(); } }); } /** * @return {?} */ ngOnDestroy() { 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 /** * @param {?} event * @return {?} */ onClick(event) { /** @type {?} */ const menu = this.element.nativeElement.querySelector('nb-menu'); if (menu && menu.contains(event.target)) { /** @type {?} */ let link = event.target; /** @type {?} */ const 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 */ /** * @return {?} */ collapse() { this.state = NbSidebarComponent.STATE_COLLAPSED; } /* * Expands the sidebar */ /** * @return {?} */ expand() { this.state = NbSidebarComponent.STATE_EXPANDED; } /* * Compacts the sidebar (minimizes) */ /** * @return {?} */ compact() { 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); * ``` */ /** * @param {?=} compact * @return {?} */ toggle(compact = false) { if (this.responsiveEnabled()) { if (this.responsiveState === NbSidebarComponent.RESPONSIVE_STATE_MOBILE) { compact = false; } } /** @type {?} */ const 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 {?} */ onMediaQueryChanges() { return this.themeService.onMediaQueryChange() .subscribe(([prev, current]) => { /** @type {?} */ const isCollapsed = this.collapsedBreakpoints.includes(current.name); /** @type {?} */ const 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 {?} */ responsiveEnabled() { 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: ` <div class="main-container" [class.main-container-fixed]="containerFixedValue"> <ng-content select="nb-sidebar-header"></ng-content> <div class="scrollable" (click)="onClick($event)"> <ng-content></ng-content> </div> <ng-content select="nb-sidebar-footer"></ng-content> </div> `, 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 = () => [ { 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 }] }; 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,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2lkZWJhci5jb21wb25lbnQuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9zaWRlYmFyL3NpZGViYXIuY29tcG9uZW50LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7OztBQU1BLE9BQU8sRUFBRSxTQUFTLEVBQUUsV0FBVyxFQUFFLEtBQUssRUFBcUIsVUFBVSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBRXhHLE9BQU8sRUFBRSxTQUFTLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUUzQyxPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbkQsT0FBTyxFQUFFLGNBQWMsRUFBRSxNQUFNLDhCQUE4QixDQUFDO0FBRTlELE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLG1CQUFtQixDQUFDOzs7Ozs7O0FBZXJELE1BQU0sT0FBTyx3QkFBd0I7OztZQU5wQyxTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLG1CQUFtQjtnQkFDN0IsUUFBUSxFQUFFOztHQUVUO2FBQ0Y7Ozs7Ozs7O0FBZ0JELE1BQU0sT0FBTyx3QkFBd0I7OztZQU5wQyxTQUFTLFNBQUM7Z0JBQ1QsUUFBUSxFQUFFLG1CQUFtQjtnQkFDN0IsUUFBUSxFQUFFOztHQUVUO2FBQ0Y7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQXFGRCxNQUFNLE9BQU8sa0JBQWtCOzs7Ozs7SUF1SjdCLFlBQW9CLGNBQWdDLEVBQzFDLFlBQTRCLEVBQzVCLE9BQW1CO1FBRlQsbUJBQWMsR0FBZCxjQUFjLENBQWtCO1FBQzFDLGlCQUFZLEdBQVosWUFBWSxDQUFnQjtRQUM1QixZQUFPLEdBQVAsT0FBTyxDQUFZO1FBOUluQixvQkFBZSxHQUFZLEtBQUssQ0FBQztRQUVuQyxVQUFLLEdBQUcsSUFBSSxDQUFDO1FBRXJCLHdCQUFtQixHQUFZLElB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bGljZW5zZVxyXG4gKiBDb3B5cmlnaHQgQWt2ZW8uIEFsbCBSaWdodHMgUmVzZXJ2ZWQuXHJcbiAqIExpY2Vuc2VkIHVuZGVyIHRoZSBNSVQgTGljZW5zZS4gU2VlIExpY2Vuc2UudHh0IGluIHRoZSBwcm9qZWN0IHJvb3QgZm9yIGxpY2Vuc2UgaW5mb3JtYXRpb24uXHJcbiAqL1xyXG5cclxuaW1wb3J0IHsgQ29tcG9uZW50LCBIb3N0QmluZGluZywgSW5wdXQsIE9uSW5pdCwgT25EZXN0cm95LCBFbGVtZW50UmVmLCBPbkNoYW5nZXMgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IHRha2VXaGlsZSB9IGZyb20gJ3J4anMvb3BlcmF0b3JzJztcclxuXHJcbmltcG9ydCB7IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSB9IGZyb20gJy4uL2hlbHBlcnMnO1xyXG5pbXBvcnQgeyBOYlRoZW1lU2VydmljZSB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL3RoZW1lLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOYk1lZGlhQnJlYWtwb2ludCB9IGZyb20gJy4uLy4uL3NlcnZpY2VzL2JyZWFrcG9pbnRzLnNlcnZpY2UnO1xyXG5pbXBvcnQgeyBOYlNpZGViYXJTZXJ2aWNlIH0gZnJvbSAnLi9zaWRlYmFyLnNlcnZpY2UnO1xyXG5cclxuXHJcbi8qXHJcbiAqIFNpZGViYXIgaGVhZGVyIGNvbnRhaW5lci5cclxuICpcclxuICogUGxhY2Vob2xkZXIgd2hpY2ggY29udGFpbnMgYSBzaWRlYmFyIGhlYWRlciBjb250ZW50LFxyXG4gKiBwbGFjZWQgYXQgdGhlIHZlcnkgdG9wIG9mIHRoZSBzaWRlYmFyIG91dHNpZGUgb2YgdGhlIHNjcm9sbCBhcmVhLlxyXG4gKi9cclxuQENvbXBvbmVudCh7XHJcbiAgc2VsZWN0b3I6ICduYi1zaWRlYmFyLWhlYWRlcicsXHJcbiAgdGVtcGxhdGU6IGBcclxuICAgIDxuZy1jb250ZW50PjwvbmctY29udGVudD5cclxuICBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmJTaWRlYmFySGVhZGVyQ29tcG9uZW50IHtcclxufVxyXG5cclxuLypcclxuICogU2lkZWJhciBmb290ZXIgY29udGFpbmVyLlxyXG4gKlxyXG4gKiBQbGFjZWhvbGRlciB3aGljaCBjb250YWlucyBhIHNpZGViYXIgZm9vdGVyIGNvbnRlbnQsXHJcbiAqIHBsYWNlZCBhdCB0aGUgdmVyeSBib3R0b20gb2YgdGhlIHNpZGViYXIgb3V0c2lkZSBvZiB0aGUgc2Nyb2xsIGFyZWEuXHJcbiAqL1xyXG5AQ29tcG9uZW50KHtcclxuICBzZWxlY3RvcjogJ25iLXNpZGViYXItZm9vdGVyJyxcclxuICB0ZW1wbGF0ZTogYFxyXG4gICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG4gIGAsXHJcbn0pXHJcbmV4cG9ydCBjbGFzcyBOYlNpZGViYXJGb290ZXJDb21wb25lbnQge1xyXG59XHJcblxyXG4vKlxyXG4gKiBMYXlvdXQgc2lkZWJhciBjb21wb25lbnQuXHJcbiAqXHJcbiAqIEBzdGFja2VkLWV4YW1wbGUoU2hvd2Nhc2UsIHNpZGViYXIvc2lkZWJhci1zaG93Y2FzZS5jb21wb25lbnQpXHJcbiAqXHJcbiAqICMjIyBJbnN0YWxsYXRpb25cclxuICpcclxuICogSW1wb3J0IGBOYlNpZGViYXJNb2R1bGUuZm9yUm9vdCgpYCB0byB5b3VyIGFwcCBtb2R1bGUuXHJcbiAqIGBgYHRzXHJcbiAqIEBOZ01vZHVsZSh7XHJcbiAqICAgaW1wb3J0czogW1xyXG4gKiAgIFx0Ly8gLi4uXHJcbiAqICAgICBOYlNpZGViYXJNb2R1bGUuZm9yUm9vdCgpLFxyXG4gKiAgIF0sXHJcbiAqIH0pXHJcbiAqIGV4cG9ydCBjbGFzcyBBcHBNb2R1bGUgeyB9XHJcbiAqIGBgYFxyXG4gKiBhbmQgYE5iU2lkZWJhck1vZHVsZWAgdG8geW91ciBmZWF0dXJlIG1vZHVsZSB3aGVyZSB0aGUgY29tcG9uZW50IHNob3VsZCBiZSBzaG93bjpcclxuICogYGBgdHNcclxuICogQE5nTW9kdWxlKHtcclxuICogICBpbXBvcnRzOiBbXHJcbiAqICAgXHQvLyAuLi5cclxuICogICAgIE5iU2lkZWJhck1vZHVsZSxcclxuICogICBdLFxyXG4gKiB9KVxyXG4gKiBleHBvcnQgY2xhc3MgUGFnZU1vZHVsZSB7IH1cclxuICogYGBgXHJcbiAqICMjIyBVc2FnZVxyXG4gKlxyXG4gKiBTaWRlYmFyIGNhbiBiZSBwbGFjZWQgb24gdGhlIGxlZnQgb3IgdGhlIHJpZ2h0IHNpZGUgb2YgdGhlIGxheW91dCxcclxuICogb3Igb24gc3RhcnQvZW5kIHBvc2l0aW9uIG9mIGxheW91dCAoZGVwZW5kcyBvbiBkb2N1bWVudCBkaXJlY3Rpb24sIGxlZnQgdG8gcmlnaHQgb3IgcmlnaHQgdG8gbGVmdClcclxuICogSXQgY2FuIGJlIGZpeGVkIChzaG93biBhYm92ZSB0aGUgY29udGVudCkgb3IgY2FuIHB1c2ggdGhlIGxheW91dCB3aGVuIG9wZW5lZC5cclxuICpcclxuICogVGhlcmUgYXJlIHRocmVlIHN0YXRlcyAtIGBleHBhbmRlZGAsIGBjb2xsYXBzZWRgLCBgY29tcGFjdGVkYC5cclxuICogQnkgZGVmYXVsdCBzaWRlYmFyIGNvbnRlbnQgaXMgZml4ZWQgYW5kIHNhdmVzIGl0cyBwb3NpdGlvbiB3aGlsZSB0aGUgcGFnZSBpcyBiZWluZyBzY3JvbGxlZC5cclxuICpcclxuICogQ29tcGFjdGVkIHNpZGViYXIgZXhhbXBsZTpcclxuICogQHN0YWNrZWQtZXhhbXBsZShDb21wYWN0ZWQgU2lkZWJhciwgc2lkZWJhci9zaWRlYmFyLWNvbXBhY3RlZC5jb21wb25lbnQpXHJcbiAqXHJcbiAqIFNpZGViYXIgYWxzbyBzdXBwb3J0cyBhIGByZXNwb25zaXZlYCBiZWhhdmlvciwgbGlzdGVuaW5nIHRvIHdpbmRvdyBzaXplIGNoYW5nZSBhbmQgY2hhbmdpbmcgaXRzIHNpemUgcmVzcGVjdGFibHkuXHJcbiAqXHJcbiAqIEluIGEgcGFpciB3aXRoIGhlYWRlciBpdCBpcyBwb3NzaWJsZSB0byBzZXR1cCBhIGNvbmZpZ3VyYXRpb24gd2hlbiBoZWFkZXIgaXMgcGxhY2VkIG9uIGEgc2lkZSBvZiB0aGUgc2lkZWJhclxyXG4gKiBhbmQgbm90IG9uIHRvcCBvZiBpdC4gVG8gYWNoaWV2ZSB0aGlzIHNpbXBseSBwdXQgYSBgc3ViaGVhZGVyYCBwcm9wZXJ0eSB0byB0aGUgaGVhZGVyIGxpa2UgdGhpczpcclxuICogYGBgaHRtbFxyXG4gKiA8bmItbGF5b3V0LWhlYWRlciBzdWJoZWFkZXI+PC9uYi1sYXlvdXQtaGVhZGVyPlxyXG4gKiBgYGBcclxuICogQHN0YWNrZWQtZXhhbXBsZShTdWJoZWFkZXIsIGxheW91dC9sYXlvdXQtc2lkZWJhci1zdWJoZWFkZXIuY29tcG9uZW50KVxyXG4gKiBOb3RlIHRoYXQgaW4gc3VjaCBjb25maWd1cmF0aW9uIHNpZGViYXIgc2hhZG93IGlzIHJlbW92ZWQgYW5kIGhlYWRlciBjYW5ub3QgYmUgbWFrZSBgZml4ZWRgLlxyXG4gKlxyXG4gKiBAYWRkaXRpb25hbC1leGFtcGxlKFJpZ2h0IFNpZGViYXIsIHNpZGViYXIvc2lkZWJhci1yaWdodC5jb21wb25lbnQpXHJcbiAqIEBhZGRpdGlvbmFsLWV4YW1wbGUoRml4ZWQgU2lkZWJhciwgc2lkZWJhci9zaWRlYmFyLWZpeGVkLmNvbXBvbmVudClcclxuICpcclxuICogQHN0eWxlc1xyXG4gKlxyXG4gKiBzaWRlYmFyLWZvbnQtc2l6ZTogU2lkZWJhciBjb250ZW50IGZvbnQgc2l6ZVxyXG4gKiBzaWRlYmFyLWxpbmUtaGVpZ2h0OiBTaWRlYmFyIGNvbnRlbnQgbGluZSBoZWlnaHRcclxuICogc2lkZWJhci1mZzogRm9yZWdyb3VuZCBjb2xvclxyXG4gKiBzaWRlYmFyLWJnOiBCYWNrZ3JvdW5kIGNvbG9yXHJcbiAqIHNpZGViYXItaGVpZ2h0OiBDb250ZW50IGhlaWdodFxyXG4gKiBzaWRlYmFyLXdpZHRoOiBFeHBhbmRlZCB3aWR0aFxyXG4gKiBzaWRlYmFyLXdpZHRoLWNvbXBhY3Q6IENvbXBhY3RlZCB3aWR0aFxyXG4gKiBzaWRlYmFyLXBhZGRpbmc6IFNpZGViYXIgY29udGVudCBwYWRkaW5nXHJcbiAqIHNpZGViYXItaGVhZGVyLWhlaWdodDogU2lkZWJhciBoZWFkZXIgaGVpZ2h0XHJcbiAqIHNpZGViYXItZm9vdGVyLWhlaWdodDogU2lkZWJhciBmb290ZXIgaGVpZ2h0XHJcbiAqIHNpZGViYXItc2hhZG93OiBTaWRlYmFyIGNvbnRhaW5lciBzaGFkb3dcclxuICpcclxuICovXHJcbkBDb21wb25lbnQoe1xyXG4gIHNlbGVjdG9yOiAnbmItc2lkZWJhcicsXHJcbiAgc3R5bGVVcmxzOiBbJy4vc2lkZWJhci5jb21wb25lbnQuc2NzcyddLFxyXG4gIHRlbXBsYXRlOiBgXHJcbiAgICA8ZGl2IGNsYXNzPVwibWFpbi1jb250YWluZXJcIlxyXG4gICAgICAgICBbY2xhc3MubWFpbi1jb250YWluZXItZml4ZWRdPVwiY29udGFpbmVyRml4ZWRWYWx1ZVwiPlxyXG4gICAgICA8bmctY29udGVudCBzZWxlY3Q9XCJuYi1zaWRlYmFyLWhlYWRlclwiPjwvbmctY29udGVudD5cclxuICAgICAgPGRpdiBjbGFzcz1cInNjcm9sbGFibGVcIiAoY2xpY2spPVwib25DbGljaygkZXZlbnQpXCI+XHJcbiAgICAgICAgPG5nLWNvbnRlbnQ+PC9uZy1jb250ZW50PlxyXG4gICAgICA8L2Rpdj5cclxuICAgICAgPG5nLWNvbnRlbnQgc2VsZWN0PVwibmItc2lkZWJhci1mb290ZXJcIj48L25nLWNvbnRlbnQ+XHJcbiAgICA8L2Rpdj5cclxuICBgLFxyXG59KVxyXG5leHBvcnQgY2xhc3MgTmJTaWRlYmFyQ29tcG9uZW50IGltcGxlbWVudHMgT25DaGFuZ2VzLCBPbkluaXQsIE9uRGVzdHJveSB7XHJcblxyXG4gIHN0YXRpYyByZWFkb25seSBTVEFURV9FWFBBTkRFRDogc3RyaW5nID0gJ2V4cGFuZGVkJztcclxuICBzdGF0aWMgcmVhZG9ubHkgU1RBVEVfQ09MTEFQU0VEOiBzdHJpbmcgPSAnY29sbGFwc2VkJztcclxuICBzdGF0aWMgcmVhZG9ubHkgU1RBVEVfQ09NUEFDVEVEOiBzdHJpbmcgPSAnY29tcGFjdGVkJztcclxuXHJcbiAgc3RhdGljIHJlYWRvbmx5IFJFU1BPTlNJVkVfU1RBVEVfTU9CSUxFOiBzdHJpbmcgPSAnbW9iaWxlJztcclxuICBzdGF0aWMgcmVhZG9ubHkgUkVTUE9OU0lWRV9TVEFURV9UQUJMRVQ6IHN0cmluZyA9ICd0YWJsZXQnO1xyXG4gIHN0YXRpYyByZWFkb25seSBSRVNQT05TSVZFX1NUQVRFX1BDOiBzdHJpbmcgPSAncGMnO1xyXG5cclxuICBwcm90ZWN0ZWQgc3RhdGVWYWx1ZTogc3RyaW5nO1xyXG4gIHByb3RlY3RlZCByZXNwb25zaXZlVmFsdWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgcHJpdmF0ZSBhbGl2ZSA9IHRydWU7XHJcblxyXG4gIGNvbnRhaW5lckZpeGVkVmFsdWU6IGJvb2xlYW4gPSB0cnVlO1xyXG5cclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmZpeGVkJykgZml4ZWRWYWx1ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBIb3N0QmluZGluZygnY2xhc3MucmlnaHQnKSByaWdodFZhbHVlOiBib29sZWFuID0gZmFsc2U7XHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5sZWZ0JykgbGVmdFZhbHVlOiBib29sZWFuID0gdHJ1ZTtcclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLnN0YXJ0Jykgc3RhcnRWYWx1ZTogYm9vbGVhbiA9IGZhbHNlO1xyXG4gIEBIb3N0QmluZGluZygnY2xhc3MuZW5kJykgZW5kVmFsdWU6IGJvb2xlYW4gPSBmYWxzZTtcclxuXHJcbiAgLy8gVE9ETzogcmVuYW1lIHN0YXRlVmFsdWUgdG8gc3RhdGUgKHRha2UgYSBsb29rIHRvIHRoZSBjYXJkIGNvbXBvbmVudClcclxuICBASG9zdEJpbmRpbmcoJ2NsYXNzLmV4cGFuZGVkJylcclxuICBnZXQgZXhwYW5kZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGF0ZVZhbHVlID09PSBOYlNpZGViYXJDb21wb25lbnQuU1RBVEVfRVhQQU5ERUQ7XHJcbiAgfVxyXG4gIEBIb3N0QmluZGluZygnY2xhc3MuY29sbGFwc2VkJylcclxuICBnZXQgY29sbGFwc2VkKCkge1xyXG4gICAgcmV0dXJuIHRoaXMuc3RhdGVWYWx1ZSA9PT0gTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0NPTExBUFNFRDtcclxuICB9XHJcbiAgQEhvc3RCaW5kaW5nKCdjbGFzcy5jb21wYWN0ZWQnKVxyXG4gIGdldCBjb21wYWN0ZWQoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5zdGF0ZVZhbHVlID09PSBOYlNpZGViYXJDb21wb25lbnQuU1RBVEVfQ09NUEFDVEVEO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBQbGFjZXMgc2lkZWJhciBvbiB0aGUgcmlnaHQgc2lkZVxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHJpZ2h0KHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5yaWdodFZhbHVlID0gY29udmVydFRvQm9vbFByb3BlcnR5KHZhbCk7XHJcbiAgICB0aGlzLmxlZnRWYWx1ZSA9ICF0aGlzLnJpZ2h0VmFsdWU7XHJcbiAgICB0aGlzLnN0YXJ0VmFsdWUgPSBmYWxzZTtcclxuICAgIHRoaXMuZW5kVmFsdWUgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogUGxhY2VzIHNpZGViYXIgb24gdGhlIGxlZnQgc2lkZVxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGxlZnQodmFsOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmxlZnRWYWx1ZSA9IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSh2YWwpO1xyXG4gICAgdGhpcy5yaWdodFZhbHVlID0gIXRoaXMubGVmdFZhbHVlO1xyXG4gICAgdGhpcy5zdGFydFZhbHVlID0gZmFsc2U7XHJcbiAgICB0aGlzLmVuZFZhbHVlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFBsYWNlcyBzaWRlYmFyIG9uIHRoZSBzdGFydCBlZGdlIG9mIGxheW91dFxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHN0YXJ0KHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5zdGFydFZhbHVlID0gY29udmVydFRvQm9vbFByb3BlcnR5KHZhbCk7XHJcbiAgICB0aGlzLmVuZFZhbHVlID0gIXRoaXMuc3RhcnRWYWx1ZTtcclxuICAgIHRoaXMubGVmdFZhbHVlID0gZmFsc2U7XHJcbiAgICB0aGlzLnJpZ2h0VmFsdWUgPSBmYWxzZTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogUGxhY2VzIHNpZGViYXIgb24gdGhlIGVuZCBlZGdlIG9mIGxheW91dFxyXG4gICAqIEB0eXBlIHtib29sZWFufVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGVuZCh2YWw6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuZW5kVmFsdWUgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkodmFsKTtcclxuICAgIHRoaXMuc3RhcnRWYWx1ZSA9ICF0aGlzLmVuZFZhbHVlO1xyXG4gICAgdGhpcy5sZWZ0VmFsdWUgPSBmYWxzZTtcclxuICAgIHRoaXMucmlnaHRWYWx1ZSA9IGZhbHNlO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBNYWtlcyBzaWRlYmFyIGZpeGVkIChzaG93biBhYm92ZSB0aGUgbGF5b3V0IGNvbnRlbnQpXHJcbiAgICogQHR5cGUge2Jvb2xlYW59XHJcbiAgICovXHJcbiAgQElucHV0KClcclxuICBzZXQgZml4ZWQodmFsOiBib29sZWFuKSB7XHJcbiAgICB0aGlzLmZpeGVkVmFsdWUgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkodmFsKTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogTWFrZXMgc2lkZWJhciBjb250YWluZXIgZml4ZWRcclxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCBjb250YWluZXJGaXhlZCh2YWw6IGJvb2xlYW4pIHtcclxuICAgIHRoaXMuY29udGFpbmVyRml4ZWRWYWx1ZSA9IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSh2YWwpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBJbml0aWFsIHNpZGViYXIgc3RhdGUsIGBleHBhbmRlZGB8YGNvbGxhcHNlZGB8YGNvbXBhY3RlZGBcclxuICAgKiBAdHlwZSB7c3RyaW5nfVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IHN0YXRlKHZhbDogc3RyaW5nKSB7XHJcbiAgICB0aGlzLnN0YXRlVmFsdWUgPSB2YWw7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIE1ha2VzIHNpZGViYXIgbGlzdGVuIHRvIG1lZGlhIHF1ZXJ5IGV2ZW50cyBhbmQgY2hhbmdlIGl0cyBiZWhhdmlvdXJcclxuICAgKiBAdHlwZSB7Ym9vbGVhbn1cclxuICAgKi9cclxuICBASW5wdXQoKVxyXG4gIHNldCByZXNwb25zaXZlKHZhbDogYm9vbGVhbikge1xyXG4gICAgdGhpcy5yZXNwb25zaXZlVmFsdWUgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkodmFsKTtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogVGFncyBhIHNpZGViYXIgd2l0aCBzb21lIElELCBjYW4gYmUgbGF0ZXIgdXNlZCBpbiB0aGUgc2lkZWJhciBzZXJ2aWNlXHJcbiAgICogdG8gZGV0ZXJtaW5lIHdoaWNoIHNpZGViYXIgdHJpZ2dlcmVkIHRoZSBhY3Rpb24sIGlmIG11bHRpcGxlIHNpZGViYXJzIGV4aXN0IG9uIHRoZSBwYWdlLlxyXG4gICAqXHJcbiAgICogQHR5cGUge3N0cmluZ31cclxuICAgKi9cclxuICBASW5wdXQoKSB0YWc6IHN0cmluZztcclxuXHJcbiAgLy8gVE9ETzogZ2V0IHdpZHRoIGJ5IHRoZSBrZXkgYW5kIGRlZmluZSBvbmx5IG1heCB3aWR0aCBmb3IgdGhlIHRhYmxldHMgYW5kIG1vYmlsZXNcclxuICAvKlxyXG4gICAqIENvbnRyb2xzIG9uIHdoaWNoIHNjcmVlbiBzaXplcyBzaWRlYmFyIHNob3VsZCBiZSBzd2l0Y2hlZCB0byBjb21wYWN0ZWQgc3RhdGUuXHJcbiAgICogV29ya3Mgb25seSB3aGVuIHJlc3BvbnNpdmUgbW9kZSBpcyBvbi5cclxuICAgKiBEZWZhdWx0IHZhbHVlcyBhcmUgYFsneHMnLCAnaXMnLCAnc20nLCAnbWQnLCAnbGcnXWAuXHJcbiAgICpcclxuICAgKiBAdHlwZSBzdHJpbmdbXVxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGNvbXBhY3RlZEJyZWFrcG9pbnRzOiBzdHJpbmdbXSA9IFsneHMnLCAnaXMnLCAnc20nLCAnbWQnLCAnbGcnXTtcclxuXHJcbiAgLypcclxuICAgKiBDb250cm9scyBvbiB3aGljaCBzY3JlZW4gc2l6ZXMgc2lkZWJhciBzaG91bGQgYmUgc3dpdGNoZWQgdG8gY29sbGFwc2VkIHN0YXRlLlxyXG4gICAqIFdvcmtzIG9ubHkgd2hlbiByZXNwb25zaXZlIG1vZGUgaXMgb24uXHJcbiAgICogRGVmYXVsdCB2YWx1ZXMgYXJlIGBbJ3hzJywgJ2lzJ11gLlxyXG4gICAqXHJcbiAgICogQHR5cGUgc3RyaW5nW11cclxuICAgKi9cclxuICBASW5wdXQoKSBjb2xsYXBzZWRCcmVha3BvaW50czogc3RyaW5nW10gPSBbJ3hzJywgJ2lzJ107XHJcblxyXG4gIHByaXZhdGUgbWVkaWFRdWVyeVN1YnNjcmlwdGlvbjogU3Vic2NyaXB0aW9uO1xyXG4gIHByaXZhdGUgcmVzcG9uc2l2ZVN0YXRlID0gTmJTaWRlYmFyQ29tcG9uZW50LlJFU1BPTlNJVkVfU1RBVEVfUEM7XHJcblxyXG4gIGNvbnN0cnVjdG9yKHByaXZhdGUgc2lkZWJhclNlcnZpY2U6IE5iU2lkZWJhclNlcnZpY2UsXHJcbiAgICBwcml2YXRlIHRoZW1lU2VydmljZTogTmJUaGVtZVNlcnZpY2UsXHJcbiAgICBwcml2YXRlIGVsZW1lbnQ6IEVsZW1lbnRSZWYpIHtcclxuICB9XHJcblxyXG4gIHRvZ2dsZVJlc3BvbnNpdmUoZW5hYmxlZDogYm9vbGVhbikge1xyXG4gICAgaWYgKGVuYWJsZWQpIHtcclxuICAgICAgdGhpcy5tZWRpYVF1ZXJ5U3Vic2NyaXB0aW9uID0gdGhpcy5vbk1lZGlhUXVlcnlDaGFuZ2VzKCk7XHJcbiAgICB9IGVsc2UgaWYgKHRoaXMubWVkaWFRdWVyeVN1YnNjcmlwdGlvbikge1xyXG4gICAgICB0aGlzLm1lZGlhUXVlcnlTdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25DaGFuZ2VzKGNoYW5nZXMpIHtcclxuICAgIGlmIChjaGFuZ2VzLnJlc3BvbnNpdmUpIHtcclxuICAgICAgdGhpcy50b2dnbGVSZXNwb25zaXZlKHRoaXMucmVzcG9uc2l2ZVZhbHVlKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIG5nT25Jbml0KCkge1xyXG4gICAgdGhpcy5zaWRlYmFyU2VydmljZS5vblRvZ2dsZSgpXHJcbiAgICAgIC5waXBlKHRha2VXaGlsZSgoKSA9PiB0aGlzLmFsaXZlKSlcclxuICAgICAgLnN1YnNjcmliZSgoZGF0YTogeyBjb21wYWN0OiBib29sZWFuLCB0YWc6IHN0cmluZyB9KSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnRhZyB8fCB0aGlzLnRhZyA9PT0gZGF0YS50YWcpIHtcclxuICAgICAgICAgIHRoaXMudG9nZ2xlKGRhdGEuY29tcGFjdCk7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuXHJcbiAgICB0aGlzLnNpZGViYXJTZXJ2aWNlLm9uRXhwYW5kKClcclxuICAgICAgLnBpcGUodGFrZVdoaWxlKCgpID0+IHRoaXMuYWxpdmUpKVxyXG4gICAgICAuc3Vic2NyaWJlKChkYXRhOiB7IHRhZzogc3RyaW5nIH0pID0+IHtcclxuICAgICAgICBpZiAoIXRoaXMudGFnIHx8IHRoaXMudGFnID09PSBkYXRhLnRhZykge1xyXG4gICAgICAgICAgdGhpcy5leHBhbmQoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG5cclxuICAgIHRoaXMuc2lkZWJhclNlcnZpY2Uub25Db2xsYXBzZSgpXHJcbiAgICAgIC5waXBlKHRha2VXaGlsZSgoKSA9PiB0aGlzLmFsaXZlKSlcclxuICAgICAgLnN1YnNjcmliZSgoZGF0YTogeyB0YWc6IHN0cmluZyB9KSA9PiB7XHJcbiAgICAgICAgaWYgKCF0aGlzLnRhZyB8fCB0aGlzLnRhZyA9PT0gZGF0YS50YWcpIHtcclxuICAgICAgICAgIHRoaXMuY29sbGFwc2UoKTtcclxuICAgICAgICB9XHJcbiAgICAgIH0pO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmFsaXZlID0gZmFsc2U7XHJcbiAgICBpZiAodGhpcy5tZWRpYVF1ZXJ5U3Vic2NyaXB0aW9uKSB7XHJcbiAgICAgIHRoaXMubWVkaWFRdWVyeVN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpO1xyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgLy8gVE9ETzogdGhpcyBpcyBtb3JlIG9mIGEgd29ya2Fyb3VuZCwgc2hvdWxkIGJlIGEgYmV0dGVyIHdheSB0byBtYWtlIGNvbXBvbmVudHMgY29tbXVuaWNhdGUgdG8gZWFjaCBvdGhlclxyXG4gIG9uQ2xpY2soZXZlbnQpOiB2b2lkIHtcclxuICAgIGNvbnN0IG1lbnUgPSB0aGlzLmVsZW1lbnQubmF0aXZlRWxlbWVudC5xdWVyeVNlbGVjdG9yKCduYi1tZW51Jyk7XHJcblxyXG4gICAgaWYgKG1lbnUgJiYgbWVudS5jb250YWlucyhldmVudC50YXJnZXQpKSB7XHJcbiAgICAgIGxldCBsaW5rID0gZXZlbnQudGFyZ2V0O1xyXG4gICAgICBjb25zdCBsaW5rQ2hpbGRyZW4gPSBbJ3NwYW4nLCAnaSddO1xyXG5cclxuICAgICAgLy8gaWYgd2UgY2xpY2tlZCBvbiBzcGFuIC0gZ2V0IHRoZSBsaW5rXHJcbiAgICAgIGlmIChsaW5rQ2hpbGRyZW4uaW5jbHVkZXMobGluay50YWdOYW1lLnRvTG93ZXJDYXNlKCkpICYmIGxpbmsucGFyZW50Tm9kZSkge1xyXG4gICAgICAgIGxpbmsgPSBldmVudC50YXJnZXQucGFyZW50Tm9kZTtcclxuICAgICAgfVxyXG5cclxuICAgICAgLy8gd2Ugb25seSBleHBhbmQgaWYgYW4gaXRlbSBoYXMgY2hpbGRyZW5cclxuICAgICAgaWYgKGxpbmsgJiYgbGluay5uZXh0RWxlbWVudFNpYmxpbmcgJiYgbGluay5uZXh0RWxlbWVudFNpYmxpbmcuY2xhc3NMaXN0LmNvbnRhaW5zKCdtZW51LWl0ZW1zJykpIHtcclxuICAgICAgICB0aGlzLmV4cGFuZCgpO1xyXG4gICAgICB9XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIENvbGxhcHNlcyB0aGUgc2lkZWJhclxyXG4gICAqL1xyXG4gIGNvbGxhcHNlKCkge1xyXG4gICAgdGhpcy5zdGF0ZSA9IE5iU2lkZWJhckNvbXBvbmVudC5TVEFURV9DT0xMQVBTRUQ7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIEV4cGFuZHMgdGhlIHNpZGViYXJcclxuICAgKi9cclxuICBleHBhbmQoKSB7XHJcbiAgICB0aGlzLnN0YXRlID0gTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0VYUEFOREVEO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBDb21wYWN0cyB0aGUgc2lkZWJhciAobWluaW1pemVzKVxyXG4gICAqL1xyXG4gIGNvbXBhY3QoKSB7XHJcbiAgICB0aGlzLnN0YXRlID0gTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0NPTVBBQ1RFRDtcclxuICB9XHJcblxyXG4gIC8qXHJcbiAgICogVG9nZ2xlcyBzaWRlYmFyIHN0YXRlIChleHBhbmRlZHxjb2xsYXBzZWR8Y29tcGFjdGVkKVxyXG4gICAqIEBwYXJhbSB7Ym9vbGVhbn0gY29tcGFjdCBJZiB0cnVlLCB0aGVuIHNpZGViYXIgc3RhdGUgd2lsbCBiZSBjaGFuZ2VkIGJldHdlZW4gZXhwYW5kZWQgJiBjb21wYWN0ZWQsXHJcbiAgICogb3RoZXJ3aXNlIC0gYmV0d2VlbiBleHBhbmRlZCAmIGNvbGxhcHNlZC4gRmFsc2UgYnkgZGVmYXVsdC5cclxuICAgKlxyXG4gICAqIFRvZ2dsZSBzaWRlYmFyIHN0YXRlXHJcbiAgICpcclxuICAgKiBgYGB0c1xyXG4gICAqIHRoaXMuc2lkZWJhci50b2dnbGUodHJ1ZSk7XHJcbiAgICogYGBgXHJcbiAgICovXHJcbiAgdG9nZ2xlKGNvbXBhY3Q6IGJvb2xlYW4gPSBmYWxzZSkge1xyXG4gICAgaWYgKHRoaXMucmVzcG9uc2l2ZUVuYWJsZWQoKSkge1xyXG4gICAgICBpZiAodGhpcy5yZXNwb25zaXZlU3RhdGUgPT09IE5iU2lkZWJhckNvbXBvbmVudC5SRVNQT05TSVZFX1NUQVRFX01PQklMRSkge1xyXG4gICAgICAgIGNvbXBhY3QgPSBmYWxzZTtcclxuICAgICAgfVxyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IGNsb3NlZFN0YXRlcyA9IFtOYlNpZGViYXJDb21wb25lbnQuU1RBVEVfQ09NUEFDVEVELCBOYlNpZGViYXJDb21wb25lbnQuU1RBVEVfQ09MTEFQU0VEXTtcclxuICAgIGlmIChjb21wYWN0KSB7XHJcbiAgICAgIHRoaXMuc3RhdGUgPSBjbG9zZWRTdGF0ZXMuaW5jbHVkZXModGhpcy5zdGF0ZVZhbHVlKSA/XHJcbiAgICAgICAgTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0VYUEFOREVEIDogTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0NPTVBBQ1RFRDtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMuc3RhdGUgPSBjbG9zZWRTdGF0ZXMuaW5jbHVkZXModGhpcy5zdGF0ZVZhbHVlKSA/XHJcbiAgICAgICAgTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0VYUEFOREVEIDogTmJTaWRlYmFyQ29tcG9uZW50LlNUQVRFX0NPTExBUFNFRDtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCBvbk1lZGlhUXVlcnlDaGFuZ2VzKCk6IFN1YnNjcmlwdGlvbiB7XHJcbiAgICByZXR1cm4gdGhpcy50aGVtZVNlcnZpY2Uub25NZWRpYVF1ZXJ5Q2hhbmdlKClcclxuICAgICAgLnN1YnNjcmliZSgoW3ByZXYsIGN1cnJlbnRdOiBbTmJNZWRpYUJyZWFrcG9pbnQsIE5iTWVkaWFCcmVha3BvaW50XSkgPT4ge1xyXG5cclxuICAgICAgICBjb25zdCBpc0NvbGxhcHNlZCA9IHRoaXMuY29sbGFwc2VkQnJlYWtwb2ludHMuaW5jbHVkZXMoY3VycmVudC5uYW1lKTtcclxuICAgICAgICBjb25zdCBpc0NvbXBhY3RlZCA9IHRoaXMuY29tcGFjdGVkQnJlYWtwb2ludHMuaW5jbHVkZXMoY3VycmVudC5uYW1lKTtcclxuXHJcbiAgICAgICAgaWYgKGlzQ29tcGFjdGVkKSB7XHJcbiAgICAgICAgICB0aGlzLmZpeGVkID0gdGhpcy5jb250YWluZXJGaXhlZFZhbHVlO1xyXG4gICAgICAgICAgdGhpcy5jb21wYWN0KCk7XHJcbiAgICAgICAgICB0aGlzLnJlc3BvbnNpdmVTdGF0ZSA9IE5iU2lkZWJhckNvbXBvbmVudC5SRVNQT05TSVZFX1NUQVRFX1RBQkxFVDtcclxuICAgICAgICB9XHJcbiAgICAgICAgaWYgKGlzQ29sbGFwc2VkKSB7XHJcbiAgICAgICAgICB0aGlzLmZpeGVkID0gdHJ1ZTtcclxuICAgICAgICAgIHRoaXMuY29sbGFwc2UoKTtcclxuICAgICAgICAgIHRoaXMucmVzcG9uc2l2ZVN0YXRlID0gTmJTaWRlYmFyQ29tcG9uZW50LlJFU1BPTlNJVkVfU1RBVEVfTU9CSUxFO1xyXG4gICAgICAgIH1cclxuICAgICAgICBpZiAoIWlzQ29sbGFwc2VkICYmICFpc0NvbXBhY3RlZCAmJiBwcmV2LndpZHRoIDwgY3VycmVudC53aWR0aCkge1xyXG4gICAgICAgICAgdGhpcy5leHBhbmQoKTtcclxuICAgICAgICAgIHRoaXMuZml4ZWQgPSBmYWxzZTtcclxuICAgICAgICAgIHRoaXMucmVzcG9uc2l2ZVN0YXRlID0gTmJTaWRlYmFyQ29tcG9uZW50LlJFU1BPTlNJVkVfU1RBVEVfUEM7XHJcbiAgICAgICAgfVxyXG4gICAgICB9KTtcclxuICB9XHJcblxyXG4gIHByb3RlY3RlZCByZXNwb25zaXZlRW5hYmxlZCgpOiBib29sZWFuIHtcclxuICAgIHJldHVybiB0aGlzLnJlc3BvbnNpdmVWYWx1ZTtcclxuICB9XHJcbn1cclxuIl19