"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); var PowerEdge = (function () { function PowerEdge(source, target, type) { this.source = source; this.target = target; this.type = type; } return PowerEdge; }()); exports.PowerEdge = PowerEdge; var Configuration = (function () { function Configuration(n, edges, linkAccessor, rootGroup) { var _this = this; this.linkAccessor = linkAccessor; this.modules = new Array(n); this.roots = []; if (rootGroup) { this.initModulesFromGroup(rootGroup); } else { this.roots.push(new ModuleSet()); for (var i = 0; i < n; ++i) this.roots[0].add(this.modules[i] = new Module(i)); } this.R = edges.length; edges.forEach(function (e) { var s = _this.modules[linkAccessor.getSourceIndex(e)], t = _this.modules[linkAccessor.getTargetIndex(e)], type = linkAccessor.getType(e); s.outgoing.add(type, t); t.incoming.add(type, s); }); } Configuration.prototype.initModulesFromGroup = function (group) { var moduleSet = new ModuleSet(); this.roots.push(moduleSet); for (var i = 0; i < group.leaves.length; ++i) { var node = group.leaves[i]; var module = new Module(node.id); this.modules[node.id] = module; moduleSet.add(module); } if (group.groups) { for (var j = 0; j < group.groups.length; ++j) { var child = group.groups[j]; var definition = {}; for (var prop in child) if (prop !== "leaves" && prop !== "groups" && child.hasOwnProperty(prop)) definition[prop] = child[prop]; moduleSet.add(new Module(-1 - j, new LinkSets(), new LinkSets(), this.initModulesFromGroup(child), definition)); } } return moduleSet; }; Configuration.prototype.merge = function (a, b, k) { if (k === void 0) { k = 0; } var inInt = a.incoming.intersection(b.incoming), outInt = a.outgoing.intersection(b.outgoing); var children = new ModuleSet(); children.add(a); children.add(b); var m = new Module(this.modules.length, outInt, inInt, children); this.modules.push(m); var update = function (s, i, o) { s.forAll(function (ms, linktype) { ms.forAll(function (n) { var nls = n[i]; nls.add(linktype, m); nls.remove(linktype, a); nls.remove(linktype, b); a[o].remove(linktype, n); b[o].remove(linktype, n); }); }); }; update(outInt, "incoming", "outgoing"); update(inInt, "outgoing", "incoming"); this.R -= inInt.count() + outInt.count(); this.roots[k].remove(a); this.roots[k].remove(b); this.roots[k].add(m); return m; }; Configuration.prototype.rootMerges = function (k) { if (k === void 0) { k = 0; } var rs = this.roots[k].modules(); var n = rs.length; var merges = new Array(n * (n - 1)); var ctr = 0; for (var i = 0, i_ = n - 1; i < i_; ++i) { for (var j = i + 1; j < n; ++j) { var a = rs[i], b = rs[j]; merges[ctr] = { id: ctr, nEdges: this.nEdges(a, b), a: a, b: b }; ctr++; } } return merges; }; Configuration.prototype.greedyMerge = function () { for (var i = 0; i < this.roots.length; ++i) { if (this.roots[i].modules().length < 2) continue; var ms = this.rootMerges(i).sort(function (a, b) { return a.nEdges == b.nEdges ? a.id - b.id : a.nEdges - b.nEdges; }); var m = ms[0]; if (m.nEdges >= this.R) continue; this.merge(m.a, m.b, i); return true; } }; Configuration.prototype.nEdges = function (a, b) { var inInt = a.incoming.intersection(b.incoming), outInt = a.outgoing.intersection(b.outgoing); return this.R - inInt.count() - outInt.count(); }; Configuration.prototype.getGroupHierarchy = function (retargetedEdges) { var _this = this; var groups = []; var root = {}; toGroups(this.roots[0], root, groups); var es = this.allEdges(); es.forEach(function (e) { var a = _this.modules[e.source]; var b = _this.modules[e.target]; retargetedEdges.push(new PowerEdge(typeof a.gid === "undefined" ? e.source : groups[a.gid], typeof b.gid === "undefined" ? e.target : groups[b.gid], e.type)); }); return groups; }; Configuration.prototype.allEdges = function () { var es = []; Configuration.getEdges(this.roots[0], es); return es; }; Configuration.getEdges = function (modules, es) { modules.forAll(function (m) { m.getEdges(es); Configuration.getEdges(m.children, es); }); }; return Configuration; }()); exports.Configuration = Configuration; function toGroups(modules, group, groups) { modules.forAll(function (m) { if (m.isLeaf()) { if (!group.leaves) group.leaves = []; group.leaves.push(m.id); } else { var g = group; m.gid = groups.length; if (!m.isIsland() || m.isPredefined()) { g = { id: m.gid }; if (m.isPredefined()) for (var prop in m.definition) g[prop] = m.definition[prop]; if (!group.groups) group.groups = []; group.groups.push(m.gid); groups.push(g); } toGroups(m.children, g, groups); } }); } var Module = (function () { function Module(id, outgoing, incoming, children, definition) { if (outgoing === void 0) { outgoing = new LinkSets(); } if (incoming === void 0) { incoming = new LinkSets(); } if (children === void 0) { children = new ModuleSet(); } this.id = id; this.outgoing = outgoing; this.incoming = incoming; this.children = children; this.definition = definition; } Module.prototype.getEdges = function (es) { var _this = this; this.outgoing.forAll(function (ms, edgetype) { ms.forAll(function (target) { es.push(new PowerEdge(_this.id, target.id, edgetype)); }); }); }; Module.prototype.isLeaf = function () { return this.children.count() === 0; }; Module.prototype.isIsland = function () { return this.outgoing.count() === 0 && this.incoming.count() === 0; }; Module.prototype.isPredefined = function () { return typeof this.definition !== "undefined"; }; return Module; }()); exports.Module = Module; function intersection(m, n) { var i = {}; for (var v in m) if (v in n) i[v] = m[v]; return i; } var ModuleSet = (function () { function ModuleSet() { this.table = {}; } ModuleSet.prototype.count = function () { return Object.keys(this.table).length; }; ModuleSet.prototype.intersection = function (other) { var result = new ModuleSet(); result.table = intersection(this.table, other.table); return result; }; ModuleSet.prototype.intersectionCount = function (other) { return this.intersection(other).count(); }; ModuleSet.prototype.contains = function (id) { return id in this.table; }; ModuleSet.prototype.add = function (m) { this.table[m.id] = m; }; ModuleSet.prototype.remove = function (m) { delete this.table[m.id]; }; ModuleSet.prototype.forAll = function (f) { for (var mid in this.table) { f(this.table[mid]); } }; ModuleSet.prototype.modules = function () { var vs = []; this.forAll(function (m) { if (!m.isPredefined()) vs.push(m); }); return vs; }; return ModuleSet; }()); exports.ModuleSet = ModuleSet; var LinkSets = (function () { function LinkSets() { this.sets = {}; this.n = 0; } LinkSets.prototype.count = function () { return this.n; }; LinkSets.prototype.contains = function (id) { var result = false; this.forAllModules(function (m) { if (!result && m.id == id) { result = true; } }); return result; }; LinkSets.prototype.add = function (linktype, m) { var s = linktype in this.sets ? this.sets[linktype] : this.sets[linktype] = new ModuleSet(); s.add(m); ++this.n; }; LinkSets.prototype.remove = function (linktype, m) { var ms = this.sets[linktype]; ms.remove(m); if (ms.count() === 0) { delete this.sets[linktype]; } --this.n; }; LinkSets.prototype.forAll = function (f) { for (var linktype in this.sets) { f(this.sets[linktype], Number(linktype)); } }; LinkSets.prototype.forAllModules = function (f) { this.forAll(function (ms, lt) { return ms.forAll(f); }); }; LinkSets.prototype.intersection = function (other) { var result = new LinkSets(); this.forAll(function (ms, lt) { if (lt in other.sets) { var i = ms.intersection(other.sets[lt]), n = i.count(); if (n > 0) { result.sets[lt] = i; result.n += n; } } }); return result; }; return LinkSets; }()); exports.LinkSets = LinkSets; function intersectionCount(m, n) { return Object.keys(intersection(m, n)).length; } function getGroups(nodes, links, la, rootGroup) { var n = nodes.length, c = new Configuration(n, links, la, rootGroup); while (c.greedyMerge()) ; var powerEdges = []; var g = c.getGroupHierarchy(powerEdges); powerEdges.forEach(function (e) { var f = function (end) { var g = e[end]; if (typeof g == "number") e[end] = nodes[g]; }; f("source"); f("target"); }); return { groups: g, powerEdges: powerEdges }; } exports.getGroups = getGroups; //# sourceMappingURL=powergraph.js.map