UNPKG

ngx-hide-on-scroll

Version:

Hide an element on scroll down or up in Angular.

150 lines 19.9 kB
import { Directive, ElementRef, Inject, PLATFORM_ID, Input, Renderer2, Output, EventEmitter } from '@angular/core'; import { fromEvent, Subject } from 'rxjs'; import { distinctUntilChanged, filter, map, pairwise, share, takeUntil, throttleTime } from 'rxjs/operators'; import { isPlatformServer } from '@angular/common'; // Inspired by: https://netbasal.com/reactive-sticky-header-in-angular-12dbffb3f1d3 /** * The `ngxHideOnScroll` directive allows you to hide an html element (e.g. navbar) on scroll down and show it again on scroll up. */ export class NgxHideOnScrollDirective { constructor(elementRef, renderer2, platformId) { this.elementRef = elementRef; this.renderer2 = renderer2; this.platformId = platformId; /** * `'Down'`: The element will be hidden on scroll down and it will be shown again on scroll up.<br/>`Up`: The element will be hidden on scroll up and it will be shown again on scroll down. */ this.hideOnScroll = 'Down'; /** * CSS class name added to the element to hide it. When this property is set, `propertyUsedToHide`, `valueWhenHidden`, and `valueWhenShown` have not effect. */ this.classNameWhenHidden = ''; /** * The CSS property used to hide/show the element. * * @default * 'transform' */ this.propertyUsedToHide = 'transform'; /** * The value of `propertyUsedToHide` when the element is hidden. * * @default * 'translateY(-100%)' */ this.valueWhenHidden = 'translateY(-100%)'; /** * The value of `propertyUsedToHide` when the element is shown. * * @default * 'translateY(0)' */ this.valueWhenShown = 'translateY(0)'; /** * The selector of the element you want to listen the scroll event, in case it is not the default browser scrolling element (`document.scrollingElement` or `document.documentElement`). For example [` .mat-sidenav-content`]( https://stackoverflow.com/a/52931772/12954396) if you are using [Angular Material Sidenav]( https://material.angular.io/components/sidenav) */ this.scrollingElementSelector = ''; /** * Emitted when the element is hidden. */ this.eventElementHidden = new EventEmitter(); /** * Emitted when the element is shown. */ this.eventElementShown = new EventEmitter(); this.unsubscribeNotifier = new Subject(); } ngAfterViewInit() { if (isPlatformServer(this.platformId)) { return; } let elementToListenScrollEvent; let scrollingElement; if (!this.scrollingElementSelector) { elementToListenScrollEvent = window; scrollingElement = this.getDefaultScrollingElement(); } else { scrollingElement = document.querySelector(this.scrollingElementSelector); if (!scrollingElement) { console.error(`NgxHideOnScroll: @Input() scrollingElementSelector\nElement with selector: "${this.scrollingElementSelector}" not found.`); return; } elementToListenScrollEvent = scrollingElement; } const scroll$ = fromEvent(elementToListenScrollEvent, 'scroll').pipe(takeUntil(this.unsubscribeNotifier), throttleTime(50), // only emit every 50 ms map(() => scrollingElement.scrollTop), // get vertical scroll position pairwise(), // look at this and the last emitted element // compare this and the last element to figure out scrolling direction map(([y1, y2]) => (y2 < y1 ? ScrollDirection.Up : ScrollDirection.Down)), distinctUntilChanged(), // only emit when scrolling direction changed share() // share a single subscription to the underlying sequence in case of multiple subscribers ); const scrollUp$ = scroll$.pipe(filter(direction => direction === ScrollDirection.Up)); const scrollDown$ = scroll$.pipe(filter(direction => direction === ScrollDirection.Down)); let scrollUpAction; let scrollDownAction; if (this.hideOnScroll === 'Up') { scrollUpAction = () => this.hideElement(); scrollDownAction = () => this.showElement(); } else { scrollUpAction = () => this.showElement(); scrollDownAction = () => this.hideElement(); } scrollUp$.subscribe(() => scrollUpAction()); scrollDown$.subscribe(() => scrollDownAction()); } ngOnDestroy() { this.unsubscribeNotifier.next(); this.unsubscribeNotifier.complete(); } hideElement() { const nativeElement = this.elementRef.nativeElement; if (this.classNameWhenHidden) { this.renderer2.addClass(nativeElement, this.classNameWhenHidden); } else { this.renderer2.setStyle(nativeElement, this.propertyUsedToHide, this.valueWhenHidden); } this.eventElementHidden.emit(); } showElement() { const nativeElement = this.elementRef.nativeElement; if (this.classNameWhenHidden) { this.renderer2.removeClass(nativeElement, this.classNameWhenHidden); } else { this.renderer2.setStyle(nativeElement, this.propertyUsedToHide, this.valueWhenShown); } this.eventElementShown.emit(); } getDefaultScrollingElement() { return (document.scrollingElement || document.documentElement); } } NgxHideOnScrollDirective.decorators = [ { type: Directive, args: [{ selector: '[ngxHideOnScroll]' },] } ]; NgxHideOnScrollDirective.ctorParameters = () => [ { type: ElementRef }, { type: Renderer2 }, { type: String, decorators: [{ type: Inject, args: [PLATFORM_ID,] }] } ]; NgxHideOnScrollDirective.propDecorators = { hideOnScroll: [{ type: Input }], classNameWhenHidden: [{ type: Input }], propertyUsedToHide: [{ type: Input }], valueWhenHidden: [{ type: Input }], valueWhenShown: [{ type: Input }], scrollingElementSelector: [{ type: Input }], eventElementHidden: [{ type: Output }], eventElementShown: [{ type: Output }] }; var ScrollDirection; (function (ScrollDirection) { ScrollDirection["Up"] = "Up"; ScrollDirection["Down"] = "Down"; })(ScrollDirection || (ScrollDirection = {})); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibmd4LWhpZGUtb24tc2Nyb2xsLmRpcmVjdGl2ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uL3Byb2plY3RzL25neC1oaWRlLW9uLXNjcm9sbC9zcmMvbGliL25neC1oaWRlLW9uLXNjcm9sbC5kaXJlY3RpdmUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQWlCLE1BQU0sRUFBRSxXQUFXLEVBQWEsS0FBSyxFQUFFLFNBQVMsRUFBRSxNQUFNLEVBQUUsWUFBWSxFQUFFLE1BQU0sZUFBZSxDQUFDO0FBQzdJLE9BQU8sRUFBRSxTQUFTLEVBQUUsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBQzFDLE9BQU8sRUFDTCxvQkFBb0IsRUFDcEIsTUFBTSxFQUNOLEdBQUcsRUFDSCxRQUFRLEVBQ1IsS0FBSyxFQUNMLFNBQVMsRUFDVCxZQUFZLEVBQ2IsTUFBTSxnQkFBZ0IsQ0FBQztBQUN4QixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVuRCxtRkFBbUY7QUFFbkY7O0dBRUc7QUFJSCxNQUFNLE9BQU8sd0JBQXdCO0lBcURuQyxZQUNVLFVBQW1DLEVBQ25DLFNBQW9CLEVBQ0MsVUFBa0I7UUFGdkMsZUFBVSxHQUFWLFVBQVUsQ0FBeUI7UUFDbkMsY0FBUyxHQUFULFNBQVMsQ0FBVztRQUNDLGVBQVUsR0FBVixVQUFVLENBQVE7UUF0RGpEOztXQUVHO1FBQ00saUJBQVksR0FBa0IsTUFBTSxDQUFDO1FBRTlDOztXQUVHO1FBQ00sd0JBQW1CLEdBQVcsRUFBRSxDQUFDO1FBRTFDOzs7OztXQUtHO1FBQ00sdUJBQWtCLEdBQThDLFdBQVcsQ0FBQztRQUVyRjs7Ozs7V0FLRztRQUNNLG9CQUFlLEdBQVcsbUJBQW1CLENBQUM7UUFFdkQ7Ozs7O1dBS0c7UUFDTSxtQkFBYyxHQUFXLGVBQWUsQ0FBQztRQUVsRDs7V0FFRztRQUNNLDZCQUF3QixHQUFX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QyxXQUFXOzs7MkJBbkRwQixLQUFLO2tDQUtMLEtBQUs7aUNBUUwsS0FBSzs4QkFRTCxLQUFLOzZCQVFMLEtBQUs7dUNBS0wsS0FBSztpQ0FLTCxNQUFNO2dDQUtOLE1BQU07O0FBNEZULElBQUssZUFHSjtBQUhELFdBQUssZUFBZTtJQUNsQiw0QkFBUyxDQUFBO0lBQ1QsZ0NBQWEsQ0FBQTtBQUNmLENBQUMsRUFISSxlQUFlLEtBQWYsZUFBZSxRQUduQiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IERpcmVjdGl2ZSwgRWxlbWVudFJlZiwgQWZ0ZXJWaWV3SW5pdCwgSW5qZWN0LCBQTEFURk9STV9JRCwgT25EZXN0cm95LCBJbnB1dCwgUmVuZGVyZXIyLCBPdXRwdXQsIEV2ZW50RW1pdHRlciB9IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBmcm9tRXZlbnQsIFN1YmplY3QgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHtcclxuICBkaXN0aW5jdFVudGlsQ2hhbmdlZCxcclxuICBmaWx0ZXIsXHJcbiAgbWFwLFxyXG4gIHBhaXJ3aXNlLFxyXG4gIHNoYXJlLFxyXG4gIHRha2VVbnRpbCxcclxuICB0aHJvdHRsZVRpbWVcclxufSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IGlzUGxhdGZvcm1TZXJ2ZXIgfSBmcm9tICdAYW5ndWxhci9jb21tb24nO1xyXG5cclxuLy8gSW5zcGlyZWQgYnk6IGh0dHBzOi8vbmV0YmFzYWwuY29tL3JlYWN0aXZlLXN0aWNreS1oZWFkZXItaW4tYW5ndWxhci0xMmRiZmZiM2YxZDNcclxuXHJcbi8qKlxyXG4gKiBUaGUgYG5neEhpZGVPblNjcm9sbGAgZGlyZWN0aXZlIGFsbG93cyB5b3UgdG8gaGlkZSBhbiBodG1sIGVsZW1lbnQgKGUuZy4gbmF2YmFyKSBvbiBzY3JvbGwgZG93biBhbmQgc2hvdyBpdCBhZ2FpbiBvbiBzY3JvbGwgdXAuXHJcbiAqL1xyXG5ARGlyZWN0aXZlKHtcclxuICBzZWxlY3RvcjogJ1tuZ3hIaWRlT25TY3JvbGxdJ1xyXG59KVxyXG5leHBvcnQgY2xhc3MgTmd4SGlkZU9uU2Nyb2xsRGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgLyoqXHJcbiAgICogYCdEb3duJ2A6IFRoZSBlbGVtZW50IHdpbGwgYmUgaGlkZGVuIG9uIHNjcm9sbCBkb3duIGFuZCBpdCB3aWxsIGJlIHNob3duIGFnYWluIG9uIHNjcm9sbCB1cC48YnIvPmBVcGA6IFRoZSBlbGVtZW50IHdpbGwgYmUgaGlkZGVuIG9uIHNjcm9sbCB1cCBhbmQgaXQgd2lsbCBiZSBzaG93biBhZ2FpbiBvbiBzY3JvbGwgZG93bi5cclxuICAgKi9cclxuICBASW5wdXQoKSBoaWRlT25TY3JvbGw6ICdEb3duJyB8ICdVcCcgPSAnRG93bic7XHJcblxyXG4gIC8qKlxyXG4gICAqIENTUyBjbGFzcyBuYW1lIGFkZGVkIHRvIHRoZSBlbGVtZW50IHRvIGhpZGUgaXQuIFdoZW4gdGhpcyBwcm9wZXJ0eSBpcyBzZXQsIGBwcm9wZXJ0eVVzZWRUb0hpZGVgLCBgdmFsdWVXaGVuSGlkZGVuYCwgYW5kIGB2YWx1ZVdoZW5TaG93bmAgaGF2ZSBub3QgZWZmZWN0LlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpIGNsYXNzTmFtZVdoZW5IaWRkZW46IHN0cmluZyA9ICcnO1xyXG5cclxuICAvKipcclxuICAgKiBUaGUgQ1NTIHByb3BlcnR5IHVzZWQgdG8gaGlkZS9zaG93IHRoZSBlbGVtZW50LlxyXG4gICAqIFxyXG4gICAqIEBkZWZhdWx0XHJcbiAgICogJ3RyYW5zZm9ybSdcclxuICAgKi9cclxuICBASW5wdXQoKSBwcm9wZXJ0eVVzZWRUb0hpZGU6ICd0cmFuc2Zvcm0nIHwgJ3RvcCcgfCAnYm90dG9tJyB8ICdoZWlnaHQnID0gJ3RyYW5zZm9ybSc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSB2YWx1ZSBvZiBgcHJvcGVydHlVc2VkVG9IaWRlYCB3aGVuIHRoZSBlbGVtZW50IGlzIGhpZGRlbi5cclxuICAgKiBcclxuICAgKiBAZGVmYXVsdFxyXG4gICAqICd0cmFuc2xhdGVZKC0xMDAlKSdcclxuICAgKi9cclxuICBASW5wdXQoKSB2YWx1ZVdoZW5IaWRkZW46IHN0cmluZyA9ICd0cmFuc2xhdGVZKC0xMDAlKSc7XHJcblxyXG4gIC8qKlxyXG4gICAqIFRoZSB2YWx1ZSBvZiBgcHJvcGVydHlVc2VkVG9IaWRlYCB3aGVuIHRoZSBlbGVtZW50IGlzIHNob3duLlxyXG4gICAqIFxyXG4gICAqIEBkZWZhdWx0XHJcbiAgICogJ3RyYW5zbGF0ZVkoMCknXHJcbiAgICovXHJcbiAgQElucHV0KCkgdmFsdWVXaGVuU2hvd246IHN0cmluZyA9ICd0cmFuc2xhdGVZKDApJztcclxuXHJcbiAgLyoqXHJcbiAgICogVGhlIHNlbGVjdG9yIG9mIHRoZSBlbGVtZW50IHlvdSB3YW50IHRvIGxpc3RlbiB0aGUgc2Nyb2xsIGV2ZW50LCBpbiBjYXNlIGl0IGlzIG5vdCB0aGUgZGVmYXVsdCBicm93c2VyIHNjcm9sbGluZyBlbGVtZW50IChgZG9jdW1lbnQuc2Nyb2xsaW5nRWxlbWVudGAgb3IgYGRvY3VtZW50LmRvY3VtZW50RWxlbWVudGApLiBGb3IgZXhhbXBsZSBbYCAubWF0LXNpZGVuYXYtY29udGVudGBdKCBodHRwczovL3N0YWNrb3ZlcmZsb3cuY29tL2EvNTI5MzE3NzIvMTI5NTQzOTYpIGlmIHlvdSBhcmUgdXNpbmcgW0FuZ3VsYXIgTWF0ZXJpYWwgU2lkZW5hdl0oIGh0dHBzOi8vbWF0ZXJpYWwuYW5ndWxhci5pby9jb21wb25lbnRzL3NpZGVuYXYpXHJcbiAgICovXHJcbiAgQElucHV0KCkgc2Nyb2xsaW5nRWxlbWVudFNlbGVjdG9yOiBzdHJpbmcgPSAnJztcclxuXHJcbiAgLyoqXHJcbiAgICogRW1pdHRlZCB3aGVuIHRoZSBlbGVtZW50IGlzIGhpZGRlbi5cclxuICAgKi9cclxuICBAT3V0cHV0KCkgZXZlbnRFbGVtZW50SGlkZGVuID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICAvKipcclxuICAgKiBFbWl0dGVkIHdoZW4gdGhlIGVsZW1lbnQgaXMgc2hvd24uXHJcbiAgICovXHJcbiAgQE91dHB1dCgpIGV2ZW50RWxlbWVudFNob3duID0gbmV3IEV2ZW50RW1pdHRlcjx2b2lkPigpO1xyXG5cclxuICBwcml2YXRlIHVuc3Vic2NyaWJlTm90aWZpZXIgPSBuZXcgU3ViamVjdCgpO1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZjxIVE1MRWxlbWVudD4sXHJcbiAgICBwcml2YXRlIHJlbmRlcmVyMjogUmVuZGVyZXIyLFxyXG4gICAgQEluamVjdChQTEFURk9STV9JRCkgcHJpdmF0ZSBwbGF0Zm9ybUlkOiBzdHJpbmdcclxuICApIHsgfVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKTogdm9pZCB7XHJcbiAgICBpZiAoaXNQbGF0Zm9ybVNlcnZlcih0aGlzLnBsYXRmb3JtSWQpKSB7XHJcbiAgICAgIHJldHVybjtcclxuICAgIH1cclxuXHJcbiAgICBsZXQgZWxlbWVudFRvTGlzdGVuU2Nyb2xsRXZlbnQ7XHJcbiAgICBsZXQgc2Nyb2xsaW5nRWxlbWVudDogSFRNTEVsZW1lbnQ7XHJcbiAgICBpZiAoIXRoaXMuc2Nyb2xsaW5nRWxlbWVudFNlbGVjdG9yKSB7XHJcbiAgICAgIGVsZW1lbnRUb0xpc3RlblNjcm9sbEV2ZW50ID0gd2luZG93O1xyXG4gICAgICBzY3JvbGxpbmdFbGVtZW50ID0gdGhpcy5nZXREZWZhdWx0U2Nyb2xsaW5nRWxlbWVudCgpO1xyXG4gICAgfSBlbHNlIHtcclxuICAgICAgc2Nyb2xsaW5nRWxlbWVudCA9IGRvY3VtZW50LnF1ZXJ5U2VsZWN0b3IodGhpcy5zY3JvbGxpbmdFbGVtZW50U2VsZWN0b3IpIGFzIEhUTUxFbGVtZW50O1xyXG4gICAgICBpZiAoIXNjcm9sbGluZ0VsZW1lbnQpIHtcclxuICAgICAgICBjb25zb2xlLmVycm9yKGBOZ3hIaWRlT25TY3JvbGw6IEBJbnB1dCgpIHNjcm9sbGluZ0VsZW1lbnRTZWxlY3RvclxcbkVsZW1lbnQgd2l0aCBzZWxlY3RvcjogXCIke3RoaXMuc2Nyb2xsaW5nRWxlbWVudFNlbGVjdG9yfVwiIG5vdCBmb3VuZC5gKTtcclxuICAgICAgICByZXR1cm47XHJcbiAgICAgIH1cclxuICAgICAgZWxlbWVudFRvTGlzdGVuU2Nyb2xsRXZlbnQgPSBzY3JvbGxpbmdFbGVtZW50O1xyXG4gICAgfVxyXG5cclxuICAgIGNvbnN0IHNjcm9sbCQgPSBmcm9tRXZlbnQoZWxlbWVudFRvTGlzdGVuU2Nyb2xsRXZlbnQsICdzY3JvbGwnKS5waXBlKFxyXG4gICAgICB0YWtlVW50aWwodGhpcy51bnN1YnNjcmliZU5vdGlmaWVyKSxcclxuICAgICAgdGhyb3R0bGVUaW1lKDUwKSwgLy8gb25seSBlbWl0IGV2ZXJ5IDUwIG1zXHJcbiAgICAgIG1hcCgoKSA9PiBzY3JvbGxpbmdFbGVtZW50LnNjcm9sbFRvcCksIC8vIGdldCB2ZXJ0aWNhbCBzY3JvbGwgcG9zaXRpb25cclxuICAgICAgcGFpcndpc2UoKSwgIC8vIGxvb2sgYXQgdGhpcyBhbmQgdGhlIGxhc3QgZW1pdHRlZCBlbGVtZW50XHJcbiAgICAgIC8vIGNvbXBhcmUgdGhpcyBhbmQgdGhlIGxhc3QgZWxlbWVudCB0byBmaWd1cmUgb3V0IHNjcm9sbGluZyBkaXJlY3Rpb25cclxuICAgICAgbWFwKChbeTEsIHkyXSk6IFNjcm9sbERpcmVjdGlvbiA9PiAoeTIgPCB5MSA/IFNjcm9sbERpcmVjdGlvbi5VcCA6IFNjcm9sbERpcmVjdGlvbi5Eb3duKSksXHJcbiAgICAgIGRpc3RpbmN0VW50aWxDaGFuZ2VkKCksIC8vIG9ubHkgZW1pdCB3aGVuIHNjcm9sbGluZyBkaXJlY3Rpb24gY2hhbmdlZFxyXG4gICAgICBzaGFyZSgpIC8vIHNoYXJlIGEgc2luZ2xlIHN1YnNjcmlwdGlvbiB0byB0aGUgdW5kZXJseWluZyBzZXF1ZW5jZSBpbiBjYXNlIG9mIG11bHRpcGxlIHN1YnNjcmliZXJzXHJcbiAgICApO1xyXG5cclxuICAgIGNvbnN0IHNjcm9sbFVwJCA9IHNjcm9sbCQucGlwZShcclxuICAgICAgZmlsdGVyKGRpcmVjdGlvbiA9PiBkaXJlY3Rpb24gPT09IFNjcm9sbERpcmVjdGlvbi5VcClcclxuICAgICk7XHJcblxyXG4gICAgY29uc3Qgc2Nyb2xsRG93biQgPSBzY3JvbGwkLnBpcGUoXHJcbiAgICAgIGZpbHRlcihkaXJlY3Rpb24gPT4gZGlyZWN0aW9uID09PSBTY3JvbGxEaXJlY3Rpb24uRG93bilcclxuICAgICk7XHJcblxyXG4gICAgbGV0IHNjcm9sbFVwQWN0aW9uOiAoKSA9PiB2b2lkO1xyXG4gICAgbGV0IHNjcm9sbERvd25BY3Rpb246ICgpID0+IHZvaWQ7XHJcbiAgICBpZiAodGhpcy5oaWRlT25TY3JvbGwgPT09ICdVcCcpIHtcclxuICAgICAgc2Nyb2xsVXBBY3Rpb24gPSAoKSA9PiB0aGlzLmhpZGVFbGVtZW50KCk7XHJcbiAgICAgIHNjcm9sbERvd25BY3Rpb24gPSAoKSA9PiB0aGlzLnNob3dFbGVtZW50KCk7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICBzY3JvbGxVcEFjdGlvbiA9ICgpID0+IHRoaXMuc2hvd0VsZW1lbnQoKTtcclxuICAgICAgc2Nyb2xsRG93bkFjdGlvbiA9ICgpID0+IHRoaXMuaGlkZUVsZW1lbnQoKTtcclxuICAgIH1cclxuXHJcbiAgICBzY3JvbGxVcCQuc3Vic2NyaWJlKCgpID0+IHNjcm9sbFVwQWN0aW9uKCkpO1xyXG4gICAgc2Nyb2xsRG93biQuc3Vic2NyaWJlKCgpID0+IHNjcm9sbERvd25BY3Rpb24oKSk7XHJcbiAgfVxyXG5cclxuICBuZ09uRGVzdHJveSgpOiB2b2lkIHtcclxuICAgIHRoaXMudW5zdWJzY3JpYmVOb3RpZmllci5uZXh0KCk7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlTm90aWZpZXIuY29tcGxldGUoKTtcclxuICB9XHJcblxyXG4gIHByaXZhdGUgaGlkZUVsZW1lbnQoKTogdm9pZCB7XHJcbiAgICBjb25zdCBuYXRpdmVFbGVtZW50ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICBpZiAodGhpcy5jbGFzc05hbWVXaGVuSGlkZGVuKSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIyLmFkZENsYXNzKG5hdGl2ZUVsZW1lbnQsIHRoaXMuY2xhc3NOYW1lV2hlbkhpZGRlbik7XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLnJlbmRlcmVyMi5zZXRTdHlsZShuYXRpdmVFbGVtZW50LCB0aGlzLnByb3BlcnR5VXNlZFRvSGlkZSwgdGhpcy52YWx1ZVdoZW5IaWRkZW4pO1xyXG4gICAgfVxyXG4gICAgdGhpcy5ldmVudEVsZW1lbnRIaWRkZW4uZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBzaG93RWxlbWVudCgpOiB2b2lkIHtcclxuICAgIGNvbnN0IG5hdGl2ZUVsZW1lbnQgPSB0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudDtcclxuICAgIGlmICh0aGlzLmNsYXNzTmFtZVdoZW5IaWRkZW4pIHtcclxuICAgICAgdGhpcy5yZW5kZXJlcjIucmVtb3ZlQ2xhc3MobmF0aXZlRWxlbWVudCwgdGhpcy5jbGFzc05hbWVXaGVuSGlkZGVuKTtcclxuICAgIH0gZWxzZSB7XHJcbiAgICAgIHRoaXMucmVuZGVyZXIyLnNldFN0eWxlKG5hdGl2ZUVsZW1lbnQsIHRoaXMucHJvcGVydHlVc2VkVG9IaWRlLCB0aGlzLnZhbHVlV2hlblNob3duKTtcclxuICAgIH1cclxuICAgIHRoaXMuZXZlbnRFbGVtZW50U2hvd24uZW1pdCgpO1xyXG4gIH1cclxuXHJcbiAgcHJpdmF0ZSBnZXREZWZhdWx0U2Nyb2xsaW5nRWxlbWVudCgpOiBIVE1MRWxlbWVudCB7XHJcbiAgICByZXR1cm4gKGRvY3VtZW50LnNjcm9sbGluZ0VsZW1lbnQgfHwgZG9jdW1lbnQuZG9jdW1lbnRFbGVtZW50KSBhcyBIVE1MRWxlbWVudDtcclxuICB9XHJcbn1cclxuXHJcbmVudW0gU2Nyb2xsRGlyZWN0aW9uIHtcclxuICBVcCA9ICdVcCcsXHJcbiAgRG93biA9ICdEb3duJ1xyXG59Il19