UNPKG

@swimlane/ngx-graph

Version:
220 lines 33.1 kB
import { id } from '../../utils/id'; import { d3adaptor } from 'webcola'; import * as d3Dispatch from 'd3-dispatch'; import * as d3Force from 'd3-force'; import * as d3Timer from 'd3-timer'; import { Subject } from 'rxjs'; export function toNode(nodes, nodeRef) { if (typeof nodeRef === 'number') { return nodes[nodeRef]; } return nodeRef; } export class ColaForceDirectedLayout { defaultSettings = { force: d3adaptor({ ...d3Dispatch, ...d3Force, ...d3Timer }) .linkDistance(150) .avoidOverlaps(true), viewDimensions: { width: 600, height: 600 } }; settings = {}; inputGraph; outputGraph; internalGraph; outputGraph$ = new Subject(); draggingStart; run(graph) { this.inputGraph = graph; if (!this.inputGraph.clusters) { this.inputGraph.clusters = []; } this.internalGraph = { nodes: [ ...this.inputGraph.nodes.map(n => ({ ...n, width: n.dimension ? n.dimension.width : 20, height: n.dimension ? n.dimension.height : 20 })) ], groups: [ ...this.inputGraph.clusters.map((cluster) => ({ padding: 5, groups: cluster.childNodeIds .map(nodeId => this.inputGraph.clusters.findIndex(node => node.id === nodeId)) .filter(x => x >= 0), leaves: cluster.childNodeIds .map(nodeId => this.inputGraph.nodes.findIndex(node => node.id === nodeId)) .filter(x => x >= 0) })) ], links: [ ...this.inputGraph.edges .map(e => { const sourceNodeIndex = this.inputGraph.nodes.findIndex(node => e.source === node.id); const targetNodeIndex = this.inputGraph.nodes.findIndex(node => e.target === node.id); if (sourceNodeIndex === -1 || targetNodeIndex === -1) { return undefined; } return { ...e, source: sourceNodeIndex, target: targetNodeIndex }; }) .filter(x => !!x) ], groupLinks: [ ...this.inputGraph.edges .map(e => { const sourceNodeIndex = this.inputGraph.nodes.findIndex(node => e.source === node.id); const targetNodeIndex = this.inputGraph.nodes.findIndex(node => e.target === node.id); if (sourceNodeIndex >= 0 && targetNodeIndex >= 0) { return undefined; } return e; }) .filter(x => !!x) ] }; this.outputGraph = { nodes: [], clusters: [], edges: [], edgeLabels: [] }; this.outputGraph$.next(this.outputGraph); this.settings = Object.assign({}, this.defaultSettings, this.settings); if (this.settings.force) { this.settings.force = this.settings.force .nodes(this.internalGraph.nodes) .groups(this.internalGraph.groups) .links(this.internalGraph.links) .alpha(0.5) .on('tick', () => { if (this.settings.onTickListener) { this.settings.onTickListener(this.internalGraph); } this.outputGraph$.next(this.internalGraphToOutputGraph(this.internalGraph)); }); if (this.settings.viewDimensions) { this.settings.force = this.settings.force.size([ this.settings.viewDimensions.width, this.settings.viewDimensions.height ]); } if (this.settings.forceModifierFn) { this.settings.force = this.settings.forceModifierFn(this.settings.force); } this.settings.force.start(); } return this.outputGraph$.asObservable(); } updateEdge(graph, edge) { const settings = Object.assign({}, this.defaultSettings, this.settings); if (settings.force) { settings.force.start(); } return this.outputGraph$.asObservable(); } internalGraphToOutputGraph(internalGraph) { this.outputGraph.nodes = internalGraph.nodes.map(node => ({ ...node, id: node.id || id(), position: { x: node.x, y: node.y }, dimension: { width: (node.dimension && node.dimension.width) || 20, height: (node.dimension && node.dimension.height) || 20 }, transform: `translate(${node.x - ((node.dimension && node.dimension.width) || 20) / 2 || 0}, ${node.y - ((node.dimension && node.dimension.height) || 20) / 2 || 0})` })); this.outputGraph.edges = internalGraph.links .map(edge => { const source = toNode(internalGraph.nodes, edge.source); const target = toNode(internalGraph.nodes, edge.target); return { ...edge, source: source.id, target: target.id, points: [ source.bounds.rayIntersection(target.bounds.cx(), target.bounds.cy()), target.bounds.rayIntersection(source.bounds.cx(), source.bounds.cy()) ] }; }) .concat(internalGraph.groupLinks.map(groupLink => { const sourceNode = internalGraph.nodes.find(foundNode => foundNode.id === groupLink.source); const targetNode = internalGraph.nodes.find(foundNode => foundNode.id === groupLink.target); const source = sourceNode || internalGraph.groups.find(foundGroup => foundGroup.id === groupLink.source); const target = targetNode || internalGraph.groups.find(foundGroup => foundGroup.id === groupLink.target); return { ...groupLink, source: source.id, target: target.id, points: [ source.bounds.rayIntersection(target.bounds.cx(), target.bounds.cy()), target.bounds.rayIntersection(source.bounds.cx(), source.bounds.cy()) ] }; })); this.outputGraph.clusters = internalGraph.groups.map((group, index) => { const inputGroup = this.inputGraph.clusters[index]; return { ...inputGroup, dimension: { width: group.bounds ? group.bounds.width() : 20, height: group.bounds ? group.bounds.height() : 20 }, position: { x: group.bounds ? group.bounds.x + group.bounds.width() / 2 : 0, y: group.bounds ? group.bounds.y + group.bounds.height() / 2 : 0 } }; }); this.outputGraph.edgeLabels = this.outputGraph.edges; return this.outputGraph; } onDragStart(draggingNode, $event) { const nodeIndex = this.outputGraph.nodes.findIndex(foundNode => foundNode.id === draggingNode.id); const node = this.internalGraph.nodes[nodeIndex]; if (!node) { return; } this.draggingStart = { x: node.x - $event.x, y: node.y - $event.y }; node.fixed = 1; this.settings.force.start(); } onDrag(draggingNode, $event) { if (!draggingNode) { return; } const nodeIndex = this.outputGraph.nodes.findIndex(foundNode => foundNode.id === draggingNode.id); const node = this.internalGraph.nodes[nodeIndex]; if (!node) { return; } node.x = this.draggingStart.x + $event.x; node.y = this.draggingStart.y + $event.y; } onDragEnd(draggingNode, $event) { if (!draggingNode) { return; } const nodeIndex = this.outputGraph.nodes.findIndex(foundNode => foundNode.id === draggingNode.id); const node = this.internalGraph.nodes[nodeIndex]; if (!node) { return; } node.fixed = 0; } } //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29sYUZvcmNlRGlyZWN0ZWQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi8uLi8uLi8uLi9wcm9qZWN0cy9zd2ltbGFuZS9uZ3gtZ3JhcGgvc3JjL2xpYi9ncmFwaC9sYXlvdXRzL2NvbGFGb3JjZURpcmVjdGVkLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUdBLE9BQU8sRUFBRSxFQUFFLEVBQUUsTUFBTSxnQkFBZ0IsQ0FBQztBQUNwQyxPQUFPLEVBQUUsU0FBUyxFQUFrRixNQUFNLFNBQVMsQ0FBQztBQUNwSCxPQUFPLEtBQUssVUFBVSxNQUFNLGFBQWEsQ0FBQztBQUMxQyxPQUFPLEtBQUssT0FBTyxNQUFNLFVBQVUsQ0FBQztBQUNwQyxPQUFPLEtBQUssT0FBTyxNQUFNLFVBQVUsQ0FBQztBQUVwQyxPQUFPLEVBQWMsT0FBTyxFQUFFLE1BQU0sTUFBTSxDQUFDO0FBYzNDLE1BQU0sVUFBVSxNQUFNLENBQUMsS0FBa0IsRUFBRSxPQUEyQjtJQUNwRSxJQUFJLE9BQU8sT0FBTyxLQUFLLFFBQVEsRUFBRSxDQUFDO1FBQ2hDLE9BQU8sS0FBSyxDQUFDLE9BQU8sQ0FBQyxDQUFDO0lBQ3hCLENBQUM7SUFDRCxPQUFPLE9BQU8sQ0FBQztBQUNqQixDQUFDO0FBRUQsTUFBTSxPQUFPLHVCQUF1QjtJQUNsQyxlQUFlLEdBQThCO1FBQzNDLEtBQUssRUFBRSxTQUFTLENBQUM7WUFDZixHQUFHLFVBQVU7WUFDYixHQUFHLE9BQU87WUFDVixHQUFHLE9BQU87U0FDWCxDQUFDO2FBQ0MsWUFBWSxDQUFDLEdBQUcsQ0FBQzthQUNqQixhQUFhLENBQUMsSUFBSSxDQUFDO1FBQ3RCLGNBQWMsRUFBRTtZQUNkLEtBQUssRUFBRSxHQUFHO1lBQ1YsTUFBTSxFQUFFLEdBQUc7U0FDWjtLQUNGLENBQUM7SUFDRixRQUFRLEdBQThCLEVBQUUsQ0FBQztJQUV6QyxVQUFVLENBQVE7SUFDbEIsV0FBVyxDQUFRO0lBQ25CLGFBQWEsQ0FBc0M7SUFD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LFlBQVksQ0FBQyxFQUFFLENBQUMsQ0FBQztRQUNsRyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsYUFBYSxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztRQUNqRCxJQUFJLENBQUMsSUFBSSxFQUFFLENBQUM7WUFDVixPQUFPO1FBQ1QsQ0FBQztRQUVELElBQUksQ0FBQyxLQUFLLEdBQUcsQ0FBQyxDQUFDO0lBQ2pCLENBQUM7Q0FDRiIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IExheW91dCB9IGZyb20gJy4uLy4uL21vZGVscy9sYXlvdXQubW9kZWwnO1xuaW1wb3J0IHsgR3JhcGggfSBmcm9tICcuLi8uLi9tb2RlbHMvZ3JhcGgubW9kZWwnO1xuaW1wb3J0IHsgTm9kZSwgQ2x1c3Rlck5vZGUgfSBmcm9tICcuLi8uLi9tb2RlbHMvbm9kZS5tb2RlbCc7XG5pbXBvcnQgeyBpZCB9IGZyb20gJy4uLy4uL3V0aWxzL2lkJztcbmltcG9ydCB7IGQzYWRhcHRvciwgSUQzU3R5bGVMYXlvdXRBZGFwdG9yLCBMYXlvdXQgYXMgQ29sYUxheW91dCwgR3JvdXAsIElucHV0Tm9kZSwgTGluaywgUmVjdGFuZ2xlIH0gZnJvbSAnd2ViY29sYSc7XG5pbXBvcnQgKiBhcyBkM0Rpc3BhdGNoIGZyb20gJ2QzLWRpc3BhdGNoJztcbmltcG9ydCAqIGFzIGQzRm9yY2UgZnJvbSAnZDMtZm9yY2UnO1xuaW1wb3J0ICogYXMgZDNUaW1lciBmcm9tICdkMy10aW1lcic7XG5pbXBvcnQgeyBFZGdlIH0gZnJvbSAnLi4vLi4vbW9kZWxzL2VkZ2UubW9kZWwnO1xuaW1wb3J0IHsgT2JzZXJ2YWJsZSwgU3ViamVjdCB9IGZyb20gJ3J4anMnO1xuaW1wb3J0IHsgVmlld0RpbWVuc2lvbnMgfSBmcm9tICcuLi8uLi91dGlscy92aWV3LWRpbWVuc2lvbnMuaGVscGVyJztcblxuZXhwb3J0IGludGVyZmFjZSBDb2xhRm9yY2VEaXJlY3RlZFNldHRpbmdzIHtcbiAgZm9yY2U/OiBDb2xhTGF5b3V0ICYgSUQzU3R5bGVMYXlvdXRBZGFwdG9yO1xuICBmb3JjZU1vZGlmaWVyRm4/OiAoZm9yY2U6IENvbGFMYXlvdXQgJiBJRDNTdHlsZUxheW91dEFkYXB0b3IpID0+IENvbGFMYXlvdXQgJiBJRDNTdHlsZUxheW91dEFkYXB0b3I7XG4gIG9uVGlja0xpc3RlbmVyPzogKGludGVybmFsR3JhcGg6IENvbGFHcmFwaCkgPT4gdm9pZDtcbiAgdmlld0RpbWVuc2lvbnM/OiBWaWV3RGltZW5zaW9ucztcbn1cbmV4cG9ydCBpbnRlcmZhY2UgQ29sYUdyYXBoIHtcbiAgZ3JvdXBzOiBHcm91cFtdO1xuICBub2RlczogSW5wdXROb2RlW107XG4gIGxpbmtzOiBBcnJheTxMaW5rPG51bWJlcj4+O1xufVxuZXhwb3J0IGZ1bmN0aW9uIHRvTm9kZShub2RlczogSW5wdXROb2RlW10sIG5vZGVSZWY6IElucHV0Tm9kZSB8IG51bWJlcik6IElucHV0Tm9kZSB7XG4gIGlmICh0eXBlb2Ygbm9kZVJlZiA9PT0gJ251bWJlcicpIHtcbiAgICByZXR1cm4gbm9kZXNbbm9kZVJlZl07XG4gIH1cbiAgcmV0dXJuIG5vZGVSZWY7XG59XG5cbmV4cG9ydCBjbGFzcyBDb2xhRm9yY2VEaXJlY3RlZExheW91dCBpbXBsZW1lbnRzIExheW91dCB7XG4gIGRlZmF1bHRTZXR0aW5nczogQ29sYUZvcmNlRGlyZWN0ZWRTZXR0aW5ncyA9IHtcbiAgICBmb3JjZTogZDNhZGFwdG9yKHtcbiAgICAgIC4uLmQzRGlzcGF0Y2gsXG4gICAgICAuLi5kM0ZvcmNlLFxuICAgICAgLi4uZDNUaW1lclxuICAgIH0pXG4gICAgICAubGlua0Rpc3RhbmNlKDE1MClcbiAgICAgIC5hdm9pZE92ZXJsYXBzKHRydWUpLFxuICAgIHZpZXdEaW1lbnNpb25zOiB7XG4gICAgICB3aWR0aDogNjAwLFxuICAgICAgaGVpZ2h0OiA2MDBcbiAgICB9XG4gIH07XG4gIHNldHRpbmdzOiBDb2xhRm9yY2VEaXJlY3RlZFNldHRpbmdzID0ge307XG5cbiAgaW5wdXRHcmFwaDogR3JhcGg7XG4gIG91dHB1dEdyYXBoOiBHcmFwaDtcbiAgaW50ZXJuYWxHcmFwaDogQ29sYUdyYXBoICYgeyBncm91cExpbmtzPzogRWRnZVtdIH07XG4gIG91dHB1dEdyYXBoJDogU3ViamVjdDxHcmFwaD4gPSBuZXcgU3ViamVjdCgpO1xuXG4gIGRyYWdnaW5nU3RhcnQ6IHsgeDogbnVtYmVyOyB5OiBudW1iZXIgfTtcblxuICBydW4oZ3JhcGg6IEdyYXBoKTogT2JzZXJ2YWJsZTxHcmFwaD4ge1xuICAgIHRoaXMuaW5wdXRHcmFwaCA9IGdyYXBoO1xuICAgIGlmICghdGhpcy5pbnB1dEdyYXBoLmNsdXN0ZXJzKSB7XG4gICAgICB0aGlzLmlucHV0R3JhcGguY2x1c3RlcnMgPSBbXTtcbiAgICB9XG4gICAgdGhpcy5pbnRlcm5hbEdyYXBoID0ge1xuICAgICAgbm9kZXM6IFtcbiAgICAgICAgLi4udGhpcy5pbnB1dEdyYXBoLm5vZGVzLm1hcChuID0+ICh7XG4gICAgICAgICAgLi4ubixcbiAgICAgICAgICB3aWR0aDogbi5kaW1lbnNpb24gPyBuLmRpbWVuc2lvbi53aWR0aCA6IDIwLFxuICAgICAgICAgIGhlaWdodDogbi5kaW1lbnNpb24gPyBuLmRpbWVuc2lvbi5oZWlnaHQgOiAyMFxuICAgICAgICB9KSlcbiAgICAgIF0gYXMgYW55LFxuICAgICAgZ3JvdXBzOiBbXG4gICAgICAgIC4uLnRoaXMuaW5wdXRHcmFwaC5jbHVzdGVycy5tYXAoXG4gICAgICAgICAgKGNsdXN0ZXIpOiBHcm91cCA9PiAoe1xuICAgICAgICAgICAgcGFkZGluZzogNSxcbiAgICAgICAgICAgIGdyb3VwczogY2x1c3Rlci5jaGlsZE5vZGVJZHNcbiAgICAgICAgICAgICAgLm1hcChub2RlSWQgPT4gPGFueT50aGlzLmlucHV0R3JhcGguY2x1c3RlcnMuZmluZEluZGV4KG5vZGUgPT4gbm9kZS5pZCA9PT0gbm9kZUlkKSlcbiAgICAgICAgICAgICAgLmZpbHRlcih4ID0+IHggPj0gMCksXG4gICAgICAgICAgICBsZWF2ZXM6IGNsdXN0ZXIuY2hpbGROb2RlSWRzXG4gICAgICAgICAgICAgIC5tYXAobm9kZUlkID0+IDxhbnk+dGhpcy5pbnB1dEdyYXBoLm5vZGVzLmZpbmRJbmRleChub2RlID0+IG5vZGUuaWQgPT09IG5vZGVJZCkpXG4gICAgICAgICAgICAgIC5maWx0ZXIoeCA9PiB4ID49IDApXG4gICAgICAgICAgfSlcbiAgICAgICAgKVxuICAgICAgXSxcbiAgICAgIGxpbmtzOiBbXG4gICAgICAgIC4uLnRoaXMuaW5wdXRHcmFwaC5lZGdlc1xuICAgICAgICAgIC5tYXAoZSA9PiB7XG4gICAgICAgICAgICBjb25zdCBzb3VyY2VOb2RlSW5kZXggPSB0aGlzLmlucHV0R3JhcGgubm9kZXMuZmluZEluZGV4KG5vZGUgPT4gZS5zb3VyY2UgPT09IG5vZGUuaWQpO1xuICAgICAgICAgICAgY29uc3QgdGFyZ2V0Tm9kZUluZGV4ID0gdGhpcy5pbnB1dEdyYXBoLm5vZGVzLmZpbmRJbmRleChub2RlID0+IGUudGFyZ2V0ID09PSBub2RlLmlkKTtcbiAgICAgICAgICAgIGlmIChzb3VyY2VOb2RlSW5kZXggPT09IC0xIHx8IHRhcmdldE5vZGVJbmRleCA9PT0gLTEpIHtcbiAgICAgICAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgICAgICAgIH1cbiAgICAgICAgICAgIHJldHVybiB7XG4gICAgICAgICAgICAgIC4uLmUsXG4gICAgICAgICAgICAgIHNvdXJjZTogc291cmNlTm9kZUluZGV4LFxuICAgICAgICAgICAgICB0YXJnZXQ6IHRhcmdldE5vZGVJbmRleFxuICAgICAgICAgICAgfTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoeCA9PiAhIXgpXG4gICAgICBdIGFzIGFueSxcbiAgICAgIGdyb3VwTGlua3M6IFtcbiAgICAgICAgLi4udGhpcy5pbnB1dEdyYXBoLmVkZ2VzXG4gICAgICAgICAgLm1hcChlID0+IHtcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZU5vZGVJbmRleCA9IHRoaXMuaW5wdXRHcmFwaC5ub2Rlcy5maW5kSW5kZXgobm9kZSA9PiBlLnNvdXJjZSA9PT0gbm9kZS5pZCk7XG4gICAgICAgICAgICBjb25zdCB0YXJnZXROb2RlSW5kZXggPSB0aGlzLmlucHV0R3JhcGgubm9kZXMuZmluZEluZGV4KG5vZGUgPT4gZS50YXJnZXQgPT09IG5vZGUuaWQpO1xuICAgICAgICAgICAgaWYgKHNvdXJjZU5vZGVJbmRleCA+PSAwICYmIHRhcmdldE5vZGVJbmRleCA+PSAwKSB7XG4gICAgICAgICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICByZXR1cm4gZTtcbiAgICAgICAgICB9KVxuICAgICAgICAgIC5maWx0ZXIoeCA9PiAhIXgpXG4gICAgICBdXG4gICAgfTtcbiAgICB0aGlzLm91dHB1dEdyYXBoID0ge1xuICAgICAgbm9kZXM6IFtdLFxuICAgICAgY2x1c3RlcnM6IFtdLFxuICAgICAgZWRnZXM6IFtdLFxuICAgICAgZWRnZUxhYmVsczogW11cbiAgICB9O1xuICAgIHRoaXMub3V0cHV0R3JhcGgkLm5leHQodGhpcy5vdXRwdXRHcmFwaCk7XG4gICAgdGhpcy5zZXR0aW5ncyA9IE9iamVjdC5hc3NpZ24oe30sIHRoaXMuZGVmYXVsdFNldHRpbmdzLCB0aGlzLnNldHRpbmdzKTtcbiAgICBpZiAodGhpcy5zZXR0aW5ncy5mb3JjZSkge1xuICAgICAgdGhpcy5zZXR0aW5ncy5mb3JjZSA9IHRoaXMuc2V0dGluZ3MuZm9yY2VcbiAgICAgICAgLm5vZGVzKHRoaXMuaW50ZXJuYWxHcmFwaC5ub2RlcylcbiAgICAgICAgLmdyb3Vwcyh0aGlzLmludGVybmFsR3JhcGguZ3JvdXBzKVxuICAgICAgICAubGlua3ModGhpcy5pbnRlcm5hbEdyYXBoLmxpbmtzKVxuICAgICAgICAuYWxwaGEoMC41KVxuICAgICAgICAub24oJ3RpY2snLCAoKSA9PiB7XG4gICAgICAgICAgaWYgKHRoaXMuc2V0dGluZ3Mub25UaWNrTGlzdGVuZXIpIHtcbiAgICAgICAgICAgIHRoaXMuc2V0dGluZ3Mub25UaWNrTGlzdGVuZXIodGhpcy5pbnRlcm5hbEdyYXBoKTtcbiAgICAgICAgICB9XG4gICAgICAgICAgdGhpcy5vdXRwdXRHcmFwaCQubmV4dCh0aGlzLmludGVybmFsR3JhcGhUb091dHB1dEdyYXBoKHRoaXMuaW50ZXJuYWxHcmFwaCkpO1xuICAgICAgICB9KTtcbiAgICAgIGlmICh0aGlzLnNldHRpbmdzLnZpZXdEaW1lbnNpb25zKSB7XG4gICAgICAgIHRoaXMuc2V0dGluZ3MuZm9yY2UgPSB0aGlzLnNldHRpbmdzLmZvcmNlLnNpemUoW1xuICAgICAgICAgIHRoaXMuc2V0dGluZ3Mudmlld0RpbWVuc2lvbnMud2lkdGgsXG4gICAgICAgICAgdGhpcy5zZXR0aW5ncy52aWV3RGltZW5zaW9ucy5oZWlnaHRcbiAgICAgICAgXSk7XG4gICAgICB9XG4gICAgICBpZiAodGhpcy5zZXR0aW5ncy5mb3JjZU1vZGlmaWVyRm4pIHtcbiAgICAgICAgdGhpcy5zZXR0aW5ncy5mb3JjZSA9IHRoaXMuc2V0dGluZ3MuZm9yY2VNb2RpZmllckZuKHRoaXMuc2V0dGluZ3MuZm9yY2UpO1xuICAgICAgfVxuICAgICAgdGhpcy5zZXR0aW5ncy5mb3JjZS5zdGFydCgpO1xuICAgIH1cblxuICAgIHJldHVybiB0aGlzLm91dHB1dEdyYXBoJC5hc09ic2VydmFibGUoKTtcbiAgfVxuXG4gIHVwZGF0ZUVkZ2UoZ3JhcGg6IEdyYXBoLCBlZGdlOiBFZGdlKTogT2JzZXJ2YWJsZTxHcmFwaD4ge1xuICAgIGNvbnN0IHNldHRpbmdzID0gT2JqZWN0LmFzc2lnbih7fSwgdGhpcy5kZWZhdWx0U2V0dGluZ3MsIHRoaXMuc2V0dGluZ3MpO1xuICAgIGlmIChzZXR0aW5ncy5mb3JjZSkge1xuICAgICAgc2V0dGluZ3MuZm9yY2Uuc3RhcnQoKTtcbiAgICB9XG5cbiAgICByZXR1cm4gdGhpcy5vdXRwdXRHcmFwaCQuYXNPYnNlcnZhYmxlKCk7XG4gIH1cblxuICBpbnRlcm5hbEdyYXBoVG9PdXRwdXRHcmFwaChpbnRlcm5hbEdyYXBoOiBhbnkpOiBHcmFwaCB7XG4gICAgdGhpcy5vdXRwdXRHcmFwaC5ub2RlcyA9IGludGVybmFsR3JhcGgubm9kZXMubWFwKG5vZGUgPT4gKHtcbiAgICAgIC4uLm5vZGUsXG4gICAgICBpZDogbm9kZS5pZCB8fCBpZCgpLFxuICAgICAgcG9zaXRpb246IHtcbiAgICAgICAgeDogbm9kZS54LFxuICAgICAgICB5OiBub2RlLnlcbiAgICAgIH0sXG4gICAgICBkaW1lbnNpb246IHtcbiAgICAgICAgd2lkdGg6IChub2RlLmRpbWVuc2lvbiAmJiBub2RlLmRpbWVuc2lvbi53aWR0aCkgfHwgMjAsXG4gICAgICAgIGhlaWdodDogKG5vZGUuZGltZW5zaW9uICYmIG5vZGUuZGltZW5zaW9uLmhlaWdodCkgfHwgMjBcbiAgICAgIH0sXG4gICAgICB0cmFuc2Zvcm06IGB0cmFuc2xhdGUoJHtub2RlLnggLSAoKG5vZGUuZGltZW5zaW9uICYmIG5vZGUuZGltZW5zaW9uLndpZHRoKSB8fCAyMCkgLyAyIHx8IDB9LCAke1xuICAgICAgICBub2RlLnkgLSAoKG5vZGUuZGltZW5zaW9uICYmIG5vZGUuZGltZW5zaW9uLmhlaWdodCkgfHwgMjApIC8gMiB8fCAwXG4gICAgICB9KWBcbiAgICB9KSk7XG5cbiAgICB0aGlzLm91dHB1dEdyYXBoLmVkZ2VzID0gaW50ZXJuYWxHcmFwaC5saW5rc1xuICAgICAgLm1hcChlZGdlID0+IHtcbiAgICAgICAgY29uc3Qgc291cmNlOiBhbnkgPSB0b05vZGUoaW50ZXJuYWxHcmFwaC5ub2RlcywgZWRnZS5zb3VyY2UpO1xuICAgICAgICBjb25zdCB0YXJnZXQ6IGFueSA9IHRvTm9kZShpbnRlcm5hbEdyYXBoLm5vZGVzLCBlZGdlLnRhcmdldCk7XG4gICAgICAgIHJldHVybiB7XG4gICAgICAgICAgLi4uZWRnZSxcbiAgICAgICAgICBzb3VyY2U6IHNvdXJjZS5pZCxcbiAgICAgICAgICB0YXJnZXQ6IHRhcmdldC5pZCxcbiAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgIChzb3VyY2UuYm91bmRzIGFzIFJlY3RhbmdsZSkucmF5SW50ZXJzZWN0aW9uKHRhcmdldC5ib3VuZHMuY3goKSwgdGFyZ2V0LmJvdW5kcy5jeSgpKSxcbiAgICAgICAgICAgICh0YXJnZXQuYm91bmRzIGFzIFJlY3RhbmdsZSkucmF5SW50ZXJzZWN0aW9uKHNvdXJjZS5ib3VuZHMuY3goKSwgc291cmNlLmJvdW5kcy5jeSgpKVxuICAgICAgICAgIF1cbiAgICAgICAgfTtcbiAgICAgIH0pXG4gICAgICAuY29uY2F0KFxuICAgICAgICBpbnRlcm5hbEdyYXBoLmdyb3VwTGlua3MubWFwKGdyb3VwTGluayA9PiB7XG4gICAgICAgICAgY29uc3Qgc291cmNlTm9kZSA9IGludGVybmFsR3JhcGgubm9kZXMuZmluZChmb3VuZE5vZGUgPT4gKGZvdW5kTm9kZSBhcyBhbnkpLmlkID09PSBncm91cExpbmsuc291cmNlKTtcbiAgICAgICAgICBjb25zdCB0YXJnZXROb2RlID0gaW50ZXJuYWxHcmFwaC5ub2Rlcy5maW5kKGZvdW5kTm9kZSA9PiAoZm91bmROb2RlIGFzIGFueSkuaWQgPT09IGdyb3VwTGluay50YXJnZXQpO1xuICAgICAgICAgIGNvbnN0IHNvdXJjZSA9XG4gICAgICAgICAgICBzb3VyY2VOb2RlIHx8IGludGVybmFsR3JhcGguZ3JvdXBzLmZpbmQoZm91bmRHcm91cCA9PiAoZm91bmRHcm91cCBhcyBhbnkpLmlkID09PSBncm91cExpbmsuc291cmNlKTtcbiAgICAgICAgICBjb25zdCB0YXJnZXQgPVxuICAgICAgICAgICAgdGFyZ2V0Tm9kZSB8fCBpbnRlcm5hbEdyYXBoLmdyb3Vwcy5maW5kKGZvdW5kR3JvdXAgPT4gKGZvdW5kR3JvdXAgYXMgYW55KS5pZCA9PT0gZ3JvdXBMaW5rLnRhcmdldCk7XG4gICAgICAgICAgcmV0dXJuIHtcbiAgICAgICAgICAgIC4uLmdyb3VwTGluayxcbiAgICAgICAgICAgIHNvdXJjZTogc291cmNlLmlkLFxuICAgICAgICAgICAgdGFyZ2V0OiB0YXJnZXQuaWQsXG4gICAgICAgICAgICBwb2ludHM6IFtcbiAgICAgICAgICAgICAgKHNvdXJjZS5ib3VuZHMgYXMgUmVjdGFuZ2xlKS5yYXlJbnRlcnNlY3Rpb24odGFyZ2V0LmJvdW5kcy5jeCgpLCB0YXJnZXQuYm91bmRzLmN5KCkpLFxuICAgICAgICAgICAgICAodGFyZ2V0LmJvdW5kcyBhcyBSZWN0YW5nbGUpLnJheUludGVyc2VjdGlvbihzb3VyY2UuYm91bmRzLmN4KCksIHNvdXJjZS5ib3VuZHMuY3koKSlcbiAgICAgICAgICAgIF1cbiAgICAgICAgICB9O1xuICAgICAgICB9KVxuICAgICAgKTtcblxuICAgIHRoaXMub3V0cHV0R3JhcGguY2x1c3RlcnMgPSBpbnRlcm5hbEdyYXBoLmdyb3Vwcy5tYXAoKGdyb3VwLCBpbmRleCk6IENsdXN0ZXJOb2RlID0+IHtcbiAgICAgIGNvbnN0IGlucHV0R3JvdXAgPSB0aGlzLmlucHV0R3JhcGguY2x1c3RlcnNbaW5kZXhdO1xuICAgICAgcmV0dXJuIHtcbiAgICAgICAgLi4uaW5wdXRHcm91cCxcbiAgICAgICAgZGltZW5zaW9uOiB7XG4gICAgICAgICAgd2lkdGg6IGdyb3VwLmJvdW5kcyA/IGdyb3VwLmJvdW5kcy53aWR0aCgpIDogMjAsXG4gICAgICAgICAgaGVpZ2h0OiBncm91cC5ib3VuZHMgPyBncm91cC5ib3VuZHMuaGVpZ2h0KCkgOiAyMFxuICAgICAgICB9LFxuICAgICAgICBwb3NpdGlvbjoge1xuICAgICAgICAgIHg6IGdyb3VwLmJvdW5kcyA/IGdyb3VwLmJvdW5kcy54ICsgZ3JvdXAuYm91bmRzLndpZHRoKCkgLyAyIDogMCxcbiAgICAgICAgICB5OiBncm91cC5ib3VuZHMgPyBncm91cC5ib3VuZHMueSArIGdyb3VwLmJvdW5kcy5oZWlnaHQoKSAvIDIgOiAwXG4gICAgICAgIH1cbiAgICAgIH07XG4gICAgfSk7XG4gICAgdGhpcy5vdXRwdXRHcmFwaC5lZGdlTGFiZWxzID0gdGhpcy5vdXRwdXRHcmFwaC5lZGdlcztcbiAgICByZXR1cm4gdGhpcy5vdXRwdXRHcmFwaDtcbiAgfVxuXG4gIG9uRHJhZ1N0YXJ0KGRyYWdnaW5nTm9kZTogTm9kZSwgJGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgY29uc3Qgbm9kZUluZGV4ID0gdGhpcy5vdXRwdXRHcmFwaC5ub2Rlcy5maW5kSW5kZXgoZm91bmROb2RlID0+IGZvdW5kTm9kZS5pZCA9PT0gZHJhZ2dpbmdOb2RlLmlkKTtcbiAgICBjb25zdCBub2RlID0gdGhpcy5pbnRlcm5hbEdyYXBoLm5vZGVzW25vZGVJbmRleF07XG4gICAgaWYgKCFub2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIHRoaXMuZHJhZ2dpbmdTdGFydCA9IHsgeDogbm9kZS54IC0gJGV2ZW50LngsIHk6IG5vZGUueSAtICRldmVudC55IH07XG4gICAgbm9kZS5maXhlZCA9IDE7XG4gICAgdGhpcy5zZXR0aW5ncy5mb3JjZS5zdGFydCgpO1xuICB9XG5cbiAgb25EcmFnKGRyYWdnaW5nTm9kZTogTm9kZSwgJGV2ZW50OiBNb3VzZUV2ZW50KTogdm9pZCB7XG4gICAgaWYgKCFkcmFnZ2luZ05vZGUpIHtcbiAgICAgIHJldHVybjtcbiAgICB9XG4gICAgY29uc3Qgbm9kZUluZGV4ID0gdGhpcy5vdXRwdXRHcmFwaC5ub2Rlcy5maW5kSW5kZXgoZm91bmROb2RlID0+IGZvdW5kTm9kZS5pZCA9PT0gZHJhZ2dpbmdOb2RlLmlkKTtcbiAgICBjb25zdCBub2RlID0gdGhpcy5pbnRlcm5hbEdyYXBoLm5vZGVzW25vZGVJbmRleF07XG4gICAgaWYgKCFub2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIG5vZGUueCA9IHRoaXMuZHJhZ2dpbmdTdGFydC54ICsgJGV2ZW50Lng7XG4gICAgbm9kZS55ID0gdGhpcy5kcmFnZ2luZ1N0YXJ0LnkgKyAkZXZlbnQueTtcbiAgfVxuXG4gIG9uRHJhZ0VuZChkcmFnZ2luZ05vZGU6IE5vZGUsICRldmVudDogTW91c2VFdmVudCk6IHZvaWQge1xuICAgIGlmICghZHJhZ2dpbmdOb2RlKSB7XG4gICAgICByZXR1cm47XG4gICAgfVxuICAgIGNvbnN0IG5vZGVJbmRleCA9IHRoaXMub3V0cHV0R3JhcGgubm9kZXMuZmluZEluZGV4KGZvdW5kTm9kZSA9PiBmb3VuZE5vZGUuaWQgPT09IGRyYWdnaW5nTm9kZS5pZCk7XG4gICAgY29uc3Qgbm9kZSA9IHRoaXMuaW50ZXJuYWxHcmFwaC5ub2Rlc1tub2RlSW5kZXhdO1xuICAgIGlmICghbm9kZSkge1xuICAgICAgcmV0dXJuO1xuICAgIH1cblxuICAgIG5vZGUuZml4ZWQgPSAwO1xuICB9XG59XG4iXX0=