theme-lib
Version:
This is a simple example Angular Library published to npm.
223 lines • 21.7 kB
JavaScript
/**
* @fileoverview added by tsickle
* @suppress {checkTypes,extraRequire,missingReturn,unusedPrivateMembers,uselessCode} checked by tsc
*/
import { Directive, Input, HostListener, ElementRef, EventEmitter, Output, ContentChildren, QueryList, } from '@angular/core';
import { forkJoin, of as observableOf, interval, timer } from 'rxjs';
import { takeWhile, filter, switchMap, map, takeUntil, take } from 'rxjs/operators';
import { convertToBoolProperty } from '../helpers';
import { NbLayoutScrollService } from '../../services/scroll.service';
import { NbLayoutRulerService } from '../../services/ruler.service';
import { NbListItemComponent } from './list.component';
export class NbScrollableContainerDimentions {
}
if (false) {
/** @type {?} */
NbScrollableContainerDimentions.prototype.scrollTop;
/** @type {?} */
NbScrollableContainerDimentions.prototype.scrollHeight;
/** @type {?} */
NbScrollableContainerDimentions.prototype.clientHeight;
}
/*
* Infinite List Directive
*
* ```html
* <nb-list nbInfiniteList [threshold]="500" (bottomThreshold)="loadNext()">
* <nb-list-item *ngFor="let item of items"></nb-list-item>
* </nb-list>
* ```
*
* @stacked-example(Simple infinite list, infinite-list/infinite-list-showcase.component)
*
* Directive will notify when list scrolled up or down to given a threshold.
* By default it listen to scroll of list on which applied, but also can be set to listen to window scroll.
*
* @stacked-example(Scroll modes, infinite-list/infinite-list-scroll-modes.component)
*
* To improve UX of infinite lists, it's better to keep current page in url,
* so user able to return to the last viewed page or to share a link to this page.
* `nbListPageTracker` directive will help you to know, what page user currently viewing.
* Just put it on a list, set page size and it will calculate page that currently in viewport.
* You can [open the example](example/infinite-list/infinite-news-list.component)
* in a new tab to check out this feature.
*
* @stacked-example(Infinite list with pager, infinite-list/infinite-news-list.component)
*
* @stacked-example(Infinite list with placeholders at the top, infinite-list/infinite-list-placeholders.component)
*
*/
export class NbInfiniteListDirective {
/**
* @param {?} elementRef
* @param {?} scrollService
* @param {?} dimensionsService
*/
constructor(elementRef, scrollService, dimensionsService) {
this.elementRef = elementRef;
this.scrollService = scrollService;
this.dimensionsService = dimensionsService;
this.alive = true;
this.windowScroll = false;
/*
* Emits when distance between list bottom and current scroll position is less than threshold.
*/
this.bottomThreshold = new EventEmitter(true);
/*
* Emits when distance between list top and current scroll position is less than threshold.
*/
this.topThreshold = new EventEmitter(true);
}
/**
* @private
* @return {?}
*/
get elementScroll() {
return !this.windowScroll;
}
/*
* By default component observes list scroll position.
* If set to `true`, component will observe position of page scroll instead.
*/
/**
* @param {?} value
* @return {?}
*/
set listenWindowScroll(value) {
this.windowScroll = convertToBoolProperty(value);
}
/**
* @return {?}
*/
onElementScroll() {
if (this.elementScroll) {
this.checkPosition(this.elementRef.nativeElement);
}
}
/**
* @return {?}
*/
ngAfterViewInit() {
this.scrollService.onScroll()
.pipe(takeWhile(() => this.alive), filter(() => this.windowScroll), switchMap(() => this.getContainerDimensions()))
.subscribe(dimentions => this.checkPosition(dimentions));
this.listItems.changes
.pipe(takeWhile(() => this.alive),
// For some reason, changes are emitted before list item removed from dom,
// so dimensions will be incorrect.
// Check every 50ms for a second if dom and query are in sync.
// Once they synchronized, we can get proper dimensions.
switchMap(() => interval(50).pipe(takeUntil(timer(1000)), filter(() => this.inSyncWithDom()), take(1))), switchMap(() => this.getContainerDimensions()))
.subscribe(dimentions => this.checkPosition(dimentions));
this.getContainerDimensions().subscribe(dimentions => this.checkPosition(dimentions));
}
/**
* @return {?}
*/
ngOnDestroy() {
this.alive = false;
}
/**
* @param {?} __0
* @return {?}
*/
checkPosition({ scrollHeight, scrollTop, clientHeight }) {
/** @type {?} */
const initialCheck = this.lastScrollPosition == null;
/** @type {?} */
const manualCheck = this.lastScrollPosition === scrollTop;
/** @type {?} */
const scrollUp = scrollTop < this.lastScrollPosition;
/** @type {?} */
const scrollDown = scrollTop > this.lastScrollPosition;
/** @type {?} */
const distanceToBottom = scrollHeight - scrollTop - clientHeight;
if ((initialCheck || manualCheck || scrollDown) && distanceToBottom <= this.threshold) {
this.bottomThreshold.emit();
}
if ((initialCheck || scrollUp) && scrollTop <= this.threshold) {
this.topThreshold.emit();
}
this.lastScrollPosition = scrollTop;
}
/**
* @private
* @return {?}
*/
getContainerDimensions() {
if (this.elementScroll) {
const { scrollTop, scrollHeight, clientHeight } = this.elementRef.nativeElement;
return observableOf({ scrollTop, scrollHeight, clientHeight });
}
return forkJoin(this.scrollService.getPosition(), this.dimensionsService.getDimensions())
.pipe(map(([scrollPosition, dimensions]) => ({
scrollTop: scrollPosition.y,
scrollHeight: dimensions.scrollHeight,
clientHeight: dimensions.clientHeight,
})));
}
/**
* @private
* @return {?}
*/
inSyncWithDom() {
return this.elementRef.nativeElement.children.length === this.listItems.length;
}
}
NbInfiniteListDirective.decorators = [
{ type: Directive, args: [{
selector: '[nbInfiniteList]',
},] }
];
/** @nocollapse */
NbInfiniteListDirective.ctorParameters = () => [
{ type: ElementRef },
{ type: NbLayoutScrollService },
{ type: NbLayoutRulerService }
];
NbInfiniteListDirective.propDecorators = {
threshold: [{ type: Input }],
listenWindowScroll: [{ type: Input }],
bottomThreshold: [{ type: Output }],
topThreshold: [{ type: Output }],
onElementScroll: [{ type: HostListener, args: ['scroll',] }],
listItems: [{ type: ContentChildren, args: [NbListItemComponent,] }]
};
if (false) {
/**
* @type {?}
* @private
*/
NbInfiniteListDirective.prototype.alive;
/**
* @type {?}
* @private
*/
NbInfiniteListDirective.prototype.lastScrollPosition;
/** @type {?} */
NbInfiniteListDirective.prototype.windowScroll;
/** @type {?} */
NbInfiniteListDirective.prototype.threshold;
/** @type {?} */
NbInfiniteListDirective.prototype.bottomThreshold;
/** @type {?} */
NbInfiniteListDirective.prototype.topThreshold;
/** @type {?} */
NbInfiniteListDirective.prototype.listItems;
/**
* @type {?}
* @private
*/
NbInfiniteListDirective.prototype.elementRef;
/**
* @type {?}
* @private
*/
NbInfiniteListDirective.prototype.scrollService;
/**
* @type {?}
* @private
*/
NbInfiniteListDirective.prototype.dimensionsService;
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5maW5pdGUtbGlzdC5kaXJlY3RpdmUuanMiLCJzb3VyY2VSb290Ijoibmc6Ly90aGVtZS1saWIvIiwic291cmNlcyI6WyJsaWIvY29tcG9uZW50cy9saXN0L2luZmluaXRlLWxpc3QuZGlyZWN0aXZlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7QUFBQSxPQUFPLEVBQ0wsU0FBUyxFQUNULEtBQUssRUFDTCxZQUFZLEVBQ1osVUFBVSxFQUNWLFlBQVksRUFDWixNQUFNLEVBR04sZUFBZSxFQUNmLFNBQVMsR0FDVixNQUFNLGVBQWUsQ0FBQztBQUN2QixPQUFPLEVBQWMsUUFBUSxFQUFFLEVBQUUsSUFBSSxZQUFZLEVBQUUsUUFBUSxFQUFFLEtBQUssRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNqRixPQUFPLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxJQUFJLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwRixPQUFPLEVBQUUscUJBQXFCLEVBQUUsTUFBTSxZQUFZLENBQUM7QUFDbkQsT0FBTyxFQUFFLHFCQUFxQixFQUFFLE1BQU0sK0JBQStCLENBQUM7QUFDdEUsT0FBTyxFQUFFLG9CQUFvQixFQUFFLE1BQU0sOEJBQThCLENBQUM7QUFDcEUsT0FBTyxFQUFFLG1CQUFtQixFQUFFLE1BQU0sa0JBQWtCLENBQUM7QUFFdkQsTUFBTSxPQUFPLCtCQUErQjtDQUkzQzs7O0lBSEMsb0RBQWtCOztJQUNsQix1REFBcUI7O0lBQ3JCLHVEQUFxQjs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBa0N2QixNQUFNLE9BQU8sdUJBQXVCOzs7Ozs7SUE4Q2xDLFlBQ1UsVUFBc0IsRUFDdEIsYUFBb0MsRUFDcEMsaUJBQXVDO1FBRnZDLGVBQVUsR0FBVixVQUFVLENBQVk7UUFDdEIsa0JBQWEsR0FBYixhQUFhLENBQXVCO1FBQ3BDLHNCQUFpQixHQUFqQixpQkFBaUIsQ0FBc0I7UUEvQ3pDLFVBQUss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TixZQUFZLFNBQUMsUUFBUTt3QkFPckIsZUFBZSxTQUFDLG1CQUFtQjs7Ozs7OztJQTFDcEMsd0NBQXFCOzs7OztJQUNyQixxREFBMkI7O0lBQzNCLCtDQUFxQjs7SUFTckIsNENBQ2tCOztJQWNsQixrREFDeUM7O0lBS3pDLCtDQUNzQzs7SUFTdEMsNENBQWdGOzs7OztJQUc5RSw2Q0FBOEI7Ozs7O0lBQzlCLGdEQUE0Qzs7Ozs7SUFDNUMsb0RBQStDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHtcclxuICBEaXJlY3RpdmUsXHJcbiAgSW5wdXQsXHJcbiAgSG9zdExpc3RlbmVyLFxyXG4gIEVsZW1lbnRSZWYsXHJcbiAgRXZlbnRFbWl0dGVyLFxyXG4gIE91dHB1dCxcclxuICBPbkRlc3Ryb3ksXHJcbiAgQWZ0ZXJWaWV3SW5pdCxcclxuICBDb250ZW50Q2hpbGRyZW4sXHJcbiAgUXVlcnlMaXN0LFxyXG59IGZyb20gJ0Bhbmd1bGFyL2NvcmUnO1xyXG5pbXBvcnQgeyBPYnNlcnZhYmxlLCBmb3JrSm9pbiwgb2YgYXMgb2JzZXJ2YWJsZU9mLCBpbnRlcnZhbCwgdGltZXIgfSBmcm9tICdyeGpzJztcclxuaW1wb3J0IHsgdGFrZVdoaWxlLCBmaWx0ZXIsIHN3aXRjaE1hcCwgbWFwLCB0YWtlVW50aWwsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XHJcbmltcG9ydCB7IGNvbnZlcnRUb0Jvb2xQcm9wZXJ0eSB9IGZyb20gJy4uL2hlbHBlcnMnO1xyXG5pbXBvcnQgeyBOYkxheW91dFNjcm9sbFNlcnZpY2UgfSBmcm9tICcuLi8uLi9zZXJ2aWNlcy9zY3JvbGwuc2VydmljZSc7XHJcbmltcG9ydCB7IE5iTGF5b3V0UnVsZXJTZXJ2aWNlIH0gZnJvbSAnLi4vLi4vc2VydmljZXMvcnVsZXIuc2VydmljZSc7XHJcbmltcG9ydCB7IE5iTGlzdEl0ZW1Db21wb25lbnQgfSBmcm9tICcuL2xpc3QuY29tcG9uZW50JztcclxuXHJcbmV4cG9ydCBjbGFzcyBOYlNjcm9sbGFibGVDb250YWluZXJEaW1lbnRpb25zIHtcclxuICBzY3JvbGxUb3A6IG51bWJlcjtcclxuICBzY3JvbGxIZWlnaHQ6IG51bWJlcjtcclxuICBjbGllbnRIZWlnaHQ6IG51bWJlcjtcclxufVxyXG5cclxuLypcclxuICogSW5maW5pdGUgTGlzdCBEaXJlY3RpdmVcclxuICpcclxuICogYGBgaHRtbFxyXG4gKiAgPG5iLWxpc3QgbmJJbmZpbml0ZUxpc3QgW3RocmVzaG9sZF09XCI1MDBcIiAoYm90dG9tVGhyZXNob2xkKT1cImxvYWROZXh0KClcIj5cclxuICogICAgPG5iLWxpc3QtaXRlbSAqbmdGb3I9XCJsZXQgaXRlbSBvZiBpdGVtc1wiPjwvbmItbGlzdC1pdGVtPlxyXG4gKiAgPC9uYi1saXN0PlxyXG4gKiBgYGBcclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShTaW1wbGUgaW5maW5pdGUgbGlzdCwgaW5maW5pdGUtbGlzdC9pbmZpbml0ZS1saXN0LXNob3djYXNlLmNvbXBvbmVudClcclxuICpcclxuICogRGlyZWN0aXZlIHdpbGwgbm90aWZ5IHdoZW4gbGlzdCBzY3JvbGxlZCB1cCBvciBkb3duIHRvIGdpdmVuIGEgdGhyZXNob2xkLlxyXG4gKiBCeSBkZWZhdWx0IGl0IGxpc3RlbiB0byBzY3JvbGwgb2YgbGlzdCBvbiB3aGljaCBhcHBsaWVkLCBidXQgYWxzbyBjYW4gYmUgc2V0IHRvIGxpc3RlbiB0byB3aW5kb3cgc2Nyb2xsLlxyXG4gKlxyXG4gKiBAc3RhY2tlZC1leGFtcGxlKFNjcm9sbCBtb2RlcywgaW5maW5pdGUtbGlzdC9pbmZpbml0ZS1saXN0LXNjcm9sbC1tb2Rlcy5jb21wb25lbnQpXHJcbiAqXHJcbiAqIFRvIGltcHJvdmUgVVggb2YgaW5maW5pdGUgbGlzdHMsIGl0J3MgYmV0dGVyIHRvIGtlZXAgY3VycmVudCBwYWdlIGluIHVybCxcclxuICogc28gdXNlciBhYmxlIHRvIHJldHVybiB0byB0aGUgbGFzdCB2aWV3ZWQgcGFnZSBvciB0byBzaGFyZSBhIGxpbmsgdG8gdGhpcyBwYWdlLlxyXG4gKiBgbmJMaXN0UGFnZVRyYWNrZXJgIGRpcmVjdGl2ZSB3aWxsIGhlbHAgeW91IHRvIGtub3csIHdoYXQgcGFnZSB1c2VyIGN1cnJlbnRseSB2aWV3aW5nLlxyXG4gKiBKdXN0IHB1dCBpdCBvbiBhIGxpc3QsIHNldCBwYWdlIHNpemUgYW5kIGl0IHdpbGwgY2FsY3VsYXRlIHBhZ2UgdGhhdCBjdXJyZW50bHkgaW4gdmlld3BvcnQuXHJcbiAqIFlvdSBjYW4gW29wZW4gdGhlIGV4YW1wbGVdKGV4YW1wbGUvaW5maW5pdGUtbGlzdC9pbmZpbml0ZS1uZXdzLWxpc3QuY29tcG9uZW50KVxyXG4gKiBpbiBhIG5ldyB0YWIgdG8gY2hlY2sgb3V0IHRoaXMgZmVhdHVyZS5cclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShJbmZpbml0ZSBsaXN0IHdpdGggcGFnZXIsIGluZmluaXRlLWxpc3QvaW5maW5pdGUtbmV3cy1saXN0LmNvbXBvbmVudClcclxuICpcclxuICogQHN0YWNrZWQtZXhhbXBsZShJbmZpbml0ZSBsaXN0IHdpdGggcGxhY2Vob2xkZXJzIGF0IHRoZSB0b3AsIGluZmluaXRlLWxpc3QvaW5maW5pdGUtbGlzdC1wbGFjZWhvbGRlcnMuY29tcG9uZW50KVxyXG4gKlxyXG4gKi9cclxuQERpcmVjdGl2ZSh7XHJcbiAgc2VsZWN0b3I6ICdbbmJJbmZpbml0ZUxpc3RdJyxcclxufSlcclxuZXhwb3J0IGNsYXNzIE5iSW5maW5pdGVMaXN0RGlyZWN0aXZlIGltcGxlbWVudHMgQWZ0ZXJWaWV3SW5pdCwgT25EZXN0cm95IHtcclxuXHJcbiAgcHJpdmF0ZSBhbGl2ZSA9IHRydWU7XHJcbiAgcHJpdmF0ZSBsYXN0U2Nyb2xsUG9zaXRpb247XHJcbiAgd2luZG93U2Nyb2xsID0gZmFsc2U7XHJcbiAgcHJpdmF0ZSBnZXQgZWxlbWVudFNjcm9sbCgpIHtcclxuICAgIHJldHVybiAhdGhpcy53aW5kb3dTY3JvbGw7XHJcbiAgfVxyXG5cclxuICAvKlxyXG4gICAqIFRocmVzaG9sZCBhZnRlciB3aGljaCBldmVudCBsb2FkIG1vcmUgZXZlbnQgd2lsbCBiZSBlbWl0ZWQuXHJcbiAgICogSW4gcGl4ZWxzLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgdGhyZXNob2xkOiBudW1iZXI7XHJcblxyXG4gIC8qXHJcbiAgICogQnkgZGVmYXVsdCBjb21wb25lbnQgb2JzZXJ2ZXMgbGlzdCBzY3JvbGwgcG9zaXRpb24uXHJcbiAgICogSWYgc2V0IHRvIGB0cnVlYCwgY29tcG9uZW50IHdpbGwgb2JzZXJ2ZSBwb3NpdGlvbiBvZiBwYWdlIHNjcm9sbCBpbnN0ZWFkLlxyXG4gICAqL1xyXG4gIEBJbnB1dCgpXHJcbiAgc2V0IGxpc3RlbldpbmRvd1Njcm9sbCh2YWx1ZSkge1xyXG4gICAgdGhpcy53aW5kb3dTY3JvbGwgPSBjb252ZXJ0VG9Cb29sUHJvcGVydHkodmFsdWUpO1xyXG4gIH1cclxuXHJcbiAgLypcclxuICAgKiBFbWl0cyB3aGVuIGRpc3RhbmNlIGJldHdlZW4gbGlzdCBib3R0b20gYW5kIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uIGlzIGxlc3MgdGhhbiB0aHJlc2hvbGQuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgYm90dG9tVGhyZXNob2xkID0gbmV3IEV2ZW50RW1pdHRlcih0cnVlKTtcclxuXHJcbiAgLypcclxuICAgKiBFbWl0cyB3aGVuIGRpc3RhbmNlIGJldHdlZW4gbGlzdCB0b3AgYW5kIGN1cnJlbnQgc2Nyb2xsIHBvc2l0aW9uIGlzIGxlc3MgdGhhbiB0aHJlc2hvbGQuXHJcbiAgICovXHJcbiAgQE91dHB1dCgpXHJcbiAgdG9wVGhyZXNob2xkID0gbmV3IEV2ZW50RW1pdHRlcih0cnVlKTtcclxuXHJcbiAgQEhvc3RMaXN0ZW5lcignc2Nyb2xsJylcclxuICBvbkVsZW1lbnRTY3JvbGwoKSB7XHJcbiAgICBpZiAodGhpcy5lbGVtZW50U2Nyb2xsKSB7XHJcbiAgICAgIHRoaXMuY2hlY2tQb3NpdGlvbih0aGlzLmVsZW1lbnRSZWYubmF0aXZlRWxlbWVudCk7XHJcbiAgICB9XHJcbiAgfVxyXG5cclxuICBAQ29udGVudENoaWxkcmVuKE5iTGlzdEl0ZW1Db21wb25lbnQpIGxpc3RJdGVtczogUXVlcnlMaXN0PE5iTGlzdEl0ZW1Db21wb25lbnQ+O1xyXG5cclxuICBjb25zdHJ1Y3RvcihcclxuICAgIHByaXZhdGUgZWxlbWVudFJlZjogRWxlbWVudFJlZixcclxuICAgIHByaXZhdGUgc2Nyb2xsU2VydmljZTogTmJMYXlvdXRTY3JvbGxTZXJ2aWNlLFxyXG4gICAgcHJpdmF0ZSBkaW1lbnNpb25zU2VydmljZTogTmJMYXlvdXRSdWxlclNlcnZpY2UsXHJcbiAgKSB7fVxyXG5cclxuICBuZ0FmdGVyVmlld0luaXQoKSB7XHJcbiAgICB0aGlzLnNjcm9sbFNlcnZpY2Uub25TY3JvbGwoKVxyXG4gICAgICAucGlwZShcclxuICAgICAgICB0YWtlV2hpbGUoKCkgPT4gdGhpcy5hbGl2ZSksXHJcbiAgICAgICAgZmlsdGVyKCgpID0+IHRoaXMud2luZG93U2Nyb2xsKSxcclxuICAgICAgICBzd2l0Y2hNYXAoKCkgPT4gdGhpcy5nZXRDb250YWluZXJEaW1lbnNpb25zKCkpLFxyXG4gICAgICApXHJcbiAgICAgIC5zdWJzY3JpYmUoZGltZW50aW9ucyA9PiB0aGlzLmNoZWNrUG9zaXRpb24oZGltZW50aW9ucykpO1xyXG5cclxuICAgIHRoaXMubGlzdEl0ZW1zLmNoYW5nZXNcclxuICAgICAgLnBpcGUoXHJcbiAgICAgICAgdGFrZVdoaWxlKCgpID0+IHRoaXMuYWxpdmUpLFxyXG4gICAgICAgIC8vIEZvciBzb21lIHJlYXNvbiwgY2hhbmdlcyBhcmUgZW1pdHRlZCBiZWZvcmUgbGlzdCBpdGVtIHJlbW92ZWQgZnJvbSBkb20sXHJcbiAgICAgICAgLy8gc28gZGltZW5zaW9ucyB3aWxsIGJlIGluY29ycmVjdC5cclxuICAgICAgICAvLyBDaGVjayBldmVyeSA1MG1zIGZvciBhIHNlY29uZCBpZiBkb20gYW5kIHF1ZXJ5IGFyZSBpbiBzeW5jLlxyXG4gICAgICAgIC8vIE9uY2UgdGhleSBzeW5jaHJvbml6ZWQsIHdlIGNhbiBnZXQgcHJvcGVyIGRpbWVuc2lvbnMuXHJcbiAgICAgICAgc3dpdGNoTWFwKCgpID0+IGludGVydmFsKDUwKS5waXBlKFxyXG4gICAgICAgICAgdGFrZVVudGlsKHRpbWVyKDEwMDApKSxcclxuICAgICAgICAgIGZpbHRlcigoKSA9PiB0aGlzLmluU3luY1dpdGhEb20oKSksXHJcbiAgICAgICAgICB0YWtlKDEpLFxyXG4gICAgICAgICkpLFxyXG4gICAgICAgIHN3aXRjaE1hcCgoKSA9PiB0aGlzLmdldENvbnRhaW5lckRpbWVuc2lvbnMoKSksXHJcbiAgICAgIClcclxuICAgICAgLnN1YnNjcmliZShkaW1lbnRpb25zID0+IHRoaXMuY2hlY2tQb3NpdGlvbihkaW1lbnRpb25zKSk7XHJcblxyXG4gICAgICB0aGlzLmdldENvbnRhaW5lckRpbWVuc2lvbnMoKS5zdWJzY3JpYmUoZGltZW50aW9ucyA9PiB0aGlzLmNoZWNrUG9zaXRpb24oZGltZW50aW9ucykpO1xyXG4gIH1cclxuXHJcbiAgbmdPbkRlc3Ryb3koKSB7XHJcbiAgICB0aGlzLmFsaXZlID0gZmFsc2U7XHJcbiAgfVxyXG5cclxuICBjaGVja1Bvc2l0aW9uKHsgc2Nyb2xsSGVpZ2h0LCBzY3JvbGxUb3AsIGNsaWVudEhlaWdodCB9OiBOYlNjcm9sbGFibGVDb250YWluZXJEaW1lbnRpb25zKSB7XHJcbiAgICBjb25zdCBpbml0aWFsQ2hlY2sgPSB0aGlzLmxhc3RTY3JvbGxQb3NpdGlvbiA9PSBudWxsO1xyXG4gICAgY29uc3QgbWFudWFsQ2hlY2sgPSB0aGlzLmxhc3RTY3JvbGxQb3NpdGlvbiA9PT0gc2Nyb2xsVG9wO1xyXG4gICAgY29uc3Qgc2Nyb2xsVXAgPSBzY3JvbGxUb3AgPCB0aGlzLmxhc3RTY3JvbGxQb3NpdGlvbjtcclxuICAgIGNvbnN0IHNjcm9sbERvd24gPSBzY3JvbGxUb3AgPiB0aGlzLmxhc3RTY3JvbGxQb3NpdGlvbjtcclxuICAgIGNvbnN0IGRpc3RhbmNlVG9Cb3R0b20gPSBzY3JvbGxIZWlnaHQgLSBzY3JvbGxUb3AgLSBjbGllbnRIZWlnaHQ7XHJcblxyXG4gICAgaWYgKChpbml0aWFsQ2hlY2sgfHwgIG1hbnVhbENoZWNrIHx8IHNjcm9sbERvd24pICYmIGRpc3RhbmNlVG9Cb3R0b20gPD0gdGhpcy50aHJlc2hvbGQpIHtcclxuICAgICAgdGhpcy5ib3R0b21UaHJlc2hvbGQuZW1pdCgpO1xyXG4gICAgfVxyXG4gICAgaWYgKChpbml0aWFsQ2hlY2sgfHwgc2Nyb2xsVXApICYmIHNjcm9sbFRvcCA8PSB0aGlzLnRocmVzaG9sZCkge1xyXG4gICAgICB0aGlzLnRvcFRocmVzaG9sZC5lbWl0KCk7XHJcbiAgICB9XHJcblxyXG4gICAgdGhpcy5sYXN0U2Nyb2xsUG9zaXRpb24gPSBzY3JvbGxUb3A7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGdldENvbnRhaW5lckRpbWVuc2lvbnMoKTogT2JzZXJ2YWJsZTxOYlNjcm9sbGFibGVDb250YWluZXJEaW1lbnRpb25zPiB7XHJcbiAgICBpZiAodGhpcy5lbGVtZW50U2Nyb2xsKSB7XHJcbiAgICAgIGNvbnN0IHsgc2Nyb2xsVG9wLCBzY3JvbGxIZWlnaHQsIGNsaWVudEhlaWdodCB9ID0gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQ7XHJcbiAgICAgIHJldHVybiBvYnNlcnZhYmxlT2YoeyBzY3JvbGxUb3AsIHNjcm9sbEhlaWdodCwgY2xpZW50SGVpZ2h0IH0pO1xyXG4gICAgfVxyXG5cclxuICAgIHJldHVybiBmb3JrSm9pbih0aGlzLnNjcm9sbFNlcnZpY2UuZ2V0UG9zaXRpb24oKSwgdGhpcy5kaW1lbnNpb25zU2VydmljZS5nZXREaW1lbnNpb25zKCkpXHJcbiAgICAgIC5waXBlKFxyXG4gICAgICAgICAgbWFwKChbc2Nyb2xsUG9zaXRpb24sIGRpbWVuc2lvbnNdKSA9PiAoe1xyXG4gICAgICAgICAgICBzY3JvbGxUb3A6IHNjcm9sbFBvc2l0aW9uLnksXHJcbiAgICAgICAgICAgIHNjcm9sbEhlaWdodDogZGltZW5zaW9ucy5zY3JvbGxIZWlnaHQsXHJcbiAgICAgICAgICAgIGNsaWVudEhlaWdodDogZGltZW5zaW9ucy5jbGllbnRIZWlnaHQsXHJcbiAgICAgICAgICB9KSksXHJcbiAgICAgICk7XHJcbiAgfVxyXG5cclxuICBwcml2YXRlIGluU3luY1dpdGhEb20oKTogYm9vbGVhbiB7XHJcbiAgICByZXR1cm4gdGhpcy5lbGVtZW50UmVmLm5hdGl2ZUVsZW1lbnQuY2hpbGRyZW4ubGVuZ3RoID09PSB0aGlzLmxpc3RJdGVtcy5sZW5ndGg7XHJcbiAgfVxyXG59XHJcbiJdfQ==