| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051 | "use strict";module.exports = tarjan;// Adapted from https://en.wikipedia.org/wiki/Tarjan%27s_strongly_connected_components_algorithm#The_algorithm_in_pseudocodefunction tarjan(graph) {  const indices = new Map();  const lowlinks = new Map();  const onStack = new Set();  const stack = [];  const scc = [];  let idx = 0;  function strongConnect(v) {    indices.set(v, idx);    lowlinks.set(v, idx);    idx++;    stack.push(v);    onStack.add(v);    const deps = graph.get(v);    for (const dep of deps) {      if (!indices.has(dep)) {        strongConnect(dep);        lowlinks.set(v, Math.min(lowlinks.get(v), lowlinks.get(dep)));      } else if (onStack.has(dep)) {        lowlinks.set(v, Math.min(lowlinks.get(v), indices.get(dep)));      }    }    if (lowlinks.get(v) === indices.get(v)) {      const vertices = new Set();      let w = null;      while (v !== w) {        w = stack.pop();        onStack.delete(w);        vertices.add(w);      }      scc.push(vertices);    }  }  for (const v of graph.keys()) {    if (!indices.has(v)) {      strongConnect(v);    }  }  return scc;}
 |