(function(f){if(typeof exports==="object"&&typeof module!=="undefined"){module.exports=f()}else if(typeof define==="function"&&define.amd){define([],f)}else{var g;if(typeof window!=="undefined"){g=window}else if(typeof global!=="undefined"){g=global}else if(typeof self!=="undefined"){g=self}else{g=this}g.dagreD3 = f()}})(function(){var define,module,exports;return (function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
  /**
   * @license
   * Copyright (c) 2012-2013 Chris Pettitt
   *
   * Permission is hereby granted, free of charge, to any person obtaining a copy
   * of this software and associated documentation files (the "Software"), to deal
   * in the Software without restriction, including without limitation the rights
   * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
   * copies of the Software, and to permit persons to whom the Software is
   * furnished to do so, subject to the following conditions:
   *
   * The above copyright notice and this permission notice shall be included in
   * all copies or substantial portions of the Software.
   *
   * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
   * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
   * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
   * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
   * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
   * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
   * THE SOFTWARE.
   */
  module.exports =  {
    graphlib: require("./lib/graphlib"),
    dagre: require("./lib/dagre"),
    intersect: require("./lib/intersect"),
    render: require("./lib/render"),
    util: require("./lib/util"),
    version: require("./lib/version")
  };

},{"./lib/dagre":8,"./lib/graphlib":9,"./lib/intersect":10,"./lib/render":25,"./lib/util":27,"./lib/version":28}],2:[function(require,module,exports){
  var util = require("./util");

  module.exports = {
    "default": normal,
    "normal": normal,
    "vee": vee,
    "undirected": undirected
  };

  function normal(parent, id, edge, type) {
    var marker = parent.append("marker")
      .attr("id", id)
      .attr("viewBox", "0 0 10 10")
      .attr("refX", 9)
      .attr("refY", 5)
      .attr("markerUnits", "strokeWidth")
      .attr("markerWidth", 8)
      .attr("markerHeight", 6)
      .attr("orient", "auto");

    var path = marker.append("path")
      .attr("d", "M 0 0 L 10 5 L 0 10 z")
      .style("stroke-width", 1)
      .style("stroke-dasharray", "1,0");
    util.applyStyle(path, edge[type + "Style"]);
    if (edge[type + "Class"]) {
      path.attr("class", edge[type + "Class"]);
    }
  }

  function vee(parent, id, edge, type) {
    var marker = parent.append("marker")
      .attr("id", id)
      .attr("viewBox", "0 0 10 10")
      .attr("refX", 9)
      .attr("refY", 5)
      .attr("markerUnits", "strokeWidth")
      .attr("markerWidth", 8)
      .attr("markerHeight", 6)
      .attr("orient", "auto");

    var path = marker.append("path")
      .attr("d", "M 0 0 L 10 5 L 0 10 L 4 5 z")
      .style("stroke-width", 1)
      .style("stroke-dasharray", "1,0");
    util.applyStyle(path, edge[type + "Style"]);
    if (edge[type + "Class"]) {
      path.attr("class", edge[type + "Class"]);
    }
  }

  function undirected(parent, id, edge, type) {
    var marker = parent.append("marker")
      .attr("id", id)
      .attr("viewBox", "0 0 10 10")
      .attr("refX", 9)
      .attr("refY", 5)
      .attr("markerUnits", "strokeWidth")
      .attr("markerWidth", 8)
      .attr("markerHeight", 6)
      .attr("orient", "auto");

    var path = marker.append("path")
      .attr("d", "M 0 5 L 10 5")
      .style("stroke-width", 1)
      .style("stroke-dasharray", "1,0");
    util.applyStyle(path, edge[type + "Style"]);
    if (edge[type + "Class"]) {
      path.attr("class", edge[type + "Class"]);
    }
  }

},{"./util":27}],3:[function(require,module,exports){
  var util = require("./util"),
    addLabel = require("./label/add-label");

  module.exports = createClusters;

  function createClusters(selection, g) {
    var clusters = g.nodes().filter(function(v) { return util.isSubgraph(g, v); }),
      svgClusters = selection.selectAll("g.cluster")
        .data(clusters, function(v) { return v; });

    svgClusters.selectAll("*").remove();
    svgClusters.enter()
      .append("g")
      .attr("class", "cluster")
      .attr("id",function(v){
        var node = g.node(v);
        return node.id;
      })
      .style("opacity", 0);

    util.applyTransition(svgClusters, g)
      .style("opacity", 1);

    svgClusters.each(function(v) {
      var node = g.node(v),
        thisGroup = d3.select(this);
      d3.select(this).append("rect");
      var labelGroup = thisGroup.append("g").attr("class", "label");
      addLabel(labelGroup, node, node.clusterLabelPos);
    });

    svgClusters.selectAll("rect").each(function(c) {
      var node = g.node(c);
      var domCluster = d3.select(this);
      util.applyStyle(domCluster, node.style);
    });

    util.applyTransition(svgClusters.exit(), g)
      .style("opacity", 0)
      .remove();

    return svgClusters;
  }

},{"./label/add-label":18,"./util":27}],4:[function(require,module,exports){
  "use strict";

  var _ = require("./lodash"),
    addLabel = require("./label/add-label"),
    util = require("./util"),
    d3 = require("./d3");

  module.exports = createEdgeLabels;

  function createEdgeLabels(selection, g) {
    var svgEdgeLabels = selection.selectAll("g.edgeLabel")
      .data(g.edges(), function(e) { return util.edgeToId(e); })
      .classed("update", true);

    svgEdgeLabels.selectAll("*").remove();
    svgEdgeLabels.enter()
      .append("g")
      .classed("edgeLabel", true)
      .style("opacity", 0);
    svgEdgeLabels.each(function(e) {
      var edge = g.edge(e),
        label = addLabel(d3.select(this), g.edge(e), 0, 0).classed("label", true),
        bbox = label.node().getBBox();

      if (edge.labelId) { label.attr("id", edge.labelId); }
      if (!_.has(edge, "width")) { edge.width = bbox.width; }
      if (!_.has(edge, "height")) { edge.height = bbox.height; }
    });

    util.applyTransition(svgEdgeLabels.exit(), g)
      .style("opacity", 0)
      .remove();

    return svgEdgeLabels;
  }

},{"./d3":7,"./label/add-label":18,"./lodash":21,"./util":27}],5:[function(require,module,exports){
  "use strict";

  var _ = require("./lodash"),
    intersectNode = require("./intersect/intersect-node"),
    util = require("./util"),
    d3 = require("./d3");
  module.exports = createEdgePaths;

  function createEdgePaths(selection, g, arrows) {
    var svgPaths = selection.selectAll("g.edgePath")
      .data(g.edges(), function(e) { return util.edgeToId(e); })
      .classed("update", true);

    enter(svgPaths, g);
    exit(svgPaths, g);

    util.applyTransition(svgPaths, g)
      .style("opacity", 1);

    // Save DOM element in the path group, and set ID and class
    svgPaths.each(function(e) {
      var domEdge = d3.select(this);
      var edge = g.edge(e);
      edge.elem = this;

      if (edge.id) {
        domEdge.attr("id", edge.id);
      }

      util.applyClass(domEdge, edge["class"],
        (domEdge.classed("update") ? "update " : "") + "edgePath");
    });

    svgPaths.selectAll("path.path")
      .each(function(e) {
        var edge = g.edge(e);
        edge.arrowheadId = _.uniqueId("arrowhead");

        var domEdge = d3.select(this)
          .attr("marker-end", function() {
            return "url(" + makeFragmentRef(location.href, edge.arrowheadId) + ")";
          })
          .style("fill", "none");

        util.applyTransition(domEdge, g)
          .attr("d", function(e) { return calcPoints(g, e); });

        util.applyStyle(domEdge, edge.style);
      });

    svgPaths.selectAll("defs *").remove();
    svgPaths.selectAll("defs")
      .each(function(e) {
        var edge = g.edge(e),
          arrowhead = arrows[edge.arrowhead];
        arrowhead(d3.select(this), edge.arrowheadId, edge, "arrowhead");
      });

    return svgPaths;
  }

  function makeFragmentRef(url, fragmentId) {
    var baseUrl = url.split("#")[0];
    return baseUrl + "#" + fragmentId;
  }

  function calcPoints(g, e) {
    var edge = g.edge(e),
      tail = g.node(e.v),
      head = g.node(e.w),
      points = edge.points.slice(1, edge.points.length - 1);
    points.unshift(intersectNode(tail, points[0]));
    points.push(intersectNode(head, points[points.length - 1]));

    return createLine(edge, points);
  }

  function createLine(edge, points) {
    var line = d3.svg.line()
      .x(function(d) { return d.x; })
      .y(function(d) { return d.y; });

    if (_.has(edge, "lineInterpolate")) {
      line.interpolate(edge.lineInterpolate);
    }

    if (_.has(edge, "lineTension")) {
      line.tension(Number(edge.lineTension));
    }

    return line(points);
  }

  function getCoords(elem) {
    var bbox = elem.getBBox(),
      matrix = elem.ownerSVGElement.getScreenCTM()
        .inverse()
        .multiply(elem.getScreenCTM())
        .translate(bbox.width / 2, bbox.height / 2);
    return { x: matrix.e, y: matrix.f };
  }

  function enter(svgPaths, g) {
    var svgPathsEnter = svgPaths.enter()
      .append("g")
      .attr("class", "edgePath")
      .style("opacity", 0);
    svgPathsEnter.append("path")
      .attr("class", "path")
      .attr("d", function(e) {
        var edge = g.edge(e),
          sourceElem = g.node(e.v).elem,
          points = _.range(edge.points.length).map(function() { return getCoords(sourceElem); });
        return createLine(edge, points);
      });
    svgPathsEnter.append("defs");
  }

  function exit(svgPaths, g) {
    var svgPathExit = svgPaths.exit();
    util.applyTransition(svgPathExit, g)
      .style("opacity", 0)
      .remove();

    util.applyTransition(svgPathExit.select("path.path"), g)
      .attr("d", function(e) {
        var source = g.node(e.v);

        if (source) {
          var points = _.range(this.getTotalLength()).map(function() { return source; });
          return createLine({}, points);
        } else {
          return d3.select(this).attr("d");
        }
      });
  }

},{"./d3":7,"./intersect/intersect-node":14,"./lodash":21,"./util":27}],6:[function(require,module,exports){
  "use strict";

  var _ = require("./lodash"),
    addLabel = require("./label/add-label"),
    util = require("./util"),
    d3 = require("./d3");

  module.exports = createNodes;

  function createNodes(selection, g, shapes) {
    var simpleNodes = g.nodes().filter(function(v) { return !util.isSubgraph(g, v); });
    var svgNodes = selection.selectAll("g.node")
      .data(simpleNodes, function(v) { return v; })
      .classed("update", true);

    svgNodes.selectAll("*").remove();
    svgNodes.enter()
      .append("g")
      .attr("class", "node")
      .style("opacity", 0);
    svgNodes.each(function(v) {
      var node = g.node(v),
        thisGroup = d3.select(this),
        labelGroup = thisGroup.append("g").attr("class", "label"),
        labelDom = addLabel(labelGroup, node),
        shape = shapes[node.shape],
        bbox = _.pick(labelDom.node().getBBox(), "width", "height");

      node.elem = this;

      if (node.id) { thisGroup.attr("id", node.id); }
      if (node.labelId) { labelGroup.attr("id", node.labelId); }
      util.applyClass(thisGroup, node["class"],
        (thisGroup.classed("update") ? "update " : "") + "node");

      if (_.has(node, "width")) { bbox.width = node.width; }
      if (_.has(node, "height")) { bbox.height = node.height; }

      bbox.width += node.paddingLeft + node.paddingRight;
      bbox.height += node.paddingTop + node.paddingBottom;
      labelGroup.attr("transform", "translate(" +
        ((node.paddingLeft - node.paddingRight) / 2) + "," +
        ((node.paddingTop - node.paddingBottom) / 2) + ")");

      var shapeSvg = shape(d3.select(this), bbox, node);
      util.applyStyle(shapeSvg, node.style);

      var shapeBBox = shapeSvg.node().getBBox();
      node.width = shapeBBox.width;
      node.height = shapeBBox.height;
    });

    util.applyTransition(svgNodes.exit(), g)
      .style("opacity", 0)
      .remove();

    return svgNodes;
  }

},{"./d3":7,"./label/add-label":18,"./lodash":21,"./util":27}],7:[function(require,module,exports){
// Stub to get D3 either via NPM or from the global object
  module.exports = window.d3;

},{}],8:[function(require,module,exports){
  /* global window */

  var dagre;

  if (require) {
    try {
      dagre = require("dagre");
    } catch (e) {}
  }

  if (!dagre) {
    dagre = window.dagre;
  }

  module.exports = dagre;

},{"dagre":undefined}],9:[function(require,module,exports){
  /* global window */

  var graphlib;

  if (require) {
    try {
      graphlib = require("graphlib");
    } catch (e) {}
  }

  if (!graphlib) {
    graphlib = window.graphlib;
  }

  module.exports = graphlib;

},{"graphlib":undefined}],10:[function(require,module,exports){
  module.exports = {
    node: require("./intersect-node"),
    circle: require("./intersect-circle"),
    ellipse: require("./intersect-ellipse"),
    polygon: require("./intersect-polygon"),
    rect: require("./intersect-rect")
  };

},{"./intersect-circle":11,"./intersect-ellipse":12,"./intersect-node":14,"./intersect-polygon":15,"./intersect-rect":16}],11:[function(require,module,exports){
  var intersectEllipse = require("./intersect-ellipse");

  module.exports = intersectCircle;

  function intersectCircle(node, rx, point) {
    return intersectEllipse(node, rx, rx, point);
  }

},{"./intersect-ellipse":12}],12:[function(require,module,exports){
  module.exports = intersectEllipse;

  function intersectEllipse(node, rx, ry, point) {
    // Formulae from: http://mathworld.wolfram.com/Ellipse-LineIntersection.html

    var cx = node.x;
    var cy = node.y;

    var px = cx - point.x;
    var py = cy - point.y;

    var det = Math.sqrt(rx * rx * py * py + ry * ry * px * px);

    var dx = Math.abs(rx * ry * px / det);
    if (point.x < cx) {
      dx = -dx;
    }
    var dy = Math.abs(rx * ry * py / det);
    if (point.y < cy) {
      dy = -dy;
    }

    return {x: cx + dx, y: cy + dy};
  }


},{}],13:[function(require,module,exports){
  module.exports = intersectLine;

  /*
   * Returns the point at which two lines, p and q, intersect or returns
   * undefined if they do not intersect.
   */
  function intersectLine(p1, p2, q1, q2) {
    // Algorithm from J. Avro, (ed.) Graphics Gems, No 2, Morgan Kaufmann, 1994,
    // p7 and p473.

    var a1, a2, b1, b2, c1, c2;
    var r1, r2 , r3, r4;
    var denom, offset, num;
    var x, y;

    // Compute a1, b1, c1, where line joining points 1 and 2 is F(x,y) = a1 x +
    // b1 y + c1 = 0.
    a1 = p2.y - p1.y;
    b1 = p1.x - p2.x;
    c1 = (p2.x * p1.y) - (p1.x * p2.y);

    // Compute r3 and r4.
    r3 = ((a1 * q1.x) + (b1 * q1.y) + c1);
    r4 = ((a1 * q2.x) + (b1 * q2.y) + c1);

    // Check signs of r3 and r4. If both point 3 and point 4 lie on
    // same side of line 1, the line segments do not intersect.
    if ((r3 !== 0) && (r4 !== 0) && sameSign(r3, r4)) {
      return /*DONT_INTERSECT*/;
    }

    // Compute a2, b2, c2 where line joining points 3 and 4 is G(x,y) = a2 x + b2 y + c2 = 0
    a2 = q2.y - q1.y;
    b2 = q1.x - q2.x;
    c2 = (q2.x * q1.y) - (q1.x * q2.y);

    // Compute r1 and r2
    r1 = (a2 * p1.x) + (b2 * p1.y) + c2;
    r2 = (a2 * p2.x) + (b2 * p2.y) + c2;

    // Check signs of r1 and r2. If both point 1 and point 2 lie
    // on same side of second line segment, the line segments do
    // not intersect.
    if ((r1 !== 0) && (r2 !== 0) && (sameSign(r1, r2))) {
      return /*DONT_INTERSECT*/;
    }

    // Line segments intersect: compute intersection point.
    denom = (a1 * b2) - (a2 * b1);
    if (denom === 0) {
      return /*COLLINEAR*/;
    }

    offset = Math.abs(denom / 2);

    // The denom/2 is to get rounding instead of truncating. It
    // is added or subtracted to the numerator, depending upon the
    // sign of the numerator.
    num = (b1 * c2) - (b2 * c1);
    x = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);

    num = (a2 * c1) - (a1 * c2);
    y = (num < 0) ? ((num - offset) / denom) : ((num + offset) / denom);

    return { x: x, y: y };
  }

  function sameSign(r1, r2) {
    return r1 * r2 > 0;
  }

},{}],14:[function(require,module,exports){
  module.exports = intersectNode;

  function intersectNode(node, point) {
    return node.intersect(point);
  }

},{}],15:[function(require,module,exports){
  var intersectLine = require("./intersect-line");

  module.exports = intersectPolygon;

  /*
   * Returns the point ({x, y}) at which the point argument intersects with the
   * node argument assuming that it has the shape specified by polygon.
   */
  function intersectPolygon(node, polyPoints, point) {
    var x1 = node.x;
    var y1 = node.y;

    var intersections = [];

    var minX = Number.POSITIVE_INFINITY,
      minY = Number.POSITIVE_INFINITY;
    polyPoints.forEach(function(entry) {
      minX = Math.min(minX, entry.x);
      minY = Math.min(minY, entry.y);
    });

    var left = x1 - node.width / 2 - minX;
    var top =  y1 - node.height / 2 - minY;

    for (var i = 0; i < polyPoints.length; i++) {
      var p1 = polyPoints[i];
      var p2 = polyPoints[i < polyPoints.length - 1 ? i + 1 : 0];
      var intersect = intersectLine(node, point,
        {x: left + p1.x, y: top + p1.y}, {x: left + p2.x, y: top + p2.y});
      if (intersect) {
        intersections.push(intersect);
      }
    }

    if (!intersections.length) {
      console.log("NO INTERSECTION FOUND, RETURN NODE CENTER", node);
      return node;
    }

    if (intersections.length > 1) {
      // More intersections, find the one nearest to edge end point
      intersections.sort(function(p, q) {
        var pdx = p.x - point.x,
          pdy = p.y - point.y,
          distp = Math.sqrt(pdx * pdx + pdy * pdy),

          qdx = q.x - point.x,
          qdy = q.y - point.y,
          distq = Math.sqrt(qdx * qdx + qdy * qdy);

        return (distp < distq) ? -1 : (distp === distq ? 0 : 1);
      });
    }
    return intersections[0];
  }

},{"./intersect-line":13}],16:[function(require,module,exports){
  module.exports = intersectRect;

  function intersectRect(node, point) {
    var x = node.x;
    var y = node.y;

    // Rectangle intersection algorithm from:
    // http://math.stackexchange.com/questions/108113/find-edge-between-two-boxes
    var dx = point.x - x;
    var dy = point.y - y;
    var w = node.width / 2;
    var h = node.height / 2;

    var sx, sy;
    if (Math.abs(dy) * w > Math.abs(dx) * h) {
      // Intersection is top or bottom of rect.
      if (dy < 0) {
        h = -h;
      }
      sx = dy === 0 ? 0 : h * dx / dy;
      sy = h;
    } else {
      // Intersection is left or right of rect.
      if (dx < 0) {
        w = -w;
      }
      sx = w;
      sy = dx === 0 ? 0 : w * dy / dx;
    }

    return {x: x + sx, y: y + sy};
  }

},{}],17:[function(require,module,exports){
  var util = require("../util");

  module.exports = addHtmlLabel;

  function addHtmlLabel(root, node) {
    var fo = root
      .append("foreignObject")
      .attr("width", "100000");

    var div = fo
      .append("xhtml:div");
    div.attr("xmlns", "http://www.w3.org/1999/xhtml");

    var label = node.label;
    switch(typeof label) {
      case "function":
        div.insert(label);
        break;
      case "object":
        // Currently we assume this is a DOM object.
        div.insert(function() { return label; });
        break;
      default: div.html(label);
    }

    util.applyStyle(div, node.labelStyle);
    div.style("display", "inline-block");
    // Fix for firefox
    div.style("white-space", "nowrap");

    var client = div[0][0].getBoundingClientRect();
    fo
      .attr("width", client.width)
      .attr("height", client.height);

    return fo;
  }

},{"../util":27}],18:[function(require,module,exports){
  var addTextLabel = require("./add-text-label"),
    addHtmlLabel = require("./add-html-label"),
    addSVGLabel  = require("./add-svg-label");

  module.exports = addLabel;

  function addLabel(root, node, location) {
    var label = node.label;
    var labelSvg = root.append("g");

    // Allow the label to be a string, a function that returns a DOM element, or
    // a DOM element itself.
    if (node.labelType === "svg") {
      addSVGLabel(labelSvg, node);
    } else if (typeof label !== "string" || node.labelType === "html") {
      addHtmlLabel(labelSvg, node);
    } else {
      addTextLabel(labelSvg, node);
    }

    var labelBBox = labelSvg.node().getBBox();
    var y;
    switch(location) {
      case "top":
        y = (-node.height / 2);
        break;
      case "bottom":
        y = (node.height / 2) - labelBBox.height;
        break;
      default:
        y = (-labelBBox.height / 2);
    }
    labelSvg.attr("transform",
      "translate(" + (-labelBBox.width / 2) + "," + y + ")");

    return labelSvg;
  }

},{"./add-html-label":17,"./add-svg-label":19,"./add-text-label":20}],19:[function(require,module,exports){
  var util = require("../util");

  module.exports = addSVGLabel;

  function addSVGLabel(root, node) {
    var domNode = root;

    domNode.node().appendChild(node.label);

    util.applyStyle(domNode, node.labelStyle);

    return domNode;
  }

},{"../util":27}],20:[function(require,module,exports){
  var util = require("../util");

  module.exports = addTextLabel;

  /*
   * Attaches a text label to the specified root. Handles escape sequences.
   */
  function addTextLabel(root, node) {
    var domNode = root.append("text");

    var lines = processEscapeSequences(node.label).split("\n");
    for (var i = 0; i < lines.length; i++) {
      domNode
        .append("tspan")
        .attr("xml:space", "preserve")
        .attr("dy", "1em")
        .attr("x", "1")
        .text(lines[i]);
    }

    util.applyStyle(domNode, node.labelStyle);

    return domNode;
  }

  function processEscapeSequences(text) {
    var newText = "",
      escaped = false,
      ch;
    for (var i = 0; i < text.length; ++i) {
      ch = text[i];
      if (escaped) {
        switch(ch) {
          case "n": newText += "\n"; break;
          default: newText += ch;
        }
        escaped = false;
      } else if (ch === "\\") {
        escaped = true;
      } else {
        newText += ch;
      }
    }
    return newText;
  }

},{"../util":27}],21:[function(require,module,exports){
  /* global window */

  var lodash;

  if (require) {
    try {
      lodash = require("lodash");
    } catch (e) {}
  }

  if (!lodash) {
    lodash = window._;
  }

  module.exports = lodash;

},{"lodash":undefined}],22:[function(require,module,exports){
  "use strict";

  var util = require("./util"),
    d3 = require("./d3");

  module.exports = positionClusters;

  function positionClusters(selection, g) {
    var created = selection.filter(function() { return !d3.select(this).classed("update"); });

    function translate(v) {
      var node = g.node(v);
      return "translate(" + node.x + "," + node.y + ")";
    }

    created.attr("transform", translate);

    util.applyTransition(selection, g)
      .style("opacity", 1)
      .attr("transform", translate);

    util.applyTransition(created.selectAll("rect"), g)
      .attr("width", function(v) { return g.node(v).width; })
      .attr("height", function(v) { return g.node(v).height; })
      .attr("x", function(v) {
        var node = g.node(v);
        return -node.width / 2;
      })
      .attr("y", function(v) {
        var node = g.node(v);
        return -node.height / 2;
      });

  }

},{"./d3":7,"./util":27}],23:[function(require,module,exports){
  "use strict";

  var util = require("./util"),
    d3 = require("./d3"),
    _ = require("./lodash");

  module.exports = positionEdgeLabels;

  function positionEdgeLabels(selection, g) {
    var created = selection.filter(function() { return !d3.select(this).classed("update"); });

    function translate(e) {
      var edge = g.edge(e);
      return _.has(edge, "x") ? "translate(" + edge.x + "," + edge.y + ")" : "";
    }

    created.attr("transform", translate);

    util.applyTransition(selection, g)
      .style("opacity", 1)
      .attr("transform", translate);
  }

},{"./d3":7,"./lodash":21,"./util":27}],24:[function(require,module,exports){
  "use strict";

  var util = require("./util"),
    d3 = require("./d3");

  module.exports = positionNodes;

  function positionNodes(selection, g) {
    var created = selection.filter(function() { return !d3.select(this).classed("update"); });

    function translate(v) {
      var node = g.node(v);
      return "translate(" + node.x + "," + node.y + ")";
    }

    created.attr("transform", translate);

    util.applyTransition(selection, g)
      .style("opacity", 1)
      .attr("transform", translate);
  }

},{"./d3":7,"./util":27}],25:[function(require,module,exports){
  var _ = require("./lodash"),
    layout = require("./dagre").layout;

  module.exports = render;

// This design is based on http://bost.ocks.org/mike/chart/.
  function render() {
    var createNodes = require("./create-nodes"),
      createClusters = require("./create-clusters"),
      createEdgeLabels = require("./create-edge-labels"),
      createEdgePaths = require("./create-edge-paths"),
      positionNodes = require("./position-nodes"),
      positionEdgeLabels = require("./position-edge-labels"),
      positionClusters = require("./position-clusters"),
      shapes = require("./shapes"),
      arrows = require("./arrows");

    var fn = function(svg, g) {
      preProcessGraph(g);

      var outputGroup = createOrSelectGroup(svg, "output"),
        clustersGroup = createOrSelectGroup(outputGroup, "clusters"),
        edgePathsGroup = createOrSelectGroup(outputGroup, "edgePaths"),
        edgeLabels = createEdgeLabels(createOrSelectGroup(outputGroup, "edgeLabels"), g),
        nodes = createNodes(createOrSelectGroup(outputGroup, "nodes"), g, shapes);

      layout(g);

      positionNodes(nodes, g);
      positionEdgeLabels(edgeLabels, g);
      createEdgePaths(edgePathsGroup, g, arrows);

      var clusters = createClusters(clustersGroup, g);
      positionClusters(clusters, g);

      postProcessGraph(g);
    };

    fn.createNodes = function(value) {
      if (!arguments.length) return createNodes;
      createNodes = value;
      return fn;
    };

    fn.createClusters = function(value) {
      if (!arguments.length) return createClusters;
      createClusters = value;
      return fn;
    };

    fn.createEdgeLabels = function(value) {
      if (!arguments.length) return createEdgeLabels;
      createEdgeLabels = value;
      return fn;
    };

    fn.createEdgePaths = function(value) {
      if (!arguments.length) return createEdgePaths;
      createEdgePaths = value;
      return fn;
    };

    fn.shapes = function(value) {
      if (!arguments.length) return shapes;
      shapes = value;
      return fn;
    };

    fn.arrows = function(value) {
      if (!arguments.length) return arrows;
      arrows = value;
      return fn;
    };

    return fn;
  }

  var NODE_DEFAULT_ATTRS = {
    paddingLeft: 10,
    paddingRight: 10,
    paddingTop: 10,
    paddingBottom: 10,
    rx: 0,
    ry: 0,
    shape: "rect"
  };

  var EDGE_DEFAULT_ATTRS = {
    arrowhead: "normal",
    lineInterpolate: "linear"
  };

  function preProcessGraph(g) {
    g.nodes().forEach(function(v) {
      var node = g.node(v);
      if (!_.has(node, "label") && !g.children(v).length) { node.label = v; }

      if (_.has(node, "paddingX")) {
        _.defaults(node, {
          paddingLeft: node.paddingX,
          paddingRight: node.paddingX
        });
      }

      if (_.has(node, "paddingY")) {
        _.defaults(node, {
          paddingTop: node.paddingY,
          paddingBottom: node.paddingY
        });
      }

      if (_.has(node, "padding")) {
        _.defaults(node, {
          paddingLeft: node.padding,
          paddingRight: node.padding,
          paddingTop: node.padding,
          paddingBottom: node.padding
        });
      }

      _.defaults(node, NODE_DEFAULT_ATTRS);

      _.each(["paddingLeft", "paddingRight", "paddingTop", "paddingBottom"], function(k) {
        node[k] = Number(node[k]);
      });

      // Save dimensions for restore during post-processing
      if (_.has(node, "width")) { node._prevWidth = node.width; }
      if (_.has(node, "height")) { node._prevHeight = node.height; }
    });

    g.edges().forEach(function(e) {
      var edge = g.edge(e);
      if (!_.has(edge, "label")) { edge.label = ""; }
      _.defaults(edge, EDGE_DEFAULT_ATTRS);
    });
  }

  function postProcessGraph(g) {
    _.each(g.nodes(), function(v) {
      var node = g.node(v);

      // Restore original dimensions
      if (_.has(node, "_prevWidth")) {
        node.width = node._prevWidth;
      } else {
        delete node.width;
      }

      if (_.has(node, "_prevHeight")) {
        node.height = node._prevHeight;
      } else {
        delete node.height;
      }

      delete node._prevWidth;
      delete node._prevHeight;
    });
  }

  function createOrSelectGroup(root, name) {
    var selection = root.select("g." + name);
    if (selection.empty()) {
      selection = root.append("g").attr("class", name);
    }
    return selection;
  }

},{"./arrows":2,"./create-clusters":3,"./create-edge-labels":4,"./create-edge-paths":5,"./create-nodes":6,"./dagre":8,"./lodash":21,"./position-clusters":22,"./position-edge-labels":23,"./position-nodes":24,"./shapes":26}],26:[function(require,module,exports){
  "use strict";

  var intersectRect = require("./intersect/intersect-rect"),
    intersectEllipse = require("./intersect/intersect-ellipse"),
    intersectCircle = require("./intersect/intersect-circle"),
    intersectPolygon = require("./intersect/intersect-polygon");

  module.exports = {
    rect: rect,
    ellipse: ellipse,
    circle: circle,
    diamond: diamond
  };

  function rect(parent, bbox, node) {
    var shapeSvg = parent.insert("rect", ":first-child")
      .attr("rx", node.rx)
      .attr("ry", node.ry)
      .attr("x", -bbox.width / 2)
      .attr("y", -bbox.height / 2)
      .attr("width", bbox.width)
      .attr("height", bbox.height);

    node.intersect = function(point) {
      return intersectRect(node, point);
    };

    return shapeSvg;
  }

  function ellipse(parent, bbox, node) {
    var rx = bbox.width / 2,
      ry = bbox.height / 2,
      shapeSvg = parent.insert("ellipse", ":first-child")
        .attr("x", -bbox.width / 2)
        .attr("y", -bbox.height / 2)
        .attr("rx", rx)
        .attr("ry", ry);

    node.intersect = function(point) {
      return intersectEllipse(node, rx, ry, point);
    };

    return shapeSvg;
  }

  function circle(parent, bbox, node) {
    var r = Math.max(bbox.width, bbox.height) / 2,
      shapeSvg = parent.insert("circle", ":first-child")
        .attr("x", -bbox.width / 2)
        .attr("y", -bbox.height / 2)
        .attr("r", r);

    node.intersect = function(point) {
      return intersectCircle(node, r, point);
    };

    return shapeSvg;
  }

// Circumscribe an ellipse for the bounding box with a diamond shape. I derived
// the function to calculate the diamond shape from:
// http://mathforum.org/kb/message.jspa?messageID=3750236
  function diamond(parent, bbox, node) {
    var w = (bbox.width * Math.SQRT2) / 2,
      h = (bbox.height * Math.SQRT2) / 2,
      points = [
        { x:  0, y: -h },
        { x: -w, y:  0 },
        { x:  0, y:  h },
        { x:  w, y:  0 }
      ],
      shapeSvg = parent.insert("polygon", ":first-child")
        .attr("points", points.map(function(p) { return p.x + "," + p.y; }).join(" "));

    node.intersect = function(p) {
      return intersectPolygon(node, points, p);
    };

    return shapeSvg;
  }

},{"./intersect/intersect-circle":11,"./intersect/intersect-ellipse":12,"./intersect/intersect-polygon":15,"./intersect/intersect-rect":16}],27:[function(require,module,exports){
  var _ = require("./lodash");

// Public utility functions
  module.exports = {
    isSubgraph: isSubgraph,
    edgeToId: edgeToId,
    applyStyle: applyStyle,
    applyClass: applyClass,
    applyTransition: applyTransition
  };

  /*
   * Returns true if the specified node in the graph is a subgraph node. A
   * subgraph node is one that contains other nodes.
   */
  function isSubgraph(g, v) {
    return !!g.children(v).length;
  }

  function edgeToId(e) {
    return escapeId(e.v) + ":" + escapeId(e.w) + ":" + escapeId(e.name);
  }

  var ID_DELIM = /:/g;
  function escapeId(str) {
    return str ? String(str).replace(ID_DELIM, "\\:") : "";
  }

  function applyStyle(dom, styleFn) {
    if (styleFn) {
      dom.attr("style", styleFn);
    }
  }

  function applyClass(dom, classFn, otherClasses) {
    if (classFn) {
      dom
        .attr("class", classFn)
        .attr("class", otherClasses + " " + dom.attr("class"));
    }
  }

  function applyTransition(selection, g) {
    var graph = g.graph();

    if (_.isPlainObject(graph)) {
      var transition = graph.transition;
      if (_.isFunction(transition)) {
        return transition(selection);
      }
    }

    return selection;
  }

},{"./lodash":21}],28:[function(require,module,exports){
  module.exports = "0.4.17";

},{}]},{},[1])(1)
});
//# sourceMappingURL=data:application/json;charset:utf-8;base64,[encoded data, 51212 characters]