UNPKG

@odymaui/angular-tree-component

Version:

A simple yet powerful tree component for Angular16. WARNING: This is an unsupported fork for use in a dependent project to upgrade it to Angular 16. Unit tests pass and the example-app works as expected.

481 lines 61.4 kB
import { Injectable } from '@angular/core'; import { observable, computed, action, autorun, makeObservable } from 'mobx'; import { TreeNode } from './tree-node.model'; import { TreeOptions } from './tree-options.model'; import { TREE_EVENTS } from '../constants/events'; import * as i0 from "@angular/core"; export class TreeModel { static focusedTree = null; options = new TreeOptions(); nodes; eventNames = Object.keys(TREE_EVENTS); virtualScroll; roots; expandedNodeIds = {}; selectedLeafNodeIds = {}; activeNodeIds = {}; hiddenNodeIds = {}; focusedNodeId = null; virtualRoot; firstUpdate = true; events; subscriptions = []; constructor() { makeObservable(this, { roots: observable, expandedNodeIds: observable, selectedLeafNodeIds: observable, activeNodeIds: observable, hiddenNodeIds: observable, focusedNodeId: observable, virtualRoot: observable, focusedNode: computed, expandedNodes: computed, activeNodes: computed, hiddenNodes: computed, selectedLeafNodes: computed, setData: action, update: action, setFocusedNode: action, setFocus: action, doForAll: action, focusNextNode: action, focusPreviousNode: action, focusDrillDown: action, focusDrillUp: action, setActiveNode: action, setSelectedNode: action, setExpandedNode: action, expandAll: action, collapseAll: action, setIsHidden: action, setHiddenNodeIds: action, filterNodes: action, clearFilter: action, moveNode: action, copyNode: action, setState: action, }); } // events fireEvent(event) { event.treeModel = this; this.events[event.eventName].emit(event); this.events.event.emit(event); } subscribe(eventName, fn) { const subscription = this.events[eventName].subscribe(fn); this.subscriptions.push(subscription); } // getters getFocusedNode() { return this.focusedNode; } getActiveNode() { return this.activeNodes[0]; } getActiveNodes() { return this.activeNodes; } getVisibleRoots() { return this.virtualRoot.visibleChildren; } getFirstRoot(skipHidden = false) { const root = skipHidden ? this.getVisibleRoots() : this.roots; return root != null && root.length ? root[0] : null; } getLastRoot(skipHidden = false) { const root = skipHidden ? this.getVisibleRoots() : this.roots; return root != null && root.length ? root[root.length - 1] : null; } get isFocused() { return TreeModel.focusedTree === this; } isNodeFocused(node) { return this.focusedNode === node; } isEmptyTree() { return this.roots && this.roots.length === 0; } get focusedNode() { return this.focusedNodeId ? this.getNodeById(this.focusedNodeId) : null; } get expandedNodes() { const nodes = Object.keys(this.expandedNodeIds) .filter((id) => this.expandedNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } get activeNodes() { const nodes = Object.keys(this.activeNodeIds) .filter((id) => this.activeNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } get hiddenNodes() { const nodes = Object.keys(this.hiddenNodeIds) .filter((id) => this.hiddenNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } get selectedLeafNodes() { const nodes = Object.keys(this.selectedLeafNodeIds) .filter((id) => this.selectedLeafNodeIds[id]) .map((id) => this.getNodeById(id)); return nodes.filter(Boolean); } // locating nodes getNodeByPath(path, startNode = null) { if (!path) return null; startNode = startNode || this.virtualRoot; if (path.length === 0) return startNode; if (!startNode.children) return null; const childId = path.shift(); const childNode = startNode.children.find(c => c.id === childId); if (!childNode) return null; return this.getNodeByPath(path, childNode); } getNodeById(id) { const idStr = id.toString(); return this.getNodeBy((node) => node.id.toString() === idStr); } getNodeBy(predicate, startNode = null) { startNode = startNode || this.virtualRoot; if (!startNode.children) return null; const found = startNode.children.find(predicate); if (found) { // found in children return found; } else { // look in children's children for (let child of startNode.children) { const foundInChildren = this.getNodeBy(predicate, child); if (foundInChildren) return foundInChildren; } } } isExpanded(node) { return this.expandedNodeIds[node.id]; } isHidden(node) { return this.hiddenNodeIds[node.id]; } isActive(node) { return this.activeNodeIds[node.id]; } isSelected(node) { return this.selectedLeafNodeIds[node.id]; } ngOnDestroy() { this.dispose(); this.unsubscribeAll(); } dispose() { // Dispose reactions of the replaced nodes if (this.virtualRoot) { this.virtualRoot.dispose(); } } unsubscribeAll() { this.subscriptions.forEach(subscription => subscription.unsubscribe()); this.subscriptions = []; } // actions setData({ nodes, options = null, events = null }) { if (options) { this.options = new TreeOptions(options); } if (events) { this.events = events; } if (nodes) { this.nodes = nodes; } this.update(); } update() { // Rebuild tree: let virtualRootConfig = { id: this.options.rootId, virtual: true, [this.options.childrenField]: this.nodes }; this.dispose(); this.virtualRoot = new TreeNode(virtualRootConfig, null, this, 0); this.roots = this.virtualRoot.children; // Fire event: if (this.firstUpdate) { if (this.roots) { this.firstUpdate = false; this._calculateExpandedNodes(); } } else { this.fireEvent({ eventName: TREE_EVENTS.updateData }); } } setFocusedNode(node) { this.focusedNodeId = node ? node.id : null; } setFocus(value) { TreeModel.focusedTree = value ? this : null; } doForAll(fn) { this.roots.forEach((root) => root.doForAll(fn)); } focusNextNode() { let previousNode = this.getFocusedNode(); let nextNode = previousNode ? previousNode.findNextNode(true, true) : this.getFirstRoot(true); if (nextNode) nextNode.focus(); } focusPreviousNode() { let previousNode = this.getFocusedNode(); let nextNode = previousNode ? previousNode.findPreviousNode(true) : this.getLastRoot(true); if (nextNode) nextNode.focus(); } focusDrillDown() { let previousNode = this.getFocusedNode(); if (previousNode && previousNode.isCollapsed && previousNode.hasChildren) { previousNode.toggleExpanded(); } else { let nextNode = previousNode ? previousNode.getFirstChild(true) : this.getFirstRoot(true); if (nextNode) nextNode.focus(); } } focusDrillUp() { let previousNode = this.getFocusedNode(); if (!previousNode) return; if (previousNode.isExpanded) { previousNode.toggleExpanded(); } else { let nextNode = previousNode.realParent; if (nextNode) nextNode.focus(); } } setActiveNode(node, value, multi = false) { if (multi) { this._setActiveNodeMulti(node, value); } else { this._setActiveNodeSingle(node, value); } if (value) { node.focus(this.options.scrollOnActivate); this.fireEvent({ eventName: TREE_EVENTS.activate, node }); this.fireEvent({ eventName: TREE_EVENTS.nodeActivate, node }); // For IE11 } else { this.fireEvent({ eventName: TREE_EVENTS.deactivate, node }); this.fireEvent({ eventName: TREE_EVENTS.nodeDeactivate, node }); // For IE11 } } setSelectedNode(node, value) { this.selectedLeafNodeIds = Object.assign({}, this.selectedLeafNodeIds, { [node.id]: value }); if (value) { node.focus(); this.fireEvent({ eventName: TREE_EVENTS.select, node }); } else { this.fireEvent({ eventName: TREE_EVENTS.deselect, node }); } } setExpandedNode(node, value) { this.expandedNodeIds = Object.assign({}, this.expandedNodeIds, { [node.id]: value }); this.fireEvent({ eventName: TREE_EVENTS.toggleExpanded, node, isExpanded: value }); } expandAll() { this.roots.forEach((root) => root.expandAll()); } collapseAll() { this.roots.forEach((root) => root.collapseAll()); } setIsHidden(node, value) { this.hiddenNodeIds = Object.assign({}, this.hiddenNodeIds, { [node.id]: value }); } setHiddenNodeIds(nodeIds) { this.hiddenNodeIds = nodeIds.reduce((hiddenNodeIds, id) => Object.assign(hiddenNodeIds, { [id]: true }), {}); } performKeyAction(node, $event) { const keyAction = this.options.actionMapping.keys[$event.keyCode]; if (keyAction) { $event.preventDefault(); keyAction(this, node, $event); return true; } else { return false; } } filterNodes(filter, autoShow = true) { let filterFn; if (!filter) { return this.clearFilter(); } // support function and string filter if (filter && typeof filter.valueOf() === 'string') { filterFn = (node) => node.displayField.toLowerCase().indexOf(filter.toLowerCase()) !== -1; } else if (filter && typeof filter === 'function') { filterFn = filter; } else { console.error('Don\'t know what to do with filter', filter); console.error('Should be either a string or function'); return; } const ids = {}; this.roots.forEach((node) => this._filterNode(ids, node, filterFn, autoShow)); this.hiddenNodeIds = ids; this.fireEvent({ eventName: TREE_EVENTS.changeFilter }); } clearFilter() { this.hiddenNodeIds = {}; this.fireEvent({ eventName: TREE_EVENTS.changeFilter }); } moveNode(node, to) { const fromIndex = node.getIndexInParent(); const fromParent = node.parent; if (!this.canMoveNode(node, to, fromIndex)) return; const fromChildren = fromParent.getField('children'); // If node doesn't have children - create children array if (!to.parent.getField('children')) { to.parent.setField('children', []); } const toChildren = to.parent.getField('children'); const originalNode = fromChildren.splice(fromIndex, 1)[0]; // Compensate for index if already removed from parent: let toIndex = (fromParent === to.parent && to.index > fromIndex) ? to.index - 1 : to.index; toChildren.splice(toIndex, 0, originalNode); fromParent.treeModel.update(); if (to.parent.treeModel !== fromParent.treeModel) { to.parent.treeModel.update(); } this.fireEvent({ eventName: TREE_EVENTS.moveNode, node: originalNode, to: { parent: to.parent.data, index: toIndex }, from: { parent: fromParent.data, index: fromIndex } }); } copyNode(node, to) { const fromIndex = node.getIndexInParent(); if (!this.canMoveNode(node, to, fromIndex)) return; // If node doesn't have children - create children array if (!to.parent.getField('children')) { to.parent.setField('children', []); } const toChildren = to.parent.getField('children'); const nodeCopy = this.options.getNodeClone(node); toChildren.splice(to.index, 0, nodeCopy); node.treeModel.update(); if (to.parent.treeModel !== node.treeModel) { to.parent.treeModel.update(); } this.fireEvent({ eventName: TREE_EVENTS.copyNode, node: nodeCopy, to: { parent: to.parent.data, index: to.index } }); } getState() { return { expandedNodeIds: this.expandedNodeIds, selectedLeafNodeIds: this.selectedLeafNodeIds, activeNodeIds: this.activeNodeIds, hiddenNodeIds: this.hiddenNodeIds, focusedNodeId: this.focusedNodeId }; } setState(state) { if (!state) return; Object.assign(this, { expandedNodeIds: state.expandedNodeIds || {}, selectedLeafNodeIds: state.selectedLeafNodeIds || {}, activeNodeIds: state.activeNodeIds || {}, hiddenNodeIds: state.hiddenNodeIds || {}, focusedNodeId: state.focusedNodeId }); } subscribeToState(fn) { autorun(() => fn(this.getState())); } canMoveNode(node, to, fromIndex = undefined) { const fromNodeIndex = fromIndex || node.getIndexInParent(); // same node: if (node.parent === to.parent && fromIndex === to.index) { return false; } return !to.parent.isDescendantOf(node); } calculateExpandedNodes() { this._calculateExpandedNodes(); } // private methods _filterNode(ids, node, filterFn, autoShow) { // if node passes function then it's visible let isVisible = filterFn(node); if (node.children) { // if one of node's children passes filter then this node is also visible node.children.forEach((child) => { if (this._filterNode(ids, child, filterFn, autoShow)) { isVisible = true; } }); } // mark node as hidden if (!isVisible) { ids[node.id] = true; } // auto expand parents to make sure the filtered nodes are visible if (autoShow && isVisible) { node.ensureVisible(); } return isVisible; } _calculateExpandedNodes(startNode = null) { startNode = startNode || this.virtualRoot; if (startNode.data[this.options.isExpandedField]) { this.expandedNodeIds = Object.assign({}, this.expandedNodeIds, { [startNode.id]: true }); } if (startNode.children) { startNode.children.forEach((child) => this._calculateExpandedNodes(child)); } } _setActiveNodeSingle(node, value) { // Deactivate all other nodes: this.activeNodes .filter((activeNode) => activeNode !== node) .forEach((activeNode) => { this.fireEvent({ eventName: TREE_EVENTS.deactivate, node: activeNode }); this.fireEvent({ eventName: TREE_EVENTS.nodeDeactivate, node: activeNode }); // For IE11 }); if (value) { this.activeNodeIds = { [node.id]: true }; } else { this.activeNodeIds = {}; } } _setActiveNodeMulti(node, value) { this.activeNodeIds = Object.assign({}, this.activeNodeIds, { [node.id]: value }); } /** @nocollapse */ static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeModel, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); /** @nocollapse */ static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeModel }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "16.1.2", ngImport: i0, type: TreeModel, decorators: [{ type: Injectable }], ctorParameters: function () { return []; } }); //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidHJlZS5tb2RlbC5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uL3Byb2plY3RzL2FuZ3VsYXItdHJlZS1jb21wb25lbnQvc3JjL2xpYi9tb2RlbHMvdHJlZS5tb2RlbC50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxPQUFPLEVBQUUsVUFBVSxFQUFhLE1BQU0sZUFBZSxDQUFDO0FBQ3RELE9BQU8sRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLE1BQU0sRUFBRSxPQUFPLEVBQUUsY0FBYyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBRTdFLE9BQU8sRUFBRSxRQUFRLEVBQUUsTUFBTSxtQkFBbUIsQ0FBQztBQUM3QyxPQUFPLEVBQUUsV0FBVyxFQUFFLE1BQU0sc0JBQXNCLENBQUM7QUFHbkQsT0FBTyxFQUFFLFdBQVcsRUFBRSxNQUFNLHFCQUFxQixDQUFDOztBQUdsRCxNQUFNLE9BQU8sU0FBUztJQUNwQixNQUFNLENBQUMsV0FBVyxHQUFHLElBQUksQ0FBQztJQUUxQixPQUFPLEdBQWdCLElBQUksV0FBVyxFQUFFLENBQUM7SUFDekMsS0FBSyxDQUFRO0lBQ2IsVUFBVSxHQUFHLE1BQU0sQ0FBQyxJQUFJLENBQUMsV0FBVyxDQUFDLENBQUM7SUFDdEMsYUFBYSxDQUFvQjtJQUVqQyxLQUFLLENBQWE7SUFDbEIsZUFBZSxHQUFxQixFQUFFLENBQUM7SUFDdkMsbUJBQW1CLEdBQXFCLEVBQUUsQ0FBQztJQUMzQyxhQUFhLEdBQXFCLEVBQUUsQ0FBQztJQUNyQyxhQUFhLEdBQXFCLEVBQUUsQ0FBQztJQUNyQyxhQUFhLEdBQVcsSUFBSSxDQUFDO0lBQzdCLFdBQVcsQ0FBVztJQUVkLFdBQVcsR0FBRyxJQUFJLENBQUM7SUFDbkIsTUFBTSxDQUFNO0lBQ1osYUFBYSxHQUFtQixFQUFFLENBQUM7SUFFM0M7UUFDRSxjQUFjLENBQUMsSUFBSSxFQUFFO1lBQ25CLEtBQUssRUFBRSxVQUFVO1lBQ2pCLGVBQWUsRUFBRSxVQUFV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QUksQ0FBQyxFQUFFLENBQUMsRUFBRSxLQUFLLEVBQUMsQ0FBQyxDQUFDO0lBQ2pGLENBQUM7MEhBN2lCVSxTQUFTOzhIQUFULFNBQVM7OzJGQUFULFNBQVM7a0JBRHJCLFVBQVUiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBJbmplY3RhYmxlLCBPbkRlc3Ryb3kgfSBmcm9tICdAYW5ndWxhci9jb3JlJztcclxuaW1wb3J0IHsgb2JzZXJ2YWJsZSwgY29tcHV0ZWQsIGFjdGlvbiwgYXV0b3J1biwgbWFrZU9ic2VydmFibGUgfSBmcm9tICdtb2J4JztcclxuaW1wb3J0IHsgU3Vic2NyaXB0aW9uIH0gZnJvbSAncnhqcyc7XHJcbmltcG9ydCB7IFRyZWVOb2RlIH0gZnJvbSAnLi90cmVlLW5vZGUubW9kZWwnO1xyXG5pbXBvcnQgeyBUcmVlT3B0aW9ucyB9IGZyb20gJy4vdHJlZS1vcHRpb25zLm1vZGVsJztcclxuaW1wb3J0IHsgVHJlZVZpcnR1YWxTY3JvbGwgfSBmcm9tICcuL3RyZWUtdmlydHVhbC1zY3JvbGwubW9kZWwnO1xyXG5pbXBvcnQgeyBJVHJlZU1vZGVsLCBJRFR5cGUsIElEVHlwZURpY3Rpb25hcnkgfSBmcm9tICcuLi9kZWZzL2FwaSc7XHJcbmltcG9ydCB7IFRSRUVfRVZFTlRTIH0gZnJvbSAnLi4vY29uc3RhbnRzL2V2ZW50cyc7XHJcblxyXG5ASW5qZWN0YWJsZSgpXHJcbmV4cG9ydCBjbGFzcyBUcmVlTW9kZWwgaW1wbGVtZW50cyBJVHJlZU1vZGVsLCBPbkRlc3Ryb3kge1xyXG4gIHN0YXRpYyBmb2N1c2VkVHJlZSA9IG51bGw7XHJcblxyXG4gIG9wdGlvbnM6IFRyZWVPcHRpb25zID0gbmV3IFRyZWVPcHRpb25zKCk7XHJcbiAgbm9kZXM6IGFueVtdO1xyXG4gIGV2ZW50TmFtZXMgPSBPYmplY3Qua2V5cyhUUkVFX0VWRU5UUyk7XHJcbiAgdmlydHVhbFNjcm9sbDogVHJlZVZpcnR1YWxTY3JvbGw7XHJcblxyXG4gIHJvb3RzOiBUcmVlTm9kZVtdO1xyXG4gIGV4cGFuZGVkTm9kZUlkczogSURUeXBlRGljdGlvbmFyeSA9IHt9O1xyXG4gIHNlbGVjdGVkTGVhZk5vZGVJZHM6IElEVHlwZURpY3Rpb25hcnkgPSB7fTtcclxuICBhY3RpdmVOb2RlSWRzOiBJRFR5cGVEaWN0aW9uYXJ5ID0ge307XHJcbiAgaGlkZGVuTm9kZUlkczogSURUeXBlRGljdGlvbmFyeSA9IHt9O1xyXG4gIGZvY3VzZWROb2RlSWQ6IElEVHlwZSA9IG51bGw7XHJcbiAgdmlydHVhbFJvb3Q6IFRyZWVOb2RlO1xyXG5cclxuICBwcml2YXRlIGZpcnN0VXBkYXRlID0gdHJ1ZTtcclxuICBwcml2YXRlIGV2ZW50czogYW55O1xyXG4gIHByaXZhdGUgc3Vic2NyaXB0aW9uczogU3Vic2NyaXB0aW9uW10gPSBbXTtcclxuXHJcbiAgY29uc3RydWN0b3IoKSB7XHJcbiAgICBtYWtlT2JzZXJ2YWJsZSh0aGlzLCB7XHJcbiAgICAgIHJvb3RzOiBvYnNlcnZhYmxlLFxyXG4gICAgICBleHBhbmRlZE5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIHNlbGVjdGVkTGVhZk5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIGFjdGl2ZU5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIGhpZGRlbk5vZGVJZHM6IG9ic2VydmFibGUsXHJcbiAgICAgIGZvY3VzZWROb2RlSWQ6IG9ic2VydmFibGUsXHJcbiAgICAgIHZpcnR1YWxSb290OiBvYnNlcnZhYmxlLFxyXG5cclxuICAgICAgZm9jdXNlZE5vZGU6IGNvbXB1dGVkLFxyXG4gICAgICBleHBhbmRlZE5vZGVzOiBjb21wdXRlZCxcclxuICAgICAgYWN0aXZlTm9kZXM6IGNvbXB1dGVkLFxyXG4gICAgICBoaWRkZW5Ob2RlczogY29tcHV0ZWQsXHJcbiAgICAgIHNlbGVjdGVkTGVhZk5vZGVzOiBjb21wdXRlZCxcclxuICAgICAgc2V0RGF0YTogYWN0aW9uLFxyXG4gICAgICB1cGRhdGU6IGFjdGlvbixcclxuICAgICAgc2V0Rm9jdXNlZE5vZGU6IGFjdGlvbixcclxuICAgICAgc2V0Rm9jdXM6IGFjdGlvbixcclxuICAgICAgZG9Gb3JBbGw6IGFjdGlvbixcclxuICAgICAgZm9jdXNOZXh0Tm9kZTogYWN0aW9uLFxyXG4gICAgICBmb2N1c1ByZXZpb3VzTm9kZTogYWN0aW9uLFxyXG4gICAgICBmb2N1c0RyaWxsRG93bjogYWN0aW9uLFxyXG4gICAgICBmb2N1c0RyaWxsVXA6IGFjdGlvbixcclxuICAgICAgc2V0QWN0aXZlTm9kZTogYWN0aW9uLFxyXG4gICAgICBzZXRTZWxlY3RlZE5vZGU6IGFjdGlvbixcclxuICAgICAgc2V0RXhwYW5kZWROb2RlOmFjdGlvbixcclxuICAgICAgZXhwYW5kQWxsOiBhY3Rpb24sXHJcbiAgICAgIGNvbGxhcHNlQWxsOmFjdGlvbixcclxuICAgICAgc2V0SXNIaWRkZW46YWN0aW9uLFxyXG4gICAgICBzZXRIaWRkZW5Ob2RlSWRzOmFjdGlvbixcclxuICAgICAgZmlsdGVyTm9kZXM6IGFjdGlvbixcclxuICAgICAgY2xlYXJGaWx0ZXI6IGFjdGlvbixcclxuICAgICAgbW92ZU5vZGU6IGFjdGlvbixcclxuICAgICAgY29weU5vZGU6IGFjdGlvbixcclxuICAgICAgc2V0U3RhdGU6IGFjdGlvbixcclxuICAgICAgXHJcbiAgICB9KTtcclxuICB9XHJcblxyXG4gIC8vIGV2ZW50c1xyXG4gIGZpcmVFdmVudChldmVudCkge1xyXG4gICAgZXZlbnQudHJlZU1vZGVsID0gdGhpcztcclxuICAgIHRoaXMuZXZlbnRzW2V2ZW50LmV2ZW50TmFtZV0uZW1pdChldmVudCk7XHJcbiAgICB0aGlzLmV2ZW50cy5ldmVudC5lbWl0KGV2ZW50KTtcclxuICB9XHJcblxyXG4gIHN1YnNjcmliZShldmVudE5hbWUsIGZuKSB7XHJcbiAgICBjb25zdCBzdWJzY3JpcHRpb24gPSB0aGlzLmV2ZW50c1tldmVudE5hbWVdLnN1YnNjcmliZShmbik7XHJcbiAgICB0aGlzLnN1YnNjcmlwdGlvbnMucHVzaChzdWJzY3JpcHRpb24pO1xyXG4gIH1cclxuXHJcblxyXG4gIC8vIGdldHRlcnNcclxuICBnZXRGb2N1c2VkTm9kZSgpOiBUcmVlTm9kZSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb2N1c2VkTm9kZTtcclxuICB9XHJcblxyXG5cclxuICBnZXRBY3RpdmVOb2RlKCk6IFRyZWVOb2RlIHtcclxuICAgIHJldHVybiB0aGlzLmFjdGl2ZU5vZGVzWzBdO1xyXG4gIH1cclxuXHJcbiAgZ2V0QWN0aXZlTm9kZXMoKTogVHJlZU5vZGVbXSB7XHJcbiAgICByZXR1cm4gdGhpcy5hY3RpdmVOb2RlcztcclxuICB9XHJcblxyXG4gIGdldFZpc2libGVSb290cygpIHtcclxuICAgIHJldHVybiB0aGlzLnZpcnR1YWxSb290LnZpc2libGVDaGlsZHJlbjtcclxuICB9XHJcblxyXG4gIGdldEZpcnN0Um9vdChza2lwSGlkZGVuID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IHJvb3QgPSBza2lwSGlkZGVuID8gdGhpcy5nZXRWaXNpYmxlUm9vdHMoKSA6IHRoaXMucm9vdHM7XHJcbiAgICByZXR1cm4gcm9vdCAhPSBudWxsICYmIHJvb3QubGVuZ3RoID8gcm9vdFswXSA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBnZXRMYXN0Um9vdChza2lwSGlkZGVuID0gZmFsc2UpIHtcclxuICAgIGNvbnN0IHJvb3QgPSBza2lwSGlkZGVuID8gdGhpcy5nZXRWaXNpYmxlUm9vdHMoKSA6IHRoaXMucm9vdHM7XHJcbiAgICByZXR1cm4gcm9vdCAhPSBudWxsICYmIHJvb3QubGVuZ3RoID8gcm9vdFtyb290Lmxlbmd0aCAtIDFdIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBpc0ZvY3VzZWQoKSB7XHJcbiAgICByZXR1cm4gVHJlZU1vZGVsLmZvY3VzZWRUcmVlID09PSB0aGlzO1xyXG4gIH1cclxuXHJcbiAgaXNOb2RlRm9jdXNlZChub2RlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb2N1c2VkTm9kZSA9PT0gbm9kZTtcclxuICB9XHJcblxyXG4gIGlzRW1wdHlUcmVlKCk6IGJvb2xlYW4ge1xyXG4gICAgcmV0dXJuIHRoaXMucm9vdHMgJiYgdGhpcy5yb290cy5sZW5ndGggPT09IDA7XHJcbiAgfVxyXG5cclxuICBnZXQgZm9jdXNlZE5vZGUoKSB7XHJcbiAgICByZXR1cm4gdGhpcy5mb2N1c2VkTm9kZUlkID8gdGhpcy5nZXROb2RlQnlJZCh0aGlzLmZvY3VzZWROb2RlSWQpIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGdldCBleHBhbmRlZE5vZGVzKCkge1xyXG4gICAgY29uc3Qgbm9kZXMgPSBPYmplY3Qua2V5cyh0aGlzLmV4cGFuZGVkTm9kZUlkcylcclxuICAgICAgLmZpbHRlcigoaWQpID0+IHRoaXMuZXhwYW5kZWROb2RlSWRzW2lkXSlcclxuICAgICAgLm1hcCgoaWQpID0+IHRoaXMuZ2V0Tm9kZUJ5SWQoaWQpKTtcclxuXHJcbiAgICByZXR1cm4gbm9kZXMuZmlsdGVyKEJvb2xlYW4pO1xyXG4gIH1cclxuXHJcbiAgZ2V0IGFjdGl2ZU5vZGVzKCkge1xyXG4gICAgY29uc3Qgbm9kZXMgPSBPYmplY3Qua2V5cyh0aGlzLmFjdGl2ZU5vZGVJZHMpXHJcbiAgICAgIC5maWx0ZXIoKGlkKSA9PiB0aGlzLmFjdGl2ZU5vZGVJZHNbaWRdKVxyXG4gICAgICAubWFwKChpZCkgPT4gdGhpcy5nZXROb2RlQnlJZChpZCkpO1xyXG5cclxuICAgIHJldHVybiBub2Rlcy5maWx0ZXIoQm9vbGVhbik7XHJcbiAgfVxyXG5cclxuICBnZXQgaGlkZGVuTm9kZXMoKSB7XHJcbiAgICBjb25zdCBub2RlcyA9IE9iamVjdC5rZXlzKHRoaXMuaGlkZGVuTm9kZUlkcylcclxuICAgICAgICAuZmlsdGVyKChpZCkgPT4gdGhpcy5oaWRkZW5Ob2RlSWRzW2lkXSlcclxuICAgICAgICAubWFwKChpZCkgPT4gdGhpcy5nZXROb2RlQnlJZChpZCkpO1xyXG5cclxuICAgIHJldHVybiBub2Rlcy5maWx0ZXIoQm9vbGVhbik7XHJcbiAgfVxyXG5cclxuICBnZXQgc2VsZWN0ZWRMZWFmTm9kZXMoKSB7XHJcbiAgICBjb25zdCBub2RlcyA9IE9iamVjdC5rZXlzKHRoaXMuc2VsZWN0ZWRMZWFmTm9kZUlkcylcclxuICAgICAgICAuZmlsdGVyKChpZCkgPT4gdGhpcy5zZWxlY3RlZExlYWZOb2RlSWRzW2lkXSlcclxuICAgICAgICAubWFwKChpZCkgPT4gdGhpcy5nZXROb2RlQnlJZChpZCkpO1xyXG5cclxuICAgIHJldHVybiBub2Rlcy5maWx0ZXIoQm9vbGVhbik7XHJcbiAgfVxyXG5cclxuICAvLyBsb2NhdGluZyBub2Rlc1xyXG4gIGdldE5vZGVCeVBhdGgocGF0aDogYW55W10sIHN0YXJ0Tm9kZT0gbnVsbCk6IFRyZWVOb2RlIHtcclxuICAgIGlmICghcGF0aCkgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgc3RhcnROb2RlID0gc3RhcnROb2RlIHx8IHRoaXMudmlydHVhbFJvb3Q7XHJcbiAgICBpZiAocGF0aC5sZW5ndGggPT09IDApIHJldHVybiBzdGFydE5vZGU7XHJcblxyXG4gICAgaWYgKCFzdGFydE5vZGUuY2hpbGRyZW4pIHJldHVybiBudWxsO1xyXG5cclxuICAgIGNvbnN0IGNoaWxkSWQgPSBwYXRoLnNoaWZ0KCk7XHJcbiAgICBjb25zdCBjaGlsZE5vZGUgPSBzdGFydE5vZGUuY2hpbGRyZW4uZmluZChjID0+IGMuaWQgPT09IGNoaWxkSWQpO1xyXG5cclxuICAgIGlmICghY2hpbGROb2RlKSByZXR1cm4gbnVsbDtcclxuXHJcbiAgICByZXR1cm4gdGhpcy5nZXROb2RlQnlQYXRoKHBhdGgsIGNoaWxkTm9kZSk7XHJcbiAgfVxyXG5cclxuICBnZXROb2RlQnlJZChpZCkge1xyXG4gICAgY29uc3QgaWRTdHIgPSBpZC50b1N0cmluZygpO1xyXG5cclxuICAgIHJldHVybiB0aGlzLmdldE5vZGVCeSgobm9kZSkgPT4gbm9kZS5pZC50b1N0cmluZygpID09PSBpZFN0cik7XHJcbiAgfVxyXG5cclxuICBnZXROb2RlQnkocHJlZGljYXRlLCBzdGFydE5vZGUgPSBudWxsKSB7XHJcbiAgICBzdGFydE5vZGUgPSBzdGFydE5vZGUgfHwgdGhpcy52aXJ0dWFsUm9vdDtcclxuXHJcbiAgICBpZiAoIXN0YXJ0Tm9kZS5jaGlsZHJlbikgcmV0dXJuIG51bGw7XHJcblxyXG4gICAgY29uc3QgZm91bmQgPSBzdGFydE5vZGUuY2hpbGRyZW4uZmluZChwcmVkaWNhdGUpO1xyXG5cclxuICAgIGlmIChmb3VuZCkgeyAvLyBmb3VuZCBpbiBjaGlsZHJlblxyXG4gICAgICByZXR1cm4gZm91bmQ7XHJcbiAgICB9IGVsc2UgeyAvLyBsb29rIGluIGNoaWxkcmVuJ3MgY2hpbGRyZW5cclxuICAgICAgZm9yIChsZXQgY2hpbGQgb2Ygc3RhcnROb2RlLmNoaWxkcmVuKSB7XHJcbiAgICAgICAgY29uc3QgZm91bmRJbkNoaWxkcmVuID0gdGhpcy5nZXROb2RlQnkocHJlZGljYXRlLCBjaGlsZCk7XHJcbiAgICAgICAgaWYgKGZvdW5kSW5DaGlsZHJlbikgcmV0dXJuIGZvdW5kSW5DaGlsZHJlbjtcclxuICAgICAgfVxyXG4gICAgfVxyXG4gIH1cclxuXHJcbiAgaXNFeHBhbmRlZChub2RlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5leHBhbmRlZE5vZGVJZHNbbm9kZS5pZF07XHJcbiAgfVxyXG5cclxuICBpc0hpZGRlbihub2RlKSB7XHJcbiAgICByZXR1cm4gdGhpcy5oaWRkZW5Ob2RlSWRzW25vZGUuaWRdO1xyXG4gIH1cclxuXHJcbiAgaXNBY3RpdmUobm9kZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuYWN0aXZlTm9kZUlkc1tub2RlLmlkXTtcclxuICB9XHJcblxyXG4gIGlzU2VsZWN0ZWQobm9kZSkge1xyXG4gICAgcmV0dXJuIHRoaXMuc2VsZWN0ZWRMZWFmTm9kZUlkc1tub2RlLmlkXTtcclxuICB9XHJcblxyXG4gIG5nT25EZXN0cm95KCkge1xyXG4gICAgdGhpcy5kaXNwb3NlKCk7XHJcbiAgICB0aGlzLnVuc3Vic2NyaWJlQWxsKCk7XHJcbiAgfVxyXG5cclxuICBkaXNwb3NlKCkge1xyXG4gICAgLy8gRGlzcG9zZSByZWFjdGlvbnMgb2YgdGhlIHJlcGxhY2VkIG5vZGVzXHJcbiAgICBpZiAodGhpcy52aXJ0dWFsUm9vdCkge1xyXG4gICAgICB0aGlzLnZpcnR1YWxSb290LmRpc3Bvc2UoKTtcclxuICAgIH1cclxuICB9XHJcblxyXG4gIHVuc3Vic2NyaWJlQWxsKCkge1xyXG4gICAgdGhpcy5zdWJzY3JpcHRpb25zLmZvckVhY2goc3Vic2NyaXB0aW9uID0+IHN1YnNjcmlwdGlvbi51bnN1YnNjcmliZSgpKTtcclxuICAgIHRoaXMuc3Vic2NyaXB0aW9ucyA9IFtdO1xyXG4gIH1cclxuXHJcbiAgLy8gYWN0aW9uc1xyXG4gIHNldERhdGEoeyBub2Rlcywgb3B0aW9ucyA9IG51bGwsIGV2ZW50cyA9IG51bGwgfToge25vZGVzOiBhbnksIG9wdGlvbnM6IGFueSwgZXZlbnRzOiBhbnl9KSB7XHJcbiAgICBpZiAob3B0aW9ucykge1xyXG4gICAgICB0aGlzLm9wdGlvbnMgPSBuZXcgVHJlZU9wdGlvbnMob3B0aW9ucyk7XHJcbiAgICB9XHJcbiAgICBpZiAoZXZlbnRzKSB7XHJcbiAgICAgIHRoaXMuZXZlbnRzID0gZXZlbnRzO1xyXG4gICAgfVxyXG4gICAgaWYgKG5vZGVzKSB7XHJcbiAgICAgIHRoaXMubm9kZXMgPSBub2RlcztcclxuICAgIH1cclxuXHJcbiAgICB0aGlzLnVwZGF0ZSgpO1xyXG4gIH1cclxuXHJcbiAgdXBkYXRlKCkge1xyXG4gICAgLy8gUmVidWlsZCB0cmVlOlxyXG4gICAgbGV0IHZpcnR1YWxSb290Q29uZmlnID0ge1xyXG4gICAgICBpZDogdGhpcy5vcHRpb25zLnJvb3RJZCxcclxuICAgICAgdmlydHVhbDogdHJ1ZSxcclxuICAgICAgW3RoaXMub3B0aW9ucy5jaGlsZHJlbkZpZWxkXTogdGhpcy5ub2Rlc1xyXG4gICAgfTtcclxuXHJcbiAgICB0aGlzLmRpc3Bvc2UoKTtcclxuXHJcbiAgICB0aGlzLnZpcnR1YWxSb290ID0gbmV3IFRyZWVOb2RlKHZpcnR1YWxSb290Q29uZmlnLCBudWxsLCB0aGlzLCAwKTtcclxuXHJcbiAgICB0aGlzLnJvb3RzID0gdGhpcy52aXJ0dWFsUm9vdC5jaGlsZHJlbjtcclxuXHJcbiAgICAvLyBGaXJlIGV2ZW50OlxyXG4gICAgaWYgKHRoaXMuZmlyc3RVcGRhdGUpIHtcclxuICAgICAgaWYgKHRoaXMucm9vdHMpIHtcclxuICAgICAgICB0aGlzLmZpcnN0VXBkYXRlID0gZmFsc2U7XHJcbiAgICAgICAgdGhpcy5fY2FsY3VsYXRlRXhwYW5kZWROb2RlcygpO1xyXG4gICAgICB9XHJcbiAgICB9IGVsc2Uge1xyXG4gICAgICB0aGlzLmZpcmVFdmVudCh7IGV2ZW50TmFtZTogVFJFRV9FVkVOVFMudXBkYXRlRGF0YSB9KTtcclxuICAgIH1cclxuICB9XHJcblxyXG5cclxuICBzZXRGb2N1c2VkTm9kZShub2RlKSB7XHJcbiAgICB0aGlzLmZvY3VzZWROb2RlSWQgPSBub2RlID8gbm9kZS5pZCA6IG51bGw7XHJcbiAgfVxyXG5cclxuICBzZXRGb2N1cyh2YWx1ZSkge1xyXG4gICAgVHJlZU1vZGVsLmZvY3VzZWRUcmVlID0gdmFsdWUgPyB0aGlzIDogbnVsbDtcclxuICB9XHJcblxyXG4gIGRvRm9yQWxsKGZuKSB7XHJcbiAgICB0aGlzLnJvb3RzLmZvckVhY2goKHJvb3QpID0+IHJvb3QuZG9Gb3JBbGwoZm4pKTtcclxuICB9XHJcblxyXG4gIGZvY3VzTmV4dE5vZGUoKSB7XHJcbiAgICBsZXQgcHJldmlvdXNOb2RlID0gdGhpcy5nZXRGb2N1c2VkTm9kZSgpO1xyXG4gICAgbGV0IG5leHROb2RlID0gcHJldmlvdXNOb2RlID8gcHJldmlvdXNOb2RlLmZpbmROZXh0Tm9kZSh0cnVlLCB0cnVlKSA6IHRoaXMuZ2V0Rmlyc3RSb290KHRydWUpO1xyXG4gICAgaWYgKG5leHROb2RlKSBuZXh0Tm9kZS5mb2N1cygpO1xyXG4gIH1cclxuXHJcbiAgZm9jdXNQcmV2aW91c05vZGUoKSB7XHJcbiAgICBsZXQgcHJldmlvdXNOb2RlID0gdGhpcy5nZXRGb2N1c2VkTm9kZSgpO1xyXG4gICAgbGV0IG5leHROb2RlID0gcHJldmlvdXNOb2RlID8gcHJldmlvdXNOb2RlLmZpbmRQcmV2aW91c05vZGUodHJ1ZSkgOiB0aGlzLmdldExhc3RSb290KHRydWUpO1xyXG4gICAgaWYgKG5leHROb2Rl