@bimeister/pupakit.kit
Version:
PupaKit is an open source collection of Angular components based on an atomic approach to building interfaces, which guarantees better performance and greater development flexibility.
104 lines • 20.4 kB
JavaScript
import { filterNotNil, isEmpty, isNil, resizeObservable, shareReplayWithRefCount, VOID, } from '@bimeister/utilities';
import { asyncScheduler, BehaviorSubject, combineLatest } from 'rxjs';
import { distinctUntilChanged, filter, map, observeOn, subscribeOn, switchMap, take } from 'rxjs/operators';
import '../../../components/scrollable/components/scrollable/scrollable.component';
export class TabsServiceBase {
constructor() {
this.tabNameToHtmlElementMap = new Map();
this.activeTabNameState$ = new BehaviorSubject(null);
this.activeTabName$ = this.activeTabNameState$.asObservable();
this.hostElement$ = new BehaviorSubject(null);
this.scrollable$ = new BehaviorSubject(null);
this.tabsHtmlElement$ = new BehaviorSubject(null);
this.activeHtmlElement$ = this.activeTabName$.pipe(filterNotNil(), map((activeTabName) => this.tabNameToHtmlElementMap.get(JSON.stringify(activeTabName))), shareReplayWithRefCount());
this.tabsContainerResize$ = this.tabsHtmlElement$.pipe(filterNotNil(), switchMap((tabsHtmlElement) => resizeObservable(tabsHtmlElement)));
this.refresh$ = new BehaviorSubject(VOID);
this.railHighlighterOffsetLeftPx$ = combineLatest([
this.activeHtmlElement$.pipe(filterNotNil()),
this.tabsHtmlElement$.pipe(filterNotNil()),
this.tabsContainerResize$,
this.refresh$,
]).pipe(observeOn(asyncScheduler), map(([activeHtmlElement, tabsHtmlElement]) => {
const activeClientRect = activeHtmlElement.getBoundingClientRect();
const tabsClientRect = tabsHtmlElement.getBoundingClientRect();
return activeClientRect.left - tabsClientRect.left;
}));
this.railHighlighterWidthPx$ = combineLatest([
this.activeHtmlElement$,
this.tabsContainerResize$,
this.refresh$,
]).pipe(observeOn(asyncScheduler), map(([activeHtmlElement]) => activeHtmlElement.clientWidth));
this.tabNames = [];
this.isContentDraggingState$ = new BehaviorSubject(false);
this.isContentDragging$ = this.isContentDraggingState$.pipe(distinctUntilChanged());
}
registerTab(tabName) {
this.tabNames.push(tabName);
this.refresh$.next();
}
unregisterTab(tabName) {
this.tabNames = this.tabNames.filter((tab) => tab !== tabName);
this.resetActiveTabIfUnregisteredTabIsActive(tabName);
this.refresh$.next();
}
setInitialTab() {
this.activeTabName$
.pipe(take(1), filter((activeTab) => isNil(activeTab) && !isEmpty(this.tabNames)), subscribeOn(asyncScheduler))
.subscribe(() => {
this.setActiveTab(this.tabNames[0]);
});
}
setActiveTab(tabName) {
this.activeTabNameState$.next(tabName);
this.correctScrollLeftByTargetTab(tabName);
}
registerTabsHtmlElement(htmlElement) {
this.tabsHtmlElement$.next(htmlElement);
}
registerHostHtmlElement(htmlElement) {
this.hostElement$.next(htmlElement);
}
registerScrollable(scrollable) {
this.scrollable$.next(scrollable);
}
registerTabHtmlElement(tabName, htmlElement) {
this.tabNameToHtmlElementMap.set(JSON.stringify(tabName), htmlElement);
}
setContentDraggingStateState(isContentDragging) {
this.isContentDraggingState$.next(isContentDragging);
}
correctScrollLeftByTargetTab(tabName) {
const targetElement = this.tabNameToHtmlElementMap.get(JSON.stringify(tabName));
if (isNil(targetElement)) {
return;
}
combineLatest([this.hostElement$.pipe(filterNotNil()), this.scrollable$.pipe(filterNotNil())])
.pipe(take(1), map(([hostElement, scrollable]) => {
const hostClientRect = hostElement.getBoundingClientRect();
const targetClientRect = targetElement.getBoundingClientRect();
const leftOffsetPx = targetClientRect.left - hostClientRect.left;
const rightOffsetPx = hostClientRect.right - targetClientRect.right;
const centerLeftDeltaPx = (hostClientRect.width - targetClientRect.width) / 2;
return [leftOffsetPx, rightOffsetPx, scrollable, centerLeftDeltaPx];
}))
.subscribe(([leftOffsetPx, rightOffsetPx, scrollable, centerLeftDeltaPx]) => {
const isNeedScrollToLeft = leftOffsetPx < rightOffsetPx;
const isNeedScrollToRight = rightOffsetPx < leftOffsetPx;
const isSmoothScroll = true;
if (isNeedScrollToLeft) {
scrollable.setScrollLeftByDelta(Math.ceil(-centerLeftDeltaPx + leftOffsetPx), isSmoothScroll);
return;
}
if (isNeedScrollToRight) {
scrollable.setScrollLeftByDelta(Math.ceil(-rightOffsetPx + centerLeftDeltaPx), isSmoothScroll);
return;
}
});
}
resetActiveTabIfUnregisteredTabIsActive(removedTabName) {
this.activeTabName$
.pipe(take(1), filter((activeTabName) => activeTabName === removedTabName))
.subscribe(() => this.setActiveTab(null));
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGFicy1zZXJ2aWNlLWJhc2UuYWJzdHJhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi9zcmMvZGVjbGFyYXRpb25zL2NsYXNzZXMvYWJzdHJhY3QvdGFicy1zZXJ2aWNlLWJhc2UuYWJzdHJhY3QudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUNMLFlBQVksRUFDWixPQUFPLEVBQ1AsS0FBSyxFQUVMLGdCQUFnQixFQUNoQix1QkFBdUIsRUFDdkIsSUFBSSxHQUNMLE1BQU0sc0JBQXNCLENBQUM7QUFDOUIsT0FBTyxFQUFFLGNBQWMsRUFBRSxlQUFlLEVBQUUsYUFBYSxFQUFjLE1BQU0sTUFBTSxDQUFDO0FBQ2xGLE9BQU8sRUFBRSxvQkFBb0IsRUFBRSxNQUFNLEVBQUUsR0FBRyxFQUFFLFNBQVMsRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLElBQUksRUFBRSxNQUFNLGdCQUFnQixDQUFDO0FBQzVHLE9BQW9DLDJFQUEyRSxDQUFDO0FBRWhILE1BQU0sT0FBZ0IsZUFBZTtJQUFyQztRQUNxQiw0QkFBdUIsR0FBNkIsSUFBSSxHQUFHLEVBQXVCLENBQUM7UUFDckYsd0JBQW1CLEdBQWlDLElBQUksZUFBZSxDQUFjLElBQUksQ0FBQyxDQUFDO1FBQzVGLG1CQUFjLEdBQTRCLElBQUksQ0FBQyxtQkFBbUIsQ0FBQyxZQUFZLEVBQUUsQ0FBQztRQUUvRSxpQkFBWSxHQUEyQyxJQUFJLGVBQWUsQ0FDM0YsSUFBSSxDQUNMLENBQUM7UUFDaUIsZ0JBQVcsR0FBbUQsSUFBSSxlQUFlLENBRWxHLElBQUksQ0FBQyxDQUFDO1FBQ1cscUJBQWdCLEdBQTJDLElBQUksZUFBZSxDQUUvRixJQUFJLENBQUMsQ0FBQztRQUVTLHVCQUFrQixHQUE0QixJQUFJLENBQUMsY0FBYyxDQUFDLElBQUksQ0FDckYsWUFBWSxFQUFFLEVBQ2QsR0FBRyxDQUFDLENBQUMsYUFBZ0IsRUFBRSxFQUFFLENBQUMsSUFBSSxDQUFD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aUIsQ0FBQyxFQUFFLGNBQWMsQ0FBQyxDQUFDO2dCQUMvRixPQUFPO2FBQ1I7UUFDSCxDQUFDLENBQ0YsQ0FBQztJQUNOLENBQUM7SUFFTyx1Q0FBdUMsQ0FBQyxjQUFpQjtRQUMvRCxJQUFJLENBQUMsY0FBYzthQUNoQixJQUFJLENBQ0gsSUFBSSxDQUFDLENBQUMsQ0FBQyxFQUNQLE1BQU0sQ0FBQyxDQUFDLGFBQWdCLEVBQUUsRUFBRSxDQUFDLGFBQWEsS0FBSyxjQUFjLENBQUMsQ0FDL0Q7YUFDQSxTQUFTLENBQUMsR0FBRyxFQUFFLENBQUMsSUFBSSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDO0lBQzlDLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGZpbHRlck5vdE5pbCxcbiAgaXNFbXB0eSxcbiAgaXNOaWwsXG4gIE51bGxhYmxlLFxuICByZXNpemVPYnNlcnZhYmxlLFxuICBzaGFyZVJlcGxheVdpdGhSZWZDb3VudCxcbiAgVk9JRCxcbn0gZnJvbSAnQGJpbWVpc3Rlci91dGlsaXRpZXMnO1xuaW1wb3J0IHsgYXN5bmNTY2hlZHVsZXIsIEJlaGF2aW9yU3ViamVjdCwgY29tYmluZUxhdGVzdCwgT2JzZXJ2YWJsZSB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgZGlzdGluY3RVbnRpbENoYW5nZWQsIGZpbHRlciwgbWFwLCBvYnNlcnZlT24sIHN1YnNjcmliZU9uLCBzd2l0Y2hNYXAsIHRha2UgfSBmcm9tICdyeGpzL29wZXJhdG9ycyc7XG5pbXBvcnQgeyBTY3JvbGxhYmxlQ29tcG9uZW50IH0gZnJvbSAnLi4vLi4vLi4vY29tcG9uZW50cy9zY3JvbGxhYmxlL2NvbXBvbmVudHMvc2Nyb2xsYWJsZS9zY3JvbGxhYmxlLmNvbXBvbmVudCc7XG5cbmV4cG9ydCBhYnN0cmFjdCBjbGFzcyBUYWJzU2VydmljZUJhc2U8VD4ge1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgdGFiTmFtZVRvSHRtbEVsZW1lbnRNYXA6IE1hcDxzdHJpbmcsIEhUTUxFbGVtZW50PiA9IG5ldyBNYXA8c3RyaW5nLCBIVE1MRWxlbWVudD4oKTtcbiAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmVUYWJOYW1lU3RhdGUkOiBCZWhhdmlvclN1YmplY3Q8TnVsbGFibGU8VD4+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDxOdWxsYWJsZTxUPj4obnVsbCk7XG4gIHB1YmxpYyByZWFkb25seSBhY3RpdmVUYWJOYW1lJDogT2JzZXJ2YWJsZTxOdWxsYWJsZTxUPj4gPSB0aGlzLmFjdGl2ZVRhYk5hbWVTdGF0ZSQuYXNPYnNlcnZhYmxlKCk7XG5cbiAgcHJvdGVjdGVkIHJlYWRvbmx5IGhvc3RFbGVtZW50JDogQmVoYXZpb3JTdWJqZWN0PE51bGxhYmxlPEhUTUxFbGVtZW50Pj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PE51bGxhYmxlPEhUTUxFbGVtZW50Pj4oXG4gICAgbnVsbFxuICApO1xuICBwcm90ZWN0ZWQgcmVhZG9ubHkgc2Nyb2xsYWJsZSQ6IEJlaGF2aW9yU3ViamVjdDxOdWxsYWJsZTxTY3JvbGxhYmxlQ29tcG9uZW50Pj4gPSBuZXcgQmVoYXZpb3JTdWJqZWN0PFxuICAgIE51bGxhYmxlPFNjcm9sbGFibGVDb21wb25lbnQ+XG4gID4obnVsbCk7XG4gIHByb3RlY3RlZCByZWFkb25seSB0YWJzSHRtbEVsZW1lbnQkOiBCZWhhdmlvclN1YmplY3Q8TnVsbGFibGU8SFRNTEVsZW1lbnQ+PiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8XG4gICAgTnVsbGFibGU8SFRNTEVsZW1lbnQ+XG4gID4obnVsbCk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSBhY3RpdmVIdG1sRWxlbWVudCQ6IE9ic2VydmFibGU8SFRNTEVsZW1lbnQ+ID0gdGhpcy5hY3RpdmVUYWJOYW1lJC5waXBlKFxuICAgIGZpbHRlck5vdE5pbCgpLFxuICAgIG1hcCgoYWN0aXZlVGFiTmFtZTogVCkgPT4gdGhpcy50YWJOYW1lVG9IdG1sRWxlbWVudE1hcC5nZXQoSlNPTi5zdHJpbmdpZnkoYWN0aXZlVGFiTmFtZSkpKSxcbiAgICBzaGFyZVJlcGxheVdpdGhSZWZDb3VudCgpXG4gICk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSB0YWJzQ29udGFpbmVyUmVzaXplJDogT2JzZXJ2YWJsZTxSZXNpemVPYnNlcnZlckVudHJ5W10+ID0gdGhpcy50YWJzSHRtbEVsZW1lbnQkLnBpcGUoXG4gICAgZmlsdGVyTm90TmlsKCksXG4gICAgc3dpdGNoTWFwKCh0YWJzSHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50KSA9PiByZXNpemVPYnNlcnZhYmxlKHRhYnNIdG1sRWxlbWVudCkpXG4gICk7XG5cbiAgcHJpdmF0ZSByZWFkb25seSByZWZyZXNoJDogQmVoYXZpb3JTdWJqZWN0PHZvaWQ+ID0gbmV3IEJlaGF2aW9yU3ViamVjdDx2b2lkPihWT0lEKTtcblxuICBwdWJsaWMgcmVhZG9ubHkgcmFpbEhpZ2hsaWdodGVyT2Zmc2V0TGVmdFB4JDogT2JzZXJ2YWJsZTxudW1iZXI+ID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5hY3RpdmVIdG1sRWxlbWVudCQucGlwZShmaWx0ZXJOb3ROaWwoKSksXG4gICAgdGhpcy50YWJzSHRtbEVsZW1lbnQkLnBpcGUoZmlsdGVyTm90TmlsKCkpLFxuICAgIHRoaXMudGFic0NvbnRhaW5lclJlc2l6ZSQsXG4gICAgdGhpcy5yZWZyZXNoJCxcbiAgXSkucGlwZShcbiAgICBvYnNlcnZlT24oYXN5bmNTY2hlZHVsZXIpLFxuICAgIG1hcCgoW2FjdGl2ZUh0bWxFbGVtZW50LCB0YWJzSHRtbEVsZW1lbnRdOiBbSFRNTEVsZW1lbnQsIEhUTUxFbGVtZW50LCBSZXNpemVPYnNlcnZlckVudHJ5W10sIHZvaWRdKSA9PiB7XG4gICAgICBjb25zdCBhY3RpdmVDbGllbnRSZWN0OiBDbGllbnRSZWN0ID0gYWN0aXZlSHRtbEVsZW1lbnQuZ2V0Qm91bmRpbmdDbGllbnRSZWN0KCk7XG4gICAgICBjb25zdCB0YWJzQ2xpZW50UmVjdDogQ2xpZW50UmVjdCA9IHRhYnNIdG1sRWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgIHJldHVybiBhY3RpdmVDbGllbnRSZWN0LmxlZnQgLSB0YWJzQ2xpZW50UmVjdC5sZWZ0O1xuICAgIH0pXG4gICk7XG4gIHB1YmxpYyByZWFkb25seSByYWlsSGlnaGxpZ2h0ZXJXaWR0aFB4JDogT2JzZXJ2YWJsZTxudW1iZXI+ID0gY29tYmluZUxhdGVzdChbXG4gICAgdGhpcy5hY3RpdmVIdG1sRWxlbWVudCQsXG4gICAgdGhpcy50YWJzQ29udGFpbmVyUmVzaXplJCxcbiAgICB0aGlzLnJlZnJlc2gkLFxuICBdKS5waXBlKFxuICAgIG9ic2VydmVPbihhc3luY1NjaGVkdWxlciksXG4gICAgbWFwKChbYWN0aXZlSHRtbEVsZW1lbnRdOiBbSFRNTEVsZW1lbnQsIFJlc2l6ZU9ic2VydmVyRW50cnlbXSwgdm9pZF0pID0+IGFjdGl2ZUh0bWxFbGVtZW50LmNsaWVudFdpZHRoKVxuICApO1xuXG4gIHByaXZhdGUgdGFiTmFtZXM6IFRbXSA9IFtdO1xuXG4gIHByaXZhdGUgcmVhZG9ubHkgaXNDb250ZW50RHJhZ2dpbmdTdGF0ZSQ6IEJlaGF2aW9yU3ViamVjdDxib29sZWFuPiA9IG5ldyBCZWhhdmlvclN1YmplY3Q8Ym9vbGVhbj4oZmFsc2UpO1xuICBwdWJsaWMgcmVhZG9ubHkgaXNDb250ZW50RHJhZ2dpbmckOiBPYnNlcnZhYmxlPGJvb2xlYW4+ID0gdGhpcy5pc0NvbnRlbnREcmFnZ2luZ1N0YXRlJC5waXBlKGRpc3RpbmN0VW50aWxDaGFuZ2VkKCkpO1xuXG4gIHB1YmxpYyByZWdpc3RlclRhYih0YWJOYW1lOiBUKTogdm9pZCB7XG4gICAgdGhpcy50YWJOYW1lcy5wdXNoKHRhYk5hbWUpO1xuXG4gICAgdGhpcy5yZWZyZXNoJC5uZXh0KCk7XG4gIH1cblxuICBwdWJsaWMgdW5yZWdpc3RlclRhYih0YWJOYW1lOiBUKTogdm9pZCB7XG4gICAgdGhpcy50YWJOYW1lcyA9IHRoaXMudGFiTmFtZXMuZmlsdGVyKCh0YWI6IFQpID0+IHRhYiAhPT0gdGFiTmFtZSk7XG5cbiAgICB0aGlzLnJlc2V0QWN0aXZlVGFiSWZVbnJlZ2lzdGVyZWRUYWJJc0FjdGl2ZSh0YWJOYW1lKTtcblxuICAgIHRoaXMucmVmcmVzaCQubmV4dCgpO1xuICB9XG5cbiAgcHVibGljIHNldEluaXRpYWxUYWIoKTogdm9pZCB7XG4gICAgdGhpcy5hY3RpdmVUYWJOYW1lJFxuICAgICAgLnBpcGUoXG4gICAgICAgIHRha2UoMSksXG4gICAgICAgIGZpbHRlcigoYWN0aXZlVGFiOiBOdWxsYWJsZTxUPikgPT4gaXNOaWwoYWN0aXZlVGFiKSAmJiAhaXNFbXB0eSh0aGlzLnRhYk5hbWVzKSksXG4gICAgICAgIHN1YnNjcmliZU9uKGFzeW5jU2NoZWR1bGVyKVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZSgoKSA9PiB7XG4gICAgICAgIHRoaXMuc2V0QWN0aXZlVGFiKHRoaXMudGFiTmFtZXNbMF0pO1xuICAgICAgfSk7XG4gIH1cblxuICBwdWJsaWMgc2V0QWN0aXZlVGFiKHRhYk5hbWU6IFQpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZVRhYk5hbWVTdGF0ZSQubmV4dCh0YWJOYW1lKTtcbiAgICB0aGlzLmNvcnJlY3RTY3JvbGxMZWZ0QnlUYXJnZXRUYWIodGFiTmFtZSk7XG4gIH1cblxuICBwdWJsaWMgcmVnaXN0ZXJUYWJzSHRtbEVsZW1lbnQoaHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgdGhpcy50YWJzSHRtbEVsZW1lbnQkLm5leHQoaHRtbEVsZW1lbnQpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVySG9zdEh0bWxFbGVtZW50KGh0bWxFbGVtZW50OiBIVE1MRWxlbWVudCk6IHZvaWQge1xuICAgIHRoaXMuaG9zdEVsZW1lbnQkLm5leHQoaHRtbEVsZW1lbnQpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyU2Nyb2xsYWJsZShzY3JvbGxhYmxlOiBTY3JvbGxhYmxlQ29tcG9uZW50KTogdm9pZCB7XG4gICAgdGhpcy5zY3JvbGxhYmxlJC5uZXh0KHNjcm9sbGFibGUpO1xuICB9XG5cbiAgcHVibGljIHJlZ2lzdGVyVGFiSHRtbEVsZW1lbnQodGFiTmFtZTogVCwgaHRtbEVsZW1lbnQ6IEhUTUxFbGVtZW50KTogdm9pZCB7XG4gICAgdGhpcy50YWJOYW1lVG9IdG1sRWxlbWVudE1hcC5zZXQoSlNPTi5zdHJpbmdpZnkodGFiTmFtZSksIGh0bWxFbGVtZW50KTtcbiAgfVxuXG4gIHB1YmxpYyBzZXRDb250ZW50RHJhZ2dpbmdTdGF0ZVN0YXRlKGlzQ29udGVudERyYWdnaW5nOiBib29sZWFuKTogdm9pZCB7XG4gICAgdGhpcy5pc0NvbnRlbnREcmFnZ2luZ1N0YXRlJC5uZXh0KGlzQ29udGVudERyYWdnaW5nKTtcbiAgfVxuXG4gIHByaXZhdGUgY29ycmVjdFNjcm9sbExlZnRCeVRhcmdldFRhYih0YWJOYW1lOiBUKTogdm9pZCB7XG4gICAgY29uc3QgdGFyZ2V0RWxlbWVudDogSFRNTEVsZW1lbnQgPSB0aGlzLnRhYk5hbWVUb0h0bWxFbGVtZW50TWFwLmdldChKU09OLnN0cmluZ2lmeSh0YWJOYW1lKSk7XG5cbiAgICBpZiAoaXNOaWwodGFyZ2V0RWxlbWVudCkpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG5cbiAgICBjb21iaW5lTGF0ZXN0KFt0aGlzLmhvc3RFbGVtZW50JC5waXBlKGZpbHRlck5vdE5pbCgpKSwgdGhpcy5zY3JvbGxhYmxlJC5waXBlKGZpbHRlck5vdE5pbCgpKV0pXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgbWFwKChbaG9zdEVsZW1lbnQsIHNjcm9sbGFibGVdOiBbSFRNTEVsZW1lbnQsIFNjcm9sbGFibGVDb21wb25lbnRdKSA9PiB7XG4gICAgICAgICAgY29uc3QgaG9zdENsaWVudFJlY3Q6IENsaWVudFJlY3QgPSBob3N0RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcbiAgICAgICAgICBjb25zdCB0YXJnZXRDbGllbnRSZWN0OiBDbGllbnRSZWN0ID0gdGFyZ2V0RWxlbWVudC5nZXRCb3VuZGluZ0NsaWVudFJlY3QoKTtcblxuICAgICAgICAgIGNvbnN0IGxlZnRPZmZzZXRQeDogbnVtYmVyID0gdGFyZ2V0Q2xpZW50UmVjdC5sZWZ0IC0gaG9zdENsaWVudFJlY3QubGVmdDtcbiAgICAgICAgICBjb25zdCByaWdodE9mZnNldFB4OiBudW1iZXIgPSBob3N0Q2xpZW50UmVjdC5yaWdodCAtIHRhcmdldENsaWVudFJlY3QucmlnaHQ7XG4gICAgICAgICAgY29uc3QgY2VudGVyTGVmdERlbHRhUHg6IG51bWJlciA9IChob3N0Q2xpZW50UmVjdC53aWR0aCAtIHRhcmdldENsaWVudFJlY3Qud2lkdGgpIC8gMjtcbiAgICAgICAgICByZXR1cm4gW2xlZnRPZmZzZXRQeCwgcmlnaHRPZmZzZXRQeCwgc2Nyb2xsYWJsZSwgY2VudGVyTGVmdERlbHRhUHhdO1xuICAgICAgICB9KVxuICAgICAgKVxuICAgICAgLnN1YnNjcmliZShcbiAgICAgICAgKFtsZWZ0T2Zmc2V0UHgsIHJpZ2h0T2Zmc2V0UHgsIHNjcm9sbGFibGUsIGNlbnRlckxlZnREZWx0YVB4XTogW1xuICAgICAgICAgIG51bWJlcixcbiAgICAgICAgICBudW1iZXIsXG4gICAgICAgICAgU2Nyb2xsYWJsZUNvbXBvbmVudCxcbiAgICAgICAgICBudW1iZXJcbiAgICAgICAgXSkgPT4ge1xuICAgICAgICAgIGNvbnN0IGlzTmVlZFNjcm9sbFRvTGVmdDogYm9vbGVhbiA9IGxlZnRPZmZzZXRQeCA8IHJpZ2h0T2Zmc2V0UHg7XG4gICAgICAgICAgY29uc3QgaXNOZWVkU2Nyb2xsVG9SaWdodDogYm9vbGVhbiA9IHJpZ2h0T2Zmc2V0UHggPCBsZWZ0T2Zmc2V0UHg7XG5cbiAgICAgICAgICBjb25zdCBpc1Ntb290aFNjcm9sbDogYm9vbGVhbiA9IHRydWU7XG5cbiAgICAgICAgICBpZiAoaXNOZWVkU2Nyb2xsVG9MZWZ0KSB7XG4gICAgICAgICAgICBzY3JvbGxhYmxlLnNldFNjcm9sbExlZnRCeURlbHRhKE1hdGguY2VpbCgtY2VudGVyTGVmdERlbHRhUHggKyBsZWZ0T2Zmc2V0UHgpLCBpc1Ntb290aFNjcm9sbCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgaWYgKGlzTmVlZFNjcm9sbFRvUmlnaHQpIHtcbiAgICAgICAgICAgIHNjcm9sbGFibGUuc2V0U2Nyb2xsTGVmdEJ5RGVsdGEoTWF0aC5jZWlsKC1yaWdodE9mZnNldFB4ICsgY2VudGVyTGVmdERlbHRhUHgpLCBpc1Ntb290aFNjcm9sbCk7XG4gICAgICAgICAgICByZXR1cm47XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICApO1xuICB9XG5cbiAgcHJpdmF0ZSByZXNldEFjdGl2ZVRhYklmVW5yZWdpc3RlcmVkVGFiSXNBY3RpdmUocmVtb3ZlZFRhYk5hbWU6IFQpOiB2b2lkIHtcbiAgICB0aGlzLmFjdGl2ZVRhYk5hbWUkXG4gICAgICAucGlwZShcbiAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgZmlsdGVyKChhY3RpdmVUYWJOYW1lOiBUKSA9PiBhY3RpdmVUYWJOYW1lID09PSByZW1vdmVkVGFiTmFtZSlcbiAgICAgIClcbiAgICAgIC5zdWJzY3JpYmUoKCkgPT4gdGhpcy5zZXRBY3RpdmVUYWIobnVsbCkpO1xuICB9XG59XG4iXX0=