eulerPath = graph => {
  if (!graph.vertices.size) {
    return [];
  }

  const endpoints = eulerEndpoints(graph);
  const route = [endpoints.finish];

  const seen = new Graph(graph.directed);
  graph.vertices.forEach(seen.addVertex.bind(seen));

  depthFirstSearch(graph, endpoints.start, {
    allowTraversal: function(vertex, neighbor) {
      return !seen.edge(vertex, neighbor);
    },
    beforeTraversal: function(vertex, neighbor) {
      seen.addEdge(vertex, neighbor);
    },
    afterTraversal: function(vertex) {
      route.push(vertex);
    }
  });

  graph.vertices.forEach(vertex => {
    if (seen.neighbors(vertex).length < graph.neighbors(vertex).length) {
      throw new Error('There is no euler path for a disconnected graph.');
    }
  });
  return route.reverse();
}
Compute Euler path (either walk or tour, depending on the graph).
Euler path is a trail in a graph which visits every edge exactly once.
The procedure works both for directed and undirected graphs,
  although the details differ a bit.
The resulting array consists of exactly |E|+1 vertices.

@param {Graph}
@return Array