@bimeister/pupakit.tree
Version:
PupaKit Tree
187 lines • 35.2 kB
JavaScript
import '@angular/core';
import '@bimeister/event-bus/rxjs';
import { QueueEvents } from '@bimeister/pupakit.common';
import { isNil } from '@bimeister/utilities';
import { Subscription } from 'rxjs';
import { filter, mapTo, switchMap, withLatestFrom } from 'rxjs/operators';
import { TreeEvents } from '../events/tree.events';
import { FlatTreeItem } from './flat-tree-item.class';
import './tree-data-display-collection.class';
export class DefaultTreeEventHandler {
constructor(eventBus, dataDisplayCollection) {
this.eventBus = eventBus;
this.dataDisplayCollection = dataDisplayCollection;
this.subscription = new Subscription();
this.reconnect();
}
subscribeToEvents() {
this.subscription.add(this.getSubscriptionToSetData());
this.subscription.add(this.getSubscriptionForUpdateItem());
this.subscription.add(this.getSubscriptionForRemoveItem());
this.subscription.add(this.getSubscriptionForScrollTo());
this.subscription.add(this.getSubscriptionForRemoveChildren());
this.subscription.add(this.getSubscriptionForSetChildren());
}
getSubscriptionToSetData() {
return this.getEvents(TreeEvents.SetData)
.pipe(switchMap((event) => this.dataDisplayCollection.setData(event.payload).pipe(mapTo(event))))
.subscribe((event) => this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id)));
}
getSubscriptionForScrollTo() {
return this.getEvents(TreeEvents.ScrollById)
.pipe(withLatestFrom(this.dataDisplayCollection.data$))
.subscribe(([event, data]) => {
const treeItem = DefaultTreeEventHandler.getTreeItem(event.payload, data);
if (isNil(treeItem)) {
return this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id));
}
const index = data.indexOf(treeItem);
this.eventBus.dispatch(new TreeEvents.ScrollByIndex(index));
this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id));
});
}
getSubscriptionForRemoveItem() {
return this.getEvents(TreeEvents.RemoveItem)
.pipe(withLatestFrom(this.dataDisplayCollection.data$, this.dataDisplayCollection.expandedIdsList$))
.subscribe(([event, data, expandedIdsList]) => {
this.removeItemWithChildren(event.payload, data, expandedIdsList);
this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id));
});
}
getSubscriptionForUpdateItem() {
return this.getEvents(TreeEvents.UpdateItem)
.pipe(withLatestFrom(this.dataDisplayCollection.data$))
.subscribe(([event, data]) => {
this.updateItem(event.payload, data);
this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id));
});
}
updateItem(updatedItem, data) {
const treeItemExists = DefaultTreeEventHandler.treeItemExists(updatedItem.id, data);
if (!treeItemExists) {
return;
}
const updatedData = data.map((treeItem) => {
if (treeItem.id === updatedItem.id) {
return new FlatTreeItem(treeItem.isExpandable, updatedItem.name, treeItem.level, treeItem.id, updatedItem.originalData, treeItem.isElement);
}
return treeItem;
});
this.eventBus.dispatch(new TreeEvents.SetData(updatedData));
}
removeItem(removeItemId, data) {
const treeItemExists = DefaultTreeEventHandler.treeItemExists(removeItemId, data);
if (!treeItemExists) {
return;
}
const updatedData = data.filter((treeItem) => treeItem.id !== removeItemId);
this.eventBus.dispatch(new TreeEvents.SetData(updatedData));
}
reconnect() {
this.disconnect();
this.subscribeToEvents();
}
disconnect() {
this.subscription.unsubscribe();
this.subscription = new Subscription();
}
getEvents(eventType) {
return this.eventBus
.listen()
.pipe(filter((event) => event instanceof eventType));
}
getSubscriptionForSetChildren() {
return this.getEvents(TreeEvents.SetChildren)
.pipe(withLatestFrom(this.dataDisplayCollection.data$, this.dataDisplayCollection.expandedIdsList$))
.subscribe(([event, data, expandedIdsList]) => {
this.setChildren(event.payload.treeItemId, event.payload.children, data, expandedIdsList);
this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id));
});
}
getSubscriptionForRemoveChildren() {
return this.getEvents(TreeEvents.RemoveChildren)
.pipe(withLatestFrom(this.dataDisplayCollection.data$, this.dataDisplayCollection.expandedIdsList$))
.subscribe(([event, data, expandedIdsList]) => {
this.removeChildren(event.payload, data, expandedIdsList);
this.eventBus.dispatch(new QueueEvents.RemoveFromQueue(event.id));
});
}
setChildren(parentId, children, data, expandedIdsList) {
if (isNil(parentId)) {
const newData = children.map((treeItem) => ({ ...treeItem, level: 0 }));
this.eventBus.dispatch(new TreeEvents.SetData(newData));
this.eventBus.dispatch(new TreeEvents.SetExpanded([]));
return;
}
const parentIsExpanded = expandedIdsList.includes(parentId);
if (parentIsExpanded) {
return;
}
const parent = DefaultTreeEventHandler.getTreeItem(parentId, data);
const isExpanded = expandedIdsList.includes(parentId);
if (isNil(parent) || isExpanded) {
return;
}
const childrenIdsSet = new Set();
const childrenWithLevel = children.map((childItem) => {
childrenIdsSet.add(childItem.id);
return {
...childItem,
level: Number(parent.level) + 1,
};
});
const parentIndex = data.indexOf(parent);
const dataWithChildren = [
...data.slice(0, parentIndex),
parent,
...childrenWithLevel,
...data.slice(parentIndex + 1),
];
const noExpandedChildrenList = expandedIdsList.filter((expandedTreeItemId) => !childrenIdsSet.has(expandedTreeItemId));
const newExpandedList = [...noExpandedChildrenList, parent.id];
this.eventBus.dispatch(new TreeEvents.SetData(dataWithChildren));
this.eventBus.dispatch(new TreeEvents.SetExpanded(newExpandedList));
}
removeItemWithChildren(removeItemId, data, expanded) {
const treeItemExists = DefaultTreeEventHandler.treeItemExists(removeItemId, data);
if (!treeItemExists) {
this.eventBus.dispatch(new TreeEvents.SetData(data));
this.eventBus.dispatch(new TreeEvents.SetExpanded(expanded));
return;
}
const [dataWithoutChildren, expandedWithoutChildren] = this.getRemovedChildren(removeItemId, data, expanded);
const dataWithoutRemovedItem = dataWithoutChildren.filter((treeItem) => treeItem.id !== removeItemId);
this.eventBus.dispatch(new TreeEvents.SetData(dataWithoutRemovedItem));
this.eventBus.dispatch(new TreeEvents.SetExpanded(expandedWithoutChildren));
}
removeChildren(parentId, data, expanded) {
const [dataWithoutChildren, expandedWithoutChildren] = this.getRemovedChildren(parentId, data, expanded);
this.eventBus.dispatch(new TreeEvents.SetData(dataWithoutChildren));
this.eventBus.dispatch(new TreeEvents.SetExpanded(expandedWithoutChildren));
}
getRemovedChildren(parentId, data, expanded) {
const parent = DefaultTreeEventHandler.getTreeItem(parentId, data);
if (isNil(parent)) {
return [data, expanded];
}
const parentIndex = data.indexOf(parent);
const dataBeforeParent = parentIndex === 0 ? [] : data.slice(0, parentIndex);
const dataAfterParent = data.slice(parentIndex + 1);
const nextNonChildIndex = dataAfterParent.findIndex((dataItem) => dataItem.level <= parent.level);
const isLastParent = nextNonChildIndex === -1;
const children = dataAfterParent.slice(0, nextNonChildIndex);
const childrenIdsList = children.map((child) => child.id);
const expandedWithoutChildren = expanded.filter((expandedItemId) => !childrenIdsList.includes(expandedItemId) && expandedItemId !== parentId);
const dataAfterLastChild = isLastParent ? [] : dataAfterParent.slice(nextNonChildIndex);
const dataWithoutChildren = [...dataBeforeParent, parent, ...dataAfterLastChild];
return [dataWithoutChildren, expandedWithoutChildren];
}
static treeItemExists(treeItemId, data) {
const treeItem = DefaultTreeEventHandler.getTreeItem(treeItemId, data);
return !isNil(treeItem);
}
static getTreeItem(treeItemId, data) {
return data.find((treeItem) => treeItem.id === treeItemId);
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGVmYXVsdC10cmVlLWV2ZW50LWhhbmRsZXIuY2xhc3MuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi9zcmMvZGVjbGFyYXRpb25zL2NsYXNzZXMvZGVmYXVsdC10cmVlLWV2ZW50LWhhbmRsZXIuY2xhc3MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBcUIsZUFBZSxDQUFDO0FBQ3JDLE9BQXlCLDJCQUEyQixDQUFDO0FBQ3JELE9BQU8sRUFBRSxXQUFXLEVBQUUsTUFBTSwyQkFBMkIsQ0FBQztBQUN4RCxPQUFPLEVBQUUsS0FBSyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFDN0MsT0FBTyxFQUFjLFlBQVksRUFBRSxNQUFNLE1BQU0sQ0FBQztBQUNoRCxPQUFPLEVBQUUsTUFBTSxFQUFFLEtBQUssRUFBRSxTQUFTLEVBQUUsY0FBYyxFQUFFLE1BQU0sZ0JBQWdCLENBQUM7QUFDMUUsT0FBTyxFQUFFLFVBQVUsRUFBRSxNQUFNLHVCQUF1QixDQUFDO0FBQ25ELE9BQU8sRUFBRSxZQUFZLEVBQUUsTUFBTSx3QkFBd0IsQ0FBQztBQUN0RCxPQUEwQyxzQ0FBc0MsQ0FBQztBQUVqRixNQUFNLE9BQU8sdUJBQXVCO0lBR2xDLFlBQ3FCLFFBQWtCLEVBQ2xCLHFCQUFnRDtRQURoRCxhQUFRLEdBQVIsUUFBUSxDQUFVO1FBQ2xCLDBCQUFxQixHQUFyQixxQkFBcUIsQ0FBMkI7UUFKM0QsaUJBQVksR0FBaUIsSUFBSSxZQUFZLEVBQUUsQ0FBQztRQU14RCxJQUFJLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDbkIsQ0FBQztJQUVTLGlCQUFpQjtRQUN6QixJQUFJLENBQUMsWUFBWSxDQUFDLEdBQUcsQ0FBQyxJQUFJLENBQUMsd0JBQXdCLEVBQUUsQ0FBQyxDQUFDO1FBQ3ZELElBQUksQ0FBQyxZQUFZLENBQUMsR0FBRyxDQUFDLElBQUksQ0FBQyw0QkFBNEIsRUFBRSxDQUFDLENBQUM7UUFDM0QsSUFBSSxDQUFDLFlBQVks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QUFJLENBQUMsSUFBSSxDQUFDLENBQUMsUUFBc0IsRUFBRSxFQUFFLENBQUMsUUFBUSxDQUFDLEVBQUUsS0FBSyxVQUFVLENBQUMsQ0FBQztJQUMzRSxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBUeXBlIH0gZnJvbSAnQGFuZ3VsYXIvY29yZSc7XG5pbXBvcnQgeyBFdmVudEJ1cyB9IGZyb20gJ0BiaW1laXN0ZXIvZXZlbnQtYnVzL3J4anMnO1xuaW1wb3J0IHsgUXVldWVFdmVudHMgfSBmcm9tICdAYmltZWlzdGVyL3B1cGFraXQuY29tbW9uJztcbmltcG9ydCB7IGlzTmlsIH0gZnJvbSAnQGJpbWVpc3Rlci91dGlsaXRpZXMnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XG5pbXBvcnQgeyBmaWx0ZXIsIG1hcFRvLCBzd2l0Y2hNYXAsIHdpdGhMYXRlc3RGcm9tIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgVHJlZUV2ZW50cyB9IGZyb20gJy4uL2V2ZW50cy90cmVlLmV2ZW50cyc7XG5pbXBvcnQgeyBGbGF0VHJlZUl0ZW0gfSBmcm9tICcuL2ZsYXQtdHJlZS1pdGVtLmNsYXNzJztcbmltcG9ydCB7IFRyZWVEYXRhRGlzcGxheUNvbGxlY3Rpb24gfSBmcm9tICcuL3RyZWUtZGF0YS1kaXNwbGF5LWNvbGxlY3Rpb24uY2xhc3MnO1xuXG5leHBvcnQgY2xhc3MgRGVmYXVsdFRyZWVFdmVudEhhbmRsZXIge1xuICBwcm90ZWN0ZWQgc3Vic2NyaXB0aW9uOiBTdWJzY3JpcHRpb24gPSBuZXcgU3Vic2NyaXB0aW9uKCk7XG5cbiAgY29uc3RydWN0b3IoXG4gICAgcHJvdGVjdGVkIHJlYWRvbmx5IGV2ZW50QnVzOiBFdmVudEJ1cyxcbiAgICBwcm90ZWN0ZWQgcmVhZG9ubHkgZGF0YURpc3BsYXlDb2xsZWN0aW9uOiBUcmVlRGF0YURpc3BsYXlDb2xsZWN0aW9uXG4gICkge1xuICAgIHRoaXMucmVjb25uZWN0KCk7XG4gIH1cblxuICBwcm90ZWN0ZWQgc3Vic2NyaWJlVG9FdmVudHMoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKHRoaXMuZ2V0U3Vic2NyaXB0aW9uVG9TZXREYXRhKCkpO1xuICAgIHRoaXMuc3Vic2NyaXB0aW9uLmFkZCh0aGlzLmdldFN1YnNjcmlwdGlvbkZvclVwZGF0ZUl0ZW0oKSk7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24uYWRkKHRoaXMuZ2V0U3Vic2NyaXB0aW9uRm9yUmVtb3ZlSXRlbSgpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQodGhpcy5nZXRTdWJzY3JpcHRpb25Gb3JTY3JvbGxUbygpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQodGhpcy5nZXRTdWJzY3JpcHRpb25Gb3JSZW1vdmVDaGlsZHJlbigpKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbi5hZGQodGhpcy5nZXRTdWJzY3JpcHRpb25Gb3JTZXRDaGlsZHJlbigpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBnZXRTdWJzY3JpcHRpb25Ub1NldERhdGEoKTogU3Vic2NyaXB0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5nZXRFdmVudHMoVHJlZUV2ZW50cy5TZXREYXRhKVxuICAgICAgLnBpcGUoXG4gICAgICAgIHN3aXRjaE1hcCgoZXZlbnQ6IFRyZWVFdmVudHMuU2V0RGF0YSkgPT4gdGhpcy5kYXRhRGlzcGxheUNvbGxlY3Rpb24uc2V0RGF0YShldmVudC5wYXlsb2FkKS5waXBlKG1hcFRvKGV2ZW50KSkpXG4gICAgICApXG4gICAgICAuc3Vic2NyaWJlKChldmVudDogVHJlZUV2ZW50cy5TZXREYXRhKSA9PiB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBRdWV1ZUV2ZW50cy5SZW1vdmVGcm9tUXVldWUoZXZlbnQuaWQpKSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0U3Vic2NyaXB0aW9uRm9yU2Nyb2xsVG8oKTogU3Vic2NyaXB0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5nZXRFdmVudHMoVHJlZUV2ZW50cy5TY3JvbGxCeUlkKVxuICAgICAgLnBpcGUod2l0aExhdGVzdEZyb20odGhpcy5kYXRhRGlzcGxheUNvbGxlY3Rpb24uZGF0YSQpKVxuICAgICAgLnN1YnNjcmliZSgoW2V2ZW50LCBkYXRhXTogW1RyZWVFdmVudHMuU2Nyb2xsQnlJZCwgRmxhdFRyZWVJdGVtW11dKSA9PiB7XG4gICAgICAgIGNvbnN0IHRyZWVJdGVtOiBGbGF0VHJlZUl0ZW0gPSBEZWZhdWx0VHJlZUV2ZW50SGFuZGxlci5nZXRUcmVlSXRlbShldmVudC5wYXlsb2FkLCBkYXRhKTtcbiAgICAgICAgaWYgKGlzTmlsKHRyZWVJdGVtKSkge1xuICAgICAgICAgIHJldHVybiB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBRdWV1ZUV2ZW50cy5SZW1vdmVGcm9tUXVldWUoZXZlbnQuaWQpKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBpbmRleDogbnVtYmVyID0gZGF0YS5pbmRleE9mKHRyZWVJdGVtKTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5kaXNwYXRjaChuZXcgVHJlZUV2ZW50cy5TY3JvbGxCeUluZGV4KGluZGV4KSk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZGlzcGF0Y2gobmV3IFF1ZXVlRXZlbnRzLlJlbW92ZUZyb21RdWV1ZShldmVudC5pZCkpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0U3Vic2NyaXB0aW9uRm9yUmVtb3ZlSXRlbSgpOiBTdWJzY3JpcHRpb24ge1xuICAgIHJldHVybiB0aGlzLmdldEV2ZW50cyhUcmVlRXZlbnRzLlJlbW92ZUl0ZW0pXG4gICAgICAucGlwZSh3aXRoTGF0ZXN0RnJvbSh0aGlzLmRhdGFEaXNwbGF5Q29sbGVjdGlvbi5kYXRhJCwgdGhpcy5kYXRhRGlzcGxheUNvbGxlY3Rpb24uZXhwYW5kZWRJZHNMaXN0JCkpXG4gICAgICAuc3Vic2NyaWJlKChbZXZlbnQsIGRhdGEsIGV4cGFuZGVkSWRzTGlzdF06IFtUcmVlRXZlbnRzLlJlbW92ZUl0ZW0sIEZsYXRUcmVlSXRlbVtdLCBzdHJpbmdbXV0pID0+IHtcbiAgICAgICAgdGhpcy5yZW1vdmVJdGVtV2l0aENoaWxkcmVuKGV2ZW50LnBheWxvYWQsIGRhdGEsIGV4cGFuZGVkSWRzTGlzdCk7XG4gICAgICAgIHRoaXMuZXZlbnRCdXMuZGlzcGF0Y2gobmV3IFF1ZXVlRXZlbnRzLlJlbW92ZUZyb21RdWV1ZShldmVudC5pZCkpO1xuICAgICAgfSk7XG4gIH1cblxuICBwcm90ZWN0ZWQgZ2V0U3Vic2NyaXB0aW9uRm9yVXBkYXRlSXRlbSgpOiBTdWJzY3JpcHRpb24ge1xuICAgIHJldHVybiB0aGlzLmdldEV2ZW50cyhUcmVlRXZlbnRzLlVwZGF0ZUl0ZW0pXG4gICAgICAucGlwZSh3aXRoTGF0ZXN0RnJvbSh0aGlzLmRhdGFEaXNwbGF5Q29sbGVjdGlvbi5kYXRhJCkpXG4gICAgICAuc3Vic2NyaWJlKChbZXZlbnQsIGRhdGFdOiBbVHJlZUV2ZW50cy5VcGRhdGVJdGVtLCBGbGF0VHJlZUl0ZW1bXV0pID0+IHtcbiAgICAgICAgdGhpcy51cGRhdGVJdGVtKGV2ZW50LnBheWxvYWQsIGRhdGEpO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBRdWV1ZUV2ZW50cy5SZW1vdmVGcm9tUXVldWUoZXZlbnQuaWQpKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJvdGVjdGVkIHVwZGF0ZUl0ZW0odXBkYXRlZEl0ZW06IEZsYXRUcmVlSXRlbSwgZGF0YTogRmxhdFRyZWVJdGVtW10pOiB2b2lkIHtcbiAgICBjb25zdCB0cmVlSXRlbUV4aXN0czogYm9vbGVhbiA9IERlZmF1bHRUcmVlRXZlbnRIYW5kbGVyLnRyZWVJdGVtRXhpc3RzKHVwZGF0ZWRJdGVtLmlkLCBkYXRhKTtcbiAgICBpZiAoIXRyZWVJdGVtRXhpc3RzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZWREYXRhOiBGbGF0VHJlZUl0ZW1bXSA9IGRhdGEubWFwKCh0cmVlSXRlbTogRmxhdFRyZWVJdGVtKSA9PiB7XG4gICAgICBpZiAodHJlZUl0ZW0uaWQgPT09IHVwZGF0ZWRJdGVtLmlkKSB7XG4gICAgICAgIHJldHVybiBuZXcgRmxhdFRyZWVJdGVtKFxuICAgICAgICAgIHRyZWVJdGVtLmlzRXhwYW5kYWJsZSxcbiAgICAgICAgICB1cGRhdGVkSXRlbS5uYW1lLFxuICAgICAgICAgIHRyZWVJdGVtLmxldmVsLFxuICAgICAgICAgIHRyZWVJdGVtLmlkLFxuICAgICAgICAgIHVwZGF0ZWRJdGVtLm9yaWdpbmFsRGF0YSxcbiAgICAgICAgICB0cmVlSXRlbS5pc0VsZW1lbnRcbiAgICAgICAgKTtcbiAgICAgIH1cbiAgICAgIHJldHVybiB0cmVlSXRlbTtcbiAgICB9KTtcbiAgICB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBUcmVlRXZlbnRzLlNldERhdGEodXBkYXRlZERhdGEpKTtcbiAgfVxuXG4gIHByb3RlY3RlZCByZW1vdmVJdGVtKHJlbW92ZUl0ZW1JZDogc3RyaW5nLCBkYXRhOiBGbGF0VHJlZUl0ZW1bXSk6IHZvaWQge1xuICAgIGNvbnN0IHRyZWVJdGVtRXhpc3RzOiBib29sZWFuID0gRGVmYXVsdFRyZWVFdmVudEhhbmRsZXIudHJlZUl0ZW1FeGlzdHMocmVtb3ZlSXRlbUlkLCBkYXRhKTtcbiAgICBpZiAoIXRyZWVJdGVtRXhpc3RzKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IHVwZGF0ZWREYXRhOiBGbGF0VHJlZUl0ZW1bXSA9IGRhdGEuZmlsdGVyKCh0cmVlSXRlbTogRmxhdFRyZWVJdGVtKSA9PiB0cmVlSXRlbS5pZCAhPT0gcmVtb3ZlSXRlbUlkKTtcbiAgICB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBUcmVlRXZlbnRzLlNldERhdGEodXBkYXRlZERhdGEpKTtcbiAgfVxuXG4gIHB1YmxpYyByZWNvbm5lY3QoKTogdm9pZCB7XG4gICAgdGhpcy5kaXNjb25uZWN0KCk7XG4gICAgdGhpcy5zdWJzY3JpYmVUb0V2ZW50cygpO1xuICB9XG5cbiAgcHVibGljIGRpc2Nvbm5lY3QoKTogdm9pZCB7XG4gICAgdGhpcy5zdWJzY3JpcHRpb24udW5zdWJzY3JpYmUoKTtcbiAgICB0aGlzLnN1YnNjcmlwdGlvbiA9IG5ldyBTdWJzY3JpcHRpb24oKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRFdmVudHM8RSBleHRlbmRzIFRyZWVFdmVudHMuVHJlZUV2ZW50QmFzZT4oZXZlbnRUeXBlOiBUeXBlPEU+KTogT2JzZXJ2YWJsZTxFPiB7XG4gICAgcmV0dXJuIHRoaXMuZXZlbnRCdXNcbiAgICAgIC5saXN0ZW4oKVxuICAgICAgLnBpcGUoZmlsdGVyKChldmVudDogVHJlZUV2ZW50cy5UcmVlRXZlbnRCYXNlKTogZXZlbnQgaXMgRSA9PiBldmVudCBpbnN0YW5jZW9mIGV2ZW50VHlwZSkpO1xuICB9XG5cbiAgcHJpdmF0ZSBnZXRTdWJzY3JpcHRpb25Gb3JTZXRDaGlsZHJlbigpOiBTdWJzY3JpcHRpb24ge1xuICAgIHJldHVybiB0aGlzLmdldEV2ZW50cyhUcmVlRXZlbnRzLlNldENoaWxkcmVuKVxuICAgICAgLnBpcGUod2l0aExhdGVzdEZyb20odGhpcy5kYXRhRGlzcGxheUNvbGxlY3Rpb24uZGF0YSQsIHRoaXMuZGF0YURpc3BsYXlDb2xsZWN0aW9uLmV4cGFuZGVkSWRzTGlzdCQpKVxuICAgICAgLnN1YnNjcmliZSgoW2V2ZW50LCBkYXRhLCBleHBhbmRlZElkc0xpc3RdOiBbVHJlZUV2ZW50cy5TZXRDaGlsZHJlbiwgRmxhdFRyZWVJdGVtW10sIHN0cmluZ1tdXSkgPT4ge1xuICAgICAgICB0aGlzLnNldENoaWxkcmVuKGV2ZW50LnBheWxvYWQudHJlZUl0ZW1JZCwgZXZlbnQucGF5bG9hZC5jaGlsZHJlbiwgZGF0YSwgZXhwYW5kZWRJZHNMaXN0KTtcbiAgICAgICAgdGhpcy5ldmVudEJ1cy5kaXNwYXRjaChuZXcgUXVldWVFdmVudHMuUmVtb3ZlRnJvbVF1ZXVlKGV2ZW50LmlkKSk7XG4gICAgICB9KTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0U3Vic2NyaXB0aW9uRm9yUmVtb3ZlQ2hpbGRyZW4oKTogU3Vic2NyaXB0aW9uIHtcbiAgICByZXR1cm4gdGhpcy5nZXRFdmVudHMoVHJlZUV2ZW50cy5SZW1vdmVDaGlsZHJlbilcbiAgICAgIC5waXBlKHdpdGhMYXRlc3RGcm9tKHRoaXMuZGF0YURpc3BsYXlDb2xsZWN0aW9uLmRhdGEkLCB0aGlzLmRhdGFEaXNwbGF5Q29sbGVjdGlvbi5leHBhbmRlZElkc0xpc3QkKSlcbiAgICAgIC5zdWJzY3JpYmUoKFtldmVudCwgZGF0YSwgZXhwYW5kZWRJZHNMaXN0XTogW1RyZWVFdmVudHMuUmVtb3ZlQ2hpbGRyZW4sIEZsYXRUcmVlSXRlbVtdLCBzdHJpbmdbXV0pID0+IHtcbiAgICAgICAgdGhpcy5yZW1vdmVDaGlsZHJlbihldmVudC5wYXlsb2FkLCBkYXRhLCBleHBhbmRlZElkc0xpc3QpO1xuICAgICAgICB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBRdWV1ZUV2ZW50cy5SZW1vdmVGcm9tUXVldWUoZXZlbnQuaWQpKTtcbiAgICAgIH0pO1xuICB9XG5cbiAgcHJpdmF0ZSBzZXRDaGlsZHJlbihcbiAgICBwYXJlbnRJZDogc3RyaW5nLFxuICAgIGNoaWxkcmVuOiBGbGF0VHJlZUl0ZW1bXSxcbiAgICBkYXRhOiBGbGF0VHJlZUl0ZW1bXSxcbiAgICBleHBhbmRlZElkc0xpc3Q6IHN0cmluZ1tdXG4gICk6IHZvaWQge1xuICAgIGlmIChpc05pbChwYXJlbnRJZCkpIHtcbiAgICAgIGNvbnN0IG5ld0RhdGE6IEZsYXRUcmVlSXRlbVtdID0gY2hpbGRyZW4ubWFwKCh0cmVlSXRlbTogRmxhdFRyZWVJdGVtKSA9PiAoeyAuLi50cmVlSXRlbSwgbGV2ZWw6IDAgfSkpO1xuICAgICAgdGhpcy5ldmVudEJ1cy5kaXNwYXRjaChuZXcgVHJlZUV2ZW50cy5TZXREYXRhKG5ld0RhdGEpKTtcbiAgICAgIHRoaXMuZXZlbnRCdXMuZGlzcGF0Y2gobmV3IFRyZWVFdmVudHMuU2V0RXhwYW5kZWQoW10pKTtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50SXNFeHBhbmRlZDogYm9vbGVhbiA9IGV4cGFuZGVkSWRzTGlzdC5pbmNsdWRlcyhwYXJlbnRJZCk7XG4gICAgaWYgKHBhcmVudElzRXhwYW5kZWQpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3QgcGFyZW50OiBGbGF0VHJlZUl0ZW0gPSBEZWZhdWx0VHJlZUV2ZW50SGFuZGxlci5nZXRUcmVlSXRlbShwYXJlbnRJZCwgZGF0YSk7XG4gICAgY29uc3QgaXNFeHBhbmRlZDogYm9vbGVhbiA9IGV4cGFuZGVkSWRzTGlzdC5pbmNsdWRlcyhwYXJlbnRJZCk7XG4gICAgaWYgKGlzTmlsKHBhcmVudCkgfHwgaXNFeHBhbmRlZCkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBjaGlsZHJlbklkc1NldDogU2V0PHN0cmluZz4gPSBuZXcgU2V0KCk7XG4gICAgY29uc3QgY2hpbGRyZW5XaXRoTGV2ZWw6IEZsYXRUcmVlSXRlbVtdID0gY2hpbGRyZW4ubWFwKChjaGlsZEl0ZW06IEZsYXRUcmVlSXRlbSkgPT4ge1xuICAgICAgY2hpbGRyZW5JZHNTZXQuYWRkKGNoaWxkSXRlbS5pZCk7XG4gICAgICByZXR1cm4ge1xuICAgICAgICAuLi5jaGlsZEl0ZW0sXG4gICAgICAgIGxldmVsOiBOdW1iZXIocGFyZW50LmxldmVsKSArIDEsXG4gICAgICB9O1xuICAgIH0pO1xuICAgIGNvbnN0IHBhcmVudEluZGV4OiBudW1iZXIgPSBkYXRhLmluZGV4T2YocGFyZW50KTtcbiAgICBjb25zdCBkYXRhV2l0aENoaWxkcmVuOiBGbGF0VHJlZUl0ZW1bXSA9IFtcbiAgICAgIC4uLmRhdGEuc2xpY2UoMCwgcGFyZW50SW5kZXgpLFxuICAgICAgcGFyZW50LFxuICAgICAgLi4uY2hpbGRyZW5XaXRoTGV2ZWwsXG4gICAgICAuLi5kYXRhLnNsaWNlKHBhcmVudEluZGV4ICsgMSksXG4gICAgXTtcbiAgICBjb25zdCBub0V4cGFuZGVkQ2hpbGRyZW5MaXN0OiBzdHJpbmdbXSA9IGV4cGFuZGVkSWRzTGlzdC5maWx0ZXIoXG4gICAgICAoZXhwYW5kZWRUcmVlSXRlbUlkOiBzdHJpbmcpID0+ICFjaGlsZHJlbklkc1NldC5oYXMoZXhwYW5kZWRUcmVlSXRlbUlkKVxuICAgICk7XG4gICAgY29uc3QgbmV3RXhwYW5kZWRMaXN0OiBzdHJpbmdbXSA9IFsuLi5ub0V4cGFuZGVkQ2hpbGRyZW5MaXN0LCBwYXJlbnQuaWRdO1xuICAgIHRoaXMuZXZlbnRCdXMuZGlzcGF0Y2gobmV3IFRyZWVFdmVudHMuU2V0RGF0YShkYXRhV2l0aENoaWxkcmVuKSk7XG4gICAgdGhpcy5ldmVudEJ1cy5kaXNwYXRjaChuZXcgVHJlZUV2ZW50cy5TZXRFeHBhbmRlZChuZXdFeHBhbmRlZExpc3QpKTtcbiAgfVxuXG4gIHByaXZhdGUgcmVtb3ZlSXRlbVdpdGhDaGlsZHJlbihyZW1vdmVJdGVtSWQ6IHN0cmluZywgZGF0YTogRmxhdFRyZWVJdGVtW10sIGV4cGFuZGVkOiBzdHJpbmdbXSk6IHZvaWQge1xuICAgIGNvbnN0IHRyZWVJdGVtRXhpc3RzOiBib29sZWFuID0gRGVmYXVsdFRyZWVFdmVudEhhbmRsZXIudHJlZUl0ZW1FeGlzdHMocmVtb3ZlSXRlbUlkLCBkYXRhKTtcbiAgICBpZiAoIXRyZWVJdGVtRXhpc3RzKSB7XG4gICAgICB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBUcmVlRXZlbnRzLlNldERhdGEoZGF0YSkpO1xuICAgICAgdGhpcy5ldmVudEJ1cy5kaXNwYXRjaChuZXcgVHJlZUV2ZW50cy5TZXRFeHBhbmRlZChleHBhbmRlZCkpO1xuICAgICAgcmV0dXJuO1xuICAgIH1cbiAgICBjb25zdCBbZGF0YVdpdGhvdXRDaGlsZHJlbiwgZXhwYW5kZWRXaXRob3V0Q2hpbGRyZW5dOiBbRmxhdFRyZWVJdGVtW10sIHN0cmluZ1tdXSA9IHRoaXMuZ2V0UmVtb3ZlZENoaWxkcmVuKFxuICAgICAgcmVtb3ZlSXRlbUlkLFxuICAgICAgZGF0YSxcbiAgICAgIGV4cGFuZGVkXG4gICAgKTtcbiAgICBjb25zdCBkYXRhV2l0aG91dFJlbW92ZWRJdGVtOiBGbGF0VHJlZUl0ZW1bXSA9IGRhdGFXaXRob3V0Q2hpbGRyZW4uZmlsdGVyKFxuICAgICAgKHRyZWVJdGVtOiBGbGF0VHJlZUl0ZW0pID0+IHRyZWVJdGVtLmlkICE9PSByZW1vdmVJdGVtSWRcbiAgICApO1xuICAgIHRoaXMuZXZlbnRCdXMuZGlzcGF0Y2gobmV3IFRyZWVFdmVudHMuU2V0RGF0YShkYXRhV2l0aG91dFJlbW92ZWRJdGVtKSk7XG4gICAgdGhpcy5ldmVudEJ1cy5kaXNwYXRjaChuZXcgVHJlZUV2ZW50cy5TZXRFeHBhbmRlZChleHBhbmRlZFdpdGhvdXRDaGlsZHJlbikpO1xuICB9XG5cbiAgcHJpdmF0ZSByZW1vdmVDaGlsZHJlbihwYXJlbnRJZDogc3RyaW5nLCBkYXRhOiBGbGF0VHJlZUl0ZW1bXSwgZXhwYW5kZWQ6IHN0cmluZ1tdKTogdm9pZCB7XG4gICAgY29uc3QgW2RhdGFXaXRob3V0Q2hpbGRyZW4sIGV4cGFuZGVkV2l0aG91dENoaWxkcmVuXTogW0ZsYXRUcmVlSXRlbVtdLCBzdHJpbmdbXV0gPSB0aGlzLmdldFJlbW92ZWRDaGlsZHJlbihcbiAgICAgIHBhcmVudElkLFxuICAgICAgZGF0YSxcbiAgICAgIGV4cGFuZGVkXG4gICAgKTtcbiAgICB0aGlzLmV2ZW50QnVzLmRpc3BhdGNoKG5ldyBUcmVlRXZlbnRzLlNldERhdGEoZGF0YVdpdGhvdXRDaGlsZHJlbikpO1xuICAgIHRoaXMuZXZlbnRCdXMuZGlzcGF0Y2gobmV3IFRyZWVFdmVudHMuU2V0RXhwYW5kZWQoZXhwYW5kZWRXaXRob3V0Q2hpbGRyZW4pKTtcbiAgfVxuXG4gIHByaXZhdGUgZ2V0UmVtb3ZlZENoaWxkcmVuKHBhcmVudElkOiBzdHJpbmcsIGRhdGE6IEZsYXRUcmVlSXRlbVtdLCBleHBhbmRlZDogc3RyaW5nW10pOiBbRmxhdFRyZWVJdGVtW10sIHN0cmluZ1tdXSB7XG4gICAgY29uc3QgcGFyZW50OiBGbGF0VHJlZUl0ZW0gPSBEZWZhdWx0VHJlZUV2ZW50SGFuZGxlci5nZXRUcmVlSXRlbShwYXJlbnRJZCwgZGF0YSk7XG4gICAgaWYgKGlzTmlsKHBhcmVudCkpIHtcbiAgICAgIHJldHVybiBbZGF0YSwgZXhwYW5kZWRdO1xuICAgIH1cbiAgICBjb25zdCBwYXJlbnRJbmRleDogbnVtYmVyID0gZGF0YS5pbmRleE9mKHBhcmVudCk7XG4gICAgY29uc3QgZGF0YUJlZm9yZVBhcmVudDogRmxhdFRyZWVJdGVtW10gPSBwYXJlbnRJbmRleCA9PT0gMCA/IFtdIDogZGF0YS5zbGljZSgwLCBwYXJlbnRJbmRleCk7XG4gICAgY29uc3QgZGF0YUFmdGVyUGFyZW50OiBGbGF0VHJlZUl0ZW1bXSA9IGRhdGEuc2xpY2UocGFyZW50SW5kZXggKyAxKTtcbiAgICBjb25zdCBuZXh0Tm9uQ2hpbGRJbmRleDogbnVtYmVyID0gZGF0YUFmdGVyUGFyZW50LmZpbmRJbmRleChcbiAgICAgIChkYXRhSXRlbTogRmxhdFRyZWVJdGVtKSA9PiBkYXRhSXRlbS5sZXZlbCA8PSBwYXJlbnQubGV2ZWxcbiAgICApO1xuICAgIGNvbnN0IGlzTGFzdFBhcmVudDogYm9vbGVhbiA9IG5leHROb25DaGlsZEluZGV4ID09PSAtMTtcbiAgICBjb25zdCBjaGlsZHJlbjogRmxhdFRyZWVJdGVtW10gPSBkYXRhQWZ0ZXJQYXJlbnQuc2xpY2UoMCwgbmV4dE5vbkNoaWxkSW5kZXgpO1xuICAgIGNvbnN0IGNoaWxkcmVuSWRzTGlzdDogc3RyaW5nW10gPSBjaGlsZHJlbi5tYXAoKGNoaWxkOiBGbGF0VHJlZUl0ZW0pID0+IGNoaWxkLmlkKTtcbiAgICBjb25zdCBleHBhbmRlZFdpdGhvdXRDaGlsZHJlbjogc3RyaW5nW10gPSBleHBhbmRlZC5maWx0ZXIoXG4gICAgICAoZXhwYW5kZWRJdGVtSWQ6IHN0cmluZykgPT4gIWNoaWxkcmVuSWRzTGlzdC5pbmNsdWRlcyhleHBhbmRlZEl0ZW1JZCkgJiYgZXhwYW5kZWRJdGVtSWQgIT09IHBhcmVudElkXG4gICAgKTtcbiAgICBjb25zdCBkYXRhQWZ0ZXJMYXN0Q2hpbGQ6IEZsYXRUcmVlSXRlbVtdID0gaXNMYXN0UGFyZW50ID8gW10gOiBkYXRhQWZ0ZXJQYXJlbnQuc2xpY2UobmV4dE5vbkNoaWxkSW5kZXgpO1xuICAgIGNvbnN0IGRhdGFXaXRob3V0Q2hpbGRyZW46IEZsYXRUcmVlSXRlbVtdID0gWy4uLmRhdGFCZWZvcmVQYXJlbnQsIHBhcmVudCwgLi4uZGF0YUFmdGVyTGFzdENoaWxkXTtcbiAgICByZXR1cm4gW2RhdGFXaXRob3V0Q2hpbGRyZW4sIGV4cGFuZGVkV2l0aG91dENoaWxkcmVuXTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdGF0aWMgdHJlZUl0ZW1FeGlzdHModHJlZUl0ZW1JZDogc3RyaW5nLCBkYXRhOiBGbGF0VHJlZUl0ZW1bXSk6IGJvb2xlYW4ge1xuICAgIGNvbnN0IHRyZWVJdGVtOiBGbGF0VHJlZUl0ZW0gPSBEZWZhdWx0VHJlZUV2ZW50SGFuZGxlci5nZXRUcmVlSXRlbSh0cmVlSXRlbUlkLCBkYXRhKTtcbiAgICByZXR1cm4gIWlzTmlsKHRyZWVJdGVtKTtcbiAgfVxuXG4gIHByb3RlY3RlZCBzdGF0aWMgZ2V0VHJlZUl0ZW0odHJlZUl0ZW1JZDogc3RyaW5nLCBkYXRhOiBGbGF0VHJlZUl0ZW1bXSk6IEZsYXRUcmVlSXRlbSB7XG4gICAgcmV0dXJuIGRhdGEuZmluZCgodHJlZUl0ZW06IEZsYXRUcmVlSXRlbSkgPT4gdHJlZUl0ZW0uaWQgPT09IHRyZWVJdGVtSWQpO1xuICB9XG59XG4iXX0=